aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Vorontsov <anton.vorontsov@linaro.org>2012-12-11 22:15:57 -0800
committerAnton Vorontsov <anton.vorontsov@linaro.org>2012-12-11 22:15:57 -0800
commit76d8a23b127020472207b281427d3e9f4f1227e4 (patch)
treee14d7063d96d850fb259115d6fb08cbeb98ccf88
parenteba3b670a9166a91be5a11fe33290dca6b9457a2 (diff)
parent1ebaf4f4e6912199f8a4e30ba3ab55da2b71bcdf (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux
The merge is merely to fix conflicts before sending a pull request. Conflicts: drivers/power/ab8500_btemp.c drivers/power/ab8500_charger.c drivers/power/ab8500_fg.c drivers/power/abx500_chargalg.c drivers/power/max8925_power.c Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
-rw-r--r--CREDITS5
-rw-r--r--Documentation/ABI/testing/sysfs-bus-iio24
-rw-r--r--Documentation/ABI/testing/sysfs-class-devfreq44
-rw-r--r--Documentation/ABI/testing/sysfs-devices-power31
-rw-r--r--Documentation/ABI/testing/sysfs-devices-sun14
-rw-r--r--Documentation/ABI/testing/sysfs-tty112
-rw-r--r--Documentation/DocBook/gadget.tmpl2
-rw-r--r--Documentation/DocBook/uio-howto.tmpl56
-rw-r--r--Documentation/IRQ-domain.txt34
-rw-r--r--Documentation/RCU/RTFP.txt2
-rw-r--r--Documentation/RCU/checklist.txt17
-rw-r--r--Documentation/RCU/listRCU.txt2
-rw-r--r--Documentation/RCU/rcuref.txt61
-rw-r--r--Documentation/RCU/trace.txt396
-rw-r--r--Documentation/RCU/whatisRCU.txt17
-rw-r--r--Documentation/acpi/enumeration.txt227
-rw-r--r--Documentation/cgroups/memory.txt10
-rw-r--r--Documentation/cpu-hotplug.txt24
-rw-r--r--Documentation/devices.txt3
-rw-r--r--Documentation/devicetree/bindings/arm/atmel-at91.txt6
-rw-r--r--Documentation/devicetree/bindings/arm/davinci/nand.txt37
-rw-r--r--Documentation/devicetree/bindings/arm/l2cc.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/imx23-clock.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/imx28-clock.txt4
-rw-r--r--Documentation/devicetree/bindings/cpufreq/cpufreq-spear.txt42
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-stmpe.txt18
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio.txt36
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio_atmel.txt5
-rw-r--r--Documentation/devicetree/bindings/gpio/spear_spics.txt50
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-at91.txt (renamed from Documentation/devicetree/bindings/i2c/atmel-i2c.txt)0
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-davinci.txt (renamed from Documentation/devicetree/bindings/i2c/davinci.txt)0
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-gpio.txt (renamed from Documentation/devicetree/bindings/i2c/gpio-i2c.txt)0
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-imx.txt (renamed from Documentation/devicetree/bindings/i2c/fsl-imx-i2c.txt)0
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-mpc.txt (renamed from Documentation/devicetree/bindings/i2c/fsl-i2c.txt)0
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-mux.txt (renamed from Documentation/devicetree/bindings/i2c/mux.txt)0
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt18
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-nomadik.txt (renamed from Documentation/devicetree/bindings/i2c/nomadik.txt)0
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-octeon.txt (renamed from Documentation/devicetree/bindings/i2c/cavium-i2c.txt)0
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-omap.txt (renamed from Documentation/devicetree/bindings/i2c/omap-i2c.txt)0
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-pnx.txt (renamed from Documentation/devicetree/bindings/i2c/pnx.txt)0
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-pxa-pci-ce4100.txt (renamed from Documentation/devicetree/bindings/i2c/ce4100-i2c.txt)0
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-pxa.txt (renamed from Documentation/devicetree/bindings/i2c/mrvl-i2c.txt)18
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt (renamed from Documentation/devicetree/bindings/i2c/samsung-i2c.txt)0
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-sirf.txt (renamed from Documentation/devicetree/bindings/i2c/sirf-i2c.txt)0
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-versatile.txt (renamed from Documentation/devicetree/bindings/i2c/arm-versatile.txt)0
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-xiic.txt (renamed from Documentation/devicetree/bindings/i2c/xiic.txt)0
-rw-r--r--Documentation/devicetree/bindings/leds/common.txt23
-rw-r--r--Documentation/devicetree/bindings/leds/leds-gpio.txt (renamed from Documentation/devicetree/bindings/gpio/led.txt)14
-rw-r--r--Documentation/devicetree/bindings/mmc/mmc.txt8
-rw-r--r--Documentation/devicetree/bindings/mmc/samsung-sdhci.txt20
-rw-r--r--Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt (renamed from Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt)0
-rw-r--r--Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt1
-rw-r--r--Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt23
-rw-r--r--Documentation/devicetree/bindings/net/mdio-gpio.txt9
-rw-r--r--Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt141
-rw-r--r--Documentation/devicetree/bindings/rtc/orion-rtc.txt18
-rw-r--r--Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt8
-rw-r--r--Documentation/devicetree/bindings/tty/serial/of-serial.txt5
-rw-r--r--Documentation/devicetree/bindings/usb/am33xx-usb.txt8
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt6
-rw-r--r--Documentation/devicetree/usage-model.txt2
-rw-r--r--Documentation/filesystems/proc.txt16
-rw-r--r--Documentation/firmware_class/README12
-rw-r--r--Documentation/gpio.txt42
-rw-r--r--Documentation/hwmon/ads782846
-rw-r--r--Documentation/hwmon/coretemp2
-rw-r--r--Documentation/hwmon/da905547
-rw-r--r--Documentation/kbuild/makefiles.txt15
-rw-r--r--Documentation/kernel-parameters.txt55
-rw-r--r--Documentation/memory-barriers.txt9
-rw-r--r--Documentation/memory-hotplug.txt19
-rw-r--r--Documentation/mmc/mmc-dev-attrs.txt7
-rw-r--r--Documentation/networking/netdev-features.txt2
-rw-r--r--Documentation/networking/vxlan.txt4
-rw-r--r--Documentation/pinctrl.txt7
-rw-r--r--Documentation/power/pm_qos_interface.txt2
-rw-r--r--Documentation/telephony/00-INDEX4
-rw-r--r--Documentation/telephony/ixj.txt394
-rw-r--r--Documentation/usb/error-codes.txt7
-rw-r--r--Documentation/usb/mass-storage.txt15
-rw-r--r--Documentation/x86/boot.txt4
-rw-r--r--Documentation/zh_CN/arm/kernel_user_helpers.txt284
-rw-r--r--Documentation/zh_CN/arm64/memory.txt14
-rw-r--r--MAINTAINERS129
-rw-r--r--Makefile8
-rw-r--r--arch/Kconfig15
-rw-r--r--arch/alpha/include/asm/Kbuild1
-rw-r--r--arch/alpha/include/asm/ioctls.h3
-rw-r--r--arch/alpha/include/asm/mman.h11
-rw-r--r--arch/alpha/kernel/osf_sys.c6
-rw-r--r--arch/alpha/kernel/srmcons.c5
-rw-r--r--arch/arm/Kconfig6
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/boot/Makefile22
-rw-r--r--arch/arm/boot/compressed/head.S14
-rw-r--r--arch/arm/boot/dts/Makefile56
-rw-r--r--arch/arm/boot/dts/animeo_ip.dts178
-rw-r--r--arch/arm/boot/dts/at91rm9200.dtsi349
-rw-r--r--arch/arm/boot/dts/at91rm9200ek.dts79
-rw-r--r--arch/arm/boot/dts/at91sam9260.dtsi295
-rw-r--r--arch/arm/boot/dts/at91sam9263.dtsi299
-rw-r--r--arch/arm/boot/dts/at91sam9263ek.dts29
-rw-r--r--arch/arm/boot/dts/at91sam9g15.dtsi28
-rw-r--r--arch/arm/boot/dts/at91sam9g15ek.dts16
-rw-r--r--arch/arm/boot/dts/at91sam9g20ek_2mmc.dts26
-rw-r--r--arch/arm/boot/dts/at91sam9g20ek_common.dtsi30
-rw-r--r--arch/arm/boot/dts/at91sam9g25.dtsi28
-rw-r--r--arch/arm/boot/dts/at91sam9g25ek.dts49
-rw-r--r--arch/arm/boot/dts/at91sam9g35.dtsi28
-rw-r--r--arch/arm/boot/dts/at91sam9g35ek.dts16
-rw-r--r--arch/arm/boot/dts/at91sam9g45.dtsi301
-rw-r--r--arch/arm/boot/dts/at91sam9m10g45ek.dts48
-rw-r--r--arch/arm/boot/dts/at91sam9n12.dtsi225
-rw-r--r--arch/arm/boot/dts/at91sam9n12ek.dts22
-rw-r--r--arch/arm/boot/dts/at91sam9x25.dtsi49
-rw-r--r--arch/arm/boot/dts/at91sam9x25ek.dts16
-rw-r--r--arch/arm/boot/dts/at91sam9x35.dtsi28
-rw-r--r--arch/arm/boot/dts/at91sam9x35ek.dts16
-rw-r--r--arch/arm/boot/dts/at91sam9x5.dtsi270
-rw-r--r--arch/arm/boot/dts/at91sam9x5ek.dtsi101
-rw-r--r--arch/arm/boot/dts/imx28.dtsi1
-rw-r--r--arch/arm/boot/dts/pm9g45.dts165
-rw-r--r--arch/arm/boot/dts/spear1310-evb.dts4
-rw-r--r--arch/arm/boot/dts/spear1310.dtsi27
-rw-r--r--arch/arm/boot/dts/spear1340-evb.dts4
-rw-r--r--arch/arm/boot/dts/spear1340.dtsi26
-rw-r--r--arch/arm/boot/dts/spear310.dtsi22
-rw-r--r--arch/arm/boot/dts/spear320-evb.dts4
-rw-r--r--arch/arm/boot/dts/spear320.dtsi23
-rw-r--r--arch/arm/boot/dts/tegra20-seaboard.dts4
-rw-r--r--arch/arm/boot/dts/tegra30.dtsi4
-rw-r--r--arch/arm/common/timer-sp.c2
-rw-r--r--arch/arm/configs/afeb9260_defconfig2
-rw-r--r--arch/arm/configs/at91_dt_defconfig1
-rw-r--r--arch/arm/configs/at91sam9260_defconfig2
-rw-r--r--arch/arm/configs/at91sam9261_defconfig2
-rw-r--r--arch/arm/configs/at91sam9263_defconfig2
-rw-r--r--arch/arm/configs/at91sam9g20_defconfig2
-rw-r--r--arch/arm/configs/corgi_defconfig2
-rw-r--r--arch/arm/configs/davinci_all_defconfig2
-rw-r--r--arch/arm/configs/h7202_defconfig3
-rw-r--r--arch/arm/configs/magician_defconfig2
-rw-r--r--arch/arm/configs/mini2440_defconfig2
-rw-r--r--arch/arm/configs/omap1_defconfig3
-rw-r--r--arch/arm/configs/prima2_defconfig1
-rw-r--r--arch/arm/configs/spitz_defconfig2
-rw-r--r--arch/arm/configs/stamp9g20_defconfig2
-rw-r--r--arch/arm/configs/viper_defconfig2
-rw-r--r--arch/arm/configs/zeus_defconfig2
-rw-r--r--arch/arm/include/asm/Kbuild1
-rw-r--r--arch/arm/include/asm/hardware/sp810.h2
-rw-r--r--arch/arm/include/asm/io.h2
-rw-r--r--arch/arm/include/asm/prom.h2
-rw-r--r--arch/arm/mach-at91/Kconfig9
-rw-r--r--arch/arm/mach-at91/Makefile1
-rw-r--r--arch/arm/mach-at91/at91rm9200.c22
-rw-r--r--arch/arm/mach-at91/at91rm9200_devices.c2
-rw-r--r--arch/arm/mach-at91/at91rm9200_time.c63
-rw-r--r--arch/arm/mach-at91/at91sam9260.c8
-rw-r--r--arch/arm/mach-at91/at91sam9260_devices.c2
-rw-r--r--arch/arm/mach-at91/at91sam9261.c4
-rw-r--r--arch/arm/mach-at91/at91sam9261_devices.c2
-rw-r--r--arch/arm/mach-at91/at91sam9263.c11
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c2
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c12
-rw-r--r--arch/arm/mach-at91/at91sam9g45_devices.c12
-rw-r--r--arch/arm/mach-at91/at91sam9n12.c16
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c4
-rw-r--r--arch/arm/mach-at91/at91sam9x5.c21
-rw-r--r--arch/arm/mach-at91/board-dt.c2
-rw-r--r--arch/arm/mach-at91/board-rm9200-dt.c57
-rw-r--r--arch/arm/mach-at91/generic.h1
-rw-r--r--arch/arm/mach-at91/gpio.c190
-rw-r--r--arch/arm/mach-at91/include/mach/board.h10
-rw-r--r--arch/arm/mach-at91/setup.c20
-rw-r--r--arch/arm/mach-at91/soc.h12
-rw-r--r--arch/arm/mach-cns3xxx/cns3420vb.c53
-rw-r--r--arch/arm/mach-davinci/dm644x.c3
-rw-r--r--arch/arm/mach-dove/include/mach/pm.h2
-rw-r--r--arch/arm/mach-dove/irq.c14
-rw-r--r--arch/arm/mach-exynos/dma.c3
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h1
-rw-r--r--arch/arm/mach-highbank/system.c3
-rw-r--r--arch/arm/mach-imx/clk-gate2.c2
-rw-r--r--arch/arm/mach-imx/ehci-imx25.c2
-rw-r--r--arch/arm/mach-imx/ehci-imx35.c2
-rw-r--r--arch/arm/mach-integrator/impd1.c69
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c1
-rw-r--r--arch/arm/mach-ixp4xx/common.c13
-rw-r--r--arch/arm/mach-ixp4xx/goramo_mlr.c3
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/debug-macro.S4
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h46
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/qmgr.h12
-rw-r--r--arch/arm/mach-ixp4xx/ixp4xx_npe.c9
-rw-r--r--arch/arm/mach-ixp4xx/ixp4xx_qmgr.c12
-rw-r--r--arch/arm/mach-kirkwood/pcie.c11
-rw-r--r--arch/arm/mach-nomadik/board-nhk8815.c3
-rw-r--r--arch/arm/mach-nomadik/cpu-8815.c2
-rw-r--r--arch/arm/mach-nomadik/i2c-8815nhk.c3
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c5
-rw-r--r--arch/arm/mach-omap2/board-overo.c1
-rw-r--r--arch/arm/mach-omap2/clockdomains44xx_data.c2
-rw-r--r--arch/arm/mach-omap2/common-board-devices.c34
-rw-r--r--arch/arm/mach-omap2/devices.c79
-rw-r--r--arch/arm/mach-omap2/drm.c7
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c63
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c36
-rw-r--r--arch/arm/mach-omap2/twl-common.c3
-rw-r--r--arch/arm/mach-omap2/vc.c2
-rw-r--r--arch/arm/mach-pxa/hx4700.c8
-rw-r--r--arch/arm/mach-pxa/spitz_pm.c8
-rw-r--r--arch/arm/mach-shmobile/board-kzm9g.c2
-rw-r--r--arch/arm/mach-u300/core.c5
-rw-r--r--arch/arm/mach-u300/include/mach/irqs.h126
-rw-r--r--arch/arm/mach-ux500/board-mop500-audio.c3
-rw-r--r--arch/arm/mach-ux500/board-mop500-pins.c3
-rw-r--r--arch/arm/mach-ux500/board-mop500.c2
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c12
-rw-r--r--arch/arm/mach-ux500/devices-common.c3
-rw-r--r--arch/arm/mach-ux500/devices-common.h8
-rw-r--r--arch/arm/mach-vexpress/v2m.c2
-rw-r--r--arch/arm/mm/mmap.c134
-rw-r--r--arch/arm/mm/proc-v6.S2
-rw-r--r--arch/arm/plat-nomadik/include/plat/gpio-nomadik.h102
-rw-r--r--arch/arm/plat-omap/i2c.c21
-rw-r--r--arch/arm/plat-omap/include/plat/mmc.h1
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h6
-rw-r--r--arch/arm/plat-omap/include/plat/serial.h9
-rw-r--r--arch/arm/plat-s3c24xx/dma.c9
-rw-r--r--arch/arm/plat-spear/Kconfig1
-rw-r--r--arch/arm/tools/Makefile2
-rw-r--r--arch/arm64/Makefile17
-rw-r--r--arch/arm64/boot/Makefile5
-rw-r--r--arch/arm64/boot/dts/.gitignore1
-rw-r--r--arch/arm64/boot/dts/Makefile5
-rw-r--r--arch/arm64/include/asm/Kbuild1
-rw-r--r--arch/arm64/include/asm/io.h2
-rw-r--r--arch/arm64/include/asm/pgtable-hwdef.h6
-rw-r--r--arch/arm64/include/asm/pgtable.h40
-rw-r--r--arch/arm64/include/asm/unistd32.h2
-rw-r--r--arch/avr32/Kconfig3
-rw-r--r--arch/avr32/configs/atngw100_defconfig2
-rw-r--r--arch/avr32/configs/atngw100_evklcd100_defconfig2
-rw-r--r--arch/avr32/configs/atngw100_evklcd101_defconfig2
-rw-r--r--arch/avr32/configs/atngw100_mrmt_defconfig2
-rw-r--r--arch/avr32/configs/atngw100mkii_defconfig2
-rw-r--r--arch/avr32/configs/atngw100mkii_evklcd100_defconfig2
-rw-r--r--arch/avr32/configs/atngw100mkii_evklcd101_defconfig2
-rw-r--r--arch/avr32/configs/atstk1002_defconfig2
-rw-r--r--arch/avr32/configs/atstk1003_defconfig2
-rw-r--r--arch/avr32/configs/atstk1004_defconfig2
-rw-r--r--arch/avr32/configs/atstk1006_defconfig2
-rw-r--r--arch/avr32/configs/favr-32_defconfig2
-rw-r--r--arch/avr32/configs/hammerhead_defconfig2
-rw-r--r--arch/avr32/include/asm/Kbuild1
-rw-r--r--arch/blackfin/configs/CM-BF527_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF548_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF561_defconfig2
-rw-r--r--arch/blackfin/include/asm/Kbuild1
-rw-r--r--arch/c6x/Makefile2
-rw-r--r--arch/c6x/boot/Makefile20
-rw-r--r--arch/c6x/boot/dts/Makefile20
-rw-r--r--arch/c6x/boot/dts/linked_dtb.S2
-rw-r--r--arch/c6x/boot/linked_dtb.S2
-rw-r--r--arch/c6x/include/asm/Kbuild1
-rw-r--r--arch/c6x/include/asm/setup.h33
-rw-r--r--arch/c6x/include/uapi/asm/Kbuild2
-rw-r--r--arch/c6x/include/uapi/asm/kvm_para.h1
-rw-r--r--arch/c6x/include/uapi/asm/setup.h33
-rw-r--r--arch/c6x/kernel/entry.S5
-rw-r--r--arch/cris/include/asm/Kbuild1
-rw-r--r--arch/frv/include/asm/Kbuild1
-rw-r--r--arch/h8300/include/asm/Kbuild1
-rw-r--r--arch/hexagon/include/asm/Kbuild1
-rw-r--r--arch/ia64/hp/sim/simserial.c1
-rw-r--r--arch/ia64/include/asm/Kbuild1
-rw-r--r--arch/ia64/include/asm/cputime.h2
-rw-r--r--arch/ia64/include/asm/device.h3
-rw-r--r--arch/ia64/include/asm/io.h2
-rw-r--r--arch/ia64/kernel/acpi.c2
-rw-r--r--arch/ia64/kernel/efi.c2
-rw-r--r--arch/ia64/kernel/time.c22
-rw-r--r--arch/ia64/mm/init.c1
-rw-r--r--arch/m32r/include/asm/Kbuild1
-rw-r--r--arch/m68k/emu/nfcon.c6
-rw-r--r--arch/m68k/include/asm/Kbuild1
-rw-r--r--arch/m68k/include/asm/signal.h6
-rw-r--r--arch/microblaze/Makefile2
-rw-r--r--arch/microblaze/boot/Makefile19
-rw-r--r--arch/microblaze/boot/dts/Makefile22
-rw-r--r--arch/microblaze/boot/dts/linked_dtb.S2
-rw-r--r--arch/microblaze/boot/linked_dtb.S3
-rw-r--r--arch/microblaze/include/asm/Kbuild1
-rw-r--r--arch/microblaze/kernel/signal.c2
-rw-r--r--arch/microblaze/pci/pci-common.c4
-rw-r--r--arch/mips/alchemy/common/Makefile2
-rw-r--r--arch/mips/alchemy/common/platform.c58
-rw-r--r--arch/mips/alchemy/common/usb.c (renamed from drivers/usb/host/alchemy-common.c)0
-rw-r--r--arch/mips/ath79/dev-usb.c2
-rw-r--r--arch/mips/cavium-octeon/Makefile3
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-l2c.c1
-rw-r--r--arch/mips/configs/bcm47xx_defconfig2
-rw-r--r--arch/mips/configs/db1000_defconfig1
-rw-r--r--arch/mips/configs/db1235_defconfig2
-rw-r--r--arch/mips/configs/gpr_defconfig1
-rw-r--r--arch/mips/configs/ls1b_defconfig1
-rw-r--r--arch/mips/configs/mtx1_defconfig3
-rw-r--r--arch/mips/fw/arc/misc.c1
-rw-r--r--arch/mips/include/asm/Kbuild1
-rw-r--r--arch/mips/include/asm/bitops.h128
-rw-r--r--arch/mips/include/asm/compat.h2
-rw-r--r--arch/mips/include/asm/hugetlb.h12
-rw-r--r--arch/mips/include/asm/io.h1
-rw-r--r--arch/mips/include/asm/irqflags.h207
-rw-r--r--arch/mips/include/asm/thread_info.h6
-rw-r--r--arch/mips/include/uapi/asm/ioctls.h3
-rw-r--r--arch/mips/include/uapi/asm/mman.h11
-rw-r--r--arch/mips/kernel/cpu-probe.c1
-rw-r--r--arch/mips/kernel/entry.S7
-rw-r--r--arch/mips/kernel/scall64-n32.S6
-rw-r--r--arch/mips/kernel/setup.c26
-rw-r--r--arch/mips/lantiq/dts/Makefile3
-rw-r--r--arch/mips/lib/Makefile5
-rw-r--r--arch/mips/lib/bitops.c179
-rw-r--r--arch/mips/lib/mips-atomic.c176
-rw-r--r--arch/mips/loongson1/common/platform.c7
-rw-r--r--arch/mips/mm/mmap.c111
-rw-r--r--arch/mips/mm/tlb-r4k.c18
-rw-r--r--arch/mips/mti-malta/malta-platform.c3
-rw-r--r--arch/mips/netlogic/dts/Makefile3
-rw-r--r--arch/mips/netlogic/xlr/platform.c17
-rw-r--r--arch/mips/pci/pci.c2
-rw-r--r--arch/mips/pnx8550/common/platform.c31
-rw-r--r--arch/mn10300/include/asm/Kbuild1
-rw-r--r--arch/openrisc/Makefile2
-rw-r--r--arch/openrisc/boot/dts/Makefile (renamed from arch/openrisc/boot/Makefile)5
-rw-r--r--arch/openrisc/include/asm/Kbuild1
-rw-r--r--arch/openrisc/kernel/signal.c6
-rw-r--r--arch/parisc/include/asm/Kbuild1
-rw-r--r--arch/parisc/include/uapi/asm/ioctls.h3
-rw-r--r--arch/parisc/include/uapi/asm/mman.h11
-rw-r--r--arch/parisc/kernel/pdc_cons.c5
-rw-r--r--arch/parisc/kernel/signal32.c6
-rw-r--r--arch/parisc/kernel/sys_parisc.c2
-rw-r--r--arch/parisc/kernel/syscall_table.S2
-rw-r--r--arch/powerpc/boot/dts/mpc5200b.dtsi6
-rw-r--r--arch/powerpc/boot/dts/o2d.dtsi6
-rw-r--r--arch/powerpc/boot/dts/pcm030.dts7
-rw-r--r--arch/powerpc/include/asm/Kbuild1
-rw-r--r--arch/powerpc/include/asm/cputime.h2
-rw-r--r--arch/powerpc/include/uapi/asm/ioctls.h3
-rw-r--r--arch/powerpc/kernel/pci-common.c4
-rw-r--r--arch/powerpc/kernel/pci_64.c4
-rw-r--r--arch/powerpc/kernel/signal.c4
-rw-r--r--arch/powerpc/kernel/sysfs.c4
-rw-r--r--arch/powerpc/kernel/time.c20
-rw-r--r--arch/powerpc/kernel/uprobes.c6
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pic.c9
-rw-r--r--arch/powerpc/platforms/cell/celleb_pci.c4
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_core.c2
-rw-r--r--arch/powerpc/platforms/pseries/eeh_pe.c2
-rw-r--r--arch/powerpc/platforms/pseries/msi.c3
-rw-r--r--arch/powerpc/platforms/pseries/processor_idle.c4
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c3
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c2
-rw-r--r--arch/powerpc/sysdev/scom.c2
-rw-r--r--arch/s390/Kconfig1
-rw-r--r--arch/s390/include/asm/Kbuild1
-rw-r--r--arch/s390/include/asm/compat.h2
-rw-r--r--arch/s390/include/asm/cputime.h1
-rw-r--r--arch/s390/include/asm/page.h3
-rw-r--r--arch/s390/include/asm/topology.h3
-rw-r--r--arch/s390/include/uapi/asm/ptrace.h4
-rw-r--r--arch/s390/kernel/compat_signal.c14
-rw-r--r--arch/s390/kernel/compat_wrapper.S2
-rw-r--r--arch/s390/kernel/signal.c14
-rw-r--r--arch/s390/kernel/topology.c6
-rw-r--r--arch/s390/kernel/vtime.c13
-rw-r--r--arch/s390/kvm/kvm-s390.c4
-rw-r--r--arch/s390/mm/gup.c5
-rw-r--r--arch/score/include/asm/Kbuild1
-rw-r--r--arch/score/kernel/signal.c7
-rw-r--r--arch/sh/configs/ecovec24_defconfig2
-rw-r--r--arch/sh/configs/se7724_defconfig2
-rw-r--r--arch/sh/drivers/pci/pci.c2
-rw-r--r--arch/sh/include/asm/Kbuild1
-rw-r--r--arch/sh/include/asm/io.h2
-rw-r--r--arch/sh/include/uapi/asm/ioctls.h3
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7720.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7757.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7763.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7786.c6
-rw-r--r--arch/sh/kernel/signal_64.c6
-rw-r--r--arch/sh/mm/mmap.c139
-rw-r--r--arch/sparc/boot/piggyback.c12
-rw-r--r--arch/sparc/include/asm/Kbuild1
-rw-r--r--arch/sparc/include/asm/prom.h5
-rw-r--r--arch/sparc/include/uapi/asm/ioctls.h3
-rw-r--r--arch/sparc/kernel/pci_impl.h2
-rw-r--r--arch/sparc/kernel/signal_64.c4
-rw-r--r--arch/sparc/kernel/sys32.S2
-rw-r--r--arch/sparc/kernel/sys_sparc_32.c27
-rw-r--r--arch/sparc/kernel/sys_sparc_64.c150
-rw-r--r--arch/sparc/kernel/syscalls.S14
-rw-r--r--arch/sparc/kernel/systbls_64.S2
-rw-r--r--arch/sparc/mm/hugetlbpage.c124
-rw-r--r--arch/tile/include/asm/Kbuild1
-rw-r--r--arch/tile/mm/hugetlbpage.c139
-rw-r--r--arch/um/drivers/chan_kern.c17
-rw-r--r--arch/um/drivers/line.c2
-rw-r--r--arch/um/drivers/mconsole_kern.c2
-rw-r--r--arch/um/include/asm/Kbuild1
-rw-r--r--arch/um/kernel/exec.c3
-rw-r--r--arch/unicore32/Kconfig7
-rw-r--r--arch/unicore32/include/asm/Kbuild2
-rw-r--r--arch/unicore32/include/asm/bug.h5
-rw-r--r--arch/unicore32/include/asm/cmpxchg.h2
-rw-r--r--arch/unicore32/include/asm/kvm_para.h1
-rw-r--r--arch/unicore32/include/asm/processor.h5
-rw-r--r--arch/unicore32/include/asm/ptrace.h76
-rw-r--r--arch/unicore32/include/uapi/asm/Kbuild7
-rw-r--r--arch/unicore32/include/uapi/asm/byteorder.h (renamed from arch/unicore32/include/asm/byteorder.h)0
-rw-r--r--arch/unicore32/include/uapi/asm/ptrace.h90
-rw-r--r--arch/unicore32/include/uapi/asm/sigcontext.h (renamed from arch/unicore32/include/asm/sigcontext.h)0
-rw-r--r--arch/unicore32/include/uapi/asm/unistd.h (renamed from arch/unicore32/include/asm/unistd.h)1
-rw-r--r--arch/unicore32/kernel/entry.S20
-rw-r--r--arch/unicore32/kernel/pci.c2
-rw-r--r--arch/unicore32/kernel/process.c58
-rw-r--r--arch/unicore32/kernel/setup.h6
-rw-r--r--arch/unicore32/kernel/sys.c63
-rw-r--r--arch/unicore32/mm/fault.c37
-rw-r--r--arch/x86/Kconfig59
-rw-r--r--arch/x86/Kconfig.cpu73
-rw-r--r--arch/x86/Makefile_32.cpu1
-rw-r--r--arch/x86/boot/compressed/eboot.c2
-rw-r--r--arch/x86/boot/header.S3
-rw-r--r--arch/x86/include/asm/Kbuild3
-rw-r--r--arch/x86/include/asm/atomic.h16
-rw-r--r--arch/x86/include/asm/cmpxchg_32.h55
-rw-r--r--arch/x86/include/asm/context_tracking.h (renamed from arch/x86/include/asm/rcu.h)15
-rw-r--r--arch/x86/include/asm/cpu.h4
-rw-r--r--arch/x86/include/asm/cpufeature.h7
-rw-r--r--arch/x86/include/asm/device.h3
-rw-r--r--arch/x86/include/asm/elf.h6
-rw-r--r--arch/x86/include/asm/fpu-internal.h15
-rw-r--r--arch/x86/include/asm/futex.h12
-rw-r--r--arch/x86/include/asm/local.h18
-rw-r--r--arch/x86/include/asm/mman.h3
-rw-r--r--arch/x86/include/asm/module.h2
-rw-r--r--arch/x86/include/asm/msr-index.h2
-rw-r--r--arch/x86/include/asm/percpu.h3
-rw-r--r--arch/x86/include/asm/processor.h35
-rw-r--r--arch/x86/include/asm/ptrace.h24
-rw-r--r--arch/x86/include/asm/smp.h1
-rw-r--r--arch/x86/include/asm/swab.h29
-rw-r--r--arch/x86/include/asm/tlbflush.h3
-rw-r--r--arch/x86/include/asm/trace_clock.h20
-rw-r--r--arch/x86/include/asm/uaccess.h42
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/kernel/acpi/boot.c6
-rw-r--r--arch/x86/kernel/acpi/sleep.c2
-rw-r--r--arch/x86/kernel/apic/apic.c73
-rw-r--r--arch/x86/kernel/apic/io_apic.c35
-rw-r--r--arch/x86/kernel/cpu/amd.c26
-rw-r--r--arch/x86/kernel/cpu/bugs.c41
-rw-r--r--arch/x86/kernel/cpu/common.c5
-rw-r--r--arch/x86/kernel/cpu/intel.c4
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c75
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd.c2
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_intel.c31
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c9
-rw-r--r--arch/x86/kernel/cpu/perf_event.c121
-rw-r--r--arch/x86/kernel/cpu/perf_event.h5
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd.c9
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c9
-rw-r--r--arch/x86/kernel/cpu/perf_event_p6.c2
-rw-r--r--arch/x86/kernel/entry_64.S57
-rw-r--r--arch/x86/kernel/head_32.S22
-rw-r--r--arch/x86/kernel/head_64.S16
-rw-r--r--arch/x86/kernel/hpet.c4
-rw-r--r--arch/x86/kernel/i387.c6
-rw-r--r--arch/x86/kernel/microcode_amd.c8
-rw-r--r--arch/x86/kernel/process.c39
-rw-r--r--arch/x86/kernel/ptrace.c42
-rw-r--r--arch/x86/kernel/rtc.c6
-rw-r--r--arch/x86/kernel/signal.c5
-rw-r--r--arch/x86/kernel/smpboot.c156
-rw-r--r--arch/x86/kernel/sys_x86_64.c151
-rw-r--r--arch/x86/kernel/topology.c101
-rw-r--r--arch/x86/kernel/trace_clock.c21
-rw-r--r--arch/x86/kernel/traps.c2
-rw-r--r--arch/x86/kernel/tsc.c6
-rw-r--r--arch/x86/kernel/uprobes.c54
-rw-r--r--arch/x86/kvm/cpuid.h3
-rw-r--r--arch/x86/kvm/emulate.c3
-rw-r--r--arch/x86/kvm/vmx.c11
-rw-r--r--arch/x86/kvm/x86.c3
-rw-r--r--arch/x86/lib/Makefile1
-rw-r--r--arch/x86/lib/cmpxchg.c54
-rw-r--r--arch/x86/lib/copy_page_64.S120
-rw-r--r--arch/x86/lib/usercopy_32.c57
-rw-r--r--arch/x86/mm/fault.c2
-rw-r--r--arch/x86/mm/hugetlbpage.c130
-rw-r--r--arch/x86/mm/init_32.c5
-rw-r--r--arch/x86/mm/tlb.c10
-rw-r--r--arch/x86/pci/ce4100.c13
-rw-r--r--arch/x86/platform/ce4100/ce4100.c27
-rw-r--r--arch/x86/power/cpu.c82
-rw-r--r--arch/x86/tools/gen-insn-attr-x86.awk6
-rw-r--r--arch/x86/um/Kconfig2
-rw-r--r--arch/x86/vdso/vma.c2
-rw-r--r--arch/x86/xen/Kconfig2
-rw-r--r--arch/xtensa/include/asm/Kbuild1
-rw-r--r--arch/xtensa/include/uapi/asm/ioctls.h3
-rw-r--r--arch/xtensa/include/uapi/asm/mman.h11
-rw-r--r--arch/xtensa/platforms/iss/console.c1
-rw-r--r--block/blk-exec.c8
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acpi/Kconfig6
-rw-r--r--drivers/acpi/Makefile6
-rw-r--r--drivers/acpi/acpi_i2c.c103
-rw-r--r--drivers/acpi/acpi_memhotplug.c193
-rw-r--r--drivers/acpi/acpi_pad.c8
-rw-r--r--drivers/acpi/acpi_platform.c104
-rw-r--r--drivers/acpi/acpica/Makefile3
-rw-r--r--drivers/acpi/acpica/acdebug.h94
-rw-r--r--drivers/acpi/acpica/acdispat.h11
-rw-r--r--drivers/acpi/acpica/acevents.h6
-rw-r--r--drivers/acpi/acpica/acglobal.h73
-rw-r--r--drivers/acpi/acpica/aclocal.h16
-rw-r--r--drivers/acpi/acpica/acmacros.h163
-rw-r--r--drivers/acpi/acpica/acobject.h7
-rw-r--r--drivers/acpi/acpica/acopcode.h6
-rw-r--r--drivers/acpi/acpica/acparser.h3
-rw-r--r--drivers/acpi/acpica/acpredef.h11
-rw-r--r--drivers/acpi/acpica/acstruct.h2
-rw-r--r--drivers/acpi/acpica/acutils.h58
-rw-r--r--drivers/acpi/acpica/amlresrc.h1
-rw-r--r--drivers/acpi/acpica/dscontrol.c2
-rw-r--r--drivers/acpi/acpica/dsfield.c2
-rw-r--r--drivers/acpi/acpica/dsmethod.c6
-rw-r--r--drivers/acpi/acpica/dsmthdat.c14
-rw-r--r--drivers/acpi/acpica/dsobject.c6
-rw-r--r--drivers/acpi/acpica/dsopcode.c3
-rw-r--r--drivers/acpi/acpica/dsutils.c33
-rw-r--r--drivers/acpi/acpica/dswexec.c10
-rw-r--r--drivers/acpi/acpica/dswload2.c4
-rw-r--r--drivers/acpi/acpica/dswstate.c26
-rw-r--r--drivers/acpi/acpica/evgpe.c20
-rw-r--r--drivers/acpi/acpica/evgpeblk.c3
-rw-r--r--drivers/acpi/acpica/evgpeutil.c3
-rw-r--r--drivers/acpi/acpica/evrgnini.c7
-rw-r--r--drivers/acpi/acpica/evxface.c2
-rw-r--r--drivers/acpi/acpica/evxfgpe.c13
-rw-r--r--drivers/acpi/acpica/exconvrt.c4
-rw-r--r--drivers/acpi/acpica/excreate.c9
-rw-r--r--drivers/acpi/acpica/exdebug.c10
-rw-r--r--drivers/acpi/acpica/exdump.c20
-rw-r--r--drivers/acpi/acpica/exfield.c4
-rw-r--r--drivers/acpi/acpica/exfldio.c15
-rw-r--r--drivers/acpi/acpica/exmisc.c5
-rw-r--r--drivers/acpi/acpica/exmutex.c9
-rw-r--r--drivers/acpi/acpica/exnames.c9
-rw-r--r--drivers/acpi/acpica/exoparg1.c11
-rw-r--r--drivers/acpi/acpica/exoparg2.c2
-rw-r--r--drivers/acpi/acpica/exoparg3.c3
-rw-r--r--drivers/acpi/acpica/exoparg6.c5
-rw-r--r--drivers/acpi/acpica/exprep.c13
-rw-r--r--drivers/acpi/acpica/exregion.c3
-rw-r--r--drivers/acpi/acpica/exresnte.c9
-rw-r--r--drivers/acpi/acpica/exresolv.c3
-rw-r--r--drivers/acpi/acpica/exresop.c8
-rw-r--r--drivers/acpi/acpica/exstore.c4
-rw-r--r--drivers/acpi/acpica/exstoren.c11
-rw-r--r--drivers/acpi/acpica/exstorob.c5
-rw-r--r--drivers/acpi/acpica/exsystem.c9
-rw-r--r--drivers/acpi/acpica/exutils.c5
-rw-r--r--drivers/acpi/acpica/hwacpi.c3
-rw-r--r--drivers/acpi/acpica/hwgpe.c4
-rw-r--r--drivers/acpi/acpica/hwpci.c4
-rw-r--r--drivers/acpi/acpica/hwregs.c1
-rw-r--r--drivers/acpi/acpica/hwtimer.c6
-rw-r--r--drivers/acpi/acpica/hwvalid.c1
-rw-r--r--drivers/acpi/acpica/hwxface.c1
-rw-r--r--drivers/acpi/acpica/hwxfsleep.c12
-rw-r--r--drivers/acpi/acpica/nsaccess.c7
-rw-r--r--drivers/acpi/acpica/nsalloc.c4
-rw-r--r--drivers/acpi/acpica/nsdump.c10
-rw-r--r--drivers/acpi/acpica/nsinit.c4
-rw-r--r--drivers/acpi/acpica/nsload.c10
-rw-r--r--drivers/acpi/acpica/nsnames.c2
-rw-r--r--drivers/acpi/acpica/nsobject.c8
-rw-r--r--drivers/acpi/acpica/nsparse.c8
-rw-r--r--drivers/acpi/acpica/nssearch.c17
-rw-r--r--drivers/acpi/acpica/nsutils.c18
-rw-r--r--drivers/acpi/acpica/nswalk.c10
-rw-r--r--drivers/acpi/acpica/nsxfeval.c20
-rw-r--r--drivers/acpi/acpica/nsxfname.c66
-rw-r--r--drivers/acpi/acpica/nsxfobj.c4
-rw-r--r--drivers/acpi/acpica/psargs.c8
-rw-r--r--drivers/acpi/acpica/psloop.c61
-rw-r--r--drivers/acpi/acpica/psopcode.c29
-rw-r--r--drivers/acpi/acpica/psparse.c13
-rw-r--r--drivers/acpi/acpica/psutils.c4
-rw-r--r--drivers/acpi/acpica/rscalc.c14
-rw-r--r--drivers/acpi/acpica/rslist.c4
-rw-r--r--drivers/acpi/acpica/tbfind.c2
-rw-r--r--drivers/acpi/acpica/tbinstal.c2
-rw-r--r--drivers/acpi/acpica/tbutils.c2
-rw-r--r--drivers/acpi/acpica/tbxface.c4
-rw-r--r--drivers/acpi/acpica/tbxfload.c2
-rw-r--r--drivers/acpi/acpica/tbxfroot.c3
-rw-r--r--drivers/acpi/acpica/utcache.c323
-rw-r--r--drivers/acpi/acpica/utclib.c749
-rw-r--r--drivers/acpi/acpica/utdebug.c37
-rw-r--r--drivers/acpi/acpica/utids.c104
-rw-r--r--drivers/acpi/acpica/utmath.c2
-rw-r--r--drivers/acpi/acpica/utmisc.c150
-rw-r--r--drivers/acpi/acpica/utmutex.c14
-rw-r--r--drivers/acpi/acpica/utobject.c8
-rw-r--r--drivers/acpi/acpica/utstate.c2
-rw-r--r--drivers/acpi/acpica/uttrack.c692
-rw-r--r--drivers/acpi/acpica/utxface.c5
-rw-r--r--drivers/acpi/acpica/utxferror.c2
-rw-r--r--drivers/acpi/apei/ghes.c4
-rw-r--r--drivers/acpi/battery.c77
-rw-r--r--drivers/acpi/bus.c21
-rw-r--r--drivers/acpi/container.c27
-rw-r--r--drivers/acpi/device_pm.c668
-rw-r--r--drivers/acpi/dock.c56
-rw-r--r--drivers/acpi/ec.c97
-rw-r--r--drivers/acpi/glue.c56
-rw-r--r--drivers/acpi/hed.c4
-rw-r--r--drivers/acpi/internal.h11
-rw-r--r--drivers/acpi/osl.c22
-rw-r--r--drivers/acpi/pci_irq.c15
-rw-r--r--drivers/acpi/pci_root.c2
-rw-r--r--drivers/acpi/power.c2
-rw-r--r--drivers/acpi/proc.c11
-rw-r--r--drivers/acpi/processor_driver.c74
-rw-r--r--drivers/acpi/processor_idle.c57
-rw-r--r--drivers/acpi/resource.c526
-rw-r--r--drivers/acpi/scan.c154
-rw-r--r--drivers/acpi/sleep.c535
-rw-r--r--drivers/acpi/sysfs.c4
-rw-r--r--drivers/acpi/thermal.c34
-rw-r--r--drivers/acpi/utils.c38
-rw-r--r--drivers/acpi/video.c14
-rw-r--r--drivers/acpi/video_detect.c8
-rw-r--r--drivers/ata/ahci_platform.c2
-rw-r--r--drivers/ata/libata-acpi.c11
-rw-r--r--drivers/ata/libata-core.c4
-rw-r--r--drivers/ata/libata-scsi.c2
-rw-r--r--drivers/ata/pata_arasan_cf.c8
-rw-r--r--drivers/ata/sata_highbank.c4
-rw-r--r--drivers/ata/sata_svw.c35
-rw-r--r--drivers/atm/ambassador.c1
-rw-r--r--drivers/base/Kconfig7
-rw-r--r--drivers/base/attribute_container.c2
-rw-r--r--drivers/base/bus.c14
-rw-r--r--drivers/base/core.c10
-rw-r--r--drivers/base/devres.c4
-rw-r--r--drivers/base/dma-contiguous.c24
-rw-r--r--drivers/base/firmware_class.c52
-rw-r--r--drivers/base/memory.c42
-rw-r--r--drivers/base/node.c78
-rw-r--r--drivers/base/platform.c30
-rw-r--r--drivers/base/power/clock_ops.c6
-rw-r--r--drivers/base/power/domain.c11
-rw-r--r--drivers/base/power/opp.c44
-rw-r--r--drivers/base/power/power.h6
-rw-r--r--drivers/base/power/qos.c323
-rw-r--r--drivers/base/power/sysfs.c94
-rw-r--r--drivers/block/aoe/aoecmd.c2
-rw-r--r--drivers/block/floppy.c5
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c18
-rw-r--r--drivers/block/mtip32xx/mtip32xx.h6
-rw-r--r--drivers/bluetooth/ath3k.c1
-rw-r--r--drivers/bluetooth/btusb.c1
-rw-r--r--drivers/bluetooth/hci_ldisc.c7
-rw-r--r--drivers/bus/omap-ocp2scp.c68
-rw-r--r--drivers/char/agp/ali-agp.c4
-rw-r--r--drivers/char/agp/amd-k7-agp.c4
-rw-r--r--drivers/char/agp/amd64-agp.c2
-rw-r--r--drivers/char/agp/ati-agp.c4
-rw-r--r--drivers/char/agp/efficeon-agp.c2
-rw-r--r--drivers/char/agp/i460-agp.c2
-rw-r--r--drivers/char/agp/intel-agp.c2
-rw-r--r--drivers/char/agp/nvidia-agp.c2
-rw-r--r--drivers/char/agp/sgi-agp.c2
-rw-r--r--drivers/char/agp/sis-agp.c8
-rw-r--r--drivers/char/agp/sworks-agp.c2
-rw-r--r--drivers/char/agp/uninorth-agp.c4
-rw-r--r--drivers/char/agp/via-agp.c4
-rw-r--r--drivers/char/hpet.c5
-rw-r--r--drivers/char/hw_random/Kconfig6
-rw-r--r--drivers/char/hw_random/atmel-rng.c2
-rw-r--r--drivers/char/hw_random/bcm63xx-rng.c2
-rw-r--r--drivers/char/hw_random/exynos-rng.c2
-rw-r--r--drivers/char/hw_random/ixp4xx-rng.c5
-rw-r--r--drivers/char/hw_random/n2-drv.c4
-rw-r--r--drivers/char/hw_random/pasemi-rng.c2
-rw-r--r--drivers/char/hw_random/picoxcell-rng.c2
-rw-r--r--drivers/char/hw_random/ppc4xx-rng.c2
-rw-r--r--drivers/char/hw_random/timeriomem-rng.c2
-rw-r--r--drivers/char/hw_random/virtio-rng.c2
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c32
-rw-r--r--drivers/char/mbcs.c2
-rw-r--r--drivers/char/mem.c10
-rw-r--r--drivers/char/pc8736x_gpio.c3
-rw-r--r--drivers/char/pcmcia/synclink_cs.c5
-rw-r--r--drivers/char/ps3flash.c2
-rw-r--r--drivers/char/raw.c2
-rw-r--r--drivers/char/sonypi.c14
-rw-r--r--drivers/char/tb0219.c6
-rw-r--r--drivers/char/tpm/tpm_i2c_infineon.c6
-rw-r--r--drivers/char/tpm/tpm_ibmvtpm.c6
-rw-r--r--drivers/char/tpm/tpm_infineon.c6
-rw-r--r--drivers/char/tpm/tpm_tis.c6
-rw-r--r--drivers/char/ttyprintk.c4
-rw-r--r--drivers/char/virtio_console.c2
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c14
-rw-r--r--drivers/clk/Kconfig16
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/clk-bcm2835.c8
-rw-r--r--drivers/clk/clk-fixed-rate.c2
-rw-r--r--drivers/clk/clk-max77686.c6
-rw-r--r--drivers/clk/clk-prima2.c84
-rw-r--r--drivers/clk/clk-twl6040.c126
-rw-r--r--drivers/clk/clk-vt8500.c18
-rw-r--r--drivers/clk/clk-wm831x.c40
-rw-r--r--drivers/clk/clk.c154
-rw-r--r--drivers/clk/mxs/clk-imx23.c6
-rw-r--r--drivers/clk/mxs/clk-imx28.c10
-rw-r--r--drivers/clk/spear/clk-aux-synth.c3
-rw-r--r--drivers/clk/spear/clk-vco-pll.c2
-rw-r--r--drivers/clk/spear/clk.c3
-rw-r--r--drivers/clk/spear/spear1310_clock.c106
-rw-r--r--drivers/clk/spear/spear1340_clock.c237
-rw-r--r--drivers/clk/spear/spear3xx_clock.c154
-rw-r--r--drivers/clk/spear/spear6xx_clock.c13
-rw-r--r--drivers/clk/ux500/Makefile3
-rw-r--r--drivers/clk/ux500/abx500-clk.c73
-rw-r--r--drivers/clk/ux500/clk-prcmu.c72
-rw-r--r--drivers/clk/ux500/clk.h12
-rw-r--r--drivers/clk/ux500/u8500_clk.c78
-rw-r--r--drivers/clk/versatile/Makefile3
-rw-r--r--drivers/clk/versatile/clk-icst.c66
-rw-r--r--drivers/clk/versatile/clk-icst.h14
-rw-r--r--drivers/clk/versatile/clk-impd1.c97
-rw-r--r--drivers/clk/versatile/clk-integrator.c55
-rw-r--r--drivers/clk/versatile/clk-realview.c65
-rw-r--r--drivers/clk/versatile/clk-vexpress-osc.c146
-rw-r--r--drivers/clk/versatile/clk-vexpress.c142
-rw-r--r--drivers/clocksource/acpi_pm.c17
-rw-r--r--drivers/clocksource/arm_generic.c6
-rw-r--r--drivers/clocksource/i8253.c2
-rw-r--r--drivers/cpufreq/Kconfig.arm7
-rw-r--r--drivers/cpufreq/Makefile5
-rw-r--r--drivers/cpufreq/cpufreq-cpu0.c2
-rw-r--r--drivers/cpufreq/cpufreq.c37
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c558
-rw-r--r--drivers/cpufreq/cpufreq_governor.c318
-rw-r--r--drivers/cpufreq/cpufreq_governor.h176
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c731
-rw-r--r--drivers/cpufreq/cpufreq_performance.c2
-rw-r--r--drivers/cpufreq/cpufreq_powersave.c2
-rw-r--r--drivers/cpufreq/cpufreq_stats.c4
-rw-r--r--drivers/cpufreq/cpufreq_userspace.c2
-rw-r--r--drivers/cpufreq/db8500-cpufreq.c101
-rw-r--r--drivers/cpufreq/exynos-cpufreq.c11
-rw-r--r--drivers/cpufreq/freq_table.c2
-rw-r--r--drivers/cpufreq/longhaul.c4
-rw-r--r--drivers/cpufreq/powernow-k8.c4
-rw-r--r--drivers/cpufreq/spear-cpufreq.c291
-rw-r--r--drivers/cpuidle/Kconfig9
-rw-r--r--drivers/cpuidle/cpuidle.c55
-rw-r--r--drivers/cpuidle/cpuidle.h13
-rw-r--r--drivers/cpuidle/driver.c209
-rw-r--r--drivers/cpuidle/governors/menu.c168
-rw-r--r--drivers/cpuidle/sysfs.c201
-rw-r--r--drivers/crypto/Kconfig2
-rw-r--r--drivers/crypto/ixp4xx_crypto.c12
-rw-r--r--drivers/devfreq/Kconfig8
-rw-r--r--drivers/devfreq/devfreq.c921
-rw-r--r--drivers/devfreq/exynos4_bus.c45
-rw-r--r--drivers/devfreq/governor.h17
-rw-r--r--drivers/devfreq/governor_performance.c38
-rw-r--r--drivers/devfreq/governor_powersave.c38
-rw-r--r--drivers/devfreq/governor_simpleondemand.c55
-rw-r--r--drivers/devfreq/governor_userspace.c45
-rw-r--r--drivers/dma/dw_dmac.c4
-rw-r--r--drivers/dma/edma.c4
-rw-r--r--drivers/dma/fsldma.c4
-rw-r--r--drivers/dma/intel_mid_dma.c4
-rw-r--r--drivers/dma/ioat/pci.c2
-rw-r--r--drivers/dma/iop-adma.c10
-rw-r--r--drivers/dma/mmp_pdma.c6
-rw-r--r--drivers/dma/mmp_tdma.c6
-rw-r--r--drivers/dma/mpc512x_dma.c4
-rw-r--r--drivers/dma/mv_xor.c8
-rw-r--r--drivers/dma/pch_dma.c4
-rw-r--r--drivers/dma/pl330.c2
-rw-r--r--drivers/dma/ppc4xx/adma.c4
-rw-r--r--drivers/dma/sa11x0-dma.c6
-rw-r--r--drivers/dma/sh/shdma.c6
-rw-r--r--drivers/dma/sirf-dma.c4
-rw-r--r--drivers/dma/tegra20-apb-dma.c4
-rw-r--r--drivers/dma/timb_dma.c2
-rw-r--r--drivers/edac/Kconfig8
-rw-r--r--drivers/edac/amd64_edac.c297
-rw-r--r--drivers/edac/amd64_edac.h61
-rw-r--r--drivers/edac/amd64_edac_inj.c128
-rw-r--r--drivers/edac/edac_mc.c65
-rw-r--r--drivers/edac/edac_mc_sysfs.c39
-rw-r--r--drivers/edac/edac_module.c27
-rw-r--r--drivers/edac/edac_pci.c3
-rw-r--r--drivers/edac/edac_pci_sysfs.c12
-rw-r--r--drivers/edac/edac_stub.c2
-rw-r--r--drivers/edac/highbank_mc_edac.c8
-rw-r--r--drivers/edac/i7300_edac.c8
-rw-r--r--drivers/edac/i7core_edac.c6
-rw-r--r--drivers/edac/i82975x_edac.c11
-rw-r--r--drivers/edac/mce_amd.c254
-rw-r--r--drivers/edac/mce_amd.h11
-rw-r--r--drivers/edac/mce_amd_inj.c4
-rw-r--r--drivers/extcon/extcon-adc-jack.c6
-rw-r--r--drivers/extcon/extcon-arizona.c6
-rw-r--r--drivers/extcon/extcon-gpio.c6
-rw-r--r--drivers/extcon/extcon-max77693.c6
-rw-r--r--drivers/extcon/extcon-max8997.c6
-rw-r--r--drivers/firewire/nosy.c4
-rw-r--r--drivers/firewire/ohci.c2
-rw-r--r--drivers/firewire/sbp2.c2
-rw-r--r--drivers/gpio/Kconfig38
-rw-r--r--drivers/gpio/Makefile5
-rw-r--r--drivers/gpio/gpio-74x164.c6
-rw-r--r--drivers/gpio/gpio-ab8500.c6
-rw-r--r--drivers/gpio/gpio-adnp.c10
-rw-r--r--drivers/gpio/gpio-adp5520.c6
-rw-r--r--drivers/gpio/gpio-adp5588.c6
-rw-r--r--drivers/gpio/gpio-arizona.c6
-rw-r--r--drivers/gpio/gpio-clps711x.c199
-rw-r--r--drivers/gpio/gpio-cs5535.c6
-rw-r--r--drivers/gpio/gpio-da9052.c8
-rw-r--r--drivers/gpio/gpio-da9055.c204
-rw-r--r--drivers/gpio/gpio-em.c54
-rw-r--r--drivers/gpio/gpio-ep93xx.c2
-rw-r--r--drivers/gpio/gpio-generic.c6
-rw-r--r--drivers/gpio/gpio-ich.c10
-rw-r--r--drivers/gpio/gpio-janz-ttl.c10
-rw-r--r--drivers/gpio/gpio-langwell.c8
-rw-r--r--drivers/gpio/gpio-lpc32xx.c4
-rw-r--r--drivers/gpio/gpio-max7300.c6
-rw-r--r--drivers/gpio/gpio-max7301.c6
-rw-r--r--drivers/gpio/gpio-max730x.c16
-rw-r--r--drivers/gpio/gpio-max732x.c8
-rw-r--r--drivers/gpio/gpio-mc33880.c6
-rw-r--r--drivers/gpio/gpio-mcp23s08.c12
-rw-r--r--drivers/gpio/gpio-ml-ioh.c8
-rw-r--r--drivers/gpio/gpio-mpc5200.c4
-rw-r--r--drivers/gpio/gpio-msic.c2
-rw-r--r--drivers/gpio/gpio-msm-v2.c6
-rw-r--r--drivers/gpio/gpio-mvebu.c36
-rw-r--r--drivers/gpio/gpio-mxc.c4
-rw-r--r--drivers/gpio/gpio-mxs.c2
-rw-r--r--drivers/gpio/gpio-omap.c8
-rw-r--r--drivers/gpio/gpio-pca953x.c61
-rw-r--r--drivers/gpio/gpio-pcf857x.c29
-rw-r--r--drivers/gpio/gpio-pch.c9
-rw-r--r--drivers/gpio/gpio-pl061.c66
-rw-r--r--drivers/gpio/gpio-pxa.c6
-rw-r--r--drivers/gpio/gpio-rc5t583.c6
-rw-r--r--drivers/gpio/gpio-rdc321x.c6
-rw-r--r--drivers/gpio/gpio-sch.c6
-rw-r--r--drivers/gpio/gpio-sodaville.c4
-rw-r--r--drivers/gpio/gpio-spear-spics.c217
-rw-r--r--drivers/gpio/gpio-sta2x11.c4
-rw-r--r--drivers/gpio/gpio-stmpe.c94
-rw-r--r--drivers/gpio/gpio-stp-xway.c2
-rw-r--r--drivers/gpio/gpio-sx150x.c6
-rw-r--r--drivers/gpio/gpio-tc3589x.c26
-rw-r--r--drivers/gpio/gpio-tegra.c47
-rw-r--r--drivers/gpio/gpio-timberdale.c4
-rw-r--r--drivers/gpio/gpio-tps6586x.c6
-rw-r--r--drivers/gpio/gpio-tps65910.c6
-rw-r--r--drivers/gpio/gpio-tps65912.c6
-rw-r--r--drivers/gpio/gpio-ts5500.c466
-rw-r--r--drivers/gpio/gpio-twl4030.c43
-rw-r--r--drivers/gpio/gpio-twl6040.c4
-rw-r--r--drivers/gpio/gpio-vr41xx.c6
-rw-r--r--drivers/gpio/gpio-vt8500.c4
-rw-r--r--drivers/gpio/gpio-vx855.c6
-rw-r--r--drivers/gpio/gpio-wm831x.c6
-rw-r--r--drivers/gpio/gpio-wm8350.c6
-rw-r--r--drivers/gpio/gpio-wm8994.c6
-rw-r--r--drivers/gpio/gpio-xilinx.c4
-rw-r--r--drivers/gpio/gpiolib-acpi.c54
-rw-r--r--drivers/gpio/gpiolib-of.c52
-rw-r--r--drivers/gpio/gpiolib.c200
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.c8
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c4
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c1
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c6
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c11
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c11
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c12
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c39
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.c19
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c12
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv40.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv40.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/object.h14
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/clock.h3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c19
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c3
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c48
-rw-r--r--drivers/gpu/drm/radeon/atombios_encoders.c2
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_agp.c5
-rw-r--r--drivers/gpu/drm/ttm/ttm_page_alloc.c5
-rw-r--r--drivers/gpu/drm/ttm/ttm_tt.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c2
-rw-r--r--drivers/hid/hid-microsoft.c6
-rw-r--r--drivers/hv/Kconfig6
-rw-r--r--drivers/hv/Makefile1
-rw-r--r--drivers/hv/channel.c8
-rw-r--r--drivers/hv/channel_mgmt.c8
-rw-r--r--drivers/hv/hv_balloon.c1041
-rw-r--r--drivers/hwmon/Kconfig19
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/abituguru.c12
-rw-r--r--drivers/hwmon/abituguru3.c6
-rw-r--r--drivers/hwmon/ad7314.c6
-rw-r--r--drivers/hwmon/ad7414.c4
-rw-r--r--drivers/hwmon/adcxx.c6
-rw-r--r--drivers/hwmon/ads7828.c247
-rw-r--r--drivers/hwmon/ads7871.c6
-rw-r--r--drivers/hwmon/adt7411.c6
-rw-r--r--drivers/hwmon/coretemp.c68
-rw-r--r--drivers/hwmon/da9052-hwmon.c33
-rw-r--r--drivers/hwmon/da9055-hwmon.c336
-rw-r--r--drivers/hwmon/dme1737.c6
-rw-r--r--drivers/hwmon/f71805f.c8
-rw-r--r--drivers/hwmon/f71882fg.c8
-rw-r--r--drivers/hwmon/fam15h_power.c14
-rw-r--r--drivers/hwmon/gpio-fan.c8
-rw-r--r--drivers/hwmon/hih6130.c6
-rw-r--r--drivers/hwmon/i5k_amb.c18
-rw-r--r--drivers/hwmon/ina2xx.c13
-rw-r--r--drivers/hwmon/it87.c12
-rw-r--r--drivers/hwmon/jz4740-hwmon.c6
-rw-r--r--drivers/hwmon/k10temp.c8
-rw-r--r--drivers/hwmon/k8temp.c8
-rw-r--r--drivers/hwmon/lm70.c6
-rw-r--r--drivers/hwmon/lm78.c6
-rw-r--r--drivers/hwmon/max1111.c8
-rw-r--r--drivers/hwmon/max197.c6
-rw-r--r--drivers/hwmon/mc13783-adc.c4
-rw-r--r--drivers/hwmon/ntc_thermistor.c6
-rw-r--r--drivers/hwmon/pc87360.c8
-rw-r--r--drivers/hwmon/pc87427.c10
-rw-r--r--drivers/hwmon/s3c-hwmon.c6
-rw-r--r--drivers/hwmon/sch5627.c4
-rw-r--r--drivers/hwmon/sch5636.c2
-rw-r--r--drivers/hwmon/sht15.c6
-rw-r--r--drivers/hwmon/sht21.c6
-rw-r--r--drivers/hwmon/sis5595.c16
-rw-r--r--drivers/hwmon/smsc47b397.c6
-rw-r--r--drivers/hwmon/tmp102.c6
-rw-r--r--drivers/hwmon/twl4030-madc-hwmon.c4
-rw-r--r--drivers/hwmon/ultra45_env.c6
-rw-r--r--drivers/hwmon/via-cputemp.c6
-rw-r--r--drivers/hwmon/via686a.c14
-rw-r--r--drivers/hwmon/vt1211.c8
-rw-r--r--drivers/hwmon/vt8231.c12
-rw-r--r--drivers/hwmon/w83627ehf.c12
-rw-r--r--drivers/hwmon/w83627hf.c14
-rw-r--r--drivers/hwmon/w83781d.c6
-rw-r--r--drivers/hwmon/wm831x-hwmon.c6
-rw-r--r--drivers/hwmon/wm8350-hwmon.c6
-rw-r--r--drivers/hwspinlock/omap_hwspinlock.c6
-rw-r--r--drivers/hwspinlock/u8500_hsem.c6
-rw-r--r--drivers/i2c/busses/i2c-at91.c7
-rw-r--r--drivers/i2c/busses/i2c-mxs.c2
-rw-r--r--drivers/i2c/busses/i2c-ocores.c4
-rw-r--r--drivers/i2c/busses/i2c-omap.c36
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c1
-rw-r--r--drivers/i2c/i2c-core.c6
-rw-r--r--drivers/i2c/muxes/i2c-mux-pinctrl.c2
-rw-r--r--drivers/idle/intel_idle.c14
-rw-r--r--drivers/iio/Kconfig13
-rw-r--r--drivers/iio/Makefile8
-rw-r--r--drivers/iio/accel/Kconfig2
-rw-r--r--drivers/iio/accel/hid-sensor-accel-3d.c21
-rw-r--r--drivers/iio/adc/Kconfig65
-rw-r--r--drivers/iio/adc/Makefile6
-rw-r--r--drivers/iio/adc/ad7266.c3
-rw-r--r--drivers/iio/adc/ad7298.c (renamed from drivers/staging/iio/adc/ad7298_core.c)201
-rw-r--r--drivers/iio/adc/ad7476.c2
-rw-r--r--drivers/iio/adc/ad7793.c (renamed from drivers/staging/iio/adc/ad7793.c)390
-rw-r--r--drivers/iio/adc/ad7887.c (renamed from drivers/staging/iio/adc/ad7887_core.c)217
-rw-r--r--drivers/iio/adc/ad_sigma_delta.c2
-rw-r--r--drivers/iio/adc/at91_adc.c6
-rw-r--r--drivers/iio/adc/max1363.c (renamed from drivers/staging/iio/adc/max1363_core.c)330
-rw-r--r--drivers/iio/adc/ti-adc081c.c161
-rw-r--r--drivers/iio/buffer_cb.c113
-rw-r--r--drivers/iio/common/hid-sensors/Kconfig2
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-trigger.c6
-rw-r--r--drivers/iio/dac/Kconfig12
-rw-r--r--drivers/iio/dac/Makefile1
-rw-r--r--drivers/iio/dac/ad5449.c376
-rw-r--r--drivers/iio/dac/ad5686.c2
-rw-r--r--drivers/iio/gyro/Kconfig9
-rw-r--r--drivers/iio/gyro/Makefile1
-rw-r--r--drivers/iio/gyro/adis16136.c580
-rw-r--r--drivers/iio/gyro/hid-sensor-gyro-3d.c21
-rw-r--r--drivers/iio/imu/Kconfig27
-rw-r--r--drivers/iio/imu/Makefile10
-rw-r--r--drivers/iio/imu/adis.c440
-rw-r--r--drivers/iio/imu/adis16480.c924
-rw-r--r--drivers/iio/imu/adis_buffer.c176
-rw-r--r--drivers/iio/imu/adis_trigger.c89
-rw-r--r--drivers/iio/industrialio-buffer.c386
-rw-r--r--drivers/iio/industrialio-core.c105
-rw-r--r--drivers/iio/industrialio-event.c11
-rw-r--r--drivers/iio/inkern.c6
-rw-r--r--drivers/iio/light/adjd_s311.c3
-rw-r--r--drivers/iio/light/hid-sensor-als.c20
-rw-r--r--drivers/iio/magnetometer/hid-sensor-magn-3d.c21
-rw-r--r--drivers/input/input-mt.c4
-rw-r--r--drivers/input/matrix-keymap.c3
-rw-r--r--drivers/input/mousedev.c4
-rw-r--r--drivers/input/touchscreen/ads7846.c6
-rw-r--r--drivers/iommu/intel-iommu.c4
-rw-r--r--drivers/iommu/tegra-smmu.c1
-rw-r--r--drivers/ipack/Kconfig24
-rw-r--r--drivers/ipack/Makefile (renamed from drivers/staging/ipack/Makefile)2
-rw-r--r--drivers/ipack/carriers/Kconfig7
-rw-r--r--drivers/ipack/carriers/Makefile (renamed from drivers/staging/ipack/bridges/Makefile)0
-rw-r--r--drivers/ipack/carriers/tpci200.c (renamed from drivers/staging/ipack/bridges/tpci200.c)321
-rw-r--r--drivers/ipack/carriers/tpci200.h (renamed from drivers/staging/ipack/bridges/tpci200.h)33
-rw-r--r--drivers/ipack/devices/Kconfig (renamed from drivers/staging/ipack/devices/Kconfig)1
-rw-r--r--drivers/ipack/devices/Makefile (renamed from drivers/staging/ipack/devices/Makefile)0
-rw-r--r--drivers/ipack/devices/ipoctal.c (renamed from drivers/staging/ipack/devices/ipoctal.c)129
-rw-r--r--drivers/ipack/devices/ipoctal.h (renamed from drivers/staging/ipack/devices/ipoctal.h)7
-rw-r--r--drivers/ipack/devices/scc2698.h (renamed from drivers/staging/ipack/devices/scc2698.h)7
-rw-r--r--drivers/ipack/ipack.c (renamed from drivers/staging/ipack/ipack.c)64
-rw-r--r--drivers/irqchip/irq-bcm2835.c3
-rw-r--r--drivers/isdn/capi/capi.c36
-rw-r--r--drivers/isdn/gigaset/common.c1
-rw-r--r--drivers/isdn/i4l/isdn_tty.c4
-rw-r--r--drivers/leds/leds-adp5520.c8
-rw-r--r--drivers/leds/leds-asic3.c6
-rw-r--r--drivers/leds/leds-atmel-pwm.c2
-rw-r--r--drivers/leds/leds-bd2802.c2
-rw-r--r--drivers/leds/leds-blinkm.c6
-rw-r--r--drivers/leds/leds-clevo-mail.c2
-rw-r--r--drivers/leds/leds-cobalt-qube.c6
-rw-r--r--drivers/leds/leds-cobalt-raq.c6
-rw-r--r--drivers/leds/leds-da903x.c6
-rw-r--r--drivers/leds/leds-da9052.c6
-rw-r--r--drivers/leds/leds-gpio.c12
-rw-r--r--drivers/leds/leds-lm3530.c6
-rw-r--r--drivers/leds/leds-lm3533.c8
-rw-r--r--drivers/leds/leds-lm355x.c8
-rw-r--r--drivers/leds/leds-lm3642.c8
-rw-r--r--drivers/leds/leds-lp3944.c6
-rw-r--r--drivers/leds/leds-lp5521.c8
-rw-r--r--drivers/leds/leds-lp5523.c4
-rw-r--r--drivers/leds/leds-lp8788.c6
-rw-r--r--drivers/leds/leds-lt3593.c8
-rw-r--r--drivers/leds/leds-max8997.c6
-rw-r--r--drivers/leds/leds-mc13783.c10
-rw-r--r--drivers/leds/leds-netxbig.c10
-rw-r--r--drivers/leds/leds-ns2.c8
-rw-r--r--drivers/leds/leds-ot200.c6
-rw-r--r--drivers/leds/leds-pca955x.c6
-rw-r--r--drivers/leds/leds-pca9633.c6
-rw-r--r--drivers/leds/leds-pwm.c4
-rw-r--r--drivers/leds/leds-rb532.c6
-rw-r--r--drivers/leds/leds-regulator.c6
-rw-r--r--drivers/leds/leds-renesas-tpu.c6
-rw-r--r--drivers/leds/leds-ss4200.c4
-rw-r--r--drivers/leds/leds-sunfire.c12
-rw-r--r--drivers/leds/leds-tca6507.c6
-rw-r--r--drivers/leds/ledtrig-cpu.c21
-rw-r--r--drivers/macintosh/smu.c2
-rw-r--r--drivers/md/dm.c8
-rw-r--r--drivers/md/md.c27
-rw-r--r--drivers/md/raid1.c2
-rw-r--r--drivers/md/raid10.c133
-rw-r--r--drivers/md/raid5.c79
-rw-r--r--drivers/media/dvb-frontends/stv0900_core.c6
-rw-r--r--drivers/media/i2c/adv7604.c377
-rw-r--r--drivers/media/i2c/soc_camera/mt9v022.c11
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-core.c6
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-m2m.c4
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-regs.h16
-rw-r--r--drivers/media/platform/omap3isp/ispccdc.c4
-rw-r--r--drivers/media/platform/omap3isp/ispstat.c4
-rw-r--r--drivers/media/platform/omap3isp/ispstat.h4
-rw-r--r--drivers/media/platform/omap3isp/ispvideo.c2
-rw-r--r--drivers/media/platform/s5p-fimc/Kconfig1
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-capture.c14
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-lite.c10
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-m2m.c3
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-mdevice.c41
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c7
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c2
-rw-r--r--drivers/media/platform/sh_vou.c3
-rw-r--r--drivers/media/platform/soc_camera/mx1_camera.c9
-rw-r--r--drivers/media/platform/soc_camera/mx2_camera.c13
-rw-r--r--drivers/media/platform/soc_camera/mx3_camera.c5
-rw-r--r--drivers/media/platform/soc_camera/omap1_camera.c4
-rw-r--r--drivers/media/platform/soc_camera/pxa_camera.c4
-rw-r--r--drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c13
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_core.c11
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.c4
-rw-r--r--drivers/memstick/host/Kconfig10
-rw-r--r--drivers/memstick/host/Makefile1
-rw-r--r--drivers/memstick/host/rtsx_pci_ms.c641
-rw-r--r--drivers/mfd/88pm800.c12
-rw-r--r--drivers/mfd/88pm805.c10
-rw-r--r--drivers/mfd/88pm80x.c2
-rw-r--r--drivers/mfd/88pm860x-core.c104
-rw-r--r--drivers/mfd/Kconfig10
-rw-r--r--drivers/mfd/Makefile3
-rw-r--r--drivers/mfd/ab3100-core.c13
-rw-r--r--drivers/mfd/ab8500-core.c40
-rw-r--r--drivers/mfd/ab8500-debugfs.c6
-rw-r--r--drivers/mfd/ab8500-gpadc.c6
-rw-r--r--drivers/mfd/ab8500-sysctrl.c6
-rw-r--r--drivers/mfd/adp5520.c6
-rw-r--r--drivers/mfd/arizona-core.c18
-rw-r--r--drivers/mfd/arizona-i2c.c6
-rw-r--r--drivers/mfd/arizona-irq.c1
-rw-r--r--drivers/mfd/arizona-spi.c6
-rw-r--r--drivers/mfd/asic3.c4
-rw-r--r--drivers/mfd/cs5535-mfd.c12
-rw-r--r--drivers/mfd/da903x.c10
-rw-r--r--drivers/mfd/da9052-core.c4
-rw-r--r--drivers/mfd/da9052-i2c.c6
-rw-r--r--drivers/mfd/da9052-spi.c6
-rw-r--r--drivers/mfd/da9055-core.c4
-rw-r--r--drivers/mfd/da9055-i2c.c6
-rw-r--r--drivers/mfd/davinci_voicecodec.c4
-rw-r--r--drivers/mfd/db8500-prcmu.c88
-rw-r--r--drivers/mfd/ezx-pcap.c8
-rw-r--r--drivers/mfd/htc-i2cpld.c12
-rw-r--r--drivers/mfd/intel_msic.c10
-rw-r--r--drivers/mfd/janz-cmodio.c10
-rw-r--r--drivers/mfd/jz4740-adc.c6
-rw-r--r--drivers/mfd/lm3533-core.c18
-rw-r--r--drivers/mfd/lp8788.c4
-rw-r--r--drivers/mfd/lpc_ich.c20
-rw-r--r--drivers/mfd/lpc_sch.c6
-rw-r--r--drivers/mfd/max77686.c2
-rw-r--r--drivers/mfd/max8907.c4
-rw-r--r--drivers/mfd/max8925-core.c58
-rw-r--r--drivers/mfd/max8925-i2c.c6
-rw-r--r--drivers/mfd/mc13xxx-i2c.c4
-rw-r--r--drivers/mfd/mc13xxx-spi.c4
-rw-r--r--drivers/mfd/omap-usb-host.c4
-rw-r--r--drivers/mfd/omap-usb-tll.c6
-rw-r--r--drivers/mfd/palmas.c6
-rw-r--r--drivers/mfd/pcf50633-adc.c6
-rw-r--r--drivers/mfd/pcf50633-core.c6
-rw-r--r--drivers/mfd/pm8921-core.c8
-rw-r--r--drivers/mfd/pm8xxx-irq.c4
-rw-r--r--drivers/mfd/rc5t583.c6
-rw-r--r--drivers/mfd/rdc321x-southbridge.c6
-rw-r--r--drivers/mfd/rtl8411.c251
-rw-r--r--drivers/mfd/rts5209.c223
-rw-r--r--drivers/mfd/rts5229.c205
-rw-r--r--drivers/mfd/rtsx_pcr.c1251
-rw-r--r--drivers/mfd/rtsx_pcr.h (renamed from drivers/staging/rts_pstor/general.h)15
-rw-r--r--drivers/mfd/sm501.c16
-rw-r--r--drivers/mfd/sta2x11-mfd.c20
-rw-r--r--drivers/mfd/stmpe-i2c.c6
-rw-r--r--drivers/mfd/stmpe-spi.c6
-rw-r--r--drivers/mfd/stmpe.c2
-rw-r--r--drivers/mfd/syscon.c6
-rw-r--r--drivers/mfd/tc3589x.c8
-rw-r--r--drivers/mfd/tc6387xb.c6
-rw-r--r--drivers/mfd/tc6393xb.c12
-rw-r--r--drivers/mfd/ti-ssp.c6
-rw-r--r--drivers/mfd/timberdale.c64
-rw-r--r--drivers/mfd/tps6105x.c8
-rw-r--r--drivers/mfd/tps65090.c8
-rw-r--r--drivers/mfd/tps65217.c6
-rw-r--r--drivers/mfd/tps6586x.c10
-rw-r--r--drivers/mfd/tps65910.c10
-rw-r--r--drivers/mfd/tps65911-comparator.c6
-rw-r--r--drivers/mfd/tps65912-spi.c6
-rw-r--r--drivers/mfd/twl-core.c4
-rw-r--r--drivers/mfd/twl4030-audio.c6
-rw-r--r--drivers/mfd/twl4030-irq.c3
-rw-r--r--drivers/mfd/twl4030-madc.c4
-rw-r--r--drivers/mfd/twl4030-power.c20
-rw-r--r--drivers/mfd/vx855.c6
-rw-r--r--drivers/mfd/wl1273-core.c4
-rw-r--r--drivers/mfd/wm5102-tables.c519
-rw-r--r--drivers/mfd/wm831x-spi.c6
-rw-r--r--drivers/mfd/wm8994-core.c16
-rw-r--r--drivers/misc/ad525x_dpot-i2c.c6
-rw-r--r--drivers/misc/ad525x_dpot-spi.c6
-rw-r--r--drivers/misc/ad525x_dpot.c4
-rw-r--r--drivers/misc/apds9802als.c6
-rw-r--r--drivers/misc/apds990x.c6
-rw-r--r--drivers/misc/atmel-ssc.c4
-rw-r--r--drivers/misc/bh1770glc.c6
-rw-r--r--drivers/misc/bh1780gli.c6
-rw-r--r--drivers/misc/bmp085-i2c.c4
-rw-r--r--drivers/misc/bmp085-spi.c4
-rw-r--r--drivers/misc/bmp085.c2
-rw-r--r--drivers/misc/cb710/core.c10
-rw-r--r--drivers/misc/cs5535-mfgpt.c6
-rw-r--r--drivers/misc/eeprom/at24.c4
-rw-r--r--drivers/misc/eeprom/at25.c4
-rw-r--r--drivers/misc/eeprom/eeprom_93xx46.c6
-rw-r--r--drivers/misc/fsa9480.c6
-rw-r--r--drivers/misc/hpilo.c21
-rw-r--r--drivers/misc/ibmasm/module.c6
-rw-r--r--drivers/misc/ioc4.c10
-rw-r--r--drivers/misc/isl29003.c6
-rw-r--r--drivers/misc/lis3lv02d/lis3lv02d_i2c.c6
-rw-r--r--drivers/misc/lis3lv02d/lis3lv02d_spi.c6
-rw-r--r--drivers/misc/mei/Makefile1
-rw-r--r--drivers/misc/mei/amthif.c722
-rw-r--r--drivers/misc/mei/hw.h36
-rw-r--r--drivers/misc/mei/init.c368
-rw-r--r--drivers/misc/mei/interface.c91
-rw-r--r--drivers/misc/mei/interrupt.c760
-rw-r--r--drivers/misc/mei/iorw.c455
-rw-r--r--drivers/misc/mei/main.c462
-rw-r--r--drivers/misc/mei/mei_dev.h155
-rw-r--r--drivers/misc/mei/wd.c15
-rw-r--r--drivers/misc/pch_phub.c6
-rw-r--r--drivers/misc/phantom.c10
-rw-r--r--drivers/misc/pti.c15
-rw-r--r--drivers/misc/spear13xx_pcie_gadget.c4
-rw-r--r--drivers/misc/ti-st/st_core.c1
-rw-r--r--drivers/misc/ti-st/st_kim.c30
-rw-r--r--drivers/misc/ti_dac7512.c6
-rw-r--r--drivers/misc/tsl2550.c6
-rw-r--r--drivers/mmc/card/block.c81
-rw-r--r--drivers/mmc/card/queue.c17
-rw-r--r--drivers/mmc/card/sdio_uart.c24
-rw-r--r--drivers/mmc/core/bus.c3
-rw-r--r--drivers/mmc/core/core.c32
-rw-r--r--drivers/mmc/core/debugfs.c16
-rw-r--r--drivers/mmc/core/mmc.c19
-rw-r--r--drivers/mmc/core/mmc_ops.c11
-rw-r--r--drivers/mmc/core/sdio_bus.c17
-rw-r--r--drivers/mmc/core/sdio_io.c10
-rw-r--r--drivers/mmc/core/sdio_ops.c32
-rw-r--r--drivers/mmc/core/slot-gpio.c8
-rw-r--r--drivers/mmc/host/Kconfig52
-rw-r--r--drivers/mmc/host/Makefile5
-rw-r--r--drivers/mmc/host/at91_mci.c1219
-rw-r--r--drivers/mmc/host/at91_mci.h115
-rw-r--r--drivers/mmc/host/atmel-mci.c2
-rw-r--r--drivers/mmc/host/au1xmmc.c4
-rw-r--r--drivers/mmc/host/bfin_sdh.c6
-rw-r--r--drivers/mmc/host/cb710-mmc.c6
-rw-r--r--drivers/mmc/host/dw_mmc-pci.c6
-rw-r--r--drivers/mmc/host/dw_mmc-pltfm.c20
-rw-r--r--drivers/mmc/host/dw_mmc-pltfm.h2
-rw-r--r--drivers/mmc/host/dw_mmc.c86
-rw-r--r--drivers/mmc/host/jz4740_mmc.c12
-rw-r--r--drivers/mmc/host/mmc_spi.c6
-rw-r--r--drivers/mmc/host/mmci.c10
-rw-r--r--drivers/mmc/host/mxcmmc.c2
-rw-r--r--drivers/mmc/host/mxs-mmc.c31
-rw-r--r--drivers/mmc/host/omap.c8
-rw-r--r--drivers/mmc/host/omap_hsmmc.c183
-rw-r--r--drivers/mmc/host/pxamci.c4
-rw-r--r--drivers/mmc/host/rtsx_pci_sdmmc.c1348
-rw-r--r--drivers/mmc/host/s3cmci.c6
-rw-r--r--drivers/mmc/host/sdhci-acpi.c312
-rw-r--r--drivers/mmc/host/sdhci-cns3xxx.c6
-rw-r--r--drivers/mmc/host/sdhci-dove.c116
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c64
-rw-r--r--drivers/mmc/host/sdhci-of-esdhc.c60
-rw-r--r--drivers/mmc/host/sdhci-of-hlwd.c6
-rw-r--r--drivers/mmc/host/sdhci-pci.c15
-rw-r--r--drivers/mmc/host/sdhci-pltfm.c9
-rw-r--r--drivers/mmc/host/sdhci-pxav2.c6
-rw-r--r--drivers/mmc/host/sdhci-pxav3.c19
-rw-r--r--drivers/mmc/host/sdhci-s3c.c75
-rw-r--r--drivers/mmc/host/sdhci-spear.c21
-rw-r--r--drivers/mmc/host/sdhci-tegra.c10
-rw-r--r--drivers/mmc/host/sdhci.c79
-rw-r--r--drivers/mmc/host/sdhci.h5
-rw-r--r--drivers/mmc/host/sh_mmcif.c18
-rw-r--r--drivers/mmc/host/sh_mobile_sdhi.c12
-rw-r--r--drivers/mmc/host/tmio_mmc.c6
-rw-r--r--drivers/mmc/host/tmio_mmc_pio.c2
-rw-r--r--drivers/mmc/host/via-sdmmc.c6
-rw-r--r--drivers/mmc/host/vub300.c1
-rw-r--r--drivers/mmc/host/wbsd.c28
-rw-r--r--drivers/mmc/host/wmt-sdmmc.c1029
-rw-r--r--drivers/mtd/devices/slram.c2
-rw-r--r--drivers/mtd/mtdcore.c6
-rw-r--r--drivers/mtd/nand/atmel_nand.c9
-rw-r--r--drivers/mtd/nand/nand_base.c10
-rw-r--r--drivers/mtd/nand/sh_flctl.c4
-rw-r--r--drivers/mtd/ofpart.c2
-rw-r--r--drivers/mtd/onenand/onenand_base.c2
-rw-r--r--drivers/mtd/ubi/wl.c26
-rw-r--r--drivers/net/bonding/bond_main.c100
-rw-r--r--drivers/net/bonding/bond_sysfs.c36
-rw-r--r--drivers/net/can/usb/peak_usb/pcan_usb.c8
-rw-r--r--drivers/net/can/usb/peak_usb/pcan_usb_pro.c8
-rw-r--r--drivers/net/ethernet/8390/ne.c1
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c11
-rw-r--r--drivers/net/ethernet/jme.c28
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c2
-rw-r--r--drivers/net/ethernet/micrel/ksz884x.c16
-rw-r--r--drivers/net/ethernet/realtek/8139cp.c33
-rw-r--r--drivers/net/ethernet/sis/sis900.c2
-rw-r--r--drivers/net/ethernet/smsc/smsc911x.c17
-rw-r--r--drivers/net/ethernet/tile/tilegx.c2
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_axienet_main.c14
-rw-r--r--drivers/net/ethernet/xscale/ixp4xx_eth.c8
-rw-r--r--drivers/net/irda/sir_dev.c2
-rw-r--r--drivers/net/phy/mdio-bitbang.c1
-rw-r--r--drivers/net/phy/mdio-gpio.c11
-rw-r--r--drivers/net/team/team.c4
-rw-r--r--drivers/net/team/team_mode_broadcast.c6
-rw-r--r--drivers/net/usb/cdc_ncm.c22
-rw-r--r--drivers/net/usb/hso.c5
-rw-r--r--drivers/net/usb/qmi_wwan.c1
-rw-r--r--drivers/net/usb/smsc95xx.c4
-rw-r--r--drivers/net/vxlan.c10
-rw-r--r--drivers/net/wan/ixp4xx_hss.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c16
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rxon.c12
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c23
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c8
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c11
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c11
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c1
-rw-r--r--drivers/net/xen-netfront.c98
-rw-r--r--drivers/nfc/pn533.c25
-rw-r--r--drivers/of/base.c128
-rw-r--r--drivers/of/fdt.c18
-rw-r--r--drivers/of/of_i2c.c2
-rw-r--r--drivers/of/of_mdio.c2
-rw-r--r--drivers/of/pdt.c12
-rw-r--r--drivers/parport/Kconfig16
-rw-r--r--drivers/pci/Makefile7
-rw-r--r--drivers/pci/hotplug.c37
-rw-r--r--drivers/pci/hotplug/cpcihp_zt5550.c4
-rw-r--r--drivers/pci/ioapic.c6
-rw-r--r--drivers/pci/pci-acpi.c79
-rw-r--r--drivers/pci/pci-driver.c42
-rw-r--r--drivers/pci/pci-sysfs.c7
-rw-r--r--drivers/pci/pci.c4
-rw-r--r--drivers/pci/pci.h5
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c4
-rw-r--r--drivers/pci/pcie/portdrv_pci.c2
-rw-r--r--drivers/pci/probe.c20
-rw-r--r--drivers/pci/quirks.c132
-rw-r--r--drivers/pci/xen-pcifront.c10
-rw-r--r--drivers/pcmcia/bcm63xx_pcmcia.c12
-rw-r--r--drivers/pcmcia/bfin_cf_pcmcia.c6
-rw-r--r--drivers/pcmcia/db1xxx_ss.c6
-rw-r--r--drivers/pcmcia/ds.c13
-rw-r--r--drivers/pcmcia/electra_cf.c4
-rw-r--r--drivers/pcmcia/i82092.c6
-rw-r--r--drivers/pcmcia/pd6729.c8
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c2
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c6
-rw-r--r--drivers/pcmcia/sa1100_assabet.c2
-rw-r--r--drivers/pcmcia/sa1100_cerf.c2
-rw-r--r--drivers/pcmcia/sa1100_generic.c4
-rw-r--r--drivers/pcmcia/sa1100_h3600.c2
-rw-r--r--drivers/pcmcia/sa1100_shannon.c2
-rw-r--r--drivers/pcmcia/sa1100_simpad.c2
-rw-r--r--drivers/pcmcia/sa1111_generic.c4
-rw-r--r--drivers/pcmcia/sa1111_jornada720.c2
-rw-r--r--drivers/pcmcia/vrc4171_card.c8
-rw-r--r--drivers/pcmcia/vrc4173_cardu.c8
-rw-r--r--drivers/pcmcia/xxs1500_ss.c6
-rw-r--r--drivers/pcmcia/yenta_socket.c6
-rw-r--r--drivers/pinctrl/Kconfig52
-rw-r--r--drivers/pinctrl/Makefile7
-rw-r--r--drivers/pinctrl/core.c58
-rw-r--r--drivers/pinctrl/core.h2
-rw-r--r--drivers/pinctrl/devicetree.c11
-rw-r--r--drivers/pinctrl/mvebu/Kconfig24
-rw-r--r--drivers/pinctrl/mvebu/Makefile5
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-armada-370.c (renamed from drivers/pinctrl/pinctrl-armada-370.c)0
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-armada-xp.c (renamed from drivers/pinctrl/pinctrl-armada-xp.c)0
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-dove.c (renamed from drivers/pinctrl/pinctrl-dove.c)0
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-kirkwood.c (renamed from drivers/pinctrl/pinctrl-kirkwood.c)0
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-mvebu.c (renamed from drivers/pinctrl/pinctrl-mvebu.c)1
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-mvebu.h (renamed from drivers/pinctrl/pinctrl-mvebu.h)0
-rw-r--r--drivers/pinctrl/pinconf-generic.c1
-rw-r--r--drivers/pinctrl/pinctrl-at91.c1634
-rw-r--r--drivers/pinctrl/pinctrl-bcm2835.c10
-rw-r--r--drivers/pinctrl/pinctrl-coh901.c175
-rw-r--r--drivers/pinctrl/pinctrl-exynos.c1
-rw-r--r--drivers/pinctrl/pinctrl-falcon.c2
-rw-r--r--drivers/pinctrl/pinctrl-imx.c6
-rw-r--r--drivers/pinctrl/pinctrl-imx23.c4
-rw-r--r--drivers/pinctrl/pinctrl-imx28.c4
-rw-r--r--drivers/pinctrl/pinctrl-imx35.c4
-rw-r--r--drivers/pinctrl/pinctrl-imx51.c4
-rw-r--r--drivers/pinctrl/pinctrl-imx53.c4
-rw-r--r--drivers/pinctrl/pinctrl-imx6q.c4
-rw-r--r--drivers/pinctrl/pinctrl-lantiq.c23
-rw-r--r--drivers/pinctrl/pinctrl-mmp2.c4
-rw-r--r--drivers/pinctrl/pinctrl-mxs.c4
-rw-r--r--drivers/pinctrl/pinctrl-nomadik-db8500.c125
-rw-r--r--drivers/pinctrl/pinctrl-nomadik-db8540.c16
-rw-r--r--drivers/pinctrl/pinctrl-nomadik.c152
-rw-r--r--drivers/pinctrl/pinctrl-nomadik.h2
-rw-r--r--drivers/pinctrl/pinctrl-pxa168.c4
-rw-r--r--drivers/pinctrl/pinctrl-pxa3xx.c12
-rw-r--r--drivers/pinctrl/pinctrl-pxa3xx.h2
-rw-r--r--drivers/pinctrl/pinctrl-pxa910.c4
-rw-r--r--drivers/pinctrl/pinctrl-single.c96
-rw-r--r--drivers/pinctrl/pinctrl-sirf.c54
-rw-r--r--drivers/pinctrl/pinctrl-tegra.c26
-rw-r--r--drivers/pinctrl/pinctrl-tegra20.c4
-rw-r--r--drivers/pinctrl/pinctrl-tegra30.c4
-rw-r--r--drivers/pinctrl/pinctrl-u300.c101
-rw-r--r--drivers/pinctrl/pinctrl-xway.c2
-rw-r--r--drivers/pinctrl/pinmux.c85
-rw-r--r--drivers/pinctrl/spear/Kconfig11
-rw-r--r--drivers/pinctrl/spear/Makefile1
-rw-r--r--drivers/pinctrl/spear/pinctrl-plgpio.c758
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear.c133
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear.h62
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear1310.c270
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear1340.c33
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear300.c8
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear310.c8
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear320.c8
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear3xx.c37
-rw-r--r--drivers/pnp/base.h2
-rw-r--r--drivers/pnp/pnpacpi/core.c9
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c296
-rw-r--r--drivers/pnp/pnpbios/core.c20
-rw-r--r--drivers/pnp/resource.c16
-rw-r--r--drivers/power/88pm860x_battery.c6
-rw-r--r--drivers/power/88pm860x_charger.c6
-rw-r--r--drivers/power/ab8500_btemp.c6
-rw-r--r--drivers/power/ab8500_charger.c6
-rw-r--r--drivers/power/ab8500_fg.c6
-rw-r--r--drivers/power/abx500_chargalg.c6
-rw-r--r--drivers/power/avs/smartreflex.c8
-rw-r--r--drivers/power/bq27x00_battery.c6
-rw-r--r--drivers/power/charger-manager.c4
-rw-r--r--drivers/power/collie_battery.c6
-rw-r--r--drivers/power/da9052-battery.c6
-rw-r--r--drivers/power/ds2780_battery.c6
-rw-r--r--drivers/power/ds2781_battery.c6
-rw-r--r--drivers/power/generic-adc-battery.c6
-rw-r--r--drivers/power/gpio-charger.c6
-rw-r--r--drivers/power/intel_mid_battery.c8
-rw-r--r--drivers/power/isp1704_charger.c6
-rw-r--r--drivers/power/jz4740-battery.c6
-rw-r--r--drivers/power/lp8727_charger.c4
-rw-r--r--drivers/power/lp8788-charger.c6
-rw-r--r--drivers/power/max17040_battery.c6
-rw-r--r--drivers/power/max17042_battery.c6
-rw-r--r--drivers/power/max8903_charger.c6
-rw-r--r--drivers/power/max8925_power.c10
-rw-r--r--drivers/power/max8997_charger.c6
-rw-r--r--drivers/power/max8998_charger.c6
-rw-r--r--drivers/power/olpc_battery.c6
-rw-r--r--drivers/power/pcf50633-charger.c6
-rw-r--r--drivers/power/s3c_adc_battery.c2
-rw-r--r--drivers/power/sbs-battery.c6
-rw-r--r--drivers/power/smb347-charger.c2
-rw-r--r--drivers/power/tosa_battery.c6
-rw-r--r--drivers/power/wm831x_backup.c6
-rw-r--r--drivers/power/wm831x_power.c6
-rw-r--r--drivers/power/wm8350_power.c6
-rw-r--r--drivers/power/wm97xx_battery.c6
-rw-r--r--drivers/power/z2_battery.c6
-rw-r--r--drivers/ptp/ptp_pch.c4
-rw-r--r--drivers/pwm/pwm-ab8500.c6
-rw-r--r--drivers/pwm/pwm-bfin.c4
-rw-r--r--drivers/pwm/pwm-imx.c6
-rw-r--r--drivers/pwm/pwm-jz4740.c6
-rw-r--r--drivers/pwm/pwm-lpc32xx.c4
-rw-r--r--drivers/pwm/pwm-mxs.c4
-rw-r--r--drivers/pwm/pwm-puv3.c6
-rw-r--r--drivers/pwm/pwm-pxa.c6
-rw-r--r--drivers/pwm/pwm-samsung.c4
-rw-r--r--drivers/pwm/pwm-tegra.c4
-rw-r--r--drivers/pwm/pwm-tiecap.c6
-rw-r--r--drivers/pwm/pwm-tiehrpwm.c6
-rw-r--r--drivers/pwm/pwm-twl6030.c2
-rw-r--r--drivers/rapidio/devices/tsi721.c4
-rw-r--r--drivers/rapidio/devices/tsi721.h2
-rw-r--r--drivers/rapidio/devices/tsi721_dma.c2
-rw-r--r--drivers/rapidio/rio-scan.c14
-rw-r--r--drivers/rapidio/rio.c8
-rw-r--r--drivers/regulator/core.c33
-rw-r--r--drivers/remoteproc/remoteproc_virtio.c18
-rw-r--r--drivers/rtc/rtc-tps65910.c6
-rw-r--r--drivers/s390/char/con3215.c13
-rw-r--r--drivers/s390/char/sclp_tty.c4
-rw-r--r--drivers/s390/char/sclp_vt220.c2
-rw-r--r--drivers/s390/char/tty3270.c2
-rw-r--r--drivers/s390/net/qeth_core_main.c24
-rw-r--r--drivers/s390/net/qeth_l2_main.c13
-rw-r--r--drivers/scsi/isci/request.c2
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h2
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c14
-rw-r--r--drivers/scsi/scsi.c45
-rw-r--r--drivers/scsi/scsi_lib.c22
-rw-r--r--drivers/scsi/sd.c202
-rw-r--r--drivers/scsi/sd.h7
-rw-r--r--drivers/spi/spi.c105
-rw-r--r--drivers/staging/Kconfig10
-rw-r--r--drivers/staging/Makefile5
-rw-r--r--drivers/staging/android/Makefile2
-rw-r--r--drivers/staging/android/android_alarm.h4
-rw-r--r--drivers/staging/android/binder.c471
-rw-r--r--drivers/staging/android/binder_trace.h327
-rw-r--r--drivers/staging/android/logger.c21
-rw-r--r--drivers/staging/android/lowmemorykiller.c16
-rw-r--r--drivers/staging/bcm/Adapter.h8
-rw-r--r--drivers/staging/bcm/Bcmchar.c149
-rw-r--r--drivers/staging/bcm/Bcmnet.c6
-rw-r--r--drivers/staging/bcm/CmHost.c90
-rw-r--r--drivers/staging/bcm/CmHost.h189
-rw-r--r--drivers/staging/bcm/HandleControlPacket.c2
-rw-r--r--drivers/staging/bcm/HostMIBSInterface.h384
-rw-r--r--drivers/staging/bcm/InterfaceAdapter.h142
-rw-r--r--drivers/staging/bcm/InterfaceDld.c4
-rw-r--r--drivers/staging/bcm/InterfaceIdleMode.c2
-rw-r--r--drivers/staging/bcm/InterfaceIdleMode.h5
-rw-r--r--drivers/staging/bcm/InterfaceInit.c25
-rw-r--r--drivers/staging/bcm/InterfaceInit.h4
-rw-r--r--drivers/staging/bcm/InterfaceIsr.c6
-rw-r--r--drivers/staging/bcm/InterfaceIsr.h4
-rw-r--r--drivers/staging/bcm/InterfaceMisc.c124
-rw-r--r--drivers/staging/bcm/InterfaceMisc.h6
-rw-r--r--drivers/staging/bcm/InterfaceRx.c16
-rw-r--r--drivers/staging/bcm/InterfaceRx.h2
-rw-r--r--drivers/staging/bcm/InterfaceTx.c14
-rw-r--r--drivers/staging/bcm/Ioctl.h482
-rw-r--r--drivers/staging/bcm/LeakyBucket.c6
-rw-r--r--drivers/staging/bcm/Misc.c236
-rw-r--r--drivers/staging/bcm/Prototypes.h36
-rw-r--r--drivers/staging/bcm/Transmit.c2
-rw-r--r--drivers/staging/bcm/cntrl_SignalingInterface.h256
-rw-r--r--drivers/staging/bcm/hostmibs.c12
-rw-r--r--drivers/staging/bcm/nvm.c94
-rw-r--r--drivers/staging/bcm/vendorspecificextn.c6
-rw-r--r--drivers/staging/bcm/vendorspecificextn.h6
-rw-r--r--drivers/staging/ccg/ccg.c8
-rw-r--r--drivers/staging/ccg/u_serial.c5
-rw-r--r--drivers/staging/ced1401/ced_ioc.c37
-rw-r--r--drivers/staging/ced1401/usb1401.c36
-rw-r--r--drivers/staging/ced1401/usb1401.h2
-rw-r--r--drivers/staging/ced1401/userspace/use1401.c8
-rw-r--r--drivers/staging/comedi/Kconfig45
-rw-r--r--drivers/staging/comedi/comedi.h65
-rw-r--r--drivers/staging/comedi/comedi_compat32.c1
-rw-r--r--drivers/staging/comedi/comedi_fops.c5
-rw-r--r--drivers/staging/comedi/comedidev.h70
-rw-r--r--drivers/staging/comedi/drivers.c144
-rw-r--r--drivers/staging/comedi/drivers/8255.c27
-rw-r--r--drivers/staging/comedi/drivers/8255_pci.c26
-rw-r--r--drivers/staging/comedi/drivers/Makefile2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c205
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h73
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c245
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h74
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c44
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h46
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c886
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h271
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c39
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h47
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c278
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h76
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c41
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h43
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c50
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h57
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c38
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h44
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h469
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.c2036
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.h32
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_eeprom.c1367
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c69
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h71
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c116
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h109
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c287
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h64
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c197
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h165
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c542
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h65
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c469
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h121
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c57
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h79
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c460
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h72
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c579
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h83
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c392
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h61
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c1704
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h249
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c2777
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h191
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c320
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h98
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c414
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h48
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_035.c72
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1032.c396
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1500.c72
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1516.c348
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1564.c69
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_16xx.c72
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1710.c153
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2016.c9
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2032.c381
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2200.c64
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3001.c9
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3120.c273
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3200.c119
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3300.c5
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3501.c70
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3xxx.c794
-rw-r--r--drivers/staging/comedi/drivers/adl_pci6208.c23
-rw-r--r--drivers/staging/comedi/drivers/adl_pci7x3x.c15
-rw-r--r--drivers/staging/comedi/drivers/adl_pci8164.c27
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9111.c81
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c494
-rw-r--r--drivers/staging/comedi/drivers/adq12b.c46
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1710.c73
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1723.c24
-rw-r--r--drivers/staging/comedi/drivers/adv_pci_dio.c25
-rw-r--r--drivers/staging/comedi/drivers/aio_aio12_8.c8
-rw-r--r--drivers/staging/comedi/drivers/aio_iiro_16.c19
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.c1468
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236.c72
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc263.c23
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci224.c93
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci230.c157
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c69
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas.c106
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas64.c3009
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidda.c681
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdas.c121
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdda.c25
-rw-r--r--drivers/staging/comedi/drivers/comedi_bond.c8
-rw-r--r--drivers/staging/comedi/drivers/comedi_fc.c2
-rw-r--r--drivers/staging/comedi/drivers/comedi_fc.h44
-rw-r--r--drivers/staging/comedi/drivers/comedi_parport.c35
-rw-r--r--drivers/staging/comedi/drivers/comedi_test.c71
-rw-r--r--drivers/staging/comedi/drivers/contec_pci_dio.c15
-rw-r--r--drivers/staging/comedi/drivers/daqboard2000.c23
-rw-r--r--drivers/staging/comedi/drivers/das08.c39
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c9
-rw-r--r--drivers/staging/comedi/drivers/das16.c78
-rw-r--r--drivers/staging/comedi/drivers/das16m1.c80
-rw-r--r--drivers/staging/comedi/drivers/das1800.c66
-rw-r--r--drivers/staging/comedi/drivers/das6402.c16
-rw-r--r--drivers/staging/comedi/drivers/das800.c79
-rw-r--r--drivers/staging/comedi/drivers/dmm32at.c80
-rw-r--r--drivers/staging/comedi/drivers/dt2801.c14
-rw-r--r--drivers/staging/comedi/drivers/dt2811.c13
-rw-r--r--drivers/staging/comedi/drivers/dt2814.c54
-rw-r--r--drivers/staging/comedi/drivers/dt2815.c9
-rw-r--r--drivers/staging/comedi/drivers/dt282x.c115
-rw-r--r--drivers/staging/comedi/drivers/dt3000.c620
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c27
-rw-r--r--drivers/staging/comedi/drivers/dyna_pci10xx.c27
-rw-r--r--drivers/staging/comedi/drivers/fl512.c10
-rw-r--r--drivers/staging/comedi/drivers/gsc_hpdi.c515
-rw-r--r--drivers/staging/comedi/drivers/icp_multi.c22
-rw-r--r--drivers/staging/comedi/drivers/ii_pci20kc.c51
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.c658
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.h12
-rw-r--r--drivers/staging/comedi/drivers/ke_counter.c60
-rw-r--r--drivers/staging/comedi/drivers/me4000.c42
-rw-r--r--drivers/staging/comedi/drivers/me_daq.c595
-rw-r--r--drivers/staging/comedi/drivers/mpc624.c10
-rw-r--r--drivers/staging/comedi/drivers/mpc8260cpm.c164
-rw-r--r--drivers/staging/comedi/drivers/multiq3.c11
-rw-r--r--drivers/staging/comedi/drivers/ni_6527.c64
-rw-r--r--drivers/staging/comedi/drivers/ni_65xx.c164
-rw-r--r--drivers/staging/comedi/drivers/ni_660x.c586
-rw-r--r--drivers/staging/comedi/drivers/ni_670x.c24
-rw-r--r--drivers/staging/comedi/drivers/ni_at_a2150.c64
-rw-r--r--drivers/staging/comedi/drivers/ni_at_ao.c13
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio.c11
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio16d.c58
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_dio24.c14
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c114
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_cs.c6
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c336
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_cs.c29
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c85
-rw-r--r--drivers/staging/comedi/drivers/ni_pcimio.c62
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.h4
-rw-r--r--drivers/staging/comedi/drivers/ni_tiocmd.c60
-rw-r--r--drivers/staging/comedi/drivers/pcl711.c51
-rw-r--r--drivers/staging/comedi/drivers/pcl726.c10
-rw-r--r--drivers/staging/comedi/drivers/pcl812.c85
-rw-r--r--drivers/staging/comedi/drivers/pcl816.c71
-rw-r--r--drivers/staging/comedi/drivers/pcl818.c80
-rw-r--r--drivers/staging/comedi/drivers/pcm3724.c44
-rw-r--r--drivers/staging/comedi/drivers/pcm_common.c34
-rw-r--r--drivers/staging/comedi/drivers/pcmad.c10
-rw-r--r--drivers/staging/comedi/drivers/pcmda12.c34
-rw-r--r--drivers/staging/comedi/drivers/pcmmio.c124
-rw-r--r--drivers/staging/comedi/drivers/pcmuio.c25
-rw-r--r--drivers/staging/comedi/drivers/poc.c15
-rw-r--r--drivers/staging/comedi/drivers/quatech_daqp_cs.c95
-rw-r--r--drivers/staging/comedi/drivers/rtd520.c950
-rw-r--r--drivers/staging/comedi/drivers/rtd520.h267
-rw-r--r--drivers/staging/comedi/drivers/rti800.c13
-rw-r--r--drivers/staging/comedi/drivers/rti802.c9
-rw-r--r--drivers/staging/comedi/drivers/s526.c8
-rw-r--r--drivers/staging/comedi/drivers/s626.c129
-rw-r--r--drivers/staging/comedi/drivers/serial2002.c44
-rw-r--r--drivers/staging/comedi/drivers/skel.c610
-rw-r--r--drivers/staging/comedi/drivers/ssv_dnp.c26
-rw-r--r--drivers/staging/comedi/drivers/unioxx5.c44
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c125
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c211
-rw-r--r--drivers/staging/comedi/drivers/usbduxsigma.c116
-rw-r--r--drivers/staging/comedi/drivers/vmk80xx.c20
-rw-r--r--drivers/staging/comedi/kcomedilib/kcomedilib_main.c6
-rw-r--r--drivers/staging/comedi/proc.c1
-rw-r--r--drivers/staging/crystalhd/crystalhd_cmds.c8
-rw-r--r--drivers/staging/crystalhd/crystalhd_lnx.c14
-rw-r--r--drivers/staging/crystalhd/crystalhd_misc.c2
-rw-r--r--drivers/staging/csr/Makefile3
-rw-r--r--drivers/staging/csr/bh.c19
-rw-r--r--drivers/staging/csr/csr_framework_ext.c97
-rw-r--r--drivers/staging/csr/csr_framework_ext.h213
-rw-r--r--drivers/staging/csr/csr_framework_ext_types.h41
-rw-r--r--drivers/staging/csr/csr_lib.h188
-rw-r--r--drivers/staging/csr/csr_log.h172
-rw-r--r--drivers/staging/csr/csr_log_configure.h105
-rw-r--r--drivers/staging/csr/csr_log_text.h8
-rw-r--r--drivers/staging/csr/csr_macro.h75
-rw-r--r--drivers/staging/csr/csr_msg_transport.h8
-rw-r--r--drivers/staging/csr/csr_msgconv.c1
-rw-r--r--drivers/staging/csr/csr_msgconv.h9
-rw-r--r--drivers/staging/csr/csr_panic.c20
-rw-r--r--drivers/staging/csr/csr_panic.h53
-rw-r--r--drivers/staging/csr/csr_prim_defs.h7
-rw-r--r--drivers/staging/csr/csr_result.h8
-rw-r--r--drivers/staging/csr/csr_sched.h215
-rw-r--r--drivers/staging/csr/csr_sdio.h8
-rw-r--r--drivers/staging/csr/csr_serialize_primitive_types.c1
-rw-r--r--drivers/staging/csr/csr_time.c9
-rw-r--r--drivers/staging/csr/csr_time.h82
-rw-r--r--drivers/staging/csr/csr_wifi_common.h8
-rw-r--r--drivers/staging/csr/csr_wifi_fsm.h8
-rw-r--r--drivers/staging/csr/csr_wifi_fsm_event.h8
-rw-r--r--drivers/staging/csr/csr_wifi_fsm_types.h10
-rw-r--r--drivers/staging/csr/csr_wifi_hip_card.h9
-rw-r--r--drivers/staging/csr/csr_wifi_hip_card_sdio.c162
-rw-r--r--drivers/staging/csr/csr_wifi_hip_card_sdio.h8
-rw-r--r--drivers/staging/csr/csr_wifi_hip_chiphelper.h64
-rw-r--r--drivers/staging/csr/csr_wifi_hip_chiphelper_private.h8
-rw-r--r--drivers/staging/csr/csr_wifi_hip_conversions.h8
-rw-r--r--drivers/staging/csr/csr_wifi_hip_download.c18
-rw-r--r--drivers/staging/csr/csr_wifi_hip_dump.c32
-rw-r--r--drivers/staging/csr/csr_wifi_hip_send.c2
-rw-r--r--drivers/staging/csr/csr_wifi_hip_signals.h17
-rw-r--r--drivers/staging/csr/csr_wifi_hip_sigs.h8
-rw-r--r--drivers/staging/csr/csr_wifi_hip_ta_sampling.h9
-rw-r--r--drivers/staging/csr/csr_wifi_hip_unifi.h10
-rw-r--r--drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c45
-rw-r--r--drivers/staging/csr/csr_wifi_hip_unifi_udi.h9
-rw-r--r--drivers/staging/csr/csr_wifi_hip_unifihw.h8
-rw-r--r--drivers/staging/csr/csr_wifi_hip_unifiversion.h8
-rw-r--r--drivers/staging/csr/csr_wifi_hip_xbv.c2
-rw-r--r--drivers/staging/csr/csr_wifi_hip_xbv.h8
-rw-r--r--drivers/staging/csr/csr_wifi_hostio_prim.h9
-rw-r--r--drivers/staging/csr/csr_wifi_lib.h9
-rw-r--r--drivers/staging/csr/csr_wifi_msgconv.h9
-rw-r--r--drivers/staging/csr/csr_wifi_nme_ap_converter_init.h8
-rw-r--r--drivers/staging/csr/csr_wifi_nme_ap_lib.h28
-rw-r--r--drivers/staging/csr/csr_wifi_nme_ap_prim.h9
-rw-r--r--drivers/staging/csr/csr_wifi_nme_ap_sef.h10
-rw-r--r--drivers/staging/csr/csr_wifi_nme_ap_serialize.h9
-rw-r--r--drivers/staging/csr/csr_wifi_nme_converter_init.h8
-rw-r--r--drivers/staging/csr/csr_wifi_nme_lib.h63
-rw-r--r--drivers/staging/csr/csr_wifi_nme_prim.h9
-rw-r--r--drivers/staging/csr/csr_wifi_nme_serialize.h8
-rw-r--r--drivers/staging/csr/csr_wifi_nme_task.h11
-rw-r--r--drivers/staging/csr/csr_wifi_private_common.h8
-rw-r--r--drivers/staging/csr/csr_wifi_result.h8
-rw-r--r--drivers/staging/csr/csr_wifi_router_converter_init.h8
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h8
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_lib.h10
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_prim.h9
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_sef.c67
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_sef.h7
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_serialize.h8
-rw-r--r--drivers/staging/csr/csr_wifi_router_free_upstream_contents.c46
-rw-r--r--drivers/staging/csr/csr_wifi_router_lib.h10
-rw-r--r--drivers/staging/csr/csr_wifi_router_prim.h9
-rw-r--r--drivers/staging/csr/csr_wifi_router_sef.h8
-rw-r--r--drivers/staging/csr/csr_wifi_router_serialize.h8
-rw-r--r--drivers/staging/csr/csr_wifi_router_task.h8
-rw-r--r--drivers/staging/csr/csr_wifi_sme_ap_lib.h9
-rw-r--r--drivers/staging/csr/csr_wifi_sme_ap_prim.h8
-rw-r--r--drivers/staging/csr/csr_wifi_sme_converter_init.h8
-rw-r--r--drivers/staging/csr/csr_wifi_sme_lib.h10
-rw-r--r--drivers/staging/csr/csr_wifi_sme_prim.h9
-rw-r--r--drivers/staging/csr/csr_wifi_sme_sef.h213
-rw-r--r--drivers/staging/csr/csr_wifi_sme_serialize.h336
-rw-r--r--drivers/staging/csr/csr_wifi_sme_task.h16
-rw-r--r--drivers/staging/csr/csr_wifi_vif_utils.h81
-rw-r--r--drivers/staging/csr/data_tx.c45
-rw-r--r--drivers/staging/csr/drv.c101
-rw-r--r--drivers/staging/csr/firmware.c15
-rw-r--r--drivers/staging/csr/inet.c10
-rw-r--r--drivers/staging/csr/io.c102
-rw-r--r--drivers/staging/csr/mlme.c3
-rw-r--r--drivers/staging/csr/monitor.c10
-rw-r--r--drivers/staging/csr/netdev.c90
-rw-r--r--drivers/staging/csr/os.c18
-rw-r--r--drivers/staging/csr/sdio_mmc.c28
-rw-r--r--drivers/staging/csr/sme_blocking.c307
-rw-r--r--drivers/staging/csr/sme_native.c21
-rw-r--r--drivers/staging/csr/sme_sys.c17
-rw-r--r--drivers/staging/csr/sme_userspace.h2
-rw-r--r--drivers/staging/csr/sme_wext.c49
-rw-r--r--drivers/staging/csr/ul_int.c1
-rw-r--r--drivers/staging/csr/unifi_event.c8
-rw-r--r--drivers/staging/csr/unifi_os.h23
-rw-r--r--drivers/staging/csr/unifi_pdu_processing.c39
-rw-r--r--drivers/staging/csr/unifi_priv.h7
-rw-r--r--drivers/staging/csr/unifi_sme.c15
-rw-r--r--drivers/staging/csr/unifi_wext.h1
-rw-r--r--drivers/staging/cxt1e1/musycc.c2162
-rw-r--r--drivers/staging/cxt1e1/musycc.h236
-rw-r--r--drivers/staging/cxt1e1/sbecrc.c105
-rw-r--r--drivers/staging/dgrp/dgrp_common.h1
-rw-r--r--drivers/staging/dgrp/dgrp_dpa_ops.c2
-rw-r--r--drivers/staging/dgrp/dgrp_driver.c4
-rw-r--r--drivers/staging/dgrp/dgrp_net_ops.c78
-rw-r--r--drivers/staging/dgrp/dgrp_specproc.c4
-rw-r--r--drivers/staging/dgrp/dgrp_sysfs.c21
-rw-r--r--drivers/staging/dgrp/dgrp_tty.c39
-rw-r--r--drivers/staging/et131x/README2
-rw-r--r--drivers/staging/et131x/et131x.c1323
-rw-r--r--drivers/staging/et131x/et131x.h4
-rw-r--r--drivers/staging/ft1000/ft1000-usb/ft1000_proc.c4
-rw-r--r--drivers/staging/fwserial/Kconfig9
-rw-r--r--drivers/staging/fwserial/Makefile2
-rw-r--r--drivers/staging/fwserial/TODO37
-rw-r--r--drivers/staging/fwserial/dma_fifo.c307
-rw-r--r--drivers/staging/fwserial/dma_fifo.h130
-rw-r--r--drivers/staging/fwserial/fwserial.c2943
-rw-r--r--drivers/staging/fwserial/fwserial.h387
-rw-r--r--drivers/staging/gdm72xx/gdm_qos.c33
-rw-r--r--drivers/staging/gdm72xx/gdm_sdio.c29
-rw-r--r--drivers/staging/gdm72xx/gdm_usb.c64
-rw-r--r--drivers/staging/gdm72xx/gdm_wimax.c70
-rw-r--r--drivers/staging/gdm72xx/netlink_k.c23
-rw-r--r--drivers/staging/gdm72xx/sdio_boot.c100
-rw-r--r--drivers/staging/gdm72xx/usb_boot.c49
-rw-r--r--drivers/staging/iio/accel/Kconfig21
-rw-r--r--drivers/staging/iio/accel/Makefile5
-rw-r--r--drivers/staging/iio/accel/adis16201.h89
-rw-r--r--drivers/staging/iio/accel/adis16201_core.c476
-rw-r--r--drivers/staging/iio/accel/adis16201_ring.c136
-rw-r--r--drivers/staging/iio/accel/adis16201_trigger.c71
-rw-r--r--drivers/staging/iio/accel/adis16203.h80
-rw-r--r--drivers/staging/iio/accel/adis16203_core.c432
-rw-r--r--drivers/staging/iio/accel/adis16203_ring.c136
-rw-r--r--drivers/staging/iio/accel/adis16203_trigger.c73
-rw-r--r--drivers/staging/iio/accel/adis16204.h79
-rw-r--r--drivers/staging/iio/accel/adis16204_core.c462
-rw-r--r--drivers/staging/iio/accel/adis16204_ring.c134
-rw-r--r--drivers/staging/iio/accel/adis16204_trigger.c73
-rw-r--r--drivers/staging/iio/accel/adis16209.h77
-rw-r--r--drivers/staging/iio/accel/adis16209_core.c496
-rw-r--r--drivers/staging/iio/accel/adis16209_ring.c134
-rw-r--r--drivers/staging/iio/accel/adis16209_trigger.c81
-rw-r--r--drivers/staging/iio/accel/adis16220.h20
-rw-r--r--drivers/staging/iio/accel/adis16220_core.c288
-rw-r--r--drivers/staging/iio/accel/adis16240.h85
-rw-r--r--drivers/staging/iio/accel/adis16240_core.c481
-rw-r--r--drivers/staging/iio/accel/adis16240_ring.c132
-rw-r--r--drivers/staging/iio/accel/adis16240_trigger.c82
-rw-r--r--drivers/staging/iio/accel/kxsd9.c10
-rw-r--r--drivers/staging/iio/accel/lis3l02dq.h1
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_core.c16
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_ring.c6
-rw-r--r--drivers/staging/iio/accel/sca3000_core.c6
-rw-r--r--drivers/staging/iio/adc/Kconfig73
-rw-r--r--drivers/staging/iio/adc/Makefile15
-rw-r--r--drivers/staging/iio/adc/ad7192.c6
-rw-r--r--drivers/staging/iio/adc/ad7280a.c8
-rw-r--r--drivers/staging/iio/adc/ad7291.c6
-rw-r--r--drivers/staging/iio/adc/ad7298.h75
-rw-r--r--drivers/staging/iio/adc/ad7298_ring.c113
-rw-r--r--drivers/staging/iio/adc/ad7606_par.c6
-rw-r--r--drivers/staging/iio/adc/ad7606_ring.c2
-rw-r--r--drivers/staging/iio/adc/ad7606_spi.c6
-rw-r--r--drivers/staging/iio/adc/ad7780.c6
-rw-r--r--drivers/staging/iio/adc/ad7793.h115
-rw-r--r--drivers/staging/iio/adc/ad7816.c6
-rw-r--r--drivers/staging/iio/adc/ad7887.h99
-rw-r--r--drivers/staging/iio/adc/ad7887_ring.c122
-rw-r--r--drivers/staging/iio/adc/ad799x_core.c6
-rw-r--r--drivers/staging/iio/adc/ad799x_ring.c2
-rw-r--r--drivers/staging/iio/adc/adt7310.c881
-rw-r--r--drivers/staging/iio/adc/adt7410.c460
-rw-r--r--drivers/staging/iio/adc/lpc32xx_adc.c8
-rw-r--r--drivers/staging/iio/adc/max1363.h177
-rw-r--r--drivers/staging/iio/adc/max1363_ring.c139
-rw-r--r--drivers/staging/iio/adc/mxs-lradc.c11
-rw-r--r--drivers/staging/iio/adc/spear_adc.c6
-rw-r--r--drivers/staging/iio/addac/adt7316-i2c.c6
-rw-r--r--drivers/staging/iio/addac/adt7316-spi.c6
-rw-r--r--drivers/staging/iio/addac/adt7316.c4
-rw-r--r--drivers/staging/iio/cdc/ad7150.c18
-rw-r--r--drivers/staging/iio/cdc/ad7152.c8
-rw-r--r--drivers/staging/iio/cdc/ad7746.c8
-rw-r--r--drivers/staging/iio/frequency/ad5930.c6
-rw-r--r--drivers/staging/iio/frequency/ad9832.c6
-rw-r--r--drivers/staging/iio/frequency/ad9834.c6
-rw-r--r--drivers/staging/iio/frequency/ad9850.c6
-rw-r--r--drivers/staging/iio/frequency/ad9852.c6
-rw-r--r--drivers/staging/iio/frequency/ad9910.c6
-rw-r--r--drivers/staging/iio/frequency/ad9951.c6
-rw-r--r--drivers/staging/iio/gyro/Makefile1
-rw-r--r--drivers/staging/iio/gyro/adis16060_core.c12
-rw-r--r--drivers/staging/iio/gyro/adis16080_core.c6
-rw-r--r--drivers/staging/iio/gyro/adis16130_core.c6
-rw-r--r--drivers/staging/iio/gyro/adis16260.h84
-rw-r--r--drivers/staging/iio/gyro/adis16260_core.c496
-rw-r--r--drivers/staging/iio/gyro/adis16260_ring.c136
-rw-r--r--drivers/staging/iio/gyro/adis16260_trigger.c75
-rw-r--r--drivers/staging/iio/gyro/adxrs450_core.c6
-rw-r--r--drivers/staging/iio/iio_dummy_evgen.c2
-rw-r--r--drivers/staging/iio/iio_hwmon.c6
-rw-r--r--drivers/staging/iio/iio_simple_dummy.c2
-rw-r--r--drivers/staging/iio/iio_simple_dummy_buffer.c5
-rw-r--r--drivers/staging/iio/impedance-analyzer/ad5933.c10
-rw-r--r--drivers/staging/iio/imu/adis16400.h12
-rw-r--r--drivers/staging/iio/imu/adis16400_core.c161
-rw-r--r--drivers/staging/iio/imu/adis16400_ring.c5
-rw-r--r--drivers/staging/iio/light/isl29018.c53
-rw-r--r--drivers/staging/iio/light/isl29028.c6
-rw-r--r--drivers/staging/iio/light/tsl2563.c10
-rw-r--r--drivers/staging/iio/light/tsl2583.c6
-rw-r--r--drivers/staging/iio/light/tsl2x7x_core.c6
-rw-r--r--drivers/staging/iio/magnetometer/ak8975.c6
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843.c8
-rw-r--r--drivers/staging/iio/meter/ade7753.c6
-rw-r--r--drivers/staging/iio/meter/ade7753.h2
-rw-r--r--drivers/staging/iio/meter/ade7754.c6
-rw-r--r--drivers/staging/iio/meter/ade7754.h2
-rw-r--r--drivers/staging/iio/meter/ade7758.h3
-rw-r--r--drivers/staging/iio/meter/ade7758_core.c6
-rw-r--r--drivers/staging/iio/meter/ade7758_ring.c2
-rw-r--r--drivers/staging/iio/meter/ade7759.c6
-rw-r--r--drivers/staging/iio/meter/ade7759.h2
-rw-r--r--drivers/staging/iio/meter/ade7854-i2c.c6
-rw-r--r--drivers/staging/iio/meter/ade7854-spi.c6
-rw-r--r--drivers/staging/iio/meter/ade7854.h2
-rw-r--r--drivers/staging/iio/resolver/ad2s1200.c6
-rw-r--r--drivers/staging/iio/resolver/ad2s1210.c8
-rw-r--r--drivers/staging/iio/resolver/ad2s90.c6
-rw-r--r--drivers/staging/iio/trigger/iio-trig-bfin-timer.c6
-rw-r--r--drivers/staging/iio/trigger/iio-trig-gpio.c6
-rw-r--r--drivers/staging/iio/trigger/iio-trig-periodic-rtc.c6
-rw-r--r--drivers/staging/imx-drm/Kconfig2
-rw-r--r--drivers/staging/imx-drm/imx-drm-core.c2
-rw-r--r--drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h2
-rw-r--r--drivers/staging/imx-drm/ipu-v3/ipu-common.c67
-rw-r--r--drivers/staging/imx-drm/ipuv3-crtc.c8
-rw-r--r--drivers/staging/imx-drm/parallel-display.c16
-rw-r--r--drivers/staging/ipack/Kconfig21
-rw-r--r--drivers/staging/ipack/TODO22
-rw-r--r--drivers/staging/ipack/bridges/Kconfig8
-rw-r--r--drivers/staging/ipack/ipack_ids.h32
-rw-r--r--drivers/staging/line6/Kconfig37
-rw-r--r--drivers/staging/line6/Makefile2
-rw-r--r--drivers/staging/line6/audio.c8
-rw-r--r--drivers/staging/line6/capture.c13
-rw-r--r--drivers/staging/line6/control.c995
-rw-r--r--drivers/staging/line6/control.h195
-rw-r--r--drivers/staging/line6/driver.c85
-rw-r--r--drivers/staging/line6/driver.h10
-rw-r--r--drivers/staging/line6/dumprequest.c135
-rw-r--r--drivers/staging/line6/dumprequest.h76
-rw-r--r--drivers/staging/line6/midi.c126
-rw-r--r--drivers/staging/line6/midi.h10
-rw-r--r--drivers/staging/line6/midibuf.c6
-rw-r--r--drivers/staging/line6/pcm.c4
-rw-r--r--drivers/staging/line6/pcm.h2
-rw-r--r--drivers/staging/line6/playback.c17
-rw-r--r--drivers/staging/line6/pod.c879
-rw-r--r--drivers/staging/line6/pod.h105
-rw-r--r--drivers/staging/line6/toneport.c8
-rw-r--r--drivers/staging/line6/usbdefs.h10
-rw-r--r--drivers/staging/line6/variax.c484
-rw-r--r--drivers/staging/line6/variax.h60
-rw-r--r--drivers/staging/media/dt3155v4l/dt3155v4l.c12
-rw-r--r--drivers/staging/media/lirc/lirc_parallel.c6
-rw-r--r--drivers/staging/media/lirc/lirc_serial.c6
-rw-r--r--drivers/staging/media/lirc/lirc_sir.c6
-rw-r--r--drivers/staging/media/solo6x10/core.c4
-rw-r--r--drivers/staging/net/pc300_drv.c6
-rw-r--r--drivers/staging/nvec/Kconfig1
-rw-r--r--drivers/staging/nvec/nvec.c8
-rw-r--r--drivers/staging/nvec/nvec_kbd.c6
-rw-r--r--drivers/staging/nvec/nvec_paz00.c6
-rw-r--r--drivers/staging/nvec/nvec_power.c6
-rw-r--r--drivers/staging/nvec/nvec_ps2.c6
-rw-r--r--drivers/staging/octeon/ethernet.c12
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon.c85
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon.h2
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c30
-rw-r--r--drivers/staging/omap-thermal/omap-bandgap.c67
-rw-r--r--drivers/staging/omap-thermal/omap-bandgap.h9
-rw-r--r--drivers/staging/omap-thermal/omap-thermal-common.c69
-rw-r--r--drivers/staging/omapdrm/Kconfig2
-rw-r--r--drivers/staging/omapdrm/omap_connector.c8
-rw-r--r--drivers/staging/omapdrm/omap_crtc.c8
-rw-r--r--drivers/staging/omapdrm/omap_dmm_priv.h9
-rw-r--r--drivers/staging/omapdrm/omap_dmm_tiler.c108
-rw-r--r--drivers/staging/omapdrm/omap_dmm_tiler.h8
-rw-r--r--drivers/staging/omapdrm/omap_drv.c73
-rw-r--r--drivers/staging/omapdrm/omap_drv.h14
-rw-r--r--drivers/staging/omapdrm/omap_encoder.c7
-rw-r--r--drivers/staging/omapdrm/omap_fb.c25
-rw-r--r--drivers/staging/omapdrm/omap_gem.c46
-rw-r--r--drivers/staging/omapdrm/omap_gem_dmabuf.c4
-rw-r--r--drivers/staging/omapdrm/omap_gem_helpers.c6
-rw-r--r--drivers/staging/omapdrm/omap_plane.c42
-rw-r--r--drivers/staging/ozwpan/ozevent.c2
-rw-r--r--drivers/staging/ozwpan/ozhcd.c7
-rw-r--r--drivers/staging/ozwpan/ozpd.c6
-rw-r--r--drivers/staging/ozwpan/ozproto.c3
-rw-r--r--drivers/staging/panel/panel.c8
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211.h6
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c24
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h2
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c38
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c18
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_module.c23
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c321
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c121
-rw-r--r--drivers/staging/rtl8187se/r8180.h28
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c496
-rw-r--r--drivers/staging/rtl8187se/r8180_dm.h4
-rw-r--r--drivers/staging/rtl8187se/r8180_rtl8225.h4
-rw-r--r--drivers/staging/rtl8187se/r8180_rtl8225z2.c229
-rw-r--r--drivers/staging/rtl8187se/r8180_wx.c2
-rw-r--r--drivers/staging/rtl8187se/r8185b_init.c239
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_core.c15
-rw-r--r--drivers/staging/rtl8192e/rtllib.h6
-rw-r--r--drivers/staging/rtl8192e/rtllib_tx.c2
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211.h5
-rw-r--r--drivers/staging/rtl8192u/r8192U_core.c8
-rw-r--r--drivers/staging/rtl8712/mlme_linux.c2
-rw-r--r--drivers/staging/rtl8712/rtl871x_cmd.c4
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl_linux.c4
-rw-r--r--drivers/staging/rts5139/Makefile22
-rw-r--r--drivers/staging/rts5139/ms.c96
-rw-r--r--drivers/staging/rts5139/ms.h18
-rw-r--r--drivers/staging/rts5139/ms_mg.c104
-rw-r--r--drivers/staging/rts5139/ms_mg.h14
-rw-r--r--drivers/staging/rts5139/rts51x.c10
-rw-r--r--drivers/staging/rts5139/rts51x_card.c80
-rw-r--r--drivers/staging/rts5139/rts51x_card.h30
-rw-r--r--drivers/staging/rts5139/rts51x_chip.c24
-rw-r--r--drivers/staging/rts5139/rts51x_chip.h16
-rw-r--r--drivers/staging/rts5139/rts51x_fop.c6
-rw-r--r--drivers/staging/rts5139/rts51x_scsi.c238
-rw-r--r--drivers/staging/rts5139/rts51x_scsi.h6
-rw-r--r--drivers/staging/rts5139/sd.c36
-rw-r--r--drivers/staging/rts5139/sd.h12
-rw-r--r--drivers/staging/rts5139/sd_cprm.c124
-rw-r--r--drivers/staging/rts5139/sd_cprm.h18
-rw-r--r--drivers/staging/rts5139/xd.c58
-rw-r--r--drivers/staging/rts5139/xd.h10
-rw-r--r--drivers/staging/rts_pstor/Kconfig16
-rw-r--r--drivers/staging/rts_pstor/Makefile16
-rw-r--r--drivers/staging/rts_pstor/TODO9
-rw-r--r--drivers/staging/rts_pstor/general.c35
-rw-r--r--drivers/staging/rts_pstor/ms.c4051
-rw-r--r--drivers/staging/rts_pstor/ms.h225
-rw-r--r--drivers/staging/rts_pstor/rtsx.c1105
-rw-r--r--drivers/staging/rts_pstor/rtsx.h186
-rw-r--r--drivers/staging/rts_pstor/rtsx_card.c1233
-rw-r--r--drivers/staging/rts_pstor/rtsx_card.h1093
-rw-r--r--drivers/staging/rts_pstor/rtsx_chip.c2264
-rw-r--r--drivers/staging/rts_pstor/rtsx_chip.h989
-rw-r--r--drivers/staging/rts_pstor/rtsx_scsi.c3137
-rw-r--r--drivers/staging/rts_pstor/rtsx_scsi.h142
-rw-r--r--drivers/staging/rts_pstor/rtsx_sys.h50
-rw-r--r--drivers/staging/rts_pstor/rtsx_transport.c769
-rw-r--r--drivers/staging/rts_pstor/rtsx_transport.h66
-rw-r--r--drivers/staging/rts_pstor/sd.c4570
-rw-r--r--drivers/staging/rts_pstor/sd.h300
-rw-r--r--drivers/staging/rts_pstor/spi.c812
-rw-r--r--drivers/staging/rts_pstor/spi.h65
-rw-r--r--drivers/staging/rts_pstor/trace.h93
-rw-r--r--drivers/staging/rts_pstor/xd.c2052
-rw-r--r--drivers/staging/rts_pstor/xd.h188
-rw-r--r--drivers/staging/sb105x/Kconfig9
-rw-r--r--drivers/staging/sb105x/Makefile3
-rw-r--r--drivers/staging/sb105x/sb_mp_register.h295
-rw-r--r--drivers/staging/sb105x/sb_pci_mp.c3196
-rw-r--r--drivers/staging/sb105x/sb_pci_mp.h293
-rw-r--r--drivers/staging/sb105x/sb_ser_core.h368
-rw-r--r--drivers/staging/sbe-2t3e3/cpld.c2
-rw-r--r--drivers/staging/sbe-2t3e3/main.c7
-rw-r--r--drivers/staging/sbe-2t3e3/module.c19
-rw-r--r--drivers/staging/sbe-2t3e3/netdev.c5
-rw-r--r--drivers/staging/sep/sep_main.c6
-rw-r--r--drivers/staging/serqt_usb2/serqt_usb2.c287
-rw-r--r--drivers/staging/silicom/bp_mod.c219
-rw-r--r--drivers/staging/silicom/bp_proc.c85
-rw-r--r--drivers/staging/silicom/bypasslib/bplibk.h9
-rw-r--r--drivers/staging/silicom/bypasslib/bypass.c1
-rw-r--r--drivers/staging/slicoss/slicoss.c166
-rw-r--r--drivers/staging/sm7xxfb/sm7xxfb.c6
-rw-r--r--drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c106
-rw-r--r--drivers/staging/telephony/Kconfig47
-rw-r--r--drivers/staging/telephony/Makefile7
-rw-r--r--drivers/staging/telephony/TODO10
-rw-r--r--drivers/staging/telephony/ixj-ver.h4
-rw-r--r--drivers/staging/telephony/ixj.c10571
-rw-r--r--drivers/staging/telephony/ixj.h1322
-rw-r--r--drivers/staging/telephony/ixj_pcmcia.c187
-rw-r--r--drivers/staging/telephony/phonedev.c166
-rw-r--r--drivers/staging/tidspbridge/dynload/dload_internal.h8
-rw-r--r--drivers/staging/tidspbridge/dynload/reloc.c6
-rw-r--r--drivers/staging/tidspbridge/rmgr/drv_interface.c6
-rw-r--r--drivers/staging/usbip/stub_dev.c15
-rw-r--r--drivers/staging/usbip/stub_rx.c5
-rw-r--r--drivers/staging/usbip/stub_tx.c3
-rw-r--r--drivers/staging/usbip/usbip_common.c40
-rw-r--r--drivers/staging/usbip/usbip_common.h4
-rw-r--r--drivers/staging/usbip/userspace/src/usbip_detach.c9
-rw-r--r--drivers/staging/usbip/vhci.h1
-rw-r--r--drivers/staging/usbip/vhci_hcd.c51
-rw-r--r--drivers/staging/usbip/vhci_rx.c2
-rw-r--r--drivers/staging/usbip/vhci_sysfs.c6
-rw-r--r--drivers/staging/usbip/vhci_tx.c2
-rw-r--r--drivers/staging/vme/devices/vme_pio2.h2
-rw-r--r--drivers/staging/vme/devices/vme_pio2_core.c10
-rw-r--r--drivers/staging/vme/devices/vme_pio2_gpio.c2
-rw-r--r--drivers/staging/vme/devices/vme_user.c83
-rw-r--r--drivers/staging/vt6655/device_main.c6
-rw-r--r--drivers/staging/vt6655/hostap.c6
-rw-r--r--drivers/staging/vt6655/rxtx.c2
-rw-r--r--drivers/staging/vt6655/wcmd.c1
-rw-r--r--drivers/staging/vt6656/80211mgr.c2
-rw-r--r--drivers/staging/vt6656/Makefile1
-rw-r--r--drivers/staging/vt6656/bssdb.c43
-rw-r--r--drivers/staging/vt6656/desc.h28
-rw-r--r--drivers/staging/vt6656/device.h48
-rw-r--r--drivers/staging/vt6656/dpc.c64
-rw-r--r--drivers/staging/vt6656/firmware.c22
-rw-r--r--drivers/staging/vt6656/hostap.c6
-rw-r--r--drivers/staging/vt6656/int.h4
-rw-r--r--drivers/staging/vt6656/ioctl.c648
-rw-r--r--drivers/staging/vt6656/ioctl.h54
-rw-r--r--drivers/staging/vt6656/iwctl.c510
-rw-r--r--drivers/staging/vt6656/iwctl.h79
-rw-r--r--drivers/staging/vt6656/key.c55
-rw-r--r--drivers/staging/vt6656/key.h8
-rw-r--r--drivers/staging/vt6656/mac.c6
-rw-r--r--drivers/staging/vt6656/main_usb.c552
-rw-r--r--drivers/staging/vt6656/mib.c1
-rw-r--r--drivers/staging/vt6656/mib.h1
-rw-r--r--drivers/staging/vt6656/rf.c3
-rw-r--r--drivers/staging/vt6656/rxtx.c36
-rw-r--r--drivers/staging/vt6656/rxtx.h8
-rw-r--r--drivers/staging/vt6656/tkip.c40
-rw-r--r--drivers/staging/vt6656/ttype.h16
-rw-r--r--drivers/staging/vt6656/upc.h162
-rw-r--r--drivers/staging/vt6656/usbpipe.c4
-rw-r--r--drivers/staging/vt6656/wcmd.c44
-rw-r--r--drivers/staging/vt6656/wmgr.c66
-rw-r--r--drivers/staging/vt6656/wmgr.h42
-rw-r--r--drivers/staging/vt6656/wpa2.c2
-rw-r--r--drivers/staging/vt6656/wpa2.h4
-rw-r--r--drivers/staging/vt6656/wpactl.c664
-rw-r--r--drivers/staging/vt6656/wpactl.h12
-rw-r--r--drivers/staging/winbond/mds.c7
-rw-r--r--drivers/staging/winbond/wb35rx_f.h12
-rw-r--r--drivers/staging/winbond/wb35rx_s.h62
-rw-r--r--drivers/staging/winbond/wbhal.h4
-rw-r--r--drivers/staging/winbond/wbusb.c14
-rw-r--r--drivers/staging/wlags49_h2/ap_h2.c16
-rw-r--r--drivers/staging/wlags49_h2/man/wlags49.42
-rw-r--r--drivers/staging/wlags49_h2/wl_if.h133
-rw-r--r--drivers/staging/wlags49_h2/wl_pci.c25
-rw-r--r--drivers/staging/wlan-ng/hfa384x_usb.c6
-rw-r--r--drivers/staging/xgifb/TODO2
-rw-r--r--drivers/staging/xgifb/XGI_main_26.c60
-rw-r--r--drivers/staging/xgifb/vb_def.h9
-rw-r--r--drivers/staging/xgifb/vb_init.c47
-rw-r--r--drivers/staging/xgifb/vb_init.h1
-rw-r--r--drivers/staging/xgifb/vb_setmode.c898
-rw-r--r--drivers/staging/xgifb/vb_struct.h36
-rw-r--r--drivers/staging/xgifb/vb_table.h504
-rw-r--r--drivers/staging/zram/zram_drv.c113
-rw-r--r--drivers/staging/zram/zram_drv.h4
-rw-r--r--drivers/staging/zram/zram_sysfs.c8
-rw-r--r--drivers/target/target_core_transport.c6
-rw-r--r--drivers/tty/amiserial.c2
-rw-r--r--drivers/tty/bfin_jtag_comm.c6
-rw-r--r--drivers/tty/cyclades.c28
-rw-r--r--drivers/tty/ehv_bytechan.c4
-rw-r--r--drivers/tty/hvc/hvc_console.c7
-rw-r--r--drivers/tty/hvc/hvc_opal.c8
-rw-r--r--drivers/tty/hvc/hvc_vio.c6
-rw-r--r--drivers/tty/hvc/hvc_xen.c2
-rw-r--r--drivers/tty/hvc/hvcs.c20
-rw-r--r--drivers/tty/hvc/hvsi.c1
-rw-r--r--drivers/tty/ipwireless/network.c5
-rw-r--r--drivers/tty/ipwireless/tty.c1
-rw-r--r--drivers/tty/isicom.c35
-rw-r--r--drivers/tty/moxa.c12
-rw-r--r--drivers/tty/mxser.c35
-rw-r--r--drivers/tty/n_gsm.c11
-rw-r--r--drivers/tty/n_tty.c752
-rw-r--r--drivers/tty/nozomi.c23
-rw-r--r--drivers/tty/pty.c81
-rw-r--r--drivers/tty/rocket.c4
-rw-r--r--drivers/tty/serial/68328serial.c2
-rw-r--r--drivers/tty/serial/8250/8250.c98
-rw-r--r--drivers/tty/serial/8250/8250.h36
-rw-r--r--drivers/tty/serial/8250/8250_acorn.c6
-rw-r--r--drivers/tty/serial/8250/8250_dw.c31
-rw-r--r--drivers/tty/serial/8250/8250_early.c46
-rw-r--r--drivers/tty/serial/8250/8250_em.c8
-rw-r--r--drivers/tty/serial/8250/8250_hp300.c10
-rw-r--r--drivers/tty/serial/8250/8250_pci.c352
-rw-r--r--drivers/tty/serial/8250/8250_pnp.c14
-rw-r--r--drivers/tty/serial/Kconfig48
-rw-r--r--drivers/tty/serial/Makefile1
-rw-r--r--drivers/tty/serial/altera_jtaguart.c6
-rw-r--r--drivers/tty/serial/altera_uart.c6
-rw-r--r--drivers/tty/serial/amba-pl011.c25
-rw-r--r--drivers/tty/serial/apbuart.c2
-rw-r--r--drivers/tty/serial/ar933x_uart.c96
-rw-r--r--drivers/tty/serial/arc_uart.c746
-rw-r--r--drivers/tty/serial/atmel_serial.c18
-rw-r--r--drivers/tty/serial/bcm63xx_uart.c6
-rw-r--r--drivers/tty/serial/bfin_sport_uart.c6
-rw-r--r--drivers/tty/serial/bfin_uart.c20
-rw-r--r--drivers/tty/serial/clps711x.c595
-rw-r--r--drivers/tty/serial/cpm_uart/cpm_uart_core.c4
-rw-r--r--drivers/tty/serial/efm32-uart.c6
-rw-r--r--drivers/tty/serial/icom.c14
-rw-r--r--drivers/tty/serial/ifx6x60.c168
-rw-r--r--drivers/tty/serial/ifx6x60.h2
-rw-r--r--drivers/tty/serial/ioc3_serial.c2
-rw-r--r--drivers/tty/serial/jsm/jsm.h8
-rw-r--r--drivers/tty/serial/jsm/jsm_driver.c9
-rw-r--r--drivers/tty/serial/jsm/jsm_neo.c116
-rw-r--r--drivers/tty/serial/jsm/jsm_tty.c104
-rw-r--r--drivers/tty/serial/kgdb_nmi.c2
-rw-r--r--drivers/tty/serial/lpc32xx_hs.c6
-rw-r--r--drivers/tty/serial/max3100.c6
-rw-r--r--drivers/tty/serial/max310x.c12
-rw-r--r--drivers/tty/serial/mcf.c6
-rw-r--r--drivers/tty/serial/mfd.c7
-rw-r--r--drivers/tty/serial/mpc52xx_uart.c2
-rw-r--r--drivers/tty/serial/mrst_max3110.c6
-rw-r--r--drivers/tty/serial/msm_serial.c2
-rw-r--r--drivers/tty/serial/msm_serial_hs.c8
-rw-r--r--drivers/tty/serial/mux.c6
-rw-r--r--drivers/tty/serial/mxs-auart.c376
-rw-r--r--drivers/tty/serial/of_serial.c38
-rw-r--r--drivers/tty/serial/omap-serial.c30
-rw-r--r--drivers/tty/serial/pch_uart.c4
-rw-r--r--drivers/tty/serial/pxa.c55
-rw-r--r--drivers/tty/serial/sa1100.c2
-rw-r--r--drivers/tty/serial/samsung.c46
-rw-r--r--drivers/tty/serial/sc26xx.c6
-rw-r--r--drivers/tty/serial/sccnxp.c6
-rw-r--r--drivers/tty/serial/serial_core.c186
-rw-r--r--drivers/tty/serial/serial_txx9.c16
-rw-r--r--drivers/tty/serial/sh-sci.c154
-rw-r--r--drivers/tty/serial/sirfsoc_uart.c4
-rw-r--r--drivers/tty/serial/sunhv.c6
-rw-r--r--drivers/tty/serial/sunsab.c8
-rw-r--r--drivers/tty/serial/sunsu.c10
-rw-r--r--drivers/tty/serial/sunzilog.c14
-rw-r--r--drivers/tty/serial/timbuart.c6
-rw-r--r--drivers/tty/serial/uartlite.c14
-rw-r--r--drivers/tty/serial/vr41xx_siu.c8
-rw-r--r--drivers/tty/serial/vt8500_serial.c14
-rw-r--r--drivers/tty/serial/xilinx_uartps.c15
-rw-r--r--drivers/tty/synclink.c7
-rw-r--r--drivers/tty/synclink_gt.c11
-rw-r--r--drivers/tty/synclinkmp.c11
-rw-r--r--drivers/tty/sysrq.c3
-rw-r--r--drivers/tty/tty_audit.c15
-rw-r--r--drivers/tty/tty_buffer.c228
-rw-r--r--drivers/tty/tty_io.c24
-rw-r--r--drivers/tty/tty_ioctl.c21
-rw-r--r--drivers/tty/tty_ldisc.c47
-rw-r--r--drivers/tty/tty_mutex.c4
-rw-r--r--drivers/tty/tty_port.c18
-rw-r--r--drivers/tty/vt/consolemap.c6
-rw-r--r--drivers/tty/vt/selection.c9
-rw-r--r--drivers/tty/vt/vt.c13
-rw-r--r--drivers/tty/vt/vt_ioctl.c1
-rw-r--r--drivers/uio/Kconfig16
-rw-r--r--drivers/uio/Makefile1
-rw-r--r--drivers/uio/uio_aec.c2
-rw-r--r--drivers/uio/uio_cif.c4
-rw-r--r--drivers/uio/uio_dmem_genirq.c359
-rw-r--r--drivers/uio/uio_netx.c2
-rw-r--r--drivers/uio/uio_pci_generic.c2
-rw-r--r--drivers/uio/uio_pdrv.c1
-rw-r--r--drivers/uio/uio_pdrv_genirq.c3
-rw-r--r--drivers/uio/uio_pruss.c6
-rw-r--r--drivers/uio/uio_sercos3.c4
-rw-r--r--drivers/usb/c67x00/c67x00-drv.c6
-rw-r--r--drivers/usb/chipidea/Kconfig1
-rw-r--r--drivers/usb/chipidea/ci13xxx_imx.c8
-rw-r--r--drivers/usb/chipidea/ci13xxx_msm.c6
-rw-r--r--drivers/usb/chipidea/ci13xxx_pci.c6
-rw-r--r--drivers/usb/chipidea/core.c9
-rw-r--r--drivers/usb/chipidea/debug.c3
-rw-r--r--drivers/usb/chipidea/host.c67
-rw-r--r--drivers/usb/chipidea/usbmisc_imx6q.c6
-rw-r--r--drivers/usb/class/cdc-acm.c38
-rw-r--r--drivers/usb/core/devices.c18
-rw-r--r--drivers/usb/core/driver.c25
-rw-r--r--drivers/usb/core/generic.c7
-rw-r--r--drivers/usb/core/hcd.c35
-rw-r--r--drivers/usb/core/hub.c97
-rw-r--r--drivers/usb/core/message.c66
-rw-r--r--drivers/usb/core/urb.c29
-rw-r--r--drivers/usb/core/usb.c13
-rw-r--r--drivers/usb/dwc3/Makefile14
-rw-r--r--drivers/usb/dwc3/core.c96
-rw-r--r--drivers/usb/dwc3/core.h3
-rw-r--r--drivers/usb/dwc3/debugfs.c4
-rw-r--r--drivers/usb/dwc3/dwc3-exynos.c57
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c24
-rw-r--r--drivers/usb/dwc3/dwc3-pci.c24
-rw-r--r--drivers/usb/dwc3/gadget.c4
-rw-r--r--drivers/usb/early/ehci-dbgp.c15
-rw-r--r--drivers/usb/gadget/Kconfig29
-rw-r--r--drivers/usb/gadget/Makefile2
-rw-r--r--drivers/usb/gadget/at91_udc.c4
-rw-r--r--drivers/usb/gadget/bcm63xx_udc.c6
-rw-r--r--drivers/usb/gadget/composite.c8
-rw-r--r--drivers/usb/gadget/config.c39
-rw-r--r--drivers/usb/gadget/dummy_hcd.c170
-rw-r--r--drivers/usb/gadget/f_acm.c79
-rw-r--r--drivers/usb/gadget/f_ecm.c112
-rw-r--r--drivers/usb/gadget/f_eem.c51
-rw-r--r--drivers/usb/gadget/f_fs.c4
-rw-r--r--drivers/usb/gadget/f_hid.c30
-rw-r--r--drivers/usb/gadget/f_loopback.c28
-rw-r--r--drivers/usb/gadget/f_mass_storage.c63
-rw-r--r--drivers/usb/gadget/f_midi.c14
-rw-r--r--drivers/usb/gadget/f_ncm.c94
-rw-r--r--drivers/usb/gadget/f_obex.c42
-rw-r--r--drivers/usb/gadget/f_phonet.c21
-rw-r--r--drivers/usb/gadget/f_rndis.c94
-rw-r--r--drivers/usb/gadget/f_serial.c38
-rw-r--r--drivers/usb/gadget/f_sourcesink.c104
-rw-r--r--drivers/usb/gadget/f_subset.c75
-rw-r--r--drivers/usb/gadget/f_uac1.c23
-rw-r--r--drivers/usb/gadget/f_uac2.c222
-rw-r--r--drivers/usb/gadget/f_uvc.c138
-rw-r--r--drivers/usb/gadget/file_storage.c3656
-rw-r--r--drivers/usb/gadget/fsl_qe_udc.c14
-rw-r--r--drivers/usb/gadget/fsl_udc_core.c2
-rw-r--r--drivers/usb/gadget/hid.c4
-rw-r--r--drivers/usb/gadget/inode.c3
-rw-r--r--drivers/usb/gadget/lpc32xx_udc.c6
-rw-r--r--drivers/usb/gadget/mv_u3d_core.c2
-rw-r--r--drivers/usb/gadget/mv_udc_core.c4
-rw-r--r--drivers/usb/gadget/net2272.c29
-rw-r--r--drivers/usb/gadget/net2280.c2
-rw-r--r--drivers/usb/gadget/omap_udc.c10
-rw-r--r--drivers/usb/gadget/printer.c12
-rw-r--r--drivers/usb/gadget/pxa27x_udc.h2
-rw-r--r--drivers/usb/gadget/s3c-hsotg.c12
-rw-r--r--drivers/usb/gadget/s3c-hsudc.c2
-rw-r--r--drivers/usb/gadget/storage_common.c165
-rw-r--r--drivers/usb/gadget/tcm_usb_gadget.c13
-rw-r--r--drivers/usb/gadget/u_serial.c5
-rw-r--r--drivers/usb/gadget/udc-core.c11
-rw-r--r--drivers/usb/host/Kconfig35
-rw-r--r--drivers/usb/host/Makefile4
-rw-r--r--drivers/usb/host/bcma-hcd.c15
-rw-r--r--drivers/usb/host/ehci-atmel.c15
-rw-r--r--drivers/usb/host/ehci-au1xxx.c184
-rw-r--r--drivers/usb/host/ehci-cns3xxx.c155
-rw-r--r--drivers/usb/host/ehci-dbg.c112
-rw-r--r--drivers/usb/host/ehci-fsl.c1
-rw-r--r--drivers/usb/host/ehci-grlib.c20
-rw-r--r--drivers/usb/host/ehci-hcd.c204
-rw-r--r--drivers/usb/host/ehci-hub.c47
-rw-r--r--drivers/usb/host/ehci-ixp4xx.c139
-rw-r--r--drivers/usb/host/ehci-lpm.c84
-rw-r--r--drivers/usb/host/ehci-ls1x.c147
-rw-r--r--drivers/usb/host/ehci-msm.c5
-rw-r--r--drivers/usb/host/ehci-mxc.c10
-rw-r--r--drivers/usb/host/ehci-octeon.c3
-rw-r--r--drivers/usb/host/ehci-omap.c3
-rw-r--r--drivers/usb/host/ehci-orion.c20
-rw-r--r--drivers/usb/host/ehci-pci.c132
-rw-r--r--drivers/usb/host/ehci-platform.c102
-rw-r--r--drivers/usb/host/ehci-pmcmsp.c1
-rw-r--r--drivers/usb/host/ehci-ppc-of.c4
-rw-r--r--drivers/usb/host/ehci-ps3.c2
-rw-r--r--drivers/usb/host/ehci-q.c12
-rw-r--r--drivers/usb/host/ehci-s5p.c16
-rw-r--r--drivers/usb/host/ehci-sched.c136
-rw-r--r--drivers/usb/host/ehci-sh.c9
-rw-r--r--drivers/usb/host/ehci-spear.c59
-rw-r--r--drivers/usb/host/ehci-tegra.c18
-rw-r--r--drivers/usb/host/ehci-vt8500.c21
-rw-r--r--drivers/usb/host/ehci-w90x900.c10
-rw-r--r--drivers/usb/host/ehci-xilinx-of.c2
-rw-r--r--drivers/usb/host/ehci-xls.c142
-rw-r--r--drivers/usb/host/ehci.h45
-rw-r--r--drivers/usb/host/fhci-hcd.c8
-rw-r--r--drivers/usb/host/fsl-mph-dr-of.c16
-rw-r--r--drivers/usb/host/imx21-hcd.c2
-rw-r--r--drivers/usb/host/isp116x-hcd.c2
-rw-r--r--drivers/usb/host/isp1362-hcd.c6
-rw-r--r--drivers/usb/host/isp1760-if.c15
-rw-r--r--drivers/usb/host/ohci-at91.c22
-rw-r--r--drivers/usb/host/ohci-au1xxx.c234
-rw-r--r--drivers/usb/host/ohci-cns3xxx.c166
-rw-r--r--drivers/usb/host/ohci-ep93xx.c4
-rw-r--r--drivers/usb/host/ohci-exynos.c38
-rw-r--r--drivers/usb/host/ohci-hcd.c139
-rw-r--r--drivers/usb/host/ohci-hub.c42
-rw-r--r--drivers/usb/host/ohci-jz4740.c6
-rw-r--r--drivers/usb/host/ohci-nxp.c4
-rw-r--r--drivers/usb/host/ohci-octeon.c2
-rw-r--r--drivers/usb/host/ohci-omap.c2
-rw-r--r--drivers/usb/host/ohci-omap3.c6
-rw-r--r--drivers/usb/host/ohci-pci.c49
-rw-r--r--drivers/usb/host/ohci-platform.c34
-rw-r--r--drivers/usb/host/ohci-pnx8550.c243
-rw-r--r--drivers/usb/host/ohci-ppc-of.c4
-rw-r--r--drivers/usb/host/ohci-ppc-soc.c216
-rw-r--r--drivers/usb/host/ohci-ps3.c4
-rw-r--r--drivers/usb/host/ohci-pxa27x.c8
-rw-r--r--drivers/usb/host/ohci-q.c23
-rw-r--r--drivers/usb/host/ohci-s3c2410.c41
-rw-r--r--drivers/usb/host/ohci-sa1111.c2
-rw-r--r--drivers/usb/host/ohci-sh.c141
-rw-r--r--drivers/usb/host/ohci-sm501.c2
-rw-r--r--drivers/usb/host/ohci-spear.c50
-rw-r--r--drivers/usb/host/ohci-tmio.c8
-rw-r--r--drivers/usb/host/ohci-xls.c152
-rw-r--r--drivers/usb/host/pci-quirks.c20
-rw-r--r--drivers/usb/host/r8a66597-hcd.c12
-rw-r--r--drivers/usb/host/sl811-hcd.c6
-rw-r--r--drivers/usb/host/ssb-hcd.c19
-rw-r--r--drivers/usb/host/u132-hcd.c6
-rw-r--r--drivers/usb/host/uhci-grlib.c2
-rw-r--r--drivers/usb/host/uhci-platform.c2
-rw-r--r--drivers/usb/host/uhci-q.c73
-rw-r--r--drivers/usb/host/xhci-mem.c9
-rw-r--r--drivers/usb/host/xhci-pci.c16
-rw-r--r--drivers/usb/host/xhci-ring.c34
-rw-r--r--drivers/usb/host/xhci.c32
-rw-r--r--drivers/usb/host/xhci.h2
-rw-r--r--drivers/usb/misc/Kconfig1
-rw-r--r--drivers/usb/misc/ezusb.c38
-rw-r--r--drivers/usb/misc/usbtest.c4
-rw-r--r--drivers/usb/musb/am35x.c40
-rw-r--r--drivers/usb/musb/blackfin.c38
-rw-r--r--drivers/usb/musb/cppi_dma.c4
-rw-r--r--drivers/usb/musb/da8xx.c40
-rw-r--r--drivers/usb/musb/davinci.c40
-rw-r--r--drivers/usb/musb/musb_core.c137
-rw-r--r--drivers/usb/musb/musb_core.h5
-rw-r--r--drivers/usb/musb/musb_debugfs.c2
-rw-r--r--drivers/usb/musb/musb_dma.h3
-rw-r--r--drivers/usb/musb/musb_dsps.c141
-rw-r--r--drivers/usb/musb/musb_gadget.c66
-rw-r--r--drivers/usb/musb/musb_gadget_ep0.c6
-rw-r--r--drivers/usb/musb/musb_host.c2
-rw-r--r--drivers/usb/musb/musbhsdma.c3
-rw-r--r--drivers/usb/musb/musbhsdma.h4
-rw-r--r--drivers/usb/musb/omap2430.c52
-rw-r--r--drivers/usb/musb/tusb6010.c40
-rw-r--r--drivers/usb/musb/tusb6010_omap.c3
-rw-r--r--drivers/usb/musb/ux500.c62
-rw-r--r--drivers/usb/musb/ux500_dma.c3
-rw-r--r--drivers/usb/otg/Kconfig4
-rw-r--r--drivers/usb/otg/ab8500-usb.c6
-rw-r--r--drivers/usb/otg/fsl_otg.c6
-rw-r--r--drivers/usb/otg/isp1301_omap.c2
-rw-r--r--drivers/usb/otg/msm_otg.c4
-rw-r--r--drivers/usb/otg/mv_otg.c14
-rw-r--r--drivers/usb/otg/mxs-phy.c59
-rw-r--r--drivers/usb/otg/nop-usb-xceiv.c6
-rw-r--r--drivers/usb/otg/twl4030-usb.c48
-rw-r--r--drivers/usb/otg/twl6030-usb.c2
-rw-r--r--drivers/usb/phy/Kconfig12
-rw-r--r--drivers/usb/phy/Makefile1
-rw-r--r--drivers/usb/phy/mv_u3d_phy.c4
-rw-r--r--drivers/usb/phy/omap-usb2.c6
-rw-r--r--drivers/usb/phy/rcar-phy.c220
-rw-r--r--drivers/usb/phy/tegra_usb_phy.c4
-rw-r--r--drivers/usb/renesas_usbhs/common.c9
-rw-r--r--drivers/usb/renesas_usbhs/common.h1
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c14
-rw-r--r--drivers/usb/renesas_usbhs/mod.c3
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c11
-rw-r--r--drivers/usb/renesas_usbhs/mod_host.c45
-rw-r--r--drivers/usb/renesas_usbhs/pipe.c101
-rw-r--r--drivers/usb/renesas_usbhs/pipe.h1
-rw-r--r--drivers/usb/serial/aircable.c5
-rw-r--r--drivers/usb/serial/ark3116.c5
-rw-r--r--drivers/usb/serial/belkin_sa.c5
-rw-r--r--drivers/usb/serial/bus.c10
-rw-r--r--drivers/usb/serial/cp210x.c37
-rw-r--r--drivers/usb/serial/cyberjack.c5
-rw-r--r--drivers/usb/serial/cypress_m8.c5
-rw-r--r--drivers/usb/serial/digi_acceleport.c4
-rw-r--r--drivers/usb/serial/empeg.c4
-rw-r--r--drivers/usb/serial/ftdi_sio.c82
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h6
-rw-r--r--drivers/usb/serial/generic.c1
-rw-r--r--drivers/usb/serial/hp4x.c5
-rw-r--r--drivers/usb/serial/io_edgeport.c4
-rw-r--r--drivers/usb/serial/io_ti.c4
-rw-r--r--drivers/usb/serial/ipaq.c5
-rw-r--r--drivers/usb/serial/ipw.c4
-rw-r--r--drivers/usb/serial/iuu_phoenix.c8
-rw-r--r--drivers/usb/serial/keyspan.c7
-rw-r--r--drivers/usb/serial/keyspan_pda.c4
-rw-r--r--drivers/usb/serial/kl5kusb105.c4
-rw-r--r--drivers/usb/serial/kobil_sct.c2
-rw-r--r--drivers/usb/serial/mct_u232.c4
-rw-r--r--drivers/usb/serial/metro-usb.c2
-rw-r--r--drivers/usb/serial/mos7720.c4
-rw-r--r--drivers/usb/serial/mos7840.c4
-rw-r--r--drivers/usb/serial/omninet.c4
-rw-r--r--drivers/usb/serial/opticon.c351
-rw-r--r--drivers/usb/serial/option.c122
-rw-r--r--drivers/usb/serial/oti6858.c2
-rw-r--r--drivers/usb/serial/quatech2.c2
-rw-r--r--drivers/usb/serial/siemens_mpi.c2
-rw-r--r--drivers/usb/serial/sierra.c3
-rw-r--r--drivers/usb/serial/spcp8x5.c4
-rw-r--r--drivers/usb/serial/ssu100.c2
-rw-r--r--drivers/usb/serial/usb-serial.c1
-rw-r--r--drivers/usb/serial/usb_wwan.c12
-rw-r--r--drivers/usb/serial/vivopay-serial.c3
-rw-r--r--drivers/usb/storage/Kconfig2
-rw-r--r--drivers/usb/storage/realtek_cr.c2
-rw-r--r--drivers/usb/storage/scsiglue.c6
-rw-r--r--drivers/usb/storage/usb.c1
-rw-r--r--drivers/usb/usb-skeleton.c13
-rw-r--r--drivers/usb/wusbcore/devconnect.c13
-rw-r--r--drivers/uwb/Kconfig3
-rw-r--r--drivers/uwb/reset.c1
-rw-r--r--drivers/uwb/umc-bus.c2
-rw-r--r--drivers/vhost/vhost.c2
-rw-r--r--drivers/video/backlight/adp5520_bl.c6
-rw-r--r--drivers/video/backlight/adp8860_bl.c14
-rw-r--r--drivers/video/backlight/adp8870_bl.c14
-rw-r--r--drivers/video/backlight/ams369fg06.c6
-rw-r--r--drivers/video/backlight/apple_bl.c4
-rw-r--r--drivers/video/backlight/corgi_lcd.c6
-rw-r--r--drivers/video/backlight/ep93xx_bl.c2
-rw-r--r--drivers/video/backlight/hp680_bl.c2
-rw-r--r--drivers/video/backlight/ili9320.c4
-rw-r--r--drivers/video/backlight/l4f00242t03.c6
-rw-r--r--drivers/video/backlight/ld9040.c4
-rw-r--r--drivers/video/backlight/lm3533_bl.c8
-rw-r--r--drivers/video/backlight/lm3630_bl.c8
-rw-r--r--drivers/video/backlight/lm3639_bl.c8
-rw-r--r--drivers/video/backlight/lms283gf05.c6
-rw-r--r--drivers/video/backlight/lp855x_bl.c4
-rw-r--r--drivers/video/backlight/ltv350qv.c6
-rw-r--r--drivers/video/backlight/max8925_bl.c6
-rw-r--r--drivers/video/backlight/pcf50633-backlight.c6
-rw-r--r--drivers/video/backlight/platform_lcd.c6
-rw-r--r--drivers/video/backlight/s6e63m0.c6
-rw-r--r--drivers/video/backlight/tdo24m.c6
-rw-r--r--drivers/video/backlight/tosa_bl.c6
-rw-r--r--drivers/video/backlight/tosa_lcd.c6
-rw-r--r--drivers/video/backlight/vgg2432a4.c6
-rw-r--r--drivers/video/omap2/dss/dsi.c13
-rw-r--r--drivers/video/omap2/dss/dss.c18
-rw-r--r--drivers/video/omap2/dss/hdmi.c4
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c2
-rw-r--r--drivers/virtio/virtio_balloon.c151
-rw-r--r--drivers/vme/boards/vme_vmivme7805.c15
-rw-r--r--drivers/vme/bridges/vme_ca91cx42.c15
-rw-r--r--drivers/vme/bridges/vme_tsi148.c15
-rw-r--r--drivers/w1/masters/Kconfig2
-rw-r--r--drivers/w1/masters/ds2482.c13
-rw-r--r--drivers/w1/masters/matrox_w1.c10
-rw-r--r--drivers/w1/masters/mxc_w1.c28
-rw-r--r--drivers/w1/masters/omap_hdq.c10
-rw-r--r--drivers/w1/masters/w1-gpio.c65
-rw-r--r--drivers/w1/w1.c7
-rw-r--r--drivers/watchdog/acquirewdt.c6
-rw-r--r--drivers/watchdog/advantechwdt.c6
-rw-r--r--drivers/watchdog/ar7_wdt.c6
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c6
-rw-r--r--drivers/watchdog/ath79_wdt.c6
-rw-r--r--drivers/watchdog/bcm63xx_wdt.c6
-rw-r--r--drivers/watchdog/bfin_wdt.c6
-rw-r--r--drivers/watchdog/cpu5wdt.c8
-rw-r--r--drivers/watchdog/cpwd.c6
-rw-r--r--drivers/watchdog/da9052_wdt.c6
-rw-r--r--drivers/watchdog/davinci_wdt.c6
-rw-r--r--drivers/watchdog/dw_wdt.c6
-rw-r--r--drivers/watchdog/ep93xx_wdt.c6
-rw-r--r--drivers/watchdog/gef_wdt.c4
-rw-r--r--drivers/watchdog/geodewdt.c6
-rw-r--r--drivers/watchdog/hpwdt.c30
-rw-r--r--drivers/watchdog/i6300esb.c10
-rw-r--r--drivers/watchdog/iTCO_wdt.c8
-rw-r--r--drivers/watchdog/ib700wdt.c6
-rw-r--r--drivers/watchdog/ie6xx_wdt.c10
-rw-r--r--drivers/watchdog/jz4740_wdt.c6
-rw-r--r--drivers/watchdog/ks8695_wdt.c6
-rw-r--r--drivers/watchdog/lantiq_wdt.c6
-rw-r--r--drivers/watchdog/max63xx_wdt.c6
-rw-r--r--drivers/watchdog/mixcomwd.c2
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c6
-rw-r--r--drivers/watchdog/mpcore_wdt.c6
-rw-r--r--drivers/watchdog/mtx-1_wdt.c6
-rw-r--r--drivers/watchdog/mv64x60_wdt.c6
-rw-r--r--drivers/watchdog/nuc900_wdt.c6
-rw-r--r--drivers/watchdog/nv_tco.c10
-rw-r--r--drivers/watchdog/of_xilinx_wdt.c8
-rw-r--r--drivers/watchdog/omap_wdt.c6
-rw-r--r--drivers/watchdog/orion_wdt.c8
-rw-r--r--drivers/watchdog/pcwd.c8
-rw-r--r--drivers/watchdog/pcwd_pci.c6
-rw-r--r--drivers/watchdog/pnx4008_wdt.c6
-rw-r--r--drivers/watchdog/rc32434_wdt.c6
-rw-r--r--drivers/watchdog/rdc321x_wdt.c6
-rw-r--r--drivers/watchdog/riowd.c6
-rw-r--r--drivers/watchdog/s3c2410_wdt.c6
-rw-r--r--drivers/watchdog/sch311x_wdt.c6
-rw-r--r--drivers/watchdog/shwdt.c6
-rw-r--r--drivers/watchdog/sp5100_tco.c10
-rw-r--r--drivers/watchdog/sp805_wdt.c6
-rw-r--r--drivers/watchdog/stmp3xxx_wdt.c6
-rw-r--r--drivers/watchdog/ts72xx_wdt.c6
-rw-r--r--drivers/watchdog/twl4030_wdt.c6
-rw-r--r--drivers/watchdog/via_wdt.c6
-rw-r--r--drivers/watchdog/wdt_pci.c6
-rw-r--r--drivers/watchdog/wm831x_wdt.c6
-rw-r--r--drivers/watchdog/wm8350_wdt.c6
-rw-r--r--drivers/watchdog/xen_wdt.c6
-rw-r--r--drivers/xen/privcmd.c18
-rw-r--r--drivers/xen/xen-selfballoon.c2
-rw-r--r--firmware/Makefile1
-rw-r--r--firmware/dabusb/bitstream.bin.ihex761
-rw-r--r--firmware/dabusb/firmware.HEX649
-rw-r--r--fs/block_dev.c166
-rw-r--r--fs/btrfs/disk-io.c8
-rw-r--r--fs/btrfs/file.c3
-rw-r--r--fs/btrfs/ioctl.c2
-rw-r--r--fs/buffer.c157
-rw-r--r--fs/cifs/file.c6
-rw-r--r--fs/cifs/readdir.c5
-rw-r--r--fs/cifs/smb1ops.c3
-rw-r--r--fs/compat_ioctl.c3
-rw-r--r--fs/debugfs/inode.c1
-rw-r--r--fs/devpts/inode.c61
-rw-r--r--fs/direct-io.c8
-rw-r--r--fs/ext3/balloc.c5
-rw-r--r--fs/file.c15
-rw-r--r--fs/fs-writeback.c2
-rw-r--r--fs/gfs2/glock.c2
-rw-r--r--fs/hugetlbfs/inode.c109
-rw-r--r--fs/inode.c18
-rw-r--r--fs/internal.h1
-rw-r--r--fs/jbd/transaction.c2
-rw-r--r--fs/jffs2/file.c39
-rw-r--r--fs/namei.c5
-rw-r--r--fs/nfs/dir.c7
-rw-r--r--fs/nilfs2/page.c2
-rw-r--r--fs/notify/fanotify/fanotify_user.c3
-rw-r--r--fs/ocfs2/file.c5
-rw-r--r--fs/proc/array.c4
-rw-r--r--fs/proc/base.c124
-rw-r--r--fs/pstore/platform.c3
-rw-r--r--fs/reiserfs/inode.c10
-rw-r--r--fs/reiserfs/stree.c4
-rw-r--r--fs/reiserfs/super.c60
-rw-r--r--fs/splice.c5
-rw-r--r--fs/sysfs/file.c4
-rw-r--r--fs/ubifs/find.c12
-rw-r--r--fs/ubifs/lprops.c6
-rw-r--r--fs/ubifs/ubifs.h3
-rw-r--r--fs/xfs/xfs_aops.c54
-rw-r--r--fs/xfs/xfs_attr_leaf.c20
-rw-r--r--fs/xfs/xfs_buf.c14
-rw-r--r--include/acpi/acconfig.h1
-rw-r--r--include/acpi/acexcep.h2
-rw-r--r--include/acpi/acnames.h1
-rw-r--r--include/acpi/acpi_bus.h78
-rw-r--r--include/acpi/acpiosxf.h3
-rw-r--r--include/acpi/acpixf.h18
-rw-r--r--include/acpi/actbl3.h22
-rw-r--r--include/acpi/actypes.h42
-rw-r--r--include/asm-generic/gpio.h52
-rw-r--r--include/asm-generic/trace_clock.h16
-rw-r--r--include/drm/drm_pciids.h1
-rw-r--r--include/linux/acpi.h135
-rw-r--r--include/linux/acpi_gpio.h19
-rw-r--r--include/linux/balloon_compaction.h272
-rw-r--r--include/linux/bootmem.h4
-rw-r--r--include/linux/bug.h1
-rw-r--r--include/linux/clk-provider.h24
-rw-r--r--include/linux/context_tracking.h18
-rw-r--r--include/linux/cpufreq.h5
-rw-r--r--include/linux/cpuidle.h15
-rw-r--r--include/linux/devfreq.h136
-rw-r--r--include/linux/device.h18
-rw-r--r--include/linux/devpts_fs.h20
-rw-r--r--include/linux/dma-contiguous.h4
-rw-r--r--include/linux/edac.h3
-rw-r--r--include/linux/freezer.h1
-rw-r--r--include/linux/fs.h7
-rw-r--r--include/linux/ftrace_event.h20
-rw-r--r--include/linux/gfp.h7
-rw-r--r--include/linux/gpio.h21
-rw-r--r--include/linux/hardirq.h15
-rw-r--r--include/linux/huge_mm.h4
-rw-r--r--include/linux/hugetlb.h7
-rw-r--r--include/linux/hw_breakpoint.h31
-rw-r--r--include/linux/i2c-omap.h1
-rw-r--r--include/linux/i2c.h9
-rw-r--r--include/linux/i2c/pcf857x.h3
-rw-r--r--include/linux/iio/buffer.h26
-rw-r--r--include/linux/iio/consumer.h50
-rw-r--r--include/linux/iio/iio.h5
-rw-r--r--include/linux/iio/imu/adis.h280
-rw-r--r--include/linux/iio/machine.h2
-rw-r--r--include/linux/iio/types.h2
-rw-r--r--include/linux/init.h18
-rw-r--r--include/linux/ipack.h (renamed from drivers/staging/ipack/ipack.h)100
-rw-r--r--include/linux/irq.h9
-rw-r--r--include/linux/irqdesc.h3
-rw-r--r--include/linux/jiffies.h3
-rw-r--r--include/linux/kernel.h22
-rw-r--r--include/linux/kernel_stat.h17
-rw-r--r--include/linux/kobject.h18
-rw-r--r--include/linux/kvm_host.h12
-rw-r--r--include/linux/memory.h1
-rw-r--r--include/linux/memory_hotplug.h13
-rw-r--r--include/linux/mempolicy.h16
-rw-r--r--include/linux/mfd/88pm80x.h2
-rw-r--r--include/linux/mfd/abx500/ab8500.h4
-rw-r--r--include/linux/mfd/db8500-prcmu.h4
-rw-r--r--include/linux/mfd/dbx500-prcmu.h10
-rw-r--r--include/linux/mfd/pm8xxx/irq.h8
-rw-r--r--include/linux/mfd/rtsx_common.h (renamed from drivers/staging/rts_pstor/debug.h)43
-rw-r--r--include/linux/mfd/rtsx_pci.h794
-rw-r--r--include/linux/migrate.h19
-rw-r--r--include/linux/mm.h35
-rw-r--r--include/linux/mm_types.h19
-rw-r--r--include/linux/mman.h2
-rw-r--r--include/linux/mmc/card.h2
-rw-r--r--include/linux/mmc/core.h2
-rw-r--r--include/linux/mmc/dw_mmc.h5
-rw-r--r--include/linux/mmc/host.h17
-rw-r--r--include/linux/mmc/mmc.h2
-rw-r--r--include/linux/mmc/mxs-mmc.h19
-rw-r--r--include/linux/mmc/sdhci.h6
-rw-r--r--include/linux/mmzone.h11
-rw-r--r--include/linux/netdevice.h3
-rw-r--r--include/linux/node.h3
-rw-r--r--include/linux/of.h57
-rw-r--r--include/linux/of_address.h2
-rw-r--r--include/linux/oom.h21
-rw-r--r--include/linux/page-isolation.h10
-rw-r--r--include/linux/pagemap.h16
-rw-r--r--include/linux/pci.h8
-rw-r--r--include/linux/pci_ids.h5
-rw-r--r--include/linux/percpu-rwsem.h4
-rw-r--r--include/linux/pinctrl/pinconf-generic.h5
-rw-r--r--include/linux/pinctrl/pinctrl.h19
-rw-r--r--include/linux/platform_data/ad5449.h40
-rw-r--r--include/linux/platform_data/ad7298.h20
-rw-r--r--include/linux/platform_data/ad7793.h112
-rw-r--r--include/linux/platform_data/ad7887.h26
-rw-r--r--include/linux/platform_data/ads7828.h29
-rw-r--r--include/linux/platform_data/clk-integrator.h2
-rw-r--r--include/linux/platform_data/gpio-ts5500.h27
-rw-r--r--include/linux/platform_data/omap_drm.h1
-rw-r--r--include/linux/platform_data/omap_ocp2scp.h31
-rw-r--r--include/linux/platform_data/pinctrl-coh901.h4
-rw-r--r--include/linux/platform_data/pinctrl-nomadik.h (renamed from arch/arm/plat-nomadik/include/plat/pincfg.h)111
-rw-r--r--include/linux/platform_data/pxa_sdhci.h6
-rw-r--r--include/linux/platform_data/uio_dmem_genirq.h26
-rw-r--r--include/linux/platform_device.h1
-rw-r--r--include/linux/pm.h3
-rw-r--r--include/linux/pm_qos.h77
-rw-r--r--include/linux/rculist.h17
-rw-r--r--include/linux/rcupdate.h29
-rw-r--r--include/linux/ring_buffer.h3
-rw-r--r--include/linux/rio.h2
-rw-r--r--include/linux/sched.h66
-rw-r--r--include/linux/serial_8250.h2
-rw-r--r--include/linux/shm.h15
-rw-r--r--include/linux/spi/ads7846.h5
-rw-r--r--include/linux/srcu.h34
-rw-r--r--include/linux/tick.h6
-rw-r--r--include/linux/trace_clock.h2
-rw-r--r--include/linux/tty.h45
-rw-r--r--include/linux/tty_flip.h2
-rw-r--r--include/linux/types.h1
-rw-r--r--include/linux/uprobes.h10
-rw-r--r--include/linux/usb.h50
-rw-r--r--include/linux/usb/composite.h4
-rw-r--r--include/linux/usb/ehci_pdriver.h5
-rw-r--r--include/linux/usb/ezusb.h8
-rw-r--r--include/linux/usb/gadget.h7
-rw-r--r--include/linux/usb/ohci_pdriver.h2
-rw-r--r--include/linux/usb/phy.h15
-rw-r--r--include/linux/vtime.h48
-rw-r--r--include/linux/writeback.h9
-rw-r--r--include/media/adv7604.h21
-rw-r--r--include/net/tcp.h1
-rw-r--r--include/net/xfrm.h2
-rw-r--r--include/scsi/scsi_device.h4
-rw-r--r--include/trace/events/gfpflags.h1
-rw-r--r--include/trace/events/oom.h4
-rw-r--r--include/trace/events/rcu.h1
-rw-r--r--include/trace/events/task.h8
-rw-r--r--include/trace/ftrace.h76
-rw-r--r--include/trace/syscall.h23
-rw-r--r--include/uapi/asm-generic/ioctls.h3
-rw-r--r--include/uapi/asm-generic/mman-common.h11
-rw-r--r--include/uapi/asm-generic/mman.h2
-rw-r--r--include/uapi/linux/Kbuild1
-rw-r--r--include/uapi/linux/hw_breakpoint.h30
-rw-r--r--include/uapi/linux/oom.h9
-rw-r--r--include/uapi/linux/serial_core.h5
-rw-r--r--include/uapi/linux/serial_reg.h18
-rw-r--r--init/Kconfig67
-rw-r--r--ipc/shm.c3
-rw-r--r--kernel/Makefile1
-rw-r--r--kernel/auditsc.c2
-rw-r--r--kernel/context_tracking.c83
-rw-r--r--kernel/cpu.c13
-rw-r--r--kernel/events/hw_breakpoint.c12
-rw-r--r--kernel/events/uprobes.c43
-rw-r--r--kernel/exit.c4
-rw-r--r--kernel/fork.c4
-rw-r--r--kernel/futex.c59
-rw-r--r--kernel/irq/chip.c1
-rw-r--r--kernel/irq/irqdomain.c4
-rw-r--r--kernel/irq/manage.c41
-rw-r--r--kernel/irq/resend.c8
-rw-r--r--kernel/ksysfs.c23
-rw-r--r--kernel/lockdep_proc.c2
-rw-r--r--kernel/modsign_pubkey.c4
-rw-r--r--kernel/module_signing.c14
-rw-r--r--kernel/posix-cpu-timers.c24
-rw-r--r--kernel/power/main.c2
-rw-r--r--kernel/power/qos.c65
-rw-r--r--kernel/power/swap.c2
-rw-r--r--kernel/printk.c12
-rw-r--r--kernel/rcu.h2
-rw-r--r--kernel/rcupdate.c3
-rw-r--r--kernel/rcutiny.c2
-rw-r--r--kernel/rcutiny_plugin.h5
-rw-r--r--kernel/rcutorture.c54
-rw-r--r--kernel/rcutree.c347
-rw-r--r--kernel/rcutree.h67
-rw-r--r--kernel/rcutree_plugin.h415
-rw-r--r--kernel/rcutree_trace.c330
-rw-r--r--kernel/sched/core.c34
-rw-r--r--kernel/sched/cputime.c131
-rw-r--r--kernel/sched/debug.c36
-rw-r--r--kernel/sched/fair.c914
-rw-r--r--kernel/sched/features.h5
-rw-r--r--kernel/sched/sched.h60
-rw-r--r--kernel/softirq.c6
-rw-r--r--kernel/srcu.c16
-rw-r--r--kernel/sys.c6
-rw-r--r--kernel/sysctl.c4
-rw-r--r--kernel/time/jiffies.c8
-rw-r--r--kernel/time/tick-common.c8
-rw-r--r--kernel/time/tick-internal.h1
-rw-r--r--kernel/time/tick-sched.c137
-rw-r--r--kernel/time/timekeeping.c14
-rw-r--r--kernel/trace/Kconfig1
-rw-r--r--kernel/trace/ftrace.c8
-rw-r--r--kernel/trace/ring_buffer.c65
-rw-r--r--kernel/trace/trace.c411
-rw-r--r--kernel/trace/trace.h18
-rw-r--r--kernel/trace/trace_branch.c4
-rw-r--r--kernel/trace/trace_events.c51
-rw-r--r--kernel/trace/trace_events_filter.c4
-rw-r--r--kernel/trace/trace_functions.c5
-rw-r--r--kernel/trace/trace_functions_graph.c6
-rw-r--r--kernel/trace/trace_irqsoff.c14
-rw-r--r--kernel/trace/trace_kprobe.c10
-rw-r--r--kernel/trace/trace_output.c78
-rw-r--r--kernel/trace/trace_probe.c14
-rw-r--r--kernel/trace/trace_sched_switch.c4
-rw-r--r--kernel/trace/trace_sched_wakeup.c10
-rw-r--r--kernel/trace/trace_selftest.c13
-rw-r--r--kernel/trace/trace_syscalls.c61
-rw-r--r--kernel/trace/trace_uprobe.c4
-rw-r--r--kernel/watchdog.c7
-rw-r--r--kernel/workqueue.c22
-rw-r--r--lib/Kconfig.debug2
-rw-r--r--lib/Makefile5
-rw-r--r--lib/asn1_decoder.c2
-rw-r--r--lib/cpumask.c2
-rw-r--r--lib/mpi/longlong.h19
-rw-r--r--mm/Kconfig15
-rw-r--r--mm/Makefile3
-rw-r--r--mm/balloon_compaction.c302
-rw-r--r--mm/bootmem.c30
-rw-r--r--mm/compaction.c37
-rw-r--r--mm/dmapool.c55
-rw-r--r--mm/highmem.c31
-rw-r--r--mm/huge_memory.c174
-rw-r--r--mm/hugetlb.c4
-rw-r--r--mm/internal.h5
-rw-r--r--mm/ksm.c21
-rw-r--r--mm/memcontrol.c71
-rw-r--r--mm/memory-failure.c36
-rw-r--r--mm/memory.c18
-rw-r--r--mm/memory_hotplug.c339
-rw-r--r--mm/mempolicy.c43
-rw-r--r--mm/migrate.c99
-rw-r--r--mm/mmap.c529
-rw-r--r--mm/mmzone.c6
-rw-r--r--mm/nobootmem.c3
-rw-r--r--mm/nommu.c15
-rw-r--r--mm/oom_kill.c86
-rw-r--r--mm/page-writeback.c11
-rw-r--r--mm/page_alloc.c221
-rw-r--r--mm/page_cgroup.c3
-rw-r--r--mm/page_isolation.c27
-rw-r--r--mm/rmap.c56
-rw-r--r--mm/shmem.c44
-rw-r--r--mm/slub.c4
-rw-r--r--mm/sparse.c35
-rw-r--r--mm/swapfile.c35
-rw-r--r--mm/vmalloc.c4
-rw-r--r--mm/vmscan.c132
-rw-r--r--net/batman-adv/soft-interface.c12
-rw-r--r--net/batman-adv/translation-table.c15
-rw-r--r--net/bluetooth/hci_core.c4
-rw-r--r--net/bluetooth/mgmt.c12
-rw-r--r--net/bluetooth/smp.c2
-rw-r--r--net/can/bcm.c3
-rw-r--r--net/core/dev.c6
-rw-r--r--net/core/dev_addr_lists.c3
-rw-r--r--net/core/net-sysfs.c20
-rw-r--r--net/core/skbuff.c6
-rw-r--r--net/ipv4/icmp.c3
-rw-r--r--net/ipv4/inet_diag.c154
-rw-r--r--net/ipv4/ip_fragment.c19
-rw-r--r--net/ipv4/ip_sockglue.c35
-rw-r--r--net/ipv4/ip_vti.c5
-rw-r--r--net/ipv4/ipmr.c4
-rw-r--r--net/ipv4/route.c9
-rw-r--r--net/ipv4/tcp.c19
-rw-r--r--net/ipv4/tcp_input.c21
-rw-r--r--net/ipv4/tcp_metrics.c12
-rw-r--r--net/ipv4/tcp_output.c19
-rw-r--r--net/ipv4/xfrm4_policy.c13
-rw-r--r--net/ipv6/inet6_connection_sock.c3
-rw-r--r--net/ipv6/ipv6_sockglue.c1
-rw-r--r--net/irda/ircomm/ircomm_tty.c1
-rw-r--r--net/irda/irttp.c1
-rw-r--r--net/mac80211/cfg.c3
-rw-r--r--net/mac80211/ibss.c8
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/main.c6
-rw-r--r--net/mac80211/offchannel.c2
-rw-r--r--net/mac80211/scan.c2
-rw-r--r--net/mac80211/sta_info.c11
-rw-r--r--net/mac80211/status.c9
-rw-r--r--net/mac80211/tx.c9
-rw-r--r--net/mac80211/util.c2
-rw-r--r--net/netfilter/ipset/ip_set_hash_ip.c4
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipport.c7
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportip.c7
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportnet.c7
-rw-r--r--net/netfilter/ipset/ip_set_hash_netiface.c2
-rw-r--r--net/netfilter/nfnetlink_cttimeout.c3
-rw-r--r--net/nfc/llcp/llcp.c2
-rw-r--r--net/openvswitch/flow.c14
-rw-r--r--net/openvswitch/vport-netdev.c2
-rw-r--r--net/sctp/chunk.c20
-rw-r--r--net/sctp/proc.c8
-rw-r--r--net/sctp/socket.c4
-rw-r--r--net/sctp/transport.c2
-rw-r--r--net/wireless/reg.c5
-rw-r--r--scripts/Makefile.lib3
-rw-r--r--scripts/dtc/Makefile2
-rw-r--r--scripts/headers_install.pl3
-rw-r--r--scripts/kconfig/expr.h5
-rw-r--r--scripts/kconfig/list.h91
-rw-r--r--scripts/kconfig/lkc_proto.h4
-rw-r--r--scripts/kconfig/mconf.c6
-rw-r--r--scripts/kconfig/menu.c14
-rw-r--r--scripts/mod/modpost.c24
-rwxr-xr-xscripts/sign-file6
-rw-r--r--security/device_cgroup.c18
-rw-r--r--security/selinux/netnode.c3
-rw-r--r--sound/pci/es1968.c11
-rw-r--r--sound/pci/fm801.c11
-rw-r--r--sound/pci/hda/hda_codec.c13
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_intel.c39
-rw-r--r--sound/pci/hda/patch_cirrus.c1
-rw-r--r--sound/pci/hda/patch_realtek.c2
-rw-r--r--sound/soc/codecs/arizona.c4
-rw-r--r--sound/soc/codecs/cs4271.c11
-rw-r--r--sound/soc/codecs/cs42l52.c3
-rw-r--r--sound/soc/codecs/wm5102.c552
-rw-r--r--sound/soc/codecs/wm8978.c2
-rw-r--r--sound/soc/kirkwood/kirkwood-dma.c3
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c74
-rw-r--r--sound/soc/mxs/mxs-saif.c17
-rw-r--r--sound/soc/samsung/Kconfig2
-rw-r--r--sound/soc/samsung/bells.c2
-rw-r--r--sound/soc/soc-core.c5
-rw-r--r--sound/soc/soc-dapm.c2
-rw-r--r--sound/usb/card.c6
-rw-r--r--sound/usb/midi.c8
-rw-r--r--sound/usb/pcm.c2
-rw-r--r--tools/Makefile24
-rw-r--r--tools/hv/hv_kvp_daemon.c40
-rw-r--r--tools/lib/traceevent/Makefile2
-rw-r--r--tools/lib/traceevent/event-parse.c22
-rw-r--r--tools/perf/Documentation/Makefile31
-rw-r--r--tools/perf/Documentation/android.txt78
-rw-r--r--tools/perf/Documentation/perf-diff.txt60
-rw-r--r--tools/perf/Documentation/perf-inject.txt11
-rw-r--r--tools/perf/Documentation/perf-stat.txt5
-rw-r--r--tools/perf/Documentation/perf-trace.txt6
-rw-r--r--tools/perf/Makefile203
-rw-r--r--tools/perf/arch/common.c211
-rw-r--r--tools/perf/arch/common.h10
-rw-r--r--tools/perf/arch/x86/include/perf_regs.h2
-rw-r--r--tools/perf/builtin-annotate.c17
-rw-r--r--tools/perf/builtin-buildid-cache.c1
-rw-r--r--tools/perf/builtin-buildid-list.c6
-rw-r--r--tools/perf/builtin-diff.c437
-rw-r--r--tools/perf/builtin-evlist.c5
-rw-r--r--tools/perf/builtin-inject.c195
-rw-r--r--tools/perf/builtin-kmem.c5
-rw-r--r--tools/perf/builtin-kvm.c156
-rw-r--r--tools/perf/builtin-lock.c2
-rw-r--r--tools/perf/builtin-record.c66
-rw-r--r--tools/perf/builtin-report.c23
-rw-r--r--tools/perf/builtin-sched.c8
-rw-r--r--tools/perf/builtin-script.c87
-rw-r--r--tools/perf/builtin-stat.c54
-rw-r--r--tools/perf/builtin-test.c1547
-rw-r--r--tools/perf/builtin-timechart.c5
-rw-r--r--tools/perf/builtin-top.c17
-rw-r--r--tools/perf/builtin-trace.c403
-rw-r--r--tools/perf/config/feature-tests.mak25
-rw-r--r--tools/perf/config/utilities.mak10
-rw-r--r--tools/perf/perf.c20
-rw-r--r--tools/perf/perf.h34
-rw-r--r--tools/perf/tests/attr.c175
-rw-r--r--tools/perf/tests/attr.py322
-rw-r--r--tools/perf/tests/attr/README64
-rw-r--r--tools/perf/tests/attr/base-record39
-rw-r--r--tools/perf/tests/attr/base-stat39
-rw-r--r--tools/perf/tests/attr/test-record-basic5
-rw-r--r--tools/perf/tests/attr/test-record-branch-any8
-rw-r--r--tools/perf/tests/attr/test-record-branch-filter-any8
-rw-r--r--tools/perf/tests/attr/test-record-branch-filter-any_call8
-rw-r--r--tools/perf/tests/attr/test-record-branch-filter-any_ret8
-rw-r--r--tools/perf/tests/attr/test-record-branch-filter-hv8
-rw-r--r--tools/perf/tests/attr/test-record-branch-filter-ind_call8
-rw-r--r--tools/perf/tests/attr/test-record-branch-filter-k8
-rw-r--r--tools/perf/tests/attr/test-record-branch-filter-u8
-rw-r--r--tools/perf/tests/attr/test-record-count8
-rw-r--r--tools/perf/tests/attr/test-record-data8
-rw-r--r--tools/perf/tests/attr/test-record-freq6
-rw-r--r--tools/perf/tests/attr/test-record-graph-default6
-rw-r--r--tools/perf/tests/attr/test-record-graph-dwarf10
-rw-r--r--tools/perf/tests/attr/test-record-graph-fp6
-rw-r--r--tools/perf/tests/attr/test-record-group18
-rw-r--r--tools/perf/tests/attr/test-record-group119
-rw-r--r--tools/perf/tests/attr/test-record-no-delay9
-rw-r--r--tools/perf/tests/attr/test-record-no-inherit7
-rw-r--r--tools/perf/tests/attr/test-record-no-samples6
-rw-r--r--tools/perf/tests/attr/test-record-period7
-rw-r--r--tools/perf/tests/attr/test-record-raw7
-rw-r--r--tools/perf/tests/attr/test-stat-basic6
-rw-r--r--tools/perf/tests/attr/test-stat-default64
-rw-r--r--tools/perf/tests/attr/test-stat-detailed-1101
-rw-r--r--tools/perf/tests/attr/test-stat-detailed-2155
-rw-r--r--tools/perf/tests/attr/test-stat-detailed-3173
-rw-r--r--tools/perf/tests/attr/test-stat-group15
-rw-r--r--tools/perf/tests/attr/test-stat-group115
-rw-r--r--tools/perf/tests/attr/test-stat-no-inherit7
-rw-r--r--tools/perf/tests/builtin-test.c173
-rw-r--r--tools/perf/tests/dso-data.c (renamed from tools/perf/util/dso-test-data.c)8
-rw-r--r--tools/perf/tests/evsel-roundtrip-name.c114
-rw-r--r--tools/perf/tests/evsel-tp-sched.c84
-rw-r--r--tools/perf/tests/mmap-basic.c162
-rw-r--r--tools/perf/tests/open-syscall-all-cpus.c120
-rw-r--r--tools/perf/tests/open-syscall-tp-fields.c117
-rw-r--r--tools/perf/tests/open-syscall.c66
-rw-r--r--tools/perf/tests/parse-events.c (renamed from tools/perf/util/parse-events-test.c)93
-rw-r--r--tools/perf/tests/perf-record.c312
-rw-r--r--tools/perf/tests/pmu.c178
-rw-r--r--tools/perf/tests/rdpmc.c175
-rw-r--r--tools/perf/tests/tests.h22
-rw-r--r--tools/perf/tests/util.c30
-rw-r--r--tools/perf/tests/vmlinux-kallsyms.c230
-rw-r--r--tools/perf/ui/browsers/annotate.c45
-rw-r--r--tools/perf/ui/browsers/hists.c97
-rw-r--r--tools/perf/ui/browsers/scripts.c189
-rw-r--r--tools/perf/ui/gtk/browser.c4
-rw-r--r--tools/perf/ui/gtk/gtk.h1
-rw-r--r--tools/perf/ui/gtk/progress.c59
-rw-r--r--tools/perf/ui/gtk/setup.c2
-rw-r--r--tools/perf/ui/gtk/util.c11
-rw-r--r--tools/perf/ui/hist.c138
-rw-r--r--tools/perf/ui/progress.c44
-rw-r--r--tools/perf/ui/progress.h10
-rw-r--r--tools/perf/ui/stdio/hist.c2
-rw-r--r--tools/perf/ui/tui/progress.c42
-rw-r--r--tools/perf/ui/tui/setup.c1
-rw-r--r--tools/perf/ui/ui.h28
-rwxr-xr-xtools/perf/util/PERF-VERSION-GEN14
-rw-r--r--tools/perf/util/annotate.c72
-rw-r--r--tools/perf/util/annotate.h10
-rw-r--r--tools/perf/util/build-id.c27
-rw-r--r--tools/perf/util/build-id.h11
-rw-r--r--tools/perf/util/cache.h39
-rw-r--r--tools/perf/util/debug.h1
-rw-r--r--tools/perf/util/dso.c595
-rw-r--r--tools/perf/util/dso.h148
-rw-r--r--tools/perf/util/event.c302
-rw-r--r--tools/perf/util/event.h9
-rw-r--r--tools/perf/util/evlist.c13
-rw-r--r--tools/perf/util/evsel.c56
-rw-r--r--tools/perf/util/evsel.h11
-rw-r--r--tools/perf/util/header.c13
-rw-r--r--tools/perf/util/header.h3
-rw-r--r--tools/perf/util/hist.c99
-rw-r--r--tools/perf/util/hist.h49
-rw-r--r--tools/perf/util/machine.c464
-rw-r--r--tools/perf/util/machine.h148
-rw-r--r--tools/perf/util/map.c182
-rw-r--r--tools/perf/util/map.h93
-rw-r--r--tools/perf/util/parse-events.c56
-rw-r--r--tools/perf/util/parse-events.h5
-rw-r--r--tools/perf/util/parse-events.l4
-rw-r--r--tools/perf/util/parse-events.y18
-rw-r--r--tools/perf/util/pmu.c192
-rw-r--r--tools/perf/util/pmu.h6
-rw-r--r--tools/perf/util/pstack.c46
-rw-r--r--tools/perf/util/python.c2
-rw-r--r--tools/perf/util/rblist.c4
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c1
-rw-r--r--tools/perf/util/session.c5
-rw-r--r--tools/perf/util/session.h7
-rw-r--r--tools/perf/util/sort.h45
-rw-r--r--tools/perf/util/strbuf.c8
-rw-r--r--tools/perf/util/string.c18
-rw-r--r--tools/perf/util/symbol.c658
-rw-r--r--tools/perf/util/symbol.h162
-rw-r--r--tools/perf/util/thread.c41
-rw-r--r--tools/perf/util/thread.h2
-rw-r--r--tools/perf/util/trace-event-read.c2
-rw-r--r--tools/perf/util/util.c35
-rw-r--r--tools/perf/util/util.h8
-rw-r--r--tools/power/cpupower/.gitignore7
-rw-r--r--tools/power/cpupower/Makefile3
-rw-r--r--tools/power/cpupower/debug/i386/Makefile5
-rw-r--r--tools/power/cpupower/man/cpupower-monitor.115
-rw-r--r--tools/power/cpupower/utils/helpers/cpuid.c2
-rw-r--r--tools/power/cpupower/utils/helpers/helpers.h18
-rw-r--r--tools/power/cpupower/utils/helpers/sysfs.c19
-rw-r--r--tools/power/cpupower/utils/helpers/topology.c53
-rw-r--r--tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c21
-rw-r--r--tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h17
-rw-r--r--tools/power/cpupower/utils/idle_monitor/snb_idle.c10
-rw-r--r--tools/power/x86/turbostat/turbostat.c28
-rw-r--r--tools/scripts/Makefile.include23
-rw-r--r--tools/testing/selftests/vm/Makefile4
-rw-r--r--tools/testing/selftests/vm/thuge-gen.c254
3228 files changed, 95747 insertions, 116575 deletions
diff --git a/CREDITS b/CREDITS
index d8fe12a9421..2346b09ca8b 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1823,6 +1823,11 @@ S: Kattreinstr 38
S: D-64295
S: Germany
+N: Avi Kivity
+E: avi.kivity@gmail.com
+D: Kernel-based Virtual Machine (KVM)
+S: Ra'annana, Israel
+
N: Andi Kleen
E: andi@firstfloor.org
U: http://www.halobates.de
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 2f06d40fe07..2e33dc6b234 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -189,6 +189,14 @@ Description:
A computed peak value based on the sum squared magnitude of
the underlying value in the specified directions.
+What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_raw
+What: /sys/bus/iio/devices/iio:deviceX/in_pressure_raw
+KernelVersion: 3.8
+Contact: linux-iio@vger.kernel.org
+Description:
+ Raw pressure measurement from channel Y. Units after
+ application of scale and offset are kilopascal.
+
What: /sys/bus/iio/devices/iio:deviceX/in_accel_offset
What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_offset
What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_offset
@@ -197,6 +205,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_voltage_offset
What: /sys/bus/iio/devices/iio:deviceX/in_tempY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_temp_offset
+What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_offset
+What: /sys/bus/iio/devices/iio:deviceX/in_pressure_offset
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
Description:
@@ -226,6 +236,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_magn_scale
What: /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale
What: /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
What: /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale
+What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
+What: /sys/bus/iio/devices/iio:deviceX/in_pressure_scale
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
Description:
@@ -245,6 +257,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibbias
What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibbias
What: /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibbias
What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibbias
+What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_calibbias
+What: /sys/bus/iio/devices/iio:deviceX/in_pressure_calibbias
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
Description:
@@ -262,6 +276,8 @@ What /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibscale
What /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibscale
what /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibscale
what /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibscale
+What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_calibscale
+What: /sys/bus/iio/devices/iio:deviceX/in_pressure_calibscale
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
Description:
@@ -275,6 +291,8 @@ What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available
What: /sys/.../iio:deviceX/out_voltageX_scale_available
What: /sys/.../iio:deviceX/out_altvoltageX_scale_available
What: /sys/.../iio:deviceX/in_capacitance_scale_available
+What: /sys/.../iio:deviceX/in_pressure_scale_available
+What: /sys/.../iio:deviceX/in_pressureY_scale_available
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
Description:
@@ -694,6 +712,8 @@ What: /sys/.../buffer/scan_elements/in_voltageY_en
What: /sys/.../buffer/scan_elements/in_voltageY-voltageZ_en
What: /sys/.../buffer/scan_elements/in_incli_x_en
What: /sys/.../buffer/scan_elements/in_incli_y_en
+What: /sys/.../buffer/scan_elements/in_pressureY_en
+What: /sys/.../buffer/scan_elements/in_pressure_en
KernelVersion: 2.6.37
Contact: linux-iio@vger.kernel.org
Description:
@@ -707,6 +727,8 @@ What: /sys/.../buffer/scan_elements/in_voltageY_type
What: /sys/.../buffer/scan_elements/in_voltage_type
What: /sys/.../buffer/scan_elements/in_voltageY_supply_type
What: /sys/.../buffer/scan_elements/in_timestamp_type
+What: /sys/.../buffer/scan_elements/in_pressureY_type
+What: /sys/.../buffer/scan_elements/in_pressure_type
KernelVersion: 2.6.37
Contact: linux-iio@vger.kernel.org
Description:
@@ -751,6 +773,8 @@ What: /sys/.../buffer/scan_elements/in_magn_z_index
What: /sys/.../buffer/scan_elements/in_incli_x_index
What: /sys/.../buffer/scan_elements/in_incli_y_index
What: /sys/.../buffer/scan_elements/in_timestamp_index
+What: /sys/.../buffer/scan_elements/in_pressureY_index
+What: /sys/.../buffer/scan_elements/in_pressure_index
KernelVersion: 2.6.37
Contact: linux-iio@vger.kernel.org
Description:
diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq
index 23d78b5aab1..0ba6ea2f89d 100644
--- a/Documentation/ABI/testing/sysfs-class-devfreq
+++ b/Documentation/ABI/testing/sysfs-class-devfreq
@@ -11,7 +11,7 @@ What: /sys/class/devfreq/.../governor
Date: September 2011
Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
Description:
- The /sys/class/devfreq/.../governor shows the name of the
+ The /sys/class/devfreq/.../governor show or set the name of the
governor used by the corresponding devfreq object.
What: /sys/class/devfreq/.../cur_freq
@@ -19,15 +19,16 @@ Date: September 2011
Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
Description:
The /sys/class/devfreq/.../cur_freq shows the current
- frequency of the corresponding devfreq object.
+ frequency of the corresponding devfreq object. Same as
+ target_freq when get_cur_freq() is not implemented by
+ devfreq driver.
-What: /sys/class/devfreq/.../central_polling
-Date: September 2011
-Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
+What: /sys/class/devfreq/.../target_freq
+Date: September 2012
+Contact: Rajagopal Venkat <rajagopal.venkat@linaro.org>
Description:
- The /sys/class/devfreq/.../central_polling shows whether
- the devfreq ojbect is using devfreq-provided central
- polling mechanism or not.
+ The /sys/class/devfreq/.../target_freq shows the next governor
+ predicted target frequency of the corresponding devfreq object.
What: /sys/class/devfreq/.../polling_interval
Date: September 2011
@@ -43,6 +44,17 @@ Description:
(/sys/class/devfreq/.../central_polling is 0), this value
may be useless.
+What: /sys/class/devfreq/.../trans_stat
+Date: October 2012
+Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
+Descrtiption:
+ This ABI shows the statistics of devfreq behavior on a
+ specific device. It shows the time spent in each state and
+ the number of transitions between states.
+ In order to activate this ABI, the devfreq target device
+ driver should provide the list of available frequencies
+ with its profile.
+
What: /sys/class/devfreq/.../userspace/set_freq
Date: September 2011
Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
@@ -50,3 +62,19 @@ Description:
The /sys/class/devfreq/.../userspace/set_freq shows and
sets the requested frequency for the devfreq object if
userspace governor is in effect.
+
+What: /sys/class/devfreq/.../available_frequencies
+Date: October 2012
+Contact: Nishanth Menon <nm@ti.com>
+Description:
+ The /sys/class/devfreq/.../available_frequencies shows
+ the available frequencies of the corresponding devfreq object.
+ This is a snapshot of available frequencies and not limited
+ by the min/max frequency restrictions.
+
+What: /sys/class/devfreq/.../available_governors
+Date: October 2012
+Contact: Nishanth Menon <nm@ti.com>
+Description:
+ The /sys/class/devfreq/.../available_governors shows
+ currently available governors in the system.
diff --git a/Documentation/ABI/testing/sysfs-devices-power b/Documentation/ABI/testing/sysfs-devices-power
index 45000f0db4d..7fc2997b23a 100644
--- a/Documentation/ABI/testing/sysfs-devices-power
+++ b/Documentation/ABI/testing/sysfs-devices-power
@@ -204,3 +204,34 @@ Description:
This attribute has no effect on system-wide suspend/resume and
hibernation.
+
+What: /sys/devices/.../power/pm_qos_no_power_off
+Date: September 2012
+Contact: Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+ The /sys/devices/.../power/pm_qos_no_power_off attribute
+ is used for manipulating the PM QoS "no power off" flag. If
+ set, this flag indicates to the kernel that power should not
+ be removed entirely from the device.
+
+ Not all drivers support this attribute. If it isn't supported,
+ it is not present.
+
+ This attribute has no effect on system-wide suspend/resume and
+ hibernation.
+
+What: /sys/devices/.../power/pm_qos_remote_wakeup
+Date: September 2012
+Contact: Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+ The /sys/devices/.../power/pm_qos_remote_wakeup attribute
+ is used for manipulating the PM QoS "remote wakeup required"
+ flag. If set, this flag indicates to the kernel that the
+ device is a source of user events that have to be signaled from
+ its low-power states.
+
+ Not all drivers support this attribute. If it isn't supported,
+ it is not present.
+
+ This attribute has no effect on system-wide suspend/resume and
+ hibernation.
diff --git a/Documentation/ABI/testing/sysfs-devices-sun b/Documentation/ABI/testing/sysfs-devices-sun
new file mode 100644
index 00000000000..86be9848a77
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-sun
@@ -0,0 +1,14 @@
+Whatt: /sys/devices/.../sun
+Date: October 2012
+Contact: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
+Description:
+ The file contains a Slot-unique ID which provided by the _SUN
+ method in the ACPI namespace. The value is written in Advanced
+ Configuration and Power Interface Specification as follows:
+
+ "The _SUN value is required to be unique among the slots of
+ the same type. It is also recommended that this number match
+ the slot number printed on the physical slot whenever possible."
+
+ So reading the sysfs file, we can identify a physical position
+ of the slot in the system.
diff --git a/Documentation/ABI/testing/sysfs-tty b/Documentation/ABI/testing/sysfs-tty
index 0c430150d92..ad22fb0ee76 100644
--- a/Documentation/ABI/testing/sysfs-tty
+++ b/Documentation/ABI/testing/sysfs-tty
@@ -26,3 +26,115 @@ Description:
UART port in serial_core, that is bound to TTY like ttyS0.
uartclk = 16 * baud_base
+ These sysfs values expose the TIOCGSERIAL interface via
+ sysfs rather than via ioctls.
+
+What: /sys/class/tty/ttyS0/type
+Date: October 2012
+Contact: Alan Cox <alan@linux.intel.com>
+Description:
+ Shows the current tty type for this port.
+
+ These sysfs values expose the TIOCGSERIAL interface via
+ sysfs rather than via ioctls.
+
+What: /sys/class/tty/ttyS0/line
+Date: October 2012
+Contact: Alan Cox <alan@linux.intel.com>
+Description:
+ Shows the current tty line number for this port.
+
+ These sysfs values expose the TIOCGSERIAL interface via
+ sysfs rather than via ioctls.
+
+What: /sys/class/tty/ttyS0/port
+Date: October 2012
+Contact: Alan Cox <alan@linux.intel.com>
+Description:
+ Shows the current tty port I/O address for this port.
+
+ These sysfs values expose the TIOCGSERIAL interface via
+ sysfs rather than via ioctls.
+
+What: /sys/class/tty/ttyS0/irq
+Date: October 2012
+Contact: Alan Cox <alan@linux.intel.com>
+Description:
+ Shows the current primary interrupt for this port.
+
+ These sysfs values expose the TIOCGSERIAL interface via
+ sysfs rather than via ioctls.
+
+What: /sys/class/tty/ttyS0/flags
+Date: October 2012
+Contact: Alan Cox <alan@linux.intel.com>
+Description:
+ Show the tty port status flags for this port.
+
+ These sysfs values expose the TIOCGSERIAL interface via
+ sysfs rather than via ioctls.
+
+What: /sys/class/tty/ttyS0/xmit_fifo_size
+Date: October 2012
+Contact: Alan Cox <alan@linux.intel.com>
+Description:
+ Show the transmit FIFO size for this port.
+
+ These sysfs values expose the TIOCGSERIAL interface via
+ sysfs rather than via ioctls.
+
+What: /sys/class/tty/ttyS0/close_delay
+Date: October 2012
+Contact: Alan Cox <alan@linux.intel.com>
+Description:
+ Show the closing delay time for this port in ms.
+
+ These sysfs values expose the TIOCGSERIAL interface via
+ sysfs rather than via ioctls.
+
+What: /sys/class/tty/ttyS0/closing_wait
+Date: October 2012
+Contact: Alan Cox <alan@linux.intel.com>
+Description:
+ Show the close wait time for this port in ms.
+
+ These sysfs values expose the TIOCGSERIAL interface via
+ sysfs rather than via ioctls.
+
+What: /sys/class/tty/ttyS0/custom_divisor
+Date: October 2012
+Contact: Alan Cox <alan@linux.intel.com>
+Description:
+ Show the custom divisor if any that is set on this port.
+
+ These sysfs values expose the TIOCGSERIAL interface via
+ sysfs rather than via ioctls.
+
+What: /sys/class/tty/ttyS0/io_type
+Date: October 2012
+Contact: Alan Cox <alan@linux.intel.com>
+Description:
+ Show the I/O type that is to be used with the iomem base
+ address.
+
+ These sysfs values expose the TIOCGSERIAL interface via
+ sysfs rather than via ioctls.
+
+What: /sys/class/tty/ttyS0/iomem_base
+Date: October 2012
+Contact: Alan Cox <alan@linux.intel.com>
+Description:
+ The I/O memory base for this port.
+
+ These sysfs values expose the TIOCGSERIAL interface via
+ sysfs rather than via ioctls.
+
+What: /sys/class/tty/ttyS0/iomem_reg_shift
+Date: October 2012
+Contact: Alan Cox <alan@linux.intel.com>
+Description:
+ Show the register shift indicating the spacing to be used
+ for accesses on this iomem address.
+
+ These sysfs values expose the TIOCGSERIAL interface via
+ sysfs rather than via ioctls.
diff --git a/Documentation/DocBook/gadget.tmpl b/Documentation/DocBook/gadget.tmpl
index 6ef2f0073e5..4017f147ba2 100644
--- a/Documentation/DocBook/gadget.tmpl
+++ b/Documentation/DocBook/gadget.tmpl
@@ -671,7 +671,7 @@ than a kernel driver.
<para>There's a USB Mass Storage class driver, which provides
a different solution for interoperability with systems such
as MS-Windows and MacOS.
-That <emphasis>File-backed Storage</emphasis> driver uses a
+That <emphasis>Mass Storage</emphasis> driver uses a
file or block device as backing store for a drive,
like the <filename>loop</filename> driver.
The USB host uses the BBB, CB, or CBI versions of the mass
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
index ac3d0018140..ddb05e98af0 100644
--- a/Documentation/DocBook/uio-howto.tmpl
+++ b/Documentation/DocBook/uio-howto.tmpl
@@ -719,6 +719,62 @@ framework to set up sysfs files for this region. Simply leave it alone.
</para>
</sect1>
+<sect1 id="using uio_dmem_genirq">
+<title>Using uio_dmem_genirq for platform devices</title>
+ <para>
+ In addition to statically allocated memory ranges, they may also be
+ a desire to use dynamically allocated regions in a user space driver.
+ In particular, being able to access memory made available through the
+ dma-mapping API, may be particularly useful. The
+ <varname>uio_dmem_genirq</varname> driver provides a way to accomplish
+ this.
+ </para>
+ <para>
+ This driver is used in a similar manner to the
+ <varname>"uio_pdrv_genirq"</varname> driver with respect to interrupt
+ configuration and handling.
+ </para>
+ <para>
+ Set the <varname>.name</varname> element of
+ <varname>struct platform_device</varname> to
+ <varname>"uio_dmem_genirq"</varname> to use this driver.
+ </para>
+ <para>
+ When using this driver, fill in the <varname>.platform_data</varname>
+ element of <varname>struct platform_device</varname>, which is of type
+ <varname>struct uio_dmem_genirq_pdata</varname> and which contains the
+ following elements:
+ </para>
+ <itemizedlist>
+ <listitem><varname>struct uio_info uioinfo</varname>: The same
+ structure used as the <varname>uio_pdrv_genirq</varname> platform
+ data</listitem>
+ <listitem><varname>unsigned int *dynamic_region_sizes</varname>:
+ Pointer to list of sizes of dynamic memory regions to be mapped into
+ user space.
+ </listitem>
+ <listitem><varname>unsigned int num_dynamic_regions</varname>:
+ Number of elements in <varname>dynamic_region_sizes</varname> array.
+ </listitem>
+ </itemizedlist>
+ <para>
+ The dynamic regions defined in the platform data will be appended to
+ the <varname> mem[] </varname> array after the platform device
+ resources, which implies that the total number of static and dynamic
+ memory regions cannot exceed <varname>MAX_UIO_MAPS</varname>.
+ </para>
+ <para>
+ The dynamic memory regions will be allocated when the UIO device file,
+ <varname>/dev/uioX</varname> is opened.
+ Simiar to static memory resources, the memory region information for
+ dynamic regions is then visible via sysfs at
+ <varname>/sys/class/uio/uioX/maps/mapY/*</varname>.
+ The dynmaic memory regions will be freed when the UIO device file is
+ closed. When no processes are holding the device file open, the address
+ returned to userspace is ~0.
+ </para>
+</sect1>
+
</chapter>
<chapter id="userspace_driver" xreflabel="Writing a driver in user space">
diff --git a/Documentation/IRQ-domain.txt b/Documentation/IRQ-domain.txt
index 1401cece745..9bc95942ec2 100644
--- a/Documentation/IRQ-domain.txt
+++ b/Documentation/IRQ-domain.txt
@@ -7,6 +7,21 @@ systems with multiple interrupt controllers the kernel must ensure
that each one gets assigned non-overlapping allocations of Linux
IRQ numbers.
+The number of interrupt controllers registered as unique irqchips
+show a rising tendency: for example subdrivers of different kinds
+such as GPIO controllers avoid reimplementing identical callback
+mechanisms as the IRQ core system by modelling their interrupt
+handlers as irqchips, i.e. in effect cascading interrupt controllers.
+
+Here the interrupt number loose all kind of correspondence to
+hardware interrupt numbers: whereas in the past, IRQ numbers could
+be chosen so they matched the hardware IRQ line into the root
+interrupt controller (i.e. the component actually fireing the
+interrupt line to the CPU) nowadays this number is just a number.
+
+For this reason we need a mechanism to separate controller-local
+interrupt numbers, called hardware irq's, from Linux IRQ numbers.
+
The irq_alloc_desc*() and irq_free_desc*() APIs provide allocation of
irq numbers, but they don't provide any support for reverse mapping of
the controller-local IRQ (hwirq) number into the Linux IRQ number
@@ -40,6 +55,10 @@ required hardware setup.
When an interrupt is received, irq_find_mapping() function should
be used to find the Linux IRQ number from the hwirq number.
+The irq_create_mapping() function must be called *atleast once*
+before any call to irq_find_mapping(), lest the descriptor will not
+be allocated.
+
If the driver has the Linux IRQ number or the irq_data pointer, and
needs to know the associated hwirq number (such as in the irq_chip
callbacks) then it can be directly obtained from irq_data->hwirq.
@@ -119,4 +138,17 @@ numbers.
Most users of legacy mappings should use irq_domain_add_simple() which
will use a legacy domain only if an IRQ range is supplied by the
-system and will otherwise use a linear domain mapping.
+system and will otherwise use a linear domain mapping. The semantics
+of this call are such that if an IRQ range is specified then
+descriptors will be allocated on-the-fly for it, and if no range is
+specified it will fall through to irq_domain_add_linear() which meand
+*no* irq descriptors will be allocated.
+
+A typical use case for simple domains is where an irqchip provider
+is supporting both dynamic and static IRQ assignments.
+
+In order to avoid ending up in a situation where a linear domain is
+used and no descriptor gets allocated it is very important to make sure
+that the driver using the simple domain call irq_create_mapping()
+before any irq_find_mapping() since the latter will actually work
+for the static IRQ assignment case.
diff --git a/Documentation/RCU/RTFP.txt b/Documentation/RCU/RTFP.txt
index 7c1dfb19fc4..7f40c72a9c5 100644
--- a/Documentation/RCU/RTFP.txt
+++ b/Documentation/RCU/RTFP.txt
@@ -186,7 +186,7 @@ Bibtex Entries
@article{Kung80
,author="H. T. Kung and Q. Lehman"
-,title="Concurrent Maintenance of Binary Search Trees"
+,title="Concurrent Manipulation of Binary Search Trees"
,Year="1980"
,Month="September"
,journal="ACM Transactions on Database Systems"
diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt
index cdb20d41a44..31ef8fe07f8 100644
--- a/Documentation/RCU/checklist.txt
+++ b/Documentation/RCU/checklist.txt
@@ -271,15 +271,14 @@ over a rather long period of time, but improvements are always welcome!
The same cautions apply to call_rcu_bh() and call_rcu_sched().
9. All RCU list-traversal primitives, which include
- rcu_dereference(), list_for_each_entry_rcu(),
- list_for_each_continue_rcu(), and list_for_each_safe_rcu(),
- must be either within an RCU read-side critical section or
- must be protected by appropriate update-side locks. RCU
- read-side critical sections are delimited by rcu_read_lock()
- and rcu_read_unlock(), or by similar primitives such as
- rcu_read_lock_bh() and rcu_read_unlock_bh(), in which case
- the matching rcu_dereference() primitive must be used in order
- to keep lockdep happy, in this case, rcu_dereference_bh().
+ rcu_dereference(), list_for_each_entry_rcu(), and
+ list_for_each_safe_rcu(), must be either within an RCU read-side
+ critical section or must be protected by appropriate update-side
+ locks. RCU read-side critical sections are delimited by
+ rcu_read_lock() and rcu_read_unlock(), or by similar primitives
+ such as rcu_read_lock_bh() and rcu_read_unlock_bh(), in which
+ case the matching rcu_dereference() primitive must be used in
+ order to keep lockdep happy, in this case, rcu_dereference_bh().
The reason that it is permissible to use RCU list-traversal
primitives when the update-side lock is held is that doing so
diff --git a/Documentation/RCU/listRCU.txt b/Documentation/RCU/listRCU.txt
index 4349c1487e9..adb5a378284 100644
--- a/Documentation/RCU/listRCU.txt
+++ b/Documentation/RCU/listRCU.txt
@@ -205,7 +205,7 @@ RCU ("read-copy update") its name. The RCU code is as follows:
audit_copy_rule(&ne->rule, &e->rule);
ne->rule.action = newaction;
ne->rule.file_count = newfield_count;
- list_replace_rcu(e, ne);
+ list_replace_rcu(&e->list, &ne->list);
call_rcu(&e->rcu, audit_free_rule);
return 0;
}
diff --git a/Documentation/RCU/rcuref.txt b/Documentation/RCU/rcuref.txt
index 4202ad09313..141d531aa14 100644
--- a/Documentation/RCU/rcuref.txt
+++ b/Documentation/RCU/rcuref.txt
@@ -20,7 +20,7 @@ release_referenced() delete()
{ {
... write_lock(&list_lock);
atomic_dec(&el->rc, relfunc) ...
- ... delete_element
+ ... remove_element
} write_unlock(&list_lock);
...
if (atomic_dec_and_test(&el->rc))
@@ -52,7 +52,7 @@ release_referenced() delete()
{ {
... spin_lock(&list_lock);
if (atomic_dec_and_test(&el->rc)) ...
- call_rcu(&el->head, el_free); delete_element
+ call_rcu(&el->head, el_free); remove_element
... spin_unlock(&list_lock);
} ...
if (atomic_dec_and_test(&el->rc))
@@ -64,3 +64,60 @@ Sometimes, a reference to the element needs to be obtained in the
update (write) stream. In such cases, atomic_inc_not_zero() might be
overkill, since we hold the update-side spinlock. One might instead
use atomic_inc() in such cases.
+
+It is not always convenient to deal with "FAIL" in the
+search_and_reference() code path. In such cases, the
+atomic_dec_and_test() may be moved from delete() to el_free()
+as follows:
+
+1. 2.
+add() search_and_reference()
+{ {
+ alloc_object rcu_read_lock();
+ ... search_for_element
+ atomic_set(&el->rc, 1); atomic_inc(&el->rc);
+ spin_lock(&list_lock); ...
+
+ add_element rcu_read_unlock();
+ ... }
+ spin_unlock(&list_lock); 4.
+} delete()
+3. {
+release_referenced() spin_lock(&list_lock);
+{ ...
+ ... remove_element
+ if (atomic_dec_and_test(&el->rc)) spin_unlock(&list_lock);
+ kfree(el); ...
+ ... call_rcu(&el->head, el_free);
+} ...
+5. }
+void el_free(struct rcu_head *rhp)
+{
+ release_referenced();
+}
+
+The key point is that the initial reference added by add() is not removed
+until after a grace period has elapsed following removal. This means that
+search_and_reference() cannot find this element, which means that the value
+of el->rc cannot increase. Thus, once it reaches zero, there are no
+readers that can or ever will be able to reference the element. The
+element can therefore safely be freed. This in turn guarantees that if
+any reader finds the element, that reader may safely acquire a reference
+without checking the value of the reference counter.
+
+In cases where delete() can sleep, synchronize_rcu() can be called from
+delete(), so that el_free() can be subsumed into delete as follows:
+
+4.
+delete()
+{
+ spin_lock(&list_lock);
+ ...
+ remove_element
+ spin_unlock(&list_lock);
+ ...
+ synchronize_rcu();
+ if (atomic_dec_and_test(&el->rc))
+ kfree(el);
+ ...
+}
diff --git a/Documentation/RCU/trace.txt b/Documentation/RCU/trace.txt
index 672d1908325..c776968f446 100644
--- a/Documentation/RCU/trace.txt
+++ b/Documentation/RCU/trace.txt
@@ -10,51 +10,63 @@ for rcutree and next for rcutiny.
CONFIG_TREE_RCU and CONFIG_TREE_PREEMPT_RCU debugfs Files and Formats
-These implementations of RCU provides several debugfs files under the
+These implementations of RCU provide several debugfs directories under the
top-level directory "rcu":
-rcu/rcudata:
+rcu/rcu_bh
+rcu/rcu_preempt
+rcu/rcu_sched
+
+Each directory contains files for the corresponding flavor of RCU.
+Note that rcu/rcu_preempt is only present for CONFIG_TREE_PREEMPT_RCU.
+For CONFIG_TREE_RCU, the RCU flavor maps onto the RCU-sched flavor,
+so that activity for both appears in rcu/rcu_sched.
+
+In addition, the following file appears in the top-level directory:
+rcu/rcutorture. This file displays rcutorture test progress. The output
+of "cat rcu/rcutorture" looks as follows:
+
+rcutorture test sequence: 0 (test in progress)
+rcutorture update version number: 615
+
+The first line shows the number of rcutorture tests that have completed
+since boot. If a test is currently running, the "(test in progress)"
+string will appear as shown above. The second line shows the number of
+update cycles that the current test has started, or zero if there is
+no test in progress.
+
+
+Within each flavor directory (rcu/rcu_bh, rcu/rcu_sched, and possibly
+also rcu/rcu_preempt) the following files will be present:
+
+rcudata:
Displays fields in struct rcu_data.
-rcu/rcudata.csv:
- Comma-separated values spreadsheet version of rcudata.
-rcu/rcugp:
+rcuexp:
+ Displays statistics for expedited grace periods.
+rcugp:
Displays grace-period counters.
-rcu/rcuhier:
+rcuhier:
Displays the struct rcu_node hierarchy.
-rcu/rcu_pending:
+rcu_pending:
Displays counts of the reasons rcu_pending() decided that RCU had
work to do.
-rcu/rcutorture:
- Displays rcutorture test progress.
-rcu/rcuboost:
+rcuboost:
Displays RCU boosting statistics. Only present if
CONFIG_RCU_BOOST=y.
-The output of "cat rcu/rcudata" looks as follows:
-
-rcu_sched:
- 0 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=545/1/0 df=50 of=0 ql=163 qs=NRW. kt=0/W/0 ktl=ebc3 b=10 ci=153737 co=0 ca=0
- 1 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=967/1/0 df=58 of=0 ql=634 qs=NRW. kt=0/W/1 ktl=58c b=10 ci=191037 co=0 ca=0
- 2 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=1081/1/0 df=175 of=0 ql=74 qs=N.W. kt=0/W/2 ktl=da94 b=10 ci=75991 co=0 ca=0
- 3 c=20942 g=20943 pq=1 pgp=20942 qp=1 dt=1846/0/0 df=404 of=0 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=72261 co=0 ca=0
- 4 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=369/1/0 df=83 of=0 ql=48 qs=N.W. kt=0/W/4 ktl=e0e7 b=10 ci=128365 co=0 ca=0
- 5 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=381/1/0 df=64 of=0 ql=169 qs=NRW. kt=0/W/5 ktl=fb2f b=10 ci=164360 co=0 ca=0
- 6 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=1037/1/0 df=183 of=0 ql=62 qs=N.W. kt=0/W/6 ktl=d2ad b=10 ci=65663 co=0 ca=0
- 7 c=20897 g=20897 pq=1 pgp=20896 qp=0 dt=1572/0/0 df=382 of=0 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=75006 co=0 ca=0
-rcu_bh:
- 0 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=545/1/0 df=6 of=0 ql=0 qs=.... kt=0/W/0 ktl=ebc3 b=10 ci=0 co=0 ca=0
- 1 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=967/1/0 df=3 of=0 ql=0 qs=.... kt=0/W/1 ktl=58c b=10 ci=151 co=0 ca=0
- 2 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1081/1/0 df=6 of=0 ql=0 qs=.... kt=0/W/2 ktl=da94 b=10 ci=0 co=0 ca=0
- 3 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1846/0/0 df=8 of=0 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=0 co=0 ca=0
- 4 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=369/1/0 df=6 of=0 ql=0 qs=.... kt=0/W/4 ktl=e0e7 b=10 ci=0 co=0 ca=0
- 5 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=381/1/0 df=4 of=0 ql=0 qs=.... kt=0/W/5 ktl=fb2f b=10 ci=0 co=0 ca=0
- 6 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1037/1/0 df=6 of=0 ql=0 qs=.... kt=0/W/6 ktl=d2ad b=10 ci=0 co=0 ca=0
- 7 c=1474 g=1474 pq=1 pgp=1473 qp=0 dt=1572/0/0 df=8 of=0 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=0 co=0 ca=0
-
-The first section lists the rcu_data structures for rcu_sched, the second
-for rcu_bh. Note that CONFIG_TREE_PREEMPT_RCU kernels will have an
-additional section for rcu_preempt. Each section has one line per CPU,
-or eight for this 8-CPU system. The fields are as follows:
+The output of "cat rcu/rcu_preempt/rcudata" looks as follows:
+
+ 0!c=30455 g=30456 pq=1 qp=1 dt=126535/140000000000000/0 df=2002 of=4 ql=0/0 qs=N... b=10 ci=74572 nci=0 co=1131 ca=716
+ 1!c=30719 g=30720 pq=1 qp=0 dt=132007/140000000000000/0 df=1874 of=10 ql=0/0 qs=N... b=10 ci=123209 nci=0 co=685 ca=982
+ 2!c=30150 g=30151 pq=1 qp=1 dt=138537/140000000000000/0 df=1707 of=8 ql=0/0 qs=N... b=10 ci=80132 nci=0 co=1328 ca=1458
+ 3 c=31249 g=31250 pq=1 qp=0 dt=107255/140000000000000/0 df=1749 of=6 ql=0/450 qs=NRW. b=10 ci=151700 nci=0 co=509 ca=622
+ 4!c=29502 g=29503 pq=1 qp=1 dt=83647/140000000000000/0 df=965 of=5 ql=0/0 qs=N... b=10 ci=65643 nci=0 co=1373 ca=1521
+ 5 c=31201 g=31202 pq=1 qp=1 dt=70422/0/0 df=535 of=7 ql=0/0 qs=.... b=10 ci=58500 nci=0 co=764 ca=698
+ 6!c=30253 g=30254 pq=1 qp=1 dt=95363/140000000000000/0 df=780 of=5 ql=0/0 qs=N... b=10 ci=100607 nci=0 co=1414 ca=1353
+ 7 c=31178 g=31178 pq=1 qp=0 dt=91536/0/0 df=547 of=4 ql=0/0 qs=.... b=10 ci=109819 nci=0 co=1115 ca=969
+
+This file has one line per CPU, or eight for this 8-CPU system.
+The fields are as follows:
o The number at the beginning of each line is the CPU number.
CPUs numbers followed by an exclamation mark are offline,
@@ -64,11 +76,13 @@ o The number at the beginning of each line is the CPU number.
substantially larger than the number of actual CPUs.
o "c" is the count of grace periods that this CPU believes have
- completed. Offlined CPUs and CPUs in dynticks idle mode may
- lag quite a ways behind, for example, CPU 6 under "rcu_sched"
- above, which has been offline through not quite 40,000 RCU grace
- periods. It is not unusual to see CPUs lagging by thousands of
- grace periods.
+ completed. Offlined CPUs and CPUs in dynticks idle mode may lag
+ quite a ways behind, for example, CPU 4 under "rcu_sched" above,
+ which has been offline through 16 RCU grace periods. It is not
+ unusual to see offline CPUs lagging by thousands of grace periods.
+ Note that although the grace-period number is an unsigned long,
+ it is printed out as a signed long to allow more human-friendly
+ representation near boot time.
o "g" is the count of grace periods that this CPU believes have
started. Again, offlined CPUs and CPUs in dynticks idle mode
@@ -84,30 +98,25 @@ o "pq" indicates that this CPU has passed through a quiescent state
CPU has not yet reported that fact, (2) some other CPU has not
yet reported for this grace period, or (3) both.
-o "pgp" indicates which grace period the last-observed quiescent
- state for this CPU corresponds to. This is important for handling
- the race between CPU 0 reporting an extended dynticks-idle
- quiescent state for CPU 1 and CPU 1 suddenly waking up and
- reporting its own quiescent state. If CPU 1 was the last CPU
- for the current grace period, then the CPU that loses this race
- will attempt to incorrectly mark CPU 1 as having checked in for
- the next grace period!
-
o "qp" indicates that RCU still expects a quiescent state from
this CPU. Offlined CPUs and CPUs in dyntick idle mode might
well have qp=1, which is OK: RCU is still ignoring them.
o "dt" is the current value of the dyntick counter that is incremented
- when entering or leaving dynticks idle state, either by the
- scheduler or by irq. This number is even if the CPU is in
- dyntick idle mode and odd otherwise. The number after the first
- "/" is the interrupt nesting depth when in dyntick-idle state,
- or one greater than the interrupt-nesting depth otherwise.
- The number after the second "/" is the NMI nesting depth.
+ when entering or leaving idle, either due to a context switch or
+ due to an interrupt. This number is even if the CPU is in idle
+ from RCU's viewpoint and odd otherwise. The number after the
+ first "/" is the interrupt nesting depth when in idle state,
+ or a large number added to the interrupt-nesting depth when
+ running a non-idle task. Some architectures do not accurately
+ count interrupt nesting when running in non-idle kernel context,
+ which can result in interesting anomalies such as negative
+ interrupt-nesting levels. The number after the second "/"
+ is the NMI nesting depth.
o "df" is the number of times that some other CPU has forced a
quiescent state on behalf of this CPU due to this CPU being in
- dynticks-idle state.
+ idle state.
o "of" is the number of times that some other CPU has forced a
quiescent state on behalf of this CPU due to this CPU being
@@ -120,9 +129,13 @@ o "of" is the number of times that some other CPU has forced a
error, so it makes sense to err conservatively.
o "ql" is the number of RCU callbacks currently residing on
- this CPU. This is the total number of callbacks, regardless
- of what state they are in (new, waiting for grace period to
- start, waiting for grace period to end, ready to invoke).
+ this CPU. The first number is the number of "lazy" callbacks
+ that are known to RCU to only be freeing memory, and the number
+ after the "/" is the total number of callbacks, lazy or not.
+ These counters count callbacks regardless of what phase of
+ grace-period processing that they are in (new, waiting for
+ grace period to start, waiting for grace period to end, ready
+ to invoke).
o "qs" gives an indication of the state of the callback queue
with four characters:
@@ -150,6 +163,43 @@ o "qs" gives an indication of the state of the callback queue
If there are no callbacks in a given one of the above states,
the corresponding character is replaced by ".".
+o "b" is the batch limit for this CPU. If more than this number
+ of RCU callbacks is ready to invoke, then the remainder will
+ be deferred.
+
+o "ci" is the number of RCU callbacks that have been invoked for
+ this CPU. Note that ci+nci+ql is the number of callbacks that have
+ been registered in absence of CPU-hotplug activity.
+
+o "nci" is the number of RCU callbacks that have been offloaded from
+ this CPU. This will always be zero unless the kernel was built
+ with CONFIG_RCU_NOCB_CPU=y and the "rcu_nocbs=" kernel boot
+ parameter was specified.
+
+o "co" is the number of RCU callbacks that have been orphaned due to
+ this CPU going offline. These orphaned callbacks have been moved
+ to an arbitrarily chosen online CPU.
+
+o "ca" is the number of RCU callbacks that have been adopted by this
+ CPU due to other CPUs going offline. Note that ci+co-ca+ql is
+ the number of RCU callbacks registered on this CPU.
+
+
+Kernels compiled with CONFIG_RCU_BOOST=y display the following from
+/debug/rcu/rcu_preempt/rcudata:
+
+ 0!c=12865 g=12866 pq=1 qp=1 dt=83113/140000000000000/0 df=288 of=11 ql=0/0 qs=N... kt=0/O ktl=944 b=10 ci=60709 nci=0 co=748 ca=871
+ 1 c=14407 g=14408 pq=1 qp=0 dt=100679/140000000000000/0 df=378 of=7 ql=0/119 qs=NRW. kt=0/W ktl=9b6 b=10 ci=109740 nci=0 co=589 ca=485
+ 2 c=14407 g=14408 pq=1 qp=0 dt=105486/0/0 df=90 of=9 ql=0/89 qs=NRW. kt=0/W ktl=c0c b=10 ci=83113 nci=0 co=533 ca=490
+ 3 c=14407 g=14408 pq=1 qp=0 dt=107138/0/0 df=142 of=8 ql=0/188 qs=NRW. kt=0/W ktl=b96 b=10 ci=121114 nci=0 co=426 ca=290
+ 4 c=14405 g=14406 pq=1 qp=1 dt=50238/0/0 df=706 of=7 ql=0/0 qs=.... kt=0/W ktl=812 b=10 ci=34929 nci=0 co=643 ca=114
+ 5!c=14168 g=14169 pq=1 qp=0 dt=45465/140000000000000/0 df=161 of=11 ql=0/0 qs=N... kt=0/O ktl=b4d b=10 ci=47712 nci=0 co=677 ca=722
+ 6 c=14404 g=14405 pq=1 qp=0 dt=59454/0/0 df=94 of=6 ql=0/0 qs=.... kt=0/W ktl=e57 b=10 ci=55597 nci=0 co=701 ca=811
+ 7 c=14407 g=14408 pq=1 qp=1 dt=68850/0/0 df=31 of=8 ql=0/0 qs=.... kt=0/W ktl=14bd b=10 ci=77475 nci=0 co=508 ca=1042
+
+This is similar to the output discussed above, but contains the following
+additional fields:
+
o "kt" is the per-CPU kernel-thread state. The digit preceding
the first slash is zero if there is no work pending and 1
otherwise. The character between the first pair of slashes is
@@ -184,35 +234,51 @@ o "ktl" is the low-order 16 bits (in hexadecimal) of the count of
This field is displayed only for CONFIG_RCU_BOOST kernels.
-o "b" is the batch limit for this CPU. If more than this number
- of RCU callbacks is ready to invoke, then the remainder will
- be deferred.
-o "ci" is the number of RCU callbacks that have been invoked for
- this CPU. Note that ci+ql is the number of callbacks that have
- been registered in absence of CPU-hotplug activity.
+The output of "cat rcu/rcu_preempt/rcuexp" looks as follows:
-o "co" is the number of RCU callbacks that have been orphaned due to
- this CPU going offline. These orphaned callbacks have been moved
- to an arbitrarily chosen online CPU.
+s=21872 d=21872 w=0 tf=0 wd1=0 wd2=0 n=0 sc=21872 dt=21872 dl=0 dx=21872
+
+These fields are as follows:
+
+o "s" is the starting sequence number.
-o "ca" is the number of RCU callbacks that have been adopted due to
- other CPUs going offline. Note that ci+co-ca+ql is the number of
- RCU callbacks registered on this CPU.
+o "d" is the ending sequence number. When the starting and ending
+ numbers differ, there is an expedited grace period in progress.
-There is also an rcu/rcudata.csv file with the same information in
-comma-separated-variable spreadsheet format.
+o "w" is the number of times that the sequence numbers have been
+ in danger of wrapping.
+o "tf" is the number of times that contention has resulted in a
+ failure to begin an expedited grace period.
-The output of "cat rcu/rcugp" looks as follows:
+o "wd1" and "wd2" are the number of times that an attempt to
+ start an expedited grace period found that someone else had
+ completed an expedited grace period that satisfies the
+ attempted request. "Our work is done."
-rcu_sched: completed=33062 gpnum=33063
-rcu_bh: completed=464 gpnum=464
+o "n" is number of times that contention was so great that
+ the request was demoted from an expedited grace period to
+ a normal grace period.
+
+o "sc" is the number of times that the attempt to start a
+ new expedited grace period succeeded.
+
+o "dt" is the number of times that we attempted to update
+ the "d" counter.
+
+o "dl" is the number of times that we failed to update the "d"
+ counter.
+
+o "dx" is the number of times that we succeeded in updating
+ the "d" counter.
-Again, this output is for both "rcu_sched" and "rcu_bh". Note that
-kernels built with CONFIG_TREE_PREEMPT_RCU will have an additional
-"rcu_preempt" line. The fields are taken from the rcu_state structure,
-and are as follows:
+
+The output of "cat rcu/rcu_preempt/rcugp" looks as follows:
+
+completed=31249 gpnum=31250 age=1 max=18
+
+These fields are taken from the rcu_state structure, and are as follows:
o "completed" is the number of grace periods that have completed.
It is comparable to the "c" field from rcu/rcudata in that a
@@ -220,44 +286,42 @@ o "completed" is the number of grace periods that have completed.
that the corresponding RCU grace period has completed.
o "gpnum" is the number of grace periods that have started. It is
- comparable to the "g" field from rcu/rcudata in that a CPU
- whose "g" field matches the value of "gpnum" is aware that the
- corresponding RCU grace period has started.
+ similarly comparable to the "g" field from rcu/rcudata in that
+ a CPU whose "g" field matches the value of "gpnum" is aware that
+ the corresponding RCU grace period has started.
+
+ If these two fields are equal, then there is no grace period
+ in progress, in other words, RCU is idle. On the other hand,
+ if the two fields differ (as they are above), then an RCU grace
+ period is in progress.
- If these two fields are equal (as they are for "rcu_bh" above),
- then there is no grace period in progress, in other words, RCU
- is idle. On the other hand, if the two fields differ (as they
- do for "rcu_sched" above), then an RCU grace period is in progress.
+o "age" is the number of jiffies that the current grace period
+ has extended for, or zero if there is no grace period currently
+ in effect.
+o "max" is the age in jiffies of the longest-duration grace period
+ thus far.
-The output of "cat rcu/rcuhier" looks as follows, with very long lines:
+The output of "cat rcu/rcu_preempt/rcuhier" looks as follows:
-c=6902 g=6903 s=2 jfq=3 j=72c7 nfqs=13142/nfqsng=0(13142) fqlh=6
-1/1 ..>. 0:127 ^0
-3/3 ..>. 0:35 ^0 0/0 ..>. 36:71 ^1 0/0 ..>. 72:107 ^2 0/0 ..>. 108:127 ^3
-3/3f ..>. 0:5 ^0 2/3 ..>. 6:11 ^1 0/0 ..>. 12:17 ^2 0/0 ..>. 18:23 ^3 0/0 ..>. 24:29 ^4 0/0 ..>. 30:35 ^5 0/0 ..>. 36:41 ^0 0/0 ..>. 42:47 ^1 0/0 ..>. 48:53 ^2 0/0 ..>. 54:59 ^3 0/0 ..>. 60:65 ^4 0/0 ..>. 66:71 ^5 0/0 ..>. 72:77 ^0 0/0 ..>. 78:83 ^1 0/0 ..>. 84:89 ^2 0/0 ..>. 90:95 ^3 0/0 ..>. 96:101 ^4 0/0 ..>. 102:107 ^5 0/0 ..>. 108:113 ^0 0/0 ..>. 114:119 ^1 0/0 ..>. 120:125 ^2 0/0 ..>. 126:127 ^3
-rcu_bh:
-c=-226 g=-226 s=1 jfq=-5701 j=72c7 nfqs=88/nfqsng=0(88) fqlh=0
-0/1 ..>. 0:127 ^0
-0/3 ..>. 0:35 ^0 0/0 ..>. 36:71 ^1 0/0 ..>. 72:107 ^2 0/0 ..>. 108:127 ^3
-0/3f ..>. 0:5 ^0 0/3 ..>. 6:11 ^1 0/0 ..>. 12:17 ^2 0/0 ..>. 18:23 ^3 0/0 ..>. 24:29 ^4 0/0 ..>. 30:35 ^5 0/0 ..>. 36:41 ^0 0/0 ..>. 42:47 ^1 0/0 ..>. 48:53 ^2 0/0 ..>. 54:59 ^3 0/0 ..>. 60:65 ^4 0/0 ..>. 66:71 ^5 0/0 ..>. 72:77 ^0 0/0 ..>. 78:83 ^1 0/0 ..>. 84:89 ^2 0/0 ..>. 90:95 ^3 0/0 ..>. 96:101 ^4 0/0 ..>. 102:107 ^5 0/0 ..>. 108:113 ^0 0/0 ..>. 114:119 ^1 0/0 ..>. 120:125 ^2 0/0 ..>. 126:127 ^3
+c=14407 g=14408 s=0 jfq=2 j=c863 nfqs=12040/nfqsng=0(12040) fqlh=1051 oqlen=0/0
+3/3 ..>. 0:7 ^0
+e/e ..>. 0:3 ^0 d/d ..>. 4:7 ^1
-This is once again split into "rcu_sched" and "rcu_bh" portions,
-and CONFIG_TREE_PREEMPT_RCU kernels will again have an additional
-"rcu_preempt" section. The fields are as follows:
+The fields are as follows:
-o "c" is exactly the same as "completed" under rcu/rcugp.
+o "c" is exactly the same as "completed" under rcu/rcu_preempt/rcugp.
-o "g" is exactly the same as "gpnum" under rcu/rcugp.
+o "g" is exactly the same as "gpnum" under rcu/rcu_preempt/rcugp.
-o "s" is the "signaled" state that drives force_quiescent_state()'s
+o "s" is the current state of the force_quiescent_state()
state machine.
o "jfq" is the number of jiffies remaining for this grace period
before force_quiescent_state() is invoked to help push things
- along. Note that CPUs in dyntick-idle mode throughout the grace
- period will not report on their own, but rather must be check by
- some other CPU via force_quiescent_state().
+ along. Note that CPUs in idle mode throughout the grace period
+ will not report on their own, but rather must be check by some
+ other CPU via force_quiescent_state().
o "j" is the low-order four hex digits of the jiffies counter.
Yes, Paul did run into a number of problems that turned out to
@@ -268,7 +332,8 @@ o "nfqs" is the number of calls to force_quiescent_state() since
o "nfqsng" is the number of useless calls to force_quiescent_state(),
where there wasn't actually a grace period active. This can
- happen due to races. The number in parentheses is the difference
+ no longer happen due to grace-period processing being pushed
+ into a kthread. The number in parentheses is the difference
between "nfqs" and "nfqsng", or the number of times that
force_quiescent_state() actually did some real work.
@@ -276,28 +341,27 @@ o "fqlh" is the number of calls to force_quiescent_state() that
exited immediately (without even being counted in nfqs above)
due to contention on ->fqslock.
-o Each element of the form "1/1 0:127 ^0" represents one struct
- rcu_node. Each line represents one level of the hierarchy, from
- root to leaves. It is best to think of the rcu_data structures
- as forming yet another level after the leaves. Note that there
- might be either one, two, or three levels of rcu_node structures,
- depending on the relationship between CONFIG_RCU_FANOUT and
- CONFIG_NR_CPUS.
+o Each element of the form "3/3 ..>. 0:7 ^0" represents one rcu_node
+ structure. Each line represents one level of the hierarchy,
+ from root to leaves. It is best to think of the rcu_data
+ structures as forming yet another level after the leaves.
+ Note that there might be either one, two, three, or even four
+ levels of rcu_node structures, depending on the relationship
+ between CONFIG_RCU_FANOUT, CONFIG_RCU_FANOUT_LEAF (possibly
+ adjusted using the rcu_fanout_leaf kernel boot parameter), and
+ CONFIG_NR_CPUS (possibly adjusted using the nr_cpu_ids count of
+ possible CPUs for the booting hardware).
o The numbers separated by the "/" are the qsmask followed
by the qsmaskinit. The qsmask will have one bit
- set for each entity in the next lower level that
- has not yet checked in for the current grace period.
+ set for each entity in the next lower level that has
+ not yet checked in for the current grace period ("e"
+ indicating CPUs 5, 6, and 7 in the example above).
The qsmaskinit will have one bit for each entity that is
currently expected to check in during each grace period.
The value of qsmaskinit is assigned to that of qsmask
at the beginning of each grace period.
- For example, for "rcu_sched", the qsmask of the first
- entry of the lowest level is 0x14, meaning that we
- are still waiting for CPUs 2 and 4 to check in for the
- current grace period.
-
o The characters separated by the ">" indicate the state
of the blocked-tasks lists. A "G" preceding the ">"
indicates that at least one task blocked in an RCU
@@ -312,48 +376,39 @@ o Each element of the form "1/1 0:127 ^0" represents one struct
A "." character appears if the corresponding condition
does not hold, so that "..>." indicates that no tasks
are blocked. In contrast, "GE>T" indicates maximal
- inconvenience from blocked tasks.
+ inconvenience from blocked tasks. CONFIG_TREE_RCU
+ builds of the kernel will always show "..>.".
o The numbers separated by the ":" are the range of CPUs
served by this struct rcu_node. This can be helpful
in working out how the hierarchy is wired together.
- For example, the first entry at the lowest level shows
- "0:5", indicating that it covers CPUs 0 through 5.
+ For example, the example rcu_node structure shown above
+ has "0:7", indicating that it covers CPUs 0 through 7.
o The number after the "^" indicates the bit in the
- next higher level rcu_node structure that this
- rcu_node structure corresponds to.
-
- For example, the first entry at the lowest level shows
- "^0", indicating that it corresponds to bit zero in
- the first entry at the middle level.
-
-
-The output of "cat rcu/rcu_pending" looks as follows:
-
-rcu_sched:
- 0 np=255892 qsp=53936 rpq=85 cbr=0 cng=14417 gpc=10033 gps=24320 nn=146741
- 1 np=261224 qsp=54638 rpq=33 cbr=0 cng=25723 gpc=16310 gps=2849 nn=155792
- 2 np=237496 qsp=49664 rpq=23 cbr=0 cng=2762 gpc=45478 gps=1762 nn=136629
- 3 np=236249 qsp=48766 rpq=98 cbr=0 cng=286 gpc=48049 gps=1218 nn=137723
- 4 np=221310 qsp=46850 rpq=7 cbr=0 cng=26 gpc=43161 gps=4634 nn=123110
- 5 np=237332 qsp=48449 rpq=9 cbr=0 cng=54 gpc=47920 gps=3252 nn=137456
- 6 np=219995 qsp=46718 rpq=12 cbr=0 cng=50 gpc=42098 gps=6093 nn=120834
- 7 np=249893 qsp=49390 rpq=42 cbr=0 cng=72 gpc=38400 gps=17102 nn=144888
-rcu_bh:
- 0 np=146741 qsp=1419 rpq=6 cbr=0 cng=6 gpc=0 gps=0 nn=145314
- 1 np=155792 qsp=12597 rpq=3 cbr=0 cng=0 gpc=4 gps=8 nn=143180
- 2 np=136629 qsp=18680 rpq=1 cbr=0 cng=0 gpc=7 gps=6 nn=117936
- 3 np=137723 qsp=2843 rpq=0 cbr=0 cng=0 gpc=10 gps=7 nn=134863
- 4 np=123110 qsp=12433 rpq=0 cbr=0 cng=0 gpc=4 gps=2 nn=110671
- 5 np=137456 qsp=4210 rpq=1 cbr=0 cng=0 gpc=6 gps=5 nn=133235
- 6 np=120834 qsp=9902 rpq=2 cbr=0 cng=0 gpc=6 gps=3 nn=110921
- 7 np=144888 qsp=26336 rpq=0 cbr=0 cng=0 gpc=8 gps=2 nn=118542
-
-As always, this is once again split into "rcu_sched" and "rcu_bh"
-portions, with CONFIG_TREE_PREEMPT_RCU kernels having an additional
-"rcu_preempt" section. The fields are as follows:
+ next higher level rcu_node structure that this rcu_node
+ structure corresponds to. For example, the "d/d ..>. 4:7
+ ^1" has a "1" in this position, indicating that it
+ corresponds to the "1" bit in the "3" shown in the
+ "3/3 ..>. 0:7 ^0" entry on the next level up.
+
+
+The output of "cat rcu/rcu_sched/rcu_pending" looks as follows:
+
+ 0!np=26111 qsp=29 rpq=5386 cbr=1 cng=570 gpc=3674 gps=577 nn=15903
+ 1!np=28913 qsp=35 rpq=6097 cbr=1 cng=448 gpc=3700 gps=554 nn=18113
+ 2!np=32740 qsp=37 rpq=6202 cbr=0 cng=476 gpc=4627 gps=546 nn=20889
+ 3 np=23679 qsp=22 rpq=5044 cbr=1 cng=415 gpc=3403 gps=347 nn=14469
+ 4!np=30714 qsp=4 rpq=5574 cbr=0 cng=528 gpc=3931 gps=639 nn=20042
+ 5 np=28910 qsp=2 rpq=5246 cbr=0 cng=428 gpc=4105 gps=709 nn=18422
+ 6!np=38648 qsp=5 rpq=7076 cbr=0 cng=840 gpc=4072 gps=961 nn=25699
+ 7 np=37275 qsp=2 rpq=6873 cbr=0 cng=868 gpc=3416 gps=971 nn=25147
+
+The fields are as follows:
+
+o The leading number is the CPU number, with "!" indicating
+ an offline CPU.
o "np" is the number of times that __rcu_pending() has been invoked
for the corresponding flavor of RCU.
@@ -377,38 +432,23 @@ o "gpc" is the number of times that an old grace period had
o "gps" is the number of times that a new grace period had started,
but this CPU was not yet aware of it.
-o "nn" is the number of times that this CPU needed nothing. Alert
- readers will note that the rcu "nn" number for a given CPU very
- closely matches the rcu_bh "np" number for that same CPU. This
- is due to short-circuit evaluation in rcu_pending().
-
-
-The output of "cat rcu/rcutorture" looks as follows:
-
-rcutorture test sequence: 0 (test in progress)
-rcutorture update version number: 615
-
-The first line shows the number of rcutorture tests that have completed
-since boot. If a test is currently running, the "(test in progress)"
-string will appear as shown above. The second line shows the number of
-update cycles that the current test has started, or zero if there is
-no test in progress.
+o "nn" is the number of times that this CPU needed nothing.
The output of "cat rcu/rcuboost" looks as follows:
-0:5 tasks=.... kt=W ntb=0 neb=0 nnb=0 j=2f95 bt=300f
- balk: nt=0 egt=989 bt=0 nb=0 ny=0 nos=16
-6:7 tasks=.... kt=W ntb=0 neb=0 nnb=0 j=2f95 bt=300f
- balk: nt=0 egt=225 bt=0 nb=0 ny=0 nos=6
+0:3 tasks=.... kt=W ntb=0 neb=0 nnb=0 j=c864 bt=c894
+ balk: nt=0 egt=4695 bt=0 nb=0 ny=56 nos=0
+4:7 tasks=.... kt=W ntb=0 neb=0 nnb=0 j=c864 bt=c894
+ balk: nt=0 egt=6541 bt=0 nb=0 ny=126 nos=0
This information is output only for rcu_preempt. Each two-line entry
corresponds to a leaf rcu_node strcuture. The fields are as follows:
o "n:m" is the CPU-number range for the corresponding two-line
entry. In the sample output above, the first entry covers
- CPUs zero through five and the second entry covers CPUs 6
- and 7.
+ CPUs zero through three and the second entry covers CPUs four
+ through seven.
o "tasks=TNEB" gives the state of the various segments of the
rnp->blocked_tasks list:
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt
index bf0f6de2aa0..0cc7820967f 100644
--- a/Documentation/RCU/whatisRCU.txt
+++ b/Documentation/RCU/whatisRCU.txt
@@ -499,6 +499,8 @@ The foo_reclaim() function might appear as follows:
{
struct foo *fp = container_of(rp, struct foo, rcu);
+ foo_cleanup(fp->a);
+
kfree(fp);
}
@@ -521,6 +523,12 @@ o Use call_rcu() -after- removing a data element from an
read-side critical sections that might be referencing that
data item.
+If the callback for call_rcu() is not doing anything more than calling
+kfree() on the structure, you can use kfree_rcu() instead of call_rcu()
+to avoid having to write your own callback:
+
+ kfree_rcu(old_fp, rcu);
+
Again, see checklist.txt for additional rules governing the use of RCU.
@@ -773,8 +781,8 @@ a single atomic update, converting to RCU will require special care.
Also, the presence of synchronize_rcu() means that the RCU version of
delete() can now block. If this is a problem, there is a callback-based
-mechanism that never blocks, namely call_rcu(), that can be used in
-place of synchronize_rcu().
+mechanism that never blocks, namely call_rcu() or kfree_rcu(), that can
+be used in place of synchronize_rcu().
7. FULL LIST OF RCU APIs
@@ -789,9 +797,7 @@ RCU list traversal:
list_for_each_entry_rcu
hlist_for_each_entry_rcu
hlist_nulls_for_each_entry_rcu
-
- list_for_each_continue_rcu (to be deprecated in favor of new
- list_for_each_entry_continue_rcu)
+ list_for_each_entry_continue_rcu
RCU pointer/list update:
@@ -813,6 +819,7 @@ RCU: Critical sections Grace period Barrier
rcu_read_unlock synchronize_rcu
rcu_dereference synchronize_rcu_expedited
call_rcu
+ kfree_rcu
bh: Critical sections Grace period Barrier
diff --git a/Documentation/acpi/enumeration.txt b/Documentation/acpi/enumeration.txt
new file mode 100644
index 00000000000..4f27785ca0c
--- /dev/null
+++ b/Documentation/acpi/enumeration.txt
@@ -0,0 +1,227 @@
+ACPI based device enumeration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ACPI 5 introduced a set of new resources (UartTSerialBus, I2cSerialBus,
+SpiSerialBus, GpioIo and GpioInt) which can be used in enumerating slave
+devices behind serial bus controllers.
+
+In addition we are starting to see peripherals integrated in the
+SoC/Chipset to appear only in ACPI namespace. These are typically devices
+that are accessed through memory-mapped registers.
+
+In order to support this and re-use the existing drivers as much as
+possible we decided to do following:
+
+ o Devices that have no bus connector resource are represented as
+ platform devices.
+
+ o Devices behind real busses where there is a connector resource
+ are represented as struct spi_device or struct i2c_device
+ (standard UARTs are not busses so there is no struct uart_device).
+
+As both ACPI and Device Tree represent a tree of devices (and their
+resources) this implementation follows the Device Tree way as much as
+possible.
+
+The ACPI implementation enumerates devices behind busses (platform, SPI and
+I2C), creates the physical devices and binds them to their ACPI handle in
+the ACPI namespace.
+
+This means that when ACPI_HANDLE(dev) returns non-NULL the device was
+enumerated from ACPI namespace. This handle can be used to extract other
+device-specific configuration. There is an example of this below.
+
+Platform bus support
+~~~~~~~~~~~~~~~~~~~~
+Since we are using platform devices to represent devices that are not
+connected to any physical bus we only need to implement a platform driver
+for the device and add supported ACPI IDs. If this same IP-block is used on
+some other non-ACPI platform, the driver might work out of the box or needs
+some minor changes.
+
+Adding ACPI support for an existing driver should be pretty
+straightforward. Here is the simplest example:
+
+ #ifdef CONFIG_ACPI
+ static struct acpi_device_id mydrv_acpi_match[] = {
+ /* ACPI IDs here */
+ { }
+ };
+ MODULE_DEVICE_TABLE(acpi, mydrv_acpi_match);
+ #endif
+
+ static struct platform_driver my_driver = {
+ ...
+ .driver = {
+ .acpi_match_table = ACPI_PTR(mydrv_acpi_match),
+ },
+ };
+
+If the driver needs to perform more complex initialization like getting and
+configuring GPIOs it can get its ACPI handle and extract this information
+from ACPI tables.
+
+Currently the kernel is not able to automatically determine from which ACPI
+device it should make the corresponding platform device so we need to add
+the ACPI device explicitly to acpi_platform_device_ids list defined in
+drivers/acpi/scan.c. This limitation is only for the platform devices, SPI
+and I2C devices are created automatically as described below.
+
+SPI serial bus support
+~~~~~~~~~~~~~~~~~~~~~~
+Slave devices behind SPI bus have SpiSerialBus resource attached to them.
+This is extracted automatically by the SPI core and the slave devices are
+enumerated once spi_register_master() is called by the bus driver.
+
+Here is what the ACPI namespace for a SPI slave might look like:
+
+ Device (EEP0)
+ {
+ Name (_ADR, 1)
+ Name (_CID, Package() {
+ "ATML0025",
+ "AT25",
+ })
+ ...
+ Method (_CRS, 0, NotSerialized)
+ {
+ SPISerialBus(1, PolarityLow, FourWireMode, 8,
+ ControllerInitiated, 1000000, ClockPolarityLow,
+ ClockPhaseFirst, "\\_SB.PCI0.SPI1",)
+ }
+ ...
+
+The SPI device drivers only need to add ACPI IDs in a similar way than with
+the platform device drivers. Below is an example where we add ACPI support
+to at25 SPI eeprom driver (this is meant for the above ACPI snippet):
+
+ #ifdef CONFIG_ACPI
+ static struct acpi_device_id at25_acpi_match[] = {
+ { "AT25", 0 },
+ { },
+ };
+ MODULE_DEVICE_TABLE(acpi, at25_acpi_match);
+ #endif
+
+ static struct spi_driver at25_driver = {
+ .driver = {
+ ...
+ .acpi_match_table = ACPI_PTR(at25_acpi_match),
+ },
+ };
+
+Note that this driver actually needs more information like page size of the
+eeprom etc. but at the time writing this there is no standard way of
+passing those. One idea is to return this in _DSM method like:
+
+ Device (EEP0)
+ {
+ ...
+ Method (_DSM, 4, NotSerialized)
+ {
+ Store (Package (6)
+ {
+ "byte-len", 1024,
+ "addr-mode", 2,
+ "page-size, 32
+ }, Local0)
+
+ // Check UUIDs etc.
+
+ Return (Local0)
+ }
+
+Then the at25 SPI driver can get this configation by calling _DSM on its
+ACPI handle like:
+
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_object_list input;
+ acpi_status status;
+
+ /* Fill in the input buffer */
+
+ status = acpi_evaluate_object(ACPI_HANDLE(&spi->dev), "_DSM",
+ &input, &output);
+ if (ACPI_FAILURE(status))
+ /* Handle the error */
+
+ /* Extract the data here */
+
+ kfree(output.pointer);
+
+I2C serial bus support
+~~~~~~~~~~~~~~~~~~~~~~
+The slaves behind I2C bus controller only need to add the ACPI IDs like
+with the platform and SPI drivers. However the I2C bus controller driver
+needs to call acpi_i2c_register_devices() after it has added the adapter.
+
+An I2C bus (controller) driver does:
+
+ ...
+ ret = i2c_add_numbered_adapter(adapter);
+ if (ret)
+ /* handle error */
+
+ of_i2c_register_devices(adapter);
+ /* Enumerate the slave devices behind this bus via ACPI */
+ acpi_i2c_register_devices(adapter);
+
+Below is an example of how to add ACPI support to the existing mpu3050
+input driver:
+
+ #ifdef CONFIG_ACPI
+ static struct acpi_device_id mpu3050_acpi_match[] = {
+ { "MPU3050", 0 },
+ { },
+ };
+ MODULE_DEVICE_TABLE(acpi, mpu3050_acpi_match);
+ #endif
+
+ static struct i2c_driver mpu3050_i2c_driver = {
+ .driver = {
+ .name = "mpu3050",
+ .owner = THIS_MODULE,
+ .pm = &mpu3050_pm,
+ .of_match_table = mpu3050_of_match,
+ .acpi_match_table ACPI_PTR(mpu3050_acpi_match),
+ },
+ .probe = mpu3050_probe,
+ .remove = __devexit_p(mpu3050_remove),
+ .id_table = mpu3050_ids,
+ };
+
+GPIO support
+~~~~~~~~~~~~
+ACPI 5 introduced two new resources to describe GPIO connections: GpioIo
+and GpioInt. These resources are used be used to pass GPIO numbers used by
+the device to the driver. For example:
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (SBUF, ResourceTemplate()
+ {
+ GpioIo (Exclusive, PullDefault, 0x0000, 0x0000,
+ IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
+ 0x00, ResourceConsumer,,)
+ {
+ // Pin List
+ 0x0055
+ }
+ ...
+
+ Return (SBUF)
+ }
+ }
+
+These GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0"
+specifies the path to the controller. In order to use these GPIOs in Linux
+we need to translate them to the Linux GPIO numbers.
+
+The driver can do this by including <linux/acpi_gpio.h> and then calling
+acpi_get_gpio(path, gpio). This will return the Linux GPIO number or
+negative errno if there was no translation found.
+
+Other GpioIo parameters must be converted first by the driver to be
+suitable to the gpiolib before passing them.
+
+In case of GpioInt resource an additional call to gpio_to_irq() must be
+done before calling request_irq().
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
index c07f7b4fb88..a25cb3fafeb 100644
--- a/Documentation/cgroups/memory.txt
+++ b/Documentation/cgroups/memory.txt
@@ -144,9 +144,9 @@ Figure 1 shows the important aspects of the controller
3. Each page has a pointer to the page_cgroup, which in turn knows the
cgroup it belongs to
-The accounting is done as follows: mem_cgroup_charge() is invoked to set up
-the necessary data structures and check if the cgroup that is being charged
-is over its limit. If it is, then reclaim is invoked on the cgroup.
+The accounting is done as follows: mem_cgroup_charge_common() is invoked to
+set up the necessary data structures and check if the cgroup that is being
+charged is over its limit. If it is, then reclaim is invoked on the cgroup.
More details can be found in the reclaim section of this document.
If everything goes well, a page meta-data-structure called page_cgroup is
updated. page_cgroup has its own LRU on cgroup.
@@ -466,6 +466,10 @@ Note:
5.3 swappiness
Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only.
+Please note that unlike the global swappiness, memcg knob set to 0
+really prevents from any swapping even if there is a swap storage
+available. This might lead to memcg OOM killer if there are no file
+pages to reclaim.
Following cgroups' swappiness can't be changed.
- root cgroup (uses /proc/sys/vm/swappiness).
diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt
index 66ef8f35613..9f401350f50 100644
--- a/Documentation/cpu-hotplug.txt
+++ b/Documentation/cpu-hotplug.txt
@@ -207,6 +207,30 @@ by making it not-removable.
In such cases you will also notice that the online file is missing under cpu0.
+Q: Is CPU0 removable on X86?
+A: Yes. If kernel is compiled with CONFIG_BOOTPARAM_HOTPLUG_CPU0=y, CPU0 is
+removable by default. Otherwise, CPU0 is also removable by kernel option
+cpu0_hotplug.
+
+But some features depend on CPU0. Two known dependencies are:
+
+1. Resume from hibernate/suspend depends on CPU0. Hibernate/suspend will fail if
+CPU0 is offline and you need to online CPU0 before hibernate/suspend can
+continue.
+2. PIC interrupts also depend on CPU0. CPU0 can't be removed if a PIC interrupt
+is detected.
+
+It's said poweroff/reboot may depend on CPU0 on some machines although I haven't
+seen any poweroff/reboot failure so far after CPU0 is offline on a few tested
+machines.
+
+Please let me know if you know or see any other dependencies of CPU0.
+
+If the dependencies are under your control, you can turn on CPU0 hotplug feature
+either by CONFIG_BOOTPARAM_HOTPLUG_CPU0 or by kernel parameter cpu0_hotplug.
+
+--Fenghua Yu <fenghua.yu@intel.com>
+
Q: How do i find out if a particular CPU is not removable?
A: Depending on the implementation, some architectures may show this by the
absence of the "online" file. This is done if it can be determined ahead of
diff --git a/Documentation/devices.txt b/Documentation/devices.txt
index b6251cca926..08f01e79c41 100644
--- a/Documentation/devices.txt
+++ b/Documentation/devices.txt
@@ -2561,9 +2561,6 @@ Your cooperation is appreciated.
192 = /dev/usb/yurex1 First USB Yurex device
...
209 = /dev/usb/yurex16 16th USB Yurex device
- 240 = /dev/usb/dabusb0 First daubusb device
- ...
- 243 = /dev/usb/dabusb3 Fourth dabusb device
180 block USB block devices
0 = /dev/uba First USB block device
diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt
index d187e9f7cf1..1196290082d 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.txt
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt
@@ -7,6 +7,12 @@ PIT Timer required properties:
- interrupts: Should contain interrupt for the PIT which is the IRQ line
shared across all System Controller members.
+System Timer (ST) required properties:
+- compatible: Should be "atmel,at91rm9200-st"
+- reg: Should contain registers location and length
+- interrupts: Should contain interrupt for the ST which is the IRQ line
+ shared across all System Controller members.
+
TC/TCLIB Timer required properties:
- compatible: Should be "atmel,<chip>-tcb".
<chip> can be "at91rm9200" or "at91sam9x5"
diff --git a/Documentation/devicetree/bindings/arm/davinci/nand.txt b/Documentation/devicetree/bindings/arm/davinci/nand.txt
index e37241f1fdd..49fc7ada929 100644
--- a/Documentation/devicetree/bindings/arm/davinci/nand.txt
+++ b/Documentation/devicetree/bindings/arm/davinci/nand.txt
@@ -23,29 +23,16 @@ Recommended properties :
- ti,davinci-nand-buswidth: buswidth 8 or 16
- ti,davinci-nand-use-bbt: use flash based bad block table support.
-Example (enbw_cmc board):
-aemif@60000000 {
- compatible = "ti,davinci-aemif";
- #address-cells = <2>;
- #size-cells = <1>;
- reg = <0x68000000 0x80000>;
- ranges = <2 0 0x60000000 0x02000000
- 3 0 0x62000000 0x02000000
- 4 0 0x64000000 0x02000000
- 5 0 0x66000000 0x02000000
- 6 0 0x68000000 0x02000000>;
- nand@3,0 {
- compatible = "ti,davinci-nand";
- reg = <3 0x0 0x807ff
- 6 0x0 0x8000>;
- #address-cells = <1>;
- #size-cells = <1>;
- ti,davinci-chipselect = <1>;
- ti,davinci-mask-ale = <0>;
- ti,davinci-mask-cle = <0>;
- ti,davinci-mask-chipsel = <0>;
- ti,davinci-ecc-mode = "hw";
- ti,davinci-ecc-bits = <4>;
- ti,davinci-nand-use-bbt;
- };
+Example(da850 EVM ):
+nand_cs3@62000000 {
+ compatible = "ti,davinci-nand";
+ reg = <0x62000000 0x807ff
+ 0x68000000 0x8000>;
+ ti,davinci-chipselect = <1>;
+ ti,davinci-mask-ale = <0>;
+ ti,davinci-mask-cle = <0>;
+ ti,davinci-mask-chipsel = <0>;
+ ti,davinci-ecc-mode = "hw";
+ ti,davinci-ecc-bits = <4>;
+ ti,davinci-nand-use-bbt;
};
diff --git a/Documentation/devicetree/bindings/arm/l2cc.txt b/Documentation/devicetree/bindings/arm/l2cc.txt
index 7ca52161e7a..7c3ee3aeb7b 100644
--- a/Documentation/devicetree/bindings/arm/l2cc.txt
+++ b/Documentation/devicetree/bindings/arm/l2cc.txt
@@ -37,7 +37,7 @@ L2: cache-controller {
reg = <0xfff12000 0x1000>;
arm,data-latency = <1 1 1>;
arm,tag-latency = <2 2 2>;
- arm,filter-latency = <0x80000000 0x8000000>;
+ arm,filter-ranges = <0x80000000 0x8000000>;
cache-unified;
cache-level = <2>;
interrupts = <45>;
diff --git a/Documentation/devicetree/bindings/clock/imx23-clock.txt b/Documentation/devicetree/bindings/clock/imx23-clock.txt
index a0b867ef8d9..baadbb11fe9 100644
--- a/Documentation/devicetree/bindings/clock/imx23-clock.txt
+++ b/Documentation/devicetree/bindings/clock/imx23-clock.txt
@@ -52,7 +52,7 @@ clocks and IDs.
lcdif 38
etm 39
usb 40
- usb_pwr 41
+ usb_phy 41
Examples:
diff --git a/Documentation/devicetree/bindings/clock/imx28-clock.txt b/Documentation/devicetree/bindings/clock/imx28-clock.txt
index aa2af2866fe..52a49a4a50b 100644
--- a/Documentation/devicetree/bindings/clock/imx28-clock.txt
+++ b/Documentation/devicetree/bindings/clock/imx28-clock.txt
@@ -73,8 +73,8 @@ clocks and IDs.
can1 59
usb0 60
usb1 61
- usb0_pwr 62
- usb1_pwr 63
+ usb0_phy 62
+ usb1_phy 63
enet_out 64
Examples:
diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-spear.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-spear.txt
new file mode 100644
index 00000000000..f3d44984d91
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-spear.txt
@@ -0,0 +1,42 @@
+SPEAr cpufreq driver
+-------------------
+
+SPEAr SoC cpufreq driver for CPU frequency scaling.
+It supports both uniprocessor (UP) and symmetric multiprocessor (SMP) systems
+which share clock across all CPUs.
+
+Required properties:
+- cpufreq_tbl: Table of frequencies CPU could be transitioned into, in the
+ increasing order.
+
+Optional properties:
+- clock-latency: Specify the possible maximum transition latency for clock, in
+ unit of nanoseconds.
+
+Both required and optional properties listed above must be defined under node
+/cpus/cpu@0.
+
+Examples:
+--------
+cpus {
+
+ <...>
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+
+ <...>
+
+ cpufreq_tbl = < 166000
+ 200000
+ 250000
+ 300000
+ 400000
+ 500000
+ 600000 >;
+ };
+
+ <...>
+
+};
diff --git a/Documentation/devicetree/bindings/gpio/gpio-stmpe.txt b/Documentation/devicetree/bindings/gpio/gpio-stmpe.txt
new file mode 100644
index 00000000000..a0e4cf88521
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-stmpe.txt
@@ -0,0 +1,18 @@
+STMPE gpio
+----------
+
+Required properties:
+ - compatible: "st,stmpe-gpio"
+
+Optional properties:
+ - st,norequest-mask: bitmask specifying which GPIOs should _not_ be requestable
+ due to different usage (e.g. touch, keypad)
+
+Node name must be stmpe_gpio and should be child node of stmpe node to which it
+belongs.
+
+Example:
+ stmpe_gpio {
+ compatible = "st,stmpe-gpio";
+ st,norequest-mask = <0x20>; //gpio 5 can't be used
+ };
diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt
index 4e16ba4feab..a33628759d3 100644
--- a/Documentation/devicetree/bindings/gpio/gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio.txt
@@ -75,4 +75,40 @@ Example of two SOC GPIO banks defined as gpio-controller nodes:
gpio-controller;
};
+2.1) gpio-controller and pinctrl subsystem
+------------------------------------------
+gpio-controller on a SOC might be tightly coupled with the pinctrl
+subsystem, in the sense that the pins can be used by other functions
+together with optional gpio feature.
+
+While the pin allocation is totally managed by the pin ctrl subsystem,
+gpio (under gpiolib) is still maintained by gpio drivers. It may happen
+that different pin ranges in a SoC is managed by different gpio drivers.
+
+This makes it logical to let gpio drivers announce their pin ranges to
+the pin ctrl subsystem and call 'pinctrl_request_gpio' in order to
+request the corresponding pin before any gpio usage.
+
+For this, the gpio controller can use a pinctrl phandle and pins to
+announce the pinrange to the pin ctrl subsystem. For example,
+
+ qe_pio_e: gpio-controller@1460 {
+ #gpio-cells = <2>;
+ compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank";
+ reg = <0x1460 0x18>;
+ gpio-controller;
+ gpio-ranges = <&pinctrl1 20 10>, <&pinctrl2 50 20>;
+
+ }
+
+where,
+ &pinctrl1 and &pinctrl2 is the phandle to the pinctrl DT node.
+
+ Next values specify the base pin and number of pins for the range
+ handled by 'qe_pio_e' gpio. In the given example from base pin 20 to
+ pin 29 under pinctrl1 and pin 50 to pin 69 under pinctrl2 is handled
+ by this gpio controller.
+
+The pinctrl node must have "#gpio-range-cells" property to show number of
+arguments to pass with phandle from gpio controllers node.
diff --git a/Documentation/devicetree/bindings/gpio/gpio_atmel.txt b/Documentation/devicetree/bindings/gpio/gpio_atmel.txt
index 66efc804806..85f8c0d084f 100644
--- a/Documentation/devicetree/bindings/gpio/gpio_atmel.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio_atmel.txt
@@ -9,6 +9,10 @@ Required properties:
unused).
- gpio-controller: Marks the device node as a GPIO controller.
+optional properties:
+- #gpio-lines: Number of gpio if absent 32.
+
+
Example:
pioA: gpio@fffff200 {
compatible = "atmel,at91rm9200-gpio";
@@ -16,5 +20,6 @@ Example:
interrupts = <2 4>;
#gpio-cells = <2>;
gpio-controller;
+ #gpio-lines = <19>;
};
diff --git a/Documentation/devicetree/bindings/gpio/spear_spics.txt b/Documentation/devicetree/bindings/gpio/spear_spics.txt
new file mode 100644
index 00000000000..96c37eb1507
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/spear_spics.txt
@@ -0,0 +1,50 @@
+=== ST Microelectronics SPEAr SPI CS Driver ===
+
+SPEAr platform provides a provision to control chipselects of ARM PL022 Prime
+Cell spi controller through its system registers, which otherwise remains under
+PL022 control. If chipselect remain under PL022 control then they would be
+released as soon as transfer is over and TxFIFO becomes empty. This is not
+desired by some of the device protocols above spi which expect (multiple)
+transfers without releasing their chipselects.
+
+Chipselects can be controlled by software by turning them as GPIOs. SPEAr
+provides another interface through system registers through which software can
+directly control each PL022 chipselect. Hence, it is natural for SPEAr to export
+the control of this interface as gpio.
+
+Required properties:
+
+ * compatible: should be defined as "st,spear-spics-gpio"
+ * reg: mentioning address range of spics controller
+ * st-spics,peripcfg-reg: peripheral configuration register offset
+ * st-spics,sw-enable-bit: bit offset to enable sw control
+ * st-spics,cs-value-bit: bit offset to drive chipselect low or high
+ * st-spics,cs-enable-mask: chip select number bit mask
+ * st-spics,cs-enable-shift: chip select number program offset
+ * gpio-controller: Marks the device node as gpio controller
+ * #gpio-cells: should be 1 and will mention chip select number
+
+All the above bit offsets are within peripcfg register.
+
+Example:
+-------
+spics: spics@e0700000{
+ compatible = "st,spear-spics-gpio";
+ reg = <0xe0700000 0x1000>;
+ st-spics,peripcfg-reg = <0x3b0>;
+ st-spics,sw-enable-bit = <12>;
+ st-spics,cs-value-bit = <11>;
+ st-spics,cs-enable-mask = <3>;
+ st-spics,cs-enable-shift = <8>;
+ gpio-controller;
+ #gpio-cells = <2>;
+};
+
+
+spi0: spi@e0100000 {
+ status = "okay";
+ num-cs = <3>;
+ cs-gpios = <&gpio1 7 0>, <&spics 0>,
+ <&spics 1>;
+ ...
+}
diff --git a/Documentation/devicetree/bindings/i2c/atmel-i2c.txt b/Documentation/devicetree/bindings/i2c/i2c-at91.txt
index b689a0d9441..b689a0d9441 100644
--- a/Documentation/devicetree/bindings/i2c/atmel-i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-at91.txt
diff --git a/Documentation/devicetree/bindings/i2c/davinci.txt b/Documentation/devicetree/bindings/i2c/i2c-davinci.txt
index 2dc935b4113..2dc935b4113 100644
--- a/Documentation/devicetree/bindings/i2c/davinci.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-davinci.txt
diff --git a/Documentation/devicetree/bindings/i2c/gpio-i2c.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
index 4f8ec947c6b..4f8ec947c6b 100644
--- a/Documentation/devicetree/bindings/i2c/gpio-i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
diff --git a/Documentation/devicetree/bindings/i2c/fsl-imx-i2c.txt b/Documentation/devicetree/bindings/i2c/i2c-imx.txt
index f3cf43b66f7..f3cf43b66f7 100644
--- a/Documentation/devicetree/bindings/i2c/fsl-imx-i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-imx.txt
diff --git a/Documentation/devicetree/bindings/i2c/fsl-i2c.txt b/Documentation/devicetree/bindings/i2c/i2c-mpc.txt
index 1eacd6b20ed..1eacd6b20ed 100644
--- a/Documentation/devicetree/bindings/i2c/fsl-i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mpc.txt
diff --git a/Documentation/devicetree/bindings/i2c/mux.txt b/Documentation/devicetree/bindings/i2c/i2c-mux.txt
index af84cce5cd7..af84cce5cd7 100644
--- a/Documentation/devicetree/bindings/i2c/mux.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mux.txt
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt b/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
new file mode 100644
index 00000000000..f46d928aa73
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
@@ -0,0 +1,18 @@
+
+* Marvell MV64XXX I2C controller
+
+Required properties :
+
+ - reg : Offset and length of the register set for the device
+ - compatible : Should be "marvell,mv64xxx-i2c"
+ - interrupts : The interrupt number
+ - clock-frequency : Desired I2C bus clock frequency in Hz.
+
+Examples:
+
+ i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x20>;
+ interrupts = <29>;
+ clock-frequency = <100000>;
+ };
diff --git a/Documentation/devicetree/bindings/i2c/nomadik.txt b/Documentation/devicetree/bindings/i2c/i2c-nomadik.txt
index 72065b0ff68..72065b0ff68 100644
--- a/Documentation/devicetree/bindings/i2c/nomadik.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-nomadik.txt
diff --git a/Documentation/devicetree/bindings/i2c/cavium-i2c.txt b/Documentation/devicetree/bindings/i2c/i2c-octeon.txt
index dced82ebe31..dced82ebe31 100644
--- a/Documentation/devicetree/bindings/i2c/cavium-i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-octeon.txt
diff --git a/Documentation/devicetree/bindings/i2c/omap-i2c.txt b/Documentation/devicetree/bindings/i2c/i2c-omap.txt
index 56564aa4b44..56564aa4b44 100644
--- a/Documentation/devicetree/bindings/i2c/omap-i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-omap.txt
diff --git a/Documentation/devicetree/bindings/i2c/pnx.txt b/Documentation/devicetree/bindings/i2c/i2c-pnx.txt
index fe98ada33ee..fe98ada33ee 100644
--- a/Documentation/devicetree/bindings/i2c/pnx.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-pnx.txt
diff --git a/Documentation/devicetree/bindings/i2c/ce4100-i2c.txt b/Documentation/devicetree/bindings/i2c/i2c-pxa-pci-ce4100.txt
index 569b1624851..569b1624851 100644
--- a/Documentation/devicetree/bindings/i2c/ce4100-i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-pxa-pci-ce4100.txt
diff --git a/Documentation/devicetree/bindings/i2c/mrvl-i2c.txt b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
index 0f7945019f6..12b78ac507e 100644
--- a/Documentation/devicetree/bindings/i2c/mrvl-i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
@@ -31,21 +31,3 @@ Examples:
reg = <0xd4025000 0x1000>;
interrupts = <58>;
};
-
-* Marvell MV64XXX I2C controller
-
-Required properties :
-
- - reg : Offset and length of the register set for the device
- - compatible : Should be "marvell,mv64xxx-i2c"
- - interrupts : The interrupt number
- - clock-frequency : Desired I2C bus clock frequency in Hz.
-
-Examples:
-
- i2c@11000 {
- compatible = "marvell,mv64xxx-i2c";
- reg = <0x11000 0x20>;
- interrupts = <29>;
- clock-frequency = <100000>;
- };
diff --git a/Documentation/devicetree/bindings/i2c/samsung-i2c.txt b/Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt
index b6cb5a12c67..b6cb5a12c67 100644
--- a/Documentation/devicetree/bindings/i2c/samsung-i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt
diff --git a/Documentation/devicetree/bindings/i2c/sirf-i2c.txt b/Documentation/devicetree/bindings/i2c/i2c-sirf.txt
index 7baf9e133fa..7baf9e133fa 100644
--- a/Documentation/devicetree/bindings/i2c/sirf-i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-sirf.txt
diff --git a/Documentation/devicetree/bindings/i2c/arm-versatile.txt b/Documentation/devicetree/bindings/i2c/i2c-versatile.txt
index 361d31c51b6..361d31c51b6 100644
--- a/Documentation/devicetree/bindings/i2c/arm-versatile.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-versatile.txt
diff --git a/Documentation/devicetree/bindings/i2c/xiic.txt b/Documentation/devicetree/bindings/i2c/i2c-xiic.txt
index ceabbe91ae4..ceabbe91ae4 100644
--- a/Documentation/devicetree/bindings/i2c/xiic.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-xiic.txt
diff --git a/Documentation/devicetree/bindings/leds/common.txt b/Documentation/devicetree/bindings/leds/common.txt
new file mode 100644
index 00000000000..2d88816dd55
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/common.txt
@@ -0,0 +1,23 @@
+Common leds properties.
+
+Optional properties for child nodes:
+- label : The label for this LED. If omitted, the label is
+ taken from the node name (excluding the unit address).
+
+- linux,default-trigger : This parameter, if present, is a
+ string defining the trigger assigned to the LED. Current triggers are:
+ "backlight" - LED will act as a back-light, controlled by the framebuffer
+ system
+ "default-on" - LED will turn on (but for leds-gpio see "default-state"
+ property in Documentation/devicetree/bindings/gpio/led.txt)
+ "heartbeat" - LED "double" flashes at a load average based rate
+ "ide-disk" - LED indicates disk activity
+ "timer" - LED flashes at a fixed, configurable rate
+
+Examples:
+
+system-status {
+ label = "Status";
+ linux,default-trigger = "heartbeat";
+ ...
+};
diff --git a/Documentation/devicetree/bindings/gpio/led.txt b/Documentation/devicetree/bindings/leds/leds-gpio.txt
index edc83c1c0d5..df1b3080f6b 100644
--- a/Documentation/devicetree/bindings/gpio/led.txt
+++ b/Documentation/devicetree/bindings/leds/leds-gpio.txt
@@ -10,16 +10,10 @@ LED sub-node properties:
- gpios : Should specify the LED's GPIO, see "gpios property" in
Documentation/devicetree/bindings/gpio/gpio.txt. Active low LEDs should be
indicated using flags in the GPIO specifier.
-- label : (optional) The label for this LED. If omitted, the label is
- taken from the node name (excluding the unit address).
-- linux,default-trigger : (optional) This parameter, if present, is a
- string defining the trigger assigned to the LED. Current triggers are:
- "backlight" - LED will act as a back-light, controlled by the framebuffer
- system
- "default-on" - LED will turn on, but see "default-state" below
- "heartbeat" - LED "double" flashes at a load average based rate
- "ide-disk" - LED indicates disk activity
- "timer" - LED flashes at a fixed, configurable rate
+- label : (optional)
+ see Documentation/devicetree/bindings/leds/common.txt
+- linux,default-trigger : (optional)
+ see Documentation/devicetree/bindings/leds/common.txt
- default-state: (optional) The initial state of the LED. Valid
values are "on", "off", and "keep". If the LED is already on or off
and the default-state property is set the to same value, then no
diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
index 8e2e0ba2f48..a591c6741d7 100644
--- a/Documentation/devicetree/bindings/mmc/mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc.txt
@@ -21,6 +21,12 @@ Optional properties:
- cd-inverted: when present, polarity on the cd gpio line is inverted
- wp-inverted: when present, polarity on the wp gpio line is inverted
- max-frequency: maximum operating clock frequency
+- no-1-8-v: when present, denotes that 1.8v card voltage is not supported on
+ this system, even if the controller claims it is.
+
+Optional SDIO properties:
+- keep-power-in-suspend: Preserves card power during a suspend/resume cycle
+- enable-sdio-wakeup: Enables wake up of host system on SDIO IRQ assertion
Example:
@@ -33,4 +39,6 @@ sdhci@ab000000 {
cd-inverted;
wp-gpios = <&gpio 70 0>;
max-frequency = <50000000>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
}
diff --git a/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt b/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt
index 630a7d7f471..97e9e315400 100644
--- a/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt
+++ b/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt
@@ -12,10 +12,6 @@ is used. The Samsung's SDHCI controller bindings extends this as listed below.
[A] The property "samsung,cd-pinmux-gpio" can be used as stated in the
"Optional Board Specific Properties" section below.
-[B] If core card-detect bindings and "samsung,cd-pinmux-gpio" property
- is not specified, it is assumed that there is no card detection
- mechanism used.
-
Required SoC Specific Properties:
- compatible: should be one of the following
- "samsung,s3c6410-sdhci": For controllers compatible with s3c6410 sdhci
@@ -24,14 +20,18 @@ Required SoC Specific Properties:
controller.
Required Board Specific Properties:
-- gpios: Should specify the gpios used for clock, command and data lines. The
- gpio specifier format depends on the gpio controller.
+- Samsung GPIO variant (will be completely replaced by pinctrl):
+ - gpios: Should specify the gpios used for clock, command and data lines. The
+ gpio specifier format depends on the gpio controller.
+- Pinctrl variant (preferred if available):
+ - pinctrl-0: Should specify pin control groups used for this controller.
+ - pinctrl-names: Should contain only one value - "default".
Optional Board Specific Properties:
- samsung,cd-pinmux-gpio: Specifies the card detect line that is routed
through a pinmux to the card-detect pin of the card slot. This property
should be used only if none of the mmc core card-detect properties are
- used.
+ used. Only for Samsung GPIO variant.
Example:
sdhci@12530000 {
@@ -40,12 +40,18 @@ Example:
interrupts = <0 75 0>;
bus-width = <4>;
cd-gpios = <&gpk2 2 2 3 3>;
+
+ /* Samsung GPIO variant */
gpios = <&gpk2 0 2 0 3>, /* clock line */
<&gpk2 1 2 0 3>, /* command line */
<&gpk2 3 2 3 3>, /* data line 0 */
<&gpk2 4 2 3 3>, /* data line 1 */
<&gpk2 5 2 3 3>, /* data line 2 */
<&gpk2 6 2 3 3>; /* data line 3 */
+
+ /* Pinctrl variant */
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4>;
+ pinctrl-names = "default";
};
Note: This example shows both SoC specific and board specific properties
diff --git a/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
index 06cd32d0805..06cd32d0805 100644
--- a/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
index be76a23b34c..ed271fc255b 100644
--- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
+++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
@@ -19,6 +19,7 @@ ti,dual-volt: boolean, supports dual voltage cards
"supply-name" examples are "vmmc", "vmmc_aux" etc
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
Example:
mmc1: mmc@0x4809c000 {
diff --git a/Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt b/Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt
new file mode 100644
index 00000000000..d7fb6abb3eb
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt
@@ -0,0 +1,23 @@
+* Wondermedia WM8505/WM8650 SD/MMC Host Controller
+
+This file documents differences between the core properties described
+by mmc.txt and the properties used by the wmt-sdmmc driver.
+
+Required properties:
+- compatible: Should be "wm,wm8505-sdhc".
+- interrupts: Two interrupts are required - regular irq and dma irq.
+
+Optional properties:
+- sdon-inverted: SD_ON bit is inverted on the controller
+
+Examples:
+
+sdhc@d800a000 {
+ compatible = "wm,wm8505-sdhc";
+ reg = <0xd800a000 0x1000>;
+ interrupts = <20 21>;
+ clocks = <&sdhc>;
+ bus-width = <4>;
+ sdon-inverted;
+};
+
diff --git a/Documentation/devicetree/bindings/net/mdio-gpio.txt b/Documentation/devicetree/bindings/net/mdio-gpio.txt
index bc954952901..c79bab02536 100644
--- a/Documentation/devicetree/bindings/net/mdio-gpio.txt
+++ b/Documentation/devicetree/bindings/net/mdio-gpio.txt
@@ -8,9 +8,16 @@ gpios property as described in section VIII.1 in the following order:
MDC, MDIO.
+Note: Each gpio-mdio bus should have an alias correctly numbered in "aliases"
+node.
+
Example:
-mdio {
+aliases {
+ mdio-gpio0 = <&mdio0>;
+};
+
+mdio0: mdio {
compatible = "virtual,mdio-gpio";
#address-cells = <1>;
#size-cells = <0>;
diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
new file mode 100644
index 00000000000..3a268127b05
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
@@ -0,0 +1,141 @@
+* Atmel AT91 Pinmux Controller
+
+The AT91 Pinmux Controler, enables the IC
+to share one PAD to several functional blocks. The sharing is done by
+multiplexing the PAD input/output signals. For each PAD there are up to
+8 muxing options (called periph modes). Since different modules require
+different PAD settings (like pull up, keeper, etc) the contoller controls
+also the PAD settings parameters.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+Atmel AT91 pin configuration node is a node of a group of pins which can be
+used for a specific device or function. This node represents both mux and config
+of the pins in that group. The 'pins' selects the function mode(also named pin
+mode) this pin can work on and the 'config' configures various pad settings
+such as pull-up, multi drive, etc.
+
+Required properties for iomux controller:
+- compatible: "atmel,at91rm9200-pinctrl"
+- atmel,mux-mask: array of mask (periph per bank) to describe if a pin can be
+ configured in this periph mode. All the periph and bank need to be describe.
+
+How to create such array:
+
+Each column will represent the possible peripheral of the pinctrl
+Each line will represent a pio bank
+
+Take an example on the 9260
+Peripheral: 2 ( A and B)
+Bank: 3 (A, B and C)
+=>
+
+ /* A B */
+ 0xffffffff 0xffc00c3b /* pioA */
+ 0xffffffff 0x7fff3ccf /* pioB */
+ 0xffffffff 0x007fffff /* pioC */
+
+For each peripheral/bank we will descibe in a u32 if a pin can can be
+configured in it by putting 1 to the pin bit (1 << pin)
+
+Let's take the pioA on peripheral B
+From the datasheet Table 10-2.
+Peripheral B
+PA0 MCDB0
+PA1 MCCDB
+PA2
+PA3 MCDB3
+PA4 MCDB2
+PA5 MCDB1
+PA6
+PA7
+PA8
+PA9
+PA10 ETX2
+PA11 ETX3
+PA12
+PA13
+PA14
+PA15
+PA16
+PA17
+PA18
+PA19
+PA20
+PA21
+PA22 ETXER
+PA23 ETX2
+PA24 ETX3
+PA25 ERX2
+PA26 ERX3
+PA27 ERXCK
+PA28 ECRS
+PA29 ECOL
+PA30 RXD4
+PA31 TXD4
+
+=> 0xffc00c3b
+
+Required properties for pin configuration node:
+- atmel,pins: 4 integers array, represents a group of pins mux and config
+ setting. The format is atmel,pins = <PIN_BANK PIN_BANK_NUM PERIPH CONFIG>.
+ The PERIPH 0 means gpio.
+
+Bits used for CONFIG:
+PULL_UP (1 << 0): indicate this pin need a pull up.
+MULTIDRIVE (1 << 1): indicate this pin need to be configured as multidrive.
+DEGLITCH (1 << 2): indicate this pin need deglitch.
+PULL_DOWN (1 << 3): indicate this pin need a pull down.
+DIS_SCHMIT (1 << 4): indicate this pin need to disable schmit trigger.
+DEBOUNCE (1 << 16): indicate this pin need debounce.
+DEBOUNCE_VAL (0x3fff << 17): debounce val.
+
+NOTE:
+Some requirements for using atmel,at91rm9200-pinctrl binding:
+1. We have pin function node defined under at91 controller node to represent
+ what pinmux functions this SoC supports.
+2. The driver can use the function node's name and pin configuration node's
+ name describe the pin function and group hierarchy.
+ For example, Linux at91 pinctrl driver takes the function node's name
+ as the function name and pin configuration node's name as group name to
+ create the map table.
+3. Each pin configuration node should have a phandle, devices can set pins
+ configurations by referring to the phandle of that pin configuration node.
+4. The gpio controller must be describe in the pinctrl simple-bus.
+
+Examples:
+
+pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ reg = <0xfffff400 0x600>;
+
+ atmel,mux-mask = <
+ /* A B */
+ 0xffffffff 0xffc00c3b /* pioA */
+ 0xffffffff 0x7fff3ccf /* pioB */
+ 0xffffffff 0x007fffff /* pioC */
+ >;
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <1 14 0x1 0x0 /* PB14 periph A */
+ 1 15 0x1 0x1>; /* PB15 periph with pullup */
+ };
+ };
+};
+
+dbgu: serial@fffff200 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffff200 0x200>;
+ interrupts = <1 4 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
+ status = "disabled";
+};
diff --git a/Documentation/devicetree/bindings/rtc/orion-rtc.txt b/Documentation/devicetree/bindings/rtc/orion-rtc.txt
new file mode 100644
index 00000000000..3bf63ffa516
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/orion-rtc.txt
@@ -0,0 +1,18 @@
+* Mvebu Real Time Clock
+
+RTC controller for the Kirkwood, the Dove, the Armada 370 and the
+Armada XP SoCs
+
+Required properties:
+- compatible : Should be "marvell,orion-rtc"
+- reg: physical base address of the controller and length of memory mapped
+ region.
+- interrupts: IRQ line for the RTC.
+
+Example:
+
+rtc@10300 {
+ compatible = "marvell,orion-rtc";
+ reg = <0xd0010300 0x20>;
+ interrupts = <50>;
+};
diff --git a/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt b/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt
index 2ee903fad25..273a8d5b330 100644
--- a/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt
+++ b/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt
@@ -6,11 +6,19 @@ Required properties:
- reg : Address and length of the register set for the device
- interrupts : Should contain the auart interrupt numbers
+Optional properties:
+- fsl,auart-dma-channel : The DMA channels, the first is for RX, the other
+ is for TX. If you add this property, it also means that you
+ will enable the DMA support for the auart.
+ Note: due to the hardware bug in imx23(see errata : 2836),
+ only the imx28 can enable the DMA support for the auart.
+
Example:
auart0: serial@8006a000 {
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x8006a000 0x2000>;
interrupts = <112 70 71>;
+ fsl,auart-dma-channel = <8 9>;
};
Note: Each auart port should have an alias correctly numbered in "aliases"
diff --git a/Documentation/devicetree/bindings/tty/serial/of-serial.txt b/Documentation/devicetree/bindings/tty/serial/of-serial.txt
index ba385f2e0dd..1e1145ca4f3 100644
--- a/Documentation/devicetree/bindings/tty/serial/of-serial.txt
+++ b/Documentation/devicetree/bindings/tty/serial/of-serial.txt
@@ -14,7 +14,10 @@ Required properties:
- "serial" if the port type is unknown.
- reg : offset and length of the register set for the device.
- interrupts : should contain uart interrupt.
-- clock-frequency : the input clock frequency for the UART.
+- clock-frequency : the input clock frequency for the UART
+ or
+ clocks phandle to refer to the clk used as per Documentation/devicetree
+ /bindings/clock/clock-bindings.txt
Optional properties:
- current-speed : the current active speed of the UART.
diff --git a/Documentation/devicetree/bindings/usb/am33xx-usb.txt b/Documentation/devicetree/bindings/usb/am33xx-usb.txt
index ca8fa56e9f0..a92250512a4 100644
--- a/Documentation/devicetree/bindings/usb/am33xx-usb.txt
+++ b/Documentation/devicetree/bindings/usb/am33xx-usb.txt
@@ -3,12 +3,12 @@ AM33XX MUSB GLUE
- ti,hwmods : must be "usb_otg_hs"
- 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
+ - num-eps : Specifies the number of endpoints. This is also a
MUSB configuration-specific setting. Should be set to "16"
- - ram_bits : Specifies the ram address size. Should be set to "12"
- - port0_mode : Should be "3" to represent OTG. "1" signifies HOST and "2"
+ - ram-bits : Specifies the ram address size. Should be set to "12"
+ - port0-mode : Should be "3" to represent OTG. "1" signifies HOST and "2"
represents PERIPHERAL.
- - port1_mode : Should be "1" to represent HOST. "3" signifies OTG and "2"
+ - port1-mode : Should be "1" to represent HOST. "3" signifies OTG and "2"
represents PERIPHERAL.
- power : Should be "250". This signifies the controller can supply upto
500mA when operating in host mode.
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 9de2b9ff9d6..770a0193ca1 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -5,6 +5,7 @@ using them to avoid name-space collisions.
ad Avionic Design GmbH
adi Analog Devices, Inc.
+ak Asahi Kasei Corp.
amcc Applied Micro Circuits Corporation (APM, formally AMCC)
apm Applied Micro Circuits Corporation (APM)
arm ARM Ltd.
@@ -25,6 +26,7 @@ gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
hp Hewlett Packard
ibm International Business Machines (IBM)
idt Integrated Device Technologies, Inc.
+img Imagination Technologies Ltd.
intercontrol Inter Control Group
linux Linux-specific binding
marvell Marvell Technology Group Ltd.
@@ -34,8 +36,9 @@ national National Semiconductor
nintendo Nintendo
nvidia NVIDIA
nxp NXP Semiconductors
+onnn ON Semiconductor Corp.
picochip Picochip Ltd
-powervr Imagination Technologies
+powervr PowerVR (deprecated, use img)
qcom Qualcomm, Inc.
ramtron Ramtron International
realtek Realtek Semiconductor Corp.
@@ -45,6 +48,7 @@ schindler Schindler
sil Silicon Image
simtek
sirf SiRF Technology, Inc.
+snps Synopsys, Inc.
st STMicroelectronics
stericsson ST-Ericsson
ti Texas Instruments
diff --git a/Documentation/devicetree/usage-model.txt b/Documentation/devicetree/usage-model.txt
index dca90fe22a9..ef9d06c9f8f 100644
--- a/Documentation/devicetree/usage-model.txt
+++ b/Documentation/devicetree/usage-model.txt
@@ -347,7 +347,7 @@ later), which will happily live at the base of the Linux /sys/devices
tree. Therefore, if a DT node is at the root of the tree, then it
really probably is best registered as a platform_device.
-Linux board support code calls of_platform_populate(NULL, NULL, NULL)
+Linux board support code calls of_platform_populate(NULL, NULL, NULL, NULL)
to kick off discovery of devices at the root of the tree. The
parameters are all NULL because when starting from the root of the
tree, there is no need to provide a starting node (the first NULL), a
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index a1793d670cd..3844d21d6ca 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -33,7 +33,7 @@ Table of Contents
2 Modifying System Parameters
3 Per-Process Parameters
- 3.1 /proc/<pid>/oom_score_adj - Adjust the oom-killer
+ 3.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj - Adjust the oom-killer
score
3.2 /proc/<pid>/oom_score - Display current oom-killer score
3.3 /proc/<pid>/io - Display the IO accounting fields
@@ -1320,10 +1320,10 @@ of the kernel.
CHAPTER 3: PER-PROCESS PARAMETERS
------------------------------------------------------------------------------
-3.1 /proc/<pid>/oom_score_adj- Adjust the oom-killer score
+3.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj- Adjust the oom-killer score
--------------------------------------------------------------------------------
-This file can be used to adjust the badness heuristic used to select which
+These file can be used to adjust the badness heuristic used to select which
process gets killed in out of memory conditions.
The badness heuristic assigns a value to each candidate task ranging from 0
@@ -1361,6 +1361,12 @@ same system, cpuset, mempolicy, or memory controller resources to use at least
equivalent to discounting 50% of the task's allowed memory from being considered
as scoring against the task.
+For backwards compatibility with previous kernels, /proc/<pid>/oom_adj may also
+be used to tune the badness score. Its acceptable values range from -16
+(OOM_ADJUST_MIN) to +15 (OOM_ADJUST_MAX) and a special value of -17
+(OOM_DISABLE) to disable oom killing entirely for that task. Its value is
+scaled linearly with /proc/<pid>/oom_score_adj.
+
The value of /proc/<pid>/oom_score_adj may be reduced no lower than the last
value set by a CAP_SYS_RESOURCE process. To reduce the value any lower
requires CAP_SYS_RESOURCE.
@@ -1375,7 +1381,9 @@ minimal amount of work.
-------------------------------------------------------------
This file can be used to check the current score used by the oom-killer is for
-any given <pid>.
+any given <pid>. Use it together with /proc/<pid>/oom_score_adj to tune which
+process should be killed in an out-of-memory situation.
+
3.3 /proc/<pid>/io - Display the IO accounting fields
-------------------------------------------------------
diff --git a/Documentation/firmware_class/README b/Documentation/firmware_class/README
index 815b711bcd8..43fada989e6 100644
--- a/Documentation/firmware_class/README
+++ b/Documentation/firmware_class/README
@@ -22,12 +22,17 @@
- calls request_firmware(&fw_entry, $FIRMWARE, device)
- kernel searchs the fimware image with name $FIRMWARE directly
in the below search path of root filesystem:
+ User customized search path by module parameter 'path'[1]
"/lib/firmware/updates/" UTS_RELEASE,
"/lib/firmware/updates",
"/lib/firmware/" UTS_RELEASE,
"/lib/firmware"
- If found, goto 7), else goto 2)
+ [1], the 'path' is a string parameter which length should be less
+ than 256, user should pass 'firmware_class.path=$CUSTOMIZED_PATH'
+ if firmware_class is built in kernel(the general situation)
+
2), userspace:
- /sys/class/firmware/xxx/{loading,data} appear.
- hotplug gets called with a firmware identifier in $FIRMWARE
@@ -114,3 +119,10 @@
on the setup, so I think that the choice on what firmware to make
persistent should be left to userspace.
+ about firmware cache:
+ --------------------
+ After firmware cache mechanism is introduced during system sleep,
+ request_firmware can be called safely inside device's suspend and
+ resume callback, and callers need't cache the firmware by
+ themselves any more for dealing with firmware loss during system
+ resume.
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt
index e08a883de36..77a1d11af72 100644
--- a/Documentation/gpio.txt
+++ b/Documentation/gpio.txt
@@ -439,6 +439,48 @@ slower clock delays the rising edge of SCK, and the I2C master adjusts its
signaling rate accordingly.
+GPIO controllers and the pinctrl subsystem
+------------------------------------------
+
+A GPIO controller on a SOC might be tightly coupled with the pinctrl
+subsystem, in the sense that the pins can be used by other functions
+together with an optional gpio feature. We have already covered the
+case where e.g. a GPIO controller need to reserve a pin or set the
+direction of a pin by calling any of:
+
+pinctrl_request_gpio()
+pinctrl_free_gpio()
+pinctrl_gpio_direction_input()
+pinctrl_gpio_direction_output()
+
+But how does the pin control subsystem cross-correlate the GPIO
+numbers (which are a global business) to a certain pin on a certain
+pin controller?
+
+This is done by registering "ranges" of pins, which are essentially
+cross-reference tables. These are described in
+Documentation/pinctrl.txt
+
+While the pin allocation is totally managed by the pinctrl subsystem,
+gpio (under gpiolib) is still maintained by gpio drivers. It may happen
+that different pin ranges in a SoC is managed by different gpio drivers.
+
+This makes it logical to let gpio drivers announce their pin ranges to
+the pin ctrl subsystem before it will call 'pinctrl_request_gpio' in order
+to request the corresponding pin to be prepared by the pinctrl subsystem
+before any gpio usage.
+
+For this, the gpio controller can register its pin range with pinctrl
+subsystem. There are two ways of doing it currently: with or without DT.
+
+For with DT support refer to Documentation/devicetree/bindings/gpio/gpio.txt.
+
+For non-DT support, user can call gpiochip_add_pin_range() with appropriate
+parameters to register a range of gpio pins with a pinctrl driver. For this
+exact name string of pinctrl device has to be passed as one of the
+argument to this routine.
+
+
What do these conventions omit?
===============================
One of the biggest things these conventions omit is pin multiplexing, since
diff --git a/Documentation/hwmon/ads7828 b/Documentation/hwmon/ads7828
index 2bbebe6f771..f6e263e0f60 100644
--- a/Documentation/hwmon/ads7828
+++ b/Documentation/hwmon/ads7828
@@ -4,29 +4,47 @@ Kernel driver ads7828
Supported chips:
* Texas Instruments/Burr-Brown ADS7828
Prefix: 'ads7828'
- Addresses scanned: I2C 0x48, 0x49, 0x4a, 0x4b
- Datasheet: Publicly available at the Texas Instruments website :
+ Datasheet: Publicly available at the Texas Instruments website:
http://focus.ti.com/lit/ds/symlink/ads7828.pdf
+ * Texas Instruments ADS7830
+ Prefix: 'ads7830'
+ Datasheet: Publicly available at the Texas Instruments website:
+ http://focus.ti.com/lit/ds/symlink/ads7830.pdf
+
Authors:
Steve Hardy <shardy@redhat.com>
+ Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+ Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
+
+Platform data
+-------------
+
+The ads7828 driver accepts an optional ads7828_platform_data structure (defined
+in include/linux/platform_data/ads7828.h). The structure fields are:
-Module Parameters
------------------
+* diff_input: (bool) Differential operation
+ set to true for differential mode, false for default single ended mode.
-* se_input: bool (default Y)
- Single ended operation - set to N for differential mode
-* int_vref: bool (default Y)
- Operate with the internal 2.5V reference - set to N for external reference
-* vref_mv: int (default 2500)
- If using an external reference, set this to the reference voltage in mV
+* ext_vref: (bool) External reference
+ set to true if it operates with an external reference, false for default
+ internal reference.
+
+* vref_mv: (unsigned int) Voltage reference
+ if using an external reference, set this to the reference voltage in mV,
+ otherwise it will default to the internal value (2500mV). This value will be
+ bounded with limits accepted by the chip, described in the datasheet.
+
+ If no structure is provided, the configuration defaults to single ended
+ operation and internal voltage reference (2.5V).
Description
-----------
-This driver implements support for the Texas Instruments ADS7828.
+This driver implements support for the Texas Instruments ADS7828 and ADS7830.
-This device is a 12-bit 8-channel A-D converter.
+The ADS7828 device is a 12-bit 8-channel A/D converter, while the ADS7830 does
+8-bit sampling.
It can operate in single ended mode (8 +ve inputs) or in differential mode,
where 4 differential pairs can be measured.
@@ -34,3 +52,7 @@ where 4 differential pairs can be measured.
The chip also has the facility to use an external voltage reference. This
may be required if your hardware supplies the ADS7828 from a 5V supply, see
the datasheet for more details.
+
+There is no reliable way to identify this chip, so the driver will not scan
+some addresses to try to auto-detect it. That means that you will have to
+statically declare the device in the platform support code.
diff --git a/Documentation/hwmon/coretemp b/Documentation/hwmon/coretemp
index f17256f069b..3374c085678 100644
--- a/Documentation/hwmon/coretemp
+++ b/Documentation/hwmon/coretemp
@@ -98,8 +98,10 @@ Process Processor TjMax(C)
45nm Atom Processors
D525/510/425/410 100
+ Z670/650 90
Z560/550/540/530P/530/520PT/520/515/510PT/510P 90
Z510/500 90
+ N570/550 100
N475/470/455/450 100
N280/270 90
330/230 125
diff --git a/Documentation/hwmon/da9055 b/Documentation/hwmon/da9055
new file mode 100644
index 00000000000..855c3f536e0
--- /dev/null
+++ b/Documentation/hwmon/da9055
@@ -0,0 +1,47 @@
+Supported chips:
+ * Dialog Semiconductors DA9055 PMIC
+ Prefix: 'da9055'
+ Datasheet: Datasheet is not publicly available.
+
+Authors: David Dajun Chen <dchen@diasemi.com>
+
+Description
+-----------
+
+The DA9055 provides an Analogue to Digital Converter (ADC) with 10 bits
+resolution and track and hold circuitry combined with an analogue input
+multiplexer. The analogue input multiplexer will allow conversion of up to 5
+different inputs. The track and hold circuit ensures stable input voltages at
+the input of the ADC during the conversion.
+
+The ADC is used to measure the following inputs:
+Channel 0: VDDOUT - measurement of the system voltage
+Channel 1: ADC_IN1 - high impedance input (0 - 2.5V)
+Channel 2: ADC_IN2 - high impedance input (0 - 2.5V)
+Channel 3: ADC_IN3 - high impedance input (0 - 2.5V)
+Channel 4: Internal Tjunc. - sense (internal temp. sensor)
+
+By using sysfs attributes we can measure the system voltage VDDOUT,
+chip junction temperature and auxiliary channels voltages.
+
+Voltage Monitoring
+------------------
+
+Voltages are sampled in a AUTO mode it can be manually sampled too and results
+are stored in a 10 bit ADC.
+
+The system voltage is calculated as:
+ Milli volt = ((ADC value * 1000) / 85) + 2500
+
+The voltages on ADC channels 1, 2 and 3 are calculated as:
+ Milli volt = (ADC value * 1000) / 102
+
+Temperature Monitoring
+----------------------
+
+Temperatures are sampled by a 10 bit ADC. Junction temperatures
+are monitored by the ADC channels.
+
+The junction temperature is calculated:
+ Degrees celsius = -0.4084 * (ADC_RES - T_OFFSET) + 307.6332
+The junction temperature attribute is supported by the driver.
diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
index ec9ae670869..14c3f4f1b61 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -1175,15 +1175,16 @@ When kbuild executes, the following steps are followed (roughly):
in an init section in the image. Platform code *must* copy the
blob to non-init memory prior to calling unflatten_device_tree().
- Example:
- #arch/x86/platform/ce4100/Makefile
- clean-files := *dtb.S
+ To use this command, simply add *.dtb into obj-y or targets, or make
+ some other target depend on %.dtb
- DTC_FLAGS := -p 1024
- obj-y += foo.dtb.o
+ A central rule exists to create $(obj)/%.dtb from $(src)/%.dts;
+ architecture Makefiles do no need to explicitly write out that rule.
- $(obj)/%.dtb: $(src)/%.dts
- $(call cmd,dtc)
+ Example:
+ targets += $(dtb-y)
+ clean-files += *.dtb
+ DTC_FLAGS ?= -p 1024
--- 6.8 Custom kbuild commands
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 9776f068306..28bd0f0e32c 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1304,6 +1304,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
lapic [X86-32,APIC] Enable the local APIC even if BIOS
disabled it.
+ lapic= [x86,APIC] "notscdeadline" Do not use TSC deadline
+ value for LAPIC timer one-shot implementation. Default
+ back to the programmable timer unit in the LAPIC.
+
lapic_timer_c2_ok [X86,APIC] trust the local apic timer
in C2 power state.
@@ -1984,6 +1988,20 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
nox2apic [X86-64,APIC] Do not enable x2APIC mode.
+ cpu0_hotplug [X86] Turn on CPU0 hotplug feature when
+ CONFIG_BOOTPARAM_HOTPLUG_CPU0 is off.
+ Some features depend on CPU0. Known dependencies are:
+ 1. Resume from suspend/hibernate depends on CPU0.
+ Suspend/hibernate will fail if CPU0 is offline and you
+ need to online CPU0 before suspend/hibernate.
+ 2. PIC interrupts also depend on CPU0. CPU0 can't be
+ removed if a PIC interrupt is detected.
+ It's said poweroff/reboot may depend on CPU0 on some
+ machines although I haven't seen such issues so far
+ after CPU0 is offline on a few tested machines.
+ If the dependencies are under your control, you can
+ turn on cpu0_hotplug.
+
nptcg= [IA-64] Override max number of concurrent global TLB
purges which is reported from either PAL_VM_SUMMARY or
SAL PALO.
@@ -2394,6 +2412,27 @@ 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]
+ 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
+ be offloaded to "rcuoN" kthreads created for
+ that purpose. This reduces OS jitter on the
+ offloaded CPUs, which can be useful for HPC and
+ real-time workloads. It can also improve energy
+ efficiency for asymmetric multiprocessors.
+
+ rcu_nocbs_poll [KNL,BOOT]
+ Rather than requiring that offloaded CPUs
+ (specified by rcu_nocbs= above) explicitly
+ awaken the corresponding "rcuoN" kthreads,
+ make these kthreads poll for callbacks.
+ This improves the real-time response for the
+ offloaded CPUs by relieving them of the need to
+ wake up the corresponding kthread, but degrades
+ energy efficiency by requiring that the kthreads
+ periodically wake up to do the polling.
+
rcutree.blimit= [KNL,BOOT]
Set maximum number of finished RCU callbacks to process
in one batch.
@@ -2859,6 +2898,22 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
to facilitate early boot debugging.
See also Documentation/trace/events.txt
+ trace_options=[option-list]
+ [FTRACE] Enable or disable tracer options at boot.
+ The option-list is a comma delimited list of options
+ that can be enabled or disabled just as if you were
+ to echo the option name into
+
+ /sys/kernel/debug/tracing/trace_options
+
+ For example, to enable stacktrace option (to dump the
+ stack trace of each event), add to the command line:
+
+ trace_options=stacktrace
+
+ See also Documentation/trace/ftrace.txt "trace options"
+ section.
+
transparent_hugepage=
[KNL]
Format: [always|madvise|never]
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index 2759f7c188f..3c4e1b3b80a 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -251,12 +251,13 @@ And there are a number of things that _must_ or _must_not_ be assumed:
And for:
- *A = X; Y = *A;
+ *A = X; *(A + 4) = Y;
- we may get either of:
+ we may get any of:
- STORE *A = X; Y = LOAD *A;
- STORE *A = Y = X;
+ STORE *A = X; STORE *(A + 4) = Y;
+ STORE *(A + 4) = Y; STORE *A = X;
+ STORE {*A, *(A + 4) } = {X, Y};
=========================
diff --git a/Documentation/memory-hotplug.txt b/Documentation/memory-hotplug.txt
index 6d0c2519cf4..c6f993d491b 100644
--- a/Documentation/memory-hotplug.txt
+++ b/Documentation/memory-hotplug.txt
@@ -161,7 +161,8 @@ a recent addition and not present on older kernels.
in the memory block.
'state' : read-write
at read: contains online/offline state of memory.
- at write: user can specify "online", "offline" command
+ at write: user can specify "online_kernel",
+ "online_movable", "online", "offline" command
which will be performed on al sections in the block.
'phys_device' : read-only: designed to show the name of physical memory
device. This is not well implemented now.
@@ -255,6 +256,17 @@ For onlining, you have to write "online" to the section's state file as:
% echo online > /sys/devices/system/memory/memoryXXX/state
+This onlining will not change the ZONE type of the target memory section,
+If the memory section is in ZONE_NORMAL, you can change it to ZONE_MOVABLE:
+
+% echo online_movable > /sys/devices/system/memory/memoryXXX/state
+(NOTE: current limit: this memory section must be adjacent to ZONE_MOVABLE)
+
+And if the memory section is in ZONE_MOVABLE, you can change it to ZONE_NORMAL:
+
+% echo online_kernel > /sys/devices/system/memory/memoryXXX/state
+(NOTE: current limit: this memory section must be adjacent to ZONE_NORMAL)
+
After this, section memoryXXX's state will be 'online' and the amount of
available memory will be increased.
@@ -377,15 +389,18 @@ The third argument is passed by pointer of struct memory_notify.
struct memory_notify {
unsigned long start_pfn;
unsigned long nr_pages;
+ int status_change_nid_normal;
int status_change_nid;
}
start_pfn is start_pfn of online/offline memory.
nr_pages is # of pages of online/offline memory.
+status_change_nid_normal is set node id when N_NORMAL_MEMORY of nodemask
+is (will be) set/clear, if this is -1, then nodemask status is not changed.
status_change_nid is set node id when N_HIGH_MEMORY of nodemask is (will be)
set/clear. It means a new(memoryless) node gets new memory by online and a
node loses all memory. If this is -1, then nodemask status is not changed.
-If status_changed_nid >= 0, callback should create/discard structures for the
+If status_changed_nid* >= 0, callback should create/discard structures for the
node if necessary.
--------------
diff --git a/Documentation/mmc/mmc-dev-attrs.txt b/Documentation/mmc/mmc-dev-attrs.txt
index 22ae8441489..0d98fac8893 100644
--- a/Documentation/mmc/mmc-dev-attrs.txt
+++ b/Documentation/mmc/mmc-dev-attrs.txt
@@ -25,6 +25,8 @@ All attributes are read-only.
serial Product Serial Number (from CID Register)
erase_size Erase group size
preferred_erase_size Preferred erase size
+ raw_rpmb_size_mult RPMB partition size
+ rel_sectors Reliable write sector count
Note on Erase Size and Preferred Erase Size:
@@ -65,6 +67,11 @@ Note on Erase Size and Preferred Erase Size:
"preferred_erase_size" is in bytes.
+Note on raw_rpmb_size_mult:
+ "raw_rpmb_size_mult" is a mutliple of 128kB block.
+ RPMB size in byte is calculated by using the following equation:
+ RPMB partition size = 128kB x raw_rpmb_size_mult
+
SD/MMC/SDIO Clock Gating Attribute
==================================
diff --git a/Documentation/networking/netdev-features.txt b/Documentation/networking/netdev-features.txt
index 4164f5c02e4..f310edec8a7 100644
--- a/Documentation/networking/netdev-features.txt
+++ b/Documentation/networking/netdev-features.txt
@@ -164,4 +164,4 @@ read the CRC recorded by the NIC on receipt of the packet.
This requests that the NIC receive all possible frames, including errored
frames (such as bad FCS, etc). This can be helpful when sniffing a link with
bad packets on it. Some NICs may receive more packets if also put into normal
-PROMISC mdoe.
+PROMISC mode.
diff --git a/Documentation/networking/vxlan.txt b/Documentation/networking/vxlan.txt
index 5b34b762d7d..6d993510f09 100644
--- a/Documentation/networking/vxlan.txt
+++ b/Documentation/networking/vxlan.txt
@@ -32,7 +32,7 @@ no entry is in the forwarding table.
# ip link delete vxlan0
3. Show vxlan info
- # ip -d show vxlan0
+ # ip -d link show vxlan0
It is possible to create, destroy and display the vxlan
forwarding table using the new bridge command.
@@ -41,7 +41,7 @@ forwarding table using the new bridge command.
# bridge fdb add to 00:17:42:8a:b4:05 dst 192.19.0.2 dev vxlan0
2. Delete forwarding table entry
- # bridge fdb delete 00:17:42:8a:b4:05
+ # bridge fdb delete 00:17:42:8a:b4:05 dev vxlan0
3. Show forwarding table
# bridge fdb show dev vxlan0
diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt
index 3b4ee532886..da40efbef6e 100644
--- a/Documentation/pinctrl.txt
+++ b/Documentation/pinctrl.txt
@@ -364,6 +364,9 @@ will get an pin number into its handled number range. Further it is also passed
the range ID value, so that the pin controller knows which range it should
deal with.
+Calling pinctrl_add_gpio_range from pinctrl driver is DEPRECATED. Please see
+section 2.1 of Documentation/devicetree/bindings/gpio/gpio.txt on how to bind
+pinctrl and gpio drivers.
PINMUX interfaces
=================
@@ -1193,4 +1196,6 @@ foo_switch()
...
}
-The above has to be done from process context.
+The above has to be done from process context. The reservation of the pins
+will be done when the state is activated, so in effect one specific pin
+can be used by different functions at different times on a running system.
diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt
index 17e130a8034..79a2a58425e 100644
--- a/Documentation/power/pm_qos_interface.txt
+++ b/Documentation/power/pm_qos_interface.txt
@@ -99,7 +99,7 @@ reading the aggregated value does not require any locking mechanism.
From kernel mode the use of this interface is the following:
-int dev_pm_qos_add_request(device, handle, value):
+int dev_pm_qos_add_request(device, handle, type, value):
Will insert an element into the list for that identified device with the
target value. Upon change to this list the new target is recomputed and any
registered notifiers are called only if the target value is now different.
diff --git a/Documentation/telephony/00-INDEX b/Documentation/telephony/00-INDEX
deleted file mode 100644
index 4ffe0ed5b6f..00000000000
--- a/Documentation/telephony/00-INDEX
+++ /dev/null
@@ -1,4 +0,0 @@
-00-INDEX
- - this file.
-ixj.txt
- - document describing the Quicknet drivers.
diff --git a/Documentation/telephony/ixj.txt b/Documentation/telephony/ixj.txt
deleted file mode 100644
index db94fb6c567..00000000000
--- a/Documentation/telephony/ixj.txt
+++ /dev/null
@@ -1,394 +0,0 @@
-Linux Quicknet-Drivers-Howto
-Quicknet Technologies, Inc. (www.quicknet.net)
-Version 0.3.4 December 18, 1999
-
-1.0 Introduction
-
-This document describes the first GPL release version of the Linux
-driver for the Quicknet Internet PhoneJACK and Internet LineJACK
-cards. More information about these cards is available at
-www.quicknet.net. The driver version discussed in this document is
-0.3.4.
-
-These cards offer nice telco style interfaces to use your standard
-telephone/key system/PBX as the user interface for VoIP applications.
-The Internet LineJACK also offers PSTN connectivity for a single line
-Internet to PSTN gateway. Of course, you can add more than one card
-to a system to obtain multi-line functionality. At this time, the
-driver supports the POTS port on both the Internet PhoneJACK and the
-Internet LineJACK, but the PSTN port on the latter card is not yet
-supported.
-
-This document, and the drivers for the cards, are intended for a
-limited audience that includes technically capable programmers who
-would like to experiment with Quicknet cards. The drivers are
-considered in ALPHA status and are not yet considered stable enough
-for general, widespread use in an unlimited audience.
-
-That's worth saying again:
-
-THE LINUX DRIVERS FOR QUICKNET CARDS ARE PRESENTLY IN A ALPHA STATE
-AND SHOULD NOT BE CONSIDERED AS READY FOR NORMAL WIDESPREAD USE.
-
-They are released early in the spirit of Internet development and to
-make this technology available to innovators who would benefit from
-early exposure.
-
-When we promote the device driver to "beta" level it will be
-considered ready for non-programmer, non-technical users. Until then,
-please be aware that these drivers may not be stable and may affect
-the performance of your system.
-
-
-1.1 Latest Additions/Improvements
-
-The 0.3.4 version of the driver is the first GPL release. Several
-features had to be removed from the prior binary only module, mostly
-for reasons of Intellectual Property rights. We can't release
-information that is not ours - so certain aspects of the driver had to
-be removed to protect the rights of others.
-
-Specifically, very old Internet PhoneJACK cards have non-standard
-G.723.1 codecs (due to the early nature of the DSPs in those days).
-The auto-conversion code to bring those cards into compliance with
-today's standards is available as a binary only module to those people
-needing it. If you bought your card after 1997 or so, you are OK -
-it's only the very old cards that are affected.
-
-Also, the code to download G.728/G.729/G.729a codecs to the DSP is
-available as a binary only module as well. This IP is not ours to
-release.
-
-Hooks are built into the GPL driver to allow it to work with other
-companion modules that are completely separate from this module.
-
-1.2 Copyright, Trademarks, Disclaimer, & Credits
-
-Copyright
-
-Copyright (c) 1999 Quicknet Technologies, Inc. Permission is granted
-to freely copy and distribute this document provided you preserve it
-in its original form. For corrections and minor changes contact the
-maintainer at linux@quicknet.net.
-
-Trademarks
-
-Internet PhoneJACK and Internet LineJACK are registered trademarks of
-Quicknet Technologies, Inc.
-
-Disclaimer
-
-Much of the info in this HOWTO is early information released by
-Quicknet Technologies, Inc. for the express purpose of allowing early
-testing and use of the Linux drivers developed for their products.
-While every attempt has been made to be thorough, complete and
-accurate, the information contained here may be unreliable and there
-are likely a number of errors in this document. Please let the
-maintainer know about them. Since this is free documentation, it
-should be obvious that neither I nor previous authors can be held
-legally responsible for any errors.
-
-Credits
-
-This HOWTO was written by:
-
- Greg Herlein <gherlein@quicknet.net>
- Ed Okerson <eokerson@quicknet.net>
-
-1.3 Future Plans: You Can Help
-
-Please let the maintainer know of any errors in facts, opinions,
-logic, spelling, grammar, clarity, links, etc. But first, if the date
-is over a month old, check to see that you have the latest
-version. Please send any info that you think belongs in this document.
-
-You can also contribute code and/or bug-fixes for the sample
-applications.
-
-
-1.4 Where to get things
-
-Info on latest versions of the driver are here:
-
-http://web.archive.org/web/*/http://www.quicknet.net/develop.htm
-
-1.5 Mailing List
-
-Quicknet operates a mailing list to provide a public forum on using
-these drivers.
-
-To subscribe to the linux-sdk mailing list, send an email to:
-
- majordomo@linux.quicknet.net
-
-In the body of the email, type:
-
- subscribe linux-sdk <your-email-address>
-
-Please delete any signature block that you would normally add to the
-bottom of your email - it tends to confuse majordomo.
-
-To send mail to the list, address your mail to
-
- linux-sdk@linux.quicknet.net
-
-Your message will go out to everyone on the list.
-
-To unsubscribe to the linux-sdk mailing list, send an email to:
-
- majordomo@linux.quicknet.net
-
-In the body of the email, type:
-
- unsubscribe linux-sdk <your-email-address>
-
-
-
-2.0 Requirements
-
-2.1 Quicknet Card(s)
-
-You will need at least one Internet PhoneJACK or Internet LineJACK
-cards. These are ISA or PCI bus devices that use Plug-n-Play for
-configuration, and use no IRQs. The driver will support up to 16
-cards in any one system, of any mix between the two types.
-
-Note that you will need two cards to do any useful testing alone, since
-you will need a card on both ends of the connection. Of course, if
-you are doing collaborative work, perhaps your friends or coworkers
-have cards too. If not, we'll gladly sell them some!
-
-
-2.2 ISAPNP
-
-Since the Quicknet cards are Plug-n-Play devices, you will need the
-isapnp tools package to configure the cards, or you can use the isapnp
-module to autoconfigure them. The former package probably came with
-your Linux distribution. Documentation on this package is available
-online at:
-
-http://mailer.wiwi.uni-marburg.de/linux/LDP/HOWTO/Plug-and-Play-HOWTO.html
-
-The isapnp autoconfiguration is available on the Quicknet website at:
-
- http://www.quicknet.net/develop.htm
-
-though it may be in the kernel by the time you read this.
-
-
-3.0 Card Configuration
-
-If you did not get your drivers as part of the linux kernel, do the
-following to install them:
-
- a. untar the distribution file. We use the following command:
- tar -xvzf ixj-0.x.x.tgz
-
-This creates a subdirectory holding all the necessary files. Go to that
-subdirectory.
-
- b. run the "ixj_dev_create" script to remove any stray device
-files left in the /dev directory, and to create the new officially
-designated device files. Note that the old devices were called
-/dev/ixj, and the new method uses /dev/phone.
-
- c. type "make;make install" - this will compile and install the
-module.
-
- d. type "depmod -av" to rebuild all your kernel version dependencies.
-
- e. if you are using the isapnp module to configure the cards
- automatically, then skip to step f. Otherwise, ensure that you
- have run the isapnp configuration utility to properly configure
- the cards.
-
- e1. The Internet PhoneJACK has one configuration register that
- requires 16 IO ports. The Internet LineJACK card has two
- configuration registers and isapnp reports that IO 0
- requires 16 IO ports and IO 1 requires 8. The Quicknet
- driver assumes that these registers are configured to be
- contiguous, i.e. if IO 0 is set to 0x340 then IO 1 should
- be set to 0x350.
-
- Make sure that none of the cards overlap if you have
- multiple cards in the system.
-
- If you are new to the isapnp tools, you can jumpstart
- yourself by doing the following:
-
- e2. go to the /etc directory and run pnpdump to get a blank
- isapnp.conf file.
-
- pnpdump > /etc/isapnp.conf
-
- e3. edit the /etc/isapnp.conf file to set the IO warnings and
- the register IO addresses. The IO warnings means that you
- should find the line in the file that looks like this:
-
- (CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) # or WARNING
-
- and you should edit the line to look like this:
-
- (CONFLICT (IO WARNING)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) #
- or WARNING
-
- The next step is to set the IO port addresses. The issue
- here is that isapnp does not identify all of the ports out
- there. Specifically any device that does not have a driver
- or module loaded by Linux will not be registered. This
- includes older sound cards and network cards. We have
- found that the IO port 0x300 is often used even though
- isapnp claims that no-one is using those ports. We
- recommend that for a single card installation that port
- 0x340 (and 0x350) be used. The IO port line should change
- from this:
-
- (IO 0 (SIZE 16) (BASE 0x0300) (CHECK))
-
- to this:
-
- (IO 0 (SIZE 16) (BASE 0x0340) )
-
- e4. if you have multiple Quicknet cards, make sure that you do
- not have any overlaps. Be especially careful if you are
- mixing Internet PhoneJACK and Internet LineJACK cards in
- the same system. In these cases we recommend moving the
- IO port addresses to the 0x400 block. Please note that on
- a few machines the 0x400 series are used. Feel free to
- experiment with other addresses. Our cards have been
- proven to work using IO addresses of up to 0xFF0.
-
- e5. the last step is to uncomment the activation line so the
- drivers will be associated with the port. This means the
- line (immediately below) the IO line should go from this:
-
- # (ACT Y)
-
- to this:
-
- (ACT Y)
-
- Once you have finished editing the isapnp.conf file you
- must submit it into the pnp driverconfigure the cards.
- This is done using the following command:
-
- isapnp isapnp.conf
-
- If this works you should see a line that identifies the
- Quicknet device, the IO port(s) chosen, and a message
- "Enabled OK".
-
- f. if you are loading the module by hand, use insmod. An example
-of this would look like this:
-
- insmod phonedev
- insmod ixj dspio=0x320,0x310 xio=0,0x330
-
-Then verify the module loaded by running lsmod. If you are not using a
-module that matches your kernel version, you may need to "force" the
-load using the -f option in the insmod command.
-
- insmod phonedev
- insmod -f ixj dspio=0x320,0x310 xio=0,0x330
-
-
-If you are using isapnp to autoconfigure your card, then you do NOT
-need any of the above, though you need to use depmod to load the
-driver, like this:
-
- depmod ixj
-
-which will result in the needed drivers getting loaded automatically.
-
- g. if you are planning on having the kernel automatically request
-the module for you, then you need to edit /etc/conf.modules and add the
-following lines:
-
- options ixj dspio=0x340 xio=0x330 ixjdebug=0
-
-If you do this, then when you execute an application that uses the
-module the kernel will request that it is loaded.
-
- h. if you want non-root users to be able to read and write to the
-ixj devices (this is a good idea!) you should do the following:
-
- - decide upon a group name to use and create that group if
- needed. Add the user names to that group that you wish to
- have access to the device. For example, we typically will
- create a group named "ixj" in /etc/group and add all users
- to that group that we want to run software that can use the
- ixjX devices.
-
- - change the permissions on the device files, like this:
-
- chgrp ixj /dev/ixj*
- chmod 660 /dev/ixj*
-
-Once this is done, then non-root users should be able to use the
-devices. If you have enabled autoloading of modules, then the user
-should be able to open the device and have the module loaded
-automatically for them.
-
-
-4.0 Driver Installation problems.
-
-We have tested these drivers on the 2.2.9, 2.2.10, 2.2.12, and 2.2.13 kernels
-and in all cases have eventually been able to get the drivers to load and
-run. We have found four types of problems that prevent this from happening.
-The problems and solutions are:
-
- a. A step was missed in the installation. Go back and use section 3
-as a checklist. Many people miss running the ixj_dev_create script and thus
-never load the device names into the filesystem.
-
- b. The kernel is inconsistently linked. We have found this problem in
-the Out Of the Box installation of several distributions. The symptoms
-are that neither driver will load, and that the unknown symbols include "jiffy"
-and "kmalloc". The solution is to recompile both the kernel and the
-modules. The command string for the final compile looks like this:
-
- In the kernel directory:
- 1. cp .config /tmp
- 2. make mrproper
- 3. cp /tmp/.config .
- 4. make clean;make bzImage;make modules;make modules_install
-
-This rebuilds both the kernel and all the modules and makes sure they all
-have the same linkages. This generally solves the problem once the new
-kernel is installed and the system rebooted.
-
- c. The kernel has been patched, then unpatched. This happens when
-someone decides to use an earlier kernel after they load a later kernel.
-The symptoms are proceeding through all three above steps and still not
-being able to load the driver. What has happened is that the generated
-header files are out of sync with the kernel itself. The solution is
-to recompile (again) using "make mrproper". This will remove and then
-regenerate all the necessary header files. Once this is done, then you
-need to install and reboot the kernel. We have not seen any problem
-loading one of our drivers after this treatment.
-
-5.0 Known Limitations
-
-We cannot currently play "dial-tone" and listen for DTMF digits at the
-same time using the ISA PhoneJACK. This is a bug in the 8020 DSP chip
-used on that product. All other Quicknet products function normally
-in this regard. We have a work-around, but it's not done yet. Until
-then, if you want dial-tone, you can always play a recorded dial-tone
-sound into the audio until you have gathered the DTMF digits.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Documentation/usb/error-codes.txt b/Documentation/usb/error-codes.txt
index b3f606b81a0..9c3eb845ebe 100644
--- a/Documentation/usb/error-codes.txt
+++ b/Documentation/usb/error-codes.txt
@@ -21,6 +21,8 @@ Non-USB-specific:
USB-specific:
+-EBUSY The URB is already active.
+
-ENODEV specified USB-device or bus doesn't exist
-ENOENT specified interface or endpoint does not exist or
@@ -35,9 +37,8 @@ USB-specific:
d) ISO: number_of_packets is < 0
e) various other cases
--EAGAIN a) specified ISO start frame too early
- b) (using ISO-ASAP) too much scheduled for the future
- wait some time and try again.
+-EXDEV ISO: URB_ISO_ASAP wasn't specified and all the frames
+ the URB would be scheduled in have already expired.
-EFBIG Host controller driver can't schedule that many ISO frames.
diff --git a/Documentation/usb/mass-storage.txt b/Documentation/usb/mass-storage.txt
index e9b9334627b..59063ad7a60 100644
--- a/Documentation/usb/mass-storage.txt
+++ b/Documentation/usb/mass-storage.txt
@@ -20,9 +20,9 @@
This document describes how to use the gadget from user space, its
relation to mass storage function (or MSF) and different gadgets
- using it, and how it differs from File Storage Gadget (or FSG). It
- will talk only briefly about how to use MSF within composite
- gadgets.
+ using it, and how it differs from File Storage Gadget (or FSG)
+ (which is no longer included in Linux). It will talk only briefly
+ about how to use MSF within composite gadgets.
* Module parameters
@@ -198,16 +198,15 @@
The Mass Storage Function and thus the Mass Storage Gadget has been
based on the File Storage Gadget. The difference between the two is
that MSG is a composite gadget (ie. uses the composite framework)
- while file storage gadget is a traditional gadget. From userspace
+ while file storage gadget was a traditional gadget. From userspace
point of view this distinction does not really matter, but from
kernel hacker's point of view, this means that (i) MSG does not
duplicate code needed for handling basic USB protocol commands and
(ii) MSF can be used in any other composite gadget.
- Because of that, File Storage Gadget has been deprecated and
- scheduled to be removed in Linux 3.8. All users need to transition
- to the Mass Storage Gadget by that time. The two gadgets behave
- mostly the same from the outside except:
+ Because of that, File Storage Gadget has been removed in Linux 3.8.
+ All users need to transition to the Mass Storage Gadget. The two
+ gadgets behave mostly the same from the outside except:
1. In FSG the “removable” and “cdrom” module parameters set the flag
for all logical units whereas in MSG they accept a list of y/n
diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt
index 9efceff51bf..f15cb74c4f7 100644
--- a/Documentation/x86/boot.txt
+++ b/Documentation/x86/boot.txt
@@ -1013,7 +1013,7 @@ boot_params as that of 16-bit boot protocol, the boot loader should
also fill the additional fields of the struct boot_params as that
described in zero-page.txt.
-After setupping the struct boot_params, the boot loader can load the
+After setting up the struct boot_params, the boot loader can load the
32/64-bit kernel in the same way as that of 16-bit boot protocol.
In 32-bit boot protocol, the kernel is started by jumping to the
@@ -1023,7 +1023,7 @@ In 32-bit boot protocol, the kernel is started by jumping to the
At entry, the CPU must be in 32-bit protected mode with paging
disabled; a GDT must be loaded with the descriptors for selectors
__BOOT_CS(0x10) and __BOOT_DS(0x18); both descriptors must be 4G flat
-segment; __BOOS_CS must have execute/read permission, and __BOOT_DS
+segment; __BOOT_CS must have execute/read permission, and __BOOT_DS
must have read/write permission; CS must be __BOOT_CS and DS, ES, SS
must be __BOOT_DS; interrupt must be disabled; %esi must hold the base
address of the struct boot_params; %ebp, %edi and %ebx must be zero.
diff --git a/Documentation/zh_CN/arm/kernel_user_helpers.txt b/Documentation/zh_CN/arm/kernel_user_helpers.txt
new file mode 100644
index 00000000000..cd7fc8f34cf
--- /dev/null
+++ b/Documentation/zh_CN/arm/kernel_user_helpers.txt
@@ -0,0 +1,284 @@
+Chinese translated version of Documentation/arm/kernel_user_helpers.txt
+
+If you have any comment or update to the content, please contact the
+original document maintainer directly. However, if you have a problem
+communicating in English you can also ask the Chinese maintainer for
+help. Contact the Chinese maintainer if this translation is outdated
+or if there is a problem with the translation.
+
+Maintainer: Nicolas Pitre <nicolas.pitre@linaro.org>
+ Dave Martin <dave.martin@linaro.org>
+Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
+---------------------------------------------------------------------
+Documentation/arm/kernel_user_helpers.txt 的中文翻译
+
+如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
+交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
+译存在问题,请联系中文版维护者。
+英文版维护者: Nicolas Pitre <nicolas.pitre@linaro.org>
+ Dave Martin <dave.martin@linaro.org>
+中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
+中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
+中文版校译者: 宋冬生 Dongsheng Song <dongshneg.song@gmail.com>
+ 傅炜 Fu Wei <tekkamanninja@gmail.com>
+
+
+以下为正文
+---------------------------------------------------------------------
+内核提供的用户空间辅助代码
+=========================
+
+在内核内存空间的固定地址处,有一个由内核提供并可从用户空间访问的代码
+段。它用于向用户空间提供因在许多 ARM CPU 中未实现的特性和/或指令而需
+内核提供帮助的某些操作。这些代码直接在用户模式下执行的想法是为了获得
+最佳效率,但那些与内核计数器联系过于紧密的部分,则被留给了用户库实现。
+事实上,此代码甚至可能因不同的 CPU 而异,这取决于其可用的指令集或它
+是否为 SMP 系统。换句话说,内核保留在不作出警告的情况下根据需要更改
+这些代码的权利。只有本文档描述的入口及其结果是保证稳定的。
+
+这与完全成熟的 VDSO 实现不同(但两者并不冲突),尽管如此,VDSO 可阻止
+某些通过常量高效跳转到那些代码段的汇编技巧。且由于那些代码段在返回用户
+代码前仅使用少量的代码周期,则一个 VDSO 间接远程调用将会在这些简单的
+操作上增加一个可测量的开销。
+
+在对那些拥有原生支持的新型处理器进行代码优化时,仅在已为其他操作使用
+了类似的新增指令,而导致二进制结果已与早期 ARM 处理器不兼容的情况下,
+用户空间才应绕过这些辅助代码,并在内联函数中实现这些操作(无论是通过
+编译器在代码中直接放置,还是作为库函数调用实现的一部分)。也就是说,
+如果你编译的代码不会为了其他目的使用新指令,则不要仅为了避免使用这些
+内核辅助代码,导致二进制程序无法在早期处理器上运行。
+
+新的辅助代码可能随着时间的推移而增加,所以新内核中的某些辅助代码在旧
+内核中可能不存在。因此,程序必须在对任何辅助代码调用假设是安全之前,
+检测 __kuser_helper_version 的值(见下文)。理想情况下,这种检测应该
+只在进程启动时执行一次;如果内核版本不支持所需辅助代码,则该进程可尽早
+中止执行。
+
+kuser_helper_version
+--------------------
+
+位置: 0xffff0ffc
+
+参考声明:
+
+ extern int32_t __kuser_helper_version;
+
+定义:
+
+ 这个区域包含了当前运行内核实现的辅助代码版本号。用户空间可以通过读
+ 取此版本号以确定特定的辅助代码是否存在。
+
+使用范例:
+
+#define __kuser_helper_version (*(int32_t *)0xffff0ffc)
+
+void check_kuser_version(void)
+{
+ if (__kuser_helper_version < 2) {
+ fprintf(stderr, "can't do atomic operations, kernel too old\n");
+ abort();
+ }
+}
+
+注意:
+
+ 用户空间可以假设这个域的值不会在任何单个进程的生存期内改变。也就
+ 是说,这个域可以仅在库的初始化阶段或进程启动阶段读取一次。
+
+kuser_get_tls
+-------------
+
+位置: 0xffff0fe0
+
+参考原型:
+
+ void * __kuser_get_tls(void);
+
+输入:
+
+ lr = 返回地址
+
+输出:
+
+ r0 = TLS 值
+
+被篡改的寄存器:
+
+ 无
+
+定义:
+
+ 获取之前通过 __ARM_NR_set_tls 系统调用设置的 TLS 值。
+
+使用范例:
+
+typedef void * (__kuser_get_tls_t)(void);
+#define __kuser_get_tls (*(__kuser_get_tls_t *)0xffff0fe0)
+
+void foo()
+{
+ void *tls = __kuser_get_tls();
+ printf("TLS = %p\n", tls);
+}
+
+注意:
+
+ - 仅在 __kuser_helper_version >= 1 时,此辅助代码存在
+ (从内核版本 2.6.12 开始)。
+
+kuser_cmpxchg
+-------------
+
+位置: 0xffff0fc0
+
+参考原型:
+
+ int __kuser_cmpxchg(int32_t oldval, int32_t newval, volatile int32_t *ptr);
+
+输入:
+
+ r0 = oldval
+ r1 = newval
+ r2 = ptr
+ lr = 返回地址
+
+输出:
+
+ r0 = 成功代码 (零或非零)
+ C flag = 如果 r0 == 0 则置 1,如果 r0 != 0 则清零。
+
+被篡改的寄存器:
+
+ r3, ip, flags
+
+定义:
+
+ 仅在 *ptr 为 oldval 时原子保存 newval 于 *ptr 中。
+ 如果 *ptr 被改变,则返回值为零,否则为非零值。
+ 如果 *ptr 被改变,则 C flag 也会被置 1,以实现调用代码中的汇编
+ 优化。
+
+使用范例:
+
+typedef int (__kuser_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
+#define __kuser_cmpxchg (*(__kuser_cmpxchg_t *)0xffff0fc0)
+
+int atomic_add(volatile int *ptr, int val)
+{
+ int old, new;
+
+ do {
+ old = *ptr;
+ new = old + val;
+ } while(__kuser_cmpxchg(old, new, ptr));
+
+ return new;
+}
+
+注意:
+
+ - 这个例程已根据需要包含了内存屏障。
+
+ - 仅在 __kuser_helper_version >= 2 时,此辅助代码存在
+ (从内核版本 2.6.12 开始)。
+
+kuser_memory_barrier
+--------------------
+
+位置: 0xffff0fa0
+
+参考原型:
+
+ void __kuser_memory_barrier(void);
+
+输入:
+
+ lr = 返回地址
+
+输出:
+
+ 无
+
+被篡改的寄存器:
+
+ 无
+
+定义:
+
+ 应用于任何需要内存屏障以防止手动数据修改带来的一致性问题,以及
+ __kuser_cmpxchg 中。
+
+使用范例:
+
+typedef void (__kuser_dmb_t)(void);
+#define __kuser_dmb (*(__kuser_dmb_t *)0xffff0fa0)
+
+注意:
+
+ - 仅在 __kuser_helper_version >= 3 时,此辅助代码存在
+ (从内核版本 2.6.15 开始)。
+
+kuser_cmpxchg64
+---------------
+
+位置: 0xffff0f60
+
+参考原型:
+
+ int __kuser_cmpxchg64(const int64_t *oldval,
+ const int64_t *newval,
+ volatile int64_t *ptr);
+
+输入:
+
+ r0 = 指向 oldval
+ r1 = 指向 newval
+ r2 = 指向目标值
+ lr = 返回地址
+
+输出:
+
+ r0 = 成功代码 (零或非零)
+ C flag = 如果 r0 == 0 则置 1,如果 r0 != 0 则清零。
+
+被篡改的寄存器:
+
+ r3, lr, flags
+
+定义:
+
+ 仅在 *ptr 等于 *oldval 指向的 64 位值时,原子保存 *newval
+ 指向的 64 位值于 *ptr 中。如果 *ptr 被改变,则返回值为零,
+ 否则为非零值。
+
+ 如果 *ptr 被改变,则 C flag 也会被置 1,以实现调用代码中的汇编
+ 优化。
+
+使用范例:
+
+typedef int (__kuser_cmpxchg64_t)(const int64_t *oldval,
+ const int64_t *newval,
+ volatile int64_t *ptr);
+#define __kuser_cmpxchg64 (*(__kuser_cmpxchg64_t *)0xffff0f60)
+
+int64_t atomic_add64(volatile int64_t *ptr, int64_t val)
+{
+ int64_t old, new;
+
+ do {
+ old = *ptr;
+ new = old + val;
+ } while(__kuser_cmpxchg64(&old, &new, ptr));
+
+ return new;
+}
+
+注意:
+
+ - 这个例程已根据需要包含了内存屏障。
+
+ - 由于这个过程的代码长度(此辅助代码跨越 2 个常规的 kuser “槽”),
+ 因此 0xffff0f80 不被作为有效的入口点。
+
+ - 仅在 __kuser_helper_version >= 5 时,此辅助代码存在
+ (从内核版本 3.1 开始)。
diff --git a/Documentation/zh_CN/arm64/memory.txt b/Documentation/zh_CN/arm64/memory.txt
index 83b51931470..a5f6283829f 100644
--- a/Documentation/zh_CN/arm64/memory.txt
+++ b/Documentation/zh_CN/arm64/memory.txt
@@ -47,21 +47,21 @@ AArch64 Linux 内存布局:
-----------------------------------------------------------------------
0000000000000000 0000007fffffffff 512GB 用户空间
-ffffff8000000000 ffffffbbfffcffff ~240GB vmalloc
+ffffff8000000000 ffffffbbfffeffff ~240GB vmalloc
-ffffffbbfffd0000 ffffffbcfffdffff 64KB [防护页]
+ffffffbbffff0000 ffffffbbffffffff 64KB [防护页]
-ffffffbbfffe0000 ffffffbcfffeffff 64KB PCI I/O 空间
+ffffffbc00000000 ffffffbdffffffff 8GB vmemmap
-ffffffbbffff0000 ffffffbcffffffff 64KB [防护页]
+ffffffbe00000000 ffffffbffbbfffff ~8GB [防护页,未来用于 vmmemap]
-ffffffbc00000000 ffffffbdffffffff 8GB vmemmap
+ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O 空间
-ffffffbe00000000 ffffffbffbffffff ~8GB [防护页,未来用于 vmmemap]
+ffffffbbffff0000 ffffffbcffffffff ~2MB [防护页]
ffffffbffc000000 ffffffbfffffffff 64MB 模块
-ffffffc000000000 ffffffffffffffff 256GB 内存空间
+ffffffc000000000 ffffffffffffffff 256GB 内核逻辑内存映射
4KB 页大小的转换表查找:
diff --git a/MAINTAINERS b/MAINTAINERS
index 59203e77ce9..23b9584c44c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -526,17 +526,17 @@ F: drivers/video/geode/
F: arch/x86/include/asm/geode.h
AMD IOMMU (AMD-VI)
-M: Joerg Roedel <joerg.roedel@amd.com>
+M: Joerg Roedel <joro@8bytes.org>
L: iommu@lists.linux-foundation.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
-S: Supported
+S: Maintained
F: drivers/iommu/amd_iommu*.[ch]
F: include/linux/amd-iommu.h
AMD MICROCODE UPDATE SUPPORT
-M: Andreas Herrmann <andreas.herrmann3@amd.com>
+M: Andreas Herrmann <herrmann.der.user@googlemail.com>
L: amd64-microcode@amd64.org
-S: Supported
+S: Maintained
F: arch/x86/kernel/microcode_amd.c
AMS (Apple Motion Sensor) DRIVER
@@ -841,6 +841,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git
F: arch/arm/mach-sa1100/jornada720.c
F: arch/arm/mach-sa1100/include/mach/jornada720.h
+ARM/IGEP MACHINE SUPPORT
+M: Enric Balletbo i Serra <eballetbo@gmail.com>
+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
+
ARM/INCOME PXA270 SUPPORT
M: Marek Vasut <marek.vasut@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1229,6 +1237,7 @@ F: drivers/video/wm8505fb*
F: drivers/video/wmt_ge_rops.*
F: drivers/tty/serial/vt8500_serial.c
F: drivers/rtc/rtc-vt8500-c
+F: drivers/mmc/host/wmt-sdmmc.c
ARM/ZIPIT Z2 SUPPORT
M: Marek Vasut <marek.vasut@gmail.com>
@@ -1360,14 +1369,6 @@ S: Maintained
F: drivers/atm/
F: include/linux/atm*
-ATMEL AT91 MCI DRIVER
-M: Ludovic Desroches <ludovic.desroches@atmel.com>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-W: http://www.atmel.com/products/AT91/
-W: http://www.at91.com/
-S: Maintained
-F: drivers/mmc/host/at91_mci.c
-
ATMEL AT91 / AT32 MCI DRIVER
M: Ludovic Desroches <ludovic.desroches@atmel.com>
S: Maintained
@@ -1986,7 +1987,6 @@ F: fs/coda/
F: include/linux/coda*.h
COMMON CLK FRAMEWORK
-M: Mike Turquette <mturquette@ti.com>
M: Mike Turquette <mturquette@linaro.org>
L: linux-arm-kernel@lists.infradead.org (same as CLK API & CLKDEV)
T: git git://git.linaro.org/people/mturquette/linux.git
@@ -2708,10 +2708,10 @@ F: include/linux/edac.h
EDAC-AMD64
M: Doug Thompson <dougthompson@xmission.com>
-M: Borislav Petkov <borislav.petkov@amd.com>
+M: Borislav Petkov <bp@alien8.de>
L: linux-edac@vger.kernel.org
W: bluesmoke.sourceforge.net
-S: Supported
+S: Maintained
F: drivers/edac/amd64_edac*
EDAC-E752X
@@ -3596,7 +3596,49 @@ S: Maintained
F: drivers/hv/
F: drivers/hid/hid-hyperv.c
F: drivers/net/hyperv/
-F: drivers/staging/hv/
+
+I2C OVER PARALLEL PORT
+M: Jean Delvare <khali@linux-fr.org>
+L: linux-i2c@vger.kernel.org
+S: Maintained
+F: Documentation/i2c/busses/i2c-parport
+F: Documentation/i2c/busses/i2c-parport-light
+F: drivers/i2c/busses/i2c-parport.c
+F: drivers/i2c/busses/i2c-parport-light.c
+
+I2C/SMBUS CONTROLLER DRIVERS FOR PC
+M: Jean Delvare <khali@linux-fr.org>
+L: linux-i2c@vger.kernel.org
+S: Maintained
+F: Documentation/i2c/busses/i2c-ali1535
+F: Documentation/i2c/busses/i2c-ali1563
+F: Documentation/i2c/busses/i2c-ali15x3
+F: Documentation/i2c/busses/i2c-amd756
+F: Documentation/i2c/busses/i2c-amd8111
+F: Documentation/i2c/busses/i2c-i801
+F: Documentation/i2c/busses/i2c-nforce2
+F: Documentation/i2c/busses/i2c-piix4
+F: Documentation/i2c/busses/i2c-sis5595
+F: Documentation/i2c/busses/i2c-sis630
+F: Documentation/i2c/busses/i2c-sis96x
+F: Documentation/i2c/busses/i2c-via
+F: Documentation/i2c/busses/i2c-viapro
+F: drivers/i2c/busses/i2c-ali1535.c
+F: drivers/i2c/busses/i2c-ali1563.c
+F: drivers/i2c/busses/i2c-ali15x3.c
+F: drivers/i2c/busses/i2c-amd756.c
+F: drivers/i2c/busses/i2c-amd756-s4882.c
+F: drivers/i2c/busses/i2c-amd8111.c
+F: drivers/i2c/busses/i2c-i801.c
+F: drivers/i2c/busses/i2c-isch.c
+F: drivers/i2c/busses/i2c-nforce2.c
+F: drivers/i2c/busses/i2c-nforce2-s4985.c
+F: drivers/i2c/busses/i2c-piix4.c
+F: drivers/i2c/busses/i2c-sis5595.c
+F: drivers/i2c/busses/i2c-sis630.c
+F: drivers/i2c/busses/i2c-sis96x.c
+F: drivers/i2c/busses/i2c-via.c
+F: drivers/i2c/busses/i2c-viapro.c
I2C/SMBUS STUB DRIVER
M: "Mark M. Hoffman" <mhoffman@lightlink.com>
@@ -3605,9 +3647,8 @@ S: Maintained
F: drivers/i2c/busses/i2c-stub.c
I2C SUBSYSTEM
-M: "Jean Delvare (PC drivers, core)" <khali@linux-fr.org>
+M: Wolfram Sang <w.sang@pengutronix.de>
M: "Ben Dooks (embedded platforms)" <ben-linux@fluff.org>
-M: "Wolfram Sang (embedded platforms)" <w.sang@pengutronix.de>
L: linux-i2c@vger.kernel.org
W: http://i2c.wiki.kernel.org/
T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/
@@ -3618,6 +3659,13 @@ F: drivers/i2c/
F: include/linux/i2c.h
F: include/linux/i2c-*.h
+I2C-TAOS-EVM DRIVER
+M: Jean Delvare <khali@linux-fr.org>
+L: linux-i2c@vger.kernel.org
+S: Maintained
+F: Documentation/i2c/busses/i2c-taos-evm
+F: drivers/i2c/busses/i2c-taos-evm.c
+
I2C-TINY-USB DRIVER
M: Till Harbaum <till@harbaum.org>
L: linux-i2c@vger.kernel.org
@@ -3704,7 +3752,7 @@ S: Maintained
F: drivers/platform/x86/ideapad-laptop.c
IDE/ATAPI DRIVERS
-M: Borislav Petkov <petkovbb@gmail.com>
+M: Borislav Petkov <bp@alien8.de>
L: linux-ide@vger.kernel.org
S: Maintained
F: Documentation/cdrom/ide-cd
@@ -3740,6 +3788,15 @@ M: Stanislaw Gruszka <stf_xl@wp.pl>
S: Maintained
F: drivers/usb/atm/ueagle-atm.c
+INDUSTRY PACK SUBSYSTEM (IPACK)
+M: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
+M: Jens Taprogge <jens.taprogge@taprogge.org>
+M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+L: industrypack-devel@lists.sourceforge.net
+W: http://industrypack.sourceforge.net
+S: Maintained
+F: drivers/ipack/
+
INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
M: Mimi Zohar <zohar@us.ibm.com>
S: Supported
@@ -4231,8 +4288,8 @@ F: include/linux/lockd/
F: include/linux/sunrpc/
KERNEL VIRTUAL MACHINE (KVM)
-M: Avi Kivity <avi@redhat.com>
M: Marcelo Tosatti <mtosatti@redhat.com>
+M: Gleb Natapov <gleb@redhat.com>
L: kvm@vger.kernel.org
W: http://kvm.qumranet.com
S: Supported
@@ -5364,7 +5421,7 @@ S: Maintained
F: sound/drivers/opl4/
OPROFILE
-M: Robert Richter <robert.richter@amd.com>
+M: Robert Richter <rric@kernel.org>
L: oprofile-list@lists.sf.net
S: Maintained
F: arch/*/include/asm/oprofile*.h
@@ -5639,6 +5696,12 @@ S: Maintained
F: drivers/pinctrl/
F: include/linux/pinctrl/
+PIN CONTROLLER - ATMEL AT91
+M: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: drivers/pinctrl/pinctrl-at91.c
+
PIN CONTROLLER - ST SPEAR
M: Viresh Kumar <viresh.linux@gmail.com>
L: spear-devel@list.st.com
@@ -7210,6 +7273,14 @@ L: linux-xtensa@linux-xtensa.org
S: Maintained
F: arch/xtensa/
+THERMAL
+M: Zhang Rui <rui.zhang@intel.com>
+L: linux-pm@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git
+S: Supported
+F: drivers/thermal/
+F: include/linux/thermal.h
+
THINKPAD ACPI EXTRAS DRIVER
M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br>
L: ibm-acpi-devel@lists.sourceforge.net
@@ -7359,6 +7430,7 @@ K: ^Subject:.*(?i)trivial
TTY LAYER
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+M: Jiri Slaby <jslaby@suse.cz>
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git
F: drivers/tty/
@@ -7515,12 +7587,6 @@ L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/usb/storage/uas.c
-USB BLOCK DRIVER (UB ub)
-M: Pete Zaitcev <zaitcev@redhat.com>
-L: linux-usb@vger.kernel.org
-S: Supported
-F: drivers/block/ub.c
-
USB CDC ETHERNET DRIVER
M: Oliver Neukum <oliver@neukum.org>
L: linux-usb@vger.kernel.org
@@ -7887,13 +7953,6 @@ M: Roger Luethi <rl@hellgate.ch>
S: Maintained
F: drivers/net/ethernet/via/via-rhine.c
-VIAPRO SMBUS DRIVER
-M: Jean Delvare <khali@linux-fr.org>
-L: linux-i2c@vger.kernel.org
-S: Maintained
-F: Documentation/i2c/busses/i2c-viapro
-F: drivers/i2c/busses/i2c-viapro.c
-
VIA SD/MMC CARD CONTROLLER DRIVER
M: Bruce Chang <brucechang@via.com.tw>
M: Harald Welte <HaraldWelte@viatech.com>
@@ -8148,7 +8207,7 @@ F: drivers/platform/x86
X86 MCE INFRASTRUCTURE
M: Tony Luck <tony.luck@intel.com>
-M: Borislav Petkov <bp@amd64.org>
+M: Borislav Petkov <bp@alien8.de>
L: linux-edac@vger.kernel.org
S: Maintained
F: arch/x86/kernel/cpu/mcheck/*
diff --git a/Makefile b/Makefile
index 6edac73ee1b..540f7b240c7 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 3
PATCHLEVEL = 7
SUBLEVEL = 0
-EXTRAVERSION = -rc5
+EXTRAVERSION =
NAME = Terrified Chipmunk
# *DOCUMENTATION*
@@ -1321,10 +1321,12 @@ kernelversion:
# Clear a bunch of variables before executing the submake
tools/: FORCE
- $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/
+ $(Q)mkdir -p $(objtree)/tools
+ $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/
tools/%: FORCE
- $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/ $*
+ $(Q)mkdir -p $(objtree)/tools
+ $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/ $*
# Single targets
# ---------------------------------------------------------------------------
diff --git a/arch/Kconfig b/arch/Kconfig
index 366ec06a518..cc74aaea116 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -300,15 +300,16 @@ config SECCOMP_FILTER
See Documentation/prctl/seccomp_filter.txt for details.
-config HAVE_RCU_USER_QS
+config HAVE_CONTEXT_TRACKING
bool
help
- Provide kernel entry/exit hooks necessary for userspace
- RCU extended quiescent state. Syscalls need to be wrapped inside
- rcu_user_exit()-rcu_user_enter() through the slow path using
- TIF_NOHZ flag. Exceptions handlers must be wrapped as well. Irqs
- are already protected inside rcu_irq_enter/rcu_irq_exit() but
- preemption or signal handling on irq exit still need to be protected.
+ Provide kernel/user boundaries probes necessary for subsystems
+ that need it, such as userspace RCU extended quiescent state.
+ Syscalls need to be wrapped inside user_exit()-user_enter() through
+ the slow path using TIF_NOHZ flag. Exceptions handlers must be
+ wrapped as well. Irqs are already protected inside
+ rcu_irq_enter/rcu_irq_exit() but preemption or signal handling on
+ irq exit still need to be protected.
config HAVE_VIRT_CPU_ACCOUNTING
bool
diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild
index 64ffc9e9e54..dcfabb9f05a 100644
--- a/arch/alpha/include/asm/Kbuild
+++ b/arch/alpha/include/asm/Kbuild
@@ -11,3 +11,4 @@ header-y += reg.h
header-y += regdef.h
header-y += sysinfo.h
generic-y += exec.h
+generic-y += trace_clock.h
diff --git a/arch/alpha/include/asm/ioctls.h b/arch/alpha/include/asm/ioctls.h
index 80e1cee90f1..92c557be49f 100644
--- a/arch/alpha/include/asm/ioctls.h
+++ b/arch/alpha/include/asm/ioctls.h
@@ -95,6 +95,9 @@
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
#define TIOCVHANGUP 0x5437
+#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
+#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
+#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
#define TIOCSERCONFIG 0x5453
#define TIOCSERGWILD 0x5454
diff --git a/arch/alpha/include/asm/mman.h b/arch/alpha/include/asm/mman.h
index cbeb3616a28..0086b472bc2 100644
--- a/arch/alpha/include/asm/mman.h
+++ b/arch/alpha/include/asm/mman.h
@@ -63,4 +63,15 @@
/* compatibility flags */
#define MAP_FILE 0
+/*
+ * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size.
+ * This gives us 6 bits, which is enough until someone invents 128 bit address
+ * spaces.
+ *
+ * Assume these are all power of twos.
+ * When 0 use the default page size.
+ */
+#define MAP_HUGE_SHIFT 26
+#define MAP_HUGE_MASK 0x3f
+
#endif /* __ALPHA_MMAN_H__ */
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 1e6956a9060..14db93e4c8a 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -445,7 +445,7 @@ struct procfs_args {
* unhappy with OSF UFS. [CHECKME]
*/
static int
-osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
+osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags)
{
int retval;
struct cdfs_args tmp;
@@ -465,7 +465,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
}
static int
-osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
+osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags)
{
int retval;
struct cdfs_args tmp;
@@ -485,7 +485,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
}
static int
-osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags)
+osf_procfs_mount(const char *dirname, struct procfs_args __user *args, int flags)
{
struct procfs_args tmp;
diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c
index 5d5865204a1..59b7bbad839 100644
--- a/arch/alpha/kernel/srmcons.c
+++ b/arch/alpha/kernel/srmcons.c
@@ -205,7 +205,6 @@ static const struct tty_operations srmcons_ops = {
static int __init
srmcons_init(void)
{
- tty_port_init(&srmcons_singleton.port);
setup_timer(&srmcons_singleton.timer, srmcons_receive_chars,
(unsigned long)&srmcons_singleton);
if (srm_is_registered_console) {
@@ -215,6 +214,9 @@ srmcons_init(void)
driver = alloc_tty_driver(MAX_SRM_CONSOLE_DEVICES);
if (!driver)
return -ENOMEM;
+
+ tty_port_init(&srmcons_singleton.port);
+
driver->driver_name = "srm";
driver->name = "srm";
driver->major = 0; /* dynamic */
@@ -227,6 +229,7 @@ srmcons_init(void)
err = tty_register_driver(driver);
if (err) {
put_tty_driver(driver);
+ tty_port_destroy(&srmcons_singleton.port);
return err;
}
srmcons_driver = driver;
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ade7e924bef..8a027f9e339 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -330,6 +330,8 @@ config ARCH_AT91
select IRQ_DOMAIN
select NEED_MACH_GPIO_H
select NEED_MACH_IO_H if PCCARD
+ select PINCTRL
+ select PINCTRL_AT91 if USE_OF
help
This enables support for systems based on Atmel
AT91RM9200 and AT91SAM9* processors.
@@ -364,6 +366,7 @@ config ARCH_CNS3XXX
config ARCH_CLPS711X
bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
+ select ARCH_REQUIRE_GPIOLIB
select ARCH_USES_GETTIMEOFFSET
select CLKDEV_LOOKUP
select COMMON_CLK
@@ -547,6 +550,7 @@ config ARCH_KIRKWOOD
select CPU_FEROCEON
select GENERIC_CLOCKEVENTS
select PCI
+ select PCI_QUIRKS
select PLAT_ORION_LEGACY
help
Support for the following Marvell Kirkwood series SoCs:
@@ -586,6 +590,7 @@ config ARCH_MMP
select GPIO_PXA
select IRQ_DOMAIN
select NEED_MACH_GPIO_H
+ select PINCTRL
select PLAT_PXA
select SPARSE_IRQ
help
@@ -904,6 +909,7 @@ config ARCH_NOMADIK
config PLAT_SPEAR
bool "ST SPEAr"
+ select ARCH_HAS_CPUFREQ
select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
select CLKDEV_LOOKUP
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 5f914fca911..c35baf102f6 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -292,10 +292,10 @@ zinstall uinstall install: vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
%.dtb: scripts
- $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@
dtbs: scripts
- $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) dtbs
# We use MRPROPER_FILES and CLEAN_FILES now
archclean:
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index f2aa09eb658..abfce280f57 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -15,8 +15,6 @@ ifneq ($(MACHINE),)
include $(srctree)/$(MACHINE)/Makefile.boot
endif
-include $(srctree)/arch/arm/boot/dts/Makefile
-
# Note: the following conditions must always be true:
# ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
# PARAMS_PHYS must be within 4MB of ZRELADDR
@@ -33,7 +31,7 @@ ifeq ($(CONFIG_XIP_KERNEL),y)
$(obj)/xipImage: vmlinux FORCE
$(call if_changed,objcopy)
- $(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))'
+ @$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))'
$(obj)/Image $(obj)/zImage: FORCE
@echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)'
@@ -48,27 +46,17 @@ $(obj)/xipImage: FORCE
$(obj)/Image: vmlinux FORCE
$(call if_changed,objcopy)
- $(kecho) ' Kernel: $@ is ready'
+ @$(kecho) ' Kernel: $@ is ready'
$(obj)/compressed/vmlinux: $(obj)/Image FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
- $(kecho) ' Kernel: $@ is ready'
+ @$(kecho) ' Kernel: $@ is ready'
endif
-targets += $(dtb-y)
-
-# Rule to build device tree blobs
-$(obj)/%.dtb: $(src)/dts/%.dts FORCE
- $(call if_changed_dep,dtc)
-
-$(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y))
-
-clean-files := *.dtb
-
ifneq ($(LOADADDR),)
UIMAGE_LOADADDR=$(LOADADDR)
else
@@ -90,7 +78,7 @@ fi
$(obj)/uImage: $(obj)/zImage FORCE
@$(check_for_multiple_loadaddr)
$(call if_changed,uimage)
- $(kecho) ' Image $@ is ready'
+ @$(kecho) ' Image $@ is ready'
$(obj)/bootp/bootp: $(obj)/zImage initrd FORCE
$(Q)$(MAKE) $(build)=$(obj)/bootp $@
@@ -98,7 +86,7 @@ $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE
$(obj)/bootpImage: $(obj)/bootp/bootp FORCE
$(call if_changed,objcopy)
- $(kecho) ' Kernel: $@ is ready'
+ @$(kecho) ' Kernel: $@ is ready'
PHONY += initrd FORCE
initrd:
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 90275f036cd..49ca86e37b8 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -652,6 +652,15 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size
mov pc, lr
ENDPROC(__setup_mmu)
+@ Enable unaligned access on v6, to allow better code generation
+@ for the decompressor C code:
+__armv6_mmu_cache_on:
+ mrc p15, 0, r0, c1, c0, 0 @ read SCTLR
+ bic r0, r0, #2 @ A (no unaligned access fault)
+ orr r0, r0, #1 << 22 @ U (v6 unaligned access model)
+ mcr p15, 0, r0, c1, c0, 0 @ write SCTLR
+ b __armv4_mmu_cache_on
+
__arm926ejs_mmu_cache_on:
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
mov r0, #4 @ put dcache in WT mode
@@ -694,6 +703,9 @@ __armv7_mmu_cache_on:
bic r0, r0, #1 << 28 @ clear SCTLR.TRE
orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
orr r0, r0, #0x003c @ write buffer
+ bic r0, r0, #2 @ A (no unaligned access fault)
+ orr r0, r0, #1 << 22 @ U (v6 unaligned access model)
+ @ (needed for ARM1176)
#ifdef CONFIG_MMU
#ifdef CONFIG_CPU_ENDIAN_BE8
orr r0, r0, #1 << 25 @ big-endian page tables
@@ -914,7 +926,7 @@ proc_types:
.word 0x0007b000 @ ARMv6
.word 0x000ff000
- W(b) __armv4_mmu_cache_on
+ W(b) __armv6_mmu_cache_on
W(b) __armv4_mmu_cache_off
W(b) __armv6_mmu_cache_flush
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index f37cf9fa5fa..26249375223 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1,21 +1,37 @@
ifeq ($(CONFIG_OF),y)
-dtb-$(CONFIG_ARCH_AT91) += aks-cdu.dtb \
- at91sam9263ek.dtb \
- at91sam9g20ek_2mmc.dtb \
- at91sam9g20ek.dtb \
- at91sam9g25ek.dtb \
- at91sam9m10g45ek.dtb \
- at91sam9n12ek.dtb \
- ethernut5.dtb \
- evk-pro3.dtb \
- kizbox.dtb \
- tny_a9260.dtb \
- tny_a9263.dtb \
- tny_a9g20.dtb \
- usb_a9260.dtb \
- usb_a9263.dtb \
- usb_a9g20.dtb
+# Keep at91 dtb files sorted alphabetically for each SoC
+# rm9200
+dtb-$(CONFIG_ARCH_AT91) += at91rm9200ek.dtb
+# sam9260
+dtb-$(CONFIG_ARCH_AT91) += animeo_ip.dtb
+dtb-$(CONFIG_ARCH_AT91) += aks-cdu.dtb
+dtb-$(CONFIG_ARCH_AT91) += ethernut5.dtb
+dtb-$(CONFIG_ARCH_AT91) += evk-pro3.dtb
+dtb-$(CONFIG_ARCH_AT91) += tny_a9260.dtb
+dtb-$(CONFIG_ARCH_AT91) += usb_a9260.dtb
+# sam9263
+dtb-$(CONFIG_ARCH_AT91) += at91sam9263ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += tny_a9263.dtb
+dtb-$(CONFIG_ARCH_AT91) += usb_a9263.dtb
+# sam9g20
+dtb-$(CONFIG_ARCH_AT91) += at91sam9g20ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += at91sam9g20ek_2mmc.dtb
+dtb-$(CONFIG_ARCH_AT91) += kizbox.dtb
+dtb-$(CONFIG_ARCH_AT91) += tny_a9g20.dtb
+dtb-$(CONFIG_ARCH_AT91) += usb_a9g20.dtb
+# sam9g45
+dtb-$(CONFIG_ARCH_AT91) += at91sam9m10g45ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += pm9g45.dtb
+# sam9n12
+dtb-$(CONFIG_ARCH_AT91) += at91sam9n12ek.dtb
+# sam9x5
+dtb-$(CONFIG_ARCH_AT91) += at91sam9g15ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += at91sam9g25ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += at91sam9g35ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += at91sam9x25ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += at91sam9x35ek.dtb
+
dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \
dove-cubox.dtb \
@@ -104,4 +120,12 @@ dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \
wm8505-ref.dtb \
wm8650-mid.dtb
+targets += dtbs
endif
+
+# *.dtb used to be generated in the directory above. Clean out the
+# old build results so people don't accidentally use them.
+dtbs: $(addprefix $(obj)/, $(dtb-y))
+ $(Q)rm -f $(obj)/../*.dtb
+
+clean-files := *.dtb
diff --git a/arch/arm/boot/dts/animeo_ip.dts b/arch/arm/boot/dts/animeo_ip.dts
new file mode 100644
index 00000000000..74d92cd29d8
--- /dev/null
+++ b/arch/arm/boot/dts/animeo_ip.dts
@@ -0,0 +1,178 @@
+/*
+ * animeo_ip.dts - Device Tree file for Somfy Animeo IP Boards
+ *
+ * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 only.
+ */
+
+/dts-v1/;
+/include/ "at91sam9260.dtsi"
+
+/ {
+ model = "Somfy Animeo IP";
+ compatible = "somfy,animeo-ip", "atmel,at91sam9260", "atmel,at91sam9";
+
+ aliases {
+ serial0 = &usart1;
+ serial1 = &usart2;
+ serial2 = &usart0;
+ serial3 = &dbgu;
+ serial4 = &usart3;
+ serial5 = &uart0;
+ serial6 = &uart1;
+ };
+
+ chosen {
+ linux,stdout-path = &usart2;
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <18432000>;
+ };
+ };
+
+ ahb {
+ apb {
+ usart0: serial@fffb0000 {
+ pinctrl-0 = <&pinctrl_usart0 &pinctrl_usart0_rts>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+ };
+
+ usart1: serial@fffb4000 {
+ pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+ };
+
+ usart2: serial@fffb8000 {
+ pinctrl-0 = <&pinctrl_usart2>;
+ status = "okay";
+ };
+
+ macb0: ethernet@fffc4000 {
+ pinctrl-0 = <&pinctrl_macb_rmii &pinctrl_macb_rmii_mii>;
+ phy-mode = "mii";
+ status = "okay";
+ };
+
+ mmc0: mmc@fffa8000 {
+ pinctrl-0 = <&pinctrl_mmc0_clk
+ &pinctrl_mmc0_slot1_cmd_dat0
+ &pinctrl_mmc0_slot1_dat1_3>;
+ status = "okay";
+
+ slot@1 {
+ reg = <1>;
+ bus-width = <4>;
+ };
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x8000>;
+ };
+
+ barebox@8000 {
+ label = "barebox";
+ reg = <0x8000 0x40000>;
+ };
+
+ bareboxenv@48000 {
+ label = "bareboxenv";
+ reg = <0x48000 0x8000>;
+ };
+
+ user_block@0x50000 {
+ label = "user_block";
+ reg = <0x50000 0xb0000>;
+ };
+
+ kernel@100000 {
+ label = "kernel";
+ reg = <0x100000 0x1b0000>;
+ };
+
+ root@2b0000 {
+ label = "root";
+ reg = <0x2b0000 0x1D50000>;
+ };
+ };
+
+ usb0: ohci@00500000 {
+ num-ports = <2>;
+ atmel,vbus-gpio = <&pioB 15 1>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ power_green {
+ label = "power_green";
+ gpios = <&pioC 17 0>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ power_red {
+ label = "power_red";
+ gpios = <&pioA 2 0>;
+ };
+
+ tx_green {
+ label = "tx_green";
+ gpios = <&pioC 19 0>;
+ };
+
+ tx_red {
+ label = "tx_red";
+ gpios = <&pioC 18 0>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ keyswitch_in {
+ label = "keyswitch_in";
+ gpios = <&pioB 1 0>;
+ linux,code = <28>;
+ gpio-key,wakeup;
+ };
+
+ error_in {
+ label = "error_in";
+ gpios = <&pioB 2 0>;
+ linux,code = <29>;
+ gpio-key,wakeup;
+ };
+
+ btn {
+ label = "btn";
+ gpios = <&pioC 23 0>;
+ linux,code = <31>;
+ gpio-key,wakeup;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi
new file mode 100644
index 00000000000..e154f242c68
--- /dev/null
+++ b/arch/arm/boot/dts/at91rm9200.dtsi
@@ -0,0 +1,349 @@
+/*
+ * at91rm9200.dtsi - Device Tree Include file for AT91RM9200 family SoC
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>,
+ * 2012 Joachim Eastwood <manabian@gmail.com>
+ *
+ * Based on at91sam9260.dtsi
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Atmel AT91RM9200 family SoC";
+ compatible = "atmel,at91rm9200";
+ interrupt-parent = <&aic>;
+
+ aliases {
+ serial0 = &dbgu;
+ serial1 = &usart0;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ serial4 = &usart3;
+ gpio0 = &pioA;
+ gpio1 = &pioB;
+ gpio2 = &pioC;
+ gpio3 = &pioD;
+ tcb0 = &tcb0;
+ tcb1 = &tcb1;
+ };
+ cpus {
+ cpu@0 {
+ compatible = "arm,arm920t";
+ };
+ };
+
+ memory {
+ reg = <0x20000000 0x04000000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ aic: interrupt-controller@fffff000 {
+ #interrupt-cells = <3>;
+ compatible = "atmel,at91rm9200-aic";
+ interrupt-controller;
+ reg = <0xfffff000 0x200>;
+ atmel,external-irqs = <25 26 27 28 29 30 31>;
+ };
+
+ ramc0: ramc@ffffff00 {
+ compatible = "atmel,at91rm9200-sdramc";
+ reg = <0xffffff00 0x100>;
+ };
+
+ pmc: pmc@fffffc00 {
+ compatible = "atmel,at91rm9200-pmc";
+ reg = <0xfffffc00 0x100>;
+ };
+
+ st: timer@fffffd00 {
+ compatible = "atmel,at91rm9200-st";
+ reg = <0xfffffd00 0x100>;
+ interrupts = <1 4 7>;
+ };
+
+ tcb0: timer@fffa0000 {
+ compatible = "atmel,at91rm9200-tcb";
+ reg = <0xfffa0000 0x100>;
+ interrupts = <17 4 0 18 4 0 19 4 0>;
+ };
+
+ tcb1: timer@fffa4000 {
+ compatible = "atmel,at91rm9200-tcb";
+ reg = <0xfffa4000 0x100>;
+ interrupts = <20 4 0 21 4 0 22 4 0>;
+ };
+
+ pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff400 0xfffff400 0x800>;
+
+ atmel,mux-mask = <
+ /* A B */
+ 0xffffffff 0xffffffff /* pioA */
+ 0xffffffff 0x083fffff /* pioB */
+ 0xffff3fff 0x00000000 /* pioC */
+ 0x03ff87ff 0x0fffff80 /* pioD */
+ >;
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <0 30 0x1 0x0 /* PA30 periph A */
+ 0 31 0x1 0x1>; /* PA31 periph with pullup */
+ };
+ };
+
+ uart0 {
+ pinctrl_uart0: uart0-0 {
+ atmel,pins =
+ <0 17 0x1 0x0 /* PA17 periph A */
+ 0 18 0x1 0x0>; /* PA18 periph A */
+ };
+
+ pinctrl_uart0_rts: uart0_rts-0 {
+ atmel,pins =
+ <0 20 0x1 0x0>; /* PA20 periph A */
+ };
+
+ pinctrl_uart0_cts: uart0_cts-0 {
+ atmel,pins =
+ <0 21 0x1 0x0>; /* PA21 periph A */
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1: uart1-0 {
+ atmel,pins =
+ <1 20 0x1 0x1 /* PB20 periph A with pullup */
+ 1 21 0x1 0x0>; /* PB21 periph A */
+ };
+
+ pinctrl_uart1_rts: uart1_rts-0 {
+ atmel,pins =
+ <1 24 0x1 0x0>; /* PB24 periph A */
+ };
+
+ pinctrl_uart1_cts: uart1_cts-0 {
+ atmel,pins =
+ <1 26 0x1 0x0>; /* PB26 periph A */
+ };
+
+ pinctrl_uart1_dtr_dsr: uart1_dtr_dsr-0 {
+ atmel,pins =
+ <1 19 0x1 0x0 /* PB19 periph A */
+ 1 25 0x1 0x0>; /* PB25 periph A */
+ };
+
+ pinctrl_uart1_dcd: uart1_dcd-0 {
+ atmel,pins =
+ <1 23 0x1 0x0>; /* PB23 periph A */
+ };
+
+ pinctrl_uart1_ri: uart1_ri-0 {
+ atmel,pins =
+ <1 18 0x1 0x0>; /* PB18 periph A */
+ };
+ };
+
+ uart2 {
+ pinctrl_uart2: uart2-0 {
+ atmel,pins =
+ <0 22 0x1 0x0 /* PA22 periph A */
+ 0 23 0x1 0x1>; /* PA23 periph A with pullup */
+ };
+
+ pinctrl_uart2_rts: uart2_rts-0 {
+ atmel,pins =
+ <0 30 0x2 0x0>; /* PA30 periph B */
+ };
+
+ pinctrl_uart2_cts: uart2_cts-0 {
+ atmel,pins =
+ <0 31 0x2 0x0>; /* PA31 periph B */
+ };
+ };
+
+ uart3 {
+ pinctrl_uart3: uart3-0 {
+ atmel,pins =
+ <0 5 0x2 0x1 /* PA5 periph B with pullup */
+ 0 6 0x2 0x0>; /* PA6 periph B */
+ };
+
+ pinctrl_uart3_rts: uart3_rts-0 {
+ atmel,pins =
+ <1 0 0x2 0x0>; /* PB0 periph B */
+ };
+
+ pinctrl_uart3_cts: uart3_cts-0 {
+ atmel,pins =
+ <1 1 0x2 0x0>; /* PB1 periph B */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <2 2 0x0 0x1 /* PC2 gpio RDY pin pull_up */
+ 1 1 0x0 0x1>; /* PB1 gpio CD pin pull_up */
+ };
+ };
+
+ pioA: gpio@fffff400 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioB: gpio@fffff600 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioC: gpio@fffff800 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <4 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioD: gpio@fffffa00 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <5 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ dbgu: serial@fffff200 {
+ compatible = "atmel,at91rm9200-usart";
+ reg = <0xfffff200 0x200>;
+ interrupts = <1 4 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
+ status = "disabled";
+ };
+
+ usart0: serial@fffc0000 {
+ compatible = "atmel,at91rm9200-usart";
+ reg = <0xfffc0000 0x200>;
+ interrupts = <6 4 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ status = "disabled";
+ };
+
+ usart1: serial@fffc4000 {
+ compatible = "atmel,at91rm9200-usart";
+ reg = <0xfffc4000 0x200>;
+ interrupts = <7 4 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "disabled";
+ };
+
+ usart2: serial@fffc8000 {
+ compatible = "atmel,at91rm9200-usart";
+ reg = <0xfffc8000 0x200>;
+ interrupts = <8 4 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "disabled";
+ };
+
+ usart3: serial@fffcc000 {
+ compatible = "atmel,at91rm9200-usart";
+ reg = <0xfffcc000 0x200>;
+ interrupts = <23 4 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "disabled";
+ };
+
+ usb1: gadget@fffb0000 {
+ compatible = "atmel,at91rm9200-udc";
+ reg = <0xfffb0000 0x4000>;
+ interrupts = <11 4 2>;
+ status = "disabled";
+ };
+ };
+
+ nand0: nand@40000000 {
+ compatible = "atmel,at91rm9200-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x40000000 0x10000000>;
+ atmel,nand-addr-offset = <21>;
+ atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+ nand-ecc-mode = "soft";
+ gpios = <&pioC 2 0
+ 0
+ &pioB 1 0
+ >;
+ status = "disabled";
+ };
+
+ usb0: ohci@00300000 {
+ compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+ reg = <0x00300000 0x100000>;
+ interrupts = <23 4 2>;
+ status = "disabled";
+ };
+ };
+
+ i2c@0 {
+ compatible = "i2c-gpio";
+ gpios = <&pioA 23 0 /* sda */
+ &pioA 24 0 /* scl */
+ >;
+ i2c-gpio,sda-open-drain;
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/at91rm9200ek.dts b/arch/arm/boot/dts/at91rm9200ek.dts
new file mode 100644
index 00000000000..8aa48931e0a
--- /dev/null
+++ b/arch/arm/boot/dts/at91rm9200ek.dts
@@ -0,0 +1,79 @@
+/*
+ * at91rm9200ek.dts - Device Tree file for Atmel AT91RM9200 evaluation kit
+ *
+ * Copyright (C) 2012 Joachim Eastwood <manabian@gmail.com>
+ *
+ * Licensed under GPLv2 only
+ */
+/dts-v1/;
+/include/ "at91rm9200.dtsi"
+
+/ {
+ model = "Atmel AT91RM9200 evaluation kit";
+ compatible = "atmel,at91rm9200ek", "atmel,at91rm9200";
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <18432000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ usart1: serial@fffc4000 {
+ pinctrl-0 =
+ <&pinctrl_uart1
+ &pinctrl_uart1_rts
+ &pinctrl_uart1_cts
+ &pinctrl_uart1_dtr_dsr
+ &pinctrl_uart1_dcd
+ &pinctrl_uart1_ri>;
+ status = "okay";
+ };
+
+ usb1: gadget@fffb0000 {
+ atmel,vbus-gpio = <&pioD 4 0>;
+ status = "okay";
+ };
+ };
+
+ usb0: ohci@00300000 {
+ num-ports = <2>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ ds2 {
+ label = "green";
+ gpios = <&pioB 0 0x1>;
+ linux,default-trigger = "mmc0";
+ };
+
+ ds4 {
+ label = "yellow";
+ gpios = <&pioB 1 0x1>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ ds6 {
+ label = "red";
+ gpios = <&pioB 2 0x1>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index d410581a5a8..b1d3fab60e0 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -21,8 +21,8 @@
serial2 = &usart1;
serial3 = &usart2;
serial4 = &usart3;
- serial5 = &usart4;
- serial6 = &usart5;
+ serial5 = &uart0;
+ serial6 = &uart1;
gpio0 = &pioA;
gpio1 = &pioB;
gpio2 = &pioC;
@@ -98,40 +98,250 @@
interrupts = <26 4 0 27 4 0 28 4 0>;
};
- pioA: gpio@fffff400 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff400 0x100>;
- interrupts = <2 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff400 0xfffff400 0x600>;
+
+ atmel,mux-mask = <
+ /* A B */
+ 0xffffffff 0xffc00c3b /* pioA */
+ 0xffffffff 0x7fff3ccf /* pioB */
+ 0xffffffff 0x007fffff /* pioC */
+ >;
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <1 14 0x1 0x0 /* PB14 periph A */
+ 1 15 0x1 0x1>; /* PB15 periph with pullup */
+ };
+ };
- pioB: gpio@fffff600 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff600 0x100>;
- interrupts = <3 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <1 4 0x1 0x0 /* PB4 periph A */
+ 1 5 0x1 0x0>; /* PB5 periph A */
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <1 26 0x1 0x0>; /* PB26 periph A */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <1 27 0x1 0x0>; /* PB27 periph A */
+ };
+
+ pinctrl_usart0_dtr_dsr: usart0_dtr_dsr-0 {
+ atmel,pins =
+ <1 24 0x1 0x0 /* PB24 periph A */
+ 1 22 0x1 0x0>; /* PB22 periph A */
+ };
+
+ pinctrl_usart0_dcd: usart0_dcd-0 {
+ atmel,pins =
+ <1 23 0x1 0x0>; /* PB23 periph A */
+ };
+
+ pinctrl_usart0_ri: usart0_ri-0 {
+ atmel,pins =
+ <1 25 0x1 0x0>; /* PB25 periph A */
+ };
+ };
- pioC: gpio@fffff800 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff800 0x100>;
- interrupts = <4 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <2 6 0x1 0x1 /* PB6 periph A with pullup */
+ 2 7 0x1 0x0>; /* PB7 periph A */
+ };
+
+ pinctrl_usart1_rts: usart1_rts-0 {
+ atmel,pins =
+ <1 28 0x1 0x0>; /* PB28 periph A */
+ };
+
+ pinctrl_usart1_cts: usart1_cts-0 {
+ atmel,pins =
+ <1 29 0x1 0x0>; /* PB29 periph A */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <1 8 0x1 0x1 /* PB8 periph A with pullup */
+ 1 9 0x1 0x0>; /* PB9 periph A */
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <0 4 0x1 0x0>; /* PA4 periph A */
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <0 5 0x1 0x0>; /* PA5 periph A */
+ };
+ };
+
+ usart3 {
+ pinctrl_usart3: usart3-0 {
+ atmel,pins =
+ <2 10 0x1 0x1 /* PB10 periph A with pullup */
+ 2 11 0x1 0x0>; /* PB11 periph A */
+ };
+
+ pinctrl_usart3_rts: usart3_rts-0 {
+ atmel,pins =
+ <3 8 0x2 0x0>; /* PB8 periph B */
+ };
+
+ pinctrl_usart3_cts: usart3_cts-0 {
+ atmel,pins =
+ <3 10 0x2 0x0>; /* PB10 periph B */
+ };
+ };
+
+ uart0 {
+ pinctrl_uart0: uart0-0 {
+ atmel,pins =
+ <0 31 0x2 0x1 /* PA31 periph B with pullup */
+ 0 30 0x2 0x0>; /* PA30 periph B */
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1: uart1-0 {
+ atmel,pins =
+ <2 12 0x1 0x1 /* PB12 periph A with pullup */
+ 2 13 0x1 0x0>; /* PB13 periph A */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <2 13 0x0 0x1 /* PC13 gpio RDY pin pull_up */
+ 2 14 0x0 0x1>; /* PC14 gpio enable pin pull_up */
+ };
+ };
+
+ macb {
+ pinctrl_macb_rmii: macb_rmii-0 {
+ atmel,pins =
+ <0 12 0x1 0x0 /* PA12 periph A */
+ 0 13 0x1 0x0 /* PA13 periph A */
+ 0 14 0x1 0x0 /* PA14 periph A */
+ 0 15 0x1 0x0 /* PA15 periph A */
+ 0 16 0x1 0x0 /* PA16 periph A */
+ 0 17 0x1 0x0 /* PA17 periph A */
+ 0 18 0x1 0x0 /* PA18 periph A */
+ 0 19 0x1 0x0 /* PA19 periph A */
+ 0 20 0x1 0x0 /* PA20 periph A */
+ 0 21 0x1 0x0>; /* PA21 periph A */
+ };
+
+ pinctrl_macb_rmii_mii: macb_rmii_mii-0 {
+ atmel,pins =
+ <0 22 0x2 0x0 /* PA22 periph B */
+ 0 23 0x2 0x0 /* PA23 periph B */
+ 0 24 0x2 0x0 /* PA24 periph B */
+ 0 25 0x2 0x0 /* PA25 periph B */
+ 0 26 0x2 0x0 /* PA26 periph B */
+ 0 27 0x2 0x0 /* PA27 periph B */
+ 0 28 0x2 0x0 /* PA28 periph B */
+ 0 29 0x2 0x0>; /* PA29 periph B */
+ };
+
+ pinctrl_macb_rmii_mii_alt: macb_rmii_mii-1 {
+ atmel,pins =
+ <0 10 0x2 0x0 /* PA10 periph B */
+ 0 11 0x2 0x0 /* PA11 periph B */
+ 0 24 0x2 0x0 /* PA24 periph B */
+ 0 25 0x2 0x0 /* PA25 periph B */
+ 0 26 0x2 0x0 /* PA26 periph B */
+ 0 27 0x2 0x0 /* PA27 periph B */
+ 0 28 0x2 0x0 /* PA28 periph B */
+ 0 29 0x2 0x0>; /* PA29 periph B */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_clk: mmc0_clk-0 {
+ atmel,pins =
+ <0 8 0x1 0x0>; /* PA8 periph A */
+ };
+
+ pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
+ atmel,pins =
+ <0 7 0x1 0x1 /* PA7 periph A with pullup */
+ 0 6 0x1 0x1>; /* PA6 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 9 0x1 0x1 /* PA9 periph A with pullup */
+ 0 10 0x1 0x1 /* PA10 periph A with pullup */
+ 0 11 0x1 0x1>; /* PA11 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot1_cmd_dat0: mmc0_slot1_cmd_dat0-0 {
+ atmel,pins =
+ <0 1 0x2 0x1 /* PA1 periph B with pullup */
+ 0 0 0x2 0x1>; /* PA0 periph B with pullup */
+ };
+
+ pinctrl_mmc0_slot1_dat1_3: mmc0_slot1_dat1_3-0 {
+ atmel,pins =
+ <0 5 0x2 0x1 /* PA5 periph B with pullup */
+ 0 4 0x2 0x1 /* PA4 periph B with pullup */
+ 0 3 0x2 0x1>; /* PA3 periph B with pullup */
+ };
+ };
+
+ pioA: gpio@fffff400 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioB: gpio@fffff600 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioC: gpio@fffff800 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <4 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
dbgu: serial@fffff200 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffff200 0x200>;
interrupts = <1 4 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
status = "disabled";
};
@@ -141,6 +351,8 @@
interrupts = <6 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
status = "disabled";
};
@@ -150,6 +362,8 @@
interrupts = <7 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
status = "disabled";
};
@@ -159,6 +373,8 @@
interrupts = <8 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
status = "disabled";
};
@@ -168,24 +384,30 @@
interrupts = <23 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart3>;
status = "disabled";
};
- usart4: serial@fffd4000 {
+ uart0: serial@fffd4000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffd4000 0x200>;
interrupts = <24 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
status = "disabled";
};
- usart5: serial@fffd8000 {
+ uart1: serial@fffd8000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffd8000 0x200>;
interrupts = <25 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
status = "disabled";
};
@@ -193,6 +415,8 @@
compatible = "cdns,at32ap7000-macb", "cdns,macb";
reg = <0xfffc4000 0x100>;
interrupts = <21 4 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb_rmii>;
status = "disabled";
};
@@ -212,6 +436,15 @@
status = "disabled";
};
+ mmc0: mmc@fffa8000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfffa8000 0x600>;
+ interrupts = <9 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
adc0: adc@fffe0000 {
compatible = "atmel,at91sam9260-adc";
reg = <0xfffe0000 0x100>;
@@ -257,6 +490,8 @@
>;
atmel,nand-addr-offset = <21>;
atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
gpios = <&pioC 13 0
&pioC 14 0
0
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index 3e6e5c1abbf..66106eecf1e 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -89,60 +89,243 @@
reg = <0xfffffd10 0x10>;
};
- pioA: gpio@fffff200 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff200 0x100>;
- interrupts = <2 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ pinctrl@fffff200 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff200 0xfffff200 0xa00>;
- pioB: gpio@fffff400 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff400 0x100>;
- interrupts = <3 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ atmel,mux-mask = <
+ /* A B */
+ 0xfffffffb 0xffffe07f /* pioA */
+ 0x0007ffff 0x39072fff /* pioB */
+ 0xffffffff 0x3ffffff8 /* pioC */
+ 0xfffffbff 0xffffffff /* pioD */
+ 0xffe00fff 0xfbfcff00 /* pioE */
+ >;
- pioC: gpio@fffff600 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff600 0x100>;
- interrupts = <4 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <2 30 0x1 0x0 /* PC30 periph A */
+ 2 31 0x1 0x1>; /* PC31 periph with pullup */
+ };
+ };
- pioD: gpio@fffff800 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff800 0x100>;
- interrupts = <4 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <0 26 0x1 0x1 /* PA26 periph A with pullup */
+ 0 27 0x1 0x0>; /* PA27 periph A */
+ };
- pioE: gpio@fffffa00 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffffa00 0x100>;
- interrupts = <4 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <0 28 0x1 0x0>; /* PA28 periph A */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <0 29 0x1 0x0>; /* PA29 periph A */
+ };
+ };
+
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <3 0 0x1 0x1 /* PD0 periph A with pullup */
+ 3 1 0x1 0x0>; /* PD1 periph A */
+ };
+
+ pinctrl_usart1_rts: usart1_rts-0 {
+ atmel,pins =
+ <3 7 0x2 0x0>; /* PD7 periph B */
+ };
+
+ pinctrl_usart1_cts: usart1_cts-0 {
+ atmel,pins =
+ <3 8 0x2 0x0>; /* PD8 periph B */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <3 2 0x1 0x1 /* PD2 periph A with pullup */
+ 3 3 0x1 0x0>; /* PD3 periph A */
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <3 5 0x2 0x0>; /* PD5 periph B */
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <4 6 0x2 0x0>; /* PD6 periph B */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <0 22 0x0 0x1 /* PA22 gpio RDY pin pull_up*/
+ 3 15 0x0 0x1>; /* PD15 gpio enable pin pull_up */
+ };
+ };
+
+ macb {
+ pinctrl_macb_rmii: macb_rmii-0 {
+ atmel,pins =
+ <2 25 0x2 0x0 /* PC25 periph B */
+ 4 21 0x1 0x0 /* PE21 periph A */
+ 4 23 0x1 0x0 /* PE23 periph A */
+ 4 24 0x1 0x0 /* PE24 periph A */
+ 4 25 0x1 0x0 /* PE25 periph A */
+ 4 26 0x1 0x0 /* PE26 periph A */
+ 4 27 0x1 0x0 /* PE27 periph A */
+ 4 28 0x1 0x0 /* PE28 periph A */
+ 4 29 0x1 0x0 /* PE29 periph A */
+ 4 30 0x1 0x0>; /* PE30 periph A */
+ };
+
+ pinctrl_macb_rmii_mii: macb_rmii_mii-0 {
+ atmel,pins =
+ <2 20 0x2 0x0 /* PC20 periph B */
+ 2 21 0x2 0x0 /* PC21 periph B */
+ 2 22 0x2 0x0 /* PC22 periph B */
+ 2 23 0x2 0x0 /* PC23 periph B */
+ 2 24 0x2 0x0 /* PC24 periph B */
+ 2 25 0x2 0x0 /* PC25 periph B */
+ 2 27 0x2 0x0 /* PC27 periph B */
+ 4 22 0x2 0x0>; /* PE22 periph B */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_clk: mmc0_clk-0 {
+ atmel,pins =
+ <0 12 0x1 0x0>; /* PA12 periph A */
+ };
+
+ pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
+ atmel,pins =
+ <0 1 0x1 0x1 /* PA1 periph A with pullup */
+ 0 0 0x1 0x1>; /* PA0 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 3 0x1 0x1 /* PA3 periph A with pullup */
+ 0 4 0x1 0x1 /* PA4 periph A with pullup */
+ 0 5 0x1 0x1>; /* PA5 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot1_cmd_dat0: mmc0_slot1_cmd_dat0-0 {
+ atmel,pins =
+ <0 16 0x1 0x1 /* PA16 periph A with pullup */
+ 0 17 0x1 0x1>; /* PA17 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot1_dat1_3: mmc0_slot1_dat1_3-0 {
+ atmel,pins =
+ <0 18 0x1 0x1 /* PA18 periph A with pullup */
+ 0 19 0x1 0x1 /* PA19 periph A with pullup */
+ 0 20 0x1 0x1>; /* PA20 periph A with pullup */
+ };
+ };
+
+ mmc1 {
+ pinctrl_mmc1_clk: mmc1_clk-0 {
+ atmel,pins =
+ <0 6 0x1 0x0>; /* PA6 periph A */
+ };
+
+ pinctrl_mmc1_slot0_cmd_dat0: mmc1_slot0_cmd_dat0-0 {
+ atmel,pins =
+ <0 7 0x1 0x1 /* PA7 periph A with pullup */
+ 0 8 0x1 0x1>; /* PA8 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 9 0x1 0x1 /* PA9 periph A with pullup */
+ 0 10 0x1 0x1 /* PA10 periph A with pullup */
+ 0 11 0x1 0x1>; /* PA11 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot1_cmd_dat0: mmc1_slot1_cmd_dat0-0 {
+ atmel,pins =
+ <0 21 0x1 0x1 /* PA21 periph A with pullup */
+ 0 22 0x1 0x1>; /* PA22 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot1_dat1_3: mmc1_slot1_dat1_3-0 {
+ atmel,pins =
+ <0 23 0x1 0x1 /* PA23 periph A with pullup */
+ 0 24 0x1 0x1 /* PA24 periph A with pullup */
+ 0 25 0x1 0x1>; /* PA25 periph A with pullup */
+ };
+ };
+
+ pioA: gpio@fffff200 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff200 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioB: gpio@fffff400 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioC: gpio@fffff600 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <4 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioD: gpio@fffff800 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <4 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioE: gpio@fffffa00 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <4 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
dbgu: serial@ffffee00 {
compatible = "atmel,at91sam9260-usart";
reg = <0xffffee00 0x200>;
interrupts = <1 4 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
status = "disabled";
};
@@ -152,6 +335,8 @@
interrupts = <7 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
status = "disabled";
};
@@ -161,6 +346,8 @@
interrupts = <8 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
status = "disabled";
};
@@ -170,6 +357,8 @@
interrupts = <9 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
status = "disabled";
};
@@ -177,6 +366,8 @@
compatible = "cdns,at32ap7000-macb", "cdns,macb";
reg = <0xfffbc000 0x100>;
interrupts = <21 4 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb_rmii>;
status = "disabled";
};
@@ -195,6 +386,24 @@
#size-cells = <0>;
status = "disabled";
};
+
+ mmc0: mmc@fff80000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfff80000 0x600>;
+ interrupts = <10 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@fff84000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfff84000 0x600>;
+ interrupts = <11 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
nand0: nand@40000000 {
@@ -206,6 +415,8 @@
>;
atmel,nand-addr-offset = <21>;
atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
gpios = <&pioA 22 0
&pioD 15 0
0
diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts
index f86ac4b609f..1eb08728f52 100644
--- a/arch/arm/boot/dts/at91sam9263ek.dts
+++ b/arch/arm/boot/dts/at91sam9263ek.dts
@@ -38,6 +38,10 @@
};
usart0: serial@fff8c000 {
+ pinctrl-0 = <
+ &pinctrl_usart0
+ &pinctrl_usart0_rts
+ &pinctrl_usart0_cts>;
status = "okay";
};
@@ -50,6 +54,31 @@
atmel,vbus-gpio = <&pioA 25 0>;
status = "okay";
};
+
+ mmc0: mmc@fff80000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_clk
+ &pinctrl_mmc0_slot0_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioE 18 0>;
+ wp-gpios = <&pioE 19 0>;
+ };
+ };
+
+ pinctrl@fffff200 {
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <5 18 0x0 0x5 /* PE18 gpio CD pin pull up and deglitch */
+ 5 19 0x0 0x1>; /* PE19 gpio WP pin pull up */
+ };
+ };
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9g15.dtsi b/arch/arm/boot/dts/at91sam9g15.dtsi
new file mode 100644
index 00000000000..fbe7a7089c2
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g15.dtsi
@@ -0,0 +1,28 @@
+/*
+ * at91sam9g15.dtsi - Device Tree Include file for AT91SAM9G15 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+/include/ "at91sam9x5.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G15 SoC";
+ compatible = "atmel, at91sam9g15, atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe0399f 0x00000000 /* pioA */
+ 0x00040000 0x00047e3f 0x00000000 /* pioB */
+ 0xfdffffff 0x00000000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g15ek.dts b/arch/arm/boot/dts/at91sam9g15ek.dts
new file mode 100644
index 00000000000..86dd3f6d938
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g15ek.dts
@@ -0,0 +1,16 @@
+/*
+ * at91sam9g15ek.dts - Device Tree file for AT91SAM9G15-EK board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+/include/ "at91sam9g15.dtsi"
+/include/ "at91sam9x5ek.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G25-EK";
+ compatible = "atmel,at91sam9g15ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+};
diff --git a/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts b/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts
index f1b2e148ac8..66467b11312 100644
--- a/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts
+++ b/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts
@@ -12,6 +12,32 @@
model = "Atmel at91sam9g20ek 2 mmc";
compatible = "atmel,at91sam9g20ek_2mmc", "atmel,at91sam9g20", "atmel,at91sam9";
+ ahb {
+ apb{
+ mmc0: mmc@fffa8000 {
+ /* clk already mux wuth slot0 */
+ pinctrl-0 = <
+ &pinctrl_board_mmc0_slot0
+ &pinctrl_mmc0_slot0_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioC 2 0>;
+ };
+ };
+
+ pinctrl@fffff400 {
+ mmc0_slot0 {
+ pinctrl_board_mmc0_slot0: mmc0_slot0-board {
+ atmel,pins =
+ <2 2 0x0 0x5>; /* PC2 gpio CD pin pull up and deglitch */
+ };
+ };
+ };
+ };
+ };
+
leds {
compatible = "gpio-leds";
diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
index e6391a4e664..32a500a0e48 100644
--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
@@ -35,6 +35,13 @@
};
usart0: serial@fffb0000 {
+ pinctrl-0 =
+ <&pinctrl_usart0
+ &pinctrl_usart0_rts
+ &pinctrl_usart0_cts
+ &pinctrl_usart0_dtr_dsr
+ &pinctrl_usart0_dcd
+ &pinctrl_usart0_ri>;
status = "okay";
};
@@ -51,6 +58,29 @@
atmel,vbus-gpio = <&pioC 5 0>;
status = "okay";
};
+
+ mmc0: mmc@fffa8000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0_slot1
+ &pinctrl_mmc0_clk
+ &pinctrl_mmc0_slot1_cmd_dat0
+ &pinctrl_mmc0_slot1_dat1_3>;
+ status = "okay";
+ slot@1 {
+ reg = <1>;
+ bus-width = <4>;
+ cd-gpios = <&pioC 9 0>;
+ };
+ };
+
+ pinctrl@fffff400 {
+ mmc0_slot1 {
+ pinctrl_board_mmc0_slot1: mmc0_slot1-board {
+ atmel,pins =
+ <2 9 0x0 0x5>; /* PC9 gpio CD pin pull up and deglitch */
+ };
+ };
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9g25.dtsi b/arch/arm/boot/dts/at91sam9g25.dtsi
new file mode 100644
index 00000000000..05a718fb83c
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g25.dtsi
@@ -0,0 +1,28 @@
+/*
+ * at91sam9g25.dtsi - Device Tree Include file for AT91SAM9G25 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+/include/ "at91sam9x5.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G25 SoC";
+ compatible = "atmel, at91sam9g25, atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe0399f 0xc000001c /* pioA */
+ 0x0007ffff 0x8000fe3f 0x00000000 /* pioB */
+ 0x80000000 0x07c0ffff 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts
index 877c08f0676..c5ab16fba05 100644
--- a/arch/arm/boot/dts/at91sam9g25ek.dts
+++ b/arch/arm/boot/dts/at91sam9g25ek.dts
@@ -7,55 +7,10 @@
* Licensed under GPLv2 or later.
*/
/dts-v1/;
-/include/ "at91sam9x5.dtsi"
-/include/ "at91sam9x5cm.dtsi"
+/include/ "at91sam9g25.dtsi"
+/include/ "at91sam9x5ek.dtsi"
/ {
model = "Atmel AT91SAM9G25-EK";
compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
-
- chosen {
- bootargs = "console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs";
- };
-
- ahb {
- apb {
- dbgu: serial@fffff200 {
- status = "okay";
- };
-
- usart0: serial@f801c000 {
- status = "okay";
- };
-
- macb0: ethernet@f802c000 {
- phy-mode = "rmii";
- status = "okay";
- };
-
- i2c0: i2c@f8010000 {
- status = "okay";
- };
-
- i2c1: i2c@f8014000 {
- status = "okay";
- };
-
- i2c2: i2c@f8018000 {
- status = "okay";
- };
- };
-
- usb0: ohci@00600000 {
- status = "okay";
- num-ports = <2>;
- atmel,vbus-gpio = <&pioD 19 1
- &pioD 20 1
- >;
- };
-
- usb1: ehci@00700000 {
- status = "okay";
- };
- };
};
diff --git a/arch/arm/boot/dts/at91sam9g35.dtsi b/arch/arm/boot/dts/at91sam9g35.dtsi
new file mode 100644
index 00000000000..f9d14a72279
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g35.dtsi
@@ -0,0 +1,28 @@
+/*
+ * at91sam9g35.dtsi - Device Tree Include file for AT91SAM9G35 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+/include/ "at91sam9x5.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G35 SoC";
+ compatible = "atmel, at91sam9g35, atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe0399f 0xc000000c /* pioA */
+ 0x000406ff 0x00047e3f 0x00000000 /* pioB */
+ 0xfdffffff 0x00000000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g35ek.dts b/arch/arm/boot/dts/at91sam9g35ek.dts
new file mode 100644
index 00000000000..95944bdd798
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g35ek.dts
@@ -0,0 +1,16 @@
+/*
+ * at91sam9g35ek.dts - Device Tree file for AT91SAM9G35-EK board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+/include/ "at91sam9g35.dtsi"
+/include/ "at91sam9x5ek.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G35-EK";
+ compatible = "atmel,at91sam9g35ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+};
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index 3add030d61f..0741caeeced 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -108,60 +108,243 @@
interrupts = <21 4 0>;
};
- pioA: gpio@fffff200 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff200 0x100>;
- interrupts = <2 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ pinctrl@fffff200 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff200 0xfffff200 0xa00>;
+
+ atmel,mux-mask = <
+ /* A B */
+ 0xffffffff 0xffc003ff /* pioA */
+ 0xffffffff 0x800f8f00 /* pioB */
+ 0xffffffff 0x00000e00 /* pioC */
+ 0xffffffff 0xff0c1381 /* pioD */
+ 0xffffffff 0x81ffff81 /* pioE */
+ >;
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <1 12 0x1 0x0 /* PB12 periph A */
+ 1 13 0x1 0x0>; /* PB13 periph A */
+ };
+ };
- pioB: gpio@fffff400 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff400 0x100>;
- interrupts = <3 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <1 19 0x1 0x1 /* PB19 periph A with pullup */
+ 1 18 0x1 0x0>; /* PB18 periph A */
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <1 17 0x2 0x0>; /* PB17 periph B */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <1 15 0x2 0x0>; /* PB15 periph B */
+ };
+ };
- pioC: gpio@fffff600 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff600 0x100>;
- interrupts = <4 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ uart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <1 4 0x1 0x1 /* PB4 periph A with pullup */
+ 1 5 0x1 0x0>; /* PB5 periph A */
+ };
+
+ pinctrl_usart1_rts: usart1_rts-0 {
+ atmel,pins =
+ <3 16 0x1 0x0>; /* PD16 periph A */
+ };
+
+ pinctrl_usart1_cts: usart1_cts-0 {
+ atmel,pins =
+ <3 17 0x1 0x0>; /* PD17 periph A */
+ };
+ };
- pioD: gpio@fffff800 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff800 0x100>;
- interrupts = <5 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <1 6 0x1 0x1 /* PB6 periph A with pullup */
+ 1 7 0x1 0x0>; /* PB7 periph A */
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <2 9 0x2 0x0>; /* PC9 periph B */
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <2 11 0x2 0x0>; /* PC11 periph B */
+ };
+ };
- pioE: gpio@fffffa00 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffffa00 0x100>;
- interrupts = <5 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
+ usart3 {
+ pinctrl_usart3: usart3-0 {
+ atmel,pins =
+ <1 8 0x1 0x1 /* PB9 periph A with pullup */
+ 1 9 0x1 0x0>; /* PB8 periph A */
+ };
+
+ pinctrl_usart3_rts: usart3_rts-0 {
+ atmel,pins =
+ <0 23 0x2 0x0>; /* PA23 periph B */
+ };
+
+ pinctrl_usart3_cts: usart3_cts-0 {
+ atmel,pins =
+ <0 24 0x2 0x0>; /* PA24 periph B */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <2 8 0x0 0x1 /* PC8 gpio RDY pin pull_up*/
+ 2 14 0x0 0x1>; /* PC14 gpio enable pin pull_up */
+ };
+ };
+
+ macb {
+ pinctrl_macb_rmii: macb_rmii-0 {
+ atmel,pins =
+ <0 10 0x1 0x0 /* PA10 periph A */
+ 0 11 0x1 0x0 /* PA11 periph A */
+ 0 12 0x1 0x0 /* PA12 periph A */
+ 0 13 0x1 0x0 /* PA13 periph A */
+ 0 14 0x1 0x0 /* PA14 periph A */
+ 0 15 0x1 0x0 /* PA15 periph A */
+ 0 16 0x1 0x0 /* PA16 periph A */
+ 0 17 0x1 0x0 /* PA17 periph A */
+ 0 18 0x1 0x0 /* PA18 periph A */
+ 0 19 0x1 0x0>; /* PA19 periph A */
+ };
+
+ pinctrl_macb_rmii_mii: macb_rmii_mii-0 {
+ atmel,pins =
+ <0 6 0x2 0x0 /* PA6 periph B */
+ 0 7 0x2 0x0 /* PA7 periph B */
+ 0 8 0x2 0x0 /* PA8 periph B */
+ 0 9 0x2 0x0 /* PA9 periph B */
+ 0 27 0x2 0x0 /* PA27 periph B */
+ 0 28 0x2 0x0 /* PA28 periph B */
+ 0 29 0x2 0x0 /* PA29 periph B */
+ 0 30 0x2 0x0>; /* PA30 periph B */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <0 0 0x1 0x0 /* PA0 periph A */
+ 0 1 0x1 0x1 /* PA1 periph A with pullup */
+ 0 2 0x1 0x1>; /* PA2 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 3 0x1 0x1 /* PA3 periph A with pullup */
+ 0 4 0x1 0x1 /* PA4 periph A with pullup */
+ 0 5 0x1 0x1>; /* PA5 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat4_7: mmc0_slot0_dat4_7-0 {
+ atmel,pins =
+ <0 6 0x1 0x1 /* PA6 periph A with pullup */
+ 0 7 0x1 0x1 /* PA7 periph A with pullup */
+ 0 8 0x1 0x1 /* PA8 periph A with pullup */
+ 0 9 0x1 0x1>; /* PA9 periph A with pullup */
+ };
+ };
+
+ mmc1 {
+ pinctrl_mmc1_slot0_clk_cmd_dat0: mmc1_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <0 31 0x1 0x0 /* PA31 periph A */
+ 0 22 0x1 0x1 /* PA22 periph A with pullup */
+ 0 23 0x1 0x1>; /* PA23 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 24 0x1 0x1 /* PA24 periph A with pullup */
+ 0 25 0x1 0x1 /* PA25 periph A with pullup */
+ 0 26 0x1 0x1>; /* PA26 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot0_dat4_7: mmc1_slot0_dat4_7-0 {
+ atmel,pins =
+ <0 27 0x1 0x1 /* PA27 periph A with pullup */
+ 0 28 0x1 0x1 /* PA28 periph A with pullup */
+ 0 29 0x1 0x1 /* PA29 periph A with pullup */
+ 0 20 0x1 0x1>; /* PA30 periph A with pullup */
+ };
+ };
+
+ pioA: gpio@fffff200 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff200 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioB: gpio@fffff400 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioC: gpio@fffff600 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <4 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioD: gpio@fffff800 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <5 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioE: gpio@fffffa00 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <5 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
dbgu: serial@ffffee00 {
compatible = "atmel,at91sam9260-usart";
reg = <0xffffee00 0x200>;
interrupts = <1 4 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
status = "disabled";
};
@@ -171,6 +354,8 @@
interrupts = <7 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
status = "disabled";
};
@@ -180,6 +365,8 @@
interrupts = <8 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
status = "disabled";
};
@@ -189,6 +376,8 @@
interrupts = <9 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
status = "disabled";
};
@@ -198,6 +387,8 @@
interrupts = <10 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart3>;
status = "disabled";
};
@@ -205,6 +396,8 @@
compatible = "cdns,at32ap7000-macb", "cdns,macb";
reg = <0xfffbc000 0x100>;
interrupts = <25 4 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb_rmii>;
status = "disabled";
};
@@ -262,6 +455,24 @@
trigger-value = <0x6>;
};
};
+
+ mmc0: mmc@fff80000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfff80000 0x600>;
+ interrupts = <11 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@fffd0000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfffd0000 0x600>;
+ interrupts = <29 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
nand0: nand@40000000 {
@@ -273,6 +484,8 @@
>;
atmel,nand-addr-offset = <21>;
atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
gpios = <&pioC 8 0
&pioC 14 0
0
diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts
index 15e1dd43f62..20c31913c27 100644
--- a/arch/arm/boot/dts/at91sam9m10g45ek.dts
+++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts
@@ -39,6 +39,10 @@
};
usart1: serial@fff90000 {
+ pinctrl-0 =
+ <&pinctrl_usart1
+ &pinctrl_usart1_rts
+ &pinctrl_usart1_cts>;
status = "okay";
};
@@ -54,6 +58,50 @@
i2c1: i2c@fff88000 {
status = "okay";
};
+
+ mmc0: mmc@fff80000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 10 0>;
+ };
+ };
+
+ mmc1: mmc@fffd0000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc1
+ &pinctrl_mmc1_slot0_clk_cmd_dat0
+ &pinctrl_mmc1_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 11 0>;
+ wp-gpios = <&pioD 29 0>;
+ };
+ };
+
+ pinctrl@fffff200 {
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <3 10 0x0 0x5>; /* PD10 gpio CD pin pull up and deglitch */
+ };
+ };
+
+ mmc1 {
+ pinctrl_board_mmc1: mmc1-board {
+ atmel,pins =
+ <3 11 0x0 0x5 /* PD11 gpio CD pin pull up and deglitch */
+ 3 29 0x0 0x1>; /* PD29 gpio WP pin pull up */
+ };
+ };
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
index 82508d68aa7..e9efb34f437 100644
--- a/arch/arm/boot/dts/at91sam9n12.dtsi
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -84,6 +84,15 @@
reg = <0xfffffe10 0x10>;
};
+ mmc0: mmc@f0008000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf0008000 0x600>;
+ interrupts = <12 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
tcb0: timer@f8008000 {
compatible = "atmel,at91sam9x5-tcb";
reg = <0xf8008000 0x100>;
@@ -102,50 +111,186 @@
interrupts = <20 4 0>;
};
- pioA: gpio@fffff400 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffff400 0x100>;
- interrupts = <2 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff400 0xfffff400 0x800>;
- pioB: gpio@fffff600 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffff600 0x100>;
- interrupts = <2 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe07983 0x00000000 /* pioA */
+ 0x00040000 0x00047e0f 0x00000000 /* pioB */
+ 0xfdffffff 0x07c00000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
- pioC: gpio@fffff800 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffff800 0x100>;
- interrupts = <3 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <0 9 0x1 0x0 /* PA9 periph A */
+ 0 10 0x1 0x1>; /* PA10 periph with pullup */
+ };
+ };
- pioD: gpio@fffffa00 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffffa00 0x100>;
- interrupts = <3 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <0 1 0x1 0x1 /* PA1 periph A with pullup */
+ 0 0 0x1 0x0>; /* PA0 periph A */
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <0 2 0x1 0x0>; /* PA2 periph A */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <0 3 0x1 0x0>; /* PA3 periph A */
+ };
+ };
+
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <0 6 0x1 0x1 /* PA6 periph A with pullup */
+ 0 5 0x1 0x0>; /* PA5 periph A */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <0 8 0x1 0x1 /* PA8 periph A with pullup */
+ 0 7 0x1 0x0>; /* PA7 periph A */
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <1 0 0x2 0x0>; /* PB0 periph B */
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <1 1 0x2 0x0>; /* PB1 periph B */
+ };
+ };
+
+ usart3 {
+ pinctrl_usart3: usart3-0 {
+ atmel,pins =
+ <2 23 0x2 0x1 /* PC23 periph B with pullup */
+ 2 22 0x2 0x0>; /* PC22 periph B */
+ };
+
+ pinctrl_usart3_rts: usart3_rts-0 {
+ atmel,pins =
+ <2 24 0x2 0x0>; /* PC24 periph B */
+ };
+
+ pinctrl_usart3_cts: usart3_cts-0 {
+ atmel,pins =
+ <2 25 0x2 0x0>; /* PC25 periph B */
+ };
+ };
+
+ uart0 {
+ pinctrl_uart0: uart0-0 {
+ atmel,pins =
+ <2 9 0x3 0x1 /* PC9 periph C with pullup */
+ 2 8 0x3 0x0>; /* PC8 periph C */
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1: uart1-0 {
+ atmel,pins =
+ <2 16 0x3 0x1 /* PC17 periph C with pullup */
+ 2 17 0x3 0x0>; /* PC16 periph C */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <3 5 0x0 0x1 /* PD5 gpio RDY pin pull_up*/
+ 3 4 0x0 0x1>; /* PD4 gpio enable pin pull_up */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <0 17 0x1 0x0 /* PA17 periph A */
+ 0 16 0x1 0x1 /* PA16 periph A with pullup */
+ 0 15 0x1 0x1>; /* PA15 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 18 0x1 0x1 /* PA18 periph A with pullup */
+ 0 19 0x1 0x1 /* PA19 periph A with pullup */
+ 0 20 0x1 0x1>; /* PA20 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat4_7: mmc0_slot0_dat4_7-0 {
+ atmel,pins =
+ <0 11 0x2 0x1 /* PA11 periph B with pullup */
+ 0 12 0x2 0x1 /* PA12 periph B with pullup */
+ 0 13 0x2 0x1 /* PA13 periph B with pullup */
+ 0 14 0x2 0x1>; /* PA14 periph B with pullup */
+ };
+ };
+
+ pioA: gpio@fffff400 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioB: gpio@fffff600 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioC: gpio@fffff800 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioD: gpio@fffffa00 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
dbgu: serial@fffff200 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffff200 0x200>;
interrupts = <1 4 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
status = "disabled";
};
@@ -155,6 +300,8 @@
interrupts = <5 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
status = "disabled";
};
@@ -164,6 +311,8 @@
interrupts = <6 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
status = "disabled";
};
@@ -173,6 +322,8 @@
interrupts = <7 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
status = "disabled";
};
@@ -182,6 +333,8 @@
interrupts = <8 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart3>;
status = "disabled";
};
@@ -215,6 +368,8 @@
>;
atmel,nand-addr-offset = <21>;
atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
gpios = <&pioD 5 0
&pioD 4 0
0
diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts
index 912b2c283d6..0376bf4fd66 100644
--- a/arch/arm/boot/dts/at91sam9n12ek.dts
+++ b/arch/arm/boot/dts/at91sam9n12ek.dts
@@ -45,6 +45,28 @@
i2c1: i2c@f8014000 {
status = "okay";
};
+
+ mmc0: mmc@f0008000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioA 7 0>;
+ };
+ };
+
+ pinctrl@fffff400 {
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <0 7 0x0 0x5>; /* PA7 gpio CD pin pull up and deglitch */
+ };
+ };
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9x25.dtsi b/arch/arm/boot/dts/at91sam9x25.dtsi
new file mode 100644
index 00000000000..54eb33ba6d2
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x25.dtsi
@@ -0,0 +1,49 @@
+/*
+ * at91sam9x25.dtsi - Device Tree Include file for AT91SAM9X25 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+/include/ "at91sam9x5.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9X25 SoC";
+ compatible = "atmel, at91sam9x25, atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe03fff 0xc000001c /* pioA */
+ 0x0007ffff 0x00047e3f 0x00000000 /* pioB */
+ 0x80000000 0xfffd0000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+
+ macb1 {
+ pinctrl_macb1_rmii: macb1_rmii-0 {
+ atmel,pins =
+ <2 16 0x2 0x0 /* PC16 periph B */
+ 2 18 0x2 0x0 /* PC18 periph B */
+ 2 19 0x2 0x0 /* PC19 periph B */
+ 2 20 0x2 0x0 /* PC20 periph B */
+ 2 21 0x2 0x0 /* PC21 periph B */
+ 2 27 0x2 0x0 /* PC27 periph B */
+ 2 28 0x2 0x0 /* PC28 periph B */
+ 2 29 0x2 0x0 /* PC29 periph B */
+ 2 30 0x2 0x0 /* PC30 periph B */
+ 2 31 0x2 0x0>; /* PC31 periph B */
+ };
+ };
+ };
+
+ macb1: ethernet@f8030000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb1_rmii>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x25ek.dts b/arch/arm/boot/dts/at91sam9x25ek.dts
new file mode 100644
index 00000000000..af907eaa1f2
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x25ek.dts
@@ -0,0 +1,16 @@
+/*
+ * at91sam9x25ek.dts - Device Tree file for AT91SAM9X25-EK board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+/include/ "at91sam9x25.dtsi"
+/include/ "at91sam9x5ek.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G25-EK";
+ compatible = "atmel,at91sam9x25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+};
diff --git a/arch/arm/boot/dts/at91sam9x35.dtsi b/arch/arm/boot/dts/at91sam9x35.dtsi
new file mode 100644
index 00000000000..fb102d6126c
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x35.dtsi
@@ -0,0 +1,28 @@
+/*
+ * at91sam9x35.dtsi - Device Tree Include file for AT91SAM9X35 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+/include/ "at91sam9x5.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9X35 SoC";
+ compatible = "atmel, at91sam9x35, atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe03fff 0xc000000c /* pioA */
+ 0x000406ff 0x00047e3f 0x00000000 /* pioB */
+ 0xfdffffff 0x00000000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x35ek.dts b/arch/arm/boot/dts/at91sam9x35ek.dts
new file mode 100644
index 00000000000..5ccb607b541
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x35ek.dts
@@ -0,0 +1,16 @@
+/*
+ * at91sam9x35ek.dts - Device Tree file for AT91SAM9X35-EK board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+/include/ "at91sam9x35.dtsi"
+/include/ "at91sam9x5ek.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9X35-EK";
+ compatible = "atmel,at91sam9x35ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+};
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index 03fc136421c..7ee49e8daf9 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -111,50 +111,244 @@
interrupts = <21 4 0>;
};
- pioA: gpio@fffff400 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffff400 0x100>;
- interrupts = <2 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff400 0xfffff400 0x800>;
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <0 9 0x1 0x0 /* PA9 periph A */
+ 0 10 0x1 0x1>; /* PA10 periph A with pullup */
+ };
+ };
- pioB: gpio@fffff600 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffff600 0x100>;
- interrupts = <2 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <0 0 0x1 0x1 /* PA0 periph A with pullup */
+ 0 1 0x1 0x0>; /* PA1 periph A */
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <0 2 0x1 0x0>; /* PA2 periph A */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <0 3 0x1 0x0>; /* PA3 periph A */
+ };
+ };
+
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <0 5 0x1 0x1 /* PA5 periph A with pullup */
+ 0 6 0x1 0x0>; /* PA6 periph A */
+ };
+
+ pinctrl_usart1_rts: usart1_rts-0 {
+ atmel,pins =
+ <3 27 0x3 0x0>; /* PC27 periph C */
+ };
+
+ pinctrl_usart1_cts: usart1_cts-0 {
+ atmel,pins =
+ <3 28 0x3 0x0>; /* PC28 periph C */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <0 7 0x1 0x1 /* PA7 periph A with pullup */
+ 0 8 0x1 0x0>; /* PA8 periph A */
+ };
+
+ pinctrl_uart2_rts: uart2_rts-0 {
+ atmel,pins =
+ <0 0 0x2 0x0>; /* PB0 periph B */
+ };
+
+ pinctrl_uart2_cts: uart2_cts-0 {
+ atmel,pins =
+ <0 1 0x2 0x0>; /* PB1 periph B */
+ };
+ };
+
+ usart3 {
+ pinctrl_uart3: usart3-0 {
+ atmel,pins =
+ <3 23 0x2 0x1 /* PC22 periph B with pullup */
+ 3 23 0x2 0x0>; /* PC23 periph B */
+ };
+
+ pinctrl_usart3_rts: usart3_rts-0 {
+ atmel,pins =
+ <3 24 0x2 0x0>; /* PC24 periph B */
+ };
+
+ pinctrl_usart3_cts: usart3_cts-0 {
+ atmel,pins =
+ <3 25 0x2 0x0>; /* PC25 periph B */
+ };
+ };
+
+ uart0 {
+ pinctrl_uart0: uart0-0 {
+ atmel,pins =
+ <3 8 0x3 0x0 /* PC8 periph C */
+ 3 9 0x3 0x1>; /* PC9 periph C with pullup */
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1: uart1-0 {
+ atmel,pins =
+ <3 16 0x3 0x0 /* PC16 periph C */
+ 3 17 0x3 0x1>; /* PC17 periph C with pullup */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <3 4 0x0 0x1 /* PD5 gpio RDY pin pull_up */
+ 3 5 0x0 0x1>; /* PD4 gpio enable pin pull_up */
+ };
+ };
+
+ macb0 {
+ pinctrl_macb0_rmii: macb0_rmii-0 {
+ atmel,pins =
+ <1 0 0x1 0x0 /* PB0 periph A */
+ 1 1 0x1 0x0 /* PB1 periph A */
+ 1 2 0x1 0x0 /* PB2 periph A */
+ 1 3 0x1 0x0 /* PB3 periph A */
+ 1 4 0x1 0x0 /* PB4 periph A */
+ 1 5 0x1 0x0 /* PB5 periph A */
+ 1 6 0x1 0x0 /* PB6 periph A */
+ 1 7 0x1 0x0 /* PB7 periph A */
+ 1 9 0x1 0x0 /* PB9 periph A */
+ 1 10 0x1 0x0>; /* PB10 periph A */
+ };
+
+ pinctrl_macb0_rmii_mii: macb0_rmii_mii-0 {
+ atmel,pins =
+ <1 8 0x1 0x0 /* PA8 periph A */
+ 1 11 0x1 0x0 /* PA11 periph A */
+ 1 12 0x1 0x0 /* PA12 periph A */
+ 1 13 0x1 0x0 /* PA13 periph A */
+ 1 14 0x1 0x0 /* PA14 periph A */
+ 1 15 0x1 0x0 /* PA15 periph A */
+ 1 16 0x1 0x0 /* PA16 periph A */
+ 1 17 0x1 0x0>; /* PA17 periph A */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <0 17 0x1 0x0 /* PA17 periph A */
+ 0 16 0x1 0x1 /* PA16 periph A with pullup */
+ 0 15 0x1 0x1>; /* PA15 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 18 0x1 0x1 /* PA18 periph A with pullup */
+ 0 19 0x1 0x1 /* PA19 periph A with pullup */
+ 0 20 0x1 0x1>; /* PA20 periph A with pullup */
+ };
+ };
+
+ mmc1 {
+ pinctrl_mmc1_slot0_clk_cmd_dat0: mmc1_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <0 13 0x2 0x0 /* PA13 periph B */
+ 0 12 0x2 0x1 /* PA12 periph B with pullup */
+ 0 11 0x2 0x1>; /* PA11 periph B with pullup */
+ };
+
+ pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 2 0x2 0x1 /* PA2 periph B with pullup */
+ 0 3 0x2 0x1 /* PA3 periph B with pullup */
+ 0 4 0x2 0x1>; /* PA4 periph B with pullup */
+ };
+ };
+
+ pioA: gpio@fffff400 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioB: gpio@fffff600 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #gpio-lines = <19>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioC: gpio@fffff800 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioD: gpio@fffffa00 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #gpio-lines = <22>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
- pioC: gpio@fffff800 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffff800 0x100>;
- interrupts = <3 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
+ mmc0: mmc@f0008000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf0008000 0x600>;
+ interrupts = <12 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
};
- pioD: gpio@fffffa00 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffffa00 0x100>;
- interrupts = <3 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
+ mmc1: mmc@f000c000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf000c000 0x600>;
+ interrupts = <26 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
};
dbgu: serial@fffff200 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffff200 0x200>;
interrupts = <1 4 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
status = "disabled";
};
@@ -164,6 +358,8 @@
interrupts = <5 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
status = "disabled";
};
@@ -173,6 +369,8 @@
interrupts = <6 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
status = "disabled";
};
@@ -182,6 +380,8 @@
interrupts = <7 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
status = "disabled";
};
@@ -189,6 +389,8 @@
compatible = "cdns,at32ap7000-macb", "cdns,macb";
reg = <0xf802c000 0x100>;
interrupts = <24 4 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb0_rmii>;
status = "disabled";
};
@@ -273,6 +475,8 @@
>;
atmel,nand-addr-offset = <21>;
atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
gpios = <&pioD 5 0
&pioD 4 0
0
diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi
new file mode 100644
index 00000000000..8a7cf1d9cf5
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi
@@ -0,0 +1,101 @@
+/*
+ * at91sam9x5ek.dtsi - Device Tree file for AT91SAM9x5CM Base board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/include/ "at91sam9x5cm.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9X5-EK";
+ compatible = "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "128M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs";
+ };
+
+ ahb {
+ apb {
+ mmc0: mmc@f0008000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 15 0>;
+ };
+ };
+
+ mmc1: mmc@f000c000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc1
+ &pinctrl_mmc1_slot0_clk_cmd_dat0
+ &pinctrl_mmc1_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 14 0>;
+ };
+ };
+
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ usart0: serial@f801c000 {
+ status = "okay";
+ };
+
+ macb0: ethernet@f802c000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ i2c0: i2c@f8010000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@f8014000 {
+ status = "okay";
+ };
+
+ i2c2: i2c@f8018000 {
+ status = "okay";
+ };
+
+ pinctrl@fffff400 {
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <3 15 0x0 0x5>; /* PD15 gpio CD pin pull up and deglitch */
+ };
+ };
+
+ mmc1 {
+ pinctrl_board_mmc1: mmc1-board {
+ atmel,pins =
+ <3 14 0x0 0x5>; /* PD14 gpio CD pin pull up and deglitch */
+ };
+ };
+ };
+ };
+
+ usb0: ohci@00600000 {
+ status = "okay";
+ num-ports = <2>;
+ atmel,vbus-gpio = <&pioD 19 1
+ &pioD 20 1
+ >;
+ };
+
+ usb1: ehci@00700000 {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 55c57ea6169..b4587b27ae4 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -799,6 +799,7 @@
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x8006a000 0x2000>;
interrupts = <112 70 71>;
+ fsl,auart-dma-channel = <8 9>;
clocks = <&clks 45>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/pm9g45.dts b/arch/arm/boot/dts/pm9g45.dts
new file mode 100644
index 00000000000..387fedb5898
--- /dev/null
+++ b/arch/arm/boot/dts/pm9g45.dts
@@ -0,0 +1,165 @@
+/*
+ * pm9g45.dts - Device Tree file for Ronetix pm9g45 board
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+/dts-v1/;
+/include/ "at91sam9g45.dtsi"
+
+/ {
+ model = "Ronetix pm9g45";
+ compatible = "ronetix,pm9g45", "atmel,at91sam9g45", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x70000000 0x8000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@ffffee00 {
+ status = "okay";
+ };
+
+ pinctrl@fffff200 {
+
+ board {
+ pinctrl_board_nand: nand0-board {
+ atmel,pins =
+ <3 3 0x0 0x1 /* PD3 gpio RDY pin pull_up*/
+ 2 14 0x0 0x1>; /* PC14 gpio enable pin pull_up */
+ };
+ };
+
+ mmc {
+ pinctrl_board_mmc: mmc0-board {
+ atmel,pins =
+ <3 6 0x0 0x5>; /* PD6 gpio CD pin pull_up and deglitch */
+ };
+ };
+ };
+
+ mmc0: mmc@fff80000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 6 0>;
+ };
+ };
+
+ macb0: ethernet@fffbc000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ pinctrl-0 = <&pinctrl_board_nand>;
+
+ gpios = <&pioD 3 0
+ &pioC 14 0
+ 0
+ >;
+
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x20000>;
+ };
+
+ barebox@20000 {
+ label = "barebox";
+ reg = <0x20000 0x40000>;
+ };
+
+ bareboxenv@60000 {
+ label = "bareboxenv";
+ reg = <0x60000 0x1A0000>;
+ };
+
+ kernel@200000 {
+ label = "bareboxenv2";
+ reg = <0x200000 0x300000>;
+ };
+
+ kernel@500000 {
+ label = "root";
+ reg = <0x500000 0x400000>;
+ };
+
+ data@900000 {
+ label = "data";
+ reg = <0x900000 0x8340000>;
+ };
+ };
+
+ usb0: ohci@00700000 {
+ status = "okay";
+ num-ports = <2>;
+ };
+
+ usb1: ehci@00800000 {
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led0 {
+ label = "led0";
+ gpios = <&pioD 0 1>;
+ linux,default-trigger = "nand-disk";
+ };
+
+ led1 {
+ label = "led1";
+ gpios = <&pioD 31 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ right {
+ label = "SW4";
+ gpios = <&pioE 7 1>;
+ linux,code = <106>;
+ };
+
+ up {
+ label = "SW3";
+ gpios = <&pioE 8 1>;
+ linux,code = <103>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts
index dd4358bc26e..2e4c5727468 100644
--- a/arch/arm/boot/dts/spear1310-evb.dts
+++ b/arch/arm/boot/dts/spear1310-evb.dts
@@ -181,6 +181,10 @@
status = "okay";
};
+ gpio@d8400000 {
+ status = "okay";
+ };
+
i2c0: i2c@e0280000 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi
index 419ea7413d2..7cd25eb4f8e 100644
--- a/arch/arm/boot/dts/spear1310.dtsi
+++ b/arch/arm/boot/dts/spear1310.dtsi
@@ -70,6 +70,12 @@
status = "disabled";
};
+ pinmux: pinmux@e0700000 {
+ compatible = "st,spear1310-pinmux";
+ reg = <0xe0700000 0x1000>;
+ #gpio-range-cells = <2>;
+ };
+
spi1: spi@5d400000 {
compatible = "arm,pl022", "arm,primecell";
reg = <0x5d400000 0x1000>;
@@ -179,6 +185,27 @@
thermal@e07008c4 {
st,thermal-flags = <0x7000>;
};
+
+ gpiopinctrl: gpio@d8400000 {
+ compatible = "st,spear-plgpio";
+ reg = <0xd8400000 0x1000>;
+ interrupts = <0 100 0x4>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinmux 0 246>;
+ status = "disabled";
+
+ st-plgpio,ngpio = <246>;
+ st-plgpio,enb-reg = <0xd0>;
+ st-plgpio,wdata-reg = <0x90>;
+ st-plgpio,dir-reg = <0xb0>;
+ st-plgpio,ie-reg = <0x30>;
+ st-plgpio,rdata-reg = <0x70>;
+ st-plgpio,mis-reg = <0x10>;
+ st-plgpio,eit-reg = <0x50>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts
index c9a54e06fb6..045f7123ffa 100644
--- a/arch/arm/boot/dts/spear1340-evb.dts
+++ b/arch/arm/boot/dts/spear1340-evb.dts
@@ -193,6 +193,10 @@
status = "okay";
};
+ gpio@e2800000 {
+ status = "okay";
+ };
+
i2c0: i2c@e0280000 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi
index d71fe2a68f0..6c09eb0a1b2 100644
--- a/arch/arm/boot/dts/spear1340.dtsi
+++ b/arch/arm/boot/dts/spear1340.dtsi
@@ -24,6 +24,12 @@
status = "disabled";
};
+ pinmux: pinmux@e0700000 {
+ compatible = "st,spear1340-pinmux";
+ reg = <0xe0700000 0x1000>;
+ #gpio-range-cells = <2>;
+ };
+
spi1: spi@5d400000 {
compatible = "arm,pl022", "arm,primecell";
reg = <0x5d400000 0x1000>;
@@ -51,6 +57,26 @@
thermal@e07008c4 {
st,thermal-flags = <0x2a00>;
};
+
+ gpiopinctrl: gpio@e2800000 {
+ compatible = "st,spear-plgpio";
+ reg = <0xe2800000 0x1000>;
+ interrupts = <0 107 0x4>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinmux 0 252>;
+ status = "disabled";
+
+ st-plgpio,ngpio = <250>;
+ st-plgpio,wdata-reg = <0x40>;
+ st-plgpio,dir-reg = <0x00>;
+ st-plgpio,ie-reg = <0x80>;
+ st-plgpio,rdata-reg = <0x20>;
+ st-plgpio,mis-reg = <0xa0>;
+ st-plgpio,eit-reg = <0x60>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi
index 62fc4fb3e5f..930303e48df 100644
--- a/arch/arm/boot/dts/spear310.dtsi
+++ b/arch/arm/boot/dts/spear310.dtsi
@@ -22,9 +22,10 @@
0xb0000000 0xb0000000 0x10000000
0xd0000000 0xd0000000 0x30000000>;
- pinmux@b4000000 {
+ pinmux: pinmux@b4000000 {
compatible = "st,spear310-pinmux";
reg = <0xb4000000 0x1000>;
+ #gpio-range-cells = <2>;
};
fsmc: flash@44000000 {
@@ -75,6 +76,25 @@
reg = <0xb2200000 0x1000>;
status = "disabled";
};
+
+ gpiopinctrl: gpio@b4000000 {
+ compatible = "st,spear-plgpio";
+ reg = <0xb4000000 0x1000>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinmux 0 102>;
+ status = "disabled";
+
+ st-plgpio,ngpio = <102>;
+ st-plgpio,enb-reg = <0x10>;
+ st-plgpio,wdata-reg = <0x20>;
+ st-plgpio,dir-reg = <0x30>;
+ st-plgpio,ie-reg = <0x50>;
+ st-plgpio,rdata-reg = <0x40>;
+ st-plgpio,mis-reg = <0x60>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts
index 082328bd64a..ad4bfc68ee0 100644
--- a/arch/arm/boot/dts/spear320-evb.dts
+++ b/arch/arm/boot/dts/spear320-evb.dts
@@ -164,6 +164,10 @@
status = "okay";
};
+ gpio@b3000000 {
+ status = "okay";
+ };
+
i2c0: i2c@d0180000 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi
index 1f49d69595a..67d7ada7127 100644
--- a/arch/arm/boot/dts/spear320.dtsi
+++ b/arch/arm/boot/dts/spear320.dtsi
@@ -21,9 +21,10 @@
ranges = <0x40000000 0x40000000 0x80000000
0xd0000000 0xd0000000 0x30000000>;
- pinmux@b3000000 {
+ pinmux: pinmux@b3000000 {
compatible = "st,spear320-pinmux";
reg = <0xb3000000 0x1000>;
+ #gpio-range-cells = <2>;
};
clcd@90000000 {
@@ -90,6 +91,26 @@
reg = <0xa4000000 0x1000>;
status = "disabled";
};
+
+ gpiopinctrl: gpio@b3000000 {
+ compatible = "st,spear-plgpio";
+ reg = <0xb3000000 0x1000>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinmux 0 102>;
+ status = "disabled";
+
+ st-plgpio,ngpio = <102>;
+ st-plgpio,enb-reg = <0x24>;
+ st-plgpio,wdata-reg = <0x34>;
+ st-plgpio,dir-reg = <0x44>;
+ st-plgpio,ie-reg = <0x64>;
+ st-plgpio,rdata-reg = <0x54>;
+ st-plgpio,mis-reg = <0x84>;
+ st-plgpio,eit-reg = <0x94>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts
index f0ba901676a..a20d4ff3fb3 100644
--- a/arch/arm/boot/dts/tegra20-seaboard.dts
+++ b/arch/arm/boot/dts/tegra20-seaboard.dts
@@ -523,12 +523,12 @@
};
temperature-sensor@4c {
- compatible = "nct1008";
+ compatible = "onnn,nct1008";
reg = <0x4c>;
};
magnetometer@c {
- compatible = "ak8975";
+ compatible = "ak,ak8975";
reg = <0xc>;
interrupt-parent = <&gpio>;
interrupts = <109 0x04>; /* gpio PN5 */
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index b1497c7d7d6..df7f2270fc9 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -73,8 +73,8 @@
pinmux: pinmux {
compatible = "nvidia,tegra30-pinmux";
- reg = <0x70000868 0xd0 /* Pad control registers */
- 0x70003000 0x3e0>; /* Mux registers */
+ reg = <0x70000868 0xd4 /* Pad control registers */
+ 0x70003000 0x3e4>; /* Mux registers */
};
serial@70006000 {
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c
index df13a3ffff3..9d2d3ba339f 100644
--- a/arch/arm/common/timer-sp.c
+++ b/arch/arm/common/timer-sp.c
@@ -162,7 +162,6 @@ static struct clock_event_device sp804_clockevent = {
.set_mode = sp804_set_mode,
.set_next_event = sp804_set_next_event,
.rating = 300,
- .cpumask = cpu_all_mask,
};
static struct irqaction sp804_timer_irq = {
@@ -185,6 +184,7 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ);
evt->name = name;
evt->irq = irq;
+ evt->cpumask = cpu_possible_mask;
setup_irq(irq, &sp804_timer_irq);
clockevents_config_and_register(evt, rate, 0xf, 0xffffffff);
diff --git a/arch/arm/configs/afeb9260_defconfig b/arch/arm/configs/afeb9260_defconfig
index c285a9d777d..a8dbc1e0525 100644
--- a/arch/arm/configs/afeb9260_defconfig
+++ b/arch/arm/configs/afeb9260_defconfig
@@ -79,7 +79,7 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_RTC_CLASS=y
CONFIG_RTC_DEBUG=y
diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
index 67bc571ed0c..b175577d7ab 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -111,6 +111,7 @@ CONFIG_I2C=y
CONFIG_I2C_GPIO=y
CONFIG_SPI=y
CONFIG_SPI_ATMEL=y
+CONFIG_PINCTRL_AT91=y
# CONFIG_HWMON is not set
CONFIG_WATCHDOG=y
CONFIG_AT91SAM9X_WATCHDOG=y
diff --git a/arch/arm/configs/at91sam9260_defconfig b/arch/arm/configs/at91sam9260_defconfig
index 505b3765f87..0ea5d2c97fc 100644
--- a/arch/arm/configs/at91sam9260_defconfig
+++ b/arch/arm/configs/at91sam9260_defconfig
@@ -75,7 +75,7 @@ CONFIG_USB_STORAGE_DEBUG=y
CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_AT91SAM9=y
diff --git a/arch/arm/configs/at91sam9261_defconfig b/arch/arm/configs/at91sam9261_defconfig
index 1e8712ef062..c87beb973b3 100644
--- a/arch/arm/configs/at91sam9261_defconfig
+++ b/arch/arm/configs/at91sam9261_defconfig
@@ -125,7 +125,7 @@ CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_ATMELMCI=m
diff --git a/arch/arm/configs/at91sam9263_defconfig b/arch/arm/configs/at91sam9263_defconfig
index d2050cada82..c5212f43eee 100644
--- a/arch/arm/configs/at91sam9263_defconfig
+++ b/arch/arm/configs/at91sam9263_defconfig
@@ -133,7 +133,7 @@ CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_SDIO_UART=m
diff --git a/arch/arm/configs/at91sam9g20_defconfig b/arch/arm/configs/at91sam9g20_defconfig
index e1b0e80b54a..3b1881033ad 100644
--- a/arch/arm/configs/at91sam9g20_defconfig
+++ b/arch/arm/configs/at91sam9g20_defconfig
@@ -96,7 +96,7 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_ATMELMCI=m
diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig
index 4b8a25d9e68..1fd1d1de322 100644
--- a/arch/arm/configs/corgi_defconfig
+++ b/arch/arm/configs/corgi_defconfig
@@ -218,7 +218,7 @@ CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_PXA=y
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index 67b5abb6f85..4ea7c95719d 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -144,7 +144,7 @@ CONFIG_USB_GADGET_DEBUG_FS=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_G_PRINTER=m
CONFIG_USB_CDC_COMPOSITE=m
diff --git a/arch/arm/configs/h7202_defconfig b/arch/arm/configs/h7202_defconfig
index 69405a76242..e16d3f372e2 100644
--- a/arch/arm/configs/h7202_defconfig
+++ b/arch/arm/configs/h7202_defconfig
@@ -34,8 +34,7 @@ CONFIG_FB_MODE_HELPERS=y
CONFIG_USB_GADGET=m
CONFIG_USB_ZERO=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_FILE_STORAGE_TEST=y
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_EXT2_FS=y
CONFIG_TMPFS=y
diff --git a/arch/arm/configs/magician_defconfig b/arch/arm/configs/magician_defconfig
index a691ef4c600..557dd291288 100644
--- a/arch/arm/configs/magician_defconfig
+++ b/arch/arm/configs/magician_defconfig
@@ -136,7 +136,7 @@ CONFIG_USB_PXA27X=y
CONFIG_USB_ETH=m
# CONFIG_USB_ETH_RNDIS is not set
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_USB_GPIO_VBUS=y
diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig
index 00630e6af45..a07948a87ca 100644
--- a/arch/arm/configs/mini2440_defconfig
+++ b/arch/arm/configs/mini2440_defconfig
@@ -240,7 +240,7 @@ CONFIG_USB_GADGET_S3C2410=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_MMC=y
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig
index dde2a1af7b3..42eab9a2a0f 100644
--- a/arch/arm/configs/omap1_defconfig
+++ b/arch/arm/configs/omap1_defconfig
@@ -214,8 +214,7 @@ CONFIG_USB_TEST=y
CONFIG_USB_GADGET=y
CONFIG_USB_ETH=m
# CONFIG_USB_ETH_RNDIS is not set
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_FILE_STORAGE_TEST=y
+CONFIG_USB_MASS_STORAGE=m
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
diff --git a/arch/arm/configs/prima2_defconfig b/arch/arm/configs/prima2_defconfig
index 807d4e2acb1..6a936c7c078 100644
--- a/arch/arm/configs/prima2_defconfig
+++ b/arch/arm/configs/prima2_defconfig
@@ -37,7 +37,6 @@ CONFIG_SPI_SIRF=y
CONFIG_SPI_SPIDEV=y
# CONFIG_HWMON is not set
CONFIG_USB_GADGET=y
-CONFIG_USB_FILE_STORAGE=m
CONFIG_USB_MASS_STORAGE=m
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index df77931a432..2e0419d1b96 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -214,7 +214,7 @@ CONFIG_USB_GADGET_DUMMY_HCD=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_PXA=y
diff --git a/arch/arm/configs/stamp9g20_defconfig b/arch/arm/configs/stamp9g20_defconfig
index 52f1488591c..b845f5519bc 100644
--- a/arch/arm/configs/stamp9g20_defconfig
+++ b/arch/arm/configs/stamp9g20_defconfig
@@ -97,7 +97,7 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=m
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_ATMELMCI=y
diff --git a/arch/arm/configs/viper_defconfig b/arch/arm/configs/viper_defconfig
index 1d01ddd3312..d36e0d3c86e 100644
--- a/arch/arm/configs/viper_defconfig
+++ b/arch/arm/configs/viper_defconfig
@@ -139,7 +139,7 @@ CONFIG_USB_SERIAL_MCT_U232=m
CONFIG_USB_GADGET=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_G_PRINTER=m
CONFIG_RTC_CLASS=y
diff --git a/arch/arm/configs/zeus_defconfig b/arch/arm/configs/zeus_defconfig
index 547a3c1e59d..731d4f98531 100644
--- a/arch/arm/configs/zeus_defconfig
+++ b/arch/arm/configs/zeus_defconfig
@@ -143,7 +143,7 @@ CONFIG_USB_GADGET=m
CONFIG_USB_PXA27X=y
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_G_PRINTER=m
CONFIG_MMC=y
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index f70ae175a3d..514e398f1a0 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -31,5 +31,6 @@ generic-y += sockios.h
generic-y += termbits.h
generic-y += termios.h
generic-y += timex.h
+generic-y += trace_clock.h
generic-y += types.h
generic-y += unaligned.h
diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h
index 6b9b077d86b..afd7e916472 100644
--- a/arch/arm/include/asm/hardware/sp810.h
+++ b/arch/arm/include/asm/hardware/sp810.h
@@ -56,6 +56,8 @@
#define SCCTRL_TIMEREN1SEL_REFCLK (0 << 17)
#define SCCTRL_TIMEREN1SEL_TIMCLK (1 << 17)
+#define SCCTRL_TIMERENnSEL_SHIFT(n) (15 + ((n) * 2))
+
static inline void sysctl_soft_reset(void __iomem *base)
{
/* switch to slow mode */
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 42f042ee4ad..652b56086de 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -374,7 +374,7 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
#ifdef CONFIG_MMU
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
-extern int valid_phys_addr_range(unsigned long addr, size_t size);
+extern int valid_phys_addr_range(phys_addr_t addr, size_t size);
extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
extern int devmem_is_allowed(unsigned long pfn);
#endif
diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h
index aeae9c609df..6d65ba222db 100644
--- a/arch/arm/include/asm/prom.h
+++ b/arch/arm/include/asm/prom.h
@@ -11,6 +11,8 @@
#ifndef __ASMARM_PROM_H
#define __ASMARM_PROM_H
+#define HAVE_ARCH_DEVTREE_FIXUPS
+
#ifdef CONFIG_OF
extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 043624219b5..e34c1bdb804 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -494,8 +494,17 @@ endif
comment "Generic Board Type"
+config MACH_AT91RM9200_DT
+ bool "Atmel AT91RM9200 Evaluation Kits with device-tree support"
+ depends on SOC_AT91RM9200
+ select USE_OF
+ help
+ Select this if you want to experiment device-tree with
+ an Atmel RM9200 Evaluation Kit.
+
config MACH_AT91SAM_DT
bool "Atmel AT91SAM Evaluation Kits with device-tree support"
+ depends on SOC_AT91SAM9
select USE_OF
help
Select this if you want to experiment device-tree with
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 3bb7a51efc9..b38a1dcb79b 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o
obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o
# AT91SAM board with device-tree
+obj-$(CONFIG_MACH_AT91RM9200_DT) += board-rm9200-dt.o
obj-$(CONFIG_MACH_AT91SAM_DT) += board-dt.o
# AT91X40 board-specific support
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 5269825194a..6cceb42a4c3 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -194,6 +194,24 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_ID("pioB", &pioB_clk),
CLKDEV_CON_ID("pioC", &pioC_clk),
CLKDEV_CON_ID("pioD", &pioD_clk),
+ /* usart lookup table for DT entries */
+ CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
+ CLKDEV_CON_DEV_ID("usart", "fffc0000.serial", &usart0_clk),
+ CLKDEV_CON_DEV_ID("usart", "fffc4000.serial", &usart1_clk),
+ CLKDEV_CON_DEV_ID("usart", "fffc8000.serial", &usart2_clk),
+ CLKDEV_CON_DEV_ID("usart", "fffcc000.serial", &usart3_clk),
+ /* tc lookup table for DT entries */
+ CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk),
+ CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk),
+ CLKDEV_CON_DEV_ID("t2_clk", "fffa0000.timer", &tc2_clk),
+ CLKDEV_CON_DEV_ID("t0_clk", "fffa4000.timer", &tc3_clk),
+ CLKDEV_CON_DEV_ID("t1_clk", "fffa4000.timer", &tc4_clk),
+ CLKDEV_CON_DEV_ID("t2_clk", "fffa4000.timer", &tc5_clk),
+ CLKDEV_CON_DEV_ID("hclk", "300000.ohci", &ohci_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioD_clk),
};
static struct clk_lookup usart_clocks_lookups[] = {
@@ -361,10 +379,10 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
0 /* Advanced Interrupt Controller (IRQ6) */
};
-struct at91_init_soc __initdata at91rm9200_soc = {
+AT91_SOC_START(rm9200)
.map_io = at91rm9200_map_io,
.default_irq_priority = at91rm9200_default_irq_priority,
.ioremap_registers = at91rm9200_ioremap_registers,
.register_clocks = at91rm9200_register_clocks,
.init = at91rm9200_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 1e122bcd784..3cee0e6ea7c 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -68,7 +68,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
/* Enable overcurrent notification */
for (i = 0; i < data->ports; i++) {
- if (data->overcurrent_pin[i])
+ if (gpio_is_valid(data->overcurrent_pin[i]))
at91_set_gpio_input(data->overcurrent_pin[i], 1);
}
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
index aaa443b48c9..cafe98836c8 100644
--- a/arch/arm/mach-at91/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -24,6 +24,9 @@
#include <linux/irq.h>
#include <linux/clockchips.h>
#include <linux/export.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
#include <asm/mach/time.h>
@@ -91,7 +94,8 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
static struct irqaction at91rm9200_timer_irq = {
.name = "at91_tick",
.flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
- .handler = at91rm9200_timer_interrupt
+ .handler = at91rm9200_timer_interrupt,
+ .irq = NR_IRQS_LEGACY + AT91_ID_SYS,
};
static cycle_t read_clk32k(struct clocksource *cs)
@@ -179,8 +183,60 @@ static struct clock_event_device clkevt = {
void __iomem *at91_st_base;
EXPORT_SYMBOL_GPL(at91_st_base);
+#ifdef CONFIG_OF
+static struct of_device_id at91rm9200_st_timer_ids[] = {
+ { .compatible = "atmel,at91rm9200-st" },
+ { /* sentinel */ }
+};
+
+static int __init of_at91rm9200_st_init(void)
+{
+ struct device_node *np;
+ int ret;
+
+ np = of_find_matching_node(NULL, at91rm9200_st_timer_ids);
+ if (!np)
+ goto err;
+
+ at91_st_base = of_iomap(np, 0);
+ if (!at91_st_base)
+ goto node_err;
+
+ /* Get the interrupts property */
+ ret = irq_of_parse_and_map(np, 0);
+ if (!ret)
+ goto ioremap_err;
+ at91rm9200_timer_irq.irq = ret;
+
+ of_node_put(np);
+
+ return 0;
+
+ioremap_err:
+ iounmap(at91_st_base);
+node_err:
+ of_node_put(np);
+err:
+ return -EINVAL;
+}
+#else
+static int __init of_at91rm9200_st_init(void)
+{
+ return -EINVAL;
+}
+#endif
+
void __init at91rm9200_ioremap_st(u32 addr)
{
+#ifdef CONFIG_OF
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, at91rm9200_st_timer_ids);
+ if (np) {
+ of_node_put(np);
+ return;
+ }
+#endif
at91_st_base = ioremap(addr, 256);
if (!at91_st_base)
panic("Impossible to ioremap ST\n");
@@ -191,13 +247,16 @@ void __init at91rm9200_ioremap_st(u32 addr)
*/
void __init at91rm9200_timer_init(void)
{
+ /* For device tree enabled device: initialize here */
+ of_at91rm9200_st_init();
+
/* Disable all timer interrupts, and clear any pending ones */
at91_st_write(AT91_ST_IDR,
AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
at91_st_read(AT91_ST_SR);
/* Make IRQs happen for the system timer */
- setup_irq(NR_IRQS_LEGACY + AT91_ID_SYS, &at91rm9200_timer_irq);
+ setup_irq(at91rm9200_timer_irq.irq, &at91rm9200_timer_irq);
/* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used
* directly for the clocksource and all clockevents, after adjusting
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index f8202615f4a..c9e029e44d8 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -230,11 +230,15 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("t1_clk", "fffdc000.timer", &tc4_clk),
CLKDEV_CON_DEV_ID("t2_clk", "fffdc000.timer", &tc5_clk),
CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &ohci_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "fffa8000.mmc", &mmc_clk),
/* fake hclk clock */
CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
CLKDEV_CON_ID("pioA", &pioA_clk),
CLKDEV_CON_ID("pioB", &pioB_clk),
CLKDEV_CON_ID("pioC", &pioC_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk),
};
static struct clk_lookup usart_clocks_lookups[] = {
@@ -390,10 +394,10 @@ static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller */
};
-struct at91_init_soc __initdata at91sam9260_soc = {
+AT91_SOC_START(sam9260)
.map_io = at91sam9260_map_io,
.default_irq_priority = at91sam9260_default_irq_priority,
.ioremap_registers = at91sam9260_ioremap_registers,
.register_clocks = at91sam9260_register_clocks,
.init = at91sam9260_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index aa1e5872988..414bd855fb0 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
/* Enable overcurrent notification */
for (i = 0; i < data->ports; i++) {
- if (data->overcurrent_pin[i])
+ if (gpio_is_valid(data->overcurrent_pin[i]))
at91_set_gpio_input(data->overcurrent_pin[i], 1);
}
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 04295c04b3e..4d262f346fd 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -334,10 +334,10 @@ static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller */
};
-struct at91_init_soc __initdata at91sam9261_soc = {
+AT91_SOC_START(sam9261)
.map_io = at91sam9261_map_io,
.default_irq_priority = at91sam9261_default_irq_priority,
.ioremap_registers = at91sam9261_ioremap_registers,
.register_clocks = at91sam9261_register_clocks,
.init = at91sam9261_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index b9487696b7b..cd604aad8e9 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
/* Enable overcurrent notification */
for (i = 0; i < data->ports; i++) {
- if (data->overcurrent_pin[i])
+ if (gpio_is_valid(data->overcurrent_pin[i]))
at91_set_gpio_input(data->overcurrent_pin[i], 1);
}
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index d6f9c23927c..ed390f6fa23 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -211,7 +211,14 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("hclk", "a00000.ohci", &ohci_clk),
CLKDEV_CON_DEV_ID("spi_clk", "fffa4000.spi", &spi0_clk),
CLKDEV_CON_DEV_ID("spi_clk", "fffa8000.spi", &spi1_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "fff80000.mmc", &mmc0_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "fff84000.mmc", &mmc1_clk),
CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioCDE_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCDE_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCDE_clk),
};
static struct clk_lookup usart_clocks_lookups[] = {
@@ -365,10 +372,10 @@ static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller (IRQ1) */
};
-struct at91_init_soc __initdata at91sam9263_soc = {
+AT91_SOC_START(sam9263)
.map_io = at91sam9263_map_io,
.default_irq_priority = at91sam9263_default_irq_priority,
.ioremap_registers = at91sam9263_ioremap_registers,
.register_clocks = at91sam9263_register_clocks,
.init = at91sam9263_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index cb85da2ecce..9c61e59a210 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -78,7 +78,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
/* Enable overcurrent notification */
for (i = 0; i < data->ports; i++) {
- if (data->overcurrent_pin[i])
+ if (gpio_is_valid(data->overcurrent_pin[i]))
at91_set_gpio_input(data->overcurrent_pin[i], 1);
}
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 84af1b506d9..c5c2acc4bf2 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -256,10 +256,18 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("t0_clk", "fffd4000.timer", &tcb0_clk),
CLKDEV_CON_DEV_ID("hclk", "700000.ohci", &uhphs_clk),
CLKDEV_CON_DEV_ID("ehci_clk", "800000.ehci", &uhphs_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "fff80000.mmc", &mmc0_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "fffd0000.mmc", &mmc1_clk),
CLKDEV_CON_DEV_ID(NULL, "fff84000.i2c", &twi0_clk),
CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi1_clk),
/* fake hclk clock */
CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioC_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioDE_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioDE_clk),
+
CLKDEV_CON_ID("pioA", &pioA_clk),
CLKDEV_CON_ID("pioB", &pioB_clk),
CLKDEV_CON_ID("pioC", &pioC_clk),
@@ -409,10 +417,10 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller (IRQ0) */
};
-struct at91_init_soc __initdata at91sam9g45_soc = {
+AT91_SOC_START(sam9g45)
.map_io = at91sam9g45_map_io,
.default_irq_priority = at91sam9g45_default_irq_priority,
.ioremap_registers = at91sam9g45_ioremap_registers,
.register_clocks = at91sam9g45_register_clocks,
.init = at91sam9g45_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index b1596072dcc..fcd233cb33d 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -1841,8 +1841,8 @@ static struct resource sha_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = AT91SAM9G45_ID_AESTDESSHA,
- .end = AT91SAM9G45_ID_AESTDESSHA,
+ .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
+ .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
.flags = IORESOURCE_IRQ,
},
};
@@ -1874,8 +1874,8 @@ static struct resource tdes_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = AT91SAM9G45_ID_AESTDESSHA,
- .end = AT91SAM9G45_ID_AESTDESSHA,
+ .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
+ .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
.flags = IORESOURCE_IRQ,
},
};
@@ -1910,8 +1910,8 @@ static struct resource aes_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = AT91SAM9G45_ID_AESTDESSHA,
- .end = AT91SAM9G45_ID_AESTDESSHA,
+ .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
+ .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
.flags = IORESOURCE_IRQ,
},
};
diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c
index 732d3d3f4ec..70b3a99244a 100644
--- a/arch/arm/mach-at91/at91sam9n12.c
+++ b/arch/arm/mach-at91/at91sam9n12.c
@@ -168,13 +168,14 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk),
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("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),
- CLKDEV_CON_ID("pioA", &pioAB_clk),
- CLKDEV_CON_ID("pioB", &pioAB_clk),
- CLKDEV_CON_ID("pioC", &pioCD_clk),
- CLKDEV_CON_ID("pioD", &pioCD_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCD_clk),
/* additional fake clock for macb_hclk */
CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &uhp_clk),
CLKDEV_CON_DEV_ID("ohci_clk", "500000.ohci", &uhp_clk),
@@ -223,13 +224,10 @@ static void __init at91sam9n12_map_io(void)
void __init at91sam9n12_initialize(void)
{
at91_extern_irq = (1 << AT91SAM9N12_ID_IRQ0);
-
- /* Register GPIO subsystem (using DT) */
- at91_gpio_init(NULL, 0);
}
-struct at91_init_soc __initdata at91sam9n12_soc = {
+AT91_SOC_START(sam9n12)
.map_io = at91sam9n12_map_io,
.register_clocks = at91sam9n12_register_clocks,
.init = at91sam9n12_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 72e90841222..cbe72e44c13 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -338,10 +338,10 @@ static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller */
};
-struct at91_init_soc __initdata at91sam9rl_soc = {
+AT91_SOC_START(sam9rl)
.map_io = at91sam9rl_map_io,
.default_irq_priority = at91sam9rl_default_irq_priority,
.ioremap_registers = at91sam9rl_ioremap_registers,
.register_clocks = at91sam9rl_register_clocks,
.init = at91sam9rl_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
index e5035380dcb..3c729f0e2d3 100644
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -229,15 +229,17 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk),
CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk),
CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "f0008000.mmc", &mmc0_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "f000c000.mmc", &mmc1_clk),
CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk),
CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk),
CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk),
CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk),
CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", &twi2_clk),
- CLKDEV_CON_ID("pioA", &pioAB_clk),
- CLKDEV_CON_ID("pioB", &pioAB_clk),
- CLKDEV_CON_ID("pioC", &pioCD_clk),
- CLKDEV_CON_ID("pioD", &pioCD_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCD_clk),
/* additional fake clock for macb_hclk */
CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk),
CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk),
@@ -313,18 +315,11 @@ static void __init at91sam9x5_map_io(void)
at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE);
}
-void __init at91sam9x5_initialize(void)
-{
- /* Register GPIO subsystem (using DT) */
- at91_gpio_init(NULL, 0);
-}
-
/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */
-struct at91_init_soc __initdata at91sam9x5_soc = {
+AT91_SOC_START(sam9x5)
.map_io = at91sam9x5_map_io,
.register_clocks = at91sam9x5_register_clocks,
- .init = at91sam9x5_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c
index e8f45c4e0ea..3b6a94820fa 100644
--- a/arch/arm/mach-at91/board-dt.c
+++ b/arch/arm/mach-at91/board-dt.c
@@ -30,8 +30,6 @@
static const struct of_device_id irq_of_match[] __initconst = {
{ .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
- { .compatible = "atmel,at91rm9200-gpio", .data = at91_gpio_of_irq_setup },
- { .compatible = "atmel,at91sam9x5-gpio", .data = at91_gpio_of_irq_setup },
{ /*sentinel*/ }
};
diff --git a/arch/arm/mach-at91/board-rm9200-dt.c b/arch/arm/mach-at91/board-rm9200-dt.c
new file mode 100644
index 00000000000..5f9ce3da3fd
--- /dev/null
+++ b/arch/arm/mach-at91/board-rm9200-dt.c
@@ -0,0 +1,57 @@
+/*
+ * Setup code for AT91RM9200 Evaluation Kits with Device Tree support
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
+ * 2012 Joachim Eastwood <manabian@gmail.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#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>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include "at91_aic.h"
+#include "generic.h"
+
+
+static const struct of_device_id irq_of_match[] __initconst = {
+ { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
+ { /*sentinel*/ }
+};
+
+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
+};
+
+DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)")
+ .timer = &at91rm9200_timer,
+ .map_io = at91_map_io,
+ .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
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index b62f560e6c7..fc593d615e7 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -20,6 +20,7 @@ extern void __init at91_init_sram(int bank, unsigned long base,
extern void __init at91rm9200_set_type(int type);
extern void __init at91_initialize(unsigned long main_clock);
extern void __init at91x40_initialize(unsigned long main_clock);
+extern void __init at91rm9200_dt_initialize(void);
extern void __init at91_dt_initialize(void);
/* Interrupts */
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index be42cf0e74b..c5d7e1e9d75 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -23,8 +23,6 @@
#include <linux/io.h>
#include <linux/irqdomain.h>
#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/of_gpio.h>
#include <asm/mach/irq.h>
@@ -33,6 +31,8 @@
#include "generic.h"
+#define MAX_NB_GPIO_PER_BANK 32
+
struct at91_gpio_chip {
struct gpio_chip chip;
struct at91_gpio_chip *next; /* Bank sharing same clock */
@@ -46,6 +46,7 @@ struct at91_gpio_chip {
#define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip)
+static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset);
static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip);
static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val);
static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset);
@@ -55,26 +56,27 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip,
unsigned offset);
static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset);
-#define AT91_GPIO_CHIP(name, nr_gpio) \
+#define AT91_GPIO_CHIP(name) \
{ \
.chip = { \
.label = name, \
+ .request = at91_gpiolib_request, \
.direction_input = at91_gpiolib_direction_input, \
.direction_output = at91_gpiolib_direction_output, \
.get = at91_gpiolib_get, \
.set = at91_gpiolib_set, \
.dbg_show = at91_gpiolib_dbg_show, \
.to_irq = at91_gpiolib_to_irq, \
- .ngpio = nr_gpio, \
+ .ngpio = MAX_NB_GPIO_PER_BANK, \
}, \
}
static struct at91_gpio_chip gpio_chip[] = {
- AT91_GPIO_CHIP("pioA", 32),
- AT91_GPIO_CHIP("pioB", 32),
- AT91_GPIO_CHIP("pioC", 32),
- AT91_GPIO_CHIP("pioD", 32),
- AT91_GPIO_CHIP("pioE", 32),
+ AT91_GPIO_CHIP("pioA"),
+ AT91_GPIO_CHIP("pioB"),
+ AT91_GPIO_CHIP("pioC"),
+ AT91_GPIO_CHIP("pioD"),
+ AT91_GPIO_CHIP("pioE"),
};
static int gpio_banks;
@@ -89,7 +91,7 @@ static unsigned long at91_gpio_caps;
static inline void __iomem *pin_to_controller(unsigned pin)
{
- pin /= 32;
+ pin /= MAX_NB_GPIO_PER_BANK;
if (likely(pin < gpio_banks))
return gpio_chip[pin].regbase;
@@ -98,7 +100,7 @@ static inline void __iomem *pin_to_controller(unsigned pin)
static inline unsigned pin_to_mask(unsigned pin)
{
- return 1 << (pin % 32);
+ return 1 << (pin % MAX_NB_GPIO_PER_BANK);
}
@@ -713,80 +715,6 @@ postcore_initcall(at91_gpio_debugfs_init);
*/
static struct lock_class_key gpio_lock_class;
-#if defined(CONFIG_OF)
-static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq,
- irq_hw_number_t hw)
-{
- struct at91_gpio_chip *at91_gpio = h->host_data;
-
- irq_set_lockdep_class(virq, &gpio_lock_class);
-
- /*
- * Can use the "simple" and not "edge" handler since it's
- * shorter, and the AIC handles interrupts sanely.
- */
- irq_set_chip_and_handler(virq, &gpio_irqchip,
- handle_simple_irq);
- set_irq_flags(virq, IRQF_VALID);
- irq_set_chip_data(virq, at91_gpio);
-
- return 0;
-}
-
-static struct irq_domain_ops at91_gpio_ops = {
- .map = at91_gpio_irq_map,
- .xlate = irq_domain_xlate_twocell,
-};
-
-int __init at91_gpio_of_irq_setup(struct device_node *node,
- struct device_node *parent)
-{
- struct at91_gpio_chip *prev = NULL;
- int alias_idx = of_alias_get_id(node, "gpio");
- struct at91_gpio_chip *at91_gpio = &gpio_chip[alias_idx];
-
- /* Setup proper .irq_set_type function */
- if (has_pio3())
- gpio_irqchip.irq_set_type = alt_gpio_irq_type;
- else
- gpio_irqchip.irq_set_type = gpio_irq_type;
-
- /* Disable irqs of this PIO controller */
- __raw_writel(~0, at91_gpio->regbase + PIO_IDR);
-
- /* Setup irq domain */
- at91_gpio->domain = irq_domain_add_linear(node, at91_gpio->chip.ngpio,
- &at91_gpio_ops, at91_gpio);
- if (!at91_gpio->domain)
- panic("at91_gpio.%d: couldn't allocate irq domain (DT).\n",
- at91_gpio->pioc_idx);
-
- /* Setup chained handler */
- if (at91_gpio->pioc_idx)
- prev = &gpio_chip[at91_gpio->pioc_idx - 1];
-
- /* The toplevel handler handles one bank of GPIOs, except
- * on some SoC it can handles up to three...
- * We only set up the handler for the first of the list.
- */
- if (prev && prev->next == at91_gpio)
- return 0;
-
- at91_gpio->pioc_virq = irq_create_mapping(irq_find_host(parent),
- at91_gpio->pioc_hwirq);
- irq_set_chip_data(at91_gpio->pioc_virq, at91_gpio);
- irq_set_chained_handler(at91_gpio->pioc_virq, gpio_irq_handler);
-
- return 0;
-}
-#else
-int __init at91_gpio_of_irq_setup(struct device_node *node,
- struct device_node *parent)
-{
- return -EINVAL;
-}
-#endif
-
/*
* irqdomain initialization: pile up irqdomains on top of AIC range
*/
@@ -862,6 +790,16 @@ void __init at91_gpio_irq_setup(void)
}
/* gpiolib support */
+static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << offset;
+
+ __raw_writel(mask, pio + PIO_PER);
+ return 0;
+}
+
static int at91_gpiolib_direction_input(struct gpio_chip *chip,
unsigned offset)
{
@@ -975,81 +913,11 @@ err:
return -EINVAL;
}
-#ifdef CONFIG_OF_GPIO
-static void __init of_at91_gpio_init_one(struct device_node *np)
-{
- int alias_idx;
- struct at91_gpio_chip *at91_gpio;
-
- if (!np)
- return;
-
- alias_idx = of_alias_get_id(np, "gpio");
- if (alias_idx >= MAX_GPIO_BANKS) {
- pr_err("at91_gpio, failed alias idx(%d) > MAX_GPIO_BANKS(%d), ignoring.\n",
- alias_idx, MAX_GPIO_BANKS);
- return;
- }
-
- at91_gpio = &gpio_chip[alias_idx];
- at91_gpio->chip.base = alias_idx * at91_gpio->chip.ngpio;
-
- at91_gpio->regbase = of_iomap(np, 0);
- if (!at91_gpio->regbase) {
- pr_err("at91_gpio.%d, failed to map registers, ignoring.\n",
- alias_idx);
- return;
- }
-
- /* Get the interrupts property */
- if (of_property_read_u32(np, "interrupts", &at91_gpio->pioc_hwirq)) {
- pr_err("at91_gpio.%d, failed to get interrupts property, ignoring.\n",
- alias_idx);
- goto ioremap_err;
- }
-
- /* Get capabilities from compatibility property */
- if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio"))
- at91_gpio_caps |= AT91_GPIO_CAP_PIO3;
-
- /* Setup clock */
- if (at91_gpio_setup_clk(alias_idx))
- goto ioremap_err;
-
- at91_gpio->chip.of_node = np;
- gpio_banks = max(gpio_banks, alias_idx + 1);
- at91_gpio->pioc_idx = alias_idx;
- return;
-
-ioremap_err:
- iounmap(at91_gpio->regbase);
-}
-
-static int __init of_at91_gpio_init(void)
-{
- struct device_node *np = NULL;
-
- /*
- * This isn't ideal, but it gets things hooked up until this
- * driver is converted into a platform_device
- */
- for_each_compatible_node(np, NULL, "atmel,at91rm9200-gpio")
- of_at91_gpio_init_one(np);
-
- return gpio_banks > 0 ? 0 : -EINVAL;
-}
-#else
-static int __init of_at91_gpio_init(void)
-{
- return -EINVAL;
-}
-#endif
-
static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq)
{
struct at91_gpio_chip *at91_gpio = &gpio_chip[idx];
- at91_gpio->chip.base = idx * at91_gpio->chip.ngpio;
+ at91_gpio->chip.base = idx * MAX_NB_GPIO_PER_BANK;
at91_gpio->pioc_hwirq = pioc_hwirq;
at91_gpio->pioc_idx = idx;
@@ -1079,11 +947,11 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
BUG_ON(nr_banks > MAX_GPIO_BANKS);
- if (of_at91_gpio_init() < 0) {
- /* No GPIO controller found in device tree */
- for (i = 0; i < nr_banks; i++)
- at91_gpio_init_one(i, data[i].regbase, data[i].id);
- }
+ if (of_have_populated_dt())
+ return;
+
+ for (i = 0; i < nr_banks; i++)
+ at91_gpio_init_one(i, data[i].regbase, data[i].id);
for (i = 0; i < gpio_banks; i++) {
at91_gpio = &gpio_chip[i];
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index c55a4364ffb..a0d92a960f4 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -70,16 +70,6 @@ struct at91_cf_data {
extern void __init at91_add_device_cf(struct at91_cf_data *data);
/* MMC / SD */
- /* at91_mci platform config */
-struct at91_mmc_data {
- int det_pin; /* card detect IRQ */
- unsigned slot_b:1; /* uses Slot B */
- unsigned wire4:1; /* (SD) supports DAT0..DAT3 */
- int wp_pin; /* (SD) writeprotect detect */
- int vcc_pin; /* power switching (high == on) */
-};
-extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data);
-
/* atmel-mci platform config */
extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data);
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index 0b32c81730a..19cdd0b5b39 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -10,6 +10,7 @@
#include <linux/mm.h>
#include <linux/pm.h>
#include <linux/of_address.h>
+#include <linux/pinctrl/machine.h>
#include <asm/system_misc.h>
#include <asm/mach/map.h>
@@ -338,6 +339,7 @@ static void at91_dt_rstc(void)
}
static struct of_device_id ramc_ids[] = {
+ { .compatible = "atmel,at91rm9200-sdramc" },
{ .compatible = "atmel,at91sam9260-sdramc" },
{ .compatible = "atmel,at91sam9g45-ddramc" },
{ /*sentinel*/ }
@@ -436,6 +438,19 @@ end:
of_node_put(np);
}
+void __init at91rm9200_dt_initialize(void)
+{
+ at91_dt_ramc();
+
+ /* Init clock subsystem */
+ at91_dt_clock_init();
+
+ /* Register the processor-specific clocks */
+ at91_boot_soc.register_clocks();
+
+ at91_boot_soc.init();
+}
+
void __init at91_dt_initialize(void)
{
at91_dt_rstc();
@@ -448,7 +463,8 @@ void __init at91_dt_initialize(void)
/* Register the processor-specific clocks */
at91_boot_soc.register_clocks();
- at91_boot_soc.init();
+ if (at91_boot_soc.init)
+ at91_boot_soc.init();
}
#endif
@@ -463,4 +479,6 @@ void __init at91_initialize(unsigned long main_clock)
at91_boot_soc.register_clocks();
at91_boot_soc.init();
+
+ pinctrl_provide_dummies();
}
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
index a9cfeb15371..9c6d3d4f9a2 100644
--- a/arch/arm/mach-at91/soc.h
+++ b/arch/arm/mach-at91/soc.h
@@ -5,6 +5,7 @@
*/
struct at91_init_soc {
+ int builtin;
unsigned int *default_irq_priority;
void (*map_io)(void);
void (*ioremap_registers)(void);
@@ -22,9 +23,18 @@ extern struct at91_init_soc at91sam9rl_soc;
extern struct at91_init_soc at91sam9x5_soc;
extern struct at91_init_soc at91sam9n12_soc;
+#define AT91_SOC_START(_name) \
+struct at91_init_soc __initdata at91##_name##_soc \
+ __used \
+ = { \
+ .builtin = 1, \
+
+#define AT91_SOC_END \
+};
+
static inline int at91_soc_is_enabled(void)
{
- return at91_boot_soc.init != NULL;
+ return at91_boot_soc.builtin;
}
#if !defined(CONFIG_SOC_AT91RM9200)
diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c
index 2c5fb4c7e50..ae305397003 100644
--- a/arch/arm/mach-cns3xxx/cns3420vb.c
+++ b/arch/arm/mach-cns3xxx/cns3420vb.c
@@ -24,6 +24,8 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/partitions.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/hardware/gic.h>
@@ -32,6 +34,7 @@
#include <asm/mach/time.h>
#include <mach/cns3xxx.h>
#include <mach/irqs.h>
+#include <mach/pm.h>
#include "core.h"
#include "devices.h"
@@ -125,13 +128,52 @@ static struct resource cns3xxx_usb_ehci_resources[] = {
static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
+static int csn3xxx_usb_power_on(struct platform_device *pdev)
+{
+ /*
+ * EHCI and OHCI share the same clock and power,
+ * resetting twice would cause the 1st controller been reset.
+ * Therefore only do power up at the first up device, and
+ * power down at the last down device.
+ *
+ * Set USB AHB INCR length to 16
+ */
+ if (atomic_inc_return(&usb_pwr_ref) == 1) {
+ cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
+ cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
+ cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
+ __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
+ MISC_CHIP_CONFIG_REG);
+ }
+
+ return 0;
+}
+
+static void csn3xxx_usb_power_off(struct platform_device *pdev)
+{
+ /*
+ * EHCI and OHCI share the same clock and power,
+ * resetting twice would cause the 1st controller been reset.
+ * Therefore only do power up at the first up device, and
+ * power down at the last down device.
+ */
+ if (atomic_dec_return(&usb_pwr_ref) == 0)
+ cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
+}
+
+static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = {
+ .power_on = csn3xxx_usb_power_on,
+ .power_off = csn3xxx_usb_power_off,
+};
+
static struct platform_device cns3xxx_usb_ehci_device = {
- .name = "cns3xxx-ehci",
+ .name = "ehci-platform",
.num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
.resource = cns3xxx_usb_ehci_resources,
.dev = {
.dma_mask = &cns3xxx_usb_ehci_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &cns3xxx_usb_ehci_pdata,
},
};
@@ -149,13 +191,20 @@ static struct resource cns3xxx_usb_ohci_resources[] = {
static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
+static struct usb_ohci_pdata cns3xxx_usb_ohci_pdata = {
+ .num_ports = 1,
+ .power_on = csn3xxx_usb_power_on,
+ .power_off = csn3xxx_usb_power_off,
+};
+
static struct platform_device cns3xxx_usb_ohci_device = {
- .name = "cns3xxx-ohci",
+ .name = "ohci-platform",
.num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
.resource = cns3xxx_usb_ohci_resources,
.dev = {
.dma_mask = &cns3xxx_usb_ohci_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &cns3xxx_usb_ohci_pdata,
},
};
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index cd0c8b1e1ec..14e9947bad6 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -713,8 +713,7 @@ static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type,
break;
case VPBE_ENC_CUSTOM_TIMINGS:
if (pclock <= 27000000) {
- v |= DM644X_VPSS_MUXSEL_PLL2_MODE |
- DM644X_VPSS_DACCLKEN;
+ v |= DM644X_VPSS_DACCLKEN;
writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
} else {
/*
diff --git a/arch/arm/mach-dove/include/mach/pm.h b/arch/arm/mach-dove/include/mach/pm.h
index 7bcd0dfce4b..b47f7503868 100644
--- a/arch/arm/mach-dove/include/mach/pm.h
+++ b/arch/arm/mach-dove/include/mach/pm.h
@@ -63,7 +63,7 @@ static inline int pmu_to_irq(int pin)
static inline int irq_to_pmu(int irq)
{
- if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS)
+ if (IRQ_DOVE_PMU_START <= irq && irq < NR_IRQS)
return irq - IRQ_DOVE_PMU_START;
return -EINVAL;
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c
index 087711524e8..bc4344aa100 100644
--- a/arch/arm/mach-dove/irq.c
+++ b/arch/arm/mach-dove/irq.c
@@ -46,8 +46,20 @@ static void pmu_irq_ack(struct irq_data *d)
int pin = irq_to_pmu(d->irq);
u32 u;
+ /*
+ * The PMU mask register is not RW0C: it is RW. This means that
+ * the bits take whatever value is written to them; if you write
+ * a '1', you will set the interrupt.
+ *
+ * Unfortunately this means there is NO race free way to clear
+ * these interrupts.
+ *
+ * So, let's structure the code so that the window is as small as
+ * possible.
+ */
u = ~(1 << (pin & 31));
- writel(u, PMU_INTERRUPT_CAUSE);
+ u &= readl_relaxed(PMU_INTERRUPT_CAUSE);
+ writel_relaxed(u, PMU_INTERRUPT_CAUSE);
}
static struct irq_chip pmu_irq_chip = {
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c
index 21d568b3b14..87e07d6fc61 100644
--- a/arch/arm/mach-exynos/dma.c
+++ b/arch/arm/mach-exynos/dma.c
@@ -275,6 +275,9 @@ static int __init exynos_dma_init(void)
exynos_pdma1_pdata.nr_valid_peri =
ARRAY_SIZE(exynos4210_pdma1_peri);
exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri;
+
+ if (samsung_rev() == EXYNOS4210_REV_0)
+ exynos_mdma1_device.res.start = EXYNOS4_PA_S_MDMA1;
} else if (soc_is_exynos4212() || soc_is_exynos4412()) {
exynos_pdma0_pdata.nr_valid_peri =
ARRAY_SIZE(exynos4212_pdma0_peri);
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 8480849affb..ed4da4544cd 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -90,6 +90,7 @@
#define EXYNOS4_PA_MDMA0 0x10810000
#define EXYNOS4_PA_MDMA1 0x12850000
+#define EXYNOS4_PA_S_MDMA1 0x12840000
#define EXYNOS4_PA_PDMA0 0x12680000
#define EXYNOS4_PA_PDMA1 0x12690000
#define EXYNOS5_PA_MDMA0 0x10800000
diff --git a/arch/arm/mach-highbank/system.c b/arch/arm/mach-highbank/system.c
index 82c27230d4a..86e37cd9376 100644
--- a/arch/arm/mach-highbank/system.c
+++ b/arch/arm/mach-highbank/system.c
@@ -28,6 +28,7 @@ void highbank_restart(char mode, const char *cmd)
hignbank_set_pwr_soft_reset();
scu_power_mode(scu_base_addr, SCU_PM_POWEROFF);
- cpu_do_idle();
+ while (1)
+ cpu_do_idle();
}
diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
index 3c1b8ff9a0a..cc49c7ae186 100644
--- a/arch/arm/mach-imx/clk-gate2.c
+++ b/arch/arm/mach-imx/clk-gate2.c
@@ -112,7 +112,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
clk = clk_register(dev, &gate->hw);
if (IS_ERR(clk))
- kfree(clk);
+ kfree(gate);
return clk;
}
diff --git a/arch/arm/mach-imx/ehci-imx25.c b/arch/arm/mach-imx/ehci-imx25.c
index 412c583a24b..576af744695 100644
--- a/arch/arm/mach-imx/ehci-imx25.c
+++ b/arch/arm/mach-imx/ehci-imx25.c
@@ -30,7 +30,7 @@
#define MX25_H1_SIC_SHIFT 21
#define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT)
#define MX25_H1_PP_BIT (1 << 18)
-#define MX25_H1_PM_BIT (1 << 8)
+#define MX25_H1_PM_BIT (1 << 16)
#define MX25_H1_IPPUE_UP_BIT (1 << 7)
#define MX25_H1_IPPUE_DOWN_BIT (1 << 6)
#define MX25_H1_TLL_BIT (1 << 5)
diff --git a/arch/arm/mach-imx/ehci-imx35.c b/arch/arm/mach-imx/ehci-imx35.c
index 779e16eb65c..293397852e4 100644
--- a/arch/arm/mach-imx/ehci-imx35.c
+++ b/arch/arm/mach-imx/ehci-imx35.c
@@ -30,7 +30,7 @@
#define MX35_H1_SIC_SHIFT 21
#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT)
#define MX35_H1_PP_BIT (1 << 18)
-#define MX35_H1_PM_BIT (1 << 8)
+#define MX35_H1_PM_BIT (1 << 16)
#define MX35_H1_IPPUE_UP_BIT (1 << 7)
#define MX35_H1_IPPUE_DOWN_BIT (1 << 6)
#define MX35_H1_TLL_BIT (1 << 5)
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index e428f3ab15c..b3d86d7081a 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -21,10 +21,9 @@
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#include <linux/io.h>
+#include <linux/platform_data/clk-integrator.h>
#include <linux/slab.h>
-#include <linux/clkdev.h>
-#include <asm/hardware/icst.h>
#include <mach/lm.h>
#include <mach/impd1.h>
#include <asm/sizes.h>
@@ -36,45 +35,6 @@ MODULE_PARM_DESC(lmid, "logic module stack position");
struct impd1_module {
void __iomem *base;
- struct clk vcos[2];
- struct clk_lookup *clks[3];
-};
-
-static const struct icst_params impd1_vco_params = {
- .ref = 24000000, /* 24 MHz */
- .vco_max = ICST525_VCO_MAX_3V,
- .vco_min = ICST525_VCO_MIN,
- .vd_min = 12,
- .vd_max = 519,
- .rd_min = 3,
- .rd_max = 120,
- .s2div = icst525_s2div,
- .idx2s = icst525_idx2s,
-};
-
-static void impd1_setvco(struct clk *clk, struct icst_vco vco)
-{
- struct impd1_module *impd1 = clk->data;
- u32 val = vco.v | (vco.r << 9) | (vco.s << 16);
-
- writel(0xa05f, impd1->base + IMPD1_LOCK);
- writel(val, clk->vcoreg);
- writel(0, impd1->base + IMPD1_LOCK);
-
-#ifdef DEBUG
- vco.v = val & 0x1ff;
- vco.r = (val >> 9) & 0x7f;
- vco.s = (val >> 16) & 7;
-
- pr_debug("IM-PD1: VCO%d clock is %ld Hz\n",
- vconr, icst525_hz(&impd1_vco_params, vco));
-#endif
-}
-
-static const struct clk_ops impd1_clk_ops = {
- .round = icst_clk_round,
- .set = icst_clk_set,
- .setvco = impd1_setvco,
};
void impd1_tweak_control(struct device *dev, u32 mask, u32 val)
@@ -344,10 +304,6 @@ static struct impd1_device impd1_devs[] = {
}
};
-static struct clk fixed_14745600 = {
- .rate = 14745600,
-};
-
static int impd1_probe(struct lm_device *dev)
{
struct impd1_module *impd1;
@@ -376,23 +332,7 @@ static int impd1_probe(struct lm_device *dev)
printk("IM-PD1 found at 0x%08lx\n",
(unsigned long)dev->resource.start);
- for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) {
- impd1->vcos[i].ops = &impd1_clk_ops,
- impd1->vcos[i].owner = THIS_MODULE,
- impd1->vcos[i].params = &impd1_vco_params,
- impd1->vcos[i].data = impd1;
- }
- impd1->vcos[0].vcoreg = impd1->base + IMPD1_OSC1;
- impd1->vcos[1].vcoreg = impd1->base + IMPD1_OSC2;
-
- impd1->clks[0] = clkdev_alloc(&impd1->vcos[0], NULL, "lm%x:01000",
- dev->id);
- impd1->clks[1] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00100",
- dev->id);
- impd1->clks[2] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00200",
- dev->id);
- for (i = 0; i < ARRAY_SIZE(impd1->clks); i++)
- clkdev_add(impd1->clks[i]);
+ integrator_impd1_clk_init(impd1->base, dev->id);
for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) {
struct impd1_device *idev = impd1_devs + i;
@@ -431,12 +371,9 @@ static int impd1_remove_one(struct device *dev, void *data)
static void impd1_remove(struct lm_device *dev)
{
struct impd1_module *impd1 = lm_get_drvdata(dev);
- int i;
device_for_each_child(&dev->dev, NULL, impd1_remove_one);
-
- for (i = 0; i < ARRAY_SIZE(impd1->clks); i++)
- clkdev_drop(impd1->clks[i]);
+ integrator_impd1_clk_exit(dev->id);
lm_set_drvdata(dev, NULL);
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index 1694f01ce2b..6d6bde3e15f 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -410,6 +410,7 @@ void __init ixp4xx_pci_preinit(void)
* Enable the IO window to be way up high, at 0xfffffc00
*/
local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01);
+ local_write_config(0x40, 4, 0x000080FF); /* No TRDY time limit */
} else {
printk("PCI: IXP4xx is target - No bus scan performed\n");
}
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index fdf91a16088..8c0c0e2d072 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -67,15 +67,12 @@ static struct map_desc ixp4xx_io_desc[] __initdata = {
.pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
.length = IXP4XX_PCI_CFG_REGION_SIZE,
.type = MT_DEVICE
- },
-#ifdef CONFIG_DEBUG_LL
- { /* Debug UART mapping */
- .virtual = (unsigned long)IXP4XX_DEBUG_UART_BASE_VIRT,
- .pfn = __phys_to_pfn(IXP4XX_DEBUG_UART_BASE_PHYS),
- .length = IXP4XX_DEBUG_UART_REGION_SIZE,
+ }, { /* Queue Manager */
+ .virtual = (unsigned long)IXP4XX_QMGR_BASE_VIRT,
+ .pfn = __phys_to_pfn(IXP4XX_QMGR_BASE_PHYS),
+ .length = IXP4XX_QMGR_REGION_SIZE,
.type = MT_DEVICE
- }
-#endif
+ },
};
void __init ixp4xx_map_io(void)
diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c
index b800a031207..53b8348dfcc 100644
--- a/arch/arm/mach-ixp4xx/goramo_mlr.c
+++ b/arch/arm/mach-ixp4xx/goramo_mlr.c
@@ -15,6 +15,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/pci.h>
+#include <asm/system_info.h>
#define SLOT_ETHA 0x0B /* IDSEL = AD21 */
#define SLOT_ETHB 0x0C /* IDSEL = AD20 */
@@ -329,7 +330,7 @@ static struct platform_device device_hss_tab[] = {
};
-static struct platform_device *device_tab[6] __initdata = {
+static struct platform_device *device_tab[7] __initdata = {
&device_flash, /* index 0 */
};
diff --git a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S
index 8c9f8d56449..ff686cbc5df 100644
--- a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S
+++ b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S
@@ -17,8 +17,8 @@
#else
mov \rp, #0
#endif
- orr \rv, \rp, #0xff000000 @ virtual
- orr \rv, \rv, #0x00b00000
+ orr \rv, \rp, #0xfe000000 @ virtual
+ orr \rv, \rv, #0x00f00000
orr \rp, \rp, #0xc8000000 @ physical
.endm
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
index eb68b61ce97..c5bae9c035d 100644
--- a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
@@ -30,51 +30,43 @@
*
* 0x50000000 0x10000000 ioremap'd EXP BUS
*
- * 0x6000000 0x00004000 ioremap'd QMgr
+ * 0xC8000000 0x00013000 0xFEF00000 On-Chip Peripherals
*
- * 0xC0000000 0x00001000 0xffbff000 PCI CFG
+ * 0xC0000000 0x00001000 0xFEF13000 PCI CFG
*
- * 0xC4000000 0x00001000 0xffbfe000 EXP CFG
+ * 0xC4000000 0x00001000 0xFEF14000 EXP CFG
*
- * 0xC8000000 0x00013000 0xffbeb000 On-Chip Peripherals
+ * 0x60000000 0x00004000 0xFEF15000 QMgr
*/
/*
* Queue Manager
*/
-#define IXP4XX_QMGR_BASE_PHYS (0x60000000)
-#define IXP4XX_QMGR_REGION_SIZE (0x00004000)
+#define IXP4XX_QMGR_BASE_PHYS 0x60000000
+#define IXP4XX_QMGR_BASE_VIRT IOMEM(0xFEF15000)
+#define IXP4XX_QMGR_REGION_SIZE 0x00004000
/*
- * Expansion BUS Configuration registers
+ * Peripheral space, including debug UART. Must be section-aligned so that
+ * it can be used with the low-level debug code.
*/
-#define IXP4XX_EXP_CFG_BASE_PHYS (0xC4000000)
-#define IXP4XX_EXP_CFG_BASE_VIRT IOMEM(0xFFBFE000)
-#define IXP4XX_EXP_CFG_REGION_SIZE (0x00001000)
+#define IXP4XX_PERIPHERAL_BASE_PHYS 0xC8000000
+#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFEF00000)
+#define IXP4XX_PERIPHERAL_REGION_SIZE 0x00013000
/*
* PCI Config registers
*/
-#define IXP4XX_PCI_CFG_BASE_PHYS (0xC0000000)
-#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFFBFF000)
-#define IXP4XX_PCI_CFG_REGION_SIZE (0x00001000)
-
-/*
- * Peripheral space
- */
-#define IXP4XX_PERIPHERAL_BASE_PHYS (0xC8000000)
-#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFFBEB000)
-#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000)
+#define IXP4XX_PCI_CFG_BASE_PHYS 0xC0000000
+#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFEF13000)
+#define IXP4XX_PCI_CFG_REGION_SIZE 0x00001000
/*
- * Debug UART
- *
- * This is basically a remap of UART1 into a region that is section
- * aligned so that it * can be used with the low-level debug code.
+ * Expansion BUS Configuration registers
*/
-#define IXP4XX_DEBUG_UART_BASE_PHYS (0xC8000000)
-#define IXP4XX_DEBUG_UART_BASE_VIRT IOMEM(0xffb00000)
-#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000)
+#define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000
+#define IXP4XX_EXP_CFG_BASE_VIRT 0xFEF14000
+#define IXP4XX_EXP_CFG_REGION_SIZE 0x00001000
#define IXP4XX_EXP_CS0_OFFSET 0x00
#define IXP4XX_EXP_CS1_OFFSET 0x04
diff --git a/arch/arm/mach-ixp4xx/include/mach/qmgr.h b/arch/arm/mach-ixp4xx/include/mach/qmgr.h
index 9e7cad2d54c..4de8da536db 100644
--- a/arch/arm/mach-ixp4xx/include/mach/qmgr.h
+++ b/arch/arm/mach-ixp4xx/include/mach/qmgr.h
@@ -86,7 +86,7 @@ void qmgr_release_queue(unsigned int queue);
static inline void qmgr_put_entry(unsigned int queue, u32 val)
{
- extern struct qmgr_regs __iomem *qmgr_regs;
+ struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
#if DEBUG_QMGR
BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
@@ -99,7 +99,7 @@ static inline void qmgr_put_entry(unsigned int queue, u32 val)
static inline u32 qmgr_get_entry(unsigned int queue)
{
u32 val;
- extern struct qmgr_regs __iomem *qmgr_regs;
+ const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
val = __raw_readl(&qmgr_regs->acc[queue][0]);
#if DEBUG_QMGR
BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
@@ -112,14 +112,14 @@ static inline u32 qmgr_get_entry(unsigned int queue)
static inline int __qmgr_get_stat1(unsigned int queue)
{
- extern struct qmgr_regs __iomem *qmgr_regs;
+ const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
return (__raw_readl(&qmgr_regs->stat1[queue >> 3])
>> ((queue & 7) << 2)) & 0xF;
}
static inline int __qmgr_get_stat2(unsigned int queue)
{
- extern struct qmgr_regs __iomem *qmgr_regs;
+ const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
BUG_ON(queue >= HALF_QUEUES);
return (__raw_readl(&qmgr_regs->stat2[queue >> 4])
>> ((queue & 0xF) << 1)) & 0x3;
@@ -145,7 +145,7 @@ static inline int qmgr_stat_empty(unsigned int queue)
*/
static inline int qmgr_stat_below_low_watermark(unsigned int queue)
{
- extern struct qmgr_regs __iomem *qmgr_regs;
+ const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
if (queue >= HALF_QUEUES)
return (__raw_readl(&qmgr_regs->statne_h) >>
(queue - HALF_QUEUES)) & 0x01;
@@ -172,7 +172,7 @@ static inline int qmgr_stat_above_high_watermark(unsigned int queue)
*/
static inline int qmgr_stat_full(unsigned int queue)
{
- extern struct qmgr_regs __iomem *qmgr_regs;
+ const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
if (queue >= HALF_QUEUES)
return (__raw_readl(&qmgr_regs->statf_h) >>
(queue - HALF_QUEUES)) & 0x01;
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_npe.c b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
index a17ed79207a..d4eb09a6286 100644
--- a/arch/arm/mach-ixp4xx/ixp4xx_npe.c
+++ b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
@@ -116,7 +116,11 @@
/* NPE mailbox_status value for reset */
#define RESET_MBOX_STAT 0x0000F0F0
-const char *npe_names[] = { "NPE-A", "NPE-B", "NPE-C" };
+#define NPE_A_FIRMWARE "NPE-A"
+#define NPE_B_FIRMWARE "NPE-B"
+#define NPE_C_FIRMWARE "NPE-C"
+
+const char *npe_names[] = { NPE_A_FIRMWARE, NPE_B_FIRMWARE, NPE_C_FIRMWARE };
#define print_npe(pri, npe, fmt, ...) \
printk(pri "%s: " fmt, npe_name(npe), ## __VA_ARGS__)
@@ -724,6 +728,9 @@ module_exit(npe_cleanup_module);
MODULE_AUTHOR("Krzysztof Halasa");
MODULE_LICENSE("GPL v2");
+MODULE_FIRMWARE(NPE_A_FIRMWARE);
+MODULE_FIRMWARE(NPE_B_FIRMWARE);
+MODULE_FIRMWARE(NPE_C_FIRMWARE);
EXPORT_SYMBOL(npe_names);
EXPORT_SYMBOL(npe_running);
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
index 852f7c9f87d..9d1b6b7c394 100644
--- a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
+++ b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
@@ -14,7 +14,7 @@
#include <linux/module.h>
#include <mach/qmgr.h>
-struct qmgr_regs __iomem *qmgr_regs;
+static struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
static struct resource *mem_res;
static spinlock_t qmgr_lock;
static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
@@ -293,12 +293,6 @@ static int qmgr_init(void)
if (mem_res == NULL)
return -EBUSY;
- qmgr_regs = ioremap(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
- if (qmgr_regs == NULL) {
- err = -ENOMEM;
- goto error_map;
- }
-
/* reset qmgr registers */
for (i = 0; i < 4; i++) {
__raw_writel(0x33333333, &qmgr_regs->stat1[i]);
@@ -347,8 +341,6 @@ static int qmgr_init(void)
error_irq2:
free_irq(IRQ_IXP4XX_QM1, NULL);
error_irq:
- iounmap(qmgr_regs);
-error_map:
release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
return err;
}
@@ -359,7 +351,6 @@ static void qmgr_remove(void)
free_irq(IRQ_IXP4XX_QM2, NULL);
synchronize_irq(IRQ_IXP4XX_QM1);
synchronize_irq(IRQ_IXP4XX_QM2);
- iounmap(qmgr_regs);
release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
}
@@ -369,7 +360,6 @@ module_exit(qmgr_remove);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Krzysztof Halasa");
-EXPORT_SYMBOL(qmgr_regs);
EXPORT_SYMBOL(qmgr_set_irq);
EXPORT_SYMBOL(qmgr_enable_irq);
EXPORT_SYMBOL(qmgr_disable_irq);
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index ec544918b12..74fc5a074fc 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -207,14 +207,19 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
return 1;
}
+/*
+ * The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it
+ * is operating as a root complex this needs to be switched to
+ * PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on
+ * the device. Decoding setup is handled by the orion code.
+ */
static void __devinit rc_pci_fixup(struct pci_dev *dev)
{
- /*
- * Prevent enumeration of root complex.
- */
if (dev->bus->parent == NULL && dev->devfn == 0) {
int i;
+ dev->class &= 0xff;
+ dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
dev->resource[i].start = 0;
dev->resource[i].end = 0;
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
index bfa1eab91f4..22ef8a1abe0 100644
--- a/arch/arm/mach-nomadik/board-nhk8815.c
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -24,6 +24,7 @@
#include <linux/i2c.h>
#include <linux/io.h>
#include <linux/pinctrl/machine.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
#include <asm/hardware/vic.h>
#include <asm/sizes.h>
#include <asm/mach-types.h>
@@ -32,9 +33,7 @@
#include <asm/mach/flash.h>
#include <asm/mach/time.h>
-#include <plat/gpio-nomadik.h>
#include <plat/mtu.h>
-#include <plat/pincfg.h>
#include <linux/platform_data/mtd-nomadik-nand.h>
#include <mach/fsmc.h>
diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c
index b617eaed0ce..1273931303f 100644
--- a/arch/arm/mach-nomadik/cpu-8815.c
+++ b/arch/arm/mach-nomadik/cpu-8815.c
@@ -26,8 +26,8 @@
#include <linux/irq.h>
#include <linux/dma-mapping.h>
#include <linux/platform_data/clk-nomadik.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
-#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <asm/mach/map.h>
diff --git a/arch/arm/mach-nomadik/i2c-8815nhk.c b/arch/arm/mach-nomadik/i2c-8815nhk.c
index 6d14454d460..0c2f6628299 100644
--- a/arch/arm/mach-nomadik/i2c-8815nhk.c
+++ b/arch/arm/mach-nomadik/i2c-8815nhk.c
@@ -4,8 +4,7 @@
#include <linux/i2c-algo-bit.h>
#include <linux/i2c-gpio.h>
#include <linux/platform_device.h>
-#include <plat/gpio-nomadik.h>
-#include <plat/pincfg.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
/*
* There are two busses in the 8815NHK.
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 48d5e41dfbf..37859069444 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -580,6 +580,11 @@ static void __init igep_wlan_bt_init(void)
} 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) {
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index b700685762b..56277a04713 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -45,7 +45,6 @@
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
-#include "common.h"
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include <video/omap-panel-tfp410.h>
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index b56d06b4878..95192a062d5 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -359,7 +359,7 @@ static struct clockdomain iss_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS,
.wkdep_srcs = iss_wkup_sleep_deps,
.sleepdep_srcs = iss_wkup_sleep_deps,
- .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .flags = CLKDM_CAN_SWSUP,
};
static struct clockdomain l3_dss_44xx_clkdm = {
diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c
index 48daac2581b..84551f205e4 100644
--- a/arch/arm/mach-omap2/common-board-devices.c
+++ b/arch/arm/mach-omap2/common-board-devices.c
@@ -64,30 +64,36 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
struct spi_board_info *spi_bi = &ads7846_spi_board_info;
int err;
- err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown");
- if (err) {
- pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err);
- return;
- }
+ /*
+ * If a board defines get_pendown_state() function, request the pendown
+ * GPIO and set the GPIO debounce time.
+ * If a board does not define the get_pendown_state() function, then
+ * the ads7846 driver will setup the pendown GPIO itself.
+ */
+ if (board_pdata && board_pdata->get_pendown_state) {
+ err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown");
+ if (err) {
+ pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err);
+ return;
+ }
- if (gpio_debounce)
- gpio_set_debounce(gpio_pendown, gpio_debounce);
+ if (gpio_debounce)
+ gpio_set_debounce(gpio_pendown, gpio_debounce);
+
+ gpio_export(gpio_pendown, 0);
+ }
spi_bi->bus_num = bus_num;
spi_bi->irq = gpio_to_irq(gpio_pendown);
+ ads7846_config.gpio_pendown = gpio_pendown;
+
if (board_pdata) {
board_pdata->gpio_pendown = gpio_pendown;
+ board_pdata->gpio_pendown_debounce = gpio_debounce;
spi_bi->platform_data = board_pdata;
- if (board_pdata->get_pendown_state)
- gpio_export(gpio_pendown, 0);
- } else {
- ads7846_config.gpio_pendown = gpio_pendown;
}
- if (!board_pdata || (board_pdata && !board_pdata->get_pendown_state))
- gpio_free(gpio_pendown);
-
spi_register_board_info(&ads7846_spi_board_info, 1);
}
#else
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index cba60e05e32..c72b5a72772 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -19,6 +19,7 @@
#include <linux/of.h>
#include <linux/pinctrl/machine.h>
#include <linux/platform_data/omap4-keypad.h>
+#include <linux/platform_data/omap_ocp2scp.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
@@ -613,6 +614,83 @@ static void omap_init_vout(void)
static inline void omap_init_vout(void) {}
#endif
+#if defined(CONFIG_OMAP_OCP2SCP) || defined(CONFIG_OMAP_OCP2SCP_MODULE)
+static int count_ocp2scp_devices(struct omap_ocp2scp_dev *ocp2scp_dev)
+{
+ int cnt = 0;
+
+ while (ocp2scp_dev->drv_name != NULL) {
+ cnt++;
+ ocp2scp_dev++;
+ }
+
+ return cnt;
+}
+
+static void omap_init_ocp2scp(void)
+{
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+ int bus_id = -1, dev_cnt = 0, i;
+ struct omap_ocp2scp_dev *ocp2scp_dev;
+ const char *oh_name, *name;
+ struct omap_ocp2scp_platform_data *pdata;
+
+ if (!cpu_is_omap44xx())
+ return;
+
+ oh_name = "ocp2scp_usb_phy";
+ name = "omap-ocp2scp";
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("%s: could not find omap_hwmod for %s\n", __func__,
+ oh_name);
+ return;
+ }
+
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ pr_err("%s: No memory for ocp2scp pdata\n", __func__);
+ return;
+ }
+
+ ocp2scp_dev = oh->dev_attr;
+ dev_cnt = count_ocp2scp_devices(ocp2scp_dev);
+
+ if (!dev_cnt) {
+ pr_err("%s: No devices connected to ocp2scp\n", __func__);
+ kfree(pdata);
+ return;
+ }
+
+ pdata->devices = kzalloc(sizeof(struct omap_ocp2scp_dev *)
+ * dev_cnt, GFP_KERNEL);
+ if (!pdata->devices) {
+ pr_err("%s: No memory for ocp2scp pdata devices\n", __func__);
+ kfree(pdata);
+ return;
+ }
+
+ for (i = 0; i < dev_cnt; i++, ocp2scp_dev++)
+ pdata->devices[i] = ocp2scp_dev;
+
+ pdata->dev_cnt = dev_cnt;
+
+ pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL,
+ 0, false);
+ if (IS_ERR(pdev)) {
+ pr_err("Could not build omap_device for %s %s\n",
+ name, oh_name);
+ kfree(pdata->devices);
+ kfree(pdata);
+ return;
+ }
+}
+#else
+static inline void omap_init_ocp2scp(void) { }
+#endif
+
/*-------------------------------------------------------------------------*/
static int __init omap2_init_devices(void)
@@ -640,6 +718,7 @@ static int __init omap2_init_devices(void)
omap_init_sham();
omap_init_aes();
omap_init_vout();
+ omap_init_ocp2scp();
return 0;
}
diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c
index 72e0f01b715..49a7ffb716a 100644
--- a/arch/arm/mach-omap2/drm.c
+++ b/arch/arm/mach-omap2/drm.c
@@ -23,15 +23,20 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <linux/platform_data/omap_drm.h>
#include <plat/omap_device.h>
#include <plat/omap_hwmod.h>
+#include <plat/cpu.h>
#if defined(CONFIG_DRM_OMAP) || (CONFIG_DRM_OMAP_MODULE)
+static struct omap_drm_platform_data platform_data;
+
static struct platform_device omap_drm_device = {
.dev = {
.coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &platform_data,
},
.name = "omapdrm",
.id = 0,
@@ -52,6 +57,8 @@ static int __init omap_init_drm(void)
oh->name);
}
+ platform_data.omaprev = GET_OMAP_REVISION();
+
return platform_device_register(&omap_drm_device);
}
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index b969ab1d258..87cc6d058de 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -422,6 +422,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)
}
/**
+ * _wait_softreset_complete - wait for an OCP softreset to complete
+ * @oh: struct omap_hwmod * to wait on
+ *
+ * Wait until the IP block represented by @oh reports that its OCP
+ * softreset is complete. This can be triggered by software (see
+ * _ocp_softreset()) or by hardware upon returning from off-mode (one
+ * example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT
+ * microseconds. Returns the number of microseconds waited.
+ */
+static int _wait_softreset_complete(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_class_sysconfig *sysc;
+ u32 softrst_mask;
+ int c = 0;
+
+ sysc = oh->class->sysc;
+
+ if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
+ omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs)
+ & SYSS_RESETDONE_MASK),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+ else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
+ softrst_mask = (0x1 << sysc->sysc_fields->srst_shift);
+ omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs)
+ & softrst_mask),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+ }
+
+ return c;
+}
+
+/**
* _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v
* @oh: struct omap_hwmod *
*
@@ -1282,6 +1314,18 @@ static void _enable_sysc(struct omap_hwmod *oh)
if (!oh->class->sysc)
return;
+ /*
+ * Wait until reset has completed, this is needed as the IP
+ * block is reset automatically by hardware in some cases
+ * (off-mode for example), and the drivers require the
+ * IP to be ready when they access it
+ */
+ if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
+ _enable_optional_clocks(oh);
+ _wait_softreset_complete(oh);
+ if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
+ _disable_optional_clocks(oh);
+
v = oh->_sysc_cache;
sf = oh->class->sysc->sysc_flags;
@@ -1804,7 +1848,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh)
*/
static int _ocp_softreset(struct omap_hwmod *oh)
{
- u32 v, softrst_mask;
+ u32 v;
int c = 0;
int ret = 0;
@@ -1834,19 +1878,7 @@ static int _ocp_softreset(struct omap_hwmod *oh)
if (oh->class->sysc->srst_udelay)
udelay(oh->class->sysc->srst_udelay);
- if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
- omap_test_timeout((omap_hwmod_read(oh,
- oh->class->sysc->syss_offs)
- & SYSS_RESETDONE_MASK),
- MAX_MODULE_SOFTRESET_WAIT, c);
- else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
- softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
- omap_test_timeout(!(omap_hwmod_read(oh,
- oh->class->sysc->sysc_offs)
- & softrst_mask),
- MAX_MODULE_SOFTRESET_WAIT, c);
- }
-
+ c = _wait_softreset_complete(oh);
if (c == MAX_MODULE_SOFTRESET_WAIT)
pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
oh->name, MAX_MODULE_SOFTRESET_WAIT);
@@ -2352,6 +2384,9 @@ static int __init _setup_reset(struct omap_hwmod *oh)
if (oh->_state != _HWMOD_STATE_INITIALIZED)
return -EINVAL;
+ if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK)
+ return -EPERM;
+
if (oh->rst_lines_cnt == 0) {
r = _enable(oh);
if (r) {
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 652d0285bd6..0b1249e0039 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -21,6 +21,7 @@
#include <linux/io.h>
#include <linux/platform_data/gpio-omap.h>
#include <linux/power/smartreflex.h>
+#include <linux/platform_data/omap_ocp2scp.h>
#include <plat/omap_hwmod.h>
#include <plat/i2c.h>
@@ -2125,6 +2126,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = {
.name = "mcpdm",
.class = &omap44xx_mcpdm_hwmod_class,
.clkdm_name = "abe_clkdm",
+ /*
+ * It's suspected that the McPDM requires an off-chip main
+ * functional clock, controlled via I2C. This IP block is
+ * currently reset very early during boot, before I2C is
+ * available, so it doesn't seem that we have any choice in
+ * the kernel other than to avoid resetting it.
+ */
+ .flags = HWMOD_EXT_OPT_MAIN_CLK,
.mpu_irqs = omap44xx_mcpdm_irqs,
.sdma_reqs = omap44xx_mcpdm_sdma_reqs,
.main_clk = "mcpdm_fck",
@@ -2681,6 +2690,32 @@ static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = {
.sysc = &omap44xx_ocp2scp_sysc,
};
+/* ocp2scp dev_attr */
+static struct resource omap44xx_usb_phy_and_pll_addrs[] = {
+ {
+ .name = "usb_phy",
+ .start = 0x4a0ad080,
+ .end = 0x4a0ae000,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* XXX: Remove this once control module driver is in place */
+ .name = "ctrl_dev",
+ .start = 0x4a002300,
+ .end = 0x4a002303,
+ .flags = IORESOURCE_MEM,
+ },
+ { }
+};
+
+static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = {
+ {
+ .drv_name = "omap-usb2",
+ .res = omap44xx_usb_phy_and_pll_addrs,
+ },
+ { }
+};
+
/* ocp2scp_usb_phy */
static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
.name = "ocp2scp_usb_phy",
@@ -2694,6 +2729,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
.modulemode = MODULEMODE_HWCTRL,
},
},
+ .dev_attr = ocp2scp_dev_attr,
};
/*
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index 635e109f5ad..a256135d8e4 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -73,6 +73,7 @@ void __init omap4_pmic_init(const char *pmic_type,
{
/* PMIC part*/
omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);
+ omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT);
omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data);
/* Register additional devices on i2c1 bus if needed */
@@ -366,7 +367,7 @@ static struct regulator_init_data omap4_clk32kg_idata = {
};
static struct regulator_consumer_supply omap4_vdd1_supply[] = {
- REGULATOR_SUPPLY("vcc", "mpu.0"),
+ REGULATOR_SUPPLY("vcc", "cpu0"),
};
static struct regulator_consumer_supply omap4_vdd2_supply[] = {
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 880249b1701..75878c37959 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -264,7 +264,7 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)
if (initialized) {
if (voltdm->pmic->i2c_high_speed != i2c_high_speed)
- pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).",
+ pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).\n",
__func__, voltdm->name, i2c_high_speed);
return;
}
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index 5ecbd17b564..e2c6391863f 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -28,6 +28,7 @@
#include <linux/mfd/asic3.h>
#include <linux/mtd/physmap.h>
#include <linux/pda_power.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/gpio-regulator.h>
@@ -556,7 +557,7 @@ static struct platform_device hx4700_lcd = {
*/
static struct platform_pwm_backlight_data backlight_data = {
- .pwm_id = 1,
+ .pwm_id = -1, /* Superseded by pwm_lookup */
.max_brightness = 200,
.dft_brightness = 100,
.pwm_period_ns = 30923,
@@ -571,6 +572,10 @@ static struct platform_device backlight = {
},
};
+static struct pwm_lookup hx4700_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL),
+};
+
/*
* USB "Transceiver"
*/
@@ -872,6 +877,7 @@ static void __init hx4700_init(void)
pxa_set_stuart_info(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
+ pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup));
pxa_set_ficp_info(&ficp_info);
pxa27x_set_i2c_power_info(NULL);
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 438f02fe122..842596d4d31 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -86,10 +86,7 @@ static void spitz_discharge1(int on)
gpio_set_value(SPITZ_GPIO_LED_GREEN, on);
}
-static unsigned long gpio18_config[] = {
- GPIO18_RDY,
- GPIO18_GPIO,
-};
+static unsigned long gpio18_config = GPIO18_GPIO;
static void spitz_presuspend(void)
{
@@ -112,7 +109,7 @@ static void spitz_presuspend(void)
PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0);
- pxa2xx_mfp_config(&gpio18_config[0], 1);
+ pxa2xx_mfp_config(&gpio18_config, 1);
gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown");
gpio_free(18);
@@ -131,7 +128,6 @@ static void spitz_presuspend(void)
static void spitz_postsuspend(void)
{
- pxa2xx_mfp_config(&gpio18_config[1], 1);
}
static int spitz_should_wakeup(unsigned int resume_on_alarm)
diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
index 0a43f3189c2..7a05de794a8 100644
--- a/arch/arm/mach-shmobile/board-kzm9g.c
+++ b/arch/arm/mach-shmobile/board-kzm9g.c
@@ -548,7 +548,6 @@ static struct platform_device fsi_ak4648_device = {
/* I2C */
static struct pcf857x_platform_data pcf8575_pdata = {
.gpio_base = GPIO_PCF8575_BASE,
- .irq = intcs_evt2irq(0x3260), /* IRQ19 */
};
static struct i2c_board_info i2c0_devices[] = {
@@ -570,6 +569,7 @@ static struct i2c_board_info i2c1_devices[] = {
static struct i2c_board_info i2c3_devices[] = {
{
I2C_BOARD_INFO("pcf8575", 0x20),
+ .irq = intcs_evt2irq(0x3260), /* IRQ19 */
.platform_data = &pcf8575_pdata,
},
};
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index b8efac4daed..ece8a2dfb81 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -1445,8 +1445,6 @@ static struct platform_device pinctrl_device = {
static struct u300_gpio_platform u300_gpio_plat = {
.ports = 7,
.gpio_base = 0,
- .gpio_irq_base = IRQ_U300_GPIO_BASE,
- .pinctrl_device = &pinctrl_device,
};
static struct platform_device gpio_device = {
@@ -1590,6 +1588,7 @@ static struct platform_device *platform_devs[] __initdata = {
&i2c1_device,
&keypad_device,
&rtc_device,
+ &pinctrl_device,
&gpio_device,
&nand_device,
&wdog_device,
@@ -1804,7 +1803,7 @@ MACHINE_START(U300, "Ericsson AB U335 S335/B335 Prototype Board")
/* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */
.atag_offset = 0x100,
.map_io = u300_map_io,
- .nr_irqs = NR_IRQS_U300,
+ .nr_irqs = 0,
.init_irq = u300_init_irq,
.handle_irq = vic_handle_irq,
.timer = &u300_timer,
diff --git a/arch/arm/mach-u300/include/mach/irqs.h b/arch/arm/mach-u300/include/mach/irqs.h
index e27425a63fa..21d5e76a6cd 100644
--- a/arch/arm/mach-u300/include/mach/irqs.h
+++ b/arch/arm/mach-u300/include/mach/irqs.h
@@ -12,79 +12,69 @@
#ifndef __MACH_IRQS_H
#define __MACH_IRQS_H
-#define IRQ_U300_INTCON0_START 1
-#define IRQ_U300_INTCON1_START 33
+#define IRQ_U300_INTCON0_START 32
+#define IRQ_U300_INTCON1_START 64
/* These are on INTCON0 - 30 lines */
-#define IRQ_U300_IRQ0_EXT 1
-#define IRQ_U300_IRQ1_EXT 2
-#define IRQ_U300_DMA 3
-#define IRQ_U300_VIDEO_ENC_0 4
-#define IRQ_U300_VIDEO_ENC_1 5
-#define IRQ_U300_AAIF_RX 6
-#define IRQ_U300_AAIF_TX 7
-#define IRQ_U300_AAIF_VGPIO 8
-#define IRQ_U300_AAIF_WAKEUP 9
-#define IRQ_U300_PCM_I2S0_FRAME 10
-#define IRQ_U300_PCM_I2S0_FIFO 11
-#define IRQ_U300_PCM_I2S1_FRAME 12
-#define IRQ_U300_PCM_I2S1_FIFO 13
-#define IRQ_U300_XGAM_GAMCON 14
-#define IRQ_U300_XGAM_CDI 15
-#define IRQ_U300_XGAM_CDICON 16
-#define IRQ_U300_XGAM_PDI 18
-#define IRQ_U300_XGAM_PDICON 19
-#define IRQ_U300_XGAM_GAMEACC 20
-#define IRQ_U300_XGAM_MCIDCT 21
-#define IRQ_U300_APEX 22
-#define IRQ_U300_UART0 23
-#define IRQ_U300_SPI 24
-#define IRQ_U300_TIMER_APP_OS 25
-#define IRQ_U300_TIMER_APP_DD 26
-#define IRQ_U300_TIMER_APP_GP1 27
-#define IRQ_U300_TIMER_APP_GP2 28
-#define IRQ_U300_TIMER_OS 29
-#define IRQ_U300_TIMER_MS 30
-#define IRQ_U300_KEYPAD_KEYBF 31
-#define IRQ_U300_KEYPAD_KEYBR 32
+#define IRQ_U300_IRQ0_EXT 32
+#define IRQ_U300_IRQ1_EXT 33
+#define IRQ_U300_DMA 34
+#define IRQ_U300_VIDEO_ENC_0 35
+#define IRQ_U300_VIDEO_ENC_1 36
+#define IRQ_U300_AAIF_RX 37
+#define IRQ_U300_AAIF_TX 38
+#define IRQ_U300_AAIF_VGPIO 39
+#define IRQ_U300_AAIF_WAKEUP 40
+#define IRQ_U300_PCM_I2S0_FRAME 41
+#define IRQ_U300_PCM_I2S0_FIFO 42
+#define IRQ_U300_PCM_I2S1_FRAME 43
+#define IRQ_U300_PCM_I2S1_FIFO 44
+#define IRQ_U300_XGAM_GAMCON 45
+#define IRQ_U300_XGAM_CDI 46
+#define IRQ_U300_XGAM_CDICON 47
+#define IRQ_U300_XGAM_PDI 49
+#define IRQ_U300_XGAM_PDICON 50
+#define IRQ_U300_XGAM_GAMEACC 51
+#define IRQ_U300_XGAM_MCIDCT 52
+#define IRQ_U300_APEX 53
+#define IRQ_U300_UART0 54
+#define IRQ_U300_SPI 55
+#define IRQ_U300_TIMER_APP_OS 56
+#define IRQ_U300_TIMER_APP_DD 57
+#define IRQ_U300_TIMER_APP_GP1 58
+#define IRQ_U300_TIMER_APP_GP2 59
+#define IRQ_U300_TIMER_OS 60
+#define IRQ_U300_TIMER_MS 61
+#define IRQ_U300_KEYPAD_KEYBF 62
+#define IRQ_U300_KEYPAD_KEYBR 63
/* These are on INTCON1 - 32 lines */
-#define IRQ_U300_GPIO_PORT0 33
-#define IRQ_U300_GPIO_PORT1 34
-#define IRQ_U300_GPIO_PORT2 35
+#define IRQ_U300_GPIO_PORT0 64
+#define IRQ_U300_GPIO_PORT1 65
+#define IRQ_U300_GPIO_PORT2 66
/* These are for DB3150, DB3200 and DB3350 */
-#define IRQ_U300_WDOG 36
-#define IRQ_U300_EVHIST 37
-#define IRQ_U300_MSPRO 38
-#define IRQ_U300_MMCSD_MCIINTR0 39
-#define IRQ_U300_MMCSD_MCIINTR1 40
-#define IRQ_U300_I2C0 41
-#define IRQ_U300_I2C1 42
-#define IRQ_U300_RTC 43
-#define IRQ_U300_NFIF 44
-#define IRQ_U300_NFIF2 45
+#define IRQ_U300_WDOG 67
+#define IRQ_U300_EVHIST 68
+#define IRQ_U300_MSPRO 69
+#define IRQ_U300_MMCSD_MCIINTR0 70
+#define IRQ_U300_MMCSD_MCIINTR1 71
+#define IRQ_U300_I2C0 72
+#define IRQ_U300_I2C1 73
+#define IRQ_U300_RTC 74
+#define IRQ_U300_NFIF 75
+#define IRQ_U300_NFIF2 76
/* The DB3350-specific interrupt lines */
-#define IRQ_U300_ISP_F0 46
-#define IRQ_U300_ISP_F1 47
-#define IRQ_U300_ISP_F2 48
-#define IRQ_U300_ISP_F3 49
-#define IRQ_U300_ISP_F4 50
-#define IRQ_U300_GPIO_PORT3 51
-#define IRQ_U300_SYSCON_PLL_LOCK 52
-#define IRQ_U300_UART1 53
-#define IRQ_U300_GPIO_PORT4 54
-#define IRQ_U300_GPIO_PORT5 55
-#define IRQ_U300_GPIO_PORT6 56
-#define U300_VIC_IRQS_END 57
-
-/* Maximum 8*7 GPIO lines */
-#ifdef CONFIG_PINCTRL_COH901
-#define IRQ_U300_GPIO_BASE (U300_VIC_IRQS_END)
-#define IRQ_U300_GPIO_END (IRQ_U300_GPIO_BASE + 56)
-#else
-#define IRQ_U300_GPIO_END (U300_VIC_IRQS_END)
-#endif
-
-#define NR_IRQS_U300 (IRQ_U300_GPIO_END - IRQ_U300_INTCON0_START)
+#define IRQ_U300_ISP_F0 77
+#define IRQ_U300_ISP_F1 78
+#define IRQ_U300_ISP_F2 79
+#define IRQ_U300_ISP_F3 80
+#define IRQ_U300_ISP_F4 81
+#define IRQ_U300_GPIO_PORT3 82
+#define IRQ_U300_SYSCON_PLL_LOCK 83
+#define IRQ_U300_UART1 84
+#define IRQ_U300_GPIO_PORT4 85
+#define IRQ_U300_GPIO_PORT5 86
+#define IRQ_U300_GPIO_PORT6 87
+#define U300_VIC_IRQS_END 88
#endif
diff --git a/arch/arm/mach-ux500/board-mop500-audio.c b/arch/arm/mach-ux500/board-mop500-audio.c
index 070629a9562..33631c9f121 100644
--- a/arch/arm/mach-ux500/board-mop500-audio.c
+++ b/arch/arm/mach-ux500/board-mop500-audio.c
@@ -7,9 +7,8 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/gpio.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
-#include <plat/gpio-nomadik.h>
-#include <plat/pincfg.h>
#include <plat/ste_dma40.h>
#include <mach/devices.h>
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c
index a267c6d30e3..c34d4efd0d5 100644
--- a/arch/arm/mach-ux500/board-mop500-pins.c
+++ b/arch/arm/mach-ux500/board-mop500-pins.c
@@ -9,10 +9,9 @@
#include <linux/bug.h>
#include <linux/string.h>
#include <linux/pinctrl/machine.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
#include <asm/mach-types.h>
-#include <plat/pincfg.h>
-#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index 416d436111f..0a3dd601a40 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -37,13 +37,13 @@
#include <linux/of_platform.h>
#include <linux/leds.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
#include <plat/ste_dma40.h>
-#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
#include <mach/setup.h>
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index bcdfe6b1d45..91f028c1264 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -17,14 +17,14 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/mfd/abx500/ab8500.h>
+#include <linux/platform_data/usb-musb-ux500.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
#include <asm/pmu.h>
#include <asm/mach/map.h>
-#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
#include <mach/setup.h>
#include <mach/devices.h>
-#include <linux/platform_data/usb-musb-ux500.h>
#include <mach/db8500-regs.h>
#include "devices-db8500.h"
@@ -158,7 +158,7 @@ static void __init db8500_add_gpios(struct device *parent)
dbx500_add_gpios(parent, ARRAY_AND_SIZE(db8500_gpio_base),
IRQ_DB8500_GPIO0, &pdata);
- dbx500_add_pinctrl(parent, "pinctrl-db8500");
+ dbx500_add_pinctrl(parent, "pinctrl-db8500", U8500_PRCMU_BASE);
}
static int usb_db8500_rx_dma_cfg[] = {
@@ -214,9 +214,6 @@ struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500)
db8500_add_gpios(parent);
db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
- platform_device_register_data(parent,
- "cpufreq-u8500", -1, NULL, 0);
-
for (i = 0; i < ARRAY_SIZE(platform_devs); i++)
platform_devs[i]->dev.parent = parent;
@@ -236,9 +233,6 @@ struct device * __init u8500_of_init_devices(void)
db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
- platform_device_register_data(parent,
- "cpufreq-u8500", -1, NULL, 0);
-
u8500_dma40_device.dev.parent = parent;
/*
diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c
index dfdd4a54668..692a77a1c15 100644
--- a/arch/arm/mach-ux500/devices-common.c
+++ b/arch/arm/mach-ux500/devices-common.c
@@ -11,8 +11,7 @@
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
-
-#include <plat/gpio-nomadik.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
#include <mach/hardware.h>
diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h
index 7fbf0ba336e..96fa4ac89e2 100644
--- a/arch/arm/mach-ux500/devices-common.h
+++ b/arch/arm/mach-ux500/devices-common.h
@@ -129,12 +129,18 @@ 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)
+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);
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 560e0df728f..359f782c747 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -589,7 +589,7 @@ void __init v2m_dt_init_early(void)
return;
/* Confirm board type against DT property, if available */
- if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) {
+ if (of_property_read_u32(of_allnodes, "arm,hbi", &dt_hbi) == 0) {
int site = v2m_get_master_site();
u32 id = readl(v2m_sysreg_base + (site == SYS_CFG_SITE_DB2 ?
V2M_SYS_PROCID1 : V2M_SYS_PROCID0));
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index ce8cb1970d7..10062ceadd1 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -11,18 +11,6 @@
#include <linux/random.h>
#include <asm/cachetype.h>
-static inline unsigned long COLOUR_ALIGN_DOWN(unsigned long addr,
- unsigned long pgoff)
-{
- unsigned long base = addr & ~(SHMLBA-1);
- unsigned long off = (pgoff << PAGE_SHIFT) & (SHMLBA-1);
-
- if (base + off <= addr)
- return base + off;
-
- return base - off;
-}
-
#define COLOUR_ALIGN(addr,pgoff) \
((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \
(((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
@@ -69,9 +57,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
- unsigned long start_addr;
int do_align = 0;
int aliasing = cache_is_vipt_aliasing();
+ struct vm_unmapped_area_info info;
/*
* We only need to do colour alignment if either the I or D
@@ -104,46 +92,14 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
(!vma || addr + len <= vma->vm_start))
return addr;
}
- if (len > mm->cached_hole_size) {
- start_addr = addr = mm->free_area_cache;
- } else {
- start_addr = addr = mm->mmap_base;
- mm->cached_hole_size = 0;
- }
-full_search:
- if (do_align)
- addr = COLOUR_ALIGN(addr, pgoff);
- else
- addr = PAGE_ALIGN(addr);
-
- for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
- /* At this point: (!vma || addr < vma->vm_end). */
- if (TASK_SIZE - len < addr) {
- /*
- * Start a new search - just in case we missed
- * some holes.
- */
- if (start_addr != TASK_UNMAPPED_BASE) {
- start_addr = addr = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = 0;
- goto full_search;
- }
- return -ENOMEM;
- }
- if (!vma || addr + len <= vma->vm_start) {
- /*
- * Remember the place where we stopped the search:
- */
- mm->free_area_cache = addr + len;
- return addr;
- }
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
- addr = vma->vm_end;
- if (do_align)
- addr = COLOUR_ALIGN(addr, pgoff);
- }
+ info.flags = 0;
+ info.length = len;
+ info.low_limit = mm->mmap_base;
+ info.high_limit = TASK_SIZE;
+ info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+ return vm_unmapped_area(&info);
}
unsigned long
@@ -156,6 +112,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
unsigned long addr = addr0;
int do_align = 0;
int aliasing = cache_is_vipt_aliasing();
+ struct vm_unmapped_area_info info;
/*
* We only need to do colour alignment if either the I or D
@@ -187,70 +144,27 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
return addr;
}
- /* check if free_area_cache is useful for us */
- if (len <= mm->cached_hole_size) {
- mm->cached_hole_size = 0;
- mm->free_area_cache = mm->mmap_base;
- }
-
- /* either no address requested or can't fit in requested address hole */
- addr = mm->free_area_cache;
- if (do_align) {
- unsigned long base = COLOUR_ALIGN_DOWN(addr - len, pgoff);
- addr = base + len;
- }
-
- /* make sure it can fit in the remaining address space */
- if (addr > len) {
- vma = find_vma(mm, addr-len);
- if (!vma || addr <= vma->vm_start)
- /* remember the address as a hint for next time */
- return (mm->free_area_cache = addr-len);
- }
-
- if (mm->mmap_base < len)
- goto bottomup;
-
- addr = mm->mmap_base - len;
- if (do_align)
- addr = COLOUR_ALIGN_DOWN(addr, pgoff);
-
- do {
- /*
- * Lookup failure means no vma is above this address,
- * else if new region fits below vma->vm_start,
- * return with success:
- */
- vma = find_vma(mm, addr);
- if (!vma || addr+len <= vma->vm_start)
- /* remember the address as a hint for next time */
- return (mm->free_area_cache = addr);
+ info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+ info.length = len;
+ info.low_limit = PAGE_SIZE;
+ info.high_limit = mm->mmap_base;
+ info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+ addr = vm_unmapped_area(&info);
- /* remember the largest hole we saw so far */
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
-
- /* try just below the current vma->vm_start */
- addr = vma->vm_start - len;
- if (do_align)
- addr = COLOUR_ALIGN_DOWN(addr, pgoff);
- } while (len < vma->vm_start);
-
-bottomup:
/*
* A failed mmap() very likely causes application failure,
* so fall back to the bottom-up function here. This scenario
* can happen with large stack limits and large mmap()
* allocations.
*/
- mm->cached_hole_size = ~0UL;
- mm->free_area_cache = TASK_UNMAPPED_BASE;
- addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
- /*
- * Restore the topdown base:
- */
- mm->free_area_cache = mm->mmap_base;
- mm->cached_hole_size = ~0UL;
+ if (addr & ~PAGE_MASK) {
+ VM_BUG_ON(addr != -ENOMEM);
+ info.flags = 0;
+ info.low_limit = mm->mmap_base;
+ info.high_limit = TASK_SIZE;
+ addr = vm_unmapped_area(&info);
+ }
return addr;
}
@@ -279,7 +193,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
* You really shouldn't be using read() or write() on /dev/mem. This
* might go away in the future.
*/
-int valid_phys_addr_range(unsigned long addr, size_t size)
+int valid_phys_addr_range(phys_addr_t addr, size_t size)
{
if (addr < PHYS_OFFSET)
return 0;
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 86b8b480634..09c5233f4df 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -89,7 +89,7 @@ ENTRY(cpu_v6_dcache_clean_area)
mov pc, lr
/*
- * cpu_arm926_switch_mm(pgd_phys, tsk)
+ * cpu_v6_switch_mm(pgd_phys, tsk)
*
* Set the translation table base pointer to be pgd_phys
*
diff --git a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
deleted file mode 100644
index c08a54d9d88..00000000000
--- a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Structures and registers for GPIO access in the Nomadik SoC
- *
- * Copyright (C) 2008 STMicroelectronics
- * Author: Prafulla WADASKAR <prafulla.wadaskar@st.com>
- * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
- *
- * 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 __PLAT_NOMADIK_GPIO
-#define __PLAT_NOMADIK_GPIO
-
-/*
- * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
- * the "gpio" namespace for generic and cross-machine functions
- */
-
-/* Register in the logic block */
-#define NMK_GPIO_DAT 0x00
-#define NMK_GPIO_DATS 0x04
-#define NMK_GPIO_DATC 0x08
-#define NMK_GPIO_PDIS 0x0c
-#define NMK_GPIO_DIR 0x10
-#define NMK_GPIO_DIRS 0x14
-#define NMK_GPIO_DIRC 0x18
-#define NMK_GPIO_SLPC 0x1c
-#define NMK_GPIO_AFSLA 0x20
-#define NMK_GPIO_AFSLB 0x24
-#define NMK_GPIO_LOWEMI 0x28
-
-#define NMK_GPIO_RIMSC 0x40
-#define NMK_GPIO_FIMSC 0x44
-#define NMK_GPIO_IS 0x48
-#define NMK_GPIO_IC 0x4c
-#define NMK_GPIO_RWIMSC 0x50
-#define NMK_GPIO_FWIMSC 0x54
-#define NMK_GPIO_WKS 0x58
-
-/* Alternate functions: function C is set in hw by setting both A and B */
-#define NMK_GPIO_ALT_GPIO 0
-#define NMK_GPIO_ALT_A 1
-#define NMK_GPIO_ALT_B 2
-#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
-
-#define NMK_GPIO_ALT_CX_SHIFT 2
-#define NMK_GPIO_ALT_C1 ((1<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-#define NMK_GPIO_ALT_C2 ((2<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-#define NMK_GPIO_ALT_C3 ((3<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-#define NMK_GPIO_ALT_C4 ((4<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-
-/* Pull up/down values */
-enum nmk_gpio_pull {
- NMK_GPIO_PULL_NONE,
- NMK_GPIO_PULL_UP,
- NMK_GPIO_PULL_DOWN,
-};
-
-/* Sleep mode */
-enum nmk_gpio_slpm {
- NMK_GPIO_SLPM_INPUT,
- NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
- NMK_GPIO_SLPM_NOCHANGE,
- NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
-};
-
-extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode);
-extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull);
-#ifdef CONFIG_PINCTRL_NOMADIK
-extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
-#else
-static inline int nmk_gpio_set_mode(int gpio, int gpio_mode)
-{
- return -ENODEV;
-}
-#endif
-extern int nmk_gpio_get_mode(int gpio);
-
-extern void nmk_gpio_wakeups_suspend(void);
-extern void nmk_gpio_wakeups_resume(void);
-
-extern void nmk_gpio_clocks_enable(void);
-extern void nmk_gpio_clocks_disable(void);
-
-extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up);
-
-/*
- * Platform data to register a block: only the initial gpio/irq number.
- */
-struct nmk_gpio_platform_data {
- char *name;
- int first_gpio;
- int first_irq;
- int num_gpio;
- u32 (*get_secondary_status)(unsigned int bank);
- void (*set_ioforce)(bool enable);
- bool supports_sleepmode;
-};
-
-#endif /* __PLAT_NOMADIK_GPIO */
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index a5683a84c6e..6013831a043 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -26,12 +26,14 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
+#include <linux/i2c-omap.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <mach/irqs.h>
#include <plat/i2c.h>
+#include <plat/omap-pm.h>
#include <plat/omap_device.h>
#define OMAP_I2C_SIZE 0x3f
@@ -127,6 +129,16 @@ static inline int omap1_i2c_add_bus(int bus_id)
#ifdef CONFIG_ARCH_OMAP2PLUS
+/*
+ * XXX This function is a temporary compatibility wrapper - only
+ * needed until the I2C driver can be converted to call
+ * omap_pm_set_max_dev_wakeup_lat() and handle a return code.
+ */
+static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
+{
+ omap_pm_set_max_mpu_wakeup_lat(dev, t);
+}
+
static inline int omap2_i2c_add_bus(int bus_id)
{
int l;
@@ -158,6 +170,15 @@ static inline int omap2_i2c_add_bus(int bus_id)
dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr;
pdata->flags = dev_attr->flags;
+ /*
+ * When waiting for completion of a i2c transfer, we need to
+ * set a wake up latency constraint for the MPU. This is to
+ * ensure quick enough wakeup from idle, when transfer
+ * completes.
+ * Only omap3 has support for constraints
+ */
+ if (cpu_is_omap34xx())
+ pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
pdev = omap_device_build(name, bus_id, oh, pdata,
sizeof(struct omap_i2c_bus_platform_data),
NULL, 0, 0);
diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h
index 8b4e4f2da2f..346af5b490b 100644
--- a/arch/arm/plat-omap/include/plat/mmc.h
+++ b/arch/arm/plat-omap/include/plat/mmc.h
@@ -126,6 +126,7 @@ struct omap_mmc_platform_data {
/* we can put the features above into this variable */
#define HSMMC_HAS_PBIAS (1 << 0)
#define HSMMC_HAS_UPDATED_RESET (1 << 1)
+#define HSMMC_HAS_HSPE_SUPPORT (1 << 2)
unsigned features;
int switch_pin; /* gpio (card detect) */
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index b3349f7b1a2..1db02943802 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -443,6 +443,11 @@ struct omap_hwmod_omap4_prcm {
* in order to complete the reset. Optional clocks will be disabled
* again after the reset.
* HWMOD_16BIT_REG: Module has 16bit registers
+ * HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for
+ * this IP block comes from an off-chip source and is not always
+ * enabled. This prevents the hwmod code from being able to
+ * enable and reset the IP block early. XXX Eventually it should
+ * be possible to query the clock framework for this information.
*/
#define HWMOD_SWSUP_SIDLE (1 << 0)
#define HWMOD_SWSUP_MSTANDBY (1 << 1)
@@ -453,6 +458,7 @@ struct omap_hwmod_omap4_prcm {
#define HWMOD_NO_IDLEST (1 << 6)
#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7)
#define HWMOD_16BIT_REG (1 << 8)
+#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9)
/*
* omap_hwmod._int_flags definitions
diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
index 65fce44dce3..b780470d03e 100644
--- a/arch/arm/plat-omap/include/plat/serial.h
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -109,15 +109,6 @@
#define OMAP5UART4 OMAP4UART4
#define ZOOM_UART 95 /* Only on zoom2/3 */
-/* This is only used by 8250.c for omap1510 */
-#define is_omap_port(pt) ({int __ret = 0; \
- if ((pt)->port.mapbase == OMAP1_UART1_BASE || \
- (pt)->port.mapbase == OMAP1_UART2_BASE || \
- (pt)->port.mapbase == OMAP1_UART3_BASE) \
- __ret = 1; \
- __ret; \
- })
-
#ifndef __ASSEMBLER__
struct omap_board_data;
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index db98e7021f0..0abd1c46988 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -473,12 +473,13 @@ int s3c2410_dma_enqueue(enum dma_ch channel, void *id,
pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
chan->number, __func__, buf);
- if (chan->end == NULL)
+ if (chan->end == NULL) {
pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
chan->number, __func__, chan);
-
- chan->end->next = buf;
- chan->end = buf;
+ } else {
+ chan->end->next = buf;
+ chan->end = buf;
+ }
}
/* if necessary, update the next buffer field */
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
index f8db7b2deb3..87dbd81bdf5 100644
--- a/arch/arm/plat-spear/Kconfig
+++ b/arch/arm/plat-spear/Kconfig
@@ -12,6 +12,7 @@ config ARCH_SPEAR13XX
bool "ST SPEAr13xx with Device Tree"
select ARM_GIC
select CPU_V7
+ select GPIO_SPEAR_SPICS
select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
select PINCTRL
diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile
index cd60a81163e..32d05c8219d 100644
--- a/arch/arm/tools/Makefile
+++ b/arch/arm/tools/Makefile
@@ -5,6 +5,6 @@
#
include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types
- $(kecho) ' Generating $@'
+ @$(kecho) ' Generating $@'
@mkdir -p $(dir $@)
$(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; }
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 364191f3be4..c95c5cb212f 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -41,20 +41,24 @@ libs-y := arch/arm64/lib/ $(libs-y)
libs-y += $(LIBGCC)
# Default target when executing plain make
-KBUILD_IMAGE := Image.gz
+KBUILD_IMAGE := Image.gz
+KBUILD_DTBS := dtbs
-all: $(KBUILD_IMAGE)
+all: $(KBUILD_IMAGE) $(KBUILD_DTBS)
boot := arch/arm64/boot
Image Image.gz: vmlinux
- $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
zinstall install: vmlinux
- $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
+ $(Q)$(MAKE) $(build)=$(boot) $@
-%.dtb:
- $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+%.dtb: scripts
+ $(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@
+
+dtbs: scripts
+ $(Q)$(MAKE) $(build)=$(boot)/dts dtbs
# We use MRPROPER_FILES and CLEAN_FILES now
archclean:
@@ -63,6 +67,7 @@ archclean:
define archhelp
echo '* Image.gz - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)'
echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
+ echo '* dtbs - Build device tree blobs for enabled boards'
echo ' install - Install uncompressed kernel'
echo ' zinstall - Install compressed kernel'
echo ' Install using (your) ~/bin/installkernel or'
diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile
index eca209b2b0b..5a0e3ab854a 100644
--- a/arch/arm64/boot/Makefile
+++ b/arch/arm64/boot/Makefile
@@ -22,9 +22,6 @@ $(obj)/Image: vmlinux FORCE
$(obj)/Image.gz: $(obj)/Image FORCE
$(call if_changed,gzip)
-$(obj)/%.dtb: $(src)/dts/%.dts
- $(call cmd,dtc)
-
install: $(obj)/Image
$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
$(obj)/Image System.map "$(INSTALL_PATH)"
@@ -32,5 +29,3 @@ install: $(obj)/Image
zinstall: $(obj)/Image.gz
$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
$(obj)/Image.gz System.map "$(INSTALL_PATH)"
-
-clean-files += *.dtb
diff --git a/arch/arm64/boot/dts/.gitignore b/arch/arm64/boot/dts/.gitignore
new file mode 100644
index 00000000000..b60ed208c77
--- /dev/null
+++ b/arch/arm64/boot/dts/.gitignore
@@ -0,0 +1 @@
+*.dtb
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
new file mode 100644
index 00000000000..801e2d7fcbc
--- /dev/null
+++ b/arch/arm64/boot/dts/Makefile
@@ -0,0 +1,5 @@
+targets += dtbs
+
+dtbs: $(addprefix $(obj)/, $(dtb-y))
+
+clean-files := *.dtb
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index a581a220593..6e9ca462127 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -43,6 +43,7 @@ generic-y += swab.h
generic-y += termbits.h
generic-y += termios.h
generic-y += topology.h
+generic-y += trace_clock.h
generic-y += types.h
generic-y += unaligned.h
generic-y += user.h
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 54f6116697f..d2f05a60827 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -222,7 +222,7 @@ extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot
extern void __iounmap(volatile void __iomem *addr);
#define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY)
-#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
+#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC))
#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 0f3b4581d92..75fd13d289b 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -38,7 +38,8 @@
#define PMD_SECT_S (_AT(pmdval_t, 3) << 8)
#define PMD_SECT_AF (_AT(pmdval_t, 1) << 10)
#define PMD_SECT_NG (_AT(pmdval_t, 1) << 11)
-#define PMD_SECT_XN (_AT(pmdval_t, 1) << 54)
+#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 53)
+#define PMD_SECT_UXN (_AT(pmdval_t, 1) << 54)
/*
* AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
@@ -57,7 +58,8 @@
#define PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */
#define PTE_AF (_AT(pteval_t, 1) << 10) /* Access Flag */
#define PTE_NG (_AT(pteval_t, 1) << 11) /* nG */
-#define PTE_XN (_AT(pteval_t, 1) << 54) /* XN */
+#define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */
+#define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */
/*
* AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 8960239be72..14aba2db677 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -62,23 +62,23 @@ extern pgprot_t pgprot_default;
#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b))
-#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_XN | PTE_RDONLY)
-#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN)
-#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG)
-#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
-#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY)
-#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
-#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY)
-#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_XN | PTE_DIRTY)
-#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_DIRTY)
-
-#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_XN | PTE_RDONLY)
-#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN)
-#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG)
-#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
-#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY)
-#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
-#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY)
+#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
+#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN)
+#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
+#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
+#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY)
+#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY)
+
+#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
+#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
+#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
+#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
#endif /* __ASSEMBLY__ */
@@ -130,10 +130,10 @@ extern struct page *empty_zero_page;
#define pte_young(pte) (pte_val(pte) & PTE_AF)
#define pte_special(pte) (pte_val(pte) & PTE_SPECIAL)
#define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY))
-#define pte_exec(pte) (!(pte_val(pte) & PTE_XN))
+#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN))
#define pte_present_exec_user(pte) \
- ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_XN)) == \
+ ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == \
(PTE_VALID | PTE_USER))
#define PTE_BIT_FUNC(fn,op) \
@@ -262,7 +262,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
- const pteval_t mask = PTE_USER | PTE_XN | PTE_RDONLY;
+ const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY;
pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
return pte;
}
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index 6d909faebf2..656a6f291a3 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -392,7 +392,7 @@ __SYSCALL(367, sys_fanotify_init)
__SYSCALL(368, compat_sys_fanotify_mark_wrapper)
__SYSCALL(369, sys_prlimit64)
__SYSCALL(370, sys_name_to_handle_at)
-__SYSCALL(371, sys_open_by_handle_at)
+__SYSCALL(371, compat_sys_open_by_handle_at)
__SYSCALL(372, sys_clock_adjtime)
__SYSCALL(373, sys_syncfs)
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index 06e73bf665e..c2bbc9a7222 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -193,9 +193,6 @@ source "kernel/Kconfig.preempt"
config QUICKLIST
def_bool y
-config HAVE_ARCH_BOOTMEM
- def_bool n
-
config ARCH_HAVE_MEMORY_PRESENT
def_bool n
diff --git a/arch/avr32/configs/atngw100_defconfig b/arch/avr32/configs/atngw100_defconfig
index a06bfccc284..f4025db184f 100644
--- a/arch/avr32/configs/atngw100_defconfig
+++ b/arch/avr32/configs/atngw100_defconfig
@@ -109,7 +109,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_MMC=y
diff --git a/arch/avr32/configs/atngw100_evklcd100_defconfig b/arch/avr32/configs/atngw100_evklcd100_defconfig
index d8f1fe80d21..c76a49b9e9d 100644
--- a/arch/avr32/configs/atngw100_evklcd100_defconfig
+++ b/arch/avr32/configs/atngw100_evklcd100_defconfig
@@ -125,7 +125,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_MMC=y
diff --git a/arch/avr32/configs/atngw100_evklcd101_defconfig b/arch/avr32/configs/atngw100_evklcd101_defconfig
index d4c5b19ec95..2d8ab089a64 100644
--- a/arch/avr32/configs/atngw100_evklcd101_defconfig
+++ b/arch/avr32/configs/atngw100_evklcd101_defconfig
@@ -124,7 +124,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_MMC=y
diff --git a/arch/avr32/configs/atngw100_mrmt_defconfig b/arch/avr32/configs/atngw100_mrmt_defconfig
index 77ca4f905d2..b189e0cab04 100644
--- a/arch/avr32/configs/atngw100_mrmt_defconfig
+++ b/arch/avr32/configs/atngw100_mrmt_defconfig
@@ -99,7 +99,7 @@ CONFIG_SND_ATMEL_AC97C=m
# CONFIG_SND_SPI is not set
CONFIG_USB_GADGET=m
CONFIG_USB_GADGET_DEBUG_FILES=y
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_ATMELMCI=y
diff --git a/arch/avr32/configs/atngw100mkii_defconfig b/arch/avr32/configs/atngw100mkii_defconfig
index 6e0dca4d313..2e4de42a53c 100644
--- a/arch/avr32/configs/atngw100mkii_defconfig
+++ b/arch/avr32/configs/atngw100mkii_defconfig
@@ -111,7 +111,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_MMC=y
diff --git a/arch/avr32/configs/atngw100mkii_evklcd100_defconfig b/arch/avr32/configs/atngw100mkii_evklcd100_defconfig
index 7f2a344a5fa..fad3cd22dfd 100644
--- a/arch/avr32/configs/atngw100mkii_evklcd100_defconfig
+++ b/arch/avr32/configs/atngw100mkii_evklcd100_defconfig
@@ -128,7 +128,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_MMC=y
diff --git a/arch/avr32/configs/atngw100mkii_evklcd101_defconfig b/arch/avr32/configs/atngw100mkii_evklcd101_defconfig
index 085eeba88f6..29986230aaa 100644
--- a/arch/avr32/configs/atngw100mkii_evklcd101_defconfig
+++ b/arch/avr32/configs/atngw100mkii_evklcd101_defconfig
@@ -127,7 +127,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_MMC=y
diff --git a/arch/avr32/configs/atstk1002_defconfig b/arch/avr32/configs/atstk1002_defconfig
index d1a887e6405..a582465e1ce 100644
--- a/arch/avr32/configs/atstk1002_defconfig
+++ b/arch/avr32/configs/atstk1002_defconfig
@@ -126,7 +126,7 @@ CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_MMC=y
diff --git a/arch/avr32/configs/atstk1003_defconfig b/arch/avr32/configs/atstk1003_defconfig
index 956f2819ad4..57a79df2ce5 100644
--- a/arch/avr32/configs/atstk1003_defconfig
+++ b/arch/avr32/configs/atstk1003_defconfig
@@ -105,7 +105,7 @@ CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_MMC=y
diff --git a/arch/avr32/configs/atstk1004_defconfig b/arch/avr32/configs/atstk1004_defconfig
index 40c69f38c61..1a49bd8c634 100644
--- a/arch/avr32/configs/atstk1004_defconfig
+++ b/arch/avr32/configs/atstk1004_defconfig
@@ -104,7 +104,7 @@ CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_MMC=y
diff --git a/arch/avr32/configs/atstk1006_defconfig b/arch/avr32/configs/atstk1006_defconfig
index 511eb8af356..206a1b67f76 100644
--- a/arch/avr32/configs/atstk1006_defconfig
+++ b/arch/avr32/configs/atstk1006_defconfig
@@ -129,7 +129,7 @@ CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_MMC=y
diff --git a/arch/avr32/configs/favr-32_defconfig b/arch/avr32/configs/favr-32_defconfig
index 19973b06170..0421498d666 100644
--- a/arch/avr32/configs/favr-32_defconfig
+++ b/arch/avr32/configs/favr-32_defconfig
@@ -117,7 +117,7 @@ CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_MMC=y
diff --git a/arch/avr32/configs/hammerhead_defconfig b/arch/avr32/configs/hammerhead_defconfig
index 6f45681196d..82f24eb251b 100644
--- a/arch/avr32/configs/hammerhead_defconfig
+++ b/arch/avr32/configs/hammerhead_defconfig
@@ -127,7 +127,7 @@ CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=m
CONFIG_MMC_ATMELMCI=m
diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild
index 4807ded352c..4dd4f78d3dc 100644
--- a/arch/avr32/include/asm/Kbuild
+++ b/arch/avr32/include/asm/Kbuild
@@ -1,3 +1,4 @@
generic-y += clkdev.h
generic-y += exec.h
+generic-y += trace_clock.h
diff --git a/arch/blackfin/configs/CM-BF527_defconfig b/arch/blackfin/configs/CM-BF527_defconfig
index c280a50e794..f59c80ee78e 100644
--- a/arch/blackfin/configs/CM-BF527_defconfig
+++ b/arch/blackfin/configs/CM-BF527_defconfig
@@ -106,7 +106,7 @@ CONFIG_MUSB_PIO_ONLY=y
CONFIG_USB_STORAGE=m
CONFIG_USB_GADGET=m
CONFIG_USB_ETH=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_G_PRINTER=m
CONFIG_RTC_CLASS=y
diff --git a/arch/blackfin/configs/CM-BF548_defconfig b/arch/blackfin/configs/CM-BF548_defconfig
index 349922be01f..e961483f187 100644
--- a/arch/blackfin/configs/CM-BF548_defconfig
+++ b/arch/blackfin/configs/CM-BF548_defconfig
@@ -107,7 +107,7 @@ CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
# CONFIG_USB_ETH_RNDIS is not set
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_G_PRINTER=m
CONFIG_MMC=m
diff --git a/arch/blackfin/configs/CM-BF561_defconfig b/arch/blackfin/configs/CM-BF561_defconfig
index 0456deaa2d6..24936b91a6e 100644
--- a/arch/blackfin/configs/CM-BF561_defconfig
+++ b/arch/blackfin/configs/CM-BF561_defconfig
@@ -83,7 +83,7 @@ CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
CONFIG_USB_GADGET=m
CONFIG_USB_ETH=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_G_PRINTER=m
CONFIG_MMC=y
diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild
index 5a0625aad6a..27d70759474 100644
--- a/arch/blackfin/include/asm/Kbuild
+++ b/arch/blackfin/include/asm/Kbuild
@@ -38,6 +38,7 @@ generic-y += statfs.h
generic-y += termbits.h
generic-y += termios.h
generic-y += topology.h
+generic-y += trace_clock.h
generic-y += types.h
generic-y += ucontext.h
generic-y += unaligned.h
diff --git a/arch/c6x/Makefile b/arch/c6x/Makefile
index a9eb9597e03..e72eb341723 100644
--- a/arch/c6x/Makefile
+++ b/arch/c6x/Makefile
@@ -41,7 +41,7 @@ DTB:=$(subst dtbImage.,,$(filter dtbImage.%, $(MAKECMDGOALS)))
export DTB
ifneq ($(DTB),)
-core-y += $(boot)/
+core-y += $(boot)/dts/
endif
# With make 3.82 we cannot mix normal and wildcard targets
diff --git a/arch/c6x/boot/Makefile b/arch/c6x/boot/Makefile
index 6891257d514..8734abee548 100644
--- a/arch/c6x/boot/Makefile
+++ b/arch/c6x/boot/Makefile
@@ -6,25 +6,5 @@ OBJCOPYFLAGS_vmlinux.bin := -O binary
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
-DTC_FLAGS ?= -p 1024
-
-ifneq ($(DTB),)
-obj-y += linked_dtb.o
-endif
-
-$(obj)/%.dtb: $(src)/dts/%.dts FORCE
- $(call if_changed_dep,dtc)
-
-quiet_cmd_cp = CP $< $@$2
- cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false)
-
-# Generate builtin.dtb from $(DTB).dtb
-$(obj)/builtin.dtb: $(obj)/$(DTB).dtb
- $(call if_changed,cp)
-
-$(obj)/linked_dtb.o: $(obj)/builtin.dtb
-
$(obj)/dtbImage.%: vmlinux
$(call if_changed,objcopy)
-
-clean-files := $(obj)/*.dtb
diff --git a/arch/c6x/boot/dts/Makefile b/arch/c6x/boot/dts/Makefile
new file mode 100644
index 00000000000..c7528b02d06
--- /dev/null
+++ b/arch/c6x/boot/dts/Makefile
@@ -0,0 +1,20 @@
+#
+# Makefile for device trees
+#
+
+DTC_FLAGS ?= -p 1024
+
+ifneq ($(DTB),)
+obj-y += linked_dtb.o
+endif
+
+quiet_cmd_cp = CP $< $@$2
+ cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false)
+
+# Generate builtin.dtb from $(DTB).dtb
+$(obj)/builtin.dtb: $(obj)/$(DTB).dtb
+ $(call if_changed,cp)
+
+$(obj)/linked_dtb.o: $(obj)/builtin.dtb
+
+clean-files := *.dtb
diff --git a/arch/c6x/boot/dts/linked_dtb.S b/arch/c6x/boot/dts/linked_dtb.S
new file mode 100644
index 00000000000..cf347f1d16c
--- /dev/null
+++ b/arch/c6x/boot/dts/linked_dtb.S
@@ -0,0 +1,2 @@
+.section __fdt_blob,"a"
+.incbin "arch/c6x/boot/dts/builtin.dtb"
diff --git a/arch/c6x/boot/linked_dtb.S b/arch/c6x/boot/linked_dtb.S
deleted file mode 100644
index 57a4454eaec..00000000000
--- a/arch/c6x/boot/linked_dtb.S
+++ /dev/null
@@ -1,2 +0,0 @@
-.section __fdt_blob,"a"
-.incbin "arch/c6x/boot/builtin.dtb"
diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild
index 112a496d835..eae7b5963e8 100644
--- a/arch/c6x/include/asm/Kbuild
+++ b/arch/c6x/include/asm/Kbuild
@@ -49,6 +49,7 @@ generic-y += termbits.h
generic-y += termios.h
generic-y += tlbflush.h
generic-y += topology.h
+generic-y += trace_clock.h
generic-y += types.h
generic-y += ucontext.h
generic-y += user.h
diff --git a/arch/c6x/include/asm/setup.h b/arch/c6x/include/asm/setup.h
new file mode 100644
index 00000000000..ecead15872a
--- /dev/null
+++ b/arch/c6x/include/asm/setup.h
@@ -0,0 +1,33 @@
+/*
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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 _ASM_C6X_SETUP_H
+#define _ASM_C6X_SETUP_H
+
+#include <uapi/asm/setup.h>
+
+#ifndef __ASSEMBLY__
+extern char c6x_command_line[COMMAND_LINE_SIZE];
+
+extern int c6x_add_memory(phys_addr_t start, unsigned long size);
+
+extern unsigned long ram_start;
+extern unsigned long ram_end;
+
+extern int c6x_num_cores;
+extern unsigned int c6x_silicon_rev;
+extern unsigned int c6x_devstat;
+extern unsigned char c6x_fuse_mac[6];
+
+extern void machine_init(unsigned long dt_ptr);
+extern void time_init(void);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASM_C6X_SETUP_H */
diff --git a/arch/c6x/include/uapi/asm/Kbuild b/arch/c6x/include/uapi/asm/Kbuild
index c312b424c43..e9bc2b2b814 100644
--- a/arch/c6x/include/uapi/asm/Kbuild
+++ b/arch/c6x/include/uapi/asm/Kbuild
@@ -1,6 +1,8 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
+generic-y += kvm_para.h
+
header-y += byteorder.h
header-y += kvm_para.h
header-y += ptrace.h
diff --git a/arch/c6x/include/uapi/asm/kvm_para.h b/arch/c6x/include/uapi/asm/kvm_para.h
deleted file mode 100644
index 14fab8f0b95..00000000000
--- a/arch/c6x/include/uapi/asm/kvm_para.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/kvm_para.h>
diff --git a/arch/c6x/include/uapi/asm/setup.h b/arch/c6x/include/uapi/asm/setup.h
index a01e31896fa..ad9ac97a8da 100644
--- a/arch/c6x/include/uapi/asm/setup.h
+++ b/arch/c6x/include/uapi/asm/setup.h
@@ -1,33 +1,6 @@
-/*
- * Port on Texas Instruments TMS320C6x architecture
- *
- * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated
- * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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 _ASM_C6X_SETUP_H
-#define _ASM_C6X_SETUP_H
+#ifndef _UAPI_ASM_C6X_SETUP_H
+#define _UAPI_ASM_C6X_SETUP_H
#define COMMAND_LINE_SIZE 1024
-#ifndef __ASSEMBLY__
-extern char c6x_command_line[COMMAND_LINE_SIZE];
-
-extern int c6x_add_memory(phys_addr_t start, unsigned long size);
-
-extern unsigned long ram_start;
-extern unsigned long ram_end;
-
-extern int c6x_num_cores;
-extern unsigned int c6x_silicon_rev;
-extern unsigned int c6x_devstat;
-extern unsigned char c6x_fuse_mac[6];
-
-extern void machine_init(unsigned long dt_ptr);
-extern void time_init(void);
-
-#endif /* !__ASSEMBLY__ */
-#endif /* _ASM_C6X_SETUP_H */
+#endif /* _UAPI_ASM_C6X_SETUP_H */
diff --git a/arch/c6x/kernel/entry.S b/arch/c6x/kernel/entry.S
index 5449c36018f..0ed6157dd25 100644
--- a/arch/c6x/kernel/entry.S
+++ b/arch/c6x/kernel/entry.S
@@ -277,6 +277,8 @@ work_rescheduled:
[A1] BNOP .S1 work_resched,5
work_notifysig:
+ ;; enable interrupts for do_notify_resume()
+ UNMASK_INT B2
B .S2 do_notify_resume
LDW .D2T1 *+SP(REGS__END+8),A6 ; syscall flag
ADDKPC .S2 resume_userspace,B3,1
@@ -427,8 +429,7 @@ ENTRY(ret_from_kernel_execve)
ENDPROC(ret_from_kernel_execve)
;;
- ;; These are the interrupt handlers, responsible for calling __do_IRQ()
- ;; int6 is used for syscalls (see _system_call entry)
+ ;; These are the interrupt handlers, responsible for calling c6x_do_IRQ()
;;
.macro SAVE_ALL_INT
SAVE_ALL IRP,ITSR
diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild
index 6d43a951b5e..15a122c3767 100644
--- a/arch/cris/include/asm/Kbuild
+++ b/arch/cris/include/asm/Kbuild
@@ -11,3 +11,4 @@ header-y += sync_serial.h
generic-y += clkdev.h
generic-y += exec.h
generic-y += module.h
+generic-y += trace_clock.h
diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild
index 4a159da2363..c5d76702830 100644
--- a/arch/frv/include/asm/Kbuild
+++ b/arch/frv/include/asm/Kbuild
@@ -1,3 +1,4 @@
generic-y += clkdev.h
generic-y += exec.h
+generic-y += trace_clock.h
diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild
index 50bbf387b2f..4bc8ae73e08 100644
--- a/arch/h8300/include/asm/Kbuild
+++ b/arch/h8300/include/asm/Kbuild
@@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm
generic-y += clkdev.h
generic-y += exec.h
generic-y += module.h
+generic-y += trace_clock.h
diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild
index 3bfa9b30f44..bdb54ceb53b 100644
--- a/arch/hexagon/include/asm/Kbuild
+++ b/arch/hexagon/include/asm/Kbuild
@@ -48,6 +48,7 @@ generic-y += stat.h
generic-y += termbits.h
generic-y += termios.h
generic-y += topology.h
+generic-y += trace_clock.h
generic-y += types.h
generic-y += ucontext.h
generic-y += unaligned.h
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index ec536e4e36c..fc3924d18c1 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -555,6 +555,7 @@ static int __init simrs_init(void)
return 0;
err_free_tty:
put_tty_driver(hp_simserial_driver);
+ tty_port_destroy(&state->port);
return retval;
}
diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild
index dd02f09b6ed..05b03ecd793 100644
--- a/arch/ia64/include/asm/Kbuild
+++ b/arch/ia64/include/asm/Kbuild
@@ -2,3 +2,4 @@
generic-y += clkdev.h
generic-y += exec.h
generic-y += kvm_para.h
+generic-y += trace_clock.h
diff --git a/arch/ia64/include/asm/cputime.h b/arch/ia64/include/asm/cputime.h
index 3deac956d32..7fcf7f08ab0 100644
--- a/arch/ia64/include/asm/cputime.h
+++ b/arch/ia64/include/asm/cputime.h
@@ -103,5 +103,7 @@ static inline void cputime_to_timeval(const cputime_t ct, struct timeval *val)
#define cputime64_to_clock_t(__ct) \
cputime_to_clock_t((__force cputime_t)__ct)
+extern void arch_vtime_task_switch(struct task_struct *tsk);
+
#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
#endif /* __IA64_CPUTIME_H */
diff --git a/arch/ia64/include/asm/device.h b/arch/ia64/include/asm/device.h
index d05e78f6db9..f69c32ffbe6 100644
--- a/arch/ia64/include/asm/device.h
+++ b/arch/ia64/include/asm/device.h
@@ -7,9 +7,6 @@
#define _ASM_IA64_DEVICE_H
struct dev_archdata {
-#ifdef CONFIG_ACPI
- void *acpi_handle;
-#endif
#ifdef CONFIG_INTEL_IOMMU
void *iommu; /* hook for IOMMU specific extension */
#endif
diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
index 2c26321c28c..74a7cc3293b 100644
--- a/arch/ia64/include/asm/io.h
+++ b/arch/ia64/include/asm/io.h
@@ -90,7 +90,7 @@ phys_to_virt (unsigned long address)
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
extern u64 kern_mem_attribute (unsigned long phys_addr, unsigned long size);
-extern int valid_phys_addr_range (unsigned long addr, size_t count); /* efi.c */
+extern int valid_phys_addr_range (phys_addr_t addr, size_t count); /* efi.c */
extern int valid_mmap_phys_addr_range (unsigned long pfn, size_t count);
/*
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 440578850ae..e9682f5be34 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -633,6 +633,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity)
ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE :
IOSAPIC_LEVEL);
}
+EXPORT_SYMBOL_GPL(acpi_register_gsi);
void acpi_unregister_gsi(u32 gsi)
{
@@ -644,6 +645,7 @@ void acpi_unregister_gsi(u32 gsi)
iosapic_unregister_intr(gsi);
}
+EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
static int __init acpi_parse_fadt(struct acpi_table_header *table)
{
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index d37bbd48637..f034563aeae 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -870,7 +870,7 @@ kern_mem_attribute (unsigned long phys_addr, unsigned long size)
EXPORT_SYMBOL(kern_mem_attribute);
int
-valid_phys_addr_range (unsigned long phys_addr, unsigned long size)
+valid_phys_addr_range (phys_addr_t phys_addr, unsigned long size)
{
u64 attr;
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index f6388216080..b1995efbfd2 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -83,7 +83,7 @@ static struct clocksource *itc_clocksource;
extern cputime_t cycle_to_cputime(u64 cyc);
-static void vtime_account_user(struct task_struct *tsk)
+void vtime_account_user(struct task_struct *tsk)
{
cputime_t delta_utime;
struct thread_info *ti = task_thread_info(tsk);
@@ -100,18 +100,11 @@ static void vtime_account_user(struct task_struct *tsk)
* accumulated times to the current process, and to prepare accounting on
* the next process.
*/
-void vtime_task_switch(struct task_struct *prev)
+void arch_vtime_task_switch(struct task_struct *prev)
{
struct thread_info *pi = task_thread_info(prev);
struct thread_info *ni = task_thread_info(current);
- if (idle_task(smp_processor_id()) != prev)
- vtime_account_system(prev);
- else
- vtime_account_idle(prev);
-
- vtime_account_user(prev);
-
pi->ac_stamp = ni->ac_stamp;
ni->ac_stime = ni->ac_utime = 0;
}
@@ -126,6 +119,8 @@ static cputime_t vtime_delta(struct task_struct *tsk)
cputime_t delta_stime;
__u64 now;
+ WARN_ON_ONCE(!irqs_disabled());
+
now = ia64_get_itc();
delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp));
@@ -147,15 +142,6 @@ void vtime_account_idle(struct task_struct *tsk)
account_idle_time(vtime_delta(tsk));
}
-/*
- * Called from the timer interrupt handler to charge accumulated user time
- * to the current process. Must be called with interrupts disabled.
- */
-void account_process_tick(struct task_struct *p, int user_tick)
-{
- vtime_account_user(p);
-}
-
#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
static irqreturn_t
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index acd5b68e887..082e383c1b6 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -637,7 +637,6 @@ mem_init (void)
high_memory = __va(max_low_pfn * PAGE_SIZE);
- reset_zone_present_pages();
for_each_online_pgdat(pgdat)
if (pgdat->bdata->node_bootmem_map)
totalram_pages += free_all_bootmem_node(pgdat);
diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild
index 50bbf387b2f..4bc8ae73e08 100644
--- a/arch/m32r/include/asm/Kbuild
+++ b/arch/m32r/include/asm/Kbuild
@@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm
generic-y += clkdev.h
generic-y += exec.h
generic-y += module.h
+generic-y += trace_clock.h
diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c
index 16d170f53bf..6685bf45c2c 100644
--- a/arch/m68k/emu/nfcon.c
+++ b/arch/m68k/emu/nfcon.c
@@ -120,8 +120,6 @@ static int __init nfcon_init(void)
{
int res;
- tty_port_init(&nfcon_tty_port);
-
stderr_id = nf_get_id("NF_STDERR");
if (!stderr_id)
return -ENODEV;
@@ -130,6 +128,8 @@ static int __init nfcon_init(void)
if (!nfcon_tty_driver)
return -ENOMEM;
+ tty_port_init(&nfcon_tty_port);
+
nfcon_tty_driver->driver_name = "nfcon";
nfcon_tty_driver->name = "nfcon";
nfcon_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
@@ -143,6 +143,7 @@ static int __init nfcon_init(void)
if (res) {
pr_err("failed to register nfcon tty driver\n");
put_tty_driver(nfcon_tty_driver);
+ tty_port_destroy(&nfcon_tty_port);
return res;
}
@@ -157,6 +158,7 @@ static void __exit nfcon_exit(void)
unregister_console(&nf_console);
tty_unregister_driver(nfcon_tty_driver);
put_tty_driver(nfcon_tty_driver);
+ tty_port_destroy(&nfcon_tty_port);
}
module_init(nfcon_init);
diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild
index 88fa3ac86fa..7f1949c0e08 100644
--- a/arch/m68k/include/asm/Kbuild
+++ b/arch/m68k/include/asm/Kbuild
@@ -24,6 +24,7 @@ generic-y += sections.h
generic-y += siginfo.h
generic-y += statfs.h
generic-y += topology.h
+generic-y += trace_clock.h
generic-y += types.h
generic-y += word-at-a-time.h
generic-y += xor.h
diff --git a/arch/m68k/include/asm/signal.h b/arch/m68k/include/asm/signal.h
index 67e489d8d1b..2df26b57c26 100644
--- a/arch/m68k/include/asm/signal.h
+++ b/arch/m68k/include/asm/signal.h
@@ -41,7 +41,7 @@ struct k_sigaction {
static inline void sigaddset(sigset_t *set, int _sig)
{
asm ("bfset %0{%1,#1}"
- : "+od" (*set)
+ : "+o" (*set)
: "id" ((_sig - 1) ^ 31)
: "cc");
}
@@ -49,7 +49,7 @@ static inline void sigaddset(sigset_t *set, int _sig)
static inline void sigdelset(sigset_t *set, int _sig)
{
asm ("bfclr %0{%1,#1}"
- : "+od" (*set)
+ : "+o" (*set)
: "id" ((_sig - 1) ^ 31)
: "cc");
}
@@ -65,7 +65,7 @@ static inline int __gen_sigismember(sigset_t *set, int _sig)
int ret;
asm ("bfextu %1{%2,#1},%0"
: "=d" (ret)
- : "od" (*set), "id" ((_sig-1) ^ 31)
+ : "o" (*set), "id" ((_sig-1) ^ 31)
: "cc");
return ret;
}
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile
index b23c40eb7a5..d26fb905ee0 100644
--- a/arch/microblaze/Makefile
+++ b/arch/microblaze/Makefile
@@ -57,7 +57,7 @@ boot := arch/microblaze/boot
DTB:=$(subst simpleImage.,,$(filter simpleImage.%, $(MAKECMDGOALS)))
ifneq ($(DTB),)
- core-y += $(boot)/
+ core-y += $(boot)/dts/
endif
# defines filename extension depending memory management type
diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile
index fa83ea497db..80fe54fb7ca 100644
--- a/arch/microblaze/boot/Makefile
+++ b/arch/microblaze/boot/Makefile
@@ -2,21 +2,10 @@
# arch/microblaze/boot/Makefile
#
-obj-y += linked_dtb.o
-
targets := linux.bin linux.bin.gz simpleImage.%
OBJCOPYFLAGS := -R .note -R .comment -R .note.gnu.build-id -O binary
-# Ensure system.dtb exists
-$(obj)/linked_dtb.o: $(obj)/system.dtb
-
-# Generate system.dtb from $(DTB).dtb
-ifneq ($(DTB),system)
-$(obj)/system.dtb: $(obj)/$(DTB).dtb
- $(call if_changed,cp)
-endif
-
$(obj)/linux.bin: vmlinux FORCE
$(call if_changed,objcopy)
$(call if_changed,uimage)
@@ -45,10 +34,4 @@ $(obj)/simpleImage.%: vmlinux FORCE
@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
-# Rule to build device tree blobs
-DTC_FLAGS := -p 1024
-
-$(obj)/%.dtb: $(src)/dts/%.dts FORCE
- $(call if_changed_dep,dtc)
-
-clean-files += *.dtb simpleImage.*.unstrip linux.bin.ub
+clean-files += simpleImage.*.unstrip linux.bin.ub
diff --git a/arch/microblaze/boot/dts/Makefile b/arch/microblaze/boot/dts/Makefile
new file mode 100644
index 00000000000..c3b3a5d67b8
--- /dev/null
+++ b/arch/microblaze/boot/dts/Makefile
@@ -0,0 +1,22 @@
+#
+# arch/microblaze/boot/Makefile
+#
+
+obj-y += linked_dtb.o
+
+# Ensure system.dtb exists
+$(obj)/linked_dtb.o: $(obj)/system.dtb
+
+# Generate system.dtb from $(DTB).dtb
+ifneq ($(DTB),system)
+$(obj)/system.dtb: $(obj)/$(DTB).dtb
+ $(call if_changed,cp)
+endif
+
+quiet_cmd_cp = CP $< $@$2
+ cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false)
+
+# Rule to build device tree blobs
+DTC_FLAGS := -p 1024
+
+clean-files += *.dtb
diff --git a/arch/microblaze/boot/dts/linked_dtb.S b/arch/microblaze/boot/dts/linked_dtb.S
new file mode 100644
index 00000000000..23345af3721
--- /dev/null
+++ b/arch/microblaze/boot/dts/linked_dtb.S
@@ -0,0 +1,2 @@
+.section __fdt_blob,"a"
+.incbin "arch/microblaze/boot/dts/system.dtb"
diff --git a/arch/microblaze/boot/linked_dtb.S b/arch/microblaze/boot/linked_dtb.S
deleted file mode 100644
index cb2b537aebe..00000000000
--- a/arch/microblaze/boot/linked_dtb.S
+++ /dev/null
@@ -1,3 +0,0 @@
-.section __fdt_blob,"a"
-.incbin "arch/microblaze/boot/system.dtb"
-
diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild
index 8653072d7e9..2957fcc7176 100644
--- a/arch/microblaze/include/asm/Kbuild
+++ b/arch/microblaze/include/asm/Kbuild
@@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm
header-y += elf.h
generic-y += clkdev.h
generic-y += exec.h
+generic-y += trace_clock.h
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index 3847e5b9c60..3903e3d11f5 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -111,7 +111,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
- if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1))
+ if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1) == -EFAULT)
goto badframe;
return rval;
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 4dbb5055d04..a1c5b996d66 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -1346,8 +1346,6 @@ void __init pcibios_resource_survey(void)
pci_assign_unassigned_resources();
}
-#ifdef CONFIG_HOTPLUG
-
/* This is used by the PCI hotplug driver to allocate resource
* of newly plugged busses. We can try to consolidate with the
* rest of the code later, for now, keep it as-is as our main
@@ -1407,8 +1405,6 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus)
}
EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus);
-#endif /* CONFIG_HOTPLUG */
-
int pcibios_enable_device(struct pci_dev *dev, int mask)
{
return pci_enable_resources(dev, mask);
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile
index 407ebc00e66..cb83d8d21ae 100644
--- a/arch/mips/alchemy/common/Makefile
+++ b/arch/mips/alchemy/common/Makefile
@@ -6,7 +6,7 @@
#
obj-y += prom.o time.o clocks.o platform.o power.o setup.o \
- sleeper.o dma.o dbdma.o vss.o irq.o
+ sleeper.o dma.o dbdma.o vss.o irq.o usb.o
# optional gpiolib support
ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index c0f3ce6dcb5..7af941d8e71 100644
--- a/arch/mips/alchemy/common/platform.c
+++ b/arch/mips/alchemy/common/platform.c
@@ -17,6 +17,8 @@
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/slab.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
@@ -122,6 +124,53 @@ static void __init alchemy_setup_uarts(int ctype)
static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32);
static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32);
+/* Power on callback for the ehci platform driver */
+static int alchemy_ehci_power_on(struct platform_device *pdev)
+{
+ return alchemy_usb_control(ALCHEMY_USB_EHCI0, 1);
+}
+
+/* Power off/suspend callback for the ehci platform driver */
+static void alchemy_ehci_power_off(struct platform_device *pdev)
+{
+ alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
+}
+
+static struct usb_ehci_pdata alchemy_ehci_pdata = {
+ .no_io_watchdog = 1,
+ .power_on = alchemy_ehci_power_on,
+ .power_off = alchemy_ehci_power_off,
+ .power_suspend = alchemy_ehci_power_off,
+};
+
+/* Power on callback for the ohci platform driver */
+static int alchemy_ohci_power_on(struct platform_device *pdev)
+{
+ int unit;
+
+ unit = (pdev->id == 1) ?
+ ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
+
+ return alchemy_usb_control(unit, 1);
+}
+
+/* Power off/suspend callback for the ohci platform driver */
+static void alchemy_ohci_power_off(struct platform_device *pdev)
+{
+ int unit;
+
+ unit = (pdev->id == 1) ?
+ ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
+
+ alchemy_usb_control(unit, 0);
+}
+
+static struct usb_ohci_pdata alchemy_ohci_pdata = {
+ .power_on = alchemy_ohci_power_on,
+ .power_off = alchemy_ohci_power_off,
+ .power_suspend = alchemy_ohci_power_off,
+};
+
static unsigned long alchemy_ohci_data[][2] __initdata = {
[ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT },
[ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT },
@@ -169,9 +218,10 @@ static void __init alchemy_setup_usb(int ctype)
res[1].start = alchemy_ohci_data[ctype][1];
res[1].end = res[1].start;
res[1].flags = IORESOURCE_IRQ;
- pdev->name = "au1xxx-ohci";
+ pdev->name = "ohci-platform";
pdev->id = 0;
pdev->dev.dma_mask = &alchemy_ohci_dmamask;
+ pdev->dev.platform_data = &alchemy_ohci_pdata;
if (platform_device_register(pdev))
printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n");
@@ -188,9 +238,10 @@ static void __init alchemy_setup_usb(int ctype)
res[1].start = alchemy_ehci_data[ctype][1];
res[1].end = res[1].start;
res[1].flags = IORESOURCE_IRQ;
- pdev->name = "au1xxx-ehci";
+ pdev->name = "ehci-platform";
pdev->id = 0;
pdev->dev.dma_mask = &alchemy_ehci_dmamask;
+ pdev->dev.platform_data = &alchemy_ehci_pdata;
if (platform_device_register(pdev))
printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n");
@@ -207,9 +258,10 @@ static void __init alchemy_setup_usb(int ctype)
res[1].start = AU1300_USB_INT;
res[1].end = res[1].start;
res[1].flags = IORESOURCE_IRQ;
- pdev->name = "au1xxx-ohci";
+ pdev->name = "ohci-platform";
pdev->id = 1;
pdev->dev.dma_mask = &alchemy_ohci_dmamask;
+ pdev->dev.platform_data = &alchemy_ohci_pdata;
if (platform_device_register(pdev))
printk(KERN_INFO "Alchemy USB: cannot add OHCI1\n");
diff --git a/drivers/usb/host/alchemy-common.c b/arch/mips/alchemy/common/usb.c
index 936af8359fb..936af8359fb 100644
--- a/drivers/usb/host/alchemy-common.c
+++ b/arch/mips/alchemy/common/usb.c
diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c
index 072bb9be230..bd2bc108e1b 100644
--- a/arch/mips/ath79/dev-usb.c
+++ b/arch/mips/ath79/dev-usb.c
@@ -50,13 +50,11 @@ static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32);
static struct usb_ehci_pdata ath79_ehci_pdata_v1 = {
.has_synopsys_hc_bug = 1,
- .port_power_off = 1,
};
static struct usb_ehci_pdata ath79_ehci_pdata_v2 = {
.caps_offset = 0x100,
.has_tt = 1,
- .port_power_off = 1,
};
static struct platform_device ath79_ehci_device = {
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index bc96e2908f1..6e927cf20df 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -24,9 +24,6 @@ DTB_FILES = $(patsubst %.dts, %.dtb, $(DTS_FILES))
obj-y += $(patsubst %.dts, %.dtb.o, $(DTS_FILES))
-$(obj)/%.dtb: $(src)/%.dts FORCE
- $(call if_changed_dep,dtc)
-
# Let's keep the .dtb files around in case we want to look at them.
.SECONDARY: $(addprefix $(obj)/, $(DTB_FILES))
diff --git a/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/arch/mips/cavium-octeon/executive/cvmx-l2c.c
index d38246e33dd..9f883bf7695 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-l2c.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-l2c.c
@@ -30,6 +30,7 @@
* measurement, and debugging facilities.
*/
+#include <linux/irqflags.h>
#include <asm/octeon/cvmx.h>
#include <asm/octeon/cvmx-l2c.h>
#include <asm/octeon/cvmx-spinlock.h>
diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig
index b6fde2bb51b..4ca8e5c9922 100644
--- a/arch/mips/configs/bcm47xx_defconfig
+++ b/arch/mips/configs/bcm47xx_defconfig
@@ -473,7 +473,7 @@ CONFIG_USB_GADGET_NET2280=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_MIDI_GADGET=m
CONFIG_LEDS_CLASS=y
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 17a36c12517..face9d26e6d 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -233,6 +233,7 @@ CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
CONFIG_USB_UHCI_HCD=y
CONFIG_USB_STORAGE=y
CONFIG_NEW_LEDS=y
diff --git a/arch/mips/configs/db1235_defconfig b/arch/mips/configs/db1235_defconfig
index c48998ffd19..14752dde754 100644
--- a/arch/mips/configs/db1235_defconfig
+++ b/arch/mips/configs/db1235_defconfig
@@ -346,8 +346,10 @@ CONFIG_USB=y
CONFIG_USB_DYNAMIC_MINORS=y
CONFIG_USB_SUSPEND=y
CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
CONFIG_USB_STORAGE=y
CONFIG_MMC=y
CONFIG_MMC_CLKGATE=y
diff --git a/arch/mips/configs/gpr_defconfig b/arch/mips/configs/gpr_defconfig
index 48a40aefaf5..fb64589015f 100644
--- a/arch/mips/configs/gpr_defconfig
+++ b/arch/mips/configs/gpr_defconfig
@@ -291,6 +291,7 @@ CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
CONFIG_USB_STORAGE=m
CONFIG_USB_LIBUSUAL=y
CONFIG_USB_SERIAL=y
diff --git a/arch/mips/configs/ls1b_defconfig b/arch/mips/configs/ls1b_defconfig
index 80cff8bea8e..7eb75543ca1 100644
--- a/arch/mips/configs/ls1b_defconfig
+++ b/arch/mips/configs/ls1b_defconfig
@@ -76,6 +76,7 @@ CONFIG_HID_GENERIC=m
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
CONFIG_USB_STORAGE=m
CONFIG_USB_SERIAL=m
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
index 46c61edcdf7..9fa8f16068d 100644
--- a/arch/mips/configs/mtx1_defconfig
+++ b/arch/mips/configs/mtx1_defconfig
@@ -581,6 +581,7 @@ CONFIG_USB_MON=m
CONFIG_USB_EHCI_HCD=m
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_HCD_PLATFORM=y
CONFIG_USB_UHCI_HCD=m
CONFIG_USB_U132_HCD=m
CONFIG_USB_SL811_HCD=m
@@ -661,7 +662,7 @@ CONFIG_USB_GADGET_NET2280=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_MIDI_GADGET=m
CONFIG_MMC=m
diff --git a/arch/mips/fw/arc/misc.c b/arch/mips/fw/arc/misc.c
index 7cf80ca2c1d..f9f5307434c 100644
--- a/arch/mips/fw/arc/misc.c
+++ b/arch/mips/fw/arc/misc.c
@@ -11,6 +11,7 @@
*/
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/irqflags.h>
#include <asm/bcache.h>
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
index 533053d12ce..9b54b7a403d 100644
--- a/arch/mips/include/asm/Kbuild
+++ b/arch/mips/include/asm/Kbuild
@@ -1 +1,2 @@
# MIPS headers
+generic-y += trace_clock.h
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index 82ad35ce2b4..46ac73abd5e 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -14,7 +14,6 @@
#endif
#include <linux/compiler.h>
-#include <linux/irqflags.h>
#include <linux/types.h>
#include <asm/barrier.h>
#include <asm/byteorder.h> /* sigh ... */
@@ -44,6 +43,24 @@
#define smp_mb__before_clear_bit() smp_mb__before_llsc()
#define smp_mb__after_clear_bit() smp_llsc_mb()
+
+/*
+ * These are the "slower" versions of the functions and are in bitops.c.
+ * These functions call raw_local_irq_{save,restore}().
+ */
+void __mips_set_bit(unsigned long nr, volatile unsigned long *addr);
+void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr);
+void __mips_change_bit(unsigned long nr, volatile unsigned long *addr);
+int __mips_test_and_set_bit(unsigned long nr,
+ volatile unsigned long *addr);
+int __mips_test_and_set_bit_lock(unsigned long nr,
+ volatile unsigned long *addr);
+int __mips_test_and_clear_bit(unsigned long nr,
+ volatile unsigned long *addr);
+int __mips_test_and_change_bit(unsigned long nr,
+ volatile unsigned long *addr);
+
+
/*
* set_bit - Atomically set a bit in memory
* @nr: the bit to set
@@ -57,7 +74,7 @@
static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
- unsigned short bit = nr & SZLONG_MASK;
+ int bit = nr & SZLONG_MASK;
unsigned long temp;
if (kernel_uses_llsc && R10000_LLSC_WAR) {
@@ -92,17 +109,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
: "=&r" (temp), "+m" (*m)
: "ir" (1UL << bit));
} while (unlikely(!temp));
- } else {
- volatile unsigned long *a = addr;
- unsigned long mask;
- unsigned long flags;
-
- a += nr >> SZLONG_LOG;
- mask = 1UL << bit;
- raw_local_irq_save(flags);
- *a |= mask;
- raw_local_irq_restore(flags);
- }
+ } else
+ __mips_set_bit(nr, addr);
}
/*
@@ -118,7 +126,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
- unsigned short bit = nr & SZLONG_MASK;
+ int bit = nr & SZLONG_MASK;
unsigned long temp;
if (kernel_uses_llsc && R10000_LLSC_WAR) {
@@ -153,17 +161,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
: "=&r" (temp), "+m" (*m)
: "ir" (~(1UL << bit)));
} while (unlikely(!temp));
- } else {
- volatile unsigned long *a = addr;
- unsigned long mask;
- unsigned long flags;
-
- a += nr >> SZLONG_LOG;
- mask = 1UL << bit;
- raw_local_irq_save(flags);
- *a &= ~mask;
- raw_local_irq_restore(flags);
- }
+ } else
+ __mips_clear_bit(nr, addr);
}
/*
@@ -191,7 +190,7 @@ static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *ad
*/
static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
{
- unsigned short bit = nr & SZLONG_MASK;
+ int bit = nr & SZLONG_MASK;
if (kernel_uses_llsc && R10000_LLSC_WAR) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
@@ -220,17 +219,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
: "=&r" (temp), "+m" (*m)
: "ir" (1UL << bit));
} while (unlikely(!temp));
- } else {
- volatile unsigned long *a = addr;
- unsigned long mask;
- unsigned long flags;
-
- a += nr >> SZLONG_LOG;
- mask = 1UL << bit;
- raw_local_irq_save(flags);
- *a ^= mask;
- raw_local_irq_restore(flags);
- }
+ } else
+ __mips_change_bit(nr, addr);
}
/*
@@ -244,7 +234,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
static inline int test_and_set_bit(unsigned long nr,
volatile unsigned long *addr)
{
- unsigned short bit = nr & SZLONG_MASK;
+ int bit = nr & SZLONG_MASK;
unsigned long res;
smp_mb__before_llsc();
@@ -281,18 +271,8 @@ static inline int test_and_set_bit(unsigned long nr,
} while (unlikely(!res));
res = temp & (1UL << bit);
- } else {
- volatile unsigned long *a = addr;
- unsigned long mask;
- unsigned long flags;
-
- a += nr >> SZLONG_LOG;
- mask = 1UL << bit;
- raw_local_irq_save(flags);
- res = (mask & *a);
- *a |= mask;
- raw_local_irq_restore(flags);
- }
+ } else
+ res = __mips_test_and_set_bit(nr, addr);
smp_llsc_mb();
@@ -310,7 +290,7 @@ static inline int test_and_set_bit(unsigned long nr,
static inline int test_and_set_bit_lock(unsigned long nr,
volatile unsigned long *addr)
{
- unsigned short bit = nr & SZLONG_MASK;
+ int bit = nr & SZLONG_MASK;
unsigned long res;
if (kernel_uses_llsc && R10000_LLSC_WAR) {
@@ -345,18 +325,8 @@ static inline int test_and_set_bit_lock(unsigned long nr,
} while (unlikely(!res));
res = temp & (1UL << bit);
- } else {
- volatile unsigned long *a = addr;
- unsigned long mask;
- unsigned long flags;
-
- a += nr >> SZLONG_LOG;
- mask = 1UL << bit;
- raw_local_irq_save(flags);
- res = (mask & *a);
- *a |= mask;
- raw_local_irq_restore(flags);
- }
+ } else
+ res = __mips_test_and_set_bit_lock(nr, addr);
smp_llsc_mb();
@@ -373,7 +343,7 @@ static inline int test_and_set_bit_lock(unsigned long nr,
static inline int test_and_clear_bit(unsigned long nr,
volatile unsigned long *addr)
{
- unsigned short bit = nr & SZLONG_MASK;
+ int bit = nr & SZLONG_MASK;
unsigned long res;
smp_mb__before_llsc();
@@ -428,18 +398,8 @@ static inline int test_and_clear_bit(unsigned long nr,
} while (unlikely(!res));
res = temp & (1UL << bit);
- } else {
- volatile unsigned long *a = addr;
- unsigned long mask;
- unsigned long flags;
-
- a += nr >> SZLONG_LOG;
- mask = 1UL << bit;
- raw_local_irq_save(flags);
- res = (mask & *a);
- *a &= ~mask;
- raw_local_irq_restore(flags);
- }
+ } else
+ res = __mips_test_and_clear_bit(nr, addr);
smp_llsc_mb();
@@ -457,7 +417,7 @@ static inline int test_and_clear_bit(unsigned long nr,
static inline int test_and_change_bit(unsigned long nr,
volatile unsigned long *addr)
{
- unsigned short bit = nr & SZLONG_MASK;
+ int bit = nr & SZLONG_MASK;
unsigned long res;
smp_mb__before_llsc();
@@ -494,18 +454,8 @@ static inline int test_and_change_bit(unsigned long nr,
} while (unlikely(!res));
res = temp & (1UL << bit);
- } else {
- volatile unsigned long *a = addr;
- unsigned long mask;
- unsigned long flags;
-
- a += nr >> SZLONG_LOG;
- mask = 1UL << bit;
- raw_local_irq_save(flags);
- res = (mask & *a);
- *a ^= mask;
- raw_local_irq_restore(flags);
- }
+ } else
+ res = __mips_test_and_change_bit(nr, addr);
smp_llsc_mb();
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index 58277e0e9cd..3c5d1464b7b 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -290,7 +290,7 @@ struct compat_shmid64_ds {
static inline int is_compat_task(void)
{
- return test_thread_flag(TIF_32BIT);
+ return test_thread_flag(TIF_32BIT_ADDR);
}
#endif /* _ASM_COMPAT_H */
diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h
index bd94946a18f..ef99db994c2 100644
--- a/arch/mips/include/asm/hugetlb.h
+++ b/arch/mips/include/asm/hugetlb.h
@@ -95,7 +95,17 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
pte_t *ptep, pte_t pte,
int dirty)
{
- return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+ int changed = !pte_same(*ptep, pte);
+
+ if (changed) {
+ set_pte_at(vma->vm_mm, addr, ptep, pte);
+ /*
+ * There could be some standard sized pages in there,
+ * get them all.
+ */
+ flush_tlb_range(vma, addr, addr + HPAGE_SIZE);
+ }
+ return changed;
}
static inline pte_t huge_ptep_get(pte_t *ptep)
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 29d9c23c20c..ff2e0345e01 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -15,6 +15,7 @@
#include <linux/compiler.h>
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/irqflags.h>
#include <asm/addrspace.h>
#include <asm/bug.h>
diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h
index 309cbcd6909..9f3384c789d 100644
--- a/arch/mips/include/asm/irqflags.h
+++ b/arch/mips/include/asm/irqflags.h
@@ -16,83 +16,13 @@
#include <linux/compiler.h>
#include <asm/hazards.h>
-__asm__(
- " .macro arch_local_irq_enable \n"
- " .set push \n"
- " .set reorder \n"
- " .set noat \n"
-#ifdef CONFIG_MIPS_MT_SMTC
- " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n"
- " ori $1, 0x400 \n"
- " xori $1, 0x400 \n"
- " mtc0 $1, $2, 1 \n"
-#elif defined(CONFIG_CPU_MIPSR2)
- " ei \n"
-#else
- " mfc0 $1,$12 \n"
- " ori $1,0x1f \n"
- " xori $1,0x1e \n"
- " mtc0 $1,$12 \n"
-#endif
- " irq_enable_hazard \n"
- " .set pop \n"
- " .endm");
+#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC)
-extern void smtc_ipi_replay(void);
-
-static inline void arch_local_irq_enable(void)
-{
-#ifdef CONFIG_MIPS_MT_SMTC
- /*
- * SMTC kernel needs to do a software replay of queued
- * IPIs, at the cost of call overhead on each local_irq_enable()
- */
- smtc_ipi_replay();
-#endif
- __asm__ __volatile__(
- "arch_local_irq_enable"
- : /* no outputs */
- : /* no inputs */
- : "memory");
-}
-
-
-/*
- * For cli() we have to insert nops to make sure that the new value
- * has actually arrived in the status register before the end of this
- * macro.
- * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
- * no nops at all.
- */
-/*
- * For TX49, operating only IE bit is not enough.
- *
- * If mfc0 $12 follows store and the mfc0 is last instruction of a
- * page and fetching the next instruction causes TLB miss, the result
- * of the mfc0 might wrongly contain EXL bit.
- *
- * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
- *
- * Workaround: mask EXL bit of the result or place a nop before mfc0.
- */
__asm__(
" .macro arch_local_irq_disable\n"
" .set push \n"
" .set noat \n"
-#ifdef CONFIG_MIPS_MT_SMTC
- " mfc0 $1, $2, 1 \n"
- " ori $1, 0x400 \n"
- " .set noreorder \n"
- " mtc0 $1, $2, 1 \n"
-#elif defined(CONFIG_CPU_MIPSR2)
" di \n"
-#else
- " mfc0 $1,$12 \n"
- " ori $1,0x1f \n"
- " xori $1,0x1f \n"
- " .set noreorder \n"
- " mtc0 $1,$12 \n"
-#endif
" irq_disable_hazard \n"
" .set pop \n"
" .endm \n");
@@ -106,46 +36,14 @@ static inline void arch_local_irq_disable(void)
: "memory");
}
-__asm__(
- " .macro arch_local_save_flags flags \n"
- " .set push \n"
- " .set reorder \n"
-#ifdef CONFIG_MIPS_MT_SMTC
- " mfc0 \\flags, $2, 1 \n"
-#else
- " mfc0 \\flags, $12 \n"
-#endif
- " .set pop \n"
- " .endm \n");
-
-static inline unsigned long arch_local_save_flags(void)
-{
- unsigned long flags;
- asm volatile("arch_local_save_flags %0" : "=r" (flags));
- return flags;
-}
__asm__(
" .macro arch_local_irq_save result \n"
" .set push \n"
" .set reorder \n"
" .set noat \n"
-#ifdef CONFIG_MIPS_MT_SMTC
- " mfc0 \\result, $2, 1 \n"
- " ori $1, \\result, 0x400 \n"
- " .set noreorder \n"
- " mtc0 $1, $2, 1 \n"
- " andi \\result, \\result, 0x400 \n"
-#elif defined(CONFIG_CPU_MIPSR2)
" di \\result \n"
" andi \\result, 1 \n"
-#else
- " mfc0 \\result, $12 \n"
- " ori $1, \\result, 0x1f \n"
- " xori $1, 0x1f \n"
- " .set noreorder \n"
- " mtc0 $1, $12 \n"
-#endif
" irq_disable_hazard \n"
" .set pop \n"
" .endm \n");
@@ -160,61 +58,37 @@ static inline unsigned long arch_local_irq_save(void)
return flags;
}
+
__asm__(
" .macro arch_local_irq_restore flags \n"
" .set push \n"
" .set noreorder \n"
" .set noat \n"
-#ifdef CONFIG_MIPS_MT_SMTC
- "mfc0 $1, $2, 1 \n"
- "andi \\flags, 0x400 \n"
- "ori $1, 0x400 \n"
- "xori $1, 0x400 \n"
- "or \\flags, $1 \n"
- "mtc0 \\flags, $2, 1 \n"
-#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
+#if defined(CONFIG_IRQ_CPU)
/*
* Slow, but doesn't suffer from a relatively unlikely race
* condition we're having since days 1.
*/
" beqz \\flags, 1f \n"
- " di \n"
+ " di \n"
" ei \n"
"1: \n"
-#elif defined(CONFIG_CPU_MIPSR2)
+#else
/*
* Fast, dangerous. Life is fun, life is good.
*/
" mfc0 $1, $12 \n"
" ins $1, \\flags, 0, 1 \n"
" mtc0 $1, $12 \n"
-#else
- " mfc0 $1, $12 \n"
- " andi \\flags, 1 \n"
- " ori $1, 0x1f \n"
- " xori $1, 0x1f \n"
- " or \\flags, $1 \n"
- " mtc0 \\flags, $12 \n"
#endif
" irq_disable_hazard \n"
" .set pop \n"
" .endm \n");
-
static inline void arch_local_irq_restore(unsigned long flags)
{
unsigned long __tmp1;
-#ifdef CONFIG_MIPS_MT_SMTC
- /*
- * SMTC kernel needs to do a software replay of queued
- * IPIs, at the cost of branch and call overhead on each
- * local_irq_restore()
- */
- if (unlikely(!(flags & 0x0400)))
- smtc_ipi_replay();
-#endif
-
__asm__ __volatile__(
"arch_local_irq_restore\t%0"
: "=r" (__tmp1)
@@ -232,6 +106,75 @@ static inline void __arch_local_irq_restore(unsigned long flags)
: "0" (flags)
: "memory");
}
+#else
+/* Functions that require preempt_{dis,en}able() are in mips-atomic.c */
+void arch_local_irq_disable(void);
+unsigned long arch_local_irq_save(void);
+void arch_local_irq_restore(unsigned long flags);
+void __arch_local_irq_restore(unsigned long flags);
+#endif /* if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) */
+
+
+__asm__(
+ " .macro arch_local_irq_enable \n"
+ " .set push \n"
+ " .set reorder \n"
+ " .set noat \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n"
+ " ori $1, 0x400 \n"
+ " xori $1, 0x400 \n"
+ " mtc0 $1, $2, 1 \n"
+#elif defined(CONFIG_CPU_MIPSR2)
+ " ei \n"
+#else
+ " mfc0 $1,$12 \n"
+ " ori $1,0x1f \n"
+ " xori $1,0x1e \n"
+ " mtc0 $1,$12 \n"
+#endif
+ " irq_enable_hazard \n"
+ " .set pop \n"
+ " .endm");
+
+extern void smtc_ipi_replay(void);
+
+static inline void arch_local_irq_enable(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC kernel needs to do a software replay of queued
+ * IPIs, at the cost of call overhead on each local_irq_enable()
+ */
+ smtc_ipi_replay();
+#endif
+ __asm__ __volatile__(
+ "arch_local_irq_enable"
+ : /* no outputs */
+ : /* no inputs */
+ : "memory");
+}
+
+
+__asm__(
+ " .macro arch_local_save_flags flags \n"
+ " .set push \n"
+ " .set reorder \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ " mfc0 \\flags, $2, 1 \n"
+#else
+ " mfc0 \\flags, $12 \n"
+#endif
+ " .set pop \n"
+ " .endm \n");
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+ asm volatile("arch_local_save_flags %0" : "=r" (flags));
+ return flags;
+}
+
static inline int arch_irqs_disabled_flags(unsigned long flags)
{
@@ -245,7 +188,7 @@ static inline int arch_irqs_disabled_flags(unsigned long flags)
#endif
}
-#endif
+#endif /* #ifndef __ASSEMBLY__ */
/*
* Do the CPU's IRQ-state tracing from assembly code.
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index 8debe9e9175..18806a52061 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -112,12 +112,6 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define TIF_LOAD_WATCH 25 /* If set, load watch registers */
#define TIF_SYSCALL_TRACE 31 /* syscall trace active */
-#ifdef CONFIG_MIPS32_O32
-#define TIF_32BIT TIF_32BIT_REGS
-#elif defined(CONFIG_MIPS32_N32)
-#define TIF_32BIT _TIF_32BIT_ADDR
-#endif /* CONFIG_MIPS32_O32 */
-
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
diff --git a/arch/mips/include/uapi/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h
index 92403c3d600..addd56b6069 100644
--- a/arch/mips/include/uapi/asm/ioctls.h
+++ b/arch/mips/include/uapi/asm/ioctls.h
@@ -86,6 +86,9 @@
#define TIOCGDEV _IOR('T', 0x32, unsigned int) /* Get primary device node of /dev/console */
#define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */
#define TIOCVHANGUP 0x5437
+#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
+#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
+#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
/* I hope the range from 0x5480 on is free ... */
#define TIOCSCTTY 0x5480 /* become controlling tty */
diff --git a/arch/mips/include/uapi/asm/mman.h b/arch/mips/include/uapi/asm/mman.h
index 46d3da0d4b9..9a936ac9a94 100644
--- a/arch/mips/include/uapi/asm/mman.h
+++ b/arch/mips/include/uapi/asm/mman.h
@@ -87,4 +87,15 @@
/* compatibility flags */
#define MAP_FILE 0
+/*
+ * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size.
+ * This gives us 6 bits, which is enough until someone invents 128 bit address
+ * spaces.
+ *
+ * Assume these are all power of twos.
+ * When 0 use the default page size.
+ */
+#define MAP_HUGE_SHIFT 26
+#define MAP_HUGE_MASK 0x3f
+
#endif /* _ASM_MMAN_H */
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index b1fb7af3c35..cce3782c96c 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -510,7 +510,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
c->cputype = CPU_R3000A;
__cpu_name[cpu] = "R3000A";
}
- break;
} else {
c->cputype = CPU_R3000;
__cpu_name[cpu] = "R3000";
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index a6c13321200..9b00362f32f 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -36,6 +36,11 @@ FEXPORT(ret_from_exception)
FEXPORT(ret_from_irq)
LONG_S s0, TI_REGS($28)
FEXPORT(__ret_from_irq)
+/*
+ * We can be coming here from a syscall done in the kernel space,
+ * e.g. a failed kernel_execve().
+ */
+resume_userspace_check:
LONG_L t0, PT_STATUS(sp) # returning to kernel mode?
andi t0, t0, KU_USER
beqz t0, resume_kernel
@@ -162,7 +167,7 @@ work_notifysig: # deal with pending signals and
move a0, sp
li a1, 0
jal do_notify_resume # a2 already loaded
- j resume_userspace
+ j resume_userspace_check
FEXPORT(syscall_exit_partial)
local_irq_disable # make sure need_resched doesn't
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index f6ba8381ee0..86ec03f0e00 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -397,14 +397,14 @@ EXPORT(sysn32_call_table)
PTR sys_timerfd_create
PTR compat_sys_timerfd_gettime /* 6285 */
PTR compat_sys_timerfd_settime
- PTR sys_signalfd4
+ PTR compat_sys_signalfd4
PTR sys_eventfd2
PTR sys_epoll_create1
PTR sys_dup3 /* 6290 */
PTR sys_pipe2
PTR sys_inotify_init1
- PTR sys_preadv
- PTR sys_pwritev
+ PTR compat_sys_preadv
+ PTR compat_sys_pwritev
PTR compat_sys_rt_tgsigqueueinfo /* 6295 */
PTR sys_perf_event_open
PTR sys_accept4
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index a53f8ec37aa..290dc6a1d7a 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -79,7 +79,7 @@ static struct resource data_resource = { .name = "Kernel data", };
void __init add_memory_region(phys_t start, phys_t size, long type)
{
int x = boot_mem_map.nr_map;
- struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1;
+ int i;
/* Sanity check */
if (start + size < start) {
@@ -88,15 +88,29 @@ void __init add_memory_region(phys_t start, phys_t size, long type)
}
/*
- * Try to merge with previous entry if any. This is far less than
- * perfect but is sufficient for most real world cases.
+ * Try to merge with existing entry, if any.
*/
- if (x && prev->addr + prev->size == start && prev->type == type) {
- prev->size += size;
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ struct boot_mem_map_entry *entry = boot_mem_map.map + i;
+ unsigned long top;
+
+ if (entry->type != type)
+ continue;
+
+ if (start + size < entry->addr)
+ continue; /* no overlap */
+
+ if (entry->addr + entry->size < start)
+ continue; /* no overlap */
+
+ top = max(entry->addr + entry->size, start + size);
+ entry->addr = min(entry->addr, start);
+ entry->size = top - entry->addr;
+
return;
}
- if (x == BOOT_MEM_MAP_MAX) {
+ if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) {
pr_err("Ooops! Too many entries in the memory map!\n");
return;
}
diff --git a/arch/mips/lantiq/dts/Makefile b/arch/mips/lantiq/dts/Makefile
index 674fca45f72..6fa72dd641b 100644
--- a/arch/mips/lantiq/dts/Makefile
+++ b/arch/mips/lantiq/dts/Makefile
@@ -1,4 +1 @@
obj-$(CONFIG_DT_EASY50712) := easy50712.dtb.o
-
-$(obj)/%.dtb: $(obj)/%.dts
- $(call if_changed,dtc)
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index c4a82e841c7..eeddc58802e 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -2,8 +2,9 @@
# Makefile for MIPS-specific library files..
#
-lib-y += csum_partial.o delay.o memcpy.o memset.o \
- strlen_user.o strncpy_user.o strnlen_user.o uncached.o
+lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \
+ mips-atomic.o strlen_user.o strncpy_user.o \
+ strnlen_user.o uncached.o
obj-y += iomap.o
obj-$(CONFIG_PCI) += iomap-pci.o
diff --git a/arch/mips/lib/bitops.c b/arch/mips/lib/bitops.c
new file mode 100644
index 00000000000..239a9c957b0
--- /dev/null
+++ b/arch/mips/lib/bitops.c
@@ -0,0 +1,179 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (c) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/bitops.h>
+#include <linux/irqflags.h>
+#include <linux/export.h>
+
+
+/**
+ * __mips_set_bit - Atomically set a bit in memory. This is called by
+ * set_bit() if it cannot find a faster solution.
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ */
+void __mips_set_bit(unsigned long nr, volatile unsigned long *addr)
+{
+ volatile unsigned long *a = addr;
+ unsigned bit = nr & SZLONG_MASK;
+ unsigned long mask;
+ unsigned long flags;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ *a |= mask;
+ raw_local_irq_restore(flags);
+}
+EXPORT_SYMBOL(__mips_set_bit);
+
+
+/**
+ * __mips_clear_bit - Clears a bit in memory. This is called by clear_bit() if
+ * it cannot find a faster solution.
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ */
+void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr)
+{
+ volatile unsigned long *a = addr;
+ unsigned bit = nr & SZLONG_MASK;
+ unsigned long mask;
+ unsigned long flags;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ *a &= ~mask;
+ raw_local_irq_restore(flags);
+}
+EXPORT_SYMBOL(__mips_clear_bit);
+
+
+/**
+ * __mips_change_bit - Toggle a bit in memory. This is called by change_bit()
+ * if it cannot find a faster solution.
+ * @nr: Bit to change
+ * @addr: Address to start counting from
+ */
+void __mips_change_bit(unsigned long nr, volatile unsigned long *addr)
+{
+ volatile unsigned long *a = addr;
+ unsigned bit = nr & SZLONG_MASK;
+ unsigned long mask;
+ unsigned long flags;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ *a ^= mask;
+ raw_local_irq_restore(flags);
+}
+EXPORT_SYMBOL(__mips_change_bit);
+
+
+/**
+ * __mips_test_and_set_bit - Set a bit and return its old value. This is
+ * called by test_and_set_bit() if it cannot find a faster solution.
+ * @nr: Bit to set
+ * @addr: Address to count from
+ */
+int __mips_test_and_set_bit(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ volatile unsigned long *a = addr;
+ unsigned bit = nr & SZLONG_MASK;
+ unsigned long mask;
+ unsigned long flags;
+ unsigned long res;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ res = (mask & *a);
+ *a |= mask;
+ raw_local_irq_restore(flags);
+ return res;
+}
+EXPORT_SYMBOL(__mips_test_and_set_bit);
+
+
+/**
+ * __mips_test_and_set_bit_lock - Set a bit and return its old value. This is
+ * called by test_and_set_bit_lock() if it cannot find a faster solution.
+ * @nr: Bit to set
+ * @addr: Address to count from
+ */
+int __mips_test_and_set_bit_lock(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ volatile unsigned long *a = addr;
+ unsigned bit = nr & SZLONG_MASK;
+ unsigned long mask;
+ unsigned long flags;
+ unsigned long res;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ res = (mask & *a);
+ *a |= mask;
+ raw_local_irq_restore(flags);
+ return res;
+}
+EXPORT_SYMBOL(__mips_test_and_set_bit_lock);
+
+
+/**
+ * __mips_test_and_clear_bit - Clear a bit and return its old value. This is
+ * called by test_and_clear_bit() if it cannot find a faster solution.
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ */
+int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
+{
+ volatile unsigned long *a = addr;
+ unsigned bit = nr & SZLONG_MASK;
+ unsigned long mask;
+ unsigned long flags;
+ unsigned long res;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ res = (mask & *a);
+ *a &= ~mask;
+ raw_local_irq_restore(flags);
+ return res;
+}
+EXPORT_SYMBOL(__mips_test_and_clear_bit);
+
+
+/**
+ * __mips_test_and_change_bit - Change a bit and return its old value. This is
+ * called by test_and_change_bit() if it cannot find a faster solution.
+ * @nr: Bit to change
+ * @addr: Address to count from
+ */
+int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
+{
+ volatile unsigned long *a = addr;
+ unsigned bit = nr & SZLONG_MASK;
+ unsigned long mask;
+ unsigned long flags;
+ unsigned long res;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ res = (mask & *a);
+ *a ^= mask;
+ raw_local_irq_restore(flags);
+ return res;
+}
+EXPORT_SYMBOL(__mips_test_and_change_bit);
diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c
new file mode 100644
index 00000000000..cd160be3ce4
--- /dev/null
+++ b/arch/mips/lib/mips-atomic.c
@@ -0,0 +1,176 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle
+ * Copyright (C) 1996 by Paul M. Antoine
+ * Copyright (C) 1999 Silicon Graphics
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ */
+#include <asm/irqflags.h>
+#include <asm/hazards.h>
+#include <linux/compiler.h>
+#include <linux/preempt.h>
+#include <linux/export.h>
+
+#if !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC)
+
+/*
+ * For cli() we have to insert nops to make sure that the new value
+ * has actually arrived in the status register before the end of this
+ * macro.
+ * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
+ * no nops at all.
+ */
+/*
+ * For TX49, operating only IE bit is not enough.
+ *
+ * If mfc0 $12 follows store and the mfc0 is last instruction of a
+ * page and fetching the next instruction causes TLB miss, the result
+ * of the mfc0 might wrongly contain EXL bit.
+ *
+ * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
+ *
+ * Workaround: mask EXL bit of the result or place a nop before mfc0.
+ */
+__asm__(
+ " .macro arch_local_irq_disable\n"
+ " .set push \n"
+ " .set noat \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ " mfc0 $1, $2, 1 \n"
+ " ori $1, 0x400 \n"
+ " .set noreorder \n"
+ " mtc0 $1, $2, 1 \n"
+#elif defined(CONFIG_CPU_MIPSR2)
+ /* see irqflags.h for inline function */
+#else
+ " mfc0 $1,$12 \n"
+ " ori $1,0x1f \n"
+ " xori $1,0x1f \n"
+ " .set noreorder \n"
+ " mtc0 $1,$12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set pop \n"
+ " .endm \n");
+
+notrace void arch_local_irq_disable(void)
+{
+ preempt_disable();
+ __asm__ __volatile__(
+ "arch_local_irq_disable"
+ : /* no outputs */
+ : /* no inputs */
+ : "memory");
+ preempt_enable();
+}
+EXPORT_SYMBOL(arch_local_irq_disable);
+
+
+__asm__(
+ " .macro arch_local_irq_save result \n"
+ " .set push \n"
+ " .set reorder \n"
+ " .set noat \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ " mfc0 \\result, $2, 1 \n"
+ " ori $1, \\result, 0x400 \n"
+ " .set noreorder \n"
+ " mtc0 $1, $2, 1 \n"
+ " andi \\result, \\result, 0x400 \n"
+#elif defined(CONFIG_CPU_MIPSR2)
+ /* see irqflags.h for inline function */
+#else
+ " mfc0 \\result, $12 \n"
+ " ori $1, \\result, 0x1f \n"
+ " xori $1, 0x1f \n"
+ " .set noreorder \n"
+ " mtc0 $1, $12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set pop \n"
+ " .endm \n");
+
+notrace unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags;
+ preempt_disable();
+ asm volatile("arch_local_irq_save\t%0"
+ : "=r" (flags)
+ : /* no inputs */
+ : "memory");
+ preempt_enable();
+ return flags;
+}
+EXPORT_SYMBOL(arch_local_irq_save);
+
+
+__asm__(
+ " .macro arch_local_irq_restore flags \n"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set noat \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ "mfc0 $1, $2, 1 \n"
+ "andi \\flags, 0x400 \n"
+ "ori $1, 0x400 \n"
+ "xori $1, 0x400 \n"
+ "or \\flags, $1 \n"
+ "mtc0 \\flags, $2, 1 \n"
+#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
+ /* see irqflags.h for inline function */
+#elif defined(CONFIG_CPU_MIPSR2)
+ /* see irqflags.h for inline function */
+#else
+ " mfc0 $1, $12 \n"
+ " andi \\flags, 1 \n"
+ " ori $1, 0x1f \n"
+ " xori $1, 0x1f \n"
+ " or \\flags, $1 \n"
+ " mtc0 \\flags, $12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set pop \n"
+ " .endm \n");
+
+notrace void arch_local_irq_restore(unsigned long flags)
+{
+ unsigned long __tmp1;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC kernel needs to do a software replay of queued
+ * IPIs, at the cost of branch and call overhead on each
+ * local_irq_restore()
+ */
+ if (unlikely(!(flags & 0x0400)))
+ smtc_ipi_replay();
+#endif
+ preempt_disable();
+ __asm__ __volatile__(
+ "arch_local_irq_restore\t%0"
+ : "=r" (__tmp1)
+ : "0" (flags)
+ : "memory");
+ preempt_enable();
+}
+EXPORT_SYMBOL(arch_local_irq_restore);
+
+
+notrace void __arch_local_irq_restore(unsigned long flags)
+{
+ unsigned long __tmp1;
+
+ preempt_disable();
+ __asm__ __volatile__(
+ "arch_local_irq_restore\t%0"
+ : "=r" (__tmp1)
+ : "0" (flags)
+ : "memory");
+ preempt_enable();
+}
+EXPORT_SYMBOL(__arch_local_irq_restore);
+
+#endif /* !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) */
diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c
index e92d59c4bd7..0412ad61e29 100644
--- a/arch/mips/loongson1/common/platform.c
+++ b/arch/mips/loongson1/common/platform.c
@@ -13,6 +13,7 @@
#include <linux/phy.h>
#include <linux/serial_8250.h>
#include <linux/stmmac.h>
+#include <linux/usb/ehci_pdriver.h>
#include <asm-generic/sizes.h>
#include <loongson1.h>
@@ -107,13 +108,17 @@ static struct resource ls1x_ehci_resources[] = {
},
};
+static struct usb_ehci_pdata ls1x_ehci_pdata = {
+};
+
struct platform_device ls1x_ehci_device = {
- .name = "ls1x-ehci",
+ .name = "ehci-platform",
.id = -1,
.num_resources = ARRAY_SIZE(ls1x_ehci_resources),
.resource = ls1x_ehci_resources,
.dev = {
.dma_mask = &ls1x_ehci_dmamask,
+ .platform_data = &ls1x_ehci_pdata,
},
};
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index 302d779d5b0..d9be7540a6b 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -45,18 +45,6 @@ static unsigned long mmap_base(unsigned long rnd)
return PAGE_ALIGN(TASK_SIZE - gap - rnd);
}
-static inline unsigned long COLOUR_ALIGN_DOWN(unsigned long addr,
- unsigned long pgoff)
-{
- unsigned long base = addr & ~shm_align_mask;
- unsigned long off = (pgoff << PAGE_SHIFT) & shm_align_mask;
-
- if (base + off <= addr)
- return base + off;
-
- return base - off;
-}
-
#define COLOUR_ALIGN(addr, pgoff) \
((((addr) + shm_align_mask) & ~shm_align_mask) + \
(((pgoff) << PAGE_SHIFT) & shm_align_mask))
@@ -71,6 +59,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
struct vm_area_struct *vma;
unsigned long addr = addr0;
int do_color_align;
+ struct vm_unmapped_area_info info;
if (unlikely(len > TASK_SIZE))
return -ENOMEM;
@@ -107,97 +96,31 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
return addr;
}
- if (dir == UP) {
- addr = mm->mmap_base;
- if (do_color_align)
- addr = COLOUR_ALIGN(addr, pgoff);
- else
- addr = PAGE_ALIGN(addr);
+ info.length = len;
+ info.align_mask = do_color_align ? (PAGE_MASK & shm_align_mask) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
- for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
- /* At this point: (!vma || addr < vma->vm_end). */
- if (TASK_SIZE - len < addr)
- return -ENOMEM;
- if (!vma || addr + len <= vma->vm_start)
- return addr;
- addr = vma->vm_end;
- if (do_color_align)
- addr = COLOUR_ALIGN(addr, pgoff);
- }
- } else {
- /* check if free_area_cache is useful for us */
- if (len <= mm->cached_hole_size) {
- mm->cached_hole_size = 0;
- mm->free_area_cache = mm->mmap_base;
- }
+ if (dir == DOWN) {
+ info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+ info.low_limit = PAGE_SIZE;
+ info.high_limit = mm->mmap_base;
+ addr = vm_unmapped_area(&info);
+
+ if (!(addr & ~PAGE_MASK))
+ return addr;
- /*
- * either no address requested, or the mapping can't fit into
- * the requested address hole
- */
- addr = mm->free_area_cache;
- if (do_color_align) {
- unsigned long base =
- COLOUR_ALIGN_DOWN(addr - len, pgoff);
- addr = base + len;
- }
-
- /* make sure it can fit in the remaining address space */
- if (likely(addr > len)) {
- vma = find_vma(mm, addr - len);
- if (!vma || addr <= vma->vm_start) {
- /* cache the address as a hint for next time */
- return mm->free_area_cache = addr - len;
- }
- }
-
- if (unlikely(mm->mmap_base < len))
- goto bottomup;
-
- addr = mm->mmap_base - len;
- if (do_color_align)
- addr = COLOUR_ALIGN_DOWN(addr, pgoff);
-
- do {
- /*
- * Lookup failure means no vma is above this address,
- * else if new region fits below vma->vm_start,
- * return with success:
- */
- vma = find_vma(mm, addr);
- if (likely(!vma || addr + len <= vma->vm_start)) {
- /* cache the address as a hint for next time */
- return mm->free_area_cache = addr;
- }
-
- /* remember the largest hole we saw so far */
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
-
- /* try just below the current vma->vm_start */
- addr = vma->vm_start - len;
- if (do_color_align)
- addr = COLOUR_ALIGN_DOWN(addr, pgoff);
- } while (likely(len < vma->vm_start));
-
-bottomup:
/*
* A failed mmap() very likely causes application failure,
* so fall back to the bottom-up function here. This scenario
* can happen with large stack limits and large mmap()
* allocations.
*/
- mm->cached_hole_size = ~0UL;
- mm->free_area_cache = TASK_UNMAPPED_BASE;
- addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
- /*
- * Restore the topdown base:
- */
- mm->free_area_cache = mm->mmap_base;
- mm->cached_hole_size = ~0UL;
-
- return addr;
}
+
+ info.flags = 0;
+ info.low_limit = mm->mmap_base;
+ info.high_limit = TASK_SIZE;
+ return vm_unmapped_area(&info);
}
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0,
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 4b9b935a070..88e79ad6f81 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -120,18 +120,11 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
if (cpu_context(cpu, mm) != 0) {
unsigned long size, flags;
- int huge = is_vm_hugetlb_page(vma);
ENTER_CRITICAL(flags);
- if (huge) {
- start = round_down(start, HPAGE_SIZE);
- end = round_up(end, HPAGE_SIZE);
- size = (end - start) >> HPAGE_SHIFT;
- } else {
- start = round_down(start, PAGE_SIZE << 1);
- end = round_up(end, PAGE_SIZE << 1);
- size = (end - start) >> (PAGE_SHIFT + 1);
- }
+ start = round_down(start, PAGE_SIZE << 1);
+ end = round_up(end, PAGE_SIZE << 1);
+ size = (end - start) >> (PAGE_SHIFT + 1);
if (size <= current_cpu_data.tlbsize/2) {
int oldpid = read_c0_entryhi();
int newpid = cpu_asid(cpu, mm);
@@ -140,10 +133,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
int idx;
write_c0_entryhi(start | newpid);
- if (huge)
- start += HPAGE_SIZE;
- else
- start += (PAGE_SIZE << 1);
+ start += (PAGE_SIZE << 1);
mtc0_tlbw_hazard();
tlb_probe();
tlb_probe_hazard();
diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c
index 80562b81f0f..74732177851 100644
--- a/arch/mips/mti-malta/malta-platform.c
+++ b/arch/mips/mti-malta/malta-platform.c
@@ -29,6 +29,7 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_device.h>
+#include <asm/mips-boards/maltaint.h>
#include <mtd/mtd-abi.h>
#define SMC_PORT(base, int) \
@@ -48,7 +49,7 @@ static struct plat_serial8250_port uart8250_data[] = {
SMC_PORT(0x2F8, 3),
{
.mapbase = 0x1f000900, /* The CBUS UART */
- .irq = MIPS_CPU_IRQ_BASE + 2,
+ .irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2,
.uartclk = 3686400, /* Twice the usual clk! */
.iotype = UPIO_MEM32,
.flags = CBUS_UART_FLAGS,
diff --git a/arch/mips/netlogic/dts/Makefile b/arch/mips/netlogic/dts/Makefile
index 67ae3fe296f..d117d46413a 100644
--- a/arch/mips/netlogic/dts/Makefile
+++ b/arch/mips/netlogic/dts/Makefile
@@ -1,4 +1 @@
obj-$(CONFIG_DT_XLP_EVP) := xlp_evp.dtb.o
-
-$(obj)/%.dtb: $(obj)/%.dts
- $(call if_changed,dtc)
diff --git a/arch/mips/netlogic/xlr/platform.c b/arch/mips/netlogic/xlr/platform.c
index 71b44d82621..507230eeb76 100644
--- a/arch/mips/netlogic/xlr/platform.c
+++ b/arch/mips/netlogic/xlr/platform.c
@@ -15,6 +15,8 @@
#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
#include <linux/i2c.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
#include <asm/netlogic/haldefs.h>
#include <asm/netlogic/xlr/iomap.h>
@@ -123,12 +125,18 @@ static u64 xls_usb_dmamask = ~(u32)0;
}, \
}
+static struct usb_ehci_pdata xls_usb_ehci_pdata = {
+ .caps_offset = 0,
+};
+
+static struct usb_ohci_pdata xls_usb_ohci_pdata;
+
static struct platform_device xls_usb_ehci_device =
- USB_PLATFORM_DEV("ehci-xls", 0, PIC_USB_IRQ);
+ USB_PLATFORM_DEV("ehci-platform", 0, PIC_USB_IRQ);
static struct platform_device xls_usb_ohci_device_0 =
- USB_PLATFORM_DEV("ohci-xls-0", 1, PIC_USB_IRQ);
+ USB_PLATFORM_DEV("ohci-platform", 1, PIC_USB_IRQ);
static struct platform_device xls_usb_ohci_device_1 =
- USB_PLATFORM_DEV("ohci-xls-1", 2, PIC_USB_IRQ);
+ USB_PLATFORM_DEV("ohci-platform", 2, PIC_USB_IRQ);
static struct platform_device *xls_platform_devices[] = {
&xls_usb_ehci_device,
@@ -172,14 +180,17 @@ int xls_platform_usb_init(void)
memres = CPHYSADDR((unsigned long)usb_mmio);
xls_usb_ehci_device.resource[0].start = memres;
xls_usb_ehci_device.resource[0].end = memres + 0x400 - 1;
+ xls_usb_ehci_device.dev.platform_data = &xls_usb_ehci_pdata;
memres += 0x400;
xls_usb_ohci_device_0.resource[0].start = memres;
xls_usb_ohci_device_0.resource[0].end = memres + 0x400 - 1;
+ xls_usb_ohci_device_0.dev.platform_data = &xls_usb_ohci_pdata;
memres += 0x400;
xls_usb_ohci_device_1.resource[0].start = memres;
xls_usb_ohci_device_1.resource[0].end = memres + 0x400 - 1;
+ xls_usb_ohci_device_1.dev.platform_data = &xls_usb_ohci_pdata;
return platform_add_devices(xls_platform_devices,
ARRAY_SIZE(xls_platform_devices));
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 04e35bcde07..4040416e060 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -313,10 +313,8 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
}
}
-#ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL(PCIBIOS_MIN_IO);
EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
-#endif
int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine)
diff --git a/arch/mips/pnx8550/common/platform.c b/arch/mips/pnx8550/common/platform.c
index 5264cc09a27..0a8faeaa7b7 100644
--- a/arch/mips/pnx8550/common/platform.c
+++ b/arch/mips/pnx8550/common/platform.c
@@ -20,6 +20,7 @@
#include <linux/serial.h>
#include <linux/serial_pnx8xxx.h>
#include <linux/platform_device.h>
+#include <linux/usb/ohci_pdriver.h>
#include <int.h>
#include <usb.h>
@@ -96,12 +97,40 @@ static u64 ohci_dmamask = DMA_BIT_MASK(32);
static u64 uart_dmamask = DMA_BIT_MASK(32);
+static int pnx8550_usb_ohci_power_on(struct platform_device *pdev)
+{
+ /*
+ * Set register CLK48CTL to enable and 48MHz
+ */
+ outl(0x00000003, PCI_BASE | 0x0004770c);
+
+ /*
+ * Set register CLK12CTL to enable and 48MHz
+ */
+ outl(0x00000003, PCI_BASE | 0x00047710);
+
+ udelay(100);
+
+ return 0;
+}
+
+static void pnx8550_usb_ohci_power_off(struct platform_device *pdev)
+{
+ udelay(10);
+}
+
+static struct usb_ohci_pdata pnx8550_usb_ohci_pdata = {
+ .power_on = pnx8550_usb_ohci_power_on,
+ .power_off = pnx8550_usb_ohci_power_off,
+};
+
static struct platform_device pnx8550_usb_ohci_device = {
- .name = "pnx8550-ohci",
+ .name = "ohci-platform",
.id = -1,
.dev = {
.dma_mask = &ohci_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &pnx8550_usb_ohci_pdata,
},
.num_resources = ARRAY_SIZE(pnx8550_usb_ohci_resources),
.resource = pnx8550_usb_ohci_resources,
diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild
index 4a159da2363..c5d76702830 100644
--- a/arch/mn10300/include/asm/Kbuild
+++ b/arch/mn10300/include/asm/Kbuild
@@ -1,3 +1,4 @@
generic-y += clkdev.h
generic-y += exec.h
+generic-y += trace_clock.h
diff --git a/arch/openrisc/Makefile b/arch/openrisc/Makefile
index 966886c8daf..4739b8302a5 100644
--- a/arch/openrisc/Makefile
+++ b/arch/openrisc/Makefile
@@ -50,6 +50,6 @@ BUILTIN_DTB := y
else
BUILTIN_DTB := n
endif
-core-$(BUILTIN_DTB) += arch/openrisc/boot/
+core-$(BUILTIN_DTB) += arch/openrisc/boot/dts/
all: vmlinux
diff --git a/arch/openrisc/boot/Makefile b/arch/openrisc/boot/dts/Makefile
index 09958358601..b092d30d6c2 100644
--- a/arch/openrisc/boot/Makefile
+++ b/arch/openrisc/boot/dts/Makefile
@@ -1,5 +1,3 @@
-
-
ifneq '$(CONFIG_OPENRISC_BUILTIN_DTB)' '""'
BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_OPENRISC_BUILTIN_DTB)).dtb.o
else
@@ -10,6 +8,3 @@ obj-y += $(BUILTIN_DTB)
clean-files := *.dtb.S
#DTC_FLAGS ?= -p 1024
-
-$(obj)/%.dtb: $(src)/dts/%.dts FORCE
- $(call if_changed_dep,dtc)
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index 78de6805268..8971026e1c6 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -60,6 +60,7 @@ generic-y += swab.h
generic-y += termbits.h
generic-y += termios.h
generic-y += topology.h
+generic-y += trace_clock.h
generic-y += types.h
generic-y += ucontext.h
generic-y += user.h
diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c
index 30110297f4f..ddedc8a7786 100644
--- a/arch/openrisc/kernel/signal.c
+++ b/arch/openrisc/kernel/signal.c
@@ -84,7 +84,6 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs)
{
struct rt_sigframe *frame = (struct rt_sigframe __user *)regs->sp;
sigset_t set;
- stack_t st;
/*
* Since we stacked the signal on a dword boundary,
@@ -104,11 +103,10 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs)
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
goto badframe;
- if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
- goto badframe;
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
- do_sigaltstack(&st, NULL, regs->sp);
+ if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
+ goto badframe;
return regs->gpr[11];
diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild
index bac8debecff..ff4c9faed54 100644
--- a/arch/parisc/include/asm/Kbuild
+++ b/arch/parisc/include/asm/Kbuild
@@ -3,3 +3,4 @@ generic-y += word-at-a-time.h auxvec.h user.h cputime.h emergency-restart.h \
segment.h topology.h vga.h device.h percpu.h hw_irq.h mutex.h \
div64.h irq_regs.h kdebug.h kvm_para.h local64.h local.h param.h \
poll.h xor.h clkdev.h exec.h
+generic-y += trace_clock.h
diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h
index 054ec06f9e2..66719c38a36 100644
--- a/arch/parisc/include/uapi/asm/ioctls.h
+++ b/arch/parisc/include/uapi/asm/ioctls.h
@@ -55,6 +55,9 @@
#define TIOCGDEV _IOR('T',0x32, int) /* Get primary device node of /dev/console */
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
#define TIOCVHANGUP 0x5437
+#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
+#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
+#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
#define FIOCLEX 0x5451
diff --git a/arch/parisc/include/uapi/asm/mman.h b/arch/parisc/include/uapi/asm/mman.h
index 12219ebce86..294d251ca7b 100644
--- a/arch/parisc/include/uapi/asm/mman.h
+++ b/arch/parisc/include/uapi/asm/mman.h
@@ -70,4 +70,15 @@
#define MAP_FILE 0
#define MAP_VARIABLE 0
+/*
+ * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size.
+ * This gives us 6 bits, which is enough until someone invents 128 bit address
+ * spaces.
+ *
+ * Assume these are all power of twos.
+ * When 0 use the default page size.
+ */
+#define MAP_HUGE_SHIFT 26
+#define MAP_HUGE_MASK 0x3f
+
#endif /* __PARISC_MMAN_H__ */
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
index 88238638aee..efc5e7d3053 100644
--- a/arch/parisc/kernel/pdc_cons.c
+++ b/arch/parisc/kernel/pdc_cons.c
@@ -186,13 +186,13 @@ static int __init pdc_console_tty_driver_init(void)
printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n");
pdc_cons.flags &= ~CON_BOOT;
- tty_port_init(&tty_port);
-
pdc_console_tty_driver = alloc_tty_driver(1);
if (!pdc_console_tty_driver)
return -ENOMEM;
+ tty_port_init(&tty_port);
+
pdc_console_tty_driver->driver_name = "pdc_cons";
pdc_console_tty_driver->name = "ttyB";
pdc_console_tty_driver->major = MUX_MAJOR;
@@ -207,6 +207,7 @@ static int __init pdc_console_tty_driver_init(void)
err = tty_register_driver(pdc_console_tty_driver);
if (err) {
printk(KERN_ERR "Unable to register the PDC console TTY driver\n");
+ tty_port_destroy(&tty_port);
return err;
}
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
index fd49aeda9eb..5dede04f2f3 100644
--- a/arch/parisc/kernel/signal32.c
+++ b/arch/parisc/kernel/signal32.c
@@ -65,7 +65,8 @@ put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
{
compat_sigset_t s;
- if (sz != sizeof *set) panic("put_sigset32()");
+ if (sz != sizeof *set)
+ return -EINVAL;
sigset_64to32(&s, set);
return copy_to_user(up, &s, sizeof s);
@@ -77,7 +78,8 @@ get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
compat_sigset_t s;
int r;
- if (sz != sizeof *set) panic("put_sigset32()");
+ if (sz != sizeof *set)
+ return -EINVAL;
if ((r = copy_from_user(&s, up, sz)) == 0) {
sigset_32to64(set, &s);
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 7426e40699b..f76c10863c6 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -73,6 +73,8 @@ static unsigned long get_shared_area(struct address_space *mapping,
struct vm_area_struct *vma;
int offset = mapping ? get_offset(mapping) : 0;
+ offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000;
+
addr = DCACHE_ALIGN(addr - offset) + offset;
for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 3735abd7f8f..cbf5d59d5d6 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -60,7 +60,7 @@
ENTRY_SAME(fork_wrapper)
ENTRY_SAME(read)
ENTRY_SAME(write)
- ENTRY_SAME(open) /* 5 */
+ ENTRY_COMP(open) /* 5 */
ENTRY_SAME(close)
ENTRY_SAME(waitpid)
ENTRY_SAME(creat)
diff --git a/arch/powerpc/boot/dts/mpc5200b.dtsi b/arch/powerpc/boot/dts/mpc5200b.dtsi
index 7ab286ab530..39ed65a44c5 100644
--- a/arch/powerpc/boot/dts/mpc5200b.dtsi
+++ b/arch/powerpc/boot/dts/mpc5200b.dtsi
@@ -231,6 +231,12 @@
interrupts = <2 7 0>;
};
+ sclpc@3c00 {
+ compatible = "fsl,mpc5200-lpbfifo";
+ reg = <0x3c00 0x60>;
+ interrupts = <2 23 0>;
+ };
+
i2c@3d00 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/powerpc/boot/dts/o2d.dtsi b/arch/powerpc/boot/dts/o2d.dtsi
index 3444eb8f0ad..24f66803929 100644
--- a/arch/powerpc/boot/dts/o2d.dtsi
+++ b/arch/powerpc/boot/dts/o2d.dtsi
@@ -86,12 +86,6 @@
reg = <0>;
};
};
-
- sclpc@3c00 {
- compatible = "fsl,mpc5200-lpbfifo";
- reg = <0x3c00 0x60>;
- interrupts = <3 23 0>;
- };
};
localbus {
diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm030.dts
index 9e354997eb7..96512c05803 100644
--- a/arch/powerpc/boot/dts/pcm030.dts
+++ b/arch/powerpc/boot/dts/pcm030.dts
@@ -59,7 +59,7 @@
#gpio-cells = <2>;
};
- psc@2000 { /* PSC1 in ac97 mode */
+ audioplatform: psc@2000 { /* PSC1 in ac97 mode */
compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97";
cell-index = <0>;
};
@@ -134,4 +134,9 @@
localbus {
status = "disabled";
};
+
+ sound {
+ compatible = "phytec,pcm030-audio-fabric";
+ asoc-platform = <&audioplatform>;
+ };
};
diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild
index a4fe15e33c6..2d62b484b3f 100644
--- a/arch/powerpc/include/asm/Kbuild
+++ b/arch/powerpc/include/asm/Kbuild
@@ -2,3 +2,4 @@
generic-y += clkdev.h
generic-y += rwsem.h
+generic-y += trace_clock.h
diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h
index 487d46ff68a..483733bd06d 100644
--- a/arch/powerpc/include/asm/cputime.h
+++ b/arch/powerpc/include/asm/cputime.h
@@ -228,6 +228,8 @@ static inline cputime_t clock_t_to_cputime(const unsigned long clk)
#define cputime64_to_clock_t(ct) cputime_to_clock_t((cputime_t)(ct))
+static inline void arch_vtime_task_switch(struct task_struct *tsk) { }
+
#endif /* __KERNEL__ */
#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
#endif /* __POWERPC_CPUTIME_H */
diff --git a/arch/powerpc/include/uapi/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h
index e9b78870aaa..49a25796a61 100644
--- a/arch/powerpc/include/uapi/asm/ioctls.h
+++ b/arch/powerpc/include/uapi/asm/ioctls.h
@@ -97,6 +97,9 @@
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
#define TIOCVHANGUP 0x5437
+#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
+#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
+#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
#define TIOCSERCONFIG 0x5453
#define TIOCSERGWILD 0x5454
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 7f94f760dd0..abc0d085699 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1428,8 +1428,6 @@ void __init pcibios_resource_survey(void)
ppc_md.pcibios_fixup();
}
-#ifdef CONFIG_HOTPLUG
-
/* This is used by the PCI hotplug driver to allocate resource
* of newly plugged busses. We can try to consolidate with the
* rest of the code later, for now, keep it as-is as our main
@@ -1488,8 +1486,6 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus)
}
EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus);
-#endif /* CONFIG_HOTPLUG */
-
int pcibios_enable_device(struct pci_dev *dev, int mask)
{
if (ppc_md.pcibios_enable_device_hook)
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 4ff190ff24a..2cbe6768fdd 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -74,8 +74,6 @@ static int __init pcibios_init(void)
subsys_initcall(pcibios_init);
-#ifdef CONFIG_HOTPLUG
-
int pcibios_unmap_io_space(struct pci_bus *bus)
{
struct pci_controller *hose;
@@ -124,8 +122,6 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
}
EXPORT_SYMBOL_GPL(pcibios_unmap_io_space);
-#endif /* CONFIG_HOTPLUG */
-
static int __devinit pcibios_map_phb_io_space(struct pci_controller *hose)
{
struct vm_struct *area;
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index a2dc75793bd..3b997118df5 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -158,10 +158,8 @@ static int do_signal(struct pt_regs *regs)
void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
{
- if (thread_info_flags & _TIF_UPROBE) {
- clear_thread_flag(TIF_UPROBE);
+ if (thread_info_flags & _TIF_UPROBE)
uprobe_notify_resume(regs);
- }
if (thread_info_flags & _TIF_SIGPENDING)
do_signal(regs);
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index cf357a059dd..3ce1f864c2d 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -607,7 +607,7 @@ static void register_nodes(void)
int sysfs_add_device_to_node(struct device *dev, int nid)
{
- struct node *node = &node_devices[nid];
+ struct node *node = node_devices[nid];
return sysfs_create_link(&node->dev.kobj, &dev->kobj,
kobject_name(&dev->kobj));
}
@@ -615,7 +615,7 @@ EXPORT_SYMBOL_GPL(sysfs_add_device_to_node);
void sysfs_remove_device_from_node(struct device *dev, int nid)
{
- struct node *node = &node_devices[nid];
+ struct node *node = node_devices[nid];
sysfs_remove_link(&node->dev.kobj, kobject_name(&dev->kobj));
}
EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node);
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index ce4cb772dc7..b3b14352b05 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -297,6 +297,8 @@ static u64 vtime_delta(struct task_struct *tsk,
u64 now, nowscaled, deltascaled;
u64 udelta, delta, user_scaled;
+ WARN_ON_ONCE(!irqs_disabled());
+
now = mftb();
nowscaled = read_spurr(now);
get_paca()->system_time += now - get_paca()->starttime;
@@ -355,15 +357,15 @@ void vtime_account_idle(struct task_struct *tsk)
}
/*
- * Transfer the user and system times accumulated in the paca
- * by the exception entry and exit code to the generic process
- * user and system time records.
+ * Transfer the user time accumulated in the paca
+ * by the exception entry and exit code to the generic
+ * process user time records.
* Must be called with interrupts disabled.
- * Assumes that vtime_account() has been called recently
- * (i.e. since the last entry from usermode) so that
+ * Assumes that vtime_account_system/idle() has been called
+ * recently (i.e. since the last entry from usermode) so that
* get_paca()->user_time_scaled is up to date.
*/
-void account_process_tick(struct task_struct *tsk, int user_tick)
+void vtime_account_user(struct task_struct *tsk)
{
cputime_t utime, utimescaled;
@@ -375,12 +377,6 @@ void account_process_tick(struct task_struct *tsk, int user_tick)
account_user_time(tsk, utime, utimescaled);
}
-void vtime_task_switch(struct task_struct *prev)
-{
- vtime_account(prev);
- account_process_tick(prev, 0);
-}
-
#else /* ! CONFIG_VIRT_CPU_ACCOUNTING */
#define calc_cputime_factors()
#endif
diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
index d2d46d1014f..bc77834dbf4 100644
--- a/arch/powerpc/kernel/uprobes.c
+++ b/arch/powerpc/kernel/uprobes.c
@@ -64,6 +64,8 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
autask->saved_trap_nr = current->thread.trap_nr;
current->thread.trap_nr = UPROBE_TRAP_NR;
regs->nip = current->utask->xol_vaddr;
+
+ user_enable_single_step(current);
return 0;
}
@@ -119,6 +121,8 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
* to be executed.
*/
regs->nip = utask->vaddr + MAX_UINSN_BYTES;
+
+ user_disable_single_step(current);
return 0;
}
@@ -162,6 +166,8 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
current->thread.trap_nr = utask->autask.saved_trap_nr;
instruction_pointer_set(regs, utask->vaddr);
+
+ user_disable_single_step(current);
}
/*
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 8520b58a5e9..b89ef65392d 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -372,10 +372,11 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break;
case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break;
case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break;
- default:
- pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n",
- __func__, virq, l1irq, l2irq);
- return -EINVAL;
+ case MPC52xx_IRQ_L1_CRIT:
+ pr_warn("%s: Critical IRQ #%d is unsupported! Nopping it.\n",
+ __func__, l2irq);
+ irq_set_chip(virq, &no_irq_chip);
+ return 0;
}
irq_set_chip_and_handler(virq, irqchip, handle_level_irq);
diff --git a/arch/powerpc/platforms/cell/celleb_pci.c b/arch/powerpc/platforms/cell/celleb_pci.c
index abc8af43ea7..173568140a3 100644
--- a/arch/powerpc/platforms/cell/celleb_pci.c
+++ b/arch/powerpc/platforms/cell/celleb_pci.c
@@ -401,11 +401,11 @@ error:
} else {
if (config && *config) {
size = 256;
- free_bootmem((unsigned long)(*config), size);
+ free_bootmem(__pa(*config), size);
}
if (res && *res) {
size = sizeof(struct celleb_pci_resource);
- free_bootmem((unsigned long)(*res), size);
+ free_bootmem(__pa(*res), size);
}
}
diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c
index b0c3777528a..d588e48dff7 100644
--- a/arch/powerpc/platforms/powermac/pfunc_core.c
+++ b/arch/powerpc/platforms/powermac/pfunc_core.c
@@ -686,7 +686,7 @@ static int pmf_add_functions(struct pmf_device *dev, void *driverdata)
int count = 0;
for (pp = dev->node->properties; pp != 0; pp = pp->next) {
- char *name;
+ const char *name;
if (strncmp(pp->name, PP_PREFIX, plen) != 0)
continue;
name = pp->name + plen;
diff --git a/arch/powerpc/platforms/pseries/eeh_pe.c b/arch/powerpc/platforms/pseries/eeh_pe.c
index 797cd181dc3..d16c8ded108 100644
--- a/arch/powerpc/platforms/pseries/eeh_pe.c
+++ b/arch/powerpc/platforms/pseries/eeh_pe.c
@@ -449,7 +449,7 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe)
if (list_empty(&pe->edevs)) {
cnt = 0;
list_for_each_entry(child, &pe->child_list, child) {
- if (!(pe->type & EEH_PE_INVALID)) {
+ if (!(child->type & EEH_PE_INVALID)) {
cnt++;
break;
}
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index d19f4977c83..e5b08472313 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -220,7 +220,8 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
/* Get the top level device in the PE */
edev = of_node_to_eeh_dev(dn);
- edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list);
+ if (edev->pe)
+ edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list);
dn = eeh_dev_to_of_node(edev);
if (!dn)
return NULL;
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
index 45d00e5fe14..4d806b41960 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -36,7 +36,7 @@ static struct cpuidle_state *cpuidle_state_table;
static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before)
{
- *kt_before = ktime_get_real();
+ *kt_before = ktime_get();
*in_purr = mfspr(SPRN_PURR);
/*
* Indicate to the HV that we are idle. Now would be
@@ -50,7 +50,7 @@ static inline s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before)
get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr;
get_lppaca()->idle = 0;
- return ktime_to_us(ktime_sub(ktime_get_real(), kt_before));
+ return ktime_to_us(ktime_sub(ktime_get(), kt_before));
}
static int snooze_loop(struct cpuidle_device *dev,
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 39f71fba9b3..2f4668136b2 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -281,12 +281,11 @@ static struct property *new_property(const char *name, const int length,
if (!new)
return NULL;
- if (!(new->name = kmalloc(strlen(name) + 1, GFP_KERNEL)))
+ if (!(new->name = kstrdup(name, GFP_KERNEL)))
goto cleanup;
if (!(new->value = kmalloc(length + 1, GFP_KERNEL)))
goto cleanup;
- strcpy(new->name, name);
memcpy(new->value, value, length);
*(((char *)new->value) + length) = 0;
new->length = length;
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index ffb93ae9379..01b62a62c63 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -136,7 +136,7 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
u32 pcicsrbar = 0, pcicsrbar_sz;
u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL |
PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
- char *name = hose->dn->full_name;
+ const char *name = hose->dn->full_name;
const u64 *reg;
int len;
diff --git a/arch/powerpc/sysdev/scom.c b/arch/powerpc/sysdev/scom.c
index 702256a1ca1..9193e12df69 100644
--- a/arch/powerpc/sysdev/scom.c
+++ b/arch/powerpc/sysdev/scom.c
@@ -157,7 +157,7 @@ static int scom_debug_init_one(struct dentry *root, struct device_node *dn,
ent->map = SCOM_MAP_INVALID;
spin_lock_init(&ent->lock);
snprintf(ent->name, 8, "scom%d", i);
- ent->blob.data = dn->full_name;
+ ent->blob.data = (void*) dn->full_name;
ent->blob.size = strlen(dn->full_name);
dir = debugfs_create_dir(ent->name, root);
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 5dba755a43e..d385f396dfe 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -96,6 +96,7 @@ config S390
select HAVE_MEMBLOCK_NODE_MAP
select HAVE_CMPXCHG_LOCAL
select HAVE_CMPXCHG_DOUBLE
+ select HAVE_ALIGNED_STRUCT_PAGE if SLUB
select HAVE_VIRT_CPU_ACCOUNTING
select VIRT_CPU_ACCOUNTING
select ARCH_DISCARD_MEMBLOCK
diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild
index 0633dc6d254..f313f9cbcf4 100644
--- a/arch/s390/include/asm/Kbuild
+++ b/arch/s390/include/asm/Kbuild
@@ -1,3 +1,4 @@
generic-y += clkdev.h
+generic-y += trace_clock.h
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index a34a9d612fc..18cd6b59265 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -20,7 +20,7 @@
#define PSW32_MASK_CC 0x00003000UL
#define PSW32_MASK_PM 0x00000f00UL
-#define PSW32_MASK_USER 0x00003F00UL
+#define PSW32_MASK_USER 0x0000FF00UL
#define PSW32_ADDR_AMODE 0x80000000UL
#define PSW32_ADDR_INSN 0x7FFFFFFFUL
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h
index 023d5ae2448..d2ff41370c0 100644
--- a/arch/s390/include/asm/cputime.h
+++ b/arch/s390/include/asm/cputime.h
@@ -14,6 +14,7 @@
#define __ARCH_HAS_VTIME_ACCOUNT
+#define __ARCH_HAS_VTIME_TASK_SWITCH
/* We want to use full resolution of the CPU timer: 2**-12 micro-seconds. */
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h
index 6d5367060a5..39faa4ac966 100644
--- a/arch/s390/include/asm/page.h
+++ b/arch/s390/include/asm/page.h
@@ -158,6 +158,9 @@ static inline int page_reset_referenced(unsigned long addr)
* race against modification of the referenced bit. This function
* should therefore only be called if it is not mapped in any
* address space.
+ *
+ * Note that the bit gets set whenever page content is changed. That means
+ * also when the page is modified by DMA or from inside the kernel.
*/
#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY
static inline int page_test_and_clear_dirty(unsigned long pfn, int mapped)
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h
index 9ca30538376..9935cbd6a46 100644
--- a/arch/s390/include/asm/topology.h
+++ b/arch/s390/include/asm/topology.h
@@ -8,6 +8,9 @@ struct cpu;
#ifdef CONFIG_SCHED_BOOK
+extern unsigned char cpu_socket_id[NR_CPUS];
+#define topology_physical_package_id(cpu) (cpu_socket_id[cpu])
+
extern unsigned char cpu_core_id[NR_CPUS];
extern cpumask_t cpu_core_map[NR_CPUS];
diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h
index 705588a16d7..a5ca214b34f 100644
--- a/arch/s390/include/uapi/asm/ptrace.h
+++ b/arch/s390/include/uapi/asm/ptrace.h
@@ -239,7 +239,7 @@ typedef struct
#define PSW_MASK_EA 0x00000000UL
#define PSW_MASK_BA 0x00000000UL
-#define PSW_MASK_USER 0x00003F00UL
+#define PSW_MASK_USER 0x0000FF00UL
#define PSW_ADDR_AMODE 0x80000000UL
#define PSW_ADDR_INSN 0x7FFFFFFFUL
@@ -269,7 +269,7 @@ typedef struct
#define PSW_MASK_EA 0x0000000100000000UL
#define PSW_MASK_BA 0x0000000080000000UL
-#define PSW_MASK_USER 0x00003F8180000000UL
+#define PSW_MASK_USER 0x0000FF8180000000UL
#define PSW_ADDR_AMODE 0x0000000000000000UL
#define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index a1e8a8694bb..593fcc9253f 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -309,6 +309,10 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
(__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 |
(__u64)(regs32.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) |
+ (regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
for (i = 0; i < NUM_GPRS; i++)
regs->gprs[i] = (__u64) regs32.gprs[i];
@@ -481,7 +485,10 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
/* Set up registers for signal handler */
regs->gprs[15] = (__force __u64) frame;
- regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */
+ /* Force 31 bit amode and default user address space control. */
+ regs->psw.mask = PSW_MASK_BA |
+ (psw_user_bits & PSW_MASK_ASC) |
+ (regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (__force __u64) ka->sa.sa_handler;
regs->gprs[2] = map_signal(sig);
@@ -549,7 +556,10 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up registers for signal handler */
regs->gprs[15] = (__force __u64) frame;
- regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */
+ /* Force 31 bit amode and default user address space control. */
+ regs->psw.mask = PSW_MASK_BA |
+ (psw_user_bits & PSW_MASK_ASC) |
+ (regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (__u64) ka->sa.sa_handler;
regs->gprs[2] = map_signal(sig);
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index ad79b846535..827e094a2f4 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -28,7 +28,7 @@ ENTRY(sys32_open_wrapper)
llgtr %r2,%r2 # const char *
lgfr %r3,%r3 # int
lgfr %r4,%r4 # int
- jg sys_open # branch to system call
+ jg compat_sys_open # branch to system call
ENTRY(sys32_close_wrapper)
llgfr %r2,%r2 # unsigned int
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index c13a2a37ef0..d1259d87507 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -136,6 +136,10 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
/* 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);
+ /* 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) |
+ (regs->psw.mask & ~PSW_MASK_ASC);
/* Check for invalid amode */
if (regs->psw.mask & PSW_MASK_EA)
regs->psw.mask |= PSW_MASK_BA;
@@ -273,7 +277,10 @@ static int setup_frame(int sig, struct k_sigaction *ka,
/* Set up registers for signal handler */
regs->gprs[15] = (unsigned long) frame;
- regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */
+ /* Force default amode and default user address space control. */
+ regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
+ (psw_user_bits & PSW_MASK_ASC) |
+ (regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
regs->gprs[2] = map_signal(sig);
@@ -346,7 +353,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up registers for signal handler */
regs->gprs[15] = (unsigned long) frame;
- regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */
+ /* Force default amode and default user address space control. */
+ regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
+ (psw_user_bits & PSW_MASK_ASC) |
+ (regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
regs->gprs[2] = map_signal(sig);
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 54d93f4b681..dd55f7c2010 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -40,6 +40,7 @@ static DEFINE_SPINLOCK(topology_lock);
static struct mask_info core_info;
cpumask_t cpu_core_map[NR_CPUS];
unsigned char cpu_core_id[NR_CPUS];
+unsigned char cpu_socket_id[NR_CPUS];
static struct mask_info book_info;
cpumask_t cpu_book_map[NR_CPUS];
@@ -83,11 +84,12 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
cpumask_set_cpu(lcpu, &book->mask);
cpu_book_id[lcpu] = book->id;
cpumask_set_cpu(lcpu, &core->mask);
+ cpu_core_id[lcpu] = rcpu;
if (one_core_per_cpu) {
- cpu_core_id[lcpu] = rcpu;
+ cpu_socket_id[lcpu] = rcpu;
core = core->next;
} else {
- cpu_core_id[lcpu] = core->id;
+ cpu_socket_id[lcpu] = core->id;
}
smp_cpu_set_polarization(lcpu, tl_cpu->pp);
}
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 79033442789..e84b8b68444 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -112,7 +112,12 @@ void vtime_task_switch(struct task_struct *prev)
S390_lowcore.system_timer = ti->system_timer;
}
-void account_process_tick(struct task_struct *tsk, int user_tick)
+/*
+ * In s390, accounting pending user time also implies
+ * accounting system time in order to correctly compute
+ * the stolen time accounting.
+ */
+void vtime_account_user(struct task_struct *tsk)
{
if (do_account_vtime(tsk, HARDIRQ_OFFSET))
virt_timer_expire();
@@ -127,6 +132,8 @@ void vtime_account(struct task_struct *tsk)
struct thread_info *ti = task_thread_info(tsk);
u64 timer, system;
+ WARN_ON_ONCE(!irqs_disabled());
+
timer = S390_lowcore.last_update_timer;
S390_lowcore.last_update_timer = get_vtimer();
S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
@@ -140,6 +147,10 @@ void vtime_account(struct task_struct *tsk)
}
EXPORT_SYMBOL_GPL(vtime_account);
+void vtime_account_system(struct task_struct *tsk)
+__attribute__((alias("vtime_account")));
+EXPORT_SYMBOL_GPL(vtime_account_system);
+
void __kprobes vtime_stop_cpu(void)
{
struct s390_idle_data *idle = &__get_cpu_var(s390_idle);
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index ecced9d1898..d91a9556800 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -608,9 +608,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
kvm_s390_deliver_pending_interrupts(vcpu);
vcpu->arch.sie_block->icptcode = 0;
- local_irq_disable();
kvm_guest_enter();
- local_irq_enable();
VCPU_EVENT(vcpu, 6, "entering sie flags %x",
atomic_read(&vcpu->arch.sie_block->cpuflags));
trace_kvm_s390_sie_enter(vcpu,
@@ -629,9 +627,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
vcpu->arch.sie_block->icptcode);
trace_kvm_s390_sie_exit(vcpu, vcpu->arch.sie_block->icptcode);
- local_irq_disable();
kvm_guest_exit();
- local_irq_enable();
memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
return rc;
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c
index 8b8285310b5..1f5315d1215 100644
--- a/arch/s390/mm/gup.c
+++ b/arch/s390/mm/gup.c
@@ -180,8 +180,7 @@ 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 (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
- (void __user *)start, len)))
+ if ((end < start) || (end > TASK_SIZE))
return 0;
local_irq_save(flags);
@@ -229,7 +228,7 @@ 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)
+ if ((end < start) || (end > TASK_SIZE))
goto slow_irqon;
/*
diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild
index ec697aeefd0..16e41fe1a41 100644
--- a/arch/score/include/asm/Kbuild
+++ b/arch/score/include/asm/Kbuild
@@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm
header-y +=
generic-y += clkdev.h
+generic-y += trace_clock.h
diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c
index c268bbf8b41..02353bde92d 100644
--- a/arch/score/kernel/signal.c
+++ b/arch/score/kernel/signal.c
@@ -148,7 +148,6 @@ score_rt_sigreturn(struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
sigset_t set;
- stack_t st;
int sig;
/* Always make any pending restarted system calls return -EINTR */
@@ -168,12 +167,10 @@ score_rt_sigreturn(struct pt_regs *regs)
else if (sig)
force_sig(sig, current);
- if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
- goto badframe;
-
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
- do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]);
+ if (do_sigaltstack(&frame->rs_uc.uc_stack, NULL, regs->regs[0]) == -EFAULT)
+ goto badframe;
regs->is_syscall = 0;
__asm__ __volatile__(
diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig
index 911e30c9abf..c6c2becdc8a 100644
--- a/arch/sh/configs/ecovec24_defconfig
+++ b/arch/sh/configs/ecovec24_defconfig
@@ -112,7 +112,7 @@ CONFIG_USB_MON=y
CONFIG_USB_R8A66597_HCD=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_MMC=y
CONFIG_MMC_SPI=y
CONFIG_MMC_SDHI=y
diff --git a/arch/sh/configs/se7724_defconfig b/arch/sh/configs/se7724_defconfig
index ed35093e375..1faa788aeca 100644
--- a/arch/sh/configs/se7724_defconfig
+++ b/arch/sh/configs/se7724_defconfig
@@ -109,7 +109,7 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_SPI=y
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index a7e078f2e2e..81e5dafed3e 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -319,7 +319,5 @@ EXPORT_SYMBOL(pci_iounmap);
#endif /* CONFIG_GENERIC_IOMAP */
-#ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL(PCIBIOS_MIN_IO);
EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
-#endif
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index 29f83beeef7..280bea9e5e2 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -31,5 +31,6 @@ generic-y += socket.h
generic-y += statfs.h
generic-y += termbits.h
generic-y += termios.h
+generic-y += trace_clock.h
generic-y += ucontext.h
generic-y += xor.h
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 73a23f4617a..629db2ad791 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -382,7 +382,7 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
#define xlate_dev_kmem_ptr(p) p
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
-int valid_phys_addr_range(unsigned long addr, size_t size);
+int valid_phys_addr_range(phys_addr_t addr, size_t size);
int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
#endif /* __KERNEL__ */
diff --git a/arch/sh/include/uapi/asm/ioctls.h b/arch/sh/include/uapi/asm/ioctls.h
index a6769f352bf..34224107976 100644
--- a/arch/sh/include/uapi/asm/ioctls.h
+++ b/arch/sh/include/uapi/asm/ioctls.h
@@ -88,6 +88,9 @@
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
#define TIOCVHANGUP _IO('T', 0x37)
+#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
+#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
+#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
#define TIOCSERCONFIG _IO('T', 83) /* 0x5453 */
#define TIOCSERGWILD _IOR('T', 84, int) /* 0x5454 */
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index 0c2f1b2c2e1..42d991f632b 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -20,6 +20,7 @@
#include <linux/serial_sci.h>
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
+#include <linux/usb/ohci_pdriver.h>
#include <asm/rtc.h>
#include <cpu/serial.h>
@@ -103,12 +104,15 @@ static struct resource usb_ohci_resources[] = {
static u64 usb_ohci_dma_mask = 0xffffffffUL;
+static struct usb_ohci_pdata usb_ohci_pdata;
+
static struct platform_device usb_ohci_device = {
- .name = "sh_ohci",
+ .name = "ohci-platform",
.id = -1,
.dev = {
.dma_mask = &usb_ohci_dma_mask,
.coherent_dma_mask = 0xffffffff,
+ .platform_data = &usb_ohci_pdata,
},
.num_resources = ARRAY_SIZE(usb_ohci_resources),
.resource = usb_ohci_resources,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
index 4a2f357f4df..9079a0f9ea9 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
@@ -19,6 +19,7 @@
#include <linux/sh_timer.h>
#include <linux/sh_dma.h>
#include <linux/sh_intc.h>
+#include <linux/usb/ohci_pdriver.h>
#include <cpu/dma-register.h>
#include <cpu/sh7757.h>
@@ -750,12 +751,15 @@ static struct resource usb_ohci_resources[] = {
},
};
+static struct usb_ohci_pdata usb_ohci_pdata;
+
static struct platform_device usb_ohci_device = {
- .name = "sh_ohci",
+ .name = "ohci-platform",
.id = -1,
.dev = {
.dma_mask = &usb_ohci_device.dev.coherent_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &usb_ohci_pdata,
},
.num_resources = ARRAY_SIZE(usb_ohci_resources),
.resource = usb_ohci_resources,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
index bd0a8fbe610..1686acaaf45 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
@@ -16,6 +16,7 @@
#include <linux/sh_intc.h>
#include <linux/io.h>
#include <linux/serial_sci.h>
+#include <linux/usb/ohci_pdriver.h>
static struct plat_sci_port scif0_platform_data = {
.mapbase = 0xffe00000,
@@ -106,12 +107,15 @@ static struct resource usb_ohci_resources[] = {
static u64 usb_ohci_dma_mask = 0xffffffffUL;
+static struct usb_ohci_pdata usb_ohci_pdata;
+
static struct platform_device usb_ohci_device = {
- .name = "sh_ohci",
+ .name = "ohci-platform",
.id = -1,
.dev = {
.dma_mask = &usb_ohci_dma_mask,
.coherent_dma_mask = 0xffffffff,
+ .platform_data = &usb_ohci_pdata,
},
.num_resources = ARRAY_SIZE(usb_ohci_resources),
.resource = usb_ohci_resources,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
index 2e6952f8784..ab52d4d4484 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
@@ -23,6 +23,7 @@
#include <linux/sh_timer.h>
#include <linux/sh_dma.h>
#include <linux/sh_intc.h>
+#include <linux/usb/ohci_pdriver.h>
#include <cpu/dma-register.h>
#include <asm/mmzone.h>
@@ -583,12 +584,15 @@ static struct resource usb_ohci_resources[] = {
},
};
+static struct usb_ohci_pdata usb_ohci_pdata;
+
static struct platform_device usb_ohci_device = {
- .name = "sh_ohci",
+ .name = "ohci-platform",
.id = -1,
.dev = {
.dma_mask = &usb_ohci_device.dev.coherent_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &usb_ohci_pdata,
},
.num_resources = ARRAY_SIZE(usb_ohci_resources),
.resource = usb_ohci_resources,
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 23853814bd1..d867cd95a62 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -347,7 +347,6 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
{
struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP;
sigset_t set;
- stack_t __user st;
long long ret;
/* Always make any pending restarted system calls return -EINTR */
@@ -365,11 +364,10 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
goto badframe;
regs->pc -= 4;
- if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
- goto badframe;
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
- do_sigaltstack(&st, NULL, REF_REG_SP);
+ if (do_sigaltstack(&frame->uc.uc_stack, NULL, REF_REG_SP) == -EFAULT)
+ goto badframe;
return (int) ret;
diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
index afeb710ec5c..6777177807c 100644
--- a/arch/sh/mm/mmap.c
+++ b/arch/sh/mm/mmap.c
@@ -30,25 +30,13 @@ static inline unsigned long COLOUR_ALIGN(unsigned long addr,
return base + off;
}
-static inline unsigned long COLOUR_ALIGN_DOWN(unsigned long addr,
- unsigned long pgoff)
-{
- unsigned long base = addr & ~shm_align_mask;
- unsigned long off = (pgoff << PAGE_SHIFT) & shm_align_mask;
-
- if (base + off <= addr)
- return base + off;
-
- return base - off;
-}
-
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff, unsigned long flags)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
- unsigned long start_addr;
int do_colour_align;
+ struct vm_unmapped_area_info info;
if (flags & MAP_FIXED) {
/* We do not accept a shared mapping if it would violate
@@ -79,47 +67,13 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
return addr;
}
- if (len > mm->cached_hole_size) {
- start_addr = addr = mm->free_area_cache;
- } else {
- mm->cached_hole_size = 0;
- start_addr = addr = TASK_UNMAPPED_BASE;
- }
-
-full_search:
- if (do_colour_align)
- addr = COLOUR_ALIGN(addr, pgoff);
- else
- addr = PAGE_ALIGN(mm->free_area_cache);
-
- for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
- /* At this point: (!vma || addr < vma->vm_end). */
- if (unlikely(TASK_SIZE - len < addr)) {
- /*
- * Start a new search - just in case we missed
- * some holes.
- */
- if (start_addr != TASK_UNMAPPED_BASE) {
- start_addr = addr = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = 0;
- goto full_search;
- }
- return -ENOMEM;
- }
- if (likely(!vma || addr + len <= vma->vm_start)) {
- /*
- * Remember the place where we stopped the search:
- */
- mm->free_area_cache = addr + len;
- return addr;
- }
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
-
- addr = vma->vm_end;
- if (do_colour_align)
- addr = COLOUR_ALIGN(addr, pgoff);
- }
+ info.flags = 0;
+ info.length = len;
+ info.low_limit = TASK_UNMAPPED_BASE;
+ info.high_limit = TASK_SIZE;
+ info.align_mask = do_colour_align ? (PAGE_MASK & shm_align_mask) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+ return vm_unmapped_area(&info);
}
unsigned long
@@ -131,6 +85,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
struct mm_struct *mm = current->mm;
unsigned long addr = addr0;
int do_colour_align;
+ struct vm_unmapped_area_info info;
if (flags & MAP_FIXED) {
/* We do not accept a shared mapping if it would violate
@@ -162,73 +117,27 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
return addr;
}
- /* check if free_area_cache is useful for us */
- if (len <= mm->cached_hole_size) {
- mm->cached_hole_size = 0;
- mm->free_area_cache = mm->mmap_base;
- }
-
- /* either no address requested or can't fit in requested address hole */
- addr = mm->free_area_cache;
- if (do_colour_align) {
- unsigned long base = COLOUR_ALIGN_DOWN(addr-len, pgoff);
+ info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+ info.length = len;
+ info.low_limit = PAGE_SIZE;
+ info.high_limit = mm->mmap_base;
+ info.align_mask = do_colour_align ? (PAGE_MASK & shm_align_mask) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+ addr = vm_unmapped_area(&info);
- addr = base + len;
- }
-
- /* make sure it can fit in the remaining address space */
- if (likely(addr > len)) {
- vma = find_vma(mm, addr-len);
- if (!vma || addr <= vma->vm_start) {
- /* remember the address as a hint for next time */
- return (mm->free_area_cache = addr-len);
- }
- }
-
- if (unlikely(mm->mmap_base < len))
- goto bottomup;
-
- addr = mm->mmap_base-len;
- if (do_colour_align)
- addr = COLOUR_ALIGN_DOWN(addr, pgoff);
-
- do {
- /*
- * Lookup failure means no vma is above this address,
- * else if new region fits below vma->vm_start,
- * return with success:
- */
- vma = find_vma(mm, addr);
- if (likely(!vma || addr+len <= vma->vm_start)) {
- /* remember the address as a hint for next time */
- return (mm->free_area_cache = addr);
- }
-
- /* remember the largest hole we saw so far */
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
-
- /* try just below the current vma->vm_start */
- addr = vma->vm_start-len;
- if (do_colour_align)
- addr = COLOUR_ALIGN_DOWN(addr, pgoff);
- } while (likely(len < vma->vm_start));
-
-bottomup:
/*
* A failed mmap() very likely causes application failure,
* so fall back to the bottom-up function here. This scenario
* can happen with large stack limits and large mmap()
* allocations.
*/
- mm->cached_hole_size = ~0UL;
- mm->free_area_cache = TASK_UNMAPPED_BASE;
- addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
- /*
- * Restore the topdown base:
- */
- mm->free_area_cache = mm->mmap_base;
- mm->cached_hole_size = ~0UL;
+ if (addr & ~PAGE_MASK) {
+ VM_BUG_ON(addr != -ENOMEM);
+ info.flags = 0;
+ info.low_limit = TASK_UNMAPPED_BASE;
+ info.high_limit = TASK_SIZE;
+ addr = vm_unmapped_area(&info);
+ }
return addr;
}
@@ -238,7 +147,7 @@ bottomup:
* You really shouldn't be using read() or write() on /dev/mem. This
* might go away in the future.
*/
-int valid_phys_addr_range(unsigned long addr, size_t count)
+int valid_phys_addr_range(phys_addr_t addr, size_t count)
{
if (addr < __MEMORY_START)
return 0;
diff --git a/arch/sparc/boot/piggyback.c b/arch/sparc/boot/piggyback.c
index c0a798fcf03..bb7c95161d7 100644
--- a/arch/sparc/boot/piggyback.c
+++ b/arch/sparc/boot/piggyback.c
@@ -81,18 +81,18 @@ static void usage(void)
static int start_line(const char *line)
{
- if (strcmp(line + 8, " T _start\n") == 0)
+ if (strcmp(line + 10, " _start\n") == 0)
return 1;
- else if (strcmp(line + 16, " T _start\n") == 0)
+ else if (strcmp(line + 18, " _start\n") == 0)
return 1;
return 0;
}
static int end_line(const char *line)
{
- if (strcmp(line + 8, " A _end\n") == 0)
+ if (strcmp(line + 10, " _end\n") == 0)
return 1;
- else if (strcmp (line + 16, " A _end\n") == 0)
+ else if (strcmp (line + 18, " _end\n") == 0)
return 1;
return 0;
}
@@ -100,8 +100,8 @@ static int end_line(const char *line)
/*
* Find address for start and end in System.map.
* The file looks like this:
- * f0004000 T _start
- * f0379f79 A _end
+ * f0004000 ... _start
+ * f0379f79 ... _end
* 1234567890123456
* ^coloumn 1
* There is support for 64 bit addresses too.
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index 645a58da0e8..e26d430ce2f 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -8,4 +8,5 @@ generic-y += local64.h
generic-y += irq_regs.h
generic-y += local.h
generic-y += module.h
+generic-y += trace_clock.h
generic-y += word-at-a-time.h
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h
index f93003123bc..67c62578d17 100644
--- a/arch/sparc/include/asm/prom.h
+++ b/arch/sparc/include/asm/prom.h
@@ -63,10 +63,13 @@ extern char *of_console_options;
extern void irq_trans_init(struct device_node *dp);
extern char *build_path_component(struct device_node *dp);
-/* SPARC has a local implementation */
+/* SPARC has local implementations */
extern int of_address_to_resource(struct device_node *dev, int index,
struct resource *r);
#define of_address_to_resource of_address_to_resource
+void __iomem *of_iomap(struct device_node *node, int index);
+#define of_iomap of_iomap
+
#endif /* __KERNEL__ */
#endif /* _SPARC_PROM_H */
diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h
index 9155f7041d4..897d1723fa1 100644
--- a/arch/sparc/include/uapi/asm/ioctls.h
+++ b/arch/sparc/include/uapi/asm/ioctls.h
@@ -21,6 +21,9 @@
#define TCSETSF2 _IOW('T', 15, struct termios2)
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
#define TIOCVHANGUP _IO('T', 0x37)
+#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
+#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
+#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
/* Note that all the ioctls that are not available in Linux have a
* double underscore on the front to: a) avoid some programs to
diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h
index 918a2031c8b..5f688531f48 100644
--- a/arch/sparc/kernel/pci_impl.h
+++ b/arch/sparc/kernel/pci_impl.h
@@ -88,7 +88,7 @@ struct pci_pbm_info {
int chip_revision;
/* Name used for top-level resources. */
- char *name;
+ const char *name;
/* OBP specific information. */
struct platform_device *op;
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index 867de2f8189..689e1ba6280 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -295,9 +295,7 @@ void do_rt_sigreturn(struct pt_regs *regs)
err |= restore_fpu_state(regs, fpu_save);
err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
- err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf);
-
- if (err)
+ if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT)
goto segv;
err |= __get_user(rwin_save, &sf->rwin_save);
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S
index 44025f4ba41..8475a474273 100644
--- a/arch/sparc/kernel/sys32.S
+++ b/arch/sparc/kernel/sys32.S
@@ -47,7 +47,7 @@ STUB: sra REG1, 0, REG1; \
sra REG4, 0, REG4
SIGN1(sys32_exit, sparc_exit, %o0)
-SIGN1(sys32_exit_group, sys_exit_group, %o0)
+SIGN1(sys32_exit_group, sparc_exit_group, %o0)
SIGN1(sys32_wait4, compat_sys_wait4, %o2)
SIGN1(sys32_creat, sys_creat, %o1)
SIGN1(sys32_mknod, sys_mknod, %o1)
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index 0c9b31b22e0..57277c83015 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -34,11 +34,9 @@ asmlinkage unsigned long sys_getpagesize(void)
return PAGE_SIZE; /* Possibly older binaries want 8192 on sun4's? */
}
-#define COLOUR_ALIGN(addr) (((addr)+SHMLBA-1)&~(SHMLBA-1))
-
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
{
- struct vm_area_struct * vmm;
+ struct vm_unmapped_area_info info;
if (flags & MAP_FIXED) {
/* We do not accept a shared mapping if it would violate
@@ -56,21 +54,14 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
if (!addr)
addr = TASK_UNMAPPED_BASE;
- if (flags & MAP_SHARED)
- addr = COLOUR_ALIGN(addr);
- else
- addr = PAGE_ALIGN(addr);
-
- for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
- /* At this point: (!vmm || addr < vmm->vm_end). */
- if (TASK_SIZE - PAGE_SIZE - len < addr)
- return -ENOMEM;
- if (!vmm || addr + len <= vmm->vm_start)
- return addr;
- addr = vmm->vm_end;
- if (flags & MAP_SHARED)
- addr = COLOUR_ALIGN(addr);
- }
+ info.flags = 0;
+ info.length = len;
+ info.low_limit = addr;
+ info.high_limit = TASK_SIZE;
+ info.align_mask = (flags & MAP_SHARED) ?
+ (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+ return vm_unmapped_area(&info);
}
/*
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 878ef3d5fec..97309c0ec53 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -75,7 +75,7 @@ static inline int invalid_64bit_range(unsigned long addr, unsigned long len)
* the spitfire/niagara VA-hole.
*/
-static inline unsigned long COLOUR_ALIGN(unsigned long addr,
+static inline unsigned long COLOR_ALIGN(unsigned long addr,
unsigned long pgoff)
{
unsigned long base = (addr+SHMLBA-1)&~(SHMLBA-1);
@@ -84,24 +84,13 @@ static inline unsigned long COLOUR_ALIGN(unsigned long addr,
return base + off;
}
-static inline unsigned long COLOUR_ALIGN_DOWN(unsigned long addr,
- unsigned long pgoff)
-{
- unsigned long base = addr & ~(SHMLBA-1);
- unsigned long off = (pgoff<<PAGE_SHIFT) & (SHMLBA-1);
-
- if (base + off <= addr)
- return base + off;
- return base - off;
-}
-
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct * vma;
unsigned long task_size = TASK_SIZE;
- unsigned long start_addr;
int do_color_align;
+ struct vm_unmapped_area_info info;
if (flags & MAP_FIXED) {
/* We do not accept a shared mapping if it would violate
@@ -124,7 +113,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
if (addr) {
if (do_color_align)
- addr = COLOUR_ALIGN(addr, pgoff);
+ addr = COLOR_ALIGN(addr, pgoff);
else
addr = PAGE_ALIGN(addr);
@@ -134,50 +123,22 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
return addr;
}
- if (len > mm->cached_hole_size) {
- start_addr = addr = mm->free_area_cache;
- } else {
- start_addr = addr = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = 0;
+ info.flags = 0;
+ info.length = len;
+ info.low_limit = TASK_UNMAPPED_BASE;
+ info.high_limit = min(task_size, VA_EXCLUDE_START);
+ info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+ addr = vm_unmapped_area(&info);
+
+ if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) {
+ VM_BUG_ON(addr != -ENOMEM);
+ info.low_limit = VA_EXCLUDE_END;
+ info.high_limit = task_size;
+ addr = vm_unmapped_area(&info);
}
- task_size -= len;
-
-full_search:
- if (do_color_align)
- addr = COLOUR_ALIGN(addr, pgoff);
- else
- addr = PAGE_ALIGN(addr);
-
- for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
- /* At this point: (!vma || addr < vma->vm_end). */
- if (addr < VA_EXCLUDE_START &&
- (addr + len) >= VA_EXCLUDE_START) {
- addr = VA_EXCLUDE_END;
- vma = find_vma(mm, VA_EXCLUDE_END);
- }
- if (unlikely(task_size < addr)) {
- if (start_addr != TASK_UNMAPPED_BASE) {
- start_addr = addr = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = 0;
- goto full_search;
- }
- return -ENOMEM;
- }
- if (likely(!vma || addr + len <= vma->vm_start)) {
- /*
- * Remember the place where we stopped the search:
- */
- mm->free_area_cache = addr + len;
- return addr;
- }
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
-
- addr = vma->vm_end;
- if (do_color_align)
- addr = COLOUR_ALIGN(addr, pgoff);
- }
+ return addr;
}
unsigned long
@@ -190,6 +151,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
unsigned long task_size = STACK_TOP32;
unsigned long addr = addr0;
int do_color_align;
+ struct vm_unmapped_area_info info;
/* This should only ever run for 32-bit processes. */
BUG_ON(!test_thread_flag(TIF_32BIT));
@@ -214,7 +176,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
/* requesting a specific address */
if (addr) {
if (do_color_align)
- addr = COLOUR_ALIGN(addr, pgoff);
+ addr = COLOR_ALIGN(addr, pgoff);
else
addr = PAGE_ALIGN(addr);
@@ -224,73 +186,27 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
return addr;
}
- /* check if free_area_cache is useful for us */
- if (len <= mm->cached_hole_size) {
- mm->cached_hole_size = 0;
- mm->free_area_cache = mm->mmap_base;
- }
-
- /* either no address requested or can't fit in requested address hole */
- addr = mm->free_area_cache;
- if (do_color_align) {
- unsigned long base = COLOUR_ALIGN_DOWN(addr-len, pgoff);
+ info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+ info.length = len;
+ info.low_limit = PAGE_SIZE;
+ info.high_limit = mm->mmap_base;
+ info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+ addr = vm_unmapped_area(&info);
- addr = base + len;
- }
-
- /* make sure it can fit in the remaining address space */
- if (likely(addr > len)) {
- vma = find_vma(mm, addr-len);
- if (!vma || addr <= vma->vm_start) {
- /* remember the address as a hint for next time */
- return (mm->free_area_cache = addr-len);
- }
- }
-
- if (unlikely(mm->mmap_base < len))
- goto bottomup;
-
- addr = mm->mmap_base-len;
- if (do_color_align)
- addr = COLOUR_ALIGN_DOWN(addr, pgoff);
-
- do {
- /*
- * Lookup failure means no vma is above this address,
- * else if new region fits below vma->vm_start,
- * return with success:
- */
- vma = find_vma(mm, addr);
- if (likely(!vma || addr+len <= vma->vm_start)) {
- /* remember the address as a hint for next time */
- return (mm->free_area_cache = addr);
- }
-
- /* remember the largest hole we saw so far */
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
-
- /* try just below the current vma->vm_start */
- addr = vma->vm_start-len;
- if (do_color_align)
- addr = COLOUR_ALIGN_DOWN(addr, pgoff);
- } while (likely(len < vma->vm_start));
-
-bottomup:
/*
* A failed mmap() very likely causes application failure,
* so fall back to the bottom-up function here. This scenario
* can happen with large stack limits and large mmap()
* allocations.
*/
- mm->cached_hole_size = ~0UL;
- mm->free_area_cache = TASK_UNMAPPED_BASE;
- addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
- /*
- * Restore the topdown base:
- */
- mm->free_area_cache = mm->mmap_base;
- mm->cached_hole_size = ~0UL;
+ if (addr & ~PAGE_MASK) {
+ VM_BUG_ON(addr != -ENOMEM);
+ info.flags = 0;
+ info.low_limit = TASK_UNMAPPED_BASE;
+ info.high_limit = STACK_TOP32;
+ addr = vm_unmapped_area(&info);
+ }
return addr;
}
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
index 7f5f65d0b3f..bf2347794e3 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -118,10 +118,20 @@ ret_from_syscall:
ba,pt %xcc, ret_sys_call
ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0
+ .globl sparc_exit_group
+ .type sparc_exit_group,#function
+sparc_exit_group:
+ sethi %hi(sys_exit_group), %g7
+ ba,pt %xcc, 1f
+ or %g7, %lo(sys_exit_group), %g7
+ .size sparc_exit_group,.-sparc_exit_group
+
.globl sparc_exit
.type sparc_exit,#function
sparc_exit:
- rdpr %pstate, %g2
+ sethi %hi(sys_exit), %g7
+ or %g7, %lo(sys_exit), %g7
+1: rdpr %pstate, %g2
wrpr %g2, PSTATE_IE, %pstate
rdpr %otherwin, %g1
rdpr %cansave, %g3
@@ -129,7 +139,7 @@ sparc_exit:
wrpr %g3, 0x0, %cansave
wrpr %g0, 0x0, %otherwin
wrpr %g2, 0x0, %pstate
- ba,pt %xcc, sys_exit
+ jmpl %g7, %g0
stb %g0, [%g6 + TI_WSAVED]
.size sparc_exit,.-sparc_exit
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index 1c9af9fa38e..017b74a63dc 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -133,7 +133,7 @@ sys_call_table:
/*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall
- .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname
+ .word sys_setpgid, sys_fremovexattr, sys_tkill, sparc_exit_group, sys_newuname
/*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl
.word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask
/*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index f76f83d5ac6..d2b59441ebd 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -30,55 +30,28 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
unsigned long pgoff,
unsigned long flags)
{
- struct mm_struct *mm = current->mm;
- struct vm_area_struct * vma;
unsigned long task_size = TASK_SIZE;
- unsigned long start_addr;
+ struct vm_unmapped_area_info info;
if (test_thread_flag(TIF_32BIT))
task_size = STACK_TOP32;
- if (unlikely(len >= VA_EXCLUDE_START))
- return -ENOMEM;
- if (len > mm->cached_hole_size) {
- start_addr = addr = mm->free_area_cache;
- } else {
- start_addr = addr = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = 0;
+ info.flags = 0;
+ info.length = len;
+ info.low_limit = TASK_UNMAPPED_BASE;
+ info.high_limit = min(task_size, VA_EXCLUDE_START);
+ info.align_mask = PAGE_MASK & ~HPAGE_MASK;
+ info.align_offset = 0;
+ addr = vm_unmapped_area(&info);
+
+ if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) {
+ VM_BUG_ON(addr != -ENOMEM);
+ info.low_limit = VA_EXCLUDE_END;
+ info.high_limit = task_size;
+ addr = vm_unmapped_area(&info);
}
- task_size -= len;
-
-full_search:
- addr = ALIGN(addr, HPAGE_SIZE);
-
- for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
- /* At this point: (!vma || addr < vma->vm_end). */
- if (addr < VA_EXCLUDE_START &&
- (addr + len) >= VA_EXCLUDE_START) {
- addr = VA_EXCLUDE_END;
- vma = find_vma(mm, VA_EXCLUDE_END);
- }
- if (unlikely(task_size < addr)) {
- if (start_addr != TASK_UNMAPPED_BASE) {
- start_addr = addr = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = 0;
- goto full_search;
- }
- return -ENOMEM;
- }
- if (likely(!vma || addr + len <= vma->vm_start)) {
- /*
- * Remember the place where we stopped the search:
- */
- mm->free_area_cache = addr + len;
- return addr;
- }
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
-
- addr = ALIGN(vma->vm_end, HPAGE_SIZE);
- }
+ return addr;
}
static unsigned long
@@ -87,71 +60,34 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
const unsigned long pgoff,
const unsigned long flags)
{
- struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
unsigned long addr = addr0;
+ struct vm_unmapped_area_info info;
/* This should only ever run for 32-bit processes. */
BUG_ON(!test_thread_flag(TIF_32BIT));
- /* check if free_area_cache is useful for us */
- if (len <= mm->cached_hole_size) {
- mm->cached_hole_size = 0;
- mm->free_area_cache = mm->mmap_base;
- }
-
- /* either no address requested or can't fit in requested address hole */
- addr = mm->free_area_cache & HPAGE_MASK;
-
- /* make sure it can fit in the remaining address space */
- if (likely(addr > len)) {
- vma = find_vma(mm, addr-len);
- if (!vma || addr <= vma->vm_start) {
- /* remember the address as a hint for next time */
- return (mm->free_area_cache = addr-len);
- }
- }
-
- if (unlikely(mm->mmap_base < len))
- goto bottomup;
-
- addr = (mm->mmap_base-len) & HPAGE_MASK;
-
- do {
- /*
- * Lookup failure means no vma is above this address,
- * else if new region fits below vma->vm_start,
- * return with success:
- */
- vma = find_vma(mm, addr);
- if (likely(!vma || addr+len <= vma->vm_start)) {
- /* remember the address as a hint for next time */
- return (mm->free_area_cache = addr);
- }
-
- /* remember the largest hole we saw so far */
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
-
- /* try just below the current vma->vm_start */
- addr = (vma->vm_start-len) & HPAGE_MASK;
- } while (likely(len < vma->vm_start));
+ info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+ info.length = len;
+ info.low_limit = PAGE_SIZE;
+ info.high_limit = mm->mmap_base;
+ info.align_mask = PAGE_MASK & ~HPAGE_MASK;
+ info.align_offset = 0;
+ addr = vm_unmapped_area(&info);
-bottomup:
/*
* A failed mmap() very likely causes application failure,
* so fall back to the bottom-up function here. This scenario
* can happen with large stack limits and large mmap()
* allocations.
*/
- mm->cached_hole_size = ~0UL;
- mm->free_area_cache = TASK_UNMAPPED_BASE;
- addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
- /*
- * Restore the topdown base:
- */
- mm->free_area_cache = mm->mmap_base;
- mm->cached_hole_size = ~0UL;
+ if (addr & ~PAGE_MASK) {
+ VM_BUG_ON(addr != -ENOMEM);
+ info.flags = 0;
+ info.low_limit = TASK_UNMAPPED_BASE;
+ info.high_limit = STACK_TOP32;
+ addr = vm_unmapped_area(&info);
+ }
return addr;
}
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index 6948015e08a..b17b9b8e53c 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -34,5 +34,6 @@ generic-y += sockios.h
generic-y += statfs.h
generic-y += termbits.h
generic-y += termios.h
+generic-y += trace_clock.h
generic-y += types.h
generic-y += xor.h
diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c
index 812e2d03797..650ccff8378 100644
--- a/arch/tile/mm/hugetlbpage.c
+++ b/arch/tile/mm/hugetlbpage.c
@@ -231,42 +231,15 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
unsigned long pgoff, unsigned long flags)
{
struct hstate *h = hstate_file(file);
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
- unsigned long start_addr;
-
- if (len > mm->cached_hole_size) {
- start_addr = mm->free_area_cache;
- } else {
- start_addr = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = 0;
- }
-
-full_search:
- addr = ALIGN(start_addr, huge_page_size(h));
-
- for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
- /* At this point: (!vma || addr < vma->vm_end). */
- if (TASK_SIZE - len < addr) {
- /*
- * Start a new search - just in case we missed
- * some holes.
- */
- if (start_addr != TASK_UNMAPPED_BASE) {
- start_addr = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = 0;
- goto full_search;
- }
- return -ENOMEM;
- }
- if (!vma || addr + len <= vma->vm_start) {
- mm->free_area_cache = addr + len;
- return addr;
- }
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
- addr = ALIGN(vma->vm_end, huge_page_size(h));
- }
+ struct vm_unmapped_area_info info;
+
+ info.flags = 0;
+ info.length = len;
+ info.low_limit = TASK_UNMAPPED_BASE;
+ info.high_limit = TASK_SIZE;
+ info.align_mask = PAGE_MASK & ~huge_page_mask(h);
+ info.align_offset = 0;
+ return vm_unmapped_area(&info);
}
static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
@@ -274,92 +247,30 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
unsigned long pgoff, unsigned long flags)
{
struct hstate *h = hstate_file(file);
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma, *prev_vma;
- unsigned long base = mm->mmap_base, addr = addr0;
- unsigned long largest_hole = mm->cached_hole_size;
- int first_time = 1;
-
- /* don't allow allocations above current base */
- if (mm->free_area_cache > base)
- mm->free_area_cache = base;
-
- if (len <= largest_hole) {
- largest_hole = 0;
- mm->free_area_cache = base;
- }
-try_again:
- /* make sure it can fit in the remaining address space */
- if (mm->free_area_cache < len)
- goto fail;
-
- /* either no address requested or can't fit in requested address hole */
- addr = (mm->free_area_cache - len) & huge_page_mask(h);
- do {
- /*
- * Lookup failure means no vma is above this address,
- * i.e. return with success:
- */
- vma = find_vma_prev(mm, addr, &prev_vma);
- if (!vma) {
- return addr;
- break;
- }
-
- /*
- * new region fits between prev_vma->vm_end and
- * vma->vm_start, use it:
- */
- if (addr + len <= vma->vm_start &&
- (!prev_vma || (addr >= prev_vma->vm_end))) {
- /* remember the address as a hint for next time */
- mm->cached_hole_size = largest_hole;
- mm->free_area_cache = addr;
- return addr;
- } else {
- /* pull free_area_cache down to the first hole */
- if (mm->free_area_cache == vma->vm_end) {
- mm->free_area_cache = vma->vm_start;
- mm->cached_hole_size = largest_hole;
- }
- }
+ struct vm_unmapped_area_info info;
+ unsigned long addr;
- /* remember the largest hole we saw so far */
- if (addr + largest_hole < vma->vm_start)
- largest_hole = vma->vm_start - addr;
+ info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+ info.length = len;
+ info.low_limit = PAGE_SIZE;
+ info.high_limit = current->mm->mmap_base;
+ info.align_mask = PAGE_MASK & ~huge_page_mask(h);
+ info.align_offset = 0;
+ addr = vm_unmapped_area(&info);
- /* try just below the current vma->vm_start */
- addr = (vma->vm_start - len) & huge_page_mask(h);
-
- } while (len <= vma->vm_start);
-
-fail:
- /*
- * if hint left us with no space for the requested
- * mapping then try again:
- */
- if (first_time) {
- mm->free_area_cache = base;
- largest_hole = 0;
- first_time = 0;
- goto try_again;
- }
/*
* A failed mmap() very likely causes application failure,
* so fall back to the bottom-up function here. This scenario
* can happen with large stack limits and large mmap()
* allocations.
*/
- mm->free_area_cache = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = ~0UL;
- addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
- len, pgoff, flags);
-
- /*
- * Restore the topdown base:
- */
- mm->free_area_cache = base;
- mm->cached_hole_size = ~0UL;
+ if (addr & ~PAGE_MASK) {
+ VM_BUG_ON(addr != -ENOMEM);
+ info.flags = 0;
+ info.low_limit = TASK_UNMAPPED_BASE;
+ info.high_limit = TASK_SIZE;
+ addr = vm_unmapped_area(&info);
+ }
return addr;
}
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index c3bba73e4be..e9a0abc6a32 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -83,21 +83,8 @@ static const struct chan_ops not_configged_ops = {
static void tty_receive_char(struct tty_struct *tty, char ch)
{
- if (tty == NULL)
- return;
-
- if (I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
- if (ch == STOP_CHAR(tty)) {
- stop_tty(tty);
- return;
- }
- else if (ch == START_CHAR(tty)) {
- start_tty(tty);
- return;
- }
- }
-
- tty_insert_flip_char(tty, ch, TTY_NORMAL);
+ if (tty)
+ tty_insert_flip_char(tty, ch, TTY_NORMAL);
}
static int open_one_chan(struct chan *chan)
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index fd9a15b318a..9ffc28bd4b7 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -584,6 +584,8 @@ int register_lines(struct line_driver *line_driver,
printk(KERN_ERR "register_lines : can't register %s driver\n",
line_driver->name);
put_tty_driver(driver);
+ for (i = 0; i < nlines; i++)
+ tty_port_destroy(&lines[i].port);
return err;
}
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 79ccfe6c707..49e3b49e552 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -648,7 +648,7 @@ static void stack_proc(void *arg)
struct task_struct *from = current, *to = arg;
to->thread.saved_task = from;
- rcu_switch(from, to);
+ rcu_user_hooks_switch(from, to);
switch_to(from, to, from);
}
diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild
index 0f6e7b32826..b30f34a7988 100644
--- a/arch/um/include/asm/Kbuild
+++ b/arch/um/include/asm/Kbuild
@@ -2,3 +2,4 @@ generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h
generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h
generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h
generic-y += switch_to.h clkdev.h
+generic-y += trace_clock.h
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index 3a8ece7d09c..0d7103c9eff 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -32,13 +32,14 @@ void flush_thread(void)
"err = %d\n", ret);
force_sig(SIGKILL, current);
}
+ get_safe_registers(current_pt_regs()->regs.gp,
+ current_pt_regs()->regs.fp);
__switch_mm(&current->mm->context.id);
}
void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
{
- get_safe_registers(regs->regs.gp, regs->regs.fp);
PT_REGS_IP(regs) = eip;
PT_REGS_SP(regs) = esp;
current->ptrace &= ~PT_DTRACE;
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig
index e5c5473e69c..c4fbb21e802 100644
--- a/arch/unicore32/Kconfig
+++ b/arch/unicore32/Kconfig
@@ -16,6 +16,8 @@ config UNICORE32
select ARCH_WANT_FRAME_POINTERS
select GENERIC_IOMAP
select MODULES_USE_ELF_REL
+ select GENERIC_KERNEL_THREAD
+ select GENERIC_KERNEL_EXECVE
help
UniCore-32 is 32-bit Instruction Set Architecture,
including a series of low-power-consumption RISC chip
@@ -64,6 +66,9 @@ config GENERIC_CALIBRATE_DELAY
config ARCH_MAY_HAVE_PC_FDC
bool
+config ZONE_DMA
+ def_bool y
+
config NEED_DMA_MAP_STATE
def_bool y
@@ -216,7 +221,7 @@ config PUV3_GPIO
bool
depends on !ARCH_FPGA
select GENERIC_GPIO
- select GPIO_SYSFS if EXPERIMENTAL
+ select GPIO_SYSFS
default y
if PUV3_NB0916
diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild
index c910c9857e1..89d8b6c4e39 100644
--- a/arch/unicore32/include/asm/Kbuild
+++ b/arch/unicore32/include/asm/Kbuild
@@ -1,4 +1,3 @@
-include include/asm-generic/Kbuild.asm
generic-y += atomic.h
generic-y += auxvec.h
@@ -54,6 +53,7 @@ generic-y += syscalls.h
generic-y += termbits.h
generic-y += termios.h
generic-y += topology.h
+generic-y += trace_clock.h
generic-y += types.h
generic-y += ucontext.h
generic-y += unaligned.h
diff --git a/arch/unicore32/include/asm/bug.h b/arch/unicore32/include/asm/bug.h
index b1ff8cadb08..93a56f3e234 100644
--- a/arch/unicore32/include/asm/bug.h
+++ b/arch/unicore32/include/asm/bug.h
@@ -19,9 +19,4 @@ extern void die(const char *msg, struct pt_regs *regs, int err);
extern void uc32_notify_die(const char *str, struct pt_regs *regs,
struct siginfo *info, unsigned long err, unsigned long trap);
-extern asmlinkage void __backtrace(void);
-extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
-
-extern void __show_regs(struct pt_regs *);
-
#endif /* __UNICORE_BUG_H__ */
diff --git a/arch/unicore32/include/asm/cmpxchg.h b/arch/unicore32/include/asm/cmpxchg.h
index df4d5acfd19..8e797ad4fa2 100644
--- a/arch/unicore32/include/asm/cmpxchg.h
+++ b/arch/unicore32/include/asm/cmpxchg.h
@@ -35,7 +35,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
: "memory", "cc");
break;
default:
- ret = __xchg_bad_pointer();
+ __xchg_bad_pointer();
}
return ret;
diff --git a/arch/unicore32/include/asm/kvm_para.h b/arch/unicore32/include/asm/kvm_para.h
deleted file mode 100644
index 14fab8f0b95..00000000000
--- a/arch/unicore32/include/asm/kvm_para.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/kvm_para.h>
diff --git a/arch/unicore32/include/asm/processor.h b/arch/unicore32/include/asm/processor.h
index 14382cb0965..4eaa4216766 100644
--- a/arch/unicore32/include/asm/processor.h
+++ b/arch/unicore32/include/asm/processor.h
@@ -72,11 +72,6 @@ unsigned long get_wchan(struct task_struct *p);
#define cpu_relax() barrier()
-/*
- * Create a new kernel thread
- */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
#define task_pt_regs(p) \
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
diff --git a/arch/unicore32/include/asm/ptrace.h b/arch/unicore32/include/asm/ptrace.h
index b9caf9b0997..726749dab52 100644
--- a/arch/unicore32/include/asm/ptrace.h
+++ b/arch/unicore32/include/asm/ptrace.h
@@ -12,80 +12,10 @@
#ifndef __UNICORE_PTRACE_H__
#define __UNICORE_PTRACE_H__
-#define PTRACE_GET_THREAD_AREA 22
-
-/*
- * PSR bits
- */
-#define USER_MODE 0x00000010
-#define REAL_MODE 0x00000011
-#define INTR_MODE 0x00000012
-#define PRIV_MODE 0x00000013
-#define ABRT_MODE 0x00000017
-#define EXTN_MODE 0x0000001b
-#define SUSR_MODE 0x0000001f
-#define MODE_MASK 0x0000001f
-#define PSR_R_BIT 0x00000040
-#define PSR_I_BIT 0x00000080
-#define PSR_V_BIT 0x10000000
-#define PSR_C_BIT 0x20000000
-#define PSR_Z_BIT 0x40000000
-#define PSR_S_BIT 0x80000000
-
-/*
- * Groups of PSR bits
- */
-#define PSR_f 0xff000000 /* Flags */
-#define PSR_c 0x000000ff /* Control */
+#include <uapi/asm/ptrace.h>
#ifndef __ASSEMBLY__
-/*
- * This struct defines the way the registers are stored on the
- * stack during a system call. Note that sizeof(struct pt_regs)
- * has to be a multiple of 8.
- */
-struct pt_regs {
- unsigned long uregs[34];
-};
-
-#define UCreg_asr uregs[32]
-#define UCreg_pc uregs[31]
-#define UCreg_lr uregs[30]
-#define UCreg_sp uregs[29]
-#define UCreg_ip uregs[28]
-#define UCreg_fp uregs[27]
-#define UCreg_26 uregs[26]
-#define UCreg_25 uregs[25]
-#define UCreg_24 uregs[24]
-#define UCreg_23 uregs[23]
-#define UCreg_22 uregs[22]
-#define UCreg_21 uregs[21]
-#define UCreg_20 uregs[20]
-#define UCreg_19 uregs[19]
-#define UCreg_18 uregs[18]
-#define UCreg_17 uregs[17]
-#define UCreg_16 uregs[16]
-#define UCreg_15 uregs[15]
-#define UCreg_14 uregs[14]
-#define UCreg_13 uregs[13]
-#define UCreg_12 uregs[12]
-#define UCreg_11 uregs[11]
-#define UCreg_10 uregs[10]
-#define UCreg_09 uregs[9]
-#define UCreg_08 uregs[8]
-#define UCreg_07 uregs[7]
-#define UCreg_06 uregs[6]
-#define UCreg_05 uregs[5]
-#define UCreg_04 uregs[4]
-#define UCreg_03 uregs[3]
-#define UCreg_02 uregs[2]
-#define UCreg_01 uregs[1]
-#define UCreg_00 uregs[0]
-#define UCreg_ORIG_00 uregs[33]
-
-#ifdef __KERNEL__
-
#define user_mode(regs) \
(processor_mode(regs) == USER_MODE)
@@ -125,9 +55,5 @@ static inline int valid_user_regs(struct pt_regs *regs)
#define instruction_pointer(regs) ((regs)->UCreg_pc)
-#endif /* __KERNEL__ */
-
#endif /* __ASSEMBLY__ */
-
#endif
-
diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild
index baebb3da1d4..0514d7ad685 100644
--- a/arch/unicore32/include/uapi/asm/Kbuild
+++ b/arch/unicore32/include/uapi/asm/Kbuild
@@ -1,3 +1,10 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
+header-y += byteorder.h
+header-y += kvm_para.h
+header-y += ptrace.h
+header-y += sigcontext.h
+header-y += unistd.h
+
+generic-y += kvm_para.h
diff --git a/arch/unicore32/include/asm/byteorder.h b/arch/unicore32/include/uapi/asm/byteorder.h
index ebe1b3fef3e..ebe1b3fef3e 100644
--- a/arch/unicore32/include/asm/byteorder.h
+++ b/arch/unicore32/include/uapi/asm/byteorder.h
diff --git a/arch/unicore32/include/uapi/asm/ptrace.h b/arch/unicore32/include/uapi/asm/ptrace.h
new file mode 100644
index 00000000000..187aa2e98a5
--- /dev/null
+++ b/arch/unicore32/include/uapi/asm/ptrace.h
@@ -0,0 +1,90 @@
+/*
+ * linux/arch/unicore32/include/asm/ptrace.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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 _UAPI__UNICORE_PTRACE_H__
+#define _UAPI__UNICORE_PTRACE_H__
+
+#define PTRACE_GET_THREAD_AREA 22
+
+/*
+ * PSR bits
+ */
+#define USER_MODE 0x00000010
+#define REAL_MODE 0x00000011
+#define INTR_MODE 0x00000012
+#define PRIV_MODE 0x00000013
+#define ABRT_MODE 0x00000017
+#define EXTN_MODE 0x0000001b
+#define SUSR_MODE 0x0000001f
+#define MODE_MASK 0x0000001f
+#define PSR_R_BIT 0x00000040
+#define PSR_I_BIT 0x00000080
+#define PSR_V_BIT 0x10000000
+#define PSR_C_BIT 0x20000000
+#define PSR_Z_BIT 0x40000000
+#define PSR_S_BIT 0x80000000
+
+/*
+ * Groups of PSR bits
+ */
+#define PSR_f 0xff000000 /* Flags */
+#define PSR_c 0x000000ff /* Control */
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This struct defines the way the registers are stored on the
+ * stack during a system call. Note that sizeof(struct pt_regs)
+ * has to be a multiple of 8.
+ */
+struct pt_regs {
+ unsigned long uregs[34];
+};
+
+#define UCreg_asr uregs[32]
+#define UCreg_pc uregs[31]
+#define UCreg_lr uregs[30]
+#define UCreg_sp uregs[29]
+#define UCreg_ip uregs[28]
+#define UCreg_fp uregs[27]
+#define UCreg_26 uregs[26]
+#define UCreg_25 uregs[25]
+#define UCreg_24 uregs[24]
+#define UCreg_23 uregs[23]
+#define UCreg_22 uregs[22]
+#define UCreg_21 uregs[21]
+#define UCreg_20 uregs[20]
+#define UCreg_19 uregs[19]
+#define UCreg_18 uregs[18]
+#define UCreg_17 uregs[17]
+#define UCreg_16 uregs[16]
+#define UCreg_15 uregs[15]
+#define UCreg_14 uregs[14]
+#define UCreg_13 uregs[13]
+#define UCreg_12 uregs[12]
+#define UCreg_11 uregs[11]
+#define UCreg_10 uregs[10]
+#define UCreg_09 uregs[9]
+#define UCreg_08 uregs[8]
+#define UCreg_07 uregs[7]
+#define UCreg_06 uregs[6]
+#define UCreg_05 uregs[5]
+#define UCreg_04 uregs[4]
+#define UCreg_03 uregs[3]
+#define UCreg_02 uregs[2]
+#define UCreg_01 uregs[1]
+#define UCreg_00 uregs[0]
+#define UCreg_ORIG_00 uregs[33]
+
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _UAPI__UNICORE_PTRACE_H__ */
diff --git a/arch/unicore32/include/asm/sigcontext.h b/arch/unicore32/include/uapi/asm/sigcontext.h
index 6a2d7671c05..6a2d7671c05 100644
--- a/arch/unicore32/include/asm/sigcontext.h
+++ b/arch/unicore32/include/uapi/asm/sigcontext.h
diff --git a/arch/unicore32/include/asm/unistd.h b/arch/unicore32/include/uapi/asm/unistd.h
index 2abcf61c615..d18a3be89b3 100644
--- a/arch/unicore32/include/asm/unistd.h
+++ b/arch/unicore32/include/uapi/asm/unistd.h
@@ -12,3 +12,4 @@
/* Use the standard ABI for syscalls. */
#include <asm-generic/unistd.h>
+#define __ARCH_WANT_SYS_EXECVE
diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S
index dcb87ab19dd..7049350c790 100644
--- a/arch/unicore32/kernel/entry.S
+++ b/arch/unicore32/kernel/entry.S
@@ -573,17 +573,16 @@ ENDPROC(ret_to_user)
*/
ENTRY(ret_from_fork)
b.l schedule_tail
- get_thread_info tsk
- ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing
- mov why, #1
- cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
- beq ret_slow_syscall
- mov r1, sp
- mov r0, #1 @ trace exit [IP = 1]
- b.l syscall_trace
b ret_slow_syscall
ENDPROC(ret_from_fork)
+ENTRY(ret_from_kernel_thread)
+ b.l schedule_tail
+ mov r0, r5
+ adr lr, ret_slow_syscall
+ mov pc, r4
+ENDPROC(ret_from_kernel_thread)
+
/*=============================================================================
* SWI handler
*-----------------------------------------------------------------------------
@@ -669,11 +668,6 @@ __cr_alignment:
#endif
.ltorg
-ENTRY(sys_execve)
- add r3, sp, #S_OFF
- b __sys_execve
-ENDPROC(sys_execve)
-
ENTRY(sys_clone)
add ip, sp, #S_OFF
stw ip, [sp+], #4
diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c
index b0056f68d32..7c4359240b8 100644
--- a/arch/unicore32/kernel/pci.c
+++ b/arch/unicore32/kernel/pci.c
@@ -250,9 +250,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n",
bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
}
-#ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL(pcibios_fixup_bus);
-#endif
static int __init pci_common_init(void)
{
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c
index b008586dad7..a8fe265ce2c 100644
--- a/arch/unicore32/kernel/process.c
+++ b/arch/unicore32/kernel/process.c
@@ -258,6 +258,7 @@ void release_thread(struct task_struct *dead_task)
}
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
int
copy_thread(unsigned long clone_flags, unsigned long stack_start,
@@ -266,17 +267,22 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
struct thread_info *thread = task_thread_info(p);
struct pt_regs *childregs = task_pt_regs(p);
- *childregs = *regs;
- childregs->UCreg_00 = 0;
- childregs->UCreg_sp = stack_start;
-
memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
thread->cpu_context.sp = (unsigned long)childregs;
- thread->cpu_context.pc = (unsigned long)ret_from_fork;
-
- if (clone_flags & CLONE_SETTLS)
- childregs->UCreg_16 = regs->UCreg_03;
+ if (unlikely(!regs)) {
+ thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread;
+ thread->cpu_context.r4 = stack_start;
+ thread->cpu_context.r5 = stk_sz;
+ memset(childregs, 0, sizeof(struct pt_regs));
+ } else {
+ thread->cpu_context.pc = (unsigned long)ret_from_fork;
+ *childregs = *regs;
+ childregs->UCreg_00 = 0;
+ childregs->UCreg_sp = stack_start;
+ if (clone_flags & CLONE_SETTLS)
+ childregs->UCreg_16 = regs->UCreg_03;
+ }
return 0;
}
@@ -305,42 +311,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp)
}
EXPORT_SYMBOL(dump_fpu);
-/*
- * Shuffle the argument into the correct register before calling the
- * thread function. r1 is the thread argument, r2 is the pointer to
- * the thread function, and r3 points to the exit function.
- */
-asm(".pushsection .text\n"
-" .align\n"
-" .type kernel_thread_helper, #function\n"
-"kernel_thread_helper:\n"
-" mov.a asr, r7\n"
-" mov r0, r4\n"
-" mov lr, r6\n"
-" mov pc, r5\n"
-" .size kernel_thread_helper, . - kernel_thread_helper\n"
-" .popsection");
-
-/*
- * Create a kernel thread.
- */
-pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
- struct pt_regs regs;
-
- memset(&regs, 0, sizeof(regs));
-
- regs.UCreg_04 = (unsigned long)arg;
- regs.UCreg_05 = (unsigned long)fn;
- regs.UCreg_06 = (unsigned long)do_exit;
- regs.UCreg_07 = PRIV_MODE;
- regs.UCreg_pc = (unsigned long)kernel_thread_helper;
- regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT;
-
- return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
unsigned long get_wchan(struct task_struct *p)
{
struct stackframe frame;
diff --git a/arch/unicore32/kernel/setup.h b/arch/unicore32/kernel/setup.h
index f23955028a1..30f749da8f7 100644
--- a/arch/unicore32/kernel/setup.h
+++ b/arch/unicore32/kernel/setup.h
@@ -30,4 +30,10 @@ extern char __vectors_start[], __vectors_end[];
extern void kernel_thread_helper(void);
extern void __init early_signal_init(void);
+
+extern asmlinkage void __backtrace(void);
+extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
+
+extern void __show_regs(struct pt_regs *);
+
#endif
diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c
index fabdee96110..9680134b31f 100644
--- a/arch/unicore32/kernel/sys.c
+++ b/arch/unicore32/kernel/sys.c
@@ -42,69 +42,6 @@ asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp,
parent_tid, child_tid);
}
-/* sys_execve() executes a new program.
- * This is called indirectly via a small wrapper
- */
-asmlinkage long __sys_execve(const char __user *filename,
- const char __user *const __user *argv,
- const char __user *const __user *envp,
- struct pt_regs *regs)
-{
- int error;
- struct filename *fn;
-
- fn = getname(filename);
- error = PTR_ERR(fn);
- if (IS_ERR(fn))
- goto out;
- error = do_execve(fn->name, argv, envp, regs);
- putname(fn);
-out:
- return error;
-}
-
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
-{
- struct pt_regs regs;
- int ret;
-
- memset(&regs, 0, sizeof(struct pt_regs));
- ret = do_execve(filename,
- (const char __user *const __user *)argv,
- (const char __user *const __user *)envp, &regs);
- if (ret < 0)
- goto out;
-
- /*
- * Save argc to the register structure for userspace.
- */
- regs.UCreg_00 = ret;
-
- /*
- * We were successful. We won't be returning to our caller, but
- * instead to user space by manipulating the kernel stack.
- */
- asm("add r0, %0, %1\n\t"
- "mov r1, %2\n\t"
- "mov r2, %3\n\t"
- "mov r22, #0\n\t" /* not a syscall */
- "mov r23, %0\n\t" /* thread structure */
- "b.l memmove\n\t" /* copy regs to top of stack */
- "mov sp, r0\n\t" /* reposition stack pointer */
- "b ret_to_user"
- :
- : "r" (current_thread_info()),
- "Ir" (THREAD_START_SP - sizeof(regs)),
- "r" (&regs),
- "Ir" (sizeof(regs))
- : "r0", "r1", "r2", "r3", "ip", "lr", "memory");
-
- out:
- return ret;
-}
-
/* Note: used by the compat code even in 64-bit Linux. */
SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c
index 2eeb9c04cab..f9b5c10bcce 100644
--- a/arch/unicore32/mm/fault.c
+++ b/arch/unicore32/mm/fault.c
@@ -168,7 +168,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma)
}
static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
- struct task_struct *tsk)
+ unsigned int flags, struct task_struct *tsk)
{
struct vm_area_struct *vma;
int fault;
@@ -194,14 +194,7 @@ good_area:
* If for any reason at all we couldn't handle the fault, make
* sure we exit gracefully rather than endlessly redo the fault.
*/
- fault = handle_mm_fault(mm, vma, addr & PAGE_MASK,
- (!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0);
- if (unlikely(fault & VM_FAULT_ERROR))
- return fault;
- if (fault & VM_FAULT_MAJOR)
- tsk->maj_flt++;
- else
- tsk->min_flt++;
+ fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, flags);
return fault;
check_stack:
@@ -216,6 +209,8 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
struct task_struct *tsk;
struct mm_struct *mm;
int fault, sig, code;
+ unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
+ ((!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0);
tsk = current;
mm = tsk->mm;
@@ -236,6 +231,7 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (!user_mode(regs)
&& !search_exception_tables(regs->UCreg_pc))
goto no_context;
+retry:
down_read(&mm->mmap_sem);
} else {
/*
@@ -251,7 +247,28 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
#endif
}
- fault = __do_pf(mm, addr, fsr, tsk);
+ fault = __do_pf(mm, addr, fsr, flags, tsk);
+
+ /* If we need to retry but a fatal signal is pending, handle the
+ * signal first. We do not need to release the mmap_sem because
+ * it would already be released in __lock_page_or_retry in
+ * mm/filemap.c. */
+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+ return 0;
+
+ if (!(fault & VM_FAULT_ERROR) && (flags & FAULT_FLAG_ALLOW_RETRY)) {
+ if (fault & VM_FAULT_MAJOR)
+ tsk->maj_flt++;
+ else
+ tsk->min_flt++;
+ if (fault & VM_FAULT_RETRY) {
+ /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
+ * of starvation. */
+ flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ goto retry;
+ }
+ }
+
up_read(&mm->mmap_sem);
/*
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 46c3bff3ced..037c4e30c27 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -69,8 +69,8 @@ config X86
select HAVE_PERF_USER_STACK_DUMP
select HAVE_DEBUG_KMEMLEAK
select ANON_INODES
- select HAVE_ALIGNED_STRUCT_PAGE if SLUB && !M386
- select HAVE_CMPXCHG_LOCAL if !M386
+ select HAVE_ALIGNED_STRUCT_PAGE if SLUB
+ select HAVE_CMPXCHG_LOCAL
select HAVE_CMPXCHG_DOUBLE
select HAVE_ARCH_KMEMCHECK
select HAVE_USER_RETURN_NOTIFIER
@@ -106,7 +106,7 @@ config X86
select KTIME_SCALAR if X86_32
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
- select HAVE_RCU_USER_QS if X86_64
+ select HAVE_CONTEXT_TRACKING if X86_64
select HAVE_IRQ_TIME_ACCOUNTING
select GENERIC_KERNEL_THREAD
select GENERIC_KERNEL_EXECVE
@@ -171,13 +171,8 @@ config ARCH_MAY_HAVE_PC_FDC
def_bool y
depends on ISA_DMA_API
-config RWSEM_GENERIC_SPINLOCK
- def_bool y
- depends on !X86_XADD
-
config RWSEM_XCHGADD_ALGORITHM
def_bool y
- depends on X86_XADD
config GENERIC_CALIBRATE_DELAY
def_bool y
@@ -310,7 +305,7 @@ config X86_X2APIC
If you don't know what to do here, say N.
config X86_MPPARSE
- bool "Enable MPS table" if ACPI
+ bool "Enable MPS table" if ACPI || SFI
default y
depends on X86_LOCAL_APIC
---help---
@@ -1100,7 +1095,7 @@ config HIGHMEM4G
config HIGHMEM64G
bool "64GB"
- depends on !M386 && !M486
+ depends on !M486
select X86_PAE
---help---
Select this if you have a 32-bit processor and more than 4
@@ -1698,6 +1693,50 @@ config HOTPLUG_CPU
automatically on SMP systems. )
Say N if you want to disable CPU hotplug.
+config BOOTPARAM_HOTPLUG_CPU0
+ bool "Set default setting of cpu0_hotpluggable"
+ default n
+ depends on HOTPLUG_CPU && EXPERIMENTAL
+ ---help---
+ Set whether default state of cpu0_hotpluggable is on or off.
+
+ Say Y here to enable CPU0 hotplug by default. If this switch
+ is turned on, there is no need to give cpu0_hotplug kernel
+ parameter and the CPU0 hotplug feature is enabled by default.
+
+ Please note: there are two known CPU0 dependencies if you want
+ to enable the CPU0 hotplug feature either by this switch or by
+ cpu0_hotplug kernel parameter.
+
+ First, resume from hibernate or suspend always starts from CPU0.
+ So hibernate and suspend are prevented if CPU0 is offline.
+
+ Second dependency is PIC interrupts always go to CPU0. CPU0 can not
+ offline if any interrupt can not migrate out of CPU0. There may
+ be other CPU0 dependencies.
+
+ Please make sure the dependencies are under your control before
+ you enable this feature.
+
+ Say N if you don't want to enable CPU0 hotplug feature by default.
+ You still can enable the CPU0 hotplug feature at boot by kernel
+ parameter cpu0_hotplug.
+
+config DEBUG_HOTPLUG_CPU0
+ def_bool n
+ prompt "Debug CPU0 hotplug"
+ depends on HOTPLUG_CPU && EXPERIMENTAL
+ ---help---
+ Enabling this option offlines CPU0 (if CPU0 can be offlined) as
+ soon as possible and boots up userspace with CPU0 offlined. User
+ can online CPU0 back after boot time.
+
+ To debug CPU0 hotplug, you need to enable CPU0 offline/online
+ feature by either turning on CONFIG_BOOTPARAM_HOTPLUG_CPU0 during
+ compilation or giving cpu0_hotplug kernel parameter at boot.
+
+ If unsure, say N.
+
config COMPAT_VDSO
def_bool y
prompt "Compat VDSO support"
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index f3b86d0df44..c026cca5602 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -4,23 +4,24 @@ choice
default M686 if X86_32
default GENERIC_CPU if X86_64
-config M386
- bool "386"
- depends on X86_32 && !UML
+config M486
+ bool "486"
+ depends on X86_32
---help---
- This is the processor type of your CPU. This information is used for
- optimizing purposes. In order to compile a kernel that can run on
- all x86 CPU types (albeit not optimally fast), you can specify
- "386" here.
+ This is the processor type of your CPU. This information is
+ used for optimizing purposes. In order to compile a kernel
+ that can run on all supported x86 CPU types (albeit not
+ optimally fast), you can specify "486" here.
+
+ Note that the 386 is no longer supported, this includes
+ AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI 486DLC/DLC2,
+ UMC 486SX-S and the NexGen Nx586.
The kernel will not necessarily run on earlier architectures than
the one you have chosen, e.g. a Pentium optimized kernel will run on
a PPro, but not necessarily on a i486.
Here are the settings recommended for greatest speed:
- - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
- 486DLC/DLC2, and UMC 486SX-S. Only "386" kernels will run on a 386
- class machine.
- "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
- "586" for generic Pentium CPUs lacking the TSC
@@ -43,16 +44,7 @@ config M386
- "VIA C3-2" for VIA C3-2 "Nehemiah" (model 9 and above).
- "VIA C7" for VIA C7.
- If you don't know what to do, choose "386".
-
-config M486
- bool "486"
- depends on X86_32
- ---help---
- Select this for a 486 series processor, either Intel or one of the
- compatible processors from AMD, Cyrix, IBM, or Intel. Includes DX,
- DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
- U5S.
+ If you don't know what to do, choose "486".
config M586
bool "586/K5/5x86/6x86/6x86MX"
@@ -305,24 +297,16 @@ config X86_INTERNODE_CACHE_SHIFT
default "12" if X86_VSMP
default X86_L1_CACHE_SHIFT
-config X86_CMPXCHG
- def_bool y
- depends on X86_64 || (X86_32 && !M386)
-
config X86_L1_CACHE_SHIFT
int
default "7" if MPENTIUM4 || MPSC
default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
- default "4" if MELAN || M486 || M386 || MGEODEGX1
+ default "4" if MELAN || M486 || MGEODEGX1
default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
-config X86_XADD
- def_bool y
- depends on !M386
-
config X86_PPRO_FENCE
bool "PentiumPro memory ordering errata workaround"
- depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
+ depends on M686 || M586MMX || M586TSC || M586 || M486 || MGEODEGX1
---help---
Old PentiumPro multiprocessor systems had errata that could cause
memory operations to violate the x86 ordering standard in rare cases.
@@ -335,27 +319,11 @@ config X86_PPRO_FENCE
config X86_F00F_BUG
def_bool y
- depends on M586MMX || M586TSC || M586 || M486 || M386
+ depends on M586MMX || M586TSC || M586 || M486
config X86_INVD_BUG
def_bool y
- depends on M486 || M386
-
-config X86_WP_WORKS_OK
- def_bool y
- depends on !M386
-
-config X86_INVLPG
- def_bool y
- depends on X86_32 && !M386
-
-config X86_BSWAP
- def_bool y
- depends on X86_32 && !M386
-
-config X86_POPAD_OK
- def_bool y
- depends on X86_32 && !M386
+ depends on M486
config X86_ALIGNMENT_16
def_bool y
@@ -412,12 +380,11 @@ config X86_MINIMUM_CPU_FAMILY
default "64" if X86_64
default "6" if X86_32 && X86_P6_NOP
default "5" if X86_32 && X86_CMPXCHG64
- default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK)
- default "3"
+ default "4"
config X86_DEBUGCTLMSR
def_bool y
- depends on !(MK6 || MWINCHIPC6 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486 || M386) && !UML
+ depends on !(MK6 || MWINCHIPC6 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486) && !UML
menuconfig PROCESSOR_SELECT
bool "Supported processor vendors" if EXPERT
@@ -441,7 +408,7 @@ config CPU_SUP_INTEL
config CPU_SUP_CYRIX_32
default y
bool "Support Cyrix processors" if PROCESSOR_SELECT
- depends on M386 || M486 || M586 || M586TSC || M586MMX || (EXPERT && !64BIT)
+ depends on M486 || M586 || M586TSC || M586MMX || (EXPERT && !64BIT)
---help---
This enables detection, tunings and quirks for Cyrix processors
@@ -495,7 +462,7 @@ config CPU_SUP_TRANSMETA_32
config CPU_SUP_UMC_32
default y
bool "Support UMC processors" if PROCESSOR_SELECT
- depends on M386 || M486 || (EXPERT && !64BIT)
+ depends on M486 || (EXPERT && !64BIT)
---help---
This enables detection, tunings and quirks for UMC processors
diff --git a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu
index 86cee7b749e..6647ed49c66 100644
--- a/arch/x86/Makefile_32.cpu
+++ b/arch/x86/Makefile_32.cpu
@@ -10,7 +10,6 @@ tune = $(call cc-option,-mcpu=$(1),$(2))
endif
align := $(cc-option-align)
-cflags-$(CONFIG_M386) += -march=i386
cflags-$(CONFIG_M486) += -march=i486
cflags-$(CONFIG_M586) += -march=i586
cflags-$(CONFIG_M586TSC) += -march=i586
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index c760e073963..e87b0cac14b 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -12,6 +12,8 @@
#include <asm/setup.h>
#include <asm/desc.h>
+#undef memcpy /* Use memcpy from misc.c */
+
#include "eboot.h"
static efi_system_table_t *sys_table;
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 2a017441b8b..8c132a625b9 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -476,6 +476,3 @@ die:
setup_corrupt:
.byte 7
.string "No setup signature found...\n"
-
- .data
-dummy: .long 0
diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild
index 66e5f0ef052..79fd8a3418f 100644
--- a/arch/x86/include/asm/Kbuild
+++ b/arch/x86/include/asm/Kbuild
@@ -12,6 +12,7 @@ header-y += mce.h
header-y += msr-index.h
header-y += msr.h
header-y += mtrr.h
+header-y += perf_regs.h
header-y += posix_types_32.h
header-y += posix_types_64.h
header-y += posix_types_x32.h
@@ -19,8 +20,10 @@ header-y += prctl.h
header-y += processor-flags.h
header-y += ptrace-abi.h
header-y += sigcontext32.h
+header-y += svm.h
header-y += ucontext.h
header-y += vm86.h
+header-y += vmx.h
header-y += vsyscall.h
genhdr-y += unistd_32.h
diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
index b6c3b821acf..722aa3b0462 100644
--- a/arch/x86/include/asm/atomic.h
+++ b/arch/x86/include/asm/atomic.h
@@ -172,23 +172,7 @@ static inline int atomic_add_negative(int i, atomic_t *v)
*/
static inline int atomic_add_return(int i, atomic_t *v)
{
-#ifdef CONFIG_M386
- int __i;
- unsigned long flags;
- if (unlikely(boot_cpu_data.x86 <= 3))
- goto no_xadd;
-#endif
- /* Modern 486+ processor */
return i + xadd(&v->counter, i);
-
-#ifdef CONFIG_M386
-no_xadd: /* Legacy 386 processor */
- raw_local_irq_save(flags);
- __i = atomic_read(v);
- atomic_set(v, i + __i);
- raw_local_irq_restore(flags);
- return i + __i;
-#endif
}
/**
diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h
index 53f4b219336..f8bf2eecab8 100644
--- a/arch/x86/include/asm/cmpxchg_32.h
+++ b/arch/x86/include/asm/cmpxchg_32.h
@@ -34,9 +34,7 @@ static inline void set_64bit(volatile u64 *ptr, u64 value)
: "memory");
}
-#ifdef CONFIG_X86_CMPXCHG
#define __HAVE_ARCH_CMPXCHG 1
-#endif
#ifdef CONFIG_X86_CMPXCHG64
#define cmpxchg64(ptr, o, n) \
@@ -73,59 +71,6 @@ static inline u64 __cmpxchg64_local(volatile u64 *ptr, u64 old, u64 new)
return prev;
}
-#ifndef CONFIG_X86_CMPXCHG
-/*
- * Building a kernel capable running on 80386. It may be necessary to
- * simulate the cmpxchg on the 80386 CPU. For that purpose we define
- * a function for each of the sizes we support.
- */
-
-extern unsigned long cmpxchg_386_u8(volatile void *, u8, u8);
-extern unsigned long cmpxchg_386_u16(volatile void *, u16, u16);
-extern unsigned long cmpxchg_386_u32(volatile void *, u32, u32);
-
-static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
- unsigned long new, int size)
-{
- switch (size) {
- case 1:
- return cmpxchg_386_u8(ptr, old, new);
- case 2:
- return cmpxchg_386_u16(ptr, old, new);
- case 4:
- return cmpxchg_386_u32(ptr, old, new);
- }
- return old;
-}
-
-#define cmpxchg(ptr, o, n) \
-({ \
- __typeof__(*(ptr)) __ret; \
- if (likely(boot_cpu_data.x86 > 3)) \
- __ret = (__typeof__(*(ptr)))__cmpxchg((ptr), \
- (unsigned long)(o), (unsigned long)(n), \
- sizeof(*(ptr))); \
- else \
- __ret = (__typeof__(*(ptr)))cmpxchg_386((ptr), \
- (unsigned long)(o), (unsigned long)(n), \
- sizeof(*(ptr))); \
- __ret; \
-})
-#define cmpxchg_local(ptr, o, n) \
-({ \
- __typeof__(*(ptr)) __ret; \
- if (likely(boot_cpu_data.x86 > 3)) \
- __ret = (__typeof__(*(ptr)))__cmpxchg_local((ptr), \
- (unsigned long)(o), (unsigned long)(n), \
- sizeof(*(ptr))); \
- else \
- __ret = (__typeof__(*(ptr)))cmpxchg_386((ptr), \
- (unsigned long)(o), (unsigned long)(n), \
- sizeof(*(ptr))); \
- __ret; \
-})
-#endif
-
#ifndef CONFIG_X86_CMPXCHG64
/*
* Building a kernel capable running on 80386 and 80486. It may be necessary
diff --git a/arch/x86/include/asm/rcu.h b/arch/x86/include/asm/context_tracking.h
index d1ac07a2397..1616562683e 100644
--- a/arch/x86/include/asm/rcu.h
+++ b/arch/x86/include/asm/context_tracking.h
@@ -1,27 +1,26 @@
-#ifndef _ASM_X86_RCU_H
-#define _ASM_X86_RCU_H
+#ifndef _ASM_X86_CONTEXT_TRACKING_H
+#define _ASM_X86_CONTEXT_TRACKING_H
#ifndef __ASSEMBLY__
-
-#include <linux/rcupdate.h>
+#include <linux/context_tracking.h>
#include <asm/ptrace.h>
static inline void exception_enter(struct pt_regs *regs)
{
- rcu_user_exit();
+ user_exit();
}
static inline void exception_exit(struct pt_regs *regs)
{
-#ifdef CONFIG_RCU_USER_QS
+#ifdef CONFIG_CONTEXT_TRACKING
if (user_mode(regs))
- rcu_user_enter();
+ user_enter();
#endif
}
#else /* __ASSEMBLY__ */
-#ifdef CONFIG_RCU_USER_QS
+#ifdef CONFIG_CONTEXT_TRACKING
# define SCHEDULE_USER call schedule_user
#else
# define SCHEDULE_USER call schedule
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index 4564c8e28a3..5f9a1243190 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -28,6 +28,10 @@ struct x86_cpu {
#ifdef CONFIG_HOTPLUG_CPU
extern int arch_register_cpu(int num);
extern void arch_unregister_cpu(int);
+extern void __cpuinit start_cpu0(void);
+#ifdef CONFIG_DEBUG_HOTPLUG_CPU0
+extern int _debug_hotplug_cpu(int cpu, int action);
+#endif
#endif
DECLARE_PER_CPU(int, cpu_state);
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 8c297aa53ee..da40b1e2228 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -311,12 +311,7 @@ extern const char * const x86_power_flags[32];
#define cpu_has_cx8 boot_cpu_has(X86_FEATURE_CX8)
#define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16)
#define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU)
-
-#if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64)
-# define cpu_has_invlpg 1
-#else
-# define cpu_has_invlpg (boot_cpu_data.x86 > 3)
-#endif
+#define cpu_has_topoext boot_cpu_has(X86_FEATURE_TOPOEXT)
#ifdef CONFIG_X86_64
diff --git a/arch/x86/include/asm/device.h b/arch/x86/include/asm/device.h
index 93e1c55f14a..03dd72957d2 100644
--- a/arch/x86/include/asm/device.h
+++ b/arch/x86/include/asm/device.h
@@ -2,9 +2,6 @@
#define _ASM_X86_DEVICE_H
struct dev_archdata {
-#ifdef CONFIG_ACPI
- void *acpi_handle;
-#endif
#ifdef CONFIG_X86_DEV_DMA_OPS
struct dma_map_ops *dma_ops;
#endif
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index 5939f44fe0c..9c999c1674f 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -354,12 +354,10 @@ static inline int mmap_is_ia32(void)
return 0;
}
-/* The first two values are special, do not change. See align_addr() */
+/* Do not change the values. See get_align_mask() */
enum align_flags {
ALIGN_VA_32 = BIT(0),
ALIGN_VA_64 = BIT(1),
- ALIGN_VDSO = BIT(2),
- ALIGN_TOPDOWN = BIT(3),
};
struct va_alignment {
@@ -368,5 +366,5 @@ struct va_alignment {
} ____cacheline_aligned;
extern struct va_alignment va_align;
-extern unsigned long align_addr(unsigned long, struct file *, enum align_flags);
+extern unsigned long align_vdso_addr(unsigned long);
#endif /* _ASM_X86_ELF_H */
diff --git a/arch/x86/include/asm/fpu-internal.h b/arch/x86/include/asm/fpu-internal.h
index 831dbb9c6c0..41ab26ea656 100644
--- a/arch/x86/include/asm/fpu-internal.h
+++ b/arch/x86/include/asm/fpu-internal.h
@@ -399,14 +399,17 @@ static inline void drop_init_fpu(struct task_struct *tsk)
typedef struct { int preload; } fpu_switch_t;
/*
- * FIXME! We could do a totally lazy restore, but we need to
- * add a per-cpu "this was the task that last touched the FPU
- * on this CPU" variable, and the task needs to have a "I last
- * touched the FPU on this CPU" and check them.
+ * Must be run with preemption disabled: this clears the fpu_owner_task,
+ * on this CPU.
*
- * We don't do that yet, so "fpu_lazy_restore()" always returns
- * false, but some day..
+ * This will disable any lazy FPU state restore of the current FPU state,
+ * but if the current thread owns the FPU, it will still be saved by.
*/
+static inline void __cpu_disable_lazy_restore(unsigned int cpu)
+{
+ per_cpu(fpu_owner_task, cpu) = NULL;
+}
+
static inline int fpu_lazy_restore(struct task_struct *new, unsigned int cpu)
{
return new == this_cpu_read_stable(fpu_owner_task) &&
diff --git a/arch/x86/include/asm/futex.h b/arch/x86/include/asm/futex.h
index f373046e63e..be27ba1e947 100644
--- a/arch/x86/include/asm/futex.h
+++ b/arch/x86/include/asm/futex.h
@@ -55,12 +55,6 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;
-#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_BSWAP)
- /* Real i386 machines can only support FUTEX_OP_SET */
- if (op != FUTEX_OP_SET && boot_cpu_data.x86 == 3)
- return -ENOSYS;
-#endif
-
pagefault_disable();
switch (op) {
@@ -118,12 +112,6 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
{
int ret = 0;
-#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_BSWAP)
- /* Real i386 machines have no cmpxchg instruction */
- if (boot_cpu_data.x86 == 3)
- return -ENOSYS;
-#endif
-
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;
diff --git a/arch/x86/include/asm/local.h b/arch/x86/include/asm/local.h
index c8bed0da434..2d89e3980cb 100644
--- a/arch/x86/include/asm/local.h
+++ b/arch/x86/include/asm/local.h
@@ -124,27 +124,11 @@ static inline int local_add_negative(long i, local_t *l)
*/
static inline long local_add_return(long i, local_t *l)
{
- long __i;
-#ifdef CONFIG_M386
- unsigned long flags;
- if (unlikely(boot_cpu_data.x86 <= 3))
- goto no_xadd;
-#endif
- /* Modern 486+ processor */
- __i = i;
+ long __i = i;
asm volatile(_ASM_XADD "%0, %1;"
: "+r" (i), "+m" (l->a.counter)
: : "memory");
return i + __i;
-
-#ifdef CONFIG_M386
-no_xadd: /* Legacy 386 processor */
- local_irq_save(flags);
- __i = local_read(l);
- local_set(l, i + __i);
- local_irq_restore(flags);
- return i + __i;
-#endif
}
static inline long local_sub_return(long i, local_t *l)
diff --git a/arch/x86/include/asm/mman.h b/arch/x86/include/asm/mman.h
index 593e51d4643..513b05f15bb 100644
--- a/arch/x86/include/asm/mman.h
+++ b/arch/x86/include/asm/mman.h
@@ -3,6 +3,9 @@
#define MAP_32BIT 0x40 /* only give out 32bit addresses */
+#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT)
+#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT)
+
#include <asm-generic/mman.h>
#endif /* _ASM_X86_MMAN_H */
diff --git a/arch/x86/include/asm/module.h b/arch/x86/include/asm/module.h
index 9eae7752ae9..e3b7819caee 100644
--- a/arch/x86/include/asm/module.h
+++ b/arch/x86/include/asm/module.h
@@ -5,8 +5,6 @@
#ifdef CONFIG_X86_64
/* X86_64 does not define MODULE_PROC_FAMILY */
-#elif defined CONFIG_M386
-#define MODULE_PROC_FAMILY "386 "
#elif defined CONFIG_M486
#define MODULE_PROC_FAMILY "486 "
#elif defined CONFIG_M586
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 7f0edceb756..e400cdb2dd6 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -337,6 +337,8 @@
#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38)
#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39)
+#define MSR_IA32_TSC_DEADLINE 0x000006E0
+
/* P4/Xeon+ specific */
#define MSR_IA32_MCG_EAX 0x00000180
#define MSR_IA32_MCG_EBX 0x00000181
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index 1104afaba52..0da5200ee79 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -406,7 +406,6 @@ do { \
#define this_cpu_xchg_2(pcp, nval) percpu_xchg_op(pcp, nval)
#define this_cpu_xchg_4(pcp, nval) percpu_xchg_op(pcp, nval)
-#ifndef CONFIG_M386
#define __this_cpu_add_return_1(pcp, val) percpu_add_return_op(pcp, val)
#define __this_cpu_add_return_2(pcp, val) percpu_add_return_op(pcp, val)
#define __this_cpu_add_return_4(pcp, val) percpu_add_return_op(pcp, val)
@@ -421,8 +420,6 @@ do { \
#define this_cpu_cmpxchg_2(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
#define this_cpu_cmpxchg_4(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
-#endif /* !CONFIG_M386 */
-
#ifdef CONFIG_X86_CMPXCHG64
#define percpu_cmpxchg8b_double(pcp1, pcp2, o1, o2, n1, n2) \
({ \
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index ad1fc851167..e101b38912d 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -187,7 +187,7 @@ extern void print_cpu_info(struct cpuinfo_x86 *);
void print_cpu_msr(struct cpuinfo_x86 *);
extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
-extern unsigned short num_cache_leaves;
+extern void init_amd_cacheinfo(struct cpuinfo_x86 *c);
extern void detect_extended_topology(struct cpuinfo_x86 *c);
extern void detect_ht(struct cpuinfo_x86 *c);
@@ -672,18 +672,29 @@ static inline void sync_core(void)
{
int tmp;
-#if defined(CONFIG_M386) || defined(CONFIG_M486)
- if (boot_cpu_data.x86 < 5)
- /* There is no speculative execution.
- * jmp is a barrier to prefetching. */
- asm volatile("jmp 1f\n1:\n" ::: "memory");
- else
+#ifdef CONFIG_M486
+ /*
+ * Do a CPUID if available, otherwise do a jump. The jump
+ * can conveniently enough be the jump around CPUID.
+ */
+ asm volatile("cmpl %2,%1\n\t"
+ "jl 1f\n\t"
+ "cpuid\n"
+ "1:"
+ : "=a" (tmp)
+ : "rm" (boot_cpu_data.cpuid_level), "ri" (0), "0" (1)
+ : "ebx", "ecx", "edx", "memory");
+#else
+ /*
+ * CPUID is a barrier to speculative execution.
+ * Prefetched instructions are automatically
+ * invalidated when modified.
+ */
+ asm volatile("cpuid"
+ : "=a" (tmp)
+ : "0" (1)
+ : "ebx", "ecx", "edx", "memory");
#endif
- /* cpuid is a barrier to speculative execution.
- * Prefetched instructions are automatically
- * invalidated when modified. */
- asm volatile("cpuid" : "=a" (tmp) : "0" (1)
- : "ebx", "ecx", "edx", "memory");
}
static inline void __monitor(const void *eax, unsigned long ecx,
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
index dcfde52979c..54d80fddb73 100644
--- a/arch/x86/include/asm/ptrace.h
+++ b/arch/x86/include/asm/ptrace.h
@@ -205,21 +205,14 @@ static inline bool user_64bit_mode(struct pt_regs *regs)
}
#endif
-/*
- * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode
- * when it traps. The previous stack will be directly underneath the saved
- * registers, and 'sp/ss' won't even have been saved. Thus the '&regs->sp'.
- *
- * This is valid only for kernel mode traps.
- */
-static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
-{
#ifdef CONFIG_X86_32
- return (unsigned long)(&regs->sp);
+extern unsigned long kernel_stack_pointer(struct pt_regs *regs);
#else
+static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
+{
return regs->sp;
-#endif
}
+#endif
#define GET_IP(regs) ((regs)->ip)
#define GET_FP(regs) ((regs)->bp)
@@ -246,6 +239,15 @@ static inline unsigned long regs_get_register(struct pt_regs *regs,
{
if (unlikely(offset > MAX_REG_OFFSET))
return 0;
+#ifdef CONFIG_X86_32
+ /*
+ * Traps from the kernel do not save sp and ss.
+ * Use the helper function to retrieve sp.
+ */
+ if (offset == offsetof(struct pt_regs, sp) &&
+ regs->cs == __KERNEL_CS)
+ return kernel_stack_pointer(regs);
+#endif
return *(unsigned long *)((unsigned long)regs + offset);
}
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 4f19a152603..b073aaea747 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -166,6 +166,7 @@ void native_send_call_func_ipi(const struct cpumask *mask);
void native_send_call_func_single_ipi(int cpu);
void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle);
+void smp_store_boot_cpu_info(void);
void smp_store_cpu_info(int id);
#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu)
diff --git a/arch/x86/include/asm/swab.h b/arch/x86/include/asm/swab.h
index 557cd9f0066..7f235c7105c 100644
--- a/arch/x86/include/asm/swab.h
+++ b/arch/x86/include/asm/swab.h
@@ -6,22 +6,7 @@
static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
{
-#ifdef __i386__
-# ifdef CONFIG_X86_BSWAP
- asm("bswap %0" : "=r" (val) : "0" (val));
-# else
- asm("xchgb %b0,%h0\n\t" /* swap lower bytes */
- "rorl $16,%0\n\t" /* swap words */
- "xchgb %b0,%h0" /* swap higher bytes */
- : "=q" (val)
- : "0" (val));
-# endif
-
-#else /* __i386__ */
- asm("bswapl %0"
- : "=r" (val)
- : "0" (val));
-#endif
+ asm("bswapl %0" : "=r" (val) : "0" (val));
return val;
}
#define __arch_swab32 __arch_swab32
@@ -37,22 +22,12 @@ static inline __attribute_const__ __u64 __arch_swab64(__u64 val)
__u64 u;
} v;
v.u = val;
-# ifdef CONFIG_X86_BSWAP
asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1"
: "=r" (v.s.a), "=r" (v.s.b)
: "0" (v.s.a), "1" (v.s.b));
-# else
- v.s.a = __arch_swab32(v.s.a);
- v.s.b = __arch_swab32(v.s.b);
- asm("xchgl %0,%1"
- : "=r" (v.s.a), "=r" (v.s.b)
- : "0" (v.s.a), "1" (v.s.b));
-# endif
return v.u;
#else /* __i386__ */
- asm("bswapq %0"
- : "=r" (val)
- : "0" (val));
+ asm("bswapq %0" : "=r" (val) : "0" (val));
return val;
#endif
}
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 74a44333545..0fee48e279c 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -56,10 +56,7 @@ static inline void __flush_tlb_all(void)
static inline void __flush_tlb_one(unsigned long addr)
{
- if (cpu_has_invlpg)
__flush_tlb_single(addr);
- else
- __flush_tlb();
}
#define TLB_FLUSH_ALL -1UL
diff --git a/arch/x86/include/asm/trace_clock.h b/arch/x86/include/asm/trace_clock.h
new file mode 100644
index 00000000000..beab86cc282
--- /dev/null
+++ b/arch/x86/include/asm/trace_clock.h
@@ -0,0 +1,20 @@
+#ifndef _ASM_X86_TRACE_CLOCK_H
+#define _ASM_X86_TRACE_CLOCK_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+#ifdef CONFIG_X86_TSC
+
+extern u64 notrace trace_clock_x86_tsc(void);
+
+# define ARCH_TRACE_CLOCKS \
+ { trace_clock_x86_tsc, "x86-tsc", .in_ns = 0 },
+
+#else /* !CONFIG_X86_TSC */
+
+#define ARCH_TRACE_CLOCKS
+
+#endif
+
+#endif /* _ASM_X86_TRACE_CLOCK_H */
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 7ccf8d13153..1709801d18e 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -237,8 +237,6 @@ extern void __put_user_2(void);
extern void __put_user_4(void);
extern void __put_user_8(void);
-#ifdef CONFIG_X86_WP_WORKS_OK
-
/**
* put_user: - Write a simple value into user space.
* @x: Value to copy to user space.
@@ -326,29 +324,6 @@ do { \
} \
} while (0)
-#else
-
-#define __put_user_size(x, ptr, size, retval, errret) \
-do { \
- __typeof__(*(ptr))__pus_tmp = x; \
- retval = 0; \
- \
- if (unlikely(__copy_to_user_ll(ptr, &__pus_tmp, size) != 0)) \
- retval = errret; \
-} while (0)
-
-#define put_user(x, ptr) \
-({ \
- int __ret_pu; \
- __typeof__(*(ptr))__pus_tmp = x; \
- __ret_pu = 0; \
- if (unlikely(__copy_to_user_ll(ptr, &__pus_tmp, \
- sizeof(*(ptr))) != 0)) \
- __ret_pu = -EFAULT; \
- __ret_pu; \
-})
-#endif
-
#ifdef CONFIG_X86_32
#define __get_user_asm_u64(x, ptr, retval, errret) (x) = __get_user_bad()
#define __get_user_asm_ex_u64(x, ptr) (x) = __get_user_bad()
@@ -543,29 +518,12 @@ struct __large_struct { unsigned long buf[100]; };
(x) = (__force __typeof__(*(ptr)))__gue_val; \
} while (0)
-#ifdef CONFIG_X86_WP_WORKS_OK
-
#define put_user_try uaccess_try
#define put_user_catch(err) uaccess_catch(err)
#define put_user_ex(x, ptr) \
__put_user_size_ex((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
-#else /* !CONFIG_X86_WP_WORKS_OK */
-
-#define put_user_try do { \
- int __uaccess_err = 0;
-
-#define put_user_catch(err) \
- (err) |= __uaccess_err; \
-} while (0)
-
-#define put_user_ex(x, ptr) do { \
- __uaccess_err |= __put_user(x, ptr); \
-} while (0)
-
-#endif /* CONFIG_X86_WP_WORKS_OK */
-
extern unsigned long
copy_from_user_nmi(void *to, const void __user *from, unsigned long n);
extern __must_check long
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 91ce48f05f9..34e923a5376 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -9,7 +9,6 @@ CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE)
ifdef CONFIG_FUNCTION_TRACER
# Do not profile debug and lowlevel utilities
CFLAGS_REMOVE_tsc.o = -pg
-CFLAGS_REMOVE_rtc.o = -pg
CFLAGS_REMOVE_paravirt-spinlocks.o = -pg
CFLAGS_REMOVE_pvclock.o = -pg
CFLAGS_REMOVE_kvmclock.o = -pg
@@ -62,6 +61,7 @@ obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
+obj-$(CONFIG_X86_TSC) += trace_clock.o
obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o
obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index e651f7a589a..e48cafcf92a 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -574,6 +574,12 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
return irq;
}
+EXPORT_SYMBOL_GPL(acpi_register_gsi);
+
+void acpi_unregister_gsi(u32 gsi)
+{
+}
+EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
void __init acpi_set_irq_model_pic(void)
{
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 11676cf65ae..d5e0d717005 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -101,6 +101,8 @@ static int __init acpi_sleep_setup(char *str)
#endif
if (strncmp(str, "nonvs", 5) == 0)
acpi_nvs_nosave();
+ if (strncmp(str, "nonvs_s3", 8) == 0)
+ acpi_nvs_nosave_s3();
if (strncmp(str, "old_ordering", 12) == 0)
acpi_old_suspend_ordering();
str = strchr(str, ',');
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index b17416e72fb..b994cc84aa7 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -90,21 +90,6 @@ EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
*/
DEFINE_EARLY_PER_CPU_READ_MOSTLY(int, x86_cpu_to_logical_apicid, BAD_APICID);
-/*
- * Knob to control our willingness to enable the local APIC.
- *
- * +1=force-enable
- */
-static int force_enable_local_apic __initdata;
-/*
- * APIC command line parameters
- */
-static int __init parse_lapic(char *arg)
-{
- force_enable_local_apic = 1;
- return 0;
-}
-early_param("lapic", parse_lapic);
/* Local APIC was disabled by the BIOS and enabled by the kernel */
static int enabled_via_apicbase;
@@ -133,6 +118,25 @@ static inline void imcr_apic_to_pic(void)
}
#endif
+/*
+ * Knob to control our willingness to enable the local APIC.
+ *
+ * +1=force-enable
+ */
+static int force_enable_local_apic __initdata;
+/*
+ * APIC command line parameters
+ */
+static int __init parse_lapic(char *arg)
+{
+ if (config_enabled(CONFIG_X86_32) && !arg)
+ force_enable_local_apic = 1;
+ else if (!strncmp(arg, "notscdeadline", 13))
+ setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER);
+ return 0;
+}
+early_param("lapic", parse_lapic);
+
#ifdef CONFIG_X86_64
static int apic_calibrate_pmtmr __initdata;
static __init int setup_apicpmtimer(char *s)
@@ -315,6 +319,7 @@ int lapic_get_maxlvt(void)
/* Clock divisor */
#define APIC_DIVISOR 16
+#define TSC_DIVISOR 32
/*
* This function sets up the local APIC timer, with a timeout of
@@ -333,6 +338,9 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
lvtt_value = LOCAL_TIMER_VECTOR;
if (!oneshot)
lvtt_value |= APIC_LVT_TIMER_PERIODIC;
+ else if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER))
+ lvtt_value |= APIC_LVT_TIMER_TSCDEADLINE;
+
if (!lapic_is_integrated())
lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV);
@@ -341,6 +349,11 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
apic_write(APIC_LVTT, lvtt_value);
+ if (lvtt_value & APIC_LVT_TIMER_TSCDEADLINE) {
+ printk_once(KERN_DEBUG "TSC deadline timer enabled\n");
+ return;
+ }
+
/*
* Divide PICLK by 16
*/
@@ -453,6 +466,16 @@ static int lapic_next_event(unsigned long delta,
return 0;
}
+static int lapic_next_deadline(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ u64 tsc;
+
+ rdtscll(tsc);
+ wrmsrl(MSR_IA32_TSC_DEADLINE, tsc + (((u64) delta) * TSC_DIVISOR));
+ return 0;
+}
+
/*
* Setup the lapic timer in periodic or oneshot mode
*/
@@ -533,7 +556,15 @@ static void __cpuinit setup_APIC_timer(void)
memcpy(levt, &lapic_clockevent, sizeof(*levt));
levt->cpumask = cpumask_of(smp_processor_id());
- clockevents_register_device(levt);
+ if (this_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) {
+ levt->features &= ~(CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_DUMMY);
+ levt->set_next_event = lapic_next_deadline;
+ clockevents_config_and_register(levt,
+ (tsc_khz / TSC_DIVISOR) * 1000,
+ 0xF, ~0UL);
+ } else
+ clockevents_register_device(levt);
}
/*
@@ -661,7 +692,9 @@ static int __init calibrate_APIC_clock(void)
* in the clockevent structure and return.
*/
- if (lapic_timer_frequency) {
+ if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) {
+ return 0;
+ } else if (lapic_timer_frequency) {
apic_printk(APIC_VERBOSE, "lapic timer already calibrated %d\n",
lapic_timer_frequency);
lapic_clockevent.mult = div_sc(lapic_timer_frequency/APIC_DIVISOR,
@@ -674,6 +707,9 @@ static int __init calibrate_APIC_clock(void)
return 0;
}
+ apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
+ "calibrating APIC timer ...\n");
+
local_irq_disable();
/* Replace the global interrupt handler */
@@ -811,9 +847,6 @@ void __init setup_boot_APIC_clock(void)
return;
}
- apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
- "calibrating APIC timer ...\n");
-
if (calibrate_APIC_clock()) {
/* No broadcast on UP ! */
if (num_possible_cpus() > 1)
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 1817fa91102..b739d398bb2 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -234,11 +234,11 @@ int __init arch_early_irq_init(void)
zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_KERNEL, node);
/*
* For legacy IRQ's, start with assigning irq0 to irq15 to
- * IRQ0_VECTOR to IRQ15_VECTOR on cpu 0.
+ * IRQ0_VECTOR to IRQ15_VECTOR for all cpu's.
*/
if (i < legacy_pic->nr_legacy_irqs) {
cfg[i].vector = IRQ0_VECTOR + i;
- cpumask_set_cpu(0, cfg[i].domain);
+ cpumask_setall(cfg[i].domain);
}
}
@@ -1141,7 +1141,8 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
* allocation for the members that are not used anymore.
*/
cpumask_andnot(cfg->old_domain, cfg->domain, tmp_mask);
- cfg->move_in_progress = 1;
+ cfg->move_in_progress =
+ cpumask_intersects(cfg->old_domain, cpu_online_mask);
cpumask_and(cfg->domain, cfg->domain, tmp_mask);
break;
}
@@ -1172,8 +1173,9 @@ next:
current_vector = vector;
current_offset = offset;
if (cfg->vector) {
- cfg->move_in_progress = 1;
cpumask_copy(cfg->old_domain, cfg->domain);
+ cfg->move_in_progress =
+ cpumask_intersects(cfg->old_domain, cpu_online_mask);
}
for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask)
per_cpu(vector_irq, new_cpu)[vector] = irq;
@@ -1241,12 +1243,6 @@ void __setup_vector_irq(int cpu)
cfg = irq_get_chip_data(irq);
if (!cfg)
continue;
- /*
- * If it is a legacy IRQ handled by the legacy PIC, this cpu
- * will be part of the irq_cfg's domain.
- */
- if (irq < legacy_pic->nr_legacy_irqs && !IO_APIC_IRQ(irq))
- cpumask_set_cpu(cpu, cfg->domain);
if (!cpumask_test_cpu(cpu, cfg->domain))
continue;
@@ -1356,16 +1352,6 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg,
if (!IO_APIC_IRQ(irq))
return;
- /*
- * For legacy irqs, cfg->domain starts with cpu 0. Now that IO-APIC
- * can handle this irq and the apic driver is finialized at this point,
- * update the cfg->domain.
- */
- if (irq < legacy_pic->nr_legacy_irqs &&
- cpumask_equal(cfg->domain, cpumask_of(0)))
- apic->vector_allocation_domain(0, cfg->domain,
- apic->target_cpus());
-
if (assign_irq_vector(irq, cfg, apic->target_cpus()))
return;
@@ -2199,9 +2185,11 @@ static int ioapic_retrigger_irq(struct irq_data *data)
{
struct irq_cfg *cfg = data->chip_data;
unsigned long flags;
+ int cpu;
raw_spin_lock_irqsave(&vector_lock, flags);
- apic->send_IPI_mask(cpumask_of(cpumask_first(cfg->domain)), cfg->vector);
+ cpu = cpumask_first_and(cfg->domain, cpu_online_mask);
+ apic->send_IPI_mask(cpumask_of(cpu), cfg->vector);
raw_spin_unlock_irqrestore(&vector_lock, flags);
return 1;
@@ -3317,8 +3305,9 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
int ret;
if (irq_remapping_enabled) {
- if (!setup_hpet_msi_remapped(irq, id))
- return -1;
+ ret = setup_hpet_msi_remapped(irq, id);
+ if (ret)
+ return ret;
}
ret = msi_compose_msg(NULL, irq, &msg, id);
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index f7e98a2c0d1..15239fffd6f 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -304,7 +304,7 @@ static void __cpuinit amd_get_topology(struct cpuinfo_x86 *c)
int cpu = smp_processor_id();
/* get information required for multi-node processors */
- if (cpu_has(c, X86_FEATURE_TOPOEXT)) {
+ if (cpu_has_topoext) {
u32 eax, ebx, ecx, edx;
cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
@@ -631,6 +631,20 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
}
}
+ /*
+ * The way access filter has a performance penalty on some workloads.
+ * Disable it on the affected CPUs.
+ */
+ if ((c->x86 == 0x15) &&
+ (c->x86_model >= 0x02) && (c->x86_model < 0x20)) {
+ u64 val;
+
+ if (!rdmsrl_safe(0xc0011021, &val) && !(val & 0x1E)) {
+ val |= 0x1E;
+ wrmsrl_safe(0xc0011021, val);
+ }
+ }
+
cpu_detect_cache_sizes(c);
/* Multi core CPU? */
@@ -643,12 +657,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
detect_ht(c);
#endif
- if (c->extended_cpuid_level >= 0x80000006) {
- if (cpuid_edx(0x80000006) & 0xf000)
- num_cache_leaves = 4;
- else
- num_cache_leaves = 3;
- }
+ init_amd_cacheinfo(c);
if (c->x86 >= 0xf)
set_cpu_cap(c, X86_FEATURE_K8);
@@ -739,9 +748,6 @@ static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c,
static void __cpuinit cpu_set_tlb_flushall_shift(struct cpuinfo_x86 *c)
{
- if (!cpu_has_invlpg)
- return;
-
tlb_flushall_shift = 5;
if (c->x86 <= 0x11)
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index d0e910da16c..92dfec986a4 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -107,53 +107,17 @@ static void __init check_hlt(void)
}
/*
- * Most 386 processors have a bug where a POPAD can lock the
- * machine even from user space.
- */
-
-static void __init check_popad(void)
-{
-#ifndef CONFIG_X86_POPAD_OK
- int res, inp = (int) &res;
-
- pr_info("Checking for popad bug... ");
- __asm__ __volatile__(
- "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx "
- : "=&a" (res)
- : "d" (inp)
- : "ecx", "edi");
- /*
- * If this fails, it means that any user program may lock the
- * CPU hard. Too bad.
- */
- if (res != 12345678)
- pr_cont("Buggy\n");
- else
- pr_cont("OK\n");
-#endif
-}
-
-/*
* Check whether we are able to run this kernel safely on SMP.
*
- * - In order to run on a i386, we need to be compiled for i386
- * (for due to lack of "invlpg" and working WP on a i386)
+ * - i386 is no longer supported.
* - In order to run on anything without a TSC, we need to be
* compiled for a i486.
*/
static void __init check_config(void)
{
-/*
- * We'd better not be a i386 if we're configured to use some
- * i486+ only features! (WP works in supervisor mode and the
- * new "invlpg" and "bswap" instructions)
- */
-#if defined(CONFIG_X86_WP_WORKS_OK) || defined(CONFIG_X86_INVLPG) || \
- defined(CONFIG_X86_BSWAP)
- if (boot_cpu_data.x86 == 3)
+ if (boot_cpu_data.x86 < 4)
panic("Kernel requires i486+ for 'invlpg' and other features");
-#endif
}
@@ -166,7 +130,6 @@ void __init check_bugs(void)
#endif
check_config();
check_hlt();
- check_popad();
init_utsname()->machine[1] =
'0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
alternative_instructions();
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 7505f7b13e7..ca165ac6793 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1237,7 +1237,7 @@ void __cpuinit cpu_init(void)
oist = &per_cpu(orig_ist, cpu);
#ifdef CONFIG_NUMA
- if (cpu != 0 && this_cpu_read(numa_node) == 0 &&
+ if (this_cpu_read(numa_node) == 0 &&
early_cpu_to_node(cpu) != NUMA_NO_NODE)
set_numa_node(early_cpu_to_node(cpu));
#endif
@@ -1269,8 +1269,7 @@ void __cpuinit cpu_init(void)
barrier();
x86_configure_nx();
- if (cpu != 0)
- enable_x2apic();
+ enable_x2apic();
/*
* set up and load the per-CPU TSS
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 198e019a531..fcaabd0432c 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -612,10 +612,6 @@ static void __cpuinit intel_tlb_lookup(const unsigned char desc)
static void __cpuinit intel_tlb_flushall_shift_set(struct cpuinfo_x86 *c)
{
- if (!cpu_has_invlpg) {
- tlb_flushall_shift = -1;
- return;
- }
switch ((c->x86 << 8) + c->x86_model) {
case 0x60f: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
case 0x616: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 93c5451bdd5..fe9edec6698 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -538,7 +538,11 @@ __cpuinit cpuid4_cache_lookup_regs(int index,
unsigned edx;
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
- amd_cpuid4(index, &eax, &ebx, &ecx);
+ if (cpu_has_topoext)
+ cpuid_count(0x8000001d, index, &eax.full,
+ &ebx.full, &ecx.full, &edx);
+ else
+ amd_cpuid4(index, &eax, &ebx, &ecx);
amd_init_l3_cache(this_leaf, index);
} else {
cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
@@ -557,21 +561,39 @@ __cpuinit cpuid4_cache_lookup_regs(int index,
return 0;
}
-static int __cpuinit find_num_cache_leaves(void)
+static int __cpuinit find_num_cache_leaves(struct cpuinfo_x86 *c)
{
- unsigned int eax, ebx, ecx, edx;
+ unsigned int eax, ebx, ecx, edx, op;
union _cpuid4_leaf_eax cache_eax;
int i = -1;
+ if (c->x86_vendor == X86_VENDOR_AMD)
+ op = 0x8000001d;
+ else
+ op = 4;
+
do {
++i;
- /* Do cpuid(4) loop to find out num_cache_leaves */
- cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
+ /* Do cpuid(op) loop to find out num_cache_leaves */
+ cpuid_count(op, i, &eax, &ebx, &ecx, &edx);
cache_eax.full = eax;
} while (cache_eax.split.type != CACHE_TYPE_NULL);
return i;
}
+void __cpuinit init_amd_cacheinfo(struct cpuinfo_x86 *c)
+{
+
+ if (cpu_has_topoext) {
+ num_cache_leaves = find_num_cache_leaves(c);
+ } else if (c->extended_cpuid_level >= 0x80000006) {
+ if (cpuid_edx(0x80000006) & 0xf000)
+ num_cache_leaves = 4;
+ else
+ num_cache_leaves = 3;
+ }
+}
+
unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
{
/* Cache sizes */
@@ -588,7 +610,7 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
if (is_initialized == 0) {
/* Init num_cache_leaves from boot CPU */
- num_cache_leaves = find_num_cache_leaves();
+ num_cache_leaves = find_num_cache_leaves(c);
is_initialized++;
}
@@ -728,37 +750,50 @@ static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info);
static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index)
{
struct _cpuid4_info *this_leaf;
- int ret, i, sibling;
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ int i, sibling;
- ret = 0;
- if (index == 3) {
- ret = 1;
- for_each_cpu(i, cpu_llc_shared_mask(cpu)) {
+ if (cpu_has_topoext) {
+ unsigned int apicid, nshared, first, last;
+
+ if (!per_cpu(ici_cpuid4_info, cpu))
+ return 0;
+
+ this_leaf = CPUID4_INFO_IDX(cpu, index);
+ nshared = this_leaf->base.eax.split.num_threads_sharing + 1;
+ apicid = cpu_data(cpu).apicid;
+ first = apicid - (apicid % nshared);
+ last = first + nshared - 1;
+
+ for_each_online_cpu(i) {
+ apicid = cpu_data(i).apicid;
+ if ((apicid < first) || (apicid > last))
+ continue;
if (!per_cpu(ici_cpuid4_info, i))
continue;
this_leaf = CPUID4_INFO_IDX(i, index);
- for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) {
- if (!cpu_online(sibling))
+
+ for_each_online_cpu(sibling) {
+ apicid = cpu_data(sibling).apicid;
+ if ((apicid < first) || (apicid > last))
continue;
set_bit(sibling, this_leaf->shared_cpu_map);
}
}
- } else if ((c->x86 == 0x15) && ((index == 1) || (index == 2))) {
- ret = 1;
- for_each_cpu(i, cpu_sibling_mask(cpu)) {
+ } else if (index == 3) {
+ for_each_cpu(i, cpu_llc_shared_mask(cpu)) {
if (!per_cpu(ici_cpuid4_info, i))
continue;
this_leaf = CPUID4_INFO_IDX(i, index);
- for_each_cpu(sibling, cpu_sibling_mask(cpu)) {
+ for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) {
if (!cpu_online(sibling))
continue;
set_bit(sibling, this_leaf->shared_cpu_map);
}
}
- }
+ } else
+ return 0;
- return ret;
+ return 1;
}
static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index 698b6ec12e0..1ac581f38df 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -6,7 +6,7 @@
*
* Written by Jacob Shin - AMD, Inc.
*
- * Support: borislav.petkov@amd.com
+ * Maintained by: Borislav Petkov <bp@alien8.de>
*
* April 2006
* - added support for AMD Family 0x10 processors
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c
index 5f88abf07e9..4f9a3cbfc4a 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_intel.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c
@@ -285,34 +285,39 @@ void cmci_clear(void)
raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
}
+static long cmci_rediscover_work_func(void *arg)
+{
+ int banks;
+
+ /* Recheck banks in case CPUs don't all have the same */
+ if (cmci_supported(&banks))
+ cmci_discover(banks);
+
+ return 0;
+}
+
/*
* After a CPU went down cycle through all the others and rediscover
* Must run in process context.
*/
void cmci_rediscover(int dying)
{
- int banks;
- int cpu;
- cpumask_var_t old;
+ int cpu, banks;
if (!cmci_supported(&banks))
return;
- if (!alloc_cpumask_var(&old, GFP_KERNEL))
- return;
- cpumask_copy(old, &current->cpus_allowed);
for_each_online_cpu(cpu) {
if (cpu == dying)
continue;
- if (set_cpus_allowed_ptr(current, cpumask_of(cpu)))
+
+ if (cpu == smp_processor_id()) {
+ cmci_rediscover_work_func(NULL);
continue;
- /* Recheck banks in case CPUs don't all have the same */
- if (cmci_supported(&banks))
- cmci_discover(banks);
- }
+ }
- set_cpus_allowed_ptr(current, old);
- free_cpumask_var(old);
+ work_on_cpu(cpu, cmci_rediscover_work_func, NULL);
+ }
}
/*
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index 6b96110bb0c..e4c1a418453 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -695,11 +695,16 @@ void mtrr_ap_init(void)
}
/**
- * Save current fixed-range MTRR state of the BSP
+ * Save current fixed-range MTRR state of the first cpu in cpu_online_mask.
*/
void mtrr_save_state(void)
{
- smp_call_function_single(0, mtrr_save_fixed_ranges, NULL, 1);
+ int first_cpu;
+
+ get_online_cpus();
+ first_cpu = cpumask_first(cpu_online_mask);
+ smp_call_function_single(first_cpu, mtrr_save_fixed_ranges, NULL, 1);
+ put_online_cpus();
}
void set_mtrr_aps_delayed_init(void)
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 4a3374e61a9..4428fd178bc 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1316,6 +1316,121 @@ static struct attribute_group x86_pmu_format_group = {
.attrs = NULL,
};
+struct perf_pmu_events_attr {
+ struct device_attribute attr;
+ u64 id;
+};
+
+/*
+ * Remove all undefined events (x86_pmu.event_map(id) == 0)
+ * out of events_attr attributes.
+ */
+static void __init filter_events(struct attribute **attrs)
+{
+ int i, j;
+
+ for (i = 0; attrs[i]; i++) {
+ if (x86_pmu.event_map(i))
+ continue;
+
+ for (j = i; attrs[j]; j++)
+ attrs[j] = attrs[j + 1];
+
+ /* Check the shifted attr. */
+ i--;
+ }
+}
+
+static ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr,
+ char *page)
+{
+ struct perf_pmu_events_attr *pmu_attr = \
+ container_of(attr, struct perf_pmu_events_attr, attr);
+
+ u64 config = x86_pmu.event_map(pmu_attr->id);
+ return x86_pmu.events_sysfs_show(page, config);
+}
+
+#define EVENT_VAR(_id) event_attr_##_id
+#define EVENT_PTR(_id) &event_attr_##_id.attr.attr
+
+#define EVENT_ATTR(_name, _id) \
+static struct perf_pmu_events_attr EVENT_VAR(_id) = { \
+ .attr = __ATTR(_name, 0444, events_sysfs_show, NULL), \
+ .id = PERF_COUNT_HW_##_id, \
+};
+
+EVENT_ATTR(cpu-cycles, CPU_CYCLES );
+EVENT_ATTR(instructions, INSTRUCTIONS );
+EVENT_ATTR(cache-references, CACHE_REFERENCES );
+EVENT_ATTR(cache-misses, CACHE_MISSES );
+EVENT_ATTR(branch-instructions, BRANCH_INSTRUCTIONS );
+EVENT_ATTR(branch-misses, BRANCH_MISSES );
+EVENT_ATTR(bus-cycles, BUS_CYCLES );
+EVENT_ATTR(stalled-cycles-frontend, STALLED_CYCLES_FRONTEND );
+EVENT_ATTR(stalled-cycles-backend, STALLED_CYCLES_BACKEND );
+EVENT_ATTR(ref-cycles, REF_CPU_CYCLES );
+
+static struct attribute *empty_attrs;
+
+static struct attribute *events_attr[] = {
+ EVENT_PTR(CPU_CYCLES),
+ EVENT_PTR(INSTRUCTIONS),
+ EVENT_PTR(CACHE_REFERENCES),
+ EVENT_PTR(CACHE_MISSES),
+ EVENT_PTR(BRANCH_INSTRUCTIONS),
+ EVENT_PTR(BRANCH_MISSES),
+ EVENT_PTR(BUS_CYCLES),
+ EVENT_PTR(STALLED_CYCLES_FRONTEND),
+ EVENT_PTR(STALLED_CYCLES_BACKEND),
+ EVENT_PTR(REF_CPU_CYCLES),
+ NULL,
+};
+
+static struct attribute_group x86_pmu_events_group = {
+ .name = "events",
+ .attrs = events_attr,
+};
+
+ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event)
+{
+ u64 umask = (config & ARCH_PERFMON_EVENTSEL_UMASK) >> 8;
+ u64 cmask = (config & ARCH_PERFMON_EVENTSEL_CMASK) >> 24;
+ bool edge = (config & ARCH_PERFMON_EVENTSEL_EDGE);
+ bool pc = (config & ARCH_PERFMON_EVENTSEL_PIN_CONTROL);
+ bool any = (config & ARCH_PERFMON_EVENTSEL_ANY);
+ bool inv = (config & ARCH_PERFMON_EVENTSEL_INV);
+ ssize_t ret;
+
+ /*
+ * We have whole page size to spend and just little data
+ * to write, so we can safely use sprintf.
+ */
+ ret = sprintf(page, "event=0x%02llx", event);
+
+ if (umask)
+ ret += sprintf(page + ret, ",umask=0x%02llx", umask);
+
+ if (edge)
+ ret += sprintf(page + ret, ",edge");
+
+ if (pc)
+ ret += sprintf(page + ret, ",pc");
+
+ if (any)
+ ret += sprintf(page + ret, ",any");
+
+ if (inv)
+ ret += sprintf(page + ret, ",inv");
+
+ if (cmask)
+ ret += sprintf(page + ret, ",cmask=0x%02llx", cmask);
+
+ ret += sprintf(page + ret, "\n");
+
+ return ret;
+}
+
static int __init init_hw_perf_events(void)
{
struct x86_pmu_quirk *quirk;
@@ -1362,6 +1477,11 @@ static int __init init_hw_perf_events(void)
x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */
x86_pmu_format_group.attrs = x86_pmu.format_attrs;
+ if (!x86_pmu.events_sysfs_show)
+ x86_pmu_events_group.attrs = &empty_attrs;
+ else
+ filter_events(x86_pmu_events_group.attrs);
+
pr_info("... version: %d\n", x86_pmu.version);
pr_info("... bit width: %d\n", x86_pmu.cntval_bits);
pr_info("... generic registers: %d\n", x86_pmu.num_counters);
@@ -1651,6 +1771,7 @@ static struct attribute_group x86_pmu_attr_group = {
static const struct attribute_group *x86_pmu_attr_groups[] = {
&x86_pmu_attr_group,
&x86_pmu_format_group,
+ &x86_pmu_events_group,
NULL,
};
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 271d2570029..115c1ea9774 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -354,6 +354,8 @@ struct x86_pmu {
int attr_rdpmc;
struct attribute **format_attrs;
+ ssize_t (*events_sysfs_show)(char *page, u64 config);
+
/*
* CPU Hotplug hooks
*/
@@ -536,6 +538,9 @@ static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip)
regs->ip = ip;
}
+ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event);
+ssize_t intel_event_sysfs_show(char *page, u64 config);
+
#ifdef CONFIG_CPU_SUP_AMD
int amd_pmu_init(void);
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c
index 4528ae7b6ec..c93bc4e813a 100644
--- a/arch/x86/kernel/cpu/perf_event_amd.c
+++ b/arch/x86/kernel/cpu/perf_event_amd.c
@@ -568,6 +568,14 @@ amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, struct perf_event *ev
}
}
+static ssize_t amd_event_sysfs_show(char *page, u64 config)
+{
+ u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT) |
+ (config & AMD64_EVENTSEL_EVENT) >> 24;
+
+ return x86_event_sysfs_show(page, config, event);
+}
+
static __initconst const struct x86_pmu amd_pmu = {
.name = "AMD",
.handle_irq = x86_pmu_handle_irq,
@@ -591,6 +599,7 @@ static __initconst const struct x86_pmu amd_pmu = {
.put_event_constraints = amd_put_event_constraints,
.format_attrs = amd_format_attr,
+ .events_sysfs_show = amd_event_sysfs_show,
.cpu_prepare = amd_pmu_cpu_prepare,
.cpu_starting = amd_pmu_cpu_starting,
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 324bb523d9d..93b9e1181f8 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -1603,6 +1603,13 @@ static struct attribute *intel_arch_formats_attr[] = {
NULL,
};
+ssize_t intel_event_sysfs_show(char *page, u64 config)
+{
+ u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT);
+
+ return x86_event_sysfs_show(page, config, event);
+}
+
static __initconst const struct x86_pmu core_pmu = {
.name = "core",
.handle_irq = x86_pmu_handle_irq,
@@ -1628,6 +1635,7 @@ static __initconst const struct x86_pmu core_pmu = {
.event_constraints = intel_core_event_constraints,
.guest_get_msrs = core_guest_get_msrs,
.format_attrs = intel_arch_formats_attr,
+ .events_sysfs_show = intel_event_sysfs_show,
};
struct intel_shared_regs *allocate_shared_regs(int cpu)
@@ -1766,6 +1774,7 @@ static __initconst const struct x86_pmu intel_pmu = {
.pebs_aliases = intel_pebs_aliases_core2,
.format_attrs = intel_arch3_formats_attr,
+ .events_sysfs_show = intel_event_sysfs_show,
.cpu_prepare = intel_pmu_cpu_prepare,
.cpu_starting = intel_pmu_cpu_starting,
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c
index 7d0270bd793..f2af39f5dc3 100644
--- a/arch/x86/kernel/cpu/perf_event_p6.c
+++ b/arch/x86/kernel/cpu/perf_event_p6.c
@@ -227,6 +227,8 @@ static __initconst const struct x86_pmu p6_pmu = {
.event_constraints = p6_event_constraints,
.format_attrs = intel_p6_formats_attr,
+ .events_sysfs_show = intel_event_sysfs_show,
+
};
__init int p6_pmu_init(void)
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index b51b2c7ee51..31b46128a63 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -56,7 +56,7 @@
#include <asm/ftrace.h>
#include <asm/percpu.h>
#include <asm/asm.h>
-#include <asm/rcu.h>
+#include <asm/context_tracking.h>
#include <asm/smap.h>
#include <linux/err.h>
@@ -995,8 +995,8 @@ END(interrupt)
*/
.p2align CONFIG_X86_L1_CACHE_SHIFT
common_interrupt:
- ASM_CLAC
XCPT_FRAME
+ ASM_CLAC
addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */
interrupt do_IRQ
/* 0(%rsp): old_rsp-ARGOFFSET */
@@ -1135,8 +1135,8 @@ END(common_interrupt)
*/
.macro apicinterrupt num sym do_sym
ENTRY(\sym)
- ASM_CLAC
INTR_FRAME
+ ASM_CLAC
pushq_cfi $~(\num)
.Lcommon_\sym:
interrupt \do_sym
@@ -1190,8 +1190,8 @@ apicinterrupt IRQ_WORK_VECTOR \
*/
.macro zeroentry sym do_sym
ENTRY(\sym)
- ASM_CLAC
INTR_FRAME
+ ASM_CLAC
PARAVIRT_ADJUST_EXCEPTION_FRAME
pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */
subq $ORIG_RAX-R15, %rsp
@@ -1208,8 +1208,8 @@ END(\sym)
.macro paranoidzeroentry sym do_sym
ENTRY(\sym)
- ASM_CLAC
INTR_FRAME
+ ASM_CLAC
PARAVIRT_ADJUST_EXCEPTION_FRAME
pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */
subq $ORIG_RAX-R15, %rsp
@@ -1227,8 +1227,8 @@ END(\sym)
#define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8)
.macro paranoidzeroentry_ist sym do_sym ist
ENTRY(\sym)
- ASM_CLAC
INTR_FRAME
+ ASM_CLAC
PARAVIRT_ADJUST_EXCEPTION_FRAME
pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */
subq $ORIG_RAX-R15, %rsp
@@ -1247,8 +1247,8 @@ END(\sym)
.macro errorentry sym do_sym
ENTRY(\sym)
- ASM_CLAC
XCPT_FRAME
+ ASM_CLAC
PARAVIRT_ADJUST_EXCEPTION_FRAME
subq $ORIG_RAX-R15, %rsp
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
@@ -1266,8 +1266,8 @@ END(\sym)
/* error code is on the stack already */
.macro paranoiderrorentry sym do_sym
ENTRY(\sym)
- ASM_CLAC
XCPT_FRAME
+ ASM_CLAC
PARAVIRT_ADJUST_EXCEPTION_FRAME
subq $ORIG_RAX-R15, %rsp
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
@@ -1699,9 +1699,10 @@ nested_nmi:
1:
/* Set up the interrupted NMIs stack to jump to repeat_nmi */
- leaq -6*8(%rsp), %rdx
+ leaq -1*8(%rsp), %rdx
movq %rdx, %rsp
- CFI_ADJUST_CFA_OFFSET 6*8
+ CFI_ADJUST_CFA_OFFSET 1*8
+ leaq -10*8(%rsp), %rdx
pushq_cfi $__KERNEL_DS
pushq_cfi %rdx
pushfq_cfi
@@ -1709,8 +1710,8 @@ nested_nmi:
pushq_cfi $repeat_nmi
/* Put stack back */
- addq $(11*8), %rsp
- CFI_ADJUST_CFA_OFFSET -11*8
+ addq $(6*8), %rsp
+ CFI_ADJUST_CFA_OFFSET -6*8
nested_nmi_out:
popq_cfi %rdx
@@ -1736,18 +1737,18 @@ first_nmi:
* +-------------------------+
* | NMI executing variable |
* +-------------------------+
- * | Saved SS |
- * | Saved Return RSP |
- * | Saved RFLAGS |
- * | Saved CS |
- * | Saved RIP |
- * +-------------------------+
* | copied SS |
* | copied Return RSP |
* | copied RFLAGS |
* | copied CS |
* | copied RIP |
* +-------------------------+
+ * | Saved SS |
+ * | Saved Return RSP |
+ * | Saved RFLAGS |
+ * | Saved CS |
+ * | Saved RIP |
+ * +-------------------------+
* | pt_regs |
* +-------------------------+
*
@@ -1763,9 +1764,14 @@ first_nmi:
/* Set the NMI executing variable on the stack. */
pushq_cfi $1
+ /*
+ * Leave room for the "copied" frame
+ */
+ subq $(5*8), %rsp
+
/* Copy the stack frame to the Saved frame */
.rept 5
- pushq_cfi 6*8(%rsp)
+ pushq_cfi 11*8(%rsp)
.endr
CFI_DEF_CFA_OFFSET SS+8-RIP
@@ -1786,12 +1792,15 @@ repeat_nmi:
* is benign for the non-repeat case, where 1 was pushed just above
* to this very stack slot).
*/
- movq $1, 5*8(%rsp)
+ movq $1, 10*8(%rsp)
/* Make another copy, this one may be modified by nested NMIs */
+ addq $(10*8), %rsp
+ CFI_ADJUST_CFA_OFFSET -10*8
.rept 5
- pushq_cfi 4*8(%rsp)
+ pushq_cfi -6*8(%rsp)
.endr
+ subq $(5*8), %rsp
CFI_DEF_CFA_OFFSET SS+8-RIP
end_repeat_nmi:
@@ -1842,8 +1851,12 @@ nmi_swapgs:
SWAPGS_UNSAFE_STACK
nmi_restore:
RESTORE_ALL 8
+
+ /* Pop the extra iret frame */
+ addq $(5*8), %rsp
+
/* Clear the NMI executing stack variable */
- movq $0, 10*8(%rsp)
+ movq $0, 5*8(%rsp)
jmp irq_return
CFI_ENDPROC
END(nmi)
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 957a47aec64..8e7f6556028 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -266,6 +266,19 @@ num_subarch_entries = (. - subarch_entries) / 4
jmp default_entry
#endif /* CONFIG_PARAVIRT */
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * Boot CPU0 entry point. It's called from play_dead(). Everything has been set
+ * up already except stack. We just set up stack here. Then call
+ * start_secondary().
+ */
+ENTRY(start_cpu0)
+ movl stack_start, %ecx
+ movl %ecx, %esp
+ jmp *(initial_code)
+ENDPROC(start_cpu0)
+#endif
+
/*
* Non-boot CPU entry point; entered from trampoline.S
* We can't lgdt here, because lgdt itself uses a data segment, but
@@ -292,8 +305,8 @@ default_entry:
* be using the global pages.
*
* NOTE! If we are on a 486 we may have no cr4 at all!
- * Specifically, cr4 exists if and only if CPUID exists,
- * which in turn exists if and only if EFLAGS.ID exists.
+ * Specifically, cr4 exists if and only if CPUID exists
+ * and has flags other than the FPU flag set.
*/
movl $X86_EFLAGS_ID,%ecx
pushl %ecx
@@ -308,6 +321,11 @@ default_entry:
testl %ecx,%eax
jz 6f # No ID flag = no CPUID = no CR4
+ movl $1,%eax
+ cpuid
+ andl $~1,%edx # Ignore CPUID.FPU
+ jz 6f # No flags or only CPUID.FPU = no CR4
+
movl pa(mmu_cr4_features),%eax
movl %eax,%cr4
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 94bf9cc2c7e..980053c4b9c 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -252,6 +252,22 @@ ENTRY(secondary_startup_64)
pushq %rax # target address in negative space
lretq
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * Boot CPU0 entry point. It's called from play_dead(). Everything has been set
+ * up already except stack. We just set up stack here. Then call
+ * start_secondary().
+ */
+ENTRY(start_cpu0)
+ movq stack_start(%rip),%rsp
+ movq initial_code(%rip),%rax
+ pushq $0 # fake return address to stop unwinder
+ pushq $__KERNEL_CS # set correct cs
+ pushq %rax # target address in negative space
+ lretq
+ENDPROC(start_cpu0)
+#endif
+
/* SMP bootup changes these two */
__REFDATA
.align 8
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 1460a5df92f..e28670f9a58 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -434,7 +434,7 @@ void hpet_msi_unmask(struct irq_data *data)
/* unmask it */
cfg = hpet_readl(HPET_Tn_CFG(hdev->num));
- cfg |= HPET_TN_FSB;
+ cfg |= HPET_TN_ENABLE | HPET_TN_FSB;
hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
}
@@ -445,7 +445,7 @@ void hpet_msi_mask(struct irq_data *data)
/* mask it */
cfg = hpet_readl(HPET_Tn_CFG(hdev->num));
- cfg &= ~HPET_TN_FSB;
+ cfg &= ~(HPET_TN_ENABLE | HPET_TN_FSB);
hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
}
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
index 675a0501244..245a71db401 100644
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
@@ -175,7 +175,11 @@ void __cpuinit fpu_init(void)
cr0 |= X86_CR0_EM;
write_cr0(cr0);
- if (!smp_processor_id())
+ /*
+ * init_thread_xstate is only called once to avoid overriding
+ * xstate_size during boot time or during CPU hotplug.
+ */
+ if (xstate_size == 0)
init_thread_xstate();
mxcsr_feature_mask_init();
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index 7720ff5a9ee..efdec7cd8e0 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -8,8 +8,8 @@
* Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
*
* Maintainers:
- * Andreas Herrmann <andreas.herrmann3@amd.com>
- * Borislav Petkov <borislav.petkov@amd.com>
+ * Andreas Herrmann <herrmann.der.user@googlemail.com>
+ * Borislav Petkov <bp@alien8.de>
*
* This driver allows to upgrade microcode on F10h AMD
* CPUs and later.
@@ -190,6 +190,7 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size,
#define F1XH_MPB_MAX_SIZE 2048
#define F14H_MPB_MAX_SIZE 1824
#define F15H_MPB_MAX_SIZE 4096
+#define F16H_MPB_MAX_SIZE 3458
switch (c->x86) {
case 0x14:
@@ -198,6 +199,9 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size,
case 0x15:
max_size = F15H_MPB_MAX_SIZE;
break;
+ case 0x16:
+ max_size = F16H_MPB_MAX_SIZE;
+ break;
default:
max_size = F1XH_MPB_MAX_SIZE;
break;
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index b644e1c765d..2f99e312187 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -306,11 +306,6 @@ void (*pm_idle)(void);
EXPORT_SYMBOL(pm_idle);
#endif
-static inline int hlt_use_halt(void)
-{
- return 1;
-}
-
#ifndef CONFIG_SMP
static inline void play_dead(void)
{
@@ -410,28 +405,22 @@ void cpu_idle(void)
*/
void default_idle(void)
{
- if (hlt_use_halt()) {
- trace_power_start_rcuidle(POWER_CSTATE, 1, smp_processor_id());
- trace_cpu_idle_rcuidle(1, smp_processor_id());
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we
- * test NEED_RESCHED:
- */
- smp_mb();
+ trace_power_start_rcuidle(POWER_CSTATE, 1, smp_processor_id());
+ trace_cpu_idle_rcuidle(1, smp_processor_id());
+ current_thread_info()->status &= ~TS_POLLING;
+ /*
+ * TS_POLLING-cleared state must be visible before we
+ * test NEED_RESCHED:
+ */
+ smp_mb();
- if (!need_resched())
- safe_halt(); /* enables interrupts racelessly */
- else
- local_irq_enable();
- current_thread_info()->status |= TS_POLLING;
- trace_power_end_rcuidle(smp_processor_id());
- trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
- } else {
+ if (!need_resched())
+ safe_halt(); /* enables interrupts racelessly */
+ else
local_irq_enable();
- /* loop is done by the caller */
- cpu_relax();
- }
+ current_thread_info()->status |= TS_POLLING;
+ trace_power_end_rcuidle(smp_processor_id());
+ trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
}
#ifdef CONFIG_APM_MODULE
EXPORT_SYMBOL(default_idle);
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index b00b33a1839..b629bbe0d9b 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -22,6 +22,8 @@
#include <linux/perf_event.h>
#include <linux/hw_breakpoint.h>
#include <linux/rcupdate.h>
+#include <linux/module.h>
+#include <linux/context_tracking.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -166,6 +168,35 @@ static inline bool invalid_selector(u16 value)
#define FLAG_MASK FLAG_MASK_32
+/*
+ * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode
+ * when it traps. The previous stack will be directly underneath the saved
+ * registers, and 'sp/ss' won't even have been saved. Thus the '&regs->sp'.
+ *
+ * Now, if the stack is empty, '&regs->sp' is out of range. In this
+ * case we try to take the previous stack. To always return a non-null
+ * stack pointer we fall back to regs as stack if no previous stack
+ * exists.
+ *
+ * This is valid only for kernel mode traps.
+ */
+unsigned long kernel_stack_pointer(struct pt_regs *regs)
+{
+ unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1);
+ unsigned long sp = (unsigned long)&regs->sp;
+ struct thread_info *tinfo;
+
+ if (context == (sp & ~(THREAD_SIZE - 1)))
+ return sp;
+
+ tinfo = (struct thread_info *)context;
+ if (tinfo->previous_esp)
+ return tinfo->previous_esp;
+
+ return (unsigned long)regs;
+}
+EXPORT_SYMBOL_GPL(kernel_stack_pointer);
+
static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno)
{
BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0);
@@ -1461,7 +1492,7 @@ long syscall_trace_enter(struct pt_regs *regs)
{
long ret = 0;
- rcu_user_exit();
+ user_exit();
/*
* If we stepped into a sysenter/syscall insn, it trapped in
@@ -1511,6 +1542,13 @@ void syscall_trace_leave(struct pt_regs *regs)
{
bool step;
+ /*
+ * We may come here right after calling schedule_user()
+ * or do_notify_resume(), in which case we can be in RCU
+ * user mode.
+ */
+ user_exit();
+
audit_syscall_exit(regs);
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
@@ -1527,5 +1565,5 @@ void syscall_trace_leave(struct pt_regs *regs)
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, step);
- rcu_user_enter();
+ user_enter();
}
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 4929c1be0ac..801602b5d74 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -195,12 +195,6 @@ void read_persistent_clock(struct timespec *ts)
ts->tv_nsec = 0;
}
-unsigned long long native_read_tsc(void)
-{
- return __native_read_tsc();
-}
-EXPORT_SYMBOL(native_read_tsc);
-
static struct resource rtc_resources[] = {
[0] = {
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 70b27ee6118..fbbb604313a 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -22,6 +22,7 @@
#include <linux/uaccess.h>
#include <linux/user-return-notifier.h>
#include <linux/uprobes.h>
+#include <linux/context_tracking.h>
#include <asm/processor.h>
#include <asm/ucontext.h>
@@ -816,7 +817,7 @@ static void do_signal(struct pt_regs *regs)
void
do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
{
- rcu_user_exit();
+ user_exit();
#ifdef CONFIG_X86_MCE
/* notify userspace of pending MCEs */
@@ -838,7 +839,7 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
if (thread_info_flags & _TIF_USER_RETURN_NOTIFY)
fire_user_return_notifiers();
- rcu_user_enter();
+ user_enter();
}
void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index c80a33bc528..ed0fe385289 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -68,6 +68,8 @@
#include <asm/mwait.h>
#include <asm/apic.h>
#include <asm/io_apic.h>
+#include <asm/i387.h>
+#include <asm/fpu-internal.h>
#include <asm/setup.h>
#include <asm/uv/uv.h>
#include <linux/mc146818rtc.h>
@@ -125,8 +127,8 @@ EXPORT_PER_CPU_SYMBOL(cpu_info);
atomic_t init_deasserted;
/*
- * Report back to the Boot Processor.
- * Running on AP.
+ * Report back to the Boot Processor during boot time or to the caller processor
+ * during CPU online.
*/
static void __cpuinit smp_callin(void)
{
@@ -138,15 +140,17 @@ static void __cpuinit smp_callin(void)
* we may get here before an INIT-deassert IPI reaches
* our local APIC. We have to wait for the IPI or we'll
* lock up on an APIC access.
+ *
+ * Since CPU0 is not wakened up by INIT, it doesn't wait for the IPI.
*/
- if (apic->wait_for_init_deassert)
+ cpuid = smp_processor_id();
+ if (apic->wait_for_init_deassert && cpuid != 0)
apic->wait_for_init_deassert(&init_deasserted);
/*
* (This works even if the APIC is not enabled.)
*/
phys_id = read_apic_id();
- cpuid = smp_processor_id();
if (cpumask_test_cpu(cpuid, cpu_callin_mask)) {
panic("%s: phys CPU#%d, CPU#%d already present??\n", __func__,
phys_id, cpuid);
@@ -228,6 +232,8 @@ static void __cpuinit smp_callin(void)
cpumask_set_cpu(cpuid, cpu_callin_mask);
}
+static int cpu0_logical_apicid;
+static int enable_start_cpu0;
/*
* Activate a secondary processor.
*/
@@ -243,6 +249,8 @@ notrace static void __cpuinit start_secondary(void *unused)
preempt_disable();
smp_callin();
+ enable_start_cpu0 = 0;
+
#ifdef CONFIG_X86_32
/* switch away from the initial page table */
load_cr3(swapper_pg_dir);
@@ -279,19 +287,30 @@ notrace static void __cpuinit start_secondary(void *unused)
cpu_idle();
}
+void __init smp_store_boot_cpu_info(void)
+{
+ int id = 0; /* CPU 0 */
+ struct cpuinfo_x86 *c = &cpu_data(id);
+
+ *c = boot_cpu_data;
+ c->cpu_index = id;
+}
+
/*
* The bootstrap kernel entry code has set these up. Save them for
* a given CPU
*/
-
void __cpuinit smp_store_cpu_info(int id)
{
struct cpuinfo_x86 *c = &cpu_data(id);
*c = boot_cpu_data;
c->cpu_index = id;
- if (id != 0)
- identify_secondary_cpu(c);
+ /*
+ * During boot time, CPU0 has this setup already. Save the info when
+ * bringing up AP or offlined CPU0.
+ */
+ identify_secondary_cpu(c);
}
static bool __cpuinit
@@ -313,7 +332,7 @@ do { \
static bool __cpuinit match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
{
- if (cpu_has(c, X86_FEATURE_TOPOEXT)) {
+ if (cpu_has_topoext) {
int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
if (c->phys_proc_id == o->phys_proc_id &&
@@ -481,7 +500,7 @@ void __inquire_remote_apic(int apicid)
* won't ... remember to clear down the APIC, etc later.
*/
int __cpuinit
-wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip)
+wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip)
{
unsigned long send_status, accept_status = 0;
int maxlvt;
@@ -489,7 +508,7 @@ wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip)
/* Target chip */
/* Boot on the stack */
/* Kick the second */
- apic_icr_write(APIC_DM_NMI | apic->dest_logical, logical_apicid);
+ apic_icr_write(APIC_DM_NMI | apic->dest_logical, apicid);
pr_debug("Waiting for send to finish...\n");
send_status = safe_apic_wait_icr_idle();
@@ -649,6 +668,63 @@ static void __cpuinit announce_cpu(int cpu, int apicid)
node, cpu, apicid);
}
+static int wakeup_cpu0_nmi(unsigned int cmd, struct pt_regs *regs)
+{
+ int cpu;
+
+ cpu = smp_processor_id();
+ if (cpu == 0 && !cpu_online(cpu) && enable_start_cpu0)
+ return NMI_HANDLED;
+
+ return NMI_DONE;
+}
+
+/*
+ * Wake up AP by INIT, INIT, STARTUP sequence.
+ *
+ * Instead of waiting for STARTUP after INITs, BSP will execute the BIOS
+ * boot-strap code which is not a desired behavior for waking up BSP. To
+ * void the boot-strap code, wake up CPU0 by NMI instead.
+ *
+ * This works to wake up soft offlined CPU0 only. If CPU0 is hard offlined
+ * (i.e. physically hot removed and then hot added), NMI won't wake it up.
+ * We'll change this code in the future to wake up hard offlined CPU0 if
+ * real platform and request are available.
+ */
+static int __cpuinit
+wakeup_cpu_via_init_nmi(int cpu, unsigned long start_ip, int apicid,
+ int *cpu0_nmi_registered)
+{
+ int id;
+ int boot_error;
+
+ /*
+ * Wake up AP by INIT, INIT, STARTUP sequence.
+ */
+ if (cpu)
+ return wakeup_secondary_cpu_via_init(apicid, start_ip);
+
+ /*
+ * Wake up BSP by nmi.
+ *
+ * Register a NMI handler to help wake up CPU0.
+ */
+ boot_error = register_nmi_handler(NMI_LOCAL,
+ wakeup_cpu0_nmi, 0, "wake_cpu0");
+
+ if (!boot_error) {
+ enable_start_cpu0 = 1;
+ *cpu0_nmi_registered = 1;
+ if (apic->dest_logical == APIC_DEST_LOGICAL)
+ id = cpu0_logical_apicid;
+ else
+ id = apicid;
+ boot_error = wakeup_secondary_cpu_via_nmi(id, start_ip);
+ }
+
+ return boot_error;
+}
+
/*
* NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
* (ie clustered apic addressing mode), this is a LOGICAL apic ID.
@@ -664,6 +740,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
unsigned long boot_error = 0;
int timeout;
+ int cpu0_nmi_registered = 0;
/* Just in case we booted with a single CPU. */
alternatives_enable_smp();
@@ -711,13 +788,16 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
}
/*
- * Kick the secondary CPU. Use the method in the APIC driver
- * if it's defined - or use an INIT boot APIC message otherwise:
+ * Wake up a CPU in difference cases:
+ * - Use the method in the APIC driver if it's defined
+ * Otherwise,
+ * - Use an INIT boot APIC message for APs or NMI for BSP.
*/
if (apic->wakeup_secondary_cpu)
boot_error = apic->wakeup_secondary_cpu(apicid, start_ip);
else
- boot_error = wakeup_secondary_cpu_via_init(apicid, start_ip);
+ boot_error = wakeup_cpu_via_init_nmi(cpu, start_ip, apicid,
+ &cpu0_nmi_registered);
if (!boot_error) {
/*
@@ -782,6 +862,13 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
*/
smpboot_restore_warm_reset_vector();
}
+ /*
+ * Clean up the nmi handler. Do this after the callin and callout sync
+ * to avoid impact of possible long unregister time.
+ */
+ if (cpu0_nmi_registered)
+ unregister_nmi_handler(NMI_LOCAL, "wake_cpu0");
+
return boot_error;
}
@@ -795,7 +882,7 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle)
pr_debug("++++++++++++++++++++=_---CPU UP %u\n", cpu);
- if (apicid == BAD_APICID || apicid == boot_cpu_physical_apicid ||
+ if (apicid == BAD_APICID ||
!physid_isset(apicid, phys_cpu_present_map) ||
!apic->apic_id_valid(apicid)) {
pr_err("%s: bad cpu %d\n", __func__, cpu);
@@ -818,6 +905,9 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle)
per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
+ /* the FPU context is blank, nobody can own it */
+ __cpu_disable_lazy_restore(cpu);
+
err = do_boot_cpu(apicid, cpu, tidle);
if (err) {
pr_debug("do_boot_cpu failed %d\n", err);
@@ -990,7 +1080,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
/*
* Setup boot CPU information
*/
- smp_store_cpu_info(0); /* Final full version of the data */
+ smp_store_boot_cpu_info(); /* Final full version of the data */
cpumask_copy(cpu_callin_mask, cpumask_of(0));
mb();
@@ -1026,6 +1116,11 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
*/
setup_local_APIC();
+ if (x2apic_mode)
+ cpu0_logical_apicid = apic_read(APIC_LDR);
+ else
+ cpu0_logical_apicid = GET_APIC_LOGICAL_ID(apic_read(APIC_LDR));
+
/*
* Enable IO APIC before setting up error vector
*/
@@ -1214,19 +1309,6 @@ void cpu_disable_common(void)
int native_cpu_disable(void)
{
- int cpu = smp_processor_id();
-
- /*
- * Perhaps use cpufreq to drop frequency, but that could go
- * into generic code.
- *
- * We won't take down the boot processor on i386 due to some
- * interrupts only being able to be serviced by the BSP.
- * Especially so if we're not using an IOAPIC -zwane
- */
- if (cpu == 0)
- return -EBUSY;
-
clear_local_APIC();
cpu_disable_common();
@@ -1266,6 +1348,14 @@ void play_dead_common(void)
local_irq_disable();
}
+static bool wakeup_cpu0(void)
+{
+ if (smp_processor_id() == 0 && enable_start_cpu0)
+ return true;
+
+ return false;
+}
+
/*
* We need to flush the caches before going to sleep, lest we have
* dirty data in our caches when we come back up.
@@ -1329,6 +1419,11 @@ static inline void mwait_play_dead(void)
__monitor(mwait_ptr, 0, 0);
mb();
__mwait(eax, 0);
+ /*
+ * If NMI wants to wake up CPU0, start CPU0.
+ */
+ if (wakeup_cpu0())
+ start_cpu0();
}
}
@@ -1339,6 +1434,11 @@ static inline void hlt_play_dead(void)
while (1) {
native_halt();
+ /*
+ * If NMI wants to wake up CPU0, start CPU0.
+ */
+ if (wakeup_cpu0())
+ start_cpu0();
}
}
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index b4d3c3927dd..97ef74b88e0 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -21,37 +21,23 @@
/*
* Align a virtual address to avoid aliasing in the I$ on AMD F15h.
- *
- * @flags denotes the allocation direction - bottomup or topdown -
- * or vDSO; see call sites below.
*/
-unsigned long align_addr(unsigned long addr, struct file *filp,
- enum align_flags flags)
+static unsigned long get_align_mask(void)
{
- unsigned long tmp_addr;
-
/* handle 32- and 64-bit case with a single conditional */
if (va_align.flags < 0 || !(va_align.flags & (2 - mmap_is_ia32())))
- return addr;
+ return 0;
if (!(current->flags & PF_RANDOMIZE))
- return addr;
-
- if (!((flags & ALIGN_VDSO) || filp))
- return addr;
-
- tmp_addr = addr;
-
- /*
- * We need an address which is <= than the original
- * one only when in topdown direction.
- */
- if (!(flags & ALIGN_TOPDOWN))
- tmp_addr += va_align.mask;
+ return 0;
- tmp_addr &= ~va_align.mask;
+ return va_align.mask;
+}
- return tmp_addr;
+unsigned long align_vdso_addr(unsigned long addr)
+{
+ unsigned long align_mask = get_align_mask();
+ return (addr + align_mask) & ~align_mask;
}
static int __init control_va_addr_alignment(char *str)
@@ -126,7 +112,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
- unsigned long start_addr;
+ struct vm_unmapped_area_info info;
unsigned long begin, end;
if (flags & MAP_FIXED)
@@ -144,50 +130,16 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
(!vma || addr + len <= vma->vm_start))
return addr;
}
- if (((flags & MAP_32BIT) || test_thread_flag(TIF_ADDR32))
- && len <= mm->cached_hole_size) {
- mm->cached_hole_size = 0;
- mm->free_area_cache = begin;
- }
- addr = mm->free_area_cache;
- if (addr < begin)
- addr = begin;
- start_addr = addr;
-
-full_search:
-
- addr = align_addr(addr, filp, 0);
-
- for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
- /* At this point: (!vma || addr < vma->vm_end). */
- if (end - len < addr) {
- /*
- * Start a new search - just in case we missed
- * some holes.
- */
- if (start_addr != begin) {
- start_addr = addr = begin;
- mm->cached_hole_size = 0;
- goto full_search;
- }
- return -ENOMEM;
- }
- if (!vma || addr + len <= vma->vm_start) {
- /*
- * Remember the place where we stopped the search:
- */
- mm->free_area_cache = addr + len;
- return addr;
- }
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
- addr = vma->vm_end;
- addr = align_addr(addr, filp, 0);
- }
+ info.flags = 0;
+ info.length = len;
+ info.low_limit = begin;
+ info.high_limit = end;
+ info.align_mask = filp ? get_align_mask() : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+ return vm_unmapped_area(&info);
}
-
unsigned long
arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
const unsigned long len, const unsigned long pgoff,
@@ -195,7 +147,8 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
{
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
- unsigned long addr = addr0, start_addr;
+ unsigned long addr = addr0;
+ struct vm_unmapped_area_info info;
/* requested length too big for entire address space */
if (len > TASK_SIZE)
@@ -217,51 +170,16 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
return addr;
}
- /* check if free_area_cache is useful for us */
- if (len <= mm->cached_hole_size) {
- mm->cached_hole_size = 0;
- mm->free_area_cache = mm->mmap_base;
- }
-
-try_again:
- /* either no address requested or can't fit in requested address hole */
- start_addr = addr = mm->free_area_cache;
-
- if (addr < len)
- goto fail;
-
- addr -= len;
- do {
- addr = align_addr(addr, filp, ALIGN_TOPDOWN);
-
- /*
- * Lookup failure means no vma is above this address,
- * else if new region fits below vma->vm_start,
- * return with success:
- */
- vma = find_vma(mm, addr);
- if (!vma || addr+len <= vma->vm_start)
- /* remember the address as a hint for next time */
- return mm->free_area_cache = addr;
-
- /* remember the largest hole we saw so far */
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
-
- /* try just below the current vma->vm_start */
- addr = vma->vm_start-len;
- } while (len < vma->vm_start);
-
-fail:
- /*
- * if hint left us with no space for the requested
- * mapping then try again:
- */
- if (start_addr != mm->mmap_base) {
- mm->free_area_cache = mm->mmap_base;
- mm->cached_hole_size = 0;
- goto try_again;
- }
+ info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+ info.length = len;
+ info.low_limit = PAGE_SIZE;
+ info.high_limit = mm->mmap_base;
+ info.align_mask = filp ? get_align_mask() : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+ addr = vm_unmapped_area(&info);
+ if (!(addr & ~PAGE_MASK))
+ return addr;
+ VM_BUG_ON(addr != -ENOMEM);
bottomup:
/*
@@ -270,14 +188,5 @@ bottomup:
* can happen with large stack limits and large mmap()
* allocations.
*/
- mm->cached_hole_size = ~0UL;
- mm->free_area_cache = TASK_UNMAPPED_BASE;
- addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
- /*
- * Restore the topdown base:
- */
- mm->free_area_cache = mm->mmap_base;
- mm->cached_hole_size = ~0UL;
-
- return addr;
+ return arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
}
diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
index 76ee97709a0..6e60b5fe224 100644
--- a/arch/x86/kernel/topology.c
+++ b/arch/x86/kernel/topology.c
@@ -30,23 +30,110 @@
#include <linux/mmzone.h>
#include <linux/init.h>
#include <linux/smp.h>
+#include <linux/irq.h>
#include <asm/cpu.h>
static DEFINE_PER_CPU(struct x86_cpu, cpu_devices);
#ifdef CONFIG_HOTPLUG_CPU
+
+#ifdef CONFIG_BOOTPARAM_HOTPLUG_CPU0
+static int cpu0_hotpluggable = 1;
+#else
+static int cpu0_hotpluggable;
+static int __init enable_cpu0_hotplug(char *str)
+{
+ cpu0_hotpluggable = 1;
+ return 1;
+}
+
+__setup("cpu0_hotplug", enable_cpu0_hotplug);
+#endif
+
+#ifdef CONFIG_DEBUG_HOTPLUG_CPU0
+/*
+ * This function offlines a CPU as early as possible and allows userspace to
+ * boot up without the CPU. The CPU can be onlined back by user after boot.
+ *
+ * This is only called for debugging CPU offline/online feature.
+ */
+int __ref _debug_hotplug_cpu(int cpu, int action)
+{
+ struct device *dev = get_cpu_device(cpu);
+ int ret;
+
+ if (!cpu_is_hotpluggable(cpu))
+ return -EINVAL;
+
+ cpu_hotplug_driver_lock();
+
+ switch (action) {
+ case 0:
+ ret = cpu_down(cpu);
+ if (!ret) {
+ pr_info("CPU %u is now offline\n", cpu);
+ kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
+ } else
+ pr_debug("Can't offline CPU%d.\n", cpu);
+ break;
+ case 1:
+ ret = cpu_up(cpu);
+ if (!ret)
+ kobject_uevent(&dev->kobj, KOBJ_ONLINE);
+ else
+ pr_debug("Can't online CPU%d.\n", cpu);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ cpu_hotplug_driver_unlock();
+
+ return ret;
+}
+
+static int __init debug_hotplug_cpu(void)
+{
+ _debug_hotplug_cpu(0, 0);
+ return 0;
+}
+
+late_initcall_sync(debug_hotplug_cpu);
+#endif /* CONFIG_DEBUG_HOTPLUG_CPU0 */
+
int __ref arch_register_cpu(int num)
{
+ struct cpuinfo_x86 *c = &cpu_data(num);
+
+ /*
+ * Currently CPU0 is only hotpluggable on Intel platforms. Other
+ * vendors can add hotplug support later.
+ */
+ if (c->x86_vendor != X86_VENDOR_INTEL)
+ cpu0_hotpluggable = 0;
+
/*
- * CPU0 cannot be offlined due to several
- * restrictions and assumptions in kernel. This basically
- * doesn't add a control file, one cannot attempt to offline
- * BSP.
+ * Two known BSP/CPU0 dependencies: Resume from suspend/hibernate
+ * depends on BSP. PIC interrupts depend on BSP.
*
- * Also certain PCI quirks require not to enable hotplug control
- * for all CPU's.
+ * If the BSP depencies are under control, one can tell kernel to
+ * enable BSP hotplug. This basically adds a control file and
+ * one can attempt to offline BSP.
*/
- if (num)
+ if (num == 0 && cpu0_hotpluggable) {
+ unsigned int irq;
+ /*
+ * We won't take down the boot processor on i386 if some
+ * interrupts only are able to be serviced by the BSP in PIC.
+ */
+ for_each_active_irq(irq) {
+ if (!IO_APIC_IRQ(irq) && irq_has_action(irq)) {
+ cpu0_hotpluggable = 0;
+ break;
+ }
+ }
+ }
+ if (num || cpu0_hotpluggable)
per_cpu(cpu_devices, num).cpu.hotpluggable = 1;
return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
diff --git a/arch/x86/kernel/trace_clock.c b/arch/x86/kernel/trace_clock.c
new file mode 100644
index 00000000000..25b993729f9
--- /dev/null
+++ b/arch/x86/kernel/trace_clock.c
@@ -0,0 +1,21 @@
+/*
+ * X86 trace clocks
+ */
+#include <asm/trace_clock.h>
+#include <asm/barrier.h>
+#include <asm/msr.h>
+
+/*
+ * trace_clock_x86_tsc(): A clock that is just the cycle counter.
+ *
+ * Unlike the other clocks, this is not in nanoseconds.
+ */
+u64 notrace trace_clock_x86_tsc(void)
+{
+ u64 ret;
+
+ rdtsc_barrier();
+ rdtscll(ret);
+
+ return ret;
+}
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 8276dc6794c..eb8586693e0 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -55,7 +55,7 @@
#include <asm/i387.h>
#include <asm/fpu-internal.h>
#include <asm/mce.h>
-#include <asm/rcu.h>
+#include <asm/context_tracking.h>
#include <asm/mach_traps.h>
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index cfa5d4f7ca5..06ccb5073a3 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -77,6 +77,12 @@ unsigned long long
sched_clock(void) __attribute__((alias("native_sched_clock")));
#endif
+unsigned long long native_read_tsc(void)
+{
+ return __native_read_tsc();
+}
+EXPORT_SYMBOL(native_read_tsc);
+
int check_tsc_unstable(void)
{
return tsc_unstable;
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index aafa5557b39..c71025b6746 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -478,6 +478,11 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
regs->ip = current->utask->xol_vaddr;
pre_xol_rip_insn(auprobe, regs, autask);
+ autask->saved_tf = !!(regs->flags & X86_EFLAGS_TF);
+ regs->flags |= X86_EFLAGS_TF;
+ if (test_tsk_thread_flag(current, TIF_BLOCKSTEP))
+ set_task_blockstep(current, false);
+
return 0;
}
@@ -603,6 +608,16 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
if (auprobe->fixups & UPROBE_FIX_CALL)
result = adjust_ret_addr(regs->sp, correction);
+ /*
+ * arch_uprobe_pre_xol() doesn't save the state of TIF_BLOCKSTEP
+ * so we can get an extra SIGTRAP if we do not clear TF. We need
+ * to examine the opcode to make it right.
+ */
+ if (utask->autask.saved_tf)
+ send_sig(SIGTRAP, current, 0);
+ else if (!(auprobe->fixups & UPROBE_FIX_SETF))
+ regs->flags &= ~X86_EFLAGS_TF;
+
return result;
}
@@ -647,6 +662,10 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
current->thread.trap_nr = utask->autask.saved_trap_nr;
handle_riprel_post_xol(auprobe, regs, NULL);
instruction_pointer_set(regs, utask->vaddr);
+
+ /* clear TF if it was set by us in arch_uprobe_pre_xol() */
+ if (!utask->autask.saved_tf)
+ regs->flags &= ~X86_EFLAGS_TF;
}
/*
@@ -676,38 +695,3 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
send_sig(SIGTRAP, current, 0);
return ret;
}
-
-void arch_uprobe_enable_step(struct arch_uprobe *auprobe)
-{
- struct task_struct *task = current;
- struct arch_uprobe_task *autask = &task->utask->autask;
- struct pt_regs *regs = task_pt_regs(task);
-
- autask->saved_tf = !!(regs->flags & X86_EFLAGS_TF);
-
- regs->flags |= X86_EFLAGS_TF;
- if (test_tsk_thread_flag(task, TIF_BLOCKSTEP))
- set_task_blockstep(task, false);
-}
-
-void arch_uprobe_disable_step(struct arch_uprobe *auprobe)
-{
- struct task_struct *task = current;
- struct arch_uprobe_task *autask = &task->utask->autask;
- bool trapped = (task->utask->state == UTASK_SSTEP_TRAPPED);
- struct pt_regs *regs = task_pt_regs(task);
- /*
- * The state of TIF_BLOCKSTEP was not saved so we can get an extra
- * SIGTRAP if we do not clear TF. We need to examine the opcode to
- * make it right.
- */
- if (unlikely(trapped)) {
- if (!autask->saved_tf)
- regs->flags &= ~X86_EFLAGS_TF;
- } else {
- if (autask->saved_tf)
- send_sig(SIGTRAP, task, 0);
- else if (!(auprobe->fixups & UPROBE_FIX_SETF))
- regs->flags &= ~X86_EFLAGS_TF;
- }
-}
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index a10e4601685..58fc5148882 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -24,6 +24,9 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu)
{
struct kvm_cpuid_entry2 *best;
+ if (!static_cpu_has(X86_FEATURE_XSAVE))
+ return 0;
+
best = kvm_find_cpuid_entry(vcpu, 1, 0);
return best && (best->ecx & bit(X86_FEATURE_XSAVE));
}
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 39171cb307e..bba39bfa1c4 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -426,8 +426,7 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt)
_ASM_EXTABLE(1b, 3b) \
: "=m" ((ctxt)->eflags), "=&r" (_tmp), \
"+a" (*rax), "+d" (*rdx), "+qm"(_ex) \
- : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val), \
- "a" (*rax), "d" (*rdx)); \
+ : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val)); \
} while (0)
/* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ad6b1dd06f8..f85815945fc 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -6549,19 +6549,22 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
}
}
- exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
/* Exposing INVPCID only when PCID is exposed */
best = kvm_find_cpuid_entry(vcpu, 0x7, 0);
if (vmx_invpcid_supported() &&
best && (best->ebx & bit(X86_FEATURE_INVPCID)) &&
guest_cpuid_has_pcid(vcpu)) {
+ exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
exec_control |= SECONDARY_EXEC_ENABLE_INVPCID;
vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
exec_control);
} else {
- exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID;
- vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
- exec_control);
+ if (cpu_has_secondary_exec_ctrls()) {
+ exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
+ exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID;
+ vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
+ exec_control);
+ }
if (best)
best->ebx &= ~bit(X86_FEATURE_INVPCID);
}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 224a7e78cb6..4f7641756be 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5781,6 +5781,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
int pending_vec, max_bits, idx;
struct desc_ptr dt;
+ if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE))
+ return -EINVAL;
+
dt.size = sregs->idt.limit;
dt.address = sregs->idt.base;
kvm_x86_ops->set_idt(vcpu, &dt);
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index b00f6785da7..96b2c6697c9 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -32,7 +32,6 @@ ifeq ($(CONFIG_X86_32),y)
lib-y += checksum_32.o
lib-y += strstr_32.o
lib-y += string_32.o
- lib-y += cmpxchg.o
ifneq ($(CONFIG_X86_CMPXCHG64),y)
lib-y += cmpxchg8b_emu.o atomic64_386_32.o
endif
diff --git a/arch/x86/lib/cmpxchg.c b/arch/x86/lib/cmpxchg.c
deleted file mode 100644
index 5d619f6df3e..00000000000
--- a/arch/x86/lib/cmpxchg.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * cmpxchg*() fallbacks for CPU not supporting these instructions
- */
-
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/module.h>
-
-#ifndef CONFIG_X86_CMPXCHG
-unsigned long cmpxchg_386_u8(volatile void *ptr, u8 old, u8 new)
-{
- u8 prev;
- unsigned long flags;
-
- /* Poor man's cmpxchg for 386. Unsuitable for SMP */
- local_irq_save(flags);
- prev = *(u8 *)ptr;
- if (prev == old)
- *(u8 *)ptr = new;
- local_irq_restore(flags);
- return prev;
-}
-EXPORT_SYMBOL(cmpxchg_386_u8);
-
-unsigned long cmpxchg_386_u16(volatile void *ptr, u16 old, u16 new)
-{
- u16 prev;
- unsigned long flags;
-
- /* Poor man's cmpxchg for 386. Unsuitable for SMP */
- local_irq_save(flags);
- prev = *(u16 *)ptr;
- if (prev == old)
- *(u16 *)ptr = new;
- local_irq_restore(flags);
- return prev;
-}
-EXPORT_SYMBOL(cmpxchg_386_u16);
-
-unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new)
-{
- u32 prev;
- unsigned long flags;
-
- /* Poor man's cmpxchg for 386. Unsuitable for SMP */
- local_irq_save(flags);
- prev = *(u32 *)ptr;
- if (prev == old)
- *(u32 *)ptr = new;
- local_irq_restore(flags);
- return prev;
-}
-EXPORT_SYMBOL(cmpxchg_386_u32);
-#endif
diff --git a/arch/x86/lib/copy_page_64.S b/arch/x86/lib/copy_page_64.S
index 6b34d04d096..176cca67212 100644
--- a/arch/x86/lib/copy_page_64.S
+++ b/arch/x86/lib/copy_page_64.S
@@ -5,91 +5,89 @@
#include <asm/alternative-asm.h>
ALIGN
-copy_page_c:
+copy_page_rep:
CFI_STARTPROC
- movl $4096/8,%ecx
- rep movsq
+ movl $4096/8, %ecx
+ rep movsq
ret
CFI_ENDPROC
-ENDPROC(copy_page_c)
+ENDPROC(copy_page_rep)
-/* Don't use streaming store because it's better when the target
- ends up in cache. */
-
-/* Could vary the prefetch distance based on SMP/UP */
+/*
+ * Don't use streaming copy unless the CPU indicates X86_FEATURE_REP_GOOD.
+ * Could vary the prefetch distance based on SMP/UP.
+*/
ENTRY(copy_page)
CFI_STARTPROC
- subq $2*8,%rsp
+ subq $2*8, %rsp
CFI_ADJUST_CFA_OFFSET 2*8
- movq %rbx,(%rsp)
+ movq %rbx, (%rsp)
CFI_REL_OFFSET rbx, 0
- movq %r12,1*8(%rsp)
+ movq %r12, 1*8(%rsp)
CFI_REL_OFFSET r12, 1*8
- movl $(4096/64)-5,%ecx
+ movl $(4096/64)-5, %ecx
.p2align 4
.Loop64:
- dec %rcx
-
- movq (%rsi), %rax
- movq 8 (%rsi), %rbx
- movq 16 (%rsi), %rdx
- movq 24 (%rsi), %r8
- movq 32 (%rsi), %r9
- movq 40 (%rsi), %r10
- movq 48 (%rsi), %r11
- movq 56 (%rsi), %r12
+ dec %rcx
+ movq 0x8*0(%rsi), %rax
+ movq 0x8*1(%rsi), %rbx
+ movq 0x8*2(%rsi), %rdx
+ movq 0x8*3(%rsi), %r8
+ movq 0x8*4(%rsi), %r9
+ movq 0x8*5(%rsi), %r10
+ movq 0x8*6(%rsi), %r11
+ movq 0x8*7(%rsi), %r12
prefetcht0 5*64(%rsi)
- movq %rax, (%rdi)
- movq %rbx, 8 (%rdi)
- movq %rdx, 16 (%rdi)
- movq %r8, 24 (%rdi)
- movq %r9, 32 (%rdi)
- movq %r10, 40 (%rdi)
- movq %r11, 48 (%rdi)
- movq %r12, 56 (%rdi)
+ movq %rax, 0x8*0(%rdi)
+ movq %rbx, 0x8*1(%rdi)
+ movq %rdx, 0x8*2(%rdi)
+ movq %r8, 0x8*3(%rdi)
+ movq %r9, 0x8*4(%rdi)
+ movq %r10, 0x8*5(%rdi)
+ movq %r11, 0x8*6(%rdi)
+ movq %r12, 0x8*7(%rdi)
- leaq 64 (%rsi), %rsi
- leaq 64 (%rdi), %rdi
+ leaq 64 (%rsi), %rsi
+ leaq 64 (%rdi), %rdi
- jnz .Loop64
+ jnz .Loop64
- movl $5,%ecx
+ movl $5, %ecx
.p2align 4
.Loop2:
- decl %ecx
-
- movq (%rsi), %rax
- movq 8 (%rsi), %rbx
- movq 16 (%rsi), %rdx
- movq 24 (%rsi), %r8
- movq 32 (%rsi), %r9
- movq 40 (%rsi), %r10
- movq 48 (%rsi), %r11
- movq 56 (%rsi), %r12
-
- movq %rax, (%rdi)
- movq %rbx, 8 (%rdi)
- movq %rdx, 16 (%rdi)
- movq %r8, 24 (%rdi)
- movq %r9, 32 (%rdi)
- movq %r10, 40 (%rdi)
- movq %r11, 48 (%rdi)
- movq %r12, 56 (%rdi)
-
- leaq 64(%rdi),%rdi
- leaq 64(%rsi),%rsi
-
+ decl %ecx
+
+ movq 0x8*0(%rsi), %rax
+ movq 0x8*1(%rsi), %rbx
+ movq 0x8*2(%rsi), %rdx
+ movq 0x8*3(%rsi), %r8
+ movq 0x8*4(%rsi), %r9
+ movq 0x8*5(%rsi), %r10
+ movq 0x8*6(%rsi), %r11
+ movq 0x8*7(%rsi), %r12
+
+ movq %rax, 0x8*0(%rdi)
+ movq %rbx, 0x8*1(%rdi)
+ movq %rdx, 0x8*2(%rdi)
+ movq %r8, 0x8*3(%rdi)
+ movq %r9, 0x8*4(%rdi)
+ movq %r10, 0x8*5(%rdi)
+ movq %r11, 0x8*6(%rdi)
+ movq %r12, 0x8*7(%rdi)
+
+ leaq 64(%rdi), %rdi
+ leaq 64(%rsi), %rsi
jnz .Loop2
- movq (%rsp),%rbx
+ movq (%rsp), %rbx
CFI_RESTORE rbx
- movq 1*8(%rsp),%r12
+ movq 1*8(%rsp), %r12
CFI_RESTORE r12
- addq $2*8,%rsp
+ addq $2*8, %rsp
CFI_ADJUST_CFA_OFFSET -2*8
ret
.Lcopy_page_end:
@@ -103,7 +101,7 @@ ENDPROC(copy_page)
.section .altinstr_replacement,"ax"
1: .byte 0xeb /* jmp <disp8> */
- .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
+ .byte (copy_page_rep - copy_page) - (2f - 1b) /* offset */
2:
.previous
.section .altinstructions,"a"
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
index 98f6d6b68f5..f0312d74640 100644
--- a/arch/x86/lib/usercopy_32.c
+++ b/arch/x86/lib/usercopy_32.c
@@ -570,63 +570,6 @@ do { \
unsigned long __copy_to_user_ll(void __user *to, const void *from,
unsigned long n)
{
-#ifndef CONFIG_X86_WP_WORKS_OK
- if (unlikely(boot_cpu_data.wp_works_ok == 0) &&
- ((unsigned long)to) < TASK_SIZE) {
- /*
- * When we are in an atomic section (see
- * mm/filemap.c:file_read_actor), return the full
- * length to take the slow path.
- */
- if (in_atomic())
- return n;
-
- /*
- * CPU does not honor the WP bit when writing
- * from supervisory mode, and due to preemption or SMP,
- * the page tables can change at any time.
- * Do it manually. Manfred <manfred@colorfullife.com>
- */
- while (n) {
- unsigned long offset = ((unsigned long)to)%PAGE_SIZE;
- unsigned long len = PAGE_SIZE - offset;
- int retval;
- struct page *pg;
- void *maddr;
-
- if (len > n)
- len = n;
-
-survive:
- down_read(&current->mm->mmap_sem);
- retval = get_user_pages(current, current->mm,
- (unsigned long)to, 1, 1, 0, &pg, NULL);
-
- if (retval == -ENOMEM && is_global_init(current)) {
- up_read(&current->mm->mmap_sem);
- congestion_wait(BLK_RW_ASYNC, HZ/50);
- goto survive;
- }
-
- if (retval != 1) {
- up_read(&current->mm->mmap_sem);
- break;
- }
-
- maddr = kmap_atomic(pg);
- memcpy(maddr + offset, from, len);
- kunmap_atomic(maddr);
- set_page_dirty_lock(pg);
- put_page(pg);
- up_read(&current->mm->mmap_sem);
-
- from += len;
- to += len;
- n -= len;
- }
- return n;
- }
-#endif
stac();
if (movsl_is_ok(to, from, n))
__copy_user(to, from, n);
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 8e13ecb41be..7a529cbab7a 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -18,7 +18,7 @@
#include <asm/pgalloc.h> /* pgd_*(), ... */
#include <asm/kmemcheck.h> /* kmemcheck_*(), ... */
#include <asm/fixmap.h> /* VSYSCALL_START */
-#include <asm/rcu.h> /* exception_enter(), ... */
+#include <asm/context_tracking.h> /* exception_enter(), ... */
/*
* Page fault error code bits:
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index 937bff5cdaa..ae1aa71d011 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -274,42 +274,15 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
unsigned long pgoff, unsigned long flags)
{
struct hstate *h = hstate_file(file);
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
- unsigned long start_addr;
-
- if (len > mm->cached_hole_size) {
- start_addr = mm->free_area_cache;
- } else {
- start_addr = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = 0;
- }
-
-full_search:
- addr = ALIGN(start_addr, huge_page_size(h));
-
- for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
- /* At this point: (!vma || addr < vma->vm_end). */
- if (TASK_SIZE - len < addr) {
- /*
- * Start a new search - just in case we missed
- * some holes.
- */
- if (start_addr != TASK_UNMAPPED_BASE) {
- start_addr = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = 0;
- goto full_search;
- }
- return -ENOMEM;
- }
- if (!vma || addr + len <= vma->vm_start) {
- mm->free_area_cache = addr + len;
- return addr;
- }
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
- addr = ALIGN(vma->vm_end, huge_page_size(h));
- }
+ struct vm_unmapped_area_info info;
+
+ info.flags = 0;
+ info.length = len;
+ info.low_limit = TASK_UNMAPPED_BASE;
+ info.high_limit = TASK_SIZE;
+ info.align_mask = PAGE_MASK & ~huge_page_mask(h);
+ info.align_offset = 0;
+ return vm_unmapped_area(&info);
}
static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
@@ -317,83 +290,30 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
unsigned long pgoff, unsigned long flags)
{
struct hstate *h = hstate_file(file);
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
- unsigned long base = mm->mmap_base;
- unsigned long addr = addr0;
- unsigned long largest_hole = mm->cached_hole_size;
- unsigned long start_addr;
-
- /* don't allow allocations above current base */
- if (mm->free_area_cache > base)
- mm->free_area_cache = base;
-
- if (len <= largest_hole) {
- largest_hole = 0;
- mm->free_area_cache = base;
- }
-try_again:
- start_addr = mm->free_area_cache;
-
- /* make sure it can fit in the remaining address space */
- if (mm->free_area_cache < len)
- goto fail;
-
- /* either no address requested or can't fit in requested address hole */
- addr = (mm->free_area_cache - len) & huge_page_mask(h);
- do {
- /*
- * Lookup failure means no vma is above this address,
- * i.e. return with success:
- */
- vma = find_vma(mm, addr);
- if (!vma)
- return addr;
+ struct vm_unmapped_area_info info;
+ unsigned long addr;
- if (addr + len <= vma->vm_start) {
- /* remember the address as a hint for next time */
- mm->cached_hole_size = largest_hole;
- return (mm->free_area_cache = addr);
- } else if (mm->free_area_cache == vma->vm_end) {
- /* pull free_area_cache down to the first hole */
- mm->free_area_cache = vma->vm_start;
- mm->cached_hole_size = largest_hole;
- }
+ info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+ info.length = len;
+ info.low_limit = PAGE_SIZE;
+ info.high_limit = current->mm->mmap_base;
+ info.align_mask = PAGE_MASK & ~huge_page_mask(h);
+ info.align_offset = 0;
+ addr = vm_unmapped_area(&info);
- /* remember the largest hole we saw so far */
- if (addr + largest_hole < vma->vm_start)
- largest_hole = vma->vm_start - addr;
-
- /* try just below the current vma->vm_start */
- addr = (vma->vm_start - len) & huge_page_mask(h);
- } while (len <= vma->vm_start);
-
-fail:
- /*
- * if hint left us with no space for the requested
- * mapping then try again:
- */
- if (start_addr != base) {
- mm->free_area_cache = base;
- largest_hole = 0;
- goto try_again;
- }
/*
* A failed mmap() very likely causes application failure,
* so fall back to the bottom-up function here. This scenario
* can happen with large stack limits and large mmap()
* allocations.
*/
- mm->free_area_cache = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = ~0UL;
- addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
- len, pgoff, flags);
-
- /*
- * Restore the topdown base:
- */
- mm->free_area_cache = base;
- mm->cached_hole_size = ~0UL;
+ if (addr & ~PAGE_MASK) {
+ VM_BUG_ON(addr != -ENOMEM);
+ info.flags = 0;
+ info.low_limit = TASK_UNMAPPED_BASE;
+ info.high_limit = TASK_SIZE;
+ addr = vm_unmapped_area(&info);
+ }
return addr;
}
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 11a58001b4c..745d66b843c 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -715,10 +715,7 @@ static void __init test_wp_bit(void)
if (!boot_cpu_data.wp_works_ok) {
printk(KERN_CONT "No.\n");
-#ifdef CONFIG_X86_WP_WORKS_OK
- panic(
- "This kernel doesn't support CPU's with broken WP. Recompile it for a 386!");
-#endif
+ panic("Linux doesn't support CPUs with broken WP.");
} else {
printk(KERN_CONT "Ok.\n");
}
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 0777f042e40..13a6b29e2e5 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -104,7 +104,7 @@ static void flush_tlb_func(void *info)
return;
if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) {
- if (f->flush_end == TLB_FLUSH_ALL || !cpu_has_invlpg)
+ if (f->flush_end == TLB_FLUSH_ALL)
local_flush_tlb();
else if (!f->flush_end)
__flush_tlb_single(f->flush_start);
@@ -197,7 +197,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
}
if (end == TLB_FLUSH_ALL || tlb_flushall_shift == -1
- || vmflag == VM_HUGETLB) {
+ || vmflag & VM_HUGETLB) {
local_flush_tlb();
goto flush_all;
}
@@ -337,10 +337,8 @@ static const struct file_operations fops_tlbflush = {
static int __cpuinit create_tlb_flushall_shift(void)
{
- if (cpu_has_invlpg) {
- debugfs_create_file("tlb_flushall_shift", S_IRUSR | S_IWUSR,
- arch_debugfs_dir, NULL, &fops_tlbflush);
- }
+ debugfs_create_file("tlb_flushall_shift", S_IRUSR | S_IWUSR,
+ arch_debugfs_dir, NULL, &fops_tlbflush);
return 0;
}
late_initcall(create_tlb_flushall_shift);
diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c
index 41bd2a2d2c5..b914e20b5a0 100644
--- a/arch/x86/pci/ce4100.c
+++ b/arch/x86/pci/ce4100.c
@@ -115,6 +115,16 @@ static void sata_revid_read(struct sim_dev_reg *reg, u32 *value)
reg_read(reg, value);
}
+static void reg_noirq_read(struct sim_dev_reg *reg, u32 *value)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pci_config_lock, flags);
+ /* force interrupt pin value to 0 */
+ *value = reg->sim_reg.value & 0xfff00ff;
+ raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+}
+
static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write)
DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write)
@@ -144,6 +154,7 @@ static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write)
DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write)
DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write)
+ DEFINE_REG(11, 7, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write)
DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write)
@@ -161,8 +172,10 @@ static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write)
DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write)
DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write)
+ DEFINE_REG(16, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write)
+ DEFINE_REG(18, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
};
static void __init init_sim_regs(void)
diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index 4c61b52191e..f8ab4945892 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -21,12 +21,25 @@
#include <asm/i8259.h>
#include <asm/io.h>
#include <asm/io_apic.h>
+#include <asm/emergency-restart.h>
static int ce4100_i8042_detect(void)
{
return 0;
}
+/*
+ * The CE4100 platform has an internal 8051 Microcontroller which is
+ * responsible for signaling to the external Power Management Unit the
+ * intention to reset, reboot or power off the system. This 8051 device has
+ * its command register mapped at I/O port 0xcf9 and the value 0x4 is used
+ * to power off the system.
+ */
+static void ce4100_power_off(void)
+{
+ outb(0x4, 0xcf9);
+}
+
#ifdef CONFIG_SERIAL_8250
static unsigned int mem_serial_in(struct uart_port *p, int offset)
@@ -92,8 +105,11 @@ static void ce4100_serial_fixup(int port, struct uart_port *up,
up->membase =
(void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
up->membase += up->mapbase & ~PAGE_MASK;
+ up->mapbase += port * 0x100;
+ up->membase += port * 0x100;
up->iotype = UPIO_MEM32;
up->regshift = 2;
+ up->irq = 4;
}
#endif
up->iobase = 0;
@@ -139,8 +155,19 @@ void __init x86_ce4100_early_setup(void)
x86_init.mpparse.find_smp_config = x86_init_noop;
x86_init.pci.init = ce4100_pci_init;
+ /*
+ * By default, the reboot method is ACPI which is supported by the
+ * CE4100 bootloader CEFDK using FADT.ResetReg Address and ResetValue
+ * the bootloader will however issue a system power off instead of
+ * reboot. By using BOOT_KBD we ensure proper system reboot as
+ * expected.
+ */
+ reboot_type = BOOT_KBD;
+
#ifdef CONFIG_X86_IO_APIC
x86_init.pci.init_irq = sdv_pci_init;
x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;
#endif
+
+ pm_power_off = ce4100_power_off;
}
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 218cdb16163..120cee1c3f8 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -21,6 +21,7 @@
#include <asm/suspend.h>
#include <asm/debugreg.h>
#include <asm/fpu-internal.h> /* pcntxt_mask */
+#include <asm/cpu.h>
#ifdef CONFIG_X86_32
static struct saved_context saved_context;
@@ -237,3 +238,84 @@ void restore_processor_state(void)
#ifdef CONFIG_X86_32
EXPORT_SYMBOL(restore_processor_state);
#endif
+
+/*
+ * When bsp_check() is called in hibernate and suspend, cpu hotplug
+ * is disabled already. So it's unnessary to handle race condition between
+ * cpumask query and cpu hotplug.
+ */
+static int bsp_check(void)
+{
+ if (cpumask_first(cpu_online_mask) != 0) {
+ pr_warn("CPU0 is offline.\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int bsp_pm_callback(struct notifier_block *nb, unsigned long action,
+ void *ptr)
+{
+ int ret = 0;
+
+ switch (action) {
+ case PM_SUSPEND_PREPARE:
+ case PM_HIBERNATION_PREPARE:
+ ret = bsp_check();
+ break;
+#ifdef CONFIG_DEBUG_HOTPLUG_CPU0
+ case PM_RESTORE_PREPARE:
+ /*
+ * When system resumes from hibernation, online CPU0 because
+ * 1. it's required for resume and
+ * 2. the CPU was online before hibernation
+ */
+ if (!cpu_online(0))
+ _debug_hotplug_cpu(0, 1);
+ break;
+ case PM_POST_RESTORE:
+ /*
+ * When a resume really happens, this code won't be called.
+ *
+ * This code is called only when user space hibernation software
+ * prepares for snapshot device during boot time. So we just
+ * call _debug_hotplug_cpu() to restore to CPU0's state prior to
+ * preparing the snapshot device.
+ *
+ * This works for normal boot case in our CPU0 hotplug debug
+ * mode, i.e. CPU0 is offline and user mode hibernation
+ * software initializes during boot time.
+ *
+ * If CPU0 is online and user application accesses snapshot
+ * device after boot time, this will offline CPU0 and user may
+ * see different CPU0 state before and after accessing
+ * the snapshot device. But hopefully this is not a case when
+ * user debugging CPU0 hotplug. Even if users hit this case,
+ * they can easily online CPU0 back.
+ *
+ * To simplify this debug code, we only consider normal boot
+ * case. Otherwise we need to remember CPU0's state and restore
+ * to that state and resolve racy conditions etc.
+ */
+ _debug_hotplug_cpu(0, 0);
+ break;
+#endif
+ default:
+ break;
+ }
+ return notifier_from_errno(ret);
+}
+
+static int __init bsp_pm_check_init(void)
+{
+ /*
+ * Set this bsp_pm_callback as lower priority than
+ * cpu_hotplug_pm_callback. So cpu_hotplug_pm_callback will be called
+ * earlier to disable cpu hotplug before bsp online check.
+ */
+ pm_notifier(bsp_pm_callback, -INT_MAX);
+ return 0;
+}
+
+core_initcall(bsp_pm_check_init);
diff --git a/arch/x86/tools/gen-insn-attr-x86.awk b/arch/x86/tools/gen-insn-attr-x86.awk
index ddcf39b1a18..e6773dc8ac4 100644
--- a/arch/x86/tools/gen-insn-attr-x86.awk
+++ b/arch/x86/tools/gen-insn-attr-x86.awk
@@ -356,7 +356,7 @@ END {
exit 1
# print escape opcode map's array
print "/* Escape opcode map array */"
- print "const insn_attr_t const *inat_escape_tables[INAT_ESC_MAX + 1]" \
+ print "const insn_attr_t * const inat_escape_tables[INAT_ESC_MAX + 1]" \
"[INAT_LSTPFX_MAX + 1] = {"
for (i = 0; i < geid; i++)
for (j = 0; j < max_lprefix; j++)
@@ -365,7 +365,7 @@ END {
print "};\n"
# print group opcode map's array
print "/* Group opcode map array */"
- print "const insn_attr_t const *inat_group_tables[INAT_GRP_MAX + 1]"\
+ print "const insn_attr_t * const inat_group_tables[INAT_GRP_MAX + 1]"\
"[INAT_LSTPFX_MAX + 1] = {"
for (i = 0; i < ggid; i++)
for (j = 0; j < max_lprefix; j++)
@@ -374,7 +374,7 @@ END {
print "};\n"
# print AVX opcode map's array
print "/* AVX opcode map array */"
- print "const insn_attr_t const *inat_avx_tables[X86_VEX_M_MAX + 1]"\
+ print "const insn_attr_t * const inat_avx_tables[X86_VEX_M_MAX + 1]"\
"[INAT_LSTPFX_MAX + 1] = {"
for (i = 0; i < gaid; i++)
for (j = 0; j < max_lprefix; j++)
diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig
index 07611759ce3..b0c30dae9f5 100644
--- a/arch/x86/um/Kconfig
+++ b/arch/x86/um/Kconfig
@@ -31,7 +31,7 @@ config X86_64
select MODULES_USE_ELF_RELA
config RWSEM_XCHGADD_ALGORITHM
- def_bool X86_XADD && 64BIT
+ def_bool 64BIT
config RWSEM_GENERIC_SPINLOCK
def_bool !RWSEM_XCHGADD_ALGORITHM
diff --git a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c
index 00aaf047b39..431e8754441 100644
--- a/arch/x86/vdso/vma.c
+++ b/arch/x86/vdso/vma.c
@@ -141,7 +141,7 @@ static unsigned long vdso_addr(unsigned long start, unsigned len)
* unaligned here as a result of stack start randomization.
*/
addr = PAGE_ALIGN(addr);
- addr = align_addr(addr, NULL, ALIGN_VDSO);
+ addr = align_vdso_addr(addr);
return addr;
}
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index fdce49c7aff..9a6775c9ddc 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -7,7 +7,7 @@ config XEN
select PARAVIRT
select PARAVIRT_CLOCK
depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS)
- depends on X86_CMPXCHG && X86_TSC
+ depends on X86_TSC
help
This is the Linux Xen port. Enabling this will allow the
kernel to boot in a paravirtualized environment under the
diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild
index 6d130278999..095f0a2244f 100644
--- a/arch/xtensa/include/asm/Kbuild
+++ b/arch/xtensa/include/asm/Kbuild
@@ -25,4 +25,5 @@ generic-y += siginfo.h
generic-y += statfs.h
generic-y += termios.h
generic-y += topology.h
+generic-y += trace_clock.h
generic-y += xor.h
diff --git a/arch/xtensa/include/uapi/asm/ioctls.h b/arch/xtensa/include/uapi/asm/ioctls.h
index 2aa4cd9f0ce..b4cb1100c0f 100644
--- a/arch/xtensa/include/uapi/asm/ioctls.h
+++ b/arch/xtensa/include/uapi/asm/ioctls.h
@@ -101,6 +101,9 @@
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
#define TIOCVHANGUP _IO('T', 0x37)
+#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
+#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
+#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
#define TIOCSERCONFIG _IO('T', 83)
#define TIOCSERGWILD _IOR('T', 84, int)
diff --git a/arch/xtensa/include/uapi/asm/mman.h b/arch/xtensa/include/uapi/asm/mman.h
index 25bc6c1309c..00eed6786d7 100644
--- a/arch/xtensa/include/uapi/asm/mman.h
+++ b/arch/xtensa/include/uapi/asm/mman.h
@@ -93,4 +93,15 @@
/* compatibility flags */
#define MAP_FILE 0
+/*
+ * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size.
+ * This gives us 6 bits, which is enough until someone invents 128 bit address
+ * spaces.
+ *
+ * Assume these are all power of twos.
+ * When 0 use the default page size.
+ */
+#define MAP_HUGE_SHIFT 26
+#define MAP_HUGE_MASK 0x3f
+
#endif /* _XTENSA_MMAN_H */
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c
index 7e74895eee0..8207a119eee 100644
--- a/arch/xtensa/platforms/iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -221,6 +221,7 @@ static __exit void rs_exit(void)
printk("ISS_SERIAL: failed to unregister serial driver (%d)\n",
error);
put_tty_driver(serial_driver);
+ tty_port_destroy(&serial_port);
}
diff --git a/block/blk-exec.c b/block/blk-exec.c
index 8b6dc5bd4dd..f71eac35c1b 100644
--- a/block/blk-exec.c
+++ b/block/blk-exec.c
@@ -52,11 +52,17 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
rq_end_io_fn *done)
{
int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
+ bool is_pm_resume;
WARN_ON(irqs_disabled());
rq->rq_disk = bd_disk;
rq->end_io = done;
+ /*
+ * need to check this before __blk_run_queue(), because rq can
+ * be freed before that returns.
+ */
+ is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME;
spin_lock_irq(q->queue_lock);
@@ -71,7 +77,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
__elv_add_request(q, rq, where);
__blk_run_queue(q);
/* the queue is stopped so it won't be run */
- if (rq->cmd_type == REQ_TYPE_PM_RESUME)
+ if (is_pm_resume)
q->request_fn(q);
spin_unlock_irq(q->queue_lock);
}
diff --git a/drivers/Kconfig b/drivers/Kconfig
index dbdefa3fe77..f5fb0722a63 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -156,4 +156,6 @@ source "drivers/pwm/Kconfig"
source "drivers/irqchip/Kconfig"
+source "drivers/ipack/Kconfig"
+
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index a16a8d001ae..7863b9fee50 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -145,3 +145,4 @@ obj-$(CONFIG_EXTCON) += extcon/
obj-$(CONFIG_MEMORY) += memory/
obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_VME_BUS) += vme/
+obj-$(CONFIG_IPACK_BUS) += ipack/
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 119d58db834..0300bf61294 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -181,6 +181,12 @@ config ACPI_DOCK
This driver supports ACPI-controlled docking stations and removable
drive bays such as the IBM Ultrabay and the Dell Module Bay.
+config ACPI_I2C
+ def_tristate I2C
+ depends on I2C
+ help
+ ACPI I2C enumeration support.
+
config ACPI_PROCESSOR
tristate "Processor"
select THERMAL
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 82422fe90f8..2a4502becd1 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -21,9 +21,10 @@ obj-y += acpi.o \
acpi-y += osl.o utils.o reboot.o
acpi-y += nvs.o
-# sleep related files
+# Power management related files
acpi-y += wakeup.o
acpi-y += sleep.o
+acpi-$(CONFIG_PM) += device_pm.o
acpi-$(CONFIG_ACPI_SLEEP) += proc.o
@@ -32,10 +33,12 @@ acpi-$(CONFIG_ACPI_SLEEP) += proc.o
#
acpi-y += bus.o glue.o
acpi-y += scan.o
+acpi-y += resource.o
acpi-y += processor_core.o
acpi-y += ec.o
acpi-$(CONFIG_ACPI_DOCK) += dock.o
acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
+acpi-y += acpi_platform.o
acpi-y += power.o
acpi-y += event.o
acpi-y += sysfs.o
@@ -67,6 +70,7 @@ obj-$(CONFIG_ACPI_HED) += hed.o
obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o
obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
obj-$(CONFIG_ACPI_BGRT) += bgrt.o
+obj-$(CONFIG_ACPI_I2C) += acpi_i2c.o
# processor has its own "processor." module_param namespace
processor-y := processor_driver.o processor_throttling.o
diff --git a/drivers/acpi/acpi_i2c.c b/drivers/acpi/acpi_i2c.c
new file mode 100644
index 00000000000..82045e3f5ca
--- /dev/null
+++ b/drivers/acpi/acpi_i2c.c
@@ -0,0 +1,103 @@
+/*
+ * ACPI I2C enumeration support
+ *
+ * Copyright (C) 2012, Intel Corporation
+ * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/i2c.h>
+#include <linux/ioport.h>
+
+ACPI_MODULE_NAME("i2c");
+
+static int acpi_i2c_add_resource(struct acpi_resource *ares, void *data)
+{
+ struct i2c_board_info *info = data;
+
+ if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
+ struct acpi_resource_i2c_serialbus *sb;
+
+ sb = &ares->data.i2c_serial_bus;
+ if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
+ info->addr = sb->slave_address;
+ if (sb->access_mode == ACPI_I2C_10BIT_MODE)
+ info->flags |= I2C_CLIENT_TEN;
+ }
+ } else if (info->irq < 0) {
+ struct resource r;
+
+ if (acpi_dev_resource_interrupt(ares, 0, &r))
+ info->irq = r.start;
+ }
+
+ /* Tell the ACPI core to skip this resource */
+ return 1;
+}
+
+static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
+ void *data, void **return_value)
+{
+ struct i2c_adapter *adapter = data;
+ struct list_head resource_list;
+ struct i2c_board_info info;
+ struct acpi_device *adev;
+ int ret;
+
+ if (acpi_bus_get_device(handle, &adev))
+ return AE_OK;
+ if (acpi_bus_get_status(adev) || !adev->status.present)
+ return AE_OK;
+
+ memset(&info, 0, sizeof(info));
+ info.acpi_node.handle = handle;
+ info.irq = -1;
+
+ INIT_LIST_HEAD(&resource_list);
+ ret = acpi_dev_get_resources(adev, &resource_list,
+ acpi_i2c_add_resource, &info);
+ acpi_dev_free_resource_list(&resource_list);
+
+ if (ret < 0 || !info.addr)
+ return AE_OK;
+
+ strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type));
+ if (!i2c_new_device(adapter, &info)) {
+ dev_err(&adapter->dev,
+ "failed to add I2C device %s from ACPI\n",
+ dev_name(&adev->dev));
+ }
+
+ return AE_OK;
+}
+
+/**
+ * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter
+ * @adapter: pointer to adapter
+ *
+ * Enumerate all I2C slave devices behind this adapter by walking the ACPI
+ * namespace. When a device is found it will be added to the Linux device
+ * model and bound to the corresponding ACPI handle.
+ */
+void acpi_i2c_register_devices(struct i2c_adapter *adapter)
+{
+ acpi_handle handle;
+ acpi_status status;
+
+ handle = ACPI_HANDLE(&adapter->dev);
+ if (!handle)
+ return;
+
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+ acpi_i2c_add_device, NULL,
+ adapter, NULL);
+ if (ACPI_FAILURE(status))
+ dev_warn(&adapter->dev, "failed to enumerate I2C slaves\n");
+}
+EXPORT_SYMBOL_GPL(acpi_i2c_register_devices);
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 24c807f9663..eb30e5ab4ca 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -31,6 +31,7 @@
#include <linux/types.h>
#include <linux/memory_hotplug.h>
#include <linux/slab.h>
+#include <linux/acpi.h>
#include <acpi/acpi_drivers.h>
#define ACPI_MEMORY_DEVICE_CLASS "memory"
@@ -78,6 +79,7 @@ struct acpi_memory_info {
unsigned short caching; /* memory cache attribute */
unsigned short write_protect; /* memory read/write attribute */
unsigned int enabled:1;
+ unsigned int failed:1;
};
struct acpi_memory_device {
@@ -86,8 +88,6 @@ struct acpi_memory_device {
struct list_head res_list;
};
-static int acpi_hotmem_initialized;
-
static acpi_status
acpi_memory_get_resource(struct acpi_resource *resource, void *context)
{
@@ -125,12 +125,20 @@ acpi_memory_get_resource(struct acpi_resource *resource, void *context)
return AE_OK;
}
+static void
+acpi_memory_free_device_resources(struct acpi_memory_device *mem_device)
+{
+ struct acpi_memory_info *info, *n;
+
+ list_for_each_entry_safe(info, n, &mem_device->res_list, list)
+ kfree(info);
+ INIT_LIST_HEAD(&mem_device->res_list);
+}
+
static int
acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
{
acpi_status status;
- struct acpi_memory_info *info, *n;
-
if (!list_empty(&mem_device->res_list))
return 0;
@@ -138,9 +146,7 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
status = acpi_walk_resources(mem_device->device->handle, METHOD_NAME__CRS,
acpi_memory_get_resource, mem_device);
if (ACPI_FAILURE(status)) {
- list_for_each_entry_safe(info, n, &mem_device->res_list, list)
- kfree(info);
- INIT_LIST_HEAD(&mem_device->res_list);
+ acpi_memory_free_device_resources(mem_device);
return -EINVAL;
}
@@ -170,7 +176,7 @@ acpi_memory_get_device(acpi_handle handle,
/* Get the parent device */
result = acpi_bus_get_device(phandle, &pdevice);
if (result) {
- printk(KERN_WARNING PREFIX "Cannot get acpi bus device");
+ acpi_handle_warn(phandle, "Cannot get acpi bus device\n");
return -EINVAL;
}
@@ -180,14 +186,14 @@ acpi_memory_get_device(acpi_handle handle,
*/
result = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE);
if (result) {
- printk(KERN_WARNING PREFIX "Cannot add acpi bus");
+ acpi_handle_warn(handle, "Cannot add acpi bus\n");
return -EINVAL;
}
end:
*mem_device = acpi_driver_data(device);
if (!(*mem_device)) {
- printk(KERN_ERR "\n driver data not found");
+ dev_err(&device->dev, "driver data not found\n");
return -ENODEV;
}
@@ -224,7 +230,8 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
/* Get the range from the _CRS */
result = acpi_memory_get_device_resources(mem_device);
if (result) {
- printk(KERN_ERR PREFIX "get_device_resources failed\n");
+ dev_err(&mem_device->device->dev,
+ "get_device_resources failed\n");
mem_device->state = MEMORY_INVALID_STATE;
return result;
}
@@ -251,13 +258,27 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
node = memory_add_physaddr_to_nid(info->start_addr);
result = add_memory(node, info->start_addr, info->length);
- if (result)
+
+ /*
+ * If the memory block has been used by the kernel, add_memory()
+ * returns -EEXIST. If add_memory() returns the other error, it
+ * means that this memory block is not used by the kernel.
+ */
+ if (result && result != -EEXIST) {
+ info->failed = 1;
continue;
- info->enabled = 1;
+ }
+
+ if (!result)
+ info->enabled = 1;
+ /*
+ * Add num_enable even if add_memory() returns -EEXIST, so the
+ * device is bound to this driver.
+ */
num_enabled++;
}
if (!num_enabled) {
- printk(KERN_ERR PREFIX "add_memory failed\n");
+ dev_err(&mem_device->device->dev, "add_memory failed\n");
mem_device->state = MEMORY_INVALID_STATE;
return -EINVAL;
}
@@ -272,68 +293,31 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
return 0;
}
-static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
+static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device)
{
- acpi_status status;
- struct acpi_object_list arg_list;
- union acpi_object arg;
- unsigned long long current_status;
-
-
- /* Issue the _EJ0 command */
- arg_list.count = 1;
- arg_list.pointer = &arg;
- arg.type = ACPI_TYPE_INTEGER;
- arg.integer.value = 1;
- status = acpi_evaluate_object(mem_device->device->handle,
- "_EJ0", &arg_list, NULL);
- /* Return on _EJ0 failure */
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status, "_EJ0 failed"));
- return -ENODEV;
- }
-
- /* Evalute _STA to check if the device is disabled */
- status = acpi_evaluate_integer(mem_device->device->handle, "_STA",
- NULL, &current_status);
- if (ACPI_FAILURE(status))
- return -ENODEV;
-
- /* Check for device status. Device should be disabled */
- if (current_status & ACPI_STA_DEVICE_ENABLED)
- return -EINVAL;
+ int result = 0;
+ struct acpi_memory_info *info, *n;
- return 0;
-}
+ list_for_each_entry_safe(info, n, &mem_device->res_list, list) {
+ if (info->failed)
+ /* The kernel does not use this memory block */
+ continue;
-static int acpi_memory_disable_device(struct acpi_memory_device *mem_device)
-{
- int result;
- struct acpi_memory_info *info, *n;
+ if (!info->enabled)
+ /*
+ * The kernel uses this memory block, but it may be not
+ * managed by us.
+ */
+ return -EBUSY;
+ result = remove_memory(info->start_addr, info->length);
+ if (result)
+ return result;
- /*
- * Ask the VM to offline this memory range.
- * Note: Assume that this function returns zero on success
- */
- list_for_each_entry_safe(info, n, &mem_device->res_list, list) {
- if (info->enabled) {
- result = remove_memory(info->start_addr, info->length);
- if (result)
- return result;
- }
+ list_del(&info->list);
kfree(info);
}
- /* Power-off and eject the device */
- result = acpi_memory_powerdown_device(mem_device);
- if (result) {
- /* Set the status of the device to invalid */
- mem_device->state = MEMORY_INVALID_STATE;
- return result;
- }
-
- mem_device->state = MEMORY_POWER_OFF_STATE;
return result;
}
@@ -341,6 +325,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
{
struct acpi_memory_device *mem_device;
struct acpi_device *device;
+ struct acpi_eject_event *ej_event = NULL;
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
switch (event) {
@@ -353,7 +338,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"\nReceived DEVICE CHECK notification for device\n"));
if (acpi_memory_get_device(handle, &mem_device)) {
- printk(KERN_ERR PREFIX "Cannot find driver data\n");
+ acpi_handle_err(handle, "Cannot find driver data\n");
break;
}
@@ -361,7 +346,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
break;
if (acpi_memory_enable_device(mem_device)) {
- printk(KERN_ERR PREFIX "Cannot enable memory device\n");
+ acpi_handle_err(handle,"Cannot enable memory device\n");
break;
}
@@ -373,40 +358,28 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
"\nReceived EJECT REQUEST notification for device\n"));
if (acpi_bus_get_device(handle, &device)) {
- printk(KERN_ERR PREFIX "Device doesn't exist\n");
+ acpi_handle_err(handle, "Device doesn't exist\n");
break;
}
mem_device = acpi_driver_data(device);
if (!mem_device) {
- printk(KERN_ERR PREFIX "Driver Data is NULL\n");
+ acpi_handle_err(handle, "Driver Data is NULL\n");
break;
}
- /*
- * Currently disabling memory device from kernel mode
- * TBD: Can also be disabled from user mode scripts
- * TBD: Can also be disabled by Callback registration
- * with generic sysfs driver
- */
- if (acpi_memory_disable_device(mem_device)) {
- printk(KERN_ERR PREFIX "Disable memory device\n");
- /*
- * If _EJ0 was called but failed, _OST is not
- * necessary.
- */
- if (mem_device->state == MEMORY_INVALID_STATE)
- return;
-
+ ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
+ if (!ej_event) {
+ pr_err(PREFIX "No memory, dropping EJECT\n");
break;
}
- /*
- * TBD: Invoke acpi_bus_remove to cleanup data structures
- */
+ ej_event->handle = handle;
+ ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
+ acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
+ (void *)ej_event);
- /* _EJ0 succeeded; _OST is not necessary */
+ /* eject is performed asynchronously */
return;
-
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
@@ -420,6 +393,15 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
return;
}
+static void acpi_memory_device_free(struct acpi_memory_device *mem_device)
+{
+ if (!mem_device)
+ return;
+
+ acpi_memory_free_device_resources(mem_device);
+ kfree(mem_device);
+}
+
static int acpi_memory_device_add(struct acpi_device *device)
{
int result;
@@ -449,23 +431,16 @@ static int acpi_memory_device_add(struct acpi_device *device)
/* Set the device state */
mem_device->state = MEMORY_POWER_ON_STATE;
- printk(KERN_DEBUG "%s \n", acpi_device_name(device));
-
- /*
- * Early boot code has recognized memory area by EFI/E820.
- * If DSDT shows these memory devices on boot, hotplug is not necessary
- * for them. So, it just returns until completion of this driver's
- * start up.
- */
- if (!acpi_hotmem_initialized)
- return 0;
+ pr_debug("%s\n", acpi_device_name(device));
if (!acpi_memory_check_device(mem_device)) {
/* call add_memory func */
result = acpi_memory_enable_device(mem_device);
- if (result)
- printk(KERN_ERR PREFIX
+ if (result) {
+ dev_err(&device->dev,
"Error in acpi_memory_enable_device\n");
+ acpi_memory_device_free(mem_device);
+ }
}
return result;
}
@@ -473,13 +448,18 @@ static int acpi_memory_device_add(struct acpi_device *device)
static int acpi_memory_device_remove(struct acpi_device *device, int type)
{
struct acpi_memory_device *mem_device = NULL;
-
+ int result;
if (!device || !acpi_driver_data(device))
return -EINVAL;
mem_device = acpi_driver_data(device);
- kfree(mem_device);
+
+ result = acpi_memory_remove_memory(mem_device);
+ if (result)
+ return result;
+
+ acpi_memory_device_free(mem_device);
return 0;
}
@@ -568,7 +548,6 @@ static int __init acpi_memory_device_init(void)
return -ENODEV;
}
- acpi_hotmem_initialized = 1;
return 0;
}
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index af4aad6ee2e..16fa979f718 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -286,7 +286,7 @@ static ssize_t acpi_pad_rrtime_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
unsigned long num;
- if (strict_strtoul(buf, 0, &num))
+ if (kstrtoul(buf, 0, &num))
return -EINVAL;
if (num < 1 || num >= 100)
return -EINVAL;
@@ -309,7 +309,7 @@ static ssize_t acpi_pad_idlepct_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
unsigned long num;
- if (strict_strtoul(buf, 0, &num))
+ if (kstrtoul(buf, 0, &num))
return -EINVAL;
if (num < 1 || num >= 100)
return -EINVAL;
@@ -332,7 +332,7 @@ static ssize_t acpi_pad_idlecpus_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
unsigned long num;
- if (strict_strtoul(buf, 0, &num))
+ if (kstrtoul(buf, 0, &num))
return -EINVAL;
mutex_lock(&isolated_cpus_lock);
acpi_pad_idle_cpus(num);
@@ -457,7 +457,7 @@ static void acpi_pad_notify(acpi_handle handle, u32 event,
dev_name(&device->dev), event, 0);
break;
default:
- printk(KERN_WARNING "Unsupported event [0x%x]\n", event);
+ pr_warn("Unsupported event [0x%x]\n", event);
break;
}
}
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
new file mode 100644
index 00000000000..db129b9f52c
--- /dev/null
+++ b/drivers/acpi/acpi_platform.c
@@ -0,0 +1,104 @@
+/*
+ * ACPI support for platform bus type.
+ *
+ * Copyright (C) 2012, Intel Corporation
+ * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
+ * Mathias Nyman <mathias.nyman@linux.intel.com>
+ * Rafael J. Wysocki <rafael.j.wysocki@intel.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/acpi.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "internal.h"
+
+ACPI_MODULE_NAME("platform");
+
+/**
+ * acpi_create_platform_device - Create platform device for ACPI device node
+ * @adev: ACPI device node to create a platform device for.
+ *
+ * Check if the given @adev can be represented as a platform device and, if
+ * that's the case, create and register a platform device, populate its common
+ * resources and returns a pointer to it. Otherwise, return %NULL.
+ *
+ * The platform device's name will be taken from the @adev's _HID and _UID.
+ */
+struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
+{
+ struct platform_device *pdev = NULL;
+ struct acpi_device *acpi_parent;
+ struct platform_device_info pdevinfo;
+ struct resource_list_entry *rentry;
+ struct list_head resource_list;
+ struct resource *resources;
+ int count;
+
+ /* If the ACPI node already has a physical device attached, skip it. */
+ if (adev->physical_node_count)
+ return NULL;
+
+ INIT_LIST_HEAD(&resource_list);
+ count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
+ if (count <= 0)
+ return NULL;
+
+ resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL);
+ if (!resources) {
+ dev_err(&adev->dev, "No memory for resources\n");
+ acpi_dev_free_resource_list(&resource_list);
+ return NULL;
+ }
+ count = 0;
+ list_for_each_entry(rentry, &resource_list, node)
+ resources[count++] = rentry->res;
+
+ acpi_dev_free_resource_list(&resource_list);
+
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
+ /*
+ * If the ACPI node has a parent and that parent has a physical device
+ * attached to it, that physical device should be the parent of the
+ * platform device we are about to create.
+ */
+ pdevinfo.parent = NULL;
+ acpi_parent = adev->parent;
+ if (acpi_parent) {
+ struct acpi_device_physical_node *entry;
+ struct list_head *list;
+
+ mutex_lock(&acpi_parent->physical_node_lock);
+ list = &acpi_parent->physical_node_list;
+ if (!list_empty(list)) {
+ entry = list_first_entry(list,
+ struct acpi_device_physical_node,
+ node);
+ pdevinfo.parent = entry->dev;
+ }
+ mutex_unlock(&acpi_parent->physical_node_lock);
+ }
+ pdevinfo.name = dev_name(&adev->dev);
+ pdevinfo.id = -1;
+ pdevinfo.res = resources;
+ pdevinfo.num_res = count;
+ pdevinfo.acpi_node.handle = adev->handle;
+ pdev = platform_device_register_full(&pdevinfo);
+ if (IS_ERR(pdev)) {
+ dev_err(&adev->dev, "platform device creation failed: %ld\n",
+ PTR_ERR(pdev));
+ pdev = NULL;
+ } else {
+ dev_dbg(&adev->dev, "created platform device %s\n",
+ dev_name(&pdev->dev));
+ }
+
+ kfree(resources);
+ return pdev;
+}
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index 7f1d40797e8..c8bc24bd1f7 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -161,3 +161,6 @@ acpi-y += \
utxfinit.o \
utxferror.o \
utxfmutex.o
+
+acpi-$(ACPI_FUTURE_USAGE) += uttrack.o utcache.o utclib.o
+
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h
index 5e8abb07724..432a318c9ed 100644
--- a/drivers/acpi/acpica/acdebug.h
+++ b/drivers/acpi/acpica/acdebug.h
@@ -44,17 +44,28 @@
#ifndef __ACDEBUG_H__
#define __ACDEBUG_H__
-#define ACPI_DEBUG_BUFFER_SIZE 4196
+#define ACPI_DEBUG_BUFFER_SIZE 0x4000 /* 16K buffer for return objects */
-struct command_info {
+struct acpi_db_command_info {
char *name; /* Command Name */
u8 min_args; /* Minimum arguments required */
};
-struct argument_info {
+struct acpi_db_command_help {
+ u8 line_count; /* Number of help lines */
+ char *invocation; /* Command Invocation */
+ char *description; /* Command Description */
+};
+
+struct acpi_db_argument_info {
char *name; /* Argument Name */
};
+struct acpi_db_execute_walk {
+ u32 count;
+ u32 max_count;
+};
+
#define PARAM_LIST(pl) pl
#define DBTEST_OUTPUT_LEVEL(lvl) if (acpi_gbl_db_opt_verbose)
#define VERBOSE_PRINT(fp) DBTEST_OUTPUT_LEVEL(lvl) {\
@@ -77,59 +88,71 @@ acpi_db_single_step(struct acpi_walk_state *walk_state,
/*
* dbcmds - debug commands and output routines
*/
-acpi_status acpi_db_disassemble_method(char *name);
+struct acpi_namespace_node *acpi_db_convert_to_node(char *in_string);
void acpi_db_display_table_info(char *table_arg);
-void acpi_db_unload_acpi_table(char *table_arg, char *instance_arg);
+void acpi_db_display_template(char *buffer_arg);
-void
-acpi_db_set_method_breakpoint(char *location,
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op);
+void acpi_db_unload_acpi_table(char *name);
-void acpi_db_set_method_call_breakpoint(union acpi_parse_object *op);
+void acpi_db_send_notify(char *name, u32 value);
-void acpi_db_get_bus_info(void);
+void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg);
-void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op);
+acpi_status acpi_db_sleep(char *object_arg);
-void acpi_db_dump_namespace(char *start_arg, char *depth_arg);
+void acpi_db_display_locks(void);
-void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg);
+void acpi_db_display_resources(char *object_arg);
-void acpi_db_send_notify(char *name, u32 value);
+ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_db_display_gpes(void))
+
+void acpi_db_display_handlers(void);
+
+ACPI_HW_DEPENDENT_RETURN_VOID(void
+ acpi_db_generate_gpe(char *gpe_arg,
+ char *block_arg))
+
+/*
+ * dbmethod - control method commands
+ */
+void
+acpi_db_set_method_breakpoint(char *location,
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op);
+
+void acpi_db_set_method_call_breakpoint(union acpi_parse_object *op);
void acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg);
-acpi_status
-acpi_db_display_objects(char *obj_type_arg, char *display_count_arg);
+acpi_status acpi_db_disassemble_method(char *name);
-void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg);
+void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op);
-acpi_status acpi_db_find_name_in_namespace(char *name_arg);
+void acpi_db_batch_execute(char *count_arg);
+/*
+ * dbnames - namespace commands
+ */
void acpi_db_set_scope(char *name);
-ACPI_HW_DEPENDENT_RETURN_OK(acpi_status acpi_db_sleep(char *object_arg))
+void acpi_db_dump_namespace(char *start_arg, char *depth_arg);
-void acpi_db_find_references(char *object_arg);
+void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg);
-void acpi_db_display_locks(void);
+acpi_status acpi_db_find_name_in_namespace(char *name_arg);
-void acpi_db_display_resources(char *object_arg);
+void acpi_db_check_predefined_names(void);
-ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_db_display_gpes(void))
+acpi_status
+acpi_db_display_objects(char *obj_type_arg, char *display_count_arg);
void acpi_db_check_integrity(void);
-ACPI_HW_DEPENDENT_RETURN_VOID(void
- acpi_db_generate_gpe(char *gpe_arg,
- char *block_arg))
-
-void acpi_db_check_predefined_names(void);
+void acpi_db_find_references(char *object_arg);
-void acpi_db_batch_execute(void);
+void acpi_db_get_bus_info(void);
/*
* dbdisply - debug display commands
@@ -161,7 +184,8 @@ acpi_db_display_argument_object(union acpi_operand_object *obj_desc,
/*
* dbexec - debugger control method execution
*/
-void acpi_db_execute(char *name, char **args, u32 flags);
+void
+acpi_db_execute(char *name, char **args, acpi_object_type * types, u32 flags);
void
acpi_db_create_execution_threads(char *num_threads_arg,
@@ -175,7 +199,8 @@ u32 acpi_db_get_cache_info(struct acpi_memory_list *cache);
* dbfileio - Debugger file I/O commands
*/
acpi_object_type
-acpi_db_match_argument(char *user_argument, struct argument_info *arguments);
+acpi_db_match_argument(char *user_argument,
+ struct acpi_db_argument_info *arguments);
void acpi_db_close_debug_file(void);
@@ -208,6 +233,11 @@ acpi_db_command_dispatch(char *input_buffer,
void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void *context);
+acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op);
+
+char *acpi_db_get_next_token(char *string,
+ char **next, acpi_object_type * return_type);
+
/*
* dbstats - Generation and display of ACPI table statistics
*/
diff --git a/drivers/acpi/acpica/acdispat.h b/drivers/acpi/acpica/acdispat.h
index 5935ba6707e..ed33ebcdaeb 100644
--- a/drivers/acpi/acpica/acdispat.h
+++ b/drivers/acpi/acpica/acdispat.h
@@ -309,10 +309,13 @@ acpi_ds_obj_stack_push(void *object, struct acpi_walk_state *walk_state);
acpi_status
acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state *walk_state);
-struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union acpi_parse_object
- *origin, union acpi_operand_object
- *mth_desc, struct acpi_thread_state
- *thread);
+struct acpi_walk_state * acpi_ds_create_walk_state(acpi_owner_id owner_id,
+ union acpi_parse_object
+ *origin,
+ union acpi_operand_object
+ *mth_desc,
+ struct acpi_thread_state
+ *thread);
acpi_status
acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h
index c0a43b38c6a..e975c672044 100644
--- a/drivers/acpi/acpica/acevents.h
+++ b/drivers/acpi/acpica/acevents.h
@@ -84,9 +84,11 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
-acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info);
+acpi_status
+acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info);
-acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info);
+acpi_status
+acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info);
struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
u32 gpe_number);
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index ce79100fb5e..64472e4ec32 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -70,7 +70,7 @@
/*
* Enable "slack" in the AML interpreter? Default is FALSE, and the
- * interpreter strictly follows the ACPI specification. Setting to TRUE
+ * interpreter strictly follows the ACPI specification. Setting to TRUE
* allows the interpreter to ignore certain errors and/or bad AML constructs.
*
* Currently, these features are enabled by this flag:
@@ -155,26 +155,6 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_no_resource_disassembly, FALSE);
/*****************************************************************************
*
- * Debug support
- *
- ****************************************************************************/
-
-/* Procedure nesting level for debug output */
-
-extern u32 acpi_gbl_nesting_level;
-
-ACPI_EXTERN u32 acpi_gpe_count;
-ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS];
-
-/* Support for dynamic control method tracing mechanism */
-
-ACPI_EXTERN u32 acpi_gbl_original_dbg_level;
-ACPI_EXTERN u32 acpi_gbl_original_dbg_layer;
-ACPI_EXTERN u32 acpi_gbl_trace_dbg_level;
-ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer;
-
-/*****************************************************************************
- *
* ACPI Table globals
*
****************************************************************************/
@@ -259,15 +239,6 @@ ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock; /* For ACPI H/W except GPE reg
*
****************************************************************************/
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
-
-/* Lists for tracking memory allocations */
-
-ACPI_EXTERN struct acpi_memory_list *acpi_gbl_global_list;
-ACPI_EXTERN struct acpi_memory_list *acpi_gbl_ns_node_list;
-ACPI_EXTERN u8 acpi_gbl_display_final_mem_stats;
-#endif
-
/* Object caches */
ACPI_EXTERN acpi_cache_t *acpi_gbl_namespace_cache;
@@ -326,6 +297,15 @@ extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS];
#endif
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+/* Lists for tracking memory allocations */
+
+ACPI_EXTERN struct acpi_memory_list *acpi_gbl_global_list;
+ACPI_EXTERN struct acpi_memory_list *acpi_gbl_ns_node_list;
+ACPI_EXTERN u8 acpi_gbl_display_final_mem_stats;
+#endif
+
/*****************************************************************************
*
* Namespace globals
@@ -396,13 +376,35 @@ ACPI_EXTERN struct acpi_gpe_block_info
#if (!ACPI_REDUCED_HARDWARE)
ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized;
-ACPI_EXTERN ACPI_GBL_EVENT_HANDLER acpi_gbl_global_event_handler;
+ACPI_EXTERN acpi_gbl_event_handler acpi_gbl_global_event_handler;
ACPI_EXTERN void *acpi_gbl_global_event_handler_context;
#endif /* !ACPI_REDUCED_HARDWARE */
/*****************************************************************************
*
+ * Debug support
+ *
+ ****************************************************************************/
+
+/* Procedure nesting level for debug output */
+
+extern u32 acpi_gbl_nesting_level;
+
+/* Event counters */
+
+ACPI_EXTERN u32 acpi_gpe_count;
+ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS];
+
+/* Support for dynamic control method tracing mechanism */
+
+ACPI_EXTERN u32 acpi_gbl_original_dbg_level;
+ACPI_EXTERN u32 acpi_gbl_original_dbg_layer;
+ACPI_EXTERN u32 acpi_gbl_trace_dbg_level;
+ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer;
+
+/*****************************************************************************
+ *
* Debugger globals
*
****************************************************************************/
@@ -426,10 +428,11 @@ ACPI_EXTERN u8 acpi_gbl_db_opt_stats;
ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods;
ACPI_EXTERN char *acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS];
-ACPI_EXTERN char acpi_gbl_db_line_buf[80];
-ACPI_EXTERN char acpi_gbl_db_parsed_buf[80];
-ACPI_EXTERN char acpi_gbl_db_scope_buf[40];
-ACPI_EXTERN char acpi_gbl_db_debug_filename[40];
+ACPI_EXTERN acpi_object_type acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS];
+ACPI_EXTERN char acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE];
+ACPI_EXTERN char acpi_gbl_db_parsed_buf[ACPI_DB_LINE_BUFFER_SIZE];
+ACPI_EXTERN char acpi_gbl_db_scope_buf[80];
+ACPI_EXTERN char acpi_gbl_db_debug_filename[80];
ACPI_EXTERN u8 acpi_gbl_db_output_to_file;
ACPI_EXTERN char *acpi_gbl_db_buffer;
ACPI_EXTERN char *acpi_gbl_db_filename;
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index c816ee67509..ff8bd0061e8 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -262,10 +262,10 @@ struct acpi_create_field_info {
};
typedef
-acpi_status(*ACPI_INTERNAL_METHOD) (struct acpi_walk_state * walk_state);
+acpi_status(*acpi_internal_method) (struct acpi_walk_state * walk_state);
/*
- * Bitmapped ACPI types. Used internally only
+ * Bitmapped ACPI types. Used internally only
*/
#define ACPI_BTYPE_ANY 0x00000000
#define ACPI_BTYPE_INTEGER 0x00000001
@@ -486,8 +486,10 @@ struct acpi_gpe_device_info {
struct acpi_namespace_node *gpe_device;
};
-typedef acpi_status(*acpi_gpe_callback) (struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block, void *context);
+typedef acpi_status(*acpi_gpe_callback) (struct acpi_gpe_xrupt_info *
+ gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block,
+ void *context);
/* Information about each particular fixed event */
@@ -582,7 +584,7 @@ struct acpi_pscope_state {
};
/*
- * Thread state - one per thread across multiple walk states. Multiple walk
+ * Thread state - one per thread across multiple walk states. Multiple walk
* states are created when there are nested control methods executing.
*/
struct acpi_thread_state {
@@ -645,7 +647,7 @@ union acpi_generic_state {
*
****************************************************************************/
-typedef acpi_status(*ACPI_EXECUTE_OP) (struct acpi_walk_state * walk_state);
+typedef acpi_status(*acpi_execute_op) (struct acpi_walk_state * walk_state);
/* Address Range info block */
@@ -1031,6 +1033,7 @@ struct acpi_db_method_info {
acpi_handle method;
acpi_handle main_thread_gate;
acpi_handle thread_complete_gate;
+ acpi_handle info_gate;
acpi_thread_id *threads;
u32 num_threads;
u32 num_created;
@@ -1041,6 +1044,7 @@ struct acpi_db_method_info {
u32 num_loops;
char pathname[128];
char **args;
+ acpi_object_type *types;
/*
* Arguments to be passed to method for the command
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h
index a7f68c47f51..5efad99f216 100644
--- a/drivers/acpi/acpica/acmacros.h
+++ b/drivers/acpi/acpica/acmacros.h
@@ -84,29 +84,29 @@
/* These macros reverse the bytes during the move, converting little-endian to big endian */
- /* Big Endian <== Little Endian */
- /* Hi...Lo Lo...Hi */
+ /* Big Endian <== Little Endian */
+ /* Hi...Lo Lo...Hi */
/* 16-bit source, 16/32/64 destination */
#define ACPI_MOVE_16_TO_16(d, s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[1];\
- (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[0];}
+ (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[0];}
#define ACPI_MOVE_16_TO_32(d, s) {(*(u32 *)(void *)(d))=0;\
- ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\
- ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];}
+ ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\
+ ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];}
#define ACPI_MOVE_16_TO_64(d, s) {(*(u64 *)(void *)(d))=0;\
- ((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[1];\
- ((u8 *)(void *)(d))[7] = ((u8 *)(void *)(s))[0];}
+ ((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[1];\
+ ((u8 *)(void *)(d))[7] = ((u8 *)(void *)(s))[0];}
/* 32-bit source, 16/32/64 destination */
#define ACPI_MOVE_32_TO_16(d, s) ACPI_MOVE_16_TO_16(d, s) /* Truncate to 16 */
#define ACPI_MOVE_32_TO_32(d, s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[3];\
- (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[2];\
- (( u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\
- (( u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];}
+ (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[2];\
+ (( u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\
+ (( u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];}
#define ACPI_MOVE_32_TO_64(d, s) {(*(u64 *)(void *)(d))=0;\
((u8 *)(void *)(d))[4] = ((u8 *)(void *)(s))[3];\
@@ -196,24 +196,12 @@
#endif
#endif
-/* Macros based on machine integer width */
-
-#if ACPI_MACHINE_WIDTH == 32
-#define ACPI_MOVE_SIZE_TO_16(d, s) ACPI_MOVE_32_TO_16(d, s)
-
-#elif ACPI_MACHINE_WIDTH == 64
-#define ACPI_MOVE_SIZE_TO_16(d, s) ACPI_MOVE_64_TO_16(d, s)
-
-#else
-#error unknown ACPI_MACHINE_WIDTH
-#endif
-
/*
* Fast power-of-two math macros for non-optimized compilers
*/
-#define _ACPI_DIV(value, power_of2) ((u32) ((value) >> (power_of2)))
-#define _ACPI_MUL(value, power_of2) ((u32) ((value) << (power_of2)))
-#define _ACPI_MOD(value, divisor) ((u32) ((value) & ((divisor) -1)))
+#define _ACPI_DIV(value, power_of2) ((u32) ((value) >> (power_of2)))
+#define _ACPI_MUL(value, power_of2) ((u32) ((value) << (power_of2)))
+#define _ACPI_MOD(value, divisor) ((u32) ((value) & ((divisor) -1)))
#define ACPI_DIV_2(a) _ACPI_DIV(a, 1)
#define ACPI_MUL_2(a) _ACPI_MUL(a, 1)
@@ -238,12 +226,12 @@
/*
* Rounding macros (Power of two boundaries only)
*/
-#define ACPI_ROUND_DOWN(value, boundary) (((acpi_size)(value)) & \
- (~(((acpi_size) boundary)-1)))
+#define ACPI_ROUND_DOWN(value, boundary) (((acpi_size)(value)) & \
+ (~(((acpi_size) boundary)-1)))
-#define ACPI_ROUND_UP(value, boundary) ((((acpi_size)(value)) + \
- (((acpi_size) boundary)-1)) & \
- (~(((acpi_size) boundary)-1)))
+#define ACPI_ROUND_UP(value, boundary) ((((acpi_size)(value)) + \
+ (((acpi_size) boundary)-1)) & \
+ (~(((acpi_size) boundary)-1)))
/* Note: sizeof(acpi_size) evaluates to either 4 or 8 (32- vs 64-bit mode) */
@@ -264,7 +252,7 @@
#define ACPI_ROUND_UP_TO(value, boundary) (((value) + ((boundary)-1)) / (boundary))
-#define ACPI_IS_MISALIGNED(value) (((acpi_size) value) & (sizeof(acpi_size)-1))
+#define ACPI_IS_MISALIGNED(value) (((acpi_size) value) & (sizeof(acpi_size)-1))
/*
* Bitmask creation
@@ -355,7 +343,6 @@
* Ascii error messages can be configured out
*/
#ifndef ACPI_NO_ERROR_MESSAGES
-
/*
* Error reporting. Callers module and line number are inserted by AE_INFO,
* the plist contains a set of parens to allow variable-length lists.
@@ -375,18 +362,15 @@
#define ACPI_WARN_PREDEFINED(plist)
#define ACPI_INFO_PREDEFINED(plist)
-#endif /* ACPI_NO_ERROR_MESSAGES */
+#endif /* ACPI_NO_ERROR_MESSAGES */
/*
* Debug macros that are conditionally compiled
*/
#ifdef ACPI_DEBUG_OUTPUT
-
/*
* Function entry tracing
*/
-#ifdef CONFIG_ACPI_DEBUG_FUNC_TRACE
-
#define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \
acpi_ut_trace(ACPI_DEBUG_PARAMETERS)
#define ACPI_FUNCTION_TRACE_PTR(a, b) ACPI_FUNCTION_NAME(a) \
@@ -464,45 +448,19 @@
#endif /* ACPI_SIMPLE_RETURN_MACROS */
-#else /* !CONFIG_ACPI_DEBUG_FUNC_TRACE */
-
-#define ACPI_FUNCTION_TRACE(a)
-#define ACPI_FUNCTION_TRACE_PTR(a,b)
-#define ACPI_FUNCTION_TRACE_U32(a,b)
-#define ACPI_FUNCTION_TRACE_STR(a,b)
-#define ACPI_FUNCTION_EXIT
-#define ACPI_FUNCTION_STATUS_EXIT(s)
-#define ACPI_FUNCTION_VALUE_EXIT(s)
-#define ACPI_FUNCTION_TRACE(a)
-#define ACPI_FUNCTION_ENTRY()
-
-#define return_VOID return
-#define return_ACPI_STATUS(s) return(s)
-#define return_VALUE(s) return(s)
-#define return_UINT8(s) return(s)
-#define return_UINT32(s) return(s)
-#define return_PTR(s) return(s)
-
-#endif /* CONFIG_ACPI_DEBUG_FUNC_TRACE */
-
/* Conditional execution */
#define ACPI_DEBUG_EXEC(a) a
-#define ACPI_NORMAL_EXEC(a)
-
-#define ACPI_DEBUG_DEFINE(a) a;
#define ACPI_DEBUG_ONLY_MEMBERS(a) a;
#define _VERBOSE_STRUCTURES
-/* Stack and buffer dumping */
+/* Various object display routines for debug */
#define ACPI_DUMP_STACK_ENTRY(a) acpi_ex_dump_operand((a), 0)
-#define ACPI_DUMP_OPERANDS(a, b, c) acpi_ex_dump_operands(a, b, c)
-
+#define ACPI_DUMP_OPERANDS(a, b ,c) acpi_ex_dump_operands(a, b, c)
#define ACPI_DUMP_ENTRY(a, b) acpi_ns_dump_entry (a, b)
#define ACPI_DUMP_PATHNAME(a, b, c, d) acpi_ns_dump_pathname(a, b, c, d)
-#define ACPI_DUMP_RESOURCE_LIST(a) acpi_rs_dump_resource_list(a)
-#define ACPI_DUMP_BUFFER(a, b) acpi_ut_dump_buffer((u8 *) a, b, DB_BYTE_DISPLAY, _COMPONENT)
+#define ACPI_DUMP_BUFFER(a, b) acpi_ut_debug_dump_buffer((u8 *) a, b, DB_BYTE_DISPLAY, _COMPONENT)
#else
/*
@@ -510,25 +468,23 @@
* leaving no executable debug code!
*/
#define ACPI_DEBUG_EXEC(a)
-#define ACPI_NORMAL_EXEC(a) a;
-
-#define ACPI_DEBUG_DEFINE(a) do { } while(0)
-#define ACPI_DEBUG_ONLY_MEMBERS(a) do { } while(0)
-#define ACPI_FUNCTION_TRACE(a) do { } while(0)
-#define ACPI_FUNCTION_TRACE_PTR(a, b) do { } while(0)
-#define ACPI_FUNCTION_TRACE_U32(a, b) do { } while(0)
-#define ACPI_FUNCTION_TRACE_STR(a, b) do { } while(0)
-#define ACPI_FUNCTION_EXIT do { } while(0)
-#define ACPI_FUNCTION_STATUS_EXIT(s) do { } while(0)
-#define ACPI_FUNCTION_VALUE_EXIT(s) do { } while(0)
-#define ACPI_FUNCTION_ENTRY() do { } while(0)
-#define ACPI_DUMP_STACK_ENTRY(a) do { } while(0)
-#define ACPI_DUMP_OPERANDS(a, b, c) do { } while(0)
-#define ACPI_DUMP_ENTRY(a, b) do { } while(0)
-#define ACPI_DUMP_TABLES(a, b) do { } while(0)
-#define ACPI_DUMP_PATHNAME(a, b, c, d) do { } while(0)
-#define ACPI_DUMP_RESOURCE_LIST(a) do { } while(0)
-#define ACPI_DUMP_BUFFER(a, b) do { } while(0)
+#define ACPI_DEBUG_ONLY_MEMBERS(a)
+#define ACPI_FUNCTION_TRACE(a)
+#define ACPI_FUNCTION_TRACE_PTR(a, b)
+#define ACPI_FUNCTION_TRACE_U32(a, b)
+#define ACPI_FUNCTION_TRACE_STR(a, b)
+#define ACPI_FUNCTION_EXIT
+#define ACPI_FUNCTION_STATUS_EXIT(s)
+#define ACPI_FUNCTION_VALUE_EXIT(s)
+#define ACPI_FUNCTION_ENTRY()
+#define ACPI_DUMP_STACK_ENTRY(a)
+#define ACPI_DUMP_OPERANDS(a, b, c)
+#define ACPI_DUMP_ENTRY(a, b)
+#define ACPI_DUMP_TABLES(a, b)
+#define ACPI_DUMP_PATHNAME(a, b, c, d)
+#define ACPI_DUMP_BUFFER(a, b)
+#define ACPI_DEBUG_PRINT(pl)
+#define ACPI_DEBUG_PRINT_RAW(pl)
#define return_VOID return
#define return_ACPI_STATUS(s) return(s)
@@ -556,18 +512,6 @@
#define ACPI_DEBUGGER_EXEC(a)
#endif
-#ifdef ACPI_DEBUG_OUTPUT
-/*
- * 1) Set name to blanks
- * 2) Copy the object name
- */
-#define ACPI_ADD_OBJECT_NAME(a,b) ACPI_MEMSET (a->common.name, ' ', sizeof (a->common.name));\
- ACPI_STRNCPY (a->common.name, acpi_gbl_ns_type_names[b], sizeof (a->common.name))
-#else
-
-#define ACPI_ADD_OBJECT_NAME(a,b)
-#endif
-
/*
* Memory allocation tracking (DEBUG ONLY)
*/
@@ -578,13 +522,13 @@
/* Memory allocation */
#ifndef ACPI_ALLOCATE
-#define ACPI_ALLOCATE(a) acpi_ut_allocate((acpi_size)(a), ACPI_MEM_PARAMETERS)
+#define ACPI_ALLOCATE(a) acpi_ut_allocate((acpi_size) (a), ACPI_MEM_PARAMETERS)
#endif
#ifndef ACPI_ALLOCATE_ZEROED
-#define ACPI_ALLOCATE_ZEROED(a) acpi_ut_allocate_zeroed((acpi_size)(a), ACPI_MEM_PARAMETERS)
+#define ACPI_ALLOCATE_ZEROED(a) acpi_ut_allocate_zeroed((acpi_size) (a), ACPI_MEM_PARAMETERS)
#endif
#ifndef ACPI_FREE
-#define ACPI_FREE(a) acpio_os_free(a)
+#define ACPI_FREE(a) acpi_os_free(a)
#endif
#define ACPI_MEM_TRACKING(a)
@@ -592,16 +536,25 @@
/* Memory allocation */
-#define ACPI_ALLOCATE(a) acpi_ut_allocate_and_track((acpi_size)(a), ACPI_MEM_PARAMETERS)
-#define ACPI_ALLOCATE_ZEROED(a) acpi_ut_allocate_zeroed_and_track((acpi_size)(a), ACPI_MEM_PARAMETERS)
+#define ACPI_ALLOCATE(a) acpi_ut_allocate_and_track((acpi_size) (a), ACPI_MEM_PARAMETERS)
+#define ACPI_ALLOCATE_ZEROED(a) acpi_ut_allocate_zeroed_and_track((acpi_size) (a), ACPI_MEM_PARAMETERS)
#define ACPI_FREE(a) acpi_ut_free_and_track(a, ACPI_MEM_PARAMETERS)
#define ACPI_MEM_TRACKING(a) a
#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
-/* Preemption point */
-#ifndef ACPI_PREEMPTION_POINT
-#define ACPI_PREEMPTION_POINT() /* no preemption */
-#endif
+/*
+ * Macros used for ACPICA utilities only
+ */
+
+/* Generate a UUID */
+
+#define ACPI_INIT_UUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
+ (a) & 0xFF, ((a) >> 8) & 0xFF, ((a) >> 16) & 0xFF, ((a) >> 24) & 0xFF, \
+ (b) & 0xFF, ((b) >> 8) & 0xFF, \
+ (c) & 0xFF, ((c) >> 8) & 0xFF, \
+ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)
+
+#define ACPI_IS_OCTAL_DIGIT(d) (((char)(d) >= '0') && ((char)(d) <= '7'))
#endif /* ACMACROS_H */
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h
index 364a1303fb8..24eb9eac951 100644
--- a/drivers/acpi/acpica/acobject.h
+++ b/drivers/acpi/acpica/acobject.h
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Name: acobject.h - Definition of union acpi_operand_object (Internal object only)
@@ -179,7 +178,7 @@ struct acpi_object_method {
union acpi_operand_object *mutex;
u8 *aml_start;
union {
- ACPI_INTERNAL_METHOD implementation;
+ acpi_internal_method implementation;
union acpi_operand_object *handler;
} dispatch;
@@ -198,7 +197,7 @@ struct acpi_object_method {
/******************************************************************************
*
- * Objects that can be notified. All share a common notify_info area.
+ * Objects that can be notified. All share a common notify_info area.
*
*****************************************************************************/
@@ -235,7 +234,7 @@ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO};
/******************************************************************************
*
- * Fields. All share a common header/info field.
+ * Fields. All share a common header/info field.
*
*****************************************************************************/
diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h
index 9440d053fbb..d786a5128b7 100644
--- a/drivers/acpi/acpica/acopcode.h
+++ b/drivers/acpi/acpica/acopcode.h
@@ -54,7 +54,7 @@
#define _UNK 0x6B
/*
- * Reserved ASCII characters. Do not use any of these for
+ * Reserved ASCII characters. Do not use any of these for
* internal opcodes, since they are used to differentiate
* name strings from AML opcodes
*/
@@ -63,7 +63,7 @@
#define _PFX 0x6D
/*
- * All AML opcodes and the parse-time arguments for each. Used by the AML
+ * All AML opcodes and the parse-time arguments for each. Used by the AML
* parser Each list is compressed into a 32-bit number and stored in the
* master opcode table (in psopcode.c).
*/
@@ -193,7 +193,7 @@
#define ARGP_ZERO_OP ARG_NONE
/*
- * All AML opcodes and the runtime arguments for each. Used by the AML
+ * All AML opcodes and the runtime arguments for each. Used by the AML
* interpreter Each list is compressed into a 32-bit number and stored
* in the master opcode table (in psopcode.c).
*
diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h
index b725d780d34..eefcf47a61a 100644
--- a/drivers/acpi/acpica/acparser.h
+++ b/drivers/acpi/acpica/acparser.h
@@ -150,8 +150,7 @@ u8 acpi_ps_has_completed_scope(struct acpi_parse_state *parser_state);
void
acpi_ps_pop_scope(struct acpi_parse_state *parser_state,
- union acpi_parse_object **op,
- u32 * arg_list, u32 * arg_count);
+ union acpi_parse_object **op, u32 *arg_list, u32 *arg_count);
acpi_status
acpi_ps_push_scope(struct acpi_parse_state *parser_state,
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h
index 3080c017f5b..9dfa1c83bd4 100644
--- a/drivers/acpi/acpica/acpredef.h
+++ b/drivers/acpi/acpica/acpredef.h
@@ -150,8 +150,7 @@ enum acpi_return_package_types {
* is saved here (rather than in a separate table) in order to minimize the
* overall size of the stored data.
*/
-static const union acpi_predefined_info predefined_names[] =
-{
+static const union acpi_predefined_info predefined_names[] = {
{{"_AC0", 0, ACPI_RTYPE_INTEGER}},
{{"_AC1", 0, ACPI_RTYPE_INTEGER}},
{{"_AC2", 0, ACPI_RTYPE_INTEGER}},
@@ -538,7 +537,8 @@ static const union acpi_predefined_info predefined_names[] =
/* Acpi 1.0 defined _WAK with no return value. Later, it was changed to return a package */
- {{"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}},
+ {{"_WAK", 1,
+ ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}},
{{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, /* Fixed-length (2 Int), but is optional */
/* _WDG/_WED are MS extensions defined by "Windows Instrumentation" */
@@ -551,11 +551,12 @@ static const union acpi_predefined_info predefined_names[] =
};
#if 0
+
/* This is an internally implemented control method, no need to check */
- {{"_OSI", 1, ACPI_RTYPE_INTEGER}},
+{ {
+"_OSI", 1, ACPI_RTYPE_INTEGER}},
/* TBD: */
-
_PRT - currently ignore reversed entries. attempt to fix here?
think about possibly fixing package elements like _BIF, etc.
#endif
diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h
index f196e2c9a71..937e66c65d1 100644
--- a/drivers/acpi/acpica/acstruct.h
+++ b/drivers/acpi/acpica/acstruct.h
@@ -53,7 +53,7 @@
****************************************************************************/
/*
- * Walk state - current state of a parse tree walk. Used for both a leisurely
+ * Walk state - current state of a parse tree walk. Used for both a leisurely
* stroll through the tree (for whatever reason), and for control method
* execution.
*/
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h
index 5035327ebcc..b0f5f92b674 100644
--- a/drivers/acpi/acpica/acutils.h
+++ b/drivers/acpi/acpica/acutils.h
@@ -69,6 +69,22 @@ extern const char *acpi_gbl_siz_decode[];
extern const char *acpi_gbl_trs_decode[];
extern const char *acpi_gbl_ttp_decode[];
extern const char *acpi_gbl_typ_decode[];
+extern const char *acpi_gbl_ppc_decode[];
+extern const char *acpi_gbl_ior_decode[];
+extern const char *acpi_gbl_dts_decode[];
+extern const char *acpi_gbl_ct_decode[];
+extern const char *acpi_gbl_sbt_decode[];
+extern const char *acpi_gbl_am_decode[];
+extern const char *acpi_gbl_sm_decode[];
+extern const char *acpi_gbl_wm_decode[];
+extern const char *acpi_gbl_cph_decode[];
+extern const char *acpi_gbl_cpo_decode[];
+extern const char *acpi_gbl_dp_decode[];
+extern const char *acpi_gbl_ed_decode[];
+extern const char *acpi_gbl_bpb_decode[];
+extern const char *acpi_gbl_sb_decode[];
+extern const char *acpi_gbl_fc_decode[];
+extern const char *acpi_gbl_pt_decode[];
#endif
/* Types for Resource descriptor entries */
@@ -79,14 +95,14 @@ extern const char *acpi_gbl_typ_decode[];
#define ACPI_SMALL_VARIABLE_LENGTH 3
typedef
-acpi_status(*acpi_walk_aml_callback) (u8 * aml,
+acpi_status(*acpi_walk_aml_callback) (u8 *aml,
u32 length,
u32 offset,
u8 resource_index, void **context);
typedef
acpi_status(*acpi_pkg_callback) (u8 object_type,
- union acpi_operand_object * source_object,
+ union acpi_operand_object *source_object,
union acpi_generic_state * state,
void *context);
@@ -202,7 +218,9 @@ extern const u8 _acpi_ctype[];
#define ACPI_IS_PRINT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_SP | _ACPI_PU))
#define ACPI_IS_ALPHA(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP))
-#endif /* ACPI_USE_SYSTEM_CLIBRARY */
+#endif /* !ACPI_USE_SYSTEM_CLIBRARY */
+
+#define ACPI_IS_ASCII(c) ((c) < 0x80)
/*
* utcopy - Object construction and conversion interfaces
@@ -210,11 +228,11 @@ extern const u8 _acpi_ctype[];
acpi_status
acpi_ut_build_simple_object(union acpi_operand_object *obj,
union acpi_object *user_obj,
- u8 * data_space, u32 * buffer_space_used);
+ u8 *data_space, u32 *buffer_space_used);
acpi_status
acpi_ut_build_package_object(union acpi_operand_object *obj,
- u8 * buffer, u32 * space_used);
+ u8 *buffer, u32 *space_used);
acpi_status
acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *obj,
@@ -287,9 +305,10 @@ acpi_ut_ptr_exit(u32 line_number,
const char *function_name,
const char *module_name, u32 component_id, u8 *ptr);
-void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id);
+void
+acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id);
-void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display);
+void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 offset);
void acpi_ut_report_error(char *module_name, u32 line_number);
@@ -337,15 +356,19 @@ acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node,
*/
acpi_status
acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
- struct acpica_device_id **return_id);
+ struct acpi_pnp_device_id ** return_id);
acpi_status
acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
- struct acpica_device_id **return_id);
+ struct acpi_pnp_device_id ** return_id);
+
+acpi_status
+acpi_ut_execute_SUB(struct acpi_namespace_node *device_node,
+ struct acpi_pnp_device_id **return_id);
acpi_status
acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
- struct acpica_device_id_list **return_cid_list);
+ struct acpi_pnp_device_id_list ** return_cid_list);
/*
* utlock - reader/writer locks
@@ -479,15 +502,19 @@ acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
void acpi_ut_strupr(char *src_string);
+void acpi_ut_strlwr(char *src_string);
+
+int acpi_ut_stricmp(char *string1, char *string2);
+
void acpi_ut_print_string(char *string, u8 max_length);
u8 acpi_ut_valid_acpi_name(u32 name);
-acpi_name acpi_ut_repair_name(char *name);
+void acpi_ut_repair_name(char *name);
u8 acpi_ut_valid_acpi_char(char character, u32 position);
-acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer);
+acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer);
/* Values for Base above (16=Hex, 10=Decimal) */
@@ -508,12 +535,12 @@ acpi_ut_display_init_pathname(u8 type,
* utresrc
*/
acpi_status
-acpi_ut_walk_aml_resources(u8 * aml,
+acpi_ut_walk_aml_resources(u8 *aml,
acpi_size aml_length,
acpi_walk_aml_callback user_function,
void **context);
-acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index);
+acpi_status acpi_ut_validate_resource(void *aml, u8 *return_index);
u32 acpi_ut_get_descriptor_length(void *aml);
@@ -524,8 +551,7 @@ u8 acpi_ut_get_resource_header_length(void *aml);
u8 acpi_ut_get_resource_type(void *aml);
acpi_status
-acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc,
- u8 ** end_tag);
+acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, u8 **end_tag);
/*
* utmutex - mutex support
diff --git a/drivers/acpi/acpica/amlresrc.h b/drivers/acpi/acpica/amlresrc.h
index af4947956ec..968449685e0 100644
--- a/drivers/acpi/acpica/amlresrc.h
+++ b/drivers/acpi/acpica/amlresrc.h
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: amlresrc.h - AML resource descriptors
diff --git a/drivers/acpi/acpica/dscontrol.c b/drivers/acpi/acpica/dscontrol.c
index 465f02134b8..57895db3231 100644
--- a/drivers/acpi/acpica/dscontrol.c
+++ b/drivers/acpi/acpica/dscontrol.c
@@ -280,7 +280,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
/*
* Get the return value and save as the last result
- * value. This is the only place where walk_state->return_desc
+ * value. This is the only place where walk_state->return_desc
* is set to anything other than zero!
*/
walk_state->return_desc = walk_state->operands[0];
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c
index 3da6fd8530c..b5b904ee815 100644
--- a/drivers/acpi/acpica/dsfield.c
+++ b/drivers/acpi/acpica/dsfield.c
@@ -277,7 +277,7 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
*
* RETURN: Status
*
- * DESCRIPTION: Process all named fields in a field declaration. Names are
+ * DESCRIPTION: Process all named fields in a field declaration. Names are
* entered into the namespace.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c
index aa9a5d4e405..52eb4e01622 100644
--- a/drivers/acpi/acpica/dsmethod.c
+++ b/drivers/acpi/acpica/dsmethod.c
@@ -170,7 +170,7 @@ acpi_ds_create_method_mutex(union acpi_operand_object *method_desc)
*
* RETURN: Status
*
- * DESCRIPTION: Prepare a method for execution. Parses the method if necessary,
+ * DESCRIPTION: Prepare a method for execution. Parses the method if necessary,
* increments the thread count, and waits at the method semaphore
* for clearance to execute.
*
@@ -444,7 +444,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
* RETURN: Status
*
* DESCRIPTION: Restart a method that was preempted by another (nested) method
- * invocation. Handle the return value (if any) from the callee.
+ * invocation. Handle the return value (if any) from the callee.
*
******************************************************************************/
@@ -530,7 +530,7 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state,
*
* RETURN: None
*
- * DESCRIPTION: Terminate a control method. Delete everything that the method
+ * DESCRIPTION: Terminate a control method. Delete everything that the method
* created, delete all locals and arguments, and delete the parse
* tree if requested.
*
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c
index 8d55cebaa65..9a83b7e0f3b 100644
--- a/drivers/acpi/acpica/dsmthdat.c
+++ b/drivers/acpi/acpica/dsmthdat.c
@@ -76,7 +76,7 @@ acpi_ds_method_data_get_type(u16 opcode,
* RETURN: Status
*
* DESCRIPTION: Initialize the data structures that hold the method's arguments
- * and locals. The data struct is an array of namespace nodes for
+ * and locals. The data struct is an array of namespace nodes for
* each - this allows ref_of and de_ref_of to work properly for these
* special data types.
*
@@ -129,7 +129,7 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state)
*
* RETURN: None
*
- * DESCRIPTION: Delete method locals and arguments. Arguments are only
+ * DESCRIPTION: Delete method locals and arguments. Arguments are only
* deleted if this method was called from another method.
*
******************************************************************************/
@@ -183,7 +183,7 @@ void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state)
*
* RETURN: Status
*
- * DESCRIPTION: Initialize arguments for a method. The parameter list is a list
+ * DESCRIPTION: Initialize arguments for a method. The parameter list is a list
* of ACPI operand objects, either null terminated or whose length
* is defined by max_param_count.
*
@@ -401,7 +401,7 @@ acpi_ds_method_data_get_value(u8 type,
* This means that either 1) The expected argument was
* not passed to the method, or 2) A local variable
* was referenced by the method (via the ASL)
- * before it was initialized. Either case is an error.
+ * before it was initialized. Either case is an error.
*/
/* If slack enabled, init the local_x/arg_x to an Integer of value zero */
@@ -465,7 +465,7 @@ acpi_ds_method_data_get_value(u8 type,
*
* RETURN: None
*
- * DESCRIPTION: Delete the entry at Opcode:Index. Inserts
+ * DESCRIPTION: Delete the entry at Opcode:Index. Inserts
* a null into the stack slot after the object is deleted.
*
******************************************************************************/
@@ -523,7 +523,7 @@ acpi_ds_method_data_delete_value(u8 type,
*
* RETURN: Status
*
- * DESCRIPTION: Store a value in an Arg or Local. The obj_desc is installed
+ * DESCRIPTION: Store a value in an Arg or Local. The obj_desc is installed
* as the new value for the Arg or Local and the reference count
* for obj_desc is incremented.
*
@@ -566,7 +566,7 @@ acpi_ds_store_object_to_local(u8 type,
/*
* If the reference count on the object is more than one, we must
- * take a copy of the object before we store. A reference count
+ * take a copy of the object before we store. A reference count
* of exactly 1 means that the object was just created during the
* evaluation of an expression, and we can safely use it since it
* is not used anywhere else.
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c
index 68592dd3496..c9f15d3a368 100644
--- a/drivers/acpi/acpica/dsobject.c
+++ b/drivers/acpi/acpica/dsobject.c
@@ -293,7 +293,7 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
/*
* Second arg is the buffer data (optional) byte_list can be either
- * individual bytes or a string initializer. In either case, a
+ * individual bytes or a string initializer. In either case, a
* byte_list appears in the AML.
*/
arg = op->common.value.arg; /* skip first arg */
@@ -568,7 +568,7 @@ acpi_ds_create_node(struct acpi_walk_state *walk_state,
/*
* Because of the execution pass through the non-control-method
- * parts of the table, we can arrive here twice. Only init
+ * parts of the table, we can arrive here twice. Only init
* the named object node the first time through
*/
if (acpi_ns_get_attached_object(node)) {
@@ -618,7 +618,7 @@ acpi_ds_create_node(struct acpi_walk_state *walk_state,
* RETURN: Status
*
* DESCRIPTION: Initialize a namespace object from a parser Op and its
- * associated arguments. The namespace object is a more compact
+ * associated arguments. The namespace object is a more compact
* representation of the Op and its arguments.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
index aa34d8984d3..0df024e5fb6 100644
--- a/drivers/acpi/acpica/dsopcode.c
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -649,7 +649,8 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) &&
(op->common.parent->common.aml_opcode !=
AML_VAR_PACKAGE_OP)
- && (op->common.parent->common.aml_opcode != AML_NAME_OP))) {
+ && (op->common.parent->common.aml_opcode !=
+ AML_NAME_OP))) {
walk_state->result_obj = obj_desc;
}
}
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c
index 73a5447475f..afeb99f4948 100644
--- a/drivers/acpi/acpica/dsutils.c
+++ b/drivers/acpi/acpica/dsutils.c
@@ -61,7 +61,7 @@ ACPI_MODULE_NAME("dsutils")
*
* RETURN: None.
*
- * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
+ * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
* to delete "stale" return values (if enabled, the return value
* from every operator is saved at least momentarily, in case the
* parent method exits.)
@@ -107,7 +107,7 @@ void acpi_ds_clear_implicit_return(struct acpi_walk_state *walk_state)
*
* DESCRIPTION: Implements the optional "implicit return". We save the result
* of every ASL operator and control method invocation in case the
- * parent method exit. Before storing a new return value, we
+ * parent method exit. Before storing a new return value, we
* delete the previous return value.
*
******************************************************************************/
@@ -198,7 +198,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
*
* If there is no parent, or the parent is a scope_op, we are executing
* at the method level. An executing method typically has no parent,
- * since each method is parsed separately. A method invoked externally
+ * since each method is parsed separately. A method invoked externally
* via execute_control_method has a scope_op as the parent.
*/
if ((!op->common.parent) ||
@@ -223,7 +223,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
}
/*
- * Decide what to do with the result based on the parent. If
+ * Decide what to do with the result based on the parent. If
* the parent opcode will not use the result, delete the object.
* Otherwise leave it as is, it will be deleted when it is used
* as an operand later.
@@ -266,7 +266,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
/*
* These opcodes allow term_arg(s) as operands and therefore
- * the operands can be method calls. The result is used.
+ * the operands can be method calls. The result is used.
*/
goto result_used;
@@ -284,7 +284,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
AML_BANK_FIELD_OP)) {
/*
* These opcodes allow term_arg(s) as operands and therefore
- * the operands can be method calls. The result is used.
+ * the operands can be method calls. The result is used.
*/
goto result_used;
}
@@ -329,9 +329,9 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
*
* RETURN: Status
*
- * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
+ * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
* result descriptor, check if the parent opcode will actually use
- * this result. If not, delete the result now so that it will
+ * this result. If not, delete the result now so that it will
* not become orphaned.
*
******************************************************************************/
@@ -376,7 +376,7 @@ acpi_ds_delete_result_if_not_used(union acpi_parse_object *op,
*
* RETURN: Status
*
- * DESCRIPTION: Resolve all operands to their values. Used to prepare
+ * DESCRIPTION: Resolve all operands to their values. Used to prepare
* arguments to a control method invocation (a call from one
* method to another.)
*
@@ -391,7 +391,7 @@ acpi_status acpi_ds_resolve_operands(struct acpi_walk_state *walk_state)
/*
* Attempt to resolve each of the valid operands
- * Method arguments are passed by reference, not by value. This means
+ * Method arguments are passed by reference, not by value. This means
* that the actual objects are passed, not copies of the objects.
*/
for (i = 0; i < walk_state->num_operands; i++) {
@@ -451,7 +451,7 @@ void acpi_ds_clear_operands(struct acpi_walk_state *walk_state)
* RETURN: Status
*
* DESCRIPTION: Translate a parse tree object that is an argument to an AML
- * opcode to the equivalent interpreter object. This may include
+ * opcode to the equivalent interpreter object. This may include
* looking up a name or entering a new name into the internal
* namespace.
*
@@ -496,9 +496,9 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
/*
* Special handling for buffer_field declarations. This is a deferred
* opcode that unfortunately defines the field name as the last
- * parameter instead of the first. We get here when we are performing
+ * parameter instead of the first. We get here when we are performing
* the deferred execution, so the actual name of the field is already
- * in the namespace. We don't want to attempt to look it up again
+ * in the namespace. We don't want to attempt to look it up again
* because we may be executing in a different scope than where the
* actual opcode exists.
*/
@@ -560,7 +560,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
* indicate this to the interpreter, set the
* object to the root
*/
- obj_desc = ACPI_CAST_PTR(union
+ obj_desc =
+ ACPI_CAST_PTR(union
acpi_operand_object,
acpi_gbl_root_node);
status = AE_OK;
@@ -604,8 +605,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
/*
* If the name is null, this means that this is an
* optional result parameter that was not specified
- * in the original ASL. Create a Zero Constant for a
- * placeholder. (Store to a constant is a Noop.)
+ * in the original ASL. Create a Zero Constant for a
+ * placeholder. (Store to a constant is a Noop.)
*/
opcode = AML_ZERO_OP; /* Has no arguments! */
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c
index 642f3c053e8..58593931be9 100644
--- a/drivers/acpi/acpica/dswexec.c
+++ b/drivers/acpi/acpica/dswexec.c
@@ -57,7 +57,7 @@ ACPI_MODULE_NAME("dswexec")
/*
* Dispatch table for opcode classes
*/
-static ACPI_EXECUTE_OP acpi_gbl_op_type_dispatch[] = {
+static acpi_execute_op acpi_gbl_op_type_dispatch[] = {
acpi_ex_opcode_0A_0T_1R,
acpi_ex_opcode_1A_0T_0R,
acpi_ex_opcode_1A_0T_1R,
@@ -204,7 +204,7 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state,
* RETURN: Status
*
* DESCRIPTION: Descending callback used during the execution of control
- * methods. This is where most operators and operands are
+ * methods. This is where most operators and operands are
* dispatched to the interpreter.
*
****************************************************************************/
@@ -297,7 +297,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
if (walk_state->walk_type & ACPI_WALK_METHOD) {
/*
* Found a named object declaration during method execution;
- * we must enter this object into the namespace. The created
+ * we must enter this object into the namespace. The created
* object is temporary and will be deleted upon completion of
* the execution of this method.
*
@@ -348,7 +348,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
* RETURN: Status
*
* DESCRIPTION: Ascending callback used during the execution of control
- * methods. The only thing we really need to do here is to
+ * methods. The only thing we really need to do here is to
* notice the beginning of IF, ELSE, and WHILE blocks.
*
****************************************************************************/
@@ -432,7 +432,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
if (ACPI_SUCCESS(status)) {
/*
* Dispatch the request to the appropriate interpreter handler
- * routine. There is one routine per opcode "type" based upon the
+ * routine. There is one routine per opcode "type" based upon the
* number of opcode arguments and return type.
*/
status =
diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c
index 89c0114210c..37983574835 100644
--- a/drivers/acpi/acpica/dswload2.c
+++ b/drivers/acpi/acpica/dswload2.c
@@ -254,7 +254,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
acpi_ut_get_type_name(node->type),
acpi_ut_get_node_name(node)));
- return (AE_AML_OPERAND_TYPE);
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
break;
@@ -602,7 +602,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
region_space,
walk_state);
if (ACPI_FAILURE(status)) {
- return (status);
+ return_ACPI_STATUS(status);
}
acpi_ex_exit_interpreter();
diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c
index d0e6555061e..3e65a15a735 100644
--- a/drivers/acpi/acpica/dswstate.c
+++ b/drivers/acpi/acpica/dswstate.c
@@ -51,8 +51,9 @@
ACPI_MODULE_NAME("dswstate")
/* Local prototypes */
-static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *ws);
-static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *ws);
+static acpi_status
+acpi_ds_result_stack_push(struct acpi_walk_state *walk_state);
+static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state);
/*******************************************************************************
*
@@ -347,7 +348,7 @@ acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state)
*
* RETURN: Status
*
- * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
+ * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
* deleted by this routine.
*
******************************************************************************/
@@ -491,7 +492,7 @@ acpi_ds_push_walk_state(struct acpi_walk_state *walk_state,
* RETURN: A walk_state object popped from the thread's stack
*
* DESCRIPTION: Remove and return the walkstate object that is at the head of
- * the walk stack for the given walk list. NULL indicates that
+ * the walk stack for the given walk list. NULL indicates that
* the list is empty.
*
******************************************************************************/
@@ -531,14 +532,17 @@ struct acpi_walk_state *acpi_ds_pop_walk_state(struct acpi_thread_state *thread)
*
* RETURN: Pointer to the new walk state.
*
- * DESCRIPTION: Allocate and initialize a new walk state. The current walk
+ * DESCRIPTION: Allocate and initialize a new walk state. The current walk
* state is set to this new state.
*
******************************************************************************/
-struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union acpi_parse_object
- *origin, union acpi_operand_object
- *method_desc, struct acpi_thread_state
+struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id,
+ union acpi_parse_object
+ *origin,
+ union acpi_operand_object
+ *method_desc,
+ struct acpi_thread_state
*thread)
{
struct acpi_walk_state *walk_state;
@@ -653,7 +657,7 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
/*
* Setup the current scope.
* Find a Named Op that has a namespace node associated with it.
- * search upwards from this Op. Current scope is the first
+ * search upwards from this Op. Current scope is the first
* Op with a namespace node.
*/
extra_op = parser_state->start_op;
@@ -704,13 +708,13 @@ void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state)
ACPI_FUNCTION_TRACE_PTR(ds_delete_walk_state, walk_state);
if (!walk_state) {
- return;
+ return_VOID;
}
if (walk_state->descriptor_type != ACPI_DESC_TYPE_WALK) {
ACPI_ERROR((AE_INFO, "%p is not a valid walk state",
walk_state));
- return;
+ return_VOID;
}
/* There should not be any open scopes */
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index ef0193d74b5..36d12057442 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -89,7 +89,8 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info)
/* Set the mask bit only if there are references to this GPE */
if (gpe_event_info->runtime_count) {
- ACPI_SET_BIT(gpe_register_info->enable_for_run, (u8)register_bit);
+ ACPI_SET_BIT(gpe_register_info->enable_for_run,
+ (u8)register_bit);
}
return_ACPI_STATUS(AE_OK);
@@ -106,8 +107,7 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info)
* DESCRIPTION: Clear a GPE of stale events and enable it.
*
******************************************************************************/
-acpi_status
-acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
+acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
{
acpi_status status;
@@ -131,8 +131,8 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
}
/* Enable the requested GPE */
- status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
+ status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
return_ACPI_STATUS(status);
}
@@ -150,7 +150,8 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
*
******************************************************************************/
-acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info)
+acpi_status
+acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info)
{
acpi_status status = AE_OK;
@@ -191,7 +192,8 @@ acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info
*
******************************************************************************/
-acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info)
+acpi_status
+acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info)
{
acpi_status status = AE_OK;
@@ -208,7 +210,8 @@ acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_i
status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
if (ACPI_SUCCESS(status)) {
- status = acpi_hw_low_set_gpe(gpe_event_info,
+ status =
+ acpi_hw_low_set_gpe(gpe_event_info,
ACPI_GPE_DISABLE);
}
@@ -306,7 +309,8 @@ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
/* A Non-NULL gpe_device means this is a GPE Block Device */
- obj_desc = acpi_ns_get_attached_object((struct acpi_namespace_node *)
+ obj_desc =
+ acpi_ns_get_attached_object((struct acpi_namespace_node *)
gpe_device);
if (!obj_desc || !obj_desc->device.gpe_block) {
return (NULL);
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index 8cf4c104c7b..1571a61a783 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -486,7 +486,8 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Could not enable GPE 0x%02X",
- gpe_index + gpe_block->block_base_number));
+ gpe_index +
+ gpe_block->block_base_number));
continue;
}
diff --git a/drivers/acpi/acpica/evgpeutil.c b/drivers/acpi/acpica/evgpeutil.c
index cb50dd91bc1..228a0c3b1d4 100644
--- a/drivers/acpi/acpica/evgpeutil.c
+++ b/drivers/acpi/acpica/evgpeutil.c
@@ -374,7 +374,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
gpe_event_info->dispatch.handler = NULL;
gpe_event_info->flags &=
~ACPI_GPE_DISPATCH_MASK;
- } else if ((gpe_event_info->
+ } else
+ if ((gpe_event_info->
flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_NOTIFY) {
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c
index 4c1c8261166..1474241bfc7 100644
--- a/drivers/acpi/acpica/evrgnini.c
+++ b/drivers/acpi/acpica/evrgnini.c
@@ -227,8 +227,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
/* Install a handler for this PCI root bridge */
- status =
- acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
+ status = acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
if (ACPI_FAILURE(status)) {
if (status == AE_SAME_HANDLER) {
/*
@@ -350,8 +349,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
{
acpi_status status;
- struct acpica_device_id *hid;
- struct acpica_device_id_list *cid;
+ struct acpi_pnp_device_id *hid;
+ struct acpi_pnp_device_id_list *cid;
u32 i;
u8 match;
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
index 7587eb6c958..ae668f32cf1 100644
--- a/drivers/acpi/acpica/evxface.c
+++ b/drivers/acpi/acpica/evxface.c
@@ -398,7 +398,7 @@ ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
*
******************************************************************************/
acpi_status
-acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context)
+acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context)
{
acpi_status status;
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c
index 87c5f233226..3f30e753b65 100644
--- a/drivers/acpi/acpica/evxfgpe.c
+++ b/drivers/acpi/acpica/evxfgpe.c
@@ -221,7 +221,8 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
if (wake_device == ACPI_ROOT_OBJECT) {
device_node = acpi_gbl_root_node;
} else {
- device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
+ device_node =
+ ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
}
/* Validate WakeDevice is of type Device */
@@ -324,7 +325,8 @@ ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake)
*
******************************************************************************/
-acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action)
+acpi_status
+acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action)
{
acpi_status status = AE_OK;
struct acpi_gpe_event_info *gpe_event_info;
@@ -567,7 +569,7 @@ acpi_install_gpe_block(acpi_handle gpe_device,
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
- return (status);
+ return_ACPI_STATUS(status);
}
node = acpi_ns_validate_handle(gpe_device);
@@ -650,7 +652,7 @@ acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
- return (status);
+ return_ACPI_STATUS(status);
}
node = acpi_ns_validate_handle(gpe_device);
@@ -694,8 +696,7 @@ ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
* the FADT-defined gpe blocks. Otherwise, the GPE block device.
*
******************************************************************************/
-acpi_status
-acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
+acpi_status acpi_get_gpe_device(u32 index, acpi_handle * gpe_device)
{
struct acpi_gpe_device_info info;
acpi_status status;
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c
index bfb062e4c4b..4492a4e0302 100644
--- a/drivers/acpi/acpica/exconvrt.c
+++ b/drivers/acpi/acpica/exconvrt.c
@@ -516,8 +516,8 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
string_length--;
}
- return_desc = acpi_ut_create_string_object((acpi_size)
- string_length);
+ return_desc =
+ acpi_ut_create_string_object((acpi_size) string_length);
if (!return_desc) {
return_ACPI_STATUS(AE_NO_MEMORY);
}
diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c
index 691d4763102..66554bc6f9a 100644
--- a/drivers/acpi/acpica/excreate.c
+++ b/drivers/acpi/acpica/excreate.c
@@ -78,7 +78,7 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
(target_node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
/*
* Dereference an existing alias so that we don't create a chain
- * of aliases. With this code, we guarantee that an alias is
+ * of aliases. With this code, we guarantee that an alias is
* always exactly one level of indirection away from the
* actual aliased name.
*/
@@ -90,7 +90,7 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
/*
* For objects that can never change (i.e., the NS node will
* permanently point to the same object), we can simply attach
- * the object to the new NS node. For other objects (such as
+ * the object to the new NS node. For other objects (such as
* Integers, buffers, etc.), we have to point the Alias node
* to the original Node.
*/
@@ -139,7 +139,7 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
/*
* The new alias assumes the type of the target, and it points
- * to the same object. The reference count of the object has an
+ * to the same object. The reference count of the object has an
* additional reference to prevent deletion out from under either the
* target node or the alias Node
*/
@@ -243,8 +243,7 @@ acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state)
/* Init object and attach to NS node */
- obj_desc->mutex.sync_level =
- (u8) walk_state->operands[1]->integer.value;
+ obj_desc->mutex.sync_level = (u8)walk_state->operands[1]->integer.value;
obj_desc->mutex.node =
(struct acpi_namespace_node *)walk_state->operands[0];
diff --git a/drivers/acpi/acpica/exdebug.c b/drivers/acpi/acpica/exdebug.c
index bc5b9a6a131..d7c9f51608a 100644
--- a/drivers/acpi/acpica/exdebug.c
+++ b/drivers/acpi/acpica/exdebug.c
@@ -145,10 +145,10 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
case ACPI_TYPE_BUFFER:
acpi_os_printf("[0x%.2X]\n", (u32)source_desc->buffer.length);
- acpi_ut_dump_buffer2(source_desc->buffer.pointer,
- (source_desc->buffer.length < 256) ?
- source_desc->buffer.length : 256,
- DB_BYTE_DISPLAY);
+ acpi_ut_dump_buffer(source_desc->buffer.pointer,
+ (source_desc->buffer.length < 256) ?
+ source_desc->buffer.length : 256,
+ DB_BYTE_DISPLAY, 0);
break;
case ACPI_TYPE_STRING:
@@ -190,7 +190,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
acpi_os_printf("Table Index 0x%X\n",
source_desc->reference.value);
- return;
+ return_VOID;
default:
break;
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c
index 213c081776f..858b43a7dcf 100644
--- a/drivers/acpi/acpica/exdump.c
+++ b/drivers/acpi/acpica/exdump.c
@@ -464,7 +464,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
ACPI_FUNCTION_NAME(ex_dump_operand)
- if (!((ACPI_LV_EXEC & acpi_dbg_level)
+ if (!
+ ((ACPI_LV_EXEC & acpi_dbg_level)
&& (_COMPONENT & acpi_dbg_layer))) {
return;
}
@@ -777,7 +778,7 @@ acpi_ex_dump_operands(union acpi_operand_object **operands,
* PARAMETERS: title - Descriptive text
* value - Value to be displayed
*
- * DESCRIPTION: Object dump output formatting functions. These functions
+ * DESCRIPTION: Object dump output formatting functions. These functions
* reduce the number of format strings required and keeps them
* all in one place for easy modification.
*
@@ -810,7 +811,8 @@ void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags)
ACPI_FUNCTION_ENTRY();
if (!flags) {
- if (!((ACPI_LV_OBJECTS & acpi_dbg_level)
+ if (!
+ ((ACPI_LV_OBJECTS & acpi_dbg_level)
&& (_COMPONENT & acpi_dbg_layer))) {
return;
}
@@ -940,10 +942,11 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
acpi_os_printf("[Buffer] Length %.2X = ",
obj_desc->buffer.length);
if (obj_desc->buffer.length) {
- acpi_ut_dump_buffer(ACPI_CAST_PTR
- (u8, obj_desc->buffer.pointer),
- obj_desc->buffer.length,
- DB_DWORD_DISPLAY, _COMPONENT);
+ acpi_ut_debug_dump_buffer(ACPI_CAST_PTR
+ (u8,
+ obj_desc->buffer.pointer),
+ obj_desc->buffer.length,
+ DB_DWORD_DISPLAY, _COMPONENT);
} else {
acpi_os_printf("\n");
}
@@ -996,7 +999,8 @@ acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags)
}
if (!flags) {
- if (!((ACPI_LV_OBJECTS & acpi_dbg_level)
+ if (!
+ ((ACPI_LV_OBJECTS & acpi_dbg_level)
&& (_COMPONENT & acpi_dbg_layer))) {
return_VOID;
}
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
index dc092f5b35d..ebc55fbf3ff 100644
--- a/drivers/acpi/acpica/exfield.c
+++ b/drivers/acpi/acpica/exfield.c
@@ -59,7 +59,7 @@ ACPI_MODULE_NAME("exfield")
*
* RETURN: Status
*
- * DESCRIPTION: Read from a named field. Returns either an Integer or a
+ * DESCRIPTION: Read from a named field. Returns either an Integer or a
* Buffer, depending on the size of the field.
*
******************************************************************************/
@@ -149,7 +149,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
* Allocate a buffer for the contents of the field.
*
* If the field is larger than the current integer width, create
- * a BUFFER to hold it. Otherwise, use an INTEGER. This allows
+ * a BUFFER to hold it. Otherwise, use an INTEGER. This allows
* the use of arithmetic operators on the returned value if the
* field size is equal or smaller than an Integer.
*
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c
index a7784152ed3..aa2ccfb7cb6 100644
--- a/drivers/acpi/acpica/exfldio.c
+++ b/drivers/acpi/acpica/exfldio.c
@@ -54,8 +54,7 @@ ACPI_MODULE_NAME("exfldio")
/* Local prototypes */
static acpi_status
acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
- u32 field_datum_byte_offset,
- u64 *value, u32 read_write);
+ u32 field_datum_byte_offset, u64 *value, u32 read_write);
static u8
acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value);
@@ -155,7 +154,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
#endif
/*
- * Validate the request. The entire request from the byte offset for a
+ * Validate the request. The entire request from the byte offset for a
* length of one field datum (access width) must fit within the region.
* (Region length is specified in bytes)
*/
@@ -183,7 +182,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
obj_desc->common_field.access_byte_width) {
/*
* This is the case where the access_type (acc_word, etc.) is wider
- * than the region itself. For example, a region of length one
+ * than the region itself. For example, a region of length one
* byte, and a field with Dword access specified.
*/
ACPI_ERROR((AE_INFO,
@@ -321,7 +320,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
*
* DESCRIPTION: Check if a value is out of range of the field being written.
* Used to check if the values written to Index and Bank registers
- * are out of range. Normally, the value is simply truncated
+ * are out of range. Normally, the value is simply truncated
* to fit the field, but this case is most likely a serious
* coding error in the ASL.
*
@@ -370,7 +369,7 @@ acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value)
*
* RETURN: Status
*
- * DESCRIPTION: Read or Write a single datum of a field. The field_type is
+ * DESCRIPTION: Read or Write a single datum of a field. The field_type is
* demultiplexed here to handle the different types of fields
* (buffer_field, region_field, index_field, bank_field)
*
@@ -860,7 +859,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length);
/*
* We must have a buffer that is at least as long as the field
- * we are writing to. This is because individual fields are
+ * we are writing to. This is because individual fields are
* indivisible and partial writes are not supported -- as per
* the ACPI specification.
*/
@@ -875,7 +874,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
/*
* Copy the original data to the new buffer, starting
- * at Byte zero. All unused (upper) bytes of the
+ * at Byte zero. All unused (upper) bytes of the
* buffer will be 0.
*/
ACPI_MEMCPY((char *)new_buffer, (char *)buffer, buffer_length);
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c
index 271c0c57ea1..84058705ed1 100644
--- a/drivers/acpi/acpica/exmisc.c
+++ b/drivers/acpi/acpica/exmisc.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
@@ -254,7 +253,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
ACPI_FUNCTION_TRACE(ex_do_concatenate);
/*
- * Convert the second operand if necessary. The first operand
+ * Convert the second operand if necessary. The first operand
* determines the type of the second operand, (See the Data Types
* section of the ACPI specification.) Both object types are
* guaranteed to be either Integer/String/Buffer by the operand
@@ -573,7 +572,7 @@ acpi_ex_do_logical_op(u16 opcode,
ACPI_FUNCTION_TRACE(ex_do_logical_op);
/*
- * Convert the second operand if necessary. The first operand
+ * Convert the second operand if necessary. The first operand
* determines the type of the second operand, (See the Data Types
* section of the ACPI 3.0+ specification.) Both object types are
* guaranteed to be either Integer/String/Buffer by the operand
diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c
index bcceda5be9e..d1f449d93dc 100644
--- a/drivers/acpi/acpica/exmutex.c
+++ b/drivers/acpi/acpica/exmutex.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exmutex - ASL Mutex Acquire/Release functions
@@ -305,7 +304,7 @@ acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc)
ACPI_FUNCTION_TRACE(ex_release_mutex_object);
if (obj_desc->mutex.acquisition_depth == 0) {
- return (AE_NOT_ACQUIRED);
+ return_ACPI_STATUS(AE_NOT_ACQUIRED);
}
/* Match multiple Acquires with multiple Releases */
@@ -462,7 +461,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
union acpi_operand_object *next = thread->acquired_mutex_list;
union acpi_operand_object *obj_desc;
- ACPI_FUNCTION_ENTRY();
+ ACPI_FUNCTION_NAME(ex_release_all_mutexes);
/* Traverse the list of owned mutexes, releasing each one */
@@ -474,6 +473,10 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
obj_desc->mutex.next = NULL;
obj_desc->mutex.acquisition_depth = 0;
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Force-releasing held mutex: %p\n",
+ obj_desc));
+
/* Release the mutex, special case for Global Lock */
if (obj_desc == acpi_gbl_global_lock_mutex) {
diff --git a/drivers/acpi/acpica/exnames.c b/drivers/acpi/acpica/exnames.c
index fcc75fa27d3..2ff578a16ad 100644
--- a/drivers/acpi/acpica/exnames.c
+++ b/drivers/acpi/acpica/exnames.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exnames - interpreter/scanner name load/execute
@@ -53,8 +52,7 @@ ACPI_MODULE_NAME("exnames")
/* Local prototypes */
static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs);
-static acpi_status
-acpi_ex_name_segment(u8 ** in_aml_address, char *name_string);
+static acpi_status acpi_ex_name_segment(u8 **in_aml_address, char *name_string);
/*******************************************************************************
*
@@ -64,7 +62,7 @@ acpi_ex_name_segment(u8 ** in_aml_address, char *name_string);
* (-1)==root, 0==none
* num_name_segs - count of 4-character name segments
*
- * RETURN: A pointer to the allocated string segment. This segment must
+ * RETURN: A pointer to the allocated string segment. This segment must
* be deleted by the caller.
*
* DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
@@ -178,7 +176,8 @@ static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string)
ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "Bytes from stream:\n"));
- for (index = 0; (index < ACPI_NAME_SIZE)
+ for (index = 0;
+ (index < ACPI_NAME_SIZE)
&& (acpi_ut_valid_acpi_char(*aml_address, 0)); index++) {
char_buf[index] = *aml_address++;
ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "%c\n", char_buf[index]));
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c
index 9ba8c73cea1..bbf01e9bf05 100644
--- a/drivers/acpi/acpica/exoparg1.c
+++ b/drivers/acpi/acpica/exoparg1.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exoparg1 - AML execution - opcodes with 1 argument
@@ -606,7 +605,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
}
/*
- * Set result to ONES (TRUE) if Value == 0. Note:
+ * Set result to ONES (TRUE) if Value == 0. Note:
* return_desc->Integer.Value is initially == 0 (FALSE) from above.
*/
if (!operand[0]->integer.value) {
@@ -618,7 +617,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
case AML_INCREMENT_OP: /* Increment (Operand) */
/*
- * Create a new integer. Can't just get the base integer and
+ * Create a new integer. Can't just get the base integer and
* increment it because it may be an Arg or Field.
*/
return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
@@ -686,7 +685,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
/*
* Note: The operand is not resolved at this point because we want to
- * get the associated object, not its value. For example, we don't
+ * get the associated object, not its value. For example, we don't
* want to resolve a field_unit to its value, we want the actual
* field_unit object.
*/
@@ -727,7 +726,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
/*
* The type of the base object must be integer, buffer, string, or
- * package. All others are not supported.
+ * package. All others are not supported.
*
* NOTE: Integer is not specifically supported by the ACPI spec,
* but is supported implicitly via implicit operand conversion.
@@ -965,7 +964,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
case ACPI_TYPE_PACKAGE:
/*
- * Return the referenced element of the package. We must
+ * Return the referenced element of the package. We must
* add another reference to the referenced object, however.
*/
return_desc =
diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c
index 879e8a277b9..ee5634a074c 100644
--- a/drivers/acpi/acpica/exoparg2.c
+++ b/drivers/acpi/acpica/exoparg2.c
@@ -123,7 +123,7 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state)
/*
* Dispatch the notify to the appropriate handler
* NOTE: the request is queued for execution after this method
- * completes. The notify handlers are NOT invoked synchronously
+ * completes. The notify handlers are NOT invoked synchronously
* from this thread -- because handlers may in turn run other
* control methods.
*/
diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c
index 71fcc65c9ff..2c89b4651f0 100644
--- a/drivers/acpi/acpica/exoparg3.c
+++ b/drivers/acpi/acpica/exoparg3.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exoparg3 - AML execution - opcodes with 3 arguments
@@ -158,7 +157,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state)
case AML_MID_OP: /* Mid (Source[0], Index[1], Length[2], Result[3]) */
/*
- * Create the return object. The Source operand is guaranteed to be
+ * Create the return object. The Source operand is guaranteed to be
* either a String or a Buffer, so just use its type.
*/
return_desc = acpi_ut_create_internal_object((operand[0])->
diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c
index 0786b865906..3e08695c3b3 100644
--- a/drivers/acpi/acpica/exoparg6.c
+++ b/drivers/acpi/acpica/exoparg6.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exoparg6 - AML execution - opcodes with 6 arguments
@@ -198,7 +197,7 @@ acpi_ex_do_match(u32 match_op,
return (FALSE);
}
- return logical_result;
+ return (logical_result);
}
/*******************************************************************************
@@ -269,7 +268,7 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state)
* and the next should be examined.
*
* Upon finding a match, the loop will terminate via "break" at
- * the bottom. If it terminates "normally", match_value will be
+ * the bottom. If it terminates "normally", match_value will be
* ACPI_UINT64_MAX (Ones) (its initial value) indicating that no
* match was found.
*/
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c
index 81eca60d274..ba9db4de7c8 100644
--- a/drivers/acpi/acpica/exprep.c
+++ b/drivers/acpi/acpica/exprep.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exprep - ACPI AML (p-code) execution - field prep utilities
@@ -78,8 +77,8 @@ acpi_ex_generate_access(u32 field_bit_offset,
* any_acc keyword.
*
* NOTE: Need to have the region_length in order to check for boundary
- * conditions (end-of-region). However, the region_length is a deferred
- * operation. Therefore, to complete this implementation, the generation
+ * conditions (end-of-region). However, the region_length is a deferred
+ * operation. Therefore, to complete this implementation, the generation
* of this access width must be deferred until the region length has
* been evaluated.
*
@@ -308,7 +307,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
* RETURN: Status
*
* DESCRIPTION: Initialize the areas of the field object that are common
- * to the various types of fields. Note: This is very "sensitive"
+ * to the various types of fields. Note: This is very "sensitive"
* code because we are solving the general case for field
* alignment.
*
@@ -336,13 +335,13 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,
obj_desc->common_field.bit_length = field_bit_length;
/*
- * Decode the access type so we can compute offsets. The access type gives
+ * Decode the access type so we can compute offsets. The access type gives
* two pieces of information - the width of each field access and the
* necessary byte_alignment (address granularity) of the access.
*
* For any_acc, the access_bit_width is the largest width that is both
* necessary and possible in an attempt to access the whole field in one
- * I/O operation. However, for any_acc, the byte_alignment is always one
+ * I/O operation. However, for any_acc, the byte_alignment is always one
* byte.
*
* For all Buffer Fields, the byte_alignment is always one byte.
@@ -363,7 +362,7 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,
/*
* base_byte_offset is the address of the start of the field within the
- * region. It is the byte address of the first *datum* (field-width data
+ * region. It is the byte address of the first *datum* (field-width data
* unit) of the field. (i.e., the first datum that contains at least the
* first *bit* of the field.)
*
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c
index 1f1ce0c3d2f..1db2c0bfde0 100644
--- a/drivers/acpi/acpica/exregion.c
+++ b/drivers/acpi/acpica/exregion.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exregion - ACPI default op_region (address space) handlers
@@ -202,7 +201,7 @@ acpi_ex_system_memory_space_handler(u32 function,
* Perform the memory read or write
*
* Note: For machines that do not support non-aligned transfers, the target
- * address was checked for alignment above. We do not attempt to break the
+ * address was checked for alignment above. We do not attempt to break the
* transfer up into smaller (byte-size) chunks because the AML specifically
* asked for a transfer width that the hardware may require.
*/
diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c
index fa50e77e64a..6239956786e 100644
--- a/drivers/acpi/acpica/exresnte.c
+++ b/drivers/acpi/acpica/exresnte.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exresnte - AML Interpreter object resolution
@@ -58,8 +57,8 @@ ACPI_MODULE_NAME("exresnte")
* PARAMETERS: object_ptr - Pointer to a location that contains
* a pointer to a NS node, and will receive a
* pointer to the resolved object.
- * walk_state - Current state. Valid only if executing AML
- * code. NULL if simply resolving an object
+ * walk_state - Current state. Valid only if executing AML
+ * code. NULL if simply resolving an object
*
* RETURN: Status
*
@@ -67,7 +66,7 @@ ACPI_MODULE_NAME("exresnte")
*
* Note: for some of the data types, the pointer attached to the Node
* can be either a pointer to an actual internal object or a pointer into the
- * AML stream itself. These types are currently:
+ * AML stream itself. These types are currently:
*
* ACPI_TYPE_INTEGER
* ACPI_TYPE_STRING
@@ -89,7 +88,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
ACPI_FUNCTION_TRACE(ex_resolve_node_to_value);
/*
- * The stack pointer points to a struct acpi_namespace_node (Node). Get the
+ * The stack pointer points to a struct acpi_namespace_node (Node). Get the
* object that is attached to the Node.
*/
node = *object_ptr;
diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c
index bbf40ac2758..cc176b245e2 100644
--- a/drivers/acpi/acpica/exresolv.c
+++ b/drivers/acpi/acpica/exresolv.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exresolv - AML Interpreter object resolution
@@ -327,7 +326,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
*
* RETURN: Status
*
- * DESCRIPTION: Return the base object and type. Traverse a reference list if
+ * DESCRIPTION: Return the base object and type. Traverse a reference list if
* necessary to get to the base object.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c
index f232fbabdea..b9ebff2f6a0 100644
--- a/drivers/acpi/acpica/exresop.c
+++ b/drivers/acpi/acpica/exresop.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exresop - AML Interpreter operand/object resolution
@@ -87,7 +86,7 @@ acpi_ex_check_object_type(acpi_object_type type_needed,
if (type_needed == ACPI_TYPE_LOCAL_REFERENCE) {
/*
* Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference
- * objects and thus allow them to be targets. (As per the ACPI
+ * objects and thus allow them to be targets. (As per the ACPI
* specification, a store to a constant is a noop.)
*/
if ((this_type == ACPI_TYPE_INTEGER) &&
@@ -337,7 +336,8 @@ acpi_ex_resolve_operands(u16 opcode,
if ((opcode == AML_STORE_OP) &&
((*stack_ptr)->common.type ==
ACPI_TYPE_LOCAL_REFERENCE)
- && ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) {
+ && ((*stack_ptr)->reference.class ==
+ ACPI_REFCLASS_INDEX)) {
goto next_operand;
}
break;
@@ -638,7 +638,7 @@ acpi_ex_resolve_operands(u16 opcode,
if (acpi_gbl_enable_interpreter_slack) {
/*
* Enable original behavior of Store(), allowing any and all
- * objects as the source operand. The ACPI spec does not
+ * objects as the source operand. The ACPI spec does not
* allow this, however.
*/
break;
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c
index 5fffe7ab5ec..90431f12f83 100644
--- a/drivers/acpi/acpica/exstore.c
+++ b/drivers/acpi/acpica/exstore.c
@@ -374,7 +374,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
* with the input value.
*
* When storing into an object the data is converted to the
- * target object type then stored in the object. This means
+ * target object type then stored in the object. This means
* that the target object type (for an initialized target) will
* not be changed by a store operation.
*
@@ -491,7 +491,7 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
acpi_ut_get_object_type_name(source_desc),
source_desc, node));
- /* No conversions for all other types. Just attach the source object */
+ /* No conversions for all other types. Just attach the source object */
status = acpi_ns_attach_object(node, source_desc,
source_desc->common.type);
diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c
index b35bed52e06..87153bbc4b4 100644
--- a/drivers/acpi/acpica/exstoren.c
+++ b/drivers/acpi/acpica/exstoren.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exstoren - AML Interpreter object store support,
@@ -61,7 +60,7 @@ ACPI_MODULE_NAME("exstoren")
*
* RETURN: Status, resolved object in source_desc_ptr.
*
- * DESCRIPTION: Resolve an object. If the object is a reference, dereference
+ * DESCRIPTION: Resolve an object. If the object is a reference, dereference
* it and return the actual object in the source_desc_ptr.
*
******************************************************************************/
@@ -93,7 +92,7 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
/*
* Stores into a Field/Region or into a Integer/Buffer/String
- * are all essentially the same. This case handles the
+ * are all essentially the same. This case handles the
* "interchangeable" types Integer, String, and Buffer.
*/
if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
@@ -167,7 +166,7 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
*
* RETURN: Status
*
- * DESCRIPTION: "Store" an object to another object. This may include
+ * DESCRIPTION: "Store" an object to another object. This may include
* converting the source type to the target type (implicit
* conversion), and a copy of the value of the source to
* the target.
@@ -178,14 +177,14 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
* with the input value.
*
* When storing into an object the data is converted to the
- * target object type then stored in the object. This means
+ * target object type then stored in the object. This means
* that the target object type (for an initialized target) will
* not be changed by a store operation.
*
* This module allows destination types of Number, String,
* Buffer, and Package.
*
- * Assumes parameters are already validated. NOTE: source_desc
+ * Assumes parameters are already validated. NOTE: source_desc
* resolution (from a reference object) must be performed by
* the caller if necessary.
*
diff --git a/drivers/acpi/acpica/exstorob.c b/drivers/acpi/acpica/exstorob.c
index 53c24847354..b5f339cb130 100644
--- a/drivers/acpi/acpica/exstorob.c
+++ b/drivers/acpi/acpica/exstorob.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exstorob - AML Interpreter object store support, store to object
@@ -108,7 +107,7 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc,
#ifdef ACPI_OBSOLETE_BEHAVIOR
/*
* NOTE: ACPI versions up to 3.0 specified that the buffer must be
- * truncated if the string is smaller than the buffer. However, "other"
+ * truncated if the string is smaller than the buffer. However, "other"
* implementations of ACPI never did this and thus became the defacto
* standard. ACPI 3.0A changes this behavior such that the buffer
* is no longer truncated.
@@ -117,7 +116,7 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc,
/*
* OBSOLETE BEHAVIOR:
* If the original source was a string, we must truncate the buffer,
- * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer
+ * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer
* copy must not truncate the original buffer.
*/
if (original_src_type == ACPI_TYPE_STRING) {
diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c
index b760641e2fc..c8a0ad5c1f5 100644
--- a/drivers/acpi/acpica/exsystem.c
+++ b/drivers/acpi/acpica/exsystem.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exsystem - Interface to OS services
@@ -59,7 +58,7 @@ ACPI_MODULE_NAME("exsystem")
* RETURN: Status
*
* DESCRIPTION: Implements a semaphore wait with a check to see if the
- * semaphore is available immediately. If it is not, the
+ * semaphore is available immediately. If it is not, the
* interpreter is released before waiting.
*
******************************************************************************/
@@ -104,7 +103,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
* RETURN: Status
*
* DESCRIPTION: Implements a mutex wait with a check to see if the
- * mutex is available immediately. If it is not, the
+ * mutex is available immediately. If it is not, the
* interpreter is released before waiting.
*
******************************************************************************/
@@ -152,7 +151,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
* DESCRIPTION: Suspend running thread for specified amount of time.
* Note: ACPI specification requires that Stall() does not
* relinquish the processor, and delays longer than 100 usec
- * should use Sleep() instead. We allow stalls up to 255 usec
+ * should use Sleep() instead. We allow stalls up to 255 usec
* for compatibility with other interpreters and existing BIOSs.
*
******************************************************************************/
@@ -254,7 +253,7 @@ acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc)
* RETURN: Status
*
* DESCRIPTION: Provides an access point to perform synchronization operations
- * within the AML. This operation is a request to wait for an
+ * within the AML. This operation is a request to wait for an
* event.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c
index d1ab7917eed..264d22d8018 100644
--- a/drivers/acpi/acpica/exutils.c
+++ b/drivers/acpi/acpica/exutils.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: exutils - interpreter/scanner utilities
@@ -45,12 +44,12 @@
/*
* DEFINE_AML_GLOBALS is tested in amlcode.h
* to determine whether certain global names should be "defined" or only
- * "declared" in the current compilation. This enhances maintainability
+ * "declared" in the current compilation. This enhances maintainability
* by enabling a single header file to embody all knowledge of the names
* in question.
*
* Exactly one module of any executable should #define DEFINE_GLOBALS
- * before #including the header files which use this convention. The
+ * before #including the header files which use this convention. The
* names in question will be defined and initialized in that module,
* and declared as extern in all other modules which #include those
* header files.
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c
index a1e71d0ef57..90a9aea1cee 100644
--- a/drivers/acpi/acpica/hwacpi.c
+++ b/drivers/acpi/acpica/hwacpi.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface
@@ -136,7 +135,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
*
* RETURN: SYS_MODE_ACPI or SYS_MODE_LEGACY
*
- * DESCRIPTION: Return current operating state of system. Determined by
+ * DESCRIPTION: Return current operating state of system. Determined by
* querying the SCI_EN bit.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index db4076580e2..64560045052 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: hwgpe - Low level GPE enable/disable/clear functions
@@ -339,7 +338,8 @@ acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
acpi_status
acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block, void *context)
+ struct acpi_gpe_block_info * gpe_block,
+ void *context)
{
u32 i;
acpi_status status;
diff --git a/drivers/acpi/acpica/hwpci.c b/drivers/acpi/acpica/hwpci.c
index 1455ddcdc32..65bc3453a29 100644
--- a/drivers/acpi/acpica/hwpci.c
+++ b/drivers/acpi/acpica/hwpci.c
@@ -259,7 +259,7 @@ acpi_hw_process_pci_list(struct acpi_pci_id *pci_id,
status = acpi_hw_get_pci_device_info(pci_id, info->device,
&bus_number, &is_bridge);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ return (status);
}
info = info->next;
@@ -271,7 +271,7 @@ acpi_hw_process_pci_list(struct acpi_pci_id *pci_id,
pci_id->segment, pci_id->bus, pci_id->device,
pci_id->function, status, bus_number, is_bridge));
- return_ACPI_STATUS(AE_OK);
+ return (AE_OK);
}
/*******************************************************************************
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c
index 4af6d20ef07..f4e57503576 100644
--- a/drivers/acpi/acpica/hwregs.c
+++ b/drivers/acpi/acpica/hwregs.c
@@ -1,4 +1,3 @@
-
/*******************************************************************************
*
* Module Name: hwregs - Read/write access functions for the various ACPI
diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c
index b6411f16832..bfdce22f379 100644
--- a/drivers/acpi/acpica/hwtimer.c
+++ b/drivers/acpi/acpica/hwtimer.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Name: hwtimer.c - ACPI Power Management Timer Interface
@@ -101,8 +100,7 @@ acpi_status acpi_get_timer(u32 * ticks)
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- status =
- acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block);
+ status = acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block);
return_ACPI_STATUS(status);
}
@@ -129,7 +127,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_timer)
* a versatile and accurate timer.
*
* Note that this function accommodates only a single timer
- * rollover. Thus for 24-bit timers, this function should only
+ * rollover. Thus for 24-bit timers, this function should only
* be used for calculating durations less than ~4.6 seconds
* (~20 minutes for 32-bit timers) -- calculations below:
*
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c
index c99d546b217..b6aae58299d 100644
--- a/drivers/acpi/acpica/hwvalid.c
+++ b/drivers/acpi/acpica/hwvalid.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: hwvalid - I/O request validation
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index 7bfd649d199..05a154c3c9a 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Module Name: hwxface - Public ACPICA hardware interfaces
diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c
index 0ff1ecea5c3..ae443fe2ebf 100644
--- a/drivers/acpi/acpica/hwxfsleep.c
+++ b/drivers/acpi/acpica/hwxfsleep.c
@@ -49,8 +49,7 @@
ACPI_MODULE_NAME("hwxfsleep")
/* Local prototypes */
-static acpi_status
-acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id);
+static acpi_status acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id);
/*
* Dispatch table used to efficiently branch to the various sleep
@@ -234,8 +233,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios)
* function.
*
******************************************************************************/
-static acpi_status
-acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id)
+static acpi_status acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id)
{
acpi_status status;
struct acpi_sleep_functions *sleep_functions =
@@ -369,8 +367,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
}
- status =
- acpi_hw_sleep_dispatch(sleep_state, ACPI_SLEEP_FUNCTION_ID);
+ status = acpi_hw_sleep_dispatch(sleep_state, ACPI_SLEEP_FUNCTION_ID);
return_ACPI_STATUS(status);
}
@@ -396,8 +393,7 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
status =
- acpi_hw_sleep_dispatch(sleep_state,
- ACPI_WAKE_PREP_FUNCTION_ID);
+ acpi_hw_sleep_dispatch(sleep_state, ACPI_WAKE_PREP_FUNCTION_ID);
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c
index 23db53ce229..d70eaf39dfd 100644
--- a/drivers/acpi/acpica/nsaccess.c
+++ b/drivers/acpi/acpica/nsaccess.c
@@ -110,11 +110,11 @@ acpi_status acpi_ns_root_initialize(void)
status = acpi_ns_lookup(NULL, init_val->name, init_val->type,
ACPI_IMODE_LOAD_PASS2,
ACPI_NS_NO_UPSEARCH, NULL, &new_node);
-
- if (ACPI_FAILURE(status) || (!new_node)) { /* Must be on same line for code converter */
+ if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Could not create predefined name %s",
init_val->name));
+ continue;
}
/*
@@ -179,8 +179,7 @@ acpi_status acpi_ns_root_initialize(void)
/* Build an object around the static string */
- obj_desc->string.length =
- (u32) ACPI_STRLEN(val);
+ obj_desc->string.length = (u32)ACPI_STRLEN(val);
obj_desc->string.pointer = val;
obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
break;
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c
index ac389e5bb59..15143c44f5e 100644
--- a/drivers/acpi/acpica/nsalloc.c
+++ b/drivers/acpi/acpica/nsalloc.c
@@ -332,7 +332,7 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
*
* RETURN: None.
*
- * DESCRIPTION: Delete a subtree of the namespace. This includes all objects
+ * DESCRIPTION: Delete a subtree of the namespace. This includes all objects
* stored within the subtree.
*
******************************************************************************/
@@ -418,7 +418,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
* RETURN: Status
*
* DESCRIPTION: Delete entries within the namespace that are owned by a
- * specific ID. Used to delete entire ACPI tables. All
+ * specific ID. Used to delete entire ACPI tables. All
* reference counts are updated.
*
* MUTEX: Locks namespace during deletion walk.
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c
index 2526aaf945e..924b3c71473 100644
--- a/drivers/acpi/acpica/nsdump.c
+++ b/drivers/acpi/acpica/nsdump.c
@@ -209,14 +209,6 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
"Invalid ACPI Object Type 0x%08X", type));
}
- if (!acpi_ut_valid_acpi_name(this_node->name.integer)) {
- this_node->name.integer =
- acpi_ut_repair_name(this_node->name.ascii);
-
- ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X",
- this_node->name.integer));
- }
-
acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node));
}
@@ -700,7 +692,7 @@ void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level)
*
* PARAMETERS: search_base - Root of subtree to be dumped, or
* NS_ALL to dump the entire namespace
- * max_depth - Maximum depth of dump. Use INT_MAX
+ * max_depth - Maximum depth of dump. Use INT_MAX
* for an effectively unlimited depth.
*
* RETURN: None
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c
index 95ffe8dfa1f..4328e2adfeb 100644
--- a/drivers/acpi/acpica/nsinit.c
+++ b/drivers/acpi/acpica/nsinit.c
@@ -96,8 +96,8 @@ acpi_status acpi_ns_initialize_objects(void)
/* Walk entire namespace from the supplied root */
status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, acpi_ns_init_one_object, NULL,
- &info, NULL);
+ ACPI_UINT32_MAX, acpi_ns_init_one_object,
+ NULL, &info, NULL);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
}
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c
index 76935ff2928..911f99127b9 100644
--- a/drivers/acpi/acpica/nsload.c
+++ b/drivers/acpi/acpica/nsload.c
@@ -80,8 +80,8 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
/*
* Parse the table and load the namespace with all named
- * objects found within. Control methods are NOT parsed
- * at this time. In fact, the control methods cannot be
+ * objects found within. Control methods are NOT parsed
+ * at this time. In fact, the control methods cannot be
* parsed until the entire namespace is loaded, because
* if a control method makes a forward reference (call)
* to another control method, we can't continue parsing
@@ -122,7 +122,7 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
}
/*
- * Now we can parse the control methods. We always parse
+ * Now we can parse the control methods. We always parse
* them here for a sanity check, and if configured for
* just-in-time parsing, we delete the control method
* parse trees.
@@ -166,7 +166,7 @@ acpi_status acpi_ns_load_namespace(void)
}
/*
- * Load the namespace. The DSDT is required,
+ * Load the namespace. The DSDT is required,
* but the SSDT and PSDT tables are optional.
*/
status = acpi_ns_load_table_by_type(ACPI_TABLE_ID_DSDT);
@@ -283,7 +283,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle)
* RETURN: Status
*
* DESCRIPTION: Shrinks the namespace, typically in response to an undocking
- * event. Deletes an entire subtree starting from (and
+ * event. Deletes an entire subtree starting from (and
* including) the given handle.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c
index 96e0eb609bb..55a175eadcc 100644
--- a/drivers/acpi/acpica/nsnames.c
+++ b/drivers/acpi/acpica/nsnames.c
@@ -195,7 +195,7 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
ACPI_ERROR((AE_INFO,
"Invalid Namespace Node (%p) while traversing namespace",
next_node));
- return 0;
+ return (0);
}
size += ACPI_PATH_SEGMENT_LENGTH;
next_node = next_node->parent;
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c
index d6c9a3cc671..e69f7fa2579 100644
--- a/drivers/acpi/acpica/nsobject.c
+++ b/drivers/acpi/acpica/nsobject.c
@@ -61,7 +61,7 @@ ACPI_MODULE_NAME("nsobject")
* RETURN: Status
*
* DESCRIPTION: Record the given object as the value associated with the
- * name whose acpi_handle is passed. If Object is NULL
+ * name whose acpi_handle is passed. If Object is NULL
* and Type is ACPI_TYPE_ANY, set the name as having no value.
* Note: Future may require that the Node->Flags field be passed
* as a parameter.
@@ -133,7 +133,7 @@ acpi_ns_attach_object(struct acpi_namespace_node *node,
((struct acpi_namespace_node *)object)->object) {
/*
* Value passed is a name handle and that name has a
- * non-null value. Use that name's value and type.
+ * non-null value. Use that name's value and type.
*/
obj_desc = ((struct acpi_namespace_node *)object)->object;
object_type = ((struct acpi_namespace_node *)object)->type;
@@ -321,7 +321,7 @@ union acpi_operand_object *acpi_ns_get_secondary_object(union
*
* RETURN: Status
*
- * DESCRIPTION: Low-level attach data. Create and attach a Data object.
+ * DESCRIPTION: Low-level attach data. Create and attach a Data object.
*
******************************************************************************/
@@ -377,7 +377,7 @@ acpi_ns_attach_data(struct acpi_namespace_node *node,
*
* RETURN: Status
*
- * DESCRIPTION: Low-level detach data. Delete the data node, but the caller
+ * DESCRIPTION: Low-level detach data. Delete the data node, but the caller
* is responsible for the actual data.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c
index ec7ba2d3463..233f756d5cf 100644
--- a/drivers/acpi/acpica/nsparse.c
+++ b/drivers/acpi/acpica/nsparse.c
@@ -168,11 +168,11 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
/*
* AML Parse, pass 1
*
- * In this pass, we load most of the namespace. Control methods
- * are not parsed until later. A parse tree is not created. Instead,
- * each Parser Op subtree is deleted when it is finished. This saves
+ * In this pass, we load most of the namespace. Control methods
+ * are not parsed until later. A parse tree is not created. Instead,
+ * each Parser Op subtree is deleted when it is finished. This saves
* a great deal of memory, and allows a small cache of parse objects
- * to service the entire parse. The second pass of the parse then
+ * to service the entire parse. The second pass of the parse then
* performs another complete parse of the AML.
*/
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c
index 456cc859f86..1d2d8ffc1bc 100644
--- a/drivers/acpi/acpica/nssearch.c
+++ b/drivers/acpi/acpica/nssearch.c
@@ -314,22 +314,7 @@ acpi_ns_search_and_enter(u32 target_name,
* this problem, and we want to be able to enable ACPI support for them,
* even though there are a few bad names.
*/
- if (!acpi_ut_valid_acpi_name(target_name)) {
- target_name =
- acpi_ut_repair_name(ACPI_CAST_PTR(char, &target_name));
-
- /* Report warning only if in strict mode or debug mode */
-
- if (!acpi_gbl_enable_interpreter_slack) {
- ACPI_WARNING((AE_INFO,
- "Found bad character(s) in name, repaired: [%4.4s]\n",
- ACPI_CAST_PTR(char, &target_name)));
- } else {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Found bad character(s) in name, repaired: [%4.4s]\n",
- ACPI_CAST_PTR(char, &target_name)));
- }
- }
+ acpi_ut_repair_name(ACPI_CAST_PTR(char, &target_name));
/* Try to find the name in the namespace level specified by the caller */
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c
index ef753a41e08..b5b4cb72a8a 100644
--- a/drivers/acpi/acpica/nsutils.c
+++ b/drivers/acpi/acpica/nsutils.c
@@ -530,7 +530,7 @@ acpi_ns_externalize_name(u32 internal_name_length,
((num_segments > 0) ? (num_segments - 1) : 0) + 1;
/*
- * Check to see if we're still in bounds. If not, there's a problem
+ * Check to see if we're still in bounds. If not, there's a problem
* with internal_name (invalid format).
*/
if (required_length > internal_name_length) {
@@ -557,10 +557,14 @@ acpi_ns_externalize_name(u32 internal_name_length,
(*converted_name)[j++] = '.';
}
- (*converted_name)[j++] = internal_name[names_index++];
- (*converted_name)[j++] = internal_name[names_index++];
- (*converted_name)[j++] = internal_name[names_index++];
- (*converted_name)[j++] = internal_name[names_index++];
+ /* Copy and validate the 4-char name segment */
+
+ ACPI_MOVE_NAME(&(*converted_name)[j],
+ &internal_name[names_index]);
+ acpi_ut_repair_name(&(*converted_name)[j]);
+
+ j += ACPI_NAME_SIZE;
+ names_index += ACPI_NAME_SIZE;
}
}
@@ -681,7 +685,7 @@ u32 acpi_ns_opens_scope(acpi_object_type type)
* \ (backslash) and ^ (carat) prefixes, and the
* . (period) to separate segments are supported.
* prefix_node - Root of subtree to be searched, or NS_ALL for the
- * root of the name space. If Name is fully
+ * root of the name space. If Name is fully
* qualified (first s8 is '\'), the passed value
* of Scope will not be accessed.
* flags - Used to indicate whether to perform upsearch or
@@ -689,7 +693,7 @@ u32 acpi_ns_opens_scope(acpi_object_type type)
* return_node - Where the Node is returned
*
* DESCRIPTION: Look up a name relative to a given scope and return the
- * corresponding Node. NOTE: Scope can be null.
+ * corresponding Node. NOTE: Scope can be null.
*
* MUTEX: Locks namespace
*
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c
index 730bccc5e7f..0483877f26b 100644
--- a/drivers/acpi/acpica/nswalk.c
+++ b/drivers/acpi/acpica/nswalk.c
@@ -60,8 +60,8 @@ ACPI_MODULE_NAME("nswalk")
* RETURN: struct acpi_namespace_node - Pointer to the NEXT child or NULL if
* none is found.
*
- * DESCRIPTION: Return the next peer node within the namespace. If Handle
- * is valid, Scope is ignored. Otherwise, the first node
+ * DESCRIPTION: Return the next peer node within the namespace. If Handle
+ * is valid, Scope is ignored. Otherwise, the first node
* within Scope is returned.
*
******************************************************************************/
@@ -97,8 +97,8 @@ struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node
* RETURN: struct acpi_namespace_node - Pointer to the NEXT child or NULL if
* none is found.
*
- * DESCRIPTION: Return the next peer node within the namespace. If Handle
- * is valid, Scope is ignored. Otherwise, the first node
+ * DESCRIPTION: Return the next peer node within the namespace. If Handle
+ * is valid, Scope is ignored. Otherwise, the first node
* within Scope is returned.
*
******************************************************************************/
@@ -305,7 +305,7 @@ acpi_ns_walk_namespace(acpi_object_type type,
/*
* Depth first search: Attempt to go down another level in the
- * namespace if we are allowed to. Don't go any further if we have
+ * namespace if we are allowed to. Don't go any further if we have
* reached the caller specified maximum depth or if the user
* function has specified that the maximum depth has been reached.
*/
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c
index 9692e670233..d6a9f77972b 100644
--- a/drivers/acpi/acpica/nsxfeval.c
+++ b/drivers/acpi/acpica/nsxfeval.c
@@ -61,16 +61,16 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info);
* PARAMETERS: handle - Object handle (optional)
* pathname - Object pathname (optional)
* external_params - List of parameters to pass to method,
- * terminated by NULL. May be NULL
+ * terminated by NULL. May be NULL
* if no parameters are being passed.
* return_buffer - Where to put method's return value (if
- * any). If NULL, no value is returned.
+ * any). If NULL, no value is returned.
* return_type - Expected type of return object
*
* RETURN: Status
*
* DESCRIPTION: Find and evaluate the given object, passing the given
- * parameters if necessary. One of "Handle" or "Pathname" must
+ * parameters if necessary. One of "Handle" or "Pathname" must
* be valid (non-null)
*
******************************************************************************/
@@ -155,15 +155,15 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed)
* PARAMETERS: handle - Object handle (optional)
* pathname - Object pathname (optional)
* external_params - List of parameters to pass to method,
- * terminated by NULL. May be NULL
+ * terminated by NULL. May be NULL
* if no parameters are being passed.
* return_buffer - Where to put method's return value (if
- * any). If NULL, no value is returned.
+ * any). If NULL, no value is returned.
*
* RETURN: Status
*
* DESCRIPTION: Find and evaluate the given object, passing the given
- * parameters if necessary. One of "Handle" or "Pathname" must
+ * parameters if necessary. One of "Handle" or "Pathname" must
* be valid (non-null)
*
******************************************************************************/
@@ -542,15 +542,15 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
acpi_status status;
struct acpi_namespace_node *node;
u32 flags;
- struct acpica_device_id *hid;
- struct acpica_device_id_list *cid;
+ struct acpi_pnp_device_id *hid;
+ struct acpi_pnp_device_id_list *cid;
u32 i;
u8 found;
int no_match;
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
- return (status);
+ return_ACPI_STATUS(status);
}
node = acpi_ns_validate_handle(obj_handle);
@@ -656,7 +656,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
* DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
* starting (and ending) at the object specified by start_handle.
* The user_function is called whenever an object of type
- * Device is found. If the user function returns
+ * Device is found. If the user function returns
* a non-zero value, the search is terminated immediately and this
* value is returned to the caller.
*
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c
index 08e9610b34c..811c6f13f47 100644
--- a/drivers/acpi/acpica/nsxfname.c
+++ b/drivers/acpi/acpica/nsxfname.c
@@ -53,8 +53,8 @@
ACPI_MODULE_NAME("nsxfname")
/* Local prototypes */
-static char *acpi_ns_copy_device_id(struct acpica_device_id *dest,
- struct acpica_device_id *source,
+static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest,
+ struct acpi_pnp_device_id *source,
char *string_area);
/******************************************************************************
@@ -69,8 +69,8 @@ static char *acpi_ns_copy_device_id(struct acpica_device_id *dest,
* RETURN: Status
*
* DESCRIPTION: This routine will search for a caller specified name in the
- * name space. The caller can restrict the search region by
- * specifying a non NULL parent. The parent value is itself a
+ * name space. The caller can restrict the search region by
+ * specifying a non NULL parent. The parent value is itself a
* namespace handle.
*
******************************************************************************/
@@ -149,7 +149,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_handle)
* RETURN: Pointer to a string containing the fully qualified Name.
*
* DESCRIPTION: This routine returns the fully qualified name associated with
- * the Handle parameter. This and the acpi_pathname_to_handle are
+ * the Handle parameter. This and the acpi_pathname_to_handle are
* complementary functions.
*
******************************************************************************/
@@ -202,8 +202,7 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer)
/* Just copy the ACPI name from the Node and zero terminate it */
- ACPI_STRNCPY(buffer->pointer, acpi_ut_get_node_name(node),
- ACPI_NAME_SIZE);
+ ACPI_MOVE_NAME(buffer->pointer, acpi_ut_get_node_name(node));
((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0;
status = AE_OK;
@@ -219,20 +218,21 @@ ACPI_EXPORT_SYMBOL(acpi_get_name)
*
* FUNCTION: acpi_ns_copy_device_id
*
- * PARAMETERS: dest - Pointer to the destination DEVICE_ID
- * source - Pointer to the source DEVICE_ID
+ * PARAMETERS: dest - Pointer to the destination PNP_DEVICE_ID
+ * source - Pointer to the source PNP_DEVICE_ID
* string_area - Pointer to where to copy the dest string
*
* RETURN: Pointer to the next string area
*
- * DESCRIPTION: Copy a single DEVICE_ID, including the string data.
+ * DESCRIPTION: Copy a single PNP_DEVICE_ID, including the string data.
*
******************************************************************************/
-static char *acpi_ns_copy_device_id(struct acpica_device_id *dest,
- struct acpica_device_id *source,
+static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest,
+ struct acpi_pnp_device_id *source,
char *string_area)
{
- /* Create the destination DEVICE_ID */
+
+ /* Create the destination PNP_DEVICE_ID */
dest->string = string_area;
dest->length = source->length;
@@ -256,8 +256,8 @@ static char *acpi_ns_copy_device_id(struct acpica_device_id *dest,
* namespace node and possibly by running several standard
* control methods (Such as in the case of a device.)
*
- * For Device and Processor objects, run the Device _HID, _UID, _CID, _STA,
- * _ADR, _sx_w, and _sx_d methods.
+ * For Device and Processor objects, run the Device _HID, _UID, _CID, _SUB,
+ * _STA, _ADR, _sx_w, and _sx_d methods.
*
* Note: Allocates the return buffer, must be freed by the caller.
*
@@ -269,9 +269,10 @@ acpi_get_object_info(acpi_handle handle,
{
struct acpi_namespace_node *node;
struct acpi_device_info *info;
- struct acpica_device_id_list *cid_list = NULL;
- struct acpica_device_id *hid = NULL;
- struct acpica_device_id *uid = NULL;
+ struct acpi_pnp_device_id_list *cid_list = NULL;
+ struct acpi_pnp_device_id *hid = NULL;
+ struct acpi_pnp_device_id *uid = NULL;
+ struct acpi_pnp_device_id *sub = NULL;
char *next_id_string;
acpi_object_type type;
acpi_name name;
@@ -316,7 +317,7 @@ acpi_get_object_info(acpi_handle handle,
if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) {
/*
* Get extra info for ACPI Device/Processor objects only:
- * Run the Device _HID, _UID, and _CID methods.
+ * Run the Device _HID, _UID, _SUB, and _CID methods.
*
* Note: none of these methods are required, so they may or may
* not be present for this device. The Info->Valid bitfield is used
@@ -339,6 +340,14 @@ acpi_get_object_info(acpi_handle handle,
valid |= ACPI_VALID_UID;
}
+ /* Execute the Device._SUB method */
+
+ status = acpi_ut_execute_SUB(node, &sub);
+ if (ACPI_SUCCESS(status)) {
+ info_size += sub->length;
+ valid |= ACPI_VALID_SUB;
+ }
+
/* Execute the Device._CID method */
status = acpi_ut_execute_CID(node, &cid_list);
@@ -348,7 +357,7 @@ acpi_get_object_info(acpi_handle handle,
info_size +=
(cid_list->list_size -
- sizeof(struct acpica_device_id_list));
+ sizeof(struct acpi_pnp_device_id_list));
valid |= ACPI_VALID_CID;
}
}
@@ -418,16 +427,17 @@ acpi_get_object_info(acpi_handle handle,
next_id_string = ACPI_CAST_PTR(char, info->compatible_id_list.ids);
if (cid_list) {
- /* Point past the CID DEVICE_ID array */
+ /* Point past the CID PNP_DEVICE_ID array */
next_id_string +=
((acpi_size) cid_list->count *
- sizeof(struct acpica_device_id));
+ sizeof(struct acpi_pnp_device_id));
}
/*
- * Copy the HID, UID, and CIDs to the return buffer. The variable-length
- * strings are copied to the reserved area at the end of the buffer.
+ * Copy the HID, UID, SUB, and CIDs to the return buffer.
+ * The variable-length strings are copied to the reserved area
+ * at the end of the buffer.
*
* For HID and CID, check if the ID is a PCI Root Bridge.
*/
@@ -445,6 +455,11 @@ acpi_get_object_info(acpi_handle handle,
uid, next_id_string);
}
+ if (sub) {
+ next_id_string = acpi_ns_copy_device_id(&info->subsystem_id,
+ sub, next_id_string);
+ }
+
if (cid_list) {
info->compatible_id_list.count = cid_list->count;
info->compatible_id_list.list_size = cid_list->list_size;
@@ -481,6 +496,9 @@ acpi_get_object_info(acpi_handle handle,
if (uid) {
ACPI_FREE(uid);
}
+ if (sub) {
+ ACPI_FREE(sub);
+ }
if (cid_list) {
ACPI_FREE(cid_list);
}
diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c
index 6766fc4f088..9d029dac6b6 100644
--- a/drivers/acpi/acpica/nsxfobj.c
+++ b/drivers/acpi/acpica/nsxfobj.c
@@ -220,8 +220,8 @@ ACPI_EXPORT_SYMBOL(acpi_get_parent)
*
* RETURN: Status
*
- * DESCRIPTION: Return the next peer object within the namespace. If Handle is
- * valid, Scope is ignored. Otherwise, the first object within
+ * DESCRIPTION: Return the next peer object within the namespace. If Handle is
+ * valid, Scope is ignored. Otherwise, the first object within
* Scope is returned.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c
index 844464c4f90..cb79e2d4d74 100644
--- a/drivers/acpi/acpica/psargs.c
+++ b/drivers/acpi/acpica/psargs.c
@@ -120,7 +120,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
* RETURN: Pointer to end-of-package +1
*
* DESCRIPTION: Get next package length and return a pointer past the end of
- * the package. Consumes the package length field
+ * the package. Consumes the package length field
*
******************************************************************************/
@@ -147,8 +147,8 @@ u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
* RETURN: Pointer to the start of the name string (pointer points into
* the AML.
*
- * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
- * prefix characters. Set parser state to point past the string.
+ * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
+ * prefix characters. Set parser state to point past the string.
* (Name is consumed from the AML.)
*
******************************************************************************/
@@ -220,7 +220,7 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
*
* DESCRIPTION: Get next name (if method call, return # of required args).
* Names are looked up in the internal namespace to determine
- * if the name represents a control method. If a method
+ * if the name represents a control method. If a method
* is found, the number of arguments to the method is returned.
* This information is critical for parsing to continue correctly.
*
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c
index 799162c1b6d..5607805aab2 100644
--- a/drivers/acpi/acpica/psloop.c
+++ b/drivers/acpi/acpica/psloop.c
@@ -133,18 +133,46 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
case AML_CLASS_UNKNOWN:
- /* The opcode is unrecognized. Just skip unknown opcodes */
+ /* The opcode is unrecognized. Complain and skip unknown opcodes */
- ACPI_ERROR((AE_INFO,
- "Found unknown opcode 0x%X at AML address %p offset 0x%X, ignoring",
- walk_state->opcode, walk_state->parser_state.aml,
- walk_state->aml_offset));
+ if (walk_state->pass_number == 2) {
+ ACPI_ERROR((AE_INFO,
+ "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
+ walk_state->opcode,
+ (u32)(walk_state->aml_offset +
+ sizeof(struct acpi_table_header))));
- ACPI_DUMP_BUFFER(walk_state->parser_state.aml, 128);
+ ACPI_DUMP_BUFFER(walk_state->parser_state.aml - 16, 48);
- /* Assume one-byte bad opcode */
+#ifdef ACPI_ASL_COMPILER
+ /*
+ * This is executed for the disassembler only. Output goes
+ * to the disassembled ASL output file.
+ */
+ acpi_os_printf
+ ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
+ walk_state->opcode,
+ (u32)(walk_state->aml_offset +
+ sizeof(struct acpi_table_header)));
+
+ /* Dump the context surrounding the invalid opcode */
+
+ acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
+ aml - 16), 48, DB_BYTE_DISPLAY,
+ walk_state->aml_offset +
+ sizeof(struct acpi_table_header) -
+ 16);
+ acpi_os_printf(" */\n");
+#endif
+ }
+
+ /* Increment past one-byte or two-byte opcode */
walk_state->parser_state.aml++;
+ if (walk_state->opcode > 0xFF) { /* Can only happen if first byte is 0x5B */
+ walk_state->parser_state.aml++;
+ }
+
return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
default:
@@ -519,11 +547,18 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
if ((op_info->class ==
AML_CLASS_EXECUTE) && (!arg)) {
ACPI_WARNING((AE_INFO,
- "Detected an unsupported executable opcode "
- "at module-level: [0x%.4X] at table offset 0x%.4X",
- op->common.aml_opcode,
- (u32)((aml_op_start - walk_state->parser_state.aml_start)
- + sizeof(struct acpi_table_header))));
+ "Unsupported module-level executable opcode "
+ "0x%.2X at table offset 0x%.4X",
+ op->common.
+ aml_opcode,
+ (u32)
+ (ACPI_PTR_DIFF
+ (aml_op_start,
+ walk_state->
+ parser_state.
+ aml_start) +
+ sizeof(struct
+ acpi_table_header))));
}
}
break;
@@ -843,8 +878,6 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
*op = NULL;
}
- ACPI_PREEMPTION_POINT();
-
return_ACPI_STATUS(AE_OK);
}
diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c
index ed1d457bd5c..1793d934aa3 100644
--- a/drivers/acpi/acpica/psopcode.c
+++ b/drivers/acpi/acpica/psopcode.c
@@ -59,7 +59,7 @@ static const u8 acpi_gbl_argument_count[] =
*
* DESCRIPTION: Opcode table. Each entry contains <opcode, type, name, operands>
* The name is a simple ascii string, the operand specifier is an
- * ascii string with one letter per operand. The letter specifies
+ * ascii string with one letter per operand. The letter specifies
* the operand type.
*
******************************************************************************/
@@ -183,7 +183,7 @@ static const u8 acpi_gbl_argument_count[] =
******************************************************************************/
/*
- * Master Opcode information table. A summary of everything we know about each
+ * Master Opcode information table. A summary of everything we know about each
* opcode, all in one place.
*/
const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
@@ -392,10 +392,12 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
/* 38 */ ACPI_OP("LAnd", ARGP_LAND_OP, ARGI_LAND_OP, ACPI_TYPE_ANY,
AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R,
- AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
+ AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC |
+ AML_CONSTANT),
/* 39 */ ACPI_OP("LOr", ARGP_LOR_OP, ARGI_LOR_OP, ACPI_TYPE_ANY,
AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R,
- AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
+ AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC |
+ AML_CONSTANT),
/* 3A */ ACPI_OP("LNot", ARGP_LNOT_OP, ARGI_LNOT_OP, ACPI_TYPE_ANY,
AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R,
AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
@@ -495,7 +497,8 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
AML_NSNODE | AML_NAMED | AML_DEFER),
/* 59 */ ACPI_OP("Field", ARGP_FIELD_OP, ARGI_FIELD_OP, ACPI_TYPE_ANY,
AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD,
- AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD),
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_FIELD),
/* 5A */ ACPI_OP("Device", ARGP_DEVICE_OP, ARGI_DEVICE_OP,
ACPI_TYPE_DEVICE, AML_CLASS_NAMED_OBJECT,
AML_TYPE_NAMED_NO_OBJ,
@@ -519,12 +522,13 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
/* 5E */ ACPI_OP("IndexField", ARGP_INDEX_FIELD_OP, ARGI_INDEX_FIELD_OP,
ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT,
AML_TYPE_NAMED_FIELD,
- AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD),
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_FIELD),
/* 5F */ ACPI_OP("BankField", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP,
- ACPI_TYPE_LOCAL_BANK_FIELD, AML_CLASS_NAMED_OBJECT,
- AML_TYPE_NAMED_FIELD,
- AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD |
- AML_DEFER),
+ ACPI_TYPE_LOCAL_BANK_FIELD,
+ AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD,
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_FIELD | AML_DEFER),
/* Internal opcodes that map to invalid AML opcodes */
@@ -632,7 +636,8 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
/* 7D */ ACPI_OP("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP,
ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT,
AML_TYPE_NAMED_NO_OBJ,
- AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE),
+ AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
+ AML_NSNODE),
/* ACPI 3.0 opcodes */
@@ -695,7 +700,7 @@ static const u8 acpi_gbl_short_op_index[256] = {
/*
* This table is indexed by the second opcode of the extended opcode
- * pair. It returns an index into the opcode table (acpi_gbl_aml_op_info)
+ * pair. It returns an index into the opcode table (acpi_gbl_aml_op_info)
*/
static const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] = {
/* 0 1 2 3 4 5 6 7 */
diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c
index 01985703bb9..2494caf4775 100644
--- a/drivers/acpi/acpica/psparse.c
+++ b/drivers/acpi/acpica/psparse.c
@@ -43,9 +43,9 @@
/*
* Parse the AML and build an operation tree as most interpreters,
- * like Perl, do. Parsing is done by hand rather than with a YACC
+ * like Perl, do. Parsing is done by hand rather than with a YACC
* generated parser to tightly constrain stack and dynamic memory
- * usage. At the same time, parsing is kept flexible and the code
+ * usage. At the same time, parsing is kept flexible and the code
* fairly compact by parsing based on a list of AML opcode
* templates in aml_op_info[]
*/
@@ -379,7 +379,7 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state,
case AE_CTRL_FALSE:
/*
* Either an IF/WHILE Predicate was false or we encountered a BREAK
- * opcode. In both cases, we do not execute the rest of the
+ * opcode. In both cases, we do not execute the rest of the
* package; We simply close out the parent (finishing the walk of
* this branch of the tree) and continue execution at the parent
* level.
@@ -459,8 +459,9 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
/* Executing a control method - additional cleanup */
- acpi_ds_terminate_control_method(
- walk_state->method_desc, walk_state);
+ acpi_ds_terminate_control_method(walk_state->
+ method_desc,
+ walk_state);
}
acpi_ds_delete_walk_state(walk_state);
@@ -487,7 +488,7 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
acpi_gbl_current_walk_list = thread;
/*
- * Execute the walk loop as long as there is a valid Walk State. This
+ * Execute the walk loop as long as there is a valid Walk State. This
* handles nested control method invocations without recursion.
*/
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "State=%p\n", walk_state));
diff --git a/drivers/acpi/acpica/psutils.c b/drivers/acpi/acpica/psutils.c
index 8736ad5f04d..4137dcb352d 100644
--- a/drivers/acpi/acpica/psutils.c
+++ b/drivers/acpi/acpica/psutils.c
@@ -108,7 +108,7 @@ void acpi_ps_init_op(union acpi_parse_object *op, u16 opcode)
* RETURN: Pointer to the new Op, null on failure
*
* DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
- * opcode. A cache of opcodes is available for the pure
+ * opcode. A cache of opcodes is available for the pure
* GENERIC_OP, since this is by far the most commonly used.
*
******************************************************************************/
@@ -164,7 +164,7 @@ union acpi_parse_object *acpi_ps_alloc_op(u16 opcode)
*
* RETURN: None.
*
- * DESCRIPTION: Free an Op object. Either put it on the GENERIC_OP cache list
+ * DESCRIPTION: Free an Op object. Either put it on the GENERIC_OP cache list
* or actually free it.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c
index de12469d1c9..147feb6aa2a 100644
--- a/drivers/acpi/acpica/rscalc.c
+++ b/drivers/acpi/acpica/rscalc.c
@@ -457,6 +457,15 @@ acpi_rs_get_list_length(u8 * aml_buffer,
* Get the number of vendor data bytes
*/
extra_struct_bytes = resource_length;
+
+ /*
+ * There is already one byte included in the minimum
+ * descriptor size. If there are extra struct bytes,
+ * subtract one from the count.
+ */
+ if (extra_struct_bytes) {
+ extra_struct_bytes--;
+ }
break;
case ACPI_RESOURCE_NAME_END_TAG:
@@ -601,7 +610,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
/*
* Calculate the size of the return buffer.
* The base size is the number of elements * the sizes of the
- * structures. Additional space for the strings is added below.
+ * structures. Additional space for the strings is added below.
* The minus one is to subtract the size of the u8 Source[1]
* member because it is added below.
*
@@ -664,8 +673,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
(*sub_object_list)->string.
length + 1);
} else {
- temp_size_needed +=
- acpi_ns_get_pathname_length((*sub_object_list)->reference.node);
+ temp_size_needed += acpi_ns_get_pathname_length((*sub_object_list)->reference.node);
}
} else {
/*
diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c
index 46b5324b22d..8b64db9a3fd 100644
--- a/drivers/acpi/acpica/rslist.c
+++ b/drivers/acpi/acpica/rslist.c
@@ -109,7 +109,7 @@ acpi_rs_convert_aml_to_resources(u8 * aml,
ACPI_ERROR((AE_INFO,
"Invalid/unsupported resource descriptor: Type 0x%2.2X",
resource_index));
- return (AE_AML_INVALID_RESOURCE_TYPE);
+ return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
}
/* Convert the AML byte stream resource to a local resource struct */
@@ -200,7 +200,7 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource,
ACPI_ERROR((AE_INFO,
"Invalid/unsupported resource descriptor: Type 0x%2.2X",
resource->type));
- return (AE_AML_INVALID_RESOURCE_TYPE);
+ return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
}
status = acpi_rs_convert_resource_to_aml(resource,
diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c
index 57deae16657..77d1db29a72 100644
--- a/drivers/acpi/acpica/tbfind.c
+++ b/drivers/acpi/acpica/tbfind.c
@@ -77,7 +77,7 @@ acpi_tb_find_table(char *signature,
/* Normalize the input strings */
ACPI_MEMSET(&header, 0, sizeof(struct acpi_table_header));
- ACPI_STRNCPY(header.signature, signature, ACPI_NAME_SIZE);
+ ACPI_MOVE_NAME(header.signature, signature);
ACPI_STRNCPY(header.oem_id, oem_id, ACPI_OEM_ID_SIZE);
ACPI_STRNCPY(header.oem_table_id, oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 70f9d787c82..f540ae46292 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -526,6 +526,8 @@ void acpi_tb_terminate(void)
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+
+ return_VOID;
}
/*******************************************************************************
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index b6cea30da63..285e24b9738 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -354,7 +354,7 @@ u8 acpi_tb_checksum(u8 *buffer, u32 length)
sum = (u8) (sum + *(buffer++));
}
- return sum;
+ return (sum);
}
/*******************************************************************************
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index 21101262e47..f5632780421 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -236,7 +236,7 @@ acpi_get_table_header(char *signature,
sizeof(struct
acpi_table_header));
if (!header) {
- return AE_NO_MEMORY;
+ return (AE_NO_MEMORY);
}
ACPI_MEMCPY(out_table_header, header,
sizeof(struct acpi_table_header));
@@ -244,7 +244,7 @@ acpi_get_table_header(char *signature,
sizeof(struct
acpi_table_header));
} else {
- return AE_NOT_FOUND;
+ return (AE_NOT_FOUND);
}
} else {
ACPI_MEMCPY(out_table_header,
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
index f87cc63e69a..a5e1e4e4709 100644
--- a/drivers/acpi/acpica/tbxfload.c
+++ b/drivers/acpi/acpica/tbxfload.c
@@ -211,7 +211,7 @@ static acpi_status acpi_tb_load_namespace(void)
* DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must
* be a valid ACPI table with a valid ACPI table header.
* Note1: Mainly intended to support hotplug addition of SSDTs.
- * Note2: Does not copy the incoming table. User is reponsible
+ * Note2: Does not copy the incoming table. User is responsible
* to ensure that the table is not deleted or unmapped.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c
index 74e72080003..28f330230f9 100644
--- a/drivers/acpi/acpica/tbxfroot.c
+++ b/drivers/acpi/acpica/tbxfroot.c
@@ -67,7 +67,6 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp);
static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
{
- ACPI_FUNCTION_ENTRY();
/*
* The signature and checksum must both be correct
@@ -108,7 +107,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
* RETURN: Status, RSDP physical address
*
* DESCRIPTION: Search lower 1Mbyte of memory for the root system descriptor
- * pointer structure. If it is found, set *RSDP to point to it.
+ * pointer structure. If it is found, set *RSDP to point to it.
*
* NOTE1: The RSDP must be either in the first 1K of the Extended
* BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.)
diff --git a/drivers/acpi/acpica/utcache.c b/drivers/acpi/acpica/utcache.c
new file mode 100644
index 00000000000..e1d40ed2639
--- /dev/null
+++ b/drivers/acpi/acpica/utcache.c
@@ -0,0 +1,323 @@
+/******************************************************************************
+ *
+ * Module Name: utcache - local cache allocation routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#define _COMPONENT ACPI_UTILITIES
+ACPI_MODULE_NAME("utcache")
+
+#ifdef ACPI_USE_LOCAL_CACHE
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_create_cache
+ *
+ * PARAMETERS: cache_name - Ascii name for the cache
+ * object_size - Size of each cached object
+ * max_depth - Maximum depth of the cache (in objects)
+ * return_cache - Where the new cache object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a cache object
+ *
+ ******************************************************************************/
+acpi_status
+acpi_os_create_cache(char *cache_name,
+ u16 object_size,
+ u16 max_depth, struct acpi_memory_list ** return_cache)
+{
+ struct acpi_memory_list *cache;
+
+ ACPI_FUNCTION_ENTRY();
+
+ if (!cache_name || !return_cache || (object_size < 16)) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Create the cache object */
+
+ cache = acpi_os_allocate(sizeof(struct acpi_memory_list));
+ if (!cache) {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Populate the cache object and return it */
+
+ ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list));
+ cache->link_offset = 8;
+ cache->list_name = cache_name;
+ cache->object_size = object_size;
+ cache->max_depth = max_depth;
+
+ *return_cache = cache;
+ return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_purge_cache
+ *
+ * PARAMETERS: cache - Handle to cache object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Free all objects within the requested cache.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_os_purge_cache(struct acpi_memory_list * cache)
+{
+ char *next;
+ acpi_status status;
+
+ ACPI_FUNCTION_ENTRY();
+
+ if (!cache) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ /* Walk the list of objects in this cache */
+
+ while (cache->list_head) {
+
+ /* Delete and unlink one cached state object */
+
+ next = *(ACPI_CAST_INDIRECT_PTR(char,
+ &(((char *)cache->
+ list_head)[cache->
+ link_offset])));
+ ACPI_FREE(cache->list_head);
+
+ cache->list_head = next;
+ cache->current_depth--;
+ }
+
+ (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
+ return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_delete_cache
+ *
+ * PARAMETERS: cache - Handle to cache object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Free all objects within the requested cache and delete the
+ * cache object.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_os_delete_cache(struct acpi_memory_list * cache)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_ENTRY();
+
+ /* Purge all objects in the cache */
+
+ status = acpi_os_purge_cache(cache);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ /* Now we can delete the cache object */
+
+ acpi_os_free(cache);
+ return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_release_object
+ *
+ * PARAMETERS: cache - Handle to cache object
+ * object - The object to be released
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Release an object to the specified cache. If cache is full,
+ * the object is deleted.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_os_release_object(struct acpi_memory_list * cache, void *object)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_ENTRY();
+
+ if (!cache || !object) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* If cache is full, just free this object */
+
+ if (cache->current_depth >= cache->max_depth) {
+ ACPI_FREE(object);
+ ACPI_MEM_TRACKING(cache->total_freed++);
+ }
+
+ /* Otherwise put this object back into the cache */
+
+ else {
+ status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ /* Mark the object as cached */
+
+ ACPI_MEMSET(object, 0xCA, cache->object_size);
+ ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_CACHED);
+
+ /* Put the object at the head of the cache list */
+
+ *(ACPI_CAST_INDIRECT_PTR(char,
+ &(((char *)object)[cache->
+ link_offset]))) =
+ cache->list_head;
+ cache->list_head = object;
+ cache->current_depth++;
+
+ (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
+ }
+
+ return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_os_acquire_object
+ *
+ * PARAMETERS: cache - Handle to cache object
+ *
+ * RETURN: the acquired object. NULL on error
+ *
+ * DESCRIPTION: Get an object from the specified cache. If cache is empty,
+ * the object is allocated.
+ *
+ ******************************************************************************/
+
+void *acpi_os_acquire_object(struct acpi_memory_list *cache)
+{
+ acpi_status status;
+ void *object;
+
+ ACPI_FUNCTION_NAME(os_acquire_object);
+
+ if (!cache) {
+ return (NULL);
+ }
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
+ if (ACPI_FAILURE(status)) {
+ return (NULL);
+ }
+
+ ACPI_MEM_TRACKING(cache->requests++);
+
+ /* Check the cache first */
+
+ if (cache->list_head) {
+
+ /* There is an object available, use it */
+
+ object = cache->list_head;
+ cache->list_head = *(ACPI_CAST_INDIRECT_PTR(char,
+ &(((char *)
+ object)[cache->
+ link_offset])));
+
+ cache->current_depth--;
+
+ ACPI_MEM_TRACKING(cache->hits++);
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "Object %p from %s cache\n", object,
+ cache->list_name));
+
+ status = acpi_ut_release_mutex(ACPI_MTX_CACHES);
+ if (ACPI_FAILURE(status)) {
+ return (NULL);
+ }
+
+ /* Clear (zero) the previously used Object */
+
+ ACPI_MEMSET(object, 0, cache->object_size);
+ } else {
+ /* The cache is empty, create a new object */
+
+ ACPI_MEM_TRACKING(cache->total_allocated++);
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ if ((cache->total_allocated - cache->total_freed) >
+ cache->max_occupied) {
+ cache->max_occupied =
+ cache->total_allocated - cache->total_freed;
+ }
+#endif
+
+ /* Avoid deadlock with ACPI_ALLOCATE_ZEROED */
+
+ status = acpi_ut_release_mutex(ACPI_MTX_CACHES);
+ if (ACPI_FAILURE(status)) {
+ return (NULL);
+ }
+
+ object = ACPI_ALLOCATE_ZEROED(cache->object_size);
+ if (!object) {
+ return (NULL);
+ }
+ }
+
+ return (object);
+}
+#endif /* ACPI_USE_LOCAL_CACHE */
diff --git a/drivers/acpi/acpica/utclib.c b/drivers/acpi/acpica/utclib.c
new file mode 100644
index 00000000000..19ea4755aa7
--- /dev/null
+++ b/drivers/acpi/acpica/utclib.c
@@ -0,0 +1,749 @@
+/******************************************************************************
+ *
+ * Module Name: cmclib - Local implementation of C library functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+/*
+ * These implementations of standard C Library routines can optionally be
+ * used if a C library is not available. In general, they are less efficient
+ * than an inline or assembly implementation
+ */
+
+#define _COMPONENT ACPI_UTILITIES
+ACPI_MODULE_NAME("cmclib")
+
+#ifndef ACPI_USE_SYSTEM_CLIBRARY
+#define NEGATIVE 1
+#define POSITIVE 0
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_memcmp (memcmp)
+ *
+ * PARAMETERS: buffer1 - First Buffer
+ * buffer2 - Second Buffer
+ * count - Maximum # of bytes to compare
+ *
+ * RETURN: Index where Buffers mismatched, or 0 if Buffers matched
+ *
+ * DESCRIPTION: Compare two Buffers, with a maximum length
+ *
+ ******************************************************************************/
+int acpi_ut_memcmp(const char *buffer1, const char *buffer2, acpi_size count)
+{
+
+ return ((count == ACPI_SIZE_MAX) ? 0 : ((unsigned char)*buffer1 -
+ (unsigned char)*buffer2));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_memcpy (memcpy)
+ *
+ * PARAMETERS: dest - Target of the copy
+ * src - Source buffer to copy
+ * count - Number of bytes to copy
+ *
+ * RETURN: Dest
+ *
+ * DESCRIPTION: Copy arbitrary bytes of memory
+ *
+ ******************************************************************************/
+
+void *acpi_ut_memcpy(void *dest, const void *src, acpi_size count)
+{
+ char *new = (char *)dest;
+ char *old = (char *)src;
+
+ while (count) {
+ *new = *old;
+ new++;
+ old++;
+ count--;
+ }
+
+ return (dest);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_memset (memset)
+ *
+ * PARAMETERS: dest - Buffer to set
+ * value - Value to set each byte of memory
+ * count - Number of bytes to set
+ *
+ * RETURN: Dest
+ *
+ * DESCRIPTION: Initialize a buffer to a known value.
+ *
+ ******************************************************************************/
+
+void *acpi_ut_memset(void *dest, u8 value, acpi_size count)
+{
+ char *new = (char *)dest;
+
+ while (count) {
+ *new = (char)value;
+ new++;
+ count--;
+ }
+
+ return (dest);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_strlen (strlen)
+ *
+ * PARAMETERS: string - Null terminated string
+ *
+ * RETURN: Length
+ *
+ * DESCRIPTION: Returns the length of the input string
+ *
+ ******************************************************************************/
+
+acpi_size acpi_ut_strlen(const char *string)
+{
+ u32 length = 0;
+
+ /* Count the string until a null is encountered */
+
+ while (*string) {
+ length++;
+ string++;
+ }
+
+ return (length);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_strcpy (strcpy)
+ *
+ * PARAMETERS: dst_string - Target of the copy
+ * src_string - The source string to copy
+ *
+ * RETURN: dst_string
+ *
+ * DESCRIPTION: Copy a null terminated string
+ *
+ ******************************************************************************/
+
+char *acpi_ut_strcpy(char *dst_string, const char *src_string)
+{
+ char *string = dst_string;
+
+ /* Move bytes brute force */
+
+ while (*src_string) {
+ *string = *src_string;
+
+ string++;
+ src_string++;
+ }
+
+ /* Null terminate */
+
+ *string = 0;
+ return (dst_string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_strncpy (strncpy)
+ *
+ * PARAMETERS: dst_string - Target of the copy
+ * src_string - The source string to copy
+ * count - Maximum # of bytes to copy
+ *
+ * RETURN: dst_string
+ *
+ * DESCRIPTION: Copy a null terminated string, with a maximum length
+ *
+ ******************************************************************************/
+
+char *acpi_ut_strncpy(char *dst_string, const char *src_string, acpi_size count)
+{
+ char *string = dst_string;
+
+ /* Copy the string */
+
+ for (string = dst_string;
+ count && (count--, (*string++ = *src_string++));) {;
+ }
+
+ /* Pad with nulls if necessary */
+
+ while (count--) {
+ *string = 0;
+ string++;
+ }
+
+ /* Return original pointer */
+
+ return (dst_string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_strcmp (strcmp)
+ *
+ * PARAMETERS: string1 - First string
+ * string2 - Second string
+ *
+ * RETURN: Index where strings mismatched, or 0 if strings matched
+ *
+ * DESCRIPTION: Compare two null terminated strings
+ *
+ ******************************************************************************/
+
+int acpi_ut_strcmp(const char *string1, const char *string2)
+{
+
+ for (; (*string1 == *string2); string2++) {
+ if (!*string1++) {
+ return (0);
+ }
+ }
+
+ return ((unsigned char)*string1 - (unsigned char)*string2);
+}
+
+#ifdef ACPI_FUTURE_IMPLEMENTATION
+/* Not used at this time */
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_strchr (strchr)
+ *
+ * PARAMETERS: string - Search string
+ * ch - character to search for
+ *
+ * RETURN: Ptr to char or NULL if not found
+ *
+ * DESCRIPTION: Search a string for a character
+ *
+ ******************************************************************************/
+
+char *acpi_ut_strchr(const char *string, int ch)
+{
+
+ for (; (*string); string++) {
+ if ((*string) == (char)ch) {
+ return ((char *)string);
+ }
+ }
+
+ return (NULL);
+}
+#endif
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_strncmp (strncmp)
+ *
+ * PARAMETERS: string1 - First string
+ * string2 - Second string
+ * count - Maximum # of bytes to compare
+ *
+ * RETURN: Index where strings mismatched, or 0 if strings matched
+ *
+ * DESCRIPTION: Compare two null terminated strings, with a maximum length
+ *
+ ******************************************************************************/
+
+int acpi_ut_strncmp(const char *string1, const char *string2, acpi_size count)
+{
+
+ for (; count-- && (*string1 == *string2); string2++) {
+ if (!*string1++) {
+ return (0);
+ }
+ }
+
+ return ((count == ACPI_SIZE_MAX) ? 0 : ((unsigned char)*string1 -
+ (unsigned char)*string2));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_strcat (Strcat)
+ *
+ * PARAMETERS: dst_string - Target of the copy
+ * src_string - The source string to copy
+ *
+ * RETURN: dst_string
+ *
+ * DESCRIPTION: Append a null terminated string to a null terminated string
+ *
+ ******************************************************************************/
+
+char *acpi_ut_strcat(char *dst_string, const char *src_string)
+{
+ char *string;
+
+ /* Find end of the destination string */
+
+ for (string = dst_string; *string++;) {;
+ }
+
+ /* Concatenate the string */
+
+ for (--string; (*string++ = *src_string++);) {;
+ }
+
+ return (dst_string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_strncat (strncat)
+ *
+ * PARAMETERS: dst_string - Target of the copy
+ * src_string - The source string to copy
+ * count - Maximum # of bytes to copy
+ *
+ * RETURN: dst_string
+ *
+ * DESCRIPTION: Append a null terminated string to a null terminated string,
+ * with a maximum count.
+ *
+ ******************************************************************************/
+
+char *acpi_ut_strncat(char *dst_string, const char *src_string, acpi_size count)
+{
+ char *string;
+
+ if (count) {
+
+ /* Find end of the destination string */
+
+ for (string = dst_string; *string++;) {;
+ }
+
+ /* Concatenate the string */
+
+ for (--string; (*string++ = *src_string++) && --count;) {;
+ }
+
+ /* Null terminate if necessary */
+
+ if (!count) {
+ *string = 0;
+ }
+ }
+
+ return (dst_string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_strstr (strstr)
+ *
+ * PARAMETERS: string1 - Target string
+ * string2 - Substring to search for
+ *
+ * RETURN: Where substring match starts, Null if no match found
+ *
+ * DESCRIPTION: Checks if String2 occurs in String1. This is not really a
+ * full implementation of strstr, only sufficient for command
+ * matching
+ *
+ ******************************************************************************/
+
+char *acpi_ut_strstr(char *string1, char *string2)
+{
+ char *string;
+
+ if (acpi_ut_strlen(string2) > acpi_ut_strlen(string1)) {
+ return (NULL);
+ }
+
+ /* Walk entire string, comparing the letters */
+
+ for (string = string1; *string2;) {
+ if (*string2 != *string) {
+ return (NULL);
+ }
+
+ string2++;
+ string++;
+ }
+
+ return (string1);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_strtoul (strtoul)
+ *
+ * PARAMETERS: string - Null terminated string
+ * terminater - Where a pointer to the terminating byte is
+ * returned
+ * base - Radix of the string
+ *
+ * RETURN: Converted value
+ *
+ * DESCRIPTION: Convert a string into a 32-bit unsigned value.
+ * Note: use acpi_ut_strtoul64 for 64-bit integers.
+ *
+ ******************************************************************************/
+
+u32 acpi_ut_strtoul(const char *string, char **terminator, u32 base)
+{
+ u32 converted = 0;
+ u32 index;
+ u32 sign;
+ const char *string_start;
+ u32 return_value = 0;
+ acpi_status status = AE_OK;
+
+ /*
+ * Save the value of the pointer to the buffer's first
+ * character, save the current errno value, and then
+ * skip over any white space in the buffer:
+ */
+ string_start = string;
+ while (ACPI_IS_SPACE(*string) || *string == '\t') {
+ ++string;
+ }
+
+ /*
+ * The buffer may contain an optional plus or minus sign.
+ * If it does, then skip over it but remember what is was:
+ */
+ if (*string == '-') {
+ sign = NEGATIVE;
+ ++string;
+ } else if (*string == '+') {
+ ++string;
+ sign = POSITIVE;
+ } else {
+ sign = POSITIVE;
+ }
+
+ /*
+ * If the input parameter Base is zero, then we need to
+ * determine if it is octal, decimal, or hexadecimal:
+ */
+ if (base == 0) {
+ if (*string == '0') {
+ if (acpi_ut_to_lower(*(++string)) == 'x') {
+ base = 16;
+ ++string;
+ } else {
+ base = 8;
+ }
+ } else {
+ base = 10;
+ }
+ } else if (base < 2 || base > 36) {
+ /*
+ * The specified Base parameter is not in the domain of
+ * this function:
+ */
+ goto done;
+ }
+
+ /*
+ * For octal and hexadecimal bases, skip over the leading
+ * 0 or 0x, if they are present.
+ */
+ if (base == 8 && *string == '0') {
+ string++;
+ }
+
+ if (base == 16 &&
+ *string == '0' && acpi_ut_to_lower(*(++string)) == 'x') {
+ string++;
+ }
+
+ /*
+ * Main loop: convert the string to an unsigned long:
+ */
+ while (*string) {
+ if (ACPI_IS_DIGIT(*string)) {
+ index = (u32)((u8)*string - '0');
+ } else {
+ index = (u32)acpi_ut_to_upper(*string);
+ if (ACPI_IS_UPPER(index)) {
+ index = index - 'A' + 10;
+ } else {
+ goto done;
+ }
+ }
+
+ if (index >= base) {
+ goto done;
+ }
+
+ /*
+ * Check to see if value is out of range:
+ */
+
+ if (return_value > ((ACPI_UINT32_MAX - (u32)index) / (u32)base)) {
+ status = AE_ERROR;
+ return_value = 0; /* reset */
+ } else {
+ return_value *= base;
+ return_value += index;
+ converted = 1;
+ }
+
+ ++string;
+ }
+
+ done:
+ /*
+ * If appropriate, update the caller's pointer to the next
+ * unconverted character in the buffer.
+ */
+ if (terminator) {
+ if (converted == 0 && return_value == 0 && string != NULL) {
+ *terminator = (char *)string_start;
+ } else {
+ *terminator = (char *)string;
+ }
+ }
+
+ if (status == AE_ERROR) {
+ return_value = ACPI_UINT32_MAX;
+ }
+
+ /*
+ * If a minus sign was present, then "the conversion is negated":
+ */
+ if (sign == NEGATIVE) {
+ return_value = (ACPI_UINT32_MAX - return_value) + 1;
+ }
+
+ return (return_value);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_to_upper (TOUPPER)
+ *
+ * PARAMETERS: c - Character to convert
+ *
+ * RETURN: Converted character as an int
+ *
+ * DESCRIPTION: Convert character to uppercase
+ *
+ ******************************************************************************/
+
+int acpi_ut_to_upper(int c)
+{
+
+ return (ACPI_IS_LOWER(c) ? ((c) - 0x20) : (c));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_to_lower (TOLOWER)
+ *
+ * PARAMETERS: c - Character to convert
+ *
+ * RETURN: Converted character as an int
+ *
+ * DESCRIPTION: Convert character to lowercase
+ *
+ ******************************************************************************/
+
+int acpi_ut_to_lower(int c)
+{
+
+ return (ACPI_IS_UPPER(c) ? ((c) + 0x20) : (c));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: is* functions
+ *
+ * DESCRIPTION: is* functions use the ctype table below
+ *
+ ******************************************************************************/
+
+const u8 _acpi_ctype[257] = {
+ _ACPI_CN, /* 0x00 0 NUL */
+ _ACPI_CN, /* 0x01 1 SOH */
+ _ACPI_CN, /* 0x02 2 STX */
+ _ACPI_CN, /* 0x03 3 ETX */
+ _ACPI_CN, /* 0x04 4 EOT */
+ _ACPI_CN, /* 0x05 5 ENQ */
+ _ACPI_CN, /* 0x06 6 ACK */
+ _ACPI_CN, /* 0x07 7 BEL */
+ _ACPI_CN, /* 0x08 8 BS */
+ _ACPI_CN | _ACPI_SP, /* 0x09 9 TAB */
+ _ACPI_CN | _ACPI_SP, /* 0x0A 10 LF */
+ _ACPI_CN | _ACPI_SP, /* 0x0B 11 VT */
+ _ACPI_CN | _ACPI_SP, /* 0x0C 12 FF */
+ _ACPI_CN | _ACPI_SP, /* 0x0D 13 CR */
+ _ACPI_CN, /* 0x0E 14 SO */
+ _ACPI_CN, /* 0x0F 15 SI */
+ _ACPI_CN, /* 0x10 16 DLE */
+ _ACPI_CN, /* 0x11 17 DC1 */
+ _ACPI_CN, /* 0x12 18 DC2 */
+ _ACPI_CN, /* 0x13 19 DC3 */
+ _ACPI_CN, /* 0x14 20 DC4 */
+ _ACPI_CN, /* 0x15 21 NAK */
+ _ACPI_CN, /* 0x16 22 SYN */
+ _ACPI_CN, /* 0x17 23 ETB */
+ _ACPI_CN, /* 0x18 24 CAN */
+ _ACPI_CN, /* 0x19 25 EM */
+ _ACPI_CN, /* 0x1A 26 SUB */
+ _ACPI_CN, /* 0x1B 27 ESC */
+ _ACPI_CN, /* 0x1C 28 FS */
+ _ACPI_CN, /* 0x1D 29 GS */
+ _ACPI_CN, /* 0x1E 30 RS */
+ _ACPI_CN, /* 0x1F 31 US */
+ _ACPI_XS | _ACPI_SP, /* 0x20 32 ' ' */
+ _ACPI_PU, /* 0x21 33 '!' */
+ _ACPI_PU, /* 0x22 34 '"' */
+ _ACPI_PU, /* 0x23 35 '#' */
+ _ACPI_PU, /* 0x24 36 '$' */
+ _ACPI_PU, /* 0x25 37 '%' */
+ _ACPI_PU, /* 0x26 38 '&' */
+ _ACPI_PU, /* 0x27 39 ''' */
+ _ACPI_PU, /* 0x28 40 '(' */
+ _ACPI_PU, /* 0x29 41 ')' */
+ _ACPI_PU, /* 0x2A 42 '*' */
+ _ACPI_PU, /* 0x2B 43 '+' */
+ _ACPI_PU, /* 0x2C 44 ',' */
+ _ACPI_PU, /* 0x2D 45 '-' */
+ _ACPI_PU, /* 0x2E 46 '.' */
+ _ACPI_PU, /* 0x2F 47 '/' */
+ _ACPI_XD | _ACPI_DI, /* 0x30 48 '0' */
+ _ACPI_XD | _ACPI_DI, /* 0x31 49 '1' */
+ _ACPI_XD | _ACPI_DI, /* 0x32 50 '2' */
+ _ACPI_XD | _ACPI_DI, /* 0x33 51 '3' */
+ _ACPI_XD | _ACPI_DI, /* 0x34 52 '4' */
+ _ACPI_XD | _ACPI_DI, /* 0x35 53 '5' */
+ _ACPI_XD | _ACPI_DI, /* 0x36 54 '6' */
+ _ACPI_XD | _ACPI_DI, /* 0x37 55 '7' */
+ _ACPI_XD | _ACPI_DI, /* 0x38 56 '8' */
+ _ACPI_XD | _ACPI_DI, /* 0x39 57 '9' */
+ _ACPI_PU, /* 0x3A 58 ':' */
+ _ACPI_PU, /* 0x3B 59 ';' */
+ _ACPI_PU, /* 0x3C 60 '<' */
+ _ACPI_PU, /* 0x3D 61 '=' */
+ _ACPI_PU, /* 0x3E 62 '>' */
+ _ACPI_PU, /* 0x3F 63 '?' */
+ _ACPI_PU, /* 0x40 64 '@' */
+ _ACPI_XD | _ACPI_UP, /* 0x41 65 'A' */
+ _ACPI_XD | _ACPI_UP, /* 0x42 66 'B' */
+ _ACPI_XD | _ACPI_UP, /* 0x43 67 'C' */
+ _ACPI_XD | _ACPI_UP, /* 0x44 68 'D' */
+ _ACPI_XD | _ACPI_UP, /* 0x45 69 'E' */
+ _ACPI_XD | _ACPI_UP, /* 0x46 70 'F' */
+ _ACPI_UP, /* 0x47 71 'G' */
+ _ACPI_UP, /* 0x48 72 'H' */
+ _ACPI_UP, /* 0x49 73 'I' */
+ _ACPI_UP, /* 0x4A 74 'J' */
+ _ACPI_UP, /* 0x4B 75 'K' */
+ _ACPI_UP, /* 0x4C 76 'L' */
+ _ACPI_UP, /* 0x4D 77 'M' */
+ _ACPI_UP, /* 0x4E 78 'N' */
+ _ACPI_UP, /* 0x4F 79 'O' */
+ _ACPI_UP, /* 0x50 80 'P' */
+ _ACPI_UP, /* 0x51 81 'Q' */
+ _ACPI_UP, /* 0x52 82 'R' */
+ _ACPI_UP, /* 0x53 83 'S' */
+ _ACPI_UP, /* 0x54 84 'T' */
+ _ACPI_UP, /* 0x55 85 'U' */
+ _ACPI_UP, /* 0x56 86 'V' */
+ _ACPI_UP, /* 0x57 87 'W' */
+ _ACPI_UP, /* 0x58 88 'X' */
+ _ACPI_UP, /* 0x59 89 'Y' */
+ _ACPI_UP, /* 0x5A 90 'Z' */
+ _ACPI_PU, /* 0x5B 91 '[' */
+ _ACPI_PU, /* 0x5C 92 '\' */
+ _ACPI_PU, /* 0x5D 93 ']' */
+ _ACPI_PU, /* 0x5E 94 '^' */
+ _ACPI_PU, /* 0x5F 95 '_' */
+ _ACPI_PU, /* 0x60 96 '`' */
+ _ACPI_XD | _ACPI_LO, /* 0x61 97 'a' */
+ _ACPI_XD | _ACPI_LO, /* 0x62 98 'b' */
+ _ACPI_XD | _ACPI_LO, /* 0x63 99 'c' */
+ _ACPI_XD | _ACPI_LO, /* 0x64 100 'd' */
+ _ACPI_XD | _ACPI_LO, /* 0x65 101 'e' */
+ _ACPI_XD | _ACPI_LO, /* 0x66 102 'f' */
+ _ACPI_LO, /* 0x67 103 'g' */
+ _ACPI_LO, /* 0x68 104 'h' */
+ _ACPI_LO, /* 0x69 105 'i' */
+ _ACPI_LO, /* 0x6A 106 'j' */
+ _ACPI_LO, /* 0x6B 107 'k' */
+ _ACPI_LO, /* 0x6C 108 'l' */
+ _ACPI_LO, /* 0x6D 109 'm' */
+ _ACPI_LO, /* 0x6E 110 'n' */
+ _ACPI_LO, /* 0x6F 111 'o' */
+ _ACPI_LO, /* 0x70 112 'p' */
+ _ACPI_LO, /* 0x71 113 'q' */
+ _ACPI_LO, /* 0x72 114 'r' */
+ _ACPI_LO, /* 0x73 115 's' */
+ _ACPI_LO, /* 0x74 116 't' */
+ _ACPI_LO, /* 0x75 117 'u' */
+ _ACPI_LO, /* 0x76 118 'v' */
+ _ACPI_LO, /* 0x77 119 'w' */
+ _ACPI_LO, /* 0x78 120 'x' */
+ _ACPI_LO, /* 0x79 121 'y' */
+ _ACPI_LO, /* 0x7A 122 'z' */
+ _ACPI_PU, /* 0x7B 123 '{' */
+ _ACPI_PU, /* 0x7C 124 '|' */
+ _ACPI_PU, /* 0x7D 125 '}' */
+ _ACPI_PU, /* 0x7E 126 '~' */
+ _ACPI_CN, /* 0x7F 127 DEL */
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 to 0x8F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 to 0x9F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 to 0xAF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0 to 0xBF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0 to 0xCF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0 to 0xDF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0 to 0xEF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0 to 0xFF */
+ 0 /* 0x100 */
+};
+
+#endif /* ACPI_USE_SYSTEM_CLIBRARY */
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c
index e810894149a..5d95166245a 100644
--- a/drivers/acpi/acpica/utdebug.c
+++ b/drivers/acpi/acpica/utdebug.c
@@ -47,8 +47,9 @@
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME("utdebug")
+
#ifdef ACPI_DEBUG_OUTPUT
-static acpi_thread_id acpi_gbl_prev_thread_id;
+static acpi_thread_id acpi_gbl_prev_thread_id = (acpi_thread_id) 0xFFFFFFFF;
static char *acpi_gbl_fn_entry_str = "----Entry";
static char *acpi_gbl_fn_exit_str = "----Exit-";
@@ -109,7 +110,7 @@ void acpi_ut_track_stack_ptr(void)
* RETURN: Updated pointer to the function name
*
* DESCRIPTION: Remove the "Acpi" prefix from the function name, if present.
- * This allows compiler macros such as __func__ to be used
+ * This allows compiler macros such as __FUNCTION__ to be used
* with no change to the debug output.
*
******************************************************************************/
@@ -222,7 +223,7 @@ ACPI_EXPORT_SYMBOL(acpi_debug_print)
*
* RETURN: None
*
- * DESCRIPTION: Print message with no headers. Has same interface as
+ * DESCRIPTION: Print message with no headers. Has same interface as
* debug_print so that the same macros can be used.
*
******************************************************************************/
@@ -258,7 +259,7 @@ ACPI_EXPORT_SYMBOL(acpi_debug_print_raw)
*
* RETURN: None
*
- * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
+ * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level
*
******************************************************************************/
@@ -290,7 +291,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_trace)
*
* RETURN: None
*
- * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
+ * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level
*
******************************************************************************/
@@ -299,6 +300,7 @@ acpi_ut_trace_ptr(u32 line_number,
const char *function_name,
const char *module_name, u32 component_id, void *pointer)
{
+
acpi_gbl_nesting_level++;
acpi_ut_track_stack_ptr();
@@ -319,7 +321,7 @@ acpi_ut_trace_ptr(u32 line_number,
*
* RETURN: None
*
- * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
+ * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level
*
******************************************************************************/
@@ -350,7 +352,7 @@ acpi_ut_trace_str(u32 line_number,
*
* RETURN: None
*
- * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
+ * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level
*
******************************************************************************/
@@ -380,7 +382,7 @@ acpi_ut_trace_u32(u32 line_number,
*
* RETURN: None
*
- * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
+ * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level
*
******************************************************************************/
@@ -412,7 +414,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_exit)
*
* RETURN: None
*
- * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
+ * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level. Prints exit status also.
*
******************************************************************************/
@@ -453,7 +455,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_status_exit)
*
* RETURN: None
*
- * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
+ * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level. Prints exit value also.
*
******************************************************************************/
@@ -485,7 +487,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_value_exit)
*
* RETURN: None
*
- * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
+ * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level. Prints exit value also.
*
******************************************************************************/
@@ -511,7 +513,7 @@ acpi_ut_ptr_exit(u32 line_number,
* PARAMETERS: buffer - Buffer to dump
* count - Amount to dump, in bytes
* display - BYTE, WORD, DWORD, or QWORD display
- * component_ID - Caller's component ID
+ * offset - Beginning buffer offset (display only)
*
* RETURN: None
*
@@ -519,7 +521,7 @@ acpi_ut_ptr_exit(u32 line_number,
*
******************************************************************************/
-void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
+void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 base_offset)
{
u32 i = 0;
u32 j;
@@ -541,7 +543,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
/* Print current offset */
- acpi_os_printf("%6.4X: ", i);
+ acpi_os_printf("%6.4X: ", (base_offset + i));
/* Print 16 hex chars */
@@ -623,7 +625,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
/*******************************************************************************
*
- * FUNCTION: acpi_ut_dump_buffer
+ * FUNCTION: acpi_ut_debug_dump_buffer
*
* PARAMETERS: buffer - Buffer to dump
* count - Amount to dump, in bytes
@@ -636,7 +638,8 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
*
******************************************************************************/
-void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id)
+void
+acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id)
{
/* Only dump the buffer if tracing is enabled */
@@ -646,5 +649,5 @@ void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id)
return;
}
- acpi_ut_dump_buffer2(buffer, count, display);
+ acpi_ut_dump_buffer(buffer, count, display, 0);
}
diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c
index 5d84e195457..774c3aefbf5 100644
--- a/drivers/acpi/acpica/utids.c
+++ b/drivers/acpi/acpica/utids.c
@@ -67,10 +67,10 @@ ACPI_MODULE_NAME("utids")
******************************************************************************/
acpi_status
acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
- struct acpica_device_id **return_id)
+ struct acpi_pnp_device_id **return_id)
{
union acpi_operand_object *obj_desc;
- struct acpica_device_id *hid;
+ struct acpi_pnp_device_id *hid;
u32 length;
acpi_status status;
@@ -94,16 +94,17 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
/* Allocate a buffer for the HID */
hid =
- ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) +
+ ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
(acpi_size) length);
if (!hid) {
status = AE_NO_MEMORY;
goto cleanup;
}
- /* Area for the string starts after DEVICE_ID struct */
+ /* Area for the string starts after PNP_DEVICE_ID struct */
- hid->string = ACPI_ADD_PTR(char, hid, sizeof(struct acpica_device_id));
+ hid->string =
+ ACPI_ADD_PTR(char, hid, sizeof(struct acpi_pnp_device_id));
/* Convert EISAID to a string or simply copy existing string */
@@ -126,6 +127,73 @@ cleanup:
/*******************************************************************************
*
+ * FUNCTION: acpi_ut_execute_SUB
+ *
+ * PARAMETERS: device_node - Node for the device
+ * return_id - Where the _SUB is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Executes the _SUB control method that returns the subsystem
+ * ID of the device. The _SUB value is always a string containing
+ * either a valid PNP or ACPI ID.
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_execute_SUB(struct acpi_namespace_node *device_node,
+ struct acpi_pnp_device_id **return_id)
+{
+ union acpi_operand_object *obj_desc;
+ struct acpi_pnp_device_id *sub;
+ u32 length;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(ut_execute_SUB);
+
+ status = acpi_ut_evaluate_object(device_node, METHOD_NAME__SUB,
+ ACPI_BTYPE_STRING, &obj_desc);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ /* Get the size of the String to be returned, includes null terminator */
+
+ length = obj_desc->string.length + 1;
+
+ /* Allocate a buffer for the SUB */
+
+ sub =
+ ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
+ (acpi_size) length);
+ if (!sub) {
+ status = AE_NO_MEMORY;
+ goto cleanup;
+ }
+
+ /* Area for the string starts after PNP_DEVICE_ID struct */
+
+ sub->string =
+ ACPI_ADD_PTR(char, sub, sizeof(struct acpi_pnp_device_id));
+
+ /* Simply copy existing string */
+
+ ACPI_STRCPY(sub->string, obj_desc->string.pointer);
+ sub->length = length;
+ *return_id = sub;
+
+ cleanup:
+
+ /* On exit, we must delete the return object */
+
+ acpi_ut_remove_reference(obj_desc);
+ return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
* FUNCTION: acpi_ut_execute_UID
*
* PARAMETERS: device_node - Node for the device
@@ -144,10 +212,10 @@ cleanup:
acpi_status
acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
- struct acpica_device_id **return_id)
+ struct acpi_pnp_device_id **return_id)
{
union acpi_operand_object *obj_desc;
- struct acpica_device_id *uid;
+ struct acpi_pnp_device_id *uid;
u32 length;
acpi_status status;
@@ -171,16 +239,17 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
/* Allocate a buffer for the UID */
uid =
- ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) +
+ ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
(acpi_size) length);
if (!uid) {
status = AE_NO_MEMORY;
goto cleanup;
}
- /* Area for the string starts after DEVICE_ID struct */
+ /* Area for the string starts after PNP_DEVICE_ID struct */
- uid->string = ACPI_ADD_PTR(char, uid, sizeof(struct acpica_device_id));
+ uid->string =
+ ACPI_ADD_PTR(char, uid, sizeof(struct acpi_pnp_device_id));
/* Convert an Integer to string, or just copy an existing string */
@@ -226,11 +295,11 @@ cleanup:
acpi_status
acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
- struct acpica_device_id_list **return_cid_list)
+ struct acpi_pnp_device_id_list **return_cid_list)
{
union acpi_operand_object **cid_objects;
union acpi_operand_object *obj_desc;
- struct acpica_device_id_list *cid_list;
+ struct acpi_pnp_device_id_list *cid_list;
char *next_id_string;
u32 string_area_size;
u32 length;
@@ -288,11 +357,12 @@ acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
/*
* Now that we know the length of the CIDs, allocate return buffer:
* 1) Size of the base structure +
- * 2) Size of the CID DEVICE_ID array +
+ * 2) Size of the CID PNP_DEVICE_ID array +
* 3) Size of the actual CID strings
*/
- cid_list_size = sizeof(struct acpica_device_id_list) +
- ((count - 1) * sizeof(struct acpica_device_id)) + string_area_size;
+ cid_list_size = sizeof(struct acpi_pnp_device_id_list) +
+ ((count - 1) * sizeof(struct acpi_pnp_device_id)) +
+ string_area_size;
cid_list = ACPI_ALLOCATE_ZEROED(cid_list_size);
if (!cid_list) {
@@ -300,10 +370,10 @@ acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
goto cleanup;
}
- /* Area for CID strings starts after the CID DEVICE_ID array */
+ /* Area for CID strings starts after the CID PNP_DEVICE_ID array */
next_id_string = ACPI_CAST_PTR(char, cid_list->ids) +
- ((acpi_size) count * sizeof(struct acpica_device_id));
+ ((acpi_size) count * sizeof(struct acpi_pnp_device_id));
/* Copy/convert the CIDs to the return buffer */
diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c
index d88a8aaab2a..49563674833 100644
--- a/drivers/acpi/acpica/utmath.c
+++ b/drivers/acpi/acpica/utmath.c
@@ -81,7 +81,7 @@ typedef union uint64_overlay {
* RETURN: Status (Checks for divide-by-zero)
*
* DESCRIPTION: Perform a short (maximum 64 bits divided by 32 bits)
- * divide and modulo. The result is a 64-bit quotient and a
+ * divide and modulo. The result is a 64-bit quotient and a
* 32-bit remainder.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c
index 33c6cf7ff46..9286a69eb9a 100644
--- a/drivers/acpi/acpica/utmisc.c
+++ b/drivers/acpi/acpica/utmisc.c
@@ -41,8 +41,6 @@
* POSSIBILITY OF SUCH DAMAGES.
*/
-#include <linux/module.h>
-
#include <acpi/acpi.h>
#include "accommon.h"
#include "acnamesp.h"
@@ -201,8 +199,8 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
*/
acpi_gbl_owner_id_mask[j] |= (1 << k);
- acpi_gbl_last_owner_id_index = (u8) j;
- acpi_gbl_next_owner_id_offset = (u8) (k + 1);
+ acpi_gbl_last_owner_id_index = (u8)j;
+ acpi_gbl_next_owner_id_offset = (u8)(k + 1);
/*
* Construct encoded ID from the index and bit position
@@ -252,7 +250,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
* control method or unloading a table. Either way, we would
* ignore any error anyway.
*
- * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255
+ * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255
*
******************************************************************************/
@@ -339,6 +337,73 @@ void acpi_ut_strupr(char *src_string)
return;
}
+#ifdef ACPI_ASL_COMPILER
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_strlwr (strlwr)
+ *
+ * PARAMETERS: src_string - The source string to convert
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert string to lowercase
+ *
+ * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
+ *
+ ******************************************************************************/
+
+void acpi_ut_strlwr(char *src_string)
+{
+ char *string;
+
+ ACPI_FUNCTION_ENTRY();
+
+ if (!src_string) {
+ return;
+ }
+
+ /* Walk entire string, lowercasing the letters */
+
+ for (string = src_string; *string; string++) {
+ *string = (char)ACPI_TOLOWER(*string);
+ }
+
+ return;
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_ut_stricmp
+ *
+ * PARAMETERS: string1 - first string to compare
+ * string2 - second string to compare
+ *
+ * RETURN: int that signifies string relationship. Zero means strings
+ * are equal.
+ *
+ * DESCRIPTION: Implementation of the non-ANSI stricmp function (compare
+ * strings with no case sensitivity)
+ *
+ ******************************************************************************/
+
+int acpi_ut_stricmp(char *string1, char *string2)
+{
+ int c1;
+ int c2;
+
+ do {
+ c1 = tolower((int)*string1);
+ c2 = tolower((int)*string2);
+
+ string1++;
+ string2++;
+ }
+ while ((c1 == c2) && (c1));
+
+ return (c1 - c2);
+}
+#endif
+
/*******************************************************************************
*
* FUNCTION: acpi_ut_print_string
@@ -469,8 +534,8 @@ u32 acpi_ut_dword_byte_swap(u32 value)
* RETURN: None
*
* DESCRIPTION: Set the global integer bit width based upon the revision
- * of the DSDT. For Revision 1 and 0, Integers are 32 bits.
- * For Revision 2 and above, Integers are 64 bits. Yes, this
+ * of the DSDT. For Revision 1 and 0, Integers are 32 bits.
+ * For Revision 2 and above, Integers are 64 bits. Yes, this
* makes a difference.
*
******************************************************************************/
@@ -606,7 +671,7 @@ u8 acpi_ut_valid_acpi_char(char character, u32 position)
*
* RETURN: TRUE if the name is valid, FALSE otherwise
*
- * DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
+ * DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
* 1) Upper case alpha
* 2) numeric
* 3) underscore
@@ -638,29 +703,59 @@ u8 acpi_ut_valid_acpi_name(u32 name)
* RETURN: Repaired version of the name
*
* DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
- * return the new name.
+ * return the new name. NOTE: the Name parameter must reside in
+ * read/write memory, cannot be a const.
+ *
+ * An ACPI Name must consist of valid ACPI characters. We will repair the name
+ * if necessary because we don't want to abort because of this, but we want
+ * all namespace names to be printable. A warning message is appropriate.
+ *
+ * This issue came up because there are in fact machines that exhibit
+ * this problem, and we want to be able to enable ACPI support for them,
+ * even though there are a few bad names.
*
******************************************************************************/
-acpi_name acpi_ut_repair_name(char *name)
+void acpi_ut_repair_name(char *name)
{
- u32 i;
- char new_name[ACPI_NAME_SIZE];
+ u32 i;
+ u8 found_bad_char = FALSE;
+ u32 original_name;
+
+ ACPI_FUNCTION_NAME(ut_repair_name);
+
+ ACPI_MOVE_NAME(&original_name, name);
+
+ /* Check each character in the name */
for (i = 0; i < ACPI_NAME_SIZE; i++) {
- new_name[i] = name[i];
+ if (acpi_ut_valid_acpi_char(name[i], i)) {
+ continue;
+ }
/*
* Replace a bad character with something printable, yet technically
* still invalid. This prevents any collisions with existing "good"
* names in the namespace.
*/
- if (!acpi_ut_valid_acpi_char(name[i], i)) {
- new_name[i] = '*';
- }
+ name[i] = '*';
+ found_bad_char = TRUE;
}
- return (*(u32 *) new_name);
+ if (found_bad_char) {
+
+ /* Report warning only if in strict mode or debug mode */
+
+ if (!acpi_gbl_enable_interpreter_slack) {
+ ACPI_WARNING((AE_INFO,
+ "Found bad character(s) in name, repaired: [%4.4s]\n",
+ name));
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Found bad character(s) in name, repaired: [%4.4s]\n",
+ name));
+ }
+ }
}
/*******************************************************************************
@@ -681,7 +776,7 @@ acpi_name acpi_ut_repair_name(char *name)
*
******************************************************************************/
-acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer)
+acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer)
{
u32 this_digit = 0;
u64 return_value = 0;
@@ -754,14 +849,14 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer)
/* Convert ASCII 0-9 to Decimal value */
- this_digit = ((u8) * string) - '0';
+ this_digit = ((u8)*string) - '0';
} else if (base == 10) {
/* Digit is out of range; possible in to_integer case only */
term = 1;
} else {
- this_digit = (u8) ACPI_TOUPPER(*string);
+ this_digit = (u8)ACPI_TOUPPER(*string);
if (ACPI_IS_XDIGIT((char)this_digit)) {
/* Convert ASCII Hex char to value */
@@ -788,8 +883,9 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer)
valid_digits++;
- if (sign_of0x && ((valid_digits > 16)
- || ((valid_digits > 8) && mode32))) {
+ if (sign_of0x
+ && ((valid_digits > 16)
+ || ((valid_digits > 8) && mode32))) {
/*
* This is to_integer operation case.
* No any restrictions for string-to-integer conversion,
@@ -800,7 +896,7 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer)
/* Divide the digit into the correct position */
- (void)acpi_ut_short_divide((dividend - (u64) this_digit),
+ (void)acpi_ut_short_divide((dividend - (u64)this_digit),
base, &quotient, NULL);
if (return_value > quotient) {
@@ -890,7 +986,7 @@ acpi_ut_create_update_state_and_push(union acpi_operand_object *object,
******************************************************************************/
acpi_status
-acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
+acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
void *target_object,
acpi_pkg_callback walk_callback, void *context)
{
@@ -917,10 +1013,10 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
/*
* Check for:
- * 1) An uninitialized package element. It is completely
+ * 1) An uninitialized package element. It is completely
* legal to declare a package and leave it uninitialized
* 2) Not an internal object - can be a namespace node instead
- * 3) Any type other than a package. Packages are handled in else
+ * 3) Any type other than a package. Packages are handled in else
* case below.
*/
if ((!this_source_obj) ||
@@ -939,7 +1035,7 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
state->pkg.source_object->package.count) {
/*
* We've handled all of the objects at this level, This means
- * that we have just completed a package. That package may
+ * that we have just completed a package. That package may
* have contained one or more packages itself.
*
* Delete this state and pop the previous state (package).
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index 296baa676bc..5ccf57c0d87 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -193,6 +193,8 @@ static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id)
acpi_gbl_mutex_info[mutex_id].mutex = NULL;
acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
+
+ return_VOID;
}
/*******************************************************************************
@@ -226,9 +228,9 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
/*
* Mutex debug code, for internal debugging only.
*
- * Deadlock prevention. Check if this thread owns any mutexes of value
- * greater than or equal to this one. If so, the thread has violated
- * the mutex ordering rule. This indicates a coding error somewhere in
+ * Deadlock prevention. Check if this thread owns any mutexes of value
+ * greater than or equal to this one. If so, the thread has violated
+ * the mutex ordering rule. This indicates a coding error somewhere in
* the ACPI subsystem code.
*/
for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
@@ -319,9 +321,9 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
/*
* Mutex debug code, for internal debugging only.
*
- * Deadlock prevention. Check if this thread owns any mutexes of value
- * greater than this one. If so, the thread has violated the mutex
- * ordering rule. This indicates a coding error somewhere in
+ * Deadlock prevention. Check if this thread owns any mutexes of value
+ * greater than this one. If so, the thread has violated the mutex
+ * ordering rule. This indicates a coding error somewhere in
* the ACPI subsystem code.
*/
for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c
index 655f0799a39..5c52ca78f6f 100644
--- a/drivers/acpi/acpica/utobject.c
+++ b/drivers/acpi/acpica/utobject.c
@@ -77,7 +77,7 @@ acpi_ut_get_element_length(u8 object_type,
*
* NOTE: We always allocate the worst-case object descriptor because
* these objects are cached, and we want them to be
- * one-size-satisifies-any-request. This in itself may not be
+ * one-size-satisifies-any-request. This in itself may not be
* the most memory efficient, but the efficiency of the object
* cache should more than make up for this!
*
@@ -370,9 +370,9 @@ u8 acpi_ut_valid_internal_object(void *object)
* line_number - Caller's line number (for error output)
* component_id - Caller's component ID (for error output)
*
- * RETURN: Pointer to newly allocated object descriptor. Null on error
+ * RETURN: Pointer to newly allocated object descriptor. Null on error
*
- * DESCRIPTION: Allocate a new object descriptor. Gracefully handle
+ * DESCRIPTION: Allocate a new object descriptor. Gracefully handle
* error conditions.
*
******************************************************************************/
@@ -554,7 +554,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
/*
* Account for the space required by the object rounded up to the next
- * multiple of the machine word size. This keeps each object aligned
+ * multiple of the machine word size. This keeps each object aligned
* on a machine word boundary. (preventing alignment faults on some
* machines.)
*/
diff --git a/drivers/acpi/acpica/utstate.c b/drivers/acpi/acpica/utstate.c
index a1c98826007..cee0473ba81 100644
--- a/drivers/acpi/acpica/utstate.c
+++ b/drivers/acpi/acpica/utstate.c
@@ -147,7 +147,7 @@ union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state
*
* RETURN: The new state object. NULL on failure.
*
- * DESCRIPTION: Create a generic state object. Attempt to obtain one from
+ * DESCRIPTION: Create a generic state object. Attempt to obtain one from
* the global state cache; If none available, create a new one.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/uttrack.c b/drivers/acpi/acpica/uttrack.c
new file mode 100644
index 00000000000..a424a9e3fea
--- /dev/null
+++ b/drivers/acpi/acpica/uttrack.c
@@ -0,0 +1,692 @@
+/******************************************************************************
+ *
+ * Module Name: uttrack - Memory allocation tracking routines (debug only)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+/*
+ * These procedures are used for tracking memory leaks in the subsystem, and
+ * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
+ *
+ * Each memory allocation is tracked via a doubly linked list. Each
+ * element contains the caller's component, module name, function name, and
+ * line number. acpi_ut_allocate and acpi_ut_allocate_zeroed call
+ * acpi_ut_track_allocation to add an element to the list; deletion
+ * occurs in the body of acpi_ut_free.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+#define _COMPONENT ACPI_UTILITIES
+ACPI_MODULE_NAME("uttrack")
+
+/* Local prototypes */
+static struct acpi_debug_mem_block *acpi_ut_find_allocation(struct
+ acpi_debug_mem_block
+ *allocation);
+
+static acpi_status
+acpi_ut_track_allocation(struct acpi_debug_mem_block *address,
+ acpi_size size,
+ u8 alloc_type,
+ u32 component, const char *module, u32 line);
+
+static acpi_status
+acpi_ut_remove_allocation(struct acpi_debug_mem_block *address,
+ u32 component, const char *module, u32 line);
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_list
+ *
+ * PARAMETERS: cache_name - Ascii name for the cache
+ * object_size - Size of each cached object
+ * return_cache - Where the new cache object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a local memory list for tracking purposed
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_create_list(char *list_name,
+ u16 object_size, struct acpi_memory_list **return_cache)
+{
+ struct acpi_memory_list *cache;
+
+ cache = acpi_os_allocate(sizeof(struct acpi_memory_list));
+ if (!cache) {
+ return (AE_NO_MEMORY);
+ }
+
+ ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list));
+
+ cache->list_name = list_name;
+ cache->object_size = object_size;
+
+ *return_cache = cache;
+ return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_allocate_and_track
+ *
+ * PARAMETERS: size - Size of the allocation
+ * component - Component type of caller
+ * module - Source file name of caller
+ * line - Line number of caller
+ *
+ * RETURN: Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: The subsystem's equivalent of malloc.
+ *
+ ******************************************************************************/
+
+void *acpi_ut_allocate_and_track(acpi_size size,
+ u32 component, const char *module, u32 line)
+{
+ struct acpi_debug_mem_block *allocation;
+ acpi_status status;
+
+ allocation =
+ acpi_ut_allocate(size + sizeof(struct acpi_debug_mem_header),
+ component, module, line);
+ if (!allocation) {
+ return (NULL);
+ }
+
+ status = acpi_ut_track_allocation(allocation, size,
+ ACPI_MEM_MALLOC, component, module,
+ line);
+ if (ACPI_FAILURE(status)) {
+ acpi_os_free(allocation);
+ return (NULL);
+ }
+
+ acpi_gbl_global_list->total_allocated++;
+ acpi_gbl_global_list->total_size += (u32)size;
+ acpi_gbl_global_list->current_total_size += (u32)size;
+ if (acpi_gbl_global_list->current_total_size >
+ acpi_gbl_global_list->max_occupied) {
+ acpi_gbl_global_list->max_occupied =
+ acpi_gbl_global_list->current_total_size;
+ }
+
+ return ((void *)&allocation->user_space);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_allocate_zeroed_and_track
+ *
+ * PARAMETERS: size - Size of the allocation
+ * component - Component type of caller
+ * module - Source file name of caller
+ * line - Line number of caller
+ *
+ * RETURN: Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: Subsystem equivalent of calloc.
+ *
+ ******************************************************************************/
+
+void *acpi_ut_allocate_zeroed_and_track(acpi_size size,
+ u32 component,
+ const char *module, u32 line)
+{
+ struct acpi_debug_mem_block *allocation;
+ acpi_status status;
+
+ allocation =
+ acpi_ut_allocate_zeroed(size + sizeof(struct acpi_debug_mem_header),
+ component, module, line);
+ if (!allocation) {
+
+ /* Report allocation error */
+
+ ACPI_ERROR((module, line,
+ "Could not allocate size %u", (u32)size));
+ return (NULL);
+ }
+
+ status = acpi_ut_track_allocation(allocation, size,
+ ACPI_MEM_CALLOC, component, module,
+ line);
+ if (ACPI_FAILURE(status)) {
+ acpi_os_free(allocation);
+ return (NULL);
+ }
+
+ acpi_gbl_global_list->total_allocated++;
+ acpi_gbl_global_list->total_size += (u32)size;
+ acpi_gbl_global_list->current_total_size += (u32)size;
+ if (acpi_gbl_global_list->current_total_size >
+ acpi_gbl_global_list->max_occupied) {
+ acpi_gbl_global_list->max_occupied =
+ acpi_gbl_global_list->current_total_size;
+ }
+
+ return ((void *)&allocation->user_space);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_free_and_track
+ *
+ * PARAMETERS: allocation - Address of the memory to deallocate
+ * component - Component type of caller
+ * module - Source file name of caller
+ * line - Line number of caller
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Frees the memory at Allocation
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_free_and_track(void *allocation,
+ u32 component, const char *module, u32 line)
+{
+ struct acpi_debug_mem_block *debug_block;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE_PTR(ut_free, allocation);
+
+ if (NULL == allocation) {
+ ACPI_ERROR((module, line, "Attempt to delete a NULL address"));
+
+ return_VOID;
+ }
+
+ debug_block = ACPI_CAST_PTR(struct acpi_debug_mem_block,
+ (((char *)allocation) -
+ sizeof(struct acpi_debug_mem_header)));
+
+ acpi_gbl_global_list->total_freed++;
+ acpi_gbl_global_list->current_total_size -= debug_block->size;
+
+ status = acpi_ut_remove_allocation(debug_block,
+ component, module, line);
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status, "Could not free memory"));
+ }
+
+ acpi_os_free(debug_block);
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation));
+ return_VOID;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_find_allocation
+ *
+ * PARAMETERS: allocation - Address of allocated memory
+ *
+ * RETURN: Three cases:
+ * 1) List is empty, NULL is returned.
+ * 2) Element was found. Returns Allocation parameter.
+ * 3) Element was not found. Returns position where it should be
+ * inserted into the list.
+ *
+ * DESCRIPTION: Searches for an element in the global allocation tracking list.
+ * If the element is not found, returns the location within the
+ * list where the element should be inserted.
+ *
+ * Note: The list is ordered by larger-to-smaller addresses.
+ *
+ * This global list is used to detect memory leaks in ACPICA as
+ * well as other issues such as an attempt to release the same
+ * internal object more than once. Although expensive as far
+ * as cpu time, this list is much more helpful for finding these
+ * types of issues than using memory leak detectors outside of
+ * the ACPICA code.
+ *
+ ******************************************************************************/
+
+static struct acpi_debug_mem_block *acpi_ut_find_allocation(struct
+ acpi_debug_mem_block
+ *allocation)
+{
+ struct acpi_debug_mem_block *element;
+
+ element = acpi_gbl_global_list->list_head;
+ if (!element) {
+ return (NULL);
+ }
+
+ /*
+ * Search for the address.
+ *
+ * Note: List is ordered by larger-to-smaller addresses, on the
+ * assumption that a new allocation usually has a larger address
+ * than previous allocations.
+ */
+ while (element > allocation) {
+
+ /* Check for end-of-list */
+
+ if (!element->next) {
+ return (element);
+ }
+
+ element = element->next;
+ }
+
+ if (element == allocation) {
+ return (element);
+ }
+
+ return (element->previous);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_track_allocation
+ *
+ * PARAMETERS: allocation - Address of allocated memory
+ * size - Size of the allocation
+ * alloc_type - MEM_MALLOC or MEM_CALLOC
+ * component - Component type of caller
+ * module - Source file name of caller
+ * line - Line number of caller
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Inserts an element into the global allocation tracking list.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation,
+ acpi_size size,
+ u8 alloc_type,
+ u32 component, const char *module, u32 line)
+{
+ struct acpi_memory_list *mem_list;
+ struct acpi_debug_mem_block *element;
+ acpi_status status = AE_OK;
+
+ ACPI_FUNCTION_TRACE_PTR(ut_track_allocation, allocation);
+
+ if (acpi_gbl_disable_mem_tracking) {
+ return_ACPI_STATUS(AE_OK);
+ }
+
+ mem_list = acpi_gbl_global_list;
+ status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ /*
+ * Search the global list for this address to make sure it is not
+ * already present. This will catch several kinds of problems.
+ */
+ element = acpi_ut_find_allocation(allocation);
+ if (element == allocation) {
+ ACPI_ERROR((AE_INFO,
+ "UtTrackAllocation: Allocation (%p) already present in global list!",
+ allocation));
+ goto unlock_and_exit;
+ }
+
+ /* Fill in the instance data */
+
+ allocation->size = (u32)size;
+ allocation->alloc_type = alloc_type;
+ allocation->component = component;
+ allocation->line = line;
+
+ ACPI_STRNCPY(allocation->module, module, ACPI_MAX_MODULE_NAME);
+ allocation->module[ACPI_MAX_MODULE_NAME - 1] = 0;
+
+ if (!element) {
+
+ /* Insert at list head */
+
+ if (mem_list->list_head) {
+ ((struct acpi_debug_mem_block *)(mem_list->list_head))->
+ previous = allocation;
+ }
+
+ allocation->next = mem_list->list_head;
+ allocation->previous = NULL;
+
+ mem_list->list_head = allocation;
+ } else {
+ /* Insert after element */
+
+ allocation->next = element->next;
+ allocation->previous = element;
+
+ if (element->next) {
+ (element->next)->previous = allocation;
+ }
+
+ element->next = allocation;
+ }
+
+ unlock_and_exit:
+ status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
+ return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_remove_allocation
+ *
+ * PARAMETERS: allocation - Address of allocated memory
+ * component - Component type of caller
+ * module - Source file name of caller
+ * line - Line number of caller
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Deletes an element from the global allocation tracking list.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation,
+ u32 component, const char *module, u32 line)
+{
+ struct acpi_memory_list *mem_list;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(ut_remove_allocation);
+
+ if (acpi_gbl_disable_mem_tracking) {
+ return_ACPI_STATUS(AE_OK);
+ }
+
+ mem_list = acpi_gbl_global_list;
+ if (NULL == mem_list->list_head) {
+
+ /* No allocations! */
+
+ ACPI_ERROR((module, line,
+ "Empty allocation list, nothing to free!"));
+
+ return_ACPI_STATUS(AE_OK);
+ }
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ /* Unlink */
+
+ if (allocation->previous) {
+ (allocation->previous)->next = allocation->next;
+ } else {
+ mem_list->list_head = allocation->next;
+ }
+
+ if (allocation->next) {
+ (allocation->next)->previous = allocation->previous;
+ }
+
+ /* Mark the segment as deleted */
+
+ ACPI_MEMSET(&allocation->user_space, 0xEA, allocation->size);
+
+ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n",
+ allocation->size));
+
+ status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
+ return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_dump_allocation_info
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print some info about the outstanding allocations.
+ *
+ ******************************************************************************/
+
+void acpi_ut_dump_allocation_info(void)
+{
+/*
+ struct acpi_memory_list *mem_list;
+*/
+
+ ACPI_FUNCTION_TRACE(ut_dump_allocation_info);
+
+/*
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Current allocations",
+ mem_list->current_count,
+ ROUND_UP_TO_1K (mem_list->current_size)));
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
+ mem_list->max_concurrent_count,
+ ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
+ running_object_count,
+ ROUND_UP_TO_1K (running_object_size)));
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
+ running_alloc_count,
+ ROUND_UP_TO_1K (running_alloc_size)));
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Current Nodes",
+ acpi_gbl_current_node_count,
+ ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Max Nodes",
+ acpi_gbl_max_concurrent_node_count,
+ ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count *
+ sizeof (struct acpi_namespace_node)))));
+*/
+ return_VOID;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_dump_allocations
+ *
+ * PARAMETERS: component - Component(s) to dump info for.
+ * module - Module to dump info for. NULL means all.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print a list of all outstanding allocations.
+ *
+ ******************************************************************************/
+
+void acpi_ut_dump_allocations(u32 component, const char *module)
+{
+ struct acpi_debug_mem_block *element;
+ union acpi_descriptor *descriptor;
+ u32 num_outstanding = 0;
+ u8 descriptor_type;
+
+ ACPI_FUNCTION_TRACE(ut_dump_allocations);
+
+ if (acpi_gbl_disable_mem_tracking) {
+ return_VOID;
+ }
+
+ /*
+ * Walk the allocation list.
+ */
+ if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_MEMORY))) {
+ return_VOID;
+ }
+
+ element = acpi_gbl_global_list->list_head;
+ while (element) {
+ if ((element->component & component) &&
+ ((module == NULL)
+ || (0 == ACPI_STRCMP(module, element->module)))) {
+ descriptor =
+ ACPI_CAST_PTR(union acpi_descriptor,
+ &element->user_space);
+
+ if (element->size <
+ sizeof(struct acpi_common_descriptor)) {
+ acpi_os_printf("%p Length 0x%04X %9.9s-%u "
+ "[Not a Descriptor - too small]\n",
+ descriptor, element->size,
+ element->module, element->line);
+ } else {
+ /* Ignore allocated objects that are in a cache */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE(descriptor) !=
+ ACPI_DESC_TYPE_CACHED) {
+ acpi_os_printf
+ ("%p Length 0x%04X %9.9s-%u [%s] ",
+ descriptor, element->size,
+ element->module, element->line,
+ acpi_ut_get_descriptor_name
+ (descriptor));
+
+ /* Validate the descriptor type using Type field and length */
+
+ descriptor_type = 0; /* Not a valid descriptor type */
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE
+ (descriptor)) {
+ case ACPI_DESC_TYPE_OPERAND:
+ if (element->size ==
+ sizeof(union
+ acpi_operand_object))
+ {
+ descriptor_type =
+ ACPI_DESC_TYPE_OPERAND;
+ }
+ break;
+
+ case ACPI_DESC_TYPE_PARSER:
+ if (element->size ==
+ sizeof(union
+ acpi_parse_object)) {
+ descriptor_type =
+ ACPI_DESC_TYPE_PARSER;
+ }
+ break;
+
+ case ACPI_DESC_TYPE_NAMED:
+ if (element->size ==
+ sizeof(struct
+ acpi_namespace_node))
+ {
+ descriptor_type =
+ ACPI_DESC_TYPE_NAMED;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Display additional info for the major descriptor types */
+
+ switch (descriptor_type) {
+ case ACPI_DESC_TYPE_OPERAND:
+ acpi_os_printf
+ ("%12.12s RefCount 0x%04X\n",
+ acpi_ut_get_type_name
+ (descriptor->object.common.
+ type),
+ descriptor->object.common.
+ reference_count);
+ break;
+
+ case ACPI_DESC_TYPE_PARSER:
+ acpi_os_printf
+ ("AmlOpcode 0x%04hX\n",
+ descriptor->op.asl.
+ aml_opcode);
+ break;
+
+ case ACPI_DESC_TYPE_NAMED:
+ acpi_os_printf("%4.4s\n",
+ acpi_ut_get_node_name
+ (&descriptor->
+ node));
+ break;
+
+ default:
+ acpi_os_printf("\n");
+ break;
+ }
+ }
+ }
+
+ num_outstanding++;
+ }
+
+ element = element->next;
+ }
+
+ (void)acpi_ut_release_mutex(ACPI_MTX_MEMORY);
+
+ /* Print summary */
+
+ if (!num_outstanding) {
+ ACPI_INFO((AE_INFO, "No outstanding allocations"));
+ } else {
+ ACPI_ERROR((AE_INFO, "%u(0x%X) Outstanding allocations",
+ num_outstanding, num_outstanding));
+ }
+
+ return_VOID;
+}
+
+#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c
index b09632b4f5b..390db0ca5e2 100644
--- a/drivers/acpi/acpica/utxface.c
+++ b/drivers/acpi/acpica/utxface.c
@@ -147,7 +147,7 @@ ACPI_EXPORT_SYMBOL(acpi_subsystem_status)
* RETURN: status - the status of the call
*
* DESCRIPTION: This function is called to get information about the current
- * state of the ACPI subsystem. It will return system information
+ * state of the ACPI subsystem. It will return system information
* in the out_buffer.
*
* If the function fails an appropriate status will be returned
@@ -238,7 +238,7 @@ acpi_install_initialization_handler(acpi_init_handler handler, u32 function)
}
acpi_gbl_init_handler = handler;
- return AE_OK;
+ return (AE_OK);
}
ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler)
@@ -263,6 +263,7 @@ acpi_status acpi_purge_cached_objects(void)
(void)acpi_os_purge_cache(acpi_gbl_operand_cache);
(void)acpi_os_purge_cache(acpi_gbl_ps_node_cache);
(void)acpi_os_purge_cache(acpi_gbl_ps_node_ext_cache);
+
return_ACPI_STATUS(AE_OK);
}
diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c
index 6d63cc39b9a..d4d3826140d 100644
--- a/drivers/acpi/acpica/utxferror.c
+++ b/drivers/acpi/acpica/utxferror.c
@@ -408,7 +408,7 @@ acpi_ut_namespace_error(const char *module_name,
ACPI_MOVE_32_TO_32(&bad_name,
ACPI_CAST_PTR(u32, internal_name));
- acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name);
+ acpi_os_printf("[0x%.8X] (NON-ASCII)", bad_name);
} else {
/* Convert path to external format */
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 1599566ed1f..7ae2750bb45 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -901,7 +901,7 @@ static unsigned long ghes_esource_prealloc_size(
return prealloc_size;
}
-static int __devinit ghes_probe(struct platform_device *ghes_dev)
+static int ghes_probe(struct platform_device *ghes_dev)
{
struct acpi_hest_generic *generic;
struct ghes *ghes = NULL;
@@ -994,7 +994,7 @@ err:
return rc;
}
-static int __devexit ghes_remove(struct platform_device *ghes_dev)
+static int ghes_remove(struct platform_device *ghes_dev)
{
struct ghes *ghes;
struct acpi_hest_generic *generic;
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 45e3e1759fb..7efaeaa53b8 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -34,6 +34,7 @@
#include <linux/dmi.h>
#include <linux/slab.h>
#include <linux/suspend.h>
+#include <asm/unaligned.h>
#ifdef CONFIG_ACPI_PROCFS_POWER
#include <linux/proc_fs.h>
@@ -95,6 +96,18 @@ enum {
ACPI_BATTERY_ALARM_PRESENT,
ACPI_BATTERY_XINFO_PRESENT,
ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
+ /* On Lenovo Thinkpad models from 2010 and 2011, the power unit
+ switches between mWh and mAh depending on whether the system
+ is running on battery or not. When mAh is the unit, most
+ reported values are incorrect and need to be adjusted by
+ 10000/design_voltage. Verified on x201, t410, t410s, and x220.
+ Pre-2010 and 2012 models appear to always report in mWh and
+ are thus unaffected (tested with t42, t61, t500, x200, x300,
+ and x230). Also, in mid-2012 Lenovo issued a BIOS update for
+ the 2011 models that fixes the issue (tested on x220 with a
+ post-1.29 BIOS), but as of Nov. 2012, no such update is
+ available for the 2010 models. */
+ ACPI_BATTERY_QUIRK_THINKPAD_MAH,
};
struct acpi_battery {
@@ -438,6 +451,21 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
kfree(buffer.pointer);
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
battery->full_charge_capacity = battery->design_capacity;
+ if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
+ battery->power_unit && battery->design_voltage) {
+ battery->design_capacity = battery->design_capacity *
+ 10000 / battery->design_voltage;
+ battery->full_charge_capacity = battery->full_charge_capacity *
+ 10000 / battery->design_voltage;
+ battery->design_capacity_warning =
+ battery->design_capacity_warning *
+ 10000 / battery->design_voltage;
+ /* Curiously, design_capacity_low, unlike the rest of them,
+ is correct. */
+ /* capacity_granularity_* equal 1 on the systems tested, so
+ it's impossible to tell if they would need an adjustment
+ or not if their values were higher. */
+ }
return result;
}
@@ -486,6 +514,11 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
&& battery->capacity_now >= 0 && battery->capacity_now <= 100)
battery->capacity_now = (battery->capacity_now *
battery->full_charge_capacity) / 100;
+ if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
+ battery->power_unit && battery->design_voltage) {
+ battery->capacity_now = battery->capacity_now *
+ 10000 / battery->design_voltage;
+ }
return result;
}
@@ -595,6 +628,24 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
mutex_unlock(&battery->sysfs_lock);
}
+static void find_battery(const struct dmi_header *dm, void *private)
+{
+ struct acpi_battery *battery = (struct acpi_battery *)private;
+ /* Note: the hardcoded offsets below have been extracted from
+ the source code of dmidecode. */
+ if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) {
+ const u8 *dmi_data = (const u8 *)(dm + 1);
+ int dmi_capacity = get_unaligned((const u16 *)(dmi_data + 6));
+ if (dm->length >= 18)
+ dmi_capacity *= dmi_data[17];
+ if (battery->design_capacity * battery->design_voltage / 1000
+ != dmi_capacity &&
+ battery->design_capacity * 10 == dmi_capacity)
+ set_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
+ &battery->flags);
+ }
+}
+
/*
* According to the ACPI spec, some kinds of primary batteries can
* report percentage battery remaining capacity directly to OS.
@@ -620,6 +671,32 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
battery->capacity_now = (battery->capacity_now *
battery->full_charge_capacity) / 100;
}
+
+ if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
+ return ;
+
+ if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
+ const char *s;
+ s = dmi_get_system_info(DMI_PRODUCT_VERSION);
+ if (s && !strnicmp(s, "ThinkPad", 8)) {
+ dmi_walk(find_battery, battery);
+ if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
+ &battery->flags) &&
+ battery->design_voltage) {
+ battery->design_capacity =
+ battery->design_capacity *
+ 10000 / battery->design_voltage;
+ battery->full_charge_capacity =
+ battery->full_charge_capacity *
+ 10000 / battery->design_voltage;
+ battery->design_capacity_warning =
+ battery->design_capacity_warning *
+ 10000 / battery->design_voltage;
+ battery->capacity_now = battery->capacity_now *
+ 10000 / battery->design_voltage;
+ }
+ }
+ }
}
static int acpi_battery_update(struct acpi_battery *battery)
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index d59175efc42..1f0d457ecbc 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -257,7 +257,15 @@ static int __acpi_bus_get_power(struct acpi_device *device, int *state)
}
-static int __acpi_bus_set_power(struct acpi_device *device, int state)
+/**
+ * acpi_device_set_power - Set power state of an ACPI device.
+ * @device: Device to set the power state of.
+ * @state: New power state to set.
+ *
+ * Callers must ensure that the device is power manageable before using this
+ * function.
+ */
+int acpi_device_set_power(struct acpi_device *device, int state)
{
int result = 0;
acpi_status status = AE_OK;
@@ -298,6 +306,12 @@ static int __acpi_bus_set_power(struct acpi_device *device, int state)
* a lower-powered state.
*/
if (state < device->power.state) {
+ if (device->power.state >= ACPI_STATE_D3_HOT &&
+ state != ACPI_STATE_D0) {
+ printk(KERN_WARNING PREFIX
+ "Cannot transition to non-D0 state from D3\n");
+ return -ENODEV;
+ }
if (device->power.flags.power_resources) {
result = acpi_power_transition(device, state);
if (result)
@@ -341,6 +355,7 @@ static int __acpi_bus_set_power(struct acpi_device *device, int state)
return result;
}
+EXPORT_SYMBOL(acpi_device_set_power);
int acpi_bus_set_power(acpi_handle handle, int state)
@@ -359,7 +374,7 @@ int acpi_bus_set_power(acpi_handle handle, int state)
return -ENODEV;
}
- return __acpi_bus_set_power(device, state);
+ return acpi_device_set_power(device, state);
}
EXPORT_SYMBOL(acpi_bus_set_power);
@@ -402,7 +417,7 @@ int acpi_bus_update_power(acpi_handle handle, int *state_p)
if (result)
return result;
- result = __acpi_bus_set_power(device, state);
+ result = acpi_device_set_power(device, state);
if (!result && state_p)
*state_p = state;
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 1f9f7d7d7bc..811910b50b7 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -92,17 +92,24 @@ static int is_device_present(acpi_handle handle)
return ((sta & ACPI_STA_DEVICE_PRESENT) == ACPI_STA_DEVICE_PRESENT);
}
+static bool is_container_device(const char *hid)
+{
+ const struct acpi_device_id *container_id;
+
+ for (container_id = container_device_ids;
+ container_id->id[0]; container_id++) {
+ if (!strcmp((char *)container_id->id, hid))
+ return true;
+ }
+
+ return false;
+}
+
/*******************************************************************/
static int acpi_container_add(struct acpi_device *device)
{
struct acpi_container *container;
-
- if (!device) {
- printk(KERN_ERR PREFIX "device is NULL\n");
- return -EINVAL;
- }
-
container = kzalloc(sizeof(struct acpi_container), GFP_KERNEL);
if (!container)
return -ENOMEM;
@@ -164,7 +171,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
case ACPI_NOTIFY_BUS_CHECK:
/* Fall through */
case ACPI_NOTIFY_DEVICE_CHECK:
- printk(KERN_WARNING "Container driver received %s event\n",
+ pr_debug("Container driver received %s event\n",
(type == ACPI_NOTIFY_BUS_CHECK) ?
"ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK");
@@ -185,7 +192,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
result = container_device_add(&device, handle);
if (result) {
- printk(KERN_WARNING "Failed to add container\n");
+ acpi_handle_warn(handle, "Failed to add container\n");
break;
}
@@ -232,10 +239,8 @@ container_walk_namespace_cb(acpi_handle handle,
goto end;
}
- if (strcmp(hid, "ACPI0004") && strcmp(hid, "PNP0A05") &&
- strcmp(hid, "PNP0A06")) {
+ if (!is_container_device(hid))
goto end;
- }
switch (*action) {
case INSTALL_NOTIFY_HANDLER:
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
new file mode 100644
index 00000000000..f09dc987cf1
--- /dev/null
+++ b/drivers/acpi/device_pm.c
@@ -0,0 +1,668 @@
+/*
+ * drivers/acpi/device_pm.c - ACPI device power management routines.
+ *
+ * Copyright (C) 2012, Intel Corp.
+ * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/mutex.h>
+#include <linux/pm_qos.h>
+#include <linux/pm_runtime.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acpi_bus.h>
+
+static DEFINE_MUTEX(acpi_pm_notifier_lock);
+
+/**
+ * acpi_add_pm_notifier - Register PM notifier for given ACPI device.
+ * @adev: ACPI device to add the notifier for.
+ * @context: Context information to pass to the notifier routine.
+ *
+ * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of
+ * PM wakeup events. For example, wakeup events may be generated for bridges
+ * if one of the devices below the bridge is signaling wakeup, even if the
+ * bridge itself doesn't have a wakeup GPE associated with it.
+ */
+acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
+ acpi_notify_handler handler, void *context)
+{
+ acpi_status status = AE_ALREADY_EXISTS;
+
+ mutex_lock(&acpi_pm_notifier_lock);
+
+ if (adev->wakeup.flags.notifier_present)
+ goto out;
+
+ status = acpi_install_notify_handler(adev->handle,
+ ACPI_SYSTEM_NOTIFY,
+ handler, context);
+ if (ACPI_FAILURE(status))
+ goto out;
+
+ adev->wakeup.flags.notifier_present = true;
+
+ out:
+ mutex_unlock(&acpi_pm_notifier_lock);
+ return status;
+}
+
+/**
+ * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device.
+ * @adev: ACPI device to remove the notifier from.
+ */
+acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
+ acpi_notify_handler handler)
+{
+ acpi_status status = AE_BAD_PARAMETER;
+
+ mutex_lock(&acpi_pm_notifier_lock);
+
+ if (!adev->wakeup.flags.notifier_present)
+ goto out;
+
+ status = acpi_remove_notify_handler(adev->handle,
+ ACPI_SYSTEM_NOTIFY,
+ handler);
+ if (ACPI_FAILURE(status))
+ goto out;
+
+ adev->wakeup.flags.notifier_present = false;
+
+ out:
+ mutex_unlock(&acpi_pm_notifier_lock);
+ return status;
+}
+
+/**
+ * acpi_device_power_state - Get preferred power state of ACPI device.
+ * @dev: Device whose preferred target power state to return.
+ * @adev: ACPI device node corresponding to @dev.
+ * @target_state: System state to match the resultant device state.
+ * @d_max_in: Deepest low-power state to take into consideration.
+ * @d_min_p: Location to store the upper limit of the allowed states range.
+ * Return value: Preferred power state of the device on success, -ENODEV
+ * (if there's no 'struct acpi_device' for @dev) or -EINVAL on failure
+ *
+ * Find the lowest power (highest number) ACPI device power state that the
+ * device can be in while the system is in the state represented by
+ * @target_state. If @d_min_p is set, the highest power (lowest number) device
+ * power state that @dev can be in for the given system sleep state is stored
+ * at the location pointed to by it.
+ *
+ * Callers must ensure that @dev and @adev are valid pointers and that @adev
+ * actually corresponds to @dev before using this function.
+ */
+int acpi_device_power_state(struct device *dev, struct acpi_device *adev,
+ u32 target_state, int d_max_in, int *d_min_p)
+{
+ char acpi_method[] = "_SxD";
+ unsigned long long d_min, d_max;
+ bool wakeup = false;
+
+ if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3)
+ return -EINVAL;
+
+ if (d_max_in > ACPI_STATE_D3_HOT) {
+ enum pm_qos_flags_status stat;
+
+ stat = dev_pm_qos_flags(dev, PM_QOS_FLAG_NO_POWER_OFF);
+ if (stat == PM_QOS_FLAGS_ALL)
+ d_max_in = ACPI_STATE_D3_HOT;
+ }
+
+ acpi_method[2] = '0' + target_state;
+ /*
+ * If the sleep state is S0, the lowest limit from ACPI is D3,
+ * but if the device has _S0W, we will use the value from _S0W
+ * as the lowest limit from ACPI. Finally, we will constrain
+ * the lowest limit with the specified one.
+ */
+ d_min = ACPI_STATE_D0;
+ d_max = ACPI_STATE_D3;
+
+ /*
+ * If present, _SxD methods return the minimum D-state (highest power
+ * state) we can use for the corresponding S-states. Otherwise, the
+ * minimum D-state is D0 (ACPI 3.x).
+ *
+ * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer
+ * provided -- that's our fault recovery, we ignore retval.
+ */
+ if (target_state > ACPI_STATE_S0) {
+ acpi_evaluate_integer(adev->handle, acpi_method, NULL, &d_min);
+ wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid
+ && adev->wakeup.sleep_state >= target_state;
+ } else if (dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) !=
+ PM_QOS_FLAGS_NONE) {
+ wakeup = adev->wakeup.flags.valid;
+ }
+
+ /*
+ * If _PRW says we can wake up the system from the target sleep state,
+ * the D-state returned by _SxD is sufficient for that (we assume a
+ * wakeup-aware driver if wake is set). Still, if _SxW exists
+ * (ACPI 3.x), it should return the maximum (lowest power) D-state that
+ * can wake the system. _S0W may be valid, too.
+ */
+ if (wakeup) {
+ acpi_status status;
+
+ acpi_method[3] = 'W';
+ status = acpi_evaluate_integer(adev->handle, acpi_method, NULL,
+ &d_max);
+ if (ACPI_FAILURE(status)) {
+ if (target_state != ACPI_STATE_S0 ||
+ status != AE_NOT_FOUND)
+ d_max = d_min;
+ } else if (d_max < d_min) {
+ /* Warn the user of the broken DSDT */
+ printk(KERN_WARNING "ACPI: Wrong value from %s\n",
+ acpi_method);
+ /* Sanitize it */
+ d_min = d_max;
+ }
+ }
+
+ if (d_max_in < d_min)
+ return -EINVAL;
+ if (d_min_p)
+ *d_min_p = d_min;
+ /* constrain d_max with specified lowest limit (max number) */
+ if (d_max > d_max_in) {
+ for (d_max = d_max_in; d_max > d_min; d_max--) {
+ if (adev->power.states[d_max].flags.valid)
+ break;
+ }
+ }
+ return d_max;
+}
+EXPORT_SYMBOL_GPL(acpi_device_power_state);
+
+/**
+ * acpi_pm_device_sleep_state - Get preferred power state of ACPI device.
+ * @dev: Device whose preferred target power state to return.
+ * @d_min_p: Location to store the upper limit of the allowed states range.
+ * @d_max_in: Deepest low-power state to take into consideration.
+ * Return value: Preferred power state of the device on success, -ENODEV
+ * (if there's no 'struct acpi_device' for @dev) or -EINVAL on failure
+ *
+ * The caller must ensure that @dev is valid before using this function.
+ */
+int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in)
+{
+ acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
+ struct acpi_device *adev;
+
+ if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
+ dev_dbg(dev, "ACPI handle without context in %s!\n", __func__);
+ return -ENODEV;
+ }
+
+ return acpi_device_power_state(dev, adev, acpi_target_system_state(),
+ d_max_in, d_min_p);
+}
+EXPORT_SYMBOL(acpi_pm_device_sleep_state);
+
+#ifdef CONFIG_PM_RUNTIME
+/**
+ * acpi_wakeup_device - Wakeup notification handler for ACPI devices.
+ * @handle: ACPI handle of the device the notification is for.
+ * @event: Type of the signaled event.
+ * @context: Device corresponding to @handle.
+ */
+static void acpi_wakeup_device(acpi_handle handle, u32 event, void *context)
+{
+ struct device *dev = context;
+
+ if (event == ACPI_NOTIFY_DEVICE_WAKE && dev) {
+ pm_wakeup_event(dev, 0);
+ pm_runtime_resume(dev);
+ }
+}
+
+/**
+ * __acpi_device_run_wake - Enable/disable runtime remote wakeup for device.
+ * @adev: ACPI device to enable/disable the remote wakeup for.
+ * @enable: Whether to enable or disable the wakeup functionality.
+ *
+ * Enable/disable the GPE associated with @adev so that it can generate
+ * wakeup signals for the device in response to external (remote) events and
+ * enable/disable device wakeup power.
+ *
+ * Callers must ensure that @adev is a valid ACPI device node before executing
+ * this function.
+ */
+int __acpi_device_run_wake(struct acpi_device *adev, bool enable)
+{
+ struct acpi_device_wakeup *wakeup = &adev->wakeup;
+
+ if (enable) {
+ acpi_status res;
+ int error;
+
+ error = acpi_enable_wakeup_device_power(adev, ACPI_STATE_S0);
+ if (error)
+ return error;
+
+ res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number);
+ if (ACPI_FAILURE(res)) {
+ acpi_disable_wakeup_device_power(adev);
+ return -EIO;
+ }
+ } else {
+ acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number);
+ acpi_disable_wakeup_device_power(adev);
+ }
+ return 0;
+}
+
+/**
+ * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device.
+ * @dev: Device to enable/disable the platform to wake up.
+ * @enable: Whether to enable or disable the wakeup functionality.
+ */
+int acpi_pm_device_run_wake(struct device *phys_dev, bool enable)
+{
+ struct acpi_device *adev;
+ acpi_handle handle;
+
+ if (!device_run_wake(phys_dev))
+ return -EINVAL;
+
+ handle = DEVICE_ACPI_HANDLE(phys_dev);
+ if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
+ dev_dbg(phys_dev, "ACPI handle without context in %s!\n",
+ __func__);
+ return -ENODEV;
+ }
+
+ return __acpi_device_run_wake(adev, enable);
+}
+EXPORT_SYMBOL(acpi_pm_device_run_wake);
+#else
+static inline void acpi_wakeup_device(acpi_handle handle, u32 event,
+ void *context) {}
+#endif /* CONFIG_PM_RUNTIME */
+
+ #ifdef CONFIG_PM_SLEEP
+/**
+ * __acpi_device_sleep_wake - Enable or disable device to wake up the system.
+ * @dev: Device to enable/desible to wake up the system.
+ * @target_state: System state the device is supposed to wake up from.
+ * @enable: Whether to enable or disable @dev to wake up the system.
+ */
+int __acpi_device_sleep_wake(struct acpi_device *adev, u32 target_state,
+ bool enable)
+{
+ return enable ?
+ acpi_enable_wakeup_device_power(adev, target_state) :
+ acpi_disable_wakeup_device_power(adev);
+}
+
+/**
+ * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system.
+ * @dev: Device to enable/desible to wake up the system from sleep states.
+ * @enable: Whether to enable or disable @dev to wake up the system.
+ */
+int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
+{
+ acpi_handle handle;
+ struct acpi_device *adev;
+ int error;
+
+ if (!device_can_wakeup(dev))
+ return -EINVAL;
+
+ handle = DEVICE_ACPI_HANDLE(dev);
+ if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
+ dev_dbg(dev, "ACPI handle without context in %s!\n", __func__);
+ return -ENODEV;
+ }
+
+ error = __acpi_device_sleep_wake(adev, acpi_target_system_state(),
+ enable);
+ if (!error)
+ dev_info(dev, "System wakeup %s by ACPI\n",
+ enable ? "enabled" : "disabled");
+
+ return error;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+/**
+ * acpi_dev_pm_get_node - Get ACPI device node for the given physical device.
+ * @dev: Device to get the ACPI node for.
+ */
+static struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
+{
+ acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
+ struct acpi_device *adev;
+
+ return handle && ACPI_SUCCESS(acpi_bus_get_device(handle, &adev)) ?
+ adev : NULL;
+}
+
+/**
+ * acpi_dev_pm_low_power - Put ACPI device into a low-power state.
+ * @dev: Device to put into a low-power state.
+ * @adev: ACPI device node corresponding to @dev.
+ * @system_state: System state to choose the device state for.
+ */
+static int acpi_dev_pm_low_power(struct device *dev, struct acpi_device *adev,
+ u32 system_state)
+{
+ int power_state;
+
+ if (!acpi_device_power_manageable(adev))
+ return 0;
+
+ power_state = acpi_device_power_state(dev, adev, system_state,
+ ACPI_STATE_D3, NULL);
+ if (power_state < ACPI_STATE_D0 || power_state > ACPI_STATE_D3)
+ return -EIO;
+
+ return acpi_device_set_power(adev, power_state);
+}
+
+/**
+ * acpi_dev_pm_full_power - Put ACPI device into the full-power state.
+ * @adev: ACPI device node to put into the full-power state.
+ */
+static int acpi_dev_pm_full_power(struct acpi_device *adev)
+{
+ return acpi_device_power_manageable(adev) ?
+ acpi_device_set_power(adev, ACPI_STATE_D0) : 0;
+}
+
+#ifdef CONFIG_PM_RUNTIME
+/**
+ * acpi_dev_runtime_suspend - Put device into a low-power state using ACPI.
+ * @dev: Device to put into a low-power state.
+ *
+ * Put the given device into a runtime low-power state using the standard ACPI
+ * mechanism. Set up remote wakeup if desired, choose the state to put the
+ * device into (this checks if remote wakeup is expected to work too), and set
+ * the power state of the device.
+ */
+int acpi_dev_runtime_suspend(struct device *dev)
+{
+ struct acpi_device *adev = acpi_dev_pm_get_node(dev);
+ bool remote_wakeup;
+ int error;
+
+ if (!adev)
+ return 0;
+
+ remote_wakeup = dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) >
+ PM_QOS_FLAGS_NONE;
+ error = __acpi_device_run_wake(adev, remote_wakeup);
+ if (remote_wakeup && error)
+ return -EAGAIN;
+
+ error = acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
+ if (error)
+ __acpi_device_run_wake(adev, false);
+
+ return error;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_runtime_suspend);
+
+/**
+ * acpi_dev_runtime_resume - Put device into the full-power state using ACPI.
+ * @dev: Device to put into the full-power state.
+ *
+ * Put the given device into the full-power state using the standard ACPI
+ * mechanism at run time. Set the power state of the device to ACPI D0 and
+ * disable remote wakeup.
+ */
+int acpi_dev_runtime_resume(struct device *dev)
+{
+ struct acpi_device *adev = acpi_dev_pm_get_node(dev);
+ int error;
+
+ if (!adev)
+ return 0;
+
+ error = acpi_dev_pm_full_power(adev);
+ __acpi_device_run_wake(adev, false);
+ return error;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume);
+
+/**
+ * acpi_subsys_runtime_suspend - Suspend device using ACPI.
+ * @dev: Device to suspend.
+ *
+ * Carry out the generic runtime suspend procedure for @dev and use ACPI to put
+ * it into a runtime low-power state.
+ */
+int acpi_subsys_runtime_suspend(struct device *dev)
+{
+ int ret = pm_generic_runtime_suspend(dev);
+ return ret ? ret : acpi_dev_runtime_suspend(dev);
+}
+EXPORT_SYMBOL_GPL(acpi_subsys_runtime_suspend);
+
+/**
+ * acpi_subsys_runtime_resume - Resume device using ACPI.
+ * @dev: Device to Resume.
+ *
+ * Use ACPI to put the given device into the full-power state and carry out the
+ * generic runtime resume procedure for it.
+ */
+int acpi_subsys_runtime_resume(struct device *dev)
+{
+ int ret = acpi_dev_runtime_resume(dev);
+ return ret ? ret : pm_generic_runtime_resume(dev);
+}
+EXPORT_SYMBOL_GPL(acpi_subsys_runtime_resume);
+#endif /* CONFIG_PM_RUNTIME */
+
+#ifdef CONFIG_PM_SLEEP
+/**
+ * acpi_dev_suspend_late - Put device into a low-power state using ACPI.
+ * @dev: Device to put into a low-power state.
+ *
+ * Put the given device into a low-power state during system transition to a
+ * sleep state using the standard ACPI mechanism. Set up system wakeup if
+ * desired, choose the state to put the device into (this checks if system
+ * wakeup is expected to work too), and set the power state of the device.
+ */
+int acpi_dev_suspend_late(struct device *dev)
+{
+ struct acpi_device *adev = acpi_dev_pm_get_node(dev);
+ u32 target_state;
+ bool wakeup;
+ int error;
+
+ if (!adev)
+ return 0;
+
+ target_state = acpi_target_system_state();
+ wakeup = device_may_wakeup(dev);
+ error = __acpi_device_sleep_wake(adev, target_state, wakeup);
+ if (wakeup && error)
+ return error;
+
+ error = acpi_dev_pm_low_power(dev, adev, target_state);
+ if (error)
+ __acpi_device_sleep_wake(adev, ACPI_STATE_UNKNOWN, false);
+
+ return error;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_suspend_late);
+
+/**
+ * acpi_dev_resume_early - Put device into the full-power state using ACPI.
+ * @dev: Device to put into the full-power state.
+ *
+ * Put the given device into the full-power state using the standard ACPI
+ * mechanism during system transition to the working state. Set the power
+ * state of the device to ACPI D0 and disable remote wakeup.
+ */
+int acpi_dev_resume_early(struct device *dev)
+{
+ struct acpi_device *adev = acpi_dev_pm_get_node(dev);
+ int error;
+
+ if (!adev)
+ return 0;
+
+ error = acpi_dev_pm_full_power(adev);
+ __acpi_device_sleep_wake(adev, ACPI_STATE_UNKNOWN, false);
+ return error;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
+
+/**
+ * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
+ * @dev: Device to prepare.
+ */
+int acpi_subsys_prepare(struct device *dev)
+{
+ /*
+ * Follow PCI and resume devices suspended at run time before running
+ * their system suspend callbacks.
+ */
+ pm_runtime_resume(dev);
+ return pm_generic_prepare(dev);
+}
+EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
+
+/**
+ * acpi_subsys_suspend_late - Suspend device using ACPI.
+ * @dev: Device to suspend.
+ *
+ * Carry out the generic late suspend procedure for @dev and use ACPI to put
+ * it into a low-power state during system transition into a sleep state.
+ */
+int acpi_subsys_suspend_late(struct device *dev)
+{
+ int ret = pm_generic_suspend_late(dev);
+ return ret ? ret : acpi_dev_suspend_late(dev);
+}
+EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late);
+
+/**
+ * acpi_subsys_resume_early - Resume device using ACPI.
+ * @dev: Device to Resume.
+ *
+ * Use ACPI to put the given device into the full-power state and carry out the
+ * generic early resume procedure for it during system transition into the
+ * working state.
+ */
+int acpi_subsys_resume_early(struct device *dev)
+{
+ int ret = acpi_dev_resume_early(dev);
+ return ret ? ret : pm_generic_resume_early(dev);
+}
+EXPORT_SYMBOL_GPL(acpi_subsys_resume_early);
+#endif /* CONFIG_PM_SLEEP */
+
+static struct dev_pm_domain acpi_general_pm_domain = {
+ .ops = {
+#ifdef CONFIG_PM_RUNTIME
+ .runtime_suspend = acpi_subsys_runtime_suspend,
+ .runtime_resume = acpi_subsys_runtime_resume,
+ .runtime_idle = pm_generic_runtime_idle,
+#endif
+#ifdef CONFIG_PM_SLEEP
+ .prepare = acpi_subsys_prepare,
+ .suspend_late = acpi_subsys_suspend_late,
+ .resume_early = acpi_subsys_resume_early,
+ .poweroff_late = acpi_subsys_suspend_late,
+ .restore_early = acpi_subsys_resume_early,
+#endif
+ },
+};
+
+/**
+ * acpi_dev_pm_attach - Prepare device for ACPI power management.
+ * @dev: Device to prepare.
+ * @power_on: Whether or not to power on the device.
+ *
+ * If @dev has a valid ACPI handle that has a valid struct acpi_device object
+ * attached to it, install a wakeup notification handler for the device and
+ * add it to the general ACPI PM domain. If @power_on is set, the device will
+ * be put into the ACPI D0 state before the function returns.
+ *
+ * This assumes that the @dev's bus type uses generic power management callbacks
+ * (or doesn't use any power management callbacks at all).
+ *
+ * Callers must ensure proper synchronization of this function with power
+ * management callbacks.
+ */
+int acpi_dev_pm_attach(struct device *dev, bool power_on)
+{
+ struct acpi_device *adev = acpi_dev_pm_get_node(dev);
+
+ if (!adev)
+ return -ENODEV;
+
+ if (dev->pm_domain)
+ return -EEXIST;
+
+ acpi_add_pm_notifier(adev, acpi_wakeup_device, dev);
+ dev->pm_domain = &acpi_general_pm_domain;
+ if (power_on) {
+ acpi_dev_pm_full_power(adev);
+ __acpi_device_run_wake(adev, false);
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
+
+/**
+ * acpi_dev_pm_detach - Remove ACPI power management from the device.
+ * @dev: Device to take care of.
+ * @power_off: Whether or not to try to remove power from the device.
+ *
+ * Remove the device from the general ACPI PM domain and remove its wakeup
+ * notifier. If @power_off is set, additionally remove power from the device if
+ * possible.
+ *
+ * Callers must ensure proper synchronization of this function with power
+ * management callbacks.
+ */
+void acpi_dev_pm_detach(struct device *dev, bool power_off)
+{
+ struct acpi_device *adev = acpi_dev_pm_get_node(dev);
+
+ if (adev && dev->pm_domain == &acpi_general_pm_domain) {
+ dev->pm_domain = NULL;
+ acpi_remove_pm_notifier(adev, acpi_wakeup_device);
+ if (power_off) {
+ /*
+ * If the device's PM QoS resume latency limit or flags
+ * have been exposed to user space, they have to be
+ * hidden at this point, so that they don't affect the
+ * choice of the low-power state to put the device into.
+ */
+ dev_pm_qos_hide_latency_limit(dev);
+ dev_pm_qos_hide_flags(dev);
+ __acpi_device_run_wake(adev, false);
+ acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(acpi_dev_pm_detach);
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 88eb1430466..f32bd47b35e 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -31,6 +31,7 @@
#include <linux/platform_device.h>
#include <linux/jiffies.h>
#include <linux/stddef.h>
+#include <linux/acpi.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
@@ -460,12 +461,8 @@ static void handle_dock(struct dock_station *ds, int dock)
struct acpi_object_list arg_list;
union acpi_object arg;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer);
-
- printk(KERN_INFO PREFIX "%s - %s\n",
- (char *)name_buffer.pointer, dock ? "docking" : "undocking");
+ acpi_handle_info(ds->handle, "%s\n", dock ? "docking" : "undocking");
/* _DCK method has one argument */
arg_list.count = 1;
@@ -474,11 +471,10 @@ static void handle_dock(struct dock_station *ds, int dock)
arg.integer.value = dock;
status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
- ACPI_EXCEPTION((AE_INFO, status, "%s - failed to execute"
- " _DCK\n", (char *)name_buffer.pointer));
+ acpi_handle_err(ds->handle, "Failed to execute _DCK (0x%x)\n",
+ status);
kfree(buffer.pointer);
- kfree(name_buffer.pointer);
}
static inline void dock(struct dock_station *ds)
@@ -525,9 +521,11 @@ static void dock_lock(struct dock_station *ds, int lock)
status = acpi_evaluate_object(ds->handle, "_LCK", &arg_list, NULL);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
if (lock)
- printk(KERN_WARNING PREFIX "Locking device failed\n");
+ acpi_handle_warn(ds->handle,
+ "Locking device failed (0x%x)\n", status);
else
- printk(KERN_WARNING PREFIX "Unlocking device failed\n");
+ acpi_handle_warn(ds->handle,
+ "Unlocking device failed (0x%x)\n", status);
}
}
@@ -667,7 +665,7 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
dock_lock(ds, 0);
eject_dock(ds);
if (dock_present(ds)) {
- printk(KERN_ERR PREFIX "Unable to undock!\n");
+ acpi_handle_err(ds->handle, "Unable to undock!\n");
return -EBUSY;
}
complete_undock(ds);
@@ -715,7 +713,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
begin_dock(ds);
dock(ds);
if (!dock_present(ds)) {
- printk(KERN_ERR PREFIX "Unable to dock!\n");
+ acpi_handle_err(handle, "Unable to dock!\n");
complete_dock(ds);
break;
}
@@ -743,7 +741,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
dock_event(ds, event, UNDOCK_EVENT);
break;
default:
- printk(KERN_ERR PREFIX "Unknown dock event %d\n", event);
+ acpi_handle_err(handle, "Unknown dock event %d\n", event);
}
}
@@ -987,7 +985,7 @@ err_rmgroup:
sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group);
err_unregister:
platform_device_unregister(dd);
- printk(KERN_ERR "%s encountered error %d\n", __func__, ret);
+ acpi_handle_err(handle, "%s encountered error %d\n", __func__, ret);
return ret;
}
@@ -1016,51 +1014,39 @@ static int dock_remove(struct dock_station *ds)
}
/**
- * find_dock - look for a dock station
+ * find_dock_and_bay - look for dock stations and bays
* @handle: acpi handle of a device
* @lvl: unused
- * @context: counter of dock stations found
+ * @context: unused
* @rv: unused
*
- * This is called by acpi_walk_namespace to look for dock stations.
+ * This is called by acpi_walk_namespace to look for dock stations and bays.
*/
static __init acpi_status
-find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
+find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
{
- if (is_dock(handle))
+ if (is_dock(handle) || is_ejectable_bay(handle))
dock_add(handle);
return AE_OK;
}
-static __init acpi_status
-find_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
- /* If bay is a dock, it's already handled */
- if (is_ejectable_bay(handle) && !is_dock(handle))
- dock_add(handle);
- return AE_OK;
-}
-
static int __init dock_init(void)
{
if (acpi_disabled)
return 0;
- /* look for a dock station */
+ /* look for dock stations and bays */
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, find_dock, NULL, NULL, NULL);
+ ACPI_UINT32_MAX, find_dock_and_bay, NULL, NULL, NULL);
- /* look for bay */
- acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, find_bay, NULL, NULL, NULL);
if (!dock_station_count) {
- printk(KERN_INFO PREFIX "No dock devices found.\n");
+ pr_info(PREFIX "No dock devices found.\n");
return 0;
}
register_acpi_bus_notifier(&dock_acpi_notifier);
- printk(KERN_INFO PREFIX "%s: %d docks/bays found\n",
+ pr_info(PREFIX "%s: %d docks/bays found\n",
ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
return 0;
}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index a51df968131..354007d490d 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -158,10 +158,10 @@ static int ec_transaction_done(struct acpi_ec *ec)
{
unsigned long flags;
int ret = 0;
- spin_lock_irqsave(&ec->curr_lock, flags);
+ spin_lock_irqsave(&ec->lock, flags);
if (!ec->curr || ec->curr->done)
ret = 1;
- spin_unlock_irqrestore(&ec->curr_lock, flags);
+ spin_unlock_irqrestore(&ec->lock, flags);
return ret;
}
@@ -175,32 +175,38 @@ static void start_transaction(struct acpi_ec *ec)
static void advance_transaction(struct acpi_ec *ec, u8 status)
{
unsigned long flags;
- spin_lock_irqsave(&ec->curr_lock, flags);
- if (!ec->curr)
+ struct transaction *t = ec->curr;
+
+ spin_lock_irqsave(&ec->lock, flags);
+ if (!t)
goto unlock;
- if (ec->curr->wlen > ec->curr->wi) {
+ if (t->wlen > t->wi) {
if ((status & ACPI_EC_FLAG_IBF) == 0)
acpi_ec_write_data(ec,
- ec->curr->wdata[ec->curr->wi++]);
+ t->wdata[t->wi++]);
else
goto err;
- } else if (ec->curr->rlen > ec->curr->ri) {
+ } else if (t->rlen > t->ri) {
if ((status & ACPI_EC_FLAG_OBF) == 1) {
- ec->curr->rdata[ec->curr->ri++] = acpi_ec_read_data(ec);
- if (ec->curr->rlen == ec->curr->ri)
- ec->curr->done = true;
+ t->rdata[t->ri++] = acpi_ec_read_data(ec);
+ if (t->rlen == t->ri)
+ t->done = true;
} else
goto err;
- } else if (ec->curr->wlen == ec->curr->wi &&
+ } else if (t->wlen == t->wi &&
(status & ACPI_EC_FLAG_IBF) == 0)
- ec->curr->done = true;
+ t->done = true;
goto unlock;
err:
- /* false interrupt, state didn't change */
- if (in_interrupt())
- ++ec->curr->irq_count;
+ /*
+ * If SCI bit is set, then don't think it's a false IRQ
+ * otherwise will take a not handled IRQ as a false one.
+ */
+ if (in_interrupt() && !(status & ACPI_EC_FLAG_SCI))
+ ++t->irq_count;
+
unlock:
- spin_unlock_irqrestore(&ec->curr_lock, flags);
+ spin_unlock_irqrestore(&ec->lock, flags);
}
static int acpi_ec_sync_query(struct acpi_ec *ec);
@@ -238,9 +244,9 @@ static int ec_poll(struct acpi_ec *ec)
if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
break;
pr_debug(PREFIX "controller reset, restart transaction\n");
- spin_lock_irqsave(&ec->curr_lock, flags);
+ spin_lock_irqsave(&ec->lock, flags);
start_transaction(ec);
- spin_unlock_irqrestore(&ec->curr_lock, flags);
+ spin_unlock_irqrestore(&ec->lock, flags);
}
return -ETIME;
}
@@ -253,17 +259,17 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
if (EC_FLAGS_MSI)
udelay(ACPI_EC_MSI_UDELAY);
/* start transaction */
- spin_lock_irqsave(&ec->curr_lock, tmp);
+ spin_lock_irqsave(&ec->lock, tmp);
/* following two actions should be kept atomic */
ec->curr = t;
start_transaction(ec);
if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
- spin_unlock_irqrestore(&ec->curr_lock, tmp);
+ spin_unlock_irqrestore(&ec->lock, tmp);
ret = ec_poll(ec);
- spin_lock_irqsave(&ec->curr_lock, tmp);
+ spin_lock_irqsave(&ec->lock, tmp);
ec->curr = NULL;
- spin_unlock_irqrestore(&ec->curr_lock, tmp);
+ spin_unlock_irqrestore(&ec->lock, tmp);
return ret;
}
@@ -292,7 +298,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
return -EINVAL;
if (t->rdata)
memset(t->rdata, 0, t->rlen);
- mutex_lock(&ec->lock);
+ mutex_lock(&ec->mutex);
if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) {
status = -EINVAL;
goto unlock;
@@ -310,7 +316,8 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
status = -ETIME;
goto end;
}
- pr_debug(PREFIX "transaction start\n");
+ pr_debug(PREFIX "transaction start (cmd=0x%02x, addr=0x%02x)\n",
+ t->command, t->wdata ? t->wdata[0] : 0);
/* disable GPE during transaction if storm is detected */
if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
/* It has to be disabled, so that it doesn't trigger. */
@@ -326,8 +333,9 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
/* It is safe to enable the GPE outside of the transaction. */
acpi_enable_gpe(NULL, ec->gpe);
} else if (t->irq_count > ec_storm_threshold) {
- pr_info(PREFIX "GPE storm detected, "
- "transactions will use polling mode\n");
+ pr_info(PREFIX "GPE storm detected(%d GPEs), "
+ "transactions will use polling mode\n",
+ t->irq_count);
set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
}
pr_debug(PREFIX "transaction end\n");
@@ -335,7 +343,7 @@ end:
if (ec->global_lock)
acpi_release_global_lock(glk);
unlock:
- mutex_unlock(&ec->lock);
+ mutex_unlock(&ec->mutex);
return status;
}
@@ -403,7 +411,7 @@ int ec_burst_disable(void)
EXPORT_SYMBOL(ec_burst_disable);
-int ec_read(u8 addr, u8 * val)
+int ec_read(u8 addr, u8 *val)
{
int err;
u8 temp_data;
@@ -468,10 +476,10 @@ void acpi_ec_block_transactions(void)
if (!ec)
return;
- mutex_lock(&ec->lock);
+ mutex_lock(&ec->mutex);
/* Prevent transactions from being carried out */
set_bit(EC_FLAGS_BLOCKED, &ec->flags);
- mutex_unlock(&ec->lock);
+ mutex_unlock(&ec->mutex);
}
void acpi_ec_unblock_transactions(void)
@@ -481,10 +489,10 @@ void acpi_ec_unblock_transactions(void)
if (!ec)
return;
- mutex_lock(&ec->lock);
+ mutex_lock(&ec->mutex);
/* Allow transactions to be carried out again */
clear_bit(EC_FLAGS_BLOCKED, &ec->flags);
- mutex_unlock(&ec->lock);
+ mutex_unlock(&ec->mutex);
}
void acpi_ec_unblock_transactions_early(void)
@@ -536,9 +544,9 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
handler->handle = handle;
handler->func = func;
handler->data = data;
- mutex_lock(&ec->lock);
+ mutex_lock(&ec->mutex);
list_add(&handler->node, &ec->list);
- mutex_unlock(&ec->lock);
+ mutex_unlock(&ec->mutex);
return 0;
}
@@ -547,14 +555,14 @@ EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
{
struct acpi_ec_query_handler *handler, *tmp;
- mutex_lock(&ec->lock);
+ mutex_lock(&ec->mutex);
list_for_each_entry_safe(handler, tmp, &ec->list, node) {
if (query_bit == handler->query_bit) {
list_del(&handler->node);
kfree(handler);
}
}
- mutex_unlock(&ec->lock);
+ mutex_unlock(&ec->mutex);
}
EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
@@ -601,9 +609,9 @@ static void acpi_ec_gpe_query(void *ec_cxt)
struct acpi_ec *ec = ec_cxt;
if (!ec)
return;
- mutex_lock(&ec->lock);
+ mutex_lock(&ec->mutex);
acpi_ec_sync_query(ec);
- mutex_unlock(&ec->lock);
+ mutex_unlock(&ec->mutex);
}
static int ec_check_sci(struct acpi_ec *ec, u8 state)
@@ -622,10 +630,11 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
u32 gpe_number, void *data)
{
struct acpi_ec *ec = data;
+ u8 status = acpi_ec_read_status(ec);
- pr_debug(PREFIX "~~~> interrupt\n");
+ pr_debug(PREFIX "~~~> interrupt, status:0x%02x\n", status);
- advance_transaction(ec, acpi_ec_read_status(ec));
+ advance_transaction(ec, status);
if (ec_transaction_done(ec) &&
(acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
wake_up(&ec->wait);
@@ -691,10 +700,10 @@ static struct acpi_ec *make_acpi_ec(void)
if (!ec)
return NULL;
ec->flags = 1 << EC_FLAGS_QUERY_PENDING;
- mutex_init(&ec->lock);
+ mutex_init(&ec->mutex);
init_waitqueue_head(&ec->wait);
INIT_LIST_HEAD(&ec->list);
- spin_lock_init(&ec->curr_lock);
+ spin_lock_init(&ec->lock);
return ec;
}
@@ -853,12 +862,12 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
ec = acpi_driver_data(device);
ec_remove_handlers(ec);
- mutex_lock(&ec->lock);
+ mutex_lock(&ec->mutex);
list_for_each_entry_safe(handler, tmp, &ec->list, node) {
list_del(&handler->node);
kfree(handler);
}
- mutex_unlock(&ec->lock);
+ mutex_unlock(&ec->mutex);
release_region(ec->data_addr, 1);
release_region(ec->command_addr, 1);
device->driver_data = NULL;
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 08373086cd7..01551840d23 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -130,46 +130,59 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
{
struct acpi_device *acpi_dev;
acpi_status status;
- struct acpi_device_physical_node *physical_node;
+ struct acpi_device_physical_node *physical_node, *pn;
char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
int retval = -EINVAL;
- if (dev->archdata.acpi_handle) {
- dev_warn(dev, "Drivers changed 'acpi_handle'\n");
- return -EINVAL;
+ if (ACPI_HANDLE(dev)) {
+ if (handle) {
+ dev_warn(dev, "ACPI handle is already set\n");
+ return -EINVAL;
+ } else {
+ handle = ACPI_HANDLE(dev);
+ }
}
+ if (!handle)
+ return -EINVAL;
get_device(dev);
status = acpi_bus_get_device(handle, &acpi_dev);
if (ACPI_FAILURE(status))
goto err;
- physical_node = kzalloc(sizeof(struct acpi_device_physical_node),
- GFP_KERNEL);
+ physical_node = kzalloc(sizeof(*physical_node), GFP_KERNEL);
if (!physical_node) {
retval = -ENOMEM;
goto err;
}
mutex_lock(&acpi_dev->physical_node_lock);
+
+ /* Sanity check. */
+ list_for_each_entry(pn, &acpi_dev->physical_node_list, node)
+ if (pn->dev == dev) {
+ dev_warn(dev, "Already associated with ACPI node\n");
+ goto err_free;
+ }
+
/* allocate physical node id according to physical_node_id_bitmap */
physical_node->node_id =
find_first_zero_bit(acpi_dev->physical_node_id_bitmap,
ACPI_MAX_PHYSICAL_NODE);
if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) {
retval = -ENOSPC;
- mutex_unlock(&acpi_dev->physical_node_lock);
- kfree(physical_node);
- goto err;
+ goto err_free;
}
set_bit(physical_node->node_id, acpi_dev->physical_node_id_bitmap);
physical_node->dev = dev;
list_add_tail(&physical_node->node, &acpi_dev->physical_node_list);
acpi_dev->physical_node_count++;
+
mutex_unlock(&acpi_dev->physical_node_lock);
- dev->archdata.acpi_handle = handle;
+ if (!ACPI_HANDLE(dev))
+ ACPI_HANDLE_SET(dev, acpi_dev->handle);
if (!physical_node->node_id)
strcpy(physical_node_name, PHYSICAL_NODE_STRING);
@@ -187,8 +200,14 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
return 0;
err:
+ ACPI_HANDLE_SET(dev, NULL);
put_device(dev);
return retval;
+
+ err_free:
+ mutex_unlock(&acpi_dev->physical_node_lock);
+ kfree(physical_node);
+ goto err;
}
static int acpi_unbind_one(struct device *dev)
@@ -198,11 +217,10 @@ static int acpi_unbind_one(struct device *dev)
acpi_status status;
struct list_head *node, *next;
- if (!dev->archdata.acpi_handle)
+ if (!ACPI_HANDLE(dev))
return 0;
- status = acpi_bus_get_device(dev->archdata.acpi_handle,
- &acpi_dev);
+ status = acpi_bus_get_device(ACPI_HANDLE(dev), &acpi_dev);
if (ACPI_FAILURE(status))
goto err;
@@ -228,7 +246,7 @@ static int acpi_unbind_one(struct device *dev)
sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name);
sysfs_remove_link(&dev->kobj, "firmware_node");
- dev->archdata.acpi_handle = NULL;
+ ACPI_HANDLE_SET(dev, NULL);
/* acpi_bind_one increase refcnt by one */
put_device(dev);
kfree(entry);
@@ -248,6 +266,10 @@ static int acpi_platform_notify(struct device *dev)
acpi_handle handle;
int ret = -EINVAL;
+ ret = acpi_bind_one(dev, NULL);
+ if (!ret)
+ goto out;
+
if (!dev->bus || !dev->parent) {
/* bridge devices genernally haven't bus or parent */
ret = acpi_find_bridge_device(dev, &handle);
@@ -261,16 +283,16 @@ static int acpi_platform_notify(struct device *dev)
}
if ((ret = type->find_device(dev, &handle)) != 0)
DBG("Can't get handler for %s\n", dev_name(dev));
- end:
+ end:
if (!ret)
acpi_bind_one(dev, handle);
+ out:
#if ACPI_GLUE_DEBUG
if (!ret) {
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- acpi_get_name(dev->archdata.acpi_handle,
- ACPI_FULL_PATHNAME, &buffer);
+ acpi_get_name(dev->acpi_handle, ACPI_FULL_PATHNAME, &buffer);
DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer);
kfree(buffer.pointer);
} else
diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c
index 20a0f2c3ca3..a0cc796932f 100644
--- a/drivers/acpi/hed.c
+++ b/drivers/acpi/hed.c
@@ -61,7 +61,7 @@ static void acpi_hed_notify(struct acpi_device *device, u32 event)
blocking_notifier_call_chain(&acpi_hed_notify_list, 0, NULL);
}
-static int __devinit acpi_hed_add(struct acpi_device *device)
+static int acpi_hed_add(struct acpi_device *device)
{
/* Only one hardware error device */
if (hed_handle)
@@ -70,7 +70,7 @@ static int __devinit acpi_hed_add(struct acpi_device *device)
return 0;
}
-static int __devexit acpi_hed_remove(struct acpi_device *device, int type)
+static int acpi_hed_remove(struct acpi_device *device, int type)
{
hed_handle = NULL;
return 0;
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index ca75b9ce048..3c407cdc1ec 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -58,11 +58,11 @@ struct acpi_ec {
unsigned long data_addr;
unsigned long global_lock;
unsigned long flags;
- struct mutex lock;
+ struct mutex mutex;
wait_queue_head_t wait;
struct list_head list;
struct transaction *curr;
- spinlock_t curr_lock;
+ spinlock_t lock;
};
extern struct acpi_ec *first_ec;
@@ -93,4 +93,11 @@ static inline int suspend_nvs_save(void) { return 0; }
static inline void suspend_nvs_restore(void) {}
#endif
+/*--------------------------------------------------------------------------
+ Platform bus support
+ -------------------------------------------------------------------------- */
+struct platform_device;
+
+struct platform_device *acpi_create_platform_device(struct acpi_device *adev);
+
#endif /* _ACPI_INTERNAL_H_ */
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 9eaf708f588..6dc4a2b1e95 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -932,7 +932,7 @@ static acpi_status __acpi_os_execute(acpi_execute_type type,
* having a static work_struct.
*/
- dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
+ dpc = kzalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
if (!dpc)
return AE_NO_MEMORY;
@@ -944,17 +944,22 @@ static acpi_status __acpi_os_execute(acpi_execute_type type,
* because the hotplug code may call driver .remove() functions,
* which invoke flush_scheduled_work/acpi_os_wait_events_complete
* to flush these workqueues.
+ *
+ * To prevent lockdep from complaining unnecessarily, make sure that
+ * there is a different static lockdep key for each workqueue by using
+ * INIT_WORK() for each of them separately.
*/
- queue = hp ? kacpi_hotplug_wq :
- (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq);
- dpc->wait = hp ? 1 : 0;
-
- if (queue == kacpi_hotplug_wq)
+ if (hp) {
+ queue = kacpi_hotplug_wq;
+ dpc->wait = 1;
INIT_WORK(&dpc->work, acpi_os_execute_deferred);
- else if (queue == kacpi_notify_wq)
+ } else if (type == OSL_NOTIFY_HANDLER) {
+ queue = kacpi_notify_wq;
INIT_WORK(&dpc->work, acpi_os_execute_deferred);
- else
+ } else {
+ queue = kacpid_wq;
INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+ }
/*
* On some machines, a software-initiated SMI causes corruption unless
@@ -986,6 +991,7 @@ acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function,
{
return __acpi_os_execute(0, function, context, 1);
}
+EXPORT_SYMBOL(acpi_os_hotplug_execute);
void acpi_os_wait_events_complete(void)
{
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 0eefa12e648..23a03249013 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -459,19 +459,19 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
*/
if (gsi < 0) {
u32 dev_gsi;
- dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin));
/* Interrupt Line values above 0xF are forbidden */
if (dev->irq > 0 && (dev->irq <= 0xF) &&
(acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) {
- printk(" - using ISA IRQ %d\n", dev->irq);
+ dev_warn(&dev->dev, "PCI INT %c: no GSI - using ISA IRQ %d\n",
+ pin_name(pin), dev->irq);
acpi_register_gsi(&dev->dev, dev_gsi,
ACPI_LEVEL_SENSITIVE,
ACPI_ACTIVE_LOW);
- return 0;
} else {
- printk("\n");
- return 0;
+ dev_warn(&dev->dev, "PCI INT %c: no GSI\n",
+ pin_name(pin));
}
+ return 0;
}
rc = acpi_register_gsi(&dev->dev, gsi, triggering, polarity);
@@ -495,11 +495,6 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
return 0;
}
-/* FIXME: implement x86/x86_64 version */
-void __attribute__ ((weak)) acpi_unregister_gsi(u32 i)
-{
-}
-
void acpi_pci_irq_disable(struct pci_dev *dev)
{
struct acpi_prt_entry *entry;
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index bce469c0b48..f70b9e5fc1b 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -445,7 +445,7 @@ out:
}
EXPORT_SYMBOL(acpi_pci_osc_control_set);
-static int __devinit acpi_pci_root_add(struct acpi_device *device)
+static int acpi_pci_root_add(struct acpi_device *device)
{
unsigned long long segment, bus;
acpi_status status;
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 40e38a06ba8..7db61b8fa11 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -473,7 +473,7 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle)
return ret;
no_power_resource:
- printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!");
+ printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!\n");
return -ENODEV;
}
EXPORT_SYMBOL_GPL(acpi_power_resource_register_device);
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index 27adb090bb3..ef98796b382 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -362,16 +362,13 @@ acpi_system_write_wakeup_device(struct file *file,
struct list_head *node, *next;
char strbuf[5];
char str[5] = "";
- unsigned int len = count;
- if (len > 4)
- len = 4;
- if (len < 0)
- return -EFAULT;
+ if (count > 4)
+ count = 4;
- if (copy_from_user(strbuf, buffer, len))
+ if (copy_from_user(strbuf, buffer, count))
return -EFAULT;
- strbuf[len] = '\0';
+ strbuf[count] = '\0';
sscanf(strbuf, "%s", str);
mutex_lock(&acpi_device_lock);
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index bd4e5dca3ff..e83311bf1eb 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -44,6 +44,7 @@
#include <linux/moduleparam.h>
#include <linux/cpuidle.h>
#include <linux/slab.h>
+#include <linux/acpi.h>
#include <asm/io.h>
#include <asm/cpu.h>
@@ -282,7 +283,9 @@ static int acpi_processor_get_info(struct acpi_device *device)
/* Declared with "Processor" statement; match ProcessorID */
status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX "Evaluating processor object\n");
+ dev_err(&device->dev,
+ "Failed to evaluate processor object (0x%x)\n",
+ status);
return -ENODEV;
}
@@ -301,8 +304,9 @@ static int acpi_processor_get_info(struct acpi_device *device)
status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
NULL, &value);
if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX
- "Evaluating processor _UID [%#x]\n", status);
+ dev_err(&device->dev,
+ "Failed to evaluate processor _UID (0x%x)\n",
+ status);
return -ENODEV;
}
device_declaration = 1;
@@ -345,7 +349,7 @@ static int acpi_processor_get_info(struct acpi_device *device)
if (!object.processor.pblk_address)
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
else if (object.processor.pblk_length != 6)
- printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n",
+ dev_err(&device->dev, "Invalid PBLK length [%d]\n",
object.processor.pblk_length);
else {
pr->throttling.address = object.processor.pblk_address;
@@ -430,8 +434,8 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
* Initialize missing things
*/
if (pr->flags.need_hotplug_init) {
- printk(KERN_INFO "Will online and init hotplugged "
- "CPU: %d\n", pr->id);
+ pr_info("Will online and init hotplugged CPU: %d\n",
+ pr->id);
WARN(acpi_processor_start(pr), "Failed to start CPU:"
" %d\n", pr->id);
pr->flags.need_hotplug_init = 0;
@@ -492,14 +496,16 @@ static __ref int acpi_processor_start(struct acpi_processor *pr)
&pr->cdev->device.kobj,
"thermal_cooling");
if (result) {
- printk(KERN_ERR PREFIX "Create sysfs link\n");
+ dev_err(&device->dev,
+ "Failed to create sysfs link 'thermal_cooling'\n");
goto err_thermal_unregister;
}
result = sysfs_create_link(&pr->cdev->device.kobj,
&device->dev.kobj,
"device");
if (result) {
- printk(KERN_ERR PREFIX "Create sysfs link\n");
+ dev_err(&pr->cdev->device,
+ "Failed to create sysfs link 'device'\n");
goto err_remove_sysfs_thermal;
}
@@ -561,8 +567,9 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
*/
if (per_cpu(processor_device_array, pr->id) != NULL &&
per_cpu(processor_device_array, pr->id) != device) {
- printk(KERN_WARNING "BIOS reported wrong ACPI id "
- "for the processor\n");
+ dev_warn(&device->dev,
+ "BIOS reported wrong ACPI id %d for the processor\n",
+ pr->id);
result = -ENODEV;
goto err_free_cpumask;
}
@@ -695,8 +702,8 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
static void acpi_processor_hotplug_notify(acpi_handle handle,
u32 event, void *data)
{
- struct acpi_processor *pr;
struct acpi_device *device = NULL;
+ struct acpi_eject_event *ej_event = NULL;
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
int result;
@@ -716,7 +723,7 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
result = acpi_processor_device_add(handle, &device);
if (result) {
- printk(KERN_ERR PREFIX "Unable to add the device\n");
+ acpi_handle_err(handle, "Unable to add the device\n");
break;
}
@@ -728,20 +735,29 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
"received ACPI_NOTIFY_EJECT_REQUEST\n"));
if (acpi_bus_get_device(handle, &device)) {
- printk(KERN_ERR PREFIX
- "Device don't exist, dropping EJECT\n");
+ acpi_handle_err(handle,
+ "Device don't exist, dropping EJECT\n");
break;
}
- pr = acpi_driver_data(device);
- if (!pr) {
- printk(KERN_ERR PREFIX
- "Driver data is NULL, dropping EJECT\n");
+ if (!acpi_driver_data(device)) {
+ acpi_handle_err(handle,
+ "Driver data is NULL, dropping EJECT\n");
break;
}
- /* REVISIT: update when eject is supported */
- ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
- break;
+ ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
+ if (!ej_event) {
+ acpi_handle_err(handle, "No memory, dropping EJECT\n");
+ break;
+ }
+
+ ej_event->handle = handle;
+ ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
+ acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
+ (void *)ej_event);
+
+ /* eject is performed asynchronously */
+ return;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -841,7 +857,7 @@ static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
* and do it when the CPU gets online the first time
* TBD: Cleanup above functions and try to do this more elegant.
*/
- printk(KERN_INFO "CPU %d got hotplugged\n", pr->id);
+ pr_info("CPU %d got hotplugged\n", pr->id);
pr->flags.need_hotplug_init = 1;
return AE_OK;
@@ -852,8 +868,22 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr)
if (cpu_online(pr->id))
cpu_down(pr->id);
+ get_online_cpus();
+ /*
+ * The cpu might become online again at this point. So we check whether
+ * the cpu has been onlined or not. If the cpu became online, it means
+ * that someone wants to use the cpu. So acpi_processor_handle_eject()
+ * returns -EAGAIN.
+ */
+ if (unlikely(cpu_online(pr->id))) {
+ put_online_cpus();
+ pr_warn("Failed to remove CPU %d, because other task "
+ "brought the CPU back online\n", pr->id);
+ return -EAGAIN;
+ }
arch_unregister_cpu(pr->id);
acpi_unmap_lsapic(pr->id);
+ put_online_cpus();
return (0);
}
#else
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index e8086c72530..f1a5da44591 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -735,31 +735,18 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
static int acpi_idle_enter_c1(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index)
{
- ktime_t kt1, kt2;
- s64 idle_time;
struct acpi_processor *pr;
struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage);
pr = __this_cpu_read(processors);
- dev->last_residency = 0;
if (unlikely(!pr))
return -EINVAL;
- local_irq_disable();
-
-
lapic_timer_state_broadcast(pr, cx, 1);
- kt1 = ktime_get_real();
acpi_idle_do_entry(cx);
- kt2 = ktime_get_real();
- idle_time = ktime_to_us(ktime_sub(kt2, kt1));
-
- /* Update device last_residency*/
- dev->last_residency = (int)idle_time;
- local_irq_enable();
lapic_timer_state_broadcast(pr, cx, 0);
return index;
@@ -806,19 +793,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
struct acpi_processor *pr;
struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage);
- ktime_t kt1, kt2;
- s64 idle_time_ns;
- s64 idle_time;
pr = __this_cpu_read(processors);
- dev->last_residency = 0;
if (unlikely(!pr))
return -EINVAL;
- local_irq_disable();
-
-
if (cx->entry_method != ACPI_CSTATE_FFH) {
current_thread_info()->status &= ~TS_POLLING;
/*
@@ -829,7 +809,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
if (unlikely(need_resched())) {
current_thread_info()->status |= TS_POLLING;
- local_irq_enable();
return -EINVAL;
}
}
@@ -843,22 +822,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
if (cx->type == ACPI_STATE_C3)
ACPI_FLUSH_CPU_CACHE();
- kt1 = ktime_get_real();
/* Tell the scheduler that we are going deep-idle: */
sched_clock_idle_sleep_event();
acpi_idle_do_entry(cx);
- kt2 = ktime_get_real();
- idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
- idle_time = idle_time_ns;
- do_div(idle_time, NSEC_PER_USEC);
- /* Update device last_residency*/
- dev->last_residency = (int)idle_time;
+ sched_clock_idle_wakeup_event(0);
- /* Tell the scheduler how much we idled: */
- sched_clock_idle_wakeup_event(idle_time_ns);
-
- local_irq_enable();
if (cx->entry_method != ACPI_CSTATE_FFH)
current_thread_info()->status |= TS_POLLING;
@@ -883,13 +852,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
struct acpi_processor *pr;
struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage);
- ktime_t kt1, kt2;
- s64 idle_time_ns;
- s64 idle_time;
-
pr = __this_cpu_read(processors);
- dev->last_residency = 0;
if (unlikely(!pr))
return -EINVAL;
@@ -899,16 +863,11 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
return drv->states[drv->safe_state_index].enter(dev,
drv, drv->safe_state_index);
} else {
- local_irq_disable();
acpi_safe_halt();
- local_irq_enable();
return -EBUSY;
}
}
- local_irq_disable();
-
-
if (cx->entry_method != ACPI_CSTATE_FFH) {
current_thread_info()->status &= ~TS_POLLING;
/*
@@ -919,7 +878,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
if (unlikely(need_resched())) {
current_thread_info()->status |= TS_POLLING;
- local_irq_enable();
return -EINVAL;
}
}
@@ -934,7 +892,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
*/
lapic_timer_state_broadcast(pr, cx, 1);
- kt1 = ktime_get_real();
/*
* disable bus master
* bm_check implies we need ARB_DIS
@@ -965,18 +922,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
c3_cpu_count--;
raw_spin_unlock(&c3_lock);
}
- kt2 = ktime_get_real();
- idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
- idle_time = idle_time_ns;
- do_div(idle_time, NSEC_PER_USEC);
-
- /* Update device last_residency*/
- dev->last_residency = (int)idle_time;
- /* Tell the scheduler how much we idled: */
- sched_clock_idle_wakeup_event(idle_time_ns);
+ sched_clock_idle_wakeup_event(0);
- local_irq_enable();
if (cx->entry_method != ACPI_CSTATE_FFH)
current_thread_info()->status |= TS_POLLING;
@@ -987,6 +935,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
struct cpuidle_driver acpi_idle_driver = {
.name = "acpi_idle",
.owner = THIS_MODULE,
+ .en_core_tk_irqen = 1,
};
/**
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
new file mode 100644
index 00000000000..a3868f6c222
--- /dev/null
+++ b/drivers/acpi/resource.c
@@ -0,0 +1,526 @@
+/*
+ * drivers/acpi/resource.c - ACPI device resources interpretation.
+ *
+ * Copyright (C) 2012, Intel Corp.
+ * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_X86
+#define valid_IRQ(i) (((i) != 0) && ((i) != 2))
+#else
+#define valid_IRQ(i) (true)
+#endif
+
+static unsigned long acpi_dev_memresource_flags(u64 len, u8 write_protect,
+ bool window)
+{
+ unsigned long flags = IORESOURCE_MEM;
+
+ if (len == 0)
+ flags |= IORESOURCE_DISABLED;
+
+ if (write_protect == ACPI_READ_WRITE_MEMORY)
+ flags |= IORESOURCE_MEM_WRITEABLE;
+
+ if (window)
+ flags |= IORESOURCE_WINDOW;
+
+ return flags;
+}
+
+static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
+ u8 write_protect)
+{
+ res->start = start;
+ res->end = start + len - 1;
+ res->flags = acpi_dev_memresource_flags(len, write_protect, false);
+}
+
+/**
+ * acpi_dev_resource_memory - Extract ACPI memory resource information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents a memory resource and
+ * if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
+{
+ struct acpi_resource_memory24 *memory24;
+ struct acpi_resource_memory32 *memory32;
+ struct acpi_resource_fixed_memory32 *fixed_memory32;
+
+ switch (ares->type) {
+ case ACPI_RESOURCE_TYPE_MEMORY24:
+ memory24 = &ares->data.memory24;
+ acpi_dev_get_memresource(res, memory24->minimum,
+ memory24->address_length,
+ memory24->write_protect);
+ break;
+ case ACPI_RESOURCE_TYPE_MEMORY32:
+ memory32 = &ares->data.memory32;
+ acpi_dev_get_memresource(res, memory32->minimum,
+ memory32->address_length,
+ memory32->write_protect);
+ break;
+ case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+ fixed_memory32 = &ares->data.fixed_memory32;
+ acpi_dev_get_memresource(res, fixed_memory32->address,
+ fixed_memory32->address_length,
+ fixed_memory32->write_protect);
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_memory);
+
+static unsigned int acpi_dev_ioresource_flags(u64 start, u64 end, u8 io_decode,
+ bool window)
+{
+ int flags = IORESOURCE_IO;
+
+ if (io_decode == ACPI_DECODE_16)
+ flags |= IORESOURCE_IO_16BIT_ADDR;
+
+ if (start > end || end >= 0x10003)
+ flags |= IORESOURCE_DISABLED;
+
+ if (window)
+ flags |= IORESOURCE_WINDOW;
+
+ return flags;
+}
+
+static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len,
+ u8 io_decode)
+{
+ u64 end = start + len - 1;
+
+ res->start = start;
+ res->end = end;
+ res->flags = acpi_dev_ioresource_flags(start, end, io_decode, false);
+}
+
+/**
+ * acpi_dev_resource_io - Extract ACPI I/O resource information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an I/O resource and
+ * if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
+{
+ struct acpi_resource_io *io;
+ struct acpi_resource_fixed_io *fixed_io;
+
+ switch (ares->type) {
+ case ACPI_RESOURCE_TYPE_IO:
+ io = &ares->data.io;
+ acpi_dev_get_ioresource(res, io->minimum,
+ io->address_length,
+ io->io_decode);
+ break;
+ case ACPI_RESOURCE_TYPE_FIXED_IO:
+ fixed_io = &ares->data.fixed_io;
+ acpi_dev_get_ioresource(res, fixed_io->address,
+ fixed_io->address_length,
+ ACPI_DECODE_10);
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_io);
+
+/**
+ * acpi_dev_resource_address_space - Extract ACPI address space information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an address space resource
+ * and if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_address_space(struct acpi_resource *ares,
+ struct resource *res)
+{
+ acpi_status status;
+ struct acpi_resource_address64 addr;
+ bool window;
+ u64 len;
+ u8 io_decode;
+
+ switch (ares->type) {
+ case ACPI_RESOURCE_TYPE_ADDRESS16:
+ case ACPI_RESOURCE_TYPE_ADDRESS32:
+ case ACPI_RESOURCE_TYPE_ADDRESS64:
+ break;
+ default:
+ return false;
+ }
+
+ status = acpi_resource_to_address64(ares, &addr);
+ if (ACPI_FAILURE(status))
+ return true;
+
+ res->start = addr.minimum;
+ res->end = addr.maximum;
+ window = addr.producer_consumer == ACPI_PRODUCER;
+
+ switch(addr.resource_type) {
+ case ACPI_MEMORY_RANGE:
+ len = addr.maximum - addr.minimum + 1;
+ res->flags = acpi_dev_memresource_flags(len,
+ addr.info.mem.write_protect,
+ window);
+ break;
+ case ACPI_IO_RANGE:
+ io_decode = addr.granularity == 0xfff ?
+ ACPI_DECODE_10 : ACPI_DECODE_16;
+ res->flags = acpi_dev_ioresource_flags(addr.minimum,
+ addr.maximum,
+ io_decode, window);
+ break;
+ case ACPI_BUS_NUMBER_RANGE:
+ res->flags = IORESOURCE_BUS;
+ break;
+ default:
+ res->flags = 0;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space);
+
+/**
+ * acpi_dev_resource_ext_address_space - Extract ACPI address space information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an extended address space
+ * resource and if that's the case, use the information in it to populate the
+ * generic resource object pointed to by @res.
+ */
+bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
+ struct resource *res)
+{
+ struct acpi_resource_extended_address64 *ext_addr;
+ bool window;
+ u64 len;
+ u8 io_decode;
+
+ if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64)
+ return false;
+
+ ext_addr = &ares->data.ext_address64;
+
+ res->start = ext_addr->minimum;
+ res->end = ext_addr->maximum;
+ window = ext_addr->producer_consumer == ACPI_PRODUCER;
+
+ switch(ext_addr->resource_type) {
+ case ACPI_MEMORY_RANGE:
+ len = ext_addr->maximum - ext_addr->minimum + 1;
+ res->flags = acpi_dev_memresource_flags(len,
+ ext_addr->info.mem.write_protect,
+ window);
+ break;
+ case ACPI_IO_RANGE:
+ io_decode = ext_addr->granularity == 0xfff ?
+ ACPI_DECODE_10 : ACPI_DECODE_16;
+ res->flags = acpi_dev_ioresource_flags(ext_addr->minimum,
+ ext_addr->maximum,
+ io_decode, window);
+ break;
+ case ACPI_BUS_NUMBER_RANGE:
+ res->flags = IORESOURCE_BUS;
+ break;
+ default:
+ res->flags = 0;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space);
+
+/**
+ * acpi_dev_irq_flags - Determine IRQ resource flags.
+ * @triggering: Triggering type as provided by ACPI.
+ * @polarity: Interrupt polarity as provided by ACPI.
+ * @shareable: Whether or not the interrupt is shareable.
+ */
+unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable)
+{
+ unsigned long flags;
+
+ if (triggering == ACPI_LEVEL_SENSITIVE)
+ flags = polarity == ACPI_ACTIVE_LOW ?
+ IORESOURCE_IRQ_LOWLEVEL : IORESOURCE_IRQ_HIGHLEVEL;
+ else
+ flags = polarity == ACPI_ACTIVE_LOW ?
+ IORESOURCE_IRQ_LOWEDGE : IORESOURCE_IRQ_HIGHEDGE;
+
+ if (shareable == ACPI_SHARED)
+ flags |= IORESOURCE_IRQ_SHAREABLE;
+
+ return flags | IORESOURCE_IRQ;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_irq_flags);
+
+static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
+{
+ res->start = gsi;
+ res->end = gsi;
+ res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED;
+}
+
+static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
+ u8 triggering, u8 polarity, u8 shareable)
+{
+ int irq, p, t;
+
+ if (!valid_IRQ(gsi)) {
+ acpi_dev_irqresource_disabled(res, gsi);
+ return;
+ }
+
+ /*
+ * In IO-APIC mode, use overrided attribute. Two reasons:
+ * 1. BIOS bug in DSDT
+ * 2. BIOS uses IO-APIC mode Interrupt Source Override
+ */
+ if (!acpi_get_override_irq(gsi, &t, &p)) {
+ u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
+ u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
+
+ if (triggering != trig || polarity != pol) {
+ pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi,
+ t ? "edge" : "level", p ? "low" : "high");
+ triggering = trig;
+ polarity = pol;
+ }
+ }
+
+ res->flags = acpi_dev_irq_flags(triggering, polarity, shareable);
+ irq = acpi_register_gsi(NULL, gsi, triggering, polarity);
+ if (irq >= 0) {
+ res->start = irq;
+ res->end = irq;
+ } else {
+ acpi_dev_irqresource_disabled(res, gsi);
+ }
+}
+
+/**
+ * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
+ * @ares: Input ACPI resource object.
+ * @index: Index into the array of GSIs represented by the resource.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an interrupt resource
+ * and @index does not exceed the resource's interrupt count (true is returned
+ * in that case regardless of the results of the other checks)). If that's the
+ * case, register the GSI corresponding to @index from the array of interrupts
+ * represented by the resource and populate the generic resource object pointed
+ * to by @res accordingly. If the registration of the GSI is not successful,
+ * IORESOURCE_DISABLED will be set it that object's flags.
+ */
+bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
+ struct resource *res)
+{
+ struct acpi_resource_irq *irq;
+ struct acpi_resource_extended_irq *ext_irq;
+
+ switch (ares->type) {
+ case ACPI_RESOURCE_TYPE_IRQ:
+ /*
+ * Per spec, only one interrupt per descriptor is allowed in
+ * _CRS, but some firmware violates this, so parse them all.
+ */
+ irq = &ares->data.irq;
+ if (index >= irq->interrupt_count) {
+ acpi_dev_irqresource_disabled(res, 0);
+ return false;
+ }
+ acpi_dev_get_irqresource(res, irq->interrupts[index],
+ irq->triggering, irq->polarity,
+ irq->sharable);
+ break;
+ case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+ ext_irq = &ares->data.extended_irq;
+ if (index >= ext_irq->interrupt_count) {
+ acpi_dev_irqresource_disabled(res, 0);
+ return false;
+ }
+ acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
+ ext_irq->triggering, ext_irq->polarity,
+ ext_irq->sharable);
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
+
+/**
+ * acpi_dev_free_resource_list - Free resource from %acpi_dev_get_resources().
+ * @list: The head of the resource list to free.
+ */
+void acpi_dev_free_resource_list(struct list_head *list)
+{
+ struct resource_list_entry *rentry, *re;
+
+ list_for_each_entry_safe(rentry, re, list, node) {
+ list_del(&rentry->node);
+ kfree(rentry);
+ }
+}
+EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list);
+
+struct res_proc_context {
+ struct list_head *list;
+ int (*preproc)(struct acpi_resource *, void *);
+ void *preproc_data;
+ int count;
+ int error;
+};
+
+static acpi_status acpi_dev_new_resource_entry(struct resource *r,
+ struct res_proc_context *c)
+{
+ struct resource_list_entry *rentry;
+
+ rentry = kmalloc(sizeof(*rentry), GFP_KERNEL);
+ if (!rentry) {
+ c->error = -ENOMEM;
+ return AE_NO_MEMORY;
+ }
+ rentry->res = *r;
+ list_add_tail(&rentry->node, c->list);
+ c->count++;
+ return AE_OK;
+}
+
+static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
+ void *context)
+{
+ struct res_proc_context *c = context;
+ struct resource r;
+ int i;
+
+ if (c->preproc) {
+ int ret;
+
+ ret = c->preproc(ares, c->preproc_data);
+ if (ret < 0) {
+ c->error = ret;
+ return AE_CTRL_TERMINATE;
+ } else if (ret > 0) {
+ return AE_OK;
+ }
+ }
+
+ memset(&r, 0, sizeof(r));
+
+ if (acpi_dev_resource_memory(ares, &r)
+ || acpi_dev_resource_io(ares, &r)
+ || acpi_dev_resource_address_space(ares, &r)
+ || acpi_dev_resource_ext_address_space(ares, &r))
+ return acpi_dev_new_resource_entry(&r, c);
+
+ for (i = 0; acpi_dev_resource_interrupt(ares, i, &r); i++) {
+ acpi_status status;
+
+ status = acpi_dev_new_resource_entry(&r, c);
+ if (ACPI_FAILURE(status))
+ return status;
+ }
+
+ return AE_OK;
+}
+
+/**
+ * acpi_dev_get_resources - Get current resources of a device.
+ * @adev: ACPI device node to get the resources for.
+ * @list: Head of the resultant list of resources (must be empty).
+ * @preproc: The caller's preprocessing routine.
+ * @preproc_data: Pointer passed to the caller's preprocessing routine.
+ *
+ * Evaluate the _CRS method for the given device node and process its output by
+ * (1) executing the @preproc() rountine provided by the caller, passing the
+ * resource pointer and @preproc_data to it as arguments, for each ACPI resource
+ * returned and (2) converting all of the returned ACPI resources into struct
+ * resource objects if possible. If the return value of @preproc() in step (1)
+ * is different from 0, step (2) is not applied to the given ACPI resource and
+ * if that value is negative, the whole processing is aborted and that value is
+ * returned as the final error code.
+ *
+ * The resultant struct resource objects are put on the list pointed to by
+ * @list, that must be empty initially, as members of struct resource_list_entry
+ * objects. Callers of this routine should use %acpi_dev_free_resource_list() to
+ * free that list.
+ *
+ * The number of resources in the output list is returned on success, an error
+ * code reflecting the error condition is returned otherwise.
+ */
+int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
+ int (*preproc)(struct acpi_resource *, void *),
+ void *preproc_data)
+{
+ struct res_proc_context c;
+ acpi_handle not_used;
+ acpi_status status;
+
+ if (!adev || !adev->handle || !list_empty(list))
+ return -EINVAL;
+
+ status = acpi_get_handle(adev->handle, METHOD_NAME__CRS, &not_used);
+ if (ACPI_FAILURE(status))
+ return 0;
+
+ c.list = list;
+ c.preproc = preproc;
+ c.preproc_data = preproc_data;
+ c.count = 0;
+ c.error = 0;
+ status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
+ acpi_dev_process_resource, &c);
+ if (ACPI_FAILURE(status)) {
+ acpi_dev_free_resource_list(list);
+ return c.error ? c.error : -EIO;
+ }
+
+ return c.count;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_get_resources);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 1fcb8678665..53502d1bbf2 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -29,6 +29,27 @@ extern struct acpi_device *acpi_root;
static const char *dummy_hid = "device";
+/*
+ * The following ACPI IDs are known to be suitable for representing as
+ * platform devices.
+ */
+static const struct acpi_device_id acpi_platform_device_ids[] = {
+
+ { "PNP0D40" },
+
+ /* Haswell LPSS devices */
+ { "INT33C0", 0 },
+ { "INT33C1", 0 },
+ { "INT33C2", 0 },
+ { "INT33C3", 0 },
+ { "INT33C4", 0 },
+ { "INT33C5", 0 },
+ { "INT33C6", 0 },
+ { "INT33C7", 0 },
+
+ { }
+};
+
static LIST_HEAD(acpi_device_list);
static LIST_HEAD(acpi_bus_id_list);
DEFINE_MUTEX(acpi_device_lock);
@@ -97,6 +118,7 @@ void acpi_bus_hot_remove_device(void *context)
struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context;
struct acpi_device *device;
acpi_handle handle = ej_event->handle;
+ acpi_handle temp;
struct acpi_object_list arg_list;
union acpi_object arg;
acpi_status status = AE_OK;
@@ -117,13 +139,16 @@ void acpi_bus_hot_remove_device(void *context)
goto err_out;
}
+ /* device has been freed */
+ device = NULL;
+
/* power off device */
status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
printk(KERN_WARNING PREFIX
"Power-off device failed\n");
- if (device->flags.lockable) {
+ if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &temp))) {
arg_list.count = 1;
arg_list.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER;
@@ -157,6 +182,7 @@ err_out:
kfree(context);
return;
}
+EXPORT_SYMBOL(acpi_bus_hot_remove_device);
static ssize_t
acpi_eject_store(struct device *d, struct device_attribute *attr,
@@ -216,6 +242,25 @@ acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *bu
}
static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL);
+static ssize_t acpi_device_uid_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+
+ return sprintf(buf, "%s\n", acpi_dev->pnp.unique_id);
+}
+static DEVICE_ATTR(uid, 0444, acpi_device_uid_show, NULL);
+
+static ssize_t acpi_device_adr_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+
+ return sprintf(buf, "0x%08x\n",
+ (unsigned int)(acpi_dev->pnp.bus_address));
+}
+static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL);
+
static ssize_t
acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) {
struct acpi_device *acpi_dev = to_acpi_device(dev);
@@ -259,11 +304,21 @@ static ssize_t description_show(struct device *dev,
}
static DEVICE_ATTR(description, 0444, description_show, NULL);
+static ssize_t
+acpi_device_sun_show(struct device *dev, struct device_attribute *attr,
+ char *buf) {
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+
+ return sprintf(buf, "%lu\n", acpi_dev->pnp.sun);
+}
+static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL);
+
static int acpi_device_setup_files(struct acpi_device *dev)
{
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
acpi_status status;
acpi_handle temp;
+ unsigned long long sun;
int result = 0;
/*
@@ -300,6 +355,21 @@ static int acpi_device_setup_files(struct acpi_device *dev)
goto end;
}
+ if (dev->flags.bus_address)
+ result = device_create_file(&dev->dev, &dev_attr_adr);
+ if (dev->pnp.unique_id)
+ result = device_create_file(&dev->dev, &dev_attr_uid);
+
+ status = acpi_evaluate_integer(dev->handle, "_SUN", NULL, &sun);
+ if (ACPI_SUCCESS(status)) {
+ dev->pnp.sun = (unsigned long)sun;
+ result = device_create_file(&dev->dev, &dev_attr_sun);
+ if (result)
+ goto end;
+ } else {
+ dev->pnp.sun = (unsigned long)-1;
+ }
+
/*
* If device has _EJ0, 'eject' file is created that is used to trigger
* hot-removal function from userland.
@@ -331,6 +401,14 @@ static void acpi_device_remove_files(struct acpi_device *dev)
if (ACPI_SUCCESS(status))
device_remove_file(&dev->dev, &dev_attr_eject);
+ status = acpi_get_handle(dev->handle, "_SUN", &temp);
+ if (ACPI_SUCCESS(status))
+ device_remove_file(&dev->dev, &dev_attr_sun);
+
+ if (dev->pnp.unique_id)
+ device_remove_file(&dev->dev, &dev_attr_uid);
+ if (dev->flags.bus_address)
+ device_remove_file(&dev->dev, &dev_attr_adr);
device_remove_file(&dev->dev, &dev_attr_modalias);
device_remove_file(&dev->dev, &dev_attr_hid);
if (dev->handle)
@@ -340,8 +418,8 @@ static void acpi_device_remove_files(struct acpi_device *dev)
ACPI Bus operations
-------------------------------------------------------------------------- */
-int acpi_match_device_ids(struct acpi_device *device,
- const struct acpi_device_id *ids)
+static const struct acpi_device_id *__acpi_match_device(
+ struct acpi_device *device, const struct acpi_device_id *ids)
{
const struct acpi_device_id *id;
struct acpi_hardware_id *hwid;
@@ -351,14 +429,44 @@ int acpi_match_device_ids(struct acpi_device *device,
* driver for it.
*/
if (!device->status.present)
- return -ENODEV;
+ return NULL;
for (id = ids; id->id[0]; id++)
list_for_each_entry(hwid, &device->pnp.ids, list)
if (!strcmp((char *) id->id, hwid->id))
- return 0;
+ return id;
- return -ENOENT;
+ return NULL;
+}
+
+/**
+ * acpi_match_device - Match a struct device against a given list of ACPI IDs
+ * @ids: Array of struct acpi_device_id object to match against.
+ * @dev: The device structure to match.
+ *
+ * Check if @dev has a valid ACPI handle and if there is a struct acpi_device
+ * object for that handle and use that object to match against a given list of
+ * device IDs.
+ *
+ * Return a pointer to the first matching ID on success or %NULL on failure.
+ */
+const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
+ const struct device *dev)
+{
+ struct acpi_device *adev;
+
+ if (!ids || !ACPI_HANDLE(dev)
+ || ACPI_FAILURE(acpi_bus_get_device(ACPI_HANDLE(dev), &adev)))
+ return NULL;
+
+ return __acpi_match_device(adev, ids);
+}
+EXPORT_SYMBOL_GPL(acpi_match_device);
+
+int acpi_match_device_ids(struct acpi_device *device,
+ const struct acpi_device_id *ids)
+{
+ return __acpi_match_device(device, ids) ? 0 : -ENOENT;
}
EXPORT_SYMBOL(acpi_match_device_ids);
@@ -377,6 +485,7 @@ static void acpi_device_release(struct device *dev)
struct acpi_device *acpi_dev = to_acpi_device(dev);
acpi_free_ids(acpi_dev);
+ kfree(acpi_dev->pnp.unique_id);
kfree(acpi_dev);
}
@@ -859,8 +968,8 @@ acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
{
struct acpi_device_id button_device_ids[] = {
- {"PNP0C0D", 0},
{"PNP0C0C", 0},
+ {"PNP0C0D", 0},
{"PNP0C0E", 0},
{"", 0},
};
@@ -872,6 +981,11 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
/* Power button, Lid switch always enable wakeup */
if (!acpi_match_device_ids(device, button_device_ids)) {
device->wakeup.flags.run_wake = 1;
+ if (!acpi_match_device_ids(device, &button_device_ids[1])) {
+ /* Do not use Lid/sleep button for S5 wakeup */
+ if (device->wakeup.sleep_state == ACPI_STATE_S5)
+ device->wakeup.sleep_state = ACPI_STATE_S4;
+ }
device_set_wakeup_capable(&device->dev, true);
return;
}
@@ -965,8 +1079,10 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
* D3hot is only valid if _PR3 present.
*/
if (ps->resources.count ||
- (ps->flags.explicit_set && i < ACPI_STATE_D3_HOT))
+ (ps->flags.explicit_set && i < ACPI_STATE_D3_HOT)) {
ps->flags.valid = 1;
+ ps->flags.os_accessible = 1;
+ }
ps->power = -1; /* Unknown - driver assigned */
ps->latency = -1; /* Unknown - driver assigned */
@@ -982,6 +1098,11 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set)
device->power.states[ACPI_STATE_D3_COLD].flags.explicit_set = 1;
+ /* Presence of _PS3 or _PRx means we can put the device into D3 cold */
+ if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set ||
+ device->power.flags.power_resources)
+ device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1;
+
acpi_bus_init_power(device);
return 0;
@@ -1013,11 +1134,6 @@ static int acpi_bus_get_flags(struct acpi_device *device)
device->flags.ejectable = 1;
}
- /* Presence of _LCK indicates 'lockable' */
- status = acpi_get_handle(device->handle, "_LCK", &temp);
- if (ACPI_SUCCESS(status))
- device->flags.lockable = 1;
-
/* Power resources cannot be power manageable. */
if (device->device_type == ACPI_BUS_TYPE_POWER)
return 0;
@@ -1185,7 +1301,7 @@ static void acpi_device_set_id(struct acpi_device *device)
{
acpi_status status;
struct acpi_device_info *info;
- struct acpica_device_id_list *cid_list;
+ struct acpi_pnp_device_id_list *cid_list;
int i;
switch (device->device_type) {
@@ -1212,6 +1328,9 @@ static void acpi_device_set_id(struct acpi_device *device)
device->pnp.bus_address = info->address;
device->flags.bus_address = 1;
}
+ if (info->valid & ACPI_VALID_UID)
+ device->pnp.unique_id = kstrdup(info->unique_id.string,
+ GFP_KERNEL);
kfree(info);
@@ -1483,8 +1602,13 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
*/
device = NULL;
acpi_bus_get_device(handle, &device);
- if (ops->acpi_op_add && !device)
+ if (ops->acpi_op_add && !device) {
acpi_add_single_object(&device, handle, type, sta, ops);
+ /* Is the device a known good platform device? */
+ if (device
+ && !acpi_match_device_ids(device, acpi_platform_device_ids))
+ acpi_create_platform_device(device);
+ }
if (!device)
return AE_CTRL_DEPTH;
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index fdcdbb65291..2fcc67d34b1 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -18,7 +18,6 @@
#include <linux/reboot.h>
#include <linux/acpi.h>
#include <linux/module.h>
-#include <linux/pm_runtime.h>
#include <asm/io.h>
@@ -81,6 +80,12 @@ static int acpi_sleep_prepare(u32 acpi_state)
#ifdef CONFIG_ACPI_SLEEP
static u32 acpi_target_sleep_state = ACPI_STATE_S0;
+
+u32 acpi_target_system_state(void)
+{
+ return acpi_target_sleep_state;
+}
+
static bool pwr_btn_event_pending;
/*
@@ -98,6 +103,21 @@ void __init acpi_nvs_nosave(void)
}
/*
+ * The ACPI specification wants us to save NVS memory regions during hibernation
+ * but says nothing about saving NVS during S3. Not all versions of Windows
+ * save NVS on S3 suspend either, and it is clear that not all systems need
+ * NVS to be saved at S3 time. To improve suspend/resume time, allow the
+ * user to disable saving NVS on S3 if their system does not require it, but
+ * continue to save/restore NVS for S4 as specified.
+ */
+static bool nvs_nosave_s3;
+
+void __init acpi_nvs_nosave_s3(void)
+{
+ nvs_nosave_s3 = true;
+}
+
+/*
* ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the
* user to request that behavior by using the 'acpi_old_suspend_ordering'
* kernel command line option that causes the following variable to be set.
@@ -109,6 +129,180 @@ void __init acpi_old_suspend_ordering(void)
old_suspend_ordering = true;
}
+static int __init init_old_suspend_ordering(const struct dmi_system_id *d)
+{
+ acpi_old_suspend_ordering();
+ return 0;
+}
+
+static int __init init_nvs_nosave(const struct dmi_system_id *d)
+{
+ acpi_nvs_nosave();
+ return 0;
+}
+
+static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
+ {
+ .callback = init_old_suspend_ordering,
+ .ident = "Abit KN9 (nForce4 variant)",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"),
+ DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
+ },
+ },
+ {
+ .callback = init_old_suspend_ordering,
+ .ident = "HP xw4600 Workstation",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),
+ },
+ },
+ {
+ .callback = init_old_suspend_ordering,
+ .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "M2N8L"),
+ },
+ },
+ {
+ .callback = init_old_suspend_ordering,
+ .ident = "Panasonic CF51-2L",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR,
+ "Matsushita Electric Industrial Co.,Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Sony Vaio VGN-FW21E",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21E"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Sony Vaio VPCEB17FX",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB17FX"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Sony Vaio VGN-SR11M",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Everex StepNote Series",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Sony Vaio VPCEB1Z1E",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Sony Vaio VGN-NW130D",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Sony Vaio VPCCW29FX",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Averatec AV1020-ED2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"),
+ },
+ },
+ {
+ .callback = init_old_suspend_ordering,
+ .ident = "Asus A8N-SLI DELUXE",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI DELUXE"),
+ },
+ },
+ {
+ .callback = init_old_suspend_ordering,
+ .ident = "Asus A8N-SLI Premium",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI Premium"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Sony Vaio VGN-SR26GN_P",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR26GN_P"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Sony Vaio VPCEB1S1E",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1S1E"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Sony Vaio VGN-FW520F",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW520F"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Asus K54C",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "K54C"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Asus K54HR",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"),
+ },
+ },
+ {},
+};
+
+static void acpi_sleep_dmi_check(void)
+{
+ dmi_check_system(acpisleep_dmi_table);
+}
+
/**
* acpi_pm_freeze - Disable the GPEs and suspend EC transactions.
*/
@@ -224,6 +418,7 @@ static void acpi_pm_end(void)
}
#else /* !CONFIG_ACPI_SLEEP */
#define acpi_target_sleep_state ACPI_STATE_S0
+static inline void acpi_sleep_dmi_check(void) {}
#endif /* CONFIG_ACPI_SLEEP */
#ifdef CONFIG_SUSPEND
@@ -243,7 +438,7 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
u32 acpi_state = acpi_suspend_states[pm_state];
int error = 0;
- error = nvs_nosave ? 0 : suspend_nvs_alloc();
+ error = (nvs_nosave || nvs_nosave_s3) ? 0 : suspend_nvs_alloc();
if (error)
return error;
@@ -382,167 +577,6 @@ static const struct platform_suspend_ops acpi_suspend_ops_old = {
.end = acpi_pm_end,
.recover = acpi_pm_finish,
};
-
-static int __init init_old_suspend_ordering(const struct dmi_system_id *d)
-{
- old_suspend_ordering = true;
- return 0;
-}
-
-static int __init init_nvs_nosave(const struct dmi_system_id *d)
-{
- acpi_nvs_nosave();
- return 0;
-}
-
-static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
- {
- .callback = init_old_suspend_ordering,
- .ident = "Abit KN9 (nForce4 variant)",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"),
- DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
- },
- },
- {
- .callback = init_old_suspend_ordering,
- .ident = "HP xw4600 Workstation",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
- DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),
- },
- },
- {
- .callback = init_old_suspend_ordering,
- .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."),
- DMI_MATCH(DMI_BOARD_NAME, "M2N8L"),
- },
- },
- {
- .callback = init_old_suspend_ordering,
- .ident = "Panasonic CF51-2L",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR,
- "Matsushita Electric Industrial Co.,Ltd."),
- DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
- },
- },
- {
- .callback = init_nvs_nosave,
- .ident = "Sony Vaio VGN-FW21E",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21E"),
- },
- },
- {
- .callback = init_nvs_nosave,
- .ident = "Sony Vaio VPCEB17FX",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB17FX"),
- },
- },
- {
- .callback = init_nvs_nosave,
- .ident = "Sony Vaio VGN-SR11M",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"),
- },
- },
- {
- .callback = init_nvs_nosave,
- .ident = "Everex StepNote Series",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"),
- },
- },
- {
- .callback = init_nvs_nosave,
- .ident = "Sony Vaio VPCEB1Z1E",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
- },
- },
- {
- .callback = init_nvs_nosave,
- .ident = "Sony Vaio VGN-NW130D",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
- },
- },
- {
- .callback = init_nvs_nosave,
- .ident = "Sony Vaio VPCCW29FX",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"),
- },
- },
- {
- .callback = init_nvs_nosave,
- .ident = "Averatec AV1020-ED2",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),
- DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"),
- },
- },
- {
- .callback = init_old_suspend_ordering,
- .ident = "Asus A8N-SLI DELUXE",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
- DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI DELUXE"),
- },
- },
- {
- .callback = init_old_suspend_ordering,
- .ident = "Asus A8N-SLI Premium",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
- DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI Premium"),
- },
- },
- {
- .callback = init_nvs_nosave,
- .ident = "Sony Vaio VGN-SR26GN_P",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR26GN_P"),
- },
- },
- {
- .callback = init_nvs_nosave,
- .ident = "Sony Vaio VGN-FW520F",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW520F"),
- },
- },
- {
- .callback = init_nvs_nosave,
- .ident = "Asus K54C",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "K54C"),
- },
- },
- {
- .callback = init_nvs_nosave,
- .ident = "Asus K54HR",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"),
- },
- },
- {},
-};
#endif /* CONFIG_SUSPEND */
#ifdef CONFIG_HIBERNATION
@@ -681,177 +715,6 @@ int acpi_suspend(u32 acpi_state)
return -EINVAL;
}
-#ifdef CONFIG_PM
-/**
- * acpi_pm_device_sleep_state - return preferred power state of ACPI device
- * in the system sleep state given by %acpi_target_sleep_state
- * @dev: device to examine; its driver model wakeup flags control
- * whether it should be able to wake up the system
- * @d_min_p: used to store the upper limit of allowed states range
- * @d_max_in: specify the lowest allowed states
- * Return value: preferred power state of the device on success, -ENODEV
- * (ie. if there's no 'struct acpi_device' for @dev) or -EINVAL on failure
- *
- * Find the lowest power (highest number) ACPI device power state that
- * device @dev can be in while the system is in the sleep state represented
- * by %acpi_target_sleep_state. If @wake is nonzero, the device should be
- * able to wake up the system from this sleep state. If @d_min_p is set,
- * the highest power (lowest number) device power state of @dev allowed
- * in this system sleep state is stored at the location pointed to by it.
- *
- * The caller must ensure that @dev is valid before using this function.
- * The caller is also responsible for figuring out if the device is
- * supposed to be able to wake up the system and passing this information
- * via @wake.
- */
-
-int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in)
-{
- acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
- struct acpi_device *adev;
- char acpi_method[] = "_SxD";
- unsigned long long d_min, d_max;
-
- if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3)
- return -EINVAL;
- if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
- printk(KERN_DEBUG "ACPI handle has no context!\n");
- return -ENODEV;
- }
-
- acpi_method[2] = '0' + acpi_target_sleep_state;
- /*
- * If the sleep state is S0, the lowest limit from ACPI is D3,
- * but if the device has _S0W, we will use the value from _S0W
- * as the lowest limit from ACPI. Finally, we will constrain
- * the lowest limit with the specified one.
- */
- d_min = ACPI_STATE_D0;
- d_max = ACPI_STATE_D3;
-
- /*
- * If present, _SxD methods return the minimum D-state (highest power
- * state) we can use for the corresponding S-states. Otherwise, the
- * minimum D-state is D0 (ACPI 3.x).
- *
- * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer
- * provided -- that's our fault recovery, we ignore retval.
- */
- if (acpi_target_sleep_state > ACPI_STATE_S0)
- acpi_evaluate_integer(handle, acpi_method, NULL, &d_min);
-
- /*
- * If _PRW says we can wake up the system from the target sleep state,
- * the D-state returned by _SxD is sufficient for that (we assume a
- * wakeup-aware driver if wake is set). Still, if _SxW exists
- * (ACPI 3.x), it should return the maximum (lowest power) D-state that
- * can wake the system. _S0W may be valid, too.
- */
- if (acpi_target_sleep_state == ACPI_STATE_S0 ||
- (device_may_wakeup(dev) && adev->wakeup.flags.valid &&
- adev->wakeup.sleep_state >= acpi_target_sleep_state)) {
- acpi_status status;
-
- acpi_method[3] = 'W';
- status = acpi_evaluate_integer(handle, acpi_method, NULL,
- &d_max);
- if (ACPI_FAILURE(status)) {
- if (acpi_target_sleep_state != ACPI_STATE_S0 ||
- status != AE_NOT_FOUND)
- d_max = d_min;
- } else if (d_max < d_min) {
- /* Warn the user of the broken DSDT */
- printk(KERN_WARNING "ACPI: Wrong value from %s\n",
- acpi_method);
- /* Sanitize it */
- d_min = d_max;
- }
- }
-
- if (d_max_in < d_min)
- return -EINVAL;
- if (d_min_p)
- *d_min_p = d_min;
- /* constrain d_max with specified lowest limit (max number) */
- if (d_max > d_max_in) {
- for (d_max = d_max_in; d_max > d_min; d_max--) {
- if (adev->power.states[d_max].flags.valid)
- break;
- }
- }
- return d_max;
-}
-EXPORT_SYMBOL(acpi_pm_device_sleep_state);
-#endif /* CONFIG_PM */
-
-#ifdef CONFIG_PM_SLEEP
-/**
- * acpi_pm_device_run_wake - Enable/disable wake-up for given device.
- * @phys_dev: Device to enable/disable the platform to wake-up the system for.
- * @enable: Whether enable or disable the wake-up functionality.
- *
- * Find the ACPI device object corresponding to @pci_dev and try to
- * enable/disable the GPE associated with it.
- */
-int acpi_pm_device_run_wake(struct device *phys_dev, bool enable)
-{
- struct acpi_device *dev;
- acpi_handle handle;
-
- if (!device_run_wake(phys_dev))
- return -EINVAL;
-
- handle = DEVICE_ACPI_HANDLE(phys_dev);
- if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) {
- dev_dbg(phys_dev, "ACPI handle has no context in %s!\n",
- __func__);
- return -ENODEV;
- }
-
- if (enable) {
- acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0);
- acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
- } else {
- acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
- acpi_disable_wakeup_device_power(dev);
- }
-
- return 0;
-}
-EXPORT_SYMBOL(acpi_pm_device_run_wake);
-
-/**
- * acpi_pm_device_sleep_wake - enable or disable the system wake-up
- * capability of given device
- * @dev: device to handle
- * @enable: 'true' - enable, 'false' - disable the wake-up capability
- */
-int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
-{
- acpi_handle handle;
- struct acpi_device *adev;
- int error;
-
- if (!device_can_wakeup(dev))
- return -EINVAL;
-
- handle = DEVICE_ACPI_HANDLE(dev);
- if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
- dev_dbg(dev, "ACPI handle has no context in %s!\n", __func__);
- return -ENODEV;
- }
-
- error = enable ?
- acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) :
- acpi_disable_wakeup_device_power(adev);
- if (!error)
- dev_info(dev, "wake-up capability %s by ACPI\n",
- enable ? "enabled" : "disabled");
-
- return error;
-}
-#endif /* CONFIG_PM_SLEEP */
-
static void acpi_power_off_prepare(void)
{
/* Prepare to power off the system */
@@ -873,13 +736,13 @@ int __init acpi_sleep_init(void)
u8 type_a, type_b;
#ifdef CONFIG_SUSPEND
int i = 0;
-
- dmi_check_system(acpisleep_dmi_table);
#endif
if (acpi_disabled)
return 0;
+ acpi_sleep_dmi_check();
+
sleep_states[ACPI_STATE_S0] = 1;
printk(KERN_INFO PREFIX "(supports S0");
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 7c3f98ba4af..ea61ca9129c 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -476,7 +476,7 @@ static void fixed_event_count(u32 event_number)
return;
}
-static void acpi_gbl_event_handler(u32 event_type, acpi_handle device,
+static void acpi_global_event_handler(u32 event_type, acpi_handle device,
u32 event_number, void *context)
{
if (event_type == ACPI_EVENT_TYPE_GPE)
@@ -638,7 +638,7 @@ void acpi_irq_stats_init(void)
if (all_counters == NULL)
goto fail;
- status = acpi_install_global_event_handler(acpi_gbl_event_handler, NULL);
+ status = acpi_install_global_event_handler(acpi_global_event_handler, NULL);
if (ACPI_FAILURE(status))
goto fail;
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 804204d4199..6e8cc16b54c 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -984,6 +984,38 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event)
}
}
+/*
+ * On some platforms, the AML code has dependency about
+ * the evaluating order of _TMP and _CRT/_HOT/_PSV/_ACx.
+ * 1. On HP Pavilion G4-1016tx, _TMP must be invoked after
+ * /_CRT/_HOT/_PSV/_ACx, or else system will be power off.
+ * 2. On HP Compaq 6715b/6715s, the return value of _PSV is 0
+ * if _TMP has never been evaluated.
+ *
+ * As this dependency is totally transparent to OS, evaluate
+ * all of them once, in the order of _CRT/_HOT/_PSV/_ACx,
+ * _TMP, before they are actually used.
+ */
+static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz)
+{
+ acpi_handle handle = tz->device->handle;
+ unsigned long long value;
+ int i;
+
+ acpi_evaluate_integer(handle, "_CRT", NULL, &value);
+ acpi_evaluate_integer(handle, "_HOT", NULL, &value);
+ acpi_evaluate_integer(handle, "_PSV", NULL, &value);
+ for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
+ char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
+ acpi_status status;
+
+ status = acpi_evaluate_integer(handle, name, NULL, &value);
+ if (status == AE_NOT_FOUND)
+ break;
+ }
+ acpi_evaluate_integer(handle, "_TMP", NULL, &value);
+}
+
static int acpi_thermal_get_info(struct acpi_thermal *tz)
{
int result = 0;
@@ -992,6 +1024,8 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz)
if (!tz)
return -EINVAL;
+ acpi_thermal_aml_dependency_fix(tz);
+
/* Get trip points [_CRT, _PSV, etc.] (required) */
result = acpi_thermal_get_trip_points(tz);
if (result)
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 462f7e30036..74437130431 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -28,6 +28,8 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
+#include <linux/hardirq.h>
+#include <linux/acpi.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
@@ -457,3 +459,39 @@ acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event,
#endif
}
EXPORT_SYMBOL(acpi_evaluate_hotplug_ost);
+
+/**
+ * acpi_handle_printk: Print message with ACPI prefix and object path
+ *
+ * This function is called through acpi_handle_<level> macros and prints
+ * a message with ACPI prefix and object path. This function acquires
+ * the global namespace mutex to obtain an object path. In interrupt
+ * context, it shows the object path as <n/a>.
+ */
+void
+acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...)
+{
+ struct va_format vaf;
+ va_list args;
+ struct acpi_buffer buffer = {
+ .length = ACPI_ALLOCATE_BUFFER,
+ .pointer = NULL
+ };
+ const char *path;
+
+ va_start(args, fmt);
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ if (in_interrupt() ||
+ acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer) != AE_OK)
+ path = "<n/a>";
+ else
+ path = buffer.pointer;
+
+ printk("%sACPI: %s: %pV", level, path, &vaf);
+
+ va_end(args);
+ kfree(buffer.pointer);
+}
+EXPORT_SYMBOL(acpi_handle_printk);
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 0230cb6cbb3..ac9a69cd45f 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -389,6 +389,12 @@ static int __init video_set_bqc_offset(const struct dmi_system_id *d)
return 0;
}
+static int video_ignore_initial_backlight(const struct dmi_system_id *d)
+{
+ use_bios_initial_backlight = 0;
+ return 0;
+}
+
static struct dmi_system_id video_dmi_table[] __initdata = {
/*
* Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121
@@ -433,6 +439,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"),
},
},
+ {
+ .callback = video_ignore_initial_backlight,
+ .ident = "HP Folio 13-2000",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13 - 2000 Notebook PC"),
+ },
+ },
{}
};
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index b728880ef10..4ac2593234e 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -156,6 +156,14 @@ static struct dmi_system_id video_detect_dmi_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "X360"),
},
},
+ {
+ .callback = video_detect_force_vendor,
+ .ident = "Asus UL30VT",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"),
+ },
+ },
{ },
};
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index b1ae48054dc..b7078afddb7 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -238,7 +238,7 @@ static int __devexit ahci_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int ahci_suspend(struct device *dev)
{
struct ahci_platform_data *pdata = dev_get_platdata(dev);
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index fd9ecf74e63..5b0ba3f20ed 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -1105,10 +1105,15 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev,
struct acpi_device *acpi_dev;
struct acpi_device_power_state *states;
- if (ap->flags & ATA_FLAG_ACPI_SATA)
- ata_dev = &ap->link.device[sdev->channel];
- else
+ if (ap->flags & ATA_FLAG_ACPI_SATA) {
+ if (!sata_pmp_attached(ap))
+ ata_dev = &ap->link.device[sdev->id];
+ else
+ ata_dev = &ap->pmp_link[sdev->channel].device[sdev->id];
+ }
+ else {
ata_dev = &ap->link.device[sdev->id];
+ }
*handle = ata_dev_acpi_handle(ata_dev);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 3cc7096cfda..f46fbd3bd3f 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2942,6 +2942,10 @@ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode)
if (xfer_mode == t->mode)
return t;
+
+ WARN_ONCE(true, "%s: unable to find timing for xfer_mode 0x%x\n",
+ __func__, xfer_mode);
+
return NULL;
}
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index e3bda074fa1..a6df6a351d6 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1052,6 +1052,8 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
{
sdev->use_10_for_rw = 1;
sdev->use_10_for_ms = 1;
+ sdev->no_report_opcodes = 1;
+ sdev->no_write_same = 1;
/* Schedule policy is determined by ->qc_defer() callback and
* it needs to see every deferred qc. Set dev_blocked to 1 to
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c
index 26201ebef3c..371fd2c698b 100644
--- a/drivers/ata/pata_arasan_cf.c
+++ b/drivers/ata/pata_arasan_cf.c
@@ -317,6 +317,12 @@ static int cf_init(struct arasan_cf_dev *acdev)
return ret;
}
+ ret = clk_set_rate(acdev->clk, 166000000);
+ if (ret) {
+ dev_warn(acdev->host->dev, "clock set rate failed");
+ return ret;
+ }
+
spin_lock_irqsave(&acdev->host->lock, flags);
/* configure CF interface clock */
writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk :
@@ -908,7 +914,7 @@ static int __devexit arasan_cf_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int arasan_cf_suspend(struct device *dev)
{
struct ata_host *host = dev_get_drvdata(dev);
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c
index 0d7c4c2cd26..400bf1c3e98 100644
--- a/drivers/ata/sata_highbank.c
+++ b/drivers/ata/sata_highbank.c
@@ -260,7 +260,7 @@ static const struct of_device_id ahci_of_match[] = {
};
MODULE_DEVICE_TABLE(of, ahci_of_match);
-static int __init ahci_highbank_probe(struct platform_device *pdev)
+static int __devinit ahci_highbank_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ahci_host_priv *hpriv;
@@ -378,7 +378,7 @@ static int __devexit ahci_highbank_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int ahci_highbank_suspend(struct device *dev)
{
struct ata_host *host = dev_get_drvdata(dev);
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index 44a4256533e..08608de87e4 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -142,6 +142,39 @@ static int k2_sata_scr_write(struct ata_link *link,
return 0;
}
+static int k2_sata_softreset(struct ata_link *link,
+ unsigned int *class, unsigned long deadline)
+{
+ u8 dmactl;
+ void __iomem *mmio = link->ap->ioaddr.bmdma_addr;
+
+ dmactl = readb(mmio + ATA_DMA_CMD);
+
+ /* Clear the start bit */
+ if (dmactl & ATA_DMA_START) {
+ dmactl &= ~ATA_DMA_START;
+ writeb(dmactl, mmio + ATA_DMA_CMD);
+ }
+
+ return ata_sff_softreset(link, class, deadline);
+}
+
+static int k2_sata_hardreset(struct ata_link *link,
+ unsigned int *class, unsigned long deadline)
+{
+ u8 dmactl;
+ void __iomem *mmio = link->ap->ioaddr.bmdma_addr;
+
+ dmactl = readb(mmio + ATA_DMA_CMD);
+
+ /* Clear the start bit */
+ if (dmactl & ATA_DMA_START) {
+ dmactl &= ~ATA_DMA_START;
+ writeb(dmactl, mmio + ATA_DMA_CMD);
+ }
+
+ return sata_sff_hardreset(link, class, deadline);
+}
static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
{
@@ -346,6 +379,8 @@ static struct scsi_host_template k2_sata_sht = {
static struct ata_port_operations k2_sata_ops = {
.inherits = &ata_bmdma_port_ops,
+ .softreset = k2_sata_softreset,
+ .hardreset = k2_sata_hardreset,
.sff_tf_load = k2_sata_tf_load,
.sff_tf_read = k2_sata_tf_read,
.sff_check_status = k2_stat_check_status,
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index 89b30f32ba6..ff7bb8a42ed 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -1961,6 +1961,7 @@ static int __devinit ucode_init (loader_block * lb, amb_dev * dev) {
res = loader_verify(lb, dev, rec);
if (res)
break;
+ rec = ihex_next_binrec(rec);
}
release_firmware(fw);
if (!res)
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index b34b5cda5ae..c8b453939da 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -57,7 +57,7 @@ config DEVTMPFS_MOUNT
on the rootfs is completely empty.
config STANDALONE
- bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL
+ bool "Select only drivers that don't need compile-time external firmware"
default y
help
Select this option if you don't have magic firmware for drivers that
@@ -185,7 +185,6 @@ config DMA_SHARED_BUFFER
bool
default n
select ANON_INODES
- depends on EXPERIMENTAL
help
This option enables the framework for buffer-sharing between
multiple drivers. A buffer is associated with a file using driver
@@ -193,8 +192,8 @@ config DMA_SHARED_BUFFER
driver.
config CMA
- bool "Contiguous Memory Allocator (EXPERIMENTAL)"
- depends on HAVE_DMA_CONTIGUOUS && HAVE_MEMBLOCK && EXPERIMENTAL
+ bool "Contiguous Memory Allocator"
+ depends on HAVE_DMA_CONTIGUOUS && HAVE_MEMBLOCK
select MIGRATION
select MEMORY_ISOLATION
help
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
index 8fc200b2e2c..d78b204e65c 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -158,7 +158,7 @@ attribute_container_add_device(struct device *dev,
ic = kzalloc(sizeof(*ic), GFP_KERNEL);
if (!ic) {
- dev_printk(KERN_ERR, dev, "failed to allocate class container\n");
+ dev_err(dev, "failed to allocate class container\n");
continue;
}
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 181ed2660b3..24eb0786834 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -164,8 +164,6 @@ static const struct kset_uevent_ops bus_uevent_ops = {
static struct kset *bus_kset;
-
-#ifdef CONFIG_HOTPLUG
/* Manually detach a device from its associated driver. */
static ssize_t driver_unbind(struct device_driver *drv,
const char *buf, size_t count)
@@ -252,7 +250,6 @@ static ssize_t store_drivers_probe(struct bus_type *bus,
return -EINVAL;
return count;
}
-#endif
static struct device *next_device(struct klist_iter *i)
{
@@ -618,11 +615,6 @@ static void driver_remove_attrs(struct bus_type *bus,
}
}
-#ifdef CONFIG_HOTPLUG
-/*
- * Thanks to drivers making their tables __devinit, we can't allow manual
- * bind and unbind from userspace unless CONFIG_HOTPLUG is enabled.
- */
static int __must_check add_bind_files(struct device_driver *drv)
{
int ret;
@@ -666,12 +658,6 @@ static void remove_probe_files(struct bus_type *bus)
bus_remove_file(bus, &bus_attr_drivers_autoprobe);
bus_remove_file(bus, &bus_attr_drivers_probe);
}
-#else
-static inline int add_bind_files(struct device_driver *drv) { return 0; }
-static inline void remove_bind_files(struct device_driver *drv) {}
-static inline int add_probe_files(struct bus_type *bus) { return 0; }
-static inline void remove_probe_files(struct bus_type *bus) {}
-#endif
static ssize_t driver_uevent_store(struct device_driver *drv,
const char *buf, size_t count)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index abea76c36a4..417913974df 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1180,7 +1180,6 @@ void device_del(struct device *dev)
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_DEL_DEVICE, dev);
- device_pm_remove(dev);
dpm_sysfs_remove(dev);
if (parent)
klist_del(&dev->p->knode_parent);
@@ -1205,6 +1204,7 @@ void device_del(struct device *dev)
device_remove_file(dev, &uevent_attr);
device_remove_attrs(dev);
bus_remove_device(dev);
+ device_pm_remove(dev);
driver_deferred_probe_del(dev);
/* Notify the platform of the removal, in case they
@@ -1399,7 +1399,7 @@ struct root_device {
struct module *owner;
};
-inline struct root_device *to_root_device(struct device *d)
+static inline struct root_device *to_root_device(struct device *d)
{
return container_of(d, struct root_device, dev);
}
@@ -1840,10 +1840,12 @@ void device_shutdown(void)
pm_runtime_barrier(dev);
if (dev->bus && dev->bus->shutdown) {
- dev_dbg(dev, "shutdown\n");
+ if (initcall_debug)
+ dev_info(dev, "shutdown\n");
dev->bus->shutdown(dev);
} else if (dev->driver && dev->driver->shutdown) {
- dev_dbg(dev, "shutdown\n");
+ if (initcall_debug)
+ dev_info(dev, "shutdown\n");
dev->driver->shutdown(dev);
}
diff --git a/drivers/base/devres.c b/drivers/base/devres.c
index 8731979d668..66839066476 100644
--- a/drivers/base/devres.c
+++ b/drivers/base/devres.c
@@ -50,8 +50,8 @@ static void devres_log(struct device *dev, struct devres_node *node,
const char *op)
{
if (unlikely(log_devres))
- dev_printk(KERN_ERR, dev, "DEVRES %3s %p %s (%lu bytes)\n",
- op, node, node->name, (unsigned long)node->size);
+ dev_err(dev, "DEVRES %3s %p %s (%lu bytes)\n",
+ op, node, node->name, (unsigned long)node->size);
}
#else /* CONFIG_DEBUG_DEVRES */
#define set_node_dbginfo(node, n, s) do {} while (0)
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 612afcc5a93..0ca54421ce9 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -57,8 +57,8 @@ struct cma *dma_contiguous_default_area;
* Users, who want to set the size of global CMA area for their system
* should use cma= kernel parameter.
*/
-static const unsigned long size_bytes = CMA_SIZE_MBYTES * SZ_1M;
-static long size_cmdline = -1;
+static const phys_addr_t size_bytes = CMA_SIZE_MBYTES * SZ_1M;
+static phys_addr_t size_cmdline = -1;
static int __init early_cma(char *p)
{
@@ -70,7 +70,7 @@ early_param("cma", early_cma);
#ifdef CONFIG_CMA_SIZE_PERCENTAGE
-static unsigned long __init __maybe_unused cma_early_percent_memory(void)
+static phys_addr_t __init __maybe_unused cma_early_percent_memory(void)
{
struct memblock_region *reg;
unsigned long total_pages = 0;
@@ -88,7 +88,7 @@ static unsigned long __init __maybe_unused cma_early_percent_memory(void)
#else
-static inline __maybe_unused unsigned long cma_early_percent_memory(void)
+static inline __maybe_unused phys_addr_t cma_early_percent_memory(void)
{
return 0;
}
@@ -106,7 +106,7 @@ static inline __maybe_unused unsigned long cma_early_percent_memory(void)
*/
void __init dma_contiguous_reserve(phys_addr_t limit)
{
- unsigned long selected_size = 0;
+ phys_addr_t selected_size = 0;
pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit);
@@ -126,7 +126,7 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
if (selected_size) {
pr_debug("%s: reserving %ld MiB for global area\n", __func__,
- selected_size / SZ_1M);
+ (unsigned long)selected_size / SZ_1M);
dma_declare_contiguous(NULL, selected_size, 0, limit);
}
@@ -227,11 +227,11 @@ core_initcall(cma_init_reserved_areas);
* called by board specific code when early allocator (memblock or bootmem)
* is still activate.
*/
-int __init dma_declare_contiguous(struct device *dev, unsigned long size,
+int __init dma_declare_contiguous(struct device *dev, phys_addr_t size,
phys_addr_t base, phys_addr_t limit)
{
struct cma_reserved *r = &cma_reserved[cma_reserved_count];
- unsigned long alignment;
+ phys_addr_t alignment;
pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__,
(unsigned long)size, (unsigned long)base,
@@ -268,10 +268,6 @@ int __init dma_declare_contiguous(struct device *dev, unsigned long size,
if (!addr) {
base = -ENOMEM;
goto err;
- } else if (addr + size > ~(unsigned long)0) {
- memblock_free(addr, size);
- base = -EINVAL;
- goto err;
} else {
base = addr;
}
@@ -285,14 +281,14 @@ int __init dma_declare_contiguous(struct device *dev, unsigned long size,
r->size = size;
r->dev = dev;
cma_reserved_count++;
- pr_info("CMA: reserved %ld MiB at %08lx\n", size / SZ_1M,
+ pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
(unsigned long)base);
/* Architecture specific contiguous memory fixup. */
dma_contiguous_early_fixup(base, size);
return 0;
err:
- pr_err("CMA: failed to reserve %ld MiB\n", size / SZ_1M);
+ pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
return base;
}
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 8945f4e489e..d8146030918 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -143,7 +143,7 @@ struct fw_cache_entry {
};
struct firmware_priv {
- struct timer_list timeout;
+ struct delayed_work timeout_work;
bool nowait;
struct device dev;
struct firmware_buf *buf;
@@ -246,7 +246,6 @@ static void __fw_free_buf(struct kref *ref)
__func__, buf->fw_id, buf, buf->data,
(unsigned int)buf->size);
- spin_lock(&fwc->lock);
list_del(&buf->list);
spin_unlock(&fwc->lock);
@@ -263,19 +262,32 @@ static void __fw_free_buf(struct kref *ref)
static void fw_free_buf(struct firmware_buf *buf)
{
- kref_put(&buf->ref, __fw_free_buf);
+ struct firmware_cache *fwc = buf->fwc;
+ spin_lock(&fwc->lock);
+ if (!kref_put(&buf->ref, __fw_free_buf))
+ spin_unlock(&fwc->lock);
}
/* direct firmware loading support */
-static const char *fw_path[] = {
+static char fw_path_para[256];
+static const char * const fw_path[] = {
+ fw_path_para,
"/lib/firmware/updates/" UTS_RELEASE,
"/lib/firmware/updates",
"/lib/firmware/" UTS_RELEASE,
"/lib/firmware"
};
+/*
+ * Typical usage is that passing 'firmware_class.path=$CUSTOMIZED_PATH'
+ * from kernel command line because firmware_class is generally built in
+ * kernel instead of module.
+ */
+module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644);
+MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path");
+
/* Don't inline this: 'struct kstat' is biggish */
-static noinline long fw_file_size(struct file *file)
+static noinline_for_stack long fw_file_size(struct file *file)
{
struct kstat st;
if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st))
@@ -315,6 +327,11 @@ static bool fw_get_filesystem_firmware(struct firmware_buf *buf)
for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
struct file *file;
+
+ /* skip the unset customized path */
+ if (!fw_path[i][0])
+ continue;
+
snprintf(path, PATH_MAX, "%s/%s", fw_path[i], buf->fw_id);
file = filp_open(path, O_RDONLY, 0);
@@ -667,11 +684,18 @@ static struct bin_attribute firmware_attr_data = {
.write = firmware_data_write,
};
-static void firmware_class_timeout(u_long data)
+static void firmware_class_timeout_work(struct work_struct *work)
{
- struct firmware_priv *fw_priv = (struct firmware_priv *) data;
+ struct firmware_priv *fw_priv = container_of(work,
+ struct firmware_priv, timeout_work.work);
+ mutex_lock(&fw_lock);
+ if (test_bit(FW_STATUS_DONE, &(fw_priv->buf->status))) {
+ mutex_unlock(&fw_lock);
+ return;
+ }
fw_load_abort(fw_priv);
+ mutex_unlock(&fw_lock);
}
static struct firmware_priv *
@@ -690,8 +714,8 @@ fw_create_instance(struct firmware *firmware, const char *fw_name,
fw_priv->nowait = nowait;
fw_priv->fw = firmware;
- setup_timer(&fw_priv->timeout,
- firmware_class_timeout, (u_long) fw_priv);
+ INIT_DELAYED_WORK(&fw_priv->timeout_work,
+ firmware_class_timeout_work);
f_dev = &fw_priv->dev;
@@ -858,7 +882,9 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
dev_dbg(f_dev->parent, "firmware: direct-loading"
" firmware %s\n", buf->fw_id);
+ mutex_lock(&fw_lock);
set_bit(FW_STATUS_DONE, &buf->status);
+ mutex_unlock(&fw_lock);
complete_all(&buf->completion);
direct_load = 1;
goto handle_fw;
@@ -894,15 +920,14 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
dev_set_uevent_suppress(f_dev, false);
dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id);
if (timeout != MAX_SCHEDULE_TIMEOUT)
- mod_timer(&fw_priv->timeout,
- round_jiffies_up(jiffies + timeout));
+ schedule_delayed_work(&fw_priv->timeout_work, timeout);
kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD);
}
wait_for_completion(&buf->completion);
- del_timer_sync(&fw_priv->timeout);
+ cancel_delayed_work_sync(&fw_priv->timeout_work);
handle_fw:
mutex_lock(&fw_lock);
@@ -963,6 +988,9 @@ err_put_dev:
* firmware image for this or any other device.
*
* Caller must hold the reference count of @device.
+ *
+ * The function can be called safely inside device's suspend and
+ * resume callback.
**/
int
request_firmware(const struct firmware **firmware_p, const char *name,
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 86c88216a50..987604d56c8 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -70,6 +70,13 @@ void unregister_memory_isolate_notifier(struct notifier_block *nb)
}
EXPORT_SYMBOL(unregister_memory_isolate_notifier);
+static void memory_block_release(struct device *dev)
+{
+ struct memory_block *mem = container_of(dev, struct memory_block, dev);
+
+ kfree(mem);
+}
+
/*
* register_memory - Setup a sysfs device for a memory block
*/
@@ -80,6 +87,7 @@ int register_memory(struct memory_block *memory)
memory->dev.bus = &memory_subsys;
memory->dev.id = memory->start_section_nr / sections_per_block;
+ memory->dev.release = memory_block_release;
error = device_register(&memory->dev);
return error;
@@ -246,7 +254,7 @@ static bool pages_correctly_reserved(unsigned long start_pfn,
* OK to have direct references to sparsemem variables in here.
*/
static int
-memory_block_action(unsigned long phys_index, unsigned long action)
+memory_block_action(unsigned long phys_index, unsigned long action, int online_type)
{
unsigned long start_pfn;
unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
@@ -261,7 +269,7 @@ memory_block_action(unsigned long phys_index, unsigned long action)
if (!pages_correctly_reserved(start_pfn, nr_pages))
return -EBUSY;
- ret = online_pages(start_pfn, nr_pages);
+ ret = online_pages(start_pfn, nr_pages, online_type);
break;
case MEM_OFFLINE:
ret = offline_pages(start_pfn, nr_pages);
@@ -276,7 +284,8 @@ memory_block_action(unsigned long phys_index, unsigned long action)
}
static int __memory_block_change_state(struct memory_block *mem,
- unsigned long to_state, unsigned long from_state_req)
+ unsigned long to_state, unsigned long from_state_req,
+ int online_type)
{
int ret = 0;
@@ -288,7 +297,7 @@ static int __memory_block_change_state(struct memory_block *mem,
if (to_state == MEM_OFFLINE)
mem->state = MEM_GOING_OFFLINE;
- ret = memory_block_action(mem->start_section_nr, to_state);
+ ret = memory_block_action(mem->start_section_nr, to_state, online_type);
if (ret) {
mem->state = from_state_req;
@@ -311,12 +320,14 @@ out:
}
static int memory_block_change_state(struct memory_block *mem,
- unsigned long to_state, unsigned long from_state_req)
+ unsigned long to_state, unsigned long from_state_req,
+ int online_type)
{
int ret;
mutex_lock(&mem->state_mutex);
- ret = __memory_block_change_state(mem, to_state, from_state_req);
+ ret = __memory_block_change_state(mem, to_state, from_state_req,
+ online_type);
mutex_unlock(&mem->state_mutex);
return ret;
@@ -330,10 +341,18 @@ store_mem_state(struct device *dev,
mem = container_of(dev, struct memory_block, dev);
- if (!strncmp(buf, "online", min((int)count, 6)))
- ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE);
- else if(!strncmp(buf, "offline", min((int)count, 7)))
- ret = memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE);
+ if (!strncmp(buf, "online_kernel", min_t(int, count, 13)))
+ ret = memory_block_change_state(mem, MEM_ONLINE,
+ MEM_OFFLINE, ONLINE_KERNEL);
+ else if (!strncmp(buf, "online_movable", min_t(int, count, 14)))
+ ret = memory_block_change_state(mem, MEM_ONLINE,
+ MEM_OFFLINE, ONLINE_MOVABLE);
+ else if (!strncmp(buf, "online", min_t(int, count, 6)))
+ ret = memory_block_change_state(mem, MEM_ONLINE,
+ MEM_OFFLINE, ONLINE_KEEP);
+ else if(!strncmp(buf, "offline", min_t(int, count, 7)))
+ ret = memory_block_change_state(mem, MEM_OFFLINE,
+ MEM_ONLINE, -1);
if (ret)
return ret;
@@ -635,7 +654,6 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section,
mem_remove_simple_file(mem, phys_device);
mem_remove_simple_file(mem, removable);
unregister_memory(mem);
- kfree(mem);
} else
kobject_put(&mem->dev.kobj);
@@ -669,7 +687,7 @@ int offline_memory_block(struct memory_block *mem)
mutex_lock(&mem->state_mutex);
if (mem->state != MEM_OFFLINE)
- ret = __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE);
+ ret = __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE, -1);
mutex_unlock(&mem->state_mutex);
return ret;
diff --git a/drivers/base/node.c b/drivers/base/node.c
index af1a177216f..294e3162621 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -252,6 +252,24 @@ static inline void hugetlb_register_node(struct node *node) {}
static inline void hugetlb_unregister_node(struct node *node) {}
#endif
+static void node_device_release(struct device *dev)
+{
+ struct node *node = to_node(dev);
+
+#if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_HUGETLBFS)
+ /*
+ * We schedule the work only when a memory section is
+ * onlined/offlined on this node. When we come here,
+ * all the memory on this node has been offlined,
+ * so we won't enqueue new work to this work.
+ *
+ * The work is using node->node_work, so we should
+ * flush work before freeing the memory.
+ */
+ flush_work(&node->node_work);
+#endif
+ kfree(node);
+}
/*
* register_node - Setup a sysfs device for a node.
@@ -259,12 +277,13 @@ static inline void hugetlb_unregister_node(struct node *node) {}
*
* Initialize and register the node device.
*/
-int register_node(struct node *node, int num, struct node *parent)
+static int register_node(struct node *node, int num, struct node *parent)
{
int error;
node->dev.id = num;
node->dev.bus = &node_subsys;
+ node->dev.release = node_device_release;
error = device_register(&node->dev);
if (!error){
@@ -306,7 +325,7 @@ void unregister_node(struct node *node)
device_unregister(&node->dev);
}
-struct node node_devices[MAX_NUMNODES];
+struct node *node_devices[MAX_NUMNODES];
/*
* register cpu under node
@@ -323,15 +342,15 @@ int register_cpu_under_node(unsigned int cpu, unsigned int nid)
if (!obj)
return 0;
- ret = sysfs_create_link(&node_devices[nid].dev.kobj,
+ ret = sysfs_create_link(&node_devices[nid]->dev.kobj,
&obj->kobj,
kobject_name(&obj->kobj));
if (ret)
return ret;
return sysfs_create_link(&obj->kobj,
- &node_devices[nid].dev.kobj,
- kobject_name(&node_devices[nid].dev.kobj));
+ &node_devices[nid]->dev.kobj,
+ kobject_name(&node_devices[nid]->dev.kobj));
}
int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
@@ -345,10 +364,10 @@ int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
if (!obj)
return 0;
- sysfs_remove_link(&node_devices[nid].dev.kobj,
+ sysfs_remove_link(&node_devices[nid]->dev.kobj,
kobject_name(&obj->kobj));
sysfs_remove_link(&obj->kobj,
- kobject_name(&node_devices[nid].dev.kobj));
+ kobject_name(&node_devices[nid]->dev.kobj));
return 0;
}
@@ -390,15 +409,15 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, int nid)
continue;
if (page_nid != nid)
continue;
- ret = sysfs_create_link_nowarn(&node_devices[nid].dev.kobj,
+ ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj,
&mem_blk->dev.kobj,
kobject_name(&mem_blk->dev.kobj));
if (ret)
return ret;
return sysfs_create_link_nowarn(&mem_blk->dev.kobj,
- &node_devices[nid].dev.kobj,
- kobject_name(&node_devices[nid].dev.kobj));
+ &node_devices[nid]->dev.kobj,
+ kobject_name(&node_devices[nid]->dev.kobj));
}
/* mem section does not span the specified node */
return 0;
@@ -431,10 +450,10 @@ int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
continue;
if (node_test_and_set(nid, *unlinked_nodes))
continue;
- sysfs_remove_link(&node_devices[nid].dev.kobj,
+ sysfs_remove_link(&node_devices[nid]->dev.kobj,
kobject_name(&mem_blk->dev.kobj));
sysfs_remove_link(&mem_blk->dev.kobj,
- kobject_name(&node_devices[nid].dev.kobj));
+ kobject_name(&node_devices[nid]->dev.kobj));
}
NODEMASK_FREE(unlinked_nodes);
return 0;
@@ -500,7 +519,7 @@ static void node_hugetlb_work(struct work_struct *work)
static void init_node_hugetlb_work(int nid)
{
- INIT_WORK(&node_devices[nid].node_work, node_hugetlb_work);
+ INIT_WORK(&node_devices[nid]->node_work, node_hugetlb_work);
}
static int node_memory_callback(struct notifier_block *self,
@@ -517,7 +536,7 @@ static int node_memory_callback(struct notifier_block *self,
* when transitioning to/from memoryless state.
*/
if (nid != NUMA_NO_NODE)
- schedule_work(&node_devices[nid].node_work);
+ schedule_work(&node_devices[nid]->node_work);
break;
case MEM_GOING_ONLINE:
@@ -558,9 +577,13 @@ int register_one_node(int nid)
struct node *parent = NULL;
if (p_node != nid)
- parent = &node_devices[p_node];
+ parent = node_devices[p_node];
+
+ node_devices[nid] = kzalloc(sizeof(struct node), GFP_KERNEL);
+ if (!node_devices[nid])
+ return -ENOMEM;
- error = register_node(&node_devices[nid], nid, parent);
+ error = register_node(node_devices[nid], nid, parent);
/* link cpu under this node */
for_each_present_cpu(cpu) {
@@ -581,7 +604,8 @@ int register_one_node(int nid)
void unregister_one_node(int nid)
{
- unregister_node(&node_devices[nid]);
+ unregister_node(node_devices[nid]);
+ node_devices[nid] = NULL;
}
/*
@@ -614,23 +638,23 @@ static ssize_t show_node_state(struct device *dev,
{ __ATTR(name, 0444, show_node_state, NULL), state }
static struct node_attr node_state_attr[] = {
- _NODE_ATTR(possible, N_POSSIBLE),
- _NODE_ATTR(online, N_ONLINE),
- _NODE_ATTR(has_normal_memory, N_NORMAL_MEMORY),
- _NODE_ATTR(has_cpu, N_CPU),
+ [N_POSSIBLE] = _NODE_ATTR(possible, N_POSSIBLE),
+ [N_ONLINE] = _NODE_ATTR(online, N_ONLINE),
+ [N_NORMAL_MEMORY] = _NODE_ATTR(has_normal_memory, N_NORMAL_MEMORY),
#ifdef CONFIG_HIGHMEM
- _NODE_ATTR(has_high_memory, N_HIGH_MEMORY),
+ [N_HIGH_MEMORY] = _NODE_ATTR(has_high_memory, N_HIGH_MEMORY),
#endif
+ [N_CPU] = _NODE_ATTR(has_cpu, N_CPU),
};
static struct attribute *node_state_attrs[] = {
- &node_state_attr[0].attr.attr,
- &node_state_attr[1].attr.attr,
- &node_state_attr[2].attr.attr,
- &node_state_attr[3].attr.attr,
+ &node_state_attr[N_POSSIBLE].attr.attr,
+ &node_state_attr[N_ONLINE].attr.attr,
+ &node_state_attr[N_NORMAL_MEMORY].attr.attr,
#ifdef CONFIG_HIGHMEM
- &node_state_attr[4].attr.attr,
+ &node_state_attr[N_HIGH_MEMORY].attr.attr,
#endif
+ &node_state_attr[N_CPU].attr.attr,
NULL
};
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 72c776f2a1f..c0b8df38402 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/idr.h>
+#include <linux/acpi.h>
#include "base.h"
#include "power/power.h"
@@ -44,7 +45,7 @@ EXPORT_SYMBOL_GPL(platform_bus);
* be setup before the platform_notifier is called. So if a user needs to
* manipulate any relevant information in the pdev_archdata they can do:
*
- * platform_devic_alloc()
+ * platform_device_alloc()
* ... manipulate ...
* platform_device_add()
*
@@ -122,7 +123,7 @@ struct resource *platform_get_resource_byname(struct platform_device *dev,
EXPORT_SYMBOL_GPL(platform_get_resource_byname);
/**
- * platform_get_irq - get an IRQ for a device
+ * platform_get_irq_byname - get an IRQ for a device by name
* @dev: platform device
* @name: IRQ name
*/
@@ -436,6 +437,7 @@ struct platform_device *platform_device_register_full(
goto err_alloc;
pdev->dev.parent = pdevinfo->parent;
+ ACPI_HANDLE_SET(&pdev->dev, pdevinfo->acpi_node.handle);
if (pdevinfo->dma_mask) {
/*
@@ -466,6 +468,7 @@ struct platform_device *platform_device_register_full(
ret = platform_device_add(pdev);
if (ret) {
err:
+ ACPI_HANDLE_SET(&pdev->dev, NULL);
kfree(pdev->dev.dma_mask);
err_alloc:
@@ -481,8 +484,16 @@ static int platform_drv_probe(struct device *_dev)
{
struct platform_driver *drv = to_platform_driver(_dev->driver);
struct platform_device *dev = to_platform_device(_dev);
+ int ret;
+
+ if (ACPI_HANDLE(_dev))
+ acpi_dev_pm_attach(_dev, true);
- return drv->probe(dev);
+ ret = drv->probe(dev);
+ if (ret && ACPI_HANDLE(_dev))
+ acpi_dev_pm_detach(_dev, true);
+
+ return ret;
}
static int platform_drv_probe_fail(struct device *_dev)
@@ -494,8 +505,13 @@ static int platform_drv_remove(struct device *_dev)
{
struct platform_driver *drv = to_platform_driver(_dev->driver);
struct platform_device *dev = to_platform_device(_dev);
+ int ret;
- return drv->remove(dev);
+ ret = drv->remove(dev);
+ if (ACPI_HANDLE(_dev))
+ acpi_dev_pm_detach(_dev, true);
+
+ return ret;
}
static void platform_drv_shutdown(struct device *_dev)
@@ -504,6 +520,8 @@ static void platform_drv_shutdown(struct device *_dev)
struct platform_device *dev = to_platform_device(_dev);
drv->shutdown(dev);
+ if (ACPI_HANDLE(_dev))
+ acpi_dev_pm_detach(_dev, true);
}
/**
@@ -709,6 +727,10 @@ static int platform_match(struct device *dev, struct device_driver *drv)
if (of_driver_match_device(dev, drv))
return 1;
+ /* Then try ACPI style match */
+ if (acpi_driver_match_device(dev, drv))
+ return 1;
+
/* Then try to match against the id table */
if (pdrv->id_table)
return platform_match_id(pdrv->id_table, pdev) != NULL;
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c
index eb78e9640c4..9d8fde70939 100644
--- a/drivers/base/power/clock_ops.c
+++ b/drivers/base/power/clock_ops.c
@@ -99,7 +99,7 @@ static void __pm_clk_remove(struct pm_clock_entry *ce)
if (ce->status < PCE_STATUS_ERROR) {
if (ce->status == PCE_STATUS_ENABLED)
- clk_disable(ce->clk);
+ clk_disable_unprepare(ce->clk);
if (ce->status >= PCE_STATUS_ACQUIRED)
clk_put(ce->clk);
@@ -396,7 +396,7 @@ static void enable_clock(struct device *dev, const char *con_id)
clk = clk_get(dev, con_id);
if (!IS_ERR(clk)) {
- clk_enable(clk);
+ clk_prepare_enable(clk);
clk_put(clk);
dev_info(dev, "Runtime PM disabled, clock forced on.\n");
}
@@ -413,7 +413,7 @@ static void disable_clock(struct device *dev, const char *con_id)
clk = clk_get(dev, con_id);
if (!IS_ERR(clk)) {
- clk_disable(clk);
+ clk_disable_unprepare(clk);
clk_put(clk);
dev_info(dev, "Runtime PM disabled, clock forced off.\n");
}
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 96b71b6536d..acc3a8ded29 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -470,10 +470,19 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
return -EBUSY;
not_suspended = 0;
- list_for_each_entry(pdd, &genpd->dev_list, list_node)
+ list_for_each_entry(pdd, &genpd->dev_list, list_node) {
+ enum pm_qos_flags_status stat;
+
+ stat = dev_pm_qos_flags(pdd->dev,
+ PM_QOS_FLAG_NO_POWER_OFF
+ | PM_QOS_FLAG_REMOTE_WAKEUP);
+ if (stat > PM_QOS_FLAGS_NONE)
+ return -EBUSY;
+
if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev)
|| pdd->dev->power.irq_safe))
not_suspended++;
+ }
if (not_suspended > genpd->in_progress)
return -EBUSY;
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
index d9468642fc4..50b2831e027 100644
--- a/drivers/base/power/opp.c
+++ b/drivers/base/power/opp.c
@@ -23,6 +23,7 @@
#include <linux/rcupdate.h>
#include <linux/opp.h>
#include <linux/of.h>
+#include <linux/export.h>
/*
* Internal data structure organization with the OPP layer library is as
@@ -65,6 +66,7 @@ struct opp {
unsigned long u_volt;
struct device_opp *dev_opp;
+ struct rcu_head head;
};
/**
@@ -160,6 +162,7 @@ unsigned long opp_get_voltage(struct opp *opp)
return v;
}
+EXPORT_SYMBOL(opp_get_voltage);
/**
* opp_get_freq() - Gets the frequency corresponding to an available opp
@@ -189,6 +192,7 @@ unsigned long opp_get_freq(struct opp *opp)
return f;
}
+EXPORT_SYMBOL(opp_get_freq);
/**
* opp_get_opp_count() - Get number of opps available in the opp list
@@ -221,6 +225,7 @@ int opp_get_opp_count(struct device *dev)
return count;
}
+EXPORT_SYMBOL(opp_get_opp_count);
/**
* opp_find_freq_exact() - search for an exact frequency
@@ -230,7 +235,10 @@ int opp_get_opp_count(struct device *dev)
*
* Searches for exact match in the opp list and returns pointer to the matching
* opp if found, else returns ERR_PTR in case of error and should be handled
- * using IS_ERR.
+ * using IS_ERR. Error return values can be:
+ * EINVAL: for bad pointer
+ * ERANGE: no match found for search
+ * ENODEV: if device not found in list of registered devices
*
* Note: available is a modifier for the search. if available=true, then the
* match is for exact matching frequency and is available in the stored OPP
@@ -249,7 +257,7 @@ struct opp *opp_find_freq_exact(struct device *dev, unsigned long freq,
bool available)
{
struct device_opp *dev_opp;
- struct opp *temp_opp, *opp = ERR_PTR(-ENODEV);
+ struct opp *temp_opp, *opp = ERR_PTR(-ERANGE);
dev_opp = find_device_opp(dev);
if (IS_ERR(dev_opp)) {
@@ -268,6 +276,7 @@ struct opp *opp_find_freq_exact(struct device *dev, unsigned long freq,
return opp;
}
+EXPORT_SYMBOL(opp_find_freq_exact);
/**
* opp_find_freq_ceil() - Search for an rounded ceil freq
@@ -278,7 +287,11 @@ struct opp *opp_find_freq_exact(struct device *dev, unsigned long freq,
* for a device.
*
* Returns matching *opp and refreshes *freq accordingly, else returns
- * ERR_PTR in case of error and should be handled using IS_ERR.
+ * ERR_PTR in case of error and should be handled using IS_ERR. Error return
+ * values can be:
+ * EINVAL: for bad pointer
+ * ERANGE: no match found for search
+ * ENODEV: if device not found in list of registered devices
*
* Locking: This function must be called under rcu_read_lock(). opp is a rcu
* protected pointer. The reason for the same is that the opp pointer which is
@@ -289,7 +302,7 @@ struct opp *opp_find_freq_exact(struct device *dev, unsigned long freq,
struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq)
{
struct device_opp *dev_opp;
- struct opp *temp_opp, *opp = ERR_PTR(-ENODEV);
+ struct opp *temp_opp, *opp = ERR_PTR(-ERANGE);
if (!dev || !freq) {
dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq);
@@ -298,7 +311,7 @@ struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq)
dev_opp = find_device_opp(dev);
if (IS_ERR(dev_opp))
- return opp;
+ return ERR_CAST(dev_opp);
list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) {
if (temp_opp->available && temp_opp->rate >= *freq) {
@@ -310,6 +323,7 @@ struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq)
return opp;
}
+EXPORT_SYMBOL(opp_find_freq_ceil);
/**
* opp_find_freq_floor() - Search for a rounded floor freq
@@ -320,7 +334,11 @@ struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq)
* for a device.
*
* Returns matching *opp and refreshes *freq accordingly, else returns
- * ERR_PTR in case of error and should be handled using IS_ERR.
+ * ERR_PTR in case of error and should be handled using IS_ERR. Error return
+ * values can be:
+ * EINVAL: for bad pointer
+ * ERANGE: no match found for search
+ * ENODEV: if device not found in list of registered devices
*
* Locking: This function must be called under rcu_read_lock(). opp is a rcu
* protected pointer. The reason for the same is that the opp pointer which is
@@ -331,7 +349,7 @@ struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq)
struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq)
{
struct device_opp *dev_opp;
- struct opp *temp_opp, *opp = ERR_PTR(-ENODEV);
+ struct opp *temp_opp, *opp = ERR_PTR(-ERANGE);
if (!dev || !freq) {
dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq);
@@ -340,7 +358,7 @@ struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq)
dev_opp = find_device_opp(dev);
if (IS_ERR(dev_opp))
- return opp;
+ return ERR_CAST(dev_opp);
list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) {
if (temp_opp->available) {
@@ -356,6 +374,7 @@ struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq)
return opp;
}
+EXPORT_SYMBOL(opp_find_freq_floor);
/**
* opp_add() - Add an OPP table from a table definitions
@@ -512,7 +531,7 @@ static int opp_set_availability(struct device *dev, unsigned long freq,
list_replace_rcu(&opp->node, &new_opp->node);
mutex_unlock(&dev_opp_list_lock);
- synchronize_rcu();
+ kfree_rcu(opp, head);
/* Notify the change of the OPP availability */
if (availability_req)
@@ -522,13 +541,10 @@ static int opp_set_availability(struct device *dev, unsigned long freq,
srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_DISABLE,
new_opp);
- /* clean up old opp */
- new_opp = opp;
- goto out;
+ return 0;
unlock:
mutex_unlock(&dev_opp_list_lock);
-out:
kfree(new_opp);
return r;
}
@@ -552,6 +568,7 @@ int opp_enable(struct device *dev, unsigned long freq)
{
return opp_set_availability(dev, freq, true);
}
+EXPORT_SYMBOL(opp_enable);
/**
* opp_disable() - Disable a specific OPP
@@ -573,6 +590,7 @@ int opp_disable(struct device *dev, unsigned long freq)
{
return opp_set_availability(dev, freq, false);
}
+EXPORT_SYMBOL(opp_disable);
#ifdef CONFIG_CPU_FREQ
/**
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index 0dbfdf4419a..b16686a0a5a 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -93,8 +93,10 @@ extern void dpm_sysfs_remove(struct device *dev);
extern void rpm_sysfs_remove(struct device *dev);
extern int wakeup_sysfs_add(struct device *dev);
extern void wakeup_sysfs_remove(struct device *dev);
-extern int pm_qos_sysfs_add(struct device *dev);
-extern void pm_qos_sysfs_remove(struct device *dev);
+extern int pm_qos_sysfs_add_latency(struct device *dev);
+extern void pm_qos_sysfs_remove_latency(struct device *dev);
+extern int pm_qos_sysfs_add_flags(struct device *dev);
+extern void pm_qos_sysfs_remove_flags(struct device *dev);
#else /* CONFIG_PM */
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
index 74a67e0019a..ff46387f530 100644
--- a/drivers/base/power/qos.c
+++ b/drivers/base/power/qos.c
@@ -40,6 +40,7 @@
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/export.h>
+#include <linux/pm_runtime.h>
#include "power.h"
@@ -48,6 +49,50 @@ static DEFINE_MUTEX(dev_pm_qos_mtx);
static BLOCKING_NOTIFIER_HEAD(dev_pm_notifiers);
/**
+ * __dev_pm_qos_flags - Check PM QoS flags for a given device.
+ * @dev: Device to check the PM QoS flags for.
+ * @mask: Flags to check against.
+ *
+ * This routine must be called with dev->power.lock held.
+ */
+enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, s32 mask)
+{
+ struct dev_pm_qos *qos = dev->power.qos;
+ struct pm_qos_flags *pqf;
+ s32 val;
+
+ if (!qos)
+ return PM_QOS_FLAGS_UNDEFINED;
+
+ pqf = &qos->flags;
+ if (list_empty(&pqf->list))
+ return PM_QOS_FLAGS_UNDEFINED;
+
+ val = pqf->effective_flags & mask;
+ if (val)
+ return (val == mask) ? PM_QOS_FLAGS_ALL : PM_QOS_FLAGS_SOME;
+
+ return PM_QOS_FLAGS_NONE;
+}
+
+/**
+ * dev_pm_qos_flags - Check PM QoS flags for a given device (locked).
+ * @dev: Device to check the PM QoS flags for.
+ * @mask: Flags to check against.
+ */
+enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev, s32 mask)
+{
+ unsigned long irqflags;
+ enum pm_qos_flags_status ret;
+
+ spin_lock_irqsave(&dev->power.lock, irqflags);
+ ret = __dev_pm_qos_flags(dev, mask);
+ spin_unlock_irqrestore(&dev->power.lock, irqflags);
+
+ return ret;
+}
+
+/**
* __dev_pm_qos_read_value - Get PM QoS constraint for a given device.
* @dev: Device to get the PM QoS constraint value for.
*
@@ -55,9 +100,7 @@ static BLOCKING_NOTIFIER_HEAD(dev_pm_notifiers);
*/
s32 __dev_pm_qos_read_value(struct device *dev)
{
- struct pm_qos_constraints *c = dev->power.constraints;
-
- return c ? pm_qos_read_value(c) : 0;
+ return dev->power.qos ? pm_qos_read_value(&dev->power.qos->latency) : 0;
}
/**
@@ -76,30 +119,39 @@ s32 dev_pm_qos_read_value(struct device *dev)
return ret;
}
-/*
- * apply_constraint
- * @req: constraint request to apply
- * @action: action to perform add/update/remove, of type enum pm_qos_req_action
- * @value: defines the qos request
+/**
+ * apply_constraint - Add/modify/remove device PM QoS request.
+ * @req: Constraint request to apply
+ * @action: Action to perform (add/update/remove).
+ * @value: Value to assign to the QoS request.
*
* Internal function to update the constraints list using the PM QoS core
* code and if needed call the per-device and the global notification
* callbacks
*/
static int apply_constraint(struct dev_pm_qos_request *req,
- enum pm_qos_req_action action, int value)
+ enum pm_qos_req_action action, s32 value)
{
- int ret, curr_value;
-
- ret = pm_qos_update_target(req->dev->power.constraints,
- &req->node, action, value);
+ struct dev_pm_qos *qos = req->dev->power.qos;
+ int ret;
- if (ret) {
- /* Call the global callbacks if needed */
- curr_value = pm_qos_read_value(req->dev->power.constraints);
- blocking_notifier_call_chain(&dev_pm_notifiers,
- (unsigned long)curr_value,
- req);
+ switch(req->type) {
+ case DEV_PM_QOS_LATENCY:
+ ret = pm_qos_update_target(&qos->latency, &req->data.pnode,
+ action, value);
+ if (ret) {
+ value = pm_qos_read_value(&qos->latency);
+ blocking_notifier_call_chain(&dev_pm_notifiers,
+ (unsigned long)value,
+ req);
+ }
+ break;
+ case DEV_PM_QOS_FLAGS:
+ ret = pm_qos_update_flags(&qos->flags, &req->data.flr,
+ action, value);
+ break;
+ default:
+ ret = -EINVAL;
}
return ret;
@@ -114,28 +166,32 @@ static int apply_constraint(struct dev_pm_qos_request *req,
*/
static int dev_pm_qos_constraints_allocate(struct device *dev)
{
+ struct dev_pm_qos *qos;
struct pm_qos_constraints *c;
struct blocking_notifier_head *n;
- c = kzalloc(sizeof(*c), GFP_KERNEL);
- if (!c)
+ qos = kzalloc(sizeof(*qos), GFP_KERNEL);
+ if (!qos)
return -ENOMEM;
n = kzalloc(sizeof(*n), GFP_KERNEL);
if (!n) {
- kfree(c);
+ kfree(qos);
return -ENOMEM;
}
BLOCKING_INIT_NOTIFIER_HEAD(n);
+ c = &qos->latency;
plist_head_init(&c->list);
c->target_value = PM_QOS_DEV_LAT_DEFAULT_VALUE;
c->default_value = PM_QOS_DEV_LAT_DEFAULT_VALUE;
c->type = PM_QOS_MIN;
c->notifiers = n;
+ INIT_LIST_HEAD(&qos->flags.list);
+
spin_lock_irq(&dev->power.lock);
- dev->power.constraints = c;
+ dev->power.qos = qos;
spin_unlock_irq(&dev->power.lock);
return 0;
@@ -151,7 +207,7 @@ static int dev_pm_qos_constraints_allocate(struct device *dev)
void dev_pm_qos_constraints_init(struct device *dev)
{
mutex_lock(&dev_pm_qos_mtx);
- dev->power.constraints = NULL;
+ dev->power.qos = NULL;
dev->power.power_state = PMSG_ON;
mutex_unlock(&dev_pm_qos_mtx);
}
@@ -164,24 +220,28 @@ void dev_pm_qos_constraints_init(struct device *dev)
*/
void dev_pm_qos_constraints_destroy(struct device *dev)
{
+ struct dev_pm_qos *qos;
struct dev_pm_qos_request *req, *tmp;
struct pm_qos_constraints *c;
+ struct pm_qos_flags *f;
/*
- * If the device's PM QoS resume latency limit has been exposed to user
- * space, it has to be hidden at this point.
+ * If the device's PM QoS resume latency limit or PM QoS flags have been
+ * exposed to user space, they have to be hidden at this point.
*/
dev_pm_qos_hide_latency_limit(dev);
+ dev_pm_qos_hide_flags(dev);
mutex_lock(&dev_pm_qos_mtx);
dev->power.power_state = PMSG_INVALID;
- c = dev->power.constraints;
- if (!c)
+ qos = dev->power.qos;
+ if (!qos)
goto out;
- /* Flush the constraints list for the device */
- plist_for_each_entry_safe(req, tmp, &c->list, node) {
+ /* Flush the constraints lists for the device. */
+ c = &qos->latency;
+ plist_for_each_entry_safe(req, tmp, &c->list, data.pnode) {
/*
* Update constraints list and call the notification
* callbacks if needed
@@ -189,13 +249,18 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
memset(req, 0, sizeof(*req));
}
+ f = &qos->flags;
+ list_for_each_entry_safe(req, tmp, &f->list, data.flr.node) {
+ apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
+ memset(req, 0, sizeof(*req));
+ }
spin_lock_irq(&dev->power.lock);
- dev->power.constraints = NULL;
+ dev->power.qos = NULL;
spin_unlock_irq(&dev->power.lock);
kfree(c->notifiers);
- kfree(c);
+ kfree(qos);
out:
mutex_unlock(&dev_pm_qos_mtx);
@@ -205,6 +270,7 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
* dev_pm_qos_add_request - inserts new qos request into the list
* @dev: target device for the constraint
* @req: pointer to a preallocated handle
+ * @type: type of the request
* @value: defines the qos request
*
* This function inserts a new entry in the device constraints list of
@@ -218,9 +284,12 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
* -EINVAL in case of wrong parameters, -ENOMEM if there's not enough memory
* to allocate for data structures, -ENODEV if the device has just been removed
* from the system.
+ *
+ * Callers should ensure that the target device is not RPM_SUSPENDED before
+ * using this function for requests of type DEV_PM_QOS_FLAGS.
*/
int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
- s32 value)
+ enum dev_pm_qos_req_type type, s32 value)
{
int ret = 0;
@@ -235,7 +304,7 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
mutex_lock(&dev_pm_qos_mtx);
- if (!dev->power.constraints) {
+ if (!dev->power.qos) {
if (dev->power.power_state.event == PM_EVENT_INVALID) {
/* The device has been removed from the system. */
req->dev = NULL;
@@ -251,8 +320,10 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
}
}
- if (!ret)
+ if (!ret) {
+ req->type = type;
ret = apply_constraint(req, PM_QOS_ADD_REQ, value);
+ }
out:
mutex_unlock(&dev_pm_qos_mtx);
@@ -262,6 +333,37 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
EXPORT_SYMBOL_GPL(dev_pm_qos_add_request);
/**
+ * __dev_pm_qos_update_request - Modify an existing device PM QoS request.
+ * @req : PM QoS request to modify.
+ * @new_value: New value to request.
+ */
+static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req,
+ s32 new_value)
+{
+ s32 curr_value;
+ int ret = 0;
+
+ if (!req->dev->power.qos)
+ return -ENODEV;
+
+ switch(req->type) {
+ case DEV_PM_QOS_LATENCY:
+ curr_value = req->data.pnode.prio;
+ break;
+ case DEV_PM_QOS_FLAGS:
+ curr_value = req->data.flr.flags;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (curr_value != new_value)
+ ret = apply_constraint(req, PM_QOS_UPDATE_REQ, new_value);
+
+ return ret;
+}
+
+/**
* dev_pm_qos_update_request - modifies an existing qos request
* @req : handle to list element holding a dev_pm_qos request to use
* @new_value: defines the qos request
@@ -275,11 +377,13 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_add_request);
* 0 if the aggregated constraint value has not changed,
* -EINVAL in case of wrong parameters, -ENODEV if the device has been
* removed from the system
+ *
+ * Callers should ensure that the target device is not RPM_SUSPENDED before
+ * using this function for requests of type DEV_PM_QOS_FLAGS.
*/
-int dev_pm_qos_update_request(struct dev_pm_qos_request *req,
- s32 new_value)
+int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value)
{
- int ret = 0;
+ int ret;
if (!req) /*guard against callers passing in null */
return -EINVAL;
@@ -289,17 +393,9 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req,
return -EINVAL;
mutex_lock(&dev_pm_qos_mtx);
-
- if (req->dev->power.constraints) {
- if (new_value != req->node.prio)
- ret = apply_constraint(req, PM_QOS_UPDATE_REQ,
- new_value);
- } else {
- /* Return if the device has been removed */
- ret = -ENODEV;
- }
-
+ ret = __dev_pm_qos_update_request(req, new_value);
mutex_unlock(&dev_pm_qos_mtx);
+
return ret;
}
EXPORT_SYMBOL_GPL(dev_pm_qos_update_request);
@@ -315,6 +411,9 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_update_request);
* 0 if the aggregated constraint value has not changed,
* -EINVAL in case of wrong parameters, -ENODEV if the device has been
* removed from the system
+ *
+ * Callers should ensure that the target device is not RPM_SUSPENDED before
+ * using this function for requests of type DEV_PM_QOS_FLAGS.
*/
int dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
{
@@ -329,7 +428,7 @@ int dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
mutex_lock(&dev_pm_qos_mtx);
- if (req->dev->power.constraints) {
+ if (req->dev->power.qos) {
ret = apply_constraint(req, PM_QOS_REMOVE_REQ,
PM_QOS_DEFAULT_VALUE);
memset(req, 0, sizeof(*req));
@@ -362,13 +461,13 @@ int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier)
mutex_lock(&dev_pm_qos_mtx);
- if (!dev->power.constraints)
+ if (!dev->power.qos)
ret = dev->power.power_state.event != PM_EVENT_INVALID ?
dev_pm_qos_constraints_allocate(dev) : -ENODEV;
if (!ret)
ret = blocking_notifier_chain_register(
- dev->power.constraints->notifiers, notifier);
+ dev->power.qos->latency.notifiers, notifier);
mutex_unlock(&dev_pm_qos_mtx);
return ret;
@@ -393,9 +492,9 @@ int dev_pm_qos_remove_notifier(struct device *dev,
mutex_lock(&dev_pm_qos_mtx);
/* Silently return if the constraints object is not present. */
- if (dev->power.constraints)
+ if (dev->power.qos)
retval = blocking_notifier_chain_unregister(
- dev->power.constraints->notifiers,
+ dev->power.qos->latency.notifiers,
notifier);
mutex_unlock(&dev_pm_qos_mtx);
@@ -449,9 +548,10 @@ int dev_pm_qos_add_ancestor_request(struct device *dev,
ancestor = ancestor->parent;
if (ancestor)
- error = dev_pm_qos_add_request(ancestor, req, value);
+ error = dev_pm_qos_add_request(ancestor, req,
+ DEV_PM_QOS_LATENCY, value);
- if (error)
+ if (error < 0)
req->dev = NULL;
return error;
@@ -459,10 +559,19 @@ int dev_pm_qos_add_ancestor_request(struct device *dev,
EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request);
#ifdef CONFIG_PM_RUNTIME
-static void __dev_pm_qos_drop_user_request(struct device *dev)
+static void __dev_pm_qos_drop_user_request(struct device *dev,
+ enum dev_pm_qos_req_type type)
{
- dev_pm_qos_remove_request(dev->power.pq_req);
- dev->power.pq_req = NULL;
+ switch(type) {
+ case DEV_PM_QOS_LATENCY:
+ dev_pm_qos_remove_request(dev->power.qos->latency_req);
+ dev->power.qos->latency_req = NULL;
+ break;
+ case DEV_PM_QOS_FLAGS:
+ dev_pm_qos_remove_request(dev->power.qos->flags_req);
+ dev->power.qos->flags_req = NULL;
+ break;
+ }
}
/**
@@ -478,21 +587,21 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value)
if (!device_is_registered(dev) || value < 0)
return -EINVAL;
- if (dev->power.pq_req)
+ if (dev->power.qos && dev->power.qos->latency_req)
return -EEXIST;
req = kzalloc(sizeof(*req), GFP_KERNEL);
if (!req)
return -ENOMEM;
- ret = dev_pm_qos_add_request(dev, req, value);
+ ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_LATENCY, value);
if (ret < 0)
return ret;
- dev->power.pq_req = req;
- ret = pm_qos_sysfs_add(dev);
+ dev->power.qos->latency_req = req;
+ ret = pm_qos_sysfs_add_latency(dev);
if (ret)
- __dev_pm_qos_drop_user_request(dev);
+ __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);
return ret;
}
@@ -504,10 +613,92 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit);
*/
void dev_pm_qos_hide_latency_limit(struct device *dev)
{
- if (dev->power.pq_req) {
- pm_qos_sysfs_remove(dev);
- __dev_pm_qos_drop_user_request(dev);
+ if (dev->power.qos && dev->power.qos->latency_req) {
+ pm_qos_sysfs_remove_latency(dev);
+ __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);
}
}
EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit);
+
+/**
+ * dev_pm_qos_expose_flags - Expose PM QoS flags of a device to user space.
+ * @dev: Device whose PM QoS flags are to be exposed to user space.
+ * @val: Initial values of the flags.
+ */
+int dev_pm_qos_expose_flags(struct device *dev, s32 val)
+{
+ struct dev_pm_qos_request *req;
+ int ret;
+
+ if (!device_is_registered(dev))
+ return -EINVAL;
+
+ if (dev->power.qos && dev->power.qos->flags_req)
+ return -EEXIST;
+
+ req = kzalloc(sizeof(*req), GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ pm_runtime_get_sync(dev);
+ ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_FLAGS, val);
+ if (ret < 0)
+ goto fail;
+
+ dev->power.qos->flags_req = req;
+ ret = pm_qos_sysfs_add_flags(dev);
+ if (ret)
+ __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);
+
+fail:
+ pm_runtime_put(dev);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_qos_expose_flags);
+
+/**
+ * dev_pm_qos_hide_flags - Hide PM QoS flags of a device from user space.
+ * @dev: Device whose PM QoS flags are to be hidden from user space.
+ */
+void dev_pm_qos_hide_flags(struct device *dev)
+{
+ if (dev->power.qos && dev->power.qos->flags_req) {
+ pm_qos_sysfs_remove_flags(dev);
+ pm_runtime_get_sync(dev);
+ __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);
+ pm_runtime_put(dev);
+ }
+}
+EXPORT_SYMBOL_GPL(dev_pm_qos_hide_flags);
+
+/**
+ * dev_pm_qos_update_flags - Update PM QoS flags request owned by user space.
+ * @dev: Device to update the PM QoS flags request for.
+ * @mask: Flags to set/clear.
+ * @set: Whether to set or clear the flags (true means set).
+ */
+int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set)
+{
+ s32 value;
+ int ret;
+
+ if (!dev->power.qos || !dev->power.qos->flags_req)
+ return -EINVAL;
+
+ pm_runtime_get_sync(dev);
+ mutex_lock(&dev_pm_qos_mtx);
+
+ value = dev_pm_qos_requested_flags(dev);
+ if (set)
+ value |= mask;
+ else
+ value &= ~mask;
+
+ ret = __dev_pm_qos_update_request(dev->power.qos->flags_req, value);
+
+ mutex_unlock(&dev_pm_qos_mtx);
+ pm_runtime_put(dev);
+
+ return ret;
+}
#endif /* CONFIG_PM_RUNTIME */
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index b91dc6f1e91..50d16e3cb0a 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -221,7 +221,7 @@ static DEVICE_ATTR(autosuspend_delay_ms, 0644, autosuspend_delay_ms_show,
static ssize_t pm_qos_latency_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", dev->power.pq_req->node.prio);
+ return sprintf(buf, "%d\n", dev_pm_qos_requested_latency(dev));
}
static ssize_t pm_qos_latency_store(struct device *dev,
@@ -237,12 +237,66 @@ static ssize_t pm_qos_latency_store(struct device *dev,
if (value < 0)
return -EINVAL;
- ret = dev_pm_qos_update_request(dev->power.pq_req, value);
+ ret = dev_pm_qos_update_request(dev->power.qos->latency_req, value);
return ret < 0 ? ret : n;
}
static DEVICE_ATTR(pm_qos_resume_latency_us, 0644,
pm_qos_latency_show, pm_qos_latency_store);
+
+static ssize_t pm_qos_no_power_off_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", !!(dev_pm_qos_requested_flags(dev)
+ & PM_QOS_FLAG_NO_POWER_OFF));
+}
+
+static ssize_t pm_qos_no_power_off_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t n)
+{
+ int ret;
+
+ if (kstrtoint(buf, 0, &ret))
+ return -EINVAL;
+
+ if (ret != 0 && ret != 1)
+ return -EINVAL;
+
+ ret = dev_pm_qos_update_flags(dev, PM_QOS_FLAG_NO_POWER_OFF, ret);
+ return ret < 0 ? ret : n;
+}
+
+static DEVICE_ATTR(pm_qos_no_power_off, 0644,
+ pm_qos_no_power_off_show, pm_qos_no_power_off_store);
+
+static ssize_t pm_qos_remote_wakeup_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", !!(dev_pm_qos_requested_flags(dev)
+ & PM_QOS_FLAG_REMOTE_WAKEUP));
+}
+
+static ssize_t pm_qos_remote_wakeup_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t n)
+{
+ int ret;
+
+ if (kstrtoint(buf, 0, &ret))
+ return -EINVAL;
+
+ if (ret != 0 && ret != 1)
+ return -EINVAL;
+
+ ret = dev_pm_qos_update_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP, ret);
+ return ret < 0 ? ret : n;
+}
+
+static DEVICE_ATTR(pm_qos_remote_wakeup, 0644,
+ pm_qos_remote_wakeup_show, pm_qos_remote_wakeup_store);
#endif /* CONFIG_PM_RUNTIME */
#ifdef CONFIG_PM_SLEEP
@@ -564,15 +618,27 @@ static struct attribute_group pm_runtime_attr_group = {
.attrs = runtime_attrs,
};
-static struct attribute *pm_qos_attrs[] = {
+static struct attribute *pm_qos_latency_attrs[] = {
#ifdef CONFIG_PM_RUNTIME
&dev_attr_pm_qos_resume_latency_us.attr,
#endif /* CONFIG_PM_RUNTIME */
NULL,
};
-static struct attribute_group pm_qos_attr_group = {
+static struct attribute_group pm_qos_latency_attr_group = {
.name = power_group_name,
- .attrs = pm_qos_attrs,
+ .attrs = pm_qos_latency_attrs,
+};
+
+static struct attribute *pm_qos_flags_attrs[] = {
+#ifdef CONFIG_PM_RUNTIME
+ &dev_attr_pm_qos_no_power_off.attr,
+ &dev_attr_pm_qos_remote_wakeup.attr,
+#endif /* CONFIG_PM_RUNTIME */
+ NULL,
+};
+static struct attribute_group pm_qos_flags_attr_group = {
+ .name = power_group_name,
+ .attrs = pm_qos_flags_attrs,
};
int dpm_sysfs_add(struct device *dev)
@@ -615,14 +681,24 @@ void wakeup_sysfs_remove(struct device *dev)
sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group);
}
-int pm_qos_sysfs_add(struct device *dev)
+int pm_qos_sysfs_add_latency(struct device *dev)
+{
+ return sysfs_merge_group(&dev->kobj, &pm_qos_latency_attr_group);
+}
+
+void pm_qos_sysfs_remove_latency(struct device *dev)
+{
+ sysfs_unmerge_group(&dev->kobj, &pm_qos_latency_attr_group);
+}
+
+int pm_qos_sysfs_add_flags(struct device *dev)
{
- return sysfs_merge_group(&dev->kobj, &pm_qos_attr_group);
+ return sysfs_merge_group(&dev->kobj, &pm_qos_flags_attr_group);
}
-void pm_qos_sysfs_remove(struct device *dev)
+void pm_qos_sysfs_remove_flags(struct device *dev)
{
- sysfs_unmerge_group(&dev->kobj, &pm_qos_attr_group);
+ sysfs_unmerge_group(&dev->kobj, &pm_qos_flags_attr_group);
}
void rpm_sysfs_remove(struct device *dev)
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 3804a0af3ef..9fe4f186555 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -935,7 +935,7 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail)
/* cf. http://lkml.org/lkml/2006/10/31/28 */
if (!fastfail)
- q->request_fn(q);
+ __blk_run_queue(q);
}
static void
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 1c49d717396..2ddd64a9ffd 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4330,6 +4330,7 @@ out_unreg_region:
out_unreg_blkdev:
unregister_blkdev(FLOPPY_MAJOR, "fd");
out_put_disk:
+ destroy_workqueue(floppy_wq);
for (drive = 0; drive < N_DRIVE; drive++) {
if (!disks[drive])
break;
@@ -4340,7 +4341,6 @@ out_put_disk:
}
put_disk(disks[drive]);
}
- destroy_workqueue(floppy_wq);
return err;
}
@@ -4555,6 +4555,8 @@ static void __exit floppy_module_exit(void)
unregister_blkdev(FLOPPY_MAJOR, "fd");
platform_driver_unregister(&floppy_driver);
+ destroy_workqueue(floppy_wq);
+
for (drive = 0; drive < N_DRIVE; drive++) {
del_timer_sync(&motor_off_timer[drive]);
@@ -4578,7 +4580,6 @@ static void __exit floppy_module_exit(void)
cancel_delayed_work_sync(&fd_timeout);
cancel_delayed_work_sync(&fd_timer);
- destroy_workqueue(floppy_wq);
if (atomic_read(&usage_count))
floppy_release_irq_and_dma();
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index adc6f36564c..9694dd99bbb 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -559,7 +559,7 @@ static void mtip_timeout_function(unsigned long int data)
struct mtip_cmd *command;
int tag, cmdto_cnt = 0;
unsigned int bit, group;
- unsigned int num_command_slots = port->dd->slot_groups * 32;
+ unsigned int num_command_slots;
unsigned long to, tagaccum[SLOTBITS_IN_LONGS];
if (unlikely(!port))
@@ -572,6 +572,7 @@ static void mtip_timeout_function(unsigned long int data)
}
/* clear the tag accumulator */
memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
+ num_command_slots = port->dd->slot_groups * 32;
for (tag = 0; tag < num_command_slots; tag++) {
/*
@@ -2218,8 +2219,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
fis.device);
/* check for erase mode support during secure erase.*/
- if ((fis.command == ATA_CMD_SEC_ERASE_UNIT)
- && (outbuf[0] & MTIP_SEC_ERASE_MODE)) {
+ if ((fis.command == ATA_CMD_SEC_ERASE_UNIT) && outbuf &&
+ (outbuf[0] & MTIP_SEC_ERASE_MODE)) {
erasemode = 1;
}
@@ -2439,7 +2440,7 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd,
* return value
* None
*/
-static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
+static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector,
int nsect, int nents, int tag, void *callback,
void *data, int dir)
{
@@ -2447,6 +2448,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
struct mtip_port *port = dd->port;
struct mtip_cmd *command = &port->commands[tag];
int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+ u64 start = sector;
/* Map the scatter list for DMA access */
nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir);
@@ -2465,8 +2467,12 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
fis->opts = 1 << 7;
fis->command =
(dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE);
- *((unsigned int *) &fis->lba_low) = (start & 0xFFFFFF);
- *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xFFFFFF);
+ fis->lba_low = start & 0xFF;
+ fis->lba_mid = (start >> 8) & 0xFF;
+ fis->lba_hi = (start >> 16) & 0xFF;
+ fis->lba_low_ex = (start >> 24) & 0xFF;
+ fis->lba_mid_ex = (start >> 32) & 0xFF;
+ fis->lba_hi_ex = (start >> 40) & 0xFF;
fis->device = 1 << 6;
fis->features = nsect & 0xFF;
fis->features_ex = (nsect >> 8) & 0xFF;
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h
index 5f4a917bd8b..b1742640556 100644
--- a/drivers/block/mtip32xx/mtip32xx.h
+++ b/drivers/block/mtip32xx/mtip32xx.h
@@ -34,7 +34,7 @@
#define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48
/* check for erase mode support during secure erase */
-#define MTIP_SEC_ERASE_MODE 0x3
+#define MTIP_SEC_ERASE_MODE 0x2
/* # of times to retry timed out/failed IOs */
#define MTIP_MAX_RETRIES 2
@@ -155,14 +155,14 @@ enum {
MTIP_DDF_REBUILD_FAILED_BIT = 8,
};
-__packed struct smart_attr{
+struct smart_attr {
u8 attr_id;
u16 flags;
u8 cur;
u8 worst;
u32 data;
u8 res[3];
-};
+} __packed;
/* Register Frame Information Structure (FIS), host to device. */
struct host_to_dev_fis {
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index fc2de5528dc..b00000e8aef 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -67,6 +67,7 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x13d3, 0x3304) },
{ USB_DEVICE(0x0930, 0x0215) },
{ USB_DEVICE(0x0489, 0xE03D) },
+ { USB_DEVICE(0x0489, 0xE027) },
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03F0, 0x311D) },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index debda27df9b..ee82f2fb65f 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -124,6 +124,7 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE },
+ { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE },
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index c8abce3d2d9..ed0fade46ae 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -270,15 +270,10 @@ static int hci_uart_send_frame(struct sk_buff *skb)
*/
static int hci_uart_tty_open(struct tty_struct *tty)
{
- struct hci_uart *hu = (void *) tty->disc_data;
+ struct hci_uart *hu;
BT_DBG("tty %p", tty);
- /* FIXME: This btw is bogus, nothing requires the old ldisc to clear
- the pointer */
- if (hu)
- return -EEXIST;
-
/* Error if the tty has no write op instead of leaving an exploitable
hole */
if (tty->ops->write == NULL)
diff --git a/drivers/bus/omap-ocp2scp.c b/drivers/bus/omap-ocp2scp.c
index ff63560b846..0c48b0e05ed 100644
--- a/drivers/bus/omap-ocp2scp.c
+++ b/drivers/bus/omap-ocp2scp.c
@@ -22,6 +22,26 @@
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/platform_data/omap_ocp2scp.h>
+
+/**
+ * _count_resources - count for the number of resources
+ * @res: struct resource *
+ *
+ * Count and return the number of resources populated for the device that is
+ * connected to ocp2scp.
+ */
+static unsigned _count_resources(struct resource *res)
+{
+ int cnt = 0;
+
+ while (res->start != res->end) {
+ cnt++;
+ res++;
+ }
+
+ return cnt;
+}
static int ocp2scp_remove_devices(struct device *dev, void *c)
{
@@ -34,20 +54,62 @@ static int ocp2scp_remove_devices(struct device *dev, void *c)
static int __devinit omap_ocp2scp_probe(struct platform_device *pdev)
{
- int ret;
- struct device_node *np = pdev->dev.of_node;
+ int ret;
+ unsigned res_cnt, i;
+ struct device_node *np = pdev->dev.of_node;
+ struct platform_device *pdev_child;
+ struct omap_ocp2scp_platform_data *pdata = pdev->dev.platform_data;
+ struct omap_ocp2scp_dev *dev;
if (np) {
ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
if (ret) {
- dev_err(&pdev->dev, "failed to add resources for ocp2scp child\n");
+ dev_err(&pdev->dev,
+ "failed to add resources for ocp2scp child\n");
goto err0;
}
+ } else if (pdata) {
+ for (i = 0, dev = *pdata->devices; i < pdata->dev_cnt; i++,
+ dev++) {
+ res_cnt = _count_resources(dev->res);
+
+ pdev_child = platform_device_alloc(dev->drv_name,
+ PLATFORM_DEVID_AUTO);
+ if (!pdev_child) {
+ dev_err(&pdev->dev,
+ "failed to allocate mem for ocp2scp child\n");
+ goto err0;
+ }
+
+ ret = platform_device_add_resources(pdev_child,
+ dev->res, res_cnt);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to add resources for ocp2scp child\n");
+ goto err1;
+ }
+
+ pdev_child->dev.parent = &pdev->dev;
+
+ ret = platform_device_add(pdev_child);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to register ocp2scp child device\n");
+ goto err1;
+ }
+ }
+ } else {
+ dev_err(&pdev->dev, "OCP2SCP initialized without plat data\n");
+ return -EINVAL;
}
+
pm_runtime_enable(&pdev->dev);
return 0;
+err1:
+ platform_device_put(pdev_child);
+
err0:
device_for_each_child(&pdev->dev, NULL, ocp2scp_remove_devices);
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index fd793519ea2..478493543b3 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -249,7 +249,7 @@ static const struct agp_bridge_driver ali_m1541_bridge = {
};
-static struct agp_device_ids ali_agp_device_ids[] __devinitdata =
+static struct agp_device_ids ali_agp_device_ids[] =
{
{
.device_id = PCI_DEVICE_ID_AL_M1541,
@@ -374,7 +374,7 @@ found:
return agp_add_bridge(bridge);
}
-static void __devexit agp_ali_remove(struct pci_dev *pdev)
+static void agp_ali_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index f7e88787af9..1b2101160e9 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -388,7 +388,7 @@ static const struct agp_bridge_driver amd_irongate_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_device_ids amd_agp_device_ids[] __devinitdata =
+static struct agp_device_ids amd_agp_device_ids[] =
{
{
.device_id = PCI_DEVICE_ID_AMD_FE_GATE_7006,
@@ -480,7 +480,7 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev,
return agp_add_bridge(bridge);
}
-static void __devexit agp_amdk7_remove(struct pci_dev *pdev)
+static void agp_amdk7_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 444f8b6ab41..061d46209b1 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -579,7 +579,7 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev,
return 0;
}
-static void __devexit agp_amd64_remove(struct pci_dev *pdev)
+static void agp_amd64_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index dc30e224349..ed0433576e7 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -445,7 +445,7 @@ static const struct agp_bridge_driver ati_generic_bridge = {
};
-static struct agp_device_ids ati_agp_device_ids[] __devinitdata =
+static struct agp_device_ids ati_agp_device_ids[] =
{
{
.device_id = PCI_DEVICE_ID_ATI_RS100,
@@ -533,7 +533,7 @@ found:
return agp_add_bridge(bridge);
}
-static void __devexit agp_ati_remove(struct pci_dev *pdev)
+static void agp_ati_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index d607f53d8af..55f3e33a309 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -407,7 +407,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev,
return agp_add_bridge(bridge);
}
-static void __devexit agp_efficeon_remove(struct pci_dev *pdev)
+static void agp_efficeon_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 75b763cb3ea..d328b662e50 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -611,7 +611,7 @@ static int __devinit agp_intel_i460_probe(struct pci_dev *pdev,
return agp_add_bridge(bridge);
}
-static void __devexit agp_intel_i460_remove(struct pci_dev *pdev)
+static void agp_intel_i460_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index b130df0a195..f3a8f52b5a0 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -819,7 +819,7 @@ found_gmch:
return err;
}
-static void __devexit agp_intel_remove(struct pci_dev *pdev)
+static void agp_intel_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index b9734a97818..66e0868000f 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -388,7 +388,7 @@ static int __devinit agp_nvidia_probe(struct pci_dev *pdev,
return agp_add_bridge(bridge);
}
-static void __devexit agp_nvidia_remove(struct pci_dev *pdev)
+static void agp_nvidia_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index 3a5af2f9b01..a18791d7718 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -327,7 +327,7 @@ static int __devinit agp_sgi_init(void)
return 0;
}
-static void __devexit agp_sgi_cleanup(void)
+static void agp_sgi_cleanup(void)
{
kfree(sgi_tioca_agp_bridges);
sgi_tioca_agp_bridges = NULL;
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index 08704ae5395..93d1d31f9d0 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -17,8 +17,8 @@
#define PCI_DEVICE_ID_SI_662 0x0662
#define PCI_DEVICE_ID_SI_671 0x0671
-static bool __devinitdata agp_sis_force_delay = 0;
-static int __devinitdata agp_sis_agp_spec = -1;
+static bool agp_sis_force_delay = 0;
+static int agp_sis_agp_spec = -1;
static int sis_fetch_size(void)
{
@@ -148,7 +148,7 @@ static struct agp_bridge_driver sis_driver = {
};
// chipsets that require the 'delay hack'
-static int sis_broken_chipsets[] __devinitdata = {
+static int sis_broken_chipsets[] = {
PCI_DEVICE_ID_SI_648,
PCI_DEVICE_ID_SI_746,
0 // terminator
@@ -211,7 +211,7 @@ static int __devinit agp_sis_probe(struct pci_dev *pdev,
return agp_add_bridge(bridge);
}
-static void __devexit agp_sis_remove(struct pci_dev *pdev)
+static void agp_sis_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index f02f9b07fd4..26020fb8d7a 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -518,7 +518,7 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev,
return agp_add_bridge(bridge);
}
-static void __devexit agp_serverworks_remove(struct pci_dev *pdev)
+static void agp_serverworks_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index a32c492baf5..011967ad3ee 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -557,7 +557,7 @@ const struct agp_bridge_driver u3_agp_driver = {
.needs_scratch_page = true,
};
-static struct agp_device_ids uninorth_agp_device_ids[] __devinitdata = {
+static struct agp_device_ids uninorth_agp_device_ids[] = {
{
.device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP,
.chipset_name = "UniNorth",
@@ -663,7 +663,7 @@ static int __devinit agp_uninorth_probe(struct pci_dev *pdev,
return agp_add_bridge(bridge);
}
-static void __devexit agp_uninorth_remove(struct pci_dev *pdev)
+static void agp_uninorth_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index 8bc38493740..6818595bb86 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -224,7 +224,7 @@ static const struct agp_bridge_driver via_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_device_ids via_agp_device_ids[] __devinitdata =
+static struct agp_device_ids via_agp_device_ids[] =
{
{
.device_id = PCI_DEVICE_ID_VIA_82C597_0,
@@ -485,7 +485,7 @@ static int __devinit agp_via_probe(struct pci_dev *pdev,
return agp_add_bridge(bridge);
}
-static void __devexit agp_via_remove(struct pci_dev *pdev)
+static void agp_via_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index dfd7876f127..fe6d4be4829 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -816,7 +816,7 @@ static unsigned long __hpet_calibrate(struct hpets *hpetp)
static unsigned long hpet_calibrate(struct hpets *hpetp)
{
- unsigned long ret = -1;
+ unsigned long ret = ~0UL;
unsigned long tmp;
/*
@@ -1001,6 +1001,9 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
irqp = &res->data.extended_irq;
for (i = 0; i < irqp->interrupt_count; i++) {
+ if (hdp->hd_nirqs >= HPET_MAX_TIMERS)
+ break;
+
irq = acpi_register_gsi(NULL, irqp->interrupts[i],
irqp->triggering, irqp->polarity);
if (irq < 0)
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index fbd9b2b850e..c58ea9b80b1 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -127,12 +127,12 @@ config HW_RANDOM_VIA
If unsure, say Y.
config HW_RANDOM_IXP4XX
- tristate "Intel IXP4xx NPU HW Random Number Generator support"
+ tristate "Intel IXP4xx NPU HW Pseudo-Random Number Generator support"
depends on HW_RANDOM && ARCH_IXP4XX
default HW_RANDOM
---help---
- This driver provides kernel-side support for the Random
- Number Generator hardware found on the Intel IXP4xx NPU.
+ This driver provides kernel-side support for the Pseudo-Random
+ Number Generator hardware found on the Intel IXP45x/46x NPU.
To compile this driver as a module, choose M here: the
module will be called ixp4xx-rng.
diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c
index 731c9046cf7..5a4a6e70478 100644
--- a/drivers/char/hw_random/atmel-rng.c
+++ b/drivers/char/hw_random/atmel-rng.c
@@ -98,7 +98,7 @@ err_enable:
return ret;
}
-static int __devexit atmel_trng_remove(struct platform_device *pdev)
+static int atmel_trng_remove(struct platform_device *pdev)
{
struct atmel_trng *trng = platform_get_drvdata(pdev);
diff --git a/drivers/char/hw_random/bcm63xx-rng.c b/drivers/char/hw_random/bcm63xx-rng.c
index aec6a4277ca..ae95bcb18d4 100644
--- a/drivers/char/hw_random/bcm63xx-rng.c
+++ b/drivers/char/hw_random/bcm63xx-rng.c
@@ -145,7 +145,7 @@ out:
return ret;
}
-static int __devexit bcm63xx_rng_remove(struct platform_device *pdev)
+static int bcm63xx_rng_remove(struct platform_device *pdev)
{
struct hwrng *rng = platform_get_drvdata(pdev);
struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
diff --git a/drivers/char/hw_random/exynos-rng.c b/drivers/char/hw_random/exynos-rng.c
index 232ba9ce579..bdc852ea763 100644
--- a/drivers/char/hw_random/exynos-rng.c
+++ b/drivers/char/hw_random/exynos-rng.c
@@ -134,7 +134,7 @@ static int __devinit exynos_rng_probe(struct platform_device *pdev)
return hwrng_register(&exynos_rng->rng);
}
-static int __devexit exynos_rng_remove(struct platform_device *pdev)
+static int exynos_rng_remove(struct platform_device *pdev)
{
struct exynos_rng *exynos_rng = platform_get_drvdata(pdev);
diff --git a/drivers/char/hw_random/ixp4xx-rng.c b/drivers/char/hw_random/ixp4xx-rng.c
index 263567f5f39..beec1627db3 100644
--- a/drivers/char/hw_random/ixp4xx-rng.c
+++ b/drivers/char/hw_random/ixp4xx-rng.c
@@ -45,6 +45,9 @@ static int __init ixp4xx_rng_init(void)
void __iomem * rng_base;
int err;
+ if (!cpu_is_ixp46x()) /* includes IXP455 */
+ return -ENOSYS;
+
rng_base = ioremap(0x70002100, 4);
if (!rng_base)
return -ENOMEM;
@@ -68,5 +71,5 @@ module_init(ixp4xx_rng_init);
module_exit(ixp4xx_rng_exit);
MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
-MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for IXP4xx");
+MODULE_DESCRIPTION("H/W Pseudo-Random Number Generator (RNG) driver for IXP45x/46x");
MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c
index ebd48f0135d..d68a72a08b5 100644
--- a/drivers/char/hw_random/n2-drv.c
+++ b/drivers/char/hw_random/n2-drv.c
@@ -25,7 +25,7 @@
#define DRV_MODULE_VERSION "0.2"
#define DRV_MODULE_RELDATE "July 27, 2011"
-static char version[] __devinitdata =
+static char version[] =
DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
@@ -719,7 +719,7 @@ out:
return err;
}
-static int __devexit n2rng_remove(struct platform_device *op)
+static int n2rng_remove(struct platform_device *op)
{
struct n2rng *np = dev_get_drvdata(&op->dev);
diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c
index 3a632673aed..a1f70407cc9 100644
--- a/drivers/char/hw_random/pasemi-rng.c
+++ b/drivers/char/hw_random/pasemi-rng.c
@@ -122,7 +122,7 @@ static int __devinit rng_probe(struct platform_device *ofdev)
return err;
}
-static int __devexit rng_remove(struct platform_device *dev)
+static int rng_remove(struct platform_device *dev)
{
void __iomem *rng_regs = (void __iomem *)pasemi_rng.priv;
diff --git a/drivers/char/hw_random/picoxcell-rng.c b/drivers/char/hw_random/picoxcell-rng.c
index 97bd891422c..d4b24c1dd48 100644
--- a/drivers/char/hw_random/picoxcell-rng.c
+++ b/drivers/char/hw_random/picoxcell-rng.c
@@ -151,7 +151,7 @@ err_enable:
return ret;
}
-static int __devexit picoxcell_trng_remove(struct platform_device *pdev)
+static int picoxcell_trng_remove(struct platform_device *pdev)
{
hwrng_unregister(&picoxcell_trng);
clk_disable(rng_clk);
diff --git a/drivers/char/hw_random/ppc4xx-rng.c b/drivers/char/hw_random/ppc4xx-rng.c
index c51762c1303..af6506a69cd 100644
--- a/drivers/char/hw_random/ppc4xx-rng.c
+++ b/drivers/char/hw_random/ppc4xx-rng.c
@@ -111,7 +111,7 @@ static int __devinit ppc4xx_rng_probe(struct platform_device *dev)
return err;
}
-static int __devexit ppc4xx_rng_remove(struct platform_device *dev)
+static int ppc4xx_rng_remove(struct platform_device *dev)
{
void __iomem *rng_regs = (void __iomem *) ppc4xx_rng.priv;
diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c
index f1a1618db1f..3a1abc9417e 100644
--- a/drivers/char/hw_random/timeriomem-rng.c
+++ b/drivers/char/hw_random/timeriomem-rng.c
@@ -130,7 +130,7 @@ failed:
return ret;
}
-static int __devexit timeriomem_rng_remove(struct platform_device *pdev)
+static int timeriomem_rng_remove(struct platform_device *pdev)
{
del_timer_sync(&timeriomem_rng_timer);
hwrng_unregister(&timeriomem_rng_ops);
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index 5708299507d..621f595f1a9 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -119,7 +119,7 @@ static int virtrng_probe(struct virtio_device *vdev)
return probe_common(vdev);
}
-static void __devexit virtrng_remove(struct virtio_device *vdev)
+static void virtrng_remove(struct virtio_device *vdev)
{
remove_common(vdev);
}
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 32a6c7e256b..20ab5b3a891 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1836,7 +1836,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
return rv;
}
-static int __devinit hardcode_find_bmc(void)
+static int hardcode_find_bmc(void)
{
int ret = -ENODEV;
int i;
@@ -2023,7 +2023,7 @@ struct SPMITable {
s8 spmi_id[1]; /* A '\0' terminated array starts here. */
};
-static int __devinit try_init_spmi(struct SPMITable *spmi)
+static int try_init_spmi(struct SPMITable *spmi)
{
struct smi_info *info;
@@ -2106,7 +2106,7 @@ static int __devinit try_init_spmi(struct SPMITable *spmi)
return 0;
}
-static void __devinit spmi_find_bmc(void)
+static void spmi_find_bmc(void)
{
acpi_status status;
struct SPMITable *spmi;
@@ -2128,7 +2128,7 @@ static void __devinit spmi_find_bmc(void)
}
}
-static int __devinit ipmi_pnp_probe(struct pnp_dev *dev,
+static int ipmi_pnp_probe(struct pnp_dev *dev,
const struct pnp_device_id *dev_id)
{
struct acpi_device *acpi_dev;
@@ -2228,7 +2228,7 @@ err_free:
return -EINVAL;
}
-static void __devexit ipmi_pnp_remove(struct pnp_dev *dev)
+static void ipmi_pnp_remove(struct pnp_dev *dev)
{
struct smi_info *info = pnp_get_drvdata(dev);
@@ -2258,7 +2258,7 @@ struct dmi_ipmi_data {
u8 slave_addr;
};
-static int __devinit decode_dmi(const struct dmi_header *dm,
+static int decode_dmi(const struct dmi_header *dm,
struct dmi_ipmi_data *dmi)
{
const u8 *data = (const u8 *)dm;
@@ -2320,7 +2320,7 @@ static int __devinit decode_dmi(const struct dmi_header *dm,
return 0;
}
-static void __devinit try_init_dmi(struct dmi_ipmi_data *ipmi_data)
+static void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
{
struct smi_info *info;
@@ -2388,7 +2388,7 @@ static void __devinit try_init_dmi(struct dmi_ipmi_data *ipmi_data)
kfree(info);
}
-static void __devinit dmi_find_bmc(void)
+static void dmi_find_bmc(void)
{
const struct dmi_device *dev = NULL;
struct dmi_ipmi_data data;
@@ -2424,7 +2424,7 @@ static void ipmi_pci_cleanup(struct smi_info *info)
pci_disable_device(pdev);
}
-static int __devinit ipmi_pci_probe_regspacing(struct smi_info *info)
+static int ipmi_pci_probe_regspacing(struct smi_info *info)
{
if (info->si_type == SI_KCS) {
unsigned char status;
@@ -2456,7 +2456,7 @@ static int __devinit ipmi_pci_probe_regspacing(struct smi_info *info)
return DEFAULT_REGSPACING;
}
-static int __devinit ipmi_pci_probe(struct pci_dev *pdev,
+static int ipmi_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
int rv;
@@ -2529,7 +2529,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev,
return 0;
}
-static void __devexit ipmi_pci_remove(struct pci_dev *pdev)
+static void ipmi_pci_remove(struct pci_dev *pdev)
{
struct smi_info *info = pci_get_drvdata(pdev);
cleanup_one_si(info);
@@ -2551,7 +2551,7 @@ static struct pci_driver ipmi_pci_driver = {
#endif /* CONFIG_PCI */
static struct of_device_id ipmi_match[];
-static int __devinit ipmi_probe(struct platform_device *dev)
+static int ipmi_probe(struct platform_device *dev)
{
#ifdef CONFIG_OF
const struct of_device_id *match;
@@ -2635,7 +2635,7 @@ static int __devinit ipmi_probe(struct platform_device *dev)
return 0;
}
-static int __devexit ipmi_remove(struct platform_device *dev)
+static int ipmi_remove(struct platform_device *dev)
{
#ifdef CONFIG_OF
cleanup_one_si(dev_get_drvdata(&dev->dev));
@@ -3047,7 +3047,7 @@ static inline void wait_for_timer_and_thread(struct smi_info *smi_info)
}
}
-static __devinitdata struct ipmi_default_vals
+static struct ipmi_default_vals
{
int type;
int port;
@@ -3059,7 +3059,7 @@ static __devinitdata struct ipmi_default_vals
{ .port = 0 }
};
-static void __devinit default_find_bmc(void)
+static void default_find_bmc(void)
{
struct smi_info *info;
int i;
@@ -3359,7 +3359,7 @@ static int try_smi_init(struct smi_info *new_smi)
return rv;
}
-static int __devinit init_ipmi_si(void)
+static int init_ipmi_si(void)
{
int i;
char *str;
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index f74e892711d..e5d3e3f7a49 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -799,7 +799,7 @@ static int mbcs_remove(struct cx_dev *dev)
return 0;
}
-static const struct cx_device_id __devinitconst mbcs_id_table[] = {
+static const struct cx_device_id mbcs_id_table[] = {
{
.part_num = MBCS_PART_NUM,
.mfg_num = MBCS_MFG_NUM,
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 0537903c985..c6fa3bc2baa 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -48,7 +48,7 @@ static inline unsigned long size_inside_page(unsigned long start,
}
#ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE
-static inline int valid_phys_addr_range(unsigned long addr, size_t count)
+static inline int valid_phys_addr_range(phys_addr_t addr, size_t count)
{
return addr + count <= __pa(high_memory);
}
@@ -96,7 +96,7 @@ void __weak unxlate_dev_mem_ptr(unsigned long phys, void *addr)
static ssize_t read_mem(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- unsigned long p = *ppos;
+ phys_addr_t p = *ppos;
ssize_t read, sz;
char *ptr;
@@ -153,7 +153,7 @@ static ssize_t read_mem(struct file *file, char __user *buf,
static ssize_t write_mem(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
- unsigned long p = *ppos;
+ phys_addr_t p = *ppos;
ssize_t written, sz;
unsigned long copied;
void *ptr;
@@ -226,7 +226,7 @@ int __weak phys_mem_access_prot_allowed(struct file *file,
*
*/
#ifdef pgprot_noncached
-static int uncached_access(struct file *file, unsigned long addr)
+static int uncached_access(struct file *file, phys_addr_t addr)
{
#if defined(CONFIG_IA64)
/*
@@ -258,7 +258,7 @@ static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot)
{
#ifdef pgprot_noncached
- unsigned long offset = pfn << PAGE_SHIFT;
+ phys_addr_t offset = pfn << PAGE_SHIFT;
if (uncached_access(file, offset))
return pgprot_noncached(vma_prot);
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c
index b304ec05250..3f79a9fb6b1 100644
--- a/drivers/char/pc8736x_gpio.c
+++ b/drivers/char/pc8736x_gpio.c
@@ -345,8 +345,7 @@ static void __exit pc8736x_gpio_cleanup(void)
unregister_chrdev_region(MKDEV(major,0), PC8736X_GPIO_CT);
release_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE);
- platform_device_del(pdev);
- platform_device_put(pdev);
+ platform_device_unregister(pdev);
}
module_init(pc8736x_gpio_init);
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 21721d25e38..b66eaa04f8c 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -549,8 +549,10 @@ static int mgslpc_probe(struct pcmcia_device *link)
/* Initialize the struct pcmcia_device structure */
ret = mgslpc_config(link);
- if (ret)
+ if (ret) {
+ tty_port_destroy(&info->port);
return ret;
+ }
mgslpc_add_device(info);
@@ -2757,6 +2759,7 @@ static void mgslpc_remove_device(MGSLPC_INFO *remove_info)
hdlcdev_exit(info);
#endif
release_resources(info);
+ tty_port_destroy(&info->port);
kfree(info);
mgslpc_device_count--;
return;
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
index 6abdde4da2b..588063ac951 100644
--- a/drivers/char/ps3flash.c
+++ b/drivers/char/ps3flash.c
@@ -363,7 +363,7 @@ static struct miscdevice ps3flash_misc = {
.fops = &ps3flash_fops,
};
-static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev)
+static int ps3flash_probe(struct ps3_system_bus_device *_dev)
{
struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
struct ps3flash_private *priv;
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 0bb207eaef2..54a3a6d0981 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -285,7 +285,7 @@ static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd,
static const struct file_operations raw_fops = {
.read = do_sync_read,
- .aio_read = blkdev_aio_read,
+ .aio_read = generic_file_aio_read,
.write = do_sync_write,
.aio_write = blkdev_aio_write,
.fsync = blkdev_fsync,
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 9b4f0116ff2..d780295a147 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -1164,7 +1164,7 @@ static struct acpi_driver sonypi_acpi_driver = {
};
#endif
-static int __devinit sonypi_create_input_devices(struct platform_device *pdev)
+static int sonypi_create_input_devices(struct platform_device *pdev)
{
struct input_dev *jog_dev;
struct input_dev *key_dev;
@@ -1225,7 +1225,7 @@ static int __devinit sonypi_create_input_devices(struct platform_device *pdev)
return error;
}
-static int __devinit sonypi_setup_ioports(struct sonypi_device *dev,
+static int sonypi_setup_ioports(struct sonypi_device *dev,
const struct sonypi_ioport_list *ioport_list)
{
/* try to detect if sony-laptop is being used and thus
@@ -1265,7 +1265,7 @@ static int __devinit sonypi_setup_ioports(struct sonypi_device *dev,
return -EBUSY;
}
-static int __devinit sonypi_setup_irq(struct sonypi_device *dev,
+static int sonypi_setup_irq(struct sonypi_device *dev,
const struct sonypi_irq_list *irq_list)
{
while (irq_list->irq) {
@@ -1282,7 +1282,7 @@ static int __devinit sonypi_setup_irq(struct sonypi_device *dev,
return -EBUSY;
}
-static void __devinit sonypi_display_info(void)
+static void sonypi_display_info(void)
{
printk(KERN_INFO "sonypi: detected type%d model, "
"verbose = %d, fnkeyinit = %s, camera = %s, "
@@ -1304,7 +1304,7 @@ static void __devinit sonypi_display_info(void)
sonypi_misc_device.minor);
}
-static int __devinit sonypi_probe(struct platform_device *dev)
+static int sonypi_probe(struct platform_device *dev)
{
const struct sonypi_ioport_list *ioport_list;
const struct sonypi_irq_list *irq_list;
@@ -1428,7 +1428,7 @@ static int __devinit sonypi_probe(struct platform_device *dev)
return error;
}
-static int __devexit sonypi_remove(struct platform_device *dev)
+static int sonypi_remove(struct platform_device *dev)
{
sonypi_disable();
@@ -1491,7 +1491,7 @@ static struct platform_driver sonypi_driver = {
.pm = SONYPI_PM,
},
.probe = sonypi_probe,
- .remove = __devexit_p(sonypi_remove),
+ .remove = sonypi_remove,
.shutdown = sonypi_shutdown,
};
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
index ad264185eb1..34c63f85104 100644
--- a/drivers/char/tb0219.c
+++ b/drivers/char/tb0219.c
@@ -284,7 +284,7 @@ static void tb0219_pci_irq_init(void)
vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, IRQ_LEVEL_LOW);
}
-static int __devinit tb0219_probe(struct platform_device *dev)
+static int tb0219_probe(struct platform_device *dev)
{
int retval;
@@ -318,7 +318,7 @@ static int __devinit tb0219_probe(struct platform_device *dev)
return 0;
}
-static int __devexit tb0219_remove(struct platform_device *dev)
+static int tb0219_remove(struct platform_device *dev)
{
_machine_restart = old_machine_restart;
@@ -334,7 +334,7 @@ static struct platform_device *tb0219_platform_device;
static struct platform_driver tb0219_device_driver = {
.probe = tb0219_probe,
- .remove = __devexit_p(tb0219_remove),
+ .remove = tb0219_remove,
.driver = {
.name = "TB0219",
.owner = THIS_MODULE,
diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
index 5a831aec9d4..fb447bd0cb6 100644
--- a/drivers/char/tpm/tpm_i2c_infineon.c
+++ b/drivers/char/tpm/tpm_i2c_infineon.c
@@ -555,7 +555,7 @@ static struct tpm_vendor_specific tpm_tis_i2c = {
.miscdev.fops = &tis_ops,
};
-static int __devinit tpm_tis_i2c_init(struct device *dev)
+static int tpm_tis_i2c_init(struct device *dev)
{
u32 vendor;
int rc = 0;
@@ -632,7 +632,7 @@ static const struct i2c_device_id tpm_tis_i2c_table[] = {
MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_table);
static SIMPLE_DEV_PM_OPS(tpm_tis_i2c_ops, tpm_pm_suspend, tpm_pm_resume);
-static int __devinit tpm_tis_i2c_probe(struct i2c_client *client,
+static int tpm_tis_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int rc;
@@ -656,7 +656,7 @@ static int __devinit tpm_tis_i2c_probe(struct i2c_client *client,
return rc;
}
-static int __devexit tpm_tis_i2c_remove(struct i2c_client *client)
+static int tpm_tis_i2c_remove(struct i2c_client *client)
{
struct tpm_chip *chip = tpm_dev.chip;
release_locality(chip, chip->vendor.locality, 1);
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c
index efc4ab36a9d..7da840d487d 100644
--- a/drivers/char/tpm/tpm_ibmvtpm.c
+++ b/drivers/char/tpm/tpm_ibmvtpm.c
@@ -32,7 +32,7 @@
static const char tpm_ibmvtpm_driver_name[] = "tpm_ibmvtpm";
-static struct vio_device_id tpm_ibmvtpm_device_table[] __devinitdata = {
+static struct vio_device_id tpm_ibmvtpm_device_table[] = {
{ "IBM,vtpm", "IBM,vtpm"},
{ "", "" }
};
@@ -267,7 +267,7 @@ static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm)
* Return value:
* 0
*/
-static int __devexit tpm_ibmvtpm_remove(struct vio_dev *vdev)
+static int tpm_ibmvtpm_remove(struct vio_dev *vdev)
{
struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(&vdev->dev);
int rc = 0;
@@ -602,7 +602,7 @@ static void ibmvtpm_tasklet(void *data)
* 0 - Success
* Non-zero - Failure
*/
-static int __devinit tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
+static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
const struct vio_device_id *id)
{
struct ibmvtpm_dev *ibmvtpm;
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index 3251a44e8ce..2b480c2960b 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -415,7 +415,7 @@ static const struct pnp_device_id tpm_inf_pnp_tbl[] = {
MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl);
-static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
+static int tpm_inf_pnp_probe(struct pnp_dev *dev,
const struct pnp_device_id *dev_id)
{
int rc = 0;
@@ -594,7 +594,7 @@ err_last:
return rc;
}
-static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
+static void tpm_inf_pnp_remove(struct pnp_dev *dev)
{
struct tpm_chip *chip = pnp_get_drvdata(dev);
@@ -655,7 +655,7 @@ static struct pnp_driver tpm_inf_pnp_driver = {
.probe = tpm_inf_pnp_probe,
.suspend = tpm_inf_pnp_suspend,
.resume = tpm_inf_pnp_resume,
- .remove = __devexit_p(tpm_inf_pnp_remove)
+ .remove = tpm_inf_pnp_remove
};
static int __init init_inf(void)
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 6bdf2671254..ea31dafbcac 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -729,7 +729,7 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
#endif
#ifdef CONFIG_PNP
-static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
+static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
const struct pnp_device_id *pnp_id)
{
resource_size_t start, len;
@@ -769,7 +769,7 @@ static int tpm_tis_pnp_resume(struct pnp_dev *dev)
return ret;
}
-static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
+static struct pnp_device_id tpm_pnp_tbl[] = {
{"PNP0C31", 0}, /* TPM */
{"ATM1200", 0}, /* Atmel */
{"IFX0102", 0}, /* Infineon */
@@ -783,7 +783,7 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
};
MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
-static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev)
+static void tpm_tis_pnp_remove(struct pnp_dev *dev)
{
struct tpm_chip *chip = pnp_get_drvdata(dev);
diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c
index af98f6d6509..4945bd3d18d 100644
--- a/drivers/char/ttyprintk.c
+++ b/drivers/char/ttyprintk.c
@@ -179,7 +179,6 @@ static int __init ttyprintk_init(void)
{
int ret = -ENOMEM;
- tty_port_init(&tpk_port.port);
tpk_port.port.ops = &null_ops;
mutex_init(&tpk_port.port_write_mutex);
@@ -190,6 +189,8 @@ static int __init ttyprintk_init(void)
if (IS_ERR(ttyprintk_driver))
return PTR_ERR(ttyprintk_driver);
+ tty_port_init(&tpk_port.port);
+
ttyprintk_driver->driver_name = "ttyprintk";
ttyprintk_driver->name = "ttyprintk";
ttyprintk_driver->major = TTYAUX_MAJOR;
@@ -211,6 +212,7 @@ static int __init ttyprintk_init(void)
error:
tty_unregister_driver(ttyprintk_driver);
put_tty_driver(ttyprintk_driver);
+ tty_port_destroy(&tpk_port.port);
ttyprintk_driver = NULL;
return ret;
}
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 8ab9c3d4bf1..90493d4ead1 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -1846,7 +1846,7 @@ static void remove_controlq_data(struct ports_device *portdev)
* config space to see how many ports the host has spawned. We
* initialize each port found.
*/
-static int __devinit virtcons_probe(struct virtio_device *vdev)
+static int virtcons_probe(struct virtio_device *vdev)
{
struct ports_device *portdev;
int err;
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 2c5d15beea3..5224da5202d 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -595,7 +595,7 @@ static const struct file_operations hwicap_fops = {
.llseek = noop_llseek,
};
-static int __devinit hwicap_setup(struct device *dev, int id,
+static int hwicap_setup(struct device *dev, int id,
const struct resource *regs_res,
const struct hwicap_driver_config *config,
const struct config_registers *config_regs)
@@ -717,7 +717,7 @@ static struct hwicap_driver_config fifo_icap_config = {
.reset = fifo_icap_reset,
};
-static int __devexit hwicap_remove(struct device *dev)
+static int hwicap_remove(struct device *dev)
{
struct hwicap_drvdata *drvdata;
@@ -740,7 +740,7 @@ static int __devexit hwicap_remove(struct device *dev)
}
#ifdef CONFIG_OF
-static int __devinit hwicap_of_probe(struct platform_device *op,
+static int hwicap_of_probe(struct platform_device *op,
const struct hwicap_driver_config *config)
{
struct resource res;
@@ -785,8 +785,8 @@ static inline int hwicap_of_probe(struct platform_device *op,
}
#endif /* CONFIG_OF */
-static const struct of_device_id __devinitconst hwicap_of_match[];
-static int __devinit hwicap_drv_probe(struct platform_device *pdev)
+static const struct of_device_id hwicap_of_match[];
+static int hwicap_drv_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
struct resource *res;
@@ -822,14 +822,14 @@ static int __devinit hwicap_drv_probe(struct platform_device *pdev)
&buffer_icap_config, regs);
}
-static int __devexit hwicap_drv_remove(struct platform_device *pdev)
+static int hwicap_drv_remove(struct platform_device *pdev)
{
return hwicap_remove(&pdev->dev);
}
#ifdef CONFIG_OF
/* Match table for device tree binding */
-static const struct of_device_id __devinitconst hwicap_of_match[] = {
+static const struct of_device_id hwicap_of_match[] = {
{ .compatible = "xlnx,opb-hwicap-1.00.b", .data = &buffer_icap_config},
{ .compatible = "xlnx,xps-hwicap-1.00.a", .data = &fifo_icap_config},
{},
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index bace9e98f75..823f62d900b 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -42,10 +42,12 @@ config COMMON_CLK_WM831X
config COMMON_CLK_VERSATILE
bool "Clock driver for ARM Reference designs"
- depends on ARCH_INTEGRATOR || ARCH_REALVIEW
+ depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS
---help---
- Supports clocking on ARM Reference designs Integrator/AP,
- Integrator/CP, RealView PB1176, EB, PB11MP and PBX.
+ Supports clocking on ARM Reference designs:
+ - Integrator/AP and Integrator/CP
+ - RealView PB1176, EB, PB11MP and PBX
+ - Versatile Express
config COMMON_CLK_MAX77686
tristate "Clock driver for Maxim 77686 MFD"
@@ -53,4 +55,12 @@ config COMMON_CLK_MAX77686
---help---
This driver supports Maxim 77686 crystal oscillator clock.
+config CLK_TWL6040
+ tristate "External McPDM functional clock from twl6040"
+ depends on TWL6040_CORE
+ ---help---
+ Enable the external functional clock support on OMAP4+ platforms for
+ McPDM. McPDM module is using the external bit clock on the McPDM bus
+ as functional clock.
+
endmenu
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 71a25b91de0..2701235d575 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
# Chip specific
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
+obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
diff --git a/drivers/clk/clk-bcm2835.c b/drivers/clk/clk-bcm2835.c
index 67ad16b20b8..b61ee2c5af8 100644
--- a/drivers/clk/clk-bcm2835.c
+++ b/drivers/clk/clk-bcm2835.c
@@ -33,17 +33,17 @@ void __init bcm2835_init_clocks(void)
clk = clk_register_fixed_rate(NULL, "sys_pclk", NULL, CLK_IS_ROOT,
250000000);
- if (!clk)
+ if (IS_ERR(clk))
pr_err("sys_pclk not registered\n");
clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT,
126000000);
- if (!clk)
+ if (IS_ERR(clk))
pr_err("apb_pclk not registered\n");
clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT,
3000000);
- if (!clk)
+ if (IS_ERR(clk))
pr_err("uart0_pclk not registered\n");
ret = clk_register_clkdev(clk, NULL, "20201000.uart");
if (ret)
@@ -51,7 +51,7 @@ void __init bcm2835_init_clocks(void)
clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT,
125000000);
- if (!clk)
+ if (IS_ERR(clk))
pr_err("uart1_pclk not registered\n");
ret = clk_register_clkdev(clk, NULL, "20215000.uart");
if (ret)
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
index f5ec0eebd4d..af78ed6b67e 100644
--- a/drivers/clk/clk-fixed-rate.c
+++ b/drivers/clk/clk-fixed-rate.c
@@ -97,7 +97,7 @@ void __init of_fixed_clk_setup(struct device_node *node)
of_property_read_string(node, "clock-output-names", &clk_name);
clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, rate);
- if (clk)
+ if (!IS_ERR(clk))
of_clk_add_provider(node, of_clk_src_simple_get, clk);
}
EXPORT_SYMBOL_GPL(of_fixed_clk_setup);
diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c
index ac5f5434cb9..d098f72e1d5 100644
--- a/drivers/clk/clk-max77686.c
+++ b/drivers/clk/clk-max77686.c
@@ -143,7 +143,7 @@ static int max77686_clk_register(struct device *dev,
return 0;
}
-static __devinit int max77686_clk_probe(struct platform_device *pdev)
+static int max77686_clk_probe(struct platform_device *pdev)
{
struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct max77686_clk **max77686_clks;
@@ -199,7 +199,7 @@ out:
return ret;
}
-static int __devexit max77686_clk_remove(struct platform_device *pdev)
+static int max77686_clk_remove(struct platform_device *pdev)
{
struct max77686_clk **max77686_clks = platform_get_drvdata(pdev);
int i;
@@ -223,7 +223,7 @@ static struct platform_driver max77686_clk_driver = {
.owner = THIS_MODULE,
},
.probe = max77686_clk_probe,
- .remove = __devexit_p(max77686_clk_remove),
+ .remove = max77686_clk_remove,
.id_table = max77686_clk_id,
};
diff --git a/drivers/clk/clk-prima2.c b/drivers/clk/clk-prima2.c
index 517874fa685..a203ecccdc4 100644
--- a/drivers/clk/clk-prima2.c
+++ b/drivers/clk/clk-prima2.c
@@ -1054,118 +1054,118 @@ void __init sirfsoc_of_clk_init(void)
/* These are always available (RTC and 26MHz OSC)*/
clk = clk_register_fixed_rate(NULL, "rtc", NULL,
CLK_IS_ROOT, 32768);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk = clk_register_fixed_rate(NULL, "osc", NULL,
CLK_IS_ROOT, 26000000);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk = clk_register(NULL, &clk_pll1.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk = clk_register(NULL, &clk_pll2.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk = clk_register(NULL, &clk_pll3.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk = clk_register(NULL, &clk_mem.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk = clk_register(NULL, &clk_sys.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk = clk_register(NULL, &clk_security.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b8030000.security");
clk = clk_register(NULL, &clk_dsp.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk = clk_register(NULL, &clk_gps.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "a8010000.gps");
clk = clk_register(NULL, &clk_mf.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk = clk_register(NULL, &clk_io.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "io");
clk = clk_register(NULL, &clk_cpu.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "cpu");
clk = clk_register(NULL, &clk_uart0.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b0050000.uart");
clk = clk_register(NULL, &clk_uart1.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b0060000.uart");
clk = clk_register(NULL, &clk_uart2.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b0070000.uart");
clk = clk_register(NULL, &clk_tsc.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b0110000.tsc");
clk = clk_register(NULL, &clk_i2c0.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b00e0000.i2c");
clk = clk_register(NULL, &clk_i2c1.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b00f0000.i2c");
clk = clk_register(NULL, &clk_spi0.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b00d0000.spi");
clk = clk_register(NULL, &clk_spi1.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b0170000.spi");
clk = clk_register(NULL, &clk_pwmc.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b0130000.pwm");
clk = clk_register(NULL, &clk_efuse.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b0140000.efusesys");
clk = clk_register(NULL, &clk_pulse.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b0150000.pulsec");
clk = clk_register(NULL, &clk_dmac0.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b00b0000.dma-controller");
clk = clk_register(NULL, &clk_dmac1.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b0160000.dma-controller");
clk = clk_register(NULL, &clk_nand.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b0030000.nand");
clk = clk_register(NULL, &clk_audio.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b0040000.audio");
clk = clk_register(NULL, &clk_usp0.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b0080000.usp");
clk = clk_register(NULL, &clk_usp1.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b0090000.usp");
clk = clk_register(NULL, &clk_usp2.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b00a0000.usp");
clk = clk_register(NULL, &clk_vip.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b00c0000.vip");
clk = clk_register(NULL, &clk_gfx.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "98000000.graphics");
clk = clk_register(NULL, &clk_mm.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "a0000000.multimedia");
clk = clk_register(NULL, &clk_lcd.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "90010000.display");
clk = clk_register(NULL, &clk_vpp.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "90020000.vpp");
clk = clk_register(NULL, &clk_mmc01.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk = clk_register(NULL, &clk_mmc23.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk = clk_register(NULL, &clk_mmc45.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk = clk_register(NULL, &usb_pll_clk_hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk = clk_register(NULL, &clk_usb0.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b00e0000.usb");
clk = clk_register(NULL, &clk_usb1.hw);
- BUG_ON(!clk);
+ BUG_ON(IS_ERR(clk));
clk_register_clkdev(clk, NULL, "b00f0000.usb");
}
diff --git a/drivers/clk/clk-twl6040.c b/drivers/clk/clk-twl6040.c
new file mode 100644
index 00000000000..bc1e713e7b9
--- /dev/null
+++ b/drivers/clk/clk-twl6040.c
@@ -0,0 +1,126 @@
+/*
+* TWL6040 clock module driver for OMAP4 McPDM functional clock
+*
+* Copyright (C) 2012 Texas Instruments Inc.
+* Peter Ujfalusi <peter.ujfalusi@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.
+*
+* 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/clk.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/twl6040.h>
+#include <linux/clk-provider.h>
+
+struct twl6040_clk {
+ struct twl6040 *twl6040;
+ struct device *dev;
+ struct clk_hw mcpdm_fclk;
+ struct clk *clk;
+ int enabled;
+};
+
+static int twl6040_bitclk_is_enabled(struct clk_hw *hw)
+{
+ struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk,
+ mcpdm_fclk);
+ return twl6040_clk->enabled;
+}
+
+static int twl6040_bitclk_prepare(struct clk_hw *hw)
+{
+ struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk,
+ mcpdm_fclk);
+ int ret;
+
+ ret = twl6040_power(twl6040_clk->twl6040, 1);
+ if (!ret)
+ twl6040_clk->enabled = 1;
+
+ return ret;
+}
+
+static void twl6040_bitclk_unprepare(struct clk_hw *hw)
+{
+ struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk,
+ mcpdm_fclk);
+ int ret;
+
+ ret = twl6040_power(twl6040_clk->twl6040, 0);
+ if (!ret)
+ twl6040_clk->enabled = 0;
+}
+
+static const struct clk_ops twl6040_mcpdm_ops = {
+ .is_enabled = twl6040_bitclk_is_enabled,
+ .prepare = twl6040_bitclk_prepare,
+ .unprepare = twl6040_bitclk_unprepare,
+};
+
+static struct clk_init_data wm831x_clkout_init = {
+ .name = "mcpdm_fclk",
+ .ops = &twl6040_mcpdm_ops,
+ .flags = CLK_IS_ROOT,
+};
+
+static int __devinit twl6040_clk_probe(struct platform_device *pdev)
+{
+ struct twl6040 *twl6040 = dev_get_drvdata(pdev->dev.parent);
+ struct twl6040_clk *clkdata;
+
+ clkdata = devm_kzalloc(&pdev->dev, sizeof(*clkdata), GFP_KERNEL);
+ if (!clkdata)
+ return -ENOMEM;
+
+ clkdata->dev = &pdev->dev;
+ clkdata->twl6040 = twl6040;
+
+ clkdata->mcpdm_fclk.init = &wm831x_clkout_init;
+ clkdata->clk = clk_register(&pdev->dev, &clkdata->mcpdm_fclk);
+ if (IS_ERR(clkdata->clk))
+ return PTR_ERR(clkdata->clk);
+
+ dev_set_drvdata(&pdev->dev, clkdata);
+
+ return 0;
+}
+
+static int __devexit twl6040_clk_remove(struct platform_device *pdev)
+{
+ struct twl6040_clk *clkdata = dev_get_drvdata(&pdev->dev);
+
+ clk_unregister(clkdata->clk);
+
+ return 0;
+}
+
+static struct platform_driver twl6040_clk_driver = {
+ .driver = {
+ .name = "twl6040-clk",
+ .owner = THIS_MODULE,
+ },
+ .probe = twl6040_clk_probe,
+ .remove = __devexit_p(twl6040_clk_remove),
+};
+
+module_platform_driver(twl6040_clk_driver);
+
+MODULE_DESCRIPTION("TWL6040 clock driver for McPDM functional clock");
+MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
+MODULE_ALIAS("platform:twl6040-clk");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c
index a885600f527..fe25570874d 100644
--- a/drivers/clk/clk-vt8500.c
+++ b/drivers/clk/clk-vt8500.c
@@ -120,8 +120,17 @@ static unsigned long vt8500_dclk_recalc_rate(struct clk_hw *hw,
static long vt8500_dclk_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
+ struct clk_device *cdev = to_clk_device(hw);
u32 divisor = *prate / rate;
+ /*
+ * If this is a request for SDMMC we have to adjust the divisor
+ * when >31 to use the fixed predivisor
+ */
+ if ((cdev->div_mask == 0x3F) && (divisor > 31)) {
+ divisor = 64 * ((divisor / 64) + 1);
+ }
+
return *prate / divisor;
}
@@ -135,6 +144,15 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate,
if (divisor == cdev->div_mask + 1)
divisor = 0;
+ /* SDMMC mask may need to be corrected before testing if its valid */
+ if ((cdev->div_mask == 0x3F) && (divisor > 31)) {
+ /*
+ * Bit 5 is a fixed /64 predivisor. If the requested divisor
+ * is >31 then correct for the fixed divisor being required.
+ */
+ divisor = 0x20 + (divisor / 64);
+ }
+
if (divisor > cdev->div_mask) {
pr_err("%s: invalid divisor for clock\n", __func__);
return -EINVAL;
diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c
index e7b7765e85f..16ed0680855 100644
--- a/drivers/clk/clk-wm831x.c
+++ b/drivers/clk/clk-wm831x.c
@@ -350,7 +350,7 @@ static struct clk_init_data wm831x_clkout_init = {
.flags = CLK_SET_RATE_PARENT,
};
-static __devinit int wm831x_clk_probe(struct platform_device *pdev)
+static int wm831x_clk_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_clk *clkdata;
@@ -370,49 +370,33 @@ static __devinit int wm831x_clk_probe(struct platform_device *pdev)
clkdata->xtal_ena = ret & WM831X_XTAL_ENA;
clkdata->xtal_hw.init = &wm831x_xtal_init;
- clkdata->xtal = clk_register(&pdev->dev, &clkdata->xtal_hw);
- if (!clkdata->xtal)
- return -EINVAL;
+ clkdata->xtal = devm_clk_register(&pdev->dev, &clkdata->xtal_hw);
+ if (IS_ERR(clkdata->xtal))
+ return PTR_ERR(clkdata->xtal);
clkdata->fll_hw.init = &wm831x_fll_init;
- clkdata->fll = clk_register(&pdev->dev, &clkdata->fll_hw);
- if (!clkdata->fll) {
- ret = -EINVAL;
- goto err_xtal;
- }
+ clkdata->fll = devm_clk_register(&pdev->dev, &clkdata->fll_hw);
+ if (IS_ERR(clkdata->fll))
+ return PTR_ERR(clkdata->fll);
clkdata->clkout_hw.init = &wm831x_clkout_init;
- clkdata->clkout = clk_register(&pdev->dev, &clkdata->clkout_hw);
- if (!clkdata->clkout) {
- ret = -EINVAL;
- goto err_fll;
- }
+ clkdata->clkout = devm_clk_register(&pdev->dev, &clkdata->clkout_hw);
+ if (IS_ERR(clkdata->clkout))
+ return PTR_ERR(clkdata->clkout);
dev_set_drvdata(&pdev->dev, clkdata);
return 0;
-
-err_fll:
- clk_unregister(clkdata->fll);
-err_xtal:
- clk_unregister(clkdata->xtal);
- return ret;
}
-static int __devexit wm831x_clk_remove(struct platform_device *pdev)
+static int wm831x_clk_remove(struct platform_device *pdev)
{
- struct wm831x_clk *clkdata = dev_get_drvdata(&pdev->dev);
-
- clk_unregister(clkdata->clkout);
- clk_unregister(clkdata->fll);
- clk_unregister(clkdata->xtal);
-
return 0;
}
static struct platform_driver wm831x_clk_driver = {
.probe = wm831x_clk_probe,
- .remove = __devexit_p(wm831x_clk_remove),
+ .remove = wm831x_clk_remove,
.driver = {
.name = "wm831x-clk",
.owner = THIS_MODULE,
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 56e4495ebeb..251e45d6024 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -17,6 +17,7 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/of.h>
+#include <linux/device.h>
static DEFINE_SPINLOCK(enable_lock);
static DEFINE_MUTEX(prepare_lock);
@@ -218,8 +219,17 @@ static void clk_disable_unused_subtree(struct clk *clk)
if (clk->flags & CLK_IGNORE_UNUSED)
goto unlock_out;
- if (__clk_is_enabled(clk) && clk->ops->disable)
- clk->ops->disable(clk->hw);
+ /*
+ * some gate clocks have special needs during the disable-unused
+ * sequence. call .disable_unused if available, otherwise fall
+ * back to .disable
+ */
+ if (__clk_is_enabled(clk)) {
+ if (clk->ops->disable_unused)
+ clk->ops->disable_unused(clk->hw);
+ else if (clk->ops->disable)
+ clk->ops->disable(clk->hw);
+ }
unlock_out:
spin_unlock_irqrestore(&enable_lock, flags);
@@ -261,7 +271,7 @@ inline struct clk_hw *__clk_get_hw(struct clk *clk)
inline u8 __clk_get_num_parents(struct clk *clk)
{
- return !clk ? -EINVAL : clk->num_parents;
+ return !clk ? 0 : clk->num_parents;
}
inline struct clk *__clk_get_parent(struct clk *clk)
@@ -269,14 +279,14 @@ inline struct clk *__clk_get_parent(struct clk *clk)
return !clk ? NULL : clk->parent;
}
-inline int __clk_get_enable_count(struct clk *clk)
+inline unsigned int __clk_get_enable_count(struct clk *clk)
{
- return !clk ? -EINVAL : clk->enable_count;
+ return !clk ? 0 : clk->enable_count;
}
-inline int __clk_get_prepare_count(struct clk *clk)
+inline unsigned int __clk_get_prepare_count(struct clk *clk)
{
- return !clk ? -EINVAL : clk->prepare_count;
+ return !clk ? 0 : clk->prepare_count;
}
unsigned long __clk_get_rate(struct clk *clk)
@@ -302,15 +312,15 @@ out:
inline unsigned long __clk_get_flags(struct clk *clk)
{
- return !clk ? -EINVAL : clk->flags;
+ return !clk ? 0 : clk->flags;
}
-int __clk_is_enabled(struct clk *clk)
+bool __clk_is_enabled(struct clk *clk)
{
int ret;
if (!clk)
- return -EINVAL;
+ return false;
/*
* .is_enabled is only mandatory for clocks that gate
@@ -323,7 +333,7 @@ int __clk_is_enabled(struct clk *clk)
ret = clk->ops->is_enabled(clk->hw);
out:
- return ret;
+ return !!ret;
}
static struct clk *__clk_lookup_subtree(const char *name, struct clk *clk)
@@ -568,7 +578,7 @@ unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
unsigned long parent_rate = 0;
if (!clk)
- return -EINVAL;
+ return 0;
if (!clk->ops->round_rate) {
if (clk->flags & CLK_SET_RATE_PARENT)
@@ -1297,12 +1307,20 @@ int __clk_init(struct device *dev, struct clk *clk)
* walk the list of orphan clocks and reparent any that are children of
* this clock
*/
- hlist_for_each_entry_safe(orphan, tmp, tmp2, &clk_orphan_list, child_node)
+ hlist_for_each_entry_safe(orphan, tmp, tmp2, &clk_orphan_list, child_node) {
+ if (orphan->ops->get_parent) {
+ i = orphan->ops->get_parent(orphan->hw);
+ if (!strcmp(clk->name, orphan->parent_names[i]))
+ __clk_reparent(orphan, clk);
+ continue;
+ }
+
for (i = 0; i < orphan->num_parents; i++)
if (!strcmp(clk->name, orphan->parent_names[i])) {
__clk_reparent(orphan, clk);
break;
}
+ }
/*
* optional platform-specific magic
@@ -1361,28 +1379,9 @@ struct clk *__clk_register(struct device *dev, struct clk_hw *hw)
}
EXPORT_SYMBOL_GPL(__clk_register);
-/**
- * clk_register - allocate a new clock, register it and return an opaque cookie
- * @dev: device that is registering this clock
- * @hw: link to hardware-specific clock data
- *
- * clk_register is the primary interface for populating the clock tree with new
- * clock nodes. It returns a pointer to the newly allocated struct clk which
- * cannot be dereferenced by driver code but may be used in conjuction with the
- * rest of the clock API. In the event of an error clk_register will return an
- * error code; drivers must test for an error code after calling clk_register.
- */
-struct clk *clk_register(struct device *dev, struct clk_hw *hw)
+static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk)
{
int i, ret;
- struct clk *clk;
-
- clk = kzalloc(sizeof(*clk), GFP_KERNEL);
- if (!clk) {
- pr_err("%s: could not allocate clk\n", __func__);
- ret = -ENOMEM;
- goto fail_out;
- }
clk->name = kstrdup(hw->init->name, GFP_KERNEL);
if (!clk->name) {
@@ -1420,7 +1419,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
ret = __clk_init(dev, clk);
if (!ret)
- return clk;
+ return 0;
fail_parent_names_copy:
while (--i >= 0)
@@ -1429,6 +1428,36 @@ fail_parent_names_copy:
fail_parent_names:
kfree(clk->name);
fail_name:
+ return ret;
+}
+
+/**
+ * clk_register - allocate a new clock, register it and return an opaque cookie
+ * @dev: device that is registering this clock
+ * @hw: link to hardware-specific clock data
+ *
+ * clk_register is the primary interface for populating the clock tree with new
+ * clock nodes. It returns a pointer to the newly allocated struct clk which
+ * cannot be dereferenced by driver code but may be used in conjuction with the
+ * rest of the clock API. In the event of an error clk_register will return an
+ * error code; drivers must test for an error code after calling clk_register.
+ */
+struct clk *clk_register(struct device *dev, struct clk_hw *hw)
+{
+ int ret;
+ struct clk *clk;
+
+ clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+ if (!clk) {
+ pr_err("%s: could not allocate clk\n", __func__);
+ ret = -ENOMEM;
+ goto fail_out;
+ }
+
+ ret = _clk_register(dev, hw, clk);
+ if (!ret)
+ return clk;
+
kfree(clk);
fail_out:
return ERR_PTR(ret);
@@ -1444,6 +1473,63 @@ EXPORT_SYMBOL_GPL(clk_register);
void clk_unregister(struct clk *clk) {}
EXPORT_SYMBOL_GPL(clk_unregister);
+static void devm_clk_release(struct device *dev, void *res)
+{
+ clk_unregister(res);
+}
+
+/**
+ * devm_clk_register - resource managed clk_register()
+ * @dev: device that is registering this clock
+ * @hw: link to hardware-specific clock data
+ *
+ * Managed clk_register(). Clocks returned from this function are
+ * automatically clk_unregister()ed on driver detach. See clk_register() for
+ * more information.
+ */
+struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw)
+{
+ struct clk *clk;
+ int ret;
+
+ clk = devres_alloc(devm_clk_release, sizeof(*clk), GFP_KERNEL);
+ if (!clk)
+ return ERR_PTR(-ENOMEM);
+
+ ret = _clk_register(dev, hw, clk);
+ if (!ret) {
+ devres_add(dev, clk);
+ } else {
+ devres_free(clk);
+ clk = ERR_PTR(ret);
+ }
+
+ return clk;
+}
+EXPORT_SYMBOL_GPL(devm_clk_register);
+
+static int devm_clk_match(struct device *dev, void *res, void *data)
+{
+ struct clk *c = res;
+ if (WARN_ON(!c))
+ return 0;
+ return c == data;
+}
+
+/**
+ * devm_clk_unregister - resource managed clk_unregister()
+ * @clk: clock to unregister
+ *
+ * Deallocate a clock allocated with devm_clk_register(). Normally
+ * this function will not need to be called and the resource management
+ * code will ensure that the resource is freed.
+ */
+void devm_clk_unregister(struct device *dev, struct clk *clk)
+{
+ WARN_ON(devres_release(dev, devm_clk_release, devm_clk_match, clk));
+}
+EXPORT_SYMBOL_GPL(devm_clk_unregister);
+
/*** clk rate change notifiers ***/
/**
diff --git a/drivers/clk/mxs/clk-imx23.c b/drivers/clk/mxs/clk-imx23.c
index f00dffb9ad6..8dd476e2a9c 100644
--- a/drivers/clk/mxs/clk-imx23.c
+++ b/drivers/clk/mxs/clk-imx23.c
@@ -85,7 +85,7 @@ enum imx23_clk {
cpu_xtal, hbus, xbus, lcdif_div, ssp_div, gpmi_div, emi_pll,
emi_xtal, etm_div, saif_div, clk32k_div, rtc, adc, spdif_div,
clk32k, dri, pwm, filt, uart, ssp, gpmi, spdif, emi, saif,
- lcdif, etm, usb, usb_pwr,
+ lcdif, etm, usb, usb_phy,
clk_max
};
@@ -143,8 +143,8 @@ int __init mx23_clocks_init(void)
clks[saif] = mxs_clk_gate("saif", "saif_div", SAIF, 31);
clks[lcdif] = mxs_clk_gate("lcdif", "lcdif_div", PIX, 31);
clks[etm] = mxs_clk_gate("etm", "etm_div", ETM, 31);
- clks[usb] = mxs_clk_gate("usb", "usb_pwr", DIGCTRL, 2);
- clks[usb_pwr] = clk_register_gate(NULL, "usb_pwr", "pll", 0, PLLCTRL0, 18, 0, &mxs_lock);
+ clks[usb] = mxs_clk_gate("usb", "usb_phy", DIGCTRL, 2);
+ clks[usb_phy] = clk_register_gate(NULL, "usb_phy", "pll", 0, PLLCTRL0, 18, 0, &mxs_lock);
for (i = 0; i < ARRAY_SIZE(clks); i++)
if (IS_ERR(clks[i])) {
diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c
index 42978f1b4bd..db3af087412 100644
--- a/drivers/clk/mxs/clk-imx28.c
+++ b/drivers/clk/mxs/clk-imx28.c
@@ -140,7 +140,7 @@ enum imx28_clk {
emi_xtal, lcdif_div, etm_div, ptp, saif0_div, saif1_div,
clk32k_div, rtc, lradc, spdif_div, clk32k, pwm, uart, ssp0,
ssp1, ssp2, ssp3, gpmi, spdif, emi, saif0, saif1, lcdif, etm,
- fec, can0, can1, usb0, usb1, usb0_pwr, usb1_pwr, enet_out,
+ fec, can0, can1, usb0, usb1, usb0_phy, usb1_phy, enet_out,
clk_max
};
@@ -218,10 +218,10 @@ int __init mx28_clocks_init(void)
clks[fec] = mxs_clk_gate("fec", "hbus", ENET, 30);
clks[can0] = mxs_clk_gate("can0", "ref_xtal", FLEXCAN, 30);
clks[can1] = mxs_clk_gate("can1", "ref_xtal", FLEXCAN, 28);
- clks[usb0] = mxs_clk_gate("usb0", "usb0_pwr", DIGCTRL, 2);
- clks[usb1] = mxs_clk_gate("usb1", "usb1_pwr", DIGCTRL, 16);
- clks[usb0_pwr] = clk_register_gate(NULL, "usb0_pwr", "pll0", 0, PLL0CTRL0, 18, 0, &mxs_lock);
- clks[usb1_pwr] = clk_register_gate(NULL, "usb1_pwr", "pll1", 0, PLL1CTRL0, 18, 0, &mxs_lock);
+ clks[usb0] = mxs_clk_gate("usb0", "usb0_phy", DIGCTRL, 2);
+ clks[usb1] = mxs_clk_gate("usb1", "usb1_phy", DIGCTRL, 16);
+ clks[usb0_phy] = clk_register_gate(NULL, "usb0_phy", "pll0", 0, PLL0CTRL0, 18, 0, &mxs_lock);
+ clks[usb1_phy] = clk_register_gate(NULL, "usb1_phy", "pll1", 0, PLL1CTRL0, 18, 0, &mxs_lock);
clks[enet_out] = clk_register_gate(NULL, "enet_out", "pll2", 0, ENET, 18, 0, &mxs_lock);
for (i = 0; i < ARRAY_SIZE(clks); i++)
diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c
index 6756e7c3bc0..bdfb4421c64 100644
--- a/drivers/clk/spear/clk-aux-synth.c
+++ b/drivers/clk/spear/clk-aux-synth.c
@@ -179,7 +179,8 @@ struct clk *clk_register_aux(const char *aux_name, const char *gate_name,
if (gate_name) {
struct clk *tgate_clk;
- tgate_clk = clk_register_gate(NULL, gate_name, aux_name, 0, reg,
+ tgate_clk = clk_register_gate(NULL, gate_name, aux_name,
+ CLK_SET_RATE_PARENT, reg,
aux->masks->enable_bit, 0, lock);
if (IS_ERR_OR_NULL(tgate_clk))
goto free_aux;
diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c
index 5f1b6badeb1..1b9b65bca51 100644
--- a/drivers/clk/spear/clk-vco-pll.c
+++ b/drivers/clk/spear/clk-vco-pll.c
@@ -147,7 +147,7 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long drate,
struct clk_pll *pll = to_clk_pll(hw);
struct pll_rate_tbl *rtbl = pll->vco->rtbl;
unsigned long flags = 0, val;
- int i;
+ int uninitialized_var(i);
clk_pll_round_rate_index(hw, drate, NULL, &i);
diff --git a/drivers/clk/spear/clk.c b/drivers/clk/spear/clk.c
index 7cd63788d54..628b6d5ed3d 100644
--- a/drivers/clk/spear/clk.c
+++ b/drivers/clk/spear/clk.c
@@ -32,5 +32,8 @@ long clk_round_rate_index(struct clk_hw *hw, unsigned long drate,
}
}
+ if ((*index) == rtbl_cnt)
+ (*index)--;
+
return rate;
}
diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c
index 0fcec2aae19..147e25f0040 100644
--- a/drivers/clk/spear/spear1310_clock.c
+++ b/drivers/clk/spear/spear1310_clock.c
@@ -313,6 +313,20 @@ static struct aux_clk_masks i2s_sclk_masks = {
/* i2s prs1 aux rate configuration table, in ascending order of rates */
static struct aux_rate_tbl i2s_prs1_rtbl[] = {
/* For parent clk = 49.152 MHz */
+ {.xscale = 1, .yscale = 12, .eq = 0}, /* 2.048 MHz, smp freq = 8Khz */
+ {.xscale = 11, .yscale = 96, .eq = 0}, /* 2.816 MHz, smp freq = 11Khz */
+ {.xscale = 1, .yscale = 6, .eq = 0}, /* 4.096 MHz, smp freq = 16Khz */
+ {.xscale = 11, .yscale = 48, .eq = 0}, /* 5.632 MHz, smp freq = 22Khz */
+
+ /*
+ * with parent clk = 49.152, freq gen is 8.192 MHz, smp freq = 32Khz
+ * with parent clk = 12.288, freq gen is 2.048 MHz, smp freq = 8Khz
+ */
+ {.xscale = 1, .yscale = 3, .eq = 0},
+
+ /* For parent clk = 49.152 MHz */
+ {.xscale = 17, .yscale = 37, .eq = 0}, /* 11.289 MHz, smp freq = 44Khz*/
+
{.xscale = 1, .yscale = 2, .eq = 0}, /* 12.288 MHz */
};
@@ -374,9 +388,6 @@ void __init spear1310_clk_init(void)
{
struct clk *clk, *clk1;
- clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0);
- clk_register_clkdev(clk, "apb_pclk", NULL);
-
clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT,
32000);
clk_register_clkdev(clk, "osc_32k_clk", NULL);
@@ -401,7 +412,7 @@ void __init spear1310_clk_init(void)
clk = clk_register_gate(NULL, "rtc-spear", "osc_32k_clk", 0,
SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_RTC_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, NULL, "fc900000.rtc");
+ clk_register_clkdev(clk, NULL, "e0580000.rtc");
/* clock derived from 24 or 25 MHz osc clk */
/* vco-pll */
@@ -483,13 +494,18 @@ void __init spear1310_clk_init(void)
clk_register_clkdev(clk, "ddr_clk", NULL);
/* clock derived from pll1 clk */
- clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", 0, 1, 2);
+ clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk",
+ CLK_SET_RATE_PARENT, 1, 2);
clk_register_clkdev(clk, "cpu_clk", NULL);
clk = clk_register_fixed_factor(NULL, "wdt_clk", "cpu_clk", 0, 1,
2);
clk_register_clkdev(clk, NULL, "ec800620.wdt");
+ clk = clk_register_fixed_factor(NULL, "smp_twd_clk", "cpu_clk", 0, 1,
+ 2);
+ clk_register_clkdev(clk, NULL, "smp_twd");
+
clk = clk_register_fixed_factor(NULL, "ahb_clk", "pll1_clk", 0, 1,
6);
clk_register_clkdev(clk, "ahb_clk", NULL);
@@ -547,14 +563,14 @@ void __init spear1310_clk_init(void)
clk_register_clkdev(clk1, "uart_syn_gclk", NULL);
clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents,
- ARRAY_SIZE(uart0_parents), 0, SPEAR1310_PERIP_CLK_CFG,
- SPEAR1310_UART_CLK_SHIFT, SPEAR1310_UART_CLK_MASK, 0,
- &_lock);
+ ARRAY_SIZE(uart0_parents), CLK_SET_RATE_PARENT,
+ SPEAR1310_PERIP_CLK_CFG, SPEAR1310_UART_CLK_SHIFT,
+ SPEAR1310_UART_CLK_MASK, 0, &_lock);
clk_register_clkdev(clk, "uart0_mclk", NULL);
- clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk", 0,
- SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UART_CLK_ENB, 0,
- &_lock);
+ clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk",
+ CLK_SET_RATE_PARENT, SPEAR1310_PERIP1_CLK_ENB,
+ SPEAR1310_UART_CLK_ENB, 0, &_lock);
clk_register_clkdev(clk, NULL, "e0000000.serial");
clk = clk_register_aux("sdhci_syn_clk", "sdhci_syn_gclk",
@@ -563,9 +579,9 @@ void __init spear1310_clk_init(void)
clk_register_clkdev(clk, "sdhci_syn_clk", NULL);
clk_register_clkdev(clk1, "sdhci_syn_gclk", NULL);
- clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk", 0,
- SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_SDHCI_CLK_ENB, 0,
- &_lock);
+ clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk",
+ CLK_SET_RATE_PARENT, SPEAR1310_PERIP1_CLK_ENB,
+ SPEAR1310_SDHCI_CLK_ENB, 0, &_lock);
clk_register_clkdev(clk, NULL, "b3000000.sdhci");
clk = clk_register_aux("cfxd_syn_clk", "cfxd_syn_gclk", "vco1div2_clk",
@@ -574,9 +590,9 @@ void __init spear1310_clk_init(void)
clk_register_clkdev(clk, "cfxd_syn_clk", NULL);
clk_register_clkdev(clk1, "cfxd_syn_gclk", NULL);
- clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk", 0,
- SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_CFXD_CLK_ENB, 0,
- &_lock);
+ clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk",
+ CLK_SET_RATE_PARENT, SPEAR1310_PERIP1_CLK_ENB,
+ SPEAR1310_CFXD_CLK_ENB, 0, &_lock);
clk_register_clkdev(clk, NULL, "b2800000.cf");
clk_register_clkdev(clk, NULL, "arasan_xd");
@@ -587,9 +603,9 @@ void __init spear1310_clk_init(void)
clk_register_clkdev(clk1, "c3_syn_gclk", NULL);
clk = clk_register_mux(NULL, "c3_mclk", c3_parents,
- ARRAY_SIZE(c3_parents), 0, SPEAR1310_PERIP_CLK_CFG,
- SPEAR1310_C3_CLK_SHIFT, SPEAR1310_C3_CLK_MASK, 0,
- &_lock);
+ ARRAY_SIZE(c3_parents), CLK_SET_RATE_PARENT,
+ SPEAR1310_PERIP_CLK_CFG, SPEAR1310_C3_CLK_SHIFT,
+ SPEAR1310_C3_CLK_MASK, 0, &_lock);
clk_register_clkdev(clk, "c3_mclk", NULL);
clk = clk_register_gate(NULL, "c3_clk", "c3_mclk", 0,
@@ -615,7 +631,7 @@ void __init spear1310_clk_init(void)
ARRAY_SIZE(gmac_phy_parents), 0,
SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GMAC_PHY_CLK_SHIFT,
SPEAR1310_GMAC_PHY_CLK_MASK, 0, &_lock);
- clk_register_clkdev(clk, NULL, "stmmacphy.0");
+ clk_register_clkdev(clk, "stmmacphy.0", NULL);
/* clcd */
clk = clk_register_mux(NULL, "clcd_syn_mclk", clcd_synth_parents,
@@ -630,22 +646,22 @@ void __init spear1310_clk_init(void)
clk_register_clkdev(clk, "clcd_syn_clk", NULL);
clk = clk_register_mux(NULL, "clcd_pixel_mclk", clcd_pixel_parents,
- ARRAY_SIZE(clcd_pixel_parents), 0,
+ ARRAY_SIZE(clcd_pixel_parents), CLK_SET_RATE_PARENT,
SPEAR1310_PERIP_CLK_CFG, SPEAR1310_CLCD_CLK_SHIFT,
SPEAR1310_CLCD_CLK_MASK, 0, &_lock);
- clk_register_clkdev(clk, "clcd_pixel_clk", NULL);
+ clk_register_clkdev(clk, "clcd_pixel_mclk", NULL);
clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mclk", 0,
SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_CLCD_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, "clcd_clk", NULL);
+ clk_register_clkdev(clk, NULL, "e1000000.clcd");
/* i2s */
clk = clk_register_mux(NULL, "i2s_src_mclk", i2s_src_parents,
ARRAY_SIZE(i2s_src_parents), 0, SPEAR1310_I2S_CLK_CFG,
SPEAR1310_I2S_SRC_CLK_SHIFT, SPEAR1310_I2S_SRC_CLK_MASK,
0, &_lock);
- clk_register_clkdev(clk, "i2s_src_clk", NULL);
+ clk_register_clkdev(clk, "i2s_src_mclk", NULL);
clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk", 0,
SPEAR1310_I2S_CLK_CFG, &i2s_prs1_masks, i2s_prs1_rtbl,
@@ -653,10 +669,10 @@ void __init spear1310_clk_init(void)
clk_register_clkdev(clk, "i2s_prs1_clk", NULL);
clk = clk_register_mux(NULL, "i2s_ref_mclk", i2s_ref_parents,
- ARRAY_SIZE(i2s_ref_parents), 0, SPEAR1310_I2S_CLK_CFG,
- SPEAR1310_I2S_REF_SHIFT, SPEAR1310_I2S_REF_SEL_MASK, 0,
- &_lock);
- clk_register_clkdev(clk, "i2s_ref_clk", NULL);
+ ARRAY_SIZE(i2s_ref_parents), CLK_SET_RATE_PARENT,
+ SPEAR1310_I2S_CLK_CFG, SPEAR1310_I2S_REF_SHIFT,
+ SPEAR1310_I2S_REF_SEL_MASK, 0, &_lock);
+ clk_register_clkdev(clk, "i2s_ref_mclk", NULL);
clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mclk", 0,
SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_I2S_REF_PAD_CLK_ENB,
@@ -664,7 +680,7 @@ void __init spear1310_clk_init(void)
clk_register_clkdev(clk, "i2s_ref_pad_clk", NULL);
clk = clk_register_aux("i2s_sclk_clk", "i2s_sclk_gclk",
- "i2s_ref_pad_clk", 0, SPEAR1310_I2S_CLK_CFG,
+ "i2s_ref_mclk", 0, SPEAR1310_I2S_CLK_CFG,
&i2s_sclk_masks, i2s_sclk_rtbl,
ARRAY_SIZE(i2s_sclk_rtbl), &_lock, &clk1);
clk_register_clkdev(clk, "i2s_sclk_clk", NULL);
@@ -705,35 +721,37 @@ void __init spear1310_clk_init(void)
clk = clk_register_gate(NULL, "usbh0_clk", "ahb_clk", 0,
SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UHC0_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, "usbh.0_clk", NULL);
+ clk_register_clkdev(clk, NULL, "e4000000.ohci");
+ clk_register_clkdev(clk, NULL, "e4800000.ehci");
clk = clk_register_gate(NULL, "usbh1_clk", "ahb_clk", 0,
SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UHC1_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, "usbh.1_clk", NULL);
+ clk_register_clkdev(clk, NULL, "e5000000.ohci");
+ clk_register_clkdev(clk, NULL, "e5800000.ehci");
clk = clk_register_gate(NULL, "uoc_clk", "ahb_clk", 0,
SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UOC_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, NULL, "uoc");
+ clk_register_clkdev(clk, NULL, "e3800000.otg");
clk = clk_register_gate(NULL, "pcie_sata_0_clk", "ahb_clk", 0,
SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_0_CLK_ENB,
0, &_lock);
clk_register_clkdev(clk, NULL, "dw_pcie.0");
- clk_register_clkdev(clk, NULL, "ahci.0");
+ clk_register_clkdev(clk, NULL, "b1000000.ahci");
clk = clk_register_gate(NULL, "pcie_sata_1_clk", "ahb_clk", 0,
SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_1_CLK_ENB,
0, &_lock);
clk_register_clkdev(clk, NULL, "dw_pcie.1");
- clk_register_clkdev(clk, NULL, "ahci.1");
+ clk_register_clkdev(clk, NULL, "b1800000.ahci");
clk = clk_register_gate(NULL, "pcie_sata_2_clk", "ahb_clk", 0,
SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_2_CLK_ENB,
0, &_lock);
clk_register_clkdev(clk, NULL, "dw_pcie.2");
- clk_register_clkdev(clk, NULL, "ahci.2");
+ clk_register_clkdev(clk, NULL, "b4000000.ahci");
clk = clk_register_gate(NULL, "sysram0_clk", "ahb_clk", 0,
SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_SYSRAM0_CLK_ENB, 0,
@@ -751,10 +769,10 @@ void __init spear1310_clk_init(void)
clk_register_clkdev(clk, "adc_syn_clk", NULL);
clk_register_clkdev(clk1, "adc_syn_gclk", NULL);
- clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", 0,
- SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_ADC_CLK_ENB, 0,
- &_lock);
- clk_register_clkdev(clk, NULL, "adc_clk");
+ clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk",
+ CLK_SET_RATE_PARENT, SPEAR1310_PERIP1_CLK_ENB,
+ SPEAR1310_ADC_CLK_ENB, 0, &_lock);
+ clk_register_clkdev(clk, NULL, "e0080000.adc");
/* clock derived from apb clk */
clk = clk_register_gate(NULL, "ssp0_clk", "apb_clk", 0,
@@ -916,15 +934,15 @@ void __init spear1310_clk_init(void)
SPEAR1310_RAS_CTRL_REG1,
SPEAR1310_SMII_RGMII_PHY_CLK_SHIFT,
SPEAR1310_PHY_CLK_MASK, 0, &_lock);
- clk_register_clkdev(clk, NULL, "stmmacphy.1");
- clk_register_clkdev(clk, NULL, "stmmacphy.2");
- clk_register_clkdev(clk, NULL, "stmmacphy.4");
+ clk_register_clkdev(clk, "stmmacphy.1", NULL);
+ clk_register_clkdev(clk, "stmmacphy.2", NULL);
+ clk_register_clkdev(clk, "stmmacphy.4", NULL);
clk = clk_register_mux(NULL, "rmii_phy_mclk", rmii_phy_parents,
ARRAY_SIZE(rmii_phy_parents), 0,
SPEAR1310_RAS_CTRL_REG1, SPEAR1310_RMII_PHY_CLK_SHIFT,
SPEAR1310_PHY_CLK_MASK, 0, &_lock);
- clk_register_clkdev(clk, NULL, "stmmacphy.3");
+ clk_register_clkdev(clk, "stmmacphy.3", NULL);
clk = clk_register_mux(NULL, "uart1_mclk", uart_parents,
ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0,
diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c
index 2352cee7f64..82abea366b7 100644
--- a/drivers/clk/spear/spear1340_clock.c
+++ b/drivers/clk/spear/spear1340_clock.c
@@ -190,6 +190,7 @@ static struct pll_rate_tbl pll4_rtbl[] = {
* different values of vco1div2
*/
static struct frac_rate_tbl amba_synth_rtbl[] = {
+ {.div = 0x073A8}, /* for vco1div2 = 600 MHz */
{.div = 0x06062}, /* for vco1div2 = 500 MHz */
{.div = 0x04D1B}, /* for vco1div2 = 400 MHz */
{.div = 0x04000}, /* for vco1div2 = 332 MHz */
@@ -220,6 +221,12 @@ static struct frac_rate_tbl amba_synth_rtbl[] = {
* 500 400 200 0x02800
* 500 500 250 0x02000
* --------------------------------------------------------------------
+ * 600 200 100 0x06000
+ * 600 250 125 0x04CCE
+ * 600 332 166 0x039D5
+ * 600 400 200 0x03000
+ * 600 500 250 0x02666
+ * --------------------------------------------------------------------
* 664 200 100 0x06a38
* 664 250 125 0x054FD
* 664 332 166 0x04000
@@ -238,28 +245,50 @@ static struct frac_rate_tbl sys_synth_rtbl[] = {
{.div = 0x08000},
{.div = 0x06a38},
{.div = 0x06666},
+ {.div = 0x06000},
{.div = 0x054FD},
{.div = 0x05000},
{.div = 0x04D18},
+ {.div = 0x04CCE},
{.div = 0x04000},
+ {.div = 0x039D5},
{.div = 0x0351E},
{.div = 0x03333},
{.div = 0x03031},
+ {.div = 0x03000},
{.div = 0x02A7E},
{.div = 0x02800},
{.div = 0x0268D},
+ {.div = 0x02666},
{.div = 0x02000},
};
/* aux rate configuration table, in ascending order of rates */
static struct aux_rate_tbl aux_rtbl[] = {
- /* For VCO1div2 = 500 MHz */
- {.xscale = 10, .yscale = 204, .eq = 0}, /* 12.29 MHz */
- {.xscale = 4, .yscale = 21, .eq = 0}, /* 48 MHz */
- {.xscale = 2, .yscale = 6, .eq = 0}, /* 83 MHz */
- {.xscale = 2, .yscale = 4, .eq = 0}, /* 125 MHz */
- {.xscale = 1, .yscale = 3, .eq = 1}, /* 166 MHz */
- {.xscale = 1, .yscale = 2, .eq = 1}, /* 250 MHz */
+ /* 12.29MHz for vic1div2=600MHz and 10.24MHz for VCO1div2=500MHz */
+ {.xscale = 5, .yscale = 122, .eq = 0},
+ /* 14.70MHz for vic1div2=600MHz and 12.29MHz for VCO1div2=500MHz */
+ {.xscale = 10, .yscale = 204, .eq = 0},
+ /* 48MHz for vic1div2=600MHz and 40 MHz for VCO1div2=500MHz */
+ {.xscale = 4, .yscale = 25, .eq = 0},
+ /* 57.14MHz for vic1div2=600MHz and 48 MHz for VCO1div2=500MHz */
+ {.xscale = 4, .yscale = 21, .eq = 0},
+ /* 83.33MHz for vic1div2=600MHz and 69.44MHz for VCO1div2=500MHz */
+ {.xscale = 5, .yscale = 18, .eq = 0},
+ /* 100MHz for vic1div2=600MHz and 83.33 MHz for VCO1div2=500MHz */
+ {.xscale = 2, .yscale = 6, .eq = 0},
+ /* 125MHz for vic1div2=600MHz and 104.1MHz for VCO1div2=500MHz */
+ {.xscale = 5, .yscale = 12, .eq = 0},
+ /* 150MHz for vic1div2=600MHz and 125MHz for VCO1div2=500MHz */
+ {.xscale = 2, .yscale = 4, .eq = 0},
+ /* 166MHz for vic1div2=600MHz and 138.88MHz for VCO1div2=500MHz */
+ {.xscale = 5, .yscale = 18, .eq = 1},
+ /* 200MHz for vic1div2=600MHz and 166MHz for VCO1div2=500MHz */
+ {.xscale = 1, .yscale = 3, .eq = 1},
+ /* 250MHz for vic1div2=600MHz and 208.33MHz for VCO1div2=500MHz */
+ {.xscale = 5, .yscale = 12, .eq = 1},
+ /* 300MHz for vic1div2=600MHz and 250MHz for VCO1div2=500MHz */
+ {.xscale = 1, .yscale = 2, .eq = 1},
};
/* gmac rate configuration table, in ascending order of rates */
@@ -273,16 +302,23 @@ static struct aux_rate_tbl gmac_rtbl[] = {
/* clcd rate configuration table, in ascending order of rates */
static struct frac_rate_tbl clcd_rtbl[] = {
+ {.div = 0x18000}, /* 25 Mhz , for vc01div4 = 300 MHz*/
+ {.div = 0x1638E}, /* 27 Mhz , for vc01div4 = 300 MHz*/
{.div = 0x14000}, /* 25 Mhz , for vc01div4 = 250 MHz*/
{.div = 0x1284B}, /* 27 Mhz , for vc01div4 = 250 MHz*/
{.div = 0x0D8D3}, /* 58 Mhz , for vco1div4 = 393 MHz */
{.div = 0x0B72C}, /* 58 Mhz , for vco1div4 = 332 MHz */
+ {.div = 0x0A584}, /* 58 Mhz , for vco1div4 = 300 MHz */
+ {.div = 0x093B1}, /* 65 Mhz , for vc01div4 = 300 MHz*/
{.div = 0x089EE}, /* 58 Mhz , for vc01div4 = 250 MHz*/
+ {.div = 0x081BA}, /* 74 Mhz , for vc01div4 = 300 MHz*/
{.div = 0x07BA0}, /* 65 Mhz , for vc01div4 = 250 MHz*/
{.div = 0x06f1C}, /* 72 Mhz , for vc01div4 = 250 MHz*/
{.div = 0x06E58}, /* 58 Mhz , for vco1div4 = 200 MHz */
{.div = 0x06c1B}, /* 74 Mhz , for vc01div4 = 250 MHz*/
+ {.div = 0x058E3}, /* 108 Mhz , for vc01div4 = 300 MHz*/
{.div = 0x04A12}, /* 108 Mhz , for vc01div4 = 250 MHz*/
+ {.div = 0x040A5}, /* 148.5 Mhz , for vc01div4 = 300 MHz*/
{.div = 0x0378E}, /* 144 Mhz , for vc01div4 = 250 MHz*/
{.div = 0x0360D}, /* 148 Mhz , for vc01div4 = 250 MHz*/
{.div = 0x035E0}, /* 148.5 MHz, for vc01div4 = 250 MHz*/
@@ -351,26 +387,37 @@ static struct aux_rate_tbl adc_rtbl[] = {
/* General synth rate configuration table, in ascending order of rates */
static struct frac_rate_tbl gen_rtbl[] = {
- /* For vco1div4 = 250 MHz */
- {.div = 0x1624E}, /* 22.5792 MHz */
- {.div = 0x14585}, /* 24.576 MHz */
- {.div = 0x14000}, /* 25 MHz */
- {.div = 0x0B127}, /* 45.1584 MHz */
- {.div = 0x0A000}, /* 50 MHz */
- {.div = 0x061A8}, /* 81.92 MHz */
- {.div = 0x05000}, /* 100 MHz */
- {.div = 0x02800}, /* 200 MHz */
- {.div = 0x02620}, /* 210 MHz */
- {.div = 0x02460}, /* 220 MHz */
- {.div = 0x022C0}, /* 230 MHz */
- {.div = 0x02160}, /* 240 MHz */
- {.div = 0x02000}, /* 250 MHz */
+ {.div = 0x1A92B}, /* 22.5792 MHz for vco1div4=300 MHz*/
+ {.div = 0x186A0}, /* 24.576 MHz for vco1div4=300 MHz*/
+ {.div = 0x18000}, /* 25 MHz for vco1div4=300 MHz*/
+ {.div = 0x1624E}, /* 22.5792 MHz for vco1div4=250 MHz*/
+ {.div = 0x14585}, /* 24.576 MHz for vco1div4=250 MHz*/
+ {.div = 0x14000}, /* 25 MHz for vco1div4=250 MHz*/
+ {.div = 0x0D495}, /* 45.1584 MHz for vco1div4=300 MHz*/
+ {.div = 0x0C000}, /* 50 MHz for vco1div4=300 MHz*/
+ {.div = 0x0B127}, /* 45.1584 MHz for vco1div4=250 MHz*/
+ {.div = 0x0A000}, /* 50 MHz for vco1div4=250 MHz*/
+ {.div = 0x07530}, /* 81.92 MHz for vco1div4=300 MHz*/
+ {.div = 0x061A8}, /* 81.92 MHz for vco1div4=250 MHz*/
+ {.div = 0x06000}, /* 100 MHz for vco1div4=300 MHz*/
+ {.div = 0x05000}, /* 100 MHz for vco1div4=250 MHz*/
+ {.div = 0x03000}, /* 200 MHz for vco1div4=300 MHz*/
+ {.div = 0x02DB6}, /* 210 MHz for vco1div4=300 MHz*/
+ {.div = 0x02BA2}, /* 220 MHz for vco1div4=300 MHz*/
+ {.div = 0x029BD}, /* 230 MHz for vco1div4=300 MHz*/
+ {.div = 0x02800}, /* 200 MHz for vco1div4=250 MHz*/
+ {.div = 0x02666}, /* 250 MHz for vco1div4=300 MHz*/
+ {.div = 0x02620}, /* 210 MHz for vco1div4=250 MHz*/
+ {.div = 0x02460}, /* 220 MHz for vco1div4=250 MHz*/
+ {.div = 0x022C0}, /* 230 MHz for vco1div4=250 MHz*/
+ {.div = 0x02160}, /* 240 MHz for vco1div4=250 MHz*/
+ {.div = 0x02000}, /* 250 MHz for vco1div4=250 MHz*/
};
/* clock parents */
static const char *vco_parents[] = { "osc_24m_clk", "osc_25m_clk", };
static const char *sys_parents[] = { "pll1_clk", "pll1_clk", "pll1_clk",
- "pll1_clk", "sys_synth_clk", "sys_synth_clk", "pll2_clk", "pll3_clk", };
+ "pll1_clk", "sys_syn_clk", "sys_syn_clk", "pll2_clk", "pll3_clk", };
static const char *ahb_parents[] = { "cpu_div3_clk", "amba_syn_clk", };
static const char *gpt_parents[] = { "osc_24m_clk", "apb_clk", };
static const char *uart0_parents[] = { "pll5_clk", "osc_24m_clk",
@@ -391,16 +438,13 @@ static const char *spdif_in_parents[] = { "pll2_clk", "gen_syn3_clk", };
static const char *gen_synth0_1_parents[] = { "vco1div4_clk", "vco3div2_clk",
"pll3_clk", };
-static const char *gen_synth2_3_parents[] = { "vco1div4_clk", "vco3div2_clk",
+static const char *gen_synth2_3_parents[] = { "vco1div4_clk", "vco2div2_clk",
"pll2_clk", };
void __init spear1340_clk_init(void)
{
struct clk *clk, *clk1;
- clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0);
- clk_register_clkdev(clk, "apb_pclk", NULL);
-
clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT,
32000);
clk_register_clkdev(clk, "osc_32k_clk", NULL);
@@ -425,7 +469,7 @@ void __init spear1340_clk_init(void)
clk = clk_register_gate(NULL, "rtc-spear", "osc_32k_clk", 0,
SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_RTC_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, NULL, "fc900000.rtc");
+ clk_register_clkdev(clk, NULL, "e0580000.rtc");
/* clock derived from 24 or 25 MHz osc clk */
/* vco-pll */
@@ -499,7 +543,7 @@ void __init spear1340_clk_init(void)
clk = clk_register_gate(NULL, "thermal_gclk", "thermal_clk", 0,
SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_THSENS_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, NULL, "spear_thermal");
+ clk_register_clkdev(clk, NULL, "e07008c4.thermal");
/* clock derived from pll4 clk */
clk = clk_register_fixed_factor(NULL, "ddr_clk", "pll4_clk", 0, 1,
@@ -521,7 +565,7 @@ void __init spear1340_clk_init(void)
ARRAY_SIZE(sys_parents), 0, SPEAR1340_SYS_CLK_CTRL,
SPEAR1340_SCLK_SRC_SEL_SHIFT,
SPEAR1340_SCLK_SRC_SEL_MASK, 0, &_lock);
- clk_register_clkdev(clk, "sys_clk", NULL);
+ clk_register_clkdev(clk, "sys_mclk", NULL);
clk = clk_register_fixed_factor(NULL, "cpu_clk", "sys_mclk", 0, 1,
2);
@@ -535,6 +579,10 @@ void __init spear1340_clk_init(void)
2);
clk_register_clkdev(clk, NULL, "ec800620.wdt");
+ clk = clk_register_fixed_factor(NULL, "smp_twd_clk", "cpu_clk", 0, 1,
+ 2);
+ clk_register_clkdev(clk, NULL, "smp_twd");
+
clk = clk_register_mux(NULL, "ahb_clk", ahb_parents,
ARRAY_SIZE(ahb_parents), 0, SPEAR1340_SYS_CLK_CTRL,
SPEAR1340_HCLK_SRC_SEL_SHIFT,
@@ -594,14 +642,14 @@ void __init spear1340_clk_init(void)
clk_register_clkdev(clk1, "uart0_syn_gclk", NULL);
clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents,
- ARRAY_SIZE(uart0_parents), 0, SPEAR1340_PERIP_CLK_CFG,
- SPEAR1340_UART0_CLK_SHIFT, SPEAR1340_UART_CLK_MASK, 0,
- &_lock);
+ ARRAY_SIZE(uart0_parents), CLK_SET_RATE_PARENT,
+ SPEAR1340_PERIP_CLK_CFG, SPEAR1340_UART0_CLK_SHIFT,
+ SPEAR1340_UART_CLK_MASK, 0, &_lock);
clk_register_clkdev(clk, "uart0_mclk", NULL);
- clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk", 0,
- SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UART0_CLK_ENB, 0,
- &_lock);
+ clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk",
+ CLK_SET_RATE_PARENT, SPEAR1340_PERIP1_CLK_ENB,
+ SPEAR1340_UART0_CLK_ENB, 0, &_lock);
clk_register_clkdev(clk, NULL, "e0000000.serial");
clk = clk_register_aux("uart1_syn_clk", "uart1_syn_gclk",
@@ -627,9 +675,9 @@ void __init spear1340_clk_init(void)
clk_register_clkdev(clk, "sdhci_syn_clk", NULL);
clk_register_clkdev(clk1, "sdhci_syn_gclk", NULL);
- clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk", 0,
- SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_SDHCI_CLK_ENB, 0,
- &_lock);
+ clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk",
+ CLK_SET_RATE_PARENT, SPEAR1340_PERIP1_CLK_ENB,
+ SPEAR1340_SDHCI_CLK_ENB, 0, &_lock);
clk_register_clkdev(clk, NULL, "b3000000.sdhci");
clk = clk_register_aux("cfxd_syn_clk", "cfxd_syn_gclk", "vco1div2_clk",
@@ -638,9 +686,9 @@ void __init spear1340_clk_init(void)
clk_register_clkdev(clk, "cfxd_syn_clk", NULL);
clk_register_clkdev(clk1, "cfxd_syn_gclk", NULL);
- clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk", 0,
- SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_CFXD_CLK_ENB, 0,
- &_lock);
+ clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk",
+ CLK_SET_RATE_PARENT, SPEAR1340_PERIP1_CLK_ENB,
+ SPEAR1340_CFXD_CLK_ENB, 0, &_lock);
clk_register_clkdev(clk, NULL, "b2800000.cf");
clk_register_clkdev(clk, NULL, "arasan_xd");
@@ -651,15 +699,15 @@ void __init spear1340_clk_init(void)
clk_register_clkdev(clk1, "c3_syn_gclk", NULL);
clk = clk_register_mux(NULL, "c3_mclk", c3_parents,
- ARRAY_SIZE(c3_parents), 0, SPEAR1340_PERIP_CLK_CFG,
- SPEAR1340_C3_CLK_SHIFT, SPEAR1340_C3_CLK_MASK, 0,
- &_lock);
+ ARRAY_SIZE(c3_parents), CLK_SET_RATE_PARENT,
+ SPEAR1340_PERIP_CLK_CFG, SPEAR1340_C3_CLK_SHIFT,
+ SPEAR1340_C3_CLK_MASK, 0, &_lock);
clk_register_clkdev(clk, "c3_mclk", NULL);
- clk = clk_register_gate(NULL, "c3_clk", "c3_mclk", 0,
+ clk = clk_register_gate(NULL, "c3_clk", "c3_mclk", CLK_SET_RATE_PARENT,
SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_C3_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, NULL, "c3");
+ clk_register_clkdev(clk, NULL, "e1800000.c3");
/* gmac */
clk = clk_register_mux(NULL, "phy_input_mclk", gmac_phy_input_parents,
@@ -679,7 +727,7 @@ void __init spear1340_clk_init(void)
ARRAY_SIZE(gmac_phy_parents), 0,
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GMAC_PHY_CLK_SHIFT,
SPEAR1340_GMAC_PHY_CLK_MASK, 0, &_lock);
- clk_register_clkdev(clk, NULL, "stmmacphy.0");
+ clk_register_clkdev(clk, "stmmacphy.0", NULL);
/* clcd */
clk = clk_register_mux(NULL, "clcd_syn_mclk", clcd_synth_parents,
@@ -694,33 +742,34 @@ void __init spear1340_clk_init(void)
clk_register_clkdev(clk, "clcd_syn_clk", NULL);
clk = clk_register_mux(NULL, "clcd_pixel_mclk", clcd_pixel_parents,
- ARRAY_SIZE(clcd_pixel_parents), 0,
+ ARRAY_SIZE(clcd_pixel_parents), CLK_SET_RATE_PARENT,
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_CLCD_CLK_SHIFT,
SPEAR1340_CLCD_CLK_MASK, 0, &_lock);
- clk_register_clkdev(clk, "clcd_pixel_clk", NULL);
+ clk_register_clkdev(clk, "clcd_pixel_mclk", NULL);
clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mclk", 0,
SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_CLCD_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, "clcd_clk", NULL);
+ clk_register_clkdev(clk, NULL, "e1000000.clcd");
/* i2s */
clk = clk_register_mux(NULL, "i2s_src_mclk", i2s_src_parents,
ARRAY_SIZE(i2s_src_parents), 0, SPEAR1340_I2S_CLK_CFG,
SPEAR1340_I2S_SRC_CLK_SHIFT, SPEAR1340_I2S_SRC_CLK_MASK,
0, &_lock);
- clk_register_clkdev(clk, "i2s_src_clk", NULL);
+ clk_register_clkdev(clk, "i2s_src_mclk", NULL);
- clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk", 0,
- SPEAR1340_I2S_CLK_CFG, &i2s_prs1_masks, i2s_prs1_rtbl,
+ clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk",
+ CLK_SET_RATE_PARENT, SPEAR1340_I2S_CLK_CFG,
+ &i2s_prs1_masks, i2s_prs1_rtbl,
ARRAY_SIZE(i2s_prs1_rtbl), &_lock, NULL);
clk_register_clkdev(clk, "i2s_prs1_clk", NULL);
clk = clk_register_mux(NULL, "i2s_ref_mclk", i2s_ref_parents,
- ARRAY_SIZE(i2s_ref_parents), 0, SPEAR1340_I2S_CLK_CFG,
- SPEAR1340_I2S_REF_SHIFT, SPEAR1340_I2S_REF_SEL_MASK, 0,
- &_lock);
- clk_register_clkdev(clk, "i2s_ref_clk", NULL);
+ ARRAY_SIZE(i2s_ref_parents), CLK_SET_RATE_PARENT,
+ SPEAR1340_I2S_CLK_CFG, SPEAR1340_I2S_REF_SHIFT,
+ SPEAR1340_I2S_REF_SEL_MASK, 0, &_lock);
+ clk_register_clkdev(clk, "i2s_ref_mclk", NULL);
clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mclk", 0,
SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_I2S_REF_PAD_CLK_ENB,
@@ -769,23 +818,25 @@ void __init spear1340_clk_init(void)
clk = clk_register_gate(NULL, "usbh0_clk", "ahb_clk", 0,
SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UHC0_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, "usbh.0_clk", NULL);
+ clk_register_clkdev(clk, NULL, "e4000000.ohci");
+ clk_register_clkdev(clk, NULL, "e4800000.ehci");
clk = clk_register_gate(NULL, "usbh1_clk", "ahb_clk", 0,
SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UHC1_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, "usbh.1_clk", NULL);
+ clk_register_clkdev(clk, NULL, "e5000000.ohci");
+ clk_register_clkdev(clk, NULL, "e5800000.ehci");
clk = clk_register_gate(NULL, "uoc_clk", "ahb_clk", 0,
SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UOC_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, NULL, "uoc");
+ clk_register_clkdev(clk, NULL, "e3800000.otg");
clk = clk_register_gate(NULL, "pcie_sata_clk", "ahb_clk", 0,
SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_PCIE_SATA_CLK_ENB,
0, &_lock);
clk_register_clkdev(clk, NULL, "dw_pcie");
- clk_register_clkdev(clk, NULL, "ahci");
+ clk_register_clkdev(clk, NULL, "b1000000.ahci");
clk = clk_register_gate(NULL, "sysram0_clk", "ahb_clk", 0,
SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_SYSRAM0_CLK_ENB, 0,
@@ -803,10 +854,10 @@ void __init spear1340_clk_init(void)
clk_register_clkdev(clk, "adc_syn_clk", NULL);
clk_register_clkdev(clk1, "adc_syn_gclk", NULL);
- clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", 0,
- SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_ADC_CLK_ENB, 0,
- &_lock);
- clk_register_clkdev(clk, NULL, "adc_clk");
+ clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk",
+ CLK_SET_RATE_PARENT, SPEAR1340_PERIP1_CLK_ENB,
+ SPEAR1340_ADC_CLK_ENB, 0, &_lock);
+ clk_register_clkdev(clk, NULL, "e0080000.adc");
/* clock derived from apb clk */
clk = clk_register_gate(NULL, "ssp_clk", "apb_clk", 0,
@@ -827,12 +878,12 @@ void __init spear1340_clk_init(void)
clk = clk_register_gate(NULL, "i2s_play_clk", "apb_clk", 0,
SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_I2S_PLAY_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, NULL, "b2400000.i2s");
+ clk_register_clkdev(clk, NULL, "b2400000.i2s-play");
clk = clk_register_gate(NULL, "i2s_rec_clk", "apb_clk", 0,
SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_I2S_REC_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, NULL, "b2000000.i2s");
+ clk_register_clkdev(clk, NULL, "b2000000.i2s-rec");
clk = clk_register_gate(NULL, "kbd_clk", "apb_clk", 0,
SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_KBD_CLK_ENB, 0,
@@ -844,37 +895,37 @@ void __init spear1340_clk_init(void)
ARRAY_SIZE(gen_synth0_1_parents), 0, SPEAR1340_PLL_CFG,
SPEAR1340_GEN_SYNT0_1_CLK_SHIFT,
SPEAR1340_GEN_SYNT_CLK_MASK, 0, &_lock);
- clk_register_clkdev(clk, "gen_syn0_1_clk", NULL);
+ clk_register_clkdev(clk, "gen_syn0_1_mclk", NULL);
clk = clk_register_mux(NULL, "gen_syn2_3_mclk", gen_synth2_3_parents,
ARRAY_SIZE(gen_synth2_3_parents), 0, SPEAR1340_PLL_CFG,
SPEAR1340_GEN_SYNT2_3_CLK_SHIFT,
SPEAR1340_GEN_SYNT_CLK_MASK, 0, &_lock);
- clk_register_clkdev(clk, "gen_syn2_3_clk", NULL);
+ clk_register_clkdev(clk, "gen_syn2_3_mclk", NULL);
- clk = clk_register_frac("gen_syn0_clk", "gen_syn0_1_clk", 0,
+ clk = clk_register_frac("gen_syn0_clk", "gen_syn0_1_mclk", 0,
SPEAR1340_GEN_CLK_SYNT0, gen_rtbl, ARRAY_SIZE(gen_rtbl),
&_lock);
clk_register_clkdev(clk, "gen_syn0_clk", NULL);
- clk = clk_register_frac("gen_syn1_clk", "gen_syn0_1_clk", 0,
+ clk = clk_register_frac("gen_syn1_clk", "gen_syn0_1_mclk", 0,
SPEAR1340_GEN_CLK_SYNT1, gen_rtbl, ARRAY_SIZE(gen_rtbl),
&_lock);
clk_register_clkdev(clk, "gen_syn1_clk", NULL);
- clk = clk_register_frac("gen_syn2_clk", "gen_syn2_3_clk", 0,
+ clk = clk_register_frac("gen_syn2_clk", "gen_syn2_3_mclk", 0,
SPEAR1340_GEN_CLK_SYNT2, gen_rtbl, ARRAY_SIZE(gen_rtbl),
&_lock);
clk_register_clkdev(clk, "gen_syn2_clk", NULL);
- clk = clk_register_frac("gen_syn3_clk", "gen_syn2_3_clk", 0,
+ clk = clk_register_frac("gen_syn3_clk", "gen_syn2_3_mclk", 0,
SPEAR1340_GEN_CLK_SYNT3, gen_rtbl, ARRAY_SIZE(gen_rtbl),
&_lock);
clk_register_clkdev(clk, "gen_syn3_clk", NULL);
- clk = clk_register_gate(NULL, "mali_clk", "gen_syn3_clk", 0,
- SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_MALI_CLK_ENB, 0,
- &_lock);
+ clk = clk_register_gate(NULL, "mali_clk", "gen_syn3_clk",
+ CLK_SET_RATE_PARENT, SPEAR1340_PERIP3_CLK_ENB,
+ SPEAR1340_MALI_CLK_ENB, 0, &_lock);
clk_register_clkdev(clk, NULL, "mali");
clk = clk_register_gate(NULL, "cec0_clk", "ahb_clk", 0,
@@ -888,26 +939,26 @@ void __init spear1340_clk_init(void)
clk_register_clkdev(clk, NULL, "spear_cec.1");
clk = clk_register_mux(NULL, "spdif_out_mclk", spdif_out_parents,
- ARRAY_SIZE(spdif_out_parents), 0,
+ ARRAY_SIZE(spdif_out_parents), CLK_SET_RATE_PARENT,
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_SPDIF_OUT_CLK_SHIFT,
SPEAR1340_SPDIF_CLK_MASK, 0, &_lock);
clk_register_clkdev(clk, "spdif_out_mclk", NULL);
- clk = clk_register_gate(NULL, "spdif_out_clk", "spdif_out_mclk", 0,
- SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_SPDIF_OUT_CLK_ENB,
- 0, &_lock);
- clk_register_clkdev(clk, NULL, "spdif-out");
+ clk = clk_register_gate(NULL, "spdif_out_clk", "spdif_out_mclk",
+ CLK_SET_RATE_PARENT, SPEAR1340_PERIP3_CLK_ENB,
+ SPEAR1340_SPDIF_OUT_CLK_ENB, 0, &_lock);
+ clk_register_clkdev(clk, NULL, "d0000000.spdif-out");
clk = clk_register_mux(NULL, "spdif_in_mclk", spdif_in_parents,
- ARRAY_SIZE(spdif_in_parents), 0,
+ ARRAY_SIZE(spdif_in_parents), CLK_SET_RATE_PARENT,
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_SPDIF_IN_CLK_SHIFT,
SPEAR1340_SPDIF_CLK_MASK, 0, &_lock);
clk_register_clkdev(clk, "spdif_in_mclk", NULL);
- clk = clk_register_gate(NULL, "spdif_in_clk", "spdif_in_mclk", 0,
- SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_SPDIF_IN_CLK_ENB, 0,
- &_lock);
- clk_register_clkdev(clk, NULL, "spdif-in");
+ clk = clk_register_gate(NULL, "spdif_in_clk", "spdif_in_mclk",
+ CLK_SET_RATE_PARENT, SPEAR1340_PERIP3_CLK_ENB,
+ SPEAR1340_SPDIF_IN_CLK_ENB, 0, &_lock);
+ clk_register_clkdev(clk, NULL, "d0100000.spdif-in");
clk = clk_register_gate(NULL, "acp_clk", "acp_mclk", 0,
SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_ACP_CLK_ENB, 0,
@@ -917,7 +968,7 @@ void __init spear1340_clk_init(void)
clk = clk_register_gate(NULL, "plgpio_clk", "plgpio_mclk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PLGPIO_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, NULL, "plgpio");
+ clk_register_clkdev(clk, NULL, "e2800000.gpio");
clk = clk_register_gate(NULL, "video_dec_clk", "video_dec_mclk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_DEC_CLK_ENB,
@@ -937,25 +988,25 @@ void __init spear1340_clk_init(void)
clk = clk_register_gate(NULL, "cam0_clk", "cam0_mclk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM0_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, NULL, "spear_camif.0");
+ clk_register_clkdev(clk, NULL, "d0200000.cam0");
clk = clk_register_gate(NULL, "cam1_clk", "cam1_mclk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM1_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, NULL, "spear_camif.1");
+ clk_register_clkdev(clk, NULL, "d0300000.cam1");
clk = clk_register_gate(NULL, "cam2_clk", "cam2_mclk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM2_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, NULL, "spear_camif.2");
+ clk_register_clkdev(clk, NULL, "d0400000.cam2");
clk = clk_register_gate(NULL, "cam3_clk", "cam3_mclk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM3_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, NULL, "spear_camif.3");
+ clk_register_clkdev(clk, NULL, "d0500000.cam3");
- clk = clk_register_gate(NULL, "pwm_clk", "pwm_mclk", 0,
+ clk = clk_register_gate(NULL, "pwm_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PWM_CLK_ENB, 0,
&_lock);
- clk_register_clkdev(clk, NULL, "pwm");
+ clk_register_clkdev(clk, NULL, "e0180000.pwm");
}
diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c
index c3157454bb3..33d3ac588da 100644
--- a/drivers/clk/spear/spear3xx_clock.c
+++ b/drivers/clk/spear/spear3xx_clock.c
@@ -107,6 +107,12 @@ static struct pll_rate_tbl pll_rtbl[] = {
/* aux rate configuration table, in ascending order of rates */
static struct aux_rate_tbl aux_rtbl[] = {
/* For PLL1 = 332 MHz */
+ {.xscale = 1, .yscale = 81, .eq = 0}, /* 2.049 MHz */
+ {.xscale = 1, .yscale = 59, .eq = 0}, /* 2.822 MHz */
+ {.xscale = 2, .yscale = 81, .eq = 0}, /* 4.098 MHz */
+ {.xscale = 3, .yscale = 89, .eq = 0}, /* 5.644 MHz */
+ {.xscale = 4, .yscale = 81, .eq = 0}, /* 8.197 MHz */
+ {.xscale = 4, .yscale = 59, .eq = 0}, /* 11.254 MHz */
{.xscale = 2, .yscale = 27, .eq = 0}, /* 12.296 MHz */
{.xscale = 2, .yscale = 8, .eq = 0}, /* 41.5 MHz */
{.xscale = 2, .yscale = 4, .eq = 0}, /* 83 MHz */
@@ -157,6 +163,8 @@ static void __init spear300_clk_init(void)
1);
clk_register_clkdev(clk, NULL, "a0000000.kbd");
}
+#else
+static inline void spear300_clk_init(void) { }
#endif
/* array of all spear 310 clock lookups */
@@ -197,6 +205,8 @@ static void __init spear310_clk_init(void)
1);
clk_register_clkdev(clk, NULL, "b2200000.serial");
}
+#else
+static inline void spear310_clk_init(void) { }
#endif
/* array of all spear 320 clock lookups */
@@ -251,7 +261,7 @@ static void __init spear320_clk_init(void)
clk = clk_register_fixed_factor(NULL, "pwm_clk", "ras_ahb_clk", 0, 1,
1);
- clk_register_clkdev(clk, "pwm", NULL);
+ clk_register_clkdev(clk, NULL, "a8000000.pwm");
clk = clk_register_fixed_factor(NULL, "ssp1_clk", "ras_ahb_clk", 0, 1,
1);
@@ -271,26 +281,37 @@ static void __init spear320_clk_init(void)
clk = clk_register_fixed_factor(NULL, "i2s_clk", "ras_apb_clk", 0, 1,
1);
- clk_register_clkdev(clk, NULL, "i2s");
+ clk_register_clkdev(clk, NULL, "a9400000.i2s");
clk = clk_register_mux(NULL, "i2s_ref_clk", i2s_ref_parents,
- ARRAY_SIZE(i2s_ref_parents), 0, SPEAR320_CONTROL_REG,
- I2S_REF_PCLK_SHIFT, I2S_REF_PCLK_MASK, 0, &_lock);
+ ARRAY_SIZE(i2s_ref_parents), CLK_SET_RATE_PARENT,
+ SPEAR320_CONTROL_REG, I2S_REF_PCLK_SHIFT,
+ I2S_REF_PCLK_MASK, 0, &_lock);
clk_register_clkdev(clk, "i2s_ref_clk", NULL);
- clk = clk_register_fixed_factor(NULL, "i2s_sclk", "i2s_ref_clk", 0, 1,
+ clk = clk_register_fixed_factor(NULL, "i2s_sclk", "i2s_ref_clk",
+ CLK_SET_RATE_PARENT, 1,
4);
clk_register_clkdev(clk, "i2s_sclk", NULL);
+ clk = clk_register_fixed_factor(NULL, "macb1_clk", "ras_apb_clk", 0, 1,
+ 1);
+ clk_register_clkdev(clk, "hclk", "aa000000.eth");
+
+ clk = clk_register_fixed_factor(NULL, "macb2_clk", "ras_apb_clk", 0, 1,
+ 1);
+ clk_register_clkdev(clk, "hclk", "ab000000.eth");
+
clk = clk_register_mux(NULL, "rs485_clk", uartx_parents,
- ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG,
- SPEAR320_RS485_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0,
- &_lock);
+ ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT,
+ SPEAR320_EXT_CTRL_REG, SPEAR320_RS485_PCLK_SHIFT,
+ SPEAR320_UARTX_PCLK_MASK, 0, &_lock);
clk_register_clkdev(clk, NULL, "a9300000.serial");
clk = clk_register_mux(NULL, "sdhci_clk", sdhci_parents,
- ARRAY_SIZE(sdhci_parents), 0, SPEAR320_CONTROL_REG,
- SDHCI_PCLK_SHIFT, SDHCI_PCLK_MASK, 0, &_lock);
+ ARRAY_SIZE(sdhci_parents), CLK_SET_RATE_PARENT,
+ SPEAR320_CONTROL_REG, SDHCI_PCLK_SHIFT, SDHCI_PCLK_MASK,
+ 0, &_lock);
clk_register_clkdev(clk, NULL, "70000000.sdhci");
clk = clk_register_mux(NULL, "smii_pclk", smii0_parents,
@@ -302,49 +323,49 @@ static void __init spear320_clk_init(void)
clk_register_clkdev(clk, NULL, "smii");
clk = clk_register_mux(NULL, "uart1_clk", uartx_parents,
- ARRAY_SIZE(uartx_parents), 0, SPEAR320_CONTROL_REG,
- UART1_PCLK_SHIFT, UART1_PCLK_MASK, 0, &_lock);
+ ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT,
+ SPEAR320_CONTROL_REG, UART1_PCLK_SHIFT, UART1_PCLK_MASK,
+ 0, &_lock);
clk_register_clkdev(clk, NULL, "a3000000.serial");
clk = clk_register_mux(NULL, "uart2_clk", uartx_parents,
- ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG,
- SPEAR320_UART2_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0,
- &_lock);
+ ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT,
+ SPEAR320_EXT_CTRL_REG, SPEAR320_UART2_PCLK_SHIFT,
+ SPEAR320_UARTX_PCLK_MASK, 0, &_lock);
clk_register_clkdev(clk, NULL, "a4000000.serial");
clk = clk_register_mux(NULL, "uart3_clk", uartx_parents,
- ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG,
- SPEAR320_UART3_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0,
- &_lock);
+ ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT,
+ SPEAR320_EXT_CTRL_REG, SPEAR320_UART3_PCLK_SHIFT,
+ SPEAR320_UARTX_PCLK_MASK, 0, &_lock);
clk_register_clkdev(clk, NULL, "a9100000.serial");
clk = clk_register_mux(NULL, "uart4_clk", uartx_parents,
- ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG,
- SPEAR320_UART4_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0,
- &_lock);
+ ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT,
+ SPEAR320_EXT_CTRL_REG, SPEAR320_UART4_PCLK_SHIFT,
+ SPEAR320_UARTX_PCLK_MASK, 0, &_lock);
clk_register_clkdev(clk, NULL, "a9200000.serial");
clk = clk_register_mux(NULL, "uart5_clk", uartx_parents,
- ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG,
- SPEAR320_UART5_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0,
- &_lock);
+ ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT,
+ SPEAR320_EXT_CTRL_REG, SPEAR320_UART5_PCLK_SHIFT,
+ SPEAR320_UARTX_PCLK_MASK, 0, &_lock);
clk_register_clkdev(clk, NULL, "60000000.serial");
clk = clk_register_mux(NULL, "uart6_clk", uartx_parents,
- ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG,
- SPEAR320_UART6_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0,
- &_lock);
+ ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT,
+ SPEAR320_EXT_CTRL_REG, SPEAR320_UART6_PCLK_SHIFT,
+ SPEAR320_UARTX_PCLK_MASK, 0, &_lock);
clk_register_clkdev(clk, NULL, "60100000.serial");
}
+#else
+static inline void spear320_clk_init(void) { }
#endif
void __init spear3xx_clk_init(void)
{
struct clk *clk, *clk1;
- clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0);
- clk_register_clkdev(clk, "apb_pclk", NULL);
-
clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT,
32000);
clk_register_clkdev(clk, "osc_32k_clk", NULL);
@@ -380,7 +401,8 @@ void __init spear3xx_clk_init(void)
clk_register_clkdev(clk1, "pll2_clk", NULL);
/* clock derived from pll1 clk */
- clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", 0, 1, 1);
+ clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk",
+ CLK_SET_RATE_PARENT, 1, 1);
clk_register_clkdev(clk, "cpu_clk", NULL);
clk = clk_register_divider(NULL, "ahb_clk", "pll1_clk",
@@ -395,12 +417,14 @@ void __init spear3xx_clk_init(void)
clk_register_clkdev(clk1, "uart_syn_gclk", NULL);
clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents,
- ARRAY_SIZE(uart0_parents), 0, PERIP_CLK_CFG,
- UART_CLK_SHIFT, UART_CLK_MASK, 0, &_lock);
+ ARRAY_SIZE(uart0_parents), CLK_SET_RATE_PARENT,
+ PERIP_CLK_CFG, UART_CLK_SHIFT, UART_CLK_MASK, 0,
+ &_lock);
clk_register_clkdev(clk, "uart0_mclk", NULL);
- clk = clk_register_gate(NULL, "uart0", "uart0_mclk", 0, PERIP1_CLK_ENB,
- UART_CLK_ENB, 0, &_lock);
+ clk = clk_register_gate(NULL, "uart0", "uart0_mclk",
+ CLK_SET_RATE_PARENT, PERIP1_CLK_ENB, UART_CLK_ENB, 0,
+ &_lock);
clk_register_clkdev(clk, NULL, "d0000000.serial");
clk = clk_register_aux("firda_syn_clk", "firda_syn_gclk", "pll1_clk", 0,
@@ -410,40 +434,44 @@ void __init spear3xx_clk_init(void)
clk_register_clkdev(clk1, "firda_syn_gclk", NULL);
clk = clk_register_mux(NULL, "firda_mclk", firda_parents,
- ARRAY_SIZE(firda_parents), 0, PERIP_CLK_CFG,
- FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, &_lock);
+ ARRAY_SIZE(firda_parents), CLK_SET_RATE_PARENT,
+ PERIP_CLK_CFG, FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0,
+ &_lock);
clk_register_clkdev(clk, "firda_mclk", NULL);
- clk = clk_register_gate(NULL, "firda_clk", "firda_mclk", 0,
- PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0, &_lock);
+ clk = clk_register_gate(NULL, "firda_clk", "firda_mclk",
+ CLK_SET_RATE_PARENT, PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0,
+ &_lock);
clk_register_clkdev(clk, NULL, "firda");
/* gpt clocks */
clk_register_gpt("gpt0_syn_clk", "pll1_clk", 0, PRSC0_CLK_CFG, gpt_rtbl,
ARRAY_SIZE(gpt_rtbl), &_lock);
clk = clk_register_mux(NULL, "gpt0_clk", gpt0_parents,
- ARRAY_SIZE(gpt0_parents), 0, PERIP_CLK_CFG,
- GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
+ ARRAY_SIZE(gpt0_parents), CLK_SET_RATE_PARENT,
+ PERIP_CLK_CFG, GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
clk_register_clkdev(clk, NULL, "gpt0");
clk_register_gpt("gpt1_syn_clk", "pll1_clk", 0, PRSC1_CLK_CFG, gpt_rtbl,
ARRAY_SIZE(gpt_rtbl), &_lock);
clk = clk_register_mux(NULL, "gpt1_mclk", gpt1_parents,
- ARRAY_SIZE(gpt1_parents), 0, PERIP_CLK_CFG,
- GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
+ ARRAY_SIZE(gpt1_parents), CLK_SET_RATE_PARENT,
+ PERIP_CLK_CFG, GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
clk_register_clkdev(clk, "gpt1_mclk", NULL);
- clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0,
- PERIP1_CLK_ENB, GPT1_CLK_ENB, 0, &_lock);
+ clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk",
+ CLK_SET_RATE_PARENT, PERIP1_CLK_ENB, GPT1_CLK_ENB, 0,
+ &_lock);
clk_register_clkdev(clk, NULL, "gpt1");
clk_register_gpt("gpt2_syn_clk", "pll1_clk", 0, PRSC2_CLK_CFG, gpt_rtbl,
ARRAY_SIZE(gpt_rtbl), &_lock);
clk = clk_register_mux(NULL, "gpt2_mclk", gpt2_parents,
- ARRAY_SIZE(gpt2_parents), 0, PERIP_CLK_CFG,
- GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
+ ARRAY_SIZE(gpt2_parents), CLK_SET_RATE_PARENT,
+ PERIP_CLK_CFG, GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
clk_register_clkdev(clk, "gpt2_mclk", NULL);
- clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0,
- PERIP1_CLK_ENB, GPT2_CLK_ENB, 0, &_lock);
+ clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk",
+ CLK_SET_RATE_PARENT, PERIP1_CLK_ENB, GPT2_CLK_ENB, 0,
+ &_lock);
clk_register_clkdev(clk, NULL, "gpt2");
/* general synths clocks */
@@ -480,7 +508,9 @@ void __init spear3xx_clk_init(void)
/* clock derived from pll3 clk */
clk = clk_register_gate(NULL, "usbh_clk", "pll3_clk", 0, PERIP1_CLK_ENB,
USBH_CLK_ENB, 0, &_lock);
- clk_register_clkdev(clk, "usbh_clk", NULL);
+ clk_register_clkdev(clk, NULL, "e1800000.ehci");
+ clk_register_clkdev(clk, NULL, "e1900000.ohci");
+ clk_register_clkdev(clk, NULL, "e2100000.ohci");
clk = clk_register_fixed_factor(NULL, "usbh.0_clk", "usbh_clk", 0, 1,
1);
@@ -492,7 +522,7 @@ void __init spear3xx_clk_init(void)
clk = clk_register_gate(NULL, "usbd_clk", "pll3_clk", 0, PERIP1_CLK_ENB,
USBD_CLK_ENB, 0, &_lock);
- clk_register_clkdev(clk, NULL, "designware_udc");
+ clk_register_clkdev(clk, NULL, "e1100000.usbd");
/* clock derived from ahb clk */
clk = clk_register_fixed_factor(NULL, "ahbmult2_clk", "ahb_clk", 0, 2,
@@ -540,7 +570,7 @@ void __init spear3xx_clk_init(void)
/* clock derived from apb clk */
clk = clk_register_gate(NULL, "adc_clk", "apb_clk", 0, PERIP1_CLK_ENB,
ADC_CLK_ENB, 0, &_lock);
- clk_register_clkdev(clk, NULL, "adc");
+ clk_register_clkdev(clk, NULL, "d0080000.adc");
clk = clk_register_gate(NULL, "gpio0_clk", "apb_clk", 0, PERIP1_CLK_ENB,
GPIO_CLK_ENB, 0, &_lock);
@@ -579,20 +609,24 @@ void __init spear3xx_clk_init(void)
RAS_CLK_ENB, RAS_48M_CLK_ENB, 0, &_lock);
clk_register_clkdev(clk, "ras_pll3_clk", NULL);
- clk = clk_register_gate(NULL, "ras_syn0_gclk", "gen0_syn_gclk", 0,
- RAS_CLK_ENB, RAS_SYNT0_CLK_ENB, 0, &_lock);
+ clk = clk_register_gate(NULL, "ras_syn0_gclk", "gen0_syn_gclk",
+ CLK_SET_RATE_PARENT, RAS_CLK_ENB, RAS_SYNT0_CLK_ENB, 0,
+ &_lock);
clk_register_clkdev(clk, "ras_syn0_gclk", NULL);
- clk = clk_register_gate(NULL, "ras_syn1_gclk", "gen1_syn_gclk", 0,
- RAS_CLK_ENB, RAS_SYNT1_CLK_ENB, 0, &_lock);
+ clk = clk_register_gate(NULL, "ras_syn1_gclk", "gen1_syn_gclk",
+ CLK_SET_RATE_PARENT, RAS_CLK_ENB, RAS_SYNT1_CLK_ENB, 0,
+ &_lock);
clk_register_clkdev(clk, "ras_syn1_gclk", NULL);
- clk = clk_register_gate(NULL, "ras_syn2_gclk", "gen2_syn_gclk", 0,
- RAS_CLK_ENB, RAS_SYNT2_CLK_ENB, 0, &_lock);
+ clk = clk_register_gate(NULL, "ras_syn2_gclk", "gen2_syn_gclk",
+ CLK_SET_RATE_PARENT, RAS_CLK_ENB, RAS_SYNT2_CLK_ENB, 0,
+ &_lock);
clk_register_clkdev(clk, "ras_syn2_gclk", NULL);
- clk = clk_register_gate(NULL, "ras_syn3_gclk", "gen3_syn_gclk", 0,
- RAS_CLK_ENB, RAS_SYNT3_CLK_ENB, 0, &_lock);
+ clk = clk_register_gate(NULL, "ras_syn3_gclk", "gen3_syn_gclk",
+ CLK_SET_RATE_PARENT, RAS_CLK_ENB, RAS_SYNT3_CLK_ENB, 0,
+ &_lock);
clk_register_clkdev(clk, "ras_syn3_gclk", NULL);
if (of_machine_is_compatible("st,spear300"))
diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c
index a98d0866f54..e862a333ad3 100644
--- a/drivers/clk/spear/spear6xx_clock.c
+++ b/drivers/clk/spear/spear6xx_clock.c
@@ -92,6 +92,7 @@ static struct pll_rate_tbl pll_rtbl[] = {
/* aux rate configuration table, in ascending order of rates */
static struct aux_rate_tbl aux_rtbl[] = {
/* For PLL1 = 332 MHz */
+ {.xscale = 2, .yscale = 27, .eq = 0}, /* 12.296 MHz */
{.xscale = 2, .yscale = 8, .eq = 0}, /* 41.5 MHz */
{.xscale = 2, .yscale = 4, .eq = 0}, /* 83 MHz */
{.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */
@@ -118,9 +119,6 @@ void __init spear6xx_clk_init(void)
{
struct clk *clk, *clk1;
- clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0);
- clk_register_clkdev(clk, "apb_pclk", NULL);
-
clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT,
32000);
clk_register_clkdev(clk, "osc_32k_clk", NULL);
@@ -156,7 +154,8 @@ void __init spear6xx_clk_init(void)
clk_register_clkdev(clk, NULL, "wdt");
/* clock derived from pll1 clk */
- clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", 0, 1, 1);
+ clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk",
+ CLK_SET_RATE_PARENT, 1, 1);
clk_register_clkdev(clk, "cpu_clk", NULL);
clk = clk_register_divider(NULL, "ahb_clk", "pll1_clk",
@@ -261,11 +260,13 @@ void __init spear6xx_clk_init(void)
/* clock derived from pll3 clk */
clk = clk_register_gate(NULL, "usbh0_clk", "pll3_clk", 0,
PERIP1_CLK_ENB, USBH0_CLK_ENB, 0, &_lock);
- clk_register_clkdev(clk, NULL, "usbh.0_clk");
+ clk_register_clkdev(clk, NULL, "e1800000.ehci");
+ clk_register_clkdev(clk, NULL, "e1900000.ohci");
clk = clk_register_gate(NULL, "usbh1_clk", "pll3_clk", 0,
PERIP1_CLK_ENB, USBH1_CLK_ENB, 0, &_lock);
- clk_register_clkdev(clk, NULL, "usbh.1_clk");
+ clk_register_clkdev(clk, NULL, "e2000000.ehci");
+ clk_register_clkdev(clk, NULL, "e2100000.ohci");
clk = clk_register_gate(NULL, "usbd_clk", "pll3_clk", 0, PERIP1_CLK_ENB,
USBD_CLK_ENB, 0, &_lock);
diff --git a/drivers/clk/ux500/Makefile b/drivers/clk/ux500/Makefile
index 858fbfe6628..bcc0c11a507 100644
--- a/drivers/clk/ux500/Makefile
+++ b/drivers/clk/ux500/Makefile
@@ -10,3 +10,6 @@ obj-y += clk-prcmu.o
obj-y += u8500_clk.o
obj-y += u9540_clk.o
obj-y += u8540_clk.o
+
+# ABX500 clock driver
+obj-y += abx500-clk.o
diff --git a/drivers/clk/ux500/abx500-clk.c b/drivers/clk/ux500/abx500-clk.c
new file mode 100644
index 00000000000..e27c52317ff
--- /dev/null
+++ b/drivers/clk/ux500/abx500-clk.c
@@ -0,0 +1,73 @@
+/*
+ * abx500 clock implementation for ux500 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/err.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/abx500/ab8500.h>
+
+/* TODO: Add clock implementations here */
+
+
+/* Clock definitions for ab8500 */
+static int ab8500_reg_clks(struct device *dev)
+{
+ return 0;
+}
+
+/* Clock definitions for ab8540 */
+static int ab8540_reg_clks(struct device *dev)
+{
+ return 0;
+}
+
+/* Clock definitions for ab9540 */
+static int ab9540_reg_clks(struct device *dev)
+{
+ return 0;
+}
+
+static int __devinit abx500_clk_probe(struct platform_device *pdev)
+{
+ struct ab8500 *parent = dev_get_drvdata(pdev->dev.parent);
+ int ret;
+
+ if (is_ab8500(parent) || is_ab8505(parent)) {
+ ret = ab8500_reg_clks(&pdev->dev);
+ } else if (is_ab8540(parent)) {
+ ret = ab8540_reg_clks(&pdev->dev);
+ } else if (is_ab9540(parent)) {
+ ret = ab9540_reg_clks(&pdev->dev);
+ } else {
+ dev_err(&pdev->dev, "non supported plf id\n");
+ return -ENODEV;
+ }
+
+ return ret;
+}
+
+static struct platform_driver abx500_clk_driver = {
+ .driver = {
+ .name = "abx500-clk",
+ .owner = THIS_MODULE,
+ },
+ .probe = abx500_clk_probe,
+};
+
+static int __init abx500_clk_init(void)
+{
+ return platform_driver_register(&abx500_clk_driver);
+}
+
+arch_initcall(abx500_clk_init);
+
+MODULE_AUTHOR("Ulf Hansson <ulf.hansson@linaro.org");
+MODULE_DESCRIPTION("ABX500 clk driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c
index 930cdfeb47a..74faa7e3cf5 100644
--- a/drivers/clk/ux500/clk-prcmu.c
+++ b/drivers/clk/ux500/clk-prcmu.c
@@ -133,6 +133,40 @@ out_error:
hw->init->name);
}
+static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
+{
+ int err;
+ struct clk_prcmu *clk = to_clk_prcmu(hw);
+
+ err = prcmu_request_ape_opp_100_voltage(true);
+ if (err) {
+ pr_err("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n",
+ __func__, hw->init->name);
+ return err;
+ }
+
+ err = prcmu_request_clock(clk->cg_sel, true);
+ if (err)
+ prcmu_request_ape_opp_100_voltage(false);
+
+ return err;
+}
+
+static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw)
+{
+ struct clk_prcmu *clk = to_clk_prcmu(hw);
+
+ if (prcmu_request_clock(clk->cg_sel, false))
+ goto out_error;
+ if (prcmu_request_ape_opp_100_voltage(false))
+ goto out_error;
+ return;
+
+out_error:
+ pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
+ hw->init->name);
+}
+
static struct clk_ops clk_prcmu_scalable_ops = {
.prepare = clk_prcmu_prepare,
.unprepare = clk_prcmu_unprepare,
@@ -153,6 +187,13 @@ static struct clk_ops clk_prcmu_gate_ops = {
.recalc_rate = clk_prcmu_recalc_rate,
};
+static struct clk_ops clk_prcmu_scalable_rate_ops = {
+ .is_enabled = clk_prcmu_is_enabled,
+ .recalc_rate = clk_prcmu_recalc_rate,
+ .round_rate = clk_prcmu_round_rate,
+ .set_rate = clk_prcmu_set_rate,
+};
+
static struct clk_ops clk_prcmu_rate_ops = {
.is_enabled = clk_prcmu_is_enabled,
.recalc_rate = clk_prcmu_recalc_rate,
@@ -167,6 +208,17 @@ static struct clk_ops clk_prcmu_opp_gate_ops = {
.recalc_rate = clk_prcmu_recalc_rate,
};
+static struct clk_ops clk_prcmu_opp_volt_scalable_ops = {
+ .prepare = clk_prcmu_opp_volt_prepare,
+ .unprepare = clk_prcmu_opp_volt_unprepare,
+ .enable = clk_prcmu_enable,
+ .disable = clk_prcmu_disable,
+ .is_enabled = clk_prcmu_is_enabled,
+ .recalc_rate = clk_prcmu_recalc_rate,
+ .round_rate = clk_prcmu_round_rate,
+ .set_rate = clk_prcmu_set_rate,
+};
+
static struct clk *clk_reg_prcmu(const char *name,
const char *parent_name,
u8 cg_sel,
@@ -233,6 +285,16 @@ struct clk *clk_reg_prcmu_gate(const char *name,
&clk_prcmu_gate_ops);
}
+struct clk *clk_reg_prcmu_scalable_rate(const char *name,
+ const char *parent_name,
+ u8 cg_sel,
+ unsigned long rate,
+ unsigned long flags)
+{
+ return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
+ &clk_prcmu_scalable_rate_ops);
+}
+
struct clk *clk_reg_prcmu_rate(const char *name,
const char *parent_name,
u8 cg_sel,
@@ -250,3 +312,13 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name,
return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
&clk_prcmu_opp_gate_ops);
}
+
+struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name,
+ const char *parent_name,
+ u8 cg_sel,
+ unsigned long rate,
+ unsigned long flags)
+{
+ return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
+ &clk_prcmu_opp_volt_scalable_ops);
+}
diff --git a/drivers/clk/ux500/clk.h b/drivers/clk/ux500/clk.h
index 836d7d16751..c3e449169a8 100644
--- a/drivers/clk/ux500/clk.h
+++ b/drivers/clk/ux500/clk.h
@@ -35,6 +35,12 @@ struct clk *clk_reg_prcmu_gate(const char *name,
u8 cg_sel,
unsigned long flags);
+struct clk *clk_reg_prcmu_scalable_rate(const char *name,
+ const char *parent_name,
+ u8 cg_sel,
+ unsigned long rate,
+ unsigned long flags);
+
struct clk *clk_reg_prcmu_rate(const char *name,
const char *parent_name,
u8 cg_sel,
@@ -45,4 +51,10 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name,
u8 cg_sel,
unsigned long flags);
+struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name,
+ const char *parent_name,
+ u8 cg_sel,
+ unsigned long rate,
+ unsigned long flags);
+
#endif /* __UX500_CLK_H */
diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c
index ca4a25ed844..7d0e0258f20 100644
--- a/drivers/clk/ux500/u8500_clk.c
+++ b/drivers/clk/ux500/u8500_clk.c
@@ -40,7 +40,7 @@ void u8500_clk_init(void)
CLK_IS_ROOT|CLK_IGNORE_UNUSED,
32768);
clk_register_clkdev(clk, "clk32k", NULL);
- clk_register_clkdev(clk, NULL, "rtc-pl031");
+ clk_register_clkdev(clk, "apb_pclk", "rtc-pl031");
/* PRCMU clocks */
fw_version = prcmu_get_fw_version();
@@ -170,10 +170,11 @@ void u8500_clk_init(void)
clk_register_clkdev(clk, NULL, "mtu0");
clk_register_clkdev(clk, NULL, "mtu1");
- clk = clk_reg_prcmu_gate("sdmmcclk", NULL, PRCMU_SDMMCCLK, CLK_IS_ROOT);
+ clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL, PRCMU_SDMMCCLK,
+ 100000000,
+ CLK_IS_ROOT|CLK_SET_RATE_GATE);
clk_register_clkdev(clk, NULL, "sdmmc");
-
clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk",
PRCMU_PLLDSI, 0, CLK_SET_RATE_GATE);
clk_register_clkdev(clk, "dsihs2", "mcde");
@@ -205,16 +206,18 @@ void u8500_clk_init(void)
clk_register_clkdev(clk, "dsilp2", "dsilink.2");
clk_register_clkdev(clk, "dsilp2", "mcde");
- clk = clk_reg_prcmu_rate("smp_twd", NULL, PRCMU_ARMSS,
- CLK_IS_ROOT|CLK_GET_RATE_NOCACHE|
- CLK_IGNORE_UNUSED);
+ clk = clk_reg_prcmu_scalable_rate("armss", NULL,
+ PRCMU_ARMSS, 0, CLK_IS_ROOT|CLK_IGNORE_UNUSED);
+ clk_register_clkdev(clk, "armss", NULL);
+
+ clk = clk_register_fixed_factor(NULL, "smp_twd", "armss",
+ CLK_IGNORE_UNUSED, 1, 2);
clk_register_clkdev(clk, NULL, "smp_twd");
/*
* FIXME: Add special handled PRCMU clocks here:
- * 1. clk_arm, use PRCMU_ARMCLK.
- * 2. clkout0yuv, use PRCMU as parent + need regulator + pinctrl.
- * 3. ab9540_clkout1yuv, see clkout0yuv
+ * 1. clkout0yuv, use PRCMU as parent + need regulator + pinctrl.
+ * 2. ab9540_clkout1yuv, see clkout0yuv
*/
/* PRCC P-clocks */
@@ -228,10 +231,17 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE,
BIT(2), 0);
+ clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1");
+
clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE,
BIT(3), 0);
+ clk_register_clkdev(clk, "apb_pclk", "msp0");
+ clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.0");
+
clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE,
BIT(4), 0);
+ clk_register_clkdev(clk, "apb_pclk", "msp1");
+ clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.1");
clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE,
BIT(5), 0);
@@ -239,6 +249,7 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE,
BIT(6), 0);
+ clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2");
clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE,
BIT(7), 0);
@@ -246,6 +257,7 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE,
BIT(8), 0);
+ clk_register_clkdev(clk, "apb_pclk", "slimbus0");
clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE,
BIT(9), 0);
@@ -255,11 +267,16 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE,
BIT(10), 0);
+ clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4");
+
clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE,
BIT(11), 0);
+ clk_register_clkdev(clk, "apb_pclk", "msp3");
+ clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.3");
clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE,
BIT(0), 0);
+ clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3");
clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE,
BIT(1), 0);
@@ -279,12 +296,13 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE,
BIT(5), 0);
+ clk_register_clkdev(clk, "apb_pclk", "msp2");
+ clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.2");
clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE,
BIT(6), 0);
clk_register_clkdev(clk, "apb_pclk", "sdi1");
-
clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE,
BIT(7), 0);
clk_register_clkdev(clk, "apb_pclk", "sdi3");
@@ -308,7 +326,7 @@ void u8500_clk_init(void)
clk_register_clkdev(clk, NULL, "gpioblock1");
clk = clk_reg_prcc_pclk("p2_pclk12", "per2clk", U8500_CLKRST2_BASE,
- BIT(11), 0);
+ BIT(12), 0);
clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", U8500_CLKRST3_BASE,
BIT(0), 0);
@@ -316,10 +334,15 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE,
BIT(1), 0);
+ clk_register_clkdev(clk, "apb_pclk", "ssp0");
+
clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE,
BIT(2), 0);
+ clk_register_clkdev(clk, "apb_pclk", "ssp1");
+
clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE,
BIT(3), 0);
+ clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0");
clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE,
BIT(4), 0);
@@ -327,6 +350,8 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_pclk("p3_pclk5", "per3clk", U8500_CLKRST3_BASE,
BIT(5), 0);
+ clk_register_clkdev(clk, "apb_pclk", "ske");
+ clk_register_clkdev(clk, "apb_pclk", "nmk-ske-keypad");
clk = clk_reg_prcc_pclk("p3_pclk6", "per3clk", U8500_CLKRST3_BASE,
BIT(6), 0);
@@ -355,6 +380,7 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_pclk("p6_pclk0", "per6clk", U8500_CLKRST6_BASE,
BIT(0), 0);
+ clk_register_clkdev(clk, "apb_pclk", "rng");
clk = clk_reg_prcc_pclk("p6_pclk1", "per6clk", U8500_CLKRST6_BASE,
BIT(1), 0);
@@ -401,10 +427,17 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk",
U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "nmk-i2c.1");
+
clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk",
U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "msp0");
+ clk_register_clkdev(clk, NULL, "ux500-msp-i2s.0");
+
clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk",
U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "msp1");
+ clk_register_clkdev(clk, NULL, "ux500-msp-i2s.1");
clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk",
U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE);
@@ -412,17 +445,25 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk",
U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "nmk-i2c.2");
+
clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk",
- U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE);
- /* FIXME: Redefinition of BIT(3). */
+ U8500_CLKRST1_BASE, BIT(8), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "slimbus0");
+
clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk",
U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "nmk-i2c.4");
+
clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk",
U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "msp3");
+ clk_register_clkdev(clk, NULL, "ux500-msp-i2s.3");
/* Periph2 */
clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk",
U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "nmk-i2c.3");
clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk",
U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE);
@@ -430,6 +471,8 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk",
U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "msp2");
+ clk_register_clkdev(clk, NULL, "ux500-msp-i2s.2");
clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk",
U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE);
@@ -450,10 +493,15 @@ void u8500_clk_init(void)
/* Periph3 */
clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk",
U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "ssp0");
+
clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk",
U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "ssp1");
+
clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk",
U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "nmk-i2c.0");
clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk",
U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE);
@@ -461,6 +509,8 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_kclk("p3_ske_kclk", "rtc32k",
U8500_CLKRST3_BASE, BIT(5), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "ske");
+ clk_register_clkdev(clk, NULL, "nmk-ske-keypad");
clk = clk_reg_prcc_kclk("p3_uart2_kclk", "uartclk",
U8500_CLKRST3_BASE, BIT(6), CLK_SET_RATE_GATE);
@@ -473,5 +523,5 @@ void u8500_clk_init(void)
/* Periph6 */
clk = clk_reg_prcc_kclk("p3_rng_kclk", "rngclk",
U8500_CLKRST6_BASE, BIT(0), CLK_SET_RATE_GATE);
-
+ clk_register_clkdev(clk, NULL, "rng");
}
diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile
index c0a0f647879..ec3b88fe3e6 100644
--- a/drivers/clk/versatile/Makefile
+++ b/drivers/clk/versatile/Makefile
@@ -1,4 +1,7 @@
# Makefile for Versatile-specific clocks
obj-$(CONFIG_ICST) += clk-icst.o
obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o
+obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o
obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o
+obj-$(CONFIG_ARCH_VEXPRESS) += clk-vexpress.o
+obj-$(CONFIG_VEXPRESS_CONFIG) += clk-vexpress-osc.o
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c
index f555b50a5fa..67ccf4aa727 100644
--- a/drivers/clk/versatile/clk-icst.c
+++ b/drivers/clk/versatile/clk-icst.c
@@ -3,6 +3,12 @@
* We wrap the custom interface from <asm/hardware/icst.h> into the generic
* clock framework.
*
+ * Copyright (C) 2012 Linus Walleij
+ *
+ * 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.
+ *
* TODO: when all ARM reference designs are migrated to generic clocks, the
* ICST clock code from the ARM tree should probably be merged into this
* file.
@@ -11,33 +17,74 @@
#include <linux/clkdev.h>
#include <linux/err.h>
#include <linux/clk-provider.h>
+#include <linux/io.h>
#include "clk-icst.h"
/**
* struct clk_icst - ICST VCO clock wrapper
* @hw: corresponding clock hardware entry
+ * @vcoreg: VCO register address
+ * @lockreg: VCO lock register address
* @params: parameters for this ICST instance
* @rate: current rate
- * @setvco: function to commit ICST settings to hardware
*/
struct clk_icst {
struct clk_hw hw;
+ void __iomem *vcoreg;
+ void __iomem *lockreg;
const struct icst_params *params;
unsigned long rate;
- struct icst_vco (*getvco)(void);
- void (*setvco)(struct icst_vco);
};
#define to_icst(_hw) container_of(_hw, struct clk_icst, hw)
+/**
+ * vco_get() - get ICST VCO settings from a certain register
+ * @vcoreg: register containing the VCO settings
+ */
+static struct icst_vco vco_get(void __iomem *vcoreg)
+{
+ u32 val;
+ struct icst_vco vco;
+
+ val = readl(vcoreg);
+ vco.v = val & 0x1ff;
+ vco.r = (val >> 9) & 0x7f;
+ vco.s = (val >> 16) & 03;
+ return vco;
+}
+
+/**
+ * vco_set() - commit changes to an ICST VCO
+ * @locreg: register to poke to unlock the VCO for writing
+ * @vcoreg: register containing the VCO settings
+ * @vco: ICST VCO parameters to commit
+ */
+static void vco_set(void __iomem *lockreg,
+ void __iomem *vcoreg,
+ struct icst_vco vco)
+{
+ u32 val;
+
+ val = readl(vcoreg) & ~0x7ffff;
+ val |= vco.v | (vco.r << 9) | (vco.s << 16);
+
+ /* This magic unlocks the VCO so it can be controlled */
+ writel(0xa05f, lockreg);
+ writel(val, vcoreg);
+ /* This locks the VCO again */
+ writel(0, lockreg);
+}
+
+
static unsigned long icst_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_icst *icst = to_icst(hw);
struct icst_vco vco;
- vco = icst->getvco();
+ vco = vco_get(icst->vcoreg);
icst->rate = icst_hz(icst->params, vco);
return icst->rate;
}
@@ -60,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);
- icst->setvco(vco);
+ vco_set(icst->vcoreg, icst->lockreg, vco);
return 0;
}
@@ -70,8 +117,9 @@ static const struct clk_ops icst_ops = {
.set_rate = icst_set_rate,
};
-struct clk * __init icst_clk_register(struct device *dev,
- const struct clk_icst_desc *desc)
+struct clk *icst_clk_register(struct device *dev,
+ const struct clk_icst_desc *desc,
+ void __iomem *base)
{
struct clk *clk;
struct clk_icst *icst;
@@ -89,8 +137,8 @@ struct clk * __init icst_clk_register(struct device *dev,
init.num_parents = 0;
icst->hw.init = &init;
icst->params = desc->params;
- icst->getvco = desc->getvco;
- icst->setvco = desc->setvco;
+ icst->vcoreg = base + desc->vco_offset;
+ icst->lockreg = base + desc->lock_offset;
clk = clk_register(dev, &icst->hw);
if (IS_ERR(clk))
diff --git a/drivers/clk/versatile/clk-icst.h b/drivers/clk/versatile/clk-icst.h
index 71b4c56c141..dad51b6ffd0 100644
--- a/drivers/clk/versatile/clk-icst.h
+++ b/drivers/clk/versatile/clk-icst.h
@@ -1,10 +1,18 @@
#include <asm/hardware/icst.h>
+/**
+ * struct clk_icst_desc - descriptor for the ICST VCO
+ * @params: ICST parameters
+ * @vco_offset: offset to the ICST VCO from the provided memory base
+ * @lock_offset: offset to the ICST VCO locking register from the provided
+ * memory base
+ */
struct clk_icst_desc {
const struct icst_params *params;
- struct icst_vco (*getvco)(void);
- void (*setvco)(struct icst_vco);
+ u32 vco_offset;
+ u32 lock_offset;
};
struct clk *icst_clk_register(struct device *dev,
- const struct clk_icst_desc *desc);
+ const struct clk_icst_desc *desc,
+ void __iomem *base);
diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c
new file mode 100644
index 00000000000..369139af2a3
--- /dev/null
+++ b/drivers/clk/versatile/clk-impd1.c
@@ -0,0 +1,97 @@
+/*
+ * Clock driver for the ARM Integrator/IM-PD1 board
+ * Copyright (C) 2012 Linus Walleij
+ *
+ * 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/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_data/clk-integrator.h>
+
+#include <mach/impd1.h>
+
+#include "clk-icst.h"
+
+struct impd1_clk {
+ struct clk *vcoclk;
+ struct clk *uartclk;
+ struct clk_lookup *clks[3];
+};
+
+static struct impd1_clk impd1_clks[4];
+
+/*
+ * There are two VCO's on the IM-PD1 but only one is used by the
+ * kernel, that is why we are only implementing the control of
+ * IMPD1_OSC1 here.
+ */
+
+static const struct icst_params impd1_vco_params = {
+ .ref = 24000000, /* 24 MHz */
+ .vco_max = ICST525_VCO_MAX_3V,
+ .vco_min = ICST525_VCO_MIN,
+ .vd_min = 12,
+ .vd_max = 519,
+ .rd_min = 3,
+ .rd_max = 120,
+ .s2div = icst525_s2div,
+ .idx2s = icst525_idx2s,
+};
+
+static const struct clk_icst_desc impd1_icst1_desc = {
+ .params = &impd1_vco_params,
+ .vco_offset = IMPD1_OSC1,
+ .lock_offset = IMPD1_LOCK,
+};
+
+/**
+ * integrator_impd1_clk_init() - set up the integrator clock tree
+ * @base: base address of the logic module (LM)
+ * @id: the ID of this LM
+ */
+void integrator_impd1_clk_init(void __iomem *base, unsigned int id)
+{
+ struct impd1_clk *imc;
+ struct clk *clk;
+ int i;
+
+ if (id > 3) {
+ pr_crit("no more than 4 LMs can be attached\n");
+ return;
+ }
+ imc = &impd1_clks[id];
+
+ clk = icst_clk_register(NULL, &impd1_icst1_desc, base);
+ imc->vcoclk = clk;
+ imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id);
+
+ /* UART reference clock */
+ clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT,
+ 14745600);
+ imc->uartclk = clk;
+ imc->clks[1] = clkdev_alloc(clk, NULL, "lm%x:00100", id);
+ imc->clks[2] = clkdev_alloc(clk, NULL, "lm%x:00200", id);
+
+ for (i = 0; i < ARRAY_SIZE(imc->clks); i++)
+ clkdev_add(imc->clks[i]);
+}
+
+void integrator_impd1_clk_exit(unsigned int id)
+{
+ int i;
+ struct impd1_clk *imc;
+
+ if (id > 3)
+ return;
+ imc = &impd1_clks[id];
+
+ for (i = 0; i < ARRAY_SIZE(imc->clks); i++)
+ clkdev_drop(imc->clks[i]);
+ clk_unregister(imc->uartclk);
+ clk_unregister(imc->vcoclk);
+}
diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c
index a5053921bf7..08593b4ee2c 100644
--- a/drivers/clk/versatile/clk-integrator.c
+++ b/drivers/clk/versatile/clk-integrator.c
@@ -1,8 +1,16 @@
+/*
+ * Clock driver for the ARM Integrator/AP and Integrator/CP boards
+ * Copyright (C) 2012 Linus Walleij
+ *
+ * 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/clk.h>
#include <linux/clkdev.h>
#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/clk-provider.h>
+#include <linux/platform_data/clk-integrator.h>
#include <mach/hardware.h>
#include <mach/platform.h>
@@ -14,42 +22,6 @@
* Inspired by portions of:
* plat-versatile/clock.c and plat-versatile/include/plat/clock.h
*/
-#define CM_LOCK (__io_address(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET)
-#define CM_AUXOSC (__io_address(INTEGRATOR_HDR_BASE)+0x1c)
-
-/**
- * cp_auxvco_get() - get ICST VCO settings for the Integrator/CP
- * @vco: ICST VCO parameters to update with hardware status
- */
-static struct icst_vco cp_auxvco_get(void)
-{
- u32 val;
- struct icst_vco vco;
-
- val = readl(CM_AUXOSC);
- vco.v = val & 0x1ff;
- vco.r = (val >> 9) & 0x7f;
- vco.s = (val >> 16) & 03;
- return vco;
-}
-
-/**
- * cp_auxvco_set() - commit changes to Integrator/CP ICST VCO
- * @vco: ICST VCO parameters to commit
- */
-static void cp_auxvco_set(struct icst_vco vco)
-{
- u32 val;
-
- val = readl(CM_AUXOSC) & ~0x7ffff;
- val |= vco.v | (vco.r << 9) | (vco.s << 16);
-
- /* This magic unlocks the CM VCO so it can be controlled */
- writel(0xa05f, CM_LOCK);
- writel(val, CM_AUXOSC);
- /* This locks the CM again */
- writel(0, CM_LOCK);
-}
static const struct icst_params cp_auxvco_params = {
.ref = 24000000,
@@ -65,8 +37,8 @@ static const struct icst_params cp_auxvco_params = {
static const struct clk_icst_desc __initdata cp_icst_desc = {
.params = &cp_auxvco_params,
- .getvco = cp_auxvco_get,
- .setvco = cp_auxvco_set,
+ .vco_offset = 0x1c,
+ .lock_offset = INTEGRATOR_HDR_LOCK_OFFSET,
};
/*
@@ -106,6 +78,7 @@ void __init integrator_clk_init(bool is_cp)
clk_register_clkdev(clk, NULL, "sp804");
/* ICST VCO clock used on the Integrator/CP CLCD */
- clk = icst_clk_register(NULL, &cp_icst_desc);
+ clk = icst_clk_register(NULL, &cp_icst_desc,
+ __io_address(INTEGRATOR_HDR_BASE));
clk_register_clkdev(clk, NULL, "clcd");
}
diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c
index e21a99cef37..cda07e70a40 100644
--- a/drivers/clk/versatile/clk-realview.c
+++ b/drivers/clk/versatile/clk-realview.c
@@ -1,3 +1,11 @@
+/*
+ * Clock driver for the ARM RealView boards
+ * Copyright (C) 2012 Linus Walleij
+ *
+ * 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/clkdev.h>
#include <linux/err.h>
@@ -13,38 +21,6 @@
* Implementation of the ARM RealView clock trees.
*/
-static void __iomem *sys_lock;
-static void __iomem *sys_vcoreg;
-
-/**
- * realview_oscvco_get() - get ICST OSC settings for the RealView
- */
-static struct icst_vco realview_oscvco_get(void)
-{
- u32 val;
- struct icst_vco vco;
-
- val = readl(sys_vcoreg);
- vco.v = val & 0x1ff;
- vco.r = (val >> 9) & 0x7f;
- vco.s = (val >> 16) & 03;
- return vco;
-}
-
-static void realview_oscvco_set(struct icst_vco vco)
-{
- u32 val;
-
- val = readl(sys_vcoreg) & ~0x7ffff;
- val |= vco.v | (vco.r << 9) | (vco.s << 16);
-
- /* This magic unlocks the CM VCO so it can be controlled */
- writel(0xa05f, sys_lock);
- writel(val, sys_vcoreg);
- /* This locks the CM again */
- writel(0, sys_lock);
-}
-
static const struct icst_params realview_oscvco_params = {
.ref = 24000000,
.vco_max = ICST307_VCO_MAX,
@@ -57,10 +33,16 @@ static const struct icst_params realview_oscvco_params = {
.idx2s = icst307_idx2s,
};
-static const struct clk_icst_desc __initdata realview_icst_desc = {
+static const struct clk_icst_desc __initdata realview_osc0_desc = {
+ .params = &realview_oscvco_params,
+ .vco_offset = REALVIEW_SYS_OSC0_OFFSET,
+ .lock_offset = REALVIEW_SYS_LOCK_OFFSET,
+};
+
+static const struct clk_icst_desc __initdata realview_osc4_desc = {
.params = &realview_oscvco_params,
- .getvco = realview_oscvco_get,
- .setvco = realview_oscvco_set,
+ .vco_offset = REALVIEW_SYS_OSC4_OFFSET,
+ .lock_offset = REALVIEW_SYS_LOCK_OFFSET,
};
/*
@@ -70,13 +52,6 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176)
{
struct clk *clk;
- sys_lock = sysbase + REALVIEW_SYS_LOCK_OFFSET;
- if (is_pb1176)
- sys_vcoreg = sysbase + REALVIEW_SYS_OSC0_OFFSET;
- else
- sys_vcoreg = sysbase + REALVIEW_SYS_OSC4_OFFSET;
-
-
/* APB clock dummy */
clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0);
clk_register_clkdev(clk, "apb_pclk", NULL);
@@ -108,7 +83,11 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176)
clk_register_clkdev(clk, NULL, "sp804");
/* ICST VCO clock */
- clk = icst_clk_register(NULL, &realview_icst_desc);
+ if (is_pb1176)
+ clk = icst_clk_register(NULL, &realview_osc0_desc, sysbase);
+ else
+ clk = icst_clk_register(NULL, &realview_osc4_desc, sysbase);
+
clk_register_clkdev(clk, NULL, "dev:clcd");
clk_register_clkdev(clk, NULL, "issp:clcd");
}
diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c
new file mode 100644
index 00000000000..dcb6ae0a042
--- /dev/null
+++ b/drivers/clk/versatile/clk-vexpress-osc.c
@@ -0,0 +1,146 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#define pr_fmt(fmt) "vexpress-osc: " fmt
+
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/vexpress.h>
+
+struct vexpress_osc {
+ struct vexpress_config_func *func;
+ struct clk_hw hw;
+ unsigned long rate_min;
+ unsigned long rate_max;
+};
+
+#define to_vexpress_osc(osc) container_of(osc, struct vexpress_osc, hw)
+
+static unsigned long vexpress_osc_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct vexpress_osc *osc = to_vexpress_osc(hw);
+ u32 rate;
+
+ vexpress_config_read(osc->func, 0, &rate);
+
+ return rate;
+}
+
+static long vexpress_osc_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct vexpress_osc *osc = to_vexpress_osc(hw);
+
+ if (WARN_ON(osc->rate_min && rate < osc->rate_min))
+ rate = osc->rate_min;
+
+ if (WARN_ON(osc->rate_max && rate > osc->rate_max))
+ rate = osc->rate_max;
+
+ return rate;
+}
+
+static int vexpress_osc_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct vexpress_osc *osc = to_vexpress_osc(hw);
+
+ return vexpress_config_write(osc->func, 0, rate);
+}
+
+static struct clk_ops vexpress_osc_ops = {
+ .recalc_rate = vexpress_osc_recalc_rate,
+ .round_rate = vexpress_osc_round_rate,
+ .set_rate = vexpress_osc_set_rate,
+};
+
+
+struct clk * __init vexpress_osc_setup(struct device *dev)
+{
+ struct clk_init_data init;
+ struct vexpress_osc *osc = kzalloc(sizeof(*osc), GFP_KERNEL);
+
+ if (!osc)
+ return NULL;
+
+ osc->func = vexpress_config_func_get_by_dev(dev);
+ if (!osc->func) {
+ kfree(osc);
+ return NULL;
+ }
+
+ init.name = dev_name(dev);
+ init.ops = &vexpress_osc_ops;
+ init.flags = CLK_IS_ROOT;
+ init.num_parents = 0;
+ osc->hw.init = &init;
+
+ return clk_register(NULL, &osc->hw);
+}
+
+void __init vexpress_osc_of_setup(struct device_node *node)
+{
+ struct clk_init_data init;
+ struct vexpress_osc *osc;
+ struct clk *clk;
+ u32 range[2];
+
+ osc = kzalloc(sizeof(*osc), GFP_KERNEL);
+ if (!osc)
+ goto error;
+
+ osc->func = vexpress_config_func_get_by_node(node);
+ if (!osc->func) {
+ pr_err("Failed to obtain config func for node '%s'!\n",
+ node->name);
+ goto error;
+ }
+
+ if (of_property_read_u32_array(node, "freq-range", range,
+ ARRAY_SIZE(range)) == 0) {
+ osc->rate_min = range[0];
+ osc->rate_max = range[1];
+ }
+
+ of_property_read_string(node, "clock-output-names", &init.name);
+ if (!init.name)
+ init.name = node->name;
+
+ init.ops = &vexpress_osc_ops;
+ init.flags = CLK_IS_ROOT;
+ init.num_parents = 0;
+
+ osc->hw.init = &init;
+
+ clk = clk_register(NULL, &osc->hw);
+ if (IS_ERR(clk)) {
+ pr_err("Failed to register clock '%s'!\n", init.name);
+ goto error;
+ }
+
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+
+ pr_debug("Registered clock '%s'\n", init.name);
+
+ return;
+
+error:
+ if (osc->func)
+ vexpress_config_func_put(osc->func);
+ kfree(osc);
+}
diff --git a/drivers/clk/versatile/clk-vexpress.c b/drivers/clk/versatile/clk-vexpress.c
new file mode 100644
index 00000000000..c742ac7c60b
--- /dev/null
+++ b/drivers/clk/versatile/clk-vexpress.c
@@ -0,0 +1,142 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/vexpress.h>
+
+#include <asm/hardware/sp810.h>
+
+static struct clk *vexpress_sp810_timerclken[4];
+static DEFINE_SPINLOCK(vexpress_sp810_lock);
+
+static void __init vexpress_sp810_init(void __iomem *base)
+{
+ int i;
+
+ if (WARN_ON(!base))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++) {
+ char name[12];
+ const char *parents[] = {
+ "v2m:refclk32khz", /* REFCLK */
+ "v2m:refclk1mhz" /* TIMCLK */
+ };
+
+ snprintf(name, ARRAY_SIZE(name), "timerclken%d", i);
+
+ vexpress_sp810_timerclken[i] = clk_register_mux(NULL, name,
+ parents, 2, 0, base + SCCTRL,
+ SCCTRL_TIMERENnSEL_SHIFT(i), 1,
+ 0, &vexpress_sp810_lock);
+
+ if (WARN_ON(IS_ERR(vexpress_sp810_timerclken[i])))
+ break;
+ }
+}
+
+
+static const char * const vexpress_clk_24mhz_periphs[] __initconst = {
+ "mb:uart0", "mb:uart1", "mb:uart2", "mb:uart3",
+ "mb:mmci", "mb:kmi0", "mb:kmi1"
+};
+
+void __init vexpress_clk_init(void __iomem *sp810_base)
+{
+ struct clk *clk;
+ int i;
+
+ clk = clk_register_fixed_rate(NULL, "dummy_apb_pclk", NULL,
+ CLK_IS_ROOT, 0);
+ WARN_ON(clk_register_clkdev(clk, "apb_pclk", NULL));
+
+ clk = clk_register_fixed_rate(NULL, "v2m:clk_24mhz", NULL,
+ CLK_IS_ROOT, 24000000);
+ for (i = 0; i < ARRAY_SIZE(vexpress_clk_24mhz_periphs); i++)
+ WARN_ON(clk_register_clkdev(clk, NULL,
+ vexpress_clk_24mhz_periphs[i]));
+
+ clk = clk_register_fixed_rate(NULL, "v2m:refclk32khz", NULL,
+ CLK_IS_ROOT, 32768);
+ WARN_ON(clk_register_clkdev(clk, NULL, "v2m:wdt"));
+
+ clk = clk_register_fixed_rate(NULL, "v2m:refclk1mhz", NULL,
+ CLK_IS_ROOT, 1000000);
+
+ vexpress_sp810_init(sp810_base);
+
+ for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++)
+ WARN_ON(clk_set_parent(vexpress_sp810_timerclken[i], clk));
+
+ WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[0],
+ "v2m-timer0", "sp804"));
+ WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[1],
+ "v2m-timer1", "sp804"));
+}
+
+#if defined(CONFIG_OF)
+
+struct clk *vexpress_sp810_of_get(struct of_phandle_args *clkspec, void *data)
+{
+ if (WARN_ON(clkspec->args_count != 1 || clkspec->args[0] >
+ ARRAY_SIZE(vexpress_sp810_timerclken)))
+ return NULL;
+
+ return vexpress_sp810_timerclken[clkspec->args[0]];
+}
+
+static const __initconst struct of_device_id vexpress_fixed_clk_match[] = {
+ { .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
+ { .compatible = "arm,vexpress-osc", .data = vexpress_osc_of_setup, },
+ {}
+};
+
+void __init vexpress_clk_of_init(void)
+{
+ struct device_node *node;
+ struct clk *clk;
+ struct clk *refclk, *timclk;
+
+ of_clk_init(vexpress_fixed_clk_match);
+
+ node = of_find_compatible_node(NULL, NULL, "arm,sp810");
+ vexpress_sp810_init(of_iomap(node, 0));
+ of_clk_add_provider(node, vexpress_sp810_of_get, NULL);
+
+ /* Select "better" (faster) parent for SP804 timers */
+ refclk = of_clk_get_by_name(node, "refclk");
+ timclk = of_clk_get_by_name(node, "timclk");
+ if (!WARN_ON(IS_ERR(refclk) || IS_ERR(timclk))) {
+ int i = 0;
+
+ if (clk_get_rate(refclk) > clk_get_rate(timclk))
+ clk = refclk;
+ else
+ clk = timclk;
+
+ for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++)
+ WARN_ON(clk_set_parent(vexpress_sp810_timerclken[i],
+ clk));
+ }
+
+ WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[0],
+ "v2m-timer0", "sp804"));
+ WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[1],
+ "v2m-timer1", "sp804"));
+}
+
+#endif
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index 6b5cf02c35c..5d1b9268bca 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -233,16 +233,15 @@ fs_initcall(init_acpi_pm_clocksource);
*/
static int __init parse_pmtmr(char *arg)
{
- unsigned long base;
+ unsigned int base;
+ int ret;
- if (strict_strtoul(arg, 16, &base))
- return -EINVAL;
-#ifdef CONFIG_X86_64
- if (base > UINT_MAX)
- return -ERANGE;
-#endif
- printk(KERN_INFO "PMTMR IOPort override: 0x%04x -> 0x%04lx\n",
- pmtmr_ioport, base);
+ ret = kstrtouint(arg, 16, &base);
+ if (ret)
+ return ret;
+
+ pr_info("PMTMR IOPort override: 0x%04x -> 0x%04x\n", pmtmr_ioport,
+ base);
pmtmr_ioport = base;
return 1;
diff --git a/drivers/clocksource/arm_generic.c b/drivers/clocksource/arm_generic.c
index c4d9f9566c6..c210f4f1ecf 100644
--- a/drivers/clocksource/arm_generic.c
+++ b/drivers/clocksource/arm_generic.c
@@ -127,7 +127,7 @@ static void __init arch_timer_calibrate(void)
/* Cache the sched_clock multiplier to save a divide in the hot path. */
- sched_clock_mult = NSEC_PER_SEC / arch_timer_rate;
+ sched_clock_mult = DIV_ROUND_CLOSEST(NSEC_PER_SEC, arch_timer_rate);
pr_info("Architected local timer running at %u.%02uMHz.\n",
arch_timer_rate / 1000000, (arch_timer_rate / 10000) % 100);
@@ -221,10 +221,10 @@ int __init arm_generic_timer_init(void)
clocksource_register_hz(&clocksource_counter, arch_timer_rate);
/* Calibrate the delay loop directly */
- lpj_fine = arch_timer_rate / HZ;
+ lpj_fine = DIV_ROUND_CLOSEST(arch_timer_rate, HZ);
/* Immediately configure the timer on the boot CPU */
- arch_timer_setup(per_cpu_ptr(&arch_timer_evt, smp_processor_id()));
+ arch_timer_setup(this_cpu_ptr(&arch_timer_evt));
register_cpu_notifier(&arch_timer_cpu_nb);
diff --git a/drivers/clocksource/i8253.c b/drivers/clocksource/i8253.c
index e7cab2da910..14ee3efcc40 100644
--- a/drivers/clocksource/i8253.c
+++ b/drivers/clocksource/i8253.c
@@ -35,7 +35,7 @@ static cycle_t i8253_read(struct clocksource *cs)
raw_spin_lock_irqsave(&i8253_lock, flags);
/*
- * Although our caller may have the read side of xtime_lock,
+ * Although our caller may have the read side of jiffies_lock,
* this is now a seqlock, and we are cheating in this routine
* by having side effects on state that we cannot undo if
* there is a collision on the seqlock and our caller has to
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 5961e6415f0..a0b3661d90b 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -76,3 +76,10 @@ config ARM_EXYNOS5250_CPUFREQ
help
This adds the CPUFreq driver for Samsung EXYNOS5250
SoC.
+
+config ARM_SPEAR_CPUFREQ
+ bool "SPEAr CPUFreq support"
+ depends on PLAT_SPEAR
+ default y
+ help
+ This adds the CPUFreq driver support for SPEAr SOCs.
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 1bc90e1306d..1f254ec087c 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -7,8 +7,8 @@ obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o
obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o
obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o
-obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o
-obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o
+obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o cpufreq_governor.o
+obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o cpufreq_governor.o
# CPUfreq cross-arch helpers
obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o
@@ -50,6 +50,7 @@ obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ) += exynos4210-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ) += exynos4x12-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o
obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
+obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o
##################################################################################
# PowerPC platform drivers
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
index e9158278c71..52bf36d599f 100644
--- a/drivers/cpufreq/cpufreq-cpu0.c
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -174,7 +174,7 @@ static struct cpufreq_driver cpu0_cpufreq_driver = {
.attr = cpu0_cpufreq_attr,
};
-static int __devinit cpu0_cpufreq_driver_init(void)
+static int cpu0_cpufreq_driver_init(void)
{
struct device_node *np;
int ret;
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index fb8a5279c5d..1f93dbd7235 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -15,6 +15,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -127,7 +129,7 @@ static int __init init_cpufreq_transition_notifier_list(void)
pure_initcall(init_cpufreq_transition_notifier_list);
static int off __read_mostly;
-int cpufreq_disabled(void)
+static int cpufreq_disabled(void)
{
return off;
}
@@ -402,7 +404,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
static ssize_t store_##file_name \
(struct cpufreq_policy *policy, const char *buf, size_t count) \
{ \
- unsigned int ret = -EINVAL; \
+ unsigned int ret; \
struct cpufreq_policy new_policy; \
\
ret = cpufreq_get_policy(&new_policy, policy->cpu); \
@@ -445,7 +447,7 @@ static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
return sprintf(buf, "performance\n");
else if (policy->governor)
- return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n",
+ return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
policy->governor->name);
return -EINVAL;
}
@@ -457,7 +459,7 @@ static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
const char *buf, size_t count)
{
- unsigned int ret = -EINVAL;
+ unsigned int ret;
char str_governor[16];
struct cpufreq_policy new_policy;
@@ -491,7 +493,7 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
*/
static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
{
- return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", cpufreq_driver->name);
+ return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name);
}
/**
@@ -512,7 +514,7 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
- (CPUFREQ_NAME_LEN + 2)))
goto out;
- i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
+ i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
}
out:
i += sprintf(&buf[i], "\n");
@@ -581,7 +583,7 @@ static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
}
/**
- * show_scaling_driver - show the current cpufreq HW/BIOS limitation
+ * show_bios_limit - show the current cpufreq HW/BIOS limitation
*/
static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
{
@@ -1468,12 +1470,23 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int relation)
{
int retval = -EINVAL;
+ unsigned int old_target_freq = target_freq;
if (cpufreq_disabled())
return -ENODEV;
- pr_debug("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
- target_freq, relation);
+ /* Make sure that target_freq is within supported range */
+ if (target_freq > policy->max)
+ target_freq = policy->max;
+ if (target_freq < policy->min)
+ target_freq = policy->min;
+
+ pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
+ policy->cpu, target_freq, relation, old_target_freq);
+
+ if (target_freq == policy->cur)
+ return 0;
+
if (cpu_online(policy->cpu) && cpufreq_driver->target)
retval = cpufreq_driver->target(policy, target_freq, relation);
@@ -1509,12 +1522,14 @@ int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
{
int ret = 0;
+ if (!(cpu_online(cpu) && cpufreq_driver->getavg))
+ return 0;
+
policy = cpufreq_cpu_get(policy->cpu);
if (!policy)
return -EINVAL;
- if (cpu_online(cpu) && cpufreq_driver->getavg)
- ret = cpufreq_driver->getavg(policy, cpu);
+ ret = cpufreq_driver->getavg(policy, cpu);
cpufreq_cpu_put(policy);
return ret;
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index a152af7e199..64ef737e7e7 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -11,83 +11,30 @@
* published by the Free Software Foundation.
*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
#include <linux/cpufreq.h>
-#include <linux/cpu.h>
-#include <linux/jiffies.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
#include <linux/kernel_stat.h>
+#include <linux/kobject.h>
+#include <linux/module.h>
#include <linux/mutex.h>
-#include <linux/hrtimer.h>
-#include <linux/tick.h>
-#include <linux/ktime.h>
-#include <linux/sched.h>
+#include <linux/notifier.h>
+#include <linux/percpu-defs.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
-/*
- * dbs is used in this file as a shortform for demandbased switching
- * It helps to keep variable names smaller, simpler
- */
+#include "cpufreq_governor.h"
+/* Conservative governor macors */
#define DEF_FREQUENCY_UP_THRESHOLD (80)
#define DEF_FREQUENCY_DOWN_THRESHOLD (20)
-
-/*
- * The polling frequency of this governor depends on the capability of
- * the processor. Default polling frequency is 1000 times the transition
- * latency of the processor. The governor will work on any processor with
- * transition latency <= 10mS, using appropriate sampling
- * rate.
- * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL)
- * this governor will not work.
- * All times here are in uS.
- */
-#define MIN_SAMPLING_RATE_RATIO (2)
-
-static unsigned int min_sampling_rate;
-
-#define LATENCY_MULTIPLIER (1000)
-#define MIN_LATENCY_MULTIPLIER (100)
#define DEF_SAMPLING_DOWN_FACTOR (1)
#define MAX_SAMPLING_DOWN_FACTOR (10)
-#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000)
-
-static void do_dbs_timer(struct work_struct *work);
-
-struct cpu_dbs_info_s {
- cputime64_t prev_cpu_idle;
- cputime64_t prev_cpu_wall;
- cputime64_t prev_cpu_nice;
- struct cpufreq_policy *cur_policy;
- struct delayed_work work;
- unsigned int down_skip;
- unsigned int requested_freq;
- int cpu;
- unsigned int enable:1;
- /*
- * percpu mutex that serializes governor limit change with
- * do_dbs_timer invocation. We do not want do_dbs_timer to run
- * when user is changing the governor or limits.
- */
- struct mutex timer_mutex;
-};
-static DEFINE_PER_CPU(struct cpu_dbs_info_s, cs_cpu_dbs_info);
-static unsigned int dbs_enable; /* number of CPUs using this policy */
+static struct dbs_data cs_dbs_data;
+static DEFINE_PER_CPU(struct cs_cpu_dbs_info_s, cs_cpu_dbs_info);
-/*
- * dbs_mutex protects dbs_enable in governor start/stop.
- */
-static DEFINE_MUTEX(dbs_mutex);
-
-static struct dbs_tuners {
- unsigned int sampling_rate;
- unsigned int sampling_down_factor;
- unsigned int up_threshold;
- unsigned int down_threshold;
- unsigned int ignore_nice;
- unsigned int freq_step;
-} dbs_tuners_ins = {
+static struct cs_dbs_tuners cs_tuners = {
.up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
.down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD,
.sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR,
@@ -95,95 +42,121 @@ static struct dbs_tuners {
.freq_step = 5,
};
-static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
+/*
+ * Every sampling_rate, we check, if current idle time is less than 20%
+ * (default), then we try to increase frequency Every sampling_rate *
+ * sampling_down_factor, we check, if current idle time is more than 80%, then
+ * we try to decrease frequency
+ *
+ * Any frequency increase takes it to the maximum frequency. Frequency reduction
+ * happens at minimum steps of 5% (default) of maximum frequency
+ */
+static void cs_check_cpu(int cpu, unsigned int load)
{
- u64 idle_time;
- u64 cur_wall_time;
- u64 busy_time;
+ struct cs_cpu_dbs_info_s *dbs_info = &per_cpu(cs_cpu_dbs_info, cpu);
+ struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;
+ unsigned int freq_target;
+
+ /*
+ * break out if we 'cannot' reduce the speed as the user might
+ * want freq_step to be zero
+ */
+ if (cs_tuners.freq_step == 0)
+ return;
- cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
+ /* Check for frequency increase */
+ if (load > cs_tuners.up_threshold) {
+ dbs_info->down_skip = 0;
- busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER];
- busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM];
- busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ];
- busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ];
- busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
- busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE];
+ /* if we are already at full speed then break out early */
+ if (dbs_info->requested_freq == policy->max)
+ return;
- idle_time = cur_wall_time - busy_time;
- if (wall)
- *wall = jiffies_to_usecs(cur_wall_time);
+ freq_target = (cs_tuners.freq_step * policy->max) / 100;
- return jiffies_to_usecs(idle_time);
+ /* max freq cannot be less than 100. But who knows.... */
+ if (unlikely(freq_target == 0))
+ freq_target = 5;
+
+ dbs_info->requested_freq += freq_target;
+ if (dbs_info->requested_freq > policy->max)
+ dbs_info->requested_freq = policy->max;
+
+ __cpufreq_driver_target(policy, dbs_info->requested_freq,
+ CPUFREQ_RELATION_H);
+ return;
+ }
+
+ /*
+ * The optimal frequency is the frequency that is the lowest that can
+ * support the current CPU usage without triggering the up policy. To be
+ * safe, we focus 10 points under the threshold.
+ */
+ if (load < (cs_tuners.down_threshold - 10)) {
+ freq_target = (cs_tuners.freq_step * policy->max) / 100;
+
+ dbs_info->requested_freq -= freq_target;
+ if (dbs_info->requested_freq < policy->min)
+ dbs_info->requested_freq = policy->min;
+
+ /*
+ * if we cannot reduce the frequency anymore, break out early
+ */
+ if (policy->cur == policy->min)
+ return;
+
+ __cpufreq_driver_target(policy, dbs_info->requested_freq,
+ CPUFREQ_RELATION_H);
+ return;
+ }
}
-static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
+static void cs_dbs_timer(struct work_struct *work)
{
- u64 idle_time = get_cpu_idle_time_us(cpu, NULL);
+ struct cs_cpu_dbs_info_s *dbs_info = container_of(work,
+ struct cs_cpu_dbs_info_s, cdbs.work.work);
+ unsigned int cpu = dbs_info->cdbs.cpu;
+ int delay = delay_for_sampling_rate(cs_tuners.sampling_rate);
- if (idle_time == -1ULL)
- return get_cpu_idle_time_jiffy(cpu, wall);
- else
- idle_time += get_cpu_iowait_time_us(cpu, wall);
+ mutex_lock(&dbs_info->cdbs.timer_mutex);
- return idle_time;
+ dbs_check_cpu(&cs_dbs_data, cpu);
+
+ schedule_delayed_work_on(cpu, &dbs_info->cdbs.work, delay);
+ mutex_unlock(&dbs_info->cdbs.timer_mutex);
}
-/* keep track of frequency transitions */
-static int
-dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
- void *data)
+static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
+ void *data)
{
struct cpufreq_freqs *freq = data;
- struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cs_cpu_dbs_info,
- freq->cpu);
-
+ struct cs_cpu_dbs_info_s *dbs_info =
+ &per_cpu(cs_cpu_dbs_info, freq->cpu);
struct cpufreq_policy *policy;
- if (!this_dbs_info->enable)
+ if (!dbs_info->enable)
return 0;
- policy = this_dbs_info->cur_policy;
+ policy = dbs_info->cdbs.cur_policy;
/*
- * we only care if our internally tracked freq moves outside
- * the 'valid' ranges of freqency available to us otherwise
- * we do not change it
+ * we only care if our internally tracked freq moves outside the 'valid'
+ * ranges of freqency available to us otherwise we do not change it
*/
- if (this_dbs_info->requested_freq > policy->max
- || this_dbs_info->requested_freq < policy->min)
- this_dbs_info->requested_freq = freq->new;
+ if (dbs_info->requested_freq > policy->max
+ || dbs_info->requested_freq < policy->min)
+ dbs_info->requested_freq = freq->new;
return 0;
}
-static struct notifier_block dbs_cpufreq_notifier_block = {
- .notifier_call = dbs_cpufreq_notifier
-};
-
/************************** sysfs interface ************************/
static ssize_t show_sampling_rate_min(struct kobject *kobj,
struct attribute *attr, char *buf)
{
- return sprintf(buf, "%u\n", min_sampling_rate);
+ return sprintf(buf, "%u\n", cs_dbs_data.min_sampling_rate);
}
-define_one_global_ro(sampling_rate_min);
-
-/* cpufreq_conservative Governor Tunables */
-#define show_one(file_name, object) \
-static ssize_t show_##file_name \
-(struct kobject *kobj, struct attribute *attr, char *buf) \
-{ \
- return sprintf(buf, "%u\n", dbs_tuners_ins.object); \
-}
-show_one(sampling_rate, sampling_rate);
-show_one(sampling_down_factor, sampling_down_factor);
-show_one(up_threshold, up_threshold);
-show_one(down_threshold, down_threshold);
-show_one(ignore_nice_load, ignore_nice);
-show_one(freq_step, freq_step);
-
static ssize_t store_sampling_down_factor(struct kobject *a,
struct attribute *b,
const char *buf, size_t count)
@@ -195,7 +168,7 @@ static ssize_t store_sampling_down_factor(struct kobject *a,
if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1)
return -EINVAL;
- dbs_tuners_ins.sampling_down_factor = input;
+ cs_tuners.sampling_down_factor = input;
return count;
}
@@ -209,7 +182,7 @@ static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
if (ret != 1)
return -EINVAL;
- dbs_tuners_ins.sampling_rate = max(input, min_sampling_rate);
+ cs_tuners.sampling_rate = max(input, cs_dbs_data.min_sampling_rate);
return count;
}
@@ -220,11 +193,10 @@ static ssize_t store_up_threshold(struct kobject *a, struct attribute *b,
int ret;
ret = sscanf(buf, "%u", &input);
- if (ret != 1 || input > 100 ||
- input <= dbs_tuners_ins.down_threshold)
+ if (ret != 1 || input > 100 || input <= cs_tuners.down_threshold)
return -EINVAL;
- dbs_tuners_ins.up_threshold = input;
+ cs_tuners.up_threshold = input;
return count;
}
@@ -237,21 +209,19 @@ static ssize_t store_down_threshold(struct kobject *a, struct attribute *b,
/* cannot be lower than 11 otherwise freq will not fall */
if (ret != 1 || input < 11 || input > 100 ||
- input >= dbs_tuners_ins.up_threshold)
+ input >= cs_tuners.up_threshold)
return -EINVAL;
- dbs_tuners_ins.down_threshold = input;
+ cs_tuners.down_threshold = input;
return count;
}
static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,
const char *buf, size_t count)
{
- unsigned int input;
+ unsigned int input, j;
int ret;
- unsigned int j;
-
ret = sscanf(buf, "%u", &input);
if (ret != 1)
return -EINVAL;
@@ -259,19 +229,20 @@ static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,
if (input > 1)
input = 1;
- if (input == dbs_tuners_ins.ignore_nice) /* nothing to do */
+ if (input == cs_tuners.ignore_nice) /* nothing to do */
return count;
- dbs_tuners_ins.ignore_nice = input;
+ cs_tuners.ignore_nice = input;
/* we need to re-evaluate prev_cpu_idle */
for_each_online_cpu(j) {
- struct cpu_dbs_info_s *dbs_info;
+ struct cs_cpu_dbs_info_s *dbs_info;
dbs_info = &per_cpu(cs_cpu_dbs_info, j);
- dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
- &dbs_info->prev_cpu_wall);
- if (dbs_tuners_ins.ignore_nice)
- dbs_info->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE];
+ dbs_info->cdbs.prev_cpu_idle = get_cpu_idle_time(j,
+ &dbs_info->cdbs.prev_cpu_wall);
+ if (cs_tuners.ignore_nice)
+ dbs_info->cdbs.prev_cpu_nice =
+ kcpustat_cpu(j).cpustat[CPUTIME_NICE];
}
return count;
}
@@ -289,18 +260,28 @@ static ssize_t store_freq_step(struct kobject *a, struct attribute *b,
if (input > 100)
input = 100;
- /* no need to test here if freq_step is zero as the user might actually
- * want this, they would be crazy though :) */
- dbs_tuners_ins.freq_step = input;
+ /*
+ * no need to test here if freq_step is zero as the user might actually
+ * want this, they would be crazy though :)
+ */
+ cs_tuners.freq_step = input;
return count;
}
+show_one(cs, sampling_rate, sampling_rate);
+show_one(cs, sampling_down_factor, sampling_down_factor);
+show_one(cs, up_threshold, up_threshold);
+show_one(cs, down_threshold, down_threshold);
+show_one(cs, ignore_nice_load, ignore_nice);
+show_one(cs, freq_step, freq_step);
+
define_one_global_rw(sampling_rate);
define_one_global_rw(sampling_down_factor);
define_one_global_rw(up_threshold);
define_one_global_rw(down_threshold);
define_one_global_rw(ignore_nice_load);
define_one_global_rw(freq_step);
+define_one_global_ro(sampling_rate_min);
static struct attribute *dbs_attributes[] = {
&sampling_rate_min.attr,
@@ -313,283 +294,38 @@ static struct attribute *dbs_attributes[] = {
NULL
};
-static struct attribute_group dbs_attr_group = {
+static struct attribute_group cs_attr_group = {
.attrs = dbs_attributes,
.name = "conservative",
};
/************************** sysfs end ************************/
-static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
-{
- unsigned int load = 0;
- unsigned int max_load = 0;
- unsigned int freq_target;
-
- struct cpufreq_policy *policy;
- unsigned int j;
-
- policy = this_dbs_info->cur_policy;
-
- /*
- * Every sampling_rate, we check, if current idle time is less
- * than 20% (default), then we try to increase frequency
- * Every sampling_rate*sampling_down_factor, we check, if current
- * idle time is more than 80%, then we try to decrease frequency
- *
- * Any frequency increase takes it to the maximum frequency.
- * Frequency reduction happens at minimum steps of
- * 5% (default) of maximum frequency
- */
-
- /* Get Absolute Load */
- for_each_cpu(j, policy->cpus) {
- struct cpu_dbs_info_s *j_dbs_info;
- cputime64_t cur_wall_time, cur_idle_time;
- unsigned int idle_time, wall_time;
-
- j_dbs_info = &per_cpu(cs_cpu_dbs_info, j);
-
- cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
-
- wall_time = (unsigned int)
- (cur_wall_time - j_dbs_info->prev_cpu_wall);
- j_dbs_info->prev_cpu_wall = cur_wall_time;
-
- idle_time = (unsigned int)
- (cur_idle_time - j_dbs_info->prev_cpu_idle);
- j_dbs_info->prev_cpu_idle = cur_idle_time;
-
- if (dbs_tuners_ins.ignore_nice) {
- u64 cur_nice;
- unsigned long cur_nice_jiffies;
-
- cur_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE] -
- j_dbs_info->prev_cpu_nice;
- /*
- * Assumption: nice time between sampling periods will
- * be less than 2^32 jiffies for 32 bit sys
- */
- cur_nice_jiffies = (unsigned long)
- cputime64_to_jiffies64(cur_nice);
-
- j_dbs_info->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE];
- idle_time += jiffies_to_usecs(cur_nice_jiffies);
- }
+define_get_cpu_dbs_routines(cs_cpu_dbs_info);
- if (unlikely(!wall_time || wall_time < idle_time))
- continue;
-
- load = 100 * (wall_time - idle_time) / wall_time;
-
- if (load > max_load)
- max_load = load;
- }
-
- /*
- * break out if we 'cannot' reduce the speed as the user might
- * want freq_step to be zero
- */
- if (dbs_tuners_ins.freq_step == 0)
- return;
-
- /* Check for frequency increase */
- if (max_load > dbs_tuners_ins.up_threshold) {
- this_dbs_info->down_skip = 0;
-
- /* if we are already at full speed then break out early */
- if (this_dbs_info->requested_freq == policy->max)
- return;
-
- freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100;
-
- /* max freq cannot be less than 100. But who knows.... */
- if (unlikely(freq_target == 0))
- freq_target = 5;
-
- this_dbs_info->requested_freq += freq_target;
- if (this_dbs_info->requested_freq > policy->max)
- this_dbs_info->requested_freq = policy->max;
-
- __cpufreq_driver_target(policy, this_dbs_info->requested_freq,
- CPUFREQ_RELATION_H);
- return;
- }
-
- /*
- * The optimal frequency is the frequency that is the lowest that
- * can support the current CPU usage without triggering the up
- * policy. To be safe, we focus 10 points under the threshold.
- */
- if (max_load < (dbs_tuners_ins.down_threshold - 10)) {
- freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100;
-
- this_dbs_info->requested_freq -= freq_target;
- if (this_dbs_info->requested_freq < policy->min)
- this_dbs_info->requested_freq = policy->min;
-
- /*
- * if we cannot reduce the frequency anymore, break out early
- */
- if (policy->cur == policy->min)
- return;
-
- __cpufreq_driver_target(policy, this_dbs_info->requested_freq,
- CPUFREQ_RELATION_H);
- return;
- }
-}
-
-static void do_dbs_timer(struct work_struct *work)
-{
- struct cpu_dbs_info_s *dbs_info =
- container_of(work, struct cpu_dbs_info_s, work.work);
- unsigned int cpu = dbs_info->cpu;
-
- /* We want all CPUs to do sampling nearly on same jiffy */
- int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
-
- delay -= jiffies % delay;
-
- mutex_lock(&dbs_info->timer_mutex);
-
- dbs_check_cpu(dbs_info);
-
- schedule_delayed_work_on(cpu, &dbs_info->work, delay);
- mutex_unlock(&dbs_info->timer_mutex);
-}
-
-static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
-{
- /* We want all CPUs to do sampling nearly on same jiffy */
- int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
- delay -= jiffies % delay;
+static struct notifier_block cs_cpufreq_notifier_block = {
+ .notifier_call = dbs_cpufreq_notifier,
+};
- dbs_info->enable = 1;
- INIT_DEFERRABLE_WORK(&dbs_info->work, do_dbs_timer);
- schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay);
-}
+static struct cs_ops cs_ops = {
+ .notifier_block = &cs_cpufreq_notifier_block,
+};
-static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
-{
- dbs_info->enable = 0;
- cancel_delayed_work_sync(&dbs_info->work);
-}
+static struct dbs_data cs_dbs_data = {
+ .governor = GOV_CONSERVATIVE,
+ .attr_group = &cs_attr_group,
+ .tuners = &cs_tuners,
+ .get_cpu_cdbs = get_cpu_cdbs,
+ .get_cpu_dbs_info_s = get_cpu_dbs_info_s,
+ .gov_dbs_timer = cs_dbs_timer,
+ .gov_check_cpu = cs_check_cpu,
+ .gov_ops = &cs_ops,
+};
-static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+static int cs_cpufreq_governor_dbs(struct cpufreq_policy *policy,
unsigned int event)
{
- unsigned int cpu = policy->cpu;
- struct cpu_dbs_info_s *this_dbs_info;
- unsigned int j;
- int rc;
-
- this_dbs_info = &per_cpu(cs_cpu_dbs_info, cpu);
-
- switch (event) {
- case CPUFREQ_GOV_START:
- if ((!cpu_online(cpu)) || (!policy->cur))
- return -EINVAL;
-
- mutex_lock(&dbs_mutex);
-
- for_each_cpu(j, policy->cpus) {
- struct cpu_dbs_info_s *j_dbs_info;
- j_dbs_info = &per_cpu(cs_cpu_dbs_info, j);
- j_dbs_info->cur_policy = policy;
-
- j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
- &j_dbs_info->prev_cpu_wall);
- if (dbs_tuners_ins.ignore_nice)
- j_dbs_info->prev_cpu_nice =
- kcpustat_cpu(j).cpustat[CPUTIME_NICE];
- }
- this_dbs_info->cpu = cpu;
- this_dbs_info->down_skip = 0;
- this_dbs_info->requested_freq = policy->cur;
-
- mutex_init(&this_dbs_info->timer_mutex);
- dbs_enable++;
- /*
- * Start the timerschedule work, when this governor
- * is used for first time
- */
- if (dbs_enable == 1) {
- unsigned int latency;
- /* policy latency is in nS. Convert it to uS first */
- latency = policy->cpuinfo.transition_latency / 1000;
- if (latency == 0)
- latency = 1;
-
- rc = sysfs_create_group(cpufreq_global_kobject,
- &dbs_attr_group);
- if (rc) {
- mutex_unlock(&dbs_mutex);
- return rc;
- }
-
- /*
- * conservative does not implement micro like ondemand
- * governor, thus we are bound to jiffes/HZ
- */
- min_sampling_rate =
- MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10);
- /* Bring kernel and HW constraints together */
- min_sampling_rate = max(min_sampling_rate,
- MIN_LATENCY_MULTIPLIER * latency);
- dbs_tuners_ins.sampling_rate =
- max(min_sampling_rate,
- latency * LATENCY_MULTIPLIER);
-
- cpufreq_register_notifier(
- &dbs_cpufreq_notifier_block,
- CPUFREQ_TRANSITION_NOTIFIER);
- }
- mutex_unlock(&dbs_mutex);
-
- dbs_timer_init(this_dbs_info);
-
- break;
-
- case CPUFREQ_GOV_STOP:
- dbs_timer_exit(this_dbs_info);
-
- mutex_lock(&dbs_mutex);
- dbs_enable--;
- mutex_destroy(&this_dbs_info->timer_mutex);
-
- /*
- * Stop the timerschedule work, when this governor
- * is used for first time
- */
- if (dbs_enable == 0)
- cpufreq_unregister_notifier(
- &dbs_cpufreq_notifier_block,
- CPUFREQ_TRANSITION_NOTIFIER);
-
- mutex_unlock(&dbs_mutex);
- if (!dbs_enable)
- sysfs_remove_group(cpufreq_global_kobject,
- &dbs_attr_group);
-
- break;
-
- case CPUFREQ_GOV_LIMITS:
- mutex_lock(&this_dbs_info->timer_mutex);
- if (policy->max < this_dbs_info->cur_policy->cur)
- __cpufreq_driver_target(
- this_dbs_info->cur_policy,
- policy->max, CPUFREQ_RELATION_H);
- else if (policy->min > this_dbs_info->cur_policy->cur)
- __cpufreq_driver_target(
- this_dbs_info->cur_policy,
- policy->min, CPUFREQ_RELATION_L);
- dbs_check_cpu(this_dbs_info);
- mutex_unlock(&this_dbs_info->timer_mutex);
-
- break;
- }
- return 0;
+ return cpufreq_governor_dbs(&cs_dbs_data, policy, event);
}
#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
@@ -597,13 +333,14 @@ static
#endif
struct cpufreq_governor cpufreq_gov_conservative = {
.name = "conservative",
- .governor = cpufreq_governor_dbs,
+ .governor = cs_cpufreq_governor_dbs,
.max_transition_latency = TRANSITION_LATENCY_LIMIT,
.owner = THIS_MODULE,
};
static int __init cpufreq_gov_dbs_init(void)
{
+ mutex_init(&cs_dbs_data.mutex);
return cpufreq_register_governor(&cpufreq_gov_conservative);
}
@@ -612,7 +349,6 @@ static void __exit cpufreq_gov_dbs_exit(void)
cpufreq_unregister_governor(&cpufreq_gov_conservative);
}
-
MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
MODULE_DESCRIPTION("'cpufreq_conservative' - A dynamic cpufreq governor for "
"Low Latency Frequency Transition capable processors "
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
new file mode 100644
index 00000000000..6c5f1d383cd
--- /dev/null
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -0,0 +1,318 @@
+/*
+ * drivers/cpufreq/cpufreq_governor.c
+ *
+ * CPUFREQ governors common code
+ *
+ * Copyright (C) 2001 Russell King
+ * (C) 2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
+ * (C) 2003 Jun Nakajima <jun.nakajima@intel.com>
+ * (C) 2009 Alexander Clouter <alex@digriz.org.uk>
+ * (c) 2012 Viresh Kumar <viresh.kumar@linaro.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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <asm/cputime.h>
+#include <linux/cpufreq.h>
+#include <linux/cpumask.h>
+#include <linux/export.h>
+#include <linux/kernel_stat.h>
+#include <linux/mutex.h>
+#include <linux/tick.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+#include "cpufreq_governor.h"
+
+static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
+{
+ u64 idle_time;
+ u64 cur_wall_time;
+ u64 busy_time;
+
+ cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
+
+ busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER];
+ busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM];
+ busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ];
+ busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ];
+ busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
+ busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE];
+
+ idle_time = cur_wall_time - busy_time;
+ if (wall)
+ *wall = cputime_to_usecs(cur_wall_time);
+
+ return cputime_to_usecs(idle_time);
+}
+
+u64 get_cpu_idle_time(unsigned int cpu, u64 *wall)
+{
+ u64 idle_time = get_cpu_idle_time_us(cpu, NULL);
+
+ if (idle_time == -1ULL)
+ return get_cpu_idle_time_jiffy(cpu, wall);
+ else
+ idle_time += get_cpu_iowait_time_us(cpu, wall);
+
+ return idle_time;
+}
+EXPORT_SYMBOL_GPL(get_cpu_idle_time);
+
+void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
+{
+ struct cpu_dbs_common_info *cdbs = dbs_data->get_cpu_cdbs(cpu);
+ struct od_dbs_tuners *od_tuners = dbs_data->tuners;
+ struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
+ struct cpufreq_policy *policy;
+ unsigned int max_load = 0;
+ unsigned int ignore_nice;
+ unsigned int j;
+
+ if (dbs_data->governor == GOV_ONDEMAND)
+ ignore_nice = od_tuners->ignore_nice;
+ else
+ ignore_nice = cs_tuners->ignore_nice;
+
+ policy = cdbs->cur_policy;
+
+ /* Get Absolute Load (in terms of freq for ondemand gov) */
+ for_each_cpu(j, policy->cpus) {
+ struct cpu_dbs_common_info *j_cdbs;
+ u64 cur_wall_time, cur_idle_time, cur_iowait_time;
+ unsigned int idle_time, wall_time, iowait_time;
+ unsigned int load;
+
+ j_cdbs = dbs_data->get_cpu_cdbs(j);
+
+ cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
+
+ wall_time = (unsigned int)
+ (cur_wall_time - j_cdbs->prev_cpu_wall);
+ j_cdbs->prev_cpu_wall = cur_wall_time;
+
+ idle_time = (unsigned int)
+ (cur_idle_time - j_cdbs->prev_cpu_idle);
+ j_cdbs->prev_cpu_idle = cur_idle_time;
+
+ if (ignore_nice) {
+ u64 cur_nice;
+ unsigned long cur_nice_jiffies;
+
+ cur_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE] -
+ cdbs->prev_cpu_nice;
+ /*
+ * Assumption: nice time between sampling periods will
+ * be less than 2^32 jiffies for 32 bit sys
+ */
+ cur_nice_jiffies = (unsigned long)
+ cputime64_to_jiffies64(cur_nice);
+
+ cdbs->prev_cpu_nice =
+ kcpustat_cpu(j).cpustat[CPUTIME_NICE];
+ idle_time += jiffies_to_usecs(cur_nice_jiffies);
+ }
+
+ if (dbs_data->governor == GOV_ONDEMAND) {
+ struct od_cpu_dbs_info_s *od_j_dbs_info =
+ dbs_data->get_cpu_dbs_info_s(cpu);
+
+ cur_iowait_time = get_cpu_iowait_time_us(j,
+ &cur_wall_time);
+ if (cur_iowait_time == -1ULL)
+ cur_iowait_time = 0;
+
+ iowait_time = (unsigned int) (cur_iowait_time -
+ od_j_dbs_info->prev_cpu_iowait);
+ od_j_dbs_info->prev_cpu_iowait = cur_iowait_time;
+
+ /*
+ * For the purpose of ondemand, waiting for disk IO is
+ * an indication that you're performance critical, and
+ * not that the system is actually idle. So subtract the
+ * iowait time from the cpu idle time.
+ */
+ if (od_tuners->io_is_busy && idle_time >= iowait_time)
+ idle_time -= iowait_time;
+ }
+
+ if (unlikely(!wall_time || wall_time < idle_time))
+ continue;
+
+ load = 100 * (wall_time - idle_time) / wall_time;
+
+ if (dbs_data->governor == GOV_ONDEMAND) {
+ int freq_avg = __cpufreq_driver_getavg(policy, j);
+ if (freq_avg <= 0)
+ freq_avg = policy->cur;
+
+ load *= freq_avg;
+ }
+
+ if (load > max_load)
+ max_load = load;
+ }
+
+ dbs_data->gov_check_cpu(cpu, max_load);
+}
+EXPORT_SYMBOL_GPL(dbs_check_cpu);
+
+static inline void dbs_timer_init(struct dbs_data *dbs_data,
+ struct cpu_dbs_common_info *cdbs, unsigned int sampling_rate)
+{
+ int delay = delay_for_sampling_rate(sampling_rate);
+
+ INIT_DEFERRABLE_WORK(&cdbs->work, dbs_data->gov_dbs_timer);
+ schedule_delayed_work_on(cdbs->cpu, &cdbs->work, delay);
+}
+
+static inline void dbs_timer_exit(struct cpu_dbs_common_info *cdbs)
+{
+ cancel_delayed_work_sync(&cdbs->work);
+}
+
+int cpufreq_governor_dbs(struct dbs_data *dbs_data,
+ struct cpufreq_policy *policy, unsigned int event)
+{
+ struct od_cpu_dbs_info_s *od_dbs_info = NULL;
+ struct cs_cpu_dbs_info_s *cs_dbs_info = NULL;
+ struct od_dbs_tuners *od_tuners = dbs_data->tuners;
+ struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
+ struct cpu_dbs_common_info *cpu_cdbs;
+ unsigned int *sampling_rate, latency, ignore_nice, j, cpu = policy->cpu;
+ int rc;
+
+ cpu_cdbs = dbs_data->get_cpu_cdbs(cpu);
+
+ if (dbs_data->governor == GOV_CONSERVATIVE) {
+ cs_dbs_info = dbs_data->get_cpu_dbs_info_s(cpu);
+ sampling_rate = &cs_tuners->sampling_rate;
+ ignore_nice = cs_tuners->ignore_nice;
+ } else {
+ od_dbs_info = dbs_data->get_cpu_dbs_info_s(cpu);
+ sampling_rate = &od_tuners->sampling_rate;
+ ignore_nice = od_tuners->ignore_nice;
+ }
+
+ switch (event) {
+ case CPUFREQ_GOV_START:
+ if ((!cpu_online(cpu)) || (!policy->cur))
+ return -EINVAL;
+
+ mutex_lock(&dbs_data->mutex);
+
+ dbs_data->enable++;
+ cpu_cdbs->cpu = cpu;
+ for_each_cpu(j, policy->cpus) {
+ struct cpu_dbs_common_info *j_cdbs;
+ j_cdbs = dbs_data->get_cpu_cdbs(j);
+
+ j_cdbs->cur_policy = policy;
+ j_cdbs->prev_cpu_idle = get_cpu_idle_time(j,
+ &j_cdbs->prev_cpu_wall);
+ if (ignore_nice)
+ j_cdbs->prev_cpu_nice =
+ kcpustat_cpu(j).cpustat[CPUTIME_NICE];
+ }
+
+ /*
+ * Start the timerschedule work, when this governor is used for
+ * first time
+ */
+ if (dbs_data->enable != 1)
+ goto second_time;
+
+ rc = sysfs_create_group(cpufreq_global_kobject,
+ dbs_data->attr_group);
+ if (rc) {
+ mutex_unlock(&dbs_data->mutex);
+ return rc;
+ }
+
+ /* policy latency is in nS. Convert it to uS first */
+ latency = policy->cpuinfo.transition_latency / 1000;
+ if (latency == 0)
+ latency = 1;
+
+ /*
+ * conservative does not implement micro like ondemand
+ * governor, thus we are bound to jiffes/HZ
+ */
+ if (dbs_data->governor == GOV_CONSERVATIVE) {
+ struct cs_ops *ops = dbs_data->gov_ops;
+
+ cpufreq_register_notifier(ops->notifier_block,
+ CPUFREQ_TRANSITION_NOTIFIER);
+
+ dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO *
+ jiffies_to_usecs(10);
+ } else {
+ struct od_ops *ops = dbs_data->gov_ops;
+
+ od_tuners->io_is_busy = ops->io_busy();
+ }
+
+ /* Bring kernel and HW constraints together */
+ dbs_data->min_sampling_rate = max(dbs_data->min_sampling_rate,
+ MIN_LATENCY_MULTIPLIER * latency);
+ *sampling_rate = max(dbs_data->min_sampling_rate, latency *
+ LATENCY_MULTIPLIER);
+
+second_time:
+ if (dbs_data->governor == GOV_CONSERVATIVE) {
+ cs_dbs_info->down_skip = 0;
+ cs_dbs_info->enable = 1;
+ cs_dbs_info->requested_freq = policy->cur;
+ } else {
+ struct od_ops *ops = dbs_data->gov_ops;
+ od_dbs_info->rate_mult = 1;
+ od_dbs_info->sample_type = OD_NORMAL_SAMPLE;
+ ops->powersave_bias_init_cpu(cpu);
+ }
+ mutex_unlock(&dbs_data->mutex);
+
+ mutex_init(&cpu_cdbs->timer_mutex);
+ dbs_timer_init(dbs_data, cpu_cdbs, *sampling_rate);
+ break;
+
+ case CPUFREQ_GOV_STOP:
+ if (dbs_data->governor == GOV_CONSERVATIVE)
+ cs_dbs_info->enable = 0;
+
+ dbs_timer_exit(cpu_cdbs);
+
+ mutex_lock(&dbs_data->mutex);
+ mutex_destroy(&cpu_cdbs->timer_mutex);
+ dbs_data->enable--;
+ if (!dbs_data->enable) {
+ struct cs_ops *ops = dbs_data->gov_ops;
+
+ sysfs_remove_group(cpufreq_global_kobject,
+ dbs_data->attr_group);
+ if (dbs_data->governor == GOV_CONSERVATIVE)
+ cpufreq_unregister_notifier(ops->notifier_block,
+ CPUFREQ_TRANSITION_NOTIFIER);
+ }
+ mutex_unlock(&dbs_data->mutex);
+
+ break;
+
+ case CPUFREQ_GOV_LIMITS:
+ mutex_lock(&cpu_cdbs->timer_mutex);
+ if (policy->max < cpu_cdbs->cur_policy->cur)
+ __cpufreq_driver_target(cpu_cdbs->cur_policy,
+ policy->max, CPUFREQ_RELATION_H);
+ else if (policy->min > cpu_cdbs->cur_policy->cur)
+ __cpufreq_driver_target(cpu_cdbs->cur_policy,
+ policy->min, CPUFREQ_RELATION_L);
+ dbs_check_cpu(dbs_data, cpu);
+ mutex_unlock(&cpu_cdbs->timer_mutex);
+ break;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cpufreq_governor_dbs);
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
new file mode 100644
index 00000000000..f6616540c53
--- /dev/null
+++ b/drivers/cpufreq/cpufreq_governor.h
@@ -0,0 +1,176 @@
+/*
+ * drivers/cpufreq/cpufreq_governor.h
+ *
+ * Header file for CPUFreq governors common code
+ *
+ * Copyright (C) 2001 Russell King
+ * (C) 2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
+ * (C) 2003 Jun Nakajima <jun.nakajima@intel.com>
+ * (C) 2009 Alexander Clouter <alex@digriz.org.uk>
+ * (c) 2012 Viresh Kumar <viresh.kumar@linaro.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 _CPUFREQ_GOVERNER_H
+#define _CPUFREQ_GOVERNER_H
+
+#include <linux/cpufreq.h>
+#include <linux/kobject.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/sysfs.h>
+
+/*
+ * The polling frequency depends on the capability of the processor. Default
+ * polling frequency is 1000 times the transition latency of the processor. The
+ * governor will work on any processor with transition latency <= 10mS, using
+ * appropriate sampling rate.
+ *
+ * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL)
+ * this governor will not work. All times here are in uS.
+ */
+#define MIN_SAMPLING_RATE_RATIO (2)
+#define LATENCY_MULTIPLIER (1000)
+#define MIN_LATENCY_MULTIPLIER (100)
+#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000)
+
+/* Ondemand Sampling types */
+enum {OD_NORMAL_SAMPLE, OD_SUB_SAMPLE};
+
+/* Macro creating sysfs show routines */
+#define show_one(_gov, file_name, object) \
+static ssize_t show_##file_name \
+(struct kobject *kobj, struct attribute *attr, char *buf) \
+{ \
+ return sprintf(buf, "%u\n", _gov##_tuners.object); \
+}
+
+#define define_get_cpu_dbs_routines(_dbs_info) \
+static struct cpu_dbs_common_info *get_cpu_cdbs(int cpu) \
+{ \
+ return &per_cpu(_dbs_info, cpu).cdbs; \
+} \
+ \
+static void *get_cpu_dbs_info_s(int cpu) \
+{ \
+ return &per_cpu(_dbs_info, cpu); \
+}
+
+/*
+ * Abbreviations:
+ * dbs: used as a shortform for demand based switching It helps to keep variable
+ * names smaller, simpler
+ * cdbs: common dbs
+ * on_*: On-demand governor
+ * cs_*: Conservative governor
+ */
+
+/* Per cpu structures */
+struct cpu_dbs_common_info {
+ int cpu;
+ u64 prev_cpu_idle;
+ u64 prev_cpu_wall;
+ u64 prev_cpu_nice;
+ struct cpufreq_policy *cur_policy;
+ struct delayed_work work;
+ /*
+ * percpu mutex that serializes governor limit change with gov_dbs_timer
+ * invocation. We do not want gov_dbs_timer to run when user is changing
+ * the governor or limits.
+ */
+ struct mutex timer_mutex;
+};
+
+struct od_cpu_dbs_info_s {
+ struct cpu_dbs_common_info cdbs;
+ u64 prev_cpu_iowait;
+ struct cpufreq_frequency_table *freq_table;
+ unsigned int freq_lo;
+ unsigned int freq_lo_jiffies;
+ unsigned int freq_hi_jiffies;
+ unsigned int rate_mult;
+ unsigned int sample_type:1;
+};
+
+struct cs_cpu_dbs_info_s {
+ struct cpu_dbs_common_info cdbs;
+ unsigned int down_skip;
+ unsigned int requested_freq;
+ unsigned int enable:1;
+};
+
+/* Governers sysfs tunables */
+struct od_dbs_tuners {
+ unsigned int ignore_nice;
+ unsigned int sampling_rate;
+ unsigned int sampling_down_factor;
+ unsigned int up_threshold;
+ unsigned int down_differential;
+ unsigned int powersave_bias;
+ unsigned int io_is_busy;
+};
+
+struct cs_dbs_tuners {
+ unsigned int ignore_nice;
+ unsigned int sampling_rate;
+ unsigned int sampling_down_factor;
+ unsigned int up_threshold;
+ unsigned int down_threshold;
+ unsigned int freq_step;
+};
+
+/* Per Governer data */
+struct dbs_data {
+ /* Common across governors */
+ #define GOV_ONDEMAND 0
+ #define GOV_CONSERVATIVE 1
+ int governor;
+ unsigned int min_sampling_rate;
+ unsigned int enable; /* number of CPUs using this policy */
+ struct attribute_group *attr_group;
+ void *tuners;
+
+ /* dbs_mutex protects dbs_enable in governor start/stop */
+ struct mutex mutex;
+
+ struct cpu_dbs_common_info *(*get_cpu_cdbs)(int cpu);
+ void *(*get_cpu_dbs_info_s)(int cpu);
+ void (*gov_dbs_timer)(struct work_struct *work);
+ void (*gov_check_cpu)(int cpu, unsigned int load);
+
+ /* Governor specific ops, see below */
+ void *gov_ops;
+};
+
+/* Governor specific ops, will be passed to dbs_data->gov_ops */
+struct od_ops {
+ int (*io_busy)(void);
+ void (*powersave_bias_init_cpu)(int cpu);
+ unsigned int (*powersave_bias_target)(struct cpufreq_policy *policy,
+ unsigned int freq_next, unsigned int relation);
+ void (*freq_increase)(struct cpufreq_policy *p, unsigned int freq);
+};
+
+struct cs_ops {
+ struct notifier_block *notifier_block;
+};
+
+static inline int delay_for_sampling_rate(unsigned int sampling_rate)
+{
+ int delay = usecs_to_jiffies(sampling_rate);
+
+ /* We want all CPUs to do sampling nearly on same jiffy */
+ if (num_online_cpus() > 1)
+ delay -= jiffies % delay;
+
+ return delay;
+}
+
+u64 get_cpu_idle_time(unsigned int cpu, u64 *wall);
+void dbs_check_cpu(struct dbs_data *dbs_data, int cpu);
+int cpufreq_governor_dbs(struct dbs_data *dbs_data,
+ struct cpufreq_policy *policy, unsigned int event);
+#endif /* _CPUFREQ_GOVERNER_H */
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 396322f2a83..7731f7c7e79 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -10,24 +10,23 @@
* published by the Free Software Foundation.
*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/cpufreq.h>
-#include <linux/cpu.h>
-#include <linux/jiffies.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
#include <linux/kernel_stat.h>
+#include <linux/kobject.h>
+#include <linux/module.h>
#include <linux/mutex.h>
-#include <linux/hrtimer.h>
+#include <linux/percpu-defs.h>
+#include <linux/sysfs.h>
#include <linux/tick.h>
-#include <linux/ktime.h>
-#include <linux/sched.h>
+#include <linux/types.h>
-/*
- * dbs is used in this file as a shortform for demandbased switching
- * It helps to keep variable names smaller, simpler
- */
+#include "cpufreq_governor.h"
+/* On-demand governor macors */
#define DEF_FREQUENCY_DOWN_DIFFERENTIAL (10)
#define DEF_FREQUENCY_UP_THRESHOLD (80)
#define DEF_SAMPLING_DOWN_FACTOR (1)
@@ -38,80 +37,14 @@
#define MIN_FREQUENCY_UP_THRESHOLD (11)
#define MAX_FREQUENCY_UP_THRESHOLD (100)
-/*
- * The polling frequency of this governor depends on the capability of
- * the processor. Default polling frequency is 1000 times the transition
- * latency of the processor. The governor will work on any processor with
- * transition latency <= 10mS, using appropriate sampling
- * rate.
- * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL)
- * this governor will not work.
- * All times here are in uS.
- */
-#define MIN_SAMPLING_RATE_RATIO (2)
-
-static unsigned int min_sampling_rate;
-
-#define LATENCY_MULTIPLIER (1000)
-#define MIN_LATENCY_MULTIPLIER (100)
-#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000)
-
-static void do_dbs_timer(struct work_struct *work);
-static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
- unsigned int event);
+static struct dbs_data od_dbs_data;
+static DEFINE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info);
#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
-static
+static struct cpufreq_governor cpufreq_gov_ondemand;
#endif
-struct cpufreq_governor cpufreq_gov_ondemand = {
- .name = "ondemand",
- .governor = cpufreq_governor_dbs,
- .max_transition_latency = TRANSITION_LATENCY_LIMIT,
- .owner = THIS_MODULE,
-};
-/* Sampling types */
-enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE};
-
-struct cpu_dbs_info_s {
- cputime64_t prev_cpu_idle;
- cputime64_t prev_cpu_iowait;
- cputime64_t prev_cpu_wall;
- cputime64_t prev_cpu_nice;
- struct cpufreq_policy *cur_policy;
- struct delayed_work work;
- struct cpufreq_frequency_table *freq_table;
- unsigned int freq_lo;
- unsigned int freq_lo_jiffies;
- unsigned int freq_hi_jiffies;
- unsigned int rate_mult;
- int cpu;
- unsigned int sample_type:1;
- /*
- * percpu mutex that serializes governor limit change with
- * do_dbs_timer invocation. We do not want do_dbs_timer to run
- * when user is changing the governor or limits.
- */
- struct mutex timer_mutex;
-};
-static DEFINE_PER_CPU(struct cpu_dbs_info_s, od_cpu_dbs_info);
-
-static unsigned int dbs_enable; /* number of CPUs using this policy */
-
-/*
- * dbs_mutex protects dbs_enable in governor start/stop.
- */
-static DEFINE_MUTEX(dbs_mutex);
-
-static struct dbs_tuners {
- unsigned int sampling_rate;
- unsigned int up_threshold;
- unsigned int down_differential;
- unsigned int ignore_nice;
- unsigned int sampling_down_factor;
- unsigned int powersave_bias;
- unsigned int io_is_busy;
-} dbs_tuners_ins = {
+static struct od_dbs_tuners od_tuners = {
.up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
.sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR,
.down_differential = DEF_FREQUENCY_DOWN_DIFFERENTIAL,
@@ -119,48 +52,35 @@ static struct dbs_tuners {
.powersave_bias = 0,
};
-static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
-{
- u64 idle_time;
- u64 cur_wall_time;
- u64 busy_time;
-
- cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
-
- busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER];
- busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM];
- busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ];
- busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ];
- busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
- busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE];
-
- idle_time = cur_wall_time - busy_time;
- if (wall)
- *wall = jiffies_to_usecs(cur_wall_time);
-
- return jiffies_to_usecs(idle_time);
-}
-
-static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
+static void ondemand_powersave_bias_init_cpu(int cpu)
{
- u64 idle_time = get_cpu_idle_time_us(cpu, NULL);
-
- if (idle_time == -1ULL)
- return get_cpu_idle_time_jiffy(cpu, wall);
- else
- idle_time += get_cpu_iowait_time_us(cpu, wall);
+ struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
- return idle_time;
+ dbs_info->freq_table = cpufreq_frequency_get_table(cpu);
+ dbs_info->freq_lo = 0;
}
-static inline cputime64_t get_cpu_iowait_time(unsigned int cpu, cputime64_t *wall)
+/*
+ * Not all CPUs want IO time to be accounted as busy; this depends on how
+ * efficient idling at a higher frequency/voltage is.
+ * Pavel Machek says this is not so for various generations of AMD and old
+ * Intel systems.
+ * Mike Chan (androidlcom) calis this is also not true for ARM.
+ * Because of this, whitelist specific known (series) of CPUs by default, and
+ * leave all others up to the user.
+ */
+static int should_io_be_busy(void)
{
- u64 iowait_time = get_cpu_iowait_time_us(cpu, wall);
-
- if (iowait_time == -1ULL)
- return 0;
-
- return iowait_time;
+#if defined(CONFIG_X86)
+ /*
+ * For Intel, Core 2 (model 15) andl later have an efficient idle.
+ */
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
+ boot_cpu_data.x86 == 6 &&
+ boot_cpu_data.x86_model >= 15)
+ return 1;
+#endif
+ return 0;
}
/*
@@ -169,14 +89,13 @@ static inline cputime64_t get_cpu_iowait_time(unsigned int cpu, cputime64_t *wal
* freq_lo, and freq_lo_jiffies in percpu area for averaging freqs.
*/
static unsigned int powersave_bias_target(struct cpufreq_policy *policy,
- unsigned int freq_next,
- unsigned int relation)
+ unsigned int freq_next, unsigned int relation)
{
unsigned int freq_req, freq_reduc, freq_avg;
unsigned int freq_hi, freq_lo;
unsigned int index = 0;
unsigned int jiffies_total, jiffies_hi, jiffies_lo;
- struct cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info,
+ struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info,
policy->cpu);
if (!dbs_info->freq_table) {
@@ -188,7 +107,7 @@ static unsigned int powersave_bias_target(struct cpufreq_policy *policy,
cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_next,
relation, &index);
freq_req = dbs_info->freq_table[index].frequency;
- freq_reduc = freq_req * dbs_tuners_ins.powersave_bias / 1000;
+ freq_reduc = freq_req * od_tuners.powersave_bias / 1000;
freq_avg = freq_req - freq_reduc;
/* Find freq bounds for freq_avg in freq_table */
@@ -207,7 +126,7 @@ static unsigned int powersave_bias_target(struct cpufreq_policy *policy,
dbs_info->freq_lo_jiffies = 0;
return freq_lo;
}
- jiffies_total = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+ jiffies_total = usecs_to_jiffies(od_tuners.sampling_rate);
jiffies_hi = (freq_avg - freq_lo) * jiffies_total;
jiffies_hi += ((freq_hi - freq_lo) / 2);
jiffies_hi /= (freq_hi - freq_lo);
@@ -218,13 +137,6 @@ static unsigned int powersave_bias_target(struct cpufreq_policy *policy,
return freq_hi;
}
-static void ondemand_powersave_bias_init_cpu(int cpu)
-{
- struct cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
- dbs_info->freq_table = cpufreq_frequency_get_table(cpu);
- dbs_info->freq_lo = 0;
-}
-
static void ondemand_powersave_bias_init(void)
{
int i;
@@ -233,83 +145,173 @@ static void ondemand_powersave_bias_init(void)
}
}
-/************************** sysfs interface ************************/
+static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq)
+{
+ if (od_tuners.powersave_bias)
+ freq = powersave_bias_target(p, freq, CPUFREQ_RELATION_H);
+ else if (p->cur == p->max)
+ return;
-static ssize_t show_sampling_rate_min(struct kobject *kobj,
- struct attribute *attr, char *buf)
+ __cpufreq_driver_target(p, freq, od_tuners.powersave_bias ?
+ CPUFREQ_RELATION_L : CPUFREQ_RELATION_H);
+}
+
+/*
+ * Every sampling_rate, we check, if current idle time is less than 20%
+ * (default), then we try to increase frequency Every sampling_rate, we look for
+ * a the lowest frequency which can sustain the load while keeping idle time
+ * over 30%. If such a frequency exist, we try to decrease to this frequency.
+ *
+ * Any frequency increase takes it to the maximum frequency. Frequency reduction
+ * happens at minimum steps of 5% (default) of current frequency
+ */
+static void od_check_cpu(int cpu, unsigned int load_freq)
{
- return sprintf(buf, "%u\n", min_sampling_rate);
+ struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
+ struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;
+
+ dbs_info->freq_lo = 0;
+
+ /* Check for frequency increase */
+ if (load_freq > od_tuners.up_threshold * policy->cur) {
+ /* If switching to max speed, apply sampling_down_factor */
+ if (policy->cur < policy->max)
+ dbs_info->rate_mult =
+ od_tuners.sampling_down_factor;
+ dbs_freq_increase(policy, policy->max);
+ return;
+ }
+
+ /* Check for frequency decrease */
+ /* if we cannot reduce the frequency anymore, break out early */
+ if (policy->cur == policy->min)
+ return;
+
+ /*
+ * The optimal frequency is the frequency that is the lowest that can
+ * support the current CPU usage without triggering the up policy. To be
+ * safe, we focus 10 points under the threshold.
+ */
+ if (load_freq < (od_tuners.up_threshold - od_tuners.down_differential) *
+ policy->cur) {
+ unsigned int freq_next;
+ freq_next = load_freq / (od_tuners.up_threshold -
+ od_tuners.down_differential);
+
+ /* No longer fully busy, reset rate_mult */
+ dbs_info->rate_mult = 1;
+
+ if (freq_next < policy->min)
+ freq_next = policy->min;
+
+ if (!od_tuners.powersave_bias) {
+ __cpufreq_driver_target(policy, freq_next,
+ CPUFREQ_RELATION_L);
+ } else {
+ int freq = powersave_bias_target(policy, freq_next,
+ CPUFREQ_RELATION_L);
+ __cpufreq_driver_target(policy, freq,
+ CPUFREQ_RELATION_L);
+ }
+ }
}
-define_one_global_ro(sampling_rate_min);
+static void od_dbs_timer(struct work_struct *work)
+{
+ struct od_cpu_dbs_info_s *dbs_info =
+ container_of(work, struct od_cpu_dbs_info_s, cdbs.work.work);
+ unsigned int cpu = dbs_info->cdbs.cpu;
+ int delay, sample_type = dbs_info->sample_type;
+
+ mutex_lock(&dbs_info->cdbs.timer_mutex);
+
+ /* Common NORMAL_SAMPLE setup */
+ dbs_info->sample_type = OD_NORMAL_SAMPLE;
+ if (sample_type == OD_SUB_SAMPLE) {
+ delay = dbs_info->freq_lo_jiffies;
+ __cpufreq_driver_target(dbs_info->cdbs.cur_policy,
+ dbs_info->freq_lo, CPUFREQ_RELATION_H);
+ } else {
+ dbs_check_cpu(&od_dbs_data, cpu);
+ if (dbs_info->freq_lo) {
+ /* Setup timer for SUB_SAMPLE */
+ dbs_info->sample_type = OD_SUB_SAMPLE;
+ delay = dbs_info->freq_hi_jiffies;
+ } else {
+ delay = delay_for_sampling_rate(od_tuners.sampling_rate
+ * dbs_info->rate_mult);
+ }
+ }
+
+ schedule_delayed_work_on(cpu, &dbs_info->cdbs.work, delay);
+ mutex_unlock(&dbs_info->cdbs.timer_mutex);
+}
+
+/************************** sysfs interface ************************/
-/* cpufreq_ondemand Governor Tunables */
-#define show_one(file_name, object) \
-static ssize_t show_##file_name \
-(struct kobject *kobj, struct attribute *attr, char *buf) \
-{ \
- return sprintf(buf, "%u\n", dbs_tuners_ins.object); \
+static ssize_t show_sampling_rate_min(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u\n", od_dbs_data.min_sampling_rate);
}
-show_one(sampling_rate, sampling_rate);
-show_one(io_is_busy, io_is_busy);
-show_one(up_threshold, up_threshold);
-show_one(sampling_down_factor, sampling_down_factor);
-show_one(ignore_nice_load, ignore_nice);
-show_one(powersave_bias, powersave_bias);
/**
* update_sampling_rate - update sampling rate effective immediately if needed.
* @new_rate: new sampling rate
*
* If new rate is smaller than the old, simply updaing
- * dbs_tuners_int.sampling_rate might not be appropriate. For example,
- * if the original sampling_rate was 1 second and the requested new sampling
- * rate is 10 ms because the user needs immediate reaction from ondemand
- * governor, but not sure if higher frequency will be required or not,
- * then, the governor may change the sampling rate too late; up to 1 second
- * later. Thus, if we are reducing the sampling rate, we need to make the
- * new value effective immediately.
+ * dbs_tuners_int.sampling_rate might not be appropriate. For example, if the
+ * original sampling_rate was 1 second and the requested new sampling rate is 10
+ * ms because the user needs immediate reaction from ondemand governor, but not
+ * sure if higher frequency will be required or not, then, the governor may
+ * change the sampling rate too late; up to 1 second later. Thus, if we are
+ * reducing the sampling rate, we need to make the new value effective
+ * immediately.
*/
static void update_sampling_rate(unsigned int new_rate)
{
int cpu;
- dbs_tuners_ins.sampling_rate = new_rate
- = max(new_rate, min_sampling_rate);
+ od_tuners.sampling_rate = new_rate = max(new_rate,
+ od_dbs_data.min_sampling_rate);
for_each_online_cpu(cpu) {
struct cpufreq_policy *policy;
- struct cpu_dbs_info_s *dbs_info;
+ struct od_cpu_dbs_info_s *dbs_info;
unsigned long next_sampling, appointed_at;
policy = cpufreq_cpu_get(cpu);
if (!policy)
continue;
+ if (policy->governor != &cpufreq_gov_ondemand) {
+ cpufreq_cpu_put(policy);
+ continue;
+ }
dbs_info = &per_cpu(od_cpu_dbs_info, policy->cpu);
cpufreq_cpu_put(policy);
- mutex_lock(&dbs_info->timer_mutex);
+ mutex_lock(&dbs_info->cdbs.timer_mutex);
- if (!delayed_work_pending(&dbs_info->work)) {
- mutex_unlock(&dbs_info->timer_mutex);
+ if (!delayed_work_pending(&dbs_info->cdbs.work)) {
+ mutex_unlock(&dbs_info->cdbs.timer_mutex);
continue;
}
- next_sampling = jiffies + usecs_to_jiffies(new_rate);
- appointed_at = dbs_info->work.timer.expires;
-
+ next_sampling = jiffies + usecs_to_jiffies(new_rate);
+ appointed_at = dbs_info->cdbs.work.timer.expires;
if (time_before(next_sampling, appointed_at)) {
- mutex_unlock(&dbs_info->timer_mutex);
- cancel_delayed_work_sync(&dbs_info->work);
- mutex_lock(&dbs_info->timer_mutex);
+ mutex_unlock(&dbs_info->cdbs.timer_mutex);
+ cancel_delayed_work_sync(&dbs_info->cdbs.work);
+ mutex_lock(&dbs_info->cdbs.timer_mutex);
- schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work,
- usecs_to_jiffies(new_rate));
+ schedule_delayed_work_on(dbs_info->cdbs.cpu,
+ &dbs_info->cdbs.work,
+ usecs_to_jiffies(new_rate));
}
- mutex_unlock(&dbs_info->timer_mutex);
+ mutex_unlock(&dbs_info->cdbs.timer_mutex);
}
}
@@ -334,7 +336,7 @@ static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b,
ret = sscanf(buf, "%u", &input);
if (ret != 1)
return -EINVAL;
- dbs_tuners_ins.io_is_busy = !!input;
+ od_tuners.io_is_busy = !!input;
return count;
}
@@ -349,7 +351,7 @@ static ssize_t store_up_threshold(struct kobject *a, struct attribute *b,
input < MIN_FREQUENCY_UP_THRESHOLD) {
return -EINVAL;
}
- dbs_tuners_ins.up_threshold = input;
+ od_tuners.up_threshold = input;
return count;
}
@@ -362,12 +364,12 @@ static ssize_t store_sampling_down_factor(struct kobject *a,
if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1)
return -EINVAL;
- dbs_tuners_ins.sampling_down_factor = input;
+ od_tuners.sampling_down_factor = input;
/* Reset down sampling multiplier in case it was active */
for_each_online_cpu(j) {
- struct cpu_dbs_info_s *dbs_info;
- dbs_info = &per_cpu(od_cpu_dbs_info, j);
+ struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info,
+ j);
dbs_info->rate_mult = 1;
}
return count;
@@ -388,19 +390,20 @@ static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,
if (input > 1)
input = 1;
- if (input == dbs_tuners_ins.ignore_nice) { /* nothing to do */
+ if (input == od_tuners.ignore_nice) { /* nothing to do */
return count;
}
- dbs_tuners_ins.ignore_nice = input;
+ od_tuners.ignore_nice = input;
/* we need to re-evaluate prev_cpu_idle */
for_each_online_cpu(j) {
- struct cpu_dbs_info_s *dbs_info;
+ struct od_cpu_dbs_info_s *dbs_info;
dbs_info = &per_cpu(od_cpu_dbs_info, j);
- dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
- &dbs_info->prev_cpu_wall);
- if (dbs_tuners_ins.ignore_nice)
- dbs_info->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE];
+ dbs_info->cdbs.prev_cpu_idle = get_cpu_idle_time(j,
+ &dbs_info->cdbs.prev_cpu_wall);
+ if (od_tuners.ignore_nice)
+ dbs_info->cdbs.prev_cpu_nice =
+ kcpustat_cpu(j).cpustat[CPUTIME_NICE];
}
return count;
@@ -419,17 +422,25 @@ static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b,
if (input > 1000)
input = 1000;
- dbs_tuners_ins.powersave_bias = input;
+ od_tuners.powersave_bias = input;
ondemand_powersave_bias_init();
return count;
}
+show_one(od, sampling_rate, sampling_rate);
+show_one(od, io_is_busy, io_is_busy);
+show_one(od, up_threshold, up_threshold);
+show_one(od, sampling_down_factor, sampling_down_factor);
+show_one(od, ignore_nice_load, ignore_nice);
+show_one(od, powersave_bias, powersave_bias);
+
define_one_global_rw(sampling_rate);
define_one_global_rw(io_is_busy);
define_one_global_rw(up_threshold);
define_one_global_rw(sampling_down_factor);
define_one_global_rw(ignore_nice_load);
define_one_global_rw(powersave_bias);
+define_one_global_ro(sampling_rate_min);
static struct attribute *dbs_attributes[] = {
&sampling_rate_min.attr,
@@ -442,354 +453,71 @@ static struct attribute *dbs_attributes[] = {
NULL
};
-static struct attribute_group dbs_attr_group = {
+static struct attribute_group od_attr_group = {
.attrs = dbs_attributes,
.name = "ondemand",
};
/************************** sysfs end ************************/
-static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq)
-{
- if (dbs_tuners_ins.powersave_bias)
- freq = powersave_bias_target(p, freq, CPUFREQ_RELATION_H);
- else if (p->cur == p->max)
- return;
-
- __cpufreq_driver_target(p, freq, dbs_tuners_ins.powersave_bias ?
- CPUFREQ_RELATION_L : CPUFREQ_RELATION_H);
-}
-
-static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
-{
- unsigned int max_load_freq;
-
- struct cpufreq_policy *policy;
- unsigned int j;
-
- this_dbs_info->freq_lo = 0;
- policy = this_dbs_info->cur_policy;
-
- /*
- * Every sampling_rate, we check, if current idle time is less
- * than 20% (default), then we try to increase frequency
- * Every sampling_rate, we look for a the lowest
- * frequency which can sustain the load while keeping idle time over
- * 30%. If such a frequency exist, we try to decrease to this frequency.
- *
- * Any frequency increase takes it to the maximum frequency.
- * Frequency reduction happens at minimum steps of
- * 5% (default) of current frequency
- */
-
- /* Get Absolute Load - in terms of freq */
- max_load_freq = 0;
-
- for_each_cpu(j, policy->cpus) {
- struct cpu_dbs_info_s *j_dbs_info;
- cputime64_t cur_wall_time, cur_idle_time, cur_iowait_time;
- unsigned int idle_time, wall_time, iowait_time;
- unsigned int load, load_freq;
- int freq_avg;
-
- j_dbs_info = &per_cpu(od_cpu_dbs_info, j);
-
- cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
- cur_iowait_time = get_cpu_iowait_time(j, &cur_wall_time);
-
- wall_time = (unsigned int)
- (cur_wall_time - j_dbs_info->prev_cpu_wall);
- j_dbs_info->prev_cpu_wall = cur_wall_time;
-
- idle_time = (unsigned int)
- (cur_idle_time - j_dbs_info->prev_cpu_idle);
- j_dbs_info->prev_cpu_idle = cur_idle_time;
-
- iowait_time = (unsigned int)
- (cur_iowait_time - j_dbs_info->prev_cpu_iowait);
- j_dbs_info->prev_cpu_iowait = cur_iowait_time;
-
- if (dbs_tuners_ins.ignore_nice) {
- u64 cur_nice;
- unsigned long cur_nice_jiffies;
-
- cur_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE] -
- j_dbs_info->prev_cpu_nice;
- /*
- * Assumption: nice time between sampling periods will
- * be less than 2^32 jiffies for 32 bit sys
- */
- cur_nice_jiffies = (unsigned long)
- cputime64_to_jiffies64(cur_nice);
-
- j_dbs_info->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE];
- idle_time += jiffies_to_usecs(cur_nice_jiffies);
- }
-
- /*
- * For the purpose of ondemand, waiting for disk IO is an
- * indication that you're performance critical, and not that
- * the system is actually idle. So subtract the iowait time
- * from the cpu idle time.
- */
-
- if (dbs_tuners_ins.io_is_busy && idle_time >= iowait_time)
- idle_time -= iowait_time;
-
- if (unlikely(!wall_time || wall_time < idle_time))
- continue;
-
- load = 100 * (wall_time - idle_time) / wall_time;
-
- freq_avg = __cpufreq_driver_getavg(policy, j);
- if (freq_avg <= 0)
- freq_avg = policy->cur;
-
- load_freq = load * freq_avg;
- if (load_freq > max_load_freq)
- max_load_freq = load_freq;
- }
+define_get_cpu_dbs_routines(od_cpu_dbs_info);
- /* Check for frequency increase */
- if (max_load_freq > dbs_tuners_ins.up_threshold * policy->cur) {
- /* If switching to max speed, apply sampling_down_factor */
- if (policy->cur < policy->max)
- this_dbs_info->rate_mult =
- dbs_tuners_ins.sampling_down_factor;
- dbs_freq_increase(policy, policy->max);
- return;
- }
-
- /* Check for frequency decrease */
- /* if we cannot reduce the frequency anymore, break out early */
- if (policy->cur == policy->min)
- return;
-
- /*
- * The optimal frequency is the frequency that is the lowest that
- * can support the current CPU usage without triggering the up
- * policy. To be safe, we focus 10 points under the threshold.
- */
- if (max_load_freq <
- (dbs_tuners_ins.up_threshold - dbs_tuners_ins.down_differential) *
- policy->cur) {
- unsigned int freq_next;
- freq_next = max_load_freq /
- (dbs_tuners_ins.up_threshold -
- dbs_tuners_ins.down_differential);
-
- /* No longer fully busy, reset rate_mult */
- this_dbs_info->rate_mult = 1;
-
- if (freq_next < policy->min)
- freq_next = policy->min;
-
- if (!dbs_tuners_ins.powersave_bias) {
- __cpufreq_driver_target(policy, freq_next,
- CPUFREQ_RELATION_L);
- } else {
- int freq = powersave_bias_target(policy, freq_next,
- CPUFREQ_RELATION_L);
- __cpufreq_driver_target(policy, freq,
- CPUFREQ_RELATION_L);
- }
- }
-}
-
-static void do_dbs_timer(struct work_struct *work)
-{
- struct cpu_dbs_info_s *dbs_info =
- container_of(work, struct cpu_dbs_info_s, work.work);
- unsigned int cpu = dbs_info->cpu;
- int sample_type = dbs_info->sample_type;
-
- int delay;
-
- mutex_lock(&dbs_info->timer_mutex);
-
- /* Common NORMAL_SAMPLE setup */
- dbs_info->sample_type = DBS_NORMAL_SAMPLE;
- if (!dbs_tuners_ins.powersave_bias ||
- sample_type == DBS_NORMAL_SAMPLE) {
- dbs_check_cpu(dbs_info);
- if (dbs_info->freq_lo) {
- /* Setup timer for SUB_SAMPLE */
- dbs_info->sample_type = DBS_SUB_SAMPLE;
- delay = dbs_info->freq_hi_jiffies;
- } else {
- /* We want all CPUs to do sampling nearly on
- * same jiffy
- */
- delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate
- * dbs_info->rate_mult);
-
- if (num_online_cpus() > 1)
- delay -= jiffies % delay;
- }
- } else {
- __cpufreq_driver_target(dbs_info->cur_policy,
- dbs_info->freq_lo, CPUFREQ_RELATION_H);
- delay = dbs_info->freq_lo_jiffies;
- }
- schedule_delayed_work_on(cpu, &dbs_info->work, delay);
- mutex_unlock(&dbs_info->timer_mutex);
-}
-
-static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
-{
- /* We want all CPUs to do sampling nearly on same jiffy */
- int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
-
- if (num_online_cpus() > 1)
- delay -= jiffies % delay;
+static struct od_ops od_ops = {
+ .io_busy = should_io_be_busy,
+ .powersave_bias_init_cpu = ondemand_powersave_bias_init_cpu,
+ .powersave_bias_target = powersave_bias_target,
+ .freq_increase = dbs_freq_increase,
+};
- dbs_info->sample_type = DBS_NORMAL_SAMPLE;
- INIT_DEFERRABLE_WORK(&dbs_info->work, do_dbs_timer);
- schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay);
-}
+static struct dbs_data od_dbs_data = {
+ .governor = GOV_ONDEMAND,
+ .attr_group = &od_attr_group,
+ .tuners = &od_tuners,
+ .get_cpu_cdbs = get_cpu_cdbs,
+ .get_cpu_dbs_info_s = get_cpu_dbs_info_s,
+ .gov_dbs_timer = od_dbs_timer,
+ .gov_check_cpu = od_check_cpu,
+ .gov_ops = &od_ops,
+};
-static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
+static int od_cpufreq_governor_dbs(struct cpufreq_policy *policy,
+ unsigned int event)
{
- cancel_delayed_work_sync(&dbs_info->work);
+ return cpufreq_governor_dbs(&od_dbs_data, policy, event);
}
-/*
- * Not all CPUs want IO time to be accounted as busy; this dependson how
- * efficient idling at a higher frequency/voltage is.
- * Pavel Machek says this is not so for various generations of AMD and old
- * Intel systems.
- * Mike Chan (androidlcom) calis this is also not true for ARM.
- * Because of this, whitelist specific known (series) of CPUs by default, and
- * leave all others up to the user.
- */
-static int should_io_be_busy(void)
-{
-#if defined(CONFIG_X86)
- /*
- * For Intel, Core 2 (model 15) andl later have an efficient idle.
- */
- if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
- boot_cpu_data.x86 == 6 &&
- boot_cpu_data.x86_model >= 15)
- return 1;
+#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
+static
#endif
- return 0;
-}
-
-static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
- unsigned int event)
-{
- unsigned int cpu = policy->cpu;
- struct cpu_dbs_info_s *this_dbs_info;
- unsigned int j;
- int rc;
-
- this_dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
-
- switch (event) {
- case CPUFREQ_GOV_START:
- if ((!cpu_online(cpu)) || (!policy->cur))
- return -EINVAL;
-
- mutex_lock(&dbs_mutex);
-
- dbs_enable++;
- for_each_cpu(j, policy->cpus) {
- struct cpu_dbs_info_s *j_dbs_info;
- j_dbs_info = &per_cpu(od_cpu_dbs_info, j);
- j_dbs_info->cur_policy = policy;
-
- j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
- &j_dbs_info->prev_cpu_wall);
- if (dbs_tuners_ins.ignore_nice)
- j_dbs_info->prev_cpu_nice =
- kcpustat_cpu(j).cpustat[CPUTIME_NICE];
- }
- this_dbs_info->cpu = cpu;
- this_dbs_info->rate_mult = 1;
- ondemand_powersave_bias_init_cpu(cpu);
- /*
- * Start the timerschedule work, when this governor
- * is used for first time
- */
- if (dbs_enable == 1) {
- unsigned int latency;
-
- rc = sysfs_create_group(cpufreq_global_kobject,
- &dbs_attr_group);
- if (rc) {
- mutex_unlock(&dbs_mutex);
- return rc;
- }
-
- /* policy latency is in nS. Convert it to uS first */
- latency = policy->cpuinfo.transition_latency / 1000;
- if (latency == 0)
- latency = 1;
- /* Bring kernel and HW constraints together */
- min_sampling_rate = max(min_sampling_rate,
- MIN_LATENCY_MULTIPLIER * latency);
- dbs_tuners_ins.sampling_rate =
- max(min_sampling_rate,
- latency * LATENCY_MULTIPLIER);
- dbs_tuners_ins.io_is_busy = should_io_be_busy();
- }
- mutex_unlock(&dbs_mutex);
-
- mutex_init(&this_dbs_info->timer_mutex);
- dbs_timer_init(this_dbs_info);
- break;
-
- case CPUFREQ_GOV_STOP:
- dbs_timer_exit(this_dbs_info);
-
- mutex_lock(&dbs_mutex);
- mutex_destroy(&this_dbs_info->timer_mutex);
- dbs_enable--;
- mutex_unlock(&dbs_mutex);
- if (!dbs_enable)
- sysfs_remove_group(cpufreq_global_kobject,
- &dbs_attr_group);
-
- break;
-
- case CPUFREQ_GOV_LIMITS:
- mutex_lock(&this_dbs_info->timer_mutex);
- if (policy->max < this_dbs_info->cur_policy->cur)
- __cpufreq_driver_target(this_dbs_info->cur_policy,
- policy->max, CPUFREQ_RELATION_H);
- else if (policy->min > this_dbs_info->cur_policy->cur)
- __cpufreq_driver_target(this_dbs_info->cur_policy,
- policy->min, CPUFREQ_RELATION_L);
- dbs_check_cpu(this_dbs_info);
- mutex_unlock(&this_dbs_info->timer_mutex);
- break;
- }
- return 0;
-}
+struct cpufreq_governor cpufreq_gov_ondemand = {
+ .name = "ondemand",
+ .governor = od_cpufreq_governor_dbs,
+ .max_transition_latency = TRANSITION_LATENCY_LIMIT,
+ .owner = THIS_MODULE,
+};
static int __init cpufreq_gov_dbs_init(void)
{
u64 idle_time;
int cpu = get_cpu();
+ mutex_init(&od_dbs_data.mutex);
idle_time = get_cpu_idle_time_us(cpu, NULL);
put_cpu();
if (idle_time != -1ULL) {
/* Idle micro accounting is supported. Use finer thresholds */
- dbs_tuners_ins.up_threshold = MICRO_FREQUENCY_UP_THRESHOLD;
- dbs_tuners_ins.down_differential =
- MICRO_FREQUENCY_DOWN_DIFFERENTIAL;
+ od_tuners.up_threshold = MICRO_FREQUENCY_UP_THRESHOLD;
+ od_tuners.down_differential = MICRO_FREQUENCY_DOWN_DIFFERENTIAL;
/*
* In nohz/micro accounting case we set the minimum frequency
* not depending on HZ, but fixed (very low). The deferred
* timer might skip some samples if idle/sleeping as needed.
*/
- min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE;
+ od_dbs_data.min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE;
} else {
/* For correct statistics, we need 10 ticks for each measure */
- min_sampling_rate =
- MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10);
+ od_dbs_data.min_sampling_rate = MIN_SAMPLING_RATE_RATIO *
+ jiffies_to_usecs(10);
}
return cpufreq_register_governor(&cpufreq_gov_ondemand);
@@ -800,7 +528,6 @@ static void __exit cpufreq_gov_dbs_exit(void)
cpufreq_unregister_governor(&cpufreq_gov_ondemand);
}
-
MODULE_AUTHOR("Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>");
MODULE_AUTHOR("Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>");
MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for "
diff --git a/drivers/cpufreq/cpufreq_performance.c b/drivers/cpufreq/cpufreq_performance.c
index f13a8a9af6a..ceee06849b9 100644
--- a/drivers/cpufreq/cpufreq_performance.c
+++ b/drivers/cpufreq/cpufreq_performance.c
@@ -10,6 +10,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/cpufreq.h>
diff --git a/drivers/cpufreq/cpufreq_powersave.c b/drivers/cpufreq/cpufreq_powersave.c
index 4c2eb512f2b..2d948a17115 100644
--- a/drivers/cpufreq/cpufreq_powersave.c
+++ b/drivers/cpufreq/cpufreq_powersave.c
@@ -10,6 +10,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/cpufreq.h>
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 399831690fe..e40e5080964 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -37,7 +37,7 @@ struct cpufreq_stats {
unsigned int max_state;
unsigned int state_num;
unsigned int last_index;
- cputime64_t *time_in_state;
+ u64 *time_in_state;
unsigned int *freq_table;
#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
unsigned int *trans_table;
@@ -223,7 +223,7 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
count++;
}
- alloc_size = count * sizeof(int) + count * sizeof(cputime64_t);
+ alloc_size = count * sizeof(int) + count * sizeof(u64);
#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
alloc_size += count * count * sizeof(int);
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
index bedac1aa9be..c8c3d293cc5 100644
--- a/drivers/cpufreq/cpufreq_userspace.c
+++ b/drivers/cpufreq/cpufreq_userspace.c
@@ -11,6 +11,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/smp.h>
diff --git a/drivers/cpufreq/db8500-cpufreq.c b/drivers/cpufreq/db8500-cpufreq.c
index 74b830b635a..4f154bc0ebe 100644
--- a/drivers/cpufreq/db8500-cpufreq.c
+++ b/drivers/cpufreq/db8500-cpufreq.c
@@ -8,43 +8,17 @@
* Author: Jonas Aaberg <jonas.aberg@stericsson.com>
*
*/
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/cpufreq.h>
#include <linux/delay.h>
#include <linux/slab.h>
-#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
#include <mach/id.h>
-static struct cpufreq_frequency_table freq_table[] = {
- [0] = {
- .index = 0,
- .frequency = 200000,
- },
- [1] = {
- .index = 1,
- .frequency = 400000,
- },
- [2] = {
- .index = 2,
- .frequency = 800000,
- },
- [3] = {
- /* Used for MAX_OPP, if available */
- .index = 3,
- .frequency = CPUFREQ_TABLE_END,
- },
- [4] = {
- .index = 4,
- .frequency = CPUFREQ_TABLE_END,
- },
-};
-
-static enum arm_opp idx2opp[] = {
- ARM_EXTCLK,
- ARM_50_OPP,
- ARM_100_OPP,
- ARM_MAX_OPP
-};
+static struct cpufreq_frequency_table *freq_table;
+static struct clk *armss_clk;
static struct freq_attr *db8500_cpufreq_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
@@ -85,9 +59,9 @@ static int db8500_cpufreq_target(struct cpufreq_policy *policy,
for_each_cpu(freqs.cpu, policy->cpus)
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- /* request the PRCM unit for opp change */
- if (prcmu_set_arm_opp(idx2opp[idx])) {
- pr_err("db8500-cpufreq: Failed to set OPP level\n");
+ /* update armss clk frequency */
+ if (clk_set_rate(armss_clk, freq_table[idx].frequency * 1000)) {
+ pr_err("db8500-cpufreq: Failed to update armss clk\n");
return -EINVAL;
}
@@ -100,25 +74,36 @@ static int db8500_cpufreq_target(struct cpufreq_policy *policy,
static unsigned int db8500_cpufreq_getspeed(unsigned int cpu)
{
- int i;
- /* request the prcm to get the current ARM opp */
- for (i = 0; prcmu_get_arm_opp() != idx2opp[i]; i++)
- ;
- return freq_table[i].frequency;
+ int i = 0;
+ unsigned long freq = clk_get_rate(armss_clk) / 1000;
+
+ while (freq_table[i].frequency != CPUFREQ_TABLE_END) {
+ if (freq <= freq_table[i].frequency)
+ return freq_table[i].frequency;
+ i++;
+ }
+
+ /* We could not find a corresponding frequency. */
+ pr_err("db8500-cpufreq: Failed to find cpufreq speed\n");
+ return 0;
}
static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy)
{
- int i, res;
-
- BUILD_BUG_ON(ARRAY_SIZE(idx2opp) + 1 != ARRAY_SIZE(freq_table));
+ int i = 0;
+ int res;
- if (prcmu_has_arm_maxopp())
- freq_table[3].frequency = 1000000;
+ armss_clk = clk_get(NULL, "armss");
+ if (IS_ERR(armss_clk)) {
+ pr_err("db8500-cpufreq : Failed to get armss clk\n");
+ return PTR_ERR(armss_clk);
+ }
pr_info("db8500-cpufreq : Available frequencies:\n");
- for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
+ while (freq_table[i].frequency != CPUFREQ_TABLE_END) {
pr_info(" %d Mhz\n", freq_table[i].frequency/1000);
+ i++;
+ }
/* get policy fields based on the table */
res = cpufreq_frequency_table_cpuinfo(policy, freq_table);
@@ -126,6 +111,7 @@ static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy)
cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
else {
pr_err("db8500-cpufreq : Failed to read policy table\n");
+ clk_put(armss_clk);
return res;
}
@@ -159,12 +145,35 @@ static struct cpufreq_driver db8500_cpufreq_driver = {
.attr = db8500_cpufreq_attr,
};
+static int db8500_cpufreq_probe(struct platform_device *pdev)
+{
+ freq_table = dev_get_platdata(&pdev->dev);
+
+ if (!freq_table) {
+ pr_err("db8500-cpufreq: Failed to fetch cpufreq table\n");
+ return -ENODEV;
+ }
+
+ return cpufreq_register_driver(&db8500_cpufreq_driver);
+}
+
+static struct platform_driver db8500_cpufreq_plat_driver = {
+ .driver = {
+ .name = "cpufreq-u8500",
+ .owner = THIS_MODULE,
+ },
+ .probe = db8500_cpufreq_probe,
+};
+
static int __init db8500_cpufreq_register(void)
{
if (!cpu_is_u8500_family())
return -ENODEV;
pr_info("cpufreq for DB8500 started\n");
- return cpufreq_register_driver(&db8500_cpufreq_driver);
+ return platform_driver_register(&db8500_cpufreq_plat_driver);
}
device_initcall(db8500_cpufreq_register);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("cpufreq driver for DB8500");
diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
index af2d81e10f7..7012ea8bf1e 100644
--- a/drivers/cpufreq/exynos-cpufreq.c
+++ b/drivers/cpufreq/exynos-cpufreq.c
@@ -31,13 +31,13 @@ static unsigned int locking_frequency;
static bool frequency_locked;
static DEFINE_MUTEX(cpufreq_lock);
-int exynos_verify_speed(struct cpufreq_policy *policy)
+static int exynos_verify_speed(struct cpufreq_policy *policy)
{
return cpufreq_frequency_table_verify(policy,
exynos_info->freq_table);
}
-unsigned int exynos_getspeed(unsigned int cpu)
+static unsigned int exynos_getspeed(unsigned int cpu)
{
return clk_get_rate(exynos_info->cpu_clk) / 1000;
}
@@ -100,7 +100,8 @@ static int exynos_target(struct cpufreq_policy *policy,
}
arm_volt = volt_table[index];
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ for_each_cpu(freqs.cpu, policy->cpus)
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
/* When the new frequency is higher than current frequency */
if ((freqs.new > freqs.old) && !safe_arm_volt) {
@@ -115,7 +116,8 @@ static int exynos_target(struct cpufreq_policy *policy,
if (freqs.new != freqs.old)
exynos_info->set_freq(old_index, index);
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ for_each_cpu(freqs.cpu, policy->cpus)
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
/* When the new frequency is lower than current frequency */
if ((freqs.new < freqs.old) ||
@@ -235,6 +237,7 @@ static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
cpumask_copy(policy->related_cpus, cpu_possible_mask);
cpumask_copy(policy->cpus, cpu_online_mask);
} else {
+ policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
cpumask_setall(policy->cpus);
}
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index 90431cb9280..49cda256efb 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -9,6 +9,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c
index 53ddbc760af..f1fa500ac10 100644
--- a/drivers/cpufreq/longhaul.c
+++ b/drivers/cpufreq/longhaul.c
@@ -930,7 +930,7 @@ static int __cpuinit longhaul_cpu_init(struct cpufreq_policy *policy)
return 0;
}
-static int __devexit longhaul_cpu_exit(struct cpufreq_policy *policy)
+static int longhaul_cpu_exit(struct cpufreq_policy *policy)
{
cpufreq_frequency_table_put_attr(policy->cpu);
return 0;
@@ -946,7 +946,7 @@ static struct cpufreq_driver longhaul_driver = {
.target = longhaul_target,
.get = longhaul_get,
.init = longhaul_cpu_init,
- .exit = __devexit_p(longhaul_cpu_exit),
+ .exit = longhaul_cpu_exit,
.name = "longhaul",
.owner = THIS_MODULE,
.attr = longhaul_attr,
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index e3ebb4fa2c3..056faf6af1a 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -1186,7 +1186,7 @@ err_out:
return -ENODEV;
}
-static int __devexit powernowk8_cpu_exit(struct cpufreq_policy *pol)
+static int powernowk8_cpu_exit(struct cpufreq_policy *pol)
{
struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
@@ -1242,7 +1242,7 @@ static struct cpufreq_driver cpufreq_amd64_driver = {
.target = powernowk8_target,
.bios_limit = acpi_processor_get_bios_limit,
.init = powernowk8_cpu_init,
- .exit = __devexit_p(powernowk8_cpu_exit),
+ .exit = powernowk8_cpu_exit,
.get = powernowk8_get,
.name = "powernow-k8",
.owner = THIS_MODULE,
diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c
new file mode 100644
index 00000000000..4575cfe4175
--- /dev/null
+++ b/drivers/cpufreq/spear-cpufreq.c
@@ -0,0 +1,291 @@
+/*
+ * drivers/cpufreq/spear-cpufreq.c
+ *
+ * CPU Frequency Scaling for SPEAr platform
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Deepak Sikri <deepak.sikri@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+/* SPEAr CPUFreq driver data structure */
+static struct {
+ struct clk *clk;
+ unsigned int transition_latency;
+ struct cpufreq_frequency_table *freq_tbl;
+ u32 cnt;
+} spear_cpufreq;
+
+int spear_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, spear_cpufreq.freq_tbl);
+}
+
+static unsigned int spear_cpufreq_get(unsigned int cpu)
+{
+ return clk_get_rate(spear_cpufreq.clk) / 1000;
+}
+
+static struct clk *spear1340_cpu_get_possible_parent(unsigned long newfreq)
+{
+ struct clk *sys_pclk;
+ int pclk;
+ /*
+ * In SPEAr1340, cpu clk's parent sys clk can take input from
+ * following sources
+ */
+ const char *sys_clk_src[] = {
+ "sys_syn_clk",
+ "pll1_clk",
+ "pll2_clk",
+ "pll3_clk",
+ };
+
+ /*
+ * As sys clk can have multiple source with their own range
+ * limitation so we choose possible sources accordingly
+ */
+ if (newfreq <= 300000000)
+ pclk = 0; /* src is sys_syn_clk */
+ else if (newfreq > 300000000 && newfreq <= 500000000)
+ pclk = 3; /* src is pll3_clk */
+ else if (newfreq == 600000000)
+ pclk = 1; /* src is pll1_clk */
+ else
+ return ERR_PTR(-EINVAL);
+
+ /* Get parent to sys clock */
+ sys_pclk = clk_get(NULL, sys_clk_src[pclk]);
+ if (IS_ERR(sys_pclk))
+ pr_err("Failed to get %s clock\n", sys_clk_src[pclk]);
+
+ return sys_pclk;
+}
+
+/*
+ * In SPEAr1340, we cannot use newfreq directly because we need to actually
+ * access a source clock (clk) which might not be ancestor of cpu at present.
+ * Hence in SPEAr1340 we would operate on source clock directly before switching
+ * cpu clock to it.
+ */
+static int spear1340_set_cpu_rate(struct clk *sys_pclk, unsigned long newfreq)
+{
+ struct clk *sys_clk;
+ int ret = 0;
+
+ sys_clk = clk_get_parent(spear_cpufreq.clk);
+ if (IS_ERR(sys_clk)) {
+ pr_err("failed to get cpu's parent (sys) clock\n");
+ return PTR_ERR(sys_clk);
+ }
+
+ /* Set the rate of the source clock before changing the parent */
+ ret = clk_set_rate(sys_pclk, newfreq);
+ if (ret) {
+ pr_err("Failed to set sys clk rate to %lu\n", newfreq);
+ return ret;
+ }
+
+ ret = clk_set_parent(sys_clk, sys_pclk);
+ if (ret) {
+ pr_err("Failed to set sys clk parent\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int spear_cpufreq_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ unsigned long newfreq;
+ struct clk *srcclk;
+ int index, ret, mult = 1;
+
+ if (cpufreq_frequency_table_target(policy, spear_cpufreq.freq_tbl,
+ target_freq, relation, &index))
+ return -EINVAL;
+
+ freqs.cpu = policy->cpu;
+ freqs.old = spear_cpufreq_get(0);
+
+ newfreq = spear_cpufreq.freq_tbl[index].frequency * 1000;
+ if (of_machine_is_compatible("st,spear1340")) {
+ /*
+ * SPEAr1340 is special in the sense that due to the possibility
+ * of multiple clock sources for cpu clk's parent we can have
+ * different clock source for different frequency of cpu clk.
+ * Hence we need to choose one from amongst these possible clock
+ * sources.
+ */
+ srcclk = spear1340_cpu_get_possible_parent(newfreq);
+ if (IS_ERR(srcclk)) {
+ pr_err("Failed to get src clk\n");
+ return PTR_ERR(srcclk);
+ }
+
+ /* SPEAr1340: src clk is always 2 * intended cpu clk */
+ mult = 2;
+ } else {
+ /*
+ * src clock to be altered is ancestor of cpu clock. Hence we
+ * can directly work on cpu clk
+ */
+ srcclk = spear_cpufreq.clk;
+ }
+
+ newfreq = clk_round_rate(srcclk, newfreq * mult);
+ if (newfreq < 0) {
+ pr_err("clk_round_rate failed for cpu src clock\n");
+ return newfreq;
+ }
+
+ freqs.new = newfreq / 1000;
+ freqs.new /= mult;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ if (mult == 2)
+ ret = spear1340_set_cpu_rate(srcclk, newfreq);
+ else
+ ret = clk_set_rate(spear_cpufreq.clk, newfreq);
+
+ /* Get current rate after clk_set_rate, in case of failure */
+ if (ret) {
+ pr_err("CPU Freq: cpu clk_set_rate failed: %d\n", ret);
+ freqs.new = clk_get_rate(spear_cpufreq.clk) / 1000;
+ }
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ return ret;
+}
+
+static int spear_cpufreq_init(struct cpufreq_policy *policy)
+{
+ int ret;
+
+ ret = cpufreq_frequency_table_cpuinfo(policy, spear_cpufreq.freq_tbl);
+ if (ret) {
+ pr_err("cpufreq_frequency_table_cpuinfo() failed");
+ return ret;
+ }
+
+ cpufreq_frequency_table_get_attr(spear_cpufreq.freq_tbl, policy->cpu);
+ policy->cpuinfo.transition_latency = spear_cpufreq.transition_latency;
+ policy->cur = spear_cpufreq_get(0);
+
+ cpumask_copy(policy->cpus, topology_core_cpumask(policy->cpu));
+ cpumask_copy(policy->related_cpus, policy->cpus);
+
+ return 0;
+}
+
+static int spear_cpufreq_exit(struct cpufreq_policy *policy)
+{
+ cpufreq_frequency_table_put_attr(policy->cpu);
+ return 0;
+}
+
+static struct freq_attr *spear_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver spear_cpufreq_driver = {
+ .name = "cpufreq-spear",
+ .flags = CPUFREQ_STICKY,
+ .verify = spear_cpufreq_verify,
+ .target = spear_cpufreq_target,
+ .get = spear_cpufreq_get,
+ .init = spear_cpufreq_init,
+ .exit = spear_cpufreq_exit,
+ .attr = spear_cpufreq_attr,
+};
+
+static int spear_cpufreq_driver_init(void)
+{
+ struct device_node *np;
+ const struct property *prop;
+ struct cpufreq_frequency_table *freq_tbl;
+ const __be32 *val;
+ int cnt, i, ret;
+
+ np = of_find_node_by_path("/cpus/cpu@0");
+ if (!np) {
+ pr_err("No cpu node found");
+ return -ENODEV;
+ }
+
+ if (of_property_read_u32(np, "clock-latency",
+ &spear_cpufreq.transition_latency))
+ spear_cpufreq.transition_latency = CPUFREQ_ETERNAL;
+
+ prop = of_find_property(np, "cpufreq_tbl", NULL);
+ if (!prop || !prop->value) {
+ pr_err("Invalid cpufreq_tbl");
+ ret = -ENODEV;
+ goto out_put_node;
+ }
+
+ cnt = prop->length / sizeof(u32);
+ val = prop->value;
+
+ freq_tbl = kmalloc(sizeof(*freq_tbl) * (cnt + 1), GFP_KERNEL);
+ if (!freq_tbl) {
+ ret = -ENOMEM;
+ goto out_put_node;
+ }
+
+ for (i = 0; i < cnt; i++) {
+ freq_tbl[i].index = i;
+ freq_tbl[i].frequency = be32_to_cpup(val++);
+ }
+
+ freq_tbl[i].index = i;
+ freq_tbl[i].frequency = CPUFREQ_TABLE_END;
+
+ spear_cpufreq.freq_tbl = freq_tbl;
+
+ of_node_put(np);
+
+ spear_cpufreq.clk = clk_get(NULL, "cpu_clk");
+ if (IS_ERR(spear_cpufreq.clk)) {
+ pr_err("Unable to get CPU clock\n");
+ ret = PTR_ERR(spear_cpufreq.clk);
+ goto out_put_mem;
+ }
+
+ ret = cpufreq_register_driver(&spear_cpufreq_driver);
+ if (!ret)
+ return 0;
+
+ pr_err("failed register driver: %d\n", ret);
+ clk_put(spear_cpufreq.clk);
+
+out_put_mem:
+ kfree(freq_tbl);
+ return ret;
+
+out_put_node:
+ of_node_put(np);
+ return ret;
+}
+late_initcall(spear_cpufreq_driver_init);
+
+MODULE_AUTHOR("Deepak Sikri <deepak.sikri@st.com>");
+MODULE_DESCRIPTION("SPEAr CPUFreq driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index a76b689e553..234ae651b38 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -9,6 +9,15 @@ config CPU_IDLE
If you're using an ACPI-enabled platform, you should say Y here.
+config CPU_IDLE_MULTIPLE_DRIVERS
+ bool "Support multiple cpuidle drivers"
+ depends on CPU_IDLE
+ default n
+ help
+ Allows the cpuidle framework to use different drivers for each CPU.
+ This is useful if you have a system with different CPU latencies and
+ states. If unsure say N.
+
config CPU_IDLE_GOV_LADDER
bool
depends on CPU_IDLE
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 7f15b8514a1..8df53dd8dbe 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -68,7 +68,7 @@ static cpuidle_enter_t cpuidle_enter_ops;
int cpuidle_play_dead(void)
{
struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
- struct cpuidle_driver *drv = cpuidle_get_driver();
+ struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
int i, dead_state = -1;
int power_usage = -1;
@@ -109,8 +109,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
/* This can be moved to within driver enter routine
* but that results in multiple copies of same code.
*/
- dev->states_usage[entered_state].time +=
- (unsigned long long)dev->last_residency;
+ dev->states_usage[entered_state].time += dev->last_residency;
dev->states_usage[entered_state].usage++;
} else {
dev->last_residency = 0;
@@ -128,7 +127,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
int cpuidle_idle_call(void)
{
struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
- struct cpuidle_driver *drv = cpuidle_get_driver();
+ struct cpuidle_driver *drv;
int next_state, entered_state;
if (off)
@@ -141,9 +140,15 @@ int cpuidle_idle_call(void)
if (!dev || !dev->enabled)
return -EBUSY;
+ drv = cpuidle_get_cpu_driver(dev);
+
/* ask the governor for the next state */
next_state = cpuidle_curr_governor->select(drv, dev);
if (need_resched()) {
+ dev->last_residency = 0;
+ /* give the governor an opportunity to reflect on the outcome */
+ if (cpuidle_curr_governor->reflect)
+ cpuidle_curr_governor->reflect(dev, next_state);
local_irq_enable();
return 0;
}
@@ -308,15 +313,19 @@ static void poll_idle_init(struct cpuidle_driver *drv) {}
int cpuidle_enable_device(struct cpuidle_device *dev)
{
int ret, i;
- struct cpuidle_driver *drv = cpuidle_get_driver();
+ struct cpuidle_driver *drv;
if (!dev)
return -EINVAL;
if (dev->enabled)
return 0;
+
+ drv = cpuidle_get_cpu_driver(dev);
+
if (!drv || !cpuidle_curr_governor)
return -EIO;
+
if (!dev->state_count)
dev->state_count = drv->state_count;
@@ -331,7 +340,8 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
poll_idle_init(drv);
- if ((ret = cpuidle_add_state_sysfs(dev)))
+ ret = cpuidle_add_device_sysfs(dev);
+ if (ret)
return ret;
if (cpuidle_curr_governor->enable &&
@@ -352,7 +362,7 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
return 0;
fail_sysfs:
- cpuidle_remove_state_sysfs(dev);
+ cpuidle_remove_device_sysfs(dev);
return ret;
}
@@ -368,17 +378,20 @@ EXPORT_SYMBOL_GPL(cpuidle_enable_device);
*/
void cpuidle_disable_device(struct cpuidle_device *dev)
{
+ struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
+
if (!dev || !dev->enabled)
return;
- if (!cpuidle_get_driver() || !cpuidle_curr_governor)
+
+ if (!drv || !cpuidle_curr_governor)
return;
dev->enabled = 0;
if (cpuidle_curr_governor->disable)
- cpuidle_curr_governor->disable(cpuidle_get_driver(), dev);
+ cpuidle_curr_governor->disable(drv, dev);
- cpuidle_remove_state_sysfs(dev);
+ cpuidle_remove_device_sysfs(dev);
enabled_devices--;
}
@@ -394,17 +407,14 @@ EXPORT_SYMBOL_GPL(cpuidle_disable_device);
static int __cpuidle_register_device(struct cpuidle_device *dev)
{
int ret;
- struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
- struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver();
+ struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
- if (!try_module_get(cpuidle_driver->owner))
+ if (!try_module_get(drv->owner))
return -EINVAL;
- init_completion(&dev->kobj_unregister);
-
per_cpu(cpuidle_devices, dev->cpu) = dev;
list_add(&dev->device_list, &cpuidle_detected_devices);
- ret = cpuidle_add_sysfs(cpu_dev);
+ ret = cpuidle_add_sysfs(dev);
if (ret)
goto err_sysfs;
@@ -416,12 +426,11 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
return 0;
err_coupled:
- cpuidle_remove_sysfs(cpu_dev);
- wait_for_completion(&dev->kobj_unregister);
+ cpuidle_remove_sysfs(dev);
err_sysfs:
list_del(&dev->device_list);
per_cpu(cpuidle_devices, dev->cpu) = NULL;
- module_put(cpuidle_driver->owner);
+ module_put(drv->owner);
return ret;
}
@@ -460,8 +469,7 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device);
*/
void cpuidle_unregister_device(struct cpuidle_device *dev)
{
- struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
- struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver();
+ struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
if (dev->registered == 0)
return;
@@ -470,16 +478,15 @@ void cpuidle_unregister_device(struct cpuidle_device *dev)
cpuidle_disable_device(dev);
- cpuidle_remove_sysfs(cpu_dev);
+ cpuidle_remove_sysfs(dev);
list_del(&dev->device_list);
- wait_for_completion(&dev->kobj_unregister);
per_cpu(cpuidle_devices, dev->cpu) = NULL;
cpuidle_coupled_unregister_device(dev);
cpuidle_resume_and_unlock();
- module_put(cpuidle_driver->owner);
+ module_put(drv->owner);
}
EXPORT_SYMBOL_GPL(cpuidle_unregister_device);
diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h
index 76e7f696ad8..ee97e9672ec 100644
--- a/drivers/cpuidle/cpuidle.h
+++ b/drivers/cpuidle/cpuidle.h
@@ -5,8 +5,6 @@
#ifndef __DRIVER_CPUIDLE_H
#define __DRIVER_CPUIDLE_H
-#include <linux/device.h>
-
/* For internal use only */
extern struct cpuidle_governor *cpuidle_curr_governor;
extern struct list_head cpuidle_governors;
@@ -25,12 +23,15 @@ extern void cpuidle_uninstall_idle_handler(void);
extern int cpuidle_switch_governor(struct cpuidle_governor *gov);
/* sysfs */
+
+struct device;
+
extern int cpuidle_add_interface(struct device *dev);
extern void cpuidle_remove_interface(struct device *dev);
-extern int cpuidle_add_state_sysfs(struct cpuidle_device *device);
-extern void cpuidle_remove_state_sysfs(struct cpuidle_device *device);
-extern int cpuidle_add_sysfs(struct device *dev);
-extern void cpuidle_remove_sysfs(struct device *dev);
+extern int cpuidle_add_device_sysfs(struct cpuidle_device *device);
+extern void cpuidle_remove_device_sysfs(struct cpuidle_device *device);
+extern int cpuidle_add_sysfs(struct cpuidle_device *dev);
+extern void cpuidle_remove_sysfs(struct cpuidle_device *dev);
#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
bool cpuidle_state_is_coupled(struct cpuidle_device *dev,
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
index 87db3877fea..3af841fb397 100644
--- a/drivers/cpuidle/driver.c
+++ b/drivers/cpuidle/driver.c
@@ -14,9 +14,10 @@
#include "cpuidle.h"
-static struct cpuidle_driver *cpuidle_curr_driver;
DEFINE_SPINLOCK(cpuidle_driver_lock);
-int cpuidle_driver_refcount;
+
+static void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu);
+static struct cpuidle_driver * __cpuidle_get_cpu_driver(int cpu);
static void set_power_states(struct cpuidle_driver *drv)
{
@@ -40,11 +41,15 @@ static void set_power_states(struct cpuidle_driver *drv)
drv->states[i].power_usage = -1 - i;
}
-/**
- * cpuidle_register_driver - registers a driver
- * @drv: the driver
- */
-int cpuidle_register_driver(struct cpuidle_driver *drv)
+static void __cpuidle_driver_init(struct cpuidle_driver *drv)
+{
+ drv->refcnt = 0;
+
+ if (!drv->power_specified)
+ set_power_states(drv);
+}
+
+static int __cpuidle_register_driver(struct cpuidle_driver *drv, int cpu)
{
if (!drv || !drv->state_count)
return -EINVAL;
@@ -52,31 +57,145 @@ int cpuidle_register_driver(struct cpuidle_driver *drv)
if (cpuidle_disabled())
return -ENODEV;
- spin_lock(&cpuidle_driver_lock);
- if (cpuidle_curr_driver) {
- spin_unlock(&cpuidle_driver_lock);
+ if (__cpuidle_get_cpu_driver(cpu))
return -EBUSY;
+
+ __cpuidle_driver_init(drv);
+
+ __cpuidle_set_cpu_driver(drv, cpu);
+
+ return 0;
+}
+
+static void __cpuidle_unregister_driver(struct cpuidle_driver *drv, int cpu)
+{
+ if (drv != __cpuidle_get_cpu_driver(cpu))
+ return;
+
+ if (!WARN_ON(drv->refcnt > 0))
+ __cpuidle_set_cpu_driver(NULL, cpu);
+}
+
+#ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
+
+static DEFINE_PER_CPU(struct cpuidle_driver *, cpuidle_drivers);
+
+static void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu)
+{
+ per_cpu(cpuidle_drivers, cpu) = drv;
+}
+
+static struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
+{
+ return per_cpu(cpuidle_drivers, cpu);
+}
+
+static void __cpuidle_unregister_all_cpu_driver(struct cpuidle_driver *drv)
+{
+ int cpu;
+ for_each_present_cpu(cpu)
+ __cpuidle_unregister_driver(drv, cpu);
+}
+
+static int __cpuidle_register_all_cpu_driver(struct cpuidle_driver *drv)
+{
+ int ret = 0;
+ int i, cpu;
+
+ for_each_present_cpu(cpu) {
+ ret = __cpuidle_register_driver(drv, cpu);
+ if (ret)
+ break;
}
- if (!drv->power_specified)
- set_power_states(drv);
+ if (ret)
+ for_each_present_cpu(i) {
+ if (i == cpu)
+ break;
+ __cpuidle_unregister_driver(drv, i);
+ }
- cpuidle_curr_driver = drv;
+ return ret;
+}
+
+int cpuidle_register_cpu_driver(struct cpuidle_driver *drv, int cpu)
+{
+ int ret;
+
+ spin_lock(&cpuidle_driver_lock);
+ ret = __cpuidle_register_driver(drv, cpu);
spin_unlock(&cpuidle_driver_lock);
- return 0;
+ return ret;
+}
+
+void cpuidle_unregister_cpu_driver(struct cpuidle_driver *drv, int cpu)
+{
+ spin_lock(&cpuidle_driver_lock);
+ __cpuidle_unregister_driver(drv, cpu);
+ spin_unlock(&cpuidle_driver_lock);
+}
+
+/**
+ * cpuidle_register_driver - registers a driver
+ * @drv: the driver
+ */
+int cpuidle_register_driver(struct cpuidle_driver *drv)
+{
+ int ret;
+
+ spin_lock(&cpuidle_driver_lock);
+ ret = __cpuidle_register_all_cpu_driver(drv);
+ spin_unlock(&cpuidle_driver_lock);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(cpuidle_register_driver);
/**
- * cpuidle_get_driver - return the current driver
+ * cpuidle_unregister_driver - unregisters a driver
+ * @drv: the driver
*/
-struct cpuidle_driver *cpuidle_get_driver(void)
+void cpuidle_unregister_driver(struct cpuidle_driver *drv)
+{
+ spin_lock(&cpuidle_driver_lock);
+ __cpuidle_unregister_all_cpu_driver(drv);
+ spin_unlock(&cpuidle_driver_lock);
+}
+EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
+
+#else
+
+static struct cpuidle_driver *cpuidle_curr_driver;
+
+static inline void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu)
+{
+ cpuidle_curr_driver = drv;
+}
+
+static inline struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
{
return cpuidle_curr_driver;
}
-EXPORT_SYMBOL_GPL(cpuidle_get_driver);
+
+/**
+ * cpuidle_register_driver - registers a driver
+ * @drv: the driver
+ */
+int cpuidle_register_driver(struct cpuidle_driver *drv)
+{
+ int ret, cpu;
+
+ cpu = get_cpu();
+ spin_lock(&cpuidle_driver_lock);
+ ret = __cpuidle_register_driver(drv, cpu);
+ spin_unlock(&cpuidle_driver_lock);
+ put_cpu();
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(cpuidle_register_driver);
/**
* cpuidle_unregister_driver - unregisters a driver
@@ -84,20 +203,50 @@ EXPORT_SYMBOL_GPL(cpuidle_get_driver);
*/
void cpuidle_unregister_driver(struct cpuidle_driver *drv)
{
- if (drv != cpuidle_curr_driver) {
- WARN(1, "invalid cpuidle_unregister_driver(%s)\n",
- drv->name);
- return;
- }
+ int cpu;
+ cpu = get_cpu();
spin_lock(&cpuidle_driver_lock);
+ __cpuidle_unregister_driver(drv, cpu);
+ spin_unlock(&cpuidle_driver_lock);
+ put_cpu();
+}
+EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
+#endif
+
+/**
+ * cpuidle_get_driver - return the current driver
+ */
+struct cpuidle_driver *cpuidle_get_driver(void)
+{
+ struct cpuidle_driver *drv;
+ int cpu;
- if (!WARN_ON(cpuidle_driver_refcount > 0))
- cpuidle_curr_driver = NULL;
+ cpu = get_cpu();
+ drv = __cpuidle_get_cpu_driver(cpu);
+ put_cpu();
+ return drv;
+}
+EXPORT_SYMBOL_GPL(cpuidle_get_driver);
+
+/**
+ * cpuidle_get_cpu_driver - return the driver tied with a cpu
+ */
+struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev)
+{
+ struct cpuidle_driver *drv;
+
+ if (!dev)
+ return NULL;
+
+ spin_lock(&cpuidle_driver_lock);
+ drv = __cpuidle_get_cpu_driver(dev->cpu);
spin_unlock(&cpuidle_driver_lock);
+
+ return drv;
}
-EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
+EXPORT_SYMBOL_GPL(cpuidle_get_cpu_driver);
struct cpuidle_driver *cpuidle_driver_ref(void)
{
@@ -105,8 +254,8 @@ struct cpuidle_driver *cpuidle_driver_ref(void)
spin_lock(&cpuidle_driver_lock);
- drv = cpuidle_curr_driver;
- cpuidle_driver_refcount++;
+ drv = cpuidle_get_driver();
+ drv->refcnt++;
spin_unlock(&cpuidle_driver_lock);
return drv;
@@ -114,10 +263,12 @@ struct cpuidle_driver *cpuidle_driver_ref(void)
void cpuidle_driver_unref(void)
{
+ struct cpuidle_driver *drv = cpuidle_get_driver();
+
spin_lock(&cpuidle_driver_lock);
- if (!WARN_ON(cpuidle_driver_refcount <= 0))
- cpuidle_driver_refcount--;
+ if (drv && !WARN_ON(drv->refcnt <= 0))
+ drv->refcnt--;
spin_unlock(&cpuidle_driver_lock);
}
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index 5b1f2c372c1..bd40b943b6d 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -28,6 +28,13 @@
#define MAX_INTERESTING 50000
#define STDDEV_THRESH 400
+/* 60 * 60 > STDDEV_THRESH * INTERVALS = 400 * 8 */
+#define MAX_DEVIATION 60
+
+static DEFINE_PER_CPU(struct hrtimer, menu_hrtimer);
+static DEFINE_PER_CPU(int, hrtimer_status);
+/* menu hrtimer mode */
+enum {MENU_HRTIMER_STOP, MENU_HRTIMER_REPEAT, MENU_HRTIMER_GENERAL};
/*
* Concepts and ideas behind the menu governor
@@ -109,6 +116,13 @@
*
*/
+/*
+ * The C-state residency is so long that is is worthwhile to exit
+ * from the shallow C-state and re-enter into a deeper C-state.
+ */
+static unsigned int perfect_cstate_ms __read_mostly = 30;
+module_param(perfect_cstate_ms, uint, 0000);
+
struct menu_device {
int last_state_idx;
int needs_update;
@@ -191,40 +205,102 @@ static u64 div_round64(u64 dividend, u32 divisor)
return div_u64(dividend + (divisor / 2), divisor);
}
+/* Cancel the hrtimer if it is not triggered yet */
+void menu_hrtimer_cancel(void)
+{
+ int cpu = smp_processor_id();
+ struct hrtimer *hrtmr = &per_cpu(menu_hrtimer, cpu);
+
+ /* The timer is still not time out*/
+ if (per_cpu(hrtimer_status, cpu)) {
+ hrtimer_cancel(hrtmr);
+ per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_STOP;
+ }
+}
+EXPORT_SYMBOL_GPL(menu_hrtimer_cancel);
+
+/* Call back for hrtimer is triggered */
+static enum hrtimer_restart menu_hrtimer_notify(struct hrtimer *hrtimer)
+{
+ int cpu = smp_processor_id();
+ struct menu_device *data = &per_cpu(menu_devices, cpu);
+
+ /* In general case, the expected residency is much larger than
+ * deepest C-state target residency, but prediction logic still
+ * predicts a small predicted residency, so the prediction
+ * history is totally broken if the timer is triggered.
+ * So reset the correction factor.
+ */
+ if (per_cpu(hrtimer_status, cpu) == MENU_HRTIMER_GENERAL)
+ data->correction_factor[data->bucket] = RESOLUTION * DECAY;
+
+ per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_STOP;
+
+ return HRTIMER_NORESTART;
+}
+
/*
* Try detecting repeating patterns by keeping track of the last 8
* intervals, and checking if the standard deviation of that set
* of points is below a threshold. If it is... then use the
* average of these 8 points as the estimated value.
*/
-static void detect_repeating_patterns(struct menu_device *data)
+static u32 get_typical_interval(struct menu_device *data)
{
- int i;
- uint64_t avg = 0;
- uint64_t stddev = 0; /* contains the square of the std deviation */
-
- /* first calculate average and standard deviation of the past */
- for (i = 0; i < INTERVALS; i++)
- avg += data->intervals[i];
- avg = avg / INTERVALS;
+ int i = 0, divisor = 0;
+ uint64_t max = 0, avg = 0, stddev = 0;
+ int64_t thresh = LLONG_MAX; /* Discard outliers above this value. */
+ unsigned int ret = 0;
- /* if the avg is beyond the known next tick, it's worthless */
- if (avg > data->expected_us)
- return;
+again:
- for (i = 0; i < INTERVALS; i++)
- stddev += (data->intervals[i] - avg) *
- (data->intervals[i] - avg);
-
- stddev = stddev / INTERVALS;
+ /* first calculate average and standard deviation of the past */
+ max = avg = divisor = stddev = 0;
+ for (i = 0; i < INTERVALS; i++) {
+ int64_t value = data->intervals[i];
+ if (value <= thresh) {
+ avg += value;
+ divisor++;
+ if (value > max)
+ max = value;
+ }
+ }
+ do_div(avg, divisor);
+ for (i = 0; i < INTERVALS; i++) {
+ int64_t value = data->intervals[i];
+ if (value <= thresh) {
+ int64_t diff = value - avg;
+ stddev += diff * diff;
+ }
+ }
+ do_div(stddev, divisor);
+ stddev = int_sqrt(stddev);
/*
- * now.. if stddev is small.. then assume we have a
- * repeating pattern and predict we keep doing this.
+ * If we have outliers to the upside in our distribution, discard
+ * those by setting the threshold to exclude these outliers, then
+ * calculate the average and standard deviation again. Once we get
+ * down to the bottom 3/4 of our samples, stop excluding samples.
+ *
+ * This can deal with workloads that have long pauses interspersed
+ * with sporadic activity with a bunch of short pauses.
+ *
+ * The typical interval is obtained when standard deviation is small
+ * or standard deviation is small compared to the average interval.
*/
-
- if (avg && stddev < STDDEV_THRESH)
+ if (((avg > stddev * 6) && (divisor * 4 >= INTERVALS * 3))
+ || stddev <= 20) {
data->predicted_us = avg;
+ ret = 1;
+ return ret;
+
+ } else if ((divisor * 4) > INTERVALS * 3) {
+ /* Exclude the max interval */
+ thresh = max - 1;
+ goto again;
+ }
+
+ return ret;
}
/**
@@ -240,6 +316,9 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
int i;
int multiplier;
struct timespec t;
+ int repeat = 0, low_predicted = 0;
+ int cpu = smp_processor_id();
+ struct hrtimer *hrtmr = &per_cpu(menu_hrtimer, cpu);
if (data->needs_update) {
menu_update(drv, dev);
@@ -274,7 +353,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
data->predicted_us = div_round64(data->expected_us * data->correction_factor[data->bucket],
RESOLUTION * DECAY);
- detect_repeating_patterns(data);
+ repeat = get_typical_interval(data);
/*
* We want to default to C1 (hlt), not to busy polling
@@ -295,8 +374,10 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
if (s->disabled || su->disable)
continue;
- if (s->target_residency > data->predicted_us)
+ if (s->target_residency > data->predicted_us) {
+ low_predicted = 1;
continue;
+ }
if (s->exit_latency > latency_req)
continue;
if (s->exit_latency * multiplier > data->predicted_us)
@@ -309,6 +390,44 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
}
}
+ /* not deepest C-state chosen for low predicted residency */
+ if (low_predicted) {
+ unsigned int timer_us = 0;
+ unsigned int perfect_us = 0;
+
+ /*
+ * Set a timer to detect whether this sleep is much
+ * longer than repeat mode predicted. If the timer
+ * triggers, the code will evaluate whether to put
+ * the CPU into a deeper C-state.
+ * The timer is cancelled on CPU wakeup.
+ */
+ timer_us = 2 * (data->predicted_us + MAX_DEVIATION);
+
+ perfect_us = perfect_cstate_ms * 1000;
+
+ if (repeat && (4 * timer_us < data->expected_us)) {
+ RCU_NONIDLE(hrtimer_start(hrtmr,
+ ns_to_ktime(1000 * timer_us),
+ HRTIMER_MODE_REL_PINNED));
+ /* In repeat case, menu hrtimer is started */
+ per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_REPEAT;
+ } else if (perfect_us < data->expected_us) {
+ /*
+ * The next timer is long. This could be because
+ * we did not make a useful prediction.
+ * In that case, it makes sense to re-enter
+ * into a deeper C-state after some time.
+ */
+ RCU_NONIDLE(hrtimer_start(hrtmr,
+ ns_to_ktime(1000 * timer_us),
+ HRTIMER_MODE_REL_PINNED));
+ /* In general case, menu hrtimer is started */
+ per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_GENERAL;
+ }
+
+ }
+
return data->last_state_idx;
}
@@ -399,6 +518,9 @@ static int menu_enable_device(struct cpuidle_driver *drv,
struct cpuidle_device *dev)
{
struct menu_device *data = &per_cpu(menu_devices, dev->cpu);
+ struct hrtimer *t = &per_cpu(menu_hrtimer, dev->cpu);
+ hrtimer_init(t, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ t->function = menu_hrtimer_notify;
memset(data, 0, sizeof(struct menu_device));
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c
index 5f809e337b8..34094294610 100644
--- a/drivers/cpuidle/sysfs.c
+++ b/drivers/cpuidle/sysfs.c
@@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/capability.h>
+#include <linux/device.h>
#include "cpuidle.h"
@@ -297,6 +298,13 @@ static struct attribute *cpuidle_state_default_attrs[] = {
NULL
};
+struct cpuidle_state_kobj {
+ struct cpuidle_state *state;
+ struct cpuidle_state_usage *state_usage;
+ struct completion kobj_unregister;
+ struct kobject kobj;
+};
+
#define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj)
#define kobj_to_state(k) (kobj_to_state_obj(k)->state)
#define kobj_to_state_usage(k) (kobj_to_state_obj(k)->state_usage)
@@ -356,17 +364,17 @@ static inline void cpuidle_free_state_kobj(struct cpuidle_device *device, int i)
}
/**
- * cpuidle_add_driver_sysfs - adds driver-specific sysfs attributes
+ * cpuidle_add_state_sysfs - adds cpuidle states sysfs attributes
* @device: the target device
*/
-int cpuidle_add_state_sysfs(struct cpuidle_device *device)
+static int cpuidle_add_state_sysfs(struct cpuidle_device *device)
{
int i, ret = -ENOMEM;
struct cpuidle_state_kobj *kobj;
- struct cpuidle_driver *drv = cpuidle_get_driver();
+ struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device);
/* state statistics */
- for (i = 0; i < device->state_count; i++) {
+ for (i = 0; i < drv->state_count; i++) {
kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL);
if (!kobj)
goto error_state;
@@ -374,8 +382,8 @@ int cpuidle_add_state_sysfs(struct cpuidle_device *device)
kobj->state_usage = &device->states_usage[i];
init_completion(&kobj->kobj_unregister);
- ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle, &device->kobj,
- "state%d", i);
+ ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle,
+ &device->kobj, "state%d", i);
if (ret) {
kfree(kobj);
goto error_state;
@@ -393,10 +401,10 @@ error_state:
}
/**
- * cpuidle_remove_driver_sysfs - removes driver-specific sysfs attributes
+ * cpuidle_remove_driver_sysfs - removes the cpuidle states sysfs attributes
* @device: the target device
*/
-void cpuidle_remove_state_sysfs(struct cpuidle_device *device)
+static void cpuidle_remove_state_sysfs(struct cpuidle_device *device)
{
int i;
@@ -404,17 +412,179 @@ void cpuidle_remove_state_sysfs(struct cpuidle_device *device)
cpuidle_free_state_kobj(device, i);
}
+#ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
+#define kobj_to_driver_kobj(k) container_of(k, struct cpuidle_driver_kobj, kobj)
+#define attr_to_driver_attr(a) container_of(a, struct cpuidle_driver_attr, attr)
+
+#define define_one_driver_ro(_name, show) \
+ static struct cpuidle_driver_attr attr_driver_##_name = \
+ __ATTR(_name, 0644, show, NULL)
+
+struct cpuidle_driver_kobj {
+ struct cpuidle_driver *drv;
+ struct completion kobj_unregister;
+ struct kobject kobj;
+};
+
+struct cpuidle_driver_attr {
+ struct attribute attr;
+ ssize_t (*show)(struct cpuidle_driver *, char *);
+ ssize_t (*store)(struct cpuidle_driver *, const char *, size_t);
+};
+
+static ssize_t show_driver_name(struct cpuidle_driver *drv, char *buf)
+{
+ ssize_t ret;
+
+ spin_lock(&cpuidle_driver_lock);
+ ret = sprintf(buf, "%s\n", drv ? drv->name : "none");
+ spin_unlock(&cpuidle_driver_lock);
+
+ return ret;
+}
+
+static void cpuidle_driver_sysfs_release(struct kobject *kobj)
+{
+ struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj);
+ complete(&driver_kobj->kobj_unregister);
+}
+
+static ssize_t cpuidle_driver_show(struct kobject *kobj, struct attribute * attr,
+ char * buf)
+{
+ int ret = -EIO;
+ struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj);
+ struct cpuidle_driver_attr *dattr = attr_to_driver_attr(attr);
+
+ if (dattr->show)
+ ret = dattr->show(driver_kobj->drv, buf);
+
+ return ret;
+}
+
+static ssize_t cpuidle_driver_store(struct kobject *kobj, struct attribute *attr,
+ const char *buf, size_t size)
+{
+ int ret = -EIO;
+ struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj);
+ struct cpuidle_driver_attr *dattr = attr_to_driver_attr(attr);
+
+ if (dattr->store)
+ ret = dattr->store(driver_kobj->drv, buf, size);
+
+ return ret;
+}
+
+define_one_driver_ro(name, show_driver_name);
+
+static const struct sysfs_ops cpuidle_driver_sysfs_ops = {
+ .show = cpuidle_driver_show,
+ .store = cpuidle_driver_store,
+};
+
+static struct attribute *cpuidle_driver_default_attrs[] = {
+ &attr_driver_name.attr,
+ NULL
+};
+
+static struct kobj_type ktype_driver_cpuidle = {
+ .sysfs_ops = &cpuidle_driver_sysfs_ops,
+ .default_attrs = cpuidle_driver_default_attrs,
+ .release = cpuidle_driver_sysfs_release,
+};
+
+/**
+ * cpuidle_add_driver_sysfs - adds the driver name sysfs attribute
+ * @device: the target device
+ */
+static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev)
+{
+ struct cpuidle_driver_kobj *kdrv;
+ struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
+ int ret;
+
+ kdrv = kzalloc(sizeof(*kdrv), GFP_KERNEL);
+ if (!kdrv)
+ return -ENOMEM;
+
+ kdrv->drv = drv;
+ init_completion(&kdrv->kobj_unregister);
+
+ ret = kobject_init_and_add(&kdrv->kobj, &ktype_driver_cpuidle,
+ &dev->kobj, "driver");
+ if (ret) {
+ kfree(kdrv);
+ return ret;
+ }
+
+ kobject_uevent(&kdrv->kobj, KOBJ_ADD);
+ dev->kobj_driver = kdrv;
+
+ return ret;
+}
+
+/**
+ * cpuidle_remove_driver_sysfs - removes the driver name sysfs attribute
+ * @device: the target device
+ */
+static void cpuidle_remove_driver_sysfs(struct cpuidle_device *dev)
+{
+ struct cpuidle_driver_kobj *kdrv = dev->kobj_driver;
+ kobject_put(&kdrv->kobj);
+ wait_for_completion(&kdrv->kobj_unregister);
+ kfree(kdrv);
+}
+#else
+static inline int cpuidle_add_driver_sysfs(struct cpuidle_device *dev)
+{
+ return 0;
+}
+
+static inline void cpuidle_remove_driver_sysfs(struct cpuidle_device *dev)
+{
+ ;
+}
+#endif
+
+/**
+ * cpuidle_add_device_sysfs - adds device specific sysfs attributes
+ * @device: the target device
+ */
+int cpuidle_add_device_sysfs(struct cpuidle_device *device)
+{
+ int ret;
+
+ ret = cpuidle_add_state_sysfs(device);
+ if (ret)
+ return ret;
+
+ ret = cpuidle_add_driver_sysfs(device);
+ if (ret)
+ cpuidle_remove_state_sysfs(device);
+ return ret;
+}
+
+/**
+ * cpuidle_remove_device_sysfs : removes device specific sysfs attributes
+ * @device : the target device
+ */
+void cpuidle_remove_device_sysfs(struct cpuidle_device *device)
+{
+ cpuidle_remove_driver_sysfs(device);
+ cpuidle_remove_state_sysfs(device);
+}
+
/**
* cpuidle_add_sysfs - creates a sysfs instance for the target device
* @dev: the target device
*/
-int cpuidle_add_sysfs(struct device *cpu_dev)
+int cpuidle_add_sysfs(struct cpuidle_device *dev)
{
- int cpu = cpu_dev->id;
- struct cpuidle_device *dev;
+ struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
int error;
- dev = per_cpu(cpuidle_devices, cpu);
+ init_completion(&dev->kobj_unregister);
+
error = kobject_init_and_add(&dev->kobj, &ktype_cpuidle, &cpu_dev->kobj,
"cpuidle");
if (!error)
@@ -426,11 +596,8 @@ int cpuidle_add_sysfs(struct device *cpu_dev)
* cpuidle_remove_sysfs - deletes a sysfs instance on the target device
* @dev: the target device
*/
-void cpuidle_remove_sysfs(struct device *cpu_dev)
+void cpuidle_remove_sysfs(struct cpuidle_device *dev)
{
- int cpu = cpu_dev->id;
- struct cpuidle_device *dev;
-
- dev = per_cpu(cpuidle_devices, cpu);
kobject_put(&dev->kobj);
+ wait_for_completion(&dev->kobj_unregister);
}
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 308c7fb92a6..f6644f59fd9 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -224,7 +224,7 @@ config CRYPTO_DEV_TALITOS
config CRYPTO_DEV_IXP4XX
tristate "Driver for IXP4xx crypto hardware acceleration"
- depends on ARCH_IXP4XX
+ depends on ARCH_IXP4XX && IXP4XX_QMGR && IXP4XX_NPE
select CRYPTO_DES
select CRYPTO_ALGAPI
select CRYPTO_AUTHENC
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index 8f3f74ce8c7..21180d6cad6 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -750,12 +750,12 @@ static int setup_cipher(struct crypto_tfm *tfm, int encrypt,
}
if (cipher_cfg & MOD_AES) {
switch (key_len) {
- case 16: keylen_cfg = MOD_AES128 | KEYLEN_128; break;
- case 24: keylen_cfg = MOD_AES192 | KEYLEN_192; break;
- case 32: keylen_cfg = MOD_AES256 | KEYLEN_256; break;
- default:
- *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
- return -EINVAL;
+ case 16: keylen_cfg = MOD_AES128; break;
+ case 24: keylen_cfg = MOD_AES192; break;
+ case 32: keylen_cfg = MOD_AES256; break;
+ default:
+ *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
}
cipher_cfg |= keylen_cfg;
} else if (cipher_cfg & MOD_3DES) {
diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index f6b0a6e2ea5..0f079be1330 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -30,7 +30,7 @@ if PM_DEVFREQ
comment "DEVFREQ Governors"
config DEVFREQ_GOV_SIMPLE_ONDEMAND
- bool "Simple Ondemand"
+ tristate "Simple Ondemand"
help
Chooses frequency based on the recent load on the device. Works
similar as ONDEMAND governor of CPUFREQ does. A device with
@@ -39,7 +39,7 @@ config DEVFREQ_GOV_SIMPLE_ONDEMAND
values to the governor with data field at devfreq_add_device().
config DEVFREQ_GOV_PERFORMANCE
- bool "Performance"
+ tristate "Performance"
help
Sets the frequency at the maximum available frequency.
This governor always returns UINT_MAX as frequency so that
@@ -47,7 +47,7 @@ config DEVFREQ_GOV_PERFORMANCE
at any time.
config DEVFREQ_GOV_POWERSAVE
- bool "Powersave"
+ tristate "Powersave"
help
Sets the frequency at the minimum available frequency.
This governor always returns 0 as frequency so that
@@ -55,7 +55,7 @@ config DEVFREQ_GOV_POWERSAVE
at any time.
config DEVFREQ_GOV_USERSPACE
- bool "Userspace"
+ tristate "Userspace"
help
Sets the frequency at the user specified one.
This governor returns the user configured frequency if there
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index b146d76f04c..53766f39aad 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -27,21 +27,17 @@
#include <linux/hrtimer.h>
#include "governor.h"
-struct class *devfreq_class;
+static struct class *devfreq_class;
/*
- * devfreq_work periodically monitors every registered device.
- * The minimum polling interval is one jiffy. The polling interval is
- * determined by the minimum polling period among all polling devfreq
- * devices. The resolution of polling interval is one jiffy.
+ * devfreq core provides delayed work based load monitoring helper
+ * functions. Governors can use these or can implement their own
+ * monitoring mechanism.
*/
-static bool polling;
static struct workqueue_struct *devfreq_wq;
-static struct delayed_work devfreq_work;
-
-/* wait removing if this is to be removed */
-static struct devfreq *wait_remove_device;
+/* The list of all device-devfreq governors */
+static LIST_HEAD(devfreq_governor_list);
/* The list of all device-devfreq */
static LIST_HEAD(devfreq_list);
static DEFINE_MUTEX(devfreq_list_lock);
@@ -73,6 +69,79 @@ static struct devfreq *find_device_devfreq(struct device *dev)
}
/**
+ * devfreq_get_freq_level() - Lookup freq_table for the frequency
+ * @devfreq: the devfreq instance
+ * @freq: the target frequency
+ */
+static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq)
+{
+ int lev;
+
+ for (lev = 0; lev < devfreq->profile->max_state; lev++)
+ if (freq == devfreq->profile->freq_table[lev])
+ return lev;
+
+ return -EINVAL;
+}
+
+/**
+ * devfreq_update_status() - Update statistics of devfreq behavior
+ * @devfreq: the devfreq instance
+ * @freq: the update target frequency
+ */
+static int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
+{
+ int lev, prev_lev;
+ unsigned long cur_time;
+
+ lev = devfreq_get_freq_level(devfreq, freq);
+ if (lev < 0)
+ return lev;
+
+ cur_time = jiffies;
+ devfreq->time_in_state[lev] +=
+ cur_time - devfreq->last_stat_updated;
+ if (freq != devfreq->previous_freq) {
+ prev_lev = devfreq_get_freq_level(devfreq,
+ devfreq->previous_freq);
+ devfreq->trans_table[(prev_lev *
+ devfreq->profile->max_state) + lev]++;
+ devfreq->total_trans++;
+ }
+ devfreq->last_stat_updated = cur_time;
+
+ return 0;
+}
+
+/**
+ * find_devfreq_governor() - find devfreq governor from name
+ * @name: name of the governor
+ *
+ * Search the list of devfreq governors and return the matched
+ * governor's pointer. devfreq_list_lock should be held by the caller.
+ */
+static struct devfreq_governor *find_devfreq_governor(const char *name)
+{
+ struct devfreq_governor *tmp_governor;
+
+ if (unlikely(IS_ERR_OR_NULL(name))) {
+ pr_err("DEVFREQ: %s: Invalid parameters\n", __func__);
+ return ERR_PTR(-EINVAL);
+ }
+ WARN(!mutex_is_locked(&devfreq_list_lock),
+ "devfreq_list_lock must be locked.");
+
+ list_for_each_entry(tmp_governor, &devfreq_governor_list, node) {
+ if (!strncmp(tmp_governor->name, name, DEVFREQ_NAME_LEN))
+ return tmp_governor;
+ }
+
+ return ERR_PTR(-ENODEV);
+}
+
+/* Load monitoring helper functions for governors use */
+
+/**
* update_devfreq() - Reevaluate the device and configure frequency.
* @devfreq: the devfreq instance.
*
@@ -90,6 +159,9 @@ int update_devfreq(struct devfreq *devfreq)
return -EINVAL;
}
+ if (!devfreq->governor)
+ return -EINVAL;
+
/* Reevaluate the proper frequency */
err = devfreq->governor->get_target_freq(devfreq, &freq);
if (err)
@@ -116,16 +188,173 @@ int update_devfreq(struct devfreq *devfreq)
if (err)
return err;
+ if (devfreq->profile->freq_table)
+ if (devfreq_update_status(devfreq, freq))
+ dev_err(&devfreq->dev,
+ "Couldn't update frequency transition information.\n");
+
devfreq->previous_freq = freq;
return err;
}
+EXPORT_SYMBOL(update_devfreq);
+
+/**
+ * devfreq_monitor() - Periodically poll devfreq objects.
+ * @work: the work struct used to run devfreq_monitor periodically.
+ *
+ */
+static void devfreq_monitor(struct work_struct *work)
+{
+ int err;
+ struct devfreq *devfreq = container_of(work,
+ struct devfreq, work.work);
+
+ mutex_lock(&devfreq->lock);
+ err = update_devfreq(devfreq);
+ if (err)
+ dev_err(&devfreq->dev, "dvfs failed with (%d) error\n", err);
+
+ queue_delayed_work(devfreq_wq, &devfreq->work,
+ msecs_to_jiffies(devfreq->profile->polling_ms));
+ mutex_unlock(&devfreq->lock);
+}
+
+/**
+ * devfreq_monitor_start() - Start load monitoring of devfreq instance
+ * @devfreq: the devfreq instance.
+ *
+ * Helper function for starting devfreq device load monitoing. By
+ * default delayed work based monitoring is supported. Function
+ * to be called from governor in response to DEVFREQ_GOV_START
+ * event when device is added to devfreq framework.
+ */
+void devfreq_monitor_start(struct devfreq *devfreq)
+{
+ INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor);
+ if (devfreq->profile->polling_ms)
+ queue_delayed_work(devfreq_wq, &devfreq->work,
+ msecs_to_jiffies(devfreq->profile->polling_ms));
+}
+EXPORT_SYMBOL(devfreq_monitor_start);
+
+/**
+ * devfreq_monitor_stop() - Stop load monitoring of a devfreq instance
+ * @devfreq: the devfreq instance.
+ *
+ * Helper function to stop devfreq device load monitoing. Function
+ * to be called from governor in response to DEVFREQ_GOV_STOP
+ * event when device is removed from devfreq framework.
+ */
+void devfreq_monitor_stop(struct devfreq *devfreq)
+{
+ cancel_delayed_work_sync(&devfreq->work);
+}
+EXPORT_SYMBOL(devfreq_monitor_stop);
+
+/**
+ * devfreq_monitor_suspend() - Suspend load monitoring of a devfreq instance
+ * @devfreq: the devfreq instance.
+ *
+ * Helper function to suspend devfreq device load monitoing. Function
+ * to be called from governor in response to DEVFREQ_GOV_SUSPEND
+ * event or when polling interval is set to zero.
+ *
+ * Note: Though this function is same as devfreq_monitor_stop(),
+ * intentionally kept separate to provide hooks for collecting
+ * transition statistics.
+ */
+void devfreq_monitor_suspend(struct devfreq *devfreq)
+{
+ mutex_lock(&devfreq->lock);
+ if (devfreq->stop_polling) {
+ mutex_unlock(&devfreq->lock);
+ return;
+ }
+
+ devfreq->stop_polling = true;
+ mutex_unlock(&devfreq->lock);
+ cancel_delayed_work_sync(&devfreq->work);
+}
+EXPORT_SYMBOL(devfreq_monitor_suspend);
+
+/**
+ * devfreq_monitor_resume() - Resume load monitoring of a devfreq instance
+ * @devfreq: the devfreq instance.
+ *
+ * Helper function to resume devfreq device load monitoing. Function
+ * to be called from governor in response to DEVFREQ_GOV_RESUME
+ * event or when polling interval is set to non-zero.
+ */
+void devfreq_monitor_resume(struct devfreq *devfreq)
+{
+ mutex_lock(&devfreq->lock);
+ if (!devfreq->stop_polling)
+ goto out;
+
+ if (!delayed_work_pending(&devfreq->work) &&
+ devfreq->profile->polling_ms)
+ queue_delayed_work(devfreq_wq, &devfreq->work,
+ msecs_to_jiffies(devfreq->profile->polling_ms));
+ devfreq->stop_polling = false;
+
+out:
+ mutex_unlock(&devfreq->lock);
+}
+EXPORT_SYMBOL(devfreq_monitor_resume);
+
+/**
+ * devfreq_interval_update() - Update device devfreq monitoring interval
+ * @devfreq: the devfreq instance.
+ * @delay: new polling interval to be set.
+ *
+ * Helper function to set new load monitoring polling interval. Function
+ * to be called from governor in response to DEVFREQ_GOV_INTERVAL event.
+ */
+void devfreq_interval_update(struct devfreq *devfreq, unsigned int *delay)
+{
+ unsigned int cur_delay = devfreq->profile->polling_ms;
+ unsigned int new_delay = *delay;
+
+ mutex_lock(&devfreq->lock);
+ devfreq->profile->polling_ms = new_delay;
+
+ if (devfreq->stop_polling)
+ goto out;
+
+ /* if new delay is zero, stop polling */
+ if (!new_delay) {
+ mutex_unlock(&devfreq->lock);
+ cancel_delayed_work_sync(&devfreq->work);
+ return;
+ }
+
+ /* if current delay is zero, start polling with new delay */
+ if (!cur_delay) {
+ queue_delayed_work(devfreq_wq, &devfreq->work,
+ msecs_to_jiffies(devfreq->profile->polling_ms));
+ goto out;
+ }
+
+ /* if current delay is greater than new delay, restart polling */
+ if (cur_delay > new_delay) {
+ mutex_unlock(&devfreq->lock);
+ cancel_delayed_work_sync(&devfreq->work);
+ mutex_lock(&devfreq->lock);
+ if (!devfreq->stop_polling)
+ queue_delayed_work(devfreq_wq, &devfreq->work,
+ msecs_to_jiffies(devfreq->profile->polling_ms));
+ }
+out:
+ mutex_unlock(&devfreq->lock);
+}
+EXPORT_SYMBOL(devfreq_interval_update);
/**
* devfreq_notifier_call() - Notify that the device frequency requirements
* has been changed out of devfreq framework.
- * @nb the notifier_block (supposed to be devfreq->nb)
- * @type not used
- * @devp not used
+ * @nb: the notifier_block (supposed to be devfreq->nb)
+ * @type: not used
+ * @devp: not used
*
* Called by a notifier that uses devfreq->nb.
*/
@@ -143,59 +372,34 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type,
}
/**
- * _remove_devfreq() - Remove devfreq from the device.
+ * _remove_devfreq() - Remove devfreq from the list and release its resources.
* @devfreq: the devfreq struct
* @skip: skip calling device_unregister().
- *
- * Note that the caller should lock devfreq->lock before calling
- * this. _remove_devfreq() will unlock it and free devfreq
- * internally. devfreq_list_lock should be locked by the caller
- * as well (not relased at return)
- *
- * Lock usage:
- * devfreq->lock: locked before call.
- * unlocked at return (and freed)
- * devfreq_list_lock: locked before call.
- * kept locked at return.
- * if devfreq is centrally polled.
- *
- * Freed memory:
- * devfreq
*/
static void _remove_devfreq(struct devfreq *devfreq, bool skip)
{
- if (!mutex_is_locked(&devfreq->lock)) {
- WARN(true, "devfreq->lock must be locked by the caller.\n");
- return;
- }
- if (!devfreq->governor->no_central_polling &&
- !mutex_is_locked(&devfreq_list_lock)) {
- WARN(true, "devfreq_list_lock must be locked by the caller.\n");
+ mutex_lock(&devfreq_list_lock);
+ if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) {
+ mutex_unlock(&devfreq_list_lock);
+ dev_warn(&devfreq->dev, "releasing devfreq which doesn't exist\n");
return;
}
+ list_del(&devfreq->node);
+ mutex_unlock(&devfreq_list_lock);
- if (devfreq->being_removed)
- return;
-
- devfreq->being_removed = true;
+ if (devfreq->governor)
+ devfreq->governor->event_handler(devfreq,
+ DEVFREQ_GOV_STOP, NULL);
if (devfreq->profile->exit)
devfreq->profile->exit(devfreq->dev.parent);
- if (devfreq->governor->exit)
- devfreq->governor->exit(devfreq);
-
if (!skip && get_device(&devfreq->dev)) {
device_unregister(&devfreq->dev);
put_device(&devfreq->dev);
}
- if (!devfreq->governor->no_central_polling)
- list_del(&devfreq->node);
-
- mutex_unlock(&devfreq->lock);
mutex_destroy(&devfreq->lock);
-
kfree(devfreq);
}
@@ -210,163 +414,39 @@ static void _remove_devfreq(struct devfreq *devfreq, bool skip)
static void devfreq_dev_release(struct device *dev)
{
struct devfreq *devfreq = to_devfreq(dev);
- bool central_polling = !devfreq->governor->no_central_polling;
-
- /*
- * If devfreq_dev_release() was called by device_unregister() of
- * _remove_devfreq(), we cannot mutex_lock(&devfreq->lock) and
- * being_removed is already set. This also partially checks the case
- * where devfreq_dev_release() is called from a thread other than
- * the one called _remove_devfreq(); however, this case is
- * dealt completely with another following being_removed check.
- *
- * Because being_removed is never being
- * unset, we do not need to worry about race conditions on
- * being_removed.
- */
- if (devfreq->being_removed)
- return;
-
- if (central_polling)
- mutex_lock(&devfreq_list_lock);
-
- mutex_lock(&devfreq->lock);
- /*
- * Check being_removed flag again for the case where
- * devfreq_dev_release() was called in a thread other than the one
- * possibly called _remove_devfreq().
- */
- if (devfreq->being_removed) {
- mutex_unlock(&devfreq->lock);
- goto out;
- }
-
- /* devfreq->lock is unlocked and removed in _removed_devfreq() */
_remove_devfreq(devfreq, true);
-
-out:
- if (central_polling)
- mutex_unlock(&devfreq_list_lock);
-}
-
-/**
- * devfreq_monitor() - Periodically poll devfreq objects.
- * @work: the work struct used to run devfreq_monitor periodically.
- *
- */
-static void devfreq_monitor(struct work_struct *work)
-{
- static unsigned long last_polled_at;
- struct devfreq *devfreq, *tmp;
- int error;
- unsigned long jiffies_passed;
- unsigned long next_jiffies = ULONG_MAX, now = jiffies;
- struct device *dev;
-
- /* Initially last_polled_at = 0, polling every device at bootup */
- jiffies_passed = now - last_polled_at;
- last_polled_at = now;
- if (jiffies_passed == 0)
- jiffies_passed = 1;
-
- mutex_lock(&devfreq_list_lock);
- list_for_each_entry_safe(devfreq, tmp, &devfreq_list, node) {
- mutex_lock(&devfreq->lock);
- dev = devfreq->dev.parent;
-
- /* Do not remove tmp for a while */
- wait_remove_device = tmp;
-
- if (devfreq->governor->no_central_polling ||
- devfreq->next_polling == 0) {
- mutex_unlock(&devfreq->lock);
- continue;
- }
- mutex_unlock(&devfreq_list_lock);
-
- /*
- * Reduce more next_polling if devfreq_wq took an extra
- * delay. (i.e., CPU has been idled.)
- */
- if (devfreq->next_polling <= jiffies_passed) {
- error = update_devfreq(devfreq);
-
- /* Remove a devfreq with an error. */
- if (error && error != -EAGAIN) {
-
- dev_err(dev, "Due to update_devfreq error(%d), devfreq(%s) is removed from the device\n",
- error, devfreq->governor->name);
-
- /*
- * Unlock devfreq before locking the list
- * in order to avoid deadlock with
- * find_device_devfreq or others
- */
- mutex_unlock(&devfreq->lock);
- mutex_lock(&devfreq_list_lock);
- /* Check if devfreq is already removed */
- if (IS_ERR(find_device_devfreq(dev)))
- continue;
- mutex_lock(&devfreq->lock);
- /* This unlocks devfreq->lock and free it */
- _remove_devfreq(devfreq, false);
- continue;
- }
- devfreq->next_polling = devfreq->polling_jiffies;
- } else {
- devfreq->next_polling -= jiffies_passed;
- }
-
- if (devfreq->next_polling)
- next_jiffies = (next_jiffies > devfreq->next_polling) ?
- devfreq->next_polling : next_jiffies;
-
- mutex_unlock(&devfreq->lock);
- mutex_lock(&devfreq_list_lock);
- }
- wait_remove_device = NULL;
- mutex_unlock(&devfreq_list_lock);
-
- if (next_jiffies > 0 && next_jiffies < ULONG_MAX) {
- polling = true;
- queue_delayed_work(devfreq_wq, &devfreq_work, next_jiffies);
- } else {
- polling = false;
- }
}
/**
* devfreq_add_device() - Add devfreq feature to the device
* @dev: the device to add devfreq feature.
* @profile: device-specific profile to run devfreq.
- * @governor: the policy to choose frequency.
+ * @governor_name: name of the policy to choose frequency.
* @data: private data for the governor. The devfreq framework does not
* touch this value.
*/
struct devfreq *devfreq_add_device(struct device *dev,
struct devfreq_dev_profile *profile,
- const struct devfreq_governor *governor,
+ const char *governor_name,
void *data)
{
struct devfreq *devfreq;
+ struct devfreq_governor *governor;
int err = 0;
- if (!dev || !profile || !governor) {
+ if (!dev || !profile || !governor_name) {
dev_err(dev, "%s: Invalid parameters.\n", __func__);
return ERR_PTR(-EINVAL);
}
-
- if (!governor->no_central_polling) {
- mutex_lock(&devfreq_list_lock);
- devfreq = find_device_devfreq(dev);
- mutex_unlock(&devfreq_list_lock);
- if (!IS_ERR(devfreq)) {
- dev_err(dev, "%s: Unable to create devfreq for the device. It already has one.\n", __func__);
- err = -EINVAL;
- goto err_out;
- }
+ mutex_lock(&devfreq_list_lock);
+ devfreq = find_device_devfreq(dev);
+ mutex_unlock(&devfreq_list_lock);
+ if (!IS_ERR(devfreq)) {
+ dev_err(dev, "%s: Unable to create devfreq for the device. It already has one.\n", __func__);
+ err = -EINVAL;
+ goto err_out;
}
devfreq = kzalloc(sizeof(struct devfreq), GFP_KERNEL);
@@ -383,92 +463,316 @@ struct devfreq *devfreq_add_device(struct device *dev,
devfreq->dev.class = devfreq_class;
devfreq->dev.release = devfreq_dev_release;
devfreq->profile = profile;
- devfreq->governor = governor;
+ strncpy(devfreq->governor_name, governor_name, DEVFREQ_NAME_LEN);
devfreq->previous_freq = profile->initial_freq;
devfreq->data = data;
- devfreq->next_polling = devfreq->polling_jiffies
- = msecs_to_jiffies(devfreq->profile->polling_ms);
devfreq->nb.notifier_call = devfreq_notifier_call;
+ devfreq->trans_table = devm_kzalloc(dev, sizeof(unsigned int) *
+ devfreq->profile->max_state *
+ devfreq->profile->max_state,
+ GFP_KERNEL);
+ devfreq->time_in_state = devm_kzalloc(dev, sizeof(unsigned int) *
+ devfreq->profile->max_state,
+ GFP_KERNEL);
+ devfreq->last_stat_updated = jiffies;
+
dev_set_name(&devfreq->dev, dev_name(dev));
err = device_register(&devfreq->dev);
if (err) {
put_device(&devfreq->dev);
+ mutex_unlock(&devfreq->lock);
goto err_dev;
}
- if (governor->init)
- err = governor->init(devfreq);
- if (err)
- goto err_init;
-
mutex_unlock(&devfreq->lock);
- if (governor->no_central_polling)
- goto out;
-
mutex_lock(&devfreq_list_lock);
-
list_add(&devfreq->node, &devfreq_list);
- if (devfreq_wq && devfreq->next_polling && !polling) {
- polling = true;
- queue_delayed_work(devfreq_wq, &devfreq_work,
- devfreq->next_polling);
- }
+ governor = find_devfreq_governor(devfreq->governor_name);
+ if (!IS_ERR(governor))
+ devfreq->governor = governor;
+ if (devfreq->governor)
+ err = devfreq->governor->event_handler(devfreq,
+ DEVFREQ_GOV_START, NULL);
mutex_unlock(&devfreq_list_lock);
-out:
+ if (err) {
+ dev_err(dev, "%s: Unable to start governor for the device\n",
+ __func__);
+ goto err_init;
+ }
+
return devfreq;
err_init:
+ list_del(&devfreq->node);
device_unregister(&devfreq->dev);
err_dev:
- mutex_unlock(&devfreq->lock);
kfree(devfreq);
err_out:
return ERR_PTR(err);
}
+EXPORT_SYMBOL(devfreq_add_device);
/**
* devfreq_remove_device() - Remove devfreq feature from a device.
- * @devfreq the devfreq instance to be removed
+ * @devfreq: the devfreq instance to be removed
*/
int devfreq_remove_device(struct devfreq *devfreq)
{
- bool central_polling;
+ if (!devfreq)
+ return -EINVAL;
+
+ _remove_devfreq(devfreq, false);
+ return 0;
+}
+EXPORT_SYMBOL(devfreq_remove_device);
+
+/**
+ * devfreq_suspend_device() - Suspend devfreq of a device.
+ * @devfreq: the devfreq instance to be suspended
+ */
+int devfreq_suspend_device(struct devfreq *devfreq)
+{
if (!devfreq)
return -EINVAL;
- central_polling = !devfreq->governor->no_central_polling;
+ if (!devfreq->governor)
+ return 0;
+
+ return devfreq->governor->event_handler(devfreq,
+ DEVFREQ_GOV_SUSPEND, NULL);
+}
+EXPORT_SYMBOL(devfreq_suspend_device);
+
+/**
+ * devfreq_resume_device() - Resume devfreq of a device.
+ * @devfreq: the devfreq instance to be resumed
+ */
+int devfreq_resume_device(struct devfreq *devfreq)
+{
+ if (!devfreq)
+ return -EINVAL;
+
+ if (!devfreq->governor)
+ return 0;
+
+ return devfreq->governor->event_handler(devfreq,
+ DEVFREQ_GOV_RESUME, NULL);
+}
+EXPORT_SYMBOL(devfreq_resume_device);
+
+/**
+ * devfreq_add_governor() - Add devfreq governor
+ * @governor: the devfreq governor to be added
+ */
+int devfreq_add_governor(struct devfreq_governor *governor)
+{
+ struct devfreq_governor *g;
+ struct devfreq *devfreq;
+ int err = 0;
+
+ if (!governor) {
+ pr_err("%s: Invalid parameters.\n", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&devfreq_list_lock);
+ g = find_devfreq_governor(governor->name);
+ if (!IS_ERR(g)) {
+ pr_err("%s: governor %s already registered\n", __func__,
+ g->name);
+ err = -EINVAL;
+ goto err_out;
+ }
- if (central_polling) {
- mutex_lock(&devfreq_list_lock);
- while (wait_remove_device == devfreq) {
- mutex_unlock(&devfreq_list_lock);
- schedule();
- mutex_lock(&devfreq_list_lock);
+ list_add(&governor->node, &devfreq_governor_list);
+
+ list_for_each_entry(devfreq, &devfreq_list, node) {
+ int ret = 0;
+ struct device *dev = devfreq->dev.parent;
+
+ if (!strncmp(devfreq->governor_name, governor->name,
+ DEVFREQ_NAME_LEN)) {
+ /* The following should never occur */
+ if (devfreq->governor) {
+ dev_warn(dev,
+ "%s: Governor %s already present\n",
+ __func__, devfreq->governor->name);
+ ret = devfreq->governor->event_handler(devfreq,
+ DEVFREQ_GOV_STOP, NULL);
+ if (ret) {
+ dev_warn(dev,
+ "%s: Governor %s stop = %d\n",
+ __func__,
+ devfreq->governor->name, ret);
+ }
+ /* Fall through */
+ }
+ devfreq->governor = governor;
+ ret = devfreq->governor->event_handler(devfreq,
+ DEVFREQ_GOV_START, NULL);
+ if (ret) {
+ dev_warn(dev, "%s: Governor %s start=%d\n",
+ __func__, devfreq->governor->name,
+ ret);
+ }
}
}
- mutex_lock(&devfreq->lock);
- _remove_devfreq(devfreq, false); /* it unlocks devfreq->lock */
+err_out:
+ mutex_unlock(&devfreq_list_lock);
- if (central_polling)
- mutex_unlock(&devfreq_list_lock);
+ return err;
+}
+EXPORT_SYMBOL(devfreq_add_governor);
- return 0;
+/**
+ * devfreq_remove_device() - Remove devfreq feature from a device.
+ * @governor: the devfreq governor to be removed
+ */
+int devfreq_remove_governor(struct devfreq_governor *governor)
+{
+ struct devfreq_governor *g;
+ struct devfreq *devfreq;
+ int err = 0;
+
+ if (!governor) {
+ pr_err("%s: Invalid parameters.\n", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&devfreq_list_lock);
+ g = find_devfreq_governor(governor->name);
+ if (IS_ERR(g)) {
+ pr_err("%s: governor %s not registered\n", __func__,
+ governor->name);
+ err = PTR_ERR(g);
+ goto err_out;
+ }
+ list_for_each_entry(devfreq, &devfreq_list, node) {
+ int ret;
+ struct device *dev = devfreq->dev.parent;
+
+ if (!strncmp(devfreq->governor_name, governor->name,
+ DEVFREQ_NAME_LEN)) {
+ /* we should have a devfreq governor! */
+ if (!devfreq->governor) {
+ dev_warn(dev, "%s: Governor %s NOT present\n",
+ __func__, governor->name);
+ continue;
+ /* Fall through */
+ }
+ ret = devfreq->governor->event_handler(devfreq,
+ DEVFREQ_GOV_STOP, NULL);
+ if (ret) {
+ dev_warn(dev, "%s: Governor %s stop=%d\n",
+ __func__, devfreq->governor->name,
+ ret);
+ }
+ devfreq->governor = NULL;
+ }
+ }
+
+ list_del(&governor->node);
+err_out:
+ mutex_unlock(&devfreq_list_lock);
+
+ return err;
}
+EXPORT_SYMBOL(devfreq_remove_governor);
static ssize_t show_governor(struct device *dev,
struct device_attribute *attr, char *buf)
{
+ if (!to_devfreq(dev)->governor)
+ return -EINVAL;
+
return sprintf(buf, "%s\n", to_devfreq(dev)->governor->name);
}
+static ssize_t store_governor(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct devfreq *df = to_devfreq(dev);
+ int ret;
+ char str_governor[DEVFREQ_NAME_LEN + 1];
+ struct devfreq_governor *governor;
+
+ ret = sscanf(buf, "%" __stringify(DEVFREQ_NAME_LEN) "s", str_governor);
+ if (ret != 1)
+ return -EINVAL;
+
+ mutex_lock(&devfreq_list_lock);
+ governor = find_devfreq_governor(str_governor);
+ if (IS_ERR(governor)) {
+ ret = PTR_ERR(governor);
+ goto out;
+ }
+ if (df->governor == governor)
+ goto out;
+
+ if (df->governor) {
+ ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL);
+ if (ret) {
+ dev_warn(dev, "%s: Governor %s not stopped(%d)\n",
+ __func__, df->governor->name, ret);
+ goto out;
+ }
+ }
+ df->governor = governor;
+ strncpy(df->governor_name, governor->name, DEVFREQ_NAME_LEN);
+ ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
+ if (ret)
+ dev_warn(dev, "%s: Governor %s not started(%d)\n",
+ __func__, df->governor->name, ret);
+out:
+ mutex_unlock(&devfreq_list_lock);
+
+ if (!ret)
+ ret = count;
+ return ret;
+}
+static ssize_t show_available_governors(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct devfreq_governor *tmp_governor;
+ ssize_t count = 0;
+
+ mutex_lock(&devfreq_list_lock);
+ list_for_each_entry(tmp_governor, &devfreq_governor_list, node)
+ count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
+ "%s ", tmp_governor->name);
+ mutex_unlock(&devfreq_list_lock);
+
+ /* Truncate the trailing space */
+ if (count)
+ count--;
+
+ count += sprintf(&buf[count], "\n");
+
+ return count;
+}
+
static ssize_t show_freq(struct device *dev,
struct device_attribute *attr, char *buf)
{
+ unsigned long freq;
+ struct devfreq *devfreq = to_devfreq(dev);
+
+ if (devfreq->profile->get_cur_freq &&
+ !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq))
+ return sprintf(buf, "%lu\n", freq);
+
+ return sprintf(buf, "%lu\n", devfreq->previous_freq);
+}
+
+static ssize_t show_target_freq(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq);
}
@@ -486,39 +790,19 @@ static ssize_t store_polling_interval(struct device *dev,
unsigned int value;
int ret;
+ if (!df->governor)
+ return -EINVAL;
+
ret = sscanf(buf, "%u", &value);
if (ret != 1)
- goto out;
-
- mutex_lock(&df->lock);
- df->profile->polling_ms = value;
- df->next_polling = df->polling_jiffies
- = msecs_to_jiffies(value);
- mutex_unlock(&df->lock);
+ return -EINVAL;
+ df->governor->event_handler(df, DEVFREQ_GOV_INTERVAL, &value);
ret = count;
- if (df->governor->no_central_polling)
- goto out;
-
- mutex_lock(&devfreq_list_lock);
- if (df->next_polling > 0 && !polling) {
- polling = true;
- queue_delayed_work(devfreq_wq, &devfreq_work,
- df->next_polling);
- }
- mutex_unlock(&devfreq_list_lock);
-out:
return ret;
}
-static ssize_t show_central_polling(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n",
- !to_devfreq(dev)->governor->no_central_polling);
-}
-
static ssize_t store_min_freq(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
@@ -529,7 +813,7 @@ static ssize_t store_min_freq(struct device *dev, struct device_attribute *attr,
ret = sscanf(buf, "%lu", &value);
if (ret != 1)
- goto out;
+ return -EINVAL;
mutex_lock(&df->lock);
max = df->max_freq;
@@ -543,7 +827,6 @@ static ssize_t store_min_freq(struct device *dev, struct device_attribute *attr,
ret = count;
unlock:
mutex_unlock(&df->lock);
-out:
return ret;
}
@@ -563,7 +846,7 @@ static ssize_t store_max_freq(struct device *dev, struct device_attribute *attr,
ret = sscanf(buf, "%lu", &value);
if (ret != 1)
- goto out;
+ return -EINVAL;
mutex_lock(&df->lock);
min = df->min_freq;
@@ -577,7 +860,6 @@ static ssize_t store_max_freq(struct device *dev, struct device_attribute *attr,
ret = count;
unlock:
mutex_unlock(&df->lock);
-out:
return ret;
}
@@ -587,34 +869,92 @@ static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr,
return sprintf(buf, "%lu\n", to_devfreq(dev)->max_freq);
}
+static ssize_t show_available_freqs(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct devfreq *df = to_devfreq(d);
+ struct device *dev = df->dev.parent;
+ struct opp *opp;
+ ssize_t count = 0;
+ unsigned long freq = 0;
+
+ rcu_read_lock();
+ do {
+ opp = opp_find_freq_ceil(dev, &freq);
+ if (IS_ERR(opp))
+ break;
+
+ count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
+ "%lu ", freq);
+ freq++;
+ } while (1);
+ rcu_read_unlock();
+
+ /* Truncate the trailing space */
+ if (count)
+ count--;
+
+ count += sprintf(&buf[count], "\n");
+
+ return count;
+}
+
+static ssize_t show_trans_table(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct devfreq *devfreq = to_devfreq(dev);
+ ssize_t len;
+ int i, j, err;
+ unsigned int max_state = devfreq->profile->max_state;
+
+ err = devfreq_update_status(devfreq, devfreq->previous_freq);
+ if (err)
+ return 0;
+
+ len = sprintf(buf, " From : To\n");
+ len += sprintf(buf + len, " :");
+ for (i = 0; i < max_state; i++)
+ len += sprintf(buf + len, "%8u",
+ devfreq->profile->freq_table[i]);
+
+ len += sprintf(buf + len, " time(ms)\n");
+
+ for (i = 0; i < max_state; i++) {
+ if (devfreq->profile->freq_table[i]
+ == devfreq->previous_freq) {
+ len += sprintf(buf + len, "*");
+ } else {
+ len += sprintf(buf + len, " ");
+ }
+ len += sprintf(buf + len, "%8u:",
+ devfreq->profile->freq_table[i]);
+ for (j = 0; j < max_state; j++)
+ len += sprintf(buf + len, "%8u",
+ devfreq->trans_table[(i * max_state) + j]);
+ len += sprintf(buf + len, "%10u\n",
+ jiffies_to_msecs(devfreq->time_in_state[i]));
+ }
+
+ len += sprintf(buf + len, "Total transition : %u\n",
+ devfreq->total_trans);
+ return len;
+}
+
static struct device_attribute devfreq_attrs[] = {
- __ATTR(governor, S_IRUGO, show_governor, NULL),
+ __ATTR(governor, S_IRUGO | S_IWUSR, show_governor, store_governor),
+ __ATTR(available_governors, S_IRUGO, show_available_governors, NULL),
__ATTR(cur_freq, S_IRUGO, show_freq, NULL),
- __ATTR(central_polling, S_IRUGO, show_central_polling, NULL),
+ __ATTR(available_frequencies, S_IRUGO, show_available_freqs, NULL),
+ __ATTR(target_freq, S_IRUGO, show_target_freq, NULL),
__ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval,
store_polling_interval),
__ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq),
__ATTR(max_freq, S_IRUGO | S_IWUSR, show_max_freq, store_max_freq),
+ __ATTR(trans_stat, S_IRUGO, show_trans_table, NULL),
{ },
};
-/**
- * devfreq_start_polling() - Initialize data structure for devfreq framework and
- * start polling registered devfreq devices.
- */
-static int __init devfreq_start_polling(void)
-{
- mutex_lock(&devfreq_list_lock);
- polling = false;
- devfreq_wq = create_freezable_workqueue("devfreq_wq");
- INIT_DEFERRABLE_WORK(&devfreq_work, devfreq_monitor);
- mutex_unlock(&devfreq_list_lock);
-
- devfreq_monitor(&devfreq_work.work);
- return 0;
-}
-late_initcall(devfreq_start_polling);
-
static int __init devfreq_init(void)
{
devfreq_class = class_create(THIS_MODULE, "devfreq");
@@ -622,7 +962,15 @@ static int __init devfreq_init(void)
pr_err("%s: couldn't create class\n", __FILE__);
return PTR_ERR(devfreq_class);
}
+
+ devfreq_wq = create_freezable_workqueue("devfreq_wq");
+ if (IS_ERR(devfreq_wq)) {
+ class_destroy(devfreq_class);
+ pr_err("%s: couldn't create workqueue\n", __FILE__);
+ return PTR_ERR(devfreq_wq);
+ }
devfreq_class->dev_attrs = devfreq_attrs;
+
return 0;
}
subsys_initcall(devfreq_init);
@@ -630,6 +978,7 @@ subsys_initcall(devfreq_init);
static void __exit devfreq_exit(void)
{
class_destroy(devfreq_class);
+ destroy_workqueue(devfreq_wq);
}
module_exit(devfreq_exit);
@@ -641,9 +990,9 @@ module_exit(devfreq_exit);
/**
* devfreq_recommended_opp() - Helper function to get proper OPP for the
* freq value given to target callback.
- * @dev The devfreq user device. (parent of devfreq)
- * @freq The frequency given to target function
- * @flags Flags handed from devfreq framework.
+ * @dev: The devfreq user device. (parent of devfreq)
+ * @freq: The frequency given to target function
+ * @flags: Flags handed from devfreq framework.
*
*/
struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq,
@@ -656,14 +1005,14 @@ struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq,
opp = opp_find_freq_floor(dev, freq);
/* If not available, use the closest opp */
- if (opp == ERR_PTR(-ENODEV))
+ if (opp == ERR_PTR(-ERANGE))
opp = opp_find_freq_ceil(dev, freq);
} else {
/* The freq is an lower bound. opp should be higher */
opp = opp_find_freq_ceil(dev, freq);
/* If not available, use the closest opp */
- if (opp == ERR_PTR(-ENODEV))
+ if (opp == ERR_PTR(-ERANGE))
opp = opp_find_freq_floor(dev, freq);
}
@@ -674,35 +1023,49 @@ struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq,
* devfreq_register_opp_notifier() - Helper function to get devfreq notified
* for any changes in the OPP availability
* changes
- * @dev The devfreq user device. (parent of devfreq)
- * @devfreq The devfreq object.
+ * @dev: The devfreq user device. (parent of devfreq)
+ * @devfreq: The devfreq object.
*/
int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq)
{
- struct srcu_notifier_head *nh = opp_get_notifier(dev);
+ struct srcu_notifier_head *nh;
+ int ret = 0;
+ rcu_read_lock();
+ nh = opp_get_notifier(dev);
if (IS_ERR(nh))
- return PTR_ERR(nh);
- return srcu_notifier_chain_register(nh, &devfreq->nb);
+ ret = PTR_ERR(nh);
+ rcu_read_unlock();
+ if (!ret)
+ ret = srcu_notifier_chain_register(nh, &devfreq->nb);
+
+ return ret;
}
/**
* devfreq_unregister_opp_notifier() - Helper function to stop getting devfreq
* notified for any changes in the OPP
* availability changes anymore.
- * @dev The devfreq user device. (parent of devfreq)
- * @devfreq The devfreq object.
+ * @dev: The devfreq user device. (parent of devfreq)
+ * @devfreq: The devfreq object.
*
* At exit() callback of devfreq_dev_profile, this must be included if
* devfreq_recommended_opp is used.
*/
int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq)
{
- struct srcu_notifier_head *nh = opp_get_notifier(dev);
+ struct srcu_notifier_head *nh;
+ int ret = 0;
+ rcu_read_lock();
+ nh = opp_get_notifier(dev);
if (IS_ERR(nh))
- return PTR_ERR(nh);
- return srcu_notifier_chain_unregister(nh, &devfreq->nb);
+ ret = PTR_ERR(nh);
+ rcu_read_unlock();
+ if (!ret)
+ ret = srcu_notifier_chain_unregister(nh, &devfreq->nb);
+
+ return ret;
}
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c
index 88ddc77a9bb..74183720871 100644
--- a/drivers/devfreq/exynos4_bus.c
+++ b/drivers/devfreq/exynos4_bus.c
@@ -987,7 +987,7 @@ static __devinit int exynos4_busfreq_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
int err = 0;
- data = kzalloc(sizeof(struct busfreq_data), GFP_KERNEL);
+ data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data), GFP_KERNEL);
if (data == NULL) {
dev_err(dev, "Cannot allocate memory.\n");
return -ENOMEM;
@@ -1012,31 +1012,26 @@ static __devinit int exynos4_busfreq_probe(struct platform_device *pdev)
err = -EINVAL;
}
if (err)
- goto err_regulator;
+ return err;
- data->vdd_int = regulator_get(dev, "vdd_int");
+ data->vdd_int = devm_regulator_get(dev, "vdd_int");
if (IS_ERR(data->vdd_int)) {
dev_err(dev, "Cannot get the regulator \"vdd_int\"\n");
- err = PTR_ERR(data->vdd_int);
- goto err_regulator;
+ return PTR_ERR(data->vdd_int);
}
if (data->type == TYPE_BUSF_EXYNOS4x12) {
- data->vdd_mif = regulator_get(dev, "vdd_mif");
+ data->vdd_mif = devm_regulator_get(dev, "vdd_mif");
if (IS_ERR(data->vdd_mif)) {
dev_err(dev, "Cannot get the regulator \"vdd_mif\"\n");
- err = PTR_ERR(data->vdd_mif);
- regulator_put(data->vdd_int);
- goto err_regulator;
-
+ return PTR_ERR(data->vdd_mif);
}
}
opp = opp_find_freq_floor(dev, &exynos4_devfreq_profile.initial_freq);
if (IS_ERR(opp)) {
dev_err(dev, "Invalid initial frequency %lu kHz.\n",
- exynos4_devfreq_profile.initial_freq);
- err = PTR_ERR(opp);
- goto err_opp_add;
+ exynos4_devfreq_profile.initial_freq);
+ return PTR_ERR(opp);
}
data->curr_opp = opp;
@@ -1045,30 +1040,20 @@ static __devinit int exynos4_busfreq_probe(struct platform_device *pdev)
busfreq_mon_reset(data);
data->devfreq = devfreq_add_device(dev, &exynos4_devfreq_profile,
- &devfreq_simple_ondemand, NULL);
- if (IS_ERR(data->devfreq)) {
- err = PTR_ERR(data->devfreq);
- goto err_opp_add;
- }
+ "simple_ondemand", NULL);
+ if (IS_ERR(data->devfreq))
+ return PTR_ERR(data->devfreq);
devfreq_register_opp_notifier(dev, data->devfreq);
err = register_pm_notifier(&data->pm_notifier);
if (err) {
dev_err(dev, "Failed to setup pm notifier\n");
- goto err_devfreq_add;
+ devfreq_remove_device(data->devfreq);
+ return err;
}
return 0;
-err_devfreq_add:
- devfreq_remove_device(data->devfreq);
-err_opp_add:
- if (data->vdd_mif)
- regulator_put(data->vdd_mif);
- regulator_put(data->vdd_int);
-err_regulator:
- kfree(data);
- return err;
}
static __devexit int exynos4_busfreq_remove(struct platform_device *pdev)
@@ -1077,10 +1062,6 @@ static __devexit int exynos4_busfreq_remove(struct platform_device *pdev)
unregister_pm_notifier(&data->pm_notifier);
devfreq_remove_device(data->devfreq);
- regulator_put(data->vdd_int);
- if (data->vdd_mif)
- regulator_put(data->vdd_mif);
- kfree(data);
return 0;
}
diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
index ea7f13c58de..fad7d632197 100644
--- a/drivers/devfreq/governor.h
+++ b/drivers/devfreq/governor.h
@@ -18,7 +18,24 @@
#define to_devfreq(DEV) container_of((DEV), struct devfreq, dev)
+/* Devfreq events */
+#define DEVFREQ_GOV_START 0x1
+#define DEVFREQ_GOV_STOP 0x2
+#define DEVFREQ_GOV_INTERVAL 0x3
+#define DEVFREQ_GOV_SUSPEND 0x4
+#define DEVFREQ_GOV_RESUME 0x5
+
/* Caution: devfreq->lock must be locked before calling update_devfreq */
extern int update_devfreq(struct devfreq *devfreq);
+extern void devfreq_monitor_start(struct devfreq *devfreq);
+extern void devfreq_monitor_stop(struct devfreq *devfreq);
+extern void devfreq_monitor_suspend(struct devfreq *devfreq);
+extern void devfreq_monitor_resume(struct devfreq *devfreq);
+extern void devfreq_interval_update(struct devfreq *devfreq,
+ unsigned int *delay);
+
+extern int devfreq_add_governor(struct devfreq_governor *governor);
+extern int devfreq_remove_governor(struct devfreq_governor *governor);
+
#endif /* _GOVERNOR_H */
diff --git a/drivers/devfreq/governor_performance.c b/drivers/devfreq/governor_performance.c
index af75ddd4f15..c72f942f30a 100644
--- a/drivers/devfreq/governor_performance.c
+++ b/drivers/devfreq/governor_performance.c
@@ -10,6 +10,7 @@
*/
#include <linux/devfreq.h>
+#include <linux/module.h>
#include "governor.h"
static int devfreq_performance_func(struct devfreq *df,
@@ -26,14 +27,41 @@ static int devfreq_performance_func(struct devfreq *df,
return 0;
}
-static int performance_init(struct devfreq *devfreq)
+static int devfreq_performance_handler(struct devfreq *devfreq,
+ unsigned int event, void *data)
{
- return update_devfreq(devfreq);
+ int ret = 0;
+
+ if (event == DEVFREQ_GOV_START) {
+ mutex_lock(&devfreq->lock);
+ ret = update_devfreq(devfreq);
+ mutex_unlock(&devfreq->lock);
+ }
+
+ return ret;
}
-const struct devfreq_governor devfreq_performance = {
+static struct devfreq_governor devfreq_performance = {
.name = "performance",
- .init = performance_init,
.get_target_freq = devfreq_performance_func,
- .no_central_polling = true,
+ .event_handler = devfreq_performance_handler,
};
+
+static int __init devfreq_performance_init(void)
+{
+ return devfreq_add_governor(&devfreq_performance);
+}
+subsys_initcall(devfreq_performance_init);
+
+static void __exit devfreq_performance_exit(void)
+{
+ int ret;
+
+ ret = devfreq_remove_governor(&devfreq_performance);
+ if (ret)
+ pr_err("%s: failed remove governor %d\n", __func__, ret);
+
+ return;
+}
+module_exit(devfreq_performance_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/devfreq/governor_powersave.c b/drivers/devfreq/governor_powersave.c
index fec0cdbd247..0c6bed567e6 100644
--- a/drivers/devfreq/governor_powersave.c
+++ b/drivers/devfreq/governor_powersave.c
@@ -10,6 +10,7 @@
*/
#include <linux/devfreq.h>
+#include <linux/module.h>
#include "governor.h"
static int devfreq_powersave_func(struct devfreq *df,
@@ -23,14 +24,41 @@ static int devfreq_powersave_func(struct devfreq *df,
return 0;
}
-static int powersave_init(struct devfreq *devfreq)
+static int devfreq_powersave_handler(struct devfreq *devfreq,
+ unsigned int event, void *data)
{
- return update_devfreq(devfreq);
+ int ret = 0;
+
+ if (event == DEVFREQ_GOV_START) {
+ mutex_lock(&devfreq->lock);
+ ret = update_devfreq(devfreq);
+ mutex_unlock(&devfreq->lock);
+ }
+
+ return ret;
}
-const struct devfreq_governor devfreq_powersave = {
+static struct devfreq_governor devfreq_powersave = {
.name = "powersave",
- .init = powersave_init,
.get_target_freq = devfreq_powersave_func,
- .no_central_polling = true,
+ .event_handler = devfreq_powersave_handler,
};
+
+static int __init devfreq_powersave_init(void)
+{
+ return devfreq_add_governor(&devfreq_powersave);
+}
+subsys_initcall(devfreq_powersave_init);
+
+static void __exit devfreq_powersave_exit(void)
+{
+ int ret;
+
+ ret = devfreq_remove_governor(&devfreq_powersave);
+ if (ret)
+ pr_err("%s: failed remove governor %d\n", __func__, ret);
+
+ return;
+}
+module_exit(devfreq_powersave_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c
index a2e3eae7901..0720ba84ca9 100644
--- a/drivers/devfreq/governor_simpleondemand.c
+++ b/drivers/devfreq/governor_simpleondemand.c
@@ -10,8 +10,10 @@
*/
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/devfreq.h>
#include <linux/math64.h>
+#include "governor.h"
/* Default constants for DevFreq-Simple-Ondemand (DFSO) */
#define DFSO_UPTHRESHOLD (90)
@@ -88,7 +90,58 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
return 0;
}
-const struct devfreq_governor devfreq_simple_ondemand = {
+static int devfreq_simple_ondemand_handler(struct devfreq *devfreq,
+ unsigned int event, void *data)
+{
+ switch (event) {
+ case DEVFREQ_GOV_START:
+ devfreq_monitor_start(devfreq);
+ break;
+
+ case DEVFREQ_GOV_STOP:
+ devfreq_monitor_stop(devfreq);
+ break;
+
+ case DEVFREQ_GOV_INTERVAL:
+ devfreq_interval_update(devfreq, (unsigned int *)data);
+ break;
+
+ case DEVFREQ_GOV_SUSPEND:
+ devfreq_monitor_suspend(devfreq);
+ break;
+
+ case DEVFREQ_GOV_RESUME:
+ devfreq_monitor_resume(devfreq);
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static struct devfreq_governor devfreq_simple_ondemand = {
.name = "simple_ondemand",
.get_target_freq = devfreq_simple_ondemand_func,
+ .event_handler = devfreq_simple_ondemand_handler,
};
+
+static int __init devfreq_simple_ondemand_init(void)
+{
+ return devfreq_add_governor(&devfreq_simple_ondemand);
+}
+subsys_initcall(devfreq_simple_ondemand_init);
+
+static void __exit devfreq_simple_ondemand_exit(void)
+{
+ int ret;
+
+ ret = devfreq_remove_governor(&devfreq_simple_ondemand);
+ if (ret)
+ pr_err("%s: failed remove governor %d\n", __func__, ret);
+
+ return;
+}
+module_exit(devfreq_simple_ondemand_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c
index 0681246fc89..35de6e83c1f 100644
--- a/drivers/devfreq/governor_userspace.c
+++ b/drivers/devfreq/governor_userspace.c
@@ -14,6 +14,7 @@
#include <linux/devfreq.h>
#include <linux/pm.h>
#include <linux/mutex.h>
+#include <linux/module.h>
#include "governor.h"
struct userspace_data {
@@ -116,10 +117,46 @@ static void userspace_exit(struct devfreq *devfreq)
devfreq->data = NULL;
}
-const struct devfreq_governor devfreq_userspace = {
+static int devfreq_userspace_handler(struct devfreq *devfreq,
+ unsigned int event, void *data)
+{
+ int ret = 0;
+
+ switch (event) {
+ case DEVFREQ_GOV_START:
+ ret = userspace_init(devfreq);
+ break;
+ case DEVFREQ_GOV_STOP:
+ userspace_exit(devfreq);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static struct devfreq_governor devfreq_userspace = {
.name = "userspace",
.get_target_freq = devfreq_userspace_func,
- .init = userspace_init,
- .exit = userspace_exit,
- .no_central_polling = true,
+ .event_handler = devfreq_userspace_handler,
};
+
+static int __init devfreq_userspace_init(void)
+{
+ return devfreq_add_governor(&devfreq_userspace);
+}
+subsys_initcall(devfreq_userspace_init);
+
+static void __exit devfreq_userspace_exit(void)
+{
+ int ret;
+
+ ret = devfreq_remove_governor(&devfreq_userspace);
+ if (ret)
+ pr_err("%s: failed remove governor %d\n", __func__, ret);
+
+ return;
+}
+module_exit(devfreq_userspace_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index c4b0eb3cde8..8f0b111af4d 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -1462,7 +1462,7 @@ static void dw_dma_off(struct dw_dma *dw)
dw->chan[i].initialized = false;
}
-static int __devinit dw_probe(struct platform_device *pdev)
+static int dw_probe(struct platform_device *pdev)
{
struct dw_dma_platform_data *pdata;
struct resource *io;
@@ -1700,7 +1700,7 @@ MODULE_DEVICE_TABLE(of, dw_dma_id_table);
#endif
static struct platform_driver dw_driver = {
- .remove = __devexit_p(dw_remove),
+ .remove = dw_remove,
.shutdown = dw_shutdown,
.driver = {
.name = "dw_dmac",
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 05aea3ce850..232b4583ae9 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -545,7 +545,7 @@ static void edma_dma_init(struct edma_cc *ecc, struct dma_device *dma,
INIT_LIST_HEAD(&dma->channels);
}
-static int __devinit edma_probe(struct platform_device *pdev)
+static int edma_probe(struct platform_device *pdev)
{
struct edma_cc *ecc;
int ret;
@@ -598,7 +598,7 @@ static int __devexit edma_remove(struct platform_device *pdev)
static struct platform_driver edma_driver = {
.probe = edma_probe,
- .remove = __devexit_p(edma_remove),
+ .remove = edma_remove,
.driver = {
.name = "edma-dma-engine",
.owner = THIS_MODULE,
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 094437b9d82..4fc2980556a 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -1221,7 +1221,7 @@ out_unwind:
/* OpenFirmware Subsystem */
/*----------------------------------------------------------------------------*/
-static int __devinit fsl_dma_chan_probe(struct fsldma_device *fdev,
+static int fsl_dma_chan_probe(struct fsldma_device *fdev,
struct device_node *node, u32 feature, const char *compatible)
{
struct fsldma_chan *chan;
@@ -1324,7 +1324,7 @@ static void fsl_dma_chan_remove(struct fsldma_chan *chan)
kfree(chan);
}
-static int __devinit fsldma_of_probe(struct platform_device *op)
+static int fsldma_of_probe(struct platform_device *op)
{
struct fsldma_device *fdev;
struct device_node *child;
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index 02b21d7d38e..bc764afacd9 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -1225,7 +1225,7 @@ static void middma_shutdown(struct pci_dev *pdev)
* Initialize the PCI device, map BARs, query driver data.
* Call setup_dma to complete contoller and chan initilzation
*/
-static int __devinit intel_mid_dma_probe(struct pci_dev *pdev,
+static int intel_mid_dma_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct middma_device *device;
@@ -1432,7 +1432,7 @@ static struct pci_driver intel_mid_dma_pci_driver = {
.name = "Intel MID DMA",
.id_table = intel_mid_dma_ids,
.probe = intel_mid_dma_probe,
- .remove = __devexit_p(intel_mid_dma_remove),
+ .remove = intel_mid_dma_remove,
#ifdef CONFIG_PM
.driver = {
.pm = &intel_mid_dma_pm,
diff --git a/drivers/dma/ioat/pci.c b/drivers/dma/ioat/pci.c
index c0573061b45..bfa9a3536e0 100644
--- a/drivers/dma/ioat/pci.c
+++ b/drivers/dma/ioat/pci.c
@@ -125,7 +125,7 @@ static struct pci_driver ioat_pci_driver = {
.name = DRV_NAME,
.id_table = ioat_pci_tbl,
.probe = ioat_pci_probe,
- .remove = __devexit_p(ioat_remove),
+ .remove = ioat_remove,
};
static struct ioatdma_device *
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 79e3eba2970..9072e173b86 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -968,7 +968,7 @@ static void iop_adma_issue_pending(struct dma_chan *chan)
*/
#define IOP_ADMA_TEST_SIZE 2000
-static int __devinit iop_adma_memcpy_self_test(struct iop_adma_device *device)
+static int iop_adma_memcpy_self_test(struct iop_adma_device *device)
{
int i;
void *src, *dest;
@@ -1042,7 +1042,7 @@ out:
}
#define IOP_ADMA_NUM_SRC_TEST 4 /* must be <= 15 */
-static int __devinit
+static int
iop_adma_xor_val_self_test(struct iop_adma_device *device)
{
int i, src_idx;
@@ -1243,7 +1243,7 @@ out:
}
#ifdef CONFIG_RAID6_PQ
-static int __devinit
+static int
iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device)
{
/* combined sources, software pq results, and extra hw pq results */
@@ -1429,7 +1429,7 @@ static int __devexit iop_adma_remove(struct platform_device *dev)
return 0;
}
-static int __devinit iop_adma_probe(struct platform_device *pdev)
+static int iop_adma_probe(struct platform_device *pdev)
{
struct resource *res;
int ret = 0, i;
@@ -1711,7 +1711,7 @@ static void iop_chan_start_null_xor(struct iop_adma_chan *iop_chan)
static struct platform_driver iop_adma_driver = {
.probe = iop_adma_probe,
- .remove = __devexit_p(iop_adma_remove),
+ .remove = iop_adma_remove,
.driver = {
.owner = THIS_MODULE,
.name = "iop-adma",
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index 14da1f403ed..13bdf4a7e1e 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -720,7 +720,7 @@ static int __devexit mmp_pdma_remove(struct platform_device *op)
return 0;
}
-static int __devinit mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
+static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
int idx, int irq)
{
struct mmp_pdma_phy *phy = &pdev->phy[idx];
@@ -764,7 +764,7 @@ static struct of_device_id mmp_pdma_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, mmp_pdma_dt_ids);
-static int __devinit mmp_pdma_probe(struct platform_device *op)
+static int mmp_pdma_probe(struct platform_device *op)
{
struct mmp_pdma_device *pdev;
const struct of_device_id *of_id;
@@ -865,7 +865,7 @@ static struct platform_driver mmp_pdma_driver = {
},
.id_table = mmp_pdma_id_table,
.probe = mmp_pdma_probe,
- .remove = __devexit_p(mmp_pdma_remove),
+ .remove = mmp_pdma_remove,
};
module_platform_driver(mmp_pdma_driver);
diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c
index f3e8d71bcbc..323821c0c09 100644
--- a/drivers/dma/mmp_tdma.c
+++ b/drivers/dma/mmp_tdma.c
@@ -475,7 +475,7 @@ static int __devexit mmp_tdma_remove(struct platform_device *pdev)
return 0;
}
-static int __devinit mmp_tdma_chan_init(struct mmp_tdma_device *tdev,
+static int mmp_tdma_chan_init(struct mmp_tdma_device *tdev,
int idx, int irq, int type)
{
struct mmp_tdma_chan *tdmac;
@@ -515,7 +515,7 @@ static struct of_device_id mmp_tdma_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, mmp_tdma_dt_ids);
-static int __devinit mmp_tdma_probe(struct platform_device *pdev)
+static int mmp_tdma_probe(struct platform_device *pdev)
{
enum mmp_tdma_type type;
const struct of_device_id *of_id;
@@ -609,7 +609,7 @@ static struct platform_driver mmp_tdma_driver = {
},
.id_table = mmp_tdma_id_table,
.probe = mmp_tdma_probe,
- .remove = __devexit_p(mmp_tdma_remove),
+ .remove = mmp_tdma_remove,
};
module_platform_driver(mmp_tdma_driver);
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 2ab0a3d0eed..2cd024a91d4 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -641,7 +641,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
return &mdesc->desc;
}
-static int __devinit mpc_dma_probe(struct platform_device *op)
+static int mpc_dma_probe(struct platform_device *op)
{
struct device_node *dn = op->dev.of_node;
struct device *dev = &op->dev;
@@ -818,7 +818,7 @@ static struct of_device_id mpc_dma_match[] = {
static struct platform_driver mpc_dma_driver = {
.probe = mpc_dma_probe,
- .remove = __devexit_p(mpc_dma_remove),
+ .remove = mpc_dma_remove,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index e362e2b80ef..d12ad00da4c 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -901,7 +901,7 @@ static void mv_xor_issue_pending(struct dma_chan *chan)
*/
#define MV_XOR_TEST_SIZE 2000
-static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device)
+static int mv_xor_memcpy_self_test(struct mv_xor_device *device)
{
int i;
void *src, *dest;
@@ -975,7 +975,7 @@ out:
}
#define MV_XOR_NUM_SRC_TEST 4 /* must be <= 15 */
-static int __devinit
+static int
mv_xor_xor_self_test(struct mv_xor_device *device)
{
int i, src_idx;
@@ -1100,7 +1100,7 @@ static int __devexit mv_xor_remove(struct platform_device *dev)
return 0;
}
-static int __devinit mv_xor_probe(struct platform_device *pdev)
+static int mv_xor_probe(struct platform_device *pdev)
{
int ret = 0;
int irq;
@@ -1262,7 +1262,7 @@ mv_xor_conf_mbus_windows(struct mv_xor_shared_private *msp,
static struct platform_driver mv_xor_driver = {
.probe = mv_xor_probe,
- .remove = __devexit_p(mv_xor_remove),
+ .remove = mv_xor_remove,
.driver = {
.owner = THIS_MODULE,
.name = MV_XOR_NAME,
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index 987ab5cd261..eca1c4ddf03 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -843,7 +843,7 @@ static int pch_dma_resume(struct pci_dev *pdev)
}
#endif
-static int __devinit pch_dma_probe(struct pci_dev *pdev,
+static int pch_dma_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct pch_dma *pd;
@@ -1022,7 +1022,7 @@ static struct pci_driver pch_dma_driver = {
.name = DRV_NAME,
.id_table = pch_dma_id_table,
.probe = pch_dma_probe,
- .remove = __devexit_p(pch_dma_remove),
+ .remove = pch_dma_remove,
#ifdef CONFIG_PM
.suspend = pch_dma_suspend,
.resume = pch_dma_resume,
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 665668b6f2b..95555f37ea6 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2851,7 +2851,7 @@ static irqreturn_t pl330_irq_handler(int irq, void *data)
return IRQ_NONE;
}
-static int __devinit
+static int
pl330_probe(struct amba_device *adev, const struct amba_id *id)
{
struct dma_pl330_platdata *pdat;
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index f72348d0bc4..b94afc339e7 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -4361,7 +4361,7 @@ static void ppc440spe_adma_release_irqs(struct ppc440spe_adma_device *adev,
/**
* ppc440spe_adma_probe - probe the asynch device
*/
-static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev)
+static int ppc440spe_adma_probe(struct platform_device *ofdev)
{
struct device_node *np = ofdev->dev.of_node;
struct resource res;
@@ -4914,7 +4914,7 @@ MODULE_DEVICE_TABLE(of, ppc440spe_adma_of_match);
static struct platform_driver ppc440spe_adma_driver = {
.probe = ppc440spe_adma_probe,
- .remove = __devexit_p(ppc440spe_adma_remove),
+ .remove = ppc440spe_adma_remove,
.driver = {
.name = "PPC440SP(E)-ADMA",
.owner = THIS_MODULE,
diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
index b893159c1ec..2ad628df822 100644
--- a/drivers/dma/sa11x0-dma.c
+++ b/drivers/dma/sa11x0-dma.c
@@ -826,7 +826,7 @@ static const struct sa11x0_dma_channel_desc chan_desc[] = {
CD(Ser4SSPRc, DDAR_RW),
};
-static int __devinit sa11x0_dma_init_dmadev(struct dma_device *dmadev,
+static int sa11x0_dma_init_dmadev(struct dma_device *dmadev,
struct device *dev)
{
unsigned i;
@@ -891,7 +891,7 @@ static void sa11x0_dma_free_channels(struct dma_device *dmadev)
}
}
-static int __devinit sa11x0_dma_probe(struct platform_device *pdev)
+static int sa11x0_dma_probe(struct platform_device *pdev)
{
struct sa11x0_dma_dev *d;
struct resource *res;
@@ -1072,7 +1072,7 @@ static struct platform_driver sa11x0_dma_driver = {
.pm = &sa11x0_dma_pm_ops,
},
.probe = sa11x0_dma_probe,
- .remove = __devexit_p(sa11x0_dma_remove),
+ .remove = sa11x0_dma_remove,
};
bool sa11x0_dma_filter_fn(struct dma_chan *chan, void *param)
diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c
index f41bcc5267f..8201bb4e0cd 100644
--- a/drivers/dma/sh/shdma.c
+++ b/drivers/dma/sh/shdma.c
@@ -483,7 +483,7 @@ static struct notifier_block sh_dmae_nmi_notifier __read_mostly = {
.priority = 1,
};
-static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
+static int sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
int irq, unsigned long flags)
{
const struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id];
@@ -646,7 +646,7 @@ static const struct shdma_ops sh_dmae_shdma_ops = {
.get_partial = sh_dmae_get_partial,
};
-static int __devinit sh_dmae_probe(struct platform_device *pdev)
+static int sh_dmae_probe(struct platform_device *pdev)
{
struct sh_dmae_pdata *pdata = pdev->dev.platform_data;
unsigned long irqflags = IRQF_DISABLED,
@@ -926,7 +926,7 @@ static struct platform_driver sh_dmae_driver = {
.pm = &sh_dmae_pm,
.name = SH_DMAE_DRV_NAME,
},
- .remove = __devexit_p(sh_dmae_remove),
+ .remove = sh_dmae_remove,
.shutdown = sh_dmae_shutdown,
};
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index d451caace80..c3de6edb965 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -550,7 +550,7 @@ bool sirfsoc_dma_filter_id(struct dma_chan *chan, void *chan_id)
}
EXPORT_SYMBOL(sirfsoc_dma_filter_id);
-static int __devinit sirfsoc_dma_probe(struct platform_device *op)
+static int sirfsoc_dma_probe(struct platform_device *op)
{
struct device_node *dn = op->dev.of_node;
struct device *dev = &op->dev;
@@ -673,7 +673,7 @@ static struct of_device_id sirfsoc_dma_match[] = {
static struct platform_driver sirfsoc_dma_driver = {
.probe = sirfsoc_dma_probe,
- .remove = __devexit_p(sirfsoc_dma_remove),
+ .remove = sirfsoc_dma_remove,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index 528c62dd4b0..efdfffa1334 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -1197,7 +1197,7 @@ static const struct of_device_id tegra_dma_of_match[] __devinitconst = {
MODULE_DEVICE_TABLE(of, tegra_dma_of_match);
#endif
-static int __devinit tegra_dma_probe(struct platform_device *pdev)
+static int tegra_dma_probe(struct platform_device *pdev)
{
struct resource *res;
struct tegra_dma *tdma;
@@ -1418,7 +1418,7 @@ static struct platform_driver tegra_dmac_driver = {
.of_match_table = of_match_ptr(tegra_dma_of_match),
},
.probe = tegra_dma_probe,
- .remove = __devexit_p(tegra_dma_remove),
+ .remove = tegra_dma_remove,
};
module_platform_driver(tegra_dmac_driver);
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index 4e0dff59901..98cf51e1544 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -667,7 +667,7 @@ static irqreturn_t td_irq(int irq, void *devid)
}
-static int __devinit td_probe(struct platform_device *pdev)
+static int td_probe(struct platform_device *pdev)
{
struct timb_dma_platform_data *pdata = pdev->dev.platform_data;
struct timb_dma *td;
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 409b92b8d34..bb82d6be793 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -42,10 +42,10 @@ config EDAC_LEGACY_SYSFS
config EDAC_DEBUG
bool "Debugging"
help
- This turns on debugging information for the entire EDAC
- sub-system. You can insert module with "debug_level=x", current
- there're four debug levels (x=0,1,2,3 from low to high).
- Usually you should select 'N'.
+ This turns on debugging information for the entire EDAC subsystem.
+ You do so by inserting edac_module with "edac_debug_level=x." Valid
+ levels are 0-4 (from low to high) and by default it is set to 2.
+ Usually you should select 'N' here.
config EDAC_DECODE_MCE
tristate "Decode MCEs in human-readable form (only on AMD for now)"
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index cc8e7c78a23..f74a684269f 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -60,8 +60,8 @@ struct scrubrate {
{ 0x00, 0UL}, /* scrubbing off */
};
-static int __amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,
- u32 *val, const char *func)
+int __amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,
+ u32 *val, const char *func)
{
int err = 0;
@@ -423,7 +423,6 @@ int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
u64 *hole_offset, u64 *hole_size)
{
struct amd64_pvt *pvt = mci->pvt_info;
- u64 base;
/* only revE and later have the DRAM Hole Address Register */
if (boot_cpu_data.x86 == 0xf && pvt->ext_model < K8_REV_E) {
@@ -462,10 +461,8 @@ int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
* addresses in the hole so that they start at 0x100000000.
*/
- base = dhar_base(pvt);
-
- *hole_base = base;
- *hole_size = (0x1ull << 32) - base;
+ *hole_base = dhar_base(pvt);
+ *hole_size = (1ULL << 32) - *hole_base;
if (boot_cpu_data.x86 > 0xf)
*hole_offset = f10_dhar_offset(pvt);
@@ -513,15 +510,15 @@ static u64 sys_addr_to_dram_addr(struct mem_ctl_info *mci, u64 sys_addr)
{
struct amd64_pvt *pvt = mci->pvt_info;
u64 dram_base, hole_base, hole_offset, hole_size, dram_addr;
- int ret = 0;
+ int ret;
dram_base = get_dram_base(pvt, pvt->mc_node_id);
ret = amd64_get_dram_hole_info(mci, &hole_base, &hole_offset,
&hole_size);
if (!ret) {
- if ((sys_addr >= (1ull << 32)) &&
- (sys_addr < ((1ull << 32) + hole_size))) {
+ if ((sys_addr >= (1ULL << 32)) &&
+ (sys_addr < ((1ULL << 32) + hole_size))) {
/* use DHAR to translate SysAddr to DramAddr */
dram_addr = sys_addr - hole_offset;
@@ -712,10 +709,10 @@ static inline u64 input_addr_to_sys_addr(struct mem_ctl_info *mci,
/* Map the Error address to a PAGE and PAGE OFFSET. */
static inline void error_address_to_page_and_offset(u64 error_address,
- u32 *page, u32 *offset)
+ struct err_info *err)
{
- *page = (u32) (error_address >> PAGE_SHIFT);
- *offset = ((u32) error_address) & ~PAGE_MASK;
+ err->page = (u32) (error_address >> PAGE_SHIFT);
+ err->offset = ((u32) error_address) & ~PAGE_MASK;
}
/*
@@ -1026,59 +1023,44 @@ static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range)
}
static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr,
- u16 syndrome)
+ struct err_info *err)
{
- struct mem_ctl_info *src_mci;
struct amd64_pvt *pvt = mci->pvt_info;
- int channel, csrow;
- u32 page, offset;
- error_address_to_page_and_offset(sys_addr, &page, &offset);
+ error_address_to_page_and_offset(sys_addr, err);
/*
* Find out which node the error address belongs to. This may be
* different from the node that detected the error.
*/
- src_mci = find_mc_by_sys_addr(mci, sys_addr);
- if (!src_mci) {
+ err->src_mci = find_mc_by_sys_addr(mci, sys_addr);
+ if (!err->src_mci) {
amd64_mc_err(mci, "failed to map error addr 0x%lx to a node\n",
(unsigned long)sys_addr);
- edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
- page, offset, syndrome,
- -1, -1, -1,
- "failed to map error addr to a node",
- "");
+ err->err_code = ERR_NODE;
return;
}
/* Now map the sys_addr to a CSROW */
- csrow = sys_addr_to_csrow(src_mci, sys_addr);
- if (csrow < 0) {
- edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
- page, offset, syndrome,
- -1, -1, -1,
- "failed to map error addr to a csrow",
- "");
+ err->csrow = sys_addr_to_csrow(err->src_mci, sys_addr);
+ if (err->csrow < 0) {
+ err->err_code = ERR_CSROW;
return;
}
/* CHIPKILL enabled */
if (pvt->nbcfg & NBCFG_CHIPKILL) {
- channel = get_channel_from_ecc_syndrome(mci, syndrome);
- if (channel < 0) {
+ err->channel = get_channel_from_ecc_syndrome(mci, err->syndrome);
+ if (err->channel < 0) {
/*
* Syndrome didn't map, so we don't know which of the
* 2 DIMMs is in error. So we need to ID 'both' of them
* as suspect.
*/
- amd64_mc_warn(src_mci, "unknown syndrome 0x%04x - "
+ amd64_mc_warn(err->src_mci, "unknown syndrome 0x%04x - "
"possible error reporting race\n",
- syndrome);
- edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
- page, offset, syndrome,
- csrow, -1, -1,
- "unknown syndrome - possible error reporting race",
- "");
+ err->syndrome);
+ err->err_code = ERR_CHANNEL;
return;
}
} else {
@@ -1090,13 +1072,8 @@ static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr,
* was obtained from email communication with someone at AMD.
* (Wish the email was placed in this comment - norsk)
*/
- channel = ((sys_addr & BIT(3)) != 0);
+ err->channel = ((sys_addr & BIT(3)) != 0);
}
-
- edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, src_mci, 1,
- page, offset, syndrome,
- csrow, channel, -1,
- "", "");
}
static int ddr2_cs_size(unsigned i, bool dct_width)
@@ -1482,7 +1459,7 @@ static u64 f1x_swap_interleaved_region(struct amd64_pvt *pvt, u64 sys_addr)
/* For a given @dram_range, check if @sys_addr falls within it. */
static int f1x_match_to_this_node(struct amd64_pvt *pvt, unsigned range,
- u64 sys_addr, int *nid, int *chan_sel)
+ u64 sys_addr, int *chan_sel)
{
int cs_found = -EINVAL;
u64 chan_addr;
@@ -1555,15 +1532,14 @@ static int f1x_match_to_this_node(struct amd64_pvt *pvt, unsigned range,
cs_found = f1x_lookup_addr_in_dct(chan_addr, node_id, channel);
- if (cs_found >= 0) {
- *nid = node_id;
+ if (cs_found >= 0)
*chan_sel = channel;
- }
+
return cs_found;
}
static int f1x_translate_sysaddr_to_cs(struct amd64_pvt *pvt, u64 sys_addr,
- int *node, int *chan_sel)
+ int *chan_sel)
{
int cs_found = -EINVAL;
unsigned range;
@@ -1577,8 +1553,7 @@ static int f1x_translate_sysaddr_to_cs(struct amd64_pvt *pvt, u64 sys_addr,
(get_dram_limit(pvt, range) >= sys_addr)) {
cs_found = f1x_match_to_this_node(pvt, range,
- sys_addr, node,
- chan_sel);
+ sys_addr, chan_sel);
if (cs_found >= 0)
break;
}
@@ -1594,22 +1569,15 @@ static int f1x_translate_sysaddr_to_cs(struct amd64_pvt *pvt, u64 sys_addr,
* (MCX_ADDR).
*/
static void f1x_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr,
- u16 syndrome)
+ struct err_info *err)
{
struct amd64_pvt *pvt = mci->pvt_info;
- u32 page, offset;
- int nid, csrow, chan = 0;
- error_address_to_page_and_offset(sys_addr, &page, &offset);
+ error_address_to_page_and_offset(sys_addr, err);
- csrow = f1x_translate_sysaddr_to_cs(pvt, sys_addr, &nid, &chan);
-
- if (csrow < 0) {
- edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
- page, offset, syndrome,
- -1, -1, -1,
- "failed to map error addr to a csrow",
- "");
+ err->csrow = f1x_translate_sysaddr_to_cs(pvt, sys_addr, &err->channel);
+ if (err->csrow < 0) {
+ err->err_code = ERR_CSROW;
return;
}
@@ -1619,12 +1587,7 @@ static void f1x_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr,
* this point.
*/
if (dct_ganging_enabled(pvt))
- chan = get_channel_from_ecc_syndrome(mci, syndrome);
-
- edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
- page, offset, syndrome,
- csrow, chan, -1,
- "", "");
+ err->channel = get_channel_from_ecc_syndrome(mci, err->syndrome);
}
/*
@@ -1633,14 +1596,11 @@ static void f1x_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr,
*/
static void amd64_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl)
{
- int dimm, size0, size1, factor = 0;
+ int dimm, size0, size1;
u32 *dcsb = ctrl ? pvt->csels[1].csbases : pvt->csels[0].csbases;
u32 dbam = ctrl ? pvt->dbam1 : pvt->dbam0;
if (boot_cpu_data.x86 == 0xf) {
- if (pvt->dclr0 & WIDTH_128)
- factor = 1;
-
/* K8 families < revF not supported yet */
if (pvt->ext_model < K8_REV_F)
return;
@@ -1671,8 +1631,8 @@ static void amd64_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl)
DBAM_DIMM(dimm, dbam));
amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n",
- dimm * 2, size0 << factor,
- dimm * 2 + 1, size1 << factor);
+ dimm * 2, size0,
+ dimm * 2 + 1, size1);
}
}
@@ -1893,101 +1853,56 @@ static int get_channel_from_ecc_syndrome(struct mem_ctl_info *mci, u16 syndrome)
return map_err_sym_to_channel(err_sym, pvt->ecc_sym_sz);
}
-/*
- * Handle any Correctable Errors (CEs) that have occurred. Check for valid ERROR
- * ADDRESS and process.
- */
-static void amd64_handle_ce(struct mem_ctl_info *mci, struct mce *m)
-{
- struct amd64_pvt *pvt = mci->pvt_info;
- u64 sys_addr;
- u16 syndrome;
-
- /* Ensure that the Error Address is VALID */
- if (!(m->status & MCI_STATUS_ADDRV)) {
- amd64_mc_err(mci, "HW has no ERROR_ADDRESS available\n");
- edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
- 0, 0, 0,
- -1, -1, -1,
- "HW has no ERROR_ADDRESS available",
- "");
- return;
- }
-
- sys_addr = get_error_address(m);
- syndrome = extract_syndrome(m->status);
-
- amd64_mc_err(mci, "CE ERROR_ADDRESS= 0x%llx\n", sys_addr);
-
- pvt->ops->map_sysaddr_to_csrow(mci, sys_addr, syndrome);
-}
-
-/* Handle any Un-correctable Errors (UEs) */
-static void amd64_handle_ue(struct mem_ctl_info *mci, struct mce *m)
+static void __log_bus_error(struct mem_ctl_info *mci, struct err_info *err,
+ u8 ecc_type)
{
- struct mem_ctl_info *log_mci, *src_mci = NULL;
- int csrow;
- u64 sys_addr;
- u32 page, offset;
-
- log_mci = mci;
+ enum hw_event_mc_err_type err_type;
+ const char *string;
- if (!(m->status & MCI_STATUS_ADDRV)) {
- amd64_mc_err(mci, "HW has no ERROR_ADDRESS available\n");
- edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
- 0, 0, 0,
- -1, -1, -1,
- "HW has no ERROR_ADDRESS available",
- "");
+ if (ecc_type == 2)
+ err_type = HW_EVENT_ERR_CORRECTED;
+ else if (ecc_type == 1)
+ err_type = HW_EVENT_ERR_UNCORRECTED;
+ else {
+ WARN(1, "Something is rotten in the state of Denmark.\n");
return;
}
- sys_addr = get_error_address(m);
- error_address_to_page_and_offset(sys_addr, &page, &offset);
-
- /*
- * Find out which node the error address belongs to. This may be
- * different from the node that detected the error.
- */
- src_mci = find_mc_by_sys_addr(mci, sys_addr);
- if (!src_mci) {
- amd64_mc_err(mci, "ERROR ADDRESS (0x%lx) NOT mapped to a MC\n",
- (unsigned long)sys_addr);
- edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
- page, offset, 0,
- -1, -1, -1,
- "ERROR ADDRESS NOT mapped to a MC",
- "");
- return;
+ switch (err->err_code) {
+ case DECODE_OK:
+ string = "";
+ break;
+ case ERR_NODE:
+ string = "Failed to map error addr to a node";
+ break;
+ case ERR_CSROW:
+ string = "Failed to map error addr to a csrow";
+ break;
+ case ERR_CHANNEL:
+ string = "unknown syndrome - possible error reporting race";
+ break;
+ default:
+ string = "WTF error";
+ break;
}
- log_mci = src_mci;
-
- csrow = sys_addr_to_csrow(log_mci, sys_addr);
- if (csrow < 0) {
- amd64_mc_err(mci, "ERROR_ADDRESS (0x%lx) NOT mapped to CS\n",
- (unsigned long)sys_addr);
- edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
- page, offset, 0,
- -1, -1, -1,
- "ERROR ADDRESS NOT mapped to CS",
- "");
- } else {
- edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
- page, offset, 0,
- csrow, -1, -1,
- "", "");
- }
+ edac_mc_handle_error(err_type, mci, 1,
+ err->page, err->offset, err->syndrome,
+ err->csrow, err->channel, -1,
+ string, "");
}
static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci,
struct mce *m)
{
- u16 ec = EC(m->status);
- u8 xec = XEC(m->status, 0x1f);
+ struct amd64_pvt *pvt = mci->pvt_info;
u8 ecc_type = (m->status >> 45) & 0x3;
+ u8 xec = XEC(m->status, 0x1f);
+ u16 ec = EC(m->status);
+ u64 sys_addr;
+ struct err_info err;
- /* Bail early out if this was an 'observed' error */
+ /* Bail out early if this was an 'observed' error */
if (PP(ec) == NBSL_PP_OBS)
return;
@@ -1995,10 +1910,16 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci,
if (xec && xec != F10_NBSL_EXT_ERR_ECC)
return;
+ memset(&err, 0, sizeof(err));
+
+ sys_addr = get_error_address(m);
+
if (ecc_type == 2)
- amd64_handle_ce(mci, m);
- else if (ecc_type == 1)
- amd64_handle_ue(mci, m);
+ err.syndrome = extract_syndrome(m->status);
+
+ pvt->ops->map_sysaddr_to_csrow(mci, sys_addr, &err);
+
+ __log_bus_error(mci, &err, ecc_type);
}
void amd64_decode_bus_error(int node_id, struct mce *m)
@@ -2166,6 +2087,7 @@ static u32 amd64_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr)
u32 cs_mode, nr_pages;
u32 dbam = dct ? pvt->dbam1 : pvt->dbam0;
+
/*
* The math on this doesn't look right on the surface because x/2*4 can
* be simplified to x*2 but this expression makes use of the fact that
@@ -2173,13 +2095,13 @@ static u32 amd64_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr)
* number of bits to shift the DBAM register to extract the proper CSROW
* field.
*/
- cs_mode = (dbam >> ((csrow_nr / 2) * 4)) & 0xF;
+ cs_mode = DBAM_DIMM(csrow_nr / 2, dbam);
nr_pages = pvt->ops->dbam_to_cs(pvt, dct, cs_mode) << (20 - PAGE_SHIFT);
- edac_dbg(0, " (csrow=%d) DBAM map index= %d\n", csrow_nr, cs_mode);
- edac_dbg(0, " nr_pages/channel= %u channel-count = %d\n",
- nr_pages, pvt->channel_count);
+ edac_dbg(0, "csrow: %d, channel: %d, DBAM idx: %d\n",
+ csrow_nr, dct, cs_mode);
+ edac_dbg(0, "nr_pages/channel: %u\n", nr_pages);
return nr_pages;
}
@@ -2190,15 +2112,14 @@ static u32 amd64_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr)
*/
static int init_csrows(struct mem_ctl_info *mci)
{
+ struct amd64_pvt *pvt = mci->pvt_info;
struct csrow_info *csrow;
struct dimm_info *dimm;
- struct amd64_pvt *pvt = mci->pvt_info;
- u64 base, mask;
- u32 val;
- int i, j, empty = 1;
- enum mem_type mtype;
enum edac_type edac_mode;
+ enum mem_type mtype;
+ int i, j, empty = 1;
int nr_pages = 0;
+ u32 val;
amd64_read_pci_cfg(pvt->F3, NBCFG, &val);
@@ -2208,29 +2129,35 @@ static int init_csrows(struct mem_ctl_info *mci)
pvt->mc_node_id, val,
!!(val & NBCFG_CHIPKILL), !!(val & NBCFG_ECC_ENABLE));
+ /*
+ * We iterate over DCT0 here but we look at DCT1 in parallel, if needed.
+ */
for_each_chip_select(i, 0, pvt) {
- csrow = mci->csrows[i];
+ bool row_dct0 = !!csrow_enabled(i, 0, pvt);
+ bool row_dct1 = false;
+
+ if (boot_cpu_data.x86 != 0xf)
+ row_dct1 = !!csrow_enabled(i, 1, pvt);
- if (!csrow_enabled(i, 0, pvt) && !csrow_enabled(i, 1, pvt)) {
- edac_dbg(1, "----CSROW %d VALID for MC node %d\n",
- i, pvt->mc_node_id);
+ if (!row_dct0 && !row_dct1)
continue;
- }
+ csrow = mci->csrows[i];
empty = 0;
- if (csrow_enabled(i, 0, pvt))
+
+ edac_dbg(1, "MC node: %d, csrow: %d\n",
+ pvt->mc_node_id, i);
+
+ if (row_dct0)
nr_pages = amd64_csrow_nr_pages(pvt, 0, i);
- if (csrow_enabled(i, 1, pvt))
- nr_pages += amd64_csrow_nr_pages(pvt, 1, i);
- get_cs_base_and_mask(pvt, i, 0, &base, &mask);
- /* 8 bytes of resolution */
+ /* K8 has only one DCT */
+ if (boot_cpu_data.x86 != 0xf && row_dct1)
+ nr_pages += amd64_csrow_nr_pages(pvt, 1, i);
mtype = amd64_determine_memory_type(pvt, i);
- edac_dbg(1, " for MC node %d csrow %d:\n", pvt->mc_node_id, i);
- edac_dbg(1, " nr_pages: %u\n",
- nr_pages * pvt->channel_count);
+ edac_dbg(1, "Total csrow%d pages: %u\n", i, nr_pages);
/*
* determine whether CHIPKILL or JUST ECC or NO ECC is operating
@@ -2247,6 +2174,7 @@ static int init_csrows(struct mem_ctl_info *mci)
dimm->edac_mode = edac_mode;
dimm->nr_pages = nr_pages;
}
+ csrow->nr_pages = nr_pages;
}
return empty;
@@ -2591,6 +2519,7 @@ static int amd64_init_one_instance(struct pci_dev *F2)
mci->pvt_info = pvt;
mci->pdev = &pvt->F2->dev;
+ mci->csbased = 1;
setup_mci_misc_attrs(mci, fam_type);
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 8d4804732ba..e864f407806 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -33,7 +33,7 @@
* detection. The mods to Rev F required more family
* information detection.
*
- * Changes/Fixes by Borislav Petkov <borislav.petkov@amd.com>:
+ * Changes/Fixes by Borislav Petkov <bp@alien8.de>:
* - misc fixes and code cleanups
*
* This module is based on the following documents
@@ -219,7 +219,7 @@
#define DBAM1 0x180
/* Extract the DIMM 'type' on the i'th DIMM from the DBAM reg value passed */
-#define DBAM_DIMM(i, reg) ((((reg) >> (4*i))) & 0xF)
+#define DBAM_DIMM(i, reg) ((((reg) >> (4*(i)))) & 0xF)
#define DBAM_MAX_VALUE 11
@@ -267,18 +267,20 @@
#define online_spare_bad_dramcs(pvt, c) (((pvt)->online_spare >> (4 + 4 * (c))) & 0x7)
#define F10_NB_ARRAY_ADDR 0xB8
-#define F10_NB_ARRAY_DRAM_ECC BIT(31)
+#define F10_NB_ARRAY_DRAM BIT(31)
/* Bits [2:1] are used to select 16-byte section within a 64-byte cacheline */
-#define SET_NB_ARRAY_ADDRESS(section) (((section) & 0x3) << 1)
+#define SET_NB_ARRAY_ADDR(section) (((section) & 0x3) << 1)
#define F10_NB_ARRAY_DATA 0xBC
-#define SET_NB_DRAM_INJECTION_WRITE(word, bits) \
- (BIT(((word) & 0xF) + 20) | \
- BIT(17) | bits)
-#define SET_NB_DRAM_INJECTION_READ(word, bits) \
- (BIT(((word) & 0xF) + 20) | \
- BIT(16) | bits)
+#define F10_NB_ARR_ECC_WR_REQ BIT(17)
+#define SET_NB_DRAM_INJECTION_WRITE(inj) \
+ (BIT(((inj.word) & 0xF) + 20) | \
+ F10_NB_ARR_ECC_WR_REQ | inj.bit_map)
+#define SET_NB_DRAM_INJECTION_READ(inj) \
+ (BIT(((inj.word) & 0xF) + 20) | \
+ BIT(16) | inj.bit_map)
+
#define NBCAP 0xE8
#define NBCAP_CHIPKILL BIT(4)
@@ -305,9 +307,9 @@ enum amd_families {
/* Error injection control structure */
struct error_injection {
- u32 section;
- u32 word;
- u32 bit_map;
+ u32 section;
+ u32 word;
+ u32 bit_map;
};
/* low and high part of PCI config space regs */
@@ -374,6 +376,23 @@ struct amd64_pvt {
struct error_injection injection;
};
+enum err_codes {
+ DECODE_OK = 0,
+ ERR_NODE = -1,
+ ERR_CSROW = -2,
+ ERR_CHANNEL = -3,
+};
+
+struct err_info {
+ int err_code;
+ struct mem_ctl_info *src_mci;
+ int csrow;
+ int channel;
+ u16 syndrome;
+ u32 page;
+ u32 offset;
+};
+
static inline u64 get_dram_base(struct amd64_pvt *pvt, unsigned i)
{
u64 addr = ((u64)pvt->ranges[i].base.lo & 0xffff0000) << 8;
@@ -447,7 +466,7 @@ static inline void amd64_remove_sysfs_inject_files(struct mem_ctl_info *mci)
struct low_ops {
int (*early_channel_count) (struct amd64_pvt *pvt);
void (*map_sysaddr_to_csrow) (struct mem_ctl_info *mci, u64 sys_addr,
- u16 syndrome);
+ struct err_info *);
int (*dbam_to_cs) (struct amd64_pvt *pvt, u8 dct, unsigned cs_mode);
int (*read_dct_pci_cfg) (struct amd64_pvt *pvt, int offset,
u32 *val, const char *func);
@@ -459,6 +478,8 @@ struct amd64_family_type {
struct low_ops ops;
};
+int __amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,
+ u32 *val, const char *func);
int __amd64_write_pci_cfg_dword(struct pci_dev *pdev, int offset,
u32 val, const char *func);
@@ -475,3 +496,15 @@ int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
u64 *hole_offset, u64 *hole_size);
#define to_mci(k) container_of(k, struct mem_ctl_info, dev)
+
+/* Injection helpers */
+static inline void disable_caches(void *dummy)
+{
+ write_cr0(read_cr0() | X86_CR0_CD);
+ wbinvd();
+}
+
+static inline void enable_caches(void *dummy)
+{
+ write_cr0(read_cr0() & ~X86_CR0_CD);
+}
diff --git a/drivers/edac/amd64_edac_inj.c b/drivers/edac/amd64_edac_inj.c
index 53d972e00df..8c171fa1cb9 100644
--- a/drivers/edac/amd64_edac_inj.c
+++ b/drivers/edac/amd64_edac_inj.c
@@ -22,20 +22,19 @@ static ssize_t amd64_inject_section_store(struct device *dev,
struct mem_ctl_info *mci = to_mci(dev);
struct amd64_pvt *pvt = mci->pvt_info;
unsigned long value;
- int ret = 0;
+ int ret;
ret = strict_strtoul(data, 10, &value);
- if (ret != -EINVAL) {
+ if (ret < 0)
+ return ret;
- if (value > 3) {
- amd64_warn("%s: invalid section 0x%lx\n", __func__, value);
- return -EINVAL;
- }
-
- pvt->injection.section = (u32) value;
- return count;
+ if (value > 3) {
+ amd64_warn("%s: invalid section 0x%lx\n", __func__, value);
+ return -EINVAL;
}
- return ret;
+
+ pvt->injection.section = (u32) value;
+ return count;
}
static ssize_t amd64_inject_word_show(struct device *dev,
@@ -60,20 +59,19 @@ static ssize_t amd64_inject_word_store(struct device *dev,
struct mem_ctl_info *mci = to_mci(dev);
struct amd64_pvt *pvt = mci->pvt_info;
unsigned long value;
- int ret = 0;
+ int ret;
ret = strict_strtoul(data, 10, &value);
- if (ret != -EINVAL) {
+ if (ret < 0)
+ return ret;
- if (value > 8) {
- amd64_warn("%s: invalid word 0x%lx\n", __func__, value);
- return -EINVAL;
- }
-
- pvt->injection.word = (u32) value;
- return count;
+ if (value > 8) {
+ amd64_warn("%s: invalid word 0x%lx\n", __func__, value);
+ return -EINVAL;
}
- return ret;
+
+ pvt->injection.word = (u32) value;
+ return count;
}
static ssize_t amd64_inject_ecc_vector_show(struct device *dev,
@@ -97,21 +95,19 @@ static ssize_t amd64_inject_ecc_vector_store(struct device *dev,
struct mem_ctl_info *mci = to_mci(dev);
struct amd64_pvt *pvt = mci->pvt_info;
unsigned long value;
- int ret = 0;
+ int ret;
ret = strict_strtoul(data, 16, &value);
- if (ret != -EINVAL) {
+ if (ret < 0)
+ return ret;
- if (value & 0xFFFF0000) {
- amd64_warn("%s: invalid EccVector: 0x%lx\n",
- __func__, value);
- return -EINVAL;
- }
-
- pvt->injection.bit_map = (u32) value;
- return count;
+ if (value & 0xFFFF0000) {
+ amd64_warn("%s: invalid EccVector: 0x%lx\n", __func__, value);
+ return -EINVAL;
}
- return ret;
+
+ pvt->injection.bit_map = (u32) value;
+ return count;
}
/*
@@ -126,28 +122,25 @@ static ssize_t amd64_inject_read_store(struct device *dev,
struct amd64_pvt *pvt = mci->pvt_info;
unsigned long value;
u32 section, word_bits;
- int ret = 0;
+ int ret;
ret = strict_strtoul(data, 10, &value);
- if (ret != -EINVAL) {
+ if (ret < 0)
+ return ret;
- /* Form value to choose 16-byte section of cacheline */
- section = F10_NB_ARRAY_DRAM_ECC |
- SET_NB_ARRAY_ADDRESS(pvt->injection.section);
- amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section);
+ /* Form value to choose 16-byte section of cacheline */
+ section = F10_NB_ARRAY_DRAM | SET_NB_ARRAY_ADDR(pvt->injection.section);
- word_bits = SET_NB_DRAM_INJECTION_READ(pvt->injection.word,
- pvt->injection.bit_map);
+ amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section);
- /* Issue 'word' and 'bit' along with the READ request */
- amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits);
+ word_bits = SET_NB_DRAM_INJECTION_READ(pvt->injection);
- edac_dbg(0, "section=0x%x word_bits=0x%x\n",
- section, word_bits);
+ /* Issue 'word' and 'bit' along with the READ request */
+ amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits);
- return count;
- }
- return ret;
+ edac_dbg(0, "section=0x%x word_bits=0x%x\n", section, word_bits);
+
+ return count;
}
/*
@@ -160,30 +153,43 @@ static ssize_t amd64_inject_write_store(struct device *dev,
{
struct mem_ctl_info *mci = to_mci(dev);
struct amd64_pvt *pvt = mci->pvt_info;
+ u32 section, word_bits, tmp;
unsigned long value;
- u32 section, word_bits;
- int ret = 0;
+ int ret;
ret = strict_strtoul(data, 10, &value);
- if (ret != -EINVAL) {
+ if (ret < 0)
+ return ret;
+
+ /* Form value to choose 16-byte section of cacheline */
+ section = F10_NB_ARRAY_DRAM | SET_NB_ARRAY_ADDR(pvt->injection.section);
+
+ amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section);
- /* Form value to choose 16-byte section of cacheline */
- section = F10_NB_ARRAY_DRAM_ECC |
- SET_NB_ARRAY_ADDRESS(pvt->injection.section);
- amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section);
+ word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection);
- word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection.word,
- pvt->injection.bit_map);
+ pr_notice_once("Don't forget to decrease MCE polling interval in\n"
+ "/sys/bus/machinecheck/devices/machinecheck<CPUNUM>/check_interval\n"
+ "so that you can get the error report faster.\n");
- /* Issue 'word' and 'bit' along with the READ request */
- amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits);
+ on_each_cpu(disable_caches, NULL, 1);
- edac_dbg(0, "section=0x%x word_bits=0x%x\n",
- section, word_bits);
+ /* Issue 'word' and 'bit' along with the READ request */
+ amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits);
- return count;
+ retry:
+ /* wait until injection happens */
+ amd64_read_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, &tmp);
+ if (tmp & F10_NB_ARR_ECC_WR_REQ) {
+ cpu_relax();
+ goto retry;
}
- return ret;
+
+ on_each_cpu(enable_caches, NULL, 1);
+
+ edac_dbg(0, "section=0x%x word_bits=0x%x\n", section, word_bits);
+
+ return count;
}
/*
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 90f0b730e9b..281f566a551 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -416,10 +416,18 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
dimm->cschannel = chn;
/* Increment csrow location */
- row++;
- if (row == tot_csrows) {
- row = 0;
+ if (layers[0].is_virt_csrow) {
chn++;
+ if (chn == tot_channels) {
+ chn = 0;
+ row++;
+ }
+ } else {
+ row++;
+ if (row == tot_csrows) {
+ row = 0;
+ chn++;
+ }
}
/* Increment dimm location */
@@ -966,20 +974,22 @@ static void edac_ce_error(struct mem_ctl_info *mci,
long grain)
{
unsigned long remapped_page;
+ char *msg_aux = "";
+
+ if (*msg)
+ msg_aux = " ";
if (edac_mc_get_log_ce()) {
if (other_detail && *other_detail)
edac_mc_printk(mci, KERN_WARNING,
- "%d CE %s on %s (%s %s - %s)\n",
- error_count,
- msg, label, location,
- detail, other_detail);
+ "%d CE %s%son %s (%s %s - %s)\n",
+ error_count, msg, msg_aux, label,
+ location, detail, other_detail);
else
edac_mc_printk(mci, KERN_WARNING,
- "%d CE %s on %s (%s %s)\n",
- error_count,
- msg, label, location,
- detail);
+ "%d CE %s%son %s (%s %s)\n",
+ error_count, msg, msg_aux, label,
+ location, detail);
}
edac_inc_ce_error(mci, enable_per_layer_report, pos, error_count);
@@ -1014,27 +1024,31 @@ static void edac_ue_error(struct mem_ctl_info *mci,
const char *other_detail,
const bool enable_per_layer_report)
{
+ char *msg_aux = "";
+
+ if (*msg)
+ msg_aux = " ";
+
if (edac_mc_get_log_ue()) {
if (other_detail && *other_detail)
edac_mc_printk(mci, KERN_WARNING,
- "%d UE %s on %s (%s %s - %s)\n",
- error_count,
- msg, label, location, detail,
- other_detail);
+ "%d UE %s%son %s (%s %s - %s)\n",
+ error_count, msg, msg_aux, label,
+ location, detail, other_detail);
else
edac_mc_printk(mci, KERN_WARNING,
- "%d UE %s on %s (%s %s)\n",
- error_count,
- msg, label, location, detail);
+ "%d UE %s%son %s (%s %s)\n",
+ error_count, msg, msg_aux, label,
+ location, detail);
}
if (edac_mc_get_panic_on_ue()) {
if (other_detail && *other_detail)
- panic("UE %s on %s (%s%s - %s)\n",
- msg, label, location, detail, other_detail);
+ panic("UE %s%son %s (%s%s - %s)\n",
+ msg, msg_aux, label, location, detail, other_detail);
else
- panic("UE %s on %s (%s%s)\n",
- msg, label, location, detail);
+ panic("UE %s%son %s (%s%s)\n",
+ msg, msg_aux, label, location, detail);
}
edac_inc_ue_error(mci, enable_per_layer_report, pos, error_count);
@@ -1093,10 +1107,6 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
*/
for (i = 0; i < mci->n_layers; i++) {
if (pos[i] >= (int)mci->layers[i].size) {
- if (type == HW_EVENT_ERR_CORRECTED)
- p = "CE";
- else
- p = "UE";
edac_mc_printk(mci, KERN_ERR,
"INTERNAL ERROR: %s value is out of range (%d >= %d)\n",
@@ -1128,6 +1138,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
grain = 0;
p = label;
*p = '\0';
+
for (i = 0; i < mci->tot_dimms; i++) {
struct dimm_info *dimm = mci->dimms[i];
@@ -1195,6 +1206,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
/* Fill the RAM location data */
p = location;
+
for (i = 0; i < mci->n_layers; i++) {
if (pos[i] < 0)
continue;
@@ -1207,7 +1219,6 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
*(p - 1) = '\0';
/* Report the error via the trace interface */
-
grain_bits = fls_long(grain) + 1;
trace_mc_event(type, msg, label, error_count,
mci->mc_idx, top_layer, mid_layer, low_layer,
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index ed0bc07b850..de2df92f9c7 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -180,6 +180,9 @@ static ssize_t csrow_size_show(struct device *dev,
int i;
u32 nr_pages = 0;
+ if (csrow->mci->csbased)
+ return sprintf(data, "%u\n", PAGES_TO_MiB(csrow->nr_pages));
+
for (i = 0; i < csrow->nr_channels; i++)
nr_pages += csrow->channels[i]->dimm->nr_pages;
return sprintf(data, "%u\n", PAGES_TO_MiB(nr_pages));
@@ -373,6 +376,7 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
csrow->dev.bus = &mci->bus;
device_initialize(&csrow->dev);
csrow->dev.parent = &mci->dev;
+ csrow->mci = mci;
dev_set_name(&csrow->dev, "csrow%d", index);
dev_set_drvdata(&csrow->dev, csrow);
@@ -777,10 +781,14 @@ static ssize_t mci_size_mb_show(struct device *dev,
for (csrow_idx = 0; csrow_idx < mci->nr_csrows; csrow_idx++) {
struct csrow_info *csrow = mci->csrows[csrow_idx];
- for (j = 0; j < csrow->nr_channels; j++) {
- struct dimm_info *dimm = csrow->channels[j]->dimm;
+ if (csrow->mci->csbased) {
+ total_pages += csrow->nr_pages;
+ } else {
+ for (j = 0; j < csrow->nr_channels; j++) {
+ struct dimm_info *dimm = csrow->channels[j]->dimm;
- total_pages += dimm->nr_pages;
+ total_pages += dimm->nr_pages;
+ }
}
}
@@ -838,14 +846,8 @@ static ssize_t edac_fake_inject_write(struct file *file,
return count;
}
-static int debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static const struct file_operations debug_fake_inject_fops = {
- .open = debugfs_open,
+ .open = simple_open,
.write = edac_fake_inject_write,
.llseek = generic_file_llseek,
};
@@ -1124,10 +1126,15 @@ int __init edac_mc_sysfs_init(void)
edac_subsys = edac_get_sysfs_subsys();
if (edac_subsys == NULL) {
edac_dbg(1, "no edac_subsys\n");
- return -EINVAL;
+ err = -EINVAL;
+ goto out;
}
mci_pdev = kzalloc(sizeof(*mci_pdev), GFP_KERNEL);
+ if (!mci_pdev) {
+ err = -ENOMEM;
+ goto out_put_sysfs;
+ }
mci_pdev->bus = edac_subsys;
mci_pdev->type = &mc_attr_type;
@@ -1136,11 +1143,18 @@ int __init edac_mc_sysfs_init(void)
err = device_add(mci_pdev);
if (err < 0)
- return err;
+ goto out_dev_free;
edac_dbg(0, "device %s created\n", dev_name(mci_pdev));
return 0;
+
+ out_dev_free:
+ kfree(mci_pdev);
+ out_put_sysfs:
+ edac_put_sysfs_subsys();
+ out:
+ return err;
}
void __exit edac_mc_sysfs_exit(void)
@@ -1148,4 +1162,5 @@ void __exit edac_mc_sysfs_exit(void)
put_device(mci_pdev);
device_del(mci_pdev);
edac_put_sysfs_subsys();
+ kfree(mci_pdev);
}
diff --git a/drivers/edac/edac_module.c b/drivers/edac/edac_module.c
index 58a28d838f3..12c951a2c33 100644
--- a/drivers/edac/edac_module.c
+++ b/drivers/edac/edac_module.c
@@ -18,9 +18,29 @@
#define EDAC_VERSION "Ver: 3.0.0"
#ifdef CONFIG_EDAC_DEBUG
+
+static int edac_set_debug_level(const char *buf, struct kernel_param *kp)
+{
+ unsigned long val;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &val);
+ if (ret)
+ return ret;
+
+ if (val < 0 || val > 4)
+ return -EINVAL;
+
+ return param_set_int(buf, kp);
+}
+
/* Values of 0 to 4 will generate output */
int edac_debug_level = 2;
EXPORT_SYMBOL_GPL(edac_debug_level);
+
+module_param_call(edac_debug_level, edac_set_debug_level, param_get_int,
+ &edac_debug_level, 0644);
+MODULE_PARM_DESC(edac_debug_level, "EDAC debug level: [0-4], default: 2");
#endif
/* scope is to module level only */
@@ -132,10 +152,3 @@ module_exit(edac_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Doug Thompson www.softwarebitmaker.com, et al");
MODULE_DESCRIPTION("Core library routines for EDAC reporting");
-
-/* refer to *_sysfs.c files for parameters that are exported via sysfs */
-
-#ifdef CONFIG_EDAC_DEBUG
-module_param(edac_debug_level, int, 0644);
-MODULE_PARM_DESC(edac_debug_level, "Debug level");
-#endif
diff --git a/drivers/edac/edac_pci.c b/drivers/edac/edac_pci.c
index ee87ef972ea..dd370f92ace 100644
--- a/drivers/edac/edac_pci.c
+++ b/drivers/edac/edac_pci.c
@@ -470,7 +470,8 @@ struct edac_pci_ctl_info *edac_pci_create_generic_ctl(struct device *dev,
pci->mod_name = mod_name;
pci->ctl_name = EDAC_PCI_GENCTL_NAME;
- pci->edac_check = edac_pci_generic_check;
+ if (edac_op_state == EDAC_OPSTATE_POLL)
+ pci->edac_check = edac_pci_generic_check;
pdata->edac_idx = edac_pci_idx++;
diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c
index e164c555a33..dc6e905ee1a 100644
--- a/drivers/edac/edac_pci_sysfs.c
+++ b/drivers/edac/edac_pci_sysfs.c
@@ -645,20 +645,16 @@ typedef void (*pci_parity_check_fn_t) (struct pci_dev *dev);
/*
* pci_dev parity list iterator
- * Scan the PCI device list for one pass, looking for SERRORs
- * Master Parity ERRORS or Parity ERRORs on primary or secondary devices
+ *
+ * Scan the PCI device list looking for SERRORs, Master Parity ERRORS or
+ * Parity ERRORs on primary or secondary devices.
*/
static inline void edac_pci_dev_parity_iterator(pci_parity_check_fn_t fn)
{
struct pci_dev *dev = NULL;
- /* request for kernel access to the next PCI device, if any,
- * and while we are looking at it have its reference count
- * bumped until we are done with it
- */
- while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+ for_each_pci_dev(dev)
fn(dev);
- }
}
/*
diff --git a/drivers/edac/edac_stub.c b/drivers/edac/edac_stub.c
index 6c86f6e5455..351945fa2ec 100644
--- a/drivers/edac/edac_stub.c
+++ b/drivers/edac/edac_stub.c
@@ -5,7 +5,7 @@
*
* 2007 (c) MontaVista Software, Inc.
* 2010 (c) Advanced Micro Devices Inc.
- * Borislav Petkov <borislav.petkov@amd.com>
+ * Borislav Petkov <bp@alien8.de>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
diff --git a/drivers/edac/highbank_mc_edac.c b/drivers/edac/highbank_mc_edac.c
index c769f477fd2..7ea4cc2e8bd 100644
--- a/drivers/edac/highbank_mc_edac.c
+++ b/drivers/edac/highbank_mc_edac.c
@@ -113,14 +113,8 @@ static ssize_t highbank_mc_err_inject_write(struct file *file,
return count;
}
-static int debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static const struct file_operations highbank_mc_debug_inject_fops = {
- .open = debugfs_open,
+ .open = simple_open,
.write = highbank_mc_err_inject_write,
.llseek = generic_file_llseek,
};
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c
index a09d0667f72..9d669cd4361 100644
--- a/drivers/edac/i7300_edac.c
+++ b/drivers/edac/i7300_edac.c
@@ -197,8 +197,8 @@ static const char *ferr_fat_fbd_name[] = {
[0] = "Memory Write error on non-redundant retry or "
"FBD configuration Write error on retry",
};
-#define GET_FBD_FAT_IDX(fbderr) (fbderr & (3 << 28))
-#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3))
+#define GET_FBD_FAT_IDX(fbderr) (((fbderr) >> 28) & 3)
+#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 22))
#define FERR_NF_FBD 0xa0
static const char *ferr_nf_fbd_name[] = {
@@ -225,7 +225,7 @@ static const char *ferr_nf_fbd_name[] = {
[1] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC",
[0] = "Uncorrectable Data ECC on Replay",
};
-#define GET_FBD_NF_IDX(fbderr) (fbderr & (3 << 28))
+#define GET_FBD_NF_IDX(fbderr) (((fbderr) >> 28) & 3)
#define FERR_NF_FBD_ERR_MASK ((1 << 24) | (1 << 23) | (1 << 22) | (1 << 21) |\
(1 << 18) | (1 << 17) | (1 << 16) | (1 << 15) |\
(1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) |\
@@ -464,7 +464,7 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
errnum = find_first_bit(&errors,
ARRAY_SIZE(ferr_nf_fbd_name));
specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum);
- branch = (GET_FBD_FAT_IDX(error_reg) == 2) ? 1 : 0;
+ branch = (GET_FBD_NF_IDX(error_reg) == 2) ? 1 : 0;
pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
REDMEMA, &syndrome);
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 3672101023b..10c8c00d646 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -816,7 +816,7 @@ static ssize_t i7core_inject_store_##param( \
struct device_attribute *mattr, \
const char *data, size_t count) \
{ \
- struct mem_ctl_info *mci = to_mci(dev); \
+ struct mem_ctl_info *mci = dev_get_drvdata(dev); \
struct i7core_pvt *pvt; \
long value; \
int rc; \
@@ -845,7 +845,7 @@ static ssize_t i7core_inject_show_##param( \
struct device_attribute *mattr, \
char *data) \
{ \
- struct mem_ctl_info *mci = to_mci(dev); \
+ struct mem_ctl_info *mci = dev_get_drvdata(dev); \
struct i7core_pvt *pvt; \
\
pvt = mci->pvt_info; \
@@ -1052,7 +1052,7 @@ static ssize_t i7core_show_counter_##param( \
struct device_attribute *mattr, \
char *data) \
{ \
- struct mem_ctl_info *mci = to_mci(dev); \
+ struct mem_ctl_info *mci = dev_get_drvdata(dev); \
struct i7core_pvt *pvt = mci->pvt_info; \
\
edac_dbg(1, "\n"); \
diff --git a/drivers/edac/i82975x_edac.c b/drivers/edac/i82975x_edac.c
index 069e26c11c4..a98020409fa 100644
--- a/drivers/edac/i82975x_edac.c
+++ b/drivers/edac/i82975x_edac.c
@@ -370,10 +370,6 @@ static enum dev_type i82975x_dram_type(void __iomem *mch_window, int rank)
static void i82975x_init_csrows(struct mem_ctl_info *mci,
struct pci_dev *pdev, void __iomem *mch_window)
{
- static const char *labels[4] = {
- "DIMM A1", "DIMM A2",
- "DIMM B1", "DIMM B2"
- };
struct csrow_info *csrow;
unsigned long last_cumul_size;
u8 value;
@@ -423,9 +419,10 @@ static void i82975x_init_csrows(struct mem_ctl_info *mci,
dimm = mci->csrows[index]->channels[chan]->dimm;
dimm->nr_pages = nr_pages / csrow->nr_channels;
- strncpy(csrow->channels[chan]->dimm->label,
- labels[(index >> 1) + (chan * 2)],
- EDAC_MC_LABEL_LEN);
+
+ snprintf(csrow->channels[chan]->dimm->label, EDAC_MC_LABEL_LEN, "DIMM %c%d",
+ (chan == 0) ? 'A' : 'B',
+ index);
dimm->grain = 1 << 7; /* 128Byte cache-line resolution */
dimm->dtype = i82975x_dram_type(mch_window, index);
dimm->mtype = MEM_DDR2; /* I82975x supports only DDR2 */
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index d0c372e30de..ad637572d8c 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -64,7 +64,7 @@ EXPORT_SYMBOL_GPL(to_msgs);
const char * const ii_msgs[] = { "MEM", "RESV", "IO", "GEN" };
EXPORT_SYMBOL_GPL(ii_msgs);
-static const char * const f15h_ic_mce_desc[] = {
+static const char * const f15h_mc1_mce_desc[] = {
"UC during a demand linefill from L2",
"Parity error during data load from IC",
"Parity error for IC valid bit",
@@ -84,7 +84,7 @@ static const char * const f15h_ic_mce_desc[] = {
"fetch address FIFO"
};
-static const char * const f15h_cu_mce_desc[] = {
+static const char * const f15h_mc2_mce_desc[] = {
"Fill ECC error on data fills", /* xec = 0x4 */
"Fill parity error on insn fills",
"Prefetcher request FIFO parity error",
@@ -101,7 +101,7 @@ static const char * const f15h_cu_mce_desc[] = {
"PRB address parity error"
};
-static const char * const nb_mce_desc[] = {
+static const char * const mc4_mce_desc[] = {
"DRAM ECC error detected on the NB",
"CRC error detected on HT link",
"Link-defined sync error packets detected on HT link",
@@ -123,7 +123,7 @@ static const char * const nb_mce_desc[] = {
"ECC Error in the Probe Filter directory"
};
-static const char * const fr_ex_mce_desc[] = {
+static const char * const mc5_mce_desc[] = {
"CPU Watchdog timer expire",
"Wakeup array dest tag",
"AG payload array",
@@ -139,7 +139,7 @@ static const char * const fr_ex_mce_desc[] = {
"DE error occurred"
};
-static bool f12h_dc_mce(u16 ec, u8 xec)
+static bool f12h_mc0_mce(u16 ec, u8 xec)
{
bool ret = false;
@@ -157,26 +157,26 @@ static bool f12h_dc_mce(u16 ec, u8 xec)
return ret;
}
-static bool f10h_dc_mce(u16 ec, u8 xec)
+static bool f10h_mc0_mce(u16 ec, u8 xec)
{
if (R4(ec) == R4_GEN && LL(ec) == LL_L1) {
pr_cont("during data scrub.\n");
return true;
}
- return f12h_dc_mce(ec, xec);
+ return f12h_mc0_mce(ec, xec);
}
-static bool k8_dc_mce(u16 ec, u8 xec)
+static bool k8_mc0_mce(u16 ec, u8 xec)
{
if (BUS_ERROR(ec)) {
pr_cont("during system linefill.\n");
return true;
}
- return f10h_dc_mce(ec, xec);
+ return f10h_mc0_mce(ec, xec);
}
-static bool f14h_dc_mce(u16 ec, u8 xec)
+static bool f14h_mc0_mce(u16 ec, u8 xec)
{
u8 r4 = R4(ec);
bool ret = true;
@@ -228,7 +228,7 @@ static bool f14h_dc_mce(u16 ec, u8 xec)
return ret;
}
-static bool f15h_dc_mce(u16 ec, u8 xec)
+static bool f15h_mc0_mce(u16 ec, u8 xec)
{
bool ret = true;
@@ -275,12 +275,12 @@ static bool f15h_dc_mce(u16 ec, u8 xec)
return ret;
}
-static void amd_decode_dc_mce(struct mce *m)
+static void decode_mc0_mce(struct mce *m)
{
u16 ec = EC(m->status);
u8 xec = XEC(m->status, xec_mask);
- pr_emerg(HW_ERR "Data Cache Error: ");
+ pr_emerg(HW_ERR "MC0 Error: ");
/* TLB error signatures are the same across families */
if (TLB_ERROR(ec)) {
@@ -290,13 +290,13 @@ static void amd_decode_dc_mce(struct mce *m)
: (xec ? "multimatch" : "parity")));
return;
}
- } else if (fam_ops->dc_mce(ec, xec))
+ } else if (fam_ops->mc0_mce(ec, xec))
;
else
- pr_emerg(HW_ERR "Corrupted DC MCE info?\n");
+ pr_emerg(HW_ERR "Corrupted MC0 MCE info?\n");
}
-static bool k8_ic_mce(u16 ec, u8 xec)
+static bool k8_mc1_mce(u16 ec, u8 xec)
{
u8 ll = LL(ec);
bool ret = true;
@@ -330,7 +330,7 @@ static bool k8_ic_mce(u16 ec, u8 xec)
return ret;
}
-static bool f14h_ic_mce(u16 ec, u8 xec)
+static bool f14h_mc1_mce(u16 ec, u8 xec)
{
u8 r4 = R4(ec);
bool ret = true;
@@ -349,7 +349,7 @@ static bool f14h_ic_mce(u16 ec, u8 xec)
return ret;
}
-static bool f15h_ic_mce(u16 ec, u8 xec)
+static bool f15h_mc1_mce(u16 ec, u8 xec)
{
bool ret = true;
@@ -358,19 +358,19 @@ static bool f15h_ic_mce(u16 ec, u8 xec)
switch (xec) {
case 0x0 ... 0xa:
- pr_cont("%s.\n", f15h_ic_mce_desc[xec]);
+ pr_cont("%s.\n", f15h_mc1_mce_desc[xec]);
break;
case 0xd:
- pr_cont("%s.\n", f15h_ic_mce_desc[xec-2]);
+ pr_cont("%s.\n", f15h_mc1_mce_desc[xec-2]);
break;
case 0x10:
- pr_cont("%s.\n", f15h_ic_mce_desc[xec-4]);
+ pr_cont("%s.\n", f15h_mc1_mce_desc[xec-4]);
break;
case 0x11 ... 0x14:
- pr_cont("Decoder %s parity error.\n", f15h_ic_mce_desc[xec-4]);
+ pr_cont("Decoder %s parity error.\n", f15h_mc1_mce_desc[xec-4]);
break;
default:
@@ -379,12 +379,12 @@ static bool f15h_ic_mce(u16 ec, u8 xec)
return ret;
}
-static void amd_decode_ic_mce(struct mce *m)
+static void decode_mc1_mce(struct mce *m)
{
u16 ec = EC(m->status);
u8 xec = XEC(m->status, xec_mask);
- pr_emerg(HW_ERR "Instruction Cache Error: ");
+ pr_emerg(HW_ERR "MC1 Error: ");
if (TLB_ERROR(ec))
pr_cont("%s TLB %s.\n", LL_MSG(ec),
@@ -393,18 +393,18 @@ static void amd_decode_ic_mce(struct mce *m)
bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
- } else if (fam_ops->ic_mce(ec, xec))
+ } else if (fam_ops->mc1_mce(ec, xec))
;
else
- pr_emerg(HW_ERR "Corrupted IC MCE info?\n");
+ pr_emerg(HW_ERR "Corrupted MC1 MCE info?\n");
}
-static void amd_decode_bu_mce(struct mce *m)
+static void decode_mc2_mce(struct mce *m)
{
u16 ec = EC(m->status);
u8 xec = XEC(m->status, xec_mask);
- pr_emerg(HW_ERR "Bus Unit Error");
+ pr_emerg(HW_ERR "MC2 Error");
if (xec == 0x1)
pr_cont(" in the write data buffers.\n");
@@ -429,24 +429,24 @@ static void amd_decode_bu_mce(struct mce *m)
pr_cont(": %s parity/ECC error during data "
"access from L2.\n", R4_MSG(ec));
else
- goto wrong_bu_mce;
+ goto wrong_mc2_mce;
} else
- goto wrong_bu_mce;
+ goto wrong_mc2_mce;
} else
- goto wrong_bu_mce;
+ goto wrong_mc2_mce;
return;
-wrong_bu_mce:
- pr_emerg(HW_ERR "Corrupted BU MCE info?\n");
+ wrong_mc2_mce:
+ pr_emerg(HW_ERR "Corrupted MC2 MCE info?\n");
}
-static void amd_decode_cu_mce(struct mce *m)
+static void decode_f15_mc2_mce(struct mce *m)
{
u16 ec = EC(m->status);
u8 xec = XEC(m->status, xec_mask);
- pr_emerg(HW_ERR "Combined Unit Error: ");
+ pr_emerg(HW_ERR "MC2 Error: ");
if (TLB_ERROR(ec)) {
if (xec == 0x0)
@@ -454,63 +454,63 @@ static void amd_decode_cu_mce(struct mce *m)
else if (xec == 0x1)
pr_cont("Poison data provided for TLB fill.\n");
else
- goto wrong_cu_mce;
+ goto wrong_f15_mc2_mce;
} else if (BUS_ERROR(ec)) {
if (xec > 2)
- goto wrong_cu_mce;
+ goto wrong_f15_mc2_mce;
pr_cont("Error during attempted NB data read.\n");
} else if (MEM_ERROR(ec)) {
switch (xec) {
case 0x4 ... 0xc:
- pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x4]);
+ pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x4]);
break;
case 0x10 ... 0x14:
- pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x7]);
+ pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x7]);
break;
default:
- goto wrong_cu_mce;
+ goto wrong_f15_mc2_mce;
}
}
return;
-wrong_cu_mce:
- pr_emerg(HW_ERR "Corrupted CU MCE info?\n");
+ wrong_f15_mc2_mce:
+ pr_emerg(HW_ERR "Corrupted MC2 MCE info?\n");
}
-static void amd_decode_ls_mce(struct mce *m)
+static void decode_mc3_mce(struct mce *m)
{
u16 ec = EC(m->status);
u8 xec = XEC(m->status, xec_mask);
if (boot_cpu_data.x86 >= 0x14) {
- pr_emerg("You shouldn't be seeing an LS MCE on this cpu family,"
+ pr_emerg("You shouldn't be seeing MC3 MCE on this cpu family,"
" please report on LKML.\n");
return;
}
- pr_emerg(HW_ERR "Load Store Error");
+ pr_emerg(HW_ERR "MC3 Error");
if (xec == 0x0) {
u8 r4 = R4(ec);
if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR))
- goto wrong_ls_mce;
+ goto wrong_mc3_mce;
pr_cont(" during %s.\n", R4_MSG(ec));
} else
- goto wrong_ls_mce;
+ goto wrong_mc3_mce;
return;
-wrong_ls_mce:
- pr_emerg(HW_ERR "Corrupted LS MCE info?\n");
+ wrong_mc3_mce:
+ pr_emerg(HW_ERR "Corrupted MC3 MCE info?\n");
}
-void amd_decode_nb_mce(struct mce *m)
+static void decode_mc4_mce(struct mce *m)
{
struct cpuinfo_x86 *c = &boot_cpu_data;
int node_id = amd_get_nb_id(m->extcpu);
@@ -518,7 +518,7 @@ void amd_decode_nb_mce(struct mce *m)
u8 xec = XEC(m->status, 0x1f);
u8 offset = 0;
- pr_emerg(HW_ERR "Northbridge Error (node %d): ", node_id);
+ pr_emerg(HW_ERR "MC4 Error (node %d): ", node_id);
switch (xec) {
case 0x0 ... 0xe:
@@ -527,9 +527,9 @@ void amd_decode_nb_mce(struct mce *m)
if (xec == 0x0 || xec == 0x8) {
/* no ECCs on F11h */
if (c->x86 == 0x11)
- goto wrong_nb_mce;
+ goto wrong_mc4_mce;
- pr_cont("%s.\n", nb_mce_desc[xec]);
+ pr_cont("%s.\n", mc4_mce_desc[xec]);
if (nb_bus_decoder)
nb_bus_decoder(node_id, m);
@@ -543,14 +543,14 @@ void amd_decode_nb_mce(struct mce *m)
else if (BUS_ERROR(ec))
pr_cont("DMA Exclusion Vector Table Walk error.\n");
else
- goto wrong_nb_mce;
+ goto wrong_mc4_mce;
return;
case 0x19:
if (boot_cpu_data.x86 == 0x15)
pr_cont("Compute Unit Data Error.\n");
else
- goto wrong_nb_mce;
+ goto wrong_mc4_mce;
return;
case 0x1c ... 0x1f:
@@ -558,46 +558,44 @@ void amd_decode_nb_mce(struct mce *m)
break;
default:
- goto wrong_nb_mce;
+ goto wrong_mc4_mce;
}
- pr_cont("%s.\n", nb_mce_desc[xec - offset]);
+ pr_cont("%s.\n", mc4_mce_desc[xec - offset]);
return;
-wrong_nb_mce:
- pr_emerg(HW_ERR "Corrupted NB MCE info?\n");
+ wrong_mc4_mce:
+ pr_emerg(HW_ERR "Corrupted MC4 MCE info?\n");
}
-EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
-static void amd_decode_fr_mce(struct mce *m)
+static void decode_mc5_mce(struct mce *m)
{
struct cpuinfo_x86 *c = &boot_cpu_data;
u8 xec = XEC(m->status, xec_mask);
if (c->x86 == 0xf || c->x86 == 0x11)
- goto wrong_fr_mce;
+ goto wrong_mc5_mce;
- pr_emerg(HW_ERR "%s Error: ",
- (c->x86 == 0x15 ? "Execution Unit" : "FIROB"));
+ pr_emerg(HW_ERR "MC5 Error: ");
if (xec == 0x0 || xec == 0xc)
- pr_cont("%s.\n", fr_ex_mce_desc[xec]);
+ pr_cont("%s.\n", mc5_mce_desc[xec]);
else if (xec < 0xd)
- pr_cont("%s parity error.\n", fr_ex_mce_desc[xec]);
+ pr_cont("%s parity error.\n", mc5_mce_desc[xec]);
else
- goto wrong_fr_mce;
+ goto wrong_mc5_mce;
return;
-wrong_fr_mce:
- pr_emerg(HW_ERR "Corrupted FR MCE info?\n");
+ wrong_mc5_mce:
+ pr_emerg(HW_ERR "Corrupted MC5 MCE info?\n");
}
-static void amd_decode_fp_mce(struct mce *m)
+static void decode_mc6_mce(struct mce *m)
{
u8 xec = XEC(m->status, xec_mask);
- pr_emerg(HW_ERR "Floating Point Unit Error: ");
+ pr_emerg(HW_ERR "MC6 Error: ");
switch (xec) {
case 0x1:
@@ -621,7 +619,7 @@ static void amd_decode_fp_mce(struct mce *m)
break;
default:
- goto wrong_fp_mce;
+ goto wrong_mc6_mce;
break;
}
@@ -629,8 +627,8 @@ static void amd_decode_fp_mce(struct mce *m)
return;
-wrong_fp_mce:
- pr_emerg(HW_ERR "Corrupted FP MCE info?\n");
+ wrong_mc6_mce:
+ pr_emerg(HW_ERR "Corrupted MC6 MCE info?\n");
}
static inline void amd_decode_err_code(u16 ec)
@@ -669,74 +667,94 @@ static bool amd_filter_mce(struct mce *m)
return false;
}
+static const char *decode_error_status(struct mce *m)
+{
+ if (m->status & MCI_STATUS_UC) {
+ if (m->status & MCI_STATUS_PCC)
+ return "System Fatal error.";
+ if (m->mcgstatus & MCG_STATUS_RIPV)
+ return "Uncorrected, software restartable error.";
+ return "Uncorrected, software containable error.";
+ }
+
+ if (m->status & MCI_STATUS_DEFERRED)
+ return "Deferred error.";
+
+ return "Corrected error, no action required.";
+}
+
int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
{
struct mce *m = (struct mce *)data;
- struct cpuinfo_x86 *c = &boot_cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(m->extcpu);
int ecc;
if (amd_filter_mce(m))
return NOTIFY_STOP;
- pr_emerg(HW_ERR "CPU:%d\tMC%d_STATUS[%s|%s|%s|%s|%s",
- m->extcpu, m->bank,
- ((m->status & MCI_STATUS_OVER) ? "Over" : "-"),
- ((m->status & MCI_STATUS_UC) ? "UE" : "CE"),
- ((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"),
- ((m->status & MCI_STATUS_PCC) ? "PCC" : "-"),
- ((m->status & MCI_STATUS_ADDRV) ? "AddrV" : "-"));
-
- if (c->x86 == 0x15)
- pr_cont("|%s|%s",
- ((m->status & BIT_64(44)) ? "Deferred" : "-"),
- ((m->status & BIT_64(43)) ? "Poison" : "-"));
-
- /* do the two bits[14:13] together */
- ecc = (m->status >> 45) & 0x3;
- if (ecc)
- pr_cont("|%sECC", ((ecc == 2) ? "C" : "U"));
-
- pr_cont("]: 0x%016llx\n", m->status);
-
- if (m->status & MCI_STATUS_ADDRV)
- pr_emerg(HW_ERR "\tMC%d_ADDR: 0x%016llx\n", m->bank, m->addr);
-
switch (m->bank) {
case 0:
- amd_decode_dc_mce(m);
+ decode_mc0_mce(m);
break;
case 1:
- amd_decode_ic_mce(m);
+ decode_mc1_mce(m);
break;
case 2:
if (c->x86 == 0x15)
- amd_decode_cu_mce(m);
+ decode_f15_mc2_mce(m);
else
- amd_decode_bu_mce(m);
+ decode_mc2_mce(m);
break;
case 3:
- amd_decode_ls_mce(m);
+ decode_mc3_mce(m);
break;
case 4:
- amd_decode_nb_mce(m);
+ decode_mc4_mce(m);
break;
case 5:
- amd_decode_fr_mce(m);
+ decode_mc5_mce(m);
break;
case 6:
- amd_decode_fp_mce(m);
+ decode_mc6_mce(m);
break;
default:
break;
}
+ pr_emerg(HW_ERR "Error Status: %s\n", decode_error_status(m));
+
+ pr_emerg(HW_ERR "CPU:%d (%x:%x:%x) MC%d_STATUS[%s|%s|%s|%s|%s",
+ m->extcpu,
+ c->x86, c->x86_model, c->x86_mask,
+ m->bank,
+ ((m->status & MCI_STATUS_OVER) ? "Over" : "-"),
+ ((m->status & MCI_STATUS_UC) ? "UE" : "CE"),
+ ((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"),
+ ((m->status & MCI_STATUS_PCC) ? "PCC" : "-"),
+ ((m->status & MCI_STATUS_ADDRV) ? "AddrV" : "-"));
+
+ if (c->x86 == 0x15)
+ pr_cont("|%s|%s",
+ ((m->status & MCI_STATUS_DEFERRED) ? "Deferred" : "-"),
+ ((m->status & MCI_STATUS_POISON) ? "Poison" : "-"));
+
+ /* do the two bits[14:13] together */
+ ecc = (m->status >> 45) & 0x3;
+ if (ecc)
+ pr_cont("|%sECC", ((ecc == 2) ? "C" : "U"));
+
+ pr_cont("]: 0x%016llx\n", m->status);
+
+ if (m->status & MCI_STATUS_ADDRV)
+ pr_emerg(HW_ERR "MC%d_ADDR: 0x%016llx\n", m->bank, m->addr);
+
amd_decode_err_code(m->status & 0xffff);
return NOTIFY_STOP;
@@ -763,35 +781,35 @@ static int __init mce_amd_init(void)
switch (c->x86) {
case 0xf:
- fam_ops->dc_mce = k8_dc_mce;
- fam_ops->ic_mce = k8_ic_mce;
+ fam_ops->mc0_mce = k8_mc0_mce;
+ fam_ops->mc1_mce = k8_mc1_mce;
break;
case 0x10:
- fam_ops->dc_mce = f10h_dc_mce;
- fam_ops->ic_mce = k8_ic_mce;
+ fam_ops->mc0_mce = f10h_mc0_mce;
+ fam_ops->mc1_mce = k8_mc1_mce;
break;
case 0x11:
- fam_ops->dc_mce = k8_dc_mce;
- fam_ops->ic_mce = k8_ic_mce;
+ fam_ops->mc0_mce = k8_mc0_mce;
+ fam_ops->mc1_mce = k8_mc1_mce;
break;
case 0x12:
- fam_ops->dc_mce = f12h_dc_mce;
- fam_ops->ic_mce = k8_ic_mce;
+ fam_ops->mc0_mce = f12h_mc0_mce;
+ fam_ops->mc1_mce = k8_mc1_mce;
break;
case 0x14:
nb_err_cpumask = 0x3;
- fam_ops->dc_mce = f14h_dc_mce;
- fam_ops->ic_mce = f14h_ic_mce;
+ fam_ops->mc0_mce = f14h_mc0_mce;
+ fam_ops->mc1_mce = f14h_mc1_mce;
break;
case 0x15:
xec_mask = 0x1f;
- fam_ops->dc_mce = f15h_dc_mce;
- fam_ops->ic_mce = f15h_ic_mce;
+ fam_ops->mc0_mce = f15h_mc0_mce;
+ fam_ops->mc1_mce = f15h_mc1_mce;
break;
default:
diff --git a/drivers/edac/mce_amd.h b/drivers/edac/mce_amd.h
index 8c87a5e8705..679679951e2 100644
--- a/drivers/edac/mce_amd.h
+++ b/drivers/edac/mce_amd.h
@@ -29,10 +29,8 @@
#define R4(x) (((x) >> 4) & 0xf)
#define R4_MSG(x) ((R4(x) < 9) ? rrrr_msgs[R4(x)] : "Wrong R4!")
-/*
- * F3x4C bits (MCi_STATUS' high half)
- */
-#define NBSH_ERR_CPU_VAL BIT(24)
+#define MCI_STATUS_DEFERRED BIT_64(44)
+#define MCI_STATUS_POISON BIT_64(43)
enum tt_ids {
TT_INSTR = 0,
@@ -78,14 +76,13 @@ extern const char * const ii_msgs[];
* per-family decoder ops
*/
struct amd_decoder_ops {
- bool (*dc_mce)(u16, u8);
- bool (*ic_mce)(u16, u8);
+ bool (*mc0_mce)(u16, u8);
+ bool (*mc1_mce)(u16, u8);
};
void amd_report_gart_errors(bool);
void amd_register_ecc_decoder(void (*f)(int, struct mce *));
void amd_unregister_ecc_decoder(void (*f)(int, struct mce *));
-void amd_decode_nb_mce(struct mce *);
int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data);
#endif /* _EDAC_MCE_AMD_H */
diff --git a/drivers/edac/mce_amd_inj.c b/drivers/edac/mce_amd_inj.c
index 66b5151c108..2ae78f20cc2 100644
--- a/drivers/edac/mce_amd_inj.c
+++ b/drivers/edac/mce_amd_inj.c
@@ -6,7 +6,7 @@
* This file may be distributed under the terms of the GNU General Public
* License version 2.
*
- * Copyright (c) 2010: Borislav Petkov <borislav.petkov@amd.com>
+ * Copyright (c) 2010: Borislav Petkov <bp@alien8.de>
* Advanced Micro Devices Inc.
*/
@@ -168,6 +168,6 @@ module_init(edac_init_mce_inject);
module_exit(edac_exit_mce_inject);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Borislav Petkov <borislav.petkov@amd.com>");
+MODULE_AUTHOR("Borislav Petkov <bp@alien8.de>");
MODULE_AUTHOR("AMD Inc.");
MODULE_DESCRIPTION("MCE injection facility for testing MCE decoding");
diff --git a/drivers/extcon/extcon-adc-jack.c b/drivers/extcon/extcon-adc-jack.c
index e87196f6d2d..eda2a1aa4ad 100644
--- a/drivers/extcon/extcon-adc-jack.c
+++ b/drivers/extcon/extcon-adc-jack.c
@@ -91,7 +91,7 @@ static irqreturn_t adc_jack_irq_thread(int irq, void *_data)
return IRQ_HANDLED;
}
-static int __devinit adc_jack_probe(struct platform_device *pdev)
+static int adc_jack_probe(struct platform_device *pdev)
{
struct adc_jack_data *data;
struct adc_jack_pdata *pdata = pdev->dev.platform_data;
@@ -175,7 +175,7 @@ out:
return err;
}
-static int __devexit adc_jack_remove(struct platform_device *pdev)
+static int adc_jack_remove(struct platform_device *pdev)
{
struct adc_jack_data *data = platform_get_drvdata(pdev);
@@ -188,7 +188,7 @@ static int __devexit adc_jack_remove(struct platform_device *pdev)
static struct platform_driver adc_jack_driver = {
.probe = adc_jack_probe,
- .remove = __devexit_p(adc_jack_remove),
+ .remove = adc_jack_remove,
.driver = {
.name = "adc-jack",
.owner = THIS_MODULE,
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index cdab9e59829..f10f05d4ee9 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -337,7 +337,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
return IRQ_HANDLED;
}
-static int __devinit arizona_extcon_probe(struct platform_device *pdev)
+static int arizona_extcon_probe(struct platform_device *pdev)
{
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
struct arizona_pdata *pdata;
@@ -517,7 +517,7 @@ err:
return ret;
}
-static int __devexit arizona_extcon_remove(struct platform_device *pdev)
+static int arizona_extcon_remove(struct platform_device *pdev)
{
struct arizona_extcon_info *info = platform_get_drvdata(pdev);
struct arizona *arizona = info->arizona;
@@ -544,7 +544,7 @@ static struct platform_driver arizona_extcon_driver = {
.owner = THIS_MODULE,
},
.probe = arizona_extcon_probe,
- .remove = __devexit_p(arizona_extcon_remove),
+ .remove = arizona_extcon_remove,
};
module_platform_driver(arizona_extcon_driver);
diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c
index 71d3ab7b3d8..1b14bfcdc17 100644
--- a/drivers/extcon/extcon-gpio.c
+++ b/drivers/extcon/extcon-gpio.c
@@ -76,7 +76,7 @@ static ssize_t extcon_gpio_print_state(struct extcon_dev *edev, char *buf)
return -EINVAL;
}
-static int __devinit gpio_extcon_probe(struct platform_device *pdev)
+static int gpio_extcon_probe(struct platform_device *pdev)
{
struct gpio_extcon_platform_data *pdata = pdev->dev.platform_data;
struct gpio_extcon_data *extcon_data;
@@ -137,7 +137,7 @@ err:
return ret;
}
-static int __devexit gpio_extcon_remove(struct platform_device *pdev)
+static int gpio_extcon_remove(struct platform_device *pdev)
{
struct gpio_extcon_data *extcon_data = platform_get_drvdata(pdev);
@@ -150,7 +150,7 @@ static int __devexit gpio_extcon_remove(struct platform_device *pdev)
static struct platform_driver gpio_extcon_driver = {
.probe = gpio_extcon_probe,
- .remove = __devexit_p(gpio_extcon_remove),
+ .remove = gpio_extcon_remove,
.driver = {
.name = "extcon-gpio",
.owner = THIS_MODULE,
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
index a17d0d91ada..b656dfa401a 100644
--- a/drivers/extcon/extcon-max77693.c
+++ b/drivers/extcon/extcon-max77693.c
@@ -648,7 +648,7 @@ out:
return ret;
}
-static int __devinit max77693_muic_probe(struct platform_device *pdev)
+static int max77693_muic_probe(struct platform_device *pdev)
{
struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev);
@@ -774,7 +774,7 @@ err_kfree:
return ret;
}
-static int __devexit max77693_muic_remove(struct platform_device *pdev)
+static int max77693_muic_remove(struct platform_device *pdev)
{
struct max77693_muic_info *info = platform_get_drvdata(pdev);
int i;
@@ -795,7 +795,7 @@ static struct platform_driver max77693_muic_driver = {
.owner = THIS_MODULE,
},
.probe = max77693_muic_probe,
- .remove = __devexit_p(max77693_muic_remove),
+ .remove = max77693_muic_remove,
};
module_platform_driver(max77693_muic_driver);
diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c
index 77b66b0cc8f..bad76f51161 100644
--- a/drivers/extcon/extcon-max8997.c
+++ b/drivers/extcon/extcon-max8997.c
@@ -426,7 +426,7 @@ static void max8997_muic_detect_dev(struct max8997_muic_info *info)
max8997_muic_handle_charger_type(info, chg_type);
}
-static int __devinit max8997_muic_probe(struct platform_device *pdev)
+static int max8997_muic_probe(struct platform_device *pdev)
{
struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent);
struct max8997_platform_data *pdata = dev_get_platdata(max8997->dev);
@@ -508,7 +508,7 @@ err_kfree:
return ret;
}
-static int __devexit max8997_muic_remove(struct platform_device *pdev)
+static int max8997_muic_remove(struct platform_device *pdev)
{
struct max8997_muic_info *info = platform_get_drvdata(pdev);
int i;
@@ -531,7 +531,7 @@ static struct platform_driver max8997_muic_driver = {
.owner = THIS_MODULE,
},
.probe = max8997_muic_probe,
- .remove = __devexit_p(max8997_muic_remove),
+ .remove = max8997_muic_remove,
};
module_platform_driver(max8997_muic_driver);
diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c
index 4ebfb227367..76b2d390f6e 100644
--- a/drivers/firewire/nosy.c
+++ b/drivers/firewire/nosy.c
@@ -529,7 +529,7 @@ remove_card(struct pci_dev *dev)
#define RCV_BUFFER_SIZE (16 * 1024)
-static int __devinit
+static int
add_card(struct pci_dev *dev, const struct pci_device_id *unused)
{
struct pcilynx *lynx;
@@ -683,7 +683,7 @@ fail_disable:
return ret;
}
-static struct pci_device_id pci_table[] __devinitdata = {
+static struct pci_device_id pci_table[] = {
{
.vendor = PCI_VENDOR_ID_TI,
.device = PCI_DEVICE_ID_TI_PCILYNX,
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 834e71d2324..f25610bb314 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -3537,7 +3537,7 @@ static inline void pmac_ohci_on(struct pci_dev *dev) {}
static inline void pmac_ohci_off(struct pci_dev *dev) {}
#endif /* CONFIG_PPC_PMAC */
-static int __devinit pci_probe(struct pci_dev *dev,
+static int pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
struct fw_ohci *ohci;
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 1162d6b3bf8..bb1b392f5cd 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -1546,6 +1546,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
struct sbp2_logical_unit *lu = sdev->hostdata;
sdev->use_10_for_rw = 1;
+ sdev->no_report_opcodes = 1;
+ sdev->no_write_same = 1;
if (sbp2_param_exclusive_login)
sdev->manage_start_stop = 1;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index f11d8e3b404..14a6c2913e4 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -49,6 +49,10 @@ config OF_GPIO
def_bool y
depends on OF
+config GPIO_ACPI
+ def_bool y
+ depends on ACPI
+
config DEBUG_GPIO
bool "Debug GPIO calls"
depends on DEBUG_KERNEL
@@ -86,11 +90,26 @@ config GPIO_DA9052
help
Say yes here to enable the GPIO driver for the DA9052 chip.
+config GPIO_DA9055
+ tristate "Dialog Semiconductor DA9055 GPIO"
+ depends on MFD_DA9055
+ help
+ Say yes here to enable the GPIO driver for the DA9055 chip.
+
+ The Dialog DA9055 PMIC chip has 3 GPIO pins that can be
+ be controller by this driver.
+
+ If driver is built as a module it will be called gpio-da9055.
+
config GPIO_MAX730X
tristate
comment "Memory mapped GPIO drivers:"
+config GPIO_CLPS711X
+ def_bool y
+ depends on ARCH_CLPS711X
+
config GPIO_GENERIC_PLATFORM
tristate "Generic memory-mapped GPIO controller support (MMIO platform device)"
select GPIO_GENERIC
@@ -170,7 +189,7 @@ config GPIO_MXS
config GPIO_PL061
bool "PrimeCell PL061 GPIO support"
- depends on ARM_AMBA
+ depends on ARM && ARM_AMBA
select GENERIC_IRQ_CHIP
help
Say yes here to support the PrimeCell PL061 GPIO device
@@ -181,6 +200,13 @@ config GPIO_PXA
help
Say yes here to support the PXA GPIO device
+config GPIO_SPEAR_SPICS
+ bool "ST SPEAr13xx SPI Chip Select as GPIO support"
+ depends on PLAT_SPEAR
+ select GENERIC_IRQ_CHIP
+ help
+ Say yes here to support ST SPEAr SPI Chip Select as GPIO device
+
config GPIO_STA2X11
bool "STA2x11/ConneXt GPIO support"
depends on MFD_STA2X11
@@ -189,6 +215,14 @@ config GPIO_STA2X11
Say yes here to support the STA2x11/ConneXt GPIO device.
The GPIO module has 128 GPIO pins with alternate functions.
+config GPIO_TS5500
+ tristate "TS-5500 DIO blocks and compatibles"
+ help
+ This driver supports Digital I/O exposed by pin blocks found on some
+ Technologic Systems platforms. It includes, but is not limited to, 3
+ blocks of the TS-5500: DIO1, DIO2 and the LCD port, and the TS-5600
+ LCD port.
+
config GPIO_VT8500
bool "VIA/Wondermedia SoC GPIO Support"
depends on ARCH_VT8500
@@ -466,7 +500,7 @@ config GPIO_ADP5588_IRQ
config GPIO_ADNP
tristate "Avionic Design N-bit GPIO expander"
- depends on I2C && OF
+ depends on I2C && OF_GPIO
help
This option enables support for N GPIOs found on Avionic Design
I2C GPIO expanders. The register space will be extended by powers
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 9aeed670732..76b34468325 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -4,6 +4,7 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
obj-$(CONFIG_GPIOLIB) += gpiolib.o devres.o
obj-$(CONFIG_OF_GPIO) += gpiolib-of.o
+obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o
# Device drivers. Generally keep list sorted alphabetically
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
@@ -16,8 +17,10 @@ obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o
obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o
obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
+obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o
obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o
+obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o
obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o
obj-$(CONFIG_GPIO_EM) += gpio-em.o
obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
@@ -57,6 +60,7 @@ obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o
obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o
+obj-$(CONFIG_GPIO_SPEAR_SPICS) += gpio-spear-spics.o
obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o
obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o
@@ -68,6 +72,7 @@ obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o
obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o
obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o
+obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o
obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o
obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o
diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c
index f05e54258ff..464be961f60 100644
--- a/drivers/gpio/gpio-74x164.c
+++ b/drivers/gpio/gpio-74x164.c
@@ -105,7 +105,7 @@ static int gen_74x164_direction_output(struct gpio_chip *gc,
return 0;
}
-static int __devinit gen_74x164_probe(struct spi_device *spi)
+static int gen_74x164_probe(struct spi_device *spi)
{
struct gen_74x164_chip *chip;
struct gen_74x164_chip_platform_data *pdata;
@@ -181,7 +181,7 @@ exit_destroy:
return ret;
}
-static int __devexit gen_74x164_remove(struct spi_device *spi)
+static int gen_74x164_remove(struct spi_device *spi)
{
struct gen_74x164_chip *chip;
int ret;
@@ -215,7 +215,7 @@ static struct spi_driver gen_74x164_driver = {
.of_match_table = of_match_ptr(gen_74x164_dt_ids),
},
.probe = gen_74x164_probe,
- .remove = __devexit_p(gen_74x164_remove),
+ .remove = gen_74x164_remove,
};
module_spi_driver(gen_74x164_driver);
diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c
index 050c05d9189..983ad425f0a 100644
--- a/drivers/gpio/gpio-ab8500.c
+++ b/drivers/gpio/gpio-ab8500.c
@@ -402,7 +402,7 @@ static void ab8500_gpio_irq_remove(struct ab8500_gpio *ab8500_gpio)
}
}
-static int __devinit ab8500_gpio_probe(struct platform_device *pdev)
+static int ab8500_gpio_probe(struct platform_device *pdev)
{
struct ab8500_platform_data *ab8500_pdata =
dev_get_platdata(pdev->dev.parent);
@@ -474,7 +474,7 @@ out_free:
* ab8500_gpio_remove() - remove Ab8500-gpio driver
* @pdev : Platform device registered
*/
-static int __devexit ab8500_gpio_remove(struct platform_device *pdev)
+static int ab8500_gpio_remove(struct platform_device *pdev)
{
struct ab8500_gpio *ab8500_gpio = platform_get_drvdata(pdev);
int ret;
@@ -499,7 +499,7 @@ static struct platform_driver ab8500_gpio_driver = {
.owner = THIS_MODULE,
},
.probe = ab8500_gpio_probe,
- .remove = __devexit_p(ab8500_gpio_remove),
+ .remove = ab8500_gpio_remove,
};
static int __init ab8500_gpio_init(void)
diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c
index 3df88336415..e60567fc507 100644
--- a/drivers/gpio/gpio-adnp.c
+++ b/drivers/gpio/gpio-adnp.c
@@ -516,7 +516,7 @@ static void adnp_irq_teardown(struct adnp *adnp)
irq_domain_remove(adnp->domain);
}
-static __devinit int adnp_i2c_probe(struct i2c_client *client,
+static int adnp_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device_node *np = client->dev.of_node;
@@ -563,7 +563,7 @@ teardown:
return err;
}
-static __devexit int adnp_i2c_remove(struct i2c_client *client)
+static int adnp_i2c_remove(struct i2c_client *client)
{
struct adnp *adnp = i2c_get_clientdata(client);
struct device_node *np = client->dev.of_node;
@@ -582,13 +582,13 @@ static __devexit int adnp_i2c_remove(struct i2c_client *client)
return 0;
}
-static const struct i2c_device_id adnp_i2c_id[] __devinitconst = {
+static const struct i2c_device_id adnp_i2c_id[] = {
{ "gpio-adnp" },
{ },
};
MODULE_DEVICE_TABLE(i2c, adnp_i2c_id);
-static const struct of_device_id adnp_of_match[] __devinitconst = {
+static const struct of_device_id adnp_of_match[] = {
{ .compatible = "ad,gpio-adnp", },
{ },
};
@@ -601,7 +601,7 @@ static struct i2c_driver adnp_i2c_driver = {
.of_match_table = of_match_ptr(adnp_of_match),
},
.probe = adnp_i2c_probe,
- .remove = __devexit_p(adnp_i2c_remove),
+ .remove = adnp_i2c_remove,
.id_table = adnp_i2c_id,
};
module_i2c_driver(adnp_i2c_driver);
diff --git a/drivers/gpio/gpio-adp5520.c b/drivers/gpio/gpio-adp5520.c
index 2f263cc3256..8afa95f831b 100644
--- a/drivers/gpio/gpio-adp5520.c
+++ b/drivers/gpio/gpio-adp5520.c
@@ -87,7 +87,7 @@ static int adp5520_gpio_direction_output(struct gpio_chip *chip,
return ret;
}
-static int __devinit adp5520_gpio_probe(struct platform_device *pdev)
+static int adp5520_gpio_probe(struct platform_device *pdev)
{
struct adp5520_gpio_platform_data *pdata = pdev->dev.platform_data;
struct adp5520_gpio *dev;
@@ -167,7 +167,7 @@ err:
return ret;
}
-static int __devexit adp5520_gpio_remove(struct platform_device *pdev)
+static int adp5520_gpio_remove(struct platform_device *pdev)
{
struct adp5520_gpio *dev;
int ret;
@@ -190,7 +190,7 @@ static struct platform_driver adp5520_gpio_driver = {
.owner = THIS_MODULE,
},
.probe = adp5520_gpio_probe,
- .remove = __devexit_p(adp5520_gpio_remove),
+ .remove = adp5520_gpio_remove,
};
module_platform_driver(adp5520_gpio_driver);
diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/gpio-adp5588.c
index eeedad42913..2ba56987db0 100644
--- a/drivers/gpio/gpio-adp5588.c
+++ b/drivers/gpio/gpio-adp5588.c
@@ -346,7 +346,7 @@ static void adp5588_irq_teardown(struct adp5588_gpio *dev)
}
#endif /* CONFIG_GPIO_ADP5588_IRQ */
-static int __devinit adp5588_gpio_probe(struct i2c_client *client,
+static int adp5588_gpio_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adp5588_gpio_platform_data *pdata = client->dev.platform_data;
@@ -438,7 +438,7 @@ err:
return ret;
}
-static int __devexit adp5588_gpio_remove(struct i2c_client *client)
+static int adp5588_gpio_remove(struct i2c_client *client)
{
struct adp5588_gpio_platform_data *pdata = client->dev.platform_data;
struct adp5588_gpio *dev = i2c_get_clientdata(client);
@@ -479,7 +479,7 @@ static struct i2c_driver adp5588_gpio_driver = {
.name = DRV_NAME,
},
.probe = adp5588_gpio_probe,
- .remove = __devexit_p(adp5588_gpio_remove),
+ .remove = adp5588_gpio_remove,
.id_table = adp5588_gpio_id,
};
diff --git a/drivers/gpio/gpio-arizona.c b/drivers/gpio/gpio-arizona.c
index 8740d2eb06f..0ea853f68db 100644
--- a/drivers/gpio/gpio-arizona.c
+++ b/drivers/gpio/gpio-arizona.c
@@ -94,7 +94,7 @@ static struct gpio_chip template_chip = {
.can_sleep = 1,
};
-static int __devinit arizona_gpio_probe(struct platform_device *pdev)
+static int arizona_gpio_probe(struct platform_device *pdev)
{
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
struct arizona_pdata *pdata = arizona->dev->platform_data;
@@ -141,7 +141,7 @@ err:
return ret;
}
-static int __devexit arizona_gpio_remove(struct platform_device *pdev)
+static int arizona_gpio_remove(struct platform_device *pdev)
{
struct arizona_gpio *arizona_gpio = platform_get_drvdata(pdev);
@@ -152,7 +152,7 @@ static struct platform_driver arizona_gpio_driver = {
.driver.name = "arizona-gpio",
.driver.owner = THIS_MODULE,
.probe = arizona_gpio_probe,
- .remove = __devexit_p(arizona_gpio_remove),
+ .remove = arizona_gpio_remove,
};
module_platform_driver(arizona_gpio_driver);
diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c
new file mode 100644
index 00000000000..ce63b75b13f
--- /dev/null
+++ b/drivers/gpio/gpio-clps711x.c
@@ -0,0 +1,199 @@
+/*
+ * CLPS711X GPIO driver
+ *
+ * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+
+#define CLPS711X_GPIO_PORTS 5
+#define CLPS711X_GPIO_NAME "gpio-clps711x"
+
+struct clps711x_gpio {
+ struct gpio_chip chip[CLPS711X_GPIO_PORTS];
+ spinlock_t lock;
+};
+
+static void __iomem *clps711x_ports[] = {
+ CLPS711X_VIRT_BASE + PADR,
+ CLPS711X_VIRT_BASE + PBDR,
+ CLPS711X_VIRT_BASE + PCDR,
+ CLPS711X_VIRT_BASE + PDDR,
+ CLPS711X_VIRT_BASE + PEDR,
+};
+
+static void __iomem *clps711x_pdirs[] = {
+ CLPS711X_VIRT_BASE + PADDR,
+ CLPS711X_VIRT_BASE + PBDDR,
+ CLPS711X_VIRT_BASE + PCDDR,
+ CLPS711X_VIRT_BASE + PDDDR,
+ CLPS711X_VIRT_BASE + PEDDR,
+};
+
+#define clps711x_port(x) clps711x_ports[x->base / 8]
+#define clps711x_pdir(x) clps711x_pdirs[x->base / 8]
+
+static int gpio_clps711x_get(struct gpio_chip *chip, unsigned offset)
+{
+ return !!(readb(clps711x_port(chip)) & (1 << offset));
+}
+
+static void gpio_clps711x_set(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ int tmp;
+ unsigned long flags;
+ struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
+
+ spin_lock_irqsave(&gpio->lock, flags);
+ tmp = readb(clps711x_port(chip)) & ~(1 << offset);
+ if (value)
+ tmp |= 1 << offset;
+ writeb(tmp, clps711x_port(chip));
+ spin_unlock_irqrestore(&gpio->lock, flags);
+}
+
+static int gpio_clps711x_dir_in(struct gpio_chip *chip, unsigned offset)
+{
+ int tmp;
+ unsigned long flags;
+ struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
+
+ spin_lock_irqsave(&gpio->lock, flags);
+ tmp = readb(clps711x_pdir(chip)) & ~(1 << offset);
+ writeb(tmp, clps711x_pdir(chip));
+ spin_unlock_irqrestore(&gpio->lock, flags);
+
+ return 0;
+}
+
+static int gpio_clps711x_dir_out(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ int tmp;
+ unsigned long flags;
+ struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
+
+ spin_lock_irqsave(&gpio->lock, flags);
+ tmp = readb(clps711x_pdir(chip)) | (1 << offset);
+ writeb(tmp, clps711x_pdir(chip));
+ tmp = readb(clps711x_port(chip)) & ~(1 << offset);
+ if (value)
+ tmp |= 1 << offset;
+ writeb(tmp, clps711x_port(chip));
+ spin_unlock_irqrestore(&gpio->lock, flags);
+
+ return 0;
+}
+
+static int gpio_clps711x_dir_in_inv(struct gpio_chip *chip, unsigned offset)
+{
+ int tmp;
+ unsigned long flags;
+ struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
+
+ spin_lock_irqsave(&gpio->lock, flags);
+ tmp = readb(clps711x_pdir(chip)) | (1 << offset);
+ writeb(tmp, clps711x_pdir(chip));
+ spin_unlock_irqrestore(&gpio->lock, flags);
+
+ return 0;
+}
+
+static int gpio_clps711x_dir_out_inv(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ int tmp;
+ unsigned long flags;
+ struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
+
+ spin_lock_irqsave(&gpio->lock, flags);
+ tmp = readb(clps711x_pdir(chip)) & ~(1 << offset);
+ writeb(tmp, clps711x_pdir(chip));
+ tmp = readb(clps711x_port(chip)) & ~(1 << offset);
+ if (value)
+ tmp |= 1 << offset;
+ writeb(tmp, clps711x_port(chip));
+ spin_unlock_irqrestore(&gpio->lock, flags);
+
+ return 0;
+}
+
+static struct {
+ char *name;
+ int nr;
+ int inv_dir;
+} clps711x_gpio_ports[] __initconst = {
+ { "PORTA", 8, 0, },
+ { "PORTB", 8, 0, },
+ { "PORTC", 8, 0, },
+ { "PORTD", 8, 1, },
+ { "PORTE", 3, 0, },
+};
+
+static int __init gpio_clps711x_init(void)
+{
+ int i;
+ struct platform_device *pdev;
+ struct clps711x_gpio *gpio;
+
+ pdev = platform_device_alloc(CLPS711X_GPIO_NAME, 0);
+ if (!pdev) {
+ pr_err("Cannot create platform device: %s\n",
+ CLPS711X_GPIO_NAME);
+ return -ENOMEM;
+ }
+
+ platform_device_add(pdev);
+
+ gpio = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_gpio),
+ GFP_KERNEL);
+ if (!gpio) {
+ dev_err(&pdev->dev, "GPIO allocating memory error\n");
+ platform_device_unregister(pdev);
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, gpio);
+
+ spin_lock_init(&gpio->lock);
+
+ for (i = 0; i < CLPS711X_GPIO_PORTS; i++) {
+ gpio->chip[i].owner = THIS_MODULE;
+ gpio->chip[i].dev = &pdev->dev;
+ gpio->chip[i].label = clps711x_gpio_ports[i].name;
+ gpio->chip[i].base = i * 8;
+ gpio->chip[i].ngpio = clps711x_gpio_ports[i].nr;
+ gpio->chip[i].get = gpio_clps711x_get;
+ gpio->chip[i].set = gpio_clps711x_set;
+ if (!clps711x_gpio_ports[i].inv_dir) {
+ gpio->chip[i].direction_input = gpio_clps711x_dir_in;
+ gpio->chip[i].direction_output = gpio_clps711x_dir_out;
+ } else {
+ gpio->chip[i].direction_input = gpio_clps711x_dir_in_inv;
+ gpio->chip[i].direction_output = gpio_clps711x_dir_out_inv;
+ }
+ WARN_ON(gpiochip_add(&gpio->chip[i]));
+ }
+
+ dev_info(&pdev->dev, "GPIO driver initialized\n");
+
+ return 0;
+}
+arch_initcall(gpio_clps711x_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
+MODULE_DESCRIPTION("CLPS711X GPIO driver");
diff --git a/drivers/gpio/gpio-cs5535.c b/drivers/gpio/gpio-cs5535.c
index 19eda1bbe34..c0a3aeba6f2 100644
--- a/drivers/gpio/gpio-cs5535.c
+++ b/drivers/gpio/gpio-cs5535.c
@@ -300,7 +300,7 @@ static struct cs5535_gpio_chip cs5535_gpio_chip = {
},
};
-static int __devinit cs5535_gpio_probe(struct platform_device *pdev)
+static int cs5535_gpio_probe(struct platform_device *pdev)
{
struct resource *res;
int err = -EIO;
@@ -355,7 +355,7 @@ done:
return err;
}
-static int __devexit cs5535_gpio_remove(struct platform_device *pdev)
+static int cs5535_gpio_remove(struct platform_device *pdev)
{
struct resource *r;
int err;
@@ -378,7 +378,7 @@ static struct platform_driver cs5535_gpio_driver = {
.owner = THIS_MODULE,
},
.probe = cs5535_gpio_probe,
- .remove = __devexit_p(cs5535_gpio_remove),
+ .remove = cs5535_gpio_remove,
};
module_platform_driver(cs5535_gpio_driver);
diff --git a/drivers/gpio/gpio-da9052.c b/drivers/gpio/gpio-da9052.c
index 24b8c297404..a05aacd2777 100644
--- a/drivers/gpio/gpio-da9052.c
+++ b/drivers/gpio/gpio-da9052.c
@@ -188,7 +188,7 @@ static int da9052_gpio_to_irq(struct gpio_chip *gc, u32 offset)
return da9052->irq_base + DA9052_IRQ_GPI0 + offset;
}
-static struct gpio_chip reference_gp __devinitdata = {
+static struct gpio_chip reference_gp = {
.label = "da9052-gpio",
.owner = THIS_MODULE,
.get = da9052_gpio_get,
@@ -201,7 +201,7 @@ static struct gpio_chip reference_gp __devinitdata = {
.base = -1,
};
-static int __devinit da9052_gpio_probe(struct platform_device *pdev)
+static int da9052_gpio_probe(struct platform_device *pdev)
{
struct da9052_gpio *gpio;
struct da9052_pdata *pdata;
@@ -229,7 +229,7 @@ static int __devinit da9052_gpio_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit da9052_gpio_remove(struct platform_device *pdev)
+static int da9052_gpio_remove(struct platform_device *pdev)
{
struct da9052_gpio *gpio = platform_get_drvdata(pdev);
@@ -238,7 +238,7 @@ static int __devexit da9052_gpio_remove(struct platform_device *pdev)
static struct platform_driver da9052_gpio_driver = {
.probe = da9052_gpio_probe,
- .remove = __devexit_p(da9052_gpio_remove),
+ .remove = da9052_gpio_remove,
.driver = {
.name = "da9052-gpio",
.owner = THIS_MODULE,
diff --git a/drivers/gpio/gpio-da9055.c b/drivers/gpio/gpio-da9055.c
new file mode 100644
index 00000000000..55d83c7d9c7
--- /dev/null
+++ b/drivers/gpio/gpio-da9055.c
@@ -0,0 +1,204 @@
+/*
+ * GPIO Driver for Dialog DA9055 PMICs.
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.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/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <linux/mfd/da9055/core.h>
+#include <linux/mfd/da9055/reg.h>
+#include <linux/mfd/da9055/pdata.h>
+
+#define DA9055_VDD_IO 0x0
+#define DA9055_PUSH_PULL 0x3
+#define DA9055_ACT_LOW 0x0
+#define DA9055_GPI 0x1
+#define DA9055_PORT_MASK 0x3
+#define DA9055_PORT_SHIFT(offset) (4 * (offset % 2))
+
+#define DA9055_INPUT DA9055_GPI
+#define DA9055_OUTPUT DA9055_PUSH_PULL
+#define DA9055_IRQ_GPI0 3
+
+struct da9055_gpio {
+ struct da9055 *da9055;
+ struct gpio_chip gp;
+};
+
+static inline struct da9055_gpio *to_da9055_gpio(struct gpio_chip *chip)
+{
+ return container_of(chip, struct da9055_gpio, gp);
+}
+
+static int da9055_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+ struct da9055_gpio *gpio = to_da9055_gpio(gc);
+ int gpio_direction = 0;
+ int ret;
+
+ /* Get GPIO direction */
+ ret = da9055_reg_read(gpio->da9055, (offset >> 1) + DA9055_REG_GPIO0_1);
+ if (ret < 0)
+ return ret;
+
+ gpio_direction = ret & (DA9055_PORT_MASK) << DA9055_PORT_SHIFT(offset);
+ gpio_direction >>= DA9055_PORT_SHIFT(offset);
+ switch (gpio_direction) {
+ case DA9055_INPUT:
+ ret = da9055_reg_read(gpio->da9055, DA9055_REG_STATUS_B);
+ if (ret < 0)
+ return ret;
+ break;
+ case DA9055_OUTPUT:
+ ret = da9055_reg_read(gpio->da9055, DA9055_REG_GPIO_MODE0_2);
+ if (ret < 0)
+ return ret;
+ }
+
+ return ret & (1 << offset);
+
+}
+
+static void da9055_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+ struct da9055_gpio *gpio = to_da9055_gpio(gc);
+
+ da9055_reg_update(gpio->da9055,
+ DA9055_REG_GPIO_MODE0_2,
+ 1 << offset,
+ value << offset);
+}
+
+static int da9055_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+ struct da9055_gpio *gpio = to_da9055_gpio(gc);
+ unsigned char reg_byte;
+
+ reg_byte = (DA9055_ACT_LOW | DA9055_GPI)
+ << DA9055_PORT_SHIFT(offset);
+
+ return da9055_reg_update(gpio->da9055, (offset >> 1) +
+ DA9055_REG_GPIO0_1,
+ DA9055_PORT_MASK <<
+ DA9055_PORT_SHIFT(offset),
+ reg_byte);
+}
+
+static int da9055_gpio_direction_output(struct gpio_chip *gc,
+ unsigned offset, int value)
+{
+ struct da9055_gpio *gpio = to_da9055_gpio(gc);
+ unsigned char reg_byte;
+ int ret;
+
+ reg_byte = (DA9055_VDD_IO | DA9055_PUSH_PULL)
+ << DA9055_PORT_SHIFT(offset);
+
+ ret = da9055_reg_update(gpio->da9055, (offset >> 1) +
+ DA9055_REG_GPIO0_1,
+ DA9055_PORT_MASK <<
+ DA9055_PORT_SHIFT(offset),
+ reg_byte);
+ if (ret < 0)
+ return ret;
+
+ da9055_gpio_set(gc, offset, value);
+
+ return 0;
+}
+
+static int da9055_gpio_to_irq(struct gpio_chip *gc, u32 offset)
+{
+ struct da9055_gpio *gpio = to_da9055_gpio(gc);
+ struct da9055 *da9055 = gpio->da9055;
+
+ return regmap_irq_get_virq(da9055->irq_data,
+ DA9055_IRQ_GPI0 + offset);
+}
+
+static struct gpio_chip reference_gp __devinitdata = {
+ .label = "da9055-gpio",
+ .owner = THIS_MODULE,
+ .get = da9055_gpio_get,
+ .set = da9055_gpio_set,
+ .direction_input = da9055_gpio_direction_input,
+ .direction_output = da9055_gpio_direction_output,
+ .to_irq = da9055_gpio_to_irq,
+ .can_sleep = 1,
+ .ngpio = 3,
+ .base = -1,
+};
+
+static int __devinit da9055_gpio_probe(struct platform_device *pdev)
+{
+ struct da9055_gpio *gpio;
+ struct da9055_pdata *pdata;
+ int ret;
+
+ gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
+ if (gpio == NULL)
+ return -ENOMEM;
+
+ gpio->da9055 = dev_get_drvdata(pdev->dev.parent);
+ pdata = gpio->da9055->dev->platform_data;
+
+ gpio->gp = reference_gp;
+ if (pdata && pdata->gpio_base)
+ gpio->gp.base = pdata->gpio_base;
+
+ ret = gpiochip_add(&gpio->gp);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
+ goto err_mem;
+ }
+
+ platform_set_drvdata(pdev, gpio);
+
+ return 0;
+
+err_mem:
+ return ret;
+}
+
+static int __devexit da9055_gpio_remove(struct platform_device *pdev)
+{
+ struct da9055_gpio *gpio = platform_get_drvdata(pdev);
+
+ return gpiochip_remove(&gpio->gp);
+}
+
+static struct platform_driver da9055_gpio_driver = {
+ .probe = da9055_gpio_probe,
+ .remove = __devexit_p(da9055_gpio_remove),
+ .driver = {
+ .name = "da9055-gpio",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init da9055_gpio_init(void)
+{
+ return platform_driver_register(&da9055_gpio_driver);
+}
+subsys_initcall(da9055_gpio_init);
+
+static void __exit da9055_gpio_exit(void)
+{
+ platform_driver_unregister(&da9055_gpio_driver);
+}
+module_exit(da9055_gpio_exit);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("DA9055 GPIO Device Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9055-gpio");
diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c
index efb4c2d0d13..bdc8302e711 100644
--- a/drivers/gpio/gpio-em.c
+++ b/drivers/gpio/gpio-em.c
@@ -35,7 +35,6 @@
struct em_gio_priv {
void __iomem *base0;
void __iomem *base1;
- unsigned int irq_base;
spinlock_t sense_lock;
struct platform_device *pdev;
struct gpio_chip gpio_chip;
@@ -214,7 +213,7 @@ static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset,
static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset)
{
- return irq_find_mapping(gpio_to_priv(chip)->irq_domain, offset);
+ return irq_create_mapping(gpio_to_priv(chip)->irq_domain, offset);
}
static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq,
@@ -234,41 +233,7 @@ static struct irq_domain_ops em_gio_irq_domain_ops = {
.map = em_gio_irq_domain_map,
};
-static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p)
-{
- struct platform_device *pdev = p->pdev;
- struct gpio_em_config *pdata = pdev->dev.platform_data;
-
- p->irq_base = irq_alloc_descs(pdata->irq_base, 0,
- pdata->number_of_pins, numa_node_id());
- if (p->irq_base < 0) {
- dev_err(&pdev->dev, "cannot get irq_desc\n");
- return p->irq_base;
- }
- pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n",
- pdata->gpio_base, pdata->number_of_pins, p->irq_base);
-
- p->irq_domain = irq_domain_add_legacy(pdev->dev.of_node,
- pdata->number_of_pins,
- p->irq_base, 0,
- &em_gio_irq_domain_ops, p);
- if (!p->irq_domain) {
- irq_free_descs(p->irq_base, pdata->number_of_pins);
- return -ENXIO;
- }
-
- return 0;
-}
-
-static void em_gio_irq_domain_cleanup(struct em_gio_priv *p)
-{
- struct gpio_em_config *pdata = p->pdev->dev.platform_data;
-
- irq_free_descs(p->irq_base, pdata->number_of_pins);
- /* FIXME: irq domain wants to be freed! */
-}
-
-static int __devinit em_gio_probe(struct platform_device *pdev)
+static int em_gio_probe(struct platform_device *pdev)
{
struct gpio_em_config *pdata = pdev->dev.platform_data;
struct em_gio_priv *p;
@@ -334,8 +299,11 @@ static int __devinit em_gio_probe(struct platform_device *pdev)
irq_chip->irq_set_type = em_gio_irq_set_type;
irq_chip->flags = IRQCHIP_SKIP_SET_WAKE;
- ret = em_gio_irq_domain_init(p);
- if (ret) {
+ p->irq_domain = irq_domain_add_linear(pdev->dev.of_node,
+ pdata->number_of_pins,
+ &em_gio_irq_domain_ops, p);
+ if (!p->irq_domain) {
+ ret = -ENXIO;
dev_err(&pdev->dev, "cannot initialize irq domain\n");
goto err3;
}
@@ -364,7 +332,7 @@ err6:
err5:
free_irq(irq[0]->start, pdev);
err4:
- em_gio_irq_domain_cleanup(p);
+ irq_domain_remove(p->irq_domain);
err3:
iounmap(p->base1);
err2:
@@ -375,7 +343,7 @@ err0:
return ret;
}
-static int __devexit em_gio_remove(struct platform_device *pdev)
+static int em_gio_remove(struct platform_device *pdev)
{
struct em_gio_priv *p = platform_get_drvdata(pdev);
struct resource *irq[2];
@@ -390,7 +358,7 @@ static int __devexit em_gio_remove(struct platform_device *pdev)
free_irq(irq[1]->start, pdev);
free_irq(irq[0]->start, pdev);
- em_gio_irq_domain_cleanup(p);
+ irq_domain_remove(p->irq_domain);
iounmap(p->base1);
iounmap(p->base0);
kfree(p);
@@ -399,7 +367,7 @@ static int __devexit em_gio_remove(struct platform_device *pdev)
static struct platform_driver em_gio_device_driver = {
.probe = em_gio_probe,
- .remove = __devexit_p(em_gio_remove),
+ .remove = em_gio_remove,
.driver = {
.name = "em_gio",
}
diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 9fe5b8fe9be..56b98eebe1f 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -340,7 +340,7 @@ static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev,
return gpiochip_add(&bgc->gc);
}
-static int __devinit ep93xx_gpio_probe(struct platform_device *pdev)
+static int ep93xx_gpio_probe(struct platform_device *pdev)
{
struct ep93xx_gpio *ep93xx_gpio;
struct resource *res;
diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c
index 82e2e4fe599..05fcc0f247c 100644
--- a/drivers/gpio/gpio-generic.c
+++ b/drivers/gpio/gpio-generic.c
@@ -444,7 +444,7 @@ static void __iomem *bgpio_map(struct platform_device *pdev,
return ret;
}
-static int __devinit bgpio_pdev_probe(struct platform_device *pdev)
+static int bgpio_pdev_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct resource *r;
@@ -507,7 +507,7 @@ static int __devinit bgpio_pdev_probe(struct platform_device *pdev)
return gpiochip_add(&bgc->gc);
}
-static int __devexit bgpio_pdev_remove(struct platform_device *pdev)
+static int bgpio_pdev_remove(struct platform_device *pdev)
{
struct bgpio_chip *bgc = platform_get_drvdata(pdev);
@@ -527,7 +527,7 @@ static struct platform_driver bgpio_driver = {
},
.id_table = bgpio_id_table,
.probe = bgpio_pdev_probe,
- .remove = __devexit_p(bgpio_pdev_remove),
+ .remove = bgpio_pdev_remove,
};
module_platform_driver(bgpio_driver);
diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c
index d4d61796669..6cc87ac8e01 100644
--- a/drivers/gpio/gpio-ich.c
+++ b/drivers/gpio/gpio-ich.c
@@ -238,7 +238,7 @@ static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val)
ichx_write_bit(GPIO_LVL, nr, val, 0);
}
-static void __devinit ichx_gpiolib_setup(struct gpio_chip *chip)
+static void ichx_gpiolib_setup(struct gpio_chip *chip)
{
chip->owner = THIS_MODULE;
chip->label = DRV_NAME;
@@ -313,7 +313,7 @@ static struct ichx_desc intel5_desc = {
.ngpio = 76,
};
-static int __devinit ichx_gpio_request_regions(struct resource *res_base,
+static int ichx_gpio_request_regions(struct resource *res_base,
const char *name, u8 use_gpio)
{
int i;
@@ -353,7 +353,7 @@ static void ichx_gpio_release_regions(struct resource *res_base, u8 use_gpio)
}
}
-static int __devinit ichx_gpio_probe(struct platform_device *pdev)
+static int ichx_gpio_probe(struct platform_device *pdev)
{
struct resource *res_base, *res_pm;
int err;
@@ -442,7 +442,7 @@ add_err:
return err;
}
-static int __devexit ichx_gpio_remove(struct platform_device *pdev)
+static int ichx_gpio_remove(struct platform_device *pdev)
{
int err;
@@ -467,7 +467,7 @@ static struct platform_driver ichx_gpio_driver = {
.name = DRV_NAME,
},
.probe = ichx_gpio_probe,
- .remove = __devexit_p(ichx_gpio_remove),
+ .remove = ichx_gpio_remove,
};
module_platform_driver(ichx_gpio_driver);
diff --git a/drivers/gpio/gpio-janz-ttl.c b/drivers/gpio/gpio-janz-ttl.c
index f2f000dd70b..7d0a04169a3 100644
--- a/drivers/gpio/gpio-janz-ttl.c
+++ b/drivers/gpio/gpio-janz-ttl.c
@@ -108,13 +108,13 @@ static void ttl_set_value(struct gpio_chip *gpio, unsigned offset, int value)
spin_unlock(&mod->lock);
}
-static void __devinit ttl_write_reg(struct ttl_module *mod, u8 reg, u16 val)
+static void ttl_write_reg(struct ttl_module *mod, u8 reg, u16 val)
{
iowrite16be(reg, &mod->regs->control);
iowrite16be(val, &mod->regs->control);
}
-static void __devinit ttl_setup_device(struct ttl_module *mod)
+static void ttl_setup_device(struct ttl_module *mod)
{
/* reset the device to a known state */
iowrite16be(0x0000, &mod->regs->control);
@@ -140,7 +140,7 @@ static void __devinit ttl_setup_device(struct ttl_module *mod)
ttl_write_reg(mod, MASTER_CONF_CTL, CONF_PAE | CONF_PBE | CONF_PCE);
}
-static int __devinit ttl_probe(struct platform_device *pdev)
+static int ttl_probe(struct platform_device *pdev)
{
struct janz_platform_data *pdata;
struct device *dev = &pdev->dev;
@@ -211,7 +211,7 @@ out_return:
return ret;
}
-static int __devexit ttl_remove(struct platform_device *pdev)
+static int ttl_remove(struct platform_device *pdev)
{
struct ttl_module *mod = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev;
@@ -234,7 +234,7 @@ static struct platform_driver ttl_driver = {
.owner = THIS_MODULE,
},
.probe = ttl_probe,
- .remove = __devexit_p(ttl_remove),
+ .remove = ttl_remove,
};
module_platform_driver(ttl_driver);
diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c
index 202a99207b7..e77b2b3e94a 100644
--- a/drivers/gpio/gpio-langwell.c
+++ b/drivers/gpio/gpio-langwell.c
@@ -332,7 +332,7 @@ static const struct dev_pm_ops lnw_gpio_pm_ops = {
.runtime_idle = lnw_gpio_runtime_idle,
};
-static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
+static int lnw_gpio_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
void *base;
@@ -435,7 +435,7 @@ static struct pci_driver lnw_gpio_driver = {
};
-static int __devinit wp_gpio_probe(struct platform_device *pdev)
+static int wp_gpio_probe(struct platform_device *pdev)
{
struct lnw_gpio *lnw;
struct gpio_chip *gc;
@@ -484,7 +484,7 @@ err_kmalloc:
return retval;
}
-static int __devexit wp_gpio_remove(struct platform_device *pdev)
+static int wp_gpio_remove(struct platform_device *pdev)
{
struct lnw_gpio *lnw = platform_get_drvdata(pdev);
int err;
@@ -499,7 +499,7 @@ static int __devexit wp_gpio_remove(struct platform_device *pdev)
static struct platform_driver wp_gpio_driver = {
.probe = wp_gpio_probe,
- .remove = __devexit_p(wp_gpio_remove),
+ .remove = wp_gpio_remove,
.driver = {
.name = "wp_gpio",
.owner = THIS_MODULE,
diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c
index 3644e0dcb3d..36d7dee07b2 100644
--- a/drivers/gpio/gpio-lpc32xx.c
+++ b/drivers/gpio/gpio-lpc32xx.c
@@ -542,7 +542,7 @@ static int lpc32xx_of_xlate(struct gpio_chip *gc,
return gpiospec->args[1];
}
-static int __devinit lpc32xx_gpio_probe(struct platform_device *pdev)
+static int lpc32xx_gpio_probe(struct platform_device *pdev)
{
int i;
@@ -559,7 +559,7 @@ static int __devinit lpc32xx_gpio_probe(struct platform_device *pdev)
}
#ifdef CONFIG_OF
-static struct of_device_id lpc32xx_gpio_of_match[] __devinitdata = {
+static struct of_device_id lpc32xx_gpio_of_match[] = {
{ .compatible = "nxp,lpc3220-gpio", },
{ },
};
diff --git a/drivers/gpio/gpio-max7300.c b/drivers/gpio/gpio-max7300.c
index a5ca0ab1b37..4b6b9a04e32 100644
--- a/drivers/gpio/gpio-max7300.c
+++ b/drivers/gpio/gpio-max7300.c
@@ -31,7 +31,7 @@ static int max7300_i2c_read(struct device *dev, unsigned int reg)
return i2c_smbus_read_byte_data(client, reg);
}
-static int __devinit max7300_probe(struct i2c_client *client,
+static int max7300_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct max7301 *ts;
@@ -55,7 +55,7 @@ static int __devinit max7300_probe(struct i2c_client *client,
return ret;
}
-static int __devexit max7300_remove(struct i2c_client *client)
+static int max7300_remove(struct i2c_client *client)
{
return __max730x_remove(&client->dev);
}
@@ -72,7 +72,7 @@ static struct i2c_driver max7300_driver = {
.owner = THIS_MODULE,
},
.probe = max7300_probe,
- .remove = __devexit_p(max7300_remove),
+ .remove = max7300_remove,
.id_table = max7300_id,
};
diff --git a/drivers/gpio/gpio-max7301.c b/drivers/gpio/gpio-max7301.c
index 741acfcbe76..c6c535c1310 100644
--- a/drivers/gpio/gpio-max7301.c
+++ b/drivers/gpio/gpio-max7301.c
@@ -50,7 +50,7 @@ static int max7301_spi_read(struct device *dev, unsigned int reg)
return word & 0xff;
}
-static int __devinit max7301_probe(struct spi_device *spi)
+static int max7301_probe(struct spi_device *spi)
{
struct max7301 *ts;
int ret;
@@ -75,7 +75,7 @@ static int __devinit max7301_probe(struct spi_device *spi)
return ret;
}
-static int __devexit max7301_remove(struct spi_device *spi)
+static int max7301_remove(struct spi_device *spi)
{
return __max730x_remove(&spi->dev);
}
@@ -92,7 +92,7 @@ static struct spi_driver max7301_driver = {
.owner = THIS_MODULE,
},
.probe = max7301_probe,
- .remove = __devexit_p(max7301_remove),
+ .remove = max7301_remove,
.id_table = max7301_id,
};
diff --git a/drivers/gpio/gpio-max730x.c b/drivers/gpio/gpio-max730x.c
index 05e2dac60b3..00092342b84 100644
--- a/drivers/gpio/gpio-max730x.c
+++ b/drivers/gpio/gpio-max730x.c
@@ -160,17 +160,13 @@ static void max7301_set(struct gpio_chip *chip, unsigned offset, int value)
mutex_unlock(&ts->lock);
}
-int __devinit __max730x_probe(struct max7301 *ts)
+int __max730x_probe(struct max7301 *ts)
{
struct device *dev = ts->dev;
struct max7301_platform_data *pdata;
int i, ret;
pdata = dev->platform_data;
- if (!pdata || !pdata->base) {
- dev_err(dev, "incorrect or missing platform data\n");
- return -EINVAL;
- }
mutex_init(&ts->lock);
dev_set_drvdata(dev, ts);
@@ -178,7 +174,12 @@ int __devinit __max730x_probe(struct max7301 *ts)
/* Power up the chip and disable IRQ output */
ts->write(dev, 0x04, 0x01);
- ts->input_pullup_active = pdata->input_pullup_active;
+ if (pdata) {
+ ts->input_pullup_active = pdata->input_pullup_active;
+ ts->chip.base = pdata->base;
+ } else {
+ ts->chip.base = -1;
+ }
ts->chip.label = dev->driver->name;
ts->chip.direction_input = max7301_direction_input;
@@ -186,7 +187,6 @@ int __devinit __max730x_probe(struct max7301 *ts)
ts->chip.direction_output = max7301_direction_output;
ts->chip.set = max7301_set;
- ts->chip.base = pdata->base;
ts->chip.ngpio = PIN_NUMBER;
ts->chip.can_sleep = 1;
ts->chip.dev = dev;
@@ -226,7 +226,7 @@ exit_destroy:
}
EXPORT_SYMBOL_GPL(__max730x_probe);
-int __devexit __max730x_remove(struct device *dev)
+int __max730x_remove(struct device *dev)
{
struct max7301 *ts = dev_get_drvdata(dev);
int ret;
diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c
index 9504120812a..1e0467ce4c3 100644
--- a/drivers/gpio/gpio-max732x.c
+++ b/drivers/gpio/gpio-max732x.c
@@ -526,7 +526,7 @@ static void max732x_irq_teardown(struct max732x_chip *chip)
}
#endif
-static int __devinit max732x_setup_gpio(struct max732x_chip *chip,
+static int max732x_setup_gpio(struct max732x_chip *chip,
const struct i2c_device_id *id,
unsigned gpio_start)
{
@@ -574,7 +574,7 @@ static int __devinit max732x_setup_gpio(struct max732x_chip *chip,
return port;
}
-static int __devinit max732x_probe(struct i2c_client *client,
+static int max732x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct max732x_platform_data *pdata;
@@ -651,7 +651,7 @@ out_failed:
return ret;
}
-static int __devexit max732x_remove(struct i2c_client *client)
+static int max732x_remove(struct i2c_client *client)
{
struct max732x_platform_data *pdata = client->dev.platform_data;
struct max732x_chip *chip = i2c_get_clientdata(client);
@@ -690,7 +690,7 @@ static struct i2c_driver max732x_driver = {
.owner = THIS_MODULE,
},
.probe = max732x_probe,
- .remove = __devexit_p(max732x_remove),
+ .remove = max732x_remove,
.id_table = max732x_id,
};
diff --git a/drivers/gpio/gpio-mc33880.c b/drivers/gpio/gpio-mc33880.c
index 2de57ce5feb..6a8fdc26ae6 100644
--- a/drivers/gpio/gpio-mc33880.c
+++ b/drivers/gpio/gpio-mc33880.c
@@ -80,7 +80,7 @@ static void mc33880_set(struct gpio_chip *chip, unsigned offset, int value)
mutex_unlock(&mc->lock);
}
-static int __devinit mc33880_probe(struct spi_device *spi)
+static int mc33880_probe(struct spi_device *spi)
{
struct mc33880 *mc;
struct mc33880_platform_data *pdata;
@@ -147,7 +147,7 @@ exit_destroy:
return ret;
}
-static int __devexit mc33880_remove(struct spi_device *spi)
+static int mc33880_remove(struct spi_device *spi)
{
struct mc33880 *mc;
int ret;
@@ -175,7 +175,7 @@ static struct spi_driver mc33880_driver = {
.owner = THIS_MODULE,
},
.probe = mc33880_probe,
- .remove = __devexit_p(mc33880_remove),
+ .remove = mc33880_remove,
};
static int __init mc33880_init(void)
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c
index 0f425189de1..3cea0ea79e8 100644
--- a/drivers/gpio/gpio-mcp23s08.c
+++ b/drivers/gpio/gpio-mcp23s08.c
@@ -77,7 +77,7 @@ struct mcp23s08_driver_data {
/*----------------------------------------------------------------------*/
-#ifdef CONFIG_I2C
+#if IS_ENABLED(CONFIG_I2C)
static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg)
{
@@ -399,7 +399,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
break;
#endif /* CONFIG_SPI_MASTER */
-#ifdef CONFIG_I2C
+#if IS_ENABLED(CONFIG_I2C)
case MCP_TYPE_008:
mcp->ops = &mcp23008_ops;
mcp->chip.ngpio = 8;
@@ -473,9 +473,9 @@ fail:
/*----------------------------------------------------------------------*/
-#ifdef CONFIG_I2C
+#if IS_ENABLED(CONFIG_I2C)
-static int __devinit mcp230xx_probe(struct i2c_client *client,
+static int mcp230xx_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct mcp23s08_platform_data *pdata;
@@ -508,7 +508,7 @@ fail:
return status;
}
-static int __devexit mcp230xx_remove(struct i2c_client *client)
+static int mcp230xx_remove(struct i2c_client *client)
{
struct mcp23s08 *mcp = i2c_get_clientdata(client);
int status;
@@ -533,7 +533,7 @@ static struct i2c_driver mcp230xx_driver = {
.owner = THIS_MODULE,
},
.probe = mcp230xx_probe,
- .remove = __devexit_p(mcp230xx_remove),
+ .remove = mcp230xx_remove,
.id_table = mcp230xx_id,
};
diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c
index 6a29ee1847b..b73366523fa 100644
--- a/drivers/gpio/gpio-ml-ioh.c
+++ b/drivers/gpio/gpio-ml-ioh.c
@@ -385,7 +385,7 @@ static irqreturn_t ioh_gpio_handler(int irq, void *dev_id)
return ret;
}
-static __devinit void ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip,
+static void ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip,
unsigned int irq_start, unsigned int num)
{
struct irq_chip_generic *gc;
@@ -406,7 +406,7 @@ static __devinit void ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip,
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
}
-static int __devinit ioh_gpio_probe(struct pci_dev *pdev,
+static int ioh_gpio_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
int ret;
@@ -517,7 +517,7 @@ err_pci_enable:
return ret;
}
-static void __devexit ioh_gpio_remove(struct pci_dev *pdev)
+static void ioh_gpio_remove(struct pci_dev *pdev)
{
int err;
int i;
@@ -606,7 +606,7 @@ static struct pci_driver ioh_gpio_driver = {
.name = "ml_ioh_gpio",
.id_table = ioh_gpio_pcidev_id,
.probe = ioh_gpio_probe,
- .remove = __devexit_p(ioh_gpio_remove),
+ .remove = ioh_gpio_remove,
.suspend = ioh_gpio_suspend,
.resume = ioh_gpio_resume
};
diff --git a/drivers/gpio/gpio-mpc5200.c b/drivers/gpio/gpio-mpc5200.c
index 2c7cef367fc..42647f26c9e 100644
--- a/drivers/gpio/gpio-mpc5200.c
+++ b/drivers/gpio/gpio-mpc5200.c
@@ -148,7 +148,7 @@ mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
return 0;
}
-static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev)
+static int mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev)
{
struct mpc52xx_gpiochip *chip;
struct mpc52xx_gpio_wkup __iomem *regs;
@@ -308,7 +308,7 @@ mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
return 0;
}
-static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev)
+static int mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev)
{
struct mpc52xx_gpiochip *chip;
struct gpio_chip *gc;
diff --git a/drivers/gpio/gpio-msic.c b/drivers/gpio/gpio-msic.c
index b3898628586..27ea7b9257f 100644
--- a/drivers/gpio/gpio-msic.c
+++ b/drivers/gpio/gpio-msic.c
@@ -256,7 +256,7 @@ static void msic_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
chip->irq_eoi(data);
}
-static int __devinit platform_msic_gpio_probe(struct platform_device *pdev)
+static int platform_msic_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct intel_msic_gpio_pdata *pdata = dev->platform_data;
diff --git a/drivers/gpio/gpio-msm-v2.c b/drivers/gpio/gpio-msm-v2.c
index 38305beb437..55a7e7769af 100644
--- a/drivers/gpio/gpio-msm-v2.c
+++ b/drivers/gpio/gpio-msm-v2.c
@@ -352,7 +352,7 @@ static struct irq_chip msm_gpio_irq_chip = {
.irq_set_wake = msm_gpio_irq_set_wake,
};
-static int __devinit msm_gpio_probe(struct platform_device *dev)
+static int msm_gpio_probe(struct platform_device *dev)
{
int i, irq, ret;
@@ -376,7 +376,7 @@ static int __devinit msm_gpio_probe(struct platform_device *dev)
return 0;
}
-static int __devexit msm_gpio_remove(struct platform_device *dev)
+static int msm_gpio_remove(struct platform_device *dev)
{
int ret = gpiochip_remove(&msm_gpio.gpio_chip);
@@ -390,7 +390,7 @@ static int __devexit msm_gpio_remove(struct platform_device *dev)
static struct platform_driver msm_gpio_driver = {
.probe = msm_gpio_probe,
- .remove = __devexit_p(msm_gpio_remove),
+ .remove = msm_gpio_remove,
.driver = {
.name = "msmgpio",
.owner = THIS_MODULE,
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index cf7afb9eb61..d767b534c4a 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -92,6 +92,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip)
return mvchip->membase + GPIO_OUT_OFF;
}
+static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip)
+{
+ return mvchip->membase + GPIO_BLINK_EN_OFF;
+}
+
static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip)
{
return mvchip->membase + GPIO_IO_CONF_OFF;
@@ -163,12 +168,12 @@ static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip)
* Functions implementing the gpio_chip methods
*/
-int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin)
+static int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin)
{
return pinctrl_request_gpio(chip->base + pin);
}
-void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin)
+static void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin)
{
pinctrl_free_gpio(chip->base + pin);
}
@@ -206,6 +211,23 @@ static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin)
return (u >> pin) & 1;
}
+static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value)
+{
+ struct mvebu_gpio_chip *mvchip =
+ container_of(chip, struct mvebu_gpio_chip, chip);
+ unsigned long flags;
+ u32 u;
+
+ spin_lock_irqsave(&mvchip->lock, flags);
+ u = readl_relaxed(mvebu_gpioreg_blink(mvchip));
+ if (value)
+ u |= 1 << pin;
+ else
+ u &= ~(1 << pin);
+ writel_relaxed(u, mvebu_gpioreg_blink(mvchip));
+ spin_unlock_irqrestore(&mvchip->lock, flags);
+}
+
static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
{
struct mvebu_gpio_chip *mvchip =
@@ -244,6 +266,7 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin,
if (ret)
return ret;
+ mvebu_gpio_blink(chip, pin, 0);
mvebu_gpio_set(chip, pin, value);
spin_lock_irqsave(&mvchip->lock, flags);
@@ -459,7 +482,7 @@ static struct platform_device_id mvebu_gpio_ids[] = {
};
MODULE_DEVICE_TABLE(platform, mvebu_gpio_ids);
-static struct of_device_id mvebu_gpio_of_match[] __devinitdata = {
+static struct of_device_id mvebu_gpio_of_match[] = {
{
.compatible = "marvell,orion-gpio",
.data = (void*) MVEBU_GPIO_SOC_VARIANT_ORION,
@@ -478,7 +501,7 @@ static struct of_device_id mvebu_gpio_of_match[] __devinitdata = {
};
MODULE_DEVICE_TABLE(of, mvebu_gpio_of_match);
-static int __devinit mvebu_gpio_probe(struct platform_device *pdev)
+static int mvebu_gpio_probe(struct platform_device *pdev)
{
struct mvebu_gpio_chip *mvchip;
const struct of_device_id *match;
@@ -523,6 +546,7 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev)
mvchip->chip.label = dev_name(&pdev->dev);
mvchip->chip.dev = &pdev->dev;
mvchip->chip.request = mvebu_gpio_request;
+ mvchip->chip.free = mvebu_gpio_free;
mvchip->chip.direction_input = mvebu_gpio_direction_input;
mvchip->chip.get = mvebu_gpio_get;
mvchip->chip.direction_output = mvebu_gpio_direction_output;
@@ -650,8 +674,8 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev)
IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
/* Setup irq domain on top of the generic chip. */
- mvchip->domain = irq_domain_add_legacy(np, mvchip->chip.ngpio,
- mvchip->irqbase, 0,
+ mvchip->domain = irq_domain_add_simple(np, mvchip->chip.ngpio,
+ mvchip->irqbase,
&irq_domain_simple_ops,
mvchip);
if (!mvchip->domain) {
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 80f44bb64a8..7877335c4cc 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -356,7 +356,7 @@ static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
IRQ_NOREQUEST, 0);
}
-static void __devinit mxc_gpio_get_hw(struct platform_device *pdev)
+static void mxc_gpio_get_hw(struct platform_device *pdev)
{
const struct of_device_id *of_id =
of_match_device(mxc_gpio_dt_ids, &pdev->dev);
@@ -395,7 +395,7 @@ static int mxc_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
return irq_find_mapping(port->domain, offset);
}
-static int __devinit mxc_gpio_probe(struct platform_device *pdev)
+static int mxc_gpio_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct mxc_gpio_port *port;
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index 796fb13e481..fa2a63cad32 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -214,7 +214,7 @@ static const struct of_device_id mxs_gpio_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, mxs_gpio_dt_ids);
-static int __devinit mxs_gpio_probe(struct platform_device *pdev)
+static int mxs_gpio_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
of_match_device(mxs_gpio_dt_ids, &pdev->dev);
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index d335af1d4d8..f1fbedb2a6f 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1012,7 +1012,7 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
dev_err(bank->dev, "Could not get gpio dbck\n");
}
-static __devinit void
+static void
omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
unsigned int num)
{
@@ -1041,7 +1041,7 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
}
-static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
+static void omap_gpio_chip_init(struct gpio_bank *bank)
{
int j;
static int gpio;
@@ -1089,7 +1089,7 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
static const struct of_device_id omap_gpio_match[];
-static int __devinit omap_gpio_probe(struct platform_device *pdev)
+static int omap_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
@@ -1105,7 +1105,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
if (!pdata)
return -EINVAL;
- bank = devm_kzalloc(&pdev->dev, sizeof(struct gpio_bank), GFP_KERNEL);
+ bank = devm_kzalloc(dev, sizeof(struct gpio_bank), GFP_KERNEL);
if (!bank) {
dev_err(dev, "Memory alloc failed\n");
return -ENOMEM;
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 9c693ae1795..cc102d25ee2 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -16,6 +16,7 @@
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
#include <linux/i2c.h>
#include <linux/i2c/pca953x.h>
#include <linux/slab.h>
@@ -83,6 +84,7 @@ struct pca953x_chip {
u32 irq_trig_raise;
u32 irq_trig_fall;
int irq_base;
+ struct irq_domain *domain;
#endif
struct i2c_client *client;
@@ -333,14 +335,14 @@ static void pca953x_irq_mask(struct irq_data *d)
{
struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
- chip->irq_mask &= ~(1 << (d->irq - chip->irq_base));
+ chip->irq_mask &= ~(1 << d->hwirq);
}
static void pca953x_irq_unmask(struct irq_data *d)
{
struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
- chip->irq_mask |= 1 << (d->irq - chip->irq_base);
+ chip->irq_mask |= 1 << d->hwirq;
}
static void pca953x_irq_bus_lock(struct irq_data *d)
@@ -372,8 +374,7 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
static int pca953x_irq_set_type(struct irq_data *d, unsigned int type)
{
struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
- u32 level = d->irq - chip->irq_base;
- u32 mask = 1 << level;
+ u32 mask = 1 << d->hwirq;
if (!(type & IRQ_TYPE_EDGE_BOTH)) {
dev_err(&chip->client->dev, "irq %d: unsupported type %d\n",
@@ -454,7 +455,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)
do {
level = __ffs(pending);
- handle_nested_irq(level + chip->irq_base);
+ handle_nested_irq(irq_find_mapping(chip->domain, level));
pending &= ~(1 << level);
} while (pending);
@@ -499,6 +500,17 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
if (chip->irq_base < 0)
goto out_failed;
+ chip->domain = irq_domain_add_legacy(client->dev.of_node,
+ chip->gpio_chip.ngpio,
+ chip->irq_base,
+ 0,
+ &irq_domain_simple_ops,
+ NULL);
+ if (!chip->domain) {
+ ret = -ENODEV;
+ goto out_irqdesc_free;
+ }
+
for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) {
int irq = lvl + chip->irq_base;
@@ -521,7 +533,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
if (ret) {
dev_err(&client->dev, "failed to request irq %d\n",
client->irq);
- goto out_failed;
+ goto out_irqdesc_free;
}
chip->gpio_chip.to_irq = pca953x_gpio_to_irq;
@@ -529,6 +541,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
return 0;
+out_irqdesc_free:
+ irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio);
out_failed:
chip->irq_base = -1;
return ret;
@@ -602,7 +616,7 @@ pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert)
}
#endif
-static int __devinit device_pca953x_init(struct pca953x_chip *chip, u32 invert)
+static int device_pca953x_init(struct pca953x_chip *chip, u32 invert)
{
int ret;
@@ -621,7 +635,7 @@ out:
return ret;
}
-static int __devinit device_pca957x_init(struct pca953x_chip *chip, u32 invert)
+static int device_pca957x_init(struct pca953x_chip *chip, u32 invert)
{
int ret;
u32 val = 0;
@@ -652,7 +666,7 @@ out:
return ret;
}
-static int __devinit pca953x_probe(struct i2c_client *client,
+static int pca953x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pca953x_platform_data *pdata;
@@ -751,9 +765,38 @@ static int pca953x_remove(struct i2c_client *client)
return 0;
}
+static const struct of_device_id pca953x_dt_ids[] = {
+ { .compatible = "nxp,pca9534", },
+ { .compatible = "nxp,pca9535", },
+ { .compatible = "nxp,pca9536", },
+ { .compatible = "nxp,pca9537", },
+ { .compatible = "nxp,pca9538", },
+ { .compatible = "nxp,pca9539", },
+ { .compatible = "nxp,pca9554", },
+ { .compatible = "nxp,pca9555", },
+ { .compatible = "nxp,pca9556", },
+ { .compatible = "nxp,pca9557", },
+ { .compatible = "nxp,pca9574", },
+ { .compatible = "nxp,pca9575", },
+
+ { .compatible = "maxim,max7310", },
+ { .compatible = "maxim,max7312", },
+ { .compatible = "maxim,max7313", },
+ { .compatible = "maxim,max7315", },
+
+ { .compatible = "ti,pca6107", },
+ { .compatible = "ti,tca6408", },
+ { .compatible = "ti,tca6416", },
+ { .compatible = "ti,tca6424", },
+ { }
+};
+
+MODULE_DEVICE_TABLE(of, pca953x_dt_ids);
+
static struct i2c_driver pca953x_driver = {
.driver = {
.name = "pca953x",
+ .of_match_table = pca953x_dt_ids,
},
.probe = pca953x_probe,
.remove = pca953x_remove,
diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c
index 16af35cd2b1..a19b7457a72 100644
--- a/drivers/gpio/gpio-pcf857x.c
+++ b/drivers/gpio/gpio-pcf857x.c
@@ -223,11 +223,11 @@ static void pcf857x_irq_domain_cleanup(struct pcf857x *gpio)
static int pcf857x_irq_domain_init(struct pcf857x *gpio,
struct pcf857x_platform_data *pdata,
- struct device *dev)
+ struct i2c_client *client)
{
int status;
- gpio->irq_domain = irq_domain_add_linear(dev->of_node,
+ gpio->irq_domain = irq_domain_add_linear(client->dev.of_node,
gpio->chip.ngpio,
&pcf857x_irq_domain_ops,
NULL);
@@ -235,15 +235,15 @@ static int pcf857x_irq_domain_init(struct pcf857x *gpio,
goto fail;
/* enable real irq */
- status = request_irq(pdata->irq, pcf857x_irq_demux, 0,
- dev_name(dev), gpio);
+ status = request_irq(client->irq, pcf857x_irq_demux, 0,
+ dev_name(&client->dev), gpio);
if (status)
goto fail;
/* enable gpio_to_irq() */
INIT_WORK(&gpio->work, pcf857x_irq_demux_work);
gpio->chip.to_irq = pcf857x_to_irq;
- gpio->irq = pdata->irq;
+ gpio->irq = client->irq;
return 0;
@@ -285,8 +285,8 @@ static int pcf857x_probe(struct i2c_client *client,
gpio->chip.ngpio = id->driver_data;
/* enable gpio_to_irq() if platform has settings */
- if (pdata && pdata->irq) {
- status = pcf857x_irq_domain_init(gpio, pdata, &client->dev);
+ if (pdata && client->irq) {
+ status = pcf857x_irq_domain_init(gpio, pdata, client);
if (status < 0) {
dev_err(&client->dev, "irq_domain init failed\n");
goto fail;
@@ -368,15 +368,6 @@ static int pcf857x_probe(struct i2c_client *client,
if (status < 0)
goto fail;
- /* NOTE: these chips can issue "some pin-changed" IRQs, which we
- * don't yet even try to use. Among other issues, the relevant
- * genirq state isn't available to modular drivers; and most irq
- * methods can't be called from sleeping contexts.
- */
-
- dev_info(&client->dev, "%s\n",
- client->irq ? " (irq ignored)" : "");
-
/* Let platform code set up the GPIOs and their users.
* Now is the first time anyone could use them.
*/
@@ -388,13 +379,15 @@ static int pcf857x_probe(struct i2c_client *client,
dev_warn(&client->dev, "setup --> %d\n", status);
}
+ dev_info(&client->dev, "probed\n");
+
return 0;
fail:
dev_dbg(&client->dev, "probe error %d for '%s'\n",
status, client->name);
- if (pdata && pdata->irq)
+ if (pdata && client->irq)
pcf857x_irq_domain_cleanup(gpio);
kfree(gpio);
@@ -418,7 +411,7 @@ static int pcf857x_remove(struct i2c_client *client)
}
}
- if (pdata && pdata->irq)
+ if (pdata && client->irq)
pcf857x_irq_domain_cleanup(gpio);
status = gpiochip_remove(&gpio->chip);
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c
index 4ad0c4f9171..cdf599687cf 100644
--- a/drivers/gpio/gpio-pch.c
+++ b/drivers/gpio/gpio-pch.c
@@ -215,6 +215,7 @@ static void pch_gpio_setup(struct pch_gpio *chip)
struct gpio_chip *gpio = &chip->gpio;
gpio->label = dev_name(chip->dev);
+ gpio->dev = chip->dev;
gpio->owner = THIS_MODULE;
gpio->direction_input = pch_gpio_direction_input;
gpio->get = pch_gpio_get;
@@ -325,7 +326,7 @@ static irqreturn_t pch_gpio_handler(int irq, void *dev_id)
return ret;
}
-static __devinit void pch_gpio_alloc_generic_chip(struct pch_gpio *chip,
+static void pch_gpio_alloc_generic_chip(struct pch_gpio *chip,
unsigned int irq_start, unsigned int num)
{
struct irq_chip_generic *gc;
@@ -345,7 +346,7 @@ static __devinit void pch_gpio_alloc_generic_chip(struct pch_gpio *chip,
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
}
-static int __devinit pch_gpio_probe(struct pci_dev *pdev,
+static int pch_gpio_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
s32 ret;
@@ -442,7 +443,7 @@ err_pci_enable:
return ret;
}
-static void __devexit pch_gpio_remove(struct pci_dev *pdev)
+static void pch_gpio_remove(struct pci_dev *pdev)
{
int err;
struct pch_gpio *chip = pci_get_drvdata(pdev);
@@ -531,7 +532,7 @@ static struct pci_driver pch_gpio_driver = {
.name = "pch_gpio",
.id_table = pch_gpio_pcidev_id,
.probe = pch_gpio_probe,
- .remove = __devexit_p(pch_gpio_remove),
+ .remove = pch_gpio_remove,
.suspend = pch_gpio_suspend,
.resume = pch_gpio_resume
};
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index b4b5da4fd2c..c1720de18a4 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -48,12 +48,7 @@ struct pl061_context_save_regs {
#endif
struct pl061_gpio {
- /* Each of the two spinlocks protects a different set of hardware
- * regiters and data structurs. This decouples the code of the IRQ from
- * the GPIO code. This also makes the case of a GPIO routine call from
- * the IRQ code simpler.
- */
- spinlock_t lock; /* GPIO registers */
+ spinlock_t lock;
void __iomem *base;
int irq_base;
@@ -216,39 +211,34 @@ static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base)
IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0);
}
-static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
+static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
{
- struct pl061_platform_data *pdata;
+ struct device *dev = &adev->dev;
+ struct pl061_platform_data *pdata = dev->platform_data;
struct pl061_gpio *chip;
int ret, irq, i;
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
- pdata = dev->dev.platform_data;
if (pdata) {
chip->gc.base = pdata->gpio_base;
chip->irq_base = pdata->irq_base;
- } else if (dev->dev.of_node) {
+ } else if (adev->dev.of_node) {
chip->gc.base = -1;
chip->irq_base = 0;
- } else {
- ret = -ENODEV;
- goto free_mem;
- }
+ } else
+ return -ENODEV;
- if (!request_mem_region(dev->res.start,
- resource_size(&dev->res), "pl061")) {
- ret = -EBUSY;
- goto free_mem;
- }
+ if (!devm_request_mem_region(dev, adev->res.start,
+ resource_size(&adev->res), "pl061"))
+ return -EBUSY;
- chip->base = ioremap(dev->res.start, resource_size(&dev->res));
- if (chip->base == NULL) {
- ret = -ENOMEM;
- goto release_region;
- }
+ chip->base = devm_ioremap(dev, adev->res.start,
+ resource_size(&adev->res));
+ if (chip->base == NULL)
+ return -ENOMEM;
spin_lock_init(&chip->lock);
@@ -258,13 +248,13 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
chip->gc.set = pl061_set_value;
chip->gc.to_irq = pl061_to_irq;
chip->gc.ngpio = PL061_GPIO_NR;
- chip->gc.label = dev_name(&dev->dev);
- chip->gc.dev = &dev->dev;
+ chip->gc.label = dev_name(dev);
+ chip->gc.dev = dev;
chip->gc.owner = THIS_MODULE;
ret = gpiochip_add(&chip->gc);
if (ret)
- goto iounmap;
+ return ret;
/*
* irq_chip support
@@ -276,11 +266,10 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
pl061_init_gc(chip, chip->irq_base);
writeb(0, chip->base + GPIOIE); /* disable irqs */
- irq = dev->irq[0];
- if (irq < 0) {
- ret = -ENODEV;
- goto iounmap;
- }
+ irq = adev->irq[0];
+ if (irq < 0)
+ return -ENODEV;
+
irq_set_chained_handler(irq, pl061_irq_handler);
irq_set_handler_data(irq, chip);
@@ -294,18 +283,9 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
}
}
- amba_set_drvdata(dev, chip);
+ amba_set_drvdata(adev, chip);
return 0;
-
-iounmap:
- iounmap(chip->base);
-release_region:
- release_mem_region(dev->res.start, resource_size(&dev->res));
-free_mem:
- kfree(chip);
-
- return ret;
}
#ifdef CONFIG_PM
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 98d52cb3fd1..3e35243c136 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -250,7 +250,7 @@ static int pxa_gpio_of_xlate(struct gpio_chip *gc,
}
#endif
-static int __devinit pxa_init_gpio_chip(int gpio_end,
+static int pxa_init_gpio_chip(int gpio_end,
int (*set_wake)(unsigned int, unsigned int))
{
int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
@@ -490,7 +490,7 @@ const struct irq_domain_ops pxa_irq_domain_ops = {
.xlate = irq_domain_xlate_twocell,
};
-static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev)
+static int pxa_gpio_probe_dt(struct platform_device *pdev)
{
int ret, nr_banks, nr_gpios;
struct device_node *prev, *next, *np = pdev->dev.of_node;
@@ -537,7 +537,7 @@ err:
#define pxa_gpio_probe_dt(pdev) (-1)
#endif
-static int __devinit pxa_gpio_probe(struct platform_device *pdev)
+static int pxa_gpio_probe(struct platform_device *pdev)
{
struct pxa_gpio_chip *c;
struct resource *res;
diff --git a/drivers/gpio/gpio-rc5t583.c b/drivers/gpio/gpio-rc5t583.c
index 08428bf1771..e63d6a397e1 100644
--- a/drivers/gpio/gpio-rc5t583.c
+++ b/drivers/gpio/gpio-rc5t583.c
@@ -111,7 +111,7 @@ static void rc5t583_gpio_free(struct gpio_chip *gc, unsigned offset)
rc5t583_set_bits(parent, RC5T583_GPIO_PGSEL, BIT(offset));
}
-static int __devinit rc5t583_gpio_probe(struct platform_device *pdev)
+static int rc5t583_gpio_probe(struct platform_device *pdev)
{
struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent);
struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev);
@@ -146,7 +146,7 @@ static int __devinit rc5t583_gpio_probe(struct platform_device *pdev)
return gpiochip_add(&rc5t583_gpio->gpio_chip);
}
-static int __devexit rc5t583_gpio_remove(struct platform_device *pdev)
+static int rc5t583_gpio_remove(struct platform_device *pdev)
{
struct rc5t583_gpio *rc5t583_gpio = platform_get_drvdata(pdev);
@@ -159,7 +159,7 @@ static struct platform_driver rc5t583_gpio_driver = {
.owner = THIS_MODULE,
},
.probe = rc5t583_gpio_probe,
- .remove = __devexit_p(rc5t583_gpio_remove),
+ .remove = rc5t583_gpio_remove,
};
static int __init rc5t583_gpio_init(void)
diff --git a/drivers/gpio/gpio-rdc321x.c b/drivers/gpio/gpio-rdc321x.c
index b62d443e9a5..1bf55f67f7a 100644
--- a/drivers/gpio/gpio-rdc321x.c
+++ b/drivers/gpio/gpio-rdc321x.c
@@ -128,7 +128,7 @@ static int rdc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
/*
* Cache the initial value of both GPIO data registers
*/
-static int __devinit rdc321x_gpio_probe(struct platform_device *pdev)
+static int rdc321x_gpio_probe(struct platform_device *pdev)
{
int err;
struct resource *r;
@@ -206,7 +206,7 @@ out_free:
return err;
}
-static int __devexit rdc321x_gpio_remove(struct platform_device *pdev)
+static int rdc321x_gpio_remove(struct platform_device *pdev)
{
int ret;
struct rdc321x_gpio *rdc321x_gpio_dev = platform_get_drvdata(pdev);
@@ -225,7 +225,7 @@ static struct platform_driver rdc321x_gpio_driver = {
.driver.name = "rdc321x-gpio",
.driver.owner = THIS_MODULE,
.probe = rdc321x_gpio_probe,
- .remove = __devexit_p(rdc321x_gpio_remove),
+ .remove = rdc321x_gpio_remove,
};
module_platform_driver(rdc321x_gpio_driver);
diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
index 8707d4572a0..edae963f462 100644
--- a/drivers/gpio/gpio-sch.c
+++ b/drivers/gpio/gpio-sch.c
@@ -185,7 +185,7 @@ static struct gpio_chip sch_gpio_resume = {
.set = sch_gpio_resume_set,
};
-static int __devinit sch_gpio_probe(struct platform_device *pdev)
+static int sch_gpio_probe(struct platform_device *pdev)
{
struct resource *res;
int err, id;
@@ -271,7 +271,7 @@ err_sch_gpio_core:
return err;
}
-static int __devexit sch_gpio_remove(struct platform_device *pdev)
+static int sch_gpio_remove(struct platform_device *pdev)
{
struct resource *res;
if (gpio_ba) {
@@ -303,7 +303,7 @@ static struct platform_driver sch_gpio_driver = {
.owner = THIS_MODULE,
},
.probe = sch_gpio_probe,
- .remove = __devexit_p(sch_gpio_remove),
+ .remove = sch_gpio_remove,
};
module_platform_driver(sch_gpio_driver);
diff --git a/drivers/gpio/gpio-sodaville.c b/drivers/gpio/gpio-sodaville.c
index e25f73130b4..88f374ac775 100644
--- a/drivers/gpio/gpio-sodaville.c
+++ b/drivers/gpio/gpio-sodaville.c
@@ -129,7 +129,7 @@ static struct irq_domain_ops irq_domain_sdv_ops = {
.xlate = sdv_xlate,
};
-static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd,
+static int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd,
struct pci_dev *pdev)
{
struct irq_chip_type *ct;
@@ -186,7 +186,7 @@ out_free_desc:
return ret;
}
-static int __devinit sdv_gpio_probe(struct pci_dev *pdev,
+static int sdv_gpio_probe(struct pci_dev *pdev,
const struct pci_device_id *pci_id)
{
struct sdv_gpio_chip_data *sd;
diff --git a/drivers/gpio/gpio-spear-spics.c b/drivers/gpio/gpio-spear-spics.c
new file mode 100644
index 00000000000..5f45fc4ed5d
--- /dev/null
+++ b/drivers/gpio/gpio-spear-spics.c
@@ -0,0 +1,217 @@
+/*
+ * SPEAr platform SPI chipselect abstraction over gpiolib
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+/* maximum chipselects */
+#define NUM_OF_GPIO 4
+
+/*
+ * Provision is available on some SPEAr SoCs to control ARM PL022 spi cs
+ * through system registers. This register lies outside spi (pl022)
+ * address space into system registers.
+ *
+ * It provides control for spi chip select lines so that any chipselect
+ * (out of 4 possible chipselects in pl022) can be made low to select
+ * the particular slave.
+ */
+
+/**
+ * struct spear_spics - represents spi chip select control
+ * @base: base address
+ * @perip_cfg: configuration register
+ * @sw_enable_bit: bit to enable s/w control over chipselects
+ * @cs_value_bit: bit to program high or low chipselect
+ * @cs_enable_mask: mask to select bits required to select chipselect
+ * @cs_enable_shift: bit pos of cs_enable_mask
+ * @use_count: use count of a spi controller cs lines
+ * @last_off: stores last offset caller of set_value()
+ * @chip: gpio_chip abstraction
+ */
+struct spear_spics {
+ void __iomem *base;
+ u32 perip_cfg;
+ u32 sw_enable_bit;
+ u32 cs_value_bit;
+ u32 cs_enable_mask;
+ u32 cs_enable_shift;
+ unsigned long use_count;
+ int last_off;
+ struct gpio_chip chip;
+};
+
+/* gpio framework specific routines */
+static int spics_get_value(struct gpio_chip *chip, unsigned offset)
+{
+ return -ENXIO;
+}
+
+static void spics_set_value(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct spear_spics *spics = container_of(chip, struct spear_spics,
+ chip);
+ u32 tmp;
+
+ /* select chip select from register */
+ tmp = readl_relaxed(spics->base + spics->perip_cfg);
+ if (spics->last_off != offset) {
+ spics->last_off = offset;
+ tmp &= ~(spics->cs_enable_mask << spics->cs_enable_shift);
+ tmp |= offset << spics->cs_enable_shift;
+ }
+
+ /* toggle chip select line */
+ tmp &= ~(0x1 << spics->cs_value_bit);
+ tmp |= value << spics->cs_value_bit;
+ writel_relaxed(tmp, spics->base + spics->perip_cfg);
+}
+
+static int spics_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ return -ENXIO;
+}
+
+static int spics_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ spics_set_value(chip, offset, value);
+ return 0;
+}
+
+static int spics_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct spear_spics *spics = container_of(chip, struct spear_spics,
+ chip);
+ u32 tmp;
+
+ if (!spics->use_count++) {
+ tmp = readl_relaxed(spics->base + spics->perip_cfg);
+ tmp |= 0x1 << spics->sw_enable_bit;
+ tmp |= 0x1 << spics->cs_value_bit;
+ writel_relaxed(tmp, spics->base + spics->perip_cfg);
+ }
+
+ return 0;
+}
+
+static void spics_free(struct gpio_chip *chip, unsigned offset)
+{
+ struct spear_spics *spics = container_of(chip, struct spear_spics,
+ chip);
+ u32 tmp;
+
+ if (!--spics->use_count) {
+ tmp = readl_relaxed(spics->base + spics->perip_cfg);
+ tmp &= ~(0x1 << spics->sw_enable_bit);
+ writel_relaxed(tmp, spics->base + spics->perip_cfg);
+ }
+}
+
+static int spics_gpio_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct spear_spics *spics;
+ struct resource *res;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n");
+ return -EBUSY;
+ }
+
+ spics = devm_kzalloc(&pdev->dev, sizeof(*spics), GFP_KERNEL);
+ if (!spics) {
+ dev_err(&pdev->dev, "memory allocation fail\n");
+ return -ENOMEM;
+ }
+
+ spics->base = devm_request_and_ioremap(&pdev->dev, res);
+ if (!spics->base) {
+ dev_err(&pdev->dev, "request and ioremap fail\n");
+ return -ENOMEM;
+ }
+
+ if (of_property_read_u32(np, "st-spics,peripcfg-reg",
+ &spics->perip_cfg))
+ goto err_dt_data;
+ if (of_property_read_u32(np, "st-spics,sw-enable-bit",
+ &spics->sw_enable_bit))
+ goto err_dt_data;
+ if (of_property_read_u32(np, "st-spics,cs-value-bit",
+ &spics->cs_value_bit))
+ goto err_dt_data;
+ if (of_property_read_u32(np, "st-spics,cs-enable-mask",
+ &spics->cs_enable_mask))
+ goto err_dt_data;
+ if (of_property_read_u32(np, "st-spics,cs-enable-shift",
+ &spics->cs_enable_shift))
+ goto err_dt_data;
+
+ platform_set_drvdata(pdev, spics);
+
+ spics->chip.ngpio = NUM_OF_GPIO;
+ spics->chip.base = -1;
+ spics->chip.request = spics_request;
+ spics->chip.free = spics_free;
+ spics->chip.direction_input = spics_direction_input;
+ spics->chip.direction_output = spics_direction_output;
+ spics->chip.get = spics_get_value;
+ spics->chip.set = spics_set_value;
+ spics->chip.label = dev_name(&pdev->dev);
+ spics->chip.dev = &pdev->dev;
+ spics->chip.owner = THIS_MODULE;
+ spics->last_off = -1;
+
+ ret = gpiochip_add(&spics->chip);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to add gpio chip\n");
+ return ret;
+ }
+
+ dev_info(&pdev->dev, "spear spics registered\n");
+ return 0;
+
+err_dt_data:
+ dev_err(&pdev->dev, "DT probe failed\n");
+ return -EINVAL;
+}
+
+static const struct of_device_id spics_gpio_of_match[] = {
+ { .compatible = "st,spear-spics-gpio" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, spics_gpio_of_match);
+
+static struct platform_driver spics_gpio_driver = {
+ .probe = spics_gpio_probe,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "spear-spics-gpio",
+ .of_match_table = spics_gpio_of_match,
+ },
+};
+
+static int __init spics_gpio_init(void)
+{
+ return platform_driver_register(&spics_gpio_driver);
+}
+subsys_initcall(spics_gpio_init);
+
+MODULE_AUTHOR("Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_DESCRIPTION("ST Microlectronics SPEAr SPI Chip Select Abstraction");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-sta2x11.c b/drivers/gpio/gpio-sta2x11.c
index 6064fb376e1..558542552aa 100644
--- a/drivers/gpio/gpio-sta2x11.c
+++ b/drivers/gpio/gpio-sta2x11.c
@@ -320,7 +320,7 @@ static irqreturn_t gsta_gpio_handler(int irq, void *dev_id)
return ret;
}
-static __devinit void gsta_alloc_irq_chip(struct gsta_gpio *chip)
+static void gsta_alloc_irq_chip(struct gsta_gpio *chip)
{
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
@@ -353,7 +353,7 @@ static __devinit void gsta_alloc_irq_chip(struct gsta_gpio *chip)
}
/* The platform device used here is instantiated by the MFD device */
-static int __devinit gsta_probe(struct platform_device *dev)
+static int gsta_probe(struct platform_device *dev)
{
int i, err;
struct pci_dev *pdev;
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index dce34727bbf..770476a9da8 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -11,7 +11,9 @@
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
#include <linux/interrupt.h>
+#include <linux/of.h>
#include <linux/mfd/stmpe.h>
/*
@@ -28,6 +30,7 @@ struct stmpe_gpio {
struct stmpe *stmpe;
struct device *dev;
struct mutex irq_lock;
+ struct irq_domain *domain;
int irq_base;
unsigned norequest_mask;
@@ -103,7 +106,7 @@ static int stmpe_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(chip);
- return stmpe_gpio->irq_base + offset;
+ return irq_create_mapping(stmpe_gpio->domain, offset);
}
static int stmpe_gpio_request(struct gpio_chip *chip, unsigned offset)
@@ -132,7 +135,7 @@ static struct gpio_chip template_chip = {
static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
- int offset = d->irq - stmpe_gpio->irq_base;
+ int offset = d->hwirq;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
@@ -199,7 +202,7 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)
static void stmpe_gpio_irq_mask(struct irq_data *d)
{
struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
- int offset = d->irq - stmpe_gpio->irq_base;
+ int offset = d->hwirq;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
@@ -209,7 +212,7 @@ static void stmpe_gpio_irq_mask(struct irq_data *d)
static void stmpe_gpio_irq_unmask(struct irq_data *d)
{
struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
- int offset = d->irq - stmpe_gpio->irq_base;
+ int offset = d->hwirq;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
@@ -251,8 +254,9 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev)
while (stat) {
int bit = __ffs(stat);
int line = bank * 8 + bit;
+ int virq = irq_find_mapping(stmpe_gpio->domain, line);
- handle_nested_irq(stmpe_gpio->irq_base + line);
+ handle_nested_irq(virq);
stat &= ~(1 << bit);
}
@@ -267,43 +271,61 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev)
return IRQ_HANDLED;
}
-static int __devinit stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio)
+int stmpe_gpio_irq_map(struct irq_domain *d, unsigned int virq,
+ irq_hw_number_t hwirq)
{
- int base = stmpe_gpio->irq_base;
- int irq;
+ struct stmpe_gpio *stmpe_gpio = d->host_data;
+
+ if (!stmpe_gpio)
+ return -EINVAL;
- for (irq = base; irq < base + stmpe_gpio->chip.ngpio; irq++) {
- irq_set_chip_data(irq, stmpe_gpio);
- irq_set_chip_and_handler(irq, &stmpe_gpio_irq_chip,
- handle_simple_irq);
- irq_set_nested_thread(irq, 1);
+ irq_set_chip_data(hwirq, stmpe_gpio);
+ irq_set_chip_and_handler(hwirq, &stmpe_gpio_irq_chip,
+ handle_simple_irq);
+ irq_set_nested_thread(hwirq, 1);
#ifdef CONFIG_ARM
- set_irq_flags(irq, IRQF_VALID);
+ set_irq_flags(hwirq, IRQF_VALID);
#else
- irq_set_noprobe(irq);
+ irq_set_noprobe(hwirq);
#endif
- }
return 0;
}
-static void stmpe_gpio_irq_remove(struct stmpe_gpio *stmpe_gpio)
+void stmpe_gpio_irq_unmap(struct irq_domain *d, unsigned int virq)
{
- int base = stmpe_gpio->irq_base;
- int irq;
-
- for (irq = base; irq < base + stmpe_gpio->chip.ngpio; irq++) {
#ifdef CONFIG_ARM
- set_irq_flags(irq, 0);
+ set_irq_flags(virq, 0);
#endif
- irq_set_chip_and_handler(irq, NULL, NULL);
- irq_set_chip_data(irq, NULL);
+ irq_set_chip_and_handler(virq, NULL, NULL);
+ irq_set_chip_data(virq, NULL);
+}
+
+static const struct irq_domain_ops stmpe_gpio_irq_simple_ops = {
+ .unmap = stmpe_gpio_irq_unmap,
+ .map = stmpe_gpio_irq_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+static int stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio)
+{
+ int base = stmpe_gpio->irq_base;
+
+ stmpe_gpio->domain = irq_domain_add_simple(NULL,
+ stmpe_gpio->chip.ngpio, base,
+ &stmpe_gpio_irq_simple_ops, stmpe_gpio);
+ if (!stmpe_gpio->domain) {
+ dev_err(stmpe_gpio->dev, "failed to create irqdomain\n");
+ return -ENOSYS;
}
+
+ return 0;
}
-static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
+static int stmpe_gpio_probe(struct platform_device *pdev)
{
struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
+ struct device_node *np = pdev->dev.of_node;
struct stmpe_gpio_platform_data *pdata;
struct stmpe_gpio *stmpe_gpio;
int ret;
@@ -321,13 +343,17 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
stmpe_gpio->dev = &pdev->dev;
stmpe_gpio->stmpe = stmpe;
- stmpe_gpio->norequest_mask = pdata ? pdata->norequest_mask : 0;
-
stmpe_gpio->chip = template_chip;
stmpe_gpio->chip.ngpio = stmpe->num_gpios;
stmpe_gpio->chip.dev = &pdev->dev;
stmpe_gpio->chip.base = pdata ? pdata->gpio_base : -1;
+ if (pdata)
+ stmpe_gpio->norequest_mask = pdata->norequest_mask;
+ else if (np)
+ of_property_read_u32(np, "st,norequest-mask",
+ &stmpe_gpio->norequest_mask);
+
if (irq >= 0)
stmpe_gpio->irq_base = stmpe->irq_base + STMPE_INT_GPIO(0);
else
@@ -348,7 +374,7 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
IRQF_ONESHOT, "stmpe-gpio", stmpe_gpio);
if (ret) {
dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
- goto out_removeirq;
+ goto out_disable;
}
}
@@ -368,9 +394,6 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
out_freeirq:
if (irq >= 0)
free_irq(irq, stmpe_gpio);
-out_removeirq:
- if (irq >= 0)
- stmpe_gpio_irq_remove(stmpe_gpio);
out_disable:
stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
out_free:
@@ -378,7 +401,7 @@ out_free:
return ret;
}
-static int __devexit stmpe_gpio_remove(struct platform_device *pdev)
+static int stmpe_gpio_remove(struct platform_device *pdev)
{
struct stmpe_gpio *stmpe_gpio = platform_get_drvdata(pdev);
struct stmpe *stmpe = stmpe_gpio->stmpe;
@@ -398,10 +421,9 @@ static int __devexit stmpe_gpio_remove(struct platform_device *pdev)
stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
- if (irq >= 0) {
+ if (irq >= 0)
free_irq(irq, stmpe_gpio);
- stmpe_gpio_irq_remove(stmpe_gpio);
- }
+
platform_set_drvdata(pdev, NULL);
kfree(stmpe_gpio);
@@ -412,7 +434,7 @@ static struct platform_driver stmpe_gpio_driver = {
.driver.name = "stmpe-gpio",
.driver.owner = THIS_MODULE,
.probe = stmpe_gpio_probe,
- .remove = __devexit_p(stmpe_gpio_remove),
+ .remove = stmpe_gpio_remove,
};
static int __init stmpe_gpio_init(void)
diff --git a/drivers/gpio/gpio-stp-xway.c b/drivers/gpio/gpio-stp-xway.c
index 8bead0bb645..85841ee70b1 100644
--- a/drivers/gpio/gpio-stp-xway.c
+++ b/drivers/gpio/gpio-stp-xway.c
@@ -197,7 +197,7 @@ static int xway_stp_hw_init(struct xway_stp *chip)
return 0;
}
-static int __devinit xway_stp_probe(struct platform_device *pdev)
+static int xway_stp_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
const __be32 *shadow, *groups, *dsl, *phy;
diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c
index eb3e215d239..796b6c42fa7 100644
--- a/drivers/gpio/gpio-sx150x.c
+++ b/drivers/gpio/gpio-sx150x.c
@@ -575,7 +575,7 @@ static void sx150x_remove_irq_chip(struct sx150x_chip *chip)
}
}
-static int __devinit sx150x_probe(struct i2c_client *client,
+static int sx150x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
static const u32 i2c_funcs = I2C_FUNC_SMBUS_BYTE_DATA |
@@ -622,7 +622,7 @@ probe_fail_pre_gpiochip_add:
return rc;
}
-static int __devexit sx150x_remove(struct i2c_client *client)
+static int sx150x_remove(struct i2c_client *client)
{
struct sx150x_chip *chip;
int rc;
@@ -646,7 +646,7 @@ static struct i2c_driver sx150x_driver = {
.owner = THIS_MODULE
},
.probe = sx150x_probe,
- .remove = __devexit_p(sx150x_remove),
+ .remove = sx150x_remove,
.id_table = sx150x_id,
};
diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c
index 1e48317e70f..c0595bbf326 100644
--- a/drivers/gpio/gpio-tc3589x.c
+++ b/drivers/gpio/gpio-tc3589x.c
@@ -292,17 +292,15 @@ static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio,
{
int base = tc3589x_gpio->irq_base;
- if (base) {
- tc3589x_gpio->domain = irq_domain_add_legacy(
- NULL, tc3589x_gpio->chip.ngpio, base,
- 0, &tc3589x_irq_ops, tc3589x_gpio);
- }
- else {
- tc3589x_gpio->domain = irq_domain_add_linear(
- np, tc3589x_gpio->chip.ngpio,
- &tc3589x_irq_ops, tc3589x_gpio);
- }
-
+ /*
+ * If this results in a linear domain, irq_create_mapping() will
+ * take care of allocating IRQ descriptors at runtime. When a base
+ * is provided, the IRQ descriptors will be allocated when the
+ * domain is instantiated.
+ */
+ tc3589x_gpio->domain = irq_domain_add_simple(np,
+ tc3589x_gpio->chip.ngpio, base, &tc3589x_irq_ops,
+ tc3589x_gpio);
if (!tc3589x_gpio->domain) {
dev_err(tc3589x_gpio->dev, "Failed to create irqdomain\n");
return -ENOSYS;
@@ -311,7 +309,7 @@ static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio,
return 0;
}
-static int __devinit tc3589x_gpio_probe(struct platform_device *pdev)
+static int tc3589x_gpio_probe(struct platform_device *pdev)
{
struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent);
struct tc3589x_gpio_platform_data *pdata;
@@ -389,7 +387,7 @@ out_free:
return ret;
}
-static int __devexit tc3589x_gpio_remove(struct platform_device *pdev)
+static int tc3589x_gpio_remove(struct platform_device *pdev)
{
struct tc3589x_gpio *tc3589x_gpio = platform_get_drvdata(pdev);
struct tc3589x *tc3589x = tc3589x_gpio->tc3589x;
@@ -419,7 +417,7 @@ static struct platform_driver tc3589x_gpio_driver = {
.driver.name = "tc3589x-gpio",
.driver.owner = THIS_MODULE,
.probe = tc3589x_gpio_probe,
- .remove = __devexit_p(tc3589x_gpio_remove),
+ .remove = tc3589x_gpio_remove,
};
static int __init tc3589x_gpio_init(void)
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index d982593d756..63cb643d4b5 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -27,6 +27,7 @@
#include <linux/module.h>
#include <linux/irqdomain.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/pm.h>
#include <asm/mach/irq.h>
@@ -64,7 +65,7 @@ struct tegra_gpio_bank {
int bank;
int irq;
spinlock_t lvl_lock[4];
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
u32 cnf[4];
u32 out[4];
u32 oe[4];
@@ -109,20 +110,18 @@ static void tegra_gpio_enable(int gpio)
{
tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1);
}
-EXPORT_SYMBOL_GPL(tegra_gpio_enable);
static void tegra_gpio_disable(int gpio)
{
tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0);
}
-EXPORT_SYMBOL_GPL(tegra_gpio_disable);
-int tegra_gpio_request(struct gpio_chip *chip, unsigned offset)
+static int tegra_gpio_request(struct gpio_chip *chip, unsigned offset)
{
return pinctrl_request_gpio(offset);
}
-void tegra_gpio_free(struct gpio_chip *chip, unsigned offset)
+static void tegra_gpio_free(struct gpio_chip *chip, unsigned offset)
{
pinctrl_free_gpio(offset);
tegra_gpio_disable(offset);
@@ -135,6 +134,11 @@ static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset)
{
+ /* If gpio is in output mode then read from the out value */
+ if ((tegra_gpio_readl(GPIO_OE(offset)) >> GPIO_BIT(offset)) & 1)
+ return (tegra_gpio_readl(GPIO_OUT(offset)) >>
+ GPIO_BIT(offset)) & 0x1;
+
return (tegra_gpio_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1;
}
@@ -285,8 +289,8 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
}
-#ifdef CONFIG_PM
-void tegra_gpio_resume(void)
+#ifdef CONFIG_PM_SLEEP
+static int tegra_gpio_resume(struct device *dev)
{
unsigned long flags;
int b;
@@ -308,9 +312,10 @@ void tegra_gpio_resume(void)
}
local_irq_restore(flags);
+ return 0;
}
-void tegra_gpio_suspend(void)
+static int tegra_gpio_suspend(struct device *dev)
{
unsigned long flags;
int b;
@@ -330,6 +335,7 @@ void tegra_gpio_suspend(void)
}
}
local_irq_restore(flags);
+ return 0;
}
static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable)
@@ -345,11 +351,15 @@ static struct irq_chip tegra_gpio_irq_chip = {
.irq_mask = tegra_gpio_irq_mask,
.irq_unmask = tegra_gpio_irq_unmask,
.irq_set_type = tegra_gpio_irq_set_type,
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
.irq_set_wake = tegra_gpio_wake_enable,
#endif
};
+static const struct dev_pm_ops tegra_gpio_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(tegra_gpio_suspend, tegra_gpio_resume)
+};
+
struct tegra_gpio_soc_config {
u32 bank_stride;
u32 upper_offset;
@@ -365,7 +375,7 @@ static struct tegra_gpio_soc_config tegra30_gpio_config = {
.upper_offset = 0x80,
};
-static struct of_device_id tegra_gpio_of_match[] __devinitdata = {
+static struct of_device_id tegra_gpio_of_match[] = {
{ .compatible = "nvidia,tegra30-gpio", .data = &tegra30_gpio_config },
{ .compatible = "nvidia,tegra20-gpio", .data = &tegra20_gpio_config },
{ },
@@ -376,11 +386,10 @@ static struct of_device_id tegra_gpio_of_match[] __devinitdata = {
*/
static struct lock_class_key gpio_lock_class;
-static int __devinit tegra_gpio_probe(struct platform_device *pdev)
+static int tegra_gpio_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
struct tegra_gpio_soc_config *config;
- int irq_base;
struct resource *res;
struct tegra_gpio_bank *bank;
int gpio;
@@ -417,14 +426,11 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
- irq_base = irq_alloc_descs(-1, 0, tegra_gpio_chip.ngpio, 0);
- if (irq_base < 0) {
- dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n");
- return -ENODEV;
- }
- irq_domain = irq_domain_add_legacy(pdev->dev.of_node,
- tegra_gpio_chip.ngpio, irq_base, 0,
+ irq_domain = irq_domain_add_linear(pdev->dev.of_node,
+ tegra_gpio_chip.ngpio,
&irq_domain_simple_ops, NULL);
+ if (!irq_domain)
+ return -ENODEV;
for (i = 0; i < tegra_gpio_bank_count; i++) {
res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
@@ -464,7 +470,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
gpiochip_add(&tegra_gpio_chip);
for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) {
- int irq = irq_find_mapping(irq_domain, gpio);
+ int irq = irq_create_mapping(irq_domain, gpio);
/* No validity check; all Tegra GPIOs are valid IRQs */
bank = &tegra_gpio_banks[GPIO_BANK(gpio)];
@@ -493,6 +499,7 @@ static struct platform_driver tegra_gpio_driver = {
.driver = {
.name = "tegra-gpio",
.owner = THIS_MODULE,
+ .pm = &tegra_gpio_pm_ops,
.of_match_table = tegra_gpio_of_match,
},
.probe = tegra_gpio_probe,
diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c
index 1a3e2b9b477..702cca9284f 100644
--- a/drivers/gpio/gpio-timberdale.c
+++ b/drivers/gpio/gpio-timberdale.c
@@ -222,7 +222,7 @@ static struct irq_chip timbgpio_irqchip = {
.irq_set_type = timbgpio_irq_type,
};
-static int __devinit timbgpio_probe(struct platform_device *pdev)
+static int timbgpio_probe(struct platform_device *pdev)
{
int err, i;
struct gpio_chip *gc;
@@ -316,7 +316,7 @@ err_mem:
return err;
}
-static int __devexit timbgpio_remove(struct platform_device *pdev)
+static int timbgpio_remove(struct platform_device *pdev)
{
int err;
struct timbgpio_platform_data *pdata = pdev->dev.platform_data;
diff --git a/drivers/gpio/gpio-tps6586x.c b/drivers/gpio/gpio-tps6586x.c
index 2526b3bb0fa..c1b82da5650 100644
--- a/drivers/gpio/gpio-tps6586x.c
+++ b/drivers/gpio/gpio-tps6586x.c
@@ -80,7 +80,7 @@ static int tps6586x_gpio_output(struct gpio_chip *gc, unsigned offset,
val, mask);
}
-static int __devinit tps6586x_gpio_probe(struct platform_device *pdev)
+static int tps6586x_gpio_probe(struct platform_device *pdev)
{
struct tps6586x_platform_data *pdata;
struct tps6586x_gpio *tps6586x_gpio;
@@ -126,7 +126,7 @@ static int __devinit tps6586x_gpio_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit tps6586x_gpio_remove(struct platform_device *pdev)
+static int tps6586x_gpio_remove(struct platform_device *pdev)
{
struct tps6586x_gpio *tps6586x_gpio = platform_get_drvdata(pdev);
@@ -137,7 +137,7 @@ static struct platform_driver tps6586x_gpio_driver = {
.driver.name = "tps6586x-gpio",
.driver.owner = THIS_MODULE,
.probe = tps6586x_gpio_probe,
- .remove = __devexit_p(tps6586x_gpio_remove),
+ .remove = tps6586x_gpio_remove,
};
static int __init tps6586x_gpio_init(void)
diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c
index 11f29c82253..5083825a034 100644
--- a/drivers/gpio/gpio-tps65910.c
+++ b/drivers/gpio/gpio-tps65910.c
@@ -113,7 +113,7 @@ static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev,
}
#endif
-static int __devinit tps65910_gpio_probe(struct platform_device *pdev)
+static int tps65910_gpio_probe(struct platform_device *pdev)
{
struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
struct tps65910_board *pdata = dev_get_platdata(tps65910->dev);
@@ -188,7 +188,7 @@ skip_init:
return ret;
}
-static int __devexit tps65910_gpio_remove(struct platform_device *pdev)
+static int tps65910_gpio_remove(struct platform_device *pdev)
{
struct tps65910_gpio *tps65910_gpio = platform_get_drvdata(pdev);
@@ -199,7 +199,7 @@ static struct platform_driver tps65910_gpio_driver = {
.driver.name = "tps65910-gpio",
.driver.owner = THIS_MODULE,
.probe = tps65910_gpio_probe,
- .remove = __devexit_p(tps65910_gpio_remove),
+ .remove = tps65910_gpio_remove,
};
static int __init tps65910_gpio_init(void)
diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c
index 99106d1e2e5..30a5844a7dc 100644
--- a/drivers/gpio/gpio-tps65912.c
+++ b/drivers/gpio/gpio-tps65912.c
@@ -84,7 +84,7 @@ static struct gpio_chip template_chip = {
.base = -1,
};
-static int __devinit tps65912_gpio_probe(struct platform_device *pdev)
+static int tps65912_gpio_probe(struct platform_device *pdev)
{
struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent);
struct tps65912_board *pdata = tps65912->dev->platform_data;
@@ -113,7 +113,7 @@ static int __devinit tps65912_gpio_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit tps65912_gpio_remove(struct platform_device *pdev)
+static int tps65912_gpio_remove(struct platform_device *pdev)
{
struct tps65912_gpio_data *tps65912_gpio = platform_get_drvdata(pdev);
@@ -126,7 +126,7 @@ static struct platform_driver tps65912_gpio_driver = {
.owner = THIS_MODULE,
},
.probe = tps65912_gpio_probe,
- .remove = __devexit_p(tps65912_gpio_remove),
+ .remove = tps65912_gpio_remove,
};
static int __init tps65912_gpio_init(void)
diff --git a/drivers/gpio/gpio-ts5500.c b/drivers/gpio/gpio-ts5500.c
new file mode 100644
index 00000000000..0634ceea3c2
--- /dev/null
+++ b/drivers/gpio/gpio-ts5500.c
@@ -0,0 +1,466 @@
+/*
+ * Digital I/O driver for Technologic Systems TS-5500
+ *
+ * Copyright (c) 2012 Savoir-faire Linux Inc.
+ * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+ *
+ * Technologic Systems platforms have pin blocks, exposing several Digital
+ * Input/Output lines (DIO). This driver aims to support single pin blocks.
+ * In that sense, the support is not limited to the TS-5500 blocks.
+ * Actually, the following platforms have DIO support:
+ *
+ * TS-5500:
+ * Documentation: http://wiki.embeddedarm.com/wiki/TS-5500
+ * Blocks: DIO1, DIO2 and LCD port.
+ *
+ * TS-5600:
+ * Documentation: http://wiki.embeddedarm.com/wiki/TS-5600
+ * Blocks: LCD port (identical to TS-5500 LCD).
+ *
+ * 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/bitops.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_data/gpio-ts5500.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* List of supported Technologic Systems platforms DIO blocks */
+enum ts5500_blocks { TS5500_DIO1, TS5500_DIO2, TS5500_LCD, TS5600_LCD };
+
+struct ts5500_priv {
+ const struct ts5500_dio *pinout;
+ struct gpio_chip gpio_chip;
+ spinlock_t lock;
+ bool strap;
+ u8 hwirq;
+};
+
+/*
+ * Hex 7D is used to control several blocks (e.g. DIO2 and LCD port).
+ * This flag ensures that the region has been requested by this driver.
+ */
+static bool hex7d_reserved;
+
+/*
+ * This structure is used to describe capabilities of DIO lines,
+ * such as available directions and connected interrupt (if any).
+ */
+struct ts5500_dio {
+ const u8 value_addr;
+ const u8 value_mask;
+ const u8 control_addr;
+ const u8 control_mask;
+ const bool no_input;
+ const bool no_output;
+ const u8 irq;
+};
+
+#define TS5500_DIO_IN_OUT(vaddr, vbit, caddr, cbit) \
+ { \
+ .value_addr = vaddr, \
+ .value_mask = BIT(vbit), \
+ .control_addr = caddr, \
+ .control_mask = BIT(cbit), \
+ }
+
+#define TS5500_DIO_IN(addr, bit) \
+ { \
+ .value_addr = addr, \
+ .value_mask = BIT(bit), \
+ .no_output = true, \
+ }
+
+#define TS5500_DIO_IN_IRQ(addr, bit, _irq) \
+ { \
+ .value_addr = addr, \
+ .value_mask = BIT(bit), \
+ .no_output = true, \
+ .irq = _irq, \
+ }
+
+#define TS5500_DIO_OUT(addr, bit) \
+ { \
+ .value_addr = addr, \
+ .value_mask = BIT(bit), \
+ .no_input = true, \
+ }
+
+/*
+ * Input/Output DIO lines are programmed in groups of 4. Their values are
+ * available through 4 consecutive bits in a value port, whereas the direction
+ * of these 4 lines is driven by only 1 bit in a control port.
+ */
+#define TS5500_DIO_GROUP(vaddr, vbitfrom, caddr, cbit) \
+ TS5500_DIO_IN_OUT(vaddr, vbitfrom + 0, caddr, cbit), \
+ TS5500_DIO_IN_OUT(vaddr, vbitfrom + 1, caddr, cbit), \
+ TS5500_DIO_IN_OUT(vaddr, vbitfrom + 2, caddr, cbit), \
+ TS5500_DIO_IN_OUT(vaddr, vbitfrom + 3, caddr, cbit)
+
+/*
+ * TS-5500 DIO1 block
+ *
+ * value control dir hw
+ * addr bit addr bit in out irq name pin offset
+ *
+ * 0x7b 0 0x7a 0 x x DIO1_0 1 0
+ * 0x7b 1 0x7a 0 x x DIO1_1 3 1
+ * 0x7b 2 0x7a 0 x x DIO1_2 5 2
+ * 0x7b 3 0x7a 0 x x DIO1_3 7 3
+ * 0x7b 4 0x7a 1 x x DIO1_4 9 4
+ * 0x7b 5 0x7a 1 x x DIO1_5 11 5
+ * 0x7b 6 0x7a 1 x x DIO1_6 13 6
+ * 0x7b 7 0x7a 1 x x DIO1_7 15 7
+ * 0x7c 0 0x7a 5 x x DIO1_8 4 8
+ * 0x7c 1 0x7a 5 x x DIO1_9 6 9
+ * 0x7c 2 0x7a 5 x x DIO1_10 8 10
+ * 0x7c 3 0x7a 5 x x DIO1_11 10 11
+ * 0x7c 4 x DIO1_12 12 12
+ * 0x7c 5 x 7 DIO1_13 14 13
+ */
+static const struct ts5500_dio ts5500_dio1[] = {
+ TS5500_DIO_GROUP(0x7b, 0, 0x7a, 0),
+ TS5500_DIO_GROUP(0x7b, 4, 0x7a, 1),
+ TS5500_DIO_GROUP(0x7c, 0, 0x7a, 5),
+ TS5500_DIO_IN(0x7c, 4),
+ TS5500_DIO_IN_IRQ(0x7c, 5, 7),
+};
+
+/*
+ * TS-5500 DIO2 block
+ *
+ * value control dir hw
+ * addr bit addr bit in out irq name pin offset
+ *
+ * 0x7e 0 0x7d 0 x x DIO2_0 1 0
+ * 0x7e 1 0x7d 0 x x DIO2_1 3 1
+ * 0x7e 2 0x7d 0 x x DIO2_2 5 2
+ * 0x7e 3 0x7d 0 x x DIO2_3 7 3
+ * 0x7e 4 0x7d 1 x x DIO2_4 9 4
+ * 0x7e 5 0x7d 1 x x DIO2_5 11 5
+ * 0x7e 6 0x7d 1 x x DIO2_6 13 6
+ * 0x7e 7 0x7d 1 x x DIO2_7 15 7
+ * 0x7f 0 0x7d 5 x x DIO2_8 4 8
+ * 0x7f 1 0x7d 5 x x DIO2_9 6 9
+ * 0x7f 2 0x7d 5 x x DIO2_10 8 10
+ * 0x7f 3 0x7d 5 x x DIO2_11 10 11
+ * 0x7f 4 x 6 DIO2_13 14 12
+ */
+static const struct ts5500_dio ts5500_dio2[] = {
+ TS5500_DIO_GROUP(0x7e, 0, 0x7d, 0),
+ TS5500_DIO_GROUP(0x7e, 4, 0x7d, 1),
+ TS5500_DIO_GROUP(0x7f, 0, 0x7d, 5),
+ TS5500_DIO_IN_IRQ(0x7f, 4, 6),
+};
+
+/*
+ * TS-5500 LCD port used as DIO block
+ * TS-5600 LCD port is identical
+ *
+ * value control dir hw
+ * addr bit addr bit in out irq name pin offset
+ *
+ * 0x72 0 0x7d 2 x x LCD_0 8 0
+ * 0x72 1 0x7d 2 x x LCD_1 7 1
+ * 0x72 2 0x7d 2 x x LCD_2 10 2
+ * 0x72 3 0x7d 2 x x LCD_3 9 3
+ * 0x72 4 0x7d 3 x x LCD_4 12 4
+ * 0x72 5 0x7d 3 x x LCD_5 11 5
+ * 0x72 6 0x7d 3 x x LCD_6 14 6
+ * 0x72 7 0x7d 3 x x LCD_7 13 7
+ * 0x73 0 x LCD_EN 5 8
+ * 0x73 6 x LCD_WR 6 9
+ * 0x73 7 x 1 LCD_RS 3 10
+ */
+static const struct ts5500_dio ts5500_lcd[] = {
+ TS5500_DIO_GROUP(0x72, 0, 0x7d, 2),
+ TS5500_DIO_GROUP(0x72, 4, 0x7d, 3),
+ TS5500_DIO_OUT(0x73, 0),
+ TS5500_DIO_IN(0x73, 6),
+ TS5500_DIO_IN_IRQ(0x73, 7, 1),
+};
+
+static inline struct ts5500_priv *ts5500_gc_to_priv(struct gpio_chip *chip)
+{
+ return container_of(chip, struct ts5500_priv, gpio_chip);
+}
+
+static inline void ts5500_set_mask(u8 mask, u8 addr)
+{
+ u8 val = inb(addr);
+ val |= mask;
+ outb(val, addr);
+}
+
+static inline void ts5500_clear_mask(u8 mask, u8 addr)
+{
+ u8 val = inb(addr);
+ val &= ~mask;
+ outb(val, addr);
+}
+
+static int ts5500_gpio_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct ts5500_priv *priv = ts5500_gc_to_priv(chip);
+ const struct ts5500_dio line = priv->pinout[offset];
+ unsigned long flags;
+
+ if (line.no_input)
+ return -ENXIO;
+
+ if (line.no_output)
+ return 0;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ts5500_clear_mask(line.control_mask, line.control_addr);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+static int ts5500_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct ts5500_priv *priv = ts5500_gc_to_priv(chip);
+ const struct ts5500_dio line = priv->pinout[offset];
+
+ return !!(inb(line.value_addr) & line.value_mask);
+}
+
+static int ts5500_gpio_output(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct ts5500_priv *priv = ts5500_gc_to_priv(chip);
+ const struct ts5500_dio line = priv->pinout[offset];
+ unsigned long flags;
+
+ if (line.no_output)
+ return -ENXIO;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (!line.no_input)
+ ts5500_set_mask(line.control_mask, line.control_addr);
+
+ if (val)
+ ts5500_set_mask(line.value_mask, line.value_addr);
+ else
+ ts5500_clear_mask(line.value_mask, line.value_addr);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+static void ts5500_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct ts5500_priv *priv = ts5500_gc_to_priv(chip);
+ const struct ts5500_dio line = priv->pinout[offset];
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (val)
+ ts5500_set_mask(line.value_mask, line.value_addr);
+ else
+ ts5500_clear_mask(line.value_mask, line.value_addr);
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int ts5500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct ts5500_priv *priv = ts5500_gc_to_priv(chip);
+ const struct ts5500_dio *block = priv->pinout;
+ const struct ts5500_dio line = block[offset];
+
+ /* Only one pin is connected to an interrupt */
+ if (line.irq)
+ return line.irq;
+
+ /* As this pin is input-only, we may strap it to another in/out pin */
+ if (priv->strap)
+ return priv->hwirq;
+
+ return -ENXIO;
+}
+
+static int ts5500_enable_irq(struct ts5500_priv *priv)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->hwirq == 7)
+ ts5500_set_mask(BIT(7), 0x7a); /* DIO1_13 on IRQ7 */
+ else if (priv->hwirq == 6)
+ ts5500_set_mask(BIT(7), 0x7d); /* DIO2_13 on IRQ6 */
+ else if (priv->hwirq == 1)
+ ts5500_set_mask(BIT(6), 0x7d); /* LCD_RS on IRQ1 */
+ else
+ ret = -EINVAL;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return ret;
+}
+
+static void ts5500_disable_irq(struct ts5500_priv *priv)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->hwirq == 7)
+ ts5500_clear_mask(BIT(7), 0x7a); /* DIO1_13 on IRQ7 */
+ else if (priv->hwirq == 6)
+ ts5500_clear_mask(BIT(7), 0x7d); /* DIO2_13 on IRQ6 */
+ else if (priv->hwirq == 1)
+ ts5500_clear_mask(BIT(6), 0x7d); /* LCD_RS on IRQ1 */
+ else
+ dev_err(priv->gpio_chip.dev, "invalid hwirq %d\n", priv->hwirq);
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int __devinit ts5500_dio_probe(struct platform_device *pdev)
+{
+ enum ts5500_blocks block = platform_get_device_id(pdev)->driver_data;
+ struct ts5500_dio_platform_data *pdata = pdev->dev.platform_data;
+ struct device *dev = &pdev->dev;
+ const char *name = dev_name(dev);
+ struct ts5500_priv *priv;
+ struct resource *res;
+ unsigned long flags;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_err(dev, "missing IRQ resource\n");
+ return -EINVAL;
+ }
+
+ priv = devm_kzalloc(dev, sizeof(struct ts5500_priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, priv);
+ priv->hwirq = res->start;
+ spin_lock_init(&priv->lock);
+
+ priv->gpio_chip.owner = THIS_MODULE;
+ priv->gpio_chip.label = name;
+ priv->gpio_chip.dev = dev;
+ priv->gpio_chip.direction_input = ts5500_gpio_input;
+ priv->gpio_chip.direction_output = ts5500_gpio_output;
+ priv->gpio_chip.get = ts5500_gpio_get;
+ priv->gpio_chip.set = ts5500_gpio_set;
+ priv->gpio_chip.to_irq = ts5500_gpio_to_irq;
+ priv->gpio_chip.base = -1;
+ if (pdata) {
+ priv->gpio_chip.base = pdata->base;
+ priv->strap = pdata->strap;
+ }
+
+ switch (block) {
+ case TS5500_DIO1:
+ priv->pinout = ts5500_dio1;
+ priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_dio1);
+
+ if (!devm_request_region(dev, 0x7a, 3, name)) {
+ dev_err(dev, "failed to request %s ports\n", name);
+ return -EBUSY;
+ }
+ break;
+ case TS5500_DIO2:
+ priv->pinout = ts5500_dio2;
+ priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_dio2);
+
+ if (!devm_request_region(dev, 0x7e, 2, name)) {
+ dev_err(dev, "failed to request %s ports\n", name);
+ return -EBUSY;
+ }
+
+ if (hex7d_reserved)
+ break;
+
+ if (!devm_request_region(dev, 0x7d, 1, name)) {
+ dev_err(dev, "failed to request %s 7D\n", name);
+ return -EBUSY;
+ }
+
+ hex7d_reserved = true;
+ break;
+ case TS5500_LCD:
+ case TS5600_LCD:
+ priv->pinout = ts5500_lcd;
+ priv->gpio_chip.ngpio = ARRAY_SIZE(ts5500_lcd);
+
+ if (!devm_request_region(dev, 0x72, 2, name)) {
+ dev_err(dev, "failed to request %s ports\n", name);
+ return -EBUSY;
+ }
+
+ if (!hex7d_reserved) {
+ if (!devm_request_region(dev, 0x7d, 1, name)) {
+ dev_err(dev, "failed to request %s 7D\n", name);
+ return -EBUSY;
+ }
+
+ hex7d_reserved = true;
+ }
+
+ /* Ensure usage of LCD port as DIO */
+ spin_lock_irqsave(&priv->lock, flags);
+ ts5500_clear_mask(BIT(4), 0x7d);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ break;
+ }
+
+ ret = gpiochip_add(&priv->gpio_chip);
+ if (ret) {
+ dev_err(dev, "failed to register the gpio chip\n");
+ return ret;
+ }
+
+ ret = ts5500_enable_irq(priv);
+ if (ret) {
+ dev_err(dev, "invalid interrupt %d\n", priv->hwirq);
+ goto cleanup;
+ }
+
+ return 0;
+cleanup:
+ if (gpiochip_remove(&priv->gpio_chip))
+ dev_err(dev, "failed to remove gpio chip\n");
+ return ret;
+}
+
+static int __devexit ts5500_dio_remove(struct platform_device *pdev)
+{
+ struct ts5500_priv *priv = platform_get_drvdata(pdev);
+
+ ts5500_disable_irq(priv);
+ return gpiochip_remove(&priv->gpio_chip);
+}
+
+static struct platform_device_id ts5500_dio_ids[] = {
+ { "ts5500-dio1", TS5500_DIO1 },
+ { "ts5500-dio2", TS5500_DIO2 },
+ { "ts5500-dio-lcd", TS5500_LCD },
+ { "ts5600-dio-lcd", TS5600_LCD },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, ts5500_dio_ids);
+
+static struct platform_driver ts5500_dio_driver = {
+ .driver = {
+ .name = "ts5500-dio",
+ .owner = THIS_MODULE,
+ },
+ .probe = ts5500_dio_probe,
+ .remove = __devexit_p(ts5500_dio_remove),
+ .id_table = ts5500_dio_ids,
+};
+
+module_platform_driver(ts5500_dio_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Savoir-faire Linux Inc. <kernel@savoirfairelinux.com>");
+MODULE_DESCRIPTION("Technologic Systems TS-5500 Digital I/O driver");
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index c5f8ca233e1..00329f2fc05 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -88,11 +88,15 @@ static inline int gpio_twl4030_write(u8 address, u8 data)
/*----------------------------------------------------------------------*/
/*
- * LED register offsets (use TWL4030_MODULE_{LED,PWMA,PWMB}))
+ * LED register offsets from TWL_MODULE_LED base
* PWMs A and B are dedicated to LEDs A and B, respectively.
*/
-#define TWL4030_LED_LEDEN 0x0
+#define TWL4030_LED_LEDEN_REG 0x00
+#define TWL4030_PWMAON_REG 0x01
+#define TWL4030_PWMAOFF_REG 0x02
+#define TWL4030_PWMBON_REG 0x03
+#define TWL4030_PWMBOFF_REG 0x04
/* LEDEN bits */
#define LEDEN_LEDAON BIT(0)
@@ -104,9 +108,6 @@ static inline int gpio_twl4030_write(u8 address, u8 data)
#define LEDEN_PWM_LENGTHA BIT(6)
#define LEDEN_PWM_LENGTHB BIT(7)
-#define TWL4030_PWMx_PWMxON 0x0
-#define TWL4030_PWMx_PWMxOFF 0x1
-
#define PWMxON_LENGTH BIT(7)
/*----------------------------------------------------------------------*/
@@ -145,7 +146,7 @@ static void twl4030_led_set_value(int led, int value)
else
cached_leden |= mask;
status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden,
- TWL4030_LED_LEDEN);
+ TWL4030_LED_LEDEN_REG);
mutex_unlock(&gpio_lock);
}
@@ -216,33 +217,33 @@ static int twl_request(struct gpio_chip *chip, unsigned offset)
if (offset >= TWL4030_GPIO_MAX) {
u8 ledclr_mask = LEDEN_LEDAON | LEDEN_LEDAEXT
| LEDEN_LEDAPWM | LEDEN_PWM_LENGTHA;
- u8 module = TWL4030_MODULE_PWMA;
+ u8 reg = TWL4030_PWMAON_REG;
offset -= TWL4030_GPIO_MAX;
if (offset) {
ledclr_mask <<= 1;
- module = TWL4030_MODULE_PWMB;
+ reg = TWL4030_PWMBON_REG;
}
/* initialize PWM to always-drive */
- status = twl_i2c_write_u8(module, 0x7f,
- TWL4030_PWMx_PWMxOFF);
+ /* Configure PWM OFF register first */
+ status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg + 1);
if (status < 0)
goto done;
- status = twl_i2c_write_u8(module, 0x7f,
- TWL4030_PWMx_PWMxON);
+
+ /* Followed by PWM ON register */
+ status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg);
if (status < 0)
goto done;
/* init LED to not-driven (high) */
- module = TWL4030_MODULE_LED;
- status = twl_i2c_read_u8(module, &cached_leden,
- TWL4030_LED_LEDEN);
+ status = twl_i2c_read_u8(TWL4030_MODULE_LED, &cached_leden,
+ TWL4030_LED_LEDEN_REG);
if (status < 0)
goto done;
cached_leden &= ~ledclr_mask;
- status = twl_i2c_write_u8(module, cached_leden,
- TWL4030_LED_LEDEN);
+ status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden,
+ TWL4030_LED_LEDEN_REG);
if (status < 0)
goto done;
@@ -352,7 +353,7 @@ static struct gpio_chip twl_gpiochip = {
/*----------------------------------------------------------------------*/
-static int __devinit gpio_twl4030_pulls(u32 ups, u32 downs)
+static int gpio_twl4030_pulls(u32 ups, u32 downs)
{
u8 message[6];
unsigned i, gpio_bit;
@@ -377,7 +378,7 @@ static int __devinit gpio_twl4030_pulls(u32 ups, u32 downs)
REG_GPIOPUPDCTR1, 5);
}
-static int __devinit gpio_twl4030_debounce(u32 debounce, u8 mmc_cd)
+static int gpio_twl4030_debounce(u32 debounce, u8 mmc_cd)
{
u8 message[4];
@@ -419,7 +420,7 @@ static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev)
return omap_twl_info;
}
-static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
+static int gpio_twl4030_probe(struct platform_device *pdev)
{
struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
struct device_node *node = pdev->dev.of_node;
@@ -505,7 +506,7 @@ out:
return ret;
}
-/* Cannot use __devexit as gpio_twl4030_probe() calls us */
+/* Cannot use as gpio_twl4030_probe() calls us */
static int gpio_twl4030_remove(struct platform_device *pdev)
{
struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
diff --git a/drivers/gpio/gpio-twl6040.c b/drivers/gpio/gpio-twl6040.c
index dd58e8b2504..0be82c6dd79 100644
--- a/drivers/gpio/gpio-twl6040.c
+++ b/drivers/gpio/gpio-twl6040.c
@@ -82,7 +82,7 @@ static struct gpio_chip twl6040gpo_chip = {
/*----------------------------------------------------------------------*/
-static int __devinit gpo_twl6040_probe(struct platform_device *pdev)
+static int gpo_twl6040_probe(struct platform_device *pdev)
{
struct twl6040_gpo_data *pdata = pdev->dev.platform_data;
struct device *twl6040_core_dev = pdev->dev.parent;
@@ -113,7 +113,7 @@ static int __devinit gpo_twl6040_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit gpo_twl6040_remove(struct platform_device *pdev)
+static int gpo_twl6040_remove(struct platform_device *pdev)
{
return gpiochip_remove(&twl6040gpo_chip);
}
diff --git a/drivers/gpio/gpio-vr41xx.c b/drivers/gpio/gpio-vr41xx.c
index 82d5c20ad3c..9902732a382 100644
--- a/drivers/gpio/gpio-vr41xx.c
+++ b/drivers/gpio/gpio-vr41xx.c
@@ -490,7 +490,7 @@ static struct gpio_chip vr41xx_gpio_chip = {
.to_irq = vr41xx_gpio_to_irq,
};
-static int __devinit giu_probe(struct platform_device *pdev)
+static int giu_probe(struct platform_device *pdev)
{
struct resource *res;
unsigned int trigger, i, pin;
@@ -552,7 +552,7 @@ static int __devinit giu_probe(struct platform_device *pdev)
return cascade_irq(irq, giu_get_irq);
}
-static int __devexit giu_remove(struct platform_device *pdev)
+static int giu_remove(struct platform_device *pdev)
{
if (giu_base) {
iounmap(giu_base);
@@ -564,7 +564,7 @@ static int __devexit giu_remove(struct platform_device *pdev)
static struct platform_driver giu_device_driver = {
.probe = giu_probe,
- .remove = __devexit_p(giu_remove),
+ .remove = giu_remove,
.driver = {
.name = "GIU",
.owner = THIS_MODULE,
diff --git a/drivers/gpio/gpio-vt8500.c b/drivers/gpio/gpio-vt8500.c
index bcd8e4aa7c7..b53320a16fc 100644
--- a/drivers/gpio/gpio-vt8500.c
+++ b/drivers/gpio/gpio-vt8500.c
@@ -96,6 +96,7 @@ static struct vt8500_gpio_data wm8505_data = {
VT8500_BANK(0x5C, 0x84, 0xAC, 0xD4, 12),
VT8500_BANK(0x60, 0x88, 0xB0, 0xD8, 16),
VT8500_BANK(0x64, 0x8C, 0xB4, 0xDC, 22),
+ VT8500_BANK(0x500, 0x504, 0x508, 0x50C, 6),
},
};
@@ -115,6 +116,7 @@ static struct vt8500_gpio_data wm8650_data = {
VT8500_BANK(0x58, 0x98, 0xD8, 0x18, 32),
VT8500_BANK(0x5C, 0x9C, 0xDC, 0x1C, 32),
VT8500_BANK(0x7C, 0xBC, 0xFC, 0x3C, 32),
+ VT8500_BANK(0x500, 0x504, 0x508, 0x50C, 6),
},
};
@@ -269,7 +271,7 @@ static struct of_device_id vt8500_gpio_dt_ids[] = {
{ /* Sentinel */ },
};
-static int __devinit vt8500_gpio_probe(struct platform_device *pdev)
+static int vt8500_gpio_probe(struct platform_device *pdev)
{
void __iomem *gpio_base;
struct device_node *np;
diff --git a/drivers/gpio/gpio-vx855.c b/drivers/gpio/gpio-vx855.c
index 76ebfe5ff70..2b7252cb242 100644
--- a/drivers/gpio/gpio-vx855.c
+++ b/drivers/gpio/gpio-vx855.c
@@ -219,7 +219,7 @@ static void vx855gpio_gpio_setup(struct vx855_gpio *vg)
}
/* This platform device is ordinarily registered by the vx855 mfd driver */
-static __devinit int vx855gpio_probe(struct platform_device *pdev)
+static int vx855gpio_probe(struct platform_device *pdev)
{
struct resource *res_gpi;
struct resource *res_gpo;
@@ -284,7 +284,7 @@ out_release:
return ret;
}
-static int __devexit vx855gpio_remove(struct platform_device *pdev)
+static int vx855gpio_remove(struct platform_device *pdev)
{
struct vx855_gpio *vg = platform_get_drvdata(pdev);
struct resource *res;
@@ -312,7 +312,7 @@ static struct platform_driver vx855gpio_driver = {
.owner = THIS_MODULE,
},
.probe = vx855gpio_probe,
- .remove = __devexit_p(vx855gpio_remove),
+ .remove = vx855gpio_remove,
};
module_platform_driver(vx855gpio_driver);
diff --git a/drivers/gpio/gpio-wm831x.c b/drivers/gpio/gpio-wm831x.c
index b6eda35089d..2a743e10ecb 100644
--- a/drivers/gpio/gpio-wm831x.c
+++ b/drivers/gpio/gpio-wm831x.c
@@ -243,7 +243,7 @@ static struct gpio_chip template_chip = {
.can_sleep = 1,
};
-static int __devinit wm831x_gpio_probe(struct platform_device *pdev)
+static int wm831x_gpio_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
@@ -275,7 +275,7 @@ static int __devinit wm831x_gpio_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit wm831x_gpio_remove(struct platform_device *pdev)
+static int wm831x_gpio_remove(struct platform_device *pdev)
{
struct wm831x_gpio *wm831x_gpio = platform_get_drvdata(pdev);
@@ -286,7 +286,7 @@ static struct platform_driver wm831x_gpio_driver = {
.driver.name = "wm831x-gpio",
.driver.owner = THIS_MODULE,
.probe = wm831x_gpio_probe,
- .remove = __devexit_p(wm831x_gpio_remove),
+ .remove = wm831x_gpio_remove,
};
static int __init wm831x_gpio_init(void)
diff --git a/drivers/gpio/gpio-wm8350.c b/drivers/gpio/gpio-wm8350.c
index fb429388939..0b598cf3df9 100644
--- a/drivers/gpio/gpio-wm8350.c
+++ b/drivers/gpio/gpio-wm8350.c
@@ -109,7 +109,7 @@ static struct gpio_chip template_chip = {
.can_sleep = 1,
};
-static int __devinit wm8350_gpio_probe(struct platform_device *pdev)
+static int wm8350_gpio_probe(struct platform_device *pdev)
{
struct wm8350 *wm8350 = dev_get_drvdata(pdev->dev.parent);
struct wm8350_platform_data *pdata = wm8350->dev->platform_data;
@@ -141,7 +141,7 @@ static int __devinit wm8350_gpio_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit wm8350_gpio_remove(struct platform_device *pdev)
+static int wm8350_gpio_remove(struct platform_device *pdev)
{
struct wm8350_gpio_data *wm8350_gpio = platform_get_drvdata(pdev);
@@ -152,7 +152,7 @@ static struct platform_driver wm8350_gpio_driver = {
.driver.name = "wm8350-gpio",
.driver.owner = THIS_MODULE,
.probe = wm8350_gpio_probe,
- .remove = __devexit_p(wm8350_gpio_remove),
+ .remove = wm8350_gpio_remove,
};
static int __init wm8350_gpio_init(void)
diff --git a/drivers/gpio/gpio-wm8994.c b/drivers/gpio/gpio-wm8994.c
index 1c764e779d8..ae409fd94af 100644
--- a/drivers/gpio/gpio-wm8994.c
+++ b/drivers/gpio/gpio-wm8994.c
@@ -245,7 +245,7 @@ static struct gpio_chip template_chip = {
.can_sleep = 1,
};
-static int __devinit wm8994_gpio_probe(struct platform_device *pdev)
+static int wm8994_gpio_probe(struct platform_device *pdev)
{
struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent);
struct wm8994_pdata *pdata = wm8994->dev->platform_data;
@@ -281,7 +281,7 @@ err:
return ret;
}
-static int __devexit wm8994_gpio_remove(struct platform_device *pdev)
+static int wm8994_gpio_remove(struct platform_device *pdev)
{
struct wm8994_gpio *wm8994_gpio = platform_get_drvdata(pdev);
@@ -292,7 +292,7 @@ static struct platform_driver wm8994_gpio_driver = {
.driver.name = "wm8994-gpio",
.driver.owner = THIS_MODULE,
.probe = wm8994_gpio_probe,
- .remove = __devexit_p(wm8994_gpio_remove),
+ .remove = wm8994_gpio_remove,
};
static int __init wm8994_gpio_init(void)
diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index 79b0fe8a725..9ae7aa8ca48 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -159,7 +159,7 @@ static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
* driver data structure. It returns 0, if the driver is bound to the GPIO
* device, or a negative value if there is an error.
*/
-static int __devinit xgpio_of_probe(struct device_node *np)
+static int xgpio_of_probe(struct device_node *np)
{
struct xgpio_instance *chip;
int status = 0;
@@ -209,7 +209,7 @@ static int __devinit xgpio_of_probe(struct device_node *np)
return 0;
}
-static struct of_device_id xgpio_of_match[] __devinitdata = {
+static struct of_device_id xgpio_of_match[] = {
{ .compatible = "xlnx,xps-gpio-1.00.a", },
{ /* end of list */ },
};
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
new file mode 100644
index 00000000000..cbad6e908d3
--- /dev/null
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -0,0 +1,54 @@
+/*
+ * ACPI helpers for GPIO API
+ *
+ * Copyright (C) 2012, Intel Corporation
+ * Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
+ * Mika Westerberg <mika.westerberg@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/errno.h>
+#include <linux/gpio.h>
+#include <linux/export.h>
+#include <linux/acpi_gpio.h>
+#include <linux/acpi.h>
+
+static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
+{
+ if (!gc->dev)
+ return false;
+
+ return ACPI_HANDLE(gc->dev) == data;
+}
+
+/**
+ * acpi_get_gpio() - Translate ACPI GPIO pin to GPIO number usable with GPIO API
+ * @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
+ * @pin: ACPI GPIO pin number (0-based, controller-relative)
+ *
+ * Returns GPIO number to use with Linux generic GPIO API, or errno error value
+ */
+
+int acpi_get_gpio(char *path, int pin)
+{
+ struct gpio_chip *chip;
+ acpi_handle handle;
+ acpi_status status;
+
+ status = acpi_get_handle(NULL, path, &handle);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+
+ chip = gpiochip_find(handle, acpi_gpiochip_find);
+ if (!chip)
+ return -ENODEV;
+
+ if (!gpio_is_valid(chip->base + pin))
+ return -EINVAL;
+
+ return chip->base + pin;
+}
+EXPORT_SYMBOL_GPL(acpi_get_gpio);
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index f1a45997aea..d542a141811 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -19,6 +19,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
+#include <linux/pinctrl/pinctrl.h>
#include <linux/slab.h>
/* Private data structure for of_gpiochip_find_and_xlate */
@@ -216,6 +217,54 @@ err0:
}
EXPORT_SYMBOL(of_mm_gpiochip_add);
+#ifdef CONFIG_PINCTRL
+static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
+{
+ struct device_node *np = chip->of_node;
+ struct of_phandle_args pinspec;
+ struct pinctrl_dev *pctldev;
+ int index = 0, ret;
+
+ if (!np)
+ return;
+
+ do {
+ ret = of_parse_phandle_with_args(np, "gpio-ranges",
+ "#gpio-range-cells", index, &pinspec);
+ if (ret)
+ break;
+
+ pctldev = of_pinctrl_get(pinspec.np);
+ if (!pctldev)
+ break;
+
+ /*
+ * This assumes that the n GPIO pins are consecutive in the
+ * GPIO number space, and that the pins are also consecutive
+ * in their local number space. Currently it is not possible
+ * to add different ranges for one and the same GPIO chip,
+ * as the code assumes that we have one consecutive range
+ * on both, mapping 1-to-1.
+ *
+ * TODO: make the OF bindings handle multiple sparse ranges
+ * on the same GPIO chip.
+ */
+ ret = gpiochip_add_pin_range(chip,
+ pinctrl_dev_get_name(pctldev),
+ 0, /* offset in gpiochip */
+ pinspec.args[0],
+ pinspec.args[1]);
+
+ if (ret)
+ break;
+
+ } while (index++);
+}
+
+#else
+static void of_gpiochip_add_pin_range(struct gpio_chip *chip) {}
+#endif
+
void of_gpiochip_add(struct gpio_chip *chip)
{
if ((!chip->of_node) && (chip->dev))
@@ -229,11 +278,14 @@ void of_gpiochip_add(struct gpio_chip *chip)
chip->of_xlate = of_gpio_simple_xlate;
}
+ of_gpiochip_add_pin_range(chip);
of_node_get(chip->of_node);
}
void of_gpiochip_remove(struct gpio_chip *chip)
{
+ gpiochip_remove_pin_ranges(chip);
+
if (chip->of_node)
of_node_put(chip->of_node);
}
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 1c8d9e3380e..199fca15f27 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -191,6 +191,32 @@ err:
return ret;
}
+/* caller ensures gpio is valid and requested, chip->get_direction may sleep */
+static int gpio_get_direction(unsigned gpio)
+{
+ struct gpio_chip *chip;
+ struct gpio_desc *desc = &gpio_desc[gpio];
+ int status = -EINVAL;
+
+ chip = gpio_to_chip(gpio);
+ gpio -= chip->base;
+
+ if (!chip->get_direction)
+ return status;
+
+ status = chip->get_direction(chip, gpio);
+ if (status > 0) {
+ /* GPIOF_DIR_IN, or other positive */
+ status = 1;
+ clear_bit(FLAG_IS_OUT, &desc->flags);
+ }
+ if (status == 0) {
+ /* GPIOF_DIR_OUT */
+ set_bit(FLAG_IS_OUT, &desc->flags);
+ }
+ return status;
+}
+
#ifdef CONFIG_GPIO_SYSFS
/* lock protects against unexport_gpio() being called while
@@ -223,6 +249,7 @@ static ssize_t gpio_direction_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
const struct gpio_desc *desc = dev_get_drvdata(dev);
+ unsigned gpio = desc - gpio_desc;
ssize_t status;
mutex_lock(&sysfs_lock);
@@ -230,6 +257,7 @@ static ssize_t gpio_direction_show(struct device *dev,
if (!test_bit(FLAG_EXPORT, &desc->flags))
status = -EIO;
else
+ gpio_get_direction(gpio);
status = sprintf(buf, "%s\n",
test_bit(FLAG_IS_OUT, &desc->flags)
? "out" : "in");
@@ -704,8 +732,9 @@ int gpio_export(unsigned gpio, bool direction_may_change)
{
unsigned long flags;
struct gpio_desc *desc;
- int status = -EINVAL;
+ int status;
const char *ioname = NULL;
+ struct device *dev;
/* can't export until sysfs is available ... */
if (!gpio_class.p) {
@@ -713,59 +742,66 @@ int gpio_export(unsigned gpio, bool direction_may_change)
return -ENOENT;
}
- if (!gpio_is_valid(gpio))
- goto done;
+ if (!gpio_is_valid(gpio)) {
+ pr_debug("%s: gpio %d is not valid\n", __func__, gpio);
+ return -EINVAL;
+ }
mutex_lock(&sysfs_lock);
spin_lock_irqsave(&gpio_lock, flags);
desc = &gpio_desc[gpio];
- if (test_bit(FLAG_REQUESTED, &desc->flags)
- && !test_bit(FLAG_EXPORT, &desc->flags)) {
- status = 0;
- if (!desc->chip->direction_input
- || !desc->chip->direction_output)
- direction_may_change = false;
+ if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
+ test_bit(FLAG_EXPORT, &desc->flags)) {
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ pr_debug("%s: gpio %d unavailable (requested=%d, exported=%d)\n",
+ __func__, gpio,
+ test_bit(FLAG_REQUESTED, &desc->flags),
+ test_bit(FLAG_EXPORT, &desc->flags));
+ status = -EPERM;
+ goto fail_unlock;
}
+
+ if (!desc->chip->direction_input || !desc->chip->direction_output)
+ direction_may_change = false;
spin_unlock_irqrestore(&gpio_lock, flags);
if (desc->chip->names && desc->chip->names[gpio - desc->chip->base])
ioname = desc->chip->names[gpio - desc->chip->base];
- if (status == 0) {
- struct device *dev;
-
- dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
- desc, ioname ? ioname : "gpio%u", gpio);
- if (!IS_ERR(dev)) {
- status = sysfs_create_group(&dev->kobj,
- &gpio_attr_group);
-
- if (!status && direction_may_change)
- status = device_create_file(dev,
- &dev_attr_direction);
-
- if (!status && gpio_to_irq(gpio) >= 0
- && (direction_may_change
- || !test_bit(FLAG_IS_OUT,
- &desc->flags)))
- status = device_create_file(dev,
- &dev_attr_edge);
-
- if (status != 0)
- device_unregister(dev);
- } else
- status = PTR_ERR(dev);
- if (status == 0)
- set_bit(FLAG_EXPORT, &desc->flags);
+ dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
+ desc, ioname ? ioname : "gpio%u", gpio);
+ if (IS_ERR(dev)) {
+ status = PTR_ERR(dev);
+ goto fail_unlock;
}
- mutex_unlock(&sysfs_lock);
-
-done:
+ status = sysfs_create_group(&dev->kobj, &gpio_attr_group);
if (status)
- pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
+ goto fail_unregister_device;
+
+ if (direction_may_change) {
+ status = device_create_file(dev, &dev_attr_direction);
+ if (status)
+ goto fail_unregister_device;
+ }
+
+ if (gpio_to_irq(gpio) >= 0 && (direction_may_change ||
+ !test_bit(FLAG_IS_OUT, &desc->flags))) {
+ status = device_create_file(dev, &dev_attr_edge);
+ if (status)
+ goto fail_unregister_device;
+ }
+
+ set_bit(FLAG_EXPORT, &desc->flags);
+ mutex_unlock(&sysfs_lock);
+ return 0;
+fail_unregister_device:
+ device_unregister(dev);
+fail_unlock:
+ mutex_unlock(&sysfs_lock);
+ pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
return status;
}
EXPORT_SYMBOL_GPL(gpio_export);
@@ -1075,6 +1111,7 @@ int gpiochip_add(struct gpio_chip *chip)
* inputs (often with pullups enabled) so power
* usage is minimized. Linux code should set the
* gpio direction first thing; but until it does,
+ * and in case chip->get_direction is not set,
* we may expose the wrong direction in sysfs.
*/
gpio_desc[id].flags = !chip->direction_input
@@ -1083,6 +1120,10 @@ int gpiochip_add(struct gpio_chip *chip)
}
}
+#ifdef CONFIG_PINCTRL
+ INIT_LIST_HEAD(&chip->pin_ranges);
+#endif
+
of_gpiochip_add(chip);
unlock:
@@ -1123,6 +1164,7 @@ int gpiochip_remove(struct gpio_chip *chip)
spin_lock_irqsave(&gpio_lock, flags);
+ gpiochip_remove_pin_ranges(chip);
of_gpiochip_remove(chip);
for (id = chip->base; id < chip->base + chip->ngpio; id++) {
@@ -1180,6 +1222,77 @@ struct gpio_chip *gpiochip_find(void *data,
}
EXPORT_SYMBOL_GPL(gpiochip_find);
+#ifdef CONFIG_PINCTRL
+
+/**
+ * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping
+ * @chip: the gpiochip to add the range for
+ * @pinctrl_name: the dev_name() of the pin controller to map to
+ * @gpio_offset: the start offset in the current gpio_chip number space
+ * @pin_offset: the start offset in the pin controller number space
+ * @npins: the number of pins from the offset of each pin space (GPIO and
+ * pin controller) to accumulate in this range
+ */
+int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
+ unsigned int gpio_offset, unsigned int pin_offset,
+ unsigned int npins)
+{
+ struct gpio_pin_range *pin_range;
+ int ret;
+
+ pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL);
+ if (!pin_range) {
+ pr_err("%s: GPIO chip: failed to allocate pin ranges\n",
+ chip->label);
+ return -ENOMEM;
+ }
+
+ /* Use local offset as range ID */
+ pin_range->range.id = gpio_offset;
+ pin_range->range.gc = chip;
+ pin_range->range.name = chip->label;
+ pin_range->range.base = chip->base + gpio_offset;
+ pin_range->range.pin_base = pin_offset;
+ pin_range->range.npins = npins;
+ pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name,
+ &pin_range->range);
+ if (IS_ERR(pin_range->pctldev)) {
+ ret = PTR_ERR(pin_range->pctldev);
+ pr_err("%s: GPIO chip: could not create pin range\n",
+ chip->label);
+ kfree(pin_range);
+ return ret;
+ }
+ pr_debug("GPIO chip %s: created GPIO range %d->%d ==> %s PIN %d->%d\n",
+ chip->label, gpio_offset, gpio_offset + npins - 1,
+ pinctl_name,
+ pin_offset, pin_offset + npins - 1);
+
+ list_add_tail(&pin_range->node, &chip->pin_ranges);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gpiochip_add_pin_range);
+
+/**
+ * gpiochip_remove_pin_ranges() - remove all the GPIO <-> pin mappings
+ * @chip: the chip to remove all the mappings for
+ */
+void gpiochip_remove_pin_ranges(struct gpio_chip *chip)
+{
+ struct gpio_pin_range *pin_range, *tmp;
+
+ list_for_each_entry_safe(pin_range, tmp, &chip->pin_ranges, node) {
+ list_del(&pin_range->node);
+ pinctrl_remove_gpio_range(pin_range->pctldev,
+ &pin_range->range);
+ kfree(pin_range);
+ }
+}
+EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges);
+
+#endif /* CONFIG_PINCTRL */
+
/* These "optional" allocation calls help prevent drivers from stomping
* on each other, and help provide better diagnostics in debugfs.
* They're called even less than the "set direction" calls.
@@ -1228,9 +1341,15 @@ int gpio_request(unsigned gpio, const char *label)
desc_set_label(desc, NULL);
module_put(chip->owner);
clear_bit(FLAG_REQUESTED, &desc->flags);
+ goto done;
}
}
-
+ if (chip->get_direction) {
+ /* chip->get_direction may sleep */
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ gpio_get_direction(gpio);
+ spin_lock_irqsave(&gpio_lock, flags);
+ }
done:
if (status)
pr_debug("gpio_request: gpio-%d (%s) status %d\n",
@@ -1766,6 +1885,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
if (!test_bit(FLAG_REQUESTED, &gdesc->flags))
continue;
+ gpio_get_direction(gpio);
is_out = test_bit(FLAG_IS_OUT, &gdesc->flags);
seq_printf(s, " gpio-%-3d (%-20.20s) %s %s",
gpio, gdesc->label,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index 241ad1eeec6..f2df06c603f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -226,6 +226,12 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
* already updated or not by exynos_drm_encoder_dpms function.
*/
exynos_encoder->updated = true;
+
+ /*
+ * In case of setcrtc, there is no way to update encoder's dpms
+ * so update it here.
+ */
+ exynos_encoder->dpms = DRM_MODE_DPMS_ON;
}
static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
@@ -507,6 +513,6 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data)
* because the setting for disabling the overlay will be updated
* at vsync.
*/
- if (overlay_ops->wait_for_vblank)
+ if (overlay_ops && overlay_ops->wait_for_vblank)
overlay_ops->wait_for_vblank(manager->dev);
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 67eb6ba56ed..e7466c4414c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -87,7 +87,8 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr;
fbi->screen_base = buffer->kvaddr + offset;
- fbi->fix.smem_start = (unsigned long)(buffer->dma_addr + offset);
+ fbi->fix.smem_start = (unsigned long)(page_to_phys(buffer->pages[0]) +
+ offset);
fbi->screen_size = size;
fbi->fix.smem_len = size;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 130a2b510d4..e08478f19f1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -61,11 +61,11 @@ struct fimd_driver_data {
unsigned int timing_base;
};
-struct fimd_driver_data exynos4_fimd_driver_data = {
+static struct fimd_driver_data exynos4_fimd_driver_data = {
.timing_base = 0x0,
};
-struct fimd_driver_data exynos5_fimd_driver_data = {
+static struct fimd_driver_data exynos5_fimd_driver_data = {
.timing_base = 0x20000,
};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 60b877a388c..862ca1eb210 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -204,7 +204,6 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
return ret;
plane->crtc = crtc;
- plane->fb = crtc->fb;
exynos_plane_commit(plane);
exynos_plane_dpms(plane, DRM_MODE_DPMS_ON);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 107f09befe9..9b285da4449 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1796,7 +1796,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
*/
mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
gfp = mapping_gfp_mask(mapping);
- gfp |= __GFP_NORETRY | __GFP_NOWARN;
+ gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD;
gfp &= ~(__GFP_IO | __GFP_WAIT);
for_each_sg(st->sgl, sg, page_count, i) {
page = shmem_read_mapping_page_gfp(mapping, i, gfp);
@@ -1809,7 +1809,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
* our own buffer, now let the real VM do its job and
* go down in flames if truly OOM.
*/
- gfp &= ~(__GFP_NORETRY | __GFP_NOWARN);
+ gfp &= ~(__GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD);
gfp |= __GFP_IO | __GFP_WAIT;
i915_gem_shrink_all(dev_priv);
@@ -1817,7 +1817,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
if (IS_ERR(page))
goto err_pages;
- gfp |= __GFP_NORETRY | __GFP_NOWARN;
+ gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD;
gfp &= ~(__GFP_IO | __GFP_WAIT);
}
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 0ed6baff4b0..56846ed5ee5 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -499,12 +499,8 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
edp = find_section(bdb, BDB_EDP);
if (!edp) {
- if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) {
- DRM_DEBUG_KMS("No eDP BDB found but eDP panel "
- "supported, assume %dbpp panel color "
- "depth.\n",
- dev_priv->edp.bpp);
- }
+ if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support)
+ DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n");
return;
}
@@ -657,9 +653,6 @@ init_vbt_defaults(struct drm_i915_private *dev_priv)
dev_priv->lvds_use_ssc = 1;
dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1);
DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq);
-
- /* eDP data */
- dev_priv->edp.bpp = 18;
}
static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id)
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index b726b478a4f..6345878ae1e 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -143,7 +143,7 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode)
int old_dpms;
/* PCH platforms and VLV only support on/off. */
- if (INTEL_INFO(dev)->gen < 5 && mode != DRM_MODE_DPMS_ON)
+ if (INTEL_INFO(dev)->gen >= 5 && mode != DRM_MODE_DPMS_ON)
mode = DRM_MODE_DPMS_OFF;
if (mode == connector->dpms)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 461a637f1ef..b426d44a2b0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3841,6 +3841,17 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
}
}
+ if (intel_encoder->type == INTEL_OUTPUT_EDP) {
+ /* Use VBT settings if we have an eDP panel */
+ unsigned int edp_bpc = dev_priv->edp.bpp / 3;
+
+ if (edp_bpc && edp_bpc < display_bpc) {
+ DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
+ display_bpc = edp_bpc;
+ }
+ continue;
+ }
+
/*
* HDMI is either 12 or 8, so if the display lets 10bpc sneak
* through, clamp it down. (Note: >12bpc will be caught below.)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 72f41aaa71f..442968f8b20 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2373,15 +2373,9 @@ int intel_enable_rc6(const struct drm_device *dev)
if (i915_enable_rc6 >= 0)
return i915_enable_rc6;
- if (INTEL_INFO(dev)->gen == 5) {
-#ifdef CONFIG_INTEL_IOMMU
- /* Disable rc6 on ilk if VT-d is on. */
- if (intel_iommu_gfx_mapped)
- return false;
-#endif
- DRM_DEBUG_DRIVER("Ironlake: only RC6 available\n");
- return INTEL_RC6_ENABLE;
- }
+ /* Disable RC6 on Ironlake */
+ if (INTEL_INFO(dev)->gen == 5)
+ return 0;
if (IS_HASWELL(dev)) {
DRM_DEBUG_DRIVER("Haswell: only RC6 available\n");
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 79d308da29f..a6ac0b41696 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2201,7 +2201,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
intel_sdvo->is_hdmi = true;
}
- intel_sdvo->base.cloneable = true;
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
if (intel_sdvo->is_hdmi)
@@ -2232,7 +2231,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
intel_sdvo->is_tv = true;
intel_sdvo->base.needs_tv_clock = true;
- intel_sdvo->base.cloneable = false;
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
@@ -2275,8 +2273,6 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
}
- intel_sdvo->base.cloneable = true;
-
intel_sdvo_connector_init(intel_sdvo_connector,
intel_sdvo);
return true;
@@ -2307,9 +2303,6 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
}
- /* SDVO LVDS is not cloneable because the input mode gets adjusted by the encoder */
- intel_sdvo->base.cloneable = false;
-
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
goto err;
@@ -2382,6 +2375,18 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags)
return true;
}
+static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo)
+{
+ struct drm_device *dev = intel_sdvo->base.base.dev;
+ struct drm_connector *connector, *tmp;
+
+ list_for_each_entry_safe(connector, tmp,
+ &dev->mode_config.connector_list, head) {
+ if (intel_attached_encoder(connector) == &intel_sdvo->base)
+ intel_sdvo_destroy(connector);
+ }
+}
+
static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
struct intel_sdvo_connector *intel_sdvo_connector,
int type)
@@ -2705,9 +2710,20 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
intel_sdvo->caps.output_flags) != true) {
DRM_DEBUG_KMS("SDVO output failed to setup on %s\n",
SDVO_NAME(intel_sdvo));
- goto err;
+ /* Output_setup can leave behind connectors! */
+ goto err_output;
}
+ /*
+ * Cloning SDVO with anything is often impossible, since the SDVO
+ * encoder can request a special input timing mode. And even if that's
+ * not the case we have evidence that cloning a plain unscaled mode with
+ * VGA doesn't really work. Furthermore the cloning flags are way too
+ * simplistic anyway to express such constraints, so just give up on
+ * cloning for SDVO encoders.
+ */
+ intel_sdvo->base.cloneable = false;
+
/* Only enable the hotplug irq if we need it, to work around noisy
* hotplug lines.
*/
@@ -2718,12 +2734,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
/* Set the input timing to the screen. Assume always input 0. */
if (!intel_sdvo_set_target_input(intel_sdvo))
- goto err;
+ goto err_output;
if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo,
&intel_sdvo->pixel_clock_min,
&intel_sdvo->pixel_clock_max))
- goto err;
+ goto err_output;
DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, "
"clock range %dMHz - %dMHz, "
@@ -2743,6 +2759,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
(SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
return true;
+err_output:
+ intel_sdvo_output_cleanup(intel_sdvo);
+
err:
drm_encoder_cleanup(&intel_encoder->base);
i2c_del_adapter(&intel_sdvo->ddc);
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
index 05a909a17ce..15b182c84ce 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
@@ -49,13 +49,7 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
if (chan->vblank.crtc != crtc)
continue;
- if (nv_device(priv)->chipset == 0x50) {
- nv_wr32(priv, 0x001704, chan->vblank.channel);
- nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
- bar->flush(bar);
- nv_wr32(priv, 0x001570, chan->vblank.offset);
- nv_wr32(priv, 0x001574, chan->vblank.value);
- } else {
+ if (nv_device(priv)->chipset >= 0xc0) {
nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel);
bar->flush(bar);
nv_wr32(priv, 0x06000c,
@@ -63,6 +57,17 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
nv_wr32(priv, 0x060010,
lower_32_bits(chan->vblank.offset));
nv_wr32(priv, 0x060014, chan->vblank.value);
+ } else {
+ nv_wr32(priv, 0x001704, chan->vblank.channel);
+ nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
+ bar->flush(bar);
+ if (nv_device(priv)->chipset == 0x50) {
+ nv_wr32(priv, 0x001570, chan->vblank.offset);
+ nv_wr32(priv, 0x001574, chan->vblank.value);
+ } else {
+ nv_wr32(priv, 0x060010, chan->vblank.offset);
+ nv_wr32(priv, 0x060014, chan->vblank.value);
+ }
}
list_del(&chan->vblank.head);
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c
index e45035efb8c..7bbb1e1b7a8 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c
@@ -669,21 +669,27 @@ nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem)
});
}
-void
+int
nv40_grctx_init(struct nouveau_device *device, u32 *size)
{
- u32 ctxprog[256], i;
+ u32 *ctxprog = kmalloc(256 * 4, GFP_KERNEL), i;
struct nouveau_grctx ctx = {
.device = device,
.mode = NOUVEAU_GRCTX_PROG,
.data = ctxprog,
- .ctxprog_max = ARRAY_SIZE(ctxprog)
+ .ctxprog_max = 256,
};
+ if (!ctxprog)
+ return -ENOMEM;
+
nv40_grctx_generate(&ctx);
nv_wr32(device, 0x400324, 0);
for (i = 0; i < ctx.ctxprog_len; i++)
nv_wr32(device, 0x400328, ctxprog[i]);
*size = ctx.ctxvals_pos * 4;
+
+ kfree(ctxprog);
+ return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
index 425001204a8..cc6574eeb80 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
@@ -346,7 +346,9 @@ nv40_graph_init(struct nouveau_object *object)
return ret;
/* generate and upload context program */
- nv40_grctx_init(nv_device(priv), &priv->size);
+ ret = nv40_grctx_init(nv_device(priv), &priv->size);
+ if (ret)
+ return ret;
/* No context present currently */
nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h
index d2ac975afc2..7da35a4e797 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h
@@ -15,7 +15,7 @@ nv44_graph_class(void *priv)
return !(0x0baf & (1 << (device->chipset & 0x0f)));
}
-void nv40_grctx_init(struct nouveau_device *, u32 *size);
+int nv40_grctx_init(struct nouveau_device *, u32 *size);
void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/object.h b/drivers/gpu/drm/nouveau/core/include/core/object.h
index 818feabbf4a..486f1a9217f 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/object.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/object.h
@@ -175,14 +175,18 @@ nv_mo32(void *obj, u32 addr, u32 mask, u32 data)
return temp;
}
-static inline bool
-nv_strncmp(void *obj, u32 addr, u32 len, const char *str)
+static inline int
+nv_memcmp(void *obj, u32 addr, const char *str, u32 len)
{
+ unsigned char c1, c2;
+
while (len--) {
- if (nv_ro08(obj, addr++) != *(str++))
- return false;
+ c1 = nv_ro08(obj, addr++);
+ c2 = *(str++);
+ if (c1 != c2)
+ return c1 - c2;
}
- return true;
+ return 0;
}
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
index 39e73b91d36..41b7a6a76f1 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
@@ -54,6 +54,7 @@ int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
int clk, struct nouveau_pll_vals *);
int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1,
struct nouveau_pll_vals *);
-
+int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
+ int clk, struct nouveau_pll_vals *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
index 7d750382a83..c5119715774 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
@@ -64,7 +64,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
} else
if (*ver >= 0x15) {
- if (!nv_strncmp(bios, dcb - 7, 7, "DEV_REC")) {
+ if (!nv_memcmp(bios, dcb - 7, "DEV_REC", 7)) {
u16 i2c = nv_ro16(bios, dcb + 2);
*hdr = 4;
*cnt = (i2c - dcb) / 10;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
index cc8d7d162d7..9068c98b96f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
@@ -66,6 +66,24 @@ nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
return ret;
}
+int
+nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
+ int clk, struct nouveau_pll_vals *pv)
+{
+ int ret, N, M, P;
+
+ ret = nva3_pll_calc(clock, info, clk, &N, NULL, &M, &P);
+
+ if (ret > 0) {
+ pv->refclk = info->refclk;
+ pv->N1 = N;
+ pv->M1 = M;
+ pv->log2P = P;
+ }
+ return ret;
+}
+
+
static int
nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
@@ -80,6 +98,7 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
priv->base.pll_set = nva3_clock_pll_set;
+ priv->base.pll_calc = nva3_clock_pll_calc;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
index 5ccce0b17bf..f6962c9b6c3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
@@ -79,6 +79,7 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
priv->base.pll_set = nvc0_clock_pll_set;
+ priv->base.pll_calc = nva3_clock_pll_calc;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c
index cc79c796afe..cbf1fc60a38 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -241,6 +241,10 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
if (unlikely(!abi16))
return -ENOMEM;
+
+ if (!drm->channel)
+ return nouveau_abi16_put(abi16, -ENODEV);
+
client = nv_client(abi16->client);
if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 0910125cbbc..8503b2ea570 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -129,7 +129,8 @@ nouveau_accel_init(struct nouveau_drm *drm)
/* initialise synchronisation routines */
if (device->card_type < NV_10) ret = nv04_fence_create(drm);
- else if (device->chipset < 0x84) ret = nv10_fence_create(drm);
+ else if (device->card_type < NV_50) ret = nv10_fence_create(drm);
+ else if (device->chipset < 0x84) ret = nv50_fence_create(drm);
else if (device->card_type < NV_C0) ret = nv84_fence_create(drm);
else ret = nvc0_fence_create(drm);
if (ret) {
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 3bce0299f64..24d932f5320 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1696,42 +1696,22 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
return ATOM_PPLL2;
DRM_ERROR("unable to allocate a PPLL\n");
return ATOM_PPLL_INVALID;
- } else if (ASIC_IS_AVIVO(rdev)) {
- /* in DP mode, the DP ref clock can come from either PPLL
- * depending on the asic:
- * DCE3: PPLL1 or PPLL2
- */
- if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
- /* use the same PPLL for all DP monitors */
- pll = radeon_get_shared_dp_ppll(crtc);
- if (pll != ATOM_PPLL_INVALID)
- return pll;
- } else {
- /* use the same PPLL for all monitors with the same clock */
- pll = radeon_get_shared_nondp_ppll(crtc);
- if (pll != ATOM_PPLL_INVALID)
- return pll;
- }
- /* all other cases */
- pll_in_use = radeon_get_pll_use_mask(crtc);
- /* the order shouldn't matter here, but we probably
- * need this until we have atomic modeset
- */
- if (rdev->flags & RADEON_IS_IGP) {
- if (!(pll_in_use & (1 << ATOM_PPLL1)))
- return ATOM_PPLL1;
- if (!(pll_in_use & (1 << ATOM_PPLL2)))
- return ATOM_PPLL2;
- } else {
- if (!(pll_in_use & (1 << ATOM_PPLL2)))
- return ATOM_PPLL2;
- if (!(pll_in_use & (1 << ATOM_PPLL1)))
- return ATOM_PPLL1;
- }
- DRM_ERROR("unable to allocate a PPLL\n");
- return ATOM_PPLL_INVALID;
} else {
/* on pre-R5xx asics, the crtc to pll mapping is hardcoded */
+ /* some atombios (observed in some DCE2/DCE3) code have a bug,
+ * the matching btw pll and crtc is done through
+ * PCLK_CRTC[1|2]_CNTL (0x480/0x484) but atombios code use the
+ * pll (1 or 2) to select which register to write. ie if using
+ * pll1 it will use PCLK_CRTC1_CNTL (0x480) and if using pll2
+ * it will use PCLK_CRTC2_CNTL (0x484), it then use crtc id to
+ * choose which value to write. Which is reverse order from
+ * register logic. So only case that works is when pllid is
+ * same as crtcid or when both pll and crtc are enabled and
+ * both use same clock.
+ *
+ * So just return crtc id as if crtc and pll were hard linked
+ * together even if they aren't
+ */
return radeon_crtc->crtc_id;
}
}
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
index ba498f8e47a..010bae19554 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -1625,7 +1625,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
/* some early dce3.2 boards have a bug in their transmitter control table */
- if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730))
+ if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730))
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
}
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index af31f829f4a..219942c660d 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1330,6 +1330,8 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
break;
udelay(1);
}
+ } else {
+ save->crtc_enabled[i] = false;
}
}
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c
index 10ea17a6b2a..42433344cb1 100644
--- a/drivers/gpu/drm/radeon/radeon_agp.c
+++ b/drivers/gpu/drm/radeon/radeon_agp.c
@@ -69,9 +69,12 @@ static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = {
/* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/
{ PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59,
PCI_VENDOR_ID_DELL, 0x00e3, 2},
- /* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */
+ /* Intel 82852/82855 host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 (lp #296617) */
{ PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66,
PCI_VENDOR_ID_DELL, 0x0149, 1},
+ /* Intel 82855PM host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 for suspend/resume */
+ { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c66,
+ PCI_VENDOR_ID_IBM, 0x0531, 1},
/* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */
{ PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50,
0x1025, 0x0061, 1},
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
index 860dc4813e9..bd2a3b40cd1 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
@@ -749,7 +749,10 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags,
/* clear the pages coming from the pool if requested */
if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) {
list_for_each_entry(p, &plist, lru) {
- clear_page(page_address(p));
+ if (PageHighMem(p))
+ clear_highpage(p);
+ else
+ clear_page(page_address(p));
}
}
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index bf8260133ea..7d759a43029 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -308,9 +308,7 @@ int ttm_tt_swapin(struct ttm_tt *ttm)
if (unlikely(to_page == NULL))
goto out_err;
- preempt_disable();
copy_highpage(to_page, from_page);
- preempt_enable();
page_cache_release(from_page);
}
@@ -358,9 +356,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
ret = PTR_ERR(to_page);
goto out_err;
}
- preempt_disable();
copy_highpage(to_page, from_page);
- preempt_enable();
set_page_dirty(to_page);
mark_page_accessed(to_page);
page_cache_release(to_page);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index b07ca2e4d04..7290811f89b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -110,6 +110,8 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data,
memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size);
ret = copy_to_user(buffer, bounce, size);
+ if (ret)
+ ret = -EFAULT;
vfree(bounce);
if (unlikely(ret != 0))
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index f676c01bb47..6fcd466d082 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -46,9 +46,9 @@ static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[559] = 0x45;
}
/* the same as above (s/usage/physical/) */
- if ((quirks & MS_RDESC_3K) && *rsize == 106 &&
- !memcmp((char []){ 0x19, 0x00, 0x29, 0xff },
- &rdesc[94], 4)) {
+ if ((quirks & MS_RDESC_3K) && *rsize == 106 && rdesc[94] == 0x19 &&
+ rdesc[95] == 0x00 && rdesc[96] == 0x29 &&
+ rdesc[97] == 0xff) {
rdesc[94] = 0x35;
rdesc[96] = 0x45;
}
diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 70f5dde1cc5..b38ef6d8d04 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -13,4 +13,10 @@ config HYPERV_UTILS
help
Select this option to enable the Hyper-V Utilities.
+config HYPERV_BALLOON
+ tristate "Microsoft Hyper-V Balloon driver"
+ depends on HYPERV
+ help
+ Select this option to enable Hyper-V Balloon driver.
+
endmenu
diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile
index a23938b991c..e6abfa02d8b 100644
--- a/drivers/hv/Makefile
+++ b/drivers/hv/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_HYPERV) += hv_vmbus.o
obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o
+obj-$(CONFIG_HYPERV_BALLOON) += hv_balloon.o
hv_vmbus-y := vmbus_drv.o \
hv.o connection.o channel.o \
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index f4c3d28cd1f..773a2f25a8f 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -33,14 +33,6 @@
#define NUM_PAGES_SPANNED(addr, len) \
((PAGE_ALIGN(addr + len) >> PAGE_SHIFT) - (addr >> PAGE_SHIFT))
-/* Internal routines */
-static int create_gpadl_header(
- void *kbuffer, /* must be phys and virt contiguous */
- u32 size, /* page-size multiple */
- struct vmbus_channel_msginfo **msginfo,
- u32 *messagecount);
-static void vmbus_setevent(struct vmbus_channel *channel);
-
/*
* vmbus_setevent- Trigger an event notification on the specified
* channel.
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 2b8b8d4558d..2f84c5cff8d 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -265,14 +265,9 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
{
struct vmbus_channel_offer_channel *offer;
struct vmbus_channel *newchannel;
- uuid_le *guidtype;
- uuid_le *guidinstance;
offer = (struct vmbus_channel_offer_channel *)hdr;
- guidtype = &offer->offer.if_type;
- guidinstance = &offer->offer.if_instance;
-
/* Allocate the channel object and save this offer. */
newchannel = alloc_channel();
if (!newchannel) {
@@ -470,7 +465,6 @@ static void vmbus_onversion_response(
{
struct vmbus_channel_msginfo *msginfo;
struct vmbus_channel_message_header *requestheader;
- struct vmbus_channel_initiate_contact *initiate;
struct vmbus_channel_version_response *version_response;
unsigned long flags;
@@ -484,8 +478,6 @@ static void vmbus_onversion_response(
if (requestheader->msgtype ==
CHANNELMSG_INITIATE_CONTACT) {
- initiate =
- (struct vmbus_channel_initiate_contact *)requestheader;
memcpy(&msginfo->response.version_response,
version_response,
sizeof(struct vmbus_channel_version_response));
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
new file mode 100644
index 00000000000..f6c0011a033
--- /dev/null
+++ b/drivers/hv/hv_balloon.c
@@ -0,0 +1,1041 @@
+/*
+ * Copyright (c) 2012, Microsoft Corporation.
+ *
+ * Author:
+ * K. Y. Srinivasan <kys@microsoft.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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/mman.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/completion.h>
+#include <linux/memory_hotplug.h>
+#include <linux/memory.h>
+#include <linux/notifier.h>
+#include <linux/mman.h>
+#include <linux/percpu_counter.h>
+
+#include <linux/hyperv.h>
+
+/*
+ * We begin with definitions supporting the Dynamic Memory protocol
+ * with the host.
+ *
+ * Begin protocol definitions.
+ */
+
+
+
+/*
+ * Protocol versions. The low word is the minor version, the high word the major
+ * version.
+ *
+ * History:
+ * Initial version 1.0
+ * Changed to 0.1 on 2009/03/25
+ * Changes to 0.2 on 2009/05/14
+ * Changes to 0.3 on 2009/12/03
+ * Changed to 1.0 on 2011/04/05
+ */
+
+#define DYNMEM_MAKE_VERSION(Major, Minor) ((__u32)(((Major) << 16) | (Minor)))
+#define DYNMEM_MAJOR_VERSION(Version) ((__u32)(Version) >> 16)
+#define DYNMEM_MINOR_VERSION(Version) ((__u32)(Version) & 0xff)
+
+enum {
+ DYNMEM_PROTOCOL_VERSION_1 = DYNMEM_MAKE_VERSION(0, 3),
+ DYNMEM_PROTOCOL_VERSION_2 = DYNMEM_MAKE_VERSION(1, 0),
+
+ DYNMEM_PROTOCOL_VERSION_WIN7 = DYNMEM_PROTOCOL_VERSION_1,
+ DYNMEM_PROTOCOL_VERSION_WIN8 = DYNMEM_PROTOCOL_VERSION_2,
+
+ DYNMEM_PROTOCOL_VERSION_CURRENT = DYNMEM_PROTOCOL_VERSION_WIN8
+};
+
+
+
+/*
+ * Message Types
+ */
+
+enum dm_message_type {
+ /*
+ * Version 0.3
+ */
+ DM_ERROR = 0,
+ DM_VERSION_REQUEST = 1,
+ DM_VERSION_RESPONSE = 2,
+ DM_CAPABILITIES_REPORT = 3,
+ DM_CAPABILITIES_RESPONSE = 4,
+ DM_STATUS_REPORT = 5,
+ DM_BALLOON_REQUEST = 6,
+ DM_BALLOON_RESPONSE = 7,
+ DM_UNBALLOON_REQUEST = 8,
+ DM_UNBALLOON_RESPONSE = 9,
+ DM_MEM_HOT_ADD_REQUEST = 10,
+ DM_MEM_HOT_ADD_RESPONSE = 11,
+ DM_VERSION_03_MAX = 11,
+ /*
+ * Version 1.0.
+ */
+ DM_INFO_MESSAGE = 12,
+ DM_VERSION_1_MAX = 12
+};
+
+
+/*
+ * Structures defining the dynamic memory management
+ * protocol.
+ */
+
+union dm_version {
+ struct {
+ __u16 minor_version;
+ __u16 major_version;
+ };
+ __u32 version;
+} __packed;
+
+
+union dm_caps {
+ struct {
+ __u64 balloon:1;
+ __u64 hot_add:1;
+ __u64 reservedz:62;
+ } cap_bits;
+ __u64 caps;
+} __packed;
+
+union dm_mem_page_range {
+ struct {
+ /*
+ * The PFN number of the first page in the range.
+ * 40 bits is the architectural limit of a PFN
+ * number for AMD64.
+ */
+ __u64 start_page:40;
+ /*
+ * The number of pages in the range.
+ */
+ __u64 page_cnt:24;
+ } finfo;
+ __u64 page_range;
+} __packed;
+
+
+
+/*
+ * The header for all dynamic memory messages:
+ *
+ * type: Type of the message.
+ * size: Size of the message in bytes; including the header.
+ * trans_id: The guest is responsible for manufacturing this ID.
+ */
+
+struct dm_header {
+ __u16 type;
+ __u16 size;
+ __u32 trans_id;
+} __packed;
+
+/*
+ * A generic message format for dynamic memory.
+ * Specific message formats are defined later in the file.
+ */
+
+struct dm_message {
+ struct dm_header hdr;
+ __u8 data[]; /* enclosed message */
+} __packed;
+
+
+/*
+ * Specific message types supporting the dynamic memory protocol.
+ */
+
+/*
+ * Version negotiation message. Sent from the guest to the host.
+ * The guest is free to try different versions until the host
+ * accepts the version.
+ *
+ * dm_version: The protocol version requested.
+ * is_last_attempt: If TRUE, this is the last version guest will request.
+ * reservedz: Reserved field, set to zero.
+ */
+
+struct dm_version_request {
+ struct dm_header hdr;
+ union dm_version version;
+ __u32 is_last_attempt:1;
+ __u32 reservedz:31;
+} __packed;
+
+/*
+ * Version response message; Host to Guest and indicates
+ * if the host has accepted the version sent by the guest.
+ *
+ * is_accepted: If TRUE, host has accepted the version and the guest
+ * should proceed to the next stage of the protocol. FALSE indicates that
+ * guest should re-try with a different version.
+ *
+ * reservedz: Reserved field, set to zero.
+ */
+
+struct dm_version_response {
+ struct dm_header hdr;
+ __u64 is_accepted:1;
+ __u64 reservedz:63;
+} __packed;
+
+/*
+ * Message reporting capabilities. This is sent from the guest to the
+ * host.
+ */
+
+struct dm_capabilities {
+ struct dm_header hdr;
+ union dm_caps caps;
+ __u64 min_page_cnt;
+ __u64 max_page_number;
+} __packed;
+
+/*
+ * Response to the capabilities message. This is sent from the host to the
+ * guest. This message notifies if the host has accepted the guest's
+ * capabilities. If the host has not accepted, the guest must shutdown
+ * the service.
+ *
+ * is_accepted: Indicates if the host has accepted guest's capabilities.
+ * reservedz: Must be 0.
+ */
+
+struct dm_capabilities_resp_msg {
+ struct dm_header hdr;
+ __u64 is_accepted:1;
+ __u64 reservedz:63;
+} __packed;
+
+/*
+ * This message is used to report memory pressure from the guest.
+ * This message is not part of any transaction and there is no
+ * response to this message.
+ *
+ * num_avail: Available memory in pages.
+ * num_committed: Committed memory in pages.
+ * page_file_size: The accumulated size of all page files
+ * in the system in pages.
+ * zero_free: The nunber of zero and free pages.
+ * page_file_writes: The writes to the page file in pages.
+ * io_diff: An indicator of file cache efficiency or page file activity,
+ * calculated as File Cache Page Fault Count - Page Read Count.
+ * This value is in pages.
+ *
+ * Some of these metrics are Windows specific and fortunately
+ * the algorithm on the host side that computes the guest memory
+ * pressure only uses num_committed value.
+ */
+
+struct dm_status {
+ struct dm_header hdr;
+ __u64 num_avail;
+ __u64 num_committed;
+ __u64 page_file_size;
+ __u64 zero_free;
+ __u32 page_file_writes;
+ __u32 io_diff;
+} __packed;
+
+
+/*
+ * Message to ask the guest to allocate memory - balloon up message.
+ * This message is sent from the host to the guest. The guest may not be
+ * able to allocate as much memory as requested.
+ *
+ * num_pages: number of pages to allocate.
+ */
+
+struct dm_balloon {
+ struct dm_header hdr;
+ __u32 num_pages;
+ __u32 reservedz;
+} __packed;
+
+
+/*
+ * Balloon response message; this message is sent from the guest
+ * to the host in response to the balloon message.
+ *
+ * reservedz: Reserved; must be set to zero.
+ * more_pages: If FALSE, this is the last message of the transaction.
+ * if TRUE there will atleast one more message from the guest.
+ *
+ * range_count: The number of ranges in the range array.
+ *
+ * range_array: An array of page ranges returned to the host.
+ *
+ */
+
+struct dm_balloon_response {
+ struct dm_header hdr;
+ __u32 reservedz;
+ __u32 more_pages:1;
+ __u32 range_count:31;
+ union dm_mem_page_range range_array[];
+} __packed;
+
+/*
+ * Un-balloon message; this message is sent from the host
+ * to the guest to give guest more memory.
+ *
+ * more_pages: If FALSE, this is the last message of the transaction.
+ * if TRUE there will atleast one more message from the guest.
+ *
+ * reservedz: Reserved; must be set to zero.
+ *
+ * range_count: The number of ranges in the range array.
+ *
+ * range_array: An array of page ranges returned to the host.
+ *
+ */
+
+struct dm_unballoon_request {
+ struct dm_header hdr;
+ __u32 more_pages:1;
+ __u32 reservedz:31;
+ __u32 range_count;
+ union dm_mem_page_range range_array[];
+} __packed;
+
+/*
+ * Un-balloon response message; this message is sent from the guest
+ * to the host in response to an unballoon request.
+ *
+ */
+
+struct dm_unballoon_response {
+ struct dm_header hdr;
+} __packed;
+
+
+/*
+ * Hot add request message. Message sent from the host to the guest.
+ *
+ * mem_range: Memory range to hot add.
+ *
+ * On Linux we currently don't support this since we cannot hot add
+ * arbitrary granularity of memory.
+ */
+
+struct dm_hot_add {
+ struct dm_header hdr;
+ union dm_mem_page_range range;
+} __packed;
+
+/*
+ * Hot add response message.
+ * This message is sent by the guest to report the status of a hot add request.
+ * If page_count is less than the requested page count, then the host should
+ * assume all further hot add requests will fail, since this indicates that
+ * the guest has hit an upper physical memory barrier.
+ *
+ * Hot adds may also fail due to low resources; in this case, the guest must
+ * not complete this message until the hot add can succeed, and the host must
+ * not send a new hot add request until the response is sent.
+ * If VSC fails to hot add memory DYNMEM_NUMBER_OF_UNSUCCESSFUL_HOTADD_ATTEMPTS
+ * times it fails the request.
+ *
+ *
+ * page_count: number of pages that were successfully hot added.
+ *
+ * result: result of the operation 1: success, 0: failure.
+ *
+ */
+
+struct dm_hot_add_response {
+ struct dm_header hdr;
+ __u32 page_count;
+ __u32 result;
+} __packed;
+
+/*
+ * Types of information sent from host to the guest.
+ */
+
+enum dm_info_type {
+ INFO_TYPE_MAX_PAGE_CNT = 0,
+ MAX_INFO_TYPE
+};
+
+
+/*
+ * Header for the information message.
+ */
+
+struct dm_info_header {
+ enum dm_info_type type;
+ __u32 data_size;
+} __packed;
+
+/*
+ * This message is sent from the host to the guest to pass
+ * some relevant information (win8 addition).
+ *
+ * reserved: no used.
+ * info_size: size of the information blob.
+ * info: information blob.
+ */
+
+struct dm_info_msg {
+ struct dm_info_header header;
+ __u32 reserved;
+ __u32 info_size;
+ __u8 info[];
+};
+
+/*
+ * End protocol definitions.
+ */
+
+static bool hot_add;
+static bool do_hot_add;
+
+module_param(hot_add, bool, (S_IRUGO | S_IWUSR));
+MODULE_PARM_DESC(hot_add, "If set attempt memory hot_add");
+
+static atomic_t trans_id = ATOMIC_INIT(0);
+
+static int dm_ring_size = (5 * PAGE_SIZE);
+
+/*
+ * Driver specific state.
+ */
+
+enum hv_dm_state {
+ DM_INITIALIZING = 0,
+ DM_INITIALIZED,
+ DM_BALLOON_UP,
+ DM_BALLOON_DOWN,
+ DM_HOT_ADD,
+ DM_INIT_ERROR
+};
+
+
+static __u8 recv_buffer[PAGE_SIZE];
+static __u8 *send_buffer;
+#define PAGES_IN_2M 512
+
+struct hv_dynmem_device {
+ struct hv_device *dev;
+ enum hv_dm_state state;
+ struct completion host_event;
+ struct completion config_event;
+
+ /*
+ * Number of pages we have currently ballooned out.
+ */
+ unsigned int num_pages_ballooned;
+
+ /*
+ * This thread handles both balloon/hot-add
+ * requests from the host as well as notifying
+ * the host with regards to memory pressure in
+ * the guest.
+ */
+ struct task_struct *thread;
+
+ /*
+ * We start with the highest version we can support
+ * and downgrade based on the host; we save here the
+ * next version to try.
+ */
+ __u32 next_version;
+};
+
+static struct hv_dynmem_device dm_device;
+
+static void hot_add_req(struct hv_dynmem_device *dm, struct dm_hot_add *msg)
+{
+
+ struct dm_hot_add_response resp;
+
+ if (do_hot_add) {
+
+ pr_info("Memory hot add not supported\n");
+
+ /*
+ * Currently we do not support hot add.
+ * Just fail the request.
+ */
+ }
+
+ memset(&resp, 0, sizeof(struct dm_hot_add_response));
+ resp.hdr.type = DM_MEM_HOT_ADD_RESPONSE;
+ resp.hdr.size = sizeof(struct dm_hot_add_response);
+ resp.hdr.trans_id = atomic_inc_return(&trans_id);
+
+ resp.page_count = 0;
+ resp.result = 0;
+
+ dm->state = DM_INITIALIZED;
+ vmbus_sendpacket(dm->dev->channel, &resp,
+ sizeof(struct dm_hot_add_response),
+ (unsigned long)NULL,
+ VM_PKT_DATA_INBAND, 0);
+
+}
+
+static void process_info(struct hv_dynmem_device *dm, struct dm_info_msg *msg)
+{
+ switch (msg->header.type) {
+ case INFO_TYPE_MAX_PAGE_CNT:
+ pr_info("Received INFO_TYPE_MAX_PAGE_CNT\n");
+ pr_info("Data Size is %d\n", msg->header.data_size);
+ break;
+ default:
+ pr_info("Received Unknown type: %d\n", msg->header.type);
+ }
+}
+
+/*
+ * Post our status as it relates memory pressure to the
+ * host. Host expects the guests to post this status
+ * periodically at 1 second intervals.
+ *
+ * The metrics specified in this protocol are very Windows
+ * specific and so we cook up numbers here to convey our memory
+ * pressure.
+ */
+
+static void post_status(struct hv_dynmem_device *dm)
+{
+ struct dm_status status;
+
+
+ memset(&status, 0, sizeof(struct dm_status));
+ status.hdr.type = DM_STATUS_REPORT;
+ status.hdr.size = sizeof(struct dm_status);
+ status.hdr.trans_id = atomic_inc_return(&trans_id);
+
+
+ status.num_committed = vm_memory_committed();
+
+ vmbus_sendpacket(dm->dev->channel, &status,
+ sizeof(struct dm_status),
+ (unsigned long)NULL,
+ VM_PKT_DATA_INBAND, 0);
+
+}
+
+
+
+static void free_balloon_pages(struct hv_dynmem_device *dm,
+ union dm_mem_page_range *range_array)
+{
+ int num_pages = range_array->finfo.page_cnt;
+ __u64 start_frame = range_array->finfo.start_page;
+ struct page *pg;
+ int i;
+
+ for (i = 0; i < num_pages; i++) {
+ pg = pfn_to_page(i + start_frame);
+ __free_page(pg);
+ dm->num_pages_ballooned--;
+ }
+}
+
+
+
+static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages,
+ struct dm_balloon_response *bl_resp, int alloc_unit,
+ bool *alloc_error)
+{
+ int i = 0;
+ struct page *pg;
+
+ if (num_pages < alloc_unit)
+ return 0;
+
+ for (i = 0; (i * alloc_unit) < num_pages; i++) {
+ if (bl_resp->hdr.size + sizeof(union dm_mem_page_range) >
+ PAGE_SIZE)
+ return i * alloc_unit;
+
+ /*
+ * We execute this code in a thread context. Furthermore,
+ * we don't want the kernel to try too hard.
+ */
+ pg = alloc_pages(GFP_HIGHUSER | __GFP_NORETRY |
+ __GFP_NOMEMALLOC | __GFP_NOWARN,
+ get_order(alloc_unit << PAGE_SHIFT));
+
+ if (!pg) {
+ *alloc_error = true;
+ return i * alloc_unit;
+ }
+
+
+ dm->num_pages_ballooned += alloc_unit;
+
+ bl_resp->range_count++;
+ bl_resp->range_array[i].finfo.start_page =
+ page_to_pfn(pg);
+ bl_resp->range_array[i].finfo.page_cnt = alloc_unit;
+ bl_resp->hdr.size += sizeof(union dm_mem_page_range);
+
+ }
+
+ return num_pages;
+}
+
+
+
+static void balloon_up(struct hv_dynmem_device *dm, struct dm_balloon *req)
+{
+ int num_pages = req->num_pages;
+ int num_ballooned = 0;
+ struct dm_balloon_response *bl_resp;
+ int alloc_unit;
+ int ret;
+ bool alloc_error = false;
+ bool done = false;
+ int i;
+
+
+ /*
+ * Currently, we only support 4k allocations.
+ */
+ alloc_unit = 1;
+
+ while (!done) {
+ bl_resp = (struct dm_balloon_response *)send_buffer;
+ memset(send_buffer, 0, PAGE_SIZE);
+ bl_resp->hdr.type = DM_BALLOON_RESPONSE;
+ bl_resp->hdr.trans_id = atomic_inc_return(&trans_id);
+ bl_resp->hdr.size = sizeof(struct dm_balloon_response);
+ bl_resp->more_pages = 1;
+
+
+ num_pages -= num_ballooned;
+ num_ballooned = alloc_balloon_pages(dm, num_pages,
+ bl_resp, alloc_unit,
+ &alloc_error);
+
+ if ((alloc_error) || (num_ballooned == num_pages)) {
+ bl_resp->more_pages = 0;
+ done = true;
+ dm->state = DM_INITIALIZED;
+ }
+
+ /*
+ * We are pushing a lot of data through the channel;
+ * deal with transient failures caused because of the
+ * lack of space in the ring buffer.
+ */
+
+ do {
+ ret = vmbus_sendpacket(dm_device.dev->channel,
+ bl_resp,
+ bl_resp->hdr.size,
+ (unsigned long)NULL,
+ VM_PKT_DATA_INBAND, 0);
+
+ if (ret == -EAGAIN)
+ msleep(20);
+
+ } while (ret == -EAGAIN);
+
+ if (ret) {
+ /*
+ * Free up the memory we allocatted.
+ */
+ pr_info("Balloon response failed\n");
+
+ for (i = 0; i < bl_resp->range_count; i++)
+ free_balloon_pages(dm,
+ &bl_resp->range_array[i]);
+
+ done = true;
+ }
+ }
+
+}
+
+static void balloon_down(struct hv_dynmem_device *dm,
+ struct dm_unballoon_request *req)
+{
+ union dm_mem_page_range *range_array = req->range_array;
+ int range_count = req->range_count;
+ struct dm_unballoon_response resp;
+ int i;
+
+ for (i = 0; i < range_count; i++)
+ free_balloon_pages(dm, &range_array[i]);
+
+ if (req->more_pages == 1)
+ return;
+
+ memset(&resp, 0, sizeof(struct dm_unballoon_response));
+ resp.hdr.type = DM_UNBALLOON_RESPONSE;
+ resp.hdr.trans_id = atomic_inc_return(&trans_id);
+ resp.hdr.size = sizeof(struct dm_unballoon_response);
+
+ vmbus_sendpacket(dm_device.dev->channel, &resp,
+ sizeof(struct dm_unballoon_response),
+ (unsigned long)NULL,
+ VM_PKT_DATA_INBAND, 0);
+
+ dm->state = DM_INITIALIZED;
+}
+
+static void balloon_onchannelcallback(void *context);
+
+static int dm_thread_func(void *dm_dev)
+{
+ struct hv_dynmem_device *dm = dm_dev;
+ int t;
+ unsigned long scan_start;
+
+ while (!kthread_should_stop()) {
+ t = wait_for_completion_timeout(&dm_device.config_event, 1*HZ);
+ /*
+ * The host expects us to post information on the memory
+ * pressure every second.
+ */
+
+ if (t == 0)
+ post_status(dm);
+
+ scan_start = jiffies;
+ switch (dm->state) {
+ case DM_BALLOON_UP:
+ balloon_up(dm, (struct dm_balloon *)recv_buffer);
+ break;
+
+ case DM_HOT_ADD:
+ hot_add_req(dm, (struct dm_hot_add *)recv_buffer);
+ break;
+ default:
+ break;
+ }
+
+ if (!time_in_range(jiffies, scan_start, scan_start + HZ))
+ post_status(dm);
+
+ }
+
+ return 0;
+}
+
+
+static void version_resp(struct hv_dynmem_device *dm,
+ struct dm_version_response *vresp)
+{
+ struct dm_version_request version_req;
+ int ret;
+
+ if (vresp->is_accepted) {
+ /*
+ * We are done; wakeup the
+ * context waiting for version
+ * negotiation.
+ */
+ complete(&dm->host_event);
+ return;
+ }
+ /*
+ * If there are more versions to try, continue
+ * with negotiations; if not
+ * shutdown the service since we are not able
+ * to negotiate a suitable version number
+ * with the host.
+ */
+ if (dm->next_version == 0)
+ goto version_error;
+
+ dm->next_version = 0;
+ memset(&version_req, 0, sizeof(struct dm_version_request));
+ version_req.hdr.type = DM_VERSION_REQUEST;
+ version_req.hdr.size = sizeof(struct dm_version_request);
+ version_req.hdr.trans_id = atomic_inc_return(&trans_id);
+ version_req.version.version = DYNMEM_PROTOCOL_VERSION_WIN7;
+ version_req.is_last_attempt = 1;
+
+ ret = vmbus_sendpacket(dm->dev->channel, &version_req,
+ sizeof(struct dm_version_request),
+ (unsigned long)NULL,
+ VM_PKT_DATA_INBAND, 0);
+
+ if (ret)
+ goto version_error;
+
+ return;
+
+version_error:
+ dm->state = DM_INIT_ERROR;
+ complete(&dm->host_event);
+}
+
+static void cap_resp(struct hv_dynmem_device *dm,
+ struct dm_capabilities_resp_msg *cap_resp)
+{
+ if (!cap_resp->is_accepted) {
+ pr_info("Capabilities not accepted by host\n");
+ dm->state = DM_INIT_ERROR;
+ }
+ complete(&dm->host_event);
+}
+
+static void balloon_onchannelcallback(void *context)
+{
+ struct hv_device *dev = context;
+ u32 recvlen;
+ u64 requestid;
+ struct dm_message *dm_msg;
+ struct dm_header *dm_hdr;
+ struct hv_dynmem_device *dm = hv_get_drvdata(dev);
+
+ memset(recv_buffer, 0, sizeof(recv_buffer));
+ vmbus_recvpacket(dev->channel, recv_buffer,
+ PAGE_SIZE, &recvlen, &requestid);
+
+ if (recvlen > 0) {
+ dm_msg = (struct dm_message *)recv_buffer;
+ dm_hdr = &dm_msg->hdr;
+
+ switch (dm_hdr->type) {
+ case DM_VERSION_RESPONSE:
+ version_resp(dm,
+ (struct dm_version_response *)dm_msg);
+ break;
+
+ case DM_CAPABILITIES_RESPONSE:
+ cap_resp(dm,
+ (struct dm_capabilities_resp_msg *)dm_msg);
+ break;
+
+ case DM_BALLOON_REQUEST:
+ dm->state = DM_BALLOON_UP;
+ complete(&dm->config_event);
+ break;
+
+ case DM_UNBALLOON_REQUEST:
+ dm->state = DM_BALLOON_DOWN;
+ balloon_down(dm,
+ (struct dm_unballoon_request *)recv_buffer);
+ break;
+
+ case DM_MEM_HOT_ADD_REQUEST:
+ dm->state = DM_HOT_ADD;
+ complete(&dm->config_event);
+ break;
+
+ case DM_INFO_MESSAGE:
+ process_info(dm, (struct dm_info_msg *)dm_msg);
+ break;
+
+ default:
+ pr_err("Unhandled message: type: %d\n", dm_hdr->type);
+
+ }
+ }
+
+}
+
+static int balloon_probe(struct hv_device *dev,
+ const struct hv_vmbus_device_id *dev_id)
+{
+ int ret, t;
+ struct dm_version_request version_req;
+ struct dm_capabilities cap_msg;
+
+ do_hot_add = hot_add;
+
+ /*
+ * First allocate a send buffer.
+ */
+
+ send_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!send_buffer)
+ return -ENOMEM;
+
+ ret = vmbus_open(dev->channel, dm_ring_size, dm_ring_size, NULL, 0,
+ balloon_onchannelcallback, dev);
+
+ if (ret)
+ return ret;
+
+ dm_device.dev = dev;
+ dm_device.state = DM_INITIALIZING;
+ dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN7;
+ init_completion(&dm_device.host_event);
+ init_completion(&dm_device.config_event);
+
+ dm_device.thread =
+ kthread_run(dm_thread_func, &dm_device, "hv_balloon");
+ if (IS_ERR(dm_device.thread)) {
+ ret = PTR_ERR(dm_device.thread);
+ goto probe_error0;
+ }
+
+ hv_set_drvdata(dev, &dm_device);
+ /*
+ * Initiate the hand shake with the host and negotiate
+ * a version that the host can support. We start with the
+ * highest version number and go down if the host cannot
+ * support it.
+ */
+ memset(&version_req, 0, sizeof(struct dm_version_request));
+ version_req.hdr.type = DM_VERSION_REQUEST;
+ version_req.hdr.size = sizeof(struct dm_version_request);
+ version_req.hdr.trans_id = atomic_inc_return(&trans_id);
+ version_req.version.version = DYNMEM_PROTOCOL_VERSION_WIN8;
+ version_req.is_last_attempt = 0;
+
+ ret = vmbus_sendpacket(dev->channel, &version_req,
+ sizeof(struct dm_version_request),
+ (unsigned long)NULL,
+ VM_PKT_DATA_INBAND,
+ VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+ if (ret)
+ goto probe_error1;
+
+ t = wait_for_completion_timeout(&dm_device.host_event, 5*HZ);
+ if (t == 0) {
+ ret = -ETIMEDOUT;
+ goto probe_error1;
+ }
+
+ /*
+ * If we could not negotiate a compatible version with the host
+ * fail the probe function.
+ */
+ if (dm_device.state == DM_INIT_ERROR) {
+ ret = -ETIMEDOUT;
+ goto probe_error1;
+ }
+ /*
+ * Now submit our capabilities to the host.
+ */
+ memset(&cap_msg, 0, sizeof(struct dm_capabilities));
+ cap_msg.hdr.type = DM_CAPABILITIES_REPORT;
+ cap_msg.hdr.size = sizeof(struct dm_capabilities);
+ cap_msg.hdr.trans_id = atomic_inc_return(&trans_id);
+
+ cap_msg.caps.cap_bits.balloon = 1;
+ /*
+ * While we currently don't support hot-add,
+ * we still advertise this capability since the
+ * host requires that guests partcipating in the
+ * dynamic memory protocol support hot add.
+ */
+ cap_msg.caps.cap_bits.hot_add = 1;
+
+ /*
+ * Currently the host does not use these
+ * values and we set them to what is done in the
+ * Windows driver.
+ */
+ cap_msg.min_page_cnt = 0;
+ cap_msg.max_page_number = -1;
+
+ ret = vmbus_sendpacket(dev->channel, &cap_msg,
+ sizeof(struct dm_capabilities),
+ (unsigned long)NULL,
+ VM_PKT_DATA_INBAND,
+ VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+ if (ret)
+ goto probe_error1;
+
+ t = wait_for_completion_timeout(&dm_device.host_event, 5*HZ);
+ if (t == 0) {
+ ret = -ETIMEDOUT;
+ goto probe_error1;
+ }
+
+ /*
+ * If the host does not like our capabilities,
+ * fail the probe function.
+ */
+ if (dm_device.state == DM_INIT_ERROR) {
+ ret = -ETIMEDOUT;
+ goto probe_error1;
+ }
+
+ dm_device.state = DM_INITIALIZED;
+
+ return 0;
+
+probe_error1:
+ kthread_stop(dm_device.thread);
+
+probe_error0:
+ vmbus_close(dev->channel);
+ return ret;
+}
+
+static int balloon_remove(struct hv_device *dev)
+{
+ struct hv_dynmem_device *dm = hv_get_drvdata(dev);
+
+ if (dm->num_pages_ballooned != 0)
+ pr_warn("Ballooned pages: %d\n", dm->num_pages_ballooned);
+
+ vmbus_close(dev->channel);
+ kthread_stop(dm->thread);
+
+ return 0;
+}
+
+static const struct hv_vmbus_device_id id_table[] = {
+ /* Dynamic Memory Class ID */
+ /* 525074DC-8985-46e2-8057-A307DC18A502 */
+ { VMBUS_DEVICE(0xdc, 0x74, 0x50, 0X52, 0x85, 0x89, 0xe2, 0x46,
+ 0x80, 0x57, 0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02)
+ },
+ { },
+};
+
+MODULE_DEVICE_TABLE(vmbus, id_table);
+
+static struct hv_driver balloon_drv = {
+ .name = "hv_balloon",
+ .id_table = id_table,
+ .probe = balloon_probe,
+ .remove = balloon_remove,
+};
+
+static int __init init_balloon_drv(void)
+{
+
+ return vmbus_driver_register(&balloon_drv);
+}
+
+static void exit_balloon_drv(void)
+{
+
+ vmbus_driver_unregister(&balloon_drv);
+}
+
+module_init(init_balloon_drv);
+module_exit(exit_balloon_drv);
+
+MODULE_DESCRIPTION("Hyper-V Balloon");
+MODULE_VERSION(HV_DRV_VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index c4633de6446..4800d4c2a7b 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -334,6 +334,16 @@ config SENSORS_DA9052_ADC
This driver can also be built as module. If so, the module
will be called da9052-hwmon.
+config SENSORS_DA9055
+ tristate "Dialog Semiconductor DA9055 ADC"
+ depends on MFD_DA9055
+ help
+ If you say yes here you get support for ADC on the Dialog
+ Semiconductor DA9055 PMIC.
+
+ This driver can also be built as a module. If so, the module
+ will be called da9055-hwmon.
+
config SENSORS_I5K_AMB
tristate "FB-DIMM AMB temperature sensor on Intel 5000 series chipsets"
depends on PCI
@@ -455,7 +465,7 @@ config SENSORS_HIH6130
config SENSORS_CORETEMP
tristate "Intel Core/Core2/Atom temperature sensor"
- depends on X86 && PCI
+ depends on X86
help
If you say yes here you get support for the temperature
sensor inside your CPU. Most of the family 6 CPUs
@@ -1106,11 +1116,12 @@ config SENSORS_ADS1015
will be called ads1015.
config SENSORS_ADS7828
- tristate "Texas Instruments ADS7828"
+ tristate "Texas Instruments ADS7828 and compatibles"
depends on I2C
help
- If you say yes here you get support for Texas Instruments ADS7828
- 12-bit 8-channel ADC device.
+ If you say yes here you get support for Texas Instruments ADS7828 and
+ ADS7830 8-channel A/D converters. ADS7828 resolution is 12-bit, while
+ it is 8-bit on ADS7830.
This driver can also be built as a module. If so, the module
will be called ads7828.
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 8d5fcb5e8e9..a930f0997d2 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o
obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o
+obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o
obj-$(CONFIG_SENSORS_DME1737) += dme1737.o
obj-$(CONFIG_SENSORS_DS620) += ds620.o
obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c
index 78b81793ddd..6119ff8e8c8 100644
--- a/drivers/hwmon/abituguru.c
+++ b/drivers/hwmon/abituguru.c
@@ -478,7 +478,7 @@ static int abituguru_write(struct abituguru_data *data,
* alarm for sensor type X and then enabling the sensor as sensor type
* X, if we then get an alarm it is a sensor of type X.
*/
-static int __devinit
+static int
abituguru_detect_bank1_sensor_type(struct abituguru_data *data,
u8 sensor_addr)
{
@@ -635,7 +635,7 @@ abituguru_detect_bank1_sensor_type_exit:
* read/write test would be feasible because of the reaction above, I've
* however opted to stay on the safe side.
*/
-static void __devinit
+static void
abituguru_detect_no_bank2_sensors(struct abituguru_data *data)
{
int i;
@@ -691,7 +691,7 @@ abituguru_detect_no_bank2_sensors(struct abituguru_data *data)
(int)data->bank2_sensors);
}
-static void __devinit
+static void
abituguru_detect_no_pwms(struct abituguru_data *data)
{
int i, j;
@@ -1264,7 +1264,7 @@ static struct sensor_device_attribute_2 abituguru_sysfs_attr[] = {
SENSOR_ATTR_2(name, 0444, show_name, NULL, 0, 0),
};
-static int __devinit abituguru_probe(struct platform_device *pdev)
+static int abituguru_probe(struct platform_device *pdev)
{
struct abituguru_data *data;
int i, j, used, sysfs_names_free, sysfs_attr_i, res = -ENODEV;
@@ -1434,7 +1434,7 @@ abituguru_probe_error:
return res;
}
-static int __devexit abituguru_remove(struct platform_device *pdev)
+static int abituguru_remove(struct platform_device *pdev)
{
int i;
struct abituguru_data *data = platform_get_drvdata(pdev);
@@ -1545,7 +1545,7 @@ static struct platform_driver abituguru_driver = {
.pm = ABIT_UGURU_PM,
},
.probe = abituguru_probe,
- .remove = __devexit_p(abituguru_remove),
+ .remove = abituguru_remove,
};
static int __init abituguru_detect(void)
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c
index b174b8b2b4d..205327d33c4 100644
--- a/drivers/hwmon/abituguru3.c
+++ b/drivers/hwmon/abituguru3.c
@@ -966,7 +966,7 @@ static struct sensor_device_attribute_2 abituguru3_sysfs_attr[] = {
SENSOR_ATTR_2(name, 0444, show_name, NULL, 0, 0),
};
-static int __devinit abituguru3_probe(struct platform_device *pdev)
+static int abituguru3_probe(struct platform_device *pdev)
{
const int no_sysfs_attr[3] = { 10, 8, 7 };
int sensor_index[3] = { 0, 1, 1 };
@@ -1072,7 +1072,7 @@ abituguru3_probe_error:
return res;
}
-static int __devexit abituguru3_remove(struct platform_device *pdev)
+static int abituguru3_remove(struct platform_device *pdev)
{
int i;
struct abituguru3_data *data = platform_get_drvdata(pdev);
@@ -1171,7 +1171,7 @@ static struct platform_driver abituguru3_driver = {
.pm = ABIT_UGURU3_PM
},
.probe = abituguru3_probe,
- .remove = __devexit_p(abituguru3_remove),
+ .remove = abituguru3_remove,
};
static int __init abituguru3_dmi_detect(void)
diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c
index 37c01e72d69..a57584d28a4 100644
--- a/drivers/hwmon/ad7314.c
+++ b/drivers/hwmon/ad7314.c
@@ -107,7 +107,7 @@ static const struct attribute_group ad7314_group = {
.attrs = ad7314_attributes,
};
-static int __devinit ad7314_probe(struct spi_device *spi_dev)
+static int ad7314_probe(struct spi_device *spi_dev)
{
int ret;
struct ad7314_data *chip;
@@ -135,7 +135,7 @@ error_remove_group:
return ret;
}
-static int __devexit ad7314_remove(struct spi_device *spi_dev)
+static int ad7314_remove(struct spi_device *spi_dev)
{
struct ad7314_data *chip = dev_get_drvdata(&spi_dev->dev);
@@ -159,7 +159,7 @@ static struct spi_driver ad7314_driver = {
.owner = THIS_MODULE,
},
.probe = ad7314_probe,
- .remove = __devexit_p(ad7314_remove),
+ .remove = ad7314_remove,
.id_table = ad7314_id,
};
diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c
index b420fb3f3a7..f3a5d4764eb 100644
--- a/drivers/hwmon/ad7414.c
+++ b/drivers/hwmon/ad7414.c
@@ -226,7 +226,7 @@ exit_remove:
return err;
}
-static int __devexit ad7414_remove(struct i2c_client *client)
+static int ad7414_remove(struct i2c_client *client)
{
struct ad7414_data *data = i2c_get_clientdata(client);
@@ -246,7 +246,7 @@ static struct i2c_driver ad7414_driver = {
.name = "ad7414",
},
.probe = ad7414_probe,
- .remove = __devexit_p(ad7414_remove),
+ .remove = ad7414_remove,
.id_table = ad7414_id,
};
diff --git a/drivers/hwmon/adcxx.c b/drivers/hwmon/adcxx.c
index f4c5867170d..751b1f0264a 100644
--- a/drivers/hwmon/adcxx.c
+++ b/drivers/hwmon/adcxx.c
@@ -161,7 +161,7 @@ static struct sensor_device_attribute ad_input[] = {
/*----------------------------------------------------------------------*/
-static int __devinit adcxx_probe(struct spi_device *spi)
+static int adcxx_probe(struct spi_device *spi)
{
int channels = spi_get_device_id(spi)->driver_data;
struct adcxx *adc;
@@ -208,7 +208,7 @@ out_err:
return status;
}
-static int __devexit adcxx_remove(struct spi_device *spi)
+static int adcxx_remove(struct spi_device *spi)
{
struct adcxx *adc = spi_get_drvdata(spi);
int i;
@@ -240,7 +240,7 @@ static struct spi_driver adcxx_driver = {
},
.id_table = adcxx_ids,
.probe = adcxx_probe,
- .remove = __devexit_p(adcxx_remove),
+ .remove = adcxx_remove,
};
module_spi_driver(adcxx_driver);
diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c
index 1f9e8af0f32..409b5c16def 100644
--- a/drivers/hwmon/ads7828.c
+++ b/drivers/hwmon/ads7828.c
@@ -1,12 +1,14 @@
/*
- * ads7828.c - lm_sensors driver for ads7828 12-bit 8-channel ADC
+ * ads7828.c - driver for TI ADS7828 8-channel A/D converter and compatibles
* (C) 2007 EADS Astrium
*
* This driver is based on the lm75 and other lm_sensors/hwmon drivers
*
* Written by Steve Hardy <shardy@redhat.com>
*
- * Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads7828.pdf
+ * ADS7830 support, by Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
+ *
+ * For further information, see the Documentation/hwmon/ads7828 file.
*
* 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
@@ -23,63 +25,48 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
+#include <linux/err.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
-#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/platform_data/ads7828.h>
+#include <linux/slab.h>
/* The ADS7828 registers */
-#define ADS7828_NCH 8 /* 8 channels of 12-bit A-D supported */
-#define ADS7828_CMD_SD_SE 0x80 /* Single ended inputs */
-#define ADS7828_CMD_SD_DIFF 0x00 /* Differential inputs */
-#define ADS7828_CMD_PD0 0x0 /* Power Down between A-D conversions */
-#define ADS7828_CMD_PD1 0x04 /* Internal ref OFF && A-D ON */
-#define ADS7828_CMD_PD2 0x08 /* Internal ref ON && A-D OFF */
-#define ADS7828_CMD_PD3 0x0C /* Internal ref ON && A-D ON */
-#define ADS7828_INT_VREF_MV 2500 /* Internal vref is 2.5V, 2500mV */
-
-/* Addresses to scan */
-static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
- I2C_CLIENT_END };
-
-/* Module parameters */
-static bool se_input = 1; /* Default is SE, 0 == diff */
-static bool int_vref = 1; /* Default is internal ref ON */
-static int vref_mv = ADS7828_INT_VREF_MV; /* set if vref != 2.5V */
-module_param(se_input, bool, S_IRUGO);
-module_param(int_vref, bool, S_IRUGO);
-module_param(vref_mv, int, S_IRUGO);
-
-/* Global Variables */
-static u8 ads7828_cmd_byte; /* cmd byte without channel bits */
-static unsigned int ads7828_lsb_resol; /* resolution of the ADC sample lsb */
-
-/* Each client has this additional data */
+#define ADS7828_NCH 8 /* 8 channels supported */
+#define ADS7828_CMD_SD_SE 0x80 /* Single ended inputs */
+#define ADS7828_CMD_PD1 0x04 /* Internal vref OFF && A/D ON */
+#define ADS7828_CMD_PD3 0x0C /* Internal vref ON && A/D ON */
+#define ADS7828_INT_VREF_MV 2500 /* Internal vref is 2.5V, 2500mV */
+#define ADS7828_EXT_VREF_MV_MIN 50 /* External vref min value 0.05V */
+#define ADS7828_EXT_VREF_MV_MAX 5250 /* External vref max value 5.25V */
+
+/* List of supported devices */
+enum ads7828_chips { ads7828, ads7830 };
+
+/* Client specific data */
struct ads7828_data {
struct device *hwmon_dev;
- struct mutex update_lock; /* mutex protect updates */
- char valid; /* !=0 if following fields are valid */
- unsigned long last_updated; /* In jiffies */
- u16 adc_input[ADS7828_NCH]; /* ADS7828_NCH 12-bit samples */
+ struct mutex update_lock; /* Mutex protecting updates */
+ unsigned long last_updated; /* Last updated time (in jiffies) */
+ u16 adc_input[ADS7828_NCH]; /* ADS7828_NCH samples */
+ bool valid; /* Validity flag */
+ bool diff_input; /* Differential input */
+ bool ext_vref; /* External voltage reference */
+ unsigned int vref_mv; /* voltage reference value */
+ u8 cmd_byte; /* Command byte without channel bits */
+ unsigned int lsb_resol; /* Resolution of the ADC sample LSB */
+ s32 (*read_channel)(const struct i2c_client *client, u8 command);
};
-/* Function declaration - necessary due to function dependencies */
-static int ads7828_detect(struct i2c_client *client,
- struct i2c_board_info *info);
-static int ads7828_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-
-static inline u8 channel_cmd_byte(int ch)
+/* Command byte C2,C1,C0 - see datasheet */
+static inline u8 ads7828_cmd_byte(u8 cmd, int ch)
{
- /* cmd byte C2,C1,C0 - see datasheet */
- u8 cmd = (((ch>>1) | (ch&0x01)<<2)<<4);
- cmd |= ads7828_cmd_byte;
- return cmd;
+ return cmd | (((ch >> 1) | (ch & 0x01) << 2) << 4);
}
/* Update data for the device (all 8 channels) */
@@ -96,12 +83,11 @@ static struct ads7828_data *ads7828_update_device(struct device *dev)
dev_dbg(&client->dev, "Starting ads7828 update\n");
for (ch = 0; ch < ADS7828_NCH; ch++) {
- u8 cmd = channel_cmd_byte(ch);
- data->adc_input[ch] =
- i2c_smbus_read_word_swapped(client, cmd);
+ u8 cmd = ads7828_cmd_byte(data->cmd_byte, ch);
+ data->adc_input[ch] = data->read_channel(client, cmd);
}
data->last_updated = jiffies;
- data->valid = 1;
+ data->valid = true;
}
mutex_unlock(&data->update_lock);
@@ -110,28 +96,25 @@ static struct ads7828_data *ads7828_update_device(struct device *dev)
}
/* sysfs callback function */
-static ssize_t show_in(struct device *dev, struct device_attribute *da,
- char *buf)
+static ssize_t ads7828_show_in(struct device *dev, struct device_attribute *da,
+ char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct ads7828_data *data = ads7828_update_device(dev);
- /* Print value (in mV as specified in sysfs-interface documentation) */
- return sprintf(buf, "%d\n", (data->adc_input[attr->index] *
- ads7828_lsb_resol)/1000);
-}
+ unsigned int value = DIV_ROUND_CLOSEST(data->adc_input[attr->index] *
+ data->lsb_resol, 1000);
-#define in_reg(offset)\
-static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in,\
- NULL, offset)
+ return sprintf(buf, "%d\n", value);
+}
-in_reg(0);
-in_reg(1);
-in_reg(2);
-in_reg(3);
-in_reg(4);
-in_reg(5);
-in_reg(6);
-in_reg(7);
+static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ads7828_show_in, NULL, 0);
+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ads7828_show_in, NULL, 1);
+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ads7828_show_in, NULL, 2);
+static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, ads7828_show_in, NULL, 3);
+static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, ads7828_show_in, NULL, 4);
+static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, ads7828_show_in, NULL, 5);
+static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, ads7828_show_in, NULL, 6);
+static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, ads7828_show_in, NULL, 7);
static struct attribute *ads7828_attributes[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
@@ -152,60 +135,9 @@ static const struct attribute_group ads7828_group = {
static int ads7828_remove(struct i2c_client *client)
{
struct ads7828_data *data = i2c_get_clientdata(client);
+
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &ads7828_group);
- return 0;
-}
-
-static const struct i2c_device_id ads7828_id[] = {
- { "ads7828", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ads7828_id);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver ads7828_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "ads7828",
- },
- .probe = ads7828_probe,
- .remove = ads7828_remove,
- .id_table = ads7828_id,
- .detect = ads7828_detect,
- .address_list = normal_i2c,
-};
-
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int ads7828_detect(struct i2c_client *client,
- struct i2c_board_info *info)
-{
- struct i2c_adapter *adapter = client->adapter;
- int ch;
-
- /* Check we have a valid client */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA))
- return -ENODEV;
-
- /*
- * Now, we do the remaining detection. There is no identification
- * dedicated register so attempt to sanity check using knowledge of
- * the chip
- * - Read from the 8 channel addresses
- * - Check the top 4 bits of each result are not set (12 data bits)
- */
- for (ch = 0; ch < ADS7828_NCH; ch++) {
- u16 in_data;
- u8 cmd = channel_cmd_byte(ch);
- in_data = i2c_smbus_read_word_swapped(client, cmd);
- if (in_data & 0xF000) {
- pr_debug("%s : Doesn't look like an ads7828 device\n",
- __func__);
- return -ENODEV;
- }
- }
-
- strlcpy(info->type, "ads7828", I2C_NAME_SIZE);
return 0;
}
@@ -213,6 +145,7 @@ static int ads7828_detect(struct i2c_client *client,
static int ads7828_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct ads7828_platform_data *pdata = client->dev.platform_data;
struct ads7828_data *data;
int err;
@@ -221,10 +154,37 @@ static int ads7828_probe(struct i2c_client *client,
if (!data)
return -ENOMEM;
+ if (pdata) {
+ data->diff_input = pdata->diff_input;
+ data->ext_vref = pdata->ext_vref;
+ if (data->ext_vref)
+ data->vref_mv = pdata->vref_mv;
+ }
+
+ /* Bound Vref with min/max values if it was provided */
+ if (data->vref_mv)
+ data->vref_mv = SENSORS_LIMIT(data->vref_mv,
+ ADS7828_EXT_VREF_MV_MIN,
+ ADS7828_EXT_VREF_MV_MAX);
+ else
+ data->vref_mv = ADS7828_INT_VREF_MV;
+
+ /* ADS7828 uses 12-bit samples, while ADS7830 is 8-bit */
+ if (id->driver_data == ads7828) {
+ data->lsb_resol = DIV_ROUND_CLOSEST(data->vref_mv * 1000, 4096);
+ data->read_channel = i2c_smbus_read_word_swapped;
+ } else {
+ data->lsb_resol = DIV_ROUND_CLOSEST(data->vref_mv * 1000, 256);
+ data->read_channel = i2c_smbus_read_byte_data;
+ }
+
+ data->cmd_byte = data->ext_vref ? ADS7828_CMD_PD1 : ADS7828_CMD_PD3;
+ if (!data->diff_input)
+ data->cmd_byte |= ADS7828_CMD_SD_SE;
+
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
- /* Register sysfs hooks */
err = sysfs_create_group(&client->dev.kobj, &ads7828_group);
if (err)
return err;
@@ -232,38 +192,35 @@ static int ads7828_probe(struct i2c_client *client,
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
- goto exit_remove;
+ goto error;
}
return 0;
-exit_remove:
+error:
sysfs_remove_group(&client->dev.kobj, &ads7828_group);
return err;
}
-static int __init sensors_ads7828_init(void)
-{
- /* Initialize the command byte according to module parameters */
- ads7828_cmd_byte = se_input ?
- ADS7828_CMD_SD_SE : ADS7828_CMD_SD_DIFF;
- ads7828_cmd_byte |= int_vref ?
- ADS7828_CMD_PD3 : ADS7828_CMD_PD1;
+static const struct i2c_device_id ads7828_device_ids[] = {
+ { "ads7828", ads7828 },
+ { "ads7830", ads7830 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ads7828_device_ids);
- /* Calculate the LSB resolution */
- ads7828_lsb_resol = (vref_mv*1000)/4096;
+static struct i2c_driver ads7828_driver = {
+ .driver = {
+ .name = "ads7828",
+ },
- return i2c_add_driver(&ads7828_driver);
-}
+ .id_table = ads7828_device_ids,
+ .probe = ads7828_probe,
+ .remove = ads7828_remove,
+};
-static void __exit sensors_ads7828_exit(void)
-{
- i2c_del_driver(&ads7828_driver);
-}
+module_i2c_driver(ads7828_driver);
-MODULE_AUTHOR("Steve Hardy <shardy@redhat.com>");
-MODULE_DESCRIPTION("ADS7828 driver");
MODULE_LICENSE("GPL");
-
-module_init(sensors_ads7828_init);
-module_exit(sensors_ads7828_exit);
+MODULE_AUTHOR("Steve Hardy <shardy@redhat.com>");
+MODULE_DESCRIPTION("Driver for TI ADS7828 A/D converter and compatibles");
diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c
index 1b53aa42b6d..a79875986f9 100644
--- a/drivers/hwmon/ads7871.c
+++ b/drivers/hwmon/ads7871.c
@@ -173,7 +173,7 @@ static const struct attribute_group ads7871_group = {
.attrs = ads7871_attributes,
};
-static int __devinit ads7871_probe(struct spi_device *spi)
+static int ads7871_probe(struct spi_device *spi)
{
int ret, err;
uint8_t val;
@@ -225,7 +225,7 @@ error_remove:
return err;
}
-static int __devexit ads7871_remove(struct spi_device *spi)
+static int ads7871_remove(struct spi_device *spi)
{
struct ads7871_data *pdata = spi_get_drvdata(spi);
@@ -241,7 +241,7 @@ static struct spi_driver ads7871_driver = {
},
.probe = ads7871_probe,
- .remove = __devexit_p(ads7871_remove),
+ .remove = ads7871_remove,
};
module_spi_driver(ads7871_driver);
diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c
index 517f1856c70..34ff03abb50 100644
--- a/drivers/hwmon/adt7411.c
+++ b/drivers/hwmon/adt7411.c
@@ -276,7 +276,7 @@ static int adt7411_detect(struct i2c_client *client,
return 0;
}
-static int __devinit adt7411_probe(struct i2c_client *client,
+static int adt7411_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adt7411_data *data;
@@ -317,7 +317,7 @@ static int __devinit adt7411_probe(struct i2c_client *client,
return ret;
}
-static int __devexit adt7411_remove(struct i2c_client *client)
+static int adt7411_remove(struct i2c_client *client)
{
struct adt7411_data *data = i2c_get_clientdata(client);
@@ -337,7 +337,7 @@ static struct i2c_driver adt7411_driver = {
.name = "adt7411",
},
.probe = adt7411_probe,
- .remove = __devexit_p(adt7411_remove),
+ .remove = adt7411_remove,
.id_table = adt7411_id,
.detect = adt7411_detect,
.address_list = normal_i2c,
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 47b8d84b489..d64923d6353 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -34,7 +34,6 @@
#include <linux/list.h>
#include <linux/platform_device.h>
#include <linux/cpu.h>
-#include <linux/pci.h>
#include <linux/smp.h>
#include <linux/moduleparam.h>
#include <asm/msr.h>
@@ -197,14 +196,6 @@ struct tjmax {
};
static const struct tjmax __cpuinitconst tjmax_table[] = {
- { "CPU D410", 100000 },
- { "CPU D425", 100000 },
- { "CPU D510", 100000 },
- { "CPU D525", 100000 },
- { "CPU N450", 100000 },
- { "CPU N455", 100000 },
- { "CPU N470", 100000 },
- { "CPU N475", 100000 },
{ "CPU 230", 100000 }, /* Model 0x1c, stepping 2 */
{ "CPU 330", 125000 }, /* Model 0x1c, stepping 2 */
{ "CPU CE4110", 110000 }, /* Model 0x1c, stepping 10 */
@@ -212,6 +203,28 @@ static const struct tjmax __cpuinitconst tjmax_table[] = {
{ "CPU CE4170", 110000 }, /* Model 0x1c, stepping 10 */
};
+struct tjmax_model {
+ u8 model;
+ u8 mask;
+ int tjmax;
+};
+
+#define ANY 0xff
+
+static const struct tjmax_model __cpuinitconst tjmax_model_table[] = {
+ { 0x1c, 10, 100000 }, /* D4xx, N4xx, D5xx, N5xx */
+ { 0x1c, ANY, 90000 }, /* Z5xx, N2xx, possibly others
+ * Note: Also matches 230 and 330,
+ * which are covered by tjmax_table
+ */
+ { 0x26, ANY, 90000 }, /* Atom Tunnel Creek (Exx), Lincroft (Z6xx)
+ * Note: TjMax for E6xxT is 110C, but CPU type
+ * is undetectable by software
+ */
+ { 0x27, ANY, 90000 }, /* Atom Medfield (Z2460) */
+ { 0x36, ANY, 100000 }, /* Atom Cedar Trail/Cedarview (N2xxx, D2xxx) */
+};
+
static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id,
struct device *dev)
{
@@ -222,7 +235,6 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id,
int usemsr_ee = 1;
int err;
u32 eax, edx;
- struct pci_dev *host_bridge;
int i;
/* explicit tjmax table entries override heuristics */
@@ -231,32 +243,18 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id,
return tjmax_table[i].tjmax;
}
+ for (i = 0; i < ARRAY_SIZE(tjmax_model_table); i++) {
+ const struct tjmax_model *tm = &tjmax_model_table[i];
+ if (c->x86_model == tm->model &&
+ (tm->mask == ANY || c->x86_mask == tm->mask))
+ return tm->tjmax;
+ }
+
/* Early chips have no MSR for TjMax */
if (c->x86_model == 0xf && c->x86_mask < 4)
usemsr_ee = 0;
- /* Atom CPUs */
-
- if (c->x86_model == 0x1c || c->x86_model == 0x26
- || c->x86_model == 0x27) {
- usemsr_ee = 0;
-
- host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
-
- if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL
- && (host_bridge->device == 0xa000 /* NM10 based nettop */
- || host_bridge->device == 0xa010)) /* NM10 based netbook */
- tjmax = 100000;
- else
- tjmax = 90000;
-
- pci_dev_put(host_bridge);
- } else if (c->x86_model == 0x36) {
- usemsr_ee = 0;
- tjmax = 100000;
- }
-
if (c->x86_model > 0xe && usemsr_ee) {
u8 platform_id;
@@ -358,7 +356,7 @@ static int __cpuinit get_tjmax(struct cpuinfo_x86 *c, u32 id,
return adjust_tjmax(c, id, dev);
}
-static int __devinit create_name_attr(struct platform_data *pdata,
+static int create_name_attr(struct platform_data *pdata,
struct device *dev)
{
sysfs_attr_init(&pdata->name_attr.attr);
@@ -553,7 +551,7 @@ static void coretemp_remove_core(struct platform_data *pdata,
pdata->core_data[indx] = NULL;
}
-static int __devinit coretemp_probe(struct platform_device *pdev)
+static int coretemp_probe(struct platform_device *pdev)
{
struct platform_data *pdata;
int err;
@@ -586,7 +584,7 @@ exit_free:
return err;
}
-static int __devexit coretemp_remove(struct platform_device *pdev)
+static int coretemp_remove(struct platform_device *pdev)
{
struct platform_data *pdata = platform_get_drvdata(pdev);
int i;
@@ -608,7 +606,7 @@ static struct platform_driver coretemp_driver = {
.name = DRVNAME,
},
.probe = coretemp_probe,
- .remove = __devexit_p(coretemp_remove),
+ .remove = coretemp_remove,
};
static int __cpuinit coretemp_device_add(unsigned int cpu)
diff --git a/drivers/hwmon/da9052-hwmon.c b/drivers/hwmon/da9052-hwmon.c
index b8d01c5f571..ab4452c5a98 100644
--- a/drivers/hwmon/da9052-hwmon.c
+++ b/drivers/hwmon/da9052-hwmon.c
@@ -60,30 +60,17 @@ static inline int vbbat_reg_to_mV(int value)
return DIV_ROUND_CLOSEST(value * 2500, 512);
}
-static int da9052_enable_vddout_channel(struct da9052 *da9052)
+static inline int da9052_enable_vddout_channel(struct da9052 *da9052)
{
- int ret;
-
- ret = da9052_reg_read(da9052, DA9052_ADC_CONT_REG);
- if (ret < 0)
- return ret;
-
- ret |= DA9052_ADCCONT_AUTOVDDEN;
-
- return da9052_reg_write(da9052, DA9052_ADC_CONT_REG, ret);
+ return da9052_reg_update(da9052, DA9052_ADC_CONT_REG,
+ DA9052_ADCCONT_AUTOVDDEN,
+ DA9052_ADCCONT_AUTOVDDEN);
}
-static int da9052_disable_vddout_channel(struct da9052 *da9052)
+static inline int da9052_disable_vddout_channel(struct da9052 *da9052)
{
- int ret;
-
- ret = da9052_reg_read(da9052, DA9052_ADC_CONT_REG);
- if (ret < 0)
- return ret;
-
- ret &= ~DA9052_ADCCONT_AUTOVDDEN;
-
- return da9052_reg_write(da9052, DA9052_ADC_CONT_REG, ret);
+ return da9052_reg_update(da9052, DA9052_ADC_CONT_REG,
+ DA9052_ADCCONT_AUTOVDDEN, 0);
}
static ssize_t da9052_read_vddout(struct device *dev,
@@ -283,7 +270,7 @@ static struct attribute *da9052_attr[] = {
static const struct attribute_group da9052_attr_group = {.attrs = da9052_attr};
-static int __devinit da9052_hwmon_probe(struct platform_device *pdev)
+static int da9052_hwmon_probe(struct platform_device *pdev)
{
struct da9052_hwmon *hwmon;
int ret;
@@ -316,7 +303,7 @@ err_mem:
return ret;
}
-static int __devexit da9052_hwmon_remove(struct platform_device *pdev)
+static int da9052_hwmon_remove(struct platform_device *pdev)
{
struct da9052_hwmon *hwmon = platform_get_drvdata(pdev);
@@ -328,7 +315,7 @@ static int __devexit da9052_hwmon_remove(struct platform_device *pdev)
static struct platform_driver da9052_hwmon_driver = {
.probe = da9052_hwmon_probe,
- .remove = __devexit_p(da9052_hwmon_remove),
+ .remove = da9052_hwmon_remove,
.driver = {
.name = "da9052-hwmon",
.owner = THIS_MODULE,
diff --git a/drivers/hwmon/da9055-hwmon.c b/drivers/hwmon/da9055-hwmon.c
new file mode 100644
index 00000000000..9465c050c32
--- /dev/null
+++ b/drivers/hwmon/da9055-hwmon.c
@@ -0,0 +1,336 @@
+/*
+ * HWMON Driver for Dialog DA9055
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.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/delay.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/completion.h>
+
+#include <linux/mfd/da9055/core.h>
+#include <linux/mfd/da9055/reg.h>
+
+#define DA9055_ADCIN_DIV 102
+#define DA9055_VSYS_DIV 85
+
+#define DA9055_ADC_VSYS 0
+#define DA9055_ADC_ADCIN1 1
+#define DA9055_ADC_ADCIN2 2
+#define DA9055_ADC_ADCIN3 3
+#define DA9055_ADC_TJUNC 4
+
+struct da9055_hwmon {
+ struct da9055 *da9055;
+ struct device *class_device;
+ struct mutex hwmon_lock;
+ struct mutex irq_lock;
+ struct completion done;
+};
+
+static const char * const input_names[] = {
+ [DA9055_ADC_VSYS] = "VSYS",
+ [DA9055_ADC_ADCIN1] = "ADC IN1",
+ [DA9055_ADC_ADCIN2] = "ADC IN2",
+ [DA9055_ADC_ADCIN3] = "ADC IN3",
+ [DA9055_ADC_TJUNC] = "CHIP TEMP",
+};
+
+static const u8 chan_mux[DA9055_ADC_TJUNC + 1] = {
+ [DA9055_ADC_VSYS] = DA9055_ADC_MUX_VSYS,
+ [DA9055_ADC_ADCIN1] = DA9055_ADC_MUX_ADCIN1,
+ [DA9055_ADC_ADCIN2] = DA9055_ADC_MUX_ADCIN2,
+ [DA9055_ADC_ADCIN3] = DA9055_ADC_MUX_ADCIN3,
+ [DA9055_ADC_TJUNC] = DA9055_ADC_MUX_T_SENSE,
+};
+
+static int da9055_adc_manual_read(struct da9055_hwmon *hwmon,
+ unsigned char channel)
+{
+ int ret;
+ unsigned short calc_data;
+ unsigned short data;
+ unsigned char mux_sel;
+ struct da9055 *da9055 = hwmon->da9055;
+
+ if (channel > DA9055_ADC_TJUNC)
+ return -EINVAL;
+
+ mutex_lock(&hwmon->irq_lock);
+
+ /* Selects desired MUX for manual conversion */
+ mux_sel = chan_mux[channel] | DA9055_ADC_MAN_CONV;
+
+ ret = da9055_reg_write(da9055, DA9055_REG_ADC_MAN, mux_sel);
+ if (ret < 0)
+ goto err;
+
+ /* Wait for an interrupt */
+ if (!wait_for_completion_timeout(&hwmon->done,
+ msecs_to_jiffies(500))) {
+ dev_err(da9055->dev,
+ "timeout waiting for ADC conversion interrupt\n");
+ ret = -ETIMEDOUT;
+ goto err;
+ }
+
+ ret = da9055_reg_read(da9055, DA9055_REG_ADC_RES_H);
+ if (ret < 0)
+ goto err;
+
+ calc_data = (unsigned short)ret;
+ data = calc_data << 2;
+
+ ret = da9055_reg_read(da9055, DA9055_REG_ADC_RES_L);
+ if (ret < 0)
+ goto err;
+
+ calc_data = (unsigned short)(ret & DA9055_ADC_LSB_MASK);
+ data |= calc_data;
+
+ ret = data;
+
+err:
+ mutex_unlock(&hwmon->irq_lock);
+ return ret;
+}
+
+static irqreturn_t da9055_auxadc_irq(int irq, void *irq_data)
+{
+ struct da9055_hwmon *hwmon = irq_data;
+
+ complete(&hwmon->done);
+
+ return IRQ_HANDLED;
+}
+
+/* Conversion function for VSYS and ADCINx */
+static inline int volt_reg_to_mV(int value, int channel)
+{
+ if (channel == DA9055_ADC_VSYS)
+ return DIV_ROUND_CLOSEST(value * 1000, DA9055_VSYS_DIV) + 2500;
+ else
+ return DIV_ROUND_CLOSEST(value * 1000, DA9055_ADCIN_DIV);
+}
+
+static int da9055_enable_auto_mode(struct da9055 *da9055, int channel)
+{
+
+ return da9055_reg_update(da9055, DA9055_REG_ADC_CONT, 1 << channel,
+ 1 << channel);
+
+}
+
+static int da9055_disable_auto_mode(struct da9055 *da9055, int channel)
+{
+
+ return da9055_reg_update(da9055, DA9055_REG_ADC_CONT, 1 << channel, 0);
+}
+
+static ssize_t da9055_read_auto_ch(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct da9055_hwmon *hwmon = dev_get_drvdata(dev);
+ int ret, adc;
+ int channel = to_sensor_dev_attr(devattr)->index;
+
+ mutex_lock(&hwmon->hwmon_lock);
+
+ ret = da9055_enable_auto_mode(hwmon->da9055, channel);
+ if (ret < 0)
+ goto hwmon_err;
+
+ usleep_range(10000, 10500);
+
+ adc = da9055_reg_read(hwmon->da9055, DA9055_REG_VSYS_RES + channel);
+ if (adc < 0) {
+ ret = adc;
+ goto hwmon_err_release;
+ }
+
+ ret = da9055_disable_auto_mode(hwmon->da9055, channel);
+ if (ret < 0)
+ goto hwmon_err;
+
+ mutex_unlock(&hwmon->hwmon_lock);
+
+ return sprintf(buf, "%d\n", volt_reg_to_mV(adc, channel));
+
+hwmon_err_release:
+ da9055_disable_auto_mode(hwmon->da9055, channel);
+hwmon_err:
+ mutex_unlock(&hwmon->hwmon_lock);
+ return ret;
+}
+
+static ssize_t da9055_read_tjunc(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct da9055_hwmon *hwmon = dev_get_drvdata(dev);
+ int tjunc;
+ int toffset;
+
+ tjunc = da9055_adc_manual_read(hwmon, DA9055_ADC_TJUNC);
+ if (tjunc < 0)
+ return tjunc;
+
+ toffset = da9055_reg_read(hwmon->da9055, DA9055_REG_T_OFFSET);
+ if (toffset < 0)
+ return toffset;
+
+ /*
+ * Degrees celsius = -0.4084 * (ADC_RES - T_OFFSET) + 307.6332
+ * T_OFFSET is a trim value used to improve accuracy of the result
+ */
+ return sprintf(buf, "%d\n", DIV_ROUND_CLOSEST(-4084 * (tjunc - toffset)
+ + 3076332, 10000));
+}
+
+static ssize_t da9055_hwmon_show_name(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ return sprintf(buf, "da9055-hwmon\n");
+}
+
+static ssize_t show_label(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ return sprintf(buf, "%s\n",
+ input_names[to_sensor_dev_attr(devattr)->index]);
+}
+
+static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, da9055_read_auto_ch, NULL,
+ DA9055_ADC_VSYS);
+static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, show_label, NULL,
+ DA9055_ADC_VSYS);
+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, da9055_read_auto_ch, NULL,
+ DA9055_ADC_ADCIN1);
+static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_label, NULL,
+ DA9055_ADC_ADCIN1);
+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, da9055_read_auto_ch, NULL,
+ DA9055_ADC_ADCIN2);
+static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_label, NULL,
+ DA9055_ADC_ADCIN2);
+static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, da9055_read_auto_ch, NULL,
+ DA9055_ADC_ADCIN3);
+static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL,
+ DA9055_ADC_ADCIN3);
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, da9055_read_tjunc, NULL,
+ DA9055_ADC_TJUNC);
+static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_label, NULL,
+ DA9055_ADC_TJUNC);
+
+static DEVICE_ATTR(name, S_IRUGO, da9055_hwmon_show_name, NULL);
+
+static struct attribute *da9055_attr[] = {
+ &dev_attr_name.attr,
+ &sensor_dev_attr_in0_input.dev_attr.attr,
+ &sensor_dev_attr_in0_label.dev_attr.attr,
+ &sensor_dev_attr_in1_input.dev_attr.attr,
+ &sensor_dev_attr_in1_label.dev_attr.attr,
+ &sensor_dev_attr_in2_input.dev_attr.attr,
+ &sensor_dev_attr_in2_label.dev_attr.attr,
+ &sensor_dev_attr_in3_input.dev_attr.attr,
+ &sensor_dev_attr_in3_label.dev_attr.attr,
+
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_temp1_label.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group da9055_attr_group = {.attrs = da9055_attr};
+
+static int da9055_hwmon_probe(struct platform_device *pdev)
+{
+ struct da9055_hwmon *hwmon;
+ int hwmon_irq, ret;
+
+ hwmon = devm_kzalloc(&pdev->dev, sizeof(struct da9055_hwmon),
+ GFP_KERNEL);
+ if (!hwmon)
+ return -ENOMEM;
+
+ mutex_init(&hwmon->hwmon_lock);
+ mutex_init(&hwmon->irq_lock);
+
+ init_completion(&hwmon->done);
+ hwmon->da9055 = dev_get_drvdata(pdev->dev.parent);
+
+ platform_set_drvdata(pdev, hwmon);
+
+ hwmon_irq = platform_get_irq_byname(pdev, "HWMON");
+ if (hwmon_irq < 0)
+ return hwmon_irq;
+
+ hwmon_irq = regmap_irq_get_virq(hwmon->da9055->irq_data, hwmon_irq);
+ if (hwmon_irq < 0)
+ return hwmon_irq;
+
+ ret = devm_request_threaded_irq(&pdev->dev, hwmon_irq,
+ NULL, da9055_auxadc_irq,
+ IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ "adc-irq", hwmon);
+ if (ret != 0) {
+ dev_err(hwmon->da9055->dev, "DA9055 ADC IRQ failed ret=%d\n",
+ ret);
+ return ret;
+ }
+
+ ret = sysfs_create_group(&pdev->dev.kobj, &da9055_attr_group);
+ if (ret)
+ return ret;
+
+ hwmon->class_device = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(hwmon->class_device)) {
+ ret = PTR_ERR(hwmon->class_device);
+ goto err;
+ }
+
+ return 0;
+
+err:
+ sysfs_remove_group(&pdev->dev.kobj, &da9055_attr_group);
+ return ret;
+}
+
+static int da9055_hwmon_remove(struct platform_device *pdev)
+{
+ struct da9055_hwmon *hwmon = platform_get_drvdata(pdev);
+
+ sysfs_remove_group(&pdev->dev.kobj, &da9055_attr_group);
+ hwmon_device_unregister(hwmon->class_device);
+
+ return 0;
+}
+
+static struct platform_driver da9055_hwmon_driver = {
+ .probe = da9055_hwmon_probe,
+ .remove = da9055_hwmon_remove,
+ .driver = {
+ .name = "da9055-hwmon",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(da9055_hwmon_driver);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("DA9055 HWMON driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9055-hwmon");
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index fe0eeec0b75..7430f70ae45 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -2630,7 +2630,7 @@ exit:
return err;
}
-static int __devinit dme1737_isa_probe(struct platform_device *pdev)
+static int dme1737_isa_probe(struct platform_device *pdev)
{
u8 company, device;
struct resource *res;
@@ -2718,7 +2718,7 @@ exit_remove_files:
return err;
}
-static int __devexit dme1737_isa_remove(struct platform_device *pdev)
+static int dme1737_isa_remove(struct platform_device *pdev)
{
struct dme1737_data *data = platform_get_drvdata(pdev);
@@ -2734,7 +2734,7 @@ static struct platform_driver dme1737_isa_driver = {
.name = "dme1737",
},
.probe = dme1737_isa_probe,
- .remove = __devexit_p(dme1737_isa_remove),
+ .remove = dme1737_isa_remove,
};
/* ---------------------------------------------------------------------
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index 4dd7723d257..a9816979c5d 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -1343,7 +1343,7 @@ static struct attribute *f71805f_attr_pwm[] = {
* Device registration and initialization
*/
-static void __devinit f71805f_init_device(struct f71805f_data *data)
+static void f71805f_init_device(struct f71805f_data *data)
{
u8 reg;
int i;
@@ -1374,7 +1374,7 @@ static void __devinit f71805f_init_device(struct f71805f_data *data)
}
}
-static int __devinit f71805f_probe(struct platform_device *pdev)
+static int f71805f_probe(struct platform_device *pdev)
{
struct f71805f_sio_data *sio_data = pdev->dev.platform_data;
struct f71805f_data *data;
@@ -1490,7 +1490,7 @@ exit_remove_files:
return err;
}
-static int __devexit f71805f_remove(struct platform_device *pdev)
+static int f71805f_remove(struct platform_device *pdev)
{
struct f71805f_data *data = platform_get_drvdata(pdev);
int i;
@@ -1510,7 +1510,7 @@ static struct platform_driver f71805f_driver = {
.name = DRVNAME,
},
.probe = f71805f_probe,
- .remove = __devexit_p(f71805f_remove),
+ .remove = f71805f_remove,
};
static int __init f71805f_device_add(unsigned short address,
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 50e4ce2d22d..bb7275cc47f 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -364,7 +364,7 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
char *buf);
-static int __devinit f71882fg_probe(struct platform_device *pdev);
+static int f71882fg_probe(struct platform_device *pdev);
static int f71882fg_remove(struct platform_device *pdev);
static struct platform_driver f71882fg_driver = {
@@ -2145,7 +2145,7 @@ static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
return sprintf(buf, "%s\n", f71882fg_names[data->type]);
}
-static int __devinit f71882fg_create_sysfs_files(struct platform_device *pdev,
+static int f71882fg_create_sysfs_files(struct platform_device *pdev,
struct sensor_device_attribute_2 *attr, int count)
{
int err, i;
@@ -2167,7 +2167,7 @@ static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
device_remove_file(&pdev->dev, &attr[i].dev_attr);
}
-static int __devinit f71882fg_create_fan_sysfs_files(
+static int f71882fg_create_fan_sysfs_files(
struct platform_device *pdev, int idx)
{
struct f71882fg_data *data = platform_get_drvdata(pdev);
@@ -2265,7 +2265,7 @@ static int __devinit f71882fg_create_fan_sysfs_files(
return err;
}
-static int __devinit f71882fg_probe(struct platform_device *pdev)
+static int f71882fg_probe(struct platform_device *pdev)
{
struct f71882fg_data *data;
struct f71882fg_sio_data *sio_data = pdev->dev.platform_data;
diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c
index 4f411040738..b757088aedd 100644
--- a/drivers/hwmon/fam15h_power.c
+++ b/drivers/hwmon/fam15h_power.c
@@ -31,6 +31,9 @@ MODULE_DESCRIPTION("AMD Family 15h CPU processor power monitor");
MODULE_AUTHOR("Andreas Herrmann <herrmann.der.user@googlemail.com>");
MODULE_LICENSE("GPL");
+/* Family 16h Northbridge's function 4 PCI ID */
+#define PCI_DEVICE_ID_AMD_16H_NB_F4 0x1534
+
/* D18F3 */
#define REG_NORTHBRIDGE_CAP 0xe8
@@ -111,7 +114,7 @@ static const struct attribute_group fam15h_power_attr_group = {
.attrs = fam15h_power_attrs,
};
-static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4)
+static bool fam15h_power_is_internal_node0(struct pci_dev *f4)
{
u32 val;
@@ -168,7 +171,7 @@ static int fam15h_power_resume(struct pci_dev *pdev)
#define fam15h_power_resume NULL
#endif
-static void __devinit fam15h_power_init_data(struct pci_dev *f4,
+static void fam15h_power_init_data(struct pci_dev *f4,
struct fam15h_power_data *data)
{
u32 val;
@@ -194,7 +197,7 @@ static void __devinit fam15h_power_init_data(struct pci_dev *f4,
data->processor_pwr_watts = (tmp * 15625) >> 10;
}
-static int __devinit fam15h_power_probe(struct pci_dev *pdev,
+static int fam15h_power_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct fam15h_power_data *data;
@@ -235,7 +238,7 @@ exit_remove_group:
return err;
}
-static void __devexit fam15h_power_remove(struct pci_dev *pdev)
+static void fam15h_power_remove(struct pci_dev *pdev)
{
struct device *dev;
struct fam15h_power_data *data;
@@ -248,6 +251,7 @@ static void __devexit fam15h_power_remove(struct pci_dev *pdev)
static DEFINE_PCI_DEVICE_TABLE(fam15h_power_id_table) = {
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) },
{}
};
MODULE_DEVICE_TABLE(pci, fam15h_power_id_table);
@@ -256,7 +260,7 @@ static struct pci_driver fam15h_power_driver = {
.name = "fam15h_power",
.id_table = fam15h_power_id_table,
.probe = fam15h_power_probe,
- .remove = __devexit_p(fam15h_power_remove),
+ .remove = fam15h_power_remove,
.resume = fam15h_power_resume,
};
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c
index 1381a2e3bbd..4e04c1228e5 100644
--- a/drivers/hwmon/gpio-fan.c
+++ b/drivers/hwmon/gpio-fan.c
@@ -499,13 +499,13 @@ static int gpio_fan_get_of_pdata(struct device *dev,
return 0;
}
-static struct of_device_id of_gpio_fan_match[] __devinitdata = {
+static struct of_device_id of_gpio_fan_match[] = {
{ .compatible = "gpio-fan", },
{},
};
#endif /* CONFIG_OF_GPIO */
-static int __devinit gpio_fan_probe(struct platform_device *pdev)
+static int gpio_fan_probe(struct platform_device *pdev)
{
int err;
struct gpio_fan_data *fan_data;
@@ -581,7 +581,7 @@ err_free_alarm:
return err;
}
-static int __devexit gpio_fan_remove(struct platform_device *pdev)
+static int gpio_fan_remove(struct platform_device *pdev)
{
struct gpio_fan_data *fan_data = platform_get_drvdata(pdev);
@@ -626,7 +626,7 @@ static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume);
static struct platform_driver gpio_fan_driver = {
.probe = gpio_fan_probe,
- .remove = __devexit_p(gpio_fan_remove),
+ .remove = gpio_fan_remove,
.driver = {
.name = "gpio-fan",
.pm = GPIO_FAN_PM,
diff --git a/drivers/hwmon/hih6130.c b/drivers/hwmon/hih6130.c
index 9a675efaa78..2dc37c7c694 100644
--- a/drivers/hwmon/hih6130.c
+++ b/drivers/hwmon/hih6130.c
@@ -220,7 +220,7 @@ static const struct attribute_group hih6130_attr_group = {
* device's name.
* Returns 0 on success.
*/
-static int __devinit hih6130_probe(struct i2c_client *client,
+static int hih6130_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct hih6130 *hih6130;
@@ -263,7 +263,7 @@ fail_remove_sysfs:
* hih6130_remove() - remove device
* @client: I2C client device
*/
-static int __devexit hih6130_remove(struct i2c_client *client)
+static int hih6130_remove(struct i2c_client *client)
{
struct hih6130 *hih6130 = i2c_get_clientdata(client);
@@ -283,7 +283,7 @@ MODULE_DEVICE_TABLE(i2c, hih6130_id);
static struct i2c_driver hih6130_driver = {
.driver.name = "hih6130",
.probe = hih6130_probe,
- .remove = __devexit_p(hih6130_remove),
+ .remove = hih6130_remove,
.id_table = hih6130_id,
};
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c
index 46141abaafb..b87c2ccee06 100644
--- a/drivers/hwmon/i5k_amb.c
+++ b/drivers/hwmon/i5k_amb.c
@@ -260,7 +260,7 @@ static ssize_t show_label(struct device *dev,
attr->index & DIMM_MASK);
}
-static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev)
+static int i5k_amb_hwmon_init(struct platform_device *pdev)
{
int i, j, k, d = 0;
u16 c;
@@ -406,7 +406,7 @@ exit_remove:
return res;
}
-static int __devinit i5k_amb_add(void)
+static int i5k_amb_add(void)
{
int res = -ENODEV;
@@ -425,7 +425,7 @@ err:
return res;
}
-static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data,
+static int i5k_find_amb_registers(struct i5k_amb_data *data,
unsigned long devid)
{
struct pci_dev *pcidev;
@@ -459,7 +459,7 @@ out:
return res;
}
-static int __devinit i5k_channel_probe(u16 *amb_present, unsigned long dev_id)
+static int i5k_channel_probe(u16 *amb_present, unsigned long dev_id)
{
struct pci_dev *pcidev;
u16 val16;
@@ -488,14 +488,14 @@ out:
static struct {
unsigned long err;
unsigned long fbd0;
-} chipset_ids[] __devinitdata = {
+} chipset_ids[] = {
{ PCI_DEVICE_ID_INTEL_5000_ERR, PCI_DEVICE_ID_INTEL_5000_FBD0 },
{ PCI_DEVICE_ID_INTEL_5400_ERR, PCI_DEVICE_ID_INTEL_5400_FBD0 },
{ 0, 0 }
};
#ifdef MODULE
-static struct pci_device_id i5k_amb_ids[] __devinitdata = {
+static struct pci_device_id i5k_amb_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR) },
{ 0, }
@@ -503,7 +503,7 @@ static struct pci_device_id i5k_amb_ids[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, i5k_amb_ids);
#endif
-static int __devinit i5k_amb_probe(struct platform_device *pdev)
+static int i5k_amb_probe(struct platform_device *pdev)
{
struct i5k_amb_data *data;
struct resource *reso;
@@ -564,7 +564,7 @@ err:
return res;
}
-static int __devexit i5k_amb_remove(struct platform_device *pdev)
+static int i5k_amb_remove(struct platform_device *pdev)
{
int i;
struct i5k_amb_data *data = platform_get_drvdata(pdev);
@@ -587,7 +587,7 @@ static struct platform_driver i5k_amb_driver = {
.name = DRVNAME,
},
.probe = i5k_amb_probe,
- .remove = __devexit_p(i5k_amb_remove),
+ .remove = i5k_amb_remove,
};
static int __init i5k_amb_init(void)
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
index 2b726346f8f..8e7158c3ad2 100644
--- a/drivers/hwmon/ina2xx.c
+++ b/drivers/hwmon/ina2xx.c
@@ -302,19 +302,8 @@ static struct i2c_driver ina2xx_driver = {
.id_table = ina2xx_id,
};
-static int __init ina2xx_init(void)
-{
- return i2c_add_driver(&ina2xx_driver);
-}
-
-static void __exit ina2xx_exit(void)
-{
- i2c_del_driver(&ina2xx_driver);
-}
+module_i2c_driver(ina2xx_driver);
MODULE_AUTHOR("Lothar Felten <l-felten@ti.com>");
MODULE_DESCRIPTION("ina2xx driver");
MODULE_LICENSE("GPL");
-
-module_init(ina2xx_init);
-module_exit(ina2xx_exit);
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index f1de3979181..d32aa354cbd 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -428,7 +428,7 @@ static inline int has_old_autopwm(const struct it87_data *data)
}
static int it87_probe(struct platform_device *pdev);
-static int __devexit it87_remove(struct platform_device *pdev);
+static int it87_remove(struct platform_device *pdev);
static int it87_read_value(struct it87_data *data, u8 reg);
static void it87_write_value(struct it87_data *data, u8 reg, u8 value);
@@ -443,7 +443,7 @@ static struct platform_driver it87_driver = {
.name = DRVNAME,
},
.probe = it87_probe,
- .remove = __devexit_p(it87_remove),
+ .remove = it87_remove,
};
static ssize_t show_in(struct device *dev, struct device_attribute *attr,
@@ -1966,7 +1966,7 @@ static void it87_remove_files(struct device *dev)
sysfs_remove_group(&dev->kobj, &it87_group_label);
}
-static int __devinit it87_probe(struct platform_device *pdev)
+static int it87_probe(struct platform_device *pdev)
{
struct it87_data *data;
struct resource *res;
@@ -2158,7 +2158,7 @@ error:
return err;
}
-static int __devexit it87_remove(struct platform_device *pdev)
+static int it87_remove(struct platform_device *pdev)
{
struct it87_data *data = platform_get_drvdata(pdev);
@@ -2191,7 +2191,7 @@ static void it87_write_value(struct it87_data *data, u8 reg, u8 value)
}
/* Return 1 if and only if the PWM interface is safe to use */
-static int __devinit it87_check_pwm(struct device *dev)
+static int it87_check_pwm(struct device *dev)
{
struct it87_data *data = dev_get_drvdata(dev);
/*
@@ -2248,7 +2248,7 @@ static int __devinit it87_check_pwm(struct device *dev)
}
/* Called when we have found a new IT87. */
-static void __devinit it87_init_device(struct platform_device *pdev)
+static void it87_init_device(struct platform_device *pdev)
{
struct it87_sio_data *sio_data = pdev->dev.platform_data;
struct it87_data *data = platform_get_drvdata(pdev);
diff --git a/drivers/hwmon/jz4740-hwmon.c b/drivers/hwmon/jz4740-hwmon.c
index dee9eec2036..e0d66b9590a 100644
--- a/drivers/hwmon/jz4740-hwmon.c
+++ b/drivers/hwmon/jz4740-hwmon.c
@@ -102,7 +102,7 @@ static const struct attribute_group jz4740_hwmon_attr_group = {
.attrs = jz4740_hwmon_attributes,
};
-static int __devinit jz4740_hwmon_probe(struct platform_device *pdev)
+static int jz4740_hwmon_probe(struct platform_device *pdev)
{
int ret;
struct jz4740_hwmon *hwmon;
@@ -172,7 +172,7 @@ err_remove_file:
return ret;
}
-static int __devexit jz4740_hwmon_remove(struct platform_device *pdev)
+static int jz4740_hwmon_remove(struct platform_device *pdev)
{
struct jz4740_hwmon *hwmon = platform_get_drvdata(pdev);
@@ -184,7 +184,7 @@ static int __devexit jz4740_hwmon_remove(struct platform_device *pdev)
static struct platform_driver jz4740_hwmon_driver = {
.probe = jz4740_hwmon_probe,
- .remove = __devexit_p(jz4740_hwmon_remove),
+ .remove = jz4740_hwmon_remove,
.driver = {
.name = "jz4740-hwmon",
.owner = THIS_MODULE,
diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c
index f2fe8078633..e3b037c73a7 100644
--- a/drivers/hwmon/k10temp.c
+++ b/drivers/hwmon/k10temp.c
@@ -95,7 +95,7 @@ static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL, 0);
static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_crit, NULL, 1);
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-static bool __devinit has_erratum_319(struct pci_dev *pdev)
+static bool has_erratum_319(struct pci_dev *pdev)
{
u32 pkg_type, reg_dram_cfg;
@@ -129,7 +129,7 @@ static bool __devinit has_erratum_319(struct pci_dev *pdev)
(boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_mask <= 2);
}
-static int __devinit k10temp_probe(struct pci_dev *pdev,
+static int k10temp_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct device *hwmon_dev;
@@ -192,7 +192,7 @@ exit:
return err;
}
-static void __devexit k10temp_remove(struct pci_dev *pdev)
+static void k10temp_remove(struct pci_dev *pdev)
{
hwmon_device_unregister(pci_get_drvdata(pdev));
device_remove_file(&pdev->dev, &dev_attr_name);
@@ -219,7 +219,7 @@ static struct pci_driver k10temp_driver = {
.name = "k10temp",
.id_table = k10temp_id_table,
.probe = k10temp_probe,
- .remove = __devexit_p(k10temp_remove),
+ .remove = k10temp_remove,
};
module_pci_driver(k10temp_driver);
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c
index e8c7fb0bbf9..9f3c0aeacdb 100644
--- a/drivers/hwmon/k8temp.c
+++ b/drivers/hwmon/k8temp.c
@@ -142,7 +142,7 @@ static DEFINE_PCI_DEVICE_TABLE(k8temp_ids) = {
MODULE_DEVICE_TABLE(pci, k8temp_ids);
-static int __devinit is_rev_g_desktop(u8 model)
+static int is_rev_g_desktop(u8 model)
{
u32 brandidx;
@@ -173,7 +173,7 @@ static int __devinit is_rev_g_desktop(u8 model)
return 1;
}
-static int __devinit k8temp_probe(struct pci_dev *pdev,
+static int k8temp_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
int err;
@@ -304,7 +304,7 @@ exit_remove:
return err;
}
-static void __devexit k8temp_remove(struct pci_dev *pdev)
+static void k8temp_remove(struct pci_dev *pdev)
{
struct k8temp_data *data = pci_get_drvdata(pdev);
@@ -324,7 +324,7 @@ static struct pci_driver k8temp_driver = {
.name = "k8temp",
.id_table = k8temp_ids,
.probe = k8temp_probe,
- .remove = __devexit_p(k8temp_remove),
+ .remove = k8temp_remove,
};
module_pci_driver(k8temp_driver);
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c
index 2d1777a03ed..016efa26ba7 100644
--- a/drivers/hwmon/lm70.c
+++ b/drivers/hwmon/lm70.c
@@ -131,7 +131,7 @@ static DEVICE_ATTR(name, S_IRUGO, lm70_show_name, NULL);
/*----------------------------------------------------------------------*/
-static int __devinit lm70_probe(struct spi_device *spi)
+static int lm70_probe(struct spi_device *spi)
{
int chip = spi_get_device_id(spi)->driver_data;
struct lm70 *p_lm70;
@@ -178,7 +178,7 @@ out_dev_create_temp_file_failed:
return status;
}
-static int __devexit lm70_remove(struct spi_device *spi)
+static int lm70_remove(struct spi_device *spi)
{
struct lm70 *p_lm70 = spi_get_drvdata(spi);
@@ -207,7 +207,7 @@ static struct spi_driver lm70_driver = {
},
.id_table = lm70_ids,
.probe = lm70_probe,
- .remove = __devexit_p(lm70_remove),
+ .remove = lm70_remove,
};
module_spi_driver(lm70_driver);
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index c6ffafe600a..53d6ee8ffa3 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -833,7 +833,7 @@ static struct lm78_data *lm78_update_device(struct device *dev)
}
#ifdef CONFIG_ISA
-static int __devinit lm78_isa_probe(struct platform_device *pdev)
+static int lm78_isa_probe(struct platform_device *pdev)
{
int err;
struct lm78_data *data;
@@ -886,7 +886,7 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev)
return err;
}
-static int __devexit lm78_isa_remove(struct platform_device *pdev)
+static int lm78_isa_remove(struct platform_device *pdev)
{
struct lm78_data *data = platform_get_drvdata(pdev);
@@ -903,7 +903,7 @@ static struct platform_driver lm78_isa_driver = {
.name = "lm78",
},
.probe = lm78_isa_probe,
- .remove = __devexit_p(lm78_isa_remove),
+ .remove = lm78_isa_remove,
};
/* return 1 if a supported chip is found, 0 otherwise */
diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c
index b4eb0889c46..eda077de8a9 100644
--- a/drivers/hwmon/max1111.c
+++ b/drivers/hwmon/max1111.c
@@ -157,7 +157,7 @@ static const struct attribute_group max1110_attr_group = {
.attrs = max1110_attributes,
};
-static int __devinit setup_transfer(struct max1111_data *data)
+static int setup_transfer(struct max1111_data *data)
{
struct spi_message *m;
struct spi_transfer *x;
@@ -179,7 +179,7 @@ static int __devinit setup_transfer(struct max1111_data *data)
return 0;
}
-static int __devinit max1111_probe(struct spi_device *spi)
+static int max1111_probe(struct spi_device *spi)
{
enum chips chip = spi_get_device_id(spi)->driver_data;
struct max1111_data *data;
@@ -256,7 +256,7 @@ err_remove:
return err;
}
-static int __devexit max1111_remove(struct spi_device *spi)
+static int max1111_remove(struct spi_device *spi)
{
struct max1111_data *data = spi_get_drvdata(spi);
@@ -283,7 +283,7 @@ static struct spi_driver max1111_driver = {
},
.id_table = max1111_ids,
.probe = max1111_probe,
- .remove = __devexit_p(max1111_remove),
+ .remove = max1111_remove,
};
module_spi_driver(max1111_driver);
diff --git a/drivers/hwmon/max197.c b/drivers/hwmon/max197.c
index 6304f2616fa..b5ebb9198c7 100644
--- a/drivers/hwmon/max197.c
+++ b/drivers/hwmon/max197.c
@@ -257,7 +257,7 @@ static const struct attribute_group max197_sysfs_group = {
},
};
-static int __devinit max197_probe(struct platform_device *pdev)
+static int max197_probe(struct platform_device *pdev)
{
int ch, ret;
struct max197_data *data;
@@ -316,7 +316,7 @@ error:
return ret;
}
-static int __devexit max197_remove(struct platform_device *pdev)
+static int max197_remove(struct platform_device *pdev)
{
struct max197_data *data = platform_get_drvdata(pdev);
@@ -339,7 +339,7 @@ static struct platform_driver max197_driver = {
.owner = THIS_MODULE,
},
.probe = max197_probe,
- .remove = __devexit_p(max197_remove),
+ .remove = max197_remove,
.id_table = max197_device_ids,
};
module_platform_driver(max197_driver);
diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c
index cf47a59657a..2a7f331cd3c 100644
--- a/drivers/hwmon/mc13783-adc.c
+++ b/drivers/hwmon/mc13783-adc.c
@@ -233,7 +233,7 @@ out_err_create_16chans:
return ret;
}
-static int __devexit mc13783_adc_remove(struct platform_device *pdev)
+static int mc13783_adc_remove(struct platform_device *pdev)
{
struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data;
@@ -265,7 +265,7 @@ static const struct platform_device_id mc13783_adc_idtable[] = {
MODULE_DEVICE_TABLE(platform, mc13783_adc_idtable);
static struct platform_driver mc13783_adc_driver = {
- .remove = __devexit_p(mc13783_adc_remove),
+ .remove = mc13783_adc_remove,
.driver = {
.owner = THIS_MODULE,
.name = DRIVER_NAME,
diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c
index 74a6c58d021..a87eb8986e3 100644
--- a/drivers/hwmon/ntc_thermistor.c
+++ b/drivers/hwmon/ntc_thermistor.c
@@ -309,7 +309,7 @@ static const struct attribute_group ntc_attr_group = {
.attrs = ntc_attributes,
};
-static int __devinit ntc_thermistor_probe(struct platform_device *pdev)
+static int ntc_thermistor_probe(struct platform_device *pdev)
{
struct ntc_data *data;
struct ntc_thermistor_platform_data *pdata = pdev->dev.platform_data;
@@ -393,7 +393,7 @@ err_after_sysfs:
return ret;
}
-static int __devexit ntc_thermistor_remove(struct platform_device *pdev)
+static int ntc_thermistor_remove(struct platform_device *pdev)
{
struct ntc_data *data = platform_get_drvdata(pdev);
@@ -419,7 +419,7 @@ static struct platform_driver ntc_thermistor_driver = {
.owner = THIS_MODULE,
},
.probe = ntc_thermistor_probe,
- .remove = __devexit_p(ntc_thermistor_remove),
+ .remove = ntc_thermistor_remove,
.id_table = ntc_thermistor_id,
};
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index 91d5b2a21dd..e35856bb79b 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -228,7 +228,7 @@ struct pc87360_data {
*/
static int pc87360_probe(struct platform_device *pdev);
-static int __devexit pc87360_remove(struct platform_device *pdev);
+static int pc87360_remove(struct platform_device *pdev);
static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank,
u8 reg);
@@ -248,7 +248,7 @@ static struct platform_driver pc87360_driver = {
.name = "pc87360",
},
.probe = pc87360_probe,
- .remove = __devexit_p(pc87360_remove),
+ .remove = pc87360_remove,
};
/*
@@ -1221,7 +1221,7 @@ static void pc87360_remove_files(struct device *dev)
sysfs_remove_group(&dev->kobj, &pc8736x_vin_group);
}
-static int __devinit pc87360_probe(struct platform_device *pdev)
+static int pc87360_probe(struct platform_device *pdev)
{
int i;
struct pc87360_data *data;
@@ -1375,7 +1375,7 @@ error:
return err;
}
-static int __devexit pc87360_remove(struct platform_device *pdev)
+static int pc87360_remove(struct platform_device *pdev)
{
struct pc87360_data *data = platform_get_drvdata(pdev);
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
index f185b1fa53e..6086ad039d7 100644
--- a/drivers/hwmon/pc87427.c
+++ b/drivers/hwmon/pc87427.c
@@ -956,7 +956,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
* Device detection, attach and detach
*/
-static int __devinit pc87427_request_regions(struct platform_device *pdev,
+static int pc87427_request_regions(struct platform_device *pdev,
int count)
{
struct resource *res;
@@ -980,7 +980,7 @@ static int __devinit pc87427_request_regions(struct platform_device *pdev,
return 0;
}
-static void __devinit pc87427_init_device(struct device *dev)
+static void pc87427_init_device(struct device *dev)
{
struct pc87427_sio_data *sio_data = dev->platform_data;
struct pc87427_data *data = dev_get_drvdata(dev);
@@ -1072,7 +1072,7 @@ static void pc87427_remove_files(struct device *dev)
}
}
-static int __devinit pc87427_probe(struct platform_device *pdev)
+static int pc87427_probe(struct platform_device *pdev)
{
struct pc87427_sio_data *sio_data = pdev->dev.platform_data;
struct pc87427_data *data;
@@ -1141,7 +1141,7 @@ exit_remove_files:
return err;
}
-static int __devexit pc87427_remove(struct platform_device *pdev)
+static int pc87427_remove(struct platform_device *pdev)
{
struct pc87427_data *data = platform_get_drvdata(pdev);
@@ -1158,7 +1158,7 @@ static struct platform_driver pc87427_driver = {
.name = DRVNAME,
},
.probe = pc87427_probe,
- .remove = __devexit_p(pc87427_remove),
+ .remove = pc87427_remove,
};
static int __init pc87427_device_add(const struct pc87427_sio_data *sio_data)
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c
index bcecd025fcc..ff2ae0252a4 100644
--- a/drivers/hwmon/s3c-hwmon.c
+++ b/drivers/hwmon/s3c-hwmon.c
@@ -275,7 +275,7 @@ static void s3c_hwmon_remove_attr(struct device *dev,
* s3c_hwmon_probe - device probe entry.
* @dev: The device being probed.
*/
-static int __devinit s3c_hwmon_probe(struct platform_device *dev)
+static int s3c_hwmon_probe(struct platform_device *dev)
{
struct s3c_hwmon_pdata *pdata = dev->dev.platform_data;
struct s3c_hwmon *hwmon;
@@ -364,7 +364,7 @@ static int __devinit s3c_hwmon_probe(struct platform_device *dev)
return ret;
}
-static int __devexit s3c_hwmon_remove(struct platform_device *dev)
+static int s3c_hwmon_remove(struct platform_device *dev)
{
struct s3c_hwmon *hwmon = platform_get_drvdata(dev);
int i;
@@ -386,7 +386,7 @@ static struct platform_driver s3c_hwmon_driver = {
.owner = THIS_MODULE,
},
.probe = s3c_hwmon_probe,
- .remove = __devexit_p(s3c_hwmon_remove),
+ .remove = s3c_hwmon_remove,
};
module_platform_driver(s3c_hwmon_driver);
diff --git a/drivers/hwmon/sch5627.c b/drivers/hwmon/sch5627.c
index 49f6230bdcf..0cc99fd83e8 100644
--- a/drivers/hwmon/sch5627.c
+++ b/drivers/hwmon/sch5627.c
@@ -153,7 +153,7 @@ abort:
return ret;
}
-static int __devinit sch5627_read_limits(struct sch5627_data *data)
+static int sch5627_read_limits(struct sch5627_data *data)
{
int i, val;
@@ -465,7 +465,7 @@ static int sch5627_remove(struct platform_device *pdev)
return 0;
}
-static int __devinit sch5627_probe(struct platform_device *pdev)
+static int sch5627_probe(struct platform_device *pdev)
{
struct sch5627_data *data;
int err, build_code, build_id, hwmon_rev, val;
diff --git a/drivers/hwmon/sch5636.c b/drivers/hwmon/sch5636.c
index 51711801619..547b5c952ef 100644
--- a/drivers/hwmon/sch5636.c
+++ b/drivers/hwmon/sch5636.c
@@ -405,7 +405,7 @@ static int sch5636_remove(struct platform_device *pdev)
return 0;
}
-static int __devinit sch5636_probe(struct platform_device *pdev)
+static int sch5636_probe(struct platform_device *pdev)
{
struct sch5636_data *data;
int i, err, val, revision[2];
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
index 07a0c1a0b84..1c85d39df17 100644
--- a/drivers/hwmon/sht15.c
+++ b/drivers/hwmon/sht15.c
@@ -884,7 +884,7 @@ static int sht15_invalidate_voltage(struct notifier_block *nb,
return NOTIFY_OK;
}
-static int __devinit sht15_probe(struct platform_device *pdev)
+static int sht15_probe(struct platform_device *pdev)
{
int ret;
struct sht15_data *data;
@@ -1002,7 +1002,7 @@ err_release_reg:
return ret;
}
-static int __devexit sht15_remove(struct platform_device *pdev)
+static int sht15_remove(struct platform_device *pdev)
{
struct sht15_data *data = platform_get_drvdata(pdev);
@@ -1043,7 +1043,7 @@ static struct platform_driver sht15_driver = {
.owner = THIS_MODULE,
},
.probe = sht15_probe,
- .remove = __devexit_p(sht15_remove),
+ .remove = sht15_remove,
.id_table = sht15_device_ids,
};
module_platform_driver(sht15_driver);
diff --git a/drivers/hwmon/sht21.c b/drivers/hwmon/sht21.c
index 5f67546950b..2e9f9570b6f 100644
--- a/drivers/hwmon/sht21.c
+++ b/drivers/hwmon/sht21.c
@@ -187,7 +187,7 @@ static const struct attribute_group sht21_attr_group = {
* device's name.
* Returns 0 on success.
*/
-static int __devinit sht21_probe(struct i2c_client *client,
+static int sht21_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct sht21 *sht21;
@@ -233,7 +233,7 @@ fail_remove_sysfs:
* sht21_remove() - remove device
* @client: I2C client device
*/
-static int __devexit sht21_remove(struct i2c_client *client)
+static int sht21_remove(struct i2c_client *client)
{
struct sht21 *sht21 = i2c_get_clientdata(client);
@@ -253,7 +253,7 @@ MODULE_DEVICE_TABLE(i2c, sht21_id);
static struct i2c_driver sht21_driver = {
.driver.name = "sht21",
.probe = sht21_probe,
- .remove = __devexit_p(sht21_remove),
+ .remove = sht21_remove,
.id_table = sht21_id,
};
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index 8275f0e14eb..06ce3c911db 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -204,7 +204,7 @@ struct sis5595_data {
static struct pci_dev *s_bridge; /* pointer to the (only) sis5595 */
static int sis5595_probe(struct platform_device *pdev);
-static int __devexit sis5595_remove(struct platform_device *pdev);
+static int sis5595_remove(struct platform_device *pdev);
static int sis5595_read_value(struct sis5595_data *data, u8 reg);
static void sis5595_write_value(struct sis5595_data *data, u8 reg, u8 value);
@@ -217,7 +217,7 @@ static struct platform_driver sis5595_driver = {
.name = "sis5595",
},
.probe = sis5595_probe,
- .remove = __devexit_p(sis5595_remove),
+ .remove = sis5595_remove,
};
/* 4 Voltages */
@@ -583,7 +583,7 @@ static const struct attribute_group sis5595_group_temp1 = {
};
/* This is called when the module is loaded */
-static int __devinit sis5595_probe(struct platform_device *pdev)
+static int sis5595_probe(struct platform_device *pdev)
{
int err = 0;
int i;
@@ -659,7 +659,7 @@ exit_remove_files:
return err;
}
-static int __devexit sis5595_remove(struct platform_device *pdev)
+static int sis5595_remove(struct platform_device *pdev)
{
struct sis5595_data *data = platform_get_drvdata(pdev);
@@ -693,7 +693,7 @@ static void sis5595_write_value(struct sis5595_data *data, u8 reg, u8 value)
}
/* Called when we have found a new SIS5595. */
-static void __devinit sis5595_init_device(struct sis5595_data *data)
+static void sis5595_init_device(struct sis5595_data *data)
{
u8 config = sis5595_read_value(data, SIS5595_REG_CONFIG);
if (!(config & 0x01))
@@ -758,7 +758,7 @@ static DEFINE_PCI_DEVICE_TABLE(sis5595_pci_ids) = {
MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
-static int blacklist[] __devinitdata = {
+static int blacklist[] = {
PCI_DEVICE_ID_SI_540,
PCI_DEVICE_ID_SI_550,
PCI_DEVICE_ID_SI_630,
@@ -774,7 +774,7 @@ static int blacklist[] __devinitdata = {
PCI_DEVICE_ID_SI_5598,
0 };
-static int __devinit sis5595_device_add(unsigned short address)
+static int sis5595_device_add(unsigned short address)
{
struct resource res = {
.start = address,
@@ -815,7 +815,7 @@ exit:
return err;
}
-static int __devinit sis5595_pci_probe(struct pci_dev *dev,
+static int sis5595_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
u16 address;
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index 65b07de11a0..81348fadf3b 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -228,7 +228,7 @@ static const struct attribute_group smsc47b397_group = {
.attrs = smsc47b397_attributes,
};
-static int __devexit smsc47b397_remove(struct platform_device *pdev)
+static int smsc47b397_remove(struct platform_device *pdev)
{
struct smsc47b397_data *data = platform_get_drvdata(pdev);
@@ -246,10 +246,10 @@ static struct platform_driver smsc47b397_driver = {
.name = DRVNAME,
},
.probe = smsc47b397_probe,
- .remove = __devexit_p(smsc47b397_remove),
+ .remove = smsc47b397_remove,
};
-static int __devinit smsc47b397_probe(struct platform_device *pdev)
+static int smsc47b397_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct smsc47b397_data *data;
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c
index b8777e54190..b10c3d36ccb 100644
--- a/drivers/hwmon/tmp102.c
+++ b/drivers/hwmon/tmp102.c
@@ -147,7 +147,7 @@ static const struct attribute_group tmp102_attr_group = {
#define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1)
#define TMP102_CONFIG_RD_ONLY (TMP102_CONF_R0 | TMP102_CONF_R1 | TMP102_CONF_AL)
-static int __devinit tmp102_probe(struct i2c_client *client,
+static int tmp102_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tmp102 *tmp102;
@@ -216,7 +216,7 @@ fail_restore_config:
return status;
}
-static int __devexit tmp102_remove(struct i2c_client *client)
+static int tmp102_remove(struct i2c_client *client)
{
struct tmp102 *tmp102 = i2c_get_clientdata(client);
@@ -283,7 +283,7 @@ static struct i2c_driver tmp102_driver = {
.driver.name = DRIVER_NAME,
.driver.pm = TMP102_DEV_PM_OPS,
.probe = tmp102_probe,
- .remove = __devexit_p(tmp102_remove),
+ .remove = tmp102_remove,
.id_table = tmp102_id,
};
diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c
index 1a174f0a3cd..149d44a7c58 100644
--- a/drivers/hwmon/twl4030-madc-hwmon.c
+++ b/drivers/hwmon/twl4030-madc-hwmon.c
@@ -96,7 +96,7 @@ static const struct attribute_group twl4030_madc_group = {
.attrs = twl4030_madc_attributes,
};
-static int __devinit twl4030_madc_hwmon_probe(struct platform_device *pdev)
+static int twl4030_madc_hwmon_probe(struct platform_device *pdev)
{
int ret;
struct device *hwmon;
@@ -120,7 +120,7 @@ err_sysfs:
return ret;
}
-static int __devexit twl4030_madc_hwmon_remove(struct platform_device *pdev)
+static int twl4030_madc_hwmon_remove(struct platform_device *pdev)
{
hwmon_device_unregister(&pdev->dev);
sysfs_remove_group(&pdev->dev.kobj, &twl4030_madc_group);
diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c
index 44136bb6d04..fb3e69341c1 100644
--- a/drivers/hwmon/ultra45_env.c
+++ b/drivers/hwmon/ultra45_env.c
@@ -250,7 +250,7 @@ static const struct attribute_group env_group = {
.attrs = env_attributes,
};
-static int __devinit env_probe(struct platform_device *op)
+static int env_probe(struct platform_device *op)
{
struct env *p = kzalloc(sizeof(*p), GFP_KERNEL);
int err = -ENOMEM;
@@ -291,7 +291,7 @@ out_free:
goto out;
}
-static int __devexit env_remove(struct platform_device *op)
+static int env_remove(struct platform_device *op)
{
struct env *p = platform_get_drvdata(op);
@@ -321,7 +321,7 @@ static struct platform_driver env_driver = {
.of_match_table = env_match,
},
.probe = env_probe,
- .remove = __devexit_p(env_remove),
+ .remove = env_remove,
};
module_platform_driver(env_driver);
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index 4cddee04f2e..76f157b568e 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -121,7 +121,7 @@ static const struct attribute_group via_cputemp_group = {
/* Optional attributes */
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_cpu_vid, NULL);
-static int __devinit via_cputemp_probe(struct platform_device *pdev)
+static int via_cputemp_probe(struct platform_device *pdev)
{
struct via_cputemp_data *data;
struct cpuinfo_x86 *c = &cpu_data(pdev->id);
@@ -192,7 +192,7 @@ exit_remove:
return err;
}
-static int __devexit via_cputemp_remove(struct platform_device *pdev)
+static int via_cputemp_remove(struct platform_device *pdev)
{
struct via_cputemp_data *data = platform_get_drvdata(pdev);
@@ -209,7 +209,7 @@ static struct platform_driver via_cputemp_driver = {
.name = DRVNAME,
},
.probe = via_cputemp_probe,
- .remove = __devexit_p(via_cputemp_remove),
+ .remove = via_cputemp_remove,
};
struct pdev_entry {
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index 299399aa30f..e0e14a9f165 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -339,7 +339,7 @@ struct via686a_data {
static struct pci_dev *s_bridge; /* pointer to the (only) via686a */
static int via686a_probe(struct platform_device *pdev);
-static int __devexit via686a_remove(struct platform_device *pdev);
+static int via686a_remove(struct platform_device *pdev);
static inline int via686a_read_value(struct via686a_data *data, u8 reg)
{
@@ -677,12 +677,12 @@ static struct platform_driver via686a_driver = {
.name = "via686a",
},
.probe = via686a_probe,
- .remove = __devexit_p(via686a_remove),
+ .remove = via686a_remove,
};
/* This is called when the module is loaded */
-static int __devinit via686a_probe(struct platform_device *pdev)
+static int via686a_probe(struct platform_device *pdev)
{
struct via686a_data *data;
struct resource *res;
@@ -728,7 +728,7 @@ exit_remove_files:
return err;
}
-static int __devexit via686a_remove(struct platform_device *pdev)
+static int via686a_remove(struct platform_device *pdev)
{
struct via686a_data *data = platform_get_drvdata(pdev);
@@ -745,7 +745,7 @@ static void via686a_update_fan_div(struct via686a_data *data)
data->fan_div[1] = reg >> 6;
}
-static void __devinit via686a_init_device(struct via686a_data *data)
+static void via686a_init_device(struct via686a_data *data)
{
u8 reg;
@@ -833,7 +833,7 @@ static DEFINE_PCI_DEVICE_TABLE(via686a_pci_ids) = {
};
MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
-static int __devinit via686a_device_add(unsigned short address)
+static int via686a_device_add(unsigned short address)
{
struct resource res = {
.start = address,
@@ -874,7 +874,7 @@ exit:
return err;
}
-static int __devinit via686a_pci_probe(struct pci_dev *dev,
+static int via686a_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
u16 address, val;
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index f2c61153dba..751703059fa 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -1086,7 +1086,7 @@ static struct device_attribute vt1211_sysfs_misc[] = {
* Device registration and initialization
* --------------------------------------------------------------------- */
-static void __devinit vt1211_init_device(struct vt1211_data *data)
+static void vt1211_init_device(struct vt1211_data *data)
{
/* set VRM */
data->vrm = vid_which_vrm();
@@ -1141,7 +1141,7 @@ static void vt1211_remove_sysfs(struct platform_device *pdev)
device_remove_file(dev, &vt1211_sysfs_misc[i]);
}
-static int __devinit vt1211_probe(struct platform_device *pdev)
+static int vt1211_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct vt1211_data *data;
@@ -1217,7 +1217,7 @@ EXIT_DEV_REMOVE_SILENT:
return err;
}
-static int __devexit vt1211_remove(struct platform_device *pdev)
+static int vt1211_remove(struct platform_device *pdev)
{
struct vt1211_data *data = platform_get_drvdata(pdev);
@@ -1233,7 +1233,7 @@ static struct platform_driver vt1211_driver = {
.name = DRVNAME,
},
.probe = vt1211_probe,
- .remove = __devexit_p(vt1211_remove),
+ .remove = vt1211_remove,
};
static int __init vt1211_device_add(unsigned short address)
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
index 84e3dc5e3a8..a56355cef18 100644
--- a/drivers/hwmon/vt8231.c
+++ b/drivers/hwmon/vt8231.c
@@ -176,7 +176,7 @@ struct vt8231_data {
static struct pci_dev *s_bridge;
static int vt8231_probe(struct platform_device *pdev);
-static int __devexit vt8231_remove(struct platform_device *pdev);
+static int vt8231_remove(struct platform_device *pdev);
static struct vt8231_data *vt8231_update_device(struct device *dev);
static void vt8231_init_device(struct vt8231_data *data);
@@ -762,7 +762,7 @@ static struct platform_driver vt8231_driver = {
.name = "vt8231",
},
.probe = vt8231_probe,
- .remove = __devexit_p(vt8231_remove),
+ .remove = vt8231_remove,
};
static DEFINE_PCI_DEVICE_TABLE(vt8231_pci_ids) = {
@@ -772,7 +772,7 @@ static DEFINE_PCI_DEVICE_TABLE(vt8231_pci_ids) = {
MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
-static int __devinit vt8231_pci_probe(struct pci_dev *dev,
+static int vt8231_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id);
static struct pci_driver vt8231_pci_driver = {
@@ -851,7 +851,7 @@ exit_remove_files:
return err;
}
-static int __devexit vt8231_remove(struct platform_device *pdev)
+static int vt8231_remove(struct platform_device *pdev)
{
struct vt8231_data *data = platform_get_drvdata(pdev);
int i;
@@ -943,7 +943,7 @@ static struct vt8231_data *vt8231_update_device(struct device *dev)
return data;
}
-static int __devinit vt8231_device_add(unsigned short address)
+static int vt8231_device_add(unsigned short address)
{
struct resource res = {
.start = address,
@@ -984,7 +984,7 @@ exit:
return err;
}
-static int __devinit vt8231_pci_probe(struct pci_dev *dev,
+static int vt8231_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
u16 address, val;
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index de3c7e04c3b..55ac41c0556 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -1866,7 +1866,7 @@ static void w83627ehf_device_remove_files(struct device *dev)
}
/* Get the monitoring functions started */
-static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data,
+static inline void w83627ehf_init_device(struct w83627ehf_data *data,
enum kinds kind)
{
int i;
@@ -1952,7 +1952,7 @@ static void w82627ehf_swap_tempreg(struct w83627ehf_data *data,
data->reg_temp_config[r2] = tmp;
}
-static void __devinit
+static void
w83627ehf_set_temp_reg_ehf(struct w83627ehf_data *data, int n_temp)
{
int i;
@@ -1965,7 +1965,7 @@ w83627ehf_set_temp_reg_ehf(struct w83627ehf_data *data, int n_temp)
}
}
-static void __devinit
+static void
w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data,
struct w83627ehf_data *data)
{
@@ -2054,7 +2054,7 @@ w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data,
}
}
-static int __devinit w83627ehf_probe(struct platform_device *pdev)
+static int w83627ehf_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct w83627ehf_sio_data *sio_data = dev->platform_data;
@@ -2596,7 +2596,7 @@ exit:
return err;
}
-static int __devexit w83627ehf_remove(struct platform_device *pdev)
+static int w83627ehf_remove(struct platform_device *pdev)
{
struct w83627ehf_data *data = platform_get_drvdata(pdev);
@@ -2614,7 +2614,7 @@ static struct platform_driver w83627ehf_driver = {
.name = DRVNAME,
},
.probe = w83627ehf_probe,
- .remove = __devexit_p(w83627ehf_remove),
+ .remove = w83627ehf_remove,
};
/* w83627ehf_find() looks for a '627 in the Super-I/O config space */
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index af158990870..7f68b8309d1 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -393,7 +393,7 @@ struct w83627hf_data {
static int w83627hf_probe(struct platform_device *pdev);
-static int __devexit w83627hf_remove(struct platform_device *pdev);
+static int w83627hf_remove(struct platform_device *pdev);
static int w83627hf_read_value(struct w83627hf_data *data, u16 reg);
static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value);
@@ -407,7 +407,7 @@ static struct platform_driver w83627hf_driver = {
.name = DRVNAME,
},
.probe = w83627hf_probe,
- .remove = __devexit_p(w83627hf_remove),
+ .remove = w83627hf_remove,
};
static ssize_t
@@ -1342,7 +1342,7 @@ static const struct attribute_group w83627hf_group_opt = {
.attrs = w83627hf_attributes_opt,
};
-static int __devinit w83627hf_probe(struct platform_device *pdev)
+static int w83627hf_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct w83627hf_sio_data *sio_data = dev->platform_data;
@@ -1508,7 +1508,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
return err;
}
-static int __devexit w83627hf_remove(struct platform_device *pdev)
+static int w83627hf_remove(struct platform_device *pdev)
{
struct w83627hf_data *data = platform_get_drvdata(pdev);
@@ -1564,7 +1564,7 @@ static int w83627hf_read_value(struct w83627hf_data *data, u16 reg)
return res;
}
-static int __devinit w83627thf_read_gpio5(struct platform_device *pdev)
+static int w83627thf_read_gpio5(struct platform_device *pdev)
{
struct w83627hf_sio_data *sio_data = pdev->dev.platform_data;
int res = 0xff, sel;
@@ -1597,7 +1597,7 @@ exit:
return res;
}
-static int __devinit w83687thf_read_vid(struct platform_device *pdev)
+static int w83687thf_read_vid(struct platform_device *pdev)
{
struct w83627hf_sio_data *sio_data = pdev->dev.platform_data;
int res = 0xff;
@@ -1649,7 +1649,7 @@ static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value)
return 0;
}
-static void __devinit w83627hf_init_device(struct platform_device *pdev)
+static void w83627hf_init_device(struct platform_device *pdev)
{
struct w83627hf_data *data = platform_get_drvdata(pdev);
int i;
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index 20f11d31da4..93bd2863959 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -1764,7 +1764,7 @@ w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value)
return 0;
}
-static int __devinit
+static int
w83781d_isa_probe(struct platform_device *pdev)
{
int err, reg;
@@ -1824,7 +1824,7 @@ w83781d_isa_probe(struct platform_device *pdev)
return err;
}
-static int __devexit
+static int
w83781d_isa_remove(struct platform_device *pdev)
{
struct w83781d_data *data = platform_get_drvdata(pdev);
@@ -1842,7 +1842,7 @@ static struct platform_driver w83781d_isa_driver = {
.name = "w83781d",
},
.probe = w83781d_isa_probe,
- .remove = __devexit_p(w83781d_isa_remove),
+ .remove = w83781d_isa_remove,
};
/* return 1 if a supported chip is found, 0 otherwise */
diff --git a/drivers/hwmon/wm831x-hwmon.c b/drivers/hwmon/wm831x-hwmon.c
index d0db1f2738f..df6ceaf8d58 100644
--- a/drivers/hwmon/wm831x-hwmon.c
+++ b/drivers/hwmon/wm831x-hwmon.c
@@ -157,7 +157,7 @@ static const struct attribute_group wm831x_attr_group = {
.attrs = wm831x_attributes,
};
-static int __devinit wm831x_hwmon_probe(struct platform_device *pdev)
+static int wm831x_hwmon_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_hwmon *hwmon;
@@ -189,7 +189,7 @@ err_sysfs:
return ret;
}
-static int __devexit wm831x_hwmon_remove(struct platform_device *pdev)
+static int wm831x_hwmon_remove(struct platform_device *pdev)
{
struct wm831x_hwmon *hwmon = platform_get_drvdata(pdev);
@@ -201,7 +201,7 @@ static int __devexit wm831x_hwmon_remove(struct platform_device *pdev)
static struct platform_driver wm831x_hwmon_driver = {
.probe = wm831x_hwmon_probe,
- .remove = __devexit_p(wm831x_hwmon_remove),
+ .remove = wm831x_hwmon_remove,
.driver = {
.name = "wm831x-hwmon",
.owner = THIS_MODULE,
diff --git a/drivers/hwmon/wm8350-hwmon.c b/drivers/hwmon/wm8350-hwmon.c
index b955756bdb4..64bf75c9442 100644
--- a/drivers/hwmon/wm8350-hwmon.c
+++ b/drivers/hwmon/wm8350-hwmon.c
@@ -91,7 +91,7 @@ static const struct attribute_group wm8350_attr_group = {
.attrs = wm8350_attributes,
};
-static int __devinit wm8350_hwmon_probe(struct platform_device *pdev)
+static int wm8350_hwmon_probe(struct platform_device *pdev)
{
struct wm8350 *wm8350 = platform_get_drvdata(pdev);
int ret;
@@ -114,7 +114,7 @@ err:
return ret;
}
-static int __devexit wm8350_hwmon_remove(struct platform_device *pdev)
+static int wm8350_hwmon_remove(struct platform_device *pdev)
{
struct wm8350 *wm8350 = platform_get_drvdata(pdev);
@@ -126,7 +126,7 @@ static int __devexit wm8350_hwmon_remove(struct platform_device *pdev)
static struct platform_driver wm8350_hwmon_driver = {
.probe = wm8350_hwmon_probe,
- .remove = __devexit_p(wm8350_hwmon_remove),
+ .remove = wm8350_hwmon_remove,
.driver = {
.name = "wm8350-hwmon",
.owner = THIS_MODULE,
diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index 887d34effb3..292869cc903 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -78,7 +78,7 @@ static const struct hwspinlock_ops omap_hwspinlock_ops = {
.relax = omap_hwspinlock_relax,
};
-static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
+static int omap_hwspinlock_probe(struct platform_device *pdev)
{
struct hwspinlock_pdata *pdata = pdev->dev.platform_data;
struct hwspinlock_device *bank;
@@ -142,7 +142,7 @@ iounmap_base:
return ret;
}
-static int __devexit omap_hwspinlock_remove(struct platform_device *pdev)
+static int omap_hwspinlock_remove(struct platform_device *pdev)
{
struct hwspinlock_device *bank = platform_get_drvdata(pdev);
void __iomem *io_base = bank->lock[0].priv - LOCK_BASE_OFFSET;
@@ -163,7 +163,7 @@ static int __devexit omap_hwspinlock_remove(struct platform_device *pdev)
static struct platform_driver omap_hwspinlock_driver = {
.probe = omap_hwspinlock_probe,
- .remove = __devexit_p(omap_hwspinlock_remove),
+ .remove = omap_hwspinlock_remove,
.driver = {
.name = "omap_hwspinlock",
.owner = THIS_MODULE,
diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c
index 86980fe0411..401c33bcdb4 100644
--- a/drivers/hwspinlock/u8500_hsem.c
+++ b/drivers/hwspinlock/u8500_hsem.c
@@ -91,7 +91,7 @@ static const struct hwspinlock_ops u8500_hwspinlock_ops = {
.relax = u8500_hsem_relax,
};
-static int __devinit u8500_hsem_probe(struct platform_device *pdev)
+static int u8500_hsem_probe(struct platform_device *pdev)
{
struct hwspinlock_pdata *pdata = pdev->dev.platform_data;
struct hwspinlock_device *bank;
@@ -148,7 +148,7 @@ iounmap_base:
return ret;
}
-static int __devexit u8500_hsem_remove(struct platform_device *pdev)
+static int u8500_hsem_remove(struct platform_device *pdev)
{
struct hwspinlock_device *bank = platform_get_drvdata(pdev);
void __iomem *io_base = bank->lock[0].priv - HSEM_REGISTER_OFFSET;
@@ -172,7 +172,7 @@ static int __devexit u8500_hsem_remove(struct platform_device *pdev)
static struct platform_driver u8500_hsem_driver = {
.probe = u8500_hsem_probe,
- .remove = __devexit_p(u8500_hsem_remove),
+ .remove = u8500_hsem_remove,
.driver = {
.name = "u8500_hsem",
.owner = THIS_MODULE,
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index aa59a254be2..c02bf208084 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -39,6 +39,7 @@
#define AT91_TWI_STOP 0x0002 /* Send a Stop Condition */
#define AT91_TWI_MSEN 0x0004 /* Master Transfer Enable */
#define AT91_TWI_SVDIS 0x0020 /* Slave Transfer Disable */
+#define AT91_TWI_QUICK 0x0040 /* SMBus quick command */
#define AT91_TWI_SWRST 0x0080 /* Software Reset */
#define AT91_TWI_MMR 0x0004 /* Master Mode Register */
@@ -212,7 +213,11 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
INIT_COMPLETION(dev->cmd_complete);
dev->transfer_status = 0;
- if (dev->msg->flags & I2C_M_RD) {
+
+ if (!dev->buf_len) {
+ at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK);
+ at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP);
+ } else if (dev->msg->flags & I2C_M_RD) {
unsigned start_flags = AT91_TWI_START;
if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) {
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index 286ca191782..0670da79ee5 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -287,12 +287,14 @@ read_init_dma_fail:
select_init_dma_fail:
dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE);
select_init_pio_fail:
+ dmaengine_terminate_all(i2c->dmach);
return -EINVAL;
/* Write failpath. */
write_init_dma_fail:
dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
write_init_pio_fail:
+ dmaengine_terminate_all(i2c->dmach);
return -EINVAL;
}
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index bffd5501ac2..15da1ac7cf9 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -9,10 +9,6 @@
* kind, whether express or implied.
*/
-/*
- * This driver can be used from the device tree, see
- * Documentation/devicetree/bindings/i2c/ocore-i2c.txt
- */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index db31eaed6ea..3525c9e62cb 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -43,7 +43,6 @@
#include <linux/slab.h>
#include <linux/i2c-omap.h>
#include <linux/pm_runtime.h>
-#include <linux/pm_qos.h>
/* I2C controller revisions */
#define OMAP_I2C_OMAP1_REV_2 0x20
@@ -187,8 +186,9 @@ struct omap_i2c_dev {
int reg_shift; /* bit shift for I2C register addresses */
struct completion cmd_complete;
struct resource *ioarea;
- u32 latency; /* maximum MPU wkup latency */
- struct pm_qos_request pm_qos_request;
+ u32 latency; /* maximum mpu wkup latency */
+ void (*set_mpu_wkup_lat)(struct device *dev,
+ long latency);
u32 speed; /* Speed of bus in kHz */
u32 dtrev; /* extra revision from DT */
u32 flags;
@@ -494,7 +494,9 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
dev->b_hw = 1; /* Enable hardware fixes */
/* calculate wakeup latency constraint for MPU */
- dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8);
+ if (dev->set_mpu_wkup_lat != NULL)
+ dev->latency = (1000000 * dev->threshold) /
+ (1000 * dev->speed / 8);
}
/*
@@ -522,6 +524,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
dev->buf = msg->buf;
dev->buf_len = msg->len;
+ /* make sure writes to dev->buf_len are ordered */
+ barrier();
+
omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len);
/* Clear the FIFO Buffers */
@@ -579,7 +584,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
*/
timeout = wait_for_completion_timeout(&dev->cmd_complete,
OMAP_I2C_TIMEOUT);
- dev->buf_len = 0;
if (timeout == 0) {
dev_err(dev->dev, "controller timed out\n");
omap_i2c_init(dev);
@@ -629,16 +633,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
if (r < 0)
goto out;
- /*
- * When waiting for completion of a i2c transfer, we need to
- * set a wake up latency constraint for the MPU. This is to
- * ensure quick enough wakeup from idle, when transfer
- * completes.
- */
- if (dev->latency)
- pm_qos_add_request(&dev->pm_qos_request,
- PM_QOS_CPU_DMA_LATENCY,
- dev->latency);
+ if (dev->set_mpu_wkup_lat != NULL)
+ dev->set_mpu_wkup_lat(dev->dev, dev->latency);
for (i = 0; i < num; i++) {
r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
@@ -646,8 +642,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
break;
}
- if (dev->latency)
- pm_qos_remove_request(&dev->pm_qos_request);
+ if (dev->set_mpu_wkup_lat != NULL)
+ dev->set_mpu_wkup_lat(dev->dev, -1);
if (r == 0)
r = num;
@@ -1104,6 +1100,7 @@ omap_i2c_probe(struct platform_device *pdev)
} else if (pdata != NULL) {
dev->speed = pdata->clkrate;
dev->flags = pdata->flags;
+ dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
dev->dtrev = pdata->rev;
}
@@ -1159,8 +1156,9 @@ omap_i2c_probe(struct platform_device *pdev)
dev->b_hw = 1; /* Enable hardware fixes */
/* calculate wakeup latency constraint for MPU */
- dev->latency = (1000000 * dev->fifo_size) /
- (1000 * dev->speed / 8);
+ if (dev->set_mpu_wkup_lat != NULL)
+ dev->latency = (1000000 * dev->fifo_size) /
+ (1000 * dev->speed / 8);
}
/* reset ASAP, clearing any IRQs */
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 3e0335f1fc6..9d902725bac 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -806,6 +806,7 @@ static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c)
dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio);
goto free_gpio;
}
+ i2c->gpios[idx] = gpio;
ret = gpio_request(gpio, "i2c-bus");
if (ret) {
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index a7edf987a33..e388590b44a 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -39,6 +39,7 @@
#include <linux/irqflags.h>
#include <linux/rwsem.h>
#include <linux/pm_runtime.h>
+#include <linux/acpi.h>
#include <asm/uaccess.h>
#include "i2c-core.h"
@@ -78,6 +79,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
if (of_driver_match_device(dev, drv))
return 1;
+ /* Then ACPI style match */
+ if (acpi_driver_match_device(dev, drv))
+ return 1;
+
driver = to_i2c_driver(drv);
/* match on an id table if there is one */
if (driver->id_table)
@@ -539,6 +544,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
client->dev.bus = &i2c_bus_type;
client->dev.type = &i2c_client_type;
client->dev.of_node = info->of_node;
+ ACPI_HANDLE_SET(&client->dev, info->acpi_node.handle);
/* For 10-bit clients, add an arbitrary offset to avoid collisions */
dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c
index 5f097f309b9..7fa5b24b16d 100644
--- a/drivers/i2c/muxes/i2c-mux-pinctrl.c
+++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c
@@ -169,7 +169,7 @@ static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev)
mux->busses = devm_kzalloc(&pdev->dev,
sizeof(mux->busses) * mux->pdata->bus_count,
GFP_KERNEL);
- if (!mux->states) {
+ if (!mux->busses) {
dev_err(&pdev->dev, "Cannot allocate busses\n");
ret = -ENOMEM;
goto err;
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index b0f6b4c8ee1..c49c04d9c2b 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -56,7 +56,6 @@
#include <linux/kernel.h>
#include <linux/cpuidle.h>
#include <linux/clockchips.h>
-#include <linux/hrtimer.h> /* ktime_get_real() */
#include <trace/events/power.h>
#include <linux/sched.h>
#include <linux/notifier.h>
@@ -72,6 +71,7 @@
static struct cpuidle_driver intel_idle_driver = {
.name = "intel_idle",
.owner = THIS_MODULE,
+ .en_core_tk_irqen = 1,
};
/* intel_idle.max_cstate=0 disables driver */
static int max_cstate = MWAIT_MAX_NUM_CSTATES - 1;
@@ -281,8 +281,6 @@ static int intel_idle(struct cpuidle_device *dev,
struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
unsigned long eax = (unsigned long)cpuidle_get_statedata(state_usage);
unsigned int cstate;
- ktime_t kt_before, kt_after;
- s64 usec_delta;
int cpu = smp_processor_id();
cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1;
@@ -297,8 +295,6 @@ static int intel_idle(struct cpuidle_device *dev,
if (!(lapic_timer_reliable_states & (1 << (cstate))))
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
- kt_before = ktime_get_real();
-
stop_critical_timings();
if (!need_resched()) {
@@ -310,17 +306,9 @@ static int intel_idle(struct cpuidle_device *dev,
start_critical_timings();
- kt_after = ktime_get_real();
- usec_delta = ktime_to_us(ktime_sub(kt_after, kt_before));
-
- local_irq_enable();
-
if (!(lapic_timer_reliable_states & (1 << (cstate))))
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
- /* Update cpuidle counters */
- dev->last_residency = (int)usec_delta;
-
return index;
}
diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index fc937aca71f..b2f963be399 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -20,6 +20,12 @@ config IIO_BUFFER
if IIO_BUFFER
+config IIO_BUFFER_CB
+boolean "IIO callback buffer used for push in-kernel interfaces"
+ help
+ Should be selected by any drivers that do-inkernel push
+ usage. That is, those where the data is pushed to the consumer.
+
config IIO_KFIFO_BUF
select IIO_TRIGGER
tristate "Industrial I/O buffering based on kfifo"
@@ -57,11 +63,12 @@ config IIO_CONSUMERS_PER_TRIGGER
source "drivers/iio/accel/Kconfig"
source "drivers/iio/adc/Kconfig"
source "drivers/iio/amplifiers/Kconfig"
-source "drivers/iio/light/Kconfig"
-source "drivers/iio/frequency/Kconfig"
-source "drivers/iio/dac/Kconfig"
source "drivers/iio/common/Kconfig"
+source "drivers/iio/dac/Kconfig"
+source "drivers/iio/frequency/Kconfig"
source "drivers/iio/gyro/Kconfig"
+source "drivers/iio/imu/Kconfig"
+source "drivers/iio/light/Kconfig"
source "drivers/iio/magnetometer/Kconfig"
endif # IIO
diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
index 761f2b65ac5..a0e8cdd67e4 100644
--- a/drivers/iio/Makefile
+++ b/drivers/iio/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_IIO) += industrialio.o
industrialio-y := industrialio-core.o industrialio-event.o inkern.o
industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o
industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o
+industrialio-$(CONFIG_IIO_BUFFER_CB) += buffer_cb.o
obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o
obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o
@@ -13,9 +14,10 @@ obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o
obj-y += accel/
obj-y += adc/
obj-y += amplifiers/
-obj-y += light/
-obj-y += frequency/
-obj-y += dac/
obj-y += common/
+obj-y += dac/
obj-y += gyro/
+obj-y += frequency/
+obj-y += imu/
+obj-y += light/
obj-y += magnetometer/
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index b2510c4d9a5..fe4bcd7c5b1 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -8,7 +8,7 @@ config HID_SENSOR_ACCEL_3D
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select HID_SENSOR_IIO_COMMON
- tristate "HID Acelerometers 3D"
+ tristate "HID Accelerometers 3D"
help
Say yes here to build support for the HID SENSOR
accelerometers 3D.
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index 314a4057879..e67bb912bd1 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -197,21 +197,8 @@ 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)
{
- struct iio_buffer *buffer = indio_dev->buffer;
- int datum_sz;
-
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
- if (!buffer) {
- dev_err(&indio_dev->dev, "Buffer == NULL\n");
- return;
- }
- datum_sz = buffer->access->get_bytes_per_datum(buffer);
- if (len > datum_sz) {
- dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
- datum_sz);
- return;
- }
- iio_push_to_buffer(buffer, (u8 *)data);
+ iio_push_to_buffers(indio_dev, (u8 *)data);
}
/* Callback handler to send event after all samples are received and captured */
@@ -319,10 +306,10 @@ static int __devinit hid_accel_3d_probe(struct platform_device *pdev)
goto error_free_dev;
}
- channels = kmemdup(accel_3d_channels,
- sizeof(accel_3d_channels),
- GFP_KERNEL);
+ channels = kmemdup(accel_3d_channels, sizeof(accel_3d_channels),
+ GFP_KERNEL);
if (!channels) {
+ ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
goto error_free_dev;
}
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 49275812033..961b8d0a4ba 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -18,6 +18,18 @@ config AD7266
Say yes here to build support for Analog Devices AD7265 and AD7266
ADCs.
+config AD7298
+ tristate "Analog Devices AD7298 ADC driver"
+ depends on SPI
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for Analog Devices AD7298
+ 8 Channel ADC with temperature sensor.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ad7298.
+
config AD7791
tristate "Analog Devices AD7791 ADC driver"
depends on SPI
@@ -30,6 +42,18 @@ config AD7791
To compile this driver as a module, choose M here: the module will be
called ad7791.
+config AD7793
+ tristate "Analog Devices AD7793 and similar ADCs driver"
+ depends on SPI
+ select AD_SIGMA_DELTA
+ help
+ Say yes here to build support for Analog Devices AD7785, AD7792, AD7793,
+ AD7794 and AD7795 SPI analog to digital converters (ADC).
+ If unsure, say N (but it's safe to say "Y").
+
+ To compile this driver as a module, choose M here: the
+ module will be called AD7793.
+
config AD7476
tristate "Analog Devices AD7476 and similar 1-channel ADCs driver"
depends on SPI
@@ -45,6 +69,19 @@ config AD7476
To compile this driver as a module, choose M here: the
module will be called ad7476.
+config AD7887
+ tristate "Analog Devices AD7887 ADC driver"
+ depends on SPI
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for Analog Devices
+ AD7887 SPI analog to digital converter (ADC).
+ If unsure, say N (but it's safe to say "Y").
+
+ To compile this driver as a module, choose M here: the
+ module will be called ad7887.
+
config AT91_ADC
tristate "Atmel AT91 ADC"
depends on ARCH_AT91
@@ -60,4 +97,32 @@ config LP8788_ADC
help
Say yes here to build support for TI LP8788 ADC.
+config MAX1363
+ tristate "Maxim max1363 ADC driver"
+ depends on I2C
+ select IIO_TRIGGER
+ select MAX1363_RING_BUFFER
+ select IIO_BUFFER
+ select IIO_KFIFO_BUF
+ help
+ Say yes here to build support for many Maxim i2c analog to digital
+ converters (ADC). (max1361, max1362, max1363, max1364, max1036,
+ max1037, max1038, max1039, max1136, max1136, max1137, max1138,
+ max1139, max1236, max1237, max11238, max1239, max11600, max11601,
+ max11602, max11603, max11604, max11605, max11606, max11607,
+ max11608, max11609, max11610, max11611, max11612, max11613,
+ max11614, max11615, max11616, max11617, max11644, max11645,
+ max11646, max11647) Provides direct access via sysfs and buffered
+ data via the iio dev interface.
+
+config TI_ADC081C
+ tristate "Texas Instruments ADC081C021/027"
+ depends on I2C
+ help
+ If you say yes here you get support for Texas Instruments ADC081C021
+ and ADC081C027 ADC chips.
+
+ This driver can also be built as a module. If so, the module will be
+ called ti-adc081c.
+
endmenu
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 900995d5e17..472fd7cd241 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -4,7 +4,13 @@
obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
obj-$(CONFIG_AD7266) += ad7266.o
+obj-$(CONFIG_AD7298) += ad7298.o
obj-$(CONFIG_AD7476) += ad7476.o
obj-$(CONFIG_AD7791) += ad7791.o
+obj-$(CONFIG_AD7793) += ad7793.o
+obj-$(CONFIG_AD7887) += ad7887.o
obj-$(CONFIG_AT91_ADC) += at91_adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
+obj-$(CONFIG_MAX1363) += max1363.o
+obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
+
diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c
index b11f214779a..a6f4fc5f820 100644
--- a/drivers/iio/adc/ad7266.c
+++ b/drivers/iio/adc/ad7266.c
@@ -91,7 +91,6 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
- struct iio_buffer *buffer = indio_dev->buffer;
struct ad7266_state *st = iio_priv(indio_dev);
int ret;
@@ -99,7 +98,7 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p)
if (ret == 0) {
if (indio_dev->scan_timestamp)
((s64 *)st->data)[1] = pf->timestamp;
- iio_push_to_buffer(buffer, (u8 *)st->data);
+ iio_push_to_buffers(indio_dev, (u8 *)st->data);
}
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/iio/adc/ad7298.c
index 4c75114e7d7..2364807a5d6 100644
--- a/drivers/staging/iio/adc/ad7298_core.c
+++ b/drivers/iio/adc/ad7298.c
@@ -15,12 +15,48 @@
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/interrupt.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
-
-#include "ad7298.h"
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#include <linux/platform_data/ad7298.h>
+
+#define AD7298_WRITE (1 << 15) /* write to the control register */
+#define AD7298_REPEAT (1 << 14) /* repeated conversion enable */
+#define AD7298_CH(x) (1 << (13 - (x))) /* channel select */
+#define AD7298_TSENSE (1 << 5) /* temperature conversion enable */
+#define AD7298_EXTREF (1 << 2) /* external reference enable */
+#define AD7298_TAVG (1 << 1) /* temperature sensor averaging enable */
+#define AD7298_PDD (1 << 0) /* partial power down enable */
+
+#define AD7298_MAX_CHAN 8
+#define AD7298_BITS 12
+#define AD7298_STORAGE_BITS 16
+#define AD7298_INTREF_mV 2500
+
+#define AD7298_CH_TEMP 9
+
+#define RES_MASK(bits) ((1 << (bits)) - 1)
+
+struct ad7298_state {
+ struct spi_device *spi;
+ struct regulator *reg;
+ unsigned ext_ref;
+ struct spi_transfer ring_xfer[10];
+ struct spi_transfer scan_single_xfer[3];
+ struct spi_message ring_msg;
+ struct spi_message scan_single_msg;
+ /*
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache lines.
+ */
+ __be16 rx_buf[12] ____cacheline_aligned;
+ __be16 tx_buf[2];
+};
#define AD7298_V_CHAN(index) \
{ \
@@ -35,6 +71,7 @@
.sign = 'u', \
.realbits = 12, \
.storagebits = 16, \
+ .endianness = IIO_BE, \
}, \
}
@@ -44,7 +81,8 @@ static const struct iio_chan_spec ad7298_channels[] = {
.indexed = 1,
.channel = 0,
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
+ IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+ IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
.address = AD7298_CH_TEMP,
.scan_index = -1,
.scan_type = {
@@ -64,6 +102,84 @@ static const struct iio_chan_spec ad7298_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(8),
};
+/**
+ * ad7298_update_scan_mode() setup the spi transfer buffer for the new scan mask
+ **/
+static int ad7298_update_scan_mode(struct iio_dev *indio_dev,
+ const unsigned long *active_scan_mask)
+{
+ struct ad7298_state *st = iio_priv(indio_dev);
+ int i, m;
+ unsigned short command;
+ int scan_count;
+
+ /* Now compute overall size */
+ scan_count = bitmap_weight(active_scan_mask, indio_dev->masklength);
+
+ command = AD7298_WRITE | st->ext_ref;
+
+ for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1)
+ if (test_bit(i, active_scan_mask))
+ command |= m;
+
+ st->tx_buf[0] = cpu_to_be16(command);
+
+ /* build spi ring message */
+ st->ring_xfer[0].tx_buf = &st->tx_buf[0];
+ st->ring_xfer[0].len = 2;
+ st->ring_xfer[0].cs_change = 1;
+ st->ring_xfer[1].tx_buf = &st->tx_buf[1];
+ st->ring_xfer[1].len = 2;
+ st->ring_xfer[1].cs_change = 1;
+
+ spi_message_init(&st->ring_msg);
+ spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg);
+ spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg);
+
+ for (i = 0; i < scan_count; i++) {
+ st->ring_xfer[i + 2].rx_buf = &st->rx_buf[i];
+ st->ring_xfer[i + 2].len = 2;
+ st->ring_xfer[i + 2].cs_change = 1;
+ spi_message_add_tail(&st->ring_xfer[i + 2], &st->ring_msg);
+ }
+ /* make sure last transfer cs_change is not set */
+ st->ring_xfer[i + 1].cs_change = 0;
+
+ return 0;
+}
+
+/**
+ * ad7298_trigger_handler() bh of trigger launched polling to ring buffer
+ *
+ * Currently there is no option in this driver to disable the saving of
+ * timestamps within the ring.
+ **/
+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);
+
+done:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch)
{
int ret;
@@ -79,7 +195,7 @@ static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch)
static int ad7298_scan_temp(struct ad7298_state *st, int *val)
{
- int tmp, ret;
+ int ret;
__be16 buf;
buf = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE |
@@ -101,24 +217,24 @@ static int ad7298_scan_temp(struct ad7298_state *st, int *val)
if (ret)
return ret;
- tmp = be16_to_cpu(buf) & RES_MASK(AD7298_BITS);
+ *val = sign_extend32(be16_to_cpu(buf), 11);
- /*
- * One LSB of the ADC corresponds to 0.25 deg C.
- * The temperature reading is in 12-bit twos complement format
- */
+ return 0;
+}
- if (tmp & (1 << (AD7298_BITS - 1))) {
- tmp = (4096 - tmp) * 250;
- tmp -= (2 * tmp);
+static int ad7298_get_ref_voltage(struct ad7298_state *st)
+{
+ int vref;
+
+ if (st->ext_ref) {
+ vref = regulator_get_voltage(st->reg);
+ if (vref < 0)
+ return vref;
+ return vref / 1000;
} else {
- tmp *= 250; /* temperature in milli degrees Celsius */
+ return AD7298_INTREF_mV;
}
-
- *val = tmp;
-
- return 0;
}
static int ad7298_read_raw(struct iio_dev *indio_dev,
@@ -129,7 +245,6 @@ static int ad7298_read_raw(struct iio_dev *indio_dev,
{
int ret;
struct ad7298_state *st = iio_priv(indio_dev);
- unsigned int scale_uv;
switch (m) {
case IIO_CHAN_INFO_RAW:
@@ -154,17 +269,19 @@ static int ad7298_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_VOLTAGE:
- scale_uv = (st->int_vref_mv * 1000) >> AD7298_BITS;
- *val = scale_uv / 1000;
- *val2 = (scale_uv % 1000) * 1000;
- return IIO_VAL_INT_PLUS_MICRO;
+ *val = ad7298_get_ref_voltage(st);
+ *val2 = chan->scan_type.realbits;
+ return IIO_VAL_FRACTIONAL_LOG2;
case IIO_TEMP:
- *val = 1;
- *val2 = 0;
- return IIO_VAL_INT_PLUS_MICRO;
+ *val = ad7298_get_ref_voltage(st);
+ *val2 = 10;
+ return IIO_VAL_FRACTIONAL;
default:
return -EINVAL;
}
+ case IIO_CHAN_INFO_OFFSET:
+ *val = 1093 - 2732500 / ad7298_get_ref_voltage(st);
+ return IIO_VAL_INT;
}
return -EINVAL;
}
@@ -179,16 +296,23 @@ static int __devinit ad7298_probe(struct spi_device *spi)
{
struct ad7298_platform_data *pdata = spi->dev.platform_data;
struct ad7298_state *st;
- int ret;
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+ int ret;
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
- st->reg = regulator_get(&spi->dev, "vcc");
- if (!IS_ERR(st->reg)) {
+ if (pdata && pdata->ext_ref)
+ st->ext_ref = AD7298_EXTREF;
+
+ if (st->ext_ref) {
+ st->reg = regulator_get(&spi->dev, "vref");
+ if (IS_ERR(st->reg)) {
+ ret = PTR_ERR(st->reg);
+ goto error_free;
+ }
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
@@ -221,14 +345,8 @@ static int __devinit ad7298_probe(struct spi_device *spi)
spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg);
spi_message_add_tail(&st->scan_single_xfer[2], &st->scan_single_msg);
- if (pdata && pdata->vref_mv) {
- st->int_vref_mv = pdata->vref_mv;
- st->ext_ref = AD7298_EXTREF;
- } else {
- st->int_vref_mv = AD7298_INTREF_mV;
- }
-
- ret = ad7298_register_ring_funcs_and_init(indio_dev);
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ &ad7298_trigger_handler, NULL);
if (ret)
goto error_disable_reg;
@@ -239,13 +357,14 @@ static int __devinit ad7298_probe(struct spi_device *spi)
return 0;
error_cleanup_ring:
- ad7298_ring_cleanup(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg:
- if (!IS_ERR(st->reg))
+ if (st->ext_ref)
regulator_disable(st->reg);
error_put_reg:
- if (!IS_ERR(st->reg))
+ if (st->ext_ref)
regulator_put(st->reg);
+error_free:
iio_device_free(indio_dev);
return ret;
@@ -257,8 +376,8 @@ static int __devexit ad7298_remove(struct spi_device *spi)
struct ad7298_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- ad7298_ring_cleanup(indio_dev);
- if (!IS_ERR(st->reg)) {
+ iio_triggered_buffer_cleanup(indio_dev);
+ if (st->ext_ref) {
regulator_disable(st->reg);
regulator_put(st->reg);
}
diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c
index 7f2f45a0a48..330248bfeba 100644
--- a/drivers/iio/adc/ad7476.c
+++ b/drivers/iio/adc/ad7476.c
@@ -76,7 +76,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
((s64 *)st->data)[1] = time_ns;
- iio_push_to_buffer(indio_dev->buffer, st->data);
+ iio_push_to_buffers(indio_dev, st->data);
done:
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c
index 691a7be6f5c..334e31ff7a4 100644
--- a/drivers/staging/iio/adc/ad7793.c
+++ b/drivers/iio/adc/ad7793.c
@@ -25,8 +25,106 @@
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/adc/ad_sigma_delta.h>
-
-#include "ad7793.h"
+#include <linux/platform_data/ad7793.h>
+
+/* Registers */
+#define AD7793_REG_COMM 0 /* Communications Register (WO, 8-bit) */
+#define AD7793_REG_STAT 0 /* Status Register (RO, 8-bit) */
+#define AD7793_REG_MODE 1 /* Mode Register (RW, 16-bit */
+#define AD7793_REG_CONF 2 /* Configuration Register (RW, 16-bit) */
+#define AD7793_REG_DATA 3 /* Data Register (RO, 16-/24-bit) */
+#define AD7793_REG_ID 4 /* ID Register (RO, 8-bit) */
+#define AD7793_REG_IO 5 /* IO Register (RO, 8-bit) */
+#define AD7793_REG_OFFSET 6 /* Offset Register (RW, 16-bit
+ * (AD7792)/24-bit (AD7793)) */
+#define AD7793_REG_FULLSALE 7 /* Full-Scale Register
+ * (RW, 16-bit (AD7792)/24-bit (AD7793)) */
+
+/* Communications Register Bit Designations (AD7793_REG_COMM) */
+#define AD7793_COMM_WEN (1 << 7) /* Write Enable */
+#define AD7793_COMM_WRITE (0 << 6) /* Write Operation */
+#define AD7793_COMM_READ (1 << 6) /* Read Operation */
+#define AD7793_COMM_ADDR(x) (((x) & 0x7) << 3) /* Register Address */
+#define AD7793_COMM_CREAD (1 << 2) /* Continuous Read of Data Register */
+
+/* Status Register Bit Designations (AD7793_REG_STAT) */
+#define AD7793_STAT_RDY (1 << 7) /* Ready */
+#define AD7793_STAT_ERR (1 << 6) /* Error (Overrange, Underrange) */
+#define AD7793_STAT_CH3 (1 << 2) /* Channel 3 */
+#define AD7793_STAT_CH2 (1 << 1) /* Channel 2 */
+#define AD7793_STAT_CH1 (1 << 0) /* Channel 1 */
+
+/* Mode Register Bit Designations (AD7793_REG_MODE) */
+#define AD7793_MODE_SEL(x) (((x) & 0x7) << 13) /* Operation Mode Select */
+#define AD7793_MODE_SEL_MASK (0x7 << 13) /* Operation Mode Select mask */
+#define AD7793_MODE_CLKSRC(x) (((x) & 0x3) << 6) /* ADC Clock Source Select */
+#define AD7793_MODE_RATE(x) ((x) & 0xF) /* Filter Update Rate Select */
+
+#define AD7793_MODE_CONT 0 /* Continuous Conversion Mode */
+#define AD7793_MODE_SINGLE 1 /* Single Conversion Mode */
+#define AD7793_MODE_IDLE 2 /* Idle Mode */
+#define AD7793_MODE_PWRDN 3 /* Power-Down Mode */
+#define AD7793_MODE_CAL_INT_ZERO 4 /* Internal Zero-Scale Calibration */
+#define AD7793_MODE_CAL_INT_FULL 5 /* Internal Full-Scale Calibration */
+#define AD7793_MODE_CAL_SYS_ZERO 6 /* System Zero-Scale Calibration */
+#define AD7793_MODE_CAL_SYS_FULL 7 /* System Full-Scale Calibration */
+
+#define AD7793_CLK_INT 0 /* Internal 64 kHz Clock not
+ * available at the CLK pin */
+#define AD7793_CLK_INT_CO 1 /* Internal 64 kHz Clock available
+ * at the CLK pin */
+#define AD7793_CLK_EXT 2 /* External 64 kHz Clock */
+#define AD7793_CLK_EXT_DIV2 3 /* External Clock divided by 2 */
+
+/* Configuration Register Bit Designations (AD7793_REG_CONF) */
+#define AD7793_CONF_VBIAS(x) (((x) & 0x3) << 14) /* Bias Voltage
+ * Generator Enable */
+#define AD7793_CONF_BO_EN (1 << 13) /* Burnout Current Enable */
+#define AD7793_CONF_UNIPOLAR (1 << 12) /* Unipolar/Bipolar Enable */
+#define AD7793_CONF_BOOST (1 << 11) /* Boost Enable */
+#define AD7793_CONF_GAIN(x) (((x) & 0x7) << 8) /* Gain Select */
+#define AD7793_CONF_REFSEL(x) ((x) << 6) /* INT/EXT Reference Select */
+#define AD7793_CONF_BUF (1 << 4) /* Buffered Mode Enable */
+#define AD7793_CONF_CHAN(x) ((x) & 0xf) /* Channel select */
+#define AD7793_CONF_CHAN_MASK 0xf /* Channel select mask */
+
+#define AD7793_CH_AIN1P_AIN1M 0 /* AIN1(+) - AIN1(-) */
+#define AD7793_CH_AIN2P_AIN2M 1 /* AIN2(+) - AIN2(-) */
+#define AD7793_CH_AIN3P_AIN3M 2 /* AIN3(+) - AIN3(-) */
+#define AD7793_CH_AIN1M_AIN1M 3 /* AIN1(-) - AIN1(-) */
+#define AD7793_CH_TEMP 6 /* Temp Sensor */
+#define AD7793_CH_AVDD_MONITOR 7 /* AVDD Monitor */
+
+#define AD7795_CH_AIN4P_AIN4M 4 /* AIN4(+) - AIN4(-) */
+#define AD7795_CH_AIN5P_AIN5M 5 /* AIN5(+) - AIN5(-) */
+#define AD7795_CH_AIN6P_AIN6M 6 /* AIN6(+) - AIN6(-) */
+#define AD7795_CH_AIN1M_AIN1M 8 /* AIN1(-) - AIN1(-) */
+
+/* ID Register Bit Designations (AD7793_REG_ID) */
+#define AD7785_ID 0xB
+#define AD7792_ID 0xA
+#define AD7793_ID 0xB
+#define AD7794_ID 0xF
+#define AD7795_ID 0xF
+#define AD7796_ID 0xA
+#define AD7797_ID 0xB
+#define AD7798_ID 0x8
+#define AD7799_ID 0x9
+#define AD7793_ID_MASK 0xF
+
+/* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */
+#define AD7793_IO_IEXC1_IOUT1_IEXC2_IOUT2 0 /* IEXC1 connect to IOUT1,
+ * IEXC2 connect to IOUT2 */
+#define AD7793_IO_IEXC1_IOUT2_IEXC2_IOUT1 1 /* IEXC1 connect to IOUT2,
+ * IEXC2 connect to IOUT1 */
+#define AD7793_IO_IEXC1_IEXC2_IOUT1 2 /* Both current sources
+ * IEXC1,2 connect to IOUT1 */
+#define AD7793_IO_IEXC1_IEXC2_IOUT2 3 /* Both current sources
+ * IEXC1,2 connect to IOUT2 */
+
+#define AD7793_IO_IXCEN_10uA (1 << 0) /* Excitation Current 10uA */
+#define AD7793_IO_IXCEN_210uA (2 << 0) /* Excitation Current 210uA */
+#define AD7793_IO_IXCEN_1mA (3 << 0) /* Excitation Current 1mA */
/* NOTE:
* The AD7792/AD7793 features a dual use data out ready DOUT/RDY output.
@@ -36,9 +134,21 @@
* The DOUT/RDY output must also be wired to an interrupt capable GPIO.
*/
+#define AD7793_FLAG_HAS_CLKSEL BIT(0)
+#define AD7793_FLAG_HAS_REFSEL BIT(1)
+#define AD7793_FLAG_HAS_VBIAS BIT(2)
+#define AD7793_HAS_EXITATION_CURRENT BIT(3)
+#define AD7793_FLAG_HAS_GAIN BIT(4)
+#define AD7793_FLAG_HAS_BUFFER BIT(5)
+
struct ad7793_chip_info {
+ unsigned int id;
const struct iio_chan_spec *channels;
unsigned int num_channels;
+ unsigned int flags;
+
+ const struct iio_info *iio_info;
+ const u16 *sample_freq_avail;
};
struct ad7793_state {
@@ -59,6 +169,10 @@ enum ad7793_supported_device_ids {
ID_AD7793,
ID_AD7794,
ID_AD7795,
+ ID_AD7796,
+ ID_AD7797,
+ ID_AD7798,
+ ID_AD7799,
};
static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd)
@@ -110,19 +224,52 @@ static int ad7793_calibrate_all(struct ad7793_state *st)
ARRAY_SIZE(ad7793_calib_arr));
}
-static int ad7793_setup(struct iio_dev *indio_dev,
+static int ad7793_check_platform_data(struct ad7793_state *st,
const struct ad7793_platform_data *pdata)
{
+ if ((pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT1 ||
+ pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT2) &&
+ ((pdata->exitation_current != AD7793_IX_10uA) &&
+ (pdata->exitation_current != AD7793_IX_210uA)))
+ return -EINVAL;
+
+ if (!(st->chip_info->flags & AD7793_FLAG_HAS_CLKSEL) &&
+ pdata->clock_src != AD7793_CLK_SRC_INT)
+ return -EINVAL;
+
+ if (!(st->chip_info->flags & AD7793_FLAG_HAS_REFSEL) &&
+ pdata->refsel != AD7793_REFSEL_REFIN1)
+ return -EINVAL;
+
+ if (!(st->chip_info->flags & AD7793_FLAG_HAS_VBIAS) &&
+ pdata->bias_voltage != AD7793_BIAS_VOLTAGE_DISABLED)
+ return -EINVAL;
+
+ if (!(st->chip_info->flags & AD7793_HAS_EXITATION_CURRENT) &&
+ pdata->exitation_current != AD7793_IX_DISABLED)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int ad7793_setup(struct iio_dev *indio_dev,
+ const struct ad7793_platform_data *pdata,
+ unsigned int vref_mv)
+{
struct ad7793_state *st = iio_priv(indio_dev);
int i, ret = -1;
unsigned long long scale_uv;
u32 id;
+ ret = ad7793_check_platform_data(st, pdata);
+ if (ret)
+ return ret;
+
/* reset the serial interface */
ret = spi_write(st->sd.spi, (u8 *)&ret, sizeof(ret));
if (ret < 0)
goto out;
- msleep(1); /* Wait for at least 500us */
+ usleep_range(500, 2000); /* Wait for at least 500us */
/* write/read test for device presence */
ret = ad_sd_read_reg(&st->sd, AD7793_REG_ID, 1, &id);
@@ -131,13 +278,32 @@ static int ad7793_setup(struct iio_dev *indio_dev,
id &= AD7793_ID_MASK;
- if (!((id == AD7792_ID) || (id == AD7793_ID) || (id == AD7795_ID))) {
+ if (id != st->chip_info->id) {
dev_err(&st->sd.spi->dev, "device ID query failed\n");
goto out;
}
- st->mode = pdata->mode;
- st->conf = pdata->conf;
+ st->mode = AD7793_MODE_RATE(1);
+ st->conf = 0;
+
+ if (st->chip_info->flags & AD7793_FLAG_HAS_CLKSEL)
+ st->mode |= AD7793_MODE_CLKSRC(pdata->clock_src);
+ if (st->chip_info->flags & AD7793_FLAG_HAS_REFSEL)
+ st->conf |= AD7793_CONF_REFSEL(pdata->refsel);
+ if (st->chip_info->flags & AD7793_FLAG_HAS_VBIAS)
+ st->conf |= AD7793_CONF_VBIAS(pdata->bias_voltage);
+ if (pdata->buffered || !(st->chip_info->flags & AD7793_FLAG_HAS_BUFFER))
+ st->conf |= AD7793_CONF_BUF;
+ if (pdata->boost_enable &&
+ (st->chip_info->flags & AD7793_FLAG_HAS_VBIAS))
+ st->conf |= AD7793_CONF_BOOST;
+ if (pdata->burnout_current)
+ st->conf |= AD7793_CONF_BO_EN;
+ if (pdata->unipolar)
+ st->conf |= AD7793_CONF_UNIPOLAR;
+
+ if (!(st->chip_info->flags & AD7793_FLAG_HAS_GAIN))
+ st->conf |= AD7793_CONF_GAIN(7);
ret = ad7793_set_mode(&st->sd, AD_SD_MODE_IDLE);
if (ret)
@@ -147,10 +313,13 @@ static int ad7793_setup(struct iio_dev *indio_dev,
if (ret)
goto out;
- ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO,
- sizeof(pdata->io), pdata->io);
- if (ret)
- goto out;
+ if (st->chip_info->flags & AD7793_HAS_EXITATION_CURRENT) {
+ ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO, 1,
+ pdata->exitation_current |
+ (pdata->current_source_direction << 2));
+ if (ret)
+ goto out;
+ }
ret = ad7793_calibrate_all(st);
if (ret)
@@ -158,7 +327,7 @@ static int ad7793_setup(struct iio_dev *indio_dev,
/* Populate available ADC input ranges */
for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) {
- scale_uv = ((u64)st->int_vref_mv * 100000000)
+ scale_uv = ((u64)vref_mv * 100000000)
>> (st->chip_info->channels[0].scan_type.realbits -
(!!(st->conf & AD7793_CONF_UNIPOLAR) ? 0 : 1));
scale_uv >>= i;
@@ -173,8 +342,11 @@ out:
return ret;
}
-static const u16 sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39, 33, 19,
- 17, 16, 12, 10, 8, 6, 4};
+static const u16 ad7793_sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39,
+ 33, 19, 17, 16, 12, 10, 8, 6, 4};
+
+static const u16 ad7797_sample_freq_avail[16] = {0, 0, 0, 123, 62, 50, 0,
+ 33, 0, 17, 16, 12, 10, 8, 6, 4};
static ssize_t ad7793_read_frequency(struct device *dev,
struct device_attribute *attr,
@@ -184,7 +356,7 @@ static ssize_t ad7793_read_frequency(struct device *dev,
struct ad7793_state *st = iio_priv(indio_dev);
return sprintf(buf, "%d\n",
- sample_freq_avail[AD7793_MODE_RATE(st->mode)]);
+ st->chip_info->sample_freq_avail[AD7793_MODE_RATE(st->mode)]);
}
static ssize_t ad7793_write_frequency(struct device *dev,
@@ -204,14 +376,17 @@ static ssize_t ad7793_write_frequency(struct device *dev,
}
mutex_unlock(&indio_dev->mlock);
- ret = strict_strtol(buf, 10, &lval);
+ ret = kstrtol(buf, 10, &lval);
if (ret)
return ret;
+ if (lval == 0)
+ return -EINVAL;
+
ret = -EINVAL;
- for (i = 0; i < ARRAY_SIZE(sample_freq_avail); i++)
- if (lval == sample_freq_avail[i]) {
+ for (i = 0; i < 16; i++)
+ if (lval == st->chip_info->sample_freq_avail[i]) {
mutex_lock(&indio_dev->mlock);
st->mode &= ~AD7793_MODE_RATE(-1);
st->mode |= AD7793_MODE_RATE(i);
@@ -231,6 +406,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
"470 242 123 62 50 39 33 19 17 16 12 10 8 6 4");
+static IIO_CONST_ATTR_NAMED(sampling_frequency_available_ad7797,
+ sampling_frequency_available, "123 62 50 33 17 16 12 10 8 6 4");
+
static ssize_t ad7793_show_scale_available(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -262,6 +440,16 @@ static const struct attribute_group ad7793_attribute_group = {
.attrs = ad7793_attributes,
};
+static struct attribute *ad7797_attributes[] = {
+ &iio_dev_attr_sampling_frequency.dev_attr.attr,
+ &iio_const_attr_sampling_frequency_available_ad7797.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group ad7797_attribute_group = {
+ .attrs = ad7797_attributes,
+};
+
static int ad7793_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val,
@@ -292,12 +480,12 @@ static int ad7793_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT_PLUS_NANO;
} else {
/* 1170mV / 2^23 * 6 */
- scale_uv = (1170ULL * 100000000ULL * 6ULL);
+ scale_uv = (1170ULL * 1000000000ULL * 6ULL);
}
break;
case IIO_TEMP:
/* 1170mV / 0.81 mV/C / 2^23 */
- scale_uv = 1444444444444ULL;
+ scale_uv = 1444444444444444ULL;
break;
default:
return -EINVAL;
@@ -387,6 +575,15 @@ static const struct iio_info ad7793_info = {
.driver_module = THIS_MODULE,
};
+static const struct iio_info ad7797_info = {
+ .read_raw = &ad7793_read_raw,
+ .write_raw = &ad7793_write_raw,
+ .write_raw_get_fmt = &ad7793_write_raw_get_fmt,
+ .attrs = &ad7793_attribute_group,
+ .validate_trigger = ad_sd_validate_trigger,
+ .driver_module = THIS_MODULE,
+};
+
#define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \
const struct iio_chan_spec _name##_channels[] = { \
AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \
@@ -412,41 +609,143 @@ const struct iio_chan_spec _name##_channels[] = { \
IIO_CHAN_SOFT_TIMESTAMP(9), \
}
+#define DECLARE_AD7797_CHANNELS(_name, _b, _sb) \
+const struct iio_chan_spec _name##_channels[] = { \
+ AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
+ AD_SD_SHORTED_CHANNEL(1, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
+ AD_SD_TEMP_CHANNEL(2, AD7793_CH_TEMP, (_b), (_sb), 0), \
+ AD_SD_SUPPLY_CHANNEL(3, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
+ IIO_CHAN_SOFT_TIMESTAMP(4), \
+}
+
+#define DECLARE_AD7799_CHANNELS(_name, _b, _sb) \
+const struct iio_chan_spec _name##_channels[] = { \
+ AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
+ AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
+ AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
+ AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
+ AD_SD_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
+ IIO_CHAN_SOFT_TIMESTAMP(5), \
+}
+
static DECLARE_AD7793_CHANNELS(ad7785, 20, 32, 4);
static DECLARE_AD7793_CHANNELS(ad7792, 16, 32, 0);
static DECLARE_AD7793_CHANNELS(ad7793, 24, 32, 0);
static DECLARE_AD7795_CHANNELS(ad7794, 16, 32);
static DECLARE_AD7795_CHANNELS(ad7795, 24, 32);
+static DECLARE_AD7797_CHANNELS(ad7796, 16, 16);
+static DECLARE_AD7797_CHANNELS(ad7797, 24, 32);
+static DECLARE_AD7799_CHANNELS(ad7798, 16, 16);
+static DECLARE_AD7799_CHANNELS(ad7799, 24, 32);
static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
[ID_AD7785] = {
+ .id = AD7785_ID,
.channels = ad7785_channels,
.num_channels = ARRAY_SIZE(ad7785_channels),
+ .iio_info = &ad7793_info,
+ .sample_freq_avail = ad7793_sample_freq_avail,
+ .flags = AD7793_FLAG_HAS_CLKSEL |
+ AD7793_FLAG_HAS_REFSEL |
+ AD7793_FLAG_HAS_VBIAS |
+ AD7793_HAS_EXITATION_CURRENT |
+ AD7793_FLAG_HAS_GAIN |
+ AD7793_FLAG_HAS_BUFFER,
},
[ID_AD7792] = {
+ .id = AD7792_ID,
.channels = ad7792_channels,
.num_channels = ARRAY_SIZE(ad7792_channels),
+ .iio_info = &ad7793_info,
+ .sample_freq_avail = ad7793_sample_freq_avail,
+ .flags = AD7793_FLAG_HAS_CLKSEL |
+ AD7793_FLAG_HAS_REFSEL |
+ AD7793_FLAG_HAS_VBIAS |
+ AD7793_HAS_EXITATION_CURRENT |
+ AD7793_FLAG_HAS_GAIN |
+ AD7793_FLAG_HAS_BUFFER,
},
[ID_AD7793] = {
+ .id = AD7793_ID,
.channels = ad7793_channels,
.num_channels = ARRAY_SIZE(ad7793_channels),
+ .iio_info = &ad7793_info,
+ .sample_freq_avail = ad7793_sample_freq_avail,
+ .flags = AD7793_FLAG_HAS_CLKSEL |
+ AD7793_FLAG_HAS_REFSEL |
+ AD7793_FLAG_HAS_VBIAS |
+ AD7793_HAS_EXITATION_CURRENT |
+ AD7793_FLAG_HAS_GAIN |
+ AD7793_FLAG_HAS_BUFFER,
},
[ID_AD7794] = {
+ .id = AD7794_ID,
.channels = ad7794_channels,
.num_channels = ARRAY_SIZE(ad7794_channels),
+ .iio_info = &ad7793_info,
+ .sample_freq_avail = ad7793_sample_freq_avail,
+ .flags = AD7793_FLAG_HAS_CLKSEL |
+ AD7793_FLAG_HAS_REFSEL |
+ AD7793_FLAG_HAS_VBIAS |
+ AD7793_HAS_EXITATION_CURRENT |
+ AD7793_FLAG_HAS_GAIN |
+ AD7793_FLAG_HAS_BUFFER,
},
[ID_AD7795] = {
+ .id = AD7795_ID,
.channels = ad7795_channels,
.num_channels = ARRAY_SIZE(ad7795_channels),
+ .iio_info = &ad7793_info,
+ .sample_freq_avail = ad7793_sample_freq_avail,
+ .flags = AD7793_FLAG_HAS_CLKSEL |
+ AD7793_FLAG_HAS_REFSEL |
+ AD7793_FLAG_HAS_VBIAS |
+ AD7793_HAS_EXITATION_CURRENT |
+ AD7793_FLAG_HAS_GAIN |
+ AD7793_FLAG_HAS_BUFFER,
+ },
+ [ID_AD7796] = {
+ .id = AD7796_ID,
+ .channels = ad7796_channels,
+ .num_channels = ARRAY_SIZE(ad7796_channels),
+ .iio_info = &ad7797_info,
+ .sample_freq_avail = ad7797_sample_freq_avail,
+ .flags = AD7793_FLAG_HAS_CLKSEL,
+ },
+ [ID_AD7797] = {
+ .id = AD7797_ID,
+ .channels = ad7797_channels,
+ .num_channels = ARRAY_SIZE(ad7797_channels),
+ .iio_info = &ad7797_info,
+ .sample_freq_avail = ad7797_sample_freq_avail,
+ .flags = AD7793_FLAG_HAS_CLKSEL,
+ },
+ [ID_AD7798] = {
+ .id = AD7798_ID,
+ .channels = ad7798_channels,
+ .num_channels = ARRAY_SIZE(ad7798_channels),
+ .iio_info = &ad7793_info,
+ .sample_freq_avail = ad7793_sample_freq_avail,
+ .flags = AD7793_FLAG_HAS_GAIN |
+ AD7793_FLAG_HAS_BUFFER,
+ },
+ [ID_AD7799] = {
+ .id = AD7799_ID,
+ .channels = ad7799_channels,
+ .num_channels = ARRAY_SIZE(ad7799_channels),
+ .iio_info = &ad7793_info,
+ .sample_freq_avail = ad7793_sample_freq_avail,
+ .flags = AD7793_FLAG_HAS_GAIN |
+ AD7793_FLAG_HAS_BUFFER,
},
};
-static int __devinit ad7793_probe(struct spi_device *spi)
+static int ad7793_probe(struct spi_device *spi)
{
const struct ad7793_platform_data *pdata = spi->dev.platform_data;
struct ad7793_state *st;
struct iio_dev *indio_dev;
- int ret, voltage_uv = 0;
+ int ret, vref_mv = 0;
if (!pdata) {
dev_err(&spi->dev, "no platform data?\n");
@@ -466,25 +765,31 @@ static int __devinit ad7793_probe(struct spi_device *spi)
ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info);
- st->reg = regulator_get(&spi->dev, "vcc");
- if (!IS_ERR(st->reg)) {
+ if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
+ st->reg = regulator_get(&spi->dev, "refin");
+ if (IS_ERR(st->reg)) {
+ ret = PTR_ERR(st->reg);
+ goto error_device_free;
+ }
+
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
- voltage_uv = regulator_get_voltage(st->reg);
+ vref_mv = regulator_get_voltage(st->reg);
+ if (vref_mv < 0) {
+ ret = vref_mv;
+ goto error_disable_reg;
+ }
+
+ vref_mv /= 1000;
+ } else {
+ vref_mv = 1170; /* Build-in ref */
}
st->chip_info =
&ad7793_chip_info_tbl[spi_get_device_id(spi)->driver_data];
- if (pdata && pdata->vref_mv)
- st->int_vref_mv = pdata->vref_mv;
- else if (voltage_uv)
- st->int_vref_mv = voltage_uv / 1000;
- else
- st->int_vref_mv = 1170; /* Build-in ref */
-
spi_set_drvdata(spi, indio_dev);
indio_dev->dev.parent = &spi->dev;
@@ -492,13 +797,13 @@ static int __devinit ad7793_probe(struct spi_device *spi)
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = st->chip_info->channels;
indio_dev->num_channels = st->chip_info->num_channels;
- indio_dev->info = &ad7793_info;
+ indio_dev->info = st->chip_info->iio_info;
ret = ad_sd_setup_buffer_and_trigger(indio_dev);
if (ret)
goto error_disable_reg;
- ret = ad7793_setup(indio_dev, pdata);
+ ret = ad7793_setup(indio_dev, pdata, vref_mv);
if (ret)
goto error_remove_trigger;
@@ -511,26 +816,27 @@ static int __devinit ad7793_probe(struct spi_device *spi)
error_remove_trigger:
ad_sd_cleanup_buffer_and_trigger(indio_dev);
error_disable_reg:
- if (!IS_ERR(st->reg))
+ if (pdata->refsel != AD7793_REFSEL_INTERNAL)
regulator_disable(st->reg);
error_put_reg:
- if (!IS_ERR(st->reg))
+ if (pdata->refsel != AD7793_REFSEL_INTERNAL)
regulator_put(st->reg);
-
+error_device_free:
iio_device_free(indio_dev);
return ret;
}
-static int __devexit ad7793_remove(struct spi_device *spi)
+static int ad7793_remove(struct spi_device *spi)
{
+ const struct ad7793_platform_data *pdata = spi->dev.platform_data;
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ad7793_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
ad_sd_cleanup_buffer_and_trigger(indio_dev);
- if (!IS_ERR(st->reg)) {
+ if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
regulator_disable(st->reg);
regulator_put(st->reg);
}
@@ -546,6 +852,10 @@ static const struct spi_device_id ad7793_id[] = {
{"ad7793", ID_AD7793},
{"ad7794", ID_AD7794},
{"ad7795", ID_AD7795},
+ {"ad7796", ID_AD7796},
+ {"ad7797", ID_AD7797},
+ {"ad7798", ID_AD7798},
+ {"ad7799", ID_AD7799},
{}
};
MODULE_DEVICE_TABLE(spi, ad7793_id);
@@ -556,7 +866,7 @@ static struct spi_driver ad7793_driver = {
.owner = THIS_MODULE,
},
.probe = ad7793_probe,
- .remove = __devexit_p(ad7793_remove),
+ .remove = ad7793_remove,
.id_table = ad7793_id,
};
module_spi_driver(ad7793_driver);
diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/iio/adc/ad7887.c
index 551790584a1..81153fafac7 100644
--- a/drivers/staging/iio/adc/ad7887_core.c
+++ b/drivers/iio/adc/ad7887.c
@@ -14,13 +14,139 @@
#include <linux/regulator/consumer.h>
#include <linux/err.h>
#include <linux/module.h>
+#include <linux/interrupt.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
-#include "ad7887.h"
+#include <linux/platform_data/ad7887.h>
+
+#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */
+#define AD7887_DUAL (1 << 4) /* dual-channel mode */
+#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */
+#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */
+#define AD7887_PM_MODE1 (0) /* CS based shutdown */
+#define AD7887_PM_MODE2 (1) /* full on */
+#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */
+#define AD7887_PM_MODE4 (3) /* standby mode */
+
+enum ad7887_channels {
+ AD7887_CH0,
+ AD7887_CH0_CH1,
+ AD7887_CH1,
+};
+
+#define RES_MASK(bits) ((1 << (bits)) - 1)
+
+/**
+ * struct ad7887_chip_info - chip specifc information
+ * @int_vref_mv: the internal reference voltage
+ * @channel: channel specification
+ */
+struct ad7887_chip_info {
+ u16 int_vref_mv;
+ struct iio_chan_spec channel[3];
+};
+
+struct ad7887_state {
+ struct spi_device *spi;
+ const struct ad7887_chip_info *chip_info;
+ struct regulator *reg;
+ struct spi_transfer xfer[4];
+ struct spi_message msg[3];
+ struct spi_message *ring_msg;
+ unsigned char tx_cmd_buf[4];
+
+ /*
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache lines.
+ * Buffer needs to be large enough to hold two 16 bit samples and a
+ * 64 bit aligned 64 bit timestamp.
+ */
+ unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)]
+ ____cacheline_aligned;
+};
+
+enum ad7887_supported_device_ids {
+ ID_AD7887
+};
+
+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) {
+ case (1 << 0):
+ st->ring_msg = &st->msg[AD7887_CH0];
+ break;
+ case (1 << 1):
+ st->ring_msg = &st->msg[AD7887_CH1];
+ /* Dummy read: push CH1 setting down to hardware */
+ spi_sync(st->spi, st->ring_msg);
+ break;
+ case ((1 << 1) | (1 << 0)):
+ st->ring_msg = &st->msg[AD7887_CH0_CH1];
+ break;
+ }
+
+ return 0;
+}
+
+static int ad7887_ring_postdisable(struct iio_dev *indio_dev)
+{
+ struct ad7887_state *st = iio_priv(indio_dev);
+
+ /* dummy read: restore default CH0 settin */
+ return spi_sync(st->spi, &st->msg[AD7887_CH0]);
+}
+
+/**
+ * ad7887_trigger_handler() bh of trigger launched polling to ring buffer
+ *
+ * Currently there is no option in this driver to disable the saving of
+ * timestamps within the ring.
+ **/
+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);
+done:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static const struct iio_buffer_setup_ops ad7887_ring_setup_ops = {
+ .preenable = &ad7887_ring_preenable,
+ .postenable = &iio_triggered_buffer_postenable,
+ .predisable = &iio_triggered_buffer_predisable,
+ .postdisable = &ad7887_ring_postdisable,
+};
static int ad7887_scan_direct(struct ad7887_state *st, unsigned ch)
{
@@ -39,7 +165,6 @@ static int ad7887_read_raw(struct iio_dev *indio_dev,
{
int ret;
struct ad7887_state *st = iio_priv(indio_dev);
- unsigned int scale_uv;
switch (m) {
case IIO_CHAN_INFO_RAW:
@@ -52,15 +177,22 @@ static int ad7887_read_raw(struct iio_dev *indio_dev,
if (ret < 0)
return ret;
- *val = (ret >> st->chip_info->channel[0].scan_type.shift) &
- RES_MASK(st->chip_info->channel[0].scan_type.realbits);
+ *val = ret >> chan->scan_type.shift;
+ *val &= RES_MASK(chan->scan_type.realbits);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- scale_uv = (st->int_vref_mv * 1000)
- >> st->chip_info->channel[0].scan_type.realbits;
- *val = scale_uv/1000;
- *val2 = (scale_uv%1000)*1000;
- return IIO_VAL_INT_PLUS_MICRO;
+ if (st->reg) {
+ *val = regulator_get_voltage(st->reg);
+ if (*val < 0)
+ return *val;
+ *val /= 1000;
+ } else {
+ *val = st->chip_info->int_vref_mv;
+ }
+
+ *val2 = chan->scan_type.realbits;
+
+ return IIO_VAL_FRACTIONAL_LOG2;
}
return -EINVAL;
}
@@ -105,21 +237,25 @@ static int __devinit ad7887_probe(struct spi_device *spi)
{
struct ad7887_platform_data *pdata = spi->dev.platform_data;
struct ad7887_state *st;
- int ret, voltage_uv = 0;
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+ uint8_t mode;
+ int ret;
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
- st->reg = regulator_get(&spi->dev, "vcc");
- if (!IS_ERR(st->reg)) {
+ if (!pdata || !pdata->use_onchip_ref) {
+ st->reg = regulator_get(&spi->dev, "vref");
+ if (IS_ERR(st->reg)) {
+ ret = PTR_ERR(st->reg);
+ goto error_free;
+ }
+
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
-
- voltage_uv = regulator_get_voltage(st->reg);
}
st->chip_info =
@@ -136,9 +272,13 @@ static int __devinit ad7887_probe(struct spi_device *spi)
/* Setup default message */
- st->tx_cmd_buf[0] = AD7887_CH_AIN0 | AD7887_PM_MODE4 |
- ((pdata && pdata->use_onchip_ref) ?
- 0 : AD7887_REF_DIS);
+ mode = AD7887_PM_MODE4;
+ if (!pdata || !pdata->use_onchip_ref)
+ mode |= AD7887_REF_DIS;
+ if (pdata && pdata->en_dual)
+ mode |= AD7887_DUAL;
+
+ st->tx_cmd_buf[0] = AD7887_CH_AIN0 | mode;
st->xfer[0].rx_buf = &st->data[0];
st->xfer[0].tx_buf = &st->tx_cmd_buf[0];
@@ -148,56 +288,36 @@ static int __devinit ad7887_probe(struct spi_device *spi)
spi_message_add_tail(&st->xfer[0], &st->msg[AD7887_CH0]);
if (pdata && pdata->en_dual) {
- st->tx_cmd_buf[0] |= AD7887_DUAL | AD7887_REF_DIS;
-
- st->tx_cmd_buf[2] = AD7887_CH_AIN1 | AD7887_DUAL |
- AD7887_REF_DIS | AD7887_PM_MODE4;
- st->tx_cmd_buf[4] = AD7887_CH_AIN0 | AD7887_DUAL |
- AD7887_REF_DIS | AD7887_PM_MODE4;
- st->tx_cmd_buf[6] = AD7887_CH_AIN1 | AD7887_DUAL |
- AD7887_REF_DIS | AD7887_PM_MODE4;
+ st->tx_cmd_buf[2] = AD7887_CH_AIN1 | mode;
st->xfer[1].rx_buf = &st->data[0];
st->xfer[1].tx_buf = &st->tx_cmd_buf[2];
st->xfer[1].len = 2;
st->xfer[2].rx_buf = &st->data[2];
- st->xfer[2].tx_buf = &st->tx_cmd_buf[4];
+ st->xfer[2].tx_buf = &st->tx_cmd_buf[0];
st->xfer[2].len = 2;
spi_message_init(&st->msg[AD7887_CH0_CH1]);
spi_message_add_tail(&st->xfer[1], &st->msg[AD7887_CH0_CH1]);
spi_message_add_tail(&st->xfer[2], &st->msg[AD7887_CH0_CH1]);
- st->xfer[3].rx_buf = &st->data[0];
- st->xfer[3].tx_buf = &st->tx_cmd_buf[6];
+ st->xfer[3].rx_buf = &st->data[2];
+ st->xfer[3].tx_buf = &st->tx_cmd_buf[2];
st->xfer[3].len = 2;
spi_message_init(&st->msg[AD7887_CH1]);
spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]);
- if (pdata && pdata->vref_mv)
- st->int_vref_mv = pdata->vref_mv;
- else if (voltage_uv)
- st->int_vref_mv = voltage_uv / 1000;
- else
- dev_warn(&spi->dev, "reference voltage unspecified\n");
-
indio_dev->channels = st->chip_info->channel;
indio_dev->num_channels = 3;
} else {
- if (pdata && pdata->vref_mv)
- st->int_vref_mv = pdata->vref_mv;
- else if (pdata && pdata->use_onchip_ref)
- st->int_vref_mv = st->chip_info->int_vref_mv;
- else
- dev_warn(&spi->dev, "reference voltage unspecified\n");
-
indio_dev->channels = &st->chip_info->channel[1];
indio_dev->num_channels = 2;
}
- ret = ad7887_register_ring_funcs_and_init(indio_dev);
+ ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+ &ad7887_trigger_handler, &ad7887_ring_setup_ops);
if (ret)
goto error_disable_reg;
@@ -207,13 +327,14 @@ static int __devinit ad7887_probe(struct spi_device *spi)
return 0;
error_unregister_ring:
- ad7887_ring_cleanup(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg:
- if (!IS_ERR(st->reg))
+ if (st->reg)
regulator_disable(st->reg);
error_put_reg:
- if (!IS_ERR(st->reg))
+ if (st->reg)
regulator_put(st->reg);
+error_free:
iio_device_free(indio_dev);
return ret;
@@ -225,8 +346,8 @@ static int __devexit ad7887_remove(struct spi_device *spi)
struct ad7887_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- ad7887_ring_cleanup(indio_dev);
- if (!IS_ERR(st->reg)) {
+ iio_triggered_buffer_cleanup(indio_dev);
+ if (st->reg) {
regulator_disable(st->reg);
regulator_put(st->reg);
}
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
index 67baa1363d7..afe6d78c8ff 100644
--- a/drivers/iio/adc/ad_sigma_delta.c
+++ b/drivers/iio/adc/ad_sigma_delta.c
@@ -391,7 +391,7 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
break;
}
- iio_push_to_buffer(indio_dev->buffer, (uint8_t *)data);
+ iio_push_to_buffers(indio_dev, (uint8_t *)data);
iio_trigger_notify_done(indio_dev->trig);
sigma_delta->irq_dis = false;
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
index 3ed94bf8059..03b85940f4b 100644
--- a/drivers/iio/adc/at91_adc.c
+++ b/drivers/iio/adc/at91_adc.c
@@ -46,7 +46,6 @@ struct at91_adc_state {
struct clk *clk;
bool done;
int irq;
- bool irq_enabled;
u16 last_value;
struct mutex lock;
u8 num_channels;
@@ -66,7 +65,6 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *idev = pf->indio_dev;
struct at91_adc_state *st = iio_priv(idev);
- struct iio_buffer *buffer = idev->buffer;
int i, j = 0;
for (i = 0; i < idev->masklength; i++) {
@@ -82,10 +80,9 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
*timestamp = pf->timestamp;
}
- buffer->access->store_to(buffer, (u8 *)st->buffer);
+ iio_push_to_buffers(indio_dev, (u8 *)st->buffer);
iio_trigger_notify_done(idev->trig);
- st->irq_enabled = true;
/* Needed to ACK the DRDY interruption */
at91_adc_readl(st, AT91_ADC_LCDR);
@@ -106,7 +103,6 @@ static irqreturn_t at91_adc_eoc_trigger(int irq, void *private)
if (iio_buffer_enabled(idev)) {
disable_irq_nosync(irq);
- st->irq_enabled = false;
iio_trigger_poll(idev->trig, iio_get_time_ns());
} else {
st->last_value = at91_adc_readl(st, AT91_ADC_LCDR);
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/iio/adc/max1363.c
index d7b4ffcfa05..1e84b5b5509 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/iio/adc/max1363.c
@@ -37,8 +37,151 @@
#include <linux/iio/events.h>
#include <linux/iio/buffer.h>
#include <linux/iio/driver.h>
+#include <linux/iio/kfifo_buf.h>
+#include <linux/iio/trigger_consumer.h>
+
+#define MAX1363_SETUP_BYTE(a) ((a) | 0x80)
+
+/* There is a fair bit more defined here than currently
+ * used, but the intention is to support everything these
+ * chips do in the long run */
+
+/* see data sheets */
+/* max1363 and max1236, max1237, max1238, max1239 */
+#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD 0x00
+#define MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF 0x20
+#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT 0x40
+#define MAX1363_SETUP_AIN3_IS_REF_REF_IS_INT 0x60
+#define MAX1363_SETUP_POWER_UP_INT_REF 0x10
+#define MAX1363_SETUP_POWER_DOWN_INT_REF 0x00
+
+/* think about includeing max11600 etc - more settings */
+#define MAX1363_SETUP_EXT_CLOCK 0x08
+#define MAX1363_SETUP_INT_CLOCK 0x00
+#define MAX1363_SETUP_UNIPOLAR 0x00
+#define MAX1363_SETUP_BIPOLAR 0x04
+#define MAX1363_SETUP_RESET 0x00
+#define MAX1363_SETUP_NORESET 0x02
+/* max1363 only - though don't care on others.
+ * For now monitor modes are not implemented as the relevant
+ * line is not connected on my test board.
+ * The definitions are here as I intend to add this soon.
+ */
+#define MAX1363_SETUP_MONITOR_SETUP 0x01
+
+/* Specific to the max1363 */
+#define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4))
+#define MAX1363_MON_INT_ENABLE 0x01
+
+/* defined for readability reasons */
+/* All chips */
+#define MAX1363_CONFIG_BYTE(a) ((a))
+
+#define MAX1363_CONFIG_SE 0x01
+#define MAX1363_CONFIG_DE 0x00
+#define MAX1363_CONFIG_SCAN_TO_CS 0x00
+#define MAX1363_CONFIG_SCAN_SINGLE_8 0x20
+#define MAX1363_CONFIG_SCAN_MONITOR_MODE 0x40
+#define MAX1363_CONFIG_SCAN_SINGLE_1 0x60
+/* max123{6-9} only */
+#define MAX1236_SCAN_MID_TO_CHANNEL 0x40
+
+/* max1363 only - merely part of channel selects or don't care for others*/
+#define MAX1363_CONFIG_EN_MON_MODE_READ 0x18
+
+#define MAX1363_CHANNEL_SEL(a) ((a) << 1)
+
+/* max1363 strictly 0x06 - but doesn't matter */
+#define MAX1363_CHANNEL_SEL_MASK 0x1E
+#define MAX1363_SCAN_MASK 0x60
+#define MAX1363_SE_DE_MASK 0x01
+
+#define MAX1363_MAX_CHANNELS 25
+/**
+ * struct max1363_mode - scan mode information
+ * @conf: The corresponding value of the configuration register
+ * @modemask: Bit mask corresponding to channels enabled in this mode
+ */
+struct max1363_mode {
+ int8_t conf;
+ DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS);
+};
-#include "max1363.h"
+/* This must be maintained along side the max1363_mode_table in max1363_core */
+enum max1363_modes {
+ /* Single read of a single channel */
+ _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11,
+ /* Differential single read */
+ d0m1, d2m3, d4m5, d6m7, d8m9, d10m11,
+ d1m0, d3m2, d5m4, d7m6, d9m8, d11m10,
+ /* Scan to channel and mid to channel where overlapping */
+ s0to1, s0to2, s2to3, s0to3, s0to4, s0to5, s0to6,
+ s6to7, s0to7, s6to8, s0to8, s6to9,
+ s0to9, s6to10, s0to10, s6to11, s0to11,
+ /* Differential scan to channel and mid to channel where overlapping */
+ d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9,
+ d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2,
+ d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8,
+ d7m6to11m10, d1m0to11m10,
+};
+
+/**
+ * struct max1363_chip_info - chip specifc information
+ * @info: iio core function callbacks structure
+ * @channels: channel specification
+ * @num_channels: number of channels
+ * @mode_list: array of available scan modes
+ * @default_mode: the scan mode in which the chip starts up
+ * @int_vref_mv: the internal reference voltage
+ * @num_channels: number of channels
+ * @bits: accuracy of the adc in bits
+ */
+struct max1363_chip_info {
+ const struct iio_info *info;
+ const struct iio_chan_spec *channels;
+ int num_channels;
+ const enum max1363_modes *mode_list;
+ enum max1363_modes default_mode;
+ u16 int_vref_mv;
+ u8 num_modes;
+ u8 bits;
+};
+
+/**
+ * struct max1363_state - driver instance specific data
+ * @client: i2c_client
+ * @setupbyte: cache of current device setup byte
+ * @configbyte: cache of current device config byte
+ * @chip_info: chip model specific constants, available modes etc
+ * @current_mode: the scan mode of this chip
+ * @requestedmask: a valid requested set of channels
+ * @reg: supply regulator
+ * @monitor_on: whether monitor mode is enabled
+ * @monitor_speed: parameter corresponding to device monitor speed setting
+ * @mask_high: bitmask for enabled high thresholds
+ * @mask_low: bitmask for enabled low thresholds
+ * @thresh_high: high threshold values
+ * @thresh_low: low threshold values
+ */
+struct max1363_state {
+ struct i2c_client *client;
+ u8 setupbyte;
+ u8 configbyte;
+ const struct max1363_chip_info *chip_info;
+ const struct max1363_mode *current_mode;
+ u32 requestedmask;
+ struct regulator *reg;
+
+ /* Using monitor modes and buffer at the same time is
+ currently not supported */
+ bool monitor_on;
+ unsigned int monitor_speed:3;
+ u8 mask_high;
+ u8 mask_low;
+ /* 4x unipolar first then the fours bipolar ones */
+ s16 thresh_high[8];
+ s16 thresh_low[8];
+};
#define MAX1363_MODE_SINGLE(_num, _mask) { \
.conf = MAX1363_CHANNEL_SEL(_num) \
@@ -148,7 +291,7 @@ static const struct max1363_mode max1363_mode_table[] = {
MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(11, 6, 0xFC0000),
};
-const struct max1363_mode
+static const struct max1363_mode
*max1363_match_mode(const unsigned long *mask,
const struct max1363_chip_info *ci)
{
@@ -172,7 +315,7 @@ static int max1363_write_basic_config(struct i2c_client *client,
return i2c_master_send(client, tx_buf, 2);
}
-int max1363_set_scan_mode(struct max1363_state *st)
+static int max1363_set_scan_mode(struct max1363_state *st)
{
st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK
| MAX1363_SCAN_MASK
@@ -622,9 +765,9 @@ static int max1363_read_event_config(struct iio_dev *indio_dev,
u64 event_code)
{
struct max1363_state *st = iio_priv(indio_dev);
-
int val;
int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
+
mutex_lock(&indio_dev->mlock);
if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
val = (1 << number) & st->mask_low;
@@ -644,7 +787,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
const long *modemask;
if (!enabled) {
- /* transition to ring capture is not currently supported */
+ /* transition to buffered capture is not currently supported */
st->setupbyte &= ~MAX1363_SETUP_MONITOR_SETUP;
st->configbyte &= ~MAX1363_SCAN_MASK;
st->monitor_on = false;
@@ -826,8 +969,21 @@ static struct attribute_group max1363_event_attribute_group = {
.name = "events",
};
-#define MAX1363_EVENT_FUNCS \
+static int max1363_update_scan_mode(struct iio_dev *indio_dev,
+ const unsigned long *scan_mask)
+{
+ struct max1363_state *st = iio_priv(indio_dev);
+ /*
+ * Need to figure out the current mode based upon the requested
+ * scan mask in iio_dev
+ */
+ st->current_mode = max1363_match_mode(scan_mask, st->chip_info);
+ if (!st->current_mode)
+ return -EINVAL;
+ max1363_set_scan_mode(st);
+ return 0;
+}
static const struct iio_info max1238_info = {
.read_raw = &max1363_read_raw,
@@ -1230,8 +1386,6 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
},
};
-
-
static int max1363_initial_setup(struct max1363_state *st)
{
st->setupbyte = MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD
@@ -1269,34 +1423,137 @@ static int __devinit max1363_alloc_scan_masks(struct iio_dev *indio_dev)
return 0;
}
+
+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;
+ unsigned long numvals = bitmap_weight(st->current_mode->modemask,
+ MAX1363_MAX_CHANNELS);
+
+ /* Ensure the timestamp is 8 byte aligned */
+ if (st->chip_info->bits != 8)
+ d_size = numvals*2;
+ else
+ d_size = numvals;
+ if (indio_dev->scan_timestamp) {
+ d_size += sizeof(s64);
+ if (d_size % sizeof(s64))
+ d_size += sizeof(s64) - (d_size % sizeof(s64));
+ }
+ /* Monitor mode prevents reading. Whilst not currently implemented
+ * might as well have this test in here in the meantime as it does
+ * no harm.
+ */
+ if (numvals == 0)
+ goto done;
+
+ rxbuf = kmalloc(d_size, GFP_KERNEL);
+ if (rxbuf == NULL)
+ goto done;
+ if (st->chip_info->bits != 8)
+ b_sent = i2c_master_recv(st->client, rxbuf, numvals*2);
+ else
+ b_sent = i2c_master_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);
+
+done_free:
+ kfree(rxbuf);
+done:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ 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_register_buffered_funcs_and_init(struct iio_dev *indio_dev)
+{
+ struct max1363_state *st = iio_priv(indio_dev);
+ int ret = 0;
+
+ indio_dev->buffer = iio_kfifo_allocate(indio_dev);
+ if (!indio_dev->buffer) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
+ indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
+ &max1363_trigger_handler,
+ IRQF_ONESHOT,
+ indio_dev,
+ "%s_consumer%d",
+ st->client->name,
+ indio_dev->id);
+ if (indio_dev->pollfunc == NULL) {
+ ret = -ENOMEM;
+ goto error_deallocate_sw_rb;
+ }
+ /* Buffer functions - here trigger setup related */
+ indio_dev->setup_ops = &max1363_buffered_setup_ops;
+
+ /* Flag that polled buffering is possible */
+ indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
+
+ return 0;
+
+error_deallocate_sw_rb:
+ iio_kfifo_free(indio_dev->buffer);
+error_ret:
+ return ret;
+}
+
+static void max1363_buffer_cleanup(struct iio_dev *indio_dev)
+{
+ /* ensure that the trigger has been detached */
+ iio_dealloc_pollfunc(indio_dev->pollfunc);
+ iio_kfifo_free(indio_dev->buffer);
+}
+
static int __devinit max1363_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret;
struct max1363_state *st;
struct iio_dev *indio_dev;
- struct regulator *reg;
-
- reg = regulator_get(&client->dev, "vcc");
- if (IS_ERR(reg)) {
- ret = PTR_ERR(reg);
- goto error_out;
- }
-
- ret = regulator_enable(reg);
- if (ret)
- goto error_put_reg;
indio_dev = iio_device_alloc(sizeof(struct max1363_state));
if (indio_dev == NULL) {
ret = -ENOMEM;
- goto error_disable_reg;
+ goto error_out;
}
+
ret = iio_map_array_register(indio_dev, client->dev.platform_data);
if (ret < 0)
goto error_free_device;
+
st = iio_priv(indio_dev);
- st->reg = reg;
+
+ st->reg = regulator_get(&client->dev, "vcc");
+ if (IS_ERR(st->reg)) {
+ ret = PTR_ERR(st->reg);
+ goto error_unregister_map;
+ }
+
+ ret = regulator_enable(st->reg);
+ if (ret)
+ goto error_put_reg;
+
/* this is only used for device removal purposes */
i2c_set_clientdata(client, indio_dev);
@@ -1305,7 +1562,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
ret = max1363_alloc_scan_masks(indio_dev);
if (ret)
- goto error_unregister_map;
+ goto error_disable_reg;
/* Estabilish that the iio_dev is a child of the i2c device */
indio_dev->dev.parent = &client->dev;
@@ -1320,7 +1577,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
if (ret < 0)
goto error_free_available_scan_masks;
- ret = max1363_register_ring_funcs_and_init(indio_dev);
+ ret = max1363_register_buffered_funcs_and_init(indio_dev);
if (ret)
goto error_free_available_scan_masks;
@@ -1328,7 +1585,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
st->chip_info->channels,
st->chip_info->num_channels);
if (ret)
- goto error_cleanup_ring;
+ goto error_cleanup_buffer;
if (client->irq) {
ret = request_threaded_irq(st->client->irq,
@@ -1339,7 +1596,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
indio_dev);
if (ret)
- goto error_uninit_ring;
+ goto error_uninit_buffer;
}
ret = iio_device_register(indio_dev);
@@ -1349,20 +1606,20 @@ static int __devinit max1363_probe(struct i2c_client *client,
return 0;
error_free_irq:
free_irq(st->client->irq, indio_dev);
-error_uninit_ring:
+error_uninit_buffer:
iio_buffer_unregister(indio_dev);
-error_cleanup_ring:
- max1363_ring_cleanup(indio_dev);
+error_cleanup_buffer:
+ max1363_buffer_cleanup(indio_dev);
error_free_available_scan_masks:
kfree(indio_dev->available_scan_masks);
error_unregister_map:
iio_map_array_unregister(indio_dev, client->dev.platform_data);
-error_free_device:
- iio_device_free(indio_dev);
error_disable_reg:
- regulator_disable(reg);
+ regulator_disable(st->reg);
error_put_reg:
- regulator_put(reg);
+ regulator_put(st->reg);
+error_free_device:
+ iio_device_free(indio_dev);
error_out:
return ret;
}
@@ -1371,17 +1628,16 @@ static int __devexit max1363_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct max1363_state *st = iio_priv(indio_dev);
- struct regulator *reg = st->reg;
iio_device_unregister(indio_dev);
if (client->irq)
free_irq(st->client->irq, indio_dev);
iio_buffer_unregister(indio_dev);
- max1363_ring_cleanup(indio_dev);
+ max1363_buffer_cleanup(indio_dev);
kfree(indio_dev->available_scan_masks);
- if (!IS_ERR(reg)) {
- regulator_disable(reg);
- regulator_put(reg);
+ if (!IS_ERR(st->reg)) {
+ regulator_disable(st->reg);
+ regulator_put(st->reg);
}
iio_map_array_unregister(indio_dev, client->dev.platform_data);
iio_device_free(indio_dev);
diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c
new file mode 100644
index 00000000000..f4a46dd8f43
--- /dev/null
+++ b/drivers/iio/adc/ti-adc081c.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2012 Avionic Design GmbH
+ *
+ * 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/err.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+#include <linux/regulator/consumer.h>
+
+struct adc081c {
+ struct i2c_client *i2c;
+ struct regulator *ref;
+};
+
+#define REG_CONV_RES 0x00
+
+static int adc081c_read_raw(struct iio_dev *iio,
+ struct iio_chan_spec const *channel, int *value,
+ int *shift, long mask)
+{
+ struct adc081c *adc = iio_priv(iio);
+ int err;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ err = i2c_smbus_read_word_swapped(adc->i2c, REG_CONV_RES);
+ if (err < 0)
+ return err;
+
+ *value = (err >> 4) & 0xff;
+ return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_SCALE:
+ err = regulator_get_voltage(adc->ref);
+ if (err < 0)
+ return err;
+
+ *value = err / 1000;
+ *shift = 8;
+
+ return IIO_VAL_FRACTIONAL_LOG2;
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static const struct iio_chan_spec adc081c_channel = {
+ .type = IIO_VOLTAGE,
+ .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT |
+ IIO_CHAN_INFO_RAW_SEPARATE_BIT,
+};
+
+static const struct iio_info adc081c_info = {
+ .read_raw = adc081c_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static int adc081c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct iio_dev *iio;
+ struct adc081c *adc;
+ int err;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
+ return -ENODEV;
+
+ iio = iio_device_alloc(sizeof(*adc));
+ if (!iio)
+ return -ENOMEM;
+
+ adc = iio_priv(iio);
+ adc->i2c = client;
+
+ adc->ref = regulator_get(&client->dev, "vref");
+ if (IS_ERR(adc->ref)) {
+ err = PTR_ERR(adc->ref);
+ goto iio_free;
+ }
+
+ err = regulator_enable(adc->ref);
+ if (err < 0)
+ goto regulator_put;
+
+ iio->dev.parent = &client->dev;
+ iio->name = dev_name(&client->dev);
+ iio->modes = INDIO_DIRECT_MODE;
+ iio->info = &adc081c_info;
+
+ iio->channels = &adc081c_channel;
+ iio->num_channels = 1;
+
+ err = iio_device_register(iio);
+ if (err < 0)
+ goto regulator_disable;
+
+ i2c_set_clientdata(client, iio);
+
+ return 0;
+
+regulator_disable:
+ regulator_disable(adc->ref);
+regulator_put:
+ regulator_put(adc->ref);
+iio_free:
+ iio_device_free(iio);
+
+ return err;
+}
+
+static int adc081c_remove(struct i2c_client *client)
+{
+ struct iio_dev *iio = i2c_get_clientdata(client);
+ struct adc081c *adc = iio_priv(iio);
+
+ iio_device_unregister(iio);
+ regulator_disable(adc->ref);
+ regulator_put(adc->ref);
+ iio_device_free(iio);
+
+ return 0;
+}
+
+static const struct i2c_device_id adc081c_id[] = {
+ { "adc081c", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, adc081c_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id adc081c_of_match[] = {
+ { .compatible = "ti,adc081c" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, adc081c_of_match);
+#endif
+
+static struct i2c_driver adc081c_driver = {
+ .driver = {
+ .name = "adc081c",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(adc081c_of_match),
+ },
+ .probe = adc081c_probe,
+ .remove = adc081c_remove,
+ .id_table = adc081c_id,
+};
+module_i2c_driver(adc081c_driver);
+
+MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
+MODULE_DESCRIPTION("Texas Instruments ADC081C021/027 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/buffer_cb.c b/drivers/iio/buffer_cb.c
new file mode 100644
index 00000000000..4d40e24f372
--- /dev/null
+++ b/drivers/iio/buffer_cb.c
@@ -0,0 +1,113 @@
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/consumer.h>
+
+struct iio_cb_buffer {
+ struct iio_buffer buffer;
+ int (*cb)(u8 *data, void *private);
+ void *private;
+ struct iio_channel *channels;
+};
+
+static int iio_buffer_cb_store_to(struct iio_buffer *buffer, u8 *data)
+{
+ struct iio_cb_buffer *cb_buff = container_of(buffer,
+ struct iio_cb_buffer,
+ buffer);
+
+ return cb_buff->cb(data, cb_buff->private);
+}
+
+static struct iio_buffer_access_funcs iio_cb_access = {
+ .store_to = &iio_buffer_cb_store_to,
+};
+
+struct iio_cb_buffer *iio_channel_get_all_cb(const char *name,
+ int (*cb)(u8 *data,
+ void *private),
+ void *private)
+{
+ int ret;
+ struct iio_cb_buffer *cb_buff;
+ struct iio_dev *indio_dev;
+ struct iio_channel *chan;
+
+ cb_buff = kzalloc(sizeof(*cb_buff), GFP_KERNEL);
+ if (cb_buff == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
+
+ cb_buff->private = private;
+ cb_buff->cb = cb;
+ cb_buff->buffer.access = &iio_cb_access;
+ INIT_LIST_HEAD(&cb_buff->buffer.demux_list);
+
+ cb_buff->channels = iio_channel_get_all(name);
+ if (IS_ERR(cb_buff->channels)) {
+ ret = PTR_ERR(cb_buff->channels);
+ goto error_free_cb_buff;
+ }
+
+ indio_dev = cb_buff->channels[0].indio_dev;
+ cb_buff->buffer.scan_mask
+ = kcalloc(BITS_TO_LONGS(indio_dev->masklength), sizeof(long),
+ GFP_KERNEL);
+ if (cb_buff->buffer.scan_mask == NULL) {
+ ret = -ENOMEM;
+ goto error_release_channels;
+ }
+ chan = &cb_buff->channels[0];
+ while (chan->indio_dev) {
+ if (chan->indio_dev != indio_dev) {
+ ret = -EINVAL;
+ goto error_release_channels;
+ }
+ set_bit(chan->channel->scan_index,
+ cb_buff->buffer.scan_mask);
+ chan++;
+ }
+
+ return cb_buff;
+
+error_release_channels:
+ iio_channel_release_all(cb_buff->channels);
+error_free_cb_buff:
+ kfree(cb_buff);
+error_ret:
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(iio_channel_get_all_cb);
+
+int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff)
+{
+ return iio_update_buffers(cb_buff->channels[0].indio_dev,
+ &cb_buff->buffer,
+ NULL);
+}
+EXPORT_SYMBOL_GPL(iio_channel_start_all_cb);
+
+void iio_channel_stop_all_cb(struct iio_cb_buffer *cb_buff)
+{
+ iio_update_buffers(cb_buff->channels[0].indio_dev,
+ NULL,
+ &cb_buff->buffer);
+}
+EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb);
+
+void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff)
+{
+ iio_channel_release_all(cb_buff->channels);
+ kfree(cb_buff);
+}
+EXPORT_SYMBOL_GPL(iio_channel_release_all_cb);
+
+struct iio_channel
+*iio_channel_cb_get_channels(const struct iio_cb_buffer *cb_buffer)
+{
+ return cb_buffer->channels;
+}
+EXPORT_SYMBOL_GPL(iio_channel_cb_get_channels);
diff --git a/drivers/iio/common/hid-sensors/Kconfig b/drivers/iio/common/hid-sensors/Kconfig
index 8e63d81d652..ae10778da7a 100644
--- a/drivers/iio/common/hid-sensors/Kconfig
+++ b/drivers/iio/common/hid-sensors/Kconfig
@@ -15,7 +15,7 @@ config HID_SENSOR_IIO_COMMON
attributes.
config HID_SENSOR_ENUM_BASE_QUIRKS
- tristate "ENUM base quirks for HID Sensor IIO drivers"
+ bool "ENUM base quirks for HID Sensor IIO drivers"
depends on HID_SENSOR_IIO_COMMON
help
Say yes here to build support for sensor hub FW using
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index d4b790d18ef..d60198a6ca2 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -36,10 +36,8 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
int state_val;
state_val = state ? 1 : 0;
-#if (defined CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS) || \
- (defined CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS_MODULE)
- ++state_val;
-#endif
+ if (IS_ENABLED(CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS))
+ ++state_val;
st->data_ready = state;
sensor_hub_set_feature(st->hsdev, st->power_state.report_id,
st->power_state.index,
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index b1c0ee5294c..f4a6f083832 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -67,6 +67,16 @@ config AD5446
To compile this driver as a module, choose M here: the
module will be called ad5446.
+config AD5449
+ tristate "Analog Device AD5449 and similar DACs driver"
+ depends on SPI_MASTER
+ help
+ Say yes here to build support for Analog Devices AD5415, AD5426, AD5429,
+ AD5432, AD5439, AD5443, AD5449 Digital to Analog Converters.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ad5449.
+
config AD5504
tristate "Analog Devices AD5504/AD5501 DAC SPI driver"
depends on SPI
@@ -122,7 +132,7 @@ config AD5686
config MAX517
tristate "Maxim MAX517/518/519 DAC driver"
- depends on I2C && EXPERIMENTAL
+ depends on I2C
help
If you say yes here you get support for the Maxim chips MAX517,
MAX518 and MAX519 (I2C 8-Bit DACs with rail-to-rail outputs).
diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile
index c0d333b23ba..5b528ebb334 100644
--- a/drivers/iio/dac/Makefile
+++ b/drivers/iio/dac/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o
obj-$(CONFIG_AD5064) += ad5064.o
obj-$(CONFIG_AD5504) += ad5504.o
obj-$(CONFIG_AD5446) += ad5446.o
+obj-$(CONFIG_AD5449) += ad5449.o
obj-$(CONFIG_AD5755) += ad5755.o
obj-$(CONFIG_AD5764) += ad5764.o
obj-$(CONFIG_AD5791) += ad5791.o
diff --git a/drivers/iio/dac/ad5449.c b/drivers/iio/dac/ad5449.c
new file mode 100644
index 00000000000..0ee6f8eeba8
--- /dev/null
+++ b/drivers/iio/dac/ad5449.c
@@ -0,0 +1,376 @@
+/*
+ * AD5415, AD5426, AD5429, AD5432, AD5439, AD5443, AD5449 Digital to Analog
+ * Converter driver.
+ *
+ * Copyright 2012 Analog Devices Inc.
+ * Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/regulator/consumer.h>
+#include <asm/unaligned.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#include <linux/platform_data/ad5449.h>
+
+#define AD5449_MAX_CHANNELS 2
+#define AD5449_MAX_VREFS 2
+
+#define AD5449_CMD_NOOP 0x0
+#define AD5449_CMD_LOAD_AND_UPDATE(x) (0x1 + (x) * 3)
+#define AD5449_CMD_READ(x) (0x2 + (x) * 3)
+#define AD5449_CMD_LOAD(x) (0x3 + (x) * 3)
+#define AD5449_CMD_CTRL 13
+
+#define AD5449_CTRL_SDO_OFFSET 10
+#define AD5449_CTRL_DAISY_CHAIN BIT(9)
+#define AD5449_CTRL_HCLR_TO_MIDSCALE BIT(8)
+#define AD5449_CTRL_SAMPLE_RISING BIT(7)
+
+/**
+ * struct ad5449_chip_info - chip specific information
+ * @channels: Channel specification
+ * @num_channels: Number of channels
+ * @has_ctrl: Chip has a control register
+ */
+struct ad5449_chip_info {
+ const struct iio_chan_spec *channels;
+ unsigned int num_channels;
+ bool has_ctrl;
+};
+
+/**
+ * struct ad5449 - driver instance specific data
+ * @spi: the SPI device for this driver instance
+ * @chip_info: chip model specific constants, available modes etc
+ * @vref_reg: vref supply regulators
+ * @has_sdo: whether the SDO line is connected
+ * @dac_cache: Cache for the DAC values
+ * @data: spi transfer buffers
+ */
+struct ad5449 {
+ struct spi_device *spi;
+ const struct ad5449_chip_info *chip_info;
+ struct regulator_bulk_data vref_reg[AD5449_MAX_VREFS];
+
+ bool has_sdo;
+ uint16_t dac_cache[AD5449_MAX_CHANNELS];
+
+ /*
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache lines.
+ */
+ __be16 data[2] ____cacheline_aligned;
+};
+
+enum ad5449_type {
+ ID_AD5426,
+ ID_AD5429,
+ ID_AD5432,
+ ID_AD5439,
+ ID_AD5443,
+ ID_AD5449,
+};
+
+static int ad5449_write(struct iio_dev *indio_dev, unsigned int addr,
+ unsigned int val)
+{
+ struct ad5449 *st = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&indio_dev->mlock);
+ st->data[0] = cpu_to_be16((addr << 12) | val);
+ ret = spi_write(st->spi, st->data, 2);
+ mutex_unlock(&indio_dev->mlock);
+
+ return ret;
+}
+
+static int ad5449_read(struct iio_dev *indio_dev, unsigned int addr,
+ unsigned int *val)
+{
+ struct ad5449 *st = iio_priv(indio_dev);
+ int ret;
+ struct spi_message msg;
+ struct spi_transfer t[] = {
+ {
+ .tx_buf = &st->data[0],
+ .len = 2,
+ .cs_change = 1,
+ }, {
+ .tx_buf = &st->data[1],
+ .rx_buf = &st->data[1],
+ .len = 2,
+ },
+ };
+
+ 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);
+ if (ret < 0)
+ goto out_unlock;
+
+ *val = be16_to_cpu(st->data[1]);
+
+out_unlock:
+ mutex_unlock(&indio_dev->mlock);
+ return ret;
+}
+
+static int ad5449_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val, int *val2, long info)
+{
+ struct ad5449 *st = iio_priv(indio_dev);
+ struct regulator_bulk_data *reg;
+ int scale_uv;
+ int ret;
+
+ switch (info) {
+ case IIO_CHAN_INFO_RAW:
+ if (st->has_sdo) {
+ ret = ad5449_read(indio_dev,
+ AD5449_CMD_READ(chan->address), val);
+ if (ret)
+ return ret;
+ *val &= 0xfff;
+ } else {
+ *val = st->dac_cache[chan->address];
+ }
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ reg = &st->vref_reg[chan->channel];
+ scale_uv = regulator_get_voltage(reg->consumer);
+ if (scale_uv < 0)
+ return scale_uv;
+
+ *val = scale_uv / 1000;
+ *val2 = chan->scan_type.realbits;
+
+ return IIO_VAL_FRACTIONAL_LOG2;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int ad5449_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int val, int val2, long info)
+{
+ struct ad5449 *st = iio_priv(indio_dev);
+ int ret;
+
+ switch (info) {
+ case IIO_CHAN_INFO_RAW:
+ if (val < 0 || val >= (1 << chan->scan_type.realbits))
+ return -EINVAL;
+
+ ret = ad5449_write(indio_dev,
+ AD5449_CMD_LOAD_AND_UPDATE(chan->address),
+ val << chan->scan_type.shift);
+ if (ret == 0)
+ st->dac_cache[chan->address] = val;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct iio_info ad5449_info = {
+ .read_raw = ad5449_read_raw,
+ .write_raw = ad5449_write_raw,
+ .driver_module = THIS_MODULE,
+};
+
+#define AD5449_CHANNEL(chan, bits) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .output = 1, \
+ .channel = (chan), \
+ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+ IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
+ .address = (chan), \
+ .scan_type = IIO_ST('u', (bits), 16, 12 - (bits)), \
+}
+
+#define DECLARE_AD5449_CHANNELS(name, bits) \
+const struct iio_chan_spec name[] = { \
+ AD5449_CHANNEL(0, bits), \
+ AD5449_CHANNEL(1, bits), \
+}
+
+static DECLARE_AD5449_CHANNELS(ad5429_channels, 8);
+static DECLARE_AD5449_CHANNELS(ad5439_channels, 10);
+static DECLARE_AD5449_CHANNELS(ad5449_channels, 12);
+
+static const struct ad5449_chip_info ad5449_chip_info[] = {
+ [ID_AD5426] = {
+ .channels = ad5429_channels,
+ .num_channels = 1,
+ .has_ctrl = false,
+ },
+ [ID_AD5429] = {
+ .channels = ad5429_channels,
+ .num_channels = 2,
+ .has_ctrl = true,
+ },
+ [ID_AD5432] = {
+ .channels = ad5439_channels,
+ .num_channels = 1,
+ .has_ctrl = false,
+ },
+ [ID_AD5439] = {
+ .channels = ad5439_channels,
+ .num_channels = 2,
+ .has_ctrl = true,
+ },
+ [ID_AD5443] = {
+ .channels = ad5449_channels,
+ .num_channels = 1,
+ .has_ctrl = false,
+ },
+ [ID_AD5449] = {
+ .channels = ad5449_channels,
+ .num_channels = 2,
+ .has_ctrl = true,
+ },
+};
+
+static const char *ad5449_vref_name(struct ad5449 *st, int n)
+{
+ if (st->chip_info->num_channels == 1)
+ return "VREF";
+
+ if (n == 0)
+ return "VREFA";
+ else
+ return "VREFB";
+}
+
+static int __devinit ad5449_spi_probe(struct spi_device *spi)
+{
+ struct ad5449_platform_data *pdata = spi->dev.platform_data;
+ const struct spi_device_id *id = spi_get_device_id(spi);
+ struct iio_dev *indio_dev;
+ struct ad5449 *st;
+ unsigned int i;
+ int ret;
+
+ indio_dev = iio_device_alloc(sizeof(*st));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ st = iio_priv(indio_dev);
+ spi_set_drvdata(spi, indio_dev);
+
+ st->chip_info = &ad5449_chip_info[id->driver_data];
+ st->spi = spi;
+
+ for (i = 0; i < st->chip_info->num_channels; ++i)
+ st->vref_reg[i].supply = ad5449_vref_name(st, i);
+
+ ret = regulator_bulk_get(&spi->dev, st->chip_info->num_channels,
+ st->vref_reg);
+ if (ret)
+ goto error_free;
+
+ ret = regulator_bulk_enable(st->chip_info->num_channels, st->vref_reg);
+ if (ret)
+ goto error_free_reg;
+
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->name = id->name;
+ indio_dev->info = &ad5449_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = st->chip_info->channels;
+ indio_dev->num_channels = st->chip_info->num_channels;
+
+ if (st->chip_info->has_ctrl) {
+ unsigned int ctrl = 0x00;
+ if (pdata) {
+ if (pdata->hardware_clear_to_midscale)
+ ctrl |= AD5449_CTRL_HCLR_TO_MIDSCALE;
+ ctrl |= pdata->sdo_mode << AD5449_CTRL_SDO_OFFSET;
+ st->has_sdo = pdata->sdo_mode != AD5449_SDO_DISABLED;
+ } else {
+ st->has_sdo = true;
+ }
+ ad5449_write(indio_dev, AD5449_CMD_CTRL, ctrl);
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto error_disable_reg;
+
+ return 0;
+
+error_disable_reg:
+ regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg);
+error_free_reg:
+ regulator_bulk_free(st->chip_info->num_channels, st->vref_reg);
+error_free:
+ iio_device_free(indio_dev);
+
+ return ret;
+}
+
+static int __devexit ad5449_spi_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct ad5449 *st = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+
+ regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg);
+ regulator_bulk_free(st->chip_info->num_channels, st->vref_reg);
+
+ iio_device_free(indio_dev);
+
+ return 0;
+}
+
+static const struct spi_device_id ad5449_spi_ids[] = {
+ { "ad5415", ID_AD5449 },
+ { "ad5426", ID_AD5426 },
+ { "ad5429", ID_AD5429 },
+ { "ad5432", ID_AD5432 },
+ { "ad5439", ID_AD5439 },
+ { "ad5443", ID_AD5443 },
+ { "ad5449", ID_AD5449 },
+ {}
+};
+MODULE_DEVICE_TABLE(spi, ad5449_spi_ids);
+
+static struct spi_driver ad5449_spi_driver = {
+ .driver = {
+ .name = "ad5449",
+ .owner = THIS_MODULE,
+ },
+ .probe = ad5449_spi_probe,
+ .remove = __devexit_p(ad5449_spi_remove),
+ .id_table = ad5449_spi_ids,
+};
+module_spi_driver(ad5449_spi_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Analog Devices AD5449 and similar DACs");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c
index 6948d75e103..bc92ff9309c 100644
--- a/drivers/iio/dac/ad5686.c
+++ b/drivers/iio/dac/ad5686.c
@@ -188,7 +188,7 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
if (ret)
return ret;
- if (readin == true)
+ if (readin)
st->pwr_down_mask |= (0x3 << (chan->channel * 2));
else
st->pwr_down_mask &= ~(0x3 << (chan->channel * 2));
diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig
index 21e27e2fc68..48ed1483ff2 100644
--- a/drivers/iio/gyro/Kconfig
+++ b/drivers/iio/gyro/Kconfig
@@ -3,6 +3,15 @@
#
menu "Digital gyroscope sensors"
+config ADIS16136
+ tristate "Analog devices ADIS16136 and similar gyroscopes driver"
+ depends on SPI_MASTER
+ select IIO_ADIS_LIB
+ select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
+ help
+ Say yes here to build support for the Analog Devices ADIS16133, ADIS16135,
+ ADIS16136 gyroscope devices.
+
config HID_SENSOR_GYRO_3D
depends on HID_SENSOR_HUB
select IIO_BUFFER
diff --git a/drivers/iio/gyro/Makefile b/drivers/iio/gyro/Makefile
index 8a895d9fcbc..702a058907e 100644
--- a/drivers/iio/gyro/Makefile
+++ b/drivers/iio/gyro/Makefile
@@ -2,4 +2,5 @@
# Makefile for industrial I/O gyroscope sensor drivers
#
+obj-$(CONFIG_ADIS16136) += adis16136.o
obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o
diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c
new file mode 100644
index 00000000000..8cb0bcbfd60
--- /dev/null
+++ b/drivers/iio/gyro/adis16136.c
@@ -0,0 +1,580 @@
+/*
+ * ADIS16133/ADIS16135/ADIS16136 gyroscope driver
+ *
+ * Copyright 2012 Analog Devices Inc.
+ * Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
+
+#include <linux/debugfs.h>
+
+#define ADIS16136_REG_FLASH_CNT 0x00
+#define ADIS16136_REG_TEMP_OUT 0x02
+#define ADIS16136_REG_GYRO_OUT2 0x04
+#define ADIS16136_REG_GYRO_OUT 0x06
+#define ADIS16136_REG_GYRO_OFF2 0x08
+#define ADIS16136_REG_GYRO_OFF 0x0A
+#define ADIS16136_REG_ALM_MAG1 0x10
+#define ADIS16136_REG_ALM_MAG2 0x12
+#define ADIS16136_REG_ALM_SAMPL1 0x14
+#define ADIS16136_REG_ALM_SAMPL2 0x16
+#define ADIS16136_REG_ALM_CTRL 0x18
+#define ADIS16136_REG_GPIO_CTRL 0x1A
+#define ADIS16136_REG_MSC_CTRL 0x1C
+#define ADIS16136_REG_SMPL_PRD 0x1E
+#define ADIS16136_REG_AVG_CNT 0x20
+#define ADIS16136_REG_DEC_RATE 0x22
+#define ADIS16136_REG_SLP_CTRL 0x24
+#define ADIS16136_REG_DIAG_STAT 0x26
+#define ADIS16136_REG_GLOB_CMD 0x28
+#define ADIS16136_REG_LOT1 0x32
+#define ADIS16136_REG_LOT2 0x34
+#define ADIS16136_REG_LOT3 0x36
+#define ADIS16136_REG_PROD_ID 0x38
+#define ADIS16136_REG_SERIAL_NUM 0x3A
+
+#define ADIS16136_DIAG_STAT_FLASH_UPDATE_FAIL 2
+#define ADIS16136_DIAG_STAT_SPI_FAIL 3
+#define ADIS16136_DIAG_STAT_SELF_TEST_FAIL 5
+#define ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL 6
+
+#define ADIS16136_MSC_CTRL_MEMORY_TEST BIT(11)
+#define ADIS16136_MSC_CTRL_SELF_TEST BIT(10)
+
+struct adis16136_chip_info {
+ unsigned int precision;
+ unsigned int fullscale;
+};
+
+struct adis16136 {
+ const struct adis16136_chip_info *chip_info;
+
+ struct adis adis;
+};
+
+#ifdef CONFIG_DEBUG_FS
+
+static ssize_t adis16136_show_serial(struct file *file,
+ char __user *userbuf, size_t count, loff_t *ppos)
+{
+ struct adis16136 *adis16136 = file->private_data;
+ uint16_t lot1, lot2, lot3, serial;
+ char buf[20];
+ size_t len;
+ int ret;
+
+ ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_SERIAL_NUM,
+ &serial);
+ if (ret < 0)
+ return ret;
+
+ ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT1, &lot1);
+ if (ret < 0)
+ return ret;
+
+ ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT2, &lot2);
+ if (ret < 0)
+ return ret;
+
+ ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT3, &lot3);
+ if (ret < 0)
+ return ret;
+
+ len = snprintf(buf, sizeof(buf), "%.4x%.4x%.4x-%.4x\n", lot1, lot2,
+ lot3, serial);
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, len);
+}
+
+static const struct file_operations adis16136_serial_fops = {
+ .open = simple_open,
+ .read = adis16136_show_serial,
+ .llseek = default_llseek,
+ .owner = THIS_MODULE,
+};
+
+static int adis16136_show_product_id(void *arg, u64 *val)
+{
+ struct adis16136 *adis16136 = arg;
+ u16 prod_id;
+ int ret;
+
+ ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_PROD_ID,
+ &prod_id);
+ if (ret < 0)
+ return ret;
+
+ *val = prod_id;
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(adis16136_product_id_fops,
+ adis16136_show_product_id, NULL, "%llu\n");
+
+static int adis16136_show_flash_count(void *arg, u64 *val)
+{
+ struct adis16136 *adis16136 = arg;
+ uint16_t flash_count;
+ int ret;
+
+ ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_FLASH_CNT,
+ &flash_count);
+ if (ret < 0)
+ return ret;
+
+ *val = flash_count;
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(adis16136_flash_count_fops,
+ adis16136_show_flash_count, NULL, "%lld\n");
+
+static int adis16136_debugfs_init(struct iio_dev *indio_dev)
+{
+ struct adis16136 *adis16136 = iio_priv(indio_dev);
+
+ debugfs_create_file("serial_number", 0400, indio_dev->debugfs_dentry,
+ adis16136, &adis16136_serial_fops);
+ debugfs_create_file("product_id", 0400, indio_dev->debugfs_dentry,
+ adis16136, &adis16136_product_id_fops);
+ debugfs_create_file("flash_count", 0400, indio_dev->debugfs_dentry,
+ adis16136, &adis16136_flash_count_fops);
+
+ return 0;
+}
+
+#else
+
+static int adis16136_debugfs_init(struct iio_dev *indio_dev)
+{
+ return 0;
+}
+
+#endif
+
+static int adis16136_set_freq(struct adis16136 *adis16136, unsigned int freq)
+{
+ unsigned int t;
+
+ t = 32768 / freq;
+ if (t < 0xf)
+ t = 0xf;
+ else if (t > 0xffff)
+ t = 0xffff;
+ else
+ t--;
+
+ return adis_write_reg_16(&adis16136->adis, ADIS16136_REG_SMPL_PRD, t);
+}
+
+static int adis16136_get_freq(struct adis16136 *adis16136, unsigned int *freq)
+{
+ uint16_t t;
+ int ret;
+
+ ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_SMPL_PRD, &t);
+ if (ret < 0)
+ return ret;
+
+ *freq = 32768 / (t + 1);
+
+ return 0;
+}
+
+static ssize_t adis16136_write_frequency(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t len)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct adis16136 *adis16136 = iio_priv(indio_dev);
+ unsigned int val;
+ int ret;
+
+ ret = kstrtouint(buf, 10, &val);
+ if (ret)
+ return ret;
+
+ if (val == 0)
+ return -EINVAL;
+
+ ret = adis16136_set_freq(adis16136, val);
+
+ return ret ? ret : len;
+}
+
+static ssize_t adis16136_read_frequency(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct adis16136 *adis16136 = iio_priv(indio_dev);
+ unsigned int freq;
+ int ret;
+
+ ret = adis16136_get_freq(adis16136, &freq);
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%d\n", freq);
+}
+
+static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
+ adis16136_read_frequency,
+ adis16136_write_frequency);
+
+static const unsigned adis16136_3db_divisors[] = {
+ [0] = 2, /* Special case */
+ [1] = 6,
+ [2] = 12,
+ [3] = 25,
+ [4] = 50,
+ [5] = 100,
+ [6] = 200,
+ [7] = 200, /* Not a valid setting */
+};
+
+static int adis16136_set_filter(struct iio_dev *indio_dev, int val)
+{
+ struct adis16136 *adis16136 = iio_priv(indio_dev);
+ unsigned int freq;
+ int i, ret;
+
+ ret = adis16136_get_freq(adis16136, &freq);
+ if (ret < 0)
+ return ret;
+
+ for (i = ARRAY_SIZE(adis16136_3db_divisors) - 1; i >= 1; i--) {
+ if (freq / adis16136_3db_divisors[i] >= val)
+ break;
+ }
+
+ return adis_write_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, i);
+}
+
+static int adis16136_get_filter(struct iio_dev *indio_dev, int *val)
+{
+ struct adis16136 *adis16136 = iio_priv(indio_dev);
+ unsigned int freq;
+ uint16_t val16;
+ int ret;
+
+ mutex_lock(&indio_dev->mlock);
+
+ ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, &val16);
+ if (ret < 0)
+ goto err_unlock;
+
+ ret = adis16136_get_freq(adis16136, &freq);
+ if (ret < 0)
+ goto err_unlock;
+
+ *val = freq / adis16136_3db_divisors[val16 & 0x07];
+
+err_unlock:
+ mutex_unlock(&indio_dev->mlock);
+
+ return ret ? ret : IIO_VAL_INT;
+}
+
+static int adis16136_read_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, int *val, int *val2, long info)
+{
+ struct adis16136 *adis16136 = iio_priv(indio_dev);
+ uint32_t val32;
+ int ret;
+
+ switch (info) {
+ case IIO_CHAN_INFO_RAW:
+ return adis_single_conversion(indio_dev, chan, 0, val);
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->type) {
+ case IIO_ANGL_VEL:
+ *val = adis16136->chip_info->precision;
+ *val2 = (adis16136->chip_info->fullscale << 16);
+ return IIO_VAL_FRACTIONAL;
+ case IIO_TEMP:
+ *val = 10;
+ *val2 = 697000; /* 0.010697 degree Celsius */
+ return IIO_VAL_INT_PLUS_MICRO;
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_CALIBBIAS:
+ ret = adis_read_reg_32(&adis16136->adis,
+ ADIS16136_REG_GYRO_OFF2, &val32);
+ if (ret < 0)
+ return ret;
+
+ *val = sign_extend32(val32, 31);
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+ return adis16136_get_filter(indio_dev, val);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int adis16136_write_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, int val, int val2, long info)
+{
+ struct adis16136 *adis16136 = iio_priv(indio_dev);
+
+ switch (info) {
+ case IIO_CHAN_INFO_CALIBBIAS:
+ return adis_write_reg_32(&adis16136->adis,
+ ADIS16136_REG_GYRO_OFF2, val);
+ case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+ return adis16136_set_filter(indio_dev, val);
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+enum {
+ ADIS16136_SCAN_GYRO,
+ ADIS16136_SCAN_TEMP,
+};
+
+static const struct iio_chan_spec adis16136_channels[] = {
+ {
+ .type = IIO_ANGL_VEL,
+ .modified = 1,
+ .channel2 = IIO_MOD_X,
+ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
+ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+ IIO_CHAN_INFO_SCALE_SHARED_BIT |
+ IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT,
+ .address = ADIS16136_REG_GYRO_OUT2,
+ .scan_index = ADIS16136_SCAN_GYRO,
+ .scan_type = {
+ .sign = 's',
+ .realbits = 32,
+ .storagebits = 32,
+ .endianness = IIO_BE,
+ },
+ }, {
+ .type = IIO_TEMP,
+ .indexed = 1,
+ .channel = 0,
+ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
+ IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
+ .address = ADIS16136_REG_TEMP_OUT,
+ .scan_index = ADIS16136_SCAN_TEMP,
+ .scan_type = {
+ .sign = 's',
+ .realbits = 16,
+ .storagebits = 16,
+ .endianness = IIO_BE,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(2),
+};
+
+static struct attribute *adis16136_attributes[] = {
+ &iio_dev_attr_sampling_frequency.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group adis16136_attribute_group = {
+ .attrs = adis16136_attributes,
+};
+
+static const struct iio_info adis16136_info = {
+ .driver_module = THIS_MODULE,
+ .attrs = &adis16136_attribute_group,
+ .read_raw = &adis16136_read_raw,
+ .write_raw = &adis16136_write_raw,
+ .update_scan_mode = adis_update_scan_mode,
+ .debugfs_reg_access = adis_debugfs_reg_access,
+};
+
+static int adis16136_stop_device(struct iio_dev *indio_dev)
+{
+ struct adis16136 *adis16136 = iio_priv(indio_dev);
+ int ret;
+
+ ret = adis_write_reg_16(&adis16136->adis, ADIS16136_REG_SLP_CTRL, 0xff);
+ if (ret)
+ dev_err(&indio_dev->dev,
+ "Could not power down device: %d\n", ret);
+
+ return ret;
+}
+
+static int adis16136_initial_setup(struct iio_dev *indio_dev)
+{
+ struct adis16136 *adis16136 = iio_priv(indio_dev);
+ unsigned int device_id;
+ uint16_t prod_id;
+ int ret;
+
+ ret = adis_initial_startup(&adis16136->adis);
+ if (ret)
+ return ret;
+
+ ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_PROD_ID,
+ &prod_id);
+ if (ret)
+ return ret;
+
+ sscanf(indio_dev->name, "adis%u\n", &device_id);
+
+ if (prod_id != device_id)
+ dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.",
+ device_id, prod_id);
+
+ return 0;
+}
+
+static const char * const adis16136_status_error_msgs[] = {
+ [ADIS16136_DIAG_STAT_FLASH_UPDATE_FAIL] = "Flash update failed",
+ [ADIS16136_DIAG_STAT_SPI_FAIL] = "SPI failure",
+ [ADIS16136_DIAG_STAT_SELF_TEST_FAIL] = "Self test error",
+ [ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL] = "Flash checksum error",
+};
+
+static const struct adis_data adis16136_data = {
+ .diag_stat_reg = ADIS16136_REG_DIAG_STAT,
+ .glob_cmd_reg = ADIS16136_REG_GLOB_CMD,
+ .msc_ctrl_reg = ADIS16136_REG_MSC_CTRL,
+
+ .self_test_mask = ADIS16136_MSC_CTRL_SELF_TEST,
+ .startup_delay = 80,
+
+ .read_delay = 10,
+ .write_delay = 10,
+
+ .status_error_msgs = adis16136_status_error_msgs,
+ .status_error_mask = BIT(ADIS16136_DIAG_STAT_FLASH_UPDATE_FAIL) |
+ BIT(ADIS16136_DIAG_STAT_SPI_FAIL) |
+ BIT(ADIS16136_DIAG_STAT_SELF_TEST_FAIL) |
+ BIT(ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL),
+};
+
+enum adis16136_id {
+ ID_ADIS16133,
+ ID_ADIS16135,
+ ID_ADIS16136,
+};
+
+static const struct adis16136_chip_info adis16136_chip_info[] = {
+ [ID_ADIS16133] = {
+ .precision = IIO_DEGREE_TO_RAD(1200),
+ .fullscale = 24000,
+ },
+ [ID_ADIS16135] = {
+ .precision = IIO_DEGREE_TO_RAD(300),
+ .fullscale = 24000,
+ },
+ [ID_ADIS16136] = {
+ .precision = IIO_DEGREE_TO_RAD(450),
+ .fullscale = 24623,
+ },
+};
+
+static int adis16136_probe(struct spi_device *spi)
+{
+ const struct spi_device_id *id = spi_get_device_id(spi);
+ struct adis16136 *adis16136;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ indio_dev = iio_device_alloc(sizeof(*adis16136));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ spi_set_drvdata(spi, indio_dev);
+
+ adis16136 = iio_priv(indio_dev);
+
+ adis16136->chip_info = &adis16136_chip_info[id->driver_data];
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->name = spi_get_device_id(spi)->name;
+ indio_dev->channels = adis16136_channels;
+ indio_dev->num_channels = ARRAY_SIZE(adis16136_channels);
+ indio_dev->info = &adis16136_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ ret = adis_init(&adis16136->adis, indio_dev, spi, &adis16136_data);
+ if (ret)
+ goto error_free_dev;
+
+ ret = adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL);
+ if (ret)
+ goto error_free_dev;
+
+ ret = adis16136_initial_setup(indio_dev);
+ if (ret)
+ goto error_cleanup_buffer;
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto error_stop_device;
+
+ adis16136_debugfs_init(indio_dev);
+
+ return 0;
+
+error_stop_device:
+ adis16136_stop_device(indio_dev);
+error_cleanup_buffer:
+ adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev);
+error_free_dev:
+ iio_device_free(indio_dev);
+ return ret;
+}
+
+static int adis16136_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct adis16136 *adis16136 = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ adis16136_stop_device(indio_dev);
+
+ adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev);
+
+ iio_device_free(indio_dev);
+
+ return 0;
+}
+
+static const struct spi_device_id adis16136_ids[] = {
+ { "adis16133", ID_ADIS16133 },
+ { "adis16135", ID_ADIS16135 },
+ { "adis16136", ID_ADIS16136 },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, adis16136_ids);
+
+static struct spi_driver adis16136_driver = {
+ .driver = {
+ .name = "adis16136",
+ .owner = THIS_MODULE,
+ },
+ .id_table = adis16136_ids,
+ .probe = adis16136_probe,
+ .remove = adis16136_remove,
+};
+module_spi_driver(adis16136_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Analog Devices ADIS16133/ADIS16135/ADIS16136 gyroscope driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index 4c56ada51c3..4c8b158e40e 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -197,21 +197,8 @@ 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)
{
- struct iio_buffer *buffer = indio_dev->buffer;
- int datum_sz;
-
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
- if (!buffer) {
- dev_err(&indio_dev->dev, "Buffer == NULL\n");
- return;
- }
- datum_sz = buffer->access->get_bytes_per_datum(buffer);
- if (len > datum_sz) {
- dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
- datum_sz);
- return;
- }
- iio_push_to_buffer(buffer, (u8 *)data);
+ iio_push_to_buffers(indio_dev, (u8 *)data);
}
/* Callback handler to send event after all samples are received and captured */
@@ -319,10 +306,10 @@ static int __devinit hid_gyro_3d_probe(struct platform_device *pdev)
goto error_free_dev;
}
- channels = kmemdup(gyro_3d_channels,
- sizeof(gyro_3d_channels),
- GFP_KERNEL);
+ channels = kmemdup(gyro_3d_channels, sizeof(gyro_3d_channels),
+ GFP_KERNEL);
if (!channels) {
+ ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
goto error_free_dev;
}
diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
new file mode 100644
index 00000000000..3d79a40e916
--- /dev/null
+++ b/drivers/iio/imu/Kconfig
@@ -0,0 +1,27 @@
+#
+# IIO imu drivers configuration
+#
+menu "Inertial measurement units"
+
+config ADIS16480
+ tristate "Analog Devices ADIS16480 and similar IMU driver"
+ depends on SPI
+ select IIO_ADIS_LIB
+ select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
+ help
+ Say yes here to build support for Analog Devices ADIS16375, ADIS16480,
+ ADIS16485, ADIS16488 inertial sensors.
+
+endmenu
+
+config IIO_ADIS_LIB
+ tristate
+ help
+ A set of IO helper functions for the Analog Devices ADIS* device family.
+
+config IIO_ADIS_LIB_BUFFER
+ bool
+ select IIO_TRIGGERED_BUFFER
+ help
+ A set of buffer helper functions for the Analog Devices ADIS* device
+ family.
diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
new file mode 100644
index 00000000000..cfe57638f6f
--- /dev/null
+++ b/drivers/iio/imu/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for Inertial Measurement Units
+#
+
+obj-$(CONFIG_ADIS16480) += adis16480.o
+
+adis_lib-y += adis.o
+adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_trigger.o
+adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o
+obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o
diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c
new file mode 100644
index 00000000000..911255d41c1
--- /dev/null
+++ b/drivers/iio/imu/adis.c
@@ -0,0 +1,440 @@
+/*
+ * Common library for ADIS16XXX devices
+ *
+ * Copyright 2012 Analog Devices Inc.
+ * Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <asm/unaligned.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
+
+#define ADIS_MSC_CTRL_DATA_RDY_EN BIT(2)
+#define ADIS_MSC_CTRL_DATA_RDY_POL_HIGH BIT(1)
+#define ADIS_MSC_CTRL_DATA_RDY_DIO2 BIT(0)
+#define ADIS_GLOB_CMD_SW_RESET BIT(7)
+
+int adis_write_reg(struct adis *adis, unsigned int reg,
+ unsigned int value, unsigned int size)
+{
+ unsigned int page = reg / ADIS_PAGE_SIZE;
+ int ret, i;
+ struct spi_message msg;
+ struct spi_transfer xfers[] = {
+ {
+ .tx_buf = adis->tx,
+ .bits_per_word = 8,
+ .len = 2,
+ .cs_change = 1,
+ .delay_usecs = adis->data->write_delay,
+ }, {
+ .tx_buf = adis->tx + 2,
+ .bits_per_word = 8,
+ .len = 2,
+ .cs_change = 1,
+ .delay_usecs = adis->data->write_delay,
+ }, {
+ .tx_buf = adis->tx + 4,
+ .bits_per_word = 8,
+ .len = 2,
+ .cs_change = 1,
+ .delay_usecs = adis->data->write_delay,
+ }, {
+ .tx_buf = adis->tx + 6,
+ .bits_per_word = 8,
+ .len = 2,
+ .delay_usecs = adis->data->write_delay,
+ }, {
+ .tx_buf = adis->tx + 8,
+ .bits_per_word = 8,
+ .len = 2,
+ .delay_usecs = adis->data->write_delay,
+ },
+ };
+
+ mutex_lock(&adis->txrx_lock);
+
+ spi_message_init(&msg);
+
+ if (adis->current_page != page) {
+ adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
+ adis->tx[1] = page;
+ spi_message_add_tail(&xfers[0], &msg);
+ }
+
+ switch (size) {
+ case 4:
+ adis->tx[8] = ADIS_WRITE_REG(reg + 3);
+ adis->tx[9] = (value >> 24) & 0xff;
+ adis->tx[6] = ADIS_WRITE_REG(reg + 2);
+ adis->tx[7] = (value >> 16) & 0xff;
+ case 2:
+ adis->tx[4] = ADIS_WRITE_REG(reg + 1);
+ adis->tx[5] = (value >> 8) & 0xff;
+ case 1:
+ adis->tx[2] = ADIS_WRITE_REG(reg);
+ adis->tx[3] = value & 0xff;
+ break;
+ default:
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ xfers[size].cs_change = 0;
+
+ for (i = 1; i <= size; i++)
+ spi_message_add_tail(&xfers[i], &msg);
+
+ ret = spi_sync(adis->spi, &msg);
+ if (ret) {
+ dev_err(&adis->spi->dev, "Failed to write register 0x%02X: %d\n",
+ reg, ret);
+ } else {
+ adis->current_page = page;
+ }
+
+out_unlock:
+ mutex_unlock(&adis->txrx_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(adis_write_reg);
+
+/**
+ * adis_read_reg() - read 2 bytes from a 16-bit register
+ * @adis: The adis device
+ * @reg: The address of the lower of the two registers
+ * @val: The value read back from the device
+ */
+int adis_read_reg(struct adis *adis, unsigned int reg,
+ unsigned int *val, unsigned int size)
+{
+ unsigned int page = reg / ADIS_PAGE_SIZE;
+ struct spi_message msg;
+ int ret;
+ struct spi_transfer xfers[] = {
+ {
+ .tx_buf = adis->tx,
+ .bits_per_word = 8,
+ .len = 2,
+ .cs_change = 1,
+ .delay_usecs = adis->data->write_delay,
+ }, {
+ .tx_buf = adis->tx + 2,
+ .bits_per_word = 8,
+ .len = 2,
+ .cs_change = 1,
+ .delay_usecs = adis->data->read_delay,
+ }, {
+ .tx_buf = adis->tx + 4,
+ .rx_buf = adis->rx,
+ .bits_per_word = 8,
+ .len = 2,
+ .cs_change = 1,
+ .delay_usecs = adis->data->read_delay,
+ }, {
+ .rx_buf = adis->rx + 2,
+ .bits_per_word = 8,
+ .len = 2,
+ .delay_usecs = adis->data->read_delay,
+ },
+ };
+
+ mutex_lock(&adis->txrx_lock);
+ spi_message_init(&msg);
+
+ if (adis->current_page != page) {
+ adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
+ adis->tx[1] = page;
+ spi_message_add_tail(&xfers[0], &msg);
+ }
+
+ switch (size) {
+ case 4:
+ adis->tx[2] = ADIS_READ_REG(reg + 2);
+ adis->tx[3] = 0;
+ spi_message_add_tail(&xfers[1], &msg);
+ case 2:
+ adis->tx[4] = ADIS_READ_REG(reg);
+ adis->tx[5] = 0;
+ spi_message_add_tail(&xfers[2], &msg);
+ spi_message_add_tail(&xfers[3], &msg);
+ break;
+ default:
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ ret = spi_sync(adis->spi, &msg);
+ if (ret) {
+ dev_err(&adis->spi->dev, "Failed to read register 0x%02X: %d\n",
+ reg, ret);
+ goto out_unlock;
+ } else {
+ adis->current_page = page;
+ }
+
+ switch (size) {
+ case 4:
+ *val = get_unaligned_be32(adis->rx);
+ break;
+ case 2:
+ *val = get_unaligned_be16(adis->rx + 2);
+ break;
+ }
+
+out_unlock:
+ mutex_unlock(&adis->txrx_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(adis_read_reg);
+
+#ifdef CONFIG_DEBUG_FS
+
+int adis_debugfs_reg_access(struct iio_dev *indio_dev,
+ unsigned int reg, unsigned int writeval, unsigned int *readval)
+{
+ struct adis *adis = iio_device_get_drvdata(indio_dev);
+
+ if (readval) {
+ uint16_t val16;
+ int ret;
+
+ ret = adis_read_reg_16(adis, reg, &val16);
+ *readval = val16;
+
+ return ret;
+ } else {
+ return adis_write_reg_16(adis, reg, writeval);
+ }
+}
+EXPORT_SYMBOL(adis_debugfs_reg_access);
+
+#endif
+
+/**
+ * adis_enable_irq() - Enable or disable data ready IRQ
+ * @adis: The adis device
+ * @enable: Whether to enable the IRQ
+ *
+ * Returns 0 on success, negative error code otherwise
+ */
+int adis_enable_irq(struct adis *adis, bool enable)
+{
+ int ret = 0;
+ uint16_t msc;
+
+ if (adis->data->enable_irq)
+ return adis->data->enable_irq(adis, enable);
+
+ ret = adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
+ if (ret)
+ goto error_ret;
+
+ msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH;
+ msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2;
+ if (enable)
+ msc |= ADIS_MSC_CTRL_DATA_RDY_EN;
+ else
+ msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN;
+
+ ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
+
+error_ret:
+ return ret;
+}
+EXPORT_SYMBOL(adis_enable_irq);
+
+/**
+ * adis_check_status() - Check the device for error conditions
+ * @adis: The adis device
+ *
+ * Returns 0 on success, a negative error code otherwise
+ */
+int adis_check_status(struct adis *adis)
+{
+ uint16_t status;
+ int ret;
+ int i;
+
+ ret = adis_read_reg_16(adis, adis->data->diag_stat_reg, &status);
+ if (ret < 0)
+ return ret;
+
+ status &= adis->data->status_error_mask;
+
+ if (status == 0)
+ return 0;
+
+ for (i = 0; i < 16; ++i) {
+ if (status & BIT(i)) {
+ dev_err(&adis->spi->dev, "%s.\n",
+ adis->data->status_error_msgs[i]);
+ }
+ }
+
+ return -EIO;
+}
+EXPORT_SYMBOL_GPL(adis_check_status);
+
+/**
+ * adis_reset() - Reset the device
+ * @adis: The adis device
+ *
+ * Returns 0 on success, a negative error code otherwise
+ */
+int adis_reset(struct adis *adis)
+{
+ int ret;
+
+ ret = adis_write_reg_8(adis, adis->data->glob_cmd_reg,
+ ADIS_GLOB_CMD_SW_RESET);
+ if (ret)
+ dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(adis_reset);
+
+static int adis_self_test(struct adis *adis)
+{
+ int ret;
+
+ ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg,
+ adis->data->self_test_mask);
+ if (ret) {
+ dev_err(&adis->spi->dev, "Failed to initiate self test: %d\n",
+ ret);
+ return ret;
+ }
+
+ msleep(adis->data->startup_delay);
+
+ return adis_check_status(adis);
+}
+
+/**
+ * adis_inital_startup() - Performs device self-test
+ * @adis: The adis device
+ *
+ * Returns 0 if the device is operational, a negative error code otherwise.
+ *
+ * This function should be called early on in the device initialization sequence
+ * to ensure that the device is in a sane and known state and that it is usable.
+ */
+int adis_initial_startup(struct adis *adis)
+{
+ int ret;
+
+ ret = adis_self_test(adis);
+ if (ret) {
+ dev_err(&adis->spi->dev, "Self-test failed, trying reset.\n");
+ adis_reset(adis);
+ msleep(adis->data->startup_delay);
+ ret = adis_self_test(adis);
+ if (ret) {
+ dev_err(&adis->spi->dev, "Second self-test failed, giving up.\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(adis_initial_startup);
+
+/**
+ * adis_single_conversion() - Performs a single sample conversion
+ * @indio_dev: The IIO device
+ * @chan: The IIO channel
+ * @error_mask: Mask for the error bit
+ * @val: Result of the conversion
+ *
+ * Returns IIO_VAL_INT on success, a negative error code otherwise.
+ *
+ * The function performs a single conversion on a given channel and post
+ * processes the value accordingly to the channel spec. If a error_mask is given
+ * the function will check if the mask is set in the returned raw value. If it
+ * is set the function will perform a self-check. If the device does not report
+ * a error bit in the channels raw value set error_mask to 0.
+ */
+int adis_single_conversion(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, unsigned int error_mask, int *val)
+{
+ struct adis *adis = iio_device_get_drvdata(indio_dev);
+ unsigned int uval;
+ int ret;
+
+ mutex_lock(&indio_dev->mlock);
+
+ ret = adis_read_reg(adis, chan->address, &uval,
+ chan->scan_type.storagebits / 8);
+ if (ret)
+ goto err_unlock;
+
+ if (uval & error_mask) {
+ ret = adis_check_status(adis);
+ if (ret)
+ goto err_unlock;
+ }
+
+ if (chan->scan_type.sign == 's')
+ *val = sign_extend32(uval, chan->scan_type.realbits - 1);
+ else
+ *val = uval & ((1 << chan->scan_type.realbits) - 1);
+
+ ret = IIO_VAL_INT;
+err_unlock:
+ mutex_unlock(&indio_dev->mlock);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(adis_single_conversion);
+
+/**
+ * adis_init() - Initialize adis device structure
+ * @adis: The adis device
+ * @indio_dev: The iio device
+ * @spi: The spi device
+ * @data: Chip specific data
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ *
+ * This function must be called, before any other adis helper function may be
+ * called.
+ */
+int adis_init(struct adis *adis, struct iio_dev *indio_dev,
+ struct spi_device *spi, const struct adis_data *data)
+{
+ mutex_init(&adis->txrx_lock);
+ adis->spi = spi;
+ adis->data = data;
+ iio_device_set_drvdata(indio_dev, adis);
+
+ if (data->has_paging) {
+ /* Need to set the page before first read/write */
+ adis->current_page = -1;
+ } else {
+ /* Page will always be 0 */
+ adis->current_page = 0;
+ }
+
+ return adis_enable_irq(adis, false);
+}
+EXPORT_SYMBOL_GPL(adis_init);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Common library code for ADIS16XXX devices");
diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c
new file mode 100644
index 00000000000..8c26a5f7cd5
--- /dev/null
+++ b/drivers/iio/imu/adis16480.c
@@ -0,0 +1,924 @@
+/*
+ * ADIS16480 and similar IMUs driver
+ *
+ * Copyright 2012 Analog Devices 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/interrupt.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
+
+#include <linux/debugfs.h>
+
+#define ADIS16480_PAGE_SIZE 0x80
+
+#define ADIS16480_REG(page, reg) ((page) * ADIS16480_PAGE_SIZE + (reg))
+
+#define ADIS16480_REG_PAGE_ID 0x00 /* Same address on each page */
+#define ADIS16480_REG_SEQ_CNT ADIS16480_REG(0x00, 0x06)
+#define ADIS16480_REG_SYS_E_FLA ADIS16480_REG(0x00, 0x08)
+#define ADIS16480_REG_DIAG_STS ADIS16480_REG(0x00, 0x0A)
+#define ADIS16480_REG_ALM_STS ADIS16480_REG(0x00, 0x0C)
+#define ADIS16480_REG_TEMP_OUT ADIS16480_REG(0x00, 0x0E)
+#define ADIS16480_REG_X_GYRO_OUT ADIS16480_REG(0x00, 0x10)
+#define ADIS16480_REG_Y_GYRO_OUT ADIS16480_REG(0x00, 0x14)
+#define ADIS16480_REG_Z_GYRO_OUT ADIS16480_REG(0x00, 0x18)
+#define ADIS16480_REG_X_ACCEL_OUT ADIS16480_REG(0x00, 0x1C)
+#define ADIS16480_REG_Y_ACCEL_OUT ADIS16480_REG(0x00, 0x20)
+#define ADIS16480_REG_Z_ACCEL_OUT ADIS16480_REG(0x00, 0x24)
+#define ADIS16480_REG_X_MAGN_OUT ADIS16480_REG(0x00, 0x28)
+#define ADIS16480_REG_Y_MAGN_OUT ADIS16480_REG(0x00, 0x2A)
+#define ADIS16480_REG_Z_MAGN_OUT ADIS16480_REG(0x00, 0x2C)
+#define ADIS16480_REG_BAROM_OUT ADIS16480_REG(0x00, 0x2E)
+#define ADIS16480_REG_X_DELTAANG_OUT ADIS16480_REG(0x00, 0x40)
+#define ADIS16480_REG_Y_DELTAANG_OUT ADIS16480_REG(0x00, 0x44)
+#define ADIS16480_REG_Z_DELTAANG_OUT ADIS16480_REG(0x00, 0x48)
+#define ADIS16480_REG_X_DELTAVEL_OUT ADIS16480_REG(0x00, 0x4C)
+#define ADIS16480_REG_Y_DELTAVEL_OUT ADIS16480_REG(0x00, 0x50)
+#define ADIS16480_REG_Z_DELTAVEL_OUT ADIS16480_REG(0x00, 0x54)
+#define ADIS16480_REG_PROD_ID ADIS16480_REG(0x00, 0x7E)
+
+#define ADIS16480_REG_X_GYRO_SCALE ADIS16480_REG(0x02, 0x04)
+#define ADIS16480_REG_Y_GYRO_SCALE ADIS16480_REG(0x02, 0x06)
+#define ADIS16480_REG_Z_GYRO_SCALE ADIS16480_REG(0x02, 0x08)
+#define ADIS16480_REG_X_ACCEL_SCALE ADIS16480_REG(0x02, 0x0A)
+#define ADIS16480_REG_Y_ACCEL_SCALE ADIS16480_REG(0x02, 0x0C)
+#define ADIS16480_REG_Z_ACCEL_SCALE ADIS16480_REG(0x02, 0x0E)
+#define ADIS16480_REG_X_GYRO_BIAS ADIS16480_REG(0x02, 0x10)
+#define ADIS16480_REG_Y_GYRO_BIAS ADIS16480_REG(0x02, 0x14)
+#define ADIS16480_REG_Z_GYRO_BIAS ADIS16480_REG(0x02, 0x18)
+#define ADIS16480_REG_X_ACCEL_BIAS ADIS16480_REG(0x02, 0x1C)
+#define ADIS16480_REG_Y_ACCEL_BIAS ADIS16480_REG(0x02, 0x20)
+#define ADIS16480_REG_Z_ACCEL_BIAS ADIS16480_REG(0x02, 0x24)
+#define ADIS16480_REG_X_HARD_IRON ADIS16480_REG(0x02, 0x28)
+#define ADIS16480_REG_Y_HARD_IRON ADIS16480_REG(0x02, 0x2A)
+#define ADIS16480_REG_Z_HARD_IRON ADIS16480_REG(0x02, 0x2C)
+#define ADIS16480_REG_BAROM_BIAS ADIS16480_REG(0x02, 0x40)
+#define ADIS16480_REG_FLASH_CNT ADIS16480_REG(0x02, 0x7C)
+
+#define ADIS16480_REG_GLOB_CMD ADIS16480_REG(0x03, 0x02)
+#define ADIS16480_REG_FNCTIO_CTRL ADIS16480_REG(0x03, 0x06)
+#define ADIS16480_REG_GPIO_CTRL ADIS16480_REG(0x03, 0x08)
+#define ADIS16480_REG_CONFIG ADIS16480_REG(0x03, 0x0A)
+#define ADIS16480_REG_DEC_RATE ADIS16480_REG(0x03, 0x0C)
+#define ADIS16480_REG_SLP_CNT ADIS16480_REG(0x03, 0x10)
+#define ADIS16480_REG_FILTER_BNK0 ADIS16480_REG(0x03, 0x16)
+#define ADIS16480_REG_FILTER_BNK1 ADIS16480_REG(0x03, 0x18)
+#define ADIS16480_REG_ALM_CNFG0 ADIS16480_REG(0x03, 0x20)
+#define ADIS16480_REG_ALM_CNFG1 ADIS16480_REG(0x03, 0x22)
+#define ADIS16480_REG_ALM_CNFG2 ADIS16480_REG(0x03, 0x24)
+#define ADIS16480_REG_XG_ALM_MAGN ADIS16480_REG(0x03, 0x28)
+#define ADIS16480_REG_YG_ALM_MAGN ADIS16480_REG(0x03, 0x2A)
+#define ADIS16480_REG_ZG_ALM_MAGN ADIS16480_REG(0x03, 0x2C)
+#define ADIS16480_REG_XA_ALM_MAGN ADIS16480_REG(0x03, 0x2E)
+#define ADIS16480_REG_YA_ALM_MAGN ADIS16480_REG(0x03, 0x30)
+#define ADIS16480_REG_ZA_ALM_MAGN ADIS16480_REG(0x03, 0x32)
+#define ADIS16480_REG_XM_ALM_MAGN ADIS16480_REG(0x03, 0x34)
+#define ADIS16480_REG_YM_ALM_MAGN ADIS16480_REG(0x03, 0x36)
+#define ADIS16480_REG_ZM_ALM_MAGN ADIS16480_REG(0x03, 0x38)
+#define ADIS16480_REG_BR_ALM_MAGN ADIS16480_REG(0x03, 0x3A)
+#define ADIS16480_REG_FIRM_REV ADIS16480_REG(0x03, 0x78)
+#define ADIS16480_REG_FIRM_DM ADIS16480_REG(0x03, 0x7A)
+#define ADIS16480_REG_FIRM_Y ADIS16480_REG(0x03, 0x7C)
+
+#define ADIS16480_REG_SERIAL_NUM ADIS16480_REG(0x04, 0x20)
+
+/* Each filter coefficent bank spans two pages */
+#define ADIS16480_FIR_COEF(page) (x < 60 ? ADIS16480_REG(page, (x) + 8) : \
+ ADIS16480_REG((page) + 1, (x) - 60 + 8))
+#define ADIS16480_FIR_COEF_A(x) ADIS16480_FIR_COEF(0x05, (x))
+#define ADIS16480_FIR_COEF_B(x) ADIS16480_FIR_COEF(0x07, (x))
+#define ADIS16480_FIR_COEF_C(x) ADIS16480_FIR_COEF(0x09, (x))
+#define ADIS16480_FIR_COEF_D(x) ADIS16480_FIR_COEF(0x0B, (x))
+
+struct adis16480_chip_info {
+ unsigned int num_channels;
+ const struct iio_chan_spec *channels;
+};
+
+struct adis16480 {
+ const struct adis16480_chip_info *chip_info;
+
+ struct adis adis;
+};
+
+#ifdef CONFIG_DEBUG_FS
+
+static ssize_t adis16480_show_firmware_revision(struct file *file,
+ char __user *userbuf, size_t count, loff_t *ppos)
+{
+ struct adis16480 *adis16480 = file->private_data;
+ char buf[7];
+ size_t len;
+ u16 rev;
+ int ret;
+
+ ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_FIRM_REV, &rev);
+ if (ret < 0)
+ return ret;
+
+ len = scnprintf(buf, sizeof(buf), "%x.%x\n", rev >> 8, rev & 0xff);
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, len);
+}
+
+static const struct file_operations adis16480_firmware_revision_fops = {
+ .open = simple_open,
+ .read = adis16480_show_firmware_revision,
+ .llseek = default_llseek,
+ .owner = THIS_MODULE,
+};
+
+static ssize_t adis16480_show_firmware_date(struct file *file,
+ char __user *userbuf, size_t count, loff_t *ppos)
+{
+ struct adis16480 *adis16480 = file->private_data;
+ u16 md, year;
+ char buf[12];
+ size_t len;
+ int ret;
+
+ ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_FIRM_Y, &year);
+ if (ret < 0)
+ return ret;
+
+ ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_FIRM_DM, &md);
+ if (ret < 0)
+ return ret;
+
+ len = snprintf(buf, sizeof(buf), "%.2x-%.2x-%.4x\n",
+ md >> 8, md & 0xff, year);
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, len);
+}
+
+static const struct file_operations adis16480_firmware_date_fops = {
+ .open = simple_open,
+ .read = adis16480_show_firmware_date,
+ .llseek = default_llseek,
+ .owner = THIS_MODULE,
+};
+
+static int adis16480_show_serial_number(void *arg, u64 *val)
+{
+ struct adis16480 *adis16480 = arg;
+ u16 serial;
+ int ret;
+
+ ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_SERIAL_NUM,
+ &serial);
+ if (ret < 0)
+ return ret;
+
+ *val = serial;
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(adis16480_serial_number_fops,
+ adis16480_show_serial_number, NULL, "0x%.4llx\n");
+
+static int adis16480_show_product_id(void *arg, u64 *val)
+{
+ struct adis16480 *adis16480 = arg;
+ u16 prod_id;
+ int ret;
+
+ ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_PROD_ID,
+ &prod_id);
+ if (ret < 0)
+ return ret;
+
+ *val = prod_id;
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(adis16480_product_id_fops,
+ adis16480_show_product_id, NULL, "%llu\n");
+
+static int adis16480_show_flash_count(void *arg, u64 *val)
+{
+ struct adis16480 *adis16480 = arg;
+ u32 flash_count;
+ int ret;
+
+ ret = adis_read_reg_32(&adis16480->adis, ADIS16480_REG_FLASH_CNT,
+ &flash_count);
+ if (ret < 0)
+ return ret;
+
+ *val = flash_count;
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(adis16480_flash_count_fops,
+ adis16480_show_flash_count, NULL, "%lld\n");
+
+static int adis16480_debugfs_init(struct iio_dev *indio_dev)
+{
+ struct adis16480 *adis16480 = iio_priv(indio_dev);
+
+ debugfs_create_file("firmware_revision", 0400,
+ indio_dev->debugfs_dentry, adis16480,
+ &adis16480_firmware_revision_fops);
+ debugfs_create_file("firmware_date", 0400, indio_dev->debugfs_dentry,
+ adis16480, &adis16480_firmware_date_fops);
+ debugfs_create_file("serial_number", 0400, indio_dev->debugfs_dentry,
+ adis16480, &adis16480_serial_number_fops);
+ debugfs_create_file("product_id", 0400, indio_dev->debugfs_dentry,
+ adis16480, &adis16480_product_id_fops);
+ debugfs_create_file("flash_count", 0400, indio_dev->debugfs_dentry,
+ adis16480, &adis16480_flash_count_fops);
+
+ return 0;
+}
+
+#else
+
+static int adis16480_debugfs_init(struct iio_dev *indio_dev)
+{
+ return 0;
+}
+
+#endif
+
+static int adis16480_set_freq(struct adis16480 *st, unsigned int freq)
+{
+ unsigned int t;
+
+ t = 2460000 / freq;
+ if (t > 2048)
+ t = 2048;
+
+ if (t != 0)
+ t--;
+
+ return adis_write_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, t);
+}
+
+static int adis16480_get_freq(struct adis16480 *st, unsigned int *freq)
+{
+ uint16_t t;
+ int ret;
+
+ ret = adis_read_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, &t);
+ if (ret < 0)
+ return ret;
+
+ *freq = 2460000 / (t + 1);
+
+ return 0;
+}
+
+static ssize_t adis16480_read_frequency(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct adis16480 *st = iio_priv(indio_dev);
+ unsigned int freq;
+ int ret;
+
+ ret = adis16480_get_freq(st, &freq);
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%d.%.3d\n", freq / 1000, freq % 1000);
+}
+
+static ssize_t adis16480_write_frequency(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct adis16480 *st = iio_priv(indio_dev);
+ int freq_int, freq_fract;
+ long val;
+ int ret;
+
+ ret = iio_str_to_fixpoint(buf, 100, &freq_int, &freq_fract);
+ if (ret)
+ return ret;
+
+ val = freq_int * 1000 + freq_fract;
+
+ if (val <= 0)
+ return -EINVAL;
+
+ ret = adis16480_set_freq(st, val);
+
+ return ret ? ret : len;
+}
+
+static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
+ adis16480_read_frequency,
+ adis16480_write_frequency);
+
+enum {
+ ADIS16480_SCAN_GYRO_X,
+ ADIS16480_SCAN_GYRO_Y,
+ ADIS16480_SCAN_GYRO_Z,
+ ADIS16480_SCAN_ACCEL_X,
+ ADIS16480_SCAN_ACCEL_Y,
+ ADIS16480_SCAN_ACCEL_Z,
+ ADIS16480_SCAN_MAGN_X,
+ ADIS16480_SCAN_MAGN_Y,
+ ADIS16480_SCAN_MAGN_Z,
+ ADIS16480_SCAN_BARO,
+ ADIS16480_SCAN_TEMP,
+};
+
+static const unsigned int adis16480_calibbias_regs[] = {
+ [ADIS16480_SCAN_GYRO_X] = ADIS16480_REG_X_GYRO_BIAS,
+ [ADIS16480_SCAN_GYRO_Y] = ADIS16480_REG_Y_GYRO_BIAS,
+ [ADIS16480_SCAN_GYRO_Z] = ADIS16480_REG_Z_GYRO_BIAS,
+ [ADIS16480_SCAN_ACCEL_X] = ADIS16480_REG_X_ACCEL_BIAS,
+ [ADIS16480_SCAN_ACCEL_Y] = ADIS16480_REG_Y_ACCEL_BIAS,
+ [ADIS16480_SCAN_ACCEL_Z] = ADIS16480_REG_Z_ACCEL_BIAS,
+ [ADIS16480_SCAN_MAGN_X] = ADIS16480_REG_X_HARD_IRON,
+ [ADIS16480_SCAN_MAGN_Y] = ADIS16480_REG_Y_HARD_IRON,
+ [ADIS16480_SCAN_MAGN_Z] = ADIS16480_REG_Z_HARD_IRON,
+ [ADIS16480_SCAN_BARO] = ADIS16480_REG_BAROM_BIAS,
+};
+
+static const unsigned int adis16480_calibscale_regs[] = {
+ [ADIS16480_SCAN_GYRO_X] = ADIS16480_REG_X_GYRO_SCALE,
+ [ADIS16480_SCAN_GYRO_Y] = ADIS16480_REG_Y_GYRO_SCALE,
+ [ADIS16480_SCAN_GYRO_Z] = ADIS16480_REG_Z_GYRO_SCALE,
+ [ADIS16480_SCAN_ACCEL_X] = ADIS16480_REG_X_ACCEL_SCALE,
+ [ADIS16480_SCAN_ACCEL_Y] = ADIS16480_REG_Y_ACCEL_SCALE,
+ [ADIS16480_SCAN_ACCEL_Z] = ADIS16480_REG_Z_ACCEL_SCALE,
+};
+
+static int adis16480_set_calibbias(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, int bias)
+{
+ unsigned int reg = adis16480_calibbias_regs[chan->scan_index];
+ struct adis16480 *st = iio_priv(indio_dev);
+
+ switch (chan->type) {
+ case IIO_MAGN:
+ case IIO_PRESSURE:
+ if (bias < -0x8000 || bias >= 0x8000)
+ return -EINVAL;
+ return adis_write_reg_16(&st->adis, reg, bias);
+ case IIO_ANGL_VEL:
+ case IIO_ACCEL:
+ return adis_write_reg_32(&st->adis, reg, bias);
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int adis16480_get_calibbias(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, int *bias)
+{
+ unsigned int reg = adis16480_calibbias_regs[chan->scan_index];
+ struct adis16480 *st = iio_priv(indio_dev);
+ uint16_t val16;
+ uint32_t val32;
+ int ret;
+
+ switch (chan->type) {
+ case IIO_MAGN:
+ case IIO_PRESSURE:
+ ret = adis_read_reg_16(&st->adis, reg, &val16);
+ *bias = sign_extend32(val16, 15);
+ break;
+ case IIO_ANGL_VEL:
+ case IIO_ACCEL:
+ ret = adis_read_reg_32(&st->adis, reg, &val32);
+ *bias = sign_extend32(val32, 31);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ if (ret < 0)
+ return ret;
+
+ return IIO_VAL_INT;
+}
+
+static int adis16480_set_calibscale(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, int scale)
+{
+ unsigned int reg = adis16480_calibscale_regs[chan->scan_index];
+ struct adis16480 *st = iio_priv(indio_dev);
+
+ if (scale < -0x8000 || scale >= 0x8000)
+ return -EINVAL;
+
+ return adis_write_reg_16(&st->adis, reg, scale);
+}
+
+static int adis16480_get_calibscale(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, int *scale)
+{
+ unsigned int reg = adis16480_calibscale_regs[chan->scan_index];
+ struct adis16480 *st = iio_priv(indio_dev);
+ uint16_t val16;
+ int ret;
+
+ ret = adis_read_reg_16(&st->adis, reg, &val16);
+ if (ret < 0)
+ return ret;
+
+ *scale = sign_extend32(val16, 15);
+ return IIO_VAL_INT;
+}
+
+static const unsigned int adis16480_def_filter_freqs[] = {
+ 310,
+ 55,
+ 275,
+ 63,
+};
+
+static const unsigned int ad16480_filter_data[][2] = {
+ [ADIS16480_SCAN_GYRO_X] = { ADIS16480_REG_FILTER_BNK0, 0 },
+ [ADIS16480_SCAN_GYRO_Y] = { ADIS16480_REG_FILTER_BNK0, 3 },
+ [ADIS16480_SCAN_GYRO_Z] = { ADIS16480_REG_FILTER_BNK0, 6 },
+ [ADIS16480_SCAN_ACCEL_X] = { ADIS16480_REG_FILTER_BNK0, 9 },
+ [ADIS16480_SCAN_ACCEL_Y] = { ADIS16480_REG_FILTER_BNK0, 12 },
+ [ADIS16480_SCAN_ACCEL_Z] = { ADIS16480_REG_FILTER_BNK1, 0 },
+ [ADIS16480_SCAN_MAGN_X] = { ADIS16480_REG_FILTER_BNK1, 3 },
+ [ADIS16480_SCAN_MAGN_Y] = { ADIS16480_REG_FILTER_BNK1, 6 },
+ [ADIS16480_SCAN_MAGN_Z] = { ADIS16480_REG_FILTER_BNK1, 9 },
+};
+
+static int adis16480_get_filter_freq(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, int *freq)
+{
+ struct adis16480 *st = iio_priv(indio_dev);
+ unsigned int enable_mask, offset, reg;
+ uint16_t val;
+ int ret;
+
+ reg = ad16480_filter_data[chan->scan_index][0];
+ offset = ad16480_filter_data[chan->scan_index][1];
+ enable_mask = BIT(offset + 2);
+
+ ret = adis_read_reg_16(&st->adis, reg, &val);
+ if (ret < 0)
+ return ret;
+
+ if (!(val & enable_mask))
+ *freq = 0;
+ else
+ *freq = adis16480_def_filter_freqs[(val >> offset) & 0x3];
+
+ return IIO_VAL_INT;
+}
+
+static int adis16480_set_filter_freq(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, unsigned int freq)
+{
+ struct adis16480 *st = iio_priv(indio_dev);
+ unsigned int enable_mask, offset, reg;
+ unsigned int diff, best_diff;
+ unsigned int i, best_freq;
+ uint16_t val;
+ int ret;
+
+ reg = ad16480_filter_data[chan->scan_index][0];
+ offset = ad16480_filter_data[chan->scan_index][1];
+ enable_mask = BIT(offset + 2);
+
+ ret = adis_read_reg_16(&st->adis, reg, &val);
+ if (ret < 0)
+ return ret;
+
+ if (freq == 0) {
+ val &= ~enable_mask;
+ } else {
+ best_freq = 0;
+ best_diff = 310;
+ for (i = 0; i < ARRAY_SIZE(adis16480_def_filter_freqs); i++) {
+ if (adis16480_def_filter_freqs[i] >= freq) {
+ diff = adis16480_def_filter_freqs[i] - freq;
+ if (diff < best_diff) {
+ best_diff = diff;
+ best_freq = i;
+ }
+ }
+ }
+
+ val &= ~(0x3 << offset);
+ val |= best_freq << offset;
+ val |= enable_mask;
+ }
+
+ return adis_write_reg_16(&st->adis, reg, val);
+}
+
+static int adis16480_read_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, int *val, int *val2, long info)
+{
+ switch (info) {
+ case IIO_CHAN_INFO_RAW:
+ return adis_single_conversion(indio_dev, chan, 0, val);
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->type) {
+ case IIO_ANGL_VEL:
+ *val = 0;
+ *val2 = IIO_DEGREE_TO_RAD(20000); /* 0.02 degree/sec */
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_ACCEL:
+ *val = 0;
+ *val2 = IIO_G_TO_M_S_2(800); /* 0.8 mg */
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_MAGN:
+ *val = 0;
+ *val2 = 100; /* 0.0001 gauss */
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_TEMP:
+ *val = 5;
+ *val2 = 650000; /* 5.65 milli degree Celsius */
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_PRESSURE:
+ *val = 0;
+ *val2 = 4000; /* 40ubar = 0.004 kPa */
+ return IIO_VAL_INT_PLUS_MICRO;
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_OFFSET:
+ /* Only the temperature channel has a offset */
+ *val = 4425; /* 25 degree Celsius = 0x0000 */
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_CALIBBIAS:
+ return adis16480_get_calibbias(indio_dev, chan, val);
+ case IIO_CHAN_INFO_CALIBSCALE:
+ return adis16480_get_calibscale(indio_dev, chan, val);
+ case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+ return adis16480_get_filter_freq(indio_dev, chan, val);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int adis16480_write_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, int val, int val2, long info)
+{
+ switch (info) {
+ case IIO_CHAN_INFO_CALIBBIAS:
+ return adis16480_set_calibbias(indio_dev, chan, val);
+ case IIO_CHAN_INFO_CALIBSCALE:
+ return adis16480_set_calibscale(indio_dev, chan, val);
+ case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+ return adis16480_set_filter_freq(indio_dev, chan, val);
+ default:
+ return -EINVAL;
+ }
+}
+
+#define ADIS16480_MOD_CHANNEL(_type, _mod, _address, _si, _info, _bits) \
+ { \
+ .type = (_type), \
+ .modified = 1, \
+ .channel2 = (_mod), \
+ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \
+ IIO_CHAN_INFO_SCALE_SHARED_BIT | \
+ _info, \
+ .address = (_address), \
+ .scan_index = (_si), \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = (_bits), \
+ .storagebits = (_bits), \
+ .endianness = IIO_BE, \
+ }, \
+ }
+
+#define ADIS16480_GYRO_CHANNEL(_mod) \
+ ADIS16480_MOD_CHANNEL(IIO_ANGL_VEL, IIO_MOD_ ## _mod, \
+ ADIS16480_REG_ ## _mod ## _GYRO_OUT, ADIS16480_SCAN_GYRO_ ## _mod, \
+ IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT | \
+ IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, \
+ 32)
+
+#define ADIS16480_ACCEL_CHANNEL(_mod) \
+ ADIS16480_MOD_CHANNEL(IIO_ACCEL, IIO_MOD_ ## _mod, \
+ ADIS16480_REG_ ## _mod ## _ACCEL_OUT, ADIS16480_SCAN_ACCEL_ ## _mod, \
+ IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT | \
+ IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, \
+ 32)
+
+#define ADIS16480_MAGN_CHANNEL(_mod) \
+ ADIS16480_MOD_CHANNEL(IIO_MAGN, IIO_MOD_ ## _mod, \
+ ADIS16480_REG_ ## _mod ## _MAGN_OUT, ADIS16480_SCAN_MAGN_ ## _mod, \
+ IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT, \
+ 16)
+
+#define ADIS16480_PRESSURE_CHANNEL() \
+ { \
+ .type = IIO_PRESSURE, \
+ .indexed = 1, \
+ .channel = 0, \
+ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \
+ IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
+ .address = ADIS16480_REG_BAROM_OUT, \
+ .scan_index = ADIS16480_SCAN_BARO, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 32, \
+ .storagebits = 32, \
+ .endianness = IIO_BE, \
+ }, \
+ }
+
+#define ADIS16480_TEMP_CHANNEL() { \
+ .type = IIO_TEMP, \
+ .indexed = 1, \
+ .channel = 0, \
+ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+ IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \
+ IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \
+ .address = ADIS16480_REG_TEMP_OUT, \
+ .scan_index = ADIS16480_SCAN_TEMP, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 16, \
+ .storagebits = 16, \
+ .endianness = IIO_BE, \
+ }, \
+ }
+
+static const struct iio_chan_spec adis16480_channels[] = {
+ ADIS16480_GYRO_CHANNEL(X),
+ ADIS16480_GYRO_CHANNEL(Y),
+ ADIS16480_GYRO_CHANNEL(Z),
+ ADIS16480_ACCEL_CHANNEL(X),
+ ADIS16480_ACCEL_CHANNEL(Y),
+ ADIS16480_ACCEL_CHANNEL(Z),
+ ADIS16480_MAGN_CHANNEL(X),
+ ADIS16480_MAGN_CHANNEL(Y),
+ ADIS16480_MAGN_CHANNEL(Z),
+ ADIS16480_PRESSURE_CHANNEL(),
+ ADIS16480_TEMP_CHANNEL(),
+ IIO_CHAN_SOFT_TIMESTAMP(11)
+};
+
+static const struct iio_chan_spec adis16485_channels[] = {
+ ADIS16480_GYRO_CHANNEL(X),
+ ADIS16480_GYRO_CHANNEL(Y),
+ ADIS16480_GYRO_CHANNEL(Z),
+ ADIS16480_ACCEL_CHANNEL(X),
+ ADIS16480_ACCEL_CHANNEL(Y),
+ ADIS16480_ACCEL_CHANNEL(Z),
+ ADIS16480_TEMP_CHANNEL(),
+ IIO_CHAN_SOFT_TIMESTAMP(7)
+};
+
+enum adis16480_variant {
+ ADIS16375,
+ ADIS16480,
+ ADIS16485,
+ ADIS16488,
+};
+
+static const struct adis16480_chip_info adis16480_chip_info[] = {
+ [ADIS16375] = {
+ .channels = adis16485_channels,
+ .num_channels = ARRAY_SIZE(adis16485_channels),
+ },
+ [ADIS16480] = {
+ .channels = adis16480_channels,
+ .num_channels = ARRAY_SIZE(adis16480_channels),
+ },
+ [ADIS16485] = {
+ .channels = adis16485_channels,
+ .num_channels = ARRAY_SIZE(adis16485_channels),
+ },
+ [ADIS16488] = {
+ .channels = adis16480_channels,
+ .num_channels = ARRAY_SIZE(adis16480_channels),
+ },
+};
+
+static struct attribute *adis16480_attributes[] = {
+ &iio_dev_attr_sampling_frequency.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group adis16480_attribute_group = {
+ .attrs = adis16480_attributes,
+};
+
+static const struct iio_info adis16480_info = {
+ .attrs = &adis16480_attribute_group,
+ .read_raw = &adis16480_read_raw,
+ .write_raw = &adis16480_write_raw,
+ .update_scan_mode = adis_update_scan_mode,
+ .driver_module = THIS_MODULE,
+};
+
+static int adis16480_stop_device(struct iio_dev *indio_dev)
+{
+ struct adis16480 *st = iio_priv(indio_dev);
+ int ret;
+
+ ret = adis_write_reg_16(&st->adis, ADIS16480_REG_SLP_CNT, BIT(9));
+ if (ret)
+ dev_err(&indio_dev->dev,
+ "Could not power down device: %d\n", ret);
+
+ return ret;
+}
+
+static int adis16480_enable_irq(struct adis *adis, bool enable)
+{
+ return adis_write_reg_16(adis, ADIS16480_REG_FNCTIO_CTRL,
+ enable ? BIT(3) : 0);
+}
+
+static int adis16480_initial_setup(struct iio_dev *indio_dev)
+{
+ struct adis16480 *st = iio_priv(indio_dev);
+ uint16_t prod_id;
+ unsigned int device_id;
+ int ret;
+
+ adis_reset(&st->adis);
+ msleep(70);
+
+ ret = adis_write_reg_16(&st->adis, ADIS16480_REG_GLOB_CMD, BIT(1));
+ if (ret)
+ return ret;
+ msleep(30);
+
+ ret = adis_check_status(&st->adis);
+ if (ret)
+ return ret;
+
+ ret = adis_read_reg_16(&st->adis, ADIS16480_REG_PROD_ID, &prod_id);
+ if (ret)
+ return ret;
+
+ sscanf(indio_dev->name, "adis%u\n", &device_id);
+
+ if (prod_id != device_id)
+ dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.",
+ device_id, prod_id);
+
+ return 0;
+}
+
+#define ADIS16480_DIAG_STAT_XGYRO_FAIL 0
+#define ADIS16480_DIAG_STAT_YGYRO_FAIL 1
+#define ADIS16480_DIAG_STAT_ZGYRO_FAIL 2
+#define ADIS16480_DIAG_STAT_XACCL_FAIL 3
+#define ADIS16480_DIAG_STAT_YACCL_FAIL 4
+#define ADIS16480_DIAG_STAT_ZACCL_FAIL 5
+#define ADIS16480_DIAG_STAT_XMAGN_FAIL 8
+#define ADIS16480_DIAG_STAT_YMAGN_FAIL 9
+#define ADIS16480_DIAG_STAT_ZMAGN_FAIL 10
+#define ADIS16480_DIAG_STAT_BARO_FAIL 11
+
+static const char * const adis16480_status_error_msgs[] = {
+ [ADIS16480_DIAG_STAT_XGYRO_FAIL] = "X-axis gyroscope self-test failure",
+ [ADIS16480_DIAG_STAT_YGYRO_FAIL] = "Y-axis gyroscope self-test failure",
+ [ADIS16480_DIAG_STAT_ZGYRO_FAIL] = "Z-axis gyroscope self-test failure",
+ [ADIS16480_DIAG_STAT_XACCL_FAIL] = "X-axis accelerometer self-test failure",
+ [ADIS16480_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure",
+ [ADIS16480_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure",
+ [ADIS16480_DIAG_STAT_XMAGN_FAIL] = "X-axis magnetometer self-test failure",
+ [ADIS16480_DIAG_STAT_YMAGN_FAIL] = "Y-axis magnetometer self-test failure",
+ [ADIS16480_DIAG_STAT_ZMAGN_FAIL] = "Z-axis magnetometer self-test failure",
+ [ADIS16480_DIAG_STAT_BARO_FAIL] = "Barometer self-test failure",
+};
+
+static const struct adis_data adis16480_data = {
+ .diag_stat_reg = ADIS16480_REG_DIAG_STS,
+ .glob_cmd_reg = ADIS16480_REG_GLOB_CMD,
+ .has_paging = true,
+
+ .read_delay = 5,
+ .write_delay = 5,
+
+ .status_error_msgs = adis16480_status_error_msgs,
+ .status_error_mask = BIT(ADIS16480_DIAG_STAT_XGYRO_FAIL) |
+ BIT(ADIS16480_DIAG_STAT_YGYRO_FAIL) |
+ BIT(ADIS16480_DIAG_STAT_ZGYRO_FAIL) |
+ BIT(ADIS16480_DIAG_STAT_XACCL_FAIL) |
+ BIT(ADIS16480_DIAG_STAT_YACCL_FAIL) |
+ BIT(ADIS16480_DIAG_STAT_ZACCL_FAIL) |
+ BIT(ADIS16480_DIAG_STAT_XMAGN_FAIL) |
+ BIT(ADIS16480_DIAG_STAT_YMAGN_FAIL) |
+ BIT(ADIS16480_DIAG_STAT_ZMAGN_FAIL) |
+ BIT(ADIS16480_DIAG_STAT_BARO_FAIL),
+
+ .enable_irq = adis16480_enable_irq,
+};
+
+static int adis16480_probe(struct spi_device *spi)
+{
+ const struct spi_device_id *id = spi_get_device_id(spi);
+ struct iio_dev *indio_dev;
+ struct adis16480 *st;
+ int ret;
+
+ indio_dev = iio_device_alloc(sizeof(*st));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ spi_set_drvdata(spi, indio_dev);
+
+ st = iio_priv(indio_dev);
+
+ st->chip_info = &adis16480_chip_info[id->driver_data];
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->name = spi_get_device_id(spi)->name;
+ indio_dev->channels = st->chip_info->channels;
+ indio_dev->num_channels = st->chip_info->num_channels;
+ indio_dev->info = &adis16480_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ ret = adis_init(&st->adis, indio_dev, spi, &adis16480_data);
+ if (ret)
+ goto error_free_dev;
+
+ ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
+ if (ret)
+ goto error_free_dev;
+
+ ret = adis16480_initial_setup(indio_dev);
+ if (ret)
+ goto error_cleanup_buffer;
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto error_stop_device;
+
+ adis16480_debugfs_init(indio_dev);
+
+ return 0;
+
+error_stop_device:
+ adis16480_stop_device(indio_dev);
+error_cleanup_buffer:
+ adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
+error_free_dev:
+ iio_device_free(indio_dev);
+ return ret;
+}
+
+static int adis16480_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct adis16480 *st = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ adis16480_stop_device(indio_dev);
+
+ adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
+
+ iio_device_free(indio_dev);
+
+ return 0;
+}
+
+static const struct spi_device_id adis16480_ids[] = {
+ { "adis16375", ADIS16375 },
+ { "adis16480", ADIS16480 },
+ { "adis16485", ADIS16485 },
+ { "adis16488", ADIS16488 },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, adis16480_ids);
+
+static struct spi_driver adis16480_driver = {
+ .driver = {
+ .name = "adis16480",
+ .owner = THIS_MODULE,
+ },
+ .id_table = adis16480_ids,
+ .probe = adis16480_probe,
+ .remove = adis16480_remove,
+};
+module_spi_driver(adis16480_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Analog Devices ADIS16480 IMU driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c
new file mode 100644
index 00000000000..99d8e0b0dd3
--- /dev/null
+++ b/drivers/iio/imu/adis_buffer.c
@@ -0,0 +1,176 @@
+/*
+ * Common library for ADIS16XXX devices
+ *
+ * Copyright 2012 Analog Devices Inc.
+ * Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/export.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/imu/adis.h>
+
+int adis_update_scan_mode(struct iio_dev *indio_dev,
+ const unsigned long *scan_mask)
+{
+ struct adis *adis = iio_device_get_drvdata(indio_dev);
+ const struct iio_chan_spec *chan;
+ unsigned int scan_count;
+ unsigned int i, j;
+ __be16 *tx, *rx;
+
+ kfree(adis->xfer);
+ kfree(adis->buffer);
+
+ scan_count = indio_dev->scan_bytes / 2;
+
+ adis->xfer = kcalloc(scan_count + 1, sizeof(*adis->xfer), GFP_KERNEL);
+ if (!adis->xfer)
+ return -ENOMEM;
+
+ adis->buffer = kzalloc(indio_dev->scan_bytes * 2, GFP_KERNEL);
+ if (!adis->buffer)
+ return -ENOMEM;
+
+ rx = adis->buffer;
+ tx = rx + indio_dev->scan_bytes;
+
+ spi_message_init(&adis->msg);
+
+ for (j = 0; j <= scan_count; j++) {
+ adis->xfer[j].bits_per_word = 8;
+ if (j != scan_count)
+ adis->xfer[j].cs_change = 1;
+ adis->xfer[j].len = 2;
+ adis->xfer[j].delay_usecs = adis->data->read_delay;
+ if (j < scan_count)
+ adis->xfer[j].tx_buf = &tx[j];
+ if (j >= 1)
+ adis->xfer[j].rx_buf = &rx[j - 1];
+ spi_message_add_tail(&adis->xfer[j], &adis->msg);
+ }
+
+ chan = indio_dev->channels;
+ for (i = 0; i < indio_dev->num_channels; i++, chan++) {
+ if (!test_bit(chan->scan_index, scan_mask))
+ continue;
+ if (chan->scan_type.storagebits == 32)
+ *tx++ = cpu_to_be16((chan->address + 2) << 8);
+ *tx++ = cpu_to_be16(chan->address << 8);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(adis_update_scan_mode);
+
+static irqreturn_t adis_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct adis *adis = iio_device_get_drvdata(indio_dev);
+ int ret;
+
+ if (!adis->buffer)
+ return -ENOMEM;
+
+ if (adis->data->has_paging) {
+ mutex_lock(&adis->txrx_lock);
+ if (adis->current_page != 0) {
+ adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
+ adis->tx[1] = 0;
+ spi_write(adis->spi, adis->tx, 2);
+ }
+ }
+
+ ret = spi_sync(adis->spi, &adis->msg);
+ if (ret)
+ dev_err(&adis->spi->dev, "Failed to read data: %d", ret);
+
+
+ if (adis->data->has_paging) {
+ adis->current_page = 0;
+ 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_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device
+ * @adis: The adis device.
+ * @indio_dev: The IIO device.
+ * @trigger_handler: Optional trigger handler, may be NULL.
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ *
+ * This function sets up the buffer and trigger for a adis devices. If
+ * 'trigger_handler' is NULL the default trigger handler will be used. The
+ * default trigger handler will simply read the registers assigned to the
+ * currently active channels.
+ *
+ * adis_cleanup_buffer_and_trigger() should be called to free the resources
+ * allocated by this function.
+ */
+int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
+ irqreturn_t (*trigger_handler)(int, void *))
+{
+ int ret;
+
+ if (!trigger_handler)
+ trigger_handler = adis_trigger_handler;
+
+ ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+ trigger_handler, NULL);
+ if (ret)
+ return ret;
+
+ if (adis->spi->irq) {
+ ret = adis_probe_trigger(adis, indio_dev);
+ if (ret)
+ goto error_buffer_cleanup;
+ }
+ return 0;
+
+error_buffer_cleanup:
+ iio_triggered_buffer_cleanup(indio_dev);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger);
+
+/**
+ * adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources
+ * @adis: The adis device.
+ * @indio_dev: The IIO device.
+ *
+ * Frees resources allocated by adis_setup_buffer_and_trigger()
+ */
+void adis_cleanup_buffer_and_trigger(struct adis *adis,
+ struct iio_dev *indio_dev)
+{
+ if (adis->spi->irq)
+ adis_remove_trigger(adis);
+ kfree(adis->buffer);
+ kfree(adis->xfer);
+ iio_triggered_buffer_cleanup(indio_dev);
+}
+EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger);
diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c
new file mode 100644
index 00000000000..5a24c9cac34
--- /dev/null
+++ b/drivers/iio/imu/adis_trigger.c
@@ -0,0 +1,89 @@
+/*
+ * Common library for ADIS16XXX devices
+ *
+ * Copyright 2012 Analog Devices Inc.
+ * Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/export.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/imu/adis.h>
+
+static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig,
+ bool state)
+{
+ struct adis *adis = trig->private_data;
+
+ return adis_enable_irq(adis, state);
+}
+
+static const struct iio_trigger_ops adis_trigger_ops = {
+ .owner = THIS_MODULE,
+ .set_trigger_state = &adis_data_rdy_trigger_set_state,
+};
+
+/**
+ * adis_probe_trigger() - Sets up trigger for a adis device
+ * @adis: The adis device
+ * @indio_dev: The IIO device
+ *
+ * Returns 0 on success or a negative error code
+ *
+ * adis_remove_trigger() should be used to free the trigger.
+ */
+int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
+{
+ int ret;
+
+ adis->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
+ indio_dev->id);
+ if (adis->trig == NULL)
+ return -ENOMEM;
+
+ ret = request_irq(adis->spi->irq,
+ &iio_trigger_generic_data_rdy_poll,
+ IRQF_TRIGGER_RISING,
+ indio_dev->name,
+ adis->trig);
+ if (ret)
+ goto error_free_trig;
+
+ adis->trig->dev.parent = &adis->spi->dev;
+ adis->trig->ops = &adis_trigger_ops;
+ adis->trig->private_data = adis;
+ ret = iio_trigger_register(adis->trig);
+
+ indio_dev->trig = adis->trig;
+ if (ret)
+ goto error_free_irq;
+
+ return 0;
+
+error_free_irq:
+ free_irq(adis->spi->irq, adis->trig);
+error_free_trig:
+ iio_trigger_free(adis->trig);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(adis_probe_trigger);
+
+/**
+ * adis_remove_trigger() - Remove trigger for a adis devices
+ * @adis: The adis device
+ *
+ * Removes the trigger previously registered with adis_probe_trigger().
+ */
+void adis_remove_trigger(struct adis *adis)
+{
+ iio_trigger_unregister(adis->trig);
+ free_irq(adis->spi->irq, adis->trig);
+ iio_trigger_free(adis->trig);
+}
+EXPORT_SYMBOL_GPL(adis_remove_trigger);
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index d4ad37455a6..aaadd32f9f0 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -31,6 +31,18 @@ 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)
+{
+ struct list_head *p;
+
+ list_for_each(p, &indio_dev->buffer_list)
+ if (p == &buf->buffer_list)
+ return true;
+
+ return false;
+}
+
/**
* iio_buffer_read_first_n_outer() - chrdev read for buffer access
*
@@ -134,7 +146,7 @@ static ssize_t iio_scan_el_store(struct device *dev,
if (ret < 0)
return ret;
mutex_lock(&indio_dev->mlock);
- if (iio_buffer_enabled(indio_dev)) {
+ if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
ret = -EBUSY;
goto error_ret;
}
@@ -180,12 +192,11 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
return ret;
mutex_lock(&indio_dev->mlock);
- if (iio_buffer_enabled(indio_dev)) {
+ if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
ret = -EBUSY;
goto error_ret;
}
indio_dev->buffer->scan_timestamp = state;
- indio_dev->scan_timestamp = state;
error_ret:
mutex_unlock(&indio_dev->mlock);
@@ -371,12 +382,12 @@ ssize_t iio_buffer_write_length(struct device *dev,
const char *buf,
size_t len)
{
- int ret;
- ulong val;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct iio_buffer *buffer = indio_dev->buffer;
+ unsigned int val;
+ int ret;
- ret = strict_strtoul(buf, 10, &val);
+ ret = kstrtouint(buf, 10, &val);
if (ret)
return ret;
@@ -385,7 +396,7 @@ ssize_t iio_buffer_write_length(struct device *dev,
return len;
mutex_lock(&indio_dev->mlock);
- if (iio_buffer_enabled(indio_dev)) {
+ if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
ret = -EBUSY;
} else {
if (buffer->access->set_length)
@@ -398,102 +409,14 @@ ssize_t iio_buffer_write_length(struct device *dev,
}
EXPORT_SYMBOL(iio_buffer_write_length);
-ssize_t iio_buffer_store_enable(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- int ret;
- bool requested_state, current_state;
- int previous_mode;
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct iio_buffer *buffer = indio_dev->buffer;
-
- mutex_lock(&indio_dev->mlock);
- previous_mode = indio_dev->currentmode;
- requested_state = !(buf[0] == '0');
- current_state = iio_buffer_enabled(indio_dev);
- if (current_state == requested_state) {
- printk(KERN_INFO "iio-buffer, current state requested again\n");
- goto done;
- }
- if (requested_state) {
- if (indio_dev->setup_ops->preenable) {
- ret = indio_dev->setup_ops->preenable(indio_dev);
- if (ret) {
- printk(KERN_ERR
- "Buffer not started: "
- "buffer preenable failed\n");
- goto error_ret;
- }
- }
- if (buffer->access->request_update) {
- ret = buffer->access->request_update(buffer);
- if (ret) {
- printk(KERN_INFO
- "Buffer not started: "
- "buffer parameter update failed\n");
- goto error_ret;
- }
- }
- /* 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");
- ret = -EINVAL;
- goto error_ret;
- }
- 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 */
- ret = -EINVAL;
- goto error_ret;
- }
-
- if (indio_dev->setup_ops->postenable) {
- ret = indio_dev->setup_ops->postenable(indio_dev);
- if (ret) {
- printk(KERN_INFO
- "Buffer not started: "
- "postenable failed\n");
- indio_dev->currentmode = previous_mode;
- if (indio_dev->setup_ops->postdisable)
- indio_dev->setup_ops->
- postdisable(indio_dev);
- goto error_ret;
- }
- }
- } else {
- if (indio_dev->setup_ops->predisable) {
- ret = indio_dev->setup_ops->predisable(indio_dev);
- if (ret)
- goto error_ret;
- }
- indio_dev->currentmode = INDIO_DIRECT_MODE;
- if (indio_dev->setup_ops->postdisable) {
- ret = indio_dev->setup_ops->postdisable(indio_dev);
- if (ret)
- goto error_ret;
- }
- }
-done:
- mutex_unlock(&indio_dev->mlock);
- return len;
-
-error_ret:
- mutex_unlock(&indio_dev->mlock);
- return ret;
-}
-EXPORT_SYMBOL(iio_buffer_store_enable);
-
ssize_t iio_buffer_show_enable(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- return sprintf(buf, "%d\n", iio_buffer_enabled(indio_dev));
+ return sprintf(buf, "%d\n",
+ iio_buffer_is_active(indio_dev,
+ indio_dev->buffer));
}
EXPORT_SYMBOL(iio_buffer_show_enable);
@@ -537,35 +460,220 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask,
return bytes;
}
-int iio_sw_buffer_preenable(struct iio_dev *indio_dev)
+int iio_update_buffers(struct iio_dev *indio_dev,
+ struct iio_buffer *insert_buffer,
+ struct iio_buffer *remove_buffer)
{
- struct iio_buffer *buffer = indio_dev->buffer;
- dev_dbg(&indio_dev->dev, "%s\n", __func__);
+ int ret;
+ int success = 0;
+ struct iio_buffer *buffer;
+ unsigned long *compound_mask;
+ const unsigned long *old_mask;
- /* How much space will the demuxed element take? */
- indio_dev->scan_bytes =
- iio_compute_scan_bytes(indio_dev, buffer->scan_mask,
- buffer->scan_timestamp);
- buffer->access->set_bytes_per_datum(buffer, indio_dev->scan_bytes);
+ /* Wind down existing buffers - iff there are any */
+ if (!list_empty(&indio_dev->buffer_list)) {
+ if (indio_dev->setup_ops->predisable) {
+ ret = indio_dev->setup_ops->predisable(indio_dev);
+ if (ret)
+ goto error_ret;
+ }
+ indio_dev->currentmode = INDIO_DIRECT_MODE;
+ if (indio_dev->setup_ops->postdisable) {
+ ret = indio_dev->setup_ops->postdisable(indio_dev);
+ if (ret)
+ goto error_ret;
+ }
+ }
+ /* Keep a copy of current setup to allow roll back */
+ old_mask = indio_dev->active_scan_mask;
+ if (!indio_dev->available_scan_masks)
+ indio_dev->active_scan_mask = NULL;
+
+ if (remove_buffer)
+ list_del(&remove_buffer->buffer_list);
+ if (insert_buffer)
+ list_add(&insert_buffer->buffer_list, &indio_dev->buffer_list);
+
+ /* If no buffers in list, we are done */
+ if (list_empty(&indio_dev->buffer_list)) {
+ indio_dev->currentmode = INDIO_DIRECT_MODE;
+ if (indio_dev->available_scan_masks == NULL)
+ kfree(old_mask);
+ return 0;
+ }
/* What scan mask do we actually have ?*/
- if (indio_dev->available_scan_masks)
+ compound_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength),
+ sizeof(long), GFP_KERNEL);
+ if (compound_mask == NULL) {
+ if (indio_dev->available_scan_masks == NULL)
+ kfree(old_mask);
+ return -ENOMEM;
+ }
+ indio_dev->scan_timestamp = 0;
+
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ bitmap_or(compound_mask, compound_mask, buffer->scan_mask,
+ indio_dev->masklength);
+ indio_dev->scan_timestamp |= buffer->scan_timestamp;
+ }
+ if (indio_dev->available_scan_masks) {
indio_dev->active_scan_mask =
iio_scan_mask_match(indio_dev->available_scan_masks,
indio_dev->masklength,
- buffer->scan_mask);
- else
- indio_dev->active_scan_mask = buffer->scan_mask;
-
- if (indio_dev->active_scan_mask == NULL)
- return -EINVAL;
+ compound_mask);
+ if (indio_dev->active_scan_mask == NULL) {
+ /*
+ * Roll back.
+ * Note can only occur when adding a buffer.
+ */
+ list_del(&insert_buffer->buffer_list);
+ indio_dev->active_scan_mask = old_mask;
+ success = -EINVAL;
+ }
+ } else {
+ indio_dev->active_scan_mask = compound_mask;
+ }
iio_update_demux(indio_dev);
- if (indio_dev->info->update_scan_mode)
- return indio_dev->info
+ /* Wind up again */
+ if (indio_dev->setup_ops->preenable) {
+ ret = indio_dev->setup_ops->preenable(indio_dev);
+ if (ret) {
+ printk(KERN_ERR
+ "Buffer not started:"
+ "buffer preenable failed\n");
+ goto error_remove_inserted;
+ }
+ }
+ indio_dev->scan_bytes =
+ 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)
+ if (buffer->access->request_update) {
+ ret = buffer->access->request_update(buffer);
+ if (ret) {
+ printk(KERN_INFO
+ "Buffer not started:"
+ "buffer parameter update failed\n");
+ goto error_run_postdisable;
+ }
+ }
+ if (indio_dev->info->update_scan_mode) {
+ ret = indio_dev->info
->update_scan_mode(indio_dev,
indio_dev->active_scan_mask);
+ if (ret < 0) {
+ printk(KERN_INFO "update scan mode failed\n");
+ goto error_run_postdisable;
+ }
+ }
+ /* 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");
+ ret = -EINVAL;
+ /* Can only occur on first buffer */
+ goto error_run_postdisable;
+ }
+ 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 */
+ ret = -EINVAL;
+ goto error_run_postdisable;
+ }
+
+ if (indio_dev->setup_ops->postenable) {
+ ret = indio_dev->setup_ops->postenable(indio_dev);
+ if (ret) {
+ printk(KERN_INFO
+ "Buffer not started: postenable failed\n");
+ indio_dev->currentmode = INDIO_DIRECT_MODE;
+ if (indio_dev->setup_ops->postdisable)
+ indio_dev->setup_ops->postdisable(indio_dev);
+ goto error_disable_all_buffers;
+ }
+ }
+
+ if (indio_dev->available_scan_masks)
+ kfree(compound_mask);
+ else
+ kfree(old_mask);
+
+ return success;
+
+error_disable_all_buffers:
+ indio_dev->currentmode = INDIO_DIRECT_MODE;
+error_run_postdisable:
+ if (indio_dev->setup_ops->postdisable)
+ indio_dev->setup_ops->postdisable(indio_dev);
+error_remove_inserted:
+
+ if (insert_buffer)
+ list_del(&insert_buffer->buffer_list);
+ indio_dev->active_scan_mask = old_mask;
+ kfree(compound_mask);
+error_ret:
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(iio_update_buffers);
+
+ssize_t iio_buffer_store_enable(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
+{
+ 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);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&indio_dev->mlock);
+
+ /* Find out if it is in the list */
+ inlist = iio_buffer_is_active(indio_dev, pbuf);
+ /* Already in desired state */
+ if (inlist == requested_state)
+ goto done;
+
+ if (requested_state)
+ ret = iio_update_buffers(indio_dev,
+ indio_dev->buffer, NULL);
+ else
+ ret = iio_update_buffers(indio_dev,
+ NULL, indio_dev->buffer);
+
+ if (ret < 0)
+ goto done;
+done:
+ mutex_unlock(&indio_dev->mlock);
+ return (ret < 0) ? ret : len;
+}
+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);
@@ -599,7 +707,11 @@ static bool iio_validate_scan_mask(struct iio_dev *indio_dev,
* iio_scan_mask_set() - set particular bit in the scan mask
* @buffer: the buffer whose scan mask we are interested in
* @bit: the bit to be set.
- **/
+ *
+ * Note that at this point we have no way of knowing what other
+ * buffers might request, hence this code only verifies that the
+ * individual buffers request is plausible.
+ */
int iio_scan_mask_set(struct iio_dev *indio_dev,
struct iio_buffer *buffer, int bit)
{
@@ -682,13 +794,12 @@ static unsigned char *iio_demux(struct iio_buffer *buffer,
return buffer->demux_bounce;
}
-int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data)
+static int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data)
{
unsigned char *dataout = iio_demux(buffer, data);
return buffer->access->store_to(buffer, dataout);
}
-EXPORT_SYMBOL_GPL(iio_push_to_buffer);
static void iio_buffer_demux_free(struct iio_buffer *buffer)
{
@@ -699,10 +810,26 @@ static void iio_buffer_demux_free(struct iio_buffer *buffer)
}
}
-int iio_update_demux(struct iio_dev *indio_dev)
+
+int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data)
+{
+ int ret;
+ struct iio_buffer *buf;
+
+ list_for_each_entry(buf, &indio_dev->buffer_list, buffer_list) {
+ ret = iio_push_to_buffer(buf, data);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(iio_push_to_buffers);
+
+static int iio_buffer_update_demux(struct iio_dev *indio_dev,
+ struct iio_buffer *buffer)
{
const struct iio_chan_spec *ch;
- struct iio_buffer *buffer = indio_dev->buffer;
int ret, in_ind = -1, out_ind, length;
unsigned in_loc = 0, out_loc = 0;
struct iio_demux_table *p;
@@ -787,4 +914,23 @@ error_clear_mux_table:
return ret;
}
+
+int iio_update_demux(struct iio_dev *indio_dev)
+{
+ struct iio_buffer *buffer;
+ int ret;
+
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ ret = iio_buffer_update_demux(indio_dev, buffer);
+ if (ret < 0)
+ goto error_clear_mux_table;
+ }
+ return 0;
+
+error_clear_mux_table:
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list)
+ iio_buffer_demux_free(buffer);
+
+ return ret;
+}
EXPORT_SYMBOL_GPL(iio_update_demux);
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 6eb24dbc081..8848f16c547 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -65,6 +65,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_CAPACITANCE] = "capacitance",
[IIO_ALTVOLTAGE] = "altvoltage",
[IIO_CCT] = "cct",
+ [IIO_PRESSURE] = "pressure",
};
static const char * const iio_modifier_names[] = {
@@ -397,11 +398,74 @@ static ssize_t iio_read_channel_info(struct device *dev,
val2 = do_div(tmp, 1000000000LL);
val = tmp;
return sprintf(buf, "%d.%09u\n", val, val2);
+ case IIO_VAL_FRACTIONAL_LOG2:
+ tmp = (s64)val * 1000000000LL >> val2;
+ val2 = do_div(tmp, 1000000000LL);
+ val = tmp;
+ return sprintf(buf, "%d.%09u\n", val, val2);
default:
return 0;
}
}
+/**
+ * iio_str_to_fixpoint() - Parse a fixed-point number from a string
+ * @str: The string to parse
+ * @fract_mult: Multiplier for the first decimal place, should be a power of 10
+ * @integer: The integer part of the number
+ * @fract: The fractional part of the number
+ *
+ * Returns 0 on success, or a negative error code if the string could not be
+ * parsed.
+ */
+int iio_str_to_fixpoint(const char *str, int fract_mult,
+ int *integer, int *fract)
+{
+ int i = 0, f = 0;
+ bool integer_part = true, negative = false;
+
+ if (str[0] == '-') {
+ negative = true;
+ str++;
+ } else if (str[0] == '+') {
+ str++;
+ }
+
+ while (*str) {
+ if ('0' <= *str && *str <= '9') {
+ if (integer_part) {
+ i = i * 10 + *str - '0';
+ } else {
+ f += fract_mult * (*str - '0');
+ fract_mult /= 10;
+ }
+ } else if (*str == '\n') {
+ if (*(str + 1) == '\0')
+ break;
+ else
+ return -EINVAL;
+ } else if (*str == '.' && integer_part) {
+ integer_part = false;
+ } else {
+ return -EINVAL;
+ }
+ str++;
+ }
+
+ if (negative) {
+ if (i)
+ i = -i;
+ else
+ f = -f;
+ }
+
+ *integer = i;
+ *fract = f;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(iio_str_to_fixpoint);
+
static ssize_t iio_write_channel_info(struct device *dev,
struct device_attribute *attr,
const char *buf,
@@ -409,8 +473,8 @@ static ssize_t iio_write_channel_info(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 ret, integer = 0, fract = 0, fract_mult = 100000;
- bool integer_part = true, negative = false;
+ int ret, fract_mult = 100000;
+ int integer, fract;
/* Assumes decimal - precision based on number of digits */
if (!indio_dev->info->write_raw)
@@ -429,39 +493,9 @@ static ssize_t iio_write_channel_info(struct device *dev,
return -EINVAL;
}
- if (buf[0] == '-') {
- negative = true;
- buf++;
- }
-
- while (*buf) {
- if ('0' <= *buf && *buf <= '9') {
- if (integer_part)
- integer = integer*10 + *buf - '0';
- else {
- fract += fract_mult*(*buf - '0');
- if (fract_mult == 1)
- break;
- fract_mult /= 10;
- }
- } else if (*buf == '\n') {
- if (*(buf + 1) == '\0')
- break;
- else
- return -EINVAL;
- } else if (*buf == '.') {
- integer_part = false;
- } else {
- return -EINVAL;
- }
- buf++;
- }
- if (negative) {
- if (integer)
- integer = -integer;
- else
- fract = -fract;
- }
+ ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
+ if (ret)
+ return ret;
ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
integer, fract, this_attr->address);
@@ -851,6 +885,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv)
return NULL;
}
dev_set_name(&dev->dev, "iio:device%d", dev->id);
+ INIT_LIST_HEAD(&dev->buffer_list);
}
return dev;
diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
index fa6543bf673..261cae00557 100644
--- a/drivers/iio/industrialio-event.c
+++ b/drivers/iio/industrialio-event.c
@@ -239,13 +239,13 @@ 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);
- unsigned long val;
+ int val;
int ret;
if (!indio_dev->info->write_event_value)
return -EINVAL;
- ret = strict_strtoul(buf, 10, &val);
+ ret = kstrtoint(buf, 10, &val);
if (ret)
return ret;
@@ -350,15 +350,10 @@ static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev)
ret = iio_device_add_event_sysfs(indio_dev,
&indio_dev->channels[j]);
if (ret < 0)
- goto error_clear_attrs;
+ return ret;
attrcount += ret;
}
return attrcount;
-
-error_clear_attrs:
- __iio_remove_event_config_attrs(indio_dev);
-
- return ret;
}
static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev)
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index f2b78d4fe45..d55e98fb300 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -78,7 +78,7 @@ int iio_map_array_unregister(struct iio_dev *indio_dev,
found_it = true;
break;
}
- if (found_it == false) {
+ if (!found_it) {
ret = -ENODEV;
goto error_ret;
}
@@ -203,6 +203,7 @@ struct iio_channel *iio_channel_get_all(const char *name)
if (name && strcmp(name, c->map->consumer_dev_name) != 0)
continue;
chans[mapind].indio_dev = c->indio_dev;
+ chans[mapind].data = c->map->consumer_data;
chans[mapind].channel =
iio_chan_spec_from_name(chans[mapind].indio_dev,
c->map->adc_channel_label);
@@ -314,6 +315,9 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
*processed = div_s64(raw64 * (s64)scale_val * scale,
scale_val2);
break;
+ case IIO_VAL_FRACTIONAL_LOG2:
+ *processed = (raw64 * (s64)scale_val * scale) >> scale_val2;
+ break;
default:
return -EINVAL;
}
diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c
index 164b62b91a4..36d210a06b2 100644
--- a/drivers/iio/light/adjd_s311.c
+++ b/drivers/iio/light/adjd_s311.c
@@ -164,7 +164,6 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adjd_s311_data *data = iio_priv(indio_dev);
- struct iio_buffer *buffer = indio_dev->buffer;
s64 time_ns = iio_get_time_ns();
int len = 0;
int i, j = 0;
@@ -187,7 +186,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)data->buffer + ALIGN(len, sizeof(s64)))
= time_ns;
- iio_push_to_buffer(buffer, (u8 *)data->buffer);
+ iio_push_to_buffers(indio_dev, (u8 *)data->buffer);
done:
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index 96e3691e42c..23eeeef64e8 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -176,21 +176,8 @@ 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)
{
- struct iio_buffer *buffer = indio_dev->buffer;
- int datum_sz;
-
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
- if (!buffer) {
- dev_err(&indio_dev->dev, "Buffer == NULL\n");
- return;
- }
- datum_sz = buffer->access->get_bytes_per_datum(buffer);
- if (len > datum_sz) {
- dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
- datum_sz);
- return;
- }
- iio_push_to_buffer(buffer, (u8 *)data);
+ iio_push_to_buffers(indio_dev, (u8 *)data);
}
/* Callback handler to send event after all samples are received and captured */
@@ -285,10 +272,9 @@ static int __devinit hid_als_probe(struct platform_device *pdev)
goto error_free_dev;
}
- channels = kmemdup(als_channels,
- sizeof(als_channels),
- GFP_KERNEL);
+ channels = kmemdup(als_channels, sizeof(als_channels), GFP_KERNEL);
if (!channels) {
+ ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
goto error_free_dev;
}
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index c4f0d274f57..8e75eb76ccd 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -198,21 +198,8 @@ 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)
{
- struct iio_buffer *buffer = indio_dev->buffer;
- int datum_sz;
-
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
- if (!buffer) {
- dev_err(&indio_dev->dev, "Buffer == NULL\n");
- return;
- }
- datum_sz = buffer->access->get_bytes_per_datum(buffer);
- if (len > datum_sz) {
- dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
- datum_sz);
- return;
- }
- iio_push_to_buffer(buffer, (u8 *)data);
+ iio_push_to_buffers(indio_dev, (u8 *)data);
}
/* Callback handler to send event after all samples are received and captured */
@@ -320,10 +307,10 @@ static int __devinit hid_magn_3d_probe(struct platform_device *pdev)
goto error_free_dev;
}
- channels = kmemdup(magn_3d_channels,
- sizeof(magn_3d_channels),
- GFP_KERNEL);
+ channels = kmemdup(magn_3d_channels, sizeof(magn_3d_channels),
+ GFP_KERNEL);
if (!channels) {
+ ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
goto error_free_dev;
}
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index c0ec7d42c3b..1abbc170d8b 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -26,10 +26,14 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src)
* input_mt_init_slots() - initialize MT input slots
* @dev: input device supporting MT events and finger tracking
* @num_slots: number of slots used by the device
+ * @flags: mt tasks to handle in core
*
* This function allocates all necessary memory for MT slot handling
* in the input device, prepares the ABS_MT_SLOT and
* ABS_MT_TRACKING_ID events for use and sets up appropriate buffers.
+ * Depending on the flags set, it also performs pointer emulation and
+ * frame synchronization.
+ *
* May be called repeatedly. Returns -EINVAL if attempting to
* reinitialize with a different number of slots.
*/
diff --git a/drivers/input/matrix-keymap.c b/drivers/input/matrix-keymap.c
index 443ad64b7f2..d88d9be1d1b 100644
--- a/drivers/input/matrix-keymap.c
+++ b/drivers/input/matrix-keymap.c
@@ -23,6 +23,7 @@
#include <linux/input.h>
#include <linux/of.h>
#include <linux/export.h>
+#include <linux/module.h>
#include <linux/input/matrix_keypad.h>
static bool matrix_keypad_map_key(struct input_dev *input_dev,
@@ -161,3 +162,5 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
return 0;
}
EXPORT_SYMBOL(matrix_keypad_build_keymap);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 8f02e3d0e71..4c842c320c2 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -12,8 +12,8 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#define MOUSEDEV_MINOR_BASE 32
-#define MOUSEDEV_MINORS 32
-#define MOUSEDEV_MIX 31
+#define MOUSEDEV_MINORS 31
+#define MOUSEDEV_MIX 63
#include <linux/sched.h>
#include <linux/slab.h>
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index f02028ec3db..78e5d9ab0ba 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -955,7 +955,8 @@ static int ads7846_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume);
-static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts)
+static int __devinit ads7846_setup_pendown(struct spi_device *spi,
+ struct ads7846 *ts)
{
struct ads7846_platform_data *pdata = spi->dev.platform_data;
int err;
@@ -981,6 +982,9 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784
ts->gpio_pendown = pdata->gpio_pendown;
+ if (pdata->gpio_pendown_debounce)
+ gpio_set_debounce(pdata->gpio_pendown,
+ pdata->gpio_pendown_debounce);
} else {
dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n");
return -EINVAL;
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index d4a4cd445ca..0badfa48b32 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -4108,7 +4108,7 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to)
static int intel_iommu_add_device(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
- struct pci_dev *bridge, *dma_pdev;
+ struct pci_dev *bridge, *dma_pdev = NULL;
struct iommu_group *group;
int ret;
@@ -4122,7 +4122,7 @@ static int intel_iommu_add_device(struct device *dev)
dma_pdev = pci_get_domain_bus_and_slot(
pci_domain_nr(pdev->bus),
bridge->subordinate->number, 0);
- else
+ if (!dma_pdev)
dma_pdev = pci_dev_get(bridge);
} else
dma_pdev = pci_dev_get(pdev);
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index a649f146d17..c0f7a426626 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -1054,6 +1054,7 @@ static int smmu_debugfs_stats_show(struct seq_file *s, void *v)
stats[i], val, offs);
}
seq_printf(s, "\n");
+ dput(dent);
return 0;
}
diff --git a/drivers/ipack/Kconfig b/drivers/ipack/Kconfig
new file mode 100644
index 00000000000..3949e558956
--- /dev/null
+++ b/drivers/ipack/Kconfig
@@ -0,0 +1,24 @@
+#
+# IPACK configuration.
+#
+
+menuconfig IPACK_BUS
+ tristate "IndustryPack bus support"
+ depends on HAS_IOMEM
+ ---help---
+ This option provides support for the IndustryPack framework. There
+ are IndustryPack carrier boards, which interface another bus (such as
+ PCI) to an IndustryPack bus, and IndustryPack modules, that are
+ hosted on these buses. While IndustryPack modules can provide a
+ large variety of functionality, they are most often found in
+ industrial control applications.
+
+ Say N if unsure.
+
+if IPACK_BUS
+
+source "drivers/ipack/carriers/Kconfig"
+
+source "drivers/ipack/devices/Kconfig"
+
+endif # IPACK
diff --git a/drivers/staging/ipack/Makefile b/drivers/ipack/Makefile
index 85ff223616f..6f14ade0f8f 100644
--- a/drivers/staging/ipack/Makefile
+++ b/drivers/ipack/Makefile
@@ -3,4 +3,4 @@
#
obj-$(CONFIG_IPACK_BUS) += ipack.o
obj-y += devices/
-obj-y += bridges/
+obj-y += carriers/
diff --git a/drivers/ipack/carriers/Kconfig b/drivers/ipack/carriers/Kconfig
new file mode 100644
index 00000000000..922ff5c35ac
--- /dev/null
+++ b/drivers/ipack/carriers/Kconfig
@@ -0,0 +1,7 @@
+config BOARD_TPCI200
+ tristate "Support for the TEWS TPCI-200 IndustryPack carrier board"
+ depends on IPACK_BUS
+ depends on PCI
+ help
+ This driver adds support for the TEWS TPCI200 IndustryPack carrier board.
+ default n
diff --git a/drivers/staging/ipack/bridges/Makefile b/drivers/ipack/carriers/Makefile
index d8b76459300..d8b76459300 100644
--- a/drivers/staging/ipack/bridges/Makefile
+++ b/drivers/ipack/carriers/Makefile
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/ipack/carriers/tpci200.c
index 46d6657280b..0246b1fddff 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/ipack/carriers/tpci200.c
@@ -2,9 +2,10 @@
* tpci200.c
*
* driver for the TEWS TPCI-200 device
- * Copyright (c) 2009 Nicolas Serafini, EIC2 SA
- * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
- * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
+ *
+ * Copyright (C) 2009-2012 CERN (www.cern.ch)
+ * Author: Nicolas Serafini, EIC2 SA
+ * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.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
@@ -15,20 +16,36 @@
#include <linux/slab.h>
#include "tpci200.h"
-static u16 tpci200_status_timeout[] = {
+static const u16 tpci200_status_timeout[] = {
TPCI200_A_TIMEOUT,
TPCI200_B_TIMEOUT,
TPCI200_C_TIMEOUT,
TPCI200_D_TIMEOUT,
};
-static u16 tpci200_status_error[] = {
+static const u16 tpci200_status_error[] = {
TPCI200_A_ERROR,
TPCI200_B_ERROR,
TPCI200_C_ERROR,
TPCI200_D_ERROR,
};
+static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = {
+ [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE,
+ [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE,
+ [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE,
+ [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_SIZE,
+ [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_SIZE,
+};
+
+static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = {
+ [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL,
+ [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL,
+ [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL,
+ [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_INTERVAL,
+ [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_INTERVAL,
+};
+
static struct tpci200_board *check_slot(struct ipack_device *dev)
{
struct tpci200_board *tpci200;
@@ -47,7 +64,7 @@ static struct tpci200_board *check_slot(struct ipack_device *dev)
if (dev->slot >= TPCI200_NB_SLOT) {
dev_info(&dev->dev,
"Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n",
- dev->bus_nr, dev->slot, TPCI200_NB_SLOT-1);
+ dev->bus->bus_nr, dev->slot, TPCI200_NB_SLOT-1);
return NULL;
}
@@ -74,33 +91,19 @@ static void tpci200_set_mask(struct tpci200_board *tpci200,
static void tpci200_unregister(struct tpci200_board *tpci200)
{
- int i;
-
free_irq(tpci200->info->pdev->irq, (void *) tpci200);
pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
- pci_iounmap(tpci200->info->pdev, tpci200->info->ioidint_space);
- pci_iounmap(tpci200->info->pdev, tpci200->info->mem8_space);
pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);
pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
+ pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR);
pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR);
pci_disable_device(tpci200->info->pdev);
pci_dev_put(tpci200->info->pdev);
-
- for (i = 0; i < TPCI200_NB_SLOT; i++) {
- tpci200->slots[i].io_phys.address = NULL;
- tpci200->slots[i].io_phys.size = 0;
- tpci200->slots[i].id_phys.address = NULL;
- tpci200->slots[i].id_phys.size = 0;
- tpci200->slots[i].int_phys.address = NULL;
- tpci200->slots[i].int_phys.size = 0;
- tpci200->slots[i].mem_phys.address = NULL;
- tpci200->slots[i].mem_phys.size = 0;
- }
}
static void tpci200_enable_irq(struct tpci200_board *tpci200,
@@ -207,7 +210,8 @@ static int tpci200_request_irq(struct ipack_device *dev,
if (tpci200->slots[dev->slot].irq != NULL) {
dev_err(&dev->dev,
- "Slot [%d:%d] IRQ already registered !\n", dev->bus_nr,
+ "Slot [%d:%d] IRQ already registered !\n",
+ dev->bus->bus_nr,
dev->slot);
res = -EINVAL;
goto out_unlock;
@@ -217,7 +221,7 @@ static int tpci200_request_irq(struct ipack_device *dev,
if (slot_irq == NULL) {
dev_err(&dev->dev,
"Slot [%d:%d] unable to allocate memory for IRQ !\n",
- dev->bus_nr, dev->slot);
+ dev->bus->bus_nr, dev->slot);
res = -ENOMEM;
goto out_unlock;
}
@@ -244,8 +248,7 @@ static int tpci200_register(struct tpci200_board *tpci200)
{
int i;
int res;
- unsigned long ioidint_base;
- unsigned long mem_base;
+ phys_addr_t ioidint_base;
unsigned short slot_ctrl;
if (pci_enable_device(tpci200->info->pdev) < 0)
@@ -274,38 +277,49 @@ static int tpci200_register(struct tpci200_board *tpci200)
goto out_release_ip_space;
}
- /* Request MEM space (Bar 4) */
+ /* Request MEM8 space (Bar 5) */
res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR,
- "Carrier MEM space");
+ "Carrier MEM8 space");
if (res) {
dev_err(&tpci200->info->pdev->dev,
- "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!",
+ "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!",
tpci200->info->pdev->bus->number,
tpci200->info->pdev->devfn);
goto out_release_ioid_int_space;
}
+ /* Request MEM16 space (Bar 4) */
+ res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR,
+ "Carrier MEM16 space");
+ if (res) {
+ dev_err(&tpci200->info->pdev->dev,
+ "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!",
+ tpci200->info->pdev->bus->number,
+ tpci200->info->pdev->devfn);
+ goto out_release_mem8_space;
+ }
+
/* Map internal tpci200 driver user space */
tpci200->info->interface_regs =
ioremap_nocache(pci_resource_start(tpci200->info->pdev,
TPCI200_IP_INTERFACE_BAR),
TPCI200_IFACE_SIZE);
- tpci200->info->ioidint_space =
- ioremap_nocache(pci_resource_start(tpci200->info->pdev,
- TPCI200_IO_ID_INT_SPACES_BAR),
- TPCI200_IOIDINT_SIZE);
- tpci200->info->mem8_space =
- ioremap_nocache(pci_resource_start(tpci200->info->pdev,
- TPCI200_MEM8_SPACE_BAR),
- TPCI200_MEM8_SIZE);
/* Initialize lock that protects interface_regs */
spin_lock_init(&tpci200->regs_lock);
ioidint_base = pci_resource_start(tpci200->info->pdev,
TPCI200_IO_ID_INT_SPACES_BAR);
- mem_base = pci_resource_start(tpci200->info->pdev,
- TPCI200_MEM8_SPACE_BAR);
+ tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF;
+ tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF;
+ tpci200->mod_mem[IPACK_INT_SPACE] =
+ ioidint_base + TPCI200_INT_SPACE_OFF;
+ tpci200->mod_mem[IPACK_MEM8_SPACE] =
+ pci_resource_start(tpci200->info->pdev,
+ TPCI200_MEM8_SPACE_BAR);
+ tpci200->mod_mem[IPACK_MEM16_SPACE] =
+ pci_resource_start(tpci200->info->pdev,
+ TPCI200_MEM16_SPACE_BAR);
/* Set the default parameters of the slot
* INT0 disabled, level sensitive
@@ -316,30 +330,8 @@ static int tpci200_register(struct tpci200_board *tpci200)
* clock rate 8 MHz
*/
slot_ctrl = 0;
-
- /* Set all slot physical address space */
- for (i = 0; i < TPCI200_NB_SLOT; i++) {
- tpci200->slots[i].io_phys.address =
- (void __iomem *)ioidint_base +
- TPCI200_IO_SPACE_OFF + TPCI200_IO_SPACE_GAP*i;
- tpci200->slots[i].io_phys.size = TPCI200_IO_SPACE_SIZE;
-
- tpci200->slots[i].id_phys.address =
- (void __iomem *)ioidint_base +
- TPCI200_ID_SPACE_OFF + TPCI200_ID_SPACE_GAP*i;
- tpci200->slots[i].id_phys.size = TPCI200_ID_SPACE_SIZE;
-
- tpci200->slots[i].int_phys.address =
- (void __iomem *)ioidint_base +
- TPCI200_INT_SPACE_OFF + TPCI200_INT_SPACE_GAP * i;
- tpci200->slots[i].int_phys.size = TPCI200_INT_SPACE_SIZE;
-
- tpci200->slots[i].mem_phys.address =
- (void __iomem *)mem_base + TPCI200_MEM8_GAP*i;
- tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SIZE;
-
+ for (i = 0; i < TPCI200_NB_SLOT; i++)
writew(slot_ctrl, &tpci200->info->interface_regs->control[i]);
- }
res = request_irq(tpci200->info->pdev->irq,
tpci200_interrupt, IRQF_SHARED,
@@ -354,6 +346,8 @@ static int tpci200_register(struct tpci200_board *tpci200)
return 0;
+out_release_mem8_space:
+ pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
out_release_ioid_int_space:
pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
out_release_ip_space:
@@ -363,166 +357,6 @@ out_disable_pci:
return res;
}
-static int tpci200_slot_unmap_space(struct ipack_device *dev, int space)
-{
- struct ipack_addr_space *virt_addr_space;
- struct tpci200_board *tpci200;
-
- tpci200 = check_slot(dev);
- if (tpci200 == NULL)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&tpci200->mutex))
- return -ERESTARTSYS;
-
- switch (space) {
- case IPACK_IO_SPACE:
- if (dev->io_space.address == NULL) {
- dev_info(&dev->dev,
- "Slot [%d:%d] IO space not mapped !\n",
- dev->bus_nr, dev->slot);
- goto out_unlock;
- }
- virt_addr_space = &dev->io_space;
- break;
- case IPACK_ID_SPACE:
- if (dev->id_space.address == NULL) {
- dev_info(&dev->dev,
- "Slot [%d:%d] ID space not mapped !\n",
- dev->bus_nr, dev->slot);
- goto out_unlock;
- }
- virt_addr_space = &dev->id_space;
- break;
- case IPACK_INT_SPACE:
- if (dev->int_space.address == NULL) {
- dev_info(&dev->dev,
- "Slot [%d:%d] INT space not mapped !\n",
- dev->bus_nr, dev->slot);
- goto out_unlock;
- }
- virt_addr_space = &dev->int_space;
- break;
- case IPACK_MEM_SPACE:
- if (dev->mem_space.address == NULL) {
- dev_info(&dev->dev,
- "Slot [%d:%d] MEM space not mapped !\n",
- dev->bus_nr, dev->slot);
- goto out_unlock;
- }
- virt_addr_space = &dev->mem_space;
- break;
- default:
- dev_err(&dev->dev,
- "Slot [%d:%d] space number %d doesn't exist !\n",
- dev->bus_nr, dev->slot, space);
- mutex_unlock(&tpci200->mutex);
- return -EINVAL;
- }
-
- iounmap(virt_addr_space->address);
-
- virt_addr_space->address = NULL;
- virt_addr_space->size = 0;
-out_unlock:
- mutex_unlock(&tpci200->mutex);
- return 0;
-}
-
-static int tpci200_slot_map_space(struct ipack_device *dev,
- unsigned int memory_size, int space)
-{
- int res = 0;
- unsigned int size_to_map;
- void __iomem *phys_address;
- struct ipack_addr_space *virt_addr_space;
- struct tpci200_board *tpci200;
-
- tpci200 = check_slot(dev);
- if (tpci200 == NULL)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&tpci200->mutex))
- return -ERESTARTSYS;
-
- switch (space) {
- case IPACK_IO_SPACE:
- if (dev->io_space.address != NULL) {
- dev_err(&dev->dev,
- "Slot [%d:%d] IO space already mapped !\n",
- tpci200->number, dev->slot);
- res = -EINVAL;
- goto out_unlock;
- }
- virt_addr_space = &dev->io_space;
-
- phys_address = tpci200->slots[dev->slot].io_phys.address;
- size_to_map = tpci200->slots[dev->slot].io_phys.size;
- break;
- case IPACK_ID_SPACE:
- if (dev->id_space.address != NULL) {
- dev_err(&dev->dev,
- "Slot [%d:%d] ID space already mapped !\n",
- tpci200->number, dev->slot);
- res = -EINVAL;
- goto out_unlock;
- }
- virt_addr_space = &dev->id_space;
-
- phys_address = tpci200->slots[dev->slot].id_phys.address;
- size_to_map = tpci200->slots[dev->slot].id_phys.size;
- break;
- case IPACK_INT_SPACE:
- if (dev->int_space.address != NULL) {
- dev_err(&dev->dev,
- "Slot [%d:%d] INT space already mapped !\n",
- tpci200->number, dev->slot);
- res = -EINVAL;
- goto out_unlock;
- }
- virt_addr_space = &dev->int_space;
-
- phys_address = tpci200->slots[dev->slot].int_phys.address;
- size_to_map = tpci200->slots[dev->slot].int_phys.size;
- break;
- case IPACK_MEM_SPACE:
- if (dev->mem_space.address != NULL) {
- dev_err(&dev->dev,
- "Slot [%d:%d] MEM space already mapped !\n",
- tpci200->number, dev->slot);
- res = -EINVAL;
- goto out_unlock;
- }
- virt_addr_space = &dev->mem_space;
-
- if (memory_size > tpci200->slots[dev->slot].mem_phys.size) {
- dev_err(&dev->dev,
- "Slot [%d:%d] request is 0x%X memory, only 0x%X available !\n",
- dev->bus_nr, dev->slot, memory_size,
- tpci200->slots[dev->slot].mem_phys.size);
- res = -EINVAL;
- goto out_unlock;
- }
-
- phys_address = tpci200->slots[dev->slot].mem_phys.address;
- size_to_map = memory_size;
- break;
- default:
- dev_err(&dev->dev, "Slot [%d:%d] space %d doesn't exist !\n",
- tpci200->number, dev->slot, space);
- res = -EINVAL;
- goto out_unlock;
- }
-
- virt_addr_space->size = size_to_map;
- virt_addr_space->address =
- ioremap_nocache((unsigned long)phys_address, size_to_map);
-
-out_unlock:
- mutex_unlock(&tpci200->mutex);
- return res;
-}
-
static int tpci200_get_clockrate(struct ipack_device *dev)
{
struct tpci200_board *tpci200 = check_slot(dev);
@@ -610,8 +444,6 @@ static void tpci200_uninstall(struct tpci200_board *tpci200)
}
static const struct ipack_bus_ops tpci200_bus_ops = {
- .map_space = tpci200_slot_map_space,
- .unmap_space = tpci200_slot_unmap_space,
.request_irq = tpci200_request_irq,
.free_irq = tpci200_free_irq,
.get_clockrate = tpci200_get_clockrate,
@@ -641,6 +473,31 @@ static int tpci200_install(struct tpci200_board *tpci200)
return 0;
}
+static void tpci200_release_device(struct ipack_device *dev)
+{
+ kfree(dev);
+}
+
+static int tpci200_create_device(struct tpci200_board *tpci200, int i)
+{
+ enum ipack_space space;
+ struct ipack_device *dev =
+ kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+ dev->slot = i;
+ dev->bus = tpci200->info->ipack_bus;
+ dev->release = tpci200_release_device;
+
+ for (space = 0; space < IPACK_SPACE_COUNT; space++) {
+ dev->region[space].start =
+ tpci200->mod_mem[space]
+ + tpci200_space_interval[space] * i;
+ dev->region[space].size = tpci200_space_size[space];
+ }
+ return ipack_device_register(dev);
+}
+
static int tpci200_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
@@ -716,7 +573,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
dev_set_drvdata(&pdev->dev, tpci200);
for (i = 0; i < TPCI200_NB_SLOT; i++)
- ipack_device_register(tpci200->info->ipack_bus, i);
+ tpci200_create_device(tpci200, i);
return 0;
out_err_bus_register:
@@ -742,7 +599,7 @@ static void __tpci200_pci_remove(struct tpci200_board *tpci200)
kfree(tpci200);
}
-static void __devexit tpci200_pci_remove(struct pci_dev *dev)
+static void tpci200_pci_remove(struct pci_dev *dev)
{
struct tpci200_board *tpci200 = pci_get_drvdata(dev);
@@ -761,20 +618,10 @@ static struct pci_driver tpci200_pci_drv = {
.name = "tpci200",
.id_table = tpci200_idtable,
.probe = tpci200_pci_probe,
- .remove = __devexit_p(tpci200_pci_remove),
+ .remove = tpci200_pci_remove,
};
-static int __init tpci200_drvr_init_module(void)
-{
- return pci_register_driver(&tpci200_pci_drv);
-}
-
-static void __exit tpci200_drvr_exit_module(void)
-{
- pci_unregister_driver(&tpci200_pci_drv);
-}
+module_pci_driver(tpci200_pci_drv);
MODULE_DESCRIPTION("TEWS TPCI-200 device driver");
MODULE_LICENSE("GPL");
-module_init(tpci200_drvr_init_module);
-module_exit(tpci200_drvr_exit_module);
diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/ipack/carriers/tpci200.h
index 235d1fe4f48..a7a151dab83 100644
--- a/drivers/staging/ipack/bridges/tpci200.h
+++ b/drivers/ipack/carriers/tpci200.h
@@ -2,9 +2,10 @@
* tpci200.h
*
* driver for the carrier TEWS TPCI-200
- * Copyright (c) 2009 Nicolas Serafini, EIC2 SA
- * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
- * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
+ *
+ * Copyright (C) 2009-2012 CERN (www.cern.ch)
+ * Author: Nicolas Serafini, EIC2 SA
+ * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.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
@@ -19,8 +20,7 @@
#include <linux/spinlock.h>
#include <linux/swab.h>
#include <linux/io.h>
-
-#include "../ipack.h"
+#include <linux/ipack.h>
#define TPCI200_NB_SLOT 0x4
#define TPCI200_NB_BAR 0x6
@@ -49,20 +49,20 @@ struct tpci200_regs {
#define TPCI200_IFACE_SIZE 0x100
#define TPCI200_IO_SPACE_OFF 0x0000
-#define TPCI200_IO_SPACE_GAP 0x0100
+#define TPCI200_IO_SPACE_INTERVAL 0x0100
#define TPCI200_IO_SPACE_SIZE 0x0080
#define TPCI200_ID_SPACE_OFF 0x0080
-#define TPCI200_ID_SPACE_GAP 0x0100
+#define TPCI200_ID_SPACE_INTERVAL 0x0100
#define TPCI200_ID_SPACE_SIZE 0x0040
#define TPCI200_INT_SPACE_OFF 0x00C0
-#define TPCI200_INT_SPACE_GAP 0x0100
+#define TPCI200_INT_SPACE_INTERVAL 0x0100
#define TPCI200_INT_SPACE_SIZE 0x0040
#define TPCI200_IOIDINT_SIZE 0x0400
-#define TPCI200_MEM8_GAP 0x00400000
-#define TPCI200_MEM8_SIZE 0x00400000
-#define TPCI200_MEM16_GAP 0x00800000
-#define TPCI200_MEM16_SIZE 0x00800000
+#define TPCI200_MEM8_SPACE_INTERVAL 0x00400000
+#define TPCI200_MEM8_SPACE_SIZE 0x00400000
+#define TPCI200_MEM16_SPACE_INTERVAL 0x00800000
+#define TPCI200_MEM16_SPACE_SIZE 0x00800000
/* control field in tpci200_regs */
#define TPCI200_INT0_EN 0x0040
@@ -137,11 +137,7 @@ struct slot_irq {
*
*/
struct tpci200_slot {
- struct slot_irq *irq;
- struct ipack_addr_space io_phys;
- struct ipack_addr_space id_phys;
- struct ipack_addr_space int_phys;
- struct ipack_addr_space mem_phys;
+ struct slot_irq *irq;
};
/**
@@ -156,8 +152,6 @@ struct tpci200_infos {
struct pci_dev *pdev;
struct pci_device_id *id_table;
struct tpci200_regs __iomem *interface_regs;
- void __iomem *ioidint_space;
- void __iomem *mem8_space;
void __iomem *cfg_regs;
struct ipack_bus_device *ipack_bus;
};
@@ -167,6 +161,7 @@ struct tpci200_board {
spinlock_t regs_lock;
struct tpci200_slot *slots;
struct tpci200_infos *info;
+ phys_addr_t mod_mem[IPACK_SPACE_COUNT];
};
#endif /* _TPCI200_H_ */
diff --git a/drivers/staging/ipack/devices/Kconfig b/drivers/ipack/devices/Kconfig
index 39f71888a58..0b82fdc198c 100644
--- a/drivers/staging/ipack/devices/Kconfig
+++ b/drivers/ipack/devices/Kconfig
@@ -4,4 +4,3 @@ config SERIAL_IPOCTAL
help
This driver supports the IPOCTAL serial port device for the IndustryPack bus.
default n
-
diff --git a/drivers/staging/ipack/devices/Makefile b/drivers/ipack/devices/Makefile
index 6de18bda4a9..6de18bda4a9 100644
--- a/drivers/staging/ipack/devices/Makefile
+++ b/drivers/ipack/devices/Makefile
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c
index d751edfda83..576d53d9267 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/ipack/devices/ipoctal.c
@@ -2,9 +2,10 @@
* ipoctal.c
*
* driver for the GE IP-OCTAL boards
- * Copyright (c) 2009 Nicolas Serafini, EIC2 SA
- * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
- * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
+ *
+ * Copyright (C) 2009-2012 CERN (www.cern.ch)
+ * Author: Nicolas Serafini, EIC2 SA
+ * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.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
@@ -21,7 +22,7 @@
#include <linux/slab.h>
#include <linux/atomic.h>
#include <linux/io.h>
-#include "../ipack.h"
+#include <linux/ipack.h>
#include "ipoctal.h"
#include "scc2698.h"
@@ -53,6 +54,8 @@ struct ipoctal {
struct ipoctal_channel channel[NR_CHANNELS];
unsigned char write;
struct tty_driver *tty_drv;
+ u8 __iomem *mem8_space;
+ u8 __iomem *int_space;
};
static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
@@ -252,35 +255,12 @@ static irqreturn_t ipoctal_irq_handler(void *arg)
ipoctal_irq_channel(&ipoctal->channel[i]);
/* Clear the IPack device interrupt */
- readw(ipoctal->dev->int_space.address + ACK_INT_REQ0);
- readw(ipoctal->dev->int_space.address + ACK_INT_REQ1);
+ readw(ipoctal->int_space + ACK_INT_REQ0);
+ readw(ipoctal->int_space + ACK_INT_REQ1);
return IRQ_HANDLED;
}
-static int ipoctal_check_model(struct ipack_device *dev, unsigned char *id)
-{
- unsigned char manufacturerID;
- unsigned char board_id;
-
-
- manufacturerID = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MANUFACTURER_ID);
- if (manufacturerID != IPACK1_VENDOR_ID_SBS)
- return -ENODEV;
- board_id = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MODEL);
- switch (board_id) {
- case IPACK1_DEVICE_ID_SBS_OCTAL_232:
- case IPACK1_DEVICE_ID_SBS_OCTAL_422:
- case IPACK1_DEVICE_ID_SBS_OCTAL_485:
- *id = board_id;
- break;
- default:
- return -ENODEV;
- }
-
- return 0;
-}
-
static const struct tty_port_operations ipoctal_tty_port_ops = {
.dtr_rts = NULL,
.activate = ipoctal_port_activate,
@@ -289,64 +269,55 @@ static const struct tty_port_operations ipoctal_tty_port_ops = {
static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
unsigned int slot)
{
- int res = 0;
+ int res;
int i;
struct tty_driver *tty;
char name[20];
- unsigned char board_id;
struct ipoctal_channel *channel;
+ struct ipack_region *region;
+ void __iomem *addr;
union scc2698_channel __iomem *chan_regs;
union scc2698_block __iomem *block_regs;
- res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
- IPACK_ID_SPACE);
- if (res) {
- dev_err(&ipoctal->dev->dev,
- "Unable to map slot [%d:%d] ID space!\n",
- bus_nr, slot);
- return res;
- }
-
- res = ipoctal_check_model(ipoctal->dev, &board_id);
- if (res) {
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev,
- IPACK_ID_SPACE);
- goto out_unregister_id_space;
- }
- ipoctal->board_id = board_id;
+ ipoctal->board_id = ipoctal->dev->id_device;
- res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
- IPACK_IO_SPACE);
- if (res) {
+ region = &ipoctal->dev->region[IPACK_IO_SPACE];
+ addr = devm_ioremap_nocache(&ipoctal->dev->dev,
+ region->start, region->size);
+ if (!addr) {
dev_err(&ipoctal->dev->dev,
"Unable to map slot [%d:%d] IO space!\n",
bus_nr, slot);
- goto out_unregister_id_space;
+ return -EADDRNOTAVAIL;
}
+ /* Save the virtual address to access the registers easily */
+ chan_regs =
+ (union scc2698_channel __iomem *) addr;
+ block_regs =
+ (union scc2698_block __iomem *) addr;
- res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
- IPACK_INT_SPACE);
- if (res) {
+ region = &ipoctal->dev->region[IPACK_INT_SPACE];
+ ipoctal->int_space =
+ devm_ioremap_nocache(&ipoctal->dev->dev,
+ region->start, region->size);
+ if (!ipoctal->int_space) {
dev_err(&ipoctal->dev->dev,
"Unable to map slot [%d:%d] INT space!\n",
bus_nr, slot);
- goto out_unregister_io_space;
+ return -EADDRNOTAVAIL;
}
- res = ipoctal->dev->bus->ops->map_space(ipoctal->dev,
- 0x8000, IPACK_MEM_SPACE);
- if (res) {
+ region = &ipoctal->dev->region[IPACK_MEM8_SPACE];
+ ipoctal->mem8_space =
+ devm_ioremap_nocache(&ipoctal->dev->dev,
+ region->start, 0x8000);
+ if (!addr) {
dev_err(&ipoctal->dev->dev,
- "Unable to map slot [%d:%d] MEM space!\n",
+ "Unable to map slot [%d:%d] MEM8 space!\n",
bus_nr, slot);
- goto out_unregister_int_space;
+ return -EADDRNOTAVAIL;
}
- /* Save the virtual address to access the registers easily */
- chan_regs =
- (union scc2698_channel __iomem *) ipoctal->dev->io_space.address;
- block_regs =
- (union scc2698_block __iomem *) ipoctal->dev->io_space.address;
/* Disable RX and TX before touching anything */
for (i = 0; i < NR_CHANNELS ; i++) {
@@ -389,17 +360,15 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
ipoctal->dev->bus->ops->request_irq(ipoctal->dev,
ipoctal_irq_handler, ipoctal);
/* Dummy write */
- iowrite8(1, ipoctal->dev->mem_space.address + 1);
+ iowrite8(1, ipoctal->mem8_space + 1);
/* Register the TTY device */
/* Each IP-OCTAL channel is a TTY port */
tty = alloc_tty_driver(NR_CHANNELS);
- if (!tty) {
- res = -ENOMEM;
- goto out_unregister_slot_unmap;
- }
+ if (!tty)
+ return -ENOMEM;
/* Fill struct tty_driver with ipoctal data */
tty->owner = THIS_MODULE;
@@ -422,7 +391,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
if (res) {
dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n");
put_tty_driver(tty);
- goto out_unregister_slot_unmap;
+ return res;
}
/* Save struct tty_driver for use it when uninstalling the device */
@@ -446,6 +415,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
tty_dev = tty_port_register_device(&channel->tty_port, tty, i, NULL);
if (IS_ERR(tty_dev)) {
dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n");
+ tty_port_destroy(&channel->tty_port);
continue;
}
dev_set_drvdata(tty_dev, channel);
@@ -458,16 +428,6 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
}
return 0;
-
-out_unregister_slot_unmap:
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE);
-out_unregister_int_space:
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE);
-out_unregister_io_space:
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE);
-out_unregister_id_space:
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE);
- return res;
}
static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel,
@@ -719,7 +679,7 @@ static int ipoctal_probe(struct ipack_device *dev)
return -ENOMEM;
ipoctal->dev = dev;
- res = ipoctal_inst_slot(ipoctal, dev->bus_nr, dev->slot);
+ res = ipoctal_inst_slot(ipoctal, dev->bus->bus_nr, dev->slot);
if (res)
goto out_uninst;
@@ -741,14 +701,11 @@ static void __ipoctal_remove(struct ipoctal *ipoctal)
struct ipoctal_channel *channel = &ipoctal->channel[i];
tty_unregister_device(ipoctal->tty_drv, i);
tty_port_free_xmit_buf(&channel->tty_port);
+ tty_port_destroy(&channel->tty_port);
}
tty_unregister_driver(ipoctal->tty_drv);
put_tty_driver(ipoctal->tty_drv);
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE);
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE);
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE);
- ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE);
kfree(ipoctal);
}
diff --git a/drivers/staging/ipack/devices/ipoctal.h b/drivers/ipack/devices/ipoctal.h
index c5b4ed46516..28f1c423315 100644
--- a/drivers/staging/ipack/devices/ipoctal.h
+++ b/drivers/ipack/devices/ipoctal.h
@@ -2,9 +2,10 @@
* ipoctal.h
*
* driver for the IPOCTAL boards
- * Copyright (c) 2009 Nicolas Serafini, EIC2 SA
- * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
- * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
+
+ * Copyright (C) 2009-2012 CERN (www.cern.ch)
+ * Author: Nicolas Serafini, EIC2 SA
+ * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.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
diff --git a/drivers/staging/ipack/devices/scc2698.h b/drivers/ipack/devices/scc2698.h
index 96e8d8c30e1..2ad6acd513f 100644
--- a/drivers/staging/ipack/devices/scc2698.h
+++ b/drivers/ipack/devices/scc2698.h
@@ -2,9 +2,10 @@
* scc2698.h
*
* driver for the IPOCTAL boards
- * Copyright (c) 2009 Nicolas Serafini, EIC2 SA
- * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
- * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
+ *
+ * Copyright (C) 2009-2012 CERN (www.cern.ch)
+ * Author: Nicolas Serafini, EIC2 SA
+ * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.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
diff --git a/drivers/staging/ipack/ipack.c b/drivers/ipack/ipack.c
index d1e0651592a..7ec6b208b1c 100644
--- a/drivers/staging/ipack/ipack.c
+++ b/drivers/ipack/ipack.c
@@ -1,8 +1,8 @@
/*
* Industry-pack bus support functions.
*
- * (C) 2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
- * (C) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
+ * Copyright (C) 2011-2012 CERN (www.cern.ch)
+ * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.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
@@ -12,8 +12,8 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/idr.h>
-#include <asm/io.h>
-#include "ipack.h"
+#include <linux/io.h>
+#include <linux/ipack.h>
#define to_ipack_dev(device) container_of(device, struct ipack_device, dev)
#define to_ipack_driver(drv) container_of(drv, struct ipack_driver, driver)
@@ -24,7 +24,7 @@ static void ipack_device_release(struct device *dev)
{
struct ipack_device *device = to_ipack_dev(dev);
kfree(device->id);
- kfree(device);
+ device->release(device);
}
static inline const struct ipack_device_id *
@@ -85,8 +85,6 @@ static int ipack_bus_remove(struct device *device)
return 0;
}
-#ifdef CONFIG_HOTPLUG
-
static int ipack_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct ipack_device *idev;
@@ -104,12 +102,6 @@ static int ipack_uevent(struct device *dev, struct kobj_uevent_env *env)
return 0;
}
-#else /* !CONFIG_HOTPLUG */
-
-#define ipack_uevent NULL
-
-#endif /* !CONFIG_HOTPLUG */
-
#define ipack_device_attr(field, format_string) \
static ssize_t \
field##_show(struct device *dev, struct device_attribute *attr, \
@@ -234,7 +226,7 @@ static int ipack_unregister_bus_member(struct device *dev, void *data)
struct ipack_device *idev = to_ipack_dev(dev);
struct ipack_bus_device *bus = data;
- if (idev->bus_nr == bus->bus_nr)
+ if (idev->bus == bus)
ipack_device_unregister(idev);
return 1;
@@ -242,7 +234,8 @@ static int ipack_unregister_bus_member(struct device *dev, void *data)
int ipack_bus_unregister(struct ipack_bus_device *bus)
{
- bus_for_each_dev(&ipack_bus_type, NULL, bus, ipack_unregister_bus_member);
+ bus_for_each_dev(&ipack_bus_type, NULL, bus,
+ ipack_unregister_bus_member);
ida_simple_remove(&ipack_ida, bus->bus_nr);
kfree(bus);
return 0;
@@ -351,12 +344,12 @@ static int ipack_device_read_id(struct ipack_device *dev)
int i;
int ret = 0;
- ret = dev->bus->ops->map_space(dev, 0, IPACK_ID_SPACE);
- if (ret) {
+ idmem = ioremap(dev->region[IPACK_ID_SPACE].start,
+ dev->region[IPACK_ID_SPACE].size);
+ if (!idmem) {
dev_err(&dev->dev, "error mapping memory\n");
- return ret;
+ return -ENOMEM;
}
- idmem = dev->id_space.address;
/* Determine ID PROM Data Format. If we find the ids "IPAC" or "IPAH"
* we are dealing with a IndustryPack format 1 device. If we detect
@@ -421,57 +414,44 @@ static int ipack_device_read_id(struct ipack_device *dev)
}
out:
- dev->bus->ops->unmap_space(dev, IPACK_ID_SPACE);
+ iounmap(idmem);
return ret;
}
-struct ipack_device *ipack_device_register(struct ipack_bus_device *bus,
- int slot)
+int ipack_device_register(struct ipack_device *dev)
{
int ret;
- struct ipack_device *dev;
-
- dev = kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
- if (!dev)
- return NULL;
dev->dev.bus = &ipack_bus_type;
dev->dev.release = ipack_device_release;
- dev->dev.parent = bus->parent;
- dev->slot = slot;
- dev->bus_nr = bus->bus_nr;
- dev->bus = bus;
+ dev->dev.parent = dev->bus->parent;
dev_set_name(&dev->dev,
- "ipack-dev.%u.%u", dev->bus_nr, dev->slot);
+ "ipack-dev.%u.%u", dev->bus->bus_nr, dev->slot);
- if (bus->ops->set_clockrate(dev, 8))
+ if (dev->bus->ops->set_clockrate(dev, 8))
dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n");
- if (bus->ops->reset_timeout(dev))
+ if (dev->bus->ops->reset_timeout(dev))
dev_warn(&dev->dev, "failed to reset potential timeout.");
ret = ipack_device_read_id(dev);
if (ret < 0) {
dev_err(&dev->dev, "error reading device id section.\n");
- kfree(dev);
- return NULL;
+ return ret;
}
/* if the device supports 32 MHz operation, use it. */
if (dev->speed_32mhz) {
- ret = bus->ops->set_clockrate(dev, 32);
+ ret = dev->bus->ops->set_clockrate(dev, 32);
if (ret < 0)
dev_err(&dev->dev, "failed to switch to 32 MHz operation.\n");
}
ret = device_register(&dev->dev);
- if (ret < 0) {
+ if (ret < 0)
kfree(dev->id);
- kfree(dev);
- return NULL;
- }
- return dev;
+ return ret;
}
EXPORT_SYMBOL_GPL(ipack_device_register);
diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c
index dc670ccc697..16c78f1c5ef 100644
--- a/drivers/irqchip/irq-bcm2835.c
+++ b/drivers/irqchip/irq-bcm2835.c
@@ -168,7 +168,8 @@ static int __init armctrl_of_init(struct device_node *node,
}
static struct of_device_id irq_of_match[] __initconst = {
- { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init }
+ { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init },
+ { }
};
void __init bcm2835_init_irq(void)
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index c679867c2cc..89562a845f6 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -77,8 +77,6 @@ struct ackqueue_entry {
};
struct capiminor {
- struct kref kref;
-
unsigned int minor;
struct capi20_appl *ap;
@@ -190,7 +188,20 @@ static void capiminor_del_all_ack(struct capiminor *mp)
/* -------- struct capiminor ---------------------------------------- */
-static const struct tty_port_operations capiminor_port_ops; /* we have none */
+static void capiminor_destroy(struct tty_port *port)
+{
+ struct capiminor *mp = container_of(port, struct capiminor, port);
+
+ kfree_skb(mp->outskb);
+ skb_queue_purge(&mp->inqueue);
+ skb_queue_purge(&mp->outqueue);
+ capiminor_del_all_ack(mp);
+ kfree(mp);
+}
+
+static const struct tty_port_operations capiminor_port_ops = {
+ .destruct = capiminor_destroy,
+};
static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
{
@@ -204,8 +215,6 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
return NULL;
}
- kref_init(&mp->kref);
-
mp->ap = ap;
mp->ncci = ncci;
INIT_LIST_HEAD(&mp->ackqueue);
@@ -247,21 +256,10 @@ err_out2:
spin_unlock(&capiminors_lock);
err_out1:
- kfree(mp);
+ tty_port_put(&mp->port);
return NULL;
}
-static void capiminor_destroy(struct kref *kref)
-{
- struct capiminor *mp = container_of(kref, struct capiminor, kref);
-
- kfree_skb(mp->outskb);
- skb_queue_purge(&mp->inqueue);
- skb_queue_purge(&mp->outqueue);
- capiminor_del_all_ack(mp);
- kfree(mp);
-}
-
static struct capiminor *capiminor_get(unsigned int minor)
{
struct capiminor *mp;
@@ -269,7 +267,7 @@ static struct capiminor *capiminor_get(unsigned int minor)
spin_lock(&capiminors_lock);
mp = capiminors[minor];
if (mp)
- kref_get(&mp->kref);
+ tty_port_get(&mp->port);
spin_unlock(&capiminors_lock);
return mp;
@@ -277,7 +275,7 @@ static struct capiminor *capiminor_get(unsigned int minor)
static inline void capiminor_put(struct capiminor *mp)
{
- kref_put(&mp->kref, capiminor_destroy);
+ tty_port_put(&mp->port);
}
static void capiminor_free(struct capiminor *mp)
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index 30a6b174fbb..6849a11a1b2 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -507,6 +507,7 @@ void gigaset_freecs(struct cardstate *cs)
gig_dbg(DEBUG_INIT, "clearing at_state");
clear_at_state(&cs->at_state);
dealloc_temp_at_states(cs);
+ tty_port_destroy(&cs->port);
/* fall through */
case 0: /* error in basic setup */
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index b817809f763..e09dc8a5e74 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1849,6 +1849,8 @@ err_unregister:
kfree(info->fax);
#endif
kfree(info->port.xmit_buf - 4);
+ info->port.xmit_buf = NULL;
+ tty_port_destroy(&info->port);
}
tty_unregister_driver(m->tty_modem);
err:
@@ -1870,6 +1872,8 @@ isdn_tty_exit(void)
kfree(info->fax);
#endif
kfree(info->port.xmit_buf - 4);
+ info->port.xmit_buf = NULL;
+ tty_port_destroy(&info->port);
}
tty_unregister_driver(dev->mdm.tty_modem);
put_tty_driver(dev->mdm.tty_modem);
diff --git a/drivers/leds/leds-adp5520.c b/drivers/leds/leds-adp5520.c
index aa56a867693..dcd9128a51a 100644
--- a/drivers/leds/leds-adp5520.c
+++ b/drivers/leds/leds-adp5520.c
@@ -85,7 +85,7 @@ static int adp5520_led_setup(struct adp5520_led *led)
return ret;
}
-static int __devinit adp5520_led_prepare(struct platform_device *pdev)
+static int adp5520_led_prepare(struct platform_device *pdev)
{
struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data;
struct device *dev = pdev->dev.parent;
@@ -101,7 +101,7 @@ static int __devinit adp5520_led_prepare(struct platform_device *pdev)
return ret;
}
-static int __devinit adp5520_led_probe(struct platform_device *pdev)
+static int adp5520_led_probe(struct platform_device *pdev)
{
struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data;
struct adp5520_led *led, *led_dat;
@@ -183,7 +183,7 @@ err:
return ret;
}
-static int __devexit adp5520_led_remove(struct platform_device *pdev)
+static int adp5520_led_remove(struct platform_device *pdev)
{
struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data;
struct adp5520_led *led;
@@ -208,7 +208,7 @@ static struct platform_driver adp5520_led_driver = {
.owner = THIS_MODULE,
},
.probe = adp5520_led_probe,
- .remove = __devexit_p(adp5520_led_remove),
+ .remove = adp5520_led_remove,
};
module_platform_driver(adp5520_led_driver);
diff --git a/drivers/leds/leds-asic3.c b/drivers/leds/leds-asic3.c
index 5de74ff90dc..b474745e001 100644
--- a/drivers/leds/leds-asic3.c
+++ b/drivers/leds/leds-asic3.c
@@ -92,7 +92,7 @@ static int blink_set(struct led_classdev *cdev,
return 0;
}
-static int __devinit asic3_led_probe(struct platform_device *pdev)
+static int asic3_led_probe(struct platform_device *pdev)
{
struct asic3_led *led = pdev->dev.platform_data;
int ret;
@@ -125,7 +125,7 @@ out:
return ret;
}
-static int __devexit asic3_led_remove(struct platform_device *pdev)
+static int asic3_led_remove(struct platform_device *pdev)
{
struct asic3_led *led = pdev->dev.platform_data;
@@ -167,7 +167,7 @@ static const struct dev_pm_ops asic3_led_pm_ops = {
static struct platform_driver asic3_led_driver = {
.probe = asic3_led_probe,
- .remove = __devexit_p(asic3_led_remove),
+ .remove = asic3_led_remove,
.driver = {
.name = "leds-asic3",
.owner = THIS_MODULE,
diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c
index 45430632faa..386773532d9 100644
--- a/drivers/leds/leds-atmel-pwm.c
+++ b/drivers/leds/leds-atmel-pwm.c
@@ -35,7 +35,7 @@ static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b)
* NOTE: we reuse the platform_data structure of GPIO leds,
* but repurpose its "gpio" number as a PWM channel number.
*/
-static int __devinit pwmled_probe(struct platform_device *pdev)
+static int pwmled_probe(struct platform_device *pdev)
{
const struct gpio_led_platform_data *pdata;
struct pwmled *leds;
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c
index 89ca6a2a19d..9abe8de40ed 100644
--- a/drivers/leds/leds-bd2802.c
+++ b/drivers/leds/leds-bd2802.c
@@ -670,7 +670,7 @@ static void bd2802_unregister_led_classdev(struct bd2802_led *led)
led_classdev_unregister(&led->cdev_led1r);
}
-static int __devinit bd2802_probe(struct i2c_client *client,
+static int bd2802_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct bd2802_led *led;
diff --git a/drivers/leds/leds-blinkm.c b/drivers/leds/leds-blinkm.c
index f7c3d7f1ec5..a502678cc7f 100644
--- a/drivers/leds/leds-blinkm.c
+++ b/drivers/leds/leds-blinkm.c
@@ -632,7 +632,7 @@ static int blinkm_detect(struct i2c_client *client, struct i2c_board_info *info)
return 0;
}
-static int __devinit blinkm_probe(struct i2c_client *client,
+static int blinkm_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct blinkm_data *data;
@@ -743,7 +743,7 @@ exit:
return err;
}
-static int __devexit blinkm_remove(struct i2c_client *client)
+static int blinkm_remove(struct i2c_client *client)
{
struct blinkm_data *data = i2c_get_clientdata(client);
int ret = 0;
@@ -801,7 +801,7 @@ static struct i2c_driver blinkm_driver = {
.name = "blinkm",
},
.probe = blinkm_probe,
- .remove = __devexit_p(blinkm_remove),
+ .remove = blinkm_remove,
.id_table = blinkm_id,
.detect = blinkm_detect,
.address_list = normal_i2c,
diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c
index e024b0b1c3b..b02547052e1 100644
--- a/drivers/leds/leds-clevo-mail.c
+++ b/drivers/leds/leds-clevo-mail.c
@@ -153,7 +153,7 @@ static struct led_classdev clevo_mail_led = {
.flags = LED_CORE_SUSPENDRESUME,
};
-static int __devinit clevo_mail_led_probe(struct platform_device *pdev)
+static int clevo_mail_led_probe(struct platform_device *pdev)
{
return led_classdev_register(&pdev->dev, &clevo_mail_led);
}
diff --git a/drivers/leds/leds-cobalt-qube.c b/drivers/leds/leds-cobalt-qube.c
index 6a8725cc7b4..ffa99303b62 100644
--- a/drivers/leds/leds-cobalt-qube.c
+++ b/drivers/leds/leds-cobalt-qube.c
@@ -34,7 +34,7 @@ static struct led_classdev qube_front_led = {
.default_trigger = "default-on",
};
-static int __devinit cobalt_qube_led_probe(struct platform_device *pdev)
+static int cobalt_qube_led_probe(struct platform_device *pdev)
{
struct resource *res;
int retval;
@@ -63,7 +63,7 @@ err_iounmap:
return retval;
}
-static int __devexit cobalt_qube_led_remove(struct platform_device *pdev)
+static int cobalt_qube_led_remove(struct platform_device *pdev)
{
led_classdev_unregister(&qube_front_led);
@@ -77,7 +77,7 @@ static int __devexit cobalt_qube_led_remove(struct platform_device *pdev)
static struct platform_driver cobalt_qube_led_driver = {
.probe = cobalt_qube_led_probe,
- .remove = __devexit_p(cobalt_qube_led_remove),
+ .remove = cobalt_qube_led_remove,
.driver = {
.name = "cobalt-qube-leds",
.owner = THIS_MODULE,
diff --git a/drivers/leds/leds-cobalt-raq.c b/drivers/leds/leds-cobalt-raq.c
index aac1c073fe7..d52e47de396 100644
--- a/drivers/leds/leds-cobalt-raq.c
+++ b/drivers/leds/leds-cobalt-raq.c
@@ -76,7 +76,7 @@ static struct led_classdev raq_power_off_led = {
.default_trigger = "power-off",
};
-static int __devinit cobalt_raq_led_probe(struct platform_device *pdev)
+static int cobalt_raq_led_probe(struct platform_device *pdev)
{
struct resource *res;
int retval;
@@ -109,7 +109,7 @@ err_iounmap:
return retval;
}
-static int __devexit cobalt_raq_led_remove(struct platform_device *pdev)
+static int cobalt_raq_led_remove(struct platform_device *pdev)
{
led_classdev_unregister(&raq_power_off_led);
led_classdev_unregister(&raq_web_led);
@@ -124,7 +124,7 @@ static int __devexit cobalt_raq_led_remove(struct platform_device *pdev)
static struct platform_driver cobalt_raq_led_driver = {
.probe = cobalt_raq_led_probe,
- .remove = __devexit_p(cobalt_raq_led_remove),
+ .remove = cobalt_raq_led_remove,
.driver = {
.name = "cobalt-raq-leds",
.owner = THIS_MODULE,
diff --git a/drivers/leds/leds-da903x.c b/drivers/leds/leds-da903x.c
index cc77c9d9261..6f31b776765 100644
--- a/drivers/leds/leds-da903x.c
+++ b/drivers/leds/leds-da903x.c
@@ -91,7 +91,7 @@ static void da903x_led_set(struct led_classdev *led_cdev,
schedule_work(&led->work);
}
-static int __devinit da903x_led_probe(struct platform_device *pdev)
+static int da903x_led_probe(struct platform_device *pdev)
{
struct led_info *pdata = pdev->dev.platform_data;
struct da903x_led *led;
@@ -136,7 +136,7 @@ static int __devinit da903x_led_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit da903x_led_remove(struct platform_device *pdev)
+static int da903x_led_remove(struct platform_device *pdev)
{
struct da903x_led *led = platform_get_drvdata(pdev);
@@ -150,7 +150,7 @@ static struct platform_driver da903x_led_driver = {
.owner = THIS_MODULE,
},
.probe = da903x_led_probe,
- .remove = __devexit_p(da903x_led_remove),
+ .remove = da903x_led_remove,
};
module_platform_driver(da903x_led_driver);
diff --git a/drivers/leds/leds-da9052.c b/drivers/leds/leds-da9052.c
index 58a5244c437..efec43344e9 100644
--- a/drivers/leds/leds-da9052.c
+++ b/drivers/leds/leds-da9052.c
@@ -102,7 +102,7 @@ static int da9052_configure_leds(struct da9052 *da9052)
return error;
}
-static int __devinit da9052_led_probe(struct platform_device *pdev)
+static int da9052_led_probe(struct platform_device *pdev)
{
struct da9052_pdata *pdata;
struct da9052 *da9052;
@@ -176,7 +176,7 @@ err:
return error;
}
-static int __devexit da9052_led_remove(struct platform_device *pdev)
+static int da9052_led_remove(struct platform_device *pdev)
{
struct da9052_led *led = platform_get_drvdata(pdev);
struct da9052_pdata *pdata;
@@ -204,7 +204,7 @@ static struct platform_driver da9052_led_driver = {
.owner = THIS_MODULE,
},
.probe = da9052_led_probe,
- .remove = __devexit_p(da9052_led_remove),
+ .remove = da9052_led_remove,
};
module_platform_driver(da9052_led_driver);
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 087d1e66f4f..291c20797ca 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -91,7 +91,7 @@ static int gpio_blink_set(struct led_classdev *led_cdev,
delay_on, delay_off);
}
-static int __devinit create_gpio_led(const struct gpio_led *template,
+static int create_gpio_led(const struct gpio_led *template,
struct gpio_led_data *led_dat, struct device *parent,
int (*blink_set)(unsigned, int, unsigned long *, unsigned long *))
{
@@ -167,7 +167,7 @@ static inline int sizeof_gpio_leds_priv(int num_leds)
/* Code to create from OpenFirmware platform devices */
#ifdef CONFIG_OF_GPIO
-static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev)
+static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node, *child;
struct gpio_leds_priv *priv;
@@ -224,14 +224,14 @@ static const struct of_device_id of_gpio_leds_match[] = {
{},
};
#else /* CONFIG_OF_GPIO */
-static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev)
+static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
{
return NULL;
}
#endif /* CONFIG_OF_GPIO */
-static int __devinit gpio_led_probe(struct platform_device *pdev)
+static int gpio_led_probe(struct platform_device *pdev)
{
struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
struct gpio_leds_priv *priv;
@@ -273,7 +273,7 @@ static int __devinit gpio_led_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit gpio_led_remove(struct platform_device *pdev)
+static int gpio_led_remove(struct platform_device *pdev)
{
struct gpio_leds_priv *priv = platform_get_drvdata(pdev);
int i;
@@ -288,7 +288,7 @@ static int __devexit gpio_led_remove(struct platform_device *pdev)
static struct platform_driver gpio_led_driver = {
.probe = gpio_led_probe,
- .remove = __devexit_p(gpio_led_remove),
+ .remove = gpio_led_remove,
.driver = {
.name = "leds-gpio",
.owner = THIS_MODULE,
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c
index b26306f6724..21414548383 100644
--- a/drivers/leds/leds-lm3530.c
+++ b/drivers/leds/leds-lm3530.c
@@ -377,7 +377,7 @@ static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute
}
static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set);
-static int __devinit lm3530_probe(struct i2c_client *client,
+static int lm3530_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct lm3530_platform_data *pdata = client->dev.platform_data;
@@ -452,7 +452,7 @@ err_create_file:
return err;
}
-static int __devexit lm3530_remove(struct i2c_client *client)
+static int lm3530_remove(struct i2c_client *client)
{
struct lm3530_data *drvdata = i2c_get_clientdata(client);
@@ -472,7 +472,7 @@ MODULE_DEVICE_TABLE(i2c, lm3530_id);
static struct i2c_driver lm3530_i2c_driver = {
.probe = lm3530_probe,
- .remove = __devexit_p(lm3530_remove),
+ .remove = lm3530_remove,
.id_table = lm3530_id,
.driver = {
.name = LM3530_NAME,
diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c
index f6837b99908..bbf24d038a7 100644
--- a/drivers/leds/leds-lm3533.c
+++ b/drivers/leds/leds-lm3533.c
@@ -646,7 +646,7 @@ static struct attribute_group lm3533_led_attribute_group = {
.attrs = lm3533_led_attributes
};
-static int __devinit lm3533_led_setup(struct lm3533_led *led,
+static int lm3533_led_setup(struct lm3533_led *led,
struct lm3533_led_platform_data *pdata)
{
int ret;
@@ -658,7 +658,7 @@ static int __devinit lm3533_led_setup(struct lm3533_led *led,
return lm3533_ctrlbank_set_pwm(&led->cb, pdata->pwm);
}
-static int __devinit lm3533_led_probe(struct platform_device *pdev)
+static int lm3533_led_probe(struct platform_device *pdev)
{
struct lm3533 *lm3533;
struct lm3533_led_platform_data *pdata;
@@ -742,7 +742,7 @@ err_unregister:
return ret;
}
-static int __devexit lm3533_led_remove(struct platform_device *pdev)
+static int lm3533_led_remove(struct platform_device *pdev)
{
struct lm3533_led *led = platform_get_drvdata(pdev);
@@ -774,7 +774,7 @@ static struct platform_driver lm3533_led_driver = {
.owner = THIS_MODULE,
},
.probe = lm3533_led_probe,
- .remove = __devexit_p(lm3533_led_remove),
+ .remove = lm3533_led_remove,
.shutdown = lm3533_led_shutdown,
};
module_platform_driver(lm3533_led_driver);
diff --git a/drivers/leds/leds-lm355x.c b/drivers/leds/leds-lm355x.c
index 065ec015d67..b13ce037191 100644
--- a/drivers/leds/leds-lm355x.c
+++ b/drivers/leds/leds-lm355x.c
@@ -168,7 +168,7 @@ static char lm355x_name[][I2C_NAME_SIZE] = {
};
/* chip initialize */
-static int __devinit lm355x_chip_init(struct lm355x_chip_data *chip)
+static int lm355x_chip_init(struct lm355x_chip_data *chip)
{
int ret;
unsigned int reg_val;
@@ -420,7 +420,7 @@ static const struct regmap_config lm355x_regmap = {
};
/* module initialize */
-static int __devinit lm355x_probe(struct i2c_client *client,
+static int lm355x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct lm355x_platform_data *pdata = client->dev.platform_data;
@@ -526,7 +526,7 @@ err_out:
return err;
}
-static int __devexit lm355x_remove(struct i2c_client *client)
+static int lm355x_remove(struct i2c_client *client)
{
struct lm355x_chip_data *chip = i2c_get_clientdata(client);
struct lm355x_reg_data *preg = chip->regs;
@@ -560,7 +560,7 @@ static struct i2c_driver lm355x_i2c_driver = {
.pm = NULL,
},
.probe = lm355x_probe,
- .remove = __devexit_p(lm355x_remove),
+ .remove = lm355x_remove,
.id_table = lm355x_id,
};
diff --git a/drivers/leds/leds-lm3642.c b/drivers/leds/leds-lm3642.c
index 3285006e988..215a7c1e56c 100644
--- a/drivers/leds/leds-lm3642.c
+++ b/drivers/leds/leds-lm3642.c
@@ -93,7 +93,7 @@ struct lm3642_chip_data {
};
/* chip initialize */
-static int __devinit lm3642_chip_init(struct lm3642_chip_data *chip)
+static int lm3642_chip_init(struct lm3642_chip_data *chip)
{
int ret;
struct lm3642_platform_data *pdata = chip->pdata;
@@ -313,7 +313,7 @@ static const struct regmap_config lm3642_regmap = {
.max_register = REG_MAX,
};
-static int __devinit lm3642_probe(struct i2c_client *client,
+static int lm3642_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct lm3642_platform_data *pdata = client->dev.platform_data;
@@ -420,7 +420,7 @@ err_out:
return err;
}
-static int __devexit lm3642_remove(struct i2c_client *client)
+static int lm3642_remove(struct i2c_client *client)
{
struct lm3642_chip_data *chip = i2c_get_clientdata(client);
@@ -450,7 +450,7 @@ static struct i2c_driver lm3642_i2c_driver = {
.pm = NULL,
},
.probe = lm3642_probe,
- .remove = __devexit_p(lm3642_remove),
+ .remove = lm3642_remove,
.id_table = lm3642_id,
};
diff --git a/drivers/leds/leds-lp3944.c b/drivers/leds/leds-lp3944.c
index c298f7d9f53..b081f67e1de 100644
--- a/drivers/leds/leds-lp3944.c
+++ b/drivers/leds/leds-lp3944.c
@@ -374,7 +374,7 @@ exit:
return err;
}
-static int __devinit lp3944_probe(struct i2c_client *client,
+static int lp3944_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct lp3944_platform_data *lp3944_pdata = client->dev.platform_data;
@@ -411,7 +411,7 @@ static int __devinit lp3944_probe(struct i2c_client *client,
return 0;
}
-static int __devexit lp3944_remove(struct i2c_client *client)
+static int lp3944_remove(struct i2c_client *client)
{
struct lp3944_platform_data *pdata = client->dev.platform_data;
struct lp3944_data *data = i2c_get_clientdata(client);
@@ -446,7 +446,7 @@ static struct i2c_driver lp3944_driver = {
.name = "lp3944",
},
.probe = lp3944_probe,
- .remove = __devexit_p(lp3944_remove),
+ .remove = lp3944_remove,
.id_table = lp3944_id,
};
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index 2064aefedc0..966f158a07d 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -687,7 +687,7 @@ static void lp5521_unregister_sysfs(struct i2c_client *client)
&lp5521_led_attribute_group);
}
-static int __devinit lp5521_init_led(struct lp5521_led *led,
+static int lp5521_init_led(struct lp5521_led *led,
struct i2c_client *client,
int chan, struct lp5521_platform_data *pdata)
{
@@ -736,7 +736,7 @@ static int __devinit lp5521_init_led(struct lp5521_led *led,
return 0;
}
-static int __devinit lp5521_probe(struct i2c_client *client,
+static int lp5521_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct lp5521_chip *chip;
@@ -855,7 +855,7 @@ fail1:
return ret;
}
-static int __devexit lp5521_remove(struct i2c_client *client)
+static int lp5521_remove(struct i2c_client *client)
{
struct lp5521_chip *chip = i2c_get_clientdata(client);
int i;
@@ -886,7 +886,7 @@ static struct i2c_driver lp5521_driver = {
.name = "lp5521",
},
.probe = lp5521_probe,
- .remove = __devexit_p(lp5521_remove),
+ .remove = lp5521_remove,
.id_table = lp5521_id,
};
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 97994ffdc01..7e304b7ff77 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -833,7 +833,7 @@ static int __init lp5523_init_engine(struct lp5523_engine *engine, int id)
return 0;
}
-static int __devinit lp5523_init_led(struct lp5523_led *led, struct device *dev,
+static int lp5523_init_led(struct lp5523_led *led, struct device *dev,
int chan, struct lp5523_platform_data *pdata,
const char *chip_name)
{
@@ -882,7 +882,7 @@ static int __devinit lp5523_init_led(struct lp5523_led *led, struct device *dev,
return 0;
}
-static int __devinit lp5523_probe(struct i2c_client *client,
+static int lp5523_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct lp5523_chip *chip;
diff --git a/drivers/leds/leds-lp8788.c b/drivers/leds/leds-lp8788.c
index 64009a17665..4353942c5fd 100644
--- a/drivers/leds/leds-lp8788.c
+++ b/drivers/leds/leds-lp8788.c
@@ -125,7 +125,7 @@ static void lp8788_brightness_set(struct led_classdev *led_cdev,
schedule_work(&led->work);
}
-static __devinit int lp8788_led_probe(struct platform_device *pdev)
+static int lp8788_led_probe(struct platform_device *pdev)
{
struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
struct lp8788_led_platform_data *led_pdata;
@@ -167,7 +167,7 @@ static __devinit int lp8788_led_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit lp8788_led_remove(struct platform_device *pdev)
+static int lp8788_led_remove(struct platform_device *pdev)
{
struct lp8788_led *led = platform_get_drvdata(pdev);
@@ -179,7 +179,7 @@ static int __devexit lp8788_led_remove(struct platform_device *pdev)
static struct platform_driver lp8788_led_driver = {
.probe = lp8788_led_probe,
- .remove = __devexit_p(lp8788_led_remove),
+ .remove = lp8788_led_remove,
.driver = {
.name = LP8788_DEV_KEYLED,
.owner = THIS_MODULE,
diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c
index 09a732217f6..34b3ba4376f 100644
--- a/drivers/leds/leds-lt3593.c
+++ b/drivers/leds/leds-lt3593.c
@@ -82,7 +82,7 @@ static void lt3593_led_set(struct led_classdev *led_cdev,
schedule_work(&led_dat->work);
}
-static int __devinit create_lt3593_led(const struct gpio_led *template,
+static int create_lt3593_led(const struct gpio_led *template,
struct lt3593_led_data *led_dat, struct device *parent)
{
int ret, state;
@@ -140,7 +140,7 @@ static void delete_lt3593_led(struct lt3593_led_data *led)
gpio_free(led->gpio);
}
-static int __devinit lt3593_led_probe(struct platform_device *pdev)
+static int lt3593_led_probe(struct platform_device *pdev)
{
struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
struct lt3593_led_data *leds_data;
@@ -173,7 +173,7 @@ err:
return ret;
}
-static int __devexit lt3593_led_remove(struct platform_device *pdev)
+static int lt3593_led_remove(struct platform_device *pdev)
{
int i;
struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
@@ -189,7 +189,7 @@ static int __devexit lt3593_led_remove(struct platform_device *pdev)
static struct platform_driver lt3593_led_driver = {
.probe = lt3593_led_probe,
- .remove = __devexit_p(lt3593_led_remove),
+ .remove = lt3593_led_remove,
.driver = {
.name = "leds-lt3593",
.owner = THIS_MODULE,
diff --git a/drivers/leds/leds-max8997.c b/drivers/leds/leds-max8997.c
index 569e36de37d..f449a8bdddc 100644
--- a/drivers/leds/leds-max8997.c
+++ b/drivers/leds/leds-max8997.c
@@ -229,7 +229,7 @@ static ssize_t max8997_led_store_mode(struct device *dev,
static DEVICE_ATTR(mode, 0644, max8997_led_show_mode, max8997_led_store_mode);
-static int __devinit max8997_led_probe(struct platform_device *pdev)
+static int max8997_led_probe(struct platform_device *pdev)
{
struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
@@ -292,7 +292,7 @@ static int __devinit max8997_led_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit max8997_led_remove(struct platform_device *pdev)
+static int max8997_led_remove(struct platform_device *pdev)
{
struct max8997_led *led = platform_get_drvdata(pdev);
@@ -308,7 +308,7 @@ static struct platform_driver max8997_led_driver = {
.owner = THIS_MODULE,
},
.probe = max8997_led_probe,
- .remove = __devexit_p(max8997_led_remove),
+ .remove = max8997_led_remove,
};
module_platform_driver(max8997_led_driver);
diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c
index 2a5d4340067..e942adaa750 100644
--- a/drivers/leds/leds-mc13783.c
+++ b/drivers/leds/leds-mc13783.c
@@ -128,7 +128,7 @@ static void mc13783_led_set(struct led_classdev *led_cdev,
schedule_work(&led->work);
}
-static int __devinit mc13783_led_setup(struct mc13783_led *led, int max_current)
+static int mc13783_led_setup(struct mc13783_led *led, int max_current)
{
int shift = 0;
int mask = 0;
@@ -181,7 +181,7 @@ static int __devinit mc13783_led_setup(struct mc13783_led *led, int max_current)
return ret;
}
-static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
+static int mc13783_leds_prepare(struct platform_device *pdev)
{
struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct mc13xxx *dev = dev_get_drvdata(pdev->dev.parent);
@@ -262,7 +262,7 @@ out:
return ret;
}
-static int __devinit mc13783_led_probe(struct platform_device *pdev)
+static int mc13783_led_probe(struct platform_device *pdev)
{
struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct mc13xxx_led_platform_data *led_cur;
@@ -348,7 +348,7 @@ err_register:
return ret;
}
-static int __devexit mc13783_led_remove(struct platform_device *pdev)
+static int mc13783_led_remove(struct platform_device *pdev)
{
struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct mc13783_led *led = platform_get_drvdata(pdev);
@@ -381,7 +381,7 @@ static struct platform_driver mc13783_led_driver = {
.owner = THIS_MODULE,
},
.probe = mc13783_led_probe,
- .remove = __devexit_p(mc13783_led_remove),
+ .remove = mc13783_led_remove,
};
module_platform_driver(mc13783_led_driver);
diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c
index 461bbf9b33f..58a800b17dc 100644
--- a/drivers/leds/leds-netxbig.c
+++ b/drivers/leds/leds-netxbig.c
@@ -71,7 +71,7 @@ static void gpio_ext_set_value(struct netxbig_gpio_ext *gpio_ext,
spin_unlock_irqrestore(&gpio_ext_lock, flags);
}
-static int __devinit gpio_ext_init(struct netxbig_gpio_ext *gpio_ext)
+static int gpio_ext_init(struct netxbig_gpio_ext *gpio_ext)
{
int err;
int i;
@@ -301,7 +301,7 @@ static void delete_netxbig_led(struct netxbig_led_data *led_dat)
led_classdev_unregister(&led_dat->cdev);
}
-static int __devinit
+static int
create_netxbig_led(struct platform_device *pdev,
struct netxbig_led_data *led_dat,
const struct netxbig_led *template)
@@ -352,7 +352,7 @@ create_netxbig_led(struct platform_device *pdev,
return ret;
}
-static int __devinit netxbig_led_probe(struct platform_device *pdev)
+static int netxbig_led_probe(struct platform_device *pdev)
{
struct netxbig_led_platform_data *pdata = pdev->dev.platform_data;
struct netxbig_led_data *leds_data;
@@ -389,7 +389,7 @@ err_free_leds:
return ret;
}
-static int __devexit netxbig_led_remove(struct platform_device *pdev)
+static int netxbig_led_remove(struct platform_device *pdev)
{
struct netxbig_led_platform_data *pdata = pdev->dev.platform_data;
struct netxbig_led_data *leds_data;
@@ -407,7 +407,7 @@ static int __devexit netxbig_led_remove(struct platform_device *pdev)
static struct platform_driver netxbig_led_driver = {
.probe = netxbig_led_probe,
- .remove = __devexit_p(netxbig_led_remove),
+ .remove = netxbig_led_remove,
.driver = {
.name = "leds-netxbig",
.owner = THIS_MODULE,
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c
index d176ec83f5d..6315e88d04f 100644
--- a/drivers/leds/leds-ns2.c
+++ b/drivers/leds/leds-ns2.c
@@ -184,7 +184,7 @@ static ssize_t ns2_led_sata_show(struct device *dev,
static DEVICE_ATTR(sata, 0644, ns2_led_sata_show, ns2_led_sata_store);
-static int __devinit
+static int
create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
const struct ns2_led *template)
{
@@ -263,7 +263,7 @@ static void delete_ns2_led(struct ns2_led_data *led_dat)
gpio_free(led_dat->slow);
}
-static int __devinit ns2_led_probe(struct platform_device *pdev)
+static int ns2_led_probe(struct platform_device *pdev)
{
struct ns2_led_platform_data *pdata = pdev->dev.platform_data;
struct ns2_led_data *leds_data;
@@ -292,7 +292,7 @@ static int __devinit ns2_led_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit ns2_led_remove(struct platform_device *pdev)
+static int ns2_led_remove(struct platform_device *pdev)
{
int i;
struct ns2_led_platform_data *pdata = pdev->dev.platform_data;
@@ -310,7 +310,7 @@ static int __devexit ns2_led_remove(struct platform_device *pdev)
static struct platform_driver ns2_led_driver = {
.probe = ns2_led_probe,
- .remove = __devexit_p(ns2_led_remove),
+ .remove = ns2_led_remove,
.driver = {
.name = "leds-ns2",
.owner = THIS_MODULE,
diff --git a/drivers/leds/leds-ot200.c b/drivers/leds/leds-ot200.c
index c4646825a62..ee14662ed5c 100644
--- a/drivers/leds/leds-ot200.c
+++ b/drivers/leds/leds-ot200.c
@@ -115,7 +115,7 @@ static void ot200_led_brightness_set(struct led_classdev *led_cdev,
spin_unlock_irqrestore(&value_lock, flags);
}
-static int __devinit ot200_led_probe(struct platform_device *pdev)
+static int ot200_led_probe(struct platform_device *pdev)
{
int i;
int ret;
@@ -144,7 +144,7 @@ err:
return ret;
}
-static int __devexit ot200_led_remove(struct platform_device *pdev)
+static int ot200_led_remove(struct platform_device *pdev)
{
int i;
@@ -156,7 +156,7 @@ static int __devexit ot200_led_remove(struct platform_device *pdev)
static struct platform_driver ot200_led_driver = {
.probe = ot200_led_probe,
- .remove = __devexit_p(ot200_led_remove),
+ .remove = ot200_led_remove,
.driver = {
.name = "leds-ot200",
.owner = THIS_MODULE,
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c
index aef3cf0432f..706791af8fc 100644
--- a/drivers/leds/leds-pca955x.c
+++ b/drivers/leds/leds-pca955x.c
@@ -255,7 +255,7 @@ static void pca955x_led_set(struct led_classdev *led_cdev, enum led_brightness v
schedule_work(&pca955x->work);
}
-static int __devinit pca955x_probe(struct i2c_client *client,
+static int pca955x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pca955x *pca955x;
@@ -363,7 +363,7 @@ exit:
return err;
}
-static int __devexit pca955x_remove(struct i2c_client *client)
+static int pca955x_remove(struct i2c_client *client)
{
struct pca955x *pca955x = i2c_get_clientdata(client);
int i;
@@ -382,7 +382,7 @@ static struct i2c_driver pca955x_driver = {
.owner = THIS_MODULE,
},
.probe = pca955x_probe,
- .remove = __devexit_p(pca955x_remove),
+ .remove = pca955x_remove,
.id_table = pca955x_id,
};
diff --git a/drivers/leds/leds-pca9633.c b/drivers/leds/leds-pca9633.c
index 2f2f9c43535..9aae5679ffb 100644
--- a/drivers/leds/leds-pca9633.c
+++ b/drivers/leds/leds-pca9633.c
@@ -93,7 +93,7 @@ static void pca9633_led_set(struct led_classdev *led_cdev,
schedule_work(&pca9633->work);
}
-static int __devinit pca9633_probe(struct i2c_client *client,
+static int pca9633_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pca9633_led *pca9633;
@@ -164,7 +164,7 @@ exit:
return err;
}
-static int __devexit pca9633_remove(struct i2c_client *client)
+static int pca9633_remove(struct i2c_client *client)
{
struct pca9633_led *pca9633 = i2c_get_clientdata(client);
int i;
@@ -183,7 +183,7 @@ static struct i2c_driver pca9633_driver = {
.owner = THIS_MODULE,
},
.probe = pca9633_probe,
- .remove = __devexit_p(pca9633_remove),
+ .remove = pca9633_remove,
.id_table = pca9633_id,
};
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index f2e44c71943..e51ff7a3cd8 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -107,7 +107,7 @@ err:
return ret;
}
-static int __devexit led_pwm_remove(struct platform_device *pdev)
+static int led_pwm_remove(struct platform_device *pdev)
{
int i;
struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
@@ -125,7 +125,7 @@ static int __devexit led_pwm_remove(struct platform_device *pdev)
static struct platform_driver led_pwm_driver = {
.probe = led_pwm_probe,
- .remove = __devexit_p(led_pwm_remove),
+ .remove = led_pwm_remove,
.driver = {
.name = "leds_pwm",
.owner = THIS_MODULE,
diff --git a/drivers/leds/leds-rb532.c b/drivers/leds/leds-rb532.c
index a7815b6cd85..9ebdd5011a7 100644
--- a/drivers/leds/leds-rb532.c
+++ b/drivers/leds/leds-rb532.c
@@ -37,12 +37,12 @@ static struct led_classdev rb532_uled = {
.default_trigger = "nand-disk",
};
-static int __devinit rb532_led_probe(struct platform_device *pdev)
+static int rb532_led_probe(struct platform_device *pdev)
{
return led_classdev_register(&pdev->dev, &rb532_uled);
}
-static int __devexit rb532_led_remove(struct platform_device *pdev)
+static int rb532_led_remove(struct platform_device *pdev)
{
led_classdev_unregister(&rb532_uled);
return 0;
@@ -50,7 +50,7 @@ static int __devexit rb532_led_remove(struct platform_device *pdev)
static struct platform_driver rb532_led_driver = {
.probe = rb532_led_probe,
- .remove = __devexit_p(rb532_led_remove),
+ .remove = rb532_led_remove,
.driver = {
.name = "rb532-led",
.owner = THIS_MODULE,
diff --git a/drivers/leds/leds-regulator.c b/drivers/leds/leds-regulator.c
index 25d382d60fa..4253a9b03db 100644
--- a/drivers/leds/leds-regulator.c
+++ b/drivers/leds/leds-regulator.c
@@ -140,7 +140,7 @@ static void regulator_led_brightness_set(struct led_classdev *led_cdev,
schedule_work(&led->work);
}
-static int __devinit regulator_led_probe(struct platform_device *pdev)
+static int regulator_led_probe(struct platform_device *pdev)
{
struct led_regulator_platform_data *pdata = pdev->dev.platform_data;
struct regulator_led *led;
@@ -206,7 +206,7 @@ err_vcc:
return ret;
}
-static int __devexit regulator_led_remove(struct platform_device *pdev)
+static int regulator_led_remove(struct platform_device *pdev)
{
struct regulator_led *led = platform_get_drvdata(pdev);
@@ -223,7 +223,7 @@ static struct platform_driver regulator_led_driver = {
.owner = THIS_MODULE,
},
.probe = regulator_led_probe,
- .remove = __devexit_p(regulator_led_remove),
+ .remove = regulator_led_remove,
};
module_platform_driver(regulator_led_driver);
diff --git a/drivers/leds/leds-renesas-tpu.c b/drivers/leds/leds-renesas-tpu.c
index 771ea067e68..bc8984795a3 100644
--- a/drivers/leds/leds-renesas-tpu.c
+++ b/drivers/leds/leds-renesas-tpu.c
@@ -238,7 +238,7 @@ static void r_tpu_set_brightness(struct led_classdev *ldev,
schedule_work(&p->work);
}
-static int __devinit r_tpu_probe(struct platform_device *pdev)
+static int r_tpu_probe(struct platform_device *pdev)
{
struct led_renesas_tpu_config *cfg = pdev->dev.platform_data;
struct r_tpu_priv *p;
@@ -309,7 +309,7 @@ static int __devinit r_tpu_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit r_tpu_remove(struct platform_device *pdev)
+static int r_tpu_remove(struct platform_device *pdev)
{
struct r_tpu_priv *p = platform_get_drvdata(pdev);
@@ -328,7 +328,7 @@ static int __devexit r_tpu_remove(struct platform_device *pdev)
static struct platform_driver r_tpu_device_driver = {
.probe = r_tpu_probe,
- .remove = __devexit_p(r_tpu_remove),
+ .remove = r_tpu_remove,
.driver = {
.name = "leds-renesas-tpu",
}
diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c
index 57371e1485a..6469849e826 100644
--- a/drivers/leds/leds-ss4200.c
+++ b/drivers/leds/leds-ss4200.c
@@ -263,7 +263,7 @@ static int nasgpio_led_set_blink(struct led_classdev *led_cdev,
* already taken care of this, but we will do so in a non destructive manner
* so that we have what we need whether the BIOS did it or not.
*/
-static int __devinit ich7_gpio_init(struct device *dev)
+static int ich7_gpio_init(struct device *dev)
{
int i;
u32 config_data = 0;
@@ -342,7 +342,7 @@ static void ich7_lpc_cleanup(struct device *dev)
* so we can retrive the required operational information and prepare the GPIO.
*/
static struct pci_dev *nas_gpio_pci_dev;
-static int __devinit ich7_lpc_probe(struct pci_dev *dev,
+static int ich7_lpc_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
int status;
diff --git a/drivers/leds/leds-sunfire.c b/drivers/leds/leds-sunfire.c
index 134d9a4b34f..07ff5a3a6ce 100644
--- a/drivers/leds/leds-sunfire.c
+++ b/drivers/leds/leds-sunfire.c
@@ -123,7 +123,7 @@ struct sunfire_drvdata {
struct sunfire_led leds[NUM_LEDS_PER_BOARD];
};
-static int __devinit sunfire_led_generic_probe(struct platform_device *pdev,
+static int sunfire_led_generic_probe(struct platform_device *pdev,
struct led_type *types)
{
struct sunfire_drvdata *p;
@@ -165,7 +165,7 @@ static int __devinit sunfire_led_generic_probe(struct platform_device *pdev,
return 0;
}
-static int __devexit sunfire_led_generic_remove(struct platform_device *pdev)
+static int sunfire_led_generic_remove(struct platform_device *pdev)
{
struct sunfire_drvdata *p = dev_get_drvdata(&pdev->dev);
int i;
@@ -192,7 +192,7 @@ static struct led_type clockboard_led_types[NUM_LEDS_PER_BOARD] = {
},
};
-static int __devinit sunfire_clockboard_led_probe(struct platform_device *pdev)
+static int sunfire_clockboard_led_probe(struct platform_device *pdev)
{
return sunfire_led_generic_probe(pdev, clockboard_led_types);
}
@@ -213,7 +213,7 @@ static struct led_type fhc_led_types[NUM_LEDS_PER_BOARD] = {
},
};
-static int __devinit sunfire_fhc_led_probe(struct platform_device *pdev)
+static int sunfire_fhc_led_probe(struct platform_device *pdev)
{
return sunfire_led_generic_probe(pdev, fhc_led_types);
}
@@ -223,7 +223,7 @@ MODULE_ALIAS("platform:sunfire-fhc-leds");
static struct platform_driver sunfire_clockboard_led_driver = {
.probe = sunfire_clockboard_led_probe,
- .remove = __devexit_p(sunfire_led_generic_remove),
+ .remove = sunfire_led_generic_remove,
.driver = {
.name = "sunfire-clockboard-leds",
.owner = THIS_MODULE,
@@ -232,7 +232,7 @@ static struct platform_driver sunfire_clockboard_led_driver = {
static struct platform_driver sunfire_fhc_led_driver = {
.probe = sunfire_fhc_led_probe,
- .remove = __devexit_p(sunfire_led_generic_remove),
+ .remove = sunfire_led_generic_remove,
.driver = {
.name = "sunfire-fhc-leds",
.owner = THIS_MODULE,
diff --git a/drivers/leds/leds-tca6507.c b/drivers/leds/leds-tca6507.c
index dabcf7ae8d0..b26a63bae16 100644
--- a/drivers/leds/leds-tca6507.c
+++ b/drivers/leds/leds-tca6507.c
@@ -667,7 +667,7 @@ static void tca6507_remove_gpio(struct tca6507_chip *tca)
}
#endif /* CONFIG_GPIOLIB */
-static int __devinit tca6507_probe(struct i2c_client *client,
+static int tca6507_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tca6507_chip *tca;
@@ -730,7 +730,7 @@ exit:
return err;
}
-static int __devexit tca6507_remove(struct i2c_client *client)
+static int tca6507_remove(struct i2c_client *client)
{
int i;
struct tca6507_chip *tca = i2c_get_clientdata(client);
@@ -752,7 +752,7 @@ static struct i2c_driver tca6507_driver = {
.owner = THIS_MODULE,
},
.probe = tca6507_probe,
- .remove = __devexit_p(tca6507_remove),
+ .remove = tca6507_remove,
.id_table = tca6507_id,
};
diff --git a/drivers/leds/ledtrig-cpu.c b/drivers/leds/ledtrig-cpu.c
index b312056da14..4239b3955ff 100644
--- a/drivers/leds/ledtrig-cpu.c
+++ b/drivers/leds/ledtrig-cpu.c
@@ -33,8 +33,6 @@
struct led_trigger_cpu {
char name[MAX_NAME_LEN];
struct led_trigger *_trig;
- struct mutex lock;
- int lock_is_inited;
};
static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig);
@@ -50,12 +48,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt)
{
struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig);
- /* mutex lock should be initialized before calling mutex_call() */
- if (!trig->lock_is_inited)
- return;
-
- mutex_lock(&trig->lock);
-
/* Locate the correct CPU LED */
switch (ledevt) {
case CPU_LED_IDLE_END:
@@ -75,8 +67,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt)
/* Will leave the LED as it is */
break;
}
-
- mutex_unlock(&trig->lock);
}
EXPORT_SYMBOL(ledtrig_cpu);
@@ -117,14 +107,9 @@ static int __init ledtrig_cpu_init(void)
for_each_possible_cpu(cpu) {
struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);
- mutex_init(&trig->lock);
-
snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu);
- mutex_lock(&trig->lock);
led_trigger_register_simple(trig->name, &trig->_trig);
- trig->lock_is_inited = 1;
- mutex_unlock(&trig->lock);
}
register_syscore_ops(&ledtrig_cpu_syscore_ops);
@@ -142,15 +127,9 @@ static void __exit ledtrig_cpu_exit(void)
for_each_possible_cpu(cpu) {
struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);
- mutex_lock(&trig->lock);
-
led_trigger_unregister_simple(trig->_trig);
trig->_trig = NULL;
memset(trig->name, 0, MAX_NAME_LEN);
- trig->lock_is_inited = 0;
-
- mutex_unlock(&trig->lock);
- mutex_destroy(&trig->lock);
}
unregister_syscore_ops(&ledtrig_cpu_syscore_ops);
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index 7d5a6b40b31..19636800900 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -565,7 +565,7 @@ fail_msg_node:
fail_db_node:
of_node_put(smu->db_node);
fail_bootmem:
- free_bootmem((unsigned long)smu, sizeof(struct smu_device));
+ free_bootmem(__pa(smu), sizeof(struct smu_device));
smu = NULL;
fail_np:
of_node_put(np);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 02db9183ca0..77e6eff41ca 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -740,8 +740,14 @@ static void rq_completed(struct mapped_device *md, int rw, int run_queue)
if (!md_in_flight(md))
wake_up(&md->wait);
+ /*
+ * Run this off this callpath, as drivers could invoke end_io while
+ * inside their request_fn (and holding the queue lock). Calling
+ * back into ->request_fn() could deadlock attempting to grab the
+ * queue lock again.
+ */
if (run_queue)
- blk_run_queue(md->queue);
+ blk_run_queue_async(md->queue);
/*
* dm_put() must be at the end of this function. See the comment above
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9ab768acfb6..61200717687 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1817,10 +1817,10 @@ retry:
memset(bbp, 0xff, PAGE_SIZE);
for (i = 0 ; i < bb->count ; i++) {
- u64 internal_bb = *p++;
+ u64 internal_bb = p[i];
u64 store_bb = ((BB_OFFSET(internal_bb) << 10)
| BB_LEN(internal_bb));
- *bbp++ = cpu_to_le64(store_bb);
+ bbp[i] = cpu_to_le64(store_bb);
}
bb->changed = 0;
if (read_seqretry(&bb->lock, seq))
@@ -5294,7 +5294,7 @@ void md_stop_writes(struct mddev *mddev)
}
EXPORT_SYMBOL_GPL(md_stop_writes);
-void md_stop(struct mddev *mddev)
+static void __md_stop(struct mddev *mddev)
{
mddev->ready = 0;
mddev->pers->stop(mddev);
@@ -5304,6 +5304,18 @@ void md_stop(struct mddev *mddev)
mddev->pers = NULL;
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
}
+
+void md_stop(struct mddev *mddev)
+{
+ /* stop the array and free an attached data structures.
+ * This is called from dm-raid
+ */
+ __md_stop(mddev);
+ bitmap_destroy(mddev);
+ if (mddev->bio_set)
+ bioset_free(mddev->bio_set);
+}
+
EXPORT_SYMBOL_GPL(md_stop);
static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
@@ -5364,7 +5376,7 @@ static int do_md_stop(struct mddev * mddev, int mode,
set_disk_ro(disk, 0);
__md_stop_writes(mddev);
- md_stop(mddev);
+ __md_stop(mddev);
mddev->queue->merge_bvec_fn = NULL;
mddev->queue->backing_dev_info.congested_fn = NULL;
@@ -7936,9 +7948,9 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors,
sector_t *first_bad, int *bad_sectors)
{
int hi;
- int lo = 0;
+ int lo;
u64 *p = bb->page;
- int rv = 0;
+ int rv;
sector_t target = s + sectors;
unsigned seq;
@@ -7953,7 +7965,8 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors,
retry:
seq = read_seqbegin(&bb->lock);
-
+ lo = 0;
+ rv = 0;
hi = bb->count;
/* Binary search between lo and hi for 'target'
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 636bae0405e..a0f73092176 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -963,7 +963,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule)
struct r1conf *conf = mddev->private;
struct bio *bio;
- if (from_schedule) {
+ if (from_schedule || current->bio_list) {
spin_lock_irq(&conf->device_lock);
bio_list_merge(&conf->pending_bio_list, &plug->pending);
conf->pending_count += plug->pending_cnt;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index d1295aff417..c9acbd71713 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -499,7 +499,7 @@ static void raid10_end_write_request(struct bio *bio, int error)
*/
one_write_done(r10_bio);
if (dec_rdev)
- rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev);
+ rdev_dec_pending(rdev, conf->mddev);
}
/*
@@ -1069,7 +1069,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
struct r10conf *conf = mddev->private;
struct bio *bio;
- if (from_schedule) {
+ if (from_schedule || current->bio_list) {
spin_lock_irq(&conf->device_lock);
bio_list_merge(&conf->pending_bio_list, &plug->pending);
conf->pending_count += plug->pending_cnt;
@@ -1334,18 +1334,21 @@ retry_write:
blocked_rdev = rrdev;
break;
}
+ if (rdev && (test_bit(Faulty, &rdev->flags)
+ || test_bit(Unmerged, &rdev->flags)))
+ rdev = NULL;
if (rrdev && (test_bit(Faulty, &rrdev->flags)
|| test_bit(Unmerged, &rrdev->flags)))
rrdev = NULL;
r10_bio->devs[i].bio = NULL;
r10_bio->devs[i].repl_bio = NULL;
- if (!rdev || test_bit(Faulty, &rdev->flags) ||
- test_bit(Unmerged, &rdev->flags)) {
+
+ if (!rdev && !rrdev) {
set_bit(R10BIO_Degraded, &r10_bio->state);
continue;
}
- if (test_bit(WriteErrorSeen, &rdev->flags)) {
+ if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) {
sector_t first_bad;
sector_t dev_sector = r10_bio->devs[i].addr;
int bad_sectors;
@@ -1387,8 +1390,10 @@ retry_write:
max_sectors = good_sectors;
}
}
- r10_bio->devs[i].bio = bio;
- atomic_inc(&rdev->nr_pending);
+ if (rdev) {
+ r10_bio->devs[i].bio = bio;
+ atomic_inc(&rdev->nr_pending);
+ }
if (rrdev) {
r10_bio->devs[i].repl_bio = bio;
atomic_inc(&rrdev->nr_pending);
@@ -1444,69 +1449,71 @@ retry_write:
for (i = 0; i < conf->copies; i++) {
struct bio *mbio;
int d = r10_bio->devs[i].devnum;
- if (!r10_bio->devs[i].bio)
- continue;
+ if (r10_bio->devs[i].bio) {
+ struct md_rdev *rdev = conf->mirrors[d].rdev;
+ mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+ md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
+ max_sectors);
+ r10_bio->devs[i].bio = mbio;
+
+ mbio->bi_sector = (r10_bio->devs[i].addr+
+ choose_data_offset(r10_bio,
+ rdev));
+ mbio->bi_bdev = rdev->bdev;
+ mbio->bi_end_io = raid10_end_write_request;
+ mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
+ mbio->bi_private = r10_bio;
- mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
- md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
- max_sectors);
- r10_bio->devs[i].bio = mbio;
+ atomic_inc(&r10_bio->remaining);
- mbio->bi_sector = (r10_bio->devs[i].addr+
- choose_data_offset(r10_bio,
- conf->mirrors[d].rdev));
- mbio->bi_bdev = conf->mirrors[d].rdev->bdev;
- mbio->bi_end_io = raid10_end_write_request;
- mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
- mbio->bi_private = r10_bio;
+ cb = blk_check_plugged(raid10_unplug, mddev,
+ sizeof(*plug));
+ if (cb)
+ plug = container_of(cb, struct raid10_plug_cb,
+ cb);
+ else
+ plug = NULL;
+ spin_lock_irqsave(&conf->device_lock, flags);
+ if (plug) {
+ bio_list_add(&plug->pending, mbio);
+ plug->pending_cnt++;
+ } else {
+ bio_list_add(&conf->pending_bio_list, mbio);
+ conf->pending_count++;
+ }
+ spin_unlock_irqrestore(&conf->device_lock, flags);
+ if (!plug)
+ md_wakeup_thread(mddev->thread);
+ }
- atomic_inc(&r10_bio->remaining);
+ if (r10_bio->devs[i].repl_bio) {
+ struct md_rdev *rdev = conf->mirrors[d].replacement;
+ if (rdev == NULL) {
+ /* Replacement just got moved to main 'rdev' */
+ smp_mb();
+ rdev = conf->mirrors[d].rdev;
+ }
+ mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+ md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
+ max_sectors);
+ r10_bio->devs[i].repl_bio = mbio;
+
+ mbio->bi_sector = (r10_bio->devs[i].addr +
+ choose_data_offset(
+ r10_bio, rdev));
+ mbio->bi_bdev = rdev->bdev;
+ mbio->bi_end_io = raid10_end_write_request;
+ mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
+ mbio->bi_private = r10_bio;
- cb = blk_check_plugged(raid10_unplug, mddev, sizeof(*plug));
- if (cb)
- plug = container_of(cb, struct raid10_plug_cb, cb);
- else
- plug = NULL;
- spin_lock_irqsave(&conf->device_lock, flags);
- if (plug) {
- bio_list_add(&plug->pending, mbio);
- plug->pending_cnt++;
- } else {
+ atomic_inc(&r10_bio->remaining);
+ spin_lock_irqsave(&conf->device_lock, flags);
bio_list_add(&conf->pending_bio_list, mbio);
conf->pending_count++;
+ spin_unlock_irqrestore(&conf->device_lock, flags);
+ if (!mddev_check_plugged(mddev))
+ md_wakeup_thread(mddev->thread);
}
- spin_unlock_irqrestore(&conf->device_lock, flags);
- if (!plug)
- md_wakeup_thread(mddev->thread);
-
- if (!r10_bio->devs[i].repl_bio)
- continue;
-
- mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
- md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
- max_sectors);
- r10_bio->devs[i].repl_bio = mbio;
-
- /* We are actively writing to the original device
- * so it cannot disappear, so the replacement cannot
- * become NULL here
- */
- mbio->bi_sector = (r10_bio->devs[i].addr +
- choose_data_offset(
- r10_bio,
- conf->mirrors[d].replacement));
- mbio->bi_bdev = conf->mirrors[d].replacement->bdev;
- mbio->bi_end_io = raid10_end_write_request;
- mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
- mbio->bi_private = r10_bio;
-
- atomic_inc(&r10_bio->remaining);
- spin_lock_irqsave(&conf->device_lock, flags);
- bio_list_add(&conf->pending_bio_list, mbio);
- conf->pending_count++;
- spin_unlock_irqrestore(&conf->device_lock, flags);
- if (!mddev_check_plugged(mddev))
- md_wakeup_thread(mddev->thread);
}
/* Don't remove the bias on 'remaining' (one_write_done) until
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index c5439dce029..a4502686e7a 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2774,10 +2774,12 @@ static void handle_stripe_clean_event(struct r5conf *conf,
dev = &sh->dev[i];
if (!test_bit(R5_LOCKED, &dev->flags) &&
(test_bit(R5_UPTODATE, &dev->flags) ||
- test_and_clear_bit(R5_Discard, &dev->flags))) {
+ test_bit(R5_Discard, &dev->flags))) {
/* We can return any write requests */
struct bio *wbi, *wbi2;
pr_debug("Return write for disc %d\n", i);
+ if (test_and_clear_bit(R5_Discard, &dev->flags))
+ clear_bit(R5_UPTODATE, &dev->flags);
wbi = dev->written;
dev->written = NULL;
while (wbi && wbi->bi_sector <
@@ -2795,7 +2797,8 @@ static void handle_stripe_clean_event(struct r5conf *conf,
!test_bit(STRIPE_DEGRADED, &sh->state),
0);
}
- }
+ } else if (test_bit(R5_Discard, &sh->dev[i].flags))
+ clear_bit(R5_Discard, &sh->dev[i].flags);
if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state))
if (atomic_dec_and_test(&conf->pending_full_writes))
@@ -3490,40 +3493,6 @@ static void handle_stripe(struct stripe_head *sh)
handle_failed_sync(conf, sh, &s);
}
- /*
- * might be able to return some write requests if the parity blocks
- * are safe, or on a failed drive
- */
- pdev = &sh->dev[sh->pd_idx];
- s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx)
- || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx);
- qdev = &sh->dev[sh->qd_idx];
- s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx)
- || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx)
- || conf->level < 6;
-
- if (s.written &&
- (s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
- && !test_bit(R5_LOCKED, &pdev->flags)
- && (test_bit(R5_UPTODATE, &pdev->flags) ||
- test_bit(R5_Discard, &pdev->flags))))) &&
- (s.q_failed || ((test_bit(R5_Insync, &qdev->flags)
- && !test_bit(R5_LOCKED, &qdev->flags)
- && (test_bit(R5_UPTODATE, &qdev->flags) ||
- test_bit(R5_Discard, &qdev->flags))))))
- handle_stripe_clean_event(conf, sh, disks, &s.return_bi);
-
- /* Now we might consider reading some blocks, either to check/generate
- * parity, or to satisfy requests
- * or to load a block that is being partially written.
- */
- if (s.to_read || s.non_overwrite
- || (conf->level == 6 && s.to_write && s.failed)
- || (s.syncing && (s.uptodate + s.compute < disks))
- || s.replacing
- || s.expanding)
- handle_stripe_fill(sh, &s, disks);
-
/* Now we check to see if any write operations have recently
* completed
*/
@@ -3561,6 +3530,40 @@ static void handle_stripe(struct stripe_head *sh)
s.dec_preread_active = 1;
}
+ /*
+ * might be able to return some write requests if the parity blocks
+ * are safe, or on a failed drive
+ */
+ pdev = &sh->dev[sh->pd_idx];
+ s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx)
+ || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx);
+ qdev = &sh->dev[sh->qd_idx];
+ s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx)
+ || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx)
+ || conf->level < 6;
+
+ if (s.written &&
+ (s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
+ && !test_bit(R5_LOCKED, &pdev->flags)
+ && (test_bit(R5_UPTODATE, &pdev->flags) ||
+ test_bit(R5_Discard, &pdev->flags))))) &&
+ (s.q_failed || ((test_bit(R5_Insync, &qdev->flags)
+ && !test_bit(R5_LOCKED, &qdev->flags)
+ && (test_bit(R5_UPTODATE, &qdev->flags) ||
+ test_bit(R5_Discard, &qdev->flags))))))
+ handle_stripe_clean_event(conf, sh, disks, &s.return_bi);
+
+ /* Now we might consider reading some blocks, either to check/generate
+ * parity, or to satisfy requests
+ * or to load a block that is being partially written.
+ */
+ if (s.to_read || s.non_overwrite
+ || (conf->level == 6 && s.to_write && s.failed)
+ || (s.syncing && (s.uptodate + s.compute < disks))
+ || s.replacing
+ || s.expanding)
+ handle_stripe_fill(sh, &s, disks);
+
/* Now to consider new write requests and what else, if anything
* should be read. We do not handle new writes when:
* 1/ A 'write' operation (copy+xor) is already in flight.
@@ -5529,6 +5532,10 @@ static int run(struct mddev *mddev)
* discard data disk but write parity disk
*/
stripe = stripe * PAGE_SIZE;
+ /* Round up to power of 2, as discard handling
+ * currently assumes that */
+ while ((stripe-1) & stripe)
+ stripe = (stripe | (stripe-1)) + 1;
mddev->queue->limits.discard_alignment = stripe;
mddev->queue->limits.discard_granularity = stripe;
/*
diff --git a/drivers/media/dvb-frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c
index 262dfa503c2..b551ca350e0 100644
--- a/drivers/media/dvb-frontends/stv0900_core.c
+++ b/drivers/media/dvb-frontends/stv0900_core.c
@@ -300,15 +300,15 @@ static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32
{
u32 m_div, clk_sel;
- dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
- intp->quartz);
-
if (intp == NULL)
return STV0900_INVALID_HANDLE;
if (intp->errs)
return STV0900_I2C_ERROR;
+ dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
+ intp->quartz);
+
clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
m_div = ((clk_sel * mclk) / intp->quartz) - 1;
stv0900_write_bits(intp, F0900_M_DIV, m_div);
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 109bc9b12e7..05f8950f6f9 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -53,8 +53,7 @@ MODULE_LICENSE("GPL");
/* ADV7604 system clock frequency */
#define ADV7604_fsc (28636360)
-#define DIGITAL_INPUT ((state->prim_mode == ADV7604_PRIM_MODE_HDMI_COMP) || \
- (state->prim_mode == ADV7604_PRIM_MODE_HDMI_GR))
+#define DIGITAL_INPUT (state->mode == ADV7604_MODE_HDMI)
/*
**********************************************************************
@@ -68,7 +67,7 @@ struct adv7604_state {
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_ctrl_handler hdl;
- enum adv7604_prim_mode prim_mode;
+ enum adv7604_mode mode;
struct v4l2_dv_timings timings;
u8 edid[256];
unsigned edid_blocks;
@@ -77,6 +76,7 @@ struct adv7604_state {
struct workqueue_struct *work_queues;
struct delayed_work delayed_work_enable_hotplug;
bool connector_hdmi;
+ bool restart_stdi_once;
/* i2c clients */
struct i2c_client *i2c_avlink;
@@ -106,7 +106,6 @@ static const struct v4l2_dv_timings adv7604_timings[] = {
V4L2_DV_BT_CEA_720X576P50,
V4L2_DV_BT_CEA_1280X720P24,
V4L2_DV_BT_CEA_1280X720P25,
- V4L2_DV_BT_CEA_1280X720P30,
V4L2_DV_BT_CEA_1280X720P50,
V4L2_DV_BT_CEA_1280X720P60,
V4L2_DV_BT_CEA_1920X1080P24,
@@ -115,6 +114,7 @@ static const struct v4l2_dv_timings adv7604_timings[] = {
V4L2_DV_BT_CEA_1920X1080P50,
V4L2_DV_BT_CEA_1920X1080P60,
+ /* sorted by DMT ID */
V4L2_DV_BT_DMT_640X350P85,
V4L2_DV_BT_DMT_640X400P85,
V4L2_DV_BT_DMT_720X400P85,
@@ -164,6 +164,89 @@ static const struct v4l2_dv_timings adv7604_timings[] = {
{ },
};
+struct adv7604_video_standards {
+ struct v4l2_dv_timings timings;
+ u8 vid_std;
+ u8 v_freq;
+};
+
+/* sorted by number of lines */
+static const struct adv7604_video_standards adv7604_prim_mode_comp[] = {
+ /* { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, TODO flickering */
+ { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 },
+ { V4L2_DV_BT_CEA_1280X720P50, 0x19, 0x01 },
+ { V4L2_DV_BT_CEA_1280X720P60, 0x19, 0x00 },
+ { V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 },
+ { V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 },
+ { V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 },
+ { V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 },
+ { V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 },
+ /* TODO add 1920x1080P60_RB (CVT timing) */
+ { },
+};
+
+/* sorted by number of lines */
+static const struct adv7604_video_standards adv7604_prim_mode_gr[] = {
+ { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 },
+ { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 },
+ { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 },
+ { V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 },
+ { V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 },
+ { V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 },
+ { V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 },
+ { V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 },
+ { V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 },
+ { V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 },
+ { V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 },
+ { V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 },
+ { V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 },
+ { V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 },
+ { V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 },
+ { V4L2_DV_BT_DMT_1360X768P60, 0x12, 0x00 },
+ { V4L2_DV_BT_DMT_1366X768P60, 0x13, 0x00 },
+ { V4L2_DV_BT_DMT_1400X1050P60, 0x14, 0x00 },
+ { V4L2_DV_BT_DMT_1400X1050P75, 0x15, 0x00 },
+ { V4L2_DV_BT_DMT_1600X1200P60, 0x16, 0x00 }, /* TODO not tested */
+ /* TODO add 1600X1200P60_RB (not a DMT timing) */
+ { V4L2_DV_BT_DMT_1680X1050P60, 0x18, 0x00 },
+ { V4L2_DV_BT_DMT_1920X1200P60_RB, 0x19, 0x00 }, /* TODO not tested */
+ { },
+};
+
+/* sorted by number of lines */
+static const struct adv7604_video_standards adv7604_prim_mode_hdmi_comp[] = {
+ { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 },
+ { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 },
+ { V4L2_DV_BT_CEA_1280X720P50, 0x13, 0x01 },
+ { V4L2_DV_BT_CEA_1280X720P60, 0x13, 0x00 },
+ { V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 },
+ { V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 },
+ { V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 },
+ { V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 },
+ { V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 },
+ { },
+};
+
+/* sorted by number of lines */
+static const struct adv7604_video_standards adv7604_prim_mode_hdmi_gr[] = {
+ { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 },
+ { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 },
+ { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 },
+ { V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 },
+ { V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 },
+ { V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 },
+ { V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 },
+ { V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 },
+ { V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 },
+ { V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 },
+ { V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 },
+ { V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 },
+ { V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 },
+ { V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 },
+ { V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 },
+ { },
+};
+
/* ----------------------------------------------------------------------- */
static inline struct adv7604_state *to_state(struct v4l2_subdev *sd)
@@ -672,64 +755,144 @@ static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd)
((io_read(sd, 0x6f) & 0x10) >> 4));
}
-static void configure_free_run(struct v4l2_subdev *sd, const struct v4l2_bt_timings *timings)
+static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd,
+ u8 prim_mode,
+ const struct adv7604_video_standards *predef_vid_timings,
+ const struct v4l2_dv_timings *timings)
+{
+ struct adv7604_state *state = to_state(sd);
+ int i;
+
+ for (i = 0; predef_vid_timings[i].timings.bt.width; i++) {
+ if (!v4l_match_dv_timings(timings, &predef_vid_timings[i].timings,
+ DIGITAL_INPUT ? 250000 : 1000000))
+ continue;
+ io_write(sd, 0x00, predef_vid_timings[i].vid_std); /* video std */
+ io_write(sd, 0x01, (predef_vid_timings[i].v_freq << 4) +
+ prim_mode); /* v_freq and prim mode */
+ return 0;
+ }
+
+ return -1;
+}
+
+static int configure_predefined_video_timings(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings *timings)
{
+ struct adv7604_state *state = to_state(sd);
+ int err;
+
+ v4l2_dbg(1, debug, sd, "%s", __func__);
+
+ /* reset to default values */
+ io_write(sd, 0x16, 0x43);
+ io_write(sd, 0x17, 0x5a);
+ /* disable embedded syncs for auto graphics mode */
+ cp_write_and_or(sd, 0x81, 0xef, 0x00);
+ cp_write(sd, 0x8f, 0x00);
+ cp_write(sd, 0x90, 0x00);
+ cp_write(sd, 0xa2, 0x00);
+ cp_write(sd, 0xa3, 0x00);
+ cp_write(sd, 0xa4, 0x00);
+ cp_write(sd, 0xa5, 0x00);
+ cp_write(sd, 0xa6, 0x00);
+ cp_write(sd, 0xa7, 0x00);
+ cp_write(sd, 0xab, 0x00);
+ cp_write(sd, 0xac, 0x00);
+
+ switch (state->mode) {
+ case ADV7604_MODE_COMP:
+ case ADV7604_MODE_GR:
+ err = find_and_set_predefined_video_timings(sd,
+ 0x01, adv7604_prim_mode_comp, timings);
+ if (err)
+ err = find_and_set_predefined_video_timings(sd,
+ 0x02, adv7604_prim_mode_gr, timings);
+ break;
+ case ADV7604_MODE_HDMI:
+ err = find_and_set_predefined_video_timings(sd,
+ 0x05, adv7604_prim_mode_hdmi_comp, timings);
+ if (err)
+ err = find_and_set_predefined_video_timings(sd,
+ 0x06, adv7604_prim_mode_hdmi_gr, timings);
+ break;
+ default:
+ v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
+ __func__, state->mode);
+ err = -1;
+ break;
+ }
+
+
+ return err;
+}
+
+static void configure_custom_video_timings(struct v4l2_subdev *sd,
+ const struct v4l2_bt_timings *bt)
+{
+ struct adv7604_state *state = to_state(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- u32 width = htotal(timings);
- u32 height = vtotal(timings);
- u16 ch1_fr_ll = (((u32)timings->pixelclock / 100) > 0) ?
- ((width * (ADV7604_fsc / 100)) / ((u32)timings->pixelclock / 100)) : 0;
+ u32 width = htotal(bt);
+ u32 height = vtotal(bt);
+ u16 cp_start_sav = bt->hsync + bt->hbackporch - 4;
+ u16 cp_start_eav = width - bt->hfrontporch;
+ u16 cp_start_vbi = height - bt->vfrontporch;
+ u16 cp_end_vbi = bt->vsync + bt->vbackporch;
+ u16 ch1_fr_ll = (((u32)bt->pixelclock / 100) > 0) ?
+ ((width * (ADV7604_fsc / 100)) / ((u32)bt->pixelclock / 100)) : 0;
+ const u8 pll[2] = {
+ 0xc0 | ((width >> 8) & 0x1f),
+ width & 0xff
+ };
v4l2_dbg(2, debug, sd, "%s\n", __func__);
- cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7); /* CH1_FR_LL */
- cp_write(sd, 0x90, ch1_fr_ll & 0xff); /* CH1_FR_LL */
- cp_write(sd, 0xab, (height >> 4) & 0xff); /* CP_LCOUNT_MAX */
- cp_write(sd, 0xac, (height & 0x0f) << 4); /* CP_LCOUNT_MAX */
- /* TODO support interlaced */
- cp_write(sd, 0x91, 0x10); /* INTERLACED */
-
- /* Should only be set in auto-graphics mode [REF_02 p. 91-92] */
- if ((io_read(sd, 0x00) == 0x07) && (io_read(sd, 0x01) == 0x02)) {
- u16 cp_start_sav, cp_start_eav, cp_start_vbi, cp_end_vbi;
- const u8 pll[2] = {
- (0xc0 | ((width >> 8) & 0x1f)),
- (width & 0xff)
- };
+ switch (state->mode) {
+ case ADV7604_MODE_COMP:
+ case ADV7604_MODE_GR:
+ /* auto graphics */
+ io_write(sd, 0x00, 0x07); /* video std */
+ io_write(sd, 0x01, 0x02); /* prim mode */
+ /* enable embedded syncs for auto graphics mode */
+ cp_write_and_or(sd, 0x81, 0xef, 0x10);
+ /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */
/* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */
/* IO-map reg. 0x16 and 0x17 should be written in sequence */
if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) {
v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n");
- return;
+ break;
}
/* active video - horizontal timing */
- cp_start_sav = timings->hsync + timings->hbackporch - 4;
- cp_start_eav = width - timings->hfrontporch;
cp_write(sd, 0xa2, (cp_start_sav >> 4) & 0xff);
- cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) | ((cp_start_eav >> 8) & 0x0f));
+ cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) |
+ ((cp_start_eav >> 8) & 0x0f));
cp_write(sd, 0xa4, cp_start_eav & 0xff);
/* active video - vertical timing */
- cp_start_vbi = height - timings->vfrontporch;
- cp_end_vbi = timings->vsync + timings->vbackporch;
cp_write(sd, 0xa5, (cp_start_vbi >> 4) & 0xff);
- cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) | ((cp_end_vbi >> 8) & 0xf));
+ cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) |
+ ((cp_end_vbi >> 8) & 0xf));
cp_write(sd, 0xa7, cp_end_vbi & 0xff);
- } else {
- /* reset to default values */
- io_write(sd, 0x16, 0x43);
- io_write(sd, 0x17, 0x5a);
- cp_write(sd, 0xa2, 0x00);
- cp_write(sd, 0xa3, 0x00);
- cp_write(sd, 0xa4, 0x00);
- cp_write(sd, 0xa5, 0x00);
- cp_write(sd, 0xa6, 0x00);
- cp_write(sd, 0xa7, 0x00);
+ break;
+ case ADV7604_MODE_HDMI:
+ /* set default prim_mode/vid_std for HDMI
+ accoring to [REF_03, c. 4.2] */
+ io_write(sd, 0x00, 0x02); /* video std */
+ io_write(sd, 0x01, 0x06); /* prim mode */
+ break;
+ default:
+ v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
+ __func__, state->mode);
+ break;
}
-}
+ cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7);
+ cp_write(sd, 0x90, ch1_fr_ll & 0xff);
+ cp_write(sd, 0xab, (height >> 4) & 0xff);
+ cp_write(sd, 0xac, (height & 0x0f) << 4);
+}
static void set_rgb_quantization_range(struct v4l2_subdev *sd)
{
@@ -738,12 +901,7 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
switch (state->rgb_quantization_range) {
case V4L2_DV_RGB_RANGE_AUTO:
/* automatic */
- if ((hdmi_read(sd, 0x05) & 0x80) ||
- (state->prim_mode == ADV7604_PRIM_MODE_COMP) ||
- (state->prim_mode == ADV7604_PRIM_MODE_RGB)) {
- /* receiving HDMI or analog signal */
- io_write_and_or(sd, 0x02, 0x0f, 0xf0);
- } else {
+ if (DIGITAL_INPUT && !(hdmi_read(sd, 0x05) & 0x80)) {
/* receiving DVI-D signal */
/* ADV7604 selects RGB limited range regardless of
@@ -756,6 +914,9 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
/* RGB full range (0-255) */
io_write_and_or(sd, 0x02, 0x0f, 0x10);
}
+ } else {
+ /* receiving HDMI or analog signal, set automode */
+ io_write_and_or(sd, 0x02, 0x0f, 0xf0);
}
break;
case V4L2_DV_RGB_RANGE_LIMITED:
@@ -967,8 +1128,10 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
state->aspect_ratio, timings))
return 0;
- v4l2_dbg(2, debug, sd, "%s: No format candidate found for lcf=%d, bl = %d\n",
- __func__, stdi->lcf, stdi->bl);
+ v4l2_dbg(2, debug, sd,
+ "%s: No format candidate found for lcvs = %d, lcf=%d, bl = %d, %chsync, %cvsync\n",
+ __func__, stdi->lcvs, stdi->lcf, stdi->bl,
+ stdi->hs_pol, stdi->vs_pol);
return -1;
}
@@ -1123,7 +1286,7 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
adv7604_fill_optional_dv_timings_fields(sd, timings);
} else {
/* find format
- * Since LCVS values are inaccurate (REF_03, page 275-276),
+ * Since LCVS values are inaccurate [REF_03, p. 275-276],
* stdi2dv_timings() is called with lcvs +-1 if the first attempt fails.
*/
if (!stdi2dv_timings(sd, &stdi, timings))
@@ -1135,9 +1298,31 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
stdi.lcvs -= 2;
v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs);
if (stdi2dv_timings(sd, &stdi, timings)) {
+ /*
+ * The STDI block may measure wrong values, especially
+ * for lcvs and lcf. If the driver can not find any
+ * valid timing, the STDI block is restarted to measure
+ * the video timings again. The function will return an
+ * error, but the restart of STDI will generate a new
+ * STDI interrupt and the format detection process will
+ * restart.
+ */
+ if (state->restart_stdi_once) {
+ v4l2_dbg(1, debug, sd, "%s: restart STDI\n", __func__);
+ /* TODO restart STDI for Sync Channel 2 */
+ /* enter one-shot mode */
+ cp_write_and_or(sd, 0x86, 0xf9, 0x00);
+ /* trigger STDI restart */
+ cp_write_and_or(sd, 0x86, 0xf9, 0x04);
+ /* reset to continuous mode */
+ cp_write_and_or(sd, 0x86, 0xf9, 0x02);
+ state->restart_stdi_once = false;
+ return -ENOLINK;
+ }
v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__);
return -ERANGE;
}
+ state->restart_stdi_once = true;
}
found:
@@ -1166,6 +1351,7 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd,
{
struct adv7604_state *state = to_state(sd);
struct v4l2_bt_timings *bt;
+ int err;
if (!timings)
return -EINVAL;
@@ -1178,12 +1364,20 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd,
__func__, (u32)bt->pixelclock);
return -ERANGE;
}
+
adv7604_fill_optional_dv_timings_fields(sd, timings);
state->timings = *timings;
- /* freerun */
- configure_free_run(sd, bt);
+ cp_write(sd, 0x91, bt->interlaced ? 0x50 : 0x10);
+
+ /* Use prim_mode and vid_std when available */
+ err = configure_predefined_video_timings(sd, timings);
+ if (err) {
+ /* custom settings when the video format
+ does not have prim_mode/vid_std */
+ configure_custom_video_timings(sd, bt);
+ }
set_rgb_quantization_range(sd);
@@ -1203,24 +1397,25 @@ static int adv7604_g_dv_timings(struct v4l2_subdev *sd,
return 0;
}
-static void enable_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode)
+static void enable_input(struct v4l2_subdev *sd)
{
- switch (prim_mode) {
- case ADV7604_PRIM_MODE_COMP:
- case ADV7604_PRIM_MODE_RGB:
+ struct adv7604_state *state = to_state(sd);
+
+ switch (state->mode) {
+ case ADV7604_MODE_COMP:
+ case ADV7604_MODE_GR:
/* enable */
io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */
break;
- case ADV7604_PRIM_MODE_HDMI_COMP:
- case ADV7604_PRIM_MODE_HDMI_GR:
+ case ADV7604_MODE_HDMI:
/* enable */
hdmi_write(sd, 0x1a, 0x0a); /* Unmute audio */
hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */
io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */
break;
default:
- v4l2_err(sd, "%s: reserved primary mode 0x%0x\n",
- __func__, prim_mode);
+ v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
+ __func__, state->mode);
break;
}
}
@@ -1233,17 +1428,13 @@ static void disable_input(struct v4l2_subdev *sd)
hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */
}
-static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode)
+static void select_input(struct v4l2_subdev *sd)
{
- switch (prim_mode) {
- case ADV7604_PRIM_MODE_COMP:
- case ADV7604_PRIM_MODE_RGB:
- /* set mode and select free run resolution */
- io_write(sd, 0x00, 0x07); /* video std */
- io_write(sd, 0x01, 0x02); /* prim mode */
- /* enable embedded syncs for auto graphics mode */
- cp_write_and_or(sd, 0x81, 0xef, 0x10);
+ struct adv7604_state *state = to_state(sd);
+ switch (state->mode) {
+ case ADV7604_MODE_COMP:
+ case ADV7604_MODE_GR:
/* reset ADI recommended settings for HDMI: */
/* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
hdmi_write(sd, 0x0d, 0x04); /* HDMI filter optimization */
@@ -1271,16 +1462,7 @@ static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mod
cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */
break;
- case ADV7604_PRIM_MODE_HDMI_COMP:
- case ADV7604_PRIM_MODE_HDMI_GR:
- /* set mode and select free run resolution */
- /* video std */
- io_write(sd, 0x00,
- (prim_mode == ADV7604_PRIM_MODE_HDMI_GR) ? 0x02 : 0x1e);
- io_write(sd, 0x01, prim_mode); /* prim mode */
- /* disable embedded syncs for auto graphics mode */
- cp_write_and_or(sd, 0x81, 0xef, 0x00);
-
+ case ADV7604_MODE_HDMI:
/* set ADI recommended settings for HDMI: */
/* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
hdmi_write(sd, 0x0d, 0x84); /* HDMI filter optimization */
@@ -1309,7 +1491,8 @@ static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mod
break;
default:
- v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", __func__, prim_mode);
+ v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
+ __func__, state->mode);
break;
}
}
@@ -1321,26 +1504,13 @@ static int adv7604_s_routing(struct v4l2_subdev *sd,
v4l2_dbg(2, debug, sd, "%s: input %d", __func__, input);
- switch (input) {
- case 0:
- /* TODO select HDMI_COMP or HDMI_GR */
- state->prim_mode = ADV7604_PRIM_MODE_HDMI_COMP;
- break;
- case 1:
- state->prim_mode = ADV7604_PRIM_MODE_RGB;
- break;
- case 2:
- state->prim_mode = ADV7604_PRIM_MODE_COMP;
- break;
- default:
- return -EINVAL;
- }
+ state->mode = input;
disable_input(sd);
- select_input(sd, state->prim_mode);
+ select_input(sd);
- enable_input(sd, state->prim_mode);
+ enable_input(sd);
return 0;
}
@@ -1549,8 +1719,9 @@ static int adv7604_log_status(struct v4l2_subdev *sd)
v4l2_info(sd, "CP locked: %s\n", no_lock_cp(sd) ? "false" : "true");
v4l2_info(sd, "CP free run: %s\n",
(!!(cp_read(sd, 0xff) & 0x10) ? "on" : "off"));
- v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x\n",
- io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f);
+ v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x, v_freq = 0x%x\n",
+ io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f,
+ (io_read(sd, 0x01) & 0x70) >> 4);
v4l2_info(sd, "-----Video Timings-----\n");
if (read_stdi(sd, &stdi))
@@ -1712,9 +1883,9 @@ static int adv7604_core_init(struct v4l2_subdev *sd)
cp_write(sd, 0xba, (pdata->hdmi_free_run_mode << 1) | 0x01); /* HDMI free run */
cp_write(sd, 0xf3, 0xdc); /* Low threshold to enter/exit free run mode */
cp_write(sd, 0xf9, 0x23); /* STDI ch. 1 - LCVS change threshold -
- ADI recommended setting [REF_01 c. 2.3.3] */
+ ADI recommended setting [REF_01, c. 2.3.3] */
cp_write(sd, 0x45, 0x23); /* STDI ch. 2 - LCVS change threshold -
- ADI recommended setting [REF_01 c. 2.3.3] */
+ ADI recommended setting [REF_01, c. 2.3.3] */
cp_write(sd, 0xc9, 0x2d); /* use prim_mode and vid_std as free run resolution
for digital formats */
@@ -1724,11 +1895,6 @@ static int adv7604_core_init(struct v4l2_subdev *sd)
afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */
io_write_and_or(sd, 0x30, ~(1 << 4), pdata->output_bus_lsb_to_msb << 4);
- state->prim_mode = pdata->prim_mode;
- select_input(sd, pdata->prim_mode);
-
- enable_input(sd, pdata->prim_mode);
-
/* interrupts */
io_write(sd, 0x40, 0xc2); /* Configure INT1 */
io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */
@@ -1883,6 +2049,7 @@ static int adv7604_probe(struct i2c_client *client,
v4l2_err(sd, "failed to create all i2c clients\n");
goto err_i2c;
}
+ state->restart_stdi_once = true;
/* work queues */
state->work_queues = create_singlethread_workqueue(client->name);
diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c
index 13057b966ee..333ef178d6f 100644
--- a/drivers/media/i2c/soc_camera/mt9v022.c
+++ b/drivers/media/i2c/soc_camera/mt9v022.c
@@ -263,9 +263,14 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
if (ret & 1) /* Autoexposure */
ret = reg_write(client, mt9v022->reg->max_total_shutter_width,
rect.height + mt9v022->y_skip_top + 43);
- else
- ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
- rect.height + mt9v022->y_skip_top + 43);
+ /*
+ * If autoexposure is off, there is no need to set
+ * MT9V022_TOTAL_SHUTTER_WIDTH here. Autoexposure can be off
+ * only if the user has set exposure manually, using the
+ * V4L2_CID_EXPOSURE_AUTO with the value V4L2_EXPOSURE_MANUAL.
+ * In this case the register MT9V022_TOTAL_SHUTTER_WIDTH
+ * already contains the correct value.
+ */
}
/* Setup frame format: defaults apart from width and height */
if (!ret)
diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c
index bfec9e65aef..19cbb12a12a 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -965,8 +965,10 @@ static struct platform_device_id gsc_driver_ids[] = {
MODULE_DEVICE_TABLE(platform, gsc_driver_ids);
static const struct of_device_id exynos_gsc_match[] = {
- { .compatible = "samsung,exynos5250-gsc",
- .data = &gsc_v_100_drvdata, },
+ {
+ .compatible = "samsung,exynos5-gsc",
+ .data = &gsc_v_100_drvdata,
+ },
{},
};
MODULE_DEVICE_TABLE(of, exynos_gsc_match);
diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c
index 3c7f00577bd..c065d040ed9 100644
--- a/drivers/media/platform/exynos-gsc/gsc-m2m.c
+++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c
@@ -657,8 +657,7 @@ static int gsc_m2m_release(struct file *file)
pr_debug("pid: %d, state: 0x%lx, refcnt= %d",
task_pid_nr(current), gsc->state, gsc->m2m.refcnt);
- if (mutex_lock_interruptible(&gsc->lock))
- return -ERESTARTSYS;
+ mutex_lock(&gsc->lock);
v4l2_m2m_ctx_release(ctx->m2m_ctx);
gsc_ctrls_delete(ctx);
@@ -732,6 +731,7 @@ int gsc_register_m2m_device(struct gsc_dev *gsc)
gsc->vdev.ioctl_ops = &gsc_m2m_ioctl_ops;
gsc->vdev.release = video_device_release_empty;
gsc->vdev.lock = &gsc->lock;
+ gsc->vdev.vfl_dir = VFL_DIR_M2M;
snprintf(gsc->vdev.name, sizeof(gsc->vdev.name), "%s.%d:m2m",
GSC_MODULE_NAME, gsc->id);
diff --git a/drivers/media/platform/exynos-gsc/gsc-regs.h b/drivers/media/platform/exynos-gsc/gsc-regs.h
index 533e9947a92..4678f9a6a4f 100644
--- a/drivers/media/platform/exynos-gsc/gsc-regs.h
+++ b/drivers/media/platform/exynos-gsc/gsc-regs.h
@@ -40,10 +40,10 @@
#define GSC_IN_ROT_YFLIP (2 << 16)
#define GSC_IN_ROT_XFLIP (1 << 16)
#define GSC_IN_RGB_TYPE_MASK (3 << 14)
-#define GSC_IN_RGB_HD_WIDE (3 << 14)
-#define GSC_IN_RGB_HD_NARROW (2 << 14)
-#define GSC_IN_RGB_SD_WIDE (1 << 14)
-#define GSC_IN_RGB_SD_NARROW (0 << 14)
+#define GSC_IN_RGB_HD_NARROW (3 << 14)
+#define GSC_IN_RGB_HD_WIDE (2 << 14)
+#define GSC_IN_RGB_SD_NARROW (1 << 14)
+#define GSC_IN_RGB_SD_WIDE (0 << 14)
#define GSC_IN_YUV422_1P_ORDER_MASK (1 << 13)
#define GSC_IN_YUV422_1P_ORDER_LSB_Y (0 << 13)
#define GSC_IN_YUV422_1P_OEDER_LSB_C (1 << 13)
@@ -85,10 +85,10 @@
#define GSC_OUT_GLOBAL_ALPHA_MASK (0xff << 24)
#define GSC_OUT_GLOBAL_ALPHA(x) ((x) << 24)
#define GSC_OUT_RGB_TYPE_MASK (3 << 10)
-#define GSC_OUT_RGB_HD_NARROW (3 << 10)
-#define GSC_OUT_RGB_HD_WIDE (2 << 10)
-#define GSC_OUT_RGB_SD_NARROW (1 << 10)
-#define GSC_OUT_RGB_SD_WIDE (0 << 10)
+#define GSC_OUT_RGB_HD_WIDE (3 << 10)
+#define GSC_OUT_RGB_HD_NARROW (2 << 10)
+#define GSC_OUT_RGB_SD_WIDE (1 << 10)
+#define GSC_OUT_RGB_SD_NARROW (0 << 10)
#define GSC_OUT_YUV422_1P_ORDER_MASK (1 << 9)
#define GSC_OUT_YUV422_1P_ORDER_LSB_Y (0 << 9)
#define GSC_OUT_YUV422_1P_OEDER_LSB_C (1 << 9)
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index 60181ab9606..aa9df9d71a7 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -1706,7 +1706,7 @@ static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
}
static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
- const struct v4l2_event_subscription *sub)
+ struct v4l2_event_subscription *sub)
{
if (sub->type != V4L2_EVENT_FRAME_SYNC)
return -EINVAL;
@@ -1719,7 +1719,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
}
static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
- const struct v4l2_event_subscription *sub)
+ struct v4l2_event_subscription *sub)
{
return v4l2_event_unsubscribe(fh, sub);
}
diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c
index d7ac76b5c2a..b8640be692f 100644
--- a/drivers/media/platform/omap3isp/ispstat.c
+++ b/drivers/media/platform/omap3isp/ispstat.c
@@ -1025,7 +1025,7 @@ void omap3isp_stat_dma_isr(struct ispstat *stat)
int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
struct v4l2_fh *fh,
- const struct v4l2_event_subscription *sub)
+ struct v4l2_event_subscription *sub)
{
struct ispstat *stat = v4l2_get_subdevdata(subdev);
@@ -1037,7 +1037,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
struct v4l2_fh *fh,
- const struct v4l2_event_subscription *sub)
+ struct v4l2_event_subscription *sub)
{
return v4l2_event_unsubscribe(fh, sub);
}
diff --git a/drivers/media/platform/omap3isp/ispstat.h b/drivers/media/platform/omap3isp/ispstat.h
index a6fe653eb23..9b7c8654dc8 100644
--- a/drivers/media/platform/omap3isp/ispstat.h
+++ b/drivers/media/platform/omap3isp/ispstat.h
@@ -147,10 +147,10 @@ int omap3isp_stat_init(struct ispstat *stat, const char *name,
void omap3isp_stat_cleanup(struct ispstat *stat);
int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
struct v4l2_fh *fh,
- const struct v4l2_event_subscription *sub);
+ struct v4l2_event_subscription *sub);
int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
struct v4l2_fh *fh,
- const struct v4l2_event_subscription *sub);
+ struct v4l2_event_subscription *sub);
int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable);
int omap3isp_stat_busy(struct ispstat *stat);
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index a0b737fecf1..75cd309035f 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -792,7 +792,7 @@ isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop)
}
static int
-isp_video_set_crop(struct file *file, void *fh, struct v4l2_crop *crop)
+isp_video_set_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
{
struct isp_video *video = video_drvdata(file);
struct v4l2_subdev *subdev;
diff --git a/drivers/media/platform/s5p-fimc/Kconfig b/drivers/media/platform/s5p-fimc/Kconfig
index 8f090a8f270..c16b20d86ed 100644
--- a/drivers/media/platform/s5p-fimc/Kconfig
+++ b/drivers/media/platform/s5p-fimc/Kconfig
@@ -24,6 +24,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
help
This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2
receiver (MIPI-CSIS) devices.
diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c b/drivers/media/platform/s5p-fimc/fimc-capture.c
index 367efd164d0..891ee873c62 100644
--- a/drivers/media/platform/s5p-fimc/fimc-capture.c
+++ b/drivers/media/platform/s5p-fimc/fimc-capture.c
@@ -556,8 +556,7 @@ static int fimc_capture_close(struct file *file)
dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
- if (mutex_lock_interruptible(&fimc->lock))
- return -ERESTARTSYS;
+ mutex_lock(&fimc->lock);
if (--fimc->vid_cap.refcnt == 0) {
clear_bit(ST_CAPT_BUSY, &fimc->state);
@@ -1736,7 +1735,9 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
q->mem_ops = &vb2_dma_contig_memops;
q->buf_struct_size = sizeof(struct fimc_vid_buffer);
- vb2_queue_init(q);
+ ret = vb2_queue_init(q);
+ if (ret)
+ goto err_ent;
vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
@@ -1772,9 +1773,13 @@ static int fimc_capture_subdev_registered(struct v4l2_subdev *sd)
if (ret)
return ret;
+ fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
+
ret = fimc_register_capture_device(fimc, sd->v4l2_dev);
- if (ret)
+ if (ret) {
fimc_unregister_m2m_device(fimc);
+ fimc->pipeline_ops = NULL;
+ }
return ret;
}
@@ -1791,6 +1796,7 @@ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
if (video_is_registered(&fimc->vid_cap.vfd)) {
video_unregister_device(&fimc->vid_cap.vfd);
media_entity_cleanup(&fimc->vid_cap.vfd.entity);
+ fimc->pipeline_ops = NULL;
}
kfree(fimc->vid_cap.ctx);
fimc->vid_cap.ctx = NULL;
diff --git a/drivers/media/platform/s5p-fimc/fimc-lite.c b/drivers/media/platform/s5p-fimc/fimc-lite.c
index 70bcf39de87..1b309a72f09 100644
--- a/drivers/media/platform/s5p-fimc/fimc-lite.c
+++ b/drivers/media/platform/s5p-fimc/fimc-lite.c
@@ -491,8 +491,7 @@ static int fimc_lite_close(struct file *file)
struct fimc_lite *fimc = video_drvdata(file);
int ret;
- if (mutex_lock_interruptible(&fimc->lock))
- return -ERESTARTSYS;
+ mutex_lock(&fimc->lock);
if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) {
clear_bit(ST_FLITE_IN_USE, &fimc->state);
@@ -1253,7 +1252,9 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
q->buf_struct_size = sizeof(struct flite_buffer);
q->drv_priv = fimc;
- vb2_queue_init(q);
+ ret = vb2_queue_init(q);
+ if (ret < 0)
+ return ret;
fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0);
@@ -1261,10 +1262,12 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
return ret;
video_set_drvdata(vfd, fimc);
+ fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
if (ret < 0) {
media_entity_cleanup(&vfd->entity);
+ fimc->pipeline_ops = NULL;
return ret;
}
@@ -1283,6 +1286,7 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
if (video_is_registered(&fimc->vfd)) {
video_unregister_device(&fimc->vfd);
media_entity_cleanup(&fimc->vfd.entity);
+ fimc->pipeline_ops = NULL;
}
}
diff --git a/drivers/media/platform/s5p-fimc/fimc-m2m.c b/drivers/media/platform/s5p-fimc/fimc-m2m.c
index 4500e44f685..62afed3162e 100644
--- a/drivers/media/platform/s5p-fimc/fimc-m2m.c
+++ b/drivers/media/platform/s5p-fimc/fimc-m2m.c
@@ -718,8 +718,7 @@ static int fimc_m2m_release(struct file *file)
dbg("pid: %d, state: 0x%lx, refcnt= %d",
task_pid_nr(current), fimc->state, fimc->m2m.refcnt);
- if (mutex_lock_interruptible(&fimc->lock))
- return -ERESTARTSYS;
+ mutex_lock(&fimc->lock);
v4l2_m2m_ctx_release(ctx->m2m_ctx);
fimc_ctrls_delete(ctx);
diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c
index 80ada5882f6..0531ab70a94 100644
--- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c
+++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c
@@ -343,53 +343,50 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
static int fimc_register_callback(struct device *dev, void *p)
{
struct fimc_dev *fimc = dev_get_drvdata(dev);
- struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
+ struct v4l2_subdev *sd;
struct fimc_md *fmd = p;
- int ret = 0;
-
- if (!fimc || !fimc->pdev)
- return 0;
+ int ret;
- if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS)
+ if (fimc == NULL || fimc->id >= FIMC_MAX_DEVS)
return 0;
- fimc->pipeline_ops = &fimc_pipeline_ops;
- fmd->fimc[fimc->pdev->id] = fimc;
+ sd = &fimc->vid_cap.subdev;
sd->grp_id = FIMC_GROUP_ID;
+ v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops);
ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
if (ret) {
v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.%d (%d)\n",
fimc->id, ret);
+ return ret;
}
- return ret;
+ fmd->fimc[fimc->id] = fimc;
+ return 0;
}
static int fimc_lite_register_callback(struct device *dev, void *p)
{
struct fimc_lite *fimc = dev_get_drvdata(dev);
- struct v4l2_subdev *sd = &fimc->subdev;
struct fimc_md *fmd = p;
int ret;
- if (fimc == NULL)
+ if (fimc == NULL || fimc->index >= FIMC_LITE_MAX_DEVS)
return 0;
- if (fimc->index >= FIMC_LITE_MAX_DEVS)
- return 0;
-
- fimc->pipeline_ops = &fimc_pipeline_ops;
- fmd->fimc_lite[fimc->index] = fimc;
- sd->grp_id = FLITE_GROUP_ID;
+ fimc->subdev.grp_id = FLITE_GROUP_ID;
+ v4l2_set_subdev_hostdata(&fimc->subdev, (void *)&fimc_pipeline_ops);
- ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
+ ret = v4l2_device_register_subdev(&fmd->v4l2_dev, &fimc->subdev);
if (ret) {
v4l2_err(&fmd->v4l2_dev,
"Failed to register FIMC-LITE.%d (%d)\n",
fimc->index, ret);
+ return ret;
}
- return ret;
+
+ fmd->fimc_lite[fimc->index] = fimc;
+ return 0;
}
static int csis_register_callback(struct device *dev, void *p)
@@ -407,10 +404,12 @@ static int csis_register_callback(struct device *dev, void *p)
v4l2_info(sd, "csis%d sd: %s\n", pdev->id, sd->name);
id = pdev->id < 0 ? 0 : pdev->id;
- fmd->csis[id].sd = sd;
sd->grp_id = CSIS_GROUP_ID;
+
ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
- if (ret)
+ if (!ret)
+ fmd->csis[id].sd = sd;
+ else
v4l2_err(&fmd->v4l2_dev,
"Failed to register CSIS subdevice: %d\n", ret);
return ret;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 130f4ac8649..3afe879d54d 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -381,11 +381,8 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
ctx->consumed_stream += s5p_mfc_hw_call(dev->mfc_ops,
get_consumed_stream, dev);
if (ctx->codec_mode != S5P_MFC_CODEC_H264_DEC &&
- s5p_mfc_hw_call(dev->mfc_ops,
- get_dec_frame_type, dev) ==
- S5P_FIMV_DECODE_FRAME_P_FRAME
- && ctx->consumed_stream + STUFF_BYTE <
- src_buf->b->v4l2_planes[0].bytesused) {
+ ctx->consumed_stream + STUFF_BYTE <
+ src_buf->b->v4l2_planes[0].bytesused) {
/* Run MFC again on the same buffer */
mfc_debug(2, "Running again the same buffer\n");
ctx->after_packed_pb = 1;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
index 50b5bee3c44..3a8cfd9fc1b 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
@@ -1762,7 +1762,7 @@ int s5p_mfc_get_dspl_y_adr_v6(struct s5p_mfc_dev *dev)
int s5p_mfc_get_dec_y_adr_v6(struct s5p_mfc_dev *dev)
{
- return mfc_read(dev, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6);
+ return mfc_read(dev, S5P_FIMV_D_DECODED_LUMA_ADDR_V6);
}
int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev)
diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 85fd312f0a8..a1c87f0ceaa 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -935,9 +935,10 @@ static int sh_vou_g_crop(struct file *file, void *fh, struct v4l2_crop *a)
/* Assume a dull encoder, do all the work ourselves. */
static int sh_vou_s_crop(struct file *file, void *fh, const struct v4l2_crop *a)
{
+ struct v4l2_crop a_writable = *a;
struct video_device *vdev = video_devdata(file);
struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
- struct v4l2_rect *rect = &a->c;
+ struct v4l2_rect *rect = &a_writable.c;
struct v4l2_crop sd_crop = {.type = V4L2_BUF_TYPE_VIDEO_OUTPUT};
struct v4l2_pix_format *pix = &vou_dev->pix;
struct sh_vou_geometry geo;
diff --git a/drivers/media/platform/soc_camera/mx1_camera.c b/drivers/media/platform/soc_camera/mx1_camera.c
index bbe70991d30..032b8c9097f 100644
--- a/drivers/media/platform/soc_camera/mx1_camera.c
+++ b/drivers/media/platform/soc_camera/mx1_camera.c
@@ -470,14 +470,6 @@ static void mx1_camera_remove_device(struct soc_camera_device *icd)
pcdev->icd = NULL;
}
-static int mx1_camera_set_crop(struct soc_camera_device *icd,
- struct v4l2_crop *a)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
- return v4l2_subdev_call(sd, video, s_crop, a);
-}
-
static int mx1_camera_set_bus_param(struct soc_camera_device *icd)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
@@ -689,7 +681,6 @@ static struct soc_camera_host_ops mx1_soc_camera_host_ops = {
.add = mx1_camera_add_device,
.remove = mx1_camera_remove_device,
.set_bus_param = mx1_camera_set_bus_param,
- .set_crop = mx1_camera_set_crop,
.set_fmt = mx1_camera_set_fmt,
.try_fmt = mx1_camera_try_fmt,
.init_videobuf = mx1_camera_init_videobuf,
diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
index 9fd9d1c5b21..9a55f4c4c7f 100644
--- a/drivers/media/platform/soc_camera/mx2_camera.c
+++ b/drivers/media/platform/soc_camera/mx2_camera.c
@@ -864,8 +864,10 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
bytesperline = soc_mbus_bytes_per_line(icd->user_width,
icd->current_fmt->host_fmt);
- if (bytesperline < 0)
+ if (bytesperline < 0) {
+ spin_unlock_irqrestore(&pcdev->lock, flags);
return bytesperline;
+ }
/*
* I didn't manage to properly enable/disable the prp
@@ -878,8 +880,10 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev,
pcdev->discard_size, &pcdev->discard_buffer_dma,
GFP_KERNEL);
- if (!pcdev->discard_buffer)
+ if (!pcdev->discard_buffer) {
+ spin_unlock_irqrestore(&pcdev->lock, flags);
return -ENOMEM;
+ }
pcdev->buf_discard[0].discard = true;
list_add_tail(&pcdev->buf_discard[0].queue,
@@ -1099,9 +1103,10 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd)
}
static int mx2_camera_set_crop(struct soc_camera_device *icd,
- struct v4l2_crop *a)
+ const struct v4l2_crop *a)
{
- struct v4l2_rect *rect = &a->c;
+ struct v4l2_crop a_writable = *a;
+ struct v4l2_rect *rect = &a_writable.c;
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct v4l2_mbus_framefmt mf;
int ret;
diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c
index 3557ac97e43..261f6e9e1b1 100644
--- a/drivers/media/platform/soc_camera/mx3_camera.c
+++ b/drivers/media/platform/soc_camera/mx3_camera.c
@@ -799,9 +799,10 @@ static inline void stride_align(__u32 *width)
* default g_crop and cropcap from soc_camera.c
*/
static int mx3_camera_set_crop(struct soc_camera_device *icd,
- struct v4l2_crop *a)
+ const struct v4l2_crop *a)
{
- struct v4l2_rect *rect = &a->c;
+ struct v4l2_crop a_writable = *a;
+ struct v4l2_rect *rect = &a_writable.c;
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct mx3_camera_dev *mx3_cam = ici->priv;
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c
index fa08c7695cc..13636a58510 100644
--- a/drivers/media/platform/soc_camera/omap1_camera.c
+++ b/drivers/media/platform/soc_camera/omap1_camera.c
@@ -1215,9 +1215,9 @@ static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev,
}
static int omap1_cam_set_crop(struct soc_camera_device *icd,
- struct v4l2_crop *crop)
+ const struct v4l2_crop *crop)
{
- struct v4l2_rect *rect = &crop->c;
+ const struct v4l2_rect *rect = &crop->c;
const struct soc_camera_format_xlate *xlate = icd->current_fmt;
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct device *dev = icd->parent;
diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c
index 1e3776d08da..3434ffe79c6 100644
--- a/drivers/media/platform/soc_camera/pxa_camera.c
+++ b/drivers/media/platform/soc_camera/pxa_camera.c
@@ -1337,9 +1337,9 @@ static int pxa_camera_check_frame(u32 width, u32 height)
}
static int pxa_camera_set_crop(struct soc_camera_device *icd,
- struct v4l2_crop *a)
+ const struct v4l2_crop *a)
{
- struct v4l2_rect *rect = &a->c;
+ const struct v4l2_rect *rect = &a->c;
struct device *dev = icd->parent;
struct soc_camera_host *ici = to_soc_camera_host(dev);
struct pxa_camera_dev *pcdev = ici->priv;
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
index 0a24253dcda..2d8861c0e8f 100644
--- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
@@ -1182,13 +1182,13 @@ static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd)
}
/* Check if any dimension of r1 is smaller than respective one of r2 */
-static bool is_smaller(struct v4l2_rect *r1, struct v4l2_rect *r2)
+static bool is_smaller(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
{
return r1->width < r2->width || r1->height < r2->height;
}
/* Check if r1 fails to cover r2 */
-static bool is_inside(struct v4l2_rect *r1, struct v4l2_rect *r2)
+static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
{
return r1->left > r2->left || r1->top > r2->top ||
r1->left + r1->width < r2->left + r2->width ||
@@ -1263,7 +1263,7 @@ static void update_subrect(struct sh_mobile_ceu_cam *cam)
* 3. if (2) failed, try to request the maximum image
*/
static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop,
- const struct v4l2_crop *cam_crop)
+ struct v4l2_crop *cam_crop)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
@@ -1519,7 +1519,8 @@ static int client_scale(struct soc_camera_device *icd,
static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
const struct v4l2_crop *a)
{
- struct v4l2_rect *rect = &a->c;
+ struct v4l2_crop a_writable = *a;
+ const struct v4l2_rect *rect = &a_writable.c;
struct device *dev = icd->parent;
struct soc_camera_host *ici = to_soc_camera_host(dev);
struct sh_mobile_ceu_dev *pcdev = ici->priv;
@@ -1545,7 +1546,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
* 1. - 2. Apply iterative camera S_CROP for new input window, read back
* actual camera rectangle.
*/
- ret = client_s_crop(icd, a, &cam_crop);
+ ret = client_s_crop(icd, &a_writable, &cam_crop);
if (ret < 0)
return ret;
@@ -1946,7 +1947,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
}
static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd,
- struct v4l2_crop *a)
+ const struct v4l2_crop *a)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
index 9859d2a2449..ba51f65204d 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
@@ -283,14 +283,13 @@ static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
/* activate the pid on the device pid filter */
if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
- adap->pid_filtering &&
- adap->props->pid_filter)
+ adap->pid_filtering && adap->props->pid_filter) {
ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
dvbdmxfeed->pid, (count == 1) ? 1 : 0);
- if (ret < 0)
- dev_err(&d->udev->dev, "%s: pid_filter() " \
- "failed=%d\n", KBUILD_MODNAME,
- ret);
+ if (ret < 0)
+ dev_err(&d->udev->dev, "%s: pid_filter() failed=%d\n",
+ KBUILD_MODNAME, ret);
+ }
/* start feeding if it is first pid */
if (adap->feed_count == 1 && count == 1) {
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c
index 0431beed0ef..5716662b483 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c
@@ -32,9 +32,7 @@ int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
return -EINVAL;
}
- ret = mutex_lock_interruptible(&d->usb_mutex);
- if (ret < 0)
- return ret;
+ mutex_lock(&d->usb_mutex);
dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, wlen, wbuf);
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index adabba8d28b..093f1acce40 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -1346,6 +1346,10 @@ static const struct usb_device_id rtl28xxu_id_table[] = {
&rtl2832u_props, "DigitalNow Quad DVB-T Receiver", NULL) },
{ DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d3,
&rtl2832u_props, "TerraTec Cinergy T Stick RC (Rev. 3)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1102,
+ &rtl2832u_props, "Dexatek DK mini DVB-T Dongle", NULL) },
+ { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d7,
+ &rtl2832u_props, "TerraTec Cinergy T Stick+", NULL) },
{ }
};
MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table);
diff --git a/drivers/memstick/host/Kconfig b/drivers/memstick/host/Kconfig
index cc0997a0517..4f7a17fd1aa 100644
--- a/drivers/memstick/host/Kconfig
+++ b/drivers/memstick/host/Kconfig
@@ -42,3 +42,13 @@ config MEMSTICK_R592
To compile this driver as a module, choose M here: the module will
be called r592.
+
+config MEMSTICK_REALTEK_PCI
+ tristate "Realtek PCI-E Memstick Card Interface Driver"
+ depends on MFD_RTSX_PCI
+ help
+ Say Y here to include driver code to support Memstick card interface
+ of Realtek PCI-E card reader
+
+ To compile this driver as a module, choose M here: the module will
+ be called rtsx_pci_ms.
diff --git a/drivers/memstick/host/Makefile b/drivers/memstick/host/Makefile
index 31ba8d378e4..af3459d7686 100644
--- a/drivers/memstick/host/Makefile
+++ b/drivers/memstick/host/Makefile
@@ -5,3 +5,4 @@
obj-$(CONFIG_MEMSTICK_TIFM_MS) += tifm_ms.o
obj-$(CONFIG_MEMSTICK_JMICRON_38X) += jmb38x_ms.o
obj-$(CONFIG_MEMSTICK_R592) += r592.o
+obj-$(CONFIG_MEMSTICK_REALTEK_PCI) += rtsx_pci_ms.o
diff --git a/drivers/memstick/host/rtsx_pci_ms.c b/drivers/memstick/host/rtsx_pci_ms.c
new file mode 100644
index 00000000000..f5ddb82dadb
--- /dev/null
+++ b/drivers/memstick/host/rtsx_pci_ms.c
@@ -0,0 +1,641 @@
+/* Realtek PCI-Express Memstick Card Interface driver
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Wei WANG <wei_wang@realsil.com.cn>
+ * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#include <linux/module.h>
+#include <linux/highmem.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/memstick.h>
+#include <linux/mfd/rtsx_pci.h>
+#include <asm/unaligned.h>
+
+struct realtek_pci_ms {
+ struct platform_device *pdev;
+ struct rtsx_pcr *pcr;
+ struct memstick_host *msh;
+ struct memstick_request *req;
+
+ struct mutex host_mutex;
+ struct work_struct handle_req;
+
+ u8 ssc_depth;
+ unsigned int clock;
+ unsigned char ifmode;
+ bool eject;
+};
+
+static inline struct device *ms_dev(struct realtek_pci_ms *host)
+{
+ return &(host->pdev->dev);
+}
+
+static inline void ms_clear_error(struct realtek_pci_ms *host)
+{
+ rtsx_pci_write_register(host->pcr, CARD_STOP,
+ MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR);
+}
+
+#ifdef DEBUG
+
+static void ms_print_debug_regs(struct realtek_pci_ms *host)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ u16 i;
+ u8 *ptr;
+
+ /* Print MS host internal registers */
+ rtsx_pci_init_cmd(pcr);
+ for (i = 0xFD40; i <= 0xFD44; i++)
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
+ for (i = 0xFD52; i <= 0xFD69; i++)
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
+ rtsx_pci_send_cmd(pcr, 100);
+
+ ptr = rtsx_pci_get_cmd_data(pcr);
+ for (i = 0xFD40; i <= 0xFD44; i++)
+ dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+ for (i = 0xFD52; i <= 0xFD69; i++)
+ dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+}
+
+#else
+
+#define ms_print_debug_regs(host)
+
+#endif
+
+static int ms_power_on(struct realtek_pci_ms *host)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int err;
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SELECT, 0x07, MS_MOD_SEL);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SHARE_MODE,
+ CARD_SHARE_MASK, CARD_SHARE_48_MS);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN,
+ MS_CLK_EN, MS_CLK_EN);
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ err = rtsx_pci_card_pull_ctl_enable(pcr, RTSX_MS_CARD);
+ if (err < 0)
+ return err;
+
+ err = rtsx_pci_card_power_on(pcr, RTSX_MS_CARD);
+ if (err < 0)
+ return err;
+
+ /* Wait ms power stable */
+ msleep(150);
+
+ err = rtsx_pci_write_register(pcr, CARD_OE,
+ MS_OUTPUT_EN, MS_OUTPUT_EN);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int ms_power_off(struct realtek_pci_ms *host)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int err;
+
+ rtsx_pci_init_cmd(pcr);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, MS_CLK_EN, 0);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, 0);
+
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ err = rtsx_pci_card_power_off(pcr, RTSX_MS_CARD);
+ if (err < 0)
+ return err;
+
+ return rtsx_pci_card_pull_ctl_disable(pcr, RTSX_MS_CARD);
+}
+
+static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir,
+ u8 tpc, u8 cfg, struct scatterlist *sg)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int err;
+ unsigned int length = sg->length;
+ u16 sec_cnt = (u16)(length / 512);
+ u8 val, trans_mode, dma_dir;
+
+ dev_dbg(ms_dev(host), "%s: tpc = 0x%02x, data_dir = %s, length = %d\n",
+ __func__, tpc, (data_dir == READ) ? "READ" : "WRITE",
+ length);
+
+ if (data_dir == READ) {
+ dma_dir = DMA_DIR_FROM_CARD;
+ trans_mode = MS_TM_AUTO_READ;
+ } else {
+ dma_dir = DMA_DIR_TO_CARD;
+ trans_mode = MS_TM_AUTO_WRITE;
+ }
+
+ rtsx_pci_init_cmd(pcr);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_H,
+ 0xFF, (u8)(sec_cnt >> 8));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_L,
+ 0xFF, (u8)sec_cnt);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0,
+ DMA_DONE_INT, DMA_DONE_INT);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, 0xFF, (u8)(length >> 24));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, 0xFF, (u8)(length >> 16));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, 0xFF, (u8)(length >> 8));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)length);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL,
+ 0x03 | DMA_PACK_SIZE_MASK, dma_dir | DMA_EN | DMA_512);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE,
+ 0x01, RING_BUFFER);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER,
+ 0xFF, MS_TRANSFER_START | trans_mode);
+ rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER,
+ MS_TRANSFER_END, MS_TRANSFER_END);
+
+ rtsx_pci_send_cmd_no_wait(pcr);
+
+ err = rtsx_pci_transfer_data(pcr, sg, 1, data_dir == READ, 10000);
+ if (err < 0) {
+ ms_clear_error(host);
+ return err;
+ }
+
+ rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val);
+ if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT))
+ return -EIO;
+
+ return 0;
+}
+
+static int ms_write_bytes(struct realtek_pci_ms *host, u8 tpc,
+ u8 cfg, u8 cnt, u8 *data, u8 *int_reg)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int err, i;
+
+ dev_dbg(ms_dev(host), "%s: tpc = 0x%02x\n", __func__, tpc);
+
+ if (!data)
+ return -EINVAL;
+
+ rtsx_pci_init_cmd(pcr);
+
+ for (i = 0; i < cnt; i++)
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ PPBUF_BASE2 + i, 0xFF, data[i]);
+ if (cnt % 2)
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ PPBUF_BASE2 + i, 0xFF, 0xFF);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE,
+ 0x01, PINGPONG_BUFFER);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER,
+ 0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES);
+ rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER,
+ MS_TRANSFER_END, MS_TRANSFER_END);
+ if (int_reg)
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, MS_TRANS_CFG, 0, 0);
+
+ err = rtsx_pci_send_cmd(pcr, 5000);
+ if (err < 0) {
+ u8 val;
+
+ rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val);
+ dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val);
+
+ if (int_reg)
+ *int_reg = val & 0x0F;
+
+ ms_print_debug_regs(host);
+
+ ms_clear_error(host);
+
+ if (!(tpc & 0x08)) {
+ if (val & MS_CRC16_ERR)
+ return -EIO;
+ } else {
+ if (!(val & 0x80)) {
+ if (val & (MS_INT_ERR | MS_INT_CMDNK))
+ return -EIO;
+ }
+ }
+
+ return -ETIMEDOUT;
+ }
+
+ if (int_reg) {
+ u8 *ptr = rtsx_pci_get_cmd_data(pcr) + 1;
+ *int_reg = *ptr & 0x0F;
+ }
+
+ return 0;
+}
+
+static int ms_read_bytes(struct realtek_pci_ms *host, u8 tpc,
+ u8 cfg, u8 cnt, u8 *data, u8 *int_reg)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int err, i;
+ u8 *ptr;
+
+ dev_dbg(ms_dev(host), "%s: tpc = 0x%02x\n", __func__, tpc);
+
+ if (!data)
+ return -EINVAL;
+
+ rtsx_pci_init_cmd(pcr);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE,
+ 0x01, PINGPONG_BUFFER);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER,
+ 0xFF, MS_TRANSFER_START | MS_TM_READ_BYTES);
+ rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER,
+ MS_TRANSFER_END, MS_TRANSFER_END);
+ for (i = 0; i < cnt - 1; i++)
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0);
+ if (cnt % 2)
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, PPBUF_BASE2 + cnt, 0, 0);
+ else
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD,
+ PPBUF_BASE2 + cnt - 1, 0, 0);
+ if (int_reg)
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, MS_TRANS_CFG, 0, 0);
+
+ err = rtsx_pci_send_cmd(pcr, 5000);
+ if (err < 0) {
+ u8 val;
+
+ rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val);
+ dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val);
+
+ if (int_reg)
+ *int_reg = val & 0x0F;
+
+ ms_print_debug_regs(host);
+
+ ms_clear_error(host);
+
+ if (!(tpc & 0x08)) {
+ if (val & MS_CRC16_ERR)
+ return -EIO;
+ } else {
+ if (!(val & 0x80)) {
+ if (val & (MS_INT_ERR | MS_INT_CMDNK))
+ return -EIO;
+ }
+ }
+
+ return -ETIMEDOUT;
+ }
+
+ ptr = rtsx_pci_get_cmd_data(pcr) + 1;
+ for (i = 0; i < cnt; i++)
+ data[i] = *ptr++;
+
+ if (int_reg)
+ *int_reg = *ptr & 0x0F;
+
+ return 0;
+}
+
+static int rtsx_pci_ms_issue_cmd(struct realtek_pci_ms *host)
+{
+ struct memstick_request *req = host->req;
+ int err = 0;
+ u8 cfg = 0, int_reg;
+
+ dev_dbg(ms_dev(host), "%s\n", __func__);
+
+ if (req->need_card_int) {
+ if (host->ifmode != MEMSTICK_SERIAL)
+ cfg = WAIT_INT;
+ }
+
+ if (req->long_data) {
+ err = ms_transfer_data(host, req->data_dir,
+ req->tpc, cfg, &(req->sg));
+ } else {
+ if (req->data_dir == READ) {
+ err = ms_read_bytes(host, req->tpc, cfg,
+ req->data_len, req->data, &int_reg);
+ } else {
+ err = ms_write_bytes(host, req->tpc, cfg,
+ req->data_len, req->data, &int_reg);
+ }
+ }
+ if (err < 0)
+ return err;
+
+ if (req->need_card_int && (host->ifmode == MEMSTICK_SERIAL)) {
+ err = ms_read_bytes(host, MS_TPC_GET_INT,
+ NO_WAIT_INT, 1, &int_reg, NULL);
+ if (err < 0)
+ return err;
+ }
+
+ if (req->need_card_int) {
+ dev_dbg(ms_dev(host), "int_reg: 0x%02x\n", int_reg);
+
+ if (int_reg & MS_INT_CMDNK)
+ req->int_reg |= MEMSTICK_INT_CMDNAK;
+ if (int_reg & MS_INT_BREQ)
+ req->int_reg |= MEMSTICK_INT_BREQ;
+ if (int_reg & MS_INT_ERR)
+ req->int_reg |= MEMSTICK_INT_ERR;
+ if (int_reg & MS_INT_CED)
+ req->int_reg |= MEMSTICK_INT_CED;
+ }
+
+ return 0;
+}
+
+static void rtsx_pci_ms_handle_req(struct work_struct *work)
+{
+ struct realtek_pci_ms *host = container_of(work,
+ struct realtek_pci_ms, handle_req);
+ struct rtsx_pcr *pcr = host->pcr;
+ struct memstick_host *msh = host->msh;
+ int rc;
+
+ mutex_lock(&pcr->pcr_mutex);
+
+ rtsx_pci_start_run(pcr);
+
+ rtsx_pci_switch_clock(host->pcr, host->clock, host->ssc_depth,
+ false, true, false);
+ rtsx_pci_write_register(pcr, CARD_SELECT, 0x07, MS_MOD_SEL);
+ rtsx_pci_write_register(pcr, CARD_SHARE_MODE,
+ CARD_SHARE_MASK, CARD_SHARE_48_MS);
+
+ if (!host->req) {
+ do {
+ rc = memstick_next_req(msh, &host->req);
+ dev_dbg(ms_dev(host), "next req %d\n", rc);
+
+ if (!rc)
+ host->req->error = rtsx_pci_ms_issue_cmd(host);
+ } while (!rc);
+ }
+
+ mutex_unlock(&pcr->pcr_mutex);
+}
+
+static void rtsx_pci_ms_request(struct memstick_host *msh)
+{
+ struct realtek_pci_ms *host = memstick_priv(msh);
+
+ dev_dbg(ms_dev(host), "--> %s\n", __func__);
+
+ schedule_work(&host->handle_req);
+}
+
+static int rtsx_pci_ms_set_param(struct memstick_host *msh,
+ enum memstick_param param, int value)
+{
+ struct realtek_pci_ms *host = memstick_priv(msh);
+ struct rtsx_pcr *pcr = host->pcr;
+ unsigned int clock = 0;
+ u8 ssc_depth = 0;
+ int err;
+
+ dev_dbg(ms_dev(host), "%s: param = %d, value = %d\n",
+ __func__, param, value);
+
+ switch (param) {
+ case MEMSTICK_POWER:
+ if (value == MEMSTICK_POWER_ON)
+ err = ms_power_on(host);
+ else if (value == MEMSTICK_POWER_OFF)
+ err = ms_power_off(host);
+ else
+ return -EINVAL;
+ break;
+
+ case MEMSTICK_INTERFACE:
+ if (value == MEMSTICK_SERIAL) {
+ clock = 19000000;
+ ssc_depth = RTSX_SSC_DEPTH_500K;
+
+ err = rtsx_pci_write_register(pcr, MS_CFG,
+ 0x18, MS_BUS_WIDTH_1);
+ if (err < 0)
+ return err;
+ } else if (value == MEMSTICK_PAR4) {
+ clock = 39000000;
+ ssc_depth = RTSX_SSC_DEPTH_1M;
+
+ err = rtsx_pci_write_register(pcr, MS_CFG,
+ 0x58, MS_BUS_WIDTH_4 | PUSH_TIME_ODD);
+ if (err < 0)
+ return err;
+ } else {
+ return -EINVAL;
+ }
+
+ err = rtsx_pci_switch_clock(pcr, clock,
+ ssc_depth, false, true, false);
+ if (err < 0)
+ return err;
+
+ host->ssc_depth = ssc_depth;
+ host->clock = clock;
+ host->ifmode = value;
+ break;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int rtsx_pci_ms_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct realtek_pci_ms *host = platform_get_drvdata(pdev);
+ struct memstick_host *msh = host->msh;
+
+ dev_dbg(ms_dev(host), "--> %s\n", __func__);
+
+ memstick_suspend_host(msh);
+ return 0;
+}
+
+static int rtsx_pci_ms_resume(struct platform_device *pdev)
+{
+ struct realtek_pci_ms *host = platform_get_drvdata(pdev);
+ struct memstick_host *msh = host->msh;
+
+ dev_dbg(ms_dev(host), "--> %s\n", __func__);
+
+ memstick_resume_host(msh);
+ return 0;
+}
+
+#else /* CONFIG_PM */
+
+#define rtsx_pci_ms_suspend NULL
+#define rtsx_pci_ms_resume NULL
+
+#endif /* CONFIG_PM */
+
+static void rtsx_pci_ms_card_event(struct platform_device *pdev)
+{
+ struct realtek_pci_ms *host = platform_get_drvdata(pdev);
+
+ memstick_detect_change(host->msh);
+}
+
+static int rtsx_pci_ms_drv_probe(struct platform_device *pdev)
+{
+ struct memstick_host *msh;
+ struct realtek_pci_ms *host;
+ struct rtsx_pcr *pcr;
+ struct pcr_handle *handle = pdev->dev.platform_data;
+ int rc;
+
+ if (!handle)
+ return -ENXIO;
+
+ pcr = handle->pcr;
+ if (!pcr)
+ return -ENXIO;
+
+ dev_dbg(&(pdev->dev),
+ ": Realtek PCI-E Memstick controller found\n");
+
+ msh = memstick_alloc_host(sizeof(*host), &pdev->dev);
+ if (!msh)
+ return -ENOMEM;
+
+ host = memstick_priv(msh);
+ host->pcr = pcr;
+ host->msh = msh;
+ host->pdev = pdev;
+ platform_set_drvdata(pdev, host);
+ pcr->slots[RTSX_MS_CARD].p_dev = pdev;
+ pcr->slots[RTSX_MS_CARD].card_event = rtsx_pci_ms_card_event;
+
+ mutex_init(&host->host_mutex);
+
+ INIT_WORK(&host->handle_req, rtsx_pci_ms_handle_req);
+ msh->request = rtsx_pci_ms_request;
+ msh->set_param = rtsx_pci_ms_set_param;
+ msh->caps = MEMSTICK_CAP_PAR4;
+
+ rc = memstick_add_host(msh);
+ if (rc) {
+ memstick_free_host(msh);
+ return rc;
+ }
+
+ return 0;
+}
+
+static int rtsx_pci_ms_drv_remove(struct platform_device *pdev)
+{
+ struct realtek_pci_ms *host = platform_get_drvdata(pdev);
+ struct rtsx_pcr *pcr;
+ struct memstick_host *msh;
+ int rc;
+
+ if (!host)
+ return 0;
+
+ pcr = host->pcr;
+ pcr->slots[RTSX_MS_CARD].p_dev = NULL;
+ pcr->slots[RTSX_MS_CARD].card_event = NULL;
+ msh = host->msh;
+ host->eject = true;
+
+ mutex_lock(&host->host_mutex);
+ if (host->req) {
+ dev_dbg(&(pdev->dev),
+ "%s: Controller removed during transfer\n",
+ dev_name(&msh->dev));
+
+ rtsx_pci_complete_unfinished_transfer(pcr);
+
+ host->req->error = -ENOMEDIUM;
+ do {
+ rc = memstick_next_req(msh, &host->req);
+ if (!rc)
+ host->req->error = -ENOMEDIUM;
+ } while (!rc);
+ }
+ mutex_unlock(&host->host_mutex);
+
+ memstick_remove_host(msh);
+ memstick_free_host(msh);
+
+ platform_set_drvdata(pdev, NULL);
+
+ dev_dbg(&(pdev->dev),
+ ": Realtek PCI-E Memstick controller has been removed\n");
+
+ return 0;
+}
+
+static struct platform_device_id rtsx_pci_ms_ids[] = {
+ {
+ .name = DRV_NAME_RTSX_PCI_MS,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(platform, rtsx_pci_ms_ids);
+
+static struct platform_driver rtsx_pci_ms_driver = {
+ .probe = rtsx_pci_ms_drv_probe,
+ .remove = rtsx_pci_ms_drv_remove,
+ .id_table = rtsx_pci_ms_ids,
+ .suspend = rtsx_pci_ms_suspend,
+ .resume = rtsx_pci_ms_resume,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRV_NAME_RTSX_PCI_MS,
+ },
+};
+module_platform_driver(rtsx_pci_ms_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Wei WANG <wei_wang@realsil.com.cn>");
+MODULE_DESCRIPTION("Realtek PCI-E Memstick Card Host Driver");
diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index ce229ea933d..391e23e6a64 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -248,7 +248,7 @@ static const struct regmap_irq pm800_irqs[] = {
},
};
-static int __devinit device_gpadc_init(struct pm80x_chip *chip,
+static int device_gpadc_init(struct pm80x_chip *chip,
struct pm80x_platform_data *pdata)
{
struct pm80x_subchip *subchip = chip->subchip;
@@ -315,7 +315,7 @@ out:
return ret;
}
-static int __devinit device_irq_init_800(struct pm80x_chip *chip)
+static int device_irq_init_800(struct pm80x_chip *chip)
{
struct regmap *map = chip->regmap;
unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
@@ -415,7 +415,7 @@ static void pm800_pages_exit(struct pm80x_chip *chip)
}
}
-static int __devinit device_800_init(struct pm80x_chip *chip,
+static int device_800_init(struct pm80x_chip *chip,
struct pm80x_platform_data *pdata)
{
int ret, pmic_id;
@@ -499,7 +499,7 @@ out:
return ret;
}
-static int __devinit pm800_probe(struct i2c_client *client,
+static int pm800_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret = 0;
@@ -554,7 +554,7 @@ out_init:
return ret;
}
-static int __devexit pm800_remove(struct i2c_client *client)
+static int pm800_remove(struct i2c_client *client)
{
struct pm80x_chip *chip = i2c_get_clientdata(client);
@@ -576,7 +576,7 @@ static struct i2c_driver pm800_driver = {
.pm = &pm80x_pm_ops,
},
.probe = pm800_probe,
- .remove = __devexit_p(pm800_remove),
+ .remove = pm800_remove,
.id_table = pm80x_id_table,
};
diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c
index c20a31136f0..e671230be2b 100644
--- a/drivers/mfd/88pm805.c
+++ b/drivers/mfd/88pm805.c
@@ -135,7 +135,7 @@ static struct regmap_irq pm805_irqs[] = {
},
};
-static int __devinit device_irq_init_805(struct pm80x_chip *chip)
+static int device_irq_init_805(struct pm80x_chip *chip)
{
struct regmap *map = chip->regmap;
unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
@@ -189,7 +189,7 @@ static struct regmap_irq_chip pm805_irq_chip = {
.ack_base = PM805_INT_STATUS1,
};
-static int __devinit device_805_init(struct pm80x_chip *chip)
+static int device_805_init(struct pm80x_chip *chip)
{
int ret = 0;
unsigned int val;
@@ -232,7 +232,7 @@ out_irq_init:
return ret;
}
-static int __devinit pm805_probe(struct i2c_client *client,
+static int pm805_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret = 0;
@@ -262,7 +262,7 @@ out_init:
return ret;
}
-static int __devexit pm805_remove(struct i2c_client *client)
+static int pm805_remove(struct i2c_client *client)
{
struct pm80x_chip *chip = i2c_get_clientdata(client);
@@ -281,7 +281,7 @@ static struct i2c_driver pm805_driver = {
.pm = &pm80x_pm_ops,
},
.probe = pm805_probe,
- .remove = __devexit_p(pm805_remove),
+ .remove = pm805_remove,
.id_table = pm80x_id_table,
};
diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c
index cd0bf527d76..1adb355d86d 100644
--- a/drivers/mfd/88pm80x.c
+++ b/drivers/mfd/88pm80x.c
@@ -31,7 +31,7 @@ const struct regmap_config pm80x_regmap_config = {
};
EXPORT_SYMBOL_GPL(pm80x_regmap_config);
-int __devinit pm80x_init(struct i2c_client *client,
+int pm80x_init(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pm80x_chip *chip;
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 8fa86edf70d..893fc1ba6ea 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -28,111 +28,111 @@
#define INT_STATUS_NUM 3
-static struct resource bk0_resources[] __devinitdata = {
+static struct resource bk0_resources[] = {
{2, 2, "duty cycle", IORESOURCE_REG, },
{3, 3, "always on", IORESOURCE_REG, },
{3, 3, "current", IORESOURCE_REG, },
};
-static struct resource bk1_resources[] __devinitdata = {
+static struct resource bk1_resources[] = {
{4, 4, "duty cycle", IORESOURCE_REG, },
{5, 5, "always on", IORESOURCE_REG, },
{5, 5, "current", IORESOURCE_REG, },
};
-static struct resource bk2_resources[] __devinitdata = {
+static struct resource bk2_resources[] = {
{6, 6, "duty cycle", IORESOURCE_REG, },
{7, 7, "always on", IORESOURCE_REG, },
{5, 5, "current", IORESOURCE_REG, },
};
-static struct resource led0_resources[] __devinitdata = {
+static struct resource led0_resources[] = {
/* RGB1 Red LED */
{0xd, 0xd, "control", IORESOURCE_REG, },
{0xc, 0xc, "blink", IORESOURCE_REG, },
};
-static struct resource led1_resources[] __devinitdata = {
+static struct resource led1_resources[] = {
/* RGB1 Green LED */
{0xe, 0xe, "control", IORESOURCE_REG, },
{0xc, 0xc, "blink", IORESOURCE_REG, },
};
-static struct resource led2_resources[] __devinitdata = {
+static struct resource led2_resources[] = {
/* RGB1 Blue LED */
{0xf, 0xf, "control", IORESOURCE_REG, },
{0xc, 0xc, "blink", IORESOURCE_REG, },
};
-static struct resource led3_resources[] __devinitdata = {
+static struct resource led3_resources[] = {
/* RGB2 Red LED */
{0x9, 0x9, "control", IORESOURCE_REG, },
{0x8, 0x8, "blink", IORESOURCE_REG, },
};
-static struct resource led4_resources[] __devinitdata = {
+static struct resource led4_resources[] = {
/* RGB2 Green LED */
{0xa, 0xa, "control", IORESOURCE_REG, },
{0x8, 0x8, "blink", IORESOURCE_REG, },
};
-static struct resource led5_resources[] __devinitdata = {
+static struct resource led5_resources[] = {
/* RGB2 Blue LED */
{0xb, 0xb, "control", IORESOURCE_REG, },
{0x8, 0x8, "blink", IORESOURCE_REG, },
};
-static struct resource buck1_resources[] __devinitdata = {
+static struct resource buck1_resources[] = {
{0x24, 0x24, "buck set", IORESOURCE_REG, },
};
-static struct resource buck2_resources[] __devinitdata = {
+static struct resource buck2_resources[] = {
{0x25, 0x25, "buck set", IORESOURCE_REG, },
};
-static struct resource buck3_resources[] __devinitdata = {
+static struct resource buck3_resources[] = {
{0x26, 0x26, "buck set", IORESOURCE_REG, },
};
-static struct resource ldo1_resources[] __devinitdata = {
+static struct resource ldo1_resources[] = {
{0x10, 0x10, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo2_resources[] __devinitdata = {
+static struct resource ldo2_resources[] = {
{0x11, 0x11, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo3_resources[] __devinitdata = {
+static struct resource ldo3_resources[] = {
{0x12, 0x12, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo4_resources[] __devinitdata = {
+static struct resource ldo4_resources[] = {
{0x13, 0x13, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo5_resources[] __devinitdata = {
+static struct resource ldo5_resources[] = {
{0x14, 0x14, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo6_resources[] __devinitdata = {
+static struct resource ldo6_resources[] = {
{0x15, 0x15, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo7_resources[] __devinitdata = {
+static struct resource ldo7_resources[] = {
{0x16, 0x16, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo8_resources[] __devinitdata = {
+static struct resource ldo8_resources[] = {
{0x17, 0x17, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo9_resources[] __devinitdata = {
+static struct resource ldo9_resources[] = {
{0x18, 0x18, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo10_resources[] __devinitdata = {
+static struct resource ldo10_resources[] = {
{0x19, 0x19, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo12_resources[] __devinitdata = {
+static struct resource ldo12_resources[] = {
{0x1a, 0x1a, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo_vibrator_resources[] __devinitdata = {
+static struct resource ldo_vibrator_resources[] = {
{0x28, 0x28, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo14_resources[] __devinitdata = {
+static struct resource ldo14_resources[] = {
{0x1b, 0x1b, "ldo set", IORESOURCE_REG, },
};
-static struct resource touch_resources[] __devinitdata = {
+static struct resource touch_resources[] = {
{PM8607_IRQ_PEN, PM8607_IRQ_PEN, "touch", IORESOURCE_IRQ,},
};
-static struct resource onkey_resources[] __devinitdata = {
+static struct resource onkey_resources[] = {
{PM8607_IRQ_ONKEY, PM8607_IRQ_ONKEY, "onkey", IORESOURCE_IRQ,},
};
-static struct resource codec_resources[] __devinitdata = {
+static struct resource codec_resources[] = {
/* Headset microphone insertion or removal */
{PM8607_IRQ_MICIN, PM8607_IRQ_MICIN, "micin", IORESOURCE_IRQ,},
/* Hook-switch press or release */
@@ -143,12 +143,12 @@ static struct resource codec_resources[] __devinitdata = {
{PM8607_IRQ_AUDIO_SHORT, PM8607_IRQ_AUDIO_SHORT, "audio-short", IORESOURCE_IRQ,},
};
-static struct resource battery_resources[] __devinitdata = {
+static struct resource battery_resources[] = {
{PM8607_IRQ_CC, PM8607_IRQ_CC, "columb counter", IORESOURCE_IRQ,},
{PM8607_IRQ_BAT, PM8607_IRQ_BAT, "battery", IORESOURCE_IRQ,},
};
-static struct resource charger_resources[] __devinitdata = {
+static struct resource charger_resources[] = {
{PM8607_IRQ_CHG, PM8607_IRQ_CHG, "charger detect", IORESOURCE_IRQ,},
{PM8607_IRQ_CHG_DONE, PM8607_IRQ_CHG_DONE, "charging done", IORESOURCE_IRQ,},
{PM8607_IRQ_CHG_FAIL, PM8607_IRQ_CHG_FAIL, "charging timeout", IORESOURCE_IRQ,},
@@ -158,11 +158,11 @@ static struct resource charger_resources[] __devinitdata = {
{PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,},
};
-static struct resource rtc_resources[] __devinitdata = {
+static struct resource rtc_resources[] = {
{PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ,},
};
-static struct mfd_cell bk_devs[] __devinitdata = {
+static struct mfd_cell bk_devs[] = {
{
.name = "88pm860x-backlight",
.id = 0,
@@ -181,7 +181,7 @@ static struct mfd_cell bk_devs[] __devinitdata = {
},
};
-static struct mfd_cell led_devs[] __devinitdata = {
+static struct mfd_cell led_devs[] = {
{
.name = "88pm860x-led",
.id = 0,
@@ -215,7 +215,7 @@ static struct mfd_cell led_devs[] __devinitdata = {
},
};
-static struct mfd_cell reg_devs[] __devinitdata = {
+static struct mfd_cell reg_devs[] = {
{
.name = "88pm860x-regulator",
.id = 0,
@@ -565,7 +565,7 @@ static struct irq_domain_ops pm860x_irq_domain_ops = {
.xlate = irq_domain_xlate_onetwocell,
};
-static int __devinit device_irq_init(struct pm860x_chip *chip,
+static int device_irq_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
@@ -730,7 +730,7 @@ out:
}
EXPORT_SYMBOL(pm8606_osc_disable);
-static void __devinit device_osc_init(struct i2c_client *i2c)
+static void device_osc_init(struct i2c_client *i2c)
{
struct pm860x_chip *chip = i2c_get_clientdata(i2c);
@@ -745,7 +745,7 @@ static void __devinit device_osc_init(struct i2c_client *i2c)
chip->osc_status = PM8606_REF_GP_OSC_OFF;
}
-static void __devinit device_bk_init(struct pm860x_chip *chip,
+static void device_bk_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret, i;
@@ -765,7 +765,7 @@ static void __devinit device_bk_init(struct pm860x_chip *chip,
dev_err(chip->dev, "Failed to add backlight subdev\n");
}
-static void __devinit device_led_init(struct pm860x_chip *chip,
+static void device_led_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret, i;
@@ -787,7 +787,7 @@ static void __devinit device_led_init(struct pm860x_chip *chip,
}
}
-static void __devinit device_regulator_init(struct pm860x_chip *chip,
+static void device_regulator_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret;
@@ -866,7 +866,7 @@ static void __devinit device_regulator_init(struct pm860x_chip *chip,
}
}
-static void __devinit device_rtc_init(struct pm860x_chip *chip,
+static void device_rtc_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret;
@@ -885,7 +885,7 @@ static void __devinit device_rtc_init(struct pm860x_chip *chip,
dev_err(chip->dev, "Failed to add rtc subdev\n");
}
-static void __devinit device_touch_init(struct pm860x_chip *chip,
+static void device_touch_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret;
@@ -904,7 +904,7 @@ static void __devinit device_touch_init(struct pm860x_chip *chip,
dev_err(chip->dev, "Failed to add touch subdev\n");
}
-static void __devinit device_power_init(struct pm860x_chip *chip,
+static void device_power_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret;
@@ -951,7 +951,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip,
}
}
-static void __devinit device_onkey_init(struct pm860x_chip *chip,
+static void device_onkey_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret;
@@ -965,7 +965,7 @@ static void __devinit device_onkey_init(struct pm860x_chip *chip,
dev_err(chip->dev, "Failed to add onkey subdev\n");
}
-static void __devinit device_codec_init(struct pm860x_chip *chip,
+static void device_codec_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret;
@@ -979,7 +979,7 @@ static void __devinit device_codec_init(struct pm860x_chip *chip,
dev_err(chip->dev, "Failed to add codec subdev\n");
}
-static void __devinit device_8607_init(struct pm860x_chip *chip,
+static void device_8607_init(struct pm860x_chip *chip,
struct i2c_client *i2c,
struct pm860x_platform_data *pdata)
{
@@ -1040,7 +1040,7 @@ out:
return;
}
-static void __devinit device_8606_init(struct pm860x_chip *chip,
+static void device_8606_init(struct pm860x_chip *chip,
struct i2c_client *i2c,
struct pm860x_platform_data *pdata)
{
@@ -1049,7 +1049,7 @@ static void __devinit device_8606_init(struct pm860x_chip *chip,
device_led_init(chip, pdata);
}
-static int __devinit pm860x_device_init(struct pm860x_chip *chip,
+static int pm860x_device_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
chip->core_irq = 0;
@@ -1077,7 +1077,7 @@ static int __devinit pm860x_device_init(struct pm860x_chip *chip,
return 0;
}
-static void __devexit pm860x_device_exit(struct pm860x_chip *chip)
+static void pm860x_device_exit(struct pm860x_chip *chip)
{
device_irq_exit(chip);
mfd_remove_devices(chip->dev);
@@ -1109,7 +1109,7 @@ static struct regmap_config pm860x_regmap_config = {
.val_bits = 8,
};
-static int __devinit pm860x_dt_init(struct device_node *np,
+static int pm860x_dt_init(struct device_node *np,
struct device *dev,
struct pm860x_platform_data *pdata)
{
@@ -1127,7 +1127,7 @@ static int __devinit pm860x_dt_init(struct device_node *np,
return 0;
}
-static int __devinit pm860x_probe(struct i2c_client *client,
+static int pm860x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pm860x_platform_data *pdata = client->dev.platform_data;
@@ -1200,7 +1200,7 @@ err:
return ret;
}
-static int __devexit pm860x_remove(struct i2c_client *client)
+static int pm860x_remove(struct i2c_client *client)
{
struct pm860x_chip *chip = i2c_get_clientdata(client);
@@ -1258,7 +1258,7 @@ static struct i2c_driver pm860x_driver = {
.of_match_table = of_match_ptr(pm860x_dt_ids),
},
.probe = pm860x_probe,
- .remove = __devexit_p(pm860x_remove),
+ .remove = pm860x_remove,
.id_table = pm860x_id_table,
};
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index acab3ef8a31..2c10938b356 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -63,6 +63,16 @@ config MFD_SM501_GPIO
lines on the SM501. The platform data is used to supply the
base number for the first GPIO line to register.
+config MFD_RTSX_PCI
+ tristate "Support for Realtek PCI-E card reader"
+ depends on PCI
+ select MFD_CORE
+ help
+ This supports for Realtek PCI-Express card reader including rts5209,
+ rts5229, rtl8411, etc. Realtek card reader supports access to many
+ types of memory cards, such as Memory Stick, Memory Stick Pro,
+ Secure Digital and MultiMediaCard.
+
config MFD_ASIC3
bool "Support for Compaq ASIC3"
depends on GENERIC_HARDIRQS && GPIOLIB && ARM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index d8ccb630ddb..b53db06d1b4 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -9,6 +9,9 @@ obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o
obj-$(CONFIG_MFD_SM501) += sm501.o
obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
+rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o
+obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
+
obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 2b3dde571a5..2ec7725f4a0 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -661,8 +661,7 @@ struct ab3100_init_setting {
u8 setting;
};
-static const struct ab3100_init_setting __devinitconst
-ab3100_init_settings[] = {
+static const struct ab3100_init_setting ab3100_init_settings[] = {
{
.abreg = AB3100_MCA,
.setting = 0x01
@@ -708,7 +707,7 @@ ab3100_init_settings[] = {
},
};
-static int __devinit ab3100_setup(struct ab3100 *ab3100)
+static int ab3100_setup(struct ab3100 *ab3100)
{
int err = 0;
int i;
@@ -803,7 +802,7 @@ struct ab_family_id {
char *name;
};
-static const struct ab_family_id ids[] __devinitconst = {
+static const struct ab_family_id ids[] = {
/* AB3100 */
{
.id = 0xc0,
@@ -857,7 +856,7 @@ static const struct ab_family_id ids[] __devinitconst = {
},
};
-static int __devinit ab3100_probe(struct i2c_client *client,
+static int ab3100_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ab3100 *ab3100;
@@ -962,7 +961,7 @@ static int __devinit ab3100_probe(struct i2c_client *client,
return err;
}
-static int __devexit ab3100_remove(struct i2c_client *client)
+static int ab3100_remove(struct i2c_client *client)
{
struct ab3100 *ab3100 = i2c_get_clientdata(client);
@@ -986,7 +985,7 @@ static struct i2c_driver ab3100_driver = {
},
.id_table = ab3100_id,
.probe = ab3100_probe,
- .remove = __devexit_p(ab3100_remove),
+ .remove = ab3100_remove,
};
static int __init ab3100_i2c_init(void)
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 5ec70f26b9d..908d09b8ff4 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -623,7 +623,7 @@ static struct resource __devinitdata ab9540_gpio_resources[] = {
}
};
-static struct resource __devinitdata ab8500_gpadc_resources[] = {
+static struct resource ab8500_gpadc_resources[] = {
{
.name = "HW_CONV_END",
.start = AB8500_INT_GP_HW_ADC_CONV_END,
@@ -638,7 +638,7 @@ static struct resource __devinitdata ab8500_gpadc_resources[] = {
},
};
-static struct resource __devinitdata ab8500_rtc_resources[] = {
+static struct resource ab8500_rtc_resources[] = {
{
.name = "60S",
.start = AB8500_INT_RTC_60S,
@@ -653,7 +653,7 @@ static struct resource __devinitdata ab8500_rtc_resources[] = {
},
};
-static struct resource __devinitdata ab8500_poweronkey_db_resources[] = {
+static struct resource ab8500_poweronkey_db_resources[] = {
{
.name = "ONKEY_DBF",
.start = AB8500_INT_PON_KEY1DB_F,
@@ -668,7 +668,7 @@ static struct resource __devinitdata ab8500_poweronkey_db_resources[] = {
},
};
-static struct resource __devinitdata ab8500_av_acc_detect_resources[] = {
+static struct resource ab8500_av_acc_detect_resources[] = {
{
.name = "ACC_DETECT_1DB_F",
.start = AB8500_INT_ACC_DETECT_1DB_F,
@@ -707,7 +707,7 @@ static struct resource __devinitdata ab8500_av_acc_detect_resources[] = {
},
};
-static struct resource __devinitdata ab8500_charger_resources[] = {
+static struct resource ab8500_charger_resources[] = {
{
.name = "MAIN_CH_UNPLUG_DET",
.start = AB8500_INT_MAIN_CH_UNPLUG_DET,
@@ -788,7 +788,7 @@ static struct resource __devinitdata ab8500_charger_resources[] = {
},
};
-static struct resource __devinitdata ab8500_btemp_resources[] = {
+static struct resource ab8500_btemp_resources[] = {
{
.name = "BAT_CTRL_INDB",
.start = AB8500_INT_BAT_CTRL_INDB,
@@ -821,7 +821,7 @@ static struct resource __devinitdata ab8500_btemp_resources[] = {
},
};
-static struct resource __devinitdata ab8500_fg_resources[] = {
+static struct resource ab8500_fg_resources[] = {
{
.name = "NCONV_ACCU",
.start = AB8500_INT_CCN_CONV_ACC,
@@ -860,10 +860,10 @@ static struct resource __devinitdata ab8500_fg_resources[] = {
},
};
-static struct resource __devinitdata ab8500_chargalg_resources[] = {};
+static struct resource ab8500_chargalg_resources[] = {};
#ifdef CONFIG_DEBUG_FS
-static struct resource __devinitdata ab8500_debug_resources[] = {
+static struct resource ab8500_debug_resources[] = {
{
.name = "IRQ_FIRST",
.start = AB8500_INT_MAIN_EXT_CH_NOT_OK,
@@ -879,7 +879,7 @@ static struct resource __devinitdata ab8500_debug_resources[] = {
};
#endif
-static struct resource __devinitdata ab8500_usb_resources[] = {
+static struct resource ab8500_usb_resources[] = {
{
.name = "ID_WAKEUP_R",
.start = AB8500_INT_ID_WAKEUP_R,
@@ -924,7 +924,7 @@ static struct resource __devinitdata ab8500_usb_resources[] = {
},
};
-static struct resource __devinitdata ab8505_iddet_resources[] = {
+static struct resource ab8505_iddet_resources[] = {
{
.name = "KeyDeglitch",
.start = AB8505_INT_KEYDEGLITCH,
@@ -957,7 +957,7 @@ static struct resource __devinitdata ab8505_iddet_resources[] = {
},
};
-static struct resource __devinitdata ab8500_temp_resources[] = {
+static struct resource ab8500_temp_resources[] = {
{
.name = "AB8500_TEMP_WARM",
.start = AB8500_INT_TEMP_WARM,
@@ -966,7 +966,7 @@ static struct resource __devinitdata ab8500_temp_resources[] = {
},
};
-static struct mfd_cell __devinitdata abx500_common_devs[] = {
+static struct mfd_cell abx500_common_devs[] = {
#ifdef CONFIG_DEBUG_FS
{
.name = "ab8500-debug",
@@ -1038,7 +1038,7 @@ static struct mfd_cell __devinitdata abx500_common_devs[] = {
},
};
-static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
+static struct mfd_cell ab8500_bm_devs[] = {
{
.name = "ab8500-charger",
.of_compatible = "stericsson,ab8500-charger",
@@ -1081,7 +1081,7 @@ static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
},
};
-static struct mfd_cell __devinitdata ab8500_devs[] = {
+static struct mfd_cell ab8500_devs[] = {
{
.name = "ab8500-gpio",
.of_compatible = "stericsson,ab8500-gpio",
@@ -1100,7 +1100,7 @@ static struct mfd_cell __devinitdata ab8500_devs[] = {
},
};
-static struct mfd_cell __devinitdata ab9540_devs[] = {
+static struct mfd_cell ab9540_devs[] = {
{
.name = "ab8500-gpio",
.num_resources = ARRAY_SIZE(ab9540_gpio_resources),
@@ -1117,7 +1117,7 @@ static struct mfd_cell __devinitdata ab9540_devs[] = {
};
/* Device list common to ab9540 and ab8505 */
-static struct mfd_cell __devinitdata ab9540_ab8505_devs[] = {
+static struct mfd_cell ab9540_ab8505_devs[] = {
{
.name = "ab-iddet",
.num_resources = ARRAY_SIZE(ab8505_iddet_resources),
@@ -1268,7 +1268,7 @@ static struct attribute_group ab9540_attr_group = {
.attrs = ab9540_sysfs_entries,
};
-static int __devinit ab8500_probe(struct platform_device *pdev)
+static int ab8500_probe(struct platform_device *pdev)
{
static char *switch_off_status[] = {
"Swoff bit programming",
@@ -1493,7 +1493,7 @@ out_free_ab8500:
return ret;
}
-static int __devexit ab8500_remove(struct platform_device *pdev)
+static int ab8500_remove(struct platform_device *pdev)
{
struct ab8500 *ab8500 = platform_get_drvdata(pdev);
@@ -1526,7 +1526,7 @@ static struct platform_driver ab8500_core_driver = {
.owner = THIS_MODULE,
},
.probe = ab8500_probe,
- .remove = __devexit_p(ab8500_remove),
+ .remove = ab8500_remove,
.id_table = ab8500_id,
};
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
index c4cb806978a..5a8e707bc03 100644
--- a/drivers/mfd/ab8500-debugfs.c
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -552,7 +552,7 @@ static struct dentry *ab8500_bank_file;
static struct dentry *ab8500_address_file;
static struct dentry *ab8500_val_file;
-static int __devinit ab8500_debug_probe(struct platform_device *plf)
+static int ab8500_debug_probe(struct platform_device *plf)
{
debug_bank = AB8500_MISC;
debug_address = AB8500_REV_REG & 0x00FF;
@@ -597,7 +597,7 @@ exit_no_debugfs:
return -ENOMEM;
}
-static int __devexit ab8500_debug_remove(struct platform_device *plf)
+static int ab8500_debug_remove(struct platform_device *plf)
{
debugfs_remove(ab8500_val_file);
debugfs_remove(ab8500_address_file);
@@ -614,7 +614,7 @@ static struct platform_driver ab8500_debug_driver = {
.owner = THIS_MODULE,
},
.probe = ab8500_debug_probe,
- .remove = __devexit_p(ab8500_debug_remove)
+ .remove = ab8500_debug_remove
};
static int __init ab8500_debug_init(void)
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c
index 29d72a259c8..3fb1f40d638 100644
--- a/drivers/mfd/ab8500-gpadc.c
+++ b/drivers/mfd/ab8500-gpadc.c
@@ -571,7 +571,7 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc)
gpadc->cal_data[ADC_INPUT_VBAT].offset);
}
-static int __devinit ab8500_gpadc_probe(struct platform_device *pdev)
+static int ab8500_gpadc_probe(struct platform_device *pdev)
{
int ret = 0;
struct ab8500_gpadc *gpadc;
@@ -634,7 +634,7 @@ fail:
return ret;
}
-static int __devexit ab8500_gpadc_remove(struct platform_device *pdev)
+static int ab8500_gpadc_remove(struct platform_device *pdev)
{
struct ab8500_gpadc *gpadc = platform_get_drvdata(pdev);
@@ -651,7 +651,7 @@ static int __devexit ab8500_gpadc_remove(struct platform_device *pdev)
static struct platform_driver ab8500_gpadc_driver = {
.probe = ab8500_gpadc_probe,
- .remove = __devexit_p(ab8500_gpadc_remove),
+ .remove = ab8500_gpadc_remove,
.driver = {
.name = "ab8500-gpadc",
.owner = THIS_MODULE,
diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c
index c28d4eb1eff..8a33b2c7eea 100644
--- a/drivers/mfd/ab8500-sysctrl.c
+++ b/drivers/mfd/ab8500-sysctrl.c
@@ -49,13 +49,13 @@ int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value)
(u8)(reg & 0xFF), mask, value);
}
-static int __devinit ab8500_sysctrl_probe(struct platform_device *pdev)
+static int ab8500_sysctrl_probe(struct platform_device *pdev)
{
sysctrl_dev = &pdev->dev;
return 0;
}
-static int __devexit ab8500_sysctrl_remove(struct platform_device *pdev)
+static int ab8500_sysctrl_remove(struct platform_device *pdev)
{
sysctrl_dev = NULL;
return 0;
@@ -67,7 +67,7 @@ static struct platform_driver ab8500_sysctrl_driver = {
.owner = THIS_MODULE,
},
.probe = ab8500_sysctrl_probe,
- .remove = __devexit_p(ab8500_sysctrl_remove),
+ .remove = ab8500_sysctrl_remove,
};
static int __init ab8500_sysctrl_init(void)
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c
index ea8b9475731..210dd038bb5 100644
--- a/drivers/mfd/adp5520.c
+++ b/drivers/mfd/adp5520.c
@@ -203,7 +203,7 @@ static int adp5520_remove_subdevs(struct adp5520_chip *chip)
return device_for_each_child(chip->dev, NULL, __remove_subdev);
}
-static int __devinit adp5520_probe(struct i2c_client *client,
+static int adp5520_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adp5520_platform_data *pdata = client->dev.platform_data;
@@ -307,7 +307,7 @@ out_free_chip:
return ret;
}
-static int __devexit adp5520_remove(struct i2c_client *client)
+static int adp5520_remove(struct i2c_client *client)
{
struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
@@ -356,7 +356,7 @@ static struct i2c_driver adp5520_driver = {
.pm = &adp5520_pm,
},
.probe = adp5520_probe,
- .remove = __devexit_p(adp5520_remove),
+ .remove = adp5520_remove,
.id_table = adp5520_id,
};
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 1b48f209480..1a6f943f733 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -98,9 +98,9 @@ static irqreturn_t arizona_underclocked(int irq, void *data)
if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
dev_err(arizona->dev, "AIF3 underclocked\n");
- if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
- dev_err(arizona->dev, "AIF3 underclocked\n");
if (val & ARIZONA_AIF2_UNDERCLOCKED_STS)
+ dev_err(arizona->dev, "AIF2 underclocked\n");
+ if (val & ARIZONA_AIF1_UNDERCLOCKED_STS)
dev_err(arizona->dev, "AIF1 underclocked\n");
if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS)
dev_err(arizona->dev, "ISRC2 underclocked\n");
@@ -285,7 +285,7 @@ static struct mfd_cell wm5110_devs[] = {
{ .name = "wm5110-codec" },
};
-int __devinit arizona_dev_init(struct arizona *arizona)
+int arizona_dev_init(struct arizona *arizona)
{
struct device *dev = arizona->dev;
const char *type_name;
@@ -415,11 +415,19 @@ int __devinit arizona_dev_init(struct arizona *arizona)
/* If we have a /RESET GPIO we'll already be reset */
if (!arizona->pdata.reset) {
+ regcache_mark_dirty(arizona->regmap);
+
ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
if (ret != 0) {
dev_err(dev, "Failed to reset device: %d\n", ret);
goto err_reset;
}
+
+ ret = regcache_sync(arizona->regmap);
+ if (ret != 0) {
+ dev_err(dev, "Failed to sync device: %d\n", ret);
+ goto err_reset;
+ }
}
ret = arizona_wait_for_boot(arizona);
@@ -520,7 +528,7 @@ int __devinit arizona_dev_init(struct arizona *arizona)
break;
case WM5110:
ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
- ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
+ ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
break;
}
@@ -553,7 +561,7 @@ err_early:
}
EXPORT_SYMBOL_GPL(arizona_dev_init);
-int __devexit arizona_dev_exit(struct arizona *arizona)
+int arizona_dev_exit(struct arizona *arizona)
{
mfd_remove_devices(arizona->dev);
arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c
index 570c4b43808..44a1bb96984 100644
--- a/drivers/mfd/arizona-i2c.c
+++ b/drivers/mfd/arizona-i2c.c
@@ -22,7 +22,7 @@
#include "arizona.h"
-static __devinit int arizona_i2c_probe(struct i2c_client *i2c,
+static int arizona_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct arizona *arizona;
@@ -65,7 +65,7 @@ static __devinit int arizona_i2c_probe(struct i2c_client *i2c,
return arizona_dev_init(arizona);
}
-static int __devexit arizona_i2c_remove(struct i2c_client *i2c)
+static int arizona_i2c_remove(struct i2c_client *i2c)
{
struct arizona *arizona = dev_get_drvdata(&i2c->dev);
arizona_dev_exit(arizona);
@@ -86,7 +86,7 @@ static struct i2c_driver arizona_i2c_driver = {
.pm = &arizona_pm_ops,
},
.probe = arizona_i2c_probe,
- .remove = __devexit_p(arizona_i2c_remove),
+ .remove = arizona_i2c_remove,
.id_table = arizona_i2c_id,
};
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
index ef0f2d001df..b1b00917740 100644
--- a/drivers/mfd/arizona-irq.c
+++ b/drivers/mfd/arizona-irq.c
@@ -178,6 +178,7 @@ int arizona_irq_init(struct arizona *arizona)
switch (arizona->rev) {
case 0:
+ case 1:
ctrlif_error = false;
break;
default:
diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c
index df2e5a8bee2..1b9fdd698b0 100644
--- a/drivers/mfd/arizona-spi.c
+++ b/drivers/mfd/arizona-spi.c
@@ -22,7 +22,7 @@
#include "arizona.h"
-static int __devinit arizona_spi_probe(struct spi_device *spi)
+static int arizona_spi_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
struct arizona *arizona;
@@ -65,7 +65,7 @@ static int __devinit arizona_spi_probe(struct spi_device *spi)
return arizona_dev_init(arizona);
}
-static int __devexit arizona_spi_remove(struct spi_device *spi)
+static int arizona_spi_remove(struct spi_device *spi)
{
struct arizona *arizona = dev_get_drvdata(&spi->dev);
arizona_dev_exit(arizona);
@@ -86,7 +86,7 @@ static struct spi_driver arizona_spi_driver = {
.pm = &arizona_pm_ops,
},
.probe = arizona_spi_probe,
- .remove = __devexit_p(arizona_spi_remove),
+ .remove = arizona_spi_remove,
.id_table = arizona_spi_ids,
};
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index 62f0883a763..1b15986c01e 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -1039,7 +1039,7 @@ static int __init asic3_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit asic3_remove(struct platform_device *pdev)
+static int asic3_remove(struct platform_device *pdev)
{
int ret;
struct asic3 *asic = platform_get_drvdata(pdev);
@@ -1071,7 +1071,7 @@ static struct platform_driver asic3_device_driver = {
.driver = {
.name = "asic3",
},
- .remove = __devexit_p(asic3_remove),
+ .remove = asic3_remove,
.shutdown = asic3_shutdown,
};
diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c
index 2b282133c72..2e4752a9220 100644
--- a/drivers/mfd/cs5535-mfd.c
+++ b/drivers/mfd/cs5535-mfd.c
@@ -71,9 +71,9 @@ static int cs5535_mfd_res_disable(struct platform_device *pdev)
return 0;
}
-static __devinitdata struct resource cs5535_mfd_resources[NR_BARS];
+static struct resource cs5535_mfd_resources[NR_BARS];
-static __devinitdata struct mfd_cell cs5535_mfd_cells[] = {
+static struct mfd_cell cs5535_mfd_cells[] = {
{
.id = SMB_BAR,
.name = "cs5535-smb",
@@ -113,7 +113,7 @@ static __devinitdata struct mfd_cell cs5535_mfd_cells[] = {
};
#ifdef CONFIG_OLPC
-static void __devinit cs5535_clone_olpc_cells(void)
+static void cs5535_clone_olpc_cells(void)
{
const char *acpi_clones[] = { "olpc-xo1-pm-acpi", "olpc-xo1-sci-acpi" };
@@ -126,7 +126,7 @@ static void __devinit cs5535_clone_olpc_cells(void)
static void cs5535_clone_olpc_cells(void) { }
#endif
-static int __devinit cs5535_mfd_probe(struct pci_dev *pdev,
+static int cs5535_mfd_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
int err, i;
@@ -166,7 +166,7 @@ err_disable:
return err;
}
-static void __devexit cs5535_mfd_remove(struct pci_dev *pdev)
+static void cs5535_mfd_remove(struct pci_dev *pdev)
{
mfd_remove_devices(&pdev->dev);
pci_disable_device(pdev);
@@ -183,7 +183,7 @@ static struct pci_driver cs5535_mfd_driver = {
.name = DRV_NAME,
.id_table = cs5535_mfd_pci_tbl,
.probe = cs5535_mfd_probe,
- .remove = __devexit_p(cs5535_mfd_remove),
+ .remove = cs5535_mfd_remove,
};
module_pci_driver(cs5535_mfd_driver);
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c
index 1924b857a0f..05176cd2862 100644
--- a/drivers/mfd/da903x.c
+++ b/drivers/mfd/da903x.c
@@ -246,7 +246,7 @@ int da903x_query_status(struct device *dev, unsigned int sbits)
}
EXPORT_SYMBOL(da903x_query_status);
-static int __devinit da9030_init_chip(struct da903x_chip *chip)
+static int da9030_init_chip(struct da903x_chip *chip)
{
uint8_t chip_id;
int err;
@@ -459,7 +459,7 @@ static int da903x_remove_subdevs(struct da903x_chip *chip)
return device_for_each_child(chip->dev, NULL, __remove_subdev);
}
-static int __devinit da903x_add_subdevs(struct da903x_chip *chip,
+static int da903x_add_subdevs(struct da903x_chip *chip,
struct da903x_platform_data *pdata)
{
struct da903x_subdev_info *subdev;
@@ -491,7 +491,7 @@ failed:
return ret;
}
-static int __devinit da903x_probe(struct i2c_client *client,
+static int da903x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct da903x_platform_data *pdata = client->dev.platform_data;
@@ -544,7 +544,7 @@ out_free_chip:
return ret;
}
-static int __devexit da903x_remove(struct i2c_client *client)
+static int da903x_remove(struct i2c_client *client)
{
struct da903x_chip *chip = i2c_get_clientdata(client);
@@ -560,7 +560,7 @@ static struct i2c_driver da903x_driver = {
.owner = THIS_MODULE,
},
.probe = da903x_probe,
- .remove = __devexit_p(da903x_remove),
+ .remove = da903x_remove,
.id_table = da903x_id_table,
};
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c
index a0a62b24621..689b747416a 100644
--- a/drivers/mfd/da9052-core.c
+++ b/drivers/mfd/da9052-core.c
@@ -515,7 +515,7 @@ static struct resource da9052_tsi_resources[] = {
},
};
-static struct mfd_cell __devinitdata da9052_subdev_info[] = {
+static struct mfd_cell da9052_subdev_info[] = {
{
.name = "da9052-regulator",
.id = 1,
@@ -769,7 +769,7 @@ struct regmap_config da9052_regmap_config = {
};
EXPORT_SYMBOL_GPL(da9052_regmap_config);
-int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)
+int da9052_device_init(struct da9052 *da9052, u8 chip_id)
{
struct da9052_pdata *pdata = da9052->dev->platform_data;
int ret;
diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c
index 352c58b5a90..ac74a4d1dae 100644
--- a/drivers/mfd/da9052-i2c.c
+++ b/drivers/mfd/da9052-i2c.c
@@ -64,7 +64,7 @@ static const struct of_device_id dialog_dt_ids[] = {
};
#endif
-static int __devinit da9052_i2c_probe(struct i2c_client *client,
+static int da9052_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct da9052 *da9052;
@@ -121,7 +121,7 @@ static int __devinit da9052_i2c_probe(struct i2c_client *client,
return 0;
}
-static int __devexit da9052_i2c_remove(struct i2c_client *client)
+static int da9052_i2c_remove(struct i2c_client *client)
{
struct da9052 *da9052 = i2c_get_clientdata(client);
@@ -131,7 +131,7 @@ static int __devexit da9052_i2c_remove(struct i2c_client *client)
static struct i2c_driver da9052_i2c_driver = {
.probe = da9052_i2c_probe,
- .remove = __devexit_p(da9052_i2c_remove),
+ .remove = da9052_i2c_remove,
.id_table = da9052_i2c_id,
.driver = {
.name = "da9052",
diff --git a/drivers/mfd/da9052-spi.c b/drivers/mfd/da9052-spi.c
index dbeadc5a643..61d63b93576 100644
--- a/drivers/mfd/da9052-spi.c
+++ b/drivers/mfd/da9052-spi.c
@@ -21,7 +21,7 @@
#include <linux/mfd/da9052/da9052.h>
-static int __devinit da9052_spi_probe(struct spi_device *spi)
+static int da9052_spi_probe(struct spi_device *spi)
{
int ret;
const struct spi_device_id *id = spi_get_device_id(spi);
@@ -58,7 +58,7 @@ static int __devinit da9052_spi_probe(struct spi_device *spi)
return 0;
}
-static int __devexit da9052_spi_remove(struct spi_device *spi)
+static int da9052_spi_remove(struct spi_device *spi)
{
struct da9052 *da9052 = dev_get_drvdata(&spi->dev);
@@ -76,7 +76,7 @@ static struct spi_device_id da9052_spi_id[] = {
static struct spi_driver da9052_spi_driver = {
.probe = da9052_spi_probe,
- .remove = __devexit_p(da9052_spi_remove),
+ .remove = da9052_spi_remove,
.id_table = da9052_spi_id,
.driver = {
.name = "da9052",
diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c
index ff6c77f392b..f56a1a9f777 100644
--- a/drivers/mfd/da9055-core.c
+++ b/drivers/mfd/da9055-core.c
@@ -377,7 +377,7 @@ static struct regmap_irq_chip da9055_regmap_irq_chip = {
.num_irqs = ARRAY_SIZE(da9055_irqs),
};
-int __devinit da9055_device_init(struct da9055 *da9055)
+int da9055_device_init(struct da9055 *da9055)
{
struct da9055_pdata *pdata = da9055->dev->platform_data;
int ret;
@@ -412,7 +412,7 @@ err:
return ret;
}
-void __devexit da9055_device_exit(struct da9055 *da9055)
+void da9055_device_exit(struct da9055 *da9055)
{
regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data);
mfd_remove_devices(da9055->dev);
diff --git a/drivers/mfd/da9055-i2c.c b/drivers/mfd/da9055-i2c.c
index 88f6dca53ba..607387ffe8c 100644
--- a/drivers/mfd/da9055-i2c.c
+++ b/drivers/mfd/da9055-i2c.c
@@ -18,7 +18,7 @@
#include <linux/mfd/da9055/core.h>
-static int __devinit da9055_i2c_probe(struct i2c_client *i2c,
+static int da9055_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct da9055 *da9055;
@@ -44,7 +44,7 @@ static int __devinit da9055_i2c_probe(struct i2c_client *i2c,
return da9055_device_init(da9055);
}
-static int __devexit da9055_i2c_remove(struct i2c_client *i2c)
+static int da9055_i2c_remove(struct i2c_client *i2c)
{
struct da9055 *da9055 = i2c_get_clientdata(i2c);
@@ -60,7 +60,7 @@ static struct i2c_device_id da9055_i2c_id[] = {
static struct i2c_driver da9055_i2c_driver = {
.probe = da9055_i2c_probe,
- .remove = __devexit_p(da9055_i2c_remove),
+ .remove = da9055_i2c_remove,
.id_table = da9055_i2c_id,
.driver = {
.name = "da9055",
diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c
index 45e83a68641..c0bcc872af4 100644
--- a/drivers/mfd/davinci_voicecodec.c
+++ b/drivers/mfd/davinci_voicecodec.c
@@ -151,7 +151,7 @@ fail1:
return ret;
}
-static int __devexit davinci_vc_remove(struct platform_device *pdev)
+static int davinci_vc_remove(struct platform_device *pdev)
{
struct davinci_vc *davinci_vc = platform_get_drvdata(pdev);
@@ -174,7 +174,7 @@ static struct platform_driver davinci_vc_driver = {
.name = "davinci_voicecodec",
.owner = THIS_MODULE,
},
- .remove = __devexit_p(davinci_vc_remove),
+ .remove = davinci_vc_remove,
};
static int __init davinci_vc_init(void)
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 00b8b0f3dfb..dc569156937 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -31,6 +31,7 @@
#include <linux/mfd/abx500/ab8500.h>
#include <linux/regulator/db8500-prcmu.h>
#include <linux/regulator/machine.h>
+#include <linux/cpufreq.h>
#include <asm/hardware/gic.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
@@ -420,9 +421,6 @@ static struct {
static atomic_t ac_wake_req_state = ATOMIC_INIT(0);
-/* Functions definition */
-static void compute_armss_rate(void);
-
/* Spinlocks */
static DEFINE_SPINLOCK(prcmu_lock);
static DEFINE_SPINLOCK(clkout_lock);
@@ -1019,7 +1017,6 @@ int db8500_prcmu_set_arm_opp(u8 opp)
(mb1_transfer.ack.arm_opp != opp))
r = -EIO;
- compute_armss_rate();
mutex_unlock(&mb1_transfer.lock);
return r;
@@ -1169,12 +1166,12 @@ int db8500_prcmu_get_ape_opp(void)
}
/**
- * prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage
+ * db8500_prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage
* @enable: true to request the higher voltage, false to drop a request.
*
* Calls to this function to enable and disable requests must be balanced.
*/
-int prcmu_request_ape_opp_100_voltage(bool enable)
+int db8500_prcmu_request_ape_opp_100_voltage(bool enable)
{
int r = 0;
u8 header;
@@ -1669,13 +1666,8 @@ static unsigned long clock_rate(u8 clock)
else
return 0;
}
-static unsigned long latest_armss_rate;
-static unsigned long armss_rate(void)
-{
- return latest_armss_rate;
-}
-static void compute_armss_rate(void)
+static unsigned long armss_rate(void)
{
u32 r;
unsigned long rate;
@@ -1700,7 +1692,7 @@ static void compute_armss_rate(void)
rate = pll_rate(PRCM_PLLARM_FREQ, ROOT_CLOCK_RATE, PLL_DIV);
}
- latest_armss_rate = rate;
+ return rate;
}
static unsigned long dsiclk_rate(u8 n)
@@ -1820,6 +1812,35 @@ static long round_clock_rate(u8 clock, unsigned long rate)
return rounded_rate;
}
+/* CPU FREQ table, may be changed due to if MAX_OPP is supported. */
+static struct cpufreq_frequency_table db8500_cpufreq_table[] = {
+ { .frequency = 200000, .index = ARM_EXTCLK,},
+ { .frequency = 400000, .index = ARM_50_OPP,},
+ { .frequency = 800000, .index = ARM_100_OPP,},
+ { .frequency = CPUFREQ_TABLE_END,}, /* To be used for MAX_OPP. */
+ { .frequency = CPUFREQ_TABLE_END,},
+};
+
+static long round_armss_rate(unsigned long rate)
+{
+ long freq = 0;
+ int i = 0;
+
+ /* cpufreq table frequencies is in KHz. */
+ rate = rate / 1000;
+
+ /* Find the corresponding arm opp from the cpufreq table. */
+ while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) {
+ freq = db8500_cpufreq_table[i].frequency;
+ if (freq == rate)
+ break;
+ i++;
+ }
+
+ /* Return the last valid value, even if a match was not found. */
+ return freq * 1000;
+}
+
#define MIN_PLL_VCO_RATE 600000000ULL
#define MAX_PLL_VCO_RATE 1680640000ULL
@@ -1891,6 +1912,8 @@ long prcmu_round_clock_rate(u8 clock, unsigned long rate)
{
if (clock < PRCMU_NUM_REG_CLOCKS)
return round_clock_rate(clock, rate);
+ else if (clock == PRCMU_ARMSS)
+ return round_armss_rate(rate);
else if (clock == PRCMU_PLLDSI)
return round_plldsi_rate(rate);
else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))
@@ -1950,6 +1973,27 @@ static void set_clock_rate(u8 clock, unsigned long rate)
spin_unlock_irqrestore(&clk_mgt_lock, flags);
}
+static int set_armss_rate(unsigned long rate)
+{
+ int i = 0;
+
+ /* cpufreq table frequencies is in KHz. */
+ rate = rate / 1000;
+
+ /* Find the corresponding arm opp from the cpufreq table. */
+ while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) {
+ if (db8500_cpufreq_table[i].frequency == rate)
+ break;
+ i++;
+ }
+
+ if (db8500_cpufreq_table[i].frequency != rate)
+ return -EINVAL;
+
+ /* Set the new arm opp. */
+ return db8500_prcmu_set_arm_opp(db8500_cpufreq_table[i].index);
+}
+
static int set_plldsi_rate(unsigned long rate)
{
unsigned long src_rate;
@@ -2030,6 +2074,8 @@ int prcmu_set_clock_rate(u8 clock, unsigned long rate)
{
if (clock < PRCMU_NUM_REG_CLOCKS)
set_clock_rate(clock, rate);
+ else if (clock == PRCMU_ARMSS)
+ return set_armss_rate(rate);
else if (clock == PRCMU_PLLDSI)
return set_plldsi_rate(rate);
else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))
@@ -2754,8 +2800,6 @@ void __init db8500_prcmu_early_init(void)
init_completion(&mb5_transfer.work);
INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work);
-
- compute_armss_rate();
}
static void __init init_prcm_registers(void)
@@ -3020,6 +3064,8 @@ static struct mfd_cell db8500_prcmu_devs[] = {
{
.name = "cpufreq-u8500",
.of_compatible = "stericsson,cpufreq-u8500",
+ .platform_data = &db8500_cpufreq_table,
+ .pdata_size = sizeof(db8500_cpufreq_table),
},
{
.name = "ab8500-core",
@@ -3030,11 +3076,19 @@ static struct mfd_cell db8500_prcmu_devs[] = {
},
};
+static void db8500_prcmu_update_cpufreq(void)
+{
+ if (prcmu_has_arm_maxopp()) {
+ db8500_cpufreq_table[3].frequency = 1000000;
+ db8500_cpufreq_table[3].index = ARM_MAX_OPP;
+ }
+}
+
/**
* prcmu_fw_init - arch init call for the Linux PRCMU fw init logic
*
*/
-static int __devinit db8500_prcmu_probe(struct platform_device *pdev)
+static int db8500_prcmu_probe(struct platform_device *pdev)
{
struct ab8500_platform_data *ab8500_platdata = pdev->dev.platform_data;
struct device_node *np = pdev->dev.of_node;
@@ -3074,6 +3128,8 @@ static int __devinit db8500_prcmu_probe(struct platform_device *pdev)
if (cpu_is_u8500v20_or_later())
prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);
+ db8500_prcmu_update_cpufreq();
+
err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs,
ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL);
if (err) {
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c
index db662e2dcfa..b7a61f0f27a 100644
--- a/drivers/mfd/ezx-pcap.c
+++ b/drivers/mfd/ezx-pcap.c
@@ -371,7 +371,7 @@ static int pcap_remove_subdev(struct device *dev, void *unused)
return 0;
}
-static int __devinit pcap_add_subdev(struct pcap_chip *pcap,
+static int pcap_add_subdev(struct pcap_chip *pcap,
struct pcap_subdev *subdev)
{
struct platform_device *pdev;
@@ -391,7 +391,7 @@ static int __devinit pcap_add_subdev(struct pcap_chip *pcap,
return ret;
}
-static int __devexit ezx_pcap_remove(struct spi_device *spi)
+static int ezx_pcap_remove(struct spi_device *spi)
{
struct pcap_chip *pcap = dev_get_drvdata(&spi->dev);
struct pcap_platform_data *pdata = spi->dev.platform_data;
@@ -420,7 +420,7 @@ static int __devexit ezx_pcap_remove(struct spi_device *spi)
return 0;
}
-static int __devinit ezx_pcap_probe(struct spi_device *spi)
+static int ezx_pcap_probe(struct spi_device *spi)
{
struct pcap_platform_data *pdata = spi->dev.platform_data;
struct pcap_chip *pcap;
@@ -525,7 +525,7 @@ ret:
static struct spi_driver ezxpcap_driver = {
.probe = ezx_pcap_probe,
- .remove = __devexit_p(ezx_pcap_remove),
+ .remove = ezx_pcap_remove,
.driver = {
.name = "ezx-pcap",
.owner = THIS_MODULE,
diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c
index d55065cc324..324187c0c12 100644
--- a/drivers/mfd/htc-i2cpld.c
+++ b/drivers/mfd/htc-i2cpld.c
@@ -327,7 +327,7 @@ static void htcpld_chip_reset(struct i2c_client *client)
client, (chip_data->cache_out = chip_data->reset));
}
-static int __devinit htcpld_setup_chip_irq(
+static int htcpld_setup_chip_irq(
struct platform_device *pdev,
int chip_index)
{
@@ -361,7 +361,7 @@ static int __devinit htcpld_setup_chip_irq(
return ret;
}
-static int __devinit htcpld_register_chip_i2c(
+static int htcpld_register_chip_i2c(
struct platform_device *pdev,
int chip_index)
{
@@ -419,7 +419,7 @@ static int __devinit htcpld_register_chip_i2c(
return 0;
}
-static void __devinit htcpld_unregister_chip_i2c(
+static void htcpld_unregister_chip_i2c(
struct platform_device *pdev,
int chip_index)
{
@@ -434,7 +434,7 @@ static void __devinit htcpld_unregister_chip_i2c(
i2c_unregister_device(chip->client);
}
-static int __devinit htcpld_register_chip_gpio(
+static int htcpld_register_chip_gpio(
struct platform_device *pdev,
int chip_index)
{
@@ -501,7 +501,7 @@ static int __devinit htcpld_register_chip_gpio(
return 0;
}
-static int __devinit htcpld_setup_chips(struct platform_device *pdev)
+static int htcpld_setup_chips(struct platform_device *pdev)
{
struct htcpld_data *htcpld;
struct device *dev = &pdev->dev;
@@ -563,7 +563,7 @@ static int __devinit htcpld_setup_chips(struct platform_device *pdev)
return 0;
}
-static int __devinit htcpld_core_probe(struct platform_device *pdev)
+static int htcpld_core_probe(struct platform_device *pdev)
{
struct htcpld_data *htcpld;
struct device *dev = &pdev->dev;
diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c
index 266bdc5bd96..ab8d0b2739b 100644
--- a/drivers/mfd/intel_msic.c
+++ b/drivers/mfd/intel_msic.c
@@ -306,7 +306,7 @@ int intel_msic_irq_read(struct intel_msic *msic, unsigned short reg, u8 *val)
}
EXPORT_SYMBOL_GPL(intel_msic_irq_read);
-static int __devinit intel_msic_init_devices(struct intel_msic *msic)
+static int intel_msic_init_devices(struct intel_msic *msic)
{
struct platform_device *pdev = msic->pdev;
struct intel_msic_platform_data *pdata = pdev->dev.platform_data;
@@ -364,7 +364,7 @@ fail:
return ret;
}
-static void __devexit intel_msic_remove_devices(struct intel_msic *msic)
+static void intel_msic_remove_devices(struct intel_msic *msic)
{
struct platform_device *pdev = msic->pdev;
struct intel_msic_platform_data *pdata = pdev->dev.platform_data;
@@ -375,7 +375,7 @@ static void __devexit intel_msic_remove_devices(struct intel_msic *msic)
gpio_free(pdata->ocd->gpio);
}
-static int __devinit intel_msic_probe(struct platform_device *pdev)
+static int intel_msic_probe(struct platform_device *pdev)
{
struct intel_msic_platform_data *pdata = pdev->dev.platform_data;
struct intel_msic *msic;
@@ -445,7 +445,7 @@ static int __devinit intel_msic_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit intel_msic_remove(struct platform_device *pdev)
+static int intel_msic_remove(struct platform_device *pdev)
{
struct intel_msic *msic = platform_get_drvdata(pdev);
@@ -457,7 +457,7 @@ static int __devexit intel_msic_remove(struct platform_device *pdev)
static struct platform_driver intel_msic_driver = {
.probe = intel_msic_probe,
- .remove = __devexit_p(intel_msic_remove),
+ .remove = intel_msic_remove,
.driver = {
.name = "intel_msic",
.owner = THIS_MODULE,
diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c
index 965c4801df8..45ece11cc27 100644
--- a/drivers/mfd/janz-cmodio.c
+++ b/drivers/mfd/janz-cmodio.c
@@ -63,7 +63,7 @@ struct cmodio_device {
* Subdevices using the mfd-core API
*/
-static int __devinit cmodio_setup_subdevice(struct cmodio_device *priv,
+static int cmodio_setup_subdevice(struct cmodio_device *priv,
char *name, unsigned int devno,
unsigned int modno)
{
@@ -120,7 +120,7 @@ static int __devinit cmodio_setup_subdevice(struct cmodio_device *priv,
}
/* Probe each submodule using kernel parameters */
-static int __devinit cmodio_probe_submodules(struct cmodio_device *priv)
+static int cmodio_probe_submodules(struct cmodio_device *priv)
{
struct pci_dev *pdev = priv->pdev;
unsigned int num_probed = 0;
@@ -177,7 +177,7 @@ static const struct attribute_group cmodio_sysfs_attr_group = {
* PCI Driver
*/
-static int __devinit cmodio_pci_probe(struct pci_dev *dev,
+static int cmodio_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct cmodio_device *priv;
@@ -254,7 +254,7 @@ out_return:
return ret;
}
-static void __devexit cmodio_pci_remove(struct pci_dev *dev)
+static void cmodio_pci_remove(struct pci_dev *dev)
{
struct cmodio_device *priv = pci_get_drvdata(dev);
@@ -280,7 +280,7 @@ static struct pci_driver cmodio_pci_driver = {
.name = DRV_NAME,
.id_table = cmodio_pci_ids,
.probe = cmodio_pci_probe,
- .remove = __devexit_p(cmodio_pci_remove),
+ .remove = cmodio_pci_remove,
};
module_pci_driver(cmodio_pci_driver);
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c
index c6b6d7dda51..0b8b55bb9b1 100644
--- a/drivers/mfd/jz4740-adc.c
+++ b/drivers/mfd/jz4740-adc.c
@@ -202,7 +202,7 @@ static struct mfd_cell jz4740_adc_cells[] = {
},
};
-static int __devinit jz4740_adc_probe(struct platform_device *pdev)
+static int jz4740_adc_probe(struct platform_device *pdev)
{
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
@@ -307,7 +307,7 @@ err_free:
return ret;
}
-static int __devexit jz4740_adc_remove(struct platform_device *pdev)
+static int jz4740_adc_remove(struct platform_device *pdev)
{
struct jz4740_adc *adc = platform_get_drvdata(pdev);
@@ -332,7 +332,7 @@ static int __devexit jz4740_adc_remove(struct platform_device *pdev)
static struct platform_driver jz4740_adc_driver = {
.probe = jz4740_adc_probe,
- .remove = __devexit_p(jz4740_adc_remove),
+ .remove = jz4740_adc_remove,
.driver = {
.name = "jz4740-adc",
.owner = THIS_MODULE,
diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c
index 24212f45b20..ceebf2c1ea9 100644
--- a/drivers/mfd/lm3533-core.c
+++ b/drivers/mfd/lm3533-core.c
@@ -382,7 +382,7 @@ static struct attribute_group lm3533_attribute_group = {
.attrs = lm3533_attributes
};
-static int __devinit lm3533_device_als_init(struct lm3533 *lm3533)
+static int lm3533_device_als_init(struct lm3533 *lm3533)
{
struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
int ret;
@@ -405,7 +405,7 @@ static int __devinit lm3533_device_als_init(struct lm3533 *lm3533)
return 0;
}
-static int __devinit lm3533_device_bl_init(struct lm3533 *lm3533)
+static int lm3533_device_bl_init(struct lm3533 *lm3533)
{
struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
int i;
@@ -434,7 +434,7 @@ static int __devinit lm3533_device_bl_init(struct lm3533 *lm3533)
return 0;
}
-static int __devinit lm3533_device_led_init(struct lm3533 *lm3533)
+static int lm3533_device_led_init(struct lm3533 *lm3533)
{
struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
int i;
@@ -463,7 +463,7 @@ static int __devinit lm3533_device_led_init(struct lm3533 *lm3533)
return 0;
}
-static int __devinit lm3533_device_setup(struct lm3533 *lm3533,
+static int lm3533_device_setup(struct lm3533 *lm3533,
struct lm3533_platform_data *pdata)
{
int ret;
@@ -479,7 +479,7 @@ static int __devinit lm3533_device_setup(struct lm3533 *lm3533,
return 0;
}
-static int __devinit lm3533_device_init(struct lm3533 *lm3533)
+static int lm3533_device_init(struct lm3533 *lm3533)
{
struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
int ret;
@@ -534,7 +534,7 @@ err_disable:
return ret;
}
-static void __devexit lm3533_device_exit(struct lm3533 *lm3533)
+static void lm3533_device_exit(struct lm3533 *lm3533)
{
dev_dbg(lm3533->dev, "%s\n", __func__);
@@ -596,7 +596,7 @@ static struct regmap_config regmap_config = {
.precious_reg = lm3533_precious_register,
};
-static int __devinit lm3533_i2c_probe(struct i2c_client *i2c,
+static int lm3533_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct lm3533 *lm3533;
@@ -624,7 +624,7 @@ static int __devinit lm3533_i2c_probe(struct i2c_client *i2c,
return 0;
}
-static int __devexit lm3533_i2c_remove(struct i2c_client *i2c)
+static int lm3533_i2c_remove(struct i2c_client *i2c)
{
struct lm3533 *lm3533 = i2c_get_clientdata(i2c);
@@ -648,7 +648,7 @@ static struct i2c_driver lm3533_i2c_driver = {
},
.id_table = lm3533_i2c_ids,
.probe = lm3533_i2c_probe,
- .remove = __devexit_p(lm3533_i2c_remove),
+ .remove = lm3533_i2c_remove,
};
static int __init lm3533_i2c_init(void)
diff --git a/drivers/mfd/lp8788.c b/drivers/mfd/lp8788.c
index 3e94a699833..c3d3c9b4d3a 100644
--- a/drivers/mfd/lp8788.c
+++ b/drivers/mfd/lp8788.c
@@ -203,7 +203,7 @@ static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id)
ARRAY_SIZE(lp8788_devs), NULL, 0, NULL);
}
-static int __devexit lp8788_remove(struct i2c_client *cl)
+static int lp8788_remove(struct i2c_client *cl)
{
struct lp8788 *lp = i2c_get_clientdata(cl);
@@ -224,7 +224,7 @@ static struct i2c_driver lp8788_driver = {
.owner = THIS_MODULE,
},
.probe = lp8788_probe,
- .remove = __devexit_p(lp8788_remove),
+ .remove = lp8788_remove,
.id_table = lp8788_ids,
};
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
index a22544fe531..2ad24caa07d 100644
--- a/drivers/mfd/lpc_ich.c
+++ b/drivers/mfd/lpc_ich.c
@@ -196,7 +196,7 @@ enum lpc_chipsets {
LPC_LPT_LP, /* Lynx Point-LP */
};
-struct lpc_ich_info lpc_chipset_info[] __devinitdata = {
+struct lpc_ich_info lpc_chipset_info[] = {
[LPC_ICH] = {
.name = "ICH",
.iTCO_version = 1,
@@ -672,7 +672,7 @@ static void lpc_ich_restore_config_space(struct pci_dev *dev)
}
}
-static void __devinit lpc_ich_enable_acpi_space(struct pci_dev *dev)
+static void lpc_ich_enable_acpi_space(struct pci_dev *dev)
{
u8 reg_save;
@@ -681,7 +681,7 @@ static void __devinit lpc_ich_enable_acpi_space(struct pci_dev *dev)
lpc_ich_acpi_save = reg_save;
}
-static void __devinit lpc_ich_enable_gpio_space(struct pci_dev *dev)
+static void lpc_ich_enable_gpio_space(struct pci_dev *dev)
{
u8 reg_save;
@@ -690,7 +690,7 @@ static void __devinit lpc_ich_enable_gpio_space(struct pci_dev *dev)
lpc_ich_gpio_save = reg_save;
}
-static void __devinit lpc_ich_finalize_cell(struct mfd_cell *cell,
+static void lpc_ich_finalize_cell(struct mfd_cell *cell,
const struct pci_device_id *id)
{
cell->platform_data = &lpc_chipset_info[id->driver_data];
@@ -702,7 +702,7 @@ static void __devinit lpc_ich_finalize_cell(struct mfd_cell *cell,
* GPIO groups and it's enough to have access to one of these to instantiate
* the device.
*/
-static int __devinit lpc_ich_check_conflict_gpio(struct resource *res)
+static int lpc_ich_check_conflict_gpio(struct resource *res)
{
int ret;
u8 use_gpio = 0;
@@ -721,7 +721,7 @@ static int __devinit lpc_ich_check_conflict_gpio(struct resource *res)
return use_gpio ? use_gpio : ret;
}
-static int __devinit lpc_ich_init_gpio(struct pci_dev *dev,
+static int lpc_ich_init_gpio(struct pci_dev *dev,
const struct pci_device_id *id)
{
u32 base_addr_cfg;
@@ -798,7 +798,7 @@ gpio_done:
return ret;
}
-static int __devinit lpc_ich_init_wdt(struct pci_dev *dev,
+static int lpc_ich_init_wdt(struct pci_dev *dev,
const struct pci_device_id *id)
{
u32 base_addr_cfg;
@@ -852,7 +852,7 @@ wdt_done:
return ret;
}
-static int __devinit lpc_ich_probe(struct pci_dev *dev,
+static int lpc_ich_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
int ret;
@@ -878,7 +878,7 @@ static int __devinit lpc_ich_probe(struct pci_dev *dev,
return 0;
}
-static void __devexit lpc_ich_remove(struct pci_dev *dev)
+static void lpc_ich_remove(struct pci_dev *dev)
{
mfd_remove_devices(&dev->dev);
lpc_ich_restore_config_space(dev);
@@ -888,7 +888,7 @@ static struct pci_driver lpc_ich_driver = {
.name = "lpc_ich",
.id_table = lpc_ich_ids,
.probe = lpc_ich_probe,
- .remove = __devexit_p(lpc_ich_remove),
+ .remove = lpc_ich_remove,
};
static int __init lpc_ich_init(void)
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c
index f6b9c5c96b2..5624fcbba69 100644
--- a/drivers/mfd/lpc_sch.c
+++ b/drivers/mfd/lpc_sch.c
@@ -83,7 +83,7 @@ static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = {
};
MODULE_DEVICE_TABLE(pci, lpc_sch_ids);
-static int __devinit lpc_sch_probe(struct pci_dev *dev,
+static int lpc_sch_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
unsigned int base_addr_cfg;
@@ -164,7 +164,7 @@ out_dev:
return ret;
}
-static void __devexit lpc_sch_remove(struct pci_dev *dev)
+static void lpc_sch_remove(struct pci_dev *dev)
{
mfd_remove_devices(&dev->dev);
}
@@ -173,7 +173,7 @@ static struct pci_driver lpc_sch_driver = {
.name = "lpc_sch",
.id_table = lpc_sch_ids,
.probe = lpc_sch_probe,
- .remove = __devexit_p(lpc_sch_remove),
+ .remove = lpc_sch_remove,
};
module_pci_driver(lpc_sch_driver);
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
index d9e24c849a0..f6878f8db57 100644
--- a/drivers/mfd/max77686.c
+++ b/drivers/mfd/max77686.c
@@ -45,7 +45,7 @@ static struct regmap_config max77686_regmap_config = {
};
#ifdef CONFIG_OF
-static struct of_device_id __devinitdata max77686_pmic_dt_match[] = {
+static struct of_device_id max77686_pmic_dt_match[] = {
{.compatible = "maxim,max77686", .data = 0},
{},
};
diff --git a/drivers/mfd/max8907.c b/drivers/mfd/max8907.c
index 17f2593d82b..e9b1c93a3ad 100644
--- a/drivers/mfd/max8907.c
+++ b/drivers/mfd/max8907.c
@@ -183,7 +183,7 @@ static void max8907_power_off(void)
MAX8907_MASK_POWER_OFF, MAX8907_MASK_POWER_OFF);
}
-static __devinit int max8907_i2c_probe(struct i2c_client *i2c,
+static int max8907_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct max8907 *max8907;
@@ -288,7 +288,7 @@ err_alloc_drvdata:
return ret;
}
-static __devexit int max8907_i2c_remove(struct i2c_client *i2c)
+static int max8907_i2c_remove(struct i2c_client *i2c)
{
struct max8907 *max8907 = i2c_get_clientdata(i2c);
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c
index 9f54c04912f..e32466e865b 100644
--- a/drivers/mfd/max8925-core.c
+++ b/drivers/mfd/max8925-core.c
@@ -19,12 +19,12 @@
#include <linux/mfd/core.h>
#include <linux/mfd/max8925.h>
-static struct resource bk_resources[] __devinitdata = {
+static struct resource bk_resources[] = {
{ 0x84, 0x84, "mode control", IORESOURCE_REG, },
{ 0x85, 0x85, "control", IORESOURCE_REG, },
};
-static struct mfd_cell bk_devs[] __devinitdata = {
+static struct mfd_cell bk_devs[] = {
{
.name = "max8925-backlight",
.num_resources = ARRAY_SIZE(bk_resources),
@@ -110,99 +110,99 @@ static struct mfd_cell onkey_devs[] = {
},
};
-static struct resource sd1_resources[] __devinitdata = {
+static struct resource sd1_resources[] = {
{0x06, 0x06, "sdv", IORESOURCE_REG, },
};
-static struct resource sd2_resources[] __devinitdata = {
+static struct resource sd2_resources[] = {
{0x09, 0x09, "sdv", IORESOURCE_REG, },
};
-static struct resource sd3_resources[] __devinitdata = {
+static struct resource sd3_resources[] = {
{0x0c, 0x0c, "sdv", IORESOURCE_REG, },
};
-static struct resource ldo1_resources[] __devinitdata = {
+static struct resource ldo1_resources[] = {
{0x1a, 0x1a, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo2_resources[] __devinitdata = {
+static struct resource ldo2_resources[] = {
{0x1e, 0x1e, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo3_resources[] __devinitdata = {
+static struct resource ldo3_resources[] = {
{0x22, 0x22, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo4_resources[] __devinitdata = {
+static struct resource ldo4_resources[] = {
{0x26, 0x26, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo5_resources[] __devinitdata = {
+static struct resource ldo5_resources[] = {
{0x2a, 0x2a, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo6_resources[] __devinitdata = {
+static struct resource ldo6_resources[] = {
{0x2e, 0x2e, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo7_resources[] __devinitdata = {
+static struct resource ldo7_resources[] = {
{0x32, 0x32, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo8_resources[] __devinitdata = {
+static struct resource ldo8_resources[] = {
{0x36, 0x36, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo9_resources[] __devinitdata = {
+static struct resource ldo9_resources[] = {
{0x3a, 0x3a, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo10_resources[] __devinitdata = {
+static struct resource ldo10_resources[] = {
{0x3e, 0x3e, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo11_resources[] __devinitdata = {
+static struct resource ldo11_resources[] = {
{0x42, 0x42, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo12_resources[] __devinitdata = {
+static struct resource ldo12_resources[] = {
{0x46, 0x46, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo13_resources[] __devinitdata = {
+static struct resource ldo13_resources[] = {
{0x4a, 0x4a, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo14_resources[] __devinitdata = {
+static struct resource ldo14_resources[] = {
{0x4e, 0x4e, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo15_resources[] __devinitdata = {
+static struct resource ldo15_resources[] = {
{0x52, 0x52, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo16_resources[] __devinitdata = {
+static struct resource ldo16_resources[] = {
{0x12, 0x12, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo17_resources[] __devinitdata = {
+static struct resource ldo17_resources[] = {
{0x16, 0x16, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo18_resources[] __devinitdata = {
+static struct resource ldo18_resources[] = {
{0x74, 0x74, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo19_resources[] __devinitdata = {
+static struct resource ldo19_resources[] = {
{0x5e, 0x5e, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo20_resources[] __devinitdata = {
+static struct resource ldo20_resources[] = {
{0x9e, 0x9e, "ldov", IORESOURCE_REG, },
};
-static struct mfd_cell reg_devs[] __devinitdata = {
+static struct mfd_cell reg_devs[] = {
{
.name = "max8925-regulator",
.id = 0,
@@ -714,7 +714,7 @@ tsc_irq:
return 0;
}
-static void __devinit init_regulator(struct max8925_chip *chip,
+static void init_regulator(struct max8925_chip *chip,
struct max8925_platform_data *pdata)
{
int ret;
@@ -821,7 +821,7 @@ static void __devinit init_regulator(struct max8925_chip *chip,
}
}
-int __devinit max8925_device_init(struct max8925_chip *chip,
+int max8925_device_init(struct max8925_chip *chip,
struct max8925_platform_data *pdata)
{
int ret;
@@ -901,7 +901,7 @@ out:
return ret;
}
-void __devexit max8925_device_exit(struct max8925_chip *chip)
+void max8925_device_exit(struct max8925_chip *chip)
{
if (chip->core_irq)
free_irq(chip->core_irq, chip);
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c
index d9e4b36edee..00b5b456063 100644
--- a/drivers/mfd/max8925-i2c.c
+++ b/drivers/mfd/max8925-i2c.c
@@ -135,7 +135,7 @@ static const struct i2c_device_id max8925_id_table[] = {
};
MODULE_DEVICE_TABLE(i2c, max8925_id_table);
-static int __devinit max8925_probe(struct i2c_client *client,
+static int max8925_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct max8925_platform_data *pdata = client->dev.platform_data;
@@ -168,7 +168,7 @@ static int __devinit max8925_probe(struct i2c_client *client,
return 0;
}
-static int __devexit max8925_remove(struct i2c_client *client)
+static int max8925_remove(struct i2c_client *client)
{
struct max8925_chip *chip = i2c_get_clientdata(client);
@@ -210,7 +210,7 @@ static struct i2c_driver max8925_driver = {
.pm = &max8925_pm_ops,
},
.probe = max8925_probe,
- .remove = __devexit_p(max8925_remove),
+ .remove = max8925_remove,
.id_table = max8925_id_table,
};
diff --git a/drivers/mfd/mc13xxx-i2c.c b/drivers/mfd/mc13xxx-i2c.c
index 9d18dde3cd2..7957999f30b 100644
--- a/drivers/mfd/mc13xxx-i2c.c
+++ b/drivers/mfd/mc13xxx-i2c.c
@@ -85,7 +85,7 @@ static int mc13xxx_i2c_probe(struct i2c_client *client,
return ret;
}
-static int __devexit mc13xxx_i2c_remove(struct i2c_client *client)
+static int mc13xxx_i2c_remove(struct i2c_client *client)
{
struct mc13xxx *mc13xxx = dev_get_drvdata(&client->dev);
@@ -102,7 +102,7 @@ static struct i2c_driver mc13xxx_i2c_driver = {
.of_match_table = mc13xxx_dt_ids,
},
.probe = mc13xxx_i2c_probe,
- .remove = __devexit_p(mc13xxx_i2c_remove),
+ .remove = mc13xxx_i2c_remove,
};
static int __init mc13xxx_i2c_init(void)
diff --git a/drivers/mfd/mc13xxx-spi.c b/drivers/mfd/mc13xxx-spi.c
index 0bdb43a0aff..cb32f69d80b 100644
--- a/drivers/mfd/mc13xxx-spi.c
+++ b/drivers/mfd/mc13xxx-spi.c
@@ -159,7 +159,7 @@ static int mc13xxx_spi_probe(struct spi_device *spi)
return ret;
}
-static int __devexit mc13xxx_spi_remove(struct spi_device *spi)
+static int mc13xxx_spi_remove(struct spi_device *spi)
{
struct mc13xxx *mc13xxx = dev_get_drvdata(&spi->dev);
@@ -176,7 +176,7 @@ static struct spi_driver mc13xxx_spi_driver = {
.of_match_table = mc13xxx_dt_ids,
},
.probe = mc13xxx_spi_probe,
- .remove = __devexit_p(mc13xxx_spi_remove),
+ .remove = mc13xxx_spi_remove,
};
static int __init mc13xxx_init(void)
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 23cec57c02b..29b8ed21213 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -464,7 +464,7 @@ static void omap_usbhs_deinit(struct device *dev)
*
* Allocates basic resources for this USB host controller.
*/
-static int __devinit usbhs_omap_probe(struct platform_device *pdev)
+static int usbhs_omap_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct usbhs_omap_platform_data *pdata = dev->platform_data;
@@ -652,7 +652,7 @@ end_probe:
*
* Reverses the effect of usbhs_omap_probe().
*/
-static int __devexit usbhs_omap_remove(struct platform_device *pdev)
+static int usbhs_omap_remove(struct platform_device *pdev)
{
struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c
index 4b7757b8430..401b976e3af 100644
--- a/drivers/mfd/omap-usb-tll.c
+++ b/drivers/mfd/omap-usb-tll.c
@@ -200,7 +200,7 @@ static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
*
* Allocates basic resources for this USB host controller.
*/
-static int __devinit usbtll_omap_probe(struct platform_device *pdev)
+static int usbtll_omap_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct usbtll_omap_platform_data *pdata = dev->platform_data;
@@ -348,7 +348,7 @@ end:
*
* Reverses the effect of usbtll_omap_probe().
*/
-static int __devexit usbtll_omap_remove(struct platform_device *pdev)
+static int usbtll_omap_remove(struct platform_device *pdev)
{
struct usbtll_omap *tll = platform_get_drvdata(pdev);
@@ -424,7 +424,7 @@ static struct platform_driver usbtll_omap_driver = {
.pm = &usbtllomap_dev_pm_ops,
},
.probe = usbtll_omap_probe,
- .remove = __devexit_p(usbtll_omap_remove),
+ .remove = usbtll_omap_remove,
};
int omap_tll_enable(void)
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index 4f8d6e6b19a..6ffd7a2affd 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -247,7 +247,7 @@ static struct regmap_irq_chip palmas_irq_chip = {
PALMAS_INT1_MASK),
};
-static void __devinit palmas_dt_to_pdata(struct device_node *node,
+static void palmas_dt_to_pdata(struct device_node *node,
struct palmas_platform_data *pdata)
{
int ret;
@@ -275,7 +275,7 @@ static void __devinit palmas_dt_to_pdata(struct device_node *node,
PALMAS_POWER_CTRL_ENABLE2_MASK;
}
-static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
+static int palmas_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct palmas *palmas;
@@ -492,7 +492,7 @@ static const struct i2c_device_id palmas_i2c_id[] = {
};
MODULE_DEVICE_TABLE(i2c, palmas_i2c_id);
-static struct of_device_id __devinitdata of_palmas_match_tbl[] = {
+static struct of_device_id of_palmas_match_tbl[] = {
{ .compatible = "ti,palmas", },
{ /* end */ }
};
diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c
index 3927c17e417..18b53cb72fe 100644
--- a/drivers/mfd/pcf50633-adc.c
+++ b/drivers/mfd/pcf50633-adc.c
@@ -199,7 +199,7 @@ static void pcf50633_adc_irq(int irq, void *data)
kfree(req);
}
-static int __devinit pcf50633_adc_probe(struct platform_device *pdev)
+static int pcf50633_adc_probe(struct platform_device *pdev)
{
struct pcf50633_adc *adc;
@@ -218,7 +218,7 @@ static int __devinit pcf50633_adc_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit pcf50633_adc_remove(struct platform_device *pdev)
+static int pcf50633_adc_remove(struct platform_device *pdev)
{
struct pcf50633_adc *adc = platform_get_drvdata(pdev);
int i, head;
@@ -246,7 +246,7 @@ static struct platform_driver pcf50633_adc_driver = {
.name = "pcf50633-adc",
},
.probe = pcf50633_adc_probe,
- .remove = __devexit_p(pcf50633_adc_remove),
+ .remove = pcf50633_adc_remove,
};
module_platform_driver(pcf50633_adc_driver);
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 45ce1fb5a54..64803f13bce 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -191,7 +191,7 @@ static struct regmap_config pcf50633_regmap_config = {
.val_bits = 8,
};
-static int __devinit pcf50633_probe(struct i2c_client *client,
+static int pcf50633_probe(struct i2c_client *client,
const struct i2c_device_id *ids)
{
struct pcf50633 *pcf;
@@ -275,7 +275,7 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
return 0;
}
-static int __devexit pcf50633_remove(struct i2c_client *client)
+static int pcf50633_remove(struct i2c_client *client)
{
struct pcf50633 *pcf = i2c_get_clientdata(client);
int i;
@@ -308,7 +308,7 @@ static struct i2c_driver pcf50633_driver = {
},
.id_table = pcf50633_id_table,
.probe = pcf50633_probe,
- .remove = __devexit_p(pcf50633_remove),
+ .remove = pcf50633_remove,
};
static int __init pcf50633_init(void)
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index e873b15753d..d4b297cbd80 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -80,7 +80,7 @@ static struct pm8xxx_drvdata pm8921_drvdata = {
.pmic_read_irq_stat = pm8921_read_irq_stat,
};
-static int __devinit pm8921_add_subdevices(const struct pm8921_platform_data
+static int pm8921_add_subdevices(const struct pm8921_platform_data
*pdata,
struct pm8921 *pmic,
u32 rev)
@@ -104,7 +104,7 @@ static int __devinit pm8921_add_subdevices(const struct pm8921_platform_data
return ret;
}
-static int __devinit pm8921_probe(struct platform_device *pdev)
+static int pm8921_probe(struct platform_device *pdev)
{
const struct pm8921_platform_data *pdata = pdev->dev.platform_data;
struct pm8921 *pmic;
@@ -165,7 +165,7 @@ err_read_rev:
return rc;
}
-static int __devexit pm8921_remove(struct platform_device *pdev)
+static int pm8921_remove(struct platform_device *pdev)
{
struct pm8xxx_drvdata *drvdata;
struct pm8921 *pmic = NULL;
@@ -187,7 +187,7 @@ static int __devexit pm8921_remove(struct platform_device *pdev)
static struct platform_driver pm8921_driver = {
.probe = pm8921_probe,
- .remove = __devexit_p(pm8921_remove),
+ .remove = pm8921_remove,
.driver = {
.name = "pm8921-core",
.owner = THIS_MODULE,
diff --git a/drivers/mfd/pm8xxx-irq.c b/drivers/mfd/pm8xxx-irq.c
index d452dd01308..1360e20adf1 100644
--- a/drivers/mfd/pm8xxx-irq.c
+++ b/drivers/mfd/pm8xxx-irq.c
@@ -309,7 +309,7 @@ bail_out:
}
EXPORT_SYMBOL_GPL(pm8xxx_get_irq_stat);
-struct pm_irq_chip * __devinit pm8xxx_irq_init(struct device *dev,
+struct pm_irq_chip * pm8xxx_irq_init(struct device *dev,
const struct pm8xxx_irq_platform_data *pdata)
{
struct pm_irq_chip *chip;
@@ -363,7 +363,7 @@ struct pm_irq_chip * __devinit pm8xxx_irq_init(struct device *dev,
return chip;
}
-int __devexit pm8xxx_irq_exit(struct pm_irq_chip *chip)
+int pm8xxx_irq_exit(struct pm_irq_chip *chip)
{
irq_set_chained_handler(chip->devirq, NULL);
kfree(chip);
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c
index f1a024ecdb1..14bdaccefbe 100644
--- a/drivers/mfd/rc5t583.c
+++ b/drivers/mfd/rc5t583.c
@@ -246,7 +246,7 @@ static const struct regmap_config rc5t583_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
-static int __devinit rc5t583_i2c_probe(struct i2c_client *i2c,
+static int rc5t583_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct rc5t583 *rc5t583;
@@ -303,7 +303,7 @@ err_add_devs:
return ret;
}
-static int __devexit rc5t583_i2c_remove(struct i2c_client *i2c)
+static int rc5t583_i2c_remove(struct i2c_client *i2c)
{
struct rc5t583 *rc5t583 = i2c_get_clientdata(i2c);
@@ -325,7 +325,7 @@ static struct i2c_driver rc5t583_i2c_driver = {
.owner = THIS_MODULE,
},
.probe = rc5t583_i2c_probe,
- .remove = __devexit_p(rc5t583_i2c_remove),
+ .remove = rc5t583_i2c_remove,
.id_table = rc5t583_i2c_id,
};
diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c
index fbabc3cbe35..21b7bef7350 100644
--- a/drivers/mfd/rdc321x-southbridge.c
+++ b/drivers/mfd/rdc321x-southbridge.c
@@ -72,7 +72,7 @@ static struct mfd_cell rdc321x_sb_cells[] = {
},
};
-static int __devinit rdc321x_sb_probe(struct pci_dev *pdev,
+static int rdc321x_sb_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
int err;
@@ -91,7 +91,7 @@ static int __devinit rdc321x_sb_probe(struct pci_dev *pdev,
NULL, 0, NULL);
}
-static void __devexit rdc321x_sb_remove(struct pci_dev *pdev)
+static void rdc321x_sb_remove(struct pci_dev *pdev)
{
mfd_remove_devices(&pdev->dev);
}
@@ -106,7 +106,7 @@ static struct pci_driver rdc321x_sb_driver = {
.name = "RDC321x Southbridge",
.id_table = rdc321x_sb_table,
.probe = rdc321x_sb_probe,
- .remove = __devexit_p(rdc321x_sb_remove),
+ .remove = rdc321x_sb_remove,
};
module_pci_driver(rdc321x_sb_driver);
diff --git a/drivers/mfd/rtl8411.c b/drivers/mfd/rtl8411.c
new file mode 100644
index 00000000000..89f046ca9e4
--- /dev/null
+++ b/drivers/mfd/rtl8411.c
@@ -0,0 +1,251 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Wei WANG <wei_wang@realsil.com.cn>
+ * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/mfd/rtsx_pci.h>
+
+#include "rtsx_pcr.h"
+
+static u8 rtl8411_get_ic_version(struct rtsx_pcr *pcr)
+{
+ u8 val;
+
+ rtsx_pci_read_register(pcr, SYS_VER, &val);
+ return val & 0x0F;
+}
+
+static int rtl8411_extra_init_hw(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CD_PAD_CTL,
+ CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
+}
+
+static int rtl8411_turn_on_led(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x00);
+}
+
+static int rtl8411_turn_off_led(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x01);
+}
+
+static int rtl8411_enable_auto_blink(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0xFF, 0x0D);
+}
+
+static int rtl8411_disable_auto_blink(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0x08, 0x00);
+}
+
+static int rtl8411_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+ int err;
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+ BPP_POWER_MASK, BPP_POWER_5_PERCENT_ON);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CTL,
+ BPP_LDO_POWB, BPP_LDO_SUSPEND);
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ /* To avoid too large in-rush current */
+ udelay(150);
+
+ err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
+ BPP_POWER_MASK, BPP_POWER_10_PERCENT_ON);
+ if (err < 0)
+ return err;
+
+ udelay(150);
+
+ err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
+ BPP_POWER_MASK, BPP_POWER_15_PERCENT_ON);
+ if (err < 0)
+ return err;
+
+ udelay(150);
+
+ err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
+ BPP_POWER_MASK, BPP_POWER_ON);
+ if (err < 0)
+ return err;
+
+ return rtsx_pci_write_register(pcr, LDO_CTL, BPP_LDO_POWB, BPP_LDO_ON);
+}
+
+static int rtl8411_card_power_off(struct rtsx_pcr *pcr, int card)
+{
+ int err;
+
+ err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
+ BPP_POWER_MASK, BPP_POWER_OFF);
+ if (err < 0)
+ return err;
+
+ return rtsx_pci_write_register(pcr, LDO_CTL,
+ BPP_LDO_POWB, BPP_LDO_SUSPEND);
+}
+
+static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr)
+{
+ unsigned int card_exist;
+
+ card_exist = rtsx_pci_readl(pcr, RTSX_BIPR);
+ card_exist &= CARD_EXIST;
+ if (!card_exist) {
+ /* Enable card CD */
+ rtsx_pci_write_register(pcr, CD_PAD_CTL,
+ CD_DISABLE_MASK, CD_ENABLE);
+ /* Enable card interrupt */
+ rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x00);
+ return 0;
+ }
+
+ if (hweight32(card_exist) > 1) {
+ rtsx_pci_write_register(pcr, CARD_PWR_CTL,
+ BPP_POWER_MASK, BPP_POWER_5_PERCENT_ON);
+ msleep(100);
+
+ card_exist = rtsx_pci_readl(pcr, RTSX_BIPR);
+ if (card_exist & MS_EXIST)
+ card_exist = MS_EXIST;
+ else if (card_exist & SD_EXIST)
+ card_exist = SD_EXIST;
+ else
+ card_exist = 0;
+
+ rtsx_pci_write_register(pcr, CARD_PWR_CTL,
+ BPP_POWER_MASK, BPP_POWER_OFF);
+
+ dev_dbg(&(pcr->pci->dev),
+ "After CD deglitch, card_exist = 0x%x\n",
+ card_exist);
+ }
+
+ if (card_exist & MS_EXIST) {
+ /* Disable SD interrupt */
+ rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x40);
+ rtsx_pci_write_register(pcr, CD_PAD_CTL,
+ CD_DISABLE_MASK, MS_CD_EN_ONLY);
+ } else if (card_exist & SD_EXIST) {
+ /* Disable MS interrupt */
+ rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x80);
+ rtsx_pci_write_register(pcr, CD_PAD_CTL,
+ CD_DISABLE_MASK, SD_CD_EN_ONLY);
+ }
+
+ return card_exist;
+}
+
+static const struct pcr_ops rtl8411_pcr_ops = {
+ .extra_init_hw = rtl8411_extra_init_hw,
+ .optimize_phy = NULL,
+ .turn_on_led = rtl8411_turn_on_led,
+ .turn_off_led = rtl8411_turn_off_led,
+ .enable_auto_blink = rtl8411_enable_auto_blink,
+ .disable_auto_blink = rtl8411_disable_auto_blink,
+ .card_power_on = rtl8411_card_power_on,
+ .card_power_off = rtl8411_card_power_off,
+ .cd_deglitch = rtl8411_cd_deglitch,
+};
+
+/* SD Pull Control Enable:
+ * SD_DAT[3:0] ==> pull up
+ * SD_CD ==> pull up
+ * SD_WP ==> pull up
+ * SD_CMD ==> pull up
+ * SD_CLK ==> pull down
+ */
+static const u32 rtl8411_sd_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xA9),
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x09),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
+ 0,
+};
+
+/* SD Pull Control Disable:
+ * SD_DAT[3:0] ==> pull down
+ * SD_CD ==> pull up
+ * SD_WP ==> pull down
+ * SD_CMD ==> pull down
+ * SD_CLK ==> pull down
+ */
+static const u32 rtl8411_sd_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95),
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
+ 0,
+};
+
+/* MS Pull Control Enable:
+ * MS CD ==> pull up
+ * others ==> pull down
+ */
+static const u32 rtl8411_ms_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95),
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x05),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
+ 0,
+};
+
+/* MS Pull Control Disable:
+ * MS CD ==> pull up
+ * others ==> pull down
+ */
+static const u32 rtl8411_ms_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95),
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
+ 0,
+};
+
+void rtl8411_init_params(struct rtsx_pcr *pcr)
+{
+ pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
+ pcr->num_slots = 2;
+ pcr->ops = &rtl8411_pcr_ops;
+
+ pcr->ic_version = rtl8411_get_ic_version(pcr);
+ pcr->sd_pull_ctl_enable_tbl = rtl8411_sd_pull_ctl_enable_tbl;
+ pcr->sd_pull_ctl_disable_tbl = rtl8411_sd_pull_ctl_disable_tbl;
+ pcr->ms_pull_ctl_enable_tbl = rtl8411_ms_pull_ctl_enable_tbl;
+ pcr->ms_pull_ctl_disable_tbl = rtl8411_ms_pull_ctl_disable_tbl;
+}
diff --git a/drivers/mfd/rts5209.c b/drivers/mfd/rts5209.c
new file mode 100644
index 00000000000..283a4f14808
--- /dev/null
+++ b/drivers/mfd/rts5209.c
@@ -0,0 +1,223 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Wei WANG <wei_wang@realsil.com.cn>
+ * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mfd/rtsx_pci.h>
+
+#include "rtsx_pcr.h"
+
+static u8 rts5209_get_ic_version(struct rtsx_pcr *pcr)
+{
+ u8 val;
+
+ val = rtsx_pci_readb(pcr, 0x1C);
+ return val & 0x0F;
+}
+
+static void rts5209_init_vendor_cfg(struct rtsx_pcr *pcr)
+{
+ u32 val;
+
+ rtsx_pci_read_config_dword(pcr, 0x724, &val);
+ dev_dbg(&(pcr->pci->dev), "Cfg 0x724: 0x%x\n", val);
+
+ if (!(val & 0x80)) {
+ if (val & 0x08)
+ pcr->ms_pmos = false;
+ else
+ pcr->ms_pmos = true;
+ }
+}
+
+static int rts5209_extra_init_hw(struct rtsx_pcr *pcr)
+{
+ rtsx_pci_init_cmd(pcr);
+
+ /* Turn off LED */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO, 0xFF, 0x03);
+ /* Configure GPIO as output */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO_DIR, 0xFF, 0x03);
+
+ return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static int rts5209_optimize_phy(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_phy_register(pcr, 0x00, 0xB966);
+}
+
+static int rts5209_turn_on_led(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x00);
+}
+
+static int rts5209_turn_off_led(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x01);
+}
+
+static int rts5209_enable_auto_blink(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0xFF, 0x0D);
+}
+
+static int rts5209_disable_auto_blink(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0x08, 0x00);
+}
+
+static int rts5209_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+ int err;
+ u8 pwr_mask, partial_pwr_on, pwr_on;
+
+ pwr_mask = SD_POWER_MASK;
+ partial_pwr_on = SD_PARTIAL_POWER_ON;
+ pwr_on = SD_POWER_ON;
+
+ if (pcr->ms_pmos && (card == RTSX_MS_CARD)) {
+ pwr_mask = MS_POWER_MASK;
+ partial_pwr_on = MS_PARTIAL_POWER_ON;
+ pwr_on = MS_POWER_ON;
+ }
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+ pwr_mask, partial_pwr_on);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+ LDO3318_PWR_MASK, 0x04);
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ /* To avoid too large in-rush current */
+ udelay(150);
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, pwr_mask, pwr_on);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+ LDO3318_PWR_MASK, 0x00);
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card)
+{
+ u8 pwr_mask, pwr_off;
+
+ pwr_mask = SD_POWER_MASK;
+ pwr_off = SD_POWER_OFF;
+
+ if (pcr->ms_pmos && (card == RTSX_MS_CARD)) {
+ pwr_mask = MS_POWER_MASK;
+ pwr_off = MS_POWER_OFF;
+ }
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+ pwr_mask | PMOS_STRG_MASK, pwr_off | PMOS_STRG_400mA);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+ LDO3318_PWR_MASK, 0X06);
+ return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static const struct pcr_ops rts5209_pcr_ops = {
+ .extra_init_hw = rts5209_extra_init_hw,
+ .optimize_phy = rts5209_optimize_phy,
+ .turn_on_led = rts5209_turn_on_led,
+ .turn_off_led = rts5209_turn_off_led,
+ .enable_auto_blink = rts5209_enable_auto_blink,
+ .disable_auto_blink = rts5209_disable_auto_blink,
+ .card_power_on = rts5209_card_power_on,
+ .card_power_off = rts5209_card_power_off,
+ .cd_deglitch = NULL,
+};
+
+/* SD Pull Control Enable:
+ * SD_DAT[3:0] ==> pull up
+ * SD_CD ==> pull up
+ * SD_WP ==> pull up
+ * SD_CMD ==> pull up
+ * SD_CLK ==> pull down
+ */
+static const u32 rts5209_sd_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9),
+ 0,
+};
+
+/* SD Pull Control Disable:
+ * SD_DAT[3:0] ==> pull down
+ * SD_CD ==> pull up
+ * SD_WP ==> pull down
+ * SD_CMD ==> pull down
+ * SD_CLK ==> pull down
+ */
+static const u32 rts5209_sd_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5),
+ 0,
+};
+
+/* MS Pull Control Enable:
+ * MS CD ==> pull up
+ * others ==> pull down
+ */
+static const u32 rts5209_ms_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
+ 0,
+};
+
+/* MS Pull Control Disable:
+ * MS CD ==> pull up
+ * others ==> pull down
+ */
+static const u32 rts5209_ms_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
+ 0,
+};
+
+void rts5209_init_params(struct rtsx_pcr *pcr)
+{
+ pcr->extra_caps = EXTRA_CAPS_SD_SDR50 |
+ EXTRA_CAPS_SD_SDR104 | EXTRA_CAPS_MMC_8BIT;
+ pcr->num_slots = 2;
+ pcr->ops = &rts5209_pcr_ops;
+
+ rts5209_init_vendor_cfg(pcr);
+
+ pcr->ic_version = rts5209_get_ic_version(pcr);
+ pcr->sd_pull_ctl_enable_tbl = rts5209_sd_pull_ctl_enable_tbl;
+ pcr->sd_pull_ctl_disable_tbl = rts5209_sd_pull_ctl_disable_tbl;
+ pcr->ms_pull_ctl_enable_tbl = rts5209_ms_pull_ctl_enable_tbl;
+ pcr->ms_pull_ctl_disable_tbl = rts5209_ms_pull_ctl_disable_tbl;
+}
diff --git a/drivers/mfd/rts5229.c b/drivers/mfd/rts5229.c
new file mode 100644
index 00000000000..b9dbab266fd
--- /dev/null
+++ b/drivers/mfd/rts5229.c
@@ -0,0 +1,205 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Wei WANG <wei_wang@realsil.com.cn>
+ * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mfd/rtsx_pci.h>
+
+#include "rtsx_pcr.h"
+
+static u8 rts5229_get_ic_version(struct rtsx_pcr *pcr)
+{
+ u8 val;
+
+ rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val);
+ return val & 0x0F;
+}
+
+static int rts5229_extra_init_hw(struct rtsx_pcr *pcr)
+{
+ rtsx_pci_init_cmd(pcr);
+
+ /* Configure GPIO as output */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
+ /* Switch LDO3318 source from DV33 to card_3v3 */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
+ /* LED shine disabled, set initial shine cycle period */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
+
+ return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static int rts5229_optimize_phy(struct rtsx_pcr *pcr)
+{
+ /* Optimize RX sensitivity */
+ return rtsx_pci_write_phy_register(pcr, 0x00, 0xBA42);
+}
+
+static int rts5229_turn_on_led(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02);
+}
+
+static int rts5229_turn_off_led(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00);
+}
+
+static int rts5229_enable_auto_blink(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08);
+}
+
+static int rts5229_disable_auto_blink(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00);
+}
+
+static int rts5229_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+ int err;
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+ SD_POWER_MASK, SD_PARTIAL_POWER_ON);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+ LDO3318_PWR_MASK, 0x02);
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ /* To avoid too large in-rush current */
+ udelay(150);
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+ SD_POWER_MASK, SD_POWER_ON);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+ LDO3318_PWR_MASK, 0x06);
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card)
+{
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+ SD_POWER_MASK | PMOS_STRG_MASK,
+ SD_POWER_OFF | PMOS_STRG_400mA);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+ LDO3318_PWR_MASK, 0X00);
+ return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static const struct pcr_ops rts5229_pcr_ops = {
+ .extra_init_hw = rts5229_extra_init_hw,
+ .optimize_phy = rts5229_optimize_phy,
+ .turn_on_led = rts5229_turn_on_led,
+ .turn_off_led = rts5229_turn_off_led,
+ .enable_auto_blink = rts5229_enable_auto_blink,
+ .disable_auto_blink = rts5229_disable_auto_blink,
+ .card_power_on = rts5229_card_power_on,
+ .card_power_off = rts5229_card_power_off,
+ .cd_deglitch = NULL,
+};
+
+/* SD Pull Control Enable:
+ * SD_DAT[3:0] ==> pull up
+ * SD_CD ==> pull up
+ * SD_WP ==> pull up
+ * SD_CMD ==> pull up
+ * SD_CLK ==> pull down
+ */
+static const u32 rts5229_sd_pull_ctl_enable_tbl1[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9),
+ 0,
+};
+
+/* For RTS5229 version C */
+static const u32 rts5229_sd_pull_ctl_enable_tbl2[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD9),
+ 0,
+};
+
+/* SD Pull Control Disable:
+ * SD_DAT[3:0] ==> pull down
+ * SD_CD ==> pull up
+ * SD_WP ==> pull down
+ * SD_CMD ==> pull down
+ * SD_CLK ==> pull down
+ */
+static const u32 rts5229_sd_pull_ctl_disable_tbl1[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5),
+ 0,
+};
+
+/* For RTS5229 version C */
+static const u32 rts5229_sd_pull_ctl_disable_tbl2[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE5),
+ 0,
+};
+
+/* MS Pull Control Enable:
+ * MS CD ==> pull up
+ * others ==> pull down
+ */
+static const u32 rts5229_ms_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
+ 0,
+};
+
+/* MS Pull Control Disable:
+ * MS CD ==> pull up
+ * others ==> pull down
+ */
+static const u32 rts5229_ms_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
+ 0,
+};
+
+void rts5229_init_params(struct rtsx_pcr *pcr)
+{
+ pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
+ pcr->num_slots = 2;
+ pcr->ops = &rts5229_pcr_ops;
+
+ pcr->ic_version = rts5229_get_ic_version(pcr);
+ if (pcr->ic_version == IC_VER_C) {
+ pcr->sd_pull_ctl_enable_tbl = rts5229_sd_pull_ctl_enable_tbl2;
+ pcr->sd_pull_ctl_disable_tbl = rts5229_sd_pull_ctl_disable_tbl2;
+ } else {
+ pcr->sd_pull_ctl_enable_tbl = rts5229_sd_pull_ctl_enable_tbl1;
+ pcr->sd_pull_ctl_disable_tbl = rts5229_sd_pull_ctl_disable_tbl1;
+ }
+ pcr->ms_pull_ctl_enable_tbl = rts5229_ms_pull_ctl_enable_tbl;
+ pcr->ms_pull_ctl_disable_tbl = rts5229_ms_pull_ctl_disable_tbl;
+}
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
new file mode 100644
index 00000000000..56d4377c62c
--- /dev/null
+++ b/drivers/mfd/rtsx_pcr.c
@@ -0,0 +1,1251 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Wei WANG <wei_wang@realsil.com.cn>
+ * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/highmem.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/idr.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/rtsx_pci.h>
+#include <asm/unaligned.h>
+
+#include "rtsx_pcr.h"
+
+static bool msi_en = true;
+module_param(msi_en, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(msi_en, "Enable MSI");
+
+static DEFINE_IDR(rtsx_pci_idr);
+static DEFINE_SPINLOCK(rtsx_pci_lock);
+
+static struct mfd_cell rtsx_pcr_cells[] = {
+ [RTSX_SD_CARD] = {
+ .name = DRV_NAME_RTSX_PCI_SDMMC,
+ },
+ [RTSX_MS_CARD] = {
+ .name = DRV_NAME_RTSX_PCI_MS,
+ },
+};
+
+static DEFINE_PCI_DEVICE_TABLE(rtsx_pci_ids) = {
+ { PCI_DEVICE(0x10EC, 0x5209), PCI_CLASS_OTHERS << 16, 0xFF0000 },
+ { PCI_DEVICE(0x10EC, 0x5229), PCI_CLASS_OTHERS << 16, 0xFF0000 },
+ { PCI_DEVICE(0x10EC, 0x5289), PCI_CLASS_OTHERS << 16, 0xFF0000 },
+ { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, rtsx_pci_ids);
+
+void rtsx_pci_start_run(struct rtsx_pcr *pcr)
+{
+ /* If pci device removed, don't queue idle work any more */
+ if (pcr->remove_pci)
+ return;
+
+ if (pcr->state != PDEV_STAT_RUN) {
+ pcr->state = PDEV_STAT_RUN;
+ if (pcr->ops->enable_auto_blink)
+ pcr->ops->enable_auto_blink(pcr);
+ }
+
+ mod_delayed_work(system_wq, &pcr->idle_work, msecs_to_jiffies(200));
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_start_run);
+
+int rtsx_pci_write_register(struct rtsx_pcr *pcr, u16 addr, u8 mask, u8 data)
+{
+ int i;
+ u32 val = HAIMR_WRITE_START;
+
+ val |= (u32)(addr & 0x3FFF) << 16;
+ val |= (u32)mask << 8;
+ val |= (u32)data;
+
+ rtsx_pci_writel(pcr, RTSX_HAIMR, val);
+
+ for (i = 0; i < MAX_RW_REG_CNT; i++) {
+ val = rtsx_pci_readl(pcr, RTSX_HAIMR);
+ if ((val & HAIMR_TRANS_END) == 0) {
+ if (data != (u8)val)
+ return -EIO;
+ return 0;
+ }
+ }
+
+ return -ETIMEDOUT;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_write_register);
+
+int rtsx_pci_read_register(struct rtsx_pcr *pcr, u16 addr, u8 *data)
+{
+ u32 val = HAIMR_READ_START;
+ int i;
+
+ val |= (u32)(addr & 0x3FFF) << 16;
+ rtsx_pci_writel(pcr, RTSX_HAIMR, val);
+
+ for (i = 0; i < MAX_RW_REG_CNT; i++) {
+ val = rtsx_pci_readl(pcr, RTSX_HAIMR);
+ if ((val & HAIMR_TRANS_END) == 0)
+ break;
+ }
+
+ if (i >= MAX_RW_REG_CNT)
+ return -ETIMEDOUT;
+
+ if (data)
+ *data = (u8)(val & 0xFF);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_read_register);
+
+int rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val)
+{
+ int err, i, finished = 0;
+ u8 tmp;
+
+ rtsx_pci_init_cmd(pcr);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYDATA0, 0xFF, (u8)val);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYDATA1, 0xFF, (u8)(val >> 8));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYADDR, 0xFF, addr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYRWCTL, 0xFF, 0x81);
+
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < 100000; i++) {
+ err = rtsx_pci_read_register(pcr, PHYRWCTL, &tmp);
+ if (err < 0)
+ return err;
+
+ if (!(tmp & 0x80)) {
+ finished = 1;
+ break;
+ }
+ }
+
+ if (!finished)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_write_phy_register);
+
+int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val)
+{
+ int err, i, finished = 0;
+ u16 data;
+ u8 *ptr, tmp;
+
+ rtsx_pci_init_cmd(pcr);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYADDR, 0xFF, addr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYRWCTL, 0xFF, 0x80);
+
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < 100000; i++) {
+ err = rtsx_pci_read_register(pcr, PHYRWCTL, &tmp);
+ if (err < 0)
+ return err;
+
+ if (!(tmp & 0x80)) {
+ finished = 1;
+ break;
+ }
+ }
+
+ if (!finished)
+ return -ETIMEDOUT;
+
+ rtsx_pci_init_cmd(pcr);
+
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, PHYDATA0, 0, 0);
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, PHYDATA1, 0, 0);
+
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ ptr = rtsx_pci_get_cmd_data(pcr);
+ data = ((u16)ptr[1] << 8) | ptr[0];
+
+ if (val)
+ *val = data;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_read_phy_register);
+
+void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr)
+{
+ rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD);
+ rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA);
+
+ rtsx_pci_write_register(pcr, DMACTL, 0x80, 0x80);
+ rtsx_pci_write_register(pcr, RBCTL, 0x80, 0x80);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_stop_cmd);
+
+void rtsx_pci_add_cmd(struct rtsx_pcr *pcr,
+ u8 cmd_type, u16 reg_addr, u8 mask, u8 data)
+{
+ unsigned long flags;
+ u32 val = 0;
+ u32 *ptr = (u32 *)(pcr->host_cmds_ptr);
+
+ val |= (u32)(cmd_type & 0x03) << 30;
+ val |= (u32)(reg_addr & 0x3FFF) << 16;
+ val |= (u32)mask << 8;
+ val |= (u32)data;
+
+ spin_lock_irqsave(&pcr->lock, flags);
+ ptr += pcr->ci;
+ if (pcr->ci < (HOST_CMDS_BUF_LEN / 4)) {
+ put_unaligned_le32(val, ptr);
+ ptr++;
+ pcr->ci++;
+ }
+ spin_unlock_irqrestore(&pcr->lock, flags);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_add_cmd);
+
+void rtsx_pci_send_cmd_no_wait(struct rtsx_pcr *pcr)
+{
+ u32 val = 1 << 31;
+
+ rtsx_pci_writel(pcr, RTSX_HCBAR, pcr->host_cmds_addr);
+
+ val |= (u32)(pcr->ci * 4) & 0x00FFFFFF;
+ /* Hardware Auto Response */
+ val |= 0x40000000;
+ rtsx_pci_writel(pcr, RTSX_HCBCTLR, val);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_send_cmd_no_wait);
+
+int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout)
+{
+ struct completion trans_done;
+ u32 val = 1 << 31;
+ long timeleft;
+ unsigned long flags;
+ int err = 0;
+
+ spin_lock_irqsave(&pcr->lock, flags);
+
+ /* set up data structures for the wakeup system */
+ pcr->done = &trans_done;
+ pcr->trans_result = TRANS_NOT_READY;
+ init_completion(&trans_done);
+
+ rtsx_pci_writel(pcr, RTSX_HCBAR, pcr->host_cmds_addr);
+
+ val |= (u32)(pcr->ci * 4) & 0x00FFFFFF;
+ /* Hardware Auto Response */
+ val |= 0x40000000;
+ rtsx_pci_writel(pcr, RTSX_HCBCTLR, val);
+
+ spin_unlock_irqrestore(&pcr->lock, flags);
+
+ /* Wait for TRANS_OK_INT */
+ timeleft = wait_for_completion_interruptible_timeout(
+ &trans_done, msecs_to_jiffies(timeout));
+ if (timeleft <= 0) {
+ dev_dbg(&(pcr->pci->dev), "Timeout (%s %d)\n",
+ __func__, __LINE__);
+ err = -ETIMEDOUT;
+ goto finish_send_cmd;
+ }
+
+ spin_lock_irqsave(&pcr->lock, flags);
+ if (pcr->trans_result == TRANS_RESULT_FAIL)
+ err = -EINVAL;
+ else if (pcr->trans_result == TRANS_RESULT_OK)
+ err = 0;
+ else if (pcr->trans_result == TRANS_NO_DEVICE)
+ err = -ENODEV;
+ spin_unlock_irqrestore(&pcr->lock, flags);
+
+finish_send_cmd:
+ spin_lock_irqsave(&pcr->lock, flags);
+ pcr->done = NULL;
+ spin_unlock_irqrestore(&pcr->lock, flags);
+
+ if ((err < 0) && (err != -ENODEV))
+ rtsx_pci_stop_cmd(pcr);
+
+ if (pcr->finish_me)
+ complete(pcr->finish_me);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_send_cmd);
+
+static void rtsx_pci_add_sg_tbl(struct rtsx_pcr *pcr,
+ dma_addr_t addr, unsigned int len, int end)
+{
+ u64 *ptr = (u64 *)(pcr->host_sg_tbl_ptr) + pcr->sgi;
+ u64 val;
+ u8 option = SG_VALID | SG_TRANS_DATA;
+
+ dev_dbg(&(pcr->pci->dev), "DMA addr: 0x%x, Len: 0x%x\n",
+ (unsigned int)addr, len);
+
+ if (end)
+ option |= SG_END;
+ val = ((u64)addr << 32) | ((u64)len << 12) | option;
+
+ put_unaligned_le64(val, ptr);
+ ptr++;
+ pcr->sgi++;
+}
+
+int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
+ int num_sg, bool read, int timeout)
+{
+ struct completion trans_done;
+ u8 dir;
+ int err = 0, i, count;
+ long timeleft;
+ unsigned long flags;
+ struct scatterlist *sg;
+ enum dma_data_direction dma_dir;
+ u32 val;
+ dma_addr_t addr;
+ unsigned int len;
+
+ dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg);
+
+ /* don't transfer data during abort processing */
+ if (pcr->remove_pci)
+ return -EINVAL;
+
+ if ((sglist == NULL) || (num_sg <= 0))
+ return -EINVAL;
+
+ if (read) {
+ dir = DEVICE_TO_HOST;
+ dma_dir = DMA_FROM_DEVICE;
+ } else {
+ dir = HOST_TO_DEVICE;
+ dma_dir = DMA_TO_DEVICE;
+ }
+
+ count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
+ if (count < 1) {
+ dev_err(&(pcr->pci->dev), "scatterlist map failed\n");
+ return -EINVAL;
+ }
+ dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count);
+
+ val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE;
+ pcr->sgi = 0;
+ for_each_sg(sglist, sg, count, i) {
+ addr = sg_dma_address(sg);
+ len = sg_dma_len(sg);
+ rtsx_pci_add_sg_tbl(pcr, addr, len, i == count - 1);
+ }
+
+ spin_lock_irqsave(&pcr->lock, flags);
+
+ pcr->done = &trans_done;
+ pcr->trans_result = TRANS_NOT_READY;
+ init_completion(&trans_done);
+ rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr);
+ rtsx_pci_writel(pcr, RTSX_HDBCTLR, val);
+
+ spin_unlock_irqrestore(&pcr->lock, flags);
+
+ timeleft = wait_for_completion_interruptible_timeout(
+ &trans_done, msecs_to_jiffies(timeout));
+ if (timeleft <= 0) {
+ dev_dbg(&(pcr->pci->dev), "Timeout (%s %d)\n",
+ __func__, __LINE__);
+ err = -ETIMEDOUT;
+ goto out;
+ }
+
+ spin_lock_irqsave(&pcr->lock, flags);
+
+ if (pcr->trans_result == TRANS_RESULT_FAIL)
+ err = -EINVAL;
+ else if (pcr->trans_result == TRANS_NO_DEVICE)
+ err = -ENODEV;
+
+ spin_unlock_irqrestore(&pcr->lock, flags);
+
+out:
+ spin_lock_irqsave(&pcr->lock, flags);
+ pcr->done = NULL;
+ spin_unlock_irqrestore(&pcr->lock, flags);
+
+ dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
+
+ if ((err < 0) && (err != -ENODEV))
+ rtsx_pci_stop_cmd(pcr);
+
+ if (pcr->finish_me)
+ complete(pcr->finish_me);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data);
+
+int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len)
+{
+ int err;
+ int i, j;
+ u16 reg;
+ u8 *ptr;
+
+ if (buf_len > 512)
+ buf_len = 512;
+
+ ptr = buf;
+ reg = PPBUF_BASE2;
+ for (i = 0; i < buf_len / 256; i++) {
+ rtsx_pci_init_cmd(pcr);
+
+ for (j = 0; j < 256; j++)
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, reg++, 0, 0);
+
+ err = rtsx_pci_send_cmd(pcr, 250);
+ if (err < 0)
+ return err;
+
+ memcpy(ptr, rtsx_pci_get_cmd_data(pcr), 256);
+ ptr += 256;
+ }
+
+ if (buf_len % 256) {
+ rtsx_pci_init_cmd(pcr);
+
+ for (j = 0; j < buf_len % 256; j++)
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, reg++, 0, 0);
+
+ err = rtsx_pci_send_cmd(pcr, 250);
+ if (err < 0)
+ return err;
+ }
+
+ memcpy(ptr, rtsx_pci_get_cmd_data(pcr), buf_len % 256);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_read_ppbuf);
+
+int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len)
+{
+ int err;
+ int i, j;
+ u16 reg;
+ u8 *ptr;
+
+ if (buf_len > 512)
+ buf_len = 512;
+
+ ptr = buf;
+ reg = PPBUF_BASE2;
+ for (i = 0; i < buf_len / 256; i++) {
+ rtsx_pci_init_cmd(pcr);
+
+ for (j = 0; j < 256; j++) {
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ reg++, 0xFF, *ptr);
+ ptr++;
+ }
+
+ err = rtsx_pci_send_cmd(pcr, 250);
+ if (err < 0)
+ return err;
+ }
+
+ if (buf_len % 256) {
+ rtsx_pci_init_cmd(pcr);
+
+ for (j = 0; j < buf_len % 256; j++) {
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ reg++, 0xFF, *ptr);
+ ptr++;
+ }
+
+ err = rtsx_pci_send_cmd(pcr, 250);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_write_ppbuf);
+
+static int rtsx_pci_set_pull_ctl(struct rtsx_pcr *pcr, const u32 *tbl)
+{
+ int err;
+
+ rtsx_pci_init_cmd(pcr);
+
+ while (*tbl & 0xFFFF0000) {
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ (u16)(*tbl >> 16), 0xFF, (u8)(*tbl));
+ tbl++;
+ }
+
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card)
+{
+ const u32 *tbl;
+
+ if (card == RTSX_SD_CARD)
+ tbl = pcr->sd_pull_ctl_enable_tbl;
+ else if (card == RTSX_MS_CARD)
+ tbl = pcr->ms_pull_ctl_enable_tbl;
+ else
+ return -EINVAL;
+
+ return rtsx_pci_set_pull_ctl(pcr, tbl);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_card_pull_ctl_enable);
+
+int rtsx_pci_card_pull_ctl_disable(struct rtsx_pcr *pcr, int card)
+{
+ const u32 *tbl;
+
+ if (card == RTSX_SD_CARD)
+ tbl = pcr->sd_pull_ctl_disable_tbl;
+ else if (card == RTSX_MS_CARD)
+ tbl = pcr->ms_pull_ctl_disable_tbl;
+ else
+ return -EINVAL;
+
+
+ return rtsx_pci_set_pull_ctl(pcr, tbl);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_card_pull_ctl_disable);
+
+static void rtsx_pci_enable_bus_int(struct rtsx_pcr *pcr)
+{
+ pcr->bier = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN | SD_INT_EN;
+
+ if (pcr->num_slots > 1)
+ pcr->bier |= MS_INT_EN;
+
+ /* Enable Bus Interrupt */
+ rtsx_pci_writel(pcr, RTSX_BIER, pcr->bier);
+
+ dev_dbg(&(pcr->pci->dev), "RTSX_BIER: 0x%08x\n", pcr->bier);
+}
+
+static inline u8 double_ssc_depth(u8 depth)
+{
+ return ((depth > 1) ? (depth - 1) : depth);
+}
+
+static u8 revise_ssc_depth(u8 ssc_depth, u8 div)
+{
+ if (div > CLK_DIV_1) {
+ if (ssc_depth > (div - 1))
+ ssc_depth -= (div - 1);
+ else
+ ssc_depth = SSC_DEPTH_4M;
+ }
+
+ return ssc_depth;
+}
+
+int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
+ u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk)
+{
+ int err, clk;
+ u8 N, min_N, max_N, clk_divider;
+ u8 mcu_cnt, div, max_div;
+ u8 depth[] = {
+ [RTSX_SSC_DEPTH_4M] = SSC_DEPTH_4M,
+ [RTSX_SSC_DEPTH_2M] = SSC_DEPTH_2M,
+ [RTSX_SSC_DEPTH_1M] = SSC_DEPTH_1M,
+ [RTSX_SSC_DEPTH_500K] = SSC_DEPTH_500K,
+ [RTSX_SSC_DEPTH_250K] = SSC_DEPTH_250K,
+ };
+
+ if (initial_mode) {
+ /* We use 250k(around) here, in initial stage */
+ clk_divider = SD_CLK_DIVIDE_128;
+ card_clock = 30000000;
+ } else {
+ clk_divider = SD_CLK_DIVIDE_0;
+ }
+ err = rtsx_pci_write_register(pcr, SD_CFG1,
+ SD_CLK_DIVIDE_MASK, clk_divider);
+ if (err < 0)
+ return err;
+
+ card_clock /= 1000000;
+ dev_dbg(&(pcr->pci->dev), "Switch card clock to %dMHz\n", card_clock);
+
+ min_N = 80;
+ max_N = 208;
+ max_div = CLK_DIV_8;
+
+ clk = card_clock;
+ if (!initial_mode && double_clk)
+ clk = card_clock * 2;
+ dev_dbg(&(pcr->pci->dev),
+ "Internal SSC clock: %dMHz (cur_clock = %d)\n",
+ clk, pcr->cur_clock);
+
+ if (clk == pcr->cur_clock)
+ return 0;
+
+ N = (u8)(clk - 2);
+ if ((clk <= 2) || (N > max_N))
+ return -EINVAL;
+
+ mcu_cnt = (u8)(125/clk + 3);
+ if (mcu_cnt > 15)
+ mcu_cnt = 15;
+
+ /* Make sure that the SSC clock div_n is equal or greater than min_N */
+ div = CLK_DIV_1;
+ while ((N < min_N) && (div < max_div)) {
+ N = (N + 2) * 2 - 2;
+ div++;
+ }
+ dev_dbg(&(pcr->pci->dev), "N = %d, div = %d\n", N, div);
+
+ ssc_depth = depth[ssc_depth];
+ if (double_clk)
+ ssc_depth = double_ssc_depth(ssc_depth);
+
+ ssc_depth = revise_ssc_depth(ssc_depth, div);
+ dev_dbg(&(pcr->pci->dev), "ssc_depth = %d\n", ssc_depth);
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL,
+ CLK_LOW_FREQ, CLK_LOW_FREQ);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_DIV,
+ 0xFF, (div << 4) | mcu_cnt);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2,
+ SSC_DEPTH_MASK, ssc_depth);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB);
+ if (vpclk) {
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL,
+ PHASE_NOT_RESET, 0);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL,
+ PHASE_NOT_RESET, PHASE_NOT_RESET);
+ }
+
+ err = rtsx_pci_send_cmd(pcr, 2000);
+ if (err < 0)
+ return err;
+
+ /* Wait SSC clock stable */
+ udelay(10);
+ err = rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
+ if (err < 0)
+ return err;
+
+ pcr->cur_clock = clk;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_switch_clock);
+
+int rtsx_pci_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+ if (pcr->ops->card_power_on)
+ return pcr->ops->card_power_on(pcr, card);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_card_power_on);
+
+int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card)
+{
+ if (pcr->ops->card_power_off)
+ return pcr->ops->card_power_off(pcr, card);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off);
+
+unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr)
+{
+ unsigned int val;
+
+ val = rtsx_pci_readl(pcr, RTSX_BIPR);
+ if (pcr->ops->cd_deglitch)
+ val = pcr->ops->cd_deglitch(pcr);
+
+ return val;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_card_exist);
+
+void rtsx_pci_complete_unfinished_transfer(struct rtsx_pcr *pcr)
+{
+ struct completion finish;
+
+ pcr->finish_me = &finish;
+ init_completion(&finish);
+
+ if (pcr->done)
+ complete(pcr->done);
+
+ if (!pcr->remove_pci)
+ rtsx_pci_stop_cmd(pcr);
+
+ wait_for_completion_interruptible_timeout(&finish,
+ msecs_to_jiffies(2));
+ pcr->finish_me = NULL;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_complete_unfinished_transfer);
+
+static void rtsx_pci_card_detect(struct work_struct *work)
+{
+ struct delayed_work *dwork;
+ struct rtsx_pcr *pcr;
+ unsigned long flags;
+ unsigned int card_detect = 0;
+ u32 irq_status;
+
+ dwork = to_delayed_work(work);
+ pcr = container_of(dwork, struct rtsx_pcr, carddet_work);
+
+ dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__);
+
+ spin_lock_irqsave(&pcr->lock, flags);
+
+ irq_status = rtsx_pci_readl(pcr, RTSX_BIPR);
+ dev_dbg(&(pcr->pci->dev), "irq_status: 0x%08x\n", irq_status);
+
+ if (pcr->card_inserted || pcr->card_removed) {
+ dev_dbg(&(pcr->pci->dev),
+ "card_inserted: 0x%x, card_removed: 0x%x\n",
+ pcr->card_inserted, pcr->card_removed);
+
+ if (pcr->ops->cd_deglitch)
+ pcr->card_inserted = pcr->ops->cd_deglitch(pcr);
+
+ card_detect = pcr->card_inserted | pcr->card_removed;
+ pcr->card_inserted = 0;
+ pcr->card_removed = 0;
+ }
+
+ spin_unlock_irqrestore(&pcr->lock, flags);
+
+ if (card_detect & SD_EXIST)
+ pcr->slots[RTSX_SD_CARD].card_event(
+ pcr->slots[RTSX_SD_CARD].p_dev);
+ if (card_detect & MS_EXIST)
+ pcr->slots[RTSX_MS_CARD].card_event(
+ pcr->slots[RTSX_MS_CARD].p_dev);
+}
+
+static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
+{
+ struct rtsx_pcr *pcr = dev_id;
+ u32 int_reg;
+
+ if (!pcr)
+ return IRQ_NONE;
+
+ spin_lock(&pcr->lock);
+
+ int_reg = rtsx_pci_readl(pcr, RTSX_BIPR);
+ /* Clear interrupt flag */
+ rtsx_pci_writel(pcr, RTSX_BIPR, int_reg);
+ if ((int_reg & pcr->bier) == 0) {
+ spin_unlock(&pcr->lock);
+ return IRQ_NONE;
+ }
+ if (int_reg == 0xFFFFFFFF) {
+ spin_unlock(&pcr->lock);
+ return IRQ_HANDLED;
+ }
+
+ int_reg &= (pcr->bier | 0x7FFFFF);
+
+ if (int_reg & SD_INT) {
+ if (int_reg & SD_EXIST) {
+ pcr->card_inserted |= SD_EXIST;
+ } else {
+ pcr->card_removed |= SD_EXIST;
+ pcr->card_inserted &= ~SD_EXIST;
+ }
+ }
+
+ if (int_reg & MS_INT) {
+ if (int_reg & MS_EXIST) {
+ pcr->card_inserted |= MS_EXIST;
+ } else {
+ pcr->card_removed |= MS_EXIST;
+ pcr->card_inserted &= ~MS_EXIST;
+ }
+ }
+
+ if (pcr->card_inserted || pcr->card_removed)
+ schedule_delayed_work(&pcr->carddet_work,
+ msecs_to_jiffies(200));
+
+ if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) {
+ if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) {
+ pcr->trans_result = TRANS_RESULT_FAIL;
+ if (pcr->done)
+ complete(pcr->done);
+ } else if (int_reg & TRANS_OK_INT) {
+ pcr->trans_result = TRANS_RESULT_OK;
+ if (pcr->done)
+ complete(pcr->done);
+ }
+ }
+
+ spin_unlock(&pcr->lock);
+ return IRQ_HANDLED;
+}
+
+static int rtsx_pci_acquire_irq(struct rtsx_pcr *pcr)
+{
+ dev_info(&(pcr->pci->dev), "%s: pcr->msi_en = %d, pci->irq = %d\n",
+ __func__, pcr->msi_en, pcr->pci->irq);
+
+ if (request_irq(pcr->pci->irq, rtsx_pci_isr,
+ pcr->msi_en ? 0 : IRQF_SHARED,
+ DRV_NAME_RTSX_PCI, pcr)) {
+ dev_err(&(pcr->pci->dev),
+ "rtsx_sdmmc: unable to grab IRQ %d, disabling device\n",
+ pcr->pci->irq);
+ return -1;
+ }
+
+ pcr->irq = pcr->pci->irq;
+ pci_intx(pcr->pci, !pcr->msi_en);
+
+ return 0;
+}
+
+static void rtsx_pci_idle_work(struct work_struct *work)
+{
+ struct delayed_work *dwork = to_delayed_work(work);
+ struct rtsx_pcr *pcr = container_of(dwork, struct rtsx_pcr, idle_work);
+
+ dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__);
+
+ mutex_lock(&pcr->pcr_mutex);
+
+ pcr->state = PDEV_STAT_IDLE;
+
+ if (pcr->ops->disable_auto_blink)
+ pcr->ops->disable_auto_blink(pcr);
+ if (pcr->ops->turn_off_led)
+ pcr->ops->turn_off_led(pcr);
+
+ mutex_unlock(&pcr->pcr_mutex);
+}
+
+static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
+{
+ int err;
+
+ rtsx_pci_writel(pcr, RTSX_HCBAR, pcr->host_cmds_addr);
+
+ rtsx_pci_enable_bus_int(pcr);
+
+ /* Power on SSC */
+ err = rtsx_pci_write_register(pcr, FPDCTL, SSC_POWER_DOWN, 0);
+ if (err < 0)
+ return err;
+
+ /* Wait SSC power stable */
+ udelay(200);
+
+ if (pcr->ops->optimize_phy) {
+ err = pcr->ops->optimize_phy(pcr);
+ if (err < 0)
+ return err;
+ }
+
+ rtsx_pci_init_cmd(pcr);
+
+ /* Set mcu_cnt to 7 to ensure data can be sampled properly */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_DIV, 0x07, 0x07);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, HOST_SLEEP_STATE, 0x03, 0x00);
+ /* Disable card clock */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, 0x1E, 0);
+ /* Reset ASPM state to default value */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
+ /* Reset delink mode */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CHANGE_LINK_STATE, 0x0A, 0);
+ /* Card driving select */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
+ 0x07, DRIVER_TYPE_D);
+ /* Enable SSC Clock */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1,
+ 0xFF, SSC_8X_EN | SSC_SEL_4M);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, 0xFF, 0x12);
+ /* Disable cd_pwr_save */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CHANGE_LINK_STATE, 0x16, 0x10);
+ /* Clear Link Ready Interrupt */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0,
+ LINK_RDY_INT, LINK_RDY_INT);
+ /* Enlarge the estimation window of PERST# glitch
+ * to reduce the chance of invalid card interrupt
+ */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PERST_GLITCH_WIDTH, 0xFF, 0x80);
+ /* Update RC oscillator to 400k
+ * bit[0] F_HIGH: for RC oscillator, Rst_value is 1'b1
+ * 1: 2M 0: 400k
+ */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, RCCTL, 0x01, 0x00);
+ /* Set interrupt write clear
+ * bit 1: U_elbi_if_rd_clr_en
+ * 1: Enable ELBI interrupt[31:22] & [7:0] flag read clear
+ * 0: ELBI interrupt flag[31:22] & [7:0] only can be write clear
+ */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, NFTS_TX_CTRL, 0x02, 0);
+ /* Force CLKREQ# PIN to drive 0 to request clock */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x08, 0x08);
+
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ /* Enable clk_request_n to enable clock power management */
+ rtsx_pci_write_config_byte(pcr, 0x81, 1);
+ /* Enter L1 when host tx idle */
+ rtsx_pci_write_config_byte(pcr, 0x70F, 0x5B);
+
+ if (pcr->ops->extra_init_hw) {
+ err = pcr->ops->extra_init_hw(pcr);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
+{
+ int err;
+
+ spin_lock_init(&pcr->lock);
+ mutex_init(&pcr->pcr_mutex);
+
+ switch (PCI_PID(pcr)) {
+ default:
+ case 0x5209:
+ rts5209_init_params(pcr);
+ break;
+
+ case 0x5229:
+ rts5229_init_params(pcr);
+ break;
+
+ case 0x5289:
+ rtl8411_init_params(pcr);
+ break;
+ }
+
+ dev_dbg(&(pcr->pci->dev), "PID: 0x%04x, IC version: 0x%02x\n",
+ PCI_PID(pcr), pcr->ic_version);
+
+ pcr->slots = kcalloc(pcr->num_slots, sizeof(struct rtsx_slot),
+ GFP_KERNEL);
+ if (!pcr->slots)
+ return -ENOMEM;
+
+ pcr->state = PDEV_STAT_IDLE;
+ err = rtsx_pci_init_hw(pcr);
+ if (err < 0) {
+ kfree(pcr->slots);
+ return err;
+ }
+
+ return 0;
+}
+
+static int __devinit rtsx_pci_probe(struct pci_dev *pcidev,
+ const struct pci_device_id *id)
+{
+ struct rtsx_pcr *pcr;
+ struct pcr_handle *handle;
+ u32 base, len;
+ int ret, i;
+
+ dev_dbg(&(pcidev->dev),
+ ": Realtek PCI-E Card Reader found at %s [%04x:%04x] (rev %x)\n",
+ pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device,
+ (int)pcidev->revision);
+
+ ret = pci_enable_device(pcidev);
+ if (ret)
+ return ret;
+
+ ret = pci_request_regions(pcidev, DRV_NAME_RTSX_PCI);
+ if (ret)
+ goto disable;
+
+ pcr = kzalloc(sizeof(*pcr), GFP_KERNEL);
+ if (!pcr) {
+ ret = -ENOMEM;
+ goto release_pci;
+ }
+
+ handle = kzalloc(sizeof(*handle), GFP_KERNEL);
+ if (!handle) {
+ ret = -ENOMEM;
+ goto free_pcr;
+ }
+ handle->pcr = pcr;
+
+ if (!idr_pre_get(&rtsx_pci_idr, GFP_KERNEL)) {
+ ret = -ENOMEM;
+ goto free_handle;
+ }
+
+ spin_lock(&rtsx_pci_lock);
+ ret = idr_get_new(&rtsx_pci_idr, pcr, &pcr->id);
+ spin_unlock(&rtsx_pci_lock);
+ if (ret)
+ goto free_handle;
+
+ pcr->pci = pcidev;
+ dev_set_drvdata(&pcidev->dev, handle);
+
+ len = pci_resource_len(pcidev, 0);
+ base = pci_resource_start(pcidev, 0);
+ pcr->remap_addr = ioremap_nocache(base, len);
+ if (!pcr->remap_addr) {
+ ret = -ENOMEM;
+ goto free_host;
+ }
+
+ pcr->rtsx_resv_buf = dma_alloc_coherent(&(pcidev->dev),
+ RTSX_RESV_BUF_LEN, &(pcr->rtsx_resv_buf_addr),
+ GFP_KERNEL);
+ if (pcr->rtsx_resv_buf == NULL) {
+ ret = -ENXIO;
+ goto unmap;
+ }
+ pcr->host_cmds_ptr = pcr->rtsx_resv_buf;
+ pcr->host_cmds_addr = pcr->rtsx_resv_buf_addr;
+ pcr->host_sg_tbl_ptr = pcr->rtsx_resv_buf + HOST_CMDS_BUF_LEN;
+ pcr->host_sg_tbl_addr = pcr->rtsx_resv_buf_addr + HOST_CMDS_BUF_LEN;
+
+ pcr->card_inserted = 0;
+ pcr->card_removed = 0;
+ INIT_DELAYED_WORK(&pcr->carddet_work, rtsx_pci_card_detect);
+ INIT_DELAYED_WORK(&pcr->idle_work, rtsx_pci_idle_work);
+
+ pcr->msi_en = msi_en;
+ if (pcr->msi_en) {
+ ret = pci_enable_msi(pcidev);
+ if (ret < 0)
+ pcr->msi_en = false;
+ }
+
+ ret = rtsx_pci_acquire_irq(pcr);
+ if (ret < 0)
+ goto free_dma;
+
+ pci_set_master(pcidev);
+ synchronize_irq(pcr->irq);
+
+ ret = rtsx_pci_init_chip(pcr);
+ if (ret < 0)
+ goto disable_irq;
+
+ for (i = 0; i < ARRAY_SIZE(rtsx_pcr_cells); i++) {
+ rtsx_pcr_cells[i].platform_data = handle;
+ rtsx_pcr_cells[i].pdata_size = sizeof(*handle);
+ }
+ ret = mfd_add_devices(&pcidev->dev, pcr->id, rtsx_pcr_cells,
+ ARRAY_SIZE(rtsx_pcr_cells), NULL, 0, NULL);
+ if (ret < 0)
+ goto disable_irq;
+
+ schedule_delayed_work(&pcr->idle_work, msecs_to_jiffies(200));
+
+ return 0;
+
+disable_irq:
+ free_irq(pcr->irq, (void *)pcr);
+free_dma:
+ dma_free_coherent(&(pcr->pci->dev), RTSX_RESV_BUF_LEN,
+ pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr);
+unmap:
+ iounmap(pcr->remap_addr);
+free_host:
+ dev_set_drvdata(&pcidev->dev, NULL);
+free_handle:
+ kfree(handle);
+free_pcr:
+ kfree(pcr);
+release_pci:
+ pci_release_regions(pcidev);
+disable:
+ pci_disable_device(pcidev);
+
+ return ret;
+}
+
+static void __devexit rtsx_pci_remove(struct pci_dev *pcidev)
+{
+ struct pcr_handle *handle = pci_get_drvdata(pcidev);
+ struct rtsx_pcr *pcr = handle->pcr;
+
+ pcr->remove_pci = true;
+
+ cancel_delayed_work(&pcr->carddet_work);
+ cancel_delayed_work(&pcr->idle_work);
+
+ mfd_remove_devices(&pcidev->dev);
+
+ dma_free_coherent(&(pcr->pci->dev), RTSX_RESV_BUF_LEN,
+ pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr);
+ free_irq(pcr->irq, (void *)pcr);
+ if (pcr->msi_en)
+ pci_disable_msi(pcr->pci);
+ iounmap(pcr->remap_addr);
+
+ dev_set_drvdata(&pcidev->dev, NULL);
+ pci_release_regions(pcidev);
+ pci_disable_device(pcidev);
+
+ spin_lock(&rtsx_pci_lock);
+ idr_remove(&rtsx_pci_idr, pcr->id);
+ spin_unlock(&rtsx_pci_lock);
+
+ kfree(pcr->slots);
+ kfree(pcr);
+ kfree(handle);
+
+ dev_dbg(&(pcidev->dev),
+ ": Realtek PCI-E Card Reader at %s [%04x:%04x] has been removed\n",
+ pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device);
+}
+
+#ifdef CONFIG_PM
+
+static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state)
+{
+ struct pcr_handle *handle;
+ struct rtsx_pcr *pcr;
+ int ret = 0;
+
+ dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
+
+ handle = pci_get_drvdata(pcidev);
+ pcr = handle->pcr;
+
+ cancel_delayed_work(&pcr->carddet_work);
+ cancel_delayed_work(&pcr->idle_work);
+
+ mutex_lock(&pcr->pcr_mutex);
+
+ if (pcr->ops->turn_off_led)
+ pcr->ops->turn_off_led(pcr);
+
+ rtsx_pci_writel(pcr, RTSX_BIER, 0);
+ pcr->bier = 0;
+
+ rtsx_pci_write_register(pcr, PETXCFG, 0x08, 0x08);
+ rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x02);
+
+ pci_save_state(pcidev);
+ pci_enable_wake(pcidev, pci_choose_state(pcidev, state), 0);
+ pci_disable_device(pcidev);
+ pci_set_power_state(pcidev, pci_choose_state(pcidev, state));
+
+ mutex_unlock(&pcr->pcr_mutex);
+ return ret;
+}
+
+static int rtsx_pci_resume(struct pci_dev *pcidev)
+{
+ struct pcr_handle *handle;
+ struct rtsx_pcr *pcr;
+ int ret = 0;
+
+ dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
+
+ handle = pci_get_drvdata(pcidev);
+ pcr = handle->pcr;
+
+ mutex_lock(&pcr->pcr_mutex);
+
+ pci_set_power_state(pcidev, PCI_D0);
+ pci_restore_state(pcidev);
+ ret = pci_enable_device(pcidev);
+ if (ret)
+ goto out;
+ pci_set_master(pcidev);
+
+ ret = rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x00);
+ if (ret)
+ goto out;
+
+ ret = rtsx_pci_init_hw(pcr);
+ if (ret)
+ goto out;
+
+ schedule_delayed_work(&pcr->idle_work, msecs_to_jiffies(200));
+
+out:
+ mutex_unlock(&pcr->pcr_mutex);
+ return ret;
+}
+
+#else /* CONFIG_PM */
+
+#define rtsx_pci_suspend NULL
+#define rtsx_pci_resume NULL
+
+#endif /* CONFIG_PM */
+
+static struct pci_driver rtsx_pci_driver = {
+ .name = DRV_NAME_RTSX_PCI,
+ .id_table = rtsx_pci_ids,
+ .probe = rtsx_pci_probe,
+ .remove = __devexit_p(rtsx_pci_remove),
+ .suspend = rtsx_pci_suspend,
+ .resume = rtsx_pci_resume,
+};
+module_pci_driver(rtsx_pci_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Wei WANG <wei_wang@realsil.com.cn>");
+MODULE_DESCRIPTION("Realtek PCI-E Card Reader Driver");
diff --git a/drivers/staging/rts_pstor/general.h b/drivers/mfd/rtsx_pcr.h
index f17930d2e0c..12462c1df1a 100644
--- a/drivers/staging/rts_pstor/general.h
+++ b/drivers/mfd/rtsx_pcr.h
@@ -1,5 +1,4 @@
/* Driver for Realtek PCI-Express card reader
- * Header file
*
* Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
*
@@ -17,15 +16,17 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Author:
- * wwang (wei_wang@realsil.com.cn)
+ * Wei WANG <wei_wang@realsil.com.cn>
* No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
*/
-#ifndef __RTSX_GENERAL_H
-#define __RTSX_GENERAL_H
+#ifndef __RTSX_PCR_H
+#define __RTSX_PCR_H
-#include "rtsx.h"
+#include <linux/mfd/rtsx_pci.h>
-int bit1cnt_long(u32 data);
+void rts5209_init_params(struct rtsx_pcr *pcr);
+void rts5229_init_params(struct rtsx_pcr *pcr);
+void rtl8411_init_params(struct rtsx_pcr *pcr);
-#endif /* __RTSX_GENERAL_H */
+#endif
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index d927dd49acb..9816c232e58 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -1014,7 +1014,7 @@ static struct gpio_chip gpio_chip_template = {
.get = sm501_gpio_get,
};
-static int __devinit sm501_gpio_register_chip(struct sm501_devdata *sm,
+static int sm501_gpio_register_chip(struct sm501_devdata *sm,
struct sm501_gpio *gpio,
struct sm501_gpio_chip *chip)
{
@@ -1042,7 +1042,7 @@ static int __devinit sm501_gpio_register_chip(struct sm501_devdata *sm,
return gpiochip_add(gchip);
}
-static int __devinit sm501_register_gpio(struct sm501_devdata *sm)
+static int sm501_register_gpio(struct sm501_devdata *sm)
{
struct sm501_gpio *gpio = &sm->gpio;
resource_size_t iobase = sm->io_res->start + SM501_GPIO;
@@ -1313,7 +1313,7 @@ static unsigned int sm501_mem_local[] = {
* Common init code for an SM501
*/
-static int __devinit sm501_init_dev(struct sm501_devdata *sm)
+static int sm501_init_dev(struct sm501_devdata *sm)
{
struct sm501_initdata *idata;
struct sm501_platdata *pdata;
@@ -1389,7 +1389,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
return 0;
}
-static int __devinit sm501_plat_probe(struct platform_device *dev)
+static int sm501_plat_probe(struct platform_device *dev)
{
struct sm501_devdata *sm;
int ret;
@@ -1578,7 +1578,7 @@ static struct sm501_platdata sm501_pci_platdata = {
.gpio_base = -1,
};
-static int __devinit sm501_pci_probe(struct pci_dev *dev,
+static int sm501_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct sm501_devdata *sm;
@@ -1685,7 +1685,7 @@ static void sm501_dev_remove(struct sm501_devdata *sm)
sm501_gpio_remove(sm);
}
-static void __devexit sm501_pci_remove(struct pci_dev *dev)
+static void sm501_pci_remove(struct pci_dev *dev)
{
struct sm501_devdata *sm = pci_get_drvdata(dev);
@@ -1723,12 +1723,12 @@ static struct pci_driver sm501_pci_driver = {
.name = "sm501",
.id_table = sm501_pci_tbl,
.probe = sm501_pci_probe,
- .remove = __devexit_p(sm501_pci_remove),
+ .remove = sm501_pci_remove,
};
MODULE_ALIAS("platform:sm501");
-static struct of_device_id __devinitdata of_sm501_match_tbl[] = {
+static struct of_device_id of_sm501_match_tbl[] = {
{ .compatible = "smi,sm501", },
{ /* end */ }
};
diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c
index d35da6820be..d6284cacd27 100644
--- a/drivers/mfd/sta2x11-mfd.c
+++ b/drivers/mfd/sta2x11-mfd.c
@@ -69,7 +69,7 @@ static struct sta2x11_mfd *sta2x11_mfd_find(struct pci_dev *pdev)
return NULL;
}
-static int __devinit sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags)
+static int sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags)
{
struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
struct sta2x11_instance *instance;
@@ -89,7 +89,7 @@ static int __devinit sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags)
return 0;
}
-static int __devexit mfd_remove(struct pci_dev *pdev)
+static int mfd_remove(struct pci_dev *pdev)
{
struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
@@ -305,7 +305,7 @@ enum bar1_cells {
.flags = IORESOURCE_MEM, \
}
-static const __devinitconst struct resource gpio_resources[] = {
+static const struct resource gpio_resources[] = {
{
.name = "sta2x11_gpio", /* 4 consecutive cells, 1 driver */
.start = 0,
@@ -313,31 +313,31 @@ static const __devinitconst struct resource gpio_resources[] = {
.flags = IORESOURCE_MEM,
}
};
-static const __devinitconst struct resource sctl_resources[] = {
+static const struct resource sctl_resources[] = {
CELL_4K("sta2x11-sctl", STA2X11_SCTL),
};
-static const __devinitconst struct resource scr_resources[] = {
+static const struct resource scr_resources[] = {
CELL_4K("sta2x11-scr", STA2X11_SCR),
};
-static const __devinitconst struct resource time_resources[] = {
+static const struct resource time_resources[] = {
CELL_4K("sta2x11-time", STA2X11_TIME),
};
-static const __devinitconst struct resource apbreg_resources[] = {
+static const struct resource apbreg_resources[] = {
CELL_4K("sta2x11-apbreg", STA2X11_APBREG),
};
#define DEV(_name, _r) \
{ .name = _name, .num_resources = ARRAY_SIZE(_r), .resources = _r, }
-static __devinitdata struct mfd_cell sta2x11_mfd_bar0[] = {
+static struct mfd_cell sta2x11_mfd_bar0[] = {
DEV("sta2x11-gpio", gpio_resources), /* offset 0: we add pdata later */
DEV("sta2x11-sctl", sctl_resources),
DEV("sta2x11-scr", scr_resources),
DEV("sta2x11-time", time_resources),
};
-static __devinitdata struct mfd_cell sta2x11_mfd_bar1[] = {
+static struct mfd_cell sta2x11_mfd_bar1[] = {
DEV("sta2x11-apbreg", apbreg_resources),
};
@@ -363,7 +363,7 @@ static int sta2x11_mfd_resume(struct pci_dev *pdev)
return 0;
}
-static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,
+static int sta2x11_mfd_probe(struct pci_dev *pdev,
const struct pci_device_id *pci_id)
{
int err, i;
diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c
index 947a06a1845..36df1877802 100644
--- a/drivers/mfd/stmpe-i2c.c
+++ b/drivers/mfd/stmpe-i2c.c
@@ -52,7 +52,7 @@ static struct stmpe_client_info i2c_ci = {
.write_block = i2c_block_write,
};
-static int __devinit
+static int
stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
{
i2c_ci.data = (void *)id;
@@ -63,7 +63,7 @@ stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
return stmpe_probe(&i2c_ci, id->driver_data);
}
-static int __devexit stmpe_i2c_remove(struct i2c_client *i2c)
+static int stmpe_i2c_remove(struct i2c_client *i2c)
{
struct stmpe *stmpe = dev_get_drvdata(&i2c->dev);
@@ -88,7 +88,7 @@ static struct i2c_driver stmpe_i2c_driver = {
.driver.pm = &stmpe_dev_pm_ops,
#endif
.probe = stmpe_i2c_probe,
- .remove = __devexit_p(stmpe_i2c_remove),
+ .remove = stmpe_i2c_remove,
.id_table = stmpe_i2c_id,
};
diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c
index 9edfe864cc0..973659f8abd 100644
--- a/drivers/mfd/stmpe-spi.c
+++ b/drivers/mfd/stmpe-spi.c
@@ -82,7 +82,7 @@ static struct stmpe_client_info spi_ci = {
.init = spi_init,
};
-static int __devinit
+static int
stmpe_spi_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
@@ -101,7 +101,7 @@ stmpe_spi_probe(struct spi_device *spi)
return stmpe_probe(&spi_ci, id->driver_data);
}
-static int __devexit stmpe_spi_remove(struct spi_device *spi)
+static int stmpe_spi_remove(struct spi_device *spi)
{
struct stmpe *stmpe = dev_get_drvdata(&spi->dev);
@@ -128,7 +128,7 @@ static struct spi_driver stmpe_spi_driver = {
#endif
},
.probe = stmpe_spi_probe,
- .remove = __devexit_p(stmpe_spi_remove),
+ .remove = stmpe_spi_remove,
.id_table = stmpe_spi_id,
};
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index c94f521f392..79e88d1fd99 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -294,12 +294,14 @@ static struct resource stmpe_gpio_resources[] = {
static struct mfd_cell stmpe_gpio_cell = {
.name = "stmpe-gpio",
+ .of_compatible = "st,stmpe-gpio",
.resources = stmpe_gpio_resources,
.num_resources = ARRAY_SIZE(stmpe_gpio_resources),
};
static struct mfd_cell stmpe_gpio_cell_noirq = {
.name = "stmpe-gpio",
+ .of_compatible = "st,stmpe-gpio",
/* gpio cell resources consist of an irq only so no resources here */
};
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 65fe609026c..3f10591ea94 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -97,7 +97,7 @@ static struct regmap_config syscon_regmap_config = {
.reg_stride = 4,
};
-static int __devinit syscon_probe(struct platform_device *pdev)
+static int syscon_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
@@ -138,7 +138,7 @@ static int __devinit syscon_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit syscon_remove(struct platform_device *pdev)
+static int syscon_remove(struct platform_device *pdev)
{
struct syscon *syscon;
@@ -156,7 +156,7 @@ static struct platform_driver syscon_driver = {
.of_match_table = of_syscon_match,
},
.probe = syscon_probe,
- .remove = __devexit_p(syscon_remove),
+ .remove = syscon_remove,
};
static int __init syscon_init(void)
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c
index 8f4c853ca11..a06d66b929b 100644
--- a/drivers/mfd/tc3589x.c
+++ b/drivers/mfd/tc3589x.c
@@ -282,7 +282,7 @@ static int tc3589x_chip_init(struct tc3589x *tc3589x)
return tc3589x_reg_write(tc3589x, TC3589x_RSTINTCLR, 0x1);
}
-static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)
+static int tc3589x_device_init(struct tc3589x *tc3589x)
{
int ret = 0;
unsigned int blocks = tc3589x->pdata->block;
@@ -329,7 +329,7 @@ static int tc3589x_of_probe(struct device_node *np,
return 0;
}
-static int __devinit tc3589x_probe(struct i2c_client *i2c,
+static int tc3589x_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct tc3589x_platform_data *pdata = i2c->dev.platform_data;
@@ -402,7 +402,7 @@ out_free:
return ret;
}
-static int __devexit tc3589x_remove(struct i2c_client *client)
+static int tc3589x_remove(struct i2c_client *client)
{
struct tc3589x *tc3589x = i2c_get_clientdata(client);
@@ -458,7 +458,7 @@ static struct i2c_driver tc3589x_driver = {
.driver.owner = THIS_MODULE,
.driver.pm = &tc3589x_dev_pm_ops,
.probe = tc3589x_probe,
- .remove = __devexit_p(tc3589x_remove),
+ .remove = tc3589x_remove,
.id_table = tc3589x_id,
};
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
index 413c891102f..366f7b90627 100644
--- a/drivers/mfd/tc6387xb.c
+++ b/drivers/mfd/tc6387xb.c
@@ -138,7 +138,7 @@ static struct mfd_cell tc6387xb_cells[] = {
},
};
-static int __devinit tc6387xb_probe(struct platform_device *dev)
+static int tc6387xb_probe(struct platform_device *dev)
{
struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
struct resource *iomem, *rscr;
@@ -208,7 +208,7 @@ err_no_irq:
return ret;
}
-static int __devexit tc6387xb_remove(struct platform_device *dev)
+static int tc6387xb_remove(struct platform_device *dev)
{
struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
@@ -229,7 +229,7 @@ static struct platform_driver tc6387xb_platform_driver = {
.name = "tc6387xb",
},
.probe = tc6387xb_probe,
- .remove = __devexit_p(tc6387xb_remove),
+ .remove = tc6387xb_remove,
.suspend = tc6387xb_suspend,
.resume = tc6387xb_resume,
};
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index dcab026fcbb..15e1463e5e1 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -137,7 +137,7 @@ static int tc6393xb_nand_enable(struct platform_device *nand)
return 0;
}
-static struct resource __devinitdata tc6393xb_nand_resources[] = {
+static struct resource tc6393xb_nand_resources[] = {
{
.start = 0x1000,
.end = 0x1007,
@@ -196,7 +196,7 @@ static const struct resource tc6393xb_ohci_resources[] = {
},
};
-static struct resource __devinitdata tc6393xb_fb_resources[] = {
+static struct resource tc6393xb_fb_resources[] = {
{
.start = 0x5000,
.end = 0x51ff,
@@ -382,7 +382,7 @@ static struct tmio_mmc_data tc6393xb_mmc_data = {
.set_clk_div = tc6393xb_mmc_clk_div,
};
-static struct mfd_cell __devinitdata tc6393xb_cells[] = {
+static struct mfd_cell tc6393xb_cells[] = {
[TC6393XB_CELL_NAND] = {
.name = "tmio-nand",
.enable = tc6393xb_nand_enable,
@@ -602,7 +602,7 @@ static void tc6393xb_detach_irq(struct platform_device *dev)
/*--------------------------------------------------------------------------*/
-static int __devinit tc6393xb_probe(struct platform_device *dev)
+static int tc6393xb_probe(struct platform_device *dev)
{
struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
struct tc6393xb *tc6393xb;
@@ -731,7 +731,7 @@ err_kzalloc:
return ret;
}
-static int __devexit tc6393xb_remove(struct platform_device *dev)
+static int tc6393xb_remove(struct platform_device *dev)
{
struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
@@ -831,7 +831,7 @@ static int tc6393xb_resume(struct platform_device *dev)
static struct platform_driver tc6393xb_driver = {
.probe = tc6393xb_probe,
- .remove = __devexit_p(tc6393xb_remove),
+ .remove = tc6393xb_remove,
.suspend = tc6393xb_suspend,
.resume = tc6393xb_resume,
diff --git a/drivers/mfd/ti-ssp.c b/drivers/mfd/ti-ssp.c
index 7c3675a74f9..09a14cec351 100644
--- a/drivers/mfd/ti-ssp.c
+++ b/drivers/mfd/ti-ssp.c
@@ -315,7 +315,7 @@ static irqreturn_t ti_ssp_interrupt(int irq, void *dev_data)
return IRQ_HANDLED;
}
-static int __devinit ti_ssp_probe(struct platform_device *pdev)
+static int ti_ssp_probe(struct platform_device *pdev)
{
static struct ti_ssp *ssp;
const struct ti_ssp_data *pdata = pdev->dev.platform_data;
@@ -433,7 +433,7 @@ error_res:
return error;
}
-static int __devexit ti_ssp_remove(struct platform_device *pdev)
+static int ti_ssp_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ti_ssp *ssp = dev_get_drvdata(dev);
@@ -451,7 +451,7 @@ static int __devexit ti_ssp_remove(struct platform_device *pdev)
static struct platform_driver ti_ssp_driver = {
.probe = ti_ssp_probe,
- .remove = __devexit_p(ti_ssp_remove),
+ .remove = ti_ssp_remove,
.driver = {
.name = "ti-ssp",
.owner = THIS_MODULE,
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c
index cccc626c83c..59e0ee247e8 100644
--- a/drivers/mfd/timberdale.c
+++ b/drivers/mfd/timberdale.c
@@ -75,13 +75,13 @@ static struct i2c_board_info timberdale_i2c_board_info[] = {
},
};
-static __devinitdata struct xiic_i2c_platform_data
+static struct xiic_i2c_platform_data
timberdale_xiic_platform_data = {
.devices = timberdale_i2c_board_info,
.num_devices = ARRAY_SIZE(timberdale_i2c_board_info)
};
-static __devinitdata struct ocores_i2c_platform_data
+static struct ocores_i2c_platform_data
timberdale_ocores_platform_data = {
.reg_shift = 2,
.clock_khz = 62500,
@@ -89,7 +89,7 @@ timberdale_ocores_platform_data = {
.num_devices = ARRAY_SIZE(timberdale_i2c_board_info)
};
-static const __devinitconst struct resource timberdale_xiic_resources[] = {
+static const struct resource timberdale_xiic_resources[] = {
{
.start = XIICOFFSET,
.end = XIICEND,
@@ -102,7 +102,7 @@ static const __devinitconst struct resource timberdale_xiic_resources[] = {
},
};
-static const __devinitconst struct resource timberdale_ocores_resources[] = {
+static const struct resource timberdale_ocores_resources[] = {
{
.start = OCORESOFFSET,
.end = OCORESEND,
@@ -143,7 +143,7 @@ static struct spi_board_info timberdale_spi_8bit_board_info[] = {
},
};
-static __devinitdata struct xspi_platform_data timberdale_xspi_platform_data = {
+static struct xspi_platform_data timberdale_xspi_platform_data = {
.num_chipselect = 3,
.little_endian = true,
/* bits per word and devices will be filled in runtime depending
@@ -151,7 +151,7 @@ static __devinitdata struct xspi_platform_data timberdale_xspi_platform_data = {
*/
};
-static const __devinitconst struct resource timberdale_spi_resources[] = {
+static const struct resource timberdale_spi_resources[] = {
{
.start = SPIOFFSET,
.end = SPIEND,
@@ -164,13 +164,13 @@ static const __devinitconst struct resource timberdale_spi_resources[] = {
},
};
-static __devinitdata struct ks8842_platform_data
+static struct ks8842_platform_data
timberdale_ks8842_platform_data = {
.rx_dma_channel = DMA_ETH_RX,
.tx_dma_channel = DMA_ETH_TX
};
-static const __devinitconst struct resource timberdale_eth_resources[] = {
+static const struct resource timberdale_eth_resources[] = {
{
.start = ETHOFFSET,
.end = ETHEND,
@@ -183,14 +183,14 @@ static const __devinitconst struct resource timberdale_eth_resources[] = {
},
};
-static __devinitdata struct timbgpio_platform_data
+static struct timbgpio_platform_data
timberdale_gpio_platform_data = {
.gpio_base = 0,
.nr_pins = GPIO_NR_PINS,
.irq_base = 200,
};
-static const __devinitconst struct resource timberdale_gpio_resources[] = {
+static const struct resource timberdale_gpio_resources[] = {
{
.start = GPIOOFFSET,
.end = GPIOEND,
@@ -203,7 +203,7 @@ static const __devinitconst struct resource timberdale_gpio_resources[] = {
},
};
-static const __devinitconst struct resource timberdale_mlogicore_resources[] = {
+static const struct resource timberdale_mlogicore_resources[] = {
{
.start = MLCOREOFFSET,
.end = MLCOREEND,
@@ -221,7 +221,7 @@ static const __devinitconst struct resource timberdale_mlogicore_resources[] = {
},
};
-static const __devinitconst struct resource timberdale_uart_resources[] = {
+static const struct resource timberdale_uart_resources[] = {
{
.start = UARTOFFSET,
.end = UARTEND,
@@ -234,7 +234,7 @@ static const __devinitconst struct resource timberdale_uart_resources[] = {
},
};
-static const __devinitconst struct resource timberdale_uartlite_resources[] = {
+static const struct resource timberdale_uartlite_resources[] = {
{
.start = UARTLITEOFFSET,
.end = UARTLITEEND,
@@ -247,13 +247,13 @@ static const __devinitconst struct resource timberdale_uartlite_resources[] = {
},
};
-static __devinitdata struct i2c_board_info timberdale_adv7180_i2c_board_info = {
+static struct i2c_board_info timberdale_adv7180_i2c_board_info = {
/* Requires jumper JP9 to be off */
I2C_BOARD_INFO("adv7180", 0x42 >> 1),
.irq = IRQ_TIMBERDALE_ADV7180
};
-static __devinitdata struct timb_video_platform_data
+static struct timb_video_platform_data
timberdale_video_platform_data = {
.dma_channel = DMA_VIDEO_RX,
.i2c_adapter = 0,
@@ -262,7 +262,7 @@ static __devinitdata struct timb_video_platform_data
}
};
-static const __devinitconst struct resource
+static const struct resource
timberdale_radio_resources[] = {
{
.start = RDSOFFSET,
@@ -276,22 +276,22 @@ timberdale_radio_resources[] = {
},
};
-static __devinitdata struct i2c_board_info timberdale_tef6868_i2c_board_info = {
+static struct i2c_board_info timberdale_tef6868_i2c_board_info = {
I2C_BOARD_INFO("tef6862", 0x60)
};
-static __devinitdata struct i2c_board_info timberdale_saa7706_i2c_board_info = {
+static struct i2c_board_info timberdale_saa7706_i2c_board_info = {
I2C_BOARD_INFO("saa7706h", 0x1C)
};
-static __devinitdata struct timb_radio_platform_data
+static struct timb_radio_platform_data
timberdale_radio_platform_data = {
.i2c_adapter = 0,
.tuner = &timberdale_tef6868_i2c_board_info,
.dsp = &timberdale_saa7706_i2c_board_info
};
-static const __devinitconst struct resource timberdale_video_resources[] = {
+static const struct resource timberdale_video_resources[] = {
{
.start = LOGIWOFFSET,
.end = LOGIWEND,
@@ -303,7 +303,7 @@ static const __devinitconst struct resource timberdale_video_resources[] = {
*/
};
-static __devinitdata struct timb_dma_platform_data timb_dma_platform_data = {
+static struct timb_dma_platform_data timb_dma_platform_data = {
.nr_channels = 10,
.channels = {
{
@@ -362,7 +362,7 @@ static __devinitdata struct timb_dma_platform_data timb_dma_platform_data = {
}
};
-static const __devinitconst struct resource timberdale_dma_resources[] = {
+static const struct resource timberdale_dma_resources[] = {
{
.start = DMAOFFSET,
.end = DMAEND,
@@ -375,7 +375,7 @@ static const __devinitconst struct resource timberdale_dma_resources[] = {
},
};
-static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
+static struct mfd_cell timberdale_cells_bar0_cfg0[] = {
{
.name = "timb-dma",
.num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -432,7 +432,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
},
};
-static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
+static struct mfd_cell timberdale_cells_bar0_cfg1[] = {
{
.name = "timb-dma",
.num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -499,7 +499,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
},
};
-static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
+static struct mfd_cell timberdale_cells_bar0_cfg2[] = {
{
.name = "timb-dma",
.num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -549,7 +549,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
},
};
-static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
+static struct mfd_cell timberdale_cells_bar0_cfg3[] = {
{
.name = "timb-dma",
.num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -606,7 +606,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
},
};
-static const __devinitconst struct resource timberdale_sdhc_resources[] = {
+static const struct resource timberdale_sdhc_resources[] = {
/* located in bar 1 and bar 2 */
{
.start = SDHC0OFFSET,
@@ -620,7 +620,7 @@ static const __devinitconst struct resource timberdale_sdhc_resources[] = {
},
};
-static __devinitdata struct mfd_cell timberdale_cells_bar1[] = {
+static struct mfd_cell timberdale_cells_bar1[] = {
{
.name = "sdhci",
.num_resources = ARRAY_SIZE(timberdale_sdhc_resources),
@@ -628,7 +628,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar1[] = {
},
};
-static __devinitdata struct mfd_cell timberdale_cells_bar2[] = {
+static struct mfd_cell timberdale_cells_bar2[] = {
{
.name = "sdhci",
.num_resources = ARRAY_SIZE(timberdale_sdhc_resources),
@@ -650,7 +650,7 @@ static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
/*--------------------------------------------------------------------------*/
-static int __devinit timb_probe(struct pci_dev *dev,
+static int timb_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct timberdale_device *priv;
@@ -840,7 +840,7 @@ err_enable:
return -ENODEV;
}
-static void __devexit timb_remove(struct pci_dev *dev)
+static void timb_remove(struct pci_dev *dev)
{
struct timberdale_device *priv = pci_get_drvdata(dev);
@@ -867,7 +867,7 @@ static struct pci_driver timberdale_pci_driver = {
.name = DRIVER_NAME,
.id_table = timberdale_pci_tbl,
.probe = timb_probe,
- .remove = __devexit_p(timb_remove),
+ .remove = timb_remove,
};
static int __init timberdale_init(void)
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c
index 14051bdc714..1d302f583ad 100644
--- a/drivers/mfd/tps6105x.c
+++ b/drivers/mfd/tps6105x.c
@@ -86,7 +86,7 @@ fail:
}
EXPORT_SYMBOL(tps6105x_mask_and_set);
-static int __devinit tps6105x_startup(struct tps6105x *tps6105x)
+static int tps6105x_startup(struct tps6105x *tps6105x)
{
int ret;
u8 regval;
@@ -133,7 +133,7 @@ static struct mfd_cell tps6105x_cells[] = {
},
};
-static int __devinit tps6105x_probe(struct i2c_client *client,
+static int tps6105x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tps6105x *tps6105x;
@@ -199,7 +199,7 @@ fail:
return ret;
}
-static int __devexit tps6105x_remove(struct i2c_client *client)
+static int tps6105x_remove(struct i2c_client *client)
{
struct tps6105x *tps6105x = i2c_get_clientdata(client);
@@ -226,7 +226,7 @@ static struct i2c_driver tps6105x_driver = {
.name = "tps6105x",
},
.probe = tps6105x_probe,
- .remove = __devexit_p(tps6105x_remove),
+ .remove = tps6105x_remove,
.id_table = tps6105x_id,
};
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c
index 074ae32b0d2..382a857b0dd 100644
--- a/drivers/mfd/tps65090.c
+++ b/drivers/mfd/tps65090.c
@@ -188,7 +188,7 @@ static irqreturn_t tps65090_irq(int irq, void *data)
return acks ? IRQ_HANDLED : IRQ_NONE;
}
-static int __devinit tps65090_irq_init(struct tps65090 *tps65090, int irq,
+static int tps65090_irq_init(struct tps65090 *tps65090, int irq,
int irq_base)
{
int i, ret;
@@ -251,7 +251,7 @@ static const struct regmap_config tps65090_regmap_config = {
.volatile_reg = is_volatile_reg,
};
-static int __devinit tps65090_i2c_probe(struct i2c_client *client,
+static int tps65090_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tps65090_platform_data *pdata = client->dev.platform_data;
@@ -308,7 +308,7 @@ err_exit:
return ret;
}
-static int __devexit tps65090_i2c_remove(struct i2c_client *client)
+static int tps65090_i2c_remove(struct i2c_client *client)
{
struct tps65090 *tps65090 = i2c_get_clientdata(client);
@@ -354,7 +354,7 @@ static struct i2c_driver tps65090_driver = {
.pm = &tps65090_pm_ops,
},
.probe = tps65090_i2c_probe,
- .remove = __devexit_p(tps65090_i2c_remove),
+ .remove = tps65090_i2c_remove,
.id_table = tps65090_id_table,
};
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c
index 3fb32e65525..e14e252e347 100644
--- a/drivers/mfd/tps65217.c
+++ b/drivers/mfd/tps65217.c
@@ -153,7 +153,7 @@ static const struct of_device_id tps65217_of_match[] = {
{ /* sentinel */ },
};
-static int __devinit tps65217_probe(struct i2c_client *client,
+static int tps65217_probe(struct i2c_client *client,
const struct i2c_device_id *ids)
{
struct tps65217 *tps;
@@ -214,7 +214,7 @@ static int __devinit tps65217_probe(struct i2c_client *client,
return 0;
}
-static int __devexit tps65217_remove(struct i2c_client *client)
+static int tps65217_remove(struct i2c_client *client)
{
struct tps65217 *tps = i2c_get_clientdata(client);
@@ -237,7 +237,7 @@ static struct i2c_driver tps65217_driver = {
},
.id_table = tps65217_id_table,
.probe = tps65217_probe,
- .remove = __devexit_p(tps65217_remove),
+ .remove = tps65217_remove,
};
static int __init tps65217_init(void)
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index 46746436877..9f92c3b2209 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -267,7 +267,7 @@ static irqreturn_t tps6586x_irq(int irq, void *data)
return IRQ_HANDLED;
}
-static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
+static int tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
int irq_base)
{
int i, ret;
@@ -316,7 +316,7 @@ static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
return ret;
}
-static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x,
+static int tps6586x_add_subdevs(struct tps6586x *tps6586x,
struct tps6586x_platform_data *pdata)
{
struct tps6586x_subdev_info *subdev;
@@ -468,7 +468,7 @@ static void tps6586x_power_off(void)
tps6586x_set_bits(tps6586x_dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT);
}
-static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
+static int tps6586x_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tps6586x_platform_data *pdata = client->dev.platform_data;
@@ -548,7 +548,7 @@ err_mfd_add:
return ret;
}
-static int __devexit tps6586x_i2c_remove(struct i2c_client *client)
+static int tps6586x_i2c_remove(struct i2c_client *client)
{
struct tps6586x *tps6586x = i2c_get_clientdata(client);
@@ -572,7 +572,7 @@ static struct i2c_driver tps6586x_driver = {
.of_match_table = of_match_ptr(tps6586x_of_match),
},
.probe = tps6586x_i2c_probe,
- .remove = __devexit_p(tps6586x_i2c_remove),
+ .remove = tps6586x_i2c_remove,
.id_table = tps6586x_id_table,
};
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index 0d79ce2b501..ce054654f5b 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -78,7 +78,7 @@ static const struct regmap_config tps65910_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
-static int __devinit tps65910_ck32k_init(struct tps65910 *tps65910,
+static int tps65910_ck32k_init(struct tps65910 *tps65910,
struct tps65910_board *pmic_pdata)
{
int ret;
@@ -96,7 +96,7 @@ static int __devinit tps65910_ck32k_init(struct tps65910 *tps65910,
return 0;
}
-static int __devinit tps65910_sleepinit(struct tps65910 *tps65910,
+static int tps65910_sleepinit(struct tps65910 *tps65910,
struct tps65910_board *pmic_pdata)
{
struct device *dev = NULL;
@@ -237,7 +237,7 @@ static void tps65910_power_off(void)
DEVCTRL_DEV_ON_MASK);
}
-static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
+static int tps65910_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct tps65910 *tps65910;
@@ -302,7 +302,7 @@ static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
return ret;
}
-static __devexit int tps65910_i2c_remove(struct i2c_client *i2c)
+static int tps65910_i2c_remove(struct i2c_client *i2c)
{
struct tps65910 *tps65910 = i2c_get_clientdata(i2c);
@@ -327,7 +327,7 @@ static struct i2c_driver tps65910_i2c_driver = {
.of_match_table = of_match_ptr(tps65910_of_match),
},
.probe = tps65910_i2c_probe,
- .remove = __devexit_p(tps65910_i2c_remove),
+ .remove = tps65910_i2c_remove,
.id_table = tps65910_i2c_id,
};
diff --git a/drivers/mfd/tps65911-comparator.c b/drivers/mfd/tps65911-comparator.c
index 0b6e361432c..c0816ebd9d7 100644
--- a/drivers/mfd/tps65911-comparator.c
+++ b/drivers/mfd/tps65911-comparator.c
@@ -122,7 +122,7 @@ static ssize_t comp_threshold_show(struct device *dev,
static DEVICE_ATTR(comp1_threshold, S_IRUGO, comp_threshold_show, NULL);
static DEVICE_ATTR(comp2_threshold, S_IRUGO, comp_threshold_show, NULL);
-static __devinit int tps65911_comparator_probe(struct platform_device *pdev)
+static int tps65911_comparator_probe(struct platform_device *pdev)
{
struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
struct tps65910_board *pdata = dev_get_platdata(tps65910->dev);
@@ -152,7 +152,7 @@ static __devinit int tps65911_comparator_probe(struct platform_device *pdev)
return ret;
}
-static __devexit int tps65911_comparator_remove(struct platform_device *pdev)
+static int tps65911_comparator_remove(struct platform_device *pdev)
{
struct tps65910 *tps65910;
@@ -169,7 +169,7 @@ static struct platform_driver tps65911_comparator_driver = {
.owner = THIS_MODULE,
},
.probe = tps65911_comparator_probe,
- .remove = __devexit_p(tps65911_comparator_remove),
+ .remove = tps65911_comparator_remove,
};
static int __init tps65911_comparator_init(void)
diff --git a/drivers/mfd/tps65912-spi.c b/drivers/mfd/tps65912-spi.c
index 27d3302d56b..b45f460d299 100644
--- a/drivers/mfd/tps65912-spi.c
+++ b/drivers/mfd/tps65912-spi.c
@@ -81,7 +81,7 @@ static int tps65912_spi_read(struct tps65912 *tps65912, u8 addr,
return ret;
}
-static int __devinit tps65912_spi_probe(struct spi_device *spi)
+static int tps65912_spi_probe(struct spi_device *spi)
{
struct tps65912 *tps65912;
@@ -99,7 +99,7 @@ static int __devinit tps65912_spi_probe(struct spi_device *spi)
return tps65912_device_init(tps65912);
}
-static int __devexit tps65912_spi_remove(struct spi_device *spi)
+static int tps65912_spi_remove(struct spi_device *spi)
{
struct tps65912 *tps65912 = spi_get_drvdata(spi);
@@ -114,7 +114,7 @@ static struct spi_driver tps65912_spi_driver = {
.owner = THIS_MODULE,
},
.probe = tps65912_spi_probe,
- .remove = __devexit_p(tps65912_spi_remove),
+ .remove = tps65912_spi_remove,
};
static int __init tps65912_spi_init(void)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 4ae64232020..11b76c0109f 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -671,7 +671,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
}
if (IS_ENABLED(CONFIG_PWM_TWL6030) && twl_class_is_6030()) {
- child = add_child(TWL6030_MODULE_ID1, "twl6030-pwm", NULL, 0,
+ child = add_child(SUB_CHIP_ID1, "twl6030-pwm", NULL, 0,
false, 0, 0);
if (IS_ERR(child))
return PTR_ERR(child);
@@ -1170,7 +1170,7 @@ static int twl_remove(struct i2c_client *client)
}
/* NOTE: This driver only handles a single twl4030/tps659x0 chip */
-static int __devinit
+static int
twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct twl4030_platform_data *pdata = client->dev.platform_data;
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c
index 5c11acf9e0f..e16edca9267 100644
--- a/drivers/mfd/twl4030-audio.c
+++ b/drivers/mfd/twl4030-audio.c
@@ -184,7 +184,7 @@ static bool twl4030_audio_has_vibra(struct twl4030_audio_data *pdata,
return false;
}
-static int __devinit twl4030_audio_probe(struct platform_device *pdev)
+static int twl4030_audio_probe(struct platform_device *pdev)
{
struct twl4030_audio *audio;
struct twl4030_audio_data *pdata = pdev->dev.platform_data;
@@ -269,7 +269,7 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit twl4030_audio_remove(struct platform_device *pdev)
+static int twl4030_audio_remove(struct platform_device *pdev)
{
mfd_remove_devices(&pdev->dev);
platform_set_drvdata(pdev, NULL);
@@ -291,7 +291,7 @@ static struct platform_driver twl4030_audio_driver = {
.of_match_table = twl4030_audio_of_match,
},
.probe = twl4030_audio_probe,
- .remove = __devexit_p(twl4030_audio_remove),
+ .remove = twl4030_audio_remove,
};
module_platform_driver(twl4030_audio_driver);
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index ad733d76207..cdd1173ed4e 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -672,7 +672,8 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
irq = sih_mod + twl4030_irq_base;
irq_set_handler_data(irq, agent);
agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name);
- status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0,
+ status = request_threaded_irq(irq, NULL, handle_twl4030_sih,
+ IRQF_EARLY_RESUME,
agent->irq_name ?: sih->name, NULL);
dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name,
diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c
index 456ecb5ac4f..a39dcf3e213 100644
--- a/drivers/mfd/twl4030-madc.c
+++ b/drivers/mfd/twl4030-madc.c
@@ -692,7 +692,7 @@ static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
/*
* Initialize MADC and request for threaded irq
*/
-static int __devinit twl4030_madc_probe(struct platform_device *pdev)
+static int twl4030_madc_probe(struct platform_device *pdev)
{
struct twl4030_madc_data *madc;
struct twl4030_madc_platform_data *pdata = pdev->dev.platform_data;
@@ -785,7 +785,7 @@ err_power:
return ret;
}
-static int __devexit twl4030_madc_remove(struct platform_device *pdev)
+static int twl4030_madc_remove(struct platform_device *pdev)
{
struct twl4030_madc_data *madc = platform_get_drvdata(pdev);
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index 79ca33dfacc..a5332063183 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -124,7 +124,7 @@ static u8 res_config_addrs[] = {
[RES_MAIN_REF] = 0x94,
};
-static int __devinit twl4030_write_script_byte(u8 address, u8 byte)
+static int twl4030_write_script_byte(u8 address, u8 byte)
{
int err;
@@ -138,7 +138,7 @@ out:
return err;
}
-static int __devinit twl4030_write_script_ins(u8 address, u16 pmb_message,
+static int twl4030_write_script_ins(u8 address, u16 pmb_message,
u8 delay, u8 next)
{
int err;
@@ -158,7 +158,7 @@ out:
return err;
}
-static int __devinit twl4030_write_script(u8 address, struct twl4030_ins *script,
+static int twl4030_write_script(u8 address, struct twl4030_ins *script,
int len)
{
int err;
@@ -183,7 +183,7 @@ static int __devinit twl4030_write_script(u8 address, struct twl4030_ins *script
return err;
}
-static int __devinit twl4030_config_wakeup3_sequence(u8 address)
+static int twl4030_config_wakeup3_sequence(u8 address)
{
int err;
u8 data;
@@ -208,7 +208,7 @@ out:
return err;
}
-static int __devinit twl4030_config_wakeup12_sequence(u8 address)
+static int twl4030_config_wakeup12_sequence(u8 address)
{
int err = 0;
u8 data;
@@ -262,7 +262,7 @@ out:
return err;
}
-static int __devinit twl4030_config_sleep_sequence(u8 address)
+static int twl4030_config_sleep_sequence(u8 address)
{
int err;
@@ -276,7 +276,7 @@ static int __devinit twl4030_config_sleep_sequence(u8 address)
return err;
}
-static int __devinit twl4030_config_warmreset_sequence(u8 address)
+static int twl4030_config_warmreset_sequence(u8 address)
{
int err;
u8 rd_data;
@@ -324,7 +324,7 @@ out:
return err;
}
-static int __devinit twl4030_configure_resource(struct twl4030_resconfig *rconfig)
+static int twl4030_configure_resource(struct twl4030_resconfig *rconfig)
{
int rconfig_addr;
int err;
@@ -416,7 +416,7 @@ static int __devinit twl4030_configure_resource(struct twl4030_resconfig *rconfi
return 0;
}
-static int __devinit load_twl4030_script(struct twl4030_script *tscript,
+static int load_twl4030_script(struct twl4030_script *tscript,
u8 address)
{
int err;
@@ -527,7 +527,7 @@ void twl4030_power_off(void)
pr_err("TWL4030 Unable to power off\n");
}
-void __devinit twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
+void twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
{
int err = 0;
int i;
diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c
index b9a636d44c7..757ecc63338 100644
--- a/drivers/mfd/vx855.c
+++ b/drivers/mfd/vx855.c
@@ -72,7 +72,7 @@ static struct mfd_cell vx855_cells[] = {
},
};
-static __devinit int vx855_probe(struct pci_dev *pdev,
+static int vx855_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
int ret;
@@ -112,7 +112,7 @@ out:
return ret;
}
-static void __devexit vx855_remove(struct pci_dev *pdev)
+static void vx855_remove(struct pci_dev *pdev)
{
mfd_remove_devices(&pdev->dev);
pci_disable_device(pdev);
@@ -128,7 +128,7 @@ static struct pci_driver vx855_pci_driver = {
.name = "vx855",
.id_table = vx855_pci_tbl,
.probe = vx855_probe,
- .remove = __devexit_p(vx855_remove),
+ .remove = vx855_remove,
};
module_pci_driver(vx855_pci_driver);
diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c
index 86e0e4309fc..edbe6c1b755 100644
--- a/drivers/mfd/wl1273-core.c
+++ b/drivers/mfd/wl1273-core.c
@@ -182,7 +182,7 @@ static int wl1273_core_remove(struct i2c_client *client)
return 0;
}
-static int __devinit wl1273_core_probe(struct i2c_client *client,
+static int wl1273_core_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct wl1273_fm_platform_data *pdata = client->dev.platform_data;
@@ -262,7 +262,7 @@ static struct i2c_driver wl1273_core_driver = {
},
.probe = wl1273_core_probe,
.id_table = wl1273_driver_id_table,
- .remove = __devexit_p(wl1273_core_remove),
+ .remove = wl1273_core_remove,
};
static int __init wl1273_core_init(void)
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c
index 01b9255ed63..14490cc785d 100644
--- a/drivers/mfd/wm5102-tables.c
+++ b/drivers/mfd/wm5102-tables.c
@@ -43,6 +43,7 @@ static const struct reg_default wm5102_reva_patch[] = {
{ 0x479, 0x0A30 },
{ 0x47B, 0x0810 },
{ 0x47D, 0x0510 },
+ { 0x4D1, 0x017F },
{ 0x500, 0x000D },
{ 0x507, 0x1820 },
{ 0x508, 0x1820 },
@@ -52,524 +53,6 @@ static const struct reg_default wm5102_reva_patch[] = {
{ 0x580, 0x000D },
{ 0x587, 0x1820 },
{ 0x588, 0x1820 },
- { 0x101, 0x8140 },
- { 0x3000, 0x2225 },
- { 0x3001, 0x3a03 },
- { 0x3002, 0x0225 },
- { 0x3003, 0x0801 },
- { 0x3004, 0x6249 },
- { 0x3005, 0x0c04 },
- { 0x3006, 0x0225 },
- { 0x3007, 0x5901 },
- { 0x3008, 0xe249 },
- { 0x3009, 0x030d },
- { 0x300a, 0x0249 },
- { 0x300b, 0x2c01 },
- { 0x300c, 0xe249 },
- { 0x300d, 0x4342 },
- { 0x300e, 0xe249 },
- { 0x300f, 0x73c0 },
- { 0x3010, 0x4249 },
- { 0x3011, 0x0c00 },
- { 0x3012, 0x0225 },
- { 0x3013, 0x1f01 },
- { 0x3014, 0x0225 },
- { 0x3015, 0x1e01 },
- { 0x3016, 0x0225 },
- { 0x3017, 0xfa00 },
- { 0x3018, 0x0000 },
- { 0x3019, 0xf000 },
- { 0x301a, 0x0000 },
- { 0x301b, 0xf000 },
- { 0x301c, 0x0000 },
- { 0x301d, 0xf000 },
- { 0x301e, 0x0000 },
- { 0x301f, 0xf000 },
- { 0x3020, 0x0000 },
- { 0x3021, 0xf000 },
- { 0x3022, 0x0000 },
- { 0x3023, 0xf000 },
- { 0x3024, 0x0000 },
- { 0x3025, 0xf000 },
- { 0x3026, 0x0000 },
- { 0x3027, 0xf000 },
- { 0x3028, 0x0000 },
- { 0x3029, 0xf000 },
- { 0x302a, 0x0000 },
- { 0x302b, 0xf000 },
- { 0x302c, 0x0000 },
- { 0x302d, 0xf000 },
- { 0x302e, 0x0000 },
- { 0x302f, 0xf000 },
- { 0x3030, 0x0225 },
- { 0x3031, 0x1a01 },
- { 0x3032, 0x0225 },
- { 0x3033, 0x1e00 },
- { 0x3034, 0x0225 },
- { 0x3035, 0x1f00 },
- { 0x3036, 0x6225 },
- { 0x3037, 0xf800 },
- { 0x3038, 0x0000 },
- { 0x3039, 0xf000 },
- { 0x303a, 0x0000 },
- { 0x303b, 0xf000 },
- { 0x303c, 0x0000 },
- { 0x303d, 0xf000 },
- { 0x303e, 0x0000 },
- { 0x303f, 0xf000 },
- { 0x3040, 0x2226 },
- { 0x3041, 0x3a03 },
- { 0x3042, 0x0226 },
- { 0x3043, 0x0801 },
- { 0x3044, 0x6249 },
- { 0x3045, 0x0c06 },
- { 0x3046, 0x0226 },
- { 0x3047, 0x5901 },
- { 0x3048, 0xe249 },
- { 0x3049, 0x030d },
- { 0x304a, 0x0249 },
- { 0x304b, 0x2c01 },
- { 0x304c, 0xe249 },
- { 0x304d, 0x4342 },
- { 0x304e, 0xe249 },
- { 0x304f, 0x73c0 },
- { 0x3050, 0x4249 },
- { 0x3051, 0x0c00 },
- { 0x3052, 0x0226 },
- { 0x3053, 0x1f01 },
- { 0x3054, 0x0226 },
- { 0x3055, 0x1e01 },
- { 0x3056, 0x0226 },
- { 0x3057, 0xfa00 },
- { 0x3058, 0x0000 },
- { 0x3059, 0xf000 },
- { 0x305a, 0x0000 },
- { 0x305b, 0xf000 },
- { 0x305c, 0x0000 },
- { 0x305d, 0xf000 },
- { 0x305e, 0x0000 },
- { 0x305f, 0xf000 },
- { 0x3060, 0x0000 },
- { 0x3061, 0xf000 },
- { 0x3062, 0x0000 },
- { 0x3063, 0xf000 },
- { 0x3064, 0x0000 },
- { 0x3065, 0xf000 },
- { 0x3066, 0x0000 },
- { 0x3067, 0xf000 },
- { 0x3068, 0x0000 },
- { 0x3069, 0xf000 },
- { 0x306a, 0x0000 },
- { 0x306b, 0xf000 },
- { 0x306c, 0x0000 },
- { 0x306d, 0xf000 },
- { 0x306e, 0x0000 },
- { 0x306f, 0xf000 },
- { 0x3070, 0x0226 },
- { 0x3071, 0x1a01 },
- { 0x3072, 0x0226 },
- { 0x3073, 0x1e00 },
- { 0x3074, 0x0226 },
- { 0x3075, 0x1f00 },
- { 0x3076, 0x6226 },
- { 0x3077, 0xf800 },
- { 0x3078, 0x0000 },
- { 0x3079, 0xf000 },
- { 0x307a, 0x0000 },
- { 0x307b, 0xf000 },
- { 0x307c, 0x0000 },
- { 0x307d, 0xf000 },
- { 0x307e, 0x0000 },
- { 0x307f, 0xf000 },
- { 0x3080, 0x2227 },
- { 0x3081, 0x3a03 },
- { 0x3082, 0x0227 },
- { 0x3083, 0x0801 },
- { 0x3084, 0x6255 },
- { 0x3085, 0x0c04 },
- { 0x3086, 0x0227 },
- { 0x3087, 0x5901 },
- { 0x3088, 0xe255 },
- { 0x3089, 0x030d },
- { 0x308a, 0x0255 },
- { 0x308b, 0x2c01 },
- { 0x308c, 0xe255 },
- { 0x308d, 0x4342 },
- { 0x308e, 0xe255 },
- { 0x308f, 0x73c0 },
- { 0x3090, 0x4255 },
- { 0x3091, 0x0c00 },
- { 0x3092, 0x0227 },
- { 0x3093, 0x1f01 },
- { 0x3094, 0x0227 },
- { 0x3095, 0x1e01 },
- { 0x3096, 0x0227 },
- { 0x3097, 0xfa00 },
- { 0x3098, 0x0000 },
- { 0x3099, 0xf000 },
- { 0x309a, 0x0000 },
- { 0x309b, 0xf000 },
- { 0x309c, 0x0000 },
- { 0x309d, 0xf000 },
- { 0x309e, 0x0000 },
- { 0x309f, 0xf000 },
- { 0x30a0, 0x0000 },
- { 0x30a1, 0xf000 },
- { 0x30a2, 0x0000 },
- { 0x30a3, 0xf000 },
- { 0x30a4, 0x0000 },
- { 0x30a5, 0xf000 },
- { 0x30a6, 0x0000 },
- { 0x30a7, 0xf000 },
- { 0x30a8, 0x0000 },
- { 0x30a9, 0xf000 },
- { 0x30aa, 0x0000 },
- { 0x30ab, 0xf000 },
- { 0x30ac, 0x0000 },
- { 0x30ad, 0xf000 },
- { 0x30ae, 0x0000 },
- { 0x30af, 0xf000 },
- { 0x30b0, 0x0227 },
- { 0x30b1, 0x1a01 },
- { 0x30b2, 0x0227 },
- { 0x30b3, 0x1e00 },
- { 0x30b4, 0x0227 },
- { 0x30b5, 0x1f00 },
- { 0x30b6, 0x6227 },
- { 0x30b7, 0xf800 },
- { 0x30b8, 0x0000 },
- { 0x30b9, 0xf000 },
- { 0x30ba, 0x0000 },
- { 0x30bb, 0xf000 },
- { 0x30bc, 0x0000 },
- { 0x30bd, 0xf000 },
- { 0x30be, 0x0000 },
- { 0x30bf, 0xf000 },
- { 0x30c0, 0x2228 },
- { 0x30c1, 0x3a03 },
- { 0x30c2, 0x0228 },
- { 0x30c3, 0x0801 },
- { 0x30c4, 0x6255 },
- { 0x30c5, 0x0c06 },
- { 0x30c6, 0x0228 },
- { 0x30c7, 0x5901 },
- { 0x30c8, 0xe255 },
- { 0x30c9, 0x030d },
- { 0x30ca, 0x0255 },
- { 0x30cb, 0x2c01 },
- { 0x30cc, 0xe255 },
- { 0x30cd, 0x4342 },
- { 0x30ce, 0xe255 },
- { 0x30cf, 0x73c0 },
- { 0x30d0, 0x4255 },
- { 0x30d1, 0x0c00 },
- { 0x30d2, 0x0228 },
- { 0x30d3, 0x1f01 },
- { 0x30d4, 0x0228 },
- { 0x30d5, 0x1e01 },
- { 0x30d6, 0x0228 },
- { 0x30d7, 0xfa00 },
- { 0x30d8, 0x0000 },
- { 0x30d9, 0xf000 },
- { 0x30da, 0x0000 },
- { 0x30db, 0xf000 },
- { 0x30dc, 0x0000 },
- { 0x30dd, 0xf000 },
- { 0x30de, 0x0000 },
- { 0x30df, 0xf000 },
- { 0x30e0, 0x0000 },
- { 0x30e1, 0xf000 },
- { 0x30e2, 0x0000 },
- { 0x30e3, 0xf000 },
- { 0x30e4, 0x0000 },
- { 0x30e5, 0xf000 },
- { 0x30e6, 0x0000 },
- { 0x30e7, 0xf000 },
- { 0x30e8, 0x0000 },
- { 0x30e9, 0xf000 },
- { 0x30ea, 0x0000 },
- { 0x30eb, 0xf000 },
- { 0x30ec, 0x0000 },
- { 0x30ed, 0xf000 },
- { 0x30ee, 0x0000 },
- { 0x30ef, 0xf000 },
- { 0x30f0, 0x0228 },
- { 0x30f1, 0x1a01 },
- { 0x30f2, 0x0228 },
- { 0x30f3, 0x1e00 },
- { 0x30f4, 0x0228 },
- { 0x30f5, 0x1f00 },
- { 0x30f6, 0x6228 },
- { 0x30f7, 0xf800 },
- { 0x30f8, 0x0000 },
- { 0x30f9, 0xf000 },
- { 0x30fa, 0x0000 },
- { 0x30fb, 0xf000 },
- { 0x30fc, 0x0000 },
- { 0x30fd, 0xf000 },
- { 0x30fe, 0x0000 },
- { 0x30ff, 0xf000 },
- { 0x3100, 0x222b },
- { 0x3101, 0x3a03 },
- { 0x3102, 0x222b },
- { 0x3103, 0x5803 },
- { 0x3104, 0xe26f },
- { 0x3105, 0x030d },
- { 0x3106, 0x626f },
- { 0x3107, 0x2c01 },
- { 0x3108, 0xe26f },
- { 0x3109, 0x4342 },
- { 0x310a, 0xe26f },
- { 0x310b, 0x73c0 },
- { 0x310c, 0x026f },
- { 0x310d, 0x0c00 },
- { 0x310e, 0x022b },
- { 0x310f, 0x1f01 },
- { 0x3110, 0x022b },
- { 0x3111, 0x1e01 },
- { 0x3112, 0x022b },
- { 0x3113, 0xfa00 },
- { 0x3114, 0x0000 },
- { 0x3115, 0xf000 },
- { 0x3116, 0x0000 },
- { 0x3117, 0xf000 },
- { 0x3118, 0x0000 },
- { 0x3119, 0xf000 },
- { 0x311a, 0x0000 },
- { 0x311b, 0xf000 },
- { 0x311c, 0x0000 },
- { 0x311d, 0xf000 },
- { 0x311e, 0x0000 },
- { 0x311f, 0xf000 },
- { 0x3120, 0x022b },
- { 0x3121, 0x0a01 },
- { 0x3122, 0x022b },
- { 0x3123, 0x1e00 },
- { 0x3124, 0x022b },
- { 0x3125, 0x1f00 },
- { 0x3126, 0x622b },
- { 0x3127, 0xf800 },
- { 0x3128, 0x0000 },
- { 0x3129, 0xf000 },
- { 0x312a, 0x0000 },
- { 0x312b, 0xf000 },
- { 0x312c, 0x0000 },
- { 0x312d, 0xf000 },
- { 0x312e, 0x0000 },
- { 0x312f, 0xf000 },
- { 0x3130, 0x0000 },
- { 0x3131, 0xf000 },
- { 0x3132, 0x0000 },
- { 0x3133, 0xf000 },
- { 0x3134, 0x0000 },
- { 0x3135, 0xf000 },
- { 0x3136, 0x0000 },
- { 0x3137, 0xf000 },
- { 0x3138, 0x0000 },
- { 0x3139, 0xf000 },
- { 0x313a, 0x0000 },
- { 0x313b, 0xf000 },
- { 0x313c, 0x0000 },
- { 0x313d, 0xf000 },
- { 0x313e, 0x0000 },
- { 0x313f, 0xf000 },
- { 0x3140, 0x0000 },
- { 0x3141, 0xf000 },
- { 0x3142, 0x0000 },
- { 0x3143, 0xf000 },
- { 0x3144, 0x0000 },
- { 0x3145, 0xf000 },
- { 0x3146, 0x0000 },
- { 0x3147, 0xf000 },
- { 0x3148, 0x0000 },
- { 0x3149, 0xf000 },
- { 0x314a, 0x0000 },
- { 0x314b, 0xf000 },
- { 0x314c, 0x0000 },
- { 0x314d, 0xf000 },
- { 0x314e, 0x0000 },
- { 0x314f, 0xf000 },
- { 0x3150, 0x0000 },
- { 0x3151, 0xf000 },
- { 0x3152, 0x0000 },
- { 0x3153, 0xf000 },
- { 0x3154, 0x0000 },
- { 0x3155, 0xf000 },
- { 0x3156, 0x0000 },
- { 0x3157, 0xf000 },
- { 0x3158, 0x0000 },
- { 0x3159, 0xf000 },
- { 0x315a, 0x0000 },
- { 0x315b, 0xf000 },
- { 0x315c, 0x0000 },
- { 0x315d, 0xf000 },
- { 0x315e, 0x0000 },
- { 0x315f, 0xf000 },
- { 0x3160, 0x0000 },
- { 0x3161, 0xf000 },
- { 0x3162, 0x0000 },
- { 0x3163, 0xf000 },
- { 0x3164, 0x0000 },
- { 0x3165, 0xf000 },
- { 0x3166, 0x0000 },
- { 0x3167, 0xf000 },
- { 0x3168, 0x0000 },
- { 0x3169, 0xf000 },
- { 0x316a, 0x0000 },
- { 0x316b, 0xf000 },
- { 0x316c, 0x0000 },
- { 0x316d, 0xf000 },
- { 0x316e, 0x0000 },
- { 0x316f, 0xf000 },
- { 0x3170, 0x0000 },
- { 0x3171, 0xf000 },
- { 0x3172, 0x0000 },
- { 0x3173, 0xf000 },
- { 0x3174, 0x0000 },
- { 0x3175, 0xf000 },
- { 0x3176, 0x0000 },
- { 0x3177, 0xf000 },
- { 0x3178, 0x0000 },
- { 0x3179, 0xf000 },
- { 0x317a, 0x0000 },
- { 0x317b, 0xf000 },
- { 0x317c, 0x0000 },
- { 0x317d, 0xf000 },
- { 0x317e, 0x0000 },
- { 0x317f, 0xf000 },
- { 0x3180, 0x2001 },
- { 0x3181, 0xf101 },
- { 0x3182, 0x0000 },
- { 0x3183, 0xf000 },
- { 0x3184, 0x0000 },
- { 0x3185, 0xf000 },
- { 0x3186, 0x0000 },
- { 0x3187, 0xf000 },
- { 0x3188, 0x0000 },
- { 0x3189, 0xf000 },
- { 0x318a, 0x0000 },
- { 0x318b, 0xf000 },
- { 0x318c, 0x0000 },
- { 0x318d, 0xf000 },
- { 0x318e, 0x0000 },
- { 0x318f, 0xf000 },
- { 0x3190, 0x0000 },
- { 0x3191, 0xf000 },
- { 0x3192, 0x0000 },
- { 0x3193, 0xf000 },
- { 0x3194, 0x0000 },
- { 0x3195, 0xf000 },
- { 0x3196, 0x0000 },
- { 0x3197, 0xf000 },
- { 0x3198, 0x0000 },
- { 0x3199, 0xf000 },
- { 0x319a, 0x0000 },
- { 0x319b, 0xf000 },
- { 0x319c, 0x0000 },
- { 0x319d, 0xf000 },
- { 0x319e, 0x0000 },
- { 0x319f, 0xf000 },
- { 0x31a0, 0x0000 },
- { 0x31a1, 0xf000 },
- { 0x31a2, 0x0000 },
- { 0x31a3, 0xf000 },
- { 0x31a4, 0x0000 },
- { 0x31a5, 0xf000 },
- { 0x31a6, 0x0000 },
- { 0x31a7, 0xf000 },
- { 0x31a8, 0x0000 },
- { 0x31a9, 0xf000 },
- { 0x31aa, 0x0000 },
- { 0x31ab, 0xf000 },
- { 0x31ac, 0x0000 },
- { 0x31ad, 0xf000 },
- { 0x31ae, 0x0000 },
- { 0x31af, 0xf000 },
- { 0x31b0, 0x0000 },
- { 0x31b1, 0xf000 },
- { 0x31b2, 0x0000 },
- { 0x31b3, 0xf000 },
- { 0x31b4, 0x0000 },
- { 0x31b5, 0xf000 },
- { 0x31b6, 0x0000 },
- { 0x31b7, 0xf000 },
- { 0x31b8, 0x0000 },
- { 0x31b9, 0xf000 },
- { 0x31ba, 0x0000 },
- { 0x31bb, 0xf000 },
- { 0x31bc, 0x0000 },
- { 0x31bd, 0xf000 },
- { 0x31be, 0x0000 },
- { 0x31bf, 0xf000 },
- { 0x31c0, 0x0000 },
- { 0x31c1, 0xf000 },
- { 0x31c2, 0x0000 },
- { 0x31c3, 0xf000 },
- { 0x31c4, 0x0000 },
- { 0x31c5, 0xf000 },
- { 0x31c6, 0x0000 },
- { 0x31c7, 0xf000 },
- { 0x31c8, 0x0000 },
- { 0x31c9, 0xf000 },
- { 0x31ca, 0x0000 },
- { 0x31cb, 0xf000 },
- { 0x31cc, 0x0000 },
- { 0x31cd, 0xf000 },
- { 0x31ce, 0x0000 },
- { 0x31cf, 0xf000 },
- { 0x31d0, 0x0000 },
- { 0x31d1, 0xf000 },
- { 0x31d2, 0x0000 },
- { 0x31d3, 0xf000 },
- { 0x31d4, 0x0000 },
- { 0x31d5, 0xf000 },
- { 0x31d6, 0x0000 },
- { 0x31d7, 0xf000 },
- { 0x31d8, 0x0000 },
- { 0x31d9, 0xf000 },
- { 0x31da, 0x0000 },
- { 0x31db, 0xf000 },
- { 0x31dc, 0x0000 },
- { 0x31dd, 0xf000 },
- { 0x31de, 0x0000 },
- { 0x31df, 0xf000 },
- { 0x31e0, 0x0000 },
- { 0x31e1, 0xf000 },
- { 0x31e2, 0x0000 },
- { 0x31e3, 0xf000 },
- { 0x31e4, 0x0000 },
- { 0x31e5, 0xf000 },
- { 0x31e6, 0x0000 },
- { 0x31e7, 0xf000 },
- { 0x31e8, 0x0000 },
- { 0x31e9, 0xf000 },
- { 0x31ea, 0x0000 },
- { 0x31eb, 0xf000 },
- { 0x31ec, 0x0000 },
- { 0x31ed, 0xf000 },
- { 0x31ee, 0x0000 },
- { 0x31ef, 0xf000 },
- { 0x31f0, 0x0000 },
- { 0x31f1, 0xf000 },
- { 0x31f2, 0x0000 },
- { 0x31f3, 0xf000 },
- { 0x31f4, 0x0000 },
- { 0x31f5, 0xf000 },
- { 0x31f6, 0x0000 },
- { 0x31f7, 0xf000 },
- { 0x31f8, 0x0000 },
- { 0x31f9, 0xf000 },
- { 0x31fa, 0x0000 },
- { 0x31fb, 0xf000 },
- { 0x31fc, 0x0000 },
- { 0x31fd, 0xf000 },
- { 0x31fe, 0x0000 },
- { 0x31ff, 0xf000 },
- { 0x024d, 0xff50 },
- { 0x0252, 0xff50 },
- { 0x0259, 0x0112 },
- { 0x025e, 0x0112 },
- { 0x101, 0x0304 },
{ 0x80, 0x0000 },
};
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c
index 4bceee98f0a..4e70e157a90 100644
--- a/drivers/mfd/wm831x-spi.c
+++ b/drivers/mfd/wm831x-spi.c
@@ -21,7 +21,7 @@
#include <linux/mfd/wm831x/core.h>
-static int __devinit wm831x_spi_probe(struct spi_device *spi)
+static int wm831x_spi_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
struct wm831x *wm831x;
@@ -51,7 +51,7 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi)
return wm831x_device_init(wm831x, type, spi->irq);
}
-static int __devexit wm831x_spi_remove(struct spi_device *spi)
+static int wm831x_spi_remove(struct spi_device *spi)
{
struct wm831x *wm831x = dev_get_drvdata(&spi->dev);
@@ -99,7 +99,7 @@ static struct spi_driver wm831x_spi_driver = {
},
.id_table = wm831x_spi_ids,
.probe = wm831x_spi_probe,
- .remove = __devexit_p(wm831x_spi_remove),
+ .remove = wm831x_spi_remove,
.shutdown = wm831x_spi_shutdown,
};
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index 8fefc961ec0..c7f62ac544a 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -374,21 +374,21 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
}
#endif
-static const __devinitconst struct reg_default wm8994_revc_patch[] = {
+static const struct reg_default wm8994_revc_patch[] = {
{ 0x102, 0x3 },
{ 0x56, 0x3 },
{ 0x817, 0x0 },
{ 0x102, 0x0 },
};
-static const __devinitconst struct reg_default wm8958_reva_patch[] = {
+static const struct reg_default wm8958_reva_patch[] = {
{ 0x102, 0x3 },
{ 0xcb, 0x81 },
{ 0x817, 0x0 },
{ 0x102, 0x0 },
};
-static const __devinitconst struct reg_default wm1811_reva_patch[] = {
+static const struct reg_default wm1811_reva_patch[] = {
{ 0x102, 0x3 },
{ 0x56, 0xc07 },
{ 0x5d, 0x7e },
@@ -399,7 +399,7 @@ static const __devinitconst struct reg_default wm1811_reva_patch[] = {
/*
* Instantiate the generic non-control parts of the device.
*/
-static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)
+static int wm8994_device_init(struct wm8994 *wm8994, int irq)
{
struct wm8994_pdata *pdata = wm8994->dev->platform_data;
struct regmap_config *regmap_config;
@@ -671,7 +671,7 @@ err:
return ret;
}
-static __devexit void wm8994_device_exit(struct wm8994 *wm8994)
+static void wm8994_device_exit(struct wm8994 *wm8994)
{
pm_runtime_disable(wm8994->dev);
mfd_remove_devices(wm8994->dev);
@@ -689,7 +689,7 @@ static const struct of_device_id wm8994_of_match[] = {
};
MODULE_DEVICE_TABLE(of, wm8994_of_match);
-static __devinit int wm8994_i2c_probe(struct i2c_client *i2c,
+static int wm8994_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8994 *wm8994;
@@ -715,7 +715,7 @@ static __devinit int wm8994_i2c_probe(struct i2c_client *i2c,
return wm8994_device_init(wm8994, i2c->irq);
}
-static __devexit int wm8994_i2c_remove(struct i2c_client *i2c)
+static int wm8994_i2c_remove(struct i2c_client *i2c)
{
struct wm8994 *wm8994 = i2c_get_clientdata(i2c);
@@ -744,7 +744,7 @@ static struct i2c_driver wm8994_i2c_driver = {
.of_match_table = wm8994_of_match,
},
.probe = wm8994_i2c_probe,
- .remove = __devexit_p(wm8994_i2c_remove),
+ .remove = wm8994_i2c_remove,
.id_table = wm8994_i2c_id,
};
diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c
index 820826270b6..705b881e186 100644
--- a/drivers/misc/ad525x_dpot-i2c.c
+++ b/drivers/misc/ad525x_dpot-i2c.c
@@ -51,7 +51,7 @@ static const struct ad_dpot_bus_ops bops = {
.write_r8d16 = write_r8d16,
};
-static int __devinit ad_dpot_i2c_probe(struct i2c_client *client,
+static int ad_dpot_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ad_dpot_bus_data bdata = {
@@ -68,7 +68,7 @@ static int __devinit ad_dpot_i2c_probe(struct i2c_client *client,
return ad_dpot_probe(&client->dev, &bdata, id->driver_data, id->name);
}
-static int __devexit ad_dpot_i2c_remove(struct i2c_client *client)
+static int ad_dpot_i2c_remove(struct i2c_client *client)
{
return ad_dpot_remove(&client->dev);
}
@@ -109,7 +109,7 @@ static struct i2c_driver ad_dpot_i2c_driver = {
.owner = THIS_MODULE,
},
.probe = ad_dpot_i2c_probe,
- .remove = __devexit_p(ad_dpot_i2c_remove),
+ .remove = ad_dpot_i2c_remove,
.id_table = ad_dpot_id,
};
diff --git a/drivers/misc/ad525x_dpot-spi.c b/drivers/misc/ad525x_dpot-spi.c
index f62317540d0..9da04ede04f 100644
--- a/drivers/misc/ad525x_dpot-spi.c
+++ b/drivers/misc/ad525x_dpot-spi.c
@@ -75,7 +75,7 @@ static const struct ad_dpot_bus_ops bops = {
.write_r8d8 = write16,
.write_r8d16 = write24,
};
-static int __devinit ad_dpot_spi_probe(struct spi_device *spi)
+static int ad_dpot_spi_probe(struct spi_device *spi)
{
struct ad_dpot_bus_data bdata = {
.client = spi,
@@ -87,7 +87,7 @@ static int __devinit ad_dpot_spi_probe(struct spi_device *spi)
spi_get_device_id(spi)->name);
}
-static int __devexit ad_dpot_spi_remove(struct spi_device *spi)
+static int ad_dpot_spi_remove(struct spi_device *spi)
{
return ad_dpot_remove(&spi->dev);
}
@@ -131,7 +131,7 @@ static struct spi_driver ad_dpot_spi_driver = {
.owner = THIS_MODULE,
},
.probe = ad_dpot_spi_probe,
- .remove = __devexit_p(ad_dpot_spi_remove),
+ .remove = ad_dpot_spi_remove,
.id_table = ad_dpot_spi_id,
};
diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c
index 6938f1be664..8f99e8e3f0a 100644
--- a/drivers/misc/ad525x_dpot.c
+++ b/drivers/misc/ad525x_dpot.c
@@ -641,7 +641,7 @@ static const struct attribute_group ad525x_group_commands = {
.attrs = ad525x_attributes_commands,
};
-__devinit int ad_dpot_add_files(struct device *dev,
+int ad_dpot_add_files(struct device *dev,
unsigned features, unsigned rdac)
{
int err = sysfs_create_file(&dev->kobj,
@@ -685,7 +685,7 @@ inline void ad_dpot_remove_files(struct device *dev,
}
}
-int __devinit ad_dpot_probe(struct device *dev,
+int ad_dpot_probe(struct device *dev,
struct ad_dpot_bus_data *bdata, unsigned long devid,
const char *name)
{
diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c
index 0314773f6db..d648b089302 100644
--- a/drivers/misc/apds9802als.c
+++ b/drivers/misc/apds9802als.c
@@ -68,7 +68,7 @@ static int als_wait_for_data_ready(struct device *dev)
ret = i2c_smbus_read_byte_data(client, 0x86);
} while (!(ret & 0x80) && retry--);
- if (!retry) {
+ if (retry < 0) {
dev_warn(dev, "timeout waiting for data ready\n");
return -ETIMEDOUT;
}
@@ -254,7 +254,7 @@ als_error1:
return res;
}
-static int __devexit apds9802als_remove(struct i2c_client *client)
+static int apds9802als_remove(struct i2c_client *client)
{
struct als_data *data = i2c_get_clientdata(client);
@@ -326,7 +326,7 @@ static struct i2c_driver apds9802als_driver = {
.pm = APDS9802ALS_PM_OPS,
},
.probe = apds9802als_probe,
- .remove = __devexit_p(apds9802als_remove),
+ .remove = apds9802als_remove,
.suspend = apds9802als_suspend,
.resume = apds9802als_resume,
.id_table = apds9802als_id,
diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c
index ee74244aa03..0e67f8263cd 100644
--- a/drivers/misc/apds990x.c
+++ b/drivers/misc/apds990x.c
@@ -1047,7 +1047,7 @@ static struct attribute_group apds990x_attribute_group[] = {
{.attrs = sysfs_attrs_ctrl },
};
-static int __devinit apds990x_probe(struct i2c_client *client,
+static int apds990x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct apds990x_chip *chip;
@@ -1181,7 +1181,7 @@ fail1:
return err;
}
-static int __devexit apds990x_remove(struct i2c_client *client)
+static int apds990x_remove(struct i2c_client *client)
{
struct apds990x_chip *chip = i2c_get_clientdata(client);
@@ -1275,7 +1275,7 @@ static struct i2c_driver apds990x_driver = {
.pm = &apds990x_pm_ops,
},
.probe = apds990x_probe,
- .remove = __devexit_p(apds990x_remove),
+ .remove = apds990x_remove,
.id_table = apds990x_id,
};
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
index 5bb18778107..c58f9abcb35 100644
--- a/drivers/misc/atmel-ssc.c
+++ b/drivers/misc/atmel-ssc.c
@@ -137,7 +137,7 @@ out:
return retval;
}
-static int __devexit ssc_remove(struct platform_device *pdev)
+static int ssc_remove(struct platform_device *pdev)
{
struct ssc_device *ssc = platform_get_drvdata(pdev);
@@ -152,7 +152,7 @@ static int __devexit ssc_remove(struct platform_device *pdev)
}
static struct platform_driver ssc_driver = {
- .remove = __devexit_p(ssc_remove),
+ .remove = ssc_remove,
.driver = {
.name = "ssc",
.owner = THIS_MODULE,
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index 3d56ae7ef8d..2ed8fc3be7e 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -1162,7 +1162,7 @@ static struct attribute_group bh1770_attribute_group = {
.attrs = sysfs_attrs
};
-static int __devinit bh1770_probe(struct i2c_client *client,
+static int bh1770_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct bh1770_chip *chip;
@@ -1285,7 +1285,7 @@ fail1:
return err;
}
-static int __devexit bh1770_remove(struct i2c_client *client)
+static int bh1770_remove(struct i2c_client *client)
{
struct bh1770_chip *chip = i2c_get_clientdata(client);
@@ -1395,7 +1395,7 @@ static struct i2c_driver bh1770_driver = {
.pm = &bh1770_pm_ops,
},
.probe = bh1770_probe,
- .remove = __devexit_p(bh1770_remove),
+ .remove = bh1770_remove,
.id_table = bh1770_id,
};
diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c
index f1f9877f3fd..cf03d0abf33 100644
--- a/drivers/misc/bh1780gli.c
+++ b/drivers/misc/bh1780gli.c
@@ -144,7 +144,7 @@ static const struct attribute_group bh1780_attr_group = {
.attrs = bh1780_attributes,
};
-static int __devinit bh1780_probe(struct i2c_client *client,
+static int bh1780_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret;
@@ -185,7 +185,7 @@ err_op_failed:
return ret;
}
-static int __devexit bh1780_remove(struct i2c_client *client)
+static int bh1780_remove(struct i2c_client *client)
{
struct bh1780_data *ddata;
@@ -248,7 +248,7 @@ static const struct i2c_device_id bh1780_id[] = {
static struct i2c_driver bh1780_driver = {
.probe = bh1780_probe,
- .remove = __devexit_p(bh1780_remove),
+ .remove = bh1780_remove,
.id_table = bh1780_id,
.driver = {
.name = "bh1780",
diff --git a/drivers/misc/bmp085-i2c.c b/drivers/misc/bmp085-i2c.c
index a4f33c995ea..3abfcecf842 100644
--- a/drivers/misc/bmp085-i2c.c
+++ b/drivers/misc/bmp085-i2c.c
@@ -36,7 +36,7 @@ static int bmp085_i2c_detect(struct i2c_client *client,
return bmp085_detect(&client->dev);
}
-static int __devinit bmp085_i2c_probe(struct i2c_client *client,
+static int bmp085_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int err;
@@ -71,7 +71,7 @@ static struct i2c_driver bmp085_i2c_driver = {
},
.id_table = bmp085_id,
.probe = bmp085_i2c_probe,
- .remove = __devexit_p(bmp085_i2c_remove),
+ .remove = bmp085_i2c_remove,
.detect = bmp085_i2c_detect,
.address_list = normal_i2c
diff --git a/drivers/misc/bmp085-spi.c b/drivers/misc/bmp085-spi.c
index 5e982af9973..d6a52659cf2 100644
--- a/drivers/misc/bmp085-spi.c
+++ b/drivers/misc/bmp085-spi.c
@@ -22,7 +22,7 @@
#include <linux/err.h>
#include "bmp085.h"
-static int __devinit bmp085_spi_probe(struct spi_device *client)
+static int bmp085_spi_probe(struct spi_device *client)
{
int err;
struct regmap *regmap;
@@ -70,7 +70,7 @@ static struct spi_driver bmp085_spi_driver = {
},
.id_table = bmp085_id,
.probe = bmp085_spi_probe,
- .remove = __devexit_p(bmp085_spi_remove)
+ .remove = bmp085_spi_remove
};
module_spi_driver(bmp085_spi_driver);
diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c
index 62e418293b7..849e2fed4da 100644
--- a/drivers/misc/bmp085.c
+++ b/drivers/misc/bmp085.c
@@ -420,7 +420,7 @@ struct regmap_config bmp085_regmap_config = {
};
EXPORT_SYMBOL_GPL(bmp085_regmap_config);
-__devinit int bmp085_probe(struct device *dev, struct regmap *regmap)
+int bmp085_probe(struct device *dev, struct regmap *regmap)
{
struct bmp085_data *data;
int err = 0;
diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c
index 9d5eed75466..2e50f811ff5 100644
--- a/drivers/misc/cb710/core.c
+++ b/drivers/misc/cb710/core.c
@@ -30,7 +30,7 @@ void cb710_pci_update_config_reg(struct pci_dev *pdev,
EXPORT_SYMBOL_GPL(cb710_pci_update_config_reg);
/* Some magic writes based on Windows driver init code */
-static int __devinit cb710_pci_configure(struct pci_dev *pdev)
+static int cb710_pci_configure(struct pci_dev *pdev)
{
unsigned int devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0);
struct pci_dev *pdev0;
@@ -96,7 +96,7 @@ static void cb710_release_slot(struct device *dev)
#endif
}
-static int __devinit cb710_register_slot(struct cb710_chip *chip,
+static int cb710_register_slot(struct cb710_chip *chip,
unsigned slot_mask, unsigned io_offset, const char *name)
{
int nr = chip->slots;
@@ -201,7 +201,7 @@ static int cb710_resume(struct pci_dev *pdev)
#endif /* CONFIG_PM */
-static int __devinit cb710_probe(struct pci_dev *pdev,
+static int cb710_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct cb710_chip *chip;
@@ -305,7 +305,7 @@ unreg_mmc:
return err;
}
-static void __devexit cb710_remove_one(struct pci_dev *pdev)
+static void cb710_remove_one(struct pci_dev *pdev)
{
struct cb710_chip *chip = pci_get_drvdata(pdev);
unsigned long flags;
@@ -332,7 +332,7 @@ static struct pci_driver cb710_driver = {
.name = KBUILD_MODNAME,
.id_table = cb710_pci_tbl,
.probe = cb710_probe,
- .remove = __devexit_p(cb710_remove_one),
+ .remove = cb710_remove_one,
#ifdef CONFIG_PM
.suspend = cb710_suspend,
.resume = cb710_resume,
diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c
index f505a40a8f4..9858f36dad8 100644
--- a/drivers/misc/cs5535-mfgpt.c
+++ b/drivers/misc/cs5535-mfgpt.c
@@ -246,7 +246,7 @@ EXPORT_SYMBOL_GPL(cs5535_mfgpt_write);
* Jordan tells me that he and Mitch once played w/ it, but it's unclear
* what the results of that were (and they experienced some instability).
*/
-static void __devinit reset_all_timers(void)
+static void reset_all_timers(void)
{
uint32_t val, dummy;
@@ -262,7 +262,7 @@ static void __devinit reset_all_timers(void)
* In other cases (such as with VSAless OpenFirmware), the system firmware
* leaves timers available for us to use.
*/
-static int __devinit scan_timers(struct cs5535_mfgpt_chip *mfgpt)
+static int scan_timers(struct cs5535_mfgpt_chip *mfgpt)
{
struct cs5535_mfgpt_timer timer = { .chip = mfgpt };
unsigned long flags;
@@ -289,7 +289,7 @@ static int __devinit scan_timers(struct cs5535_mfgpt_chip *mfgpt)
return timers;
}
-static int __devinit cs5535_mfgpt_probe(struct platform_device *pdev)
+static int cs5535_mfgpt_probe(struct platform_device *pdev)
{
struct resource *res;
int err = -EIO, t;
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index ab1ad41786d..2baeec56edf 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -656,7 +656,7 @@ err_out:
return err;
}
-static int __devexit at24_remove(struct i2c_client *client)
+static int at24_remove(struct i2c_client *client)
{
struct at24_data *at24;
int i;
@@ -680,7 +680,7 @@ static struct i2c_driver at24_driver = {
.owner = THIS_MODULE,
},
.probe = at24_probe,
- .remove = __devexit_p(at24_remove),
+ .remove = at24_remove,
.id_table = at24_ids,
};
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index 4ed93dd5411..b08cf8a0878 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -459,7 +459,7 @@ fail:
return err;
}
-static int __devexit at25_remove(struct spi_device *spi)
+static int at25_remove(struct spi_device *spi)
{
struct at25_data *at25;
@@ -477,7 +477,7 @@ static struct spi_driver at25_driver = {
.owner = THIS_MODULE,
},
.probe = at25_probe,
- .remove = __devexit_p(at25_remove),
+ .remove = at25_remove,
};
module_spi_driver(at25_driver);
diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c
index ce3fe3633dd..a6b5d5e7348 100644
--- a/drivers/misc/eeprom/eeprom_93xx46.c
+++ b/drivers/misc/eeprom/eeprom_93xx46.c
@@ -309,7 +309,7 @@ static ssize_t eeprom_93xx46_store_erase(struct device *dev,
}
static DEVICE_ATTR(erase, S_IWUSR, NULL, eeprom_93xx46_store_erase);
-static int __devinit eeprom_93xx46_probe(struct spi_device *spi)
+static int eeprom_93xx46_probe(struct spi_device *spi)
{
struct eeprom_93xx46_platform_data *pd;
struct eeprom_93xx46_dev *edev;
@@ -370,7 +370,7 @@ fail:
return err;
}
-static int __devexit eeprom_93xx46_remove(struct spi_device *spi)
+static int eeprom_93xx46_remove(struct spi_device *spi)
{
struct eeprom_93xx46_dev *edev = dev_get_drvdata(&spi->dev);
@@ -389,7 +389,7 @@ static struct spi_driver eeprom_93xx46_driver = {
.owner = THIS_MODULE,
},
.probe = eeprom_93xx46_probe,
- .remove = __devexit_p(eeprom_93xx46_remove),
+ .remove = eeprom_93xx46_remove,
};
module_spi_driver(eeprom_93xx46_driver);
diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c
index ac96c3a4034..e8cbb1c59f4 100644
--- a/drivers/misc/fsa9480.c
+++ b/drivers/misc/fsa9480.c
@@ -407,7 +407,7 @@ static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw)
return 0;
}
-static int __devinit fsa9480_probe(struct i2c_client *client,
+static int fsa9480_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
@@ -462,7 +462,7 @@ fail1:
return ret;
}
-static int __devexit fsa9480_remove(struct i2c_client *client)
+static int fsa9480_remove(struct i2c_client *client)
{
struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client);
if (client->irq)
@@ -533,7 +533,7 @@ static struct i2c_driver fsa9480_i2c_driver = {
.name = "fsa9480",
},
.probe = fsa9480_probe,
- .remove = __devexit_p(fsa9480_remove),
+ .remove = fsa9480_remove,
.resume = fsa9480_resume,
.suspend = fsa9480_suspend,
.id_table = fsa9480_id,
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
index 12ccdf94e4f..621c7a37339 100644
--- a/drivers/misc/hpilo.c
+++ b/drivers/misc/hpilo.c
@@ -30,7 +30,7 @@
static struct class *ilo_class;
static unsigned int ilo_major;
-static unsigned int max_ccb = MIN_CCB;
+static unsigned int max_ccb = 16;
static char ilo_hwdev[MAX_ILO_DEV];
static inline int get_entry_id(int entry)
@@ -686,7 +686,7 @@ static void ilo_unmap_device(struct pci_dev *pdev, struct ilo_hwinfo *hw)
pci_iounmap(pdev, hw->mmio_vaddr);
}
-static int __devinit ilo_map_device(struct pci_dev *pdev, struct ilo_hwinfo *hw)
+static int ilo_map_device(struct pci_dev *pdev, struct ilo_hwinfo *hw)
{
int error = -ENOMEM;
@@ -725,6 +725,9 @@ static void ilo_remove(struct pci_dev *pdev)
int i, minor;
struct ilo_hwinfo *ilo_hw = pci_get_drvdata(pdev);
+ if (!ilo_hw)
+ return;
+
clear_device(ilo_hw);
minor = MINOR(ilo_hw->cdev.dev);
@@ -748,12 +751,16 @@ static void ilo_remove(struct pci_dev *pdev)
ilo_hwdev[(minor / max_ccb)] = 0;
}
-static int __devinit ilo_probe(struct pci_dev *pdev,
+static int ilo_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
- int devnum, minor, start, error;
+ int devnum, minor, start, error = 0;
struct ilo_hwinfo *ilo_hw;
+ /* Ignore subsystem_device = 0x1979 (set by BIOS) */
+ if (pdev->subsystem_device == 0x1979)
+ goto out;
+
if (max_ccb > MAX_CCB)
max_ccb = MAX_CCB;
else if (max_ccb < MIN_CCB)
@@ -852,7 +859,7 @@ static struct pci_driver ilo_driver = {
.name = ILO_NAME,
.id_table = ilo_devices,
.probe = ilo_probe,
- .remove = __devexit_p(ilo_remove),
+ .remove = ilo_remove,
};
static int __init ilo_init(void)
@@ -892,14 +899,14 @@ static void __exit ilo_exit(void)
class_destroy(ilo_class);
}
-MODULE_VERSION("1.3");
+MODULE_VERSION("1.4");
MODULE_ALIAS(ILO_NAME);
MODULE_DESCRIPTION(ILO_NAME);
MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>");
MODULE_LICENSE("GPL v2");
module_param(max_ccb, uint, 0444);
-MODULE_PARM_DESC(max_ccb, "Maximum number of HP iLO channels to attach (8)");
+MODULE_PARM_DESC(max_ccb, "Maximum number of HP iLO channels to attach (16)");
module_init(ilo_init);
module_exit(ilo_exit);
diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c
index 168d8008f46..0346d87c5fe 100644
--- a/drivers/misc/ibmasm/module.c
+++ b/drivers/misc/ibmasm/module.c
@@ -62,7 +62,7 @@ module_param(ibmasm_debug, int , S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(ibmasm_debug, " Set debug mode on or off");
-static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+static int ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
int result;
struct service_processor *sp;
@@ -163,7 +163,7 @@ error_resources:
return result;
}
-static void __devexit ibmasm_remove_one(struct pci_dev *pdev)
+static void ibmasm_remove_one(struct pci_dev *pdev)
{
struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev);
@@ -198,7 +198,7 @@ static struct pci_driver ibmasm_driver = {
.name = DRIVER_NAME,
.id_table = ibmasm_pci_table,
.probe = ibmasm_init_one,
- .remove = __devexit_p(ibmasm_remove_one),
+ .remove = ibmasm_remove_one,
};
static void __exit ibmasm_exit (void)
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c
index 6a7710603a9..06f6ad29cef 100644
--- a/drivers/misc/ioc4.c
+++ b/drivers/misc/ioc4.c
@@ -139,7 +139,7 @@ ioc4_unregister_submodule(struct ioc4_submodule *is)
* even though the following code utilizes external interrupt registers
* to perform the speed calculation.
*/
-static void __devinit
+static void
ioc4_clock_calibrate(struct ioc4_driver_data *idd)
{
union ioc4_int_out int_out;
@@ -231,7 +231,7 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
* on the same PCI bus at slot number 3 to differentiate IO9 from IO10.
* If neither is present, it's a PCI-RT.
*/
-static unsigned int __devinit
+static unsigned int
ioc4_variant(struct ioc4_driver_data *idd)
{
struct pci_dev *pdev = NULL;
@@ -279,7 +279,7 @@ ioc4_load_modules(struct work_struct *work)
static DECLARE_WORK(ioc4_load_modules_work, ioc4_load_modules);
/* Adds a new instance of an IOC4 card */
-static int __devinit
+static int
ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
{
struct ioc4_driver_data *idd;
@@ -415,7 +415,7 @@ out:
}
/* Removes a particular instance of an IOC4 card. */
-static void __devexit
+static void
ioc4_remove(struct pci_dev *pdev)
{
struct ioc4_submodule *is;
@@ -466,7 +466,7 @@ static struct pci_driver ioc4_driver = {
.name = "IOC4",
.id_table = ioc4_id_table,
.probe = ioc4_probe,
- .remove = __devexit_p(ioc4_remove),
+ .remove = ioc4_remove,
};
MODULE_DEVICE_TABLE(pci, ioc4_id_table);
diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c
index eb5de2e210d..29b306c6bdb 100644
--- a/drivers/misc/isl29003.c
+++ b/drivers/misc/isl29003.c
@@ -365,7 +365,7 @@ static int isl29003_init_client(struct i2c_client *client)
* I2C layer
*/
-static int __devinit isl29003_probe(struct i2c_client *client,
+static int isl29003_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
@@ -401,7 +401,7 @@ exit_kfree:
return err;
}
-static int __devexit isl29003_remove(struct i2c_client *client)
+static int isl29003_remove(struct i2c_client *client)
{
sysfs_remove_group(&client->dev.kobj, &isl29003_attr_group);
isl29003_set_power_state(client, 0);
@@ -451,7 +451,7 @@ static struct i2c_driver isl29003_driver = {
.suspend = isl29003_suspend,
.resume = isl29003_resume,
.probe = isl29003_probe,
- .remove = __devexit_p(isl29003_remove),
+ .remove = isl29003_remove,
.id_table = isl29003_id,
};
diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c
index 60ec8689d6e..7c97550240f 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c
@@ -114,7 +114,7 @@ static struct of_device_id lis3lv02d_i2c_dt_ids[] = {
MODULE_DEVICE_TABLE(of, lis3lv02d_i2c_dt_ids);
#endif
-static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
+static int lis3lv02d_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret = 0;
@@ -191,7 +191,7 @@ fail:
return ret;
}
-static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
+static int lis3lv02d_i2c_remove(struct i2c_client *client)
{
struct lis3lv02d *lis3 = i2c_get_clientdata(client);
struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
@@ -280,7 +280,7 @@ static struct i2c_driver lis3lv02d_i2c_driver = {
.of_match_table = of_match_ptr(lis3lv02d_i2c_dt_ids),
},
.probe = lis3lv02d_i2c_probe,
- .remove = __devexit_p(lis3lv02d_i2c_remove),
+ .remove = lis3lv02d_i2c_remove,
.id_table = lis3lv02d_id,
};
diff --git a/drivers/misc/lis3lv02d/lis3lv02d_spi.c b/drivers/misc/lis3lv02d/lis3lv02d_spi.c
index ccb6475fa05..9aa2bd2a71a 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d_spi.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d_spi.c
@@ -69,7 +69,7 @@ static struct of_device_id lis302dl_spi_dt_ids[] = {
MODULE_DEVICE_TABLE(of, lis302dl_spi_dt_ids);
#endif
-static int __devinit lis302dl_spi_probe(struct spi_device *spi)
+static int lis302dl_spi_probe(struct spi_device *spi)
{
int ret;
@@ -100,7 +100,7 @@ static int __devinit lis302dl_spi_probe(struct spi_device *spi)
return lis3lv02d_init_device(&lis3_dev);
}
-static int __devexit lis302dl_spi_remove(struct spi_device *spi)
+static int lis302dl_spi_remove(struct spi_device *spi)
{
struct lis3lv02d *lis3 = spi_get_drvdata(spi);
lis3lv02d_joystick_disable(lis3);
@@ -144,7 +144,7 @@ static struct spi_driver lis302dl_spi_driver = {
.of_match_table = of_match_ptr(lis302dl_spi_dt_ids),
},
.probe = lis302dl_spi_probe,
- .remove = __devexit_p(lis302dl_spi_remove),
+ .remove = lis302dl_spi_remove,
};
module_spi_driver(lis302dl_spi_driver);
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index 57168db6c7e..0017842e166 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -8,4 +8,5 @@ mei-objs += interrupt.o
mei-objs += interface.o
mei-objs += iorw.o
mei-objs += main.o
+mei-objs += amthif.o
mei-objs += wd.o
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
new file mode 100644
index 00000000000..18794aea606
--- /dev/null
+++ b/drivers/misc/mei/amthif.c
@@ -0,0 +1,722 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2012, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/aio.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/uuid.h>
+#include <linux/jiffies.h>
+#include <linux/uaccess.h>
+
+
+#include "mei_dev.h"
+#include "hw.h"
+#include <linux/mei.h>
+#include "interface.h"
+
+const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac,
+ 0xa8, 0x46, 0xe0, 0xff, 0x65,
+ 0x81, 0x4c);
+
+/**
+ * mei_amthif_reset_params - initializes mei device iamthif
+ *
+ * @dev: the device structure
+ */
+void mei_amthif_reset_params(struct mei_device *dev)
+{
+ /* reset iamthif parameters. */
+ dev->iamthif_current_cb = NULL;
+ dev->iamthif_msg_buf_size = 0;
+ dev->iamthif_msg_buf_index = 0;
+ dev->iamthif_canceled = false;
+ dev->iamthif_ioctl = false;
+ dev->iamthif_state = MEI_IAMTHIF_IDLE;
+ dev->iamthif_timer = 0;
+}
+
+/**
+ * mei_amthif_host_init_ - mei initialization amthif client.
+ *
+ * @dev: the device structure
+ *
+ */
+void mei_amthif_host_init(struct mei_device *dev)
+{
+ int i;
+ unsigned char *msg_buf;
+
+ mei_cl_init(&dev->iamthif_cl, dev);
+ dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
+
+ /* find ME amthi client */
+ i = mei_me_cl_link(dev, &dev->iamthif_cl,
+ &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID);
+ if (i < 0) {
+ dev_info(&dev->pdev->dev, "failed to find iamthif client.\n");
+ return;
+ }
+
+ /* Assign iamthif_mtu to the value received from ME */
+
+ dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length;
+ dev_dbg(&dev->pdev->dev, "IAMTHIF_MTU = %d\n",
+ dev->me_clients[i].props.max_msg_length);
+
+ kfree(dev->iamthif_msg_buf);
+ dev->iamthif_msg_buf = NULL;
+
+ /* allocate storage for ME message buffer */
+ msg_buf = kcalloc(dev->iamthif_mtu,
+ sizeof(unsigned char), GFP_KERNEL);
+ if (!msg_buf) {
+ dev_dbg(&dev->pdev->dev, "memory allocation for ME message buffer failed.\n");
+ return;
+ }
+
+ dev->iamthif_msg_buf = msg_buf;
+
+ if (mei_connect(dev, &dev->iamthif_cl)) {
+ dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n");
+ dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
+ dev->iamthif_cl.host_client_id = 0;
+ } else {
+ dev->iamthif_cl.timer_count = MEI_CONNECT_TIMEOUT;
+ }
+}
+
+/**
+ * mei_amthif_find_read_list_entry - finds a amthilist entry for current file
+ *
+ * @dev: the device structure
+ * @file: pointer to file object
+ *
+ * returns returned a list entry on success, NULL on failure.
+ */
+struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev,
+ struct file *file)
+{
+ struct mei_cl_cb *pos = NULL;
+ struct mei_cl_cb *next = NULL;
+
+ list_for_each_entry_safe(pos, next,
+ &dev->amthif_rd_complete_list.list, list) {
+ if (pos->cl && pos->cl == &dev->iamthif_cl &&
+ pos->file_object == file)
+ return pos;
+ }
+ return NULL;
+}
+
+
+/**
+ * mei_amthif_read - read data from AMTHIF client
+ *
+ * @dev: the device structure
+ * @if_num: minor number
+ * @file: pointer to file object
+ * @*ubuf: pointer to user data in user space
+ * @length: data length to read
+ * @offset: data read offset
+ *
+ * Locking: called under "dev->device_lock" lock
+ *
+ * returns
+ * returned data length on success,
+ * zero if no data to read,
+ * negative on failure.
+ */
+int mei_amthif_read(struct mei_device *dev, struct file *file,
+ char __user *ubuf, size_t length, loff_t *offset)
+{
+ int rets;
+ int wait_ret;
+ struct mei_cl_cb *cb = NULL;
+ struct mei_cl *cl = file->private_data;
+ unsigned long timeout;
+ int i;
+
+ /* Only Posible if we are in timeout */
+ if (!cl || cl != &dev->iamthif_cl) {
+ dev_dbg(&dev->pdev->dev, "bad file ext.\n");
+ return -ETIMEDOUT;
+ }
+
+ i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id);
+
+ if (i < 0) {
+ dev_dbg(&dev->pdev->dev, "amthi client not found.\n");
+ return -ENODEV;
+ }
+ dev_dbg(&dev->pdev->dev, "checking amthi data\n");
+ cb = mei_amthif_find_read_list_entry(dev, file);
+
+ /* Check for if we can block or not*/
+ if (cb == NULL && file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+
+ dev_dbg(&dev->pdev->dev, "waiting for amthi data\n");
+ while (cb == NULL) {
+ /* unlock the Mutex */
+ mutex_unlock(&dev->device_lock);
+
+ wait_ret = wait_event_interruptible(dev->iamthif_cl.wait,
+ (cb = mei_amthif_find_read_list_entry(dev, file)));
+
+ if (wait_ret)
+ return -ERESTARTSYS;
+
+ dev_dbg(&dev->pdev->dev, "woke up from sleep\n");
+
+ /* Locking again the Mutex */
+ mutex_lock(&dev->device_lock);
+ }
+
+
+ dev_dbg(&dev->pdev->dev, "Got amthi data\n");
+ dev->iamthif_timer = 0;
+
+ if (cb) {
+ timeout = cb->read_time +
+ mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);
+ dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n",
+ timeout);
+
+ if (time_after(jiffies, timeout)) {
+ dev_dbg(&dev->pdev->dev, "amthi Time out\n");
+ /* 15 sec for the message has expired */
+ list_del(&cb->list);
+ rets = -ETIMEDOUT;
+ goto free;
+ }
+ }
+ /* if the whole message will fit remove it from the list */
+ if (cb->buf_idx >= *offset && length >= (cb->buf_idx - *offset))
+ list_del(&cb->list);
+ else if (cb->buf_idx > 0 && cb->buf_idx <= *offset) {
+ /* end of the message has been reached */
+ list_del(&cb->list);
+ rets = 0;
+ goto free;
+ }
+ /* else means that not full buffer will be read and do not
+ * remove message from deletion list
+ */
+
+ dev_dbg(&dev->pdev->dev, "amthi cb->response_buffer size - %d\n",
+ cb->response_buffer.size);
+ dev_dbg(&dev->pdev->dev, "amthi cb->buf_idx - %lu\n", cb->buf_idx);
+
+ /* length is being turncated to PAGE_SIZE, however,
+ * the buf_idx may point beyond */
+ length = min_t(size_t, length, (cb->buf_idx - *offset));
+
+ if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length))
+ rets = -EFAULT;
+ else {
+ rets = length;
+ if ((*offset + length) < cb->buf_idx) {
+ *offset += length;
+ goto out;
+ }
+ }
+free:
+ dev_dbg(&dev->pdev->dev, "free amthi cb memory.\n");
+ *offset = 0;
+ mei_io_cb_free(cb);
+out:
+ return rets;
+}
+
+/**
+ * mei_amthif_send_cmd - send amthif command to the ME
+ *
+ * @dev: the device structure
+ * @cb: mei call back struct
+ *
+ * returns 0 on success, <0 on failure.
+ *
+ */
+static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
+{
+ struct mei_msg_hdr mei_hdr;
+ int ret;
+
+ if (!dev || !cb)
+ return -ENODEV;
+
+ dev_dbg(&dev->pdev->dev, "write data to amthi client.\n");
+
+ dev->iamthif_state = MEI_IAMTHIF_WRITING;
+ dev->iamthif_current_cb = cb;
+ dev->iamthif_file_object = cb->file_object;
+ dev->iamthif_canceled = false;
+ dev->iamthif_ioctl = true;
+ dev->iamthif_msg_buf_size = cb->request_buffer.size;
+ memcpy(dev->iamthif_msg_buf, cb->request_buffer.data,
+ cb->request_buffer.size);
+
+ ret = mei_flow_ctrl_creds(dev, &dev->iamthif_cl);
+ if (ret < 0)
+ return ret;
+
+ if (ret && dev->mei_host_buffer_is_empty) {
+ ret = 0;
+ dev->mei_host_buffer_is_empty = false;
+ if (cb->request_buffer.size > mei_hbuf_max_data(dev)) {
+ mei_hdr.length = mei_hbuf_max_data(dev);
+ mei_hdr.msg_complete = 0;
+ } else {
+ mei_hdr.length = cb->request_buffer.size;
+ mei_hdr.msg_complete = 1;
+ }
+
+ mei_hdr.host_addr = dev->iamthif_cl.host_client_id;
+ 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),
+ mei_hdr.length))
+ return -ENODEV;
+
+ if (mei_hdr.msg_complete) {
+ if (mei_flow_ctrl_reduce(dev, &dev->iamthif_cl))
+ return -ENODEV;
+ dev->iamthif_flow_control_pending = true;
+ dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
+ dev_dbg(&dev->pdev->dev, "add amthi cb to write waiting list\n");
+ dev->iamthif_current_cb = cb;
+ dev->iamthif_file_object = cb->file_object;
+ list_add_tail(&cb->list, &dev->write_waiting_list.list);
+ } else {
+ dev_dbg(&dev->pdev->dev, "message does not complete, so add amthi cb to write list.\n");
+ list_add_tail(&cb->list, &dev->write_list.list);
+ }
+ } else {
+ if (!(dev->mei_host_buffer_is_empty))
+ dev_dbg(&dev->pdev->dev, "host buffer is not empty");
+
+ dev_dbg(&dev->pdev->dev, "No flow control credentials, so add iamthif cb to write list.\n");
+ list_add_tail(&cb->list, &dev->write_list.list);
+ }
+ return 0;
+}
+
+/**
+ * mei_amthif_write - write amthif data to amthif client
+ *
+ * @dev: the device structure
+ * @cb: mei call back struct
+ *
+ * returns 0 on success, <0 on failure.
+ *
+ */
+int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb)
+{
+ int ret;
+
+ if (!dev || !cb)
+ return -ENODEV;
+
+ ret = mei_io_cb_alloc_resp_buf(cb, dev->iamthif_mtu);
+ if (ret)
+ return ret;
+
+ cb->fop_type = MEI_FOP_IOCTL;
+
+ if (!list_empty(&dev->amthif_cmd_list.list) ||
+ dev->iamthif_state != MEI_IAMTHIF_IDLE) {
+ dev_dbg(&dev->pdev->dev,
+ "amthif state = %d\n", dev->iamthif_state);
+ dev_dbg(&dev->pdev->dev, "AMTHIF: add cb to the wait list\n");
+ list_add_tail(&cb->list, &dev->amthif_cmd_list.list);
+ return 0;
+ }
+ return mei_amthif_send_cmd(dev, cb);
+}
+/**
+ * mei_amthif_run_next_cmd
+ *
+ * @dev: the device structure
+ *
+ * returns 0 on success, <0 on failure.
+ */
+void mei_amthif_run_next_cmd(struct mei_device *dev)
+{
+ struct mei_cl_cb *pos = NULL;
+ struct mei_cl_cb *next = NULL;
+ int status;
+
+ if (!dev)
+ return;
+
+ dev->iamthif_msg_buf_size = 0;
+ dev->iamthif_msg_buf_index = 0;
+ dev->iamthif_canceled = false;
+ dev->iamthif_ioctl = true;
+ dev->iamthif_state = MEI_IAMTHIF_IDLE;
+ dev->iamthif_timer = 0;
+ dev->iamthif_file_object = NULL;
+
+ dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n");
+
+ list_for_each_entry_safe(pos, next, &dev->amthif_cmd_list.list, list) {
+ list_del(&pos->list);
+
+ if (pos->cl && pos->cl == &dev->iamthif_cl) {
+ status = mei_amthif_send_cmd(dev, pos);
+ if (status) {
+ dev_dbg(&dev->pdev->dev,
+ "amthi write failed status = %d\n",
+ status);
+ return;
+ }
+ break;
+ }
+ }
+}
+
+
+unsigned int mei_amthif_poll(struct mei_device *dev,
+ struct file *file, poll_table *wait)
+{
+ unsigned int mask = 0;
+ mutex_unlock(&dev->device_lock);
+ poll_wait(file, &dev->iamthif_cl.wait, wait);
+ mutex_lock(&dev->device_lock);
+ if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE &&
+ dev->iamthif_file_object == file) {
+ mask |= (POLLIN | POLLRDNORM);
+ dev_dbg(&dev->pdev->dev, "run next amthi cb\n");
+ mei_amthif_run_next_cmd(dev);
+ }
+ return mask;
+}
+
+
+
+/**
+ * mei_amthif_irq_process_completed - processes completed iamthif operation.
+ *
+ * @dev: the device structure.
+ * @slots: free slots.
+ * @cb_pos: callback block.
+ * @cl: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
+ struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list)
+{
+ struct mei_msg_hdr *mei_hdr;
+ struct mei_cl *cl = cb->cl;
+ size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index;
+ size_t msg_slots = mei_data2slots(len);
+
+ mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0];
+ mei_hdr->host_addr = cl->host_client_id;
+ mei_hdr->me_addr = cl->me_client_id;
+ mei_hdr->reserved = 0;
+
+ if (*slots >= msg_slots) {
+ mei_hdr->length = len;
+ mei_hdr->msg_complete = 1;
+ /* Split the message only if we can write the whole host buffer */
+ } else if (*slots == dev->hbuf_depth) {
+ msg_slots = *slots;
+ len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
+ mei_hdr->length = len;
+ mei_hdr->msg_complete = 0;
+ } else {
+ /* wait for next time the host buffer is empty */
+ return 0;
+ }
+
+ dev_dbg(&dev->pdev->dev, "msg: len = %d complete = %d\n",
+ mei_hdr->length, mei_hdr->msg_complete);
+
+ *slots -= msg_slots;
+ if (mei_write_message(dev, mei_hdr,
+ dev->iamthif_msg_buf + dev->iamthif_msg_buf_index,
+ mei_hdr->length)) {
+ dev->iamthif_state = MEI_IAMTHIF_IDLE;
+ cl->status = -ENODEV;
+ list_del(&cb->list);
+ return -ENODEV;
+ }
+
+ if (mei_flow_ctrl_reduce(dev, cl))
+ return -ENODEV;
+
+ dev->iamthif_msg_buf_index += mei_hdr->length;
+ cl->status = 0;
+
+ if (mei_hdr->msg_complete) {
+ dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
+ dev->iamthif_flow_control_pending = true;
+
+ /* save iamthif cb sent to amthi client */
+ cb->buf_idx = dev->iamthif_msg_buf_index;
+ dev->iamthif_current_cb = cb;
+
+ list_move_tail(&cb->list, &dev->write_waiting_list.list);
+ }
+
+
+ return 0;
+}
+
+/**
+ * mei_amthif_irq_read_message - read routine after ISR to
+ * handle the read amthi message
+ *
+ * @complete_list: An instance of our list structure
+ * @dev: the device structure
+ * @mei_hdr: header of amthi message
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list,
+ struct mei_device *dev, struct mei_msg_hdr *mei_hdr)
+{
+ struct mei_cl_cb *cb;
+ unsigned char *buffer;
+
+ BUG_ON(mei_hdr->me_addr != dev->iamthif_cl.me_client_id);
+ BUG_ON(dev->iamthif_state != MEI_IAMTHIF_READING);
+
+ buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index;
+ BUG_ON(dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length);
+
+ mei_read_slots(dev, buffer, mei_hdr->length);
+
+ dev->iamthif_msg_buf_index += mei_hdr->length;
+
+ if (!mei_hdr->msg_complete)
+ return 0;
+
+ dev_dbg(&dev->pdev->dev,
+ "amthi_message_buffer_index =%d\n",
+ mei_hdr->length);
+
+ dev_dbg(&dev->pdev->dev, "completed amthi read.\n ");
+ if (!dev->iamthif_current_cb)
+ return -ENODEV;
+
+ cb = dev->iamthif_current_cb;
+ dev->iamthif_current_cb = NULL;
+
+ if (!cb->cl)
+ return -ENODEV;
+
+ dev->iamthif_stall_timer = 0;
+ cb->buf_idx = dev->iamthif_msg_buf_index;
+ cb->read_time = jiffies;
+ if (dev->iamthif_ioctl && cb->cl == &dev->iamthif_cl) {
+ /* found the iamthif cb */
+ dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n ");
+ dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n ");
+ list_add_tail(&cb->list, &complete_list->list);
+ }
+ return 0;
+}
+
+/**
+ * mei_amthif_irq_read - prepares to read amthif data.
+ *
+ * @dev: the device structure.
+ * @slots: free slots.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+int mei_amthif_irq_read(struct mei_device *dev, s32 *slots)
+{
+
+ if (((*slots) * sizeof(u32)) < (sizeof(struct mei_msg_hdr)
+ + sizeof(struct hbm_flow_control))) {
+ return -EMSGSIZE;
+ }
+ *slots -= mei_data2slots(sizeof(struct hbm_flow_control));
+ if (mei_send_flow_control(dev, &dev->iamthif_cl)) {
+ dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n");
+ return -EIO;
+ }
+
+ dev_dbg(&dev->pdev->dev, "iamthif flow control success\n");
+ dev->iamthif_state = MEI_IAMTHIF_READING;
+ dev->iamthif_flow_control_pending = false;
+ dev->iamthif_msg_buf_index = 0;
+ dev->iamthif_msg_buf_size = 0;
+ dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER;
+ dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev);
+ return 0;
+}
+
+/**
+ * mei_amthif_complete - complete amthif callback.
+ *
+ * @dev: the device structure.
+ * @cb_pos: callback block.
+ */
+void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
+{
+ if (dev->iamthif_canceled != 1) {
+ dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE;
+ dev->iamthif_stall_timer = 0;
+ memcpy(cb->response_buffer.data,
+ dev->iamthif_msg_buf,
+ dev->iamthif_msg_buf_index);
+ list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list);
+ dev_dbg(&dev->pdev->dev, "amthi read completed\n");
+ dev->iamthif_timer = jiffies;
+ dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n",
+ dev->iamthif_timer);
+ } else {
+ mei_amthif_run_next_cmd(dev);
+ }
+
+ dev_dbg(&dev->pdev->dev, "completing amthi call back.\n");
+ wake_up_interruptible(&dev->iamthif_cl.wait);
+}
+
+/**
+ * mei_clear_list - removes all callbacks associated with file
+ * from mei_cb_list
+ *
+ * @dev: device structure.
+ * @file: file structure
+ * @mei_cb_list: callbacks list
+ *
+ * mei_clear_list is called to clear resources associated with file
+ * when application calls close function or Ctrl-C was pressed
+ *
+ * returns true if callback removed from the list, false otherwise
+ */
+static bool mei_clear_list(struct mei_device *dev,
+ const struct file *file, struct list_head *mei_cb_list)
+{
+ struct mei_cl_cb *cb_pos = NULL;
+ struct mei_cl_cb *cb_next = NULL;
+ bool removed = false;
+
+ /* list all list member */
+ list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, list) {
+ /* check if list member associated with a file */
+ if (file == cb_pos->file_object) {
+ /* remove member from the list */
+ list_del(&cb_pos->list);
+ /* check if cb equal to current iamthif cb */
+ if (dev->iamthif_current_cb == cb_pos) {
+ dev->iamthif_current_cb = NULL;
+ /* send flow control to iamthif client */
+ mei_send_flow_control(dev, &dev->iamthif_cl);
+ }
+ /* free all allocated buffers */
+ mei_io_cb_free(cb_pos);
+ cb_pos = NULL;
+ removed = true;
+ }
+ }
+ return removed;
+}
+
+/**
+ * mei_clear_lists - removes all callbacks associated with file
+ *
+ * @dev: device structure
+ * @file: file structure
+ *
+ * mei_clear_lists is called to clear resources associated with file
+ * when application calls close function or Ctrl-C was pressed
+ *
+ * returns true if callback removed from the list, false otherwise
+ */
+static bool mei_clear_lists(struct mei_device *dev, struct file *file)
+{
+ bool removed = false;
+
+ /* remove callbacks associated with a file */
+ mei_clear_list(dev, file, &dev->amthif_cmd_list.list);
+ if (mei_clear_list(dev, file, &dev->amthif_rd_complete_list.list))
+ removed = true;
+
+ mei_clear_list(dev, file, &dev->ctrl_rd_list.list);
+
+ if (mei_clear_list(dev, file, &dev->ctrl_wr_list.list))
+ removed = true;
+
+ if (mei_clear_list(dev, file, &dev->write_waiting_list.list))
+ removed = true;
+
+ if (mei_clear_list(dev, file, &dev->write_list.list))
+ removed = true;
+
+ /* check if iamthif_current_cb not NULL */
+ if (dev->iamthif_current_cb && !removed) {
+ /* check file and iamthif current cb association */
+ if (dev->iamthif_current_cb->file_object == file) {
+ /* remove cb */
+ mei_io_cb_free(dev->iamthif_current_cb);
+ dev->iamthif_current_cb = NULL;
+ removed = true;
+ }
+ }
+ return removed;
+}
+
+/**
+* mei_amthif_release - the release function
+*
+* @inode: pointer to inode structure
+* @file: pointer to file structure
+*
+* returns 0 on success, <0 on error
+*/
+int mei_amthif_release(struct mei_device *dev, struct file *file)
+{
+ if (dev->open_handle_count > 0)
+ dev->open_handle_count--;
+
+ if (dev->iamthif_file_object == file &&
+ dev->iamthif_state != MEI_IAMTHIF_IDLE) {
+
+ dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n",
+ dev->iamthif_state);
+ dev->iamthif_canceled = true;
+ if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) {
+ dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n");
+ mei_amthif_run_next_cmd(dev);
+ }
+ }
+
+ if (mei_clear_lists(dev, file))
+ dev->iamthif_state = MEI_IAMTHIF_IDLE;
+
+ return 0;
+}
diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h
index 9700532f02f..be8ca6b333c 100644
--- a/drivers/misc/mei/hw.h
+++ b/drivers/misc/mei/hw.h
@@ -20,16 +20,16 @@
#include <linux/uuid.h>
/*
- * Timeouts
+ * Timeouts in Seconds
*/
-#define MEI_INTEROP_TIMEOUT (HZ * 7)
-#define MEI_CONNECT_TIMEOUT 3 /* at least 2 seconds */
+#define MEI_INTEROP_TIMEOUT 7 /* Timeout on ready message */
+#define MEI_CONNECT_TIMEOUT 3 /* HPS: at least 2 seconds */
-#define CONNECT_TIMEOUT 15 /* HPS definition */
-#define INIT_CLIENTS_TIMEOUT 15 /* HPS definition */
+#define MEI_CL_CONNECT_TIMEOUT 15 /* HPS: Client Connect Timeout */
+#define MEI_CLIENTS_INIT_TIMEOUT 15 /* HPS: Clients Enumeration Timeout */
-#define IAMTHIF_STALL_TIMER 12 /* seconds */
-#define IAMTHIF_READ_TIMER 10000 /* ms */
+#define MEI_IAMTHIF_STALL_TIMER 12 /* HPS */
+#define MEI_IAMTHIF_READ_TIMER 10 /* HPS */
/*
* Internal Clients Number
@@ -293,6 +293,14 @@ struct hbm_props_response {
struct mei_client_properties client_properties;
} __packed;
+/**
+ * struct hbm_client_connect_request - connect/disconnect request
+ *
+ * @hbm_cmd - bus message command header
+ * @me_addr - address of the client in ME
+ * @host_addr - address of the client in the driver
+ * @reserved
+ */
struct hbm_client_connect_request {
u8 hbm_cmd;
u8 me_addr;
@@ -300,6 +308,14 @@ struct hbm_client_connect_request {
u8 reserved;
} __packed;
+/**
+ * struct hbm_client_connect_response - connect/disconnect response
+ *
+ * @hbm_cmd - bus message command header
+ * @me_addr - address of the client in ME
+ * @host_addr - address of the client in the driver
+ * @status - status of the request
+ */
struct hbm_client_connect_response {
u8 hbm_cmd;
u8 me_addr;
@@ -307,12 +323,6 @@ struct hbm_client_connect_response {
u8 status;
} __packed;
-struct hbm_client_disconnect_request {
- u8 hbm_cmd;
- u8 me_addr;
- u8 host_addr;
- u8 reserved[1];
-} __packed;
#define MEI_FC_MESSAGE_RESERVED_LENGTH 5
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 98f1430e3e1..a54cd5567ca 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -43,21 +43,6 @@ const char *mei_dev_state_str(int state)
}
-const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac,
- 0xa8, 0x46, 0xe0, 0xff, 0x65,
- 0x81, 0x4c);
-
-/**
- * mei_io_list_init - Sets up a queue list.
- *
- * @list: An instance io list structure
- * @dev: the device structure
- */
-void mei_io_list_init(struct mei_io_list *list)
-{
- /* initialize our queue list */
- INIT_LIST_HEAD(&list->mei_cb.cb_list);
-}
/**
* mei_io_list_flush - removes list entry belonging to cl.
@@ -65,17 +50,15 @@ void mei_io_list_init(struct mei_io_list *list)
* @list: An instance of our list structure
* @cl: private data of the file object
*/
-void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl)
+void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
{
struct mei_cl_cb *pos;
struct mei_cl_cb *next;
- list_for_each_entry_safe(pos, next, &list->mei_cb.cb_list, cb_list) {
- if (pos->file_private) {
- struct mei_cl *cl_tmp;
- cl_tmp = (struct mei_cl *)pos->file_private;
- if (mei_cl_cmp_id(cl, cl_tmp))
- list_del(&pos->cb_list);
+ list_for_each_entry_safe(pos, next, &list->list, list) {
+ if (pos->cl) {
+ if (mei_cl_cmp_id(cl, pos->cl))
+ list_del(&pos->list);
}
}
}
@@ -96,31 +79,14 @@ int mei_cl_flush_queues(struct mei_cl *cl)
mei_io_list_flush(&cl->dev->write_waiting_list, cl);
mei_io_list_flush(&cl->dev->ctrl_wr_list, cl);
mei_io_list_flush(&cl->dev->ctrl_rd_list, cl);
- mei_io_list_flush(&cl->dev->amthi_cmd_list, cl);
- mei_io_list_flush(&cl->dev->amthi_read_complete_list, cl);
+ mei_io_list_flush(&cl->dev->amthif_cmd_list, cl);
+ mei_io_list_flush(&cl->dev->amthif_rd_complete_list, cl);
return 0;
}
/**
- * mei_reset_iamthif_params - initializes mei device iamthif
- *
- * @dev: the device structure
- */
-static void mei_reset_iamthif_params(struct mei_device *dev)
-{
- /* reset iamthif parameters. */
- dev->iamthif_current_cb = NULL;
- dev->iamthif_msg_buf_size = 0;
- dev->iamthif_msg_buf_index = 0;
- dev->iamthif_canceled = false;
- dev->iamthif_ioctl = false;
- dev->iamthif_state = MEI_IAMTHIF_IDLE;
- dev->iamthif_timer = 0;
-}
-
-/**
* init_mei_device - allocates and initializes the mei device structure
*
* @pdev: The pci device structure
@@ -144,16 +110,14 @@ struct mei_device *mei_device_init(struct pci_dev *pdev)
init_waitqueue_head(&dev->wait_stop_wd);
dev->dev_state = MEI_DEV_INITIALIZING;
dev->iamthif_state = MEI_IAMTHIF_IDLE;
- dev->wd_interface_reg = false;
-
mei_io_list_init(&dev->read_list);
mei_io_list_init(&dev->write_list);
mei_io_list_init(&dev->write_waiting_list);
mei_io_list_init(&dev->ctrl_wr_list);
mei_io_list_init(&dev->ctrl_rd_list);
- mei_io_list_init(&dev->amthi_cmd_list);
- mei_io_list_init(&dev->amthi_read_complete_list);
+ mei_io_list_init(&dev->amthif_cmd_list);
+ mei_io_list_init(&dev->amthif_rd_complete_list);
dev->pdev = pdev;
return dev;
}
@@ -196,7 +160,8 @@ int mei_hw_init(struct mei_device *dev)
if (!dev->recvd_msg) {
mutex_unlock(&dev->device_lock);
err = wait_event_interruptible_timeout(dev->wait_recvd_msg,
- dev->recvd_msg, MEI_INTEROP_TIMEOUT);
+ dev->recvd_msg,
+ mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT));
mutex_lock(&dev->device_lock);
}
@@ -317,15 +282,13 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
cl_pos->timer_count = 0;
}
/* remove entry if already in list */
- dev_dbg(&dev->pdev->dev, "list del iamthif and wd file list.\n");
- mei_remove_client_from_file_list(dev,
- dev->wd_cl.host_client_id);
+ dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n");
+ mei_me_cl_unlink(dev, &dev->wd_cl);
- mei_remove_client_from_file_list(dev,
- dev->iamthif_cl.host_client_id);
+ mei_me_cl_unlink(dev, &dev->iamthif_cl);
- mei_reset_iamthif_params(dev);
- dev->extra_write_index = 0;
+ mei_amthif_reset_params(dev);
+ memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg));
}
dev->me_clients_num = 0;
@@ -351,10 +314,9 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
}
}
/* remove all waiting requests */
- list_for_each_entry_safe(cb_pos, cb_next,
- &dev->write_list.mei_cb.cb_list, cb_list) {
- list_del(&cb_pos->cb_list);
- mei_free_cb_private(cb_pos);
+ list_for_each_entry_safe(cb_pos, cb_next, &dev->write_list.list, list) {
+ list_del(&cb_pos->list);
+ mei_io_cb_free(cb_pos);
}
}
@@ -370,31 +332,26 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
void mei_host_start_message(struct mei_device *dev)
{
struct mei_msg_hdr *mei_hdr;
- struct hbm_host_version_request *host_start_req;
+ struct hbm_host_version_request *start_req;
+ const size_t len = sizeof(struct hbm_host_version_request);
+
+ mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
/* host start message */
- mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
- mei_hdr->host_addr = 0;
- mei_hdr->me_addr = 0;
- mei_hdr->length = sizeof(struct hbm_host_version_request);
- mei_hdr->msg_complete = 1;
- mei_hdr->reserved = 0;
-
- host_start_req =
- (struct hbm_host_version_request *) &dev->wr_msg_buf[1];
- memset(host_start_req, 0, sizeof(struct hbm_host_version_request));
- host_start_req->hbm_cmd = HOST_START_REQ_CMD;
- host_start_req->host_version.major_version = HBM_MAJOR_VERSION;
- host_start_req->host_version.minor_version = HBM_MINOR_VERSION;
+ start_req = (struct hbm_host_version_request *)&dev->wr_msg_buf[1];
+ memset(start_req, 0, len);
+ start_req->hbm_cmd = HOST_START_REQ_CMD;
+ start_req->host_version.major_version = HBM_MAJOR_VERSION;
+ start_req->host_version.minor_version = HBM_MINOR_VERSION;
+
dev->recvd_msg = false;
- if (mei_write_message(dev, mei_hdr, (unsigned char *)host_start_req,
- mei_hdr->length)) {
+ if (mei_write_message(dev, mei_hdr, (unsigned char *)start_req, len)) {
dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n");
dev->dev_state = MEI_DEV_RESETING;
mei_reset(dev, 1);
}
dev->init_clients_state = MEI_START_MESSAGE;
- dev->init_clients_timer = INIT_CLIENTS_TIMEOUT;
+ dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
return ;
}
@@ -408,26 +365,22 @@ void mei_host_start_message(struct mei_device *dev)
void mei_host_enum_clients_message(struct mei_device *dev)
{
struct mei_msg_hdr *mei_hdr;
- struct hbm_host_enum_request *host_enum_req;
- mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+ struct hbm_host_enum_request *enum_req;
+ const size_t len = sizeof(struct hbm_host_enum_request);
/* enumerate clients */
- mei_hdr->host_addr = 0;
- mei_hdr->me_addr = 0;
- mei_hdr->length = sizeof(struct hbm_host_enum_request);
- mei_hdr->msg_complete = 1;
- mei_hdr->reserved = 0;
-
- host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1];
- memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request));
- host_enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;
- if (mei_write_message(dev, mei_hdr, (unsigned char *)host_enum_req,
- mei_hdr->length)) {
+ mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
+
+ enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1];
+ memset(enum_req, 0, sizeof(struct hbm_host_enum_request));
+ enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;
+
+ if (mei_write_message(dev, mei_hdr, (unsigned char *)enum_req, len)) {
dev->dev_state = MEI_DEV_RESETING;
dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
mei_reset(dev, 1);
}
dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE;
- dev->init_clients_timer = INIT_CLIENTS_TIMEOUT;
+ dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
return;
}
@@ -470,56 +423,87 @@ void mei_allocate_me_clients_storage(struct mei_device *dev)
dev->me_clients = clients;
return ;
}
-/**
- * host_client_properties - reads properties for client
- *
- * @dev: the device structure
- *
- * returns:
- * < 0 - Error.
- * = 0 - no more clients.
- * = 1 - still have clients to send properties request.
- */
-int mei_host_client_properties(struct mei_device *dev)
+
+void mei_host_client_init(struct work_struct *work)
{
- struct mei_msg_hdr *mei_header;
- struct hbm_props_request *host_cli_req;
- int b;
- u8 client_num = dev->me_client_presentation_num;
-
- b = dev->me_client_index;
- b = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, b);
- if (b < MEI_CLIENTS_MAX) {
- dev->me_clients[client_num].client_id = b;
- dev->me_clients[client_num].mei_flow_ctrl_creds = 0;
- mei_header = (struct mei_msg_hdr *)&dev->wr_msg_buf[0];
- mei_header->host_addr = 0;
- mei_header->me_addr = 0;
- mei_header->length = sizeof(struct hbm_props_request);
- mei_header->msg_complete = 1;
- mei_header->reserved = 0;
-
- host_cli_req = (struct hbm_props_request *)&dev->wr_msg_buf[1];
-
- memset(host_cli_req, 0, sizeof(struct hbm_props_request));
-
- host_cli_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
- host_cli_req->address = b;
-
- if (mei_write_message(dev, mei_header,
- (unsigned char *)host_cli_req,
- mei_header->length)) {
- dev->dev_state = MEI_DEV_RESETING;
- dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
- mei_reset(dev, 1);
- return -EIO;
- }
+ struct mei_device *dev = container_of(work,
+ struct mei_device, init_work);
+ struct mei_client_properties *client_props;
+ int i;
+
+ 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;
+
+ if (!uuid_le_cmp(client_props->protocol_name, mei_amthi_guid))
+ mei_amthif_host_init(dev);
+ else if (!uuid_le_cmp(client_props->protocol_name, mei_wd_guid))
+ mei_wd_host_init(dev);
+ }
+
+ dev->dev_state = MEI_DEV_ENABLED;
- dev->init_clients_timer = INIT_CLIENTS_TIMEOUT;
- dev->me_client_index = b;
- return 1;
+ mutex_unlock(&dev->device_lock);
+}
+
+int mei_host_client_enumerate(struct mei_device *dev)
+{
+
+ struct mei_msg_hdr *mei_hdr;
+ struct hbm_props_request *prop_req;
+ const size_t len = sizeof(struct hbm_props_request);
+ unsigned long next_client_index;
+ u8 client_num;
+
+
+ client_num = dev->me_client_presentation_num;
+
+ next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX,
+ dev->me_client_index);
+
+ /* We got all client properties */
+ if (next_client_index == MEI_CLIENTS_MAX) {
+ schedule_work(&dev->init_work);
+
+ return 0;
}
+ dev->me_clients[client_num].client_id = next_client_index;
+ dev->me_clients[client_num].mei_flow_ctrl_creds = 0;
+
+ mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
+ prop_req = (struct hbm_props_request *)&dev->wr_msg_buf[1];
+
+ memset(prop_req, 0, sizeof(struct hbm_props_request));
+
+
+ prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
+ prop_req->address = next_client_index;
+
+ if (mei_write_message(dev, mei_hdr, (unsigned char *) prop_req,
+ mei_hdr->length)) {
+ dev->dev_state = MEI_DEV_RESETING;
+ dev_err(&dev->pdev->dev, "Properties request command failed\n");
+ mei_reset(dev, 1);
+
+ return -EIO;
+ }
+
+ dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
+ dev->me_client_index = next_client_index;
+
return 0;
}
@@ -557,17 +541,20 @@ int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid)
/**
- * mei_me_cl_update_filext - searches for ME client guid
- * sets client_id in mei_file_private if found
+ * mei_me_cl_link - create link between host and me clinet and add
+ * me_cl to the list
+ *
* @dev: the device structure
- * @cl: private file structure to set client_id in
- * @cuuid: searched uuid of ME client
- * @client_id: id of host client to be set in file private structure
+ * @cl: link between me and host client assocated with opened file descriptor
+ * @cuuid: uuid of ME client
+ * @client_id: id of the host client
*
- * returns ME client index
+ * returns ME client index if ME client
+ * -EINVAL on incorrect values
+ * -ENONET if client not found
*/
-int mei_me_cl_update_filext(struct mei_device *dev, struct mei_cl *cl,
- const uuid_le *cuuid, u8 host_cl_id)
+int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl,
+ const uuid_le *cuuid, u8 host_cl_id)
{
int i;
@@ -587,54 +574,22 @@ int mei_me_cl_update_filext(struct mei_device *dev, struct mei_cl *cl,
return -ENOENT;
}
-
/**
- * host_init_iamthif - mei initialization iamthif client.
+ * mei_me_cl_unlink - remove me_cl from the list
*
* @dev: the device structure
- *
+ * @host_client_id: host client id to be removed
*/
-void mei_host_init_iamthif(struct mei_device *dev)
+void mei_me_cl_unlink(struct mei_device *dev, struct mei_cl *cl)
{
- int i;
- unsigned char *msg_buf;
-
- mei_cl_init(&dev->iamthif_cl, dev);
- dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
-
- /* find ME amthi client */
- i = mei_me_cl_update_filext(dev, &dev->iamthif_cl,
- &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID);
- if (i < 0) {
- dev_dbg(&dev->pdev->dev, "failed to find iamthif client.\n");
- return;
- }
-
- /* Assign iamthif_mtu to the value received from ME */
-
- dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length;
- dev_dbg(&dev->pdev->dev, "IAMTHIF_MTU = %d\n",
- dev->me_clients[i].props.max_msg_length);
-
- kfree(dev->iamthif_msg_buf);
- dev->iamthif_msg_buf = NULL;
-
- /* allocate storage for ME message buffer */
- msg_buf = kcalloc(dev->iamthif_mtu,
- sizeof(unsigned char), GFP_KERNEL);
- if (!msg_buf) {
- dev_dbg(&dev->pdev->dev, "memory allocation for ME message buffer failed.\n");
- return;
- }
-
- dev->iamthif_msg_buf = msg_buf;
-
- if (mei_connect(dev, &dev->iamthif_cl)) {
- dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n");
- dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
- dev->iamthif_cl.host_client_id = 0;
- } else {
- dev->iamthif_cl.timer_count = CONNECT_TIMEOUT;
+ struct mei_cl *pos, *next;
+ 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;
+ }
}
}
@@ -671,9 +626,8 @@ struct mei_cl *mei_cl_allocate(struct mei_device *dev)
*/
int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl)
{
- int rets, err;
- long timeout = 15; /* 15 seconds */
struct mei_cl_cb *cb;
+ int rets, err;
if (!dev || !cl)
return -ENODEV;
@@ -681,13 +635,11 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl)
if (cl->state != MEI_FILE_DISCONNECTING)
return 0;
- cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
+ cb = mei_io_cb_init(cl, NULL);
if (!cb)
return -ENOMEM;
- INIT_LIST_HEAD(&cb->cb_list);
- cb->file_private = cl;
- cb->major_file_operations = MEI_CLOSE;
+ cb->fop_type = MEI_FOP_CLOSE;
if (dev->mei_host_buffer_is_empty) {
dev->mei_host_buffer_is_empty = false;
if (mei_disconnect(dev, cl)) {
@@ -696,17 +648,17 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl)
goto free;
}
mdelay(10); /* Wait for hardware disconnection ready */
- list_add_tail(&cb->cb_list, &dev->ctrl_rd_list.mei_cb.cb_list);
+ list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
} else {
dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n");
- list_add_tail(&cb->cb_list,
- &dev->ctrl_wr_list.mei_cb.cb_list);
+ list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
+
}
mutex_unlock(&dev->device_lock);
err = wait_event_timeout(dev->wait_recvd_msg,
- (MEI_FILE_DISCONNECTED == cl->state),
- timeout * HZ);
+ MEI_FILE_DISCONNECTED == cl->state,
+ mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
mutex_lock(&dev->device_lock);
if (MEI_FILE_DISCONNECTED == cl->state) {
@@ -728,29 +680,7 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl)
mei_io_list_flush(&dev->ctrl_rd_list, cl);
mei_io_list_flush(&dev->ctrl_wr_list, cl);
free:
- mei_free_cb_private(cb);
+ mei_io_cb_free(cb);
return rets;
}
-/**
- * mei_remove_client_from_file_list -
- * removes file private data from device file list
- *
- * @dev: the device structure
- * @host_client_id: host client id to be removed
- */
-void mei_remove_client_from_file_list(struct mei_device *dev,
- u8 host_client_id)
-{
- struct mei_cl *cl_pos = NULL;
- struct mei_cl *cl_next = NULL;
- list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
- if (host_client_id == cl_pos->host_client_id) {
- dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n",
- cl_pos->host_client_id,
- cl_pos->me_client_id);
- list_del_init(&cl_pos->link);
- break;
- }
- }
-}
diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c
index 509c3957ff4..8de85478596 100644
--- a/drivers/misc/mei/interface.c
+++ b/drivers/misc/mei/interface.c
@@ -292,28 +292,23 @@ int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl)
int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl)
{
struct mei_msg_hdr *mei_hdr;
- struct hbm_flow_control *mei_flow_control;
-
- mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
- mei_hdr->host_addr = 0;
- mei_hdr->me_addr = 0;
- mei_hdr->length = sizeof(struct hbm_flow_control);
- mei_hdr->msg_complete = 1;
- mei_hdr->reserved = 0;
-
- mei_flow_control = (struct hbm_flow_control *) &dev->wr_msg_buf[1];
- memset(mei_flow_control, 0, sizeof(*mei_flow_control));
- mei_flow_control->host_addr = cl->host_client_id;
- mei_flow_control->me_addr = cl->me_client_id;
- mei_flow_control->hbm_cmd = MEI_FLOW_CONTROL_CMD;
- memset(mei_flow_control->reserved, 0,
- sizeof(mei_flow_control->reserved));
+ struct hbm_flow_control *flow_ctrl;
+ const size_t len = sizeof(struct hbm_flow_control);
+
+ mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
+
+ flow_ctrl = (struct hbm_flow_control *)&dev->wr_msg_buf[1];
+ memset(flow_ctrl, 0, len);
+ flow_ctrl->hbm_cmd = MEI_FLOW_CONTROL_CMD;
+ flow_ctrl->host_addr = cl->host_client_id;
+ flow_ctrl->me_addr = cl->me_client_id;
+ /* FIXME: reserved !? */
+ memset(flow_ctrl->reserved, 0, sizeof(flow_ctrl->reserved));
dev_dbg(&dev->pdev->dev, "sending flow control host client = %d, ME client = %d\n",
cl->host_client_id, cl->me_client_id);
return mei_write_message(dev, mei_hdr,
- (unsigned char *) mei_flow_control,
- sizeof(struct hbm_flow_control));
+ (unsigned char *) flow_ctrl, len);
}
/**
@@ -352,26 +347,19 @@ int mei_other_client_is_connecting(struct mei_device *dev,
int mei_disconnect(struct mei_device *dev, struct mei_cl *cl)
{
struct mei_msg_hdr *mei_hdr;
- struct hbm_client_disconnect_request *mei_cli_disconnect;
-
- mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
- mei_hdr->host_addr = 0;
- mei_hdr->me_addr = 0;
- mei_hdr->length = sizeof(struct hbm_client_disconnect_request);
- mei_hdr->msg_complete = 1;
- mei_hdr->reserved = 0;
-
- mei_cli_disconnect =
- (struct hbm_client_disconnect_request *) &dev->wr_msg_buf[1];
- memset(mei_cli_disconnect, 0, sizeof(*mei_cli_disconnect));
- mei_cli_disconnect->host_addr = cl->host_client_id;
- mei_cli_disconnect->me_addr = cl->me_client_id;
- mei_cli_disconnect->hbm_cmd = CLIENT_DISCONNECT_REQ_CMD;
- mei_cli_disconnect->reserved[0] = 0;
+ struct hbm_client_connect_request *req;
+ const size_t len = sizeof(struct hbm_client_connect_request);
- return mei_write_message(dev, mei_hdr,
- (unsigned char *) mei_cli_disconnect,
- sizeof(struct hbm_client_disconnect_request));
+ mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
+
+ req = (struct hbm_client_connect_request *)&dev->wr_msg_buf[1];
+ memset(req, 0, len);
+ req->hbm_cmd = CLIENT_DISCONNECT_REQ_CMD;
+ req->host_addr = cl->host_client_id;
+ req->me_addr = cl->me_client_id;
+ req->reserved = 0;
+
+ return mei_write_message(dev, mei_hdr, (unsigned char *)req, len);
}
/**
@@ -385,23 +373,16 @@ int mei_disconnect(struct mei_device *dev, struct mei_cl *cl)
int mei_connect(struct mei_device *dev, struct mei_cl *cl)
{
struct mei_msg_hdr *mei_hdr;
- struct hbm_client_connect_request *mei_cli_connect;
-
- mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
- mei_hdr->host_addr = 0;
- mei_hdr->me_addr = 0;
- mei_hdr->length = sizeof(struct hbm_client_connect_request);
- mei_hdr->msg_complete = 1;
- mei_hdr->reserved = 0;
-
- mei_cli_connect =
- (struct hbm_client_connect_request *) &dev->wr_msg_buf[1];
- mei_cli_connect->host_addr = cl->host_client_id;
- mei_cli_connect->me_addr = cl->me_client_id;
- mei_cli_connect->hbm_cmd = CLIENT_CONNECT_REQ_CMD;
- mei_cli_connect->reserved = 0;
+ struct hbm_client_connect_request *req;
+ const size_t len = sizeof(struct hbm_client_connect_request);
- return mei_write_message(dev, mei_hdr,
- (unsigned char *) mei_cli_connect,
- sizeof(struct hbm_client_connect_request));
+ mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
+
+ req = (struct hbm_client_connect_request *) &dev->wr_msg_buf[1];
+ req->hbm_cmd = CLIENT_CONNECT_REQ_CMD;
+ req->host_addr = cl->host_client_id;
+ req->me_addr = cl->me_client_id;
+ req->reserved = 0;
+
+ return mei_write_message(dev, mei_hdr, (unsigned char *) req, len);
}
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 3533edde04a..04fa2134615 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -57,14 +57,14 @@ irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id)
*/
static void _mei_cmpl(struct mei_cl *cl, struct mei_cl_cb *cb_pos)
{
- if (cb_pos->major_file_operations == MEI_WRITE) {
- mei_free_cb_private(cb_pos);
+ if (cb_pos->fop_type == MEI_FOP_WRITE) {
+ mei_io_cb_free(cb_pos);
cb_pos = NULL;
cl->writing_state = MEI_WRITE_COMPLETE;
if (waitqueue_active(&cl->tx_wait))
wake_up_interruptible(&cl->tx_wait);
- } else if (cb_pos->major_file_operations == MEI_READ &&
+ } else if (cb_pos->fop_type == MEI_FOP_READ &&
MEI_READING == cl->reading_state) {
cl->reading_state = MEI_READ_COMPLETE;
if (waitqueue_active(&cl->rx_wait))
@@ -74,94 +74,6 @@ static void _mei_cmpl(struct mei_cl *cl, struct mei_cl_cb *cb_pos)
}
/**
- * _mei_cmpl_iamthif - processes completed iamthif operation.
- *
- * @dev: the device structure.
- * @cb_pos: callback block.
- */
-static void _mei_cmpl_iamthif(struct mei_device *dev, struct mei_cl_cb *cb_pos)
-{
- if (dev->iamthif_canceled != 1) {
- dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE;
- dev->iamthif_stall_timer = 0;
- memcpy(cb_pos->response_buffer.data,
- dev->iamthif_msg_buf,
- dev->iamthif_msg_buf_index);
- list_add_tail(&cb_pos->cb_list,
- &dev->amthi_read_complete_list.mei_cb.cb_list);
- dev_dbg(&dev->pdev->dev, "amthi read completed.\n");
- dev->iamthif_timer = jiffies;
- dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n",
- dev->iamthif_timer);
- } else {
- mei_run_next_iamthif_cmd(dev);
- }
-
- dev_dbg(&dev->pdev->dev, "completing amthi call back.\n");
- wake_up_interruptible(&dev->iamthif_cl.wait);
-}
-
-
-/**
- * mei_irq_thread_read_amthi_message - bottom half read routine after ISR to
- * handle the read amthi message data processing.
- *
- * @complete_list: An instance of our list structure
- * @dev: the device structure
- * @mei_hdr: header of amthi message
- *
- * returns 0 on success, <0 on failure.
- */
-static int mei_irq_thread_read_amthi_message(struct mei_io_list *complete_list,
- struct mei_device *dev,
- struct mei_msg_hdr *mei_hdr)
-{
- struct mei_cl *cl;
- struct mei_cl_cb *cb;
- unsigned char *buffer;
-
- BUG_ON(mei_hdr->me_addr != dev->iamthif_cl.me_client_id);
- BUG_ON(dev->iamthif_state != MEI_IAMTHIF_READING);
-
- buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index;
- BUG_ON(dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length);
-
- mei_read_slots(dev, buffer, mei_hdr->length);
-
- dev->iamthif_msg_buf_index += mei_hdr->length;
-
- if (!mei_hdr->msg_complete)
- return 0;
-
- dev_dbg(&dev->pdev->dev,
- "amthi_message_buffer_index =%d\n",
- mei_hdr->length);
-
- dev_dbg(&dev->pdev->dev, "completed amthi read.\n ");
- if (!dev->iamthif_current_cb)
- return -ENODEV;
-
- cb = dev->iamthif_current_cb;
- dev->iamthif_current_cb = NULL;
-
- cl = (struct mei_cl *)cb->file_private;
- if (!cl)
- return -ENODEV;
-
- dev->iamthif_stall_timer = 0;
- cb->information = dev->iamthif_msg_buf_index;
- cb->read_time = jiffies;
- if (dev->iamthif_ioctl && cl == &dev->iamthif_cl) {
- /* found the iamthif cb */
- dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n ");
- dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n ");
- list_add_tail(&cb->cb_list,
- &complete_list->mei_cb.cb_list);
- }
- return 0;
-}
-
-/**
* _mei_irq_thread_state_ok - checks if mei header matches file private data
*
* @cl: private data of the file object
@@ -188,7 +100,7 @@ static int _mei_irq_thread_state_ok(struct mei_cl *cl,
*
* returns 0 on success, <0 on failure.
*/
-static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list,
+static int mei_irq_thread_read_client_message(struct mei_cl_cb *complete_list,
struct mei_device *dev,
struct mei_msg_hdr *mei_hdr)
{
@@ -197,36 +109,36 @@ static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list,
unsigned char *buffer = NULL;
dev_dbg(&dev->pdev->dev, "start client msg\n");
- if (list_empty(&dev->read_list.mei_cb.cb_list))
+ if (list_empty(&dev->read_list.list))
goto quit;
- list_for_each_entry_safe(cb_pos, cb_next,
- &dev->read_list.mei_cb.cb_list, cb_list) {
- cl = (struct mei_cl *)cb_pos->file_private;
+ list_for_each_entry_safe(cb_pos, cb_next, &dev->read_list.list, list) {
+ cl = cb_pos->cl;
if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) {
cl->reading_state = MEI_READING;
- buffer = cb_pos->response_buffer.data + cb_pos->information;
+ buffer = cb_pos->response_buffer.data + cb_pos->buf_idx;
if (cb_pos->response_buffer.size <
- mei_hdr->length + cb_pos->information) {
+ mei_hdr->length + cb_pos->buf_idx) {
dev_dbg(&dev->pdev->dev, "message overflow.\n");
- list_del(&cb_pos->cb_list);
+ list_del(&cb_pos->list);
return -ENOMEM;
}
if (buffer)
mei_read_slots(dev, buffer, mei_hdr->length);
- cb_pos->information += mei_hdr->length;
+ cb_pos->buf_idx += mei_hdr->length;
if (mei_hdr->msg_complete) {
cl->status = 0;
- list_del(&cb_pos->cb_list);
+ list_del(&cb_pos->list);
dev_dbg(&dev->pdev->dev,
"completed read H cl = %d, ME cl = %d, length = %lu\n",
cl->host_client_id,
cl->me_client_id,
- cb_pos->information);
- list_add_tail(&cb_pos->cb_list,
- &complete_list->mei_cb.cb_list);
+ cb_pos->buf_idx);
+
+ list_add_tail(&cb_pos->list,
+ &complete_list->list);
}
break;
@@ -246,37 +158,6 @@ quit:
}
/**
- * _mei_irq_thread_iamthif_read - prepares to read iamthif data.
- *
- * @dev: the device structure.
- * @slots: free slots.
- *
- * returns 0, OK; otherwise, error.
- */
-static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots)
-{
-
- if (((*slots) * sizeof(u32)) < (sizeof(struct mei_msg_hdr)
- + sizeof(struct hbm_flow_control))) {
- return -EMSGSIZE;
- }
- *slots -= mei_data2slots(sizeof(struct hbm_flow_control));
- if (mei_send_flow_control(dev, &dev->iamthif_cl)) {
- dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n");
- return -EIO;
- }
-
- dev_dbg(&dev->pdev->dev, "iamthif flow control success\n");
- dev->iamthif_state = MEI_IAMTHIF_READING;
- dev->iamthif_flow_control_pending = false;
- dev->iamthif_msg_buf_index = 0;
- dev->iamthif_msg_buf_size = 0;
- dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER;
- dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev);
- return 0;
-}
-
-/**
* _mei_irq_thread_close - processes close related operation.
*
* @dev: the device structure.
@@ -290,26 +171,24 @@ static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots)
static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
struct mei_cl_cb *cb_pos,
struct mei_cl *cl,
- struct mei_io_list *cmpl_list)
+ struct mei_cl_cb *cmpl_list)
{
if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
- sizeof(struct hbm_client_disconnect_request)))
+ sizeof(struct hbm_client_connect_request)))
return -EBADMSG;
- *slots -= mei_data2slots(sizeof(struct hbm_client_disconnect_request));
+ *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request));
if (mei_disconnect(dev, cl)) {
cl->status = 0;
- cb_pos->information = 0;
- list_move_tail(&cb_pos->cb_list,
- &cmpl_list->mei_cb.cb_list);
+ cb_pos->buf_idx = 0;
+ list_move_tail(&cb_pos->list, &cmpl_list->list);
return -EMSGSIZE;
} else {
cl->state = MEI_FILE_DISCONNECTING;
cl->status = 0;
- cb_pos->information = 0;
- list_move_tail(&cb_pos->cb_list,
- &dev->ctrl_rd_list.mei_cb.cb_list);
+ cb_pos->buf_idx = 0;
+ list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list);
cl->timer_count = MEI_CONNECT_TIMEOUT;
}
@@ -356,7 +235,7 @@ static void mei_client_connect_response(struct mei_device *dev,
{
struct mei_cl *cl;
- struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
+ struct mei_cl_cb *pos = NULL, *next = NULL;
dev_dbg(&dev->pdev->dev,
"connect_response:\n"
@@ -373,8 +252,6 @@ static void mei_client_connect_response(struct mei_device *dev,
dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
mei_watchdog_register(dev);
- /* next step in the state maching */
- mei_host_init_iamthif(dev);
return;
}
@@ -382,17 +259,16 @@ static void mei_client_connect_response(struct mei_device *dev,
dev->iamthif_state = MEI_IAMTHIF_IDLE;
return;
}
- list_for_each_entry_safe(cb_pos, cb_next,
- &dev->ctrl_rd_list.mei_cb.cb_list, cb_list) {
+ list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
- cl = (struct mei_cl *)cb_pos->file_private;
+ cl = pos->cl;
if (!cl) {
- list_del(&cb_pos->cb_list);
+ list_del(&pos->list);
return;
}
- if (MEI_IOCTL == cb_pos->major_file_operations) {
+ if (pos->fop_type == MEI_FOP_IOCTL) {
if (is_treat_specially_client(cl, rs)) {
- list_del(&cb_pos->cb_list);
+ list_del(&pos->list);
cl->status = 0;
cl->timer_count = 0;
break;
@@ -411,7 +287,7 @@ static void mei_client_disconnect_response(struct mei_device *dev,
struct hbm_client_connect_response *rs)
{
struct mei_cl *cl;
- struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
+ struct mei_cl_cb *pos = NULL, *next = NULL;
dev_dbg(&dev->pdev->dev,
"disconnect_response:\n"
@@ -422,12 +298,11 @@ static void mei_client_disconnect_response(struct mei_device *dev,
rs->host_addr,
rs->status);
- list_for_each_entry_safe(cb_pos, cb_next,
- &dev->ctrl_rd_list.mei_cb.cb_list, cb_list) {
- cl = (struct mei_cl *)cb_pos->file_private;
+ list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
+ cl = pos->cl;
if (!cl) {
- list_del(&cb_pos->cb_list);
+ list_del(&pos->list);
return;
}
@@ -435,7 +310,7 @@ static void mei_client_disconnect_response(struct mei_device *dev,
if (cl->host_client_id == rs->host_addr &&
cl->me_client_id == rs->me_addr) {
- list_del(&cb_pos->cb_list);
+ list_del(&pos->list);
if (!rs->status)
cl->state = MEI_FILE_DISCONNECTED;
@@ -537,10 +412,10 @@ static void mei_client_flow_control_response(struct mei_device *dev,
* returns !=0, same; 0,not.
*/
static int same_disconn_addr(struct mei_cl *cl,
- struct hbm_client_disconnect_request *disconn)
+ struct hbm_client_connect_request *req)
{
- return (cl->host_client_id == disconn->host_addr &&
- cl->me_client_id == disconn->me_addr);
+ return (cl->host_client_id == req->host_addr &&
+ cl->me_client_id == req->me_addr);
}
/**
@@ -550,49 +425,38 @@ static int same_disconn_addr(struct mei_cl *cl,
* @disconnect_req: disconnect request bus message.
*/
static void mei_client_disconnect_request(struct mei_device *dev,
- struct hbm_client_disconnect_request *disconnect_req)
+ struct hbm_client_connect_request *disconnect_req)
{
- struct mei_msg_hdr *mei_hdr;
struct hbm_client_connect_response *disconnect_res;
- struct mei_cl *cl_pos = NULL;
- struct mei_cl *cl_next = NULL;
+ struct mei_cl *pos, *next;
+ const size_t len = sizeof(struct hbm_client_connect_response);
- list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
- if (same_disconn_addr(cl_pos, disconnect_req)) {
+ list_for_each_entry_safe(pos, next, &dev->file_list, link) {
+ if (same_disconn_addr(pos, disconnect_req)) {
dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n",
disconnect_req->host_addr,
disconnect_req->me_addr);
- cl_pos->state = MEI_FILE_DISCONNECTED;
- cl_pos->timer_count = 0;
- if (cl_pos == &dev->wd_cl)
+ pos->state = MEI_FILE_DISCONNECTED;
+ pos->timer_count = 0;
+ if (pos == &dev->wd_cl)
dev->wd_pending = false;
- else if (cl_pos == &dev->iamthif_cl)
+ else if (pos == &dev->iamthif_cl)
dev->iamthif_timer = 0;
/* prepare disconnect response */
- mei_hdr =
- (struct mei_msg_hdr *) &dev->ext_msg_buf[0];
- mei_hdr->host_addr = 0;
- mei_hdr->me_addr = 0;
- mei_hdr->length =
- sizeof(struct hbm_client_connect_response);
- mei_hdr->msg_complete = 1;
- mei_hdr->reserved = 0;
-
+ (void)mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len);
disconnect_res =
(struct hbm_client_connect_response *)
- &dev->ext_msg_buf[1];
- disconnect_res->host_addr = cl_pos->host_client_id;
- disconnect_res->me_addr = cl_pos->me_client_id;
+ &dev->wr_ext_msg.data;
disconnect_res->hbm_cmd = CLIENT_DISCONNECT_RES_CMD;
+ disconnect_res->host_addr = pos->host_client_id;
+ disconnect_res->me_addr = pos->me_client_id;
disconnect_res->status = 0;
- dev->extra_write_index = 2;
break;
}
}
}
-
/**
* mei_irq_thread_read_bus_message - bottom half read routine after ISR to
* handle the read bus message cmd processing.
@@ -604,16 +468,15 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
struct mei_msg_hdr *mei_hdr)
{
struct mei_bus_message *mei_msg;
+ struct mei_me_client *me_client;
struct hbm_host_version_response *version_res;
struct hbm_client_connect_response *connect_res;
struct hbm_client_connect_response *disconnect_res;
+ struct hbm_client_connect_request *disconnect_req;
struct hbm_flow_control *flow_control;
struct hbm_props_response *props_res;
struct hbm_host_enum_response *enum_res;
- struct hbm_client_disconnect_request *disconnect_req;
- struct hbm_host_stop_request *host_stop_req;
- int res;
-
+ struct hbm_host_stop_request *stop_req;
/* read the message to our buffer */
BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf));
@@ -637,26 +500,20 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
return;
}
} else {
+ u32 *buf = dev->wr_msg_buf;
+ const size_t len = sizeof(struct hbm_host_stop_request);
+
dev->version = version_res->me_max_version;
+
/* send stop message */
- mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0];
- mei_hdr->host_addr = 0;
- mei_hdr->me_addr = 0;
- mei_hdr->length = sizeof(struct hbm_host_stop_request);
- mei_hdr->msg_complete = 1;
- mei_hdr->reserved = 0;
-
- host_stop_req = (struct hbm_host_stop_request *)
- &dev->wr_msg_buf[1];
-
- memset(host_stop_req,
- 0,
- sizeof(struct hbm_host_stop_request));
- host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
- host_stop_req->reason = DRIVER_STOP_REQUEST;
+ mei_hdr = mei_hbm_hdr(&buf[0], len);
+ stop_req = (struct hbm_host_stop_request *)&buf[1];
+ memset(stop_req, 0, len);
+ stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
+ stop_req->reason = DRIVER_STOP_REQUEST;
+
mei_write_message(dev, mei_hdr,
- (unsigned char *) (host_stop_req),
- mei_hdr->length);
+ (unsigned char *)stop_req, len);
dev_dbg(&dev->pdev->dev, "version mismatch.\n");
return;
}
@@ -666,16 +523,14 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
break;
case CLIENT_CONNECT_RES_CMD:
- connect_res =
- (struct hbm_client_connect_response *) mei_msg;
+ connect_res = (struct hbm_client_connect_response *) mei_msg;
mei_client_connect_response(dev, connect_res);
dev_dbg(&dev->pdev->dev, "client connect response message received.\n");
wake_up(&dev->wait_recvd_msg);
break;
case CLIENT_DISCONNECT_RES_CMD:
- disconnect_res =
- (struct hbm_client_connect_response *) mei_msg;
+ disconnect_res = (struct hbm_client_connect_response *) mei_msg;
mei_client_disconnect_response(dev, disconnect_res);
dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n");
wake_up(&dev->wait_recvd_msg);
@@ -689,64 +544,37 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
case HOST_CLIENT_PROPERTIES_RES_CMD:
props_res = (struct hbm_props_response *)mei_msg;
+ me_client = &dev->me_clients[dev->me_client_presentation_num];
+
if (props_res->status || !dev->me_clients) {
dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n");
mei_reset(dev, 1);
return;
}
- if (dev->me_clients[dev->me_client_presentation_num]
- .client_id == props_res->address) {
- dev->me_clients[dev->me_client_presentation_num].props
- = props_res->client_properties;
+ if (me_client->client_id != props_res->address) {
+ dev_err(&dev->pdev->dev,
+ "Host client properties reply mismatch\n");
+ mei_reset(dev, 1);
- if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
- dev->init_clients_state ==
- MEI_CLIENT_PROPERTIES_MESSAGE) {
- dev->me_client_index++;
- dev->me_client_presentation_num++;
-
- /** Send Client Properties request **/
- res = mei_host_client_properties(dev);
- if (res < 0) {
- dev_dbg(&dev->pdev->dev, "mei_host_client_properties() failed");
- return;
- } else if (!res) {
- /*
- * No more clients to send to.
- * Clear Map for indicating now ME clients
- * with associated host client
- */
- bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
- dev->open_handle_count = 0;
-
- /*
- * Reserving the first three client IDs
- * Client Id 0 - Reserved for MEI Bus Message communications
- * Client Id 1 - Reserved for Watchdog
- * Client ID 2 - Reserved for AMTHI
- */
- bitmap_set(dev->host_clients_map, 0, 3);
- dev->dev_state = MEI_DEV_ENABLED;
-
- /* if wd initialization fails, initialization the AMTHI client,
- * otherwise the AMTHI client will be initialized after the WD client connect response
- * will be received
- */
- if (mei_wd_host_init(dev))
- mei_host_init_iamthif(dev);
- }
+ return;
+ }
- } else {
- dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message");
- mei_reset(dev, 1);
- return;
- }
- } else {
- dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message for wrong client ID\n");
+ if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
+ dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) {
+ dev_err(&dev->pdev->dev,
+ "Unexpected client properties reply\n");
mei_reset(dev, 1);
+
return;
}
+
+ me_client->props = props_res->client_properties;
+ dev->me_client_index++;
+ dev->me_client_presentation_num++;
+
+ mei_host_client_enumerate(dev);
+
break;
case HOST_ENUM_RES_CMD:
@@ -760,7 +588,8 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
mei_allocate_me_clients_storage(dev);
dev->init_clients_state =
MEI_CLIENT_PROPERTIES_MESSAGE;
- mei_host_client_properties(dev);
+
+ mei_host_client_enumerate(dev);
} else {
dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n");
mei_reset(dev, 1);
@@ -776,29 +605,23 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
case CLIENT_DISCONNECT_REQ_CMD:
/* search for client */
- disconnect_req =
- (struct hbm_client_disconnect_request *) mei_msg;
+ disconnect_req = (struct hbm_client_connect_request *)mei_msg;
mei_client_disconnect_request(dev, disconnect_req);
break;
case ME_STOP_REQ_CMD:
- /* prepare stop request */
- mei_hdr = (struct mei_msg_hdr *) &dev->ext_msg_buf[0];
- mei_hdr->host_addr = 0;
- mei_hdr->me_addr = 0;
- mei_hdr->length = sizeof(struct hbm_host_stop_request);
- mei_hdr->msg_complete = 1;
- mei_hdr->reserved = 0;
- host_stop_req =
- (struct hbm_host_stop_request *) &dev->ext_msg_buf[1];
- memset(host_stop_req, 0, sizeof(struct hbm_host_stop_request));
- host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
- host_stop_req->reason = DRIVER_STOP_REQUEST;
- host_stop_req->reserved[0] = 0;
- host_stop_req->reserved[1] = 0;
- dev->extra_write_index = 2;
- break;
+ {
+ /* prepare stop request: sent in next interrupt event */
+
+ const size_t len = sizeof(struct hbm_host_stop_request);
+ mei_hdr = mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len);
+ stop_req = (struct hbm_host_stop_request *)&dev->wr_ext_msg.data;
+ memset(stop_req, 0, len);
+ stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
+ stop_req->reason = DRIVER_STOP_REQUEST;
+ break;
+ }
default:
BUG();
break;
@@ -821,12 +644,12 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots,
struct mei_cl_cb *cb_pos,
struct mei_cl *cl,
- struct mei_io_list *cmpl_list)
+ struct mei_cl_cb *cmpl_list)
{
if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
sizeof(struct hbm_flow_control))) {
/* return the cancel routine */
- list_del(&cb_pos->cb_list);
+ list_del(&cb_pos->list);
return -EBADMSG;
}
@@ -834,11 +657,11 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots,
if (mei_send_flow_control(dev, cl)) {
cl->status = -ENODEV;
- cb_pos->information = 0;
- list_move_tail(&cb_pos->cb_list, &cmpl_list->mei_cb.cb_list);
+ cb_pos->buf_idx = 0;
+ list_move_tail(&cb_pos->list, &cmpl_list->list);
return -ENODEV;
}
- list_move_tail(&cb_pos->cb_list, &dev->read_list.mei_cb.cb_list);
+ list_move_tail(&cb_pos->list, &dev->read_list.list);
return 0;
}
@@ -858,12 +681,12 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots,
static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
struct mei_cl_cb *cb_pos,
struct mei_cl *cl,
- struct mei_io_list *cmpl_list)
+ struct mei_cl_cb *cmpl_list)
{
if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
sizeof(struct hbm_client_connect_request))) {
/* return the cancel routine */
- list_del(&cb_pos->cb_list);
+ list_del(&cb_pos->list);
return -EBADMSG;
}
@@ -871,188 +694,73 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
*slots -= mei_data2slots(sizeof(struct hbm_client_connect_request));
if (mei_connect(dev, cl)) {
cl->status = -ENODEV;
- cb_pos->information = 0;
- list_del(&cb_pos->cb_list);
+ cb_pos->buf_idx = 0;
+ list_del(&cb_pos->list);
return -ENODEV;
} else {
- list_move_tail(&cb_pos->cb_list,
- &dev->ctrl_rd_list.mei_cb.cb_list);
+ list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list);
cl->timer_count = MEI_CONNECT_TIMEOUT;
}
return 0;
}
/**
- * _mei_irq_thread_cmpl - processes completed and no-iamthif operation.
+ * mei_irq_thread_write_complete - write messages to device.
*
* @dev: the device structure.
* @slots: free slots.
- * @cb_pos: callback block.
- * @cl: private data of the file object.
+ * @cb: callback block.
* @cmpl_list: complete list.
*
* returns 0, OK; otherwise, error.
*/
-static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots,
- struct mei_cl_cb *cb_pos,
- struct mei_cl *cl,
- struct mei_io_list *cmpl_list)
+static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots,
+ struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list)
{
struct mei_msg_hdr *mei_hdr;
+ struct mei_cl *cl = cb->cl;
+ size_t len = cb->request_buffer.size - cb->buf_idx;
+ size_t msg_slots = mei_data2slots(len);
+
+ mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0];
+ mei_hdr->host_addr = cl->host_client_id;
+ mei_hdr->me_addr = cl->me_client_id;
+ mei_hdr->reserved = 0;
- if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
- (cb_pos->request_buffer.size -
- cb_pos->information))) {
- mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
- mei_hdr->host_addr = cl->host_client_id;
- mei_hdr->me_addr = cl->me_client_id;
- mei_hdr->length = cb_pos->request_buffer.size -
- cb_pos->information;
+ if (*slots >= msg_slots) {
+ mei_hdr->length = len;
mei_hdr->msg_complete = 1;
- mei_hdr->reserved = 0;
- dev_dbg(&dev->pdev->dev, "cb_pos->request_buffer.size =%d"
- "mei_hdr->msg_complete = %d\n",
- cb_pos->request_buffer.size,
- mei_hdr->msg_complete);
- dev_dbg(&dev->pdev->dev, "cb_pos->information =%lu\n",
- cb_pos->information);
- dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n",
- mei_hdr->length);
- *slots -= mei_data2slots(mei_hdr->length);
- if (mei_write_message(dev, mei_hdr,
- (unsigned char *)
- (cb_pos->request_buffer.data +
- cb_pos->information),
- mei_hdr->length)) {
- cl->status = -ENODEV;
- list_move_tail(&cb_pos->cb_list,
- &cmpl_list->mei_cb.cb_list);
- return -ENODEV;
- } else {
- if (mei_flow_ctrl_reduce(dev, cl))
- return -ENODEV;
- cl->status = 0;
- cb_pos->information += mei_hdr->length;
- list_move_tail(&cb_pos->cb_list,
- &dev->write_waiting_list.mei_cb.cb_list);
- }
+ /* Split the message only if we can write the whole host buffer */
} else if (*slots == dev->hbuf_depth) {
- /* buffer is still empty */
- mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
- mei_hdr->host_addr = cl->host_client_id;
- mei_hdr->me_addr = cl->me_client_id;
- mei_hdr->length =
- (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
+ msg_slots = *slots;
+ len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
+ mei_hdr->length = len;
mei_hdr->msg_complete = 0;
- mei_hdr->reserved = 0;
- *slots -= mei_data2slots(mei_hdr->length);
- if (mei_write_message(dev, mei_hdr,
- (unsigned char *)
- (cb_pos->request_buffer.data +
- cb_pos->information),
- mei_hdr->length)) {
- cl->status = -ENODEV;
- list_move_tail(&cb_pos->cb_list,
- &cmpl_list->mei_cb.cb_list);
- return -ENODEV;
- } else {
- cb_pos->information += mei_hdr->length;
- dev_dbg(&dev->pdev->dev,
- "cb_pos->request_buffer.size =%d"
- " mei_hdr->msg_complete = %d\n",
- cb_pos->request_buffer.size,
- mei_hdr->msg_complete);
- dev_dbg(&dev->pdev->dev, "cb_pos->information =%lu\n",
- cb_pos->information);
- dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n",
- mei_hdr->length);
- }
- return -EMSGSIZE;
} else {
- return -EBADMSG;
+ /* wait for next time the host buffer is empty */
+ return 0;
}
- return 0;
-}
-
-/**
- * _mei_irq_thread_cmpl_iamthif - processes completed iamthif operation.
- *
- * @dev: the device structure.
- * @slots: free slots.
- * @cb_pos: callback block.
- * @cl: private data of the file object.
- * @cmpl_list: complete list.
- *
- * returns 0, OK; otherwise, error.
- */
-static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots,
- struct mei_cl_cb *cb_pos,
- struct mei_cl *cl,
- struct mei_io_list *cmpl_list)
-{
- struct mei_msg_hdr *mei_hdr;
-
- if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
- dev->iamthif_msg_buf_size -
- dev->iamthif_msg_buf_index)) {
- mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
- mei_hdr->host_addr = cl->host_client_id;
- mei_hdr->me_addr = cl->me_client_id;
- mei_hdr->length = dev->iamthif_msg_buf_size -
- dev->iamthif_msg_buf_index;
- mei_hdr->msg_complete = 1;
- mei_hdr->reserved = 0;
-
- *slots -= mei_data2slots(mei_hdr->length);
-
- if (mei_write_message(dev, mei_hdr,
- (dev->iamthif_msg_buf +
- dev->iamthif_msg_buf_index),
- mei_hdr->length)) {
- dev->iamthif_state = MEI_IAMTHIF_IDLE;
- cl->status = -ENODEV;
- list_del(&cb_pos->cb_list);
- return -ENODEV;
- } else {
- if (mei_flow_ctrl_reduce(dev, cl))
- return -ENODEV;
- dev->iamthif_msg_buf_index += mei_hdr->length;
- cb_pos->information = dev->iamthif_msg_buf_index;
- cl->status = 0;
- dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
- dev->iamthif_flow_control_pending = true;
- /* save iamthif cb sent to amthi client */
- dev->iamthif_current_cb = cb_pos;
- list_move_tail(&cb_pos->cb_list,
- &dev->write_waiting_list.mei_cb.cb_list);
+ dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n",
+ cb->request_buffer.size, cb->buf_idx);
+ dev_dbg(&dev->pdev->dev, "msg: len = %d complete = %d\n",
+ mei_hdr->length, mei_hdr->msg_complete);
- }
- } else if (*slots == dev->hbuf_depth) {
- /* buffer is still empty */
- mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
- mei_hdr->host_addr = cl->host_client_id;
- mei_hdr->me_addr = cl->me_client_id;
- mei_hdr->length =
- (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
- mei_hdr->msg_complete = 0;
- mei_hdr->reserved = 0;
+ *slots -= msg_slots;
+ if (mei_write_message(dev, mei_hdr,
+ cb->request_buffer.data + cb->buf_idx, len)) {
+ cl->status = -ENODEV;
+ list_move_tail(&cb->list, &cmpl_list->list);
+ return -ENODEV;
+ }
- *slots -= mei_data2slots(mei_hdr->length);
+ if (mei_flow_ctrl_reduce(dev, cl))
+ return -ENODEV;
- if (mei_write_message(dev, mei_hdr,
- (dev->iamthif_msg_buf +
- dev->iamthif_msg_buf_index),
- mei_hdr->length)) {
- cl->status = -ENODEV;
- list_del(&cb_pos->cb_list);
- } else {
- dev->iamthif_msg_buf_index += mei_hdr->length;
- }
- return -EMSGSIZE;
- } else {
- return -EBADMSG;
- }
+ cl->status = 0;
+ cb->buf_idx += mei_hdr->length;
+ if (mei_hdr->msg_complete)
+ list_move_tail(&cb->list, &dev->write_waiting_list.list);
return 0;
}
@@ -1067,7 +775,7 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots,
*
* returns 0 on success, <0 on failure.
*/
-static int mei_irq_thread_read_handler(struct mei_io_list *cmpl_list,
+static int mei_irq_thread_read_handler(struct mei_cl_cb *cmpl_list,
struct mei_device *dev,
s32 *slots)
{
@@ -1130,8 +838,8 @@ static int mei_irq_thread_read_handler(struct mei_io_list *cmpl_list,
dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n");
dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n",
mei_hdr->length);
- ret = mei_irq_thread_read_amthi_message(cmpl_list,
- dev, mei_hdr);
+
+ ret = mei_amthif_irq_read_message(cmpl_list, dev, mei_hdr);
if (ret)
goto end;
@@ -1164,53 +872,51 @@ end:
* mei_irq_thread_write_handler - bottom half write routine after
* ISR to handle the write processing.
*
- * @cmpl_list: An instance of our list structure
* @dev: the device structure
- * @slots: slots to write.
+ * @cmpl_list: An instance of our list structure
*
* returns 0 on success, <0 on failure.
*/
-static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
- struct mei_device *dev,
- s32 *slots)
+static int mei_irq_thread_write_handler(struct mei_device *dev,
+ struct mei_cl_cb *cmpl_list)
{
struct mei_cl *cl;
struct mei_cl_cb *pos = NULL, *next = NULL;
- struct mei_io_list *list;
+ struct mei_cl_cb *list;
+ s32 slots;
int ret;
if (!mei_hbuf_is_empty(dev)) {
dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n");
return 0;
}
- *slots = mei_hbuf_empty_slots(dev);
- if (*slots <= 0)
+ slots = mei_hbuf_empty_slots(dev);
+ if (slots <= 0)
return -EMSGSIZE;
/* complete all waiting for write CB */
dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n");
list = &dev->write_waiting_list;
- list_for_each_entry_safe(pos, next, &list->mei_cb.cb_list, cb_list) {
- cl = (struct mei_cl *)pos->file_private;
+ list_for_each_entry_safe(pos, next, &list->list, list) {
+ cl = pos->cl;
if (cl == NULL)
continue;
cl->status = 0;
- list_del(&pos->cb_list);
+ list_del(&pos->list);
if (MEI_WRITING == cl->writing_state &&
- (pos->major_file_operations == MEI_WRITE) &&
- (cl != &dev->iamthif_cl)) {
+ pos->fop_type == MEI_FOP_WRITE &&
+ cl != &dev->iamthif_cl) {
dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n");
cl->writing_state = MEI_WRITE_COMPLETE;
- list_add_tail(&pos->cb_list,
- &cmpl_list->mei_cb.cb_list);
+ list_add_tail(&pos->list, &cmpl_list->list);
}
if (cl == &dev->iamthif_cl) {
dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
if (dev->iamthif_flow_control_pending) {
- ret = _mei_irq_thread_iamthif_read(dev, slots);
+ ret = mei_amthif_irq_read(dev, &slots);
if (ret)
return ret;
}
@@ -1222,15 +928,11 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
wake_up_interruptible(&dev->wait_stop_wd);
}
- if (dev->extra_write_index) {
- dev_dbg(&dev->pdev->dev, "extra_write_index =%d.\n",
- dev->extra_write_index);
- mei_write_message(dev,
- (struct mei_msg_hdr *) &dev->ext_msg_buf[0],
- (unsigned char *) &dev->ext_msg_buf[1],
- (dev->extra_write_index - 1) * sizeof(u32));
- *slots -= dev->extra_write_index;
- dev->extra_write_index = 0;
+ if (dev->wr_ext_msg.hdr.length) {
+ mei_write_message(dev, &dev->wr_ext_msg.hdr,
+ dev->wr_ext_msg.data, dev->wr_ext_msg.hdr.length);
+ slots -= mei_data2slots(dev->wr_ext_msg.hdr.length);
+ dev->wr_ext_msg.hdr.length = 0;
}
if (dev->dev_state == MEI_DEV_ENABLED) {
if (dev->wd_pending &&
@@ -1243,41 +945,43 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
dev->wd_pending = false;
if (dev->wd_state == MEI_WD_RUNNING)
- *slots -= mei_data2slots(MEI_WD_START_MSG_SIZE);
+ slots -= mei_data2slots(MEI_WD_START_MSG_SIZE);
else
- *slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE);
+ slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE);
}
}
/* complete control write list CB */
dev_dbg(&dev->pdev->dev, "complete control write list cb.\n");
- list_for_each_entry_safe(pos, next,
- &dev->ctrl_wr_list.mei_cb.cb_list, cb_list) {
- cl = (struct mei_cl *) pos->file_private;
+ list_for_each_entry_safe(pos, next, &dev->ctrl_wr_list.list, list) {
+ cl = pos->cl;
if (!cl) {
- list_del(&pos->cb_list);
+ list_del(&pos->list);
return -ENODEV;
}
- switch (pos->major_file_operations) {
- case MEI_CLOSE:
+ switch (pos->fop_type) {
+ case MEI_FOP_CLOSE:
/* send disconnect message */
- ret = _mei_irq_thread_close(dev, slots, pos, cl, cmpl_list);
+ ret = _mei_irq_thread_close(dev, &slots, pos,
+ cl, cmpl_list);
if (ret)
return ret;
break;
- case MEI_READ:
+ case MEI_FOP_READ:
/* send flow control message */
- ret = _mei_irq_thread_read(dev, slots, pos, cl, cmpl_list);
+ ret = _mei_irq_thread_read(dev, &slots, pos,
+ cl, cmpl_list);
if (ret)
return ret;
break;
- case MEI_IOCTL:
+ case MEI_FOP_IOCTL:
/* connect message */
if (mei_other_client_is_connecting(dev, cl))
continue;
- ret = _mei_irq_thread_ioctl(dev, slots, pos, cl, cmpl_list);
+ ret = _mei_irq_thread_ioctl(dev, &slots, pos,
+ cl, cmpl_list);
if (ret)
return ret;
@@ -1290,40 +994,26 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
}
/* complete write list CB */
dev_dbg(&dev->pdev->dev, "complete write list cb.\n");
- list_for_each_entry_safe(pos, next,
- &dev->write_list.mei_cb.cb_list, cb_list) {
- cl = (struct mei_cl *)pos->file_private;
+ list_for_each_entry_safe(pos, next, &dev->write_list.list, list) {
+ cl = pos->cl;
if (cl == NULL)
continue;
-
- if (cl != &dev->iamthif_cl) {
- if (mei_flow_ctrl_creds(dev, cl) <= 0) {
- dev_dbg(&dev->pdev->dev,
- "No flow control credentials for client %d, not sending.\n",
- cl->host_client_id);
- continue;
- }
- ret = _mei_irq_thread_cmpl(dev, slots, pos,
- cl, cmpl_list);
- if (ret)
- return ret;
-
- } else if (cl == &dev->iamthif_cl) {
- /* IAMTHIF IOCTL */
- dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n");
- if (mei_flow_ctrl_creds(dev, cl) <= 0) {
- dev_dbg(&dev->pdev->dev,
- "No flow control credentials for amthi client %d.\n",
- cl->host_client_id);
- continue;
- }
- ret = _mei_irq_thread_cmpl_iamthif(dev, slots, pos,
- cl, cmpl_list);
- if (ret)
- return ret;
-
+ if (mei_flow_ctrl_creds(dev, 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(dev, &slots,
+ pos, cmpl_list);
+ else
+ ret = mei_irq_thread_write_complete(dev, &slots, pos,
+ cmpl_list);
+ if (ret)
+ return ret;
+
}
return 0;
}
@@ -1342,7 +1032,6 @@ void mei_timer(struct work_struct *work)
unsigned long timeout;
struct mei_cl *cl_pos = NULL;
struct mei_cl *cl_next = NULL;
- struct list_head *amthi_complete_list = NULL;
struct mei_cl_cb *cb_pos = NULL;
struct mei_cl_cb *cb_next = NULL;
@@ -1385,19 +1074,18 @@ void mei_timer(struct work_struct *work)
dev->iamthif_state = MEI_IAMTHIF_IDLE;
dev->iamthif_timer = 0;
- if (dev->iamthif_current_cb)
- mei_free_cb_private(dev->iamthif_current_cb);
+ mei_io_cb_free(dev->iamthif_current_cb);
+ dev->iamthif_current_cb = NULL;
dev->iamthif_file_object = NULL;
- dev->iamthif_current_cb = NULL;
- mei_run_next_iamthif_cmd(dev);
+ mei_amthif_run_next_cmd(dev);
}
}
if (dev->iamthif_timer) {
timeout = dev->iamthif_timer +
- msecs_to_jiffies(IAMTHIF_READ_TIMER);
+ mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);
dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n",
dev->iamthif_timer);
@@ -1411,25 +1099,22 @@ void mei_timer(struct work_struct *work)
dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n");
- amthi_complete_list = &dev->amthi_read_complete_list.
- mei_cb.cb_list;
-
- list_for_each_entry_safe(cb_pos, cb_next, amthi_complete_list, cb_list) {
+ list_for_each_entry_safe(cb_pos, cb_next,
+ &dev->amthif_rd_complete_list.list, list) {
cl_pos = cb_pos->file_object->private_data;
/* Finding the AMTHI entry. */
if (cl_pos == &dev->iamthif_cl)
- list_del(&cb_pos->cb_list);
+ list_del(&cb_pos->list);
}
- if (dev->iamthif_current_cb)
- mei_free_cb_private(dev->iamthif_current_cb);
+ mei_io_cb_free(dev->iamthif_current_cb);
+ dev->iamthif_current_cb = NULL;
dev->iamthif_file_object->private_data = NULL;
dev->iamthif_file_object = NULL;
- dev->iamthif_current_cb = NULL;
dev->iamthif_timer = 0;
- mei_run_next_iamthif_cmd(dev);
+ mei_amthif_run_next_cmd(dev);
}
}
@@ -1451,7 +1136,7 @@ out:
irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
{
struct mei_device *dev = (struct mei_device *) dev_id;
- struct mei_io_list complete_list;
+ struct mei_cl_cb complete_list;
struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
struct mei_cl *cl;
s32 slots;
@@ -1504,17 +1189,17 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
}
/* check slots available for reading */
slots = mei_count_full_read_slots(dev);
- dev_dbg(&dev->pdev->dev, "slots =%08x extra_write_index =%08x.\n",
- slots, dev->extra_write_index);
- while (slots > 0 && !dev->extra_write_index) {
- dev_dbg(&dev->pdev->dev, "slots =%08x extra_write_index =%08x.\n",
- slots, dev->extra_write_index);
+ while (slots > 0) {
+ /* we have urgent data to send so break the read */
+ if (dev->wr_ext_msg.hdr.length)
+ break;
+ dev_dbg(&dev->pdev->dev, "slots =%08x\n", slots);
dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_handler.\n");
rets = mei_irq_thread_read_handler(&complete_list, dev, &slots);
if (rets)
goto end;
}
- rets = mei_irq_thread_write_handler(&complete_list, dev, &slots);
+ rets = mei_irq_thread_write_handler(dev, &complete_list);
end:
dev_dbg(&dev->pdev->dev, "end of bottom half function.\n");
dev->host_hw_state = mei_hcsr_read(dev);
@@ -1531,21 +1216,20 @@ end:
wake_up_interruptible(&dev->wait_recvd_msg);
bus_message_received = false;
}
- if (list_empty(&complete_list.mei_cb.cb_list))
+ if (list_empty(&complete_list.list))
return IRQ_HANDLED;
- list_for_each_entry_safe(cb_pos, cb_next,
- &complete_list.mei_cb.cb_list, cb_list) {
- cl = (struct mei_cl *)cb_pos->file_private;
- list_del(&cb_pos->cb_list);
+ list_for_each_entry_safe(cb_pos, cb_next, &complete_list.list, list) {
+ cl = cb_pos->cl;
+ list_del(&cb_pos->list);
if (cl) {
if (cl != &dev->iamthif_cl) {
dev_dbg(&dev->pdev->dev, "completing call back.\n");
_mei_cmpl(cl, cb_pos);
cb_pos = NULL;
} else if (cl == &dev->iamthif_cl) {
- _mei_cmpl_iamthif(dev, cb_pos);
+ mei_amthif_complete(dev, cb_pos);
}
}
}
diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c
index fcba98eb892..eb93a1b53b9 100644
--- a/drivers/misc/mei/iorw.c
+++ b/drivers/misc/mei/iorw.c
@@ -39,6 +39,95 @@
#include "interface.h"
/**
+ * mei_io_cb_free - free mei_cb_private related memory
+ *
+ * @cb: mei callback struct
+ */
+void mei_io_cb_free(struct mei_cl_cb *cb)
+{
+ if (cb == NULL)
+ return;
+
+ kfree(cb->request_buffer.data);
+ kfree(cb->response_buffer.data);
+ kfree(cb);
+}
+/**
+ * mei_io_cb_init - allocate and initialize io callback
+ *
+ * @cl - mei client
+ * @file: pointer to file structure
+ *
+ * returns mei_cl_cb pointer or NULL;
+ */
+struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp)
+{
+ struct mei_cl_cb *cb;
+
+ cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
+ if (!cb)
+ return NULL;
+
+ mei_io_list_init(cb);
+
+ cb->file_object = fp;
+ cb->cl = cl;
+ cb->buf_idx = 0;
+ return cb;
+}
+
+
+/**
+ * mei_io_cb_alloc_req_buf - allocate request buffer
+ *
+ * @cb - io callback structure
+ * @size: size of the buffer
+ *
+ * returns 0 on success
+ * -EINVAL if cb is NULL
+ * -ENOMEM if allocation failed
+ */
+int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length)
+{
+ if (!cb)
+ return -EINVAL;
+
+ if (length == 0)
+ return 0;
+
+ cb->request_buffer.data = kmalloc(length, GFP_KERNEL);
+ if (!cb->request_buffer.data)
+ return -ENOMEM;
+ cb->request_buffer.size = length;
+ return 0;
+}
+/**
+ * mei_io_cb_alloc_req_buf - allocate respose buffer
+ *
+ * @cb - io callback structure
+ * @size: size of the buffer
+ *
+ * returns 0 on success
+ * -EINVAL if cb is NULL
+ * -ENOMEM if allocation failed
+ */
+int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length)
+{
+ if (!cb)
+ return -EINVAL;
+
+ if (length == 0)
+ return 0;
+
+ cb->response_buffer.data = kmalloc(length, GFP_KERNEL);
+ if (!cb->response_buffer.data)
+ return -ENOMEM;
+ cb->response_buffer.size = length;
+ return 0;
+}
+
+
+/**
* mei_me_cl_by_id return index to me_clients for client_id
*
* @dev: the device structure
@@ -82,9 +171,7 @@ int mei_ioctl_connect_client(struct file *file,
struct mei_cl_cb *cb;
struct mei_client *client;
struct mei_cl *cl;
- struct mei_cl *cl_pos = NULL;
- struct mei_cl *cl_next = NULL;
- long timeout = CONNECT_TIMEOUT;
+ long timeout = mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT);
int i;
int err;
int rets;
@@ -97,16 +184,14 @@ int mei_ioctl_connect_client(struct file *file,
dev_dbg(&dev->pdev->dev, "mei_ioctl_connect_client() Entry\n");
-
/* buffered ioctl cb */
- cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
+ cb = mei_io_cb_init(cl, file);
if (!cb) {
rets = -ENOMEM;
goto end;
}
- INIT_LIST_HEAD(&cb->cb_list);
- cb->major_file_operations = MEI_IOCTL;
+ cb->fop_type = MEI_FOP_IOCTL;
if (dev->dev_state != MEI_DEV_ENABLED) {
rets = -ENODEV;
@@ -142,21 +227,9 @@ int mei_ioctl_connect_client(struct file *file,
goto end;
}
clear_bit(cl->host_client_id, dev->host_clients_map);
- list_for_each_entry_safe(cl_pos, cl_next,
- &dev->file_list, link) {
- if (mei_cl_cmp_id(cl, cl_pos)) {
- dev_dbg(&dev->pdev->dev,
- "remove file private data node host"
- " client = %d, ME client = %d.\n",
- cl_pos->host_client_id,
- cl_pos->me_client_id);
- list_del(&cl_pos->link);
- }
+ mei_me_cl_unlink(dev, cl);
- }
- dev_dbg(&dev->pdev->dev, "free file private data memory.\n");
kfree(cl);
-
cl = NULL;
file->private_data = &dev->iamthif_cl;
@@ -192,25 +265,19 @@ int mei_ioctl_connect_client(struct file *file,
} else {
dev_dbg(&dev->pdev->dev, "Sending connect message - succeeded\n");
cl->timer_count = MEI_CONNECT_TIMEOUT;
- cb->file_private = cl;
- list_add_tail(&cb->cb_list,
- &dev->ctrl_rd_list.mei_cb.
- cb_list);
+ list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
}
} else {
dev_dbg(&dev->pdev->dev, "Queuing the connect request due to device busy\n");
- cb->file_private = cl;
dev_dbg(&dev->pdev->dev, "add connect cb to control write list.\n");
- list_add_tail(&cb->cb_list,
- &dev->ctrl_wr_list.mei_cb.cb_list);
+ list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
}
mutex_unlock(&dev->device_lock);
err = wait_event_timeout(dev->wait_recvd_msg,
(MEI_FILE_CONNECTED == cl->state ||
- MEI_FILE_DISCONNECTED == cl->state),
- timeout * HZ);
+ MEI_FILE_DISCONNECTED == cl->state), timeout);
mutex_lock(&dev->device_lock);
if (MEI_FILE_CONNECTED == cl->state) {
@@ -234,153 +301,7 @@ int mei_ioctl_connect_client(struct file *file,
rets = 0;
end:
dev_dbg(&dev->pdev->dev, "free connect cb memory.");
- kfree(cb);
- return rets;
-}
-
-/**
- * find_amthi_read_list_entry - finds a amthilist entry for current file
- *
- * @dev: the device structure
- * @file: pointer to file object
- *
- * returns returned a list entry on success, NULL on failure.
- */
-struct mei_cl_cb *find_amthi_read_list_entry(
- struct mei_device *dev,
- struct file *file)
-{
- struct mei_cl *cl_temp;
- struct mei_cl_cb *pos = NULL;
- struct mei_cl_cb *next = NULL;
-
- list_for_each_entry_safe(pos, next,
- &dev->amthi_read_complete_list.mei_cb.cb_list, cb_list) {
- cl_temp = (struct mei_cl *)pos->file_private;
- if (cl_temp && cl_temp == &dev->iamthif_cl &&
- pos->file_object == file)
- return pos;
- }
- return NULL;
-}
-
-/**
- * amthi_read - read data from AMTHI client
- *
- * @dev: the device structure
- * @if_num: minor number
- * @file: pointer to file object
- * @*ubuf: pointer to user data in user space
- * @length: data length to read
- * @offset: data read offset
- *
- * Locking: called under "dev->device_lock" lock
- *
- * returns
- * returned data length on success,
- * zero if no data to read,
- * negative on failure.
- */
-int amthi_read(struct mei_device *dev, struct file *file,
- char __user *ubuf, size_t length, loff_t *offset)
-{
- int rets;
- int wait_ret;
- struct mei_cl_cb *cb = NULL;
- struct mei_cl *cl = file->private_data;
- unsigned long timeout;
- int i;
-
- /* Only Posible if we are in timeout */
- if (!cl || cl != &dev->iamthif_cl) {
- dev_dbg(&dev->pdev->dev, "bad file ext.\n");
- return -ETIMEDOUT;
- }
-
- i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id);
-
- if (i < 0) {
- dev_dbg(&dev->pdev->dev, "amthi client not found.\n");
- return -ENODEV;
- }
- dev_dbg(&dev->pdev->dev, "checking amthi data\n");
- cb = find_amthi_read_list_entry(dev, file);
-
- /* Check for if we can block or not*/
- if (cb == NULL && file->f_flags & O_NONBLOCK)
- return -EAGAIN;
-
-
- dev_dbg(&dev->pdev->dev, "waiting for amthi data\n");
- while (cb == NULL) {
- /* unlock the Mutex */
- mutex_unlock(&dev->device_lock);
-
- wait_ret = wait_event_interruptible(dev->iamthif_cl.wait,
- (cb = find_amthi_read_list_entry(dev, file)));
-
- if (wait_ret)
- return -ERESTARTSYS;
-
- dev_dbg(&dev->pdev->dev, "woke up from sleep\n");
-
- /* Locking again the Mutex */
- mutex_lock(&dev->device_lock);
- }
-
-
- dev_dbg(&dev->pdev->dev, "Got amthi data\n");
- dev->iamthif_timer = 0;
-
- if (cb) {
- timeout = cb->read_time + msecs_to_jiffies(IAMTHIF_READ_TIMER);
- dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n",
- timeout);
-
- if (time_after(jiffies, timeout)) {
- dev_dbg(&dev->pdev->dev, "amthi Time out\n");
- /* 15 sec for the message has expired */
- list_del(&cb->cb_list);
- rets = -ETIMEDOUT;
- goto free;
- }
- }
- /* if the whole message will fit remove it from the list */
- if (cb->information >= *offset && length >= (cb->information - *offset))
- list_del(&cb->cb_list);
- else if (cb->information > 0 && cb->information <= *offset) {
- /* end of the message has been reached */
- list_del(&cb->cb_list);
- rets = 0;
- goto free;
- }
- /* else means that not full buffer will be read and do not
- * remove message from deletion list
- */
-
- dev_dbg(&dev->pdev->dev, "amthi cb->response_buffer size - %d\n",
- cb->response_buffer.size);
- dev_dbg(&dev->pdev->dev, "amthi cb->information - %lu\n",
- cb->information);
-
- /* length is being turncated to PAGE_SIZE, however,
- * the information may be longer */
- length = min_t(size_t, length, (cb->information - *offset));
-
- if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length))
- rets = -EFAULT;
- else {
- rets = length;
- if ((*offset + length) < cb->information) {
- *offset += length;
- goto out;
- }
- }
-free:
- dev_dbg(&dev->pdev->dev, "free amthi cb memory.\n");
- *offset = 0;
- mei_free_cb_private(cb);
-out:
+ mei_io_cb_free(cb);
return rets;
}
@@ -396,7 +317,7 @@ out:
int mei_start_read(struct mei_device *dev, struct mei_cl *cl)
{
struct mei_cl_cb *cb;
- int rets = 0;
+ int rets;
int i;
if (cl->state != MEI_FILE_CONNECTED)
@@ -405,187 +326,41 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl)
if (dev->dev_state != MEI_DEV_ENABLED)
return -ENODEV;
- dev_dbg(&dev->pdev->dev, "check if read is pending.\n");
if (cl->read_pending || cl->read_cb) {
dev_dbg(&dev->pdev->dev, "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);
+ return -ENODEV;
+ }
- cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
+ cb = mei_io_cb_init(cl, NULL);
if (!cb)
return -ENOMEM;
- dev_dbg(&dev->pdev->dev, "allocation call back successful. host client = %d, ME client = %d\n",
- cl->host_client_id, cl->me_client_id);
- i = mei_me_cl_by_id(dev, cl->me_client_id);
- if (i < 0) {
- rets = -ENODEV;
- goto unlock;
- }
+ rets = mei_io_cb_alloc_resp_buf(cb,
+ dev->me_clients[i].props.max_msg_length);
+ if (rets)
+ goto err;
- cb->response_buffer.size = dev->me_clients[i].props.max_msg_length;
- cb->response_buffer.data =
- kmalloc(cb->response_buffer.size, GFP_KERNEL);
- if (!cb->response_buffer.data) {
- rets = -ENOMEM;
- goto unlock;
- }
- dev_dbg(&dev->pdev->dev, "allocation call back data success.\n");
- cb->major_file_operations = MEI_READ;
- /* make sure information is zero before we start */
- cb->information = 0;
- cb->file_private = (void *) cl;
+ cb->fop_type = MEI_FOP_READ;
cl->read_cb = cb;
if (dev->mei_host_buffer_is_empty) {
dev->mei_host_buffer_is_empty = false;
if (mei_send_flow_control(dev, cl)) {
rets = -ENODEV;
- goto unlock;
+ goto err;
}
- list_add_tail(&cb->cb_list, &dev->read_list.mei_cb.cb_list);
+ list_add_tail(&cb->list, &dev->read_list.list);
} else {
- list_add_tail(&cb->cb_list, &dev->ctrl_wr_list.mei_cb.cb_list);
+ list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
}
return rets;
-unlock:
- mei_free_cb_private(cb);
+err:
+ mei_io_cb_free(cb);
return rets;
}
-/**
- * amthi_write - write iamthif data to amthi client
- *
- * @dev: the device structure
- * @cb: mei call back struct
- *
- * returns 0 on success, <0 on failure.
- */
-int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb)
-{
- struct mei_msg_hdr mei_hdr;
- int ret;
-
- if (!dev || !cb)
- return -ENODEV;
-
- dev_dbg(&dev->pdev->dev, "write data to amthi client.\n");
-
- dev->iamthif_state = MEI_IAMTHIF_WRITING;
- dev->iamthif_current_cb = cb;
- dev->iamthif_file_object = cb->file_object;
- dev->iamthif_canceled = false;
- dev->iamthif_ioctl = true;
- dev->iamthif_msg_buf_size = cb->request_buffer.size;
- memcpy(dev->iamthif_msg_buf, cb->request_buffer.data,
- cb->request_buffer.size);
-
- ret = mei_flow_ctrl_creds(dev, &dev->iamthif_cl);
- if (ret < 0)
- return ret;
-
- if (ret && dev->mei_host_buffer_is_empty) {
- ret = 0;
- dev->mei_host_buffer_is_empty = false;
- if (cb->request_buffer.size > mei_hbuf_max_data(dev)) {
- mei_hdr.length = mei_hbuf_max_data(dev);
- mei_hdr.msg_complete = 0;
- } else {
- mei_hdr.length = cb->request_buffer.size;
- mei_hdr.msg_complete = 1;
- }
-
- mei_hdr.host_addr = dev->iamthif_cl.host_client_id;
- 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),
- mei_hdr.length))
- return -ENODEV;
-
- if (mei_hdr.msg_complete) {
- if (mei_flow_ctrl_reduce(dev, &dev->iamthif_cl))
- return -ENODEV;
- dev->iamthif_flow_control_pending = true;
- dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
- dev_dbg(&dev->pdev->dev, "add amthi cb to write waiting list\n");
- dev->iamthif_current_cb = cb;
- dev->iamthif_file_object = cb->file_object;
- list_add_tail(&cb->cb_list,
- &dev->write_waiting_list.mei_cb.cb_list);
- } else {
- dev_dbg(&dev->pdev->dev, "message does not complete, "
- "so add amthi cb to write list.\n");
- list_add_tail(&cb->cb_list,
- &dev->write_list.mei_cb.cb_list);
- }
- } else {
- if (!(dev->mei_host_buffer_is_empty))
- dev_dbg(&dev->pdev->dev, "host buffer is not empty");
-
- dev_dbg(&dev->pdev->dev, "No flow control credentials, "
- "so add iamthif cb to write list.\n");
- list_add_tail(&cb->cb_list, &dev->write_list.mei_cb.cb_list);
- }
- return 0;
-}
-
-/**
- * iamthif_ioctl_send_msg - send cmd data to amthi client
- *
- * @dev: the device structure
- *
- * returns 0 on success, <0 on failure.
- */
-void mei_run_next_iamthif_cmd(struct mei_device *dev)
-{
- struct mei_cl *cl_tmp;
- struct mei_cl_cb *pos = NULL;
- struct mei_cl_cb *next = NULL;
- int status;
-
- if (!dev)
- return;
-
- dev->iamthif_msg_buf_size = 0;
- dev->iamthif_msg_buf_index = 0;
- dev->iamthif_canceled = false;
- dev->iamthif_ioctl = true;
- dev->iamthif_state = MEI_IAMTHIF_IDLE;
- dev->iamthif_timer = 0;
- dev->iamthif_file_object = NULL;
-
- dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n");
-
- list_for_each_entry_safe(pos, next,
- &dev->amthi_cmd_list.mei_cb.cb_list, cb_list) {
- list_del(&pos->cb_list);
- cl_tmp = (struct mei_cl *)pos->file_private;
-
- if (cl_tmp && cl_tmp == &dev->iamthif_cl) {
- status = amthi_write(dev, pos);
- if (status) {
- dev_dbg(&dev->pdev->dev,
- "amthi write failed status = %d\n",
- status);
- return;
- }
- break;
- }
- }
-}
-
-/**
- * mei_free_cb_private - free mei_cb_private related memory
- *
- * @cb: mei callback struct
- */
-void mei_free_cb_private(struct mei_cl_cb *cb)
-{
- if (cb == NULL)
- return;
-
- kfree(cb->request_buffer.data);
- kfree(cb->response_buffer.data);
- kfree(cb);
-}
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index e8b0858132c..43fb52ff98a 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -90,93 +90,6 @@ static DEFINE_MUTEX(mei_mutex);
/**
- * mei_clear_list - removes all callbacks associated with file
- * from mei_cb_list
- *
- * @dev: device structure.
- * @file: file structure
- * @mei_cb_list: callbacks list
- *
- * mei_clear_list is called to clear resources associated with file
- * when application calls close function or Ctrl-C was pressed
- *
- * returns true if callback removed from the list, false otherwise
- */
-static bool mei_clear_list(struct mei_device *dev,
- struct file *file, struct list_head *mei_cb_list)
-{
- struct mei_cl_cb *cb_pos = NULL;
- struct mei_cl_cb *cb_next = NULL;
- struct file *file_temp;
- bool removed = false;
-
- /* list all list member */
- list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, cb_list) {
- file_temp = (struct file *)cb_pos->file_object;
- /* check if list member associated with a file */
- if (file_temp == file) {
- /* remove member from the list */
- list_del(&cb_pos->cb_list);
- /* check if cb equal to current iamthif cb */
- if (dev->iamthif_current_cb == cb_pos) {
- dev->iamthif_current_cb = NULL;
- /* send flow control to iamthif client */
- mei_send_flow_control(dev, &dev->iamthif_cl);
- }
- /* free all allocated buffers */
- mei_free_cb_private(cb_pos);
- cb_pos = NULL;
- removed = true;
- }
- }
- return removed;
-}
-
-/**
- * mei_clear_lists - removes all callbacks associated with file
- *
- * @dev: device structure
- * @file: file structure
- *
- * mei_clear_lists is called to clear resources associated with file
- * when application calls close function or Ctrl-C was pressed
- *
- * returns true if callback removed from the list, false otherwise
- */
-static bool mei_clear_lists(struct mei_device *dev, struct file *file)
-{
- bool removed = false;
-
- /* remove callbacks associated with a file */
- mei_clear_list(dev, file, &dev->amthi_cmd_list.mei_cb.cb_list);
- if (mei_clear_list(dev, file,
- &dev->amthi_read_complete_list.mei_cb.cb_list))
- removed = true;
-
- mei_clear_list(dev, file, &dev->ctrl_rd_list.mei_cb.cb_list);
-
- if (mei_clear_list(dev, file, &dev->ctrl_wr_list.mei_cb.cb_list))
- removed = true;
-
- if (mei_clear_list(dev, file, &dev->write_waiting_list.mei_cb.cb_list))
- removed = true;
-
- if (mei_clear_list(dev, file, &dev->write_list.mei_cb.cb_list))
- removed = true;
-
- /* check if iamthif_current_cb not NULL */
- if (dev->iamthif_current_cb && !removed) {
- /* check file and iamthif current cb association */
- if (dev->iamthif_current_cb->file_object == file) {
- /* remove cb */
- mei_free_cb_private(dev->iamthif_current_cb);
- dev->iamthif_current_cb = NULL;
- removed = true;
- }
- }
- return removed;
-}
-/**
* find_read_list_entry - find read list entry
*
* @dev: device structure
@@ -192,14 +105,9 @@ static struct mei_cl_cb *find_read_list_entry(
struct mei_cl_cb *next = NULL;
dev_dbg(&dev->pdev->dev, "remove read_list CB\n");
- list_for_each_entry_safe(pos, next,
- &dev->read_list.mei_cb.cb_list, cb_list) {
- struct mei_cl *cl_temp;
- cl_temp = (struct mei_cl *)pos->file_private;
-
- if (mei_cl_cmp_id(cl, cl_temp))
+ list_for_each_entry_safe(pos, next, &dev->read_list.list, list)
+ if (mei_cl_cmp_id(cl, pos->cl))
return pos;
- }
return NULL;
}
@@ -297,67 +205,51 @@ static int mei_release(struct inode *inode, struct file *file)
dev = cl->dev;
mutex_lock(&dev->device_lock);
- if (cl != &dev->iamthif_cl) {
- if (cl->state == MEI_FILE_CONNECTED) {
- cl->state = MEI_FILE_DISCONNECTING;
- dev_dbg(&dev->pdev->dev,
- "disconnecting client host client = %d, "
- "ME client = %d\n",
- cl->host_client_id,
- cl->me_client_id);
- rets = mei_disconnect_host_client(dev, cl);
- }
- mei_cl_flush_queues(cl);
- dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n",
+ if (cl == &dev->iamthif_cl) {
+ rets = mei_amthif_release(dev, file);
+ goto out;
+ }
+ if (cl->state == MEI_FILE_CONNECTED) {
+ cl->state = MEI_FILE_DISCONNECTING;
+ dev_dbg(&dev->pdev->dev,
+ "disconnecting client host client = %d, "
+ "ME client = %d\n",
cl->host_client_id,
cl->me_client_id);
+ rets = mei_disconnect_host_client(dev, cl);
+ }
+ mei_cl_flush_queues(cl);
+ dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n",
+ 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_me_cl_unlink(dev, cl);
- if (dev->open_handle_count > 0) {
- clear_bit(cl->host_client_id, dev->host_clients_map);
- dev->open_handle_count--;
- }
- mei_remove_client_from_file_list(dev, cl->host_client_id);
-
- /* free read cb */
- cb = NULL;
- if (cl->read_cb) {
- cb = find_read_list_entry(dev, cl);
- /* Remove entry from read list */
- if (cb)
- list_del(&cb->cb_list);
-
- cb = cl->read_cb;
- cl->read_cb = NULL;
- }
-
- file->private_data = NULL;
-
- if (cb) {
- mei_free_cb_private(cb);
- cb = NULL;
- }
+ /* free read cb */
+ cb = NULL;
+ if (cl->read_cb) {
+ cb = find_read_list_entry(dev, cl);
+ /* Remove entry from read list */
+ if (cb)
+ list_del(&cb->list);
- kfree(cl);
- } else {
- if (dev->open_handle_count > 0)
- dev->open_handle_count--;
-
- if (dev->iamthif_file_object == file &&
- dev->iamthif_state != MEI_IAMTHIF_IDLE) {
-
- dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n",
- dev->iamthif_state);
- dev->iamthif_canceled = true;
- if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) {
- dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n");
- mei_run_next_iamthif_cmd(dev);
- }
- }
+ cb = cl->read_cb;
+ cl->read_cb = NULL;
+ }
- if (mei_clear_lists(dev, file))
- dev->iamthif_state = MEI_IAMTHIF_IDLE;
+ file->private_data = NULL;
+ if (cb) {
+ mei_io_cb_free(cb);
+ cb = NULL;
}
+
+ kfree(cl);
+out:
mutex_unlock(&dev->device_lock);
return rets;
}
@@ -411,20 +303,19 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
}
if (cl == &dev->iamthif_cl) {
- rets = amthi_read(dev, file, ubuf, length, offset);
+ rets = mei_amthif_read(dev, file, ubuf, length, offset);
goto out;
}
- if (cl->read_cb && cl->read_cb->information > *offset) {
+ if (cl->read_cb && cl->read_cb->buf_idx > *offset) {
cb = cl->read_cb;
goto copy_buffer;
- } else if (cl->read_cb && cl->read_cb->information > 0 &&
- cl->read_cb->information <= *offset) {
+ } else if (cl->read_cb && cl->read_cb->buf_idx > 0 &&
+ cl->read_cb->buf_idx <= *offset) {
cb = cl->read_cb;
rets = 0;
goto free;
- } else if ((!cl->read_cb || !cl->read_cb->information) &&
- *offset > 0) {
+ } else if ((!cl->read_cb || !cl->read_cb->buf_idx) && *offset > 0) {
/*Offset needs to be cleaned for contiguous reads*/
*offset = 0;
rets = 0;
@@ -481,16 +372,15 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
copy_buffer:
dev_dbg(&dev->pdev->dev, "cb->response_buffer size - %d\n",
cb->response_buffer.size);
- dev_dbg(&dev->pdev->dev, "cb->information - %lu\n",
- cb->information);
- if (length == 0 || ubuf == NULL || *offset > cb->information) {
+ dev_dbg(&dev->pdev->dev, "cb->buf_idx - %lu\n", cb->buf_idx);
+ if (length == 0 || ubuf == NULL || *offset > cb->buf_idx) {
rets = -EMSGSIZE;
goto free;
}
- /* length is being truncated to PAGE_SIZE, however, */
- /* information size may be longer */
- length = min_t(size_t, length, (cb->information - *offset));
+ /* length is being truncated to PAGE_SIZE,
+ * however buf_idx may point beyond that */
+ length = min_t(size_t, length, cb->buf_idx - *offset);
if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) {
rets = -EFAULT;
@@ -499,15 +389,15 @@ copy_buffer:
rets = length;
*offset += length;
- if ((unsigned long)*offset < cb->information)
+ if ((unsigned long)*offset < cb->buf_idx)
goto out;
free:
cb_pos = find_read_list_entry(dev, cl);
/* Remove entry from read list */
if (cb_pos)
- list_del(&cb_pos->cb_list);
- mei_free_cb_private(cb);
+ list_del(&cb_pos->list);
+ mei_io_cb_free(cb);
cl->reading_state = MEI_IDLE;
cl->read_cb = NULL;
cl->read_pending = 0;
@@ -516,7 +406,6 @@ out:
mutex_unlock(&dev->device_lock);
return rets;
}
-
/**
* mei_write - the write function.
*
@@ -546,23 +435,39 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
mutex_lock(&dev->device_lock);
if (dev->dev_state != MEI_DEV_ENABLED) {
- mutex_unlock(&dev->device_lock);
- return -ENODEV;
+ rets = -ENODEV;
+ goto err;
}
+ i = mei_me_cl_by_id(dev, cl->me_client_id);
+ if (i < 0) {
+ rets = -ENODEV;
+ goto err;
+ }
+ if (length > dev->me_clients[i].props.max_msg_length || length <= 0) {
+ rets = -EMSGSIZE;
+ goto err;
+ }
+
+ if (cl->state != MEI_FILE_CONNECTED) {
+ rets = -ENODEV;
+ dev_err(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d",
+ cl->host_client_id, cl->me_client_id);
+ goto err;
+ }
if (cl == &dev->iamthif_cl) {
- write_cb = find_amthi_read_list_entry(dev, file);
+ write_cb = mei_amthif_find_read_list_entry(dev, file);
if (write_cb) {
timeout = write_cb->read_time +
- msecs_to_jiffies(IAMTHIF_READ_TIMER);
+ mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);
if (time_after(jiffies, timeout) ||
- cl->reading_state == MEI_READ_COMPLETE) {
- *offset = 0;
- list_del(&write_cb->cb_list);
- mei_free_cb_private(write_cb);
- write_cb = NULL;
+ cl->reading_state == MEI_READ_COMPLETE) {
+ *offset = 0;
+ list_del(&write_cb->list);
+ mei_io_cb_free(write_cb);
+ write_cb = NULL;
}
}
}
@@ -572,8 +477,8 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
*offset = 0;
write_cb = find_read_list_entry(dev, cl);
if (write_cb) {
- list_del(&write_cb->cb_list);
- mei_free_cb_private(write_cb);
+ list_del(&write_cb->list);
+ mei_io_cb_free(write_cb);
write_cb = NULL;
cl->reading_state = MEI_IDLE;
cl->read_cb = NULL;
@@ -583,24 +488,21 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
*offset = 0;
- write_cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
+ write_cb = mei_io_cb_init(cl, file);
if (!write_cb) {
- mutex_unlock(&dev->device_lock);
- return -ENOMEM;
+ dev_err(&dev->pdev->dev, "write cb allocation failed\n");
+ rets = -ENOMEM;
+ goto err;
}
+ rets = mei_io_cb_alloc_req_buf(write_cb, length);
+ if (rets)
+ goto err;
- write_cb->file_object = file;
- write_cb->file_private = cl;
- write_cb->request_buffer.data = kmalloc(length, GFP_KERNEL);
- rets = -ENOMEM;
- if (!write_cb->request_buffer.data)
- goto unlock_dev;
-
- dev_dbg(&dev->pdev->dev, "length =%d\n", (int) length);
+ dev_dbg(&dev->pdev->dev, "cb request size = %zd\n", length);
- rets = -EFAULT;
- if (copy_from_user(write_cb->request_buffer.data, ubuf, length))
- goto unlock_dev;
+ rets = copy_from_user(write_cb->request_buffer.data, ubuf, length);
+ if (rets)
+ goto err;
cl->sm_state = 0;
if (length == 4 &&
@@ -612,139 +514,71 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
write_cb->request_buffer.data, 4) == 0)))
cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT;
- INIT_LIST_HEAD(&write_cb->cb_list);
if (cl == &dev->iamthif_cl) {
- write_cb->response_buffer.data =
- kmalloc(dev->iamthif_mtu, GFP_KERNEL);
- if (!write_cb->response_buffer.data) {
- rets = -ENOMEM;
- goto unlock_dev;
- }
- if (dev->dev_state != MEI_DEV_ENABLED) {
- rets = -ENODEV;
- goto unlock_dev;
- }
- i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id);
- if (i < 0) {
- rets = -ENODEV;
- goto unlock_dev;
- }
- if (length > dev->me_clients[i].props.max_msg_length ||
- length <= 0) {
- rets = -EMSGSIZE;
- goto unlock_dev;
- }
+ rets = mei_amthif_write(dev, write_cb);
- write_cb->response_buffer.size = dev->iamthif_mtu;
- write_cb->major_file_operations = MEI_IOCTL;
- write_cb->information = 0;
- write_cb->request_buffer.size = length;
- if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) {
- rets = -ENODEV;
- goto unlock_dev;
- }
-
- if (!list_empty(&dev->amthi_cmd_list.mei_cb.cb_list) ||
- dev->iamthif_state != MEI_IAMTHIF_IDLE) {
- dev_dbg(&dev->pdev->dev, "amthi_state = %d\n",
- (int) dev->iamthif_state);
- dev_dbg(&dev->pdev->dev, "add amthi cb to amthi cmd waiting list\n");
- list_add_tail(&write_cb->cb_list,
- &dev->amthi_cmd_list.mei_cb.cb_list);
- rets = length;
- } else {
- dev_dbg(&dev->pdev->dev, "call amthi write\n");
- rets = amthi_write(dev, write_cb);
-
- if (rets) {
- dev_dbg(&dev->pdev->dev, "amthi write failed with status = %d\n",
- rets);
- goto unlock_dev;
- }
- rets = length;
+ if (rets) {
+ dev_err(&dev->pdev->dev,
+ "amthi write failed with status = %d\n", rets);
+ goto err;
}
mutex_unlock(&dev->device_lock);
- return rets;
+ return length;
}
- write_cb->major_file_operations = MEI_WRITE;
- /* make sure information is zero before we start */
-
- write_cb->information = 0;
- write_cb->request_buffer.size = length;
+ write_cb->fop_type = MEI_FOP_WRITE;
dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n",
cl->host_client_id, cl->me_client_id);
- if (cl->state != MEI_FILE_CONNECTED) {
- rets = -ENODEV;
- dev_dbg(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d",
- cl->host_client_id,
- cl->me_client_id);
- goto unlock_dev;
- }
- i = mei_me_cl_by_id(dev, cl->me_client_id);
- if (i < 0) {
- rets = -ENODEV;
- goto unlock_dev;
- }
- if (length > dev->me_clients[i].props.max_msg_length || length <= 0) {
- rets = -EINVAL;
- goto unlock_dev;
- }
- write_cb->file_private = cl;
-
rets = mei_flow_ctrl_creds(dev, cl);
if (rets < 0)
- goto unlock_dev;
+ goto err;
- if (rets && dev->mei_host_buffer_is_empty) {
- rets = 0;
- dev->mei_host_buffer_is_empty = false;
- if (length > mei_hbuf_max_data(dev)) {
- mei_hdr.length = mei_hbuf_max_data(dev);
- mei_hdr.msg_complete = 0;
- } else {
- mei_hdr.length = length;
- mei_hdr.msg_complete = 1;
- }
- mei_hdr.host_addr = cl->host_client_id;
- mei_hdr.me_addr = cl->me_client_id;
- mei_hdr.reserved = 0;
- dev_dbg(&dev->pdev->dev, "call mei_write_message header=%08x.\n",
- *((u32 *) &mei_hdr));
- if (mei_write_message(dev, &mei_hdr,
- (unsigned char *) (write_cb->request_buffer.data),
- mei_hdr.length)) {
- rets = -ENODEV;
- goto unlock_dev;
- }
+ if (rets == 0 || dev->mei_host_buffer_is_empty == false) {
+ write_cb->buf_idx = 0;
+ mei_hdr.msg_complete = 0;
cl->writing_state = MEI_WRITING;
- write_cb->information = mei_hdr.length;
- if (mei_hdr.msg_complete) {
- if (mei_flow_ctrl_reduce(dev, cl)) {
- rets = -ENODEV;
- goto unlock_dev;
- }
- list_add_tail(&write_cb->cb_list,
- &dev->write_waiting_list.mei_cb.cb_list);
- } else {
- list_add_tail(&write_cb->cb_list,
- &dev->write_list.mei_cb.cb_list);
- }
+ goto out;
+ }
+ dev->mei_host_buffer_is_empty = false;
+ if (length > mei_hbuf_max_data(dev)) {
+ mei_hdr.length = mei_hbuf_max_data(dev);
+ mei_hdr.msg_complete = 0;
} else {
+ mei_hdr.length = length;
+ mei_hdr.msg_complete = 1;
+ }
+ mei_hdr.host_addr = cl->host_client_id;
+ mei_hdr.me_addr = cl->me_client_id;
+ mei_hdr.reserved = 0;
+ dev_dbg(&dev->pdev->dev, "call mei_write_message header=%08x.\n",
+ *((u32 *) &mei_hdr));
+ if (mei_write_message(dev, &mei_hdr,
+ write_cb->request_buffer.data, mei_hdr.length)) {
+ rets = -ENODEV;
+ goto err;
+ }
+ cl->writing_state = MEI_WRITING;
+ write_cb->buf_idx = mei_hdr.length;
- write_cb->information = 0;
- cl->writing_state = MEI_WRITING;
- list_add_tail(&write_cb->cb_list,
- &dev->write_list.mei_cb.cb_list);
+out:
+ if (mei_hdr.msg_complete) {
+ if (mei_flow_ctrl_reduce(dev, cl)) {
+ rets = -ENODEV;
+ goto err;
+ }
+ list_add_tail(&write_cb->list, &dev->write_waiting_list.list);
+ } else {
+ list_add_tail(&write_cb->list, &dev->write_list.list);
}
+
mutex_unlock(&dev->device_lock);
return length;
-unlock_dev:
+err:
mutex_unlock(&dev->device_lock);
- mei_free_cb_private(write_cb);
+ mei_io_cb_free(write_cb);
return rets;
}
@@ -860,15 +694,7 @@ static unsigned int mei_poll(struct file *file, poll_table *wait)
if (cl == &dev->iamthif_cl) {
- mutex_unlock(&dev->device_lock);
- poll_wait(file, &dev->iamthif_cl.wait, wait);
- mutex_lock(&dev->device_lock);
- if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE &&
- dev->iamthif_file_object == file) {
- mask |= (POLLIN | POLLRDNORM);
- dev_dbg(&dev->pdev->dev, "run next amthi cb\n");
- mei_run_next_iamthif_cmd(dev);
- }
+ mask = mei_amthif_poll(dev, file, wait);
goto out;
}
@@ -917,7 +743,7 @@ static struct miscdevice mei_misc_device = {
*
* returns true if ME Interface is valid, false otherwise
*/
-static bool __devinit mei_quirk_probe(struct pci_dev *pdev,
+static bool mei_quirk_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
u32 reg;
@@ -939,7 +765,7 @@ static bool __devinit mei_quirk_probe(struct pci_dev *pdev,
*
* returns 0 on success, <0 on failure.
*/
-static int __devinit mei_probe(struct pci_dev *pdev,
+static int mei_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct mei_device *dev;
@@ -1003,6 +829,8 @@ static int __devinit mei_probe(struct pci_dev *pdev,
goto disable_msi;
}
INIT_DELAYED_WORK(&dev->timer_work, mei_timer);
+ INIT_WORK(&dev->init_work, mei_host_client_init);
+
if (mei_hw_init(dev)) {
dev_err(&pdev->dev, "init hw failure.\n");
err = -ENODEV;
@@ -1054,7 +882,7 @@ end:
* mei_remove is called by the PCI subsystem to alert the driver
* that it should release a PCI device.
*/
-static void __devexit mei_remove(struct pci_dev *pdev)
+static void mei_remove(struct pci_dev *pdev)
{
struct mei_device *dev;
@@ -1087,8 +915,8 @@ static void __devexit mei_remove(struct pci_dev *pdev)
/* remove entry if already in list */
dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n");
- mei_remove_client_from_file_list(dev, dev->wd_cl.host_client_id);
- mei_remove_client_from_file_list(dev, dev->iamthif_cl.host_client_id);
+ mei_me_cl_unlink(dev, &dev->wd_cl);
+ mei_me_cl_unlink(dev, &dev->iamthif_cl);
dev->iamthif_current_cb = NULL;
dev->me_clients_num = 0;
@@ -1195,8 +1023,8 @@ static struct pci_driver mei_driver = {
.name = KBUILD_MODNAME,
.id_table = mei_pci_tbl,
.probe = mei_probe,
- .remove = __devexit_p(mei_remove),
- .shutdown = __devexit_p(mei_remove),
+ .remove = mei_remove,
+ .shutdown = mei_remove,
.driver.pm = MEI_PM_OPS,
};
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index adb35fb9281..25da04549d0 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -19,6 +19,7 @@
#include <linux/types.h>
#include <linux/watchdog.h>
+#include <linux/poll.h>
#include <linux/mei.h>
#include "hw.h"
@@ -125,13 +126,20 @@ enum mei_wd_states {
MEI_WD_STOPPING,
};
-/* MEI CB */
-enum mei_cb_major_types {
- MEI_READ = 0,
- MEI_WRITE,
- MEI_IOCTL,
- MEI_OPEN,
- MEI_CLOSE
+/**
+ * enum mei_cb_file_ops - file operation associated with the callback
+ * @MEI_FOP_READ - read
+ * @MEI_FOP_WRITE - write
+ * @MEI_FOP_IOCTL - ioctl
+ * @MEI_FOP_OPEN - open
+ * @MEI_FOP_CLOSE - close
+ */
+enum mei_cb_file_ops {
+ MEI_FOP_READ = 0,
+ MEI_FOP_WRITE,
+ MEI_FOP_IOCTL,
+ MEI_FOP_OPEN,
+ MEI_FOP_CLOSE
};
/*
@@ -143,13 +151,21 @@ struct mei_message_data {
};
+struct mei_cl;
+
+/**
+ * struct mei_cl_cb - file operation callback structure
+ *
+ * @cl - file client who is running this operation
+ * @fop_type - file operation type
+ */
struct mei_cl_cb {
- struct list_head cb_list;
- enum mei_cb_major_types major_file_operations;
- void *file_private;
+ struct list_head list;
+ struct mei_cl *cl;
+ enum mei_cb_file_ops fop_type;
struct mei_message_data request_buffer;
struct mei_message_data response_buffer;
- unsigned long information;
+ unsigned long buf_idx;
unsigned long read_time;
struct file *file_object;
};
@@ -175,29 +191,23 @@ struct mei_cl {
struct mei_cl_cb *read_cb;
};
-struct mei_io_list {
- struct mei_cl_cb mei_cb;
-};
-
/**
- * struct mei_deive - MEI private device struct
+ * struct mei_device - MEI private device struct
* @hbuf_depth - depth of host(write) buffer
+ * @wr_ext_msg - buffer for hbm control responses (set in read cycle)
*/
struct mei_device {
struct pci_dev *pdev; /* pointer to pci device struct */
/*
* lists of queues
*/
- /* array of pointers to aio lists */
- struct mei_io_list read_list; /* driver read queue */
- struct mei_io_list write_list; /* driver write queue */
- struct mei_io_list write_waiting_list; /* write waiting queue */
- struct mei_io_list ctrl_wr_list; /* managed write IOCTL list */
- struct mei_io_list ctrl_rd_list; /* managed read IOCTL list */
- struct mei_io_list amthi_cmd_list; /* amthi list for cmd waiting */
-
- /* driver managed amthi list for reading completed amthi cmd data */
- struct mei_io_list amthi_read_complete_list;
+ /* array of pointers to aio lists */
+ struct mei_cl_cb read_list; /* driver read queue */
+ struct mei_cl_cb write_list; /* driver write queue */
+ struct mei_cl_cb write_waiting_list; /* write waiting queue */
+ struct mei_cl_cb ctrl_wr_list; /* managed write IOCTL list */
+ struct mei_cl_cb ctrl_rd_list; /* managed read IOCTL list */
+
/*
* list of files
*/
@@ -235,11 +245,13 @@ struct mei_device {
u16 init_clients_timer;
bool need_reset;
- u32 extra_write_index;
unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */
- u32 wr_msg_buf[128]; /* used for control messages */
- u32 ext_msg_buf[8]; /* for control responses */
u32 rd_msg_hdr;
+ u32 wr_msg_buf[128]; /* used for control messages */
+ struct {
+ struct mei_msg_hdr hdr;
+ unsigned char data[4]; /* All HBM messages are 4 bytes */
+ } wr_ext_msg; /* for control responses */
struct hbm_version version;
@@ -253,12 +265,15 @@ struct mei_device {
struct mei_cl wd_cl;
enum mei_wd_states wd_state;
- bool wd_interface_reg;
bool wd_pending;
u16 wd_timeout;
unsigned char wd_data[MEI_WD_START_MSG_SIZE];
+ /* amthif list for cmd waiting */
+ struct mei_cl_cb amthif_cmd_list;
+ /* driver managed amthif list for reading completed amthif cmd data */
+ struct mei_cl_cb amthif_rd_complete_list;
struct file *iamthif_file_object;
struct mei_cl iamthif_cl;
struct mei_cl_cb *iamthif_current_cb;
@@ -272,8 +287,15 @@ struct mei_device {
bool iamthif_flow_control_pending;
bool iamthif_ioctl;
bool iamthif_canceled;
+
+ struct work_struct init_work;
};
+static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
+{
+ return msecs_to_jiffies(sec * MSEC_PER_SEC);
+}
+
/*
* mei init function prototypes
@@ -284,21 +306,34 @@ int mei_hw_init(struct mei_device *dev);
int mei_task_initialize_clients(void *data);
int mei_initialize_clients(struct mei_device *dev);
int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl);
-void mei_remove_client_from_file_list(struct mei_device *dev, u8 host_client_id);
-void mei_host_init_iamthif(struct mei_device *dev);
void mei_allocate_me_clients_storage(struct mei_device *dev);
-int mei_me_cl_update_filext(struct mei_device *dev, struct mei_cl *cl,
+int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl,
const uuid_le *cguid, u8 host_client_id);
+void mei_me_cl_unlink(struct mei_device *dev, struct mei_cl *cl);
int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid);
int mei_me_cl_by_id(struct mei_device *dev, u8 client_id);
/*
- * MEI IO List Functions
+ * MEI IO Functions
+ */
+struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp);
+void mei_io_cb_free(struct mei_cl_cb *priv_cb);
+int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length);
+int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length);
+
+
+/**
+ * mei_io_list_init - Sets up a queue list.
+ *
+ * @list: An instance cl callback structure
*/
-void mei_io_list_init(struct mei_io_list *list);
-void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl);
+static inline void mei_io_list_init(struct mei_cl_cb *list)
+{
+ INIT_LIST_HEAD(&list->list);
+}
+void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl);
/*
* MEI ME Client Functions
@@ -330,7 +365,8 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
*/
void mei_host_start_message(struct mei_device *dev);
void mei_host_enum_clients_message(struct mei_device *dev);
-int mei_host_client_properties(struct mei_device *dev);
+int mei_host_client_enumerate(struct mei_device *dev);
+void mei_host_client_init(struct work_struct *work);
/*
* MEI interrupt functions prototype
@@ -347,18 +383,40 @@ int mei_ioctl_connect_client(struct file *file,
int mei_start_read(struct mei_device *dev, struct mei_cl *cl);
-int amthi_write(struct mei_device *dev, struct mei_cl_cb *priv_cb);
-int amthi_read(struct mei_device *dev, struct file *file,
- char __user *ubuf, size_t length, loff_t *offset);
+/*
+ * AMTHIF - AMT Host Interface Functions
+ */
+void mei_amthif_reset_params(struct mei_device *dev);
+
+void mei_amthif_host_init(struct mei_device *dev);
+
+int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *priv_cb);
-struct mei_cl_cb *find_amthi_read_list_entry(struct mei_device *dev,
+int mei_amthif_read(struct mei_device *dev, struct file *file,
+ char __user *ubuf, size_t length, loff_t *offset);
+
+unsigned int mei_amthif_poll(struct mei_device *dev,
+ struct file *file, poll_table *wait);
+
+int mei_amthif_release(struct mei_device *dev, struct file *file);
+
+struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev,
struct file *file);
-void mei_run_next_iamthif_cmd(struct mei_device *dev);
+void mei_amthif_run_next_cmd(struct mei_device *dev);
+
-void mei_free_cb_private(struct mei_cl_cb *priv_cb);
+int mei_amthif_read_message(struct mei_cl_cb *complete_list,
+ struct mei_device *dev, struct mei_msg_hdr *mei_hdr);
+int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
+ struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list);
+
+void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb);
+int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list,
+ struct mei_device *dev, struct mei_msg_hdr *mei_hdr);
+int mei_amthif_irq_read(struct mei_device *dev, s32 *slots);
/*
* Register Access Function
@@ -437,4 +495,15 @@ void mei_csr_clear_his(struct mei_device *dev);
void mei_enable_interrupts(struct mei_device *dev);
void mei_disable_interrupts(struct mei_device *dev);
+static inline struct mei_msg_hdr *mei_hbm_hdr(u32 *buf, size_t length)
+{
+ struct mei_msg_hdr *hdr = (struct mei_msg_hdr *)buf;
+ hdr->host_addr = 0;
+ hdr->me_addr = 0;
+ hdr->length = length;
+ hdr->msg_complete = 1;
+ hdr->reserved = 0;
+ return hdr;
+}
+
#endif
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index d96c537f046..636409f9667 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -62,6 +62,7 @@ static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout)
*/
int mei_wd_host_init(struct mei_device *dev)
{
+ int id;
mei_cl_init(&dev->wd_cl, dev);
/* look for WD client and connect to it */
@@ -69,12 +70,11 @@ int mei_wd_host_init(struct mei_device *dev)
dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT;
dev->wd_state = MEI_WD_IDLE;
- /* find ME WD client */
- mei_me_cl_update_filext(dev, &dev->wd_cl,
+ /* Connect WD ME client to the host client */
+ id = mei_me_cl_link(dev, &dev->wd_cl,
&mei_wd_guid, MEI_WD_HOST_CLIENT_ID);
- dev_dbg(&dev->pdev->dev, "wd: check client\n");
- if (MEI_FILE_CONNECTING != dev->wd_cl.state) {
+ if (id < 0) {
dev_info(&dev->pdev->dev, "wd: failed to find the client\n");
return -ENOENT;
}
@@ -85,7 +85,7 @@ int mei_wd_host_init(struct mei_device *dev)
dev->wd_cl.host_client_id = 0;
return -EIO;
}
- dev->wd_cl.timer_count = CONNECT_TIMEOUT;
+ dev->wd_cl.timer_count = MEI_CONNECT_TIMEOUT;
return 0;
}
@@ -360,23 +360,20 @@ void mei_watchdog_register(struct mei_device *dev)
if (watchdog_register_device(&amt_wd_dev)) {
dev_err(&dev->pdev->dev,
"wd: unable to register watchdog device.\n");
- dev->wd_interface_reg = false;
return;
}
dev_dbg(&dev->pdev->dev,
"wd: successfully register watchdog interface.\n");
- dev->wd_interface_reg = true;
watchdog_set_drvdata(&amt_wd_dev, dev);
}
void mei_watchdog_unregister(struct mei_device *dev)
{
- if (!dev->wd_interface_reg)
+ if (test_bit(WDOG_UNREGISTERED, &amt_wd_dev.status))
return;
watchdog_set_drvdata(&amt_wd_dev, NULL);
watchdog_unregister_device(&amt_wd_dev);
- dev->wd_interface_reg = false;
}
diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c
index c9f20dae185..931e635aa49 100644
--- a/drivers/misc/pch_phub.c
+++ b/drivers/misc/pch_phub.c
@@ -666,7 +666,7 @@ static struct bin_attribute pch_bin_attr = {
.write = pch_phub_bin_write,
};
-static int __devinit pch_phub_probe(struct pci_dev *pdev,
+static int pch_phub_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
int retval;
@@ -819,7 +819,7 @@ err_pci_enable_dev:
return ret;
}
-static void __devexit pch_phub_remove(struct pci_dev *pdev)
+static void pch_phub_remove(struct pci_dev *pdev)
{
struct pch_phub_reg *chip = pci_get_drvdata(pdev);
@@ -888,7 +888,7 @@ static struct pci_driver pch_phub_driver = {
.name = "pch_phub",
.id_table = pch_phub_pcidev_id,
.probe = pch_phub_probe,
- .remove = __devexit_p(pch_phub_remove),
+ .remove = pch_phub_remove,
.suspend = pch_phub_suspend,
.resume = pch_phub_resume
};
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
index 21b28fc6d91..68b7c773d2c 100644
--- a/drivers/misc/phantom.c
+++ b/drivers/misc/phantom.c
@@ -324,7 +324,7 @@ static irqreturn_t phantom_isr(int irq, void *data)
* Init and deinit driver
*/
-static unsigned int __devinit phantom_get_free(void)
+static unsigned int phantom_get_free(void)
{
unsigned int i;
@@ -335,7 +335,7 @@ static unsigned int __devinit phantom_get_free(void)
return i;
}
-static int __devinit phantom_probe(struct pci_dev *pdev,
+static int phantom_probe(struct pci_dev *pdev,
const struct pci_device_id *pci_id)
{
struct phantom_device *pht;
@@ -435,7 +435,7 @@ err:
return retval;
}
-static void __devexit phantom_remove(struct pci_dev *pdev)
+static void phantom_remove(struct pci_dev *pdev)
{
struct phantom_device *pht = pci_get_drvdata(pdev);
unsigned int minor = MINOR(pht->cdev.dev);
@@ -487,7 +487,7 @@ static int phantom_resume(struct pci_dev *pdev)
#define phantom_resume NULL
#endif
-static struct pci_device_id phantom_pci_tbl[] __devinitdata = {
+static struct pci_device_id phantom_pci_tbl[] = {
{ .vendor = PCI_VENDOR_ID_PLX, .device = PCI_DEVICE_ID_PLX_9050,
.subvendor = PCI_VENDOR_ID_PLX, .subdevice = PCI_DEVICE_ID_PLX_9050,
.class = PCI_CLASS_BRIDGE_OTHER << 8, .class_mask = 0xffff00 },
@@ -499,7 +499,7 @@ static struct pci_driver phantom_pci_driver = {
.name = "phantom",
.id_table = phantom_pci_tbl,
.probe = phantom_probe,
- .remove = __devexit_p(phantom_remove),
+ .remove = phantom_remove,
.suspend = phantom_suspend,
.resume = phantom_resume
};
diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c
index 4999b34b7a6..f84ff0c0603 100644
--- a/drivers/misc/pti.c
+++ b/drivers/misc/pti.c
@@ -76,7 +76,7 @@ struct pti_dev {
*/
static DEFINE_MUTEX(alloclock);
-static const struct pci_device_id pci_ids[] __devinitconst = {
+static const struct pci_device_id pci_ids[] = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x82B)},
{0}
};
@@ -796,7 +796,7 @@ static const struct tty_port_operations tty_port_ops = {
* 0 for success
* otherwise, error
*/
-static int __devinit pti_pci_probe(struct pci_dev *pdev,
+static int pti_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
unsigned int a;
@@ -879,14 +879,17 @@ err:
* PCI bus.
* @pdev: variable containing pci info of PTI.
*/
-static void __devexit pti_pci_remove(struct pci_dev *pdev)
+static void pti_pci_remove(struct pci_dev *pdev)
{
struct pti_dev *drv_data = pci_get_drvdata(pdev);
+ unsigned int a;
unregister_console(&pti_console);
- tty_unregister_device(pti_tty_driver, 0);
- tty_unregister_device(pti_tty_driver, 1);
+ for (a = 0; a < PTITTY_MINOR_NUM; a++) {
+ tty_unregister_device(pti_tty_driver, a);
+ tty_port_destroy(&drv_data->port[a]);
+ }
iounmap(drv_data->pti_ioaddr);
pci_set_drvdata(pdev, NULL);
@@ -901,7 +904,7 @@ static struct pci_driver pti_pci_driver = {
.name = PCINAME,
.id_table = pci_ids,
.probe = pti_pci_probe,
- .remove = __devexit_p(pti_pci_remove),
+ .remove = pti_pci_remove,
};
/**
diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c
index 123ed98eec3..7deb25dc86a 100644
--- a/drivers/misc/spear13xx_pcie_gadget.c
+++ b/drivers/misc/spear13xx_pcie_gadget.c
@@ -711,7 +711,7 @@ static void spear13xx_pcie_device_init(struct spear_pcie_gadget_config *config)
spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
}
-static int __devinit spear_pcie_gadget_probe(struct platform_device *pdev)
+static int spear_pcie_gadget_probe(struct platform_device *pdev)
{
struct resource *res0, *res1;
unsigned int status = 0;
@@ -853,7 +853,7 @@ err_rel_res0:
return status;
}
-static int __devexit spear_pcie_gadget_remove(struct platform_device *pdev)
+static int spear_pcie_gadget_remove(struct platform_device *pdev)
{
struct resource *res0, *res1;
static struct pcie_gadget_target *target;
diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c
index 46937b10726..b90a2241d79 100644
--- a/drivers/misc/ti-st/st_core.c
+++ b/drivers/misc/ti-st/st_core.c
@@ -511,7 +511,6 @@ long st_register(struct st_proto_s *new_proto)
unsigned long flags = 0;
st_kim_ref(&st_gdata, 0);
- pr_info("%s(%d) ", __func__, new_proto->chnl_id);
if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL
|| new_proto->reg_complete_cb == NULL) {
pr_err("gdata/new_proto/recv or reg_complete_cb not ready");
diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c
index 04a819944f6..9ff942a346e 100644
--- a/drivers/misc/ti-st/st_kim.c
+++ b/drivers/misc/ti-st/st_kim.c
@@ -705,9 +705,9 @@ static const struct file_operations list_debugfs_fops = {
static struct dentry *kim_debugfs_dir;
static int kim_probe(struct platform_device *pdev)
{
- long status;
struct kim_data_s *kim_gdata;
struct ti_st_plat_data *pdata = pdev->dev.platform_data;
+ int err;
if ((pdev->id != -1) && (pdev->id < MAX_ST_DEVICES)) {
/* multiple devices could exist */
@@ -724,10 +724,11 @@ static int kim_probe(struct platform_device *pdev)
}
dev_set_drvdata(&pdev->dev, kim_gdata);
- status = st_core_init(&kim_gdata->core_data);
- if (status != 0) {
+ err = st_core_init(&kim_gdata->core_data);
+ if (err != 0) {
pr_err(" ST core init failed");
- return -EIO;
+ err = -EIO;
+ goto err_core_init;
}
/* refer to itself */
kim_gdata->core_data->kim_data = kim_gdata;
@@ -738,10 +739,10 @@ static int kim_probe(struct platform_device *pdev)
init_completion(&kim_gdata->kim_rcvd);
init_completion(&kim_gdata->ldisc_installed);
- status = sysfs_create_group(&pdev->dev.kobj, &uim_attr_grp);
- if (status) {
+ err = sysfs_create_group(&pdev->dev.kobj, &uim_attr_grp);
+ if (err) {
pr_err("failed to create sysfs entries");
- return status;
+ goto err_sysfs_group;
}
/* copying platform data */
@@ -753,8 +754,8 @@ static int kim_probe(struct platform_device *pdev)
kim_debugfs_dir = debugfs_create_dir("ti-st", NULL);
if (IS_ERR(kim_debugfs_dir)) {
pr_err(" debugfs entries creation failed ");
- kim_debugfs_dir = NULL;
- return -EIO;
+ err = -EIO;
+ goto err_debugfs_dir;
}
debugfs_create_file("version", S_IRUGO, kim_debugfs_dir,
@@ -763,6 +764,17 @@ static int kim_probe(struct platform_device *pdev)
kim_gdata, &list_debugfs_fops);
pr_info(" debugfs entries created ");
return 0;
+
+err_debugfs_dir:
+ sysfs_remove_group(&pdev->dev.kobj, &uim_attr_grp);
+
+err_sysfs_group:
+ st_core_exit(kim_gdata->core_data);
+
+err_core_init:
+ kfree(kim_gdata);
+
+ return err;
}
static int kim_remove(struct platform_device *pdev)
diff --git a/drivers/misc/ti_dac7512.c b/drivers/misc/ti_dac7512.c
index 5acbba120de..1d86407189e 100644
--- a/drivers/misc/ti_dac7512.c
+++ b/drivers/misc/ti_dac7512.c
@@ -54,7 +54,7 @@ static const struct attribute_group dac7512_attr_group = {
.attrs = dac7512_attributes,
};
-static int __devinit dac7512_probe(struct spi_device *spi)
+static int dac7512_probe(struct spi_device *spi)
{
int ret;
@@ -67,7 +67,7 @@ static int __devinit dac7512_probe(struct spi_device *spi)
return sysfs_create_group(&spi->dev.kobj, &dac7512_attr_group);
}
-static int __devexit dac7512_remove(struct spi_device *spi)
+static int dac7512_remove(struct spi_device *spi)
{
sysfs_remove_group(&spi->dev.kobj, &dac7512_attr_group);
return 0;
@@ -79,7 +79,7 @@ static struct spi_driver dac7512_driver = {
.owner = THIS_MODULE,
},
.probe = dac7512_probe,
- .remove = __devexit_p(dac7512_remove),
+ .remove = dac7512_remove,
};
module_spi_driver(dac7512_driver);
diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c
index 0beb298a17d..1e7bc0eb081 100644
--- a/drivers/misc/tsl2550.c
+++ b/drivers/misc/tsl2550.c
@@ -347,7 +347,7 @@ static int tsl2550_init_client(struct i2c_client *client)
*/
static struct i2c_driver tsl2550_driver;
-static int __devinit tsl2550_probe(struct i2c_client *client,
+static int tsl2550_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
@@ -405,7 +405,7 @@ exit:
return err;
}
-static int __devexit tsl2550_remove(struct i2c_client *client)
+static int tsl2550_remove(struct i2c_client *client)
{
sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
@@ -450,7 +450,7 @@ static struct i2c_driver tsl2550_driver = {
.suspend = tsl2550_suspend,
.resume = tsl2550_resume,
.probe = tsl2550_probe,
- .remove = __devexit_p(tsl2550_remove),
+ .remove = tsl2550_remove,
.id_table = tsl2550_id,
};
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 172a768036d..21056b9ef0a 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -57,6 +57,7 @@ MODULE_ALIAS("mmc:block");
#define INAND_CMD38_ARG_SECERASE 0x80
#define INAND_CMD38_ARG_SECTRIM1 0x81
#define INAND_CMD38_ARG_SECTRIM2 0x88
+#define MMC_BLK_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */
static DEFINE_MUTEX(block_mutex);
@@ -126,6 +127,10 @@ enum mmc_blk_status {
module_param(perdev_minors, int, 0444);
MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device");
+static inline int mmc_blk_part_switch(struct mmc_card *card,
+ struct mmc_blk_data *md);
+static int get_card_status(struct mmc_card *card, u32 *status, int retries);
+
static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
{
struct mmc_blk_data *md;
@@ -357,6 +362,38 @@ out:
return ERR_PTR(err);
}
+static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status,
+ u32 retries_max)
+{
+ int err;
+ u32 retry_count = 0;
+
+ if (!status || !retries_max)
+ return -EINVAL;
+
+ do {
+ err = get_card_status(card, status, 5);
+ if (err)
+ break;
+
+ if (!R1_STATUS(*status) &&
+ (R1_CURRENT_STATE(*status) != R1_STATE_PRG))
+ break; /* RPMB programming operation complete */
+
+ /*
+ * Rechedule to give the MMC device a chance to continue
+ * processing the previous command without being polled too
+ * frequently.
+ */
+ usleep_range(1000, 5000);
+ } while (++retry_count < retries_max);
+
+ if (retry_count == retries_max)
+ err = -EPERM;
+
+ return err;
+}
+
static int mmc_blk_ioctl_cmd(struct block_device *bdev,
struct mmc_ioc_cmd __user *ic_ptr)
{
@@ -368,6 +405,8 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
struct mmc_request mrq = {NULL};
struct scatterlist sg;
int err;
+ int is_rpmb = false;
+ u32 status = 0;
/*
* The caller must have CAP_SYS_RAWIO, and must be calling this on the
@@ -387,6 +426,9 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
goto cmd_err;
}
+ if (md->area_type & MMC_BLK_DATA_AREA_RPMB)
+ is_rpmb = true;
+
card = md->queue.card;
if (IS_ERR(card)) {
err = PTR_ERR(card);
@@ -437,12 +479,23 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
mmc_claim_host(card->host);
+ err = mmc_blk_part_switch(card, md);
+ if (err)
+ goto cmd_rel_host;
+
if (idata->ic.is_acmd) {
err = mmc_app_cmd(card->host, card);
if (err)
goto cmd_rel_host;
}
+ if (is_rpmb) {
+ err = mmc_set_blockcount(card, data.blocks,
+ idata->ic.write_flag & (1 << 31));
+ if (err)
+ goto cmd_rel_host;
+ }
+
mmc_wait_for_req(card->host, &mrq);
if (cmd.error) {
@@ -478,6 +531,18 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
}
}
+ if (is_rpmb) {
+ /*
+ * Ensure RPMB command has completed by polling CMD13
+ * "Send Status".
+ */
+ err = ioctl_rpmb_card_status_poll(card, &status, 5);
+ if (err)
+ dev_err(mmc_dev(card->host),
+ "%s: Card Status=0x%08X, error %d\n",
+ __func__, status, err);
+ }
+
cmd_rel_host:
mmc_release_host(card->host);
@@ -1034,6 +1099,9 @@ static int mmc_blk_err_check(struct mmc_card *card,
*/
if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
u32 status;
+ unsigned long timeout;
+
+ timeout = jiffies + msecs_to_jiffies(MMC_BLK_TIMEOUT_MS);
do {
int err = get_card_status(card, &status, 5);
if (err) {
@@ -1041,6 +1109,17 @@ static int mmc_blk_err_check(struct mmc_card *card,
req->rq_disk->disk_name, err);
return MMC_BLK_CMD_ERR;
}
+
+ /* Timeout if the device never becomes ready for data
+ * and never leaves the program state.
+ */
+ if (time_after(jiffies, timeout)) {
+ pr_err("%s: Card stuck in programming state!"\
+ " %s %s\n", mmc_hostname(card->host),
+ req->rq_disk->disk_name, __func__);
+
+ return MMC_BLK_CMD_ERR;
+ }
/*
* Some cards mishandle the status bits,
* so make sure to check both the busy
@@ -1504,6 +1583,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
md->disk->queue = md->queue.queue;
md->disk->driverfs_dev = parent;
set_disk_ro(md->disk, md->read_only || default_ro);
+ if (area_type & MMC_BLK_DATA_AREA_RPMB)
+ md->disk->flags |= GENHD_FL_NO_PART_SCAN;
/*
* As discussed on lkml, GENHD_FL_REMOVABLE should:
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index e360a979857..fadf52eb5d7 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -68,6 +68,16 @@ static int mmc_queue_thread(void *d)
if (req || mq->mqrq_prev->req) {
set_current_state(TASK_RUNNING);
mq->issue_fn(mq, req);
+
+ /*
+ * Current request becomes previous request
+ * and vice versa.
+ */
+ mq->mqrq_prev->brq.mrq.data = NULL;
+ mq->mqrq_prev->req = NULL;
+ tmp = mq->mqrq_prev;
+ mq->mqrq_prev = mq->mqrq_cur;
+ mq->mqrq_cur = tmp;
} else {
if (kthread_should_stop()) {
set_current_state(TASK_RUNNING);
@@ -77,13 +87,6 @@ static int mmc_queue_thread(void *d)
schedule();
down(&mq->thread_sem);
}
-
- /* Current request becomes previous request and vice versa. */
- mq->mqrq_prev->brq.mrq.data = NULL;
- mq->mqrq_prev->req = NULL;
- tmp = mq->mqrq_prev;
- mq->mqrq_prev = mq->mqrq_cur;
- mq->mqrq_cur = tmp;
} while (1);
up(&mq->thread_sem);
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index d2339ea3781..bd57a11acc7 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -66,8 +66,6 @@ struct uart_icount {
struct sdio_uart_port {
struct tty_port port;
- struct kref kref;
- struct tty_struct *tty;
unsigned int index;
struct sdio_func *func;
struct mutex func_lock;
@@ -93,7 +91,6 @@ static int sdio_uart_add_port(struct sdio_uart_port *port)
{
int index, ret = -EBUSY;
- kref_init(&port->kref);
mutex_init(&port->func_lock);
spin_lock_init(&port->write_lock);
if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL))
@@ -123,23 +120,15 @@ static struct sdio_uart_port *sdio_uart_port_get(unsigned index)
spin_lock(&sdio_uart_table_lock);
port = sdio_uart_table[index];
if (port)
- kref_get(&port->kref);
+ tty_port_get(&port->port);
spin_unlock(&sdio_uart_table_lock);
return port;
}
-static void sdio_uart_port_destroy(struct kref *kref)
-{
- struct sdio_uart_port *port =
- container_of(kref, struct sdio_uart_port, kref);
- kfifo_free(&port->xmit_fifo);
- kfree(port);
-}
-
static void sdio_uart_port_put(struct sdio_uart_port *port)
{
- kref_put(&port->kref, sdio_uart_port_destroy);
+ tty_port_put(&port->port);
}
static void sdio_uart_port_remove(struct sdio_uart_port *port)
@@ -737,6 +726,14 @@ static void sdio_uart_shutdown(struct tty_port *tport)
sdio_uart_release_func(port);
}
+static void sdio_uart_port_destroy(struct tty_port *tport)
+{
+ struct sdio_uart_port *port =
+ container_of(tport, struct sdio_uart_port, port);
+ kfifo_free(&port->xmit_fifo);
+ kfree(port);
+}
+
/**
* sdio_uart_install - install method
* @driver: the driver in use (sdio_uart in our case)
@@ -1045,6 +1042,7 @@ static const struct tty_port_operations sdio_uart_port_ops = {
.carrier_raised = uart_carrier_raised,
.shutdown = sdio_uart_shutdown,
.activate = sdio_uart_activate,
+ .destruct = sdio_uart_port_destroy,
};
static const struct tty_operations sdio_uart_ops = {
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 9b68933f27e..420cb6753c1 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -225,8 +225,7 @@ static void mmc_release_card(struct device *dev)
sdio_free_common_cis(card);
- if (card->info)
- kfree(card->info);
+ kfree(card->info);
kfree(card);
}
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 06c42cfb7c3..aaed7687cf0 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -42,6 +42,9 @@
#include "sd_ops.h"
#include "sdio_ops.h"
+/* If the device is not responding */
+#define MMC_CORE_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */
+
/*
* Background operations can take a long time, depending on the housekeeping
* operations the card has to perform.
@@ -1631,6 +1634,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
{
struct mmc_command cmd = {0};
unsigned int qty = 0;
+ unsigned long timeout;
int err;
/*
@@ -1708,6 +1712,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
if (mmc_host_is_spi(card->host))
goto out;
+ timeout = jiffies + msecs_to_jiffies(MMC_CORE_TIMEOUT_MS);
do {
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = MMC_SEND_STATUS;
@@ -1721,8 +1726,19 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
err = -EIO;
goto out;
}
+
+ /* Timeout if the device never becomes ready for data and
+ * never leaves the program state.
+ */
+ if (time_after(jiffies, timeout)) {
+ pr_err("%s: Card stuck in programming state! %s\n",
+ mmc_hostname(card->host), __func__);
+ err = -EIO;
+ goto out;
+ }
+
} while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
- R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG);
+ (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG));
out:
return err;
}
@@ -1942,6 +1958,20 @@ int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen)
}
EXPORT_SYMBOL(mmc_set_blocklen);
+int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount,
+ bool is_rel_write)
+{
+ struct mmc_command cmd = {0};
+
+ cmd.opcode = MMC_SET_BLOCK_COUNT;
+ cmd.arg = blockcount & 0x0000FFFF;
+ if (is_rel_write)
+ cmd.arg |= 1 << 31;
+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
+ return mmc_wait_for_cmd(card->host, &cmd, 5);
+}
+EXPORT_SYMBOL(mmc_set_blockcount);
+
static void mmc_hw_reset_for_init(struct mmc_host *host)
{
if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset)
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index d96c643dde1..35c2f85b195 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -144,6 +144,22 @@ static int mmc_ios_show(struct seq_file *s, void *data)
}
seq_printf(s, "timing spec:\t%u (%s)\n", ios->timing, str);
+ switch (ios->signal_voltage) {
+ case MMC_SIGNAL_VOLTAGE_330:
+ str = "3.30 V";
+ break;
+ case MMC_SIGNAL_VOLTAGE_180:
+ str = "1.80 V";
+ break;
+ case MMC_SIGNAL_VOLTAGE_120:
+ str = "1.20 V";
+ break;
+ default:
+ str = "invalid";
+ break;
+ }
+ seq_printf(s, "signal voltage:\t%u (%s)\n", ios->chip_select, str);
+
return 0;
}
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 7cc46382fd6..e6e39111e05 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -239,7 +239,7 @@ static void mmc_select_card_type(struct mmc_card *card)
{
struct mmc_host *host = card->host;
u8 card_type = card->ext_csd.raw_card_type & EXT_CSD_CARD_TYPE_MASK;
- unsigned int caps = host->caps, caps2 = host->caps2;
+ u32 caps = host->caps, caps2 = host->caps2;
unsigned int hs_max_dtr = 0;
if (card_type & EXT_CSD_CARD_TYPE_26)
@@ -491,6 +491,17 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM];
card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION];
+
+ /*
+ * RPMB regions are defined in multiples of 128K.
+ */
+ card->ext_csd.raw_rpmb_size_mult = ext_csd[EXT_CSD_RPMB_MULT];
+ if (ext_csd[EXT_CSD_RPMB_MULT]) {
+ mmc_part_add(card, ext_csd[EXT_CSD_RPMB_MULT] << 17,
+ EXT_CSD_PART_CONFIG_ACC_RPMB,
+ "rpmb", 0, false,
+ MMC_BLK_DATA_AREA_RPMB);
+ }
}
card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT];
@@ -615,6 +626,8 @@ MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
MMC_DEV_ATTR(enhanced_area_offset, "%llu\n",
card->ext_csd.enhanced_area_offset);
MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size);
+MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult);
+MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);
static struct attribute *mmc_std_attrs[] = {
&dev_attr_cid.attr,
@@ -630,6 +643,8 @@ static struct attribute *mmc_std_attrs[] = {
&dev_attr_serial.attr,
&dev_attr_enhanced_area_offset.attr,
&dev_attr_enhanced_area_size.attr,
+ &dev_attr_raw_rpmb_size_mult.attr,
+ &dev_attr_rel_sectors.attr,
NULL,
};
@@ -1051,6 +1066,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
if (mmc_card_highspeed(card) || mmc_card_hs200(card)) {
if (max_dtr > card->ext_csd.hs_max_dtr)
max_dtr = card->ext_csd.hs_max_dtr;
+ if (mmc_card_highspeed(card) && (max_dtr > 52000000))
+ max_dtr = 52000000;
} else if (max_dtr > card->csd.max_dtr) {
max_dtr = card->csd.max_dtr;
}
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index a0e172042e6..6d8f7012d73 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -21,6 +21,8 @@
#include "core.h"
#include "mmc_ops.h"
+#define MMC_OPS_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */
+
static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)
{
int err;
@@ -409,6 +411,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
{
int err;
struct mmc_command cmd = {0};
+ unsigned long timeout;
u32 status;
BUG_ON(!card);
@@ -437,6 +440,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
return 0;
/* Must check status to be sure of no errors */
+ timeout = jiffies + msecs_to_jiffies(MMC_OPS_TIMEOUT_MS);
do {
err = mmc_send_status(card, &status);
if (err)
@@ -445,6 +449,13 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
break;
if (mmc_host_is_spi(card->host))
break;
+
+ /* Timeout if the device never leaves the program state. */
+ if (time_after(jiffies, timeout)) {
+ pr_err("%s: Card stuck in programming state! %s\n",
+ mmc_hostname(card->host), __func__);
+ return -ETIMEDOUT;
+ }
} while (R1_CURRENT_STATE(status) == R1_STATE_PRG);
if (mmc_host_is_spi(card->host)) {
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 6bf68799fe9..5e57048e2c1 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -193,7 +193,21 @@ static int sdio_bus_remove(struct device *dev)
}
#ifdef CONFIG_PM
+
+#ifdef CONFIG_PM_SLEEP
+static int pm_no_operation(struct device *dev)
+{
+ /*
+ * Prevent the PM core from calling SDIO device drivers' suspend
+ * callback routines, which it is not supposed to do, by using this
+ * empty function as the bus type suspend callaback for SDIO.
+ */
+ return 0;
+}
+#endif
+
static const struct dev_pm_ops sdio_bus_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation)
SET_RUNTIME_PM_OPS(
pm_generic_runtime_suspend,
pm_generic_runtime_resume,
@@ -258,8 +272,7 @@ static void sdio_release_func(struct device *dev)
sdio_free_func_cis(func);
- if (func->info)
- kfree(func->info);
+ kfree(func->info);
kfree(func);
}
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
index 8f6f5ac131f..78cb4d5d9d5 100644
--- a/drivers/mmc/core/sdio_io.c
+++ b/drivers/mmc/core/sdio_io.c
@@ -188,8 +188,7 @@ EXPORT_SYMBOL_GPL(sdio_set_block_size);
*/
static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
{
- unsigned mval = min(func->card->host->max_seg_size,
- func->card->host->max_blk_size);
+ unsigned mval = func->card->host->max_blk_size;
if (mmc_blksz_for_byte_mode(func->card))
mval = min(mval, func->cur_blksize);
@@ -311,11 +310,8 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
/* Do the bulk of the transfer using block mode (if supported). */
if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) {
/* Blocks per command is limited by host count, host transfer
- * size (we only use a single sg entry) and the maximum for
- * IO_RW_EXTENDED of 511 blocks. */
- max_blocks = min(func->card->host->max_blk_count,
- func->card->host->max_seg_size / func->cur_blksize);
- max_blocks = min(max_blocks, 511u);
+ * size and the maximum for IO_RW_EXTENDED of 511 blocks. */
+ max_blocks = min(func->card->host->max_blk_count, 511u);
while (remainder >= func->cur_blksize) {
unsigned blocks;
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
index d29e20630ee..62508b457c4 100644
--- a/drivers/mmc/core/sdio_ops.c
+++ b/drivers/mmc/core/sdio_ops.c
@@ -124,7 +124,10 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
struct mmc_request mrq = {NULL};
struct mmc_command cmd = {0};
struct mmc_data data = {0};
- struct scatterlist sg;
+ struct scatterlist sg, *sg_ptr;
+ struct sg_table sgtable;
+ unsigned int nents, left_size, i;
+ unsigned int seg_size = card->host->max_seg_size;
BUG_ON(!card);
BUG_ON(fn > 7);
@@ -152,15 +155,36 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
/* Code in host drivers/fwk assumes that "blocks" always is >=1 */
data.blocks = blocks ? blocks : 1;
data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
- data.sg = &sg;
- data.sg_len = 1;
- sg_init_one(&sg, buf, data.blksz * data.blocks);
+ left_size = data.blksz * data.blocks;
+ nents = (left_size - 1) / seg_size + 1;
+ if (nents > 1) {
+ if (sg_alloc_table(&sgtable, nents, GFP_KERNEL))
+ return -ENOMEM;
+
+ data.sg = sgtable.sgl;
+ data.sg_len = nents;
+
+ for_each_sg(data.sg, sg_ptr, data.sg_len, i) {
+ sg_set_page(sg_ptr, virt_to_page(buf + (i * seg_size)),
+ min(seg_size, left_size),
+ offset_in_page(buf + (i * seg_size)));
+ left_size = left_size - seg_size;
+ }
+ } else {
+ data.sg = &sg;
+ data.sg_len = 1;
+
+ sg_init_one(&sg, buf, left_size);
+ }
mmc_set_data_timeout(&data, card);
mmc_wait_for_req(card->host, &mrq);
+ if (nents > 1)
+ sg_free_table(&sgtable);
+
if (cmd.error)
return cmd.error;
if (data.error)
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 08c6b3dfe08..16a1c0b6f26 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -27,7 +27,13 @@ struct mmc_gpio {
static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
{
/* Schedule a card detection after a debounce timeout */
- mmc_detect_change(dev_id, msecs_to_jiffies(100));
+ struct mmc_host *host = dev_id;
+
+ if (host->ops->card_event)
+ host->ops->card_event(host);
+
+ mmc_detect_change(host, msecs_to_jiffies(200));
+
return IRQ_HANDLED;
}
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 9bf10e7bbfa..737e4edc241 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -81,6 +81,18 @@ config MMC_RICOH_MMC
If unsure, say Y.
+config MMC_SDHCI_ACPI
+ tristate "SDHCI support for ACPI enumerated SDHCI controllers"
+ depends on MMC_SDHCI && ACPI
+ help
+ This selects support for ACPI enumerated SDHCI controllers,
+ identified by ACPI Compatibility ID PNP0D40 or specific
+ ACPI Hardware IDs.
+
+ If you have a controller with this interface, say Y or M here.
+
+ If unsure, say N.
+
config MMC_SDHCI_PLTFM
tristate "SDHCI platform and OF driver helper"
depends on MMC_SDHCI
@@ -270,26 +282,8 @@ config MMC_AU1X
If unsure, say N.
-choice
- prompt "Atmel SD/MMC Driver"
- depends on AVR32 || ARCH_AT91
- default MMC_ATMELMCI if AVR32
- help
- Choose which driver to use for the Atmel MCI Silicon
-
-config MMC_AT91
- tristate "AT91 SD/MMC Card Interface support (DEPRECATED)"
- depends on ARCH_AT91
- help
- This selects the AT91 MCI controller. This driver will
- be removed soon (for more information have a look to
- Documentation/feature-removal-schedule.txt). Please use
- MMC_ATMEL_MCI.
-
- If unsure, say N.
-
config MMC_ATMELMCI
- tristate "Atmel Multimedia Card Interface support"
+ tristate "Atmel SD/MMC Driver (Multimedia Card Interface)"
depends on AVR32 || ARCH_AT91
help
This selects the Atmel Multimedia Card Interface driver. If
@@ -298,8 +292,6 @@ config MMC_ATMELMCI
If unsure, say N.
-endchoice
-
config MMC_ATMELMCI_DMA
bool "Atmel MCI DMA support"
depends on MMC_ATMELMCI && (AVR32 || ARCH_AT91SAM9G45) && DMA_ENGINE
@@ -621,3 +613,21 @@ config MMC_USHC
Note: These controllers only support SDIO cards and do not
support MMC or SD memory cards.
+
+config MMC_WMT
+ tristate "Wondermedia SD/MMC Host Controller support"
+ depends on ARCH_VT8500
+ default y
+ help
+ This selects support for the SD/MMC Host Controller on
+ Wondermedia WM8505/WM8650 based SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called wmt-sdmmc.
+
+config MMC_REALTEK_PCI
+ tristate "Realtek PCI-E SD/MMC Card Interface Driver"
+ depends on MFD_RTSX_PCI
+ help
+ Say Y here to include driver code to support SD/MMC card interface
+ of Realtek PCI-E card reader
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 17ad0a7ba40..b648058d718 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_MMC_MXS) += mxs-mmc.o
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += sdhci-pci-data.o
+obj-$(CONFIG_MMC_SDHCI_ACPI) += sdhci-acpi.o
obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o
obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o
obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o
@@ -17,7 +18,6 @@ obj-$(CONFIG_MMC_WBSD) += wbsd.o
obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
obj-$(CONFIG_MMC_OMAP) += omap.o
obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o
-obj-$(CONFIG_MMC_AT91) += at91_mci.o
obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o
obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
obj-$(CONFIG_MMC_MSM) += msm_sdcc.o
@@ -45,6 +45,9 @@ obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o
obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o
obj-$(CONFIG_MMC_VUB300) += vub300.o
obj-$(CONFIG_MMC_USHC) += ushc.o
+obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o
+
+obj-$(CONFIG_MMC_REALTEK_PCI) += rtsx_pci_sdmmc.o
obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o
obj-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
deleted file mode 100644
index 74bed0fc23e..00000000000
--- a/drivers/mmc/host/at91_mci.c
+++ /dev/null
@@ -1,1219 +0,0 @@
-/*
- * linux/drivers/mmc/host/at91_mci.c - ATMEL AT91 MCI Driver
- *
- * Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved
- *
- * Copyright (C) 2006 Malcolm Noyes
- *
- * 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 is the AT91 MCI driver that has been tested with both MMC cards
- and SD-cards. Boards that support write protect are now supported.
- The CCAT91SBC001 board does not support SD cards.
-
- The three entry points are at91_mci_request, at91_mci_set_ios
- and at91_mci_get_ro.
-
- SET IOS
- This configures the device to put it into the correct mode and clock speed
- required.
-
- MCI REQUEST
- MCI request processes the commands sent in the mmc_request structure. This
- can consist of a processing command and a stop command in the case of
- multiple block transfers.
-
- There are three main types of request, commands, reads and writes.
-
- Commands are straight forward. The command is submitted to the controller and
- the request function returns. When the controller generates an interrupt to indicate
- the command is finished, the response to the command are read and the mmc_request_done
- function called to end the request.
-
- Reads and writes work in a similar manner to normal commands but involve the PDC (DMA)
- controller to manage the transfers.
-
- A read is done from the controller directly to the scatterlist passed in from the request.
- Due to a bug in the AT91RM9200 controller, when a read is completed, all the words are byte
- swapped in the scatterlist buffers. AT91SAM926x are not affected by this bug.
-
- The sequence of read interrupts is: ENDRX, RXBUFF, CMDRDY
-
- A write is slightly different in that the bytes to write are read from the scatterlist
- into a dma memory buffer (this is in case the source buffer should be read only). The
- entire write buffer is then done from this single dma memory buffer.
-
- The sequence of write interrupts is: ENDTX, TXBUFE, NOTBUSY, CMDRDY
-
- GET RO
- Gets the status of the write protect pin, if available.
-*/
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/blkdev.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/dma-mapping.h>
-#include <linux/clk.h>
-#include <linux/atmel_pdc.h>
-#include <linux/gfp.h>
-#include <linux/highmem.h>
-
-#include <linux/mmc/host.h>
-#include <linux/mmc/sdio.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/gpio.h>
-
-#include <mach/board.h>
-#include <mach/cpu.h>
-
-#include "at91_mci.h"
-
-#define DRIVER_NAME "at91_mci"
-
-static inline int at91mci_is_mci1rev2xx(void)
-{
- return ( cpu_is_at91sam9260()
- || cpu_is_at91sam9263()
- || cpu_is_at91sam9rl()
- || cpu_is_at91sam9g10()
- || cpu_is_at91sam9g20()
- );
-}
-
-#define FL_SENT_COMMAND (1 << 0)
-#define FL_SENT_STOP (1 << 1)
-
-#define AT91_MCI_ERRORS (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE \
- | AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE \
- | AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)
-
-#define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg))
-#define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg))
-
-#define MCI_BLKSIZE 512
-#define MCI_MAXBLKSIZE 4095
-#define MCI_BLKATONCE 256
-#define MCI_BUFSIZE (MCI_BLKSIZE * MCI_BLKATONCE)
-
-/*
- * Low level type for this driver
- */
-struct at91mci_host
-{
- struct mmc_host *mmc;
- struct mmc_command *cmd;
- struct mmc_request *request;
-
- void __iomem *baseaddr;
- int irq;
-
- struct at91_mmc_data *board;
- int present;
-
- struct clk *mci_clk;
-
- /*
- * Flag indicating when the command has been sent. This is used to
- * work out whether or not to send the stop
- */
- unsigned int flags;
- /* flag for current bus settings */
- u32 bus_mode;
-
- /* DMA buffer used for transmitting */
- unsigned int* buffer;
- dma_addr_t physical_address;
- unsigned int total_length;
-
- /* Latest in the scatterlist that has been enabled for transfer, but not freed */
- int in_use_index;
-
- /* Latest in the scatterlist that has been enabled for transfer */
- int transfer_index;
-
- /* Timer for timeouts */
- struct timer_list timer;
-};
-
-/*
- * Reset the controller and restore most of the state
- */
-static void at91_reset_host(struct at91mci_host *host)
-{
- unsigned long flags;
- u32 mr;
- u32 sdcr;
- u32 dtor;
- u32 imr;
-
- local_irq_save(flags);
- imr = at91_mci_read(host, AT91_MCI_IMR);
-
- at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
-
- /* save current state */
- mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff;
- sdcr = at91_mci_read(host, AT91_MCI_SDCR);
- dtor = at91_mci_read(host, AT91_MCI_DTOR);
-
- /* reset the controller */
- at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST);
-
- /* restore state */
- at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN);
- at91_mci_write(host, AT91_MCI_MR, mr);
- at91_mci_write(host, AT91_MCI_SDCR, sdcr);
- at91_mci_write(host, AT91_MCI_DTOR, dtor);
- at91_mci_write(host, AT91_MCI_IER, imr);
-
- /* make sure sdio interrupts will fire */
- at91_mci_read(host, AT91_MCI_SR);
-
- local_irq_restore(flags);
-}
-
-static void at91_timeout_timer(unsigned long data)
-{
- struct at91mci_host *host;
-
- host = (struct at91mci_host *)data;
-
- if (host->request) {
- dev_err(host->mmc->parent, "Timeout waiting end of packet\n");
-
- if (host->cmd && host->cmd->data) {
- host->cmd->data->error = -ETIMEDOUT;
- } else {
- if (host->cmd)
- host->cmd->error = -ETIMEDOUT;
- else
- host->request->cmd->error = -ETIMEDOUT;
- }
-
- at91_reset_host(host);
- mmc_request_done(host->mmc, host->request);
- }
-}
-
-/*
- * Copy from sg to a dma block - used for transfers
- */
-static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data)
-{
- unsigned int len, i, size;
- unsigned *dmabuf = host->buffer;
-
- size = data->blksz * data->blocks;
- len = data->sg_len;
-
- /* MCI1 rev2xx Data Write Operation and number of bytes erratum */
- if (at91mci_is_mci1rev2xx())
- if (host->total_length == 12)
- memset(dmabuf, 0, 12);
-
- /*
- * Just loop through all entries. Size might not
- * be the entire list though so make sure that
- * we do not transfer too much.
- */
- for (i = 0; i < len; i++) {
- struct scatterlist *sg;
- int amount;
- unsigned int *sgbuffer;
-
- sg = &data->sg[i];
-
- sgbuffer = kmap_atomic(sg_page(sg)) + sg->offset;
- amount = min(size, sg->length);
- size -= amount;
-
- if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */
- int index;
-
- for (index = 0; index < (amount / 4); index++)
- *dmabuf++ = swab32(sgbuffer[index]);
- } else {
- char *tmpv = (char *)dmabuf;
- memcpy(tmpv, sgbuffer, amount);
- tmpv += amount;
- dmabuf = (unsigned *)tmpv;
- }
-
- kunmap_atomic(sgbuffer);
-
- if (size == 0)
- break;
- }
-
- /*
- * Check that we didn't get a request to transfer
- * more data than can fit into the SG list.
- */
- BUG_ON(size != 0);
-}
-
-/*
- * Handle after a dma read
- */
-static void at91_mci_post_dma_read(struct at91mci_host *host)
-{
- struct mmc_command *cmd;
- struct mmc_data *data;
- unsigned int len, i, size;
- unsigned *dmabuf = host->buffer;
-
- pr_debug("post dma read\n");
-
- cmd = host->cmd;
- if (!cmd) {
- pr_debug("no command\n");
- return;
- }
-
- data = cmd->data;
- if (!data) {
- pr_debug("no data\n");
- return;
- }
-
- size = data->blksz * data->blocks;
- len = data->sg_len;
-
- at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX);
- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
-
- for (i = 0; i < len; i++) {
- struct scatterlist *sg;
- int amount;
- unsigned int *sgbuffer;
-
- sg = &data->sg[i];
-
- sgbuffer = kmap_atomic(sg_page(sg)) + sg->offset;
- amount = min(size, sg->length);
- size -= amount;
-
- if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */
- int index;
- for (index = 0; index < (amount / 4); index++)
- sgbuffer[index] = swab32(*dmabuf++);
- } else {
- char *tmpv = (char *)dmabuf;
- memcpy(sgbuffer, tmpv, amount);
- tmpv += amount;
- dmabuf = (unsigned *)tmpv;
- }
-
- flush_kernel_dcache_page(sg_page(sg));
- kunmap_atomic(sgbuffer);
- data->bytes_xfered += amount;
- if (size == 0)
- break;
- }
-
- pr_debug("post dma read done\n");
-}
-
-/*
- * Handle transmitted data
- */
-static void at91_mci_handle_transmitted(struct at91mci_host *host)
-{
- struct mmc_command *cmd;
- struct mmc_data *data;
-
- pr_debug("Handling the transmit\n");
-
- /* Disable the transfer */
- at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
-
- /* Now wait for cmd ready */
- at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_TXBUFE);
-
- cmd = host->cmd;
- if (!cmd) return;
-
- data = cmd->data;
- if (!data) return;
-
- if (cmd->data->blocks > 1) {
- pr_debug("multiple write : wait for BLKE...\n");
- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
- } else
- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
-}
-
-/*
- * Update bytes transfered count during a write operation
- */
-static void at91_mci_update_bytes_xfered(struct at91mci_host *host)
-{
- struct mmc_data *data;
-
- /* always deal with the effective request (and not the current cmd) */
-
- if (host->request->cmd && host->request->cmd->error != 0)
- return;
-
- if (host->request->data) {
- data = host->request->data;
- if (data->flags & MMC_DATA_WRITE) {
- /* card is in IDLE mode now */
- pr_debug("-> bytes_xfered %d, total_length = %d\n",
- data->bytes_xfered, host->total_length);
- data->bytes_xfered = data->blksz * data->blocks;
- }
- }
-}
-
-
-/*Handle after command sent ready*/
-static int at91_mci_handle_cmdrdy(struct at91mci_host *host)
-{
- if (!host->cmd)
- return 1;
- else if (!host->cmd->data) {
- if (host->flags & FL_SENT_STOP) {
- /*After multi block write, we must wait for NOTBUSY*/
- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
- } else return 1;
- } else if (host->cmd->data->flags & MMC_DATA_WRITE) {
- /*After sendding multi-block-write command, start DMA transfer*/
- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_TXBUFE | AT91_MCI_BLKE);
- at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
- }
-
- /* command not completed, have to wait */
- return 0;
-}
-
-
-/*
- * Enable the controller
- */
-static void at91_mci_enable(struct at91mci_host *host)
-{
- unsigned int mr;
-
- at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN);
- at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
- at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
- mr = AT91_MCI_PDCMODE | 0x34a;
-
- if (at91mci_is_mci1rev2xx())
- mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF;
-
- at91_mci_write(host, AT91_MCI_MR, mr);
-
- /* use Slot A or B (only one at same time) */
- at91_mci_write(host, AT91_MCI_SDCR, host->board->slot_b);
-}
-
-/*
- * Disable the controller
- */
-static void at91_mci_disable(struct at91mci_host *host)
-{
- at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST);
-}
-
-/*
- * Send a command
- */
-static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd)
-{
- unsigned int cmdr, mr;
- unsigned int block_length;
- struct mmc_data *data = cmd->data;
-
- unsigned int blocks;
- unsigned int ier = 0;
-
- host->cmd = cmd;
-
- /* Needed for leaving busy state before CMD1 */
- if ((at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) {
- pr_debug("Clearing timeout\n");
- at91_mci_write(host, AT91_MCI_ARGR, 0);
- at91_mci_write(host, AT91_MCI_CMDR, AT91_MCI_OPDCMD);
- while (!(at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_CMDRDY)) {
- /* spin */
- pr_debug("Clearing: SR = %08X\n", at91_mci_read(host, AT91_MCI_SR));
- }
- }
-
- cmdr = cmd->opcode;
-
- if (mmc_resp_type(cmd) == MMC_RSP_NONE)
- cmdr |= AT91_MCI_RSPTYP_NONE;
- else {
- /* if a response is expected then allow maximum response latancy */
- cmdr |= AT91_MCI_MAXLAT;
- /* set 136 bit response for R2, 48 bit response otherwise */
- if (mmc_resp_type(cmd) == MMC_RSP_R2)
- cmdr |= AT91_MCI_RSPTYP_136;
- else
- cmdr |= AT91_MCI_RSPTYP_48;
- }
-
- if (data) {
-
- if (cpu_is_at91rm9200() || cpu_is_at91sam9261()) {
- if (data->blksz & 0x3) {
- pr_debug("Unsupported block size\n");
- cmd->error = -EINVAL;
- mmc_request_done(host->mmc, host->request);
- return;
- }
- if (data->flags & MMC_DATA_STREAM) {
- pr_debug("Stream commands not supported\n");
- cmd->error = -EINVAL;
- mmc_request_done(host->mmc, host->request);
- return;
- }
- }
-
- block_length = data->blksz;
- blocks = data->blocks;
-
- /* always set data start - also set direction flag for read */
- if (data->flags & MMC_DATA_READ)
- cmdr |= (AT91_MCI_TRDIR | AT91_MCI_TRCMD_START);
- else if (data->flags & MMC_DATA_WRITE)
- cmdr |= AT91_MCI_TRCMD_START;
-
- if (cmd->opcode == SD_IO_RW_EXTENDED) {
- cmdr |= AT91_MCI_TRTYP_SDIO_BLOCK;
- } else {
- if (data->flags & MMC_DATA_STREAM)
- cmdr |= AT91_MCI_TRTYP_STREAM;
- if (data->blocks > 1)
- cmdr |= AT91_MCI_TRTYP_MULTIPLE;
- }
- }
- else {
- block_length = 0;
- blocks = 0;
- }
-
- if (host->flags & FL_SENT_STOP)
- cmdr |= AT91_MCI_TRCMD_STOP;
-
- if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
- cmdr |= AT91_MCI_OPDCMD;
-
- /*
- * Set the arguments and send the command
- */
- pr_debug("Sending command %d as %08X, arg = %08X, blocks = %d, length = %d (MR = %08X)\n",
- cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(host, AT91_MCI_MR));
-
- if (!data) {
- at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS | ATMEL_PDC_RXTDIS);
- at91_mci_write(host, ATMEL_PDC_RPR, 0);
- at91_mci_write(host, ATMEL_PDC_RCR, 0);
- at91_mci_write(host, ATMEL_PDC_RNPR, 0);
- at91_mci_write(host, ATMEL_PDC_RNCR, 0);
- at91_mci_write(host, ATMEL_PDC_TPR, 0);
- at91_mci_write(host, ATMEL_PDC_TCR, 0);
- at91_mci_write(host, ATMEL_PDC_TNPR, 0);
- at91_mci_write(host, ATMEL_PDC_TNCR, 0);
- ier = AT91_MCI_CMDRDY;
- } else {
- /* zero block length and PDC mode */
- mr = at91_mci_read(host, AT91_MCI_MR) & 0x5fff;
- mr |= (data->blksz & 0x3) ? AT91_MCI_PDCFBYTE : 0;
- mr |= (block_length << 16);
- mr |= AT91_MCI_PDCMODE;
- at91_mci_write(host, AT91_MCI_MR, mr);
-
- if (!(cpu_is_at91rm9200() || cpu_is_at91sam9261()))
- at91_mci_write(host, AT91_MCI_BLKR,
- AT91_MCI_BLKR_BCNT(blocks) |
- AT91_MCI_BLKR_BLKLEN(block_length));
-
- /*
- * Disable the PDC controller
- */
- at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
-
- if (cmdr & AT91_MCI_TRCMD_START) {
- data->bytes_xfered = 0;
- host->transfer_index = 0;
- host->in_use_index = 0;
- if (cmdr & AT91_MCI_TRDIR) {
- /*
- * Handle a read
- */
- host->total_length = 0;
-
- at91_mci_write(host, ATMEL_PDC_RPR, host->physical_address);
- at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ?
- (blocks * block_length) : (blocks * block_length) / 4);
- at91_mci_write(host, ATMEL_PDC_RNPR, 0);
- at91_mci_write(host, ATMEL_PDC_RNCR, 0);
-
- ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
- }
- else {
- /*
- * Handle a write
- */
- host->total_length = block_length * blocks;
- /*
- * MCI1 rev2xx Data Write Operation and
- * number of bytes erratum
- */
- if (at91mci_is_mci1rev2xx())
- if (host->total_length < 12)
- host->total_length = 12;
-
- at91_mci_sg_to_dma(host, data);
-
- pr_debug("Transmitting %d bytes\n", host->total_length);
-
- at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
- at91_mci_write(host, ATMEL_PDC_TCR, (data->blksz & 0x3) ?
- host->total_length : host->total_length / 4);
-
- ier = AT91_MCI_CMDRDY;
- }
- }
- }
-
- /*
- * Send the command and then enable the PDC - not the other way round as
- * the data sheet says
- */
-
- at91_mci_write(host, AT91_MCI_ARGR, cmd->arg);
- at91_mci_write(host, AT91_MCI_CMDR, cmdr);
-
- if (cmdr & AT91_MCI_TRCMD_START) {
- if (cmdr & AT91_MCI_TRDIR)
- at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);
- }
-
- /* Enable selected interrupts */
- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_ERRORS | ier);
-}
-
-/*
- * Process the next step in the request
- */
-static void at91_mci_process_next(struct at91mci_host *host)
-{
- if (!(host->flags & FL_SENT_COMMAND)) {
- host->flags |= FL_SENT_COMMAND;
- at91_mci_send_command(host, host->request->cmd);
- }
- else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) {
- host->flags |= FL_SENT_STOP;
- at91_mci_send_command(host, host->request->stop);
- } else {
- del_timer(&host->timer);
- /* the at91rm9200 mci controller hangs after some transfers,
- * and the workaround is to reset it after each transfer.
- */
- if (cpu_is_at91rm9200())
- at91_reset_host(host);
- mmc_request_done(host->mmc, host->request);
- }
-}
-
-/*
- * Handle a command that has been completed
- */
-static void at91_mci_completed_command(struct at91mci_host *host, unsigned int status)
-{
- struct mmc_command *cmd = host->cmd;
- struct mmc_data *data = cmd->data;
-
- at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
-
- cmd->resp[0] = at91_mci_read(host, AT91_MCI_RSPR(0));
- cmd->resp[1] = at91_mci_read(host, AT91_MCI_RSPR(1));
- cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2));
- cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3));
-
- pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n",
- status, at91_mci_read(host, AT91_MCI_SR),
- cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
-
- if (status & AT91_MCI_ERRORS) {
- if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) {
- cmd->error = 0;
- }
- else {
- if (status & (AT91_MCI_DTOE | AT91_MCI_DCRCE)) {
- if (data) {
- if (status & AT91_MCI_DTOE)
- data->error = -ETIMEDOUT;
- else if (status & AT91_MCI_DCRCE)
- data->error = -EILSEQ;
- }
- } else {
- if (status & AT91_MCI_RTOE)
- cmd->error = -ETIMEDOUT;
- else if (status & AT91_MCI_RCRCE)
- cmd->error = -EILSEQ;
- else
- cmd->error = -EIO;
- }
-
- pr_debug("Error detected and set to %d/%d (cmd = %d, retries = %d)\n",
- cmd->error, data ? data->error : 0,
- cmd->opcode, cmd->retries);
- }
- }
- else
- cmd->error = 0;
-
- at91_mci_process_next(host);
-}
-
-/*
- * Handle an MMC request
- */
-static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
-{
- struct at91mci_host *host = mmc_priv(mmc);
- host->request = mrq;
- host->flags = 0;
-
- /* more than 1s timeout needed with slow SD cards */
- mod_timer(&host->timer, jiffies + msecs_to_jiffies(2000));
-
- at91_mci_process_next(host);
-}
-
-/*
- * Set the IOS
- */
-static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
-{
- int clkdiv;
- struct at91mci_host *host = mmc_priv(mmc);
- unsigned long at91_master_clock = clk_get_rate(host->mci_clk);
-
- host->bus_mode = ios->bus_mode;
-
- if (ios->clock == 0) {
- /* Disable the MCI controller */
- at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS);
- clkdiv = 0;
- }
- else {
- /* Enable the MCI controller */
- at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN);
-
- if ((at91_master_clock % (ios->clock * 2)) == 0)
- clkdiv = ((at91_master_clock / ios->clock) / 2) - 1;
- else
- clkdiv = (at91_master_clock / ios->clock) / 2;
-
- pr_debug("clkdiv = %d. mcck = %ld\n", clkdiv,
- at91_master_clock / (2 * (clkdiv + 1)));
- }
- if (ios->bus_width == MMC_BUS_WIDTH_4 && host->board->wire4) {
- pr_debug("MMC: Setting controller bus width to 4\n");
- at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) | AT91_MCI_SDCBUS);
- }
- else {
- pr_debug("MMC: Setting controller bus width to 1\n");
- at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS);
- }
-
- /* Set the clock divider */
- at91_mci_write(host, AT91_MCI_MR, (at91_mci_read(host, AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv);
-
- /* maybe switch power to the card */
- if (gpio_is_valid(host->board->vcc_pin)) {
- switch (ios->power_mode) {
- case MMC_POWER_OFF:
- gpio_set_value(host->board->vcc_pin, 0);
- break;
- case MMC_POWER_UP:
- gpio_set_value(host->board->vcc_pin, 1);
- break;
- case MMC_POWER_ON:
- break;
- default:
- WARN_ON(1);
- }
- }
-}
-
-/*
- * Handle an interrupt
- */
-static irqreturn_t at91_mci_irq(int irq, void *devid)
-{
- struct at91mci_host *host = devid;
- int completed = 0;
- unsigned int int_status, int_mask;
-
- int_status = at91_mci_read(host, AT91_MCI_SR);
- int_mask = at91_mci_read(host, AT91_MCI_IMR);
-
- pr_debug("MCI irq: status = %08X, %08X, %08X\n", int_status, int_mask,
- int_status & int_mask);
-
- int_status = int_status & int_mask;
-
- if (int_status & AT91_MCI_ERRORS) {
- completed = 1;
-
- if (int_status & AT91_MCI_UNRE)
- pr_debug("MMC: Underrun error\n");
- if (int_status & AT91_MCI_OVRE)
- pr_debug("MMC: Overrun error\n");
- if (int_status & AT91_MCI_DTOE)
- pr_debug("MMC: Data timeout\n");
- if (int_status & AT91_MCI_DCRCE)
- pr_debug("MMC: CRC error in data\n");
- if (int_status & AT91_MCI_RTOE)
- pr_debug("MMC: Response timeout\n");
- if (int_status & AT91_MCI_RENDE)
- pr_debug("MMC: Response end bit error\n");
- if (int_status & AT91_MCI_RCRCE)
- pr_debug("MMC: Response CRC error\n");
- if (int_status & AT91_MCI_RDIRE)
- pr_debug("MMC: Response direction error\n");
- if (int_status & AT91_MCI_RINDE)
- pr_debug("MMC: Response index error\n");
- } else {
- /* Only continue processing if no errors */
-
- if (int_status & AT91_MCI_TXBUFE) {
- pr_debug("TX buffer empty\n");
- at91_mci_handle_transmitted(host);
- }
-
- if (int_status & AT91_MCI_ENDRX) {
- pr_debug("ENDRX\n");
- at91_mci_post_dma_read(host);
- }
-
- if (int_status & AT91_MCI_RXBUFF) {
- pr_debug("RX buffer full\n");
- at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
- at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_RXBUFF | AT91_MCI_ENDRX);
- completed = 1;
- }
-
- if (int_status & AT91_MCI_ENDTX)
- pr_debug("Transmit has ended\n");
-
- if (int_status & AT91_MCI_NOTBUSY) {
- pr_debug("Card is ready\n");
- at91_mci_update_bytes_xfered(host);
- completed = 1;
- }
-
- if (int_status & AT91_MCI_DTIP)
- pr_debug("Data transfer in progress\n");
-
- if (int_status & AT91_MCI_BLKE) {
- pr_debug("Block transfer has ended\n");
- if (host->request->data && host->request->data->blocks > 1) {
- /* multi block write : complete multi write
- * command and send stop */
- completed = 1;
- } else {
- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
- }
- }
-
- if (int_status & AT91_MCI_SDIOIRQA)
- mmc_signal_sdio_irq(host->mmc);
-
- if (int_status & AT91_MCI_SDIOIRQB)
- mmc_signal_sdio_irq(host->mmc);
-
- if (int_status & AT91_MCI_TXRDY)
- pr_debug("Ready to transmit\n");
-
- if (int_status & AT91_MCI_RXRDY)
- pr_debug("Ready to receive\n");
-
- if (int_status & AT91_MCI_CMDRDY) {
- pr_debug("Command ready\n");
- completed = at91_mci_handle_cmdrdy(host);
- }
- }
-
- if (completed) {
- pr_debug("Completed command\n");
- at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
- at91_mci_completed_command(host, int_status);
- } else
- at91_mci_write(host, AT91_MCI_IDR, int_status & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t at91_mmc_det_irq(int irq, void *_host)
-{
- struct at91mci_host *host = _host;
- int present;
-
- /* entering this ISR means that we have configured det_pin:
- * we can use its value in board structure */
- present = !gpio_get_value(host->board->det_pin);
-
- /*
- * we expect this irq on both insert and remove,
- * and use a short delay to debounce.
- */
- if (present != host->present) {
- host->present = present;
- pr_debug("%s: card %s\n", mmc_hostname(host->mmc),
- present ? "insert" : "remove");
- if (!present) {
- pr_debug("****** Resetting SD-card bus width ******\n");
- at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS);
- }
- /* 0.5s needed because of early card detect switch firing */
- mmc_detect_change(host->mmc, msecs_to_jiffies(500));
- }
- return IRQ_HANDLED;
-}
-
-static int at91_mci_get_ro(struct mmc_host *mmc)
-{
- struct at91mci_host *host = mmc_priv(mmc);
-
- if (gpio_is_valid(host->board->wp_pin))
- return !!gpio_get_value(host->board->wp_pin);
- /*
- * Board doesn't support read only detection; let the mmc core
- * decide what to do.
- */
- return -ENOSYS;
-}
-
-static void at91_mci_enable_sdio_irq(struct mmc_host *mmc, int enable)
-{
- struct at91mci_host *host = mmc_priv(mmc);
-
- pr_debug("%s: sdio_irq %c : %s\n", mmc_hostname(host->mmc),
- host->board->slot_b ? 'B':'A', enable ? "enable" : "disable");
- at91_mci_write(host, enable ? AT91_MCI_IER : AT91_MCI_IDR,
- host->board->slot_b ? AT91_MCI_SDIOIRQB : AT91_MCI_SDIOIRQA);
-
-}
-
-static const struct mmc_host_ops at91_mci_ops = {
- .request = at91_mci_request,
- .set_ios = at91_mci_set_ios,
- .get_ro = at91_mci_get_ro,
- .enable_sdio_irq = at91_mci_enable_sdio_irq,
-};
-
-/*
- * Probe for the device
- */
-static int __init at91_mci_probe(struct platform_device *pdev)
-{
- struct mmc_host *mmc;
- struct at91mci_host *host;
- struct resource *res;
- int ret;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENXIO;
-
- if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME))
- return -EBUSY;
-
- mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev);
- if (!mmc) {
- ret = -ENOMEM;
- dev_dbg(&pdev->dev, "couldn't allocate mmc host\n");
- goto fail6;
- }
-
- mmc->ops = &at91_mci_ops;
- mmc->f_min = 375000;
- mmc->f_max = 25000000;
- mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
- mmc->caps = 0;
-
- mmc->max_blk_size = MCI_MAXBLKSIZE;
- mmc->max_blk_count = MCI_BLKATONCE;
- mmc->max_req_size = MCI_BUFSIZE;
- mmc->max_segs = MCI_BLKATONCE;
- mmc->max_seg_size = MCI_BUFSIZE;
-
- host = mmc_priv(mmc);
- host->mmc = mmc;
- host->bus_mode = 0;
- host->board = pdev->dev.platform_data;
- if (host->board->wire4) {
- if (at91mci_is_mci1rev2xx())
- mmc->caps |= MMC_CAP_4_BIT_DATA;
- else
- dev_warn(&pdev->dev, "4 wire bus mode not supported"
- " - using 1 wire\n");
- }
-
- host->buffer = dma_alloc_coherent(&pdev->dev, MCI_BUFSIZE,
- &host->physical_address, GFP_KERNEL);
- if (!host->buffer) {
- ret = -ENOMEM;
- dev_err(&pdev->dev, "Can't allocate transmit buffer\n");
- goto fail5;
- }
-
- /* Add SDIO capability when available */
- if (at91mci_is_mci1rev2xx()) {
- /* at91mci MCI1 rev2xx sdio interrupt erratum */
- if (host->board->wire4 || !host->board->slot_b)
- mmc->caps |= MMC_CAP_SDIO_IRQ;
- }
-
- /*
- * Reserve GPIOs ... board init code makes sure these pins are set
- * up as GPIOs with the right direction (input, except for vcc)
- */
- if (gpio_is_valid(host->board->det_pin)) {
- ret = gpio_request(host->board->det_pin, "mmc_detect");
- if (ret < 0) {
- dev_dbg(&pdev->dev, "couldn't claim card detect pin\n");
- goto fail4b;
- }
- }
- if (gpio_is_valid(host->board->wp_pin)) {
- ret = gpio_request(host->board->wp_pin, "mmc_wp");
- if (ret < 0) {
- dev_dbg(&pdev->dev, "couldn't claim wp sense pin\n");
- goto fail4;
- }
- }
- if (gpio_is_valid(host->board->vcc_pin)) {
- ret = gpio_request(host->board->vcc_pin, "mmc_vcc");
- if (ret < 0) {
- dev_dbg(&pdev->dev, "couldn't claim vcc switch pin\n");
- goto fail3;
- }
- }
-
- /*
- * Get Clock
- */
- host->mci_clk = clk_get(&pdev->dev, "mci_clk");
- if (IS_ERR(host->mci_clk)) {
- ret = -ENODEV;
- dev_dbg(&pdev->dev, "no mci_clk?\n");
- goto fail2;
- }
-
- /*
- * Map I/O region
- */
- host->baseaddr = ioremap(res->start, resource_size(res));
- if (!host->baseaddr) {
- ret = -ENOMEM;
- goto fail1;
- }
-
- /*
- * Reset hardware
- */
- clk_enable(host->mci_clk); /* Enable the peripheral clock */
- at91_mci_disable(host);
- at91_mci_enable(host);
-
- /*
- * Allocate the MCI interrupt
- */
- host->irq = platform_get_irq(pdev, 0);
- ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED,
- mmc_hostname(mmc), host);
- if (ret) {
- dev_dbg(&pdev->dev, "request MCI interrupt failed\n");
- goto fail0;
- }
-
- setup_timer(&host->timer, at91_timeout_timer, (unsigned long)host);
-
- platform_set_drvdata(pdev, mmc);
-
- /*
- * Add host to MMC layer
- */
- if (gpio_is_valid(host->board->det_pin)) {
- host->present = !gpio_get_value(host->board->det_pin);
- }
- else
- host->present = -1;
-
- mmc_add_host(mmc);
-
- /*
- * monitor card insertion/removal if we can
- */
- if (gpio_is_valid(host->board->det_pin)) {
- ret = request_irq(gpio_to_irq(host->board->det_pin),
- at91_mmc_det_irq, 0, mmc_hostname(mmc), host);
- if (ret)
- dev_warn(&pdev->dev, "request MMC detect irq failed\n");
- else
- device_init_wakeup(&pdev->dev, 1);
- }
-
- pr_debug("Added MCI driver\n");
-
- return 0;
-
-fail0:
- clk_disable(host->mci_clk);
- iounmap(host->baseaddr);
-fail1:
- clk_put(host->mci_clk);
-fail2:
- if (gpio_is_valid(host->board->vcc_pin))
- gpio_free(host->board->vcc_pin);
-fail3:
- if (gpio_is_valid(host->board->wp_pin))
- gpio_free(host->board->wp_pin);
-fail4:
- if (gpio_is_valid(host->board->det_pin))
- gpio_free(host->board->det_pin);
-fail4b:
- if (host->buffer)
- dma_free_coherent(&pdev->dev, MCI_BUFSIZE,
- host->buffer, host->physical_address);
-fail5:
- mmc_free_host(mmc);
-fail6:
- release_mem_region(res->start, resource_size(res));
- dev_err(&pdev->dev, "probe failed, err %d\n", ret);
- return ret;
-}
-
-/*
- * Remove a device
- */
-static int __exit at91_mci_remove(struct platform_device *pdev)
-{
- struct mmc_host *mmc = platform_get_drvdata(pdev);
- struct at91mci_host *host;
- struct resource *res;
-
- if (!mmc)
- return -1;
-
- host = mmc_priv(mmc);
-
- if (host->buffer)
- dma_free_coherent(&pdev->dev, MCI_BUFSIZE,
- host->buffer, host->physical_address);
-
- if (gpio_is_valid(host->board->det_pin)) {
- if (device_can_wakeup(&pdev->dev))
- free_irq(gpio_to_irq(host->board->det_pin), host);
- device_init_wakeup(&pdev->dev, 0);
- gpio_free(host->board->det_pin);
- }
-
- at91_mci_disable(host);
- del_timer_sync(&host->timer);
- mmc_remove_host(mmc);
- free_irq(host->irq, host);
-
- clk_disable(host->mci_clk); /* Disable the peripheral clock */
- clk_put(host->mci_clk);
-
- if (gpio_is_valid(host->board->vcc_pin))
- gpio_free(host->board->vcc_pin);
- if (gpio_is_valid(host->board->wp_pin))
- gpio_free(host->board->wp_pin);
-
- iounmap(host->baseaddr);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, resource_size(res));
-
- mmc_free_host(mmc);
- platform_set_drvdata(pdev, NULL);
- pr_debug("MCI Removed\n");
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int at91_mci_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct mmc_host *mmc = platform_get_drvdata(pdev);
- struct at91mci_host *host = mmc_priv(mmc);
- int ret = 0;
-
- if (gpio_is_valid(host->board->det_pin) && device_may_wakeup(&pdev->dev))
- enable_irq_wake(host->board->det_pin);
-
- if (mmc)
- ret = mmc_suspend_host(mmc);
-
- return ret;
-}
-
-static int at91_mci_resume(struct platform_device *pdev)
-{
- struct mmc_host *mmc = platform_get_drvdata(pdev);
- struct at91mci_host *host = mmc_priv(mmc);
- int ret = 0;
-
- if (gpio_is_valid(host->board->det_pin) && device_may_wakeup(&pdev->dev))
- disable_irq_wake(host->board->det_pin);
-
- if (mmc)
- ret = mmc_resume_host(mmc);
-
- return ret;
-}
-#else
-#define at91_mci_suspend NULL
-#define at91_mci_resume NULL
-#endif
-
-static struct platform_driver at91_mci_driver = {
- .remove = __exit_p(at91_mci_remove),
- .suspend = at91_mci_suspend,
- .resume = at91_mci_resume,
- .driver = {
- .name = DRIVER_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-static int __init at91_mci_init(void)
-{
- return platform_driver_probe(&at91_mci_driver, at91_mci_probe);
-}
-
-static void __exit at91_mci_exit(void)
-{
- platform_driver_unregister(&at91_mci_driver);
-}
-
-module_init(at91_mci_init);
-module_exit(at91_mci_exit);
-
-MODULE_DESCRIPTION("AT91 Multimedia Card Interface driver");
-MODULE_AUTHOR("Nick Randell");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:at91_mci");
diff --git a/drivers/mmc/host/at91_mci.h b/drivers/mmc/host/at91_mci.h
deleted file mode 100644
index eec3a6b1c2b..00000000000
--- a/drivers/mmc/host/at91_mci.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * drivers/mmc/host/at91_mci.h
- *
- * Copyright (C) 2005 Ivan Kokshaysky
- * Copyright (C) SAN People
- *
- * MultiMedia Card Interface (MCI) registers.
- * Based on AT91RM9200 datasheet revision F.
- *
- * 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 AT91_MCI_H
-#define AT91_MCI_H
-
-#define AT91_MCI_CR 0x00 /* Control Register */
-#define AT91_MCI_MCIEN (1 << 0) /* Multi-Media Interface Enable */
-#define AT91_MCI_MCIDIS (1 << 1) /* Multi-Media Interface Disable */
-#define AT91_MCI_PWSEN (1 << 2) /* Power Save Mode Enable */
-#define AT91_MCI_PWSDIS (1 << 3) /* Power Save Mode Disable */
-#define AT91_MCI_SWRST (1 << 7) /* Software Reset */
-
-#define AT91_MCI_MR 0x04 /* Mode Register */
-#define AT91_MCI_CLKDIV (0xff << 0) /* Clock Divider */
-#define AT91_MCI_PWSDIV (7 << 8) /* Power Saving Divider */
-#define AT91_MCI_RDPROOF (1 << 11) /* Read Proof Enable [SAM926[03] only] */
-#define AT91_MCI_WRPROOF (1 << 12) /* Write Proof Enable [SAM926[03] only] */
-#define AT91_MCI_PDCFBYTE (1 << 13) /* PDC Force Byte Transfer [SAM926[03] only] */
-#define AT91_MCI_PDCPADV (1 << 14) /* PDC Padding Value */
-#define AT91_MCI_PDCMODE (1 << 15) /* PDC-orientated Mode */
-#define AT91_MCI_BLKLEN (0xfff << 18) /* Data Block Length */
-
-#define AT91_MCI_DTOR 0x08 /* Data Timeout Register */
-#define AT91_MCI_DTOCYC (0xf << 0) /* Data Timeout Cycle Number */
-#define AT91_MCI_DTOMUL (7 << 4) /* Data Timeout Multiplier */
-#define AT91_MCI_DTOMUL_1 (0 << 4)
-#define AT91_MCI_DTOMUL_16 (1 << 4)
-#define AT91_MCI_DTOMUL_128 (2 << 4)
-#define AT91_MCI_DTOMUL_256 (3 << 4)
-#define AT91_MCI_DTOMUL_1K (4 << 4)
-#define AT91_MCI_DTOMUL_4K (5 << 4)
-#define AT91_MCI_DTOMUL_64K (6 << 4)
-#define AT91_MCI_DTOMUL_1M (7 << 4)
-
-#define AT91_MCI_SDCR 0x0c /* SD Card Register */
-#define AT91_MCI_SDCSEL (3 << 0) /* SD Card Selector */
-#define AT91_MCI_SDCBUS (1 << 7) /* 1-bit or 4-bit bus */
-
-#define AT91_MCI_ARGR 0x10 /* Argument Register */
-
-#define AT91_MCI_CMDR 0x14 /* Command Register */
-#define AT91_MCI_CMDNB (0x3f << 0) /* Command Number */
-#define AT91_MCI_RSPTYP (3 << 6) /* Response Type */
-#define AT91_MCI_RSPTYP_NONE (0 << 6)
-#define AT91_MCI_RSPTYP_48 (1 << 6)
-#define AT91_MCI_RSPTYP_136 (2 << 6)
-#define AT91_MCI_SPCMD (7 << 8) /* Special Command */
-#define AT91_MCI_SPCMD_NONE (0 << 8)
-#define AT91_MCI_SPCMD_INIT (1 << 8)
-#define AT91_MCI_SPCMD_SYNC (2 << 8)
-#define AT91_MCI_SPCMD_ICMD (4 << 8)
-#define AT91_MCI_SPCMD_IRESP (5 << 8)
-#define AT91_MCI_OPDCMD (1 << 11) /* Open Drain Command */
-#define AT91_MCI_MAXLAT (1 << 12) /* Max Latency for Command to Response */
-#define AT91_MCI_TRCMD (3 << 16) /* Transfer Command */
-#define AT91_MCI_TRCMD_NONE (0 << 16)
-#define AT91_MCI_TRCMD_START (1 << 16)
-#define AT91_MCI_TRCMD_STOP (2 << 16)
-#define AT91_MCI_TRDIR (1 << 18) /* Transfer Direction */
-#define AT91_MCI_TRTYP (3 << 19) /* Transfer Type */
-#define AT91_MCI_TRTYP_BLOCK (0 << 19)
-#define AT91_MCI_TRTYP_MULTIPLE (1 << 19)
-#define AT91_MCI_TRTYP_STREAM (2 << 19)
-#define AT91_MCI_TRTYP_SDIO_BYTE (4 << 19)
-#define AT91_MCI_TRTYP_SDIO_BLOCK (5 << 19)
-
-#define AT91_MCI_BLKR 0x18 /* Block Register */
-#define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */
-#define AT91_MCI_BLKR_BLKLEN(n) ((0xffff & (n)) << 16) /* Block length */
-
-#define AT91_MCI_RSPR(n) (0x20 + ((n) * 4)) /* Response Registers 0-3 */
-#define AT91_MCR_RDR 0x30 /* Receive Data Register */
-#define AT91_MCR_TDR 0x34 /* Transmit Data Register */
-
-#define AT91_MCI_SR 0x40 /* Status Register */
-#define AT91_MCI_CMDRDY (1 << 0) /* Command Ready */
-#define AT91_MCI_RXRDY (1 << 1) /* Receiver Ready */
-#define AT91_MCI_TXRDY (1 << 2) /* Transmit Ready */
-#define AT91_MCI_BLKE (1 << 3) /* Data Block Ended */
-#define AT91_MCI_DTIP (1 << 4) /* Data Transfer in Progress */
-#define AT91_MCI_NOTBUSY (1 << 5) /* Data Not Busy */
-#define AT91_MCI_ENDRX (1 << 6) /* End of RX Buffer */
-#define AT91_MCI_ENDTX (1 << 7) /* End fo TX Buffer */
-#define AT91_MCI_SDIOIRQA (1 << 8) /* SDIO Interrupt for Slot A */
-#define AT91_MCI_SDIOIRQB (1 << 9) /* SDIO Interrupt for Slot B */
-#define AT91_MCI_RXBUFF (1 << 14) /* RX Buffer Full */
-#define AT91_MCI_TXBUFE (1 << 15) /* TX Buffer Empty */
-#define AT91_MCI_RINDE (1 << 16) /* Response Index Error */
-#define AT91_MCI_RDIRE (1 << 17) /* Response Direction Error */
-#define AT91_MCI_RCRCE (1 << 18) /* Response CRC Error */
-#define AT91_MCI_RENDE (1 << 19) /* Response End Bit Error */
-#define AT91_MCI_RTOE (1 << 20) /* Response Time-out Error */
-#define AT91_MCI_DCRCE (1 << 21) /* Data CRC Error */
-#define AT91_MCI_DTOE (1 << 22) /* Data Time-out Error */
-#define AT91_MCI_OVRE (1 << 30) /* Overrun */
-#define AT91_MCI_UNRE (1 << 31) /* Underrun */
-
-#define AT91_MCI_IER 0x44 /* Interrupt Enable Register */
-#define AT91_MCI_IDR 0x48 /* Interrupt Disable Register */
-#define AT91_MCI_IMR 0x4c /* Interrupt Mask Register */
-
-#endif
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index ddf096e3803..5248ba4369a 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -511,7 +511,7 @@ static const struct of_device_id atmci_dt_ids[] = {
MODULE_DEVICE_TABLE(of, atmci_dt_ids);
-static struct mci_platform_data __devinit*
+static struct mci_platform_data*
atmci_of_init(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index dbd0c8a4e98..127a8fade4d 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -943,7 +943,7 @@ static const struct mmc_host_ops au1xmmc_ops = {
.enable_sdio_irq = au1xmmc_enable_sdio_irq,
};
-static int __devinit au1xmmc_probe(struct platform_device *pdev)
+static int au1xmmc_probe(struct platform_device *pdev)
{
struct mmc_host *mmc;
struct au1xmmc_host *host;
@@ -1114,7 +1114,7 @@ out0:
return ret;
}
-static int __devexit au1xmmc_remove(struct platform_device *pdev)
+static int au1xmmc_remove(struct platform_device *pdev)
{
struct au1xmmc_host *host = platform_get_drvdata(pdev);
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c
index b9b463eca1e..fb4348c5b6a 100644
--- a/drivers/mmc/host/bfin_sdh.c
+++ b/drivers/mmc/host/bfin_sdh.c
@@ -522,7 +522,7 @@ static void sdh_reset(void)
SSYNC();
}
-static int __devinit sdh_probe(struct platform_device *pdev)
+static int sdh_probe(struct platform_device *pdev)
{
struct mmc_host *mmc;
struct sdh_host *host;
@@ -617,7 +617,7 @@ out1:
return ret;
}
-static int __devexit sdh_remove(struct platform_device *pdev)
+static int sdh_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
@@ -680,7 +680,7 @@ static int sdh_resume(struct platform_device *dev)
static struct platform_driver sdh_driver = {
.probe = sdh_probe,
- .remove = __devexit_p(sdh_remove),
+ .remove = sdh_remove,
.suspend = sdh_suspend,
.resume = sdh_resume,
.driver = {
diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c
index 83693fd7c6b..777ca2046b2 100644
--- a/drivers/mmc/host/cb710-mmc.c
+++ b/drivers/mmc/host/cb710-mmc.c
@@ -690,7 +690,7 @@ static int cb710_mmc_resume(struct platform_device *pdev)
#endif /* CONFIG_PM */
-static int __devinit cb710_mmc_init(struct platform_device *pdev)
+static int cb710_mmc_init(struct platform_device *pdev)
{
struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
struct cb710_chip *chip = cb710_slot_to_chip(slot);
@@ -746,7 +746,7 @@ err_free_mmc:
return err;
}
-static int __devexit cb710_mmc_exit(struct platform_device *pdev)
+static int cb710_mmc_exit(struct platform_device *pdev)
{
struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
struct mmc_host *mmc = cb710_slot_to_mmc(slot);
@@ -773,7 +773,7 @@ static int __devexit cb710_mmc_exit(struct platform_device *pdev)
static struct platform_driver cb710_mmc_driver = {
.driver.name = "cb710-mmc",
.probe = cb710_mmc_init,
- .remove = __devexit_p(cb710_mmc_exit),
+ .remove = cb710_mmc_exit,
#ifdef CONFIG_PM
.suspend = cb710_mmc_suspend,
.resume = cb710_mmc_resume,
diff --git a/drivers/mmc/host/dw_mmc-pci.c b/drivers/mmc/host/dw_mmc-pci.c
index edb37e9135a..8ee0f74f937 100644
--- a/drivers/mmc/host/dw_mmc-pci.c
+++ b/drivers/mmc/host/dw_mmc-pci.c
@@ -37,7 +37,7 @@ static struct dw_mci_board pci_board_data = {
.fifo_depth = 32,
};
-static int __devinit dw_mci_pci_probe(struct pci_dev *pdev,
+static int dw_mci_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *entries)
{
struct dw_mci *host;
@@ -85,7 +85,7 @@ err_disable_dev:
return ret;
}
-static void __devexit dw_mci_pci_remove(struct pci_dev *pdev)
+static void dw_mci_pci_remove(struct pci_dev *pdev)
{
struct dw_mci *host = pci_get_drvdata(pdev);
@@ -134,7 +134,7 @@ static struct pci_driver dw_mci_pci_driver = {
.name = "dw_mmc_pci",
.id_table = dw_mci_pci_id,
.probe = dw_mci_pci_probe,
- .remove = dw_mci_pci_remove,
+ .remove = __devexit_p(dw_mci_pci_remove),
.driver = {
.pm = &dw_mci_pci_pmops
},
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index 917936bee5d..222036c9e05 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -62,12 +62,12 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
}
EXPORT_SYMBOL_GPL(dw_mci_pltfm_register);
-static int __devinit dw_mci_pltfm_probe(struct platform_device *pdev)
+static int dw_mci_pltfm_probe(struct platform_device *pdev)
{
return dw_mci_pltfm_register(pdev, NULL);
}
-static int __devexit dw_mci_pltfm_remove(struct platform_device *pdev)
+static int dw_mci_pltfm_remove(struct platform_device *pdev)
{
struct dw_mci *host = platform_get_drvdata(pdev);
@@ -119,7 +119,8 @@ static const struct of_device_id dw_mci_pltfm_match[] = {
MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match);
static struct platform_driver dw_mci_pltfm_driver = {
- .remove = __exit_p(dw_mci_pltfm_remove),
+ .probe = dw_mci_pltfm_probe,
+ .remove = __devexit_p(dw_mci_pltfm_remove),
.driver = {
.name = "dw_mmc",
.of_match_table = of_match_ptr(dw_mci_pltfm_match),
@@ -127,18 +128,7 @@ static struct platform_driver dw_mci_pltfm_driver = {
},
};
-static int __init dw_mci_init(void)
-{
- return platform_driver_probe(&dw_mci_pltfm_driver, dw_mci_pltfm_probe);
-}
-
-static void __exit dw_mci_exit(void)
-{
- platform_driver_unregister(&dw_mci_pltfm_driver);
-}
-
-module_init(dw_mci_init);
-module_exit(dw_mci_exit);
+module_platform_driver(dw_mci_pltfm_driver);
MODULE_DESCRIPTION("DW Multimedia Card Interface driver");
MODULE_AUTHOR("NXP Semiconductor VietNam");
diff --git a/drivers/mmc/host/dw_mmc-pltfm.h b/drivers/mmc/host/dw_mmc-pltfm.h
index 2ac37b81de4..68e7fd2f614 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.h
+++ b/drivers/mmc/host/dw_mmc-pltfm.h
@@ -14,7 +14,7 @@
extern int dw_mci_pltfm_register(struct platform_device *pdev,
const struct dw_mci_drv_data *drv_data);
-extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev);
+extern int dw_mci_pltfm_remove(struct platform_device *pdev);
extern const struct dev_pm_ops dw_mci_pltfm_pmops;
#endif /* _DW_MMC_PLTFM_H_ */
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index c0667c8af2b..323c5022c2c 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -232,7 +232,7 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
{
struct mmc_data *data;
struct dw_mci_slot *slot = mmc_priv(mmc);
- struct dw_mci_drv_data *drv_data = slot->host->drv_data;
+ const struct dw_mci_drv_data *drv_data = slot->host->drv_data;
u32 cmdr;
cmd->error = -EINPROGRESS;
@@ -617,13 +617,13 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
cmd, arg, cmd_status);
}
-static void dw_mci_setup_bus(struct dw_mci_slot *slot)
+static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
{
struct dw_mci *host = slot->host;
u32 div;
u32 clk_en_a;
- if (slot->clock != host->current_speed) {
+ if (slot->clock != host->current_speed || force_clkinit) {
div = host->bus_hz / slot->clock;
if (host->bus_hz % slot->clock && host->bus_hz > slot->clock)
/*
@@ -683,9 +683,6 @@ static void __dw_mci_start_request(struct dw_mci *host,
if (host->pdata->select_slot)
host->pdata->select_slot(slot->id);
- /* Slot specific timing and width adjustment */
- dw_mci_setup_bus(slot);
-
host->cur_slot = slot;
host->mrq = mrq;
@@ -773,22 +770,19 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct dw_mci_slot *slot = mmc_priv(mmc);
- struct dw_mci_drv_data *drv_data = slot->host->drv_data;
+ const struct dw_mci_drv_data *drv_data = slot->host->drv_data;
u32 regs;
- /* set default 1 bit mode */
- slot->ctype = SDMMC_CTYPE_1BIT;
-
switch (ios->bus_width) {
- case MMC_BUS_WIDTH_1:
- slot->ctype = SDMMC_CTYPE_1BIT;
- break;
case MMC_BUS_WIDTH_4:
slot->ctype = SDMMC_CTYPE_4BIT;
break;
case MMC_BUS_WIDTH_8:
slot->ctype = SDMMC_CTYPE_8BIT;
break;
+ default:
+ /* set default 1 bit mode */
+ slot->ctype = SDMMC_CTYPE_1BIT;
}
regs = mci_readl(slot->host, UHS_REG);
@@ -812,6 +806,9 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (drv_data && drv_data->set_ios)
drv_data->set_ios(slot->host, ios);
+ /* Slot specific timing and width adjustment */
+ dw_mci_setup_bus(slot, false);
+
switch (ios->power_mode) {
case MMC_POWER_UP:
set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags);
@@ -1817,7 +1814,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
{
struct mmc_host *mmc;
struct dw_mci_slot *slot;
- struct dw_mci_drv_data *drv_data = host->drv_data;
+ const struct dw_mci_drv_data *drv_data = host->drv_data;
int ctrl_id, ret;
u8 bus_width;
@@ -1850,6 +1847,9 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
if (host->pdata->caps)
mmc->caps = host->pdata->caps;
+ if (host->pdata->pm_caps)
+ mmc->pm_caps = host->pdata->pm_caps;
+
if (host->dev->of_node) {
ctrl_id = of_alias_get_id(host->dev->of_node, "mshc");
if (ctrl_id < 0)
@@ -1911,7 +1911,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
#endif /* CONFIG_MMC_DW_IDMAC */
}
- host->vmmc = regulator_get(mmc_dev(mmc), "vmmc");
+ host->vmmc = devm_regulator_get(mmc_dev(mmc), "vmmc");
if (IS_ERR(host->vmmc)) {
pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
host->vmmc = NULL;
@@ -1960,7 +1960,7 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
static void dw_mci_init_dma(struct dw_mci *host)
{
/* Alloc memory for sg translation */
- host->sg_cpu = dma_alloc_coherent(host->dev, PAGE_SIZE,
+ host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
&host->sg_dma, GFP_KERNEL);
if (!host->sg_cpu) {
dev_err(host->dev, "%s: could not alloc DMA memory\n",
@@ -2038,7 +2038,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
struct dw_mci_board *pdata;
struct device *dev = host->dev;
struct device_node *np = dev->of_node;
- struct dw_mci_drv_data *drv_data = host->drv_data;
+ const struct dw_mci_drv_data *drv_data = host->drv_data;
int idx, ret;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
@@ -2072,6 +2072,12 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
return ERR_PTR(ret);
}
+ if (of_find_property(np, "keep-power-in-suspend", NULL))
+ pdata->pm_caps |= MMC_PM_KEEP_POWER;
+
+ if (of_find_property(np, "enable-sdio-wakeup", NULL))
+ pdata->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
+
return pdata;
}
@@ -2084,7 +2090,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
int dw_mci_probe(struct dw_mci *host)
{
- struct dw_mci_drv_data *drv_data = host->drv_data;
+ const struct dw_mci_drv_data *drv_data = host->drv_data;
int width, i, ret = 0;
u32 fifo_size;
int init_slots = 0;
@@ -2103,26 +2109,24 @@ int dw_mci_probe(struct dw_mci *host)
return -ENODEV;
}
- host->biu_clk = clk_get(host->dev, "biu");
+ host->biu_clk = devm_clk_get(host->dev, "biu");
if (IS_ERR(host->biu_clk)) {
dev_dbg(host->dev, "biu clock not available\n");
} else {
ret = clk_prepare_enable(host->biu_clk);
if (ret) {
dev_err(host->dev, "failed to enable biu clock\n");
- clk_put(host->biu_clk);
return ret;
}
}
- host->ciu_clk = clk_get(host->dev, "ciu");
+ host->ciu_clk = devm_clk_get(host->dev, "ciu");
if (IS_ERR(host->ciu_clk)) {
dev_dbg(host->dev, "ciu clock not available\n");
} else {
ret = clk_prepare_enable(host->ciu_clk);
if (ret) {
dev_err(host->dev, "failed to enable ciu clock\n");
- clk_put(host->ciu_clk);
goto err_clk_biu;
}
}
@@ -2224,7 +2228,8 @@ int dw_mci_probe(struct dw_mci *host)
if (!host->card_workqueue)
goto err_dmaunmap;
INIT_WORK(&host->card_work, dw_mci_work_routine_card);
- ret = request_irq(host->irq, dw_mci_interrupt, host->irq_flags, "dw-mci", host);
+ ret = devm_request_irq(host->dev, host->irq, dw_mci_interrupt,
+ host->irq_flags, "dw-mci", host);
if (ret)
goto err_workqueue;
@@ -2262,7 +2267,7 @@ int dw_mci_probe(struct dw_mci *host)
} else {
dev_dbg(host->dev, "attempted to initialize %d slots, "
"but failed on all\n", host->num_slots);
- goto err_init_slot;
+ goto err_workqueue;
}
/*
@@ -2282,33 +2287,24 @@ int dw_mci_probe(struct dw_mci *host)
return 0;
-err_init_slot:
- free_irq(host->irq, host);
-
err_workqueue:
destroy_workqueue(host->card_workqueue);
err_dmaunmap:
if (host->use_dma && host->dma_ops->exit)
host->dma_ops->exit(host);
- dma_free_coherent(host->dev, PAGE_SIZE,
- host->sg_cpu, host->sg_dma);
- if (host->vmmc) {
+ if (host->vmmc)
regulator_disable(host->vmmc);
- regulator_put(host->vmmc);
- }
err_clk_ciu:
- if (!IS_ERR(host->ciu_clk)) {
+ if (!IS_ERR(host->ciu_clk))
clk_disable_unprepare(host->ciu_clk);
- clk_put(host->ciu_clk);
- }
+
err_clk_biu:
- if (!IS_ERR(host->biu_clk)) {
+ if (!IS_ERR(host->biu_clk))
clk_disable_unprepare(host->biu_clk);
- clk_put(host->biu_clk);
- }
+
return ret;
}
EXPORT_SYMBOL(dw_mci_probe);
@@ -2330,24 +2326,19 @@ void dw_mci_remove(struct dw_mci *host)
mci_writel(host, CLKENA, 0);
mci_writel(host, CLKSRC, 0);
- free_irq(host->irq, host);
destroy_workqueue(host->card_workqueue);
- dma_free_coherent(host->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
if (host->use_dma && host->dma_ops->exit)
host->dma_ops->exit(host);
- if (host->vmmc) {
+ if (host->vmmc)
regulator_disable(host->vmmc);
- regulator_put(host->vmmc);
- }
if (!IS_ERR(host->ciu_clk))
clk_disable_unprepare(host->ciu_clk);
+
if (!IS_ERR(host->biu_clk))
clk_disable_unprepare(host->biu_clk);
- clk_put(host->ciu_clk);
- clk_put(host->biu_clk);
}
EXPORT_SYMBOL(dw_mci_remove);
@@ -2411,6 +2402,11 @@ int dw_mci_resume(struct dw_mci *host)
struct dw_mci_slot *slot = host->slot[i];
if (!slot)
continue;
+ if (slot->mmc->pm_flags & MMC_PM_KEEP_POWER) {
+ dw_mci_set_ios(slot->mmc, &slot->mmc->ios);
+ dw_mci_setup_bus(slot, true);
+ }
+
ret = mmc_resume_host(host->slot[i]->mmc);
if (ret < 0)
return ret;
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
index c8852a8128a..2391c6b7a4b 100644
--- a/drivers/mmc/host/jz4740_mmc.c
+++ b/drivers/mmc/host/jz4740_mmc.c
@@ -702,7 +702,7 @@ static const struct jz_gpio_bulk_request jz4740_mmc_pins[] = {
JZ_GPIO_BULK_PIN(MSC_DATA3),
};
-static int __devinit jz4740_mmc_request_gpio(struct device *dev, int gpio,
+static int jz4740_mmc_request_gpio(struct device *dev, int gpio,
const char *name, bool output, int value)
{
int ret;
@@ -724,7 +724,7 @@ static int __devinit jz4740_mmc_request_gpio(struct device *dev, int gpio,
return 0;
}
-static int __devinit jz4740_mmc_request_gpios(struct platform_device *pdev)
+static int jz4740_mmc_request_gpios(struct platform_device *pdev)
{
int ret;
struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data;
@@ -759,7 +759,7 @@ err:
return ret;
}
-static int __devinit jz4740_mmc_request_cd_irq(struct platform_device *pdev,
+static int jz4740_mmc_request_cd_irq(struct platform_device *pdev,
struct jz4740_mmc_host *host)
{
struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data;
@@ -802,7 +802,7 @@ static inline size_t jz4740_mmc_num_pins(struct jz4740_mmc_host *host)
return num_pins;
}
-static int __devinit jz4740_mmc_probe(struct platform_device* pdev)
+static int jz4740_mmc_probe(struct platform_device* pdev)
{
int ret;
struct mmc_host *mmc;
@@ -938,7 +938,7 @@ err_free_host:
return ret;
}
-static int __devexit jz4740_mmc_remove(struct platform_device *pdev)
+static int jz4740_mmc_remove(struct platform_device *pdev)
{
struct jz4740_mmc_host *host = platform_get_drvdata(pdev);
@@ -1004,7 +1004,7 @@ const struct dev_pm_ops jz4740_mmc_pm_ops = {
static struct platform_driver jz4740_mmc_driver = {
.probe = jz4740_mmc_probe,
- .remove = __devexit_p(jz4740_mmc_remove),
+ .remove = jz4740_mmc_remove,
.driver = {
.name = "jz4740-mmc",
.owner = THIS_MODULE,
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index a600eabbd6c..74145d1d51f 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1485,7 +1485,7 @@ nomem:
}
-static int __devexit mmc_spi_remove(struct spi_device *spi)
+static int mmc_spi_remove(struct spi_device *spi)
{
struct mmc_host *mmc = dev_get_drvdata(&spi->dev);
struct mmc_spi_host *host;
@@ -1517,7 +1517,7 @@ static int __devexit mmc_spi_remove(struct spi_device *spi)
return 0;
}
-static struct of_device_id mmc_spi_of_match_table[] __devinitdata = {
+static struct of_device_id mmc_spi_of_match_table[] = {
{ .compatible = "mmc-spi-slot", },
{},
};
@@ -1529,7 +1529,7 @@ static struct spi_driver mmc_spi_driver = {
.of_match_table = mmc_spi_of_match_table,
},
.probe = mmc_spi_probe,
- .remove = __devexit_p(mmc_spi_remove),
+ .remove = mmc_spi_remove,
};
module_spi_driver(mmc_spi_driver);
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index edc3e9baf0e..ec28d175d9c 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -261,7 +261,7 @@ static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)
* no custom DMA interfaces are supported.
*/
#ifdef CONFIG_DMA_ENGINE
-static void __devinit mmci_dma_setup(struct mmci_host *host)
+static void mmci_dma_setup(struct mmci_host *host)
{
struct mmci_platform_data *plat = host->plat;
const char *rxname, *txname;
@@ -337,7 +337,7 @@ static void __devinit mmci_dma_setup(struct mmci_host *host)
}
/*
- * This is used in __devinit or __devexit so inline it
+ * This is used in or so inline it
* so it can be discarded.
*/
static inline void mmci_dma_release(struct mmci_host *host)
@@ -1255,7 +1255,7 @@ static void mmci_dt_populate_generic_pdata(struct device_node *np,
}
#endif
-static int __devinit mmci_probe(struct amba_device *dev,
+static int mmci_probe(struct amba_device *dev,
const struct amba_id *id)
{
struct mmci_platform_data *plat = dev->dev.platform_data;
@@ -1522,7 +1522,7 @@ static int __devinit mmci_probe(struct amba_device *dev,
return ret;
}
-static int __devexit mmci_remove(struct amba_device *dev)
+static int mmci_remove(struct amba_device *dev)
{
struct mmc_host *mmc = amba_get_drvdata(dev);
@@ -1669,7 +1669,7 @@ static struct amba_driver mmci_driver = {
.pm = &mmci_dev_pm_ops,
},
.probe = mmci_probe,
- .remove = __devexit_p(mmci_remove),
+ .remove = mmci_remove,
.id_table = mmci_ids,
};
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 6290b7f1ccf..29e680f193a 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -240,7 +240,7 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
return 0;
for_each_sg(data->sg, sg, data->sg_len, i) {
- if (sg->offset & 3 || sg->length & 3) {
+ if (sg->offset & 3 || sg->length & 3 || sg->length < 512) {
host->do_dma = 0;
return 0;
}
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index 80d1e6d4b0a..206fe499ded 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -43,7 +43,6 @@
#include <linux/module.h>
#include <linux/pinctrl/consumer.h>
#include <linux/stmp_device.h>
-#include <linux/mmc/mxs-mmc.h>
#include <linux/spi/mxs-spi.h>
#define DRIVER_NAME "mxs-mmc"
@@ -593,13 +592,13 @@ static int mxs_mmc_probe(struct platform_device *pdev)
struct mxs_mmc_host *host;
struct mmc_host *mmc;
struct resource *iores, *dmares;
- struct mxs_mmc_platform_data *pdata;
struct pinctrl *pinctrl;
int ret = 0, irq_err, irq_dma;
dma_cap_mask_t mask;
struct regulator *reg_vmmc;
enum of_gpio_flags flags;
struct mxs_ssp *ssp;
+ u32 bus_width = 0;
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -682,25 +681,15 @@ static int mxs_mmc_probe(struct platform_device *pdev)
mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED |
MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL;
- pdata = mmc_dev(host->mmc)->platform_data;
- if (!pdata) {
- u32 bus_width = 0;
- of_property_read_u32(np, "bus-width", &bus_width);
- if (bus_width == 4)
- mmc->caps |= MMC_CAP_4_BIT_DATA;
- else if (bus_width == 8)
- mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
- host->wp_gpio = of_get_named_gpio_flags(np, "wp-gpios", 0,
- &flags);
- if (flags & OF_GPIO_ACTIVE_LOW)
- host->wp_inverted = 1;
- } else {
- if (pdata->flags & SLOTF_8_BIT_CAPABLE)
- mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
- if (pdata->flags & SLOTF_4_BIT_CAPABLE)
- mmc->caps |= MMC_CAP_4_BIT_DATA;
- host->wp_gpio = pdata->wp_gpio;
- }
+ of_property_read_u32(np, "bus-width", &bus_width);
+ if (bus_width == 4)
+ mmc->caps |= MMC_CAP_4_BIT_DATA;
+ else if (bus_width == 8)
+ mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
+ host->wp_gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, &flags);
+
+ if (flags & OF_GPIO_ACTIVE_LOW)
+ host->wp_inverted = 1;
mmc->f_min = 400000;
mmc->f_max = 288000000;
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 48ad361613e..4e749ab690c 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1214,7 +1214,7 @@ static const struct mmc_host_ops mmc_omap_ops = {
.set_ios = mmc_omap_set_ios,
};
-static int __devinit mmc_omap_new_slot(struct mmc_omap_host *host, int id)
+static int mmc_omap_new_slot(struct mmc_omap_host *host, int id)
{
struct mmc_omap_slot *slot = NULL;
struct mmc_host *mmc;
@@ -1309,7 +1309,7 @@ static void mmc_omap_remove_slot(struct mmc_omap_slot *slot)
mmc_free_host(mmc);
}
-static int __devinit mmc_omap_probe(struct platform_device *pdev)
+static int mmc_omap_probe(struct platform_device *pdev)
{
struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
struct mmc_omap_host *host = NULL;
@@ -1478,7 +1478,7 @@ err_free_mem_region:
return ret;
}
-static int __devexit mmc_omap_remove(struct platform_device *pdev)
+static int mmc_omap_remove(struct platform_device *pdev)
{
struct mmc_omap_host *host = platform_get_drvdata(pdev);
int i;
@@ -1566,7 +1566,7 @@ static int mmc_omap_resume(struct platform_device *pdev)
static struct platform_driver mmc_omap_driver = {
.probe = mmc_omap_probe,
- .remove = __devexit_p(mmc_omap_remove),
+ .remove = mmc_omap_remove,
.suspend = mmc_omap_suspend,
.resume = mmc_omap_resume,
.driver = {
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index fedd258cc4e..e1f3c1135f9 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -37,6 +37,7 @@
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/pm_runtime.h>
#include <mach/hardware.h>
#include <plat/mmc.h>
@@ -62,6 +63,7 @@
#define VS18 (1 << 26)
#define VS30 (1 << 25)
+#define HSS (1 << 21)
#define SDVS18 (0x5 << 9)
#define SDVS30 (0x6 << 9)
#define SDVS33 (0x7 << 9)
@@ -78,28 +80,17 @@
#define CLKD_SHIFT 6
#define DTO_MASK 0x000F0000
#define DTO_SHIFT 16
-#define INT_EN_MASK 0x307F0033
-#define BWR_ENABLE (1 << 4)
-#define BRR_ENABLE (1 << 5)
-#define DTO_ENABLE (1 << 20)
#define INIT_STREAM (1 << 1)
#define DP_SELECT (1 << 21)
#define DDIR (1 << 4)
-#define DMA_EN 0x1
+#define DMAE 0x1
#define MSBS (1 << 5)
#define BCE (1 << 1)
#define FOUR_BIT (1 << 1)
+#define HSPE (1 << 2)
#define DDR (1 << 19)
#define DW8 (1 << 5)
-#define CC 0x1
-#define TC 0x02
#define OD 0x1
-#define ERR (1 << 15)
-#define CMD_TIMEOUT (1 << 16)
-#define DATA_TIMEOUT (1 << 20)
-#define CMD_CRC (1 << 17)
-#define DATA_CRC (1 << 21)
-#define CARD_ERR (1 << 28)
#define STAT_CLEAR 0xFFFFFFFF
#define INIT_STREAM_CMD 0x00000000
#define DUAL_VOLT_OCR_BIT 7
@@ -108,6 +99,26 @@
#define SOFTRESET (1 << 1)
#define RESETDONE (1 << 0)
+/* Interrupt masks for IE and ISE register */
+#define CC_EN (1 << 0)
+#define TC_EN (1 << 1)
+#define BWR_EN (1 << 4)
+#define BRR_EN (1 << 5)
+#define ERR_EN (1 << 15)
+#define CTO_EN (1 << 16)
+#define CCRC_EN (1 << 17)
+#define CEB_EN (1 << 18)
+#define CIE_EN (1 << 19)
+#define DTO_EN (1 << 20)
+#define DCRC_EN (1 << 21)
+#define DEB_EN (1 << 22)
+#define CERR_EN (1 << 28)
+#define BADA_EN (1 << 29)
+
+#define INT_EN_MASK (BADA_EN | CERR_EN | DEB_EN | DCRC_EN |\
+ DTO_EN | CIE_EN | CEB_EN | CCRC_EN | CTO_EN | \
+ BRR_EN | BWR_EN | TC_EN | CC_EN)
+
#define MMC_AUTOSUSPEND_DELAY 100
#define MMC_TIMEOUT_MS 20
#define OMAP_MMC_MIN_CLOCK 400000
@@ -302,7 +313,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
reg = regulator_get(host->dev, "vmmc");
if (IS_ERR(reg)) {
- dev_dbg(host->dev, "vmmc regulator missing\n");
+ dev_err(host->dev, "vmmc regulator missing\n");
return PTR_ERR(reg);
} else {
mmc_slot(host).set_power = omap_hsmmc_set_power;
@@ -455,13 +466,13 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host,
unsigned int irq_mask;
if (host->use_dma)
- irq_mask = INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE);
+ irq_mask = INT_EN_MASK & ~(BRR_EN | BWR_EN);
else
irq_mask = INT_EN_MASK;
/* Disable timeout for erases */
if (cmd->opcode == MMC_ERASE)
- irq_mask &= ~DTO_ENABLE;
+ irq_mask &= ~DTO_EN;
OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
OMAP_HSMMC_WRITE(host->base, ISE, irq_mask);
@@ -494,6 +505,7 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
struct mmc_ios *ios = &host->mmc->ios;
unsigned long regval;
unsigned long timeout;
+ unsigned long clkdiv;
dev_vdbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock);
@@ -501,7 +513,8 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
regval = OMAP_HSMMC_READ(host->base, SYSCTL);
regval = regval & ~(CLKD_MASK | DTO_MASK);
- regval = regval | (calc_divisor(host, ios) << 6) | (DTO << 16);
+ clkdiv = calc_divisor(host, ios);
+ regval = regval | (clkdiv << 6) | (DTO << 16);
OMAP_HSMMC_WRITE(host->base, SYSCTL, regval);
OMAP_HSMMC_WRITE(host->base, SYSCTL,
OMAP_HSMMC_READ(host->base, SYSCTL) | ICE);
@@ -512,6 +525,27 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
&& time_before(jiffies, timeout))
cpu_relax();
+ /*
+ * Enable High-Speed Support
+ * Pre-Requisites
+ * - Controller should support High-Speed-Enable Bit
+ * - Controller should not be using DDR Mode
+ * - Controller should advertise that it supports High Speed
+ * in capabilities register
+ * - MMC/SD clock coming out of controller > 25MHz
+ */
+ if ((mmc_slot(host).features & HSMMC_HAS_HSPE_SUPPORT) &&
+ (ios->timing != MMC_TIMING_UHS_DDR50) &&
+ ((OMAP_HSMMC_READ(host->base, CAPA) & HSS) == HSS)) {
+ regval = OMAP_HSMMC_READ(host->base, HCTL);
+ if (clkdiv && (clk_get_rate(host->fclk)/clkdiv) > 25000000)
+ regval |= HSPE;
+ else
+ regval &= ~HSPE;
+
+ OMAP_HSMMC_WRITE(host->base, HCTL, regval);
+ }
+
omap_hsmmc_start_clock(host);
}
@@ -676,8 +710,8 @@ static void send_init_stream(struct omap_hsmmc_host *host)
OMAP_HSMMC_WRITE(host->base, CMD, INIT_STREAM_CMD);
timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
- while ((reg != CC) && time_before(jiffies, timeout))
- reg = OMAP_HSMMC_READ(host->base, STAT) & CC;
+ while ((reg != CC_EN) && time_before(jiffies, timeout))
+ reg = OMAP_HSMMC_READ(host->base, STAT) & CC_EN;
OMAP_HSMMC_WRITE(host->base, CON,
OMAP_HSMMC_READ(host->base, CON) & ~INIT_STREAM);
@@ -768,7 +802,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd,
}
if (host->use_dma)
- cmdreg |= DMA_EN;
+ cmdreg |= DMAE;
host->req_in_progress = 1;
@@ -968,16 +1002,20 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
__func__);
}
-static void hsmmc_command_incomplete(struct omap_hsmmc_host *host, int err)
+static void hsmmc_command_incomplete(struct omap_hsmmc_host *host,
+ int err, int end_cmd)
{
- omap_hsmmc_reset_controller_fsm(host, SRC);
- host->cmd->error = err;
+ if (end_cmd) {
+ omap_hsmmc_reset_controller_fsm(host, SRC);
+ if (host->cmd)
+ host->cmd->error = err;
+ }
if (host->data) {
omap_hsmmc_reset_controller_fsm(host, SRD);
omap_hsmmc_dma_cleanup(host, err);
- }
-
+ } else if (host->mrq && host->mrq->cmd)
+ host->mrq->cmd->error = err;
}
static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status)
@@ -988,23 +1026,25 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status)
data = host->data;
dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
- if (status & ERR) {
+ if (status & ERR_EN) {
omap_hsmmc_dbg_report_irq(host, status);
- if (status & (CMD_TIMEOUT | DATA_TIMEOUT))
- hsmmc_command_incomplete(host, -ETIMEDOUT);
- else if (status & (CMD_CRC | DATA_CRC))
- hsmmc_command_incomplete(host, -EILSEQ);
- end_cmd = 1;
+ if (status & (CTO_EN | CCRC_EN))
+ end_cmd = 1;
+ if (status & (CTO_EN | DTO_EN))
+ hsmmc_command_incomplete(host, -ETIMEDOUT, end_cmd);
+ else if (status & (CCRC_EN | DCRC_EN))
+ hsmmc_command_incomplete(host, -EILSEQ, end_cmd);
+
if (host->data || host->response_busy) {
- end_trans = 1;
+ end_trans = !end_cmd;
host->response_busy = 0;
}
}
- if (end_cmd || ((status & CC) && host->cmd))
+ if (end_cmd || ((status & CC_EN) && host->cmd))
omap_hsmmc_cmd_done(host, host->cmd);
- if ((end_trans || (status & TC)) && host->mrq)
+ if ((end_trans || (status & TC_EN)) && host->mrq)
omap_hsmmc_xfer_done(host, data);
}
@@ -1101,7 +1141,7 @@ static int omap_hsmmc_switch_opcond(struct omap_hsmmc_host *host, int vdd)
return 0;
err:
- dev_dbg(mmc_dev(host->mmc), "Unable to switch operating voltage\n");
+ dev_err(mmc_dev(host->mmc), "Unable to switch operating voltage\n");
return ret;
}
@@ -1360,7 +1400,7 @@ omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req)
if (host->use_dma) {
ret = omap_hsmmc_start_dma_transfer(host, req);
if (ret != 0) {
- dev_dbg(mmc_dev(host->mmc), "MMC start dma failure\n");
+ dev_err(mmc_dev(host->mmc), "MMC start dma failure\n");
return ret;
}
}
@@ -1678,7 +1718,7 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev)
{
struct omap_mmc_platform_data *pdata;
struct device_node *np = dev->of_node;
- u32 bus_width;
+ u32 bus_width, max_freq;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@@ -1705,6 +1745,12 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev)
if (of_find_property(np, "ti,needs-special-reset", NULL))
pdata->slots[0].features |= HSMMC_HAS_UPDATED_RESET;
+ if (!of_property_read_u32(np, "max-frequency", &max_freq))
+ pdata->max_freq = max_freq;
+
+ if (of_find_property(np, "ti,needs-special-hs-handling", NULL))
+ pdata->slots[0].features |= HSMMC_HAS_HSPE_SUPPORT;
+
return pdata;
}
#else
@@ -1715,7 +1761,7 @@ static inline struct omap_mmc_platform_data
}
#endif
-static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
+static int omap_hsmmc_probe(struct platform_device *pdev)
{
struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
struct mmc_host *mmc;
@@ -1725,6 +1771,7 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
const struct of_device_id *match;
dma_cap_mask_t mask;
unsigned tx_req, rx_req;
+ struct pinctrl *pinctrl;
match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev);
if (match) {
@@ -1821,7 +1868,6 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
* MMC can still work without debounce clock.
*/
if (IS_ERR(host->dbclk)) {
- dev_warn(mmc_dev(host->mmc), "Failed to get debounce clk\n");
host->dbclk = NULL;
} else if (clk_prepare_enable(host->dbclk) != 0) {
dev_warn(mmc_dev(host->mmc), "Failed to enable debounce clk\n");
@@ -1889,13 +1935,13 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
ret = request_irq(host->irq, omap_hsmmc_irq, 0,
mmc_hostname(mmc), host);
if (ret) {
- dev_dbg(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n");
+ dev_err(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n");
goto err_irq;
}
if (pdata->init != NULL) {
if (pdata->init(&pdev->dev) != 0) {
- dev_dbg(mmc_dev(host->mmc),
+ dev_err(mmc_dev(host->mmc),
"Unable to configure MMC IRQs\n");
goto err_irq_cd_init;
}
@@ -1918,7 +1964,7 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
mmc_hostname(mmc), host);
if (ret) {
- dev_dbg(mmc_dev(host->mmc),
+ dev_err(mmc_dev(host->mmc),
"Unable to grab MMC CD IRQ\n");
goto err_irq_cd;
}
@@ -1928,6 +1974,11 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
omap_hsmmc_disable_irq(host);
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl))
+ dev_warn(&pdev->dev,
+ "pins are not configured from the driver\n");
+
omap_hsmmc_protect_card(host);
mmc_add_host(mmc);
@@ -1986,7 +2037,7 @@ err:
return ret;
}
-static int __devexit omap_hsmmc_remove(struct platform_device *pdev)
+static int omap_hsmmc_remove(struct platform_device *pdev)
{
struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
struct resource *res;
@@ -2027,6 +2078,25 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
+static int omap_hsmmc_prepare(struct device *dev)
+{
+ struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+
+ if (host->pdata->suspend)
+ return host->pdata->suspend(dev, host->slot_id);
+
+ return 0;
+}
+
+static void omap_hsmmc_complete(struct device *dev)
+{
+ struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+
+ if (host->pdata->resume)
+ host->pdata->resume(dev, host->slot_id);
+
+}
+
static int omap_hsmmc_suspend(struct device *dev)
{
int ret = 0;
@@ -2040,23 +2110,10 @@ static int omap_hsmmc_suspend(struct device *dev)
pm_runtime_get_sync(host->dev);
host->suspended = 1;
- if (host->pdata->suspend) {
- ret = host->pdata->suspend(dev, host->slot_id);
- if (ret) {
- dev_dbg(dev, "Unable to handle MMC board"
- " level suspend\n");
- host->suspended = 0;
- return ret;
- }
- }
ret = mmc_suspend_host(host->mmc);
if (ret) {
host->suspended = 0;
- if (host->pdata->resume) {
- if (host->pdata->resume(dev, host->slot_id))
- dev_dbg(dev, "Unmask interrupt failed\n");
- }
goto err;
}
@@ -2093,12 +2150,6 @@ static int omap_hsmmc_resume(struct device *dev)
if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
omap_hsmmc_conf_bus_power(host);
- if (host->pdata->resume) {
- ret = host->pdata->resume(dev, host->slot_id);
- if (ret)
- dev_dbg(dev, "Unmask interrupt failed\n");
- }
-
omap_hsmmc_protect_card(host);
/* Notify the core to resume the host */
@@ -2114,8 +2165,10 @@ static int omap_hsmmc_resume(struct device *dev)
}
#else
+#define omap_hsmmc_prepare NULL
+#define omap_hsmmc_complete NULL
#define omap_hsmmc_suspend NULL
-#define omap_hsmmc_resume NULL
+#define omap_hsmmc_resume NULL
#endif
static int omap_hsmmc_runtime_suspend(struct device *dev)
@@ -2143,13 +2196,15 @@ static int omap_hsmmc_runtime_resume(struct device *dev)
static struct dev_pm_ops omap_hsmmc_dev_pm_ops = {
.suspend = omap_hsmmc_suspend,
.resume = omap_hsmmc_resume,
+ .prepare = omap_hsmmc_prepare,
+ .complete = omap_hsmmc_complete,
.runtime_suspend = omap_hsmmc_runtime_suspend,
.runtime_resume = omap_hsmmc_runtime_resume,
};
static struct platform_driver omap_hsmmc_driver = {
.probe = omap_hsmmc_probe,
- .remove = __devexit_p(omap_hsmmc_remove),
+ .remove = omap_hsmmc_remove,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 3f9d6d577a9..2b2f65ada22 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -584,7 +584,7 @@ static const struct of_device_id pxa_mmc_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pxa_mmc_dt_ids);
-static int __devinit pxamci_of_init(struct platform_device *pdev)
+static int pxamci_of_init(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct pxamci_platform_data *pdata;
@@ -614,7 +614,7 @@ static int __devinit pxamci_of_init(struct platform_device *pdev)
return 0;
}
#else
-static int __devinit pxamci_of_init(struct platform_device *pdev)
+static int pxamci_of_init(struct platform_device *pdev)
{
return 0;
}
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
new file mode 100644
index 00000000000..12eff6f8cab
--- /dev/null
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -0,0 +1,1348 @@
+/* Realtek PCI-Express SD/MMC Card Interface driver
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Wei WANG <wei_wang@realsil.com.cn>
+ * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#include <linux/module.h>
+#include <linux/highmem.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
+#include <linux/mmc/card.h>
+#include <linux/mfd/rtsx_pci.h>
+#include <asm/unaligned.h>
+
+/* SD Tuning Data Structure
+ * Record continuous timing phase path
+ */
+struct timing_phase_path {
+ int start;
+ int end;
+ int mid;
+ int len;
+};
+
+struct realtek_pci_sdmmc {
+ struct platform_device *pdev;
+ struct rtsx_pcr *pcr;
+ struct mmc_host *mmc;
+ struct mmc_request *mrq;
+
+ struct mutex host_mutex;
+
+ u8 ssc_depth;
+ unsigned int clock;
+ bool vpclk;
+ bool double_clk;
+ bool eject;
+ bool initial_mode;
+ bool ddr_mode;
+};
+
+static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host)
+{
+ return &(host->pdev->dev);
+}
+
+static inline void sd_clear_error(struct realtek_pci_sdmmc *host)
+{
+ rtsx_pci_write_register(host->pcr, CARD_STOP,
+ SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR);
+}
+
+#ifdef DEBUG
+static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ u16 i;
+ u8 *ptr;
+
+ /* Print SD host internal registers */
+ rtsx_pci_init_cmd(pcr);
+ for (i = 0xFDA0; i <= 0xFDAE; i++)
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
+ for (i = 0xFD52; i <= 0xFD69; i++)
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
+ rtsx_pci_send_cmd(pcr, 100);
+
+ ptr = rtsx_pci_get_cmd_data(pcr);
+ for (i = 0xFDA0; i <= 0xFDAE; i++)
+ dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+ for (i = 0xFD52; i <= 0xFD69; i++)
+ dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+}
+#else
+#define sd_print_debug_regs(host)
+#endif /* DEBUG */
+
+static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
+ u8 *buf, int buf_len, int timeout)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int err, i;
+ u8 trans_mode;
+
+ dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD%d\n", __func__, cmd[0] - 0x40);
+
+ if (!buf)
+ buf_len = 0;
+
+ if ((cmd[0] & 0x3F) == MMC_SEND_TUNING_BLOCK)
+ trans_mode = SD_TM_AUTO_TUNING;
+ else
+ trans_mode = SD_TM_NORMAL_READ;
+
+ rtsx_pci_init_cmd(pcr);
+
+ for (i = 0; i < 5; i++)
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0 + i, 0xFF, cmd[i]);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H,
+ 0xFF, (u8)(byte_cnt >> 8));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF,
+ SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
+ SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6);
+ if (trans_mode != SD_TM_AUTO_TUNING)
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER,
+ 0xFF, trans_mode | SD_TRANSFER_START);
+ rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
+ SD_TRANSFER_END, SD_TRANSFER_END);
+
+ err = rtsx_pci_send_cmd(pcr, timeout);
+ if (err < 0) {
+ sd_print_debug_regs(host);
+ dev_dbg(sdmmc_dev(host),
+ "rtsx_pci_send_cmd fail (err = %d)\n", err);
+ return err;
+ }
+
+ if (buf && buf_len) {
+ err = rtsx_pci_read_ppbuf(pcr, buf, buf_len);
+ if (err < 0) {
+ dev_dbg(sdmmc_dev(host),
+ "rtsx_pci_read_ppbuf fail (err = %d)\n", err);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static int sd_write_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
+ u8 *buf, int buf_len, int timeout)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int err, i;
+ u8 trans_mode;
+
+ if (!buf)
+ buf_len = 0;
+
+ if (buf && buf_len) {
+ err = rtsx_pci_write_ppbuf(pcr, buf, buf_len);
+ if (err < 0) {
+ dev_dbg(sdmmc_dev(host),
+ "rtsx_pci_write_ppbuf fail (err = %d)\n", err);
+ return err;
+ }
+ }
+
+ trans_mode = cmd ? SD_TM_AUTO_WRITE_2 : SD_TM_AUTO_WRITE_3;
+ rtsx_pci_init_cmd(pcr);
+
+ if (cmd) {
+ dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d\n", __func__,
+ cmd[0] - 0x40);
+
+ for (i = 0; i < 5; i++)
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ SD_CMD0 + i, 0xFF, cmd[i]);
+ }
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H,
+ 0xFF, (u8)(byte_cnt >> 8));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF,
+ SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
+ SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
+ trans_mode | SD_TRANSFER_START);
+ rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
+ SD_TRANSFER_END, SD_TRANSFER_END);
+
+ err = rtsx_pci_send_cmd(pcr, timeout);
+ if (err < 0) {
+ sd_print_debug_regs(host);
+ dev_dbg(sdmmc_dev(host),
+ "rtsx_pci_send_cmd fail (err = %d)\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host,
+ struct mmc_command *cmd)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ u8 cmd_idx = (u8)cmd->opcode;
+ u32 arg = cmd->arg;
+ int err = 0;
+ int timeout = 100;
+ int i;
+ u8 *ptr;
+ int stat_idx = 0;
+ u8 rsp_type;
+ int rsp_len = 5;
+
+ dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
+ __func__, cmd_idx, arg);
+
+ /* Response type:
+ * R0
+ * R1, R5, R6, R7
+ * R1b
+ * R2
+ * R3, R4
+ */
+ switch (mmc_resp_type(cmd)) {
+ case MMC_RSP_NONE:
+ rsp_type = SD_RSP_TYPE_R0;
+ rsp_len = 0;
+ break;
+ case MMC_RSP_R1:
+ rsp_type = SD_RSP_TYPE_R1;
+ break;
+ case MMC_RSP_R1B:
+ rsp_type = SD_RSP_TYPE_R1b;
+ break;
+ case MMC_RSP_R2:
+ rsp_type = SD_RSP_TYPE_R2;
+ rsp_len = 16;
+ break;
+ case MMC_RSP_R3:
+ rsp_type = SD_RSP_TYPE_R3;
+ break;
+ default:
+ dev_dbg(sdmmc_dev(host), "cmd->flag is not valid\n");
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (rsp_type == SD_RSP_TYPE_R1b)
+ timeout = 3000;
+
+ if (cmd->opcode == SD_SWITCH_VOLTAGE) {
+ err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
+ 0xFF, SD_CLK_TOGGLE_EN);
+ if (err < 0)
+ goto out;
+ }
+
+ rtsx_pci_init_cmd(pcr);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | cmd_idx);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD1, 0xFF, (u8)(arg >> 24));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD2, 0xFF, (u8)(arg >> 16));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD3, 0xFF, (u8)(arg >> 8));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8)arg);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE,
+ 0x01, PINGPONG_BUFFER);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER,
+ 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START);
+ rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
+ SD_TRANSFER_END | SD_STAT_IDLE,
+ SD_TRANSFER_END | SD_STAT_IDLE);
+
+ if (rsp_type == SD_RSP_TYPE_R2) {
+ /* Read data from ping-pong buffer */
+ for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++)
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0);
+ stat_idx = 16;
+ } else if (rsp_type != SD_RSP_TYPE_R0) {
+ /* Read data from SD_CMDx registers */
+ for (i = SD_CMD0; i <= SD_CMD4; i++)
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0);
+ stat_idx = 5;
+ }
+
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0);
+
+ err = rtsx_pci_send_cmd(pcr, timeout);
+ if (err < 0) {
+ sd_print_debug_regs(host);
+ sd_clear_error(host);
+ dev_dbg(sdmmc_dev(host),
+ "rtsx_pci_send_cmd error (err = %d)\n", err);
+ goto out;
+ }
+
+ if (rsp_type == SD_RSP_TYPE_R0) {
+ err = 0;
+ goto out;
+ }
+
+ /* Eliminate returned value of CHECK_REG_CMD */
+ ptr = rtsx_pci_get_cmd_data(pcr) + 1;
+
+ /* Check (Start,Transmission) bit of Response */
+ if ((ptr[0] & 0xC0) != 0) {
+ err = -EILSEQ;
+ dev_dbg(sdmmc_dev(host), "Invalid response bit\n");
+ goto out;
+ }
+
+ /* Check CRC7 */
+ if (!(rsp_type & SD_NO_CHECK_CRC7)) {
+ if (ptr[stat_idx] & SD_CRC7_ERR) {
+ err = -EILSEQ;
+ dev_dbg(sdmmc_dev(host), "CRC7 error\n");
+ goto out;
+ }
+ }
+
+ if (rsp_type == SD_RSP_TYPE_R2) {
+ for (i = 0; i < 4; i++) {
+ cmd->resp[i] = get_unaligned_be32(ptr + 1 + i * 4);
+ dev_dbg(sdmmc_dev(host), "cmd->resp[%d] = 0x%08x\n",
+ i, cmd->resp[i]);
+ }
+ } else {
+ cmd->resp[0] = get_unaligned_be32(ptr + 1);
+ dev_dbg(sdmmc_dev(host), "cmd->resp[0] = 0x%08x\n",
+ cmd->resp[0]);
+ }
+
+out:
+ cmd->error = err;
+}
+
+static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ struct mmc_host *mmc = host->mmc;
+ struct mmc_card *card = mmc->card;
+ struct mmc_data *data = mrq->data;
+ int uhs = mmc_sd_card_uhs(card);
+ int read = (data->flags & MMC_DATA_READ) ? 1 : 0;
+ u8 cfg2, trans_mode;
+ int err;
+ size_t data_len = data->blksz * data->blocks;
+
+ if (read) {
+ cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
+ SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0;
+ trans_mode = SD_TM_AUTO_READ_3;
+ } else {
+ cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 |
+ SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | SD_RSP_LEN_0;
+ trans_mode = SD_TM_AUTO_WRITE_3;
+ }
+
+ if (!uhs)
+ cfg2 |= SD_NO_CHECK_WAIT_CRC_TO;
+
+ rtsx_pci_init_cmd(pcr);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L,
+ 0xFF, (u8)data->blocks);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H,
+ 0xFF, (u8)(data->blocks >> 8));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ CARD_DATA_SOURCE, 0x01, RING_BUFFER);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0,
+ DMA_DONE_INT, DMA_DONE_INT);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3,
+ 0xFF, (u8)(data_len >> 24));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2,
+ 0xFF, (u8)(data_len >> 16));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1,
+ 0xFF, (u8)(data_len >> 8));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)data_len);
+ if (read) {
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL,
+ 0x03 | DMA_PACK_SIZE_MASK,
+ DMA_DIR_FROM_CARD | DMA_EN | DMA_512);
+ } else {
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL,
+ 0x03 | DMA_PACK_SIZE_MASK,
+ DMA_DIR_TO_CARD | DMA_EN | DMA_512);
+ }
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE,
+ 0x01, RING_BUFFER);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
+ trans_mode | SD_TRANSFER_START);
+ rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
+ SD_TRANSFER_END, SD_TRANSFER_END);
+
+ rtsx_pci_send_cmd_no_wait(pcr);
+
+ err = rtsx_pci_transfer_data(pcr, data->sg, data->sg_len, read, 10000);
+ if (err < 0) {
+ sd_clear_error(host);
+ return err;
+ }
+
+ return 0;
+}
+
+static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host)
+{
+ rtsx_pci_write_register(host->pcr, SD_CFG1,
+ SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_128);
+}
+
+static inline void sd_disable_initial_mode(struct realtek_pci_sdmmc *host)
+{
+ rtsx_pci_write_register(host->pcr, SD_CFG1,
+ SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0);
+}
+
+static void sd_normal_rw(struct realtek_pci_sdmmc *host,
+ struct mmc_request *mrq)
+{
+ struct mmc_command *cmd = mrq->cmd;
+ struct mmc_data *data = mrq->data;
+ u8 _cmd[5], *buf;
+
+ _cmd[0] = 0x40 | (u8)cmd->opcode;
+ put_unaligned_be32(cmd->arg, (u32 *)(&_cmd[1]));
+
+ buf = kzalloc(data->blksz, GFP_NOIO);
+ if (!buf) {
+ cmd->error = -ENOMEM;
+ return;
+ }
+
+ if (data->flags & MMC_DATA_READ) {
+ if (host->initial_mode)
+ sd_disable_initial_mode(host);
+
+ cmd->error = sd_read_data(host, _cmd, (u16)data->blksz, buf,
+ data->blksz, 200);
+
+ if (host->initial_mode)
+ sd_enable_initial_mode(host);
+
+ sg_copy_from_buffer(data->sg, data->sg_len, buf, data->blksz);
+ } else {
+ sg_copy_to_buffer(data->sg, data->sg_len, buf, data->blksz);
+
+ cmd->error = sd_write_data(host, _cmd, (u16)data->blksz, buf,
+ data->blksz, 200);
+ }
+
+ kfree(buf);
+}
+
+static int sd_change_phase(struct realtek_pci_sdmmc *host, u8 sample_point)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int err;
+
+ dev_dbg(sdmmc_dev(host), "%s: sample_point = %d\n",
+ __func__, sample_point);
+
+ rtsx_pci_init_cmd(pcr);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CHANGE_CLK, CHANGE_CLK);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPRX_CTL, 0x1F, sample_point);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL,
+ PHASE_NOT_RESET, PHASE_NOT_RESET);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CHANGE_CLK, 0);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0);
+
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static u8 sd_search_final_phase(struct realtek_pci_sdmmc *host, u32 phase_map)
+{
+ struct timing_phase_path path[MAX_PHASE + 1];
+ int i, j, cont_path_cnt;
+ int new_block, max_len, final_path_idx;
+ u8 final_phase = 0xFF;
+
+ /* Parse phase_map, take it as a bit-ring */
+ cont_path_cnt = 0;
+ new_block = 1;
+ j = 0;
+ for (i = 0; i < MAX_PHASE + 1; i++) {
+ if (phase_map & (1 << i)) {
+ if (new_block) {
+ new_block = 0;
+ j = cont_path_cnt++;
+ path[j].start = i;
+ path[j].end = i;
+ } else {
+ path[j].end = i;
+ }
+ } else {
+ new_block = 1;
+ if (cont_path_cnt) {
+ /* Calculate path length and middle point */
+ int idx = cont_path_cnt - 1;
+ path[idx].len =
+ path[idx].end - path[idx].start + 1;
+ path[idx].mid =
+ path[idx].start + path[idx].len / 2;
+ }
+ }
+ }
+
+ if (cont_path_cnt == 0) {
+ dev_dbg(sdmmc_dev(host), "No continuous phase path\n");
+ goto finish;
+ } else {
+ /* Calculate last continuous path length and middle point */
+ int idx = cont_path_cnt - 1;
+ path[idx].len = path[idx].end - path[idx].start + 1;
+ path[idx].mid = path[idx].start + path[idx].len / 2;
+ }
+
+ /* Connect the first and last continuous paths if they are adjacent */
+ if (!path[0].start && (path[cont_path_cnt - 1].end == MAX_PHASE)) {
+ /* Using negative index */
+ path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1;
+ path[0].len += path[cont_path_cnt - 1].len;
+ path[0].mid = path[0].start + path[0].len / 2;
+ /* Convert negative middle point index to positive one */
+ if (path[0].mid < 0)
+ path[0].mid += MAX_PHASE + 1;
+ cont_path_cnt--;
+ }
+
+ /* Choose the longest continuous phase path */
+ max_len = 0;
+ final_phase = 0;
+ final_path_idx = 0;
+ for (i = 0; i < cont_path_cnt; i++) {
+ if (path[i].len > max_len) {
+ max_len = path[i].len;
+ final_phase = (u8)path[i].mid;
+ final_path_idx = i;
+ }
+
+ dev_dbg(sdmmc_dev(host), "path[%d].start = %d\n",
+ i, path[i].start);
+ dev_dbg(sdmmc_dev(host), "path[%d].end = %d\n",
+ i, path[i].end);
+ dev_dbg(sdmmc_dev(host), "path[%d].len = %d\n",
+ i, path[i].len);
+ dev_dbg(sdmmc_dev(host), "path[%d].mid = %d\n",
+ i, path[i].mid);
+ }
+
+finish:
+ dev_dbg(sdmmc_dev(host), "Final chosen phase: %d\n", final_phase);
+ return final_phase;
+}
+
+static void sd_wait_data_idle(struct realtek_pci_sdmmc *host)
+{
+ int err, i;
+ u8 val = 0;
+
+ for (i = 0; i < 100; i++) {
+ err = rtsx_pci_read_register(host->pcr, SD_DATA_STATE, &val);
+ if (val & SD_DATA_IDLE)
+ return;
+
+ udelay(100);
+ }
+}
+
+static int sd_tuning_rx_cmd(struct realtek_pci_sdmmc *host,
+ u8 opcode, u8 sample_point)
+{
+ int err;
+ u8 cmd[5] = {0};
+
+ err = sd_change_phase(host, sample_point);
+ if (err < 0)
+ return err;
+
+ cmd[0] = 0x40 | opcode;
+ err = sd_read_data(host, cmd, 0x40, NULL, 0, 100);
+ if (err < 0) {
+ /* Wait till SD DATA IDLE */
+ sd_wait_data_idle(host);
+ sd_clear_error(host);
+ return err;
+ }
+
+ return 0;
+}
+
+static int sd_tuning_phase(struct realtek_pci_sdmmc *host,
+ u8 opcode, u32 *phase_map)
+{
+ int err, i;
+ u32 raw_phase_map = 0;
+
+ for (i = MAX_PHASE; i >= 0; i--) {
+ err = sd_tuning_rx_cmd(host, opcode, (u8)i);
+ if (err == 0)
+ raw_phase_map |= 1 << i;
+ }
+
+ if (phase_map)
+ *phase_map = raw_phase_map;
+
+ return 0;
+}
+
+static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode)
+{
+ int err, i;
+ u32 raw_phase_map[RX_TUNING_CNT] = {0}, phase_map;
+ u8 final_phase;
+
+ for (i = 0; i < RX_TUNING_CNT; i++) {
+ err = sd_tuning_phase(host, opcode, &(raw_phase_map[i]));
+ if (err < 0)
+ return err;
+
+ if (raw_phase_map[i] == 0)
+ break;
+ }
+
+ phase_map = 0xFFFFFFFF;
+ for (i = 0; i < RX_TUNING_CNT; i++) {
+ dev_dbg(sdmmc_dev(host), "RX raw_phase_map[%d] = 0x%08x\n",
+ i, raw_phase_map[i]);
+ phase_map &= raw_phase_map[i];
+ }
+ dev_dbg(sdmmc_dev(host), "RX phase_map = 0x%08x\n", phase_map);
+
+ if (phase_map) {
+ final_phase = sd_search_final_phase(host, phase_map);
+ if (final_phase == 0xFF)
+ return -EINVAL;
+
+ err = sd_change_phase(host, final_phase);
+ if (err < 0)
+ return err;
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+ struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+ struct rtsx_pcr *pcr = host->pcr;
+ struct mmc_command *cmd = mrq->cmd;
+ struct mmc_data *data = mrq->data;
+ unsigned int data_size = 0;
+
+ if (host->eject) {
+ cmd->error = -ENOMEDIUM;
+ goto finish;
+ }
+
+ mutex_lock(&pcr->pcr_mutex);
+
+ rtsx_pci_start_run(pcr);
+
+ rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth,
+ host->initial_mode, host->double_clk, host->vpclk);
+ rtsx_pci_write_register(pcr, CARD_SELECT, 0x07, SD_MOD_SEL);
+ rtsx_pci_write_register(pcr, CARD_SHARE_MODE,
+ CARD_SHARE_MASK, CARD_SHARE_48_SD);
+
+ mutex_lock(&host->host_mutex);
+ host->mrq = mrq;
+ mutex_unlock(&host->host_mutex);
+
+ if (mrq->data)
+ data_size = data->blocks * data->blksz;
+
+ if (!data_size || mmc_op_multi(cmd->opcode) ||
+ (cmd->opcode == MMC_READ_SINGLE_BLOCK) ||
+ (cmd->opcode == MMC_WRITE_BLOCK)) {
+ sd_send_cmd_get_rsp(host, cmd);
+
+ if (!cmd->error && data_size) {
+ sd_rw_multi(host, mrq);
+
+ if (mmc_op_multi(cmd->opcode) && mrq->stop)
+ sd_send_cmd_get_rsp(host, mrq->stop);
+ }
+ } else {
+ sd_normal_rw(host, mrq);
+ }
+
+ if (mrq->data) {
+ if (cmd->error || data->error)
+ data->bytes_xfered = 0;
+ else
+ data->bytes_xfered = data->blocks * data->blksz;
+ }
+
+ mutex_unlock(&pcr->pcr_mutex);
+
+finish:
+ if (cmd->error)
+ dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error);
+
+ mutex_lock(&host->host_mutex);
+ host->mrq = NULL;
+ mutex_unlock(&host->host_mutex);
+
+ mmc_request_done(mmc, mrq);
+}
+
+static int sd_set_bus_width(struct realtek_pci_sdmmc *host,
+ unsigned char bus_width)
+{
+ int err = 0;
+ u8 width[] = {
+ [MMC_BUS_WIDTH_1] = SD_BUS_WIDTH_1BIT,
+ [MMC_BUS_WIDTH_4] = SD_BUS_WIDTH_4BIT,
+ [MMC_BUS_WIDTH_8] = SD_BUS_WIDTH_8BIT,
+ };
+
+ if (bus_width <= MMC_BUS_WIDTH_8)
+ err = rtsx_pci_write_register(host->pcr, SD_CFG1,
+ 0x03, width[bus_width]);
+
+ return err;
+}
+
+static int sd_power_on(struct realtek_pci_sdmmc *host)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int err;
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SELECT, 0x07, SD_MOD_SEL);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SHARE_MODE,
+ CARD_SHARE_MASK, CARD_SHARE_48_SD);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN,
+ SD_CLK_EN, SD_CLK_EN);
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ err = rtsx_pci_card_pull_ctl_enable(pcr, RTSX_SD_CARD);
+ if (err < 0)
+ return err;
+
+ err = rtsx_pci_card_power_on(pcr, RTSX_SD_CARD);
+ if (err < 0)
+ return err;
+
+ err = rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int sd_power_off(struct realtek_pci_sdmmc *host)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int err;
+
+ rtsx_pci_init_cmd(pcr);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, SD_CLK_EN, 0);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE, SD_OUTPUT_EN, 0);
+
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ err = rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
+ if (err < 0)
+ return err;
+
+ return rtsx_pci_card_pull_ctl_disable(pcr, RTSX_SD_CARD);
+}
+
+static int sd_set_power_mode(struct realtek_pci_sdmmc *host,
+ unsigned char power_mode)
+{
+ int err;
+
+ if (power_mode == MMC_POWER_OFF)
+ err = sd_power_off(host);
+ else
+ err = sd_power_on(host);
+
+ return err;
+}
+
+static int sd_set_timing(struct realtek_pci_sdmmc *host,
+ unsigned char timing, bool *ddr_mode)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int err = 0;
+
+ *ddr_mode = false;
+
+ rtsx_pci_init_cmd(pcr);
+
+ switch (timing) {
+ case MMC_TIMING_UHS_SDR104:
+ case MMC_TIMING_UHS_SDR50:
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1,
+ 0x0C | SD_ASYNC_FIFO_NOT_RST,
+ SD_30_MODE | SD_ASYNC_FIFO_NOT_RST);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL,
+ CLK_LOW_FREQ, CLK_LOW_FREQ);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF,
+ CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, 0);
+ break;
+
+ case MMC_TIMING_UHS_DDR50:
+ *ddr_mode = true;
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1,
+ 0x0C | SD_ASYNC_FIFO_NOT_RST,
+ SD_DDR_MODE | SD_ASYNC_FIFO_NOT_RST);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL,
+ CLK_LOW_FREQ, CLK_LOW_FREQ);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF,
+ CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, 0);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_PUSH_POINT_CTL,
+ DDR_VAR_TX_CMD_DAT, DDR_VAR_TX_CMD_DAT);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL,
+ DDR_VAR_RX_DAT | DDR_VAR_RX_CMD,
+ DDR_VAR_RX_DAT | DDR_VAR_RX_CMD);
+ break;
+
+ case MMC_TIMING_MMC_HS:
+ case MMC_TIMING_SD_HS:
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1,
+ 0x0C, SD_20_MODE);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL,
+ CLK_LOW_FREQ, CLK_LOW_FREQ);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF,
+ CRC_FIX_CLK | SD30_VAR_CLK0 | SAMPLE_VAR_CLK1);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, 0);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_PUSH_POINT_CTL,
+ SD20_TX_SEL_MASK, SD20_TX_14_AHEAD);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL,
+ SD20_RX_SEL_MASK, SD20_RX_14_DELAY);
+ break;
+
+ default:
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ SD_CFG1, 0x0C, SD_20_MODE);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL,
+ CLK_LOW_FREQ, CLK_LOW_FREQ);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF,
+ CRC_FIX_CLK | SD30_VAR_CLK0 | SAMPLE_VAR_CLK1);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, 0);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ SD_PUSH_POINT_CTL, 0xFF, 0);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL,
+ SD20_RX_SEL_MASK, SD20_RX_POS_EDGE);
+ break;
+ }
+
+ err = rtsx_pci_send_cmd(pcr, 100);
+
+ return err;
+}
+
+static void sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+ struct rtsx_pcr *pcr = host->pcr;
+
+ if (host->eject)
+ return;
+
+ mutex_lock(&pcr->pcr_mutex);
+
+ rtsx_pci_start_run(pcr);
+
+ sd_set_bus_width(host, ios->bus_width);
+ sd_set_power_mode(host, ios->power_mode);
+ sd_set_timing(host, ios->timing, &host->ddr_mode);
+
+ host->vpclk = false;
+ host->double_clk = true;
+
+ switch (ios->timing) {
+ case MMC_TIMING_UHS_SDR104:
+ case MMC_TIMING_UHS_SDR50:
+ host->ssc_depth = RTSX_SSC_DEPTH_2M;
+ host->vpclk = true;
+ host->double_clk = false;
+ break;
+ case MMC_TIMING_UHS_DDR50:
+ case MMC_TIMING_UHS_SDR25:
+ host->ssc_depth = RTSX_SSC_DEPTH_1M;
+ break;
+ default:
+ host->ssc_depth = RTSX_SSC_DEPTH_500K;
+ break;
+ }
+
+ host->initial_mode = (ios->clock <= 1000000) ? true : false;
+
+ host->clock = ios->clock;
+ rtsx_pci_switch_clock(pcr, ios->clock, host->ssc_depth,
+ host->initial_mode, host->double_clk, host->vpclk);
+
+ mutex_unlock(&pcr->pcr_mutex);
+}
+
+static int sdmmc_get_ro(struct mmc_host *mmc)
+{
+ struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+ struct rtsx_pcr *pcr = host->pcr;
+ int ro = 0;
+ u32 val;
+
+ if (host->eject)
+ return -ENOMEDIUM;
+
+ mutex_lock(&pcr->pcr_mutex);
+
+ rtsx_pci_start_run(pcr);
+
+ /* Check SD mechanical write-protect switch */
+ val = rtsx_pci_readl(pcr, RTSX_BIPR);
+ dev_dbg(sdmmc_dev(host), "%s: RTSX_BIPR = 0x%08x\n", __func__, val);
+ if (val & SD_WRITE_PROTECT)
+ ro = 1;
+
+ mutex_unlock(&pcr->pcr_mutex);
+
+ return ro;
+}
+
+static int sdmmc_get_cd(struct mmc_host *mmc)
+{
+ struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+ struct rtsx_pcr *pcr = host->pcr;
+ int cd = 0;
+ u32 val;
+
+ if (host->eject)
+ return -ENOMEDIUM;
+
+ mutex_lock(&pcr->pcr_mutex);
+
+ rtsx_pci_start_run(pcr);
+
+ /* Check SD card detect */
+ val = rtsx_pci_card_exist(pcr);
+ dev_dbg(sdmmc_dev(host), "%s: RTSX_BIPR = 0x%08x\n", __func__, val);
+ if (val & SD_EXIST)
+ cd = 1;
+
+ mutex_unlock(&pcr->pcr_mutex);
+
+ return cd;
+}
+
+static int sd_wait_voltage_stable_1(struct realtek_pci_sdmmc *host)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int err;
+ u8 stat;
+
+ /* Reference to Signal Voltage Switch Sequence in SD spec.
+ * Wait for a period of time so that the card can drive SD_CMD and
+ * SD_DAT[3:0] to low after sending back CMD11 response.
+ */
+ mdelay(1);
+
+ /* SD_CMD, SD_DAT[3:0] should be driven to low by card;
+ * If either one of SD_CMD,SD_DAT[3:0] is not low,
+ * abort the voltage switch sequence;
+ */
+ err = rtsx_pci_read_register(pcr, SD_BUS_STAT, &stat);
+ if (err < 0)
+ return err;
+
+ if (stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
+ SD_DAT1_STATUS | SD_DAT0_STATUS))
+ return -EINVAL;
+
+ /* Stop toggle SD clock */
+ err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
+ 0xFF, SD_CLK_FORCE_STOP);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int sd_wait_voltage_stable_2(struct realtek_pci_sdmmc *host)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int err;
+ u8 stat, mask, val;
+
+ /* Wait 1.8V output of voltage regulator in card stable */
+ msleep(50);
+
+ /* Toggle SD clock again */
+ err = rtsx_pci_write_register(pcr, SD_BUS_STAT, 0xFF, SD_CLK_TOGGLE_EN);
+ if (err < 0)
+ return err;
+
+ /* Wait for a period of time so that the card can drive
+ * SD_DAT[3:0] to high at 1.8V
+ */
+ msleep(20);
+
+ /* SD_CMD, SD_DAT[3:0] should be pulled high by host */
+ err = rtsx_pci_read_register(pcr, SD_BUS_STAT, &stat);
+ if (err < 0)
+ return err;
+
+ mask = SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
+ SD_DAT1_STATUS | SD_DAT0_STATUS;
+ val = SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
+ SD_DAT1_STATUS | SD_DAT0_STATUS;
+ if ((stat & mask) != val) {
+ dev_dbg(sdmmc_dev(host),
+ "%s: SD_BUS_STAT = 0x%x\n", __func__, stat);
+ rtsx_pci_write_register(pcr, SD_BUS_STAT,
+ SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
+ rtsx_pci_write_register(pcr, CARD_CLK_EN, 0xFF, 0);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int sd_change_bank_voltage(struct realtek_pci_sdmmc *host, u8 voltage)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int err;
+
+ if (voltage == SD_IO_3V3) {
+ err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
+ if (err < 0)
+ return err;
+ } else if (voltage == SD_IO_1V8) {
+ err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
+ if (err < 0)
+ return err;
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+ struct rtsx_pcr *pcr = host->pcr;
+ int err = 0;
+ u8 voltage;
+
+ dev_dbg(sdmmc_dev(host), "%s: signal_voltage = %d\n",
+ __func__, ios->signal_voltage);
+
+ if (host->eject)
+ return -ENOMEDIUM;
+
+ mutex_lock(&pcr->pcr_mutex);
+
+ rtsx_pci_start_run(pcr);
+
+ if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)
+ voltage = SD_IO_3V3;
+ else
+ voltage = SD_IO_1V8;
+
+ if (voltage == SD_IO_1V8) {
+ err = rtsx_pci_write_register(pcr,
+ SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
+ if (err < 0)
+ goto out;
+
+ err = sd_wait_voltage_stable_1(host);
+ if (err < 0)
+ goto out;
+ }
+
+ err = sd_change_bank_voltage(host, voltage);
+ if (err < 0)
+ goto out;
+
+ if (voltage == SD_IO_1V8) {
+ err = sd_wait_voltage_stable_2(host);
+ if (err < 0)
+ goto out;
+ }
+
+ /* Stop toggle SD clock in idle */
+ err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
+ SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
+
+out:
+ mutex_unlock(&pcr->pcr_mutex);
+
+ return err;
+}
+
+static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+ struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+ struct rtsx_pcr *pcr = host->pcr;
+ int err = 0;
+
+ if (host->eject)
+ return -ENOMEDIUM;
+
+ mutex_lock(&pcr->pcr_mutex);
+
+ rtsx_pci_start_run(pcr);
+
+ if (!host->ddr_mode)
+ err = sd_tuning_rx(host, MMC_SEND_TUNING_BLOCK);
+
+ mutex_unlock(&pcr->pcr_mutex);
+
+ return err;
+}
+
+static const struct mmc_host_ops realtek_pci_sdmmc_ops = {
+ .request = sdmmc_request,
+ .set_ios = sdmmc_set_ios,
+ .get_ro = sdmmc_get_ro,
+ .get_cd = sdmmc_get_cd,
+ .start_signal_voltage_switch = sdmmc_switch_voltage,
+ .execute_tuning = sdmmc_execute_tuning,
+};
+
+#ifdef CONFIG_PM
+static int rtsx_pci_sdmmc_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
+ struct mmc_host *mmc = host->mmc;
+ int err;
+
+ dev_dbg(sdmmc_dev(host), "--> %s\n", __func__);
+
+ err = mmc_suspend_host(mmc);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static int rtsx_pci_sdmmc_resume(struct platform_device *pdev)
+{
+ struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
+ struct mmc_host *mmc = host->mmc;
+
+ dev_dbg(sdmmc_dev(host), "--> %s\n", __func__);
+
+ return mmc_resume_host(mmc);
+}
+#else /* CONFIG_PM */
+#define rtsx_pci_sdmmc_suspend NULL
+#define rtsx_pci_sdmmc_resume NULL
+#endif /* CONFIG_PM */
+
+static void init_extra_caps(struct realtek_pci_sdmmc *host)
+{
+ struct mmc_host *mmc = host->mmc;
+ struct rtsx_pcr *pcr = host->pcr;
+
+ dev_dbg(sdmmc_dev(host), "pcr->extra_caps = 0x%x\n", pcr->extra_caps);
+
+ if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50)
+ mmc->caps |= MMC_CAP_UHS_SDR50;
+ if (pcr->extra_caps & EXTRA_CAPS_SD_SDR104)
+ mmc->caps |= MMC_CAP_UHS_SDR104;
+ if (pcr->extra_caps & EXTRA_CAPS_SD_DDR50)
+ mmc->caps |= MMC_CAP_UHS_DDR50;
+ if (pcr->extra_caps & EXTRA_CAPS_MMC_HSDDR)
+ mmc->caps |= MMC_CAP_1_8V_DDR;
+ if (pcr->extra_caps & EXTRA_CAPS_MMC_8BIT)
+ mmc->caps |= MMC_CAP_8_BIT_DATA;
+}
+
+static void realtek_init_host(struct realtek_pci_sdmmc *host)
+{
+ struct mmc_host *mmc = host->mmc;
+
+ mmc->f_min = 250000;
+ mmc->f_max = 208000000;
+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST |
+ MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25;
+ mmc->max_current_330 = 400;
+ mmc->max_current_180 = 800;
+ mmc->ops = &realtek_pci_sdmmc_ops;
+
+ init_extra_caps(host);
+
+ mmc->max_segs = 256;
+ mmc->max_seg_size = 65536;
+ mmc->max_blk_size = 512;
+ mmc->max_blk_count = 65535;
+ mmc->max_req_size = 524288;
+}
+
+static void rtsx_pci_sdmmc_card_event(struct platform_device *pdev)
+{
+ struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
+
+ mmc_detect_change(host->mmc, 0);
+}
+
+static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
+{
+ struct mmc_host *mmc;
+ struct realtek_pci_sdmmc *host;
+ struct rtsx_pcr *pcr;
+ struct pcr_handle *handle = pdev->dev.platform_data;
+
+ if (!handle)
+ return -ENXIO;
+
+ pcr = handle->pcr;
+ if (!pcr)
+ return -ENXIO;
+
+ dev_dbg(&(pdev->dev), ": Realtek PCI-E SDMMC controller found\n");
+
+ mmc = mmc_alloc_host(sizeof(*host), &pdev->dev);
+ if (!mmc)
+ return -ENOMEM;
+
+ host = mmc_priv(mmc);
+ host->pcr = pcr;
+ host->mmc = mmc;
+ host->pdev = pdev;
+ platform_set_drvdata(pdev, host);
+ pcr->slots[RTSX_SD_CARD].p_dev = pdev;
+ pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event;
+
+ mutex_init(&host->host_mutex);
+
+ realtek_init_host(host);
+
+ mmc_add_host(mmc);
+
+ return 0;
+}
+
+static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev)
+{
+ struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
+ struct rtsx_pcr *pcr;
+ struct mmc_host *mmc;
+
+ if (!host)
+ return 0;
+
+ pcr = host->pcr;
+ pcr->slots[RTSX_SD_CARD].p_dev = NULL;
+ pcr->slots[RTSX_SD_CARD].card_event = NULL;
+ mmc = host->mmc;
+ host->eject = true;
+
+ mutex_lock(&host->host_mutex);
+ if (host->mrq) {
+ dev_dbg(&(pdev->dev),
+ "%s: Controller removed during transfer\n",
+ mmc_hostname(mmc));
+
+ rtsx_pci_complete_unfinished_transfer(pcr);
+
+ host->mrq->cmd->error = -ENOMEDIUM;
+ if (host->mrq->stop)
+ host->mrq->stop->error = -ENOMEDIUM;
+ mmc_request_done(mmc, host->mrq);
+ }
+ mutex_unlock(&host->host_mutex);
+
+ mmc_remove_host(mmc);
+ mmc_free_host(mmc);
+
+ platform_set_drvdata(pdev, NULL);
+
+ dev_dbg(&(pdev->dev),
+ ": Realtek PCI-E SDMMC controller has been removed\n");
+
+ return 0;
+}
+
+static struct platform_device_id rtsx_pci_sdmmc_ids[] = {
+ {
+ .name = DRV_NAME_RTSX_PCI_SDMMC,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(platform, rtsx_pci_sdmmc_ids);
+
+static struct platform_driver rtsx_pci_sdmmc_driver = {
+ .probe = rtsx_pci_sdmmc_drv_probe,
+ .remove = rtsx_pci_sdmmc_drv_remove,
+ .id_table = rtsx_pci_sdmmc_ids,
+ .suspend = rtsx_pci_sdmmc_suspend,
+ .resume = rtsx_pci_sdmmc_resume,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRV_NAME_RTSX_PCI_SDMMC,
+ },
+};
+module_platform_driver(rtsx_pci_sdmmc_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Wei WANG <wei_wang@realsil.com.cn>");
+MODULE_DESCRIPTION("Realtek PCI-E SD/MMC Card Host Driver");
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 4638ddab97b..63fb265e0da 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -1540,7 +1540,7 @@ static inline void s3cmci_debugfs_remove(struct s3cmci_host *host) { }
#endif /* CONFIG_DEBUG_FS */
-static int __devinit s3cmci_probe(struct platform_device *pdev)
+static int s3cmci_probe(struct platform_device *pdev)
{
struct s3cmci_host *host;
struct mmc_host *mmc;
@@ -1819,7 +1819,7 @@ static void s3cmci_shutdown(struct platform_device *pdev)
clk_disable(host->clk);
}
-static int __devexit s3cmci_remove(struct platform_device *pdev)
+static int s3cmci_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
struct s3cmci_host *host = mmc_priv(mmc);
@@ -1906,7 +1906,7 @@ static struct platform_driver s3cmci_driver = {
},
.id_table = s3cmci_driver_ids,
.probe = s3cmci_probe,
- .remove = __devexit_p(s3cmci_remove),
+ .remove = s3cmci_remove,
.shutdown = s3cmci_shutdown,
};
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
new file mode 100644
index 00000000000..12b0a78497f
--- /dev/null
+++ b/drivers/mmc/host/sdhci-acpi.c
@@ -0,0 +1,312 @@
+/*
+ * Secure Digital Host Controller Interface ACPI driver.
+ *
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/compiler.h>
+#include <linux/stddef.h>
+#include <linux/bitops.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/acpi.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/pm.h>
+#include <linux/mmc/sdhci.h>
+
+#include "sdhci.h"
+
+enum {
+ SDHCI_ACPI_SD_CD = BIT(0),
+ SDHCI_ACPI_RUNTIME_PM = BIT(1),
+};
+
+struct sdhci_acpi_chip {
+ const struct sdhci_ops *ops;
+ unsigned int quirks;
+ unsigned int quirks2;
+ unsigned long caps;
+ unsigned int caps2;
+ mmc_pm_flag_t pm_caps;
+};
+
+struct sdhci_acpi_slot {
+ const struct sdhci_acpi_chip *chip;
+ unsigned int quirks;
+ unsigned int quirks2;
+ unsigned long caps;
+ unsigned int caps2;
+ mmc_pm_flag_t pm_caps;
+ unsigned int flags;
+};
+
+struct sdhci_acpi_host {
+ struct sdhci_host *host;
+ const struct sdhci_acpi_slot *slot;
+ struct platform_device *pdev;
+ bool use_runtime_pm;
+};
+
+static inline bool sdhci_acpi_flag(struct sdhci_acpi_host *c, unsigned int flag)
+{
+ return c->slot && (c->slot->flags & flag);
+}
+
+static int sdhci_acpi_enable_dma(struct sdhci_host *host)
+{
+ return 0;
+}
+
+static const struct sdhci_ops sdhci_acpi_ops_dflt = {
+ .enable_dma = sdhci_acpi_enable_dma,
+};
+
+static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = {
+ .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
+ .caps = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD,
+ .flags = SDHCI_ACPI_RUNTIME_PM,
+ .pm_caps = MMC_PM_KEEP_POWER,
+};
+
+static const struct acpi_device_id sdhci_acpi_ids[] = {
+ { "INT33C6", (kernel_ulong_t)&sdhci_acpi_slot_int_sdio },
+ { "PNP0D40" },
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, sdhci_acpi_ids);
+
+static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(const char *hid)
+{
+ const struct acpi_device_id *id;
+
+ for (id = sdhci_acpi_ids; id->id[0]; id++)
+ if (!strcmp(id->id, hid))
+ return (const struct sdhci_acpi_slot *)id->driver_data;
+ return NULL;
+}
+
+static int __devinit sdhci_acpi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ acpi_handle handle = ACPI_HANDLE(dev);
+ struct acpi_device *device;
+ struct sdhci_acpi_host *c;
+ struct sdhci_host *host;
+ struct resource *iomem;
+ resource_size_t len;
+ const char *hid;
+ int err;
+
+ if (acpi_bus_get_device(handle, &device))
+ return -ENODEV;
+
+ if (acpi_bus_get_status(device) || !device->status.present)
+ return -ENODEV;
+
+ hid = acpi_device_hid(device);
+
+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!iomem)
+ return -ENOMEM;
+
+ len = resource_size(iomem);
+ if (len < 0x100)
+ dev_err(dev, "Invalid iomem size!\n");
+
+ if (!devm_request_mem_region(dev, iomem->start, len, dev_name(dev)))
+ return -ENOMEM;
+
+ host = sdhci_alloc_host(dev, sizeof(struct sdhci_acpi_host));
+ if (IS_ERR(host))
+ return PTR_ERR(host);
+
+ c = sdhci_priv(host);
+ c->host = host;
+ c->slot = sdhci_acpi_get_slot(hid);
+ c->pdev = pdev;
+ c->use_runtime_pm = sdhci_acpi_flag(c, SDHCI_ACPI_RUNTIME_PM);
+
+ platform_set_drvdata(pdev, c);
+
+ host->hw_name = "ACPI";
+ host->ops = &sdhci_acpi_ops_dflt;
+ host->irq = platform_get_irq(pdev, 0);
+
+ host->ioaddr = devm_ioremap_nocache(dev, iomem->start,
+ resource_size(iomem));
+ if (host->ioaddr == NULL) {
+ err = -ENOMEM;
+ goto err_free;
+ }
+
+ if (!dev->dma_mask) {
+ u64 dma_mask;
+
+ if (sdhci_readl(host, SDHCI_CAPABILITIES) & SDHCI_CAN_64BIT) {
+ /* 64-bit DMA is not supported at present */
+ dma_mask = DMA_BIT_MASK(32);
+ } else {
+ dma_mask = DMA_BIT_MASK(32);
+ }
+
+ dev->dma_mask = &dev->coherent_dma_mask;
+ dev->coherent_dma_mask = dma_mask;
+ }
+
+ if (c->slot) {
+ if (c->slot->chip) {
+ host->ops = c->slot->chip->ops;
+ host->quirks |= c->slot->chip->quirks;
+ host->quirks2 |= c->slot->chip->quirks2;
+ host->mmc->caps |= c->slot->chip->caps;
+ host->mmc->caps2 |= c->slot->chip->caps2;
+ host->mmc->pm_caps |= c->slot->chip->pm_caps;
+ }
+ host->quirks |= c->slot->quirks;
+ host->quirks2 |= c->slot->quirks2;
+ host->mmc->caps |= c->slot->caps;
+ host->mmc->caps2 |= c->slot->caps2;
+ host->mmc->pm_caps |= c->slot->pm_caps;
+ }
+
+ err = sdhci_add_host(host);
+ if (err)
+ goto err_free;
+
+ if (c->use_runtime_pm) {
+ pm_suspend_ignore_children(dev, 1);
+ pm_runtime_set_autosuspend_delay(dev, 50);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_enable(dev);
+ }
+
+ return 0;
+
+err_free:
+ platform_set_drvdata(pdev, NULL);
+ sdhci_free_host(c->host);
+ return err;
+}
+
+static int __devexit sdhci_acpi_remove(struct platform_device *pdev)
+{
+ struct sdhci_acpi_host *c = platform_get_drvdata(pdev);
+ struct device *dev = &pdev->dev;
+ int dead;
+
+ if (c->use_runtime_pm) {
+ pm_runtime_get_sync(dev);
+ pm_runtime_disable(dev);
+ pm_runtime_put_noidle(dev);
+ }
+
+ dead = (sdhci_readl(c->host, SDHCI_INT_STATUS) == ~0);
+ sdhci_remove_host(c->host, dead);
+ platform_set_drvdata(pdev, NULL);
+ sdhci_free_host(c->host);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+
+static int sdhci_acpi_suspend(struct device *dev)
+{
+ struct sdhci_acpi_host *c = dev_get_drvdata(dev);
+
+ return sdhci_suspend_host(c->host);
+}
+
+static int sdhci_acpi_resume(struct device *dev)
+{
+ struct sdhci_acpi_host *c = dev_get_drvdata(dev);
+
+ return sdhci_resume_host(c->host);
+}
+
+#else
+
+#define sdhci_acpi_suspend NULL
+#define sdhci_acpi_resume NULL
+
+#endif
+
+#ifdef CONFIG_PM_RUNTIME
+
+static int sdhci_acpi_runtime_suspend(struct device *dev)
+{
+ struct sdhci_acpi_host *c = dev_get_drvdata(dev);
+
+ return sdhci_runtime_suspend_host(c->host);
+}
+
+static int sdhci_acpi_runtime_resume(struct device *dev)
+{
+ struct sdhci_acpi_host *c = dev_get_drvdata(dev);
+
+ return sdhci_runtime_resume_host(c->host);
+}
+
+static int sdhci_acpi_runtime_idle(struct device *dev)
+{
+ return 0;
+}
+
+#else
+
+#define sdhci_acpi_runtime_suspend NULL
+#define sdhci_acpi_runtime_resume NULL
+#define sdhci_acpi_runtime_idle NULL
+
+#endif
+
+static const struct dev_pm_ops sdhci_acpi_pm_ops = {
+ .suspend = sdhci_acpi_suspend,
+ .resume = sdhci_acpi_resume,
+ .runtime_suspend = sdhci_acpi_runtime_suspend,
+ .runtime_resume = sdhci_acpi_runtime_resume,
+ .runtime_idle = sdhci_acpi_runtime_idle,
+};
+
+static struct platform_driver sdhci_acpi_driver = {
+ .driver = {
+ .name = "sdhci-acpi",
+ .owner = THIS_MODULE,
+ .acpi_match_table = sdhci_acpi_ids,
+ .pm = &sdhci_acpi_pm_ops,
+ },
+ .probe = sdhci_acpi_probe,
+ .remove = __devexit_p(sdhci_acpi_remove),
+};
+
+module_platform_driver(sdhci_acpi_driver);
+
+MODULE_DESCRIPTION("Secure Digital Host Controller Interface ACPI driver");
+MODULE_AUTHOR("Adrian Hunter");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 28a870804f6..30bfdc4ae52 100644
--- a/drivers/mmc/host/sdhci-cns3xxx.c
+++ b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -95,12 +95,12 @@ static struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
SDHCI_QUIRK_NONSTANDARD_CLOCK,
};
-static int __devinit sdhci_cns3xxx_probe(struct platform_device *pdev)
+static int sdhci_cns3xxx_probe(struct platform_device *pdev)
{
return sdhci_pltfm_register(pdev, &sdhci_cns3xxx_pdata);
}
-static int __devexit sdhci_cns3xxx_remove(struct platform_device *pdev)
+static int sdhci_cns3xxx_remove(struct platform_device *pdev)
{
return sdhci_pltfm_unregister(pdev);
}
@@ -112,7 +112,7 @@ static struct platform_driver sdhci_cns3xxx_driver = {
.pm = SDHCI_PLTFM_PMOPS,
},
.probe = sdhci_cns3xxx_probe,
- .remove = __devexit_p(sdhci_cns3xxx_remove),
+ .remove = sdhci_cns3xxx_remove,
};
module_platform_driver(sdhci_cns3xxx_driver);
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 8fd50a21103..169fab91778 100644
--- a/drivers/mmc/host/sdhci-dove.c
+++ b/drivers/mmc/host/sdhci-dove.c
@@ -19,20 +19,30 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/err.h>
-#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
-#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
#include <linux/mmc/host.h>
+#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_gpio.h>
#include "sdhci-pltfm.h"
struct sdhci_dove_priv {
struct clk *clk;
+ int gpio_cd;
};
+static irqreturn_t sdhci_dove_carddetect_irq(int irq, void *data)
+{
+ struct sdhci_host *host = data;
+
+ tasklet_schedule(&host->card_tasklet);
+ return IRQ_HANDLED;
+}
+
static u16 sdhci_dove_readw(struct sdhci_host *host, int reg)
{
u16 ret;
@@ -50,16 +60,25 @@ static u16 sdhci_dove_readw(struct sdhci_host *host, int reg)
static u32 sdhci_dove_readl(struct sdhci_host *host, int reg)
{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_dove_priv *priv = pltfm_host->priv;
u32 ret;
+ ret = readl(host->ioaddr + reg);
+
switch (reg) {
case SDHCI_CAPABILITIES:
- ret = readl(host->ioaddr + reg);
/* Mask the support for 3.0V */
ret &= ~SDHCI_CAN_VDD_300;
break;
- default:
- ret = readl(host->ioaddr + reg);
+ case SDHCI_PRESENT_STATE:
+ if (gpio_is_valid(priv->gpio_cd)) {
+ if (gpio_get_value(priv->gpio_cd) == 0)
+ ret |= SDHCI_CARD_PRESENT;
+ else
+ ret &= ~SDHCI_CARD_PRESENT;
+ }
+ break;
}
return ret;
}
@@ -78,7 +97,7 @@ static struct sdhci_pltfm_data sdhci_dove_pdata = {
SDHCI_QUIRK_NO_HISPD_BIT,
};
-static int __devinit sdhci_dove_probe(struct platform_device *pdev)
+static int sdhci_dove_probe(struct platform_device *pdev)
{
struct sdhci_host *host;
struct sdhci_pltfm_host *pltfm_host;
@@ -92,29 +111,74 @@ static int __devinit sdhci_dove_probe(struct platform_device *pdev)
return -ENOMEM;
}
- priv->clk = clk_get(&pdev->dev, NULL);
- if (!IS_ERR(priv->clk))
- clk_prepare_enable(priv->clk);
+ priv->clk = devm_clk_get(&pdev->dev, NULL);
- ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata);
- if (ret)
- goto sdhci_dove_register_fail;
+ if (pdev->dev.of_node) {
+ priv->gpio_cd = of_get_named_gpio(pdev->dev.of_node,
+ "cd-gpios", 0);
+ } else {
+ priv->gpio_cd = -EINVAL;
+ }
+
+ if (gpio_is_valid(priv->gpio_cd)) {
+ ret = gpio_request(priv->gpio_cd, "sdhci-cd");
+ if (ret) {
+ dev_err(&pdev->dev, "card detect gpio request failed: %d\n",
+ ret);
+ return ret;
+ }
+ gpio_direction_input(priv->gpio_cd);
+ }
+
+ host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata);
+ if (IS_ERR(host)) {
+ ret = PTR_ERR(host);
+ goto err_sdhci_pltfm_init;
+ }
- host = platform_get_drvdata(pdev);
pltfm_host = sdhci_priv(host);
pltfm_host->priv = priv;
+ if (!IS_ERR(priv->clk))
+ clk_prepare_enable(priv->clk);
+
+ sdhci_get_of_property(pdev);
+
+ ret = sdhci_add_host(host);
+ if (ret)
+ goto err_sdhci_add;
+
+ /*
+ * We must request the IRQ after sdhci_add_host(), as the tasklet only
+ * gets setup in sdhci_add_host() and we oops.
+ */
+ if (gpio_is_valid(priv->gpio_cd)) {
+ ret = request_irq(gpio_to_irq(priv->gpio_cd),
+ sdhci_dove_carddetect_irq,
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ mmc_hostname(host->mmc), host);
+ if (ret) {
+ dev_err(&pdev->dev, "card detect irq request failed: %d\n",
+ ret);
+ goto err_request_irq;
+ }
+ }
+
return 0;
-sdhci_dove_register_fail:
- if (!IS_ERR(priv->clk)) {
+err_request_irq:
+ sdhci_remove_host(host, 0);
+err_sdhci_add:
+ if (!IS_ERR(priv->clk))
clk_disable_unprepare(priv->clk);
- clk_put(priv->clk);
- }
+ sdhci_pltfm_free(pdev);
+err_sdhci_pltfm_init:
+ if (gpio_is_valid(priv->gpio_cd))
+ gpio_free(priv->gpio_cd);
return ret;
}
-static int __devexit sdhci_dove_remove(struct platform_device *pdev)
+static int sdhci_dove_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -122,14 +186,18 @@ static int __devexit sdhci_dove_remove(struct platform_device *pdev)
sdhci_pltfm_unregister(pdev);
- if (!IS_ERR(priv->clk)) {
- clk_disable_unprepare(priv->clk);
- clk_put(priv->clk);
+ if (gpio_is_valid(priv->gpio_cd)) {
+ free_irq(gpio_to_irq(priv->gpio_cd), host);
+ gpio_free(priv->gpio_cd);
}
+
+ if (!IS_ERR(priv->clk))
+ clk_disable_unprepare(priv->clk);
+
return 0;
}
-static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = {
+static const struct of_device_id sdhci_dove_of_match_table[] = {
{ .compatible = "marvell,dove-sdhci", },
{}
};
@@ -143,7 +211,7 @@ static struct platform_driver sdhci_dove_driver = {
.of_match_table = of_match_ptr(sdhci_dove_of_match_table),
},
.probe = sdhci_dove_probe,
- .remove = __devexit_p(sdhci_dove_remove),
+ .remove = sdhci_dove_remove,
};
module_platform_driver(sdhci_dove_driver);
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index effc2acfe77..e07df812ff1 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -403,7 +403,7 @@ static irqreturn_t cd_irq(int irq, void *data)
};
#ifdef CONFIG_OF
-static int __devinit
+static int
sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
struct esdhc_platform_data *boarddata)
{
@@ -440,7 +440,7 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
}
#endif
-static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
+static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
of_match_device(imx_esdhc_dt_ids, &pdev->dev);
@@ -456,10 +456,10 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
pltfm_host = sdhci_priv(host);
- imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
+ imx_data = devm_kzalloc(&pdev->dev, sizeof(*imx_data), GFP_KERNEL);
if (!imx_data) {
err = -ENOMEM;
- goto err_imx_data;
+ goto free_sdhci;
}
if (of_id)
@@ -470,19 +470,19 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
if (IS_ERR(imx_data->clk_ipg)) {
err = PTR_ERR(imx_data->clk_ipg);
- goto err_clk_get;
+ goto free_sdhci;
}
imx_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
if (IS_ERR(imx_data->clk_ahb)) {
err = PTR_ERR(imx_data->clk_ahb);
- goto err_clk_get;
+ goto free_sdhci;
}
imx_data->clk_per = devm_clk_get(&pdev->dev, "per");
if (IS_ERR(imx_data->clk_per)) {
err = PTR_ERR(imx_data->clk_per);
- goto err_clk_get;
+ goto free_sdhci;
}
pltfm_host->clk = imx_data->clk_per;
@@ -494,7 +494,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
imx_data->pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
if (IS_ERR(imx_data->pinctrl)) {
err = PTR_ERR(imx_data->pinctrl);
- goto pin_err;
+ goto disable_clk;
}
host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
@@ -519,7 +519,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
if (!host->mmc->parent->platform_data) {
dev_err(mmc_dev(host->mmc), "no board data!\n");
err = -EINVAL;
- goto no_board_data;
+ goto disable_clk;
}
imx_data->boarddata = *((struct esdhc_platform_data *)
host->mmc->parent->platform_data);
@@ -527,7 +527,8 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
/* write_protect */
if (boarddata->wp_type == ESDHC_WP_GPIO) {
- err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP");
+ err = devm_gpio_request_one(&pdev->dev, boarddata->wp_gpio,
+ GPIOF_IN, "ESDHC_WP");
if (err) {
dev_warn(mmc_dev(host->mmc),
"no write-protect pin available!\n");
@@ -543,19 +544,21 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
switch (boarddata->cd_type) {
case ESDHC_CD_GPIO:
- err = gpio_request_one(boarddata->cd_gpio, GPIOF_IN, "ESDHC_CD");
+ err = devm_gpio_request_one(&pdev->dev, boarddata->cd_gpio,
+ GPIOF_IN, "ESDHC_CD");
if (err) {
dev_err(mmc_dev(host->mmc),
"no card-detect pin available!\n");
- goto no_card_detect_pin;
+ goto disable_clk;
}
- err = request_irq(gpio_to_irq(boarddata->cd_gpio), cd_irq,
+ err = devm_request_irq(&pdev->dev,
+ gpio_to_irq(boarddata->cd_gpio), cd_irq,
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
mmc_hostname(host->mmc), host);
if (err) {
dev_err(mmc_dev(host->mmc), "request irq error\n");
- goto no_card_detect_irq;
+ goto disable_clk;
}
/* fall through */
@@ -574,55 +577,32 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
err = sdhci_add_host(host);
if (err)
- goto err_add_host;
+ goto disable_clk;
return 0;
-err_add_host:
- if (gpio_is_valid(boarddata->cd_gpio))
- free_irq(gpio_to_irq(boarddata->cd_gpio), host);
-no_card_detect_irq:
- if (gpio_is_valid(boarddata->cd_gpio))
- gpio_free(boarddata->cd_gpio);
- if (gpio_is_valid(boarddata->wp_gpio))
- gpio_free(boarddata->wp_gpio);
-no_card_detect_pin:
-no_board_data:
-pin_err:
+disable_clk:
clk_disable_unprepare(imx_data->clk_per);
clk_disable_unprepare(imx_data->clk_ipg);
clk_disable_unprepare(imx_data->clk_ahb);
-err_clk_get:
- kfree(imx_data);
-err_imx_data:
+free_sdhci:
sdhci_pltfm_free(pdev);
return err;
}
-static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
+static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct pltfm_imx_data *imx_data = pltfm_host->priv;
- struct esdhc_platform_data *boarddata = &imx_data->boarddata;
int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
sdhci_remove_host(host, dead);
- if (gpio_is_valid(boarddata->wp_gpio))
- gpio_free(boarddata->wp_gpio);
-
- if (gpio_is_valid(boarddata->cd_gpio)) {
- free_irq(gpio_to_irq(boarddata->cd_gpio), host);
- gpio_free(boarddata->cd_gpio);
- }
-
clk_disable_unprepare(imx_data->clk_per);
clk_disable_unprepare(imx_data->clk_ipg);
clk_disable_unprepare(imx_data->clk_ahb);
- kfree(imx_data);
-
sdhci_pltfm_free(pdev);
return 0;
@@ -637,7 +617,7 @@ static struct platform_driver sdhci_esdhc_imx_driver = {
},
.id_table = imx_esdhc_devtype,
.probe = sdhci_esdhc_imx_probe,
- .remove = __devexit_p(sdhci_esdhc_imx_remove),
+ .remove = sdhci_esdhc_imx_remove,
};
module_platform_driver(sdhci_esdhc_imx_driver);
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 63d219f57ca..f32526d2d96 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -22,6 +22,7 @@
#include "sdhci-esdhc.h"
#define VENDOR_V_22 0x12
+#define VENDOR_V_23 0x13
static u32 esdhc_readl(struct sdhci_host *host, int reg)
{
u32 ret;
@@ -85,6 +86,18 @@ static u8 esdhc_readb(struct sdhci_host *host, int reg)
return ret;
}
+static void esdhc_writel(struct sdhci_host *host, u32 val, int reg)
+{
+ /*
+ * Enable IRQSTATEN[BGESEN] is just to set IRQSTAT[BGE]
+ * when SYSCTL[RSTD]) is set for some special operations.
+ * No any impact other operation.
+ */
+ if (reg == SDHCI_INT_ENABLE)
+ val |= SDHCI_INT_BLK_GAP;
+ sdhci_be32bs_writel(host, val, reg);
+}
+
static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
{
if (reg == SDHCI_BLOCK_SIZE) {
@@ -121,6 +134,41 @@ static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
sdhci_be32bs_writeb(host, val, reg);
}
+/*
+ * For Abort or Suspend after Stop at Block Gap, ignore the ADMA
+ * error(IRQSTAT[ADMAE]) if both Transfer Complete(IRQSTAT[TC])
+ * and Block Gap Event(IRQSTAT[BGE]) are also set.
+ * For Continue, apply soft reset for data(SYSCTL[RSTD]);
+ * and re-issue the entire read transaction from beginning.
+ */
+static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask)
+{
+ u32 tmp;
+ bool applicable;
+ dma_addr_t dmastart;
+ dma_addr_t dmanow;
+
+ tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
+ tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
+
+ applicable = (intmask & SDHCI_INT_DATA_END) &&
+ (intmask & SDHCI_INT_BLK_GAP) &&
+ (tmp == VENDOR_V_23);
+ if (!applicable)
+ return;
+
+ host->data->error = 0;
+ dmastart = sg_dma_address(host->data->sg);
+ dmanow = dmastart + host->data->bytes_xfered;
+ /*
+ * Force update to the next DMA block boundary.
+ */
+ dmanow = (dmanow & ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) +
+ SDHCI_DEFAULT_BOUNDARY_SIZE;
+ host->data->bytes_xfered = dmanow - dmastart;
+ sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS);
+}
+
static int esdhc_of_enable_dma(struct sdhci_host *host)
{
setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
@@ -177,13 +225,16 @@ static void esdhc_of_platform_init(struct sdhci_host *host)
vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
if (vvn == VENDOR_V_22)
host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
+
+ if (vvn > VENDOR_V_22)
+ host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
}
static struct sdhci_ops sdhci_esdhc_ops = {
.read_l = esdhc_readl,
.read_w = esdhc_readw,
.read_b = esdhc_readb,
- .write_l = sdhci_be32bs_writel,
+ .write_l = esdhc_writel,
.write_w = esdhc_writew,
.write_b = esdhc_writeb,
.set_clock = esdhc_of_set_clock,
@@ -195,6 +246,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
.platform_suspend = esdhc_of_suspend,
.platform_resume = esdhc_of_resume,
#endif
+ .adma_workaround = esdhci_of_adma_workaround,
};
static struct sdhci_pltfm_data sdhci_esdhc_pdata = {
@@ -208,12 +260,12 @@ static struct sdhci_pltfm_data sdhci_esdhc_pdata = {
.ops = &sdhci_esdhc_ops,
};
-static int __devinit sdhci_esdhc_probe(struct platform_device *pdev)
+static int sdhci_esdhc_probe(struct platform_device *pdev)
{
return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata);
}
-static int __devexit sdhci_esdhc_remove(struct platform_device *pdev)
+static int sdhci_esdhc_remove(struct platform_device *pdev)
{
return sdhci_pltfm_unregister(pdev);
}
@@ -234,7 +286,7 @@ static struct platform_driver sdhci_esdhc_driver = {
.pm = SDHCI_PLTFM_PMOPS,
},
.probe = sdhci_esdhc_probe,
- .remove = __devexit_p(sdhci_esdhc_remove),
+ .remove = sdhci_esdhc_remove,
};
module_platform_driver(sdhci_esdhc_driver);
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index 0ce088ae022..c3d3715ec3d 100644
--- a/drivers/mmc/host/sdhci-of-hlwd.c
+++ b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -66,12 +66,12 @@ static struct sdhci_pltfm_data sdhci_hlwd_pdata = {
.ops = &sdhci_hlwd_ops,
};
-static int __devinit sdhci_hlwd_probe(struct platform_device *pdev)
+static int sdhci_hlwd_probe(struct platform_device *pdev)
{
return sdhci_pltfm_register(pdev, &sdhci_hlwd_pdata);
}
-static int __devexit sdhci_hlwd_remove(struct platform_device *pdev)
+static int sdhci_hlwd_remove(struct platform_device *pdev)
{
return sdhci_pltfm_unregister(pdev);
}
@@ -90,7 +90,7 @@ static struct platform_driver sdhci_hlwd_driver = {
.pm = SDHCI_PLTFM_PMOPS,
},
.probe = sdhci_hlwd_probe,
- .remove = __devexit_p(sdhci_hlwd_remove),
+ .remove = sdhci_hlwd_remove,
};
module_platform_driver(sdhci_hlwd_driver);
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 04936f353ce..c7dd0cbc99d 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -114,6 +114,7 @@ static int ricoh_mmc_probe_slot(struct sdhci_pci_slot *slot)
SDHCI_TIMEOUT_CLK_UNIT |
SDHCI_CAN_VDD_330 |
+ SDHCI_CAN_DO_HISPD |
SDHCI_CAN_DO_SDMA;
return 0;
}
@@ -653,7 +654,7 @@ static const struct sdhci_pci_fixes sdhci_via = {
.probe = via_probe,
};
-static const struct pci_device_id pci_ids[] __devinitconst = {
+static const struct pci_device_id pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_RICOH,
.device = PCI_DEVICE_ID_RICOH_R5C822,
@@ -1183,7 +1184,7 @@ static const struct dev_pm_ops sdhci_pci_pm_ops = {
* *
\*****************************************************************************/
-static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
+static struct sdhci_pci_slot *sdhci_pci_probe_slot(
struct pci_dev *pdev, struct sdhci_pci_chip *chip, int first_bar,
int slotno)
{
@@ -1338,7 +1339,7 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot)
sdhci_free_host(slot->host);
}
-static void __devinit sdhci_pci_runtime_pm_allow(struct device *dev)
+static void sdhci_pci_runtime_pm_allow(struct device *dev)
{
pm_runtime_put_noidle(dev);
pm_runtime_allow(dev);
@@ -1347,13 +1348,13 @@ static void __devinit sdhci_pci_runtime_pm_allow(struct device *dev)
pm_suspend_ignore_children(dev, 1);
}
-static void __devexit sdhci_pci_runtime_pm_forbid(struct device *dev)
+static void sdhci_pci_runtime_pm_forbid(struct device *dev)
{
pm_runtime_forbid(dev);
pm_runtime_get_noresume(dev);
}
-static int __devinit sdhci_pci_probe(struct pci_dev *pdev,
+static int sdhci_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct sdhci_pci_chip *chip;
@@ -1445,7 +1446,7 @@ err:
return ret;
}
-static void __devexit sdhci_pci_remove(struct pci_dev *pdev)
+static void sdhci_pci_remove(struct pci_dev *pdev)
{
int i;
struct sdhci_pci_chip *chip;
@@ -1470,7 +1471,7 @@ static struct pci_driver sdhci_driver = {
.name = "sdhci-pci",
.id_table = pci_ids,
.probe = sdhci_pci_probe,
- .remove = __devexit_p(sdhci_pci_remove),
+ .remove = sdhci_pci_remove,
.driver = {
.pm = &sdhci_pci_pm_ops
},
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 27164457f86..d4283ef5917 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -78,6 +78,9 @@ void sdhci_get_of_property(struct platform_device *pdev)
if (of_get_property(np, "broken-cd", NULL))
host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+ if (of_get_property(np, "no-1-8-v", NULL))
+ host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
+
if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc"))
host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
@@ -89,6 +92,12 @@ void sdhci_get_of_property(struct platform_device *pdev)
clk = of_get_property(np, "clock-frequency", &size);
if (clk && size == sizeof(*clk) && *clk)
pltfm_host->clock = be32_to_cpup(clk);
+
+ if (of_find_property(np, "keep-power-in-suspend", NULL))
+ host->mmc->pm_caps |= MMC_PM_KEEP_POWER;
+
+ if (of_find_property(np, "enable-sdio-wakeup", NULL))
+ host->mmc->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
}
}
#else
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index 8e63a9c04e3..ac854aa192a 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -166,7 +166,7 @@ static inline struct sdhci_pxa_platdata *pxav2_get_mmc_pdata(struct device *dev)
}
#endif
-static int __devinit sdhci_pxav2_probe(struct platform_device *pdev)
+static int sdhci_pxav2_probe(struct platform_device *pdev)
{
struct sdhci_pltfm_host *pltfm_host;
struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
@@ -247,7 +247,7 @@ err_clk_get:
return ret;
}
-static int __devexit sdhci_pxav2_remove(struct platform_device *pdev)
+static int sdhci_pxav2_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -275,7 +275,7 @@ static struct platform_driver sdhci_pxav2_driver = {
.pm = SDHCI_PLTFM_PMOPS,
},
.probe = sdhci_pxav2_probe,
- .remove = __devexit_p(sdhci_pxav2_remove),
+ .remove = sdhci_pxav2_remove,
};
module_platform_driver(sdhci_pxav2_driver);
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index e918a2bb3af..fad0966427f 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -163,10 +163,18 @@ static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
return 0;
}
+static u32 pxav3_get_max_clock(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ return clk_get_rate(pltfm_host->clk);
+}
+
static struct sdhci_ops pxav3_sdhci_ops = {
.platform_reset_exit = pxav3_set_private_registers,
.set_uhs_signaling = pxav3_set_uhs_signaling,
.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
+ .get_max_clock = pxav3_get_max_clock,
};
#ifdef CONFIG_OF
@@ -214,7 +222,7 @@ static inline struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev)
}
#endif
-static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
+static int sdhci_pxav3_probe(struct platform_device *pdev)
{
struct sdhci_pltfm_host *pltfm_host;
struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
@@ -249,7 +257,8 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
host->quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
- | SDHCI_QUIRK_32BIT_ADMA_SIZE;
+ | SDHCI_QUIRK_32BIT_ADMA_SIZE
+ | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN;
/* enable 1/8V DDR capable */
host->mmc->caps |= MMC_CAP_1_8V_DDR;
@@ -271,6 +280,8 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
if (pdata->quirks)
host->quirks |= pdata->quirks;
+ if (pdata->quirks2)
+ host->quirks2 |= pdata->quirks2;
if (pdata->host_caps)
host->mmc->caps |= pdata->host_caps;
if (pdata->host_caps2)
@@ -313,7 +324,7 @@ err_clk_get:
return ret;
}
-static int __devexit sdhci_pxav3_remove(struct platform_device *pdev)
+static int sdhci_pxav3_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -346,7 +357,7 @@ static struct platform_driver sdhci_pxav3_driver = {
.pm = SDHCI_PLTFM_PMOPS,
},
.probe = sdhci_pxav3_probe,
- .remove = __devexit_p(sdhci_pxav3_remove),
+ .remove = sdhci_pxav3_remove,
};
module_platform_driver(sdhci_pxav3_driver);
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index a54dd5d7a5f..82a8de148a8 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -24,6 +24,7 @@
#include <linux/of_gpio.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/mmc/host.h>
@@ -57,6 +58,7 @@ struct sdhci_s3c {
int ext_cd_irq;
int ext_cd_gpio;
int *gpios;
+ struct pinctrl *pctrl;
struct clk *clk_io;
struct clk *clk_bus[MAX_BUS_CLK];
@@ -373,18 +375,27 @@ static struct sdhci_ops sdhci_s3c_ops = {
static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
{
struct sdhci_host *host = platform_get_drvdata(dev);
+#ifdef CONFIG_PM_RUNTIME
+ struct sdhci_s3c *sc = sdhci_priv(host);
+#endif
unsigned long flags;
if (host) {
spin_lock_irqsave(&host->lock, flags);
if (state) {
dev_dbg(&dev->dev, "card inserted.\n");
+#ifdef CONFIG_PM_RUNTIME
+ clk_prepare_enable(sc->clk_io);
+#endif
host->flags &= ~SDHCI_DEVICE_DEAD;
host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
} else {
dev_dbg(&dev->dev, "card removed.\n");
host->flags |= SDHCI_DEVICE_DEAD;
host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+#ifdef CONFIG_PM_RUNTIME
+ clk_disable_unprepare(sc->clk_io);
+#endif
}
tasklet_schedule(&host->card_tasklet);
spin_unlock_irqrestore(&host->lock, flags);
@@ -406,7 +417,7 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc)
struct s3c_sdhci_platdata *pdata = sc->pdata;
struct device *dev = &sc->pdev->dev;
- if (gpio_request(pdata->ext_cd_gpio, "SDHCI EXT CD") == 0) {
+ if (devm_gpio_request(dev, pdata->ext_cd_gpio, "SDHCI EXT CD") == 0) {
sc->ext_cd_gpio = pdata->ext_cd_gpio;
sc->ext_cd_irq = gpio_to_irq(pdata->ext_cd_gpio);
if (sc->ext_cd_irq &&
@@ -430,7 +441,7 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc)
}
#ifdef CONFIG_OF
-static int __devinit sdhci_s3c_parse_dt(struct device *dev,
+static int sdhci_s3c_parse_dt(struct device *dev,
struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
{
struct device_node *node = dev->of_node;
@@ -449,12 +460,12 @@ static int __devinit sdhci_s3c_parse_dt(struct device *dev,
return -ENOMEM;
/* get the card detection method */
- if (of_get_property(node, "broken-cd", 0)) {
+ if (of_get_property(node, "broken-cd", NULL)) {
pdata->cd_type = S3C_SDHCI_CD_NONE;
goto setup_bus;
}
- if (of_get_property(node, "non-removable", 0)) {
+ if (of_get_property(node, "non-removable", NULL)) {
pdata->cd_type = S3C_SDHCI_CD_PERMANENT;
goto setup_bus;
}
@@ -477,8 +488,9 @@ static int __devinit sdhci_s3c_parse_dt(struct device *dev,
return -EINVAL;
}
- dev_info(dev, "assuming no card detect line available\n");
- pdata->cd_type = S3C_SDHCI_CD_NONE;
+ /* assuming internal card detect that will be configured by pinctrl */
+ pdata->cd_type = S3C_SDHCI_CD_INTERNAL;
+ goto setup_bus;
found_cd:
if (pdata->cd_type == S3C_SDHCI_CD_GPIO) {
@@ -487,7 +499,7 @@ static int __devinit sdhci_s3c_parse_dt(struct device *dev,
if (of_get_property(node, "cd-inverted", NULL))
pdata->ext_cd_gpio_invert = 1;
} else if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
- ret = gpio_request(gpio, "sdhci-cd");
+ ret = devm_gpio_request(dev, gpio, "sdhci-cd");
if (ret) {
dev_err(dev, "card detect gpio request failed\n");
return -EINVAL;
@@ -496,36 +508,31 @@ static int __devinit sdhci_s3c_parse_dt(struct device *dev,
}
setup_bus:
+ if (!IS_ERR(ourhost->pctrl))
+ return 0;
+
/* get the gpios for command, clock and data lines */
for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) {
gpio = of_get_gpio(node, cnt);
if (!gpio_is_valid(gpio)) {
dev_err(dev, "invalid gpio[%d]\n", cnt);
- goto err_free_dt_cd_gpio;
+ return -EINVAL;
}
ourhost->gpios[cnt] = gpio;
}
for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) {
- ret = gpio_request(ourhost->gpios[cnt], "sdhci-gpio");
+ ret = devm_gpio_request(dev, ourhost->gpios[cnt], "sdhci-gpio");
if (ret) {
dev_err(dev, "gpio[%d] request failed\n", cnt);
- goto err_free_dt_gpios;
+ return -EINVAL;
}
}
return 0;
-
- err_free_dt_gpios:
- while (--cnt >= 0)
- gpio_free(ourhost->gpios[cnt]);
- err_free_dt_cd_gpio:
- if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL)
- gpio_free(ourhost->ext_cd_gpio);
- return -EINVAL;
}
#else
-static int __devinit sdhci_s3c_parse_dt(struct device *dev,
+static int sdhci_s3c_parse_dt(struct device *dev,
struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
{
return -EINVAL;
@@ -548,7 +555,7 @@ static inline struct sdhci_s3c_drv_data *sdhci_s3c_get_driver_data(
platform_get_device_id(pdev)->driver_data;
}
-static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
+static int sdhci_s3c_probe(struct platform_device *pdev)
{
struct s3c_sdhci_platdata *pdata;
struct sdhci_s3c_drv_data *drv_data;
@@ -579,13 +586,15 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
ret = -ENOMEM;
- goto err_pdata;
+ goto err_pdata_io_clk;
}
+ sc->pctrl = devm_pinctrl_get_select_default(&pdev->dev);
+
if (pdev->dev.of_node) {
ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata);
if (ret)
- goto err_pdata;
+ goto err_pdata_io_clk;
} else {
memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
sc->ext_cd_gpio = -1; /* invalid gpio number */
@@ -603,7 +612,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
if (IS_ERR(sc->clk_io)) {
dev_err(dev, "failed to get io clock\n");
ret = PTR_ERR(sc->clk_io);
- goto err_io_clk;
+ goto err_pdata_io_clk;
}
/* enable the local io clock and keep it running for the moment. */
@@ -766,19 +775,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
clk_disable_unprepare(sc->clk_io);
clk_put(sc->clk_io);
- err_io_clk:
- for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++)
- gpio_free(sc->gpios[ptr]);
- if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL)
- gpio_free(sc->ext_cd_gpio);
-
- err_pdata:
+ err_pdata_io_clk:
sdhci_free_host(host);
return ret;
}
-static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
+static int sdhci_s3c_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_s3c *sc = sdhci_priv(host);
@@ -791,9 +794,6 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
if (sc->ext_cd_irq)
free_irq(sc->ext_cd_irq, sc);
- if (gpio_is_valid(sc->ext_cd_gpio))
- gpio_free(sc->ext_cd_gpio);
-
#ifdef CONFIG_PM_RUNTIME
if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
clk_prepare_enable(sc->clk_io);
@@ -814,11 +814,6 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
clk_disable_unprepare(sc->clk_io);
clk_put(sc->clk_io);
- if (pdev->dev.of_node) {
- for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++)
- gpio_free(sc->gpios[ptr]);
- }
-
sdhci_free_host(host);
platform_set_drvdata(pdev, NULL);
@@ -916,7 +911,7 @@ MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
static struct platform_driver sdhci_s3c_driver = {
.probe = sdhci_s3c_probe,
- .remove = __devexit_p(sdhci_s3c_remove),
+ .remove = sdhci_s3c_remove,
.id_table = sdhci_s3c_driver_ids,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 6be89c032de..c6ece0bd03b 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -71,8 +71,7 @@ static irqreturn_t sdhci_gpio_irq(int irq, void *dev_id)
}
#ifdef CONFIG_OF
-static struct sdhci_plat_data * __devinit
-sdhci_probe_config_dt(struct platform_device *pdev)
+static struct sdhci_plat_data *sdhci_probe_config_dt(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct sdhci_plat_data *pdata = NULL;
@@ -96,14 +95,13 @@ sdhci_probe_config_dt(struct platform_device *pdev)
return pdata;
}
#else
-static struct sdhci_plat_data * __devinit
-sdhci_probe_config_dt(struct platform_device *pdev)
+static struct sdhci_plat_data *sdhci_probe_config_dt(struct platform_device *pdev)
{
return ERR_PTR(-ENOSYS);
}
#endif
-static int __devinit sdhci_probe(struct platform_device *pdev)
+static int sdhci_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct sdhci_host *host;
@@ -146,6 +144,11 @@ static int __devinit sdhci_probe(struct platform_device *pdev)
goto put_clk;
}
+ ret = clk_set_rate(sdhci->clk, 50000000);
+ if (ret)
+ dev_dbg(&pdev->dev, "Error setting desired clk, clk=%lu\n",
+ clk_get_rate(sdhci->clk));
+
if (np) {
sdhci->data = sdhci_probe_config_dt(pdev);
if (IS_ERR(sdhci->data)) {
@@ -268,7 +271,7 @@ err:
return ret;
}
-static int __devexit sdhci_remove(struct platform_device *pdev)
+static int sdhci_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev);
@@ -297,7 +300,7 @@ static int sdhci_suspend(struct device *dev)
ret = sdhci_suspend_host(host);
if (!ret)
- clk_disable_unprepare(sdhci->clk);
+ clk_disable(sdhci->clk);
return ret;
}
@@ -308,7 +311,7 @@ static int sdhci_resume(struct device *dev)
struct spear_sdhci *sdhci = dev_get_platdata(dev);
int ret;
- ret = clk_prepare_enable(sdhci->clk);
+ ret = clk_enable(sdhci->clk);
if (ret) {
dev_dbg(dev, "Resume: Error enabling clock\n");
return ret;
@@ -336,7 +339,7 @@ static struct platform_driver sdhci_driver = {
.of_match_table = of_match_ptr(sdhci_spear_id_table),
},
.probe = sdhci_probe,
- .remove = __devexit_p(sdhci_remove),
+ .remove = sdhci_remove,
};
module_platform_driver(sdhci_driver);
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index f9eb9162370..3695b2e0cbd 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -206,7 +206,7 @@ static struct sdhci_tegra_soc_data soc_data_tegra30 = {
};
#endif
-static const struct of_device_id sdhci_tegra_dt_match[] __devinitdata = {
+static const struct of_device_id sdhci_tegra_dt_match[] = {
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
{ .compatible = "nvidia,tegra30-sdhci", .data = &soc_data_tegra30 },
#endif
@@ -217,7 +217,7 @@ static const struct of_device_id sdhci_tegra_dt_match[] __devinitdata = {
};
MODULE_DEVICE_TABLE(of, sdhci_dt_ids);
-static struct tegra_sdhci_platform_data * __devinit sdhci_tegra_dt_parse_pdata(
+static struct tegra_sdhci_platform_data *sdhci_tegra_dt_parse_pdata(
struct platform_device *pdev)
{
struct tegra_sdhci_platform_data *plat;
@@ -244,7 +244,7 @@ static struct tegra_sdhci_platform_data * __devinit sdhci_tegra_dt_parse_pdata(
return plat;
}
-static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
+static int sdhci_tegra_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
const struct sdhci_tegra_soc_data *soc_data;
@@ -370,7 +370,7 @@ err_no_plat:
return rc;
}
-static int __devexit sdhci_tegra_remove(struct platform_device *pdev)
+static int sdhci_tegra_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -407,7 +407,7 @@ static struct platform_driver sdhci_tegra_driver = {
.pm = SDHCI_PLTFM_PMOPS,
},
.probe = sdhci_tegra_probe,
- .remove = __devexit_p(sdhci_tegra_remove),
+ .remove = sdhci_tegra_remove,
};
module_platform_driver(sdhci_tegra_driver);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index c7851c0aabc..6f0bfc0c8c9 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1618,7 +1618,7 @@ static int sdhci_do_3_3v_signal_voltage_switch(struct sdhci_host *host,
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
if (host->vqmmc) {
- ret = regulator_set_voltage(host->vqmmc, 3300000, 3300000);
+ ret = regulator_set_voltage(host->vqmmc, 2700000, 3600000);
if (ret) {
pr_warning("%s: Switching to 3.3V signalling voltage "
" failed\n", mmc_hostname(host->mmc));
@@ -1662,7 +1662,7 @@ static int sdhci_do_1_8v_signal_voltage_switch(struct sdhci_host *host,
*/
if (host->vqmmc)
ret = regulator_set_voltage(host->vqmmc,
- 1800000, 1800000);
+ 1700000, 1950000);
else
ret = 0;
@@ -1994,30 +1994,11 @@ static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable)
sdhci_runtime_pm_put(host);
}
-static const struct mmc_host_ops sdhci_ops = {
- .request = sdhci_request,
- .set_ios = sdhci_set_ios,
- .get_ro = sdhci_get_ro,
- .hw_reset = sdhci_hw_reset,
- .enable_sdio_irq = sdhci_enable_sdio_irq,
- .start_signal_voltage_switch = sdhci_start_signal_voltage_switch,
- .execute_tuning = sdhci_execute_tuning,
- .enable_preset_value = sdhci_enable_preset_value,
-};
-
-/*****************************************************************************\
- * *
- * Tasklets *
- * *
-\*****************************************************************************/
-
-static void sdhci_tasklet_card(unsigned long param)
+static void sdhci_card_event(struct mmc_host *mmc)
{
- struct sdhci_host *host;
+ struct sdhci_host *host = mmc_priv(mmc);
unsigned long flags;
- host = (struct sdhci_host*)param;
-
spin_lock_irqsave(&host->lock, flags);
/* Check host->mrq first in case we are runtime suspended */
@@ -2036,6 +2017,31 @@ static void sdhci_tasklet_card(unsigned long param)
}
spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static const struct mmc_host_ops sdhci_ops = {
+ .request = sdhci_request,
+ .set_ios = sdhci_set_ios,
+ .get_ro = sdhci_get_ro,
+ .hw_reset = sdhci_hw_reset,
+ .enable_sdio_irq = sdhci_enable_sdio_irq,
+ .start_signal_voltage_switch = sdhci_start_signal_voltage_switch,
+ .execute_tuning = sdhci_execute_tuning,
+ .enable_preset_value = sdhci_enable_preset_value,
+ .card_event = sdhci_card_event,
+};
+
+/*****************************************************************************\
+ * *
+ * Tasklets *
+ * *
+\*****************************************************************************/
+
+static void sdhci_tasklet_card(unsigned long param)
+{
+ struct sdhci_host *host = (struct sdhci_host*)param;
+
+ sdhci_card_event(host->mmc);
mmc_detect_change(host->mmc, msecs_to_jiffies(200));
}
@@ -2282,6 +2288,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
pr_err("%s: ADMA error\n", mmc_hostname(host->mmc));
sdhci_show_adma_error(host);
host->data->error = -EIO;
+ if (host->ops->adma_workaround)
+ host->ops->adma_workaround(host, intmask);
}
if (host->data->error)
@@ -2858,10 +2866,16 @@ int sdhci_add_host(struct sdhci_host *host)
mmc_hostname(mmc));
host->vqmmc = NULL;
}
- }
- else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000))
+ } else {
regulator_enable(host->vqmmc);
- else
+ if (!regulator_is_supported_voltage(host->vqmmc, 1700000,
+ 1950000))
+ caps[1] &= ~(SDHCI_SUPPORT_SDR104 |
+ SDHCI_SUPPORT_SDR50 |
+ SDHCI_SUPPORT_DDR50);
+ }
+
+ if (host->quirks2 & SDHCI_QUIRK2_NO_1_8_V)
caps[1] &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
SDHCI_SUPPORT_DDR50);
@@ -2919,21 +2933,18 @@ int sdhci_add_host(struct sdhci_host *host)
mmc_hostname(mmc));
host->vmmc = NULL;
}
- } else
- regulator_enable(host->vmmc);
+ }
#ifdef CONFIG_REGULATOR
if (host->vmmc) {
- ret = regulator_is_supported_voltage(host->vmmc, 3300000,
- 3300000);
+ ret = regulator_is_supported_voltage(host->vmmc, 2700000,
+ 3600000);
if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_330)))
caps[0] &= ~SDHCI_CAN_VDD_330;
- ret = regulator_is_supported_voltage(host->vmmc, 3000000,
- 3000000);
if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_300)))
caps[0] &= ~SDHCI_CAN_VDD_300;
- ret = regulator_is_supported_voltage(host->vmmc, 1800000,
- 1800000);
+ ret = regulator_is_supported_voltage(host->vmmc, 1700000,
+ 1950000);
if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_180)))
caps[0] &= ~SDHCI_CAN_VDD_180;
}
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 71a4a7ed46c..a6d69b7bdea 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -120,6 +120,7 @@
#define SDHCI_SIGNAL_ENABLE 0x38
#define SDHCI_INT_RESPONSE 0x00000001
#define SDHCI_INT_DATA_END 0x00000002
+#define SDHCI_INT_BLK_GAP 0x00000004
#define SDHCI_INT_DMA_END 0x00000008
#define SDHCI_INT_SPACE_AVAIL 0x00000010
#define SDHCI_INT_DATA_AVAIL 0x00000020
@@ -146,7 +147,8 @@
#define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \
SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
- SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR)
+ SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR | \
+ SDHCI_INT_BLK_GAP)
#define SDHCI_INT_ALL_MASK ((unsigned int)-1)
#define SDHCI_ACMD12_ERR 0x3C
@@ -278,6 +280,7 @@ struct sdhci_ops {
void (*hw_reset)(struct sdhci_host *host);
void (*platform_suspend)(struct sdhci_host *host);
void (*platform_resume)(struct sdhci_host *host);
+ void (*adma_workaround)(struct sdhci_host *host, u32 intmask);
void (*platform_init)(struct sdhci_host *host);
};
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index d25bc97dc5c..9a4c151067d 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -1104,7 +1104,6 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
{
struct sh_mmcif_host *host = dev_id;
struct mmc_request *mrq = host->mrq;
- struct mmc_data *data = mrq->data;
cancel_delayed_work_sync(&host->timeout_work);
@@ -1152,13 +1151,14 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
case MMCIF_WAIT_FOR_READ_END:
case MMCIF_WAIT_FOR_WRITE_END:
if (host->sd_error)
- data->error = sh_mmcif_error_manage(host);
+ mrq->data->error = sh_mmcif_error_manage(host);
break;
default:
BUG();
}
if (host->wait_for != MMCIF_WAIT_FOR_STOP) {
+ struct mmc_data *data = mrq->data;
if (!mrq->cmd->error && data && !data->error)
data->bytes_xfered =
data->blocks * data->blksz;
@@ -1231,10 +1231,6 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
host->sd_error = true;
dev_dbg(&host->pd->dev, "int err state = %08x\n", state);
}
- if (host->state == STATE_IDLE) {
- dev_info(&host->pd->dev, "Spurious IRQ status 0x%x", state);
- return IRQ_HANDLED;
- }
if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) {
if (!host->dma_active)
return IRQ_WAKE_THREAD;
@@ -1302,7 +1298,7 @@ static void sh_mmcif_init_ocr(struct sh_mmcif_host *host)
dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
}
-static int __devinit sh_mmcif_probe(struct platform_device *pdev)
+static int sh_mmcif_probe(struct platform_device *pdev)
{
int ret = 0, irq[2];
struct mmc_host *mmc;
@@ -1310,7 +1306,6 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
struct sh_mmcif_plat_data *pd = pdev->dev.platform_data;
struct resource *res;
void __iomem *reg;
- char clk_name[8];
irq[0] = platform_get_irq(pdev, 0);
irq[1] = platform_get_irq(pdev, 1);
@@ -1360,11 +1355,10 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
host->power = false;
- snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id);
- host->hclk = clk_get(&pdev->dev, clk_name);
+ host->hclk = clk_get(&pdev->dev, NULL);
if (IS_ERR(host->hclk)) {
ret = PTR_ERR(host->hclk);
- dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret);
+ dev_err(&pdev->dev, "cannot get clock: %d\n", ret);
goto eclkget;
}
ret = sh_mmcif_clk_update(host);
@@ -1430,7 +1424,7 @@ ealloch:
return ret;
}
-static int __devexit sh_mmcif_remove(struct platform_device *pdev)
+static int sh_mmcif_remove(struct platform_device *pdev)
{
struct sh_mmcif_host *host = platform_get_drvdata(pdev);
struct sh_mmcif_plat_data *pd = pdev->dev.platform_data;
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 0bdc146178d..524a7f77382 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -117,13 +117,12 @@ static const struct sh_mobile_sdhi_ops sdhi_ops = {
.cd_wakeup = sh_mobile_sdhi_cd_wakeup,
};
-static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+static int sh_mobile_sdhi_probe(struct platform_device *pdev)
{
struct sh_mobile_sdhi *priv;
struct tmio_mmc_data *mmc_data;
struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
struct tmio_mmc_host *host;
- char clk_name[8];
int irq, ret, i = 0;
bool multiplexed_isr = true;
@@ -144,11 +143,10 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
}
}
- snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id);
- priv->clk = clk_get(&pdev->dev, clk_name);
+ priv->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(priv->clk)) {
- dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
ret = PTR_ERR(priv->clk);
+ dev_err(&pdev->dev, "cannot get clock: %d\n", ret);
goto eclkget;
}
@@ -250,7 +248,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "%s base at 0x%08lx clock rate %u MHz\n",
mmc_hostname(host->mmc), (unsigned long)
(platform_get_resource(pdev, IORESOURCE_MEM, 0)->start),
- mmc_data->hclk / 1000000);
+ host->mmc->f_max / 1000000);
return ret;
@@ -330,7 +328,7 @@ static struct platform_driver sh_mobile_sdhi_driver = {
.of_match_table = sh_mobile_sdhi_of_match,
},
.probe = sh_mobile_sdhi_probe,
- .remove = __devexit_p(sh_mobile_sdhi_remove),
+ .remove = sh_mobile_sdhi_remove,
};
module_platform_driver(sh_mobile_sdhi_driver);
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index 113ce6c9cf3..139212e79cd 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -57,7 +57,7 @@ static int tmio_mmc_resume(struct platform_device *dev)
#define tmio_mmc_resume NULL
#endif
-static int __devinit tmio_mmc_probe(struct platform_device *pdev)
+static int tmio_mmc_probe(struct platform_device *pdev)
{
const struct mfd_cell *cell = mfd_get_cell(pdev);
struct tmio_mmc_data *pdata;
@@ -107,7 +107,7 @@ out:
return ret;
}
-static int __devexit tmio_mmc_remove(struct platform_device *pdev)
+static int tmio_mmc_remove(struct platform_device *pdev)
{
const struct mfd_cell *cell = mfd_get_cell(pdev);
struct mmc_host *mmc = platform_get_drvdata(pdev);
@@ -133,7 +133,7 @@ static struct platform_driver tmio_mmc_driver = {
.owner = THIS_MODULE,
},
.probe = tmio_mmc_probe,
- .remove = __devexit_p(tmio_mmc_remove),
+ .remove = tmio_mmc_remove,
.suspend = tmio_mmc_suspend,
.resume = tmio_mmc_resume,
};
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 0d8a9bbe30b..50bf495a988 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -918,7 +918,7 @@ static void tmio_mmc_init_ocr(struct tmio_mmc_host *host)
dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
}
-int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+int tmio_mmc_host_probe(struct tmio_mmc_host **host,
struct platform_device *pdev,
struct tmio_mmc_data *pdata)
{
diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
index f18becef156..4f84586c6e9 100644
--- a/drivers/mmc/host/via-sdmmc.c
+++ b/drivers/mmc/host/via-sdmmc.c
@@ -1082,7 +1082,7 @@ static void via_init_mmc_host(struct via_crdr_mmc_host *host)
msleep(1);
}
-static int __devinit via_sd_probe(struct pci_dev *pcidev,
+static int via_sd_probe(struct pci_dev *pcidev,
const struct pci_device_id *id)
{
struct mmc_host *mmc;
@@ -1176,7 +1176,7 @@ disable:
return ret;
}
-static void __devexit via_sd_remove(struct pci_dev *pcidev)
+static void via_sd_remove(struct pci_dev *pcidev)
{
struct via_crdr_mmc_host *sdhost = pci_get_drvdata(pcidev);
unsigned long flags;
@@ -1332,7 +1332,7 @@ static struct pci_driver via_sd_driver = {
.name = DRV_NAME,
.id_table = via_ids,
.probe = via_sd_probe,
- .remove = __devexit_p(via_sd_remove),
+ .remove = via_sd_remove,
.suspend = via_sd_suspend,
.resume = via_sd_resume,
};
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
index d5655a63eda..cb9f361c03a 100644
--- a/drivers/mmc/host/vub300.c
+++ b/drivers/mmc/host/vub300.c
@@ -2362,6 +2362,7 @@ error4:
error1:
usb_free_urb(command_out_urb);
error0:
+ usb_put_dev(udev);
return retval;
}
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 64acd9ce141..e954b775887 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -1196,7 +1196,7 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id)
* Allocate/free MMC structure.
*/
-static int __devinit wbsd_alloc_mmc(struct device *dev)
+static int wbsd_alloc_mmc(struct device *dev)
{
struct mmc_host *mmc;
struct wbsd_host *host;
@@ -1288,7 +1288,7 @@ static void wbsd_free_mmc(struct device *dev)
* Scan for known chip id:s
*/
-static int __devinit wbsd_scan(struct wbsd_host *host)
+static int wbsd_scan(struct wbsd_host *host)
{
int i, j, k;
int id;
@@ -1344,7 +1344,7 @@ static int __devinit wbsd_scan(struct wbsd_host *host)
* Allocate/free io port ranges
*/
-static int __devinit wbsd_request_region(struct wbsd_host *host, int base)
+static int wbsd_request_region(struct wbsd_host *host, int base)
{
if (base & 0x7)
return -EINVAL;
@@ -1374,7 +1374,7 @@ static void wbsd_release_regions(struct wbsd_host *host)
* Allocate/free DMA port and buffer
*/
-static void __devinit wbsd_request_dma(struct wbsd_host *host, int dma)
+static void wbsd_request_dma(struct wbsd_host *host, int dma)
{
if (dma < 0)
return;
@@ -1452,7 +1452,7 @@ static void wbsd_release_dma(struct wbsd_host *host)
* Allocate/free IRQ.
*/
-static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq)
+static int wbsd_request_irq(struct wbsd_host *host, int irq)
{
int ret;
@@ -1502,7 +1502,7 @@ static void wbsd_release_irq(struct wbsd_host *host)
* Allocate all resources for the host.
*/
-static int __devinit wbsd_request_resources(struct wbsd_host *host,
+static int wbsd_request_resources(struct wbsd_host *host,
int base, int irq, int dma)
{
int ret;
@@ -1644,7 +1644,7 @@ static void wbsd_chip_poweroff(struct wbsd_host *host)
* *
\*****************************************************************************/
-static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma,
+static int wbsd_init(struct device *dev, int base, int irq, int dma,
int pnp)
{
struct wbsd_host *host = NULL;
@@ -1735,7 +1735,7 @@ static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma,
return 0;
}
-static void __devexit wbsd_shutdown(struct device *dev, int pnp)
+static void wbsd_shutdown(struct device *dev, int pnp)
{
struct mmc_host *mmc = dev_get_drvdata(dev);
struct wbsd_host *host;
@@ -1762,13 +1762,13 @@ static void __devexit wbsd_shutdown(struct device *dev, int pnp)
* Non-PnP
*/
-static int __devinit wbsd_probe(struct platform_device *dev)
+static int wbsd_probe(struct platform_device *dev)
{
/* Use the module parameters for resources */
return wbsd_init(&dev->dev, param_io, param_irq, param_dma, 0);
}
-static int __devexit wbsd_remove(struct platform_device *dev)
+static int wbsd_remove(struct platform_device *dev)
{
wbsd_shutdown(&dev->dev, 0);
@@ -1781,7 +1781,7 @@ static int __devexit wbsd_remove(struct platform_device *dev)
#ifdef CONFIG_PNP
-static int __devinit
+static int
wbsd_pnp_probe(struct pnp_dev *pnpdev, const struct pnp_device_id *dev_id)
{
int io, irq, dma;
@@ -1801,7 +1801,7 @@ wbsd_pnp_probe(struct pnp_dev *pnpdev, const struct pnp_device_id *dev_id)
return wbsd_init(&pnpdev->dev, io, irq, dma, 1);
}
-static void __devexit wbsd_pnp_remove(struct pnp_dev *dev)
+static void wbsd_pnp_remove(struct pnp_dev *dev)
{
wbsd_shutdown(&dev->dev, 1);
}
@@ -1941,7 +1941,7 @@ static struct platform_device *wbsd_device;
static struct platform_driver wbsd_driver = {
.probe = wbsd_probe,
- .remove = __devexit_p(wbsd_remove),
+ .remove = wbsd_remove,
.suspend = wbsd_platform_suspend,
.resume = wbsd_platform_resume,
@@ -1957,7 +1957,7 @@ static struct pnp_driver wbsd_pnp_driver = {
.name = DRIVER_NAME,
.id_table = pnp_dev_table,
.probe = wbsd_pnp_probe,
- .remove = __devexit_p(wbsd_pnp_remove),
+ .remove = wbsd_pnp_remove,
.suspend = wbsd_pnp_suspend,
.resume = wbsd_pnp_resume,
diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c
new file mode 100644
index 00000000000..5ba4605e4f8
--- /dev/null
+++ b/drivers/mmc/host/wmt-sdmmc.c
@@ -0,0 +1,1029 @@
+/*
+ * WM8505/WM8650 SD/MMC Host Controller
+ *
+ * Copyright (C) 2010 Tony Prisk
+ * Copyright (C) 2008 WonderMedia Technologies, 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/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_device.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
+
+#include <asm/byteorder.h>
+
+
+#define DRIVER_NAME "wmt-sdhc"
+
+
+/* MMC/SD controller registers */
+#define SDMMC_CTLR 0x00
+#define SDMMC_CMD 0x01
+#define SDMMC_RSPTYPE 0x02
+#define SDMMC_ARG 0x04
+#define SDMMC_BUSMODE 0x08
+#define SDMMC_BLKLEN 0x0C
+#define SDMMC_BLKCNT 0x0E
+#define SDMMC_RSP 0x10
+#define SDMMC_CBCR 0x20
+#define SDMMC_INTMASK0 0x24
+#define SDMMC_INTMASK1 0x25
+#define SDMMC_STS0 0x28
+#define SDMMC_STS1 0x29
+#define SDMMC_STS2 0x2A
+#define SDMMC_STS3 0x2B
+#define SDMMC_RSPTIMEOUT 0x2C
+#define SDMMC_CLK 0x30 /* VT8500 only */
+#define SDMMC_EXTCTRL 0x34
+#define SDMMC_SBLKLEN 0x38
+#define SDMMC_DMATIMEOUT 0x3C
+
+
+/* SDMMC_CTLR bit fields */
+#define CTLR_CMD_START 0x01
+#define CTLR_CMD_WRITE 0x04
+#define CTLR_FIFO_RESET 0x08
+
+/* SDMMC_BUSMODE bit fields */
+#define BM_SPI_MODE 0x01
+#define BM_FOURBIT_MODE 0x02
+#define BM_EIGHTBIT_MODE 0x04
+#define BM_SD_OFF 0x10
+#define BM_SPI_CS 0x20
+#define BM_SD_POWER 0x40
+#define BM_SOFT_RESET 0x80
+#define BM_ONEBIT_MASK 0xFD
+
+/* SDMMC_BLKLEN bit fields */
+#define BLKL_CRCERR_ABORT 0x0800
+#define BLKL_CD_POL_HIGH 0x1000
+#define BLKL_GPI_CD 0x2000
+#define BLKL_DATA3_CD 0x4000
+#define BLKL_INT_ENABLE 0x8000
+
+/* SDMMC_INTMASK0 bit fields */
+#define INT0_MBLK_TRAN_DONE_INT_EN 0x10
+#define INT0_BLK_TRAN_DONE_INT_EN 0x20
+#define INT0_CD_INT_EN 0x40
+#define INT0_DI_INT_EN 0x80
+
+/* SDMMC_INTMASK1 bit fields */
+#define INT1_CMD_RES_TRAN_DONE_INT_EN 0x02
+#define INT1_CMD_RES_TOUT_INT_EN 0x04
+#define INT1_MBLK_AUTO_STOP_INT_EN 0x08
+#define INT1_DATA_TOUT_INT_EN 0x10
+#define INT1_RESCRC_ERR_INT_EN 0x20
+#define INT1_RCRC_ERR_INT_EN 0x40
+#define INT1_WCRC_ERR_INT_EN 0x80
+
+/* SDMMC_STS0 bit fields */
+#define STS0_WRITE_PROTECT 0x02
+#define STS0_CD_DATA3 0x04
+#define STS0_CD_GPI 0x08
+#define STS0_MBLK_DONE 0x10
+#define STS0_BLK_DONE 0x20
+#define STS0_CARD_DETECT 0x40
+#define STS0_DEVICE_INS 0x80
+
+/* SDMMC_STS1 bit fields */
+#define STS1_SDIO_INT 0x01
+#define STS1_CMDRSP_DONE 0x02
+#define STS1_RSP_TIMEOUT 0x04
+#define STS1_AUTOSTOP_DONE 0x08
+#define STS1_DATA_TIMEOUT 0x10
+#define STS1_RSP_CRC_ERR 0x20
+#define STS1_RCRC_ERR 0x40
+#define STS1_WCRC_ERR 0x80
+
+/* SDMMC_STS2 bit fields */
+#define STS2_CMD_RES_BUSY 0x10
+#define STS2_DATARSP_BUSY 0x20
+#define STS2_DIS_FORCECLK 0x80
+
+
+/* MMC/SD DMA Controller Registers */
+#define SDDMA_GCR 0x100
+#define SDDMA_IER 0x104
+#define SDDMA_ISR 0x108
+#define SDDMA_DESPR 0x10C
+#define SDDMA_RBR 0x110
+#define SDDMA_DAR 0x114
+#define SDDMA_BAR 0x118
+#define SDDMA_CPR 0x11C
+#define SDDMA_CCR 0x120
+
+
+/* SDDMA_GCR bit fields */
+#define DMA_GCR_DMA_EN 0x00000001
+#define DMA_GCR_SOFT_RESET 0x00000100
+
+/* SDDMA_IER bit fields */
+#define DMA_IER_INT_EN 0x00000001
+
+/* SDDMA_ISR bit fields */
+#define DMA_ISR_INT_STS 0x00000001
+
+/* SDDMA_RBR bit fields */
+#define DMA_RBR_FORMAT 0x40000000
+#define DMA_RBR_END 0x80000000
+
+/* SDDMA_CCR bit fields */
+#define DMA_CCR_RUN 0x00000080
+#define DMA_CCR_IF_TO_PERIPHERAL 0x00000000
+#define DMA_CCR_PERIPHERAL_TO_IF 0x00400000
+
+/* SDDMA_CCR event status */
+#define DMA_CCR_EVT_NO_STATUS 0x00000000
+#define DMA_CCR_EVT_UNDERRUN 0x00000001
+#define DMA_CCR_EVT_OVERRUN 0x00000002
+#define DMA_CCR_EVT_DESP_READ 0x00000003
+#define DMA_CCR_EVT_DATA_RW 0x00000004
+#define DMA_CCR_EVT_EARLY_END 0x00000005
+#define DMA_CCR_EVT_SUCCESS 0x0000000F
+
+#define PDMA_READ 0x00
+#define PDMA_WRITE 0x01
+
+#define WMT_SD_POWER_OFF 0
+#define WMT_SD_POWER_ON 1
+
+struct wmt_dma_descriptor {
+ u32 flags;
+ u32 data_buffer_addr;
+ u32 branch_addr;
+ u32 reserved1;
+};
+
+struct wmt_mci_caps {
+ unsigned int f_min;
+ unsigned int f_max;
+ u32 ocr_avail;
+ u32 caps;
+ u32 max_seg_size;
+ u32 max_segs;
+ u32 max_blk_size;
+};
+
+struct wmt_mci_priv {
+ struct mmc_host *mmc;
+ void __iomem *sdmmc_base;
+
+ int irq_regular;
+ int irq_dma;
+
+ void *dma_desc_buffer;
+ dma_addr_t dma_desc_device_addr;
+
+ struct completion cmdcomp;
+ struct completion datacomp;
+
+ struct completion *comp_cmd;
+ struct completion *comp_dma;
+
+ struct mmc_request *req;
+ struct mmc_command *cmd;
+
+ struct clk *clk_sdmmc;
+ struct device *dev;
+
+ u8 power_inverted;
+ u8 cd_inverted;
+};
+
+static void wmt_set_sd_power(struct wmt_mci_priv *priv, int enable)
+{
+ u32 reg_tmp;
+ if (enable) {
+ if (priv->power_inverted) {
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+ writeb(reg_tmp | BM_SD_OFF,
+ priv->sdmmc_base + SDMMC_BUSMODE);
+ } else {
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+ writeb(reg_tmp & (~BM_SD_OFF),
+ priv->sdmmc_base + SDMMC_BUSMODE);
+ }
+ } else {
+ if (priv->power_inverted) {
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+ writeb(reg_tmp & (~BM_SD_OFF),
+ priv->sdmmc_base + SDMMC_BUSMODE);
+ } else {
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+ writeb(reg_tmp | BM_SD_OFF,
+ priv->sdmmc_base + SDMMC_BUSMODE);
+ }
+ }
+}
+
+static void wmt_mci_read_response(struct mmc_host *mmc)
+{
+ struct wmt_mci_priv *priv;
+ int idx1, idx2;
+ u8 tmp_resp;
+ u32 response;
+
+ priv = mmc_priv(mmc);
+
+ for (idx1 = 0; idx1 < 4; idx1++) {
+ response = 0;
+ for (idx2 = 0; idx2 < 4; idx2++) {
+ if ((idx1 == 3) && (idx2 == 3))
+ tmp_resp = readb(priv->sdmmc_base + SDMMC_RSP);
+ else
+ tmp_resp = readb(priv->sdmmc_base + SDMMC_RSP +
+ (idx1*4) + idx2 + 1);
+ response |= (tmp_resp << (idx2 * 8));
+ }
+ priv->cmd->resp[idx1] = cpu_to_be32(response);
+ }
+}
+
+static void wmt_mci_start_command(struct wmt_mci_priv *priv)
+{
+ u32 reg_tmp;
+
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_CTLR);
+ writeb(reg_tmp | CTLR_CMD_START, priv->sdmmc_base + SDMMC_CTLR);
+}
+
+static int wmt_mci_send_command(struct mmc_host *mmc, u8 command, u8 cmdtype,
+ u32 arg, u8 rsptype)
+{
+ struct wmt_mci_priv *priv;
+ u32 reg_tmp;
+
+ priv = mmc_priv(mmc);
+
+ /* write command, arg, resptype registers */
+ writeb(command, priv->sdmmc_base + SDMMC_CMD);
+ writel(arg, priv->sdmmc_base + SDMMC_ARG);
+ writeb(rsptype, priv->sdmmc_base + SDMMC_RSPTYPE);
+
+ /* reset response FIFO */
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_CTLR);
+ writeb(reg_tmp | CTLR_FIFO_RESET, priv->sdmmc_base + SDMMC_CTLR);
+
+ /* ensure clock enabled - VT3465 */
+ wmt_set_sd_power(priv, WMT_SD_POWER_ON);
+
+ /* clear status bits */
+ writeb(0xFF, priv->sdmmc_base + SDMMC_STS0);
+ writeb(0xFF, priv->sdmmc_base + SDMMC_STS1);
+ writeb(0xFF, priv->sdmmc_base + SDMMC_STS2);
+ writeb(0xFF, priv->sdmmc_base + SDMMC_STS3);
+
+ /* set command type */
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_CTLR);
+ writeb((reg_tmp & 0x0F) | (cmdtype << 4),
+ priv->sdmmc_base + SDMMC_CTLR);
+
+ return 0;
+}
+
+static void wmt_mci_disable_dma(struct wmt_mci_priv *priv)
+{
+ writel(DMA_ISR_INT_STS, priv->sdmmc_base + SDDMA_ISR);
+ writel(0, priv->sdmmc_base + SDDMA_IER);
+}
+
+static void wmt_complete_data_request(struct wmt_mci_priv *priv)
+{
+ struct mmc_request *req;
+ req = priv->req;
+
+ req->data->bytes_xfered = req->data->blksz * req->data->blocks;
+
+ /* unmap the DMA pages used for write data */
+ if (req->data->flags & MMC_DATA_WRITE)
+ dma_unmap_sg(mmc_dev(priv->mmc), req->data->sg,
+ req->data->sg_len, DMA_TO_DEVICE);
+ else
+ dma_unmap_sg(mmc_dev(priv->mmc), req->data->sg,
+ req->data->sg_len, DMA_FROM_DEVICE);
+
+ /* Check if the DMA ISR returned a data error */
+ if ((req->cmd->error) || (req->data->error))
+ mmc_request_done(priv->mmc, req);
+ else {
+ wmt_mci_read_response(priv->mmc);
+ if (!req->data->stop) {
+ /* single-block read/write requests end here */
+ mmc_request_done(priv->mmc, req);
+ } else {
+ /*
+ * we change the priv->cmd variable so the response is
+ * stored in the stop struct rather than the original
+ * calling command struct
+ */
+ priv->comp_cmd = &priv->cmdcomp;
+ init_completion(priv->comp_cmd);
+ priv->cmd = req->data->stop;
+ wmt_mci_send_command(priv->mmc, req->data->stop->opcode,
+ 7, req->data->stop->arg, 9);
+ wmt_mci_start_command(priv);
+ }
+ }
+}
+
+static irqreturn_t wmt_mci_dma_isr(int irq_num, void *data)
+{
+ struct mmc_host *mmc;
+ struct wmt_mci_priv *priv;
+
+ int status;
+
+ priv = (struct wmt_mci_priv *)data;
+ mmc = priv->mmc;
+
+ status = readl(priv->sdmmc_base + SDDMA_CCR) & 0x0F;
+
+ if (status != DMA_CCR_EVT_SUCCESS) {
+ dev_err(priv->dev, "DMA Error: Status = %d\n", status);
+ priv->req->data->error = -ETIMEDOUT;
+ complete(priv->comp_dma);
+ return IRQ_HANDLED;
+ }
+
+ priv->req->data->error = 0;
+
+ wmt_mci_disable_dma(priv);
+
+ complete(priv->comp_dma);
+
+ if (priv->comp_cmd) {
+ if (completion_done(priv->comp_cmd)) {
+ /*
+ * if the command (regular) interrupt has already
+ * completed, finish off the request otherwise we wait
+ * for the command interrupt and finish from there.
+ */
+ wmt_complete_data_request(priv);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t wmt_mci_regular_isr(int irq_num, void *data)
+{
+ struct wmt_mci_priv *priv;
+ u32 status0;
+ u32 status1;
+ u32 status2;
+ u32 reg_tmp;
+ int cmd_done;
+
+ priv = (struct wmt_mci_priv *)data;
+ cmd_done = 0;
+ status0 = readb(priv->sdmmc_base + SDMMC_STS0);
+ status1 = readb(priv->sdmmc_base + SDMMC_STS1);
+ status2 = readb(priv->sdmmc_base + SDMMC_STS2);
+
+ /* Check for card insertion */
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_INTMASK0);
+ if ((reg_tmp & INT0_DI_INT_EN) && (status0 & STS0_DEVICE_INS)) {
+ mmc_detect_change(priv->mmc, 0);
+ if (priv->cmd)
+ priv->cmd->error = -ETIMEDOUT;
+ if (priv->comp_cmd)
+ complete(priv->comp_cmd);
+ if (priv->comp_dma) {
+ wmt_mci_disable_dma(priv);
+ complete(priv->comp_dma);
+ }
+ writeb(STS0_DEVICE_INS, priv->sdmmc_base + SDMMC_STS0);
+ return IRQ_HANDLED;
+ }
+
+ if ((!priv->req->data) ||
+ ((priv->req->data->stop) && (priv->cmd == priv->req->data->stop))) {
+ /* handle non-data & stop_transmission requests */
+ if (status1 & STS1_CMDRSP_DONE) {
+ priv->cmd->error = 0;
+ cmd_done = 1;
+ } else if ((status1 & STS1_RSP_TIMEOUT) ||
+ (status1 & STS1_DATA_TIMEOUT)) {
+ priv->cmd->error = -ETIMEDOUT;
+ cmd_done = 1;
+ }
+
+ if (cmd_done) {
+ priv->comp_cmd = NULL;
+
+ if (!priv->cmd->error)
+ wmt_mci_read_response(priv->mmc);
+
+ priv->cmd = NULL;
+
+ mmc_request_done(priv->mmc, priv->req);
+ }
+ } else {
+ /* handle data requests */
+ if (status1 & STS1_CMDRSP_DONE) {
+ if (priv->cmd)
+ priv->cmd->error = 0;
+ if (priv->comp_cmd)
+ complete(priv->comp_cmd);
+ }
+
+ if ((status1 & STS1_RSP_TIMEOUT) ||
+ (status1 & STS1_DATA_TIMEOUT)) {
+ if (priv->cmd)
+ priv->cmd->error = -ETIMEDOUT;
+ if (priv->comp_cmd)
+ complete(priv->comp_cmd);
+ if (priv->comp_dma) {
+ wmt_mci_disable_dma(priv);
+ complete(priv->comp_dma);
+ }
+ }
+
+ if (priv->comp_dma) {
+ /*
+ * If the dma interrupt has already completed, finish
+ * off the request; otherwise we wait for the DMA
+ * interrupt and finish from there.
+ */
+ if (completion_done(priv->comp_dma))
+ wmt_complete_data_request(priv);
+ }
+ }
+
+ writeb(status0, priv->sdmmc_base + SDMMC_STS0);
+ writeb(status1, priv->sdmmc_base + SDMMC_STS1);
+ writeb(status2, priv->sdmmc_base + SDMMC_STS2);
+
+ return IRQ_HANDLED;
+}
+
+static void wmt_reset_hardware(struct mmc_host *mmc)
+{
+ struct wmt_mci_priv *priv;
+ u32 reg_tmp;
+
+ priv = mmc_priv(mmc);
+
+ /* reset controller */
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+ writeb(reg_tmp | BM_SOFT_RESET, priv->sdmmc_base + SDMMC_BUSMODE);
+
+ /* reset response FIFO */
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_CTLR);
+ writeb(reg_tmp | CTLR_FIFO_RESET, priv->sdmmc_base + SDMMC_CTLR);
+
+ /* enable GPI pin to detect card */
+ writew(BLKL_INT_ENABLE | BLKL_GPI_CD, priv->sdmmc_base + SDMMC_BLKLEN);
+
+ /* clear interrupt status */
+ writeb(0xFF, priv->sdmmc_base + SDMMC_STS0);
+ writeb(0xFF, priv->sdmmc_base + SDMMC_STS1);
+
+ /* setup interrupts */
+ writeb(INT0_CD_INT_EN | INT0_DI_INT_EN, priv->sdmmc_base +
+ SDMMC_INTMASK0);
+ writeb(INT1_DATA_TOUT_INT_EN | INT1_CMD_RES_TRAN_DONE_INT_EN |
+ INT1_CMD_RES_TOUT_INT_EN, priv->sdmmc_base + SDMMC_INTMASK1);
+
+ /* set the DMA timeout */
+ writew(8191, priv->sdmmc_base + SDMMC_DMATIMEOUT);
+
+ /* auto clock freezing enable */
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_STS2);
+ writeb(reg_tmp | STS2_DIS_FORCECLK, priv->sdmmc_base + SDMMC_STS2);
+
+ /* set a default clock speed of 400Khz */
+ clk_set_rate(priv->clk_sdmmc, 400000);
+}
+
+static int wmt_dma_init(struct mmc_host *mmc)
+{
+ struct wmt_mci_priv *priv;
+
+ priv = mmc_priv(mmc);
+
+ writel(DMA_GCR_SOFT_RESET, priv->sdmmc_base + SDDMA_GCR);
+ writel(DMA_GCR_DMA_EN, priv->sdmmc_base + SDDMA_GCR);
+ if ((readl(priv->sdmmc_base + SDDMA_GCR) & DMA_GCR_DMA_EN) != 0)
+ return 0;
+ else
+ return 1;
+}
+
+static void wmt_dma_init_descriptor(struct wmt_dma_descriptor *desc,
+ u16 req_count, u32 buffer_addr, u32 branch_addr, int end)
+{
+ desc->flags = 0x40000000 | req_count;
+ if (end)
+ desc->flags |= 0x80000000;
+ desc->data_buffer_addr = buffer_addr;
+ desc->branch_addr = branch_addr;
+}
+
+static void wmt_dma_config(struct mmc_host *mmc, u32 descaddr, u8 dir)
+{
+ struct wmt_mci_priv *priv;
+ u32 reg_tmp;
+
+ priv = mmc_priv(mmc);
+
+ /* Enable DMA Interrupts */
+ writel(DMA_IER_INT_EN, priv->sdmmc_base + SDDMA_IER);
+
+ /* Write DMA Descriptor Pointer Register */
+ writel(descaddr, priv->sdmmc_base + SDDMA_DESPR);
+
+ writel(0x00, priv->sdmmc_base + SDDMA_CCR);
+
+ if (dir == PDMA_WRITE) {
+ reg_tmp = readl(priv->sdmmc_base + SDDMA_CCR);
+ writel(reg_tmp & DMA_CCR_IF_TO_PERIPHERAL, priv->sdmmc_base +
+ SDDMA_CCR);
+ } else {
+ reg_tmp = readl(priv->sdmmc_base + SDDMA_CCR);
+ writel(reg_tmp | DMA_CCR_PERIPHERAL_TO_IF, priv->sdmmc_base +
+ SDDMA_CCR);
+ }
+}
+
+static void wmt_dma_start(struct wmt_mci_priv *priv)
+{
+ u32 reg_tmp;
+
+ reg_tmp = readl(priv->sdmmc_base + SDDMA_CCR);
+ writel(reg_tmp | DMA_CCR_RUN, priv->sdmmc_base + SDDMA_CCR);
+}
+
+static void wmt_mci_request(struct mmc_host *mmc, struct mmc_request *req)
+{
+ struct wmt_mci_priv *priv;
+ struct wmt_dma_descriptor *desc;
+ u8 command;
+ u8 cmdtype;
+ u32 arg;
+ u8 rsptype;
+ u32 reg_tmp;
+
+ struct scatterlist *sg;
+ int i;
+ int sg_cnt;
+ int offset;
+ u32 dma_address;
+ int desc_cnt;
+
+ priv = mmc_priv(mmc);
+ priv->req = req;
+
+ /*
+ * Use the cmd variable to pass a pointer to the resp[] structure
+ * This is required on multi-block requests to pass the pointer to the
+ * stop command
+ */
+ priv->cmd = req->cmd;
+
+ command = req->cmd->opcode;
+ arg = req->cmd->arg;
+ rsptype = mmc_resp_type(req->cmd);
+ cmdtype = 0;
+
+ /* rsptype=7 only valid for SPI commands - should be =2 for SD */
+ if (rsptype == 7)
+ rsptype = 2;
+ /* rsptype=21 is R1B, convert for controller */
+ if (rsptype == 21)
+ rsptype = 9;
+
+ if (!req->data) {
+ wmt_mci_send_command(mmc, command, cmdtype, arg, rsptype);
+ wmt_mci_start_command(priv);
+ /* completion is now handled in the regular_isr() */
+ }
+ if (req->data) {
+ priv->comp_cmd = &priv->cmdcomp;
+ init_completion(priv->comp_cmd);
+
+ wmt_dma_init(mmc);
+
+ /* set controller data length */
+ reg_tmp = readw(priv->sdmmc_base + SDMMC_BLKLEN);
+ writew((reg_tmp & 0xF800) | (req->data->blksz - 1),
+ priv->sdmmc_base + SDMMC_BLKLEN);
+
+ /* set controller block count */
+ writew(req->data->blocks, priv->sdmmc_base + SDMMC_BLKCNT);
+
+ desc = (struct wmt_dma_descriptor *)priv->dma_desc_buffer;
+
+ if (req->data->flags & MMC_DATA_WRITE) {
+ sg_cnt = dma_map_sg(mmc_dev(mmc), req->data->sg,
+ req->data->sg_len, DMA_TO_DEVICE);
+ cmdtype = 1;
+ if (req->data->blocks > 1)
+ cmdtype = 3;
+ } else {
+ sg_cnt = dma_map_sg(mmc_dev(mmc), req->data->sg,
+ req->data->sg_len, DMA_FROM_DEVICE);
+ cmdtype = 2;
+ if (req->data->blocks > 1)
+ cmdtype = 4;
+ }
+
+ dma_address = priv->dma_desc_device_addr + 16;
+ desc_cnt = 0;
+
+ for_each_sg(req->data->sg, sg, sg_cnt, i) {
+ offset = 0;
+ while (offset < sg_dma_len(sg)) {
+ wmt_dma_init_descriptor(desc, req->data->blksz,
+ sg_dma_address(sg)+offset,
+ dma_address, 0);
+ desc++;
+ desc_cnt++;
+ offset += req->data->blksz;
+ dma_address += 16;
+ if (desc_cnt == req->data->blocks)
+ break;
+ }
+ }
+ desc--;
+ desc->flags |= 0x80000000;
+
+ if (req->data->flags & MMC_DATA_WRITE)
+ wmt_dma_config(mmc, priv->dma_desc_device_addr,
+ PDMA_WRITE);
+ else
+ wmt_dma_config(mmc, priv->dma_desc_device_addr,
+ PDMA_READ);
+
+ wmt_mci_send_command(mmc, command, cmdtype, arg, rsptype);
+
+ priv->comp_dma = &priv->datacomp;
+ init_completion(priv->comp_dma);
+
+ wmt_dma_start(priv);
+ wmt_mci_start_command(priv);
+ }
+}
+
+static void wmt_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct wmt_mci_priv *priv;
+ u32 reg_tmp;
+
+ priv = mmc_priv(mmc);
+
+ if (ios->power_mode == MMC_POWER_UP) {
+ wmt_reset_hardware(mmc);
+
+ wmt_set_sd_power(priv, WMT_SD_POWER_ON);
+ }
+ if (ios->power_mode == MMC_POWER_OFF)
+ wmt_set_sd_power(priv, WMT_SD_POWER_OFF);
+
+ if (ios->clock != 0)
+ clk_set_rate(priv->clk_sdmmc, ios->clock);
+
+ switch (ios->bus_width) {
+ case MMC_BUS_WIDTH_8:
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_EXTCTRL);
+ writeb(reg_tmp | 0x04, priv->sdmmc_base + SDMMC_EXTCTRL);
+ break;
+ case MMC_BUS_WIDTH_4:
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+ writeb(reg_tmp | BM_FOURBIT_MODE, priv->sdmmc_base +
+ SDMMC_BUSMODE);
+
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_EXTCTRL);
+ writeb(reg_tmp & 0xFB, priv->sdmmc_base + SDMMC_EXTCTRL);
+ break;
+ case MMC_BUS_WIDTH_1:
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+ writeb(reg_tmp & BM_ONEBIT_MASK, priv->sdmmc_base +
+ SDMMC_BUSMODE);
+
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_EXTCTRL);
+ writeb(reg_tmp & 0xFB, priv->sdmmc_base + SDMMC_EXTCTRL);
+ break;
+ }
+}
+
+static int wmt_mci_get_ro(struct mmc_host *mmc)
+{
+ struct wmt_mci_priv *priv = mmc_priv(mmc);
+
+ return !(readb(priv->sdmmc_base + SDMMC_STS0) & STS0_WRITE_PROTECT);
+}
+
+static int wmt_mci_get_cd(struct mmc_host *mmc)
+{
+ struct wmt_mci_priv *priv = mmc_priv(mmc);
+ u32 cd = (readb(priv->sdmmc_base + SDMMC_STS0) & STS0_CD_GPI) >> 3;
+
+ return !(cd ^ priv->cd_inverted);
+}
+
+static struct mmc_host_ops wmt_mci_ops = {
+ .request = wmt_mci_request,
+ .set_ios = wmt_mci_set_ios,
+ .get_ro = wmt_mci_get_ro,
+ .get_cd = wmt_mci_get_cd,
+};
+
+/* Controller capabilities */
+static struct wmt_mci_caps wm8505_caps = {
+ .f_min = 390425,
+ .f_max = 50000000,
+ .ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED |
+ MMC_CAP_SD_HIGHSPEED,
+ .max_seg_size = 65024,
+ .max_segs = 128,
+ .max_blk_size = 2048,
+};
+
+static struct of_device_id wmt_mci_dt_ids[] = {
+ { .compatible = "wm,wm8505-sdhc", .data = &wm8505_caps },
+ { /* Sentinel */ },
+};
+
+static int __devinit wmt_mci_probe(struct platform_device *pdev)
+{
+ struct mmc_host *mmc;
+ struct wmt_mci_priv *priv;
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id =
+ of_match_device(wmt_mci_dt_ids, &pdev->dev);
+ const struct wmt_mci_caps *wmt_caps = of_id->data;
+ int ret;
+ int regular_irq, dma_irq;
+
+ if (!of_id || !of_id->data) {
+ dev_err(&pdev->dev, "Controller capabilities data missing\n");
+ return -EFAULT;
+ }
+
+ if (!np) {
+ dev_err(&pdev->dev, "Missing SDMMC description in devicetree\n");
+ return -EFAULT;
+ }
+
+ regular_irq = irq_of_parse_and_map(np, 0);
+ dma_irq = irq_of_parse_and_map(np, 1);
+
+ if (!regular_irq || !dma_irq) {
+ dev_err(&pdev->dev, "Getting IRQs failed!\n");
+ ret = -ENXIO;
+ goto fail1;
+ }
+
+ mmc = mmc_alloc_host(sizeof(struct wmt_mci_priv), &pdev->dev);
+ if (!mmc) {
+ dev_err(&pdev->dev, "Failed to allocate mmc_host\n");
+ ret = -ENOMEM;
+ goto fail1;
+ }
+
+ mmc->ops = &wmt_mci_ops;
+ mmc->f_min = wmt_caps->f_min;
+ mmc->f_max = wmt_caps->f_max;
+ mmc->ocr_avail = wmt_caps->ocr_avail;
+ mmc->caps = wmt_caps->caps;
+
+ mmc->max_seg_size = wmt_caps->max_seg_size;
+ mmc->max_segs = wmt_caps->max_segs;
+ mmc->max_blk_size = wmt_caps->max_blk_size;
+
+ mmc->max_req_size = (16*512*mmc->max_segs);
+ mmc->max_blk_count = mmc->max_req_size / 512;
+
+ priv = mmc_priv(mmc);
+ priv->mmc = mmc;
+ priv->dev = &pdev->dev;
+
+ priv->power_inverted = 0;
+ priv->cd_inverted = 0;
+
+ if (of_get_property(np, "sdon-inverted", NULL))
+ priv->power_inverted = 1;
+ if (of_get_property(np, "cd-inverted", NULL))
+ priv->cd_inverted = 1;
+
+ priv->sdmmc_base = of_iomap(np, 0);
+ if (!priv->sdmmc_base) {
+ dev_err(&pdev->dev, "Failed to map IO space\n");
+ ret = -ENOMEM;
+ goto fail2;
+ }
+
+ priv->irq_regular = regular_irq;
+ priv->irq_dma = dma_irq;
+
+ ret = request_irq(regular_irq, wmt_mci_regular_isr, 0, "sdmmc", priv);
+ if (ret) {
+ dev_err(&pdev->dev, "Register regular IRQ fail\n");
+ goto fail3;
+ }
+
+ ret = request_irq(dma_irq, wmt_mci_dma_isr, 32, "sdmmc", priv);
+ if (ret) {
+ dev_err(&pdev->dev, "Register DMA IRQ fail\n");
+ goto fail4;
+ }
+
+ /* alloc some DMA buffers for descriptors/transfers */
+ priv->dma_desc_buffer = dma_alloc_coherent(&pdev->dev,
+ mmc->max_blk_count * 16,
+ &priv->dma_desc_device_addr,
+ 208);
+ if (!priv->dma_desc_buffer) {
+ dev_err(&pdev->dev, "DMA alloc fail\n");
+ ret = -EPERM;
+ goto fail5;
+ }
+
+ platform_set_drvdata(pdev, mmc);
+
+ priv->clk_sdmmc = of_clk_get(np, 0);
+ if (IS_ERR(priv->clk_sdmmc)) {
+ dev_err(&pdev->dev, "Error getting clock\n");
+ ret = PTR_ERR(priv->clk_sdmmc);
+ goto fail5;
+ }
+
+ clk_prepare_enable(priv->clk_sdmmc);
+
+ /* configure the controller to a known 'ready' state */
+ wmt_reset_hardware(mmc);
+
+ mmc_add_host(mmc);
+
+ dev_info(&pdev->dev, "WMT SDHC Controller initialized\n");
+
+ return 0;
+fail5:
+ free_irq(dma_irq, priv);
+fail4:
+ free_irq(regular_irq, priv);
+fail3:
+ iounmap(priv->sdmmc_base);
+fail2:
+ mmc_free_host(mmc);
+fail1:
+ return ret;
+}
+
+static int __devexit wmt_mci_remove(struct platform_device *pdev)
+{
+ struct mmc_host *mmc;
+ struct wmt_mci_priv *priv;
+ struct resource *res;
+ u32 reg_tmp;
+
+ mmc = platform_get_drvdata(pdev);
+ priv = mmc_priv(mmc);
+
+ /* reset SD controller */
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+ writel(reg_tmp | BM_SOFT_RESET, priv->sdmmc_base + SDMMC_BUSMODE);
+ reg_tmp = readw(priv->sdmmc_base + SDMMC_BLKLEN);
+ writew(reg_tmp & ~(0xA000), priv->sdmmc_base + SDMMC_BLKLEN);
+ writeb(0xFF, priv->sdmmc_base + SDMMC_STS0);
+ writeb(0xFF, priv->sdmmc_base + SDMMC_STS1);
+
+ /* release the dma buffers */
+ dma_free_coherent(&pdev->dev, priv->mmc->max_blk_count * 16,
+ priv->dma_desc_buffer, priv->dma_desc_device_addr);
+
+ mmc_remove_host(mmc);
+
+ free_irq(priv->irq_regular, priv);
+ free_irq(priv->irq_dma, priv);
+
+ iounmap(priv->sdmmc_base);
+
+ clk_disable_unprepare(priv->clk_sdmmc);
+ clk_put(priv->clk_sdmmc);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, res->end - res->start + 1);
+
+ mmc_free_host(mmc);
+
+ platform_set_drvdata(pdev, NULL);
+
+ dev_info(&pdev->dev, "WMT MCI device removed\n");
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int wmt_mci_suspend(struct device *dev)
+{
+ u32 reg_tmp;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mmc_host *mmc = platform_get_drvdata(pdev);
+ struct wmt_mci_priv *priv;
+ int ret;
+
+ if (!mmc)
+ return 0;
+
+ priv = mmc_priv(mmc);
+ ret = mmc_suspend_host(mmc);
+
+ if (!ret) {
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+ writeb(reg_tmp | BM_SOFT_RESET, priv->sdmmc_base +
+ SDMMC_BUSMODE);
+
+ reg_tmp = readw(priv->sdmmc_base + SDMMC_BLKLEN);
+ writew(reg_tmp & 0x5FFF, priv->sdmmc_base + SDMMC_BLKLEN);
+
+ writeb(0xFF, priv->sdmmc_base + SDMMC_STS0);
+ writeb(0xFF, priv->sdmmc_base + SDMMC_STS1);
+
+ clk_disable(priv->clk_sdmmc);
+ }
+ return ret;
+}
+
+static int wmt_mci_resume(struct device *dev)
+{
+ u32 reg_tmp;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mmc_host *mmc = platform_get_drvdata(pdev);
+ struct wmt_mci_priv *priv;
+ int ret = 0;
+
+ if (mmc) {
+ priv = mmc_priv(mmc);
+ clk_enable(priv->clk_sdmmc);
+
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+ writeb(reg_tmp | BM_SOFT_RESET, priv->sdmmc_base +
+ SDMMC_BUSMODE);
+
+ reg_tmp = readw(priv->sdmmc_base + SDMMC_BLKLEN);
+ writew(reg_tmp | (BLKL_GPI_CD | BLKL_INT_ENABLE),
+ priv->sdmmc_base + SDMMC_BLKLEN);
+
+ reg_tmp = readb(priv->sdmmc_base + SDMMC_INTMASK0);
+ writeb(reg_tmp | INT0_DI_INT_EN, priv->sdmmc_base +
+ SDMMC_INTMASK0);
+
+ ret = mmc_resume_host(mmc);
+ }
+
+ return ret;
+}
+
+static const struct dev_pm_ops wmt_mci_pm = {
+ .suspend = wmt_mci_suspend,
+ .resume = wmt_mci_resume,
+};
+
+#define wmt_mci_pm_ops (&wmt_mci_pm)
+
+#else /* !CONFIG_PM */
+
+#define wmt_mci_pm_ops NULL
+
+#endif
+
+static struct platform_driver wmt_mci_driver = {
+ .probe = wmt_mci_probe,
+ .remove = __exit_p(wmt_mci_remove),
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .pm = wmt_mci_pm_ops,
+ .of_match_table = wmt_mci_dt_ids,
+ },
+};
+
+module_platform_driver(wmt_mci_driver);
+
+MODULE_DESCRIPTION("Wondermedia MMC/SD Driver");
+MODULE_AUTHOR("Tony Prisk");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, wmt_mci_dt_ids);
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 8f52fc858e4..5a5cd2ace4a 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -240,7 +240,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
if (*(szlength) != '+') {
devlength = simple_strtoul(szlength, &buffer, 0);
- devlength = handle_unit(devlength, buffer) - devstart;
+ devlength = handle_unit(devlength, buffer);
if (devlength < devstart)
goto err_out;
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 374c46dff7d..ec794a72975 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1077,7 +1077,8 @@ EXPORT_SYMBOL_GPL(mtd_writev);
* until the request succeeds or until the allocation size falls below
* the system page size. This attempts to make sure it does not adversely
* impact system performance, so when allocating more than one page, we
- * ask the memory allocator to avoid re-trying.
+ * ask the memory allocator to avoid re-trying, swapping, writing back
+ * or performing I/O.
*
* Note, this function also makes sure that the allocated buffer is aligned to
* the MTD device's min. I/O unit, i.e. the "mtd->writesize" value.
@@ -1091,7 +1092,8 @@ EXPORT_SYMBOL_GPL(mtd_writev);
*/
void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size)
{
- gfp_t flags = __GFP_NOWARN | __GFP_WAIT | __GFP_NORETRY;
+ gfp_t flags = __GFP_NOWARN | __GFP_WAIT |
+ __GFP_NORETRY | __GFP_NO_KSWAPD;
size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE);
void *kbuf;
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 91445578330..92623ac2015 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -41,6 +41,7 @@
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/platform_data/atmel.h>
+#include <linux/pinctrl/consumer.h>
#include <mach/cpu.h>
@@ -1370,6 +1371,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
struct resource *mem;
struct mtd_part_parser_data ppdata = {};
int res;
+ struct pinctrl *pinctrl;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
@@ -1414,6 +1416,13 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
nand_chip->IO_ADDR_W = host->io_base;
nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl;
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(host->dev, "Failed to request pinctrl\n");
+ res = PTR_ERR(pinctrl);
+ goto err_ecc_ioremap;
+ }
+
if (gpio_is_valid(host->board.rdy_pin)) {
res = gpio_request(host->board.rdy_pin, "nand_rdy");
if (res < 0) {
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index ec6841d8e95..1a03b7f673c 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2983,13 +2983,15 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
/*
* Field definitions are in the following datasheets:
* Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
- * New style (6 byte ID): Samsung K9GAG08U0F (p.44)
+ * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
* Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22)
*
- * Check for ID length, cell type, and Hynix/Samsung ID to decide what
- * to do.
+ * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung
+ * ID to decide what to do.
*/
- if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) {
+ if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
+ (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+ id_data[5] != 0x00) {
/* Calc pagesize */
mtd->writesize = 2048 << (extid & 0x03);
extid >>= 2;
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 4fbfe96e37a..f48ac5d80bb 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -727,7 +727,9 @@ static void flctl_select_chip(struct mtd_info *mtd, int chipnr)
if (!flctl->qos_request) {
ret = dev_pm_qos_add_request(&flctl->pdev->dev,
- &flctl->pm_qos, 100);
+ &flctl->pm_qos,
+ DEV_PM_QOS_LATENCY,
+ 100);
if (ret < 0)
dev_err(&flctl->pdev->dev,
"PM QoS request failed: %d\n", ret);
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 64be8f0848b..d9127e2ed80 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -121,7 +121,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master,
nr_parts = plen / sizeof(part[0]);
*pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL);
- if (!pparts)
+ if (!*pparts)
return -ENOMEM;
names = of_get_property(dp, "partition-names", &plen);
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 7153e0d2710..b3f41f20062 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -3694,7 +3694,7 @@ static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int
* flexonenand_set_boundary - Writes the SLC boundary
* @param mtd - mtd info structure
*/
-int flexonenand_set_boundary(struct mtd_info *mtd, int die,
+static int flexonenand_set_boundary(struct mtd_info *mtd, int die,
int boundary, int lock)
{
struct onenand_chip *this = mtd->priv;
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index da7b44998b4..2144f611196 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -498,7 +498,7 @@ out:
* @ubi: UBI device description object
*
* This function returns a physical eraseblock in case of success and a
- * negative error code in case of failure. Might sleep.
+ * negative error code in case of failure.
*/
static int __wl_get_peb(struct ubi_device *ubi)
{
@@ -540,13 +540,6 @@ retry:
* ubi_wl_get_peb() after removing e from the pool. */
prot_queue_add(ubi, e);
#endif
- err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset,
- ubi->peb_size - ubi->vid_hdr_aloffset);
- if (err) {
- ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum);
- return err;
- }
-
return e->pnum;
}
@@ -679,17 +672,30 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
#else
static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
{
- return find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
+ struct ubi_wl_entry *e;
+
+ e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
+ self_check_in_wl_tree(ubi, e, &ubi->free);
+ rb_erase(&e->u.rb, &ubi->free);
+
+ return e;
}
int ubi_wl_get_peb(struct ubi_device *ubi)
{
- int peb;
+ int peb, err;
spin_lock(&ubi->wl_lock);
peb = __wl_get_peb(ubi);
spin_unlock(&ubi->wl_lock);
+ err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset,
+ ubi->peb_size - ubi->vid_hdr_aloffset);
+ if (err) {
+ ubi_err("new PEB %d does not contain all 0xFF bytes", peb);
+ return err;
+ }
+
return peb;
}
#endif
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index b2530b00212..a7d47350ea4 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1379,6 +1379,8 @@ static void bond_compute_features(struct bonding *bond)
struct net_device *bond_dev = bond->dev;
netdev_features_t vlan_features = BOND_VLAN_FEATURES;
unsigned short max_hard_header_len = ETH_HLEN;
+ unsigned int gso_max_size = GSO_MAX_SIZE;
+ u16 gso_max_segs = GSO_MAX_SEGS;
int i;
unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE;
@@ -1394,11 +1396,16 @@ static void bond_compute_features(struct bonding *bond)
dst_release_flag &= slave->dev->priv_flags;
if (slave->dev->hard_header_len > max_hard_header_len)
max_hard_header_len = slave->dev->hard_header_len;
+
+ gso_max_size = min(gso_max_size, slave->dev->gso_max_size);
+ gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs);
}
done:
bond_dev->vlan_features = vlan_features;
bond_dev->hard_header_len = max_hard_header_len;
+ bond_dev->gso_max_segs = gso_max_segs;
+ netif_set_gso_max_size(bond_dev, gso_max_size);
flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE;
bond_dev->priv_flags = flags | dst_release_flag;
@@ -3452,6 +3459,28 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count)
/*-------------------------- Device entry points ----------------------------*/
+static void bond_work_init_all(struct bonding *bond)
+{
+ INIT_DELAYED_WORK(&bond->mcast_work,
+ bond_resend_igmp_join_requests_delayed);
+ INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
+ INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
+ if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+ INIT_DELAYED_WORK(&bond->arp_work, bond_activebackup_arp_mon);
+ else
+ INIT_DELAYED_WORK(&bond->arp_work, bond_loadbalance_arp_mon);
+ INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
+}
+
+static void bond_work_cancel_all(struct bonding *bond)
+{
+ cancel_delayed_work_sync(&bond->mii_work);
+ cancel_delayed_work_sync(&bond->arp_work);
+ cancel_delayed_work_sync(&bond->alb_work);
+ cancel_delayed_work_sync(&bond->ad_work);
+ cancel_delayed_work_sync(&bond->mcast_work);
+}
+
static int bond_open(struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
@@ -3474,41 +3503,27 @@ static int bond_open(struct net_device *bond_dev)
}
read_unlock(&bond->lock);
- INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed);
+ bond_work_init_all(bond);
if (bond_is_lb(bond)) {
/* bond_alb_initialize must be called before the timer
* is started.
*/
- if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) {
- /* something went wrong - fail the open operation */
+ if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB)))
return -ENOMEM;
- }
-
- INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
queue_delayed_work(bond->wq, &bond->alb_work, 0);
}
- if (bond->params.miimon) { /* link check interval, in milliseconds. */
- INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
+ if (bond->params.miimon) /* link check interval, in milliseconds. */
queue_delayed_work(bond->wq, &bond->mii_work, 0);
- }
if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
- if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_activebackup_arp_mon);
- else
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_loadbalance_arp_mon);
-
queue_delayed_work(bond->wq, &bond->arp_work, 0);
if (bond->params.arp_validate)
bond->recv_probe = bond_arp_rcv;
}
if (bond->params.mode == BOND_MODE_8023AD) {
- INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
queue_delayed_work(bond->wq, &bond->ad_work, 0);
/* register to receive LACPDUs */
bond->recv_probe = bond_3ad_lacpdu_recv;
@@ -3523,34 +3538,10 @@ static int bond_close(struct net_device *bond_dev)
struct bonding *bond = netdev_priv(bond_dev);
write_lock_bh(&bond->lock);
-
bond->send_peer_notif = 0;
-
write_unlock_bh(&bond->lock);
- if (bond->params.miimon) { /* link check interval, in milliseconds. */
- cancel_delayed_work_sync(&bond->mii_work);
- }
-
- if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
- cancel_delayed_work_sync(&bond->arp_work);
- }
-
- switch (bond->params.mode) {
- case BOND_MODE_8023AD:
- cancel_delayed_work_sync(&bond->ad_work);
- break;
- case BOND_MODE_TLB:
- case BOND_MODE_ALB:
- cancel_delayed_work_sync(&bond->alb_work);
- break;
- default:
- break;
- }
-
- if (delayed_work_pending(&bond->mcast_work))
- cancel_delayed_work_sync(&bond->mcast_work);
-
+ bond_work_cancel_all(bond);
if (bond_is_lb(bond)) {
/* Must be called only after all
* slaves have been released
@@ -4429,26 +4420,6 @@ static void bond_setup(struct net_device *bond_dev)
bond_dev->features |= bond_dev->hw_features;
}
-static void bond_work_cancel_all(struct bonding *bond)
-{
- if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
- cancel_delayed_work_sync(&bond->mii_work);
-
- if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
- cancel_delayed_work_sync(&bond->arp_work);
-
- if (bond->params.mode == BOND_MODE_ALB &&
- delayed_work_pending(&bond->alb_work))
- cancel_delayed_work_sync(&bond->alb_work);
-
- if (bond->params.mode == BOND_MODE_8023AD &&
- delayed_work_pending(&bond->ad_work))
- cancel_delayed_work_sync(&bond->ad_work);
-
- if (delayed_work_pending(&bond->mcast_work))
- cancel_delayed_work_sync(&bond->mcast_work);
-}
-
/*
* Destroy a bonding device.
* Must be under rtnl_lock when this function is called.
@@ -4699,12 +4670,13 @@ static int bond_check_params(struct bond_params *params)
arp_ip_count++) {
/* not complete check, but should be good enough to
catch mistakes */
- if (!isdigit(arp_ip_target[arp_ip_count][0])) {
+ __be32 ip = in_aton(arp_ip_target[arp_ip_count]);
+ if (!isdigit(arp_ip_target[arp_ip_count][0]) ||
+ ip == 0 || ip == htonl(INADDR_BROADCAST)) {
pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n",
arp_ip_target[arp_ip_count]);
arp_interval = 0;
} else {
- __be32 ip = in_aton(arp_ip_target[arp_ip_count]);
arp_target[arp_ip_count] = ip;
}
}
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index ef8d2a080d1..1877ed7ca08 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -513,6 +513,8 @@ static ssize_t bonding_store_arp_interval(struct device *d,
int new_value, ret = count;
struct bonding *bond = to_bond(d);
+ if (!rtnl_trylock())
+ return restart_syscall();
if (sscanf(buf, "%d", &new_value) != 1) {
pr_err("%s: no arp_interval value specified.\n",
bond->dev->name);
@@ -539,10 +541,6 @@ static ssize_t bonding_store_arp_interval(struct device *d,
pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n",
bond->dev->name, bond->dev->name);
bond->params.miimon = 0;
- if (delayed_work_pending(&bond->mii_work)) {
- cancel_delayed_work(&bond->mii_work);
- flush_workqueue(bond->wq);
- }
}
if (!bond->params.arp_targets[0]) {
pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n",
@@ -554,19 +552,12 @@ static ssize_t bonding_store_arp_interval(struct device *d,
* timer will get fired off when the open function
* is called.
*/
- if (!delayed_work_pending(&bond->arp_work)) {
- if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_activebackup_arp_mon);
- else
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_loadbalance_arp_mon);
-
- queue_delayed_work(bond->wq, &bond->arp_work, 0);
- }
+ cancel_delayed_work_sync(&bond->mii_work);
+ queue_delayed_work(bond->wq, &bond->arp_work, 0);
}
out:
+ rtnl_unlock();
return ret;
}
static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR,
@@ -962,6 +953,8 @@ static ssize_t bonding_store_miimon(struct device *d,
int new_value, ret = count;
struct bonding *bond = to_bond(d);
+ if (!rtnl_trylock())
+ return restart_syscall();
if (sscanf(buf, "%d", &new_value) != 1) {
pr_err("%s: no miimon value specified.\n",
bond->dev->name);
@@ -993,10 +986,6 @@ static ssize_t bonding_store_miimon(struct device *d,
bond->params.arp_validate =
BOND_ARP_VALIDATE_NONE;
}
- if (delayed_work_pending(&bond->arp_work)) {
- cancel_delayed_work(&bond->arp_work);
- flush_workqueue(bond->wq);
- }
}
if (bond->dev->flags & IFF_UP) {
@@ -1005,15 +994,12 @@ static ssize_t bonding_store_miimon(struct device *d,
* timer will get fired off when the open function
* is called.
*/
- if (!delayed_work_pending(&bond->mii_work)) {
- INIT_DELAYED_WORK(&bond->mii_work,
- bond_mii_monitor);
- queue_delayed_work(bond->wq,
- &bond->mii_work, 0);
- }
+ cancel_delayed_work_sync(&bond->arp_work);
+ queue_delayed_work(bond->wq, &bond->mii_work, 0);
}
}
out:
+ rtnl_unlock();
return ret;
}
static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR,
@@ -1582,6 +1568,7 @@ static ssize_t bonding_store_slaves_active(struct device *d,
goto out;
}
+ read_lock(&bond->lock);
bond_for_each_slave(bond, slave, i) {
if (!bond_is_active_slave(slave)) {
if (new_value)
@@ -1590,6 +1577,7 @@ static ssize_t bonding_store_slaves_active(struct device *d,
slave->inactive = 1;
}
}
+ read_unlock(&bond->lock);
out:
return ret;
}
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 86f26a1ede4..25723d8ee20 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -519,8 +519,10 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
mc->pdev->dev.can.state = new_state;
if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) {
+ struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb);
+
peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv);
- skb->tstamp = timeval_to_ktime(tv);
+ hwts->hwtstamp = timeval_to_ktime(tv);
}
netif_rx(skb);
@@ -605,6 +607,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len)
struct sk_buff *skb;
struct can_frame *cf;
struct timeval tv;
+ struct skb_shared_hwtstamps *hwts;
skb = alloc_can_skb(mc->netdev, &cf);
if (!skb)
@@ -652,7 +655,8 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len)
/* convert timestamp into kernel time */
peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv);
- skb->tstamp = timeval_to_ktime(tv);
+ hwts = skb_hwtstamps(skb);
+ hwts->hwtstamp = timeval_to_ktime(tv);
/* push the skb */
netif_rx(skb);
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index e1626d92511..30d79bfa5b1 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -532,6 +532,7 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if,
struct can_frame *can_frame;
struct sk_buff *skb;
struct timeval tv;
+ struct skb_shared_hwtstamps *hwts;
skb = alloc_can_skb(netdev, &can_frame);
if (!skb)
@@ -549,7 +550,8 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if,
memcpy(can_frame->data, rx->data, can_frame->can_dlc);
peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(rx->ts32), &tv);
- skb->tstamp = timeval_to_ktime(tv);
+ hwts = skb_hwtstamps(skb);
+ hwts->hwtstamp = timeval_to_ktime(tv);
netif_rx(skb);
netdev->stats.rx_packets++;
@@ -570,6 +572,7 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if,
u8 err_mask = 0;
struct sk_buff *skb;
struct timeval tv;
+ struct skb_shared_hwtstamps *hwts;
/* nothing should be sent while in BUS_OFF state */
if (dev->can.state == CAN_STATE_BUS_OFF)
@@ -664,7 +667,8 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if,
dev->can.state = new_state;
peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(er->ts32), &tv);
- skb->tstamp = timeval_to_ktime(tv);
+ hwts = skb_hwtstamps(skb);
+ hwts->hwtstamp = timeval_to_ktime(tv);
netif_rx(skb);
netdev->stats.rx_packets++;
netdev->stats.rx_bytes += can_frame->can_dlc;
diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c
index d04911d33b6..47618e50535 100644
--- a/drivers/net/ethernet/8390/ne.c
+++ b/drivers/net/ethernet/8390/ne.c
@@ -813,6 +813,7 @@ static int __init ne_drv_probe(struct platform_device *pdev)
dev->irq = irq[this_dev];
dev->mem_end = bad[this_dev];
}
+ SET_NETDEV_DEV(dev, &pdev->dev);
err = do_ne_probe(dev);
if (err) {
free_netdev(dev);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index bd1fd3d87c2..01611b33a93 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -9545,10 +9545,13 @@ static int __devinit bnx2x_prev_unload_common(struct bnx2x *bp)
*/
static void __devinit bnx2x_prev_interrupted_dmae(struct bnx2x *bp)
{
- u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS);
- if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) {
- BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing");
- REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, 1 << BP_FUNC(bp));
+ if (!CHIP_IS_E1x(bp)) {
+ u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS);
+ if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) {
+ BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing");
+ REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR,
+ 1 << BP_FUNC(bp));
+ }
}
}
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 92317e9c0f7..60ac46f4ac0 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -1860,10 +1860,14 @@ jme_open(struct net_device *netdev)
jme_clear_pm(jme);
JME_NAPI_ENABLE(jme);
- tasklet_enable(&jme->linkch_task);
- tasklet_enable(&jme->txclean_task);
- tasklet_hi_enable(&jme->rxclean_task);
- tasklet_hi_enable(&jme->rxempty_task);
+ tasklet_init(&jme->linkch_task, jme_link_change_tasklet,
+ (unsigned long) jme);
+ tasklet_init(&jme->txclean_task, jme_tx_clean_tasklet,
+ (unsigned long) jme);
+ tasklet_init(&jme->rxclean_task, jme_rx_clean_tasklet,
+ (unsigned long) jme);
+ tasklet_init(&jme->rxempty_task, jme_rx_empty_tasklet,
+ (unsigned long) jme);
rc = jme_request_irq(jme);
if (rc)
@@ -3079,22 +3083,6 @@ jme_init_one(struct pci_dev *pdev,
tasklet_init(&jme->pcc_task,
jme_pcc_tasklet,
(unsigned long) jme);
- tasklet_init(&jme->linkch_task,
- jme_link_change_tasklet,
- (unsigned long) jme);
- tasklet_init(&jme->txclean_task,
- jme_tx_clean_tasklet,
- (unsigned long) jme);
- tasklet_init(&jme->rxclean_task,
- jme_rx_clean_tasklet,
- (unsigned long) jme);
- tasklet_init(&jme->rxempty_task,
- jme_rx_empty_tasklet,
- (unsigned long) jme);
- tasklet_disable_nosync(&jme->linkch_task);
- tasklet_disable_nosync(&jme->txclean_task);
- tasklet_disable_nosync(&jme->rxclean_task);
- tasklet_disable_nosync(&jme->rxempty_task);
jme->dpi.cur = PCC_P1;
jme->reg_ghc = 0;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
index 5d36795877c..b799ab12a29 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
@@ -237,7 +237,7 @@ static int mlx4_en_dcbnl_ieee_setmaxrate(struct net_device *dev,
if (err)
return err;
- memcpy(priv->maxrate, tmp, sizeof(*priv->maxrate));
+ memcpy(priv->maxrate, tmp, sizeof(priv->maxrate));
return 0;
}
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c
index e558edd1cb6..69e01977a1d 100644
--- a/drivers/net/ethernet/micrel/ksz884x.c
+++ b/drivers/net/ethernet/micrel/ksz884x.c
@@ -5459,8 +5459,10 @@ static int prepare_hardware(struct net_device *dev)
rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev);
if (rc)
return rc;
- tasklet_enable(&hw_priv->rx_tasklet);
- tasklet_enable(&hw_priv->tx_tasklet);
+ tasklet_init(&hw_priv->rx_tasklet, rx_proc_task,
+ (unsigned long) hw_priv);
+ tasklet_init(&hw_priv->tx_tasklet, tx_proc_task,
+ (unsigned long) hw_priv);
hw->promiscuous = 0;
hw->all_multi = 0;
@@ -7033,16 +7035,6 @@ static int __devinit pcidev_init(struct pci_dev *pdev,
spin_lock_init(&hw_priv->hwlock);
mutex_init(&hw_priv->lock);
- /* tasklet is enabled. */
- tasklet_init(&hw_priv->rx_tasklet, rx_proc_task,
- (unsigned long) hw_priv);
- tasklet_init(&hw_priv->tx_tasklet, tx_proc_task,
- (unsigned long) hw_priv);
-
- /* tasklet_enable will decrement the atomic counter. */
- tasklet_disable(&hw_priv->rx_tasklet);
- tasklet_disable(&hw_priv->tx_tasklet);
-
for (i = 0; i < TOTAL_PORT_NUM; i++)
init_waitqueue_head(&hw_priv->counter[i].counter);
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index 1c818254b7b..609125a249d 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -979,17 +979,6 @@ static void cp_init_hw (struct cp_private *cp)
cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4)));
- cpw32_f(HiTxRingAddr, 0);
- cpw32_f(HiTxRingAddr + 4, 0);
-
- ring_dma = cp->ring_dma;
- cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
- cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
-
- ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
- cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
- cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
-
cp_start_hw(cp);
cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */
@@ -1003,6 +992,17 @@ static void cp_init_hw (struct cp_private *cp)
cpw8(Config5, cpr8(Config5) & PMEStatus);
+ cpw32_f(HiTxRingAddr, 0);
+ cpw32_f(HiTxRingAddr + 4, 0);
+
+ ring_dma = cp->ring_dma;
+ cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
+ cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
+
+ ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
+ cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
+ cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
+
cpw16(MultiIntr, 0);
cpw8_f(Cfg9346, Cfg9346_Lock);
@@ -1060,17 +1060,22 @@ static int cp_init_rings (struct cp_private *cp)
static int cp_alloc_rings (struct cp_private *cp)
{
+ struct device *d = &cp->pdev->dev;
void *mem;
+ int rc;
- mem = dma_alloc_coherent(&cp->pdev->dev, CP_RING_BYTES,
- &cp->ring_dma, GFP_KERNEL);
+ mem = dma_alloc_coherent(d, CP_RING_BYTES, &cp->ring_dma, GFP_KERNEL);
if (!mem)
return -ENOMEM;
cp->rx_ring = mem;
cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE];
- return cp_init_rings(cp);
+ rc = cp_init_rings(cp);
+ if (rc < 0)
+ dma_free_coherent(d, CP_RING_BYTES, cp->rx_ring, cp->ring_dma);
+
+ return rc;
}
static void cp_clean_rings (struct cp_private *cp)
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
index fb9f6b38511..edf5edb1314 100644
--- a/drivers/net/ethernet/sis/sis900.c
+++ b/drivers/net/ethernet/sis/sis900.c
@@ -2479,7 +2479,7 @@ static int sis900_resume(struct pci_dev *pci_dev)
netif_start_queue(net_dev);
/* Workaround for EDB */
- sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
+ sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
/* Enable all known interrupts by setting the interrupt mask. */
sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE);
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index 62d1baf111e..c53c0f4e2ce 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -2110,7 +2110,7 @@ static void __devinit smsc911x_read_mac_address(struct net_device *dev)
static int __devinit smsc911x_init(struct net_device *dev)
{
struct smsc911x_data *pdata = netdev_priv(dev);
- unsigned int byte_test;
+ unsigned int byte_test, mask;
unsigned int to = 100;
SMSC_TRACE(pdata, probe, "Driver Parameters:");
@@ -2130,9 +2130,22 @@ static int __devinit smsc911x_init(struct net_device *dev)
/*
* poll the READY bit in PMT_CTRL. Any other access to the device is
* forbidden while this bit isn't set. Try for 100ms
+ *
+ * Note that this test is done before the WORD_SWAP register is
+ * programmed. So in some configurations the READY bit is at 16 before
+ * WORD_SWAP is written to. This issue is worked around by waiting
+ * until either bit 0 or bit 16 gets set in PMT_CTRL.
+ *
+ * SMSC has confirmed that checking bit 16 (marked as reserved in
+ * the datasheet) is fine since these bits "will either never be set
+ * or can only go high after READY does (so also indicate the device
+ * is ready)".
*/
- while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to)
+
+ mask = PMT_CTRL_READY_ | swahw32(PMT_CTRL_READY_);
+ while (!(smsc911x_reg_read(pdata, PMT_CTRL) & mask) && --to)
udelay(1000);
+
if (to == 0) {
pr_err("Device not READY in 100ms aborting\n");
return -ENODEV;
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c
index 4e981001385..66e025ad5df 100644
--- a/drivers/net/ethernet/tile/tilegx.c
+++ b/drivers/net/ethernet/tile/tilegx.c
@@ -917,7 +917,7 @@ static int tile_net_setup_interrupts(struct net_device *dev)
ingress_irq = rc;
tile_irq_activate(ingress_irq, TILE_IRQ_PERCPU);
rc = request_irq(ingress_irq, tile_net_handle_ingress_irq,
- 0, NULL, NULL);
+ 0, "tile_net", NULL);
if (rc != 0) {
netdev_err(dev, "request_irq failed: %d\n", rc);
destroy_irq(ingress_irq);
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 1d04754a663..a788501e978 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -894,6 +894,8 @@ out:
return IRQ_HANDLED;
}
+static void axienet_dma_err_handler(unsigned long data);
+
/**
* axienet_open - Driver open routine.
* @ndev: Pointer to net_device structure
@@ -942,6 +944,10 @@ static int axienet_open(struct net_device *ndev)
phy_start(lp->phy_dev);
}
+ /* Enable tasklets for Axi DMA error handling */
+ tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler,
+ (unsigned long) lp);
+
/* Enable interrupts for Axi DMA Tx */
ret = request_irq(lp->tx_irq, axienet_tx_irq, 0, ndev->name, ndev);
if (ret)
@@ -950,8 +956,7 @@ static int axienet_open(struct net_device *ndev)
ret = request_irq(lp->rx_irq, axienet_rx_irq, 0, ndev->name, ndev);
if (ret)
goto err_rx_irq;
- /* Enable tasklets for Axi DMA error handling */
- tasklet_enable(&lp->dma_err_tasklet);
+
return 0;
err_rx_irq:
@@ -960,6 +965,7 @@ err_tx_irq:
if (lp->phy_dev)
phy_disconnect(lp->phy_dev);
lp->phy_dev = NULL;
+ tasklet_kill(&lp->dma_err_tasklet);
dev_err(lp->dev, "request_irq() failed\n");
return ret;
}
@@ -1613,10 +1619,6 @@ static int __devinit axienet_of_probe(struct platform_device *op)
goto err_iounmap_2;
}
- tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler,
- (unsigned long) lp);
- tasklet_disable(&lp->dma_err_tasklet);
-
return 0;
err_iounmap_2:
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
index 98934bdf6ac..477d6729b17 100644
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -1102,10 +1102,12 @@ static int init_queues(struct port *port)
{
int i;
- if (!ports_open)
- if (!(dma_pool = dma_pool_create(DRV_NAME, NULL,
- POOL_ALLOC_SIZE, 32, 0)))
+ if (!ports_open) {
+ dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev,
+ POOL_ALLOC_SIZE, 32, 0);
+ if (!dma_pool)
return -ENOMEM;
+ }
if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL,
&port->desc_tab_phys)))
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index 5039f08f5a5..43e9ab4f4d7 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -222,7 +222,7 @@ static void sirdev_config_fsm(struct work_struct *work)
break;
case SIRDEV_STATE_DONGLE_SPEED:
- if (dev->dongle_drv->reset) {
+ if (dev->dongle_drv->set_speed) {
ret = dev->dongle_drv->set_speed(dev, fsm->param);
if (ret < 0) {
fsm->result = ret;
diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
index 6428fcbbdd4..daec9b05d16 100644
--- a/drivers/net/phy/mdio-bitbang.c
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -234,7 +234,6 @@ void free_mdio_bitbang(struct mii_bus *bus)
struct mdiobb_ctrl *ctrl = bus->priv;
module_put(ctrl->ops->owner);
- mdiobus_unregister(bus);
mdiobus_free(bus);
}
EXPORT_SYMBOL(free_mdio_bitbang);
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index 899274f2f9b..2ed1140df3e 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -185,17 +185,20 @@ static int __devinit mdio_gpio_probe(struct platform_device *pdev)
{
struct mdio_gpio_platform_data *pdata;
struct mii_bus *new_bus;
- int ret;
+ int ret, bus_id;
- if (pdev->dev.of_node)
+ if (pdev->dev.of_node) {
pdata = mdio_gpio_of_get_data(pdev);
- else
+ bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio");
+ } else {
pdata = pdev->dev.platform_data;
+ bus_id = pdev->id;
+ }
if (!pdata)
return -ENODEV;
- new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id);
+ new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, bus_id);
if (!new_bus)
return -ENODEV;
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index d44cca32758..ad86660fb8f 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -1794,10 +1794,12 @@ static void team_setup(struct net_device *dev)
dev->features |= NETIF_F_LLTX;
dev->features |= NETIF_F_GRO;
- dev->hw_features = NETIF_F_HW_VLAN_TX |
+ dev->hw_features = TEAM_VLAN_FEATURES |
+ NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER;
+ dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM);
dev->features |= dev->hw_features;
}
diff --git a/drivers/net/team/team_mode_broadcast.c b/drivers/net/team/team_mode_broadcast.c
index 9db0171e936..c5db428e73f 100644
--- a/drivers/net/team/team_mode_broadcast.c
+++ b/drivers/net/team/team_mode_broadcast.c
@@ -29,8 +29,8 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb)
if (last) {
skb2 = skb_clone(skb, GFP_ATOMIC);
if (skb2) {
- ret = team_dev_queue_xmit(team, last,
- skb2);
+ ret = !team_dev_queue_xmit(team, last,
+ skb2);
if (!sum_ret)
sum_ret = ret;
}
@@ -39,7 +39,7 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb)
}
}
if (last) {
- ret = team_dev_queue_xmit(team, last, skb);
+ ret = !team_dev_queue_xmit(team, last, skb);
if (!sum_ret)
sum_ret = ret;
}
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 4cd582a4f62..74fab1a4015 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -540,10 +540,12 @@ advance:
(ctx->ether_desc == NULL) || (ctx->control != intf))
goto error;
- /* claim interfaces, if any */
- temp = usb_driver_claim_interface(driver, ctx->data, dev);
- if (temp)
- goto error;
+ /* claim data interface, if different from control */
+ if (ctx->data != ctx->control) {
+ temp = usb_driver_claim_interface(driver, ctx->data, dev);
+ if (temp)
+ goto error;
+ }
iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;
@@ -623,6 +625,10 @@ static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
tasklet_kill(&ctx->bh);
+ /* handle devices with combined control and data interface */
+ if (ctx->control == ctx->data)
+ ctx->data = NULL;
+
/* disconnect master --> disconnect slave */
if (intf == ctx->control && ctx->data) {
usb_set_intfdata(ctx->data, NULL);
@@ -1245,6 +1251,14 @@ static const struct usb_device_id cdc_devs[] = {
.driver_info = (unsigned long) &wwan_info,
},
+ /* Huawei NCM devices disguised as vendor specific */
+ { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16),
+ .driver_info = (unsigned long)&wwan_info,
+ },
+ { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46),
+ .driver_info = (unsigned long)&wwan_info,
+ },
+
/* Generic CDC-NCM devices */
{ USB_INTERFACE_INFO(USB_CLASS_COMM,
USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 605a4baa9b7..cd8ccb240f4 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -2274,6 +2274,7 @@ static void hso_serial_common_free(struct hso_serial *serial)
/* unlink and free TX URB */
usb_free_urb(serial->tx_urb);
kfree(serial->tx_data);
+ tty_port_destroy(&serial->port);
}
static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
@@ -2283,12 +2284,12 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
int minor;
int i;
+ tty_port_init(&serial->port);
+
minor = get_free_serial_index();
if (minor < 0)
goto exit;
- tty_port_init(&serial->port);
-
/* register our minor number */
serial->parent->dev = tty_port_register_device(&serial->port, tty_drv,
minor, &serial->parent->interface->dev);
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 3b566fa0f8e..1ea91f4237f 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -385,6 +385,7 @@ static const struct usb_device_id products[] = {
},
/* 3. Combined interface devices matching on interface number */
+ {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */
{QMI_FIXED_INTF(0x19d2, 0x0002, 1)},
{QMI_FIXED_INTF(0x19d2, 0x0012, 1)},
{QMI_FIXED_INTF(0x19d2, 0x0017, 3)},
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 3286166415b..362cb8cfeb9 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -184,7 +184,7 @@ static int smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx)
/* set the address, index & direction (read from PHY) */
phy_id &= dev->mii.phy_id_mask;
idx &= dev->mii.reg_num_mask;
- addr = (phy_id << 11) | (idx << 6) | MII_READ_;
+ addr = (phy_id << 11) | (idx << 6) | MII_READ_ | MII_BUSY_;
ret = smsc95xx_write_reg(dev, MII_ADDR, addr);
check_warn_goto_done(ret, "Error writing MII_ADDR");
@@ -221,7 +221,7 @@ static void smsc95xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
/* set the address, index & direction (write to PHY) */
phy_id &= dev->mii.phy_id_mask;
idx &= dev->mii.reg_num_mask;
- addr = (phy_id << 11) | (idx << 6) | MII_WRITE_;
+ addr = (phy_id << 11) | (idx << 6) | MII_WRITE_ | MII_BUSY_;
ret = smsc95xx_write_reg(dev, MII_ADDR, addr);
check_warn_goto_done(ret, "Error writing MII_ADDR");
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 7b4adde93c0..8b5c6191707 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1,5 +1,5 @@
/*
- * VXLAN: Virtual eXtensiable Local Area Network
+ * VXLAN: Virtual eXtensible Local Area Network
*
* Copyright (c) 2012 Vyatta Inc.
*
@@ -50,8 +50,8 @@
#define VXLAN_N_VID (1u << 24)
#define VXLAN_VID_MASK (VXLAN_N_VID - 1)
-/* VLAN + IP header + UDP + VXLAN */
-#define VXLAN_HEADROOM (4 + 20 + 8 + 8)
+/* IP header + UDP + VXLAN + Ethernet header */
+#define VXLAN_HEADROOM (20 + 8 + 8 + 14)
#define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */
@@ -1102,6 +1102,10 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
if (!tb[IFLA_MTU])
dev->mtu = lowerdev->mtu - VXLAN_HEADROOM;
+
+ /* update header length based on lower device */
+ dev->hard_header_len = lowerdev->hard_header_len +
+ VXLAN_HEADROOM;
}
if (data[IFLA_VXLAN_TOS])
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index 3f575afd8cf..760776b3d66 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -969,10 +969,12 @@ static int init_hdlc_queues(struct port *port)
{
int i;
- if (!ports_open)
- if (!(dma_pool = dma_pool_create(DRV_NAME, NULL,
- POOL_ALLOC_SIZE, 32, 0)))
+ if (!ports_open) {
+ dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev,
+ POOL_ALLOC_SIZE, 32, 0);
+ if (!dma_pool)
return -ENOMEM;
+ }
if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL,
&port->desc_tab_phys)))
@@ -1363,7 +1365,7 @@ static int __devinit hss_init_one(struct platform_device *pdev)
platform_set_drvdata(pdev, port);
- netdev_info(dev, "HSS-%i\n", port->id);
+ netdev_info(dev, "initialized\n");
return 0;
err_free_netdev:
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8e1559aba49..1829b445d0b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1456,7 +1456,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
switch (type) {
case ATH9K_RESET_POWER_ON:
ret = ath9k_hw_set_reset_power_on(ah);
- if (!ret)
+ if (ret)
ah->reset_power_on = true;
break;
case ATH9K_RESET_WARM:
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index a6f1e816600..481345c23de 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -4401,7 +4401,7 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
{
-#ifndef CONFIG_BRCMFISCAN
+#ifndef CONFIG_BRCMISCAN
/* scheduled scan settings */
wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index ff8162d4c45..2d9eee93c74 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -521,7 +521,7 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw,
ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
if (iwlagn_tx_skb(priv, control->sta, skb))
- dev_kfree_skb_any(skb);
+ ieee80211_free_txskb(hw, skb);
}
static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
@@ -1354,6 +1354,20 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
vif_priv->ctx = ctx;
ctx->vif = vif;
+ /*
+ * In SNIFFER device type, the firmware reports the FCS to
+ * the host, rather than snipping it off. Unfortunately,
+ * mac80211 doesn't (yet) provide a per-packet flag for
+ * this, so that we have to set the hardware flag based
+ * on the interfaces added. As the monitor interface can
+ * only be present by itself, and will be removed before
+ * other interfaces are added, this is safe.
+ */
+ if (vif->type == NL80211_IFTYPE_MONITOR)
+ priv->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS;
+ else
+ priv->hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
+
err = iwl_setup_interface(priv, ctx);
if (!err || reset)
goto out;
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 7ff3f143067..408132cf83c 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -2114,7 +2114,7 @@ static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
info = IEEE80211_SKB_CB(skb);
iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]);
- dev_kfree_skb_any(skb);
+ ieee80211_free_txskb(priv->hw, skb);
}
static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c
index 10896393e5a..2830ea29050 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rxon.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c
@@ -1012,12 +1012,12 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv,
* As a consequence, it's not as complicated as it sounds, just add
* any lower rates to the ACK rate bitmap.
*/
- if (IWL_RATE_11M_INDEX < lowest_present_ofdm)
- ofdm |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE;
- if (IWL_RATE_5M_INDEX < lowest_present_ofdm)
- ofdm |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE;
- if (IWL_RATE_2M_INDEX < lowest_present_ofdm)
- ofdm |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE;
+ if (IWL_RATE_11M_INDEX < lowest_present_cck)
+ cck |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE;
+ if (IWL_RATE_5M_INDEX < lowest_present_cck)
+ cck |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE;
+ if (IWL_RATE_2M_INDEX < lowest_present_cck)
+ cck |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE;
/* 1M already there or needed so always add */
cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE;
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 17c8e5d8268..bb69f8f90b3 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -321,6 +321,14 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority)
dma_map_page(trans->dev, page, 0,
PAGE_SIZE << trans_pcie->rx_page_order,
DMA_FROM_DEVICE);
+ if (dma_mapping_error(trans->dev, rxb->page_dma)) {
+ rxb->page = NULL;
+ spin_lock_irqsave(&rxq->lock, flags);
+ list_add(&rxb->list, &rxq->rx_used);
+ spin_unlock_irqrestore(&rxq->lock, flags);
+ __free_pages(page, trans_pcie->rx_page_order);
+ return;
+ }
/* dma address must be no more than 36 bits */
BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
/* and also 256 byte aligned! */
@@ -488,8 +496,19 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
dma_map_page(trans->dev, rxb->page, 0,
PAGE_SIZE << trans_pcie->rx_page_order,
DMA_FROM_DEVICE);
- list_add_tail(&rxb->list, &rxq->rx_free);
- rxq->free_count++;
+ if (dma_mapping_error(trans->dev, rxb->page_dma)) {
+ /*
+ * free the page(s) as well to not break
+ * the invariant that the items on the used
+ * list have no page(s)
+ */
+ __free_pages(rxb->page, trans_pcie->rx_page_order);
+ rxb->page = NULL;
+ list_add_tail(&rxb->list, &rxq->rx_used);
+ } else {
+ list_add_tail(&rxb->list, &rxq->rx_free);
+ rxq->free_count++;
+ }
} else
list_add_tail(&rxb->list, &rxq->rx_used);
spin_unlock_irqrestore(&rxq->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 105e3af3c62..79a4ddc002d 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -480,20 +480,12 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
- u16 rd_ptr, wr_ptr;
- int n_bd = trans_pcie->txq[txq_id].q.n_bd;
if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) {
WARN_ONCE(1, "queue %d not used", txq_id);
return;
}
- rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1);
- wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id));
-
- WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]",
- txq_id, rd_ptr, wr_ptr);
-
iwl_txq_set_inactive(trans, txq_id);
IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
}
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 8d465107f52..ae9010ed58d 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -890,9 +890,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
return;
}
cmd_node = adapter->curr_cmd;
- if (cmd_node->wait_q_enabled)
- adapter->cmd_wait_q.status = -ETIMEDOUT;
-
if (cmd_node) {
adapter->dbg.timeout_cmd_id =
adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index];
@@ -938,6 +935,14 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n",
adapter->ps_mode, adapter->ps_state);
+
+ if (cmd_node->wait_q_enabled) {
+ adapter->cmd_wait_q.status = -ETIMEDOUT;
+ wake_up_interruptible(&adapter->cmd_wait_q.wait);
+ mwifiex_cancel_pending_ioctl(adapter);
+ /* reset cmd_sent flag to unblock new commands */
+ adapter->cmd_sent = false;
+ }
}
if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
mwifiex_init_fw_complete(adapter);
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index fc8a9bfa124..82cf0fa2d9f 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -161,7 +161,6 @@ static int mwifiex_sdio_suspend(struct device *dev)
struct sdio_mmc_card *card;
struct mwifiex_adapter *adapter;
mmc_pm_flag_t pm_flag = 0;
- int hs_actived = 0;
int i;
int ret = 0;
@@ -188,12 +187,14 @@ static int mwifiex_sdio_suspend(struct device *dev)
adapter = card->adapter;
/* Enable the Host Sleep */
- hs_actived = mwifiex_enable_hs(adapter);
- if (hs_actived) {
- pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n");
- ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+ if (!mwifiex_enable_hs(adapter)) {
+ dev_err(adapter->dev, "cmd: failed to suspend\n");
+ return -EFAULT;
}
+ dev_dbg(adapter->dev, "cmd: suspend with MMC_PM_KEEP_POWER\n");
+ ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+
/* Indicate device suspended */
adapter->is_suspended = true;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index 9970c2b1b19..b7e6607e6b6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -297,6 +297,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
/*=== Customer ID ===*/
/****** 8188CU ********/
{RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/
+ {RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/
{RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/
{RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/
{RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index caa011008cd..fc24eb9b394 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -452,29 +452,85 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev,
/* Grant backend access to each skb fragment page. */
for (i = 0; i < frags; i++) {
skb_frag_t *frag = skb_shinfo(skb)->frags + i;
+ struct page *page = skb_frag_page(frag);
- tx->flags |= XEN_NETTXF_more_data;
+ len = skb_frag_size(frag);
+ offset = frag->page_offset;
- id = get_id_from_freelist(&np->tx_skb_freelist, np->tx_skbs);
- np->tx_skbs[id].skb = skb_get(skb);
- tx = RING_GET_REQUEST(&np->tx, prod++);
- tx->id = id;
- ref = gnttab_claim_grant_reference(&np->gref_tx_head);
- BUG_ON((signed short)ref < 0);
+ /* Data must not cross a page boundary. */
+ BUG_ON(len + offset > PAGE_SIZE<<compound_order(page));
- mfn = pfn_to_mfn(page_to_pfn(skb_frag_page(frag)));
- gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id,
- mfn, GNTMAP_readonly);
+ /* Skip unused frames from start of page */
+ page += offset >> PAGE_SHIFT;
+ offset &= ~PAGE_MASK;
- tx->gref = np->grant_tx_ref[id] = ref;
- tx->offset = frag->page_offset;
- tx->size = skb_frag_size(frag);
- tx->flags = 0;
+ while (len > 0) {
+ unsigned long bytes;
+
+ BUG_ON(offset >= PAGE_SIZE);
+
+ bytes = PAGE_SIZE - offset;
+ if (bytes > len)
+ bytes = len;
+
+ tx->flags |= XEN_NETTXF_more_data;
+
+ id = get_id_from_freelist(&np->tx_skb_freelist,
+ np->tx_skbs);
+ np->tx_skbs[id].skb = skb_get(skb);
+ tx = RING_GET_REQUEST(&np->tx, prod++);
+ tx->id = id;
+ ref = gnttab_claim_grant_reference(&np->gref_tx_head);
+ BUG_ON((signed short)ref < 0);
+
+ mfn = pfn_to_mfn(page_to_pfn(page));
+ gnttab_grant_foreign_access_ref(ref,
+ np->xbdev->otherend_id,
+ mfn, GNTMAP_readonly);
+
+ tx->gref = np->grant_tx_ref[id] = ref;
+ tx->offset = offset;
+ tx->size = bytes;
+ tx->flags = 0;
+
+ offset += bytes;
+ len -= bytes;
+
+ /* Next frame */
+ if (offset == PAGE_SIZE && len) {
+ BUG_ON(!PageCompound(page));
+ page++;
+ offset = 0;
+ }
+ }
}
np->tx.req_prod_pvt = prod;
}
+/*
+ * Count how many ring slots are required to send the frags of this
+ * skb. Each frag might be a compound page.
+ */
+static int xennet_count_skb_frag_slots(struct sk_buff *skb)
+{
+ int i, frags = skb_shinfo(skb)->nr_frags;
+ int pages = 0;
+
+ for (i = 0; i < frags; i++) {
+ skb_frag_t *frag = skb_shinfo(skb)->frags + i;
+ unsigned long size = skb_frag_size(frag);
+ unsigned long offset = frag->page_offset;
+
+ /* Skip unused frames from start of page */
+ offset &= ~PAGE_MASK;
+
+ pages += PFN_UP(offset + size);
+ }
+
+ return pages;
+}
+
static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
unsigned short id;
@@ -487,23 +543,23 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
grant_ref_t ref;
unsigned long mfn;
int notify;
- int frags = skb_shinfo(skb)->nr_frags;
+ int slots;
unsigned int offset = offset_in_page(data);
unsigned int len = skb_headlen(skb);
unsigned long flags;
- frags += DIV_ROUND_UP(offset + len, PAGE_SIZE);
- if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
- printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n",
- frags);
- dump_stack();
+ slots = DIV_ROUND_UP(offset + len, PAGE_SIZE) +
+ xennet_count_skb_frag_slots(skb);
+ if (unlikely(slots > MAX_SKB_FRAGS + 1)) {
+ net_alert_ratelimited(
+ "xennet: skb rides the rocket: %d slots\n", slots);
goto drop;
}
spin_lock_irqsave(&np->tx_lock, flags);
if (unlikely(!netif_carrier_ok(dev) ||
- (frags > 1 && !xennet_can_sg(dev)) ||
+ (slots > 1 && !xennet_can_sg(dev)) ||
netif_needs_gso(skb, netif_skb_features(skb)))) {
spin_unlock_irqrestore(&np->tx_lock, flags);
goto drop;
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c
index 97c440a8cd6..30ae18a03a9 100644
--- a/drivers/nfc/pn533.c
+++ b/drivers/nfc/pn533.c
@@ -698,13 +698,14 @@ static void pn533_wq_cmd(struct work_struct *work)
cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue);
+ list_del(&cmd->queue);
+
mutex_unlock(&dev->cmd_lock);
__pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame,
cmd->in_frame_len, cmd->cmd_complete,
cmd->arg, cmd->flags);
- list_del(&cmd->queue);
kfree(cmd);
}
@@ -1678,11 +1679,14 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev,
static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
u8 *params, int params_len)
{
- struct pn533_cmd_jump_dep *cmd;
struct pn533_cmd_jump_dep_response *resp;
struct nfc_target nfc_target;
u8 target_gt_len;
int rc;
+ struct pn533_cmd_jump_dep *cmd = (struct pn533_cmd_jump_dep *)arg;
+ u8 active = cmd->active;
+
+ kfree(arg);
if (params_len == -ENOENT) {
nfc_dev_dbg(&dev->interface->dev, "");
@@ -1704,7 +1708,6 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
}
resp = (struct pn533_cmd_jump_dep_response *) params;
- cmd = (struct pn533_cmd_jump_dep *) arg;
rc = resp->status & PN533_CMD_RET_MASK;
if (rc != PN533_CMD_RET_SUCCESS) {
nfc_dev_err(&dev->interface->dev,
@@ -1734,7 +1737,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
if (rc == 0)
rc = nfc_dep_link_is_up(dev->nfc_dev,
dev->nfc_dev->targets[0].idx,
- !cmd->active, NFC_RF_INITIATOR);
+ !active, NFC_RF_INITIATOR);
return 0;
}
@@ -1819,12 +1822,8 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target,
rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame,
dev->in_maxlen, pn533_in_dep_link_up_complete,
cmd, GFP_KERNEL);
- if (rc)
- goto out;
-
-
-out:
- kfree(cmd);
+ if (rc < 0)
+ kfree(cmd);
return rc;
}
@@ -2078,8 +2077,12 @@ error:
static int pn533_tm_send_complete(struct pn533 *dev, void *arg,
u8 *params, int params_len)
{
+ struct sk_buff *skb_out = arg;
+
nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
+ dev_kfree_skb(skb_out);
+
if (params_len < 0) {
nfc_dev_err(&dev->interface->dev,
"Error %d when sending data",
@@ -2117,7 +2120,7 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb)
rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame,
dev->in_maxlen, pn533_tm_send_complete,
- NULL, GFP_KERNEL);
+ skb, GFP_KERNEL);
if (rc) {
nfc_dev_err(&dev->interface->dev,
"Error %d when trying to send data", rc);
diff --git a/drivers/of/base.c b/drivers/of/base.c
index af3b22ac762..538e3cfad23 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -45,7 +45,8 @@ struct alias_prop {
static LIST_HEAD(aliases_lookup);
-struct device_node *allnodes;
+struct device_node *of_allnodes;
+EXPORT_SYMBOL(of_allnodes);
struct device_node *of_chosen;
struct device_node *of_aliases;
@@ -199,7 +200,7 @@ struct device_node *of_find_all_nodes(struct device_node *prev)
struct device_node *np;
read_lock(&devtree_lock);
- np = prev ? prev->allnext : allnodes;
+ np = prev ? prev->allnext : of_allnodes;
for (; np != NULL; np = np->allnext)
if (of_node_get(np))
break;
@@ -422,7 +423,7 @@ EXPORT_SYMBOL(of_get_child_by_name);
*/
struct device_node *of_find_node_by_path(const char *path)
{
- struct device_node *np = allnodes;
+ struct device_node *np = of_allnodes;
read_lock(&devtree_lock);
for (; np; np = np->allnext) {
@@ -452,7 +453,7 @@ struct device_node *of_find_node_by_name(struct device_node *from,
struct device_node *np;
read_lock(&devtree_lock);
- np = from ? from->allnext : allnodes;
+ np = from ? from->allnext : of_allnodes;
for (; np; np = np->allnext)
if (np->name && (of_node_cmp(np->name, name) == 0)
&& of_node_get(np))
@@ -481,7 +482,7 @@ struct device_node *of_find_node_by_type(struct device_node *from,
struct device_node *np;
read_lock(&devtree_lock);
- np = from ? from->allnext : allnodes;
+ np = from ? from->allnext : of_allnodes;
for (; np; np = np->allnext)
if (np->type && (of_node_cmp(np->type, type) == 0)
&& of_node_get(np))
@@ -512,7 +513,7 @@ struct device_node *of_find_compatible_node(struct device_node *from,
struct device_node *np;
read_lock(&devtree_lock);
- np = from ? from->allnext : allnodes;
+ np = from ? from->allnext : of_allnodes;
for (; np; np = np->allnext) {
if (type
&& !(np->type && (of_node_cmp(np->type, type) == 0)))
@@ -545,7 +546,7 @@ struct device_node *of_find_node_with_property(struct device_node *from,
struct property *pp;
read_lock(&devtree_lock);
- np = from ? from->allnext : allnodes;
+ np = from ? from->allnext : of_allnodes;
for (; np; np = np->allnext) {
for (pp = np->properties; pp; pp = pp->next) {
if (of_prop_cmp(pp->name, prop_name) == 0) {
@@ -594,27 +595,35 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches,
EXPORT_SYMBOL(of_match_node);
/**
- * of_find_matching_node - Find a node based on an of_device_id match
- * table.
+ * of_find_matching_node_and_match - Find a node based on an of_device_id
+ * match table.
* @from: The node to start searching from or NULL, the node
* you pass will not be searched, only the next one
* will; typically, you pass what the previous call
* returned. of_node_put() will be called on it
* @matches: array of of device match structures to search in
+ * @match Updated to point at the matches entry which matched
*
* Returns a node pointer with refcount incremented, use
* of_node_put() on it when done.
*/
-struct device_node *of_find_matching_node(struct device_node *from,
- const struct of_device_id *matches)
+struct device_node *of_find_matching_node_and_match(struct device_node *from,
+ const struct of_device_id *matches,
+ const struct of_device_id **match)
{
struct device_node *np;
+ if (match)
+ *match = NULL;
+
read_lock(&devtree_lock);
- np = from ? from->allnext : allnodes;
+ np = from ? from->allnext : of_allnodes;
for (; np; np = np->allnext) {
- if (of_match_node(matches, np) && of_node_get(np))
+ if (of_match_node(matches, np) && of_node_get(np)) {
+ if (match)
+ *match = matches;
break;
+ }
}
of_node_put(from);
read_unlock(&devtree_lock);
@@ -661,7 +670,7 @@ struct device_node *of_find_node_by_phandle(phandle handle)
struct device_node *np;
read_lock(&devtree_lock);
- for (np = allnodes; np; np = np->allnext)
+ for (np = of_allnodes; np; np = np->allnext)
if (np->phandle == handle)
break;
of_node_get(np);
@@ -671,12 +680,89 @@ struct device_node *of_find_node_by_phandle(phandle handle)
EXPORT_SYMBOL(of_find_node_by_phandle);
/**
+ * of_property_read_u8_array - Find and read an array of u8 from a property.
+ *
+ * @np: device node from which the property value is to be read.
+ * @propname: name of the property to be searched.
+ * @out_value: pointer to return value, modified only if return value is 0.
+ * @sz: number of array elements to read
+ *
+ * Search for a property in a device node and read 8-bit value(s) from
+ * it. Returns 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ *
+ * dts entry of array should be like:
+ * property = /bits/ 8 <0x50 0x60 0x70>;
+ *
+ * The out_value is modified only if a valid u8 value can be decoded.
+ */
+int of_property_read_u8_array(const struct device_node *np,
+ const char *propname, u8 *out_values, size_t sz)
+{
+ struct property *prop = of_find_property(np, propname, NULL);
+ const u8 *val;
+
+ if (!prop)
+ return -EINVAL;
+ if (!prop->value)
+ return -ENODATA;
+ if ((sz * sizeof(*out_values)) > prop->length)
+ return -EOVERFLOW;
+
+ val = prop->value;
+ while (sz--)
+ *out_values++ = *val++;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_property_read_u8_array);
+
+/**
+ * of_property_read_u16_array - Find and read an array of u16 from a property.
+ *
+ * @np: device node from which the property value is to be read.
+ * @propname: name of the property to be searched.
+ * @out_value: pointer to return value, modified only if return value is 0.
+ * @sz: number of array elements to read
+ *
+ * Search for a property in a device node and read 16-bit value(s) from
+ * it. Returns 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ *
+ * dts entry of array should be like:
+ * property = /bits/ 16 <0x5000 0x6000 0x7000>;
+ *
+ * The out_value is modified only if a valid u16 value can be decoded.
+ */
+int of_property_read_u16_array(const struct device_node *np,
+ const char *propname, u16 *out_values, size_t sz)
+{
+ struct property *prop = of_find_property(np, propname, NULL);
+ const __be16 *val;
+
+ if (!prop)
+ return -EINVAL;
+ if (!prop->value)
+ return -ENODATA;
+ if ((sz * sizeof(*out_values)) > prop->length)
+ return -EOVERFLOW;
+
+ val = prop->value;
+ while (sz--)
+ *out_values++ = be16_to_cpup(val++);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_property_read_u16_array);
+
+/**
* of_property_read_u32_array - Find and read an array of 32 bit integers
* from a property.
*
* @np: device node from which the property value is to be read.
* @propname: name of the property to be searched.
* @out_value: pointer to return value, modified only if return value is 0.
+ * @sz: number of array elements to read
*
* Search for a property in a device node and read 32-bit value(s) from
* it. Returns 0 on success, -EINVAL if the property does not exist,
@@ -893,8 +979,8 @@ EXPORT_SYMBOL_GPL(of_property_count_strings);
* Returns the device_node pointer with refcount incremented. Use
* of_node_put() on it when done.
*/
-struct device_node *
-of_parse_phandle(struct device_node *np, const char *phandle_name, int index)
+struct device_node *of_parse_phandle(const struct device_node *np,
+ const char *phandle_name, int index)
{
const __be32 *phandle;
int size;
@@ -1169,9 +1255,9 @@ void of_attach_node(struct device_node *np)
write_lock_irqsave(&devtree_lock, flags);
np->sibling = np->parent->child;
- np->allnext = allnodes;
+ np->allnext = of_allnodes;
np->parent->child = np;
- allnodes = np;
+ of_allnodes = np;
write_unlock_irqrestore(&devtree_lock, flags);
}
@@ -1192,11 +1278,11 @@ void of_detach_node(struct device_node *np)
if (!parent)
goto out_unlock;
- if (allnodes == np)
- allnodes = np->allnext;
+ if (of_allnodes == np)
+ of_allnodes = np->allnext;
else {
struct device_node *prev;
- for (prev = allnodes;
+ for (prev = of_allnodes;
prev->allnext != np;
prev = prev->allnext)
;
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 91a375fb6ae..a65c39c473b 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -186,6 +186,8 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
*/
fpsize = 1;
allocl = 2;
+ l = 1;
+ *pathp = '\0';
} else {
/* account for '/' and path size minus terminal 0
* already in 'l'
@@ -198,10 +200,10 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
__alignof__(struct device_node));
if (allnextpp) {
+ char *fn;
memset(np, 0, sizeof(*np));
- np->full_name = ((char *)np) + sizeof(struct device_node);
+ np->full_name = fn = ((char *)np) + sizeof(*np);
if (new_format) {
- char *fn = np->full_name;
/* rebuild full path for new format */
if (dad && dad->parent) {
strcpy(fn, dad->full_name);
@@ -215,9 +217,9 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
fn += strlen(fn);
}
*(fn++) = '/';
- memcpy(fn, pathp, l);
- } else
- memcpy(np->full_name, pathp, l);
+ }
+ memcpy(fn, pathp, l);
+
prev_pp = &np->properties;
**allnextpp = np;
*allnextpp = &np->allnext;
@@ -459,7 +461,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
do {
u32 tag = be32_to_cpup((__be32 *)p);
- char *pathp;
+ const char *pathp;
p += 4;
if (tag == OF_DT_END_NODE) {
@@ -487,7 +489,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
pathp = (char *)p;
p = ALIGN(p + strlen(pathp) + 1, 4);
if ((*pathp) == '/') {
- char *lp, *np;
+ const char *lp, *np;
for (lp = NULL, np = pathp; *np; np++)
if ((*np) == '/')
lp = np+1;
@@ -710,7 +712,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
*/
void __init unflatten_device_tree(void)
{
- __unflatten_device_tree(initial_boot_params, &allnodes,
+ __unflatten_device_tree(initial_boot_params, &of_allnodes,
early_init_dt_alloc_memory_arch);
/* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
index 3550f3bf4f9..b667264222c 100644
--- a/drivers/of/of_i2c.c
+++ b/drivers/of/of_i2c.c
@@ -29,7 +29,7 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
- for_each_child_of_node(adap->dev.of_node, node) {
+ for_each_available_child_of_node(adap->dev.of_node, node) {
struct i2c_board_info info = {};
struct dev_archdata dev_ad = {};
const __be32 *addr;
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 8e6c25f3504..83ca06f4312 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -53,7 +53,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
return rc;
/* Loop over the child nodes and register a phy_device for each one */
- for_each_child_of_node(np, child) {
+ for_each_available_child_of_node(np, child) {
const __be32 *paddr;
u32 addr;
int len;
diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c
index 07cc1d678e4..37b56fd716e 100644
--- a/drivers/of/pdt.c
+++ b/drivers/of/pdt.c
@@ -241,15 +241,15 @@ void __init of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops)
BUG_ON(!ops);
of_pdt_prom_ops = ops;
- allnodes = of_pdt_create_node(root_node, NULL);
+ of_allnodes = of_pdt_create_node(root_node, NULL);
#if defined(CONFIG_SPARC)
- allnodes->path_component_name = "";
+ of_allnodes->path_component_name = "";
#endif
- allnodes->full_name = "/";
+ of_allnodes->full_name = "/";
- nextp = &allnodes->allnext;
- allnodes->child = of_pdt_build_tree(allnodes,
- of_pdt_prom_ops->getchild(allnodes->phandle), &nextp);
+ nextp = &of_allnodes->allnext;
+ of_allnodes->child = of_pdt_build_tree(of_allnodes,
+ of_pdt_prom_ops->getchild(of_allnodes->phandle), &nextp);
/* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */
of_alias_scan(kernel_tree_alloc);
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
index 4b6e4e7aca8..0e60438ebe3 100644
--- a/drivers/parport/Kconfig
+++ b/drivers/parport/Kconfig
@@ -57,8 +57,8 @@ config PARPORT_SERIAL
will be called parport_serial.
config PARPORT_PC_FIFO
- bool "Use FIFO/DMA if available (EXPERIMENTAL)"
- depends on PARPORT_PC && EXPERIMENTAL
+ bool "Use FIFO/DMA if available"
+ depends on PARPORT_PC
help
Many parallel port chipsets provide hardware that can speed up
printing. Say Y here if you want to take advantage of that.
@@ -70,8 +70,8 @@ config PARPORT_PC_FIFO
specify which IRQ/DMA to use.
config PARPORT_PC_SUPERIO
- bool "SuperIO chipset support (EXPERIMENTAL)"
- depends on PARPORT_PC && EXPERIMENTAL
+ bool "SuperIO chipset support"
+ depends on PARPORT_PC
help
Saying Y here enables some probes for Super-IO chipsets in order to
find out things like base addresses, IRQ lines and DMA channels. It
@@ -85,8 +85,8 @@ config PARPORT_PC_PCMCIA
ports. If unsure, say N.
config PARPORT_IP32
- tristate "SGI IP32 builtin port (EXPERIMENTAL)"
- depends on SGI_IP32 && EXPERIMENTAL
+ tristate "SGI IP32 builtin port"
+ depends on SGI_IP32
select PARPORT_NOT_PC
help
Say Y here if you need support for the parallel port on
@@ -126,8 +126,8 @@ config PARPORT_GSC
select PARPORT_NOT_PC
config PARPORT_SUNBPP
- tristate "Sparc hardware (EXPERIMENTAL)"
- depends on SBUS && EXPERIMENTAL
+ tristate "Sparc hardware"
+ depends on SBUS
select PARPORT_NOT_PC
help
This driver provides support for the bidirectional parallel port
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 8d688b260e2..0c3efcffa83 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -4,7 +4,7 @@
obj-y += access.o bus.o probe.o host-bridge.o remove.o pci.o \
pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \
- irq.o vpd.o
+ irq.o vpd.o setup-bus.o
obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_SYSFS) += slot.o
@@ -15,8 +15,6 @@ obj-$(CONFIG_PCIEPORTBUS) += pcie/
obj-$(CONFIG_PCI_IOAPIC) += ioapic.o
-obj-$(CONFIG_HOTPLUG) += hotplug.o
-
# Build the PCI Hotplug drivers if we were asked to
obj-$(CONFIG_HOTPLUG_PCI) += hotplug/
ifdef CONFIG_HOTPLUG_PCI
@@ -60,9 +58,6 @@ obj-$(CONFIG_ACPI) += pci-acpi.o
# SMBIOS provided firmware instance and labels
obj-$(CONFIG_PCI_LABEL) += pci-label.o
-# Cardbus & CompactPCI use setup-bus
-obj-$(CONFIG_HOTPLUG) += setup-bus.o
-
obj-$(CONFIG_PCI_SYSCALL) += syscall.o
obj-$(CONFIG_PCI_STUB) += pci-stub.o
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
deleted file mode 100644
index 2b5352a7dff..00000000000
--- a/drivers/pci/hotplug.c
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include "pci.h"
-
-int pci_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- struct pci_dev *pdev;
-
- if (!dev)
- return -ENODEV;
-
- pdev = to_pci_dev(dev);
- if (!pdev)
- return -ENODEV;
-
- if (add_uevent_var(env, "PCI_CLASS=%04X", pdev->class))
- return -ENOMEM;
-
- if (add_uevent_var(env, "PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
- return -ENOMEM;
-
- if (add_uevent_var(env, "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
- pdev->subsystem_device))
- return -ENOMEM;
-
- if (add_uevent_var(env, "PCI_SLOT_NAME=%s", pci_name(pdev)))
- return -ENOMEM;
-
- if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
- pdev->vendor, pdev->device,
- pdev->subsystem_vendor, pdev->subsystem_device,
- (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
- (u8)(pdev->class)))
- return -ENOMEM;
- return 0;
-}
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c
index 6bf8d2ab164..449b4bbc830 100644
--- a/drivers/pci/hotplug/cpcihp_zt5550.c
+++ b/drivers/pci/hotplug/cpcihp_zt5550.c
@@ -271,7 +271,7 @@ init_hc_error:
}
-static void __devexit zt5550_hc_remove_one(struct pci_dev *pdev)
+static void zt5550_hc_remove_one(struct pci_dev *pdev)
{
cpci_hp_stop();
cpci_hp_unregister_bus(bus0);
@@ -290,7 +290,7 @@ static struct pci_driver zt5550_hc_driver = {
.name = "zt5550_hc",
.id_table = zt5550_hc_pci_tbl,
.probe = zt5550_hc_init_one,
- .remove = __devexit_p(zt5550_hc_remove_one),
+ .remove = zt5550_hc_remove_one,
};
static int __init zt5550_init(void)
diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c
index 205af8dc83c..2eca902a428 100644
--- a/drivers/pci/ioapic.c
+++ b/drivers/pci/ioapic.c
@@ -27,7 +27,7 @@ struct ioapic {
u32 gsi_base;
};
-static int __devinit ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent)
{
acpi_handle handle;
acpi_status status;
@@ -88,7 +88,7 @@ exit_free:
return -ENODEV;
}
-static void __devexit ioapic_remove(struct pci_dev *dev)
+static void ioapic_remove(struct pci_dev *dev)
{
struct ioapic *ioapic = pci_get_drvdata(dev);
@@ -110,7 +110,7 @@ static struct pci_driver ioapic_driver = {
.name = "ioapic",
.id_table = ioapic_devices,
.probe = ioapic_probe,
- .remove = __devexit_p(ioapic_remove),
+ .remove = ioapic_remove,
};
static int __init ioapic_init(void)
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index c5792d622dc..1af4008182f 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -17,10 +17,9 @@
#include <linux/pci-acpi.h>
#include <linux/pm_runtime.h>
+#include <linux/pm_qos.h>
#include "pci.h"
-static DEFINE_MUTEX(pci_acpi_pm_notify_mtx);
-
/**
* pci_acpi_wake_bus - Wake-up notification handler for root buses.
* @handle: ACPI handle of a device the notification is for.
@@ -68,67 +67,6 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
}
/**
- * add_pm_notifier - Register PM notifier for given ACPI device.
- * @dev: ACPI device to add the notifier for.
- * @context: PCI device or bus to check for PME status if an event is signaled.
- *
- * NOTE: @dev need not be a run-wake or wake-up device to be a valid source of
- * PM wake-up events. For example, wake-up events may be generated for bridges
- * if one of the devices below the bridge is signaling PME, even if the bridge
- * itself doesn't have a wake-up GPE associated with it.
- */
-static acpi_status add_pm_notifier(struct acpi_device *dev,
- acpi_notify_handler handler,
- void *context)
-{
- acpi_status status = AE_ALREADY_EXISTS;
-
- mutex_lock(&pci_acpi_pm_notify_mtx);
-
- if (dev->wakeup.flags.notifier_present)
- goto out;
-
- status = acpi_install_notify_handler(dev->handle,
- ACPI_SYSTEM_NOTIFY,
- handler, context);
- if (ACPI_FAILURE(status))
- goto out;
-
- dev->wakeup.flags.notifier_present = true;
-
- out:
- mutex_unlock(&pci_acpi_pm_notify_mtx);
- return status;
-}
-
-/**
- * remove_pm_notifier - Unregister PM notifier from given ACPI device.
- * @dev: ACPI device to remove the notifier from.
- */
-static acpi_status remove_pm_notifier(struct acpi_device *dev,
- acpi_notify_handler handler)
-{
- acpi_status status = AE_BAD_PARAMETER;
-
- mutex_lock(&pci_acpi_pm_notify_mtx);
-
- if (!dev->wakeup.flags.notifier_present)
- goto out;
-
- status = acpi_remove_notify_handler(dev->handle,
- ACPI_SYSTEM_NOTIFY,
- handler);
- if (ACPI_FAILURE(status))
- goto out;
-
- dev->wakeup.flags.notifier_present = false;
-
- out:
- mutex_unlock(&pci_acpi_pm_notify_mtx);
- return status;
-}
-
-/**
* pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus.
* @dev: ACPI device to add the notifier for.
* @pci_bus: PCI bus to walk checking for PME status if an event is signaled.
@@ -136,7 +74,7 @@ static acpi_status remove_pm_notifier(struct acpi_device *dev,
acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev,
struct pci_bus *pci_bus)
{
- return add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus);
+ return acpi_add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus);
}
/**
@@ -145,7 +83,7 @@ acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev,
*/
acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
{
- return remove_pm_notifier(dev, pci_acpi_wake_bus);
+ return acpi_remove_pm_notifier(dev, pci_acpi_wake_bus);
}
/**
@@ -156,7 +94,7 @@ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
struct pci_dev *pci_dev)
{
- return add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev);
+ return acpi_add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev);
}
/**
@@ -165,7 +103,7 @@ acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
*/
acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
{
- return remove_pm_notifier(dev, pci_acpi_wake_dev);
+ return acpi_remove_pm_notifier(dev, pci_acpi_wake_dev);
}
phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
@@ -257,11 +195,16 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
return -ENODEV;
switch (state) {
+ case PCI_D3cold:
+ if (dev_pm_qos_flags(&dev->dev, PM_QOS_FLAG_NO_POWER_OFF) ==
+ PM_QOS_FLAGS_ALL) {
+ error = -EBUSY;
+ break;
+ }
case PCI_D0:
case PCI_D1:
case PCI_D2:
case PCI_D3hot:
- case PCI_D3cold:
error = acpi_bus_set_power(handle, state_conv[state]);
}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 6c94fc9489e..1dc78c5cabf 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -89,10 +89,6 @@ static void pci_free_dynids(struct pci_driver *drv)
spin_unlock(&drv->dynids.lock);
}
-/*
- * Dynamic device ID manipulation via sysfs is disabled for !CONFIG_HOTPLUG
- */
-#ifdef CONFIG_HOTPLUG
/**
* store_new_id - sysfs frontend to pci_add_dynid()
* @driver: target device driver
@@ -191,10 +187,6 @@ static struct driver_attribute pci_drv_attrs[] = {
__ATTR_NULL,
};
-#else
-#define pci_drv_attrs NULL
-#endif /* CONFIG_HOTPLUG */
-
/**
* pci_match_id - See if a pci device matches a given pci_id table
* @ids: array of PCI device id structures to search in
@@ -1223,12 +1215,38 @@ void pci_dev_put(struct pci_dev *dev)
put_device(&dev->dev);
}
-#ifndef CONFIG_HOTPLUG
-int pci_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int pci_uevent(struct device *dev, struct kobj_uevent_env *env)
{
- return -ENODEV;
+ struct pci_dev *pdev;
+
+ if (!dev)
+ return -ENODEV;
+
+ pdev = to_pci_dev(dev);
+ if (!pdev)
+ return -ENODEV;
+
+ if (add_uevent_var(env, "PCI_CLASS=%04X", pdev->class))
+ return -ENOMEM;
+
+ if (add_uevent_var(env, "PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
+ return -ENOMEM;
+
+ if (add_uevent_var(env, "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
+ pdev->subsystem_device))
+ return -ENOMEM;
+
+ if (add_uevent_var(env, "PCI_SLOT_NAME=%s", pci_name(pdev)))
+ return -ENOMEM;
+
+ if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
+ pdev->vendor, pdev->device,
+ pdev->subsystem_vendor, pdev->subsystem_device,
+ (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
+ (u8)(pdev->class)))
+ return -ENOMEM;
+ return 0;
}
-#endif
struct bus_type pci_bus_type = {
.name = "pci",
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index f39378d9da1..68d56f02e72 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -284,7 +284,6 @@ msi_bus_store(struct device *dev, struct device_attribute *attr,
return count;
}
-#ifdef CONFIG_HOTPLUG
static DEFINE_MUTEX(pci_remove_rescan_mutex);
static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf,
size_t count)
@@ -377,8 +376,6 @@ dev_bus_rescan_store(struct device *dev, struct device_attribute *attr,
return count;
}
-#endif
-
#if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI)
static ssize_t d3cold_allowed_store(struct device *dev,
struct device_attribute *attr,
@@ -424,10 +421,8 @@ struct device_attribute pci_dev_attrs[] = {
__ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
broken_parity_status_show,broken_parity_status_store),
__ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
-#ifdef CONFIG_HOTPLUG
__ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store),
__ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store),
-#endif
#if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI)
__ATTR(d3cold_allowed, 0644, d3cold_allowed_show, d3cold_allowed_store),
#endif
@@ -435,9 +430,7 @@ struct device_attribute pci_dev_attrs[] = {
};
struct device_attribute pcibus_dev_attrs[] = {
-#ifdef CONFIG_HOTPLUG
__ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_bus_rescan_store),
-#endif
__ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpumaskaffinity, NULL),
__ATTR(cpulistaffinity, S_IRUGO, pci_bus_show_cpulistaffinity, NULL),
__ATTR_NULL,
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index aabf64798bd..bdf66b500f2 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -86,7 +86,7 @@ enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_TUNE_OFF;
* the dfl or actual value as it sees fit. Don't forget this is
* measured in 32-bit words, not bytes.
*/
-u8 pci_dfl_cache_line_size __devinitdata = L1_CACHE_BYTES >> 2;
+u8 pci_dfl_cache_line_size = L1_CACHE_BYTES >> 2;
u8 pci_cache_line_size;
/*
@@ -3857,7 +3857,7 @@ static int __init pci_resource_alignment_sysfs_init(void)
late_initcall(pci_resource_alignment_sysfs_init);
-static void __devinit pci_no_domains(void)
+static void pci_no_domains(void)
{
#ifdef CONFIG_PCI_DOMAINS
pci_domains_supported = 0;
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index fd92aab9904..e253881c427 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -8,7 +8,6 @@
/* Functions internal to the PCI core code */
-extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env);
extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
#if !defined(CONFIG_DMI) && !defined(CONFIG_ACPI)
@@ -159,11 +158,7 @@ static inline int pci_no_d1d2(struct pci_dev *dev)
}
extern struct device_attribute pci_dev_attrs[];
extern struct device_attribute pcibus_dev_attrs[];
-#ifdef CONFIG_HOTPLUG
extern struct bus_attribute pci_bus_attrs[];
-#else
-#define pci_bus_attrs NULL
-#endif
/**
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 030cf12d546..76ef634caf6 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -41,7 +41,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-static int __devinit aer_probe(struct pcie_device *dev);
+static int aer_probe(struct pcie_device *dev);
static void aer_remove(struct pcie_device *dev);
static pci_ers_result_t aer_error_detected(struct pci_dev *dev,
enum pci_channel_state error);
@@ -300,7 +300,7 @@ static void aer_remove(struct pcie_device *dev)
*
* Invoked when PCI Express bus loads AER service driver.
*/
-static int __devinit aer_probe(struct pcie_device *dev)
+static int aer_probe(struct pcie_device *dev)
{
int status;
struct aer_rpc *rpc;
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 0761d90ca27..d4824cb78b4 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -182,7 +182,7 @@ static const struct pci_device_id port_runtime_pm_black_list[] = {
* this port device.
*
*/
-static int __devinit pcie_portdrv_probe(struct pci_dev *dev,
+static int pcie_portdrv_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
int status;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ec909afa90b..3683f6094e3 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -305,7 +305,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
}
}
-static void __devinit pci_read_bridge_io(struct pci_bus *child)
+static void pci_read_bridge_io(struct pci_bus *child)
{
struct pci_dev *dev = child->self;
u8 io_base_lo, io_limit_lo;
@@ -345,7 +345,7 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
}
}
-static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
+static void pci_read_bridge_mmio(struct pci_bus *child)
{
struct pci_dev *dev = child->self;
u16 mem_base_lo, mem_limit_lo;
@@ -367,7 +367,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
}
}
-static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
+static void pci_read_bridge_mmio_pref(struct pci_bus *child)
{
struct pci_dev *dev = child->self;
u16 mem_base_lo, mem_limit_lo;
@@ -417,7 +417,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
}
}
-void __devinit pci_read_bridge_bases(struct pci_bus *child)
+void pci_read_bridge_bases(struct pci_bus *child)
{
struct pci_dev *dev = child->self;
struct resource *res;
@@ -705,7 +705,7 @@ static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max)
* them, we proceed to assigning numbers to the remaining buses in
* order to avoid overlaps between old and new bus numbers.
*/
-int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
+int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
{
struct pci_bus *child;
int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
@@ -1586,7 +1586,7 @@ void pcie_bus_configure_settings(struct pci_bus *bus, u8 mpss)
}
EXPORT_SYMBOL_GPL(pcie_bus_configure_settings);
-unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
+unsigned int pci_scan_child_bus(struct pci_bus *bus)
{
unsigned int devfn, pass, max = bus->busn_res.start;
struct pci_dev *dev;
@@ -1790,7 +1790,7 @@ void pci_bus_release_busn_res(struct pci_bus *b)
res, ret ? "can not be" : "is");
}
-struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus,
+struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
struct pci_ops *ops, void *sysdata, struct list_head *resources)
{
struct pci_host_bridge_window *window;
@@ -1826,7 +1826,7 @@ struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus,
EXPORT_SYMBOL(pci_scan_root_bus);
/* Deprecated; use pci_scan_root_bus() instead */
-struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
+struct pci_bus *pci_scan_bus_parented(struct device *parent,
int bus, struct pci_ops *ops, void *sysdata)
{
LIST_HEAD(resources);
@@ -1844,7 +1844,7 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
}
EXPORT_SYMBOL(pci_scan_bus_parented);
-struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops,
+struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
void *sysdata)
{
LIST_HEAD(resources);
@@ -1864,7 +1864,6 @@ struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops,
}
EXPORT_SYMBOL(pci_scan_bus);
-#ifdef CONFIG_HOTPLUG
/**
* pci_rescan_bus_bridge_resize - scan a PCI bus for devices.
* @bridge: PCI bridge for the bus to scan
@@ -1894,7 +1893,6 @@ EXPORT_SYMBOL(pci_add_new_bus);
EXPORT_SYMBOL(pci_scan_slot);
EXPORT_SYMBOL(pci_scan_bridge);
EXPORT_SYMBOL_GPL(pci_scan_child_bus);
-#endif
static int __init pci_sort_bf_cmp(const struct device *d_a, const struct device *d_b)
{
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 7a451ff56ec..22ad3ee0cf0 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -37,7 +37,7 @@
* key system devices. For devices that need to have mmio decoding always-on,
* we need to set the dev->mmio_always_on bit.
*/
-static void __devinit quirk_mmio_always_on(struct pci_dev *dev)
+static void quirk_mmio_always_on(struct pci_dev *dev)
{
dev->mmio_always_on = 1;
}
@@ -48,7 +48,7 @@ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID,
* Mark this device with a broken_parity_status, to allow
* PCI scanning code to "skip" this now blacklisted device.
*/
-static void __devinit quirk_mellanox_tavor(struct pci_dev *dev)
+static void quirk_mellanox_tavor(struct pci_dev *dev)
{
dev->broken_parity_status = 1; /* This device gives false positives */
}
@@ -83,7 +83,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_p
This appears to be BIOS not version dependent. So presumably there is a
chipset level fix */
-static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev)
+static void quirk_isa_dma_hangs(struct pci_dev *dev)
{
if (!isa_dma_bridge_buggy) {
isa_dma_bridge_buggy=1;
@@ -106,7 +106,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_d
* Intel NM10 "TigerPoint" LPC PM1a_STS.BM_STS must be clear
* for some HT machines to use C4 w/o hanging.
*/
-static void __devinit quirk_tigerpoint_bm_sts(struct pci_dev *dev)
+static void quirk_tigerpoint_bm_sts(struct pci_dev *dev)
{
u32 pmbase;
u16 pm1a;
@@ -125,7 +125,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGP_LPC, quirk
/*
* Chipsets where PCI->PCI transfers vanish or hang
*/
-static void __devinit quirk_nopcipci(struct pci_dev *dev)
+static void quirk_nopcipci(struct pci_dev *dev)
{
if ((pci_pci_problems & PCIPCI_FAIL)==0) {
dev_info(&dev->dev, "Disabling direct PCI/PCI transfers\n");
@@ -135,7 +135,7 @@ static void __devinit quirk_nopcipci(struct pci_dev *dev)
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, quirk_nopcipci);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, quirk_nopcipci);
-static void __devinit quirk_nopciamd(struct pci_dev *dev)
+static void quirk_nopciamd(struct pci_dev *dev)
{
u8 rev;
pci_read_config_byte(dev, 0x08, &rev);
@@ -150,7 +150,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8151_0, quirk_nopci
/*
* Triton requires workarounds to be used by the drivers
*/
-static void __devinit quirk_triton(struct pci_dev *dev)
+static void quirk_triton(struct pci_dev *dev)
{
if ((pci_pci_problems&PCIPCI_TRITON)==0) {
dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
@@ -229,7 +229,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_viala
/*
* VIA Apollo VP3 needs ETBF on BT848/878
*/
-static void __devinit quirk_viaetbf(struct pci_dev *dev)
+static void quirk_viaetbf(struct pci_dev *dev)
{
if ((pci_pci_problems&PCIPCI_VIAETBF)==0) {
dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
@@ -238,7 +238,7 @@ static void __devinit quirk_viaetbf(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_viaetbf);
-static void __devinit quirk_vsfx(struct pci_dev *dev)
+static void quirk_vsfx(struct pci_dev *dev)
{
if ((pci_pci_problems&PCIPCI_VSFX)==0) {
dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
@@ -253,7 +253,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576, quirk_vsfx)
* workaround applied too
* [Info kindly provided by ALi]
*/
-static void __devinit quirk_alimagik(struct pci_dev *dev)
+static void quirk_alimagik(struct pci_dev *dev)
{
if ((pci_pci_problems&PCIPCI_ALIMAGIK)==0) {
dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
@@ -267,7 +267,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1651, quirk_alimag
* Natoma has some interesting boundary conditions with Zoran stuff
* at least
*/
-static void __devinit quirk_natoma(struct pci_dev *dev)
+static void quirk_natoma(struct pci_dev *dev)
{
if ((pci_pci_problems&PCIPCI_NATOMA)==0) {
dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
@@ -285,7 +285,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2, qu
* This chip can cause PCI parity errors if config register 0xA0 is read
* while DMAs are occurring.
*/
-static void __devinit quirk_citrine(struct pci_dev *dev)
+static void quirk_citrine(struct pci_dev *dev)
{
dev->cfg_size = 0xA0;
}
@@ -295,7 +295,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, quirk_cit
* S3 868 and 968 chips report region size equal to 32M, but they decode 64M.
* If it's needed, re-allocate the region.
*/
-static void __devinit quirk_s3_64M(struct pci_dev *dev)
+static void quirk_s3_64M(struct pci_dev *dev)
{
struct resource *r = &dev->resource[0];
@@ -313,7 +313,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M);
* BAR0 should be 8 bytes; instead, it may be set to something like 8k
* (which conflicts w/ BAR1's memory range).
*/
-static void __devinit quirk_cs5536_vsa(struct pci_dev *dev)
+static void quirk_cs5536_vsa(struct pci_dev *dev)
{
if (pci_resource_len(dev, 0) != 8) {
struct resource *res = &dev->resource[0];
@@ -324,7 +324,7 @@ static void __devinit quirk_cs5536_vsa(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, quirk_cs5536_vsa);
-static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region,
+static void quirk_io_region(struct pci_dev *dev, unsigned region,
unsigned size, int nr, const char *name)
{
region &= ~(size-1);
@@ -352,7 +352,7 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region,
* ATI Northbridge setups MCE the processor if you even
* read somewhere between 0x3b0->0x3bb or read 0x3d3
*/
-static void __devinit quirk_ati_exploding_mce(struct pci_dev *dev)
+static void quirk_ati_exploding_mce(struct pci_dev *dev)
{
dev_info(&dev->dev, "ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb\n");
/* Mae rhaid i ni beidio ag edrych ar y lleoliadiau I/O hyn */
@@ -372,7 +372,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_
* 0xE0 (64 bytes of ACPI registers)
* 0xE2 (32 bytes of SMB registers)
*/
-static void __devinit quirk_ali7101_acpi(struct pci_dev *dev)
+static void quirk_ali7101_acpi(struct pci_dev *dev)
{
u16 region;
@@ -440,7 +440,7 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int
* 0x90 (16 bytes of SMB registers)
* and a few strange programmable PIIX4 device resources.
*/
-static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
+static void quirk_piix4_acpi(struct pci_dev *dev)
{
u32 region, res_a;
@@ -489,7 +489,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3, qui
* 0x40 (128 bytes of ACPI, GPIO & TCO registers)
* 0x58 (64 bytes of GPIO I/O space)
*/
-static void __devinit quirk_ich4_lpc_acpi(struct pci_dev *dev)
+static void quirk_ich4_lpc_acpi(struct pci_dev *dev)
{
u32 region;
u8 enable;
@@ -531,7 +531,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, quirk_ich4_lpc_acpi);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, quirk_ich4_lpc_acpi);
-static void __devinit ich6_lpc_acpi_gpio(struct pci_dev *dev)
+static void ich6_lpc_acpi_gpio(struct pci_dev *dev)
{
u32 region;
u8 enable;
@@ -555,7 +555,7 @@ static void __devinit ich6_lpc_acpi_gpio(struct pci_dev *dev)
}
}
-static void __devinit ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name, int dynsize)
+static void ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name, int dynsize)
{
u32 val;
u32 size, base;
@@ -583,7 +583,7 @@ static void __devinit ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg,
dev_info(&dev->dev, "%s PIO at %04x-%04x\n", name, base, base+size-1);
}
-static void __devinit quirk_ich6_lpc(struct pci_dev *dev)
+static void quirk_ich6_lpc(struct pci_dev *dev)
{
/* Shared ACPI/GPIO decode with all ICH6+ */
ich6_lpc_acpi_gpio(dev);
@@ -595,7 +595,7 @@ static void __devinit quirk_ich6_lpc(struct pci_dev *dev)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc);
-static void __devinit ich7_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name)
+static void ich7_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name)
{
u32 val;
u32 mask, base;
@@ -619,7 +619,7 @@ static void __devinit ich7_lpc_generic_decode(struct pci_dev *dev, unsigned reg,
}
/* ICH7-10 has the same common LPC generic IO decode registers */
-static void __devinit quirk_ich7_lpc(struct pci_dev *dev)
+static void quirk_ich7_lpc(struct pci_dev *dev)
{
/* We share the common ACPI/GPIO decode with ICH6 */
ich6_lpc_acpi_gpio(dev);
@@ -648,7 +648,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_1, qui
* VIA ACPI: One IO region pointed to by longword at
* 0x48 or 0x20 (256 bytes of ACPI registers)
*/
-static void __devinit quirk_vt82c586_acpi(struct pci_dev *dev)
+static void quirk_vt82c586_acpi(struct pci_dev *dev)
{
u32 region;
@@ -666,7 +666,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt
* 0x70 (128 bytes of hardware monitoring register)
* 0x90 (16 bytes of SMB registers)
*/
-static void __devinit quirk_vt82c686_acpi(struct pci_dev *dev)
+static void quirk_vt82c686_acpi(struct pci_dev *dev)
{
u16 hm;
u32 smb;
@@ -688,7 +688,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt
* 0x88 (128 bytes of power management registers)
* 0xd0 (16 bytes of SMB registers)
*/
-static void __devinit quirk_vt8235_acpi(struct pci_dev *dev)
+static void quirk_vt8235_acpi(struct pci_dev *dev)
{
u16 pm, smb;
@@ -706,7 +706,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235
* TI XIO2000a PCIe-PCI Bridge erroneously reports it supports fast back-to-back:
* Disable fast back-to-back on the secondary bus segment
*/
-static void __devinit quirk_xio2000a(struct pci_dev *dev)
+static void quirk_xio2000a(struct pci_dev *dev)
{
struct pci_dev *pdev;
u16 command;
@@ -780,7 +780,7 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk
* noapic specified. For the moment we assume it's the erratum. We may be wrong
* of course. However the advice is demonstrably good even if so..
*/
-static void __devinit quirk_amd_ioapic(struct pci_dev *dev)
+static void quirk_amd_ioapic(struct pci_dev *dev)
{
if (dev->revision >= 0x02) {
dev_warn(&dev->dev, "I/O APIC: AMD Erratum #22 may be present. In the event of instability try\n");
@@ -789,7 +789,7 @@ static void __devinit quirk_amd_ioapic(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, quirk_amd_ioapic);
-static void __devinit quirk_ioapic_rmw(struct pci_dev *dev)
+static void quirk_ioapic_rmw(struct pci_dev *dev)
{
if (dev->devfn == 0 && dev->bus->number == 0)
sis_apic_bug = 1;
@@ -801,7 +801,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw);
* Some settings of MMRBC can lead to data corruption so block changes.
* See AMD 8131 HyperTransport PCI-X Tunnel Revision Guide
*/
-static void __devinit quirk_amd_8131_mmrbc(struct pci_dev *dev)
+static void quirk_amd_8131_mmrbc(struct pci_dev *dev)
{
if (dev->subordinate && dev->revision <= 0x12) {
dev_info(&dev->dev, "AMD8131 rev %x detected; "
@@ -819,7 +819,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_
* value of the ACPI SCI interrupt is only done for convenience.
* -jgarzik
*/
-static void __devinit quirk_via_acpi(struct pci_dev *d)
+static void quirk_via_acpi(struct pci_dev *d)
{
/*
* VIA ACPI device: SCI IRQ line in PCI config byte 0x42
@@ -926,7 +926,7 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_vlink);
* We need to switch it off to be able to recognize the real
* type of the chip.
*/
-static void __devinit quirk_vt82c598_id(struct pci_dev *dev)
+static void quirk_vt82c598_id(struct pci_dev *dev)
{
pci_write_config_byte(dev, 0xfc, 0);
pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);
@@ -978,7 +978,7 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C
* assigned to it. We force a larger allocation to ensure that
* nothing gets put too close to it.
*/
-static void __devinit quirk_dunord ( struct pci_dev * dev )
+static void quirk_dunord(struct pci_dev *dev)
{
struct resource *r = &dev->resource [1];
r->start = 0;
@@ -992,7 +992,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DUNORD, PCI_DEVICE_ID_DUNORD_I3000, quirk
* in the ProgIf. Unfortunately, the ProgIf value is wrong - 0x80
* instead of 0x01.
*/
-static void __devinit quirk_transparent_bridge(struct pci_dev *dev)
+static void quirk_transparent_bridge(struct pci_dev *dev)
{
dev->transparent = 1;
}
@@ -1066,7 +1066,7 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA
/*
* Serverworks CSB5 IDE does not fully support native mode
*/
-static void __devinit quirk_svwks_csb5ide(struct pci_dev *pdev)
+static void quirk_svwks_csb5ide(struct pci_dev *pdev)
{
u8 prog;
pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
@@ -1082,7 +1082,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB
/*
* Intel 82801CAM ICH3-M datasheet says IDE modes must be the same
*/
-static void __devinit quirk_ide_samemode(struct pci_dev *pdev)
+static void quirk_ide_samemode(struct pci_dev *pdev)
{
u8 prog;
@@ -1101,7 +1101,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, qui
* Some ATA devices break if put into D3
*/
-static void __devinit quirk_no_ata_d3(struct pci_dev *pdev)
+static void quirk_no_ata_d3(struct pci_dev *pdev)
{
pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3;
}
@@ -1121,7 +1121,7 @@ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_VIA, PCI_ANY_ID,
/* This was originally an Alpha specific thing, but it really fits here.
* The i82375 PCI/EISA bridge appears as non-classified. Fix that.
*/
-static void __devinit quirk_eisa_bridge(struct pci_dev *dev)
+static void quirk_eisa_bridge(struct pci_dev *dev)
{
dev->class = PCI_CLASS_BRIDGE_EISA << 8;
}
@@ -1155,7 +1155,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_e
*/
static int asus_hides_smbus;
-static void __devinit asus_hides_smbus_hostbridge(struct pci_dev *dev)
+static void asus_hides_smbus_hostbridge(struct pci_dev *dev)
{
if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK)) {
if (dev->device == PCI_DEVICE_ID_INTEL_82845_HB)
@@ -1538,7 +1538,7 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB3
#endif
#ifdef CONFIG_X86_IO_APIC
-static void __devinit quirk_alder_ioapic(struct pci_dev *pdev)
+static void quirk_alder_ioapic(struct pci_dev *pdev)
{
int i;
@@ -1561,7 +1561,7 @@ static void __devinit quirk_alder_ioapic(struct pci_dev *pdev)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic);
#endif
-static void __devinit quirk_pcie_mch(struct pci_dev *pdev)
+static void quirk_pcie_mch(struct pci_dev *pdev)
{
pci_msi_off(pdev);
pdev->no_msi = 1;
@@ -1575,7 +1575,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quir
* It's possible for the MSI to get corrupted if shpc and acpi
* are used together on certain PXH-based systems.
*/
-static void __devinit quirk_pcie_pxh(struct pci_dev *dev)
+static void quirk_pcie_pxh(struct pci_dev *dev)
{
pci_msi_off(dev);
dev->no_msi = 1;
@@ -1777,7 +1777,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS, qui
* but the PIO transfers won't work if BAR0 falls at the odd 8 bytes.
* Re-allocate the region if needed...
*/
-static void __devinit quirk_tc86c001_ide(struct pci_dev *dev)
+static void quirk_tc86c001_ide(struct pci_dev *dev)
{
struct resource *r = &dev->resource[0];
@@ -1790,7 +1790,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA_2,
PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE,
quirk_tc86c001_ide);
-static void __devinit quirk_netmos(struct pci_dev *dev)
+static void quirk_netmos(struct pci_dev *dev)
{
unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4;
unsigned int num_serial = dev->subsystem_device & 0xf;
@@ -1828,7 +1828,7 @@ static void __devinit quirk_netmos(struct pci_dev *dev)
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID,
PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos);
-static void __devinit quirk_e100_interrupt(struct pci_dev *dev)
+static void quirk_e100_interrupt(struct pci_dev *dev)
{
u16 command, pmcsr;
u8 __iomem *csr;
@@ -1901,7 +1901,7 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
* The 82575 and 82598 may experience data corruption issues when transitioning
* out of L0S. To prevent this we need to disable L0S on the pci-e link
*/
-static void __devinit quirk_disable_aspm_l0s(struct pci_dev *dev)
+static void quirk_disable_aspm_l0s(struct pci_dev *dev)
{
dev_info(&dev->dev, "Disabling L0s\n");
pci_disable_link_state(dev, PCIE_LINK_STATE_L0S);
@@ -1921,7 +1921,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f1, quirk_disable_aspm_l0s);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s);
-static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
+static void fixup_rev1_53c810(struct pci_dev *dev)
{
/* rev 1 ncr53c810 chips don't set the class at all which means
* they don't get their resources remapped. Fix that here.
@@ -1935,7 +1935,7 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
/* Enable 1k I/O space granularity on the Intel P64H2 */
-static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
+static void quirk_p64h2_1k_io(struct pci_dev *dev)
{
u16 en1k;
@@ -1968,7 +1968,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
quirk_nvidia_ck804_pcie_aer_ext_cap);
-static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
+static void quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
{
/*
* Disable PCI Bus Parking and PCI Master read caching on CX700
@@ -2031,7 +2031,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_c
* We believe that it is legal to read beyond the end tag and
* therefore the solution is to limit the read/write length.
*/
-static void __devinit quirk_brcm_570x_limit_vpd(struct pci_dev *dev)
+static void quirk_brcm_570x_limit_vpd(struct pci_dev *dev)
{
/*
* Only disable the VPD capability for 5706, 5706S, 5708,
@@ -2091,7 +2091,7 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_BROADCOM,
* the DRBs - this is where we expose device 6.
* http://www.x86-secret.com/articles/tweak/pat/patsecrets-2.htm
*/
-static void __devinit quirk_unhide_mch_dev6(struct pci_dev *dev)
+static void quirk_unhide_mch_dev6(struct pci_dev *dev)
{
u8 reg;
@@ -2115,7 +2115,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB,
* supports link speed auto negotiation, but falsely sets
* the link speed to 5GT/s.
*/
-static void __devinit quirk_tile_plx_gen1(struct pci_dev *dev)
+static void quirk_tile_plx_gen1(struct pci_dev *dev)
{
if (tile_plx_gen1) {
pci_write_config_dword(dev, 0x98, 0x1);
@@ -2132,7 +2132,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8624, quirk_tile_plx_gen1);
* aware of it. Instead of setting the flag on all busses in the
* machine, simply disable MSI globally.
*/
-static void __devinit quirk_disable_all_msi(struct pci_dev *dev)
+static void quirk_disable_all_msi(struct pci_dev *dev)
{
pci_no_msi();
dev_warn(&dev->dev, "MSI quirk detected; MSI disabled\n");
@@ -2146,7 +2146,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3364, quirk_disab
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8380_0, quirk_disable_all_msi);
/* Disable MSI on chipsets that are known to not support it */
-static void __devinit quirk_disable_msi(struct pci_dev *dev)
+static void quirk_disable_msi(struct pci_dev *dev)
{
if (dev->subordinate) {
dev_warn(&dev->dev, "MSI quirk detected; "
@@ -2164,7 +2164,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x5a3f, quirk_disable_msi);
* we use the possible vendor/device IDs of the host bridge for the
* declared quirk, and search for the APC bridge by slot number.
*/
-static void __devinit quirk_amd_780_apc_msi(struct pci_dev *host_bridge)
+static void quirk_amd_780_apc_msi(struct pci_dev *host_bridge)
{
struct pci_dev *apc_bridge;
@@ -2272,7 +2272,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE,
* for the MCP55 NIC. It is not yet determined whether the msi problem
* also affects other devices. As for now, turn off msi for this device.
*/
-static void __devinit nvenet_msi_disable(struct pci_dev *dev)
+static void nvenet_msi_disable(struct pci_dev *dev)
{
const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
@@ -2298,7 +2298,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA,
* we have it set correctly.
* Note this is an undocumented register.
*/
-static void __devinit nvbridge_check_legacy_irq_routing(struct pci_dev *dev)
+static void nvbridge_check_legacy_irq_routing(struct pci_dev *dev)
{
u32 cfg;
@@ -2534,11 +2534,11 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_q
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk_all);
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk_all);
-static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
+static void quirk_msi_intx_disable_bug(struct pci_dev *dev)
{
dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG;
}
-static void __devinit quirk_msi_intx_disable_ati_bug(struct pci_dev *dev)
+static void quirk_msi_intx_disable_ati_bug(struct pci_dev *dev)
{
struct pci_dev *p;
@@ -2612,7 +2612,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1083,
* kernel fails to allocate resources when hotplug device is
* inserted and PCI bus is rescanned.
*/
-static void __devinit quirk_hotplug_bridge(struct pci_dev *dev)
+static void quirk_hotplug_bridge(struct pci_dev *dev)
{
dev->is_hotplug_bridge = 1;
}
@@ -2752,7 +2752,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, vtd_mask_spec_errors);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors);
#endif
-static void __devinit fixup_ti816x_class(struct pci_dev* dev)
+static void fixup_ti816x_class(struct pci_dev *dev)
{
/* TI 816x devices do not have class code set when in PCIe boot mode */
dev_info(&dev->dev, "Setting PCI class for 816x PCIe device\n");
@@ -2764,7 +2764,7 @@ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_TI, 0xb800,
/* Some PCIe devices do not work reliably with the claimed maximum
* payload size supported.
*/
-static void __devinit fixup_mpss_256(struct pci_dev *dev)
+static void fixup_mpss_256(struct pci_dev *dev)
{
dev->pcie_mpss = 1; /* 256 bytes */
}
@@ -2782,7 +2782,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SOLARFLARE,
* coalescing must be disabled. Unfortunately, it cannot be re-enabled because
* it is possible to hotplug a device with MPS of 256B.
*/
-static void __devinit quirk_intel_mc_errata(struct pci_dev *dev)
+static void quirk_intel_mc_errata(struct pci_dev *dev)
{
int err;
u16 rcc;
@@ -2888,7 +2888,7 @@ static void fixup_debug_report(struct pci_dev *dev, ktime_t calltime,
* This resolves crashes often seen on monitor unplug.
*/
#define I915_DEIER_REG 0x4400c
-static void __devinit disable_igfx_irq(struct pci_dev *dev)
+static void disable_igfx_irq(struct pci_dev *dev)
{
void __iomem *regs = pci_iomap(dev, 0, 0);
if (regs == NULL) {
@@ -2914,7 +2914,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq);
* PCI_COMMAND_INTX_DISABLE works though they actually do not properly
* support this feature.
*/
-static void __devinit quirk_broken_intx_masking(struct pci_dev *dev)
+static void quirk_broken_intx_masking(struct pci_dev *dev)
{
dev->broken_intx_masking = 1;
}
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index 0aab85a5155..db542f4196a 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -412,7 +412,7 @@ static int pcifront_claim_resource(struct pci_dev *dev, void *data)
return 0;
}
-static int __devinit pcifront_scan_bus(struct pcifront_device *pdev,
+static int pcifront_scan_bus(struct pcifront_device *pdev,
unsigned int domain, unsigned int bus,
struct pci_bus *b)
{
@@ -441,7 +441,7 @@ static int __devinit pcifront_scan_bus(struct pcifront_device *pdev,
return 0;
}
-static int __devinit pcifront_scan_root(struct pcifront_device *pdev,
+static int pcifront_scan_root(struct pcifront_device *pdev,
unsigned int domain, unsigned int bus)
{
struct pci_bus *b;
@@ -503,7 +503,7 @@ err_out:
return err;
}
-static int __devinit pcifront_rescan_root(struct pcifront_device *pdev,
+static int pcifront_rescan_root(struct pcifront_device *pdev,
unsigned int domain, unsigned int bus)
{
int err;
@@ -834,7 +834,7 @@ out:
return err;
}
-static int __devinit pcifront_try_connect(struct pcifront_device *pdev)
+static int pcifront_try_connect(struct pcifront_device *pdev)
{
int err = -EFAULT;
int i, num_roots, len;
@@ -924,7 +924,7 @@ out:
return err;
}
-static int __devinit pcifront_attach_devices(struct pcifront_device *pdev)
+static int pcifront_attach_devices(struct pcifront_device *pdev)
{
int err = -EFAULT;
int i, num_roots, len;
diff --git a/drivers/pcmcia/bcm63xx_pcmcia.c b/drivers/pcmcia/bcm63xx_pcmcia.c
index c2e997a570b..0c6aac1232f 100644
--- a/drivers/pcmcia/bcm63xx_pcmcia.c
+++ b/drivers/pcmcia/bcm63xx_pcmcia.c
@@ -323,7 +323,7 @@ static struct pccard_operations bcm63xx_pcmcia_operations = {
/*
* register pcmcia socket to core
*/
-static int __devinit bcm63xx_drv_pcmcia_probe(struct platform_device *pdev)
+static int bcm63xx_drv_pcmcia_probe(struct platform_device *pdev)
{
struct bcm63xx_pcmcia_socket *skt;
struct pcmcia_socket *sock;
@@ -436,7 +436,7 @@ err:
return ret;
}
-static int __devexit bcm63xx_drv_pcmcia_remove(struct platform_device *pdev)
+static int bcm63xx_drv_pcmcia_remove(struct platform_device *pdev)
{
struct bcm63xx_pcmcia_socket *skt;
struct resource *res;
@@ -453,7 +453,7 @@ static int __devexit bcm63xx_drv_pcmcia_remove(struct platform_device *pdev)
struct platform_driver bcm63xx_pcmcia_driver = {
.probe = bcm63xx_drv_pcmcia_probe,
- .remove = __devexit_p(bcm63xx_drv_pcmcia_remove),
+ .remove = bcm63xx_drv_pcmcia_remove,
.driver = {
.name = "bcm63xx_pcmcia",
.owner = THIS_MODULE,
@@ -461,7 +461,7 @@ struct platform_driver bcm63xx_pcmcia_driver = {
};
#ifdef CONFIG_CARDBUS
-static int __devinit bcm63xx_cb_probe(struct pci_dev *dev,
+static int bcm63xx_cb_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
/* keep pci device */
@@ -469,7 +469,7 @@ static int __devinit bcm63xx_cb_probe(struct pci_dev *dev,
return platform_driver_register(&bcm63xx_pcmcia_driver);
}
-static void __devexit bcm63xx_cb_exit(struct pci_dev *dev)
+static void bcm63xx_cb_exit(struct pci_dev *dev)
{
platform_driver_unregister(&bcm63xx_pcmcia_driver);
bcm63xx_cb_dev = NULL;
@@ -503,7 +503,7 @@ static struct pci_driver bcm63xx_cardbus_driver = {
.name = "bcm63xx_cardbus",
.id_table = bcm63xx_cb_table,
.probe = bcm63xx_cb_probe,
- .remove = __devexit_p(bcm63xx_cb_exit),
+ .remove = bcm63xx_cb_exit,
};
#endif
diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c
index ac1a2232eab..ed3b522601b 100644
--- a/drivers/pcmcia/bfin_cf_pcmcia.c
+++ b/drivers/pcmcia/bfin_cf_pcmcia.c
@@ -195,7 +195,7 @@ static struct pccard_operations bfin_cf_ops = {
/*--------------------------------------------------------------------------*/
-static int __devinit bfin_cf_probe(struct platform_device *pdev)
+static int bfin_cf_probe(struct platform_device *pdev)
{
struct bfin_cf_socket *cf;
struct resource *io_mem, *attr_mem;
@@ -286,7 +286,7 @@ fail0:
return status;
}
-static int __devexit bfin_cf_remove(struct platform_device *pdev)
+static int bfin_cf_remove(struct platform_device *pdev)
{
struct bfin_cf_socket *cf = platform_get_drvdata(pdev);
@@ -307,7 +307,7 @@ static struct platform_driver bfin_cf_driver = {
.owner = THIS_MODULE,
},
.probe = bfin_cf_probe,
- .remove = __devexit_p(bfin_cf_remove),
+ .remove = bfin_cf_remove,
};
module_platform_driver(bfin_cf_driver);
diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c
index a484b1fb338..a31e69ea99f 100644
--- a/drivers/pcmcia/db1xxx_ss.c
+++ b/drivers/pcmcia/db1xxx_ss.c
@@ -409,7 +409,7 @@ static struct pccard_operations db1x_pcmcia_operations = {
.set_mem_map = au1x00_pcmcia_set_mem_map,
};
-static int __devinit db1x_pcmcia_socket_probe(struct platform_device *pdev)
+static int db1x_pcmcia_socket_probe(struct platform_device *pdev)
{
struct db1x_pcmcia_sock *sock;
struct resource *r;
@@ -559,7 +559,7 @@ out0:
return ret;
}
-static int __devexit db1x_pcmcia_socket_remove(struct platform_device *pdev)
+static int db1x_pcmcia_socket_remove(struct platform_device *pdev)
{
struct db1x_pcmcia_sock *sock = platform_get_drvdata(pdev);
@@ -577,7 +577,7 @@ static struct platform_driver db1x_pcmcia_socket_driver = {
.owner = THIS_MODULE,
},
.probe = db1x_pcmcia_socket_probe,
- .remove = __devexit_p(db1x_pcmcia_socket_remove),
+ .remove = db1x_pcmcia_socket_remove,
};
module_platform_driver(db1x_pcmcia_socket_driver);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 079629bff95..2deacbb2ffd 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -920,8 +920,6 @@ static int pcmcia_bus_match(struct device *dev, struct device_driver *drv)
return 0;
}
-#ifdef CONFIG_HOTPLUG
-
static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct pcmcia_device *p_dev;
@@ -962,15 +960,6 @@ static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
return 0;
}
-#else
-
-static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- return -ENODEV;
-}
-
-#endif
-
/************************ runtime PM support ***************************/
static int pcmcia_dev_suspend(struct device *dev, pm_message_t state);
@@ -1329,7 +1318,7 @@ static struct pcmcia_callback pcmcia_bus_callback = {
.resume = pcmcia_bus_resume,
};
-static int __devinit pcmcia_bus_add_socket(struct device *dev,
+static int pcmcia_bus_add_socket(struct device *dev,
struct class_interface *class_intf)
{
struct pcmcia_socket *socket = dev_get_drvdata(dev);
diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c
index 7647d232e9e..a007321ad31 100644
--- a/drivers/pcmcia/electra_cf.c
+++ b/drivers/pcmcia/electra_cf.c
@@ -181,7 +181,7 @@ static struct pccard_operations electra_cf_ops = {
.set_mem_map = electra_cf_set_mem_map,
};
-static int __devinit electra_cf_probe(struct platform_device *ofdev)
+static int electra_cf_probe(struct platform_device *ofdev)
{
struct device *device = &ofdev->dev;
struct device_node *np = ofdev->dev.of_node;
@@ -324,7 +324,7 @@ fail1:
}
-static int __devexit electra_cf_remove(struct platform_device *ofdev)
+static int electra_cf_remove(struct platform_device *ofdev)
{
struct device *device = &ofdev->dev;
struct electra_cf_socket *cf;
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index 4e8831bdb6e..3578e1ca97a 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -35,7 +35,7 @@ static struct pci_driver i82092aa_pci_driver = {
.name = "i82092aa",
.id_table = i82092aa_pci_ids,
.probe = i82092aa_pci_probe,
- .remove = __devexit_p(i82092aa_pci_remove),
+ .remove = i82092aa_pci_remove,
};
@@ -67,7 +67,7 @@ static struct socket_info sockets[MAX_SOCKETS];
static int socket_count; /* shortcut */
-static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static int i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
unsigned char configbyte;
int i, ret;
@@ -162,7 +162,7 @@ err_out_disable:
return ret;
}
-static void __devexit i82092aa_pci_remove(struct pci_dev *dev)
+static void i82092aa_pci_remove(struct pci_dev *dev)
{
struct pcmcia_socket *socket = pci_get_drvdata(dev);
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index 253e3867dec..b29d97e170a 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -589,7 +589,7 @@ static int pd6729_check_irq(int irq)
return 0;
}
-static u_int __devinit pd6729_isa_scan(void)
+static u_int pd6729_isa_scan(void)
{
u_int mask0, mask = 0;
int i;
@@ -620,7 +620,7 @@ static u_int __devinit pd6729_isa_scan(void)
return mask;
}
-static int __devinit pd6729_pci_probe(struct pci_dev *dev,
+static int pd6729_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
int i, j, ret;
@@ -739,7 +739,7 @@ err_out_free_mem:
return ret;
}
-static void __devexit pd6729_pci_remove(struct pci_dev *dev)
+static void pd6729_pci_remove(struct pci_dev *dev)
{
int i;
struct pd6729_socket *socket = pci_get_drvdata(dev);
@@ -772,7 +772,7 @@ static struct pci_driver pd6729_pci_driver = {
.name = "pd6729",
.id_table = pd6729_pci_ids,
.probe = pd6729_pci_probe,
- .remove = __devexit_p(pd6729_pci_remove),
+ .remove = pd6729_pci_remove,
};
static int pd6729_module_init(void)
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index 7dd879ce514..89ebd8c7663 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -208,7 +208,7 @@ static struct pcmcia_low_level sharpsl_pcmcia_ops = {
#ifdef CONFIG_SA1100_COLLIE
#include "sa11xx_base.h"
-int __devinit pcmcia_collie_init(struct device *dev)
+int pcmcia_collie_init(struct device *dev)
{
int ret = -ENODEV;
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 9da9656242a..430a9ac5609 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -1199,7 +1199,7 @@ static const struct attribute_group rsrc_attributes = {
.attrs = pccard_rsrc_attributes,
};
-static int __devinit pccard_sysfs_add_rsrc(struct device *dev,
+static int pccard_sysfs_add_rsrc(struct device *dev,
struct class_interface *class_intf)
{
struct pcmcia_socket *s = dev_get_drvdata(dev);
@@ -1209,7 +1209,7 @@ static int __devinit pccard_sysfs_add_rsrc(struct device *dev,
return sysfs_create_group(&dev->kobj, &rsrc_attributes);
}
-static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
+static void pccard_sysfs_remove_rsrc(struct device *dev,
struct class_interface *class_intf)
{
struct pcmcia_socket *s = dev_get_drvdata(dev);
@@ -1222,7 +1222,7 @@ static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
static struct class_interface pccard_rsrc_interface __refdata = {
.class = &pcmcia_socket_class,
.add_dev = &pccard_sysfs_add_rsrc,
- .remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc),
+ .remove_dev = &pccard_sysfs_remove_rsrc,
};
static int __init nonstatic_sysfs_init(void)
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
index ba8557eea61..44cfc4416e5 100644
--- a/drivers/pcmcia/sa1100_assabet.c
+++ b/drivers/pcmcia/sa1100_assabet.c
@@ -95,7 +95,7 @@ static struct pcmcia_low_level assabet_pcmcia_ops = {
.socket_suspend = assabet_pcmcia_socket_suspend,
};
-int __devinit pcmcia_assabet_init(struct device *dev)
+int pcmcia_assabet_init(struct device *dev)
{
int ret = -ENODEV;
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c
index c59c44921a3..b3774e5d039 100644
--- a/drivers/pcmcia/sa1100_cerf.c
+++ b/drivers/pcmcia/sa1100_cerf.c
@@ -81,7 +81,7 @@ static struct pcmcia_low_level cerf_pcmcia_ops = {
.configure_socket = cerf_pcmcia_configure_socket,
};
-int __devinit pcmcia_cerf_init(struct device *dev)
+int pcmcia_cerf_init(struct device *dev)
{
int ret = -ENODEV;
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 2eea664bc07..ff8a027a4af 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -43,7 +43,7 @@
int __init pcmcia_collie_init(struct device *dev);
-static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) __devinitdata = {
+static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
#ifdef CONFIG_SA1100_ASSABET
pcmcia_assabet_init,
#endif
@@ -67,7 +67,7 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) __devinitdata = {
#endif
};
-static int __devinit sa11x0_drv_pcmcia_probe(struct platform_device *dev)
+static int sa11x0_drv_pcmcia_probe(struct platform_device *dev)
{
int i, ret = -ENODEV;
diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c
index d9c7337b909..431d8b07cba 100644
--- a/drivers/pcmcia/sa1100_h3600.c
+++ b/drivers/pcmcia/sa1100_h3600.c
@@ -153,7 +153,7 @@ struct pcmcia_low_level h3600_pcmcia_ops = {
.socket_suspend = h3600_pcmcia_socket_suspend,
};
-int __devinit pcmcia_h3600_init(struct device *dev)
+int pcmcia_h3600_init(struct device *dev)
{
int ret = -ENODEV;
diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c
index 56ab7391560..b07a2dc3296 100644
--- a/drivers/pcmcia/sa1100_shannon.c
+++ b/drivers/pcmcia/sa1100_shannon.c
@@ -92,7 +92,7 @@ static struct pcmcia_low_level shannon_pcmcia_ops = {
.configure_socket = shannon_pcmcia_configure_socket,
};
-int __devinit pcmcia_shannon_init(struct device *dev)
+int pcmcia_shannon_init(struct device *dev)
{
int ret = -ENODEV;
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
index 8647b17c449..73fd37968b6 100644
--- a/drivers/pcmcia/sa1100_simpad.c
+++ b/drivers/pcmcia/sa1100_simpad.c
@@ -109,7 +109,7 @@ static struct pcmcia_low_level simpad_pcmcia_ops = {
.socket_suspend = simpad_pcmcia_socket_suspend,
};
-int __devinit pcmcia_simpad_init(struct device *dev)
+int pcmcia_simpad_init(struct device *dev)
{
int ret = -ENODEV;
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
index 70f728ce185..65b02c3e14c 100644
--- a/drivers/pcmcia/sa1111_generic.c
+++ b/drivers/pcmcia/sa1111_generic.c
@@ -211,7 +211,7 @@ static int pcmcia_probe(struct sa1111_dev *dev)
return 0;
}
-static int __devexit pcmcia_remove(struct sa1111_dev *dev)
+static int pcmcia_remove(struct sa1111_dev *dev)
{
struct sa1111_pcmcia_socket *next, *s = dev_get_drvdata(&dev->dev);
@@ -234,7 +234,7 @@ static struct sa1111_driver pcmcia_driver = {
},
.devid = SA1111_DEVID_PCMCIA,
.probe = pcmcia_probe,
- .remove = __devexit_p(pcmcia_remove),
+ .remove = pcmcia_remove,
};
static int __init sa1111_drv_pcmcia_init(void)
diff --git a/drivers/pcmcia/sa1111_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c
index 69428d1f5ae..3baa3ef0968 100644
--- a/drivers/pcmcia/sa1111_jornada720.c
+++ b/drivers/pcmcia/sa1111_jornada720.c
@@ -91,7 +91,7 @@ static struct pcmcia_low_level jornada720_pcmcia_ops = {
.nr = 2,
};
-int __devinit pcmcia_jornada720_init(struct device *dev)
+int pcmcia_jornada720_init(struct device *dev)
{
int ret = -ENODEV;
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index 86e4a1a3c64..75806be344e 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -564,7 +564,7 @@ static inline void reserve_using_irq(int slot)
vrc4171_irq_mask &= ~(1 << irq);
}
-static int __devinit vrc4171_add_sockets(void)
+static int vrc4171_add_sockets(void)
{
vrc4171_socket_t *socket;
int slot, retval;
@@ -631,7 +631,7 @@ static void vrc4171_remove_sockets(void)
}
}
-static int __devinit vrc4171_card_setup(char *options)
+static int vrc4171_card_setup(char *options)
{
if (options == NULL || *options == '\0')
return 1;
@@ -712,7 +712,7 @@ static struct platform_driver vrc4171_card_driver = {
},
};
-static int __devinit vrc4171_card_init(void)
+static int vrc4171_card_init(void)
{
int retval;
@@ -746,7 +746,7 @@ static int __devinit vrc4171_card_init(void)
return 0;
}
-static void __devexit vrc4171_card_exit(void)
+static void vrc4171_card_exit(void)
{
free_irq(vrc4171_irq, vrc4171_sockets);
vrc4171_remove_sockets();
diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c
index cd0a315d922..d92692056e2 100644
--- a/drivers/pcmcia/vrc4173_cardu.c
+++ b/drivers/pcmcia/vrc4173_cardu.c
@@ -456,7 +456,7 @@ static void cardu_interrupt(int irq, void *dev_id)
}
}
-static int __devinit vrc4173_cardu_probe(struct pci_dev *dev,
+static int vrc4173_cardu_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
vrc4173_socket_t *socket;
@@ -533,7 +533,7 @@ disable:
return ret;
}
-static int __devinit vrc4173_cardu_setup(char *options)
+static int vrc4173_cardu_setup(char *options)
{
if (options == NULL || *options == '\0')
return 1;
@@ -574,14 +574,14 @@ static struct pci_driver vrc4173_cardu_driver = {
.id_table = vrc4173_cardu_id_table,
};
-static int __devinit vrc4173_cardu_init(void)
+static int vrc4173_cardu_init(void)
{
vrc4173_cardu_slots = 0;
return pci_register_driver(&vrc4173_cardu_driver);
}
-static void __devexit vrc4173_cardu_exit(void)
+static void vrc4173_cardu_exit(void)
{
pci_unregister_driver(&vrc4173_cardu_driver);
}
diff --git a/drivers/pcmcia/xxs1500_ss.c b/drivers/pcmcia/xxs1500_ss.c
index fd5fbd10aad..95f5b270ad4 100644
--- a/drivers/pcmcia/xxs1500_ss.c
+++ b/drivers/pcmcia/xxs1500_ss.c
@@ -204,7 +204,7 @@ static struct pccard_operations xxs1500_pcmcia_operations = {
.set_mem_map = au1x00_pcmcia_set_mem_map,
};
-static int __devinit xxs1500_pcmcia_probe(struct platform_device *pdev)
+static int xxs1500_pcmcia_probe(struct platform_device *pdev)
{
struct xxs1500_pcmcia_sock *sock;
struct resource *r;
@@ -299,7 +299,7 @@ out0:
return ret;
}
-static int __devexit xxs1500_pcmcia_remove(struct platform_device *pdev)
+static int xxs1500_pcmcia_remove(struct platform_device *pdev)
{
struct xxs1500_pcmcia_sock *sock = platform_get_drvdata(pdev);
@@ -317,7 +317,7 @@ static struct platform_driver xxs1500_pcmcia_socket_driver = {
.owner = THIS_MODULE,
},
.probe = xxs1500_pcmcia_probe,
- .remove = __devexit_p(xxs1500_pcmcia_remove),
+ .remove = xxs1500_pcmcia_remove,
};
module_platform_driver(xxs1500_pcmcia_socket_driver);
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 667678db115..6b4ff099fb1 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -783,7 +783,7 @@ static void yenta_free_resources(struct yenta_socket *socket)
/*
* Close it down - release our resources and go home..
*/
-static void __devexit yenta_close(struct pci_dev *dev)
+static void yenta_close(struct pci_dev *dev)
{
struct yenta_socket *sock = pci_get_drvdata(dev);
@@ -1142,7 +1142,7 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge)
* interrupt, and that we can map the cardbus area. Fill in the
* socket information structure..
*/
-static int __devinit yenta_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static int yenta_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct yenta_socket *socket;
int ret;
@@ -1435,7 +1435,7 @@ static struct pci_driver yenta_cardbus_driver = {
.name = "yenta_cardbus",
.id_table = yenta_table,
.probe = yenta_probe,
- .remove = __devexit_p(yenta_close),
+ .remove = yenta_close,
.driver.pm = YENTA_PM_OPS,
};
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index d96caefd914..390ab69ea56 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -26,6 +26,15 @@ config DEBUG_PINCTRL
help
Say Y here to add some extra checks and diagnostics to PINCTRL calls.
+config PINCTRL_AT91
+ bool "AT91 pinctrl driver"
+ depends on OF
+ depends on ARCH_AT91
+ select PINMUX
+ select PINCONF
+ help
+ Say Y here to enable the at91 pinctrl driver
+
config PINCTRL_BCM2835
bool
select PINMUX
@@ -87,21 +96,18 @@ config PINCTRL_MMP2
bool "MMP2 pin controller driver"
depends on ARCH_MMP
select PINCTRL_PXA3xx
- select PINCONF
config PINCTRL_MXS
bool
+ select PINMUX
+ select PINCONF
config PINCTRL_IMX23
bool
- select PINMUX
- select PINCONF
select PINCTRL_MXS
config PINCTRL_IMX28
bool
- select PINMUX
- select PINCONF
select PINCTRL_MXS
config PINCTRL_NOMADIK
@@ -126,13 +132,11 @@ config PINCTRL_PXA168
bool "PXA168 pin controller driver"
depends on ARCH_MMP
select PINCTRL_PXA3xx
- select PINCONF
config PINCTRL_PXA910
bool "PXA910 pin controller driver"
depends on ARCH_MMP
select PINCTRL_PXA3xx
- select PINCONF
config PINCTRL_SINGLE
tristate "One-register-per-pin type device tree based pinctrl driver"
@@ -143,23 +147,21 @@ config PINCTRL_SINGLE
This selects the device tree based generic pinctrl driver.
config PINCTRL_SIRF
- bool "CSR SiRFprimaII pin controller driver"
- depends on ARCH_PRIMA2
+ bool "CSR SiRFprimaII/SiRFmarco pin controller driver"
+ depends on ARCH_SIRF
select PINMUX
config PINCTRL_TEGRA
bool
+ select PINMUX
+ select PINCONF
config PINCTRL_TEGRA20
bool
- select PINMUX
- select PINCONF
select PINCTRL_TEGRA
config PINCTRL_TEGRA30
bool
- select PINMUX
- select PINCONF
select PINCTRL_TEGRA
config PINCTRL_U300
@@ -178,7 +180,7 @@ config PINCTRL_COH901
ports of 8 GPIO pins each.
config PINCTRL_SAMSUNG
- bool "Samsung pinctrl driver"
+ bool
depends on OF && GPIOLIB
select PINMUX
select PINCONF
@@ -188,27 +190,7 @@ config PINCTRL_EXYNOS4
depends on OF && GPIOLIB
select PINCTRL_SAMSUNG
-config PINCTRL_MVEBU
- bool
- depends on ARCH_MVEBU
- select PINMUX
- select PINCONF
-
-config PINCTRL_DOVE
- bool
- select PINCTRL_MVEBU
-
-config PINCTRL_KIRKWOOD
- bool
- select PINCTRL_MVEBU
-
-config PINCTRL_ARMADA_370
- bool
- select PINCTRL_MVEBU
-
-config PINCTRL_ARMADA_XP
- bool
- select PINCTRL_MVEBU
+source "drivers/pinctrl/mvebu/Kconfig"
source "drivers/pinctrl/spear/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index f395ba5cec2..f95f5ed923b 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -9,6 +9,7 @@ ifeq ($(CONFIG_OF),y)
obj-$(CONFIG_PINCTRL) += devicetree.o
endif
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
+obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o
obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o
@@ -36,12 +37,8 @@ obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o
obj-$(CONFIG_PINCTRL_EXYNOS4) += pinctrl-exynos.o
-obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o
-obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o
-obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o
-obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o
-obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o
obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o
obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o
+obj-$(CONFIG_PLAT_ORION) += mvebu/
obj-$(CONFIG_PLAT_SPEAR) += spear/
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 2e39c04fc16..5cdee8669ea 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -345,6 +345,62 @@ void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev,
}
EXPORT_SYMBOL_GPL(pinctrl_add_gpio_ranges);
+struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname,
+ struct pinctrl_gpio_range *range)
+{
+ struct pinctrl_dev *pctldev = get_pinctrl_dev_from_devname(devname);
+
+ /*
+ * If we can't find this device, let's assume that is because
+ * it has not probed yet, so the driver trying to register this
+ * range need to defer probing.
+ */
+ if (!pctldev)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ pinctrl_add_gpio_range(pctldev, range);
+ return pctldev;
+}
+EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range);
+
+/**
+ * pinctrl_find_gpio_range_from_pin() - locate the GPIO range for a pin
+ * @pctldev: the pin controller device to look in
+ * @pin: a controller-local number to find the range for
+ */
+struct pinctrl_gpio_range *
+pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,
+ unsigned int pin)
+{
+ struct pinctrl_gpio_range *range = NULL;
+
+ /* Loop over the ranges */
+ list_for_each_entry(range, &pctldev->gpio_ranges, node) {
+ /* Check if we're in the valid range */
+ if (pin >= range->pin_base &&
+ pin < range->pin_base + range->npins) {
+ return range;
+ }
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin);
+
+/**
+ * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller
+ * @pctldev: pin controller device to remove the range from
+ * @range: the GPIO range to remove
+ */
+void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range)
+{
+ mutex_lock(&pinctrl_mutex);
+ list_del(&range->node);
+ mutex_unlock(&pinctrl_mutex);
+}
+EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range);
+
/**
* pinctrl_get_group_selector() - returns the group selector for a group
* @pctldev: the pin controller handling the group
@@ -563,6 +619,8 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map)
return -EPROBE_DEFER;
}
+ setting->dev_name = map->dev_name;
+
switch (map->type) {
case PIN_MAP_TYPE_MUX_GROUP:
ret = pinmux_map_to_setting(map, setting);
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h
index 1f40ff68a8c..12f5694f3d5 100644
--- a/drivers/pinctrl/core.h
+++ b/drivers/pinctrl/core.h
@@ -105,12 +105,14 @@ struct pinctrl_setting_configs {
* @type: the type of setting
* @pctldev: pin control device handling to be programmed. Not used for
* PIN_MAP_TYPE_DUMMY_STATE.
+ * @dev_name: the name of the device using this state
* @data: Data specific to the setting type
*/
struct pinctrl_setting {
struct list_head node;
enum pinctrl_map_type type;
struct pinctrl_dev *pctldev;
+ const char *dev_name;
union {
struct pinctrl_setting_mux mux;
struct pinctrl_setting_configs configs;
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
index fcb1de45473..fe2d1af7cfa 100644
--- a/drivers/pinctrl/devicetree.c
+++ b/drivers/pinctrl/devicetree.c
@@ -106,6 +106,17 @@ static struct pinctrl_dev *find_pinctrl_by_of_node(struct device_node *np)
return NULL;
}
+struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
+{
+ struct pinctrl_dev *pctldev;
+
+ pctldev = find_pinctrl_by_of_node(np);
+ if (!pctldev)
+ return NULL;
+
+ return pctldev;
+}
+
static int dt_to_map_one_config(struct pinctrl *p, const char *statename,
struct device_node *np_config)
{
diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig
new file mode 100644
index 00000000000..366fa541ee9
--- /dev/null
+++ b/drivers/pinctrl/mvebu/Kconfig
@@ -0,0 +1,24 @@
+if PLAT_ORION
+
+config PINCTRL_MVEBU
+ bool
+ select PINMUX
+ select PINCONF
+
+config PINCTRL_DOVE
+ bool
+ select PINCTRL_MVEBU
+
+config PINCTRL_KIRKWOOD
+ bool
+ select PINCTRL_MVEBU
+
+config PINCTRL_ARMADA_370
+ bool
+ select PINCTRL_MVEBU
+
+config PINCTRL_ARMADA_XP
+ bool
+ select PINCTRL_MVEBU
+
+endif
diff --git a/drivers/pinctrl/mvebu/Makefile b/drivers/pinctrl/mvebu/Makefile
new file mode 100644
index 00000000000..37c253297af
--- /dev/null
+++ b/drivers/pinctrl/mvebu/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o
+obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o
+obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o
+obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o
+obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o
diff --git a/drivers/pinctrl/pinctrl-armada-370.c b/drivers/pinctrl/mvebu/pinctrl-armada-370.c
index c907647de6a..c907647de6a 100644
--- a/drivers/pinctrl/pinctrl-armada-370.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-370.c
diff --git a/drivers/pinctrl/pinctrl-armada-xp.c b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
index 40bd52a46b4..40bd52a46b4 100644
--- a/drivers/pinctrl/pinctrl-armada-xp.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
diff --git a/drivers/pinctrl/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c
index ffe74b27d66..ffe74b27d66 100644
--- a/drivers/pinctrl/pinctrl-dove.c
+++ b/drivers/pinctrl/mvebu/pinctrl-dove.c
diff --git a/drivers/pinctrl/pinctrl-kirkwood.c b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c
index 9a74ef674a0..9a74ef674a0 100644
--- a/drivers/pinctrl/pinctrl-kirkwood.c
+++ b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c
diff --git a/drivers/pinctrl/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
index 8e6266c6249..6c44b7e8964 100644
--- a/drivers/pinctrl/pinctrl-mvebu.c
+++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
@@ -24,7 +24,6 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
-#include "core.h"
#include "pinctrl-mvebu.h"
#define MPPS_PER_REG 8
diff --git a/drivers/pinctrl/pinctrl-mvebu.h b/drivers/pinctrl/mvebu/pinctrl-mvebu.h
index 90bd3beee86..90bd3beee86 100644
--- a/drivers/pinctrl/pinctrl-mvebu.h
+++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.h
diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c
index 33fbaeaa65d..833a3645815 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -41,6 +41,7 @@ struct pin_config_item conf_items[] = {
PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL),
+ PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_DISABLE, "input schmitt disabled", NULL),
PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL),
PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "time units"),
PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"),
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
new file mode 100644
index 00000000000..c5e75715718
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -0,0 +1,1634 @@
+/*
+ * at91 pinctrl driver based on at91 pinmux core
+ *
+ * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+/* Since we request GPIOs from ourself */
+#include <linux/pinctrl/consumer.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/at91_pio.h>
+
+#include "core.h"
+
+#define MAX_NB_GPIO_PER_BANK 32
+
+struct at91_pinctrl_mux_ops;
+
+struct at91_gpio_chip {
+ struct gpio_chip chip;
+ struct pinctrl_gpio_range range;
+ struct at91_gpio_chip *next; /* Bank sharing same clock */
+ int pioc_hwirq; /* PIO bank interrupt identifier on AIC */
+ int pioc_virq; /* PIO bank Linux virtual interrupt */
+ int pioc_idx; /* PIO bank index */
+ void __iomem *regbase; /* PIO bank virtual address */
+ struct clk *clock; /* associated clock */
+ struct irq_domain *domain; /* associated irq domain */
+ struct at91_pinctrl_mux_ops *ops; /* ops */
+};
+
+#define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip)
+
+static struct at91_gpio_chip *gpio_chips[MAX_GPIO_BANKS];
+
+static int gpio_banks;
+
+#define PULL_UP (1 << 0)
+#define MULTI_DRIVE (1 << 1)
+#define DEGLITCH (1 << 2)
+#define PULL_DOWN (1 << 3)
+#define DIS_SCHMIT (1 << 4)
+#define DEBOUNCE (1 << 16)
+#define DEBOUNCE_VAL_SHIFT 17
+#define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT)
+
+/**
+ * struct at91_pmx_func - describes AT91 pinmux functions
+ * @name: the name of this specific function
+ * @groups: corresponding pin groups
+ * @ngroups: the number of groups
+ */
+struct at91_pmx_func {
+ const char *name;
+ const char **groups;
+ unsigned ngroups;
+};
+
+enum at91_mux {
+ AT91_MUX_GPIO = 0,
+ AT91_MUX_PERIPH_A = 1,
+ AT91_MUX_PERIPH_B = 2,
+ AT91_MUX_PERIPH_C = 3,
+ AT91_MUX_PERIPH_D = 4,
+};
+
+/**
+ * struct at91_pmx_pin - describes an At91 pin mux
+ * @bank: the bank of the pin
+ * @pin: the pin number in the @bank
+ * @mux: the mux mode : gpio or periph_x of the pin i.e. alternate function.
+ * @conf: the configuration of the pin: PULL_UP, MULTIDRIVE etc...
+ */
+struct at91_pmx_pin {
+ uint32_t bank;
+ uint32_t pin;
+ enum at91_mux mux;
+ unsigned long conf;
+};
+
+/**
+ * struct at91_pin_group - describes an At91 pin group
+ * @name: the name of this specific pin group
+ * @pins_conf: the mux mode for each pin in this group. The size of this
+ * array is the same as pins.
+ * @pins: an array of discrete physical pins used in this group, taken
+ * from the driver-local pin enumeration space
+ * @npins: the number of pins in this group array, i.e. the number of
+ * elements in .pins so we can iterate over that array
+ */
+struct at91_pin_group {
+ const char *name;
+ struct at91_pmx_pin *pins_conf;
+ unsigned int *pins;
+ unsigned npins;
+};
+
+/**
+ * struct at91_pinctrl_mux_ops - describes an At91 mux ops group
+ * on new IP with support for periph C and D the way to mux in
+ * periph A and B has changed
+ * So provide the right call back
+ * if not present means the IP does not support it
+ * @get_periph: return the periph mode configured
+ * @mux_A_periph: mux as periph A
+ * @mux_B_periph: mux as periph B
+ * @mux_C_periph: mux as periph C
+ * @mux_D_periph: mux as periph D
+ * @get_deglitch: get deglitch status
+ * @set_deglitch: enable/disable deglitch
+ * @get_debounce: get debounce status
+ * @set_debounce: enable/disable debounce
+ * @get_pulldown: get pulldown status
+ * @set_pulldown: enable/disable pulldown
+ * @get_schmitt_trig: get schmitt trigger status
+ * @disable_schmitt_trig: disable schmitt trigger
+ * @irq_type: return irq type
+ */
+struct at91_pinctrl_mux_ops {
+ enum at91_mux (*get_periph)(void __iomem *pio, unsigned mask);
+ void (*mux_A_periph)(void __iomem *pio, unsigned mask);
+ void (*mux_B_periph)(void __iomem *pio, unsigned mask);
+ void (*mux_C_periph)(void __iomem *pio, unsigned mask);
+ void (*mux_D_periph)(void __iomem *pio, unsigned mask);
+ bool (*get_deglitch)(void __iomem *pio, unsigned pin);
+ void (*set_deglitch)(void __iomem *pio, unsigned mask, bool in_on);
+ bool (*get_debounce)(void __iomem *pio, unsigned pin, u32 *div);
+ void (*set_debounce)(void __iomem *pio, unsigned mask, bool in_on, u32 div);
+ bool (*get_pulldown)(void __iomem *pio, unsigned pin);
+ void (*set_pulldown)(void __iomem *pio, unsigned mask, bool in_on);
+ bool (*get_schmitt_trig)(void __iomem *pio, unsigned pin);
+ void (*disable_schmitt_trig)(void __iomem *pio, unsigned mask);
+ /* irq */
+ int (*irq_type)(struct irq_data *d, unsigned type);
+};
+
+static int gpio_irq_type(struct irq_data *d, unsigned type);
+static int alt_gpio_irq_type(struct irq_data *d, unsigned type);
+
+struct at91_pinctrl {
+ struct device *dev;
+ struct pinctrl_dev *pctl;
+
+ int nbanks;
+
+ uint32_t *mux_mask;
+ int nmux;
+
+ struct at91_pmx_func *functions;
+ int nfunctions;
+
+ struct at91_pin_group *groups;
+ int ngroups;
+
+ struct at91_pinctrl_mux_ops *ops;
+};
+
+static const inline struct at91_pin_group *at91_pinctrl_find_group_by_name(
+ const struct at91_pinctrl *info,
+ const char *name)
+{
+ const struct at91_pin_group *grp = NULL;
+ int i;
+
+ for (i = 0; i < info->ngroups; i++) {
+ if (strcmp(info->groups[i].name, name))
+ continue;
+
+ grp = &info->groups[i];
+ dev_dbg(info->dev, "%s: %d 0:%d\n", name, grp->npins, grp->pins[0]);
+ break;
+ }
+
+ return grp;
+}
+
+static int at91_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+ return info->ngroups;
+}
+
+static const char *at91_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned selector)
+{
+ struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+ return info->groups[selector].name;
+}
+
+static int at91_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
+ const unsigned **pins,
+ unsigned *npins)
+{
+ struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+ if (selector >= info->ngroups)
+ return -EINVAL;
+
+ *pins = info->groups[selector].pins;
+ *npins = info->groups[selector].npins;
+
+ return 0;
+}
+
+static void at91_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+ unsigned offset)
+{
+ seq_printf(s, "%s", dev_name(pctldev->dev));
+}
+
+static int at91_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np,
+ struct pinctrl_map **map, unsigned *num_maps)
+{
+ struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+ const struct at91_pin_group *grp;
+ struct pinctrl_map *new_map;
+ struct device_node *parent;
+ int map_num = 1;
+ int i;
+
+ /*
+ * first find the group of this node and check if we need create
+ * config maps for pins
+ */
+ grp = at91_pinctrl_find_group_by_name(info, np->name);
+ if (!grp) {
+ dev_err(info->dev, "unable to find group for node %s\n",
+ np->name);
+ return -EINVAL;
+ }
+
+ map_num += grp->npins;
+ new_map = devm_kzalloc(pctldev->dev, sizeof(*new_map) * map_num, GFP_KERNEL);
+ if (!new_map)
+ return -ENOMEM;
+
+ *map = new_map;
+ *num_maps = map_num;
+
+ /* create mux map */
+ parent = of_get_parent(np);
+ if (!parent) {
+ kfree(new_map);
+ return -EINVAL;
+ }
+ new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
+ new_map[0].data.mux.function = parent->name;
+ new_map[0].data.mux.group = np->name;
+ of_node_put(parent);
+
+ /* create config map */
+ new_map++;
+ for (i = 0; i < grp->npins; i++) {
+ new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
+ new_map[i].data.configs.group_or_pin =
+ pin_get_name(pctldev, grp->pins[i]);
+ new_map[i].data.configs.configs = &grp->pins_conf[i].conf;
+ new_map[i].data.configs.num_configs = 1;
+ }
+
+ dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n",
+ (*map)->data.mux.function, (*map)->data.mux.group, map_num);
+
+ return 0;
+}
+
+static void at91_dt_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *map, unsigned num_maps)
+{
+}
+
+static struct pinctrl_ops at91_pctrl_ops = {
+ .get_groups_count = at91_get_groups_count,
+ .get_group_name = at91_get_group_name,
+ .get_group_pins = at91_get_group_pins,
+ .pin_dbg_show = at91_pin_dbg_show,
+ .dt_node_to_map = at91_dt_node_to_map,
+ .dt_free_map = at91_dt_free_map,
+};
+
+static void __iomem * pin_to_controller(struct at91_pinctrl *info,
+ unsigned int bank)
+{
+ return gpio_chips[bank]->regbase;
+}
+
+static inline int pin_to_bank(unsigned pin)
+{
+ return pin /= MAX_NB_GPIO_PER_BANK;
+}
+
+static unsigned pin_to_mask(unsigned int pin)
+{
+ return 1 << pin;
+}
+
+static void at91_mux_disable_interrupt(void __iomem *pio, unsigned mask)
+{
+ writel_relaxed(mask, pio + PIO_IDR);
+}
+
+static unsigned at91_mux_get_pullup(void __iomem *pio, unsigned pin)
+{
+ return (readl_relaxed(pio + PIO_PUSR) >> pin) & 0x1;
+}
+
+static void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on)
+{
+ writel_relaxed(mask, pio + (on ? PIO_PUER : PIO_PUDR));
+}
+
+static unsigned at91_mux_get_multidrive(void __iomem *pio, unsigned pin)
+{
+ return (readl_relaxed(pio + PIO_MDSR) >> pin) & 0x1;
+}
+
+static void at91_mux_set_multidrive(void __iomem *pio, unsigned mask, bool on)
+{
+ writel_relaxed(mask, pio + (on ? PIO_MDER : PIO_MDDR));
+}
+
+static void at91_mux_set_A_periph(void __iomem *pio, unsigned mask)
+{
+ writel_relaxed(mask, pio + PIO_ASR);
+}
+
+static void at91_mux_set_B_periph(void __iomem *pio, unsigned mask)
+{
+ writel_relaxed(mask, pio + PIO_BSR);
+}
+
+static void at91_mux_pio3_set_A_periph(void __iomem *pio, unsigned mask)
+{
+
+ writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) & ~mask,
+ pio + PIO_ABCDSR1);
+ writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) & ~mask,
+ pio + PIO_ABCDSR2);
+}
+
+static void at91_mux_pio3_set_B_periph(void __iomem *pio, unsigned mask)
+{
+ writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) | mask,
+ pio + PIO_ABCDSR1);
+ writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) & ~mask,
+ pio + PIO_ABCDSR2);
+}
+
+static void at91_mux_pio3_set_C_periph(void __iomem *pio, unsigned mask)
+{
+ writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) & ~mask, pio + PIO_ABCDSR1);
+ writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2);
+}
+
+static void at91_mux_pio3_set_D_periph(void __iomem *pio, unsigned mask)
+{
+ writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1);
+ writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2);
+}
+
+static enum at91_mux at91_mux_pio3_get_periph(void __iomem *pio, unsigned mask)
+{
+ unsigned select;
+
+ if (readl_relaxed(pio + PIO_PSR) & mask)
+ return AT91_MUX_GPIO;
+
+ select = !!(readl_relaxed(pio + PIO_ABCDSR1) & mask);
+ select |= (!!(readl_relaxed(pio + PIO_ABCDSR2) & mask) << 1);
+
+ return select + 1;
+}
+
+static enum at91_mux at91_mux_get_periph(void __iomem *pio, unsigned mask)
+{
+ unsigned select;
+
+ if (readl_relaxed(pio + PIO_PSR) & mask)
+ return AT91_MUX_GPIO;
+
+ select = readl_relaxed(pio + PIO_ABSR) & mask;
+
+ return select + 1;
+}
+
+static bool at91_mux_get_deglitch(void __iomem *pio, unsigned pin)
+{
+ return (__raw_readl(pio + PIO_IFSR) >> pin) & 0x1;
+}
+
+static void at91_mux_set_deglitch(void __iomem *pio, unsigned mask, bool is_on)
+{
+ __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR));
+}
+
+static void at91_mux_pio3_set_deglitch(void __iomem *pio, unsigned mask, bool is_on)
+{
+ if (is_on)
+ __raw_writel(mask, pio + PIO_IFSCDR);
+ at91_mux_set_deglitch(pio, mask, is_on);
+}
+
+static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin, u32 *div)
+{
+ *div = __raw_readl(pio + PIO_SCDR);
+
+ return (__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1;
+}
+
+static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask,
+ bool is_on, u32 div)
+{
+ if (is_on) {
+ __raw_writel(mask, pio + PIO_IFSCER);
+ __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR);
+ __raw_writel(mask, pio + PIO_IFER);
+ } else {
+ __raw_writel(mask, pio + PIO_IFDR);
+ }
+}
+
+static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin)
+{
+ return (__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1;
+}
+
+static void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is_on)
+{
+ __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR));
+}
+
+static void at91_mux_pio3_disable_schmitt_trig(void __iomem *pio, unsigned mask)
+{
+ __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT);
+}
+
+static bool at91_mux_pio3_get_schmitt_trig(void __iomem *pio, unsigned pin)
+{
+ return (__raw_readl(pio + PIO_SCHMITT) >> pin) & 0x1;
+}
+
+static struct at91_pinctrl_mux_ops at91rm9200_ops = {
+ .get_periph = at91_mux_get_periph,
+ .mux_A_periph = at91_mux_set_A_periph,
+ .mux_B_periph = at91_mux_set_B_periph,
+ .get_deglitch = at91_mux_get_deglitch,
+ .set_deglitch = at91_mux_set_deglitch,
+ .irq_type = gpio_irq_type,
+};
+
+static struct at91_pinctrl_mux_ops at91sam9x5_ops = {
+ .get_periph = at91_mux_pio3_get_periph,
+ .mux_A_periph = at91_mux_pio3_set_A_periph,
+ .mux_B_periph = at91_mux_pio3_set_B_periph,
+ .mux_C_periph = at91_mux_pio3_set_C_periph,
+ .mux_D_periph = at91_mux_pio3_set_D_periph,
+ .get_deglitch = at91_mux_get_deglitch,
+ .set_deglitch = at91_mux_pio3_set_deglitch,
+ .get_debounce = at91_mux_pio3_get_debounce,
+ .set_debounce = at91_mux_pio3_set_debounce,
+ .get_pulldown = at91_mux_pio3_get_pulldown,
+ .set_pulldown = at91_mux_pio3_set_pulldown,
+ .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig,
+ .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig,
+ .irq_type = alt_gpio_irq_type,
+};
+
+static void at91_pin_dbg(const struct device *dev, const struct at91_pmx_pin *pin)
+{
+ if (pin->mux) {
+ dev_dbg(dev, "pio%c%d configured as periph%c with conf = 0x%lu\n",
+ pin->bank + 'A', pin->pin, pin->mux - 1 + 'A', pin->conf);
+ } else {
+ dev_dbg(dev, "pio%c%d configured as gpio with conf = 0x%lu\n",
+ pin->bank + 'A', pin->pin, pin->conf);
+ }
+}
+
+static int pin_check_config(struct at91_pinctrl *info, const char* name,
+ int index, const struct at91_pmx_pin *pin)
+{
+ int mux;
+
+ /* check if it's a valid config */
+ if (pin->bank >= info->nbanks) {
+ dev_err(info->dev, "%s: pin conf %d bank_id %d >= nbanks %d\n",
+ name, index, pin->bank, info->nbanks);
+ return -EINVAL;
+ }
+
+ if (pin->pin >= MAX_NB_GPIO_PER_BANK) {
+ dev_err(info->dev, "%s: pin conf %d pin_bank_id %d >= %d\n",
+ name, index, pin->pin, MAX_NB_GPIO_PER_BANK);
+ return -EINVAL;
+ }
+
+ if (!pin->mux)
+ return 0;
+
+ mux = pin->mux - 1;
+
+ if (mux >= info->nmux) {
+ dev_err(info->dev, "%s: pin conf %d mux_id %d >= nmux %d\n",
+ name, index, mux, info->nmux);
+ return -EINVAL;
+ }
+
+ if (!(info->mux_mask[pin->bank * info->nmux + mux] & 1 << pin->pin)) {
+ dev_err(info->dev, "%s: pin conf %d mux_id %d not supported for pio%c%d\n",
+ name, index, mux, pin->bank + 'A', pin->pin);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void at91_mux_gpio_disable(void __iomem *pio, unsigned mask)
+{
+ writel_relaxed(mask, pio + PIO_PDR);
+}
+
+static void at91_mux_gpio_enable(void __iomem *pio, unsigned mask, bool input)
+{
+ writel_relaxed(mask, pio + PIO_PER);
+ writel_relaxed(mask, pio + (input ? PIO_ODR : PIO_OER));
+}
+
+static int at91_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
+ unsigned group)
+{
+ struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+ const struct at91_pmx_pin *pins_conf = info->groups[group].pins_conf;
+ const struct at91_pmx_pin *pin;
+ uint32_t npins = info->groups[group].npins;
+ int i, ret;
+ unsigned mask;
+ void __iomem *pio;
+
+ dev_dbg(info->dev, "enable function %s group %s\n",
+ info->functions[selector].name, info->groups[group].name);
+
+ /* first check that all the pins of the group are valid with a valid
+ * paramter */
+ for (i = 0; i < npins; i++) {
+ pin = &pins_conf[i];
+ ret = pin_check_config(info, info->groups[group].name, i, pin);
+ if (ret)
+ return ret;
+ }
+
+ for (i = 0; i < npins; i++) {
+ pin = &pins_conf[i];
+ at91_pin_dbg(info->dev, pin);
+ pio = pin_to_controller(info, pin->bank);
+ mask = pin_to_mask(pin->pin);
+ at91_mux_disable_interrupt(pio, mask);
+ switch(pin->mux) {
+ case AT91_MUX_GPIO:
+ at91_mux_gpio_enable(pio, mask, 1);
+ break;
+ case AT91_MUX_PERIPH_A:
+ info->ops->mux_A_periph(pio, mask);
+ break;
+ case AT91_MUX_PERIPH_B:
+ info->ops->mux_B_periph(pio, mask);
+ break;
+ case AT91_MUX_PERIPH_C:
+ if (!info->ops->mux_C_periph)
+ return -EINVAL;
+ info->ops->mux_C_periph(pio, mask);
+ break;
+ case AT91_MUX_PERIPH_D:
+ if (!info->ops->mux_D_periph)
+ return -EINVAL;
+ info->ops->mux_D_periph(pio, mask);
+ break;
+ }
+ if (pin->mux)
+ at91_mux_gpio_disable(pio, mask);
+ }
+
+ return 0;
+}
+
+static void at91_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
+ unsigned group)
+{
+ struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+ const struct at91_pmx_pin *pins_conf = info->groups[group].pins_conf;
+ const struct at91_pmx_pin *pin;
+ uint32_t npins = info->groups[group].npins;
+ int i;
+ unsigned mask;
+ void __iomem *pio;
+
+ for (i = 0; i < npins; i++) {
+ pin = &pins_conf[i];
+ at91_pin_dbg(info->dev, pin);
+ pio = pin_to_controller(info, pin->bank);
+ mask = pin_to_mask(pin->pin);
+ at91_mux_gpio_enable(pio, mask, 1);
+ }
+}
+
+static int at91_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+ struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+ return info->nfunctions;
+}
+
+static const char *at91_pmx_get_func_name(struct pinctrl_dev *pctldev,
+ unsigned selector)
+{
+ struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+ return info->functions[selector].name;
+}
+
+static int at91_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
+ const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+ *groups = info->functions[selector].groups;
+ *num_groups = info->functions[selector].ngroups;
+
+ return 0;
+}
+
+static int at91_gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned offset)
+{
+ struct at91_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+ struct at91_gpio_chip *at91_chip;
+ struct gpio_chip *chip;
+ unsigned mask;
+
+ if (!range) {
+ dev_err(npct->dev, "invalid range\n");
+ return -EINVAL;
+ }
+ if (!range->gc) {
+ dev_err(npct->dev, "missing GPIO chip in range\n");
+ return -EINVAL;
+ }
+ chip = range->gc;
+ at91_chip = container_of(chip, struct at91_gpio_chip, chip);
+
+ dev_dbg(npct->dev, "enable pin %u as GPIO\n", offset);
+
+ mask = 1 << (offset - chip->base);
+
+ dev_dbg(npct->dev, "enable pin %u as PIO%c%d 0x%x\n",
+ offset, 'A' + range->id, offset - chip->base, mask);
+
+ writel_relaxed(mask, at91_chip->regbase + PIO_PER);
+
+ return 0;
+}
+
+static void at91_gpio_disable_free(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned offset)
+{
+ struct at91_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+ dev_dbg(npct->dev, "disable pin %u as GPIO\n", offset);
+ /* Set the pin to some default state, GPIO is usually default */
+}
+
+static struct pinmux_ops at91_pmx_ops = {
+ .get_functions_count = at91_pmx_get_funcs_count,
+ .get_function_name = at91_pmx_get_func_name,
+ .get_function_groups = at91_pmx_get_groups,
+ .enable = at91_pmx_enable,
+ .disable = at91_pmx_disable,
+ .gpio_request_enable = at91_gpio_request_enable,
+ .gpio_disable_free = at91_gpio_disable_free,
+};
+
+static int at91_pinconf_get(struct pinctrl_dev *pctldev,
+ unsigned pin_id, unsigned long *config)
+{
+ struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+ void __iomem *pio;
+ unsigned pin;
+ int div;
+
+ dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, *config);
+ pio = pin_to_controller(info, pin_to_bank(pin_id));
+ pin = pin_id % MAX_NB_GPIO_PER_BANK;
+
+ if (at91_mux_get_multidrive(pio, pin))
+ *config |= MULTI_DRIVE;
+
+ if (at91_mux_get_pullup(pio, pin))
+ *config |= PULL_UP;
+
+ if (info->ops->get_deglitch && info->ops->get_deglitch(pio, pin))
+ *config |= DEGLITCH;
+ if (info->ops->get_debounce && info->ops->get_debounce(pio, pin, &div))
+ *config |= DEBOUNCE | (div << DEBOUNCE_VAL_SHIFT);
+ if (info->ops->get_pulldown && info->ops->get_pulldown(pio, pin))
+ *config |= PULL_DOWN;
+ if (info->ops->get_schmitt_trig && info->ops->get_schmitt_trig(pio, pin))
+ *config |= DIS_SCHMIT;
+
+ return 0;
+}
+
+static int at91_pinconf_set(struct pinctrl_dev *pctldev,
+ unsigned pin_id, unsigned long config)
+{
+ struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+ unsigned mask;
+ void __iomem *pio;
+
+ dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, config);
+ pio = pin_to_controller(info, pin_to_bank(pin_id));
+ mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK);
+
+ if (config & PULL_UP && config & PULL_DOWN)
+ return -EINVAL;
+
+ at91_mux_set_pullup(pio, mask, config & PULL_UP);
+ at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE);
+ if (info->ops->set_deglitch)
+ info->ops->set_deglitch(pio, mask, config & DEGLITCH);
+ if (info->ops->set_debounce)
+ info->ops->set_debounce(pio, mask, config & DEBOUNCE,
+ (config & DEBOUNCE_VAL) >> DEBOUNCE_VAL_SHIFT);
+ if (info->ops->set_pulldown)
+ info->ops->set_pulldown(pio, mask, config & PULL_DOWN);
+ if (info->ops->disable_schmitt_trig && config & DIS_SCHMIT)
+ info->ops->disable_schmitt_trig(pio, mask);
+
+ return 0;
+}
+
+static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s, unsigned pin_id)
+{
+
+}
+
+static void at91_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s, unsigned group)
+{
+}
+
+static struct pinconf_ops at91_pinconf_ops = {
+ .pin_config_get = at91_pinconf_get,
+ .pin_config_set = at91_pinconf_set,
+ .pin_config_dbg_show = at91_pinconf_dbg_show,
+ .pin_config_group_dbg_show = at91_pinconf_group_dbg_show,
+};
+
+static struct pinctrl_desc at91_pinctrl_desc = {
+ .pctlops = &at91_pctrl_ops,
+ .pmxops = &at91_pmx_ops,
+ .confops = &at91_pinconf_ops,
+ .owner = THIS_MODULE,
+};
+
+static const char *gpio_compat = "atmel,at91rm9200-gpio";
+
+static void __devinit at91_pinctrl_child_count(struct at91_pinctrl *info,
+ struct device_node *np)
+{
+ struct device_node *child;
+
+ for_each_child_of_node(np, child) {
+ if (of_device_is_compatible(child, gpio_compat)) {
+ info->nbanks++;
+ } else {
+ info->nfunctions++;
+ info->ngroups += of_get_child_count(child);
+ }
+ }
+}
+
+static int __devinit at91_pinctrl_mux_mask(struct at91_pinctrl *info,
+ struct device_node *np)
+{
+ int ret = 0;
+ int size;
+ const const __be32 *list;
+
+ list = of_get_property(np, "atmel,mux-mask", &size);
+ if (!list) {
+ dev_err(info->dev, "can not read the mux-mask of %d\n", size);
+ return -EINVAL;
+ }
+
+ size /= sizeof(*list);
+ if (!size || size % info->nbanks) {
+ dev_err(info->dev, "wrong mux mask array should be by %d\n", info->nbanks);
+ return -EINVAL;
+ }
+ info->nmux = size / info->nbanks;
+
+ info->mux_mask = devm_kzalloc(info->dev, sizeof(u32) * size, GFP_KERNEL);
+ if (!info->mux_mask) {
+ dev_err(info->dev, "could not alloc mux_mask\n");
+ return -ENOMEM;
+ }
+
+ ret = of_property_read_u32_array(np, "atmel,mux-mask",
+ info->mux_mask, size);
+ if (ret)
+ dev_err(info->dev, "can not read the mux-mask of %d\n", size);
+ return ret;
+}
+
+static int __devinit at91_pinctrl_parse_groups(struct device_node *np,
+ struct at91_pin_group *grp,
+ struct at91_pinctrl *info,
+ u32 index)
+{
+ struct at91_pmx_pin *pin;
+ int size;
+ const const __be32 *list;
+ int i, j;
+
+ dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
+
+ /* Initialise group */
+ grp->name = np->name;
+
+ /*
+ * the binding format is atmel,pins = <bank pin mux CONFIG ...>,
+ * do sanity check and calculate pins number
+ */
+ list = of_get_property(np, "atmel,pins", &size);
+ /* we do not check return since it's safe node passed down */
+ size /= sizeof(*list);
+ if (!size || size % 4) {
+ dev_err(info->dev, "wrong pins number or pins and configs should be by 4\n");
+ return -EINVAL;
+ }
+
+ grp->npins = size / 4;
+ pin = grp->pins_conf = devm_kzalloc(info->dev, grp->npins * sizeof(struct at91_pmx_pin),
+ GFP_KERNEL);
+ grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
+ GFP_KERNEL);
+ if (!grp->pins_conf || !grp->pins)
+ return -ENOMEM;
+
+ for (i = 0, j = 0; i < size; i += 4, j++) {
+ pin->bank = be32_to_cpu(*list++);
+ pin->pin = be32_to_cpu(*list++);
+ grp->pins[j] = pin->bank * MAX_NB_GPIO_PER_BANK + pin->pin;
+ pin->mux = be32_to_cpu(*list++);
+ pin->conf = be32_to_cpu(*list++);
+
+ at91_pin_dbg(info->dev, pin);
+ pin++;
+ }
+
+ return 0;
+}
+
+static int __devinit at91_pinctrl_parse_functions(struct device_node *np,
+ struct at91_pinctrl *info, u32 index)
+{
+ struct device_node *child;
+ struct at91_pmx_func *func;
+ struct at91_pin_group *grp;
+ int ret;
+ static u32 grp_index;
+ u32 i = 0;
+
+ dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
+
+ func = &info->functions[index];
+
+ /* Initialise function */
+ func->name = np->name;
+ func->ngroups = of_get_child_count(np);
+ if (func->ngroups <= 0) {
+ dev_err(info->dev, "no groups defined\n");
+ return -EINVAL;
+ }
+ func->groups = devm_kzalloc(info->dev,
+ func->ngroups * sizeof(char *), GFP_KERNEL);
+ if (!func->groups)
+ return -ENOMEM;
+
+ for_each_child_of_node(np, child) {
+ func->groups[i] = child->name;
+ grp = &info->groups[grp_index++];
+ ret = at91_pinctrl_parse_groups(child, grp, info, i++);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct of_device_id at91_pinctrl_of_match[] __devinitdata = {
+ { .compatible = "atmel,at91sam9x5-pinctrl", .data = &at91sam9x5_ops },
+ { .compatible = "atmel,at91rm9200-pinctrl", .data = &at91rm9200_ops },
+ { /* sentinel */ }
+};
+
+static int __devinit at91_pinctrl_probe_dt(struct platform_device *pdev,
+ struct at91_pinctrl *info)
+{
+ int ret = 0;
+ int i, j;
+ uint32_t *tmp;
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *child;
+
+ if (!np)
+ return -ENODEV;
+
+ info->dev = &pdev->dev;
+ info->ops = (struct at91_pinctrl_mux_ops*)
+ of_match_device(at91_pinctrl_of_match, &pdev->dev)->data;
+ at91_pinctrl_child_count(info, np);
+
+ if (info->nbanks < 1) {
+ dev_err(&pdev->dev, "you need to specify atleast one gpio-controller\n");
+ return -EINVAL;
+ }
+
+ ret = at91_pinctrl_mux_mask(info, np);
+ if (ret)
+ return ret;
+
+ dev_dbg(&pdev->dev, "nmux = %d\n", info->nmux);
+
+ dev_dbg(&pdev->dev, "mux-mask\n");
+ tmp = info->mux_mask;
+ for (i = 0; i < info->nbanks; i++) {
+ for (j = 0; j < info->nmux; j++, tmp++) {
+ dev_dbg(&pdev->dev, "%d:%d\t0x%x\n", i, j, tmp[0]);
+ }
+ }
+
+ dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
+ dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups);
+ info->functions = devm_kzalloc(&pdev->dev, info->nfunctions * sizeof(struct at91_pmx_func),
+ GFP_KERNEL);
+ if (!info->functions)
+ return -ENOMEM;
+
+ info->groups = devm_kzalloc(&pdev->dev, info->ngroups * sizeof(struct at91_pin_group),
+ GFP_KERNEL);
+ if (!info->groups)
+ return -ENOMEM;
+
+ dev_dbg(&pdev->dev, "nbanks = %d\n", info->nbanks);
+ dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
+ dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups);
+
+ i = 0;
+
+ for_each_child_of_node(np, child) {
+ if (of_device_is_compatible(child, gpio_compat))
+ continue;
+ ret = at91_pinctrl_parse_functions(child, info, i++);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to parse function\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int __devinit at91_pinctrl_probe(struct platform_device *pdev)
+{
+ struct at91_pinctrl *info;
+ struct pinctrl_pin_desc *pdesc;
+ int ret, i, j ,k;
+
+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ ret = at91_pinctrl_probe_dt(pdev, info);
+ if (ret)
+ return ret;
+
+ /*
+ * We need all the GPIO drivers to probe FIRST, or we will not be able
+ * to obtain references to the struct gpio_chip * for them, and we
+ * need this to proceed.
+ */
+ for (i = 0; i < info->nbanks; i++) {
+ if (!gpio_chips[i]) {
+ dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i);
+ devm_kfree(&pdev->dev, info);
+ return -EPROBE_DEFER;
+ }
+ }
+
+ at91_pinctrl_desc.name = dev_name(&pdev->dev);
+ at91_pinctrl_desc.npins = info->nbanks * MAX_NB_GPIO_PER_BANK;
+ at91_pinctrl_desc.pins = pdesc =
+ devm_kzalloc(&pdev->dev, sizeof(*pdesc) * at91_pinctrl_desc.npins, GFP_KERNEL);
+
+ if (!at91_pinctrl_desc.pins)
+ return -ENOMEM;
+
+ for (i = 0 , k = 0; i < info->nbanks; i++) {
+ for (j = 0; j < MAX_NB_GPIO_PER_BANK; j++, k++) {
+ pdesc->number = k;
+ pdesc->name = kasprintf(GFP_KERNEL, "pio%c%d", i + 'A', j);
+ pdesc++;
+ }
+ }
+
+ platform_set_drvdata(pdev, info);
+ info->pctl = pinctrl_register(&at91_pinctrl_desc, &pdev->dev, info);
+
+ if (!info->pctl) {
+ dev_err(&pdev->dev, "could not register AT91 pinctrl driver\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /* We will handle a range of GPIO pins */
+ for (i = 0; i < info->nbanks; i++)
+ pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range);
+
+ dev_info(&pdev->dev, "initialized AT91 pinctrl driver\n");
+
+ return 0;
+
+err:
+ return ret;
+}
+
+static int __devexit at91_pinctrl_remove(struct platform_device *pdev)
+{
+ struct at91_pinctrl *info = platform_get_drvdata(pdev);
+
+ pinctrl_unregister(info->pctl);
+
+ return 0;
+}
+
+static int at91_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ /*
+ * Map back to global GPIO space and request muxing, the direction
+ * parameter does not matter for this controller.
+ */
+ int gpio = chip->base + offset;
+ int bank = chip->base / chip->ngpio;
+
+ dev_dbg(chip->dev, "%s:%d pio%c%d(%d)\n", __func__, __LINE__,
+ 'A' + bank, offset, gpio);
+
+ return pinctrl_request_gpio(gpio);
+}
+
+static void at91_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ int gpio = chip->base + offset;
+
+ pinctrl_free_gpio(gpio);
+}
+
+static int at91_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << offset;
+
+ writel_relaxed(mask, pio + PIO_ODR);
+ return 0;
+}
+
+static int at91_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << offset;
+ u32 pdsr;
+
+ pdsr = readl_relaxed(pio + PIO_PDSR);
+ return (pdsr & mask) != 0;
+}
+
+static void at91_gpio_set(struct gpio_chip *chip, unsigned offset,
+ int val)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << offset;
+
+ writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR));
+}
+
+static int at91_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int val)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << offset;
+
+ writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR));
+ writel_relaxed(mask, pio + PIO_OER);
+
+ return 0;
+}
+
+static int at91_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ int virq;
+
+ if (offset < chip->ngpio)
+ virq = irq_create_mapping(at91_gpio->domain, offset);
+ else
+ virq = -ENXIO;
+
+ dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n",
+ chip->label, offset + chip->base, virq);
+ return virq;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void at91_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+ enum at91_mux mode;
+ int i;
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+
+ for (i = 0; i < chip->ngpio; i++) {
+ unsigned pin = chip->base + i;
+ unsigned mask = pin_to_mask(pin);
+ const char *gpio_label;
+ u32 pdsr;
+
+ gpio_label = gpiochip_is_requested(chip, i);
+ if (!gpio_label)
+ continue;
+ mode = at91_gpio->ops->get_periph(pio, mask);
+ seq_printf(s, "[%s] GPIO%s%d: ",
+ gpio_label, chip->label, i);
+ if (mode == AT91_MUX_GPIO) {
+ pdsr = readl_relaxed(pio + PIO_PDSR);
+
+ seq_printf(s, "[gpio] %s\n",
+ pdsr & mask ?
+ "set" : "clear");
+ } else {
+ seq_printf(s, "[periph %c]\n",
+ mode + 'A' - 1);
+ }
+ }
+}
+#else
+#define at91_gpio_dbg_show NULL
+#endif
+
+/* Several AIC controller irqs are dispatched through this GPIO handler.
+ * To use any AT91_PIN_* as an externally triggered IRQ, first call
+ * at91_set_gpio_input() then maybe enable its glitch filter.
+ * Then just request_irq() with the pin ID; it works like any ARM IRQ
+ * handler.
+ * First implementation always triggers on rising and falling edges
+ * whereas the newer PIO3 can be additionally configured to trigger on
+ * level, edge with any polarity.
+ *
+ * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after
+ * configuring them with at91_set_a_periph() or at91_set_b_periph().
+ * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering.
+ */
+
+static void gpio_irq_mask(struct irq_data *d)
+{
+ struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << d->hwirq;
+
+ if (pio)
+ writel_relaxed(mask, pio + PIO_IDR);
+}
+
+static void gpio_irq_unmask(struct irq_data *d)
+{
+ struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << d->hwirq;
+
+ if (pio)
+ writel_relaxed(mask, pio + PIO_IER);
+}
+
+static int gpio_irq_type(struct irq_data *d, unsigned type)
+{
+ switch (type) {
+ case IRQ_TYPE_NONE:
+ case IRQ_TYPE_EDGE_BOTH:
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+/* Alternate irq type for PIO3 support */
+static int alt_gpio_irq_type(struct irq_data *d, unsigned type)
+{
+ struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << d->hwirq;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ writel_relaxed(mask, pio + PIO_ESR);
+ writel_relaxed(mask, pio + PIO_REHLSR);
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ writel_relaxed(mask, pio + PIO_ESR);
+ writel_relaxed(mask, pio + PIO_FELLSR);
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ writel_relaxed(mask, pio + PIO_LSR);
+ writel_relaxed(mask, pio + PIO_FELLSR);
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ writel_relaxed(mask, pio + PIO_LSR);
+ writel_relaxed(mask, pio + PIO_REHLSR);
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ /*
+ * disable additional interrupt modes:
+ * fall back to default behavior
+ */
+ writel_relaxed(mask, pio + PIO_AIMDR);
+ return 0;
+ case IRQ_TYPE_NONE:
+ default:
+ pr_warn("AT91: No type for irq %d\n", gpio_to_irq(d->irq));
+ return -EINVAL;
+ }
+
+ /* enable additional interrupt modes */
+ writel_relaxed(mask, pio + PIO_AIMER);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
+{
+ struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
+ unsigned bank = at91_gpio->pioc_idx;
+
+ if (unlikely(bank >= MAX_GPIO_BANKS))
+ return -EINVAL;
+
+ irq_set_irq_wake(at91_gpio->pioc_virq, state);
+
+ return 0;
+}
+#else
+#define gpio_irq_set_wake NULL
+#endif
+
+static struct irq_chip gpio_irqchip = {
+ .name = "GPIO",
+ .irq_disable = gpio_irq_mask,
+ .irq_mask = gpio_irq_mask,
+ .irq_unmask = gpio_irq_unmask,
+ /* .irq_set_type is set dynamically */
+ .irq_set_wake = gpio_irq_set_wake,
+};
+
+static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct irq_data *idata = irq_desc_get_irq_data(desc);
+ struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned long isr;
+ int n;
+
+ chained_irq_enter(chip, desc);
+ for (;;) {
+ /* Reading ISR acks pending (edge triggered) GPIO interrupts.
+ * When there none are pending, we're finished unless we need
+ * to process multiple banks (like ID_PIOCDE on sam9263).
+ */
+ isr = readl_relaxed(pio + PIO_ISR) & readl_relaxed(pio + PIO_IMR);
+ if (!isr) {
+ if (!at91_gpio->next)
+ break;
+ at91_gpio = at91_gpio->next;
+ pio = at91_gpio->regbase;
+ continue;
+ }
+
+ for_each_set_bit(n, &isr, BITS_PER_LONG) {
+ generic_handle_irq(irq_find_mapping(at91_gpio->domain, n));
+ }
+ }
+ chained_irq_exit(chip, desc);
+ /* now it may re-trigger */
+}
+
+/*
+ * This lock class tells lockdep that GPIO irqs are in a different
+ * category than their parents, so it won't report false recursion.
+ */
+static struct lock_class_key gpio_lock_class;
+
+static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ struct at91_gpio_chip *at91_gpio = h->host_data;
+
+ irq_set_lockdep_class(virq, &gpio_lock_class);
+
+ /*
+ * Can use the "simple" and not "edge" handler since it's
+ * shorter, and the AIC handles interrupts sanely.
+ */
+ irq_set_chip_and_handler(virq, &gpio_irqchip,
+ handle_simple_irq);
+ set_irq_flags(virq, IRQF_VALID);
+ irq_set_chip_data(virq, at91_gpio);
+
+ return 0;
+}
+
+static int at91_gpio_irq_domain_xlate(struct irq_domain *d,
+ struct device_node *ctrlr,
+ const u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq,
+ unsigned int *out_type)
+{
+ struct at91_gpio_chip *at91_gpio = d->host_data;
+ int ret;
+ int pin = at91_gpio->chip.base + intspec[0];
+
+ if (WARN_ON(intsize < 2))
+ return -EINVAL;
+ *out_hwirq = intspec[0];
+ *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
+
+ ret = gpio_request(pin, ctrlr->full_name);
+ if (ret)
+ return ret;
+
+ ret = gpio_direction_input(pin);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct irq_domain_ops at91_gpio_ops = {
+ .map = at91_gpio_irq_map,
+ .xlate = at91_gpio_irq_domain_xlate,
+};
+
+static int at91_gpio_of_irq_setup(struct device_node *node,
+ struct at91_gpio_chip *at91_gpio)
+{
+ struct at91_gpio_chip *prev = NULL;
+ struct irq_data *d = irq_get_irq_data(at91_gpio->pioc_virq);
+
+ at91_gpio->pioc_hwirq = irqd_to_hwirq(d);
+
+ /* Setup proper .irq_set_type function */
+ gpio_irqchip.irq_set_type = at91_gpio->ops->irq_type;
+
+ /* Disable irqs of this PIO controller */
+ writel_relaxed(~0, at91_gpio->regbase + PIO_IDR);
+
+ /* Setup irq domain */
+ at91_gpio->domain = irq_domain_add_linear(node, at91_gpio->chip.ngpio,
+ &at91_gpio_ops, at91_gpio);
+ if (!at91_gpio->domain)
+ panic("at91_gpio.%d: couldn't allocate irq domain (DT).\n",
+ at91_gpio->pioc_idx);
+
+ /* Setup chained handler */
+ if (at91_gpio->pioc_idx)
+ prev = gpio_chips[at91_gpio->pioc_idx - 1];
+
+ /* The toplevel handler handles one bank of GPIOs, except
+ * on some SoC it can handles up to three...
+ * We only set up the handler for the first of the list.
+ */
+ if (prev && prev->next == at91_gpio)
+ return 0;
+
+ irq_set_chip_data(at91_gpio->pioc_virq, at91_gpio);
+ irq_set_chained_handler(at91_gpio->pioc_virq, gpio_irq_handler);
+
+ return 0;
+}
+
+/* This structure is replicated for each GPIO block allocated at probe time */
+static struct gpio_chip at91_gpio_template = {
+ .request = at91_gpio_request,
+ .free = at91_gpio_free,
+ .direction_input = at91_gpio_direction_input,
+ .get = at91_gpio_get,
+ .direction_output = at91_gpio_direction_output,
+ .set = at91_gpio_set,
+ .to_irq = at91_gpio_to_irq,
+ .dbg_show = at91_gpio_dbg_show,
+ .can_sleep = 0,
+ .ngpio = MAX_NB_GPIO_PER_BANK,
+};
+
+static void __devinit at91_gpio_probe_fixup(void)
+{
+ unsigned i;
+ struct at91_gpio_chip *at91_gpio, *last = NULL;
+
+ for (i = 0; i < gpio_banks; i++) {
+ at91_gpio = gpio_chips[i];
+
+ /*
+ * GPIO controller are grouped on some SoC:
+ * PIOC, PIOD and PIOE can share the same IRQ line
+ */
+ if (last && last->pioc_virq == at91_gpio->pioc_virq)
+ last->next = at91_gpio;
+ last = at91_gpio;
+ }
+}
+
+static struct of_device_id at91_gpio_of_match[] __devinitdata = {
+ { .compatible = "atmel,at91sam9x5-gpio", .data = &at91sam9x5_ops, },
+ { .compatible = "atmel,at91rm9200-gpio", .data = &at91rm9200_ops },
+ { /* sentinel */ }
+};
+
+static int __devinit at91_gpio_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct resource *res;
+ struct at91_gpio_chip *at91_chip = NULL;
+ struct gpio_chip *chip;
+ struct pinctrl_gpio_range *range;
+ int ret = 0;
+ int irq, i;
+ int alias_idx = of_alias_get_id(np, "gpio");
+ uint32_t ngpio;
+ char **names;
+
+ BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips));
+ if (gpio_chips[alias_idx]) {
+ ret = -EBUSY;
+ goto err;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ ret = -ENOENT;
+ goto err;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ ret = irq;
+ goto err;
+ }
+
+ at91_chip = devm_kzalloc(&pdev->dev, sizeof(*at91_chip), GFP_KERNEL);
+ if (!at91_chip) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ at91_chip->regbase = devm_request_and_ioremap(&pdev->dev, res);
+ if (!at91_chip->regbase) {
+ dev_err(&pdev->dev, "failed to map registers, ignoring.\n");
+ ret = -EBUSY;
+ goto err;
+ }
+
+ at91_chip->ops = (struct at91_pinctrl_mux_ops*)
+ of_match_device(at91_gpio_of_match, &pdev->dev)->data;
+ at91_chip->pioc_virq = irq;
+ at91_chip->pioc_idx = alias_idx;
+
+ at91_chip->clock = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(at91_chip->clock)) {
+ dev_err(&pdev->dev, "failed to get clock, ignoring.\n");
+ goto err;
+ }
+
+ if (clk_prepare(at91_chip->clock))
+ goto clk_prep_err;
+
+ /* enable PIO controller's clock */
+ if (clk_enable(at91_chip->clock)) {
+ dev_err(&pdev->dev, "failed to enable clock, ignoring.\n");
+ goto clk_err;
+ }
+
+ at91_chip->chip = at91_gpio_template;
+
+ chip = &at91_chip->chip;
+ chip->of_node = np;
+ chip->label = dev_name(&pdev->dev);
+ chip->dev = &pdev->dev;
+ chip->owner = THIS_MODULE;
+ chip->base = alias_idx * MAX_NB_GPIO_PER_BANK;
+
+ if (!of_property_read_u32(np, "#gpio-lines", &ngpio)) {
+ if (ngpio >= MAX_NB_GPIO_PER_BANK)
+ pr_err("at91_gpio.%d, gpio-nb >= %d failback to %d\n",
+ alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK);
+ else
+ chip->ngpio = ngpio;
+ }
+
+ names = devm_kzalloc(&pdev->dev, sizeof(char*) * chip->ngpio, GFP_KERNEL);
+
+ if (!names) {
+ ret = -ENOMEM;
+ goto clk_err;
+ }
+
+ for (i = 0; i < chip->ngpio; i++)
+ names[i] = kasprintf(GFP_KERNEL, "pio%c%d", alias_idx + 'A', i);
+
+ chip->names = (const char*const*)names;
+
+ range = &at91_chip->range;
+ range->name = chip->label;
+ range->id = alias_idx;
+ range->pin_base = range->base = range->id * MAX_NB_GPIO_PER_BANK;
+
+ range->npins = chip->ngpio;
+ range->gc = chip;
+
+ ret = gpiochip_add(chip);
+ if (ret)
+ goto clk_err;
+
+ gpio_chips[alias_idx] = at91_chip;
+ gpio_banks = max(gpio_banks, alias_idx + 1);
+
+ at91_gpio_probe_fixup();
+
+ at91_gpio_of_irq_setup(np, at91_chip);
+
+ dev_info(&pdev->dev, "at address %p\n", at91_chip->regbase);
+
+ return 0;
+
+clk_err:
+ clk_unprepare(at91_chip->clock);
+clk_prep_err:
+ clk_put(at91_chip->clock);
+err:
+ dev_err(&pdev->dev, "Failure %i for GPIO %i\n", ret, alias_idx);
+
+ return ret;
+}
+
+static struct platform_driver at91_gpio_driver = {
+ .driver = {
+ .name = "gpio-at91",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(at91_gpio_of_match),
+ },
+ .probe = at91_gpio_probe,
+};
+
+static struct platform_driver at91_pinctrl_driver = {
+ .driver = {
+ .name = "pinctrl-at91",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(at91_pinctrl_of_match),
+ },
+ .probe = at91_pinctrl_probe,
+ .remove = __devexit_p(at91_pinctrl_remove),
+};
+
+static int __init at91_pinctrl_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&at91_gpio_driver);
+ if (ret)
+ return ret;
+ return platform_driver_register(&at91_pinctrl_driver);
+}
+arch_initcall(at91_pinctrl_init);
+
+static void __exit at91_pinctrl_exit(void)
+{
+ platform_driver_unregister(&at91_pinctrl_driver);
+}
+
+module_exit(at91_pinctrl_exit);
+MODULE_AUTHOR("Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>");
+MODULE_DESCRIPTION("Atmel AT91 pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c
index 7e9be18ec2d..0b0e9b49a1b 100644
--- a/drivers/pinctrl/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/pinctrl-bcm2835.c
@@ -372,7 +372,7 @@ static int bcm2835_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
return irq_linear_revmap(pc->irq_domain, offset);
}
-static struct gpio_chip bcm2835_gpio_chip __devinitconst = {
+static struct gpio_chip bcm2835_gpio_chip = {
.label = MODULE_NAME,
.owner = THIS_MODULE,
.request = bcm2835_gpio_request,
@@ -916,7 +916,7 @@ static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev,
return 0;
}
-struct pinconf_ops bcm2835_pinconf_ops = {
+static struct pinconf_ops bcm2835_pinconf_ops = {
.pin_config_get = bcm2835_pinconf_get,
.pin_config_set = bcm2835_pinconf_set,
};
@@ -931,7 +931,7 @@ static struct pinctrl_desc bcm2835_pinctrl_desc = {
.owner = THIS_MODULE,
};
-static struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range __devinitconst = {
+static struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
.name = MODULE_NAME,
.npins = BCM2835_NUM_GPIOS,
};
@@ -1042,7 +1042,7 @@ static int __devinit bcm2835_pinctrl_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit bcm2835_pinctrl_remove(struct platform_device *pdev)
+static int bcm2835_pinctrl_remove(struct platform_device *pdev)
{
struct bcm2835_pinctrl *pc = platform_get_drvdata(pdev);
@@ -1052,7 +1052,7 @@ static int __devexit bcm2835_pinctrl_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id bcm2835_pinctrl_match[] __devinitconst = {
+static struct of_device_id bcm2835_pinctrl_match[] = {
{ .compatible = "brcm,bcm2835-gpio" },
{}
};
diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c
index b446c964121..fbb37154471 100644
--- a/drivers/pinctrl/pinctrl-coh901.c
+++ b/drivers/pinctrl/pinctrl-coh901.c
@@ -13,6 +13,7 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/io.h>
+#include <linux/irqdomain.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/platform_device.h>
@@ -64,10 +65,8 @@ struct u300_gpio {
struct gpio_chip chip;
struct list_head port_list;
struct clk *clk;
- struct resource *memres;
void __iomem *base;
struct device *dev;
- int irq_base;
u32 stride;
/* Register offsets */
u32 pcr;
@@ -83,6 +82,7 @@ struct u300_gpio_port {
struct list_head node;
struct u300_gpio *gpio;
char name[8];
+ struct irq_domain *domain;
int irq;
int number;
u8 toggle_edge_mode;
@@ -314,10 +314,30 @@ static int u300_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct u300_gpio *gpio = to_u300_gpio(chip);
- int retirq = gpio->irq_base + offset;
+ int portno = offset >> 3;
+ struct u300_gpio_port *port = NULL;
+ struct list_head *p;
+ int retirq;
- dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d\n", offset,
- retirq);
+ list_for_each(p, &gpio->port_list) {
+ port = list_entry(p, struct u300_gpio_port, node);
+ if (port->number == portno)
+ break;
+ }
+ if (port == NULL) {
+ dev_err(gpio->dev, "could not locate port for GPIO %d IRQ\n",
+ offset);
+ return -EINVAL;
+ }
+
+ /*
+ * The local hwirqs on the port are the lower three bits, there
+ * are exactly 8 IRQs per port since they are 8-bit
+ */
+ retirq = irq_find_mapping(port->domain, (offset & 0x7));
+
+ dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d from port %d\n",
+ offset, retirq, port->number);
return retirq;
}
@@ -467,7 +487,7 @@ static int u300_gpio_irq_type(struct irq_data *d, unsigned trigger)
{
struct u300_gpio_port *port = irq_data_get_irq_chip_data(d);
struct u300_gpio *gpio = port->gpio;
- int offset = d->irq - gpio->irq_base;
+ int offset = (port->number << 3) + d->hwirq;
u32 val;
if ((trigger & IRQF_TRIGGER_RISING) &&
@@ -503,10 +523,12 @@ static void u300_gpio_irq_enable(struct irq_data *d)
{
struct u300_gpio_port *port = irq_data_get_irq_chip_data(d);
struct u300_gpio *gpio = port->gpio;
- int offset = d->irq - gpio->irq_base;
+ int offset = (port->number << 3) + d->hwirq;
u32 val;
unsigned long flags;
+ dev_dbg(gpio->dev, "enable IRQ for hwirq %lu on port %s, offset %d\n",
+ d->hwirq, port->name, offset);
local_irq_save(flags);
val = readl(U300_PIN_REG(offset, ien));
writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, ien));
@@ -517,7 +539,7 @@ static void u300_gpio_irq_disable(struct irq_data *d)
{
struct u300_gpio_port *port = irq_data_get_irq_chip_data(d);
struct u300_gpio *gpio = port->gpio;
- int offset = d->irq - gpio->irq_base;
+ int offset = (port->number << 3) + d->hwirq;
u32 val;
unsigned long flags;
@@ -555,8 +577,7 @@ static void u300_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
int irqoffset;
for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) {
- int pin_irq = gpio->irq_base + (port->number << 3)
- + irqoffset;
+ int pin_irq = irq_find_mapping(port->domain, irqoffset);
int offset = pinoffset + irqoffset;
dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n",
@@ -631,64 +652,86 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio)
list_for_each_safe(p, n, &gpio->port_list) {
port = list_entry(p, struct u300_gpio_port, node);
list_del(&port->node);
+ if (port->domain)
+ irq_domain_remove(port->domain);
kfree(port);
}
}
+/*
+ * Here we map a GPIO in the local gpio_chip pin space to a pin in
+ * the local pinctrl pin space. The pin controller used is
+ * pinctrl-u300.
+ */
+struct coh901_pinpair {
+ unsigned int offset;
+ unsigned int pin_base;
+};
+
+#define COH901_PINRANGE(a, b) { .offset = a, .pin_base = b }
+
+static struct coh901_pinpair coh901_pintable[] = {
+ COH901_PINRANGE(10, 426),
+ COH901_PINRANGE(11, 180),
+ COH901_PINRANGE(12, 165), /* MS/MMC card insertion */
+ COH901_PINRANGE(13, 179),
+ COH901_PINRANGE(14, 178),
+ COH901_PINRANGE(16, 194),
+ COH901_PINRANGE(17, 193),
+ COH901_PINRANGE(18, 192),
+ COH901_PINRANGE(19, 191),
+ COH901_PINRANGE(20, 186),
+ COH901_PINRANGE(21, 185),
+ COH901_PINRANGE(22, 184),
+ COH901_PINRANGE(23, 183),
+ COH901_PINRANGE(24, 182),
+ COH901_PINRANGE(25, 181),
+};
+
static int __init u300_gpio_probe(struct platform_device *pdev)
{
struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev);
struct u300_gpio *gpio;
+ struct resource *memres;
int err = 0;
int portno;
u32 val;
u32 ifr;
int i;
- gpio = kzalloc(sizeof(struct u300_gpio), GFP_KERNEL);
- if (gpio == NULL) {
- dev_err(&pdev->dev, "failed to allocate memory\n");
+ gpio = devm_kzalloc(&pdev->dev, sizeof(struct u300_gpio), GFP_KERNEL);
+ if (gpio == NULL)
return -ENOMEM;
- }
gpio->chip = u300_gpio_chip;
gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT;
- gpio->irq_base = plat->gpio_irq_base;
gpio->chip.dev = &pdev->dev;
gpio->chip.base = plat->gpio_base;
gpio->dev = &pdev->dev;
- /* Get GPIO clock */
- gpio->clk = clk_get(gpio->dev, NULL);
+ memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!memres) {
+ dev_err(gpio->dev, "could not get GPIO memory resource\n");
+ return -ENODEV;
+ }
+
+ gpio->base = devm_request_and_ioremap(&pdev->dev, memres);
+ if (!gpio->base) {
+ dev_err(gpio->dev, "could not get remap memory\n");
+ return -ENOMEM;
+ }
+
+ gpio->clk = devm_clk_get(gpio->dev, NULL);
if (IS_ERR(gpio->clk)) {
err = PTR_ERR(gpio->clk);
dev_err(gpio->dev, "could not get GPIO clock\n");
- goto err_no_clk;
+ return err;
}
+
err = clk_prepare_enable(gpio->clk);
if (err) {
dev_err(gpio->dev, "could not enable GPIO clock\n");
- goto err_no_clk_enable;
- }
-
- gpio->memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!gpio->memres) {
- dev_err(gpio->dev, "could not get GPIO memory resource\n");
- err = -ENODEV;
- goto err_no_resource;
- }
-
- if (!request_mem_region(gpio->memres->start,
- resource_size(gpio->memres),
- "GPIO Controller")) {
- err = -ENODEV;
- goto err_no_ioregion;
- }
-
- gpio->base = ioremap(gpio->memres->start, resource_size(gpio->memres));
- if (!gpio->base) {
- err = -ENOMEM;
- goto err_no_ioremap;
+ return err;
}
dev_info(gpio->dev,
@@ -732,18 +775,28 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
port->irq = platform_get_irq_byname(pdev,
port->name);
- dev_dbg(gpio->dev, "register IRQ %d for %s\n", port->irq,
+ dev_dbg(gpio->dev, "register IRQ %d for port %s\n", port->irq,
port->name);
+ port->domain = irq_domain_add_linear(pdev->dev.of_node,
+ U300_GPIO_PINS_PER_PORT,
+ &irq_domain_simple_ops,
+ port);
+ if (!port->domain) {
+ err = -ENOMEM;
+ goto err_no_domain;
+ }
+
irq_set_chained_handler(port->irq, u300_gpio_irq_handler);
irq_set_handler_data(port->irq, port);
/* For each GPIO pin set the unique IRQ handler */
for (i = 0; i < U300_GPIO_PINS_PER_PORT; i++) {
- int irqno = gpio->irq_base + (portno << 3) + i;
+ int irqno = irq_create_mapping(port->domain, i);
- dev_dbg(gpio->dev, "handler for IRQ %d on %s\n",
- irqno, port->name);
+ dev_dbg(gpio->dev, "GPIO%d on port %s gets IRQ %d\n",
+ gpio->chip.base + (port->number << 3) + i,
+ port->name, irqno);
irq_set_chip_and_handler(irqno, &u300_gpio_irqchip,
handle_simple_irq);
set_irq_flags(irqno, IRQF_VALID);
@@ -763,32 +816,31 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
goto err_no_chip;
}
- /* Spawn pin controller device as child of the GPIO, pass gpio chip */
- plat->pinctrl_device->dev.platform_data = &gpio->chip;
- err = platform_device_register(plat->pinctrl_device);
- if (err)
- goto err_no_pinctrl;
+ /*
+ * Add pinctrl pin ranges, the pin controller must be registered
+ * at this point
+ */
+ for (i = 0; i < ARRAY_SIZE(coh901_pintable); i++) {
+ struct coh901_pinpair *p = &coh901_pintable[i];
+
+ err = gpiochip_add_pin_range(&gpio->chip, "pinctrl-u300",
+ p->offset, p->pin_base, 1);
+ if (err)
+ goto err_no_range;
+ }
platform_set_drvdata(pdev, gpio);
return 0;
-err_no_pinctrl:
+err_no_range:
err = gpiochip_remove(&gpio->chip);
err_no_chip:
+err_no_domain:
err_no_port:
u300_gpio_free_ports(gpio);
- iounmap(gpio->base);
-err_no_ioremap:
- release_mem_region(gpio->memres->start, resource_size(gpio->memres));
-err_no_ioregion:
-err_no_resource:
clk_disable_unprepare(gpio->clk);
-err_no_clk_enable:
- clk_put(gpio->clk);
-err_no_clk:
- kfree(gpio);
- dev_info(&pdev->dev, "module ERROR:%d\n", err);
+ dev_err(&pdev->dev, "module ERROR:%d\n", err);
return err;
}
@@ -806,13 +858,8 @@ static int __exit u300_gpio_remove(struct platform_device *pdev)
return err;
}
u300_gpio_free_ports(gpio);
- iounmap(gpio->base);
- release_mem_region(gpio->memres->start,
- resource_size(gpio->memres));
clk_disable_unprepare(gpio->clk);
- clk_put(gpio->clk);
platform_set_drvdata(pdev, NULL);
- kfree(gpio);
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 21362f48d37..6ff665209a4 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -36,6 +36,7 @@
/* list of external wakeup controllers supported */
static const struct of_device_id exynos_wkup_irq_ids[] = {
{ .compatible = "samsung,exynos4210-wakeup-eint", },
+ { }
};
static void exynos_gpio_irq_unmask(struct irq_data *irqd)
diff --git a/drivers/pinctrl/pinctrl-falcon.c b/drivers/pinctrl/pinctrl-falcon.c
index ee730590347..8ed20e84cb0 100644
--- a/drivers/pinctrl/pinctrl-falcon.c
+++ b/drivers/pinctrl/pinctrl-falcon.c
@@ -322,7 +322,7 @@ static void falcon_pinconf_group_dbg_show(struct pinctrl_dev *pctrldev,
{
}
-struct pinconf_ops falcon_pinconf_ops = {
+static struct pinconf_ops falcon_pinconf_ops = {
.pin_config_get = falcon_pinconf_get,
.pin_config_set = falcon_pinconf_set,
.pin_config_group_get = falcon_pinconf_group_get,
diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c
index 63866d95357..131d86d7c2a 100644
--- a/drivers/pinctrl/pinctrl-imx.c
+++ b/drivers/pinctrl/pinctrl-imx.c
@@ -71,7 +71,7 @@ static const struct imx_pin_reg *imx_find_pin_reg(
break;
}
- if (!pin_reg) {
+ if (i == info->npin_regs) {
dev_err(info->dev, "Pin(%s): unable to find pin reg map\n",
info->pins[pin].name);
return NULL;
@@ -397,7 +397,7 @@ static void imx_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
}
}
-struct pinconf_ops imx_pinconf_ops = {
+static struct pinconf_ops imx_pinconf_ops = {
.pin_config_get = imx_pinconf_get,
.pin_config_set = imx_pinconf_set,
.pin_config_dbg_show = imx_pinconf_dbg_show,
@@ -611,7 +611,7 @@ int __devinit imx_pinctrl_probe(struct platform_device *pdev,
return 0;
}
-int __devexit imx_pinctrl_remove(struct platform_device *pdev)
+int imx_pinctrl_remove(struct platform_device *pdev)
{
struct imx_pinctrl *ipctl = platform_get_drvdata(pdev);
diff --git a/drivers/pinctrl/pinctrl-imx23.c b/drivers/pinctrl/pinctrl-imx23.c
index 3674d877ed7..04364f7822b 100644
--- a/drivers/pinctrl/pinctrl-imx23.c
+++ b/drivers/pinctrl/pinctrl-imx23.c
@@ -272,7 +272,7 @@ static int __devinit imx23_pinctrl_probe(struct platform_device *pdev)
return mxs_pinctrl_probe(pdev, &imx23_pinctrl_data);
}
-static struct of_device_id imx23_pinctrl_of_match[] __devinitdata = {
+static struct of_device_id imx23_pinctrl_of_match[] = {
{ .compatible = "fsl,imx23-pinctrl", },
{ /* sentinel */ }
};
@@ -285,7 +285,7 @@ static struct platform_driver imx23_pinctrl_driver = {
.of_match_table = imx23_pinctrl_of_match,
},
.probe = imx23_pinctrl_probe,
- .remove = __devexit_p(mxs_pinctrl_remove),
+ .remove = mxs_pinctrl_remove,
};
static int __init imx23_pinctrl_init(void)
diff --git a/drivers/pinctrl/pinctrl-imx28.c b/drivers/pinctrl/pinctrl-imx28.c
index 0f5b2122b1b..e1af2ba8900 100644
--- a/drivers/pinctrl/pinctrl-imx28.c
+++ b/drivers/pinctrl/pinctrl-imx28.c
@@ -388,7 +388,7 @@ static int __devinit imx28_pinctrl_probe(struct platform_device *pdev)
return mxs_pinctrl_probe(pdev, &imx28_pinctrl_data);
}
-static struct of_device_id imx28_pinctrl_of_match[] __devinitdata = {
+static struct of_device_id imx28_pinctrl_of_match[] = {
{ .compatible = "fsl,imx28-pinctrl", },
{ /* sentinel */ }
};
@@ -401,7 +401,7 @@ static struct platform_driver imx28_pinctrl_driver = {
.of_match_table = imx28_pinctrl_of_match,
},
.probe = imx28_pinctrl_probe,
- .remove = __devexit_p(mxs_pinctrl_remove),
+ .remove = mxs_pinctrl_remove,
};
static int __init imx28_pinctrl_init(void)
diff --git a/drivers/pinctrl/pinctrl-imx35.c b/drivers/pinctrl/pinctrl-imx35.c
index 82f109e26f2..1dbf5278ace 100644
--- a/drivers/pinctrl/pinctrl-imx35.c
+++ b/drivers/pinctrl/pinctrl-imx35.c
@@ -1559,7 +1559,7 @@ static struct imx_pinctrl_soc_info imx35_pinctrl_info = {
.npin_regs = ARRAY_SIZE(imx35_pin_regs),
};
-static struct of_device_id imx35_pinctrl_of_match[] __devinitdata = {
+static struct of_device_id imx35_pinctrl_of_match[] = {
{ .compatible = "fsl,imx35-iomuxc", },
{ /* sentinel */ }
};
@@ -1576,7 +1576,7 @@ static struct platform_driver imx35_pinctrl_driver = {
.of_match_table = of_match_ptr(imx35_pinctrl_of_match),
},
.probe = imx35_pinctrl_probe,
- .remove = __devexit_p(imx_pinctrl_remove),
+ .remove = imx_pinctrl_remove,
};
static int __init imx35_pinctrl_init(void)
diff --git a/drivers/pinctrl/pinctrl-imx51.c b/drivers/pinctrl/pinctrl-imx51.c
index fb846896677..131216558a7 100644
--- a/drivers/pinctrl/pinctrl-imx51.c
+++ b/drivers/pinctrl/pinctrl-imx51.c
@@ -1286,7 +1286,7 @@ static struct imx_pinctrl_soc_info imx51_pinctrl_info = {
.npin_regs = ARRAY_SIZE(imx51_pin_regs),
};
-static struct of_device_id imx51_pinctrl_of_match[] __devinitdata = {
+static struct of_device_id imx51_pinctrl_of_match[] = {
{ .compatible = "fsl,imx51-iomuxc", },
{ /* sentinel */ }
};
@@ -1303,7 +1303,7 @@ static struct platform_driver imx51_pinctrl_driver = {
.of_match_table = of_match_ptr(imx51_pinctrl_of_match),
},
.probe = imx51_pinctrl_probe,
- .remove = __devexit_p(imx_pinctrl_remove),
+ .remove = imx_pinctrl_remove,
};
static int __init imx51_pinctrl_init(void)
diff --git a/drivers/pinctrl/pinctrl-imx53.c b/drivers/pinctrl/pinctrl-imx53.c
index 783feb1ce06..ec404869177 100644
--- a/drivers/pinctrl/pinctrl-imx53.c
+++ b/drivers/pinctrl/pinctrl-imx53.c
@@ -1613,7 +1613,7 @@ static struct imx_pinctrl_soc_info imx53_pinctrl_info = {
.npin_regs = ARRAY_SIZE(imx53_pin_regs),
};
-static struct of_device_id imx53_pinctrl_of_match[] __devinitdata = {
+static struct of_device_id imx53_pinctrl_of_match[] = {
{ .compatible = "fsl,imx53-iomuxc", },
{ /* sentinel */ }
};
@@ -1630,7 +1630,7 @@ static struct platform_driver imx53_pinctrl_driver = {
.of_match_table = of_match_ptr(imx53_pinctrl_of_match),
},
.probe = imx53_pinctrl_probe,
- .remove = __devexit_p(imx_pinctrl_remove),
+ .remove = imx_pinctrl_remove,
};
static int __init imx53_pinctrl_init(void)
diff --git a/drivers/pinctrl/pinctrl-imx6q.c b/drivers/pinctrl/pinctrl-imx6q.c
index e9bf71fbedc..844ab13c93a 100644
--- a/drivers/pinctrl/pinctrl-imx6q.c
+++ b/drivers/pinctrl/pinctrl-imx6q.c
@@ -2297,7 +2297,7 @@ static struct imx_pinctrl_soc_info imx6q_pinctrl_info = {
.npin_regs = ARRAY_SIZE(imx6q_pin_regs),
};
-static struct of_device_id imx6q_pinctrl_of_match[] __devinitdata = {
+static struct of_device_id imx6q_pinctrl_of_match[] = {
{ .compatible = "fsl,imx6q-iomuxc", },
{ /* sentinel */ }
};
@@ -2314,7 +2314,7 @@ static struct platform_driver imx6q_pinctrl_driver = {
.of_match_table = of_match_ptr(imx6q_pinctrl_of_match),
},
.probe = imx6q_pinctrl_probe,
- .remove = __devexit_p(imx_pinctrl_remove),
+ .remove = imx_pinctrl_remove,
};
static int __init imx6q_pinctrl_init(void)
diff --git a/drivers/pinctrl/pinctrl-lantiq.c b/drivers/pinctrl/pinctrl-lantiq.c
index 07ba7682cf2..15f501d8902 100644
--- a/drivers/pinctrl/pinctrl-lantiq.c
+++ b/drivers/pinctrl/pinctrl-lantiq.c
@@ -46,8 +46,8 @@ static int ltq_get_group_pins(struct pinctrl_dev *pctrldev,
return 0;
}
-void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
- struct pinctrl_map *map, unsigned num_maps)
+static void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *map, unsigned num_maps)
{
int i;
@@ -128,10 +128,10 @@ static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
return ret;
}
-int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
- struct device_node *np_config,
- struct pinctrl_map **map,
- unsigned *num_maps)
+static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np_config,
+ struct pinctrl_map **map,
+ unsigned *num_maps)
{
struct pinctrl_map *tmp;
struct device_node *np;
@@ -275,16 +275,6 @@ static int ltq_pmx_enable(struct pinctrl_dev *pctrldev,
return 0;
}
-static void ltq_pmx_disable(struct pinctrl_dev *pctrldev,
- unsigned func,
- unsigned group)
-{
- /*
- * Nothing to do here. However, pinconf_check_ops() requires this
- * callback to be defined.
- */
-}
-
static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev,
struct pinctrl_gpio_range *range,
unsigned pin)
@@ -312,7 +302,6 @@ static struct pinmux_ops ltq_pmx_ops = {
.get_function_name = ltq_pmx_func_name,
.get_function_groups = ltq_pmx_get_groups,
.enable = ltq_pmx_enable,
- .disable = ltq_pmx_disable,
.gpio_request_enable = ltq_pmx_gpio_request_enable,
};
diff --git a/drivers/pinctrl/pinctrl-mmp2.c b/drivers/pinctrl/pinctrl-mmp2.c
index 2cfed552bbe..4fbb3db3f1c 100644
--- a/drivers/pinctrl/pinctrl-mmp2.c
+++ b/drivers/pinctrl/pinctrl-mmp2.c
@@ -691,7 +691,7 @@ static int __devinit mmp2_pinmux_probe(struct platform_device *pdev)
return pxa3xx_pinctrl_register(pdev, &mmp2_info);
}
-static int __devexit mmp2_pinmux_remove(struct platform_device *pdev)
+static int mmp2_pinmux_remove(struct platform_device *pdev)
{
return pxa3xx_pinctrl_unregister(pdev);
}
@@ -702,7 +702,7 @@ static struct platform_driver mmp2_pinmux_driver = {
.owner = THIS_MODULE,
},
.probe = mmp2_pinmux_probe,
- .remove = __devexit_p(mmp2_pinmux_remove),
+ .remove = mmp2_pinmux_remove,
};
static int __init mmp2_pinmux_init(void)
diff --git a/drivers/pinctrl/pinctrl-mxs.c b/drivers/pinctrl/pinctrl-mxs.c
index 4ba4636b6a4..180f16379ec 100644
--- a/drivers/pinctrl/pinctrl-mxs.c
+++ b/drivers/pinctrl/pinctrl-mxs.c
@@ -319,7 +319,7 @@ static void mxs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
seq_printf(s, "0x%lx", config);
}
-struct pinconf_ops mxs_pinconf_ops = {
+static struct pinconf_ops mxs_pinconf_ops = {
.pin_config_get = mxs_pinconf_get,
.pin_config_set = mxs_pinconf_set,
.pin_config_group_get = mxs_pinconf_group_get,
@@ -522,7 +522,7 @@ err:
}
EXPORT_SYMBOL_GPL(mxs_pinctrl_probe);
-int __devexit mxs_pinctrl_remove(struct platform_device *pdev)
+int mxs_pinctrl_remove(struct platform_device *pdev)
{
struct mxs_pinctrl_data *d = platform_get_drvdata(pdev);
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/pinctrl-nomadik-db8500.c
index debaa75b055..7d88ae35211 100644
--- a/drivers/pinctrl/pinctrl-nomadik-db8500.c
+++ b/drivers/pinctrl/pinctrl-nomadik-db8500.c
@@ -475,8 +475,10 @@ static const unsigned hsit_a_1_pins[] = { DB8500_PIN_AJ9, DB8500_PIN_AH9,
DB8500_PIN_AG9, DB8500_PIN_AG8, DB8500_PIN_AF8 };
static const unsigned hsit_a_2_pins[] = { DB8500_PIN_AJ9, DB8500_PIN_AH9,
DB8500_PIN_AG9, DB8500_PIN_AG8 };
-static const unsigned clkout_a_1_pins[] = { DB8500_PIN_AH7, DB8500_PIN_AJ6 };
-static const unsigned clkout_a_2_pins[] = { DB8500_PIN_AG7, DB8500_PIN_AF7 };
+static const unsigned clkout1_a_1_pins[] = { DB8500_PIN_AH7 };
+static const unsigned clkout1_a_2_pins[] = { DB8500_PIN_AG7 };
+static const unsigned clkout2_a_1_pins[] = { DB8500_PIN_AJ6 };
+static const unsigned clkout2_a_2_pins[] = { DB8500_PIN_AF7 };
static const unsigned usb_a_1_pins[] = { DB8500_PIN_AF28, DB8500_PIN_AE29,
DB8500_PIN_AD29, DB8500_PIN_AC29, DB8500_PIN_AD28, DB8500_PIN_AD26,
DB8500_PIN_AE26, DB8500_PIN_AG29, DB8500_PIN_AE27, DB8500_PIN_AD27,
@@ -592,7 +594,8 @@ static const unsigned stmmod_c_1_pins[] = { DB8500_PIN_C20, DB8500_PIN_B21,
DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24 };
static const unsigned usbsim_c_1_pins[] = { DB8500_PIN_D22 };
static const unsigned mc4rstn_c_1_pins[] = { DB8500_PIN_AF25 };
-static const unsigned clkout_c_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AH12 };
+static const unsigned clkout1_c_1_pins[] = { DB8500_PIN_AH13 };
+static const unsigned clkout2_c_1_pins[] = { DB8500_PIN_AH12 };
static const unsigned i2c3_c_1_pins[] = { DB8500_PIN_AG12, DB8500_PIN_AH11 };
static const unsigned spi0_c_1_pins[] = { DB8500_PIN_AH10, DB8500_PIN_AH9,
DB8500_PIN_AG9, DB8500_PIN_AG8 };
@@ -600,14 +603,66 @@ static const unsigned usbsim_c_2_pins[] = { DB8500_PIN_AF8 };
static const unsigned i2c3_c_2_pins[] = { DB8500_PIN_AG7, DB8500_PIN_AF7 };
/* Other C1 column */
+static const unsigned u2rx_oc1_1_pins[] = { DB8500_PIN_AB2 };
+static const unsigned stmape_oc1_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_Y4,
+ DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
+static const unsigned remap0_oc1_1_pins[] = { DB8500_PIN_E1 };
+static const unsigned remap1_oc1_1_pins[] = { DB8500_PIN_E2 };
+static const unsigned ptma9_oc1_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
+ DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H2,
+ DB8500_PIN_J2, DB8500_PIN_H1 };
static const unsigned kp_oc1_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3,
DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6,
DB8500_PIN_D6, DB8500_PIN_B7 };
+static const unsigned rf_oc1_1_pins[] = { DB8500_PIN_D8, DB8500_PIN_D9 };
+static const unsigned hxclk_oc1_1_pins[] = { DB8500_PIN_D16 };
+static const unsigned uartmodrx_oc1_1_pins[] = { DB8500_PIN_B17 };
+static const unsigned uartmodtx_oc1_1_pins[] = { DB8500_PIN_C16 };
+static const unsigned stmmod_oc1_1_pins[] = { DB8500_PIN_C19, DB8500_PIN_C17,
+ DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19 };
+static const unsigned hxgpio_oc1_1_pins[] = { DB8500_PIN_D21, DB8500_PIN_D20,
+ DB8500_PIN_C20, DB8500_PIN_B21, DB8500_PIN_C21, DB8500_PIN_A22,
+ DB8500_PIN_B24, DB8500_PIN_C22 };
+static const unsigned rf_oc1_2_pins[] = { DB8500_PIN_C23, DB8500_PIN_D23 };
static const unsigned spi2_oc1_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12,
DB8500_PIN_AH12, DB8500_PIN_AH11 };
static const unsigned spi2_oc1_2_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AH12,
DB8500_PIN_AH11 };
+/* Other C2 column */
+static const unsigned sbag_oc2_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_AB2,
+ DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
+static const unsigned etmr4_oc2_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
+ DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H2,
+ DB8500_PIN_J2, DB8500_PIN_H1 };
+static const unsigned ptma9_oc2_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16,
+ DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
+ DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
+ DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
+ DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
+
+/* Other C3 column */
+static const unsigned stmmod_oc3_1_pins[] = { DB8500_PIN_AB2, DB8500_PIN_W2,
+ DB8500_PIN_W3, DB8500_PIN_V3, DB8500_PIN_V2 };
+static const unsigned stmmod_oc3_2_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
+ DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3 };
+static const unsigned uartmodrx_oc3_1_pins[] = { DB8500_PIN_H2 };
+static const unsigned uartmodtx_oc3_1_pins[] = { DB8500_PIN_J2 };
+static const unsigned etmr4_oc3_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16,
+ DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
+ DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
+ DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
+ DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
+
+/* Other C4 column */
+static const unsigned sbag_oc4_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
+ DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H1 };
+static const unsigned hwobs_oc4_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16,
+ DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
+ DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
+ DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
+ DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
+
#define DB8500_PIN_GROUP(a,b) { .name = #a, .pins = a##_pins, \
.npins = ARRAY_SIZE(a##_pins), .altsetting = b }
@@ -639,6 +694,7 @@ static const struct nmk_pingroup nmk_db8500_groups[] = {
DB8500_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(ipgpio0_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(ipgpio1_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(kp_a_2, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(msp2sck_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(msp2_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(mc4_a_1, NMK_GPIO_ALT_A),
@@ -647,8 +703,10 @@ static const struct nmk_pingroup nmk_db8500_groups[] = {
DB8500_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A),
- DB8500_PIN_GROUP(clkout_a_1, NMK_GPIO_ALT_A),
- DB8500_PIN_GROUP(clkout_a_2, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(clkout1_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(clkout1_a_2, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(clkout2_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(clkout2_a_2, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A),
/* Altfunction B column */
DB8500_PIN_GROUP(trig_b_1, NMK_GPIO_ALT_B),
@@ -720,15 +778,41 @@ static const struct nmk_pingroup nmk_db8500_groups[] = {
DB8500_PIN_GROUP(stmmod_c_1, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(usbsim_c_1, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(mc4rstn_c_1, NMK_GPIO_ALT_C),
- DB8500_PIN_GROUP(clkout_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(clkout1_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(clkout2_c_1, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(i2c3_c_1, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(usbsim_c_2, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(i2c3_c_2, NMK_GPIO_ALT_C),
/* Other alt C1 column */
+ DB8500_PIN_GROUP(u2rx_oc1_1, NMK_GPIO_ALT_C1),
+ DB8500_PIN_GROUP(stmape_oc1_1, NMK_GPIO_ALT_C1),
+ DB8500_PIN_GROUP(remap0_oc1_1, NMK_GPIO_ALT_C1),
+ DB8500_PIN_GROUP(remap1_oc1_1, NMK_GPIO_ALT_C1),
+ DB8500_PIN_GROUP(ptma9_oc1_1, NMK_GPIO_ALT_C1),
DB8500_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1),
+ DB8500_PIN_GROUP(rf_oc1_1, NMK_GPIO_ALT_C1),
+ DB8500_PIN_GROUP(hxclk_oc1_1, NMK_GPIO_ALT_C1),
+ DB8500_PIN_GROUP(uartmodrx_oc1_1, NMK_GPIO_ALT_C1),
+ DB8500_PIN_GROUP(uartmodtx_oc1_1, NMK_GPIO_ALT_C1),
+ DB8500_PIN_GROUP(stmmod_oc1_1, NMK_GPIO_ALT_C1),
+ DB8500_PIN_GROUP(hxgpio_oc1_1, NMK_GPIO_ALT_C1),
+ DB8500_PIN_GROUP(rf_oc1_2, NMK_GPIO_ALT_C1),
DB8500_PIN_GROUP(spi2_oc1_1, NMK_GPIO_ALT_C1),
DB8500_PIN_GROUP(spi2_oc1_2, NMK_GPIO_ALT_C1),
+ /* Other alt C2 column */
+ DB8500_PIN_GROUP(sbag_oc2_1, NMK_GPIO_ALT_C2),
+ DB8500_PIN_GROUP(etmr4_oc2_1, NMK_GPIO_ALT_C2),
+ DB8500_PIN_GROUP(ptma9_oc2_1, NMK_GPIO_ALT_C2),
+ /* Other alt C3 column */
+ DB8500_PIN_GROUP(stmmod_oc3_1, NMK_GPIO_ALT_C3),
+ DB8500_PIN_GROUP(stmmod_oc3_2, NMK_GPIO_ALT_C3),
+ DB8500_PIN_GROUP(uartmodrx_oc3_1, NMK_GPIO_ALT_C3),
+ DB8500_PIN_GROUP(uartmodtx_oc3_1, NMK_GPIO_ALT_C3),
+ DB8500_PIN_GROUP(etmr4_oc3_1, NMK_GPIO_ALT_C3),
+ /* Other alt C4 column */
+ DB8500_PIN_GROUP(sbag_oc4_1, NMK_GPIO_ALT_C4),
+ DB8500_PIN_GROUP(hwobs_oc4_1, NMK_GPIO_ALT_C4),
};
/* We use this macro to define the groups applicable to a function */
@@ -742,7 +826,7 @@ DB8500_FUNC_GROUPS(u1, "u1rxtx_a_1", "u1ctsrts_a_1");
* only available on two pins in alternative function C
*/
DB8500_FUNC_GROUPS(u2, "u2rxtx_b_1", "u2rxtx_c_1", "u2ctsrts_c_1",
- "u2rxtx_c_2", "u2rxtx_c_3");
+ "u2rxtx_c_2", "u2rxtx_c_3", "u2rx_oc1_1");
DB8500_FUNC_GROUPS(ipi2c, "ipi2c_a_1", "ipi2c_a_2");
/*
* MSP0 can only be on a certain set of pins, but the TX/RX pins can be
@@ -757,7 +841,7 @@ DB8500_FUNC_GROUPS(msp1, "msp1txrx_a_1", "msp1_a_1", "msp1txrx_b_1");
DB8500_FUNC_GROUPS(lcdb, "lcdb_a_1");
DB8500_FUNC_GROUPS(lcd, "lcdvsi0_a_1", "lcdvsi1_a_1", "lcd_d0_d7_a_1",
"lcd_d8_d11_a_1", "lcd_d12_d23_a_1", "lcd_b_1");
-DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_b_1", "kp_b_2", "kp_c_1", "kp_oc1_1");
+DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_a_2", "kp_b_1", "kp_b_2", "kp_c_1", "kp_oc1_1");
DB8500_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1");
DB8500_FUNC_GROUPS(ssp1, "ssp1_a_1");
DB8500_FUNC_GROUPS(ssp0, "ssp0_a_1");
@@ -773,7 +857,8 @@ DB8500_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2_a_1");
DB8500_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1");
DB8500_FUNC_GROUPS(mc1, "mc1_a_1", "mc1_a_2", "mc1dir_a_1");
DB8500_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2");
-DB8500_FUNC_GROUPS(clkout, "clkout_a_1", "clkout_a_2", "clkout_c_1");
+DB8500_FUNC_GROUPS(clkout, "clkout1_a_1", "clkout1_a_2", "clkout1_c_1",
+ "clkout2_a_1", "clkout2_a_2", "clkout2_c_1");
DB8500_FUNC_GROUPS(usb, "usb_a_1");
DB8500_FUNC_GROUPS(trig, "trig_b_1");
DB8500_FUNC_GROUPS(i2c4, "i2c4_b_1");
@@ -784,8 +869,10 @@ DB8500_FUNC_GROUPS(i2c2, "i2c2_b_1", "i2c2_b_2");
* so select one of each.
*/
DB8500_FUNC_GROUPS(uartmod, "uartmodtx_b_1", "uartmodrx_b_1", "uartmodrx_b_2",
- "uartmodrx_c_1", "uartmod_tx_c_1");
-DB8500_FUNC_GROUPS(stmmod, "stmmod_b_1", "stmmod_c_1");
+ "uartmodrx_c_1", "uartmod_tx_c_1", "uartmodrx_oc1_1",
+ "uartmodtx_oc1_1", "uartmodrx_oc3_1", "uartmodtx_oc3_1");
+DB8500_FUNC_GROUPS(stmmod, "stmmod_b_1", "stmmod_c_1", "stmmod_oc1_1",
+ "stmmod_oc3_1", "stmmod_oc3_2");
DB8500_FUNC_GROUPS(spi3, "spi3_b_1");
/* Select between CS0 on alt B or PS1 on alt C */
DB8500_FUNC_GROUPS(sm, "sm_b_1", "smcs0_b_1", "smcs1_b_1", "smcleale_c_1",
@@ -799,13 +886,19 @@ DB8500_FUNC_GROUPS(ipjtag, "ipjtag_c_1");
DB8500_FUNC_GROUPS(slim0, "slim0_c_1");
DB8500_FUNC_GROUPS(ms, "ms_c_1");
DB8500_FUNC_GROUPS(iptrigout, "iptrigout_c_1");
-DB8500_FUNC_GROUPS(stmape, "stmape_c_1", "stmape_c_2");
+DB8500_FUNC_GROUPS(stmape, "stmape_c_1", "stmape_c_2", "stmape_oc1_1");
DB8500_FUNC_GROUPS(mc5, "mc5_c_1");
DB8500_FUNC_GROUPS(usbsim, "usbsim_c_1", "usbsim_c_2");
DB8500_FUNC_GROUPS(i2c3, "i2c3_c_1", "i2c3_c_2");
DB8500_FUNC_GROUPS(spi0, "spi0_c_1");
DB8500_FUNC_GROUPS(spi2, "spi2_oc1_1", "spi2_oc1_2");
-
+DB8500_FUNC_GROUPS(remap, "remap0_oc1_1", "remap1_oc1_1");
+DB8500_FUNC_GROUPS(sbag, "sbag_oc2_1", "sbag_oc4_1");
+DB8500_FUNC_GROUPS(ptm, "ptma9_oc1_1", "ptma9_oc2_1");
+DB8500_FUNC_GROUPS(rf, "rf_oc1_1", "rf_oc1_2");
+DB8500_FUNC_GROUPS(hx, "hxclk_oc1_1", "hxgpio_oc1_1");
+DB8500_FUNC_GROUPS(etm, "etmr4_oc2_1", "etmr4_oc3_1");
+DB8500_FUNC_GROUPS(hwobs, "hwobs_oc4_1");
#define FUNCTION(fname) \
{ \
.name = #fname, \
@@ -858,6 +951,12 @@ static const struct nmk_function nmk_db8500_functions[] = {
FUNCTION(i2c3),
FUNCTION(spi0),
FUNCTION(spi2),
+ FUNCTION(remap),
+ FUNCTION(ptm),
+ FUNCTION(rf),
+ FUNCTION(hx),
+ FUNCTION(etm),
+ FUNCTION(hwobs),
};
static const struct prcm_gpiocr_altcx_pin_desc db8500_altcx_pins[] = {
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8540.c b/drivers/pinctrl/pinctrl-nomadik-db8540.c
index 52fc30181f7..bb6a4016322 100644
--- a/drivers/pinctrl/pinctrl-nomadik-db8540.c
+++ b/drivers/pinctrl/pinctrl-nomadik-db8540.c
@@ -460,8 +460,10 @@ static const unsigned hsit_a_1_pins[] = { DB8540_PIN_B11, DB8540_PIN_B10,
DB8540_PIN_E10, DB8540_PIN_B12, DB8540_PIN_D10 };
static const unsigned hsit_a_2_pins[] = { DB8540_PIN_B11, DB8540_PIN_B10,
DB8540_PIN_E10, DB8540_PIN_B12 };
-static const unsigned clkout_a_1_pins[] = { DB8540_PIN_D11, DB8540_PIN_AJ6 };
-static const unsigned clkout_a_2_pins[] = { DB8540_PIN_B13, DB8540_PIN_C12 };
+static const unsigned clkout1_a_1_pins[] = { DB8540_PIN_D11 };
+static const unsigned clkout1_a_2_pins[] = { DB8540_PIN_B13 };
+static const unsigned clkout2_a_1_pins[] = { DB8540_PIN_AJ6 };
+static const unsigned clkout2_a_2_pins[] = { DB8540_PIN_C12 };
static const unsigned msp4_a_1_pins[] = { DB8540_PIN_B14, DB8540_PIN_E11 };
static const unsigned usb_a_1_pins[] = { DB8540_PIN_D12, DB8540_PIN_D15,
DB8540_PIN_C13, DB8540_PIN_C14, DB8540_PIN_C18, DB8540_PIN_C16,
@@ -698,8 +700,10 @@ static const struct nmk_pingroup nmk_db8540_groups[] = {
DB8540_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A),
DB8540_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A),
DB8540_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A),
- DB8540_PIN_GROUP(clkout_a_1, NMK_GPIO_ALT_A),
- DB8540_PIN_GROUP(clkout_a_2, NMK_GPIO_ALT_A),
+ DB8540_PIN_GROUP(clkout1_a_1, NMK_GPIO_ALT_A),
+ DB8540_PIN_GROUP(clkout1_a_2, NMK_GPIO_ALT_A),
+ DB8540_PIN_GROUP(clkout2_a_1, NMK_GPIO_ALT_A),
+ DB8540_PIN_GROUP(clkout2_a_2, NMK_GPIO_ALT_A),
DB8540_PIN_GROUP(msp4_a_1, NMK_GPIO_ALT_A),
DB8540_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A),
/* Altfunction B column */
@@ -822,6 +826,7 @@ static const struct nmk_pingroup nmk_db8540_groups[] = {
DB8540_PIN_GROUP(modaccuarttxrx_oc4_1, NMK_GPIO_ALT_C4),
DB8540_PIN_GROUP(modaccuartrtscts_oc4_1, NMK_GPIO_ALT_C4),
DB8540_PIN_GROUP(stmmod_oc4_1, NMK_GPIO_ALT_C4),
+ DB8540_PIN_GROUP(moduartstmmux_oc4_1, NMK_GPIO_ALT_C4),
};
@@ -830,7 +835,8 @@ static const struct nmk_pingroup nmk_db8540_groups[] = {
static const char * const a##_groups[] = { b };
DB8540_FUNC_GROUPS(apetrig, "apetrig_b_1");
-DB8540_FUNC_GROUPS(clkout, "clkoutreq_a_1", "clkout_a_1", "clkout_a_2");
+DB8540_FUNC_GROUPS(clkout, "clkoutreq_a_1", "clkout1_a_1", "clkout1_a_2",
+ "clkout2_a_1", "clkout2_a_2");
DB8540_FUNC_GROUPS(ddrtrig, "ddrtrig_b_1");
DB8540_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2");
DB8540_FUNC_GROUPS(hwobs, "hwobs_oc4_1");
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c
index cf82d9ce4de..8ef3e85cb01 100644
--- a/drivers/pinctrl/pinctrl-nomadik.c
+++ b/drivers/pinctrl/pinctrl-nomadik.c
@@ -30,26 +30,10 @@
#include <linux/pinctrl/pinconf.h>
/* Since we request GPIOs from ourself */
#include <linux/pinctrl/consumer.h>
-/*
- * For the U8500 archs, use the PRCMU register interface, for the older
- * Nomadik, provide some stubs. The functions using these will only be
- * called on the U8500 series.
- */
-#ifdef CONFIG_ARCH_U8500
-#include <linux/mfd/dbx500-prcmu.h>
-#else
-static inline u32 prcmu_read(unsigned int reg) {
- return 0;
-}
-static inline void prcmu_write(unsigned int reg, u32 value) {}
-static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {}
-#endif
+#include <linux/platform_data/pinctrl-nomadik.h>
#include <asm/mach/irq.h>
-#include <plat/pincfg.h>
-#include <plat/gpio-nomadik.h>
-
#include "pinctrl-nomadik.h"
/*
@@ -60,8 +44,6 @@ static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {}
* Symbols in this file are called "nmk_gpio" for "nomadik gpio"
*/
-#define NMK_GPIO_PER_CHIP 32
-
struct nmk_gpio_chip {
struct gpio_chip chip;
struct irq_domain *domain;
@@ -86,10 +68,18 @@ struct nmk_gpio_chip {
u32 lowemi;
};
+/**
+ * struct nmk_pinctrl - state container for the Nomadik pin controller
+ * @dev: containing device pointer
+ * @pctl: corresponding pin controller device
+ * @soc: SoC data for this specific chip
+ * @prcm_base: PRCM register range virtual base
+ */
struct nmk_pinctrl {
struct device *dev;
struct pinctrl_dev *pctl;
const struct nmk_pinctrl_soc_data *soc;
+ void __iomem *prcm_base;
};
static struct nmk_gpio_chip *
@@ -251,6 +241,15 @@ nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset)
dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio);
}
+static void nmk_write_masked(void __iomem *reg, u32 mask, u32 value)
+{
+ u32 val;
+
+ val = readl(reg);
+ val = ((val & ~mask) | (value & mask));
+ writel(val, reg);
+}
+
static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
unsigned offset, unsigned alt_num)
{
@@ -289,8 +288,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
if (pin_desc->altcx[i].used == true) {
reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
bit = pin_desc->altcx[i].control_bit;
- if (prcmu_read(reg) & BIT(bit)) {
- prcmu_write_masked(reg, BIT(bit), 0);
+ if (readl(npct->prcm_base + reg) & BIT(bit)) {
+ nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0);
dev_dbg(npct->dev,
"PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
offset, i+1);
@@ -318,8 +317,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
if (pin_desc->altcx[i].used == true) {
reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
bit = pin_desc->altcx[i].control_bit;
- if (prcmu_read(reg) & BIT(bit)) {
- prcmu_write_masked(reg, BIT(bit), 0);
+ if (readl(npct->prcm_base + reg) & BIT(bit)) {
+ nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0);
dev_dbg(npct->dev,
"PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
offset, i+1);
@@ -331,7 +330,7 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
bit = pin_desc->altcx[alt_index].control_bit;
dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n",
offset, alt_index+1);
- prcmu_write_masked(reg, BIT(bit), BIT(bit));
+ nmk_write_masked(npct->prcm_base + reg, BIT(bit), BIT(bit));
}
static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
@@ -536,7 +535,7 @@ static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep)
* and its sleep mode based on the specified configuration. The @cfg is
* usually one of the SoC specific macros defined in mach/<soc>-pins.h. These
* are constructed using, and can be further enhanced with, the macros in
- * plat/pincfg.h.
+ * <linux/platform_data/pinctrl-nomadik.h>
*
* If a pin's mode is set to GPIO, it is configured as an input to avoid
* side-effects. The gpio can be manipulated later using standard GPIO API
@@ -675,6 +674,35 @@ int nmk_gpio_set_mode(int gpio, int gpio_mode)
}
EXPORT_SYMBOL(nmk_gpio_set_mode);
+static int nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio)
+{
+ int i;
+ u16 reg;
+ u8 bit;
+ struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+ const struct prcm_gpiocr_altcx_pin_desc *pin_desc;
+ const u16 *gpiocr_regs;
+
+ for (i = 0; i < npct->soc->npins_altcx; i++) {
+ if (npct->soc->altcx_pins[i].pin == gpio)
+ break;
+ }
+ if (i == npct->soc->npins_altcx)
+ return NMK_GPIO_ALT_C;
+
+ pin_desc = npct->soc->altcx_pins + i;
+ gpiocr_regs = npct->soc->prcm_gpiocr_registers;
+ for (i = 0; i < PRCM_IDX_GPIOCR_ALTC_MAX; i++) {
+ if (pin_desc->altcx[i].used == true) {
+ reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
+ bit = pin_desc->altcx[i].control_bit;
+ if (readl(npct->prcm_base + reg) & BIT(bit))
+ return NMK_GPIO_ALT_C+i+1;
+ }
+ }
+ return NMK_GPIO_ALT_C;
+}
+
int nmk_gpio_get_mode(int gpio)
{
struct nmk_gpio_chip *nmk_chip;
@@ -1063,8 +1091,9 @@ static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
#include <linux/seq_file.h>
-static void nmk_gpio_dbg_show_one(struct seq_file *s, struct gpio_chip *chip,
- unsigned offset, unsigned gpio)
+static void nmk_gpio_dbg_show_one(struct seq_file *s,
+ struct pinctrl_dev *pctldev, struct gpio_chip *chip,
+ unsigned offset, unsigned gpio)
{
const char *label = gpiochip_is_requested(chip, offset);
struct nmk_gpio_chip *nmk_chip =
@@ -1078,12 +1107,18 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s, struct gpio_chip *chip,
[NMK_GPIO_ALT_A] = "altA",
[NMK_GPIO_ALT_B] = "altB",
[NMK_GPIO_ALT_C] = "altC",
+ [NMK_GPIO_ALT_C+1] = "altC1",
+ [NMK_GPIO_ALT_C+2] = "altC2",
+ [NMK_GPIO_ALT_C+3] = "altC3",
+ [NMK_GPIO_ALT_C+4] = "altC4",
};
clk_enable(nmk_chip->clk);
is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & bit);
pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit);
mode = nmk_gpio_get_mode(gpio);
+ if ((mode == NMK_GPIO_ALT_C) && pctldev)
+ mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio);
seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s",
gpio, label ?: "(none)",
@@ -1127,13 +1162,14 @@ static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
unsigned gpio = chip->base;
for (i = 0; i < chip->ngpio; i++, gpio++) {
- nmk_gpio_dbg_show_one(s, chip, i, gpio);
+ nmk_gpio_dbg_show_one(s, NULL, chip, i, gpio);
seq_printf(s, "\n");
}
}
#else
static inline void nmk_gpio_dbg_show_one(struct seq_file *s,
+ struct pinctrl_dev *pctldev,
struct gpio_chip *chip,
unsigned offset, unsigned gpio)
{
@@ -1250,8 +1286,8 @@ void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up)
}
}
-int nmk_gpio_irq_map(struct irq_domain *d, unsigned int irq,
- irq_hw_number_t hwirq)
+static int nmk_gpio_irq_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq)
{
struct nmk_gpio_chip *nmk_chip = d->host_data;
@@ -1464,7 +1500,7 @@ static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
return;
}
chip = range->gc;
- nmk_gpio_dbg_show_one(s, chip, offset - chip->base, offset);
+ nmk_gpio_dbg_show_one(s, pctldev, chip, offset - chip->base, offset);
}
static struct pinctrl_ops nmk_pinctrl_ops = {
@@ -1635,9 +1671,9 @@ static void nmk_pmx_disable(struct pinctrl_dev *pctldev,
dev_dbg(npct->dev, "disable group %s, %u pins\n", g->name, g->npins);
}
-int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
- struct pinctrl_gpio_range *range,
- unsigned offset)
+static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned offset)
{
struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
struct nmk_gpio_chip *nmk_chip;
@@ -1666,9 +1702,9 @@ int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
return 0;
}
-void nmk_gpio_disable_free(struct pinctrl_dev *pctldev,
- struct pinctrl_gpio_range *range,
- unsigned offset)
+static void nmk_gpio_disable_free(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned offset)
{
struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
@@ -1686,17 +1722,15 @@ static struct pinmux_ops nmk_pinmux_ops = {
.gpio_disable_free = nmk_gpio_disable_free,
};
-int nmk_pin_config_get(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long *config)
+static int nmk_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
+ unsigned long *config)
{
/* Not implemented */
return -EINVAL;
}
-int nmk_pin_config_set(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long config)
+static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
+ unsigned long config)
{
static const char *pullnames[] = {
[NMK_GPIO_PULL_NONE] = "none",
@@ -1818,6 +1852,7 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev)
const struct platform_device_id *platid = platform_get_device_id(pdev);
struct device_node *np = pdev->dev.of_node;
struct nmk_pinctrl *npct;
+ struct resource *res;
unsigned int version = 0;
int i;
@@ -1827,9 +1862,14 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev)
if (platid)
version = platid->driver_data;
- else if (np)
- version = (unsigned int)
- of_match_device(nmk_pinctrl_match, &pdev->dev)->data;
+ else if (np) {
+ const struct of_device_id *match;
+
+ match = of_match_device(nmk_pinctrl_match, &pdev->dev);
+ if (!match)
+ return -ENODEV;
+ version = (unsigned int) match->data;
+ }
/* Poke in other ASIC variants here */
if (version == PINCTRL_NMK_STN8815)
@@ -1839,22 +1879,37 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev)
if (version == PINCTRL_NMK_DB8540)
nmk_pinctrl_db8540_init(&npct->soc);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res) {
+ npct->prcm_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!npct->prcm_base) {
+ dev_err(&pdev->dev,
+ "failed to ioremap PRCM registers\n");
+ return -ENOMEM;
+ }
+ } else {
+ dev_info(&pdev->dev,
+ "No PRCM base, assume no ALT-Cx control is available\n");
+ }
+
/*
* We need all the GPIO drivers to probe FIRST, or we will not be able
* to obtain references to the struct gpio_chip * for them, and we
* need this to proceed.
*/
for (i = 0; i < npct->soc->gpio_num_ranges; i++) {
- if (!nmk_gpio_chips[i]) {
+ if (!nmk_gpio_chips[npct->soc->gpio_ranges[i].id]) {
dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i);
return -EPROBE_DEFER;
}
- npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[i]->chip;
+ npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[npct->soc->gpio_ranges[i].id]->chip;
}
nmk_pinctrl_desc.pins = npct->soc->pins;
nmk_pinctrl_desc.npins = npct->soc->npins;
npct->dev = &pdev->dev;
+
npct->pctl = pinctrl_register(&nmk_pinctrl_desc, &pdev->dev, npct);
if (!npct->pctl) {
dev_err(&pdev->dev, "could not register Nomadik pinctrl driver\n");
@@ -1889,6 +1944,7 @@ static const struct platform_device_id nmk_pinctrl_id[] = {
{ "pinctrl-stn8815", PINCTRL_NMK_STN8815 },
{ "pinctrl-db8500", PINCTRL_NMK_DB8500 },
{ "pinctrl-db8540", PINCTRL_NMK_DB8540 },
+ { }
};
static struct platform_driver nmk_pinctrl_driver = {
diff --git a/drivers/pinctrl/pinctrl-nomadik.h b/drivers/pinctrl/pinctrl-nomadik.h
index eef316e979a..bcd4191e10e 100644
--- a/drivers/pinctrl/pinctrl-nomadik.h
+++ b/drivers/pinctrl/pinctrl-nomadik.h
@@ -1,7 +1,7 @@
#ifndef PINCTRL_PINCTRL_NOMADIK_H
#define PINCTRL_PINCTRL_NOMADIK_H
-#include <plat/gpio-nomadik.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
/* Package definitions */
#define PINCTRL_NMK_STN8815 0
diff --git a/drivers/pinctrl/pinctrl-pxa168.c b/drivers/pinctrl/pinctrl-pxa168.c
index c1997fa7f28..cb771e4a635 100644
--- a/drivers/pinctrl/pinctrl-pxa168.c
+++ b/drivers/pinctrl/pinctrl-pxa168.c
@@ -620,7 +620,7 @@ static int __devinit pxa168_pinmux_probe(struct platform_device *pdev)
return pxa3xx_pinctrl_register(pdev, &pxa168_info);
}
-static int __devexit pxa168_pinmux_remove(struct platform_device *pdev)
+static int pxa168_pinmux_remove(struct platform_device *pdev)
{
return pxa3xx_pinctrl_unregister(pdev);
}
@@ -631,7 +631,7 @@ static struct platform_driver pxa168_pinmux_driver = {
.owner = THIS_MODULE,
},
.probe = pxa168_pinmux_probe,
- .remove = __devexit_p(pxa168_pinmux_remove),
+ .remove = pxa168_pinmux_remove,
};
static int __init pxa168_pinmux_init(void)
diff --git a/drivers/pinctrl/pinctrl-pxa3xx.c b/drivers/pinctrl/pinctrl-pxa3xx.c
index f14cd6ba4c0..51f8a388b91 100644
--- a/drivers/pinctrl/pinctrl-pxa3xx.c
+++ b/drivers/pinctrl/pinctrl-pxa3xx.c
@@ -173,7 +173,6 @@ int pxa3xx_pinctrl_register(struct platform_device *pdev,
{
struct pinctrl_desc *desc;
struct resource *res;
- int ret = 0;
if (!info || !info->cputype)
return -EINVAL;
@@ -188,23 +187,17 @@ int pxa3xx_pinctrl_register(struct platform_device *pdev,
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENOENT;
- info->phy_base = res->start;
- info->phy_size = resource_size(res);
- info->virt_base = ioremap(info->phy_base, info->phy_size);
+ info->virt_base = devm_request_and_ioremap(&pdev->dev, res);
if (!info->virt_base)
return -ENOMEM;
info->pctrl = pinctrl_register(desc, &pdev->dev, info);
if (!info->pctrl) {
dev_err(&pdev->dev, "failed to register PXA pinmux driver\n");
- ret = -EINVAL;
- goto err;
+ return -EINVAL;
}
pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range);
platform_set_drvdata(pdev, info);
return 0;
-err:
- iounmap(info->virt_base);
- return ret;
}
int pxa3xx_pinctrl_unregister(struct platform_device *pdev)
@@ -212,7 +205,6 @@ int pxa3xx_pinctrl_unregister(struct platform_device *pdev)
struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev);
pinctrl_unregister(info->pctrl);
- iounmap(info->virt_base);
platform_set_drvdata(pdev, NULL);
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-pxa3xx.h b/drivers/pinctrl/pinctrl-pxa3xx.h
index 8135744d659..92fad088083 100644
--- a/drivers/pinctrl/pinctrl-pxa3xx.h
+++ b/drivers/pinctrl/pinctrl-pxa3xx.h
@@ -60,8 +60,6 @@ struct pxa3xx_pinmux_info {
struct device *dev;
struct pinctrl_dev *pctrl;
enum pxa_cpu_type cputype;
- unsigned int phy_base;
- unsigned int phy_size;
void __iomem *virt_base;
struct pxa3xx_mfp_pin *mfp;
diff --git a/drivers/pinctrl/pinctrl-pxa910.c b/drivers/pinctrl/pinctrl-pxa910.c
index c72ab4b9cc8..5fecd221b83 100644
--- a/drivers/pinctrl/pinctrl-pxa910.c
+++ b/drivers/pinctrl/pinctrl-pxa910.c
@@ -976,7 +976,7 @@ static int __devinit pxa910_pinmux_probe(struct platform_device *pdev)
return pxa3xx_pinctrl_register(pdev, &pxa910_info);
}
-static int __devexit pxa910_pinmux_remove(struct platform_device *pdev)
+static int pxa910_pinmux_remove(struct platform_device *pdev)
{
return pxa3xx_pinctrl_unregister(pdev);
}
@@ -987,7 +987,7 @@ static struct platform_driver pxa910_pinmux_driver = {
.owner = THIS_MODULE,
},
.probe = pxa910_pinmux_probe,
- .remove = __devexit_p(pxa910_pinmux_remove),
+ .remove = pxa910_pinmux_remove,
};
static int __init pxa910_pinmux_init(void)
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 726a729a2ec..79642831bba 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -30,6 +30,7 @@
#define PCS_MUX_BITS_NAME "pinctrl-single,bits"
#define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1)
#define PCS_OFF_DISABLED ~0U
+#define PCS_MAX_GPIO_VALUES 2
/**
* struct pcs_pingroup - pingroups for a function
@@ -77,6 +78,16 @@ struct pcs_function {
};
/**
+ * struct pcs_gpio_range - pinctrl gpio range
+ * @range: subrange of the GPIO number space
+ * @gpio_func: gpio function value in the pinmux register
+ */
+struct pcs_gpio_range {
+ struct pinctrl_gpio_range range;
+ int gpio_func;
+};
+
+/**
* struct pcs_data - wrapper for data needed by pinctrl framework
* @pa: pindesc array
* @cur: index to current element
@@ -244,15 +255,15 @@ static int pcs_get_group_pins(struct pinctrl_dev *pctldev,
static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s,
- unsigned offset)
+ unsigned pin)
{
struct pcs_device *pcs;
- unsigned val;
+ unsigned val, mux_bytes;
pcs = pinctrl_dev_get_drvdata(pctldev);
- val = pcs->read(pcs->base + offset);
- val &= pcs->fmask;
+ mux_bytes = pcs->width / BITS_PER_BYTE;
+ val = pcs->read(pcs->base + pin * mux_bytes);
seq_printf(s, "%08x %s " , val, DRIVER_NAME);
}
@@ -403,9 +414,26 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector,
}
static int pcs_request_gpio(struct pinctrl_dev *pctldev,
- struct pinctrl_gpio_range *range, unsigned offset)
+ struct pinctrl_gpio_range *range, unsigned pin)
{
- return -ENOTSUPP;
+ struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+ struct pcs_gpio_range *gpio = NULL;
+ int end, mux_bytes;
+ unsigned data;
+
+ gpio = container_of(range, struct pcs_gpio_range, range);
+ end = range->pin_base + range->npins - 1;
+ if (pin < range->pin_base || pin > end) {
+ dev_err(pctldev->dev,
+ "pin %d isn't in the range of %d to %d\n",
+ pin, range->pin_base, end);
+ return -EINVAL;
+ }
+ mux_bytes = pcs->width / BITS_PER_BYTE;
+ data = pcs->read(pcs->base + pin * mux_bytes) & ~pcs->fmask;
+ data |= gpio->gpio_func;
+ pcs->write(data, pcs->base + pin * mux_bytes);
+ return 0;
}
static struct pinmux_ops pcs_pinmux_ops = {
@@ -772,7 +800,7 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev,
pcs = pinctrl_dev_get_drvdata(pctldev);
*map = devm_kzalloc(pcs->dev, sizeof(**map), GFP_KERNEL);
- if (!map)
+ if (!*map)
return -ENOMEM;
*num_maps = 0;
@@ -879,6 +907,50 @@ static void pcs_free_resources(struct pcs_device *pcs)
static struct of_device_id pcs_of_match[];
+static int __devinit pcs_add_gpio_range(struct device_node *node,
+ struct pcs_device *pcs)
+{
+ struct pcs_gpio_range *gpio;
+ struct device_node *child;
+ struct resource r;
+ const char name[] = "pinctrl-single";
+ u32 gpiores[PCS_MAX_GPIO_VALUES];
+ int ret, i = 0, mux_bytes = 0;
+
+ for_each_child_of_node(node, child) {
+ ret = of_address_to_resource(child, 0, &r);
+ if (ret < 0)
+ continue;
+ memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES);
+ ret = of_property_read_u32_array(child, "pinctrl-single,gpio",
+ gpiores, PCS_MAX_GPIO_VALUES);
+ if (ret < 0)
+ continue;
+ gpio = devm_kzalloc(pcs->dev, sizeof(*gpio), GFP_KERNEL);
+ if (!gpio) {
+ dev_err(pcs->dev, "failed to allocate pcs gpio\n");
+ return -ENOMEM;
+ }
+ gpio->range.name = devm_kzalloc(pcs->dev, sizeof(name),
+ GFP_KERNEL);
+ if (!gpio->range.name) {
+ dev_err(pcs->dev, "failed to allocate range name\n");
+ return -ENOMEM;
+ }
+ memcpy((char *)gpio->range.name, name, sizeof(name));
+
+ gpio->range.id = i++;
+ gpio->range.base = gpiores[0];
+ gpio->gpio_func = gpiores[1];
+ mux_bytes = pcs->width / BITS_PER_BYTE;
+ gpio->range.pin_base = (r.start - pcs->res->start) / mux_bytes;
+ gpio->range.npins = (r.end - r.start) / mux_bytes + 1;
+
+ pinctrl_add_gpio_range(pcs->pctl, &gpio->range);
+ }
+ return 0;
+}
+
static int __devinit pcs_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -975,6 +1047,10 @@ static int __devinit pcs_probe(struct platform_device *pdev)
goto free;
}
+ ret = pcs_add_gpio_range(np, pcs);
+ if (ret < 0)
+ goto free;
+
dev_info(pcs->dev, "%i pins at pa %p size %u\n",
pcs->desc.npins, pcs->base, pcs->size);
@@ -986,7 +1062,7 @@ free:
return ret;
}
-static int __devexit pcs_remove(struct platform_device *pdev)
+static int pcs_remove(struct platform_device *pdev)
{
struct pcs_device *pcs = platform_get_drvdata(pdev);
@@ -998,7 +1074,7 @@ static int __devexit pcs_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id pcs_of_match[] __devinitdata = {
+static struct of_device_id pcs_of_match[] = {
{ .compatible = DRIVER_NAME, },
{ },
};
@@ -1006,7 +1082,7 @@ MODULE_DEVICE_TABLE(of, pcs_of_match);
static struct platform_driver pcs_driver = {
.probe = pcs_probe,
- .remove = __devexit_p(pcs_remove),
+ .remove = pcs_remove,
.driver = {
.owner = THIS_MODULE,
.name = DRIVER_NAME,
diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c
index 9ecacf3d0a7..a4f0c5e487d 100644
--- a/drivers/pinctrl/pinctrl-sirf.c
+++ b/drivers/pinctrl/pinctrl-sirf.c
@@ -32,10 +32,10 @@
#define SIRFSOC_NUM_PADS 622
#define SIRFSOC_RSC_PIN_MUX 0x4
-#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84)
+#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84)
+#define SIRFSOC_GPIO_PAD_EN_CLR(g) ((g)*0x100 + 0x90)
#define SIRFSOC_GPIO_CTRL(g, i) ((g)*0x100 + (i)*4)
#define SIRFSOC_GPIO_DSP_EN0 (0x80)
-#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84)
#define SIRFSOC_GPIO_INT_STATUS(g) ((g)*0x100 + 0x8C)
#define SIRFSOC_GPIO_CTL_INTR_LOW_MASK 0x1
@@ -60,6 +60,7 @@ struct sirfsoc_gpio_bank {
int id;
int parent_irq;
spinlock_t lock;
+ bool is_marco; /* for marco, some registers are different with prima2 */
};
static struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS];
@@ -191,6 +192,7 @@ struct sirfsoc_pmx {
struct pinctrl_dev *pmx;
void __iomem *gpio_virtbase;
void __iomem *rsc_virtbase;
+ bool is_marco;
};
/* SIRFSOC_GPIO_PAD_EN set */
@@ -1088,12 +1090,21 @@ static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, unsigned selector
for (i = 0; i < mux->muxmask_counts; i++) {
u32 muxval;
- muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
- if (enable)
- muxval = muxval & ~mask[i].mask;
- else
- muxval = muxval | mask[i].mask;
- writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
+ if (!spmx->is_marco) {
+ muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
+ if (enable)
+ muxval = muxval & ~mask[i].mask;
+ else
+ muxval = muxval | mask[i].mask;
+ writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
+ } else {
+ if (enable)
+ writel(mask[i].mask, spmx->gpio_virtbase +
+ SIRFSOC_GPIO_PAD_EN_CLR(mask[i].group));
+ else
+ writel(mask[i].mask, spmx->gpio_virtbase +
+ SIRFSOC_GPIO_PAD_EN(mask[i].group));
+ }
}
if (mux->funcmask && enable) {
@@ -1158,9 +1169,14 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
spmx = pinctrl_dev_get_drvdata(pmxdev);
- muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
- muxval = muxval | (1 << (offset - range->pin_base));
- writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
+ if (!spmx->is_marco) {
+ muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
+ muxval = muxval | (1 << (offset - range->pin_base));
+ writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
+ } else {
+ writel(1 << (offset - range->pin_base), spmx->gpio_virtbase +
+ SIRFSOC_GPIO_PAD_EN(group));
+ }
return 0;
}
@@ -1218,6 +1234,7 @@ static void __iomem *sirfsoc_rsc_of_iomap(void)
{
const struct of_device_id rsc_ids[] = {
{ .compatible = "sirf,prima2-rsc" },
+ { .compatible = "sirf,marco-rsc" },
{}
};
struct device_node *np;
@@ -1259,6 +1276,9 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev)
goto out_no_rsc_remap;
}
+ if (of_device_is_compatible(np, "sirf,marco-pinctrl"))
+ spmx->is_marco = 1;
+
/* Now register the pin controller and all pins it handles */
spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx);
if (!spmx->pmx) {
@@ -1285,8 +1305,9 @@ out_no_gpio_remap:
return ret;
}
-static const struct of_device_id pinmux_ids[] __devinitconst = {
+static const struct of_device_id pinmux_ids[] = {
{ .compatible = "sirf,prima2-pinctrl" },
+ { .compatible = "sirf,marco-pinctrl" },
{}
};
@@ -1621,8 +1642,8 @@ static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset,
spin_unlock_irqrestore(&bank->lock, flags);
}
-int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq,
- irq_hw_number_t hwirq)
+static int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq)
{
struct sirfsoc_gpio_bank *bank = d->host_data;
@@ -1648,6 +1669,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np)
struct sirfsoc_gpio_bank *bank;
void *regs;
struct platform_device *pdev;
+ bool is_marco = false;
pdev = of_find_device_by_node(np);
if (!pdev)
@@ -1657,6 +1679,9 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np)
if (!regs)
return -ENOMEM;
+ if (of_device_is_compatible(np, "sirf,marco-pinctrl"))
+ is_marco = 1;
+
for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
bank = &sgpio_bank[i];
spin_lock_init(&bank->lock);
@@ -1673,6 +1698,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np)
bank->chip.gc.of_node = np;
bank->chip.regs = regs;
bank->id = i;
+ bank->is_marco = is_marco;
bank->parent_irq = platform_get_irq(pdev, i);
if (bank->parent_irq < 0) {
err = bank->parent_irq;
diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c
index 7da0b371fd6..e356b0380fa 100644
--- a/drivers/pinctrl/pinctrl-tegra.c
+++ b/drivers/pinctrl/pinctrl-tegra.c
@@ -178,8 +178,9 @@ static int add_config(struct device *dev, unsigned long **configs,
return 0;
}
-void tegra_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
- struct pinctrl_map *map, unsigned num_maps)
+static void tegra_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *map,
+ unsigned num_maps)
{
int i;
@@ -209,11 +210,11 @@ static const struct cfg_param {
{"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING},
};
-int tegra_pinctrl_dt_subnode_to_map(struct device *dev,
- struct device_node *np,
- struct pinctrl_map **map,
- unsigned *reserved_maps,
- unsigned *num_maps)
+static int tegra_pinctrl_dt_subnode_to_map(struct device *dev,
+ struct device_node *np,
+ struct pinctrl_map **map,
+ unsigned *reserved_maps,
+ unsigned *num_maps)
{
int ret, i;
const char *function;
@@ -288,9 +289,10 @@ exit:
return ret;
}
-int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
- struct device_node *np_config,
- struct pinctrl_map **map, unsigned *num_maps)
+static int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np_config,
+ struct pinctrl_map **map,
+ unsigned *num_maps)
{
unsigned reserved_maps;
struct device_node *np;
@@ -660,7 +662,7 @@ static void tegra_pinconf_config_dbg_show(struct pinctrl_dev *pctldev,
}
#endif
-struct pinconf_ops tegra_pinconf_ops = {
+static struct pinconf_ops tegra_pinconf_ops = {
.pin_config_get = tegra_pinconf_get,
.pin_config_set = tegra_pinconf_set,
.pin_config_group_get = tegra_pinconf_group_get,
@@ -758,7 +760,7 @@ int __devinit tegra_pinctrl_probe(struct platform_device *pdev,
}
EXPORT_SYMBOL_GPL(tegra_pinctrl_probe);
-int __devexit tegra_pinctrl_remove(struct platform_device *pdev)
+int tegra_pinctrl_remove(struct platform_device *pdev)
{
struct tegra_pmx *pmx = platform_get_drvdata(pdev);
diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c
index a74f9a56853..1524bfd6660 100644
--- a/drivers/pinctrl/pinctrl-tegra20.c
+++ b/drivers/pinctrl/pinctrl-tegra20.c
@@ -2861,7 +2861,7 @@ static int __devinit tegra20_pinctrl_probe(struct platform_device *pdev)
return tegra_pinctrl_probe(pdev, &tegra20_pinctrl);
}
-static struct of_device_id tegra20_pinctrl_of_match[] __devinitdata = {
+static struct of_device_id tegra20_pinctrl_of_match[] = {
{ .compatible = "nvidia,tegra20-pinmux", },
{ },
};
@@ -2873,7 +2873,7 @@ static struct platform_driver tegra20_pinctrl_driver = {
.of_match_table = tegra20_pinctrl_of_match,
},
.probe = tegra20_pinctrl_probe,
- .remove = __devexit_p(tegra_pinctrl_remove),
+ .remove = tegra_pinctrl_remove,
};
static int __init tegra20_pinctrl_init(void)
diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c
index 7894f14c705..cf579ebf346 100644
--- a/drivers/pinctrl/pinctrl-tegra30.c
+++ b/drivers/pinctrl/pinctrl-tegra30.c
@@ -3727,7 +3727,7 @@ static int __devinit tegra30_pinctrl_probe(struct platform_device *pdev)
return tegra_pinctrl_probe(pdev, &tegra30_pinctrl);
}
-static struct of_device_id tegra30_pinctrl_of_match[] __devinitdata = {
+static struct of_device_id tegra30_pinctrl_of_match[] = {
{ .compatible = "nvidia,tegra30-pinmux", },
{ },
};
@@ -3739,7 +3739,7 @@ static struct platform_driver tegra30_pinctrl_driver = {
.of_match_table = tegra30_pinctrl_of_match,
},
.probe = tegra30_pinctrl_probe,
- .remove = __devexit_p(tegra_pinctrl_remove),
+ .remove = tegra_pinctrl_remove,
};
static int __init tegra30_pinctrl_init(void)
diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c
index 309f5b9a70e..8c039ad22ba 100644
--- a/drivers/pinctrl/pinctrl-u300.c
+++ b/drivers/pinctrl/pinctrl-u300.c
@@ -663,8 +663,6 @@ static const struct pinctrl_pin_desc u300_pads[] = {
struct u300_pmx {
struct device *dev;
struct pinctrl_dev *pctl;
- u32 phybase;
- u32 physize;
void __iomem *virtbase;
};
@@ -1013,52 +1011,11 @@ static struct pinmux_ops u300_pmx_ops = {
.disable = u300_pmx_disable,
};
-/*
- * GPIO ranges handled by the application-side COH901XXX GPIO controller
- * Very many pins can be converted into GPIO pins, but we only list those
- * that are useful in practice to cut down on tables.
- */
-#define U300_GPIO_RANGE(a, b, c) { .name = "COH901XXX", .id = a, .base= a, \
- .pin_base = b, .npins = c }
-
-static struct pinctrl_gpio_range u300_gpio_ranges[] = {
- U300_GPIO_RANGE(10, 426, 1),
- U300_GPIO_RANGE(11, 180, 1),
- U300_GPIO_RANGE(12, 165, 1), /* MS/MMC card insertion */
- U300_GPIO_RANGE(13, 179, 1),
- U300_GPIO_RANGE(14, 178, 1),
- U300_GPIO_RANGE(16, 194, 1),
- U300_GPIO_RANGE(17, 193, 1),
- U300_GPIO_RANGE(18, 192, 1),
- U300_GPIO_RANGE(19, 191, 1),
- U300_GPIO_RANGE(20, 186, 1),
- U300_GPIO_RANGE(21, 185, 1),
- U300_GPIO_RANGE(22, 184, 1),
- U300_GPIO_RANGE(23, 183, 1),
- U300_GPIO_RANGE(24, 182, 1),
- U300_GPIO_RANGE(25, 181, 1),
-};
-
-static struct pinctrl_gpio_range *u300_match_gpio_range(unsigned pin)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) {
- struct pinctrl_gpio_range *range;
-
- range = &u300_gpio_ranges[i];
- if (pin >= range->pin_base &&
- pin <= (range->pin_base + range->npins - 1))
- return range;
- }
- return NULL;
-}
-
-int u300_pin_config_get(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long *config)
+static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
+ unsigned long *config)
{
- struct pinctrl_gpio_range *range = u300_match_gpio_range(pin);
+ struct pinctrl_gpio_range *range =
+ pinctrl_find_gpio_range_from_pin(pctldev, pin);
/* We get config for those pins we CAN get it for and that's it */
if (!range)
@@ -1069,11 +1026,11 @@ int u300_pin_config_get(struct pinctrl_dev *pctldev,
config);
}
-int u300_pin_config_set(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long config)
+static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
+ unsigned long config)
{
- struct pinctrl_gpio_range *range = u300_match_gpio_range(pin);
+ struct pinctrl_gpio_range *range =
+ pinctrl_find_gpio_range_from_pin(pctldev, pin);
int ret;
if (!range)
@@ -1109,9 +1066,6 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev)
{
struct u300_pmx *upmx;
struct resource *res;
- struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev);
- int ret;
- int i;
/* Create state holders etc for this driver */
upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL);
@@ -1123,32 +1077,15 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENOENT;
- upmx->phybase = res->start;
- upmx->physize = resource_size(res);
-
- if (request_mem_region(upmx->phybase, upmx->physize,
- DRIVER_NAME) == NULL) {
- ret = -ENOMEM;
- goto out_no_memregion;
- }
- upmx->virtbase = ioremap(upmx->phybase, upmx->physize);
- if (!upmx->virtbase) {
- ret = -ENOMEM;
- goto out_no_remap;
- }
+ upmx->virtbase = devm_request_and_ioremap(&pdev->dev, res);
+ if (!upmx->virtbase)
+ return -ENOMEM;
upmx->pctl = pinctrl_register(&u300_pmx_desc, &pdev->dev, upmx);
if (!upmx->pctl) {
dev_err(&pdev->dev, "could not register U300 pinmux driver\n");
- ret = -EINVAL;
- goto out_no_pmx;
- }
-
- /* We will handle a range of GPIO pins */
- for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) {
- u300_gpio_ranges[i].gc = gpio_chip;
- pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]);
+ return -EINVAL;
}
platform_set_drvdata(pdev, upmx);
@@ -1156,23 +1093,13 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "initialized U300 pin control driver\n");
return 0;
-
-out_no_pmx:
- iounmap(upmx->virtbase);
-out_no_remap:
- platform_set_drvdata(pdev, NULL);
-out_no_memregion:
- release_mem_region(upmx->phybase, upmx->physize);
- return ret;
}
-static int __devexit u300_pmx_remove(struct platform_device *pdev)
+static int u300_pmx_remove(struct platform_device *pdev)
{
struct u300_pmx *upmx = platform_get_drvdata(pdev);
pinctrl_unregister(upmx->pctl);
- iounmap(upmx->virtbase);
- release_mem_region(upmx->phybase, upmx->physize);
platform_set_drvdata(pdev, NULL);
return 0;
@@ -1184,7 +1111,7 @@ static struct platform_driver u300_pmx_driver = {
.owner = THIS_MODULE,
},
.probe = u300_pmx_probe,
- .remove = __devexit_p(u300_pmx_remove),
+ .remove = u300_pmx_remove,
};
static int __init u300_pmx_init(void)
diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c
index b9bcaec6622..ad90984ec50 100644
--- a/drivers/pinctrl/pinctrl-xway.c
+++ b/drivers/pinctrl/pinctrl-xway.c
@@ -522,7 +522,7 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev,
return 0;
}
-struct pinconf_ops xway_pinconf_ops = {
+static struct pinconf_ops xway_pinconf_ops = {
.pin_config_get = xway_pinconf_get,
.pin_config_set = xway_pinconf_set,
};
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 9301a7a95ef..1a00658b3ea 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -314,14 +314,11 @@ int pinmux_map_to_setting(struct pinctrl_map const *map,
{
struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
- const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
char const * const *groups;
unsigned num_groups;
int ret;
const char *group;
int i;
- const unsigned *pins;
- unsigned num_pins;
if (!pmxops) {
dev_err(pctldev->dev, "does not support mux function\n");
@@ -376,53 +373,12 @@ int pinmux_map_to_setting(struct pinctrl_map const *map,
}
setting->data.mux.group = ret;
- ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, &pins,
- &num_pins);
- if (ret) {
- dev_err(pctldev->dev,
- "could not get pins for device %s group selector %d\n",
- pinctrl_dev_get_name(pctldev), setting->data.mux.group);
- return -ENODEV;
- }
-
- /* Try to allocate all pins in this group, one by one */
- for (i = 0; i < num_pins; i++) {
- ret = pin_request(pctldev, pins[i], map->dev_name, NULL);
- if (ret) {
- dev_err(pctldev->dev,
- "could not request pin %d on device %s\n",
- pins[i], pinctrl_dev_get_name(pctldev));
- /* On error release all taken pins */
- i--; /* this pin just failed */
- for (; i >= 0; i--)
- pin_free(pctldev, pins[i], NULL);
- return -ENODEV;
- }
- }
-
return 0;
}
void pinmux_free_setting(struct pinctrl_setting const *setting)
{
- struct pinctrl_dev *pctldev = setting->pctldev;
- const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
- const unsigned *pins;
- unsigned num_pins;
- int ret;
- int i;
-
- ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
- &pins, &num_pins);
- if (ret) {
- dev_err(pctldev->dev,
- "could not get pins for device %s group selector %d\n",
- pinctrl_dev_get_name(pctldev), setting->data.mux.group);
- return;
- }
-
- for (i = 0; i < num_pins; i++)
- pin_free(pctldev, pins[i], NULL);
+ /* This function is currently unused */
}
int pinmux_enable_setting(struct pinctrl_setting const *setting)
@@ -446,6 +402,18 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting)
num_pins = 0;
}
+ /* Try to allocate all pins in this group, one by one */
+ for (i = 0; i < num_pins; i++) {
+ ret = pin_request(pctldev, pins[i], setting->dev_name, NULL);
+ if (ret) {
+ dev_err(pctldev->dev,
+ "could not request pin %d on device %s\n",
+ pins[i], pinctrl_dev_get_name(pctldev));
+ goto err_pin_request;
+ }
+ }
+
+ /* Now that we have acquired the pins, encode the mux setting */
for (i = 0; i < num_pins; i++) {
desc = pin_desc_get(pctldev, pins[i]);
if (desc == NULL) {
@@ -457,8 +425,26 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting)
desc->mux_setting = &(setting->data.mux);
}
- return ops->enable(pctldev, setting->data.mux.func,
- setting->data.mux.group);
+ ret = ops->enable(pctldev, setting->data.mux.func,
+ setting->data.mux.group);
+
+ if (ret)
+ goto err_enable;
+
+ return 0;
+
+err_enable:
+ for (i = 0; i < num_pins; i++) {
+ desc = pin_desc_get(pctldev, pins[i]);
+ if (desc)
+ desc->mux_setting = NULL;
+ }
+err_pin_request:
+ /* On error release all taken pins */
+ while (--i >= 0)
+ pin_free(pctldev, pins[i], NULL);
+
+ return ret;
}
void pinmux_disable_setting(struct pinctrl_setting const *setting)
@@ -482,6 +468,7 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
num_pins = 0;
}
+ /* Flag the descs that no setting is active */
for (i = 0; i < num_pins; i++) {
desc = pin_desc_get(pctldev, pins[i]);
if (desc == NULL) {
@@ -493,6 +480,10 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
desc->mux_setting = NULL;
}
+ /* And release the pins */
+ for (i = 0; i < num_pins; i++)
+ pin_free(pctldev, pins[i], NULL);
+
if (ops->disable)
ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group);
}
diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig
index 91558791e76..04d93e60267 100644
--- a/drivers/pinctrl/spear/Kconfig
+++ b/drivers/pinctrl/spear/Kconfig
@@ -25,20 +25,31 @@ config PINCTRL_SPEAR310
bool "ST Microelectronics SPEAr310 SoC pin controller driver"
depends on MACH_SPEAR310
select PINCTRL_SPEAR3XX
+ select PINCTRL_SPEAR_PLGPIO
config PINCTRL_SPEAR320
bool "ST Microelectronics SPEAr320 SoC pin controller driver"
depends on MACH_SPEAR320
select PINCTRL_SPEAR3XX
+ select PINCTRL_SPEAR_PLGPIO
config PINCTRL_SPEAR1310
bool "ST Microelectronics SPEAr1310 SoC pin controller driver"
depends on MACH_SPEAR1310
select PINCTRL_SPEAR
+ select PINCTRL_SPEAR_PLGPIO
config PINCTRL_SPEAR1340
bool "ST Microelectronics SPEAr1340 SoC pin controller driver"
depends on MACH_SPEAR1340
select PINCTRL_SPEAR
+ select PINCTRL_SPEAR_PLGPIO
+
+config PINCTRL_SPEAR_PLGPIO
+ bool "SPEAr SoC PLGPIO Controller"
+ depends on GPIOLIB && PINCTRL_SPEAR
+ help
+ Say yes here to support PLGPIO controller on ST Microelectronics SPEAr
+ SoCs.
endif
diff --git a/drivers/pinctrl/spear/Makefile b/drivers/pinctrl/spear/Makefile
index b28a7ba2244..0e400ebeb8f 100644
--- a/drivers/pinctrl/spear/Makefile
+++ b/drivers/pinctrl/spear/Makefile
@@ -1,5 +1,6 @@
# SPEAr pinmux support
+obj-$(CONFIG_PINCTRL_SPEAR_PLGPIO) += pinctrl-plgpio.o
obj-$(CONFIG_PINCTRL_SPEAR) += pinctrl-spear.o
obj-$(CONFIG_PINCTRL_SPEAR3XX) += pinctrl-spear3xx.o
obj-$(CONFIG_PINCTRL_SPEAR300) += pinctrl-spear300.o
diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c
new file mode 100644
index 00000000000..4c045053bbd
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-plgpio.c
@@ -0,0 +1,758 @@
+/*
+ * SPEAr platform PLGPIO driver
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@linaro.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/spinlock.h>
+#include <asm/mach/irq.h>
+
+#define MAX_GPIO_PER_REG 32
+#define PIN_OFFSET(pin) (pin % MAX_GPIO_PER_REG)
+#define REG_OFFSET(base, reg, pin) (base + reg + (pin / MAX_GPIO_PER_REG) \
+ * sizeof(int *))
+
+/*
+ * plgpio pins in all machines are not one to one mapped, bitwise with registers
+ * bits. These set of macros define register masks for which below functions
+ * (pin_to_offset and offset_to_pin) are required to be called.
+ */
+#define PTO_ENB_REG 0x001
+#define PTO_WDATA_REG 0x002
+#define PTO_DIR_REG 0x004
+#define PTO_IE_REG 0x008
+#define PTO_RDATA_REG 0x010
+#define PTO_MIS_REG 0x020
+
+struct plgpio_regs {
+ u32 enb; /* enable register */
+ u32 wdata; /* write data register */
+ u32 dir; /* direction set register */
+ u32 rdata; /* read data register */
+ u32 ie; /* interrupt enable register */
+ u32 mis; /* mask interrupt status register */
+ u32 eit; /* edge interrupt type */
+};
+
+/*
+ * struct plgpio: plgpio driver specific structure
+ *
+ * lock: lock for guarding gpio registers
+ * base: base address of plgpio block
+ * irq_base: irq number of plgpio0
+ * chip: gpio framework specific chip information structure
+ * p2o: function ptr for pin to offset conversion. This is required only for
+ * machines where mapping b/w pin and offset is not 1-to-1.
+ * o2p: function ptr for offset to pin conversion. This is required only for
+ * machines where mapping b/w pin and offset is not 1-to-1.
+ * p2o_regs: mask of registers for which p2o and o2p are applicable
+ * regs: register offsets
+ * csave_regs: context save registers for standby/sleep/hibernate cases
+ */
+struct plgpio {
+ spinlock_t lock;
+ void __iomem *base;
+ struct clk *clk;
+ unsigned irq_base;
+ struct irq_domain *irq_domain;
+ struct gpio_chip chip;
+ int (*p2o)(int pin); /* pin_to_offset */
+ int (*o2p)(int offset); /* offset_to_pin */
+ u32 p2o_regs;
+ struct plgpio_regs regs;
+#ifdef CONFIG_PM
+ struct plgpio_regs *csave_regs;
+#endif
+};
+
+/* register manipulation inline functions */
+static inline u32 is_plgpio_set(void __iomem *base, u32 pin, u32 reg)
+{
+ u32 offset = PIN_OFFSET(pin);
+ void __iomem *reg_off = REG_OFFSET(base, reg, pin);
+ u32 val = readl_relaxed(reg_off);
+
+ return !!(val & (1 << offset));
+}
+
+static inline void plgpio_reg_set(void __iomem *base, u32 pin, u32 reg)
+{
+ u32 offset = PIN_OFFSET(pin);
+ void __iomem *reg_off = REG_OFFSET(base, reg, pin);
+ u32 val = readl_relaxed(reg_off);
+
+ writel_relaxed(val | (1 << offset), reg_off);
+}
+
+static inline void plgpio_reg_reset(void __iomem *base, u32 pin, u32 reg)
+{
+ u32 offset = PIN_OFFSET(pin);
+ void __iomem *reg_off = REG_OFFSET(base, reg, pin);
+ u32 val = readl_relaxed(reg_off);
+
+ writel_relaxed(val & ~(1 << offset), reg_off);
+}
+
+/* gpio framework specific routines */
+static int plgpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+ unsigned long flags;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & PTO_DIR_REG)) {
+ offset = plgpio->p2o(offset);
+ if (offset == -1)
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&plgpio->lock, flags);
+ plgpio_reg_set(plgpio->base, offset, plgpio->regs.dir);
+ spin_unlock_irqrestore(&plgpio->lock, flags);
+
+ return 0;
+}
+
+static int plgpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+ unsigned long flags;
+ unsigned dir_offset = offset, wdata_offset = offset, tmp;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & (PTO_DIR_REG | PTO_WDATA_REG))) {
+ tmp = plgpio->p2o(offset);
+ if (tmp == -1)
+ return -EINVAL;
+
+ if (plgpio->p2o_regs & PTO_DIR_REG)
+ dir_offset = tmp;
+ if (plgpio->p2o_regs & PTO_WDATA_REG)
+ wdata_offset = tmp;
+ }
+
+ spin_lock_irqsave(&plgpio->lock, flags);
+ if (value)
+ plgpio_reg_set(plgpio->base, wdata_offset,
+ plgpio->regs.wdata);
+ else
+ plgpio_reg_reset(plgpio->base, wdata_offset,
+ plgpio->regs.wdata);
+
+ plgpio_reg_reset(plgpio->base, dir_offset, plgpio->regs.dir);
+ spin_unlock_irqrestore(&plgpio->lock, flags);
+
+ return 0;
+}
+
+static int plgpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+ struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+
+ if (offset >= chip->ngpio)
+ return -EINVAL;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & PTO_RDATA_REG)) {
+ offset = plgpio->p2o(offset);
+ if (offset == -1)
+ return -EINVAL;
+ }
+
+ return is_plgpio_set(plgpio->base, offset, plgpio->regs.rdata);
+}
+
+static void plgpio_set_value(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+
+ if (offset >= chip->ngpio)
+ return;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & PTO_WDATA_REG)) {
+ offset = plgpio->p2o(offset);
+ if (offset == -1)
+ return;
+ }
+
+ if (value)
+ plgpio_reg_set(plgpio->base, offset, plgpio->regs.wdata);
+ else
+ plgpio_reg_reset(plgpio->base, offset, plgpio->regs.wdata);
+}
+
+static int plgpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+ int gpio = chip->base + offset;
+ unsigned long flags;
+ int ret = 0;
+
+ if (offset >= chip->ngpio)
+ return -EINVAL;
+
+ ret = pinctrl_request_gpio(gpio);
+ if (ret)
+ return ret;
+
+ if (!IS_ERR(plgpio->clk)) {
+ ret = clk_enable(plgpio->clk);
+ if (ret)
+ goto err0;
+ }
+
+ if (plgpio->regs.enb == -1)
+ return 0;
+
+ /*
+ * put gpio in IN mode before enabling it. This make enabling gpio safe
+ */
+ ret = plgpio_direction_input(chip, offset);
+ if (ret)
+ goto err1;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) {
+ offset = plgpio->p2o(offset);
+ if (offset == -1) {
+ ret = -EINVAL;
+ goto err1;
+ }
+ }
+
+ spin_lock_irqsave(&plgpio->lock, flags);
+ plgpio_reg_set(plgpio->base, offset, plgpio->regs.enb);
+ spin_unlock_irqrestore(&plgpio->lock, flags);
+ return 0;
+
+err1:
+ if (!IS_ERR(plgpio->clk))
+ clk_disable(plgpio->clk);
+err0:
+ pinctrl_free_gpio(gpio);
+ return ret;
+}
+
+static void plgpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+ int gpio = chip->base + offset;
+ unsigned long flags;
+
+ if (offset >= chip->ngpio)
+ return;
+
+ if (plgpio->regs.enb == -1)
+ goto disable_clk;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) {
+ offset = plgpio->p2o(offset);
+ if (offset == -1)
+ return;
+ }
+
+ spin_lock_irqsave(&plgpio->lock, flags);
+ plgpio_reg_reset(plgpio->base, offset, plgpio->regs.enb);
+ spin_unlock_irqrestore(&plgpio->lock, flags);
+
+disable_clk:
+ if (!IS_ERR(plgpio->clk))
+ clk_disable(plgpio->clk);
+
+ pinctrl_free_gpio(gpio);
+}
+
+static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+
+ if (IS_ERR_VALUE(plgpio->irq_base))
+ return -EINVAL;
+
+ return irq_find_mapping(plgpio->irq_domain, offset);
+}
+
+/* PLGPIO IRQ */
+static void plgpio_irq_disable(struct irq_data *d)
+{
+ struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - plgpio->irq_base;
+ unsigned long flags;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) {
+ offset = plgpio->p2o(offset);
+ if (offset == -1)
+ return;
+ }
+
+ spin_lock_irqsave(&plgpio->lock, flags);
+ plgpio_reg_set(plgpio->base, offset, plgpio->regs.ie);
+ spin_unlock_irqrestore(&plgpio->lock, flags);
+}
+
+static void plgpio_irq_enable(struct irq_data *d)
+{
+ struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - plgpio->irq_base;
+ unsigned long flags;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) {
+ offset = plgpio->p2o(offset);
+ if (offset == -1)
+ return;
+ }
+
+ spin_lock_irqsave(&plgpio->lock, flags);
+ plgpio_reg_reset(plgpio->base, offset, plgpio->regs.ie);
+ spin_unlock_irqrestore(&plgpio->lock, flags);
+}
+
+static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger)
+{
+ struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - plgpio->irq_base;
+ void __iomem *reg_off;
+ unsigned int supported_type = 0, val;
+
+ if (offset >= plgpio->chip.ngpio)
+ return -EINVAL;
+
+ if (plgpio->regs.eit == -1)
+ supported_type = IRQ_TYPE_LEVEL_HIGH;
+ else
+ supported_type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+
+ if (!(trigger & supported_type))
+ return -EINVAL;
+
+ if (plgpio->regs.eit == -1)
+ return 0;
+
+ reg_off = REG_OFFSET(plgpio->base, plgpio->regs.eit, offset);
+ val = readl_relaxed(reg_off);
+
+ offset = PIN_OFFSET(offset);
+ if (trigger & IRQ_TYPE_EDGE_RISING)
+ writel_relaxed(val | (1 << offset), reg_off);
+ else
+ writel_relaxed(val & ~(1 << offset), reg_off);
+
+ return 0;
+}
+
+static struct irq_chip plgpio_irqchip = {
+ .name = "PLGPIO",
+ .irq_enable = plgpio_irq_enable,
+ .irq_disable = plgpio_irq_disable,
+ .irq_set_type = plgpio_irq_set_type,
+};
+
+static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+ struct plgpio *plgpio = irq_get_handler_data(irq);
+ struct irq_chip *irqchip = irq_desc_get_chip(desc);
+ int regs_count, count, pin, offset, i = 0;
+ unsigned long pending;
+
+ count = plgpio->chip.ngpio;
+ regs_count = DIV_ROUND_UP(count, MAX_GPIO_PER_REG);
+
+ chained_irq_enter(irqchip, desc);
+ /* check all plgpio MIS registers for a possible interrupt */
+ for (; i < regs_count; i++) {
+ pending = readl_relaxed(plgpio->base + plgpio->regs.mis +
+ i * sizeof(int *));
+ if (!pending)
+ continue;
+
+ /* clear interrupts */
+ writel_relaxed(~pending, plgpio->base + plgpio->regs.mis +
+ i * sizeof(int *));
+ /*
+ * clear extra bits in last register having gpios < MAX/REG
+ * ex: Suppose there are max 102 plgpios. then last register
+ * must have only (102 - MAX_GPIO_PER_REG * 3) = 6 relevant bits
+ * so, we must not take other 28 bits into consideration for
+ * checking interrupt. so clear those bits.
+ */
+ count = count - i * MAX_GPIO_PER_REG;
+ if (count < MAX_GPIO_PER_REG)
+ pending &= (1 << count) - 1;
+
+ for_each_set_bit(offset, &pending, MAX_GPIO_PER_REG) {
+ /* get correct pin for "offset" */
+ if (plgpio->o2p && (plgpio->p2o_regs & PTO_MIS_REG)) {
+ pin = plgpio->o2p(offset);
+ if (pin == -1)
+ continue;
+ } else
+ pin = offset;
+
+ /* get correct irq line number */
+ pin = i * MAX_GPIO_PER_REG + pin;
+ generic_handle_irq(plgpio_to_irq(&plgpio->chip, pin));
+ }
+ }
+ chained_irq_exit(irqchip, desc);
+}
+
+/*
+ * pin to offset and offset to pin converter functions
+ *
+ * In spear310 there is inconsistency among bit positions in plgpio regiseters,
+ * for different plgpio pins. For example: for pin 27, bit offset is 23, pin
+ * 28-33 are not supported, pin 95 has offset bit 95, bit 100 has offset bit 1
+ */
+static int spear310_p2o(int pin)
+{
+ int offset = pin;
+
+ if (pin <= 27)
+ offset += 4;
+ else if (pin <= 33)
+ offset = -1;
+ else if (pin <= 97)
+ offset -= 2;
+ else if (pin <= 101)
+ offset = 101 - pin;
+ else
+ offset = -1;
+
+ return offset;
+}
+
+int spear310_o2p(int offset)
+{
+ if (offset <= 3)
+ return 101 - offset;
+ else if (offset <= 31)
+ return offset - 4;
+ else
+ return offset + 2;
+}
+
+static int __devinit plgpio_probe_dt(struct platform_device *pdev,
+ struct plgpio *plgpio)
+{
+ struct device_node *np = pdev->dev.of_node;
+ int ret = -EINVAL;
+ u32 val;
+
+ if (of_machine_is_compatible("st,spear310")) {
+ plgpio->p2o = spear310_p2o;
+ plgpio->o2p = spear310_o2p;
+ plgpio->p2o_regs = PTO_WDATA_REG | PTO_DIR_REG | PTO_IE_REG |
+ PTO_RDATA_REG | PTO_MIS_REG;
+ }
+
+ if (!of_property_read_u32(np, "st-plgpio,ngpio", &val)) {
+ plgpio->chip.ngpio = val;
+ } else {
+ dev_err(&pdev->dev, "DT: Invalid ngpio field\n");
+ goto end;
+ }
+
+ if (!of_property_read_u32(np, "st-plgpio,enb-reg", &val))
+ plgpio->regs.enb = val;
+ else
+ plgpio->regs.enb = -1;
+
+ if (!of_property_read_u32(np, "st-plgpio,wdata-reg", &val)) {
+ plgpio->regs.wdata = val;
+ } else {
+ dev_err(&pdev->dev, "DT: Invalid wdata reg\n");
+ goto end;
+ }
+
+ if (!of_property_read_u32(np, "st-plgpio,dir-reg", &val)) {
+ plgpio->regs.dir = val;
+ } else {
+ dev_err(&pdev->dev, "DT: Invalid dir reg\n");
+ goto end;
+ }
+
+ if (!of_property_read_u32(np, "st-plgpio,ie-reg", &val)) {
+ plgpio->regs.ie = val;
+ } else {
+ dev_err(&pdev->dev, "DT: Invalid ie reg\n");
+ goto end;
+ }
+
+ if (!of_property_read_u32(np, "st-plgpio,rdata-reg", &val)) {
+ plgpio->regs.rdata = val;
+ } else {
+ dev_err(&pdev->dev, "DT: Invalid rdata reg\n");
+ goto end;
+ }
+
+ if (!of_property_read_u32(np, "st-plgpio,mis-reg", &val)) {
+ plgpio->regs.mis = val;
+ } else {
+ dev_err(&pdev->dev, "DT: Invalid mis reg\n");
+ goto end;
+ }
+
+ if (!of_property_read_u32(np, "st-plgpio,eit-reg", &val))
+ plgpio->regs.eit = val;
+ else
+ plgpio->regs.eit = -1;
+
+ return 0;
+
+end:
+ return ret;
+}
+static int __devinit plgpio_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct plgpio *plgpio;
+ struct resource *res;
+ int ret, irq, i;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n");
+ return -EBUSY;
+ }
+
+ plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL);
+ if (!plgpio) {
+ dev_err(&pdev->dev, "memory allocation fail\n");
+ return -ENOMEM;
+ }
+
+ plgpio->base = devm_request_and_ioremap(&pdev->dev, res);
+ if (!plgpio->base) {
+ dev_err(&pdev->dev, "request and ioremap fail\n");
+ return -ENOMEM;
+ }
+
+ ret = plgpio_probe_dt(pdev, plgpio);
+ if (ret) {
+ dev_err(&pdev->dev, "DT probe failed\n");
+ return ret;
+ }
+
+ plgpio->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(plgpio->clk))
+ dev_warn(&pdev->dev, "clk_get() failed, work without it\n");
+
+#ifdef CONFIG_PM
+ plgpio->csave_regs = devm_kzalloc(&pdev->dev,
+ sizeof(*plgpio->csave_regs) *
+ DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG),
+ GFP_KERNEL);
+ if (!plgpio->csave_regs) {
+ dev_err(&pdev->dev, "csave registers memory allocation fail\n");
+ return -ENOMEM;
+ }
+#endif
+
+ platform_set_drvdata(pdev, plgpio);
+ spin_lock_init(&plgpio->lock);
+
+ plgpio->irq_base = -1;
+ plgpio->chip.base = -1;
+ plgpio->chip.request = plgpio_request;
+ plgpio->chip.free = plgpio_free;
+ plgpio->chip.direction_input = plgpio_direction_input;
+ plgpio->chip.direction_output = plgpio_direction_output;
+ plgpio->chip.get = plgpio_get_value;
+ plgpio->chip.set = plgpio_set_value;
+ plgpio->chip.to_irq = plgpio_to_irq;
+ plgpio->chip.label = dev_name(&pdev->dev);
+ plgpio->chip.dev = &pdev->dev;
+ plgpio->chip.owner = THIS_MODULE;
+
+ if (!IS_ERR(plgpio->clk)) {
+ ret = clk_prepare(plgpio->clk);
+ if (ret) {
+ dev_err(&pdev->dev, "clk prepare failed\n");
+ return ret;
+ }
+ }
+
+ ret = gpiochip_add(&plgpio->chip);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to add gpio chip\n");
+ goto unprepare_clk;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_info(&pdev->dev, "irqs not supported\n");
+ return 0;
+ }
+
+ plgpio->irq_base = irq_alloc_descs(-1, 0, plgpio->chip.ngpio, 0);
+ if (IS_ERR_VALUE(plgpio->irq_base)) {
+ /* we would not support irq for gpio */
+ dev_warn(&pdev->dev, "couldn't allocate irq base\n");
+ return 0;
+ }
+
+ plgpio->irq_domain = irq_domain_add_legacy(np, plgpio->chip.ngpio,
+ plgpio->irq_base, 0, &irq_domain_simple_ops, NULL);
+ if (WARN_ON(!plgpio->irq_domain)) {
+ dev_err(&pdev->dev, "irq domain init failed\n");
+ irq_free_descs(plgpio->irq_base, plgpio->chip.ngpio);
+ ret = -ENXIO;
+ goto remove_gpiochip;
+ }
+
+ irq_set_chained_handler(irq, plgpio_irq_handler);
+ for (i = 0; i < plgpio->chip.ngpio; i++) {
+ irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip,
+ handle_simple_irq);
+ set_irq_flags(i + plgpio->irq_base, IRQF_VALID);
+ irq_set_chip_data(i + plgpio->irq_base, plgpio);
+ }
+
+ irq_set_handler_data(irq, plgpio);
+ dev_info(&pdev->dev, "PLGPIO registered with IRQs\n");
+
+ return 0;
+
+remove_gpiochip:
+ dev_info(&pdev->dev, "Remove gpiochip\n");
+ if (gpiochip_remove(&plgpio->chip))
+ dev_err(&pdev->dev, "unable to remove gpiochip\n");
+unprepare_clk:
+ if (!IS_ERR(plgpio->clk))
+ clk_unprepare(plgpio->clk);
+
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static int plgpio_suspend(struct device *dev)
+{
+ struct plgpio *plgpio = dev_get_drvdata(dev);
+ int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG);
+ void __iomem *off;
+
+ for (i = 0; i < reg_count; i++) {
+ off = plgpio->base + i * sizeof(int *);
+
+ if (plgpio->regs.enb != -1)
+ plgpio->csave_regs[i].enb =
+ readl_relaxed(plgpio->regs.enb + off);
+ if (plgpio->regs.eit != -1)
+ plgpio->csave_regs[i].eit =
+ readl_relaxed(plgpio->regs.eit + off);
+ plgpio->csave_regs[i].wdata = readl_relaxed(plgpio->regs.wdata +
+ off);
+ plgpio->csave_regs[i].dir = readl_relaxed(plgpio->regs.dir +
+ off);
+ plgpio->csave_regs[i].ie = readl_relaxed(plgpio->regs.ie + off);
+ }
+
+ return 0;
+}
+
+/*
+ * This is used to correct the values in end registers. End registers contain
+ * extra bits that might be used for other purpose in platform. So, we shouldn't
+ * overwrite these bits. This macro, reads given register again, preserves other
+ * bit values (non-plgpio bits), and retain captured value (plgpio bits).
+ */
+#define plgpio_prepare_reg(__reg, _off, _mask, _tmp) \
+{ \
+ _tmp = readl_relaxed(plgpio->regs.__reg + _off); \
+ _tmp &= ~_mask; \
+ plgpio->csave_regs[i].__reg = \
+ _tmp | (plgpio->csave_regs[i].__reg & _mask); \
+}
+
+static int plgpio_resume(struct device *dev)
+{
+ struct plgpio *plgpio = dev_get_drvdata(dev);
+ int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG);
+ void __iomem *off;
+ u32 mask, tmp;
+
+ for (i = 0; i < reg_count; i++) {
+ off = plgpio->base + i * sizeof(int *);
+
+ if (i == reg_count - 1) {
+ mask = (1 << (plgpio->chip.ngpio - i *
+ MAX_GPIO_PER_REG)) - 1;
+
+ if (plgpio->regs.enb != -1)
+ plgpio_prepare_reg(enb, off, mask, tmp);
+
+ if (plgpio->regs.eit != -1)
+ plgpio_prepare_reg(eit, off, mask, tmp);
+
+ plgpio_prepare_reg(wdata, off, mask, tmp);
+ plgpio_prepare_reg(dir, off, mask, tmp);
+ plgpio_prepare_reg(ie, off, mask, tmp);
+ }
+
+ writel_relaxed(plgpio->csave_regs[i].wdata, plgpio->regs.wdata +
+ off);
+ writel_relaxed(plgpio->csave_regs[i].dir, plgpio->regs.dir +
+ off);
+
+ if (plgpio->regs.eit != -1)
+ writel_relaxed(plgpio->csave_regs[i].eit,
+ plgpio->regs.eit + off);
+
+ writel_relaxed(plgpio->csave_regs[i].ie, plgpio->regs.ie + off);
+
+ if (plgpio->regs.enb != -1)
+ writel_relaxed(plgpio->csave_regs[i].enb,
+ plgpio->regs.enb + off);
+ }
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(plgpio_dev_pm_ops, plgpio_suspend, plgpio_resume);
+
+static const struct of_device_id plgpio_of_match[] = {
+ { .compatible = "st,spear-plgpio" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, plgpio_of_match);
+
+static struct platform_driver plgpio_driver = {
+ .probe = plgpio_probe,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "spear-plgpio",
+ .pm = &plgpio_dev_pm_ops,
+ .of_match_table = of_match_ptr(plgpio_of_match),
+ },
+};
+
+static int __init plgpio_init(void)
+{
+ return platform_driver_register(&plgpio_driver);
+}
+subsys_initcall(plgpio_init);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>");
+MODULE_DESCRIPTION("ST Microlectronics SPEAr PLGPIO driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c
index b1fd6ee33c6..922c057521a 100644
--- a/drivers/pinctrl/spear/pinctrl-spear.c
+++ b/drivers/pinctrl/spear/pinctrl-spear.c
@@ -14,10 +14,10 @@
*/
#include <linux/err.h>
-#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/of_gpio.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
@@ -28,14 +28,26 @@
#define DRIVER_NAME "spear-pinmux"
-static inline u32 pmx_readl(struct spear_pmx *pmx, u32 reg)
+static void muxregs_endisable(struct spear_pmx *pmx,
+ struct spear_muxreg *muxregs, u8 count, bool enable)
{
- return readl_relaxed(pmx->vbase + reg);
-}
+ struct spear_muxreg *muxreg;
+ u32 val, temp, j;
-static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg)
-{
- writel_relaxed(val, pmx->vbase + reg);
+ for (j = 0; j < count; j++) {
+ muxreg = &muxregs[j];
+
+ val = pmx_readl(pmx, muxreg->reg);
+ val &= ~muxreg->mask;
+
+ if (enable)
+ temp = muxreg->val;
+ else
+ temp = ~muxreg->val;
+
+ val |= muxreg->mask & temp;
+ pmx_writel(pmx, val, muxreg->reg);
+ }
}
static int set_mode(struct spear_pmx *pmx, int mode)
@@ -70,6 +82,17 @@ static int set_mode(struct spear_pmx *pmx, int mode)
return 0;
}
+void __devinit
+pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup,
+ unsigned count, u16 reg)
+{
+ int i, j;
+
+ for (i = 0; i < count; i++)
+ for (j = 0; j < gpio_pingroup[i].nmuxregs; j++)
+ gpio_pingroup[i].muxregs[j].reg = reg;
+}
+
void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg)
{
struct spear_pingroup *pgroup;
@@ -121,9 +144,10 @@ static void spear_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
seq_printf(s, " " DRIVER_NAME);
}
-int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
- struct device_node *np_config,
- struct pinctrl_map **map, unsigned *num_maps)
+static int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np_config,
+ struct pinctrl_map **map,
+ unsigned *num_maps)
{
struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
struct device_node *np;
@@ -168,8 +192,9 @@ int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
return 0;
}
-void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
- struct pinctrl_map *map, unsigned num_maps)
+static void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *map,
+ unsigned num_maps)
{
kfree(map);
}
@@ -216,9 +241,7 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev,
struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
const struct spear_pingroup *pgroup;
const struct spear_modemux *modemux;
- struct spear_muxreg *muxreg;
- u32 val, temp;
- int i, j;
+ int i;
bool found = false;
pgroup = pmx->machdata->groups[group];
@@ -233,20 +256,8 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev,
}
found = true;
- for (j = 0; j < modemux->nmuxregs; j++) {
- muxreg = &modemux->muxregs[j];
-
- val = pmx_readl(pmx, muxreg->reg);
- val &= ~muxreg->mask;
-
- if (enable)
- temp = muxreg->val;
- else
- temp = ~muxreg->val;
-
- val |= muxreg->mask & temp;
- pmx_writel(pmx, val, muxreg->reg);
- }
+ muxregs_endisable(pmx, modemux->muxregs, modemux->nmuxregs,
+ enable);
}
if (!found) {
@@ -270,12 +281,74 @@ static void spear_pinctrl_disable(struct pinctrl_dev *pctldev,
spear_pinctrl_endisable(pctldev, function, group, false);
}
+/* gpio with pinmux */
+static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx,
+ unsigned pin)
+{
+ struct spear_gpio_pingroup *gpio_pingroup;
+ int i, j;
+
+ if (!pmx->machdata->gpio_pingroups)
+ return NULL;
+
+ for (i = 0; i < pmx->machdata->ngpio_pingroups; i++) {
+ gpio_pingroup = &pmx->machdata->gpio_pingroups[i];
+
+ for (j = 0; j < gpio_pingroup->npins; j++) {
+ if (gpio_pingroup->pins[j] == pin)
+ return gpio_pingroup;
+ }
+ }
+
+ return NULL;
+}
+
+static int gpio_request_endisable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range, unsigned offset, bool enable)
+{
+ struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+ struct spear_pinctrl_machdata *machdata = pmx->machdata;
+ struct spear_gpio_pingroup *gpio_pingroup;
+
+ /*
+ * Some SoC have configuration options applicable to group of pins,
+ * rather than a single pin.
+ */
+ gpio_pingroup = get_gpio_pingroup(pmx, offset);
+ if (gpio_pingroup)
+ muxregs_endisable(pmx, gpio_pingroup->muxregs,
+ gpio_pingroup->nmuxregs, enable);
+
+ /*
+ * SoC may need some extra configurations, or configurations for single
+ * pin
+ */
+ if (machdata->gpio_request_endisable)
+ machdata->gpio_request_endisable(pmx, offset, enable);
+
+ return 0;
+}
+
+static int gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range, unsigned offset)
+{
+ return gpio_request_endisable(pctldev, range, offset, true);
+}
+
+static void gpio_disable_free(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range, unsigned offset)
+{
+ gpio_request_endisable(pctldev, range, offset, false);
+}
+
static struct pinmux_ops spear_pinmux_ops = {
.get_functions_count = spear_pinctrl_get_funcs_count,
.get_function_name = spear_pinctrl_get_func_name,
.get_function_groups = spear_pinctrl_get_func_groups,
.enable = spear_pinctrl_enable,
.disable = spear_pinctrl_disable,
+ .gpio_request_enable = gpio_request_enable,
+ .gpio_disable_free = gpio_disable_free,
};
static struct pinctrl_desc spear_pinctrl_desc = {
@@ -344,7 +417,7 @@ int __devinit spear_pinctrl_probe(struct platform_device *pdev,
return 0;
}
-int __devexit spear_pinctrl_remove(struct platform_device *pdev)
+int spear_pinctrl_remove(struct platform_device *pdev)
{
struct spear_pmx *pmx = platform_get_drvdata(pdev);
diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h
index d950eb78d93..1be46ecc6d9 100644
--- a/drivers/pinctrl/spear/pinctrl-spear.h
+++ b/drivers/pinctrl/spear/pinctrl-spear.h
@@ -12,11 +12,14 @@
#ifndef __PINMUX_SPEAR_H__
#define __PINMUX_SPEAR_H__
+#include <linux/gpio.h>
+#include <linux/io.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/types.h>
struct platform_device;
struct device;
+struct spear_pmx;
/**
* struct spear_pmx_mode - SPEAr pmx mode
@@ -46,6 +49,44 @@ struct spear_muxreg {
u32 val;
};
+struct spear_gpio_pingroup {
+ const unsigned *pins;
+ unsigned npins;
+ struct spear_muxreg *muxregs;
+ u8 nmuxregs;
+};
+
+/* ste: set to enable */
+#define DEFINE_MUXREG(__pins, __muxreg, __mask, __ste) \
+static struct spear_muxreg __pins##_muxregs[] = { \
+ { \
+ .reg = __muxreg, \
+ .mask = __mask, \
+ .val = __ste ? __mask : 0, \
+ }, \
+}
+
+#define DEFINE_2_MUXREG(__pins, __muxreg1, __muxreg2, __mask, __ste1, __ste2) \
+static struct spear_muxreg __pins##_muxregs[] = { \
+ { \
+ .reg = __muxreg1, \
+ .mask = __mask, \
+ .val = __ste1 ? __mask : 0, \
+ }, { \
+ .reg = __muxreg2, \
+ .mask = __mask, \
+ .val = __ste2 ? __mask : 0, \
+ }, \
+}
+
+#define GPIO_PINGROUP(__pins) \
+ { \
+ .pins = __pins, \
+ .npins = ARRAY_SIZE(__pins), \
+ .muxregs = __pins##_muxregs, \
+ .nmuxregs = ARRAY_SIZE(__pins##_muxregs), \
+ }
+
/**
* struct spear_modemux - SPEAr mode mux configuration
* @modes: mode ids supported by this group of muxregs
@@ -100,6 +141,8 @@ struct spear_function {
* @nfunctions: The numbmer of entries in @functions.
* @groups: An array describing all pin groups the pin SoC supports.
* @ngroups: The numbmer of entries in @groups.
+ * @gpio_pingroups: gpio pingroups
+ * @ngpio_pingroups: gpio pingroups count
*
* @modes_supported: Does SoC support modes
* @mode: mode configured from probe
@@ -113,6 +156,10 @@ struct spear_pinctrl_machdata {
unsigned nfunctions;
struct spear_pingroup **groups;
unsigned ngroups;
+ struct spear_gpio_pingroup *gpio_pingroups;
+ void (*gpio_request_endisable)(struct spear_pmx *pmx, int offset,
+ bool enable);
+ unsigned ngpio_pingroups;
bool modes_supported;
u16 mode;
@@ -135,10 +182,23 @@ struct spear_pmx {
};
/* exported routines */
+static inline u32 pmx_readl(struct spear_pmx *pmx, u32 reg)
+{
+ return readl_relaxed(pmx->vbase + reg);
+}
+
+static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg)
+{
+ writel_relaxed(val, pmx->vbase + reg);
+}
+
void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg);
+void __devinit
+pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup,
+ unsigned count, u16 reg);
int __devinit spear_pinctrl_probe(struct platform_device *pdev,
struct spear_pinctrl_machdata *machdata);
-int __devexit spear_pinctrl_remove(struct platform_device *pdev);
+int spear_pinctrl_remove(struct platform_device *pdev);
#define SPEAR_PIN_0_TO_101 \
PINCTRL_PIN(0, "PLGPIO0"), \
diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c
index 0436fc7895d..e40d785a3fc 100644
--- a/drivers/pinctrl/spear/pinctrl-spear1310.c
+++ b/drivers/pinctrl/spear/pinctrl-spear1310.c
@@ -2418,6 +2418,268 @@ static struct spear_function *spear1310_functions[] = {
&gpt64_function,
};
+static const unsigned pin18[] = { 18, };
+static const unsigned pin19[] = { 19, };
+static const unsigned pin20[] = { 20, };
+static const unsigned pin21[] = { 21, };
+static const unsigned pin22[] = { 22, };
+static const unsigned pin23[] = { 23, };
+static const unsigned pin54[] = { 54, };
+static const unsigned pin55[] = { 55, };
+static const unsigned pin56[] = { 56, };
+static const unsigned pin57[] = { 57, };
+static const unsigned pin58[] = { 58, };
+static const unsigned pin59[] = { 59, };
+static const unsigned pin60[] = { 60, };
+static const unsigned pin61[] = { 61, };
+static const unsigned pin62[] = { 62, };
+static const unsigned pin63[] = { 63, };
+static const unsigned pin143[] = { 143, };
+static const unsigned pin144[] = { 144, };
+static const unsigned pin145[] = { 145, };
+static const unsigned pin146[] = { 146, };
+static const unsigned pin147[] = { 147, };
+static const unsigned pin148[] = { 148, };
+static const unsigned pin149[] = { 149, };
+static const unsigned pin150[] = { 150, };
+static const unsigned pin151[] = { 151, };
+static const unsigned pin152[] = { 152, };
+static const unsigned pin205[] = { 205, };
+static const unsigned pin206[] = { 206, };
+static const unsigned pin211[] = { 211, };
+static const unsigned pin212[] = { 212, };
+static const unsigned pin213[] = { 213, };
+static const unsigned pin214[] = { 214, };
+static const unsigned pin215[] = { 215, };
+static const unsigned pin216[] = { 216, };
+static const unsigned pin217[] = { 217, };
+static const unsigned pin218[] = { 218, };
+static const unsigned pin219[] = { 219, };
+static const unsigned pin220[] = { 220, };
+static const unsigned pin221[] = { 221, };
+static const unsigned pin222[] = { 222, };
+static const unsigned pin223[] = { 223, };
+static const unsigned pin224[] = { 224, };
+static const unsigned pin225[] = { 225, };
+static const unsigned pin226[] = { 226, };
+static const unsigned pin227[] = { 227, };
+static const unsigned pin228[] = { 228, };
+static const unsigned pin229[] = { 229, };
+static const unsigned pin230[] = { 230, };
+static const unsigned pin231[] = { 231, };
+static const unsigned pin232[] = { 232, };
+static const unsigned pin233[] = { 233, };
+static const unsigned pin234[] = { 234, };
+static const unsigned pin235[] = { 235, };
+static const unsigned pin236[] = { 236, };
+static const unsigned pin237[] = { 237, };
+static const unsigned pin238[] = { 238, };
+static const unsigned pin239[] = { 239, };
+static const unsigned pin240[] = { 240, };
+static const unsigned pin241[] = { 241, };
+static const unsigned pin242[] = { 242, };
+static const unsigned pin243[] = { 243, };
+static const unsigned pin244[] = { 244, };
+static const unsigned pin245[] = { 245, };
+
+static const unsigned pin_grp0[] = { 173, 174, };
+static const unsigned pin_grp1[] = { 175, 185, 188, 197, 198, };
+static const unsigned pin_grp2[] = { 176, 177, 178, 179, 184, 186, 187, 189,
+ 190, 191, 192, };
+static const unsigned pin_grp3[] = { 180, 181, 182, 183, 193, 194, 195, 196, };
+static const unsigned pin_grp4[] = { 199, 200, };
+static const unsigned pin_grp5[] = { 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, };
+static const unsigned pin_grp6[] = { 86, 87, 88, 89, 90, 91, 92, 93, };
+static const unsigned pin_grp7[] = { 98, 99, };
+static const unsigned pin_grp8[] = { 158, 159, 160, 161, 162, 163, 164, 165,
+ 166, 167, 168, 169, 170, 171, 172, };
+
+/* Define muxreg arrays */
+DEFINE_2_MUXREG(i2c0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_I2C0_MASK, 0, 1);
+DEFINE_2_MUXREG(ssp0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_SSP0_MASK, 0, 1);
+DEFINE_2_MUXREG(ssp0_cs0_pins, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_SSP0_CS0_MASK, 0, 1);
+DEFINE_2_MUXREG(ssp0_cs1_2_pins, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_SSP0_CS1_2_MASK, 0, 1);
+DEFINE_2_MUXREG(i2s0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_I2S0_MASK, 0, 1);
+DEFINE_2_MUXREG(i2s1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_I2S1_MASK, 0, 1);
+DEFINE_2_MUXREG(clcd_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_CLCD1_MASK, 0, 1);
+DEFINE_2_MUXREG(clcd_high_res_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_CLCD2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin18, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO15_MASK, 0, 1);
+DEFINE_2_MUXREG(pin19, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO14_MASK, 0, 1);
+DEFINE_2_MUXREG(pin20, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO13_MASK, 0, 1);
+DEFINE_2_MUXREG(pin21, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO12_MASK, 0, 1);
+DEFINE_2_MUXREG(pin22, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO11_MASK, 0, 1);
+DEFINE_2_MUXREG(pin23, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO10_MASK, 0, 1);
+DEFINE_2_MUXREG(pin143, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO00_MASK, 0, 1);
+DEFINE_2_MUXREG(pin144, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO01_MASK, 0, 1);
+DEFINE_2_MUXREG(pin145, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO02_MASK, 0, 1);
+DEFINE_2_MUXREG(pin146, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO03_MASK, 0, 1);
+DEFINE_2_MUXREG(pin147, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO04_MASK, 0, 1);
+DEFINE_2_MUXREG(pin148, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO05_MASK, 0, 1);
+DEFINE_2_MUXREG(pin149, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO06_MASK, 0, 1);
+DEFINE_2_MUXREG(pin150, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO07_MASK, 0, 1);
+DEFINE_2_MUXREG(pin151, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO08_MASK, 0, 1);
+DEFINE_2_MUXREG(pin152, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO09_MASK, 0, 1);
+DEFINE_2_MUXREG(smi_2_chips_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_SMI_MASK, 0, 1);
+DEFINE_2_MUXREG(pin54, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_SMINCS3_MASK, 0, 1);
+DEFINE_2_MUXREG(pin55, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_SMINCS2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin56, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NFRSTPWDWN3_MASK, 0, 1);
+DEFINE_2_MUXREG(pin57, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin58, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN1_MASK, 0, 1);
+DEFINE_2_MUXREG(pin59, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN0_MASK, 0, 1);
+DEFINE_2_MUXREG(pin60, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFWPRT3_MASK, 0, 1);
+DEFINE_2_MUXREG(pin61, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFCE3_MASK, 0, 1);
+DEFINE_2_MUXREG(pin62, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD25_MASK, 0, 1);
+DEFINE_2_MUXREG(pin63, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD24_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp0, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIICLK_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp1, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp2, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_RXCLK_RDV_TXEN_D03_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp3, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIID47_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp4, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_MDC_MDIO_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp5, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD23_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp6, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_MCI_DATA8_15_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp7, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NFCE2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp8, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NAND8_MASK, 0, 1);
+DEFINE_2_MUXREG(nand_16bit_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NAND16BIT_1_MASK, 0, 1);
+DEFINE_2_MUXREG(pin205, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_COL1_MASK | PMX_NFCE1_MASK, 0, 1);
+DEFINE_2_MUXREG(pin206, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_COL0_MASK | PMX_NFCE2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin211, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROW1_MASK | PMX_NFWPRT1_MASK, 0, 1);
+DEFINE_2_MUXREG(pin212, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROW0_MASK | PMX_NFWPRT2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin213, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA0_MASK, 0, 1);
+DEFINE_2_MUXREG(pin214, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA1_MASK, 0, 1);
+DEFINE_2_MUXREG(pin215, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin216, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA3_MASK, 0, 1);
+DEFINE_2_MUXREG(pin217, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA4_MASK, 0, 1);
+DEFINE_2_MUXREG(pin218, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA5_MASK, 0, 1);
+DEFINE_2_MUXREG(pin219, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA6_MASK, 0, 1);
+DEFINE_2_MUXREG(pin220, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA7_MASK, 0, 1);
+DEFINE_2_MUXREG(pin221, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA1SD_MASK, 0, 1);
+DEFINE_2_MUXREG(pin222, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA2SD_MASK, 0, 1);
+DEFINE_2_MUXREG(pin223, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA3SD_MASK, 0, 1);
+DEFINE_2_MUXREG(pin224, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR0ALE_MASK, 0, 1);
+DEFINE_2_MUXREG(pin225, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR1CLECLK_MASK, 0, 1);
+DEFINE_2_MUXREG(pin226, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin227, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICECF_MASK, 0, 1);
+DEFINE_2_MUXREG(pin228, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICEXD_MASK, 0, 1);
+DEFINE_2_MUXREG(pin229, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICESDMMC_MASK, 0, 1);
+DEFINE_2_MUXREG(pin230, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDCF1_MASK, 0, 1);
+DEFINE_2_MUXREG(pin231, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDCF2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin232, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDXD_MASK, 0, 1);
+DEFINE_2_MUXREG(pin233, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDSDMMC_MASK, 0, 1);
+DEFINE_2_MUXREG(pin234, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATADIR_MASK, 0, 1);
+DEFINE_2_MUXREG(pin235, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDMARQWP_MASK, 0, 1);
+DEFINE_2_MUXREG(pin236, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIORDRE_MASK, 0, 1);
+DEFINE_2_MUXREG(pin237, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIOWRWE_MASK, 0, 1);
+DEFINE_2_MUXREG(pin238, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIRESETCF_MASK, 0, 1);
+DEFINE_2_MUXREG(pin239, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICS0CE_MASK, 0, 1);
+DEFINE_2_MUXREG(pin240, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICFINTR_MASK, 0, 1);
+DEFINE_2_MUXREG(pin241, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIORDY_MASK, 0, 1);
+DEFINE_2_MUXREG(pin242, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICS1_MASK, 0, 1);
+DEFINE_2_MUXREG(pin243, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDMAACK_MASK, 0, 1);
+DEFINE_2_MUXREG(pin244, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCISDCMD_MASK, 0, 1);
+DEFINE_2_MUXREG(pin245, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCILEDS_MASK, 0, 1);
+DEFINE_2_MUXREG(keyboard_rowcol6_8_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROWCOL68_MASK, 0, 1);
+DEFINE_2_MUXREG(uart0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_UART0_MASK, 0, 1);
+DEFINE_2_MUXREG(uart0_modem_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_UART0_MODEM_MASK, 0, 1);
+DEFINE_2_MUXREG(gpt0_tmr0_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT0_TMR0_MASK, 0, 1);
+DEFINE_2_MUXREG(gpt0_tmr1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT0_TMR1_MASK, 0, 1);
+DEFINE_2_MUXREG(gpt1_tmr0_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT1_TMR0_MASK, 0, 1);
+DEFINE_2_MUXREG(gpt1_tmr1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT1_TMR1_MASK, 0, 1);
+DEFINE_2_MUXREG(touch_xy_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_TOUCH_XY_MASK, 0, 1);
+
+static struct spear_gpio_pingroup spear1310_gpio_pingroup[] = {
+ GPIO_PINGROUP(i2c0_pins),
+ GPIO_PINGROUP(ssp0_pins),
+ GPIO_PINGROUP(ssp0_cs0_pins),
+ GPIO_PINGROUP(ssp0_cs1_2_pins),
+ GPIO_PINGROUP(i2s0_pins),
+ GPIO_PINGROUP(i2s1_pins),
+ GPIO_PINGROUP(clcd_pins),
+ GPIO_PINGROUP(clcd_high_res_pins),
+ GPIO_PINGROUP(pin18),
+ GPIO_PINGROUP(pin19),
+ GPIO_PINGROUP(pin20),
+ GPIO_PINGROUP(pin21),
+ GPIO_PINGROUP(pin22),
+ GPIO_PINGROUP(pin23),
+ GPIO_PINGROUP(pin143),
+ GPIO_PINGROUP(pin144),
+ GPIO_PINGROUP(pin145),
+ GPIO_PINGROUP(pin146),
+ GPIO_PINGROUP(pin147),
+ GPIO_PINGROUP(pin148),
+ GPIO_PINGROUP(pin149),
+ GPIO_PINGROUP(pin150),
+ GPIO_PINGROUP(pin151),
+ GPIO_PINGROUP(pin152),
+ GPIO_PINGROUP(smi_2_chips_pins),
+ GPIO_PINGROUP(pin54),
+ GPIO_PINGROUP(pin55),
+ GPIO_PINGROUP(pin56),
+ GPIO_PINGROUP(pin57),
+ GPIO_PINGROUP(pin58),
+ GPIO_PINGROUP(pin59),
+ GPIO_PINGROUP(pin60),
+ GPIO_PINGROUP(pin61),
+ GPIO_PINGROUP(pin62),
+ GPIO_PINGROUP(pin63),
+ GPIO_PINGROUP(pin_grp0),
+ GPIO_PINGROUP(pin_grp1),
+ GPIO_PINGROUP(pin_grp2),
+ GPIO_PINGROUP(pin_grp3),
+ GPIO_PINGROUP(pin_grp4),
+ GPIO_PINGROUP(pin_grp5),
+ GPIO_PINGROUP(pin_grp6),
+ GPIO_PINGROUP(pin_grp7),
+ GPIO_PINGROUP(pin_grp8),
+ GPIO_PINGROUP(nand_16bit_pins),
+ GPIO_PINGROUP(pin205),
+ GPIO_PINGROUP(pin206),
+ GPIO_PINGROUP(pin211),
+ GPIO_PINGROUP(pin212),
+ GPIO_PINGROUP(pin213),
+ GPIO_PINGROUP(pin214),
+ GPIO_PINGROUP(pin215),
+ GPIO_PINGROUP(pin216),
+ GPIO_PINGROUP(pin217),
+ GPIO_PINGROUP(pin218),
+ GPIO_PINGROUP(pin219),
+ GPIO_PINGROUP(pin220),
+ GPIO_PINGROUP(pin221),
+ GPIO_PINGROUP(pin222),
+ GPIO_PINGROUP(pin223),
+ GPIO_PINGROUP(pin224),
+ GPIO_PINGROUP(pin225),
+ GPIO_PINGROUP(pin226),
+ GPIO_PINGROUP(pin227),
+ GPIO_PINGROUP(pin228),
+ GPIO_PINGROUP(pin229),
+ GPIO_PINGROUP(pin230),
+ GPIO_PINGROUP(pin231),
+ GPIO_PINGROUP(pin232),
+ GPIO_PINGROUP(pin233),
+ GPIO_PINGROUP(pin234),
+ GPIO_PINGROUP(pin235),
+ GPIO_PINGROUP(pin236),
+ GPIO_PINGROUP(pin237),
+ GPIO_PINGROUP(pin238),
+ GPIO_PINGROUP(pin239),
+ GPIO_PINGROUP(pin240),
+ GPIO_PINGROUP(pin241),
+ GPIO_PINGROUP(pin242),
+ GPIO_PINGROUP(pin243),
+ GPIO_PINGROUP(pin244),
+ GPIO_PINGROUP(pin245),
+ GPIO_PINGROUP(keyboard_rowcol6_8_pins),
+ GPIO_PINGROUP(uart0_pins),
+ GPIO_PINGROUP(uart0_modem_pins),
+ GPIO_PINGROUP(gpt0_tmr0_pins),
+ GPIO_PINGROUP(gpt0_tmr1_pins),
+ GPIO_PINGROUP(gpt1_tmr0_pins),
+ GPIO_PINGROUP(gpt1_tmr1_pins),
+ GPIO_PINGROUP(touch_xy_pins),
+};
+
static struct spear_pinctrl_machdata spear1310_machdata = {
.pins = spear1310_pins,
.npins = ARRAY_SIZE(spear1310_pins),
@@ -2425,10 +2687,12 @@ static struct spear_pinctrl_machdata spear1310_machdata = {
.ngroups = ARRAY_SIZE(spear1310_pingroups),
.functions = spear1310_functions,
.nfunctions = ARRAY_SIZE(spear1310_functions),
+ .gpio_pingroups = spear1310_gpio_pingroup,
+ .ngpio_pingroups = ARRAY_SIZE(spear1310_gpio_pingroup),
.modes_supported = false,
};
-static struct of_device_id spear1310_pinctrl_of_match[] __devinitdata = {
+static struct of_device_id spear1310_pinctrl_of_match[] = {
{
.compatible = "st,spear1310-pinmux",
},
@@ -2440,7 +2704,7 @@ static int __devinit spear1310_pinctrl_probe(struct platform_device *pdev)
return spear_pinctrl_probe(pdev, &spear1310_machdata);
}
-static int __devexit spear1310_pinctrl_remove(struct platform_device *pdev)
+static int spear1310_pinctrl_remove(struct platform_device *pdev)
{
return spear_pinctrl_remove(pdev);
}
@@ -2452,7 +2716,7 @@ static struct platform_driver spear1310_pinctrl_driver = {
.of_match_table = spear1310_pinctrl_of_match,
},
.probe = spear1310_pinctrl_probe,
- .remove = __devexit_p(spear1310_pinctrl_remove),
+ .remove = spear1310_pinctrl_remove,
};
static int __init spear1310_pinctrl_init(void)
diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c
index 0606b8cf3f2..8deaaff3156 100644
--- a/drivers/pinctrl/spear/pinctrl-spear1340.c
+++ b/drivers/pinctrl/spear/pinctrl-spear1340.c
@@ -1971,6 +1971,32 @@ static struct spear_function *spear1340_functions[] = {
&sata_function,
};
+static void gpio_request_endisable(struct spear_pmx *pmx, int pin,
+ bool enable)
+{
+ unsigned int regoffset, regindex, bitoffset;
+ unsigned int val;
+
+ /* pin++ as gpio configuration starts from 2nd bit of base register */
+ pin++;
+
+ regindex = pin / 32;
+ bitoffset = pin % 32;
+
+ if (regindex <= 3)
+ regoffset = PAD_FUNCTION_EN_1 + regindex * sizeof(int *);
+ else
+ regoffset = PAD_FUNCTION_EN_5 + (regindex - 4) * sizeof(int *);
+
+ val = pmx_readl(pmx, regoffset);
+ if (enable)
+ val &= ~(0x1 << bitoffset);
+ else
+ val |= 0x1 << bitoffset;
+
+ pmx_writel(pmx, val, regoffset);
+}
+
static struct spear_pinctrl_machdata spear1340_machdata = {
.pins = spear1340_pins,
.npins = ARRAY_SIZE(spear1340_pins),
@@ -1978,10 +2004,11 @@ static struct spear_pinctrl_machdata spear1340_machdata = {
.ngroups = ARRAY_SIZE(spear1340_pingroups),
.functions = spear1340_functions,
.nfunctions = ARRAY_SIZE(spear1340_functions),
+ .gpio_request_endisable = gpio_request_endisable,
.modes_supported = false,
};
-static struct of_device_id spear1340_pinctrl_of_match[] __devinitdata = {
+static struct of_device_id spear1340_pinctrl_of_match[] = {
{
.compatible = "st,spear1340-pinmux",
},
@@ -1993,7 +2020,7 @@ static int __devinit spear1340_pinctrl_probe(struct platform_device *pdev)
return spear_pinctrl_probe(pdev, &spear1340_machdata);
}
-static int __devexit spear1340_pinctrl_remove(struct platform_device *pdev)
+static int spear1340_pinctrl_remove(struct platform_device *pdev)
{
return spear_pinctrl_remove(pdev);
}
@@ -2005,7 +2032,7 @@ static struct platform_driver spear1340_pinctrl_driver = {
.of_match_table = spear1340_pinctrl_of_match,
},
.probe = spear1340_pinctrl_probe,
- .remove = __devexit_p(spear1340_pinctrl_remove),
+ .remove = spear1340_pinctrl_remove,
};
static int __init spear1340_pinctrl_init(void)
diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c
index 4dfc2849b17..f48e466e605 100644
--- a/drivers/pinctrl/spear/pinctrl-spear300.c
+++ b/drivers/pinctrl/spear/pinctrl-spear300.c
@@ -646,7 +646,7 @@ static struct spear_function *spear300_functions[] = {
&gpio1_function,
};
-static struct of_device_id spear300_pinctrl_of_match[] __devinitdata = {
+static struct of_device_id spear300_pinctrl_of_match[] = {
{
.compatible = "st,spear300-pinmux",
},
@@ -661,6 +661,8 @@ static int __devinit spear300_pinctrl_probe(struct platform_device *pdev)
spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups);
spear3xx_machdata.functions = spear300_functions;
spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions);
+ spear3xx_machdata.gpio_pingroups = NULL;
+ spear3xx_machdata.ngpio_pingroups = 0;
spear3xx_machdata.modes_supported = true;
spear3xx_machdata.pmx_modes = spear300_pmx_modes;
@@ -675,7 +677,7 @@ static int __devinit spear300_pinctrl_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit spear300_pinctrl_remove(struct platform_device *pdev)
+static int spear300_pinctrl_remove(struct platform_device *pdev)
{
return spear_pinctrl_remove(pdev);
}
@@ -687,7 +689,7 @@ static struct platform_driver spear300_pinctrl_driver = {
.of_match_table = spear300_pinctrl_of_match,
},
.probe = spear300_pinctrl_probe,
- .remove = __devexit_p(spear300_pinctrl_remove),
+ .remove = spear300_pinctrl_remove,
};
static int __init spear300_pinctrl_init(void)
diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c
index 96883693fb7..5b954c19a6d 100644
--- a/drivers/pinctrl/spear/pinctrl-spear310.c
+++ b/drivers/pinctrl/spear/pinctrl-spear310.c
@@ -371,7 +371,7 @@ static struct spear_function *spear310_functions[] = {
&tdm_function,
};
-static struct of_device_id spear310_pinctrl_of_match[] __devinitdata = {
+static struct of_device_id spear310_pinctrl_of_match[] = {
{
.compatible = "st,spear310-pinmux",
},
@@ -388,6 +388,8 @@ static int __devinit spear310_pinctrl_probe(struct platform_device *pdev)
spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions);
pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+ pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups,
+ spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG);
spear3xx_machdata.modes_supported = false;
@@ -398,7 +400,7 @@ static int __devinit spear310_pinctrl_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit spear310_pinctrl_remove(struct platform_device *pdev)
+static int spear310_pinctrl_remove(struct platform_device *pdev)
{
return spear_pinctrl_remove(pdev);
}
@@ -410,7 +412,7 @@ static struct platform_driver spear310_pinctrl_driver = {
.of_match_table = spear310_pinctrl_of_match,
},
.probe = spear310_pinctrl_probe,
- .remove = __devexit_p(spear310_pinctrl_remove),
+ .remove = spear310_pinctrl_remove,
};
static int __init spear310_pinctrl_init(void)
diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c
index ca47b0e5078..e9a5e6d3924 100644
--- a/drivers/pinctrl/spear/pinctrl-spear320.c
+++ b/drivers/pinctrl/spear/pinctrl-spear320.c
@@ -3410,7 +3410,7 @@ static struct spear_function *spear320_functions[] = {
&i2c2_function,
};
-static struct of_device_id spear320_pinctrl_of_match[] __devinitdata = {
+static struct of_device_id spear320_pinctrl_of_match[] = {
{
.compatible = "st,spear320-pinmux",
},
@@ -3431,6 +3431,8 @@ static int __devinit spear320_pinctrl_probe(struct platform_device *pdev)
spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear320_pmx_modes);
pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+ pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups,
+ spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG);
ret = spear_pinctrl_probe(pdev, &spear3xx_machdata);
if (ret)
@@ -3439,7 +3441,7 @@ static int __devinit spear320_pinctrl_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit spear320_pinctrl_remove(struct platform_device *pdev)
+static int spear320_pinctrl_remove(struct platform_device *pdev)
{
return spear_pinctrl_remove(pdev);
}
@@ -3451,7 +3453,7 @@ static struct platform_driver spear320_pinctrl_driver = {
.of_match_table = spear320_pinctrl_of_match,
},
.probe = spear320_pinctrl_probe,
- .remove = __devexit_p(spear320_pinctrl_remove),
+ .remove = spear320_pinctrl_remove,
};
static int __init spear320_pinctrl_init(void)
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.c b/drivers/pinctrl/spear/pinctrl-spear3xx.c
index 0242378f7cb..12ee21af766 100644
--- a/drivers/pinctrl/spear/pinctrl-spear3xx.c
+++ b/drivers/pinctrl/spear/pinctrl-spear3xx.c
@@ -481,7 +481,44 @@ struct spear_function spear3xx_timer_2_3_function = {
.ngroups = ARRAY_SIZE(timer_2_3_grps),
};
+/* Define muxreg arrays */
+DEFINE_MUXREG(firda_pins, 0, PMX_FIRDA_MASK, 0);
+DEFINE_MUXREG(i2c_pins, 0, PMX_I2C_MASK, 0);
+DEFINE_MUXREG(ssp_cs_pins, 0, PMX_SSP_CS_MASK, 0);
+DEFINE_MUXREG(ssp_pins, 0, PMX_SSP_MASK, 0);
+DEFINE_MUXREG(mii_pins, 0, PMX_MII_MASK, 0);
+DEFINE_MUXREG(gpio0_pin0_pins, 0, PMX_GPIO_PIN0_MASK, 0);
+DEFINE_MUXREG(gpio0_pin1_pins, 0, PMX_GPIO_PIN1_MASK, 0);
+DEFINE_MUXREG(gpio0_pin2_pins, 0, PMX_GPIO_PIN2_MASK, 0);
+DEFINE_MUXREG(gpio0_pin3_pins, 0, PMX_GPIO_PIN3_MASK, 0);
+DEFINE_MUXREG(gpio0_pin4_pins, 0, PMX_GPIO_PIN4_MASK, 0);
+DEFINE_MUXREG(gpio0_pin5_pins, 0, PMX_GPIO_PIN5_MASK, 0);
+DEFINE_MUXREG(uart0_ext_pins, 0, PMX_UART0_MODEM_MASK, 0);
+DEFINE_MUXREG(uart0_pins, 0, PMX_UART0_MASK, 0);
+DEFINE_MUXREG(timer_0_1_pins, 0, PMX_TIMER_0_1_MASK, 0);
+DEFINE_MUXREG(timer_2_3_pins, 0, PMX_TIMER_2_3_MASK, 0);
+
+static struct spear_gpio_pingroup spear3xx_gpio_pingroup[] = {
+ GPIO_PINGROUP(firda_pins),
+ GPIO_PINGROUP(i2c_pins),
+ GPIO_PINGROUP(ssp_cs_pins),
+ GPIO_PINGROUP(ssp_pins),
+ GPIO_PINGROUP(mii_pins),
+ GPIO_PINGROUP(gpio0_pin0_pins),
+ GPIO_PINGROUP(gpio0_pin1_pins),
+ GPIO_PINGROUP(gpio0_pin2_pins),
+ GPIO_PINGROUP(gpio0_pin3_pins),
+ GPIO_PINGROUP(gpio0_pin4_pins),
+ GPIO_PINGROUP(gpio0_pin5_pins),
+ GPIO_PINGROUP(uart0_ext_pins),
+ GPIO_PINGROUP(uart0_pins),
+ GPIO_PINGROUP(timer_0_1_pins),
+ GPIO_PINGROUP(timer_2_3_pins),
+};
+
struct spear_pinctrl_machdata spear3xx_machdata = {
.pins = spear3xx_pins,
.npins = ARRAY_SIZE(spear3xx_pins),
+ .gpio_pingroups = spear3xx_gpio_pingroup,
+ .ngpio_pingroups = ARRAY_SIZE(spear3xx_gpio_pingroup),
};
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index fa4e0a5db3f..ffd53e3eb92 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -159,6 +159,8 @@ struct pnp_resource {
void pnp_free_resource(struct pnp_resource *pnp_res);
+struct pnp_resource *pnp_add_resource(struct pnp_dev *dev,
+ struct resource *res);
struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
int flags);
struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 26b5d4b18dd..72e822e17d4 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -58,7 +58,7 @@ static inline int __init is_exclusive_device(struct acpi_device *dev)
if (!(('0' <= (c) && (c) <= '9') || ('A' <= (c) && (c) <= 'F'))) \
return 0
#define TEST_ALPHA(c) \
- if (!('@' <= (c) || (c) <= 'Z')) \
+ if (!('A' <= (c) && (c) <= 'Z')) \
return 0
static int __init ispnpidacpi(const char *id)
{
@@ -95,6 +95,9 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
return -ENODEV;
}
+ if (WARN_ON_ONCE(acpi_dev != dev->data))
+ dev->data = acpi_dev;
+
ret = pnpacpi_build_resource_template(dev, &buffer);
if (ret)
return ret;
@@ -242,6 +245,10 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
char *pnpid;
struct acpi_hardware_id *id;
+ /* Skip devices that are already bound */
+ if (device->physical_node_count)
+ return 0;
+
/*
* If a PnPacpi device is not present , the device
* driver should not be loaded.
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 5be4a392a3a..b8f4ea7b27f 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -28,37 +28,6 @@
#include "../base.h"
#include "pnpacpi.h"
-#ifdef CONFIG_IA64
-#define valid_IRQ(i) (1)
-#else
-#define valid_IRQ(i) (((i) != 0) && ((i) != 2))
-#endif
-
-/*
- * Allocated Resources
- */
-static int irq_flags(int triggering, int polarity, int shareable)
-{
- int flags;
-
- if (triggering == ACPI_LEVEL_SENSITIVE) {
- if (polarity == ACPI_ACTIVE_LOW)
- flags = IORESOURCE_IRQ_LOWLEVEL;
- else
- flags = IORESOURCE_IRQ_HIGHLEVEL;
- } else {
- if (polarity == ACPI_ACTIVE_LOW)
- flags = IORESOURCE_IRQ_LOWEDGE;
- else
- flags = IORESOURCE_IRQ_HIGHEDGE;
- }
-
- if (shareable == ACPI_SHARED)
- flags |= IORESOURCE_IRQ_SHAREABLE;
-
- return flags;
-}
-
static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering,
int *polarity, int *shareable)
{
@@ -94,45 +63,6 @@ static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering,
*shareable = ACPI_EXCLUSIVE;
}
-static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
- u32 gsi, int triggering,
- int polarity, int shareable)
-{
- int irq, flags;
- int p, t;
-
- if (!valid_IRQ(gsi)) {
- pnp_add_irq_resource(dev, gsi, IORESOURCE_DISABLED);
- return;
- }
-
- /*
- * in IO-APIC mode, use overrided attribute. Two reasons:
- * 1. BIOS bug in DSDT
- * 2. BIOS uses IO-APIC mode Interrupt Source Override
- */
- if (!acpi_get_override_irq(gsi, &t, &p)) {
- t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
- p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
-
- if (triggering != t || polarity != p) {
- dev_warn(&dev->dev, "IRQ %d override to %s, %s\n",
- gsi, t ? "edge":"level", p ? "low":"high");
- triggering = t;
- polarity = p;
- }
- }
-
- flags = irq_flags(triggering, polarity, shareable);
- irq = acpi_register_gsi(&dev->dev, gsi, triggering, polarity);
- if (irq >= 0)
- pcibios_penalize_isa_irq(irq, 1);
- else
- flags |= IORESOURCE_DISABLED;
-
- pnp_add_irq_resource(dev, irq, flags);
-}
-
static int dma_flags(struct pnp_dev *dev, int type, int bus_master,
int transfer)
{
@@ -177,21 +107,16 @@ static int dma_flags(struct pnp_dev *dev, int type, int bus_master,
return flags;
}
-static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
- u64 len, int io_decode,
- int window)
-{
- int flags = 0;
- u64 end = start + len - 1;
+/*
+ * Allocated Resources
+ */
- if (io_decode == ACPI_DECODE_16)
- flags |= IORESOURCE_IO_16BIT_ADDR;
- if (len == 0 || end >= 0x10003)
- flags |= IORESOURCE_DISABLED;
- if (window)
- flags |= IORESOURCE_WINDOW;
+static void pnpacpi_add_irqresource(struct pnp_dev *dev, struct resource *r)
+{
+ if (!(r->flags & IORESOURCE_DISABLED))
+ pcibios_penalize_isa_irq(r->start, 1);
- pnp_add_io_resource(dev, start, end, flags);
+ pnp_add_resource(dev, r);
}
/*
@@ -249,130 +174,49 @@ static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev,
}
}
-static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
- u64 start, u64 len,
- int write_protect, int window)
-{
- int flags = 0;
- u64 end = start + len - 1;
-
- if (len == 0)
- flags |= IORESOURCE_DISABLED;
- if (write_protect == ACPI_READ_WRITE_MEMORY)
- flags |= IORESOURCE_MEM_WRITEABLE;
- if (window)
- flags |= IORESOURCE_WINDOW;
-
- pnp_add_mem_resource(dev, start, end, flags);
-}
-
-static void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev,
- u64 start, u64 len)
-{
- u64 end = start + len - 1;
-
- pnp_add_bus_resource(dev, start, end);
-}
-
-static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
- struct acpi_resource *res)
-{
- struct acpi_resource_address64 addr, *p = &addr;
- acpi_status status;
- int window;
- u64 len;
-
- status = acpi_resource_to_address64(res, p);
- if (!ACPI_SUCCESS(status)) {
- dev_warn(&dev->dev, "failed to convert resource type %d\n",
- res->type);
- return;
- }
-
- /* Windows apparently computes length rather than using _LEN */
- len = p->maximum - p->minimum + 1;
- window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
-
- if (p->resource_type == ACPI_MEMORY_RANGE)
- pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
- p->info.mem.write_protect, window);
- else if (p->resource_type == ACPI_IO_RANGE)
- pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
- p->granularity == 0xfff ? ACPI_DECODE_10 :
- ACPI_DECODE_16, window);
- else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
- pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
-}
-
-static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
- struct acpi_resource *res)
-{
- struct acpi_resource_extended_address64 *p = &res->data.ext_address64;
- int window;
- u64 len;
-
- /* Windows apparently computes length rather than using _LEN */
- len = p->maximum - p->minimum + 1;
- window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
-
- if (p->resource_type == ACPI_MEMORY_RANGE)
- pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
- p->info.mem.write_protect, window);
- else if (p->resource_type == ACPI_IO_RANGE)
- pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
- p->granularity == 0xfff ? ACPI_DECODE_10 :
- ACPI_DECODE_16, window);
- else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
- pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
-}
-
static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
void *data)
{
struct pnp_dev *dev = data;
- struct acpi_resource_irq *irq;
struct acpi_resource_dma *dma;
- struct acpi_resource_io *io;
- struct acpi_resource_fixed_io *fixed_io;
struct acpi_resource_vendor_typed *vendor_typed;
- struct acpi_resource_memory24 *memory24;
- struct acpi_resource_memory32 *memory32;
- struct acpi_resource_fixed_memory32 *fixed_memory32;
- struct acpi_resource_extended_irq *extended_irq;
+ struct resource r;
int i, flags;
- switch (res->type) {
- case ACPI_RESOURCE_TYPE_IRQ:
- /*
- * Per spec, only one interrupt per descriptor is allowed in
- * _CRS, but some firmware violates this, so parse them all.
- */
- irq = &res->data.irq;
- if (irq->interrupt_count == 0)
- pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
- else {
- for (i = 0; i < irq->interrupt_count; i++) {
- pnpacpi_parse_allocated_irqresource(dev,
- irq->interrupts[i],
- irq->triggering,
- irq->polarity,
- irq->sharable);
- }
+ if (acpi_dev_resource_memory(res, &r)
+ || acpi_dev_resource_io(res, &r)
+ || acpi_dev_resource_address_space(res, &r)
+ || acpi_dev_resource_ext_address_space(res, &r)) {
+ pnp_add_resource(dev, &r);
+ return AE_OK;
+ }
+ r.flags = 0;
+ if (acpi_dev_resource_interrupt(res, 0, &r)) {
+ pnpacpi_add_irqresource(dev, &r);
+ for (i = 1; acpi_dev_resource_interrupt(res, i, &r); i++)
+ pnpacpi_add_irqresource(dev, &r);
+
+ if (i > 1) {
/*
* The IRQ encoder puts a single interrupt in each
* descriptor, so if a _CRS descriptor has more than
* one interrupt, we won't be able to re-encode it.
*/
- if (pnp_can_write(dev) && irq->interrupt_count > 1) {
+ if (pnp_can_write(dev)) {
dev_warn(&dev->dev, "multiple interrupts in "
"_CRS descriptor; configuration can't "
"be changed\n");
dev->capabilities &= ~PNP_WRITE;
}
}
- break;
+ return AE_OK;
+ } else if (r.flags & IORESOURCE_DISABLED) {
+ pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
+ return AE_OK;
+ }
+ switch (res->type) {
case ACPI_RESOURCE_TYPE_DMA:
dma = &res->data.dma;
if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
@@ -383,26 +227,10 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
pnp_add_dma_resource(dev, dma->channels[0], flags);
break;
- case ACPI_RESOURCE_TYPE_IO:
- io = &res->data.io;
- pnpacpi_parse_allocated_ioresource(dev,
- io->minimum,
- io->address_length,
- io->io_decode, 0);
- break;
-
case ACPI_RESOURCE_TYPE_START_DEPENDENT:
case ACPI_RESOURCE_TYPE_END_DEPENDENT:
break;
- case ACPI_RESOURCE_TYPE_FIXED_IO:
- fixed_io = &res->data.fixed_io;
- pnpacpi_parse_allocated_ioresource(dev,
- fixed_io->address,
- fixed_io->address_length,
- ACPI_DECODE_10, 0);
- break;
-
case ACPI_RESOURCE_TYPE_VENDOR:
vendor_typed = &res->data.vendor_typed;
pnpacpi_parse_allocated_vendor(dev, vendor_typed);
@@ -411,66 +239,6 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
case ACPI_RESOURCE_TYPE_END_TAG:
break;
- case ACPI_RESOURCE_TYPE_MEMORY24:
- memory24 = &res->data.memory24;
- pnpacpi_parse_allocated_memresource(dev,
- memory24->minimum,
- memory24->address_length,
- memory24->write_protect, 0);
- break;
- case ACPI_RESOURCE_TYPE_MEMORY32:
- memory32 = &res->data.memory32;
- pnpacpi_parse_allocated_memresource(dev,
- memory32->minimum,
- memory32->address_length,
- memory32->write_protect, 0);
- break;
- case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
- fixed_memory32 = &res->data.fixed_memory32;
- pnpacpi_parse_allocated_memresource(dev,
- fixed_memory32->address,
- fixed_memory32->address_length,
- fixed_memory32->write_protect, 0);
- break;
- case ACPI_RESOURCE_TYPE_ADDRESS16:
- case ACPI_RESOURCE_TYPE_ADDRESS32:
- case ACPI_RESOURCE_TYPE_ADDRESS64:
- pnpacpi_parse_allocated_address_space(dev, res);
- break;
-
- case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
- pnpacpi_parse_allocated_ext_address_space(dev, res);
- break;
-
- case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
- extended_irq = &res->data.extended_irq;
-
- if (extended_irq->interrupt_count == 0)
- pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
- else {
- for (i = 0; i < extended_irq->interrupt_count; i++) {
- pnpacpi_parse_allocated_irqresource(dev,
- extended_irq->interrupts[i],
- extended_irq->triggering,
- extended_irq->polarity,
- extended_irq->sharable);
- }
-
- /*
- * The IRQ encoder puts a single interrupt in each
- * descriptor, so if a _CRS descriptor has more than
- * one interrupt, we won't be able to re-encode it.
- */
- if (pnp_can_write(dev) &&
- extended_irq->interrupt_count > 1) {
- dev_warn(&dev->dev, "multiple interrupts in "
- "_CRS descriptor; configuration can't "
- "be changed\n");
- dev->capabilities &= ~PNP_WRITE;
- }
- }
- break;
-
case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
break;
@@ -531,7 +299,7 @@ static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
if (p->interrupts[i])
__set_bit(p->interrupts[i], map.bits);
- flags = irq_flags(p->triggering, p->polarity, p->sharable);
+ flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->sharable);
pnp_register_irq_resource(dev, option_flags, &map, flags);
}
@@ -555,7 +323,7 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
}
}
- flags = irq_flags(p->triggering, p->polarity, p->sharable);
+ flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->sharable);
pnp_register_irq_resource(dev, option_flags, &map, flags);
}
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 9d422264864..5d66e5585f9 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -91,8 +91,6 @@ struct pnp_dev_node_info node_info;
*
*/
-#ifdef CONFIG_HOTPLUG
-
static struct completion unload_sem;
/*
@@ -199,8 +197,6 @@ static int pnp_dock_thread(void *unused)
complete_and_exit(&unload_sem, 0);
}
-#endif /* CONFIG_HOTPLUG */
-
static int pnpbios_get_resources(struct pnp_dev *dev)
{
u8 nodenum = dev->number;
@@ -573,21 +569,19 @@ fs_initcall(pnpbios_init);
static int __init pnpbios_thread_init(void)
{
+ struct task_struct *task;
#if defined(CONFIG_PPC)
if (check_legacy_ioport(PNPBIOS_BASE))
return 0;
#endif
if (pnpbios_disabled)
return 0;
-#ifdef CONFIG_HOTPLUG
- {
- struct task_struct *task;
- init_completion(&unload_sem);
- task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd");
- if (IS_ERR(task))
- return PTR_ERR(task);
- }
-#endif
+
+ init_completion(&unload_sem);
+ task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd");
+ if (IS_ERR(task))
+ return PTR_ERR(task);
+
return 0;
}
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index b0ecacbe53b..3e6db1c1dc2 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -503,6 +503,22 @@ static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev)
return pnp_res;
}
+struct pnp_resource *pnp_add_resource(struct pnp_dev *dev,
+ struct resource *res)
+{
+ struct pnp_resource *pnp_res;
+
+ pnp_res = pnp_new_resource(dev);
+ if (!pnp_res) {
+ dev_err(&dev->dev, "can't add resource %pR\n", res);
+ return NULL;
+ }
+
+ pnp_res->res = *res;
+ dev_dbg(&dev->dev, "%pR\n", res);
+ return pnp_res;
+}
+
struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
int flags)
{
diff --git a/drivers/power/88pm860x_battery.c b/drivers/power/88pm860x_battery.c
index beed5ecf75e..8bc80b05c63 100644
--- a/drivers/power/88pm860x_battery.c
+++ b/drivers/power/88pm860x_battery.c
@@ -901,7 +901,7 @@ static enum power_supply_property pm860x_batt_props[] = {
POWER_SUPPLY_PROP_TEMP,
};
-static __devinit int pm860x_battery_probe(struct platform_device *pdev)
+static int pm860x_battery_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct pm860x_battery_info *info;
@@ -989,7 +989,7 @@ out:
return ret;
}
-static int __devexit pm860x_battery_remove(struct platform_device *pdev)
+static int pm860x_battery_remove(struct platform_device *pdev)
{
struct pm860x_battery_info *info = platform_get_drvdata(pdev);
@@ -1033,7 +1033,7 @@ static struct platform_driver pm860x_battery_driver = {
.pm = &pm860x_battery_pm_ops,
},
.probe = pm860x_battery_probe,
- .remove = __devexit_p(pm860x_battery_remove),
+ .remove = pm860x_battery_remove,
};
module_platform_driver(pm860x_battery_driver);
diff --git a/drivers/power/88pm860x_charger.c b/drivers/power/88pm860x_charger.c
index 2dbeb146090..4b37a5af8de 100644
--- a/drivers/power/88pm860x_charger.c
+++ b/drivers/power/88pm860x_charger.c
@@ -645,7 +645,7 @@ static struct pm860x_irq_desc {
{ "vchg", pm860x_vchg_handler },
};
-static __devinit int pm860x_charger_probe(struct platform_device *pdev)
+static int pm860x_charger_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct pm860x_charger_info *info;
@@ -718,7 +718,7 @@ out:
return ret;
}
-static int __devexit pm860x_charger_remove(struct platform_device *pdev)
+static int pm860x_charger_remove(struct platform_device *pdev)
{
struct pm860x_charger_info *info = platform_get_drvdata(pdev);
int i;
@@ -738,7 +738,7 @@ static struct platform_driver pm860x_charger_driver = {
.owner = THIS_MODULE,
},
.probe = pm860x_charger_probe,
- .remove = __devexit_p(pm860x_charger_remove),
+ .remove = pm860x_charger_remove,
};
module_platform_driver(pm860x_charger_driver);
diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c
index 8135542ee74..20e2a7d3ef4 100644
--- a/drivers/power/ab8500_btemp.c
+++ b/drivers/power/ab8500_btemp.c
@@ -938,7 +938,7 @@ static int ab8500_btemp_suspend(struct platform_device *pdev,
#define ab8500_btemp_resume NULL
#endif
-static int __devexit ab8500_btemp_remove(struct platform_device *pdev)
+static int ab8500_btemp_remove(struct platform_device *pdev)
{
struct ab8500_btemp *di = platform_get_drvdata(pdev);
int i, irq;
@@ -964,7 +964,7 @@ static char *supply_interface[] = {
"ab8500_fg",
};
-static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
+static int ab8500_btemp_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct ab8500_btemp *di;
@@ -1103,7 +1103,7 @@ static const struct of_device_id ab8500_btemp_match[] = {
static struct platform_driver ab8500_btemp_driver = {
.probe = ab8500_btemp_probe,
- .remove = __devexit_p(ab8500_btemp_remove),
+ .remove = ab8500_btemp_remove,
.suspend = ab8500_btemp_suspend,
.resume = ab8500_btemp_resume,
.driver = {
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
index dddc9473f72..3be9c0ee3fc 100644
--- a/drivers/power/ab8500_charger.c
+++ b/drivers/power/ab8500_charger.c
@@ -2492,7 +2492,7 @@ static int ab8500_charger_suspend(struct platform_device *pdev,
#define ab8500_charger_resume NULL
#endif
-static int __devexit ab8500_charger_remove(struct platform_device *pdev)
+static int ab8500_charger_remove(struct platform_device *pdev)
{
struct ab8500_charger *di = platform_get_drvdata(pdev);
int i, irq, ret;
@@ -2538,7 +2538,7 @@ static char *supply_interface[] = {
"ab8500_btemp",
};
-static int __devinit ab8500_charger_probe(struct platform_device *pdev)
+static int ab8500_charger_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct ab8500_charger *di;
@@ -2772,7 +2772,7 @@ static const struct of_device_id ab8500_charger_match[] = {
static struct platform_driver ab8500_charger_driver = {
.probe = ab8500_charger_probe,
- .remove = __devexit_p(ab8500_charger_remove),
+ .remove = ab8500_charger_remove,
.suspend = ab8500_charger_suspend,
.resume = ab8500_charger_resume,
.driver = {
diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c
index ed62ef788eb..b3bf178c346 100644
--- a/drivers/power/ab8500_fg.c
+++ b/drivers/power/ab8500_fg.c
@@ -2410,7 +2410,7 @@ static int ab8500_fg_suspend(struct platform_device *pdev,
#define ab8500_fg_resume NULL
#endif
-static int __devexit ab8500_fg_remove(struct platform_device *pdev)
+static int ab8500_fg_remove(struct platform_device *pdev)
{
int ret = 0;
struct ab8500_fg *di = platform_get_drvdata(pdev);
@@ -2445,7 +2445,7 @@ static char *supply_interface[] = {
"ab8500_usb",
};
-static int __devinit ab8500_fg_probe(struct platform_device *pdev)
+static int ab8500_fg_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct ab8500_fg *di;
@@ -2615,7 +2615,7 @@ static const struct of_device_id ab8500_fg_match[] = {
static struct platform_driver ab8500_fg_driver = {
.probe = ab8500_fg_probe,
- .remove = __devexit_p(ab8500_fg_remove),
+ .remove = ab8500_fg_remove,
.suspend = ab8500_fg_suspend,
.resume = ab8500_fg_resume,
.driver = {
diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c
index dcdc4393b9e..29708914606 100644
--- a/drivers/power/abx500_chargalg.c
+++ b/drivers/power/abx500_chargalg.c
@@ -1782,7 +1782,7 @@ static int abx500_chargalg_suspend(struct platform_device *pdev,
#define abx500_chargalg_resume NULL
#endif
-static int __devexit abx500_chargalg_remove(struct platform_device *pdev)
+static int abx500_chargalg_remove(struct platform_device *pdev)
{
struct abx500_chargalg *di = platform_get_drvdata(pdev);
@@ -1803,7 +1803,7 @@ static char *supply_interface[] = {
"ab8500_fg",
};
-static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
+static int abx500_chargalg_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct abx500_chargalg *di;
@@ -1912,7 +1912,7 @@ static const struct of_device_id ab8500_chargalg_match[] = {
static struct platform_driver abx500_chargalg_driver = {
.probe = abx500_chargalg_probe,
- .remove = __devexit_p(abx500_chargalg_remove),
+ .remove = abx500_chargalg_remove,
.suspend = abx500_chargalg_suspend,
.resume = abx500_chargalg_resume,
.driver = {
diff --git a/drivers/power/avs/smartreflex.c b/drivers/power/avs/smartreflex.c
index 24768a27e1d..d0fed2c5cf2 100644
--- a/drivers/power/avs/smartreflex.c
+++ b/drivers/power/avs/smartreflex.c
@@ -1026,7 +1026,7 @@ err_free_devinfo:
return ret;
}
-static int __devexit omap_sr_remove(struct platform_device *pdev)
+static int omap_sr_remove(struct platform_device *pdev)
{
struct omap_sr_data *pdata = pdev->dev.platform_data;
struct omap_sr *sr_info;
@@ -1059,7 +1059,7 @@ static int __devexit omap_sr_remove(struct platform_device *pdev)
return 0;
}
-static void __devexit omap_sr_shutdown(struct platform_device *pdev)
+static void omap_sr_shutdown(struct platform_device *pdev)
{
struct omap_sr_data *pdata = pdev->dev.platform_data;
struct omap_sr *sr_info;
@@ -1083,8 +1083,8 @@ static void __devexit omap_sr_shutdown(struct platform_device *pdev)
}
static struct platform_driver smartreflex_driver = {
- .remove = __devexit_p(omap_sr_remove),
- .shutdown = __devexit_p(omap_sr_shutdown),
+ .remove = omap_sr_remove,
+ .shutdown = omap_sr_shutdown,
.driver = {
.name = "smartreflex",
},
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 41b3328ecfc..36b34efdafc 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -934,7 +934,7 @@ static int bq27000_read_platform(struct bq27x00_device_info *di, u8 reg,
return pdata->read(dev, reg);
}
-static int __devinit bq27000_battery_probe(struct platform_device *pdev)
+static int bq27000_battery_probe(struct platform_device *pdev)
{
struct bq27x00_device_info *di;
struct bq27000_platform_data *pdata = pdev->dev.platform_data;
@@ -977,7 +977,7 @@ err_free:
return ret;
}
-static int __devexit bq27000_battery_remove(struct platform_device *pdev)
+static int bq27000_battery_remove(struct platform_device *pdev)
{
struct bq27x00_device_info *di = platform_get_drvdata(pdev);
@@ -991,7 +991,7 @@ static int __devexit bq27000_battery_remove(struct platform_device *pdev)
static struct platform_driver bq27000_battery_driver = {
.probe = bq27000_battery_probe,
- .remove = __devexit_p(bq27000_battery_remove),
+ .remove = bq27000_battery_remove,
.driver = {
.name = "bq27000-battery",
.owner = THIS_MODULE,
diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
index 8a0aca6364c..adb3a4b59cb 100644
--- a/drivers/power/charger-manager.c
+++ b/drivers/power/charger-manager.c
@@ -1655,7 +1655,7 @@ err_alloc:
return ret;
}
-static int __devexit charger_manager_remove(struct platform_device *pdev)
+static int charger_manager_remove(struct platform_device *pdev)
{
struct charger_manager *cm = platform_get_drvdata(pdev);
struct charger_desc *desc = cm->desc;
@@ -1812,7 +1812,7 @@ static struct platform_driver charger_manager_driver = {
.pm = &charger_manager_pm,
},
.probe = charger_manager_probe,
- .remove = __devexit_p(charger_manager_remove),
+ .remove = charger_manager_remove,
.id_table = charger_manager_id,
};
diff --git a/drivers/power/collie_battery.c b/drivers/power/collie_battery.c
index b19bfe400f8..c58d0e31bde 100644
--- a/drivers/power/collie_battery.c
+++ b/drivers/power/collie_battery.c
@@ -305,7 +305,7 @@ static int collie_bat_resume(struct ucb1x00_dev *dev)
#define collie_bat_resume NULL
#endif
-static int __devinit collie_bat_probe(struct ucb1x00_dev *dev)
+static int collie_bat_probe(struct ucb1x00_dev *dev)
{
int ret;
@@ -349,7 +349,7 @@ err_psy_reg_main:
return ret;
}
-static void __devexit collie_bat_remove(struct ucb1x00_dev *dev)
+static void collie_bat_remove(struct ucb1x00_dev *dev)
{
free_irq(gpio_to_irq(COLLIE_GPIO_CO), &collie_bat_main);
@@ -367,7 +367,7 @@ static void __devexit collie_bat_remove(struct ucb1x00_dev *dev)
static struct ucb1x00_driver collie_bat_driver = {
.add = collie_bat_probe,
- .remove = __devexit_p(collie_bat_remove),
+ .remove = collie_bat_remove,
.suspend = collie_bat_suspend,
.resume = collie_bat_resume,
};
diff --git a/drivers/power/da9052-battery.c b/drivers/power/da9052-battery.c
index d9d034d7496..bb0df8917ad 100644
--- a/drivers/power/da9052-battery.c
+++ b/drivers/power/da9052-battery.c
@@ -576,7 +576,7 @@ static const char *const da9052_bat_irqs[] = {
"CHG END",
};
-static s32 __devinit da9052_bat_probe(struct platform_device *pdev)
+static s32 da9052_bat_probe(struct platform_device *pdev)
{
struct da9052_pdata *pdata;
struct da9052_battery *bat;
@@ -630,7 +630,7 @@ err:
kfree(bat);
return ret;
}
-static int __devexit da9052_bat_remove(struct platform_device *pdev)
+static int da9052_bat_remove(struct platform_device *pdev)
{
int i;
int irq;
@@ -648,7 +648,7 @@ static int __devexit da9052_bat_remove(struct platform_device *pdev)
static struct platform_driver da9052_bat_driver = {
.probe = da9052_bat_probe,
- .remove = __devexit_p(da9052_bat_remove),
+ .remove = da9052_bat_remove,
.driver = {
.name = "da9052-bat",
.owner = THIS_MODULE,
diff --git a/drivers/power/ds2780_battery.c b/drivers/power/ds2780_battery.c
index 74fad941c56..8b6c4539e7f 100644
--- a/drivers/power/ds2780_battery.c
+++ b/drivers/power/ds2780_battery.c
@@ -755,7 +755,7 @@ static const struct attribute_group ds2780_attr_group = {
.attrs = ds2780_attributes,
};
-static int __devinit ds2780_battery_probe(struct platform_device *pdev)
+static int ds2780_battery_probe(struct platform_device *pdev)
{
int ret = 0;
struct ds2780_device_info *dev_info;
@@ -819,7 +819,7 @@ fail:
return ret;
}
-static int __devexit ds2780_battery_remove(struct platform_device *pdev)
+static int ds2780_battery_remove(struct platform_device *pdev)
{
struct ds2780_device_info *dev_info = platform_get_drvdata(pdev);
@@ -837,7 +837,7 @@ static struct platform_driver ds2780_battery_driver = {
.name = "ds2780-battery",
},
.probe = ds2780_battery_probe,
- .remove = __devexit_p(ds2780_battery_remove),
+ .remove = ds2780_battery_remove,
};
module_platform_driver(ds2780_battery_driver);
diff --git a/drivers/power/ds2781_battery.c b/drivers/power/ds2781_battery.c
index 22b3c8c9355..0a5acc6fc6f 100644
--- a/drivers/power/ds2781_battery.c
+++ b/drivers/power/ds2781_battery.c
@@ -750,7 +750,7 @@ static const struct attribute_group ds2781_attr_group = {
.attrs = ds2781_attributes,
};
-static int __devinit ds2781_battery_probe(struct platform_device *pdev)
+static int ds2781_battery_probe(struct platform_device *pdev)
{
int ret = 0;
struct ds2781_device_info *dev_info;
@@ -810,7 +810,7 @@ fail:
return ret;
}
-static int __devexit ds2781_battery_remove(struct platform_device *pdev)
+static int ds2781_battery_remove(struct platform_device *pdev)
{
struct ds2781_device_info *dev_info = platform_get_drvdata(pdev);
@@ -827,7 +827,7 @@ static struct platform_driver ds2781_battery_driver = {
.name = "ds2781-battery",
},
.probe = ds2781_battery_probe,
- .remove = __devexit_p(ds2781_battery_remove),
+ .remove = ds2781_battery_remove,
};
module_platform_driver(ds2781_battery_driver);
diff --git a/drivers/power/generic-adc-battery.c b/drivers/power/generic-adc-battery.c
index ecbf672a35d..32ce17e235c 100644
--- a/drivers/power/generic-adc-battery.c
+++ b/drivers/power/generic-adc-battery.c
@@ -236,7 +236,7 @@ static irqreturn_t gab_charged(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __devinit gab_probe(struct platform_device *pdev)
+static int gab_probe(struct platform_device *pdev)
{
struct gab *adc_bat;
struct power_supply *psy;
@@ -352,7 +352,7 @@ first_mem_fail:
return ret;
}
-static int __devexit gab_remove(struct platform_device *pdev)
+static int gab_remove(struct platform_device *pdev)
{
int chan;
struct gab *adc_bat = platform_get_drvdata(pdev);
@@ -414,7 +414,7 @@ static struct platform_driver gab_driver = {
.pm = GAB_PM_OPS
},
.probe = gab_probe,
- .remove = __devexit_p(gab_remove),
+ .remove = gab_remove,
};
module_platform_driver(gab_driver);
diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c
index cb2aa319568..e3e40a9f3af 100644
--- a/drivers/power/gpio-charger.c
+++ b/drivers/power/gpio-charger.c
@@ -68,7 +68,7 @@ static enum power_supply_property gpio_charger_properties[] = {
POWER_SUPPLY_PROP_ONLINE,
};
-static int __devinit gpio_charger_probe(struct platform_device *pdev)
+static int gpio_charger_probe(struct platform_device *pdev)
{
const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data;
struct gpio_charger *gpio_charger;
@@ -144,7 +144,7 @@ err_free:
return ret;
}
-static int __devexit gpio_charger_remove(struct platform_device *pdev)
+static int gpio_charger_remove(struct platform_device *pdev)
{
struct gpio_charger *gpio_charger = platform_get_drvdata(pdev);
@@ -177,7 +177,7 @@ static SIMPLE_DEV_PM_OPS(gpio_charger_pm_ops, NULL, gpio_charger_resume);
static struct platform_driver gpio_charger_driver = {
.probe = gpio_charger_probe,
- .remove = __devexit_p(gpio_charger_remove),
+ .remove = gpio_charger_remove,
.driver = {
.name = "gpio-charger",
.owner = THIS_MODULE,
diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c
index d09649706bd..18d136b443e 100644
--- a/drivers/power/intel_mid_battery.c
+++ b/drivers/power/intel_mid_battery.c
@@ -649,7 +649,7 @@ static void pmic_battery_handle_intrpt(struct work_struct *work)
* PMIC battery initializes its internal data structue and other
* infrastructure components for it to work as expected.
*/
-static __devinit int probe(int irq, struct device *dev)
+static int probe(int irq, struct device *dev)
{
int retval = 0;
struct pmic_power_module_info *pbi;
@@ -739,7 +739,7 @@ wqueue_failed:
return retval;
}
-static int __devinit platform_pmic_battery_probe(struct platform_device *pdev)
+static int platform_pmic_battery_probe(struct platform_device *pdev)
{
return probe(pdev->id, &pdev->dev);
}
@@ -754,7 +754,7 @@ static int __devinit platform_pmic_battery_probe(struct platform_device *pdev)
* pmic_battery_probe.
*/
-static int __devexit platform_pmic_battery_remove(struct platform_device *pdev)
+static int platform_pmic_battery_remove(struct platform_device *pdev)
{
struct pmic_power_module_info *pbi = dev_get_drvdata(&pdev->dev);
@@ -776,7 +776,7 @@ static struct platform_driver platform_pmic_battery_driver = {
.owner = THIS_MODULE,
},
.probe = platform_pmic_battery_probe,
- .remove = __devexit_p(platform_pmic_battery_remove),
+ .remove = platform_pmic_battery_remove,
};
module_platform_driver(platform_pmic_battery_driver);
diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c
index 122911978da..176ad59d99f 100644
--- a/drivers/power/isp1704_charger.c
+++ b/drivers/power/isp1704_charger.c
@@ -406,7 +406,7 @@ static inline int isp1704_test_ulpi(struct isp1704_charger *isp)
return -ENODEV;
}
-static int __devinit isp1704_charger_probe(struct platform_device *pdev)
+static int isp1704_charger_probe(struct platform_device *pdev)
{
struct isp1704_charger *isp;
int ret = -ENODEV;
@@ -484,7 +484,7 @@ fail0:
return ret;
}
-static int __devexit isp1704_charger_remove(struct platform_device *pdev)
+static int isp1704_charger_remove(struct platform_device *pdev)
{
struct isp1704_charger *isp = platform_get_drvdata(pdev);
@@ -502,7 +502,7 @@ static struct platform_driver isp1704_charger_driver = {
.name = "isp1704_charger",
},
.probe = isp1704_charger_probe,
- .remove = __devexit_p(isp1704_charger_remove),
+ .remove = isp1704_charger_remove,
};
module_platform_driver(isp1704_charger_driver);
diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c
index fc7550d4d56..bf914893c6f 100644
--- a/drivers/power/jz4740-battery.c
+++ b/drivers/power/jz4740-battery.c
@@ -237,7 +237,7 @@ static void jz_battery_work(struct work_struct *work)
schedule_delayed_work(&jz_battery->work, interval);
}
-static int __devinit jz_battery_probe(struct platform_device *pdev)
+static int jz_battery_probe(struct platform_device *pdev)
{
int ret = 0;
struct jz_battery_platform_data *pdata = pdev->dev.parent->platform_data;
@@ -353,7 +353,7 @@ err:
return ret;
}
-static int __devexit jz_battery_remove(struct platform_device *pdev)
+static int jz_battery_remove(struct platform_device *pdev)
{
struct jz_battery *jz_battery = platform_get_drvdata(pdev);
@@ -404,7 +404,7 @@ static const struct dev_pm_ops jz_battery_pm_ops = {
static struct platform_driver jz_battery_driver = {
.probe = jz_battery_probe,
- .remove = __devexit_p(jz_battery_remove),
+ .remove = jz_battery_remove,
.driver = {
.name = "jz4740-battery",
.owner = THIS_MODULE,
diff --git a/drivers/power/lp8727_charger.c b/drivers/power/lp8727_charger.c
index c628224b7f5..4ee71a90e24 100644
--- a/drivers/power/lp8727_charger.c
+++ b/drivers/power/lp8727_charger.c
@@ -522,7 +522,7 @@ static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id)
return 0;
}
-static int __devexit lp8727_remove(struct i2c_client *cl)
+static int lp8727_remove(struct i2c_client *cl)
{
struct lp8727_chg *pchg = i2c_get_clientdata(cl);
@@ -542,7 +542,7 @@ static struct i2c_driver lp8727_driver = {
.name = "lp8727",
},
.probe = lp8727_probe,
- .remove = __devexit_p(lp8727_remove),
+ .remove = lp8727_remove,
.id_table = lp8727_ids,
};
module_i2c_driver(lp8727_driver);
diff --git a/drivers/power/lp8788-charger.c b/drivers/power/lp8788-charger.c
index fb592bfbec6..22b6407c9ca 100644
--- a/drivers/power/lp8788-charger.c
+++ b/drivers/power/lp8788-charger.c
@@ -686,7 +686,7 @@ static const struct attribute_group lp8788_attr_group = {
.attrs = lp8788_charger_attr,
};
-static __devinit int lp8788_charger_probe(struct platform_device *pdev)
+static int lp8788_charger_probe(struct platform_device *pdev)
{
struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
struct lp8788_charger *pchg;
@@ -723,7 +723,7 @@ static __devinit int lp8788_charger_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit lp8788_charger_remove(struct platform_device *pdev)
+static int lp8788_charger_remove(struct platform_device *pdev)
{
struct lp8788_charger *pchg = platform_get_drvdata(pdev);
@@ -738,7 +738,7 @@ static int __devexit lp8788_charger_remove(struct platform_device *pdev)
static struct platform_driver lp8788_charger_driver = {
.probe = lp8788_charger_probe,
- .remove = __devexit_p(lp8788_charger_remove),
+ .remove = lp8788_charger_remove,
.driver = {
.name = LP8788_DEV_CHARGER,
.owner = THIS_MODULE,
diff --git a/drivers/power/max17040_battery.c b/drivers/power/max17040_battery.c
index 58e67830143..22cfe9cc472 100644
--- a/drivers/power/max17040_battery.c
+++ b/drivers/power/max17040_battery.c
@@ -197,7 +197,7 @@ static enum power_supply_property max17040_battery_props[] = {
POWER_SUPPLY_PROP_CAPACITY,
};
-static int __devinit max17040_probe(struct i2c_client *client,
+static int max17040_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
@@ -238,7 +238,7 @@ static int __devinit max17040_probe(struct i2c_client *client,
return 0;
}
-static int __devexit max17040_remove(struct i2c_client *client)
+static int max17040_remove(struct i2c_client *client)
{
struct max17040_chip *chip = i2c_get_clientdata(client);
@@ -285,7 +285,7 @@ static struct i2c_driver max17040_i2c_driver = {
.name = "max17040",
},
.probe = max17040_probe,
- .remove = __devexit_p(max17040_remove),
+ .remove = max17040_remove,
.suspend = max17040_suspend,
.resume = max17040_resume,
.id_table = max17040_id,
diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c
index 66b2c7b5091..d664ef58afa 100644
--- a/drivers/power/max17042_battery.c
+++ b/drivers/power/max17042_battery.c
@@ -682,7 +682,7 @@ max17042_get_pdata(struct device *dev)
}
#endif
-static int __devinit max17042_probe(struct i2c_client *client,
+static int max17042_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
@@ -776,7 +776,7 @@ static int __devinit max17042_probe(struct i2c_client *client,
return 0;
}
-static int __devexit max17042_remove(struct i2c_client *client)
+static int max17042_remove(struct i2c_client *client)
{
struct max17042_chip *chip = i2c_get_clientdata(client);
@@ -852,7 +852,7 @@ static struct i2c_driver max17042_i2c_driver = {
.pm = MAX17042_PM_OPS,
},
.probe = max17042_probe,
- .remove = __devexit_p(max17042_remove),
+ .remove = max17042_remove,
.id_table = max17042_id,
};
module_i2c_driver(max17042_i2c_driver);
diff --git a/drivers/power/max8903_charger.c b/drivers/power/max8903_charger.c
index 3e23f43e98a..14e2b96d93b 100644
--- a/drivers/power/max8903_charger.c
+++ b/drivers/power/max8903_charger.c
@@ -179,7 +179,7 @@ static irqreturn_t max8903_fault(int irq, void *_data)
return IRQ_HANDLED;
}
-static __devinit int max8903_probe(struct platform_device *pdev)
+static int max8903_probe(struct platform_device *pdev)
{
struct max8903_data *data;
struct device *dev = &pdev->dev;
@@ -345,7 +345,7 @@ err:
return ret;
}
-static __devexit int max8903_remove(struct platform_device *pdev)
+static int max8903_remove(struct platform_device *pdev)
{
struct max8903_data *data = platform_get_drvdata(pdev);
@@ -367,7 +367,7 @@ static __devexit int max8903_remove(struct platform_device *pdev)
static struct platform_driver max8903_driver = {
.probe = max8903_probe,
- .remove = __devexit_p(max8903_remove),
+ .remove = max8903_remove,
.driver = {
.name = "max8903-charger",
.owner = THIS_MODULE,
diff --git a/drivers/power/max8925_power.c b/drivers/power/max8925_power.c
index b5a3ccb16a1..665cdc76c26 100644
--- a/drivers/power/max8925_power.c
+++ b/drivers/power/max8925_power.c
@@ -357,7 +357,7 @@ do { \
_irq, ret); \
} while (0)
-static __devinit int max8925_init_charger(struct max8925_chip *chip,
+static int max8925_init_charger(struct max8925_chip *chip,
struct max8925_power_info *info)
{
int ret;
@@ -415,7 +415,7 @@ static __devinit int max8925_init_charger(struct max8925_chip *chip,
return 0;
}
-static __devexit int max8925_deinit_charger(struct max8925_power_info *info)
+static int max8925_deinit_charger(struct max8925_power_info *info)
{
struct max8925_chip *chip = info->chip;
int irq;
@@ -475,7 +475,7 @@ max8925_power_dt_init(struct platform_device *pdev)
}
#endif
-static __devinit int max8925_power_probe(struct platform_device *pdev)
+static int max8925_power_probe(struct platform_device *pdev)
{
struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct max8925_power_pdata *pdata = NULL;
@@ -550,7 +550,7 @@ out:
return ret;
}
-static __devexit int max8925_power_remove(struct platform_device *pdev)
+static int max8925_power_remove(struct platform_device *pdev)
{
struct max8925_power_info *info = platform_get_drvdata(pdev);
@@ -566,7 +566,7 @@ static __devexit int max8925_power_remove(struct platform_device *pdev)
static struct platform_driver max8925_power_driver = {
.probe = max8925_power_probe,
- .remove = __devexit_p(max8925_power_remove),
+ .remove = max8925_power_remove,
.driver = {
.name = "max8925-power",
},
diff --git a/drivers/power/max8997_charger.c b/drivers/power/max8997_charger.c
index 6e88c5d026b..e757885b620 100644
--- a/drivers/power/max8997_charger.c
+++ b/drivers/power/max8997_charger.c
@@ -86,7 +86,7 @@ static int max8997_battery_get_property(struct power_supply *psy,
return 0;
}
-static __devinit int max8997_battery_probe(struct platform_device *pdev)
+static int max8997_battery_probe(struct platform_device *pdev)
{
int ret = 0;
struct charger_data *charger;
@@ -167,7 +167,7 @@ err:
return ret;
}
-static int __devexit max8997_battery_remove(struct platform_device *pdev)
+static int max8997_battery_remove(struct platform_device *pdev)
{
struct charger_data *charger = platform_get_drvdata(pdev);
@@ -187,7 +187,7 @@ static struct platform_driver max8997_battery_driver = {
.owner = THIS_MODULE,
},
.probe = max8997_battery_probe,
- .remove = __devexit_p(max8997_battery_remove),
+ .remove = max8997_battery_remove,
.id_table = max8997_battery_id,
};
diff --git a/drivers/power/max8998_charger.c b/drivers/power/max8998_charger.c
index 6dc01c25559..bf677e3daec 100644
--- a/drivers/power/max8998_charger.c
+++ b/drivers/power/max8998_charger.c
@@ -75,7 +75,7 @@ static int max8998_battery_get_property(struct power_supply *psy,
return 0;
}
-static __devinit int max8998_battery_probe(struct platform_device *pdev)
+static int max8998_battery_probe(struct platform_device *pdev)
{
struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev);
@@ -178,7 +178,7 @@ err:
return ret;
}
-static int __devexit max8998_battery_remove(struct platform_device *pdev)
+static int max8998_battery_remove(struct platform_device *pdev)
{
struct max8998_battery_data *max8998 = platform_get_drvdata(pdev);
@@ -199,7 +199,7 @@ static struct platform_driver max8998_battery_driver = {
.owner = THIS_MODULE,
},
.probe = max8998_battery_probe,
- .remove = __devexit_p(max8998_battery_remove),
+ .remove = max8998_battery_remove,
.id_table = max8998_battery_id,
};
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c
index a89a41acf9c..298c47d111b 100644
--- a/drivers/power/olpc_battery.c
+++ b/drivers/power/olpc_battery.c
@@ -598,7 +598,7 @@ static int olpc_battery_suspend(struct platform_device *pdev,
return 0;
}
-static int __devinit olpc_battery_probe(struct platform_device *pdev)
+static int olpc_battery_probe(struct platform_device *pdev)
{
int ret;
uint8_t status;
@@ -659,7 +659,7 @@ battery_failed:
return ret;
}
-static int __devexit olpc_battery_remove(struct platform_device *pdev)
+static int olpc_battery_remove(struct platform_device *pdev)
{
device_remove_file(olpc_bat.dev, &olpc_bat_error);
device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom);
@@ -681,7 +681,7 @@ static struct platform_driver olpc_battery_driver = {
.of_match_table = olpc_battery_ids,
},
.probe = olpc_battery_probe,
- .remove = __devexit_p(olpc_battery_remove),
+ .remove = olpc_battery_remove,
.suspend = olpc_battery_suspend,
};
diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c
index 3d1e9efb6f5..c2122a7ad06 100644
--- a/drivers/power/pcf50633-charger.c
+++ b/drivers/power/pcf50633-charger.c
@@ -366,7 +366,7 @@ static const u8 mbc_irq_handlers[] = {
PCF50633_IRQ_LOWBAT,
};
-static int __devinit pcf50633_mbc_probe(struct platform_device *pdev)
+static int pcf50633_mbc_probe(struct platform_device *pdev)
{
struct pcf50633_mbc *mbc;
int ret;
@@ -447,7 +447,7 @@ static int __devinit pcf50633_mbc_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit pcf50633_mbc_remove(struct platform_device *pdev)
+static int pcf50633_mbc_remove(struct platform_device *pdev)
{
struct pcf50633_mbc *mbc = platform_get_drvdata(pdev);
int i;
@@ -471,7 +471,7 @@ static struct platform_driver pcf50633_mbc_driver = {
.name = "pcf50633-mbc",
},
.probe = pcf50633_mbc_probe,
- .remove = __devexit_p(pcf50633_mbc_remove),
+ .remove = pcf50633_mbc_remove,
};
module_platform_driver(pcf50633_mbc_driver);
diff --git a/drivers/power/s3c_adc_battery.c b/drivers/power/s3c_adc_battery.c
index 8b804a56675..d2ca989dcbd 100644
--- a/drivers/power/s3c_adc_battery.c
+++ b/drivers/power/s3c_adc_battery.c
@@ -286,7 +286,7 @@ static irqreturn_t s3c_adc_bat_charged(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __devinit s3c_adc_bat_probe(struct platform_device *pdev)
+static int s3c_adc_bat_probe(struct platform_device *pdev)
{
struct s3c_adc_client *client;
struct s3c_adc_bat_pdata *pdata = pdev->dev.platform_data;
diff --git a/drivers/power/sbs-battery.c b/drivers/power/sbs-battery.c
index 4146596d254..3960f0b2afe 100644
--- a/drivers/power/sbs-battery.c
+++ b/drivers/power/sbs-battery.c
@@ -675,7 +675,7 @@ static struct sbs_platform_data *sbs_of_populate_pdata(
}
#endif
-static int __devinit sbs_probe(struct i2c_client *client,
+static int sbs_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct sbs_info *chip;
@@ -800,7 +800,7 @@ exit_free_name:
return rc;
}
-static int __devexit sbs_remove(struct i2c_client *client)
+static int sbs_remove(struct i2c_client *client)
{
struct sbs_info *chip = i2c_get_clientdata(client);
@@ -853,7 +853,7 @@ MODULE_DEVICE_TABLE(i2c, sbs_id);
static struct i2c_driver sbs_battery_driver = {
.probe = sbs_probe,
- .remove = __devexit_p(sbs_remove),
+ .remove = sbs_remove,
.suspend = sbs_suspend,
.resume = sbs_resume,
.id_table = sbs_id,
diff --git a/drivers/power/smb347-charger.c b/drivers/power/smb347-charger.c
index a9707c11fbe..acf84e80fe9 100644
--- a/drivers/power/smb347-charger.c
+++ b/drivers/power/smb347-charger.c
@@ -1313,7 +1313,7 @@ static struct i2c_driver smb347_driver = {
.name = "smb347",
},
.probe = smb347_probe,
- .remove = __devexit_p(smb347_remove),
+ .remove = smb347_remove,
.id_table = smb347_id,
};
diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c
index 51199b5ce22..0224de50c54 100644
--- a/drivers/power/tosa_battery.c
+++ b/drivers/power/tosa_battery.c
@@ -342,7 +342,7 @@ static int tosa_bat_resume(struct platform_device *dev)
#define tosa_bat_resume NULL
#endif
-static int __devinit tosa_bat_probe(struct platform_device *dev)
+static int tosa_bat_probe(struct platform_device *dev)
{
int ret;
@@ -409,7 +409,7 @@ err_psy_reg_main:
return ret;
}
-static int __devexit tosa_bat_remove(struct platform_device *dev)
+static int tosa_bat_remove(struct platform_device *dev)
{
free_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT), &tosa_bat_jacket);
free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket);
@@ -433,7 +433,7 @@ static struct platform_driver tosa_bat_driver = {
.driver.name = "wm97xx-battery",
.driver.owner = THIS_MODULE,
.probe = tosa_bat_probe,
- .remove = __devexit_p(tosa_bat_remove),
+ .remove = tosa_bat_remove,
.suspend = tosa_bat_suspend,
.resume = tosa_bat_resume,
};
diff --git a/drivers/power/wm831x_backup.c b/drivers/power/wm831x_backup.c
index 6243e697512..d9cc169f142 100644
--- a/drivers/power/wm831x_backup.c
+++ b/drivers/power/wm831x_backup.c
@@ -161,7 +161,7 @@ static enum power_supply_property wm831x_backup_props[] = {
* Initialisation
*********************************************************************/
-static __devinit int wm831x_backup_probe(struct platform_device *pdev)
+static int wm831x_backup_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data;
@@ -207,7 +207,7 @@ err_kmalloc:
return ret;
}
-static __devexit int wm831x_backup_remove(struct platform_device *pdev)
+static int wm831x_backup_remove(struct platform_device *pdev)
{
struct wm831x_backup *devdata = platform_get_drvdata(pdev);
@@ -220,7 +220,7 @@ static __devexit int wm831x_backup_remove(struct platform_device *pdev)
static struct platform_driver wm831x_backup_driver = {
.probe = wm831x_backup_probe,
- .remove = __devexit_p(wm831x_backup_remove),
+ .remove = wm831x_backup_remove,
.driver = {
.name = "wm831x-backup",
},
diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
index fc1ad955118..3bed2f55cf7 100644
--- a/drivers/power/wm831x_power.c
+++ b/drivers/power/wm831x_power.c
@@ -489,7 +489,7 @@ static irqreturn_t wm831x_pwr_src_irq(int irq, void *data)
return IRQ_HANDLED;
}
-static __devinit int wm831x_power_probe(struct platform_device *pdev)
+static int wm831x_power_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data;
@@ -625,7 +625,7 @@ err_kmalloc:
return ret;
}
-static __devexit int wm831x_power_remove(struct platform_device *pdev)
+static int wm831x_power_remove(struct platform_device *pdev)
{
struct wm831x_power *wm831x_power = platform_get_drvdata(pdev);
struct wm831x *wm831x = wm831x_power->wm831x;
@@ -654,7 +654,7 @@ static __devexit int wm831x_power_remove(struct platform_device *pdev)
static struct platform_driver wm831x_power_driver = {
.probe = wm831x_power_probe,
- .remove = __devexit_p(wm831x_power_remove),
+ .remove = wm831x_power_remove,
.driver = {
.name = "wm831x-power",
},
diff --git a/drivers/power/wm8350_power.c b/drivers/power/wm8350_power.c
index fae04d38465..b3607e2906d 100644
--- a/drivers/power/wm8350_power.c
+++ b/drivers/power/wm8350_power.c
@@ -442,7 +442,7 @@ static void free_charger_irq(struct wm8350 *wm8350)
wm8350_free_irq(wm8350, WM8350_IRQ_EXT_BAT_FB, wm8350);
}
-static __devinit int wm8350_power_probe(struct platform_device *pdev)
+static int wm8350_power_probe(struct platform_device *pdev)
{
struct wm8350 *wm8350 = platform_get_drvdata(pdev);
struct wm8350_power *power = &wm8350->power;
@@ -501,7 +501,7 @@ battery_failed:
return ret;
}
-static __devexit int wm8350_power_remove(struct platform_device *pdev)
+static int wm8350_power_remove(struct platform_device *pdev)
{
struct wm8350 *wm8350 = platform_get_drvdata(pdev);
struct wm8350_power *power = &wm8350->power;
@@ -516,7 +516,7 @@ static __devexit int wm8350_power_remove(struct platform_device *pdev)
static struct platform_driver wm8350_power_driver = {
.probe = wm8350_power_probe,
- .remove = __devexit_p(wm8350_power_remove),
+ .remove = wm8350_power_remove,
.driver = {
.name = "wm8350-power",
},
diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c
index e128a813dc2..58f7348e6c2 100644
--- a/drivers/power/wm97xx_battery.c
+++ b/drivers/power/wm97xx_battery.c
@@ -162,7 +162,7 @@ static const struct dev_pm_ops wm97xx_bat_pm_ops = {
};
#endif
-static int __devinit wm97xx_bat_probe(struct platform_device *dev)
+static int wm97xx_bat_probe(struct platform_device *dev)
{
int ret = 0;
int props = 1; /* POWER_SUPPLY_PROP_PRESENT */
@@ -263,7 +263,7 @@ err:
return ret;
}
-static int __devexit wm97xx_bat_remove(struct platform_device *dev)
+static int wm97xx_bat_remove(struct platform_device *dev)
{
struct wm97xx_pdata *wmdata = dev->dev.platform_data;
struct wm97xx_batt_pdata *pdata = wmdata->batt_pdata;
@@ -287,7 +287,7 @@ static struct platform_driver wm97xx_bat_driver = {
#endif
},
.probe = wm97xx_bat_probe,
- .remove = __devexit_p(wm97xx_bat_remove),
+ .remove = wm97xx_bat_remove,
};
module_platform_driver(wm97xx_bat_driver);
diff --git a/drivers/power/z2_battery.c b/drivers/power/z2_battery.c
index 5757d0d6782..814d2e31f0c 100644
--- a/drivers/power/z2_battery.c
+++ b/drivers/power/z2_battery.c
@@ -180,7 +180,7 @@ static int z2_batt_ps_init(struct z2_charger *charger, int props)
return 0;
}
-static int __devinit z2_batt_probe(struct i2c_client *client,
+static int z2_batt_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret = 0;
@@ -251,7 +251,7 @@ err:
return ret;
}
-static int __devexit z2_batt_remove(struct i2c_client *client)
+static int z2_batt_remove(struct i2c_client *client)
{
struct z2_charger *charger = i2c_get_clientdata(client);
struct z2_battery_info *info = charger->info;
@@ -313,7 +313,7 @@ static struct i2c_driver z2_batt_driver = {
.pm = Z2_BATTERY_PM_OPS
},
.probe = z2_batt_probe,
- .remove = __devexit_p(z2_batt_remove),
+ .remove = z2_batt_remove,
.id_table = z2_batt_id,
};
module_i2c_driver(z2_batt_driver);
diff --git a/drivers/ptp/ptp_pch.c b/drivers/ptp/ptp_pch.c
index e624e4dd2ab..1367655eee3 100644
--- a/drivers/ptp/ptp_pch.c
+++ b/drivers/ptp/ptp_pch.c
@@ -557,7 +557,7 @@ static s32 pch_resume(struct pci_dev *pdev)
#define pch_resume NULL
#endif
-static void __devexit pch_remove(struct pci_dev *pdev)
+static void pch_remove(struct pci_dev *pdev)
{
struct pch_dev *chip = pci_get_drvdata(pdev);
@@ -581,7 +581,7 @@ static void __devexit pch_remove(struct pci_dev *pdev)
dev_info(&pdev->dev, "complete\n");
}
-static s32 __devinit
+static s32
pch_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
s32 ret;
diff --git a/drivers/pwm/pwm-ab8500.c b/drivers/pwm/pwm-ab8500.c
index cfb72ca873d..4248d041827 100644
--- a/drivers/pwm/pwm-ab8500.c
+++ b/drivers/pwm/pwm-ab8500.c
@@ -90,7 +90,7 @@ static const struct pwm_ops ab8500_pwm_ops = {
.disable = ab8500_pwm_disable,
};
-static int __devinit ab8500_pwm_probe(struct platform_device *pdev)
+static int ab8500_pwm_probe(struct platform_device *pdev)
{
struct ab8500_pwm_chip *ab8500;
int err;
@@ -122,7 +122,7 @@ static int __devinit ab8500_pwm_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit ab8500_pwm_remove(struct platform_device *pdev)
+static int ab8500_pwm_remove(struct platform_device *pdev)
{
struct ab8500_pwm_chip *ab8500 = platform_get_drvdata(pdev);
int err;
@@ -143,7 +143,7 @@ static struct platform_driver ab8500_pwm_driver = {
.owner = THIS_MODULE,
},
.probe = ab8500_pwm_probe,
- .remove = __devexit_p(ab8500_pwm_remove),
+ .remove = ab8500_pwm_remove,
};
module_platform_driver(ab8500_pwm_driver);
diff --git a/drivers/pwm/pwm-bfin.c b/drivers/pwm/pwm-bfin.c
index 5da8e185e83..7631ef194de 100644
--- a/drivers/pwm/pwm-bfin.c
+++ b/drivers/pwm/pwm-bfin.c
@@ -139,7 +139,7 @@ static int bfin_pwm_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit bfin_pwm_remove(struct platform_device *pdev)
+static int bfin_pwm_remove(struct platform_device *pdev)
{
struct bfin_pwm_chip *pwm = platform_get_drvdata(pdev);
@@ -151,7 +151,7 @@ static struct platform_driver bfin_pwm_driver = {
.name = "bfin-pwm",
},
.probe = bfin_pwm_probe,
- .remove = __devexit_p(bfin_pwm_remove),
+ .remove = bfin_pwm_remove,
};
module_platform_driver(bfin_pwm_driver);
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index 8a5d3ae2946..8f26e9fcea9 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -231,7 +231,7 @@ static const struct of_device_id imx_pwm_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, imx_pwm_dt_ids);
-static int __devinit imx_pwm_probe(struct platform_device *pdev)
+static int imx_pwm_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
of_match_device(imx_pwm_dt_ids, &pdev->dev);
@@ -290,7 +290,7 @@ static int __devinit imx_pwm_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit imx_pwm_remove(struct platform_device *pdev)
+static int imx_pwm_remove(struct platform_device *pdev)
{
struct imx_chip *imx;
@@ -307,7 +307,7 @@ static struct platform_driver imx_pwm_driver = {
.of_match_table = of_match_ptr(imx_pwm_dt_ids),
},
.probe = imx_pwm_probe,
- .remove = __devexit_p(imx_pwm_remove),
+ .remove = imx_pwm_remove,
};
module_platform_driver(imx_pwm_driver);
diff --git a/drivers/pwm/pwm-jz4740.c b/drivers/pwm/pwm-jz4740.c
index 10250fcefb9..0a2ede3c393 100644
--- a/drivers/pwm/pwm-jz4740.c
+++ b/drivers/pwm/pwm-jz4740.c
@@ -162,7 +162,7 @@ static const struct pwm_ops jz4740_pwm_ops = {
.owner = THIS_MODULE,
};
-static int __devinit jz4740_pwm_probe(struct platform_device *pdev)
+static int jz4740_pwm_probe(struct platform_device *pdev)
{
struct jz4740_pwm_chip *jz4740;
int ret;
@@ -191,7 +191,7 @@ static int __devinit jz4740_pwm_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit jz4740_pwm_remove(struct platform_device *pdev)
+static int jz4740_pwm_remove(struct platform_device *pdev)
{
struct jz4740_pwm_chip *jz4740 = platform_get_drvdata(pdev);
int ret;
@@ -211,7 +211,7 @@ static struct platform_driver jz4740_pwm_driver = {
.owner = THIS_MODULE,
},
.probe = jz4740_pwm_probe,
- .remove = __devexit_p(jz4740_pwm_remove),
+ .remove = jz4740_pwm_remove,
};
module_platform_driver(jz4740_pwm_driver);
diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c
index adb87f0c163..015a8223562 100644
--- a/drivers/pwm/pwm-lpc32xx.c
+++ b/drivers/pwm/pwm-lpc32xx.c
@@ -118,7 +118,7 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit lpc32xx_pwm_remove(struct platform_device *pdev)
+static int lpc32xx_pwm_remove(struct platform_device *pdev)
{
struct lpc32xx_pwm_chip *lpc32xx = platform_get_drvdata(pdev);
@@ -138,7 +138,7 @@ static struct platform_driver lpc32xx_pwm_driver = {
.of_match_table = of_match_ptr(lpc32xx_pwm_dt_ids),
},
.probe = lpc32xx_pwm_probe,
- .remove = __devexit_p(lpc32xx_pwm_remove),
+ .remove = lpc32xx_pwm_remove,
};
module_platform_driver(lpc32xx_pwm_driver);
diff --git a/drivers/pwm/pwm-mxs.c b/drivers/pwm/pwm-mxs.c
index e5852646f08..7ec345f0183 100644
--- a/drivers/pwm/pwm-mxs.c
+++ b/drivers/pwm/pwm-mxs.c
@@ -174,7 +174,7 @@ static int mxs_pwm_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit mxs_pwm_remove(struct platform_device *pdev)
+static int mxs_pwm_remove(struct platform_device *pdev)
{
struct mxs_pwm_chip *mxs = platform_get_drvdata(pdev);
@@ -193,7 +193,7 @@ static struct platform_driver mxs_pwm_driver = {
.of_match_table = of_match_ptr(mxs_pwm_dt_ids),
},
.probe = mxs_pwm_probe,
- .remove = __devexit_p(mxs_pwm_remove),
+ .remove = mxs_pwm_remove,
};
module_platform_driver(mxs_pwm_driver);
diff --git a/drivers/pwm/pwm-puv3.c b/drivers/pwm/pwm-puv3.c
index 2a93f37c46a..b882f6032fe 100644
--- a/drivers/pwm/pwm-puv3.c
+++ b/drivers/pwm/pwm-puv3.c
@@ -101,7 +101,7 @@ static const struct pwm_ops puv3_pwm_ops = {
.owner = THIS_MODULE,
};
-static int __devinit pwm_probe(struct platform_device *pdev)
+static int pwm_probe(struct platform_device *pdev)
{
struct puv3_pwm_chip *puv3;
struct resource *r;
@@ -142,7 +142,7 @@ static int __devinit pwm_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit pwm_remove(struct platform_device *pdev)
+static int pwm_remove(struct platform_device *pdev)
{
struct puv3_pwm_chip *puv3 = platform_get_drvdata(pdev);
@@ -154,7 +154,7 @@ static struct platform_driver puv3_pwm_driver = {
.name = "PKUnity-v3-PWM",
},
.probe = pwm_probe,
- .remove = __devexit_p(pwm_remove),
+ .remove = pwm_remove,
};
module_platform_driver(puv3_pwm_driver);
diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c
index 260c3a88564..f32fc4e66e0 100644
--- a/drivers/pwm/pwm-pxa.c
+++ b/drivers/pwm/pwm-pxa.c
@@ -135,7 +135,7 @@ static struct pwm_ops pxa_pwm_ops = {
.owner = THIS_MODULE,
};
-static int __devinit pwm_probe(struct platform_device *pdev)
+static int pwm_probe(struct platform_device *pdev)
{
const struct platform_device_id *id = platform_get_device_id(pdev);
struct pxa_pwm_chip *pwm;
@@ -179,7 +179,7 @@ static int __devinit pwm_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit pwm_remove(struct platform_device *pdev)
+static int pwm_remove(struct platform_device *pdev)
{
struct pxa_pwm_chip *chip;
@@ -196,7 +196,7 @@ static struct platform_driver pwm_driver = {
.owner = THIS_MODULE,
},
.probe = pwm_probe,
- .remove = __devexit_p(pwm_remove),
+ .remove = pwm_remove,
.id_table = pwm_id_table,
};
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
index 023a3bee76e..e9b15d099c0 100644
--- a/drivers/pwm/pwm-samsung.c
+++ b/drivers/pwm/pwm-samsung.c
@@ -273,7 +273,7 @@ static int s3c_pwm_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit s3c_pwm_remove(struct platform_device *pdev)
+static int s3c_pwm_remove(struct platform_device *pdev)
{
struct s3c_chip *s3c = platform_get_drvdata(pdev);
int err;
@@ -327,7 +327,7 @@ static struct platform_driver s3c_pwm_driver = {
.owner = THIS_MODULE,
},
.probe = s3c_pwm_probe,
- .remove = __devexit_p(s3c_pwm_remove),
+ .remove = s3c_pwm_remove,
.suspend = s3c_pwm_suspend,
.resume = s3c_pwm_resume,
};
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index 057465e0553..30c0e2b70ce 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -210,7 +210,7 @@ static int tegra_pwm_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit tegra_pwm_remove(struct platform_device *pdev)
+static int tegra_pwm_remove(struct platform_device *pdev)
{
struct tegra_pwm_chip *pc = platform_get_drvdata(pdev);
int i;
@@ -249,7 +249,7 @@ static struct platform_driver tegra_pwm_driver = {
.of_match_table = of_match_ptr(tegra_pwm_of_match),
},
.probe = tegra_pwm_probe,
- .remove = __devexit_p(tegra_pwm_remove),
+ .remove = tegra_pwm_remove,
};
module_platform_driver(tegra_pwm_driver);
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c
index d6d4cf05565..87c091b245c 100644
--- a/drivers/pwm/pwm-tiecap.c
+++ b/drivers/pwm/pwm-tiecap.c
@@ -184,7 +184,7 @@ static const struct pwm_ops ecap_pwm_ops = {
.owner = THIS_MODULE,
};
-static int __devinit ecap_pwm_probe(struct platform_device *pdev)
+static int ecap_pwm_probe(struct platform_device *pdev)
{
int ret;
struct resource *r;
@@ -235,7 +235,7 @@ static int __devinit ecap_pwm_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit ecap_pwm_remove(struct platform_device *pdev)
+static int ecap_pwm_remove(struct platform_device *pdev)
{
struct ecap_pwm_chip *pc = platform_get_drvdata(pdev);
@@ -249,7 +249,7 @@ static struct platform_driver ecap_pwm_driver = {
.name = "ecap",
},
.probe = ecap_pwm_probe,
- .remove = __devexit_p(ecap_pwm_remove),
+ .remove = ecap_pwm_remove,
};
module_platform_driver(ecap_pwm_driver);
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index d3c1dff0a0d..9ffd389d0c8 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -392,7 +392,7 @@ static const struct pwm_ops ehrpwm_pwm_ops = {
.owner = THIS_MODULE,
};
-static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev)
+static int ehrpwm_pwm_probe(struct platform_device *pdev)
{
int ret;
struct resource *r;
@@ -443,7 +443,7 @@ static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit ehrpwm_pwm_remove(struct platform_device *pdev)
+static int ehrpwm_pwm_remove(struct platform_device *pdev)
{
struct ehrpwm_pwm_chip *pc = platform_get_drvdata(pdev);
@@ -457,7 +457,7 @@ static struct platform_driver ehrpwm_pwm_driver = {
.name = "ehrpwm",
},
.probe = ehrpwm_pwm_probe,
- .remove = __devexit_p(ehrpwm_pwm_remove),
+ .remove = ehrpwm_pwm_remove,
};
module_platform_driver(ehrpwm_pwm_driver);
diff --git a/drivers/pwm/pwm-twl6030.c b/drivers/pwm/pwm-twl6030.c
index 8e6387864ca..378a7e28636 100644
--- a/drivers/pwm/pwm-twl6030.c
+++ b/drivers/pwm/pwm-twl6030.c
@@ -176,7 +176,7 @@ static struct platform_driver twl6030_pwm_driver = {
.name = "twl6030-pwm",
},
.probe = twl6030_pwm_probe,
- .remove = __devexit_p(twl6030_pwm_remove),
+ .remove = twl6030_pwm_remove,
};
module_platform_driver(twl6030_pwm_driver);
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 38ecd8f4d60..6faba406b6e 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -2202,7 +2202,7 @@ static void tsi721_disable_ints(struct tsi721_device *priv)
*
* Configures Tsi721 as RapidIO master port.
*/
-static int __devinit tsi721_setup_mport(struct tsi721_device *priv)
+static int tsi721_setup_mport(struct tsi721_device *priv)
{
struct pci_dev *pdev = priv->pdev;
int err = 0;
@@ -2302,7 +2302,7 @@ err_exit:
return err;
}
-static int __devinit tsi721_probe(struct pci_dev *pdev,
+static int tsi721_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct tsi721_device *priv;
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h
index 7d5b13ba8d4..b4b0d83f9ef 100644
--- a/drivers/rapidio/devices/tsi721.h
+++ b/drivers/rapidio/devices/tsi721.h
@@ -846,7 +846,7 @@ struct tsi721_device {
#ifdef CONFIG_RAPIDIO_DMA_ENGINE
extern void tsi721_bdma_handler(struct tsi721_bdma_chan *bdma_chan);
-extern int __devinit tsi721_register_dma(struct tsi721_device *priv);
+extern int tsi721_register_dma(struct tsi721_device *priv);
#endif
#endif
diff --git a/drivers/rapidio/devices/tsi721_dma.c b/drivers/rapidio/devices/tsi721_dma.c
index 92e06a5c62e..502663f5f7c 100644
--- a/drivers/rapidio/devices/tsi721_dma.c
+++ b/drivers/rapidio/devices/tsi721_dma.c
@@ -765,7 +765,7 @@ static int tsi721_device_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
return 0;
}
-int __devinit tsi721_register_dma(struct tsi721_device *priv)
+int tsi721_register_dma(struct tsi721_device *priv)
{
int i;
int nr_channels = TSI721_DMA_MAXCH;
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 07da58bb495..a965acd3c0e 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -371,7 +371,7 @@ static void rio_switch_init(struct rio_dev *rdev, int do_enum)
* device to the RIO device list. Creates the generic sysfs nodes
* for an RIO device.
*/
-static int __devinit rio_add_device(struct rio_dev *rdev)
+static int rio_add_device(struct rio_dev *rdev)
{
int err;
@@ -463,7 +463,7 @@ inline int rio_enable_rx_tx_port(struct rio_mport *port,
* to a RIO device on success or NULL on failure.
*
*/
-static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
+static struct rio_dev *rio_setup_device(struct rio_net *net,
struct rio_mport *port, u16 destid,
u8 hopcount, int do_enum)
{
@@ -837,7 +837,7 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
* Recursively enumerates a RIO network. Transactions are sent via the
* master port passed in @port.
*/
-static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
+static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
u8 hopcount, struct rio_dev *prev, int prev_port)
{
struct rio_dev *rdev;
@@ -1044,7 +1044,7 @@ static int rio_enum_complete(struct rio_mport *port)
* Recursively discovers a RIO network. Transactions are sent via the
* master port passed in @port.
*/
-static int __devinit
+static int
rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
u8 hopcount, struct rio_dev *prev, int prev_port)
{
@@ -1151,7 +1151,7 @@ static int rio_mport_is_active(struct rio_mport *port)
* network list of associated master ports. Returns a
* RIO network pointer on success or %NULL on failure.
*/
-static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port,
+static struct rio_net *rio_alloc_net(struct rio_mport *port,
int do_enum, u16 start)
{
struct rio_net *net;
@@ -1266,7 +1266,7 @@ static void rio_pw_enable(struct rio_mport *port, int enable)
* link, then start recursive peer enumeration. Returns %0 if
* enumeration succeeds or %-EBUSY if enumeration fails.
*/
-int __devinit rio_enum_mport(struct rio_mport *mport)
+int rio_enum_mport(struct rio_mport *mport)
{
struct rio_net *net = NULL;
int rc = 0;
@@ -1369,7 +1369,7 @@ static void rio_build_route_tables(struct rio_net *net)
* peer discovery. Returns %0 if discovery succeeds or %-EBUSY
* on failure.
*/
-int __devinit rio_disc_mport(struct rio_mport *mport)
+int rio_disc_mport(struct rio_mport *mport)
{
struct rio_net *net = NULL;
unsigned long to_end;
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index c17ae22567e..d553b5d1372 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -401,7 +401,7 @@ EXPORT_SYMBOL_GPL(rio_release_inb_pwrite);
/**
* rio_map_inb_region -- Map inbound memory region.
* @mport: Master port.
- * @lstart: physical address of memory region to be mapped
+ * @local: physical address of memory region to be mapped
* @rbase: RIO base address assigned to this window
* @size: Size of the memory region
* @rflags: Flags for mapping.
@@ -1250,7 +1250,7 @@ static void rio_fixup_device(struct rio_dev *dev)
{
}
-static int __devinit rio_init(void)
+static int rio_init(void)
{
struct rio_dev *dev = NULL;
@@ -1267,7 +1267,7 @@ struct rio_disc_work {
struct rio_mport *mport;
};
-static void __devinit disc_work_handler(struct work_struct *_work)
+static void disc_work_handler(struct work_struct *_work)
{
struct rio_disc_work *work;
@@ -1277,7 +1277,7 @@ static void __devinit disc_work_handler(struct work_struct *_work)
rio_disc_mport(work->mport);
}
-int __devinit rio_init_mports(void)
+int rio_init_mports(void)
{
struct rio_mport *port;
struct rio_disc_work *work;
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 5c4829cba6a..e872c8be080 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1381,22 +1381,14 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id)
}
EXPORT_SYMBOL_GPL(regulator_get_exclusive);
-/**
- * regulator_put - "free" the regulator source
- * @regulator: regulator source
- *
- * Note: drivers must ensure that all regulator_enable calls made on this
- * regulator source are balanced by regulator_disable calls prior to calling
- * this function.
- */
-void regulator_put(struct regulator *regulator)
+/* Locks held by regulator_put() */
+static void _regulator_put(struct regulator *regulator)
{
struct regulator_dev *rdev;
if (regulator == NULL || IS_ERR(regulator))
return;
- mutex_lock(&regulator_list_mutex);
rdev = regulator->rdev;
debugfs_remove_recursive(regulator->debugfs);
@@ -1412,6 +1404,20 @@ void regulator_put(struct regulator *regulator)
rdev->exclusive = 0;
module_put(rdev->owner);
+}
+
+/**
+ * regulator_put - "free" the regulator source
+ * @regulator: regulator source
+ *
+ * Note: drivers must ensure that all regulator_enable calls made on this
+ * regulator source are balanced by regulator_disable calls prior to calling
+ * this function.
+ */
+void regulator_put(struct regulator *regulator)
+{
+ mutex_lock(&regulator_list_mutex);
+ _regulator_put(regulator);
mutex_unlock(&regulator_list_mutex);
}
EXPORT_SYMBOL_GPL(regulator_put);
@@ -1974,7 +1980,7 @@ int regulator_is_supported_voltage(struct regulator *regulator,
if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
ret = regulator_get_voltage(regulator);
if (ret >= 0)
- return (min_uV >= ret && ret <= max_uV);
+ return (min_uV <= ret && ret <= max_uV);
else
return ret;
}
@@ -3365,7 +3371,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
if (ret != 0) {
rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
config->ena_gpio, ret);
- goto clean;
+ goto wash;
}
rdev->ena_gpio = config->ena_gpio;
@@ -3445,10 +3451,11 @@ unset_supplies:
scrub:
if (rdev->supply)
- regulator_put(rdev->supply);
+ _regulator_put(rdev->supply);
if (rdev->ena_gpio)
gpio_free(rdev->ena_gpio);
kfree(rdev->constraints);
+wash:
device_unregister(&rdev->dev);
/* device core frees rdev */
rdev = ERR_PTR(ret);
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index e7a4780e93d..9e198e59067 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -120,15 +120,11 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
return vq;
}
-static void rproc_virtio_del_vqs(struct virtio_device *vdev)
+static void __rproc_virtio_del_vqs(struct virtio_device *vdev)
{
struct virtqueue *vq, *n;
- struct rproc *rproc = vdev_to_rproc(vdev);
struct rproc_vring *rvring;
- /* power down the remote processor before deleting vqs */
- rproc_shutdown(rproc);
-
list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
rvring = vq->priv;
rvring->vq = NULL;
@@ -137,6 +133,16 @@ static void rproc_virtio_del_vqs(struct virtio_device *vdev)
}
}
+static void rproc_virtio_del_vqs(struct virtio_device *vdev)
+{
+ struct rproc *rproc = vdev_to_rproc(vdev);
+
+ /* power down the remote processor before deleting vqs */
+ rproc_shutdown(rproc);
+
+ __rproc_virtio_del_vqs(vdev);
+}
+
static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vqs[],
vq_callback_t *callbacks[],
@@ -163,7 +169,7 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
return 0;
error:
- rproc_virtio_del_vqs(vdev);
+ __rproc_virtio_del_vqs(vdev);
return ret;
}
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c
index 7a82337e4de..073108dcf9e 100644
--- a/drivers/rtc/rtc-tps65910.c
+++ b/drivers/rtc/rtc-tps65910.c
@@ -288,11 +288,11 @@ static int __devinit tps65910_rtc_probe(struct platform_device *pdev)
static int __devexit tps65910_rtc_remove(struct platform_device *pdev)
{
/* leave rtc running, but disable irqs */
- struct rtc_device *rtc = platform_get_drvdata(pdev);
+ struct tps65910_rtc *tps_rtc = platform_get_drvdata(pdev);
- tps65910_rtc_alarm_irq_enable(&rtc->dev, 0);
+ tps65910_rtc_alarm_irq_enable(&pdev->dev, 0);
- rtc_device_unregister(rtc);
+ rtc_device_unregister(tps_rtc->rtc);
return 0;
}
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 9ffb6d5f17a..40084501c31 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -44,7 +44,6 @@
#define RAW3215_NR_CCWS 3
#define RAW3215_TIMEOUT HZ/10 /* time for delayed output */
-#define RAW3215_FIXED 1 /* 3215 console device is not be freed */
#define RAW3215_WORKING 4 /* set if a request is being worked on */
#define RAW3215_THROTTLED 8 /* set if reading is disabled */
#define RAW3215_STOPPED 16 /* set if writing is disabled */
@@ -339,8 +338,10 @@ static void raw3215_wakeup(unsigned long data)
struct tty_struct *tty;
tty = tty_port_tty_get(&raw->port);
- tty_wakeup(tty);
- tty_kref_put(tty);
+ if (tty) {
+ tty_wakeup(tty);
+ tty_kref_put(tty);
+ }
}
/*
@@ -629,8 +630,7 @@ static void raw3215_shutdown(struct raw3215_info *raw)
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
- if (!(raw->port.flags & ASYNC_INITIALIZED) ||
- (raw->flags & RAW3215_FIXED))
+ if (!(raw->port.flags & ASYNC_INITIALIZED))
return;
/* Wait for outstanding requests, then free irq */
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
@@ -677,6 +677,7 @@ static void raw3215_free_info(struct raw3215_info *raw)
{
kfree(raw->inbuf);
kfree(raw->buffer);
+ tty_port_destroy(&raw->port);
kfree(raw);
}
@@ -926,8 +927,6 @@ static int __init con3215_init(void)
dev_set_drvdata(&cdev->dev, raw);
cdev->handler = raw3215_irq;
- raw->flags |= RAW3215_FIXED;
-
/* Request the console irq */
if (raw3215_startup(raw) != 0) {
raw3215_free_info(raw);
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
index 30ec09e3d03..877fbc37c1e 100644
--- a/drivers/s390/char/sclp_tty.c
+++ b/drivers/s390/char/sclp_tty.c
@@ -547,7 +547,6 @@ sclp_tty_init(void)
sclp_tty_tolower = 1;
}
sclp_tty_chars_count = 0;
- tty_port_init(&sclp_port);
rc = sclp_register(&sclp_input_event);
if (rc) {
@@ -555,6 +554,8 @@ sclp_tty_init(void)
return rc;
}
+ tty_port_init(&sclp_port);
+
driver->driver_name = "sclp_line";
driver->name = "sclp_line";
driver->major = TTY_MAJOR;
@@ -571,6 +572,7 @@ sclp_tty_init(void)
rc = tty_register_driver(driver);
if (rc) {
put_tty_driver(driver);
+ tty_port_destroy(&sclp_port);
return rc;
}
sclp_tty_driver = driver;
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 7e60f3d2f3f..effcc8756e0 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -615,6 +615,7 @@ static void __init __sclp_vt220_cleanup(void)
return;
sclp_unregister(&sclp_vt220_register);
__sclp_vt220_free_pages();
+ tty_port_destroy(&sclp_vt220_port);
}
/* Allocate buffer pages and register with sclp core. Controlled by init
@@ -650,6 +651,7 @@ out:
if (rc) {
__sclp_vt220_free_pages();
sclp_vt220_init_count--;
+ tty_port_destroy(&sclp_vt220_port);
}
return rc;
}
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 482ee028f84..43ea0593bdb 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -722,6 +722,7 @@ out_pages:
while (pages--)
free_pages((unsigned long) tp->freemem_pages[pages], 0);
kfree(tp->freemem_pages);
+ tty_port_destroy(&tp->port);
out_tp:
kfree(tp);
out_err:
@@ -744,6 +745,7 @@ tty3270_free_view(struct tty3270 *tp)
for (pages = 0; pages < TTY3270_STRING_PAGES; pages++)
free_pages((unsigned long) tp->freemem_pages[pages], 0);
kfree(tp->freemem_pages);
+ tty_port_destroy(&tp->port);
kfree(tp);
}
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 3e25d315045..4d6ba00d004 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2942,13 +2942,33 @@ static int qeth_query_ipassists_cb(struct qeth_card *card,
QETH_DBF_TEXT(SETUP, 2, "qipasscb");
cmd = (struct qeth_ipa_cmd *) data;
+
+ switch (cmd->hdr.return_code) {
+ case IPA_RC_NOTSUPP:
+ case IPA_RC_L2_UNSUPPORTED_CMD:
+ QETH_DBF_TEXT(SETUP, 2, "ipaunsup");
+ card->options.ipa4.supported_funcs |= IPA_SETADAPTERPARMS;
+ card->options.ipa6.supported_funcs |= IPA_SETADAPTERPARMS;
+ return -0;
+ default:
+ if (cmd->hdr.return_code) {
+ QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Unhandled "
+ "rc=%d\n",
+ dev_name(&card->gdev->dev),
+ cmd->hdr.return_code);
+ return 0;
+ }
+ }
+
if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
- } else {
+ } else if (cmd->hdr.prot_version == QETH_PROT_IPV6) {
card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
- }
+ } else
+ QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Flawed LIC detected"
+ "\n", dev_name(&card->gdev->dev));
QETH_DBF_TEXT(SETUP, 2, "suppenbl");
QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_supported);
QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_enabled);
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index e67e0258aec..fddb62654b6 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -626,10 +626,13 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card)
QETH_DBF_TEXT(SETUP, 2, "doL2init");
QETH_DBF_TEXT_(SETUP, 2, "doL2%s", CARD_BUS_ID(card));
- rc = qeth_query_setadapterparms(card);
- if (rc) {
- QETH_DBF_MESSAGE(2, "could not query adapter parameters on "
- "device %s: x%x\n", CARD_BUS_ID(card), rc);
+ if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) {
+ rc = qeth_query_setadapterparms(card);
+ if (rc) {
+ QETH_DBF_MESSAGE(2, "could not query adapter "
+ "parameters on device %s: x%x\n",
+ CARD_BUS_ID(card), rc);
+ }
}
if (card->info.type == QETH_CARD_TYPE_IQD ||
@@ -676,7 +679,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
return -ERESTARTSYS;
}
rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]);
- if (!rc)
+ if (!rc || (rc == IPA_RC_L2_MAC_NOT_FOUND))
rc = qeth_l2_send_setmac(card, addr->sa_data);
return rc ? -EINVAL : 0;
}
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index c1bafc3f3fb..9594ab62702 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -1972,7 +1972,7 @@ sci_io_request_frame_handler(struct isci_request *ireq,
frame_index,
(void **)&frame_buffer);
- sci_controller_copy_sata_response(&ireq->stp.req,
+ sci_controller_copy_sata_response(&ireq->stp.rsp,
frame_header,
frame_buffer);
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 16b7a72a70c..3b2365c8eab 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1276,7 +1276,7 @@ struct megasas_evt_detail {
} __attribute__ ((packed));
struct megasas_aen_event {
- struct work_struct hotplug_work;
+ struct delayed_work hotplug_work;
struct megasas_instance *instance;
};
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index d2c5366aff7..e4f2baacf1e 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -2060,9 +2060,9 @@ megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
} else {
ev->instance = instance;
instance->ev = ev;
- INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
- schedule_delayed_work(
- (struct delayed_work *)&ev->hotplug_work, 0);
+ INIT_DELAYED_WORK(&ev->hotplug_work,
+ megasas_aen_polling);
+ schedule_delayed_work(&ev->hotplug_work, 0);
}
}
}
@@ -4352,8 +4352,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
/* cancel the delayed work if this work still in queue */
if (instance->ev != NULL) {
struct megasas_aen_event *ev = instance->ev;
- cancel_delayed_work_sync(
- (struct delayed_work *)&ev->hotplug_work);
+ cancel_delayed_work_sync(&ev->hotplug_work);
instance->ev = NULL;
}
@@ -4545,8 +4544,7 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
/* cancel the delayed work if this work still in queue*/
if (instance->ev != NULL) {
struct megasas_aen_event *ev = instance->ev;
- cancel_delayed_work_sync(
- (struct delayed_work *)&ev->hotplug_work);
+ cancel_delayed_work_sync(&ev->hotplug_work);
instance->ev = NULL;
}
@@ -5190,7 +5188,7 @@ static void
megasas_aen_polling(struct work_struct *work)
{
struct megasas_aen_event *ev =
- container_of(work, struct megasas_aen_event, hotplug_work);
+ container_of(work, struct megasas_aen_event, hotplug_work.work);
struct megasas_instance *instance = ev->instance;
union megasas_evt_class_locale class_locale;
struct Scsi_Host *host;
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 2936b447cae..2c0d0ec8150 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -55,6 +55,7 @@
#include <linux/cpu.h>
#include <linux/mutex.h>
#include <linux/async.h>
+#include <asm/unaligned.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -1062,6 +1063,50 @@ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf,
EXPORT_SYMBOL_GPL(scsi_get_vpd_page);
/**
+ * scsi_report_opcode - Find out if a given command opcode is supported
+ * @sdev: scsi device to query
+ * @buffer: scratch buffer (must be at least 20 bytes long)
+ * @len: length of buffer
+ * @opcode: opcode for command to look up
+ *
+ * Uses the REPORT SUPPORTED OPERATION CODES to look up the given
+ * opcode. Returns 0 if RSOC fails or if the command opcode is
+ * unsupported. Returns 1 if the device claims to support the command.
+ */
+int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer,
+ unsigned int len, unsigned char opcode)
+{
+ unsigned char cmd[16];
+ struct scsi_sense_hdr sshdr;
+ int result;
+
+ if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3)
+ return 0;
+
+ memset(cmd, 0, 16);
+ cmd[0] = MAINTENANCE_IN;
+ cmd[1] = MI_REPORT_SUPPORTED_OPERATION_CODES;
+ cmd[2] = 1; /* One command format */
+ cmd[3] = opcode;
+ put_unaligned_be32(len, &cmd[6]);
+ memset(buffer, 0, len);
+
+ result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
+ &sshdr, 30 * HZ, 3, NULL);
+
+ if (result && scsi_sense_valid(&sshdr) &&
+ sshdr.sense_key == ILLEGAL_REQUEST &&
+ (sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00)
+ return 0;
+
+ if ((buffer[1] & 3) == 3) /* Command supported */
+ return 1;
+
+ return 0;
+}
+EXPORT_SYMBOL(scsi_report_opcode);
+
+/**
* scsi_device_get - get an additional reference to a scsi_device
* @sdev: device to get a reference to
*
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index da36a3a81a9..9032e910bca 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -900,11 +900,23 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
action = ACTION_FAIL;
error = -EILSEQ;
/* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */
- } else if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) &&
- (cmd->cmnd[0] == UNMAP ||
- cmd->cmnd[0] == WRITE_SAME_16 ||
- cmd->cmnd[0] == WRITE_SAME)) {
- description = "Discard failure";
+ } else if (sshdr.asc == 0x20 || sshdr.asc == 0x24) {
+ switch (cmd->cmnd[0]) {
+ case UNMAP:
+ description = "Discard failure";
+ break;
+ case WRITE_SAME:
+ case WRITE_SAME_16:
+ if (cmd->cmnd[1] & 0x8)
+ description = "Discard failure";
+ else
+ description =
+ "Write same failure";
+ break;
+ default:
+ description = "Invalid command failure";
+ break;
+ }
action = ACTION_FAIL;
error = -EREMOTEIO;
} else
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 12f6fdfc114..352bc77b7c8 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -99,6 +99,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
#endif
static void sd_config_discard(struct scsi_disk *, unsigned int);
+static void sd_config_write_same(struct scsi_disk *);
static int sd_revalidate_disk(struct gendisk *);
static void sd_unlock_native_capacity(struct gendisk *disk);
static int sd_probe(struct device *);
@@ -395,6 +396,45 @@ sd_store_max_medium_access_timeouts(struct device *dev,
return err ? err : count;
}
+static ssize_t
+sd_show_write_same_blocks(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
+
+ return snprintf(buf, 20, "%u\n", sdkp->max_ws_blocks);
+}
+
+static ssize_t
+sd_store_write_same_blocks(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
+ struct scsi_device *sdp = sdkp->device;
+ unsigned long max;
+ int err;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ if (sdp->type != TYPE_DISK)
+ return -EINVAL;
+
+ err = kstrtoul(buf, 10, &max);
+
+ if (err)
+ return err;
+
+ if (max == 0)
+ sdp->no_write_same = 1;
+ else if (max <= SD_MAX_WS16_BLOCKS)
+ sdkp->max_ws_blocks = max;
+
+ sd_config_write_same(sdkp);
+
+ return count;
+}
+
static struct device_attribute sd_disk_attrs[] = {
__ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type,
sd_store_cache_type),
@@ -410,6 +450,8 @@ static struct device_attribute sd_disk_attrs[] = {
__ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL),
__ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode,
sd_store_provisioning_mode),
+ __ATTR(max_write_same_blocks, S_IRUGO|S_IWUSR,
+ sd_show_write_same_blocks, sd_store_write_same_blocks),
__ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR,
sd_show_max_medium_access_timeouts,
sd_store_max_medium_access_timeouts),
@@ -561,19 +603,23 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
return;
case SD_LBP_UNMAP:
- max_blocks = min_not_zero(sdkp->max_unmap_blocks, 0xffffffff);
+ max_blocks = min_not_zero(sdkp->max_unmap_blocks,
+ (u32)SD_MAX_WS16_BLOCKS);
break;
case SD_LBP_WS16:
- max_blocks = min_not_zero(sdkp->max_ws_blocks, 0xffffffff);
+ max_blocks = min_not_zero(sdkp->max_ws_blocks,
+ (u32)SD_MAX_WS16_BLOCKS);
break;
case SD_LBP_WS10:
- max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff);
+ max_blocks = min_not_zero(sdkp->max_ws_blocks,
+ (u32)SD_MAX_WS10_BLOCKS);
break;
case SD_LBP_ZERO:
- max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff);
+ max_blocks = min_not_zero(sdkp->max_ws_blocks,
+ (u32)SD_MAX_WS10_BLOCKS);
q->limits.discard_zeroes_data = 1;
break;
}
@@ -583,29 +629,26 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
}
/**
- * scsi_setup_discard_cmnd - unmap blocks on thinly provisioned device
+ * sd_setup_discard_cmnd - unmap blocks on thinly provisioned device
* @sdp: scsi device to operate one
* @rq: Request to prepare
*
* Will issue either UNMAP or WRITE SAME(16) depending on preference
* indicated by target device.
**/
-static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
+static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
{
struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
- struct bio *bio = rq->bio;
- sector_t sector = bio->bi_sector;
- unsigned int nr_sectors = bio_sectors(bio);
+ sector_t sector = blk_rq_pos(rq);
+ unsigned int nr_sectors = blk_rq_sectors(rq);
+ unsigned int nr_bytes = blk_rq_bytes(rq);
unsigned int len;
int ret;
char *buf;
struct page *page;
- if (sdkp->device->sector_size == 4096) {
- sector >>= 3;
- nr_sectors >>= 3;
- }
-
+ sector >>= ilog2(sdp->sector_size) - 9;
+ nr_sectors >>= ilog2(sdp->sector_size) - 9;
rq->timeout = SD_TIMEOUT;
memset(rq->cmd, 0, rq->cmd_len);
@@ -660,6 +703,7 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
blk_add_request_payload(rq, page, len);
ret = scsi_setup_blk_pc_cmnd(sdp, rq);
rq->buffer = page_address(page);
+ rq->__data_len = nr_bytes;
out:
if (ret != BLKPREP_OK) {
@@ -669,6 +713,83 @@ out:
return ret;
}
+static void sd_config_write_same(struct scsi_disk *sdkp)
+{
+ struct request_queue *q = sdkp->disk->queue;
+ unsigned int logical_block_size = sdkp->device->sector_size;
+ unsigned int blocks = 0;
+
+ if (sdkp->device->no_write_same) {
+ sdkp->max_ws_blocks = 0;
+ goto out;
+ }
+
+ /* Some devices can not handle block counts above 0xffff despite
+ * supporting WRITE SAME(16). Consequently we default to 64k
+ * blocks per I/O unless the device explicitly advertises a
+ * bigger limit.
+ */
+ if (sdkp->max_ws_blocks == 0)
+ sdkp->max_ws_blocks = SD_MAX_WS10_BLOCKS;
+
+ if (sdkp->ws16 || sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS)
+ blocks = min_not_zero(sdkp->max_ws_blocks,
+ (u32)SD_MAX_WS16_BLOCKS);
+ else
+ blocks = min_not_zero(sdkp->max_ws_blocks,
+ (u32)SD_MAX_WS10_BLOCKS);
+
+out:
+ blk_queue_max_write_same_sectors(q, blocks * (logical_block_size >> 9));
+}
+
+/**
+ * sd_setup_write_same_cmnd - write the same data to multiple blocks
+ * @sdp: scsi device to operate one
+ * @rq: Request to prepare
+ *
+ * Will issue either WRITE SAME(10) or WRITE SAME(16) depending on
+ * preference indicated by target device.
+ **/
+static int sd_setup_write_same_cmnd(struct scsi_device *sdp, struct request *rq)
+{
+ struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
+ struct bio *bio = rq->bio;
+ sector_t sector = blk_rq_pos(rq);
+ unsigned int nr_sectors = blk_rq_sectors(rq);
+ unsigned int nr_bytes = blk_rq_bytes(rq);
+ int ret;
+
+ if (sdkp->device->no_write_same)
+ return BLKPREP_KILL;
+
+ BUG_ON(bio_offset(bio) || bio_iovec(bio)->bv_len != sdp->sector_size);
+
+ sector >>= ilog2(sdp->sector_size) - 9;
+ nr_sectors >>= ilog2(sdp->sector_size) - 9;
+
+ rq->__data_len = sdp->sector_size;
+ rq->timeout = SD_WRITE_SAME_TIMEOUT;
+ memset(rq->cmd, 0, rq->cmd_len);
+
+ if (sdkp->ws16 || sector > 0xffffffff || nr_sectors > 0xffff) {
+ rq->cmd_len = 16;
+ rq->cmd[0] = WRITE_SAME_16;
+ put_unaligned_be64(sector, &rq->cmd[2]);
+ put_unaligned_be32(nr_sectors, &rq->cmd[10]);
+ } else {
+ rq->cmd_len = 10;
+ rq->cmd[0] = WRITE_SAME;
+ put_unaligned_be32(sector, &rq->cmd[2]);
+ put_unaligned_be16(nr_sectors, &rq->cmd[7]);
+ }
+
+ ret = scsi_setup_blk_pc_cmnd(sdp, rq);
+ rq->__data_len = nr_bytes;
+
+ return ret;
+}
+
static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq)
{
rq->timeout = SD_FLUSH_TIMEOUT;
@@ -712,7 +833,10 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
* block PC requests to make life easier.
*/
if (rq->cmd_flags & REQ_DISCARD) {
- ret = scsi_setup_discard_cmnd(sdp, rq);
+ ret = sd_setup_discard_cmnd(sdp, rq);
+ goto out;
+ } else if (rq->cmd_flags & REQ_WRITE_SAME) {
+ ret = sd_setup_write_same_cmnd(sdp, rq);
goto out;
} else if (rq->cmd_flags & REQ_FLUSH) {
ret = scsi_setup_flush_cmnd(sdp, rq);
@@ -1482,12 +1606,21 @@ static int sd_done(struct scsi_cmnd *SCpnt)
unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt);
struct scsi_sense_hdr sshdr;
struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk);
+ struct request *req = SCpnt->request;
int sense_valid = 0;
int sense_deferred = 0;
unsigned char op = SCpnt->cmnd[0];
+ unsigned char unmap = SCpnt->cmnd[1] & 8;
- if ((SCpnt->request->cmd_flags & REQ_DISCARD) && !result)
- scsi_set_resid(SCpnt, 0);
+ if (req->cmd_flags & REQ_DISCARD || req->cmd_flags & REQ_WRITE_SAME) {
+ if (!result) {
+ good_bytes = blk_rq_bytes(req);
+ scsi_set_resid(SCpnt, 0);
+ } else {
+ good_bytes = 0;
+ scsi_set_resid(SCpnt, blk_rq_bytes(req));
+ }
+ }
if (result) {
sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr);
@@ -1536,9 +1669,25 @@ static int sd_done(struct scsi_cmnd *SCpnt)
if (sshdr.asc == 0x10) /* DIX: Host detected corruption */
good_bytes = sd_completed_bytes(SCpnt);
/* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */
- if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) &&
- (op == UNMAP || op == WRITE_SAME_16 || op == WRITE_SAME))
- sd_config_discard(sdkp, SD_LBP_DISABLE);
+ if (sshdr.asc == 0x20 || sshdr.asc == 0x24) {
+ switch (op) {
+ case UNMAP:
+ sd_config_discard(sdkp, SD_LBP_DISABLE);
+ break;
+ case WRITE_SAME_16:
+ case WRITE_SAME:
+ if (unmap)
+ sd_config_discard(sdkp, SD_LBP_DISABLE);
+ else {
+ sdkp->device->no_write_same = 1;
+ sd_config_write_same(sdkp);
+
+ good_bytes = 0;
+ req->__data_len = blk_rq_bytes(req);
+ req->cmd_flags |= REQ_QUIET;
+ }
+ }
+ }
break;
default:
break;
@@ -2374,9 +2523,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
if (buffer[3] == 0x3c) {
unsigned int lba_count, desc_count;
- sdkp->max_ws_blocks =
- (u32) min_not_zero(get_unaligned_be64(&buffer[36]),
- (u64)0xffffffff);
+ sdkp->max_ws_blocks = (u32)get_unaligned_be64(&buffer[36]);
if (!sdkp->lbpme)
goto out;
@@ -2469,6 +2616,13 @@ static void sd_read_block_provisioning(struct scsi_disk *sdkp)
kfree(buffer);
}
+static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
+{
+ if (scsi_report_opcode(sdkp->device, buffer, SD_BUF_SIZE,
+ WRITE_SAME_16))
+ sdkp->ws16 = 1;
+}
+
static int sd_try_extended_inquiry(struct scsi_device *sdp)
{
/*
@@ -2528,6 +2682,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
sd_read_write_protect_flag(sdkp, buffer);
sd_read_cache_type(sdkp, buffer);
sd_read_app_tag_own(sdkp, buffer);
+ sd_read_write_same(sdkp, buffer);
}
sdkp->first_scan = 0;
@@ -2545,6 +2700,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
blk_queue_flush(sdkp->disk->queue, flush);
set_capacity(disk, sdkp->capacity);
+ sd_config_write_same(sdkp);
kfree(buffer);
out:
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 47c52a6d733..74a1e4ca540 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -14,6 +14,7 @@
#define SD_TIMEOUT (30 * HZ)
#define SD_MOD_TIMEOUT (75 * HZ)
#define SD_FLUSH_TIMEOUT (60 * HZ)
+#define SD_WRITE_SAME_TIMEOUT (120 * HZ)
/*
* Number of allowed retries
@@ -39,6 +40,11 @@ enum {
};
enum {
+ SD_MAX_WS10_BLOCKS = 0xffff,
+ SD_MAX_WS16_BLOCKS = 0x7fffff,
+};
+
+enum {
SD_LBP_FULL = 0, /* Full logical block provisioning */
SD_LBP_UNMAP, /* Use UNMAP command */
SD_LBP_WS16, /* Use WRITE SAME(16) with UNMAP bit */
@@ -77,6 +83,7 @@ struct scsi_disk {
unsigned lbpws : 1;
unsigned lbpws10 : 1;
unsigned lbpvpd : 1;
+ unsigned ws16 : 1;
};
#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 84c2861d6f4..718cc1f4923 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -35,6 +35,8 @@
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/kthread.h>
+#include <linux/ioport.h>
+#include <linux/acpi.h>
static void spidev_release(struct device *dev)
{
@@ -93,6 +95,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)
if (of_driver_match_device(dev, drv))
return 1;
+ /* Then try ACPI */
+ if (acpi_driver_match_device(dev, drv))
+ return 1;
+
if (sdrv->id_table)
return !!spi_match_id(sdrv->id_table, spi);
@@ -819,7 +825,7 @@ static void of_register_spi_devices(struct spi_master *master)
if (!master->dev.of_node)
return;
- for_each_child_of_node(master->dev.of_node, nc) {
+ for_each_available_child_of_node(master->dev.of_node, nc) {
/* Alloc an spi_device */
spi = spi_alloc_device(master);
if (!spi) {
@@ -888,6 +894,100 @@ static void of_register_spi_devices(struct spi_master *master)
static void of_register_spi_devices(struct spi_master *master) { }
#endif
+#ifdef CONFIG_ACPI
+static int acpi_spi_add_resource(struct acpi_resource *ares, void *data)
+{
+ struct spi_device *spi = data;
+
+ if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
+ struct acpi_resource_spi_serialbus *sb;
+
+ sb = &ares->data.spi_serial_bus;
+ if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) {
+ spi->chip_select = sb->device_selection;
+ spi->max_speed_hz = sb->connection_speed;
+
+ if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
+ spi->mode |= SPI_CPHA;
+ if (sb->clock_polarity == ACPI_SPI_START_HIGH)
+ spi->mode |= SPI_CPOL;
+ if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH)
+ spi->mode |= SPI_CS_HIGH;
+ }
+ } else if (spi->irq < 0) {
+ struct resource r;
+
+ if (acpi_dev_resource_interrupt(ares, 0, &r))
+ spi->irq = r.start;
+ }
+
+ /* Always tell the ACPI core to skip this resource */
+ return 1;
+}
+
+static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level,
+ void *data, void **return_value)
+{
+ struct spi_master *master = data;
+ struct list_head resource_list;
+ struct acpi_device *adev;
+ struct spi_device *spi;
+ int ret;
+
+ if (acpi_bus_get_device(handle, &adev))
+ return AE_OK;
+ if (acpi_bus_get_status(adev) || !adev->status.present)
+ return AE_OK;
+
+ spi = spi_alloc_device(master);
+ if (!spi) {
+ dev_err(&master->dev, "failed to allocate SPI device for %s\n",
+ dev_name(&adev->dev));
+ return AE_NO_MEMORY;
+ }
+
+ ACPI_HANDLE_SET(&spi->dev, handle);
+ spi->irq = -1;
+
+ INIT_LIST_HEAD(&resource_list);
+ ret = acpi_dev_get_resources(adev, &resource_list,
+ acpi_spi_add_resource, spi);
+ acpi_dev_free_resource_list(&resource_list);
+
+ if (ret < 0 || !spi->max_speed_hz) {
+ spi_dev_put(spi);
+ return AE_OK;
+ }
+
+ strlcpy(spi->modalias, dev_name(&adev->dev), sizeof(spi->modalias));
+ if (spi_add_device(spi)) {
+ dev_err(&master->dev, "failed to add SPI device %s from ACPI\n",
+ dev_name(&adev->dev));
+ spi_dev_put(spi);
+ }
+
+ return AE_OK;
+}
+
+static void acpi_register_spi_devices(struct spi_master *master)
+{
+ acpi_status status;
+ acpi_handle handle;
+
+ handle = ACPI_HANDLE(&master->dev);
+ if (!handle)
+ return;
+
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+ acpi_spi_add_device, NULL,
+ master, NULL);
+ if (ACPI_FAILURE(status))
+ dev_warn(&master->dev, "failed to enumerate SPI slaves\n");
+}
+#else
+static inline void acpi_register_spi_devices(struct spi_master *master) {}
+#endif /* CONFIG_ACPI */
+
static void spi_master_release(struct device *dev)
{
struct spi_master *master;
@@ -1023,8 +1123,9 @@ int spi_register_master(struct spi_master *master)
spi_match_master_to_boardinfo(master, &bi->board_info);
mutex_unlock(&board_lock);
- /* Register devices from the device tree */
+ /* Register devices from the device tree and ACPI */
of_register_spi_devices(master);
+ acpi_register_spi_devices(master);
done:
return status;
}
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index d805eef1191..329bdb42109 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -52,8 +52,6 @@ source "drivers/staging/rtl8192e/Kconfig"
source "drivers/staging/rtl8712/Kconfig"
-source "drivers/staging/rts_pstor/Kconfig"
-
source "drivers/staging/rts5139/Kconfig"
source "drivers/staging/frontier/Kconfig"
@@ -120,14 +118,10 @@ source "drivers/staging/omapdrm/Kconfig"
source "drivers/staging/android/Kconfig"
-source "drivers/staging/telephony/Kconfig"
-
source "drivers/staging/ozwpan/Kconfig"
source "drivers/staging/ccg/Kconfig"
-source "drivers/staging/ipack/Kconfig"
-
source "drivers/staging/gdm72xx/Kconfig"
source "drivers/staging/csr/Kconfig"
@@ -144,4 +138,8 @@ source "drivers/staging/imx-drm/Kconfig"
source "drivers/staging/dgrp/Kconfig"
+source "drivers/staging/sb105x/Kconfig"
+
+source "drivers/staging/fwserial/Kconfig"
+
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 76e2ebd596f..c7ec486680f 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -19,7 +19,6 @@ obj-$(CONFIG_R8187SE) += rtl8187se/
obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_R8712U) += rtl8712/
-obj-$(CONFIG_RTS_PSTOR) += rts_pstor/
obj-$(CONFIG_RTS5139) += rts5139/
obj-$(CONFIG_TRANZPORT) += frontier/
obj-$(CONFIG_IDE_PHISON) += phison/
@@ -29,7 +28,6 @@ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/
obj-$(CONFIG_VT6655) += vt6655/
obj-$(CONFIG_VT6656) += vt6656/
obj-$(CONFIG_VME_BUS) += vme/
-obj-$(CONFIG_IPACK_BUS) += ipack/
obj-$(CONFIG_DX_SEP) += sep/
obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_ZRAM) += zram/
@@ -53,7 +51,6 @@ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/
obj-$(CONFIG_MFD_NVEC) += nvec/
obj-$(CONFIG_DRM_OMAP) += omapdrm/
obj-$(CONFIG_ANDROID) += android/
-obj-$(CONFIG_PHONE) += telephony/
obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/
obj-$(CONFIG_USB_G_CCG) += ccg/
obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/
@@ -64,3 +61,5 @@ obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/
obj-$(CONFIG_CED1401) += ced1401/
obj-$(CONFIG_DRM_IMX) += imx-drm/
obj-$(CONFIG_DGRP) += dgrp/
+obj-$(CONFIG_SB105X) += sb105x/
+obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
index e16fcd51716..b35a631734d 100644
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -1,3 +1,5 @@
+ccflags-y += -I$(src) # needed for trace events
+
obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o
obj-$(CONFIG_ASHMEM) += ashmem.o
obj-$(CONFIG_ANDROID_LOGGER) += logger.o
diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h
index f2ffd963f1c..d0cafd63719 100644
--- a/drivers/staging/android/android_alarm.h
+++ b/drivers/staging/android/android_alarm.h
@@ -51,12 +51,10 @@ enum android_alarm_return_flags {
#define ANDROID_ALARM_WAIT _IO('a', 1)
#define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size)
-#define ALARM_IOR(c, type, size) _IOR('a', (c) | ((type) << 4), size)
-
/* Set alarm */
#define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec)
#define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec)
-#define ANDROID_ALARM_GET_TIME(type) ALARM_IOR(4, type, struct timespec)
+#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec)
#define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec)
#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0)))
#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4)
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 5d4610babd8..4a36e9ab8cf 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -15,6 +15,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <asm/cacheflush.h>
#include <linux/fdtable.h>
#include <linux/file.h>
@@ -35,8 +37,9 @@
#include <linux/slab.h>
#include "binder.h"
+#include "binder_trace.h"
-static DEFINE_MUTEX(binder_lock);
+static DEFINE_MUTEX(binder_main_lock);
static DEFINE_MUTEX(binder_deferred_lock);
static DEFINE_MUTEX(binder_mmap_lock);
@@ -411,6 +414,19 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd)
return retval;
}
+static inline void binder_lock(const char *tag)
+{
+ trace_binder_lock(tag);
+ mutex_lock(&binder_main_lock);
+ trace_binder_locked(tag);
+}
+
+static inline void binder_unlock(const char *tag)
+{
+ trace_binder_unlock(tag);
+ mutex_unlock(&binder_main_lock);
+}
+
static void binder_set_nice(long nice)
{
long min_nice;
@@ -420,12 +436,12 @@ static void binder_set_nice(long nice)
}
min_nice = 20 - current->signal->rlim[RLIMIT_NICE].rlim_cur;
binder_debug(BINDER_DEBUG_PRIORITY_CAP,
- "binder: %d: nice value %ld not allowed use "
- "%ld instead\n", current->pid, nice, min_nice);
+ "%d: nice value %ld not allowed use %ld instead\n",
+ current->pid, nice, min_nice);
set_user_nice(current, min_nice);
if (min_nice < 20)
return;
- binder_user_error("binder: %d RLIMIT_NICE not set\n", current->pid);
+ binder_user_error("%d RLIMIT_NICE not set\n", current->pid);
}
static size_t binder_buffer_size(struct binder_proc *proc,
@@ -452,8 +468,8 @@ static void binder_insert_free_buffer(struct binder_proc *proc,
new_buffer_size = binder_buffer_size(proc, new_buffer);
binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
- "binder: %d: add free buffer, size %zd, "
- "at %p\n", proc->pid, new_buffer_size, new_buffer);
+ "%d: add free buffer, size %zd, at %p\n",
+ proc->pid, new_buffer_size, new_buffer);
while (*p) {
parent = *p;
@@ -531,12 +547,14 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
struct mm_struct *mm;
binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
- "binder: %d: %s pages %p-%p\n", proc->pid,
+ "%d: %s pages %p-%p\n", proc->pid,
allocate ? "allocate" : "free", start, end);
if (end <= start)
return 0;
+ trace_binder_update_page_range(proc, allocate, start, end);
+
if (vma)
mm = NULL;
else
@@ -546,7 +564,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
down_write(&mm->mmap_sem);
vma = proc->vma;
if (vma && mm != proc->vma_vm_mm) {
- pr_err("binder: %d: vma mm and task mm mismatch\n",
+ pr_err("%d: vma mm and task mm mismatch\n",
proc->pid);
vma = NULL;
}
@@ -556,8 +574,8 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
goto free_range;
if (vma == NULL) {
- pr_err("binder: %d: binder_alloc_buf failed to "
- "map pages in userspace, no vma\n", proc->pid);
+ pr_err("%d: binder_alloc_buf failed to map pages in userspace, no vma\n",
+ proc->pid);
goto err_no_vma;
}
@@ -569,8 +587,8 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
BUG_ON(*page);
*page = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
if (*page == NULL) {
- pr_err("binder: %d: binder_alloc_buf failed "
- "for page at %p\n", proc->pid, page_addr);
+ pr_err("%d: binder_alloc_buf failed for page at %p\n",
+ proc->pid, page_addr);
goto err_alloc_page_failed;
}
tmp_area.addr = page_addr;
@@ -578,8 +596,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
page_array_ptr = page;
ret = map_vm_area(&tmp_area, PAGE_KERNEL, &page_array_ptr);
if (ret) {
- pr_err("binder: %d: binder_alloc_buf failed "
- "to map page at %p in kernel\n",
+ pr_err("%d: binder_alloc_buf failed to map page at %p in kernel\n",
proc->pid, page_addr);
goto err_map_kernel_failed;
}
@@ -587,8 +604,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
(uintptr_t)page_addr + proc->user_buffer_offset;
ret = vm_insert_page(vma, user_page_addr, page[0]);
if (ret) {
- pr_err("binder: %d: binder_alloc_buf failed "
- "to map page at %lx in userspace\n",
+ pr_err("%d: binder_alloc_buf failed to map page at %lx in userspace\n",
proc->pid, user_page_addr);
goto err_vm_insert_page_failed;
}
@@ -636,7 +652,7 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
size_t size;
if (proc->vma == NULL) {
- pr_err("binder: %d: binder_alloc_buf, no vma\n",
+ pr_err("%d: binder_alloc_buf, no vma\n",
proc->pid);
return NULL;
}
@@ -645,16 +661,16 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
ALIGN(offsets_size, sizeof(void *));
if (size < data_size || size < offsets_size) {
- binder_user_error("binder: %d: got transaction with invalid "
- "size %zd-%zd\n", proc->pid, data_size, offsets_size);
+ binder_user_error("%d: got transaction with invalid size %zd-%zd\n",
+ proc->pid, data_size, offsets_size);
return NULL;
}
if (is_async &&
proc->free_async_space < size + sizeof(struct binder_buffer)) {
binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
- "binder: %d: binder_alloc_buf size %zd"
- "failed, no async space left\n", proc->pid, size);
+ "%d: binder_alloc_buf size %zd failed, no async space left\n",
+ proc->pid, size);
return NULL;
}
@@ -674,8 +690,8 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
}
}
if (best_fit == NULL) {
- pr_err("binder: %d: binder_alloc_buf size %zd failed, "
- "no address space\n", proc->pid, size);
+ pr_err("%d: binder_alloc_buf size %zd failed, no address space\n",
+ proc->pid, size);
return NULL;
}
if (n == NULL) {
@@ -684,8 +700,8 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
}
binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
- "binder: %d: binder_alloc_buf size %zd got buff"
- "er %p size %zd\n", proc->pid, size, buffer, buffer_size);
+ "%d: binder_alloc_buf size %zd got buffer %p size %zd\n",
+ proc->pid, size, buffer, buffer_size);
has_page_addr =
(void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK);
@@ -713,17 +729,16 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
binder_insert_free_buffer(proc, new_buffer);
}
binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
- "binder: %d: binder_alloc_buf size %zd got "
- "%p\n", proc->pid, size, buffer);
+ "%d: binder_alloc_buf size %zd got %p\n",
+ proc->pid, size, buffer);
buffer->data_size = data_size;
buffer->offsets_size = offsets_size;
buffer->async_transaction = is_async;
if (is_async) {
proc->free_async_space -= size + sizeof(struct binder_buffer);
binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC,
- "binder: %d: binder_alloc_buf size %zd "
- "async free %zd\n", proc->pid, size,
- proc->free_async_space);
+ "%d: binder_alloc_buf size %zd async free %zd\n",
+ proc->pid, size, proc->free_async_space);
}
return buffer;
@@ -754,8 +769,8 @@ static void binder_delete_free_buffer(struct binder_proc *proc,
if (buffer_end_page(prev) == buffer_end_page(buffer))
free_page_end = 0;
binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
- "binder: %d: merge free, buffer %p "
- "share page with %p\n", proc->pid, buffer, prev);
+ "%d: merge free, buffer %p share page with %p\n",
+ proc->pid, buffer, prev);
}
if (!list_is_last(&buffer->entry, &proc->buffers)) {
@@ -767,16 +782,14 @@ static void binder_delete_free_buffer(struct binder_proc *proc,
buffer_start_page(buffer))
free_page_start = 0;
binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
- "binder: %d: merge free, buffer"
- " %p share page with %p\n", proc->pid,
- buffer, prev);
+ "%d: merge free, buffer %p share page with %p\n",
+ proc->pid, buffer, prev);
}
}
list_del(&buffer->entry);
if (free_page_start || free_page_end) {
binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
- "binder: %d: merge free, buffer %p do "
- "not share page%s%s with with %p or %p\n",
+ "%d: merge free, buffer %p do not share page%s%s with with %p or %p\n",
proc->pid, buffer, free_page_start ? "" : " end",
free_page_end ? "" : " start", prev, next);
binder_update_page_range(proc, 0, free_page_start ?
@@ -797,8 +810,8 @@ static void binder_free_buf(struct binder_proc *proc,
ALIGN(buffer->offsets_size, sizeof(void *));
binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
- "binder: %d: binder_free_buf %p size %zd buffer"
- "_size %zd\n", proc->pid, buffer, size, buffer_size);
+ "%d: binder_free_buf %p size %zd buffer_size %zd\n",
+ proc->pid, buffer, size, buffer_size);
BUG_ON(buffer->free);
BUG_ON(size > buffer_size);
@@ -810,9 +823,8 @@ static void binder_free_buf(struct binder_proc *proc,
proc->free_async_space += size + sizeof(struct binder_buffer);
binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC,
- "binder: %d: binder_free_buf size %zd "
- "async free %zd\n", proc->pid, size,
- proc->free_async_space);
+ "%d: binder_free_buf size %zd async free %zd\n",
+ proc->pid, size, proc->free_async_space);
}
binder_update_page_range(proc, 0,
@@ -894,7 +906,7 @@ static struct binder_node *binder_new_node(struct binder_proc *proc,
INIT_LIST_HEAD(&node->work.entry);
INIT_LIST_HEAD(&node->async_todo);
binder_debug(BINDER_DEBUG_INTERNAL_REFS,
- "binder: %d:%d node %d u%p c%p created\n",
+ "%d:%d node %d u%p c%p created\n",
proc->pid, current->pid, node->debug_id,
node->ptr, node->cookie);
return node;
@@ -909,8 +921,8 @@ static int binder_inc_node(struct binder_node *node, int strong, int internal,
node->internal_strong_refs == 0 &&
!(node == binder_context_mgr_node &&
node->has_strong_ref)) {
- pr_err("binder: invalid inc strong "
- "node for %d\n", node->debug_id);
+ pr_err("invalid inc strong node for %d\n",
+ node->debug_id);
return -EINVAL;
}
node->internal_strong_refs++;
@@ -925,8 +937,8 @@ static int binder_inc_node(struct binder_node *node, int strong, int internal,
node->local_weak_refs++;
if (!node->has_weak_ref && list_empty(&node->work.entry)) {
if (target_list == NULL) {
- pr_err("binder: invalid inc weak node "
- "for %d\n", node->debug_id);
+ pr_err("invalid inc weak node for %d\n",
+ node->debug_id);
return -EINVAL;
}
list_add_tail(&node->work.entry, target_list);
@@ -962,12 +974,12 @@ static int binder_dec_node(struct binder_node *node, int strong, int internal)
if (node->proc) {
rb_erase(&node->rb_node, &node->proc->nodes);
binder_debug(BINDER_DEBUG_INTERNAL_REFS,
- "binder: refless node %d deleted\n",
+ "refless node %d deleted\n",
node->debug_id);
} else {
hlist_del(&node->dead_node);
binder_debug(BINDER_DEBUG_INTERNAL_REFS,
- "binder: dead node %d deleted\n",
+ "dead node %d deleted\n",
node->debug_id);
}
kfree(node);
@@ -1053,14 +1065,13 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc,
hlist_add_head(&new_ref->node_entry, &node->refs);
binder_debug(BINDER_DEBUG_INTERNAL_REFS,
- "binder: %d new ref %d desc %d for "
- "node %d\n", proc->pid, new_ref->debug_id,
- new_ref->desc, node->debug_id);
+ "%d new ref %d desc %d for node %d\n",
+ proc->pid, new_ref->debug_id, new_ref->desc,
+ node->debug_id);
} else {
binder_debug(BINDER_DEBUG_INTERNAL_REFS,
- "binder: %d new ref %d desc %d for "
- "dead node\n", proc->pid, new_ref->debug_id,
- new_ref->desc);
+ "%d new ref %d desc %d for dead node\n",
+ proc->pid, new_ref->debug_id, new_ref->desc);
}
return new_ref;
}
@@ -1068,9 +1079,9 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc,
static void binder_delete_ref(struct binder_ref *ref)
{
binder_debug(BINDER_DEBUG_INTERNAL_REFS,
- "binder: %d delete ref %d desc %d for "
- "node %d\n", ref->proc->pid, ref->debug_id,
- ref->desc, ref->node->debug_id);
+ "%d delete ref %d desc %d for node %d\n",
+ ref->proc->pid, ref->debug_id, ref->desc,
+ ref->node->debug_id);
rb_erase(&ref->rb_node_desc, &ref->proc->refs_by_desc);
rb_erase(&ref->rb_node_node, &ref->proc->refs_by_node);
@@ -1080,9 +1091,8 @@ static void binder_delete_ref(struct binder_ref *ref)
binder_dec_node(ref->node, 0, 1);
if (ref->death) {
binder_debug(BINDER_DEBUG_DEAD_BINDER,
- "binder: %d delete ref %d desc %d "
- "has death notification\n", ref->proc->pid,
- ref->debug_id, ref->desc);
+ "%d delete ref %d desc %d has death notification\n",
+ ref->proc->pid, ref->debug_id, ref->desc);
list_del(&ref->death->work.entry);
kfree(ref->death);
binder_stats_deleted(BINDER_STAT_DEATH);
@@ -1118,8 +1128,7 @@ static int binder_dec_ref(struct binder_ref *ref, int strong)
{
if (strong) {
if (ref->strong == 0) {
- binder_user_error("binder: %d invalid dec strong, "
- "ref %d desc %d s %d w %d\n",
+ binder_user_error("%d invalid dec strong, ref %d desc %d s %d w %d\n",
ref->proc->pid, ref->debug_id,
ref->desc, ref->strong, ref->weak);
return -EINVAL;
@@ -1133,8 +1142,7 @@ static int binder_dec_ref(struct binder_ref *ref, int strong)
}
} else {
if (ref->weak == 0) {
- binder_user_error("binder: %d invalid dec weak, "
- "ref %d desc %d s %d w %d\n",
+ binder_user_error("%d invalid dec weak, ref %d desc %d s %d w %d\n",
ref->proc->pid, ref->debug_id,
ref->desc, ref->strong, ref->weak);
return -EINVAL;
@@ -1179,8 +1187,7 @@ static void binder_send_failed_reply(struct binder_transaction *t,
}
if (target_thread->return_error == BR_OK) {
binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
- "binder: send failed reply for "
- "transaction %d to %d:%d\n",
+ "send failed reply for transaction %d to %d:%d\n",
t->debug_id, target_thread->proc->pid,
target_thread->pid);
@@ -1188,9 +1195,8 @@ static void binder_send_failed_reply(struct binder_transaction *t,
target_thread->return_error = error_code;
wake_up_interruptible(&target_thread->wait);
} else {
- pr_err("binder: reply failed, target "
- "thread, %d:%d, has error code %d "
- "already\n", target_thread->proc->pid,
+ pr_err("reply failed, target thread, %d:%d, has error code %d already\n",
+ target_thread->proc->pid,
target_thread->pid,
target_thread->return_error);
}
@@ -1199,21 +1205,19 @@ static void binder_send_failed_reply(struct binder_transaction *t,
struct binder_transaction *next = t->from_parent;
binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
- "binder: send failed reply "
- "for transaction %d, target dead\n",
+ "send failed reply for transaction %d, target dead\n",
t->debug_id);
binder_pop_transaction(target_thread, t);
if (next == NULL) {
binder_debug(BINDER_DEBUG_DEAD_BINDER,
- "binder: reply failed,"
- " no target thread at root\n");
+ "reply failed, no target thread at root\n");
return;
}
t = next;
binder_debug(BINDER_DEBUG_DEAD_BINDER,
- "binder: reply failed, no target "
- "thread -- retry %d\n", t->debug_id);
+ "reply failed, no target thread -- retry %d\n",
+ t->debug_id);
}
}
}
@@ -1226,7 +1230,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
int debug_id = buffer->debug_id;
binder_debug(BINDER_DEBUG_TRANSACTION,
- "binder: %d buffer release %d, size %zd-%zd, failed at %p\n",
+ "%d buffer release %d, size %zd-%zd, failed at %p\n",
proc->pid, buffer->debug_id,
buffer->data_size, buffer->offsets_size, failed_at);
@@ -1243,9 +1247,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
if (*offp > buffer->data_size - sizeof(*fp) ||
buffer->data_size < sizeof(*fp) ||
!IS_ALIGNED(*offp, sizeof(void *))) {
- pr_err("binder: transaction release %d bad"
- "offset %zd, size %zd\n", debug_id,
- *offp, buffer->data_size);
+ pr_err("transaction release %d bad offset %zd, size %zd\n",
+ debug_id, *offp, buffer->data_size);
continue;
}
fp = (struct flat_binder_object *)(buffer->data + *offp);
@@ -1254,8 +1257,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
case BINDER_TYPE_WEAK_BINDER: {
struct binder_node *node = binder_get_node(proc, fp->binder);
if (node == NULL) {
- pr_err("binder: transaction release %d"
- " bad node %p\n", debug_id, fp->binder);
+ pr_err("transaction release %d bad node %p\n",
+ debug_id, fp->binder);
break;
}
binder_debug(BINDER_DEBUG_TRANSACTION,
@@ -1267,9 +1270,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
case BINDER_TYPE_WEAK_HANDLE: {
struct binder_ref *ref = binder_get_ref(proc, fp->handle);
if (ref == NULL) {
- pr_err("binder: transaction release %d"
- " bad handle %ld\n", debug_id,
- fp->handle);
+ pr_err("transaction release %d bad handle %ld\n",
+ debug_id, fp->handle);
break;
}
binder_debug(BINDER_DEBUG_TRANSACTION,
@@ -1286,8 +1288,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
break;
default:
- pr_err("binder: transaction release %d bad "
- "object type %lx\n", debug_id, fp->type);
+ pr_err("transaction release %d bad object type %lx\n",
+ debug_id, fp->type);
break;
}
}
@@ -1320,17 +1322,14 @@ static void binder_transaction(struct binder_proc *proc,
if (reply) {
in_reply_to = thread->transaction_stack;
if (in_reply_to == NULL) {
- binder_user_error("binder: %d:%d got reply transaction "
- "with no transaction stack\n",
+ binder_user_error("%d:%d got reply transaction with no transaction stack\n",
proc->pid, thread->pid);
return_error = BR_FAILED_REPLY;
goto err_empty_call_stack;
}
binder_set_nice(in_reply_to->saved_priority);
if (in_reply_to->to_thread != thread) {
- binder_user_error("binder: %d:%d got reply transaction "
- "with bad transaction stack,"
- " transaction %d has target %d:%d\n",
+ binder_user_error("%d:%d got reply transaction with bad transaction stack, transaction %d has target %d:%d\n",
proc->pid, thread->pid, in_reply_to->debug_id,
in_reply_to->to_proc ?
in_reply_to->to_proc->pid : 0,
@@ -1347,9 +1346,7 @@ static void binder_transaction(struct binder_proc *proc,
goto err_dead_binder;
}
if (target_thread->transaction_stack != in_reply_to) {
- binder_user_error("binder: %d:%d got reply transaction "
- "with bad target transaction stack %d, "
- "expected %d\n",
+ binder_user_error("%d:%d got reply transaction with bad target transaction stack %d, expected %d\n",
proc->pid, thread->pid,
target_thread->transaction_stack ?
target_thread->transaction_stack->debug_id : 0,
@@ -1365,8 +1362,7 @@ static void binder_transaction(struct binder_proc *proc,
struct binder_ref *ref;
ref = binder_get_ref(proc, tr->target.handle);
if (ref == NULL) {
- binder_user_error("binder: %d:%d got "
- "transaction to invalid handle\n",
+ binder_user_error("%d:%d got transaction to invalid handle\n",
proc->pid, thread->pid);
return_error = BR_FAILED_REPLY;
goto err_invalid_target_handle;
@@ -1389,9 +1385,7 @@ static void binder_transaction(struct binder_proc *proc,
struct binder_transaction *tmp;
tmp = thread->transaction_stack;
if (tmp->to_thread != thread) {
- binder_user_error("binder: %d:%d got new "
- "transaction with bad transaction stack"
- ", transaction %d has target %d:%d\n",
+ binder_user_error("%d:%d got new transaction with bad transaction stack, transaction %d has target %d:%d\n",
proc->pid, thread->pid, tmp->debug_id,
tmp->to_proc ? tmp->to_proc->pid : 0,
tmp->to_thread ?
@@ -1436,16 +1430,14 @@ static void binder_transaction(struct binder_proc *proc,
if (reply)
binder_debug(BINDER_DEBUG_TRANSACTION,
- "binder: %d:%d BC_REPLY %d -> %d:%d, "
- "data %p-%p size %zd-%zd\n",
+ "%d:%d BC_REPLY %d -> %d:%d, data %p-%p size %zd-%zd\n",
proc->pid, thread->pid, t->debug_id,
target_proc->pid, target_thread->pid,
tr->data.ptr.buffer, tr->data.ptr.offsets,
tr->data_size, tr->offsets_size);
else
binder_debug(BINDER_DEBUG_TRANSACTION,
- "binder: %d:%d BC_TRANSACTION %d -> "
- "%d - node %d, data %p-%p size %zd-%zd\n",
+ "%d:%d BC_TRANSACTION %d -> %d - node %d, data %p-%p size %zd-%zd\n",
proc->pid, thread->pid, t->debug_id,
target_proc->pid, target_node->debug_id,
tr->data.ptr.buffer, tr->data.ptr.offsets,
@@ -1461,6 +1453,9 @@ static void binder_transaction(struct binder_proc *proc,
t->code = tr->code;
t->flags = tr->flags;
t->priority = task_nice(current);
+
+ trace_binder_transaction(reply, t, target_node);
+
t->buffer = binder_alloc_buf(target_proc, tr->data_size,
tr->offsets_size, !reply && (t->flags & TF_ONE_WAY));
if (t->buffer == NULL) {
@@ -1471,27 +1466,27 @@ static void binder_transaction(struct binder_proc *proc,
t->buffer->debug_id = t->debug_id;
t->buffer->transaction = t;
t->buffer->target_node = target_node;
+ trace_binder_transaction_alloc_buf(t->buffer);
if (target_node)
binder_inc_node(target_node, 1, 0, NULL);
offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *)));
if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) {
- binder_user_error("binder: %d:%d got transaction with invalid "
- "data ptr\n", proc->pid, thread->pid);
+ binder_user_error("%d:%d got transaction with invalid data ptr\n",
+ proc->pid, thread->pid);
return_error = BR_FAILED_REPLY;
goto err_copy_data_failed;
}
if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) {
- binder_user_error("binder: %d:%d got transaction with invalid "
- "offsets ptr\n", proc->pid, thread->pid);
+ binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
+ proc->pid, thread->pid);
return_error = BR_FAILED_REPLY;
goto err_copy_data_failed;
}
if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) {
- binder_user_error("binder: %d:%d got transaction with "
- "invalid offsets size, %zd\n",
- proc->pid, thread->pid, tr->offsets_size);
+ binder_user_error("%d:%d got transaction with invalid offsets size, %zd\n",
+ proc->pid, thread->pid, tr->offsets_size);
return_error = BR_FAILED_REPLY;
goto err_bad_offset;
}
@@ -1501,9 +1496,8 @@ static void binder_transaction(struct binder_proc *proc,
if (*offp > t->buffer->data_size - sizeof(*fp) ||
t->buffer->data_size < sizeof(*fp) ||
!IS_ALIGNED(*offp, sizeof(void *))) {
- binder_user_error("binder: %d:%d got transaction with "
- "invalid offset, %zd\n",
- proc->pid, thread->pid, *offp);
+ binder_user_error("%d:%d got transaction with invalid offset, %zd\n",
+ proc->pid, thread->pid, *offp);
return_error = BR_FAILED_REPLY;
goto err_bad_offset;
}
@@ -1523,8 +1517,7 @@ static void binder_transaction(struct binder_proc *proc,
node->accept_fds = !!(fp->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS);
}
if (fp->cookie != node->cookie) {
- binder_user_error("binder: %d:%d sending u%p "
- "node %d, cookie mismatch %p != %p\n",
+ binder_user_error("%d:%d sending u%p node %d, cookie mismatch %p != %p\n",
proc->pid, thread->pid,
fp->binder, node->debug_id,
fp->cookie, node->cookie);
@@ -1543,6 +1536,7 @@ static void binder_transaction(struct binder_proc *proc,
binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE,
&thread->todo);
+ trace_binder_transaction_node_to_ref(t, node, ref);
binder_debug(BINDER_DEBUG_TRANSACTION,
" node %d u%p -> ref %d desc %d\n",
node->debug_id, node->ptr, ref->debug_id,
@@ -1552,10 +1546,9 @@ static void binder_transaction(struct binder_proc *proc,
case BINDER_TYPE_WEAK_HANDLE: {
struct binder_ref *ref = binder_get_ref(proc, fp->handle);
if (ref == NULL) {
- binder_user_error("binder: %d:%d got "
- "transaction with invalid "
- "handle, %ld\n", proc->pid,
- thread->pid, fp->handle);
+ binder_user_error("%d:%d got transaction with invalid handle, %ld\n",
+ proc->pid,
+ thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
goto err_binder_get_ref_failed;
}
@@ -1567,6 +1560,7 @@ static void binder_transaction(struct binder_proc *proc,
fp->binder = ref->node->ptr;
fp->cookie = ref->node->cookie;
binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);
+ trace_binder_transaction_ref_to_node(t, ref);
binder_debug(BINDER_DEBUG_TRANSACTION,
" ref %d desc %d -> node %d u%p\n",
ref->debug_id, ref->desc, ref->node->debug_id,
@@ -1580,6 +1574,8 @@ static void binder_transaction(struct binder_proc *proc,
}
fp->handle = new_ref->desc;
binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
+ trace_binder_transaction_ref_to_ref(t, ref,
+ new_ref);
binder_debug(BINDER_DEBUG_TRANSACTION,
" ref %d desc %d -> ref %d desc %d (node %d)\n",
ref->debug_id, ref->desc, new_ref->debug_id,
@@ -1593,13 +1589,13 @@ static void binder_transaction(struct binder_proc *proc,
if (reply) {
if (!(in_reply_to->flags & TF_ACCEPT_FDS)) {
- binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n",
+ binder_user_error("%d:%d got reply with fd, %ld, but target does not allow fds\n",
proc->pid, thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
goto err_fd_not_allowed;
}
} else if (!target_node->accept_fds) {
- binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n",
+ binder_user_error("%d:%d got transaction with fd, %ld, but target does not allow fds\n",
proc->pid, thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
goto err_fd_not_allowed;
@@ -1607,7 +1603,7 @@ static void binder_transaction(struct binder_proc *proc,
file = fget(fp->handle);
if (file == NULL) {
- binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n",
+ binder_user_error("%d:%d got transaction with invalid fd, %ld\n",
proc->pid, thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
goto err_fget_failed;
@@ -1619,6 +1615,7 @@ static void binder_transaction(struct binder_proc *proc,
goto err_get_unused_fd_failed;
}
task_fd_install(target_proc, target_fd, file);
+ trace_binder_transaction_fd(t, fp->handle, target_fd);
binder_debug(BINDER_DEBUG_TRANSACTION,
" fd %ld -> %d\n", fp->handle, target_fd);
/* TODO: fput? */
@@ -1626,8 +1623,7 @@ static void binder_transaction(struct binder_proc *proc,
} break;
default:
- binder_user_error("binder: %d:%d got transactio"
- "n with invalid object type, %lx\n",
+ binder_user_error("%d:%d got transaction with invalid object type, %lx\n",
proc->pid, thread->pid, fp->type);
return_error = BR_FAILED_REPLY;
goto err_bad_object_type;
@@ -1667,6 +1663,7 @@ err_binder_new_node_failed:
err_bad_object_type:
err_bad_offset:
err_copy_data_failed:
+ trace_binder_transaction_failed_buffer_release(t->buffer);
binder_transaction_buffer_release(target_proc, t->buffer, offp);
t->buffer->transaction = NULL;
binder_free_buf(target_proc, t->buffer);
@@ -1683,7 +1680,7 @@ err_dead_binder:
err_invalid_target_handle:
err_no_context_mgr_node:
binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
- "binder: %d:%d transaction failed %d, size %zd-%zd\n",
+ "%d:%d transaction failed %d, size %zd-%zd\n",
proc->pid, thread->pid, return_error,
tr->data_size, tr->offsets_size);
@@ -1712,6 +1709,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
if (get_user(cmd, (uint32_t __user *)ptr))
return -EFAULT;
ptr += sizeof(uint32_t);
+ trace_binder_command(cmd);
if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) {
binder_stats.bc[_IOC_NR(cmd)]++;
proc->stats.bc[_IOC_NR(cmd)]++;
@@ -1734,18 +1732,14 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
ref = binder_get_ref_for_node(proc,
binder_context_mgr_node);
if (ref->desc != target) {
- binder_user_error("binder: %d:"
- "%d tried to acquire "
- "reference to desc 0, "
- "got %d instead\n",
+ binder_user_error("%d:%d tried to acquire reference to desc 0, got %d instead\n",
proc->pid, thread->pid,
ref->desc);
}
} else
ref = binder_get_ref(proc, target);
if (ref == NULL) {
- binder_user_error("binder: %d:%d refcou"
- "nt change on invalid ref %d\n",
+ binder_user_error("%d:%d refcount change on invalid ref %d\n",
proc->pid, thread->pid, target);
break;
}
@@ -1769,7 +1763,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
break;
}
binder_debug(BINDER_DEBUG_USER_REFS,
- "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n",
+ "%d:%d %s ref %d desc %d s %d w %d for node %d\n",
proc->pid, thread->pid, debug_string, ref->debug_id,
ref->desc, ref->strong, ref->weak, ref->node->debug_id);
break;
@@ -1788,8 +1782,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
ptr += sizeof(void *);
node = binder_get_node(proc, node_ptr);
if (node == NULL) {
- binder_user_error("binder: %d:%d "
- "%s u%p no match\n",
+ binder_user_error("%d:%d %s u%p no match\n",
proc->pid, thread->pid,
cmd == BC_INCREFS_DONE ?
"BC_INCREFS_DONE" :
@@ -1798,8 +1791,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
break;
}
if (cookie != node->cookie) {
- binder_user_error("binder: %d:%d %s u%p node %d"
- " cookie mismatch %p != %p\n",
+ binder_user_error("%d:%d %s u%p node %d cookie mismatch %p != %p\n",
proc->pid, thread->pid,
cmd == BC_INCREFS_DONE ?
"BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
@@ -1809,9 +1801,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
}
if (cmd == BC_ACQUIRE_DONE) {
if (node->pending_strong_ref == 0) {
- binder_user_error("binder: %d:%d "
- "BC_ACQUIRE_DONE node %d has "
- "no pending acquire request\n",
+ binder_user_error("%d:%d BC_ACQUIRE_DONE node %d has no pending acquire request\n",
proc->pid, thread->pid,
node->debug_id);
break;
@@ -1819,9 +1809,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
node->pending_strong_ref = 0;
} else {
if (node->pending_weak_ref == 0) {
- binder_user_error("binder: %d:%d "
- "BC_INCREFS_DONE node %d has "
- "no pending increfs request\n",
+ binder_user_error("%d:%d BC_INCREFS_DONE node %d has no pending increfs request\n",
proc->pid, thread->pid,
node->debug_id);
break;
@@ -1830,17 +1818,17 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
}
binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0);
binder_debug(BINDER_DEBUG_USER_REFS,
- "binder: %d:%d %s node %d ls %d lw %d\n",
+ "%d:%d %s node %d ls %d lw %d\n",
proc->pid, thread->pid,
cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
node->debug_id, node->local_strong_refs, node->local_weak_refs);
break;
}
case BC_ATTEMPT_ACQUIRE:
- pr_err("binder: BC_ATTEMPT_ACQUIRE not supported\n");
+ pr_err("BC_ATTEMPT_ACQUIRE not supported\n");
return -EINVAL;
case BC_ACQUIRE_RESULT:
- pr_err("binder: BC_ACQUIRE_RESULT not supported\n");
+ pr_err("BC_ACQUIRE_RESULT not supported\n");
return -EINVAL;
case BC_FREE_BUFFER: {
@@ -1853,20 +1841,17 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
buffer = binder_buffer_lookup(proc, data_ptr);
if (buffer == NULL) {
- binder_user_error("binder: %d:%d "
- "BC_FREE_BUFFER u%p no match\n",
+ binder_user_error("%d:%d BC_FREE_BUFFER u%p no match\n",
proc->pid, thread->pid, data_ptr);
break;
}
if (!buffer->allow_user_free) {
- binder_user_error("binder: %d:%d "
- "BC_FREE_BUFFER u%p matched "
- "unreturned buffer\n",
+ binder_user_error("%d:%d BC_FREE_BUFFER u%p matched unreturned buffer\n",
proc->pid, thread->pid, data_ptr);
break;
}
binder_debug(BINDER_DEBUG_FREE_BUFFER,
- "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n",
+ "%d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n",
proc->pid, thread->pid, data_ptr, buffer->debug_id,
buffer->transaction ? "active" : "finished");
@@ -1881,6 +1866,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
else
list_move_tail(buffer->target_node->async_todo.next, &thread->todo);
}
+ trace_binder_transaction_buffer_release(buffer);
binder_transaction_buffer_release(proc, buffer, NULL);
binder_free_buf(proc, buffer);
break;
@@ -1899,19 +1885,15 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
case BC_REGISTER_LOOPER:
binder_debug(BINDER_DEBUG_THREADS,
- "binder: %d:%d BC_REGISTER_LOOPER\n",
+ "%d:%d BC_REGISTER_LOOPER\n",
proc->pid, thread->pid);
if (thread->looper & BINDER_LOOPER_STATE_ENTERED) {
thread->looper |= BINDER_LOOPER_STATE_INVALID;
- binder_user_error("binder: %d:%d ERROR:"
- " BC_REGISTER_LOOPER called "
- "after BC_ENTER_LOOPER\n",
+ binder_user_error("%d:%d ERROR: BC_REGISTER_LOOPER called after BC_ENTER_LOOPER\n",
proc->pid, thread->pid);
} else if (proc->requested_threads == 0) {
thread->looper |= BINDER_LOOPER_STATE_INVALID;
- binder_user_error("binder: %d:%d ERROR:"
- " BC_REGISTER_LOOPER called "
- "without request\n",
+ binder_user_error("%d:%d ERROR: BC_REGISTER_LOOPER called without request\n",
proc->pid, thread->pid);
} else {
proc->requested_threads--;
@@ -1921,20 +1903,18 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
break;
case BC_ENTER_LOOPER:
binder_debug(BINDER_DEBUG_THREADS,
- "binder: %d:%d BC_ENTER_LOOPER\n",
+ "%d:%d BC_ENTER_LOOPER\n",
proc->pid, thread->pid);
if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) {
thread->looper |= BINDER_LOOPER_STATE_INVALID;
- binder_user_error("binder: %d:%d ERROR:"
- " BC_ENTER_LOOPER called after "
- "BC_REGISTER_LOOPER\n",
+ binder_user_error("%d:%d ERROR: BC_ENTER_LOOPER called after BC_REGISTER_LOOPER\n",
proc->pid, thread->pid);
}
thread->looper |= BINDER_LOOPER_STATE_ENTERED;
break;
case BC_EXIT_LOOPER:
binder_debug(BINDER_DEBUG_THREADS,
- "binder: %d:%d BC_EXIT_LOOPER\n",
+ "%d:%d BC_EXIT_LOOPER\n",
proc->pid, thread->pid);
thread->looper |= BINDER_LOOPER_STATE_EXITED;
break;
@@ -1954,8 +1934,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
ptr += sizeof(void *);
ref = binder_get_ref(proc, target);
if (ref == NULL) {
- binder_user_error("binder: %d:%d %s "
- "invalid ref %d\n",
+ binder_user_error("%d:%d %s invalid ref %d\n",
proc->pid, thread->pid,
cmd == BC_REQUEST_DEATH_NOTIFICATION ?
"BC_REQUEST_DEATH_NOTIFICATION" :
@@ -1965,7 +1944,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
}
binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
- "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n",
+ "%d:%d %s %p ref %d desc %d s %d w %d for node %d\n",
proc->pid, thread->pid,
cmd == BC_REQUEST_DEATH_NOTIFICATION ?
"BC_REQUEST_DEATH_NOTIFICATION" :
@@ -1975,10 +1954,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
if (cmd == BC_REQUEST_DEATH_NOTIFICATION) {
if (ref->death) {
- binder_user_error("binder: %d:%"
- "d BC_REQUEST_DEATH_NOTI"
- "FICATION death notific"
- "ation already set\n",
+ binder_user_error("%d:%d BC_REQUEST_DEATH_NOTIFICATION death notification already set\n",
proc->pid, thread->pid);
break;
}
@@ -1986,8 +1962,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
if (death == NULL) {
thread->return_error = BR_ERROR;
binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
- "binder: %d:%d "
- "BC_REQUEST_DEATH_NOTIFICATION failed\n",
+ "%d:%d BC_REQUEST_DEATH_NOTIFICATION failed\n",
proc->pid, thread->pid);
break;
}
@@ -2006,20 +1981,13 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
}
} else {
if (ref->death == NULL) {
- binder_user_error("binder: %d:%"
- "d BC_CLEAR_DEATH_NOTIFI"
- "CATION death notificat"
- "ion not active\n",
+ binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification not active\n",
proc->pid, thread->pid);
break;
}
death = ref->death;
if (death->cookie != cookie) {
- binder_user_error("binder: %d:%"
- "d BC_CLEAR_DEATH_NOTIFI"
- "CATION death notificat"
- "ion cookie mismatch "
- "%p != %p\n",
+ binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification cookie mismatch %p != %p\n",
proc->pid, thread->pid,
death->cookie, cookie);
break;
@@ -2055,11 +2023,10 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
}
}
binder_debug(BINDER_DEBUG_DEAD_BINDER,
- "binder: %d:%d BC_DEAD_BINDER_DONE %p found %p\n",
+ "%d:%d BC_DEAD_BINDER_DONE %p found %p\n",
proc->pid, thread->pid, cookie, death);
if (death == NULL) {
- binder_user_error("binder: %d:%d BC_DEAD"
- "_BINDER_DONE %p not found\n",
+ binder_user_error("%d:%d BC_DEAD_BINDER_DONE %p not found\n",
proc->pid, thread->pid, cookie);
break;
}
@@ -2077,7 +2044,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
} break;
default:
- pr_err("binder: %d:%d unknown command %d\n",
+ pr_err("%d:%d unknown command %d\n",
proc->pid, thread->pid, cmd);
return -EINVAL;
}
@@ -2089,6 +2056,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
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)) {
binder_stats.br[_IOC_NR(cmd)]++;
proc->stats.br[_IOC_NR(cmd)]++;
@@ -2135,6 +2103,7 @@ retry:
if (put_user(thread->return_error2, (uint32_t __user *)ptr))
return -EFAULT;
ptr += sizeof(uint32_t);
+ binder_stat_br(proc, thread, thread->return_error2);
if (ptr == end)
goto done;
thread->return_error2 = BR_OK;
@@ -2142,6 +2111,7 @@ retry:
if (put_user(thread->return_error, (uint32_t __user *)ptr))
return -EFAULT;
ptr += sizeof(uint32_t);
+ binder_stat_br(proc, thread, thread->return_error);
thread->return_error = BR_OK;
goto done;
}
@@ -2150,13 +2120,16 @@ retry:
thread->looper |= BINDER_LOOPER_STATE_WAITING;
if (wait_for_proc_work)
proc->ready_threads++;
- mutex_unlock(&binder_lock);
+
+ binder_unlock(__func__);
+
+ trace_binder_wait_for_work(wait_for_proc_work,
+ !!thread->transaction_stack,
+ !list_empty(&thread->todo));
if (wait_for_proc_work) {
if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED |
BINDER_LOOPER_STATE_ENTERED))) {
- binder_user_error("binder: %d:%d ERROR: Thread waiting "
- "for process work before calling BC_REGISTER_"
- "LOOPER or BC_ENTER_LOOPER (state %x)\n",
+ binder_user_error("%d:%d ERROR: Thread waiting for process work before calling BC_REGISTER_LOOPER or BC_ENTER_LOOPER (state %x)\n",
proc->pid, thread->pid, thread->looper);
wait_event_interruptible(binder_user_error_wait,
binder_stop_on_user_error < 2);
@@ -2174,7 +2147,9 @@ retry:
} else
ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread));
}
- mutex_lock(&binder_lock);
+
+ binder_lock(__func__);
+
if (wait_for_proc_work)
proc->ready_threads--;
thread->looper &= ~BINDER_LOOPER_STATE_WAITING;
@@ -2213,7 +2188,7 @@ retry:
binder_stat_br(proc, thread, cmd);
binder_debug(BINDER_DEBUG_TRANSACTION_COMPLETE,
- "binder: %d:%d BR_TRANSACTION_COMPLETE\n",
+ "%d:%d BR_TRANSACTION_COMPLETE\n",
proc->pid, thread->pid);
list_del(&w->entry);
@@ -2260,13 +2235,13 @@ retry:
binder_stat_br(proc, thread, cmd);
binder_debug(BINDER_DEBUG_USER_REFS,
- "binder: %d:%d %s %d u%p c%p\n",
+ "%d:%d %s %d u%p c%p\n",
proc->pid, thread->pid, cmd_name, node->debug_id, node->ptr, node->cookie);
} else {
list_del_init(&w->entry);
if (!weak && !strong) {
binder_debug(BINDER_DEBUG_INTERNAL_REFS,
- "binder: %d:%d node %d u%p c%p deleted\n",
+ "%d:%d node %d u%p c%p deleted\n",
proc->pid, thread->pid, node->debug_id,
node->ptr, node->cookie);
rb_erase(&node->rb_node, &proc->nodes);
@@ -2274,7 +2249,7 @@ retry:
binder_stats_deleted(BINDER_STAT_NODE);
} else {
binder_debug(BINDER_DEBUG_INTERNAL_REFS,
- "binder: %d:%d node %d u%p c%p state unchanged\n",
+ "%d:%d node %d u%p c%p state unchanged\n",
proc->pid, thread->pid, node->debug_id, node->ptr,
node->cookie);
}
@@ -2297,8 +2272,9 @@ retry:
if (put_user(death->cookie, (void * __user *)ptr))
return -EFAULT;
ptr += sizeof(void *);
+ binder_stat_br(proc, thread, cmd);
binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
- "binder: %d:%d %s %p\n",
+ "%d:%d %s %p\n",
proc->pid, thread->pid,
cmd == BR_DEAD_BINDER ?
"BR_DEAD_BINDER" :
@@ -2364,10 +2340,10 @@ retry:
return -EFAULT;
ptr += sizeof(tr);
+ trace_binder_transaction_received(t);
binder_stat_br(proc, thread, cmd);
binder_debug(BINDER_DEBUG_TRANSACTION,
- "binder: %d:%d %s %d %d:%d, cmd %d"
- "size %zd-%zd ptr %p-%p\n",
+ "%d:%d %s %d %d:%d, cmd %d size %zd-%zd ptr %p-%p\n",
proc->pid, thread->pid,
(cmd == BR_TRANSACTION) ? "BR_TRANSACTION" :
"BR_REPLY",
@@ -2400,10 +2376,11 @@ done:
/*spawn a new thread if we leave this out */) {
proc->requested_threads++;
binder_debug(BINDER_DEBUG_THREADS,
- "binder: %d:%d BR_SPAWN_LOOPER\n",
+ "%d:%d BR_SPAWN_LOOPER\n",
proc->pid, thread->pid);
if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer))
return -EFAULT;
+ binder_stat_br(proc, thread, BR_SPAWN_LOOPER);
}
return 0;
}
@@ -2424,7 +2401,7 @@ static void binder_release_work(struct list_head *list)
binder_send_failed_reply(t, BR_DEAD_REPLY);
} else {
binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
- "binder: undelivered transaction %d\n",
+ "undelivered transaction %d\n",
t->debug_id);
t->buffer->transaction = NULL;
kfree(t);
@@ -2433,7 +2410,7 @@ static void binder_release_work(struct list_head *list)
} break;
case BINDER_WORK_TRANSACTION_COMPLETE: {
binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
- "binder: undelivered TRANSACTION_COMPLETE\n");
+ "undelivered TRANSACTION_COMPLETE\n");
kfree(w);
binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
} break;
@@ -2443,13 +2420,13 @@ static void binder_release_work(struct list_head *list)
death = container_of(w, struct binder_ref_death, work);
binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
- "binder: undelivered death notification, %p\n",
+ "undelivered death notification, %p\n",
death->cookie);
kfree(death);
binder_stats_deleted(BINDER_STAT_DEATH);
} break;
default:
- pr_err("binder: unexpected work type, %d, not freed\n",
+ pr_err("unexpected work type, %d, not freed\n",
w->type);
break;
}
@@ -2506,8 +2483,8 @@ static int binder_free_thread(struct binder_proc *proc,
while (t) {
active_transactions++;
binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
- "binder: release %d:%d transaction %d "
- "%s, still active\n", proc->pid, thread->pid,
+ "release %d:%d transaction %d %s, still active\n",
+ proc->pid, thread->pid,
t->debug_id,
(t->to_thread == thread) ? "in" : "out");
@@ -2540,12 +2517,14 @@ static unsigned int binder_poll(struct file *filp,
struct binder_thread *thread = NULL;
int wait_for_proc_work;
- mutex_lock(&binder_lock);
+ binder_lock(__func__);
+
thread = binder_get_thread(proc);
wait_for_proc_work = thread->transaction_stack == NULL &&
list_empty(&thread->todo) && thread->return_error == BR_OK;
- mutex_unlock(&binder_lock);
+
+ binder_unlock(__func__);
if (wait_for_proc_work) {
if (binder_has_proc_work(proc, thread))
@@ -2573,11 +2552,13 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
/*pr_info("binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/
+ trace_binder_ioctl(cmd, arg);
+
ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
if (ret)
- return ret;
+ goto err_unlocked;
- mutex_lock(&binder_lock);
+ binder_lock(__func__);
thread = binder_get_thread(proc);
if (thread == NULL) {
ret = -ENOMEM;
@@ -2596,12 +2577,13 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
goto err;
}
binder_debug(BINDER_DEBUG_READ_WRITE,
- "binder: %d:%d write %ld at %08lx, read %ld at %08lx\n",
- proc->pid, thread->pid, bwr.write_size, bwr.write_buffer,
- bwr.read_size, bwr.read_buffer);
+ "%d:%d write %ld at %08lx, read %ld at %08lx\n",
+ proc->pid, thread->pid, bwr.write_size,
+ bwr.write_buffer, bwr.read_size, bwr.read_buffer);
if (bwr.write_size > 0) {
ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
+ trace_binder_write_done(ret);
if (ret < 0) {
bwr.read_consumed = 0;
if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
@@ -2611,6 +2593,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}
if (bwr.read_size > 0) {
ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK);
+ trace_binder_read_done(ret);
if (!list_empty(&proc->todo))
wake_up_interruptible(&proc->wait);
if (ret < 0) {
@@ -2620,7 +2603,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}
}
binder_debug(BINDER_DEBUG_READ_WRITE,
- "binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n",
+ "%d:%d wrote %ld of %ld, read return %ld of %ld\n",
proc->pid, thread->pid, bwr.write_consumed, bwr.write_size,
bwr.read_consumed, bwr.read_size);
if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
@@ -2637,14 +2620,13 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
break;
case BINDER_SET_CONTEXT_MGR:
if (binder_context_mgr_node != NULL) {
- pr_err("binder: BINDER_SET_CONTEXT_MGR already set\n");
+ pr_err("BINDER_SET_CONTEXT_MGR already set\n");
ret = -EBUSY;
goto err;
}
if (uid_valid(binder_context_mgr_uid)) {
if (!uid_eq(binder_context_mgr_uid, current->cred->euid)) {
- pr_err("binder: BINDER_SET_"
- "CONTEXT_MGR bad uid %d != %d\n",
+ pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n",
from_kuid(&init_user_ns, current->cred->euid),
from_kuid(&init_user_ns, binder_context_mgr_uid));
ret = -EPERM;
@@ -2663,7 +2645,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
binder_context_mgr_node->has_weak_ref = 1;
break;
case BINDER_THREAD_EXIT:
- binder_debug(BINDER_DEBUG_THREADS, "binder: %d:%d exit\n",
+ binder_debug(BINDER_DEBUG_THREADS, "%d:%d exit\n",
proc->pid, thread->pid);
binder_free_thread(proc, thread);
thread = NULL;
@@ -2686,10 +2668,12 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
err:
if (thread)
thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN;
- mutex_unlock(&binder_lock);
+ binder_unlock(__func__);
wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
if (ret && ret != -ERESTARTSYS)
- pr_info("binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
+ pr_info("%d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
+err_unlocked:
+ trace_binder_ioctl_done(ret);
return ret;
}
@@ -2697,7 +2681,7 @@ static void binder_vma_open(struct vm_area_struct *vma)
{
struct binder_proc *proc = vma->vm_private_data;
binder_debug(BINDER_DEBUG_OPEN_CLOSE,
- "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
+ "%d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
proc->pid, vma->vm_start, vma->vm_end,
(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
(unsigned long)pgprot_val(vma->vm_page_prot));
@@ -2707,7 +2691,7 @@ static void binder_vma_close(struct vm_area_struct *vma)
{
struct binder_proc *proc = vma->vm_private_data;
binder_debug(BINDER_DEBUG_OPEN_CLOSE,
- "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
+ "%d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
proc->pid, vma->vm_start, vma->vm_end,
(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
(unsigned long)pgprot_val(vma->vm_page_prot));
@@ -2835,13 +2819,16 @@ static int binder_open(struct inode *nodp, struct file *filp)
INIT_LIST_HEAD(&proc->todo);
init_waitqueue_head(&proc->wait);
proc->default_priority = task_nice(current);
- mutex_lock(&binder_lock);
+
+ binder_lock(__func__);
+
binder_stats_created(BINDER_STAT_PROC);
hlist_add_head(&proc->proc_node, &binder_procs);
proc->pid = current->group_leader->pid;
INIT_LIST_HEAD(&proc->delivered_death);
filp->private_data = proc;
- mutex_unlock(&binder_lock);
+
+ binder_unlock(__func__);
if (binder_debugfs_dir_entry_proc) {
char strbuf[11];
@@ -2949,9 +2936,8 @@ static void binder_deferred_release(struct binder_proc *proc)
}
}
binder_debug(BINDER_DEBUG_DEAD_BINDER,
- "binder: node %d now dead, "
- "refs %d, death %d\n", node->debug_id,
- incoming_refs, death);
+ "node %d now dead, refs %d, death %d\n",
+ node->debug_id, incoming_refs, death);
}
}
outgoing_refs = 0;
@@ -2972,8 +2958,7 @@ static void binder_deferred_release(struct binder_proc *proc)
if (t) {
t->buffer = NULL;
buffer->transaction = NULL;
- pr_err("binder: release proc %d, "
- "transaction %d, not freed\n",
+ pr_err("release proc %d, transaction %d, not freed\n",
proc->pid, t->debug_id);
/*BUG();*/
}
@@ -2990,8 +2975,7 @@ static void binder_deferred_release(struct binder_proc *proc)
if (proc->pages[i]) {
void *page_addr = proc->buffer + i * PAGE_SIZE;
binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
- "binder_release: %d: "
- "page %d at %p not freed\n",
+ "binder_release: %d: page %d at %p not freed\n",
proc->pid, i,
page_addr);
unmap_kernel_range((unsigned long)page_addr,
@@ -3007,9 +2991,7 @@ static void binder_deferred_release(struct binder_proc *proc)
put_task_struct(proc->tsk);
binder_debug(BINDER_DEBUG_OPEN_CLOSE,
- "binder_release: %d threads %d, nodes %d (ref %d), "
- "refs %d, active transactions %d, buffers %d, "
- "pages %d\n",
+ "binder_release: %d threads %d, nodes %d (ref %d), refs %d, active transactions %d, buffers %d, pages %d\n",
proc->pid, threads, nodes, incoming_refs, outgoing_refs,
active_transactions, buffers, page_count);
@@ -3023,7 +3005,7 @@ static void binder_deferred_func(struct work_struct *work)
int defer;
do {
- mutex_lock(&binder_lock);
+ binder_lock(__func__);
mutex_lock(&binder_deferred_lock);
if (!hlist_empty(&binder_deferred_list)) {
proc = hlist_entry(binder_deferred_list.first,
@@ -3050,7 +3032,7 @@ static void binder_deferred_func(struct work_struct *work)
if (defer & BINDER_DEFERRED_RELEASE)
binder_deferred_release(proc); /* frees proc */
- mutex_unlock(&binder_lock);
+ binder_unlock(__func__);
if (files)
put_files_struct(files);
} while (proc);
@@ -3391,7 +3373,7 @@ static int binder_state_show(struct seq_file *m, void *unused)
int do_lock = !binder_debug_no_lock;
if (do_lock)
- mutex_lock(&binder_lock);
+ binder_lock(__func__);
seq_puts(m, "binder state:\n");
@@ -3403,7 +3385,7 @@ static int binder_state_show(struct seq_file *m, void *unused)
hlist_for_each_entry(proc, pos, &binder_procs, proc_node)
print_binder_proc(m, proc, 1);
if (do_lock)
- mutex_unlock(&binder_lock);
+ binder_unlock(__func__);
return 0;
}
@@ -3414,7 +3396,7 @@ static int binder_stats_show(struct seq_file *m, void *unused)
int do_lock = !binder_debug_no_lock;
if (do_lock)
- mutex_lock(&binder_lock);
+ binder_lock(__func__);
seq_puts(m, "binder stats:\n");
@@ -3423,7 +3405,7 @@ static int binder_stats_show(struct seq_file *m, void *unused)
hlist_for_each_entry(proc, pos, &binder_procs, proc_node)
print_binder_proc_stats(m, proc);
if (do_lock)
- mutex_unlock(&binder_lock);
+ binder_unlock(__func__);
return 0;
}
@@ -3434,13 +3416,13 @@ static int binder_transactions_show(struct seq_file *m, void *unused)
int do_lock = !binder_debug_no_lock;
if (do_lock)
- mutex_lock(&binder_lock);
+ binder_lock(__func__);
seq_puts(m, "binder transactions:\n");
hlist_for_each_entry(proc, pos, &binder_procs, proc_node)
print_binder_proc(m, proc, 0);
if (do_lock)
- mutex_unlock(&binder_lock);
+ binder_unlock(__func__);
return 0;
}
@@ -3450,11 +3432,11 @@ static int binder_proc_show(struct seq_file *m, void *unused)
int do_lock = !binder_debug_no_lock;
if (do_lock)
- mutex_lock(&binder_lock);
+ binder_lock(__func__);
seq_puts(m, "binder proc state:\n");
print_binder_proc(m, proc, 1);
if (do_lock)
- mutex_unlock(&binder_lock);
+ binder_unlock(__func__);
return 0;
}
@@ -3549,4 +3531,7 @@ static int __init binder_init(void)
device_initcall(binder_init);
+#define CREATE_TRACE_POINTS
+#include "binder_trace.h"
+
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/android/binder_trace.h b/drivers/staging/android/binder_trace.h
new file mode 100644
index 00000000000..82a567c2af6
--- /dev/null
+++ b/drivers/staging/android/binder_trace.h
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM binder
+
+#if !defined(_BINDER_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _BINDER_TRACE_H
+
+#include <linux/tracepoint.h>
+
+struct binder_buffer;
+struct binder_node;
+struct binder_proc;
+struct binder_ref;
+struct binder_thread;
+struct binder_transaction;
+
+TRACE_EVENT(binder_ioctl,
+ TP_PROTO(unsigned int cmd, unsigned long arg),
+ TP_ARGS(cmd, arg),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, cmd)
+ __field(unsigned long, arg)
+ ),
+ TP_fast_assign(
+ __entry->cmd = cmd;
+ __entry->arg = arg;
+ ),
+ TP_printk("cmd=0x%x arg=0x%lx", __entry->cmd, __entry->arg)
+);
+
+DECLARE_EVENT_CLASS(binder_lock_class,
+ TP_PROTO(const char *tag),
+ TP_ARGS(tag),
+ TP_STRUCT__entry(
+ __field(const char *, tag)
+ ),
+ TP_fast_assign(
+ __entry->tag = tag;
+ ),
+ TP_printk("tag=%s", __entry->tag)
+);
+
+#define DEFINE_BINDER_LOCK_EVENT(name) \
+DEFINE_EVENT(binder_lock_class, name, \
+ TP_PROTO(const char *func), \
+ TP_ARGS(func))
+
+DEFINE_BINDER_LOCK_EVENT(binder_lock);
+DEFINE_BINDER_LOCK_EVENT(binder_locked);
+DEFINE_BINDER_LOCK_EVENT(binder_unlock);
+
+DECLARE_EVENT_CLASS(binder_function_return_class,
+ TP_PROTO(int ret),
+ TP_ARGS(ret),
+ TP_STRUCT__entry(
+ __field(int, ret)
+ ),
+ TP_fast_assign(
+ __entry->ret = ret;
+ ),
+ TP_printk("ret=%d", __entry->ret)
+);
+
+#define DEFINE_BINDER_FUNCTION_RETURN_EVENT(name) \
+DEFINE_EVENT(binder_function_return_class, name, \
+ TP_PROTO(int ret), \
+ TP_ARGS(ret))
+
+DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_ioctl_done);
+DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_write_done);
+DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_read_done);
+
+TRACE_EVENT(binder_wait_for_work,
+ TP_PROTO(bool proc_work, bool transaction_stack, bool thread_todo),
+ TP_ARGS(proc_work, transaction_stack, thread_todo),
+
+ TP_STRUCT__entry(
+ __field(bool, proc_work)
+ __field(bool, transaction_stack)
+ __field(bool, thread_todo)
+ ),
+ TP_fast_assign(
+ __entry->proc_work = proc_work;
+ __entry->transaction_stack = transaction_stack;
+ __entry->thread_todo = thread_todo;
+ ),
+ TP_printk("proc_work=%d transaction_stack=%d thread_todo=%d",
+ __entry->proc_work, __entry->transaction_stack,
+ __entry->thread_todo)
+);
+
+TRACE_EVENT(binder_transaction,
+ TP_PROTO(bool reply, struct binder_transaction *t,
+ struct binder_node *target_node),
+ TP_ARGS(reply, t, target_node),
+ TP_STRUCT__entry(
+ __field(int, debug_id)
+ __field(int, target_node)
+ __field(int, to_proc)
+ __field(int, to_thread)
+ __field(int, reply)
+ __field(unsigned int, code)
+ __field(unsigned int, flags)
+ ),
+ TP_fast_assign(
+ __entry->debug_id = t->debug_id;
+ __entry->target_node = target_node ? target_node->debug_id : 0;
+ __entry->to_proc = t->to_proc->pid;
+ __entry->to_thread = t->to_thread ? t->to_thread->pid : 0;
+ __entry->reply = reply;
+ __entry->code = t->code;
+ __entry->flags = t->flags;
+ ),
+ TP_printk("transaction=%d dest_node=%d dest_proc=%d dest_thread=%d reply=%d flags=0x%x code=0x%x",
+ __entry->debug_id, __entry->target_node,
+ __entry->to_proc, __entry->to_thread,
+ __entry->reply, __entry->flags, __entry->code)
+);
+
+TRACE_EVENT(binder_transaction_received,
+ TP_PROTO(struct binder_transaction *t),
+ TP_ARGS(t),
+
+ TP_STRUCT__entry(
+ __field(int, debug_id)
+ ),
+ TP_fast_assign(
+ __entry->debug_id = t->debug_id;
+ ),
+ TP_printk("transaction=%d", __entry->debug_id)
+);
+
+TRACE_EVENT(binder_transaction_node_to_ref,
+ TP_PROTO(struct binder_transaction *t, struct binder_node *node,
+ struct binder_ref *ref),
+ TP_ARGS(t, node, ref),
+
+ TP_STRUCT__entry(
+ __field(int, debug_id)
+ __field(int, node_debug_id)
+ __field(void __user *, node_ptr)
+ __field(int, ref_debug_id)
+ __field(uint32_t, ref_desc)
+ ),
+ TP_fast_assign(
+ __entry->debug_id = t->debug_id;
+ __entry->node_debug_id = node->debug_id;
+ __entry->node_ptr = node->ptr;
+ __entry->ref_debug_id = ref->debug_id;
+ __entry->ref_desc = ref->desc;
+ ),
+ TP_printk("transaction=%d node=%d src_ptr=0x%p ==> dest_ref=%d dest_desc=%d",
+ __entry->debug_id, __entry->node_debug_id, __entry->node_ptr,
+ __entry->ref_debug_id, __entry->ref_desc)
+);
+
+TRACE_EVENT(binder_transaction_ref_to_node,
+ TP_PROTO(struct binder_transaction *t, struct binder_ref *ref),
+ TP_ARGS(t, ref),
+
+ TP_STRUCT__entry(
+ __field(int, debug_id)
+ __field(int, ref_debug_id)
+ __field(uint32_t, ref_desc)
+ __field(int, node_debug_id)
+ __field(void __user *, node_ptr)
+ ),
+ TP_fast_assign(
+ __entry->debug_id = t->debug_id;
+ __entry->ref_debug_id = ref->debug_id;
+ __entry->ref_desc = ref->desc;
+ __entry->node_debug_id = ref->node->debug_id;
+ __entry->node_ptr = ref->node->ptr;
+ ),
+ TP_printk("transaction=%d node=%d src_ref=%d src_desc=%d ==> dest_ptr=0x%p",
+ __entry->debug_id, __entry->node_debug_id,
+ __entry->ref_debug_id, __entry->ref_desc, __entry->node_ptr)
+);
+
+TRACE_EVENT(binder_transaction_ref_to_ref,
+ TP_PROTO(struct binder_transaction *t, struct binder_ref *src_ref,
+ struct binder_ref *dest_ref),
+ TP_ARGS(t, src_ref, dest_ref),
+
+ TP_STRUCT__entry(
+ __field(int, debug_id)
+ __field(int, node_debug_id)
+ __field(int, src_ref_debug_id)
+ __field(uint32_t, src_ref_desc)
+ __field(int, dest_ref_debug_id)
+ __field(uint32_t, dest_ref_desc)
+ ),
+ TP_fast_assign(
+ __entry->debug_id = t->debug_id;
+ __entry->node_debug_id = src_ref->node->debug_id;
+ __entry->src_ref_debug_id = src_ref->debug_id;
+ __entry->src_ref_desc = src_ref->desc;
+ __entry->dest_ref_debug_id = dest_ref->debug_id;
+ __entry->dest_ref_desc = dest_ref->desc;
+ ),
+ TP_printk("transaction=%d node=%d src_ref=%d src_desc=%d ==> dest_ref=%d dest_desc=%d",
+ __entry->debug_id, __entry->node_debug_id,
+ __entry->src_ref_debug_id, __entry->src_ref_desc,
+ __entry->dest_ref_debug_id, __entry->dest_ref_desc)
+);
+
+TRACE_EVENT(binder_transaction_fd,
+ TP_PROTO(struct binder_transaction *t, int src_fd, int dest_fd),
+ TP_ARGS(t, src_fd, dest_fd),
+
+ TP_STRUCT__entry(
+ __field(int, debug_id)
+ __field(int, src_fd)
+ __field(int, dest_fd)
+ ),
+ TP_fast_assign(
+ __entry->debug_id = t->debug_id;
+ __entry->src_fd = src_fd;
+ __entry->dest_fd = dest_fd;
+ ),
+ TP_printk("transaction=%d src_fd=%d ==> dest_fd=%d",
+ __entry->debug_id, __entry->src_fd, __entry->dest_fd)
+);
+
+DECLARE_EVENT_CLASS(binder_buffer_class,
+ TP_PROTO(struct binder_buffer *buf),
+ TP_ARGS(buf),
+ TP_STRUCT__entry(
+ __field(int, debug_id)
+ __field(size_t, data_size)
+ __field(size_t, offsets_size)
+ ),
+ TP_fast_assign(
+ __entry->debug_id = buf->debug_id;
+ __entry->data_size = buf->data_size;
+ __entry->offsets_size = buf->offsets_size;
+ ),
+ TP_printk("transaction=%d data_size=%zd offsets_size=%zd",
+ __entry->debug_id, __entry->data_size, __entry->offsets_size)
+);
+
+DEFINE_EVENT(binder_buffer_class, binder_transaction_alloc_buf,
+ TP_PROTO(struct binder_buffer *buffer),
+ TP_ARGS(buffer));
+
+DEFINE_EVENT(binder_buffer_class, binder_transaction_buffer_release,
+ TP_PROTO(struct binder_buffer *buffer),
+ TP_ARGS(buffer));
+
+DEFINE_EVENT(binder_buffer_class, binder_transaction_failed_buffer_release,
+ TP_PROTO(struct binder_buffer *buffer),
+ TP_ARGS(buffer));
+
+TRACE_EVENT(binder_update_page_range,
+ TP_PROTO(struct binder_proc *proc, bool allocate,
+ void *start, void *end),
+ TP_ARGS(proc, allocate, start, end),
+ TP_STRUCT__entry(
+ __field(int, proc)
+ __field(bool, allocate)
+ __field(size_t, offset)
+ __field(size_t, size)
+ ),
+ TP_fast_assign(
+ __entry->proc = proc->pid;
+ __entry->allocate = allocate;
+ __entry->offset = start - proc->buffer;
+ __entry->size = end - start;
+ ),
+ TP_printk("proc=%d allocate=%d offset=%zu size=%zu",
+ __entry->proc, __entry->allocate,
+ __entry->offset, __entry->size)
+);
+
+TRACE_EVENT(binder_command,
+ TP_PROTO(uint32_t cmd),
+ TP_ARGS(cmd),
+ TP_STRUCT__entry(
+ __field(uint32_t, cmd)
+ ),
+ TP_fast_assign(
+ __entry->cmd = cmd;
+ ),
+ TP_printk("cmd=0x%x %s",
+ __entry->cmd,
+ _IOC_NR(__entry->cmd) < ARRAY_SIZE(binder_command_strings) ?
+ binder_command_strings[_IOC_NR(__entry->cmd)] :
+ "unknown")
+);
+
+TRACE_EVENT(binder_return,
+ TP_PROTO(uint32_t cmd),
+ TP_ARGS(cmd),
+ TP_STRUCT__entry(
+ __field(uint32_t, cmd)
+ ),
+ TP_fast_assign(
+ __entry->cmd = cmd;
+ ),
+ TP_printk("cmd=0x%x %s",
+ __entry->cmd,
+ _IOC_NR(__entry->cmd) < ARRAY_SIZE(binder_return_strings) ?
+ binder_return_strings[_IOC_NR(__entry->cmd)] :
+ "unknown")
+);
+
+#endif /* _BINDER_TRACE_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE binder_trace
+#include <trace/define_trace.h>
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c
index 1d5ed475364..dbc63cbb4d3 100644
--- a/drivers/staging/android/logger.c
+++ b/drivers/staging/android/logger.c
@@ -676,4 +676,25 @@ static int __init logger_init(void)
out:
return ret;
}
+
+static void __exit logger_exit(void)
+{
+ struct logger_log *current_log, *next_log;
+
+ list_for_each_entry_safe(current_log, next_log, &log_list, logs) {
+ /* we have to delete all the entry inside log_list */
+ misc_deregister(&current_log->misc);
+ vfree(current_log->buffer);
+ kfree(current_log->misc.name);
+ list_del(&current_log->logs);
+ kfree(current_log);
+ }
+}
+
+
device_initcall(logger_init);
+module_exit(logger_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Robert Love, <rlove@google.com>");
+MODULE_DESCRIPTION("Android Logger");
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index b91e4bc332a..3b91b0fd4de 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -40,7 +40,7 @@
#include <linux/notifier.h>
static uint32_t lowmem_debug_level = 2;
-static int lowmem_adj[6] = {
+static short lowmem_adj[6] = {
0,
1,
6,
@@ -70,9 +70,9 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
int rem = 0;
int tasksize;
int i;
- int min_score_adj = OOM_SCORE_ADJ_MAX + 1;
+ short min_score_adj = OOM_SCORE_ADJ_MAX + 1;
int selected_tasksize = 0;
- int selected_oom_score_adj;
+ short selected_oom_score_adj;
int array_size = ARRAY_SIZE(lowmem_adj);
int other_free = global_page_state(NR_FREE_PAGES);
int other_file = global_page_state(NR_FILE_PAGES) -
@@ -90,7 +90,7 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
}
}
if (sc->nr_to_scan > 0)
- lowmem_print(3, "lowmem_shrink %lu, %x, ofree %d %d, ma %d\n",
+ lowmem_print(3, "lowmem_shrink %lu, %x, ofree %d %d, ma %hd\n",
sc->nr_to_scan, sc->gfp_mask, other_free,
other_file, min_score_adj);
rem = global_page_state(NR_ACTIVE_ANON) +
@@ -107,7 +107,7 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
rcu_read_lock();
for_each_process(tsk) {
struct task_struct *p;
- int oom_score_adj;
+ short oom_score_adj;
if (tsk->flags & PF_KTHREAD)
continue;
@@ -141,11 +141,11 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
selected = p;
selected_tasksize = tasksize;
selected_oom_score_adj = oom_score_adj;
- lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n",
+ lowmem_print(2, "select %d (%s), adj %hd, size %d, to kill\n",
p->pid, p->comm, oom_score_adj, tasksize);
}
if (selected) {
- lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n",
+ lowmem_print(1, "send sigkill to %d (%s), adj %hd, size %d\n",
selected->pid, selected->comm,
selected_oom_score_adj, selected_tasksize);
lowmem_deathpending_timeout = jiffies + HZ;
@@ -176,7 +176,7 @@ static void __exit lowmem_exit(void)
}
module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
-module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size,
+module_param_array_named(adj, lowmem_adj, short, &lowmem_adj_size,
S_IRUGO | S_IWUSR);
module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size,
S_IRUGO | S_IWUSR);
diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h
index 4d490a99110..f57794827f7 100644
--- a/drivers/staging/bcm/Adapter.h
+++ b/drivers/staging/bcm/Adapter.h
@@ -151,7 +151,7 @@ struct bcm_packet_info {
UINT NumOfPacketsSent;
UCHAR ucDirection;
USHORT usCID;
- S_MIBS_EXTSERVICEFLOW_PARAMETERS stMibsExtServiceFlowTable;
+ struct bcm_mibs_parameters stMibsExtServiceFlowTable;
UINT uiCurrentRxRate;
UINT uiThisPeriodRxBytes;
UINT uiTotalRxBytes;
@@ -198,7 +198,7 @@ struct bcm_tarang_data {
int AppCtrlQueueLen;
BOOLEAN MacTracingEnabled;
BOOLEAN bApplicationToExit;
- S_MIBS_DROPPED_APP_CNTRL_MESSAGES stDroppedAppCntrlMsgs;
+ struct bcm_mibs_dropped_cntrl_msg stDroppedAppCntrlMsgs;
ULONG RxCntrlMsgBitMask;
};
@@ -371,8 +371,8 @@ struct bcm_mini_adapter {
PFLASH2X_VENDORSPECIFIC_INFO psFlash2xVendorInfo;
UINT uiFlashBaseAdd; /* Flash start address */
UINT uiActiveISOOffset; /* Active ISO offset chosen before f/w download */
- FLASH2X_SECTION_VAL eActiveISO; /* Active ISO section val */
- FLASH2X_SECTION_VAL eActiveDSD; /* Active DSD val chosen before f/w download */
+ enum bcm_flash2x_section_val eActiveISO; /* Active ISO section val */
+ enum bcm_flash2x_section_val eActiveDSD; /* Active DSD val chosen before f/w download */
UINT uiActiveDSDOffsetAtFwDld; /* For accessing Active DSD chosen before f/w download */
UINT uiFlashLayoutMajorVersion;
UINT uiFlashLayoutMinorVersion;
diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c
index 3d02c2ebfb8..efad33e3ba7 100644
--- a/drivers/staging/bcm/Bcmchar.c
+++ b/drivers/staging/bcm/Bcmchar.c
@@ -160,7 +160,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
struct bcm_mini_adapter *Adapter = pTarang->Adapter;
INT Status = STATUS_FAILURE;
int timeout = 0;
- IOCTL_BUFFER IoBuffer;
+ struct bcm_ioctl_buffer IoBuffer;
int bytes;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg);
@@ -203,13 +203,13 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
switch (cmd) {
/* Rdms for Swin Idle... */
case IOCTL_BCM_REGISTER_READ_PRIVATE: {
- RDM_BUFFER sRdmBuffer = {0};
+ struct bcm_rdm_buffer sRdmBuffer = {0};
PCHAR temp_buff;
UINT Bufflen;
u16 temp_value;
/* Copy Ioctl Buffer structure */
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(sRdmBuffer))
@@ -248,11 +248,11 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
}
case IOCTL_BCM_REGISTER_WRITE_PRIVATE: {
- WRM_BUFFER sWrmBuffer = {0};
+ struct bcm_wrm_buffer sWrmBuffer = {0};
UINT uiTempVar = 0;
/* Copy Ioctl Buffer structure */
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(sWrmBuffer))
@@ -287,7 +287,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
case IOCTL_BCM_REGISTER_READ:
case IOCTL_BCM_EEPROM_REGISTER_READ: {
- RDM_BUFFER sRdmBuffer = {0};
+ struct bcm_rdm_buffer sRdmBuffer = {0};
PCHAR temp_buff = NULL;
UINT uiTempVar = 0;
if ((Adapter->IdleMode == TRUE) ||
@@ -299,7 +299,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
}
/* Copy Ioctl Buffer structure */
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(sRdmBuffer))
@@ -345,8 +345,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
}
case IOCTL_BCM_REGISTER_WRITE:
case IOCTL_BCM_EEPROM_REGISTER_WRITE: {
- WRM_BUFFER sWrmBuffer = {0};
+ struct bcm_wrm_buffer sWrmBuffer = {0};
UINT uiTempVar = 0;
+
if ((Adapter->IdleMode == TRUE) ||
(Adapter->bShutStatus == TRUE) ||
(Adapter->bPreparingForLowPowerMode == TRUE)) {
@@ -356,7 +357,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
}
/* Copy Ioctl Buffer structure */
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(sWrmBuffer))
@@ -401,8 +402,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
UINT value = 0;
UINT uiBit = 0;
UINT uiOperation = 0;
+ struct bcm_gpio_info gpio_info = {0};
- GPIO_INFO gpio_info = {0};
if ((Adapter->IdleMode == TRUE) ||
(Adapter->bShutStatus == TRUE) ||
(Adapter->bPreparingForLowPowerMode == TRUE)) {
@@ -411,7 +412,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
return -EACCES;
}
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(gpio_info))
@@ -478,7 +479,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
break;
case BCM_LED_THREAD_STATE_CHANGE_REQ: {
- USER_THREAD_REQ threadReq = {0};
+ struct bcm_user_thread_req threadReq = {0};
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "User made LED thread InActive");
if ((Adapter->IdleMode == TRUE) ||
@@ -490,7 +491,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
break;
}
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(threadReq))
@@ -518,14 +519,14 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
case IOCTL_BCM_GPIO_STATUS_REQUEST: {
ULONG uiBit = 0;
UCHAR ucRead[4];
- GPIO_INFO gpio_info = {0};
+ struct bcm_gpio_info gpio_info = {0};
if ((Adapter->IdleMode == TRUE) ||
(Adapter->bShutStatus == TRUE) ||
(Adapter->bPreparingForLowPowerMode == TRUE))
return -EACCES;
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(gpio_info))
@@ -552,17 +553,17 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
case IOCTL_BCM_GPIO_MULTI_REQUEST: {
UCHAR ucResetValue[4];
- GPIO_MULTI_INFO gpio_multi_info[MAX_IDX];
- PGPIO_MULTI_INFO pgpio_multi_info = (PGPIO_MULTI_INFO)gpio_multi_info;
+ struct bcm_gpio_multi_info gpio_multi_info[MAX_IDX];
+ struct bcm_gpio_multi_info *pgpio_multi_info = (struct bcm_gpio_multi_info *)gpio_multi_info;
- memset(pgpio_multi_info, 0, MAX_IDX * sizeof(GPIO_MULTI_INFO));
+ memset(pgpio_multi_info, 0, MAX_IDX * sizeof(struct bcm_gpio_multi_info));
if ((Adapter->IdleMode == TRUE) ||
(Adapter->bShutStatus == TRUE) ||
(Adapter->bPreparingForLowPowerMode == TRUE))
return -EINVAL;
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(gpio_multi_info))
@@ -636,15 +637,15 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
case IOCTL_BCM_GPIO_MODE_REQUEST: {
UCHAR ucResetValue[4];
- GPIO_MULTI_MODE gpio_multi_mode[MAX_IDX];
- PGPIO_MULTI_MODE pgpio_multi_mode = (PGPIO_MULTI_MODE)gpio_multi_mode;
+ struct bcm_gpio_multi_mode gpio_multi_mode[MAX_IDX];
+ struct bcm_gpio_multi_mode *pgpio_multi_mode = (struct bcm_gpio_multi_mode *)gpio_multi_mode;
if ((Adapter->IdleMode == TRUE) ||
(Adapter->bShutStatus == TRUE) ||
(Adapter->bPreparingForLowPowerMode == TRUE))
return -EINVAL;
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(gpio_multi_mode))
@@ -719,7 +720,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
PVOID pvBuffer = NULL;
/* Copy Ioctl Buffer structure */
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength < sizeof(struct bcm_link_request))
@@ -799,7 +800,7 @@ cntrlEnd:
}
/* Copy Ioctl Buffer structure */
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) {
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
up(&Adapter->fw_download_sema);
return -EFAULT;
}
@@ -895,7 +896,7 @@ cntrlEnd:
mdelay(10);
/* Wait for MailBox Interrupt */
- if (StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter))
+ if (StartInterruptUrb((struct bcm_interface_adapter *)Adapter->pvInterfaceAdapter))
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n");
timeout = 5*HZ;
@@ -1000,7 +1001,7 @@ cntrlEnd:
ulong len;
/* Copy Ioctl Buffer structure */
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
len = min_t(ulong, IoBuffer.OutputLength, strlen(VER_FILEVERSION_STR) + 1);
@@ -1015,7 +1016,7 @@ cntrlEnd:
LINK_STATE link_state;
/* Copy Ioctl Buffer structure */
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) {
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy_from_user failed..\n");
return -EFAULT;
}
@@ -1042,7 +1043,7 @@ cntrlEnd:
UINT tracing_flag;
/* copy ioctl Buffer structure */
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (copy_from_user(&tracing_flag, IoBuffer.InputBuffer, sizeof(UINT)))
@@ -1057,13 +1058,13 @@ cntrlEnd:
case IOCTL_BCM_GET_DSX_INDICATION: {
ULONG ulSFId = 0;
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
- if (IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt)) {
+ if (IoBuffer.OutputLength < sizeof(struct bcm_add_indication_alt)) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
"Mismatch req: %lx needed is =0x%zx!!!",
- IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt));
+ IoBuffer.OutputLength, sizeof(struct bcm_add_indication_alt));
return -EINVAL;
}
@@ -1079,18 +1080,18 @@ cntrlEnd:
case IOCTL_BCM_GET_HOST_MIBS: {
PVOID temp_buff;
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
- if (IoBuffer.OutputLength != sizeof(S_MIBS_HOST_STATS_MIBS)) {
+ if (IoBuffer.OutputLength != sizeof(struct bcm_host_stats_mibs)) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
"Length Check failed %lu %zd\n",
- IoBuffer.OutputLength, sizeof(S_MIBS_HOST_STATS_MIBS));
+ IoBuffer.OutputLength, sizeof(struct bcm_host_stats_mibs));
return -EINVAL;
}
/* FIXME: HOST_STATS are too big for kmalloc (122048)! */
- temp_buff = kzalloc(sizeof(S_MIBS_HOST_STATS_MIBS), GFP_KERNEL);
+ temp_buff = kzalloc(sizeof(struct bcm_host_stats_mibs), GFP_KERNEL);
if (!temp_buff)
return STATUS_FAILURE;
@@ -1098,7 +1099,7 @@ cntrlEnd:
GetDroppedAppCntrlPktMibs(temp_buff, pTarang);
if (Status != STATUS_FAILURE)
- if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(S_MIBS_HOST_STATS_MIBS))) {
+ if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(struct bcm_host_stats_mibs))) {
kfree(temp_buff);
return -EFAULT;
}
@@ -1118,7 +1119,7 @@ cntrlEnd:
break;
case IOCTL_BCM_BULK_WRM: {
- PBULKWRM_BUFFER pBulkBuffer;
+ struct bcm_bulk_wrm_buffer *pBulkBuffer;
UINT uiTempVar = 0;
PCHAR pvBuffer = NULL;
@@ -1132,7 +1133,7 @@ cntrlEnd:
}
/* Copy Ioctl Buffer structure */
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength < sizeof(ULONG) * 2)
@@ -1143,7 +1144,7 @@ cntrlEnd:
if (IS_ERR(pvBuffer))
return PTR_ERR(pvBuffer);
- pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer;
+ pBulkBuffer = (struct bcm_bulk_wrm_buffer *)pvBuffer;
if (((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 ||
((ULONG)pBulkBuffer->Register & 0x3)) {
@@ -1180,7 +1181,7 @@ cntrlEnd:
}
case IOCTL_BCM_GET_NVM_SIZE:
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH) {
@@ -1194,7 +1195,7 @@ cntrlEnd:
case IOCTL_BCM_CAL_INIT: {
UINT uiSectorSize = 0 ;
if (Adapter->eNVMType == NVM_FLASH) {
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer, sizeof(UINT)))
@@ -1231,7 +1232,7 @@ cntrlEnd:
USER_BCM_DBG_STATE sUserDebugState;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In SET_DEBUG ioctl\n");
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE)))
@@ -1262,7 +1263,7 @@ cntrlEnd:
case IOCTL_BCM_NVM_READ:
case IOCTL_BCM_NVM_WRITE: {
- NVM_READWRITE stNVMReadWrite;
+ struct bcm_nvm_readwrite stNVMReadWrite;
PUCHAR pReadData = NULL;
ULONG ulDSDMagicNumInUsrBuff = 0;
struct timeval tv0, tv1;
@@ -1284,12 +1285,12 @@ cntrlEnd:
}
/* Copy Ioctl Buffer structure */
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (copy_from_user(&stNVMReadWrite,
(IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer,
- sizeof(NVM_READWRITE)))
+ sizeof(struct bcm_nvm_readwrite)))
return -EFAULT;
/*
@@ -1404,7 +1405,7 @@ cntrlEnd:
}
case IOCTL_BCM_FLASH2X_SECTION_READ: {
- FLASH2X_READWRITE sFlash2xRead = {0};
+ struct bcm_flash2x_readwrite sFlash2xRead = {0};
PUCHAR pReadBuff = NULL ;
UINT NOB = 0;
UINT BuffSize = 0;
@@ -1418,11 +1419,11 @@ cntrlEnd:
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called");
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
/* Reading FLASH 2.x READ structure */
- if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE)))
+ if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer, sizeof(struct bcm_flash2x_readwrite)))
return -EFAULT;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.Section :%x", sFlash2xRead.Section);
@@ -1495,7 +1496,7 @@ cntrlEnd:
break;
case IOCTL_BCM_FLASH2X_SECTION_WRITE: {
- FLASH2X_READWRITE sFlash2xWrite = {0};
+ struct bcm_flash2x_readwrite sFlash2xWrite = {0};
PUCHAR pWriteBuff;
void __user *InputAddr;
UINT NOB = 0;
@@ -1513,11 +1514,11 @@ cntrlEnd:
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_WRITE Called");
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
/* Reading FLASH 2.x READ structure */
- if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE)))
+ if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(struct bcm_flash2x_readwrite)))
return -EFAULT;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.Section :%x", sFlash2xWrite.Section);
@@ -1604,16 +1605,16 @@ cntrlEnd:
break;
case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP: {
- PFLASH2X_BITMAP psFlash2xBitMap;
+ struct bcm_flash2x_bitmap *psFlash2xBitMap;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called");
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
- if (IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP))
+ if (IoBuffer.OutputLength != sizeof(struct bcm_flash2x_bitmap))
return -EINVAL;
- psFlash2xBitMap = kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL);
+ psFlash2xBitMap = kzalloc(sizeof(struct bcm_flash2x_bitmap), GFP_KERNEL);
if (psFlash2xBitMap == NULL) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory is not available");
return -ENOMEM;
@@ -1634,7 +1635,7 @@ cntrlEnd:
BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap);
up(&Adapter->NVMRdmWrmLock);
- if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP))) {
+ if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(struct bcm_flash2x_bitmap))) {
kfree(psFlash2xBitMap);
return -EFAULT;
}
@@ -1644,7 +1645,7 @@ cntrlEnd:
break;
case IOCTL_BCM_SET_ACTIVE_SECTION: {
- FLASH2X_SECTION_VAL eFlash2xSectionVal = 0;
+ enum bcm_flash2x_section_val eFlash2xSectionVal = 0;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SET_ACTIVE_SECTION Called");
if (IsFlash2x(Adapter) != TRUE) {
@@ -1652,7 +1653,7 @@ cntrlEnd:
return -EINVAL;
}
- Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
+ Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
return -EFAULT;
@@ -1692,7 +1693,7 @@ cntrlEnd:
break;
case IOCTL_BCM_COPY_SECTION: {
- FLASH2X_COPY_SECTION sCopySectStrut = {0};
+ struct bcm_flash2x_copy_section sCopySectStrut = {0};
Status = STATUS_SUCCESS;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_COPY_SECTION Called");
@@ -1702,13 +1703,13 @@ cntrlEnd:
return -EINVAL;
}
- Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
+ Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status);
return -EFAULT;
}
- Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION));
+ Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(struct bcm_flash2x_copy_section));
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status);
return -EFAULT;
@@ -1769,7 +1770,7 @@ cntrlEnd:
Status = STATUS_SUCCESS;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_GET_FLASH_CS_INFO Called");
- Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
+ Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
return -EFAULT;
@@ -1799,7 +1800,7 @@ cntrlEnd:
case IOCTL_BCM_SELECT_DSD: {
UINT SectOfset = 0;
- FLASH2X_SECTION_VAL eFlash2xSectionVal;
+ enum bcm_flash2x_section_val eFlash2xSectionVal;
eFlash2xSectionVal = NO_SECTION_VAL;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SELECT_DSD Called");
@@ -1808,7 +1809,7 @@ cntrlEnd:
return -EINVAL;
}
- Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
+ Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
return -EFAULT;
@@ -1842,7 +1843,7 @@ cntrlEnd:
break;
case IOCTL_BCM_NVM_RAW_READ: {
- NVM_READWRITE stNVMRead;
+ struct bcm_nvm_readwrite stNVMRead;
INT NOB ;
INT BuffSize ;
INT ReadOffset = 0;
@@ -1856,12 +1857,12 @@ cntrlEnd:
}
/* Copy Ioctl Buffer structure */
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) {
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n");
return -EFAULT;
}
- if (copy_from_user(&stNVMRead, IoBuffer.OutputBuffer, sizeof(NVM_READWRITE)))
+ if (copy_from_user(&stNVMRead, IoBuffer.OutputBuffer, sizeof(struct bcm_nvm_readwrite)))
return -EFAULT;
NOB = stNVMRead.uiNumBytes;
@@ -1933,7 +1934,7 @@ cntrlEnd:
ULONG RxCntrlMsgBitMask = 0;
/* Copy Ioctl Buffer structure */
- Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
+ Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "copy of Ioctl buffer is failed from user space");
return -EFAULT;
@@ -1955,7 +1956,7 @@ cntrlEnd:
break;
case IOCTL_BCM_GET_DEVICE_DRIVER_INFO: {
- DEVICE_DRIVER_INFO DevInfo;
+ struct bcm_driver_info DevInfo;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n");
@@ -1965,7 +1966,7 @@ cntrlEnd:
DevInfo.u32NVMType = Adapter->eNVMType;
DevInfo.u32InterfaceType = BCM_USB;
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.OutputLength < sizeof(DevInfo))
@@ -1977,19 +1978,19 @@ cntrlEnd:
break;
case IOCTL_BCM_TIME_SINCE_NET_ENTRY: {
- ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0};
+ struct bcm_time_elapsed stTimeElapsedSinceNetEntry = {0};
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_TIME_SINCE_NET_ENTRY called");
- if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
- if (IoBuffer.OutputLength < sizeof(ST_TIME_ELAPSED))
+ if (IoBuffer.OutputLength < sizeof(struct bcm_time_elapsed))
return -EINVAL;
stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = get_seconds() - Adapter->liTimeSinceLastNetEntry;
- if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED)))
+ if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(struct bcm_time_elapsed)))
return -EFAULT;
}
break;
diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c
index 6e8c7f52321..a3b91c7ee8f 100644
--- a/drivers/staging/bcm/Bcmnet.c
+++ b/drivers/staging/bcm/Bcmnet.c
@@ -142,7 +142,7 @@ static void bcm_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
- PS_INTERFACE_ADAPTER psIntfAdapter = Adapter->pvInterfaceAdapter;
+ struct bcm_interface_adapter *psIntfAdapter = Adapter->pvInterfaceAdapter;
struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface);
strcpy(info->driver, DRV_NAME);
@@ -186,7 +186,7 @@ static const struct ethtool_ops bcm_ethtool_ops = {
int register_networkdev(struct bcm_mini_adapter *Adapter)
{
struct net_device *net = Adapter->dev;
- PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter;
+ struct bcm_interface_adapter *IntfAdapter = Adapter->pvInterfaceAdapter;
struct usb_interface *udev = IntfAdapter->interface;
struct usb_device *xdev = IntfAdapter->udev;
@@ -227,7 +227,7 @@ int register_networkdev(struct bcm_mini_adapter *Adapter)
void unregister_networkdev(struct bcm_mini_adapter *Adapter)
{
struct net_device *net = Adapter->dev;
- PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter;
+ struct bcm_interface_adapter *IntfAdapter = Adapter->pvInterfaceAdapter;
struct usb_interface *udev = IntfAdapter->interface;
struct usb_device *xdev = IntfAdapter->udev;
diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c
index 325b592fd41..23ddc3d7c9e 100644
--- a/drivers/staging/bcm/CmHost.c
+++ b/drivers/staging/bcm/CmHost.c
@@ -107,7 +107,7 @@ static VOID deleteSFBySfid(struct bcm_mini_adapter *Adapter, UINT uiSearchRuleIn
DeleteAllClassifiersForSF(Adapter, uiSearchRuleIndex);
/* Resetting only MIBS related entries in the SF */
- memset((PVOID)&Adapter->PackInfo[uiSearchRuleIndex], 0, sizeof(S_MIBS_SERVICEFLOW_TABLE));
+ memset((PVOID)&Adapter->PackInfo[uiSearchRuleIndex], 0, sizeof(struct bcm_mibs_table));
}
static inline VOID
@@ -431,7 +431,7 @@ static VOID CopyToAdapter(register struct bcm_mini_adapter *Adapter, /* <Pointer
register struct bcm_connect_mgr_params *psfLocalSet, /* Pointer to the connection manager parameters structure */
register UINT uiSearchRuleIndex, /* <Index of Queue, to which this data belongs */
register UCHAR ucDsxType,
- stLocalSFAddIndicationAlt *pstAddIndication) {
+ struct bcm_add_indication_alt *pstAddIndication) {
/* UCHAR ucProtocolLength = 0; */
ULONG ulSFID;
@@ -833,11 +833,11 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
{
int uiLoopIndex;
int nIndex;
- stLocalSFAddIndicationAlt *pstAddIndication;
+ struct bcm_add_indication_alt *pstAddIndication;
UINT nCurClassifierCnt;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- pstAddIndication = (stLocalSFAddIndicationAlt *)pvBuffer;
+ pstAddIndication = (struct bcm_add_indication_alt *)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);
@@ -1333,13 +1333,13 @@ static ULONG StoreSFParam(struct bcm_mini_adapter *Adapter, PUCHAR pucSrcBuffer,
ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, UINT *puBufferLength)
{
- stLocalSFAddIndicationAlt *pstAddIndicationAlt = NULL;
+ struct bcm_add_indication_alt *pstAddIndicationAlt = NULL;
struct bcm_add_indication *pstAddIndication = NULL;
struct bcm_del_request *pstDeletionRequest;
UINT uiSearchRuleIndex;
ULONG ulSFID;
- pstAddIndicationAlt = (stLocalSFAddIndicationAlt *)(pvBuffer);
+ pstAddIndicationAlt = (struct bcm_add_indication_alt *)(pvBuffer);
/*
* In case of DSD Req By MS, we should immediately delete this SF so that
@@ -1445,29 +1445,29 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu
return 1;
}
-static inline stLocalSFAddIndicationAlt
+static inline struct bcm_add_indication_alt
*RestoreCmControlResponseMessage(register struct bcm_mini_adapter *Adapter, register PVOID pvBuffer)
{
ULONG ulStatus = 0;
struct bcm_add_indication *pstAddIndication = NULL;
- stLocalSFAddIndicationAlt *pstAddIndicationDest = NULL;
+ struct bcm_add_indication_alt *pstAddIndicationDest = NULL;
pstAddIndication = (struct bcm_add_indication *)(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 (stLocalSFAddIndicationAlt *)pvBuffer;
+ return (struct bcm_add_indication_alt *)pvBuffer;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Inside RestoreCmControlResponseMessage ");
/*
* Need to Allocate memory to contain the SUPER Large structures
* Our driver can't create these structures on Stack :(
*/
- pstAddIndicationDest = kmalloc(sizeof(stLocalSFAddIndicationAlt), GFP_KERNEL);
+ pstAddIndicationDest = kmalloc(sizeof(struct bcm_add_indication_alt), GFP_KERNEL);
if (pstAddIndicationDest) {
- memset(pstAddIndicationDest, 0, sizeof(stLocalSFAddIndicationAlt));
+ memset(pstAddIndicationDest, 0, sizeof(struct bcm_add_indication_alt));
} else {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Failed to allocate memory for SF Add Indication Structure ");
return NULL;
@@ -1573,36 +1573,36 @@ ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter)
static ULONG GetNextTargetBufferLocation(struct bcm_mini_adapter *Adapter, B_UINT16 tid)
{
- ULONG ulTargetDSXBufferAddress;
- ULONG ulTargetDsxBufferIndexToUse, ulMaxTry;
+ ULONG dsx_buf;
+ ULONG idx, max_try;
if ((Adapter->ulTotalTargetBuffersAvailable == 0) || (Adapter->ulFreeTargetBufferCnt == 0)) {
ClearTargetDSXBuffer(Adapter, tid, FALSE);
return 0;
}
- ulTargetDsxBufferIndexToUse = Adapter->ulCurrentTargetBuffer;
- ulMaxTry = Adapter->ulTotalTargetBuffersAvailable;
- while ((ulMaxTry) && (Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid != 1)) {
- ulTargetDsxBufferIndexToUse = (ulTargetDsxBufferIndexToUse+1) % Adapter->ulTotalTargetBuffersAvailable;
- ulMaxTry--;
+ idx = Adapter->ulCurrentTargetBuffer;
+ max_try = Adapter->ulTotalTargetBuffersAvailable;
+ while ((max_try) && (Adapter->astTargetDsxBuffer[idx].valid != 1)) {
+ idx = (idx+1) % Adapter->ulTotalTargetBuffersAvailable;
+ max_try--;
}
- if (ulMaxTry == 0) {
+ 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);
return 0;
}
- ulTargetDSXBufferAddress = Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].ulTargetDsxBuffer;
- Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid = 0;
- Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].tid = tid;
+ dsx_buf = Adapter->astTargetDsxBuffer[idx].ulTargetDsxBuffer;
+ Adapter->astTargetDsxBuffer[idx].valid = 0;
+ Adapter->astTargetDsxBuffer[idx].tid = tid;
Adapter->ulFreeTargetBufferCnt--;
- ulTargetDsxBufferIndexToUse = (ulTargetDsxBufferIndexToUse+1)%Adapter->ulTotalTargetBuffersAvailable;
- Adapter->ulCurrentTargetBuffer = ulTargetDsxBufferIndexToUse;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GetNextTargetBufferLocation :Returning address %lx tid %d\n", ulTargetDSXBufferAddress, tid);
+ idx = (idx+1)%Adapter->ulTotalTargetBuffersAvailable;
+ Adapter->ulCurrentTargetBuffer = idx;
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GetNextTargetBufferLocation :Returning address %lx tid %d\n", dsx_buf, tid);
- return ulTargetDSXBufferAddress;
+ return dsx_buf;
}
int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter)
@@ -1611,7 +1611,7 @@ int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter)
* Need to Allocate memory to contain the SUPER Large structures
* Our driver can't create these structures on Stack
*/
- Adapter->caDsxReqResp = kmalloc(sizeof(stLocalSFAddIndicationAlt)+LEADER_SIZE, GFP_KERNEL);
+ Adapter->caDsxReqResp = kmalloc(sizeof(struct bcm_add_indication_alt)+LEADER_SIZE, GFP_KERNEL);
if (!Adapter->caDsxReqResp)
return -ENOMEM;
@@ -1634,8 +1634,8 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer
PVOID pvBuffer /* Starting Address of the Buffer, that contains the AddIndication Data */)
{
struct bcm_connect_mgr_params *psfLocalSet = NULL;
- stLocalSFAddIndicationAlt *pstAddIndication = NULL;
- stLocalSFChangeIndicationAlt *pstChangeIndication = NULL;
+ struct bcm_add_indication_alt *pstAddIndication = NULL;
+ struct bcm_change_indication *pstChangeIndication = NULL;
struct bcm_leader *pLeader = NULL;
/*
@@ -1661,12 +1661,12 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer
switch (pstAddIndication->u8Type) {
case DSA_REQ:
{
- pLeader->PLength = sizeof(stLocalSFAddIndicationAlt);
+ pLeader->PLength = sizeof(struct bcm_add_indication_alt);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Sending DSA Response....\n");
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA RESPONSE TO MAC %d", pLeader->PLength);
- *((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))
+ *((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))
= *pstAddIndication;
- ((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_RSP;
+ ((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_RSP;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " VCID = %x", ntohs(pstAddIndication->u16VCID));
CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp);
@@ -1675,12 +1675,12 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer
break;
case DSA_RSP:
{
- pLeader->PLength = sizeof(stLocalSFAddIndicationAlt);
+ pLeader->PLength = sizeof(struct bcm_add_indication_alt);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA ACK TO MAC %d",
pLeader->PLength);
- *((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))
+ *((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))
= *pstAddIndication;
- ((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK;
+ ((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK;
} /* no break here..we should go down. */
case DSA_ACK:
@@ -1773,12 +1773,12 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer
break;
case DSC_REQ:
{
- pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt);
- pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication;
+ pLeader->PLength = sizeof(struct bcm_change_indication);
+ pstChangeIndication = (struct bcm_change_indication *)pstAddIndication;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC RESPONSE TO MAC %d", pLeader->PLength);
- *((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
- ((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP;
+ *((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
+ ((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP;
CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp);
kfree(pstAddIndication);
@@ -1786,17 +1786,17 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer
break;
case DSC_RSP:
{
- pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt);
- pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication;
+ pLeader->PLength = sizeof(struct bcm_change_indication);
+ pstChangeIndication = (struct bcm_change_indication *)pstAddIndication;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC ACK TO MAC %d", pLeader->PLength);
- *((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
- ((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK;
+ *((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
+ ((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK;
}
case DSC_ACK:
{
UINT uiSearchRuleIndex = 0;
- pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication;
+ pstChangeIndication = (struct bcm_change_indication *)pstAddIndication;
uiSearchRuleIndex = SearchSfid(Adapter, ntohl(pstChangeIndication->sfActiveSet.u32SFID));
if (uiSearchRuleIndex > NO_OF_QUEUES-1)
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "SF doesn't exist for which DSC_ACK is received");
@@ -1902,7 +1902,7 @@ int get_dsx_sf_data_to_application(struct bcm_mini_adapter *Adapter, UINT uiSFId
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "status =%d", status);
psSfInfo = &Adapter->PackInfo[status];
if (psSfInfo->pstSFIndication && copy_to_user(user_buffer,
- psSfInfo->pstSFIndication, sizeof(stLocalSFAddIndicationAlt))) {
+ psSfInfo->pstSFIndication, sizeof(struct bcm_add_indication_alt))) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy to user failed SFID %d, present in queue !!!", uiSFId);
status = -EFAULT;
return status;
diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h
index 1c5a07c7bbe..eecad8d90ae 100644
--- a/drivers/staging/bcm/CmHost.h
+++ b/drivers/staging/bcm/CmHost.h
@@ -1,147 +1,66 @@
-/// **************************************************************************
-/// (c) Beceem Communications Inc.
-/// All Rights Reserved
-///
-/// \file : CmHost.h
-/// \author : Rajeev Tirumala
-/// \date : September 8 , 2006
-/// \brief : Definitions for Connection Management Requests structure
-/// which we will use to setup our connection structures.Its high
-/// time we had a header file for CmHost.cpp to isolate the way
-/// f/w sends DSx messages and the way we interpret them in code.
-/// Revision History
-///
-/// Date Author Version Description
-/// 08-Sep-06 Rajeev 0.1 Created
-/// **************************************************************************
+/***************************************************************************
+ * (c) Beceem Communications Inc.
+ * All Rights Reserved
+ *
+ * file : CmHost.h
+ * author: Rajeev Tirumala
+ * date : September 8 , 2006
+ * brief : Definitions for Connection Management Requests structure
+ * which we will use to setup our connection structures.Its high
+ * time we had a header file for CmHost.cpp to isolate the way
+ * f/w sends DSx messages and the way we interpret them in code.
+ * Revision History
+ *
+ * Date Author Version Description
+ * 08-Sep-06 Rajeev 0.1 Created
+ ***************************************************************************/
#ifndef _CM_HOST_H
#define _CM_HOST_H
#pragma once
-#pragma pack (push,4)
-
-#define DSX_MESSAGE_EXCHANGE_BUFFER 0xBF60AC84 // This contains the pointer
-#define DSX_MESSAGE_EXCHANGE_BUFFER_SIZE 72000 // 24 K Bytes
-
-/// \brief structure stLocalSFAddRequest
-typedef struct stLocalSFAddRequestAlt{
- B_UINT8 u8Type;
- B_UINT8 u8Direction;
-
- B_UINT16 u16TID;
- /// \brief 16bitCID
- B_UINT16 u16CID;
- /// \brief 16bitVCID
- B_UINT16 u16VCID;
-
-
- struct bcm_connect_mgr_params sfParameterSet;
-
- //USE_MEMORY_MANAGER();
-}stLocalSFAddRequestAlt;
-
-/// \brief structure stLocalSFAddIndication
-typedef struct stLocalSFAddIndicationAlt{
- B_UINT8 u8Type;
- B_UINT8 u8Direction;
- B_UINT16 u16TID;
- /// \brief 16bitCID
- B_UINT16 u16CID;
- /// \brief 16bitVCID
- B_UINT16 u16VCID;
+#pragma pack(push, 4)
+
+#define DSX_MESSAGE_EXCHANGE_BUFFER 0xBF60AC84 /* This contains the pointer */
+#define DSX_MESSAGE_EXCHANGE_BUFFER_SIZE 72000 /* 24 K Bytes */
+
+struct bcm_add_indication_alt {
+ u8 u8Type;
+ u8 u8Direction;
+ u16 u16TID;
+ /* brief 16bitCID */
+ u16 u16CID;
+ /* brief 16bitVCID */
+ u16 u16VCID;
struct bcm_connect_mgr_params sfAuthorizedSet;
struct bcm_connect_mgr_params sfAdmittedSet;
struct bcm_connect_mgr_params sfActiveSet;
-
- B_UINT8 u8CC; /**< Confirmation Code*/
- B_UINT8 u8Padd; /**< 8-bit Padding */
- B_UINT16 u16Padd; /**< 16 bit Padding */
-// USE_MEMORY_MANAGER();
-}stLocalSFAddIndicationAlt;
-
-/// \brief structure stLocalSFAddConfirmation
-typedef struct stLocalSFAddConfirmationAlt{
- B_UINT8 u8Type;
- B_UINT8 u8Direction;
- B_UINT16 u16TID;
- /// \brief 16bitCID
- B_UINT16 u16CID;
- /// \brief 16bitVCID
- B_UINT16 u16VCID;
+ u8 u8CC; /* < Confirmation Code */
+ u8 u8Padd; /* < 8-bit Padding */
+ u16 u16Padd; /* < 16 bit Padding */
+};
+
+struct bcm_change_indication {
+ u8 u8Type;
+ u8 u8Direction;
+ u16 u16TID;
+ /* brief 16bitCID */
+ u16 u16CID;
+ /* brief 16bitVCID */
+ u16 u16VCID;
struct bcm_connect_mgr_params sfAuthorizedSet;
struct bcm_connect_mgr_params sfAdmittedSet;
struct bcm_connect_mgr_params sfActiveSet;
-}stLocalSFAddConfirmationAlt;
-
-
-/// \brief structure stLocalSFChangeRequest
-typedef struct stLocalSFChangeRequestAlt{
- B_UINT8 u8Type;
- B_UINT8 u8Direction;
- B_UINT16 u16TID;
- /// \brief 16bitCID
- B_UINT16 u16CID;
- /// \brief 16bitVCID
- B_UINT16 u16VCID;
- /*
- //Pointer location at which following connection manager param Structure can be read
- //from the target. We only get the address location and we need to read out the
- //entire connection manager param structure at the given location on target
- */
- struct bcm_connect_mgr_params sfAuthorizedSet;
- struct bcm_connect_mgr_params sfAdmittedSet;
- struct bcm_connect_mgr_params sfActiveSet;
-
- B_UINT8 u8CC; /**< Confirmation Code*/
- B_UINT8 u8Padd; /**< 8-bit Padding */
- B_UINT16 u16Padd; /**< 16 bit */
-
-}stLocalSFChangeRequestAlt;
-
-/// \brief structure stLocalSFChangeConfirmation
-typedef struct stLocalSFChangeConfirmationAlt{
- B_UINT8 u8Type;
- B_UINT8 u8Direction;
- B_UINT16 u16TID;
- /// \brief 16bitCID
- B_UINT16 u16CID;
- /// \brief 16bitVCID
- B_UINT16 u16VCID;
- struct bcm_connect_mgr_params sfAuthorizedSet;
- struct bcm_connect_mgr_params sfAdmittedSet;
- struct bcm_connect_mgr_params sfActiveSet;
-
-}stLocalSFChangeConfirmationAlt;
-
-/// \brief structure stLocalSFChangeIndication
-typedef struct stLocalSFChangeIndicationAlt{
- B_UINT8 u8Type;
- B_UINT8 u8Direction;
- B_UINT16 u16TID;
- /// \brief 16bitCID
- B_UINT16 u16CID;
- /// \brief 16bitVCID
- B_UINT16 u16VCID;
- struct bcm_connect_mgr_params sfAuthorizedSet;
- struct bcm_connect_mgr_params sfAdmittedSet;
- struct bcm_connect_mgr_params sfActiveSet;
-
- B_UINT8 u8CC; /**< Confirmation Code*/
- B_UINT8 u8Padd; /**< 8-bit Padding */
- B_UINT16 u16Padd; /**< 16 bit */
-
-}stLocalSFChangeIndicationAlt;
-
-ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer,UINT *puBufferLength);
-
-INT AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter);
-
-INT FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter);
-ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter);
-
-BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer);
-
-
-#pragma pack (pop)
+ u8 u8CC; /* < Confirmation Code */
+ u8 u8Padd; /* < 8-bit Padding */
+ u16 u16Padd; /* < 16 bit */
+};
+
+unsigned long StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, void *pvBuffer, unsigned int *puBufferLength);
+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);
+
+#pragma pack(pop)
#endif
diff --git a/drivers/staging/bcm/HandleControlPacket.c b/drivers/staging/bcm/HandleControlPacket.c
index 25e5c68bfe8..1bb53e247a6 100644
--- a/drivers/staging/bcm/HandleControlPacket.c
+++ b/drivers/staging/bcm/HandleControlPacket.c
@@ -226,7 +226,7 @@ INT flushAllAppQ(void)
pTarang->AppCtrlQueueLen = 0;
/* dropped contrl packet statistics also should be reset. */
memset((PVOID)&pTarang->stDroppedAppCntrlMsgs, 0,
- sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
+ sizeof(struct bcm_mibs_dropped_cntrl_msg));
}
return STATUS_SUCCESS;
diff --git a/drivers/staging/bcm/HostMIBSInterface.h b/drivers/staging/bcm/HostMIBSInterface.h
index e34531b638e..f922ac49b70 100644
--- a/drivers/staging/bcm/HostMIBSInterface.h
+++ b/drivers/staging/bcm/HostMIBSInterface.h
@@ -1,5 +1,3 @@
-
-
#ifndef _HOST_MIBSINTERFACE_H
#define _HOST_MIBSINTERFACE_H
@@ -10,221 +8,185 @@
* statistics used for the MIBS.
*/
-#define MIBS_MAX_CLASSIFIERS 100
-#define MIBS_MAX_PHSRULES 100
-#define MIBS_MAX_SERVICEFLOWS 17
-#define MIBS_MAX_IP_RANGE_LENGTH 4
-#define MIBS_MAX_PORT_RANGE 4
-#define MIBS_MAX_PROTOCOL_LENGTH 32
-#define MIBS_MAX_PHS_LENGTHS 255
-#define MIBS_IPV6_ADDRESS_SIZEINBYTES 0x10
+#define MIBS_MAX_CLASSIFIERS 100
+#define MIBS_MAX_PHSRULES 100
+#define MIBS_MAX_SERVICEFLOWS 17
+#define MIBS_MAX_IP_RANGE_LENGTH 4
+#define MIBS_MAX_PORT_RANGE 4
+#define MIBS_MAX_PROTOCOL_LENGTH 32
+#define MIBS_MAX_PHS_LENGTHS 255
+#define MIBS_IPV6_ADDRESS_SIZEINBYTES 0x10
#define MIBS_IP_LENGTH_OF_ADDRESS 4
-#define MIBS_MAX_HIST_ENTRIES 12
-#define MIBS_PKTSIZEHIST_RANGE 128
-
-typedef union _U_MIBS_IP_ADDRESS
-{
- struct
- {
- //Source Ip Address Range
- ULONG ulIpv4Addr[MIBS_MAX_IP_RANGE_LENGTH];
- //Source Ip Mask Address Range
- ULONG ulIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH];
+#define MIBS_MAX_HIST_ENTRIES 12
+#define MIBS_PKTSIZEHIST_RANGE 128
+
+union bcm_mibs_ip_addr {
+ struct {
+ /* Source Ip Address Range */
+ unsigned long ulIpv4Addr[MIBS_MAX_IP_RANGE_LENGTH];
+ /* Source Ip Mask Address Range */
+ unsigned long ulIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH];
};
- struct
- {
- //Source Ip Address Range
- ULONG ulIpv6Addr[MIBS_MAX_IP_RANGE_LENGTH * 4];
- //Source Ip Mask Address Range
- ULONG ulIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * 4];
-
+ struct {
+ /* Source Ip Address Range */
+ unsigned long ulIpv6Addr[MIBS_MAX_IP_RANGE_LENGTH * 4];
+ /* Source Ip Mask Address Range */
+ unsigned long ulIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * 4];
};
- struct
- {
- UCHAR ucIpv4Address[MIBS_MAX_IP_RANGE_LENGTH *
- MIBS_IP_LENGTH_OF_ADDRESS];
- UCHAR ucIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH *
- MIBS_IP_LENGTH_OF_ADDRESS];
+ struct {
+ unsigned char ucIpv4Address[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IP_LENGTH_OF_ADDRESS];
+ unsigned char ucIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IP_LENGTH_OF_ADDRESS];
};
- struct
- {
- UCHAR ucIpv6Address[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES];
- UCHAR ucIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES];
+ struct {
+ unsigned char ucIpv6Address[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES];
+ unsigned char ucIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES];
};
-}U_MIBS_IP_ADDRESS;
-
-
-typedef struct _S_MIBS_HOST_INFO
-{
- ULONG64 GoodTransmits;
- ULONG64 GoodReceives;
- // this to keep track of the Tx and Rx MailBox Registers.
- ULONG NumDesUsed;
- ULONG CurrNumFreeDesc;
- ULONG PrevNumFreeDesc;
- // to keep track the no of byte received
- ULONG PrevNumRcevBytes;
- ULONG CurrNumRcevBytes;
-
+};
+
+struct bcm_mibs_host_info {
+ u64 GoodTransmits;
+ u64 GoodReceives;
+ /* this to keep track of the Tx and Rx MailBox Registers. */
+ unsigned long NumDesUsed;
+ unsigned long CurrNumFreeDesc;
+ unsigned long PrevNumFreeDesc;
+ /* to keep track the no of byte received */
+ unsigned long PrevNumRcevBytes;
+ unsigned long CurrNumRcevBytes;
/* QOS Related */
- ULONG BEBucketSize;
- ULONG rtPSBucketSize;
- ULONG LastTxQueueIndex;
- BOOLEAN TxOutofDescriptors;
- BOOLEAN TimerActive;
- UINT32 u32TotalDSD;
- UINT32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
- UINT32 aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
-}S_MIBS_HOST_INFO;
-
-typedef struct _S_MIBS_CLASSIFIER_RULE
-{
- ULONG ulSFID;
- UCHAR ucReserved[2];
- B_UINT16 uiClassifierRuleIndex;
- BOOLEAN bUsed;
- USHORT usVCID_Value;
- // This field detemines the Classifier Priority
- B_UINT8 u8ClassifierRulePriority;
- U_MIBS_IP_ADDRESS stSrcIpAddress;
- /*IP Source Address Length*/
- UCHAR ucIPSourceAddressLength;
-
- U_MIBS_IP_ADDRESS stDestIpAddress;
+ unsigned long BEBucketSize;
+ unsigned long rtPSBucketSize;
+ unsigned long LastTxQueueIndex;
+ bool TxOutofDescriptors;
+ bool TimerActive;
+ u32 u32TotalDSD;
+ u32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
+ u32 aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
+};
+
+struct bcm_mibs_classifier_rule {
+ unsigned long ulSFID;
+ unsigned char ucReserved[2];
+ u16 uiClassifierRuleIndex;
+ bool bUsed;
+ unsigned short usVCID_Value;
+ u8 u8ClassifierRulePriority;
+ union bcm_mibs_ip_addr stSrcIpAddress;
+ /* IP Source Address Length */
+ unsigned char ucIPSourceAddressLength;
+ union bcm_mibs_ip_addr stDestIpAddress;
/* IP Destination Address Length */
- UCHAR ucIPDestinationAddressLength;
- UCHAR ucIPTypeOfServiceLength;//Type of service Length
- UCHAR ucTosLow;//Tos Low
- UCHAR ucTosHigh;//Tos High
- UCHAR ucTosMask;//Tos Mask
- UCHAR ucProtocolLength;//protocol Length
- UCHAR ucProtocol[MIBS_MAX_PROTOCOL_LENGTH];//protocol Length
- USHORT usSrcPortRangeLo[MIBS_MAX_PORT_RANGE];
- USHORT usSrcPortRangeHi[MIBS_MAX_PORT_RANGE];
- UCHAR ucSrcPortRangeLength;
- USHORT usDestPortRangeLo[MIBS_MAX_PORT_RANGE];
- USHORT usDestPortRangeHi[MIBS_MAX_PORT_RANGE];
- UCHAR ucDestPortRangeLength;
- BOOLEAN bProtocolValid;
- BOOLEAN bTOSValid;
- BOOLEAN bDestIpValid;
- BOOLEAN bSrcIpValid;
- UCHAR ucDirection;
- BOOLEAN bIpv6Protocol;
- UINT32 u32PHSRuleID;
-}S_MIBS_CLASSIFIER_RULE;
-
-
-typedef struct _S_MIBS_PHS_RULE
-{
- ULONG ulSFID;
- /// brief 8bit PHSI Of The Service Flow
- B_UINT8 u8PHSI;
- /// brief PHSF Of The Service Flow
- B_UINT8 u8PHSFLength;
- B_UINT8 u8PHSF[MIBS_MAX_PHS_LENGTHS];
- /// brief PHSM Of The Service Flow
- B_UINT8 u8PHSMLength;
- B_UINT8 u8PHSM[MIBS_MAX_PHS_LENGTHS];
- /// brief 8bit PHSS Of The Service Flow
- B_UINT8 u8PHSS;
- /// brief 8bit PHSV Of The Service Flow
- B_UINT8 u8PHSV;
- // Reserved bytes are 5, so that it is similar to S_PHS_RULE structure.
- B_UINT8 reserved[5];
+ unsigned char ucIPDestinationAddressLength;
+ unsigned char ucIPTypeOfServiceLength;
+ unsigned char ucTosLow;
+ unsigned char ucTosHigh;
+ unsigned char ucTosMask;
+ unsigned char ucProtocolLength;
+ unsigned char ucProtocol[MIBS_MAX_PROTOCOL_LENGTH];
+ unsigned short usSrcPortRangeLo[MIBS_MAX_PORT_RANGE];
+ unsigned short usSrcPortRangeHi[MIBS_MAX_PORT_RANGE];
+ unsigned char ucSrcPortRangeLength;
+ unsigned short usDestPortRangeLo[MIBS_MAX_PORT_RANGE];
+ unsigned short usDestPortRangeHi[MIBS_MAX_PORT_RANGE];
+ unsigned char ucDestPortRangeLength;
+ bool bProtocolValid;
+ bool bTOSValid;
+ bool bDestIpValid;
+ bool bSrcIpValid;
+ unsigned char ucDirection;
+ bool bIpv6Protocol;
+ u32 u32PHSRuleID;
+};
+
+struct bcm_mibs_phs_rule {
+ unsigned long ulSFID;
+ u8 u8PHSI;
+ u8 u8PHSFLength;
+ u8 u8PHSF[MIBS_MAX_PHS_LENGTHS];
+ u8 u8PHSMLength;
+ u8 u8PHSM[MIBS_MAX_PHS_LENGTHS];
+ u8 u8PHSS;
+ u8 u8PHSV;
+ u8 reserved[5];
+ long PHSModifiedBytes;
+ unsigned long PHSModifiedNumPackets;
+ unsigned long PHSErrorNumPackets;
+};
+
+struct bcm_mibs_parameters {
+ u32 wmanIfSfid;
+ u32 wmanIfCmnCpsSfState;
+ u32 wmanIfCmnCpsMaxSustainedRate;
+ u32 wmanIfCmnCpsMaxTrafficBurst;
+ u32 wmanIfCmnCpsMinReservedRate;
+ u32 wmanIfCmnCpsToleratedJitter;
+ u32 wmanIfCmnCpsMaxLatency;
+ u32 wmanIfCmnCpsFixedVsVariableSduInd;
+ u32 wmanIfCmnCpsSduSize;
+ u32 wmanIfCmnCpsSfSchedulingType;
+ u32 wmanIfCmnCpsArqEnable;
+ u32 wmanIfCmnCpsArqWindowSize;
+ u32 wmanIfCmnCpsArqBlockLifetime;
+ u32 wmanIfCmnCpsArqSyncLossTimeout;
+ u32 wmanIfCmnCpsArqDeliverInOrder;
+ u32 wmanIfCmnCpsArqRxPurgeTimeout;
+ u32 wmanIfCmnCpsArqBlockSize;
+ u32 wmanIfCmnCpsMinRsvdTolerableRate;
+ u32 wmanIfCmnCpsReqTxPolicy;
+ u32 wmanIfCmnSfCsSpecification;
+ u32 wmanIfCmnCpsTargetSaid;
+};
+
+struct bcm_mibs_table {
+ unsigned long ulSFID;
+ unsigned short usVCID_Value;
+ unsigned int uiThreshold;
+ u8 u8TrafficPriority;
+ bool bValid;
+ bool bActive;
+ bool bActivateRequestSent;
+ u8 u8QueueType;
+ unsigned int uiMaxBucketSize;
+ unsigned int uiCurrentQueueDepthOnTarget;
+ unsigned int uiCurrentBytesOnHost;
+ unsigned int uiCurrentPacketsOnHost;
+ unsigned int uiDroppedCountBytes;
+ unsigned int uiDroppedCountPackets;
+ unsigned int uiSentBytes;
+ unsigned int uiSentPackets;
+ unsigned int uiCurrentDrainRate;
+ unsigned int uiThisPeriodSentBytes;
+ u64 liDrainCalculated;
+ unsigned int uiCurrentTokenCount;
+ u64 liLastUpdateTokenAt;
+ unsigned int uiMaxAllowedRate;
+ unsigned int NumOfPacketsSent;
+ unsigned char ucDirection;
+ unsigned short usCID;
+ struct bcm_mibs_parameters stMibsExtServiceFlowTable;
+ unsigned int uiCurrentRxRate;
+ unsigned int uiThisPeriodRxBytes;
+ unsigned int uiTotalRxBytes;
+ unsigned int uiTotalTxBytes;
+};
+
+struct bcm_mibs_dropped_cntrl_msg {
+ unsigned long cm_responses;
+ unsigned long cm_control_newdsx_multiclassifier_resp;
+ unsigned long link_control_resp;
+ unsigned long status_rsp;
+ unsigned long stats_pointer_resp;
+ unsigned long idle_mode_status;
+ unsigned long auth_ss_host_msg;
+ unsigned long low_priority_message;
+};
+
+struct bcm_host_stats_mibs {
+ struct bcm_mibs_host_info stHostInfo;
+ struct bcm_mibs_classifier_rule astClassifierTable[MIBS_MAX_CLASSIFIERS];
+ struct bcm_mibs_table astSFtable[MIBS_MAX_SERVICEFLOWS];
+ struct bcm_mibs_phs_rule astPhsRulesTable[MIBS_MAX_PHSRULES];
+ struct bcm_mibs_dropped_cntrl_msg stDroppedAppCntrlMsgs;
+};
- LONG PHSModifiedBytes;
- ULONG PHSModifiedNumPackets;
- ULONG PHSErrorNumPackets;
-}S_MIBS_PHS_RULE;
-
-typedef struct _S_MIBS_EXTSERVICEFLOW_PARAMETERS
-{
- UINT32 wmanIfSfid;
- UINT32 wmanIfCmnCpsSfState;
- UINT32 wmanIfCmnCpsMaxSustainedRate;
- UINT32 wmanIfCmnCpsMaxTrafficBurst;
- UINT32 wmanIfCmnCpsMinReservedRate;
- UINT32 wmanIfCmnCpsToleratedJitter;
- UINT32 wmanIfCmnCpsMaxLatency;
- UINT32 wmanIfCmnCpsFixedVsVariableSduInd;
- UINT32 wmanIfCmnCpsSduSize;
- UINT32 wmanIfCmnCpsSfSchedulingType;
- UINT32 wmanIfCmnCpsArqEnable;
- UINT32 wmanIfCmnCpsArqWindowSize;
- UINT32 wmanIfCmnCpsArqBlockLifetime;
- UINT32 wmanIfCmnCpsArqSyncLossTimeout;
- UINT32 wmanIfCmnCpsArqDeliverInOrder;
- UINT32 wmanIfCmnCpsArqRxPurgeTimeout;
- UINT32 wmanIfCmnCpsArqBlockSize;
- UINT32 wmanIfCmnCpsMinRsvdTolerableRate;
- UINT32 wmanIfCmnCpsReqTxPolicy;
- UINT32 wmanIfCmnSfCsSpecification;
- UINT32 wmanIfCmnCpsTargetSaid;
-
-}S_MIBS_EXTSERVICEFLOW_PARAMETERS;
-
-
-typedef struct _S_MIBS_SERVICEFLOW_TABLE
-{
- //classification extension Rule
- ULONG ulSFID;
- USHORT usVCID_Value;
- UINT uiThreshold;
- // This field determines the priority of the SF Queues
- B_UINT8 u8TrafficPriority;
-
- BOOLEAN bValid;
- BOOLEAN bActive;
- BOOLEAN bActivateRequestSent;
- //BE or rtPS
- B_UINT8 u8QueueType;
- //maximum size of the bucket for the queue
- UINT uiMaxBucketSize;
- UINT uiCurrentQueueDepthOnTarget;
- UINT uiCurrentBytesOnHost;
- UINT uiCurrentPacketsOnHost;
- UINT uiDroppedCountBytes;
- UINT uiDroppedCountPackets;
- UINT uiSentBytes;
- UINT uiSentPackets;
- UINT uiCurrentDrainRate;
- UINT uiThisPeriodSentBytes;
- LARGE_INTEGER liDrainCalculated;
- UINT uiCurrentTokenCount;
- LARGE_INTEGER liLastUpdateTokenAt;
- UINT uiMaxAllowedRate;
- UINT NumOfPacketsSent;
- UCHAR ucDirection;
- USHORT usCID;
- S_MIBS_EXTSERVICEFLOW_PARAMETERS stMibsExtServiceFlowTable;
- UINT uiCurrentRxRate;
- UINT uiThisPeriodRxBytes;
- UINT uiTotalRxBytes;
- UINT uiTotalTxBytes;
-}S_MIBS_SERVICEFLOW_TABLE;
-
-typedef struct _S_MIBS_DROPPED_APP_CNTRL_MESSAGES
-{
- ULONG cm_responses;
- ULONG cm_control_newdsx_multiclassifier_resp;
- ULONG link_control_resp;
- ULONG status_rsp;
- ULONG stats_pointer_resp;
- ULONG idle_mode_status;
- ULONG auth_ss_host_msg;
- ULONG low_priority_message;
-
-}S_MIBS_DROPPED_APP_CNTRL_MESSAGES;
-
-typedef struct _S_MIBS_HOST_STATS_MIBS
-{
- S_MIBS_HOST_INFO stHostInfo;
- S_MIBS_CLASSIFIER_RULE astClassifierTable[MIBS_MAX_CLASSIFIERS];
- S_MIBS_SERVICEFLOW_TABLE astSFtable[MIBS_MAX_SERVICEFLOWS];
- S_MIBS_PHS_RULE astPhsRulesTable[MIBS_MAX_PHSRULES];
- S_MIBS_DROPPED_APP_CNTRL_MESSAGES stDroppedAppCntrlMsgs;
-}S_MIBS_HOST_STATS_MIBS;
#endif
-
-
diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h
index 4607c265d98..06a6b18bca4 100644
--- a/drivers/staging/bcm/InterfaceAdapter.h
+++ b/drivers/staging/bcm/InterfaceAdapter.h
@@ -1,97 +1,79 @@
#ifndef _INTERFACE_ADAPTER_H
#define _INTERFACE_ADAPTER_H
-typedef struct _BULK_ENDP_IN
-{
- PCHAR bulk_in_buffer;
- size_t bulk_in_size;
- UCHAR bulk_in_endpointAddr;
- UINT bulk_in_pipe;
-}BULK_ENDP_IN, *PBULK_ENDP_IN;
-
-
-typedef struct _BULK_ENDP_OUT
-{
- UCHAR bulk_out_buffer;
- size_t bulk_out_size;
- UCHAR bulk_out_endpointAddr;
- UINT bulk_out_pipe;
- //this is used when int out endpoint is used as bulk out end point
- UCHAR int_out_interval;
-}BULK_ENDP_OUT, *PBULK_ENDP_OUT;
-
-typedef struct _INTR_ENDP_IN
-{
- PCHAR int_in_buffer;
- size_t int_in_size;
- UCHAR int_in_endpointAddr;
- UCHAR int_in_interval;
- UINT int_in_pipe;
-}INTR_ENDP_IN, *PINTR_ENDP_IN;
-
-typedef struct _INTR_ENDP_OUT
-{
- PCHAR int_out_buffer;
- size_t int_out_size;
- UCHAR int_out_endpointAddr;
- UCHAR int_out_interval;
- UINT int_out_pipe;
-}INTR_ENDP_OUT, *PINTR_ENDP_OUT;
-
-
-typedef struct _USB_TCB
-{
+struct bcm_bulk_endpoint_in {
+ char *bulk_in_buffer;
+ size_t bulk_in_size;
+ unsigned char bulk_in_endpointAddr;
+ unsigned int bulk_in_pipe;
+};
+
+struct bcm_bulk_endpoint_out {
+ unsigned char bulk_out_buffer;
+ size_t bulk_out_size;
+ unsigned char bulk_out_endpointAddr;
+ unsigned int bulk_out_pipe;
+ /* this is used when int out endpoint is used as bulk out end point */
+ unsigned char int_out_interval;
+};
+
+struct bcm_intr_endpoint_in {
+ char *int_in_buffer;
+ size_t int_in_size;
+ unsigned char int_in_endpointAddr;
+ unsigned char int_in_interval;
+ unsigned int int_in_pipe;
+};
+
+struct bcm_intr_endpoint_out {
+ char *int_out_buffer;
+ size_t int_out_size;
+ unsigned char int_out_endpointAddr;
+ unsigned char int_out_interval;
+ unsigned int int_out_pipe;
+};
+
+struct bcm_usb_tcb {
struct urb *urb;
- PVOID psIntfAdapter;
- BOOLEAN bUsed;
-}USB_TCB, *PUSB_TCB;
+ void *psIntfAdapter;
+ bool bUsed;
+};
-
-typedef struct _USB_RCB
-{
+struct bcm_usb_rcb {
struct urb *urb;
- PVOID psIntfAdapter;
- BOOLEAN bUsed;
-}USB_RCB, *PUSB_RCB;
+ void *psIntfAdapter;
+ bool bUsed;
+};
/*
-//This is the interface specific Sub-Adapter
-//Structure.
-*/
-typedef struct _S_INTERFACE_ADAPTER
-{
- struct usb_device * udev;
- struct usb_interface * interface;
-
+ * This is the interface specific Sub-Adapter
+ * Structure.
+ */
+struct bcm_interface_adapter {
+ struct usb_device *udev;
+ struct usb_interface *interface;
/* Bulk endpoint in info */
- BULK_ENDP_IN sBulkIn;
+ struct bcm_bulk_endpoint_in sBulkIn;
/* Bulk endpoint out info */
- BULK_ENDP_OUT sBulkOut;
+ struct bcm_bulk_endpoint_out sBulkOut;
/* Interrupt endpoint in info */
- INTR_ENDP_IN sIntrIn;
+ struct bcm_intr_endpoint_in sIntrIn;
/* Interrupt endpoint out info */
- INTR_ENDP_OUT sIntrOut;
-
-
-
- ULONG ulInterruptData[2];
-
+ struct bcm_intr_endpoint_out sIntrOut;
+ unsigned long ulInterruptData[2];
struct urb *psInterruptUrb;
-
- USB_TCB asUsbTcb[MAXIMUM_USB_TCB];
- USB_RCB asUsbRcb[MAXIMUM_USB_RCB];
- atomic_t uNumTcbUsed;
- atomic_t uCurrTcb;
- atomic_t uNumRcbUsed;
- atomic_t uCurrRcb;
-
+ struct bcm_usb_tcb asUsbTcb[MAXIMUM_USB_TCB];
+ struct bcm_usb_rcb asUsbRcb[MAXIMUM_USB_RCB];
+ atomic_t uNumTcbUsed;
+ atomic_t uCurrTcb;
+ atomic_t uNumRcbUsed;
+ atomic_t uCurrRcb;
struct bcm_mini_adapter *psAdapter;
- BOOLEAN bFlashBoot;
- BOOLEAN bHighSpeedDevice ;
-
- BOOLEAN bSuspended;
- BOOLEAN bPreparingForBusSuspend;
+ bool bFlashBoot;
+ bool bHighSpeedDevice;
+ bool bSuspended;
+ bool bPreparingForBusSuspend;
struct work_struct usbSuspendWork;
-}S_INTERFACE_ADAPTER,*PS_INTERFACE_ADAPTER;
+};
#endif
diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c
index 3a89e33733e..87117a797d5 100644
--- a/drivers/staging/bcm/InterfaceDld.c
+++ b/drivers/staging/bcm/InterfaceDld.c
@@ -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;
- PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
+ struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)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;
- PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
+ struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg;
int bytes;
buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
diff --git a/drivers/staging/bcm/InterfaceIdleMode.c b/drivers/staging/bcm/InterfaceIdleMode.c
index 4f2f490921e..a1bf21579d3 100644
--- a/drivers/staging/bcm/InterfaceIdleMode.c
+++ b/drivers/staging/bcm/InterfaceIdleMode.c
@@ -156,7 +156,7 @@ static int InterfaceAbortIdlemode(struct bcm_mini_adapter *Adapter, unsigned int
int lenwritten = 0;
unsigned char aucAbortPattern[8]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
- PS_INTERFACE_ADAPTER psInterfaceAdapter = Adapter->pvInterfaceAdapter;
+ struct bcm_interface_adapter *psInterfaceAdapter = Adapter->pvInterfaceAdapter;
//Abort Bus suspend if its already suspended
if((TRUE == psInterfaceAdapter->bSuspended) && (TRUE == Adapter->bDoSuspend))
diff --git a/drivers/staging/bcm/InterfaceIdleMode.h b/drivers/staging/bcm/InterfaceIdleMode.h
index c3338c8a1dc..2ef64003aa8 100644
--- a/drivers/staging/bcm/InterfaceIdleMode.h
+++ b/drivers/staging/bcm/InterfaceIdleMode.h
@@ -3,11 +3,12 @@
INT InterfaceIdleModeWakeup(struct bcm_mini_adapter *Adapter);
-INT InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, unsigned int *puiBuffer);
+INT InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter,
+ unsigned int *puiBuffer);
VOID InterfaceWriteIdleModeWakePattern(struct bcm_mini_adapter *Adapter);
-INT InterfaceWakeUp(struct bcm_mini_adapter * Adapter);
+INT InterfaceWakeUp(struct bcm_mini_adapter *Adapter);
VOID InterfaceHandleShutdownModeWakeup(struct bcm_mini_adapter *Adapter);
#endif
diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c
index b05f5f73548..eb246430b32 100644
--- a/drivers/staging/bcm/InterfaceInit.c
+++ b/drivers/staging/bcm/InterfaceInit.c
@@ -4,11 +4,12 @@ static struct usb_device_id InterfaceUsbtable[] = {
{ USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) },
- { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_SM250) },
+ { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_SYM) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_226) },
+ { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_326) },
{ }
};
MODULE_DEVICE_TABLE(usb, InterfaceUsbtable);
@@ -22,9 +23,9 @@ static const u32 default_msg =
| NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
| NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
-static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter);
+static int InterfaceAdapterInit(struct bcm_interface_adapter *Adapter);
-static void InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter)
+static void InterfaceAdapterFree(struct bcm_interface_adapter *psIntfAdapter)
{
int i = 0;
@@ -79,7 +80,7 @@ static void ConfigureEndPointTypesThroughEEPROM(struct bcm_mini_adapter *Adapter
ulReg = ntohl(EP2_CFG_REG);
BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x132, 4, TRUE);
- if (((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter))->bHighSpeedDevice == TRUE) {
+ if (((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter))->bHighSpeedDevice == TRUE) {
ulReg = ntohl(EP2_CFG_INT);
BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x136, 4, TRUE);
} else {
@@ -145,7 +146,7 @@ static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_devi
struct usb_device *udev = interface_to_usbdev(intf);
int retval;
struct bcm_mini_adapter *psAdapter;
- PS_INTERFACE_ADAPTER psIntfAdapter;
+ struct bcm_interface_adapter *psIntfAdapter;
struct net_device *ndev;
/* Reserve one extra queue for the bit-bucket */
@@ -189,7 +190,7 @@ static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_devi
}
/* Allocate interface adapter structure */
- psIntfAdapter = kzalloc(sizeof(S_INTERFACE_ADAPTER), GFP_KERNEL);
+ psIntfAdapter = kzalloc(sizeof(struct bcm_interface_adapter), GFP_KERNEL);
if (psIntfAdapter == NULL) {
dev_err(&udev->dev, DRV_NAME ": no memory for Interface adapter\n");
AdapterFree(psAdapter);
@@ -257,7 +258,7 @@ static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_devi
static void usbbcm_disconnect(struct usb_interface *intf)
{
- PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf);
+ struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf);
struct bcm_mini_adapter *psAdapter;
struct usb_device *udev = interface_to_usbdev(intf);
@@ -276,7 +277,7 @@ static void usbbcm_disconnect(struct usb_interface *intf)
usb_put_dev(udev);
}
-static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter)
+static int AllocUsbCb(struct bcm_interface_adapter *psIntfAdapter)
{
int i = 0;
@@ -311,7 +312,7 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter)
return 0;
}
-static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter)
+static int device_run(struct bcm_interface_adapter *psIntfAdapter)
{
int value = 0;
UINT status = STATUS_SUCCESS;
@@ -421,7 +422,7 @@ static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descrip
return bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd);
}
-static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
+static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
{
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
@@ -619,7 +620,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message)
{
- PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf);
+ struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf);
psIntfAdapter->bSuspended = TRUE;
@@ -646,7 +647,7 @@ static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message)
static int InterfaceResume(struct usb_interface *intf)
{
- PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf);
+ struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf);
mdelay(100);
psIntfAdapter->bSuspended = FALSE;
diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h
index 866924e35f9..ffa6e9667ec 100644
--- a/drivers/staging/bcm/InterfaceInit.h
+++ b/drivers/staging/bcm/InterfaceInit.h
@@ -8,11 +8,11 @@
#define BCM_USB_PRODUCT_ID_T3 0x0300
#define BCM_USB_PRODUCT_ID_T3B 0x0210
#define BCM_USB_PRODUCT_ID_T3L 0x0220
-#define BCM_USB_PRODUCT_ID_SM250 0xbccd
#define BCM_USB_PRODUCT_ID_SYM 0x15E
#define BCM_USB_PRODUCT_ID_1901 0xe017
#define BCM_USB_PRODUCT_ID_226 0x0132 /* not sure if this is valid */
#define BCM_USB_PRODUCT_ID_ZTE_226 0x172
+#define BCM_USB_PRODUCT_ID_ZTE_326 0x173 /* ZTE AX326 */
#define BCM_USB_PRODUCT_ID_ZTE_TU25 0x0007
#define BCM_USB_MINOR_BASE 192
@@ -21,6 +21,6 @@ int InterfaceInitialize(void);
int InterfaceExit(void);
-int usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter);
+int usbbcm_worker_thread(struct bcm_interface_adapter *psIntfAdapter);
#endif
diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c
index 6ee3428daa5..8322f1b76e2 100644
--- a/drivers/staging/bcm/InterfaceIsr.c
+++ b/drivers/staging/bcm/InterfaceIsr.c
@@ -4,7 +4,7 @@
static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
{
int status = urb->status;
- PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)urb->context;
+ struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)urb->context;
struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter ;
if (netif_msg_intr(Adapter))
@@ -114,7 +114,7 @@ static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
}
-int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter)
+int CreateInterruptUrb(struct bcm_interface_adapter *psIntfAdapter)
{
psIntfAdapter->psInterruptUrb = usb_alloc_urb(0, GFP_KERNEL);
if (!psIntfAdapter->psInterruptUrb)
@@ -143,7 +143,7 @@ int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter)
}
-INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter)
+INT StartInterruptUrb(struct bcm_interface_adapter *psIntfAdapter)
{
INT status = 0;
diff --git a/drivers/staging/bcm/InterfaceIsr.h b/drivers/staging/bcm/InterfaceIsr.h
index 40399788c41..3073bd71cfe 100644
--- a/drivers/staging/bcm/InterfaceIsr.h
+++ b/drivers/staging/bcm/InterfaceIsr.h
@@ -1,10 +1,10 @@
#ifndef _INTERFACE_ISR_H
#define _INTERFACE_ISR_H
-int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter);
+int CreateInterruptUrb(struct bcm_interface_adapter *psIntfAdapter);
-INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter);
+INT StartInterruptUrb(struct bcm_interface_adapter *psIntfAdapter);
VOID InterfaceEnableInterrupt(struct bcm_mini_adapter *Adapter);
diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c
index bbe90994609..afca010f9db 100644
--- a/drivers/staging/bcm/InterfaceMisc.c
+++ b/drivers/staging/bcm/InterfaceMisc.c
@@ -1,17 +1,14 @@
#include "headers.h"
-INT InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
- UINT addr,
- PVOID buff,
- INT len)
+int InterfaceRDM(struct bcm_interface_adapter *psIntfAdapter,
+ unsigned int addr,
+ void *buff,
+ int len)
{
int bytes;
- USHORT usRetries = 0;
- if (psIntfAdapter == NULL) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL");
+ if (!psIntfAdapter)
return -EINVAL;
- }
if (psIntfAdapter->psAdapter->device_removed == TRUE) {
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed");
@@ -29,27 +26,21 @@ INT InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
}
psIntfAdapter->psAdapter->DeviceAccess = TRUE;
- do {
- bytes = usb_control_msg(psIntfAdapter->udev,
- usb_rcvctrlpipe(psIntfAdapter->udev, 0),
- 0x02,
- 0xC2,
- (addr & 0xFFFF),
- ((addr >> 16) & 0xFFFF),
- buff,
- len,
- 5000);
-
- usRetries++;
- if (-ENODEV == bytes) {
- psIntfAdapter->psAdapter->device_removed = TRUE;
- break;
- }
+ bytes = usb_control_msg(psIntfAdapter->udev,
+ usb_rcvctrlpipe(psIntfAdapter->udev, 0),
+ 0x02,
+ 0xC2,
+ (addr & 0xFFFF),
+ ((addr >> 16) & 0xFFFF),
+ buff,
+ len,
+ 5000);
- } while ((bytes < 0) && (usRetries < MAX_RDM_WRM_RETIRES));
+ if (-ENODEV == bytes)
+ psIntfAdapter->psAdapter->device_removed = TRUE;
if (bytes < 0)
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", bytes, usRetries);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d", bytes);
else
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", bytes);
@@ -57,18 +48,15 @@ INT InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
return bytes;
}
-INT InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
- UINT addr,
- PVOID buff,
- INT len)
+int InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter,
+ unsigned int addr,
+ void *buff,
+ int len)
{
int retval = 0;
- USHORT usRetries = 0;
- if (psIntfAdapter == NULL) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL");
+ if (!psIntfAdapter)
return -EINVAL;
- }
if (psIntfAdapter->psAdapter->device_removed == TRUE) {
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed");
@@ -87,27 +75,21 @@ INT InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
psIntfAdapter->psAdapter->DeviceAccess = TRUE;
- do {
- retval = usb_control_msg(psIntfAdapter->udev,
- usb_sndctrlpipe(psIntfAdapter->udev, 0),
- 0x01,
- 0x42,
- (addr & 0xFFFF),
- ((addr >> 16) & 0xFFFF),
- buff,
- len,
- 5000);
-
- usRetries++;
- if (-ENODEV == retval) {
- psIntfAdapter->psAdapter->device_removed = TRUE;
- break;
- }
+ retval = usb_control_msg(psIntfAdapter->udev,
+ usb_sndctrlpipe(psIntfAdapter->udev, 0),
+ 0x01,
+ 0x42,
+ (addr & 0xFFFF),
+ ((addr >> 16) & 0xFFFF),
+ buff,
+ len,
+ 5000);
- } while ((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES));
+ if (-ENODEV == retval)
+ psIntfAdapter->psAdapter->device_removed = TRUE;
if (retval < 0) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d, retires :%d", retval, usRetries);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d", retval);
psIntfAdapter->psAdapter->DeviceAccess = FALSE;
return retval;
} else {
@@ -117,26 +99,26 @@ INT InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
}
}
-INT BcmRDM(PVOID arg,
- UINT addr,
- PVOID buff,
- INT len)
+int BcmRDM(void *arg,
+ unsigned int addr,
+ void *buff,
+ int len)
{
- return InterfaceRDM((PS_INTERFACE_ADAPTER)arg, addr, buff, len);
+ return InterfaceRDM((struct bcm_interface_adapter*)arg, addr, buff, len);
}
-INT BcmWRM(PVOID arg,
- UINT addr,
- PVOID buff,
- INT len)
+int BcmWRM(void *arg,
+ unsigned int addr,
+ void *buff,
+ int len)
{
- return InterfaceWRM((PS_INTERFACE_ADAPTER)arg, addr, buff, len);
+ return InterfaceWRM((struct bcm_interface_adapter *)arg, addr, buff, len);
}
-INT Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter)
+int Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter)
{
- PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter);
- INT status = STATUS_SUCCESS;
+ struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter);
+ int status = STATUS_SUCCESS;
/*
* usb_clear_halt - tells device to clear endpoint halt/stall condition
@@ -172,10 +154,10 @@ INT Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter)
return status;
}
-VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
+void Bcm_kill_all_URBs(struct bcm_interface_adapter *psIntfAdapter)
{
struct urb *tempUrb = NULL;
- UINT i;
+ unsigned int i;
/*
* usb_kill_urb - cancel a transfer request and wait for it to finish
@@ -193,7 +175,7 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
*/
/* Cancel submitted Interrupt-URB's */
- if (psIntfAdapter->psInterruptUrb != NULL) {
+ if (psIntfAdapter->psInterruptUrb) {
if (psIntfAdapter->psInterruptUrb->status == -EINPROGRESS)
usb_kill_urb(psIntfAdapter->psInterruptUrb);
}
@@ -222,11 +204,11 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
atomic_set(&psIntfAdapter->uCurrRcb, 0);
}
-VOID putUsbSuspend(struct work_struct *work)
+void putUsbSuspend(struct work_struct *work)
{
- PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
+ struct bcm_interface_adapter *psIntfAdapter = NULL;
struct usb_interface *intf = NULL;
- psIntfAdapter = container_of(work, S_INTERFACE_ADAPTER, usbSuspendWork);
+ psIntfAdapter = container_of(work, struct bcm_interface_adapter, usbSuspendWork);
intf = psIntfAdapter->interface;
if (psIntfAdapter->bSuspended == FALSE)
diff --git a/drivers/staging/bcm/InterfaceMisc.h b/drivers/staging/bcm/InterfaceMisc.h
index 1dfabdc3aad..bce6869a747 100644
--- a/drivers/staging/bcm/InterfaceMisc.h
+++ b/drivers/staging/bcm/InterfaceMisc.h
@@ -2,13 +2,13 @@
#define __INTERFACE_MISC_H
INT
-InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
+InterfaceRDM(struct bcm_interface_adapter *psIntfAdapter,
UINT addr,
PVOID buff,
INT len);
INT
-InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
+InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter,
UINT addr,
PVOID buff,
INT len);
@@ -35,7 +35,7 @@ int BcmWRM(PVOID arg,
INT Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter);
-VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter);
+VOID Bcm_kill_all_URBs(struct bcm_interface_adapter *psIntfAdapter);
#define DISABLE_USB_ZERO_LEN_INT 0x0F011878
diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c
index 8a9f90fbdf1..26f5bc76111 100644
--- a/drivers/staging/bcm/InterfaceRx.c
+++ b/drivers/staging/bcm/InterfaceRx.c
@@ -12,10 +12,10 @@ static int SearchVcid(struct bcm_mini_adapter *Adapter,unsigned short usVcid)
}
-static PUSB_RCB
-GetBulkInRcb(PS_INTERFACE_ADAPTER psIntfAdapter)
+static struct bcm_usb_rcb *
+GetBulkInRcb(struct bcm_interface_adapter *psIntfAdapter)
{
- PUSB_RCB pRcb = NULL;
+ struct bcm_usb_rcb *pRcb = NULL;
UINT index = 0;
if((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) &&
@@ -43,8 +43,8 @@ static void read_bulk_callback(struct urb *urb)
UINT uiIndex=0;
int process_done = 1;
//int idleflag = 0 ;
- PUSB_RCB pRcb = (PUSB_RCB)urb->context;
- PS_INTERFACE_ADAPTER psIntfAdapter = pRcb->psIntfAdapter;
+ struct bcm_usb_rcb *pRcb = (struct bcm_usb_rcb *)urb->context;
+ struct bcm_interface_adapter *psIntfAdapter = pRcb->psIntfAdapter;
struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter;
struct bcm_leader *pLeader = urb->transfer_buffer;
@@ -196,7 +196,7 @@ static void read_bulk_callback(struct urb *urb)
atomic_dec(&psIntfAdapter->uNumRcbUsed);
}
-static int ReceiveRcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_RCB pRcb)
+static int ReceiveRcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_usb_rcb *pRcb)
{
struct urb *urb = pRcb->urb;
int retval = 0;
@@ -240,10 +240,10 @@ Return: TRUE - If Rx was successful.
Other - If an error occurred.
*/
-BOOLEAN InterfaceRx (PS_INTERFACE_ADAPTER psIntfAdapter)
+BOOLEAN InterfaceRx (struct bcm_interface_adapter *psIntfAdapter)
{
USHORT RxDescCount = NUM_RX_DESC - atomic_read(&psIntfAdapter->uNumRcbUsed);
- PUSB_RCB pRcb = NULL;
+ struct bcm_usb_rcb *pRcb = NULL;
// RxDescCount = psIntfAdapter->psAdapter->CurrNumRecvDescs -
// psIntfAdapter->psAdapter->PrevNumRecvDescs;
diff --git a/drivers/staging/bcm/InterfaceRx.h b/drivers/staging/bcm/InterfaceRx.h
index 96e81a1d37b..424645e9e47 100644
--- a/drivers/staging/bcm/InterfaceRx.h
+++ b/drivers/staging/bcm/InterfaceRx.h
@@ -1,7 +1,7 @@
#ifndef _INTERFACE_RX_H
#define _INTERFACE_RX_H
-BOOLEAN InterfaceRx(PS_INTERFACE_ADAPTER Adapter);
+BOOLEAN InterfaceRx(struct bcm_interface_adapter *Adapter);
#endif
diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c
index 7e2b53be4d9..b8c785556dd 100644
--- a/drivers/staging/bcm/InterfaceTx.c
+++ b/drivers/staging/bcm/InterfaceTx.c
@@ -3,8 +3,8 @@
/*this is transmit call-back(BULK OUT)*/
static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
{
- PUSB_TCB pTcb= (PUSB_TCB)urb->context;
- PS_INTERFACE_ADAPTER psIntfAdapter = pTcb->psIntfAdapter;
+ struct bcm_usb_tcb *pTcb= (struct bcm_usb_tcb *)urb->context;
+ 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 ;
@@ -107,9 +107,9 @@ err_exit :
}
-static PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter)
+static struct bcm_usb_tcb *GetBulkOutTcb(struct bcm_interface_adapter *psIntfAdapter)
{
- PUSB_TCB pTcb = NULL;
+ struct bcm_usb_tcb *pTcb = NULL;
UINT index = 0;
if((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) &&
@@ -128,7 +128,7 @@ static PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter)
return pTcb;
}
-static int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len)
+static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_usb_tcb *pTcb, PVOID data, int len)
{
struct urb *urb = pTcb->urb;
@@ -182,9 +182,9 @@ static int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID
int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len)
{
- PUSB_TCB pTcb= NULL;
+ struct bcm_usb_tcb *pTcb= NULL;
- PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
+ struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg;
pTcb= GetBulkOutTcb(psIntfAdapter);
if(pTcb == NULL)
{
diff --git a/drivers/staging/bcm/Ioctl.h b/drivers/staging/bcm/Ioctl.h
index f859cf1c47b..8c70af90969 100644
--- a/drivers/staging/bcm/Ioctl.h
+++ b/drivers/staging/bcm/Ioctl.h
@@ -1,247 +1,136 @@
#ifndef _IOCTL_H_
#define _IOCTL_H_
-typedef struct rdmbuffer
-{
- ULONG Register;
- ULONG Length;
-}__attribute__((packed)) RDM_BUFFER, *PRDM_BUFFER;
-
-
-typedef struct wrmbuffer
-{
- ULONG Register;
- ULONG Length;
- UCHAR Data[4];
-}__attribute__((packed)) WRM_BUFFER, *PWRM_BUFFER;
-
-
-typedef struct ioctlbuffer
-{
+struct bcm_rdm_buffer {
+ unsigned long Register;
+ unsigned long Length;
+} __packed;
+
+struct bcm_wrm_buffer {
+ unsigned long Register;
+ unsigned long Length;
+ unsigned char Data[4];
+} __packed;
+
+struct bcm_ioctl_buffer {
void __user *InputBuffer;
- ULONG InputLength;
+ unsigned long InputLength;
void __user *OutputBuffer;
- ULONG OutputLength;
-}__attribute__((packed)) IOCTL_BUFFER, *PIOCTL_BUFFER;
-
-typedef struct stGPIOInfo
-{
- UINT uiGpioNumber ; /* valid numbers 0-15 */
- UINT uiGpioValue; /* 1 set ; 0 not set */
-}__attribute__((packed))GPIO_INFO,*PGPIO_INFO;
-typedef struct stUserThreadReq
-{
- //0->Inactivate LED thread.
- //1->Activate the LED thread
- UINT ThreadState;
-}__attribute__((packed))USER_THREAD_REQ,*PUSER_THREAD_REQ;
-#define LED_THREAD_ACTIVATION_REQ 1
-
-
-////********** ioctl codes ***********////
-
-#define BCM_IOCTL 'k'
-
-//1.Control code for CONTROL MESSAGES
-
-#define IOCTL_SEND_CONTROL_MESSAGE _IOW(BCM_IOCTL, 0x801,int)
-
-//2.Control code to write a particular value to a particular register
-#define IOCTL_BCM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x802, int) //
-
-//3.
-#define IOCTL_BCM_REGISTER_READ _IOR(BCM_IOCTL, 0x803, int) //
+ unsigned long OutputLength;
+} __packed;
-//4.Control code to write x number of bytes to common memory
-//starting from address y
-#define IOCTL_BCM_COMMON_MEMORY_WRITE _IOW(BCM_IOCTL, 0x804, int)//
+struct bcm_gpio_info {
+ unsigned int uiGpioNumber; /* valid numbers 0-15 */
+ unsigned int uiGpioValue; /* 1 set ; 0 not set */
+} __packed;
-//5.Control code to write x number of bytes to common memory
-//starting from address y
-#define IOCTL_BCM_COMMON_MEMORY_READ _IOR(BCM_IOCTL, 0x805, int)//
-
-//6.Control code for CONTROL MESSAGES
-#define IOCTL_GET_CONTROL_MESSAGE _IOR(BCM_IOCTL, 0x806, int)//
-
-//7.Control code for FIRMWARE DOWNLOAD
-#define IOCTL_BCM_FIRMWARE_DOWNLOAD _IOW(BCM_IOCTL, 0x807, int)//
-
-#define IOCTL_BCM_SET_SEND_VCID _IOW(BCM_IOCTL, 0x808, int)
-
-//9.Control code for TRANSFER MODE SWITCHING
-#define IOCTL_BCM_SWITCH_TRANSFER_MODE _IOW(BCM_IOCTL, 0x809, int)
-//10.Control code for LINK UP
-#define IOCTL_LINK_REQ _IOW(BCM_IOCTL, 0x80A, int)
-
-//11.Control code for RSSI Level Request
-#define IOCTL_RSSI_LEVEL_REQ _IOW(BCM_IOCTL, 0x80B, int)
-//12.Control code for IDLE MODE CONTROL
-#define IOCTL_IDLE_REQ _IOW(BCM_IOCTL, 0x80C, int)
-//13.Control code for SS/BS info
-#define IOCTL_SS_INFO_REQ _IOW(BCM_IOCTL, 0x80D, int)
+struct bcm_user_thread_req {
+ /* 0->Inactivate LED thread. */
+ /* 1->Activate the LED thread */
+ unsigned int ThreadState;
+} __packed;
+#define LED_THREAD_ACTIVATION_REQ 1
+#define BCM_IOCTL 'k'
+#define IOCTL_SEND_CONTROL_MESSAGE _IOW(BCM_IOCTL, 0x801, int)
+#define IOCTL_BCM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x802, int)
+#define IOCTL_BCM_REGISTER_READ _IOR(BCM_IOCTL, 0x803, int)
+#define IOCTL_BCM_COMMON_MEMORY_WRITE _IOW(BCM_IOCTL, 0x804, int)
+#define IOCTL_BCM_COMMON_MEMORY_READ _IOR(BCM_IOCTL, 0x805, int)
+#define IOCTL_GET_CONTROL_MESSAGE _IOR(BCM_IOCTL, 0x806, int)
+#define IOCTL_BCM_FIRMWARE_DOWNLOAD _IOW(BCM_IOCTL, 0x807, int)
+#define IOCTL_BCM_SET_SEND_VCID _IOW(BCM_IOCTL, 0x808, int)
+#define IOCTL_BCM_SWITCH_TRANSFER_MODE _IOW(BCM_IOCTL, 0x809, int)
+#define IOCTL_LINK_REQ _IOW(BCM_IOCTL, 0x80A, int)
+#define IOCTL_RSSI_LEVEL_REQ _IOW(BCM_IOCTL, 0x80B, int)
+#define IOCTL_IDLE_REQ _IOW(BCM_IOCTL, 0x80C, int)
+#define IOCTL_SS_INFO_REQ _IOW(BCM_IOCTL, 0x80D, int)
#define IOCTL_GET_STATISTICS_POINTER _IOW(BCM_IOCTL, 0x80E, int)
-
-#define IOCTL_CM_REQUEST _IOW(BCM_IOCTL, 0x80F, int)
-
-#define IOCTL_INIT_PARAM_REQ _IOW(BCM_IOCTL, 0x810, int)
-
-#define IOCTL_MAC_ADDR_REQ _IOW(BCM_IOCTL, 0x811, int)
-
-#define IOCTL_MAC_ADDR_RESP _IOWR(BCM_IOCTL, 0x812, int)
-
-#define IOCTL_CLASSIFICATION_RULE _IOW(BCM_IOCTL, 0x813, char)
-
+#define IOCTL_CM_REQUEST _IOW(BCM_IOCTL, 0x80F, int)
+#define IOCTL_INIT_PARAM_REQ _IOW(BCM_IOCTL, 0x810, int)
+#define IOCTL_MAC_ADDR_REQ _IOW(BCM_IOCTL, 0x811, int)
+#define IOCTL_MAC_ADDR_RESP _IOWR(BCM_IOCTL, 0x812, int)
+#define IOCTL_CLASSIFICATION_RULE _IOW(BCM_IOCTL, 0x813, char)
#define IOCTL_CLOSE_NOTIFICATION _IO(BCM_IOCTL, 0x814)
-
-#define IOCTL_LINK_UP _IO(BCM_IOCTL, 0x815)
-
-#define IOCTL_LINK_DOWN _IO(BCM_IOCTL, 0x816, IOCTL_BUFFER)
-
-#define IOCTL_CHIP_RESET _IO(BCM_IOCTL, 0x816)
-
+#define IOCTL_LINK_UP _IO(BCM_IOCTL, 0x815)
+#define IOCTL_LINK_DOWN _IO(BCM_IOCTL, 0x816, struct bcm_ioctl_buffer)
+#define IOCTL_CHIP_RESET _IO(BCM_IOCTL, 0x816)
#define IOCTL_CINR_LEVEL_REQ _IOW(BCM_IOCTL, 0x817, char)
-
-#define IOCTL_WTM_CONTROL_REQ _IOW(BCM_IOCTL, 0x817,char)
-
+#define IOCTL_WTM_CONTROL_REQ _IOW(BCM_IOCTL, 0x817, char)
#define IOCTL_BE_BUCKET_SIZE _IOW(BCM_IOCTL, 0x818, unsigned long)
-
#define IOCTL_RTPS_BUCKET_SIZE _IOW(BCM_IOCTL, 0x819, unsigned long)
-
-#define IOCTL_QOS_THRESHOLD _IOW(BCM_IOCTL, 0x820, unsigned long)
-
-#define IOCTL_DUMP_PACKET_INFO _IO(BCM_IOCTL, 0x821)
-
-#define IOCTL_GET_PACK_INFO _IOR(BCM_IOCTL, 0x823, int)
-
+#define IOCTL_QOS_THRESHOLD _IOW(BCM_IOCTL, 0x820, unsigned long)
+#define IOCTL_DUMP_PACKET_INFO _IO(BCM_IOCTL, 0x821)
+#define IOCTL_GET_PACK_INFO _IOR(BCM_IOCTL, 0x823, int)
#define IOCTL_BCM_GET_DRIVER_VERSION _IOR(BCM_IOCTL, 0x829, int)
-
-#define IOCTL_BCM_GET_CURRENT_STATUS _IOW(BCM_IOCTL, 0x828, int)
-
-#define IOCTL_BCM_GPIO_SET_REQUEST _IOW(BCM_IOCTL, 0x82A, int)
-
-#define IOCTL_BCM_GPIO_STATUS_REQUEST _IOW(BCM_IOCTL, 0x82b, int)
-
-#define IOCTL_BCM_GET_DSX_INDICATION _IOR(BCM_IOCTL, 0x854, int)
-
-#define IOCTL_BCM_BUFFER_DOWNLOAD_START _IOW(BCM_IOCTL, 0x855, int)
-
-#define IOCTL_BCM_BUFFER_DOWNLOAD _IOW(BCM_IOCTL, 0x856, int)
-
-#define IOCTL_BCM_BUFFER_DOWNLOAD_STOP _IOW(BCM_IOCTL, 0x857, int)
-
-#define IOCTL_BCM_REGISTER_WRITE_PRIVATE _IOW(BCM_IOCTL, 0x826, char)
-
+#define IOCTL_BCM_GET_CURRENT_STATUS _IOW(BCM_IOCTL, 0x828, int)
+#define IOCTL_BCM_GPIO_SET_REQUEST _IOW(BCM_IOCTL, 0x82A, int)
+#define IOCTL_BCM_GPIO_STATUS_REQUEST _IOW(BCM_IOCTL, 0x82b, int)
+#define IOCTL_BCM_GET_DSX_INDICATION _IOR(BCM_IOCTL, 0x854, int)
+#define IOCTL_BCM_BUFFER_DOWNLOAD_START _IOW(BCM_IOCTL, 0x855, int)
+#define IOCTL_BCM_BUFFER_DOWNLOAD _IOW(BCM_IOCTL, 0x856, int)
+#define IOCTL_BCM_BUFFER_DOWNLOAD_STOP _IOW(BCM_IOCTL, 0x857, int)
+#define IOCTL_BCM_REGISTER_WRITE_PRIVATE _IOW(BCM_IOCTL, 0x826, char)
#define IOCTL_BCM_REGISTER_READ_PRIVATE _IOW(BCM_IOCTL, 0x827, char)
-
-#define IOCTL_BCM_SET_DEBUG _IOW(BCM_IOCTL, 0x824, IOCTL_BUFFER)
-
-#define IOCTL_BCM_EEPROM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x858, int)
-
-#define IOCTL_BCM_EEPROM_REGISTER_READ _IOR(BCM_IOCTL, 0x859, int)
-
+#define IOCTL_BCM_SET_DEBUG _IOW(BCM_IOCTL, 0x824, struct bcm_ioctl_buffer)
+#define IOCTL_BCM_EEPROM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x858, int)
+#define IOCTL_BCM_EEPROM_REGISTER_READ _IOR(BCM_IOCTL, 0x859, int)
#define IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE _IOR(BCM_IOCTL, 0x860, int)
-
-#define IOCTL_BCM_SET_MAC_TRACING _IOW(BCM_IOCTL, 0x82c, int)
-
-#define IOCTL_BCM_GET_HOST_MIBS _IOW(BCM_IOCTL, 0x853, int)
-
-#define IOCTL_BCM_NVM_READ _IOR(BCM_IOCTL, 0x861, int)
-
-#define IOCTL_BCM_NVM_WRITE _IOW(BCM_IOCTL, 0x862, int)
-
-#define IOCTL_BCM_GET_NVM_SIZE _IOR(BCM_IOCTL, 0x863, int)
-
-#define IOCTL_BCM_CAL_INIT _IOR(BCM_IOCTL, 0x864, int)
-
-#define IOCTL_BCM_BULK_WRM _IOW(BCM_IOCTL, 0x90B, int)
-
-#define IOCTL_BCM_FLASH2X_SECTION_READ _IOR(BCM_IOCTL, 0x865, int)
-
+#define IOCTL_BCM_SET_MAC_TRACING _IOW(BCM_IOCTL, 0x82c, int)
+#define IOCTL_BCM_GET_HOST_MIBS _IOW(BCM_IOCTL, 0x853, int)
+#define IOCTL_BCM_NVM_READ _IOR(BCM_IOCTL, 0x861, int)
+#define IOCTL_BCM_NVM_WRITE _IOW(BCM_IOCTL, 0x862, int)
+#define IOCTL_BCM_GET_NVM_SIZE _IOR(BCM_IOCTL, 0x863, int)
+#define IOCTL_BCM_CAL_INIT _IOR(BCM_IOCTL, 0x864, int)
+#define IOCTL_BCM_BULK_WRM _IOW(BCM_IOCTL, 0x90B, int)
+#define IOCTL_BCM_FLASH2X_SECTION_READ _IOR(BCM_IOCTL, 0x865, int)
#define IOCTL_BCM_FLASH2X_SECTION_WRITE _IOW(BCM_IOCTL, 0x866, int)
+#define IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP _IOR(BCM_IOCTL, 0x867, int)
+#define IOCTL_BCM_SET_ACTIVE_SECTION _IOW(BCM_IOCTL, 0x868, int)
+#define IOCTL_BCM_IDENTIFY_ACTIVE_SECTION _IO(BCM_IOCTL, 0x869)
+#define IOCTL_BCM_COPY_SECTION _IOW(BCM_IOCTL, 0x870, int)
+#define IOCTL_BCM_GET_FLASH_CS_INFO _IOR(BCM_IOCTL, 0x871, int)
+#define IOCTL_BCM_SELECT_DSD _IOW(BCM_IOCTL, 0x872, int)
+#define IOCTL_BCM_NVM_RAW_READ _IOR(BCM_IOCTL, 0x875, int)
+#define IOCTL_BCM_CNTRLMSG_MASK _IOW(BCM_IOCTL, 0x874, int)
+#define IOCTL_BCM_GET_DEVICE_DRIVER_INFO _IOR(BCM_IOCTL, 0x877, int)
+#define IOCTL_BCM_TIME_SINCE_NET_ENTRY _IOR(BCM_IOCTL, 0x876, int)
+#define BCM_LED_THREAD_STATE_CHANGE_REQ _IOW(BCM_IOCTL, 0x878, int)
+#define IOCTL_BCM_GPIO_MULTI_REQUEST _IOW(BCM_IOCTL, 0x82D, struct bcm_ioctl_buffer)
+#define IOCTL_BCM_GPIO_MODE_REQUEST _IOW(BCM_IOCTL, 0x82E, struct bcm_ioctl_buffer)
+
+enum bcm_interface_type {
+ BCM_MII,
+ BCM_CARDBUS,
+ BCM_USB,
+ BCM_SDIO,
+ BCM_PCMCIA
+};
-#define IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP _IOR(BCM_IOCTL,0x867, int)
-
-#define IOCTL_BCM_SET_ACTIVE_SECTION _IOW(BCM_IOCTL,0x868, int)
-
-#define IOCTL_BCM_IDENTIFY_ACTIVE_SECTION _IO(BCM_IOCTL,0x869)
-
-#define IOCTL_BCM_COPY_SECTION _IOW(BCM_IOCTL, 0x870,int)
-
-#define IOCTL_BCM_GET_FLASH_CS_INFO _IOR(BCM_IOCTL, 0x871, int)
-
-#define IOCTL_BCM_SELECT_DSD _IOW(BCM_IOCTL, 0x872, int)
-
-#define IOCTL_BCM_NVM_RAW_READ _IOR(BCM_IOCTL, 0x875, int)
-
-#define IOCTL_BCM_CNTRLMSG_MASK _IOW(BCM_IOCTL, 0x874, int)
-
-#define IOCTL_BCM_GET_DEVICE_DRIVER_INFO _IOR(BCM_IOCTL, 0x877, int)
-
-#define IOCTL_BCM_TIME_SINCE_NET_ENTRY _IOR(BCM_IOCTL, 0x876, int)
-
-#define BCM_LED_THREAD_STATE_CHANGE_REQ _IOW(BCM_IOCTL, 0x878, int)
-
-#define IOCTL_BCM_GPIO_MULTI_REQUEST _IOW(BCM_IOCTL, 0x82D, IOCTL_BUFFER)
-#define IOCTL_BCM_GPIO_MODE_REQUEST _IOW(BCM_IOCTL, 0x82E, IOCTL_BUFFER)
-
-
-
-typedef enum _BCM_INTERFACE_TYPE
-{
- BCM_MII,
- BCM_CARDBUS,
- BCM_USB,
- BCM_SDIO,
- BCM_PCMCIA
-}BCM_INTERFACE_TYPE;
-
-typedef struct _DEVICE_DRIVER_INFO
-{
- NVM_TYPE u32NVMType;
- UINT MaxRDMBufferSize;
- BCM_INTERFACE_TYPE u32InterfaceType;
- UINT u32DSDStartOffset;
- UINT u32RxAlignmentCorrection;
- UINT u32Reserved[10];
-} DEVICE_DRIVER_INFO;
-
-typedef struct _NVM_READWRITE
-{
+struct bcm_driver_info {
+ NVM_TYPE u32NVMType;
+ unsigned int MaxRDMBufferSize;
+ enum bcm_interface_type u32InterfaceType;
+ unsigned int u32DSDStartOffset;
+ unsigned int u32RxAlignmentCorrection;
+ unsigned int u32Reserved[10];
+};
+struct bcm_nvm_readwrite {
void __user *pBuffer;
-// Data to be written from|read to. Memory should be allocated by the caller.
-
uint32_t uiOffset;
-// offset at which data should be written to or read from.
-
- uint32_t uiNumBytes;
-// No. of bytes to be written or read.
-
- bool bVerify;
-// Applicable only for write. If set verification of written data will be done.
-
-} NVM_READWRITE,*PNVM_READWRITE;
-typedef struct bulkwrmbuffer
-{
- ULONG Register;
- ULONG SwapEndian;
- ULONG Values[1];
-
-}BULKWRM_BUFFER,*PBULKWRM_BUFFER;
-
-
-/***********Structure used for FlashMap2.x *******************************/
+ uint32_t uiNumBytes;
+ bool bVerify;
+};
-/*
-* These are Sction present inside the Flash.
-* There is sectional RD/WR for flash Map 2.x.
-* hence these section will be used in read/write API.
-*/
+struct bcm_bulk_wrm_buffer {
+ unsigned long Register;
+ unsigned long SwapEndian;
+ unsigned long Values[1];
+};
-typedef enum _FLASH2X_SECTION_VAL
-{
- NO_SECTION_VAL = 0, //no section is chosen when absolute offset is given for RD/WR
+enum bcm_flash2x_section_val {
+ NO_SECTION_VAL = 0, /* no section is chosen when absolute offset is given for RD/WR */
ISO_IMAGE1,
ISO_IMAGE2,
DSD0,
@@ -257,104 +146,81 @@ typedef enum _FLASH2X_SECTION_VAL
ISO_IMAGE2_PART2,
ISO_IMAGE2_PART3,
TOTAL_SECTIONS
-}FLASH2X_SECTION_VAL;
+};
/*
-* Structure used for READ/WRITE Flash Map2.x
-*/
-typedef struct _FLASH2X_READWRITE
-{
-
- FLASH2X_SECTION_VAL Section; //which section has to be read/written
- B_UINT32 offset; //Offset within Section.
- B_UINT32 numOfBytes; //NOB from the offset
- B_UINT32 bVerify;
- void __user *pDataBuff; //Buffer for reading/writing
+ * Structure used for READ/WRITE Flash Map2.x
+ */
+struct bcm_flash2x_readwrite {
+ enum bcm_flash2x_section_val Section; /* which section has to be read/written */
+ u32 offset; /* Offset within Section. */
+ u32 numOfBytes; /* NOB from the offset */
+ u32 bVerify;
+ void __user *pDataBuff; /* Buffer for reading/writing */
+};
-}FLASH2X_READWRITE, *PFLASH2X_READWRITE;
/*
-* This structure is used for coping one section to other.
-* there are two ways to copy one section to other.
-* it NOB =0, complete section will be copied on to other.
-* if NOB !=0, only NOB will be copied from the given offset.
-*/
-
-typedef struct _FLASH2X_COPY_SECTION
-{
- //Src Section from which Data has to be copied to DstSection
- FLASH2X_SECTION_VAL SrcSection;
-
- //Destination Section from where Data has to be coppied.
- FLASH2X_SECTION_VAL DstSection;
-
- //Offset within Section. if NOB =0 it will be ignored and data will be coped from offset 0.
- B_UINT32 offset;
-
- //NOB from the offset. if NOB = 0 complete src section will be copied to Destination section.
- B_UINT32 numOfBytes;
-} FLASH2X_COPY_SECTION, *PFLASH2X_COPY_SECTION;
-
-
-typedef enum _SECTION_TYPE
-{
- ISO = 0,
- VSA = 1,
- DSD = 2
-} SECTION_TYPE, *PSECTION_TYPE;
+ * This structure is used for coping one section to other.
+ * there are two ways to copy one section to other.
+ * it NOB =0, complete section will be copied on to other.
+ * if NOB !=0, only NOB will be copied from the given offset.
+ */
+
+struct bcm_flash2x_copy_section {
+ enum bcm_flash2x_section_val SrcSection;
+ enum bcm_flash2x_section_val DstSection;
+ u32 offset;
+ u32 numOfBytes;
+};
/*
-* This section provide the complete bitmap of the Flash.
-* using this map lib/APP will isssue read/write command.
- Fields are defined as :
- Bit [0] = section is present //1:present, 0: Not present
-* Bit [1] = section is valid //1: valid, 0: not valid
-* Bit [2] = Section is R/W //0: RW, 1: RO
-* Bit [3] = Section is Active or not 1 means Active, 0->inactive
-* Bit [7...3] = Reserved
-*/
-
-typedef struct _FLASH2X_BITMAP
-{
- UCHAR ISO_IMAGE1;
- UCHAR ISO_IMAGE2;
- UCHAR DSD0;
- UCHAR DSD1;
- UCHAR DSD2;
- UCHAR VSA0;
- UCHAR VSA1;
- UCHAR VSA2;
- UCHAR SCSI;
- UCHAR CONTROL_SECTION;
- //Reserved for future use
- UCHAR Reserved0;
- UCHAR Reserved1;
- UCHAR Reserved2;
-}FLASH2X_BITMAP, *PFLASH2X_BITMAP;
+ * This section provide the complete bitmap of the Flash.
+ * using this map lib/APP will isssue read/write command.
+ * Fields are defined as :
+ * Bit [0] = section is present //1:present, 0: Not present
+ * Bit [1] = section is valid //1: valid, 0: not valid
+ * Bit [2] = Section is R/W //0: RW, 1: RO
+ * Bit [3] = Section is Active or not 1 means Active, 0->inactive
+ * Bit [7...3] = Reserved
+ */
+
+struct bcm_flash2x_bitmap {
+ unsigned char ISO_IMAGE1;
+ unsigned char ISO_IMAGE2;
+ unsigned char DSD0;
+ unsigned char DSD1;
+ unsigned char DSD2;
+ unsigned char VSA0;
+ unsigned char VSA1;
+ unsigned char VSA2;
+ unsigned char SCSI;
+ unsigned char CONTROL_SECTION;
+ /* Reserved for future use */
+ unsigned char Reserved0;
+ unsigned char Reserved1;
+ unsigned char Reserved2;
+};
-//for net entry time check
-typedef struct _ST_TIME_ELAPSED_
-{
- ULONG64 ul64TimeElapsedSinceNetEntry;
- UINT32 uiReserved[4]; //By chance if required for future proofing
-}ST_TIME_ELAPSED,*PST_TIME_ELAPSED;
+struct bcm_time_elapsed {
+ unsigned long long ul64TimeElapsedSinceNetEntry;
+ u32 uiReserved[4];
+};
enum {
- WIMAX_IDX=0, /*To access WiMAX chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE*/
- HOST_IDX, /*To access Host chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE*/
- MAX_IDX
+ WIMAX_IDX = 0, /* To access WiMAX chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE */
+ HOST_IDX, /* To access Host chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE */
+ MAX_IDX
};
-typedef struct stGPIOMultiInfo
-{
- UINT uiGPIOCommand; /* 1 for set and 0 for get*/
- UINT uiGPIOMask; /* set the correspondig bit to 1 to access GPIO*/
- UINT uiGPIOValue; /* 0 or 1; value to be set when command is 1.*/
-}__attribute__((packed))GPIO_MULTI_INFO , *PGPIO_MULTI_INFO;
-typedef struct stGPIOMultiMode
-{
- UINT uiGPIOMode; /* 1 for OUT mode, 0 for IN mode*/
- UINT uiGPIOMask; /* GPIO mask to set mode*/
-}__attribute__((packed))GPIO_MULTI_MODE, *PGPIO_MULTI_MODE;
+struct bcm_gpio_multi_info {
+ unsigned int uiGPIOCommand; /* 1 for set and 0 for get */
+ unsigned int uiGPIOMask; /* set the correspondig bit to 1 to access GPIO */
+ unsigned int uiGPIOValue; /* 0 or 1; value to be set when command is 1. */
+} __packed;
+struct bcm_gpio_multi_mode {
+ unsigned int uiGPIOMode; /* 1 for OUT mode, 0 for IN mode */
+ unsigned int uiGPIOMask; /* GPIO mask to set mode */
+} __packed;
#endif
diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c
index 6e8a3279698..877cf0b2bee 100644
--- a/drivers/staging/bcm/LeakyBucket.c
+++ b/drivers/staging/bcm/LeakyBucket.c
@@ -21,10 +21,12 @@ static VOID UpdateTokenCount(register struct bcm_mini_adapter *Adapter)
INT i = 0;
struct timeval tv;
- BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "=====>\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
+ "=====>\n");
if(NULL == Adapter)
{
- BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Adapter found NULL!\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS,
+ DBG_LVL_ALL, "Adapter found NULL!\n");
return;
}
diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c
index f13a9582a82..c92078e7fe8 100644
--- a/drivers/staging/bcm/Misc.c
+++ b/drivers/staging/bcm/Misc.c
@@ -1,14 +1,14 @@
#include "headers.h"
static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, unsigned int loc);
-static VOID doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter);
+static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter);
static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer);
static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter);
static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter);
-static VOID default_wimax_protocol_initialize(struct bcm_mini_adapter *Adapter)
+static void default_wimax_protocol_initialize(struct bcm_mini_adapter *Adapter)
{
- UINT uiLoopIndex;
+ unsigned int uiLoopIndex;
for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES-1; uiLoopIndex++) {
Adapter->PackInfo[uiLoopIndex].uiThreshold = TX_PACKET_THRESHOLD;
@@ -24,10 +24,10 @@ static VOID default_wimax_protocol_initialize(struct bcm_mini_adapter *Adapter)
return;
}
-INT InitAdapter(struct bcm_mini_adapter *psAdapter)
+int InitAdapter(struct bcm_mini_adapter *psAdapter)
{
int i = 0;
- INT Status = STATUS_SUCCESS;
+ int Status = STATUS_SUCCESS;
BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Initialising Adapter = %p", psAdapter);
if (psAdapter == NULL) {
@@ -93,7 +93,7 @@ INT InitAdapter(struct bcm_mini_adapter *psAdapter)
return STATUS_SUCCESS;
}
-VOID AdapterFree(struct bcm_mini_adapter *Adapter)
+void AdapterFree(struct bcm_mini_adapter *Adapter)
{
int count;
beceem_protocol_reset(Adapter);
@@ -216,12 +216,12 @@ exit_download:
* Logical Adapter
* Control Packet Buffer
*/
-INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, PVOID ioBuffer)
+int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer)
{
struct bcm_leader *pLeader = NULL;
- INT Status = 0;
- unsigned char *ctrl_buff = NULL;
- UINT pktlen = 0;
+ int Status = 0;
+ unsigned char *ctrl_buff;
+ unsigned int pktlen = 0;
struct bcm_link_request *pLinkReq = NULL;
PUCHAR pucAddIndication = NULL;
@@ -253,7 +253,7 @@ INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, PVOID ioBuffer)
return STATUS_FAILURE;
}
- if (TRUE == Adapter->bShutStatus) {
+ 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) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Waking up for the First Time..\n");
@@ -275,7 +275,7 @@ INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, PVOID ioBuffer)
}
}
- if (TRUE == Adapter->IdleMode) {
+ if (Adapter->IdleMode == TRUE) {
/* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle mode ... hence\n"); */
if (pLeader->Status == LINK_UP_CONTROL_REQ || pLeader->Status == 0x80 ||
pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ) {
@@ -325,64 +325,66 @@ INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, PVOID ioBuffer)
pktlen = pLeader->PLength;
ctrl_buff = (char *)Adapter->txctlpacket[atomic_read(&Adapter->index_wr_txcntrlpkt)%MAX_CNTRL_PKTS];
+ if (!ctrl_buff) {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "mem allocation Failed");
+ return -ENOMEM;
+ }
+
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Control packet to be taken =%d and address is =%pincoming address is =%p and packet len=%x",
atomic_read(&Adapter->index_wr_txcntrlpkt), ctrl_buff, ioBuffer, pktlen);
- if (ctrl_buff) {
- if (pLeader) {
- if ((pLeader->Status == 0x80) ||
- (pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ)) {
- /*
- * Restructure the DSX message to handle Multiple classifier Support
- * Write the Service Flow param Structures directly to the target
- * and embed the pointers in the DSX messages sent to target.
- */
- /* Lets store the current length of the control packet we are transmitting */
- pucAddIndication = (PUCHAR)ioBuffer + LEADER_SIZE;
- pktlen = pLeader->PLength;
- Status = StoreCmControlResponseMessage(Adapter, pucAddIndication, &pktlen);
- if (Status != 1) {
- ClearTargetDSXBuffer(Adapter, ((stLocalSFAddIndicationAlt *)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;
- }
- /*
- * update the leader to use the new length
- * The length of the control packet is length of message being sent + Leader length
- */
- pLeader->PLength = pktlen;
+
+ if (pLeader) {
+ if ((pLeader->Status == 0x80) ||
+ (pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ)) {
+ /*
+ * Restructure the DSX message to handle Multiple classifier Support
+ * Write the Service Flow param Structures directly to the target
+ * and embed the pointers in the DSX messages sent to target.
+ */
+ /* Lets store the current length of the control packet we are transmitting */
+ pucAddIndication = (PUCHAR)ioBuffer + LEADER_SIZE;
+ pktlen = pLeader->PLength;
+ Status = StoreCmControlResponseMessage(Adapter, pucAddIndication, &pktlen);
+ if (Status != 1) {
+ 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;
}
+ /*
+ * update the leader to use the new length
+ * The length of the control packet is length of message being sent + Leader length
+ */
+ pLeader->PLength = pktlen;
}
-
- if (pktlen + LEADER_SIZE > MAX_CNTL_PKT_SIZE)
- return -EINVAL;
-
- memset(ctrl_buff, 0, pktlen+LEADER_SIZE);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength);
- *(struct bcm_leader *)ctrl_buff = *pLeader;
- memcpy(ctrl_buff + LEADER_SIZE, ((PUCHAR)ioBuffer + LEADER_SIZE), pLeader->PLength);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet");
-
- /* Update the statistics counters */
- spin_lock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock);
- Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost += pLeader->PLength;
- Adapter->PackInfo[HiPriority].uiCurrentPacketsOnHost++;
- atomic_inc(&Adapter->TotalPacketCount);
- spin_unlock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock);
- Adapter->PackInfo[HiPriority].bValid = TRUE;
-
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "CurrBytesOnHost: %x bValid: %x",
- Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost,
- Adapter->PackInfo[HiPriority].bValid);
- Status = STATUS_SUCCESS;
- /*Queue the packet for transmission */
- atomic_inc(&Adapter->index_wr_txcntrlpkt);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Calling transmit_packets");
- atomic_set(&Adapter->TxPktAvail, 1);
- wake_up(&Adapter->tx_packet_wait_queue);
- } else {
- Status = -ENOMEM;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "mem allocation Failed");
}
+
+ if (pktlen + LEADER_SIZE > MAX_CNTL_PKT_SIZE)
+ return -EINVAL;
+
+ memset(ctrl_buff, 0, pktlen+LEADER_SIZE);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength);
+ *(struct bcm_leader *)ctrl_buff = *pLeader;
+ memcpy(ctrl_buff + LEADER_SIZE, ((PUCHAR)ioBuffer + LEADER_SIZE), pLeader->PLength);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet");
+
+ /* Update the statistics counters */
+ spin_lock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock);
+ Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost += pLeader->PLength;
+ Adapter->PackInfo[HiPriority].uiCurrentPacketsOnHost++;
+ atomic_inc(&Adapter->TotalPacketCount);
+ spin_unlock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock);
+ Adapter->PackInfo[HiPriority].bValid = TRUE;
+
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "CurrBytesOnHost: %x bValid: %x",
+ Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost,
+ Adapter->PackInfo[HiPriority].bValid);
+ Status = STATUS_SUCCESS;
+ /*Queue the packet for transmission */
+ atomic_inc(&Adapter->index_wr_txcntrlpkt);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Calling transmit_packets");
+ atomic_set(&Adapter->TxPktAvail, 1);
+ wake_up(&Adapter->tx_packet_wait_queue);
+
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<====");
return Status;
}
@@ -397,7 +399,7 @@ INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, PVOID ioBuffer)
*
* Returns - None.
*******************************************************************/
-VOID LinkMessage(struct bcm_mini_adapter *Adapter)
+void LinkMessage(struct bcm_mini_adapter *Adapter)
{
struct bcm_link_request *pstLinkRequest = NULL;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>");
@@ -448,11 +450,11 @@ VOID LinkMessage(struct bcm_mini_adapter *Adapter)
*
* Returns - None.
************************************************************************/
-VOID StatisticsResponse(struct bcm_mini_adapter *Adapter, PVOID pvBuffer)
+void StatisticsResponse(struct bcm_mini_adapter *Adapter, void *pvBuffer)
{
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>", __func__);
Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (UINT)Adapter->StatisticsPointer);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (unsigned int)Adapter->StatisticsPointer);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====", __func__);
return;
}
@@ -467,7 +469,7 @@ VOID StatisticsResponse(struct bcm_mini_adapter *Adapter, PVOID pvBuffer)
*
* Returns - None.
***********************************************************************/
-VOID LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer)
+void LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer)
{
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "=====>");
@@ -543,7 +545,7 @@ VOID LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuff
void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
{
- INT status = 0, NVMAccess = 0, lowPwrAbortMsg = 0;
+ int status = 0, NVMAccess = 0, lowPwrAbortMsg = 0;
struct timeval tv;
struct bcm_link_request stIdleResponse = {{0} };
memset(&tv, 0, sizeof(tv));
@@ -583,7 +585,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
/* Wait for the LED to TURN OFF before sending ACK response */
if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
- INT iRetVal = 0;
+ int iRetVal = 0;
/* Wake the LED Thread with IDLEMODE_ENTER State */
Adapter->DriverState = LOWPOWER_MODE_ENTER;
@@ -609,7 +611,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
up(&Adapter->rdmwrmsync);
/* Killing all URBS. */
if (Adapter->bDoSuspend == TRUE)
- Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
+ Bcm_kill_all_URBs((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
} else {
Adapter->bPreparingForLowPowerMode = FALSE;
}
@@ -625,7 +627,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
if ((status != STATUS_SUCCESS)) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "fail to send the Idle mode Request\n");
Adapter->bPreparingForLowPowerMode = FALSE;
- StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
+ StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
}
do_gettimeofday(&tv);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "IdleMode Msg submitter to Q :%ld ms", tv.tv_sec * 1000 + tv.tv_usec / 1000);
@@ -640,11 +642,11 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
*
* Returns - None.
*******************************************************************/
-VOID DumpPackInfo(struct bcm_mini_adapter *Adapter)
+void DumpPackInfo(struct bcm_mini_adapter *Adapter)
{
- UINT uiLoopIndex = 0;
- UINT uiIndex = 0;
- UINT uiClsfrIndex = 0;
+ unsigned int uiLoopIndex = 0;
+ unsigned int uiIndex = 0;
+ unsigned int uiClsfrIndex = 0;
struct bcm_classifier_rule *pstClassifierEntry = NULL;
for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) {
@@ -776,11 +778,11 @@ int reset_card_proc(struct bcm_mini_adapter *ps_adapter)
{
int retval = STATUS_SUCCESS;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
+ struct bcm_interface_adapter *psIntfAdapter = NULL;
unsigned int value = 0, uiResetValue = 0;
int bytes;
- psIntfAdapter = ((PS_INTERFACE_ADAPTER)(ps_adapter->pvInterfaceAdapter));
+ psIntfAdapter = ((struct bcm_interface_adapter *)(ps_adapter->pvInterfaceAdapter));
ps_adapter->bDDRInitDone = FALSE;
if (ps_adapter->chip_id >= T3LPB) {
@@ -920,7 +922,7 @@ int run_card_proc(struct bcm_mini_adapter *ps_adapter)
int InitCardAndDownloadFirmware(struct bcm_mini_adapter *ps_adapter)
{
int status;
- UINT value = 0;
+ unsigned int value = 0;
/*
* Create the threads first and then download the
* Firm/DDR Settings..
@@ -1088,7 +1090,7 @@ static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter)
void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter)
{
- UINT uiHostDrvrCfg6 = 0, uiEEPROMFlag = 0;
+ unsigned int uiHostDrvrCfg6 = 0, uiEEPROMFlag = 0;
if (ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE) {
pr_info(DRV_NAME ": AutoSyncup is Disabled\n");
@@ -1144,9 +1146,9 @@ void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter)
doPowerAutoCorrection(Adapter);
}
-static VOID doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter)
+static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter)
{
- UINT reporting_mode;
+ unsigned int reporting_mode;
reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) & 0x02;
psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1);
@@ -1175,26 +1177,26 @@ static VOID doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter)
}
}
-static void convertEndian(B_UINT8 rwFlag, PUINT puiBuffer, UINT uiByteCount)
+static void convertEndian(unsigned char rwFlag, unsigned int *puiBuffer, unsigned int uiByteCount)
{
- UINT uiIndex = 0;
+ unsigned int uiIndex = 0;
if (RWM_WRITE == rwFlag) {
- for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++)
+ for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(unsigned int)); uiIndex++)
puiBuffer[uiIndex] = htonl(puiBuffer[uiIndex]);
} else {
- for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++)
+ for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(unsigned int)); uiIndex++)
puiBuffer[uiIndex] = ntohl(puiBuffer[uiIndex]);
}
}
-int rdm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
+int rdm(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize)
{
return Adapter->interface_rdm(Adapter->pvInterfaceAdapter,
uiAddress, pucBuff, sSize);
}
-int wrm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
+int wrm(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize)
{
int iRetVal;
@@ -1203,25 +1205,25 @@ int wrm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t
return iRetVal;
}
-int wrmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
+int wrmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size)
{
convertEndian(RWM_WRITE, pucBuff, size);
return wrm(Adapter, uiAddress, (PUCHAR)pucBuff, size);
}
-int rdmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
+int rdmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size)
{
- INT uiRetVal = 0;
+ int uiRetVal = 0;
uiRetVal = rdm(Adapter, uiAddress, (PUCHAR)pucBuff, size);
- convertEndian(RWM_READ, (PUINT)pucBuff, size);
+ convertEndian(RWM_READ, (unsigned int *)pucBuff, size);
return uiRetVal;
}
-int wrmWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
+int wrmWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize)
{
- INT status = STATUS_SUCCESS;
+ int status = STATUS_SUCCESS;
down(&Adapter->rdmwrmsync);
if ((Adapter->IdleMode == TRUE) ||
@@ -1238,7 +1240,7 @@ exit:
return status;
}
-int wrmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
+int wrmaltWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size)
{
int iRetVal = STATUS_SUCCESS;
@@ -1258,9 +1260,9 @@ exit:
return iRetVal;
}
-int rdmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
+int rdmaltWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size)
{
- INT uiRetVal = STATUS_SUCCESS;
+ int uiRetVal = STATUS_SUCCESS;
down(&Adapter->rdmwrmsync);
if ((Adapter->IdleMode == TRUE) ||
@@ -1277,13 +1279,13 @@ exit:
return uiRetVal;
}
-static VOID HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter)
+static void HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter)
{
int clear_abort_pattern = 0, Status = 0;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n");
/* target has woken up From Shut Down */
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Clearing Shut Down Software abort pattern\n");
- Status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, (PUINT)&clear_abort_pattern, sizeof(clear_abort_pattern));
+ Status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, (unsigned int *)&clear_abort_pattern, sizeof(clear_abort_pattern));
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "WRM to SW_ABORT_IDLEMODE_LOC failed with err:%d", Status);
return;
@@ -1306,11 +1308,11 @@ static VOID HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter)
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n");
}
-static VOID SendShutModeResponse(struct bcm_mini_adapter *Adapter)
+static void SendShutModeResponse(struct bcm_mini_adapter *Adapter)
{
struct bcm_link_request stShutdownResponse;
- UINT NVMAccess = 0, lowPwrAbortMsg = 0;
- UINT Status = 0;
+ unsigned int NVMAccess = 0, lowPwrAbortMsg = 0;
+ unsigned int Status = 0;
memset(&stShutdownResponse, 0, sizeof(struct bcm_link_request));
stShutdownResponse.Leader.Status = LINK_UP_CONTROL_REQ;
@@ -1346,7 +1348,7 @@ static VOID SendShutModeResponse(struct bcm_mini_adapter *Adapter)
/* Wait for the LED to TURN OFF before sending ACK response */
if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
- INT iRetVal = 0;
+ int iRetVal = 0;
/* Wake the LED Thread with LOWPOWER_MODE_ENTER State */
Adapter->DriverState = LOWPOWER_MODE_ENTER;
@@ -1370,7 +1372,7 @@ static VOID SendShutModeResponse(struct bcm_mini_adapter *Adapter)
up(&Adapter->rdmwrmsync);
/* Killing all URBS. */
if (Adapter->bDoSuspend == TRUE)
- Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
+ Bcm_kill_all_URBs((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
} else {
Adapter->bPreparingForLowPowerMode = FALSE;
}
@@ -1386,13 +1388,13 @@ static VOID SendShutModeResponse(struct bcm_mini_adapter *Adapter)
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;
- StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
+ StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
}
}
static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer)
{
- B_UINT32 uiResetValue = 0;
+ unsigned int uiResetValue = 0;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n");
@@ -1412,14 +1414,14 @@ static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR p
}
SendShutModeResponse(Adapter);
- BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "ShutDownModeResponse:Notification received: Sending the response(Ack/Nack)\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "ShutDownModeResponse:Notification received: Sending the response(Ack/Nack)\n");
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n");
return;
}
-VOID ResetCounters(struct bcm_mini_adapter *Adapter)
+void ResetCounters(struct bcm_mini_adapter *Adapter)
{
beceem_protocol_reset(Adapter);
Adapter->CurrNumRecvDescs = 0;
@@ -1437,7 +1439,7 @@ VOID ResetCounters(struct bcm_mini_adapter *Adapter)
struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIP)
{
- UINT uiIndex = 0;
+ unsigned int uiIndex = 0;
for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) {
if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) &&
(Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) &&
@@ -1451,7 +1453,7 @@ struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter,
void AddFragIPClsEntry(struct bcm_mini_adapter *Adapter, struct bcm_fragmented_packet_info *psFragPktInfo)
{
- UINT uiIndex = 0;
+ unsigned int uiIndex = 0;
for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) {
if (!Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) {
memcpy(&Adapter->astFragmentedPktClassifierTable[uiIndex], psFragPktInfo, sizeof(struct bcm_fragmented_packet_info));
@@ -1462,7 +1464,7 @@ void AddFragIPClsEntry(struct bcm_mini_adapter *Adapter, struct bcm_fragmented_p
void DelFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIp)
{
- UINT uiIndex = 0;
+ unsigned int uiIndex = 0;
for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) {
if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) &&
(Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) &&
@@ -1474,7 +1476,7 @@ void DelFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentificati
void update_per_cid_rx(struct bcm_mini_adapter *Adapter)
{
- UINT qindex = 0;
+ unsigned int qindex = 0;
if ((jiffies - Adapter->liDrainCalculated) < XSECONDS)
return;
@@ -1498,14 +1500,14 @@ void update_per_cid_rx(struct bcm_mini_adapter *Adapter)
void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter)
{
- INT iIndex = 0;
+ int iIndex = 0;
u32 uibuff[MAX_TARGET_DSX_BUFFERS];
int bytes;
if (!atomic_read(&Adapter->uiMBupdate))
return;
- bytes = rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS);
+ bytes = rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (unsigned int *)uibuff, sizeof(unsigned int) * MAX_TARGET_DSX_BUFFERS);
if (bytes < 0) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm failed\n");
return;
@@ -1522,7 +1524,7 @@ void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter)
atomic_set(&Adapter->uiMBupdate, FALSE);
}
-void flush_queue(struct bcm_mini_adapter *Adapter, UINT iQIndex)
+void flush_queue(struct bcm_mini_adapter *Adapter, unsigned int iQIndex)
{
struct sk_buff *PacketToDrop = NULL;
struct net_device_stats *netstats = &Adapter->dev->stats;
@@ -1573,6 +1575,6 @@ static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter)
for (i = 0; i < HiPriority; i++) {
/* resetting only the first size (S_MIBS_SERVICEFLOW_TABLE) for the SF. */
/* It is same between MIBs and SF. */
- memset(&Adapter->PackInfo[i].stMibsExtServiceFlowTable, 0, sizeof(S_MIBS_EXTSERVICEFLOW_PARAMETERS));
+ memset(&Adapter->PackInfo[i].stMibsExtServiceFlowTable, 0, sizeof(struct bcm_mibs_parameters));
}
}
diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h
index 3ec8f800a5b..90dbe0f4785 100644
--- a/drivers/staging/bcm/Prototypes.h
+++ b/drivers/staging/bcm/Prototypes.h
@@ -79,17 +79,17 @@ int rdm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t
int wrm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
-int wrmalt (struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
+int wrmalt (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
-int rdmalt (struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
+int rdmalt (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
int get_dsx_sf_data_to_application(struct bcm_mini_adapter *Adapter, UINT uiSFId, void __user * user_buffer);
void SendIdleModeResponse(struct bcm_mini_adapter *Adapter);
-int ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, S_MIBS_HOST_STATS_MIBS *buf);
-void GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *ioBuffer, struct bcm_tarang_data *pTarang);
+int ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, struct bcm_host_stats_mibs *buf);
+void GetDroppedAppCntrlPktMibs(struct bcm_host_stats_mibs *ioBuffer, struct bcm_tarang_data *pTarang);
void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter);
int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo);
@@ -161,14 +161,14 @@ INT BeceemNVMWrite(
INT BcmInitNVM(struct bcm_mini_adapter *Adapter);
INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter,UINT uiSectorSize);
-BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section);
+BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section);
-INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITMAP psFlash2xBitMap);
+INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap);
INT BcmFlash2xBulkWrite(
struct bcm_mini_adapter *Adapter,
PUINT pBuffer,
- FLASH2X_SECTION_VAL eFlashSectionVal,
+ enum bcm_flash2x_section_val eFlashSectionVal,
UINT uiOffset,
UINT uiNumBytes,
UINT bVerify);
@@ -176,24 +176,24 @@ INT BcmFlash2xBulkWrite(
INT BcmFlash2xBulkRead(
struct bcm_mini_adapter *Adapter,
PUINT pBuffer,
- FLASH2X_SECTION_VAL eFlashSectionVal,
+ enum bcm_flash2x_section_val eFlashSectionVal,
UINT uiOffsetWithinSectionVal,
UINT uiNumBytes);
-INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
+INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal);
-INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal);
+INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectVal);
INT BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter);
INT BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter);
-INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectStrut);
-INT BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
-INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
-INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRITE psFlash2xReadWrite);
+INT BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut);
+INT BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
+INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal);
+INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite);
INT IsFlash2x(struct bcm_mini_adapter *Adapter);
INT BcmCopySection(struct bcm_mini_adapter *Adapter,
- FLASH2X_SECTION_VAL SrcSection,
- FLASH2X_SECTION_VAL DstSection,
+ enum bcm_flash2x_section_val SrcSection,
+ enum bcm_flash2x_section_val DstSection,
UINT offset,
UINT numOfBytes);
@@ -203,8 +203,8 @@ BOOLEAN IsNonCDLessDevice(struct bcm_mini_adapter *Adapter);
VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter,PUINT puiBuffer);
-int wrmaltWithLock (struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
-int rdmaltWithLock (struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
+int wrmaltWithLock (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
+int rdmaltWithLock (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
int wrmWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
INT buffDnldVerify(struct bcm_mini_adapter *Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c
index 27e8c890777..f8dc3e20b47 100644
--- a/drivers/staging/bcm/Transmit.c
+++ b/drivers/staging/bcm/Transmit.c
@@ -205,7 +205,7 @@ int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter obje
if (Adapter->bEndPointHalted == TRUE) {
Bcm_clear_halt_of_endpoints(Adapter);
Adapter->bEndPointHalted = FALSE;
- StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
+ StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
}
if (Adapter->LinkUpStatus && !Adapter->IdleMode) {
diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h
index 990e809e968..8683c2d4276 100644
--- a/drivers/staging/bcm/cntrl_SignalingInterface.h
+++ b/drivers/staging/bcm/cntrl_SignalingInterface.h
@@ -36,91 +36,91 @@
struct bcm_packet_class_rules {
/* 16bit UserPriority Of The Service Flow */
- B_UINT16 u16UserPriority;
+ u16 u16UserPriority;
/* 16bit VLANID Of The Service Flow */
- B_UINT16 u16VLANID;
+ u16 u16VLANID;
/* 16bit Packet Classification RuleIndex Of The Service Flow */
- B_UINT16 u16PacketClassificationRuleIndex;
+ u16 u16PacketClassificationRuleIndex;
/* 8bit Classifier Rule Priority Of The Service Flow */
- B_UINT8 u8ClassifierRulePriority;
+ u8 u8ClassifierRulePriority;
/* Length of IP TypeOfService field */
- B_UINT8 u8IPTypeOfServiceLength;
+ u8 u8IPTypeOfServiceLength;
/* 3bytes IP TypeOfService */
- B_UINT8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH];
+ u8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH];
/* Protocol used in classification of Service Flow */
- B_UINT8 u8Protocol;
+ u8 u8Protocol;
/* Length of IP Masked Source Address */
- B_UINT8 u8IPMaskedSourceAddressLength;
+ u8 u8IPMaskedSourceAddressLength;
/* IP Masked Source Address used in classification for the Service Flow */
- B_UINT8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH];
+ u8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH];
/* Length of IP Destination Address */
- B_UINT8 u8IPDestinationAddressLength;
+ u8 u8IPDestinationAddressLength;
/* IP Destination Address used in classification for the Service Flow */
- B_UINT8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH];
+ u8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH];
/* Length of Protocol Source Port Range */
- B_UINT8 u8ProtocolSourcePortRangeLength;
+ u8 u8ProtocolSourcePortRangeLength;
/* Protocol Source Port Range used in the Service Flow */
- B_UINT8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH];
+ u8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH];
/* Length of Protocol Dest Port Range */
- B_UINT8 u8ProtocolDestPortRangeLength;
+ u8 u8ProtocolDestPortRangeLength;
/* Protocol Dest Port Range used in the Service Flow */
- B_UINT8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH];
+ u8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH];
/* Length of Ethernet Destination MAC Address */
- B_UINT8 u8EthernetDestMacAddressLength;
+ u8 u8EthernetDestMacAddressLength;
/* Ethernet Destination MAC Address used in classification of the Service Flow */
- B_UINT8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH];
+ u8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH];
/* Length of Ethernet Source MAC Address */
- B_UINT8 u8EthernetSourceMACAddressLength;
+ u8 u8EthernetSourceMACAddressLength;
/* Ethernet Source MAC Address used in classification of the Service Flow */
- B_UINT8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH];
+ u8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH];
/* Length of Ethertype */
- B_UINT8 u8EthertypeLength;
+ u8 u8EthertypeLength;
/* 3bytes Ethertype Of The Service Flow */
- B_UINT8 u8Ethertype[NUM_ETHERTYPE_BYTES];
+ u8 u8Ethertype[NUM_ETHERTYPE_BYTES];
/* 8bit Associated PHSI Of The Service Flow */
- B_UINT8 u8AssociatedPHSI;
+ u8 u8AssociatedPHSI;
/* Length of Vendor Specific Classifier Param length Of The Service Flow */
- B_UINT8 u8VendorSpecificClassifierParamLength;
+ u8 u8VendorSpecificClassifierParamLength;
/* Vendor Specific Classifier Param Of The Service Flow */
- B_UINT8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH];
+ u8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH];
/* Length Of IPv6 Flow Lable of the Service Flow */
- B_UINT8 u8IPv6FlowLableLength;
+ u8 u8IPv6FlowLableLength;
/* IPv6 Flow Lable Of The Service Flow */
- B_UINT8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES];
+ u8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES];
/* Action associated with the classifier rule */
- B_UINT8 u8ClassifierActionRule;
- B_UINT16 u16ValidityBitMap;
+ u8 u8ClassifierActionRule;
+ u16 u16ValidityBitMap;
};
struct bcm_phs_rules {
/* 8bit PHS Index Of The Service Flow */
- B_UINT8 u8PHSI;
+ u8 u8PHSI;
/* PHSF Length Of The Service Flow */
- B_UINT8 u8PHSFLength;
+ u8 u8PHSFLength;
/* String of bytes containing header information to be suppressed by the sending CS and reconstructed by the receiving CS */
- B_UINT8 u8PHSF[MAX_PHS_LENGTHS];
+ u8 u8PHSF[MAX_PHS_LENGTHS];
/* PHSM Length Of The Service Flow */
- B_UINT8 u8PHSMLength;
+ u8 u8PHSMLength;
/* PHS Mask for the SF */
- B_UINT8 u8PHSM[MAX_PHS_LENGTHS];
+ u8 u8PHSM[MAX_PHS_LENGTHS];
/* 8bit Total number of bytes to be suppressed for the Service Flow */
- B_UINT8 u8PHSS;
+ u8 u8PHSS;
/* 8bit Indicates whether or not Packet Header contents need to be verified prior to suppression */
- B_UINT8 u8PHSV;
+ u8 u8PHSV;
/* Vendor Specific PHS param Length Of The Service Flow */
- B_UINT8 u8VendorSpecificPHSParamsLength;
+ u8 u8VendorSpecificPHSParamsLength;
/* Vendor Specific PHS param Of The Service Flow */
- B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH];
- B_UINT8 u8Padding[2];
+ u8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH];
+ u8 u8Padding[2];
};
struct bcm_convergence_types {
/* 8bit Phs Classfier Action Of The Service Flow */
- B_UINT8 u8ClassfierDSCAction;
+ u8 u8ClassfierDSCAction;
/* 8bit Phs DSC Action Of The Service Flow */
- B_UINT8 u8PhsDSCAction;
+ u8 u8PhsDSCAction;
/* 16bit Padding */
- B_UINT8 u8Padding[2];
+ u8 u8Padding[2];
/* Packet classification rules structure */
struct bcm_packet_class_rules cCPacketClassificationRule;
/* Payload header suppression rules structure */
@@ -129,118 +129,118 @@ struct bcm_convergence_types {
struct bcm_connect_mgr_params {
/* 32bitSFID Of The Service Flow */
- B_UINT32 u32SFID;
+ u32 u32SFID;
/* 32bit Maximum Sustained Traffic Rate of the Service Flow */
- B_UINT32 u32MaxSustainedTrafficRate;
+ u32 u32MaxSustainedTrafficRate;
/* 32bit Maximum Traffic Burst allowed for the Service Flow */
- B_UINT32 u32MaxTrafficBurst;
+ u32 u32MaxTrafficBurst;
/* 32bit Minimum Reserved Traffic Rate of the Service Flow */
- B_UINT32 u32MinReservedTrafficRate;
+ u32 u32MinReservedTrafficRate;
/* 32bit Tolerated Jitter of the Service Flow */
- B_UINT32 u32ToleratedJitter;
+ u32 u32ToleratedJitter;
/* 32bit Maximum Latency of the Service Flow */
- B_UINT32 u32MaximumLatency;
+ u32 u32MaximumLatency;
/* 16bitCID Of The Service Flow */
- B_UINT16 u16CID;
+ u16 u16CID;
/* 16bit SAID on which the service flow being set up shall be mapped */
- B_UINT16 u16TargetSAID;
+ u16 u16TargetSAID;
/* 16bit ARQ window size negotiated */
- B_UINT16 u16ARQWindowSize;
+ u16 u16ARQWindowSize;
/* 16bit Total Tx delay incl sending, receiving & processing delays */
- B_UINT16 u16ARQRetryTxTimeOut;
+ u16 u16ARQRetryTxTimeOut;
/* 16bit Total Rx delay incl sending, receiving & processing delays */
- B_UINT16 u16ARQRetryRxTimeOut;
+ u16 u16ARQRetryRxTimeOut;
/* 16bit ARQ block lifetime */
- B_UINT16 u16ARQBlockLifeTime;
+ u16 u16ARQBlockLifeTime;
/* 16bit ARQ Sync loss timeout */
- B_UINT16 u16ARQSyncLossTimeOut;
+ u16 u16ARQSyncLossTimeOut;
/* 16bit ARQ Purge timeout */
- B_UINT16 u16ARQRxPurgeTimeOut;
+ u16 u16ARQRxPurgeTimeOut;
/* TODO::Remove this once we move to a new CORR2 driver
* brief Size of an ARQ block
*/
- B_UINT16 u16ARQBlockSize;
+ u16 u16ARQBlockSize;
/* #endif */
/* 16bit Nominal interval b/w consecutive SDU arrivals at MAC SAP */
- B_UINT16 u16SDUInterArrivalTime;
+ u16 u16SDUInterArrivalTime;
/* 16bit Specifies the time base for rate measurement */
- B_UINT16 u16TimeBase;
+ u16 u16TimeBase;
/* 16bit Interval b/w Successive Grant oppurtunities */
- B_UINT16 u16UnsolicitedGrantInterval;
+ u16 u16UnsolicitedGrantInterval;
/* 16bit Interval b/w Successive Polling grant oppurtunities */
- B_UINT16 u16UnsolicitedPollingInterval;
+ u16 u16UnsolicitedPollingInterval;
/* internal var to get the overhead */
- B_UINT16 u16MacOverhead;
+ u16 u16MacOverhead;
/* MBS contents Identifier */
- B_UINT16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH];
+ u16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH];
/* MBS contents Identifier length */
- B_UINT8 u8MBSContentsIDLength;
+ u8 u8MBSContentsIDLength;
/* ServiceClassName Length Of The Service Flow */
- B_UINT8 u8ServiceClassNameLength;
+ u8 u8ServiceClassNameLength;
/* 32bytes ServiceClassName Of The Service Flow */
- B_UINT8 u8ServiceClassName[32];
+ u8 u8ServiceClassName[32];
/* 8bit Indicates whether or not MBS service is requested for this Serivce Flow */
- B_UINT8 u8MBSService;
+ u8 u8MBSService;
/* 8bit QOS Parameter Set specifies proper application of QoS parameters to Provisioned, Admitted and Active sets */
- B_UINT8 u8QosParamSet;
+ u8 u8QosParamSet;
/* 8bit Traffic Priority Of the Service Flow */
- B_UINT8 u8TrafficPriority;
+ u8 u8TrafficPriority;
/* 8bit Uplink Grant Scheduling Type of The Service Flow */
- B_UINT8 u8ServiceFlowSchedulingType;
+ u8 u8ServiceFlowSchedulingType;
/* 8bit Request transmission Policy of the Service Flow */
- B_UINT8 u8RequesttransmissionPolicy;
+ u8 u8RequesttransmissionPolicy;
/* 8bit Specifies whether SDUs for this Service flow are of FixedLength or Variable length */
- B_UINT8 u8FixedLengthVSVariableLengthSDUIndicator;
+ u8 u8FixedLengthVSVariableLengthSDUIndicator;
/* 8bit Length of the SDU for a fixed length SDU service flow */
- B_UINT8 u8SDUSize;
+ u8 u8SDUSize;
/* 8bit Indicates whether or not ARQ is requested for this connection */
- B_UINT8 u8ARQEnable;
+ u8 u8ARQEnable;
/* < 8bit Indicates whether or not data has tobe delivered in order to higher layer */
- B_UINT8 u8ARQDeliverInOrder;
+ u8 u8ARQDeliverInOrder;
/* 8bit Receiver ARQ ACK processing time */
- B_UINT8 u8RxARQAckProcessingTime;
+ u8 u8RxARQAckProcessingTime;
/* 8bit Convergence Sublayer Specification Of The Service Flow */
- B_UINT8 u8CSSpecification;
+ u8 u8CSSpecification;
/* 8 bit Type of data delivery service */
- B_UINT8 u8TypeOfDataDeliveryService;
+ u8 u8TypeOfDataDeliveryService;
/* 8bit Specifies whether a service flow may generate Paging */
- B_UINT8 u8PagingPreference;
+ u8 u8PagingPreference;
/* 8bit Indicates the MBS Zone through which the connection or virtual connection is valid */
- B_UINT8 u8MBSZoneIdentifierassignment;
+ u8 u8MBSZoneIdentifierassignment;
/* 8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode */
- B_UINT8 u8TrafficIndicationPreference;
+ u8 u8TrafficIndicationPreference;
/* 8bit Speciifes the length of predefined Global QoS parameter set encoding for this SF */
- B_UINT8 u8GlobalServicesClassNameLength;
+ u8 u8GlobalServicesClassNameLength;
/* 6 byte Speciifes the predefined Global QoS parameter set encoding for this SF */
- B_UINT8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH];
+ u8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH];
/* 8bit Indicates whether or not SN feedback is enabled for the conn */
- B_UINT8 u8SNFeedbackEnabled;
+ u8 u8SNFeedbackEnabled;
/* Indicates the size of the Fragment Sequence Number for the connection */
- B_UINT8 u8FSNSize;
+ u8 u8FSNSize;
/* 8bit Number of CIDs in active BS list */
- B_UINT8 u8CIDAllocation4activeBSsLength;
+ u8 u8CIDAllocation4activeBSsLength;
/* CIDs of BS in the active list */
- B_UINT8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS];
+ u8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS];
/* Specifies if PDU extended subheader should be applied on every PDU on this conn */
- B_UINT8 u8PDUSNExtendedSubheader4HarqReordering;
+ u8 u8PDUSNExtendedSubheader4HarqReordering;
/* 8bit Specifies whether the connection uses HARQ or not */
- B_UINT8 u8HARQServiceFlows;
+ u8 u8HARQServiceFlows;
/* Specifies the length of Authorization token */
- B_UINT8 u8AuthTokenLength;
+ u8 u8AuthTokenLength;
/* Specifies the Authorization token */
- B_UINT8 u8AuthToken[AUTH_TOKEN_LENGTH];
+ u8 u8AuthToken[AUTH_TOKEN_LENGTH];
/* specifes Number of HARQ channels used to carry data length */
- B_UINT8 u8HarqChannelMappingLength;
+ u8 u8HarqChannelMappingLength;
/* specifes HARQ channels used to carry data */
- B_UINT8 u8HARQChannelMapping[NUM_HARQ_CHANNELS];
+ u8 u8HARQChannelMapping[NUM_HARQ_CHANNELS];
/* 8bit Length of Vendor Specific QoS Params */
- B_UINT8 u8VendorSpecificQoSParamLength;
+ u8 u8VendorSpecificQoSParamLength;
/* 1byte Vendor Specific QoS Param Of The Service Flow */
- B_UINT8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM];
+ u8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM];
/* indicates total classifiers in the SF */
- B_UINT8 u8TotalClassifiers; /* < Total number of valid classifiers */
- B_UINT8 bValid; /* < Validity flag */
- B_UINT8 u8Padding; /* < Padding byte */
+ u8 u8TotalClassifiers; /* < Total number of valid classifiers */
+ u8 bValid; /* < Validity flag */
+ u8 u8Padding; /* < Padding byte */
/*
* Structure for Convergence SubLayer Types with a maximum of 4 classifiers
*/
@@ -248,64 +248,64 @@ struct bcm_connect_mgr_params {
};
struct bcm_add_request {
- B_UINT8 u8Type; /* < Type */
- B_UINT8 eConnectionDir; /* < Connection direction */
+ u8 u8Type; /* < Type */
+ u8 eConnectionDir; /* < Connection direction */
/* brief 16 bit TID */
- B_UINT16 u16TID; /* < 16bit TID */
+ u16 u16TID; /* < 16bit TID */
/* brief 16bitCID */
- B_UINT16 u16CID; /* < 16bit CID */
+ u16 u16CID; /* < 16bit CID */
/* brief 16bitVCID */
- B_UINT16 u16VCID; /* < 16bit VCID */
+ u16 u16VCID; /* < 16bit VCID */
struct bcm_connect_mgr_params *psfParameterSet; /* < connection manager parameters */
};
struct bcm_add_indication {
- B_UINT8 u8Type; /* < Type */
- B_UINT8 eConnectionDir; /* < Connection Direction */
+ u8 u8Type; /* < Type */
+ u8 eConnectionDir; /* < Connection Direction */
/* brief 16 bit TID */
- B_UINT16 u16TID; /* < TID */
+ u16 u16TID; /* < TID */
/* brief 16bitCID */
- B_UINT16 u16CID; /* < 16bitCID */
+ u16 u16CID; /* < 16bitCID */
/* brief 16bitVCID */
- B_UINT16 u16VCID; /* < 16bitVCID */
+ u16 u16VCID; /* < 16bitVCID */
struct bcm_connect_mgr_params *psfAuthorizedSet; /* Authorized set of connection manager parameters */
struct bcm_connect_mgr_params *psfAdmittedSet; /* Admitted set of connection manager parameters */
struct bcm_connect_mgr_params *psfActiveSet; /* Activeset of connection manager parameters */
- B_UINT8 u8CC; /* <Confirmation Code */
- B_UINT8 u8Padd; /* < 8-bit Padding */
- B_UINT16 u16Padd; /* < 16 bit Padding */
+ u8 u8CC; /* <Confirmation Code */
+ u8 u8Padd; /* < 8-bit Padding */
+ u16 u16Padd; /* < 16 bit Padding */
};
struct bcm_del_request {
- B_UINT8 u8Type; /* < Type */
- B_UINT8 u8Padding; /* < Padding byte */
- B_UINT16 u16TID; /* < TID */
+ u8 u8Type; /* < Type */
+ u8 u8Padding; /* < Padding byte */
+ u16 u16TID; /* < TID */
/* brief 32bitSFID */
- B_UINT32 u32SFID; /* < SFID */
+ u32 u32SFID; /* < SFID */
};
struct bcm_del_indication {
- B_UINT8 u8Type; /* < Type */
- B_UINT8 u8Padding; /* < Padding */
- B_UINT16 u16TID; /* < TID */
+ u8 u8Type; /* < Type */
+ u8 u8Padding; /* < Padding */
+ u16 u16TID; /* < TID */
/* brief 16bitCID */
- B_UINT16 u16CID; /* < CID */
+ u16 u16CID; /* < CID */
/* brief 16bitVCID */
- B_UINT16 u16VCID; /* < VCID */
+ u16 u16VCID; /* < VCID */
/* brief 32bitSFID */
- B_UINT32 u32SFID; /* < SFID */
+ u32 u32SFID; /* < SFID */
/* brief 8bit Confirmation code */
- B_UINT8 u8ConfirmationCode; /* < Confirmation code */
- B_UINT8 u8Padding1[3]; /* < 3 byte Padding */
+ u8 u8ConfirmationCode; /* < Confirmation code */
+ u8 u8Padding1[3]; /* < 3 byte Padding */
};
struct bcm_stim_sfhostnotify {
- B_UINT32 SFID; /* SFID of the service flow */
- B_UINT16 newCID; /* the new/changed CID */
- B_UINT16 VCID; /* Get new Vcid if the flow has been made active in CID update TLV, but was inactive earlier or the orig vcid */
- B_UINT8 RetainSF; /* Indication to Host if the SF is to be retained or deleted; if TRUE-retain else delete */
- B_UINT8 QoSParamSet; /* QoS paramset of the retained SF */
- B_UINT16 u16reserved; /* For byte alignment */
+ u32 SFID; /* SFID of the service flow */
+ u16 newCID; /* the new/changed CID */
+ u16 VCID; /* Get new Vcid if the flow has been made active in CID update TLV, but was inactive earlier or the orig vcid */
+ u8 RetainSF; /* Indication to Host if the SF is to be retained or deleted; if TRUE-retain else delete */
+ u8 QoSParamSet; /* QoS paramset of the retained SF */
+ u16 u16reserved; /* For byte alignment */
};
#endif
diff --git a/drivers/staging/bcm/hostmibs.c b/drivers/staging/bcm/hostmibs.c
index 10361bb3505..3c5f4a5f037 100644
--- a/drivers/staging/bcm/hostmibs.c
+++ b/drivers/staging/bcm/hostmibs.c
@@ -9,7 +9,7 @@
#include "headers.h"
-INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, S_MIBS_HOST_STATS_MIBS *pstHostMibs)
+INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, struct bcm_host_stats_mibs *pstHostMibs)
{
S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
S_PHS_RULE *pstPhsRule = NULL;
@@ -31,7 +31,7 @@ INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, S_MIBS_HOST_STATS_MIBS
astClassifierTable[nClassifierIndex],
(PVOID) & Adapter->
astClassifierTable[nClassifierIndex],
- sizeof(S_MIBS_CLASSIFIER_RULE));
+ sizeof(struct bcm_mibs_classifier_rule));
}
/* Copy the SF Table */
@@ -39,7 +39,7 @@ INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, S_MIBS_HOST_STATS_MIBS
if (Adapter->PackInfo[nSfIndex].bValid) {
memcpy((PVOID) & pstHostMibs->astSFtable[nSfIndex],
(PVOID) & Adapter->PackInfo[nSfIndex],
- sizeof(S_MIBS_SERVICEFLOW_TABLE));
+ sizeof(struct bcm_mibs_table));
} else {
/* If index in not valid,
* don't process this for the PHS table.
@@ -94,16 +94,16 @@ INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, S_MIBS_HOST_STATS_MIBS
return STATUS_SUCCESS;
}
-VOID GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *pstHostMibs, struct bcm_tarang_data *pTarang)
+VOID GetDroppedAppCntrlPktMibs(struct bcm_host_stats_mibs *pstHostMibs, struct bcm_tarang_data *pTarang)
{
memcpy(&(pstHostMibs->stDroppedAppCntrlMsgs),
&(pTarang->stDroppedAppCntrlMsgs),
- sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
+ sizeof(struct bcm_mibs_dropped_cntrl_msg));
}
VOID CopyMIBSExtendedSFParameters(struct bcm_mini_adapter *Adapter, struct bcm_connect_mgr_params *psfLocalSet, UINT uiSearchRuleIndex)
{
- S_MIBS_EXTSERVICEFLOW_PARAMETERS *t = &Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable;
+ struct bcm_mibs_parameters *t = &Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable;
t->wmanIfSfid = psfLocalSet->u32SFID;
t->wmanIfCmnCpsMaxSustainedRate = psfLocalSet->u32MaxSustainedTrafficRate;
diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c
index b034eb5fa6b..eab676fe53a 100644
--- a/drivers/staging/bcm/nvm.c
+++ b/drivers/staging/bcm/nvm.c
@@ -14,25 +14,25 @@ static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter);
static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter);
static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter);
-static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
+static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset);
-static int IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Section);
-static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section);
+static int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section);
+static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section);
-static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd);
-static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd);
-static int ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso);
-static int ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso);
+static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd);
+static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd);
+static int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso);
+static int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso);
-static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
-static int CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
+static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
+static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiSectAlignAddr);
static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff,
- FLASH2X_SECTION_VAL eFlash2xSectionVal,
+ enum bcm_flash2x_section_val eFlash2xSectionVal,
unsigned int uiOffset, unsigned int uiNumBytes);
-static FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter);
-static FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter);
+static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter);
+static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter);
static int BeceemFlashBulkRead(
struct bcm_mini_adapter *Adapter,
@@ -2413,7 +2413,7 @@ static int ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo)
return STATUS_SUCCESS;
}
-static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section)
+static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
{
return (Adapter->uiVendorExtnFlag &&
(Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) &&
@@ -2660,14 +2660,14 @@ static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter)
/*
* BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given
* @Adapter : Drivers Private Data structure
- * @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
+ * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val
*
* Return value:-
* On success it return the start offset of the provided section val
* On Failure -returns STATUS_FAILURE
*/
-int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
+int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal)
{
/*
* Considering all the section for which end offset can be calculated or directly given
@@ -2752,14 +2752,14 @@ int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTIO
/*
* BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given
* @Adapter : Drivers Private Data structure
- * @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
+ * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val
*
* Return value:-
* On success it return the end offset of the provided section val
* On Failure -returns STATUS_FAILURE
*/
-int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
+int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
{
int SectEndOffset = 0;
@@ -2837,7 +2837,7 @@ int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_
* BcmFlash2xBulkRead:- Read API for Flash Map 2.x .
* @Adapter :Driver Private Data Structure
* @pBuffer : Buffer where data has to be put after reading
- * @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
+ * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val
* @uiOffsetWithinSectionVal :- Offset with in provided section
* @uiNumBytes : Number of Bytes for Read
*
@@ -2847,7 +2847,7 @@ int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_
int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter,
PUINT pBuffer,
- FLASH2X_SECTION_VAL eFlash2xSectionVal,
+ enum bcm_flash2x_section_val eFlash2xSectionVal,
unsigned int uiOffsetWithinSectionVal,
unsigned int uiNumBytes)
{
@@ -2898,7 +2898,7 @@ int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter,
* BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x.
* @Adapter :Driver Private Data Structure
* @pBuffer : Buffer From where data has to taken for writing
- * @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
+ * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val
* @uiOffsetWithinSectionVal :- Offset with in provided section
* @uiNumBytes : Number of Bytes for Write
*
@@ -2909,7 +2909,7 @@ int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter,
int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter,
PUINT pBuffer,
- FLASH2X_SECTION_VAL eFlash2xSectVal,
+ enum bcm_flash2x_section_val eFlash2xSectVal,
unsigned int uiOffset,
unsigned int uiNumBytes,
unsigned int bVerify)
@@ -2971,7 +2971,7 @@ int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter,
static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter)
{
- FLASH2X_SECTION_VAL uiHighestPriDSD = 0;
+ enum bcm_flash2x_section_val uiHighestPriDSD = 0;
uiHighestPriDSD = getHighestPriDSD(Adapter);
Adapter->eActiveDSD = uiHighestPriDSD;
@@ -3064,7 +3064,7 @@ B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset
return FALSE;
}
-static int BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap)
+static int BcmDumpFlash2xSectionBitMap(struct bcm_flash2x_bitmap *psFlash2xBitMap)
{
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
@@ -3099,11 +3099,11 @@ static int BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap)
* Failure:- negative error code
*/
-int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITMAP psFlash2xBitMap)
+int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap)
{
PFLASH2X_CS_INFO psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
- FLASH2X_SECTION_VAL uiHighestPriDSD = 0;
- FLASH2X_SECTION_VAL uiHighestPriISO = 0;
+ enum bcm_flash2x_section_val uiHighestPriDSD = 0;
+ enum bcm_flash2x_section_val uiHighestPriISO = 0;
BOOLEAN SetActiveDSDDone = FALSE;
BOOLEAN SetActiveISODone = FALSE;
@@ -3349,7 +3349,7 @@ int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM
*
*/
-int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal)
+int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectVal)
{
unsigned int SectImagePriority = 0;
int Status = STATUS_SUCCESS;
@@ -3529,10 +3529,10 @@ int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eF
*
*/
-int BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
+int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut)
{
PCHAR Buff = NULL;
- FLASH2X_SECTION_VAL eISOReadPart = 0, eISOWritePart = 0;
+ enum bcm_flash2x_section_val eISOReadPart = 0, eISOWritePart = 0;
unsigned int uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
unsigned int uiTotalDataToCopy = 0;
BOOLEAN IsThisHeaderSector = FALSE;
@@ -3813,7 +3813,7 @@ out:
* Failure :-Return negative error code
*/
-int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
+int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
{
int Status = STATUS_SUCCESS;
@@ -3841,7 +3841,7 @@ int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e
* Failure :-Return negative error code
*/
-int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
+int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal)
{
unsigned int uiSignature = 0;
unsigned int uiOffset = 0;
@@ -3901,7 +3901,7 @@ int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFl
* Return values:-Return TRUE is request is valid else FALSE.
*/
-int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRITE psFlash2xReadWrite)
+int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite)
{
unsigned int uiNumOfBytes = 0;
unsigned int uiSectStartOffset = 0;
@@ -4021,8 +4021,8 @@ static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter)
*/
int BcmCopySection(struct bcm_mini_adapter *Adapter,
- FLASH2X_SECTION_VAL SrcSection,
- FLASH2X_SECTION_VAL DstSection,
+ enum bcm_flash2x_section_val SrcSection,
+ enum bcm_flash2x_section_val DstSection,
unsigned int offset,
unsigned int numOfBytes)
{
@@ -4264,7 +4264,7 @@ static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset
return STATUS_SUCCESS;
}
-int ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd)
+int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
{
unsigned int uiDSDsig = 0;
/* unsigned int sigoffsetInMap = 0;
@@ -4289,7 +4289,7 @@ int ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd)
return uiDSDsig;
}
-int ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd)
+int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
{
/* unsigned int priOffsetInMap = 0 ; */
unsigned int uiDSDPri = STATUS_FAILURE;
@@ -4312,11 +4312,11 @@ int ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd)
return uiDSDPri;
}
-FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter)
+enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter)
{
int DSDHighestPri = STATUS_FAILURE;
int DsdPri = 0;
- FLASH2X_SECTION_VAL HighestPriDSD = 0;
+ enum bcm_flash2x_section_val HighestPriDSD = 0;
if (IsSectionWritable(Adapter, DSD2)) {
DSDHighestPri = ReadDSDPriority(Adapter, DSD2);
@@ -4344,7 +4344,7 @@ FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter)
return HighestPriDSD;
}
-int ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso)
+int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
{
unsigned int uiISOsig = 0;
/* unsigned int sigoffsetInMap = 0;
@@ -4367,7 +4367,7 @@ int ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso)
return uiISOsig;
}
-int ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso)
+int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
{
unsigned int ISOPri = STATUS_FAILURE;
if (IsSectionWritable(Adapter, iso)) {
@@ -4386,11 +4386,11 @@ int ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso)
return ISOPri;
}
-FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter)
+enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter)
{
int ISOHighestPri = STATUS_FAILURE;
int ISOPri = 0;
- FLASH2X_SECTION_VAL HighestPriISO = NO_SECTION_VAL;
+ enum bcm_flash2x_section_val HighestPriISO = NO_SECTION_VAL;
if (IsSectionWritable(Adapter, ISO_IMAGE2)) {
ISOHighestPri = ReadISOPriority(Adapter, ISO_IMAGE2);
@@ -4412,7 +4412,7 @@ FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter)
int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
PUINT pBuff,
- FLASH2X_SECTION_VAL eFlash2xSectionVal,
+ enum bcm_flash2x_section_val eFlash2xSectionVal,
unsigned int uiOffset,
unsigned int uiNumBytes)
{
@@ -4468,7 +4468,7 @@ int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
return Status;
}
-BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section)
+BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
{
BOOLEAN SectionPresent = FALSE;
@@ -4523,7 +4523,7 @@ BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_
return SectionPresent;
}
-int IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Section)
+int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section)
{
int offset = STATUS_FAILURE;
int Status = FALSE;
@@ -4546,7 +4546,7 @@ int IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Sect
return Status;
}
-static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
+static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
{
PUCHAR pBuff = NULL;
unsigned int sig = 0;
@@ -4608,7 +4608,7 @@ static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e
return STATUS_SUCCESS;
}
-static int CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
+static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
{
PUCHAR pBuff = NULL;
unsigned int sig = 0;
diff --git a/drivers/staging/bcm/vendorspecificextn.c b/drivers/staging/bcm/vendorspecificextn.c
index 833883c21a2..40be60aa909 100644
--- a/drivers/staging/bcm/vendorspecificextn.c
+++ b/drivers/staging/bcm/vendorspecificextn.c
@@ -89,7 +89,7 @@ INT vendorextnIoctl(struct bcm_mini_adapter *Adapter, UINT cmd, ULONG arg)
//
//------------------------------------------------------------------
-INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
+INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
UINT offset, UINT numOfBytes)
{
return STATUS_FAILURE;
@@ -114,7 +114,7 @@ INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL S
// STATUS_SUCCESS/STATUS_FAILURE
//
//------------------------------------------------------------------
-INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
+INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
UINT offset, UINT numOfBytes, BOOLEAN bVerify)
{
return STATUS_FAILURE;
@@ -138,7 +138,7 @@ INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL
// STATUS_SUCCESS/STATUS_FAILURE
//
//------------------------------------------------------------------
-INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
+INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
UINT offset, UINT numOfBytes)
{
return STATUS_FAILURE;
diff --git a/drivers/staging/bcm/vendorspecificextn.h b/drivers/staging/bcm/vendorspecificextn.h
index f237891b9f2..834410e29e7 100644
--- a/drivers/staging/bcm/vendorspecificextn.h
+++ b/drivers/staging/bcm/vendorspecificextn.h
@@ -8,11 +8,11 @@ INT vendorextnGetSectionInfo(PVOID pContext,PFLASH2X_VENDORSPECIFIC_INFO pVendo
INT vendorextnExit(struct bcm_mini_adapter *Adapter);
INT vendorextnInit(struct bcm_mini_adapter *Adapter);
INT vendorextnIoctl(struct bcm_mini_adapter *Adapter, UINT cmd, ULONG arg);
-INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
+INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
UINT offset, UINT numOfBytes);
-INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
+INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
UINT offset, UINT numOfBytes, BOOLEAN bVerify);
-INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
+INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
UINT offset, UINT numOfBytes);
#endif /* */
diff --git a/drivers/staging/ccg/ccg.c b/drivers/staging/ccg/ccg.c
index 93e1e2ffca0..ffc5f73a5b5 100644
--- a/drivers/staging/ccg/ccg.c
+++ b/drivers/staging/ccg/ccg.c
@@ -1239,7 +1239,7 @@ static int ccg_create_device(struct ccg_dev *dev)
}
-static int __init init(void)
+static int __init ccg_init(void)
{
struct ccg_dev *dev;
int err;
@@ -1280,13 +1280,13 @@ static int __init init(void)
return err;
}
-module_init(init);
+module_init(ccg_init);
-static void __exit cleanup(void)
+static void __exit ccg_exit(void)
{
usb_composite_unregister(&ccg_usb_driver);
class_destroy(ccg_class);
kfree(_ccg_dev);
_ccg_dev = NULL;
}
-module_exit(cleanup);
+module_exit(ccg_exit);
diff --git a/drivers/staging/ccg/u_serial.c b/drivers/staging/ccg/u_serial.c
index 5b3f5fffea9..373c40656b5 100644
--- a/drivers/staging/ccg/u_serial.c
+++ b/drivers/staging/ccg/u_serial.c
@@ -1140,8 +1140,10 @@ int gserial_setup(struct usb_gadget *g, unsigned count)
return status;
fail:
- while (count--)
+ while (count--) {
+ tty_port_destroy(&ports[count].port->port);
kfree(ports[count].port);
+ }
put_tty_driver(gs_tty_driver);
gs_tty_driver = NULL;
return status;
@@ -1195,6 +1197,7 @@ void gserial_cleanup(void)
WARN_ON(port->port_usb != NULL);
+ tty_port_destroy(&port->port);
kfree(port);
}
n_ports = 0;
diff --git a/drivers/staging/ced1401/ced_ioc.c b/drivers/staging/ced1401/ced_ioc.c
index c9492edaadd..d0434714afd 100644
--- a/drivers/staging/ced1401/ced_ioc.c
+++ b/drivers/staging/ced1401/ced_ioc.c
@@ -341,7 +341,7 @@ bool Is1401(DEVICE_EXTENSION * pdx)
}
if (iReturn == 0) // if all is OK...
- iReturn = state == 0; // then sucess is that the state is 0
+ iReturn = state == 0; // then success is that the state is 0
} else
iReturn = 0; // we failed
pdx->bForceReset = false; // Clear forced reset flag now
@@ -565,7 +565,7 @@ int LineCount(DEVICE_EXTENSION * pdx)
if (dwIndex >= INBUF_SZ) // see if we fall off buff
dwIndex = 0;
}
- while (dwIndex != dwEnd); // go to last avaliable
+ while (dwIndex != dwEnd); // go to last available
}
spin_unlock_irq(&pdx->charInLock);
@@ -697,8 +697,7 @@ static int SetArea(DEVICE_EXTENSION * pdx, int nArea, char __user * puBuf,
return -EFAULT; // ...then we are done
// Now allocate space to hold the page pointer and virtual address pointer tables
- pPages =
- (struct page **)kmalloc(len * sizeof(struct page *), GFP_KERNEL);
+ pPages = kmalloc(len * sizeof(struct page *), GFP_KERNEL);
if (!pPages) {
iReturn = U14ERR_NOMEMORY;
goto error;
@@ -913,18 +912,24 @@ int GetTransfer(DEVICE_EXTENSION * pdx, TGET_TX_BLOCK __user * pTX)
iReturn = U14ERR_BADAREA;
else {
// Return the best information we have - we don't have physical addresses
- TGET_TX_BLOCK tx;
- memset(&tx, 0, sizeof(tx)); // clean out local work structure
- tx.size = pdx->rTransDef[dwIdent].dwLength;
- tx.linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff);
- tx.avail = GET_TX_MAXENTRIES; // how many blocks we could return
- tx.used = 1; // number we actually return
- tx.entries[0].physical =
- (long long)(tx.linear + pdx->StagedOffset);
- tx.entries[0].size = tx.size;
-
- if (copy_to_user(pTX, &tx, sizeof(tx)))
+ TGET_TX_BLOCK *tx;
+
+ tx = kzalloc(sizeof(*tx), GFP_KERNEL);
+ if (!tx) {
+ mutex_unlock(&pdx->io_mutex);
+ return -ENOMEM;
+ }
+ tx->size = pdx->rTransDef[dwIdent].dwLength;
+ tx->linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff);
+ tx->avail = GET_TX_MAXENTRIES; // how many blocks we could return
+ tx->used = 1; // number we actually return
+ tx->entries[0].physical =
+ (long long)(tx->linear + pdx->StagedOffset);
+ tx->entries[0].size = tx->size;
+
+ if (copy_to_user(pTX, tx, sizeof(*tx)))
iReturn = -EFAULT;
+ kfree(tx);
}
mutex_unlock(&pdx->io_mutex);
return iReturn;
@@ -1508,7 +1513,7 @@ int FreeCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB)
iReturn = U14ERR_BADAREA;
if (copy_to_user(pCB, &cb, sizeof(cb)))
- return -EFAULT;
+ iReturn = -EFAULT;
mutex_unlock(&pdx->io_mutex);
return iReturn;
diff --git a/drivers/staging/ced1401/usb1401.c b/drivers/staging/ced1401/usb1401.c
index 6ba0ef65256..a27043a2f8c 100644
--- a/drivers/staging/ced1401/usb1401.c
+++ b/drivers/staging/ced1401/usb1401.c
@@ -89,14 +89,11 @@ synchronous non-Urb based transfers.
#include <linux/mutex.h>
#include <linux/mm.h>
#include <linux/highmem.h>
-#include <linux/version.h>
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) )
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kref.h>
#include <linux/uaccess.h>
-#endif
#include "usb1401.h"
@@ -123,19 +120,6 @@ MODULE_DEVICE_TABLE(usb, ced_table);
#define WRITES_IN_FLIGHT 8
/* arbitrarily chosen */
-/*
-The cause for these errors is that the driver makes use of the functions usb_buffer_alloc() and usb_buffer_free() which got renamed in kernel 2.6.35. This is stated in the Changelog: USB: rename usb_buffer_alloc() and usb_buffer_free() users
- For more clearance what the functions actually do,
- usb_buffer_alloc() is renamed to usb_alloc_coherent()
- usb_buffer_free() is renamed to usb_free_coherent()
- This is needed on Debian 2.6.32-5-amd64
-*/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) )
-#define usb_alloc_coherent usb_buffer_alloc
-#define usb_free_coherent usb_buffer_free
-#define noop_llseek NULL
-#endif
-
static struct usb_driver ced_driver;
static void ced_delete(struct kref *kref)
@@ -927,9 +911,9 @@ static bool ReadWord(unsigned short *pWord, char *pBuf, unsigned int *pdDone,
** ReadHuff
**
** Reads a coded number in and returns it, Code is:
-** If data is in range 0..127 we recieve 1 byte. If data in range 128-16383
-** we recieve two bytes, top bit of first indicates another on its way. If
-** data in range 16383-4194303 we get three bytes, top two bits of first set
+** If data is in range 0..127 we receive 1 byte. If data in range 128-16383
+** we receive two bytes, top bit of first indicates another on its way. If
+** data in range 16384-4194303 we get three bytes, top two bits of first set
** to indicate three byte total.
**
*****************************************************************************/
@@ -1252,12 +1236,7 @@ int Allowi(DEVICE_EXTENSION * pdx, bool bInCallback)
** ulArg The argument passed in. Note that long is 64-bits in 64-bit system, i.e. it is big
** enough for a 64-bit pointer.
*****************************************************************************/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
static long ced_ioctl(struct file *file, unsigned int cmd, unsigned long ulArg)
-#else
-static int ced_ioctl(struct inode *node, struct file *file, unsigned int cmd,
- unsigned long ulArg)
-#endif
{
int err = 0;
DEVICE_EXTENSION *pdx = file->private_data;
@@ -1388,11 +1367,7 @@ static const struct file_operations ced_fops = {
.release = ced_release,
.flush = ced_flush,
.llseek = noop_llseek,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
.unlocked_ioctl = ced_ioctl,
-#else
- .ioctl = ced_ioctl,
-#endif
};
/*
@@ -1537,7 +1512,7 @@ error:
static void ced_disconnect(struct usb_interface *interface)
{
DEVICE_EXTENSION *pdx = usb_get_intfdata(interface);
- int minor = interface->minor; // save for message at the end
+ int minor = interface->minor;
int i;
usb_set_intfdata(interface, NULL); // remove the pdx from the interface
@@ -1572,8 +1547,7 @@ void ced_draw_down(DEVICE_EXTENSION * pdx)
pdx->bInDrawDown = true;
time = usb_wait_anchor_empty_timeout(&pdx->submitted, 3000);
- if (!time) // if we timed out we kill the urbs
- {
+ if (!time) { // if we timed out we kill the urbs
usb_kill_anchored_urbs(&pdx->submitted);
dev_err(&pdx->interface->dev, "%s timed out", __func__);
}
diff --git a/drivers/staging/ced1401/usb1401.h b/drivers/staging/ced1401/usb1401.h
index 331ca985982..adb5fa402bd 100644
--- a/drivers/staging/ced1401/usb1401.h
+++ b/drivers/staging/ced1401/usb1401.h
@@ -165,7 +165,7 @@ typedef struct _DEVICE_EXTENSION
// Parameters relating to a block read\write that is in progress. Some of these values
// are equivalent to values in rDMAInfo. The values here are those in use, while those
- // in rDMAInfo are those recieved from the 1401 via an escape sequence. If another
+ // in rDMAInfo are those received from the 1401 via an escape sequence. If another
// escape sequence arrives before the previous xfer ends, rDMAInfo values are updated while these
// are used to finish off the current transfer.
volatile short StagedId; // The transfer area id for this transfer
diff --git a/drivers/staging/ced1401/userspace/use1401.c b/drivers/staging/ced1401/userspace/use1401.c
index d4c63168ea2..38e7c1c82d4 100644
--- a/drivers/staging/ced1401/userspace/use1401.c
+++ b/drivers/staging/ced1401/userspace/use1401.c
@@ -145,7 +145,7 @@
** You should add a new one of these to keep things tidy for applications.
**
** DRIVERET_MAX (below) specifies the maximum allowed type code from the
-** 1401 driver; I have set this high to accomodate as yet undesigned 1401
+** 1401 driver; I have set this high to accommodate as yet undesigned 1401
** types. Similarly, as long as the command file names follow the ARM,
** ARN, ARO sequence, these are calculated by the ExtForType function, so
** you don't need to do anything here either.
@@ -160,7 +160,7 @@
** have broken backwards compatibility. Minor number changes mean that we
** have added new functionality that does not break backwards compatibility.
** we starts at 0. Revision changes mean we have fixed something. Each index
-** returns to 0 when a higer one changes.
+** returns to 0 when a higher one changes.
*/
#define U14LIB_MAJOR 4
#define U14LIB_MINOR 0
@@ -211,7 +211,7 @@
/*
** These are the 1401 type codes returned by the driver, they are a slightly
-** odd sequence & start for reasons of compatability with the DOS driver.
+** odd sequence & start for reasons of compatibility with the DOS driver.
** The maximum code value is the upper limit of 1401 device types.
*/
#define DRIVRET_STD 4 // Codes for 1401 types matching driver values
@@ -2327,7 +2327,7 @@ U14API(short) U14SetTransArea(short hand, WORD wArea, void *pvBuff,
/****************************************************************************
** U14SetTransferEvent Sets an event for notification of application
-** wArea The tranfer area index, from 0 to MAXAREAS-1
+** wArea The transfer area index, from 0 to MAXAREAS-1
** bEvent True to create an event, false to remove it
** bToHost Set 0 for notification on to1401 tranfers, 1 for
** notification of transfers to the host PC
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index 2093403af25..7de2a10213b 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -568,7 +568,6 @@ config COMEDI_8255_PCI
config COMEDI_ADDI_APCI_035
tristate "ADDI-DATA APCI_035 support"
- depends on VIRT_TO_BUS
---help---
Enable support for ADDI-DATA APCI_035 cards
@@ -577,7 +576,6 @@ config COMEDI_ADDI_APCI_035
config COMEDI_ADDI_APCI_1032
tristate "ADDI-DATA APCI_1032 support"
- depends on VIRT_TO_BUS
---help---
Enable support for ADDI-DATA APCI_1032 cards
@@ -586,7 +584,6 @@ config COMEDI_ADDI_APCI_1032
config COMEDI_ADDI_APCI_1500
tristate "ADDI-DATA APCI_1500 support"
- depends on VIRT_TO_BUS
---help---
Enable support for ADDI-DATA APCI_1500 cards
@@ -594,17 +591,17 @@ config COMEDI_ADDI_APCI_1500
called addi_apci_1500.
config COMEDI_ADDI_APCI_1516
- tristate "ADDI-DATA APCI_1516 support"
- depends on VIRT_TO_BUS
+ tristate "ADDI-DATA APCI-1016/1516/2016 support"
---help---
- Enable support for ADDI-DATA APCI_1516 cards
+ Enable support for ADDI-DATA APCI-1016, APCI-1516 and APCI-2016 boards.
+ These are 16 channel, optically isolated, digital I/O boards. The 1516
+ and 2016 boards also have a watchdog for resetting the outputs to "0".
To compile this driver as a module, choose M here: the module will be
called addi_apci_1516.
config COMEDI_ADDI_APCI_1564
tristate "ADDI-DATA APCI_1564 support"
- depends on VIRT_TO_BUS
---help---
Enable support for ADDI-DATA APCI_1564 cards
@@ -613,25 +610,14 @@ config COMEDI_ADDI_APCI_1564
config COMEDI_ADDI_APCI_16XX
tristate "ADDI-DATA APCI_16xx support"
- depends on VIRT_TO_BUS
---help---
Enable support for ADDI-DATA APCI_16xx cards
To compile this driver as a module, choose M here: the module will be
called addi_apci_16xx.
-config COMEDI_ADDI_APCI_2016
- tristate "ADDI-DATA APCI_2016 support"
- depends on VIRT_TO_BUS
- ---help---
- Enable support for ADDI-DATA APCI_2016 cards
-
- To compile this driver as a module, choose M here: the module will be
- called addi_apci_2016.
-
config COMEDI_ADDI_APCI_2032
tristate "ADDI-DATA APCI_2032 support"
- depends on VIRT_TO_BUS
---help---
Enable support for ADDI-DATA APCI_2032 cards
@@ -640,36 +626,24 @@ config COMEDI_ADDI_APCI_2032
config COMEDI_ADDI_APCI_2200
tristate "ADDI-DATA APCI_2200 support"
- depends on VIRT_TO_BUS
---help---
Enable support for ADDI-DATA APCI_2200 cards
To compile this driver as a module, choose M here: the module will be
called addi_apci_2200.
-config COMEDI_ADDI_APCI_3001
- tristate "ADDI-DATA APCI_3001 support"
- depends on VIRT_TO_BUS
- select COMEDI_FC
- ---help---
- Enable support for ADDI-DATA APCI_3001 cards
-
- To compile this driver as a module, choose M here: the module will be
- called addi_apci_3001.
-
config COMEDI_ADDI_APCI_3120
- tristate "ADDI-DATA APCI_3520 support"
+ tristate "ADDI-DATA APCI_3120/3001 support"
depends on VIRT_TO_BUS
select COMEDI_FC
---help---
- Enable support for ADDI-DATA APCI_3520 cards
+ Enable support for ADDI-DATA APCI_3120/3001 cards
To compile this driver as a module, choose M here: the module will be
called addi_apci_3120.
config COMEDI_ADDI_APCI_3501
tristate "ADDI-DATA APCI_3501 support"
- depends on VIRT_TO_BUS
---help---
Enable support for ADDI-DATA APCI_3501 cards
@@ -678,7 +652,6 @@ config COMEDI_ADDI_APCI_3501
config COMEDI_ADDI_APCI_3XXX
tristate "ADDI-DATA APCI_3xxx support"
- depends on VIRT_TO_BUS
---help---
Enable support for ADDI-DATA APCI_3xxx cards
@@ -761,10 +734,11 @@ config COMEDI_ADV_PCI_DIO
called adv_pci_dio.
config COMEDI_AMPLC_DIO200_PCI
- tristate "Amplicon PCI215 and PCI272 DIO board support"
+ tristate "Amplicon PCI215/PCI272/PCIe215/PCIe236/PCIe296 DIO support"
select COMEDI_AMPLC_DIO200
---help---
- Enable support for Amplicon PCI215 and PCI272 DIO boards.
+ Enable support for Amplicon PCI215, PCI272, PCIe215, PCIe236
+ and PCIe296 DIO boards.
To compile this driver as a module, choose M here: the module will be
called amplc_dio200.
@@ -1263,7 +1237,6 @@ config COMEDI_FC
config COMEDI_AMPLC_DIO200
tristate
- select COMEDI_8255
config COMEDI_AMPLC_PC236
tristate
diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h
index 133f013e0f6..c8a8ca12612 100644
--- a/drivers/staging/comedi/comedi.h
+++ b/drivers/staging/comedi/comedi.h
@@ -283,6 +283,44 @@ enum configuration_ids {
INSN_CONFIG_PWM_GET_H_BRIDGE = 5004
};
+/*
+ * Settings for INSN_CONFIG_DIGITAL_TRIG:
+ * data[0] = INSN_CONFIG_DIGITAL_TRIG
+ * data[1] = trigger ID
+ * data[2] = configuration operation
+ * data[3] = configuration parameter 1
+ * data[4] = configuration parameter 2
+ * data[5] = configuration parameter 3
+ *
+ * operation parameter 1 parameter 2 parameter 3
+ * --------------------------------- ----------- ----------- -----------
+ * COMEDI_DIGITAL_TRIG_DISABLE
+ * COMEDI_DIGITAL_TRIG_ENABLE_EDGES left-shift rising-edges falling-edges
+ * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS left-shift high-levels low-levels
+ *
+ * COMEDI_DIGITAL_TRIG_DISABLE returns the trigger to its default, inactive,
+ * unconfigured state.
+ *
+ * COMEDI_DIGITAL_TRIG_ENABLE_EDGES sets the rising and/or falling edge inputs
+ * that each can fire the trigger.
+ *
+ * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS sets a combination of high and/or low
+ * level inputs that can fire the trigger.
+ *
+ * "left-shift" is useful if the trigger has more than 32 inputs to specify the
+ * first input for this configuration.
+ *
+ * Some sequences of INSN_CONFIG_DIGITAL_TRIG instructions may have a (partly)
+ * accumulative effect, depending on the low-level driver. This is useful
+ * when setting up a trigger that has more than 32 inputs or has a combination
+ * of edge and level triggered inputs.
+ */
+enum comedi_digital_trig_op {
+ COMEDI_DIGITAL_TRIG_DISABLE = 0,
+ COMEDI_DIGITAL_TRIG_ENABLE_EDGES = 1,
+ COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = 2
+};
+
enum comedi_io_direction {
COMEDI_INPUT = 0,
COMEDI_OUTPUT = 1,
@@ -888,7 +926,20 @@ enum amplc_dio_clock_source {
subdevice, preceding counter
subdevice is the last counter
subdevice) */
- AMPLC_DIO_CLK_EXT /* per chip external input pin */
+ AMPLC_DIO_CLK_EXT, /* per chip external input pin */
+ /* the following are "enhanced" clock sources for PCIe models */
+ AMPLC_DIO_CLK_VCC, /* clock input HIGH */
+ AMPLC_DIO_CLK_GND, /* clock input LOW */
+ AMPLC_DIO_CLK_PAT_PRESENT, /* "pattern present" signal */
+ AMPLC_DIO_CLK_20MHZ /* 20 MHz internal clock */
+};
+
+/* Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for
+ * timer subdevice on some Amplicon DIO PCIe boards (amplc_dio200 driver). */
+enum amplc_dio_ts_clock_src {
+ AMPLC_DIO_TS_CLK_1GHZ, /* 1 ns period with 20 ns granularity */
+ AMPLC_DIO_TS_CLK_1MHZ, /* 1 us period */
+ AMPLC_DIO_TS_CLK_1KHZ /* 1 ms period */
};
/* Values for setting a gate source with INSN_CONFIG_SET_GATE_SRC for
@@ -907,7 +958,17 @@ enum amplc_dio_gate_source {
AMPLC_DIO_GAT_RESERVED4,
AMPLC_DIO_GAT_RESERVED5,
AMPLC_DIO_GAT_RESERVED6,
- AMPLC_DIO_GAT_RESERVED7
+ AMPLC_DIO_GAT_RESERVED7,
+ /* the following are "enhanced" gate sources for PCIe models */
+ AMPLC_DIO_GAT_NGATN = 6, /* negated per channel gate input */
+ AMPLC_DIO_GAT_OUTNM2, /* non-negated output of counter
+ channel minus 2 */
+ AMPLC_DIO_GAT_PAT_PRESENT, /* "pattern present" signal */
+ AMPLC_DIO_GAT_PAT_OCCURRED, /* "pattern occurred" latched */
+ AMPLC_DIO_GAT_PAT_GONE, /* "pattern gone away" latched */
+ AMPLC_DIO_GAT_NPAT_PRESENT, /* negated "pattern present" */
+ AMPLC_DIO_GAT_NPAT_OCCURRED, /* negated "pattern occurred" */
+ AMPLC_DIO_GAT_NPAT_GONE /* negated "pattern gone away" */
};
#endif /* _COMEDI_H */
diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c
index 0a5057f0919..4b7cbfad1d7 100644
--- a/drivers/staging/comedi/comedi_compat32.c
+++ b/drivers/staging/comedi/comedi_compat32.c
@@ -24,7 +24,6 @@
*/
-#define __NO_VERSION__
#include <linux/uaccess.h>
#include <linux/compat.h>
#include <linux/fs.h>
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index c2a32cf95a8..b7bba1790a2 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -23,7 +23,6 @@
#undef DEBUG
-#define __NO_VERSION__
#include "comedi_compat32.h"
#include <linux/module.h>
@@ -880,6 +879,10 @@ static int check_insn_config_length(struct comedi_insn *insn,
if (insn->n == 5)
return 0;
break;
+ case INSN_CONFIG_DIGITAL_TRIG:
+ if (insn->n == 6)
+ return 0;
+ break;
/* by default we allow the insn since we don't have checks for
* all possible cases yet */
default:
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h
index cb67a5cb9c8..692e1e615d4 100644
--- a/drivers/staging/comedi/comedidev.h
+++ b/drivers/staging/comedi/comedidev.h
@@ -41,6 +41,7 @@
#include <linux/io.h>
#include <linux/timer.h>
#include <linux/pci.h>
+#include <linux/usb.h>
#include "comedi.h"
@@ -54,9 +55,21 @@
COMEDI_MINORVERSION, COMEDI_MICROVERSION)
#define COMEDI_RELEASE VERSION
-#define PCI_VENDOR_ID_ADLINK 0x144a
+/*
+ * PCI Vendor IDs not in <linux/pci_ids.h>
+ */
+#define PCI_VENDOR_ID_KOLTER 0x1001
#define PCI_VENDOR_ID_ICP 0x104c
+#define PCI_VENDOR_ID_AMCC 0x10e8
+#define PCI_VENDOR_ID_DT 0x1116
+#define PCI_VENDOR_ID_IOTECH 0x1616
#define PCI_VENDOR_ID_CONTEC 0x1221
+#define PCI_VENDOR_ID_CB 0x1307 /* Measurement Computing */
+#define PCI_VENDOR_ID_ADVANTECH 0x13fe
+#define PCI_VENDOR_ID_MEILHAUS 0x1402
+#define PCI_VENDOR_ID_RTD 0x1435
+#define PCI_VENDOR_ID_ADLINK 0x144a
+#define PCI_VENDOR_ID_AMPLICON 0x14dc
#define COMEDI_NUM_MINORS 0x100
#define COMEDI_NUM_BOARD_MINORS 0x30
@@ -181,8 +194,6 @@ struct comedi_async {
unsigned int x);
};
-struct usb_interface;
-
struct comedi_driver {
struct comedi_driver *next;
@@ -190,8 +201,7 @@ struct comedi_driver {
struct module *module;
int (*attach) (struct comedi_device *, struct comedi_devconfig *);
void (*detach) (struct comedi_device *);
- int (*attach_pci) (struct comedi_device *, struct pci_dev *);
- int (*attach_usb) (struct comedi_device *, struct usb_interface *);
+ int (*auto_attach) (struct comedi_device *, unsigned long);
/* number of elements in board_name and board_id arrays */
unsigned int num_names;
@@ -235,7 +245,7 @@ struct comedi_device {
void (*close) (struct comedi_device *dev);
};
-static inline const void *comedi_board(struct comedi_device *dev)
+static inline const void *comedi_board(const struct comedi_device *dev)
{
return dev->board_ptr;
}
@@ -415,14 +425,6 @@ struct comedi_lrange {
/* some silly little inline functions */
-static inline int alloc_private(struct comedi_device *dev, int size)
-{
- dev->private = kzalloc(size, GFP_KERNEL);
- if (!dev->private)
- return -ENOMEM;
- return 0;
-}
-
static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd)
{
if (subd->subdev_flags & SDF_LSAMPL)
@@ -436,9 +438,10 @@ into comedi's buffer */
static inline void comedi_set_hw_dev(struct comedi_device *dev,
struct device *hw_dev)
{
+ if (dev->hw_dev == hw_dev)
+ return;
if (dev->hw_dev)
put_device(dev->hw_dev);
-
dev->hw_dev = hw_dev;
if (dev->hw_dev) {
dev->hw_dev = get_device(dev->hw_dev);
@@ -451,6 +454,12 @@ static inline struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev)
return dev->hw_dev ? to_pci_dev(dev->hw_dev) : NULL;
}
+static inline struct usb_interface *
+comedi_to_usb_interface(struct comedi_device *dev)
+{
+ return dev->hw_dev ? to_usb_interface(dev->hw_dev) : NULL;
+}
+
int comedi_buf_put(struct comedi_async *async, short x);
int comedi_buf_get(struct comedi_async *async, short *x);
@@ -505,11 +514,30 @@ static inline void *comedi_aux_data(int options[], int n)
int comedi_alloc_subdevice_minor(struct comedi_device *dev,
struct comedi_subdevice *s);
void comedi_free_subdevice_minor(struct comedi_subdevice *s);
-int comedi_pci_auto_config(struct pci_dev *pcidev,
- struct comedi_driver *driver);
-void comedi_pci_auto_unconfig(struct pci_dev *pcidev);
-int comedi_usb_auto_config(struct usb_interface *intf,
- struct comedi_driver *driver);
-void comedi_usb_auto_unconfig(struct usb_interface *intf);
+int comedi_auto_config(struct device *hardware_device,
+ struct comedi_driver *driver, unsigned long context);
+void comedi_auto_unconfig(struct device *hardware_device);
+
+static inline int comedi_pci_auto_config(struct pci_dev *pcidev,
+ struct comedi_driver *driver)
+{
+ return comedi_auto_config(&pcidev->dev, driver, 0);
+}
+
+static inline void comedi_pci_auto_unconfig(struct pci_dev *pcidev)
+{
+ comedi_auto_unconfig(&pcidev->dev);
+}
+
+static inline int comedi_usb_auto_config(struct usb_interface *intf,
+ struct comedi_driver *driver)
+{
+ return comedi_auto_config(&intf->dev, driver, 0);
+}
+
+static inline void comedi_usb_auto_unconfig(struct usb_interface *intf)
+{
+ comedi_auto_unconfig(&intf->dev);
+}
#endif /* _COMEDIDEV_H */
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 1db6bfdbf13..50cf498698e 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -21,9 +21,6 @@
*/
-#define _GNU_SOURCE
-
-#define __NO_VERSION__
#include <linux/device.h>
#include <linux/module.h>
#include <linux/pci.h>
@@ -833,11 +830,8 @@ void comedi_reset_async_buf(struct comedi_async *async)
async->events = 0;
}
-static int
-comedi_auto_config_helper(struct device *hardware_device,
- struct comedi_driver *driver,
- int (*attach_wrapper) (struct comedi_device *,
- void *), void *context)
+int comedi_auto_config(struct device *hardware_device,
+ struct comedi_driver *driver, unsigned long context)
{
int minor;
struct comedi_device_file_info *dev_file_info;
@@ -847,6 +841,13 @@ comedi_auto_config_helper(struct device *hardware_device,
if (!comedi_autoconfig)
return 0;
+ if (!driver->auto_attach) {
+ dev_warn(hardware_device,
+ "BUG! comedi driver '%s' has no auto_attach handler\n",
+ driver->driver_name);
+ return -EINVAL;
+ }
+
minor = comedi_alloc_board_minor(hardware_device);
if (minor < 0)
return minor;
@@ -860,9 +861,9 @@ comedi_auto_config_helper(struct device *hardware_device,
else if (!try_module_get(driver->module))
ret = -EIO;
else {
- /* set comedi_dev->driver here for attach wrapper */
+ comedi_set_hw_dev(comedi_dev, hardware_device);
comedi_dev->driver = driver;
- ret = (*attach_wrapper)(comedi_dev, context);
+ ret = driver->auto_attach(comedi_dev, context);
if (ret < 0) {
module_put(driver->module);
__comedi_device_detach(comedi_dev);
@@ -876,49 +877,9 @@ comedi_auto_config_helper(struct device *hardware_device,
comedi_free_board_minor(minor);
return ret;
}
+EXPORT_SYMBOL_GPL(comedi_auto_config);
-static int comedi_auto_config_wrapper(struct comedi_device *dev, void *context)
-{
- struct comedi_devconfig *it = context;
- struct comedi_driver *driv = dev->driver;
-
- if (driv->num_names) {
- /* look for generic board entry matching driver name, which
- * has already been copied to it->board_name */
- dev->board_ptr = comedi_recognize(driv, it->board_name);
- if (dev->board_ptr == NULL) {
- dev_warn(dev->class_dev,
- "auto config failed to find board entry '%s' for driver '%s'\n",
- it->board_name, driv->driver_name);
- comedi_report_boards(driv);
- return -EINVAL;
- }
- }
- if (!driv->attach) {
- dev_warn(dev->class_dev,
- "BUG! driver '%s' using old-style auto config but has no attach handler\n",
- driv->driver_name);
- return -EINVAL;
- }
- return driv->attach(dev, it);
-}
-
-static int comedi_auto_config(struct device *hardware_device,
- struct comedi_driver *driver, const int *options,
- unsigned num_options)
-{
- struct comedi_devconfig it;
-
- memset(&it, 0, sizeof(it));
- strncpy(it.board_name, driver->driver_name, COMEDI_NAMELEN);
- it.board_name[COMEDI_NAMELEN - 1] = '\0';
- BUG_ON(num_options > COMEDI_NDEVCONFOPTS);
- memcpy(it.options, options, num_options * sizeof(int));
- return comedi_auto_config_helper(hardware_device, driver,
- comedi_auto_config_wrapper, &it);
-}
-
-static void comedi_auto_unconfig(struct device *hardware_device)
+void comedi_auto_unconfig(struct device *hardware_device)
{
int minor;
@@ -930,6 +891,7 @@ static void comedi_auto_unconfig(struct device *hardware_device)
BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS);
comedi_free_board_minor(minor);
}
+EXPORT_SYMBOL_GPL(comedi_auto_unconfig);
/**
* comedi_pci_enable() - Enable the PCI device and request the regions.
@@ -965,48 +927,6 @@ void comedi_pci_disable(struct pci_dev *pdev)
}
EXPORT_SYMBOL_GPL(comedi_pci_disable);
-static int comedi_old_pci_auto_config(struct pci_dev *pcidev,
- struct comedi_driver *driver)
-{
- int options[2];
-
- /* pci bus */
- options[0] = pcidev->bus->number;
- /* pci slot */
- options[1] = PCI_SLOT(pcidev->devfn);
-
- return comedi_auto_config(&pcidev->dev, driver,
- options, ARRAY_SIZE(options));
-}
-
-static int comedi_pci_attach_wrapper(struct comedi_device *dev, void *pcidev)
-{
- return dev->driver->attach_pci(dev, pcidev);
-}
-
-static int comedi_new_pci_auto_config(struct pci_dev *pcidev,
- struct comedi_driver *driver)
-{
- return comedi_auto_config_helper(&pcidev->dev, driver,
- comedi_pci_attach_wrapper, pcidev);
-}
-
-int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver)
-{
-
- if (driver->attach_pci)
- return comedi_new_pci_auto_config(pcidev, driver);
- else
- return comedi_old_pci_auto_config(pcidev, driver);
-}
-EXPORT_SYMBOL_GPL(comedi_pci_auto_config);
-
-void comedi_pci_auto_unconfig(struct pci_dev *pcidev)
-{
- comedi_auto_unconfig(&pcidev->dev);
-}
-EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig);
-
int comedi_pci_driver_register(struct comedi_driver *comedi_driver,
struct pci_driver *pci_driver)
{
@@ -1040,42 +960,6 @@ EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister);
#if IS_ENABLED(CONFIG_USB)
-static int comedi_old_usb_auto_config(struct usb_interface *intf,
- struct comedi_driver *driver)
-{
- return comedi_auto_config(&intf->dev, driver, NULL, 0);
-}
-
-static int comedi_usb_attach_wrapper(struct comedi_device *dev, void *intf)
-{
- return dev->driver->attach_usb(dev, intf);
-}
-
-static int comedi_new_usb_auto_config(struct usb_interface *intf,
- struct comedi_driver *driver)
-{
- return comedi_auto_config_helper(&intf->dev, driver,
- comedi_usb_attach_wrapper, intf);
-}
-
-int comedi_usb_auto_config(struct usb_interface *intf,
- struct comedi_driver *driver)
-{
- BUG_ON(intf == NULL);
- if (driver->attach_usb)
- return comedi_new_usb_auto_config(intf, driver);
- else
- return comedi_old_usb_auto_config(intf, driver);
-}
-EXPORT_SYMBOL_GPL(comedi_usb_auto_config);
-
-void comedi_usb_auto_unconfig(struct usb_interface *intf)
-{
- BUG_ON(intf == NULL);
- comedi_auto_unconfig(&intf->dev);
-}
-EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig);
-
int comedi_usb_driver_register(struct comedi_driver *comedi_driver,
struct usb_driver *usb_driver)
{
diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c
index a256622e2dd..c7aa41ad842 100644
--- a/drivers/staging/comedi/drivers/8255.c
+++ b/drivers/staging/comedi/drivers/8255.c
@@ -249,28 +249,13 @@ static int subdev_8255_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3 */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
- if (cmd->scan_end_arg != 1) {
- cmd->scan_end_arg = 1;
- err++;
- }
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ 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;
diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c
index d00aff6671d..e0a79521f35 100644
--- a/drivers/staging/comedi/drivers/8255_pci.c
+++ b/drivers/staging/comedi/drivers/8255_pci.c
@@ -65,9 +65,6 @@ Configuration Options: not applicable, uses PCI auto config
#define PCI_DEVICE_ID_ADLINK_PCI7248 0x7248
#define PCI_DEVICE_ID_ADLINK_PCI7296 0x7296
-/* ComputerBoards is now known as Measurement Computing */
-#define PCI_VENDOR_ID_CB 0x1307
-
#define PCI_DEVICE_ID_CB_PCIDIO48H 0x000b
#define PCI_DEVICE_ID_CB_PCIDIO24H 0x0014
#define PCI_DEVICE_ID_CB_PCIDIO96H 0x0017
@@ -216,9 +213,10 @@ static const void *pci_8255_find_boardinfo(struct comedi_device *dev,
return NULL;
}
-static int pci_8255_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int pci_8255_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct pci_8255_boardinfo *board;
struct pci_8255_private *devpriv;
struct comedi_subdevice *s;
@@ -227,18 +225,16 @@ static int pci_8255_attach_pci(struct comedi_device *dev,
int ret;
int i;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
board = pci_8255_find_boardinfo(dev, pcidev);
if (!board)
return -ENODEV;
dev->board_ptr = board;
dev->board_name = board->name;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret < 0)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret)
@@ -308,17 +304,17 @@ static void pci_8255_detach(struct comedi_device *dev)
static struct comedi_driver pci_8255_driver = {
.driver_name = "8255_pci",
.module = THIS_MODULE,
- .attach_pci = pci_8255_attach_pci,
+ .auto_attach = pci_8255_auto_attach,
.detach = pci_8255_detach,
};
-static int __devinit pci_8255_pci_probe(struct pci_dev *dev,
+static int pci_8255_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &pci_8255_driver);
}
-static void __devexit pci_8255_pci_remove(struct pci_dev *dev)
+static void pci_8255_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -346,7 +342,7 @@ static struct pci_driver pci_8255_pci_driver = {
.name = "8255_pci",
.id_table = pci_8255_pci_table,
.probe = pci_8255_pci_probe,
- .remove = __devexit_p(pci_8255_pci_remove),
+ .remove = pci_8255_pci_remove,
};
module_comedi_pci_driver(pci_8255_driver, pci_8255_pci_driver);
diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile
index a2787c0ca32..0de4d2eb76f 100644
--- a/drivers/staging/comedi/drivers/Makefile
+++ b/drivers/staging/comedi/drivers/Makefile
@@ -62,10 +62,8 @@ obj-$(CONFIG_COMEDI_ADDI_APCI_1500) += addi_apci_1500.o
obj-$(CONFIG_COMEDI_ADDI_APCI_1516) += addi_apci_1516.o
obj-$(CONFIG_COMEDI_ADDI_APCI_1564) += addi_apci_1564.o
obj-$(CONFIG_COMEDI_ADDI_APCI_16XX) += addi_apci_16xx.o
-obj-$(CONFIG_COMEDI_ADDI_APCI_2016) += addi_apci_2016.o
obj-$(CONFIG_COMEDI_ADDI_APCI_2032) += addi_apci_2032.o
obj-$(CONFIG_COMEDI_ADDI_APCI_2200) += addi_apci_2200.o
-obj-$(CONFIG_COMEDI_ADDI_APCI_3001) += addi_apci_3001.o
obj-$(CONFIG_COMEDI_ADDI_APCI_3120) += addi_apci_3120.o
obj-$(CONFIG_COMEDI_ADDI_APCI_3501) += addi_apci_3501.o
obj-$(CONFIG_COMEDI_ADDI_APCI_3XXX) += addi_apci_3xxx.o
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c
index b59f2d484fd..d0702084caa 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c
@@ -18,7 +18,19 @@
| Description : APCI-1710 82X54 timer module |
*/
-#include "APCI1710_82x54.h"
+#define APCI1710_PCI_BUS_CLOCK 0
+#define APCI1710_FRONT_CONNECTOR_INPUT 1
+#define APCI1710_TIMER_READVALUE 0
+#define APCI1710_TIMER_GETOUTPUTLEVEL 1
+#define APCI1710_TIMER_GETPROGRESSSTATUS 2
+#define APCI1710_TIMER_WRITEVALUE 3
+
+#define APCI1710_TIMER_READINTERRUPT 1
+#define APCI1710_TIMER_READALLTIMER 2
+
+#ifndef APCI1710_10MHZ
+#define APCI1710_10MHZ 10
+#endif
/*
+----------------------------------------------------------------------------+
@@ -218,11 +230,12 @@ int i_InsnConfig_InitTimer(struct comedi_device *dev,struct comedi_subdevice *s,
| -9: Selection from hardware gate level is wrong |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
-
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned char b_ModulNbr;
unsigned char b_TimerNbr;
@@ -447,11 +460,12 @@ i_ReturnValue=insn->n;
| See function "i_APCI1710_SetBoardIntRoutineX" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_DummyRead;
unsigned char b_ModulNbr;
@@ -589,10 +603,12 @@ int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev,struct comedi_sub
| "i_APCI1710_InitTimer" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned char b_ModulNbr, b_ReadType;
unsigned int *pul_TimerValueArray;
@@ -668,70 +684,6 @@ int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_su
/*
+----------------------------------------------------------------------------+
-| Function Name :INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev,
-struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Read write functions for Timer |
-+----------------------------------------------------------------------------+
-| Input Parameters :
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value :
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI1710_InsnBitsTimer(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned char b_BitsType;
- int i_ReturnValue = 0;
- b_BitsType = data[0];
-
- printk("\n82X54");
-
- switch (b_BitsType) {
- case APCI1710_TIMER_READVALUE:
- i_ReturnValue = i_APCI1710_ReadTimerValue(dev,
- (unsigned char)CR_AREF(insn->chanspec),
- (unsigned char)CR_CHAN(insn->chanspec),
- (unsigned int *) &data[0]);
- break;
-
- case APCI1710_TIMER_GETOUTPUTLEVEL:
- i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev,
- (unsigned char)CR_AREF(insn->chanspec),
- (unsigned char)CR_CHAN(insn->chanspec),
- (unsigned char *) &data[0]);
- break;
-
- case APCI1710_TIMER_GETPROGRESSSTATUS:
- i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev,
- (unsigned char)CR_AREF(insn->chanspec),
- (unsigned char)CR_CHAN(insn->chanspec),
- (unsigned char *)&data[0]);
- break;
-
- case APCI1710_TIMER_WRITEVALUE:
- i_ReturnValue = i_APCI1710_WriteTimerValue(dev,
- (unsigned char)CR_AREF(insn->chanspec),
- (unsigned char)CR_CHAN(insn->chanspec),
- (unsigned int)data[1]);
-
- break;
-
- default:
- printk("Bits Config Parameter Wrong\n");
- i_ReturnValue = -1;
- }
-
- if (i_ReturnValue >= 0)
- i_ReturnValue = insn->n;
- return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_ReadTimerValue |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
@@ -759,11 +711,12 @@ int i_APCI1710_InsnBitsTimer(struct comedi_device *dev, struct comedi_subdevice
| "i_APCI1710_InitTimer" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_ReadTimerValue(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_TimerNbr,
- unsigned int *pul_TimerValue)
+static int i_APCI1710_ReadTimerValue(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_TimerNbr,
+ unsigned int *pul_TimerValue)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/* Test the module number */
@@ -847,11 +800,12 @@ int i_APCI1710_ReadTimerValue(struct comedi_device *dev,
| "i_APCI1710_InitTimer" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_TimerNbr,
- unsigned char *pb_OutputLevel)
+static int i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_TimerNbr,
+ unsigned char *pb_OutputLevel)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_TimerStatus;
@@ -926,11 +880,12 @@ int i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev,
| "i_APCI1710_InitTimer" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_TimerNbr,
- unsigned char *pb_TimerStatus)
+static int i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_TimerNbr,
+ unsigned char *pb_TimerStatus)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_TimerStatus;
@@ -1005,11 +960,12 @@ int i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev,
| "i_APCI1710_InitTimer" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_WriteTimerValue(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_TimerNbr,
- unsigned int ul_WriteValue)
+static int i_APCI1710_WriteTimerValue(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_TimerNbr,
+ unsigned int ul_WriteValue)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/* Test the module number */
@@ -1045,3 +1001,68 @@ int i_APCI1710_WriteTimerValue(struct comedi_device *dev,
return i_ReturnValue;
}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev,
+struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read write functions for Timer |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+static int i_APCI1710_InsnBitsTimer(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ unsigned char b_BitsType;
+ int i_ReturnValue = 0;
+ b_BitsType = data[0];
+
+ printk("\n82X54");
+
+ switch (b_BitsType) {
+ case APCI1710_TIMER_READVALUE:
+ i_ReturnValue = i_APCI1710_ReadTimerValue(dev,
+ (unsigned char)CR_AREF(insn->chanspec),
+ (unsigned char)CR_CHAN(insn->chanspec),
+ (unsigned int *) &data[0]);
+ break;
+
+ case APCI1710_TIMER_GETOUTPUTLEVEL:
+ i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev,
+ (unsigned char)CR_AREF(insn->chanspec),
+ (unsigned char)CR_CHAN(insn->chanspec),
+ (unsigned char *) &data[0]);
+ break;
+
+ case APCI1710_TIMER_GETPROGRESSSTATUS:
+ i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev,
+ (unsigned char)CR_AREF(insn->chanspec),
+ (unsigned char)CR_CHAN(insn->chanspec),
+ (unsigned char *)&data[0]);
+ break;
+
+ case APCI1710_TIMER_WRITEVALUE:
+ i_ReturnValue = i_APCI1710_WriteTimerValue(dev,
+ (unsigned char)CR_AREF(insn->chanspec),
+ (unsigned char)CR_CHAN(insn->chanspec),
+ (unsigned int)data[1]);
+
+ break;
+
+ default:
+ printk("Bits Config Parameter Wrong\n");
+ i_ReturnValue = -1;
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return i_ReturnValue;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h
deleted file mode 100644
index 81346dbc35f..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-#define APCI1710_PCI_BUS_CLOCK 0
-#define APCI1710_FRONT_CONNECTOR_INPUT 1
-#define APCI1710_TIMER_READVALUE 0
-#define APCI1710_TIMER_GETOUTPUTLEVEL 1
-#define APCI1710_TIMER_GETPROGRESSSTATUS 2
-#define APCI1710_TIMER_WRITEVALUE 3
-
-#define APCI1710_TIMER_READINTERRUPT 1
-#define APCI1710_TIMER_READALLTIMER 2
-
-/* BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
-#ifndef APCI1710_10MHZ
-#define APCI1710_10MHZ 10
-#endif
-/* END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
-
-/*
- * 82X54 TIMER INISIALISATION FUNCTION
- */
-int i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/*
- * 82X54 READ FUNCTION
- */
-int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1710_InsnBitsTimer(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/*
- * 82X54 READ & WRITE FUNCTION
- */
-int i_APCI1710_ReadTimerValue(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_TimerNbr,
- unsigned int *pul_TimerValue);
-
-int i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_TimerNbr,
- unsigned char *pb_OutputLevel);
-
-int i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_TimerNbr,
- unsigned char *pb_TimerStatus);
-
-/*
- * 82X54 WRITE FUNCTION
- */
-int i_APCI1710_WriteTimerValue(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_TimerNbr,
- unsigned int ul_WriteValue);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
index 482a412aa65..5bd7fe64637 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
@@ -52,12 +52,22 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-----------------------------------------------------------------------+
*/
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
-#include "APCI1710_Chrono.h"
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
+
+#define APCI1710_SINGLE 0
+#define APCI1710_CONTINUOUS 1
+
+#define APCI1710_CHRONO_PROGRESS_STATUS 0
+#define APCI1710_CHRONO_READVALUE 1
+#define APCI1710_CHRONO_CONVERTVALUE 2
+#define APCI1710_CHRONO_READINTERRUPT 3
+
+#define APCI1710_CHRONO_SET_CHANNELON 0
+#define APCI1710_CHRONO_SET_CHANNELOFF 1
+#define APCI1710_CHRONO_READ_CHANNEL 2
+#define APCI1710_CHRONO_READ_PORT 3
/*
+----------------------------------------------------------------------------+
@@ -130,10 +140,12 @@ You should also find the complete GPL in the COPYING file accompanying this sour
| this CHRONOS version |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int ul_TimerValue = 0;
unsigned int ul_TimingInterval = 0;
@@ -839,10 +851,12 @@ struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
-8: data[0] wrong input |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned char b_ModulNbr, b_CycleMode, b_InterruptEnable, b_Action;
b_ModulNbr = CR_AREF(insn->chanspec);
@@ -1077,87 +1091,6 @@ int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
/*
+----------------------------------------------------------------------------+
-| Function Name :INT i_APCI1710_InsnReadChrono(struct comedi_device *dev,struct comedi_subdevice *s,
-struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Read functions for Timer |
-+----------------------------------------------------------------------------+
-| Input Parameters :
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value :
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned char b_ReadType;
- int i_ReturnValue = insn->n;
-
- b_ReadType = CR_CHAN(insn->chanspec);
-
- switch (b_ReadType) {
- case APCI1710_CHRONO_PROGRESS_STATUS:
- i_ReturnValue = i_APCI1710_GetChronoProgressStatus(dev,
- (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
- break;
-
- case APCI1710_CHRONO_READVALUE:
- i_ReturnValue = i_APCI1710_ReadChronoValue(dev,
- (unsigned char) CR_AREF(insn->chanspec),
- (unsigned int) insn->unused[0],
- (unsigned char *) &data[0], (unsigned int *) &data[1]);
- break;
-
- case APCI1710_CHRONO_CONVERTVALUE:
- i_ReturnValue = i_APCI1710_ConvertChronoValue(dev,
- (unsigned char) CR_AREF(insn->chanspec),
- (unsigned int) insn->unused[0],
- (unsigned int *) &data[0],
- (unsigned char *) &data[1],
- (unsigned char *) &data[2],
- (unsigned int *) &data[3],
- (unsigned int *) &data[4], (unsigned int *) &data[5]);
- break;
-
- case APCI1710_CHRONO_READINTERRUPT:
- printk("In Chrono Read Interrupt\n");
-
- data[0] = devpriv->s_InterruptParameters.
- s_FIFOInterruptParameters[devpriv->
- s_InterruptParameters.ui_Read].b_OldModuleMask;
- data[1] = devpriv->s_InterruptParameters.
- s_FIFOInterruptParameters[devpriv->
- s_InterruptParameters.ui_Read].ul_OldInterruptMask;
- data[2] = devpriv->s_InterruptParameters.
- s_FIFOInterruptParameters[devpriv->
- s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
-
- /**************************/
- /* Increment the read FIFO */
- /***************************/
-
- devpriv->
- s_InterruptParameters.
- ui_Read = (devpriv->
- s_InterruptParameters.
- ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
- break;
-
- default:
- printk("ReadType Parameter wrong\n");
- }
-
- if (i_ReturnValue >= 0)
- i_ReturnValue = insn->n;
- return i_ReturnValue;
-
-}
-
-/*
-+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_GetChronoProgressStatus |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
@@ -1193,10 +1126,11 @@ int i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice
| "i_APCI1710_InitChrono" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_ChronoStatus)
+static int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char *pb_ChronoStatus)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_Status;
@@ -1354,11 +1288,13 @@ int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev,
| directly the chronometer measured timing. |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_ReadChronoValue(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned int ui_TimeOut, unsigned char *pb_ChronoStatus, unsigned int *pul_ChronoValue)
+static int i_APCI1710_ReadChronoValue(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned int ui_TimeOut,
+ unsigned char *pb_ChronoStatus,
+ unsigned int *pul_ChronoValue)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_Status;
unsigned int dw_TimeOut = 0;
@@ -1617,15 +1553,17 @@ int i_APCI1710_ReadChronoValue(struct comedi_device *dev,
| "i_APCI1710_InitChrono" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_ConvertChronoValue(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned int ul_ChronoValue,
- unsigned int *pul_Hour,
- unsigned char *pb_Minute,
- unsigned char *pb_Second,
- unsigned int *pui_MilliSecond, unsigned int *pui_MicroSecond, unsigned int *pui_NanoSecond)
+static int i_APCI1710_ConvertChronoValue(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned int ul_ChronoValue,
+ unsigned int *pul_Hour,
+ unsigned char *pb_Minute,
+ unsigned char *pb_Second,
+ unsigned int *pui_MilliSecond,
+ unsigned int *pui_MicroSecond,
+ unsigned int *pui_NanoSecond)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
double d_Hour;
double d_Minute;
@@ -1756,6 +1694,89 @@ int i_APCI1710_ConvertChronoValue(struct comedi_device *dev,
/*
+----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnReadChrono(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read functions for Timer |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+static int i_APCI1710_InsnReadChrono(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct addi_private *devpriv = dev->private;
+ unsigned char b_ReadType;
+ int i_ReturnValue = insn->n;
+
+ b_ReadType = CR_CHAN(insn->chanspec);
+
+ switch (b_ReadType) {
+ case APCI1710_CHRONO_PROGRESS_STATUS:
+ i_ReturnValue = i_APCI1710_GetChronoProgressStatus(dev,
+ (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
+ break;
+
+ case APCI1710_CHRONO_READVALUE:
+ i_ReturnValue = i_APCI1710_ReadChronoValue(dev,
+ (unsigned char) CR_AREF(insn->chanspec),
+ (unsigned int) insn->unused[0],
+ (unsigned char *) &data[0], (unsigned int *) &data[1]);
+ break;
+
+ case APCI1710_CHRONO_CONVERTVALUE:
+ i_ReturnValue = i_APCI1710_ConvertChronoValue(dev,
+ (unsigned char) CR_AREF(insn->chanspec),
+ (unsigned int) insn->unused[0],
+ (unsigned int *) &data[0],
+ (unsigned char *) &data[1],
+ (unsigned char *) &data[2],
+ (unsigned int *) &data[3],
+ (unsigned int *) &data[4], (unsigned int *) &data[5]);
+ break;
+
+ case APCI1710_CHRONO_READINTERRUPT:
+ printk("In Chrono Read Interrupt\n");
+
+ data[0] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.
+ ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+ break;
+
+ default:
+ printk("ReadType Parameter wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return i_ReturnValue;
+
+}
+
+/*
++----------------------------------------------------------------------------+
| Function Name : int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,struct comedi_subdevice *s,
struct comedi_insn *insn,unsigned int *data) |
+----------------------------------------------------------------------------+
@@ -1874,10 +1895,12 @@ int i_APCI1710_ConvertChronoValue(struct comedi_device *dev,
| "i_APCI1710_InitChrono" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned char b_ModulNbr, b_OutputChannel, b_InputChannel, b_IOType;
unsigned int dw_Status;
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h
deleted file mode 100644
index 29bad1d144a..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data-com
- * info@addi-data.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.
- */
-
-#define APCI1710_30MHZ 30
-#define APCI1710_33MHZ 33
-#define APCI1710_40MHZ 40
-
-#define APCI1710_SINGLE 0
-#define APCI1710_CONTINUOUS 1
-
-#define APCI1710_CHRONO_PROGRESS_STATUS 0
-#define APCI1710_CHRONO_READVALUE 1
-#define APCI1710_CHRONO_CONVERTVALUE 2
-#define APCI1710_CHRONO_READINTERRUPT 3
-
-#define APCI1710_CHRONO_SET_CHANNELON 0
-#define APCI1710_CHRONO_SET_CHANNELOFF 1
-#define APCI1710_CHRONO_READ_CHANNEL 2
-#define APCI1710_CHRONO_READ_PORT 3
-
-/*
- * CHRONOMETER INISIALISATION FUNCTION
- */
-int i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-
-/*
- * CHRONOMETER READ FUNCTION
- */
-int i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_ChronoStatus);
-
-int i_APCI1710_ReadChronoValue(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned int ui_TimeOut, unsigned char *pb_ChronoStatus,
- unsigned int *pul_ChronoValue);
-
-int i_APCI1710_ConvertChronoValue(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned int ul_ChronoValue,
- unsigned int *pul_Hour,
- unsigned char *pb_Minute,
- unsigned char *pb_Second,
- unsigned int *pui_MilliSecond, unsigned int *pui_MicroSecond,
- unsigned int *pui_NanoSecond);
-
-/*
- * CHRONOMETER DIGITAL INPUT OUTPUT FUNCTION
- */
-int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
index 07108f9f4a4..6b38ce7a275 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
@@ -52,12 +52,16 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-----------------------------------------------------------------------+
*/
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
-#include "APCI1710_Dig_io.h"
+/* Digital Output ON or OFF */
+#define APCI1710_ON 1
+#define APCI1710_OFF 0
+
+/* Digital I/O */
+#define APCI1710_INPUT 0
+#define APCI1710_OUTPUT 1
+
+#define APCI1710_DIGIO_MEMORYONOFF 0x10
+#define APCI1710_DIGIO_INIT 0x11
/*
+----------------------------------------------------------------------------+
@@ -99,9 +103,12 @@ Activates and deactivates the digital output memory.
+----------------------------------------------------------------------------+
*/
-int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned char b_ModulNbr, b_ChannelAMode, b_ChannelBMode;
unsigned char b_MemoryOnOff, b_ConfigType;
int i_ReturnValue = 0;
@@ -293,9 +300,12 @@ int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subd
* unsigned char_ b_ModulNbr, unsigned char_ b_InputChannel,
* unsigned char *_ pb_ChannelStatus)
*/
-int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg;
unsigned char b_ModulNbr, b_InputChannel;
@@ -481,9 +491,12 @@ int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,
* _INT_ i_APCI1710_SetDigitalIOChlOn (unsigned char_ b_BoardHandle,
* unsigned char_ b_ModulNbr, unsigned char_ b_OutputChannel)
*/
-int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_WriteValue = 0;
unsigned char b_ModulNbr, b_OutputChannel;
@@ -731,9 +744,12 @@ int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev,
* b_BoardHandle, unsigned char_ b_ModulNbr, unsigned char_
* b_PortValue)
*/
-int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_WriteValue = 0;
unsigned int dw_StatusReg;
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h
deleted file mode 100644
index cc3973d7c2a..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-#define APCI1710_ON 1 /* Digital Output ON or OFF */
-#define APCI1710_OFF 0
-
-#define APCI1710_INPUT 0 /* Digital I/O */
-#define APCI1710_OUTPUT 1
-
-#define APCI1710_DIGIO_MEMORYONOFF 0x10
-#define APCI1710_DIGIO_INIT 0x11
-
-/*
- * DIGITAL I/O INISIALISATION FUNCTION
- */
-int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/*
- * INPUT OUTPUT FUNCTIONS
- */
-int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
index 14b13eae4c5..70a7f953fa2 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
@@ -51,93 +51,121 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-----------------------------------------------------------------------+
*/
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
-
-#include "APCI1710_INCCPT.h"
-
-/*
-+----------------------------------------------------------------------------+
-| int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
-struct comedi_insn *insn,unsigned int *data)
-
-+----------------------------------------------------------------------------+
-| Task : Configuration function for INC_CPT |
-+----------------------------------------------------------------------------+
-| Input Parameters : |
-+----------------------------------------------------------------------------+
-| Output Parameters : *data
-+----------------------------------------------------------------------------+
-| Return Value : |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_ConfigType;
- int i_ReturnValue = 0;
- ui_ConfigType = CR_CHAN(insn->chanspec);
-
- printk("\nINC_CPT");
-
- devpriv->tsk_Current = current; /* Save the current process task structure */
- switch (ui_ConfigType) {
- case APCI1710_INCCPT_INITCOUNTER:
- i_ReturnValue = i_APCI1710_InitCounter(dev,
- CR_AREF(insn->chanspec),
- (unsigned char) data[0],
- (unsigned char) data[1],
- (unsigned char) data[2], (unsigned char) data[3], (unsigned char) data[4]);
- break;
-
- case APCI1710_INCCPT_COUNTERAUTOTEST:
- i_ReturnValue = i_APCI1710_CounterAutoTest(dev,
- (unsigned char *) &data[0]);
- break;
-
- case APCI1710_INCCPT_INITINDEX:
- i_ReturnValue = i_APCI1710_InitIndex(dev,
- CR_AREF(insn->chanspec),
- (unsigned char) data[0],
- (unsigned char) data[1], (unsigned char) data[2], (unsigned char) data[3]);
- break;
-
- case APCI1710_INCCPT_INITREFERENCE:
- i_ReturnValue = i_APCI1710_InitReference(dev,
- CR_AREF(insn->chanspec), (unsigned char) data[0]);
- break;
-
- case APCI1710_INCCPT_INITEXTERNALSTROBE:
- i_ReturnValue = i_APCI1710_InitExternalStrobe(dev,
- CR_AREF(insn->chanspec),
- (unsigned char) data[0], (unsigned char) data[1]);
- break;
-
- case APCI1710_INCCPT_INITCOMPARELOGIC:
- i_ReturnValue = i_APCI1710_InitCompareLogic(dev,
- CR_AREF(insn->chanspec), (unsigned int) data[0]);
- break;
-
- case APCI1710_INCCPT_INITFREQUENCYMEASUREMENT:
- i_ReturnValue = i_APCI1710_InitFrequencyMeasurement(dev,
- CR_AREF(insn->chanspec),
- (unsigned char) data[0],
- (unsigned char) data[1], (unsigned int) data[2], (unsigned int *) &data[0]);
- break;
-
- default:
- printk("Insn Config : Config Parameter Wrong\n");
-
- }
-
- if (i_ReturnValue >= 0)
- i_ReturnValue = insn->n;
- return i_ReturnValue;
-}
+#define APCI1710_16BIT_COUNTER 0x10
+#define APCI1710_32BIT_COUNTER 0x0
+#define APCI1710_QUADRUPLE_MODE 0x0
+#define APCI1710_DOUBLE_MODE 0x3
+#define APCI1710_SIMPLE_MODE 0xF
+#define APCI1710_DIRECT_MODE 0x80
+#define APCI1710_HYSTERESIS_ON 0x60
+#define APCI1710_HYSTERESIS_OFF 0x0
+#define APCI1710_INCREMENT 0x60
+#define APCI1710_DECREMENT 0x0
+#define APCI1710_LATCH_COUNTER 0x1
+#define APCI1710_CLEAR_COUNTER 0x0
+#define APCI1710_LOW 0x0
+#define APCI1710_HIGH 0x1
+
+/*********************/
+/* Version 0600-0229 */
+/*********************/
+#define APCI1710_HIGH_EDGE_CLEAR_COUNTER 0x0
+#define APCI1710_HIGH_EDGE_LATCH_COUNTER 0x1
+#define APCI1710_LOW_EDGE_CLEAR_COUNTER 0x2
+#define APCI1710_LOW_EDGE_LATCH_COUNTER 0x3
+#define APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER 0x4
+#define APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER 0x5
+#define APCI1710_SOURCE_0 0x0
+#define APCI1710_SOURCE_1 0x1
+
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
+
+#define APCI1710_ENABLE_LATCH_INT 0x80
+#define APCI1710_DISABLE_LATCH_INT (~APCI1710_ENABLE_LATCH_INT)
+
+#define APCI1710_INDEX_LATCH_COUNTER 0x10
+#define APCI1710_INDEX_AUTO_MODE 0x8
+#define APCI1710_ENABLE_INDEX 0x4
+#define APCI1710_DISABLE_INDEX (~APCI1710_ENABLE_INDEX)
+#define APCI1710_ENABLE_LATCH_AND_CLEAR 0x8
+#define APCI1710_DISABLE_LATCH_AND_CLEAR (~APCI1710_ENABLE_LATCH_AND_CLEAR)
+#define APCI1710_SET_LOW_INDEX_LEVEL 0x4
+#define APCI1710_SET_HIGH_INDEX_LEVEL (~APCI1710_SET_LOW_INDEX_LEVEL)
+#define APCI1710_INVERT_INDEX_RFERENCE 0x2
+#define APCI1710_DEFAULT_INDEX_RFERENCE (~APCI1710_INVERT_INDEX_RFERENCE)
+
+#define APCI1710_ENABLE_INDEX_INT 0x1
+#define APCI1710_DISABLE_INDEX_INT (~APCI1710_ENABLE_INDEX_INT)
+
+#define APCI1710_ENABLE_FREQUENCY 0x4
+#define APCI1710_DISABLE_FREQUENCY (~APCI1710_ENABLE_FREQUENCY)
+
+#define APCI1710_ENABLE_FREQUENCY_INT 0x8
+#define APCI1710_DISABLE_FREQUENCY_INT (~APCI1710_ENABLE_FREQUENCY_INT)
+
+#define APCI1710_ENABLE_40MHZ_FREQUENCY 0x40
+#define APCI1710_DISABLE_40MHZ_FREQUENCY (~APCI1710_ENABLE_40MHZ_FREQUENCY)
+
+#define APCI1710_ENABLE_40MHZ_FILTER 0x80
+#define APCI1710_DISABLE_40MHZ_FILTER (~APCI1710_ENABLE_40MHZ_FILTER)
+
+#define APCI1710_ENABLE_COMPARE_INT 0x2
+#define APCI1710_DISABLE_COMPARE_INT (~APCI1710_ENABLE_COMPARE_INT)
+
+#define APCI1710_ENABLE_INDEX_ACTION 0x20
+#define APCI1710_DISABLE_INDEX_ACTION (~APCI1710_ENABLE_INDEX_ACTION)
+#define APCI1710_REFERENCE_HIGH 0x40
+#define APCI1710_REFERENCE_LOW (~APCI1710_REFERENCE_HIGH)
+
+#define APCI1710_TOR_GATE_LOW 0x40
+#define APCI1710_TOR_GATE_HIGH (~APCI1710_TOR_GATE_LOW)
+
+/* INSN CONFIG */
+#define APCI1710_INCCPT_INITCOUNTER 100
+#define APCI1710_INCCPT_COUNTERAUTOTEST 101
+#define APCI1710_INCCPT_INITINDEX 102
+#define APCI1710_INCCPT_INITREFERENCE 103
+#define APCI1710_INCCPT_INITEXTERNALSTROBE 104
+#define APCI1710_INCCPT_INITCOMPARELOGIC 105
+#define APCI1710_INCCPT_INITFREQUENCYMEASUREMENT 106
+
+/* INSN READ */
+#define APCI1710_INCCPT_READLATCHREGISTERSTATUS 200
+#define APCI1710_INCCPT_READLATCHREGISTERVALUE 201
+#define APCI1710_INCCPT_READ16BITCOUNTERVALUE 202
+#define APCI1710_INCCPT_READ32BITCOUNTERVALUE 203
+#define APCI1710_INCCPT_GETINDEXSTATUS 204
+#define APCI1710_INCCPT_GETREFERENCESTATUS 205
+#define APCI1710_INCCPT_GETUASSTATUS 206
+#define APCI1710_INCCPT_GETCBSTATUS 207
+#define APCI1710_INCCPT_GET16BITCBSTATUS 208
+#define APCI1710_INCCPT_GETUDSTATUS 209
+#define APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS 210
+#define APCI1710_INCCPT_READFREQUENCYMEASUREMENT 211
+#define APCI1710_INCCPT_READINTERRUPT 212
+
+/* INSN BITS */
+#define APCI1710_INCCPT_CLEARCOUNTERVALUE 300
+#define APCI1710_INCCPT_CLEARALLCOUNTERVALUE 301
+#define APCI1710_INCCPT_SETINPUTFILTER 302
+#define APCI1710_INCCPT_LATCHCOUNTER 303
+#define APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE 304
+#define APCI1710_INCCPT_SETDIGITALCHLON 305
+#define APCI1710_INCCPT_SETDIGITALCHLOFF 306
+
+/* INSN WRITE */
+#define APCI1710_INCCPT_ENABLELATCHINTERRUPT 400
+#define APCI1710_INCCPT_DISABLELATCHINTERRUPT 401
+#define APCI1710_INCCPT_WRITE16BITCOUNTERVALUE 402
+#define APCI1710_INCCPT_WRITE32BITCOUNTERVALUE 403
+#define APCI1710_INCCPT_ENABLEINDEX 404
+#define APCI1710_INCCPT_DISABLEINDEX 405
+#define APCI1710_INCCPT_ENABLECOMPARELOGIC 406
+#define APCI1710_INCCPT_DISABLECOMPARELOGIC 407
+#define APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT 408
+#define APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT 409
/*
+----------------------------------------------------------------------------+
@@ -298,14 +326,15 @@ int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, struct comedi_subdevi
| wrong. |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_InitCounter(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_CounterRange,
- unsigned char b_FirstCounterModus,
- unsigned char b_FirstCounterOption,
- unsigned char b_SecondCounterModus, unsigned char b_SecondCounterOption)
+static int i_APCI1710_InitCounter(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_CounterRange,
+ unsigned char b_FirstCounterModus,
+ unsigned char b_FirstCounterOption,
+ unsigned char b_SecondCounterModus,
+ unsigned char b_SecondCounterOption)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/*******************************/
@@ -544,9 +573,10 @@ int i_APCI1710_InitCounter(struct comedi_device *dev,
| -2: No counter module found |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_CounterAutoTest(struct comedi_device *dev, unsigned char *pb_TestStatus)
+static int i_APCI1710_CounterAutoTest(struct comedi_device *dev,
+ unsigned char *pb_TestStatus)
{
+ struct addi_private *devpriv = dev->private;
unsigned char b_ModulCpt = 0;
int i_ReturnValue = 0;
unsigned int dw_LathchValue;
@@ -707,12 +737,14 @@ int i_APCI1710_CounterAutoTest(struct comedi_device *dev, unsigned char *pb_Test
| See function "i_APCI1710_SetBoardIntRoutineX" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_InitIndex(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_ReferenceAction,
- unsigned char b_IndexOperation, unsigned char b_AutoMode, unsigned char b_InterruptEnable)
+static int i_APCI1710_InitIndex(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_ReferenceAction,
+ unsigned char b_IndexOperation,
+ unsigned char b_AutoMode,
+ unsigned char b_InterruptEnable)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -1151,10 +1183,11 @@ int i_APCI1710_InitIndex(struct comedi_device *dev,
| -4: Reference level parameter is wrong |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_InitReference(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_ReferenceLevel)
+static int i_APCI1710_InitReference(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_ReferenceLevel)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -1276,10 +1309,12 @@ int i_APCI1710_InitReference(struct comedi_device *dev,
| -5: External strobe level parameter is wrong |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_InitExternalStrobe(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_ExternalStrobe, unsigned char b_ExternalStrobeLevel)
+static int i_APCI1710_InitExternalStrobe(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_ExternalStrobe,
+ unsigned char b_ExternalStrobeLevel)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -1390,10 +1425,11 @@ int i_APCI1710_InitExternalStrobe(struct comedi_device *dev,
| "i_APCI1710_InitCounter" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_InitCompareLogic(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned int ui_CompareValue)
+static int i_APCI1710_InitCompareLogic(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned int ui_CompareValue)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -1486,13 +1522,14 @@ int i_APCI1710_InitCompareLogic(struct comedi_device *dev,
| -7: 40MHz quartz not on board |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_PCIInputClock,
- unsigned char b_TimingUnity,
- unsigned int ul_TimingInterval, unsigned int *pul_RealTimingInterval)
+static int i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_PCIInputClock,
+ unsigned char b_TimingUnity,
+ unsigned int ul_TimingInterval,
+ unsigned int *pul_RealTimingInterval)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int ul_TimerValue = 0;
double d_RealTimingInterval;
@@ -1995,72 +2032,70 @@ int i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev,
return i_ReturnValue;
}
-/*########################################################################### */
-
- /* INSN BITS */
-/*########################################################################### */
-
/*
-+----------------------------------------------------------------------------+
-| Function Name :INT i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
-struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Set & Clear Functions for INC_CPT |
-+----------------------------------------------------------------------------+
-| Input Parameters :
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value :
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ * Configuration function for INC_CPT
+ */
+static int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned int ui_BitsType;
+ struct addi_private *devpriv = dev->private;
+ unsigned int ui_ConfigType;
int i_ReturnValue = 0;
- ui_BitsType = CR_CHAN(insn->chanspec);
- devpriv->tsk_Current = current; /* Save the current process task structure */
- switch (ui_BitsType) {
- case APCI1710_INCCPT_CLEARCOUNTERVALUE:
- i_ReturnValue = i_APCI1710_ClearCounterValue(dev,
- (unsigned char) CR_AREF(insn->chanspec));
+ ui_ConfigType = CR_CHAN(insn->chanspec);
+
+ printk("\nINC_CPT");
+
+ devpriv->tsk_Current = current; /* Save the current process task structure */
+ switch (ui_ConfigType) {
+ case APCI1710_INCCPT_INITCOUNTER:
+ i_ReturnValue = i_APCI1710_InitCounter(dev,
+ CR_AREF(insn->chanspec),
+ (unsigned char) data[0],
+ (unsigned char) data[1],
+ (unsigned char) data[2], (unsigned char) data[3], (unsigned char) data[4]);
break;
- case APCI1710_INCCPT_CLEARALLCOUNTERVALUE:
- i_ReturnValue = i_APCI1710_ClearAllCounterValue(dev);
+ case APCI1710_INCCPT_COUNTERAUTOTEST:
+ i_ReturnValue = i_APCI1710_CounterAutoTest(dev,
+ (unsigned char *) &data[0]);
break;
- case APCI1710_INCCPT_SETINPUTFILTER:
- i_ReturnValue = i_APCI1710_SetInputFilter(dev,
- (unsigned char) CR_AREF(insn->chanspec),
- (unsigned char) data[0], (unsigned char) data[1]);
+ case APCI1710_INCCPT_INITINDEX:
+ i_ReturnValue = i_APCI1710_InitIndex(dev,
+ CR_AREF(insn->chanspec),
+ (unsigned char) data[0],
+ (unsigned char) data[1], (unsigned char) data[2], (unsigned char) data[3]);
break;
- case APCI1710_INCCPT_LATCHCOUNTER:
- i_ReturnValue = i_APCI1710_LatchCounter(dev,
- (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]);
+ case APCI1710_INCCPT_INITREFERENCE:
+ i_ReturnValue = i_APCI1710_InitReference(dev,
+ CR_AREF(insn->chanspec), (unsigned char) data[0]);
break;
- case APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE:
- i_ReturnValue = i_APCI1710_SetIndexAndReferenceSource(dev,
- (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]);
+ case APCI1710_INCCPT_INITEXTERNALSTROBE:
+ i_ReturnValue = i_APCI1710_InitExternalStrobe(dev,
+ CR_AREF(insn->chanspec),
+ (unsigned char) data[0], (unsigned char) data[1]);
break;
- case APCI1710_INCCPT_SETDIGITALCHLON:
- i_ReturnValue = i_APCI1710_SetDigitalChlOn(dev,
- (unsigned char) CR_AREF(insn->chanspec));
+ case APCI1710_INCCPT_INITCOMPARELOGIC:
+ i_ReturnValue = i_APCI1710_InitCompareLogic(dev,
+ CR_AREF(insn->chanspec), (unsigned int) data[0]);
break;
- case APCI1710_INCCPT_SETDIGITALCHLOFF:
- i_ReturnValue = i_APCI1710_SetDigitalChlOff(dev,
- (unsigned char) CR_AREF(insn->chanspec));
+ case APCI1710_INCCPT_INITFREQUENCYMEASUREMENT:
+ i_ReturnValue = i_APCI1710_InitFrequencyMeasurement(dev,
+ CR_AREF(insn->chanspec),
+ (unsigned char) data[0],
+ (unsigned char) data[1], (unsigned int) data[2], (unsigned int *) &data[0]);
break;
default:
- printk("Bits Config Parameter Wrong\n");
+ printk("Insn Config : Config Parameter Wrong\n");
+
}
if (i_ReturnValue >= 0)
@@ -2090,9 +2125,10 @@ int i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice
| "i_APCI1710_InitCounter" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_ClearCounterValue(struct comedi_device *dev, unsigned char b_ModulNbr)
+static int i_APCI1710_ClearCounterValue(struct comedi_device *dev,
+ unsigned char b_ModulNbr)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -2150,9 +2186,9 @@ int i_APCI1710_ClearCounterValue(struct comedi_device *dev, unsigned char b_Modu
| -2: No counter module found |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_ClearAllCounterValue(struct comedi_device *dev)
+static int i_APCI1710_ClearAllCounterValue(struct comedi_device *dev)
{
+ struct addi_private *devpriv = dev->private;
unsigned char b_ModulCpt = 0;
int i_ReturnValue = 0;
@@ -2296,10 +2332,12 @@ int i_APCI1710_ClearAllCounterValue(struct comedi_device *dev)
| -6: 40MHz quartz not on board |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_SetInputFilter(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_PCIInputClock, unsigned char b_Filter)
+static int i_APCI1710_SetInputFilter(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_PCIInputClock,
+ unsigned char b_Filter)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_Status = 0;
@@ -2560,10 +2598,11 @@ int i_APCI1710_SetInputFilter(struct comedi_device *dev,
| -4: The selected latch register parameter is wrong |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_LatchCounter(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_LatchReg)
+static int i_APCI1710_LatchCounter(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_LatchReg)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -2657,10 +2696,11 @@ int i_APCI1710_LatchCounter(struct comedi_device *dev,
| -4: The source selection is wrong |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_SourceSelection)
+static int i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_SourceSelection)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -2794,9 +2834,10 @@ int i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev,
| "i_APCI1710_InitCounter" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, unsigned char b_ModulNbr)
+static int i_APCI1710_SetDigitalChlOn(struct comedi_device *dev,
+ unsigned char b_ModulNbr)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -2874,9 +2915,10 @@ int i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, unsigned char b_ModulN
| "i_APCI1710_InitCounter" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, unsigned char b_ModulNbr)
+static int i_APCI1710_SetDigitalChlOff(struct comedi_device *dev,
+ unsigned char b_ModulNbr)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -2932,88 +2974,59 @@ int i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, unsigned char b_Modul
return i_ReturnValue;
}
-/*########################################################################### */
-
- /* INSN WRITE */
-/*########################################################################### */
-
/*
-+----------------------------------------------------------------------------+
-| Function Name :INT i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
-struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Enable Disable functions for INC_CPT |
-+----------------------------------------------------------------------------+
-| Input Parameters :
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value :
-+----------------------------------------------------------------------------+
-*/
-int i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ * Set & Clear Functions for INC_CPT
+ */
+static int i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned int ui_WriteType;
+ struct addi_private *devpriv = dev->private;
+ unsigned int ui_BitsType;
int i_ReturnValue = 0;
- ui_WriteType = CR_CHAN(insn->chanspec);
+ ui_BitsType = CR_CHAN(insn->chanspec);
devpriv->tsk_Current = current; /* Save the current process task structure */
- switch (ui_WriteType) {
- case APCI1710_INCCPT_ENABLELATCHINTERRUPT:
- i_ReturnValue = i_APCI1710_EnableLatchInterrupt(dev,
+ switch (ui_BitsType) {
+ case APCI1710_INCCPT_CLEARCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_ClearCounterValue(dev,
(unsigned char) CR_AREF(insn->chanspec));
break;
- case APCI1710_INCCPT_DISABLELATCHINTERRUPT:
- i_ReturnValue = i_APCI1710_DisableLatchInterrupt(dev,
- (unsigned char) CR_AREF(insn->chanspec));
+ case APCI1710_INCCPT_CLEARALLCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_ClearAllCounterValue(dev);
break;
- case APCI1710_INCCPT_WRITE16BITCOUNTERVALUE:
- i_ReturnValue = i_APCI1710_Write16BitCounterValue(dev,
+ case APCI1710_INCCPT_SETINPUTFILTER:
+ i_ReturnValue = i_APCI1710_SetInputFilter(dev,
(unsigned char) CR_AREF(insn->chanspec),
- (unsigned char) data[0], (unsigned int) data[1]);
- break;
-
- case APCI1710_INCCPT_WRITE32BITCOUNTERVALUE:
- i_ReturnValue = i_APCI1710_Write32BitCounterValue(dev,
- (unsigned char) CR_AREF(insn->chanspec), (unsigned int) data[0]);
-
- break;
-
- case APCI1710_INCCPT_ENABLEINDEX:
- i_APCI1710_EnableIndex(dev, (unsigned char) CR_AREF(insn->chanspec));
+ (unsigned char) data[0], (unsigned char) data[1]);
break;
- case APCI1710_INCCPT_DISABLEINDEX:
- i_ReturnValue = i_APCI1710_DisableIndex(dev,
- (unsigned char) CR_AREF(insn->chanspec));
+ case APCI1710_INCCPT_LATCHCOUNTER:
+ i_ReturnValue = i_APCI1710_LatchCounter(dev,
+ (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]);
break;
- case APCI1710_INCCPT_ENABLECOMPARELOGIC:
- i_ReturnValue = i_APCI1710_EnableCompareLogic(dev,
- (unsigned char) CR_AREF(insn->chanspec));
+ case APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE:
+ i_ReturnValue = i_APCI1710_SetIndexAndReferenceSource(dev,
+ (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]);
break;
- case APCI1710_INCCPT_DISABLECOMPARELOGIC:
- i_ReturnValue = i_APCI1710_DisableCompareLogic(dev,
+ case APCI1710_INCCPT_SETDIGITALCHLON:
+ i_ReturnValue = i_APCI1710_SetDigitalChlOn(dev,
(unsigned char) CR_AREF(insn->chanspec));
break;
- case APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT:
- i_ReturnValue = i_APCI1710_EnableFrequencyMeasurement(dev,
- (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]);
- break;
-
- case APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT:
- i_ReturnValue = i_APCI1710_DisableFrequencyMeasurement(dev,
+ case APCI1710_INCCPT_SETDIGITALCHLOFF:
+ i_ReturnValue = i_APCI1710_SetDigitalChlOff(dev,
(unsigned char) CR_AREF(insn->chanspec));
break;
default:
- printk("Write Config Parameter Wrong\n");
+ printk("Bits Config Parameter Wrong\n");
}
if (i_ReturnValue >= 0)
@@ -3046,9 +3059,10 @@ int i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevic
| "i_APCI1710_SetBoardIntRoutine" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, unsigned char b_ModulNbr)
+static int i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev,
+ unsigned char b_ModulNbr)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -3132,9 +3146,10 @@ int i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, unsigned char b_M
| "i_APCI1710_SetBoardIntRoutine" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, unsigned char b_ModulNbr)
+static int i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev,
+ unsigned char b_ModulNbr)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -3230,10 +3245,12 @@ int i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, unsigned char b_
| -4: The selected 16-Bit counter parameter is wrong |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_Write16BitCounterValue(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_SelectedCounter, unsigned int ui_WriteValue)
+static int i_APCI1710_Write16BitCounterValue(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_SelectedCounter,
+ unsigned int ui_WriteValue)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -3315,10 +3332,11 @@ int i_APCI1710_Write16BitCounterValue(struct comedi_device *dev,
| "i_APCI1710_InitCounter" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_Write32BitCounterValue(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned int ul_WriteValue)
+static int i_APCI1710_Write32BitCounterValue(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned int ul_WriteValue)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -3382,9 +3400,10 @@ int i_APCI1710_Write32BitCounterValue(struct comedi_device *dev,
| "i_APCI1710_InitIndex" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_EnableIndex(struct comedi_device *dev, unsigned char b_ModulNbr)
+static int i_APCI1710_EnableIndex(struct comedi_device *dev,
+ unsigned char b_ModulNbr)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int ul_InterruptLatchReg;
@@ -3480,9 +3499,10 @@ int i_APCI1710_EnableIndex(struct comedi_device *dev, unsigned char b_ModulNbr)
| "i_APCI1710_InitIndex" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_DisableIndex(struct comedi_device *dev, unsigned char b_ModulNbr)
+static int i_APCI1710_DisableIndex(struct comedi_device *dev,
+ unsigned char b_ModulNbr)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -3579,9 +3599,10 @@ int i_APCI1710_DisableIndex(struct comedi_device *dev, unsigned char b_ModulNbr)
| See function "i_APCI1710_SetBoardIntRoutineX" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_EnableCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr)
+static int i_APCI1710_EnableCompareLogic(struct comedi_device *dev,
+ unsigned char b_ModulNbr)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -3679,9 +3700,10 @@ int i_APCI1710_EnableCompareLogic(struct comedi_device *dev, unsigned char b_Mod
| See function "i_APCI1710_InitCompareLogic" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_DisableCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr)
+static int i_APCI1710_DisableCompareLogic(struct comedi_device *dev,
+ unsigned char b_ModulNbr)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -3788,10 +3810,11 @@ int i_APCI1710_DisableCompareLogic(struct comedi_device *dev, unsigned char b_Mo
| -6: Interrupt function not initialised. |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_InterruptEnable)
+static int i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_InterruptEnable)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -3935,9 +3958,10 @@ int i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev,
| See function "i_APCI1710_InitFrequencyMeasurement" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev, unsigned char b_ModulNbr)
+static int i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev,
+ unsigned char b_ModulNbr)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -4029,134 +4053,80 @@ int i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev, unsigned c
return i_ReturnValue;
}
-/*########################################################################### */
-
- /* INSN READ */
-
-/*########################################################################### */
-
/*
-+----------------------------------------------------------------------------+
-| Function Name :INT i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
-struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Read and Get functions for INC_CPT |
-+----------------------------------------------------------------------------+
-| Input Parameters :
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value :
-+----------------------------------------------------------------------------+
-*/
-int i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ * Enable Disable functions for INC_CPT
+ */
+static int i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned int ui_ReadType;
+ struct addi_private *devpriv = dev->private;
+ unsigned int ui_WriteType;
int i_ReturnValue = 0;
- ui_ReadType = CR_CHAN(insn->chanspec);
-
+ ui_WriteType = CR_CHAN(insn->chanspec);
devpriv->tsk_Current = current; /* Save the current process task structure */
- switch (ui_ReadType) {
- case APCI1710_INCCPT_READLATCHREGISTERSTATUS:
- i_ReturnValue = i_APCI1710_ReadLatchRegisterStatus(dev,
- (unsigned char) CR_AREF(insn->chanspec),
- (unsigned char) CR_RANGE(insn->chanspec), (unsigned char *) &data[0]);
- break;
- case APCI1710_INCCPT_READLATCHREGISTERVALUE:
- i_ReturnValue = i_APCI1710_ReadLatchRegisterValue(dev,
- (unsigned char) CR_AREF(insn->chanspec),
- (unsigned char) CR_RANGE(insn->chanspec), (unsigned int *) &data[0]);
- printk("Latch Register Value %d\n", data[0]);
+ switch (ui_WriteType) {
+ case APCI1710_INCCPT_ENABLELATCHINTERRUPT:
+ i_ReturnValue = i_APCI1710_EnableLatchInterrupt(dev,
+ (unsigned char) CR_AREF(insn->chanspec));
break;
- case APCI1710_INCCPT_READ16BITCOUNTERVALUE:
- i_ReturnValue = i_APCI1710_Read16BitCounterValue(dev,
- (unsigned char) CR_AREF(insn->chanspec),
- (unsigned char) CR_RANGE(insn->chanspec), (unsigned int *) &data[0]);
+ case APCI1710_INCCPT_DISABLELATCHINTERRUPT:
+ i_ReturnValue = i_APCI1710_DisableLatchInterrupt(dev,
+ (unsigned char) CR_AREF(insn->chanspec));
break;
- case APCI1710_INCCPT_READ32BITCOUNTERVALUE:
- i_ReturnValue = i_APCI1710_Read32BitCounterValue(dev,
- (unsigned char) CR_AREF(insn->chanspec), (unsigned int *) &data[0]);
+ case APCI1710_INCCPT_WRITE16BITCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_Write16BitCounterValue(dev,
+ (unsigned char) CR_AREF(insn->chanspec),
+ (unsigned char) data[0], (unsigned int) data[1]);
break;
- case APCI1710_INCCPT_GETINDEXSTATUS:
- i_ReturnValue = i_APCI1710_GetIndexStatus(dev,
- (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
- break;
+ case APCI1710_INCCPT_WRITE32BITCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_Write32BitCounterValue(dev,
+ (unsigned char) CR_AREF(insn->chanspec), (unsigned int) data[0]);
- case APCI1710_INCCPT_GETREFERENCESTATUS:
- i_ReturnValue = i_APCI1710_GetReferenceStatus(dev,
- (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
break;
- case APCI1710_INCCPT_GETUASSTATUS:
- i_ReturnValue = i_APCI1710_GetUASStatus(dev,
- (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
- break;
-
- case APCI1710_INCCPT_GETCBSTATUS:
- i_ReturnValue = i_APCI1710_GetCBStatus(dev,
- (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
+ case APCI1710_INCCPT_ENABLEINDEX:
+ i_APCI1710_EnableIndex(dev, (unsigned char) CR_AREF(insn->chanspec));
break;
- case APCI1710_INCCPT_GET16BITCBSTATUS:
- i_ReturnValue = i_APCI1710_Get16BitCBStatus(dev,
- (unsigned char) CR_AREF(insn->chanspec),
- (unsigned char *) &data[0], (unsigned char *) &data[1]);
+ case APCI1710_INCCPT_DISABLEINDEX:
+ i_ReturnValue = i_APCI1710_DisableIndex(dev,
+ (unsigned char) CR_AREF(insn->chanspec));
break;
- case APCI1710_INCCPT_GETUDSTATUS:
- i_ReturnValue = i_APCI1710_GetUDStatus(dev,
- (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
-
+ case APCI1710_INCCPT_ENABLECOMPARELOGIC:
+ i_ReturnValue = i_APCI1710_EnableCompareLogic(dev,
+ (unsigned char) CR_AREF(insn->chanspec));
break;
- case APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS:
- i_ReturnValue = i_APCI1710_GetInterruptUDLatchedStatus(dev,
- (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
+ case APCI1710_INCCPT_DISABLECOMPARELOGIC:
+ i_ReturnValue = i_APCI1710_DisableCompareLogic(dev,
+ (unsigned char) CR_AREF(insn->chanspec));
break;
- case APCI1710_INCCPT_READFREQUENCYMEASUREMENT:
- i_ReturnValue = i_APCI1710_ReadFrequencyMeasurement(dev,
- (unsigned char) CR_AREF(insn->chanspec),
- (unsigned char *) &data[0],
- (unsigned char *) &data[1], (unsigned int *) &data[2]);
+ case APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT:
+ i_ReturnValue = i_APCI1710_EnableFrequencyMeasurement(dev,
+ (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]);
break;
- case APCI1710_INCCPT_READINTERRUPT:
- data[0] = devpriv->s_InterruptParameters.
- s_FIFOInterruptParameters[devpriv->
- s_InterruptParameters.ui_Read].b_OldModuleMask;
- data[1] = devpriv->s_InterruptParameters.
- s_FIFOInterruptParameters[devpriv->
- s_InterruptParameters.ui_Read].ul_OldInterruptMask;
- data[2] = devpriv->s_InterruptParameters.
- s_FIFOInterruptParameters[devpriv->
- s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
-
- /**************************/
- /* Increment the read FIFO */
- /***************************/
-
- devpriv->
- s_InterruptParameters.
- ui_Read = (devpriv->s_InterruptParameters.
- ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
-
+ case APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT:
+ i_ReturnValue = i_APCI1710_DisableFrequencyMeasurement(dev,
+ (unsigned char) CR_AREF(insn->chanspec));
break;
default:
- printk("ReadType Parameter wrong\n");
+ printk("Write Config Parameter Wrong\n");
}
if (i_ReturnValue >= 0)
i_ReturnValue = insn->n;
return i_ReturnValue;
-
}
/*
@@ -4192,10 +4162,12 @@ int i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice
| -4: The selected latch register parameter is wrong |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_LatchReg, unsigned char *pb_LatchStatus)
+static int i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_LatchReg,
+ unsigned char *pb_LatchStatus)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_LatchReg;
@@ -4279,10 +4251,12 @@ int i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev,
| -4: The selected latch register parameter is wrong |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_LatchReg, unsigned int *pul_LatchValue)
+static int i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_LatchReg,
+ unsigned int *pul_LatchValue)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -4363,10 +4337,12 @@ int i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev,
| -4: The selected 16-Bit counter parameter is wrong |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_Read16BitCounterValue(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_SelectedCounter, unsigned int *pui_CounterValue)
+static int i_APCI1710_Read16BitCounterValue(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_SelectedCounter,
+ unsigned int *pui_CounterValue)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_LathchValue = 0;
@@ -4458,10 +4434,11 @@ int i_APCI1710_Read16BitCounterValue(struct comedi_device *dev,
| "i_APCI1710_InitCounter" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_Read32BitCounterValue(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned int *pul_CounterValue)
+static int i_APCI1710_Read32BitCounterValue(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned int *pul_CounterValue)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
/**************************/
@@ -4534,10 +4511,11 @@ int i_APCI1710_Read32BitCounterValue(struct comedi_device *dev,
| "i_APCI1710_InitIndex" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_GetIndexStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_IndexStatus)
+static int i_APCI1710_GetIndexStatus(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char *pb_IndexStatus)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg = 0;
@@ -4618,10 +4596,11 @@ int i_APCI1710_GetIndexStatus(struct comedi_device *dev,
| "i_APCI1710_InitReference" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_GetReferenceStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_ReferenceStatus)
+static int i_APCI1710_GetReferenceStatus(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char *pb_ReferenceStatus)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg = 0;
@@ -4702,10 +4681,11 @@ int i_APCI1710_GetReferenceStatus(struct comedi_device *dev,
| "i_APCI1710_InitCounter" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_GetUASStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_UASStatus)
+static int i_APCI1710_GetUASStatus(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char *pb_UASStatus)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg = 0;
@@ -4770,10 +4750,11 @@ int i_APCI1710_GetUASStatus(struct comedi_device *dev,
| "i_APCI1710_InitCounter" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_GetCBStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_CBStatus)
+static int i_APCI1710_GetCBStatus(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char *pb_CBStatus)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg = 0;
@@ -4852,10 +4833,12 @@ int i_APCI1710_GetCBStatus(struct comedi_device *dev,
| -5: Firmware revision error |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_Get16BitCBStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_CBStatusCounter0, unsigned char *pb_CBStatusCounter1)
+static int i_APCI1710_Get16BitCBStatus(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char *pb_CBStatusCounter0,
+ unsigned char *pb_CBStatusCounter1)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg = 0;
@@ -4965,10 +4948,11 @@ int i_APCI1710_Get16BitCBStatus(struct comedi_device *dev,
| "i_APCI1710_InitCounter" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_GetUDStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_UDStatus)
+static int i_APCI1710_GetUDStatus(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char *pb_UDStatus)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg = 0;
@@ -5039,10 +5023,11 @@ int i_APCI1710_GetUDStatus(struct comedi_device *dev,
| See function "i_APCI1710_SetBoardIntRoutineX" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_UDStatus)
+static int i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char *pb_UDStatus)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg = 0;
@@ -5144,11 +5129,13 @@ int i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev,
| See function "i_APCI1710_InitFrequencyMeasurement" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char *pb_Status, unsigned char *pb_UDStatus, unsigned int *pul_ReadValue)
+static int i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char *pb_Status,
+ unsigned char *pb_UDStatus,
+ unsigned int *pul_ReadValue)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int ui_16BitValue;
unsigned int dw_StatusReg;
@@ -5361,3 +5348,118 @@ int i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev,
return i_ReturnValue;
}
+/*
+ * Read and Get functions for INC_CPT
+ */
+static int i_APCI1710_InsnReadINCCPT(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct addi_private *devpriv = dev->private;
+ unsigned int ui_ReadType;
+ int i_ReturnValue = 0;
+
+ ui_ReadType = CR_CHAN(insn->chanspec);
+
+ devpriv->tsk_Current = current; /* Save the current process task structure */
+ switch (ui_ReadType) {
+ case APCI1710_INCCPT_READLATCHREGISTERSTATUS:
+ i_ReturnValue = i_APCI1710_ReadLatchRegisterStatus(dev,
+ (unsigned char) CR_AREF(insn->chanspec),
+ (unsigned char) CR_RANGE(insn->chanspec), (unsigned char *) &data[0]);
+ break;
+
+ case APCI1710_INCCPT_READLATCHREGISTERVALUE:
+ i_ReturnValue = i_APCI1710_ReadLatchRegisterValue(dev,
+ (unsigned char) CR_AREF(insn->chanspec),
+ (unsigned char) CR_RANGE(insn->chanspec), (unsigned int *) &data[0]);
+ printk("Latch Register Value %d\n", data[0]);
+ break;
+
+ case APCI1710_INCCPT_READ16BITCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_Read16BitCounterValue(dev,
+ (unsigned char) CR_AREF(insn->chanspec),
+ (unsigned char) CR_RANGE(insn->chanspec), (unsigned int *) &data[0]);
+ break;
+
+ case APCI1710_INCCPT_READ32BITCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_Read32BitCounterValue(dev,
+ (unsigned char) CR_AREF(insn->chanspec), (unsigned int *) &data[0]);
+ break;
+
+ case APCI1710_INCCPT_GETINDEXSTATUS:
+ i_ReturnValue = i_APCI1710_GetIndexStatus(dev,
+ (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
+ break;
+
+ case APCI1710_INCCPT_GETREFERENCESTATUS:
+ i_ReturnValue = i_APCI1710_GetReferenceStatus(dev,
+ (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
+ break;
+
+ case APCI1710_INCCPT_GETUASSTATUS:
+ i_ReturnValue = i_APCI1710_GetUASStatus(dev,
+ (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
+ break;
+
+ case APCI1710_INCCPT_GETCBSTATUS:
+ i_ReturnValue = i_APCI1710_GetCBStatus(dev,
+ (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
+ break;
+
+ case APCI1710_INCCPT_GET16BITCBSTATUS:
+ i_ReturnValue = i_APCI1710_Get16BitCBStatus(dev,
+ (unsigned char) CR_AREF(insn->chanspec),
+ (unsigned char *) &data[0], (unsigned char *) &data[1]);
+ break;
+
+ case APCI1710_INCCPT_GETUDSTATUS:
+ i_ReturnValue = i_APCI1710_GetUDStatus(dev,
+ (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
+
+ break;
+
+ case APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS:
+ i_ReturnValue = i_APCI1710_GetInterruptUDLatchedStatus(dev,
+ (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
+ break;
+
+ case APCI1710_INCCPT_READFREQUENCYMEASUREMENT:
+ i_ReturnValue = i_APCI1710_ReadFrequencyMeasurement(dev,
+ (unsigned char) CR_AREF(insn->chanspec),
+ (unsigned char *) &data[0],
+ (unsigned char *) &data[1], (unsigned int *) &data[2]);
+ break;
+
+ case APCI1710_INCCPT_READINTERRUPT:
+ data[0] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->s_InterruptParameters.
+ ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ break;
+
+ default:
+ printk("ReadType Parameter wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return i_ReturnValue;
+
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h
deleted file mode 100644
index 358298bfc64..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-#define APCI1710_16BIT_COUNTER 0x10
-#define APCI1710_32BIT_COUNTER 0x0
-#define APCI1710_QUADRUPLE_MODE 0x0
-#define APCI1710_DOUBLE_MODE 0x3
-#define APCI1710_SIMPLE_MODE 0xF
-#define APCI1710_DIRECT_MODE 0x80
-#define APCI1710_HYSTERESIS_ON 0x60
-#define APCI1710_HYSTERESIS_OFF 0x0
-#define APCI1710_INCREMENT 0x60
-#define APCI1710_DECREMENT 0x0
-#define APCI1710_LATCH_COUNTER 0x1
-#define APCI1710_CLEAR_COUNTER 0x0
-#define APCI1710_LOW 0x0
-#define APCI1710_HIGH 0x1
-
-/*********************/
-/* Version 0600-0229 */
-/*********************/
-#define APCI1710_HIGH_EDGE_CLEAR_COUNTER 0x0
-#define APCI1710_HIGH_EDGE_LATCH_COUNTER 0x1
-#define APCI1710_LOW_EDGE_CLEAR_COUNTER 0x2
-#define APCI1710_LOW_EDGE_LATCH_COUNTER 0x3
-#define APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER 0x4
-#define APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER 0x5
-#define APCI1710_SOURCE_0 0x0
-#define APCI1710_SOURCE_1 0x1
-
-#define APCI1710_30MHZ 30
-#define APCI1710_33MHZ 33
-#define APCI1710_40MHZ 40
-
-#define APCI1710_ENABLE_LATCH_INT 0x80
-#define APCI1710_DISABLE_LATCH_INT (~APCI1710_ENABLE_LATCH_INT)
-
-#define APCI1710_INDEX_LATCH_COUNTER 0x10
-#define APCI1710_INDEX_AUTO_MODE 0x8
-#define APCI1710_ENABLE_INDEX 0x4
-#define APCI1710_DISABLE_INDEX (~APCI1710_ENABLE_INDEX)
-#define APCI1710_ENABLE_LATCH_AND_CLEAR 0x8
-#define APCI1710_DISABLE_LATCH_AND_CLEAR (~APCI1710_ENABLE_LATCH_AND_CLEAR)
-#define APCI1710_SET_LOW_INDEX_LEVEL 0x4
-#define APCI1710_SET_HIGH_INDEX_LEVEL (~APCI1710_SET_LOW_INDEX_LEVEL)
-#define APCI1710_INVERT_INDEX_RFERENCE 0x2
-#define APCI1710_DEFAULT_INDEX_RFERENCE (~APCI1710_INVERT_INDEX_RFERENCE)
-
-#define APCI1710_ENABLE_INDEX_INT 0x1
-#define APCI1710_DISABLE_INDEX_INT (~APCI1710_ENABLE_INDEX_INT)
-
-#define APCI1710_ENABLE_FREQUENCY 0x4
-#define APCI1710_DISABLE_FREQUENCY (~APCI1710_ENABLE_FREQUENCY)
-
-#define APCI1710_ENABLE_FREQUENCY_INT 0x8
-#define APCI1710_DISABLE_FREQUENCY_INT (~APCI1710_ENABLE_FREQUENCY_INT)
-
-#define APCI1710_ENABLE_40MHZ_FREQUENCY 0x40
-#define APCI1710_DISABLE_40MHZ_FREQUENCY (~APCI1710_ENABLE_40MHZ_FREQUENCY)
-
-#define APCI1710_ENABLE_40MHZ_FILTER 0x80
-#define APCI1710_DISABLE_40MHZ_FILTER (~APCI1710_ENABLE_40MHZ_FILTER)
-
-#define APCI1710_ENABLE_COMPARE_INT 0x2
-#define APCI1710_DISABLE_COMPARE_INT (~APCI1710_ENABLE_COMPARE_INT)
-
-#define APCI1710_ENABLE_INDEX_ACTION 0x20
-#define APCI1710_DISABLE_INDEX_ACTION (~APCI1710_ENABLE_INDEX_ACTION)
-#define APCI1710_REFERENCE_HIGH 0x40
-#define APCI1710_REFERENCE_LOW (~APCI1710_REFERENCE_HIGH)
-
-#define APCI1710_TOR_GATE_LOW 0x40
-#define APCI1710_TOR_GATE_HIGH (~APCI1710_TOR_GATE_LOW)
-
-/* INSN CONFIG */
-#define APCI1710_INCCPT_INITCOUNTER 100
-#define APCI1710_INCCPT_COUNTERAUTOTEST 101
-#define APCI1710_INCCPT_INITINDEX 102
-#define APCI1710_INCCPT_INITREFERENCE 103
-#define APCI1710_INCCPT_INITEXTERNALSTROBE 104
-#define APCI1710_INCCPT_INITCOMPARELOGIC 105
-#define APCI1710_INCCPT_INITFREQUENCYMEASUREMENT 106
-
-/* INSN READ */
-#define APCI1710_INCCPT_READLATCHREGISTERSTATUS 200
-#define APCI1710_INCCPT_READLATCHREGISTERVALUE 201
-#define APCI1710_INCCPT_READ16BITCOUNTERVALUE 202
-#define APCI1710_INCCPT_READ32BITCOUNTERVALUE 203
-#define APCI1710_INCCPT_GETINDEXSTATUS 204
-#define APCI1710_INCCPT_GETREFERENCESTATUS 205
-#define APCI1710_INCCPT_GETUASSTATUS 206
-#define APCI1710_INCCPT_GETCBSTATUS 207
-#define APCI1710_INCCPT_GET16BITCBSTATUS 208
-#define APCI1710_INCCPT_GETUDSTATUS 209
-#define APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS 210
-#define APCI1710_INCCPT_READFREQUENCYMEASUREMENT 211
-#define APCI1710_INCCPT_READINTERRUPT 212
-
-/* INSN BITS */
-#define APCI1710_INCCPT_CLEARCOUNTERVALUE 300
-#define APCI1710_INCCPT_CLEARALLCOUNTERVALUE 301
-#define APCI1710_INCCPT_SETINPUTFILTER 302
-#define APCI1710_INCCPT_LATCHCOUNTER 303
-#define APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE 304
-#define APCI1710_INCCPT_SETDIGITALCHLON 305
-#define APCI1710_INCCPT_SETDIGITALCHLOFF 306
-
-/* INSN WRITE */
-#define APCI1710_INCCPT_ENABLELATCHINTERRUPT 400
-#define APCI1710_INCCPT_DISABLELATCHINTERRUPT 401
-#define APCI1710_INCCPT_WRITE16BITCOUNTERVALUE 402
-#define APCI1710_INCCPT_WRITE32BITCOUNTERVALUE 403
-#define APCI1710_INCCPT_ENABLEINDEX 404
-#define APCI1710_INCCPT_DISABLEINDEX 405
-#define APCI1710_INCCPT_ENABLECOMPARELOGIC 406
-#define APCI1710_INCCPT_DISABLECOMPARELOGIC 407
-#define APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT 408
-#define APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT 409
-
-/************ Main Functions *************/
-int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int * data);
-
-int i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
- struct comedi_insn *insn, unsigned int * data);
-
-int i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
- struct comedi_insn *insn, unsigned int * data);
-
-int i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
- struct comedi_insn *insn, unsigned int * data);
-
-/*********** Supplementary Functions********/
-
-/* INSN CONFIG */
-int i_APCI1710_InitCounter(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_CounterRange,
- unsigned char b_FirstCounterModus,
- unsigned char b_FirstCounterOption,
- unsigned char b_SecondCounterModus,
- unsigned char b_SecondCounterOption);
-
-int i_APCI1710_CounterAutoTest(struct comedi_device *dev, unsigned char * pb_TestStatus);
-
-int i_APCI1710_InitIndex(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_ReferenceAction,
- unsigned char b_IndexOperation, unsigned char b_AutoMode,
- unsigned char b_InterruptEnable);
-
-int i_APCI1710_InitReference(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_ReferenceLevel);
-
-int i_APCI1710_InitExternalStrobe(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_ExternalStrobe,
- unsigned char b_ExternalStrobeLevel);
-
-int i_APCI1710_InitCompareLogic(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned int ui_CompareValue);
-
-int i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_PCIInputClock,
- unsigned char b_TimingUnity,
- unsigned int ul_TimingInterval,
- unsigned int *pul_RealTimingInterval);
-
-/* INSN BITS */
-int i_APCI1710_ClearCounterValue(struct comedi_device *dev, unsigned char b_ModulNbr);
-
-int i_APCI1710_ClearAllCounterValue(struct comedi_device *dev);
-
-int i_APCI1710_SetInputFilter(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_PCIInputClock,
- unsigned char b_Filter);
-
-int i_APCI1710_LatchCounter(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_LatchReg);
-
-int i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_SourceSelection);
-
-int i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, unsigned char b_ModulNbr);
-
-int i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, unsigned char b_ModulNbr);
-
-/* INSN WRITE */
-int i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, unsigned char b_ModulNbr);
-
-int i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, unsigned char b_ModulNbr);
-
-int i_APCI1710_Write16BitCounterValue(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_SelectedCounter,
- unsigned int ui_WriteValue);
-
-int i_APCI1710_Write32BitCounterValue(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned int ul_WriteValue);
-
-int i_APCI1710_EnableIndex(struct comedi_device *dev, unsigned char b_ModulNbr);
-
-int i_APCI1710_DisableIndex(struct comedi_device *dev, unsigned char b_ModulNbr);
-
-int i_APCI1710_EnableCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr);
-
-int i_APCI1710_DisableCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr);
-
-int i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_InterruptEnable);
-
-int i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev,
- unsigned char b_ModulNbr);
-
-/* INSN READ */
-int i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_LatchReg,
- unsigned char *pb_LatchStatus);
-
-int i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_LatchReg,
- unsigned int *pul_LatchValue);
-
-int i_APCI1710_Read16BitCounterValue(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char b_SelectedCounter,
- unsigned int *pui_CounterValue);
-
-int i_APCI1710_Read32BitCounterValue(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned int *pul_CounterValue);
-
-int i_APCI1710_GetIndexStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_IndexStatus);
-
-int i_APCI1710_GetReferenceStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_ReferenceStatus);
-
-int i_APCI1710_GetUASStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_UASStatus);
-
-int i_APCI1710_GetCBStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_CBStatus);
-
-int i_APCI1710_Get16BitCBStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_CBStatusCounter0,
- unsigned char *pb_CBStatusCounter1);
-
-int i_APCI1710_GetUDStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_UDStatus);
-
-int i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev,
- unsigned char b_ModulNbr, unsigned char *pb_UDStatus);
-
-int i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char *pb_Status, unsigned char *pb_UDStatus,
- unsigned int *pul_ReadValue);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
index 3f9cfa20d88..be0c6adbdc9 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
@@ -49,13 +49,11 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-----------------------------------------------------------------------+
*/
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
+#define APCI1710_SINGLE 0
+#define APCI1710_CONTINUOUS 1
-#include "APCI1710_Inp_cpt.h"
+#define APCI1710_PULSEENCODER_READ 0
+#define APCI1710_PULSEENCODER_WRITE 1
/*
+----------------------------------------------------------------------------+
@@ -123,12 +121,14 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+----------------------------------------------------------------------------+
*/
-int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_IntRegister;
-
unsigned char b_ModulNbr;
unsigned char b_PulseEncoderNbr;
unsigned char b_InputLevelSelection;
@@ -414,9 +414,12 @@ int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev,
+----------------------------------------------------------------------------+
*/
-int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned char b_ModulNbr;
unsigned char b_PulseEncoderNbr;
@@ -708,9 +711,12 @@ int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev,
unsigned char *_ pb_Status)
*/
-int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusRegister;
unsigned char b_ModulNbr;
@@ -834,9 +840,12 @@ int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev,
return i_ReturnValue;
}
-int i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
data[0] = devpriv->s_InterruptParameters.
s_FIFOInterruptParameters[devpriv->
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h
deleted file mode 100644
index 31fbb0bec52..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-#define APCI1710_SINGLE 0
-#define APCI1710_CONTINUOUS 1
-
-#define APCI1710_PULSEENCODER_READ 0
-#define APCI1710_PULSEENCODER_WRITE 1
-
-int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-
-/*
- * READ PULSE ENCODER FUNCTIONS
- */
-int i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-
-/*
- * WRITE PULSE ENCODER FUNCTIONS
- */
-int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
index 8883e666211..a211e78dd3b 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
@@ -47,72 +47,16 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-----------------------------------------------------------------------+
*/
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
-
-#include "APCI1710_Pwm.h"
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name :INT i_APCI1710_InsnConfigPWM(struct comedi_device *dev,
-struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Pwm Init and Get Pwm Initialisation |
-+----------------------------------------------------------------------------+
-| Input Parameters :
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value :
-+----------------------------------------------------------------------------+
-*/
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
-int i_APCI1710_InsnConfigPWM(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned char b_ConfigType;
- int i_ReturnValue = 0;
- b_ConfigType = CR_CHAN(insn->chanspec);
+#define APCI1710_PWM_INIT 0
+#define APCI1710_PWM_GETINITDATA 1
- switch (b_ConfigType) {
- case APCI1710_PWM_INIT:
- i_ReturnValue = i_APCI1710_InitPWM(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */
- (unsigned char) data[0], /* b_PWM */
- (unsigned char) data[1], /* b_ClockSelection */
- (unsigned char) data[2], /* b_TimingUnit */
- (unsigned int) data[3], /* ul_LowTiming */
- (unsigned int) data[4], /* ul_HighTiming */
- (unsigned int *) &data[0], /* pul_RealLowTiming */
- (unsigned int *) &data[1] /* pul_RealHighTiming */
- );
- break;
-
- case APCI1710_PWM_GETINITDATA:
- i_ReturnValue = i_APCI1710_GetPWMInitialisation(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */
- (unsigned char) data[0], /* b_PWM */
- (unsigned char *) &data[0], /* pb_TimingUnit */
- (unsigned int *) &data[1], /* pul_LowTiming */
- (unsigned int *) &data[2], /* pul_HighTiming */
- (unsigned char *) &data[3], /* pb_StartLevel */
- (unsigned char *) &data[4], /* pb_StopMode */
- (unsigned char *) &data[5], /* pb_StopLevel */
- (unsigned char *) &data[6], /* pb_ExternGate */
- (unsigned char *) &data[7], /* pb_InterruptEnable */
- (unsigned char *) &data[8] /* pb_Enable */
- );
- break;
-
- default:
- printk(" Config Parameter Wrong\n");
- }
-
- if (i_ReturnValue >= 0)
- i_ReturnValue = insn->n;
- return i_ReturnValue;
-}
+#define APCI1710_PWM_DISABLE 0
+#define APCI1710_PWM_ENABLE 1
+#define APCI1710_PWM_NEWTIMING 2
/*
+----------------------------------------------------------------------------+
@@ -178,16 +122,17 @@ int i_APCI1710_InsnConfigPWM(struct comedi_device *dev, struct comedi_subdevice
| this board |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_InitPWM(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_PWM,
- unsigned char b_ClockSelection,
- unsigned char b_TimingUnit,
- unsigned int ul_LowTiming,
- unsigned int ul_HighTiming,
- unsigned int *pul_RealLowTiming, unsigned int *pul_RealHighTiming)
+static int i_APCI1710_InitPWM(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_PWM,
+ unsigned char b_ClockSelection,
+ unsigned char b_TimingUnit,
+ unsigned int ul_LowTiming,
+ unsigned int ul_HighTiming,
+ unsigned int *pul_RealLowTiming,
+ unsigned int *pul_RealHighTiming)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int ul_LowTimerValue = 0;
unsigned int ul_HighTimerValue = 0;
@@ -1533,18 +1478,20 @@ int i_APCI1710_InitPWM(struct comedi_device *dev,
| "i_APCI1710_InitPWM" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_PWM,
- unsigned char *pb_TimingUnit,
- unsigned int *pul_LowTiming,
- unsigned int *pul_HighTiming,
- unsigned char *pb_StartLevel,
- unsigned char *pb_StopMode,
- unsigned char *pb_StopLevel,
- unsigned char *pb_ExternGate, unsigned char *pb_InterruptEnable, unsigned char *pb_Enable)
+static int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_PWM,
+ unsigned char *pb_TimingUnit,
+ unsigned int *pul_LowTiming,
+ unsigned int *pul_HighTiming,
+ unsigned char *pb_StartLevel,
+ unsigned char *pb_StopMode,
+ unsigned char *pb_StopLevel,
+ unsigned char *pb_ExternGate,
+ unsigned char *pb_InterruptEnable,
+ unsigned char *pb_Enable)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_Status;
unsigned int dw_Command;
@@ -1669,51 +1616,47 @@ int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev,
}
/*
-+----------------------------------------------------------------------------+
-| Function Name :INT i_APCI1710_InsnWritePWM(struct comedi_device *dev,
-struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Pwm Enable Disable and Set New Timing |
-+----------------------------------------------------------------------------+
-| Input Parameters :
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value :
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI1710_InsnWritePWM(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ * Pwm Init and Get Pwm Initialisation
+ */
+static int i_APCI1710_InsnConfigPWM(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned char b_WriteType;
+ unsigned char b_ConfigType;
int i_ReturnValue = 0;
- b_WriteType = CR_CHAN(insn->chanspec);
-
- switch (b_WriteType) {
- case APCI1710_PWM_ENABLE:
- i_ReturnValue = i_APCI1710_EnablePWM(dev,
- (unsigned char) CR_AREF(insn->chanspec),
- (unsigned char) data[0],
- (unsigned char) data[1],
- (unsigned char) data[2],
- (unsigned char) data[3], (unsigned char) data[4], (unsigned char) data[5]);
- break;
+ b_ConfigType = CR_CHAN(insn->chanspec);
- case APCI1710_PWM_DISABLE:
- i_ReturnValue = i_APCI1710_DisablePWM(dev,
- (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]);
+ switch (b_ConfigType) {
+ case APCI1710_PWM_INIT:
+ i_ReturnValue = i_APCI1710_InitPWM(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */
+ (unsigned char) data[0], /* b_PWM */
+ (unsigned char) data[1], /* b_ClockSelection */
+ (unsigned char) data[2], /* b_TimingUnit */
+ (unsigned int) data[3], /* ul_LowTiming */
+ (unsigned int) data[4], /* ul_HighTiming */
+ (unsigned int *) &data[0], /* pul_RealLowTiming */
+ (unsigned int *) &data[1] /* pul_RealHighTiming */
+ );
break;
- case APCI1710_PWM_NEWTIMING:
- i_ReturnValue = i_APCI1710_SetNewPWMTiming(dev,
- (unsigned char) CR_AREF(insn->chanspec),
- (unsigned char) data[0],
- (unsigned char) data[1], (unsigned int) data[2], (unsigned int) data[3]);
+ case APCI1710_PWM_GETINITDATA:
+ i_ReturnValue = i_APCI1710_GetPWMInitialisation(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */
+ (unsigned char) data[0], /* b_PWM */
+ (unsigned char *) &data[0], /* pb_TimingUnit */
+ (unsigned int *) &data[1], /* pul_LowTiming */
+ (unsigned int *) &data[2], /* pul_HighTiming */
+ (unsigned char *) &data[3], /* pb_StartLevel */
+ (unsigned char *) &data[4], /* pb_StopMode */
+ (unsigned char *) &data[5], /* pb_StopLevel */
+ (unsigned char *) &data[6], /* pb_ExternGate */
+ (unsigned char *) &data[7], /* pb_InterruptEnable */
+ (unsigned char *) &data[8] /* pb_Enable */
+ );
break;
default:
- printk("Write Config Parameter Wrong\n");
+ printk(" Config Parameter Wrong\n");
}
if (i_ReturnValue >= 0)
@@ -1805,14 +1748,16 @@ int i_APCI1710_InsnWritePWM(struct comedi_device *dev, struct comedi_subdevice *
| See function "i_APCI1710_SetBoardIntRoutineX" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_EnablePWM(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_PWM,
- unsigned char b_StartLevel,
- unsigned char b_StopMode,
- unsigned char b_StopLevel, unsigned char b_ExternGate, unsigned char b_InterruptEnable)
+static int i_APCI1710_EnablePWM(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_PWM,
+ unsigned char b_StartLevel,
+ unsigned char b_StopMode,
+ unsigned char b_StopLevel,
+ unsigned char b_ExternGate,
+ unsigned char b_InterruptEnable)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_Status;
unsigned int dw_Command;
@@ -2061,9 +2006,11 @@ int i_APCI1710_EnablePWM(struct comedi_device *dev,
| "i_APCI1710_EnablePWM" |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_DisablePWM(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_PWM)
+static int i_APCI1710_DisablePWM(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_PWM)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_Status;
@@ -2188,11 +2135,14 @@ int i_APCI1710_DisablePWM(struct comedi_device *dev, unsigned char b_ModulNbr, u
| -8: High base timing selection is wrong |
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_PWM, unsigned char b_TimingUnit, unsigned int ul_LowTiming, unsigned int ul_HighTiming)
+static int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev,
+ unsigned char b_ModulNbr,
+ unsigned char b_PWM,
+ unsigned char b_TimingUnit,
+ unsigned int ul_LowTiming,
+ unsigned int ul_HighTiming)
{
+ struct addi_private *devpriv = dev->private;
unsigned char b_ClockSelection;
int i_ReturnValue = 0;
unsigned int ul_LowTimerValue = 0;
@@ -3415,6 +3365,49 @@ int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev,
}
/*
+ * Pwm Enable Disable and Set New Timing
+ */
+static int i_APCI1710_InsnWritePWM(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ unsigned char b_WriteType;
+ int i_ReturnValue = 0;
+ b_WriteType = CR_CHAN(insn->chanspec);
+
+ switch (b_WriteType) {
+ case APCI1710_PWM_ENABLE:
+ i_ReturnValue = i_APCI1710_EnablePWM(dev,
+ (unsigned char) CR_AREF(insn->chanspec),
+ (unsigned char) data[0],
+ (unsigned char) data[1],
+ (unsigned char) data[2],
+ (unsigned char) data[3], (unsigned char) data[4], (unsigned char) data[5]);
+ break;
+
+ case APCI1710_PWM_DISABLE:
+ i_ReturnValue = i_APCI1710_DisablePWM(dev,
+ (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]);
+ break;
+
+ case APCI1710_PWM_NEWTIMING:
+ i_ReturnValue = i_APCI1710_SetNewPWMTiming(dev,
+ (unsigned char) CR_AREF(insn->chanspec),
+ (unsigned char) data[0],
+ (unsigned char) data[1], (unsigned int) data[2], (unsigned int) data[3]);
+ break;
+
+ default:
+ printk("Write Config Parameter Wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return i_ReturnValue;
+}
+
+/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_GetPWMStatus |
| (unsigned char_ b_BoardHandle, |
@@ -3459,13 +3452,14 @@ int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev,
| -6: PWM not enabled see function "i_APCI1710_EnablePWM"|
+----------------------------------------------------------------------------+
*/
-
-int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_Status;
-
unsigned char b_ModulNbr;
unsigned char b_PWM;
unsigned char *pb_PWMOutputStatus;
@@ -3561,9 +3555,13 @@ int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_sub
return i_ReturnValue;
}
-int i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
+
data[0] = devpriv->s_InterruptParameters.
s_FIFOInterruptParameters[devpriv->
s_InterruptParameters.ui_Read].b_OldModuleMask;
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h
deleted file mode 100644
index d8ad0b9cf50..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-#define APCI1710_30MHZ 30
-#define APCI1710_33MHZ 33
-#define APCI1710_40MHZ 40
-
-#define APCI1710_PWM_INIT 0
-#define APCI1710_PWM_GETINITDATA 1
-
-#define APCI1710_PWM_DISABLE 0
-#define APCI1710_PWM_ENABLE 1
-#define APCI1710_PWM_NEWTIMING 2
-
-int i_APCI1710_InsnConfigPWM(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1710_InitPWM(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_PWM,
- unsigned char b_ClockSelection,
- unsigned char b_TimingUnit,
- unsigned int ul_LowTiming,
- unsigned int ul_HighTiming,
- unsigned int *pul_RealLowTiming, unsigned int *pul_RealHighTiming);
-
-int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_PWM,
- unsigned char *pb_TimingUnit,
- unsigned int *pul_LowTiming,
- unsigned int *pul_HighTiming,
- unsigned char *pb_StartLevel,
- unsigned char *pb_StopMode,
- unsigned char *pb_StopLevel,
- unsigned char *pb_ExternGate,
- unsigned char *pb_InterruptEnable, unsigned char *pb_Enable);
-
-int i_APCI1710_InsnWritePWM(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1710_EnablePWM(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_PWM,
- unsigned char b_StartLevel,
- unsigned char b_StopMode,
- unsigned char b_StopLevel, unsigned char b_ExternGate,
- unsigned char b_InterruptEnable);
-
-int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev,
- unsigned char b_ModulNbr,
- unsigned char b_PWM, unsigned char b_TimingUnit,
- unsigned int ul_LowTiming, unsigned int ul_HighTiming);
-
-int i_APCI1710_DisablePWM(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_PWM);
-
-int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
index c13b0027492..1e05732e9f3 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
@@ -40,13 +40,20 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-----------------------------------------------------------------------+
*/
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
-#include "APCI1710_Ssi.h"
+#define APCI1710_BINARY_MODE 0x1
+#define APCI1710_GRAY_MODE 0x0
+
+#define APCI1710_SSI_READ1VALUE 1
+#define APCI1710_SSI_READALLVALUE 2
+
+#define APCI1710_SSI_SET_CHANNELON 0
+#define APCI1710_SSI_SET_CHANNELOFF 1
+#define APCI1710_SSI_READ_1CHANNEL 2
+#define APCI1710_SSI_READ_ALLCHANNEL 3
/*
+----------------------------------------------------------------------------+
@@ -119,9 +126,12 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+----------------------------------------------------------------------------+
*/
-int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int ui_TimerValue;
unsigned char b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength,
@@ -386,9 +396,12 @@ pul_Position = (unsigned int *) &data[0];
+----------------------------------------------------------------------------+
*/
-int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned char b_Cpt;
unsigned char b_Length;
@@ -719,9 +732,12 @@ int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevi
+----------------------------------------------------------------------------+
*/
-int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg;
unsigned char b_ModulNbr;
@@ -729,6 +745,7 @@ int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_sub
unsigned char *pb_ChannelStatus;
unsigned char *pb_InputStatus;
unsigned char b_IOType;
+
i_ReturnValue = insn->n;
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_IOType = (unsigned char) data[0];
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h
deleted file mode 100644
index ef4d88789d5..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-#define APCI1710_30MHZ 30
-#define APCI1710_33MHZ 33
-#define APCI1710_40MHZ 40
-
-#define APCI1710_BINARY_MODE 0x1
-#define APCI1710_GRAY_MODE 0x0
-
-#define APCI1710_SSI_READ1VALUE 1
-#define APCI1710_SSI_READALLVALUE 2
-
-#define APCI1710_SSI_SET_CHANNELON 0
-#define APCI1710_SSI_SET_CHANNELOFF 1
-#define APCI1710_SSI_READ_1CHANNEL 2
-#define APCI1710_SSI_READ_ALLCHANNEL 3
-
-/*
- * SSI INISIALISATION FUNCTION
- */
-int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
index 0e6affd9596..3bc9826ce40 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
@@ -52,13 +52,22 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-----------------------------------------------------------------------+
*/
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
-#include "APCI1710_Tor.h"
+#define APCI1710_GATE_INPUT 10
+
+#define APCI1710_TOR_SIMPLE_MODE 2
+#define APCI1710_TOR_DOUBLE_MODE 3
+#define APCI1710_TOR_QUADRUPLE_MODE 4
+
+#define APCI1710_SINGLE 0
+#define APCI1710_CONTINUOUS 1
+
+#define APCI1710_TOR_GETPROGRESSSTATUS 0
+#define APCI1710_TOR_GETCOUNTERVALUE 1
+#define APCI1710_TOR_READINTERRUPT 2
/*
+----------------------------------------------------------------------------+
@@ -130,9 +139,12 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+----------------------------------------------------------------------------+
*/
-int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int ul_TimerValue = 0;
unsigned int dw_Command;
@@ -987,9 +999,12 @@ int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev,
+----------------------------------------------------------------------------+
*/
-int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_Status;
unsigned int dw_DummyRead;
@@ -1460,9 +1475,12 @@ int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev,
+----------------------------------------------------------------------------+
*/
-int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_Status;
unsigned char b_ModulNbr;
@@ -1700,13 +1718,15 @@ int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev,
+----------------------------------------------------------------------------+
*/
-int i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_Status;
unsigned int dw_TimeOut = 0;
-
unsigned char b_ModulNbr;
unsigned char b_TorCounter;
unsigned char b_ReadType;
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h
deleted file mode 100644
index 537d4755132..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-#define APCI1710_30MHZ 30
-#define APCI1710_33MHZ 33
-#define APCI1710_40MHZ 40
-
-#define APCI1710_GATE_INPUT 10
-
-#define APCI1710_TOR_SIMPLE_MODE 2
-#define APCI1710_TOR_DOUBLE_MODE 3
-#define APCI1710_TOR_QUADRUPLE_MODE 4
-
-#define APCI1710_SINGLE 0
-#define APCI1710_CONTINUOUS 1
-
-#define APCI1710_TOR_GETPROGRESSSTATUS 0
-#define APCI1710_TOR_GETCOUNTERVALUE 1
-#define APCI1710_TOR_READINTERRUPT 2
-
-/*
- * TOR_COUNTER INISIALISATION FUNCTION
- */
-int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-
-int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-/*
- * TOR_COUNTER READ FUNCTION
- */
-int i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
index 9e177f4af86..c8238b8921c 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
@@ -52,13 +52,11 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-----------------------------------------------------------------------+
*/
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
+#define APCI1710_TTL_INIT 0
+#define APCI1710_TTL_INITDIRECTION 1
-#include "APCI1710_Ttl.h"
+#define APCI1710_TTL_READCHANNEL 0
+#define APCI1710_TTL_READPORT 1
/*
+----------------------------------------------------------------------------+
@@ -100,9 +98,12 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+----------------------------------------------------------------------------+
*/
-int i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned char b_ModulNbr;
unsigned char b_InitType;
@@ -406,9 +407,12 @@ APCI1710_TTL_READCHANNEL
+----------------------------------------------------------------------------+
*/
-int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg;
unsigned char b_ModulNbr;
@@ -655,9 +659,12 @@ int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdev
+----------------------------------------------------------------------------+
*/
-int i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg;
unsigned char b_ModulNbr;
@@ -825,9 +832,12 @@ int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,struct comedi
+----------------------------------------------------------------------------+
*/
-int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg = 0;
unsigned char b_ModulNbr;
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h
deleted file mode 100644
index adcab824b25..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-#define APCI1710_TTL_INIT 0
-#define APCI1710_TTL_INITDIRECTION 1
-
-#define APCI1710_TTL_READCHANNEL 0
-#define APCI1710_TTL_READPORT 1
-
-/*
- * TTL INISIALISATION FUNCTION
- */
-int i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/*
- * TTL INPUT FUNCTION
- */
-int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/*
- * TTL OUTPUT FUNCTIONS
- */
-int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h
deleted file mode 100644
index 95f7dc61cd0..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-/* Header file for AMCC s 5933 */
-
-#ifndef _AMCC_S5933_H_
-#define _AMCC_S5933_H_
-
-#include "../../comedidev.h"
-
-/* written on base0 */
-#define FIFO_ADVANCE_ON_BYTE_2 0x20000000
-
-/* added for step 6 dma written on base2 */
-#define AMWEN_ENABLE 0x02
-
-#define A2P_FIFO_WRITE_ENABLE 0x01
-
-/* for transfer count enable bit */
-#define AGCSTS_TC_ENABLE 0x10000000
-
-/*
- * ADDON RELATED ADDITIONS
- */
-/* Constant */
-#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00
-#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200
-#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L
-#define APCI3120_AMWEN_ENABLE 0x02
-#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01
-#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L
-#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L
-#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L
-#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
-#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0
-#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0
-
-/* ADD_ON ::: this needed since apci supports 16 bit interface to add on */
-#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C
-#define APCI3120_ADD_ON_AGCSTS_HIGH (APCI3120_ADD_ON_AGCSTS_LOW + 2)
-#define APCI3120_ADD_ON_MWAR_LOW 0x24
-#define APCI3120_ADD_ON_MWAR_HIGH (APCI3120_ADD_ON_MWAR_LOW + 2)
-#define APCI3120_ADD_ON_MWTC_LOW 0x058
-#define APCI3120_ADD_ON_MWTC_HIGH (APCI3120_ADD_ON_MWTC_LOW + 2)
-
-/* AMCC */
-#define APCI3120_AMCC_OP_MCSR 0x3C
-#define APCI3120_AMCC_OP_REG_INTCSR 0x38
-
-/*
- * AMCC Operation Register Offsets - PCI
- */
-#define AMCC_OP_REG_OMB1 0x00
-#define AMCC_OP_REG_OMB2 0x04
-#define AMCC_OP_REG_OMB3 0x08
-#define AMCC_OP_REG_OMB4 0x0c
-#define AMCC_OP_REG_IMB1 0x10
-#define AMCC_OP_REG_IMB2 0x14
-#define AMCC_OP_REG_IMB3 0x18
-#define AMCC_OP_REG_IMB4 0x1c
-#define AMCC_OP_REG_FIFO 0x20
-#define AMCC_OP_REG_MWAR 0x24
-#define AMCC_OP_REG_MWTC 0x28
-#define AMCC_OP_REG_MRAR 0x2c
-#define AMCC_OP_REG_MRTC 0x30
-#define AMCC_OP_REG_MBEF 0x34
-#define AMCC_OP_REG_INTCSR 0x38
-/* int source */
-#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2)
-/* FIFO ctrl */
-#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3)
-#define AMCC_OP_REG_MCSR 0x3c
-/* Data in byte 2 */
-#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2)
-/* Command in byte 3 */
-#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3)
-
-#define AMCC_FIFO_DEPTH_DWORD 8
-#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof(u32))
-
-/*
- * AMCC Operation Registers Size - PCI
- */
-#define AMCC_OP_REG_SIZE 64 /* in bytes */
-
-/*
- * AMCC Operation Register Offsets - Add-on
- */
-#define AMCC_OP_REG_AIMB1 0x00
-#define AMCC_OP_REG_AIMB2 0x04
-#define AMCC_OP_REG_AIMB3 0x08
-#define AMCC_OP_REG_AIMB4 0x0c
-#define AMCC_OP_REG_AOMB1 0x10
-#define AMCC_OP_REG_AOMB2 0x14
-#define AMCC_OP_REG_AOMB3 0x18
-#define AMCC_OP_REG_AOMB4 0x1c
-#define AMCC_OP_REG_AFIFO 0x20
-#define AMCC_OP_REG_AMWAR 0x24
-#define AMCC_OP_REG_APTA 0x28
-#define AMCC_OP_REG_APTD 0x2c
-#define AMCC_OP_REG_AMRAR 0x30
-#define AMCC_OP_REG_AMBEF 0x34
-#define AMCC_OP_REG_AINT 0x38
-#define AMCC_OP_REG_AGCSTS 0x3c
-#define AMCC_OP_REG_AMWTC 0x58
-#define AMCC_OP_REG_AMRTC 0x5c
-
-/*
- * AMCC - Add-on General Control/Status Register
- */
-#define AGCSTS_CONTROL_MASK 0xfffff000
-#define AGCSTS_NV_ACC_MASK 0xe0000000
-#define AGCSTS_RESET_MASK 0x0e000000
-#define AGCSTS_NV_DA_MASK 0x00ff0000
-#define AGCSTS_BIST_MASK 0x0000f000
-#define AGCSTS_STATUS_MASK 0x000000ff
-#define AGCSTS_TCZERO_MASK 0x000000c0
-#define AGCSTS_FIFO_ST_MASK 0x0000003f
-
-#define AGCSTS_RESET_MBFLAGS 0x08000000
-#define AGCSTS_RESET_P2A_FIFO 0x04000000
-#define AGCSTS_RESET_A2P_FIFO 0x02000000
-#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
-
-#define AGCSTS_A2P_TCOUNT 0x00000080
-#define AGCSTS_P2A_TCOUNT 0x00000040
-
-#define AGCSTS_FS_P2A_EMPTY 0x00000020
-#define AGCSTS_FS_P2A_HALF 0x00000010
-#define AGCSTS_FS_P2A_FULL 0x00000008
-
-#define AGCSTS_FS_A2P_EMPTY 0x00000004
-#define AGCSTS_FS_A2P_HALF 0x00000002
-#define AGCSTS_FS_A2P_FULL 0x00000001
-
-/*
- * AMCC - Add-on Interrupt Control/Status Register
- */
-#define AINT_INT_MASK 0x00ff0000
-#define AINT_SEL_MASK 0x0000ffff
-#define AINT_IS_ENSEL_MASK 0x00001f1f
-
-#define AINT_INT_ASSERTED 0x00800000
-#define AINT_BM_ERROR 0x00200000
-#define AINT_BIST_INT 0x00100000
-
-#define AINT_RT_COMPLETE 0x00080000
-#define AINT_WT_COMPLETE 0x00040000
-
-#define AINT_OUT_MB_INT 0x00020000
-#define AINT_IN_MB_INT 0x00010000
-
-#define AINT_READ_COMPL 0x00008000
-#define AINT_WRITE_COMPL 0x00004000
-
-#define AINT_OMB_ENABLE 0x00001000
-#define AINT_OMB_SELECT 0x00000c00
-#define AINT_OMB_BYTE 0x00000300
-
-#define AINT_IMB_ENABLE 0x00000010
-#define AINT_IMB_SELECT 0x0000000c
-#define AINT_IMB_BYTE 0x00000003
-
-/* Enable Bus Mastering */
-#define EN_A2P_TRANSFERS 0x00000400
-/* FIFO Flag Reset */
-#define RESET_A2P_FLAGS 0x04000000L
-/* FIFO Relative Priority */
-#define A2P_HI_PRIORITY 0x00000100L
-/* Identify Interrupt Sources */
-#define ANY_S593X_INT 0x00800000L
-#define READ_TC_INT 0x00080000L
-#define WRITE_TC_INT 0x00040000L
-#define IN_MB_INT 0x00020000L
-#define MASTER_ABORT_INT 0x00100000L
-#define TARGET_ABORT_INT 0x00200000L
-#define BUS_MASTER_INT 0x00200000L
-
-/****************************************************************************/
-
-struct pcilst_struct {
- struct pcilst_struct *next;
- int used;
- struct pci_dev *pcidev;
- unsigned short vendor;
- unsigned short device;
- unsigned char pci_bus;
- unsigned char pci_slot;
- unsigned char pci_func;
- resource_size_t io_addr[5];
- unsigned int irq;
-};
-
-/* ptr to root list of all amcc devices */
-static struct pcilst_struct *amcc_devices;
-
-static const int i_ADDIDATADeviceID[] = { 0x15B8, 0x10E8 };
-
-/****************************************************************************/
-
-void v_pci_card_list_init(unsigned short pci_vendor, char display);
-void v_pci_card_list_cleanup(unsigned short pci_vendor);
-struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
- unsigned short
- device_id);
-int i_find_free_pci_card_by_position(unsigned short vendor_id,
- unsigned short device_id,
- unsigned short pci_bus,
- unsigned short pci_slot,
- struct pcilst_struct **card);
-struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
- unsigned short device_id,
- unsigned short pci_bus,
- unsigned short pci_slot,
- int i_Master);
-
-int pci_card_alloc(struct pcilst_struct *amcc, int master);
-int i_pci_card_free(struct pcilst_struct *amcc);
-void v_pci_card_list_display(void);
-int i_pci_card_data(struct pcilst_struct *amcc,
- unsigned char *pci_bus, unsigned char *pci_slot,
- unsigned char *pci_func, resource_size_t * io_addr,
- unsigned int *irq);
-
-/****************************************************************************/
-
-/* build list of amcc cards in this system */
-void v_pci_card_list_init(unsigned short pci_vendor, char display)
-{
- struct pci_dev *pcidev = NULL;
- struct pcilst_struct *amcc, *last;
- int i;
- int i_Count = 0;
- amcc_devices = NULL;
- last = NULL;
-
- for_each_pci_dev(pcidev) {
- for (i_Count = 0; i_Count < 2; i_Count++) {
- pci_vendor = i_ADDIDATADeviceID[i_Count];
- if (pcidev->vendor == pci_vendor) {
- amcc = kzalloc(sizeof(*amcc), GFP_KERNEL);
- if (amcc == NULL)
- continue;
-
- amcc->pcidev = pcidev;
- if (last)
- last->next = amcc;
- else
- amcc_devices = amcc;
- last = amcc;
-
- amcc->vendor = pcidev->vendor;
- amcc->device = pcidev->device;
- amcc->pci_bus = pcidev->bus->number;
- amcc->pci_slot = PCI_SLOT(pcidev->devfn);
- amcc->pci_func = PCI_FUNC(pcidev->devfn);
- /* Note: resources may be invalid if PCI device
- * not enabled, but they are corrected in
- * pci_card_alloc. */
- for (i = 0; i < 5; i++)
- amcc->io_addr[i] =
- pci_resource_start(pcidev, i);
- amcc->irq = pcidev->irq;
-
- }
- }
- }
-
- if (display)
- v_pci_card_list_display();
-}
-
-/****************************************************************************/
-/* free up list of amcc cards in this system */
-void v_pci_card_list_cleanup(unsigned short pci_vendor)
-{
- struct pcilst_struct *amcc, *next;
-
- for (amcc = amcc_devices; amcc; amcc = next) {
- next = amcc->next;
- kfree(amcc);
- }
-
- amcc_devices = NULL;
-}
-
-/****************************************************************************/
-/* find first unused card with this device_id */
-struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
- unsigned short device_id)
-{
- struct pcilst_struct *amcc, *next;
-
- for (amcc = amcc_devices; amcc; amcc = next) {
- next = amcc->next;
- if ((!amcc->used) && (amcc->device == device_id)
- && (amcc->vendor == vendor_id))
- return amcc;
-
- }
-
- return NULL;
-}
-
-/****************************************************************************/
-/* find card on requested position */
-int i_find_free_pci_card_by_position(unsigned short vendor_id,
- unsigned short device_id,
- unsigned short pci_bus,
- unsigned short pci_slot,
- struct pcilst_struct **card)
-{
- struct pcilst_struct *amcc, *next;
-
- *card = NULL;
- for (amcc = amcc_devices; amcc; amcc = next) {
- next = amcc->next;
- if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
- && (amcc->pci_bus == pci_bus)
- && (amcc->pci_slot == pci_slot)) {
- if (!(amcc->used)) {
- *card = amcc;
- return 0; /* ok, card is found */
- } else {
- printk(" - \nCard on requested position is used b:s %d:%d!\n",
- pci_bus, pci_slot);
- return 2; /* card exist but is used */
- }
- }
- }
-
- /* no card found */
- return 1;
-}
-
-/****************************************************************************/
-/* mark card as used */
-int pci_card_alloc(struct pcilst_struct *amcc, int master)
-{
- int i;
-
- if (!amcc)
- return -1;
-
- if (amcc->used)
- return 1;
- if (comedi_pci_enable(amcc->pcidev, "addi_amcc_s5933"))
- return -1;
- /* Resources will be accurate now. */
- for (i = 0; i < 5; i++)
- amcc->io_addr[i] = pci_resource_start(amcc->pcidev, i);
- if (master)
- pci_set_master(amcc->pcidev);
- amcc->used = 1;
-
- return 0;
-}
-
-/****************************************************************************/
-/* mark card as free */
-int i_pci_card_free(struct pcilst_struct *amcc)
-{
- if (!amcc)
- return -1;
-
- if (!amcc->used)
- return 1;
- amcc->used = 0;
- comedi_pci_disable(amcc->pcidev);
- return 0;
-}
-
-/****************************************************************************/
-/* display list of found cards */
-void v_pci_card_list_display(void)
-{
- struct pcilst_struct *amcc, *next;
-
- printk(KERN_DEBUG "List of pci cards\n");
- printk(KERN_DEBUG "bus:slot:func vendor device io_amcc io_daq irq used\n");
-
- for (amcc = amcc_devices; amcc; amcc = next) {
- next = amcc->next;
- printk
- ("%2d %2d %2d 0x%4x 0x%4x 0x%8llx 0x%8llx %2u %2d\n",
- amcc->pci_bus, amcc->pci_slot, amcc->pci_func,
- amcc->vendor, amcc->device,
- (unsigned long long)amcc->io_addr[0],
- (unsigned long long)amcc->io_addr[2], amcc->irq,
- amcc->used);
-
- }
-}
-
-/****************************************************************************/
-/* return all card information for driver */
-int i_pci_card_data(struct pcilst_struct *amcc,
- unsigned char *pci_bus, unsigned char *pci_slot,
- unsigned char *pci_func, resource_size_t * io_addr,
- unsigned int *irq)
-{
- int i;
-
- if (!amcc)
- return -1;
- *pci_bus = amcc->pci_bus;
- *pci_slot = amcc->pci_slot;
- *pci_func = amcc->pci_func;
- for (i = 0; i < 5; i++)
- io_addr[i] = amcc->io_addr[i];
- *irq = amcc->irq;
- return 0;
-}
-
-/****************************************************************************/
-/* select and alloc card */
-struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
- unsigned short device_id,
- unsigned short pci_bus,
- unsigned short pci_slot,
- int i_Master)
-{
- struct pcilst_struct *card;
-
- if ((pci_bus < 1) & (pci_slot < 1)) {
- /* use autodetection */
- card = ptr_find_free_pci_card_by_device(vendor_id, device_id);
- if (card == NULL) {
- printk(" - Unused card not found in system!\n");
- return NULL;
- }
- } else {
- switch (i_find_free_pci_card_by_position(vendor_id, device_id,
- pci_bus, pci_slot,
- &card)) {
- case 1:
- printk(" - Card not found on requested position b:s %d:%d!\n",
- pci_bus, pci_slot);
- return NULL;
- case 2:
- printk(" - Card on requested position is used b:s %d:%d!\n",
- pci_bus, pci_slot);
- return NULL;
- }
- }
-
- if (pci_card_alloc(card, i_Master) != 0) {
- printk(" - Can't allocate card!\n");
- return NULL;
-
- }
-
- return card;
-}
-#endif
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c
index 99a96bd9671..90cc43263ae 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c
@@ -36,1518 +36,107 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-----------------------------------------------------------------------+
| Description : ADDI COMMON Main Module |
+-----------------------------------------------------------------------+
- | CONFIG OPTIONS |
- | option[0] - PCI bus number - if bus number and slot number are 0, |
- | then driver search for first unused card |
- | option[1] - PCI slot number |
- | |
- | option[2] = 0 - DMA ENABLE |
- | = 1 - DMA DISABLE |
- +----------+-----------+------------------------------------------------+
*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/timer.h>
-#include <linux/pci.h>
-#include <linux/gfp.h>
-#include <linux/io.h>
-#include "../../comedidev.h"
-#if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300)
-#include <asm/i387.h>
-#endif
-#include "../comedi_fc.h"
-
-#include "addi_common.h"
-#include "addi_amcc_s5933.h"
-
-#ifndef ADDIDATA_DRIVER_NAME
-#define ADDIDATA_DRIVER_NAME "addi_common"
-#endif
-
-/* Update-0.7.57->0.7.68MODULE_AUTHOR("ADDI-DATA GmbH <info@addi-data.com>"); */
-/* Update-0.7.57->0.7.68MODULE_DESCRIPTION("Comedi ADDI-DATA module"); */
-/* Update-0.7.57->0.7.68MODULE_LICENSE("GPL"); */
-
-#define devpriv ((struct addi_private *)dev->private)
-#define this_board ((const struct addi_board *)dev->board_ptr)
-
-#if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300)
-/* BYTE b_SaveFPUReg [94]; */
-
-void fpu_begin(void)
-{
- /* asm ("fstenv b_SaveFPUReg"); */
- kernel_fpu_begin();
-}
-
-void fpu_end(void)
-{
- /* asm ("frstor b_SaveFPUReg"); */
- kernel_fpu_end();
-}
-#endif
-
-#include "addi_eeprom.c"
-#if (defined (CONFIG_APCI_3120) || defined (CONFIG_APCI_3001))
-#include "hwdrv_apci3120.c"
-#endif
-#ifdef CONFIG_APCI_1032
-#include "hwdrv_apci1032.c"
-#endif
-#ifdef CONFIG_APCI_1516
-#include "hwdrv_apci1516.c"
-#endif
-#ifdef CONFIG_APCI_2016
-#include "hwdrv_apci2016.c"
-#endif
-#ifdef CONFIG_APCI_2032
-#include "hwdrv_apci2032.c"
-#endif
-#ifdef CONFIG_APCI_2200
-#include "hwdrv_apci2200.c"
-#endif
-#ifdef CONFIG_APCI_1564
-#include "hwdrv_apci1564.c"
-#endif
-#ifdef CONFIG_APCI_1500
-#include "hwdrv_apci1500.c"
-#endif
-#ifdef CONFIG_APCI_3501
-#include "hwdrv_apci3501.c"
-#endif
-#ifdef CONFIG_APCI_035
-#include "hwdrv_apci035.c"
-#endif
-#if (defined (CONFIG_APCI_3200) || defined (CONFIG_APCI_3300))
-#include "hwdrv_apci3200.c"
-#endif
-#ifdef CONFIG_APCI_1710
-#include "hwdrv_APCI1710.c"
-#endif
-#ifdef CONFIG_APCI_16XX
-#include "hwdrv_apci16xx.c"
-#endif
-#ifdef CONFIG_APCI_3XXX
-#include "hwdrv_apci3xxx.c"
-#endif
-
#ifndef COMEDI_SUBD_TTLIO
#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
#endif
-static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = {
-#ifdef CONFIG_APCI_3120
- {PCI_DEVICE(APCI3120_BOARD_VENDOR_ID, 0x818D)},
-#endif
-#ifdef CONFIG_APCI_1032
- {PCI_DEVICE(APCI1032_BOARD_VENDOR_ID, 0x1003)},
-#endif
-#ifdef CONFIG_APCI_1516
- {PCI_DEVICE(APCI1516_BOARD_VENDOR_ID, 0x1001)},
-#endif
-#ifdef CONFIG_APCI_2016
- {PCI_DEVICE(APCI2016_BOARD_VENDOR_ID, 0x1002)},
-#endif
-#ifdef CONFIG_APCI_2032
- {PCI_DEVICE(APCI2032_BOARD_VENDOR_ID, 0x1004)},
-#endif
-#ifdef CONFIG_APCI_2200
- {PCI_DEVICE(APCI2200_BOARD_VENDOR_ID, 0x1005)},
-#endif
-#ifdef CONFIG_APCI_1564
- {PCI_DEVICE(APCI1564_BOARD_VENDOR_ID, 0x1006)},
-#endif
-#ifdef CONFIG_APCI_1500
- {PCI_DEVICE(APCI1500_BOARD_VENDOR_ID, 0x80fc)},
-#endif
-#ifdef CONFIG_APCI_3001
- {PCI_DEVICE(APCI3120_BOARD_VENDOR_ID, 0x828D)},
-#endif
-#ifdef CONFIG_APCI_3501
- {PCI_DEVICE(APCI3501_BOARD_VENDOR_ID, 0x3001)},
-#endif
-#ifdef CONFIG_APCI_035
- {PCI_DEVICE(APCI035_BOARD_VENDOR_ID, 0x0300)},
-#endif
-#ifdef CONFIG_APCI_3200
- {PCI_DEVICE(APCI3200_BOARD_VENDOR_ID, 0x3000)},
-#endif
-#ifdef CONFIG_APCI_3300
- {PCI_DEVICE(APCI3200_BOARD_VENDOR_ID, 0x3007)},
-#endif
-#ifdef CONFIG_APCI_1710
- {PCI_DEVICE(APCI1710_BOARD_VENDOR_ID, APCI1710_BOARD_DEVICE_ID)},
-#endif
-#ifdef CONFIG_APCI_16XX
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1009)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x100A)},
-#endif
-#ifdef CONFIG_APCI_3XXX
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3010)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300F)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300E)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3013)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3014)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3015)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3016)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3017)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3018)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3019)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301A)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301B)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301C)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301D)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301E)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301F)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3020)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3021)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3022)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3023)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300B)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3002)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3003)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3004)},
- {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3024)},
-#endif
- {0}
-};
-
-MODULE_DEVICE_TABLE(pci, addi_apci_tbl);
-
-static const struct addi_board boardtypes[] = {
-#ifdef CONFIG_APCI_3120
- {
- .pc_DriverName = "apci3120",
- .i_VendorId = APCI3120_BOARD_VENDOR_ID,
- .i_DeviceId = 0x818D,
- .i_IorangeBase0 = AMCC_OP_REG_SIZE,
- .i_IorangeBase1 = APCI3120_ADDRESS_RANGE,
- .i_IorangeBase2 = 8,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .i_NbrAiChannel = 16,
- .i_NbrAiChannelDiff = 8,
- .i_AiChannelList = 16,
- .i_NbrAoChannel = 8,
- .i_AiMaxdata = 0xffff,
- .i_AoMaxdata = 0x3fff,
- .pr_AiRangelist = &range_apci3120_ai,
- .pr_AoRangelist = &range_apci3120_ao,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 0x0f,
- .i_Dma = 1,
- .i_Timer = 1,
- .b_AvailableConvertUnit = 1,
- .ui_MinAcquisitiontimeNs = 10000,
- .ui_MinDelaytimeNs = 100000,
- .interrupt = v_APCI3120_Interrupt,
- .reset = i_APCI3120_Reset,
- .ai_config = i_APCI3120_InsnConfigAnalogInput,
- .ai_read = i_APCI3120_InsnReadAnalogInput,
- .ai_cmdtest = i_APCI3120_CommandTestAnalogInput,
- .ai_cmd = i_APCI3120_CommandAnalogInput,
- .ai_cancel = i_APCI3120_StopCyclicAcquisition,
- .ao_write = i_APCI3120_InsnWriteAnalogOutput,
- .di_read = i_APCI3120_InsnReadDigitalInput,
- .di_bits = i_APCI3120_InsnBitsDigitalInput,
- .do_config = i_APCI3120_InsnConfigDigitalOutput,
- .do_write = i_APCI3120_InsnWriteDigitalOutput,
- .do_bits = i_APCI3120_InsnBitsDigitalOutput,
- .timer_config = i_APCI3120_InsnConfigTimer,
- .timer_write = i_APCI3120_InsnWriteTimer,
- .timer_read = i_APCI3120_InsnReadTimer,
- },
-#endif
-#ifdef CONFIG_APCI_1032
- {
- .pc_DriverName = "apci1032",
- .i_VendorId = APCI1032_BOARD_VENDOR_ID,
- .i_DeviceId = 0x1003,
- .i_IorangeBase0 = 4,
- .i_IorangeBase1 = APCI1032_ADDRESS_RANGE,
- .i_PCIEeprom = ADDIDATA_EEPROM,
- .pc_EepromChip = ADDIDATA_93C76,
- .i_NbrDiChannel = 32,
- .interrupt = v_APCI1032_Interrupt,
- .reset = i_APCI1032_Reset,
- .di_config = i_APCI1032_ConfigDigitalInput,
- .di_read = i_APCI1032_Read1DigitalInput,
- .di_bits = i_APCI1032_ReadMoreDigitalInput,
- },
-#endif
-#ifdef CONFIG_APCI_1516
- {
- .pc_DriverName = "apci1516",
- .i_VendorId = APCI1516_BOARD_VENDOR_ID,
- .i_DeviceId = 0x1001,
- .i_IorangeBase0 = 128,
- .i_IorangeBase1 = APCI1516_ADDRESS_RANGE,
- .i_IorangeBase2 = 32,
- .i_PCIEeprom = ADDIDATA_EEPROM,
- .pc_EepromChip = ADDIDATA_S5920,
- .i_NbrDiChannel = 8,
- .i_NbrDoChannel = 8,
- .i_Timer = 1,
- .reset = i_APCI1516_Reset,
- .di_read = i_APCI1516_Read1DigitalInput,
- .di_bits = i_APCI1516_ReadMoreDigitalInput,
- .do_config = i_APCI1516_ConfigDigitalOutput,
- .do_write = i_APCI1516_WriteDigitalOutput,
- .do_bits = i_APCI1516_ReadDigitalOutput,
- .timer_config = i_APCI1516_ConfigWatchdog,
- .timer_write = i_APCI1516_StartStopWriteWatchdog,
- .timer_read = i_APCI1516_ReadWatchdog,
- },
-#endif
-#ifdef CONFIG_APCI_2016
- {
- .pc_DriverName = "apci2016",
- .i_VendorId = APCI2016_BOARD_VENDOR_ID,
- .i_DeviceId = 0x1002,
- .i_IorangeBase0 = 128,
- .i_IorangeBase1 = APCI2016_ADDRESS_RANGE,
- .i_IorangeBase2 = 32,
- .i_PCIEeprom = ADDIDATA_EEPROM,
- .pc_EepromChip = ADDIDATA_S5920,
- .i_NbrDoChannel = 16,
- .i_Timer = 1,
- .reset = i_APCI2016_Reset,
- .do_config = i_APCI2016_ConfigDigitalOutput,
- .do_write = i_APCI2016_WriteDigitalOutput,
- .do_bits = i_APCI2016_BitsDigitalOutput,
- .timer_config = i_APCI2016_ConfigWatchdog,
- .timer_write = i_APCI2016_StartStopWriteWatchdog,
- .timer_read = i_APCI2016_ReadWatchdog,
- },
-#endif
-#ifdef CONFIG_APCI_2032
- {
- .pc_DriverName = "apci2032",
- .i_VendorId = APCI2032_BOARD_VENDOR_ID,
- .i_DeviceId = 0x1004,
- .i_IorangeBase0 = 4,
- .i_IorangeBase1 = APCI2032_ADDRESS_RANGE,
- .i_PCIEeprom = ADDIDATA_EEPROM,
- .pc_EepromChip = ADDIDATA_93C76,
- .i_NbrDoChannel = 32,
- .i_DoMaxdata = 0xffffffff,
- .i_Timer = 1,
- .interrupt = v_APCI2032_Interrupt,
- .reset = i_APCI2032_Reset,
- .do_config = i_APCI2032_ConfigDigitalOutput,
- .do_write = i_APCI2032_WriteDigitalOutput,
- .do_bits = i_APCI2032_ReadDigitalOutput,
- .do_read = i_APCI2032_ReadInterruptStatus,
- .timer_config = i_APCI2032_ConfigWatchdog,
- .timer_write = i_APCI2032_StartStopWriteWatchdog,
- .timer_read = i_APCI2032_ReadWatchdog,
- },
-#endif
-#ifdef CONFIG_APCI_2200
- {
- .pc_DriverName = "apci2200",
- .i_VendorId = APCI2200_BOARD_VENDOR_ID,
- .i_DeviceId = 0x1005,
- .i_IorangeBase0 = 4,
- .i_IorangeBase1 = APCI2200_ADDRESS_RANGE,
- .i_PCIEeprom = ADDIDATA_EEPROM,
- .pc_EepromChip = ADDIDATA_93C76,
- .i_NbrDiChannel = 8,
- .i_NbrDoChannel = 16,
- .i_Timer = 1,
- .reset = i_APCI2200_Reset,
- .di_read = i_APCI2200_Read1DigitalInput,
- .di_bits = i_APCI2200_ReadMoreDigitalInput,
- .do_config = i_APCI2200_ConfigDigitalOutput,
- .do_write = i_APCI2200_WriteDigitalOutput,
- .do_bits = i_APCI2200_ReadDigitalOutput,
- .timer_config = i_APCI2200_ConfigWatchdog,
- .timer_write = i_APCI2200_StartStopWriteWatchdog,
- .timer_read = i_APCI2200_ReadWatchdog,
- },
-#endif
-#ifdef CONFIG_APCI_1564
- {
- .pc_DriverName = "apci1564",
- .i_VendorId = APCI1564_BOARD_VENDOR_ID,
- .i_DeviceId = 0x1006,
- .i_IorangeBase0 = 128,
- .i_IorangeBase1 = APCI1564_ADDRESS_RANGE,
- .i_PCIEeprom = ADDIDATA_EEPROM,
- .pc_EepromChip = ADDIDATA_93C76,
- .i_NbrDiChannel = 32,
- .i_NbrDoChannel = 32,
- .i_DoMaxdata = 0xffffffff,
- .i_Timer = 1,
- .interrupt = v_APCI1564_Interrupt,
- .reset = i_APCI1564_Reset,
- .di_config = i_APCI1564_ConfigDigitalInput,
- .di_read = i_APCI1564_Read1DigitalInput,
- .di_bits = i_APCI1564_ReadMoreDigitalInput,
- .do_config = i_APCI1564_ConfigDigitalOutput,
- .do_write = i_APCI1564_WriteDigitalOutput,
- .do_bits = i_APCI1564_ReadDigitalOutput,
- .do_read = i_APCI1564_ReadInterruptStatus,
- .timer_config = i_APCI1564_ConfigTimerCounterWatchdog,
- .timer_write = i_APCI1564_StartStopWriteTimerCounterWatchdog,
- .timer_read = i_APCI1564_ReadTimerCounterWatchdog,
- },
-#endif
-#ifdef CONFIG_APCI_1500
- {
- .pc_DriverName = "apci1500",
- .i_VendorId = APCI1500_BOARD_VENDOR_ID,
- .i_DeviceId = 0x80fc,
- .i_IorangeBase0 = 128,
- .i_IorangeBase1 = APCI1500_ADDRESS_RANGE,
- .i_IorangeBase2 = 4,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .i_NbrDiChannel = 16,
- .i_NbrDoChannel = 16,
- .i_DoMaxdata = 0xffff,
- .i_Timer = 1,
- .interrupt = v_APCI1500_Interrupt,
- .reset = i_APCI1500_Reset,
- .di_config = i_APCI1500_ConfigDigitalInputEvent,
- .di_read = i_APCI1500_Initialisation,
- .di_write = i_APCI1500_StartStopInputEvent,
- .di_bits = i_APCI1500_ReadMoreDigitalInput,
- .do_config = i_APCI1500_ConfigDigitalOutputErrorInterrupt,
- .do_write = i_APCI1500_WriteDigitalOutput,
- .do_bits = i_APCI1500_ConfigureInterrupt,
- .timer_config = i_APCI1500_ConfigCounterTimerWatchdog,
- .timer_write = i_APCI1500_StartStopTriggerTimerCounterWatchdog,
- .timer_read = i_APCI1500_ReadInterruptMask,
- .timer_bits = i_APCI1500_ReadCounterTimerWatchdog,
- },
-#endif
-#ifdef CONFIG_APCI_3001
- {
- .pc_DriverName = "apci3001",
- .i_VendorId = APCI3120_BOARD_VENDOR_ID,
- .i_DeviceId = 0x828D,
- .i_IorangeBase0 = AMCC_OP_REG_SIZE,
- .i_IorangeBase1 = APCI3120_ADDRESS_RANGE,
- .i_IorangeBase2 = 8,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .i_NbrAiChannel = 16,
- .i_NbrAiChannelDiff = 8,
- .i_AiChannelList = 16,
- .i_AiMaxdata = 0xfff,
- .pr_AiRangelist = &range_apci3120_ai,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 0x0f,
- .i_Dma = 1,
- .i_Timer = 1,
- .b_AvailableConvertUnit = 1,
- .ui_MinAcquisitiontimeNs = 10000,
- .ui_MinDelaytimeNs = 100000,
- .interrupt = v_APCI3120_Interrupt,
- .reset = i_APCI3120_Reset,
- .ai_config = i_APCI3120_InsnConfigAnalogInput,
- .ai_read = i_APCI3120_InsnReadAnalogInput,
- .ai_cmdtest = i_APCI3120_CommandTestAnalogInput,
- .ai_cmd = i_APCI3120_CommandAnalogInput,
- .ai_cancel = i_APCI3120_StopCyclicAcquisition,
- .di_read = i_APCI3120_InsnReadDigitalInput,
- .di_bits = i_APCI3120_InsnBitsDigitalInput,
- .do_config = i_APCI3120_InsnConfigDigitalOutput,
- .do_write = i_APCI3120_InsnWriteDigitalOutput,
- .do_bits = i_APCI3120_InsnBitsDigitalOutput,
- .timer_config = i_APCI3120_InsnConfigTimer,
- .timer_write = i_APCI3120_InsnWriteTimer,
- .timer_read = i_APCI3120_InsnReadTimer,
- },
-#endif
-#ifdef CONFIG_APCI_3501
- {
- .pc_DriverName = "apci3501",
- .i_VendorId = APCI3501_BOARD_VENDOR_ID,
- .i_DeviceId = 0x3001,
- .i_IorangeBase0 = 64,
- .i_IorangeBase1 = APCI3501_ADDRESS_RANGE,
- .i_PCIEeprom = ADDIDATA_EEPROM,
- .pc_EepromChip = ADDIDATA_S5933,
- .i_AoMaxdata = 16383,
- .pr_AoRangelist = &range_apci3501_ao,
- .i_NbrDiChannel = 2,
- .i_NbrDoChannel = 2,
- .i_DoMaxdata = 0x3,
- .i_Timer = 1,
- .interrupt = v_APCI3501_Interrupt,
- .reset = i_APCI3501_Reset,
- .ao_config = i_APCI3501_ConfigAnalogOutput,
- .ao_write = i_APCI3501_WriteAnalogOutput,
- .di_bits = i_APCI3501_ReadDigitalInput,
- .do_config = i_APCI3501_ConfigDigitalOutput,
- .do_write = i_APCI3501_WriteDigitalOutput,
- .do_bits = i_APCI3501_ReadDigitalOutput,
- .timer_config = i_APCI3501_ConfigTimerCounterWatchdog,
- .timer_write = i_APCI3501_StartStopWriteTimerCounterWatchdog,
- .timer_read = i_APCI3501_ReadTimerCounterWatchdog,
- },
-#endif
-#ifdef CONFIG_APCI_035
- {
- .pc_DriverName = "apci035",
- .i_VendorId = APCI035_BOARD_VENDOR_ID,
- .i_DeviceId = 0x0300,
- .i_IorangeBase0 = 127,
- .i_IorangeBase1 = APCI035_ADDRESS_RANGE,
- .i_PCIEeprom = 1,
- .pc_EepromChip = ADDIDATA_S5920,
- .i_NbrAiChannel = 16,
- .i_NbrAiChannelDiff = 8,
- .i_AiChannelList = 16,
- .i_AiMaxdata = 0xff,
- .pr_AiRangelist = &range_apci035_ai,
- .i_Timer = 1,
- .ui_MinAcquisitiontimeNs = 10000,
- .ui_MinDelaytimeNs = 100000,
- .interrupt = v_APCI035_Interrupt,
- .reset = i_APCI035_Reset,
- .ai_config = i_APCI035_ConfigAnalogInput,
- .ai_read = i_APCI035_ReadAnalogInput,
- .timer_config = i_APCI035_ConfigTimerWatchdog,
- .timer_write = i_APCI035_StartStopWriteTimerWatchdog,
- .timer_read = i_APCI035_ReadTimerWatchdog,
- },
-#endif
-#ifdef CONFIG_APCI_3200
- {
- .pc_DriverName = "apci3200",
- .i_VendorId = APCI3200_BOARD_VENDOR_ID,
- .i_DeviceId = 0x3000,
- .i_IorangeBase0 = 128,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 4,
- .i_IorangeBase3 = 4,
- .i_PCIEeprom = ADDIDATA_EEPROM,
- .pc_EepromChip = ADDIDATA_S5920,
- .i_NbrAiChannel = 16,
- .i_NbrAiChannelDiff = 8,
- .i_AiChannelList = 16,
- .i_AiMaxdata = 0x3ffff,
- .pr_AiRangelist = &range_apci3200_ai,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .ui_MinAcquisitiontimeNs = 10000,
- .ui_MinDelaytimeNs = 100000,
- .interrupt = v_APCI3200_Interrupt,
- .reset = i_APCI3200_Reset,
- .ai_config = i_APCI3200_ConfigAnalogInput,
- .ai_read = i_APCI3200_ReadAnalogInput,
- .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput,
- .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test,
- .ai_cmdtest = i_APCI3200_CommandTestAnalogInput,
- .ai_cmd = i_APCI3200_CommandAnalogInput,
- .ai_cancel = i_APCI3200_StopCyclicAcquisition,
- .di_bits = i_APCI3200_ReadDigitalInput,
- .do_config = i_APCI3200_ConfigDigitalOutput,
- .do_write = i_APCI3200_WriteDigitalOutput,
- .do_bits = i_APCI3200_ReadDigitalOutput,
- },
-#endif
-#ifdef CONFIG_APCI_3300
- /* Begin JK .20.10.2004 = APCI-3300 integration */
- {
- .pc_DriverName = "apci3300",
- .i_VendorId = APCI3200_BOARD_VENDOR_ID,
- .i_DeviceId = 0x3007,
- .i_IorangeBase0 = 128,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 4,
- .i_IorangeBase3 = 4,
- .i_PCIEeprom = ADDIDATA_EEPROM,
- .pc_EepromChip = ADDIDATA_S5920,
- .i_NbrAiChannelDiff = 8,
- .i_AiChannelList = 8,
- .i_AiMaxdata = 0x3ffff,
- .pr_AiRangelist = &range_apci3300_ai,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .ui_MinAcquisitiontimeNs = 10000,
- .ui_MinDelaytimeNs = 100000,
- .interrupt = v_APCI3200_Interrupt,
- .reset = i_APCI3200_Reset,
- .ai_config = i_APCI3200_ConfigAnalogInput,
- .ai_read = i_APCI3200_ReadAnalogInput,
- .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput,
- .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test,
- .ai_cmdtest = i_APCI3200_CommandTestAnalogInput,
- .ai_cmd = i_APCI3200_CommandAnalogInput,
- .ai_cancel = i_APCI3200_StopCyclicAcquisition,
- .di_bits = i_APCI3200_ReadDigitalInput,
- .do_config = i_APCI3200_ConfigDigitalOutput,
- .do_write = i_APCI3200_WriteDigitalOutput,
- .do_bits = i_APCI3200_ReadDigitalOutput,
- },
-#endif
-#ifdef CONFIG_APCI_1710
- {
- .pc_DriverName = "apci1710",
- .i_VendorId = APCI1710_BOARD_VENDOR_ID,
- .i_DeviceId = APCI1710_BOARD_DEVICE_ID,
- .i_IorangeBase0 = 128,
- .i_IorangeBase1 = 8,
- .i_IorangeBase2 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .interrupt = v_APCI1710_Interrupt,
- .reset = i_APCI1710_Reset,
- },
-#endif
-#ifdef CONFIG_APCI_16XX
- {
- .pc_DriverName = "apci1648",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x1009,
- .i_IorangeBase0 = 128,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .i_NbrTTLChannel = 48,
- .reset = i_APCI16XX_Reset,
- .ttl_config = i_APCI16XX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI16XX_InsnBitsReadTTLIO,
- .ttl_read = i_APCI16XX_InsnReadTTLIOAllPortValue,
- .ttl_write = i_APCI16XX_InsnBitsWriteTTLIO,
- }, {
- .pc_DriverName = "apci1696",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x100A,
- .i_IorangeBase0 = 128,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .i_NbrTTLChannel = 96,
- .reset = i_APCI16XX_Reset,
- .ttl_config = i_APCI16XX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI16XX_InsnBitsReadTTLIO,
- .ttl_read = i_APCI16XX_InsnReadTTLIOAllPortValue,
- .ttl_write = i_APCI16XX_InsnBitsWriteTTLIO,
- },
-#endif
-#ifdef CONFIG_APCI_3XXX
- {
- .pc_DriverName = "apci3000-16",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3010,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 16,
- .i_NbrAiChannelDiff = 8,
- .i_AiChannelList = 16,
- .i_AiMaxdata = 4095,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 10000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3000-8",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x300F,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 8,
- .i_NbrAiChannelDiff = 4,
- .i_AiChannelList = 8,
- .i_AiMaxdata = 4095,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 10000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3000-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x300E,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 4,
- .i_NbrAiChannelDiff = 2,
- .i_AiChannelList = 4,
- .i_AiMaxdata = 4095,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 10000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3006-16",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3013,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 16,
- .i_NbrAiChannelDiff = 8,
- .i_AiChannelList = 16,
- .i_AiMaxdata = 65535,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 10000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3006-8",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3014,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 8,
- .i_NbrAiChannelDiff = 4,
- .i_AiChannelList = 8,
- .i_AiMaxdata = 65535,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 10000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3006-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3015,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 4,
- .i_NbrAiChannelDiff = 2,
- .i_AiChannelList = 4,
- .i_AiMaxdata = 65535,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 10000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3010-16",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3016,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 16,
- .i_NbrAiChannelDiff = 8,
- .i_AiChannelList = 16,
- .i_AiMaxdata = 4095,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 1,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 5000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .di_read = i_APCI3XXX_InsnReadDigitalInput,
- .di_bits = i_APCI3XXX_InsnBitsDigitalInput,
- .do_write = i_APCI3XXX_InsnWriteDigitalOutput,
- .do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
- .do_read = i_APCI3XXX_InsnReadDigitalOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3010-8",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3017,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 8,
- .i_NbrAiChannelDiff = 4,
- .i_AiChannelList = 8,
- .i_AiMaxdata = 4095,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 1,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 5000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .di_read = i_APCI3XXX_InsnReadDigitalInput,
- .di_bits = i_APCI3XXX_InsnBitsDigitalInput,
- .do_write = i_APCI3XXX_InsnWriteDigitalOutput,
- .do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
- .do_read = i_APCI3XXX_InsnReadDigitalOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3010-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3018,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 4,
- .i_NbrAiChannelDiff = 2,
- .i_AiChannelList = 4,
- .i_AiMaxdata = 4095,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 1,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 5000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .di_read = i_APCI3XXX_InsnReadDigitalInput,
- .di_bits = i_APCI3XXX_InsnBitsDigitalInput,
- .do_write = i_APCI3XXX_InsnWriteDigitalOutput,
- .do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
- .do_read = i_APCI3XXX_InsnReadDigitalOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3016-16",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3019,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 16,
- .i_NbrAiChannelDiff = 8,
- .i_AiChannelList = 16,
- .i_AiMaxdata = 65535,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 1,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 5000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .di_read = i_APCI3XXX_InsnReadDigitalInput,
- .di_bits = i_APCI3XXX_InsnBitsDigitalInput,
- .do_write = i_APCI3XXX_InsnWriteDigitalOutput,
- .do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
- .do_read = i_APCI3XXX_InsnReadDigitalOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3016-8",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x301A,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 8,
- .i_NbrAiChannelDiff = 4,
- .i_AiChannelList = 8,
- .i_AiMaxdata = 65535,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 1,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 5000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .di_read = i_APCI3XXX_InsnReadDigitalInput,
- .di_bits = i_APCI3XXX_InsnBitsDigitalInput,
- .do_write = i_APCI3XXX_InsnWriteDigitalOutput,
- .do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
- .do_read = i_APCI3XXX_InsnReadDigitalOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3016-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x301B,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 4,
- .i_NbrAiChannelDiff = 2,
- .i_AiChannelList = 4,
- .i_AiMaxdata = 65535,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 1,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 5000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .di_read = i_APCI3XXX_InsnReadDigitalInput,
- .di_bits = i_APCI3XXX_InsnBitsDigitalInput,
- .do_write = i_APCI3XXX_InsnWriteDigitalOutput,
- .do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
- .do_read = i_APCI3XXX_InsnReadDigitalOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3100-16-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x301C,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 16,
- .i_NbrAiChannelDiff = 8,
- .i_AiChannelList = 16,
- .i_NbrAoChannel = 4,
- .i_AiMaxdata = 4095,
- .i_AoMaxdata = 4095,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .pr_AoRangelist = &range_apci3XXX_ao,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 10000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3100-8-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x301D,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 8,
- .i_NbrAiChannelDiff = 4,
- .i_AiChannelList = 8,
- .i_NbrAoChannel = 4,
- .i_AiMaxdata = 4095,
- .i_AoMaxdata = 4095,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .pr_AoRangelist = &range_apci3XXX_ao,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 10000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3106-16-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x301E,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 16,
- .i_NbrAiChannelDiff = 8,
- .i_AiChannelList = 16,
- .i_NbrAoChannel = 4,
- .i_AiMaxdata = 65535,
- .i_AoMaxdata = 4095,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .pr_AoRangelist = &range_apci3XXX_ao,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 10000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3106-8-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x301F,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 8,
- .i_NbrAiChannelDiff = 4,
- .i_AiChannelList = 8,
- .i_NbrAoChannel = 4,
- .i_AiMaxdata = 65535,
- .i_AoMaxdata = 4095,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .pr_AoRangelist = &range_apci3XXX_ao,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 10000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3110-16-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3020,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 16,
- .i_NbrAiChannelDiff = 8,
- .i_AiChannelList = 16,
- .i_NbrAoChannel = 4,
- .i_AiMaxdata = 4095,
- .i_AoMaxdata = 4095,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .pr_AoRangelist = &range_apci3XXX_ao,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 1,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 5000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
- .di_read = i_APCI3XXX_InsnReadDigitalInput,
- .di_bits = i_APCI3XXX_InsnBitsDigitalInput,
- .do_write = i_APCI3XXX_InsnWriteDigitalOutput,
- .do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
- .do_read = i_APCI3XXX_InsnReadDigitalOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3110-8-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3021,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 8,
- .i_NbrAiChannelDiff = 4,
- .i_AiChannelList = 8,
- .i_NbrAoChannel = 4,
- .i_AiMaxdata = 4095,
- .i_AoMaxdata = 4095,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .pr_AoRangelist = &range_apci3XXX_ao,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 1,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 5000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
- .di_read = i_APCI3XXX_InsnReadDigitalInput,
- .di_bits = i_APCI3XXX_InsnBitsDigitalInput,
- .do_write = i_APCI3XXX_InsnWriteDigitalOutput,
- .do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
- .do_read = i_APCI3XXX_InsnReadDigitalOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3116-16-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3022,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 16,
- .i_NbrAiChannelDiff = 8,
- .i_AiChannelList = 16,
- .i_NbrAoChannel = 4,
- .i_AiMaxdata = 65535,
- .i_AoMaxdata = 4095,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .pr_AoRangelist = &range_apci3XXX_ao,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 1,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 5000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
- .di_read = i_APCI3XXX_InsnReadDigitalInput,
- .di_bits = i_APCI3XXX_InsnBitsDigitalInput,
- .do_write = i_APCI3XXX_InsnWriteDigitalOutput,
- .do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
- .do_read = i_APCI3XXX_InsnReadDigitalOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3116-8-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3023,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannel = 8,
- .i_NbrAiChannelDiff = 4,
- .i_AiChannelList = 8,
- .i_NbrAoChannel = 4,
- .i_AiMaxdata = 65535,
- .i_AoMaxdata = 4095,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .pr_AoRangelist = &range_apci3XXX_ao,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 1,
- .i_NbrTTLChannel = 24,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 5000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
- .di_read = i_APCI3XXX_InsnReadDigitalInput,
- .di_bits = i_APCI3XXX_InsnBitsDigitalInput,
- .do_write = i_APCI3XXX_InsnWriteDigitalOutput,
- .do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
- .do_read = i_APCI3XXX_InsnReadDigitalOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
- .pc_DriverName = "apci3003",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x300B,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannelDiff = 4,
- .i_AiChannelList = 4,
- .i_AiMaxdata = 65535,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 1,
- .b_AvailableConvertUnit = 7,
- .ui_MinAcquisitiontimeNs = 2500,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .di_read = i_APCI3XXX_InsnReadDigitalInput,
- .di_bits = i_APCI3XXX_InsnBitsDigitalInput,
- .do_write = i_APCI3XXX_InsnWriteDigitalOutput,
- .do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
- .do_read = i_APCI3XXX_InsnReadDigitalOutput,
- }, {
- .pc_DriverName = "apci3002-16",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3002,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannelDiff = 16,
- .i_AiChannelList = 16,
- .i_AiMaxdata = 65535,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 1,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 5000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .di_read = i_APCI3XXX_InsnReadDigitalInput,
- .di_bits = i_APCI3XXX_InsnBitsDigitalInput,
- .do_write = i_APCI3XXX_InsnWriteDigitalOutput,
- .do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
- .do_read = i_APCI3XXX_InsnReadDigitalOutput,
- }, {
- .pc_DriverName = "apci3002-8",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3003,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannelDiff = 8,
- .i_AiChannelList = 8,
- .i_AiMaxdata = 65535,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 1,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 5000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .di_read = i_APCI3XXX_InsnReadDigitalInput,
- .di_bits = i_APCI3XXX_InsnBitsDigitalInput,
- .do_write = i_APCI3XXX_InsnWriteDigitalOutput,
- .do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
- .do_read = i_APCI3XXX_InsnReadDigitalOutput,
- }, {
- .pc_DriverName = "apci3002-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3004,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAiChannelDiff = 4,
- .i_AiChannelList = 4,
- .i_AiMaxdata = 65535,
- .pr_AiRangelist = &range_apci3XXX_ai,
- .i_NbrDiChannel = 4,
- .i_NbrDoChannel = 4,
- .i_DoMaxdata = 1,
- .b_AvailableConvertUnit = 6,
- .ui_MinAcquisitiontimeNs = 5000,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
- .ai_read = i_APCI3XXX_InsnReadAnalogInput,
- .di_read = i_APCI3XXX_InsnReadDigitalInput,
- .di_bits = i_APCI3XXX_InsnBitsDigitalInput,
- .do_write = i_APCI3XXX_InsnWriteDigitalOutput,
- .do_bits = i_APCI3XXX_InsnBitsDigitalOutput,
- .do_read = i_APCI3XXX_InsnReadDigitalOutput,
- }, {
- .pc_DriverName = "apci3500",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3024,
- .i_IorangeBase0 = 256,
- .i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
- .pc_EepromChip = ADDIDATA_9054,
- .i_NbrAoChannel = 4,
- .i_AoMaxdata = 4095,
- .pr_AoRangelist = &range_apci3XXX_ao,
- .i_NbrTTLChannel = 24,
- .interrupt = v_APCI3XXX_Interrupt,
- .reset = i_APCI3XXX_Reset,
- .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
- .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
- .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
- .ttl_read = i_APCI3XXX_InsnReadTTLIO,
- .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- },
-#endif
-};
+static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
+ unsigned short w_Address = CR_CHAN(insn->chanspec);
+ unsigned short w_Data;
-static struct comedi_driver driver_addi = {
- .driver_name = ADDIDATA_DRIVER_NAME,
- .module = THIS_MODULE,
- .attach = i_ADDI_Attach,
- .detach = i_ADDI_Detach,
- .num_names = ARRAY_SIZE(boardtypes),
- .board_name = &boardtypes[0].pc_DriverName,
- .offset = sizeof(struct addi_board),
-};
+ w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc,
+ this_board->pc_EepromChip, 2 * w_Address);
+ data[0] = w_Data;
-static int __devinit driver_addi_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
-{
- return comedi_pci_auto_config(dev, &driver_addi);
+ return insn->n;
}
-static void __devexit driver_addi_pci_remove(struct pci_dev *dev)
+static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
{
- comedi_pci_auto_unconfig(dev);
-}
+ struct comedi_device *dev = d;
+ const struct addi_board *this_board = comedi_board(dev);
-static struct pci_driver driver_addi_pci_driver = {
- .id_table = addi_apci_tbl,
- .probe = &driver_addi_pci_probe,
- .remove = __devexit_p(&driver_addi_pci_remove)
-};
+ this_board->interrupt(irq, d);
+ return IRQ_RETVAL(1);
+}
-static int __init driver_addi_init_module(void)
+static int i_ADDI_Reset(struct comedi_device *dev)
{
- int retval;
-
- retval = comedi_driver_register(&driver_addi);
- if (retval < 0)
- return retval;
+ const struct addi_board *this_board = comedi_board(dev);
- driver_addi_pci_driver.name = (char *)driver_addi.driver_name;
- return pci_register_driver(&driver_addi_pci_driver);
+ this_board->reset(dev);
+ return 0;
}
-static void __exit driver_addi_cleanup_module(void)
+static const void *addi_find_boardinfo(struct comedi_device *dev,
+ struct pci_dev *pcidev)
{
- pci_unregister_driver(&driver_addi_pci_driver);
- comedi_driver_unregister(&driver_addi);
+ const void *p = dev->driver->board_name;
+ const struct addi_board *this_board;
+ int i;
+
+ for (i = 0; i < dev->driver->num_names; i++) {
+ this_board = p;
+ if (this_board->i_VendorId == pcidev->vendor &&
+ this_board->i_DeviceId == pcidev->device)
+ return this_board;
+ p += dev->driver->offset;
+ }
+ return NULL;
}
-module_init(driver_addi_init_module);
-module_exit(driver_addi_cleanup_module);
-
-/*
-+----------------------------------------------------------------------------+
-| Function name :static int i_ADDI_Attach(struct comedi_device *dev, |
-| struct comedi_devconfig *it) |
-| |
-+----------------------------------------------------------------------------+
-| Task :Detects the card. |
-| Configure the driver for a particular board. |
-| This function does all the initializations and memory |
-| allocation of data structures for the driver. |
-+----------------------------------------------------------------------------+
-| Input Parameters :struct comedi_device *dev |
-| struct comedi_devconfig *it |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int addi_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ const struct addi_board *this_board;
+ struct addi_private *devpriv;
struct comedi_subdevice *s;
- int ret, pages, i, n_subdevices;
+ int ret, n_subdevices;
unsigned int dw_Dummy;
- resource_size_t io_addr[5];
- unsigned int irq;
- resource_size_t iobase_a, iobase_main, iobase_addon, iobase_reserved;
- struct pcilst_struct *card = NULL;
- unsigned char pci_bus, pci_slot, pci_func;
- int i_Dma = 0;
-
- ret = alloc_private(dev, sizeof(struct addi_private));
- if (ret < 0)
- return -ENOMEM;
-
- if (!pci_list_builded) {
- v_pci_card_list_init(this_board->i_VendorId, 1); /* 1 for displaying the list.. */
- pci_list_builded = 1;
- }
- /* printk("comedi%d: "ADDIDATA_DRIVER_NAME": board=%s",dev->minor,this_board->pc_DriverName); */
-
- if ((this_board->i_Dma) && (it->options[2] == 0)) {
- i_Dma = 1;
- }
-
- card = ptr_select_and_alloc_pci_card(this_board->i_VendorId,
- this_board->i_DeviceId,
- it->options[0],
- it->options[1], i_Dma);
-
- if (card == NULL)
- return -EIO;
-
- devpriv->allocated = 1;
-
- if ((i_pci_card_data(card, &pci_bus, &pci_slot, &pci_func, &io_addr[0],
- &irq)) < 0) {
- i_pci_card_free(card);
- printk(" - Can't get AMCC data!\n");
- return -EIO;
- }
-
- iobase_a = io_addr[0];
- iobase_main = io_addr[1];
- iobase_addon = io_addr[2];
- iobase_reserved = io_addr[3];
- printk("\nBus %d: Slot %d: Funct%d\nBase0: 0x%8llx\nBase1: 0x%8llx\nBase2: 0x%8llx\nBase3: 0x%8llx\n", pci_bus, pci_slot, pci_func, (unsigned long long)io_addr[0], (unsigned long long)io_addr[1], (unsigned long long)io_addr[2], (unsigned long long)io_addr[3]);
- if ((this_board->pc_EepromChip == NULL)
- || (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) {
- /************************************/
- /* Test if more that 1 address used */
- /************************************/
+ this_board = addi_find_boardinfo(dev, pcidev);
+ if (!this_board)
+ return -ENODEV;
+ dev->board_ptr = this_board;
+ dev->board_name = this_board->pc_DriverName;
- if (this_board->i_IorangeBase1 != 0) {
- dev->iobase = (unsigned long)iobase_main; /* DAQ base address... */
- } else {
- dev->iobase = (unsigned long)iobase_a; /* DAQ base address... */
- }
-
- dev->board_name = this_board->pc_DriverName;
- devpriv->amcc = card;
- devpriv->iobase = (int) dev->iobase;
- devpriv->i_IobaseAmcc = (int) iobase_a; /* AMCC base address... */
- devpriv->i_IobaseAddon = (int) iobase_addon; /* ADD ON base address.... */
- devpriv->i_IobaseReserved = (int) iobase_reserved;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
+ ret = comedi_pci_enable(pcidev, dev->board_name);
+ if (ret)
+ return ret;
+
+ if (!this_board->pc_EepromChip ||
+ strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) {
+ /* board does not have an eeprom or is not ADDIDATA_9054 */
+ if (this_board->i_IorangeBase1)
+ dev->iobase = pci_resource_start(pcidev, 1);
+ else
+ dev->iobase = pci_resource_start(pcidev, 0);
+
+ devpriv->iobase = dev->iobase;
+ devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0);
+ devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2);
} else {
- dev->board_name = this_board->pc_DriverName;
- dev->iobase = (unsigned long)io_addr[2];
- devpriv->amcc = card;
- devpriv->iobase = (int) io_addr[2];
- devpriv->i_IobaseReserved = (int) io_addr[3];
- printk("\nioremap begin");
- devpriv->dw_AiBase = ioremap(io_addr[3],
+ /* board has an ADDIDATA_9054 eeprom */
+ dev->iobase = pci_resource_start(pcidev, 2);
+ devpriv->iobase = pci_resource_start(pcidev, 2);
+ devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3),
this_board->i_IorangeBase3);
- printk("\nioremap end");
}
+ devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3);
/* Initialize parameters that can be overridden in EEPROM */
devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel;
@@ -1566,30 +155,19 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
/* ## */
- if (irq > 0) {
- if (request_irq(irq, v_ADDI_Interrupt, IRQF_SHARED,
- this_board->pc_DriverName, dev) < 0) {
- printk(", unable to allocate IRQ %u, DISABLING IT",
- irq);
- irq = 0; /* Can't use IRQ */
- } else {
- printk("\nirq=%u", irq);
- }
- } else {
- printk(", IRQ disabled");
+ if (pcidev->irq > 0) {
+ ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
+ dev->board_name, dev);
+ if (ret == 0)
+ dev->irq = pcidev->irq;
}
- printk("\nOption %d %d %d\n", it->options[0], it->options[1],
- it->options[2]);
- dev->irq = irq;
-
/* Read eepeom and fill addi_board Structure */
if (this_board->i_PCIEeprom) {
- printk("\nPCI Eeprom used");
if (!(strcmp(this_board->pc_EepromChip, "S5920"))) {
/* Set 3 wait stait */
- if (!(strcmp(this_board->pc_DriverName, "apci035"))) {
+ if (!(strcmp(dev->board_name, "apci035"))) {
outl(0x80808082, devpriv->i_IobaseAmcc + 0x60);
} else {
outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
@@ -1597,340 +175,174 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
/* Enable the interrupt for the controller */
dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
- printk("\nEnable the interrupt for the controller");
}
- printk("\nRead Eeprom");
- i_EepromReadMainHeader(io_addr[0], this_board->pc_EepromChip,
- dev);
- } else {
- printk("\nPCI Eeprom unused");
- }
-
- if (it->options[2] > 0) {
- devpriv->us_UseDma = ADDI_DISABLE;
- } else {
- devpriv->us_UseDma = ADDI_ENABLE;
+ addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0));
}
- if (devpriv->s_EeParameters.i_Dma) {
- printk("\nDMA used");
- if (devpriv->us_UseDma == ADDI_ENABLE) {
- /* alloc DMA buffers */
- devpriv->b_DmaDoubleBuffer = 0;
- for (i = 0; i < 2; i++) {
- for (pages = 4; pages >= 0; pages--) {
- devpriv->ul_DmaBufferVirtual[i] =
- (void *) __get_free_pages(GFP_KERNEL, pages);
-
- if (devpriv->ul_DmaBufferVirtual[i])
- break;
- }
- if (devpriv->ul_DmaBufferVirtual[i]) {
- devpriv->ui_DmaBufferPages[i] = pages;
- devpriv->ui_DmaBufferSize[i] =
- PAGE_SIZE * pages;
- devpriv->ui_DmaBufferSamples[i] =
- devpriv->
- ui_DmaBufferSize[i] >> 1;
- devpriv->ul_DmaBufferHw[i] =
- virt_to_bus((void *)devpriv->
- ul_DmaBufferVirtual[i]);
- }
- }
- if (!devpriv->ul_DmaBufferVirtual[0]) {
- printk
- (", Can't allocate DMA buffer, DMA disabled!");
- devpriv->us_UseDma = ADDI_DISABLE;
- }
-
- if (devpriv->ul_DmaBufferVirtual[1]) {
- devpriv->b_DmaDoubleBuffer = 1;
- }
- }
-
- if ((devpriv->us_UseDma == ADDI_ENABLE)) {
- printk("\nDMA ENABLED\n");
+ n_subdevices = 7;
+ ret = comedi_alloc_subdevices(dev, n_subdevices);
+ if (ret)
+ return ret;
+
+ /* Allocate and Initialise AI Subdevice Structures */
+ s = &dev->subdevices[0];
+ if ((devpriv->s_EeParameters.i_NbrAiChannel)
+ || (this_board->i_NbrAiChannelDiff)) {
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags =
+ SDF_READABLE | SDF_COMMON | SDF_GROUND
+ | SDF_DIFF;
+ if (devpriv->s_EeParameters.i_NbrAiChannel) {
+ s->n_chan =
+ devpriv->s_EeParameters.i_NbrAiChannel;
+ devpriv->b_SingelDiff = 0;
} else {
- printk("\nDMA DISABLED\n");
+ s->n_chan = this_board->i_NbrAiChannelDiff;
+ devpriv->b_SingelDiff = 1;
}
- }
-
- if (!strcmp(this_board->pc_DriverName, "apci1710")) {
-#ifdef CONFIG_APCI_1710
- i_ADDI_AttachPCI1710(dev);
-
- /* save base address */
- devpriv->s_BoardInfos.ui_Address = io_addr[2];
-#endif
- } else {
- n_subdevices = 7;
- ret = comedi_alloc_subdevices(dev, n_subdevices);
- if (ret)
- return ret;
+ s->maxdata = devpriv->s_EeParameters.i_AiMaxdata;
+ s->len_chanlist = this_board->i_AiChannelList;
+ s->range_table = this_board->pr_AiRangelist;
- /* Allocate and Initialise AI Subdevice Structures */
- s = &dev->subdevices[0];
- if ((devpriv->s_EeParameters.i_NbrAiChannel)
- || (this_board->i_NbrAiChannelDiff)) {
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags =
- SDF_READABLE | SDF_COMMON | SDF_GROUND
- | SDF_DIFF;
- if (devpriv->s_EeParameters.i_NbrAiChannel) {
- s->n_chan =
- devpriv->s_EeParameters.i_NbrAiChannel;
- devpriv->b_SingelDiff = 0;
- } else {
- s->n_chan = this_board->i_NbrAiChannelDiff;
- devpriv->b_SingelDiff = 1;
- }
- s->maxdata = devpriv->s_EeParameters.i_AiMaxdata;
- s->len_chanlist = this_board->i_AiChannelList;
- s->range_table = this_board->pr_AiRangelist;
-
- /* Set the initialisation flag */
- devpriv->b_AiInitialisation = 1;
-
- s->insn_config = this_board->ai_config;
- s->insn_read = this_board->ai_read;
- s->insn_write = this_board->ai_write;
- s->insn_bits = this_board->ai_bits;
- s->do_cmdtest = this_board->ai_cmdtest;
- s->do_cmd = this_board->ai_cmd;
- s->cancel = this_board->ai_cancel;
-
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
+ /* Set the initialisation flag */
+ devpriv->b_AiInitialisation = 1;
- /* Allocate and Initialise AO Subdevice Structures */
- s = &dev->subdevices[1];
- if (devpriv->s_EeParameters.i_NbrAoChannel) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
- s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel;
- s->maxdata = devpriv->s_EeParameters.i_AoMaxdata;
- s->len_chanlist =
- devpriv->s_EeParameters.i_NbrAoChannel;
- s->range_table = this_board->pr_AoRangelist;
- s->insn_config = this_board->ao_config;
- s->insn_write = this_board->ao_write;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
- /* Allocate and Initialise DI Subdevice Structures */
- s = &dev->subdevices[2];
- if (devpriv->s_EeParameters.i_NbrDiChannel) {
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
- s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel;
- s->maxdata = 1;
- 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;
- s->insn_bits = this_board->di_bits;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
- /* Allocate and Initialise DO Subdevice Structures */
- s = &dev->subdevices[3];
- if (devpriv->s_EeParameters.i_NbrDoChannel) {
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags =
- SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
- s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel;
- s->maxdata = devpriv->s_EeParameters.i_DoMaxdata;
- s->len_chanlist =
- devpriv->s_EeParameters.i_NbrDoChannel;
- s->range_table = &range_digital;
- s->io_bits = 0xf; /* all bits output */
+ s->insn_config = this_board->ai_config;
+ s->insn_read = this_board->ai_read;
+ s->insn_write = this_board->ai_write;
+ s->insn_bits = this_board->ai_bits;
+ s->do_cmdtest = this_board->ai_cmdtest;
+ s->do_cmd = this_board->ai_cmd;
+ s->cancel = this_board->ai_cancel;
- /* insn_config - for digital output memory */
- s->insn_config = this_board->do_config;
- s->insn_write = this_board->do_write;
- s->insn_bits = this_board->do_bits;
- s->insn_read = this_board->do_read;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
- /* Allocate and Initialise Timer Subdevice Structures */
- s = &dev->subdevices[4];
- if (devpriv->s_EeParameters.i_Timer) {
- s->type = COMEDI_SUBD_TIMER;
- s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
- s->n_chan = 1;
- s->maxdata = 0;
- s->len_chanlist = 1;
- s->range_table = &range_digital;
+ /* Allocate and Initialise AO Subdevice Structures */
+ s = &dev->subdevices[1];
+ if (devpriv->s_EeParameters.i_NbrAoChannel) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel;
+ s->maxdata = devpriv->s_EeParameters.i_AoMaxdata;
+ s->len_chanlist =
+ devpriv->s_EeParameters.i_NbrAoChannel;
+ s->range_table = this_board->pr_AoRangelist;
+ s->insn_config = this_board->ao_config;
+ s->insn_write = this_board->ao_write;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ /* Allocate and Initialise DI Subdevice Structures */
+ s = &dev->subdevices[2];
+ if (devpriv->s_EeParameters.i_NbrDiChannel) {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel;
+ s->maxdata = 1;
+ 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;
+ s->insn_bits = this_board->di_bits;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ /* Allocate and Initialise DO Subdevice Structures */
+ s = &dev->subdevices[3];
+ if (devpriv->s_EeParameters.i_NbrDoChannel) {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel;
+ s->maxdata = devpriv->s_EeParameters.i_DoMaxdata;
+ 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;
+ s->insn_write = this_board->do_write;
+ s->insn_bits = this_board->do_bits;
+ s->insn_read = this_board->do_read;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
- s->insn_write = this_board->timer_write;
- s->insn_read = this_board->timer_read;
- s->insn_config = this_board->timer_config;
- s->insn_bits = this_board->timer_bits;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
+ /* Allocate and Initialise Timer Subdevice Structures */
+ s = &dev->subdevices[4];
+ if (devpriv->s_EeParameters.i_Timer) {
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 1;
+ s->maxdata = 0;
+ s->len_chanlist = 1;
+ s->range_table = &range_digital;
+
+ s->insn_write = this_board->timer_write;
+ s->insn_read = this_board->timer_read;
+ s->insn_config = this_board->timer_config;
+ s->insn_bits = this_board->timer_bits;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
- /* Allocate and Initialise TTL */
- s = &dev->subdevices[5];
- if (this_board->i_NbrTTLChannel) {
- s->type = COMEDI_SUBD_TTLIO;
- s->subdev_flags =
- SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON;
- s->n_chan = this_board->i_NbrTTLChannel;
- s->maxdata = 1;
- s->io_bits = 0; /* all bits input */
- s->len_chanlist = this_board->i_NbrTTLChannel;
- s->range_table = &range_digital;
- s->insn_config = this_board->ttl_config;
- s->insn_bits = this_board->ttl_bits;
- s->insn_read = this_board->ttl_read;
- s->insn_write = this_board->ttl_write;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
+ /* Allocate and Initialise TTL */
+ s = &dev->subdevices[5];
+ if (this_board->i_NbrTTLChannel) {
+ s->type = COMEDI_SUBD_TTLIO;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->i_NbrTTLChannel;
+ s->maxdata = 1;
+ s->io_bits = 0; /* all bits input */
+ s->len_chanlist = this_board->i_NbrTTLChannel;
+ s->range_table = &range_digital;
+ s->insn_config = this_board->ttl_config;
+ s->insn_bits = this_board->ttl_bits;
+ s->insn_read = this_board->ttl_read;
+ s->insn_write = this_board->ttl_write;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
- /* EEPROM */
- s = &dev->subdevices[6];
- if (this_board->i_PCIEeprom) {
- s->type = COMEDI_SUBD_MEMORY;
- s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
- s->n_chan = 256;
- s->maxdata = 0xffff;
- s->insn_read = i_ADDIDATA_InsnReadEeprom;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
+ /* EEPROM */
+ s = &dev->subdevices[6];
+ if (this_board->i_PCIEeprom) {
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+ s->n_chan = 256;
+ s->maxdata = 0xffff;
+ s->insn_read = i_ADDIDATA_InsnReadEeprom;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
}
- printk("\ni_ADDI_Attach end\n");
i_ADDI_Reset(dev);
- devpriv->b_ValidDriver = 1;
return 0;
}
static void i_ADDI_Detach(struct comedi_device *dev)
{
- if (dev->private) {
- if (devpriv->b_ValidDriver)
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct addi_private *devpriv = dev->private;
+
+ if (devpriv) {
+ if (dev->iobase)
i_ADDI_Reset(dev);
if (dev->irq)
free_irq(dev->irq, dev);
- if ((this_board->pc_EepromChip == NULL) ||
- (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) {
- if (devpriv->allocated)
- i_pci_card_free(devpriv->amcc);
- if (devpriv->ul_DmaBufferVirtual[0]) {
- free_pages((unsigned long)devpriv->
- ul_DmaBufferVirtual[0],
- devpriv->ui_DmaBufferPages[0]);
- }
- if (devpriv->ul_DmaBufferVirtual[1]) {
- free_pages((unsigned long)devpriv->
- ul_DmaBufferVirtual[1],
- devpriv->ui_DmaBufferPages[1]);
- }
- } else {
+ if (devpriv->dw_AiBase)
iounmap(devpriv->dw_AiBase);
- if (devpriv->allocated)
- i_pci_card_free(devpriv->amcc);
- }
- if (pci_list_builded) {
- v_pci_card_list_cleanup(this_board->i_VendorId);
- pci_list_builded = 0;
- }
}
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function name : static int i_ADDI_Reset(struct comedi_device *dev) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Disables all interrupts, Resets digital output to low, |
-| Set all analog output to low |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-static int i_ADDI_Reset(struct comedi_device *dev)
-{
-
- this_board->reset(dev);
- return 0;
-}
-
-/* Interrupt function */
-/*
-+----------------------------------------------------------------------------+
-| Function name : |
-|static void v_ADDI_Interrupt(int irq, void *d) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Registerd interrupt routine |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : int irq |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- this_board->interrupt(irq, d);
- return IRQ_RETVAL(1);
-}
-
-/* EEPROM Read Function */
-/*
-+----------------------------------------------------------------------------+
-| Function name : |
-|INT i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev,struct comedi_subdevice *s,
- struct comedi_insn *insn,unsigned int *data)
-| |
-+----------------------------------------------------------------------------+
-| Task : Read 256 words from EEPROM |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters :(struct comedi_device *dev,struct comedi_subdevice *s,
- struct comedi_insn *insn,unsigned int *data) |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned short w_Data;
- unsigned short w_Address;
- w_Address = CR_CHAN(insn->chanspec); /* address to be read as 0,1,2,3...255 */
-
- w_Data = w_EepromReadWord(devpriv->i_IobaseAmcc,
- this_board->pc_EepromChip, 0x100 + (2 * w_Address));
- data[0] = w_Data;
- /* multiplied by 2 bcozinput will be like 0,1,2...255 */
- return insn->n;
-
+ if (pcidev) {
+ if (dev->iobase)
+ comedi_pci_disable(pcidev);
+ }
}
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h
index b7bbb7164f5..6d8b29f945d 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.h
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h
@@ -15,26 +15,8 @@
* any later version.
*/
-#include <linux/kernel.h>
-#include <linux/module.h>
#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/timer.h>
-#include <linux/pci.h>
-#include <linux/io.h>
-#include <linux/kmod.h>
-#include <linux/uaccess.h>
-#include "../../comedidev.h"
-#include "addi_amcc_s5933.h"
-
-#define ERROR -1
-#define SUCCESS 1
#define LOBYTE(W) (unsigned char)((W) & 0xFF)
#define HIBYTE(W) (unsigned char)(((W) >> 8) & 0xFF)
@@ -312,9 +294,6 @@ struct addi_private {
int i_IobaseAddon; /* addon base address */
int i_IobaseReserved;
void __iomem *dw_AiBase;
- struct pcilst_struct *amcc; /* ptr too AMCC data */
- unsigned char allocated; /* we have blocked card */
- unsigned char b_ValidDriver; /* driver is ok */
unsigned char b_AiContinuous; /* we do unlimited AI */
unsigned char b_AiInitialisation;
unsigned int ui_AiActualScan; /* how many scans we finished */
@@ -410,14 +389,3 @@ struct addi_private {
/* Minimum Delay in Nano secs */
} s_EeParameters;
};
-
-static unsigned short pci_list_builded; /* set to 1 when list of card is known */
-
-/* Function declarations */
-static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it);
-static void i_ADDI_Detach(struct comedi_device *dev);
-static int i_ADDI_Reset(struct comedi_device *dev);
-
-static irqreturn_t v_ADDI_Interrupt(int irq, void *d);
-static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
index 3a9339b9261..5124ac9f181 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
@@ -1,1162 +1,365 @@
-/**
-@verbatim
-
-Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
-
- ADDI-DATA GmbH
- Dieselstrasse 3
- D-77833 Ottersweier
- Tel: +19(0)7223/9493-0
- Fax: +49(0)7223/9493-92
- http://www.addi-data.com
- info@addi-data.com
-
-This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
-@endverbatim
-*/
/*
-
- +-----------------------------------------------------------------------+
- | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
- +-----------------------------------------------------------------------+
- | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
- | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
- +-----------------------------------------------------------------------+
- | Project : ADDI DATA | Compiler : GCC |
- | Modulname : addi_eeprom.c | Version : 2.96 |
- +-------------------------------+---------------------------------------+
- | Project manager: Eric Stolz | Date : 02/12/2002 |
- +-----------------------------------------------------------------------+
- | Description : ADDI EEPROM Module |
- +-----------------------------------------------------------------------+
- | UPDATE'S |
- +-----------------------------------------------------------------------+
- | Date | Author | Description of updates |
- +----------+-----------+------------------------------------------------+
- | | | |
- | | | |
- +----------+-----------+------------------------------------------------+
-*/
-
-#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */
-#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */
-#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */
-#define EE76_CMD_LEN 13 /* bits in instructions */
-#define EE_READ 0x0180 /* 01 1000 0000 read instruction */
-
-#define EEPROM_DIGITALINPUT 0
-#define EEPROM_DIGITALOUTPUT 1
-#define EEPROM_ANALOGINPUT 2
-#define EEPROM_ANALOGOUTPUT 3
-#define EEPROM_TIMER 4
-#define EEPROM_WATCHDOG 5
+ * addi_eeprom.c - ADDI EEPROM Module
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ * Project manager: Eric Stolz
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data.com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * You should also find the complete GPL in the COPYING file accompanying
+ * this source code.
+ */
+
+#define NVRAM_USER_DATA_START 0x100
+
+#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */
+#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */
+#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */
+
+#define EE93C76_CLK_BIT (1 << 0)
+#define EE93C76_CS_BIT (1 << 1)
+#define EE93C76_DOUT_BIT (1 << 2)
+#define EE93C76_DIN_BIT (1 << 3)
+#define EE93C76_READ_CMD (0x0180 << 4)
+#define EE93C76_CMD_LEN 13
+
+#define EEPROM_DIGITALINPUT 0
+#define EEPROM_DIGITALOUTPUT 1
+#define EEPROM_ANALOGINPUT 2
+#define EEPROM_ANALOGOUTPUT 3
+#define EEPROM_TIMER 4
+#define EEPROM_WATCHDOG 5
#define EEPROM_TIMER_WATCHDOG_COUNTER 10
-struct str_Functionality {
- unsigned char b_Type;
- unsigned short w_Address;
-};
-
-struct str_MainHeader {
- unsigned short w_HeaderSize;
- unsigned char b_Nfunctions;
- struct str_Functionality s_Functions[7];
-};
-
-struct str_DigitalInputHeader {
- unsigned short w_Nchannel;
- unsigned char b_Interruptible;
- unsigned short w_NinterruptLogic;
-};
-
-struct str_DigitalOutputHeader {
-
- unsigned short w_Nchannel;
-};
-
-
-/* used for timer as well as watchdog */
-
-struct str_TimerDetails {
-
- unsigned short w_HeaderSize;
- unsigned char b_Resolution;
- unsigned char b_Mode; /* in case of Watchdog it is functionality */
- unsigned short w_MinTiming;
- unsigned char b_TimeBase;
-};
-
-struct str_TimerMainHeader {
-
-
- unsigned short w_Ntimer;
- struct str_TimerDetails s_TimerDetails[4]; /* supports 4 timers */
-};
-
-
-struct str_AnalogOutputHeader {
- unsigned short w_Nchannel;
- unsigned char b_Resolution;
-};
-
-struct str_AnalogInputHeader {
- unsigned short w_Nchannel;
- unsigned short w_MinConvertTiming;
- unsigned short w_MinDelayTiming;
- unsigned char b_HasDma;
- unsigned char b_Resolution;
-};
-
-
- /*****************************************/
- /* Read Header Functions */
- /*****************************************/
-
-int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, struct comedi_device *dev);
-
-int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_DigitalInputHeader *s_Header);
-
-int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_DigitalOutputHeader *s_Header);
-
-int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_TimerMainHeader *s_Header);
-
-int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_AnalogOutputHeader *s_Header);
-
-int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_AnalogInputHeader *s_Header);
-
- /******************************************/
- /* Eeprom Specific Functions */
- /******************************************/
-unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
- unsigned short w_EepromStartAddress);
-void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress);
-void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue);
-void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress);
-void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand,
- unsigned char b_DataLengthInBits);
-void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value);
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : unsigned short w_EepromReadWord |
-| (unsigned short w_PCIBoardEepromAddress, |
-| char * pc_PCIChipInformation, |
-| unsigned short w_EepromStartAddress) |
-+----------------------------------------------------------------------------+
-| Task : Read from eepromn a word |
-+----------------------------------------------------------------------------+
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address |
-| |
-| char *pc_PCIChipInformation : PCI Chip Type. |
-| |
-| unsigned short w_EepromStartAddress : Selected eeprom address |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : Read word value from eeprom |
-+----------------------------------------------------------------------------+
-*/
-
-unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
- unsigned short w_EepromStartAddress)
+static void addi_eeprom_clk_93c76(unsigned long iobase, unsigned int val)
{
-
- unsigned char b_Counter = 0;
-
- unsigned char b_ReadByte = 0;
-
- unsigned char b_ReadLowByte = 0;
-
- unsigned char b_ReadHighByte = 0;
-
- unsigned char b_SelectedAddressLow = 0;
-
- unsigned char b_SelectedAddressHigh = 0;
-
- unsigned short w_ReadWord = 0;
-
- /**************************/
-
- /* Test the PCI chip type */
-
- /**************************/
-
- if ((!strcmp(pc_PCIChipInformation, "S5920")) ||
- (!strcmp(pc_PCIChipInformation, "S5933")))
- {
-
- for (b_Counter = 0; b_Counter < 2; b_Counter++)
- {
-
- b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256; /* Read the low 8 bit part */
-
- b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256; /* Read the high 8 bit part */
-
- /************************************/
-
- /* Select the load low address mode */
-
- /************************************/
-
- outb(NVCMD_LOAD_LOW, w_PCIBoardEepromAddress + 0x3F);
-
- /****************/
-
- /* Wait on busy */
-
- /****************/
-
- v_EepromWaitBusy(w_PCIBoardEepromAddress);
-
- /************************/
-
- /* Load the low address */
-
- /************************/
-
- outb(b_SelectedAddressLow,
- w_PCIBoardEepromAddress + 0x3E);
-
- /****************/
-
- /* Wait on busy */
-
- /****************/
-
- v_EepromWaitBusy(w_PCIBoardEepromAddress);
-
- /*************************************/
-
- /* Select the load high address mode */
-
- /*************************************/
-
- outb(NVCMD_LOAD_HIGH, w_PCIBoardEepromAddress + 0x3F);
-
- /****************/
-
- /* Wait on busy */
-
- /****************/
-
- v_EepromWaitBusy(w_PCIBoardEepromAddress);
-
- /*************************/
-
- /* Load the high address */
-
- /*************************/
-
- outb(b_SelectedAddressHigh,
- w_PCIBoardEepromAddress + 0x3E);
-
- /****************/
-
- /* Wait on busy */
-
- /****************/
-
- v_EepromWaitBusy(w_PCIBoardEepromAddress);
-
- /************************/
-
- /* Select the READ mode */
-
- /************************/
-
- outb(NVCMD_BEGIN_READ, w_PCIBoardEepromAddress + 0x3F);
-
- /****************/
-
- /* Wait on busy */
-
- /****************/
-
- v_EepromWaitBusy(w_PCIBoardEepromAddress);
-
- /*****************************/
-
- /* Read data into the EEPROM */
-
- /*****************************/
-
- b_ReadByte = inb(w_PCIBoardEepromAddress + 0x3E);
-
- /****************/
-
- /* Wait on busy */
-
- /****************/
-
- v_EepromWaitBusy(w_PCIBoardEepromAddress);
-
- /*********************************/
-
- /* Select the upper address part */
-
- /*********************************/
-
- if (b_Counter == 0)
- {
-
- b_ReadLowByte = b_ReadByte;
-
- } /* if(b_Counter==0) */
-
- else
- {
-
- b_ReadHighByte = b_ReadByte;
-
- } /* if(b_Counter==0) */
-
- } /* for (b_Counter=0; b_Counter<2; b_Counter++) */
-
- w_ReadWord = (b_ReadLowByte | (((unsigned short) b_ReadHighByte) * 256));
-
- } /* end of if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933"))) */
-
- if (!strcmp(pc_PCIChipInformation, "93C76"))
- {
-
- /*************************************/
-
- /* Read 16 bit from the EEPROM 93C76 */
-
- /*************************************/
-
- v_EepromCs76Read(w_PCIBoardEepromAddress, w_EepromStartAddress,
- &w_ReadWord);
-
- }
-
- return w_ReadWord;
-
-}
-
-/*
-
-+----------------------------------------------------------------------------+
-
-| Function Name : void v_EepromWaitBusy |
-
-| (unsigned short w_PCIBoardEepromAddress) |
-
-+----------------------------------------------------------------------------+
-
-| Task : Wait the busy flag from PCI controller |
-
-+----------------------------------------------------------------------------+
-
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom base address |
-
-+----------------------------------------------------------------------------+
-
-| Output Parameters : - |
-
-+----------------------------------------------------------------------------+
-
-| Return Value : - |
-
-+----------------------------------------------------------------------------+
-
-*/
-
-void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress)
-{
-
- unsigned char b_EepromBusy = 0;
-
- do
- {
-
- /*************/
-
- /* IMPORTANT */
-
- /*************/
-
- /************************************************************************/
-
- /* An error has been written in the AMCC 5933 book at the page B-13 */
-
- /* Ex: if you read a byte and look for the busy statusEEPROM=0x80 and */
-
- /* the operator register is AMCC_OP_REG_MCSR+3 */
-
- /* unsigned short read EEPROM=0x8000 andAMCC_OP_REG_MCSR+2 */
-
- /* unsigned int read EEPROM=0x80000000 and AMCC_OP_REG_MCSR */
-
- /************************************************************************/
-
- b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F);
- b_EepromBusy = b_EepromBusy & 0x80;
-
- } while (b_EepromBusy == 0x80);
-
-}
-
-/*
-
-+---------------------------------------------------------------------------------+
-
-| Function Name : void v_EepromClock76(unsigned int dw_Address, |
-
-| unsigned int dw_RegisterValue) |
-
-+---------------------------------------------------------------------------------+
-
-| Task : This function sends the clocking sequence to the EEPROM. |
-
-+---------------------------------------------------------------------------------+
-
-| Input Parameters : unsigned int dw_Address : PCI eeprom base address |
-
-| unsigned int dw_RegisterValue : PCI eeprom register value to write.|
-
-+---------------------------------------------------------------------------------+
-
-| Output Parameters : - |
-
-+---------------------------------------------------------------------------------+
-
-| Return Value : - |
-
-+---------------------------------------------------------------------------------+
-
-*/
-
-void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue)
-{
-
- /************************/
-
- /* Set EEPROM clock Low */
-
- /************************/
-
- outl(dw_RegisterValue & 0x6, dw_Address);
-
- /***************/
-
- /* Wait 0.1 ms */
-
- /***************/
-
+ outl(val & ~EE93C76_CLK_BIT, iobase);
udelay(100);
- /*************************/
-
- /* Set EEPROM clock High */
-
- /*************************/
-
- outl(dw_RegisterValue | 0x1, dw_Address);
-
- /***************/
-
- /* Wait 0.1 ms */
-
- /***************/
-
+ outl(val | EE93C76_CLK_BIT, iobase);
udelay(100);
-
}
-/*
-
-+---------------------------------------------------------------------------------+
-
-| Function Name : void v_EepromSendCommand76(unsigned int dw_Address, |
-
-| unsigned int dw_EepromCommand, |
-
-| unsigned char b_DataLengthInBits) |
-
-+---------------------------------------------------------------------------------+
-
-| Task : This function sends a Command to the EEPROM 93C76. |
-
-+---------------------------------------------------------------------------------+
-
-| Input Parameters : unsigned int dw_Address : PCI eeprom base address |
-
-| unsigned int dw_EepromCommand : PCI eeprom command to write. |
-
-| unsigned char b_DataLengthInBits : PCI eeprom command data length. |
-
-+---------------------------------------------------------------------------------+
-
-| Output Parameters : - |
-
-+---------------------------------------------------------------------------------+
-
-| Return Value : - |
-
-+---------------------------------------------------------------------------------+
-
-*/
-
-void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand,
- unsigned char b_DataLengthInBits)
+static unsigned int addi_eeprom_cmd_93c76(unsigned long iobase,
+ unsigned int cmd,
+ unsigned char len)
{
-
- char c_BitPos = 0;
-
- unsigned int dw_RegisterValue = 0;
-
- /*****************************/
-
- /* Enable EEPROM Chip Select */
-
- /*****************************/
-
- dw_RegisterValue = 0x2;
-
- /********************************************************************/
+ unsigned int val = EE93C76_CS_BIT;
+ int i;
/* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
-
- /********************************************************************/
-
- outl(dw_RegisterValue, dw_Address);
-
- /***************/
-
- /* Wait 0.1 ms */
-
- /***************/
-
+ outl(val, iobase);
udelay(100);
- /*******************************************/
-
/* Send EEPROM command - one bit at a time */
-
- /*******************************************/
-
- for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--)
- {
-
- /**********************************/
-
- /* Check if current bit is 0 or 1 */
-
- /**********************************/
-
- if (dw_EepromCommand & (1 << c_BitPos))
- {
-
- /***********/
-
- /* Write 1 */
-
- /***********/
-
- dw_RegisterValue = dw_RegisterValue | 0x4;
-
- }
-
+ for (i = (len - 1); i >= 0; i--) {
+ if (cmd & (1 << i))
+ val |= EE93C76_DOUT_BIT;
else
- {
-
- /***********/
-
- /* Write 0 */
-
- /***********/
-
- dw_RegisterValue = dw_RegisterValue & 0x3;
-
- }
-
- /*********************/
+ val &= ~EE93C76_DOUT_BIT;
/* Write the command */
-
- /*********************/
-
- outl(dw_RegisterValue, dw_Address);
-
- /***************/
-
- /* Wait 0.1 ms */
-
- /***************/
-
+ outl(val, iobase);
udelay(100);
- /****************************/
-
- /* Trigger the EEPROM clock */
-
- /****************************/
-
- v_EepromClock76(dw_Address, dw_RegisterValue);
-
+ addi_eeprom_clk_93c76(iobase, val);
}
-
+ return val;
}
-/*
-
-+---------------------------------------------------------------------------------+
-
-| Function Name : void v_EepromCs76Read(unsigned int dw_Address, |
-
-| unsigned short w_offset, |
-
-| unsigned short * pw_Value) |
-
-+---------------------------------------------------------------------------------+
-
-| Task : This function read a value from the EEPROM 93C76. |
-
-+---------------------------------------------------------------------------------+
-
-| Input Parameters : unsigned int dw_Address : PCI eeprom base address |
-
-| unsigned short w_offset : Offset of the address to read |
-
-| unsigned short * pw_Value : PCI eeprom 16 bit read value. |
-
-+---------------------------------------------------------------------------------+
-
-| Output Parameters : - |
-
-+---------------------------------------------------------------------------------+
-
-| Return Value : - |
-
-+---------------------------------------------------------------------------------+
-
-*/
-
-void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value)
+static unsigned short addi_eeprom_readw_93c76(unsigned long iobase,
+ unsigned short addr)
{
-
- char c_BitPos = 0;
-
- unsigned int dw_RegisterValue = 0;
-
- unsigned int dw_RegisterValueRead = 0;
-
- /*************************************************/
+ unsigned short val = 0;
+ unsigned int cmd;
+ unsigned int tmp;
+ int i;
/* Send EEPROM read command and offset to EEPROM */
-
- /*************************************************/
-
- v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2),
- EE76_CMD_LEN);
-
- /*******************************/
-
- /* Get the last register value */
-
- /*******************************/
-
- dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2;
-
- /*****************************/
-
- /* Set the 16-bit value of 0 */
-
- /*****************************/
-
- *pw_Value = 0;
-
- /************************/
+ cmd = EE93C76_READ_CMD | (addr / 2);
+ cmd = addi_eeprom_cmd_93c76(iobase, cmd, EE93C76_CMD_LEN);
/* Get the 16-bit value */
+ for (i = 0; i < 16; i++) {
+ addi_eeprom_clk_93c76(iobase, cmd);
- /************************/
-
- for (c_BitPos = 0; c_BitPos < 16; c_BitPos++)
- {
-
- /****************************/
-
- /* Trigger the EEPROM clock */
-
- /****************************/
-
- v_EepromClock76(dw_Address, dw_RegisterValue);
-
- /**********************/
-
- /* Get the result bit */
-
- /**********************/
-
- dw_RegisterValueRead = inl(dw_Address);
-
- /***************/
-
- /* Wait 0.1 ms */
-
- /***************/
-
+ tmp = inl(iobase);
udelay(100);
- /***************************************/
-
- /* Get bit value and shift into result */
-
- /***************************************/
-
- if (dw_RegisterValueRead & 0x8)
- {
-
- /**********/
+ val <<= 1;
+ if (tmp & EE93C76_DIN_BIT)
+ val |= 0x1;
+ }
- /* Read 1 */
+ /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
+ outl(0, iobase);
+ udelay(100);
- /**********/
+ return val;
+}
- *pw_Value = (*pw_Value << 1) | 0x1;
+static void addi_eeprom_nvram_wait(unsigned long iobase)
+{
+ unsigned char val;
- }
+ do {
+ val = inb(iobase + AMCC_OP_REG_MCSR_NVCMD);
+ } while (val & 0x80);
+}
+static unsigned short addi_eeprom_readw_nvram(unsigned long iobase,
+ unsigned short addr)
+{
+ unsigned short val = 0;
+ unsigned char tmp;
+ unsigned char i;
+
+ for (i = 0; i < 2; i++) {
+ /* Load the low 8 bit address */
+ outb(NVCMD_LOAD_LOW, iobase + AMCC_OP_REG_MCSR_NVCMD);
+ addi_eeprom_nvram_wait(iobase);
+ outb((addr + i) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
+ addi_eeprom_nvram_wait(iobase);
+
+ /* Load the high 8 bit address */
+ outb(NVCMD_LOAD_HIGH, iobase + AMCC_OP_REG_MCSR_NVCMD);
+ addi_eeprom_nvram_wait(iobase);
+ outb(((addr + i) >> 8) & 0xff,
+ iobase + AMCC_OP_REG_MCSR_NVDATA);
+ addi_eeprom_nvram_wait(iobase);
+
+ /* Read the eeprom data byte */
+ outb(NVCMD_BEGIN_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
+ addi_eeprom_nvram_wait(iobase);
+ tmp = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
+ addi_eeprom_nvram_wait(iobase);
+
+ if (i == 0)
+ val |= tmp;
else
- {
-
- /**********/
-
- /* Read 0 */
+ val |= (tmp << 8);
+ }
- /**********/
+ return val;
+}
- *pw_Value = (*pw_Value << 1);
+static unsigned short addi_eeprom_readw(unsigned long iobase,
+ char *type,
+ unsigned short addr)
+{
+ unsigned short val = 0;
- }
+ /* Add the offset to the start of the user data */
+ addr += NVRAM_USER_DATA_START;
- }
+ if (!strcmp(type, "S5920") || !strcmp(type, "S5933"))
+ val = addi_eeprom_readw_nvram(iobase, addr);
- /*************************/
+ if (!strcmp(type, "93C76"))
+ val = addi_eeprom_readw_93c76(iobase, addr);
- /* Clear all EEPROM bits */
+ return val;
+}
- /*************************/
+static void addi_eeprom_read_di_info(struct comedi_device *dev,
+ unsigned long iobase,
+ unsigned short addr)
+{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
+ char *type = this_board->pc_EepromChip;
+ unsigned short tmp;
- dw_RegisterValue = 0x0;
+ /* Number of channels */
+ tmp = addi_eeprom_readw(iobase, type, addr + 6);
+ devpriv->s_EeParameters.i_NbrDiChannel = tmp;
- /********************************************************************/
+ /* Interruptible or not */
+ tmp = addi_eeprom_readw(iobase, type, addr + 8);
+ tmp = (tmp >> 7) & 0x01;
- /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
+ /* How many interruptible logic */
+ tmp = addi_eeprom_readw(iobase, type, addr + 10);
+}
- /********************************************************************/
+static void addi_eeprom_read_do_info(struct comedi_device *dev,
+ unsigned long iobase,
+ unsigned short addr)
+{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
+ char *type = this_board->pc_EepromChip;
+ unsigned short tmp;
- outl(dw_RegisterValue, dw_Address);
+ /* Number of channels */
+ tmp = addi_eeprom_readw(iobase, type, addr + 6);
+ devpriv->s_EeParameters.i_NbrDoChannel = tmp;
- /***************/
+ devpriv->s_EeParameters.i_DoMaxdata = 0xffffffff >> (32 - tmp);
+}
- /* Wait 0.1 ms */
+static void addi_eeprom_read_timer_info(struct comedi_device *dev,
+ unsigned long iobase,
+ unsigned short addr)
+{
+ struct addi_private *devpriv = dev->private;
+#if 0
+ const struct addi_board *this_board = comedi_board(dev);
+ char *type = this_board->pc_EepromChip;
+ unsigned short offset = 0;
+ unsigned short ntimers;
+ unsigned short tmp;
+ int i;
+
+ /* Number of Timers */
+ ntimers = addi_eeprom_readw(iobase, type, addr + 6);
+
+ /* Read header size */
+ for (i = 0; i < ntimers; i++) {
+ unsigned short size;
+ unsigned short res;
+ unsigned short mode;
+ unsigned short min_timing;
+ unsigned short timebase;
+
+ size = addi_eeprom_readw(iobase, type, addr + 8 + offset + 0);
+
+ /* Resolution / Mode */
+ tmp = addi_eeprom_readw(iobase, type, addr + 8 + offset + 2);
+ res = (tmp >> 10) & 0x3f;
+ mode = (tmp >> 4) & 0x3f;
+
+ /* MinTiming / Timebase */
+ tmp = addi_eeprom_readw(iobase, type, addr + 8 + offset + 4);
+ min_timing = (tmp >> 6) & 0x3ff;
+ Timebase = tmp & 0x3f;
+
+ offset += size;
+ }
+#endif
+ /* Timer subdevice present */
+ devpriv->s_EeParameters.i_Timer = 1;
+}
- /***************/
+static void addi_eeprom_read_ao_info(struct comedi_device *dev,
+ unsigned long iobase,
+ unsigned short addr)
+{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
+ char *type = this_board->pc_EepromChip;
+ unsigned short tmp;
+
+ /* No of channels for 1st hard component */
+ tmp = addi_eeprom_readw(iobase, type, addr + 10);
+ devpriv->s_EeParameters.i_NbrAoChannel = (tmp >> 4) & 0x3ff;
+
+ /* Resolution for 1st hard component */
+ tmp = addi_eeprom_readw(iobase, type, addr + 16);
+ tmp = (tmp >> 8) & 0xff;
+ devpriv->s_EeParameters.i_AoMaxdata = 0xfff >> (16 - tmp);
+}
- udelay(100);
+static void addi_eeprom_read_ai_info(struct comedi_device *dev,
+ unsigned long iobase,
+ unsigned short addr)
+{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
+ char *type = this_board->pc_EepromChip;
+ unsigned short offset;
+ unsigned short tmp;
+
+ /* No of channels for 1st hard component */
+ tmp = addi_eeprom_readw(iobase, type, addr + 10);
+ devpriv->s_EeParameters.i_NbrAiChannel = (tmp >> 4) & 0x3ff;
+ if (!strcmp(this_board->pc_DriverName, "apci3200"))
+ devpriv->s_EeParameters.i_NbrAiChannel *= 4;
+
+ tmp = addi_eeprom_readw(iobase, type, addr + 16);
+ devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = tmp * 1000;
+
+ tmp = addi_eeprom_readw(iobase, type, addr + 30);
+ devpriv->s_EeParameters.ui_MinDelaytimeNs = tmp * 1000;
+
+ tmp = addi_eeprom_readw(iobase, type, addr + 20);
+ devpriv->s_EeParameters.i_Dma = (tmp >> 13) & 0x01;
+
+ tmp = addi_eeprom_readw(iobase, type, addr + 72) & 0xff;
+ if (tmp) { /* > 0 */
+ /* offset of first analog input single header */
+ offset = 74 + (2 * tmp) + (10 * (1 + (tmp / 16)));
+ } else { /* = 0 */
+ offset = 74;
+ }
+ /* Resolution */
+ tmp = addi_eeprom_readw(iobase, type, addr + offset + 2) & 0x1f;
+ devpriv->s_EeParameters.i_AiMaxdata = 0xffff >> (16 - tmp);
}
- /******************************************/
- /* EEPROM HEADER READ FUNCTIONS */
- /******************************************/
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, |
-| char * pc_PCIChipInformation,struct comedi_device *dev) |
-+----------------------------------------------------------------------------+
-| Task : Read from eeprom Main Header |
-+----------------------------------------------------------------------------+
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address |
-| |
-| char *pc_PCIChipInformation : PCI Chip Type. |
-| |
-| struct comedi_device *dev : comedi device structure |
-| pointer |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-+----------------------------------------------------------------------------+
-*/
-
-int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, struct comedi_device *dev)
+static void addi_eeprom_read_info(struct comedi_device *dev,
+ unsigned long iobase)
{
- unsigned short w_Temp, i, w_Count = 0;
- unsigned int ui_Temp;
- struct str_MainHeader s_MainHeader;
- struct str_DigitalInputHeader s_DigitalInputHeader;
- struct str_DigitalOutputHeader s_DigitalOutputHeader;
- /* struct str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader; */
- struct str_AnalogOutputHeader s_AnalogOutputHeader;
- struct str_AnalogInputHeader s_AnalogInputHeader;
-
- /* Read size */
- s_MainHeader.w_HeaderSize =
- w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
- 0x100 + 8);
-
- /* Read nbr of functionality */
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + 10);
- s_MainHeader.b_Nfunctions = (unsigned char) w_Temp & 0x00FF;
+ const struct addi_board *this_board = comedi_board(dev);
+ char *type = this_board->pc_EepromChip;
+ unsigned short size;
+ unsigned char nfuncs;
+ int i;
+
+ size = addi_eeprom_readw(iobase, type, 8);
+ nfuncs = addi_eeprom_readw(iobase, type, 10) & 0xff;
/* Read functionality details */
- for (i = 0; i < s_MainHeader.b_Nfunctions; i++) {
- /* Read Type */
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + 12 + w_Count);
- s_MainHeader.s_Functions[i].b_Type = (unsigned char) w_Temp & 0x3F;
- w_Count = w_Count + 2;
- /* Read Address */
- s_MainHeader.s_Functions[i].w_Address =
- w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + 12 + w_Count);
- w_Count = w_Count + 2;
- }
+ for (i = 0; i < nfuncs; i++) {
+ unsigned short offset = i * 4;
+ unsigned short addr;
+ unsigned char func;
- /* Display main header info */
- for (i = 0; i < s_MainHeader.b_Nfunctions; i++) {
+ func = addi_eeprom_readw(iobase, type, 12 + offset) & 0x3f;
+ addr = addi_eeprom_readw(iobase, type, 14 + offset);
- switch (s_MainHeader.s_Functions[i].b_Type) {
+ switch (func) {
case EEPROM_DIGITALINPUT:
- i_EepromReadDigitalInputHeader(w_PCIBoardEepromAddress,
- pc_PCIChipInformation,
- s_MainHeader.s_Functions[i].w_Address,
- &s_DigitalInputHeader);
- devpriv->s_EeParameters.i_NbrDiChannel =
- s_DigitalInputHeader.w_Nchannel;
+ addi_eeprom_read_di_info(dev, iobase, addr);
break;
case EEPROM_DIGITALOUTPUT:
- i_EepromReadDigitalOutputHeader(w_PCIBoardEepromAddress,
- pc_PCIChipInformation,
- s_MainHeader.s_Functions[i].w_Address,
- &s_DigitalOutputHeader);
- devpriv->s_EeParameters.i_NbrDoChannel =
- s_DigitalOutputHeader.w_Nchannel;
- ui_Temp = 0xffffffff;
- devpriv->s_EeParameters.i_DoMaxdata =
- ui_Temp >> (32 -
- devpriv->s_EeParameters.i_NbrDoChannel);
+ addi_eeprom_read_do_info(dev, iobase, addr);
break;
case EEPROM_ANALOGINPUT:
- i_EepromReadAnlogInputHeader(w_PCIBoardEepromAddress,
- pc_PCIChipInformation,
- s_MainHeader.s_Functions[i].w_Address,
- &s_AnalogInputHeader);
- if (!(strcmp(this_board->pc_DriverName, "apci3200")))
- devpriv->s_EeParameters.i_NbrAiChannel =
- s_AnalogInputHeader.w_Nchannel * 4;
- else
- devpriv->s_EeParameters.i_NbrAiChannel =
- s_AnalogInputHeader.w_Nchannel;
- devpriv->s_EeParameters.i_Dma =
- s_AnalogInputHeader.b_HasDma;
- devpriv->s_EeParameters.ui_MinAcquisitiontimeNs =
- (unsigned int) s_AnalogInputHeader.w_MinConvertTiming *
- 1000;
- devpriv->s_EeParameters.ui_MinDelaytimeNs =
- (unsigned int) s_AnalogInputHeader.w_MinDelayTiming *
- 1000;
- ui_Temp = 0xffff;
- devpriv->s_EeParameters.i_AiMaxdata =
- ui_Temp >> (16 -
- s_AnalogInputHeader.b_Resolution);
+ addi_eeprom_read_ai_info(dev, iobase, addr);
break;
case EEPROM_ANALOGOUTPUT:
- i_EepromReadAnlogOutputHeader(w_PCIBoardEepromAddress,
- pc_PCIChipInformation,
- s_MainHeader.s_Functions[i].w_Address,
- &s_AnalogOutputHeader);
- devpriv->s_EeParameters.i_NbrAoChannel =
- s_AnalogOutputHeader.w_Nchannel;
- ui_Temp = 0xffff;
- devpriv->s_EeParameters.i_AoMaxdata =
- ui_Temp >> (16 -
- s_AnalogOutputHeader.b_Resolution);
+ addi_eeprom_read_ao_info(dev, iobase, addr);
break;
case EEPROM_TIMER:
- /* Timer subdevice present */
- devpriv->s_EeParameters.i_Timer = 1;
- break;
-
case EEPROM_WATCHDOG:
- /* Timer subdevice present */
- devpriv->s_EeParameters.i_Timer = 1;
- break;
-
case EEPROM_TIMER_WATCHDOG_COUNTER:
- /* Timer subdevice present */
- devpriv->s_EeParameters.i_Timer = 1;
+ addi_eeprom_read_timer_info(dev, iobase, addr);
break;
}
}
-
- return 0;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_EepromReadDigitalInputHeader(unsigned short |
-| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
-| unsigned short w_Address,struct str_DigitalInputHeader *s_Header) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Read Digital Input Header |
-+----------------------------------------------------------------------------+
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address |
-| |
-| char *pc_PCIChipInformation : PCI Chip Type. |
-| |
-| struct str_DigitalInputHeader *s_Header: Digita Input Header |
-| Pointer |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-+----------------------------------------------------------------------------+
-*/
-int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_DigitalInputHeader *s_Header)
-{
- unsigned short w_Temp;
-
- /* read nbr of channels */
- s_Header->w_Nchannel =
- w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
- 0x100 + w_Address + 6);
-
- /* interruptible or not */
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + w_Address + 8);
- s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01;
-
-/* How many interruptible logic */
- s_Header->w_NinterruptLogic =
- w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
- 0x100 + w_Address + 10);
-
- return 0;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_EepromReadDigitalOutputHeader(unsigned short |
-| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
-| unsigned short w_Address,struct str_DigitalOutputHeader *s_Header) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Read Digital Output Header |
-+----------------------------------------------------------------------------+
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address |
-| |
-| char *pc_PCIChipInformation : PCI Chip Type. |
-| |
-| struct str_DigitalOutputHeader *s_Header: Digital Output Header|
-| Pointer |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-+----------------------------------------------------------------------------+
-*/
-int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_DigitalOutputHeader *s_Header)
-{
-/* Read Nbr channels */
- s_Header->w_Nchannel =
- w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
- 0x100 + w_Address + 6);
- return 0;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, |
-| char *pc_PCIChipInformation,WORD w_Address, |
-| struct str_TimerMainHeader *s_Header) |
-+----------------------------------------------------------------------------+
-| Task : Read Timer or Watchdog Header |
-+----------------------------------------------------------------------------+
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address |
-| |
-| char *pc_PCIChipInformation : PCI Chip Type. |
-| |
-| struct str_TimerMainHeader *s_Header: Timer Header |
-| Pointer |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-+----------------------------------------------------------------------------+
-*/
-int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_TimerMainHeader *s_Header)
-{
-
- unsigned short i, w_Size = 0, w_Temp;
-
-/* Read No of Timer */
- s_Header->w_Ntimer =
- w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
- 0x100 + w_Address + 6);
-/* Read header size */
-
- for (i = 0; i < s_Header->w_Ntimer; i++) {
- s_Header->s_TimerDetails[i].w_HeaderSize =
- w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation,
- 0x100 + w_Address + 8 + w_Size + 0);
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation,
- 0x100 + w_Address + 8 + w_Size + 2);
-
- /* Read Resolution */
- s_Header->s_TimerDetails[i].b_Resolution =
- (unsigned char) (w_Temp >> 10) & 0x3F;
-
- /* Read Mode */
- s_Header->s_TimerDetails[i].b_Mode =
- (unsigned char) (w_Temp >> 4) & 0x3F;
-
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation,
- 0x100 + w_Address + 8 + w_Size + 4);
-
- /* Read MinTiming */
- s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF;
-
- /* Read Timebase */
- s_Header->s_TimerDetails[i].b_TimeBase = (unsigned char) (w_Temp) & 0x3F;
- w_Size += s_Header->s_TimerDetails[i].w_HeaderSize;
- }
-
- return 0;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_EepromReadAnlogOutputHeader(unsigned short |
-| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
-| unsigned short w_Address,str_AnalogOutputHeader *s_Header) |
-+----------------------------------------------------------------------------+
-| Task : Read Nalog Output Header |
-+----------------------------------------------------------------------------+
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address |
-| |
-| char *pc_PCIChipInformation : PCI Chip Type. |
-| |
-| str_AnalogOutputHeader *s_Header:Anlog Output Header |
-| Pointer |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-+----------------------------------------------------------------------------+
-*/
-
-int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_AnalogOutputHeader *s_Header)
-{
- unsigned short w_Temp;
- /* No of channels for 1st hard component */
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + w_Address + 10);
- s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF;
- /* Resolution for 1st hard component */
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + w_Address + 16);
- s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF;
- return 0;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_EepromReadAnlogInputHeader(unsigned short |
-| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
-| unsigned short w_Address,struct str_AnalogInputHeader *s_Header) |
-+----------------------------------------------------------------------------+
-| Task : Read Nalog Output Header |
-+----------------------------------------------------------------------------+
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address |
-| |
-| char *pc_PCIChipInformation : PCI Chip Type. |
-| |
-| struct str_AnalogInputHeader *s_Header:Anlog Input Header |
-| Pointer |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-+----------------------------------------------------------------------------+
-*/
-
-/* Reads only for ONE hardware component */
-int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_AnalogInputHeader *s_Header)
-{
- unsigned short w_Temp, w_Offset;
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + w_Address + 10);
- s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF;
- s_Header->w_MinConvertTiming =
- w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
- 0x100 + w_Address + 16);
- s_Header->w_MinDelayTiming =
- w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
- 0x100 + w_Address + 30);
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + w_Address + 20);
- s_Header->b_HasDma = (w_Temp >> 13) & 0x01; /* whether dma present or not */
-
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 72); /* reading Y */
- w_Temp = w_Temp & 0x00FF;
- if (w_Temp) /* Y>0 */
- {
- w_Offset = 74 + (2 * w_Temp) + (10 * (1 + (w_Temp / 16))); /* offset of first analog input single header */
- w_Offset = w_Offset + 2; /* resolution */
- } else /* Y=0 */
- {
- w_Offset = 74;
- w_Offset = w_Offset + 2; /* resolution */
- }
-
-/* read Resolution */
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + w_Address + w_Offset);
- s_Header->b_Resolution = w_Temp & 0x001F; /* last 5 bits */
-
- return 0;
}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
index f9a8937be8e..b05f8505c89 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
@@ -44,7 +44,35 @@ You should also find the complete GPL in the COPYING file accompanying this sour
| | | |
+----------+-----------+------------------------------------------------+
*/
-#include "hwdrv_APCI1710.h"
+
+#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
+#define COMEDI_SUBD_PWM 12 /* Pulse width Measurement */
+#define COMEDI_SUBD_SSI 13 /* Synchronous serial interface */
+#define COMEDI_SUBD_TOR 14 /* Tor counter */
+#define COMEDI_SUBD_CHRONO 15 /* Chrono meter */
+#define COMEDI_SUBD_PULSEENCODER 16 /* Pulse Encoder INP CPT */
+#define COMEDI_SUBD_INCREMENTALCOUNTER 17 /* Incremental Counter */
+
+#define APCI1710_BOARD_NAME "apci1710"
+#define APCI1710_BOARD_DEVICE_ID 0x818F
+#define APCI1710_ADDRESS_RANGE 256
+#define APCI1710_CONFIG_ADDRESS_RANGE 8
+#define APCI1710_INCREMENTAL_COUNTER 0x53430000UL
+#define APCI1710_SSI_COUNTER 0x53490000UL
+#define APCI1710_TTL_IO 0x544C0000UL
+#define APCI1710_DIGITAL_IO 0x44490000UL
+#define APCI1710_82X54_TIMER 0x49430000UL
+#define APCI1710_CHRONOMETER 0x43480000UL
+#define APCI1710_PULSE_ENCODER 0x495A0000UL
+#define APCI1710_TOR_COUNTER 0x544F0000UL
+#define APCI1710_PWM 0x50570000UL
+#define APCI1710_ETM 0x45540000UL
+#define APCI1710_CDA 0x43440000UL
+#define APCI1710_DISABLE 0
+#define APCI1710_ENABLE 1
+#define APCI1710_SYNCHRONOUS_MODE 1
+#define APCI1710_ASYNCHRONOUS_MODE 0
+
#include "APCI1710_Inp_cpt.c"
#include "APCI1710_Ssi.c"
@@ -56,7 +84,34 @@ You should also find the complete GPL in the COPYING file accompanying this sour
#include "APCI1710_Pwm.c"
#include "APCI1710_INCCPT.c"
-void i_ADDI_AttachPCI1710(struct comedi_device *dev)
+static const struct comedi_lrange range_apci1710_ttl = {
+ 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1)
+ }
+};
+
+static const struct comedi_lrange range_apci1710_ssi = {
+ 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1)
+ }
+};
+
+static const struct comedi_lrange range_apci1710_inccpt = {
+ 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1)
+ }
+};
+
+static void i_ADDI_AttachPCI1710(struct comedi_device *dev)
{
struct comedi_subdevice *s;
int ret = 0;
@@ -195,12 +250,9 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev)
s->insn_bits = i_APCI1710_InsnBitsINCCPT;
}
-int i_APCI1710_Reset(struct comedi_device *dev);
-void v_APCI1710_Interrupt(int irq, void *d);
-/* for 1710 */
-
-int i_APCI1710_Reset(struct comedi_device *dev)
+static int i_APCI1710_Reset(struct comedi_device *dev)
{
+ struct addi_private *devpriv = dev->private;
int ret;
unsigned int dw_Dummy;
@@ -247,9 +299,10 @@ int i_APCI1710_Reset(struct comedi_device *dev)
+----------------------------------------------------------------------------+
*/
-void v_APCI1710_Interrupt(int irq, void *d)
+static void v_APCI1710_Interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct addi_private *devpriv = dev->private;
unsigned char b_ModuleCpt = 0;
unsigned char b_InterruptFlag = 0;
unsigned char b_PWMCpt = 0;
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h
deleted file mode 100644
index 89c99eb5228..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
-#define COMEDI_SUBD_PWM 12 /* Pulse width Measurement */
-#define COMEDI_SUBD_SSI 13 /* Synchronous serial interface */
-#define COMEDI_SUBD_TOR 14 /* Tor counter */
-#define COMEDI_SUBD_CHRONO 15 /* Chrono meter */
-#define COMEDI_SUBD_PULSEENCODER 16 /* Pulse Encoder INP CPT */
-#define COMEDI_SUBD_INCREMENTALCOUNTER 17 /* Incremental Counter */
-
-#define APCI1710_BOARD_NAME "apci1710"
-#define APCI1710_BOARD_VENDOR_ID 0x10E8
-#define APCI1710_BOARD_DEVICE_ID 0x818F
-#define APCI1710_ADDRESS_RANGE 256
-#define APCI1710_CONFIG_ADDRESS_RANGE 8
-#define APCI1710_INCREMENTAL_COUNTER 0x53430000UL
-#define APCI1710_SSI_COUNTER 0x53490000UL
-#define APCI1710_TTL_IO 0x544C0000UL
-#define APCI1710_DIGITAL_IO 0x44490000UL
-#define APCI1710_82X54_TIMER 0x49430000UL
-#define APCI1710_CHRONOMETER 0x43480000UL
-#define APCI1710_PULSE_ENCODER 0x495A0000UL
-#define APCI1710_TOR_COUNTER 0x544F0000UL
-#define APCI1710_PWM 0x50570000UL
-#define APCI1710_ETM 0x45540000UL
-#define APCI1710_CDA 0x43440000UL
-#define APCI1710_DISABLE 0
-#define APCI1710_ENABLE 1
-#define APCI1710_SYNCHRONOUS_MODE 1
-#define APCI1710_ASYNCHRONOUS_MODE 0
-
-/* MODULE INFO STRUCTURE */
-
-static const struct comedi_lrange range_apci1710_ttl = { 4, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1)
- }
-};
-
-static const struct comedi_lrange range_apci1710_ssi = { 4, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1)
- }
-};
-
-static const struct comedi_lrange range_apci1710_inccpt = { 4, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1)
- }
-};
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
index 5997b2f504a..3d66e48e0cf 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
@@ -46,12 +46,70 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+----------+-----------+------------------------------------------------+
*/
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
-#include "hwdrv_apci035.h"
+/* Card Specific information */
+#define APCI035_ADDRESS_RANGE 255
+
+/* Timer / Watchdog Related Defines */
+#define APCI035_TCW_SYNC_ENABLEDISABLE 0
+#define APCI035_TCW_RELOAD_VALUE 4
+#define APCI035_TCW_TIMEBASE 8
+#define APCI035_TCW_PROG 12
+#define APCI035_TCW_TRIG_STATUS 16
+#define APCI035_TCW_IRQ 20
+#define APCI035_TCW_WARN_TIMEVAL 24
+#define APCI035_TCW_WARN_TIMEBASE 28
+
+#define ADDIDATA_TIMER 0
+/* #define ADDIDATA_WATCHDOG 1 */
+
+#define APCI035_TW1 0
+#define APCI035_TW2 32
+#define APCI035_TW3 64
+#define APCI035_TW4 96
+
+#define APCI035_AI_OFFSET 0
+#define APCI035_TEMP 128
+#define APCI035_ALR_SEQ 4
+#define APCI035_START_STOP_INDEX 8
+#define APCI035_ALR_START_STOP 12
+#define APCI035_ALR_IRQ 16
+#define APCI035_EOS 20
+#define APCI035_CHAN_NO 24
+#define APCI035_CHAN_VAL 28
+#define APCI035_CONV_TIME_TIME_BASE 36
+#define APCI035_RELOAD_CONV_TIME_VAL 32
+#define APCI035_DELAY_TIME_TIME_BASE 44
+#define APCI035_RELOAD_DELAY_TIME_VAL 40
+#define ENABLE_EXT_TRIG 1
+#define ENABLE_EXT_GATE 2
+#define ENABLE_EXT_TRIG_GATE 3
+
+#define ANALOG_INPUT 0
+#define TEMPERATURE 1
+#define RESISTANCE 2
+
+#define ADDIDATA_GREATER_THAN_TEST 0
+#define ADDIDATA_LESS_THAN_TEST 1
+
+#define APCI035_MAXVOLT 2.5
+
+#define ADDIDATA_UNIPOLAR 1
+#define ADDIDATA_BIPOLAR 2
+
+/* ANALOG INPUT RANGE */
+static struct comedi_lrange range_apci035_ai = {
+ 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
static int i_WatchdogNbr = 0;
static int i_Temp = 0;
static int i_Flag = 1;
@@ -109,12 +167,16 @@ static int i_Flag = 1;
| |
+----------------------------------------------------------------------------+
*/
-int i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ui_Status = 0;
unsigned int ui_Command = 0;
unsigned int ui_Mode = 0;
+
i_Temp = 0;
devpriv->tsk_Current = current;
devpriv->b_TimerSelectMode = data[0];
@@ -278,11 +340,15 @@ int i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subde
| |
+----------------------------------------------------------------------------+
*/
-int i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ui_Command = 0;
int i_Count = 0;
+
if (data[0] == 1) {
ui_Command =
inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
@@ -393,10 +459,14 @@ int i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev,
| |
+----------------------------------------------------------------------------+
*/
-int i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI035_ReadTimerWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ui_Status = 0; /* Status register */
+
i_WatchdogNbr = insn->unused[0];
/******************/
@@ -453,9 +523,13 @@ int i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevi
| |
+----------------------------------------------------------------------------+
*/
-int i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI035_ConfigAnalogInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
+
devpriv->tsk_Current = current;
outl(0x200 | 0, devpriv->iobase + 128 + 0x4);
outl(0, devpriv->iobase + 128 + 0);
@@ -490,10 +564,14 @@ int i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevi
| |
+----------------------------------------------------------------------------+
*/
-int i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI035_ReadAnalogInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ui_CommandRegister = 0;
+
/******************/
/* Set the start */
/******************/
@@ -525,9 +603,11 @@ int i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice
| |
+----------------------------------------------------------------------------+
*/
-int i_APCI035_Reset(struct comedi_device *dev)
+static int i_APCI035_Reset(struct comedi_device *dev)
{
+ struct addi_private *devpriv = dev->private;
int i_Count = 0;
+
for (i_Count = 1; i_Count <= 4; i_Count++) {
i_WatchdogNbr = i_Count;
outl(0x0, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0); /* stop all timers */
@@ -557,11 +637,13 @@ int i_APCI035_Reset(struct comedi_device *dev)
static void v_APCI035_Interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct addi_private *devpriv = dev->private;
unsigned int ui_StatusRegister1 = 0;
unsigned int ui_StatusRegister2 = 0;
unsigned int ui_ReadCommand = 0;
unsigned int ui_ChannelNumber = 0;
unsigned int ui_DigitalTemperature = 0;
+
if (i_Temp == 1) {
i_WatchdogNbr = i_Flag;
i_Flag = i_Flag + 1;
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h
deleted file mode 100644
index 3c700c7bf81..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-/* Card Specific information */
-#define APCI035_BOARD_VENDOR_ID 0x15B8
-#define APCI035_ADDRESS_RANGE 255
-
-/* ANALOG INPUT RANGE */
-static struct comedi_lrange range_apci035_ai = { 8, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2),
- UNI_RANGE(1)
- }
-};
-
-/* Timer / Watchdog Related Defines */
-#define APCI035_TCW_SYNC_ENABLEDISABLE 0
-#define APCI035_TCW_RELOAD_VALUE 4
-#define APCI035_TCW_TIMEBASE 8
-#define APCI035_TCW_PROG 12
-#define APCI035_TCW_TRIG_STATUS 16
-#define APCI035_TCW_IRQ 20
-#define APCI035_TCW_WARN_TIMEVAL 24
-#define APCI035_TCW_WARN_TIMEBASE 28
-
-#define ADDIDATA_TIMER 0
-/* #define ADDIDATA_WATCHDOG 1 */
-
-#define APCI035_TW1 0
-#define APCI035_TW2 32
-#define APCI035_TW3 64
-#define APCI035_TW4 96
-
-#define APCI035_AI_OFFSET 0
-#define APCI035_TEMP 128
-#define APCI035_ALR_SEQ 4
-#define APCI035_START_STOP_INDEX 8
-#define APCI035_ALR_START_STOP 12
-#define APCI035_ALR_IRQ 16
-#define APCI035_EOS 20
-#define APCI035_CHAN_NO 24
-#define APCI035_CHAN_VAL 28
-#define APCI035_CONV_TIME_TIME_BASE 36
-#define APCI035_RELOAD_CONV_TIME_VAL 32
-#define APCI035_DELAY_TIME_TIME_BASE 44
-#define APCI035_RELOAD_DELAY_TIME_VAL 40
-#define ENABLE_EXT_TRIG 1
-#define ENABLE_EXT_GATE 2
-#define ENABLE_EXT_TRIG_GATE 3
-
-#define ANALOG_INPUT 0
-#define TEMPERATURE 1
-#define RESISTANCE 2
-
-#define ADDIDATA_GREATER_THAN_TEST 0
-#define ADDIDATA_LESS_THAN_TEST 1
-
-#define APCI035_MAXVOLT 2.5
-
-#define ADDIDATA_UNIPOLAR 1
-#define ADDIDATA_BIPOLAR 2
-
-/* ADDIDATA Enable Disable */
-#define ADDIDATA_ENABLE 1
-#define ADDIDATA_DISABLE 0
-
-/* Hardware Layer functions for Apci035 */
-
-/* TIMER */
-/* timer value is passed as u seconds */
-int i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* Temperature Related Defines (Analog Input Subdevice) */
-
-int i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* Interrupt */
-static void v_APCI035_Interrupt(int irq, void *d);
-
-/* Reset functions */
-int i_APCI035_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
deleted file mode 100644
index bab7b61a53b..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/**
-@verbatim
-
-Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
-
- ADDI-DATA GmbH
- Dieselstrasse 3
- D-77833 Ottersweier
- Tel: +19(0)7223/9493-0
- Fax: +49(0)7223/9493-92
- http://www.addi-data.com
- info@addi-data.com
-
-This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
-@endverbatim
-*/
-/*
-
- +-----------------------------------------------------------------------+
- | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
- +-----------------------------------------------------------------------+
- | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
- | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
- +-------------------------------+---------------------------------------+
- | Project : APCI-1032 | Compiler : GCC |
- | Module name : hwdrv_apci1032.c| Version : 2.96 |
- +-------------------------------+---------------------------------------+
- | Project manager: Eric Stolz | Date : 02/12/2002 |
- +-------------------------------+---------------------------------------+
- | Description : Hardware Layer Access For APCI-1032 |
- +-----------------------------------------------------------------------+
- | UPDATES |
- +----------+-----------+------------------------------------------------+
- | Date | Author | Description of updates |
- +----------+-----------+------------------------------------------------+
- | | | |
- | | | |
- | | | |
- +----------+-----------+------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
-#include "hwdrv_apci1032.h"
-#include <linux/delay.h>
-
-static unsigned int ui_InterruptStatus;
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1032_ConfigDigitalInput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Configures the digital input Subdevice |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int *data : Data Pointer contains |
-| configuration parameters as below |
-| |
-| data[0] : 1 Enable Digital Input Interrupt |
-| 0 Disable Digital Input Interrupt |
-| data[1] : 0 ADDIDATA Interrupt OR LOGIC |
-| : 1 ADDIDATA Interrupt AND LOGIC |
-| data[2] : Interrupt mask for the mode 1 |
-| data[3] : Interrupt mask for the mode 2 |
-| |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_TmpValue;
-
- unsigned int ul_Command1 = 0;
- unsigned int ul_Command2 = 0;
- devpriv->tsk_Current = current;
-
- /*******************************/
- /* Set the digital input logic */
- /*******************************/
- if (data[0] == ADDIDATA_ENABLE) {
- ul_Command1 = ul_Command1 | data[2];
- ul_Command2 = ul_Command2 | data[3];
- outl(ul_Command1,
- devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
- outl(ul_Command2,
- devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
- if (data[1] == ADDIDATA_OR) {
- outl(0x4, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
- ui_TmpValue =
- inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
- } /* if (data[1] == ADDIDATA_OR) */
- else
- outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
- /* else if(data[1] == ADDIDATA_OR) */
- } /* if( data[0] == ADDIDATA_ENABLE) */
- else {
- ul_Command1 = ul_Command1 & 0xFFFF0000;
- ul_Command2 = ul_Command2 & 0xFFFF0000;
- outl(ul_Command1,
- devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
- outl(ul_Command2,
- devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
- outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
- } /* else if ( data[0] == ADDIDATA_ENABLE) */
-
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1032_Read1DigitalInput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Return the status of the digital input |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int ui_Channel : Channel number to read |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_TmpValue = 0;
- unsigned int ui_Channel;
- ui_Channel = CR_CHAN(insn->chanspec);
- if (ui_Channel <= 31) {
- ui_TmpValue = (unsigned int) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
-/*
-* since only 1 channel reqd to bring it to last bit it is rotated 8
-* +(chan - 1) times then ANDed with 1 for last bit.
-*/
- *data = (ui_TmpValue >> ui_Channel) & 0x1;
- } /* if(ui_Channel >= 0 && ui_Channel <=31) */
- else {
- /* comedi_error(dev," \n chan spec wrong\n"); */
- return -EINVAL; /* "sorry channel spec wrong " */
- } /* else if(ui_Channel >= 0 && ui_Channel <=31) */
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1032_ReadMoreDigitalInput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Return the status of the Requested digital inputs |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int ui_NoOfChannels : No Of Channels To be Read |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_PortValue = data[0];
- unsigned int ui_Mask = 0;
- unsigned int ui_NoOfChannels;
-
- ui_NoOfChannels = CR_CHAN(insn->chanspec);
- if (data[1] == 0) {
- *data = (unsigned int) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
- switch (ui_NoOfChannels) {
- case 2:
- ui_Mask = 3;
- *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
- break;
- case 4:
- ui_Mask = 15;
- *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
- break;
- case 8:
- ui_Mask = 255;
- *data = (*data >> (8 * ui_PortValue)) & ui_Mask;
- break;
- case 16:
- ui_Mask = 65535;
- *data = (*data >> (16 * ui_PortValue)) & ui_Mask;
- break;
- case 31:
- break;
- default:
- /* comedi_error(dev," \nchan spec wrong\n"); */
- return -EINVAL; /* "sorry channel spec wrong " */
- break;
- } /* switch(ui_NoOfChannels) */
- } /* if(data[1]==0) */
- else {
- if (data[1] == 1)
- *data = ui_InterruptStatus;
- /* if(data[1]==1) */
- } /* else if(data[1]==0) */
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : static void v_APCI1032_Interrupt |
-| (int irq , void *d) |
-+----------------------------------------------------------------------------+
-| Task : Interrupt handler for the interruptible digital inputs |
-+----------------------------------------------------------------------------+
-| Input Parameters : int irq : irq number |
-| void *d : void pointer |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-static void v_APCI1032_Interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
-
- unsigned int ui_Temp;
- /* disable the interrupt */
- ui_Temp = inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
- outl(ui_Temp & APCI1032_DIGITAL_IP_INTERRUPT_DISABLE,
- devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
- ui_InterruptStatus =
- inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS);
- ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF;
- send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */
- outl(ui_Temp, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); /* enable the interrupt */
- return;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1032_Reset(struct comedi_device *dev) | |
-+----------------------------------------------------------------------------+
-| Task :resets all the registers |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI1032_Reset(struct comedi_device *dev)
-{
- outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); /* disable the interrupts */
- inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); /* Reset the interrupt status register */
- outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); /* Disable the and/or interrupt */
- outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
- return 0;
-}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h
deleted file mode 100644
index 7114acb4bd2..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-/********* Definitions for APCI-1032 card *****/
-
-#define APCI1032_BOARD_VENDOR_ID 0x15B8
-#define APCI1032_ADDRESS_RANGE 20
-/* DIGITAL INPUT DEFINE */
-
-#define APCI1032_DIGITAL_IP 0
-#define APCI1032_DIGITAL_IP_INTERRUPT_MODE1 4
-#define APCI1032_DIGITAL_IP_INTERRUPT_MODE2 8
-#define APCI1032_DIGITAL_IP_IRQ 16
-
-/* Digital Input IRQ Function Selection */
-#define ADDIDATA_OR 0
-#define ADDIDATA_AND 1
-
-/* Digital Input Interrupt Status */
-#define APCI1032_DIGITAL_IP_INTERRUPT_STATUS 12
-
-/* Digital Input Interrupt Enable Disable. */
-#define APCI1032_DIGITAL_IP_INTERRUPT_ENABLE 0x4
-#define APCI1032_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB
-
-/* ADDIDATA Enable Disable */
-
-#define ADDIDATA_ENABLE 1
-#define ADDIDATA_DISABLE 0
-
-/* Hardware Layer functions for Apci1032 */
-
-/*
-* DI for di read
-*/
-
-int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* Interrupt functions..... */
-
-static void v_APCI1032_Interrupt(int irq, void *d);
-/* Reset */
-int i_APCI1032_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
index 62f421a06f0..24c4c983db3 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
@@ -45,7 +45,105 @@ You should also find the complete GPL in the COPYING file accompanying this sour
| | | |
+----------+-----------+------------------------------------------------+
*/
-#include "hwdrv_apci1500.h"
+
+/********* Definitions for APCI-1500 card *****/
+
+/* Card Specific information */
+#define APCI1500_ADDRESS_RANGE 4
+
+/* DIGITAL INPUT-OUTPUT DEFINE */
+
+#define APCI1500_DIGITAL_OP 2
+#define APCI1500_DIGITAL_IP 0
+#define APCI1500_AND 2
+#define APCI1500_OR 4
+#define APCI1500_OR_PRIORITY 6
+#define APCI1500_CLK_SELECT 0
+#define COUNTER1 0
+#define COUNTER2 1
+#define COUNTER3 2
+#define APCI1500_COUNTER 0x20
+#define APCI1500_TIMER 0
+#define APCI1500_WATCHDOG 0
+#define APCI1500_SINGLE 0
+#define APCI1500_CONTINUOUS 0x80
+#define APCI1500_DISABLE 0
+#define APCI1500_ENABLE 1
+#define APCI1500_SOFTWARE_TRIGGER 0x4
+#define APCI1500_HARDWARE_TRIGGER 0x10
+#define APCI1500_SOFTWARE_GATE 0
+#define APCI1500_HARDWARE_GATE 0x8
+#define START 0
+#define STOP 1
+#define TRIGGER 2
+
+/*
+ * Zillog I/O enumeration
+ */
+enum {
+ APCI1500_Z8536_PORT_C,
+ APCI1500_Z8536_PORT_B,
+ APCI1500_Z8536_PORT_A,
+ APCI1500_Z8536_CONTROL_REGISTER
+};
+
+/*
+ * Z8536 CIO Internal Address
+ */
+enum {
+ APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
+ APCI1500_RW_PORT_B_INTERRUPT_CONTROL,
+ APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR,
+ APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
+ APCI1500_RW_PORT_C_DATA_DIRECTION,
+ APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
+
+ APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ APCI1500_RW_PORT_A_DATA,
+ APCI1500_RW_PORT_B_DATA,
+ APCI1500_RW_PORT_C_DATA,
+
+ APCI1500_R_CPT_TMR1_VALUE_HIGH,
+ APCI1500_R_CPT_TMR1_VALUE_LOW,
+ APCI1500_R_CPT_TMR2_VALUE_HIGH,
+ APCI1500_R_CPT_TMR2_VALUE_LOW,
+ APCI1500_R_CPT_TMR3_VALUE_HIGH,
+ APCI1500_R_CPT_TMR3_VALUE_LOW,
+ APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
+ APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
+ APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
+ APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
+ APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
+ APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
+ APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
+ APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
+ APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
+ APCI1500_R_CURRENT_VECTOR,
+
+ APCI1500_RW_PORT_A_SPECIFICATION,
+ APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
+ APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
+ APCI1500_RW_PORT_A_DATA_DIRECTION,
+ APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL,
+ APCI1500_RW_PORT_A_PATTERN_POLARITY,
+ APCI1500_RW_PORT_A_PATTERN_TRANSITION,
+ APCI1500_RW_PORT_A_PATTERN_MASK,
+
+ APCI1500_RW_PORT_B_SPECIFICATION,
+ APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
+ APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
+ APCI1500_RW_PORT_B_DATA_DIRECTION,
+ APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL,
+ APCI1500_RW_PORT_B_PATTERN_POLARITY,
+ APCI1500_RW_PORT_B_PATTERN_TRANSITION,
+ APCI1500_RW_PORT_B_PATTERN_MASK
+};
static int i_TimerCounter1Init = 0;
static int i_TimerCounter2Init = 0;
@@ -141,6 +239,7 @@ static int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0;
int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0;
int i_PatternTransitionCount = 0, i_RegValue;
@@ -525,8 +624,10 @@ static int i_APCI1500_StartStopInputEvent(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_Event1InterruptStatus = 0, i_Event2InterruptStatus =
0, i_RegValue;
+
switch (data[0]) {
case START:
/*************************/
@@ -792,7 +893,9 @@ static int i_APCI1500_Initialisation(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_DummyRead = 0;
+
/******************/
/* Software reset */
/******************/
@@ -939,82 +1042,15 @@ static int i_APCI1500_Initialisation(struct comedi_device *dev,
return insn->n;
}
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1500_ReadMoreDigitalInput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Return the status of the Requested digital inputs |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int ui_NoOfChannels : No Of Channels To be Read |
-| unsigned int *data : Data Pointer
-| data[0] : 0 Read a single channel
-| 1 read a port value
-| data[1] : port value
-+----------------------------------------------------------------------------+
-| Output Parameters : -- data[0] :The read status value
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
+static int apci1500_di_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned int ui_PortValue = data[1];
- unsigned int ui_Mask = 0;
- unsigned int ui_Channel;
- unsigned int ui_TmpValue = 0;
- ui_Channel = CR_CHAN(insn->chanspec);
+ struct addi_private *devpriv = dev->private;
- switch (data[0]) {
- case 0:
- if (ui_Channel <= 15) {
- ui_TmpValue =
- (unsigned int) inw(devpriv->i_IobaseAddon +
- APCI1500_DIGITAL_IP);
- *data = (ui_TmpValue >> ui_Channel) & 0x1;
- } /* if(ui_Channel >= 0 && ui_Channel <=15) */
- else {
- printk("\nThe channel specification are in error\n");
- return -EINVAL; /* "sorry channel spec wrong " */
- } /* else if(ui_Channel >= 0 && ui_Channel <=15) */
- break;
- case 1:
+ data[1] = inw(devpriv->i_IobaseAddon + APCI1500_DIGITAL_IP);
- *data = (unsigned int) inw(devpriv->i_IobaseAddon +
- APCI1500_DIGITAL_IP);
- switch (ui_Channel) {
- case 2:
- ui_Mask = 3;
- *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
- break;
- case 4:
- ui_Mask = 15;
- *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
- break;
- case 8:
- ui_Mask = 255;
- *data = (*data >> (8 * ui_PortValue)) & ui_Mask;
- break;
- case 15:
- break;
-
- default:
- printk("\nSpecified channel cannot be read \n");
- return -EINVAL; /* "sorry channel spec wrong " */
- break;
- } /* switch(ui_Channel) */
- break;
- default:
- printk("\nThe specified functionality does not exist\n");
- return -EINVAL;
- } /* switch(data[0]) */
return insn->n;
}
@@ -1051,6 +1087,8 @@ static int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *de
struct comedi_insn *insn,
unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
+
devpriv->b_OutputMemoryStatus = data[0];
return insn->n;
}
@@ -1079,9 +1117,9 @@ static int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
static unsigned int ui_Temp = 0;
unsigned int ui_Temp1;
-
unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
if (!devpriv->b_OutputMemoryStatus) {
@@ -1274,6 +1312,7 @@ static int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_TimerCounterMode, i_MasterConfiguration;
devpriv->tsk_Current = current;
@@ -1875,6 +1914,7 @@ static int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device
struct comedi_insn *insn,
unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_CommandAndStatusValue;
switch (data[0]) {
@@ -2198,7 +2238,9 @@ static int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_CommandAndStatusValue;
+
switch (data[0]) {
case COUNTER1:
/* Read counter/timer1 */
@@ -2421,9 +2463,11 @@ static int i_APCI1500_ConfigureInterrupt(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ui_Status;
int i_RegValue;
int i_Constant;
+
devpriv->tsk_Current = current;
outl(0x0, devpriv->i_IobaseAmcc + 0x38);
if (data[0] == 1) {
@@ -2597,6 +2641,7 @@ static void v_APCI1500_Interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct addi_private *devpriv = dev->private;
unsigned int ui_InterruptStatus = 0;
int i_RegValue = 0;
i_InterruptMask = 0;
@@ -2840,7 +2885,9 @@ static void v_APCI1500_Interrupt(int irq, void *d)
*/
static int i_APCI1500_Reset(struct comedi_device *dev)
{
+ struct addi_private *devpriv = dev->private;
int i_DummyRead = 0;
+
i_TimerCounter1Init = 0;
i_TimerCounter2Init = 0;
i_WatchdogCounter3Init = 0;
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h
deleted file mode 100644
index 647f9ebf552..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-/********* Definitions for APCI-1500 card *****/
-
-/* Card Specific information */
-#define APCI1500_BOARD_VENDOR_ID 0x10e8
-#define APCI1500_ADDRESS_RANGE 4
-
-/* DIGITAL INPUT-OUTPUT DEFINE */
-
-#define APCI1500_DIGITAL_OP 2
-#define APCI1500_DIGITAL_IP 0
-#define APCI1500_AND 2
-#define APCI1500_OR 4
-#define APCI1500_OR_PRIORITY 6
-#define APCI1500_CLK_SELECT 0
-#define COUNTER1 0
-#define COUNTER2 1
-#define COUNTER3 2
-#define APCI1500_COUNTER 0x20
-#define APCI1500_TIMER 0
-#define APCI1500_WATCHDOG 0
-#define APCI1500_SINGLE 0
-#define APCI1500_CONTINUOUS 0x80
-#define APCI1500_DISABLE 0
-#define APCI1500_ENABLE 1
-#define APCI1500_SOFTWARE_TRIGGER 0x4
-#define APCI1500_HARDWARE_TRIGGER 0x10
-#define APCI1500_SOFTWARE_GATE 0
-#define APCI1500_HARDWARE_GATE 0x8
-#define START 0
-#define STOP 1
-#define TRIGGER 2
-
-/*
- * Zillog I/O enumeration
- */
-enum {
- APCI1500_Z8536_PORT_C,
- APCI1500_Z8536_PORT_B,
- APCI1500_Z8536_PORT_A,
- APCI1500_Z8536_CONTROL_REGISTER
-};
-
-/*
- * Z8536 CIO Internal Address
- */
-enum {
- APCI1500_RW_MASTER_INTERRUPT_CONTROL,
- APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
- APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
- APCI1500_RW_PORT_B_INTERRUPT_CONTROL,
- APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR,
- APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
- APCI1500_RW_PORT_C_DATA_DIRECTION,
- APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
-
- APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
- APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
- APCI1500_RW_CPT_TMR1_CMD_STATUS,
- APCI1500_RW_CPT_TMR2_CMD_STATUS,
- APCI1500_RW_CPT_TMR3_CMD_STATUS,
- APCI1500_RW_PORT_A_DATA,
- APCI1500_RW_PORT_B_DATA,
- APCI1500_RW_PORT_C_DATA,
-
- APCI1500_R_CPT_TMR1_VALUE_HIGH,
- APCI1500_R_CPT_TMR1_VALUE_LOW,
- APCI1500_R_CPT_TMR2_VALUE_HIGH,
- APCI1500_R_CPT_TMR2_VALUE_LOW,
- APCI1500_R_CPT_TMR3_VALUE_HIGH,
- APCI1500_R_CPT_TMR3_VALUE_LOW,
- APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
- APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
- APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
- APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
- APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
- APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
- APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
- APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
- APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
- APCI1500_R_CURRENT_VECTOR,
-
- APCI1500_RW_PORT_A_SPECIFICATION,
- APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
- APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
- APCI1500_RW_PORT_A_DATA_DIRECTION,
- APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL,
- APCI1500_RW_PORT_A_PATTERN_POLARITY,
- APCI1500_RW_PORT_A_PATTERN_TRANSITION,
- APCI1500_RW_PORT_A_PATTERN_MASK,
-
- APCI1500_RW_PORT_B_SPECIFICATION,
- APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
- APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
- APCI1500_RW_PORT_B_DATA_DIRECTION,
- APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL,
- APCI1500_RW_PORT_B_PATTERN_POLARITY,
- APCI1500_RW_PORT_B_PATTERN_TRANSITION,
- APCI1500_RW_PORT_B_PATTERN_MASK
-};
-
- /*----------DIGITAL INPUT----------------*/
-static int i_APCI1500_Initialisation(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-
-static int i_APCI1500_StartStopInputEvent(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/*---------- DIGITAL OUTPUT------------*/
-static int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-static int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/*----------TIMER----------------*/
-static int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-static int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-static int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-static int i_APCI1500_ReadInterruptMask(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/*----------INTERRUPT HANDLER------*/
-static void v_APCI1500_Interrupt(int irq, void *d);
-static int i_APCI1500_ConfigureInterrupt(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-/*----------RESET---------------*/
-static int i_APCI1500_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
deleted file mode 100644
index 8a584a014b0..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/**
-@verbatim
-
-Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
-
- ADDI-DATA GmbH
- Dieselstrasse 3
- D-77833 Ottersweier
- Tel: +19(0)7223/9493-0
- Fax: +49(0)7223/9493-92
- http://www.addi-data.com
- info@addi-data.com
-
-This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
-@endverbatim
-*/
-/*
-
- +-----------------------------------------------------------------------+
- | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
- +-----------------------------------------------------------------------+
- | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
- | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
- +-------------------------------+---------------------------------------+
- | Project : APCI-1516 | Compiler : GCC |
- | Module name : hwdrv_apci1516.c| Version : 2.96 |
- +-------------------------------+---------------------------------------+
- | Project manager: Eric Stolz | Date : 02/12/2002 |
- +-------------------------------+---------------------------------------+
- | Description : Hardware Layer Access For APCI-1516 |
- +-----------------------------------------------------------------------+
- | UPDATES |
- +----------+-----------+------------------------------------------------+
- | Date | Author | Description of updates |
- +----------+-----------+------------------------------------------------+
- | | | |
- | | | |
- | | | |
- +----------+-----------+------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
-#include "hwdrv_apci1516.h"
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1516_Read1DigitalInput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Return the status of the digital input |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure
-| struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI1516_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_TmpValue = 0;
- unsigned int ui_Channel;
- ui_Channel = CR_CHAN(insn->chanspec);
- if (ui_Channel <= 7) {
- ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI1516_DIGITAL_IP);
- /* since only 1 channel reqd to bring it to last bit it is rotated */
- /* 8 +(chan - 1) times then ANDed with 1 for last bit. */
- *data = (ui_TmpValue >> ui_Channel) & 0x1;
- } /* if(ui_Channel >= 0 && ui_Channel <=7) */
- else {
- /* comedi_error(dev," \n chan spec wrong\n"); */
- return -EINVAL; /* "sorry channel spec wrong " */
- } /* else if(ui_Channel >= 0 && ui_Channel <=7) */
-
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1516_ReadMoreDigitalInput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Return the status of the Requested digital inputs |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure
-| struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
-
- unsigned int ui_PortValue = data[0];
- unsigned int ui_Mask = 0;
- unsigned int ui_NoOfChannels;
-
- ui_NoOfChannels = CR_CHAN(insn->chanspec);
-
- *data = (unsigned int) inw(devpriv->iobase + APCI1516_DIGITAL_IP);
- switch (ui_NoOfChannels) {
- case 2:
- ui_Mask = 3;
- *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
- break;
- case 4:
- ui_Mask = 15;
- *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
- break;
- case 7:
- break;
-
- default:
- printk("\nWrong parameters\n");
- return -EINVAL; /* "sorry channel spec wrong " */
- break;
- } /* switch(ui_NoOfChannels) */
-
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1516_ConfigDigitalOutput (struct comedi_device *dev,
-| struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Configures The Digital Output Subdevice. |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int *data : Data Pointer contains |
-| configuration parameters as below |
-| struct comedi_subdevice *s, :pointer to subdevice structure
-| struct comedi_insn *insn :pointer to insn structure |
-| data[0] :1:Memory on |
-| 0:Memory off |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- devpriv->b_OutputMemoryStatus = data[0];
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1516_WriteDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
-| unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Writes port value To the selected port |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure
-| struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_Temp, ui_Temp1;
- unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
-
- printk("EL311003 : @=%x\n", devpriv->iobase + APCI1516_DIGITAL_OP);
-
- if (devpriv->b_OutputMemoryStatus) {
- ui_Temp = inw(devpriv->iobase + APCI1516_DIGITAL_OP);
-
- } /* if(devpriv->b_OutputMemoryStatus ) */
- else {
- ui_Temp = 0;
- } /* if(devpriv->b_OutputMemoryStatus ) */
- if (data[3] == 0) {
- if (data[1] == 0) {
- data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
- outw(data[0], devpriv->iobase + APCI1516_DIGITAL_OP);
-
- printk("EL311003 : d=%d @=%x\n", data[0],
- devpriv->iobase + APCI1516_DIGITAL_OP);
-
- } /* if(data[1]==0) */
- else {
- if (data[1] == 1) {
- switch (ui_NoOfChannel) {
-
- case 2:
- data[0] =
- (data[0] << (2 *
- data[2])) | ui_Temp;
- break;
-
- case 4:
- data[0] =
- (data[0] << (4 *
- data[2])) | ui_Temp;
- break;
-
- case 7:
- data[0] = data[0] | ui_Temp;
- break;
-
- default:
- comedi_error(dev, " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
-
- } /* switch(ui_NoOfChannels) */
-
- outw(data[0],
- devpriv->iobase + APCI1516_DIGITAL_OP);
-
- printk("EL311003 : d=%d @=%x\n", data[0],
- devpriv->iobase + APCI1516_DIGITAL_OP);
- } /* if(data[1]==1) */
- else {
- printk("\nSpecified channel not supported\n");
- } /* else if(data[1]==1) */
- } /* elseif(data[1]==0) */
- } /* if(data[3]==0) */
- else {
- if (data[3] == 1) {
- if (data[1] == 0) {
- data[0] = ~data[0] & 0x1;
- ui_Temp1 = 1;
- ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] = (data[0] << ui_NoOfChannel) ^ 0xff;
- data[0] = data[0] & ui_Temp;
- outw(data[0],
- devpriv->iobase + APCI1516_DIGITAL_OP);
-
- printk("EL311003 : d=%d @=%x\n", data[0],
- devpriv->iobase + APCI1516_DIGITAL_OP);
-
- } /* if(data[1]==0) */
- else {
- if (data[1] == 1) {
- switch (ui_NoOfChannel) {
-
- case 2:
- data[0] = ~data[0] & 0x3;
- ui_Temp1 = 3;
- ui_Temp1 =
- ui_Temp1 << 2 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (2 *
- data
- [2])) ^
- 0xff) & ui_Temp;
- break;
-
- case 4:
- data[0] = ~data[0] & 0xf;
- ui_Temp1 = 15;
- ui_Temp1 =
- ui_Temp1 << 4 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (4 *
- data
- [2])) ^
- 0xff) & ui_Temp;
- break;
-
- case 7:
- break;
-
- default:
- comedi_error(dev,
- " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
-
- } /* switch(ui_NoOfChannels) */
-
- outw(data[0],
- devpriv->iobase +
- APCI1516_DIGITAL_OP);
-
- printk("EL311003 : d=%d @=%x\n",
- data[0],
- devpriv->iobase +
- APCI1516_DIGITAL_OP);
- } /* if(data[1]==1) */
- else {
- printk("\nSpecified channel not supported\n");
- } /* else if(data[1]==1) */
- } /* elseif(data[1]==0) */
- } /* if(data[3]==1); */
- else {
- printk("\nSpecified functionality does not exist\n");
- return -EINVAL;
- } /* if else data[3]==1) */
- } /* if else data[3]==0) */
- return (insn->n);
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1516_ReadDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
-| unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Read value of the selected channel or port |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure
-| struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
-
- unsigned int ui_Temp;
- unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
- ui_Temp = data[0];
- *data = inw(devpriv->iobase + APCI1516_DIGITAL_OP_RW);
- if (ui_Temp == 0) {
- *data = (*data >> ui_NoOfChannel) & 0x1;
- } /* if(ui_Temp==0) */
- else {
- if (ui_Temp == 1) {
- switch (ui_NoOfChannel) {
-
- case 2:
- *data = (*data >> (2 * data[1])) & 3;
- break;
-
- case 4:
- *data = (*data >> (4 * data[1])) & 15;
- break;
-
- case 7:
- break;
-
- default:
- comedi_error(dev, " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
-
- } /* switch(ui_NoOfChannels) */
- } /* if(ui_Temp==1) */
- else {
- printk("\nSpecified channel not supported \n");
- } /* elseif(ui_Temp==1) */
- } /* elseif(ui_Temp==0) */
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1516_ConfigWatchdog(struct comedi_device *dev,
-| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Configures The Watchdog |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure
-| struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- if (data[0] == 0) {
- /* Disable the watchdog */
- outw(0x0,
- devpriv->i_IobaseAddon +
- APCI1516_WATCHDOG_ENABLEDISABLE);
- /* Loading the Reload value */
- outw(data[1],
- devpriv->i_IobaseAddon +
- APCI1516_WATCHDOG_RELOAD_VALUE);
- data[1] = data[1] >> 16;
- outw(data[1],
- devpriv->i_IobaseAddon +
- APCI1516_WATCHDOG_RELOAD_VALUE + 2);
- } /* if(data[0]==0) */
- else {
- printk("\nThe input parameters are wrong\n");
- return -EINVAL;
- } /* elseif(data[0]==0) */
-
- return insn->n;
-}
-
- /*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI1516_StartStopWriteWatchdog |
- | (struct comedi_device *dev,struct comedi_subdevice *s,
- struct comedi_insn *insn,unsigned int *data); |
- +----------------------------------------------------------------------------+
- | Task : Start / Stop The Watchdog |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | struct comedi_subdevice *s, :pointer to subdevice structure
- struct comedi_insn *insn :pointer to insn structure |
- | unsigned int *data : Data Pointer to read status |
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
- */
-
-int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- switch (data[0]) {
- case 0: /* stop the watchdog */
- outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE); /* disable the watchdog */
- break;
- case 1: /* start the watchdog */
- outw(0x0001,
- devpriv->i_IobaseAddon +
- APCI1516_WATCHDOG_ENABLEDISABLE);
- break;
- case 2: /* Software trigger */
- outw(0x0201,
- devpriv->i_IobaseAddon +
- APCI1516_WATCHDOG_ENABLEDISABLE);
- break;
- default:
- printk("\nSpecified functionality does not exist\n");
- return -EINVAL;
- } /* switch(data[0]) */
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1516_ReadWatchdog |
-| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
- unsigned int *data); |
-+----------------------------------------------------------------------------+
-| Task : Read The Watchdog |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure
- struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI1516_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- data[0] = inw(devpriv->i_IobaseAddon + APCI1516_WATCHDOG_STATUS) & 0x1;
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1516_Reset(struct comedi_device *dev) | |
-+----------------------------------------------------------------------------+
-| Task :resets all the registers |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI1516_Reset(struct comedi_device *dev)
-{
- outw(0x0, devpriv->iobase + APCI1516_DIGITAL_OP); /* RESETS THE DIGITAL OUTPUTS */
- outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE);
- outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE);
- outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE + 2);
- return 0;
-}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h
deleted file mode 100644
index 44728293e49..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-/********* Definitions for APCI-1516 card *****/
-
-/* Card Specific information */
-#define APCI1516_BOARD_VENDOR_ID 0x15B8
-#define APCI1516_ADDRESS_RANGE 8
-
-/* DIGITAL INPUT-OUTPUT DEFINE */
-
-#define APCI1516_DIGITAL_OP 4
-#define APCI1516_DIGITAL_OP_RW 4
-#define APCI1516_DIGITAL_IP 0
-
-/* TIMER COUNTER WATCHDOG DEFINES */
-
-#define ADDIDATA_WATCHDOG 2
-#define APCI1516_DIGITAL_OP_WATCHDOG 0
-#define APCI1516_WATCHDOG_ENABLEDISABLE 12
-#define APCI1516_WATCHDOG_RELOAD_VALUE 4
-#define APCI1516_WATCHDOG_STATUS 16
-
-/* Hardware Layer functions for Apci1516 */
-
-/* Digital Input */
-int i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI1516_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* Digital Output */
-int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/*
-* TIMER timer value is passed as u seconds
-*/
-int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI1516_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* reset */
-int i_APCI1516_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
index 5b92e45c9ae..fc31c4b9340 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
@@ -46,14 +46,62 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+----------+-----------+------------------------------------------------+
*/
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
-
-#include <linux/delay.h>
-#include "hwdrv_apci1564.h"
+/********* Definitions for APCI-1564 card *****/
+
+#define APCI1564_ADDRESS_RANGE 128
+
+/* DIGITAL INPUT-OUTPUT DEFINE */
+/* Input defines */
+#define APCI1564_DIGITAL_IP 0x04
+#define APCI1564_DIGITAL_IP_INTERRUPT_MODE1 4
+#define APCI1564_DIGITAL_IP_INTERRUPT_MODE2 8
+#define APCI1564_DIGITAL_IP_IRQ 16
+
+/* Output defines */
+#define APCI1564_DIGITAL_OP 0x18
+#define APCI1564_DIGITAL_OP_RW 0
+#define APCI1564_DIGITAL_OP_INTERRUPT 4
+#define APCI1564_DIGITAL_OP_IRQ 12
+
+/* Digital Input IRQ Function Selection */
+#define ADDIDATA_OR 0
+#define ADDIDATA_AND 1
+
+/* Digital Input Interrupt Status */
+#define APCI1564_DIGITAL_IP_INTERRUPT_STATUS 12
+
+/* Digital Output Interrupt Status */
+#define APCI1564_DIGITAL_OP_INTERRUPT_STATUS 8
+
+/* Digital Input Interrupt Enable Disable. */
+#define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE 0x4
+#define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE 0xfffffffb
+
+/* Digital Output Interrupt Enable Disable. */
+#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1
+#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xfffffffe
+#define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2
+#define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xfffffffd
+
+/* TIMER COUNTER WATCHDOG DEFINES */
+
+#define ADDIDATA_TIMER 0
+#define ADDIDATA_COUNTER 1
+#define ADDIDATA_WATCHDOG 2
+#define APCI1564_DIGITAL_OP_WATCHDOG 0x28
+#define APCI1564_TIMER 0x48
+#define APCI1564_COUNTER1 0x0
+#define APCI1564_COUNTER2 0x20
+#define APCI1564_COUNTER3 0x40
+#define APCI1564_COUNTER4 0x60
+#define APCI1564_TCW_SYNC_ENABLEDISABLE 0
+#define APCI1564_TCW_RELOAD_VALUE 4
+#define APCI1564_TCW_TIMEBASE 8
+#define APCI1564_TCW_PROG 12
+#define APCI1564_TCW_TRIG_STATUS 16
+#define APCI1564_TCW_IRQ 20
+#define APCI1564_TCW_WARN_TIMEVAL 24
+#define APCI1564_TCW_WARN_TIMEBASE 28
/* Global variables */
static unsigned int ui_InterruptStatus_1564 = 0;
@@ -86,9 +134,13 @@ static unsigned int ui_InterruptData, ui_Type;
| |
+----------------------------------------------------------------------------+
*/
-int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
+
devpriv->tsk_Current = current;
/*******************************/
/* Set the digital input logic */
@@ -128,107 +180,15 @@ int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subde
return insn->n;
}
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1564_Read1DigitalInput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Return the status of the digital input |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int ui_Channel : Channel number to read |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI1564_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int apci1564_di_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned int ui_TmpValue = 0;
- unsigned int ui_Channel;
+ struct addi_private *devpriv = dev->private;
- ui_Channel = CR_CHAN(insn->chanspec);
- if (ui_Channel <= 31) {
- ui_TmpValue =
- (unsigned int) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
-/*
-* since only 1 channel reqd to bring it to last bit it is rotated 8
-* +(chan - 1) times then ANDed with 1 for last bit.
-*/
- *data = (ui_TmpValue >> ui_Channel) & 0x1;
- } /* if (ui_Channel >= 0 && ui_Channel <=31) */
- else {
- comedi_error(dev, "Not a valid channel number !!! \n");
- return -EINVAL; /* "sorry channel spec wrong " */
- } /* else if (ui_Channel >= 0 && ui_Channel <=31) */
- return insn->n;
-}
+ data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1564_ReadMoreDigitalInput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Return the status of the Requested digital inputs |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int ui_NoOfChannels : No Of Channels To be Read |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_PortValue = data[0];
- unsigned int ui_Mask = 0;
- unsigned int ui_NoOfChannels;
-
- ui_NoOfChannels = CR_CHAN(insn->chanspec);
- if (data[1] == 0) {
- *data = (unsigned int) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
- switch (ui_NoOfChannels) {
- case 2:
- ui_Mask = 3;
- *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
- break;
- case 4:
- ui_Mask = 15;
- *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
- break;
- case 8:
- ui_Mask = 255;
- *data = (*data >> (8 * ui_PortValue)) & ui_Mask;
- break;
- case 16:
- ui_Mask = 65535;
- *data = (*data >> (16 * ui_PortValue)) & ui_Mask;
- break;
- case 31:
- break;
- default:
- comedi_error(dev, "Not a valid Channel number !!!\n");
- return -EINVAL; /* "sorry channel spec wrong " */
- break;
- } /* switch (ui_NoOfChannels) */
- } /* if (data[1]==0) */
- else {
- if (data[1] == 1) {
- *data = ui_InterruptStatus_1564;
- } /* if (data[1]==1) */
- } /* else if (data[1]==0) */
return insn->n;
}
@@ -257,9 +217,12 @@ int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub
| |
+----------------------------------------------------------------------------+
*/
-int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ul_Command = 0;
if ((data[0] != 0) && (data[0] != 1)) {
@@ -295,244 +258,27 @@ int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd
return insn->n;
}
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1564_WriteDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Writes port value To the selected port |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int ui_NoOfChannels : No Of Channels To Write |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int apci1564_do_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned int ui_Temp, ui_Temp1;
- unsigned int ui_NoOfChannel;
+ struct addi_private *devpriv = dev->private;
+ unsigned int mask = data[0];
+ unsigned int bits = data[1];
- ui_NoOfChannel = CR_CHAN(insn->chanspec);
- if (devpriv->b_OutputMemoryStatus) {
- ui_Temp =
- inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ s->state = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
APCI1564_DIGITAL_OP_RW);
- } /* if (devpriv->b_OutputMemoryStatus ) */
- else {
- ui_Temp = 0;
- } /* else if (devpriv->b_OutputMemoryStatus ) */
- if (data[3] == 0) {
- if (data[1] == 0) {
- data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
- outl(data[0],
- devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
- APCI1564_DIGITAL_OP_RW);
- } /* if (data[1]==0) */
- else {
- if (data[1] == 1) {
- switch (ui_NoOfChannel) {
- case 2:
- data[0] =
- (data[0] << (2 *
- data[2])) | ui_Temp;
- break;
- case 4:
- data[0] =
- (data[0] << (4 *
- data[2])) | ui_Temp;
- break;
- case 8:
- data[0] =
- (data[0] << (8 *
- data[2])) | ui_Temp;
- break;
- case 16:
- data[0] =
- (data[0] << (16 *
- data[2])) | ui_Temp;
- break;
- case 31:
- data[0] = data[0] | ui_Temp;
- break;
- default:
- comedi_error(dev, " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
- } /* switch (ui_NoOfChannels) */
- outl(data[0],
- devpriv->i_IobaseAmcc +
- APCI1564_DIGITAL_OP +
- APCI1564_DIGITAL_OP_RW);
- } /* if (data[1]==1) */
- else {
- printk("\nSpecified channel not supported\n");
- } /* else if (data[1]==1) */
- } /* else if (data[1]==0) */
- } /* if(data[3]==0) */
- else {
- if (data[3] == 1) {
- if (data[1] == 0) {
- data[0] = ~data[0] & 0x1;
- ui_Temp1 = 1;
- ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- (data[0] << ui_NoOfChannel) ^
- 0xffffffff;
- data[0] = data[0] & ui_Temp;
- outl(data[0],
- devpriv->i_IobaseAmcc +
- APCI1564_DIGITAL_OP +
- APCI1564_DIGITAL_OP_RW);
- } /* if (data[1]==0) */
- else {
- if (data[1] == 1) {
- switch (ui_NoOfChannel) {
- case 2:
- data[0] = ~data[0] & 0x3;
- ui_Temp1 = 3;
- ui_Temp1 =
- ui_Temp1 << 2 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (2 *
- data
- [2])) ^
- 0xffffffff) & ui_Temp;
- break;
- case 4:
- data[0] = ~data[0] & 0xf;
- ui_Temp1 = 15;
- ui_Temp1 =
- ui_Temp1 << 4 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (4 *
- data
- [2])) ^
- 0xffffffff) & ui_Temp;
- break;
- case 8:
- data[0] = ~data[0] & 0xff;
- ui_Temp1 = 255;
- ui_Temp1 =
- ui_Temp1 << 8 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (8 *
- data
- [2])) ^
- 0xffffffff) & ui_Temp;
- break;
- case 16:
- data[0] = ~data[0] & 0xffff;
- ui_Temp1 = 65535;
- ui_Temp1 =
- ui_Temp1 << 16 *
- data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (16 *
- data
- [2])) ^
- 0xffffffff) & ui_Temp;
- break;
- case 31:
- break;
- default:
- comedi_error(dev,
- " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
- } /* switch(ui_NoOfChannels) */
- outl(data[0],
- devpriv->i_IobaseAmcc +
- APCI1564_DIGITAL_OP +
- APCI1564_DIGITAL_OP_RW);
- } /* if (data[1]==1) */
- else {
- printk("\nSpecified channel not supported\n");
- } /* else if (data[1]==1) */
- } /* else if (data[1]==0) */
- } /* if (data[3]==1); */
- else {
- printk("\nSpecified functionality does not exist\n");
- return -EINVAL;
- } /* else if (data[3]==1) */
- } /* else if (data[3]==0) */
- return insn->n;
-}
+ if (mask) {
+ s->state &= ~mask;
+ s->state |= (bits & mask);
+
+ outl(s->state, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_RW);
+ }
+
+ data[1] = s->state;
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI1564_ReadDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Read value of the selected channel or port |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int ui_NoOfChannels : No Of Channels To read |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_Temp;
- unsigned int ui_NoOfChannel;
-
- ui_NoOfChannel = CR_CHAN(insn->chanspec);
- ui_Temp = data[0];
- *data = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
- APCI1564_DIGITAL_OP_RW);
- if (ui_Temp == 0) {
- *data = (*data >> ui_NoOfChannel) & 0x1;
- } /* if (ui_Temp==0) */
- else {
- if (ui_Temp == 1) {
- switch (ui_NoOfChannel) {
- case 2:
- *data = (*data >> (2 * data[1])) & 3;
- break;
-
- case 4:
- *data = (*data >> (4 * data[1])) & 15;
- break;
-
- case 8:
- *data = (*data >> (8 * data[1])) & 255;
- break;
-
- case 16:
- *data = (*data >> (16 * data[1])) & 65535;
- break;
-
- case 31:
- break;
-
- default:
- comedi_error(dev, " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
- break;
- } /* switch(ui_NoOfChannels) */
- } /* if (ui_Temp==1) */
- else {
- printk("\nSpecified channel not supported \n");
- } /* else if (ui_Temp==1) */
- } /* else if (ui_Temp==0) */
return insn->n;
}
@@ -566,10 +312,14 @@ int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev
| |
+----------------------------------------------------------------------------+
*/
-int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ul_Command1 = 0;
+
devpriv->tsk_Current = current;
if (data[0] == ADDIDATA_WATCHDOG) {
devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
@@ -720,10 +470,14 @@ int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev,
| |
+----------------------------------------------------------------------------+
*/
-int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ul_Command1 = 0;
+
if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
switch (data[1]) {
case 0: /* stop the watchdog */
@@ -815,9 +569,12 @@ int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
| |
+----------------------------------------------------------------------------+
*/
-int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ul_Command1 = 0;
if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
@@ -894,8 +651,10 @@ int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev,
+----------------------------------------------------------------------------+
*/
-int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
*data = ui_Type;
return insn->n;
@@ -921,10 +680,12 @@ int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subd
static void v_APCI1564_Interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct addi_private *devpriv = dev->private;
unsigned int ui_DO, ui_DI;
unsigned int ui_Timer;
unsigned int ui_C1, ui_C2, ui_C3, ui_C4;
unsigned int ul_Command2 = 0;
+
ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
APCI1564_DIGITAL_IP_IRQ) & 0x01;
ui_DO = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
@@ -1104,8 +865,10 @@ static void v_APCI1564_Interrupt(int irq, void *d)
+----------------------------------------------------------------------------+
*/
-int i_APCI1564_Reset(struct comedi_device *dev)
+static int i_APCI1564_Reset(struct comedi_device *dev)
{
+ struct addi_private *devpriv = dev->private;
+
outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_IRQ); /* disable the interrupts */
inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_STATUS); /* Reset the interrupt status register */
outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE1); /* Disable the and/or interrupt */
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h
deleted file mode 100644
index c91594d56a4..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-/********* Definitions for APCI-1564 card *****/
-
-#define APCI1564_BOARD_VENDOR_ID 0x15B8
-#define APCI1564_ADDRESS_RANGE 128
-
-/* DIGITAL INPUT-OUTPUT DEFINE */
-/* Input defines */
-#define APCI1564_DIGITAL_IP 0x04
-#define APCI1564_DIGITAL_IP_INTERRUPT_MODE1 4
-#define APCI1564_DIGITAL_IP_INTERRUPT_MODE2 8
-#define APCI1564_DIGITAL_IP_IRQ 16
-
-/* Output defines */
-#define APCI1564_DIGITAL_OP 0x18
-#define APCI1564_DIGITAL_OP_RW 0
-#define APCI1564_DIGITAL_OP_INTERRUPT 4
-#define APCI1564_DIGITAL_OP_IRQ 12
-
-/* Digital Input IRQ Function Selection */
-#define ADDIDATA_OR 0
-#define ADDIDATA_AND 1
-
-/* Digital Input Interrupt Status */
-#define APCI1564_DIGITAL_IP_INTERRUPT_STATUS 12
-
-/* Digital Output Interrupt Status */
-#define APCI1564_DIGITAL_OP_INTERRUPT_STATUS 8
-
-/* Digital Input Interrupt Enable Disable. */
-#define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE 0x4
-#define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB
-
-/* Digital Output Interrupt Enable Disable. */
-#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1
-#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE
-#define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2
-#define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD
-
-/* ADDIDATA Enable Disable */
-
-#define ADDIDATA_ENABLE 1
-#define ADDIDATA_DISABLE 0
-
-/* TIMER COUNTER WATCHDOG DEFINES */
-
-#define ADDIDATA_TIMER 0
-#define ADDIDATA_COUNTER 1
-#define ADDIDATA_WATCHDOG 2
-#define APCI1564_DIGITAL_OP_WATCHDOG 0x28
-#define APCI1564_TIMER 0x48
-#define APCI1564_COUNTER1 0x0
-#define APCI1564_COUNTER2 0x20
-#define APCI1564_COUNTER3 0x40
-#define APCI1564_COUNTER4 0x60
-#define APCI1564_TCW_SYNC_ENABLEDISABLE 0
-#define APCI1564_TCW_RELOAD_VALUE 4
-#define APCI1564_TCW_TIMEBASE 8
-#define APCI1564_TCW_PROG 12
-#define APCI1564_TCW_TRIG_STATUS 16
-#define APCI1564_TCW_IRQ 20
-#define APCI1564_TCW_WARN_TIMEVAL 24
-#define APCI1564_TCW_WARN_TIMEBASE 28
-
-/* Hardware Layer functions for Apci1564 */
-
-/*
-* DI for di read
-*/
-int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI1564_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* DO */
-int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/*
-* TIMER timer value is passed as u seconds
-*/
-int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* intERRUPT */
-static void v_APCI1564_Interrupt(int irq, void *d);
-
-/* RESET */
-int i_APCI1564_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
index 00a088f820a..5958a9cb2a3 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
@@ -47,13 +47,24 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-----------------------------------------------------------------------+
*/
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
+#ifndef COMEDI_SUBD_TTLIO
+#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
+#endif
+
+#define APCI16XX_TTL_INIT 0
+#define APCI16XX_TTL_INITDIRECTION 1
+#define APCI16XX_TTL_OUTPUTMEMORY 2
+
+#define APCI16XX_TTL_READCHANNEL 0
+#define APCI16XX_TTL_READPORT 1
+
+#define APCI16XX_TTL_WRITECHANNEL_ON 0
+#define APCI16XX_TTL_WRITECHANNEL_OFF 1
+#define APCI16XX_TTL_WRITEPORT_ON 2
+#define APCI16XX_TTL_WRITEPORT_OFF 3
-#include "hwdrv_apci16xx.h"
+#define APCI16XX_TTL_READ_ALL_INPUTS 0
+#define APCI16XX_TTL_READ_ALL_OUTPUTS 1
/*
+----------------------------------------------------------------------------+
@@ -90,9 +101,13 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+----------------------------------------------------------------------------+
*/
-int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = insn->n;
unsigned char b_Command = 0;
unsigned char b_Cpt = 0;
@@ -283,9 +298,13 @@ int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev,
+----------------------------------------------------------------------------+
*/
-int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = insn->n;
unsigned char b_Command = 0;
unsigned char b_NumberOfPort =
@@ -430,9 +449,13 @@ int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev,
+----------------------------------------------------------------------------+
*/
-int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
unsigned char b_Command = (unsigned char) CR_AREF(insn->chanspec);
int i_ReturnValue = insn->n;
unsigned char b_Cpt = 0;
@@ -570,9 +593,13 @@ int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
+----------------------------------------------------------------------------+
*/
-int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = insn->n;
unsigned char b_Command = 0;
unsigned char b_NumberOfPort =
@@ -774,7 +801,7 @@ int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev,
+----------------------------------------------------------------------------+
*/
-int i_APCI16XX_Reset(struct comedi_device *dev)
+static int i_APCI16XX_Reset(struct comedi_device *dev)
{
return 0;
}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h
deleted file mode 100644
index a12df4bc88a..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data-com
- * info@addi-data.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 COMEDI_SUBD_TTLIO
-#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
-#endif
-
-#ifndef ADDIDATA_ENABLE
-#define ADDIDATA_ENABLE 1
-#define ADDIDATA_DISABLE 0
-#endif
-
-#define APCI16XX_TTL_INIT 0
-#define APCI16XX_TTL_INITDIRECTION 1
-#define APCI16XX_TTL_OUTPUTMEMORY 2
-
-#define APCI16XX_TTL_READCHANNEL 0
-#define APCI16XX_TTL_READPORT 1
-
-#define APCI16XX_TTL_WRITECHANNEL_ON 0
-#define APCI16XX_TTL_WRITECHANNEL_OFF 1
-#define APCI16XX_TTL_WRITEPORT_ON 2
-#define APCI16XX_TTL_WRITEPORT_OFF 3
-
-#define APCI16XX_TTL_READ_ALL_INPUTS 0
-#define APCI16XX_TTL_READ_ALL_OUTPUTS 1
-
-#ifdef __KERNEL__
-
-/*
-+----------------------------------------------------------------------------+
-| TTL INISIALISATION FUNCTION |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data);
-
-/*
-+----------------------------------------------------------------------------+
-| TTL INPUT FUNCTION |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data);
-
-int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/*
-+----------------------------------------------------------------------------+
-| TTL OUTPUT FUNCTIONS |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data);
-
-int i_APCI16XX_Reset(struct comedi_device *dev);
-#endif
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
deleted file mode 100644
index 49dcbe24fcd..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
+++ /dev/null
@@ -1,460 +0,0 @@
-/**
-@verbatim
-
-Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
-
- ADDI-DATA GmbH
- Dieselstrasse 3
- D-77833 Ottersweier
- Tel: +19(0)7223/9493-0
- Fax: +49(0)7223/9493-92
- http://www.addi-data.com
- info@addi-data.com
-
-This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
-@endverbatim
-*/
-/*
-
- +-----------------------------------------------------------------------+
- | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
- +-----------------------------------------------------------------------+
- | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
- | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
- +-------------------------------+---------------------------------------+
- | Project : APCI-2016 | Compiler : GCC |
- | Module name : hwdrv_apci2016.c| Version : 2.96 |
- +-------------------------------+---------------------------------------+
- | Project manager: Eric Stolz | Date : 02/12/2002 |
- +-------------------------------+---------------------------------------+
- | Description : Hardware Layer Access For APCI-2016 |
- +-----------------------------------------------------------------------+
- | UPDATES |
- +----------+-----------+------------------------------------------------+
- | Date | Author | Description of updates |
- +----------+-----------+------------------------------------------------+
- | | | |
- | | | |
- | | | |
- +----------+-----------+------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
-#include "hwdrv_apci2016.h"
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2016_ConfigDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Configures The Digital Output Subdevice. |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int *data : Data Pointer contains |
-| configuration parameters as below |
-| |
-| data[0] : 1 Digital Memory On |
-| 0 Digital Memory Off |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- if ((data[0] != 0) && (data[0] != 1)) {
- comedi_error(dev,
- "Not a valid Data !!! ,Data should be 1 or 0\n");
- return -EINVAL;
- } /* if ((data[0]!=0) && (data[0]!=1)) */
- if (data[0]) {
- devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
- } /* if (data[0] */
- else {
- devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
- } /* else if (data[0] */
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2016_WriteDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Writes port value To the selected port |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int ui_NoOfChannels : No Of Channels To Write |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_NoOfChannel;
- unsigned int ui_Temp, ui_Temp1;
- ui_NoOfChannel = CR_CHAN(insn->chanspec);
- if (ui_NoOfChannel > 15) {
- comedi_error(dev,
- "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
- return -EINVAL;
- } /* if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15)) */
- if (devpriv->b_OutputMemoryStatus) {
- ui_Temp = inw(devpriv->iobase + APCI2016_DIGITAL_OP);
- } /* if (devpriv->b_OutputMemoryStatus ) */
- else {
- ui_Temp = 0;
- } /* else if (devpriv->b_OutputMemoryStatus ) */
- if ((data[1] != 0) && (data[1] != 1)) {
- comedi_error(dev,
- "Invalid Data[1] value !!!, Data[1] should be 0 or 1\n");
- return -EINVAL;
- } /* if ((data[1]!=0) && (data[1]!=1)) */
-
- if (data[3] == 0) {
- if (data[1] == 0) {
- data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
- outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP);
- } /* if (data[1]==0) */
- else {
- if (data[1] == 1) {
- switch (ui_NoOfChannel) {
- case 2:
- data[0] =
- (data[0] << (2 *
- data[2])) | ui_Temp;
- break;
- case 4:
- data[0] =
- (data[0] << (4 *
- data[2])) | ui_Temp;
- break;
- case 8:
- data[0] =
- (data[0] << (8 *
- data[2])) | ui_Temp;
- break;
- case 15:
- data[0] = data[0] | ui_Temp;
- break;
- default:
- comedi_error(dev, " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
- } /* switch(ui_NoOfChannels) */
- outw(data[0],
- devpriv->iobase + APCI2016_DIGITAL_OP);
- } /* if (data[1]==1) */
- else {
- printk("\nSpecified channel not supported\n");
- } /* else if (data[1]==1) */
- } /* else if (data[1]==0) */
- } /* if (data[3]==0) */
- else {
- if (data[3] == 1) {
- if (data[1] == 0) {
- data[0] = ~data[0] & 0x1;
- ui_Temp1 = 1;
- ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
- data[0] = data[0] & ui_Temp;
- outw(data[0],
- devpriv->iobase + APCI2016_DIGITAL_OP);
- } /* if (data[1]==0) */
- else {
- if (data[1] == 1) {
- switch (ui_NoOfChannel) {
- case 2:
- data[0] = ~data[0] & 0x3;
- ui_Temp1 = 3;
- ui_Temp1 =
- ui_Temp1 << 2 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (2 *
- data
- [2])) ^
- 0xffff) & ui_Temp;
- break;
- case 4:
- data[0] = ~data[0] & 0xf;
- ui_Temp1 = 15;
- ui_Temp1 =
- ui_Temp1 << 4 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (4 *
- data
- [2])) ^
- 0xffff) & ui_Temp;
- break;
- case 8:
- data[0] = ~data[0] & 0xff;
- ui_Temp1 = 255;
- ui_Temp1 =
- ui_Temp1 << 8 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (8 *
- data
- [2])) ^
- 0xffff) & ui_Temp;
- break;
- case 15:
- break;
- default:
- comedi_error(dev,
- " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
- } /* switch(ui_NoOfChannels) */
- outw(data[0],
- devpriv->iobase +
- APCI2016_DIGITAL_OP);
- } /* if(data[1]==1) */
- else {
- printk("\nSpecified channel not supported\n");
- } /* else if(data[1]==1) */
- } /* elseif(data[1]==0) */
- } /* if(data[3]==1); */
- else {
- printk("\nSpecified functionality does not exist\n");
- return -EINVAL;
- } /* if else data[3]==1) */
- } /* if else data[3]==0) */
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2016_BitsDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Read value of the selected channel or port |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int ui_NoOfChannels : No Of Channels To read |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_Temp;
- unsigned int ui_NoOfChannel;
- ui_NoOfChannel = CR_CHAN(insn->chanspec);
- if (ui_NoOfChannel > 15) {
- comedi_error(dev,
- "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
- return -EINVAL;
- } /* if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15)) */
- if ((data[0] != 0) && (data[0] != 1)) {
- comedi_error(dev,
- "Invalid Data[0] value !!!, Data[0] should be 0 or 1\n");
- return -EINVAL;
- } /* if ((data[0]!=0) && (data[0]!=1)) */
- ui_Temp = data[0];
- *data = inw(devpriv->iobase + APCI2016_DIGITAL_OP_RW);
- if (ui_Temp == 0) {
- *data = (*data >> ui_NoOfChannel) & 0x1;
- } /* if (ui_Temp==0) */
- else {
- if (ui_Temp == 1) {
- switch (ui_NoOfChannel) {
- case 2:
- *data = (*data >> (2 * data[1])) & 3;
- break;
-
- case 4:
- *data = (*data >> (4 * data[1])) & 15;
- break;
-
- case 8:
- *data = (*data >> (8 * data[1])) & 255;
- break;
-
- case 15:
- break;
-
- default:
- comedi_error(dev, " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
- } /* switch(ui_NoOfChannel) */
- } /* if (ui_Temp==1) */
- else {
- printk("\nSpecified channel not supported \n");
- } /* else if (ui_Temp==1) */
- } /* if (ui_Temp==0) */
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2016_ConfigWatchdog |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Configures The Watchdog |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure |
-| struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
-
- if (data[0] == 0) {
- /* Disable the watchdog */
- outw(0x0,
- devpriv->i_IobaseAddon +
- APCI2016_WATCHDOG_ENABLEDISABLE);
- /* Loading the Reload value */
- outw(data[1],
- devpriv->i_IobaseAddon +
- APCI2016_WATCHDOG_RELOAD_VALUE);
- data[1] = data[1] >> 16;
- outw(data[1],
- devpriv->i_IobaseAddon +
- APCI2016_WATCHDOG_RELOAD_VALUE + 2);
- } else {
- printk("\nThe input parameters are wrong\n");
- }
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2016_StartStopWriteWatchdog |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Start / Stop The Watchdog |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure |
-| struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
-
- switch (data[0]) {
- case 0: /* stop the watchdog */
- outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE); /* disable the watchdog */
- break;
- case 1: /* start the watchdog */
- outw(0x0001,
- devpriv->i_IobaseAddon +
- APCI2016_WATCHDOG_ENABLEDISABLE);
- break;
- case 2: /* Software trigger */
- outw(0x0201,
- devpriv->i_IobaseAddon +
- APCI2016_WATCHDOG_ENABLEDISABLE);
- break;
- default:
- printk("\nSpecified functionality does not exist\n");
- return -EINVAL;
- } /* switch(data[0]) */
-
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2016_ReadWatchdog |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Read The Watchdog |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure |
-| struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI2016_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- udelay(5);
- data[0] = inw(devpriv->i_IobaseAddon + APCI2016_WATCHDOG_STATUS) & 0x1;
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2016_Reset(struct comedi_device *dev) | |
-+----------------------------------------------------------------------------+
-| Task :resets all the registers |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI2016_Reset(struct comedi_device *dev)
-{
- outw(0x0, devpriv->iobase + APCI2016_DIGITAL_OP); /* Resets the digital output channels */
- outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE);
- outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE);
- outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE + 2);
- return 0;
-}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h
deleted file mode 100644
index c42612af0fa..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-/********* Definitions for APCI-2016 card *****/
-
-#define APCI2016_BOARD_VENDOR_ID 0x15B8
-#define APCI2016_ADDRESS_RANGE 8
-
-/* DIGITAL INPUT-OUTPUT DEFINE */
-
-#define APCI2016_DIGITAL_OP 0x04
-#define APCI2016_DIGITAL_OP_RW 4
-
-/* ADDIDATA Enable Disable */
-
-#define ADDIDATA_ENABLE 1
-#define ADDIDATA_DISABLE 0
-
-/* TIMER COUNTER WATCHDOG DEFINES */
-
-#define ADDIDATA_WATCHDOG 2
-#define APCI2016_DIGITAL_OP_WATCHDOG 0
-#define APCI2016_WATCHDOG_ENABLEDISABLE 12
-#define APCI2016_WATCHDOG_RELOAD_VALUE 4
-#define APCI2016_WATCHDOG_STATUS 16
-
-/* Hardware Layer functions for Apci2016 */
-
-/* DO */
-int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/*
-* TIMER
-* timer value is passed as u seconds
-*/
-
-int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int i_APCI2016_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* Interrupt functions..... */
-
-/* void v_APCI2016_Interrupt(int irq, void *d); */
-
-/* void v_APCI2016_Interrupt(int irq, void *d); */
-/* RESET */
-int i_APCI2016_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
deleted file mode 100644
index 002297dfe33..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
+++ /dev/null
@@ -1,579 +0,0 @@
-/**
-@verbatim
-
-Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
-
- ADDI-DATA GmbH
- Dieselstrasse 3
- D-77833 Ottersweier
- Tel: +19(0)7223/9493-0
- Fax: +49(0)7223/9493-92
- http://www.addi-data.com
- info@addi-data.com
-
-This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
-@endverbatim
-*/
-/*
-
- +-----------------------------------------------------------------------+
- | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
- +-----------------------------------------------------------------------+
- | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
- | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
- +-------------------------------+---------------------------------------+
- | Project : APCI-2032 | Compiler : GCC |
- | Module name : hwdrv_apci2032.c| Version : 2.96 |
- +-------------------------------+---------------------------------------+
- | Project manager: Eric Stolz | Date : 02/12/2002 |
- +-------------------------------+---------------------------------------+
- | Description : Hardware Layer Access For APCI-2032 |
- +-----------------------------------------------------------------------+
- | UPDATES |
- +----------+-----------+------------------------------------------------+
- | Date | Author | Description of updates |
- +----------+-----------+------------------------------------------------+
- | | | |
- | | | |
- | | | |
- +----------+-----------+------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
-
-#include "hwdrv_apci2032.h"
-static unsigned int ui_InterruptData, ui_Type;
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2032_ConfigDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Configures The Digital Output Subdevice. |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int *data : Data Pointer contains |
-| configuration parameters as below |
-| |
-| data[1] : 1 Enable VCC Interrupt |
-| 0 Disable VCC Interrupt |
-| data[2] : 1 Enable CC Interrupt |
-| 0 Disable CC Interrupt |
-| |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ul_Command = 0;
- devpriv->tsk_Current = current;
-
- if ((data[0] != 0) && (data[0] != 1)) {
- comedi_error(dev,
- "Not a valid Data !!! ,Data should be 1 or 0\n");
- return -EINVAL;
- } /* if ( (data[0]!=0) && (data[0]!=1) ) */
- if (data[0]) {
- devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
- } /* if (data[0]) */
- else {
- devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
- } /* else if (data[0]) */
-
- if (data[1] == ADDIDATA_ENABLE) {
- ul_Command = ul_Command | 0x1;
- } /* if (data[1] == ADDIDATA_ENABLE) */
- else {
- ul_Command = ul_Command & 0xFFFFFFFE;
- } /* elseif (data[1] == ADDIDATA_ENABLE) */
- if (data[2] == ADDIDATA_ENABLE) {
- ul_Command = ul_Command | 0x2;
- } /* if (data[2] == ADDIDATA_ENABLE) */
- else {
- ul_Command = ul_Command & 0xFFFFFFFD;
- } /* elseif (data[2] == ADDIDATA_ENABLE) */
- outl(ul_Command, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);
- ui_InterruptData = inl(devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2032_WriteDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Writes port value To the selected port |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int ui_NoOfChannels : No Of Channels To Write |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_Temp, ui_Temp1;
- unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
- if (devpriv->b_OutputMemoryStatus) {
- ui_Temp = inl(devpriv->iobase + APCI2032_DIGITAL_OP);
-
- } /* if(devpriv->b_OutputMemoryStatus ) */
- else {
- ui_Temp = 0;
- } /* if(devpriv->b_OutputMemoryStatus ) */
- if (data[3] == 0) {
- if (data[1] == 0) {
- data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
- outl(data[0], devpriv->iobase + APCI2032_DIGITAL_OP);
- } /* if(data[1]==0) */
- else {
- if (data[1] == 1) {
- switch (ui_NoOfChannel) {
-
- case 2:
- data[0] =
- (data[0] << (2 *
- data[2])) | ui_Temp;
- break;
-
- case 4:
- data[0] =
- (data[0] << (4 *
- data[2])) | ui_Temp;
- break;
-
- case 8:
- data[0] =
- (data[0] << (8 *
- data[2])) | ui_Temp;
- break;
-
- case 16:
- data[0] =
- (data[0] << (16 *
- data[2])) | ui_Temp;
- break;
- case 31:
- data[0] = data[0] | ui_Temp;
- break;
-
- default:
- comedi_error(dev, " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
-
- } /* switch(ui_NoOfChannels) */
-
- outl(data[0],
- devpriv->iobase + APCI2032_DIGITAL_OP);
- } /* if(data[1]==1) */
- else {
- printk("\nSpecified channel not supported\n");
- } /* else if(data[1]==1) */
- } /* elseif(data[1]==0) */
- } /* if(data[3]==0) */
- else {
- if (data[3] == 1) {
- if (data[1] == 0) {
- data[0] = ~data[0] & 0x1;
- ui_Temp1 = 1;
- ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- (data[0] << ui_NoOfChannel) ^
- 0xffffffff;
- data[0] = data[0] & ui_Temp;
- outl(data[0],
- devpriv->iobase + APCI2032_DIGITAL_OP);
- } /* if(data[1]==0) */
- else {
- if (data[1] == 1) {
- switch (ui_NoOfChannel) {
-
- case 2:
- data[0] = ~data[0] & 0x3;
- ui_Temp1 = 3;
- ui_Temp1 =
- ui_Temp1 << 2 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (2 *
- data
- [2])) ^
- 0xffffffff) & ui_Temp;
- break;
-
- case 4:
- data[0] = ~data[0] & 0xf;
- ui_Temp1 = 15;
- ui_Temp1 =
- ui_Temp1 << 4 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (4 *
- data
- [2])) ^
- 0xffffffff) & ui_Temp;
- break;
-
- case 8:
- data[0] = ~data[0] & 0xff;
- ui_Temp1 = 255;
- ui_Temp1 =
- ui_Temp1 << 8 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (8 *
- data
- [2])) ^
- 0xffffffff) & ui_Temp;
- break;
-
- case 16:
- data[0] = ~data[0] & 0xffff;
- ui_Temp1 = 65535;
- ui_Temp1 =
- ui_Temp1 << 16 *
- data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (16 *
- data
- [2])) ^
- 0xffffffff) & ui_Temp;
- break;
-
- case 31:
- break;
- default:
- comedi_error(dev,
- " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
-
- } /* switch(ui_NoOfChannels) */
-
- outl(data[0],
- devpriv->iobase +
- APCI2032_DIGITAL_OP);
- } /* if(data[1]==1) */
- else {
- printk("\nSpecified channel not supported\n");
- } /* else if(data[1]==1) */
- } /* elseif(data[1]==0) */
- } /* if(data[3]==1); */
- else {
- printk("\nSpecified functionality does not exist\n");
- return -EINVAL;
- } /* if else data[3]==1) */
- } /* if else data[3]==0) */
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2032_ReadDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Read value of the selected channel or port |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int ui_NoOfChannels : No Of Channels To read |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_Temp;
- unsigned int ui_NoOfChannel;
- ui_NoOfChannel = CR_CHAN(insn->chanspec);
- ui_Temp = data[0];
- *data = inl(devpriv->iobase + APCI2032_DIGITAL_OP_RW);
- if (ui_Temp == 0) {
- *data = (*data >> ui_NoOfChannel) & 0x1;
- } /* if (ui_Temp==0) */
- else {
- if (ui_Temp == 1) {
- switch (ui_NoOfChannel) {
-
- case 2:
- *data = (*data >> (2 * data[1])) & 3;
- break;
-
- case 4:
- *data = (*data >> (4 * data[1])) & 15;
- break;
-
- case 8:
- *data = (*data >> (8 * data[1])) & 255;
- break;
-
- case 16:
- *data = (*data >> (16 * data[1])) & 65535;
- break;
-
- case 31:
- break;
-
- default:
- comedi_error(dev, " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
-
- } /* switch(ui_NoOfChannels) */
- } /* if (ui_Temp==1) */
- else {
- printk("\nSpecified channel not supported \n");
- } /* elseif (ui_Temp==1) */
- }
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2032_ConfigWatchdog(comedi_device
-| *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
-| |
-+----------------------------------------------------------------------------+
-| Task : Configures The Watchdog |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure
-| struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI2032_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- if (data[0] == 0) {
- /* Disable the watchdog */
- outl(0x0,
- devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
- APCI2032_TCW_PROG);
- /* Loading the Reload value */
- outl(data[1],
- devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
- APCI2032_TCW_RELOAD_VALUE);
- } else {
- printk("\nThe input parameters are wrong\n");
- return -EINVAL;
- }
-
- return insn->n;
-}
-
- /*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI2032_StartStopWriteWatchdog |
- | (struct comedi_device *dev,struct comedi_subdevice *s,
- struct comedi_insn *insn,unsigned int *data); |
- +----------------------------------------------------------------------------+
- | Task : Start / Stop The Watchdog |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | struct comedi_subdevice *s, :pointer to subdevice structure
- struct comedi_insn *insn :pointer to insn structure |
- | unsigned int *data : Data Pointer to read status |
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
- */
-
-int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- switch (data[0]) {
- case 0: /* stop the watchdog */
- outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); /* disable the watchdog */
- break;
- case 1: /* start the watchdog */
- outl(0x0001,
- devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
- APCI2032_TCW_PROG);
- break;
- case 2: /* Software trigger */
- outl(0x0201,
- devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
- APCI2032_TCW_PROG);
- break;
- default:
- printk("\nSpecified functionality does not exist\n");
- return -EINVAL;
- }
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2032_ReadWatchdog |
-| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
-| unsigned int *data); |
-+----------------------------------------------------------------------------+
-| Task : Read The Watchdog |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure
-| struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI2032_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
-
- data[0] =
- inl(devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
- APCI2032_TCW_TRIG_STATUS) & 0x1;
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : void v_APCI2032_Interrupt |
-| (int irq , void *d) |
-+----------------------------------------------------------------------------+
-| Task : Writes port value To the selected port |
-+----------------------------------------------------------------------------+
-| Input Parameters : int irq : irq number |
-| void *d : void pointer |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-void v_APCI2032_Interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- unsigned int ui_DO;
-
- ui_DO = inl(devpriv->iobase + APCI2032_DIGITAL_OP_IRQ) & 0x1; /* Check if VCC OR CC interrupt has occurred. */
-
- if (ui_DO == 0) {
- printk("\nInterrupt from unKnown source\n");
- } /* if(ui_DO==0) */
- if (ui_DO) {
- /* Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt. */
- ui_Type =
- inl(devpriv->iobase +
- APCI2032_DIGITAL_OP_INTERRUPT_STATUS) & 0x3;
- outl(0x0,
- devpriv->iobase + APCI2032_DIGITAL_OP +
- APCI2032_DIGITAL_OP_INTERRUPT);
- if (ui_Type == 1) {
- /* Sends signal to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
- } /* if (ui_Type==1) */
- else {
- if (ui_Type == 2) {
- /* Sends signal to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
- } /* if (ui_Type==2) */
- } /* else if (ui_Type==1) */
- } /* if(ui_DO) */
-
- return;
-
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2032_ReadInterruptStatus |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task :Reads the interrupt status register |
-+----------------------------------------------------------------------------+
-| Input Parameters : |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- *data = ui_Type;
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2032_Reset(struct comedi_device *dev) |
-| |
-+----------------------------------------------------------------------------+
-| Task :Resets the registers of the card |
-+----------------------------------------------------------------------------+
-| Input Parameters : |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI2032_Reset(struct comedi_device *dev)
-{
- devpriv->b_DigitalOutputRegister = 0;
- ui_Type = 0;
- outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP); /* Resets the output channels */
- outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT); /* Disables the interrupt. */
- outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); /* disable the watchdog */
- outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_RELOAD_VALUE); /* reload=0 */
- return 0;
-}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h
deleted file mode 100644
index ab145e7c940..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-/********* Definitions for APCI-2032 card *****/
-
-/* Card Specific information */
-#define APCI2032_BOARD_VENDOR_ID 0x15B8
-#define APCI2032_ADDRESS_RANGE 63
-
-/* DIGITAL INPUT-OUTPUT DEFINE */
-
-#define APCI2032_DIGITAL_OP 0
-#define APCI2032_DIGITAL_OP_RW 0
-#define APCI2032_DIGITAL_OP_INTERRUPT 4
-#define APCI2032_DIGITAL_OP_IRQ 12
-
-/* Digital Output Interrupt Status */
-#define APCI2032_DIGITAL_OP_INTERRUPT_STATUS 8
-
-/* Digital Output Interrupt Enable Disable. */
-#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1
-#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE
-#define APCI2032_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2
-#define APCI2032_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD
-
-/* ADDIDATA Enable Disable */
-
-#define ADDIDATA_ENABLE 1
-#define ADDIDATA_DISABLE 0
-
-/* TIMER COUNTER WATCHDOG DEFINES */
-
-#define ADDIDATA_WATCHDOG 2
-#define APCI2032_DIGITAL_OP_WATCHDOG 16
-#define APCI2032_TCW_RELOAD_VALUE 4
-#define APCI2032_TCW_TIMEBASE 8
-#define APCI2032_TCW_PROG 12
-#define APCI2032_TCW_TRIG_STATUS 16
-#define APCI2032_TCW_IRQ 20
-
-/* Hardware Layer functions for Apci2032 */
-
-/* DO */
-int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* TIMER
- * timer value is passed as u seconds
-*/
-
-int i_APCI2032_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI2032_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* Interrupt functions..... */
-
-void v_APCI2032_Interrupt(int irq, void *d);
-
-/* Reset functions */
-int i_APCI2032_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
index 3d378b5ecbc..9d4a117aad4 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
@@ -46,354 +46,54 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+----------+-----------+------------------------------------------------+
*/
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
-#include "hwdrv_apci2200.h"
+/********* Definitions for APCI-2200 card *****/
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2200_Read1DigitalInput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Return the status of the digital input |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure
-| struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI2200_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_TmpValue = 0;
- unsigned int ui_Channel;
- ui_Channel = CR_CHAN(insn->chanspec);
- if (ui_Channel <= 7) {
- ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
- *data = (ui_TmpValue >> ui_Channel) & 0x1;
- } /* if(ui_Channel >= 0 && ui_Channel <=7) */
- else {
- printk("\nThe specified channel does not exist\n");
- return -EINVAL; /* "sorry channel spec wrong " */
- } /* else if(ui_Channel >= 0 && ui_Channel <=7) */
+/* Card Specific information */
+#define APCI2200_ADDRESS_RANGE 64
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2200_ReadMoreDigitalInput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Return the status of the Requested digital inputs |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure
-| struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
+/* DIGITAL INPUT-OUTPUT DEFINE */
-int i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
+#define APCI2200_DIGITAL_OP 4
+#define APCI2200_DIGITAL_IP 0
- unsigned int ui_PortValue = data[0];
- unsigned int ui_Mask = 0;
- unsigned int ui_NoOfChannels;
+/* TIMER COUNTER WATCHDOG DEFINES */
- ui_NoOfChannels = CR_CHAN(insn->chanspec);
+#define APCI2200_WATCHDOG 0x08
+#define APCI2200_WATCHDOG_ENABLEDISABLE 12
+#define APCI2200_WATCHDOG_RELOAD_VALUE 4
+#define APCI2200_WATCHDOG_STATUS 16
- *data = (unsigned int) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
- switch (ui_NoOfChannels) {
- case 2:
- ui_Mask = 3;
- *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
- break;
- case 4:
- ui_Mask = 15;
- *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
- break;
- case 7:
- break;
+static int apci2200_di_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct addi_private *devpriv = dev->private;
- default:
- printk("\nWrong parameters\n");
- return -EINVAL; /* "sorry channel spec wrong " */
- break;
- } /* switch(ui_NoOfChannels) */
+ data[1] = inw(devpriv->iobase + APCI2200_DIGITAL_IP);
return insn->n;
}
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2200_ConfigDigitalOutput (struct comedi_device *dev,
-| struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Configures The Digital Output Subdevice. |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int *data : Data Pointer contains |
-| configuration parameters as below |
-| struct comedi_subdevice *s, :pointer to subdevice structure
-| struct comedi_insn *insn :pointer to insn structure |
-| data[0] :1:Memory on |
-| 0:Memory off |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int apci2200_do_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- devpriv->b_OutputMemoryStatus = data[0];
- return insn->n;
-}
+ struct addi_private *devpriv = dev->private;
+ unsigned int mask = data[0];
+ unsigned int bits = data[1];
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2200_WriteDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
-| unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Writes port value To the selected port |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure
-| struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
+ s->state = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
+ if (mask) {
+ s->state &= ~mask;
+ s->state |= (bits & mask);
-int i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_Temp, ui_Temp1;
- unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
- if (devpriv->b_OutputMemoryStatus) {
- ui_Temp = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
+ outw(s->state, devpriv->iobase + APCI2200_DIGITAL_OP);
+ }
- } /* if(devpriv->b_OutputMemoryStatus ) */
- else {
- ui_Temp = 0;
- } /* if(devpriv->b_OutputMemoryStatus ) */
- if (data[3] == 0) {
- if (data[1] == 0) {
- data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
- outw(data[0], devpriv->iobase + APCI2200_DIGITAL_OP);
- } /* if(data[1]==0) */
- else {
- if (data[1] == 1) {
- switch (ui_NoOfChannel) {
-
- case 2:
- data[0] =
- (data[0] << (2 *
- data[2])) | ui_Temp;
- break;
-
- case 4:
- data[0] =
- (data[0] << (4 *
- data[2])) | ui_Temp;
- break;
-
- case 8:
- data[0] =
- (data[0] << (8 *
- data[2])) | ui_Temp;
- break;
- case 15:
- data[0] = data[0] | ui_Temp;
- break;
- default:
- comedi_error(dev, " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
-
- } /* switch(ui_NoOfChannels) */
-
- outw(data[0],
- devpriv->iobase + APCI2200_DIGITAL_OP);
- } /* if(data[1]==1) */
- else {
- printk("\nSpecified channel not supported\n");
- } /* else if(data[1]==1) */
- } /* elseif(data[1]==0) */
- } /* if(data[3]==0) */
- else {
- if (data[3] == 1) {
- if (data[1] == 0) {
- data[0] = ~data[0] & 0x1;
- ui_Temp1 = 1;
- ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
- data[0] = data[0] & ui_Temp;
- outw(data[0],
- devpriv->iobase + APCI2200_DIGITAL_OP);
- } /* if(data[1]==0) */
- else {
- if (data[1] == 1) {
- switch (ui_NoOfChannel) {
-
- case 2:
- data[0] = ~data[0] & 0x3;
- ui_Temp1 = 3;
- ui_Temp1 =
- ui_Temp1 << 2 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (2 *
- data
- [2])) ^
- 0xffff) & ui_Temp;
- break;
-
- case 4:
- data[0] = ~data[0] & 0xf;
- ui_Temp1 = 15;
- ui_Temp1 =
- ui_Temp1 << 4 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (4 *
- data
- [2])) ^
- 0xffff) & ui_Temp;
- break;
-
- case 8:
- data[0] = ~data[0] & 0xff;
- ui_Temp1 = 255;
- ui_Temp1 =
- ui_Temp1 << 8 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (8 *
- data
- [2])) ^
- 0xffff) & ui_Temp;
- break;
- case 15:
- break;
-
- default:
- comedi_error(dev,
- " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
-
- } /* switch(ui_NoOfChannels) */
-
- outw(data[0],
- devpriv->iobase +
- APCI2200_DIGITAL_OP);
- } /* if(data[1]==1) */
- else {
- printk("\nSpecified channel not supported\n");
- } /* else if(data[1]==1) */
- } /* elseif(data[1]==0) */
- } /* if(data[3]==1); */
- else {
- printk("\nSpecified functionality does not exist\n");
- return -EINVAL;
- } /* if else data[3]==1) */
- } /* if else data[3]==0) */
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI2200_ReadDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
-| unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Read value of the selected channel or port |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s, :pointer to subdevice structure
-| struct comedi_insn *insn :pointer to insn structure |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
+ data[1] = s->state;
- unsigned int ui_Temp;
- unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
- ui_Temp = data[0];
- *data = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
- if (ui_Temp == 0) {
- *data = (*data >> ui_NoOfChannel) & 0x1;
- } /* if(ui_Temp==0) */
- else {
- if (ui_Temp == 1) {
- switch (ui_NoOfChannel) {
-
- case 2:
- *data = (*data >> (2 * data[1])) & 3;
- break;
-
- case 4:
- *data = (*data >> (4 * data[1])) & 15;
- break;
-
- case 8:
- *data = (*data >> (8 * data[1])) & 255;
- break;
-
- case 15:
- break;
-
- default:
- comedi_error(dev, " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
-
- } /* switch(ui_NoOfChannels) */
- } /* if(ui_Temp==1) */
- else {
- printk("\nSpecified channel not supported \n");
- } /* elseif(ui_Temp==1) */
- } /* elseif(ui_Temp==0) */
return insn->n;
}
@@ -418,9 +118,13 @@ int i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev
+----------------------------------------------------------------------------+
*/
-int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI2200_ConfigWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
+
if (data[0] == 0) {
/* Disable the watchdog */
outw(0x0,
@@ -464,9 +168,13 @@ int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice
+----------------------------------------------------------------------------+
*/
-int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
+
switch (data[0]) {
case 0: /* stop the watchdog */
outw(0x0, devpriv->iobase + APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE); /* disable the watchdog */
@@ -509,9 +217,13 @@ int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_s
+----------------------------------------------------------------------------+
*/
-int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI2200_ReadWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
+
data[0] =
inw(devpriv->iobase + APCI2200_WATCHDOG +
APCI2200_WATCHDOG_STATUS) & 0x1;
@@ -533,8 +245,10 @@ int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *
+----------------------------------------------------------------------------+
*/
-int i_APCI2200_Reset(struct comedi_device *dev)
+static int i_APCI2200_Reset(struct comedi_device *dev)
{
+ struct addi_private *devpriv = dev->private;
+
outw(0x0, devpriv->iobase + APCI2200_DIGITAL_OP); /* RESETS THE DIGITAL OUTPUTS */
outw(0x0,
devpriv->iobase + APCI2200_WATCHDOG +
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h
deleted file mode 100644
index 83f42af84b8..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-/********* Definitions for APCI-2200 card *****/
-
-/* Card Specific information */
-#define APCI2200_BOARD_VENDOR_ID 0x15b8
-#define APCI2200_ADDRESS_RANGE 64
-
-/* DIGITAL INPUT-OUTPUT DEFINE */
-
-#define APCI2200_DIGITAL_OP 4
-#define APCI2200_DIGITAL_IP 0
-
-/* TIMER COUNTER WATCHDOG DEFINES */
-
-#define APCI2200_WATCHDOG 0x08
-#define APCI2200_WATCHDOG_ENABLEDISABLE 12
-#define APCI2200_WATCHDOG_RELOAD_VALUE 4
-#define APCI2200_WATCHDOG_STATUS 16
-
-/* Hardware Layer functions for Apci2200 */
-
-/* Digital Input */
-int i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI2200_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* Digital Output */
-int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* TIMER */
-int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* reset */
-int i_APCI2200_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
index f406dfb2a67..74065baa3c0 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
@@ -44,8 +44,203 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+----------+-----------+------------------------------------------------+
*/
-#include "hwdrv_apci3120.h"
-static unsigned int ui_Temp;
+/*
+ * ADDON RELATED ADDITIONS
+ */
+/* Constant */
+#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00
+#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200
+#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L
+#define APCI3120_AMWEN_ENABLE 0x02
+#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01
+#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L
+#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L
+#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L
+#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
+#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0
+#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0
+
+/* ADD_ON ::: this needed since apci supports 16 bit interface to add on */
+#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C
+#define APCI3120_ADD_ON_AGCSTS_HIGH (APCI3120_ADD_ON_AGCSTS_LOW + 2)
+#define APCI3120_ADD_ON_MWAR_LOW 0x24
+#define APCI3120_ADD_ON_MWAR_HIGH (APCI3120_ADD_ON_MWAR_LOW + 2)
+#define APCI3120_ADD_ON_MWTC_LOW 0x058
+#define APCI3120_ADD_ON_MWTC_HIGH (APCI3120_ADD_ON_MWTC_LOW + 2)
+
+/* AMCC */
+#define APCI3120_AMCC_OP_MCSR 0x3C
+#define APCI3120_AMCC_OP_REG_INTCSR 0x38
+
+/* for transfer count enable bit */
+#define AGCSTS_TC_ENABLE 0x10000000
+
+/* used for test on mixture of BIP/UNI ranges */
+#define APCI3120_BIPOLAR_RANGES 4
+
+#define APCI3120_ADDRESS_RANGE 16
+
+#define APCI3120_DISABLE 0
+#define APCI3120_ENABLE 1
+
+#define APCI3120_START 1
+#define APCI3120_STOP 0
+
+#define APCI3120_EOC_MODE 1
+#define APCI3120_EOS_MODE 2
+#define APCI3120_DMA_MODE 3
+
+/* DIGITAL INPUT-OUTPUT DEFINE */
+
+#define APCI3120_DIGITAL_OUTPUT 0x0d
+#define APCI3120_RD_STATUS 0x02
+#define APCI3120_RD_FIFO 0x00
+
+/* digital output insn_write ON /OFF selection */
+#define APCI3120_SET4DIGITALOUTPUTON 1
+#define APCI3120_SET4DIGITALOUTPUTOFF 0
+
+/* analog output SELECT BIT */
+#define APCI3120_ANALOG_OP_CHANNEL_1 0x0000
+#define APCI3120_ANALOG_OP_CHANNEL_2 0x4000
+#define APCI3120_ANALOG_OP_CHANNEL_3 0x8000
+#define APCI3120_ANALOG_OP_CHANNEL_4 0xc000
+#define APCI3120_ANALOG_OP_CHANNEL_5 0x0000
+#define APCI3120_ANALOG_OP_CHANNEL_6 0x4000
+#define APCI3120_ANALOG_OP_CHANNEL_7 0x8000
+#define APCI3120_ANALOG_OP_CHANNEL_8 0xc000
+
+/* Enable external trigger bit in nWrAddress */
+#define APCI3120_ENABLE_EXT_TRIGGER 0x8000
+
+/* ANALOG OUTPUT AND INPUT DEFINE */
+#define APCI3120_UNIPOLAR 0x80
+#define APCI3120_BIPOLAR 0x00
+#define APCI3120_ANALOG_OUTPUT_1 0x08
+#define APCI3120_ANALOG_OUTPUT_2 0x0a
+#define APCI3120_1_GAIN 0x00
+#define APCI3120_2_GAIN 0x10
+#define APCI3120_5_GAIN 0x20
+#define APCI3120_10_GAIN 0x30
+#define APCI3120_SEQ_RAM_ADDRESS 0x06
+#define APCI3120_RESET_FIFO 0x0c
+#define APCI3120_TIMER_0_MODE_2 0x01
+#define APCI3120_TIMER_0_MODE_4 0x2
+#define APCI3120_SELECT_TIMER_0_WORD 0x00
+#define APCI3120_ENABLE_TIMER0 0x1000
+#define APCI3120_CLEAR_PR 0xf0ff
+#define APCI3120_CLEAR_PA 0xfff0
+#define APCI3120_CLEAR_PA_PR (APCI3120_CLEAR_PR & APCI3120_CLEAR_PA)
+
+/* nWrMode_Select */
+#define APCI3120_ENABLE_SCAN 0x8
+#define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN)
+#define APCI3120_ENABLE_EOS_INT 0x2
+
+#define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT)
+#define APCI3120_ENABLE_EOC_INT 0x1
+#define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT)
+#define APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER \
+ (APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
+#define APCI3120_DISABLE_ALL_INTERRUPT \
+ (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
+
+/* status register bits */
+#define APCI3120_EOC 0x8000
+#define APCI3120_EOS 0x2000
+
+/* software trigger dummy register */
+#define APCI3120_START_CONVERSION 0x02
+
+/* TIMER DEFINE */
+#define APCI3120_QUARTZ_A 70
+#define APCI3120_QUARTZ_B 50
+#define APCI3120_TIMER 1
+#define APCI3120_WATCHDOG 2
+#define APCI3120_TIMER_DISABLE 0
+#define APCI3120_TIMER_ENABLE 1
+#define APCI3120_ENABLE_TIMER2 0x4000
+#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2)
+#define APCI3120_ENABLE_TIMER_INT 0x04
+#define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT)
+#define APCI3120_WRITE_MODE_SELECT 0x0e
+#define APCI3120_SELECT_TIMER_0_WORD 0x00
+#define APCI3120_SELECT_TIMER_1_WORD 0x01
+#define APCI3120_TIMER_1_MODE_2 0x4
+
+/* $$ BIT FOR MODE IN nCsTimerCtr1 */
+#define APCI3120_TIMER_2_MODE_0 0x0
+#define APCI3120_TIMER_2_MODE_2 0x10
+#define APCI3120_TIMER_2_MODE_5 0x30
+
+/* $$ BIT FOR MODE IN nCsTimerCtr0 */
+#define APCI3120_SELECT_TIMER_2_LOW_WORD 0x02
+#define APCI3120_SELECT_TIMER_2_HIGH_WORD 0x03
+
+#define APCI3120_TIMER_CRT0 0x0d
+#define APCI3120_TIMER_CRT1 0x0c
+
+#define APCI3120_TIMER_VALUE 0x04
+#define APCI3120_TIMER_STATUS_REGISTER 0x0d
+#define APCI3120_RD_STATUS 0x02
+#define APCI3120_WR_ADDRESS 0x00
+#define APCI3120_ENABLE_WATCHDOG 0x20
+#define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG)
+#define APCI3120_ENABLE_TIMER_COUNTER 0x10
+#define APCI3120_DISABLE_TIMER_COUNTER (~APCI3120_ENABLE_TIMER_COUNTER)
+#define APCI3120_FC_TIMER 0x1000
+#define APCI3120_ENABLE_TIMER0 0x1000
+#define APCI3120_ENABLE_TIMER1 0x2000
+#define APCI3120_ENABLE_TIMER2 0x4000
+#define APCI3120_DISABLE_TIMER0 (~APCI3120_ENABLE_TIMER0)
+#define APCI3120_DISABLE_TIMER1 (~APCI3120_ENABLE_TIMER1)
+#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2)
+
+#define APCI3120_TIMER2_SELECT_EOS 0xc0
+#define APCI3120_COUNTER 3
+#define APCI3120_DISABLE_ALL_TIMER (APCI3120_DISABLE_TIMER0 & \
+ APCI3120_DISABLE_TIMER1 & \
+ APCI3120_DISABLE_TIMER2)
+
+#define MAX_ANALOGINPUT_CHANNELS 32
+
+struct str_AnalogReadInformation {
+ /* EOC or EOS */
+ unsigned char b_Type;
+ /* Interrupt use or not */
+ unsigned char b_InterruptFlag;
+ /* Selection of the conversion time */
+ unsigned int ui_ConvertTiming;
+ /* Number of channel to read */
+ unsigned char b_NbrOfChannel;
+ /* Number of the channel to be read */
+ unsigned int ui_ChannelList[MAX_ANALOGINPUT_CHANNELS];
+ /* Gain of each channel */
+ unsigned int ui_RangeList[MAX_ANALOGINPUT_CHANNELS];
+};
+
+/* ANALOG INPUT RANGE */
+static const struct comedi_lrange range_apci3120_ai = {
+ 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+/* ANALOG OUTPUT RANGE */
+static const struct comedi_lrange range_apci3120_ao = {
+ 2, {
+ BIP_RANGE(10),
+ UNI_RANGE(10)
+ }
+};
+
/* FUNCTION DEFINITIONS */
@@ -55,28 +250,13 @@ static unsigned int ui_Temp;
+----------------------------------------------------------------------------+
*/
-/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev,|
-| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Calls card specific function |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| struct comedi_insn *insn |
-| unsigned int *data |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
unsigned int i;
if ((data[0] != APCI3120_EOC_MODE) && (data[0] != APCI3120_EOS_MODE))
@@ -91,7 +271,7 @@ int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_su
for (i = 0; i < data[3]; i++) {
if (CR_CHAN(data[4 + i]) >=
- devpriv->s_EeParameters.i_NbrAiChannel) {
+ this_board->i_NbrAiChannel) {
printk("bad channel list\n");
return -2;
}
@@ -121,31 +301,72 @@ int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_su
}
/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, |
-| struct comedi_subdevice *s,struct comedi_insn *insn, unsigned int *data) |
-| |
-+----------------------------------------------------------------------------+
-| Task : card specific function |
-| Reads analog input in synchronous mode |
-| EOC and EOS is selected as per configured |
-| if no conversion time is set uses default conversion |
-| time 10 microsec. |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| struct comedi_insn *insn |
-| unsigned int *data |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
+ * This function will first check channel list is ok or not and then
+ * initialize the sequence RAM with the polarity, Gain,Channel number.
+ * If the last argument of function "check"is 1 then it only checks
+ * the channel list is ok or not.
+ */
+static int i_APCI3120_SetupChannelList(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ int n_chan,
+ unsigned int *chanlist,
+ char check)
+{
+ struct addi_private *devpriv = dev->private;
+ unsigned int i; /* , differencial=0, bipolar=0; */
+ unsigned int gain;
+ unsigned short us_TmpValue;
-int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ /* correct channel and range number check itself comedi/range.c */
+ if (n_chan < 1) {
+ if (!check)
+ comedi_error(dev, "range/channel list is empty!");
+ return 0;
+ }
+ /* All is ok, so we can setup channel/range list */
+ if (check)
+ return 1;
+
+ /* Code to set the PA and PR...Here it set PA to 0.. */
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR;
+ devpriv->us_OutputRegister = ((n_chan - 1) & 0xf) << 8;
+ outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+
+ for (i = 0; i < n_chan; i++) {
+ /* store range list to card */
+ us_TmpValue = CR_CHAN(chanlist[i]); /* get channel number; */
+
+ if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES)
+ us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); /* set bipolar */
+ else
+ us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar...... */
+
+ gain = CR_RANGE(chanlist[i]); /* get gain number */
+ us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */
+ us_TmpValue |= i << 8; /* To select the RAM LOCATION.... */
+ outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS);
+
+ printk("\n Gain = %i",
+ (((unsigned char)CR_RANGE(chanlist[i]) & 0x03) << 2));
+ printk("\n Channel = %i", CR_CHAN(chanlist[i]));
+ printk("\n Polarity = %i", us_TmpValue & APCI3120_UNIPOLAR);
+ }
+ return 1; /* we can serve this with scan logic */
+}
+
+/*
+ * Reads analog input in synchronous mode EOC and EOS is selected
+ * as per configured if no conversion time is set uses default
+ * conversion time 10 microsec.
+ */
+static int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
unsigned short us_ConvertTiming, us_TmpValue, i;
unsigned char b_Tmp;
@@ -387,26 +608,86 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd
}
+static int i_APCI3120_Reset(struct comedi_device *dev)
+{
+ struct addi_private *devpriv = dev->private;
+ unsigned int i;
+ unsigned short us_TmpValue;
+
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+ devpriv->ui_EocEosConversionTime = 0; /* set eoc eos conv time to 0 */
+ devpriv->b_OutputMemoryStatus = 0;
+
+ /* variables used in timer subdevice */
+ devpriv->b_Timer2Mode = 0;
+ devpriv->b_Timer2Interrupt = 0;
+ devpriv->b_ExttrigEnable = 0; /* Disable ext trigger */
+
+ /* Disable all interrupts, watchdog for the anolog output */
+ devpriv->b_ModeSelectRegister = 0;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ /* Disables all counters, ext trigger and clears PA, PR */
+ devpriv->us_OutputRegister = 0;
+ outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+
/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev,|
-| struct comedi_subdevice *s)|
-| |
-+----------------------------------------------------------------------------+
-| Task : Stops Cyclic acquisition |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| |
-+----------------------------------------------------------------------------+
-| Return Value :0 |
-| |
-+----------------------------------------------------------------------------+
-*/
+ * Code to set the all anolog o/p channel to 0v 8191 is decimal
+ * value for zero(0 v)volt in bipolar mode(default)
+ */
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_1, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 1 */
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_2, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 2 */
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_3, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 3 */
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_4, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 4 */
-int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s)
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_5, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 5 */
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_6, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 6 */
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_7, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 7 */
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_8, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 8 */
+
+ /* Reset digital output to L0W */
+
+/* ES05 outb(0x0,dev->iobase+APCI3120_DIGITAL_OUTPUT); */
+ udelay(10);
+
+ inw(dev->iobase + 0); /* make a dummy read */
+ inb(dev->iobase + APCI3120_RESET_FIFO); /* flush FIFO */
+ inw(dev->iobase + APCI3120_RD_STATUS); /* flush A/D status register */
+
+ /* code to reset the RAM sequence */
+ for (i = 0; i < 16; i++) {
+ us_TmpValue = i << 8; /* select the location */
+ outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS);
+ }
+ return 0;
+}
+
+static int i_APCI3120_ExttrigEnable(struct comedi_device *dev)
{
+ struct addi_private *devpriv = dev->private;
+
+ devpriv->us_OutputRegister |= APCI3120_ENABLE_EXT_TRIGGER;
+ outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+ return 0;
+}
+
+static int i_APCI3120_ExttrigDisable(struct comedi_device *dev)
+{
+ struct addi_private *devpriv = dev->private;
+
+ devpriv->us_OutputRegister &= ~APCI3120_ENABLE_EXT_TRIGGER;
+ outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+ return 0;
+}
+
+static int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct addi_private *devpriv = dev->private;
+
/* Disable A2P Fifo write and AMWEN signal */
outw(0, devpriv->i_IobaseAddon + 4);
@@ -456,28 +737,11 @@ int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_su
return 0;
}
-/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev|
-| ,struct comedi_subdevice *s,struct comedi_cmd *cmd) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Test validity for a command for cyclic anlog input |
-| acquisition |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| struct comedi_cmd *cmd |
-+----------------------------------------------------------------------------+
-| Return Value :0 |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
+static int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
+ const struct addi_board *this_board = comedi_board(dev);
int err = 0;
/* Step 1 : check if triggers are trivially valid */
@@ -503,63 +767,32 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->scan_begin_src == TRIG_TIMER) { /* Test Delay timing */
- if (cmd->scan_begin_arg <
- devpriv->s_EeParameters.ui_MinDelaytimeNs) {
- cmd->scan_begin_arg =
- devpriv->s_EeParameters.ui_MinDelaytimeNs;
- err++;
- }
- }
+ if (cmd->scan_begin_src == TRIG_TIMER) /* Test Delay timing */
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 100000);
if (cmd->convert_src == TRIG_TIMER) { /* Test Acquisition timing */
if (cmd->scan_begin_src == TRIG_TIMER) {
- if ((cmd->convert_arg)
- && (cmd->convert_arg <
- devpriv->s_EeParameters.
- ui_MinAcquisitiontimeNs)) {
- cmd->convert_arg = devpriv->s_EeParameters.
- ui_MinAcquisitiontimeNs;
- err++;
- }
+ if (cmd->convert_arg)
+ err |= cfc_check_trigger_arg_min(
+ &cmd->convert_arg, 10000);
} else {
- if (cmd->convert_arg <
- devpriv->s_EeParameters.ui_MinAcquisitiontimeNs
- ) {
- cmd->convert_arg = devpriv->s_EeParameters.
- ui_MinAcquisitiontimeNs;
- err++;
-
- }
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ 10000);
}
}
- if (!cmd->chanlist_len) {
- cmd->chanlist_len = 1;
- err++;
- }
- if (cmd->chanlist_len > this_board->i_AiChannelList) {
- cmd->chanlist_len = this_board->i_AiChannelList;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) {
- if (!cmd->stop_arg) {
- cmd->stop_arg = 1;
- err++;
- }
- } else { /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
+ err |= cfc_check_trigger_arg_max(&cmd->chanlist_len,
+ this_board->i_AiChannelList);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -584,100 +817,17 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
}
/*
-+----------------------------------------------------------------------------+
-| Function name : int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, |
-| struct comedi_subdevice *s) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Does asynchronous acquisition |
-| Determines the mode 1 or 2. |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
-
- /* loading private structure with cmd structure inputs */
- devpriv->ui_AiFlags = cmd->flags;
- devpriv->ui_AiNbrofChannels = cmd->chanlist_len;
- devpriv->ui_AiScanLength = cmd->scan_end_arg;
- devpriv->pui_AiChannelList = cmd->chanlist;
-
- /* UPDATE-0.7.57->0.7.68devpriv->AiData=s->async->data; */
- devpriv->AiData = s->async->prealloc_buf;
- /* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */
- devpriv->ui_AiDataLength = s->async->prealloc_bufsz;
-
- if (cmd->stop_src == TRIG_COUNT)
- devpriv->ui_AiNbrofScans = cmd->stop_arg;
- else
- devpriv->ui_AiNbrofScans = 0;
-
- devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */
- devpriv->ui_AiTimer1 = 0;
- if ((devpriv->ui_AiNbrofScans == 0) || (devpriv->ui_AiNbrofScans == -1))
- devpriv->b_AiContinuous = 1; /* user want neverending analog acquisition */
- /* stopped using cancel */
-
- if (cmd->start_src == TRIG_EXT)
- devpriv->b_ExttrigEnable = APCI3120_ENABLE;
- else
- devpriv->b_ExttrigEnable = APCI3120_DISABLE;
-
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- /* mode 1 or 3 */
- if (cmd->convert_src == TRIG_TIMER) {
- /* mode 1 */
-
- devpriv->ui_AiTimer0 = cmd->convert_arg; /* timer constant in nano seconds */
- /* return this_board->ai_cmd(1,dev,s); */
- return i_APCI3120_CyclicAnalogInput(1, dev, s);
- }
-
- }
- if ((cmd->scan_begin_src == TRIG_TIMER)
- && (cmd->convert_src == TRIG_TIMER)) {
- /* mode 2 */
- devpriv->ui_AiTimer1 = cmd->scan_begin_arg;
- devpriv->ui_AiTimer0 = cmd->convert_arg; /* variable changed timer2 to timer0 */
- /* return this_board->ai_cmd(2,dev,s); */
- return i_APCI3120_CyclicAnalogInput(2, dev, s);
- }
- return -1;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function name : int i_APCI3120_CyclicAnalogInput(int mode, |
-| struct comedi_device * dev,struct comedi_subdevice * s) |
-+----------------------------------------------------------------------------+
-| Task : This is used for analog input cyclic acquisition |
-| Performs the command operations. |
-| If DMA is configured does DMA initialization |
-| otherwise does the acquisition with EOS interrupt. |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
- struct comedi_subdevice *s)
+ * This is used for analog input cyclic acquisition.
+ * Performs the command operations.
+ * If DMA is configured does DMA initialization otherwise does the
+ * acquisition with EOS interrupt.
+ */
+static int i_APCI3120_CyclicAnalogInput(int mode,
+ struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
unsigned char b_Tmp;
unsigned int ui_Tmp, ui_DelayTiming = 0, ui_TimerValue1 = 0, dmalen0 =
0, dmalen1 = 0, ui_TimerValue2 =
@@ -1186,241 +1336,277 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
}
/*
-+----------------------------------------------------------------------------+
-| intERNAL FUNCTIONS |
-+----------------------------------------------------------------------------+
-*/
+ * Does asynchronous acquisition.
+ * Determines the mode 1 or 2.
+ */
+static int i_APCI3120_CommandAnalogInput(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct addi_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
-/*
-+----------------------------------------------------------------------------+
-| Function name : int i_APCI3120_Reset(struct comedi_device *dev) |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Task : Hardware reset function |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
+ /* loading private structure with cmd structure inputs */
+ devpriv->ui_AiFlags = cmd->flags;
+ devpriv->ui_AiNbrofChannels = cmd->chanlist_len;
+ devpriv->ui_AiScanLength = cmd->scan_end_arg;
+ devpriv->pui_AiChannelList = cmd->chanlist;
-int i_APCI3120_Reset(struct comedi_device *dev)
-{
- unsigned int i;
- unsigned short us_TmpValue;
+ /* UPDATE-0.7.57->0.7.68devpriv->AiData=s->async->data; */
+ devpriv->AiData = s->async->prealloc_buf;
+ /* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */
+ devpriv->ui_AiDataLength = s->async->prealloc_bufsz;
- devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
- devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
- devpriv->b_InterruptMode = APCI3120_EOC_MODE;
- devpriv->ui_EocEosConversionTime = 0; /* set eoc eos conv time to 0 */
- devpriv->b_OutputMemoryStatus = 0;
+ if (cmd->stop_src == TRIG_COUNT)
+ devpriv->ui_AiNbrofScans = cmd->stop_arg;
+ else
+ devpriv->ui_AiNbrofScans = 0;
- /* variables used in timer subdevice */
- devpriv->b_Timer2Mode = 0;
- devpriv->b_Timer2Interrupt = 0;
- devpriv->b_ExttrigEnable = 0; /* Disable ext trigger */
+ devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */
+ devpriv->ui_AiTimer1 = 0;
+ if ((devpriv->ui_AiNbrofScans == 0) || (devpriv->ui_AiNbrofScans == -1))
+ devpriv->b_AiContinuous = 1; /* user want neverending analog acquisition */
+ /* stopped using cancel */
- /* Disable all interrupts, watchdog for the anolog output */
- devpriv->b_ModeSelectRegister = 0;
- outb(devpriv->b_ModeSelectRegister,
- dev->iobase + APCI3120_WRITE_MODE_SELECT);
+ if (cmd->start_src == TRIG_EXT)
+ devpriv->b_ExttrigEnable = APCI3120_ENABLE;
+ else
+ devpriv->b_ExttrigEnable = APCI3120_DISABLE;
- /* Disables all counters, ext trigger and clears PA, PR */
- devpriv->us_OutputRegister = 0;
- outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ /* mode 1 or 3 */
+ if (cmd->convert_src == TRIG_TIMER) {
+ /* mode 1 */
+
+ devpriv->ui_AiTimer0 = cmd->convert_arg; /* timer constant in nano seconds */
+ /* return this_board->ai_cmd(1,dev,s); */
+ return i_APCI3120_CyclicAnalogInput(1, dev, s);
+ }
+
+ }
+ if ((cmd->scan_begin_src == TRIG_TIMER)
+ && (cmd->convert_src == TRIG_TIMER)) {
+ /* mode 2 */
+ devpriv->ui_AiTimer1 = cmd->scan_begin_arg;
+ devpriv->ui_AiTimer0 = cmd->convert_arg; /* variable changed timer2 to timer0 */
+ /* return this_board->ai_cmd(2,dev,s); */
+ return i_APCI3120_CyclicAnalogInput(2, dev, s);
+ }
+ return -1;
+}
/*
- * Code to set the all anolog o/p channel to 0v 8191 is decimal
- * value for zero(0 v)volt in bipolar mode(default)
+ * This function copies the data from DMA buffer to the Comedi buffer.
*/
- outw(8191 | APCI3120_ANALOG_OP_CHANNEL_1, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 1 */
- outw(8191 | APCI3120_ANALOG_OP_CHANNEL_2, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 2 */
- outw(8191 | APCI3120_ANALOG_OP_CHANNEL_3, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 3 */
- outw(8191 | APCI3120_ANALOG_OP_CHANNEL_4, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 4 */
+static void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ short *dma_buffer,
+ unsigned int num_samples)
+{
+ struct addi_private *devpriv = dev->private;
- outw(8191 | APCI3120_ANALOG_OP_CHANNEL_5, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 5 */
- outw(8191 | APCI3120_ANALOG_OP_CHANNEL_6, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 6 */
- outw(8191 | APCI3120_ANALOG_OP_CHANNEL_7, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 7 */
- outw(8191 | APCI3120_ANALOG_OP_CHANNEL_8, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 8 */
+ devpriv->ui_AiActualScan +=
+ (s->async->cur_chan + num_samples) / devpriv->ui_AiScanLength;
+ s->async->cur_chan += num_samples;
+ s->async->cur_chan %= devpriv->ui_AiScanLength;
- /* Reset digital output to L0W */
+ cfc_write_array_to_buffer(s, dma_buffer, num_samples * sizeof(short));
+}
-/* ES05 outb(0x0,dev->iobase+APCI3120_DIGITAL_OUTPUT); */
- udelay(10);
+/*
+ * This is a handler for the DMA interrupt.
+ * This function copies the data to Comedi Buffer.
+ * For continuous DMA it reinitializes the DMA operation.
+ * For single mode DMA it stop the acquisition.
+ */
+static void v_APCI3120_InterruptDma(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct addi_private *devpriv = dev->private;
+ struct comedi_subdevice *s = &dev->subdevices[0];
+ unsigned int next_dma_buf, samplesinbuf;
+ unsigned long low_word, high_word, var;
+ unsigned int ui_Tmp;
- inw(dev->iobase + 0); /* make a dummy read */
- inb(dev->iobase + APCI3120_RESET_FIFO); /* flush FIFO */
- inw(dev->iobase + APCI3120_RD_STATUS); /* flush A/D status register */
+ samplesinbuf =
+ devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer] -
+ inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC);
- /* code to reset the RAM sequence */
- for (i = 0; i < 16; i++) {
- us_TmpValue = i << 8; /* select the location */
- outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS);
+ if (samplesinbuf <
+ devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) {
+ comedi_error(dev, "Interrupted DMA transfer!");
}
- return 0;
-}
+ if (samplesinbuf & 1) {
+ comedi_error(dev, "Odd count of bytes in DMA ring!");
+ i_APCI3120_StopCyclicAcquisition(dev, s);
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+
+ return;
+ }
+ samplesinbuf = samplesinbuf >> 1; /* number of received samples */
+ if (devpriv->b_DmaDoubleBuffer) {
+ /* switch DMA buffers if is used double buffering */
+ next_dma_buf = 1 - devpriv->ui_DmaActualBuffer;
+
+ ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO;
+ outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS);
+
+ /* changed since 16 bit interface for add on */
+ outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,
+ devpriv->i_IobaseAddon + 2);
+ outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* 0x1000 is out putted in windows driver */
+
+ var = devpriv->ul_DmaBufferHw[next_dma_buf];
+ low_word = var & 0xffff;
+ var = devpriv->ul_DmaBufferHw[next_dma_buf];
+ high_word = var / 65536;
+
+ /* DMA Start Address Low */
+ outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
+ outw(low_word, devpriv->i_IobaseAddon + 2);
+
+ /* DMA Start Address High */
+ outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(high_word, devpriv->i_IobaseAddon + 2);
+
+ var = devpriv->ui_DmaBufferUsesize[next_dma_buf];
+ low_word = var & 0xffff;
+ var = devpriv->ui_DmaBufferUsesize[next_dma_buf];
+ high_word = var / 65536;
+
+ /* Nbr of acquisition LOW */
+ outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
+ outw(low_word, devpriv->i_IobaseAddon + 2);
+
+ /* Nbr of acquisition HIGH */
+ outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(high_word, devpriv->i_IobaseAddon + 2);
/*
-+----------------------------------------------------------------------------+
-| Function name : int i_APCI3120_SetupChannelList(struct comedi_device * dev, |
-| struct comedi_subdevice * s, int n_chan,unsigned int *chanlist|
-| ,char check) |
-| |
-+----------------------------------------------------------------------------+
-| Task :This function will first check channel list is ok or not|
-|and then initialize the sequence RAM with the polarity, Gain,Channel number |
-|If the last argument of function "check"is 1 then it only checks the channel|
-|list is ok or not. |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device * dev |
-| struct comedi_subdevice * s |
-| int n_chan |
- unsigned int *chanlist
- char check
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
+ * To configure A2P FIFO
+ * ENABLE A2P FIFO WRITE AND ENABLE AMWEN
+ * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+ */
+ outw(3, devpriv->i_IobaseAddon + 4);
+ /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */
+ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 |
+ APCI3120_ENABLE_WRITE_TC_INT),
+ devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);
-int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevice *s,
- int n_chan, unsigned int *chanlist, char check)
-{
- unsigned int i; /* , differencial=0, bipolar=0; */
- unsigned int gain;
- unsigned short us_TmpValue;
+ }
+ if (samplesinbuf) {
+ v_APCI3120_InterruptDmaMoveBlock16bit(dev, s,
+ devpriv->ul_DmaBufferVirtual[devpriv->
+ ui_DmaActualBuffer], samplesinbuf);
- /* correct channel and range number check itself comedi/range.c */
- if (n_chan < 1) {
- if (!check)
- comedi_error(dev, "range/channel list is empty!");
- return 0;
+ if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS)) {
+ s->async->events |= COMEDI_CB_EOS;
+ comedi_event(dev, s);
+ }
}
- /* All is ok, so we can setup channel/range list */
- if (check)
- return 1;
+ if (!devpriv->b_AiContinuous)
+ if (devpriv->ui_AiActualScan >= devpriv->ui_AiNbrofScans) {
+ /* all data sampled */
+ i_APCI3120_StopCyclicAcquisition(dev, s);
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return;
+ }
- /* Code to set the PA and PR...Here it set PA to 0.. */
- devpriv->us_OutputRegister =
- devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR;
- devpriv->us_OutputRegister = ((n_chan - 1) & 0xf) << 8;
- outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+ if (devpriv->b_DmaDoubleBuffer) { /* switch dma buffers */
+ devpriv->ui_DmaActualBuffer = 1 - devpriv->ui_DmaActualBuffer;
+ } else {
+/*
+ * restart DMA if is not used double buffering
+ * ADDED REINITIALISE THE DMA
+ */
+ ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO;
+ outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS);
- for (i = 0; i < n_chan; i++) {
- /* store range list to card */
- us_TmpValue = CR_CHAN(chanlist[i]); /* get channel number; */
+ /* changed since 16 bit interface for add on */
+ outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,
+ devpriv->i_IobaseAddon + 2);
+ outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* */
+/*
+ * A2P FIFO MANAGEMENT
+ * A2P fifo reset & transfer control enable
+ */
+ outl(APCI3120_A2P_FIFO_MANAGEMENT,
+ devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR);
- if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES)
- us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); /* set bipolar */
- else
- us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar...... */
+ var = devpriv->ul_DmaBufferHw[0];
+ low_word = var & 0xffff;
+ var = devpriv->ul_DmaBufferHw[0];
+ high_word = var / 65536;
+ outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
+ outw(low_word, devpriv->i_IobaseAddon + 2);
+ outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(high_word, devpriv->i_IobaseAddon + 2);
- gain = CR_RANGE(chanlist[i]); /* get gain number */
- us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */
- us_TmpValue |= i << 8; /* To select the RAM LOCATION.... */
- outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS);
+ var = devpriv->ui_DmaBufferUsesize[0];
+ low_word = var & 0xffff; /* changed */
+ var = devpriv->ui_DmaBufferUsesize[0];
+ high_word = var / 65536;
+ outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
+ outw(low_word, devpriv->i_IobaseAddon + 2);
+ outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(high_word, devpriv->i_IobaseAddon + 2);
- printk("\n Gain = %i",
- (((unsigned char)CR_RANGE(chanlist[i]) & 0x03) << 2));
- printk("\n Channel = %i", CR_CHAN(chanlist[i]));
- printk("\n Polarity = %i", us_TmpValue & APCI3120_UNIPOLAR);
+/*
+ * To configure A2P FIFO
+ * ENABLE A2P FIFO WRITE AND ENABLE AMWEN
+ * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+ */
+ outw(3, devpriv->i_IobaseAddon + 4);
+ /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */
+ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 |
+ APCI3120_ENABLE_WRITE_TC_INT),
+ devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);
}
- return 1; /* we can serve this with scan logic */
}
/*
-+----------------------------------------------------------------------------+
-| Function name : int i_APCI3120_ExttrigEnable(struct comedi_device * dev) |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Task : Enable the external trigger |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device * dev |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI3120_ExttrigEnable(struct comedi_device *dev)
+ * This function handles EOS interrupt.
+ * This function copies the acquired data(from FIFO) to Comedi buffer.
+ */
+static int i_APCI3120_InterruptHandleEos(struct comedi_device *dev)
{
+ struct addi_private *devpriv = dev->private;
+ int n_chan, i;
+ struct comedi_subdevice *s = &dev->subdevices[0];
+ int err = 1;
- devpriv->us_OutputRegister |= APCI3120_ENABLE_EXT_TRIGGER;
- outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
- return 0;
-}
+ n_chan = devpriv->ui_AiNbrofChannels;
-/*
-+----------------------------------------------------------------------------+
-| Function name : int i_APCI3120_ExttrigDisable(struct comedi_device * dev) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Disables the external trigger |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device * dev |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-| |
-+----------------------------------------------------------------------------+
-*/
+ s->async->events = 0;
-int i_APCI3120_ExttrigDisable(struct comedi_device *dev)
-{
- devpriv->us_OutputRegister &= ~APCI3120_ENABLE_EXT_TRIGGER;
- outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
- return 0;
-}
+ for (i = 0; i < n_chan; i++)
+ err &= comedi_buf_put(s->async, inw(dev->iobase + 0));
-/*
-+----------------------------------------------------------------------------+
-| intERRUPT FUNCTIONS |
-+----------------------------------------------------------------------------+
-*/
+ s->async->events |= COMEDI_CB_EOS;
-/*
-+----------------------------------------------------------------------------+
-| Function name : void v_APCI3120_Interrupt(int irq, void *d) |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Task :Interrupt handler for APCI3120 |
-| When interrupt occurs this gets called. |
-| First it finds which interrupt has been generated and |
-| handles corresponding interrupt |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : int irq |
-| void *d |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : void |
-| |
-+----------------------------------------------------------------------------+
-*/
+ if (err == 0)
+ s->async->events |= COMEDI_CB_OVERFLOW;
+
+ comedi_event(dev, s);
+
+ return 0;
+}
-void v_APCI3120_Interrupt(int irq, void *d)
+static void v_APCI3120_Interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct addi_private *devpriv = dev->private;
unsigned short int_daq;
-
unsigned int int_amcc, ui_Check, i;
unsigned short us_TmpValue;
unsigned char b_DummyRead;
-
struct comedi_subdevice *s = &dev->subdevices[0];
+
ui_Check = 1;
int_daq = inw(dev->iobase + APCI3120_RD_STATUS) & 0xf000; /* get IRQ reasons */
@@ -1602,284 +1788,20 @@ void v_APCI3120_Interrupt(int irq, void *d)
}
/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Task : This function handles EOS interrupt. |
-| This function copies the acquired data(from FIFO) |
-| to Comedi buffer. |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-
-int i_APCI3120_InterruptHandleEos(struct comedi_device *dev)
-{
- int n_chan, i;
- struct comedi_subdevice *s = &dev->subdevices[0];
- int err = 1;
-
- n_chan = devpriv->ui_AiNbrofChannels;
-
- s->async->events = 0;
-
- for (i = 0; i < n_chan; i++)
- err &= comedi_buf_put(s->async, inw(dev->iobase + 0));
-
- s->async->events |= COMEDI_CB_EOS;
-
- if (err == 0)
- s->async->events |= COMEDI_CB_OVERFLOW;
-
- comedi_event(dev, s);
-
- return 0;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function name : void v_APCI3120_InterruptDma(int irq, void *d) |
-| |
-+----------------------------------------------------------------------------+
-| Task : This is a handler for the DMA interrupt |
-| This function copies the data to Comedi Buffer. |
-| For continuous DMA it reinitializes the DMA operation. |
-| For single mode DMA it stop the acquisition. |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : int irq, void *d |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : void |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-void v_APCI3120_InterruptDma(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = &dev->subdevices[0];
- unsigned int next_dma_buf, samplesinbuf;
- unsigned long low_word, high_word, var;
-
- unsigned int ui_Tmp;
- samplesinbuf =
- devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer] -
- inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC);
-
- if (samplesinbuf <
- devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) {
- comedi_error(dev, "Interrupted DMA transfer!");
- }
- if (samplesinbuf & 1) {
- comedi_error(dev, "Odd count of bytes in DMA ring!");
- i_APCI3120_StopCyclicAcquisition(dev, s);
- devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
-
- return;
- }
- samplesinbuf = samplesinbuf >> 1; /* number of received samples */
- if (devpriv->b_DmaDoubleBuffer) {
- /* switch DMA buffers if is used double buffering */
- next_dma_buf = 1 - devpriv->ui_DmaActualBuffer;
-
- ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO;
- outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS);
-
- /* changed since 16 bit interface for add on */
- outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
- outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,
- devpriv->i_IobaseAddon + 2);
- outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
- outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* 0x1000 is out putted in windows driver */
-
- var = devpriv->ul_DmaBufferHw[next_dma_buf];
- low_word = var & 0xffff;
- var = devpriv->ul_DmaBufferHw[next_dma_buf];
- high_word = var / 65536;
-
- /* DMA Start Address Low */
- outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
- outw(low_word, devpriv->i_IobaseAddon + 2);
-
- /* DMA Start Address High */
- outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
- outw(high_word, devpriv->i_IobaseAddon + 2);
-
- var = devpriv->ui_DmaBufferUsesize[next_dma_buf];
- low_word = var & 0xffff;
- var = devpriv->ui_DmaBufferUsesize[next_dma_buf];
- high_word = var / 65536;
-
- /* Nbr of acquisition LOW */
- outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
- outw(low_word, devpriv->i_IobaseAddon + 2);
-
- /* Nbr of acquisition HIGH */
- outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
- outw(high_word, devpriv->i_IobaseAddon + 2);
-
-/*
- * To configure A2P FIFO
- * ENABLE A2P FIFO WRITE AND ENABLE AMWEN
- * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+ * Configure Timer 2
+ *
+ * data[0] = TIMER configure as timer
+ * = WATCHDOG configure as watchdog
+ * data[1] = Timer constant
+ * data[2] = Timer2 interrupt (1)enable or(0) disable
*/
- outw(3, devpriv->i_IobaseAddon + 4);
- /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */
- outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 |
- APCI3120_ENABLE_WRITE_TC_INT),
- devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);
-
- }
- if (samplesinbuf) {
- v_APCI3120_InterruptDmaMoveBlock16bit(dev, s,
- devpriv->ul_DmaBufferVirtual[devpriv->
- ui_DmaActualBuffer], samplesinbuf);
-
- if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS)) {
- s->async->events |= COMEDI_CB_EOS;
- comedi_event(dev, s);
- }
- }
- if (!devpriv->b_AiContinuous)
- if (devpriv->ui_AiActualScan >= devpriv->ui_AiNbrofScans) {
- /* all data sampled */
- i_APCI3120_StopCyclicAcquisition(dev, s);
- devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
- s->async->events |= COMEDI_CB_EOA;
- comedi_event(dev, s);
- return;
- }
-
- if (devpriv->b_DmaDoubleBuffer) { /* switch dma buffers */
- devpriv->ui_DmaActualBuffer = 1 - devpriv->ui_DmaActualBuffer;
- } else {
-/*
- * restart DMA if is not used double buffering
- * ADDED REINITIALISE THE DMA
- */
- ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO;
- outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS);
-
- /* changed since 16 bit interface for add on */
- outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
- outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,
- devpriv->i_IobaseAddon + 2);
- outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
- outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* */
-/*
- * A2P FIFO MANAGEMENT
- * A2P fifo reset & transfer control enable
- */
- outl(APCI3120_A2P_FIFO_MANAGEMENT,
- devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR);
-
- var = devpriv->ul_DmaBufferHw[0];
- low_word = var & 0xffff;
- var = devpriv->ul_DmaBufferHw[0];
- high_word = var / 65536;
- outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
- outw(low_word, devpriv->i_IobaseAddon + 2);
- outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
- outw(high_word, devpriv->i_IobaseAddon + 2);
-
- var = devpriv->ui_DmaBufferUsesize[0];
- low_word = var & 0xffff; /* changed */
- var = devpriv->ui_DmaBufferUsesize[0];
- high_word = var / 65536;
- outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
- outw(low_word, devpriv->i_IobaseAddon + 2);
- outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
- outw(high_word, devpriv->i_IobaseAddon + 2);
-
-/*
- * To configure A2P FIFO
- * ENABLE A2P FIFO WRITE AND ENABLE AMWEN
- * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
- */
- outw(3, devpriv->i_IobaseAddon + 4);
- /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */
- outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 |
- APCI3120_ENABLE_WRITE_TC_INT),
- devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);
- }
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function name :void v_APCI3120_InterruptDmaMoveBlock16bit(comedi_device|
-|*dev,struct comedi_subdevice *s,short *dma,short *data,int n) |
-| |
-+----------------------------------------------------------------------------+
-| Task : This function copies the data from DMA buffer to the |
-| Comedi buffer |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| short *dma |
-| short *data,int n |
-+----------------------------------------------------------------------------+
-| Return Value : void |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,
- struct comedi_subdevice *s, short *dma_buffer, unsigned int num_samples)
-{
- devpriv->ui_AiActualScan +=
- (s->async->cur_chan + num_samples) / devpriv->ui_AiScanLength;
- s->async->cur_chan += num_samples;
- s->async->cur_chan %= devpriv->ui_AiScanLength;
-
- cfc_write_array_to_buffer(s, dma_buffer, num_samples * sizeof(short));
-}
-
-/*
-+----------------------------------------------------------------------------+
-| TIMER SUBDEVICE |
-+----------------------------------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, |
-| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
-| |
-+----------------------------------------------------------------------------+
-| Task :Configure Timer 2 |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| struct comedi_insn *insn |
-| unsigned int *data |
-| |
-| data[0]= TIMER configure as timer |
-| = WATCHDOG configure as watchdog |
-| data[1] = Timer constant |
-| data[2] = Timer2 interrupt (1)enable or(0) disable |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI3120_InsnConfigTimer(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
-
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
unsigned int ui_Timervalue2;
unsigned short us_TmpValue;
unsigned char b_Tmp;
@@ -2007,37 +1929,24 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic
}
/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, |
-| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
-| |
-+----------------------------------------------------------------------------+
-| Task : To start and stop the timer |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| struct comedi_insn *insn |
-| unsigned int *data |
-| |
-| data[0] = 1 (start) |
-| data[0] = 0 (stop ) |
-| data[0] = 2 (write new value) |
-| data[1]= new value |
-| |
-| devpriv->b_Timer2Mode = 0 DISABLE |
-| 1 Timer |
-| 2 Watch dog |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ * To start and stop the timer
+ *
+ * data[0] = 1 (start)
+ * = 0 (stop)
+ * = 2 (write new value)
+ * data[1] = new value
+ *
+ * devpriv->b_Timer2Mode = 0 DISABLE
+ * = 1 Timer
+ * = 2 Watch dog
+ */
+static int i_APCI3120_InsnWriteTimer(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
-
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
unsigned int ui_Timervalue2 = 0;
unsigned short us_TmpValue;
unsigned char b_Tmp;
@@ -2196,31 +2105,19 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice
}
/*
-+----------------------------------------------------------------------------+
-| Function name : int i_APCI3120_InsnReadTimer(struct comedi_device *dev, |
-| struct comedi_subdevice *s,struct comedi_insn *insn, unsigned int *data) |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Task : read the Timer value |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| struct comedi_insn *insn |
-| unsigned int *data |
-| |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| for Timer: data[0]= Timer constant |
-| |
-| for watchdog: data[0]=0 (still running) |
-| data[0]=1 (run down) |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ * Read the Timer value
+ *
+ * for Timer: data[0]= Timer constant
+ *
+ * for watchdog: data[0] = 0 (still running)
+ * = 1 (run down)
+ */
+static int i_APCI3120_InsnReadTimer(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned char b_Tmp;
unsigned short us_TmpValue, us_TmpValue_2, us_StatusValue;
@@ -2265,299 +2162,52 @@ int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice
return insn->n;
}
-/*
-+----------------------------------------------------------------------------+
-| DIGITAL INPUT SUBDEVICE |
-+----------------------------------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, |
-| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
-| |
-| |
-+----------------------------------------------------------------------------+
-| Task : Reads the value of the specified Digital input channel|
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| struct comedi_insn *insn |
-| unsigned int *data |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int ui_Chan, ui_TmpValue;
-
- ui_Chan = CR_CHAN(insn->chanspec); /* channel specified */
-
- /* this_board->di_read(dev,ui_Chan,data); */
- if (ui_Chan <= 3) {
- ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI3120_RD_STATUS);
-
-/*
- * since only 1 channel reqd to bring it to last bit it is rotated 8
- * +(chan - 1) times then ANDed with 1 for last bit.
- */
- *data = (ui_TmpValue >> (ui_Chan + 8)) & 1;
- /* return 0; */
- } else {
- /* comedi_error(dev," chan spec wrong"); */
- return -EINVAL; /* "sorry channel spec wrong " */
- }
- return insn->n;
-
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, |
-|struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Reads the value of the Digital input Port i.e.4channels|
-| value is returned in data[0] |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| struct comedi_insn *insn |
-| unsigned int *data |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_TmpValue;
- ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI3120_RD_STATUS);
- /***** state of 4 channels in the 11, 10, 9, 8 bits of status reg
- rotated right 8 times to bring them to last four bits
- ANDed with oxf for value.
- *****/
-
- *data = (ui_TmpValue >> 8) & 0xf;
- /* this_board->di_bits(dev,data); */
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| DIGITAL OUTPUT SUBDEVICE |
-+----------------------------------------------------------------------------+
-*/
-/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device |
-| *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
-| |
-+----------------------------------------------------------------------------+
-| Task :Configure the output memory ON or OFF |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters :struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| struct comedi_insn *insn |
-| unsigned int *data |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
-{
-
- if ((data[0] != 0) && (data[0] != 1)) {
- comedi_error(dev,
- "Not a valid Data !!! ,Data should be 1 or 0\n");
- return -EINVAL;
- }
- if (data[0]) {
- devpriv->b_OutputMemoryStatus = APCI3120_ENABLE;
-
- } else {
- devpriv->b_OutputMemoryStatus = APCI3120_DISABLE;
- devpriv->b_DigitalOutputRegister = 0;
- }
- if (!devpriv->b_OutputMemoryStatus)
- ui_Temp = 0;
- /* if(!devpriv->b_OutputMemoryStatus ) */
-
- return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, |
-| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
-| |
-+----------------------------------------------------------------------------+
-| Task : write diatal output port |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| struct comedi_insn *insn |
-| unsigned int *data |
-| data[0] Value to be written
-| data[1] :1 Set digital o/p ON
-| data[1] 2 Set digital o/p OFF with memory ON
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
+static int apci3120_di_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- if ((data[0] > devpriv->s_EeParameters.i_DoMaxdata) || (data[0] < 0)) {
-
- comedi_error(dev, "Data is not valid !!! \n");
- return -EINVAL;
- }
+ struct addi_private *devpriv = dev->private;
+ unsigned int val;
- switch (data[1]) {
- case 1:
- data[0] = (data[0] << 4) | devpriv->b_DigitalOutputRegister;
- break;
-
- case 2:
- data[0] = data[0];
- break;
- default:
- printk("\nThe parameter passed is in error \n");
- return -EINVAL;
- } /* switch(data[1]) */
- outb(data[0], devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
-
- devpriv->b_DigitalOutputRegister = data[0] & 0xF0;
+ /* the input channels are bits 11:8 of the status reg */
+ val = inw(devpriv->iobase + APCI3120_RD_STATUS);
+ data[1] = (val >> 8) & 0xf;
return insn->n;
-
}
-/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,|
-|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Write digiatl output |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| struct comedi_insn *insn |
-| unsigned int *data |
- data[0] Value to be written
- data[1] :1 Set digital o/p ON
- data[1] 2 Set digital o/p OFF with memory ON
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
+static int apci3120_do_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
-
- unsigned int ui_Temp1;
-
- unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
-
- if ((data[0] != 0) && (data[0] != 1)) {
- comedi_error(dev,
- "Not a valid Data !!! ,Data should be 1 or 0\n");
- return -EINVAL;
- }
- if (ui_NoOfChannel > devpriv->s_EeParameters.i_NbrDoChannel - 1) {
- comedi_error(dev,
- "This board doesn't have specified channel !!! \n");
- return -EINVAL;
+ 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;
+
+ outb(val << 4, devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
}
- switch (data[1]) {
- case 1:
- data[0] = (data[0] << ui_NoOfChannel);
-/* ES05 data[0]=(data[0]<<4)|ui_Temp; */
- data[0] = (data[0] << 4) | devpriv->b_DigitalOutputRegister;
- break;
+ data[1] = val;
- case 2:
- data[0] = ~data[0] & 0x1;
- ui_Temp1 = 1;
- ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
- ui_Temp1 = ui_Temp1 << 4;
-/* ES05 ui_Temp=ui_Temp|ui_Temp1; */
- devpriv->b_DigitalOutputRegister =
- devpriv->b_DigitalOutputRegister | ui_Temp1;
-
- data[0] = (data[0] << ui_NoOfChannel) ^ 0xf;
- data[0] = data[0] << 4;
-/* ES05 data[0]=data[0]& ui_Temp; */
- data[0] = data[0] & devpriv->b_DigitalOutputRegister;
- break;
- default:
- printk("\nThe parameter passed is in error \n");
- return -EINVAL;
- } /* switch(data[1]) */
- outb(data[0], devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
-
-/* ES05 ui_Temp=data[0] & 0xf0; */
- devpriv->b_DigitalOutputRegister = data[0] & 0xf0;
return insn->n;
-
}
-/*
-+----------------------------------------------------------------------------+
-| ANALOG OUTPUT SUBDEVICE |
-+----------------------------------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,|
-|struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Write analog output |
-| |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| struct comedi_insn *insn |
-| unsigned int *data |
-+----------------------------------------------------------------------------+
-| Return Value : |
-| |
-+----------------------------------------------------------------------------+
-*/
-
-int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
+static int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ui_Range, ui_Channel;
unsigned short us_TmpValue;
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h
deleted file mode 100644
index 50eb0a0a0a0..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h
+++ /dev/null
@@ -1,249 +0,0 @@
-
-/* hwdrv_apci3120.h */
-
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-/* comedi related defines */
-
-/* ANALOG INPUT RANGE */
-static const struct comedi_lrange range_apci3120_ai = { 8, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2),
- UNI_RANGE(1)
- }
-};
-
-/* ANALOG OUTPUT RANGE */
-static const struct comedi_lrange range_apci3120_ao = { 2, {
- BIP_RANGE(10),
- UNI_RANGE(10)
- }
-};
-
-#define APCI3120_BIPOLAR_RANGES 4 /* used for test on mixture of BIP/UNI ranges */
-
-#define APCI3120_BOARD_VENDOR_ID 0x10E8
-#define APCI3120_ADDRESS_RANGE 16
-
-#define APCI3120_DISABLE 0
-#define APCI3120_ENABLE 1
-
-#define APCI3120_START 1
-#define APCI3120_STOP 0
-
-#define APCI3120_EOC_MODE 1
-#define APCI3120_EOS_MODE 2
-#define APCI3120_DMA_MODE 3
-
-/* DIGITAL INPUT-OUTPUT DEFINE */
-
-#define APCI3120_DIGITAL_OUTPUT 0x0D
-#define APCI3120_RD_STATUS 0x02
-#define APCI3120_RD_FIFO 0x00
-
-/* digital output insn_write ON /OFF selection */
-#define APCI3120_SET4DIGITALOUTPUTON 1
-#define APCI3120_SET4DIGITALOUTPUTOFF 0
-
-/* analog output SELECT BIT */
-#define APCI3120_ANALOG_OP_CHANNEL_1 0x0000
-#define APCI3120_ANALOG_OP_CHANNEL_2 0x4000
-#define APCI3120_ANALOG_OP_CHANNEL_3 0x8000
-#define APCI3120_ANALOG_OP_CHANNEL_4 0xC000
-#define APCI3120_ANALOG_OP_CHANNEL_5 0x0000
-#define APCI3120_ANALOG_OP_CHANNEL_6 0x4000
-#define APCI3120_ANALOG_OP_CHANNEL_7 0x8000
-#define APCI3120_ANALOG_OP_CHANNEL_8 0xC000
-
-/* Enable external trigger bit in nWrAddress */
-#define APCI3120_ENABLE_EXT_TRIGGER 0x8000
-
-/* ANALOG OUTPUT AND INPUT DEFINE */
-#define APCI3120_UNIPOLAR 0x80 /* $$ RAM sequence polarity BIT */
-#define APCI3120_BIPOLAR 0x00 /* $$ RAM sequence polarity BIT */
-#define APCI3120_ANALOG_OUTPUT_1 0x08 /* (ADDRESS ) */
-#define APCI3120_ANALOG_OUTPUT_2 0x0A /* (ADDRESS ) */
-#define APCI3120_1_GAIN 0x00 /* $$ RAM sequence Gain Bits for gain 1 */
-#define APCI3120_2_GAIN 0x10 /* $$ RAM sequence Gain Bits for gain 2 */
-#define APCI3120_5_GAIN 0x20 /* $$ RAM sequence Gain Bits for gain 5 */
-#define APCI3120_10_GAIN 0x30 /* $$ RAM sequence Gain Bits for gain 10 */
-#define APCI3120_SEQ_RAM_ADDRESS 0x06 /* $$ EARLIER NAMED APCI3120_FIFO_ADDRESS */
-#define APCI3120_RESET_FIFO 0x0C /* (ADDRESS) */
-#define APCI3120_TIMER_0_MODE_2 0x01 /* $$ Bits for timer mode */
-#define APCI3120_TIMER_0_MODE_4 0x2
-#define APCI3120_SELECT_TIMER_0_WORD 0x00
-#define APCI3120_ENABLE_TIMER0 0x1000 /* $$Gatebit 0 in nWrAddress */
-#define APCI3120_CLEAR_PR 0xF0FF
-#define APCI3120_CLEAR_PA 0xFFF0
-#define APCI3120_CLEAR_PA_PR (APCI3120_CLEAR_PR & APCI3120_CLEAR_PA)
-
-/* nWrMode_Select */
-#define APCI3120_ENABLE_SCAN 0x8 /* $$ bit in nWrMode_Select */
-#define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN)
-#define APCI3120_ENABLE_EOS_INT 0x2 /* $$ bit in nWrMode_Select */
-
-#define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT)
-#define APCI3120_ENABLE_EOC_INT 0x1
-#define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT)
-#define APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER (APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
-#define APCI3120_DISABLE_ALL_INTERRUPT (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
-
-/* status register bits */
-#define APCI3120_EOC 0x8000
-#define APCI3120_EOS 0x2000
-
-/* software trigger dummy register */
-#define APCI3120_START_CONVERSION 0x02 /* (ADDRESS) */
-
-/* TIMER DEFINE */
-#define APCI3120_QUARTZ_A 70
-#define APCI3120_QUARTZ_B 50
-#define APCI3120_TIMER 1
-#define APCI3120_WATCHDOG 2
-#define APCI3120_TIMER_DISABLE 0
-#define APCI3120_TIMER_ENABLE 1
-#define APCI3120_ENABLE_TIMER2 0x4000 /* $$ gatebit 2 in nWrAddress */
-#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2)
-#define APCI3120_ENABLE_TIMER_INT 0x04 /* $$ ENAIRQ_FC_Bit in nWrModeSelect */
-#define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT)
-#define APCI3120_WRITE_MODE_SELECT 0x0E /* (ADDRESS) */
-#define APCI3120_SELECT_TIMER_0_WORD 0x00
-#define APCI3120_SELECT_TIMER_1_WORD 0x01
-#define APCI3120_TIMER_1_MODE_2 0x4
-
-/* $$ BIT FOR MODE IN nCsTimerCtr1 */
-#define APCI3120_TIMER_2_MODE_0 0x0
-#define APCI3120_TIMER_2_MODE_2 0x10
-#define APCI3120_TIMER_2_MODE_5 0x30
-
-/* $$ BIT FOR MODE IN nCsTimerCtr0 */
-#define APCI3120_SELECT_TIMER_2_LOW_WORD 0x02
-#define APCI3120_SELECT_TIMER_2_HIGH_WORD 0x03
-
-#define APCI3120_TIMER_CRT0 0x0D /* (ADDRESS for cCsTimerCtr0) */
-#define APCI3120_TIMER_CRT1 0x0C /* (ADDRESS for cCsTimerCtr1) */
-
-#define APCI3120_TIMER_VALUE 0x04 /* ADDRESS for nCsTimerWert */
-#define APCI3120_TIMER_STATUS_REGISTER 0x0D /* ADDRESS for delete timer 2 interrupt */
-#define APCI3120_RD_STATUS 0x02 /* ADDRESS */
-#define APCI3120_WR_ADDRESS 0x00 /* ADDRESS */
-#define APCI3120_ENABLE_WATCHDOG 0x20 /* $$BIT in nWrMode_Select */
-#define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG)
-#define APCI3120_ENABLE_TIMER_COUNTER 0x10 /* $$BIT in nWrMode_Select */
-#define APCI3120_DISABLE_TIMER_COUNTER (~APCI3120_ENABLE_TIMER_COUNTER)
-#define APCI3120_FC_TIMER 0x1000 /* bit in status register */
-#define APCI3120_ENABLE_TIMER0 0x1000
-#define APCI3120_ENABLE_TIMER1 0x2000
-#define APCI3120_ENABLE_TIMER2 0x4000
-#define APCI3120_DISABLE_TIMER0 (~APCI3120_ENABLE_TIMER0)
-#define APCI3120_DISABLE_TIMER1 (~APCI3120_ENABLE_TIMER1)
-#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2)
-
-#define APCI3120_TIMER2_SELECT_EOS 0xC0 /* ADDED on 20-6 */
-#define APCI3120_COUNTER 3 /* on 20-6 */
-#define APCI3120_DISABLE_ALL_TIMER (APCI3120_DISABLE_TIMER0 & APCI3120_DISABLE_TIMER1 & APCI3120_DISABLE_TIMER2) /* on 20-6 */
-
-#define MAX_ANALOGINPUT_CHANNELS 32
-
-struct str_AnalogReadInformation {
-
- unsigned char b_Type; /* EOC or EOS */
- unsigned char b_InterruptFlag; /* Interrupt use or not */
- unsigned int ui_ConvertTiming; /* Selection of the conversion time */
- unsigned char b_NbrOfChannel; /* Number of channel to read */
- unsigned int ui_ChannelList[MAX_ANALOGINPUT_CHANNELS]; /* Number of the channel to be read */
- unsigned int ui_RangeList[MAX_ANALOGINPUT_CHANNELS]; /* Gain of each channel */
-
-};
-
-
-/* Function Declaration For APCI-3120 */
-
-/* Internal functions */
-int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevice *s,
- int n_chan, unsigned int *chanlist, char check);
-int i_APCI3120_ExttrigEnable(struct comedi_device *dev);
-int i_APCI3120_ExttrigDisable(struct comedi_device *dev);
-int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
-int i_APCI3120_Reset(struct comedi_device *dev);
-int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
- struct comedi_subdevice *s);
-/* Interrupt functions */
-void v_APCI3120_Interrupt(int irq, void *d);
-/* UPDATE-0.7.57->0.7.68 void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,struct comedi_subdevice *s,short *dma,short *data,int n); */
-void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,
- struct comedi_subdevice *s,
- short *dma_buffer,
- unsigned int num_samples);
-int i_APCI3120_InterruptHandleEos(struct comedi_device *dev);
-void v_APCI3120_InterruptDma(int irq, void *d);
-
-/* TIMER */
-
-int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/*
-* DI for di read
-*/
-
-int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* DO */
-/* int i_APCI3120_WriteDigitalOutput(struct comedi_device *dev,
- * unsigned char data);
- */
-int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data);
-int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* AO */
-/* int i_APCI3120_Write1AnalogValue(struct comedi_device *dev,UINT ui_Range,
- * UINT ui_Channel,UINT data );
- */
-
-int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* AI HArdware layer */
-
-int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_cmd *cmd);
-int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s);
-/* int i_APCI3120_CancelAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s); */
-int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
index 38ab49917d7..829af187b24 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
@@ -51,15 +51,131 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+----------+-----------+------------------------------------------------+
*/
-/*
- +----------------------------------------------------------------------------+
- | Included files |
- +----------------------------------------------------------------------------+
-*/
-#include "hwdrv_apci3200.h"
-
/* #define PRINT_INFO */
+/* Card Specific information */
+/* #define APCI3200_ADDRESS_RANGE 264 */
+
+/* Analog Input related Defines */
+#define APCI3200_AI_OFFSET_GAIN 0
+#define APCI3200_AI_SC_TEST 4
+#define APCI3200_AI_IRQ 8
+#define APCI3200_AI_AUTOCAL 12
+#define APCI3200_RELOAD_CONV_TIME_VAL 32
+#define APCI3200_CONV_TIME_TIME_BASE 36
+#define APCI3200_RELOAD_DELAY_TIME_VAL 40
+#define APCI3200_DELAY_TIME_TIME_BASE 44
+#define APCI3200_AI_MODULE1 0
+#define APCI3200_AI_MODULE2 64
+#define APCI3200_AI_MODULE3 128
+#define APCI3200_AI_MODULE4 192
+#define TRUE 1
+#define FALSE 0
+#define APCI3200_AI_EOSIRQ 16
+#define APCI3200_AI_EOS 20
+#define APCI3200_AI_CHAN_ID 24
+#define APCI3200_AI_CHAN_VAL 28
+#define ANALOG_INPUT 0
+#define TEMPERATURE 1
+#define RESISTANCE 2
+
+#define ENABLE_EXT_TRIG 1
+#define ENABLE_EXT_GATE 2
+#define ENABLE_EXT_TRIG_GATE 3
+
+#define APCI3200_MAXVOLT 2.5
+#define ADDIDATA_GREATER_THAN_TEST 0
+#define ADDIDATA_LESS_THAN_TEST 1
+
+#define ADDIDATA_UNIPOLAR 1
+#define ADDIDATA_BIPOLAR 2
+
+#define MAX_MODULE 4
+
+/* ANALOG INPUT RANGE */
+static const struct comedi_lrange range_apci3200_ai = {
+ 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+static const struct comedi_lrange range_apci3300_ai = {
+ 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+int MODULE_NO;
+struct {
+ int i_Gain;
+ int i_Polarity;
+ int i_OffsetRange;
+ int i_Coupling;
+ int i_SingleDiff;
+ int i_AutoCalibration;
+ unsigned int ui_ReloadValue;
+ unsigned int ui_TimeUnitReloadVal;
+ int i_Interrupt;
+ int i_ModuleSelection;
+} Config_Parameters_Module1, Config_Parameters_Module2,
+ Config_Parameters_Module3, Config_Parameters_Module4;
+
+
+struct str_ADDIDATA_RTDStruct {
+ unsigned int ul_NumberOfValue;
+ unsigned int *pul_ResistanceValue;
+ unsigned int *pul_TemperatureValue;
+};
+
+struct str_Module {
+ unsigned long ul_CurrentSourceCJC;
+ unsigned long ul_CurrentSource[5];
+ unsigned long ul_GainFactor[8]; /* Gain Factor */
+ unsigned int w_GainValue[10];
+};
+
+struct str_BoardInfos {
+
+ int i_CJCAvailable;
+ int i_CJCPolarity;
+ int i_CJCGain;
+ int i_InterruptFlag;
+ int i_ADDIDATAPolarity;
+ int i_ADDIDATAGain;
+ int i_AutoCalibration;
+ int i_ADDIDATAConversionTime;
+ int i_ADDIDATAConversionTimeUnit;
+ int i_ADDIDATAType;
+ int i_ChannelNo;
+ int i_ChannelCount;
+ int i_ScanType;
+ int i_FirstChannel;
+ int i_LastChannel;
+ int i_Sum;
+ int i_Offset;
+ unsigned int ui_Channel_num;
+ int i_Count;
+ int i_Initialised;
+ unsigned int ui_InterruptChannelValue[144]; /* Buffer */
+ unsigned char b_StructInitialized;
+ /* 7 is the maximal number of channels */
+ unsigned int ui_ScanValueArray[7 + 12];
+
+ int i_ConnectionType;
+ int i_NbrOfModule;
+ struct str_Module s_Module[MAX_MODULE];
+};
+
/* BEGIN JK 06.07.04: Management of sevrals boards */
/*
int i_CJCAvailable=1;
@@ -94,27 +210,10 @@ struct str_BoardInfos s_BoardInfos[100]; /* 100 will be the max number of board
#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */
#define NVCMD_BEGIN_WRITE (0x6 << 5) /* EEPROM begin write command */
-/*+----------------------------------------------------------------------------+*/
-/*| Function Name : int i_AddiHeaderRW_ReadEeprom |*/
-/*| (int i_NbOfWordsToRead, |*/
-/*| unsigned int dw_PCIBoardEepromAddress, |*/
-/*| unsigned short w_EepromStartAddress, |*/
-/*| unsigned short * pw_DataRead) |*/
-/*+----------------------------------------------------------------------------+*/
-/*| Task : Read word from the 5920 eeprom. |*/
-/*+----------------------------------------------------------------------------+*/
-/*| Input Parameters : int i_NbOfWordsToRead : Nbr. of word to read |*/
-/*| unsigned int dw_PCIBoardEepromAddress : Address of the eeprom |*/
-/*| unsigned short w_EepromStartAddress : Eeprom start address |*/
-/*+----------------------------------------------------------------------------+*/
-/*| Output Parameters : unsigned short * pw_DataRead : Read data |*/
-/*+----------------------------------------------------------------------------+*/
-/*| Return Value : - |*/
-/*+----------------------------------------------------------------------------+*/
-
-int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead,
- unsigned int dw_PCIBoardEepromAddress,
- unsigned short w_EepromStartAddress, unsigned short *pw_DataRead)
+static int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead,
+ unsigned int dw_PCIBoardEepromAddress,
+ unsigned short w_EepromStartAddress,
+ unsigned short *pw_DataRead)
{
unsigned int dw_eeprom_busy = 0;
int i_Counter = 0;
@@ -241,20 +340,8 @@ int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead,
return 0;
}
-/*+----------------------------------------------------------------------------+*/
-/*| Function Name : void v_GetAPCI3200EepromCalibrationValue (void) |*/
-/*+----------------------------------------------------------------------------+*/
-/*| Task : Read calibration value from the APCI-3200 eeprom. |*/
-/*+----------------------------------------------------------------------------+*/
-/*| Input Parameters : - |*/
-/*+----------------------------------------------------------------------------+*/
-/*| Output Parameters : - |*/
-/*+----------------------------------------------------------------------------+*/
-/*| Return Value : - |*/
-/*+----------------------------------------------------------------------------+*/
-
-void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAddress,
- struct str_BoardInfos *BoardInformations)
+static void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAddress,
+ struct str_BoardInfos *BoardInformations)
{
unsigned short w_AnalogInputMainHeaderAddress;
unsigned short w_AnalogInputComponentAddress;
@@ -448,9 +535,11 @@ void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAddress,
}
}
-int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev,
- unsigned int ui_Channel_num, unsigned int *CJCCurrentSource,
- unsigned int *ChannelCurrentSource, unsigned int *ChannelGainFactor)
+static int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev,
+ unsigned int ui_Channel_num,
+ unsigned int *CJCCurrentSource,
+ unsigned int *ChannelCurrentSource,
+ unsigned int *ChannelGainFactor)
{
int i_DiffChannel = 0;
int i_Module = 0;
@@ -520,1135 +609,46 @@ int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev,
return 0;
}
-/* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-
-/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_ReadDigitalInput |
- | (struct comedi_device *dev,struct comedi_subdevice *s, |
- | struct comedi_insn *insn,unsigned int *data) |
- +----------------------------------------------------------------------------+
- | Task : Read value of the selected channel or port |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | unsigned int ui_NoOfChannels : No Of Channels To read for Port
- Channel Numberfor single channel
- | unsigned int data[0] : 0: Read single channel
- 1: Read port value
- data[1] Port number
- +----------------------------------------------------------------------------+
- | Output Parameters : -- data[0] :Read status value
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
-
-int i_APCI3200_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int apci3200_di_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned int ui_Temp = 0;
- unsigned int ui_NoOfChannel = 0;
- ui_NoOfChannel = CR_CHAN(insn->chanspec);
- ui_Temp = data[0];
- *data = inl(devpriv->i_IobaseReserved);
-
- if (ui_Temp == 0) {
- *data = (*data >> ui_NoOfChannel) & 0x1;
- } /* if (ui_Temp==0) */
- else {
- if (ui_Temp == 1) {
- if (data[1] < 0 || data[1] > 1) {
- printk("\nThe port number is in error\n");
- return -EINVAL;
- } /* if(data[1] < 0 || data[1] >1) */
- switch (ui_NoOfChannel) {
-
- case 2:
- *data = (*data >> (2 * data[1])) & 0x3;
- break;
- case 3:
- *data = (*data & 15);
- break;
- default:
- comedi_error(dev, " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
-
- } /* switch(ui_NoOfChannels) */
- } /* if (ui_Temp==1) */
- else {
- printk("\nSpecified channel not supported \n");
- } /* elseif (ui_Temp==1) */
- }
- return insn->n;
-}
+ struct addi_private *devpriv = dev->private;
-/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_ConfigDigitalOutput |
- | (struct comedi_device *dev,struct comedi_subdevice *s, |
- | struct comedi_insn *insn,unsigned int *data) |
- +----------------------------------------------------------------------------+
- | Task : Configures The Digital Output Subdevice. |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | data[0] :1 Memory enable
- 0 Memory Disable
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
-int i_APCI3200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
+ data[1] = inl(devpriv->i_IobaseReserved) & 0xf;
- if ((data[0] != 0) && (data[0] != 1)) {
- comedi_error(dev,
- "Not a valid Data !!! ,Data should be 1 or 0\n");
- return -EINVAL;
- } /* if ( (data[0]!=0) && (data[0]!=1) ) */
- if (data[0]) {
- devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
- } /* if (data[0]) */
- else {
- devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
- } /* else if (data[0]) */
return insn->n;
}
-/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_WriteDigitalOutput |
- | (struct comedi_device *dev,struct comedi_subdevice *s, |
- | struct comedi_insn *insn,unsigned int *data) |
- +----------------------------------------------------------------------------+
- | Task : writes To the digital Output Subdevice |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | struct comedi_subdevice *s : Subdevice Pointer |
- | struct comedi_insn *insn : Insn Structure Pointer |
- | unsigned int *data : Data Pointer contains |
- | configuration parameters as below |
- | data[0] :Value to output
- data[1] : 0 o/p single channel
- 1 o/p port
- data[2] : port no
- data[3] :0 set the digital o/p on
- 1 set the digital o/p off
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
-int i_APCI3200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int apci3200_do_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned int ui_Temp = 0, ui_Temp1 = 0;
- unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
- if (devpriv->b_OutputMemoryStatus) {
- ui_Temp = inl(devpriv->i_IobaseAddon);
-
- } /* if(devpriv->b_OutputMemoryStatus ) */
- else {
- ui_Temp = 0;
- } /* if(devpriv->b_OutputMemoryStatus ) */
- if (data[3] == 0) {
- if (data[1] == 0) {
- data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
- outl(data[0], devpriv->i_IobaseAddon);
- } /* if(data[1]==0) */
- else {
- if (data[1] == 1) {
- switch (ui_NoOfChannel) {
-
- case 2:
- data[0] =
- (data[0] << (2 *
- data[2])) | ui_Temp;
- break;
- case 3:
- data[0] = (data[0] | ui_Temp);
- break;
- } /* switch(ui_NoOfChannels) */
-
- outl(data[0], devpriv->i_IobaseAddon);
- } /* if(data[1]==1) */
- else {
- printk("\nSpecified channel not supported\n");
- } /* else if(data[1]==1) */
- } /* elseif(data[1]==0) */
- } /* if(data[3]==0) */
- else {
- if (data[3] == 1) {
- if (data[1] == 0) {
- data[0] = ~data[0] & 0x1;
- ui_Temp1 = 1;
- ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] = (data[0] << ui_NoOfChannel) ^ 0xf;
- data[0] = data[0] & ui_Temp;
- outl(data[0], devpriv->i_IobaseAddon);
- } /* if(data[1]==0) */
- else {
- if (data[1] == 1) {
- switch (ui_NoOfChannel) {
-
- case 2:
- data[0] = ~data[0] & 0x3;
- ui_Temp1 = 3;
- ui_Temp1 =
- ui_Temp1 << 2 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (2 *
- data
- [2])) ^
- 0xf) & ui_Temp;
-
- break;
- case 3:
- break;
-
- default:
- comedi_error(dev,
- " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
- } /* switch(ui_NoOfChannels) */
-
- outl(data[0], devpriv->i_IobaseAddon);
- } /* if(data[1]==1) */
- else {
- printk("\nSpecified channel not supported\n");
- } /* else if(data[1]==1) */
- } /* elseif(data[1]==0) */
- } /* if(data[3]==1); */
- else {
- printk("\nSpecified functionality does not exist\n");
- return -EINVAL;
- } /* if else data[3]==1) */
- } /* if else data[3]==0) */
- return insn->n;
-}
-
-/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_ReadDigitalOutput |
- | (struct comedi_device *dev,struct comedi_subdevice *s, |
- | struct comedi_insn *insn,unsigned int *data) |
- +----------------------------------------------------------------------------+
- | Task : Read value of the selected channel or port |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | unsigned int ui_NoOfChannels : No Of Channels To read |
- | unsigned int *data : Data Pointer to read status |
- data[0] :0 read single channel
- 1 read port value
- data[1] port no
-
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
-int i_APCI3200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_Temp;
- unsigned int ui_NoOfChannel;
- ui_NoOfChannel = CR_CHAN(insn->chanspec);
- ui_Temp = data[0];
- *data = inl(devpriv->i_IobaseAddon);
- if (ui_Temp == 0) {
- *data = (*data >> ui_NoOfChannel) & 0x1;
- } /* if (ui_Temp==0) */
- else {
- if (ui_Temp == 1) {
- if (data[1] < 0 || data[1] > 1) {
- printk("\nThe port selection is in error\n");
- return -EINVAL;
- } /* if(data[1] <0 ||data[1] >1) */
- switch (ui_NoOfChannel) {
- case 2:
- *data = (*data >> (2 * data[1])) & 3;
- break;
-
- case 3:
- break;
-
- default:
- comedi_error(dev, " chan spec wrong");
- return -EINVAL; /* "sorry channel spec wrong " */
- break;
- } /* switch(ui_NoOfChannels) */
- } /* if (ui_Temp==1) */
- else {
- printk("\nSpecified channel not supported \n");
- } /* else if (ui_Temp==1) */
- } /* else if (ui_Temp==0) */
- return insn->n;
-}
-
-/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_ConfigAnalogInput |
- | (struct comedi_device *dev,struct comedi_subdevice *s, |
- | struct comedi_insn *insn,unsigned int *data) |
- +----------------------------------------------------------------------------+
- | Task : Configures The Analog Input Subdevice |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | struct comedi_subdevice *s : Subdevice Pointer |
- | struct comedi_insn *insn : Insn Structure Pointer |
- | unsigned int *data : Data Pointer contains |
- | configuration parameters as below |
- | |
- | data[0]
- | 0:Normal AI |
- | 1:RTD |
- | 2:THERMOCOUPLE |
- | data[1] : Gain To Use |
- | |
- | data[2] : Polarity
- | 0:Bipolar |
- | 1:Unipolar |
- | |
- | data[3] : Offset Range
- | |
- | data[4] : Coupling
- | 0:DC Coupling |
- | 1:AC Coupling |
- | |
- | data[5] :Differential/Single
- | 0:Single |
- | 1:Differential |
- | |
- | data[6] :TimerReloadValue
- | |
- | data[7] :ConvertingTimeUnit
- | |
- | data[8] :0 Analog voltage measurement
- 1 Resistance measurement
- 2 Temperature measurement
- | data[9] :Interrupt
- | 0:Disable
- | 1:Enable
- data[10] :Type of Thermocouple
- | data[11] : 0: single channel
- Module Number
- |
- | data[12]
- | 0:Single Read
- | 1:Read more channel
- 2:Single scan
- | 3:Continuous Scan
- data[13] :Number of channels to read
- | data[14] :RTD connection type
- :0:RTD not used
- 1:RTD 2 wire connection
- 2:RTD 3 wire connection
- 3:RTD 4 wire connection
- | |
- | |
- | |
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
-int i_APCI3200_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
-
- unsigned int ul_Config = 0, ul_Temp = 0;
- unsigned int ui_ChannelNo = 0;
- unsigned int ui_Dummy = 0;
- int i_err = 0;
-
- /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-
-#ifdef PRINT_INFO
- int i = 0, i2 = 0;
-#endif
- /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* Initialize the structure */
- if (s_BoardInfos[dev->minor].b_StructInitialized != 1) {
- s_BoardInfos[dev->minor].i_CJCAvailable = 1;
- s_BoardInfos[dev->minor].i_CJCPolarity = 0;
- s_BoardInfos[dev->minor].i_CJCGain = 2; /* changed from 0 to 2 */
- s_BoardInfos[dev->minor].i_InterruptFlag = 0;
- s_BoardInfos[dev->minor].i_AutoCalibration = 0; /* : auto calibration */
- s_BoardInfos[dev->minor].i_ChannelCount = 0;
- s_BoardInfos[dev->minor].i_Sum = 0;
- s_BoardInfos[dev->minor].ui_Channel_num = 0;
- s_BoardInfos[dev->minor].i_Count = 0;
- s_BoardInfos[dev->minor].i_Initialised = 0;
- s_BoardInfos[dev->minor].b_StructInitialized = 1;
-
- /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
- s_BoardInfos[dev->minor].i_ConnectionType = 0;
- /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-
- /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
- memset(s_BoardInfos[dev->minor].s_Module, 0,
- sizeof(s_BoardInfos[dev->minor].s_Module[MAX_MODULE]));
-
- v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc,
- &s_BoardInfos[dev->minor]);
-
-#ifdef PRINT_INFO
- for (i = 0; i < MAX_MODULE; i++) {
- printk("\n s_Module[%i].ul_CurrentSourceCJC = %lu", i,
- s_BoardInfos[dev->minor].s_Module[i].
- ul_CurrentSourceCJC);
-
- for (i2 = 0; i2 < 5; i2++) {
- printk("\n s_Module[%i].ul_CurrentSource [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_CurrentSource[i2]);
- }
-
- for (i2 = 0; i2 < 8; i2++) {
- printk("\n s_Module[%i].ul_GainFactor [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_GainFactor[i2]);
- }
-
- for (i2 = 0; i2 < 8; i2++) {
- printk("\n s_Module[%i].w_GainValue [%i] = %u",
- i, i2,
- s_BoardInfos[dev->minor].s_Module[i].
- w_GainValue[i2]);
- }
- }
-#endif
- /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
- }
-
- if (data[0] != 0 && data[0] != 1 && data[0] != 2) {
- printk("\nThe selection of acquisition type is in error\n");
- i_err++;
- } /* if(data[0]!=0 && data[0]!=1 && data[0]!=2) */
- if (data[0] == 1) {
- if (data[14] != 0 && data[14] != 1 && data[14] != 2
- && data[14] != 4) {
- printk("\n Error in selection of RTD connection type\n");
- i_err++;
- } /* if(data[14]!=0 && data[14]!=1 && data[14]!=2 && data[14]!=4) */
- } /* if(data[0]==1 ) */
- if (data[1] < 0 || data[1] > 7) {
- printk("\nThe selection of gain is in error\n");
- i_err++;
- } /* if(data[1]<0 || data[1]>7) */
- if (data[2] != 0 && data[2] != 1) {
- printk("\nThe selection of polarity is in error\n");
- i_err++;
- } /* if(data[2]!=0 && data[2]!=1) */
- if (data[3] != 0) {
- printk("\nThe selection of offset range is in error\n");
- i_err++;
- } /* if(data[3]!=0) */
- if (data[4] != 0 && data[4] != 1) {
- printk("\nThe selection of coupling is in error\n");
- i_err++;
- } /* if(data[4]!=0 && data[4]!=1) */
- if (data[5] != 0 && data[5] != 1) {
- printk("\nThe selection of single/differential mode is in error\n");
- i_err++;
- } /* if(data[5]!=0 && data[5]!=1) */
- if (data[8] != 0 && data[8] != 1 && data[2] != 2) {
- printk("\nError in selection of functionality\n");
- } /* if(data[8]!=0 && data[8]!=1 && data[2]!=2) */
- if (data[12] == 0 || data[12] == 1) {
- if (data[6] != 20 && data[6] != 40 && data[6] != 80
- && data[6] != 160) {
- printk("\nThe selection of conversion time reload value is in error\n");
- i_err++;
- } /* if (data[6]!=20 && data[6]!=40 && data[6]!=80 && data[6]!=160 ) */
- if (data[7] != 2) {
- printk("\nThe selection of conversion time unit is in error\n");
- i_err++;
- } /* if(data[7]!=2) */
- }
- if (data[9] != 0 && data[9] != 1) {
- printk("\nThe selection of interrupt enable is in error\n");
- i_err++;
- } /* if(data[9]!=0 && data[9]!=1) */
- if (data[11] < 0 || data[11] > 4) {
- printk("\nThe selection of module is in error\n");
- i_err++;
- } /* if(data[11] <0 || data[11]>1) */
- if (data[12] < 0 || data[12] > 3) {
- printk("\nThe selection of singlechannel/scan selection is in error\n");
- i_err++;
- } /* if(data[12] < 0 || data[12]> 3) */
- if (data[13] < 0 || data[13] > 16) {
- printk("\nThe selection of number of channels is in error\n");
- i_err++;
- } /* if(data[13] <0 ||data[13] >15) */
-
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /*
- i_ChannelCount=data[13];
- i_ScanType=data[12];
- i_ADDIDATAPolarity = data[2];
- i_ADDIDATAGain=data[1];
- i_ADDIDATAConversionTime=data[6];
- i_ADDIDATAConversionTimeUnit=data[7];
- i_ADDIDATAType=data[0];
- */
-
- /* Save acquisition configuration for the actual board */
- s_BoardInfos[dev->minor].i_ChannelCount = data[13];
- s_BoardInfos[dev->minor].i_ScanType = data[12];
- s_BoardInfos[dev->minor].i_ADDIDATAPolarity = data[2];
- s_BoardInfos[dev->minor].i_ADDIDATAGain = data[1];
- s_BoardInfos[dev->minor].i_ADDIDATAConversionTime = data[6];
- s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit = data[7];
- s_BoardInfos[dev->minor].i_ADDIDATAType = data[0];
- /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
- s_BoardInfos[dev->minor].i_ConnectionType = data[5];
- /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
- /* END JK 06.07.04: Management of sevrals boards */
-
- /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
- memset(s_BoardInfos[dev->minor].ui_ScanValueArray, 0, (7 + 12) * sizeof(unsigned int)); /* 7 is the maximal number of channels */
- /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
-
- /* BEGIN JK 02.07.04 : This while can't be do, it block the process when using severals boards */
- /* while(i_InterruptFlag==1) */
- while (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
-#ifndef MSXBOX
- udelay(1);
-#else
- /* In the case where the driver is compiled for the MSX-Box */
- /* we used a printk to have a little delay because udelay */
- /* seems to be broken under the MSX-Box. */
- /* This solution hat to be studied. */
- printk("");
-#endif
- }
- /* END JK 02.07.04 : This while can't be do, it block the process when using severals boards */
-
- ui_ChannelNo = CR_CHAN(insn->chanspec); /* get the channel */
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_ChannelNo=ui_ChannelNo; */
- /* ui_Channel_num =ui_ChannelNo; */
-
- s_BoardInfos[dev->minor].i_ChannelNo = ui_ChannelNo;
- s_BoardInfos[dev->minor].ui_Channel_num = ui_ChannelNo;
-
- /* END JK 06.07.04: Management of sevrals boards */
-
- if (data[5] == 0) {
- if (ui_ChannelNo < 0 || ui_ChannelNo > 15) {
- printk("\nThe Selection of the channel is in error\n");
- i_err++;
- } /* if(ui_ChannelNo<0 || ui_ChannelNo>15) */
- } /* if(data[5]==0) */
- else {
- if (data[14] == 2) {
- if (ui_ChannelNo < 0 || ui_ChannelNo > 3) {
- printk("\nThe Selection of the channel is in error\n");
- i_err++;
- } /* if(ui_ChannelNo<0 || ui_ChannelNo>3) */
- } /* if(data[14]==2) */
- else {
- if (ui_ChannelNo < 0 || ui_ChannelNo > 7) {
- printk("\nThe Selection of the channel is in error\n");
- i_err++;
- } /* if(ui_ChannelNo<0 || ui_ChannelNo>7) */
- } /* elseif(data[14]==2) */
- } /* elseif(data[5]==0) */
- if (data[12] == 0 || data[12] == 1) {
- switch (data[5]) {
- case 0:
- if (ui_ChannelNo >= 0 && ui_ChannelNo <= 3) {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Offset=0; */
- s_BoardInfos[dev->minor].i_Offset = 0;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=3) */
- if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Offset=64; */
- s_BoardInfos[dev->minor].i_Offset = 64;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=7) */
- if (ui_ChannelNo >= 8 && ui_ChannelNo <= 11) {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Offset=128; */
- s_BoardInfos[dev->minor].i_Offset = 128;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* if(ui_ChannelNo >=8 && ui_ChannelNo <=11) */
- if (ui_ChannelNo >= 12 && ui_ChannelNo <= 15) {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Offset=192; */
- s_BoardInfos[dev->minor].i_Offset = 192;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* if(ui_ChannelNo >=12 && ui_ChannelNo <=15) */
- break;
- case 1:
- if (data[14] == 2) {
- if (ui_ChannelNo == 0) {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Offset=0; */
- s_BoardInfos[dev->minor].i_Offset = 0;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* if(ui_ChannelNo ==0 ) */
- if (ui_ChannelNo == 1) {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Offset=0; */
- s_BoardInfos[dev->minor].i_Offset = 64;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* if(ui_ChannelNo ==1) */
- if (ui_ChannelNo == 2) {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Offset=128; */
- s_BoardInfos[dev->minor].i_Offset = 128;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* if(ui_ChannelNo ==2 ) */
- if (ui_ChannelNo == 3) {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Offset=192; */
- s_BoardInfos[dev->minor].i_Offset = 192;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* if(ui_ChannelNo ==3) */
-
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_ChannelNo=0; */
- s_BoardInfos[dev->minor].i_ChannelNo = 0;
- /* END JK 06.07.04: Management of sevrals boards */
- ui_ChannelNo = 0;
- break;
- } /* if(data[14]==2) */
- if (ui_ChannelNo >= 0 && ui_ChannelNo <= 1) {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Offset=0; */
- s_BoardInfos[dev->minor].i_Offset = 0;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=1) */
- if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_ChannelNo=i_ChannelNo-2; */
- /* i_Offset=64; */
- s_BoardInfos[dev->minor].i_ChannelNo =
- s_BoardInfos[dev->minor].i_ChannelNo -
- 2;
- s_BoardInfos[dev->minor].i_Offset = 64;
- /* END JK 06.07.04: Management of sevrals boards */
- ui_ChannelNo = ui_ChannelNo - 2;
- } /* if(ui_ChannelNo >=2 && ui_ChannelNo <=3) */
- if (ui_ChannelNo >= 4 && ui_ChannelNo <= 5) {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_ChannelNo=i_ChannelNo-4; */
- /* i_Offset=128; */
- s_BoardInfos[dev->minor].i_ChannelNo =
- s_BoardInfos[dev->minor].i_ChannelNo -
- 4;
- s_BoardInfos[dev->minor].i_Offset = 128;
- /* END JK 06.07.04: Management of sevrals boards */
- ui_ChannelNo = ui_ChannelNo - 4;
- } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=5) */
- if (ui_ChannelNo >= 6 && ui_ChannelNo <= 7) {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_ChannelNo=i_ChannelNo-6; */
- /* i_Offset=192; */
- s_BoardInfos[dev->minor].i_ChannelNo =
- s_BoardInfos[dev->minor].i_ChannelNo -
- 6;
- s_BoardInfos[dev->minor].i_Offset = 192;
- /* END JK 06.07.04: Management of sevrals boards */
- ui_ChannelNo = ui_ChannelNo - 6;
- } /* if(ui_ChannelNo >=6 && ui_ChannelNo <=7) */
- break;
-
- default:
- printk("\n This selection of polarity does not exist\n");
- i_err++;
- } /* switch(data[2]) */
- } /* if(data[12]==0 || data[12]==1) */
- else {
- switch (data[11]) {
- case 1:
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Offset=0; */
- s_BoardInfos[dev->minor].i_Offset = 0;
- /* END JK 06.07.04: Management of sevrals boards */
- break;
- case 2:
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Offset=64; */
- s_BoardInfos[dev->minor].i_Offset = 64;
- /* END JK 06.07.04: Management of sevrals boards */
- break;
- case 3:
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Offset=128; */
- s_BoardInfos[dev->minor].i_Offset = 128;
- /* END JK 06.07.04: Management of sevrals boards */
- break;
- case 4:
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Offset=192; */
- s_BoardInfos[dev->minor].i_Offset = 192;
- /* END JK 06.07.04: Management of sevrals boards */
- break;
- default:
- printk("\nError in module selection\n");
- i_err++;
- } /* switch(data[11]) */
- } /* elseif(data[12]==0 || data[12]==1) */
- if (i_err) {
- i_APCI3200_Reset(dev);
- return -EINVAL;
- }
- /* if(i_ScanType!=1) */
- if (s_BoardInfos[dev->minor].i_ScanType != 1) {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Count=0; */
- /* i_Sum=0; */
- s_BoardInfos[dev->minor].i_Count = 0;
- s_BoardInfos[dev->minor].i_Sum = 0;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* if(i_ScanType!=1) */
-
- ul_Config =
- data[1] | (data[2] << 6) | (data[5] << 7) | (data[3] << 8) |
- (data[4] << 9);
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
- while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
- 12) >> 19) & 1) != 1) ;
- /* END JK 06.07.04: Management of sevrals boards */
- /*********************************/
- /* Write the channel to configure */
- /*********************************/
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4); */
- outl(0 | ui_ChannelNo,
- devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4);
- /* END JK 06.07.04: Management of sevrals boards */
-
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
- while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
- 12) >> 19) & 1) != 1) ;
- /* END JK 06.07.04: Management of sevrals boards */
- /**************************/
- /* Reset the configuration */
- /**************************/
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* outl(0 , devpriv->iobase+i_Offset + 0x0); */
- outl(0, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
- /* END JK 06.07.04: Management of sevrals boards */
-
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
- while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
- 12) >> 19) & 1) != 1) ;
- /* END JK 06.07.04: Management of sevrals boards */
-
- /***************************/
- /* Write the configuration */
- /***************************/
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* outl(ul_Config , devpriv->iobase+i_Offset + 0x0); */
- outl(ul_Config,
- devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
- /* END JK 06.07.04: Management of sevrals boards */
-
- /***************************/
- /*Reset the calibration bit */
- /***************************/
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* ul_Temp = inl(devpriv->iobase+i_Offset + 12); */
- ul_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
- /* END JK 06.07.04: Management of sevrals boards */
-
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
- while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
- 12) >> 19) & 1) != 1) ;
- /* END JK 06.07.04: Management of sevrals boards */
-
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+.i_Offset + 12); */
- outl((ul_Temp & 0xFFF9FFFF),
- devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
- /* END JK 06.07.04: Management of sevrals boards */
+ struct addi_private *devpriv = dev->private;
+ unsigned int mask = data[0];
+ unsigned int bits = data[1];
- if (data[9] == 1) {
- devpriv->tsk_Current = current;
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_InterruptFlag=1; */
- s_BoardInfos[dev->minor].i_InterruptFlag = 1;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* if(data[9]==1) */
- else {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_InterruptFlag=0; */
- s_BoardInfos[dev->minor].i_InterruptFlag = 0;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* else if(data[9]==1) */
-
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Initialised=1; */
- s_BoardInfos[dev->minor].i_Initialised = 1;
- /* END JK 06.07.04: Management of sevrals boards */
+ s->state = inl(devpriv->i_IobaseAddon) & 0xf;
+ if (mask) {
+ s->state &= ~mask;
+ s->state |= (bits & mask)
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* if(i_ScanType==1) */
- if (s_BoardInfos[dev->minor].i_ScanType == 1)
- /* END JK 06.07.04: Management of sevrals boards */
- {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* i_Sum=i_Sum+1; */
- s_BoardInfos[dev->minor].i_Sum =
- s_BoardInfos[dev->minor].i_Sum + 1;
- /* END JK 06.07.04: Management of sevrals boards */
-
- insn->unused[0] = 0;
- i_APCI3200_ReadAnalogInput(dev, s, insn, &ui_Dummy);
+ outl(s->state, devpriv->i_IobaseAddon);
}
- return insn->n;
-}
-
-/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_ReadAnalogInput |
- | (struct comedi_device *dev,struct comedi_subdevice *s, |
- | struct comedi_insn *insn,unsigned int *data) |
- +----------------------------------------------------------------------------+
- | Task : Read value of the selected channel |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | unsigned int ui_NoOfChannels : No Of Channels To read |
- | unsigned int *data : Data Pointer to read status |
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- | data[0] : Digital Value Of Input |
- | data[1] : Calibration Offset Value |
- | data[2] : Calibration Gain Value
- | data[3] : CJC value
- | data[4] : CJC offset value
- | data[5] : CJC gain value
- | Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
- | data[6] : CJC current source from eeprom
- | data[7] : Channel current source from eeprom
- | data[8] : Channle gain factor from eeprom
- | End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
-int i_APCI3200_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_DummyValue = 0;
- int i_ConvertCJCCalibration;
- int i = 0;
-
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* if(i_Initialised==0) */
- if (s_BoardInfos[dev->minor].i_Initialised == 0)
- /* END JK 06.07.04: Management of sevrals boards */
- {
- i_APCI3200_Reset(dev);
- return -EINVAL;
- } /* if(i_Initialised==0); */
-
-#ifdef PRINT_INFO
- printk("\n insn->unused[0] = %i", insn->unused[0]);
-#endif
-
- switch (insn->unused[0]) {
- case 0:
-
- i_APCI3200_Read1AnalogInputChannel(dev, s, insn,
- &ui_DummyValue);
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* ui_InterruptChannelValue[i_Count+0]=ui_DummyValue; */
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[s_BoardInfos[dev->minor].
- i_Count + 0] = ui_DummyValue;
- /* END JK 06.07.04: Management of sevrals boards */
-
- /* Begin JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
- i_APCI3200_GetChannelCalibrationValue(dev,
- s_BoardInfos[dev->minor].ui_Channel_num,
- &s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[s_BoardInfos[dev->minor].
- i_Count + 6],
- &s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[s_BoardInfos[dev->minor].
- i_Count + 7],
- &s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[s_BoardInfos[dev->minor].
- i_Count + 8]);
-
-#ifdef PRINT_INFO
- printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+6] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 6]);
-
- printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+7] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 7]);
-
- printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+8] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 8]);
-#endif
-
- /* End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */
- if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
- && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
- && (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
- /* END JK 06.07.04: Management of sevrals boards */
- {
- i_APCI3200_ReadCJCValue(dev, &ui_DummyValue);
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue; */
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[s_BoardInfos[dev->
- minor].i_Count + 3] = ui_DummyValue;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */
- else {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* ui_InterruptChannelValue[i_Count + 3]=0; */
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[s_BoardInfos[dev->
- minor].i_Count + 3] = 0;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */
-
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */
- if ((s_BoardInfos[dev->minor].i_AutoCalibration == FALSE)
- && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE))
- /* END JK 06.07.04: Management of sevrals boards */
- {
- i_APCI3200_ReadCalibrationOffsetValue(dev,
- &ui_DummyValue);
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue; */
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[s_BoardInfos[dev->
- minor].i_Count + 1] = ui_DummyValue;
- /* END JK 06.07.04: Management of sevrals boards */
- i_APCI3200_ReadCalibrationGainValue(dev,
- &ui_DummyValue);
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue; */
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[s_BoardInfos[dev->
- minor].i_Count + 2] = ui_DummyValue;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */
-
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1)) */
- if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
- && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
- && (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
- /* END JK 06.07.04: Management of sevrals boards */
- {
- /**********************************************************/
- /*Test if the Calibration channel must be read for the CJC */
- /**********************************************************/
- /**********************************/
- /*Test if the polarity is the same */
- /**********************************/
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */
- if (s_BoardInfos[dev->minor].i_CJCPolarity !=
- s_BoardInfos[dev->minor].i_ADDIDATAPolarity)
- /* END JK 06.07.04: Management of sevrals boards */
- {
- i_ConvertCJCCalibration = 1;
- } /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */
- else {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* if(i_CJCGain==i_ADDIDATAGain) */
- if (s_BoardInfos[dev->minor].i_CJCGain ==
- s_BoardInfos[dev->minor].i_ADDIDATAGain)
- /* END JK 06.07.04: Management of sevrals boards */
- {
- i_ConvertCJCCalibration = 0;
- } /* if(i_CJCGain==i_ADDIDATAGain) */
- else {
- i_ConvertCJCCalibration = 1;
- } /* elseif(i_CJCGain==i_ADDIDATAGain) */
- } /* elseif(i_CJCPolarity!=i_ADDIDATAPolarity) */
- if (i_ConvertCJCCalibration == 1) {
- i_APCI3200_ReadCJCCalOffset(dev,
- &ui_DummyValue);
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* ui_InterruptChannelValue[i_Count+4]=ui_DummyValue; */
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[s_BoardInfos
- [dev->minor].i_Count + 4] =
- ui_DummyValue;
- /* END JK 06.07.04: Management of sevrals boards */
-
- i_APCI3200_ReadCJCCalGain(dev, &ui_DummyValue);
-
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* ui_InterruptChannelValue[i_Count+5]=ui_DummyValue; */
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[s_BoardInfos
- [dev->minor].i_Count + 5] =
- ui_DummyValue;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* if(i_ConvertCJCCalibration==1) */
- else {
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* ui_InterruptChannelValue[i_Count+4]=0; */
- /* ui_InterruptChannelValue[i_Count+5]=0; */
-
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[s_BoardInfos
- [dev->minor].i_Count + 4] = 0;
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[s_BoardInfos
- [dev->minor].i_Count + 5] = 0;
- /* END JK 06.07.04: Management of sevrals boards */
- } /* elseif(i_ConvertCJCCalibration==1) */
- } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */
-
- /* BEGIN JK 06.07.04: Management of sevrals boards */
- /* if(i_ScanType!=1) */
- if (s_BoardInfos[dev->minor].i_ScanType != 1) {
- /* i_Count=0; */
- s_BoardInfos[dev->minor].i_Count = 0;
- } /* if(i_ScanType!=1) */
- else {
- /* i_Count=i_Count +6; */
- /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
- /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count +6; */
- s_BoardInfos[dev->minor].i_Count =
- s_BoardInfos[dev->minor].i_Count + 9;
- /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
- } /* else if(i_ScanType!=1) */
-
- /* if((i_ScanType==1) &&(i_InterruptFlag==1)) */
- if ((s_BoardInfos[dev->minor].i_ScanType == 1)
- && (s_BoardInfos[dev->minor].i_InterruptFlag == 1)) {
- /* i_Count=i_Count-6; */
- /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
- /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count-6; */
- s_BoardInfos[dev->minor].i_Count =
- s_BoardInfos[dev->minor].i_Count - 9;
- /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
- }
- /* if(i_ScanType==0) */
- if (s_BoardInfos[dev->minor].i_ScanType == 0) {
- /*
- data[0]= ui_InterruptChannelValue[0];
- data[1]= ui_InterruptChannelValue[1];
- data[2]= ui_InterruptChannelValue[2];
- data[3]= ui_InterruptChannelValue[3];
- data[4]= ui_InterruptChannelValue[4];
- data[5]= ui_InterruptChannelValue[5];
- */
-#ifdef PRINT_INFO
- printk("\n data[0]= s_BoardInfos [dev->minor].ui_InterruptChannelValue[0];");
-#endif
- data[0] =
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[0];
- data[1] =
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[1];
- data[2] =
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[2];
- data[3] =
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[3];
- data[4] =
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[4];
- data[5] =
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[5];
-
- /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
- /* printk("\n 0 - i_APCI3200_GetChannelCalibrationValue data [6] = %lu, data [7] = %lu, data [8] = %lu", data [6], data [7], data [8]); */
- i_APCI3200_GetChannelCalibrationValue(dev,
- s_BoardInfos[dev->minor].ui_Channel_num,
- &data[6], &data[7], &data[8]);
- /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
- }
- break;
- case 1:
-
- for (i = 0; i < insn->n; i++) {
- /* data[i]=ui_InterruptChannelValue[i]; */
- data[i] =
- s_BoardInfos[dev->minor].
- ui_InterruptChannelValue[i];
- }
-
- /* i_Count=0; */
- /* i_Sum=0; */
- /* if(i_ScanType==1) */
- s_BoardInfos[dev->minor].i_Count = 0;
- s_BoardInfos[dev->minor].i_Sum = 0;
- if (s_BoardInfos[dev->minor].i_ScanType == 1) {
- /* i_Initialised=0; */
- /* i_InterruptFlag=0; */
- s_BoardInfos[dev->minor].i_Initialised = 0;
- s_BoardInfos[dev->minor].i_InterruptFlag = 0;
- /* END JK 06.07.04: Management of sevrals boards */
- }
- break;
- default:
- printk("\nThe parameters passed are in error\n");
- i_APCI3200_Reset(dev);
- return -EINVAL;
- } /* switch(insn->unused[0]) */
+ data[1] = s->state;
return insn->n;
}
-/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_Read1AnalogInputChannel |
- | (struct comedi_device *dev,struct comedi_subdevice *s, |
- | struct comedi_insn *insn,unsigned int *data) |
- +----------------------------------------------------------------------------+
- | Task : Read value of the selected channel |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | unsigned int ui_NoOfChannel : Channel No to read |
- | unsigned int *data : Data Pointer to read status |
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- | data[0] : Digital Value read |
- |
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
-int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ui_EOC = 0;
unsigned int ui_ChannelNo = 0;
unsigned int ui_CommandRegister = 0;
@@ -1751,28 +751,10 @@ int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
return 0;
}
-/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_ReadCalibrationOffsetValue |
- | (struct comedi_device *dev,struct comedi_subdevice *s, |
- | struct comedi_insn *insn,unsigned int *data) |
- +----------------------------------------------------------------------------+
- | Task : Read calibration offset value of the selected channel|
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | unsigned int *data : Data Pointer to read status |
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- | data[0] : Calibration offset Value |
- |
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
-int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, unsigned int *data)
+static int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ui_Temp = 0, ui_EOC = 0;
unsigned int ui_CommandRegister = 0;
@@ -1887,28 +869,10 @@ int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, unsigned in
return 0;
}
-/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_ReadCalibrationGainValue |
- | (struct comedi_device *dev,struct comedi_subdevice *s, |
- | struct comedi_insn *insn,unsigned int *data) |
- +----------------------------------------------------------------------------+
- | Task : Read calibration gain value of the selected channel |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | unsigned int *data : Data Pointer to read status |
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- | data[0] : Calibration gain Value Of Input |
- |
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
-int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, unsigned int *data)
+static int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ui_EOC = 0;
int ui_CommandRegister = 0;
@@ -2022,29 +986,10 @@ int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, unsigned int
return 0;
}
-/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_ReadCJCValue |
- | (struct comedi_device *dev,struct comedi_subdevice *s, |
- | struct comedi_insn *insn,unsigned int *data) |
- +----------------------------------------------------------------------------+
- | Task : Read CJC value of the selected channel |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | unsigned int *data : Data Pointer to read status |
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- | data[0] : CJC Value |
- |
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
-
-int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data)
+static int i_APCI3200_ReadCJCValue(struct comedi_device *dev,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ui_EOC = 0;
int ui_CommandRegister = 0;
@@ -2142,30 +1087,13 @@ int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data)
return 0;
}
-/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_ReadCJCCalOffset |
- | (struct comedi_device *dev,struct comedi_subdevice *s, |
- | struct comedi_insn *insn,unsigned int *data) |
- +----------------------------------------------------------------------------+
- | Task : Read CJC calibration offset value of the selected channel
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | unsigned int *data : Data Pointer to read status |
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- | data[0] : CJC calibration offset Value
- |
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
-int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data)
+static int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ui_EOC = 0;
int ui_CommandRegister = 0;
+
/*******************************************/
/*Read calibration offset value for the CJC */
/*******************************************/
@@ -2257,31 +1185,13 @@ int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data)
return 0;
}
-/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_ReadCJCGainValue |
- | (struct comedi_device *dev,struct comedi_subdevice *s, |
- | struct comedi_insn *insn,unsigned int *data) |
- +----------------------------------------------------------------------------+
- | Task : Read CJC calibration gain value
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | unsigned int ui_NoOfChannels : No Of Channels To read |
- | unsigned int *data : Data Pointer to read status |
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- | data[0] : CJC calibration gain value
- |
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
-int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data)
+static int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ui_EOC = 0;
int ui_CommandRegister = 0;
+
/*******************************/
/* Set the convert timing unit */
/*******************************/
@@ -2367,43 +1277,842 @@ int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data)
return 0;
}
+static int i_APCI3200_Reset(struct comedi_device *dev)
+{
+ struct addi_private *devpriv = dev->private;
+ int i_Temp;
+ unsigned int dw_Dummy;
+
+ /* i_InterruptFlag=0; */
+ /* i_Initialised==0; */
+ /* i_Count=0; */
+ /* i_Sum=0; */
+
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ s_BoardInfos[dev->minor].b_StructInitialized = 0;
+
+ outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
+
+ /* Enable the interrupt for the controller */
+ dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
+ outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
+ outl(0, devpriv->i_IobaseAddon); /* Resets the output */
+ /***************/
+ /*Empty the buffer */
+ /**************/
+ for (i_Temp = 0; i_Temp <= 95; i_Temp++) {
+ /* ui_InterruptChannelValue[i_Temp]=0; */
+ s_BoardInfos[dev->minor].ui_InterruptChannelValue[i_Temp] = 0;
+ } /* for(i_Temp=0;i_Temp<=95;i_Temp++) */
+ /*****************************/
+ /*Reset the START and IRQ bit */
+ /*****************************/
+ for (i_Temp = 0; i_Temp <= 192;) {
+ while (((inl(devpriv->iobase + i_Temp + 12) >> 19) & 1) != 1) ;
+ outl(0, devpriv->iobase + i_Temp + 8);
+ i_Temp = i_Temp + 64;
+ } /* for(i_Temp=0;i_Temp<=192;i_Temp+64) */
+ return 0;
+}
+
/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_InsnBits_AnalogInput_Test |
- | (struct comedi_device *dev,struct comedi_subdevice *s, |
- | struct comedi_insn *insn,unsigned int *data) |
- +----------------------------------------------------------------------------+
- | Task : Tests the Selected Anlog Input Channel |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | struct comedi_subdevice *s : Subdevice Pointer |
- | struct comedi_insn *insn : Insn Structure Pointer |
- | unsigned int *data : Data Pointer contains |
- | configuration parameters as below |
- |
- |
- | data[0] : 0 TestAnalogInputShortCircuit
- | 1 TestAnalogInputConnection |
-
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- | data[0] : Digital value obtained |
- | data[1] : calibration offset |
- | data[2] : calibration gain |
- | |
- | |
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
+ * Read value of the selected channel
+ *
+ * data[0] : Digital Value Of Input
+ * data[1] : Calibration Offset Value
+ * data[2] : Calibration Gain Value
+ * data[3] : CJC value
+ * data[4] : CJC offset value
+ * data[5] : CJC gain value
+ * data[6] : CJC current source from eeprom
+ * data[7] : Channel current source from eeprom
+ * data[8] : Channle gain factor from eeprom
+ */
+static int i_APCI3200_ReadAnalogInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ unsigned int ui_DummyValue = 0;
+ int i_ConvertCJCCalibration;
+ int i = 0;
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* if(i_Initialised==0) */
+ if (s_BoardInfos[dev->minor].i_Initialised == 0)
+ /* END JK 06.07.04: Management of sevrals boards */
+ {
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ } /* if(i_Initialised==0); */
+
+#ifdef PRINT_INFO
+ printk("\n insn->unused[0] = %i", insn->unused[0]);
+#endif
+
+ switch (insn->unused[0]) {
+ case 0:
-int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+ i_APCI3200_Read1AnalogInputChannel(dev, s, insn,
+ &ui_DummyValue);
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* ui_InterruptChannelValue[i_Count+0]=ui_DummyValue; */
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 0] = ui_DummyValue;
+ /* END JK 06.07.04: Management of sevrals boards */
+
+ /* Begin JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+ i_APCI3200_GetChannelCalibrationValue(dev,
+ s_BoardInfos[dev->minor].ui_Channel_num,
+ &s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 6],
+ &s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 7],
+ &s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 8]);
+
+#ifdef PRINT_INFO
+ printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+6] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 6]);
+
+ printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+7] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 7]);
+
+ printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+8] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 8]);
+#endif
+
+ /* End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */
+ if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
+ && (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
+ /* END JK 06.07.04: Management of sevrals boards */
+ {
+ i_APCI3200_ReadCJCValue(dev, &ui_DummyValue);
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue; */
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 3] = ui_DummyValue;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */
+ else {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* ui_InterruptChannelValue[i_Count + 3]=0; */
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 3] = 0;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */
+ if ((s_BoardInfos[dev->minor].i_AutoCalibration == FALSE)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE))
+ /* END JK 06.07.04: Management of sevrals boards */
+ {
+ i_APCI3200_ReadCalibrationOffsetValue(dev,
+ &ui_DummyValue);
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue; */
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 1] = ui_DummyValue;
+ /* END JK 06.07.04: Management of sevrals boards */
+ i_APCI3200_ReadCalibrationGainValue(dev,
+ &ui_DummyValue);
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue; */
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 2] = ui_DummyValue;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1)) */
+ if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
+ && (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
+ /* END JK 06.07.04: Management of sevrals boards */
+ {
+ /**********************************************************/
+ /*Test if the Calibration channel must be read for the CJC */
+ /**********************************************************/
+ /**********************************/
+ /*Test if the polarity is the same */
+ /**********************************/
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */
+ if (s_BoardInfos[dev->minor].i_CJCPolarity !=
+ s_BoardInfos[dev->minor].i_ADDIDATAPolarity)
+ /* END JK 06.07.04: Management of sevrals boards */
+ {
+ i_ConvertCJCCalibration = 1;
+ } /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */
+ else {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* if(i_CJCGain==i_ADDIDATAGain) */
+ if (s_BoardInfos[dev->minor].i_CJCGain ==
+ s_BoardInfos[dev->minor].i_ADDIDATAGain)
+ /* END JK 06.07.04: Management of sevrals boards */
+ {
+ i_ConvertCJCCalibration = 0;
+ } /* if(i_CJCGain==i_ADDIDATAGain) */
+ else {
+ i_ConvertCJCCalibration = 1;
+ } /* elseif(i_CJCGain==i_ADDIDATAGain) */
+ } /* elseif(i_CJCPolarity!=i_ADDIDATAPolarity) */
+ if (i_ConvertCJCCalibration == 1) {
+ i_APCI3200_ReadCJCCalOffset(dev,
+ &ui_DummyValue);
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* ui_InterruptChannelValue[i_Count+4]=ui_DummyValue; */
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 4] =
+ ui_DummyValue;
+ /* END JK 06.07.04: Management of sevrals boards */
+
+ i_APCI3200_ReadCJCCalGain(dev, &ui_DummyValue);
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* ui_InterruptChannelValue[i_Count+5]=ui_DummyValue; */
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 5] =
+ ui_DummyValue;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* if(i_ConvertCJCCalibration==1) */
+ else {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* ui_InterruptChannelValue[i_Count+4]=0; */
+ /* ui_InterruptChannelValue[i_Count+5]=0; */
+
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 4] = 0;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 5] = 0;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* elseif(i_ConvertCJCCalibration==1) */
+ } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* if(i_ScanType!=1) */
+ if (s_BoardInfos[dev->minor].i_ScanType != 1) {
+ /* i_Count=0; */
+ s_BoardInfos[dev->minor].i_Count = 0;
+ } /* if(i_ScanType!=1) */
+ else {
+ /* i_Count=i_Count +6; */
+ /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+ /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count +6; */
+ s_BoardInfos[dev->minor].i_Count =
+ s_BoardInfos[dev->minor].i_Count + 9;
+ /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+ } /* else if(i_ScanType!=1) */
+
+ /* if((i_ScanType==1) &&(i_InterruptFlag==1)) */
+ if ((s_BoardInfos[dev->minor].i_ScanType == 1)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == 1)) {
+ /* i_Count=i_Count-6; */
+ /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+ /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count-6; */
+ s_BoardInfos[dev->minor].i_Count =
+ s_BoardInfos[dev->minor].i_Count - 9;
+ /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+ }
+ /* if(i_ScanType==0) */
+ if (s_BoardInfos[dev->minor].i_ScanType == 0) {
+ /*
+ data[0]= ui_InterruptChannelValue[0];
+ data[1]= ui_InterruptChannelValue[1];
+ data[2]= ui_InterruptChannelValue[2];
+ data[3]= ui_InterruptChannelValue[3];
+ data[4]= ui_InterruptChannelValue[4];
+ data[5]= ui_InterruptChannelValue[5];
+ */
+#ifdef PRINT_INFO
+ printk("\n data[0]= s_BoardInfos [dev->minor].ui_InterruptChannelValue[0];");
+#endif
+ data[0] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[0];
+ data[1] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[1];
+ data[2] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[2];
+ data[3] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[3];
+ data[4] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[4];
+ data[5] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[5];
+
+ /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+ /* printk("\n 0 - i_APCI3200_GetChannelCalibrationValue data [6] = %lu, data [7] = %lu, data [8] = %lu", data [6], data [7], data [8]); */
+ i_APCI3200_GetChannelCalibrationValue(dev,
+ s_BoardInfos[dev->minor].ui_Channel_num,
+ &data[6], &data[7], &data[8]);
+ /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+ }
+ break;
+ case 1:
+
+ for (i = 0; i < insn->n; i++) {
+ /* data[i]=ui_InterruptChannelValue[i]; */
+ data[i] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[i];
+ }
+
+ /* i_Count=0; */
+ /* i_Sum=0; */
+ /* if(i_ScanType==1) */
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ if (s_BoardInfos[dev->minor].i_ScanType == 1) {
+ /* i_Initialised=0; */
+ /* i_InterruptFlag=0; */
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ /* END JK 06.07.04: Management of sevrals boards */
+ }
+ break;
+ default:
+ printk("\nThe parameters passed are in error\n");
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ } /* switch(insn->unused[0]) */
+
+ return insn->n;
+}
+
+/*
+ * Configures The Analog Input Subdevice
+ *
+ * data[0] = 0 Normal AI
+ * = 1 RTD
+ * = 2 THERMOCOUPLE
+ * data[1] = Gain To Use
+ * data[2] = 0 Bipolar
+ * = 1 Unipolar
+ * data[3] = Offset Range
+ * data[4] = 0 DC Coupling
+ * = 1 AC Coupling
+ * data[5] = 0 Single
+ * = 1 Differential
+ * data[6] = TimerReloadValue
+ * data[7] = ConvertingTimeUnit
+ * data[8] = 0 Analog voltage measurement
+ * = 1 Resistance measurement
+ * = 2 Temperature measurement
+ * data[9] = 0 Interrupt Disable
+ * = 1 INterrupt Enable
+ * data[10] = Type of Thermocouple
+ * data[11] = single channel Module Number
+ * data[12] = 0 Single Read
+ * = 1 Read more channel
+ * = 2 Single scan
+ * = 3 Continuous Scan
+ * data[13] = Number of channels to read
+ * data[14] = 0 RTD not used
+ * = 1 RTD 2 wire connection
+ * = 2 RTD 3 wire connection
+ * = 3 RTD 4 wire connection
+ */
+static int i_APCI3200_ConfigAnalogInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
+ unsigned int ul_Config = 0, ul_Temp = 0;
+ unsigned int ui_ChannelNo = 0;
+ unsigned int ui_Dummy = 0;
+ int i_err = 0;
+
+ /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+
+#ifdef PRINT_INFO
+ int i = 0, i2 = 0;
+#endif
+ /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* Initialize the structure */
+ if (s_BoardInfos[dev->minor].b_StructInitialized != 1) {
+ s_BoardInfos[dev->minor].i_CJCAvailable = 1;
+ s_BoardInfos[dev->minor].i_CJCPolarity = 0;
+ s_BoardInfos[dev->minor].i_CJCGain = 2; /* changed from 0 to 2 */
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ s_BoardInfos[dev->minor].i_AutoCalibration = 0; /* : auto calibration */
+ s_BoardInfos[dev->minor].i_ChannelCount = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ s_BoardInfos[dev->minor].ui_Channel_num = 0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].b_StructInitialized = 1;
+
+ /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+ s_BoardInfos[dev->minor].i_ConnectionType = 0;
+ /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+
+ /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+ memset(s_BoardInfos[dev->minor].s_Module, 0,
+ sizeof(s_BoardInfos[dev->minor].s_Module[MAX_MODULE]));
+
+ v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc,
+ &s_BoardInfos[dev->minor]);
+
+#ifdef PRINT_INFO
+ for (i = 0; i < MAX_MODULE; i++) {
+ printk("\n s_Module[%i].ul_CurrentSourceCJC = %lu", i,
+ s_BoardInfos[dev->minor].s_Module[i].
+ ul_CurrentSourceCJC);
+
+ for (i2 = 0; i2 < 5; i2++) {
+ printk("\n s_Module[%i].ul_CurrentSource [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_CurrentSource[i2]);
+ }
+
+ for (i2 = 0; i2 < 8; i2++) {
+ printk("\n s_Module[%i].ul_GainFactor [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_GainFactor[i2]);
+ }
+
+ for (i2 = 0; i2 < 8; i2++) {
+ printk("\n s_Module[%i].w_GainValue [%i] = %u",
+ i, i2,
+ s_BoardInfos[dev->minor].s_Module[i].
+ w_GainValue[i2]);
+ }
+ }
+#endif
+ /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+ }
+
+ if (data[0] != 0 && data[0] != 1 && data[0] != 2) {
+ printk("\nThe selection of acquisition type is in error\n");
+ i_err++;
+ } /* if(data[0]!=0 && data[0]!=1 && data[0]!=2) */
+ if (data[0] == 1) {
+ if (data[14] != 0 && data[14] != 1 && data[14] != 2
+ && data[14] != 4) {
+ printk("\n Error in selection of RTD connection type\n");
+ i_err++;
+ } /* if(data[14]!=0 && data[14]!=1 && data[14]!=2 && data[14]!=4) */
+ } /* if(data[0]==1 ) */
+ if (data[1] < 0 || data[1] > 7) {
+ printk("\nThe selection of gain is in error\n");
+ i_err++;
+ } /* if(data[1]<0 || data[1]>7) */
+ if (data[2] != 0 && data[2] != 1) {
+ printk("\nThe selection of polarity is in error\n");
+ i_err++;
+ } /* if(data[2]!=0 && data[2]!=1) */
+ if (data[3] != 0) {
+ printk("\nThe selection of offset range is in error\n");
+ i_err++;
+ } /* if(data[3]!=0) */
+ if (data[4] != 0 && data[4] != 1) {
+ printk("\nThe selection of coupling is in error\n");
+ i_err++;
+ } /* if(data[4]!=0 && data[4]!=1) */
+ if (data[5] != 0 && data[5] != 1) {
+ printk("\nThe selection of single/differential mode is in error\n");
+ i_err++;
+ } /* if(data[5]!=0 && data[5]!=1) */
+ if (data[8] != 0 && data[8] != 1 && data[2] != 2) {
+ printk("\nError in selection of functionality\n");
+ } /* if(data[8]!=0 && data[8]!=1 && data[2]!=2) */
+ if (data[12] == 0 || data[12] == 1) {
+ if (data[6] != 20 && data[6] != 40 && data[6] != 80
+ && data[6] != 160) {
+ printk("\nThe selection of conversion time reload value is in error\n");
+ i_err++;
+ } /* if (data[6]!=20 && data[6]!=40 && data[6]!=80 && data[6]!=160 ) */
+ if (data[7] != 2) {
+ printk("\nThe selection of conversion time unit is in error\n");
+ i_err++;
+ } /* if(data[7]!=2) */
+ }
+ if (data[9] != 0 && data[9] != 1) {
+ printk("\nThe selection of interrupt enable is in error\n");
+ i_err++;
+ } /* if(data[9]!=0 && data[9]!=1) */
+ if (data[11] < 0 || data[11] > 4) {
+ printk("\nThe selection of module is in error\n");
+ i_err++;
+ } /* if(data[11] <0 || data[11]>1) */
+ if (data[12] < 0 || data[12] > 3) {
+ printk("\nThe selection of singlechannel/scan selection is in error\n");
+ i_err++;
+ } /* if(data[12] < 0 || data[12]> 3) */
+ if (data[13] < 0 || data[13] > 16) {
+ printk("\nThe selection of number of channels is in error\n");
+ i_err++;
+ } /* if(data[13] <0 ||data[13] >15) */
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /*
+ i_ChannelCount=data[13];
+ i_ScanType=data[12];
+ i_ADDIDATAPolarity = data[2];
+ i_ADDIDATAGain=data[1];
+ i_ADDIDATAConversionTime=data[6];
+ i_ADDIDATAConversionTimeUnit=data[7];
+ i_ADDIDATAType=data[0];
+ */
+
+ /* Save acquisition configuration for the actual board */
+ s_BoardInfos[dev->minor].i_ChannelCount = data[13];
+ s_BoardInfos[dev->minor].i_ScanType = data[12];
+ s_BoardInfos[dev->minor].i_ADDIDATAPolarity = data[2];
+ s_BoardInfos[dev->minor].i_ADDIDATAGain = data[1];
+ s_BoardInfos[dev->minor].i_ADDIDATAConversionTime = data[6];
+ s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit = data[7];
+ s_BoardInfos[dev->minor].i_ADDIDATAType = data[0];
+ /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+ s_BoardInfos[dev->minor].i_ConnectionType = data[5];
+ /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+ /* END JK 06.07.04: Management of sevrals boards */
+
+ /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+ memset(s_BoardInfos[dev->minor].ui_ScanValueArray, 0, (7 + 12) * sizeof(unsigned int)); /* 7 is the maximal number of channels */
+ /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+
+ /* BEGIN JK 02.07.04 : This while can't be do, it block the process when using severals boards */
+ /* while(i_InterruptFlag==1) */
+ while (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
+#ifndef MSXBOX
+ udelay(1);
+#else
+ /* In the case where the driver is compiled for the MSX-Box */
+ /* we used a printk to have a little delay because udelay */
+ /* seems to be broken under the MSX-Box. */
+ /* This solution hat to be studied. */
+ printk("");
+#endif
+ }
+ /* END JK 02.07.04 : This while can't be do, it block the process when using severals boards */
+
+ ui_ChannelNo = CR_CHAN(insn->chanspec); /* get the channel */
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_ChannelNo=ui_ChannelNo; */
+ /* ui_Channel_num =ui_ChannelNo; */
+
+ s_BoardInfos[dev->minor].i_ChannelNo = ui_ChannelNo;
+ s_BoardInfos[dev->minor].ui_Channel_num = ui_ChannelNo;
+
+ /* END JK 06.07.04: Management of sevrals boards */
+
+ if (data[5] == 0) {
+ if (ui_ChannelNo < 0 || ui_ChannelNo > 15) {
+ printk("\nThe Selection of the channel is in error\n");
+ i_err++;
+ } /* if(ui_ChannelNo<0 || ui_ChannelNo>15) */
+ } /* if(data[5]==0) */
+ else {
+ if (data[14] == 2) {
+ if (ui_ChannelNo < 0 || ui_ChannelNo > 3) {
+ printk("\nThe Selection of the channel is in error\n");
+ i_err++;
+ } /* if(ui_ChannelNo<0 || ui_ChannelNo>3) */
+ } /* if(data[14]==2) */
+ else {
+ if (ui_ChannelNo < 0 || ui_ChannelNo > 7) {
+ printk("\nThe Selection of the channel is in error\n");
+ i_err++;
+ } /* if(ui_ChannelNo<0 || ui_ChannelNo>7) */
+ } /* elseif(data[14]==2) */
+ } /* elseif(data[5]==0) */
+ if (data[12] == 0 || data[12] == 1) {
+ switch (data[5]) {
+ case 0:
+ if (ui_ChannelNo >= 0 && ui_ChannelNo <= 3) {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Offset=0; */
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=3) */
+ if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Offset=64; */
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=7) */
+ if (ui_ChannelNo >= 8 && ui_ChannelNo <= 11) {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Offset=128; */
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* if(ui_ChannelNo >=8 && ui_ChannelNo <=11) */
+ if (ui_ChannelNo >= 12 && ui_ChannelNo <= 15) {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Offset=192; */
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* if(ui_ChannelNo >=12 && ui_ChannelNo <=15) */
+ break;
+ case 1:
+ if (data[14] == 2) {
+ if (ui_ChannelNo == 0) {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Offset=0; */
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* if(ui_ChannelNo ==0 ) */
+ if (ui_ChannelNo == 1) {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Offset=0; */
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* if(ui_ChannelNo ==1) */
+ if (ui_ChannelNo == 2) {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Offset=128; */
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* if(ui_ChannelNo ==2 ) */
+ if (ui_ChannelNo == 3) {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Offset=192; */
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* if(ui_ChannelNo ==3) */
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_ChannelNo=0; */
+ s_BoardInfos[dev->minor].i_ChannelNo = 0;
+ /* END JK 06.07.04: Management of sevrals boards */
+ ui_ChannelNo = 0;
+ break;
+ } /* if(data[14]==2) */
+ if (ui_ChannelNo >= 0 && ui_ChannelNo <= 1) {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Offset=0; */
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=1) */
+ if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_ChannelNo=i_ChannelNo-2; */
+ /* i_Offset=64; */
+ s_BoardInfos[dev->minor].i_ChannelNo =
+ s_BoardInfos[dev->minor].i_ChannelNo -
+ 2;
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ /* END JK 06.07.04: Management of sevrals boards */
+ ui_ChannelNo = ui_ChannelNo - 2;
+ } /* if(ui_ChannelNo >=2 && ui_ChannelNo <=3) */
+ if (ui_ChannelNo >= 4 && ui_ChannelNo <= 5) {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_ChannelNo=i_ChannelNo-4; */
+ /* i_Offset=128; */
+ s_BoardInfos[dev->minor].i_ChannelNo =
+ s_BoardInfos[dev->minor].i_ChannelNo -
+ 4;
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ /* END JK 06.07.04: Management of sevrals boards */
+ ui_ChannelNo = ui_ChannelNo - 4;
+ } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=5) */
+ if (ui_ChannelNo >= 6 && ui_ChannelNo <= 7) {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_ChannelNo=i_ChannelNo-6; */
+ /* i_Offset=192; */
+ s_BoardInfos[dev->minor].i_ChannelNo =
+ s_BoardInfos[dev->minor].i_ChannelNo -
+ 6;
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ /* END JK 06.07.04: Management of sevrals boards */
+ ui_ChannelNo = ui_ChannelNo - 6;
+ } /* if(ui_ChannelNo >=6 && ui_ChannelNo <=7) */
+ break;
+
+ default:
+ printk("\n This selection of polarity does not exist\n");
+ i_err++;
+ } /* switch(data[2]) */
+ } /* if(data[12]==0 || data[12]==1) */
+ else {
+ switch (data[11]) {
+ case 1:
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Offset=0; */
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ /* END JK 06.07.04: Management of sevrals boards */
+ break;
+ case 2:
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Offset=64; */
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ /* END JK 06.07.04: Management of sevrals boards */
+ break;
+ case 3:
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Offset=128; */
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ /* END JK 06.07.04: Management of sevrals boards */
+ break;
+ case 4:
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Offset=192; */
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ /* END JK 06.07.04: Management of sevrals boards */
+ break;
+ default:
+ printk("\nError in module selection\n");
+ i_err++;
+ } /* switch(data[11]) */
+ } /* elseif(data[12]==0 || data[12]==1) */
+ if (i_err) {
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ }
+ /* if(i_ScanType!=1) */
+ if (s_BoardInfos[dev->minor].i_ScanType != 1) {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Count=0; */
+ /* i_Sum=0; */
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* if(i_ScanType!=1) */
+
+ ul_Config =
+ data[1] | (data[2] << 6) | (data[5] << 7) | (data[3] << 8) |
+ (data[4] << 9);
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ /* END JK 06.07.04: Management of sevrals boards */
+ /*********************************/
+ /* Write the channel to configure */
+ /*********************************/
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4); */
+ outl(0 | ui_ChannelNo,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4);
+ /* END JK 06.07.04: Management of sevrals boards */
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ /* END JK 06.07.04: Management of sevrals boards */
+ /**************************/
+ /* Reset the configuration */
+ /**************************/
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* outl(0 , devpriv->iobase+i_Offset + 0x0); */
+ outl(0, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
+ /* END JK 06.07.04: Management of sevrals boards */
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ /* END JK 06.07.04: Management of sevrals boards */
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* outl(ul_Config , devpriv->iobase+i_Offset + 0x0); */
+ outl(ul_Config,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
+ /* END JK 06.07.04: Management of sevrals boards */
+
+ /***************************/
+ /*Reset the calibration bit */
+ /***************************/
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* ul_Temp = inl(devpriv->iobase+i_Offset + 12); */
+ ul_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ /* END JK 06.07.04: Management of sevrals boards */
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ /* END JK 06.07.04: Management of sevrals boards */
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+.i_Offset + 12); */
+ outl((ul_Temp & 0xFFF9FFFF),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ /* END JK 06.07.04: Management of sevrals boards */
+
+ if (data[9] == 1) {
+ devpriv->tsk_Current = current;
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_InterruptFlag=1; */
+ s_BoardInfos[dev->minor].i_InterruptFlag = 1;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* if(data[9]==1) */
+ else {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_InterruptFlag=0; */
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ /* END JK 06.07.04: Management of sevrals boards */
+ } /* else if(data[9]==1) */
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Initialised=1; */
+ s_BoardInfos[dev->minor].i_Initialised = 1;
+ /* END JK 06.07.04: Management of sevrals boards */
+
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* if(i_ScanType==1) */
+ if (s_BoardInfos[dev->minor].i_ScanType == 1)
+ /* END JK 06.07.04: Management of sevrals boards */
+ {
+ /* BEGIN JK 06.07.04: Management of sevrals boards */
+ /* i_Sum=i_Sum+1; */
+ s_BoardInfos[dev->minor].i_Sum =
+ s_BoardInfos[dev->minor].i_Sum + 1;
+ /* END JK 06.07.04: Management of sevrals boards */
+
+ insn->unused[0] = 0;
+ i_APCI3200_ReadAnalogInput(dev, s, insn, &ui_Dummy);
+ }
+
+ return insn->n;
+}
+
+/*
+ * Tests the Selected Anlog Input Channel
+ *
+ * data[0] = 0 TestAnalogInputShortCircuit
+ * = 1 TestAnalogInputConnection
+ *
+ * data[0] : Digital value obtained
+ * data[1] : calibration offset
+ * data[2] : calibration gain
+ */
+static int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct addi_private *devpriv = dev->private;
unsigned int ui_Configuration = 0;
int i_Temp; /* ,i_TimeUnit; */
+
/* if(i_Initialised==0) */
if (s_BoardInfos[dev->minor].i_Initialised == 0) {
@@ -2502,61 +2211,18 @@ int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev,
return insn->n;
}
-/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_InsnWriteReleaseAnalogInput |
- | (struct comedi_device *dev,struct comedi_subdevice *s, |
- | struct comedi_insn *insn,unsigned int *data) |
- +----------------------------------------------------------------------------+
- | Task : Resets the channels |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev : Driver handle |
- | struct comedi_subdevice *s : Subdevice Pointer |
- | struct comedi_insn *insn : Insn Structure Pointer |
- | unsigned int *data : Data Pointer
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
-
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
-
-int i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
i_APCI3200_Reset(dev);
return insn->n;
}
-/*
- +----------------------------------------------------------------------------+
- | Function name :int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev|
- | ,struct comedi_subdevice *s,struct comedi_cmd *cmd) |
- | |
- +----------------------------------------------------------------------------+
- | Task : Test validity for a command for cyclic anlog input |
- | acquisition |
- | |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev |
- | struct comedi_subdevice *s |
- | struct comedi_cmd *cmd |
- | |
- |
- | |
- | |
- | |
- +----------------------------------------------------------------------------+
- | Return Value :0 |
- | |
- +----------------------------------------------------------------------------+
-*/
-
-int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
+static int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
int err = 0;
@@ -2716,27 +2382,12 @@ int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
return 0;
}
-/*
- +----------------------------------------------------------------------------+
- | Function name :int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev,|
- | struct comedi_subdevice *s)|
- | |
- +----------------------------------------------------------------------------+
- | Task : Stop the acquisition |
- | |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev |
- | struct comedi_subdevice *s |
- | |
- +----------------------------------------------------------------------------+
- | Return Value :0 |
- | |
- +----------------------------------------------------------------------------+
-*/
-
-int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s)
+static int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ui_Configuration = 0;
+
/* i_InterruptFlag=0; */
/* i_Initialised=0; */
/* i_Count=0; */
@@ -2765,27 +2416,13 @@ int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_su
}
/*
- +----------------------------------------------------------------------------+
- | Function name : int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, |
- | struct comedi_subdevice *s) |
- | |
- +----------------------------------------------------------------------------+
- | Task : Does asynchronous acquisition |
- | Determines the mode 1 or 2. |
- | |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev |
- | struct comedi_subdevice *s |
- | |
- | |
- +----------------------------------------------------------------------------+
- | Return Value : |
- | |
- +----------------------------------------------------------------------------+
-*/
-
-int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s)
+ * Does asynchronous acquisition
+ * Determines the mode 1 or 2.
+ */
+static int i_APCI3200_CommandAnalogInput(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
+ struct addi_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
unsigned int ui_Configuration = 0;
/* INT i_CurrentSource = 0; */
@@ -2798,6 +2435,7 @@ int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde
unsigned int ui_DelayTime = 0;
unsigned int ui_DelayTimeBase = 0;
unsigned int ui_DelayMode = 0;
+
/* i_FirstChannel=cmd->chanlist[0]; */
/* i_LastChannel=cmd->chanlist[1]; */
s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
@@ -2956,80 +2594,155 @@ int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde
}
/*
- +----------------------------------------------------------------------------+
- | Function Name : int i_APCI3200_Reset(struct comedi_device *dev) |
- | |
- +----------------------------------------------------------------------------+
- | Task :Resets the registers of the card |
- +----------------------------------------------------------------------------+
- | Input Parameters : |
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- +----------------------------------------------------------------------------+
- | Return Value : |
- | |
- +----------------------------------------------------------------------------+
-*/
-
-int i_APCI3200_Reset(struct comedi_device *dev)
+ * This function copies the acquired data(from FIFO) to Comedi buffer.
+ */
+static int i_APCI3200_InterruptHandleEos(struct comedi_device *dev)
{
- int i_Temp;
- unsigned int dw_Dummy;
- /* i_InterruptFlag=0; */
- /* i_Initialised==0; */
- /* i_Count=0; */
- /* i_Sum=0; */
+ struct addi_private *devpriv = dev->private;
+ unsigned int ui_StatusRegister = 0;
+ struct comedi_subdevice *s = &dev->subdevices[0];
- s_BoardInfos[dev->minor].i_InterruptFlag = 0;
- s_BoardInfos[dev->minor].i_Initialised = 0;
- s_BoardInfos[dev->minor].i_Count = 0;
- s_BoardInfos[dev->minor].i_Sum = 0;
- s_BoardInfos[dev->minor].b_StructInitialized = 0;
+ /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+ /* comedi_async *async = s->async; */
+ /* UINT *data; */
+ /* data=async->data+async->buf_int_ptr;//new samples added from here onwards */
+ int n = 0, i = 0;
+ /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
- outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
+ /************************************/
+ /*Read the interrupt status register */
+ /************************************/
+ /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */
+ ui_StatusRegister =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 16);
- /* Enable the interrupt for the controller */
- dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
- outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
- outl(0, devpriv->i_IobaseAddon); /* Resets the output */
- /***************/
- /*Empty the buffer */
- /**************/
- for (i_Temp = 0; i_Temp <= 95; i_Temp++) {
- /* ui_InterruptChannelValue[i_Temp]=0; */
- s_BoardInfos[dev->minor].ui_InterruptChannelValue[i_Temp] = 0;
- } /* for(i_Temp=0;i_Temp<=95;i_Temp++) */
- /*****************************/
- /*Reset the START and IRQ bit */
- /*****************************/
- for (i_Temp = 0; i_Temp <= 192;) {
- while (((inl(devpriv->iobase + i_Temp + 12) >> 19) & 1) != 1) ;
- outl(0, devpriv->iobase + i_Temp + 8);
- i_Temp = i_Temp + 64;
- } /* for(i_Temp=0;i_Temp<=192;i_Temp+64) */
+ /*************************/
+ /*Test if interrupt occur */
+ /*************************/
+
+ if ((ui_StatusRegister & 0x2) == 0x2) {
+ /*************************/
+ /*Read the channel number */
+ /*************************/
+ /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */
+ /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+ /* This value is not used */
+ /* ui_ChannelNumber = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 24); */
+ s->async->events = 0;
+ /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+
+ /*************************************/
+ /*Read the digital Analog Input value */
+ /*************************************/
+
+ /* data[i_Count] = inl(devpriv->iobase+i_Offset + 28); */
+ /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+ /* data[s_BoardInfos [dev->minor].i_Count] = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 28); */
+ s_BoardInfos[dev->minor].ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+
+ /* if((i_Count == (i_LastChannel-i_FirstChannel+3))) */
+ if ((s_BoardInfos[dev->minor].i_Count ==
+ (s_BoardInfos[dev->minor].i_LastChannel -
+ s_BoardInfos[dev->minor].
+ i_FirstChannel + 3))) {
+
+ /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+ s_BoardInfos[dev->minor].i_Count++;
+
+ for (i = s_BoardInfos[dev->minor].i_FirstChannel;
+ i <= s_BoardInfos[dev->minor].i_LastChannel;
+ i++) {
+ i_APCI3200_GetChannelCalibrationValue(dev, i,
+ &s_BoardInfos[dev->minor].
+ ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count + ((i -
+ s_BoardInfos
+ [dev->minor].
+ i_FirstChannel)
+ * 3)],
+ &s_BoardInfos[dev->minor].
+ ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count + ((i -
+ s_BoardInfos
+ [dev->minor].
+ i_FirstChannel)
+ * 3) + 1],
+ &s_BoardInfos[dev->minor].
+ ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count + ((i -
+ s_BoardInfos
+ [dev->minor].
+ i_FirstChannel)
+ * 3) + 2]);
+ }
+
+ /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
+
+ /* i_Count=-1; */
+
+ s_BoardInfos[dev->minor].i_Count = -1;
+
+ /* async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */
+ /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+ /* async->buf_int_count+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */
+ /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+ /* async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */
+ /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+ /* async->buf_int_ptr+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */
+ /* comedi_eos(dev,s); */
+
+ /* Set the event type (Comedi Buffer End Of Scan) */
+ s->async->events |= COMEDI_CB_EOS;
+
+ /* Test if enougth memory is available and allocate it for 7 values */
+ /* n = comedi_buf_write_alloc(s->async, 7*sizeof(unsigned int)); */
+ n = comedi_buf_write_alloc(s->async,
+ (7 + 12) * sizeof(unsigned int));
+
+ /* If not enough memory available, event is set to Comedi Buffer Error */
+ if (n > ((7 + 12) * sizeof(unsigned int))) {
+ printk("\ncomedi_buf_write_alloc n = %i", n);
+ s->async->events |= COMEDI_CB_ERROR;
+ }
+ /* Write all 7 scan values in the comedi buffer */
+ comedi_buf_memcpy_to(s->async, 0,
+ (unsigned int *) s_BoardInfos[dev->minor].
+ ui_ScanValueArray, (7 + 12) * sizeof(unsigned int));
+
+ /* Update comedi buffer pinters indexes */
+ comedi_buf_write_free(s->async,
+ (7 + 12) * sizeof(unsigned int));
+
+ /* Send events */
+ comedi_event(dev, s);
+ /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+
+ /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+ /* */
+ /* if (s->async->buf_int_ptr>=s->async->data_len) // for buffer rool over */
+ /* { */
+ /* /* buffer rollover */ */
+ /* s->async->buf_int_ptr=0; */
+ /* comedi_eobuf(dev,s); */
+ /* } */
+ /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
+ }
+ /* i_Count++; */
+ s_BoardInfos[dev->minor].i_Count++;
+ }
+ /* i_InterruptFlag=0; */
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
return 0;
}
-/*
- +----------------------------------------------------------------------------+
- | Function Name : static void v_APCI3200_Interrupt |
- | (int irq , void *d) |
- +----------------------------------------------------------------------------+
- | Task : Interrupt processing Routine |
- +----------------------------------------------------------------------------+
- | Input Parameters : int irq : irq number |
- | void *d : void pointer |
- +----------------------------------------------------------------------------+
- | Output Parameters : -- |
- +----------------------------------------------------------------------------+
- | Return Value : TRUE : No error occur |
- | : FALSE : Error occur. Return the error |
- | |
- +----------------------------------------------------------------------------+
-*/
-void v_APCI3200_Interrupt(int irq, void *d)
+static void v_APCI3200_Interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct addi_private *devpriv = dev->private;
unsigned int ui_StatusRegister = 0;
unsigned int ui_ChannelNumber = 0;
int i_CalibrationFlag = 0;
@@ -3038,7 +2751,6 @@ void v_APCI3200_Interrupt(int irq, void *d)
unsigned int ui_DigitalTemperature = 0;
unsigned int ui_DigitalInput = 0;
int i_ConvertCJCCalibration;
-
/* BEGIN JK TEST */
int i_ReturnValue = 0;
/* END JK TEST */
@@ -3449,164 +3161,3 @@ void v_APCI3200_Interrupt(int irq, void *d)
} /* switch(i_ScanType) */
return;
}
-
-/*
- +----------------------------------------------------------------------------+
- | Function name :int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) |
- | |
- | |
- +----------------------------------------------------------------------------+
- | Task : . |
- | This function copies the acquired data(from FIFO) |
- | to Comedi buffer. |
- | |
- +----------------------------------------------------------------------------+
- | Input Parameters : struct comedi_device *dev |
- | |
- | |
- +----------------------------------------------------------------------------+
- | Return Value : 0 |
- | |
- +----------------------------------------------------------------------------+
-*/
-int i_APCI3200_InterruptHandleEos(struct comedi_device *dev)
-{
- unsigned int ui_StatusRegister = 0;
- struct comedi_subdevice *s = &dev->subdevices[0];
-
- /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
- /* comedi_async *async = s->async; */
- /* UINT *data; */
- /* data=async->data+async->buf_int_ptr;//new samples added from here onwards */
- int n = 0, i = 0;
- /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
-
- /************************************/
- /*Read the interrupt status register */
- /************************************/
- /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */
- ui_StatusRegister =
- inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 16);
-
- /*************************/
- /*Test if interrupt occur */
- /*************************/
-
- if ((ui_StatusRegister & 0x2) == 0x2) {
- /*************************/
- /*Read the channel number */
- /*************************/
- /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */
- /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
- /* This value is not used */
- /* ui_ChannelNumber = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 24); */
- s->async->events = 0;
- /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
-
- /*************************************/
- /*Read the digital Analog Input value */
- /*************************************/
-
- /* data[i_Count] = inl(devpriv->iobase+i_Offset + 28); */
- /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
- /* data[s_BoardInfos [dev->minor].i_Count] = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 28); */
- s_BoardInfos[dev->minor].ui_ScanValueArray[s_BoardInfos[dev->
- minor].i_Count] =
- inl(devpriv->iobase +
- s_BoardInfos[dev->minor].i_Offset + 28);
- /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
-
- /* if((i_Count == (i_LastChannel-i_FirstChannel+3))) */
- if ((s_BoardInfos[dev->minor].i_Count ==
- (s_BoardInfos[dev->minor].i_LastChannel -
- s_BoardInfos[dev->minor].
- i_FirstChannel + 3))) {
-
- /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
- s_BoardInfos[dev->minor].i_Count++;
-
- for (i = s_BoardInfos[dev->minor].i_FirstChannel;
- i <= s_BoardInfos[dev->minor].i_LastChannel;
- i++) {
- i_APCI3200_GetChannelCalibrationValue(dev, i,
- &s_BoardInfos[dev->minor].
- ui_ScanValueArray[s_BoardInfos[dev->
- minor].i_Count + ((i -
- s_BoardInfos
- [dev->minor].
- i_FirstChannel)
- * 3)],
- &s_BoardInfos[dev->minor].
- ui_ScanValueArray[s_BoardInfos[dev->
- minor].i_Count + ((i -
- s_BoardInfos
- [dev->minor].
- i_FirstChannel)
- * 3) + 1],
- &s_BoardInfos[dev->minor].
- ui_ScanValueArray[s_BoardInfos[dev->
- minor].i_Count + ((i -
- s_BoardInfos
- [dev->minor].
- i_FirstChannel)
- * 3) + 2]);
- }
-
- /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-
- /* i_Count=-1; */
-
- s_BoardInfos[dev->minor].i_Count = -1;
-
- /* async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */
- /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
- /* async->buf_int_count+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */
- /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
- /* async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */
- /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
- /* async->buf_int_ptr+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */
- /* comedi_eos(dev,s); */
-
- /* Set the event type (Comedi Buffer End Of Scan) */
- s->async->events |= COMEDI_CB_EOS;
-
- /* Test if enougth memory is available and allocate it for 7 values */
- /* n = comedi_buf_write_alloc(s->async, 7*sizeof(unsigned int)); */
- n = comedi_buf_write_alloc(s->async,
- (7 + 12) * sizeof(unsigned int));
-
- /* If not enough memory available, event is set to Comedi Buffer Error */
- if (n > ((7 + 12) * sizeof(unsigned int))) {
- printk("\ncomedi_buf_write_alloc n = %i", n);
- s->async->events |= COMEDI_CB_ERROR;
- }
- /* Write all 7 scan values in the comedi buffer */
- comedi_buf_memcpy_to(s->async, 0,
- (unsigned int *) s_BoardInfos[dev->minor].
- ui_ScanValueArray, (7 + 12) * sizeof(unsigned int));
-
- /* Update comedi buffer pinters indexes */
- comedi_buf_write_free(s->async,
- (7 + 12) * sizeof(unsigned int));
-
- /* Send events */
- comedi_event(dev, s);
- /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
-
- /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
- /* */
- /* if (s->async->buf_int_ptr>=s->async->data_len) // for buffer rool over */
- /* { */
- /* /* buffer rollover */ */
- /* s->async->buf_int_ptr=0; */
- /* comedi_eobuf(dev,s); */
- /* } */
- /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
- }
- /* i_Count++; */
- s_BoardInfos[dev->minor].i_Count++;
- }
- /* i_InterruptFlag=0; */
- s_BoardInfos[dev->minor].i_InterruptFlag = 0;
- return 0;
-}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h
deleted file mode 100644
index 812a9c46e11..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-/* Card Specific information */
-#define APCI3200_BOARD_VENDOR_ID 0x15B8
-/* #define APCI3200_ADDRESS_RANGE 264 */
-
-int MODULE_NO;
-struct {
- int i_Gain;
- int i_Polarity;
- int i_OffsetRange;
- int i_Coupling;
- int i_SingleDiff;
- int i_AutoCalibration;
- unsigned int ui_ReloadValue;
- unsigned int ui_TimeUnitReloadVal;
- int i_Interrupt;
- int i_ModuleSelection;
-} Config_Parameters_Module1, Config_Parameters_Module2,
- Config_Parameters_Module3, Config_Parameters_Module4;
-
-/* ANALOG INPUT RANGE */
-static const struct comedi_lrange range_apci3200_ai = { 8, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2),
- UNI_RANGE(1)
- }
-};
-
-static const struct comedi_lrange range_apci3300_ai = { 4, {
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2),
- UNI_RANGE(1)
- }
-};
-
-/* Analog Input related Defines */
-#define APCI3200_AI_OFFSET_GAIN 0
-#define APCI3200_AI_SC_TEST 4
-#define APCI3200_AI_IRQ 8
-#define APCI3200_AI_AUTOCAL 12
-#define APCI3200_RELOAD_CONV_TIME_VAL 32
-#define APCI3200_CONV_TIME_TIME_BASE 36
-#define APCI3200_RELOAD_DELAY_TIME_VAL 40
-#define APCI3200_DELAY_TIME_TIME_BASE 44
-#define APCI3200_AI_MODULE1 0
-#define APCI3200_AI_MODULE2 64
-#define APCI3200_AI_MODULE3 128
-#define APCI3200_AI_MODULE4 192
-#define TRUE 1
-#define FALSE 0
-#define APCI3200_AI_EOSIRQ 16
-#define APCI3200_AI_EOS 20
-#define APCI3200_AI_CHAN_ID 24
-#define APCI3200_AI_CHAN_VAL 28
-#define ANALOG_INPUT 0
-#define TEMPERATURE 1
-#define RESISTANCE 2
-
-#define ENABLE_EXT_TRIG 1
-#define ENABLE_EXT_GATE 2
-#define ENABLE_EXT_TRIG_GATE 3
-
-#define APCI3200_MAXVOLT 2.5
-#define ADDIDATA_GREATER_THAN_TEST 0
-#define ADDIDATA_LESS_THAN_TEST 1
-
-#define ADDIDATA_UNIPOLAR 1
-#define ADDIDATA_BIPOLAR 2
-
-/* BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-#define MAX_MODULE 4
-/* END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-
-struct str_ADDIDATA_RTDStruct {
- unsigned int ul_NumberOfValue;
- unsigned int *pul_ResistanceValue;
- unsigned int *pul_TemperatureValue;
-};
-
-/* BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-struct str_Module {
-
- /* Begin JK 05/08/2003 change for Linux */
- unsigned long ul_CurrentSourceCJC;
- unsigned long ul_CurrentSource[5];
- /* End JK 05/08/2003 change for Linux */
-
- /* Begin CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1 */
- unsigned long ul_GainFactor[8]; /* Gain Factor */
- unsigned int w_GainValue[10];
- /* End CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1 */
-};
-
-/* END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-
-/* BEGIN JK 06.07.04: Management of sevrals boards */
-struct str_BoardInfos {
-
- int i_CJCAvailable;
- int i_CJCPolarity;
- int i_CJCGain;
- int i_InterruptFlag;
- int i_ADDIDATAPolarity;
- int i_ADDIDATAGain;
- int i_AutoCalibration;
- int i_ADDIDATAConversionTime;
- int i_ADDIDATAConversionTimeUnit;
- int i_ADDIDATAType;
- int i_ChannelNo;
- int i_ChannelCount;
- int i_ScanType;
- int i_FirstChannel;
- int i_LastChannel;
- int i_Sum;
- int i_Offset;
- unsigned int ui_Channel_num;
- int i_Count;
- int i_Initialised;
- /* UINT ui_InterruptChannelValue[96]; //Buffer */
- unsigned int ui_InterruptChannelValue[144]; /* Buffer */
- unsigned char b_StructInitialized;
- /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
- unsigned int ui_ScanValueArray[7 + 12]; /* 7 is the maximal number of channels */
- /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
-
- /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
- int i_ConnectionType;
- int i_NbrOfModule;
- struct str_Module s_Module[MAX_MODULE];
- /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-};
-
-/* END JK 06.07.04: Management of sevrals boards */
-
-/* Hardware Layer functions for Apci3200 */
-
-/* AI */
-
-int i_APCI3200_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI3200_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
-int i_APCI3200_InterruptHandleEos(struct comedi_device *dev);
-int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_cmd *cmd);
-int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s);
-int i_APCI3200_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-/* Interrupt */
-void v_APCI3200_Interrupt(int irq, void *d);
-int i_APCI3200_InterruptHandleEos(struct comedi_device *dev);
-/* Reset functions */
-int i_APCI3200_Reset(struct comedi_device *dev);
-
-int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data);
-int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data);
-int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, unsigned int *data);
-int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, unsigned int *data);
-int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data);
-int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
index acaceb01629..7a18ce704ba 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
@@ -46,229 +46,75 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+----------+-----------+------------------------------------------------+
*/
-/*
-+----------------------------------------------------------------------------+
-| Included files |
-+----------------------------------------------------------------------------+
-*/
-#include "hwdrv_apci3501.h"
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI3501_ReadDigitalInput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Read value of the selected channel or port |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int ui_NoOfChannels : No Of Channels To read |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
+/* Card Specific information */
+#define APCI3501_ADDRESS_RANGE 255
+
+#define APCI3501_DIGITAL_IP 0x50
+#define APCI3501_DIGITAL_OP 0x40
+#define APCI3501_ANALOG_OUTPUT 0x00
+
+/* Analog Output related Defines */
+#define APCI3501_AO_VOLT_MODE 0
+#define APCI3501_AO_PROG 4
+#define APCI3501_AO_TRIG_SCS 8
+#define UNIPOLAR 0
+#define BIPOLAR 1
+#define MODE0 0
+#define MODE1 1
+
+/* Watchdog Related Defines */
+
+#define APCI3501_WATCHDOG 0x20
+#define APCI3501_TCW_SYNC_ENABLEDISABLE 0
+#define APCI3501_TCW_RELOAD_VALUE 4
+#define APCI3501_TCW_TIMEBASE 8
+#define APCI3501_TCW_PROG 12
+#define APCI3501_TCW_TRIG_STATUS 16
+#define APCI3501_TCW_IRQ 20
+#define APCI3501_TCW_WARN_TIMEVAL 24
+#define APCI3501_TCW_WARN_TIMEBASE 28
+#define ADDIDATA_TIMER 0
+#define ADDIDATA_WATCHDOG 2
+
+/* ANALOG OUTPUT RANGE */
+static struct comedi_lrange range_apci3501_ao = {
+ 2, {
+ BIP_RANGE(10),
+ UNI_RANGE(10)
+ }
+};
-int i_APCI3501_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int apci3501_di_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned int ui_Temp;
- unsigned int ui_NoOfChannel;
- ui_NoOfChannel = CR_CHAN(insn->chanspec);
- ui_Temp = data[0];
- *data = inl(devpriv->iobase + APCI3501_DIGITAL_IP);
- if (ui_Temp == 0) {
- *data = (*data >> ui_NoOfChannel) & 0x1;
- } /* if (ui_Temp==0) */
- else {
- if (ui_Temp == 1) {
-
- *data = *data & 0x3;
- } /* if (ui_Temp==1) */
- else {
- printk("\nSpecified channel not supported \n");
- } /* elseif (ui_Temp==1) */
- } /* elseif (ui_Temp==0) */
- return insn->n;
-}
+ struct addi_private *devpriv = dev->private;
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI3501_ConfigDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Configures The Digital Output Subdevice. |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int *data : Data Pointer contains |
-| configuration parameters as below |
-| |
-| data[1] : 1 Enable VCC Interrupt |
-| 0 Disable VCC Interrupt |
-| data[2] : 1 Enable CC Interrupt |
-| 0 Disable CC Interrupt |
-| |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
+ data[1] = inl(devpriv->iobase + APCI3501_DIGITAL_IP) & 0x3;
- if ((data[0] != 0) && (data[0] != 1)) {
- comedi_error(dev,
- "Not a valid Data !!! ,Data should be 1 or 0\n");
- return -EINVAL;
- } /* if ( (data[0]!=0) && (data[0]!=1) ) */
- if (data[0]) {
- devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
- } /* if (data[0]) */
- else {
- devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
- } /* else if (data[0]) */
return insn->n;
}
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI3501_WriteDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : writes To the digital Output Subdevice |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| struct comedi_subdevice *s : Subdevice Pointer |
-| struct comedi_insn *insn : Insn Structure Pointer |
-| unsigned int *data : Data Pointer contains |
-| configuration parameters as below |
-| |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int apci3501_do_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned int ui_Temp, ui_Temp1;
- unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
- if (devpriv->b_OutputMemoryStatus) {
- ui_Temp = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
- } /* if(devpriv->b_OutputMemoryStatus ) */
- else {
- ui_Temp = 0;
- } /* if(devpriv->b_OutputMemoryStatus ) */
- if (data[3] == 0) {
- if (data[1] == 0) {
- data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
- outl(data[0], devpriv->iobase + APCI3501_DIGITAL_OP);
- } /* if(data[1]==0) */
- else {
- if (data[1] == 1) {
- data[0] = (data[0] << (2 * data[2])) | ui_Temp;
- outl(data[0],
- devpriv->iobase + APCI3501_DIGITAL_OP);
- } /* if(data[1]==1) */
- else {
- printk("\nSpecified channel not supported\n");
- } /* else if(data[1]==1) */
- } /* elseif(data[1]==0) */
- } /* if(data[3]==0) */
- else {
- if (data[3] == 1) {
- if (data[1] == 0) {
- data[0] = ~data[0] & 0x1;
- ui_Temp1 = 1;
- ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- (data[0] << ui_NoOfChannel) ^
- 0xffffffff;
- data[0] = data[0] & ui_Temp;
- outl(data[0],
- devpriv->iobase + APCI3501_DIGITAL_OP);
- } /* if(data[1]==0) */
- else {
- if (data[1] == 1) {
- data[0] = ~data[0] & 0x3;
- ui_Temp1 = 3;
- ui_Temp1 = ui_Temp1 << 2 * data[2];
- ui_Temp = ui_Temp | ui_Temp1;
- data[0] =
- ((data[0] << (2 *
- data[2])) ^
- 0xffffffff) & ui_Temp;
- outl(data[0],
- devpriv->iobase +
- APCI3501_DIGITAL_OP);
- } /* if(data[1]==1) */
- else {
- printk("\nSpecified channel not supported\n");
- } /* else if(data[1]==1) */
- } /* elseif(data[1]==0) */
- } /* if(data[3]==1); */
- else {
- printk("\nSpecified functionality does not exist\n");
- return -EINVAL;
- } /* if else data[3]==1) */
- } /* if else data[3]==0) */
- return insn->n;
-}
+ struct addi_private *devpriv = dev->private;
+ unsigned int mask = data[0];
+ unsigned int bits = data[1];
+
+ s->state = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
+ if (mask) {
+ s->state &= ~mask;
+ s->state |= (bits & mask);
+
+ outl(s->state, devpriv->iobase + APCI3501_DIGITAL_OP);
+ }
+
+ data[1] = s->state;
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_APCI3501_ReadDigitalOutput |
-| (struct comedi_device *dev,struct comedi_subdevice *s, |
-| struct comedi_insn *insn,unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Read value of the selected channel or port |
-+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev : Driver handle |
-| unsigned int ui_NoOfChannels : No Of Channels To read |
-| unsigned int *data : Data Pointer to read status |
-+----------------------------------------------------------------------------+
-| Output Parameters : -- |
-+----------------------------------------------------------------------------+
-| Return Value : TRUE : No error occur |
-| : FALSE : Error occur. Return the error |
-| |
-+----------------------------------------------------------------------------+
-*/
-int i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int ui_Temp;
- unsigned int ui_NoOfChannel;
-
- ui_NoOfChannel = CR_CHAN(insn->chanspec);
- ui_Temp = data[0];
- *data = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
- if (ui_Temp == 0) {
- *data = (*data >> ui_NoOfChannel) & 0x1;
- } /* if (ui_Temp==0) */
- else {
- if (ui_Temp == 1) {
- *data = *data & 0x3;
-
- } /* if (ui_Temp==1) */
- else {
- printk("\nSpecified channel not supported \n");
- } /* else if (ui_Temp==1) */
- } /* else if (ui_Temp==0) */
return insn->n;
}
@@ -298,9 +144,13 @@ int i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev
| |
+----------------------------------------------------------------------------+
*/
-int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
+
outl(data[0],
devpriv->iobase + APCI3501_ANALOG_OUTPUT +
APCI3501_AO_VOLT_MODE);
@@ -336,9 +186,12 @@ int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subde
| |
+----------------------------------------------------------------------------+
*/
-int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ul_Command1 = 0, ul_Channel_no, ul_Polarity, ul_DAC_Ready = 0;
ul_Channel_no = CR_CHAN(insn->chanspec);
@@ -410,10 +263,14 @@ int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdev
| |
+----------------------------------------------------------------------------+
*/
-int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ul_Command1 = 0;
+
devpriv->tsk_Current = current;
if (data[0] == ADDIDATA_WATCHDOG) {
@@ -511,11 +368,15 @@ int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev,
+----------------------------------------------------------------------------+
*/
-int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned int ul_Command1 = 0;
int i_Temp;
+
if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
if (data[1] == 1) {
@@ -613,9 +474,12 @@ int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
+----------------------------------------------------------------------------+
*/
-int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+static int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
data[0] =
@@ -654,10 +518,12 @@ int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev,
+----------------------------------------------------------------------------+
*/
-int i_APCI3501_Reset(struct comedi_device *dev)
+static int i_APCI3501_Reset(struct comedi_device *dev)
{
+ struct addi_private *devpriv = dev->private;
int i_Count = 0, i_temp = 0;
unsigned int ul_Command1 = 0, ul_Polarity, ul_DAC_Ready = 0;
+
outl(0x0, devpriv->iobase + APCI3501_DIGITAL_OP);
outl(1, devpriv->iobase + APCI3501_ANALOG_OUTPUT +
APCI3501_AO_VOLT_MODE);
@@ -705,12 +571,14 @@ int i_APCI3501_Reset(struct comedi_device *dev)
| |
+----------------------------------------------------------------------------+
*/
-void v_APCI3501_Interrupt(int irq, void *d)
+static void v_APCI3501_Interrupt(int irq, void *d)
{
int i_temp;
struct comedi_device *dev = d;
+ struct addi_private *devpriv = dev->private;
unsigned int ui_Timer_AOWatchdog;
unsigned long ul_Command1;
+
/* Disable Interrupt */
ul_Command1 =
inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h
deleted file mode 100644
index 63df635a7b6..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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.
- */
-
-/* Card Specific information */
-#define APCI3501_BOARD_VENDOR_ID 0x15B8
-#define APCI3501_ADDRESS_RANGE 255
-
-#define APCI3501_DIGITAL_IP 0x50
-#define APCI3501_DIGITAL_OP 0x40
-#define APCI3501_ANALOG_OUTPUT 0x00
-
-/* Analog Output related Defines */
-#define APCI3501_AO_VOLT_MODE 0
-#define APCI3501_AO_PROG 4
-#define APCI3501_AO_TRIG_SCS 8
-#define UNIPOLAR 0
-#define BIPOLAR 1
-#define MODE0 0
-#define MODE1 1
-/* ANALOG OUTPUT RANGE */
-static struct comedi_lrange range_apci3501_ao = { 2, {
- BIP_RANGE(10),
- UNI_RANGE(10)
- }
-};
-
-/* Watchdog Related Defines */
-
-#define APCI3501_WATCHDOG 0x20
-#define APCI3501_TCW_SYNC_ENABLEDISABLE 0
-#define APCI3501_TCW_RELOAD_VALUE 4
-#define APCI3501_TCW_TIMEBASE 8
-#define APCI3501_TCW_PROG 12
-#define APCI3501_TCW_TRIG_STATUS 16
-#define APCI3501_TCW_IRQ 20
-#define APCI3501_TCW_WARN_TIMEVAL 24
-#define APCI3501_TCW_WARN_TIMEBASE 28
-#define ADDIDATA_TIMER 0
-#define ADDIDATA_WATCHDOG 2
-
-/* Hardware Layer functions for Apci3501 */
-
-/* AO */
-int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/*
-* DI for di read INT i_APCI3501_ReadDigitalInput(struct
-* comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn
-* *insn,unsigned int *data);
-*/
-
-int i_APCI3501_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* DO */
-int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* TIMER
- * timer value is passed as u seconds
- */
-
-int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-/* Interrupt */
-void v_APCI3501_Interrupt(int irq, void *d);
-
-/* Reset functions */
-int i_APCI3501_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
index fff99df51e9..a45a2a26e0d 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
@@ -44,7 +44,35 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+----------+-----------+------------------------------------------------+
*/
-#include "hwdrv_apci3xxx.h"
+#ifndef COMEDI_SUBD_TTLIO
+#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
+#endif
+
+#define APCI3XXX_SINGLE 0
+#define APCI3XXX_DIFF 1
+#define APCI3XXX_CONFIGURATION 0
+
+#define APCI3XXX_TTL_INIT_DIRECTION_PORT2 0
+
+static const struct comedi_lrange range_apci3XXX_ai = {
+ 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+static const struct comedi_lrange range_apci3XXX_ao = {
+ 2, {
+ BIP_RANGE(10),
+ UNI_RANGE(10)
+ }
+};
/*
+----------------------------------------------------------------------------+
@@ -69,6 +97,8 @@ You should also find the complete GPL in the COPYING file accompanying this sour
*/
static int i_APCI3XXX_TestConversionStarted(struct comedi_device *dev)
{
+ struct addi_private *devpriv = dev->private;
+
if ((readl(devpriv->dw_AiBase + 8) & 0x80000UL) == 0x80000UL)
return 1;
else
@@ -108,6 +138,8 @@ static int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = insn->n;
unsigned char b_TimeBase = 0;
unsigned char b_SingleDiff = 0;
@@ -358,6 +390,8 @@ static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = insn->n;
unsigned char b_Configuration = (unsigned char) CR_RANGE(insn->chanspec);
unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
@@ -571,6 +605,7 @@ static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev,
static void v_APCI3XXX_Interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct addi_private *devpriv = dev->private;
unsigned char b_CopyCpt = 0;
unsigned int dw_Status = 0;
@@ -651,6 +686,7 @@ static int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned char b_Range = (unsigned char) CR_RANGE(insn->chanspec);
unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
unsigned int dw_Status = 0;
@@ -755,6 +791,7 @@ static int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = insn->n;
unsigned char b_Command = 0;
@@ -884,6 +921,7 @@ static int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = insn->n;
unsigned char b_ChannelCpt = 0;
unsigned int dw_ChannelMask = 0;
@@ -1040,6 +1078,7 @@ static int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
int i_ReturnValue = insn->n;
unsigned int *pls_ReadData = data;
@@ -1154,6 +1193,7 @@ static int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct addi_private *devpriv = dev->private;
int i_ReturnValue = insn->n;
unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
unsigned char b_State = 0;
@@ -1236,367 +1276,38 @@ static int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
return i_ReturnValue;
}
-/*
-+----------------------------------------------------------------------------+
-| DIGITAL INPUT SUBDEVICE |
-+----------------------------------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3XXX_InsnReadDigitalInput |
-| (struct comedi_device *dev, |
-| struct comedi_subdevice *s, |
-| struct comedi_insn *insn, |
-| unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Reads the value of the specified Digital input channel |
-+----------------------------------------------------------------------------+
-| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) (0 to 3) |
-+----------------------------------------------------------------------------+
-| Output Parameters : data[0] : Channel value |
-+----------------------------------------------------------------------------+
-| Return Value : 0 : No error |
-| -3 : Channel selection error |
-| -101 : Data size error |
-+----------------------------------------------------------------------------+
-*/
-
-static int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int i_ReturnValue = insn->n;
- unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
- unsigned int dw_Temp = 0;
-
- /***************************/
- /* Test the channel number */
- /***************************/
-
- if (b_Channel <= devpriv->s_EeParameters.i_NbrDiChannel) {
- /************************/
- /* Test the buffer size */
- /************************/
-
- if (insn->n >= 1) {
- dw_Temp = inl(devpriv->iobase + 32);
- *data = (dw_Temp >> b_Channel) & 1;
- } else {
- /*******************/
- /* Data size error */
- /*******************/
-
- printk("Buffer size error\n");
- i_ReturnValue = -101;
- }
- } else {
- /***************************/
- /* Channel selection error */
- /***************************/
-
- printk("Channel selection error\n");
- i_ReturnValue = -3;
- }
-
- return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3XXX_InsnBitsDigitalInput |
-| (struct comedi_device *dev, |
-| struct comedi_subdevice *s, |
-| struct comedi_insn *insn, |
-| unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Reads the value of the Digital input Port i.e.4channels|
-+----------------------------------------------------------------------------+
-| Input Parameters : - |
-+----------------------------------------------------------------------------+
-| Output Parameters : data[0] : Port value |
-+----------------------------------------------------------------------------+
-| Return Value :>0: No error |
-| .... |
-| -101 : Data size error |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int i_ReturnValue = insn->n;
- unsigned int dw_Temp = 0;
-
- /************************/
- /* Test the buffer size */
- /************************/
-
- if (insn->n >= 1) {
- dw_Temp = inl(devpriv->iobase + 32);
- *data = dw_Temp & 0xf;
- } else {
- /*******************/
- /* Data size error */
- /*******************/
-
- printk("Buffer size error\n");
- i_ReturnValue = -101;
- }
-
- return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| DIGITAL OUTPUT SUBDEVICE |
-+----------------------------------------------------------------------------+
-
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3XXX_InsnBitsDigitalOutput |
-| (struct comedi_device *dev, |
-| struct comedi_subdevice *s, |
-| struct comedi_insn *insn, |
-| unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Write the selected output mask and read the status from|
-| all digital output channles |
-+----------------------------------------------------------------------------+
-| Input Parameters : dw_ChannelMask = data [0]; |
-| dw_BitMask = data [1]; |
-+----------------------------------------------------------------------------+
-| Output Parameters : data[1] : All digital output channles states |
-+----------------------------------------------------------------------------+
-| Return Value : >0 : No error |
-| -4 : Channel mask error |
-| -101 : Data size error |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
+static int apci3xxx_di_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- int i_ReturnValue = insn->n;
- unsigned char b_ChannelCpt = 0;
- unsigned int dw_ChannelMask = 0;
- unsigned int dw_BitMask = 0;
- unsigned int dw_Status = 0;
-
- /************************/
- /* Test the buffer size */
- /************************/
-
- if (insn->n >= 2) {
- /*******************************/
- /* Get the channe and bit mask */
- /*******************************/
-
- dw_ChannelMask = data[0];
- dw_BitMask = data[1];
-
- /*************************/
- /* Test the channel mask */
- /*************************/
-
- if ((dw_ChannelMask & 0XFFFFFFF0) == 0) {
- /*********************************/
- /* Test if set/reset any channel */
- /*********************************/
-
- if (dw_ChannelMask & 0xF) {
- /********************************/
- /* Read the digital output port */
- /********************************/
-
- dw_Status = inl(devpriv->iobase + 48);
+ struct addi_private *devpriv = dev->private;
- for (b_ChannelCpt = 0; b_ChannelCpt < 4;
- b_ChannelCpt++) {
- if ((dw_ChannelMask >> b_ChannelCpt) &
- 1) {
- dw_Status =
- (dw_Status & (0xF -
- (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
- }
- }
-
- outl(dw_Status, devpriv->iobase + 48);
- }
-
- /********************************/
- /* Read the digital output port */
- /********************************/
-
- data[1] = inl(devpriv->iobase + 48);
- } else {
- /************************/
- /* Config command error */
- /************************/
-
- printk("Channel mask error\n");
- i_ReturnValue = -4;
- }
- } else {
- /*******************/
- /* Data size error */
- /*******************/
-
- printk("Buffer size error\n");
- i_ReturnValue = -101;
- }
+ data[1] = inl(devpriv->iobase + 32) & 0xf;
- return i_ReturnValue;
+ return insn->n;
}
-/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3XXX_InsnWriteDigitalOutput |
-| (struct comedi_device *dev, |
-| struct comedi_subdevice *s, |
-| struct comedi_insn *insn, |
-| unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Set the state from digital output channel |
-+----------------------------------------------------------------------------+
-| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
-| b_State = data [0] |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : >0 : No error |
-| -3 : Channel selection error |
-| -101 : Data size error |
-+----------------------------------------------------------------------------+
-*/
-
-static int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
+static int apci3xxx_do_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- int i_ReturnValue = insn->n;
- unsigned char b_Channel = CR_CHAN(insn->chanspec);
- unsigned char b_State = 0;
- unsigned int dw_Status = 0;
-
- /************************/
- /* Test the buffer size */
- /************************/
-
- if (insn->n >= 1) {
- /***************************/
- /* Test the channel number */
- /***************************/
-
- if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) {
- /*******************/
- /* Get the command */
- /*******************/
-
- b_State = (unsigned char) data[0];
-
- /********************************/
- /* Read the digital output port */
- /********************************/
-
- dw_Status = inl(devpriv->iobase + 48);
-
- dw_Status =
- (dw_Status & (0xF -
- (1 << b_Channel))) | ((b_State & 1) <<
- b_Channel);
- outl(dw_Status, devpriv->iobase + 48);
- } else {
- /***************************/
- /* Channel selection error */
- /***************************/
+ struct addi_private *devpriv = dev->private;
+ unsigned int mask = data[0];
+ unsigned int bits = data[1];
- printk("Channel selection error\n");
- i_ReturnValue = -3;
- }
- } else {
- /*******************/
- /* Data size error */
- /*******************/
+ s->state = inl(devpriv->iobase + 48) & 0xf;
+ if (mask) {
+ s->state &= ~mask;
+ s->state |= (bits & mask);
- printk("Buffer size error\n");
- i_ReturnValue = -101;
+ outl(s->state, devpriv->iobase + 48);
}
- return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function name :int i_APCI3XXX_InsnReadDigitalOutput |
-| (struct comedi_device *dev, |
-| struct comedi_subdevice *s, |
-| struct comedi_insn *insn, |
-| unsigned int *data) |
-+----------------------------------------------------------------------------+
-| Task : Read the state from digital output channel |
-+----------------------------------------------------------------------------+
-| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
-+----------------------------------------------------------------------------+
-| Output Parameters : b_State = data [0] |
-+----------------------------------------------------------------------------+
-| Return Value : >0 : No error |
-| -3 : Channel selection error |
-| -101 : Data size error |
-+----------------------------------------------------------------------------+
-*/
+ data[1] = s->state;
-static int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int i_ReturnValue = insn->n;
- unsigned char b_Channel = CR_CHAN(insn->chanspec);
- unsigned int dw_Status = 0;
-
- /************************/
- /* Test the buffer size */
- /************************/
-
- if (insn->n >= 1) {
- /***************************/
- /* Test the channel number */
- /***************************/
-
- if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) {
- /********************************/
- /* Read the digital output port */
- /********************************/
-
- dw_Status = inl(devpriv->iobase + 48);
-
- dw_Status = (dw_Status >> b_Channel) & 1;
- *data = dw_Status;
- } else {
- /***************************/
- /* Channel selection error */
- /***************************/
-
- printk("Channel selection error\n");
- i_ReturnValue = -3;
- }
- } else {
- /*******************/
- /* Data size error */
- /*******************/
-
- printk("Buffer size error\n");
- i_ReturnValue = -101;
- }
-
- return i_ReturnValue;
+ return insn->n;
}
/*
@@ -1614,6 +1325,7 @@ static int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev,
static int i_APCI3XXX_Reset(struct comedi_device *dev)
{
+ struct addi_private *devpriv = dev->private;
unsigned char b_Cpt = 0;
/*************************/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h
deleted file mode 100644
index e10b7e51033..00000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.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 COMEDI_SUBD_TTLIO
-#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
-#endif
-
-#ifndef ADDIDATA_ENABLE
-#define ADDIDATA_ENABLE 1
-#define ADDIDATA_DISABLE 0
-#endif
-
-#define APCI3XXX_SINGLE 0
-#define APCI3XXX_DIFF 1
-#define APCI3XXX_CONFIGURATION 0
-
-#define APCI3XXX_TTL_INIT_DIRECTION_PORT2 0
-
-#ifdef __KERNEL__
-
-static const struct comedi_lrange range_apci3XXX_ai = { 8, {BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2),
- UNI_RANGE(1)}
-};
-
-static const struct comedi_lrange range_apci3XXX_ao = { 2, {BIP_RANGE(10),
- UNI_RANGE(10)}
-};
-#endif
diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c
index 4c00df4bc15..c981d4b1cc7 100644
--- a/drivers/staging/comedi/drivers/addi_apci_035.c
+++ b/drivers/staging/comedi/drivers/addi_apci_035.c
@@ -1,11 +1,77 @@
-#define CONFIG_APCI_035 1
+#include "../comedidev.h"
+#include "comedi_fc.h"
+#include "amcc_s5933.h"
-#define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */
+#include "addi-data/addi_common.h"
-#define ADDIDATA_DRIVER_NAME "addi_apci_035"
+#define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */
+#include "addi-data/addi_eeprom.c"
+#include "addi-data/hwdrv_apci035.c"
#include "addi-data/addi_common.c"
+static const struct addi_board apci035_boardtypes[] = {
+ {
+ .pc_DriverName = "apci035",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x0300,
+ .i_IorangeBase0 = 127,
+ .i_IorangeBase1 = APCI035_ADDRESS_RANGE,
+ .i_PCIEeprom = 1,
+ .pc_EepromChip = ADDIDATA_S5920,
+ .i_NbrAiChannel = 16,
+ .i_NbrAiChannelDiff = 8,
+ .i_AiChannelList = 16,
+ .i_AiMaxdata = 0xff,
+ .pr_AiRangelist = &range_apci035_ai,
+ .i_Timer = 1,
+ .ui_MinAcquisitiontimeNs = 10000,
+ .ui_MinDelaytimeNs = 100000,
+ .interrupt = v_APCI035_Interrupt,
+ .reset = i_APCI035_Reset,
+ .ai_config = i_APCI035_ConfigAnalogInput,
+ .ai_read = i_APCI035_ReadAnalogInput,
+ .timer_config = i_APCI035_ConfigTimerWatchdog,
+ .timer_write = i_APCI035_StartStopWriteTimerWatchdog,
+ .timer_read = i_APCI035_ReadTimerWatchdog,
+ },
+};
+
+static struct comedi_driver apci035_driver = {
+ .driver_name = "addi_apci_035",
+ .module = THIS_MODULE,
+ .auto_attach = addi_auto_attach,
+ .detach = i_ADDI_Detach,
+ .num_names = ARRAY_SIZE(apci035_boardtypes),
+ .board_name = &apci035_boardtypes[0].pc_DriverName,
+ .offset = sizeof(struct addi_board),
+};
+
+static int apci035_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ return comedi_pci_auto_config(dev, &apci035_driver);
+}
+
+static void apci035_pci_remove(struct pci_dev *dev)
+{
+ comedi_pci_auto_unconfig(dev);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(apci035_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x0300) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, apci035_pci_table);
+
+static struct pci_driver apci035_pci_driver = {
+ .name = "addi_apci_035",
+ .id_table = apci035_pci_table,
+ .probe = apci035_pci_probe,
+ .remove = apci035_pci_remove,
+};
+module_comedi_pci_driver(apci035_driver, apci035_pci_driver);
+
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c
index 7831ce33b02..7f9424205a6 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1032.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1032.c
@@ -1,8 +1,398 @@
-#define CONFIG_APCI_1032 1
+/*
+ * addi_apci_1032.c
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ * Project manager: Eric Stolz
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data.com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * You should also find the complete GPL in the COPYING file accompanying this
+ * source code.
+ */
-#define ADDIDATA_DRIVER_NAME "addi_apci_1032"
+#include "../comedidev.h"
+#include "comedi_fc.h"
+#include "amcc_s5933.h"
-#include "addi-data/addi_common.c"
+/*
+ * I/O Register Map
+ */
+#define APCI1032_DI_REG 0x00
+#define APCI1032_MODE1_REG 0x04
+#define APCI1032_MODE2_REG 0x08
+#define APCI1032_STATUS_REG 0x0c
+#define APCI1032_CTRL_REG 0x10
+#define APCI1032_CTRL_INT_OR (0 << 1)
+#define APCI1032_CTRL_INT_AND (1 << 1)
+#define APCI1032_CTRL_INT_ENA (1 << 2)
+
+struct apci1032_private {
+ unsigned long amcc_iobase; /* base of AMCC I/O registers */
+ unsigned int mode1; /* rising-edge/high level channels */
+ unsigned int mode2; /* falling-edge/low level channels */
+ unsigned int ctrl; /* interrupt mode OR (edge) . AND (level) */
+};
+
+static int apci1032_reset(struct comedi_device *dev)
+{
+ /* disable the interrupts */
+ outl(0x0, dev->iobase + APCI1032_CTRL_REG);
+ /* Reset the interrupt status register */
+ inl(dev->iobase + APCI1032_STATUS_REG);
+ /* Disable the and/or interrupt */
+ outl(0x0, dev->iobase + APCI1032_MODE1_REG);
+ outl(0x0, dev->iobase + APCI1032_MODE2_REG);
+
+ return 0;
+}
+
+/*
+ * Change-Of-State (COS) interrupt configuration
+ *
+ * Channels 0 to 15 are interruptible. These channels can be configured
+ * to generate interrupts based on AND/OR logic for the desired channels.
+ *
+ * OR logic
+ * - reacts to rising or falling edges
+ * - interrupt is generated when any enabled channel
+ * meet the desired interrupt condition
+ *
+ * AND logic
+ * - reacts to changes in level of the selected inputs
+ * - interrupt is generated when all enabled channels
+ * meet the desired interrupt condition
+ * - after an interrupt, a change in level must occur on
+ * the selected inputs to release the IRQ logic
+ *
+ * The COS interrupt must be configured before it can be enabled.
+ *
+ * data[0] : INSN_CONFIG_DIGITAL_TRIG
+ * data[1] : trigger number (= 0)
+ * data[2] : configuration operation:
+ * COMEDI_DIGITAL_TRIG_DISABLE = no interrupts
+ * COMEDI_DIGITAL_TRIG_ENABLE_EDGES = OR (edge) interrupts
+ * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = AND (level) interrupts
+ * data[3] : left-shift for data[4] and data[5]
+ * data[4] : rising-edge/high level channels
+ * data[5] : falling-edge/low level channels
+ */
+static int apci1032_cos_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct apci1032_private *devpriv = dev->private;
+ unsigned int shift, oldmask;
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIGITAL_TRIG:
+ if (data[1] != 0)
+ return -EINVAL;
+ shift = data[3];
+ oldmask = (1U << shift) - 1;
+ switch (data[2]) {
+ case COMEDI_DIGITAL_TRIG_DISABLE:
+ devpriv->ctrl = 0;
+ devpriv->mode1 = 0;
+ devpriv->mode2 = 0;
+ apci1032_reset(dev);
+ break;
+ case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
+ if (devpriv->ctrl != (APCI1032_CTRL_INT_ENA |
+ APCI1032_CTRL_INT_OR)) {
+ /* switching to 'OR' mode */
+ devpriv->ctrl = APCI1032_CTRL_INT_ENA |
+ APCI1032_CTRL_INT_OR;
+ /* wipe old channels */
+ devpriv->mode1 = 0;
+ devpriv->mode2 = 0;
+ } else {
+ /* preserve unspecified channels */
+ devpriv->mode1 &= oldmask;
+ devpriv->mode2 &= oldmask;
+ }
+ /* configure specified channels */
+ devpriv->mode1 |= data[4] << shift;
+ devpriv->mode2 |= data[5] << shift;
+ break;
+ case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS:
+ if (devpriv->ctrl != (APCI1032_CTRL_INT_ENA |
+ APCI1032_CTRL_INT_AND)) {
+ /* switching to 'AND' mode */
+ devpriv->ctrl = APCI1032_CTRL_INT_ENA |
+ APCI1032_CTRL_INT_AND;
+ /* wipe old channels */
+ devpriv->mode1 = 0;
+ devpriv->mode2 = 0;
+ } else {
+ /* preserve unspecified channels */
+ devpriv->mode1 &= oldmask;
+ devpriv->mode2 &= oldmask;
+ }
+ /* configure specified channels */
+ devpriv->mode1 |= data[4] << shift;
+ devpriv->mode2 |= data[5] << shift;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return insn->n;
+}
+
+static int apci1032_cos_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ data[1] = s->state;
+
+ return 0;
+}
+
+static int apci1032_cos_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;
+}
+
+/*
+ * Change-Of-State (COS) 'do_cmd' operation
+ *
+ * Enable the COS interrupt as configured by apci1032_cos_insn_config().
+ */
+static int apci1032_cos_cmd(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct apci1032_private *devpriv = dev->private;
+
+ if (!devpriv->ctrl) {
+ dev_warn(dev->class_dev,
+ "Interrupts disabled due to mode configuration!\n");
+ return -EINVAL;
+ }
+
+ outl(devpriv->mode1, dev->iobase + APCI1032_MODE1_REG);
+ outl(devpriv->mode2, dev->iobase + APCI1032_MODE2_REG);
+ outl(devpriv->ctrl, dev->iobase + APCI1032_CTRL_REG);
+
+ return 0;
+}
+
+static int apci1032_cos_cancel(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ return apci1032_reset(dev);
+}
+
+static irqreturn_t apci1032_interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct apci1032_private *devpriv = dev->private;
+ struct comedi_subdevice *s = dev->read_subdev;
+ unsigned int ctrl;
+
+ /* check interrupt is from this device */
+ if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) &
+ INTCSR_INTR_ASSERTED) == 0)
+ return IRQ_NONE;
+
+ /* check interrupt is enabled */
+ ctrl = inl(dev->iobase + APCI1032_CTRL_REG);
+ if ((ctrl & APCI1032_CTRL_INT_ENA) == 0)
+ return IRQ_HANDLED;
+
+ /* disable the interrupt */
+ outl(ctrl & ~APCI1032_CTRL_INT_ENA, dev->iobase + APCI1032_CTRL_REG);
+
+ s->state = inl(dev->iobase + APCI1032_STATUS_REG) & 0xffff;
+ comedi_buf_put(s->async, s->state);
+ s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+ comedi_event(dev, s);
+
+ /* enable the interrupt */
+ outl(ctrl, dev->iobase + APCI1032_CTRL_REG);
+
+ return IRQ_HANDLED;
+}
+
+static int apci1032_di_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ data[1] = inl(dev->iobase + APCI1032_DI_REG);
+
+ return insn->n;
+}
+
+static int apci1032_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct apci1032_private *devpriv;
+ struct comedi_subdevice *s;
+ int ret;
+
+ dev->board_name = dev->driver->driver_name;
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
+ ret = comedi_pci_enable(pcidev, dev->board_name);
+ if (ret)
+ return ret;
+
+ devpriv->amcc_iobase = pci_resource_start(pcidev, 0);
+ dev->iobase = pci_resource_start(pcidev, 1);
+ apci1032_reset(dev);
+ if (pcidev->irq > 0) {
+ ret = request_irq(pcidev->irq, apci1032_interrupt, IRQF_SHARED,
+ dev->board_name, dev);
+ if (ret == 0)
+ dev->irq = pcidev->irq;
+ }
+
+ ret = comedi_alloc_subdevices(dev, 2);
+ if (ret)
+ return ret;
+
+ /* Allocate and Initialise DI Subdevice Structures */
+ s = &dev->subdevices[0];
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 32;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = apci1032_di_insn_bits;
+
+ /* Change-Of-State (COS) interrupt subdevice */
+ s = &dev->subdevices[1];
+ if (dev->irq) {
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_DI | SDF_CMD_READ;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 1;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_config = apci1032_cos_insn_config;
+ s->insn_bits = apci1032_cos_insn_bits;
+ s->do_cmdtest = apci1032_cos_cmdtest;
+ s->do_cmd = apci1032_cos_cmd;
+ s->cancel = apci1032_cos_cancel;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ return 0;
+}
+
+static void apci1032_detach(struct comedi_device *dev)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+
+ if (dev->iobase)
+ apci1032_reset(dev);
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ if (pcidev) {
+ if (dev->iobase)
+ comedi_pci_disable(pcidev);
+ }
+}
+
+static struct comedi_driver apci1032_driver = {
+ .driver_name = "addi_apci_1032",
+ .module = THIS_MODULE,
+ .auto_attach = apci1032_auto_attach,
+ .detach = apci1032_detach,
+};
+
+static int apci1032_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ return comedi_pci_auto_config(dev, &apci1032_driver);
+}
+
+static void apci1032_pci_remove(struct pci_dev *dev)
+{
+ comedi_pci_auto_unconfig(dev);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(apci1032_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1003) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, apci1032_pci_table);
+
+static struct pci_driver apci1032_pci_driver = {
+ .name = "addi_apci_1032",
+ .id_table = apci1032_pci_table,
+ .probe = apci1032_pci_probe,
+ .remove = apci1032_pci_remove,
+};
+module_comedi_pci_driver(apci1032_driver, apci1032_pci_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c
index bfd84f66d9c..8e686a9b811 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1500.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1500.c
@@ -1,9 +1,77 @@
-#define CONFIG_APCI_1500 1
+#include "../comedidev.h"
+#include "comedi_fc.h"
+#include "amcc_s5933.h"
-#define ADDIDATA_DRIVER_NAME "addi_apci_1500"
+#include "addi-data/addi_common.h"
+#include "addi-data/addi_eeprom.c"
+#include "addi-data/hwdrv_apci1500.c"
#include "addi-data/addi_common.c"
+static const struct addi_board apci1500_boardtypes[] = {
+ {
+ .pc_DriverName = "apci1500",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD,
+ .i_DeviceId = 0x80fc,
+ .i_IorangeBase0 = 128,
+ .i_IorangeBase1 = APCI1500_ADDRESS_RANGE,
+ .i_IorangeBase2 = 4,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .i_NbrDiChannel = 16,
+ .i_NbrDoChannel = 16,
+ .i_DoMaxdata = 0xffff,
+ .i_Timer = 1,
+ .interrupt = v_APCI1500_Interrupt,
+ .reset = i_APCI1500_Reset,
+ .di_config = i_APCI1500_ConfigDigitalInputEvent,
+ .di_read = i_APCI1500_Initialisation,
+ .di_write = i_APCI1500_StartStopInputEvent,
+ .di_bits = apci1500_di_insn_bits,
+ .do_config = i_APCI1500_ConfigDigitalOutputErrorInterrupt,
+ .do_write = i_APCI1500_WriteDigitalOutput,
+ .do_bits = i_APCI1500_ConfigureInterrupt,
+ .timer_config = i_APCI1500_ConfigCounterTimerWatchdog,
+ .timer_write = i_APCI1500_StartStopTriggerTimerCounterWatchdog,
+ .timer_read = i_APCI1500_ReadInterruptMask,
+ .timer_bits = i_APCI1500_ReadCounterTimerWatchdog,
+ },
+};
+
+static struct comedi_driver apci1500_driver = {
+ .driver_name = "addi_apci_1500",
+ .module = THIS_MODULE,
+ .auto_attach = addi_auto_attach,
+ .detach = i_ADDI_Detach,
+ .num_names = ARRAY_SIZE(apci1500_boardtypes),
+ .board_name = &apci1500_boardtypes[0].pc_DriverName,
+ .offset = sizeof(struct addi_board),
+};
+
+static int apci1500_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ return comedi_pci_auto_config(dev, &apci1500_driver);
+}
+
+static void apci1500_pci_remove(struct pci_dev *dev)
+{
+ comedi_pci_auto_unconfig(dev);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(apci1500_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x80fc) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, apci1500_pci_table);
+
+static struct pci_driver apci1500_pci_driver = {
+ .name = "addi_apci_1500",
+ .id_table = apci1500_pci_table,
+ .probe = apci1500_pci_probe,
+ .remove = apci1500_pci_remove,
+};
+module_comedi_pci_driver(apci1500_driver, apci1500_pci_driver);
+
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c
index a12e2f42137..8fef04b4d19 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1516.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1516.c
@@ -1,9 +1,349 @@
-#define CONFIG_APCI_1516 1
+/*
+ * addi_apci_1516.c
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ * Project manager: Eric Stolz
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data.com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * You should also find the complete GPL in the COPYING file accompanying
+ * this source code.
+ */
-#define ADDIDATA_DRIVER_NAME "addi_apci_1516"
+#include "../comedidev.h"
+#include "comedi_fc.h"
-#include "addi-data/addi_common.c"
+/*
+ * PCI device ids supported by this driver
+ */
+#define PCI_DEVICE_ID_APCI1016 0x1000
+#define PCI_DEVICE_ID_APCI1516 0x1001
+#define PCI_DEVICE_ID_APCI2016 0x1002
+/*
+ * PCI bar 1 I/O Register map - Digital input/output
+ */
+#define APCI1516_DI_REG 0x00
+#define APCI1516_DO_REG 0x04
+
+/*
+ * PCI bar 2 I/O Register map - Watchdog (APCI-1516 and APCI-2016)
+ */
+#define APCI1516_WDOG_REG 0x00
+#define APCI1516_WDOG_RELOAD_REG 0x04
+#define APCI1516_WDOG_CTRL_REG 0x0c
+#define APCI1516_WDOG_CTRL_ENABLE (1 << 0)
+#define APCI1516_WDOG_CTRL_SW_TRIG (1 << 9)
+#define APCI1516_WDOG_STATUS_REG 0x10
+#define APCI1516_WDOG_STATUS_ENABLED (1 << 0)
+#define APCI1516_WDOG_STATUS_SW_TRIG (1 << 1)
+
+struct apci1516_boardinfo {
+ const char *name;
+ unsigned short device;
+ int di_nchan;
+ int do_nchan;
+ int has_wdog;
+};
+
+static const struct apci1516_boardinfo apci1516_boardtypes[] = {
+ {
+ .name = "apci1016",
+ .device = PCI_DEVICE_ID_APCI1016,
+ .di_nchan = 16,
+ }, {
+ .name = "apci1516",
+ .device = PCI_DEVICE_ID_APCI1516,
+ .di_nchan = 8,
+ .do_nchan = 8,
+ .has_wdog = 1,
+ }, {
+ .name = "apci2016",
+ .device = PCI_DEVICE_ID_APCI2016,
+ .do_nchan = 16,
+ .has_wdog = 1,
+ },
+};
+
+struct apci1516_private {
+ unsigned long wdog_iobase;
+ unsigned int ctrl;
+};
+
+static int apci1516_di_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ data[1] = inw(dev->iobase + APCI1516_DI_REG);
+
+ return insn->n;
+}
+
+static int apci1516_do_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ 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);
+
+ outw(s->state, dev->iobase + APCI1516_DO_REG);
+ }
+
+ data[1] = s->state;
+
+ return insn->n;
+}
+
+/*
+ * The watchdog subdevice is configured with two INSN_CONFIG instructions:
+ *
+ * Enable the watchdog and set the reload timeout:
+ * data[0] = INSN_CONFIG_ARM
+ * data[1] = timeout reload value
+ *
+ * Disable the watchdog:
+ * data[0] = INSN_CONFIG_DISARM
+ */
+static int apci1516_wdog_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct apci1516_private *devpriv = dev->private;
+ unsigned int reload;
+
+ switch (data[0]) {
+ case INSN_CONFIG_ARM:
+ devpriv->ctrl = APCI1516_WDOG_CTRL_ENABLE;
+ reload = data[1] & s->maxdata;
+ outw(reload, devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_REG);
+
+ /* Time base is 20ms, let the user know the timeout */
+ dev_info(dev->class_dev, "watchdog enabled, timeout:%dms\n",
+ 20 * reload + 20);
+ break;
+ case INSN_CONFIG_DISARM:
+ devpriv->ctrl = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ outw(devpriv->ctrl, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG);
+
+ return insn->n;
+}
+
+static int apci1516_wdog_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct apci1516_private *devpriv = dev->private;
+ int i;
+
+ if (devpriv->ctrl == 0) {
+ dev_warn(dev->class_dev, "watchdog is disabled\n");
+ return -EINVAL;
+ }
+
+ /* "ping" the watchdog */
+ for (i = 0; i < insn->n; i++) {
+ outw(devpriv->ctrl | APCI1516_WDOG_CTRL_SW_TRIG,
+ devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG);
+ }
+
+ return insn->n;
+}
+
+static int apci1516_wdog_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct apci1516_private *devpriv = dev->private;
+ int i;
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = inw(devpriv->wdog_iobase + APCI1516_WDOG_STATUS_REG);
+
+ return insn->n;
+}
+
+static int apci1516_reset(struct comedi_device *dev)
+{
+ const struct apci1516_boardinfo *this_board = comedi_board(dev);
+ struct apci1516_private *devpriv = dev->private;
+
+ if (!this_board->has_wdog)
+ return 0;
+
+ outw(0x0, dev->iobase + APCI1516_DO_REG);
+ outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG);
+ outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_REG);
+
+ return 0;
+}
+
+static const void *apci1516_find_boardinfo(struct comedi_device *dev,
+ struct pci_dev *pcidev)
+{
+ const struct apci1516_boardinfo *this_board;
+ int i;
+
+ for (i = 0; i < dev->driver->num_names; i++) {
+ this_board = &apci1516_boardtypes[i];
+ if (this_board->device == pcidev->device)
+ return this_board;
+ }
+ return NULL;
+}
+
+static int apci1516_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ const struct apci1516_boardinfo *this_board;
+ struct apci1516_private *devpriv;
+ struct comedi_subdevice *s;
+ int ret;
+
+ this_board = apci1516_find_boardinfo(dev, pcidev);
+ if (!this_board)
+ return -ENODEV;
+ dev->board_ptr = this_board;
+ dev->board_name = this_board->name;
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
+ ret = comedi_pci_enable(pcidev, dev->board_name);
+ if (ret)
+ return ret;
+
+ dev->iobase = pci_resource_start(pcidev, 1);
+ devpriv->wdog_iobase = pci_resource_start(pcidev, 2);
+
+ ret = comedi_alloc_subdevices(dev, 3);
+ if (ret)
+ return ret;
+
+ /* Initialize the digital input subdevice */
+ s = &dev->subdevices[0];
+ if (this_board->di_nchan) {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = this_board->di_nchan;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = apci1516_di_insn_bits;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* Initialize the digital output subdevice */
+ s = &dev->subdevices[1];
+ if (this_board->do_nchan) {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = this_board->do_nchan;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = apci1516_do_insn_bits;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* Initialize the watchdog subdevice */
+ s = &dev->subdevices[2];
+ if (this_board->has_wdog) {
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 1;
+ s->maxdata = 0xff;
+ s->insn_write = apci1516_wdog_insn_write;
+ s->insn_read = apci1516_wdog_insn_read;
+ s->insn_config = apci1516_wdog_insn_config;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ apci1516_reset(dev);
+ return 0;
+}
+
+static void apci1516_detach(struct comedi_device *dev)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+
+ if (dev->iobase) {
+ apci1516_reset(dev);
+ comedi_pci_disable(pcidev);
+ }
+}
+
+static struct comedi_driver apci1516_driver = {
+ .driver_name = "addi_apci_1516",
+ .module = THIS_MODULE,
+ .auto_attach = apci1516_auto_attach,
+ .detach = apci1516_detach,
+};
+
+static int apci1516_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ return comedi_pci_auto_config(dev, &apci1516_driver);
+}
+
+static void apci1516_pci_remove(struct pci_dev *dev)
+{
+ comedi_pci_auto_unconfig(dev);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(apci1516_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI1016) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI1516) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI2016) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, apci1516_pci_table);
+
+static struct pci_driver apci1516_pci_driver = {
+ .name = "addi_apci_1516",
+ .id_table = apci1516_pci_table,
+ .probe = apci1516_pci_probe,
+ .remove = apci1516_pci_remove,
+};
+module_comedi_pci_driver(apci1516_driver, apci1516_pci_driver);
+
+MODULE_DESCRIPTION("ADDI-DATA APCI-1016/1516/2016, 16 channel DIO boards");
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c
index 1b9d598fb6c..513e536f292 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1564.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1564.c
@@ -1,9 +1,74 @@
-#define CONFIG_APCI_1564 1
+#include "../comedidev.h"
+#include "comedi_fc.h"
+#include "amcc_s5933.h"
-#define ADDIDATA_DRIVER_NAME "addi_apci_1564"
+#include "addi-data/addi_common.h"
+#include "addi-data/addi_eeprom.c"
+#include "addi-data/hwdrv_apci1564.c"
#include "addi-data/addi_common.c"
+static const struct addi_board apci1564_boardtypes[] = {
+ {
+ .pc_DriverName = "apci1564",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x1006,
+ .i_IorangeBase0 = 128,
+ .i_IorangeBase1 = APCI1564_ADDRESS_RANGE,
+ .i_PCIEeprom = ADDIDATA_EEPROM,
+ .pc_EepromChip = ADDIDATA_93C76,
+ .i_NbrDiChannel = 32,
+ .i_NbrDoChannel = 32,
+ .i_DoMaxdata = 0xffffffff,
+ .i_Timer = 1,
+ .interrupt = v_APCI1564_Interrupt,
+ .reset = i_APCI1564_Reset,
+ .di_config = i_APCI1564_ConfigDigitalInput,
+ .di_bits = apci1564_di_insn_bits,
+ .do_config = i_APCI1564_ConfigDigitalOutput,
+ .do_bits = apci1564_do_insn_bits,
+ .do_read = i_APCI1564_ReadInterruptStatus,
+ .timer_config = i_APCI1564_ConfigTimerCounterWatchdog,
+ .timer_write = i_APCI1564_StartStopWriteTimerCounterWatchdog,
+ .timer_read = i_APCI1564_ReadTimerCounterWatchdog,
+ },
+};
+
+static struct comedi_driver apci1564_driver = {
+ .driver_name = "addi_apci_1564",
+ .module = THIS_MODULE,
+ .auto_attach = addi_auto_attach,
+ .detach = i_ADDI_Detach,
+ .num_names = ARRAY_SIZE(apci1564_boardtypes),
+ .board_name = &apci1564_boardtypes[0].pc_DriverName,
+ .offset = sizeof(struct addi_board),
+};
+
+static int apci1564_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ return comedi_pci_auto_config(dev, &apci1564_driver);
+}
+
+static void apci1564_pci_remove(struct pci_dev *dev)
+{
+ comedi_pci_auto_unconfig(dev);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(apci1564_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1006) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, apci1564_pci_table);
+
+static struct pci_driver apci1564_pci_driver = {
+ .name = "addi_apci_1564",
+ .id_table = apci1564_pci_table,
+ .probe = apci1564_pci_probe,
+ .remove = apci1564_pci_remove,
+};
+module_comedi_pci_driver(apci1564_driver, apci1564_pci_driver);
+
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c
index d54218d59c5..ab9a96ac818 100644
--- a/drivers/staging/comedi/drivers/addi_apci_16xx.c
+++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c
@@ -1,9 +1,77 @@
-#define CONFIG_APCI_16XX 1
+#include "../comedidev.h"
+#include "comedi_fc.h"
+#include "amcc_s5933.h"
-#define ADDIDATA_DRIVER_NAME "addi_apci_16xx"
+#include "addi-data/addi_common.h"
+#include "addi-data/addi_eeprom.c"
+#include "addi-data/hwdrv_apci16xx.c"
#include "addi-data/addi_common.c"
+static const struct addi_board apci16xx_boardtypes[] = {
+ {
+ .pc_DriverName = "apci1648",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x1009,
+ .i_IorangeBase0 = 128,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .i_NbrTTLChannel = 48,
+ .reset = i_APCI16XX_Reset,
+ .ttl_config = i_APCI16XX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI16XX_InsnBitsReadTTLIO,
+ .ttl_read = i_APCI16XX_InsnReadTTLIOAllPortValue,
+ .ttl_write = i_APCI16XX_InsnBitsWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci1696",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x100A,
+ .i_IorangeBase0 = 128,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .i_NbrTTLChannel = 96,
+ .reset = i_APCI16XX_Reset,
+ .ttl_config = i_APCI16XX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI16XX_InsnBitsReadTTLIO,
+ .ttl_read = i_APCI16XX_InsnReadTTLIOAllPortValue,
+ .ttl_write = i_APCI16XX_InsnBitsWriteTTLIO,
+ },
+};
+
+static struct comedi_driver apci16xx_driver = {
+ .driver_name = "addi_apci_16xx",
+ .module = THIS_MODULE,
+ .auto_attach = addi_auto_attach,
+ .detach = i_ADDI_Detach,
+ .num_names = ARRAY_SIZE(apci16xx_boardtypes),
+ .board_name = &apci16xx_boardtypes[0].pc_DriverName,
+ .offset = sizeof(struct addi_board),
+};
+
+static int apci16xx_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ return comedi_pci_auto_config(dev, &apci16xx_driver);
+}
+
+static void apci16xx_pci_remove(struct pci_dev *dev)
+{
+ comedi_pci_auto_unconfig(dev);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(apci16xx_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1009) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x100a) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, apci16xx_pci_table);
+
+static struct pci_driver apci16xx_pci_driver = {
+ .name = "addi_apci_16xx",
+ .id_table = apci16xx_pci_table,
+ .probe = apci16xx_pci_probe,
+ .remove = apci16xx_pci_remove,
+};
+module_comedi_pci_driver(apci16xx_driver, apci16xx_pci_driver);
+
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c
index df6ba8ccf56..152e7ef9b17 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1710.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1710.c
@@ -1,5 +1,152 @@
-#define CONFIG_APCI_1710 1
+#include <asm/i387.h>
-#define ADDIDATA_DRIVER_NAME "addi_apci_1710"
+#include "../comedidev.h"
+#include "comedi_fc.h"
+#include "amcc_s5933.h"
-#include "addi-data/addi_common.c"
+#include "addi-data/addi_common.h"
+
+static void fpu_begin(void)
+{
+ kernel_fpu_begin();
+}
+
+static void fpu_end(void)
+{
+ kernel_fpu_end();
+}
+
+#include "addi-data/addi_eeprom.c"
+#include "addi-data/hwdrv_APCI1710.c"
+
+static const struct addi_board apci1710_boardtypes[] = {
+ {
+ .pc_DriverName = "apci1710",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD,
+ .i_DeviceId = APCI1710_BOARD_DEVICE_ID,
+ .interrupt = v_APCI1710_Interrupt,
+ },
+};
+
+static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ const struct addi_board *this_board = comedi_board(dev);
+
+ this_board->interrupt(irq, d);
+ return IRQ_RETVAL(1);
+}
+
+static const void *apci1710_find_boardinfo(struct comedi_device *dev,
+ struct pci_dev *pcidev)
+{
+ const struct addi_board *this_board;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(apci1710_boardtypes); i++) {
+ this_board = &apci1710_boardtypes[i];
+ if (this_board->i_VendorId == pcidev->vendor &&
+ this_board->i_DeviceId == pcidev->device)
+ return this_board;
+ }
+ return NULL;
+}
+
+static int apci1710_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ const struct addi_board *this_board;
+ struct addi_private *devpriv;
+ struct comedi_subdevice *s;
+ int ret;
+
+ this_board = apci1710_find_boardinfo(dev, pcidev);
+ if (!this_board)
+ return -ENODEV;
+ dev->board_ptr = this_board;
+ dev->board_name = this_board->pc_DriverName;
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
+ ret = comedi_pci_enable(pcidev, dev->board_name);
+ if (ret)
+ return ret;
+
+ if (this_board->i_IorangeBase1)
+ dev->iobase = pci_resource_start(pcidev, 1);
+ else
+ dev->iobase = pci_resource_start(pcidev, 0);
+
+ devpriv->iobase = dev->iobase;
+ devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0);
+ devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2);
+ devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3);
+
+ if (pcidev->irq > 0) {
+ ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
+ dev->board_name, dev);
+ if (ret == 0)
+ dev->irq = pcidev->irq;
+ }
+
+ i_ADDI_AttachPCI1710(dev);
+
+ devpriv->s_BoardInfos.ui_Address = pci_resource_start(pcidev, 2);
+
+ i_APCI1710_Reset(dev);
+ return 0;
+}
+
+static void apci1710_detach(struct comedi_device *dev)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+
+ if (dev->iobase)
+ i_APCI1710_Reset(dev);
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ if (pcidev) {
+ if (dev->iobase)
+ comedi_pci_disable(pcidev);
+ }
+}
+
+static struct comedi_driver apci1710_driver = {
+ .driver_name = "addi_apci_1710",
+ .module = THIS_MODULE,
+ .auto_attach = apci1710_auto_attach,
+ .detach = apci1710_detach,
+};
+
+static int apci1710_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ return comedi_pci_auto_config(dev, &apci1710_driver);
+}
+
+static void apci1710_pci_remove(struct pci_dev *dev)
+{
+ comedi_pci_auto_unconfig(dev);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(apci1710_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, APCI1710_BOARD_DEVICE_ID) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, apci1710_pci_table);
+
+static struct pci_driver apci1710_pci_driver = {
+ .name = "addi_apci_1710",
+ .id_table = apci1710_pci_table,
+ .probe = apci1710_pci_probe,
+ .remove = apci1710_pci_remove,
+};
+module_comedi_pci_driver(apci1710_driver, apci1710_pci_driver);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c
deleted file mode 100644
index fa50c7bb7ad..00000000000
--- a/drivers/staging/comedi/drivers/addi_apci_2016.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#define CONFIG_APCI_2016 1
-
-#define ADDIDATA_DRIVER_NAME "addi_apci_2016"
-
-#include "addi-data/addi_common.c"
-
-MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c
index 073a8a56dbe..8f8d3e95fc7 100644
--- a/drivers/staging/comedi/drivers/addi_apci_2032.c
+++ b/drivers/staging/comedi/drivers/addi_apci_2032.c
@@ -1,8 +1,383 @@
-#define CONFIG_APCI_2032 1
+/*
+ * addi_apci_2032.c
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ * Project manager: Eric Stolz
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data.com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * You should also find the complete GPL in the COPYING file accompanying
+ * this source code.
+ */
-#define ADDIDATA_DRIVER_NAME "addi_apci_2032"
+#include "../comedidev.h"
+#include "comedi_fc.h"
-#include "addi-data/addi_common.c"
+/*
+ * PCI bar 1 I/O Register map
+ */
+#define APCI2032_DO_REG 0x00
+#define APCI2032_INT_CTRL_REG 0x04
+#define APCI2032_INT_CTRL_VCC_ENA (1 << 0)
+#define APCI2032_INT_CTRL_CC_ENA (1 << 1)
+#define APCI2032_INT_STATUS_REG 0x08
+#define APCI2032_INT_STATUS_VCC (1 << 0)
+#define APCI2032_INT_STATUS_CC (1 << 1)
+#define APCI2032_STATUS_REG 0x0c
+#define APCI2032_STATUS_IRQ (1 << 0)
+#define APCI2032_WDOG_REG 0x10
+#define APCI2032_WDOG_RELOAD_REG 0x14
+#define APCI2032_WDOG_TIMEBASE 0x18
+#define APCI2032_WDOG_CTRL_REG 0x1c
+#define APCI2032_WDOG_CTRL_ENABLE (1 << 0)
+#define APCI2032_WDOG_CTRL_SW_TRIG (1 << 9)
+#define APCI2032_WDOG_STATUS_REG 0x20
+#define APCI2032_WDOG_STATUS_ENABLED (1 << 0)
+#define APCI2032_WDOG_STATUS_SW_TRIG (1 << 1)
+
+struct apci2032_private {
+ unsigned int wdog_ctrl;
+};
+
+static int apci2032_do_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ 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);
+
+ outl(s->state, dev->iobase + APCI2032_DO_REG);
+ }
+
+ data[1] = s->state;
+
+ return insn->n;
+}
+
+/*
+ * The watchdog subdevice is configured with two INSN_CONFIG instructions:
+ *
+ * Enable the watchdog and set the reload timeout:
+ * data[0] = INSN_CONFIG_ARM
+ * data[1] = timeout reload value
+ *
+ * Disable the watchdog:
+ * data[0] = INSN_CONFIG_DISARM
+ */
+static int apci2032_wdog_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct apci2032_private *devpriv = dev->private;
+ unsigned int reload;
+
+ switch (data[0]) {
+ case INSN_CONFIG_ARM:
+ devpriv->wdog_ctrl = APCI2032_WDOG_CTRL_ENABLE;
+ reload = data[1] & s->maxdata;
+ outw(reload, dev->iobase + APCI2032_WDOG_RELOAD_REG);
+
+ /* Time base is 20ms, let the user know the timeout */
+ dev_info(dev->class_dev, "watchdog enabled, timeout:%dms\n",
+ 20 * reload + 20);
+ break;
+ case INSN_CONFIG_DISARM:
+ devpriv->wdog_ctrl = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ outw(devpriv->wdog_ctrl, dev->iobase + APCI2032_WDOG_CTRL_REG);
+
+ return insn->n;
+}
+
+static int apci2032_wdog_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct apci2032_private *devpriv = dev->private;
+ int i;
+
+ if (devpriv->wdog_ctrl == 0) {
+ dev_warn(dev->class_dev, "watchdog is disabled\n");
+ return -EINVAL;
+ }
+
+ /* "ping" the watchdog */
+ for (i = 0; i < insn->n; i++) {
+ outw(devpriv->wdog_ctrl | APCI2032_WDOG_CTRL_SW_TRIG,
+ dev->iobase + APCI2032_WDOG_CTRL_REG);
+ }
+
+ return insn->n;
+}
+
+static int apci2032_wdog_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ int i;
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = inl(dev->iobase + APCI2032_WDOG_STATUS_REG);
+
+ return insn->n;
+}
+
+static int apci2032_int_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ data[1] = s->state;
+ return insn->n;
+}
+
+static int apci2032_int_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_OTHER);
+ 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);
+
+ /*
+ * 0 == no trigger
+ * 1 == trigger on VCC interrupt
+ * 2 == trigger on CC interrupt
+ * 3 == trigger on either VCC or CC interrupt
+ */
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 3);
+
+ 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 apci2032_int_cmd(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ outl(cmd->scan_begin_arg, dev->iobase + APCI2032_INT_CTRL_REG);
+
+ return 0;
+}
+
+static int apci2032_int_cancel(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ outl(0x0, dev->iobase + APCI2032_INT_CTRL_REG);
+
+ return 0;
+}
+
+static irqreturn_t apci2032_interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->read_subdev;
+ unsigned int val;
+
+ /* Check if VCC OR CC interrupt has occurred */
+ val = inl(dev->iobase + APCI2032_STATUS_REG) & APCI2032_STATUS_IRQ;
+ if (!val)
+ return IRQ_NONE;
+
+ s->state = inl(dev->iobase + APCI2032_INT_STATUS_REG);
+ outl(0x0, dev->iobase + APCI2032_INT_CTRL_REG);
+
+ comedi_buf_put(s->async, s->state);
+ s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+ comedi_event(dev, s);
+
+ return IRQ_HANDLED;
+}
+
+static int apci2032_reset(struct comedi_device *dev)
+{
+ outl(0x0, dev->iobase + APCI2032_DO_REG);
+ outl(0x0, dev->iobase + APCI2032_INT_CTRL_REG);
+ outl(0x0, dev->iobase + APCI2032_WDOG_CTRL_REG);
+ outl(0x0, dev->iobase + APCI2032_WDOG_RELOAD_REG);
+
+ return 0;
+}
+
+static int apci2032_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct apci2032_private *devpriv;
+ struct comedi_subdevice *s;
+ int ret;
+
+ dev->board_name = dev->driver->driver_name;
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
+ ret = comedi_pci_enable(pcidev, dev->board_name);
+ if (ret)
+ return ret;
+ dev->iobase = pci_resource_start(pcidev, 1);
+
+ if (pcidev->irq > 0) {
+ ret = request_irq(pcidev->irq, apci2032_interrupt,
+ IRQF_SHARED, dev->board_name, dev);
+ if (ret == 0)
+ dev->irq = pcidev->irq;
+ }
+
+ ret = comedi_alloc_subdevices(dev, 3);
+ if (ret)
+ return ret;
+
+ /* Initialize the digital output subdevice */
+ s = &dev->subdevices[0];
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 32;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = apci2032_do_insn_bits;
+
+ /* Initialize the watchdog subdevice */
+ s = &dev->subdevices[1];
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 1;
+ s->maxdata = 0xff;
+ s->insn_write = apci2032_wdog_insn_write;
+ s->insn_read = apci2032_wdog_insn_read;
+ s->insn_config = apci2032_wdog_insn_config;
+
+ /* Initialize the interrupt subdevice */
+ s = &dev->subdevices[2];
+ if (dev->irq) {
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_DI | SDF_CMD_READ;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 1;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = apci2032_int_insn_bits;
+ s->do_cmdtest = apci2032_int_cmdtest;
+ s->do_cmd = apci2032_int_cmd;
+ s->cancel = apci2032_int_cancel;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ apci2032_reset(dev);
+ return 0;
+}
+
+static void apci2032_detach(struct comedi_device *dev)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+
+ if (dev->iobase)
+ apci2032_reset(dev);
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ if (pcidev) {
+ if (dev->iobase)
+ comedi_pci_disable(pcidev);
+ }
+}
+
+static struct comedi_driver apci2032_driver = {
+ .driver_name = "addi_apci_2032",
+ .module = THIS_MODULE,
+ .auto_attach = apci2032_auto_attach,
+ .detach = apci2032_detach,
+};
+
+static int apci2032_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ return comedi_pci_auto_config(dev, &apci2032_driver);
+}
+
+static void apci2032_pci_remove(struct pci_dev *dev)
+{
+ comedi_pci_auto_unconfig(dev);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(apci2032_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1004) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, apci2032_pci_table);
+
+static struct pci_driver apci2032_pci_driver = {
+ .name = "addi_apci_2032",
+ .id_table = apci2032_pci_table,
+ .probe = apci2032_pci_probe,
+ .remove = apci2032_pci_remove,
+};
+module_comedi_pci_driver(apci2032_driver, apci2032_pci_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c
index adfbb5d410e..7c2c5db0121 100644
--- a/drivers/staging/comedi/drivers/addi_apci_2200.c
+++ b/drivers/staging/comedi/drivers/addi_apci_2200.c
@@ -1,9 +1,69 @@
-#define CONFIG_APCI_2200 1
+#include "../comedidev.h"
+#include "comedi_fc.h"
+#include "amcc_s5933.h"
-#define ADDIDATA_DRIVER_NAME "addi_apci_2200"
+#include "addi-data/addi_common.h"
+#include "addi-data/addi_eeprom.c"
+#include "addi-data/hwdrv_apci2200.c"
#include "addi-data/addi_common.c"
+static const struct addi_board apci2200_boardtypes[] = {
+ {
+ .pc_DriverName = "apci2200",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x1005,
+ .i_IorangeBase0 = 4,
+ .i_IorangeBase1 = APCI2200_ADDRESS_RANGE,
+ .i_PCIEeprom = ADDIDATA_EEPROM,
+ .pc_EepromChip = ADDIDATA_93C76,
+ .i_NbrDiChannel = 8,
+ .i_NbrDoChannel = 16,
+ .i_Timer = 1,
+ .reset = i_APCI2200_Reset,
+ .di_bits = apci2200_di_insn_bits,
+ .do_bits = apci2200_do_insn_bits,
+ .timer_config = i_APCI2200_ConfigWatchdog,
+ .timer_write = i_APCI2200_StartStopWriteWatchdog,
+ .timer_read = i_APCI2200_ReadWatchdog,
+ },
+};
+
+static struct comedi_driver apci2200_driver = {
+ .driver_name = "addi_apci_2200",
+ .module = THIS_MODULE,
+ .auto_attach = addi_auto_attach,
+ .detach = i_ADDI_Detach,
+ .num_names = ARRAY_SIZE(apci2200_boardtypes),
+ .board_name = &apci2200_boardtypes[0].pc_DriverName,
+ .offset = sizeof(struct addi_board),
+};
+
+static int apci2200_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ return comedi_pci_auto_config(dev, &apci2200_driver);
+}
+
+static void apci2200_pci_remove(struct pci_dev *dev)
+{
+ comedi_pci_auto_unconfig(dev);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(apci2200_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1005) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, apci2200_pci_table);
+
+static struct pci_driver apci2200_pci_driver = {
+ .name = "addi_apci_2200",
+ .id_table = apci2200_pci_table,
+ .probe = apci2200_pci_probe,
+ .remove = apci2200_pci_remove,
+};
+module_comedi_pci_driver(apci2200_driver, apci2200_pci_driver);
+
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c
deleted file mode 100644
index 00ac762965c..00000000000
--- a/drivers/staging/comedi/drivers/addi_apci_3001.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#define CONFIG_APCI_3001 1
-
-#define ADDIDATA_DRIVER_NAME "addi_apci_3001"
-
-#include "addi-data/addi_common.c"
-
-MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c
index c35515845cf..fec2962affc 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3120.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3120.c
@@ -1,8 +1,275 @@
-#define CONFIG_APCI_3120 1
+#include "../comedidev.h"
+#include "comedi_fc.h"
+#include "amcc_s5933.h"
-#define ADDIDATA_DRIVER_NAME "addi_apci_3120"
+#include "addi-data/addi_common.h"
-#include "addi-data/addi_common.c"
+#include "addi-data/hwdrv_apci3120.c"
+
+static const struct addi_board apci3120_boardtypes[] = {
+ {
+ .pc_DriverName = "apci3120",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD,
+ .i_DeviceId = 0x818D,
+ .i_NbrAiChannel = 16,
+ .i_NbrAiChannelDiff = 8,
+ .i_AiChannelList = 16,
+ .i_NbrAoChannel = 8,
+ .i_AiMaxdata = 0xffff,
+ .i_AoMaxdata = 0x3fff,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 0x0f,
+ .interrupt = v_APCI3120_Interrupt,
+ }, {
+ .pc_DriverName = "apci3001",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD,
+ .i_DeviceId = 0x828D,
+ .i_NbrAiChannel = 16,
+ .i_NbrAiChannelDiff = 8,
+ .i_AiChannelList = 16,
+ .i_AiMaxdata = 0xfff,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 0x0f,
+ .interrupt = v_APCI3120_Interrupt,
+ },
+};
+
+static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ const struct addi_board *this_board = comedi_board(dev);
+
+ this_board->interrupt(irq, d);
+ return IRQ_RETVAL(1);
+}
+
+static const void *apci3120_find_boardinfo(struct comedi_device *dev,
+ struct pci_dev *pcidev)
+{
+ const struct addi_board *this_board;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(apci3120_boardtypes); i++) {
+ this_board = &apci3120_boardtypes[i];
+ if (this_board->i_VendorId == pcidev->vendor &&
+ this_board->i_DeviceId == pcidev->device)
+ return this_board;
+ }
+ return NULL;
+}
+
+static int apci3120_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ const struct addi_board *this_board;
+ struct addi_private *devpriv;
+ struct comedi_subdevice *s;
+ int ret, pages, i;
+
+ this_board = apci3120_find_boardinfo(dev, pcidev);
+ if (!this_board)
+ return -ENODEV;
+ dev->board_ptr = this_board;
+ dev->board_name = this_board->pc_DriverName;
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
+ ret = comedi_pci_enable(pcidev, dev->board_name);
+ if (ret)
+ return ret;
+ pci_set_master(pcidev);
+
+ dev->iobase = pci_resource_start(pcidev, 1);
+ devpriv->iobase = dev->iobase;
+ devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0);
+ devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2);
+ devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3);
+
+ if (pcidev->irq > 0) {
+ ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
+ dev->board_name, dev);
+ if (ret == 0)
+ dev->irq = pcidev->irq;
+ }
+
+ devpriv->us_UseDma = ADDI_ENABLE;
+
+ /* Allocate DMA buffers */
+ devpriv->b_DmaDoubleBuffer = 0;
+ for (i = 0; i < 2; i++) {
+ for (pages = 4; pages >= 0; pages--) {
+ devpriv->ul_DmaBufferVirtual[i] =
+ (void *) __get_free_pages(GFP_KERNEL, pages);
+
+ if (devpriv->ul_DmaBufferVirtual[i])
+ break;
+ }
+ if (devpriv->ul_DmaBufferVirtual[i]) {
+ devpriv->ui_DmaBufferPages[i] = pages;
+ devpriv->ui_DmaBufferSize[i] = PAGE_SIZE * pages;
+ devpriv->ui_DmaBufferSamples[i] =
+ devpriv->ui_DmaBufferSize[i] >> 1;
+ devpriv->ul_DmaBufferHw[i] =
+ virt_to_bus((void *)devpriv->
+ ul_DmaBufferVirtual[i]);
+ }
+ }
+ if (!devpriv->ul_DmaBufferVirtual[0])
+ devpriv->us_UseDma = ADDI_DISABLE;
+
+ if (devpriv->ul_DmaBufferVirtual[1])
+ devpriv->b_DmaDoubleBuffer = 1;
+
+ ret = comedi_alloc_subdevices(dev, 5);
+ if (ret)
+ return ret;
+
+ /* Allocate and Initialise AI Subdevice Structures */
+ s = &dev->subdevices[0];
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags =
+ SDF_READABLE | SDF_COMMON | SDF_GROUND
+ | SDF_DIFF;
+ if (this_board->i_NbrAiChannel) {
+ s->n_chan = this_board->i_NbrAiChannel;
+ devpriv->b_SingelDiff = 0;
+ } else {
+ s->n_chan = this_board->i_NbrAiChannelDiff;
+ devpriv->b_SingelDiff = 1;
+ }
+ s->maxdata = this_board->i_AiMaxdata;
+ s->len_chanlist = this_board->i_AiChannelList;
+ s->range_table = &range_apci3120_ai;
+
+ /* Set the initialisation flag */
+ devpriv->b_AiInitialisation = 1;
+
+ s->insn_config = i_APCI3120_InsnConfigAnalogInput;
+ s->insn_read = i_APCI3120_InsnReadAnalogInput;
+ s->do_cmdtest = i_APCI3120_CommandTestAnalogInput;
+ s->do_cmd = i_APCI3120_CommandAnalogInput;
+ s->cancel = i_APCI3120_StopCyclicAcquisition;
+
+ /* Allocate and Initialise AO Subdevice Structures */
+ s = &dev->subdevices[1];
+ if (this_board->i_NbrAoChannel) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->i_NbrAoChannel;
+ s->maxdata = this_board->i_AoMaxdata;
+ s->len_chanlist = this_board->i_NbrAoChannel;
+ s->range_table = &range_apci3120_ao;
+ s->insn_write = i_APCI3120_InsnWriteAnalogOutput;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* Allocate and Initialise DI Subdevice Structures */
+ s = &dev->subdevices[2];
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->i_NbrDiChannel;
+ 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 */
+ s = &dev->subdevices[3];
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->i_NbrDoChannel;
+ 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 */
+ s = &dev->subdevices[4];
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 1;
+ s->maxdata = 0;
+ s->len_chanlist = 1;
+ s->range_table = &range_digital;
+
+ s->insn_write = i_APCI3120_InsnWriteTimer;
+ s->insn_read = i_APCI3120_InsnReadTimer;
+ s->insn_config = i_APCI3120_InsnConfigTimer;
+
+ i_APCI3120_Reset(dev);
+ return 0;
+}
+
+static void apci3120_detach(struct comedi_device *dev)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct addi_private *devpriv = dev->private;
+
+ if (devpriv) {
+ if (dev->iobase)
+ i_APCI3120_Reset(dev);
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ if (devpriv->ul_DmaBufferVirtual[0]) {
+ free_pages((unsigned long)devpriv->
+ ul_DmaBufferVirtual[0],
+ devpriv->ui_DmaBufferPages[0]);
+ }
+ if (devpriv->ul_DmaBufferVirtual[1]) {
+ free_pages((unsigned long)devpriv->
+ ul_DmaBufferVirtual[1],
+ devpriv->ui_DmaBufferPages[1]);
+ }
+ }
+ if (pcidev) {
+ if (dev->iobase)
+ comedi_pci_disable(pcidev);
+ }
+}
+
+static struct comedi_driver apci3120_driver = {
+ .driver_name = "addi_apci_3120",
+ .module = THIS_MODULE,
+ .auto_attach = apci3120_auto_attach,
+ .detach = apci3120_detach,
+};
+
+static int apci3120_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ return comedi_pci_auto_config(dev, &apci3120_driver);
+}
+
+static void apci3120_pci_remove(struct pci_dev *dev)
+{
+ comedi_pci_auto_unconfig(dev);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(apci3120_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x818d) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x828d) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, apci3120_pci_table);
+
+static struct pci_driver apci3120_pci_driver = {
+ .name = "addi_apci_3120",
+ .id_table = apci3120_pci_table,
+ .probe = apci3120_pci_probe,
+ .remove = apci3120_pci_remove,
+};
+module_comedi_pci_driver(apci3120_driver, apci3120_pci_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c
index 159313997dc..9085b774b48 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3200.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3200.c
@@ -1,5 +1,120 @@
-#define CONFIG_APCI_3200 1
+#include <asm/i387.h>
-#define ADDIDATA_DRIVER_NAME "addi_apci_3200"
+#include "../comedidev.h"
+#include "comedi_fc.h"
+#include "amcc_s5933.h"
+#include "addi-data/addi_common.h"
+
+static void fpu_begin(void)
+{
+ kernel_fpu_begin();
+}
+
+static void fpu_end(void)
+{
+ kernel_fpu_end();
+}
+
+#include "addi-data/addi_eeprom.c"
+#include "addi-data/hwdrv_apci3200.c"
#include "addi-data/addi_common.c"
+
+static const struct addi_board apci3200_boardtypes[] = {
+ {
+ .pc_DriverName = "apci3200",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3000,
+ .i_IorangeBase0 = 128,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 4,
+ .i_IorangeBase3 = 4,
+ .i_PCIEeprom = ADDIDATA_EEPROM,
+ .pc_EepromChip = ADDIDATA_S5920,
+ .i_NbrAiChannel = 16,
+ .i_NbrAiChannelDiff = 8,
+ .i_AiChannelList = 16,
+ .i_AiMaxdata = 0x3ffff,
+ .pr_AiRangelist = &range_apci3200_ai,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .ui_MinAcquisitiontimeNs = 10000,
+ .ui_MinDelaytimeNs = 100000,
+ .interrupt = v_APCI3200_Interrupt,
+ .reset = i_APCI3200_Reset,
+ .ai_config = i_APCI3200_ConfigAnalogInput,
+ .ai_read = i_APCI3200_ReadAnalogInput,
+ .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput,
+ .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test,
+ .ai_cmdtest = i_APCI3200_CommandTestAnalogInput,
+ .ai_cmd = i_APCI3200_CommandAnalogInput,
+ .ai_cancel = i_APCI3200_StopCyclicAcquisition,
+ .di_bits = apci3200_di_insn_bits,
+ .do_bits = apci3200_do_insn_bits,
+ }, {
+ .pc_DriverName = "apci3300",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3007,
+ .i_IorangeBase0 = 128,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 4,
+ .i_IorangeBase3 = 4,
+ .i_PCIEeprom = ADDIDATA_EEPROM,
+ .pc_EepromChip = ADDIDATA_S5920,
+ .i_NbrAiChannelDiff = 8,
+ .i_AiChannelList = 8,
+ .i_AiMaxdata = 0x3ffff,
+ .pr_AiRangelist = &range_apci3300_ai,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .ui_MinAcquisitiontimeNs = 10000,
+ .ui_MinDelaytimeNs = 100000,
+ .interrupt = v_APCI3200_Interrupt,
+ .reset = i_APCI3200_Reset,
+ .ai_config = i_APCI3200_ConfigAnalogInput,
+ .ai_read = i_APCI3200_ReadAnalogInput,
+ .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput,
+ .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test,
+ .ai_cmdtest = i_APCI3200_CommandTestAnalogInput,
+ .ai_cmd = i_APCI3200_CommandAnalogInput,
+ .ai_cancel = i_APCI3200_StopCyclicAcquisition,
+ .di_bits = apci3200_di_insn_bits,
+ .do_bits = apci3200_do_insn_bits,
+ },
+};
+
+static DEFINE_PCI_DEVICE_TABLE(apci3200_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3000) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3007) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, apci3200_pci_table);
+
+static struct comedi_driver apci3200_driver = {
+ .driver_name = "addi_apci_3200",
+ .module = THIS_MODULE,
+ .auto_attach = addi_auto_attach,
+ .detach = i_ADDI_Detach,
+ .num_names = ARRAY_SIZE(apci3200_boardtypes),
+ .board_name = &apci3200_boardtypes[0].pc_DriverName,
+ .offset = sizeof(struct addi_board),
+};
+
+static int apci3200_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ return comedi_pci_auto_config(dev, &apci3200_driver);
+}
+
+static void apci3200_pci_remove(struct pci_dev *dev)
+{
+ comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver apci3200_pci_driver = {
+ .name = "addi_apci_3200",
+ .id_table = apci3200_pci_table,
+ .probe = apci3200_pci_probe,
+ .remove = apci3200_pci_remove,
+};
+module_comedi_pci_driver(apci3200_driver, apci3200_pci_driver);
diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c
deleted file mode 100644
index 733c69abc43..00000000000
--- a/drivers/staging/comedi/drivers/addi_apci_3300.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#define CONFIG_APCI_3300 1
-
-#define ADDIDATA_DRIVER_NAME "addi_apci_3300"
-
-#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c
index dd2c1d3bc18..ed297deb863 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3501.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3501.c
@@ -1,9 +1,75 @@
-#define CONFIG_APCI_3501 1
+#include "../comedidev.h"
+#include "comedi_fc.h"
+#include "amcc_s5933.h"
-#define ADDIDATA_DRIVER_NAME "addi_apci_3501"
+#include "addi-data/addi_common.h"
+#include "addi-data/addi_eeprom.c"
+#include "addi-data/hwdrv_apci3501.c"
#include "addi-data/addi_common.c"
+static const struct addi_board apci3501_boardtypes[] = {
+ {
+ .pc_DriverName = "apci3501",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3001,
+ .i_IorangeBase0 = 64,
+ .i_IorangeBase1 = APCI3501_ADDRESS_RANGE,
+ .i_PCIEeprom = ADDIDATA_EEPROM,
+ .pc_EepromChip = ADDIDATA_S5933,
+ .i_AoMaxdata = 16383,
+ .pr_AoRangelist = &range_apci3501_ao,
+ .i_NbrDiChannel = 2,
+ .i_NbrDoChannel = 2,
+ .i_DoMaxdata = 0x3,
+ .i_Timer = 1,
+ .interrupt = v_APCI3501_Interrupt,
+ .reset = i_APCI3501_Reset,
+ .ao_config = i_APCI3501_ConfigAnalogOutput,
+ .ao_write = i_APCI3501_WriteAnalogOutput,
+ .di_bits = apci3501_di_insn_bits,
+ .do_bits = apci3501_do_insn_bits,
+ .timer_config = i_APCI3501_ConfigTimerCounterWatchdog,
+ .timer_write = i_APCI3501_StartStopWriteTimerCounterWatchdog,
+ .timer_read = i_APCI3501_ReadTimerCounterWatchdog,
+ },
+};
+
+static DEFINE_PCI_DEVICE_TABLE(apci3501_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, apci3501_pci_table);
+
+static struct comedi_driver apci3501_driver = {
+ .driver_name = "addi_apci_3501",
+ .module = THIS_MODULE,
+ .auto_attach = addi_auto_attach,
+ .detach = i_ADDI_Detach,
+ .num_names = ARRAY_SIZE(apci3501_boardtypes),
+ .board_name = &apci3501_boardtypes[0].pc_DriverName,
+ .offset = sizeof(struct addi_board),
+};
+
+static int apci3501_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ return comedi_pci_auto_config(dev, &apci3501_driver);
+}
+
+static void apci3501_pci_remove(struct pci_dev *dev)
+{
+ comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver apci3501_pci_driver = {
+ .name = "addi_apci_3501",
+ .id_table = apci3501_pci_table,
+ .probe = apci3501_pci_probe,
+ .remove = apci3501_pci_remove,
+};
+module_comedi_pci_driver(apci3501_driver, apci3501_pci_driver);
+
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
index 03161c88eac..1562347ed64 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
@@ -1,9 +1,799 @@
-#define CONFIG_APCI_3XXX 1
+#include "../comedidev.h"
+#include "comedi_fc.h"
+#include "amcc_s5933.h"
-#define ADDIDATA_DRIVER_NAME "addi_apci_3xxx"
+#include "addi-data/addi_common.h"
+#include "addi-data/addi_eeprom.c"
+#include "addi-data/hwdrv_apci3xxx.c"
#include "addi-data/addi_common.c"
+static const struct addi_board apci3xxx_boardtypes[] = {
+ {
+ .pc_DriverName = "apci3000-16",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3010,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 16,
+ .i_NbrAiChannelDiff = 8,
+ .i_AiChannelList = 16,
+ .i_AiMaxdata = 4095,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 10000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3000-8",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x300F,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 8,
+ .i_NbrAiChannelDiff = 4,
+ .i_AiChannelList = 8,
+ .i_AiMaxdata = 4095,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 10000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3000-4",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x300E,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 4,
+ .i_NbrAiChannelDiff = 2,
+ .i_AiChannelList = 4,
+ .i_AiMaxdata = 4095,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 10000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3006-16",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3013,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 16,
+ .i_NbrAiChannelDiff = 8,
+ .i_AiChannelList = 16,
+ .i_AiMaxdata = 65535,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 10000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3006-8",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3014,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 8,
+ .i_NbrAiChannelDiff = 4,
+ .i_AiChannelList = 8,
+ .i_AiMaxdata = 65535,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 10000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3006-4",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3015,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 4,
+ .i_NbrAiChannelDiff = 2,
+ .i_AiChannelList = 4,
+ .i_AiMaxdata = 65535,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 10000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3010-16",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3016,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 16,
+ .i_NbrAiChannelDiff = 8,
+ .i_AiChannelList = 16,
+ .i_AiMaxdata = 4095,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 1,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 5000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .di_bits = apci3xxx_di_insn_bits,
+ .do_bits = apci3xxx_do_insn_bits,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3010-8",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3017,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 8,
+ .i_NbrAiChannelDiff = 4,
+ .i_AiChannelList = 8,
+ .i_AiMaxdata = 4095,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 1,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 5000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .di_bits = apci3xxx_di_insn_bits,
+ .do_bits = apci3xxx_do_insn_bits,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3010-4",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3018,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 4,
+ .i_NbrAiChannelDiff = 2,
+ .i_AiChannelList = 4,
+ .i_AiMaxdata = 4095,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 1,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 5000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .di_bits = apci3xxx_di_insn_bits,
+ .do_bits = apci3xxx_do_insn_bits,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3016-16",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3019,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 16,
+ .i_NbrAiChannelDiff = 8,
+ .i_AiChannelList = 16,
+ .i_AiMaxdata = 65535,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 1,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 5000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .di_bits = apci3xxx_di_insn_bits,
+ .do_bits = apci3xxx_do_insn_bits,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3016-8",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x301A,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 8,
+ .i_NbrAiChannelDiff = 4,
+ .i_AiChannelList = 8,
+ .i_AiMaxdata = 65535,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 1,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 5000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .di_bits = apci3xxx_di_insn_bits,
+ .do_bits = apci3xxx_do_insn_bits,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3016-4",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x301B,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 4,
+ .i_NbrAiChannelDiff = 2,
+ .i_AiChannelList = 4,
+ .i_AiMaxdata = 65535,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 1,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 5000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .di_bits = apci3xxx_di_insn_bits,
+ .do_bits = apci3xxx_do_insn_bits,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3100-16-4",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x301C,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 16,
+ .i_NbrAiChannelDiff = 8,
+ .i_AiChannelList = 16,
+ .i_NbrAoChannel = 4,
+ .i_AiMaxdata = 4095,
+ .i_AoMaxdata = 4095,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .pr_AoRangelist = &range_apci3XXX_ao,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 10000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3100-8-4",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x301D,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 8,
+ .i_NbrAiChannelDiff = 4,
+ .i_AiChannelList = 8,
+ .i_NbrAoChannel = 4,
+ .i_AiMaxdata = 4095,
+ .i_AoMaxdata = 4095,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .pr_AoRangelist = &range_apci3XXX_ao,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 10000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3106-16-4",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x301E,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 16,
+ .i_NbrAiChannelDiff = 8,
+ .i_AiChannelList = 16,
+ .i_NbrAoChannel = 4,
+ .i_AiMaxdata = 65535,
+ .i_AoMaxdata = 4095,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .pr_AoRangelist = &range_apci3XXX_ao,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 10000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3106-8-4",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x301F,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 8,
+ .i_NbrAiChannelDiff = 4,
+ .i_AiChannelList = 8,
+ .i_NbrAoChannel = 4,
+ .i_AiMaxdata = 65535,
+ .i_AoMaxdata = 4095,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .pr_AoRangelist = &range_apci3XXX_ao,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 10000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3110-16-4",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3020,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 16,
+ .i_NbrAiChannelDiff = 8,
+ .i_AiChannelList = 16,
+ .i_NbrAoChannel = 4,
+ .i_AiMaxdata = 4095,
+ .i_AoMaxdata = 4095,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .pr_AoRangelist = &range_apci3XXX_ao,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 1,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 5000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
+ .di_bits = apci3xxx_di_insn_bits,
+ .do_bits = apci3xxx_do_insn_bits,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3110-8-4",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3021,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 8,
+ .i_NbrAiChannelDiff = 4,
+ .i_AiChannelList = 8,
+ .i_NbrAoChannel = 4,
+ .i_AiMaxdata = 4095,
+ .i_AoMaxdata = 4095,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .pr_AoRangelist = &range_apci3XXX_ao,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 1,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 5000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
+ .di_bits = apci3xxx_di_insn_bits,
+ .do_bits = apci3xxx_do_insn_bits,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3116-16-4",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3022,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 16,
+ .i_NbrAiChannelDiff = 8,
+ .i_AiChannelList = 16,
+ .i_NbrAoChannel = 4,
+ .i_AiMaxdata = 65535,
+ .i_AoMaxdata = 4095,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .pr_AoRangelist = &range_apci3XXX_ao,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 1,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 5000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
+ .di_bits = apci3xxx_di_insn_bits,
+ .do_bits = apci3xxx_do_insn_bits,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3116-8-4",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3023,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannel = 8,
+ .i_NbrAiChannelDiff = 4,
+ .i_AiChannelList = 8,
+ .i_NbrAoChannel = 4,
+ .i_AiMaxdata = 65535,
+ .i_AoMaxdata = 4095,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .pr_AoRangelist = &range_apci3XXX_ao,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 1,
+ .i_NbrTTLChannel = 24,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 5000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
+ .di_bits = apci3xxx_di_insn_bits,
+ .do_bits = apci3xxx_do_insn_bits,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ }, {
+ .pc_DriverName = "apci3003",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x300B,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannelDiff = 4,
+ .i_AiChannelList = 4,
+ .i_AiMaxdata = 65535,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 1,
+ .b_AvailableConvertUnit = 7,
+ .ui_MinAcquisitiontimeNs = 2500,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .di_bits = apci3xxx_di_insn_bits,
+ .do_bits = apci3xxx_do_insn_bits,
+ }, {
+ .pc_DriverName = "apci3002-16",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3002,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannelDiff = 16,
+ .i_AiChannelList = 16,
+ .i_AiMaxdata = 65535,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 1,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 5000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .di_bits = apci3xxx_di_insn_bits,
+ .do_bits = apci3xxx_do_insn_bits,
+ }, {
+ .pc_DriverName = "apci3002-8",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3003,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannelDiff = 8,
+ .i_AiChannelList = 8,
+ .i_AiMaxdata = 65535,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 1,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 5000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .di_bits = apci3xxx_di_insn_bits,
+ .do_bits = apci3xxx_do_insn_bits,
+ }, {
+ .pc_DriverName = "apci3002-4",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3004,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAiChannelDiff = 4,
+ .i_AiChannelList = 4,
+ .i_AiMaxdata = 65535,
+ .pr_AiRangelist = &range_apci3XXX_ai,
+ .i_NbrDiChannel = 4,
+ .i_NbrDoChannel = 4,
+ .i_DoMaxdata = 1,
+ .b_AvailableConvertUnit = 6,
+ .ui_MinAcquisitiontimeNs = 5000,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ai_config = i_APCI3XXX_InsnConfigAnalogInput,
+ .ai_read = i_APCI3XXX_InsnReadAnalogInput,
+ .di_bits = apci3xxx_di_insn_bits,
+ .do_bits = apci3xxx_do_insn_bits,
+ }, {
+ .pc_DriverName = "apci3500",
+ .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
+ .i_DeviceId = 0x3024,
+ .i_IorangeBase0 = 256,
+ .i_IorangeBase1 = 256,
+ .i_IorangeBase2 = 256,
+ .i_IorangeBase3 = 256,
+ .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .pc_EepromChip = ADDIDATA_9054,
+ .i_NbrAoChannel = 4,
+ .i_AoMaxdata = 4095,
+ .pr_AoRangelist = &range_apci3XXX_ao,
+ .i_NbrTTLChannel = 24,
+ .interrupt = v_APCI3XXX_Interrupt,
+ .reset = i_APCI3XXX_Reset,
+ .ao_write = i_APCI3XXX_InsnWriteAnalogOutput,
+ .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO,
+ .ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
+ .ttl_read = i_APCI3XXX_InsnReadTTLIO,
+ .ttl_write = i_APCI3XXX_InsnWriteTTLIO,
+ },
+};
+
+static struct comedi_driver apci3xxx_driver = {
+ .driver_name = "addi_apci_3xxx",
+ .module = THIS_MODULE,
+ .auto_attach = addi_auto_attach,
+ .detach = i_ADDI_Detach,
+ .num_names = ARRAY_SIZE(apci3xxx_boardtypes),
+ .board_name = &apci3xxx_boardtypes[0].pc_DriverName,
+ .offset = sizeof(struct addi_board),
+};
+
+static int apci3xxx_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ return comedi_pci_auto_config(dev, &apci3xxx_driver);
+}
+
+static void apci3xxx_pci_remove(struct pci_dev *dev)
+{
+ comedi_pci_auto_unconfig(dev);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(apci3xxx_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3010) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300f) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300e) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3013) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3014) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3015) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3016) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3017) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3018) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3019) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301a) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301b) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301c) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301d) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301e) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301f) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3020) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3021) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3022) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3023) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300B) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3002) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3003) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3004) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3024) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, apci3xxx_pci_table);
+
+static struct pci_driver apci3xxx_pci_driver = {
+ .name = "addi_apci_3xxx",
+ .id_table = apci3xxx_pci_table,
+ .probe = apci3xxx_pci_probe,
+ .remove = apci3xxx_pci_remove,
+};
+module_comedi_pci_driver(apci3xxx_driver, apci3xxx_pci_driver);
+
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c
index 3492ce1156e..9a56eed3910 100644
--- a/drivers/staging/comedi/drivers/adl_pci6208.c
+++ b/drivers/staging/comedi/drivers/adl_pci6208.c
@@ -174,27 +174,26 @@ static const void *pci6208_find_boardinfo(struct comedi_device *dev,
return NULL;
}
-static int pci6208_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int pci6208_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct pci6208_board *boardinfo;
struct pci6208_private *devpriv;
struct comedi_subdevice *s;
unsigned int val;
int ret;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
boardinfo = pci6208_find_boardinfo(dev, pcidev);
if (!boardinfo)
return -ENODEV;
dev->board_ptr = boardinfo;
dev->board_name = boardinfo->name;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret < 0)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret)
@@ -261,17 +260,17 @@ static void pci6208_detach(struct comedi_device *dev)
static struct comedi_driver adl_pci6208_driver = {
.driver_name = "adl_pci6208",
.module = THIS_MODULE,
- .attach_pci = pci6208_attach_pci,
+ .auto_attach = pci6208_auto_attach,
.detach = pci6208_detach,
};
-static int __devinit adl_pci6208_pci_probe(struct pci_dev *dev,
+static int adl_pci6208_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &adl_pci6208_driver);
}
-static void __devexit adl_pci6208_pci_remove(struct pci_dev *dev)
+static void adl_pci6208_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -287,7 +286,7 @@ static struct pci_driver adl_pci6208_pci_driver = {
.name = "adl_pci6208",
.id_table = adl_pci6208_pci_table,
.probe = adl_pci6208_pci_probe,
- .remove = __devexit_p(adl_pci6208_pci_remove),
+ .remove = adl_pci6208_pci_remove,
};
module_comedi_pci_driver(adl_pci6208_driver, adl_pci6208_pci_driver);
diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c
index 599714e978b..772edc02f5c 100644
--- a/drivers/staging/comedi/drivers/adl_pci7x3x.c
+++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c
@@ -168,17 +168,16 @@ static const void *adl_pci7x3x_find_boardinfo(struct comedi_device *dev,
return NULL;
}
-static int adl_pci7x3x_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int adl_pci7x3x_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct adl_pci7x3x_boardinfo *board;
struct comedi_subdevice *s;
int subdev;
int nchan;
int ret;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
board = adl_pci7x3x_find_boardinfo(dev, pcidev);
if (!board)
return -ENODEV;
@@ -293,17 +292,17 @@ static void adl_pci7x3x_detach(struct comedi_device *dev)
static struct comedi_driver adl_pci7x3x_driver = {
.driver_name = "adl_pci7x3x",
.module = THIS_MODULE,
- .attach_pci = adl_pci7x3x_attach_pci,
+ .auto_attach = adl_pci7x3x_auto_attach,
.detach = adl_pci7x3x_detach,
};
-static int __devinit adl_pci7x3x_pci_probe(struct pci_dev *dev,
+static int adl_pci7x3x_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &adl_pci7x3x_driver);
}
-static void __devexit adl_pci7x3x_pci_remove(struct pci_dev *dev)
+static void adl_pci7x3x_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -323,7 +322,7 @@ static struct pci_driver adl_pci7x3x_pci_driver = {
.name = "adl_pci7x3x",
.id_table = adl_pci7x3x_pci_table,
.probe = adl_pci7x3x_pci_probe,
- .remove = __devexit_p(adl_pci7x3x_pci_remove),
+ .remove = adl_pci7x3x_pci_remove,
};
module_comedi_pci_driver(adl_pci7x3x_driver, adl_pci7x3x_pci_driver);
diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c
index 05e06e7ba9f..4dd9d707a79 100644
--- a/drivers/staging/comedi/drivers/adl_pci8164.c
+++ b/drivers/staging/comedi/drivers/adl_pci8164.c
@@ -89,9 +89,9 @@ static void adl_pci8164_insn_read(struct comedi_device *dev,
}
data[0] = inw(dev->iobase + axis_reg + offset);
- printk(KERN_DEBUG "comedi: pci8164 %s read -> "
- "%04X:%04X on axis %s\n",
- action, data[0], data[1], axisname);
+ dev_dbg(dev->class_dev,
+ "pci8164 %s read -> %04X:%04X on axis %s\n",
+ action, data[0], data[1], axisname);
}
static int adl_pci8164_insn_read_msts(struct comedi_device *dev,
@@ -170,9 +170,9 @@ static void adl_pci8164_insn_out(struct comedi_device *dev,
outw(data[0], dev->iobase + axis_reg + offset);
- printk(KERN_DEBUG "comedi: pci8164 %s write -> "
- "%04X:%04X on axis %s\n",
- action, data[0], data[1], axisname);
+ dev_dbg(dev->class_dev,
+ "pci8164 %s write -> %04X:%04X on axis %s\n",
+ action, data[0], data[1], axisname);
}
@@ -212,14 +212,13 @@ static int adl_pci8164_insn_write_buf1(struct comedi_device *dev,
return 2;
}
-static int adl_pci8164_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int adl_pci8164_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct comedi_subdevice *s;
int ret;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
dev->board_name = dev->driver->driver_name;
ret = comedi_pci_enable(pcidev, dev->board_name);
@@ -289,17 +288,17 @@ static void adl_pci8164_detach(struct comedi_device *dev)
static struct comedi_driver adl_pci8164_driver = {
.driver_name = "adl_pci8164",
.module = THIS_MODULE,
- .attach_pci = adl_pci8164_attach_pci,
+ .auto_attach = adl_pci8164_auto_attach,
.detach = adl_pci8164_detach,
};
-static int __devinit adl_pci8164_pci_probe(struct pci_dev *dev,
+static int adl_pci8164_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &adl_pci8164_driver);
}
-static void __devexit adl_pci8164_pci_remove(struct pci_dev *dev)
+static void adl_pci8164_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -314,7 +313,7 @@ static struct pci_driver adl_pci8164_pci_driver = {
.name = "adl_pci8164",
.id_table = adl_pci8164_pci_table,
.probe = adl_pci8164_pci_probe,
- .remove = __devexit_p(adl_pci8164_pci_remove),
+ .remove = adl_pci8164_pci_remove,
};
module_comedi_pci_driver(adl_pci8164_driver, adl_pci8164_pci_driver);
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
index a87192ac284..a339b9dd27c 100644
--- a/drivers/staging/comedi/drivers/adl_pci9111.c
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -366,52 +366,29 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev,
if (error)
return 2;
- /* Step 3 : make sure arguments are trivialy compatible */
+ /* Step 3: check if arguments are trivially valid */
- if ((cmd->start_src == TRIG_NOW) && (cmd->start_arg != 0)) {
- cmd->start_arg = 0;
- error++;
- }
+ error |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if ((cmd->convert_src == TRIG_TIMER) &&
- (cmd->convert_arg < PCI9111_AI_ACQUISITION_PERIOD_MIN_NS)) {
- cmd->convert_arg = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS;
- error++;
- }
- if ((cmd->convert_src == TRIG_EXT) && (cmd->convert_arg != 0)) {
- cmd->convert_arg = 0;
- error++;
- }
+ if (cmd->convert_src == TRIG_TIMER)
+ error |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ PCI9111_AI_ACQUISITION_PERIOD_MIN_NS);
+ else /* TRIG_EXT */
+ error |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- if ((cmd->scan_begin_src == TRIG_TIMER) &&
- (cmd->scan_begin_arg < PCI9111_AI_ACQUISITION_PERIOD_MIN_NS)) {
- cmd->scan_begin_arg = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS;
- error++;
- }
- if ((cmd->scan_begin_src == TRIG_FOLLOW)
- && (cmd->scan_begin_arg != 0)) {
- cmd->scan_begin_arg = 0;
- error++;
- }
- if ((cmd->scan_begin_src == TRIG_EXT) && (cmd->scan_begin_arg != 0)) {
- cmd->scan_begin_arg = 0;
- error++;
- }
+ if (cmd->scan_begin_src == TRIG_TIMER)
+ error |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ PCI9111_AI_ACQUISITION_PERIOD_MIN_NS);
+ else /* TRIG_FOLLOW || TRIG_EXT */
+ error |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- if ((cmd->scan_end_src == TRIG_COUNT) &&
- (cmd->scan_end_arg != cmd->chanlist_len)) {
- cmd->scan_end_arg = cmd->chanlist_len;
- error++;
- }
+ error |= cfc_check_trigger_arg_is(&cmd->scan_end_arg,
+ cmd->chanlist_len);
- if ((cmd->stop_src == TRIG_COUNT) && (cmd->stop_arg < 1)) {
- cmd->stop_arg = 1;
- error++;
- }
- if ((cmd->stop_src == TRIG_NONE) && (cmd->stop_arg != 0)) {
- cmd->stop_arg = 0;
- error++;
- }
+ if (cmd->stop_src == TRIG_COUNT)
+ error |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
+ else /* TRIG_NONE */
+ error |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (error)
return 3;
@@ -879,20 +856,20 @@ static int pci9111_reset(struct comedi_device *dev)
return 0;
}
-static int pci9111_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int pci9111_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct pci9111_private_data *dev_private;
struct comedi_subdevice *s;
int ret;
- comedi_set_hw_dev(dev, &pcidev->dev);
dev->board_name = dev->driver->driver_name;
- ret = alloc_private(dev, sizeof(*dev_private));
- if (ret)
- return ret;
- dev_private = dev->private;
+ dev_private = kzalloc(sizeof(*dev_private), GFP_KERNEL);
+ if (!dev_private)
+ return -ENOMEM;
+ dev->private = dev_private;
ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret)
@@ -976,17 +953,17 @@ static void pci9111_detach(struct comedi_device *dev)
static struct comedi_driver adl_pci9111_driver = {
.driver_name = "adl_pci9111",
.module = THIS_MODULE,
- .attach_pci = pci9111_attach_pci,
+ .auto_attach = pci9111_auto_attach,
.detach = pci9111_detach,
};
-static int __devinit pci9111_pci_probe(struct pci_dev *dev,
+static int pci9111_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &adl_pci9111_driver);
}
-static void __devexit pci9111_pci_remove(struct pci_dev *dev)
+static void pci9111_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -1002,7 +979,7 @@ static struct pci_driver adl_pci9111_pci_driver = {
.name = "adl_pci9111",
.id_table = pci9111_pci_table,
.probe = pci9111_pci_probe,
- .remove = __devexit_p(pci9111_pci_remove),
+ .remove = pci9111_pci_remove,
};
module_comedi_pci_driver(adl_pci9111_driver, adl_pci9111_pci_driver);
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index 06ff65c85c9..b6dda809bd1 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -62,6 +62,20 @@ Configuration options:
256|=ignore nFull - A/D FIFO Full status
*/
+
+/*
+ * FIXME
+ *
+ * All the supported boards have the same PCI vendor and device IDs, so
+ * auto-attachment of PCI devices will always find the first board type.
+ *
+ * Perhaps the boards have different subdevice IDs that we could use to
+ * distinguish them?
+ *
+ * Need some device attributes so the board type can be corrected after
+ * attachment if necessary, and possibly to set other options supported by
+ * manual attachment.
+ */
#include "../comedidev.h"
#include <linux/delay.h>
@@ -73,8 +87,6 @@ Configuration options:
#include "8253.h"
#include "comedi_fc.h"
-#define PCI_VENDOR_ID_AMCC 0x10e8
-
/* paranoid checks are broken */
#undef PCI9118_PARANOIDCHECK /*
* if defined, then is used code which control
@@ -210,8 +222,7 @@ static const struct comedi_lrange range_pci9118hg = { 8, {
struct boardtype {
const char *name; /* board name */
- int vendor_id; /* PCI vendor a device ID of card */
- int device_id;
+ int device_id; /* PCI device ID of card */
int iorange_amcc; /* iorange for own S5933 region */
int iorange_9118; /* pass thru card region size */
int n_aichan; /* num of A/D chans */
@@ -235,6 +246,61 @@ struct boardtype {
};
+static const struct boardtype boardtypes[] = {
+ {
+ .name = "pci9118dg",
+ .device_id = 0x80d9,
+ .iorange_amcc = AMCC_OP_REG_SIZE,
+ .iorange_9118 = IORANGE_9118,
+ .n_aichan = 16,
+ .n_aichand = 8,
+ .mux_aichan = 256,
+ .n_aichanlist = PCI9118_CHANLEN,
+ .n_aochan = 2,
+ .ai_maxdata = 0x0fff,
+ .ao_maxdata = 0x0fff,
+ .rangelist_ai = &range_pci9118dg_hr,
+ .rangelist_ao = &range_bipolar10,
+ .ai_ns_min = 3000,
+ .ai_pacer_min = 12,
+ .half_fifo_size = 512,
+ }, {
+ .name = "pci9118hg",
+ .device_id = 0x80d9,
+ .iorange_amcc = AMCC_OP_REG_SIZE,
+ .iorange_9118 = IORANGE_9118,
+ .n_aichan = 16,
+ .n_aichand = 8,
+ .mux_aichan = 256,
+ .n_aichanlist = PCI9118_CHANLEN,
+ .n_aochan = 2,
+ .ai_maxdata = 0x0fff,
+ .ao_maxdata = 0x0fff,
+ .rangelist_ai = &range_pci9118hg,
+ .rangelist_ao = &range_bipolar10,
+ .ai_ns_min = 3000,
+ .ai_pacer_min = 12,
+ .half_fifo_size = 512,
+ }, {
+ .name = "pci9118hr",
+ .device_id = 0x80d9,
+ .iorange_amcc = AMCC_OP_REG_SIZE,
+ .iorange_9118 = IORANGE_9118,
+ .n_aichan = 16,
+ .n_aichand = 8,
+ .mux_aichan = 256,
+ .n_aichanlist = PCI9118_CHANLEN,
+ .n_aochan = 2,
+ .ai_maxdata = 0xffff,
+ .ao_maxdata = 0x0fff,
+ .rangelist_ai = &range_pci9118dg_hr,
+ .rangelist_ao = &range_bipolar10,
+ .ai_ns_min = 10000,
+ .ai_pacer_min = 40,
+ .half_fifo_size = 512,
+ },
+};
+
struct pci9118_private {
unsigned long iobase_a; /* base+size for AMCC chip */
unsigned int master; /* master capable */
@@ -358,10 +424,8 @@ static int check_channel_list(struct comedi_device *dev,
return 0;
}
if ((frontadd + n_chan + backadd) > s->len_chanlist) {
- printk
- ("comedi%d: range/channel list is too long for "
- "actual configuration (%d>%d)!",
- dev->minor, n_chan, s->len_chanlist - frontadd - backadd);
+ comedi_error(dev,
+ "range/channel list is too long for actual configuration!\n");
return 0;
}
@@ -892,11 +956,10 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
if (devpriv->ai16bits == 0) {
if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) {
/* data dropout! */
- printk
- ("comedi: A/D SAMPL - data dropout: "
- "received channel %d, expected %d!\n",
- sampl & 0x000f,
- devpriv->chanlist[s->async->cur_chan]);
+ dev_info(dev->class_dev,
+ "A/D SAMPL - data dropout: received channel %d, expected %d!\n",
+ sampl & 0x000f,
+ devpriv->chanlist[s->async->cur_chan]);
s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
pci9118_ai_cancel(dev, s);
comedi_event(dev, s);
@@ -1153,19 +1216,13 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
if (cmd->start_src & (TRIG_NOW | TRIG_EXT))
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
if ((cmd->scan_begin_src == TRIG_TIMER) &&
(cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
@@ -1175,64 +1232,40 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev,
}
if (cmd->scan_begin_src == TRIG_TIMER)
- if (cmd->scan_begin_arg < this_board->ai_ns_min) {
- cmd->scan_begin_arg = this_board->ai_ns_min;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ this_board->ai_ns_min);
if (cmd->scan_begin_src == TRIG_EXT)
if (cmd->scan_begin_arg) {
cmd->scan_begin_arg = 0;
- err++;
- if (cmd->scan_end_arg > 65535) {
- cmd->scan_end_arg = 65535;
- err++;
- }
+ err |= -EINVAL;
+ err |= cfc_check_trigger_arg_max(&cmd->scan_end_arg,
+ 65535);
}
if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW))
- if (cmd->convert_arg < this_board->ai_ns_min) {
- cmd->convert_arg = this_board->ai_ns_min;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ this_board->ai_ns_min);
if (cmd->convert_src == TRIG_EXT)
- if (cmd->convert_arg) {
- cmd->convert_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- if (cmd->stop_src == TRIG_COUNT) {
- if (!cmd->stop_arg) {
- cmd->stop_arg = 1;
- err++;
- }
- } else { /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
- if (!cmd->chanlist_len) {
- cmd->chanlist_len = 1;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
+ err |= cfc_check_trigger_arg_max(&cmd->chanlist_len,
+ this_board->n_aichanlist);
- if (cmd->chanlist_len > this_board->n_aichanlist) {
- cmd->chanlist_len = this_board->n_aichanlist;
- err++;
- }
-
- if (cmd->scan_end_arg < cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_end_arg,
+ cmd->chanlist_len);
if ((cmd->scan_end_arg % cmd->chanlist_len)) {
cmd->scan_end_arg =
cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len);
- err++;
+ err |= -EINVAL;
}
if (err)
@@ -1318,21 +1351,18 @@ static int Compute_and_setup_dma(struct comedi_device *dev)
if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) {
/* uff, too short DMA buffer, disable EOS support! */
devpriv->ai_flags &= (~TRIG_WAKE_EOS);
- printk
- ("comedi%d: WAR: DMA0 buf too short, can't "
- "support TRIG_WAKE_EOS (%d<%d)\n",
- dev->minor, dmalen0,
- devpriv->ai_n_realscanlen << 1);
+ dev_info(dev->class_dev,
+ "WAR: DMA0 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n",
+ dmalen0, devpriv->ai_n_realscanlen << 1);
} else {
/* short first DMA buffer to one scan */
dmalen0 = devpriv->ai_n_realscanlen << 1;
if (devpriv->useeoshandle)
dmalen0 += 2;
if (dmalen0 < 4) {
- printk
- ("comedi%d: ERR: DMA0 buf len bug? "
- "(%d<4)\n",
- dev->minor, dmalen0);
+ dev_info(dev->class_dev,
+ "ERR: DMA0 buf len bug? (%d<4)\n",
+ dmalen0);
dmalen0 = 4;
}
}
@@ -1341,21 +1371,18 @@ static int Compute_and_setup_dma(struct comedi_device *dev)
if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) {
/* uff, too short DMA buffer, disable EOS support! */
devpriv->ai_flags &= (~TRIG_WAKE_EOS);
- printk
- ("comedi%d: WAR: DMA1 buf too short, "
- "can't support TRIG_WAKE_EOS (%d<%d)\n",
- dev->minor, dmalen1,
- devpriv->ai_n_realscanlen << 1);
+ dev_info(dev->class_dev,
+ "WAR: DMA1 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n",
+ dmalen1, devpriv->ai_n_realscanlen << 1);
} else {
/* short second DMA buffer to one scan */
dmalen1 = devpriv->ai_n_realscanlen << 1;
if (devpriv->useeoshandle)
dmalen1 -= 2;
if (dmalen1 < 4) {
- printk
- ("comedi%d: ERR: DMA1 buf len bug? "
- "(%d<4)\n",
- dev->minor, dmalen1);
+ dev_info(dev->class_dev,
+ "ERR: DMA1 buf len bug? (%d<4)\n",
+ dmalen1);
dmalen1 = 4;
}
}
@@ -1865,6 +1892,20 @@ static int pci9118_reset(struct comedi_device *dev)
return 0;
}
+/*
+ * FIXME - this is pretty ineffective because all the supported board types
+ * have the same device ID!
+ */
+static const struct boardtype *pci9118_find_boardinfo(struct pci_dev *pcidev)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(boardtypes); i++)
+ if (pcidev->device == boardtypes[i].device_id)
+ return &boardtypes[i];
+ return NULL;
+}
+
static struct pci_dev *pci9118_find_pci(struct comedi_device *dev,
struct comedi_devconfig *it)
{
@@ -1884,85 +1925,63 @@ static struct pci_dev *pci9118_find_pci(struct comedi_device *dev,
PCI_SLOT(pcidev->devfn) != slot)
continue;
}
- /*
- * Look for device that isn't in use.
- * Enable PCI device and request regions.
- */
- if (comedi_pci_enable(pcidev, "adl_pci9118"))
- continue;
- printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx",
- pcidev->bus->number,
- PCI_SLOT(pcidev->devfn),
- PCI_FUNC(pcidev->devfn),
- (unsigned long)pci_resource_start(pcidev, 2),
- (unsigned long)pci_resource_start(pcidev, 0));
return pcidev;
}
- printk(KERN_ERR
- "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
- dev->minor, bus, slot);
+ dev_err(dev->class_dev,
+ "no supported board found! (req. bus/slot : %d/%d)\n",
+ bus, slot);
return NULL;
}
-static int pci9118_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
+static void pci9118_report_attach(struct comedi_device *dev, unsigned int irq)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct pci9118_private *devpriv = dev->private;
+ char irqbuf[30];
+ char muxbuf[30];
+
+ if (irq)
+ snprintf(irqbuf, sizeof(irqbuf), "irq %u%s", irq,
+ (dev->irq ? "" : " UNAVAILABLE"));
+ else
+ snprintf(irqbuf, sizeof(irqbuf), "irq DISABLED");
+ if (devpriv->usemux)
+ snprintf(muxbuf, sizeof(muxbuf), "ext mux %u chans",
+ devpriv->usemux);
+ else
+ snprintf(muxbuf, sizeof(muxbuf), "no ext mux");
+ dev_info(dev->class_dev, "%s (pci %s, %s, %sbus master, %s) attached\n",
+ dev->board_name, pci_name(pcidev), irqbuf,
+ (devpriv->master ? "" : "no "), muxbuf);
+}
+
+static int pci9118_common_attach(struct comedi_device *dev, int disable_irq,
+ int master, int ext_mux, int softsshdelay,
+ int hw_err_mask)
{
const struct boardtype *this_board = comedi_board(dev);
- struct pci9118_private *devpriv;
- struct pci_dev *pcidev;
+ struct pci9118_private *devpriv = dev->private;
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct comedi_subdevice *s;
int ret, pages, i;
- unsigned short master;
unsigned int irq;
u16 u16w;
- printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name);
-
- if (it->options[3] & 1)
- master = 0; /* user don't want use bus master */
- else
- master = 1;
-
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret < 0) {
- printk(" - Allocation failed!\n");
- return -ENOMEM;
+ dev->board_name = this_board->name;
+ ret = comedi_pci_enable(pcidev, dev->board_name);
+ if (ret) {
+ dev_err(dev->class_dev,
+ "cannot enable PCI device %s\n", pci_name(pcidev));
+ return ret;
}
- devpriv = dev->private;
-
- pcidev = pci9118_find_pci(dev, it);
- if (!pcidev)
- return -EIO;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
if (master)
pci_set_master(pcidev);
- irq = pcidev->irq;
devpriv->iobase_a = pci_resource_start(pcidev, 0);
dev->iobase = pci_resource_start(pcidev, 2);
- dev->board_name = this_board->name;
-
pci9118_reset(dev);
- if (it->options[3] & 2)
- irq = 0; /* user don't want use IRQ */
- if (irq > 0) {
- if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
- "ADLink PCI-9118", dev)) {
- printk(", unable to allocate IRQ %d, DISABLING IT",
- irq);
- irq = 0; /* Can't use IRQ */
- } else {
- printk(", irq=%u", irq);
- }
- } else {
- printk(", IRQ disabled");
- }
-
- dev->irq = irq;
-
if (master) { /* alloc DMA buffers */
devpriv->dma_doublebuf = 0;
for (i = 0; i < 2; i++) {
@@ -1984,47 +2003,37 @@ static int pci9118_attach(struct comedi_device *dev,
}
}
if (!devpriv->dmabuf_virt[0]) {
- printk(", Can't allocate DMA buffer, DMA disabled!");
+ dev_warn(dev->class_dev,
+ "Can't allocate DMA buffer, DMA disabled!\n");
master = 0;
}
-
if (devpriv->dmabuf_virt[1])
devpriv->dma_doublebuf = 1;
-
}
-
devpriv->master = master;
- if (devpriv->master)
- printk(", bus master");
- else
- printk(", no bus master");
-
- devpriv->usemux = 0;
- if (it->options[2] > 0) {
- devpriv->usemux = it->options[2];
- if (devpriv->usemux > 256)
- devpriv->usemux = 256; /* max 256 channels! */
- if (it->options[4] > 0)
- if (devpriv->usemux > 128) {
- devpriv->usemux = 128;
- /* max 128 channels with softare S&H! */
- }
- printk(", ext. mux %d channels", devpriv->usemux);
+
+ if (ext_mux > 0) {
+ if (ext_mux > 256)
+ ext_mux = 256; /* max 256 channels! */
+ if (softsshdelay > 0)
+ if (ext_mux > 128)
+ ext_mux = 128;
+ devpriv->usemux = ext_mux;
+ } else {
+ devpriv->usemux = 0;
}
- devpriv->softsshdelay = it->options[4];
- if (devpriv->softsshdelay < 0) {
- /* select sample&hold signal polarity */
- devpriv->softsshdelay = -devpriv->softsshdelay;
+ if (softsshdelay < 0) {
+ /* select sample&hold signal polarity */
+ devpriv->softsshdelay = -softsshdelay;
devpriv->softsshsample = 0x80;
devpriv->softsshhold = 0x00;
} else {
+ devpriv->softsshdelay = softsshdelay;
devpriv->softsshsample = 0x00;
devpriv->softsshhold = 0x80;
}
- printk(".\n");
-
pci_read_config_word(pcidev, PCI_COMMAND, &u16w);
pci_write_config_word(pcidev, PCI_COMMAND, u16w | 64);
/* Enable parity check for parity error */
@@ -2047,12 +2056,7 @@ static int pci9118_attach(struct comedi_device *dev,
s->range_table = this_board->rangelist_ai;
s->cancel = pci9118_ai_cancel;
s->insn_read = pci9118_insn_read_ai;
- if (dev->irq) {
- s->subdev_flags |= SDF_CMD_READ;
- s->do_cmdtest = pci9118_ai_cmdtest;
- s->do_cmd = pci9118_ai_cmd;
- s->munge = pci9118_ai_munge;
- }
+ s->munge = pci9118_ai_munge;
s = &dev->subdevices[1];
s->type = COMEDI_SUBD_AO;
@@ -2088,8 +2092,8 @@ static int pci9118_attach(struct comedi_device *dev,
devpriv->i8254_osc_base = 250; /* 250ns=4MHz */
devpriv->ai_maskharderr = 0x10a;
/* default measure crash condition */
- if (it->options[5]) /* disable some requested */
- devpriv->ai_maskharderr &= ~it->options[5];
+ if (hw_err_mask) /* disable some requested */
+ devpriv->ai_maskharderr &= ~hw_err_mask;
switch (this_board->ai_maxdata) {
case 0xffff:
@@ -2099,9 +2103,86 @@ static int pci9118_attach(struct comedi_device *dev,
devpriv->ai16bits = 0;
break;
}
+
+ if (disable_irq)
+ irq = 0;
+ else
+ irq = pcidev->irq;
+ if (irq > 0) {
+ if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
+ dev->board_name, dev)) {
+ dev_warn(dev->class_dev,
+ "unable to allocate IRQ %u, DISABLING IT\n",
+ irq);
+ } else {
+ dev->irq = irq;
+ /* Enable AI commands */
+ s = &dev->subdevices[0];
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmdtest = pci9118_ai_cmdtest;
+ s->do_cmd = pci9118_ai_cmd;
+ }
+ }
+
+ pci9118_report_attach(dev, irq);
return 0;
}
+static int pci9118_attach(struct comedi_device *dev,
+ struct comedi_devconfig *it)
+{
+ struct pci9118_private *devpriv;
+ struct pci_dev *pcidev;
+ int ext_mux, disable_irq, master, softsshdelay, hw_err_mask;
+
+ ext_mux = it->options[2];
+ master = ((it->options[3] & 1) == 0);
+ disable_irq = ((it->options[3] & 2) != 0);
+ softsshdelay = it->options[4];
+ hw_err_mask = it->options[5];
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
+ pcidev = pci9118_find_pci(dev, it);
+ if (!pcidev)
+ return -EIO;
+ comedi_set_hw_dev(dev, &pcidev->dev);
+
+ return pci9118_common_attach(dev, disable_irq, master, ext_mux,
+ softsshdelay, hw_err_mask);
+}
+
+static int pci9118_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct pci9118_private *devpriv;
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
+ dev->board_ptr = pci9118_find_boardinfo(pcidev);
+ if (dev->board_ptr == NULL) {
+ dev_err(dev->class_dev,
+ "adl_pci9118: cannot determine board type for pci %s\n",
+ pci_name(pcidev));
+ return -EINVAL;
+ }
+ /*
+ * Need to 'get' the PCI device to match the 'put' in pci9118_detach().
+ * (The 'put' also matches the implicit 'get' by pci9118_find_pci().)
+ */
+ pci_dev_get(pcidev);
+ /* Don't disable irq, use bus master, no external mux,
+ * no sample-hold delay, no error mask. */
+ return pci9118_common_attach(dev, 0, 1, 0, 0, 0);
+}
+
static void pci9118_detach(struct comedi_device *dev)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
@@ -2127,81 +2208,24 @@ static void pci9118_detach(struct comedi_device *dev)
}
}
-static const struct boardtype boardtypes[] = {
- {
- .name = "pci9118dg",
- .vendor_id = PCI_VENDOR_ID_AMCC,
- .device_id = 0x80d9,
- .iorange_amcc = AMCC_OP_REG_SIZE,
- .iorange_9118 = IORANGE_9118,
- .n_aichan = 16,
- .n_aichand = 8,
- .mux_aichan = 256,
- .n_aichanlist = PCI9118_CHANLEN,
- .n_aochan = 2,
- .ai_maxdata = 0x0fff,
- .ao_maxdata = 0x0fff,
- .rangelist_ai = &range_pci9118dg_hr,
- .rangelist_ao = &range_bipolar10,
- .ai_ns_min = 3000,
- .ai_pacer_min = 12,
- .half_fifo_size = 512,
- }, {
- .name = "pci9118hg",
- .vendor_id = PCI_VENDOR_ID_AMCC,
- .device_id = 0x80d9,
- .iorange_amcc = AMCC_OP_REG_SIZE,
- .iorange_9118 = IORANGE_9118,
- .n_aichan = 16,
- .n_aichand = 8,
- .mux_aichan = 256,
- .n_aichanlist = PCI9118_CHANLEN,
- .n_aochan = 2,
- .ai_maxdata = 0x0fff,
- .ao_maxdata = 0x0fff,
- .rangelist_ai = &range_pci9118hg,
- .rangelist_ao = &range_bipolar10,
- .ai_ns_min = 3000,
- .ai_pacer_min = 12,
- .half_fifo_size = 512,
- }, {
- .name = "pci9118hr",
- .vendor_id = PCI_VENDOR_ID_AMCC,
- .device_id = 0x80d9,
- .iorange_amcc = AMCC_OP_REG_SIZE,
- .iorange_9118 = IORANGE_9118,
- .n_aichan = 16,
- .n_aichand = 8,
- .mux_aichan = 256,
- .n_aichanlist = PCI9118_CHANLEN,
- .n_aochan = 2,
- .ai_maxdata = 0xffff,
- .ao_maxdata = 0x0fff,
- .rangelist_ai = &range_pci9118dg_hr,
- .rangelist_ao = &range_bipolar10,
- .ai_ns_min = 10000,
- .ai_pacer_min = 40,
- .half_fifo_size = 512,
- },
-};
-
static struct comedi_driver adl_pci9118_driver = {
.driver_name = "adl_pci9118",
.module = THIS_MODULE,
.attach = pci9118_attach,
+ .auto_attach = pci9118_auto_attach,
.detach = pci9118_detach,
.num_names = ARRAY_SIZE(boardtypes),
.board_name = &boardtypes[0].name,
.offset = sizeof(struct boardtype),
};
-static int __devinit adl_pci9118_pci_probe(struct pci_dev *dev,
+static int adl_pci9118_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &adl_pci9118_driver);
}
-static void __devexit adl_pci9118_pci_remove(struct pci_dev *dev)
+static void adl_pci9118_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -2216,7 +2240,7 @@ static struct pci_driver adl_pci9118_pci_driver = {
.name = "adl_pci9118",
.id_table = adl_pci9118_pci_table,
.probe = adl_pci9118_pci_probe,
- .remove = __devexit_p(adl_pci9118_pci_remove),
+ .remove = adl_pci9118_pci_remove,
};
module_comedi_pci_driver(adl_pci9118_driver, adl_pci9118_pci_driver);
diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c
index 3a2aa5628be..f7950dfe2dd 100644
--- a/drivers/staging/comedi/drivers/adq12b.c
+++ b/drivers/staging/comedi/drivers/adq12b.c
@@ -116,15 +116,6 @@ static const struct comedi_lrange range_adq12b_ai_unipolar = { 4, {
}
};
-struct adq12b_board {
- const char *name;
- int ai_se_chans;
- int ai_diff_chans;
- int ai_bits;
- int di_chans;
- int do_chans;
-};
-
struct adq12b_private {
int unipolar; /* option 2 of comedi_config (1 is iobase) */
int differential; /* option 3 of comedi_config */
@@ -220,13 +211,14 @@ static int adq12b_do_insn_bits(struct comedi_device *dev,
static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- const struct adq12b_board *board = comedi_board(dev);
struct adq12b_private *devpriv;
struct comedi_subdevice *s;
unsigned long iobase;
int unipolar, differential;
int ret;
+ dev->board_name = dev->driver->driver_name;
+
iobase = it->options[0];
unipolar = it->options[1];
differential = it->options[2];
@@ -251,12 +243,10 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
dev->iobase = iobase;
- dev->board_name = board->name;
-
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
devpriv->unipolar = unipolar;
devpriv->differential = differential;
@@ -277,10 +267,10 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->type = COMEDI_SUBD_AI;
if (differential) {
s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
- s->n_chan = board->ai_diff_chans;
+ s->n_chan = 8;
} else {
s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = board->ai_se_chans;
+ s->n_chan = 16;
}
if (unipolar)
@@ -288,7 +278,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
else
s->range_table = &range_adq12b_ai_bipolar;
- s->maxdata = (1 << board->ai_bits) - 1;
+ s->maxdata = 0xfff;
s->len_chanlist = 4; /* This is the maximum chanlist length that
the board can handle */
@@ -298,7 +288,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
/* digital input subdevice */
s->type = COMEDI_SUBD_DI;
s->subdev_flags = SDF_READABLE;
- s->n_chan = board->di_chans;
+ s->n_chan = 5;
s->maxdata = 1;
s->range_table = &range_digital;
s->insn_bits = adq12b_di_insn_bits;
@@ -307,7 +297,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
/* digital output subdevice */
s->type = COMEDI_SUBD_DO;
s->subdev_flags = SDF_WRITABLE;
- s->n_chan = board->do_chans;
+ s->n_chan = 8;
s->maxdata = 1;
s->range_table = &range_digital;
s->insn_bits = adq12b_do_insn_bits;
@@ -323,25 +313,11 @@ static void adq12b_detach(struct comedi_device *dev)
release_region(dev->iobase, ADQ12B_SIZE);
}
-static const struct adq12b_board adq12b_boards[] = {
- {
- .name = "adq12b",
- .ai_se_chans = 16,
- .ai_diff_chans = 8,
- .ai_bits = 12,
- .di_chans = 5,
- .do_chans = 8,
- },
-};
-
static struct comedi_driver adq12b_driver = {
.driver_name = "adq12b",
.module = THIS_MODULE,
.attach = adq12b_attach,
.detach = adq12b_detach,
- .board_name = &adq12b_boards[0].name,
- .offset = sizeof(struct adq12b_board),
- .num_names = ARRAY_SIZE(adq12b_boards),
};
module_comedi_driver(adq12b_driver);
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
index def37bcc2a6..a6fd8c2c16c 100644
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -53,8 +53,6 @@ Configuration options:
* correct channel number on every 12 bit
* sample */
-#define PCI_VENDOR_ID_ADVANTECH 0x13fe
-
/* hardware types of the cards */
#define TYPE_PCI171X 0
#define TYPE_PCI1713 2
@@ -1068,45 +1066,23 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ this_board->ai_ns_min);
+ else /* TRIG_FOLLOW */
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < this_board->ai_ns_min) {
- cmd->convert_arg = this_board->ai_ns_min;
- err++;
- }
- } else { /* TRIG_FOLLOW */
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) {
- if (!cmd->stop_arg) {
- cmd->stop_arg = 1;
- err++;
- }
- } else { /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -1257,26 +1233,25 @@ static const void *pci1710_find_boardinfo(struct comedi_device *dev,
return NULL;
}
-static int pci1710_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int pci1710_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct boardtype *this_board;
struct pci1710_private *devpriv;
struct comedi_subdevice *s;
int ret, subdev, n_subdevices;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
this_board = pci1710_find_boardinfo(dev, pcidev);
if (!this_board)
return -ENODEV;
dev->board_ptr = this_board;
dev->board_name = this_board->name;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret < 0)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret)
@@ -1417,17 +1392,17 @@ static void pci1710_detach(struct comedi_device *dev)
static struct comedi_driver adv_pci1710_driver = {
.driver_name = "adv_pci1710",
.module = THIS_MODULE,
- .attach_pci = pci1710_attach_pci,
+ .auto_attach = pci1710_auto_attach,
.detach = pci1710_detach,
};
-static int __devinit adv_pci1710_pci_probe(struct pci_dev *dev,
+static int adv_pci1710_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &adv_pci1710_driver);
}
-static void __devexit adv_pci1710_pci_remove(struct pci_dev *dev)
+static void adv_pci1710_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -1446,7 +1421,7 @@ static struct pci_driver adv_pci1710_pci_driver = {
.name = "adv_pci1710",
.id_table = adv_pci1710_pci_table,
.probe = adv_pci1710_pci_probe,
- .remove = __devexit_p(adv_pci1710_pci_remove),
+ .remove = adv_pci1710_pci_remove,
};
module_comedi_pci_driver(adv_pci1710_driver, adv_pci1710_pci_driver);
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c
index df4efc0606d..5af73146dd8 100644
--- a/drivers/staging/comedi/drivers/adv_pci1723.c
+++ b/drivers/staging/comedi/drivers/adv_pci1723.c
@@ -50,8 +50,6 @@ TODO:
#include "../comedidev.h"
-#define PCI_VENDOR_ID_ADVANTECH 0x13fe /* Advantech PCI vendor ID */
-
/* all the registers for the pci1723 board */
#define PCI1723_DA(N) ((N)<<1) /* W: D/A register N (0 to 7) */
@@ -234,20 +232,20 @@ static int pci1723_dio_insn_bits(struct comedi_device *dev,
return insn->n;
}
-static int pci1723_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int pci1723_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct pci1723_private *devpriv;
struct comedi_subdevice *s;
int ret;
- comedi_set_hw_dev(dev, &pcidev->dev);
dev->board_name = dev->driver->driver_name;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret < 0)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret)
@@ -319,17 +317,17 @@ static void pci1723_detach(struct comedi_device *dev)
static struct comedi_driver adv_pci1723_driver = {
.driver_name = "adv_pci1723",
.module = THIS_MODULE,
- .attach_pci = pci1723_attach_pci,
+ .auto_attach = pci1723_auto_attach,
.detach = pci1723_detach,
};
-static int __devinit adv_pci1723_pci_probe(struct pci_dev *dev,
+static int adv_pci1723_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &adv_pci1723_driver);
}
-static void __devexit adv_pci1723_pci_remove(struct pci_dev *dev)
+static void adv_pci1723_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -344,7 +342,7 @@ static struct pci_driver adv_pci1723_pci_driver = {
.name = "adv_pci1723",
.id_table = adv_pci1723_pci_table,
.probe = adv_pci1723_pci_probe,
- .remove = __devexit_p(adv_pci1723_pci_remove),
+ .remove = adv_pci1723_pci_remove,
};
module_comedi_pci_driver(adv_pci1723_driver, adv_pci1723_pci_driver);
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c
index a3c22419cd5..05a663e970c 100644
--- a/drivers/staging/comedi/drivers/adv_pci_dio.c
+++ b/drivers/staging/comedi/drivers/adv_pci_dio.c
@@ -36,8 +36,6 @@ Configuration options:
#include "8255.h"
#include "8253.h"
-#define PCI_VENDOR_ID_ADVANTECH 0x13fe
-
/* hardware types of the cards */
enum hw_cards_id {
TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1735, TYPE_PCI1736,
@@ -1092,26 +1090,25 @@ static const void *pci_dio_find_boardinfo(struct comedi_device *dev,
return NULL;
}
-static int pci_dio_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int pci_dio_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct dio_boardtype *this_board;
struct pci_dio_private *devpriv;
struct comedi_subdevice *s;
int ret, subdev, i, j;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
this_board = pci_dio_find_boardinfo(dev, pcidev);
if (!this_board)
return -ENODEV;
dev->board_ptr = this_board;
dev->board_name = this_board->name;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret < 0)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret)
@@ -1199,17 +1196,17 @@ static void pci_dio_detach(struct comedi_device *dev)
static struct comedi_driver adv_pci_dio_driver = {
.driver_name = "adv_pci_dio",
.module = THIS_MODULE,
- .attach_pci = pci_dio_attach_pci,
+ .auto_attach = pci_dio_auto_attach,
.detach = pci_dio_detach,
};
-static int __devinit adv_pci_dio_pci_probe(struct pci_dev *dev,
+static int adv_pci_dio_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &adv_pci_dio_driver);
}
-static void __devexit adv_pci_dio_pci_remove(struct pci_dev *dev)
+static void adv_pci_dio_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -1237,7 +1234,7 @@ static struct pci_driver adv_pci_dio_pci_driver = {
.name = "adv_pci_dio",
.id_table = adv_pci_dio_pci_table,
.probe = adv_pci_dio_pci_probe,
- .remove = __devexit_p(adv_pci_dio_pci_remove),
+ .remove = adv_pci_dio_pci_remove,
};
module_comedi_pci_driver(adv_pci_dio_driver, adv_pci_dio_pci_driver);
diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c
index 8acf60d0f20..601f03d5897 100644
--- a/drivers/staging/comedi/drivers/aio_aio12_8.c
+++ b/drivers/staging/comedi/drivers/aio_aio12_8.c
@@ -212,10 +212,10 @@ static int aio_aio12_8_attach(struct comedi_device *dev,
}
dev->iobase = iobase;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_alloc_subdevices(dev, 4);
if (ret)
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c
index b2cb8b02b2a..64c1ae58ce7 100644
--- a/drivers/staging/comedi/drivers/aio_iiro_16.c
+++ b/drivers/staging/comedi/drivers/aio_iiro_16.c
@@ -44,19 +44,6 @@ Configuration Options:
#define AIO_IIRO_16_RELAY_8_15 0x04
#define AIO_IIRO_16_INPUT_8_15 0x05
-struct aio_iiro_16_board {
- const char *name;
- int do_;
- int di;
-};
-
-static const struct aio_iiro_16_board aio_iiro_16_boards[] = {
- {
- .name = "aio_iiro_16",
- .di = 16,
- .do_ = 16},
-};
-
static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
@@ -90,14 +77,13 @@ static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev,
static int aio_iiro_16_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
- const struct aio_iiro_16_board *board = comedi_board(dev);
int iobase;
struct comedi_subdevice *s;
int ret;
printk(KERN_INFO "comedi%d: aio_iiro_16: ", dev->minor);
- dev->board_name = board->name;
+ dev->board_name = dev->driver->driver_name;
iobase = it->options[0];
@@ -144,9 +130,6 @@ static struct comedi_driver aio_iiro_16_driver = {
.module = THIS_MODULE,
.attach = aio_iiro_16_attach,
.detach = aio_iiro_16_detach,
- .board_name = &aio_iiro_16_boards[0].name,
- .offset = sizeof(struct aio_iiro_16_board),
- .num_names = ARRAY_SIZE(aio_iiro_16_boards),
};
module_comedi_driver(aio_iiro_16_driver);
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
index 29eb52d11d2..5f309ba88a1 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -25,185 +25,238 @@
*/
/*
-Driver: amplc_dio200
-Description: Amplicon 200 Series Digital I/O
-Author: Ian Abbott <abbotti@mev.co.uk>
-Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e),
- PCI215 (pci215 or amplc_dio200), PC218E (pc218e), PC272E (pc272e),
- PCI272 (pci272 or amplc_dio200)
-Updated: Wed, 22 Oct 2008 13:36:02 +0100
-Status: works
-
-Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E:
- [0] - I/O port base address
- [1] - IRQ (optional, but commands won't work without it)
-
-Configuration options - PCI215, PCI272:
- [0] - PCI bus of device (optional)
- [1] - PCI slot of device (optional)
- If bus/slot is not specified, the first available PCI device will
- be used.
-
-Passing a zero for an option is the same as leaving it unspecified.
-
-SUBDEVICES
-
- PC218E PC212E PC215E/PCI215
- ------------- ------------- -------------
- Subdevices 7 6 5
- 0 CTR-X1 PPI-X PPI-X
- 1 CTR-X2 CTR-Y1 PPI-Y
- 2 CTR-Y1 CTR-Y2 CTR-Z1
- 3 CTR-Y2 CTR-Z1 CTR-Z2
- 4 CTR-Z1 CTR-Z2 INTERRUPT
- 5 CTR-Z2 INTERRUPT
- 6 INTERRUPT
-
- PC214E PC272E/PCI272
- ------------- -------------
- Subdevices 4 4
- 0 PPI-X PPI-X
- 1 PPI-Y PPI-Y
- 2 CTR-Z1* PPI-Z
- 3 INTERRUPT* INTERRUPT
-
-Each PPI is a 8255 chip providing 24 DIO channels. The DIO channels
-are configurable as inputs or outputs in four groups:
-
- Port A - channels 0 to 7
- Port B - channels 8 to 15
- Port CL - channels 16 to 19
- Port CH - channels 20 to 23
-
-Only mode 0 of the 8255 chips is supported.
-
-Each CTR is a 8254 chip providing 3 16-bit counter channels. Each
-channel is configured individually with INSN_CONFIG instructions. The
-specific type of configuration instruction is specified in data[0].
-Some configuration instructions expect an additional parameter in
-data[1]; others return a value in data[1]. The following configuration
-instructions are supported:
-
- INSN_CONFIG_SET_COUNTER_MODE. Sets the counter channel's mode and
- BCD/binary setting specified in data[1].
-
- INSN_CONFIG_8254_READ_STATUS. Reads the status register value for the
- counter channel into data[1].
-
- INSN_CONFIG_SET_CLOCK_SRC. Sets the counter channel's clock source as
- specified in data[1] (this is a hardware-specific value). Not
- supported on PC214E. For the other boards, valid clock sources are
- 0 to 7 as follows:
-
- 0. CLK n, the counter channel's dedicated CLK input from the SK1
- connector. (N.B. for other values, the counter channel's CLKn
- pin on the SK1 connector is an output!)
- 1. Internal 10 MHz clock.
- 2. Internal 1 MHz clock.
- 3. Internal 100 kHz clock.
- 4. Internal 10 kHz clock.
- 5. Internal 1 kHz clock.
- 6. OUT n-1, the output of counter channel n-1 (see note 1 below).
- 7. Ext Clock, the counter chip's dedicated Ext Clock input from
- the SK1 connector. This pin is shared by all three counter
- channels on the chip.
-
- INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
- clock source in data[1]. For internal clock sources, data[2] is set
- to the period in ns.
-
- INSN_CONFIG_SET_GATE_SRC. Sets the counter channel's gate source as
- specified in data[2] (this is a hardware-specific value). Not
- supported on PC214E. For the other boards, valid gate sources are 0
- to 7 as follows:
-
- 0. VCC (internal +5V d.c.), i.e. gate permanently enabled.
- 1. GND (internal 0V d.c.), i.e. gate permanently disabled.
- 2. GAT n, the counter channel's dedicated GAT input from the SK1
- connector. (N.B. for other values, the counter channel's GATn
- pin on the SK1 connector is an output!)
- 3. /OUT n-2, the inverted output of counter channel n-2 (see note
- 2 below).
- 4. Reserved.
- 5. Reserved.
- 6. Reserved.
- 7. Reserved.
-
- INSN_CONFIG_GET_GATE_SRC. Returns the counter channel's current gate
- source in data[2].
-
-Clock and gate interconnection notes:
-
- 1. Clock source OUT n-1 is the output of the preceding channel on the
- same counter subdevice if n > 0, or the output of channel 2 on the
- preceding counter subdevice (see note 3) if n = 0.
-
- 2. Gate source /OUT n-2 is the inverted output of channel 0 on the
- same counter subdevice if n = 2, or the inverted output of channel n+1
- on the preceding counter subdevice (see note 3) if n < 2.
-
- 3. The counter subdevices are connected in a ring, so the highest
- counter subdevice precedes the lowest.
-
-The 'INTERRUPT' subdevice pretends to be a digital input subdevice. The
-digital inputs come from the interrupt status register. The number of
-channels matches the number of interrupt sources. The PC214E does not
-have an interrupt status register; see notes on 'INTERRUPT SOURCES'
-below.
-
-INTERRUPT SOURCES
-
- PC218E PC212E PC215E/PCI215
- ------------- ------------- -------------
- Sources 6 6 6
- 0 CTR-X1-OUT PPI-X-C0 PPI-X-C0
- 1 CTR-X2-OUT PPI-X-C3 PPI-X-C3
- 2 CTR-Y1-OUT CTR-Y1-OUT PPI-Y-C0
- 3 CTR-Y2-OUT CTR-Y2-OUT PPI-Y-C3
- 4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT
- 5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT
-
- PC214E PC272E/PCI272
- ------------- -------------
- Sources 1 6
- 0 JUMPER-J5 PPI-X-C0
- 1 PPI-X-C3
- 2 PPI-Y-C0
- 3 PPI-Y-C3
- 4 PPI-Z-C0
- 5 PPI-Z-C3
-
-When an interrupt source is enabled in the interrupt source enable
-register, a rising edge on the source signal latches the corresponding
-bit to 1 in the interrupt status register.
-
-When the interrupt status register value as a whole (actually, just the
-6 least significant bits) goes from zero to non-zero, the board will
-generate an interrupt. For level-triggered hardware interrupts (PCI
-card), the interrupt will remain asserted until the interrupt status
-register is cleared to zero. For edge-triggered hardware interrupts
-(ISA card), no further interrupts will occur until the interrupt status
-register is cleared to zero. To clear a bit to zero in the interrupt
-status register, the corresponding interrupt source must be disabled
-in the interrupt source enable register (there is no separate interrupt
-clear register).
-
-The PC214E does not have an interrupt source enable register or an
-interrupt status register; its 'INTERRUPT' subdevice has a single
-channel and its interrupt source is selected by the position of jumper
-J5.
-
-COMMANDS
-
-The driver supports a read streaming acquisition command on the
-'INTERRUPT' subdevice. The channel list selects the interrupt sources
-to be enabled. All channels will be sampled together (convert_src ==
-TRIG_NOW). The scan begins a short time after the hardware interrupt
-occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT,
-scan_begin_arg == 0). The value read from the interrupt status register
-is packed into a short value, one bit per requested channel, in the
-order they appear in the channel list.
-*/
+ * Driver: amplc_dio200
+ * Description: Amplicon 200 Series Digital I/O
+ * Author: Ian Abbott <abbotti@mev.co.uk>
+ * Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e),
+ * PCI215 (pci215), PCIe215 (pcie215), PC218E (pc218e), PCIe236 (pcie236),
+ * PC272E (pc272e), PCI272 (pci272), PCIe296 (pcie296)
+ * Updated: Wed, 24 Oct 2012 16:22:34 +0100
+ * Status: works
+ *
+ * Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E:
+ * [0] - I/O port base address
+ * [1] - IRQ (optional, but commands won't work without it)
+ *
+ * Manual configuration of PCI(e) cards is not supported; they are configured
+ * automatically.
+ *
+ * Passing a zero for an option is the same as leaving it unspecified.
+ *
+ * SUBDEVICES
+ *
+ * PC212E PC214E PC215E/PCI215
+ * ------------- ------------- -------------
+ * Subdevices 6 4 5
+ * 0 PPI-X PPI-X PPI-X
+ * 1 CTR-Y1 PPI-Y PPI-Y
+ * 2 CTR-Y2 CTR-Z1* CTR-Z1
+ * 3 CTR-Z1 INTERRUPT* CTR-Z2
+ * 4 CTR-Z2 INTERRUPT
+ * 5 INTERRUPT
+ *
+ * PCIe215 PC218E PCIe236
+ * ------------- ------------- -------------
+ * Subdevices 8 7 8
+ * 0 PPI-X CTR-X1 PPI-X
+ * 1 UNUSED CTR-X2 UNUSED
+ * 2 PPI-Y CTR-Y1 UNUSED
+ * 3 UNUSED CTR-Y2 UNUSED
+ * 4 CTR-Z1 CTR-Z1 CTR-Z1
+ * 5 CTR-Z2 CTR-Z2 CTR-Z2
+ * 6 TIMER INTERRUPT TIMER
+ * 7 INTERRUPT INTERRUPT
+ *
+ * PC272E/PCI272 PCIe296
+ * ------------- -------------
+ * Subdevices 4 8
+ * 0 PPI-X PPI-X1
+ * 1 PPI-Y PPI-X2
+ * 2 PPI-Z PPI-Y1
+ * 3 INTERRUPT PPI-Y2
+ * 4 CTR-Z1
+ * 5 CTR-Z2
+ * 6 TIMER
+ * 7 INTERRUPT
+ *
+ * Each PPI is a 8255 chip providing 24 DIO channels. The DIO channels
+ * are configurable as inputs or outputs in four groups:
+ *
+ * Port A - channels 0 to 7
+ * Port B - channels 8 to 15
+ * Port CL - channels 16 to 19
+ * Port CH - channels 20 to 23
+ *
+ * Only mode 0 of the 8255 chips is supported.
+ *
+ * Each CTR is a 8254 chip providing 3 16-bit counter channels. Each
+ * channel is configured individually with INSN_CONFIG instructions. The
+ * specific type of configuration instruction is specified in data[0].
+ * Some configuration instructions expect an additional parameter in
+ * data[1]; others return a value in data[1]. The following configuration
+ * instructions are supported:
+ *
+ * INSN_CONFIG_SET_COUNTER_MODE. Sets the counter channel's mode and
+ * BCD/binary setting specified in data[1].
+ *
+ * INSN_CONFIG_8254_READ_STATUS. Reads the status register value for the
+ * counter channel into data[1].
+ *
+ * INSN_CONFIG_SET_CLOCK_SRC. Sets the counter channel's clock source as
+ * specified in data[1] (this is a hardware-specific value). Not
+ * supported on PC214E. For the other boards, valid clock sources are
+ * 0 to 7 as follows:
+ *
+ * 0. CLK n, the counter channel's dedicated CLK input from the SK1
+ * connector. (N.B. for other values, the counter channel's CLKn
+ * pin on the SK1 connector is an output!)
+ * 1. Internal 10 MHz clock.
+ * 2. Internal 1 MHz clock.
+ * 3. Internal 100 kHz clock.
+ * 4. Internal 10 kHz clock.
+ * 5. Internal 1 kHz clock.
+ * 6. OUT n-1, the output of counter channel n-1 (see note 1 below).
+ * 7. Ext Clock, the counter chip's dedicated Ext Clock input from
+ * the SK1 connector. This pin is shared by all three counter
+ * channels on the chip.
+ *
+ * For the PCIe boards, clock sources in the range 0 to 31 are allowed
+ * and the following additional clock sources are defined:
+ *
+ * 8. HIGH logic level.
+ * 9. LOW logic level.
+ * 10. "Pattern present" signal.
+ * 11. Internal 20 MHz clock.
+ *
+ * INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
+ * clock source in data[1]. For internal clock sources, data[2] is set
+ * to the period in ns.
+ *
+ * INSN_CONFIG_SET_GATE_SRC. Sets the counter channel's gate source as
+ * specified in data[2] (this is a hardware-specific value). Not
+ * supported on PC214E. For the other boards, valid gate sources are 0
+ * to 7 as follows:
+ *
+ * 0. VCC (internal +5V d.c.), i.e. gate permanently enabled.
+ * 1. GND (internal 0V d.c.), i.e. gate permanently disabled.
+ * 2. GAT n, the counter channel's dedicated GAT input from the SK1
+ * connector. (N.B. for other values, the counter channel's GATn
+ * pin on the SK1 connector is an output!)
+ * 3. /OUT n-2, the inverted output of counter channel n-2 (see note
+ * 2 below).
+ * 4. Reserved.
+ * 5. Reserved.
+ * 6. Reserved.
+ * 7. Reserved.
+ *
+ * For the PCIe boards, gate sources in the range 0 to 31 are allowed;
+ * the following additional clock sources and clock sources 6 and 7 are
+ * (re)defined:
+ *
+ * 6. /GAT n, negated version of the counter channel's dedicated
+ * GAT input (negated version of gate source 2).
+ * 7. OUT n-2, the non-inverted output of counter channel n-2
+ * (negated version of gate source 3).
+ * 8. "Pattern present" signal, HIGH while pattern present.
+ * 9. "Pattern occurred" latched signal, latches HIGH when pattern
+ * occurs.
+ * 10. "Pattern gone away" latched signal, latches LOW when pattern
+ * goes away after it occurred.
+ * 11. Negated "pattern present" signal, LOW while pattern present
+ * (negated version of gate source 8).
+ * 12. Negated "pattern occurred" latched signal, latches LOW when
+ * pattern occurs (negated version of gate source 9).
+ * 13. Negated "pattern gone away" latched signal, latches LOW when
+ * pattern goes away after it occurred (negated version of gate
+ * source 10).
+ *
+ * INSN_CONFIG_GET_GATE_SRC. Returns the counter channel's current gate
+ * source in data[2].
+ *
+ * Clock and gate interconnection notes:
+ *
+ * 1. Clock source OUT n-1 is the output of the preceding channel on the
+ * same counter subdevice if n > 0, or the output of channel 2 on the
+ * preceding counter subdevice (see note 3) if n = 0.
+ *
+ * 2. Gate source /OUT n-2 is the inverted output of channel 0 on the
+ * same counter subdevice if n = 2, or the inverted output of channel n+1
+ * on the preceding counter subdevice (see note 3) if n < 2.
+ *
+ * 3. The counter subdevices are connected in a ring, so the highest
+ * counter subdevice precedes the lowest.
+ *
+ * The 'TIMER' subdevice is a free-running 32-bit timer subdevice.
+ *
+ * The 'INTERRUPT' subdevice pretends to be a digital input subdevice. The
+ * digital inputs come from the interrupt status register. The number of
+ * channels matches the number of interrupt sources. The PC214E does not
+ * have an interrupt status register; see notes on 'INTERRUPT SOURCES'
+ * below.
+ *
+ * INTERRUPT SOURCES
+ *
+ * PC212E PC214E PC215E/PCI215
+ * ------------- ------------- -------------
+ * Sources 6 1 6
+ * 0 PPI-X-C0 JUMPER-J5 PPI-X-C0
+ * 1 PPI-X-C3 PPI-X-C3
+ * 2 CTR-Y1-OUT1 PPI-Y-C0
+ * 3 CTR-Y2-OUT1 PPI-Y-C3
+ * 4 CTR-Z1-OUT1 CTR-Z1-OUT1
+ * 5 CTR-Z2-OUT1 CTR-Z2-OUT1
+ *
+ * PCIe215 PC218E PCIe236
+ * ------------- ------------- -------------
+ * Sources 6 6 6
+ * 0 PPI-X-C0 CTR-X1-OUT1 PPI-X-C0
+ * 1 PPI-X-C3 CTR-X2-OUT1 PPI-X-C3
+ * 2 PPI-Y-C0 CTR-Y1-OUT1 unused
+ * 3 PPI-Y-C3 CTR-Y2-OUT1 unused
+ * 4 CTR-Z1-OUT1 CTR-Z1-OUT1 CTR-Z1-OUT1
+ * 5 CTR-Z2-OUT1 CTR-Z2-OUT1 CTR-Z2-OUT1
+ *
+ * PC272E/PCI272 PCIe296
+ * ------------- -------------
+ * Sources 6 6
+ * 0 PPI-X-C0 PPI-X1-C0
+ * 1 PPI-X-C3 PPI-X1-C3
+ * 2 PPI-Y-C0 PPI-Y1-C0
+ * 3 PPI-Y-C3 PPI-Y1-C3
+ * 4 PPI-Z-C0 CTR-Z1-OUT1
+ * 5 PPI-Z-C3 CTR-Z2-OUT1
+ *
+ * When an interrupt source is enabled in the interrupt source enable
+ * register, a rising edge on the source signal latches the corresponding
+ * bit to 1 in the interrupt status register.
+ *
+ * When the interrupt status register value as a whole (actually, just the
+ * 6 least significant bits) goes from zero to non-zero, the board will
+ * generate an interrupt. For level-triggered hardware interrupts (PCI
+ * card), the interrupt will remain asserted until the interrupt status
+ * register is cleared to zero. For edge-triggered hardware interrupts
+ * (ISA card), no further interrupts will occur until the interrupt status
+ * register is cleared to zero. To clear a bit to zero in the interrupt
+ * status register, the corresponding interrupt source must be disabled
+ * in the interrupt source enable register (there is no separate interrupt
+ * clear register).
+ *
+ * The PC214E does not have an interrupt source enable register or an
+ * interrupt status register; its 'INTERRUPT' subdevice has a single
+ * channel and its interrupt source is selected by the position of jumper
+ * J5.
+ *
+ * COMMANDS
+ *
+ * The driver supports a read streaming acquisition command on the
+ * 'INTERRUPT' subdevice. The channel list selects the interrupt sources
+ * to be enabled. All channels will be sampled together (convert_src ==
+ * TRIG_NOW). The scan begins a short time after the hardware interrupt
+ * occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT,
+ * scan_begin_arg == 0). The value read from the interrupt status register
+ * is packed into a short value, one bit per requested channel, in the
+ * order they appear in the channel list.
+ */
#include <linux/interrupt.h>
#include <linux/slab.h>
@@ -211,7 +264,6 @@ order they appear in the channel list.
#include "../comedidev.h"
#include "comedi_fc.h"
-#include "8255.h"
#include "8253.h"
#define DIO200_DRIVER_NAME "amplc_dio200"
@@ -220,13 +272,24 @@ order they appear in the channel list.
#define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI)
/* PCI IDs */
-#define PCI_VENDOR_ID_AMPLICON 0x14dc
#define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
#define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
-#define PCI_DEVICE_ID_INVALID 0xffff
+#define PCI_DEVICE_ID_AMPLICON_PCIE236 0x0011
+#define PCI_DEVICE_ID_AMPLICON_PCIE215 0x0012
+#define PCI_DEVICE_ID_AMPLICON_PCIE296 0x0014
+
+/* 8255 control register bits */
+#define CR_C_LO_IO 0x01
+#define CR_B_IO 0x02
+#define CR_B_MODE 0x04
+#define CR_C_HI_IO 0x08
+#define CR_A_IO 0x10
+#define CR_A_MODE(a) ((a)<<5)
+#define CR_CW 0x80
/* 200 series registers */
#define DIO200_IO_SIZE 0x20
+#define DIO200_PCIE_IO_SIZE 0x4000
#define DIO200_XCLK_SCE 0x18 /* Group X clock selection register */
#define DIO200_YCLK_SCE 0x19 /* Group Y clock selection register */
#define DIO200_ZCLK_SCE 0x1a /* Group Z clock selection register */
@@ -234,30 +297,78 @@ order they appear in the channel list.
#define DIO200_YGAT_SCE 0x1c /* Group Y gate selection register */
#define DIO200_ZGAT_SCE 0x1d /* Group Z gate selection register */
#define DIO200_INT_SCE 0x1e /* Interrupt enable/status register */
+/* Extra registers for new PCIe boards */
+#define DIO200_ENHANCE 0x20 /* 1 to enable enhanced features */
+#define DIO200_VERSION 0x24 /* Hardware version register */
+#define DIO200_TS_CONFIG 0x600 /* Timestamp timer config register */
+#define DIO200_TS_COUNT 0x602 /* Timestamp timer count register */
/*
- * Macros for constructing value for DIO_200_?CLK_SCE and
+ * Functions for constructing value for DIO_200_?CLK_SCE and
* DIO_200_?GAT_SCE registers:
*
* 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
* 'chan' is the channel: 0, 1 or 2.
- * 'source' is the signal source: 0 to 7.
+ * 'source' is the signal source: 0 to 7, or 0 to 31 for "enhanced" boards.
*/
-#define CLK_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
-#define GAT_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
+static unsigned char clk_gat_sce(unsigned int which, unsigned int chan,
+ unsigned int source)
+{
+ return (which << 5) | (chan << 3) |
+ ((source & 030) << 3) | (source & 007);
+}
+
+static unsigned char clk_sce(unsigned int which, unsigned int chan,
+ unsigned int source)
+{
+ return clk_gat_sce(which, chan, source);
+}
+
+static unsigned char gat_sce(unsigned int which, unsigned int chan,
+ unsigned int source)
+{
+ return clk_gat_sce(which, chan, source);
+}
/*
* Periods of the internal clock sources in nanoseconds.
*/
-static const unsigned clock_period[8] = {
- 0, /* dedicated clock input/output pin */
- 100, /* 10 MHz */
- 1000, /* 1 MHz */
- 10000, /* 100 kHz */
- 100000, /* 10 kHz */
- 1000000, /* 1 kHz */
- 0, /* OUT N-1 */
- 0 /* group clock input pin */
+static const unsigned int clock_period[32] = {
+ [1] = 100, /* 10 MHz */
+ [2] = 1000, /* 1 MHz */
+ [3] = 10000, /* 100 kHz */
+ [4] = 100000, /* 10 kHz */
+ [5] = 1000000, /* 1 kHz */
+ [11] = 50, /* 20 MHz (enhanced boards) */
+ /* clock sources 12 and later reserved for enhanced boards */
+};
+
+/*
+ * Timestamp timer configuration register (for new PCIe boards).
+ */
+#define TS_CONFIG_RESET 0x100 /* Reset counter to zero. */
+#define TS_CONFIG_CLK_SRC_MASK 0x0FF /* Clock source. */
+#define TS_CONFIG_MAX_CLK_SRC 2 /* Maximum clock source value. */
+
+/*
+ * Periods of the timestamp timer clock sources in nanoseconds.
+ */
+static const unsigned int ts_clock_period[TS_CONFIG_MAX_CLK_SRC + 1] = {
+ 1, /* 1 nanosecond (but with 20 ns granularity). */
+ 1000, /* 1 microsecond. */
+ 1000000, /* 1 millisecond. */
+};
+
+/*
+ * Register region.
+ */
+enum dio200_regtype { no_regtype = 0, io_regtype, mmio_regtype };
+struct dio200_region {
+ union {
+ unsigned long iobase; /* I/O base address */
+ unsigned char __iomem *membase; /* mapped MMIO base address */
+ } u;
+ enum dio200_regtype regtype;
};
/*
@@ -269,13 +380,14 @@ enum dio200_bustype { isa_bustype, pci_bustype };
enum dio200_model {
pc212e_model,
pc214e_model,
- pc215e_model, pci215_model,
+ pc215e_model, pci215_model, pcie215_model,
pc218e_model,
+ pcie236_model,
pc272e_model, pci272_model,
- anypci_model
+ pcie296_model,
};
-enum dio200_layout {
+enum dio200_layout_idx {
#if DO_ISA
pc212_layout,
pc214_layout,
@@ -284,7 +396,12 @@ enum dio200_layout {
#if DO_ISA
pc218_layout,
#endif
- pc272_layout
+ pc272_layout,
+#if DO_PCI
+ pcie215_layout,
+ pcie236_layout,
+ pcie296_layout,
+#endif
};
struct dio200_board {
@@ -292,7 +409,10 @@ struct dio200_board {
unsigned short devid;
enum dio200_bustype bustype;
enum dio200_model model;
- enum dio200_layout layout;
+ enum dio200_layout_idx layout;
+ unsigned char mainbar;
+ unsigned char mainshift;
+ unsigned int mainsize;
};
static const struct dio200_board dio200_boards[] = {
@@ -302,30 +422,35 @@ static const struct dio200_board dio200_boards[] = {
.bustype = isa_bustype,
.model = pc212e_model,
.layout = pc212_layout,
+ .mainsize = DIO200_IO_SIZE,
},
{
.name = "pc214e",
.bustype = isa_bustype,
.model = pc214e_model,
.layout = pc214_layout,
+ .mainsize = DIO200_IO_SIZE,
},
{
.name = "pc215e",
.bustype = isa_bustype,
.model = pc215e_model,
.layout = pc215_layout,
+ .mainsize = DIO200_IO_SIZE,
},
{
.name = "pc218e",
.bustype = isa_bustype,
.model = pc218e_model,
.layout = pc218_layout,
+ .mainsize = DIO200_IO_SIZE,
},
{
.name = "pc272e",
.bustype = isa_bustype,
.model = pc272e_model,
.layout = pc272_layout,
+ .mainsize = DIO200_IO_SIZE,
},
#endif
#if DO_PCI
@@ -335,6 +460,8 @@ static const struct dio200_board dio200_boards[] = {
.bustype = pci_bustype,
.model = pci215_model,
.layout = pc215_layout,
+ .mainbar = 2,
+ .mainsize = DIO200_IO_SIZE,
},
{
.name = "pci272",
@@ -342,12 +469,38 @@ static const struct dio200_board dio200_boards[] = {
.bustype = pci_bustype,
.model = pci272_model,
.layout = pc272_layout,
+ .mainbar = 2,
+ .mainsize = DIO200_IO_SIZE,
+ },
+ {
+ .name = "pcie215",
+ .devid = PCI_DEVICE_ID_AMPLICON_PCIE215,
+ .bustype = pci_bustype,
+ .model = pcie215_model,
+ .layout = pcie215_layout,
+ .mainbar = 1,
+ .mainshift = 3,
+ .mainsize = DIO200_PCIE_IO_SIZE,
},
{
- .name = DIO200_DRIVER_NAME,
- .devid = PCI_DEVICE_ID_INVALID,
+ .name = "pcie236",
+ .devid = PCI_DEVICE_ID_AMPLICON_PCIE236,
.bustype = pci_bustype,
- .model = anypci_model, /* wildcard */
+ .model = pcie236_model,
+ .layout = pcie236_layout,
+ .mainbar = 1,
+ .mainshift = 3,
+ .mainsize = DIO200_PCIE_IO_SIZE,
+ },
+ {
+ .name = "pcie296",
+ .devid = PCI_DEVICE_ID_AMPLICON_PCIE296,
+ .bustype = pci_bustype,
+ .model = pcie296_model,
+ .layout = pcie296_layout,
+ .mainbar = 1,
+ .mainshift = 3,
+ .mainsize = DIO200_PCIE_IO_SIZE,
},
#endif
};
@@ -357,20 +510,21 @@ static const struct dio200_board dio200_boards[] = {
* layout.
*/
-enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254 };
+enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer };
-#define DIO200_MAX_SUBDEVS 7
+#define DIO200_MAX_SUBDEVS 8
#define DIO200_MAX_ISNS 6
-struct dio200_layout_struct {
+struct dio200_layout {
unsigned short n_subdevs; /* number of subdevices */
unsigned char sdtype[DIO200_MAX_SUBDEVS]; /* enum dio200_sdtype */
unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */
char has_int_sce; /* has interrupt enable/status register */
char has_clk_gat_sce; /* has clock/gate selection registers */
+ char has_enhancements; /* has enhanced features */
};
-static const struct dio200_layout_struct dio200_layouts[] = {
+static const struct dio200_layout dio200_layouts[] = {
#if DO_ISA
[pc212_layout] = {
.n_subdevs = 6,
@@ -421,6 +575,38 @@ static const struct dio200_layout_struct dio200_layouts[] = {
.has_int_sce = 1,
.has_clk_gat_sce = 0,
},
+#if DO_PCI
+ [pcie215_layout] = {
+ .n_subdevs = 8,
+ .sdtype = {sd_8255, sd_none, sd_8255, sd_none,
+ sd_8254, sd_8254, sd_timer, sd_intr},
+ .sdinfo = {0x00, 0x00, 0x08, 0x00,
+ 0x10, 0x14, 0x00, 0x3F},
+ .has_int_sce = 1,
+ .has_clk_gat_sce = 1,
+ .has_enhancements = 1,
+ },
+ [pcie236_layout] = {
+ .n_subdevs = 8,
+ .sdtype = {sd_8255, sd_none, sd_none, sd_none,
+ sd_8254, sd_8254, sd_timer, sd_intr},
+ .sdinfo = {0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x14, 0x00, 0x3F},
+ .has_int_sce = 1,
+ .has_clk_gat_sce = 1,
+ .has_enhancements = 1,
+ },
+ [pcie296_layout] = {
+ .n_subdevs = 8,
+ .sdtype = {sd_8255, sd_8255, sd_8255, sd_8255,
+ sd_8254, sd_8254, sd_timer, sd_intr},
+ .sdinfo = {0x00, 0x04, 0x08, 0x0C,
+ 0x10, 0x14, 0x00, 0x3F},
+ .has_int_sce = 1,
+ .has_clk_gat_sce = 1,
+ .has_enhancements = 1,
+ },
+#endif
};
/* this structure is for data unique to this hardware driver. If
@@ -428,31 +614,46 @@ static const struct dio200_layout_struct dio200_layouts[] = {
feel free to suggest moving the variable to the struct comedi_device struct.
*/
struct dio200_private {
+ struct dio200_region io; /* Register region */
int intr_sd;
};
struct dio200_subdev_8254 {
- unsigned long iobase; /* Counter base address */
- unsigned long clk_sce_iobase; /* CLK_SCE base address */
- unsigned long gat_sce_iobase; /* GAT_SCE base address */
- int which; /* Bit 5 of CLK_SCE or GAT_SCE */
- int has_clk_gat_sce;
- unsigned clock_src[3]; /* Current clock sources */
- unsigned gate_src[3]; /* Current gate sources */
+ unsigned int ofs; /* Counter base offset */
+ unsigned int clk_sce_ofs; /* CLK_SCE base address */
+ unsigned int gat_sce_ofs; /* GAT_SCE base address */
+ int which; /* Bit 5 of CLK_SCE or GAT_SCE */
+ unsigned int clock_src[3]; /* Current clock sources */
+ unsigned int gate_src[3]; /* Current gate sources */
spinlock_t spinlock;
};
+struct dio200_subdev_8255 {
+ unsigned int ofs; /* DIO base offset */
+};
+
struct dio200_subdev_intr {
- unsigned long iobase;
+ unsigned int ofs;
spinlock_t spinlock;
int active;
- int has_int_sce;
unsigned int valid_isns;
unsigned int enabled_isns;
unsigned int stopcount;
int continuous;
};
+static inline const struct dio200_layout *
+dio200_board_layout(const struct dio200_board *board)
+{
+ return &dio200_layouts[board->layout];
+}
+
+static inline const struct dio200_layout *
+dio200_dev_layout(struct comedi_device *dev)
+{
+ return dio200_board_layout(comedi_board(dev));
+}
+
static inline bool is_pci_board(const struct dio200_board *board)
{
return DO_PCI && board->bustype == pci_bustype;
@@ -464,6 +665,70 @@ static inline bool is_isa_board(const struct dio200_board *board)
}
/*
+ * Read 8-bit register.
+ */
+static unsigned char dio200_read8(struct comedi_device *dev,
+ unsigned int offset)
+{
+ const struct dio200_board *thisboard = comedi_board(dev);
+ struct dio200_private *devpriv = dev->private;
+
+ offset <<= thisboard->mainshift;
+ if (devpriv->io.regtype == io_regtype)
+ return inb(devpriv->io.u.iobase + offset);
+ else
+ return readb(devpriv->io.u.membase + offset);
+}
+
+/*
+ * Write 8-bit register.
+ */
+static void dio200_write8(struct comedi_device *dev, unsigned int offset,
+ unsigned char val)
+{
+ const struct dio200_board *thisboard = comedi_board(dev);
+ struct dio200_private *devpriv = dev->private;
+
+ offset <<= thisboard->mainshift;
+ if (devpriv->io.regtype == io_regtype)
+ outb(val, devpriv->io.u.iobase + offset);
+ else
+ writeb(val, devpriv->io.u.membase + offset);
+}
+
+/*
+ * Read 32-bit register.
+ */
+static unsigned int dio200_read32(struct comedi_device *dev,
+ unsigned int offset)
+{
+ const struct dio200_board *thisboard = comedi_board(dev);
+ struct dio200_private *devpriv = dev->private;
+
+ offset <<= thisboard->mainshift;
+ if (devpriv->io.regtype == io_regtype)
+ return inl(devpriv->io.u.iobase + offset);
+ else
+ return readl(devpriv->io.u.membase + offset);
+}
+
+/*
+ * Write 32-bit register.
+ */
+static void dio200_write32(struct comedi_device *dev, unsigned int offset,
+ unsigned int val)
+{
+ const struct dio200_board *thisboard = comedi_board(dev);
+ struct dio200_private *devpriv = dev->private;
+
+ offset <<= thisboard->mainshift;
+ if (devpriv->io.regtype == io_regtype)
+ outl(val, devpriv->io.u.iobase + offset);
+ else
+ writel(val, devpriv->io.u.membase + offset);
+}
+
+/*
* This function looks for a board matching the supplied PCI device.
*/
static const struct dio200_board *
@@ -479,49 +744,6 @@ dio200_find_pci_board(struct pci_dev *pci_dev)
}
/*
- * This function looks for a PCI device matching the requested board name,
- * bus and slot.
- */
-static struct pci_dev *dio200_find_pci_dev(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- const struct dio200_board *thisboard = comedi_board(dev);
- struct pci_dev *pci_dev = NULL;
- int bus = it->options[0];
- int slot = it->options[1];
-
- for_each_pci_dev(pci_dev) {
- if (bus || slot) {
- if (bus != pci_dev->bus->number ||
- slot != PCI_SLOT(pci_dev->devfn))
- continue;
- }
- if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
- continue;
-
- if (thisboard->model == anypci_model) {
- /* Wildcard board matches any supported PCI board. */
- const struct dio200_board *foundboard;
-
- foundboard = dio200_find_pci_board(pci_dev);
- if (foundboard == NULL)
- continue;
- /* Replace wildcard board_ptr. */
- dev->board_ptr = foundboard;
- } else {
- /* Match specific model name. */
- if (pci_dev->device != thisboard->devid)
- continue;
- }
- return pci_dev;
- }
- dev_err(dev->class_dev,
- "No supported board found! (req. bus %d, slot %d)\n",
- bus, slot);
- return NULL;
-}
-
-/*
* This function checks and requests an I/O region, reporting an error
* if there is a conflict.
*/
@@ -545,11 +767,12 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
struct dio200_subdev_intr *subpriv = s->private;
- if (subpriv->has_int_sce) {
+ if (layout->has_int_sce) {
/* Just read the interrupt status register. */
- data[1] = inb(subpriv->iobase) & subpriv->valid_isns;
+ data[1] = dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns;
} else {
/* No interrupt status register. */
data[0] = 0;
@@ -564,12 +787,13 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev,
static void dio200_stop_intr(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
struct dio200_subdev_intr *subpriv = s->private;
subpriv->active = 0;
subpriv->enabled_isns = 0;
- if (subpriv->has_int_sce)
- outb(0, subpriv->iobase);
+ if (layout->has_int_sce)
+ dio200_write8(dev, subpriv->ofs, 0);
}
/*
@@ -580,6 +804,7 @@ static int dio200_start_intr(struct comedi_device *dev,
{
unsigned int n;
unsigned isn_bits;
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
struct dio200_subdev_intr *subpriv = s->private;
struct comedi_cmd *cmd = &s->async->cmd;
int retval = 0;
@@ -599,8 +824,8 @@ static int dio200_start_intr(struct comedi_device *dev,
isn_bits &= subpriv->valid_isns;
/* Enable interrupt sources. */
subpriv->enabled_isns = isn_bits;
- if (subpriv->has_int_sce)
- outb(isn_bits, subpriv->iobase);
+ if (layout->has_int_sce)
+ dio200_write8(dev, subpriv->ofs, isn_bits);
}
return retval;
@@ -642,6 +867,7 @@ dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
static int dio200_handle_read_intr(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
struct dio200_subdev_intr *subpriv = s->private;
unsigned triggered;
unsigned intstat;
@@ -653,7 +879,7 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
spin_lock_irqsave(&subpriv->spinlock, flags);
oldevents = s->async->events;
- if (subpriv->has_int_sce) {
+ if (layout->has_int_sce) {
/*
* Collect interrupt sources that have triggered and disable
* them temporarily. Loop around until no extra interrupt
@@ -665,11 +891,11 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
* loop in case of misconfiguration.
*/
cur_enabled = subpriv->enabled_isns;
- while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns
- & ~triggered)) != 0) {
+ while ((intstat = (dio200_read8(dev, subpriv->ofs) &
+ subpriv->valid_isns & ~triggered)) != 0) {
triggered |= intstat;
cur_enabled &= ~triggered;
- outb(cur_enabled, subpriv->iobase);
+ dio200_write8(dev, subpriv->ofs, cur_enabled);
}
} else {
/*
@@ -687,8 +913,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
* Reenable them NOW to minimize the time they are disabled.
*/
cur_enabled = subpriv->enabled_isns;
- if (subpriv->has_int_sce)
- outb(cur_enabled, subpriv->iobase);
+ if (layout->has_int_sce)
+ dio200_write8(dev, subpriv->ofs, cur_enabled);
if (subpriv->active) {
/*
@@ -794,41 +1020,19 @@ dio200_subdev_intr_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
-
- /* cmd->scan_begin_src == TRIG_EXT */
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
-
- /* cmd->convert_src == TRIG_NOW */
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
-
- /* cmd->scan_end_src == TRIG_COUNT */
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ 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, cmd->chanlist_len);
switch (cmd->stop_src) {
case TRIG_COUNT:
/* any count allowed */
break;
case TRIG_NONE:
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
break;
default:
break;
@@ -894,9 +1098,9 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev,
*/
static int
dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned long iobase, unsigned valid_isns,
- int has_int_sce)
+ unsigned int offset, unsigned valid_isns)
{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
struct dio200_subdev_intr *subpriv;
subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
@@ -904,18 +1108,18 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
dev_err(dev->class_dev, "error! out of memory!\n");
return -ENOMEM;
}
- subpriv->iobase = iobase;
- subpriv->has_int_sce = has_int_sce;
+ subpriv->ofs = offset;
subpriv->valid_isns = valid_isns;
spin_lock_init(&subpriv->spinlock);
- if (has_int_sce)
- outb(0, subpriv->iobase); /* Disable interrupt sources. */
+ if (layout->has_int_sce)
+ /* Disable interrupt sources. */
+ dio200_write8(dev, subpriv->ofs, 0);
s->private = subpriv;
s->type = COMEDI_SUBD_DI;
s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
- if (has_int_sce) {
+ if (layout->has_int_sce) {
s->n_chan = DIO200_MAX_ISNS;
s->len_chanlist = DIO200_MAX_ISNS;
} else {
@@ -968,6 +1172,73 @@ static irqreturn_t dio200_interrupt(int irq, void *d)
}
/*
+ * Read an '8254' counter subdevice channel.
+ */
+static unsigned int
+dio200_subdev_8254_read_chan(struct comedi_device *dev,
+ struct comedi_subdevice *s, unsigned int chan)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+ unsigned int val;
+
+ /* latch counter */
+ val = chan << 6;
+ dio200_write8(dev, subpriv->ofs + i8254_control_reg, val);
+ /* read lsb, msb */
+ val = dio200_read8(dev, subpriv->ofs + chan);
+ val += dio200_read8(dev, subpriv->ofs + chan) << 8;
+ return val;
+}
+
+/*
+ * Write an '8254' subdevice channel.
+ */
+static void
+dio200_subdev_8254_write_chan(struct comedi_device *dev,
+ struct comedi_subdevice *s, unsigned int chan,
+ unsigned int count)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+
+ /* write lsb, msb */
+ dio200_write8(dev, subpriv->ofs + chan, count & 0xff);
+ dio200_write8(dev, subpriv->ofs + chan, (count >> 8) & 0xff);
+}
+
+/*
+ * Set mode of an '8254' subdevice channel.
+ */
+static void
+dio200_subdev_8254_set_mode(struct comedi_device *dev,
+ struct comedi_subdevice *s, unsigned int chan,
+ unsigned int mode)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+ unsigned int byte;
+
+ byte = chan << 6;
+ byte |= 0x30; /* access order: lsb, msb */
+ byte |= (mode & 0xf); /* counter mode and BCD|binary */
+ dio200_write8(dev, subpriv->ofs + i8254_control_reg, byte);
+}
+
+/*
+ * Read status byte of an '8254' counter subdevice channel.
+ */
+static unsigned int
+dio200_subdev_8254_status(struct comedi_device *dev,
+ struct comedi_subdevice *s, unsigned int chan)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+
+ /* latch status */
+ dio200_write8(dev, subpriv->ofs + i8254_control_reg,
+ 0xe0 | (2 << chan));
+ /* read status */
+ return dio200_read8(dev, subpriv->ofs + chan);
+}
+
+/*
* Handle 'insn_read' for an '8254' counter subdevice.
*/
static int
@@ -976,13 +1247,15 @@ dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
{
struct dio200_subdev_8254 *subpriv = s->private;
int chan = CR_CHAN(insn->chanspec);
+ unsigned int n;
unsigned long flags;
- spin_lock_irqsave(&subpriv->spinlock, flags);
- data[0] = i8254_read(subpriv->iobase, 0, chan);
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
-
- return 1;
+ for (n = 0; n < insn->n; n++) {
+ spin_lock_irqsave(&subpriv->spinlock, flags);
+ data[n] = dio200_subdev_8254_read_chan(dev, s, chan);
+ spin_unlock_irqrestore(&subpriv->spinlock, flags);
+ }
+ return insn->n;
}
/*
@@ -994,34 +1267,40 @@ dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
{
struct dio200_subdev_8254 *subpriv = s->private;
int chan = CR_CHAN(insn->chanspec);
+ unsigned int n;
unsigned long flags;
- spin_lock_irqsave(&subpriv->spinlock, flags);
- i8254_write(subpriv->iobase, 0, chan, data[0]);
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
-
- return 1;
+ for (n = 0; n < insn->n; n++) {
+ spin_lock_irqsave(&subpriv->spinlock, flags);
+ dio200_subdev_8254_write_chan(dev, s, chan, data[n]);
+ spin_unlock_irqrestore(&subpriv->spinlock, flags);
+ }
+ return insn->n;
}
/*
* Set gate source for an '8254' counter subdevice channel.
*/
static int
-dio200_set_gate_src(struct dio200_subdev_8254 *subpriv,
- unsigned int counter_number, unsigned int gate_src)
+dio200_subdev_8254_set_gate_src(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int counter_number,
+ unsigned int gate_src)
{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
+ struct dio200_subdev_8254 *subpriv = s->private;
unsigned char byte;
- if (!subpriv->has_clk_gat_sce)
+ if (!layout->has_clk_gat_sce)
return -1;
if (counter_number > 2)
return -1;
- if (gate_src > 7)
+ if (gate_src > (layout->has_enhancements ? 31 : 7))
return -1;
subpriv->gate_src[counter_number] = gate_src;
- byte = GAT_SCE(subpriv->which, counter_number, gate_src);
- outb(byte, subpriv->gat_sce_iobase);
+ byte = gat_sce(subpriv->which, counter_number, gate_src);
+ dio200_write8(dev, subpriv->gat_sce_ofs, byte);
return 0;
}
@@ -1030,10 +1309,14 @@ dio200_set_gate_src(struct dio200_subdev_8254 *subpriv,
* Get gate source for an '8254' counter subdevice channel.
*/
static int
-dio200_get_gate_src(struct dio200_subdev_8254 *subpriv,
- unsigned int counter_number)
+dio200_subdev_8254_get_gate_src(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int counter_number)
{
- if (!subpriv->has_clk_gat_sce)
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
+ struct dio200_subdev_8254 *subpriv = s->private;
+
+ if (!layout->has_clk_gat_sce)
return -1;
if (counter_number > 2)
return -1;
@@ -1045,21 +1328,25 @@ dio200_get_gate_src(struct dio200_subdev_8254 *subpriv,
* Set clock source for an '8254' counter subdevice channel.
*/
static int
-dio200_set_clock_src(struct dio200_subdev_8254 *subpriv,
- unsigned int counter_number, unsigned int clock_src)
+dio200_subdev_8254_set_clock_src(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int counter_number,
+ unsigned int clock_src)
{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
+ struct dio200_subdev_8254 *subpriv = s->private;
unsigned char byte;
- if (!subpriv->has_clk_gat_sce)
+ if (!layout->has_clk_gat_sce)
return -1;
if (counter_number > 2)
return -1;
- if (clock_src > 7)
+ if (clock_src > (layout->has_enhancements ? 31 : 7))
return -1;
subpriv->clock_src[counter_number] = clock_src;
- byte = CLK_SCE(subpriv->which, counter_number, clock_src);
- outb(byte, subpriv->clk_sce_iobase);
+ byte = clk_sce(subpriv->which, counter_number, clock_src);
+ dio200_write8(dev, subpriv->clk_sce_ofs, byte);
return 0;
}
@@ -1068,12 +1355,16 @@ dio200_set_clock_src(struct dio200_subdev_8254 *subpriv,
* Get clock source for an '8254' counter subdevice channel.
*/
static int
-dio200_get_clock_src(struct dio200_subdev_8254 *subpriv,
- unsigned int counter_number, unsigned int *period_ns)
+dio200_subdev_8254_get_clock_src(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int counter_number,
+ unsigned int *period_ns)
{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
+ struct dio200_subdev_8254 *subpriv = s->private;
unsigned clock_src;
- if (!subpriv->has_clk_gat_sce)
+ if (!layout->has_clk_gat_sce)
return -1;
if (counter_number > 2)
return -1;
@@ -1098,20 +1389,21 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
spin_lock_irqsave(&subpriv->spinlock, flags);
switch (data[0]) {
case INSN_CONFIG_SET_COUNTER_MODE:
- ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]);
- if (ret < 0)
+ if (data[1] > (I8254_MODE5 | I8254_BINARY))
ret = -EINVAL;
+ else
+ dio200_subdev_8254_set_mode(dev, s, chan, data[1]);
break;
case INSN_CONFIG_8254_READ_STATUS:
- data[1] = i8254_status(subpriv->iobase, 0, chan);
+ data[1] = dio200_subdev_8254_status(dev, s, chan);
break;
case INSN_CONFIG_SET_GATE_SRC:
- ret = dio200_set_gate_src(subpriv, chan, data[2]);
+ ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]);
if (ret < 0)
ret = -EINVAL;
break;
case INSN_CONFIG_GET_GATE_SRC:
- ret = dio200_get_gate_src(subpriv, chan);
+ ret = dio200_subdev_8254_get_gate_src(dev, s, chan);
if (ret < 0) {
ret = -EINVAL;
break;
@@ -1119,12 +1411,12 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
data[2] = ret;
break;
case INSN_CONFIG_SET_CLOCK_SRC:
- ret = dio200_set_clock_src(subpriv, chan, data[1]);
+ ret = dio200_subdev_8254_set_clock_src(dev, s, chan, data[1]);
if (ret < 0)
ret = -EINVAL;
break;
case INSN_CONFIG_GET_CLOCK_SRC:
- ret = dio200_get_clock_src(subpriv, chan, &data[2]);
+ ret = dio200_subdev_8254_get_clock_src(dev, s, chan, &data[2]);
if (ret < 0) {
ret = -EINVAL;
break;
@@ -1141,15 +1433,12 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
/*
* This function initializes an '8254' counter subdevice.
- *
- * Note: iobase is the base address of the board, not the subdevice;
- * offset is the offset to the 8254 chip.
*/
static int
dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned long iobase, unsigned offset,
- int has_clk_gat_sce)
+ unsigned int offset)
{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
struct dio200_subdev_8254 *subpriv;
unsigned int chan;
@@ -1169,27 +1458,24 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
s->insn_config = dio200_subdev_8254_config;
spin_lock_init(&subpriv->spinlock);
- subpriv->iobase = offset + iobase;
- subpriv->has_clk_gat_sce = has_clk_gat_sce;
- if (has_clk_gat_sce) {
+ subpriv->ofs = offset;
+ if (layout->has_clk_gat_sce) {
/* Derive CLK_SCE and GAT_SCE register offsets from
* 8254 offset. */
- subpriv->clk_sce_iobase =
- DIO200_XCLK_SCE + (offset >> 3) + iobase;
- subpriv->gat_sce_iobase =
- DIO200_XGAT_SCE + (offset >> 3) + iobase;
+ subpriv->clk_sce_ofs = DIO200_XCLK_SCE + (offset >> 3);
+ subpriv->gat_sce_ofs = DIO200_XGAT_SCE + (offset >> 3);
subpriv->which = (offset >> 2) & 1;
}
/* Initialize channels. */
for (chan = 0; chan < 3; chan++) {
- i8254_set_mode(subpriv->iobase, 0, chan,
- I8254_MODE0 | I8254_BINARY);
- if (subpriv->has_clk_gat_sce) {
+ dio200_subdev_8254_set_mode(dev, s, chan,
+ I8254_MODE0 | I8254_BINARY);
+ if (layout->has_clk_gat_sce) {
/* Gate source 0 is VCC (logic 1). */
- dio200_set_gate_src(subpriv, chan, 0);
+ dio200_subdev_8254_set_gate_src(dev, s, chan, 0);
/* Clock source 0 is the dedicated clock input. */
- dio200_set_clock_src(subpriv, chan, 0);
+ dio200_subdev_8254_set_clock_src(dev, s, chan, 0);
}
}
@@ -1207,16 +1493,294 @@ dio200_subdev_8254_cleanup(struct comedi_device *dev,
kfree(subpriv);
}
+/*
+ * This function sets I/O directions for an '8255' DIO subdevice.
+ */
+static void dio200_subdev_8255_set_dir(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct dio200_subdev_8255 *subpriv = s->private;
+ int config;
+
+ config = CR_CW;
+ /* 1 in io_bits indicates output, 1 in config indicates input */
+ if (!(s->io_bits & 0x0000ff))
+ config |= CR_A_IO;
+ if (!(s->io_bits & 0x00ff00))
+ config |= CR_B_IO;
+ if (!(s->io_bits & 0x0f0000))
+ config |= CR_C_LO_IO;
+ if (!(s->io_bits & 0xf00000))
+ config |= CR_C_HI_IO;
+ 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 dio200_subdev_8255 *subpriv = s->private;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ if (data[0] & 0xff)
+ dio200_write8(dev, subpriv->ofs, s->state & 0xff);
+ if (data[0] & 0xff00)
+ dio200_write8(dev, subpriv->ofs + 1,
+ (s->state >> 8) & 0xff);
+ if (data[0] & 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;
+}
+
+/*
+ * Handle 'insn_config' for an '8255' DIO subdevice.
+ */
+static int dio200_subdev_8255_config(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ unsigned int mask;
+ unsigned int bits;
+
+ mask = 1 << CR_CHAN(insn->chanspec);
+ if (mask & 0x0000ff)
+ bits = 0x0000ff;
+ else if (mask & 0x00ff00)
+ bits = 0x00ff00;
+ else if (mask & 0x0f0000)
+ bits = 0x0f0000;
+ else
+ bits = 0xf00000;
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~bits;
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= bits;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+ dio200_subdev_8255_set_dir(dev, s);
+ return 1;
+}
+
+/*
+ * This function initializes an '8255' DIO subdevice.
+ *
+ * offset is the offset to the 8255 chip.
+ */
+static int dio200_subdev_8255_init(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int offset)
+{
+ struct dio200_subdev_8255 *subpriv;
+
+ subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
+ if (!subpriv)
+ return -ENOMEM;
+ subpriv->ofs = offset;
+ s->private = subpriv;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 24;
+ s->range_table = &range_digital;
+ 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;
+}
+
+/*
+ * This function cleans up an '8255' DIO subdevice.
+ */
+static void dio200_subdev_8255_cleanup(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct dio200_subdev_8255 *subpriv = s->private;
+
+ kfree(subpriv);
+}
+
+/*
+ * Handle 'insn_read' for a timer subdevice.
+ */
+static int dio200_subdev_timer_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ unsigned int n;
+
+ for (n = 0; n < insn->n; n++)
+ data[n] = dio200_read32(dev, DIO200_TS_COUNT);
+ return n;
+}
+
+/*
+ * Reset timer subdevice.
+ */
+static void dio200_subdev_timer_reset(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ unsigned int clock;
+
+ clock = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK;
+ dio200_write32(dev, DIO200_TS_CONFIG, clock | TS_CONFIG_RESET);
+ dio200_write32(dev, DIO200_TS_CONFIG, clock);
+}
+
+/*
+ * Get timer subdevice clock source and period.
+ */
+static void dio200_subdev_timer_get_clock_src(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int *src,
+ unsigned int *period)
+{
+ unsigned int clk;
+
+ clk = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK;
+ *src = clk;
+ *period = (clk < ARRAY_SIZE(ts_clock_period)) ?
+ ts_clock_period[clk] : 0;
+}
+
+/*
+ * Set timer subdevice clock source.
+ */
+static int dio200_subdev_timer_set_clock_src(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int src)
+{
+ if (src > TS_CONFIG_MAX_CLK_SRC)
+ return -EINVAL;
+ dio200_write32(dev, DIO200_TS_CONFIG, src);
+ return 0;
+}
+
+/*
+ * Handle 'insn_config' for a timer subdevice.
+ */
+static int dio200_subdev_timer_config(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ int ret = 0;
+
+ switch (data[0]) {
+ case INSN_CONFIG_RESET:
+ dio200_subdev_timer_reset(dev, s);
+ break;
+ case INSN_CONFIG_SET_CLOCK_SRC:
+ ret = dio200_subdev_timer_set_clock_src(dev, s, data[1]);
+ if (ret < 0)
+ ret = -EINVAL;
+ break;
+ case INSN_CONFIG_GET_CLOCK_SRC:
+ dio200_subdev_timer_get_clock_src(dev, s, &data[1], &data[2]);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret < 0 ? ret : insn->n;
+}
+
+/*
+ * This function initializes a timer subdevice.
+ *
+ * Uses the timestamp timer registers. There is only one timestamp timer.
+ */
+static int dio200_subdev_timer_init(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
+ s->n_chan = 1;
+ s->maxdata = 0xFFFFFFFF;
+ s->insn_read = dio200_subdev_timer_read;
+ s->insn_config = dio200_subdev_timer_config;
+ return 0;
+}
+
+/*
+ * This function cleans up a timer subdevice.
+ */
+static void dio200_subdev_timer_cleanup(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ /* Nothing to do. */
+}
+
+/*
+ * This function does some special set-up for the PCIe boards
+ * PCIe215, PCIe236, PCIe296.
+ */
+static int dio200_pcie_board_setup(struct comedi_device *dev)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ void __iomem *brbase;
+ resource_size_t brlen;
+
+ /*
+ * The board uses Altera Cyclone IV with PCI-Express hard IP.
+ * The FPGA configuration has the PCI-Express Avalon-MM Bridge
+ * Control registers in PCI BAR 0, offset 0, and the length of
+ * these registers is 0x4000.
+ *
+ * We need to write 0x80 to the "Avalon-MM to PCI-Express Interrupt
+ * Enable" register at offset 0x50 to allow generation of PCIe
+ * interrupts when RXmlrq_i is asserted in the SOPC Builder system.
+ */
+ brlen = pci_resource_len(pcidev, 0);
+ if (brlen < 0x4000 ||
+ !(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM)) {
+ dev_err(dev->class_dev, "error! bad PCI region!\n");
+ return -EINVAL;
+ }
+ brbase = ioremap_nocache(pci_resource_start(pcidev, 0), brlen);
+ if (!brbase) {
+ dev_err(dev->class_dev, "error! failed to map registers!\n");
+ return -ENOMEM;
+ }
+ writel(0x80, brbase + 0x50);
+ iounmap(brbase);
+ /* Enable "enhanced" features of board. */
+ dio200_write8(dev, DIO200_ENHANCE, 1);
+ return 0;
+}
+
static void dio200_report_attach(struct comedi_device *dev, unsigned int irq)
{
const struct dio200_board *thisboard = comedi_board(dev);
+ struct dio200_private *devpriv = dev->private;
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
char tmpbuf[60];
int tmplen;
if (is_isa_board(thisboard))
tmplen = scnprintf(tmpbuf, sizeof(tmpbuf),
- "(base %#lx) ", dev->iobase);
+ "(base %#lx) ", devpriv->io.u.iobase);
else if (is_pci_board(thisboard))
tmplen = scnprintf(tmpbuf, sizeof(tmpbuf),
"(pci %s) ", pci_name(pcidev));
@@ -1232,20 +1796,18 @@ static void dio200_report_attach(struct comedi_device *dev, unsigned int irq)
dev_info(dev->class_dev, "%s %sattached\n", dev->board_name, tmpbuf);
}
-static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase,
- unsigned int irq, unsigned long req_irq_flags)
+static int dio200_common_attach(struct comedi_device *dev, unsigned int irq,
+ unsigned long req_irq_flags)
{
const struct dio200_board *thisboard = comedi_board(dev);
struct dio200_private *devpriv = dev->private;
- const struct dio200_layout_struct *layout =
- &dio200_layouts[thisboard->layout];
+ const struct dio200_layout *layout = dio200_board_layout(thisboard);
struct comedi_subdevice *s;
int sdx;
unsigned int n;
int ret;
devpriv->intr_sd = -1;
- dev->iobase = iobase;
dev->board_name = thisboard->name;
ret = comedi_alloc_subdevices(dev, layout->n_subdevs);
@@ -1257,16 +1819,15 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase,
switch (layout->sdtype[n]) {
case sd_8254:
/* counter subdevice (8254) */
- ret = dio200_subdev_8254_init(dev, s, iobase,
- layout->sdinfo[n],
- layout->has_clk_gat_sce);
+ ret = dio200_subdev_8254_init(dev, s,
+ layout->sdinfo[n]);
if (ret < 0)
return ret;
break;
case sd_8255:
/* digital i/o subdevice (8255) */
- ret = subdev_8255_init(dev, s, NULL,
- iobase + layout->sdinfo[n]);
+ ret = dio200_subdev_8255_init(dev, s,
+ layout->sdinfo[n]);
if (ret < 0)
return ret;
break;
@@ -1274,11 +1835,9 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase,
/* 'INTERRUPT' subdevice */
if (irq) {
ret = dio200_subdev_intr_init(dev, s,
- iobase +
DIO200_INT_SCE,
- layout->sdinfo[n],
- layout->
- has_int_sce);
+ layout->sdinfo[n]
+ );
if (ret < 0)
return ret;
devpriv->intr_sd = n;
@@ -1286,6 +1845,16 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase,
s->type = COMEDI_SUBD_UNUSED;
}
break;
+ case sd_timer:
+ /* Only on PCIe boards. */
+ if (DO_PCI) {
+ ret = dio200_subdev_timer_init(dev, s);
+ if (ret < 0)
+ return ret;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ break;
default:
s->type = COMEDI_SUBD_UNUSED;
break;
@@ -1307,24 +1876,6 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase,
return 1;
}
-static int dio200_pci_common_attach(struct comedi_device *dev,
- struct pci_dev *pci_dev)
-{
- unsigned long iobase;
- int ret;
-
- comedi_set_hw_dev(dev, &pci_dev->dev);
-
- ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
- if (ret < 0) {
- dev_err(dev->class_dev,
- "error! cannot enable PCI device and request regions!\n");
- return ret;
- }
- iobase = pci_resource_start(pci_dev, 2);
- return dio200_common_attach(dev, iobase, pci_dev->irq, IRQF_SHARED);
-}
-
/*
* Attach is called by the Comedi core to configure the driver
* for a particular board. If you specified a board_name array
@@ -1334,15 +1885,15 @@ static int dio200_pci_common_attach(struct comedi_device *dev,
static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct dio200_board *thisboard = comedi_board(dev);
+ struct dio200_private *devpriv;
int ret;
dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach\n");
- ret = alloc_private(dev, sizeof(struct dio200_private));
- if (ret < 0) {
- dev_err(dev->class_dev, "error! out of memory!\n");
- return ret;
- }
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
/* Process options and reserve resources according to bus type. */
if (is_isa_board(thisboard)) {
@@ -1351,17 +1902,17 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
iobase = it->options[0];
irq = it->options[1];
- ret = dio200_request_region(dev, iobase, DIO200_IO_SIZE);
+ ret = dio200_request_region(dev, iobase, thisboard->mainsize);
if (ret < 0)
return ret;
- return dio200_common_attach(dev, iobase, irq, 0);
+ devpriv->io.u.iobase = iobase;
+ devpriv->io.regtype = io_regtype;
+ return dio200_common_attach(dev, irq, 0);
} else if (is_pci_board(thisboard)) {
- struct pci_dev *pci_dev;
-
- pci_dev = dio200_find_pci_dev(dev, it);
- if (!pci_dev)
- return -EIO;
- return dio200_pci_common_attach(dev, pci_dev);
+ dev_err(dev->class_dev,
+ "Manual configuration of PCI board '%s' is not supported\n",
+ thisboard->name);
+ return -EIO;
} else {
dev_err(dev->class_dev, DIO200_DRIVER_NAME
": BUG! cannot determine board type!\n");
@@ -1370,13 +1921,18 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
/*
- * The attach_pci hook (if non-NULL) is called at PCI probe time in preference
- * to the "manual" attach hook. dev->board_ptr is NULL on entry. There should
- * be a board entry matching the supplied PCI device.
+ * The auto_attach hook is called at PCI probe time via
+ * comedi_pci_auto_config(). dev->board_ptr is NULL on entry.
+ * There should be a board entry matching the supplied PCI device.
*/
-static int __devinit dio200_attach_pci(struct comedi_device *dev,
- struct pci_dev *pci_dev)
+static int dio200_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
+ const struct dio200_board *thisboard;
+ struct dio200_private *devpriv;
+ resource_size_t base, len;
+ unsigned int bar;
int ret;
if (!DO_PCI)
@@ -1384,38 +1940,71 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev,
dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach pci %s\n",
pci_name(pci_dev));
- ret = alloc_private(dev, sizeof(struct dio200_private));
- if (ret < 0) {
- dev_err(dev->class_dev, "error! out of memory!\n");
- return ret;
- }
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
dev->board_ptr = dio200_find_pci_board(pci_dev);
if (dev->board_ptr == NULL) {
dev_err(dev->class_dev, "BUG! cannot determine board type!\n");
return -EINVAL;
}
- /*
- * Need to 'get' the PCI device to match the 'put' in dio200_detach().
- * TODO: Remove the pci_dev_get() and matching pci_dev_put() once
- * support for manual attachment of PCI devices via dio200_attach()
- * has been removed.
- */
- pci_dev_get(pci_dev);
- return dio200_pci_common_attach(dev, pci_dev);
+ thisboard = comedi_board(dev);
+ ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
+ if (ret < 0) {
+ dev_err(dev->class_dev,
+ "error! cannot enable PCI device and request regions!\n");
+ return ret;
+ }
+ bar = thisboard->mainbar;
+ base = pci_resource_start(pci_dev, bar);
+ len = pci_resource_len(pci_dev, bar);
+ if (len < thisboard->mainsize) {
+ dev_err(dev->class_dev, "error! PCI region size too small!\n");
+ return -EINVAL;
+ }
+ if ((pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) != 0) {
+ devpriv->io.u.membase = ioremap_nocache(base, len);
+ if (!devpriv->io.u.membase) {
+ dev_err(dev->class_dev,
+ "error! cannot remap registers\n");
+ return -ENOMEM;
+ }
+ devpriv->io.regtype = mmio_regtype;
+ } else {
+ devpriv->io.u.iobase = (unsigned long)base;
+ devpriv->io.regtype = io_regtype;
+ }
+ switch (thisboard->model)
+ {
+ case pcie215_model:
+ case pcie236_model:
+ case pcie296_model:
+ ret = dio200_pcie_board_setup(dev);
+ if (ret < 0)
+ return ret;
+ break;
+ default:
+ break;
+ }
+ return dio200_common_attach(dev, pci_dev->irq, IRQF_SHARED);
}
static void dio200_detach(struct comedi_device *dev)
{
const struct dio200_board *thisboard = comedi_board(dev);
- const struct dio200_layout_struct *layout;
+ struct dio200_private *devpriv = dev->private;
+ const struct dio200_layout *layout;
unsigned n;
- if (!thisboard)
+ if (!thisboard || !devpriv)
return;
if (dev->irq)
free_irq(dev->irq, dev);
if (dev->subdevices) {
- layout = &dio200_layouts[thisboard->layout];
+ layout = dio200_board_layout(thisboard);
for (n = 0; n < dev->n_subdevices; n++) {
struct comedi_subdevice *s = &dev->subdevices[n];
switch (layout->sdtype[n]) {
@@ -1423,25 +2012,33 @@ static void dio200_detach(struct comedi_device *dev)
dio200_subdev_8254_cleanup(dev, s);
break;
case sd_8255:
- subdev_8255_cleanup(dev, s);
+ dio200_subdev_8255_cleanup(dev, s);
break;
case sd_intr:
dio200_subdev_intr_cleanup(dev, s);
break;
+ case sd_timer:
+ /* Only on PCIe boards. */
+ if (DO_PCI)
+ dio200_subdev_timer_cleanup(dev, s);
+ break;
default:
break;
}
}
}
if (is_isa_board(thisboard)) {
- if (dev->iobase)
- release_region(dev->iobase, DIO200_IO_SIZE);
+ if (devpriv->io.regtype == io_regtype)
+ release_region(devpriv->io.u.iobase,
+ thisboard->mainsize);
} else if (is_pci_board(thisboard)) {
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
if (pcidev) {
- if (dev->iobase)
+ if (devpriv->io.regtype != no_regtype) {
+ if (devpriv->io.regtype == mmio_regtype)
+ iounmap(devpriv->io.u.membase);
comedi_pci_disable(pcidev);
- pci_dev_put(pcidev);
+ }
}
}
}
@@ -1456,7 +2053,7 @@ static struct comedi_driver amplc_dio200_driver = {
.driver_name = DIO200_DRIVER_NAME,
.module = THIS_MODULE,
.attach = dio200_attach,
- .attach_pci = dio200_attach_pci,
+ .auto_attach = dio200_auto_attach,
.detach = dio200_detach,
.board_name = &dio200_boards[0].name,
.offset = sizeof(struct dio200_board),
@@ -1467,19 +2064,22 @@ static struct comedi_driver amplc_dio200_driver = {
static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE236) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE215) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE296) },
{0}
};
MODULE_DEVICE_TABLE(pci, dio200_pci_table);
-static int __devinit amplc_dio200_pci_probe(struct pci_dev *dev,
+static int amplc_dio200_pci_probe(struct pci_dev *dev,
const struct pci_device_id
*ent)
{
return comedi_pci_auto_config(dev, &amplc_dio200_driver);
}
-static void __devexit amplc_dio200_pci_remove(struct pci_dev *dev)
+static void amplc_dio200_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -1488,7 +2088,7 @@ static struct pci_driver amplc_dio200_pci_driver = {
.name = DIO200_DRIVER_NAME,
.id_table = dio200_pci_table,
.probe = &amplc_dio200_pci_probe,
- .remove = __devexit_p(&amplc_dio200_pci_remove)
+ .remove = &amplc_dio200_pci_remove
};
module_comedi_pci_driver(amplc_dio200_driver, amplc_dio200_pci_driver);
#else
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c
index 4e4f3c15df8..28983541957 100644
--- a/drivers/staging/comedi/drivers/amplc_pc236.c
+++ b/drivers/staging/comedi/drivers/amplc_pc236.c
@@ -66,7 +66,6 @@ unused.
#define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI)
/* PCI236 PCI configuration register information */
-#define PCI_VENDOR_ID_AMPLICON 0x14dc
#define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009
#define PCI_DEVICE_ID_INVALID 0xffff
@@ -332,28 +331,13 @@ static int pc236_intr_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: */
+ /* Step 3: check it arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
- if (cmd->scan_end_arg != 1) {
- cmd->scan_end_arg = 1;
- err++;
- }
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ 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;
@@ -505,14 +489,16 @@ static int pc236_pci_common_attach(struct comedi_device *dev,
static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct pc236_board *thisboard = comedi_board(dev);
+ struct pc236_private *devpriv;
int ret;
dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach\n");
- ret = alloc_private(dev, sizeof(struct pc236_private));
- if (ret < 0) {
- dev_err(dev->class_dev, "error! out of memory!\n");
- return ret;
- }
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
/* Process options according to bus type. */
if (is_isa_board(thisboard)) {
unsigned long iobase = it->options[0];
@@ -536,25 +522,27 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
/*
- * The attach_pci hook (if non-NULL) is called at PCI probe time in preference
- * to the "manual" attach hook. dev->board_ptr is NULL on entry. There should
- * be a board entry matching the supplied PCI device.
+ * The auto_attach hook is called at PCI probe time via
+ * comedi_pci_auto_config(). dev->board_ptr is NULL on entry.
+ * There should be a board entry matching the supplied PCI device.
*/
-static int __devinit pc236_attach_pci(struct comedi_device *dev,
- struct pci_dev *pci_dev)
+static int pc236_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
- int ret;
+ struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
+ struct pc236_private *devpriv;
if (!DO_PCI)
return -EINVAL;
dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach pci %s\n",
pci_name(pci_dev));
- ret = alloc_private(dev, sizeof(struct pc236_private));
- if (ret < 0) {
- dev_err(dev->class_dev, "error! out of memory!\n");
- return ret;
- }
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
dev->board_ptr = pc236_find_pci_board(pci_dev);
if (dev->board_ptr == NULL) {
dev_err(dev->class_dev, "BUG! cannot determine board type!\n");
@@ -605,7 +593,7 @@ static struct comedi_driver amplc_pc236_driver = {
.driver_name = PC236_DRIVER_NAME,
.module = THIS_MODULE,
.attach = pc236_attach,
- .attach_pci = pc236_attach_pci,
+ .auto_attach = pc236_auto_attach,
.detach = pc236_detach,
.board_name = &pc236_boards[0].name,
.offset = sizeof(struct pc236_board),
@@ -620,13 +608,13 @@ static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = {
MODULE_DEVICE_TABLE(pci, pc236_pci_table);
-static int __devinit amplc_pc236_pci_probe(struct pci_dev *dev,
+static int amplc_pc236_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &amplc_pc236_driver);
}
-static void __devexit amplc_pc236_pci_remove(struct pci_dev *dev)
+static void amplc_pc236_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -635,7 +623,7 @@ static struct pci_driver amplc_pc236_pci_driver = {
.name = PC236_DRIVER_NAME,
.id_table = pc236_pci_table,
.probe = &amplc_pc236_pci_probe,
- .remove = __devexit_p(&amplc_pc236_pci_remove)
+ .remove = &amplc_pc236_pci_remove
};
module_comedi_pci_driver(amplc_pc236_driver, amplc_pc236_pci_driver);
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c
index d0a4c441228..dfbff77cd79 100644
--- a/drivers/staging/comedi/drivers/amplc_pc263.c
+++ b/drivers/staging/comedi/drivers/amplc_pc263.c
@@ -52,7 +52,6 @@ The state of the outputs can be read.
#define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI)
/* PCI263 PCI configuration register information */
-#define PCI_VENDOR_ID_AMPLICON 0x14dc
#define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c
#define PCI_DEVICE_ID_INVALID 0xffff
@@ -291,17 +290,21 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return -EINVAL;
}
}
+
/*
- * The attach_pci hook (if non-NULL) is called at PCI probe time in preference
- * to the "manual" attach hook. dev->board_ptr is NULL on entry. There should
- * be a board entry matching the supplied PCI device.
+ * The auto_attach hook is called at PCI probe time via
+ * comedi_pci_auto_config(). dev->board_ptr is NULL on entry.
+ * There should be a board entry matching the supplied PCI device.
*/
-static int __devinit pc263_attach_pci(struct comedi_device *dev,
- struct pci_dev *pci_dev)
+static int pc263_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pci_dev;
+
if (!DO_PCI)
return -EINVAL;
+ pci_dev = comedi_to_pci_dev(dev);
dev_info(dev->class_dev, PC263_DRIVER_NAME ": attach pci %s\n",
pci_name(pci_dev));
dev->board_ptr = pc263_find_pci_board(pci_dev);
@@ -348,7 +351,7 @@ static struct comedi_driver amplc_pc263_driver = {
.driver_name = PC263_DRIVER_NAME,
.module = THIS_MODULE,
.attach = pc263_attach,
- .attach_pci = pc263_attach_pci,
+ .auto_attach = pc263_auto_attach,
.detach = pc263_detach,
.board_name = &pc263_boards[0].name,
.offset = sizeof(struct pc263_board),
@@ -362,14 +365,14 @@ static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = {
};
MODULE_DEVICE_TABLE(pci, pc263_pci_table);
-static int __devinit amplc_pc263_pci_probe(struct pci_dev *dev,
+static int amplc_pc263_pci_probe(struct pci_dev *dev,
const struct pci_device_id
*ent)
{
return comedi_pci_auto_config(dev, &amplc_pc263_driver);
}
-static void __devexit amplc_pc263_pci_remove(struct pci_dev *dev)
+static void amplc_pc263_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -378,7 +381,7 @@ static struct pci_driver amplc_pc263_pci_driver = {
.name = PC263_DRIVER_NAME,
.id_table = pc263_pci_table,
.probe = &amplc_pc263_pci_probe,
- .remove = __devexit_p(&amplc_pc263_pci_remove)
+ .remove = &amplc_pc263_pci_remove
};
module_comedi_pci_driver(amplc_pc263_driver, amplc_pc263_pci_driver);
#else
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c
index 1f65ec4d261..6e2566a2dd5 100644
--- a/drivers/staging/comedi/drivers/amplc_pci224.c
+++ b/drivers/staging/comedi/drivers/amplc_pci224.c
@@ -116,7 +116,6 @@ Caveats:
/*
* PCI IDs.
*/
-#define PCI_VENDOR_ID_AMPLICON 0x14dc
#define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
#define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
#define PCI_DEVICE_ID_INVALID 0xffff
@@ -758,76 +757,58 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if (err)
return 2;
- /* Step 3: make sure arguments are trivially compatible. */
+ /* Step 3: check if arguments are trivially valid */
switch (cmd->start_src) {
case TRIG_INT:
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
break;
case TRIG_EXT:
/* Force to external trigger 0. */
if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
cmd->start_arg = COMBINE(cmd->start_arg, 0,
~CR_FLAGS_MASK);
- err++;
+ err |= -EINVAL;
}
/* The only flag allowed is CR_EDGE, which is ignored. */
if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
cmd->start_arg = COMBINE(cmd->start_arg, 0,
CR_FLAGS_MASK & ~CR_EDGE);
- err++;
+ err |= -EINVAL;
}
break;
}
switch (cmd->scan_begin_src) {
case TRIG_TIMER:
- if (cmd->scan_begin_arg > MAX_SCAN_PERIOD) {
- cmd->scan_begin_arg = MAX_SCAN_PERIOD;
- err++;
- }
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
+ MAX_SCAN_PERIOD);
+
tmp = cmd->chanlist_len * CONVERT_PERIOD;
if (tmp < MIN_SCAN_PERIOD)
tmp = MIN_SCAN_PERIOD;
-
- if (cmd->scan_begin_arg < tmp) {
- cmd->scan_begin_arg = tmp;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, tmp);
break;
case TRIG_EXT:
/* Force to external trigger 0. */
if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
~CR_FLAGS_MASK);
- err++;
+ err |= -EINVAL;
}
/* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
~(CR_EDGE | CR_INVERT)) != 0) {
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
- CR_FLAGS_MASK & ~(CR_EDGE
- |
- CR_INVERT));
- err++;
+ CR_FLAGS_MASK &
+ ~(CR_EDGE | CR_INVERT));
+ err |= -EINVAL;
}
break;
}
- /* cmd->convert_src == TRIG_NOW */
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
-
- /* cmd->scan_end_arg == TRIG_COUNT */
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
switch (cmd->stop_src) {
case TRIG_COUNT:
@@ -838,7 +819,7 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
~CR_FLAGS_MASK);
- err++;
+ err |= -EINVAL;
}
/* The only flag allowed is CR_EDGE, which is ignored. */
if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
@@ -847,10 +828,7 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
}
break;
case TRIG_NONE:
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
break;
}
@@ -1287,7 +1265,7 @@ static void pci224_report_attach(struct comedi_device *dev, unsigned int irq)
}
/*
- * Common part of attach and attach_pci.
+ * Common part of attach and auto_attach.
*/
static int pci224_attach_common(struct comedi_device *dev,
struct pci_dev *pci_dev, int *options)
@@ -1443,16 +1421,15 @@ static int pci224_attach_common(struct comedi_device *dev,
static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ struct pci224_private *devpriv;
struct pci_dev *pci_dev;
- int ret;
dev_info(dev->class_dev, DRIVER_NAME ": attach\n");
- ret = alloc_private(dev, sizeof(struct pci224_private));
- if (ret < 0) {
- dev_err(dev->class_dev, "error! out of memory!\n");
- return ret;
- }
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
pci_dev = pci224_find_pci_dev(dev, it);
if (!pci_dev)
@@ -1461,19 +1438,19 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return pci224_attach_common(dev, pci_dev, it->options);
}
-static int __devinit
-pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev)
+static int
+pci224_auto_attach(struct comedi_device *dev, unsigned long context_unused)
{
- int ret;
+ struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
+ struct pci224_private *devpriv;
- dev_info(dev->class_dev, DRIVER_NAME ": attach_pci %s\n",
+ dev_info(dev->class_dev, DRIVER_NAME ": attach pci %s\n",
pci_name(pci_dev));
- ret = alloc_private(dev, sizeof(struct pci224_private));
- if (ret < 0) {
- dev_err(dev->class_dev, "error! out of memory!\n");
- return ret;
- }
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
dev->board_ptr = pci224_find_pci_board(pci_dev);
if (dev->board_ptr == NULL) {
@@ -1522,20 +1499,20 @@ static struct comedi_driver amplc_pci224_driver = {
.module = THIS_MODULE,
.attach = pci224_attach,
.detach = pci224_detach,
- .attach_pci = pci224_attach_pci,
+ .auto_attach = pci224_auto_attach,
.board_name = &pci224_boards[0].name,
.offset = sizeof(struct pci224_board),
.num_names = ARRAY_SIZE(pci224_boards),
};
-static int __devinit amplc_pci224_pci_probe(struct pci_dev *dev,
+static int amplc_pci224_pci_probe(struct pci_dev *dev,
const struct pci_device_id
*ent)
{
return comedi_pci_auto_config(dev, &amplc_pci224_driver);
}
-static void __devexit amplc_pci224_pci_remove(struct pci_dev *dev)
+static void amplc_pci224_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -1551,7 +1528,7 @@ static struct pci_driver amplc_pci224_pci_driver = {
.name = "amplc_pci224",
.id_table = amplc_pci224_pci_table,
.probe = amplc_pci224_pci_probe,
- .remove = __devexit_p(amplc_pci224_pci_remove),
+ .remove = amplc_pci224_pci_remove,
};
module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver);
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c
index bd8fb876ce2..366c68be56b 100644
--- a/drivers/staging/comedi/drivers/amplc_pci230.c
+++ b/drivers/staging/comedi/drivers/amplc_pci230.c
@@ -198,7 +198,6 @@ for (or detection of) various hardware problems added by Ian Abbott.
#include "8255.h"
/* PCI230 PCI configuration register information */
-#define PCI_VENDOR_ID_AMPLICON 0x14dc
#define PCI_DEVICE_ID_PCI230 0x0000
#define PCI_DEVICE_ID_PCI260 0x0006
#define PCI_DEVICE_ID_INVALID 0xffff
@@ -1000,14 +999,10 @@ static int pci230_ao_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* Step 3: make sure arguments are trivially compatible.
- * "invalid argument" returned by comedilib to user mode process
- * if this fails. */
+ /* Step 3: check if arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
#define MAX_SPEED_AO 8000 /* 8000 ns => 125 kHz */
#define MIN_SPEED_AO 4294967295u /* 4294967295ns = 4.29s */
/*- Comedi limit due to unsigned int cmd. Driver limit
@@ -1016,14 +1011,10 @@ static int pci230_ao_cmdtest(struct comedi_device *dev,
switch (cmd->scan_begin_src) {
case TRIG_TIMER:
- if (cmd->scan_begin_arg < MAX_SPEED_AO) {
- cmd->scan_begin_arg = MAX_SPEED_AO;
- err++;
- }
- if (cmd->scan_begin_arg > MIN_SPEED_AO) {
- cmd->scan_begin_arg = MIN_SPEED_AO;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ MAX_SPEED_AO);
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
+ MIN_SPEED_AO);
break;
case TRIG_EXT:
/* External trigger - for PCI230+ hardware version 2 onwards. */
@@ -1031,37 +1022,27 @@ static int pci230_ao_cmdtest(struct comedi_device *dev,
if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
~CR_FLAGS_MASK);
- err++;
+ err |= -EINVAL;
}
/* The only flags allowed are CR_EDGE and CR_INVERT. The
* CR_EDGE flag is ignored. */
if ((cmd->scan_begin_arg
& (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
- cmd->scan_begin_arg =
- COMBINE(cmd->scan_begin_arg, 0,
- CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
- err++;
+ cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+ CR_FLAGS_MASK &
+ ~(CR_EDGE | CR_INVERT));
+ err |= -EINVAL;
}
break;
default:
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
break;
}
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_NONE) {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ if (cmd->stop_src == TRIG_NONE)
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -1619,14 +1600,10 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* Step 3: make sure arguments are trivially compatible.
- * "invalid argument" returned by comedilib to user mode process
- * if this fails. */
+ /* Step 3: check if arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
#define MAX_SPEED_AI_SE 3200 /* PCI230 SE: 3200 ns => 312.5 kHz */
#define MAX_SPEED_AI_DIFF 8000 /* PCI230 DIFF: 8000 ns => 125 kHz */
#define MAX_SPEED_AI_PLUS 4000 /* PCI230+: 4000 ns => 250 kHz */
@@ -1657,14 +1634,10 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
max_speed_ai = MAX_SPEED_AI_PLUS;
}
- if (cmd->convert_arg < max_speed_ai) {
- cmd->convert_arg = max_speed_ai;
- err++;
- }
- if (cmd->convert_arg > MIN_SPEED_AI) {
- cmd->convert_arg = MIN_SPEED_AI;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ max_speed_ai);
+ err |= cfc_check_trigger_arg_max(&cmd->convert_arg,
+ MIN_SPEED_AI);
} else if (cmd->convert_src == TRIG_EXT) {
/*
* external trigger
@@ -1679,46 +1652,33 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
if ((cmd->convert_arg & ~CR_FLAGS_MASK) != 0) {
cmd->convert_arg = COMBINE(cmd->convert_arg, 0,
~CR_FLAGS_MASK);
- err++;
+ err |= -EINVAL;
}
/* The only flags allowed are CR_INVERT and CR_EDGE.
* CR_EDGE is required. */
if ((cmd->convert_arg & (CR_FLAGS_MASK & ~CR_INVERT))
!= CR_EDGE) {
/* Set CR_EDGE, preserve CR_INVERT. */
- cmd->convert_arg =
- COMBINE(cmd->start_arg, (CR_EDGE | 0),
- CR_FLAGS_MASK & ~CR_INVERT);
- err++;
+ cmd->convert_arg = COMBINE(cmd->start_arg,
+ (CR_EDGE | 0),
+ CR_FLAGS_MASK &
+ ~CR_INVERT);
+ err |= -EINVAL;
}
} else {
/* Backwards compatibility with previous versions. */
/* convert_arg == 0 => trigger on -ve edge. */
/* convert_arg == 1 => trigger on +ve edge. */
- if (cmd->convert_arg > 1) {
- /* Default to trigger on +ve edge. */
- cmd->convert_arg = 1;
- err++;
- }
+ err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 1);
}
} else {
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
}
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
- if (cmd->stop_src == TRIG_NONE) {
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ if (cmd->stop_src == TRIG_NONE)
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (cmd->scan_begin_src == TRIG_EXT) {
/* external "trigger" to begin each scan
@@ -1727,24 +1687,21 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
~CR_FLAGS_MASK);
- err++;
+ err |= -EINVAL;
}
/* The only flag allowed is CR_EDGE, which is ignored. */
if ((cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
CR_FLAGS_MASK & ~CR_EDGE);
- err++;
+ err |= -EINVAL;
}
} else if (cmd->scan_begin_src == TRIG_TIMER) {
/* N.B. cmd->convert_arg is also TRIG_TIMER */
if (!pci230_ai_check_scan_period(cmd))
- err++;
+ err |= -EINVAL;
} else {
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
}
if (err)
@@ -2660,15 +2617,12 @@ static struct pci_dev *pci230_find_pci_dev(struct comedi_device *dev,
static int pci230_alloc_private(struct comedi_device *dev)
{
struct pci230_private *devpriv;
- int err;
- /* sets dev->private to allocated memory */
- err = alloc_private(dev, sizeof(struct pci230_private));
- if (err) {
- dev_err(dev->class_dev, "error! out of memory!\n");
- return err;
- }
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
spin_lock_init(&devpriv->isr_spinlock);
spin_lock_init(&devpriv->res_spinlock);
spin_lock_init(&devpriv->ai_stop_spinlock);
@@ -2676,7 +2630,7 @@ static int pci230_alloc_private(struct comedi_device *dev)
return 0;
}
-/* Common part of attach and attach_pci. */
+/* Common part of attach and auto_attach. */
static int pci230_attach_common(struct comedi_device *dev,
struct pci_dev *pci_dev)
{
@@ -2836,25 +2790,30 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
dev_info(dev->class_dev, "amplc_pci230: attach %s %d,%d\n",
thisboard->name, it->options[0], it->options[1]);
- rc = pci230_alloc_private(dev); /* sets dev->private */
+
+ rc = pci230_alloc_private(dev);
if (rc)
return rc;
+
pci_dev = pci230_find_pci_dev(dev, it);
if (!pci_dev)
return -EIO;
return pci230_attach_common(dev, pci_dev);
}
-static int __devinit pci230_attach_pci(struct comedi_device *dev,
- struct pci_dev *pci_dev)
+static int pci230_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
int rc;
dev_info(dev->class_dev, "amplc_pci230: attach pci %s\n",
pci_name(pci_dev));
- rc = pci230_alloc_private(dev); /* sets dev->private */
+
+ rc = pci230_alloc_private(dev);
if (rc)
return rc;
+
dev->board_ptr = pci230_find_pci_board(pci_dev);
if (dev->board_ptr == NULL) {
dev_err(dev->class_dev,
@@ -2891,20 +2850,20 @@ static struct comedi_driver amplc_pci230_driver = {
.driver_name = "amplc_pci230",
.module = THIS_MODULE,
.attach = pci230_attach,
- .attach_pci = pci230_attach_pci,
+ .auto_attach = pci230_auto_attach,
.detach = pci230_detach,
.board_name = &pci230_boards[0].name,
.offset = sizeof(pci230_boards[0]),
.num_names = ARRAY_SIZE(pci230_boards),
};
-static int __devinit amplc_pci230_pci_probe(struct pci_dev *dev,
+static int amplc_pci230_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &amplc_pci230_driver);
}
-static void __devexit amplc_pci230_pci_remove(struct pci_dev *dev)
+static void amplc_pci230_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -2920,7 +2879,7 @@ static struct pci_driver amplc_pci230_pci_driver = {
.name = "amplc_pci230",
.id_table = amplc_pci230_pci_table,
.probe = amplc_pci230_pci_probe,
- .remove = __devexit_p(amplc_pci230_pci_remove)
+ .remove = amplc_pci230_pci_remove
};
module_comedi_pci_driver(amplc_pci230_driver, amplc_pci230_pci_driver);
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
index 6d81d8b40cc..93731de1f2b 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -194,67 +194,41 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
#define MAX_SPEED 10000 /* in nanoseconds */
#define MIN_SPEED 1000000000 /* in nanoseconds */
if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->scan_begin_arg < MAX_SPEED) {
- cmd->scan_begin_arg = MAX_SPEED;
- err++;
- }
- if (cmd->scan_begin_arg > MIN_SPEED) {
- cmd->scan_begin_arg = MIN_SPEED;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ MAX_SPEED);
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
+ MIN_SPEED);
} else {
/* external trigger */
/* should be level/edge, hi/lo specification here */
/* should specify multiple external triggers */
- if (cmd->scan_begin_arg > 9) {
- cmd->scan_begin_arg = 9;
- err++;
- }
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
}
if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < MAX_SPEED) {
- cmd->convert_arg = MAX_SPEED;
- err++;
- }
- if (cmd->convert_arg > MIN_SPEED) {
- cmd->convert_arg = MIN_SPEED;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ MAX_SPEED);
+ err |= cfc_check_trigger_arg_max(&cmd->convert_arg,
+ MIN_SPEED);
} else {
/* external trigger */
/* see above */
- if (cmd->convert_arg > 9) {
- cmd->convert_arg = 9;
- err++;
- }
+ err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9);
}
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) {
- if (cmd->stop_arg > 0x00ffffff) {
- cmd->stop_arg = 0x00ffffff;
- err++;
- }
- } else {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -428,6 +402,7 @@ static int das16cs_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
const struct das16cs_board *thisboard;
+ struct das16cs_private *devpriv;
struct pcmcia_device *link;
struct comedi_subdevice *s;
int ret;
@@ -451,8 +426,10 @@ static int das16cs_attach(struct comedi_device *dev,
return ret;
dev->irq = link->irq;
- if (alloc_private(dev, sizeof(struct das16cs_private)) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_alloc_subdevices(dev, 3);
if (ret)
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
index de21a261ff4..aed68639cc9 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -76,9 +76,6 @@ analog triggering on 1602 series
#include "amcc_s5933.h"
#include "comedi_fc.h"
-/* PCI vendor number of ComputerBoards/MeasurementComputing */
-#define PCI_VENDOR_ID_CB 0x1307
-
#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 */
@@ -843,49 +840,32 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
/* External trigger, only CR_EDGE and CR_INVERT flags allowed */
if ((cmd->start_arg
& (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
- cmd->start_arg &=
- ~(CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
- err++;
+ cmd->start_arg &= ~(CR_FLAGS_MASK &
+ ~(CR_EDGE | CR_INVERT));
+ err |= -EINVAL;
}
if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) {
cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
- err++;
+ err |= -EINVAL;
}
break;
default:
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
break;
}
- if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->scan_begin_arg <
- thisboard->ai_speed * cmd->chanlist_len) {
- cmd->scan_begin_arg =
- thisboard->ai_speed * cmd->chanlist_len;
- err++;
- }
- }
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < thisboard->ai_speed) {
- cmd->convert_arg = thisboard->ai_speed;
- err++;
- }
- }
+ if (cmd->scan_begin_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ thisboard->ai_speed * cmd->chanlist_len);
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_NONE) {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ thisboard->ai_speed);
+
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ if (cmd->stop_src == TRIG_NONE)
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -1078,31 +1058,18 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->scan_begin_arg < thisboard->ao_scan_speed) {
- cmd->scan_begin_arg = thisboard->ao_scan_speed;
- err++;
- }
- }
+ if (cmd->scan_begin_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ thisboard->ao_scan_speed);
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_NONE) {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ if (cmd->stop_src == TRIG_NONE)
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -1469,27 +1436,26 @@ static const void *cb_pcidas_find_boardinfo(struct comedi_device *dev,
return NULL;
}
-static int cb_pcidas_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int cb_pcidas_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct cb_pcidas_board *thisboard;
struct cb_pcidas_private *devpriv;
struct comedi_subdevice *s;
int i;
int ret;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
thisboard = cb_pcidas_find_boardinfo(dev, pcidev);
if (!thisboard)
return -ENODEV;
dev->board_ptr = thisboard;
dev->board_name = thisboard->name;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret)
@@ -1656,17 +1622,17 @@ static void cb_pcidas_detach(struct comedi_device *dev)
static struct comedi_driver cb_pcidas_driver = {
.driver_name = "cb_pcidas",
.module = THIS_MODULE,
- .attach_pci = cb_pcidas_attach_pci,
+ .auto_attach = cb_pcidas_auto_attach,
.detach = cb_pcidas_detach,
};
-static int __devinit cb_pcidas_pci_probe(struct pci_dev *dev,
+static int cb_pcidas_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &cb_pcidas_driver);
}
-static void __devexit cb_pcidas_pci_remove(struct pci_dev *dev)
+static void cb_pcidas_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -1688,7 +1654,7 @@ static struct pci_driver cb_pcidas_pci_driver = {
.name = "cb_pcidas",
.id_table = cb_pcidas_pci_table,
.probe = cb_pcidas_pci_probe,
- .remove = __devexit_p(cb_pcidas_pci_remove)
+ .remove = cb_pcidas_pci_remove
};
module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
index 0472a9088ab..d72b46cc06b 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -36,53 +36,57 @@
************************************************************************/
/*
-
-Driver: cb_pcidas64
-Description: MeasurementComputing PCI-DAS64xx, 60XX, and 4020 series with the PLX 9080 PCI controller
-Author: Frank Mori Hess <fmhess@users.sourceforge.net>
-Status: works
-Updated: 2002-10-09
-Devices: [Measurement Computing] PCI-DAS6402/16 (cb_pcidas64),
- PCI-DAS6402/12, PCI-DAS64/M1/16, PCI-DAS64/M2/16,
- PCI-DAS64/M3/16, PCI-DAS6402/16/JR, PCI-DAS64/M1/16/JR,
- PCI-DAS64/M2/16/JR, PCI-DAS64/M3/16/JR, PCI-DAS64/M1/14,
- PCI-DAS64/M2/14, PCI-DAS64/M3/14, PCI-DAS6013, PCI-DAS6014,
- PCI-DAS6023, PCI-DAS6025, PCI-DAS6030,
- PCI-DAS6031, PCI-DAS6032, PCI-DAS6033, PCI-DAS6034,
- PCI-DAS6035, PCI-DAS6036, PCI-DAS6040, PCI-DAS6052,
- PCI-DAS6070, PCI-DAS6071, PCI-DAS4020/12
-
-Configuration options:
- [0] - PCI bus of device (optional)
- [1] - PCI slot of device (optional)
-
-These boards may be autocalibrated with the comedi_calibrate utility.
-
-To select the bnc trigger input on the 4020 (instead of the dio input),
-specify a nonzero channel in the chanspec. If you wish to use an external
-master clock on the 4020, you may do so by setting the scan_begin_src
-to TRIG_OTHER, and using an INSN_CONFIG_TIMER_1 configuration insn
-to configure the divisor to use for the external clock.
-
-Some devices are not identified because the PCI device IDs are not yet
-known. If you have such a board, please file a bug report at
-https://bugs.comedi.org.
-
-*/
+ * Driver: cb_pcidas64
+ * Description: MeasurementComputing PCI-DAS64xx, 60XX, and 4020 series
+ * with the PLX 9080 PCI controller
+ * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+ * Status: works
+ * Updated: Fri, 02 Nov 2012 18:58:55 +0000
+ * Devices: [Measurement Computing] PCI-DAS6402/16 (cb_pcidas64),
+ * PCI-DAS6402/12, PCI-DAS64/M1/16, PCI-DAS64/M2/16,
+ * PCI-DAS64/M3/16, PCI-DAS6402/16/JR, PCI-DAS64/M1/16/JR,
+ * PCI-DAS64/M2/16/JR, PCI-DAS64/M3/16/JR, PCI-DAS64/M1/14,
+ * PCI-DAS64/M2/14, PCI-DAS64/M3/14, PCI-DAS6013, PCI-DAS6014,
+ * PCI-DAS6023, PCI-DAS6025, PCI-DAS6030,
+ * PCI-DAS6031, PCI-DAS6032, PCI-DAS6033, PCI-DAS6034,
+ * PCI-DAS6035, PCI-DAS6036, PCI-DAS6040, PCI-DAS6052,
+ * PCI-DAS6070, PCI-DAS6071, PCI-DAS4020/12
+ *
+ * Configuration options:
+ * None.
+ *
+ * Manual attachment of PCI cards with the comedi_config utility is not
+ * supported by this driver; they are attached automatically.
+ *
+ * These boards may be autocalibrated with the comedi_calibrate utility.
+ *
+ * To select the bnc trigger input on the 4020 (instead of the dio input),
+ * specify a nonzero channel in the chanspec. If you wish to use an external
+ * master clock on the 4020, you may do so by setting the scan_begin_src
+ * to TRIG_OTHER, and using an INSN_CONFIG_TIMER_1 configuration insn
+ * to configure the divisor to use for the external clock.
+ *
+ * Some devices are not identified because the PCI device IDs are not yet
+ * known. If you have such a board, please let the maintainers know.
+ */
/*
TODO:
make it return error if user attempts an ai command that uses the
- external queue, and an ao command simultaneously
- user counter subdevice
+ external queue, and an ao command simultaneously user counter subdevice
there are a number of boards this driver will support when they are
- fully released, but does not yet since the pci device id numbers
- are not yet available.
- support prescaled 100khz clock for slow pacing (not available on 6000 series?)
+ fully released, but does not yet since the pci device id numbers
+ are not yet available.
+
+ support prescaled 100khz clock for slow pacing (not available on 6000
+ series?)
+
make ao fifo size adjustable like ai fifo
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "../comedidev.h"
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -96,17 +100,17 @@ TODO:
/* #define PCIDAS64_DEBUG enable debugging code */
#ifdef PCIDAS64_DEBUG
-#define DEBUG_PRINT(format, args...) printk(format , ## args)
+#define DEBUG_PRINT(format, args...) pr_debug(format, ## args)
#else
-#define DEBUG_PRINT(format, args...)
+#define DEBUG_PRINT(format, args...) no_printk(format, ## args)
#endif
#define TIMER_BASE 25 /* 40MHz master clock */
-#define PRESCALED_TIMER_BASE 10000 /* 100kHz 'prescaled' clock for slow acquisition, maybe I'll support this someday */
+/* 100kHz 'prescaled' clock for slow acquisition,
+ * maybe I'll support this someday */
+#define PRESCALED_TIMER_BASE 10000
#define DMA_BUFFER_SIZE 0x1000
-#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307
-
/* maximum value that can be loaded into board's 24-bit counters*/
static const int max_counter_value = 0xffffff;
@@ -119,7 +123,7 @@ enum base_address_regions {
DIO_COUNTER_BADDRINDEX = 3,
};
-/* priv(dev)->main_iobase registers */
+/* devpriv->main_iobase registers */
enum write_only_registers {
INTR_ENABLE_REG = 0x0, /* interrupt enable register */
HW_CONFIG_REG = 0x2, /* hardware config register */
@@ -128,26 +132,36 @@ enum write_only_registers {
ADC_CONTROL0_REG = 0x10, /* adc control register 0 */
ADC_CONTROL1_REG = 0x12, /* adc control register 1 */
CALIBRATION_REG = 0x14,
- ADC_SAMPLE_INTERVAL_LOWER_REG = 0x16, /* lower 16 bits of adc sample interval counter */
- ADC_SAMPLE_INTERVAL_UPPER_REG = 0x18, /* upper 8 bits of adc sample interval counter */
- ADC_DELAY_INTERVAL_LOWER_REG = 0x1a, /* lower 16 bits of delay interval counter */
- ADC_DELAY_INTERVAL_UPPER_REG = 0x1c, /* upper 8 bits of delay interval counter */
- ADC_COUNT_LOWER_REG = 0x1e, /* lower 16 bits of hardware conversion/scan counter */
- ADC_COUNT_UPPER_REG = 0x20, /* upper 8 bits of hardware conversion/scan counter */
+ /* lower 16 bits of adc sample interval counter */
+ ADC_SAMPLE_INTERVAL_LOWER_REG = 0x16,
+ /* upper 8 bits of adc sample interval counter */
+ ADC_SAMPLE_INTERVAL_UPPER_REG = 0x18,
+ /* lower 16 bits of delay interval counter */
+ ADC_DELAY_INTERVAL_LOWER_REG = 0x1a,
+ /* upper 8 bits of delay interval counter */
+ ADC_DELAY_INTERVAL_UPPER_REG = 0x1c,
+ /* lower 16 bits of hardware conversion/scan counter */
+ ADC_COUNT_LOWER_REG = 0x1e,
+ /* upper 8 bits of hardware conversion/scan counter */
+ ADC_COUNT_UPPER_REG = 0x20,
ADC_START_REG = 0x22, /* software trigger to start acquisition */
ADC_CONVERT_REG = 0x24, /* initiates single conversion */
ADC_QUEUE_CLEAR_REG = 0x26, /* clears adc queue */
ADC_QUEUE_LOAD_REG = 0x28, /* loads adc queue */
ADC_BUFFER_CLEAR_REG = 0x2a,
- ADC_QUEUE_HIGH_REG = 0x2c, /* high channel for internal queue, use adc_chan_bits() inline above */
+ /* high channel for internal queue, use adc_chan_bits() inline above */
+ ADC_QUEUE_HIGH_REG = 0x2c,
DAC_CONTROL0_REG = 0x50, /* dac control register 0 */
DAC_CONTROL1_REG = 0x52, /* dac control register 0 */
- DAC_SAMPLE_INTERVAL_LOWER_REG = 0x54, /* lower 16 bits of dac sample interval counter */
- DAC_SAMPLE_INTERVAL_UPPER_REG = 0x56, /* upper 8 bits of dac sample interval counter */
+ /* lower 16 bits of dac sample interval counter */
+ DAC_SAMPLE_INTERVAL_LOWER_REG = 0x54,
+ /* upper 8 bits of dac sample interval counter */
+ DAC_SAMPLE_INTERVAL_UPPER_REG = 0x56,
DAC_SELECT_REG = 0x60,
DAC_START_REG = 0x64,
DAC_BUFFER_CLEAR_REG = 0x66, /* clear dac buffer */
};
+
static inline unsigned int dac_convert_reg(unsigned int channel)
{
return 0x70 + (2 * (channel & 0x1));
@@ -164,7 +178,9 @@ static inline unsigned int dac_msb_4020_reg(unsigned int channel)
}
enum read_only_registers {
- HW_STATUS_REG = 0x0, /* hardware status register, reading this apparently clears pending interrupts as well */
+ /* hardware status register,
+ * reading this apparently clears pending interrupts as well */
+ HW_STATUS_REG = 0x0,
PIPE1_READ_REG = 0x4,
ADC_READ_PNTR_REG = 0x8,
LOWER_XFER_REG = 0x10,
@@ -174,12 +190,14 @@ enum read_only_registers {
enum read_write_registers {
I8255_4020_REG = 0x48, /* 8255 offset, for 4020 only */
- ADC_QUEUE_FIFO_REG = 0x100, /* external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG */
+ /* external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG */
+ ADC_QUEUE_FIFO_REG = 0x100,
ADC_FIFO_REG = 0x200, /* adc data fifo */
- DAC_FIFO_REG = 0x300, /* dac data fifo, has weird interactions with external channel queue */
+ /* dac data fifo, has weird interactions with external channel queue */
+ DAC_FIFO_REG = 0x300,
};
-/* priv(dev)->dio_counter_iobase registers */
+/* devpriv->dio_counter_iobase registers */
enum dio_counter_registers {
DIO_8255_OFFSET = 0x0,
DO_REG = 0x20,
@@ -191,13 +209,13 @@ enum dio_counter_registers {
/* bit definitions for write-only registers */
enum intr_enable_contents {
- ADC_INTR_SRC_MASK = 0x3, /* bits that set adc interrupt source */
- ADC_INTR_QFULL_BITS = 0x0, /* interrupt fifo quater full */
+ ADC_INTR_SRC_MASK = 0x3, /* adc interrupt source mask */
+ ADC_INTR_QFULL_BITS = 0x0, /* interrupt fifo quarter full */
ADC_INTR_EOC_BITS = 0x1, /* interrupt end of conversion */
ADC_INTR_EOSCAN_BITS = 0x2, /* interrupt end of scan */
- ADC_INTR_EOSEQ_BITS = 0x3, /* interrupt end of sequence (probably wont use this it's pretty fancy) */
+ ADC_INTR_EOSEQ_BITS = 0x3, /* interrupt end of sequence mask */
EN_ADC_INTR_SRC_BIT = 0x4, /* enable adc interrupt source */
- EN_ADC_DONE_INTR_BIT = 0x8, /* enable adc acquisition done interrupt */
+ EN_ADC_DONE_INTR_BIT = 0x8, /* enable adc acquisition done intr */
DAC_INTR_SRC_MASK = 0x30,
DAC_INTR_QEMPTY_BITS = 0x0,
DAC_INTR_HIGH_CHAN_BITS = 0x10,
@@ -211,25 +229,33 @@ enum intr_enable_contents {
};
enum hw_config_contents {
- MASTER_CLOCK_4020_MASK = 0x3, /* bits that specify master clock source for 4020 */
- INTERNAL_CLOCK_4020_BITS = 0x1, /* use 40 MHz internal master clock for 4020 */
+ MASTER_CLOCK_4020_MASK = 0x3, /* master clock source mask for 4020 */
+ INTERNAL_CLOCK_4020_BITS = 0x1, /* use 40 MHz internal master clock */
BNC_CLOCK_4020_BITS = 0x2, /* use BNC input for master clock */
EXT_CLOCK_4020_BITS = 0x3, /* use dio input for master clock */
- EXT_QUEUE_BIT = 0x200, /* use external channel/gain queue (more versatile than internal queue) */
- SLOW_DAC_BIT = 0x400, /* use 225 nanosec strobe when loading dac instead of 50 nanosec */
- HW_CONFIG_DUMMY_BITS = 0x2000, /* bit with unknown function yet given as default value in pci-das64 manual */
- DMA_CH_SELECT_BIT = 0x8000, /* bit selects channels 1/0 for analog input/output, otherwise 0/1 */
- FIFO_SIZE_REG = 0x4, /* allows adjustment of fifo sizes */
+ EXT_QUEUE_BIT = 0x200, /* use external channel/gain queue */
+ /* use 225 nanosec strobe when loading dac instead of 50 nanosec */
+ SLOW_DAC_BIT = 0x400,
+ /* bit with unknown function yet given as default value in pci-das64
+ * manual */
+ HW_CONFIG_DUMMY_BITS = 0x2000,
+ /* bit selects channels 1/0 for analog input/output, otherwise 0/1 */
+ DMA_CH_SELECT_BIT = 0x8000,
+ FIFO_SIZE_REG = 0x4, /* allows adjustment of fifo sizes */
DAC_FIFO_SIZE_MASK = 0xff00, /* bits that set dac fifo size */
- DAC_FIFO_BITS = 0xf800, /* 8k sample ao fifo */
+ DAC_FIFO_BITS = 0xf800, /* 8k sample ao fifo */
};
#define DAC_FIFO_SIZE 0x2000
enum daq_atrig_low_4020_contents {
- EXT_AGATE_BNC_BIT = 0x8000, /* use trig/ext clk bnc input for analog gate signal */
- EXT_STOP_TRIG_BNC_BIT = 0x4000, /* use trig/ext clk bnc input for external stop trigger signal */
- EXT_START_TRIG_BNC_BIT = 0x2000, /* use trig/ext clk bnc input for external start trigger signal */
+ /* use trig/ext clk bnc input for analog gate signal */
+ EXT_AGATE_BNC_BIT = 0x8000,
+ /* use trig/ext clk bnc input for external stop trigger signal */
+ EXT_STOP_TRIG_BNC_BIT = 0x4000,
+ /* use trig/ext clk bnc input for external start trigger signal */
+ EXT_START_TRIG_BNC_BIT = 0x2000,
};
+
static inline uint16_t analog_trig_low_threshold_bits(uint16_t threshold)
{
return threshold & 0xfff;
@@ -247,14 +273,17 @@ enum adc_control0_contents {
ADC_START_TRIG_ANALOG_BITS = 0x30,
ADC_START_TRIG_MASK = 0x30,
ADC_START_TRIG_FALLING_BIT = 0x40, /* trig 1 uses falling edge */
- ADC_EXT_CONV_FALLING_BIT = 0x800, /* external pacing uses falling edge */
- ADC_SAMPLE_COUNTER_EN_BIT = 0x1000, /* enable hardware scan counter */
+ /* external pacing uses falling edge */
+ ADC_EXT_CONV_FALLING_BIT = 0x800,
+ /* enable hardware scan counter */
+ ADC_SAMPLE_COUNTER_EN_BIT = 0x1000,
ADC_DMA_DISABLE_BIT = 0x4000, /* disables dma */
ADC_ENABLE_BIT = 0x8000, /* master adc enable */
};
enum adc_control1_contents {
- ADC_QUEUE_CONFIG_BIT = 0x1, /* should be set for boards with > 16 channels */
+ /* should be set for boards with > 16 channels */
+ ADC_QUEUE_CONFIG_BIT = 0x1,
CONVERT_POLARITY_BIT = 0x10,
EOC_POLARITY_BIT = 0x20,
ADC_SW_GATE_BIT = 0x40, /* software gate of adc */
@@ -263,10 +292,11 @@ enum adc_control1_contents {
ADC_LO_CHANNEL_4020_MASK = 0x300,
ADC_HI_CHANNEL_4020_MASK = 0xc00,
TWO_CHANNEL_4020_BITS = 0x1000, /* two channel mode for 4020 */
- FOUR_CHANNEL_4020_BITS = 0x2000, /* four channel mode for 4020 */
+ FOUR_CHANNEL_4020_BITS = 0x2000, /* four channel mode for 4020 */
CHANNEL_MODE_4020_MASK = 0x3000,
ADC_MODE_MASK = 0xf000,
};
+
static inline uint16_t adc_lo_chan_4020_bits(unsigned int channel)
{
return (channel & 0x3) << 8;
@@ -289,9 +319,10 @@ enum calibration_contents {
CAL_EN_64XX_BIT = 0x40, /* calibration enable for 64xx series */
SERIAL_DATA_IN_BIT = 0x80,
SERIAL_CLOCK_BIT = 0x100,
- CAL_EN_60XX_BIT = 0x200, /* calibration enable for 60xx series */
+ CAL_EN_60XX_BIT = 0x200, /* calibration enable for 60xx series */
CAL_GAIN_BIT = 0x800,
};
+
/* calibration sources for 6025 are:
* 0 : ground
* 1 : 10V
@@ -302,6 +333,7 @@ enum calibration_contents {
* 6 : dac channel 0
* 7 : dac channel 1
*/
+
static inline uint16_t adc_src_bits(unsigned int source)
{
return (source & 0xf) << 3;
@@ -315,10 +347,12 @@ static inline uint16_t adc_convert_chan_4020_bits(unsigned int channel)
enum adc_queue_load_contents {
UNIP_BIT = 0x800, /* unipolar/bipolar bit */
ADC_SE_DIFF_BIT = 0x1000, /* single-ended/ differential bit */
- ADC_COMMON_BIT = 0x2000, /* non-referenced single-ended (common-mode input) */
+ /* non-referenced single-ended (common-mode input) */
+ ADC_COMMON_BIT = 0x2000,
QUEUE_EOSEQ_BIT = 0x4000, /* queue end of sequence */
QUEUE_EOSCAN_BIT = 0x8000, /* queue end of scan */
};
+
static inline uint16_t adc_chan_bits(unsigned int channel)
{
return channel & 0x3f;
@@ -365,6 +399,7 @@ enum hw_status_contents {
EXT_INTR_PENDING_BIT = 0x100,
ADC_STOP_BIT = 0x200,
};
+
static inline uint16_t pipe_full_bits(uint16_t hw_status_bits)
{
return (hw_status_bits >> 10) & 0x3;
@@ -393,9 +428,12 @@ enum i2c_addresses {
};
enum range_cal_i2c_contents {
- ADC_SRC_4020_MASK = 0x70, /* bits that set what source the adc converter measures */
- BNC_TRIG_THRESHOLD_0V_BIT = 0x80, /* make bnc trig/ext clock threshold 0V instead of 2.5V */
+ /* bits that set what source the adc converter measures */
+ ADC_SRC_4020_MASK = 0x70,
+ /* make bnc trig/ext clock threshold 0V instead of 2.5V */
+ BNC_TRIG_THRESHOLD_0V_BIT = 0x80,
};
+
static inline uint8_t adc_src_4020_bits(unsigned int source)
{
return (source << 4) & ADC_SRC_4020_MASK;
@@ -562,11 +600,12 @@ struct pcidas64_board {
const struct comedi_lrange *ai_range_table;
int ao_nchan; /* number of analog out channels */
int ao_bits; /* analog output resolution */
- int ao_scan_speed; /* analog output speed (for a scan, not conversion) */
+ int ao_scan_speed; /* analog output scan speed */
const struct comedi_lrange *ao_range_table;
const int *ao_range_code;
const struct hw_fifo_info *const ai_fifo;
- enum register_layout layout; /* different board families have slightly different registers */
+ /* different board families have slightly different registers */
+ enum register_layout layout;
unsigned has_8255:1;
};
@@ -596,7 +635,7 @@ static const struct hw_fifo_info ai_fifo_60xx = {
#define MAX_AI_DMA_RING_COUNT (0x80000 / DMA_BUFFER_SIZE)
#define MIN_AI_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE)
#define AO_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE)
-static inline unsigned int ai_dma_ring_count(struct pcidas64_board *board)
+static inline unsigned int ai_dma_ring_count(const struct pcidas64_board *board)
{
if (board->layout == LAYOUT_4020)
return MAX_AI_DMA_RING_COUNT;
@@ -1025,24 +1064,23 @@ static const struct pcidas64_board pcidas64_boards[] = {
#endif
};
-static inline struct pcidas64_board *board(const struct comedi_device *dev)
-{
- return (struct pcidas64_board *)dev->board_ptr;
-}
-
static inline unsigned short se_diff_bit_6xxx(struct comedi_device *dev,
int use_differential)
{
- if ((board(dev)->layout == LAYOUT_64XX && !use_differential) ||
- (board(dev)->layout == LAYOUT_60XX && use_differential))
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+
+ if ((thisboard->layout == LAYOUT_64XX && !use_differential) ||
+ (thisboard->layout == LAYOUT_60XX && use_differential))
return ADC_SE_DIFF_BIT;
else
return 0;
};
struct ext_clock_info {
- unsigned int divisor; /* master clock divisor to use for scans with external master clock */
- unsigned int chanspec; /* chanspec for master clock input when used as scan begin src */
+ /* master clock divisor to use for scans with external master clock */
+ unsigned int divisor;
+ /* chanspec for master clock input when used as scan begin src */
+ unsigned int chanspec;
};
/* this structure is for data unique to this hardware driver. */
@@ -1058,30 +1096,52 @@ struct pcidas64_private {
/* local address (used by dma controller) */
uint32_t local0_iobase;
uint32_t local1_iobase;
- volatile unsigned int ai_count; /* number of analog input samples remaining */
- uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT]; /* dma buffers for analog input */
- dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT]; /* physical addresses of ai dma buffers */
- struct plx_dma_desc *ai_dma_desc; /* array of ai dma descriptors read by plx9080, allocated to get proper alignment */
- dma_addr_t ai_dma_desc_bus_addr; /* physical address of ai dma descriptor array */
- volatile unsigned int ai_dma_index; /* index of the ai dma descriptor/buffer that is currently being used */
- uint16_t *ao_buffer[AO_DMA_RING_COUNT]; /* dma buffers for analog output */
- dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT]; /* physical addresses of ao dma buffers */
+ /* number of analog input samples remaining */
+ volatile unsigned int ai_count;
+ /* dma buffers for analog input */
+ uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT];
+ /* physical addresses of ai dma buffers */
+ dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT];
+ /* array of ai dma descriptors read by plx9080,
+ * allocated to get proper alignment */
+ struct plx_dma_desc *ai_dma_desc;
+ /* physical address of ai dma descriptor array */
+ dma_addr_t ai_dma_desc_bus_addr;
+ /* index of the ai dma descriptor/buffer
+ * that is currently being used */
+ volatile unsigned int ai_dma_index;
+ /* dma buffers for analog output */
+ uint16_t *ao_buffer[AO_DMA_RING_COUNT];
+ /* physical addresses of ao dma buffers */
+ dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT];
struct plx_dma_desc *ao_dma_desc;
dma_addr_t ao_dma_desc_bus_addr;
- volatile unsigned int ao_dma_index; /* keeps track of buffer where the next ao sample should go */
- volatile unsigned long ao_count; /* number of analog output samples remaining */
- volatile unsigned int ao_value[2]; /* remember what the analog outputs are set to, to allow readback */
+ /* keeps track of buffer where the next ao sample should go */
+ volatile unsigned int ao_dma_index;
+ /* number of analog output samples remaining */
+ volatile unsigned long ao_count;
+ /* remember what the analog outputs are set to, to allow readback */
+ volatile unsigned int ao_value[2];
unsigned int hw_revision; /* stc chip hardware revision number */
- volatile unsigned int intr_enable_bits; /* last bits sent to INTR_ENABLE_REG register */
- volatile uint16_t adc_control1_bits; /* last bits sent to ADC_CONTROL1_REG register */
- volatile uint16_t fifo_size_bits; /* last bits sent to FIFO_SIZE_REG register */
- volatile uint16_t hw_config_bits; /* last bits sent to HW_CONFIG_REG register */
+ /* last bits sent to INTR_ENABLE_REG register */
+ volatile unsigned int intr_enable_bits;
+ /* last bits sent to ADC_CONTROL1_REG register */
+ volatile uint16_t adc_control1_bits;
+ /* last bits sent to FIFO_SIZE_REG register */
+ volatile uint16_t fifo_size_bits;
+ /* last bits sent to HW_CONFIG_REG register */
+ volatile uint16_t hw_config_bits;
volatile uint16_t dac_control1_bits;
- volatile uint32_t plx_control_bits; /* last bits written to plx9080 control register */
- volatile uint32_t plx_intcsr_bits; /* last bits written to plx interrupt control and status register */
- volatile int calibration_source; /* index of calibration source readable through ai ch0 */
- volatile uint8_t i2c_cal_range_bits; /* bits written to i2c calibration/range register */
- volatile unsigned int ext_trig_falling; /* configure digital triggers to trigger on falling edge */
+ /* last bits written to plx9080 control register */
+ volatile uint32_t plx_control_bits;
+ /* last bits written to plx interrupt control and status register */
+ volatile uint32_t plx_intcsr_bits;
+ /* index of calibration source readable through ai ch0 */
+ volatile int calibration_source;
+ /* bits written to i2c calibration/range register */
+ volatile uint8_t i2c_cal_range_bits;
+ /* configure digital triggers to trigger on falling edge */
+ volatile unsigned int ext_trig_falling;
/* states of various devices stored to enable read-back */
unsigned int ad8402_state[2];
unsigned int caldac_state[8];
@@ -1091,93 +1151,12 @@ struct pcidas64_private {
short ao_bounce_buffer[DAC_FIFO_SIZE];
};
-/* inline function that makes it easier to
- * access the private structure.
- */
-static inline struct pcidas64_private *priv(struct comedi_device *dev)
-{
- return dev->private;
-}
-
-static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ao_readback_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
-static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_cmd *cmd);
-static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
-static int ao_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *subdev, unsigned int trig_num);
-static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_cmd *cmd);
-static irqreturn_t handle_interrupt(int irq, void *d);
-static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
-static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
-static int dio_callback(int dir, int port, int data, unsigned long arg);
-static int dio_callback_4020(int dir, int port, int data, unsigned long arg);
-static int di_rbits(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);
-static int dio_60xx_config_insn(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);
-static int calib_read_insn(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data);
-static int calib_write_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ad8402_read_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static void ad8402_write(struct comedi_device *dev, unsigned int channel,
- unsigned int value);
-static int ad8402_write_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int eeprom_read_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd);
-static unsigned int get_divisor(unsigned int ns, unsigned int flags);
-static void i2c_write(struct comedi_device *dev, unsigned int address,
- const uint8_t *data, unsigned int length);
-static void caldac_write(struct comedi_device *dev, unsigned int channel,
- unsigned int value);
-static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
- uint8_t value);
-/* static int dac_1590_write(struct comedi_device *dev, unsigned int dac_a, unsigned int dac_b); */
-static int caldac_i2c_write(struct comedi_device *dev,
- unsigned int caldac_channel, unsigned int value);
-static void abort_dma(struct comedi_device *dev, unsigned int channel);
-static void disable_plx_interrupts(struct comedi_device *dev);
-static int set_ai_fifo_size(struct comedi_device *dev,
- unsigned int num_samples);
-static unsigned int ai_fifo_size(struct comedi_device *dev);
-static int set_ai_fifo_segment_length(struct comedi_device *dev,
- unsigned int num_entries);
-static void disable_ai_pacing(struct comedi_device *dev);
-static void disable_ai_interrupts(struct comedi_device *dev);
-static void enable_ai_interrupts(struct comedi_device *dev,
- const struct comedi_cmd *cmd);
-static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags);
-static void load_ao_dma(struct comedi_device *dev,
- const struct comedi_cmd *cmd);
-
static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
unsigned int range_index)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
const struct comedi_krange *range =
- &board(dev)->ai_range_table->range[range_index];
+ &thisboard->ai_range_table->range[range_index];
unsigned int bits = 0;
switch (range->max) {
@@ -1220,7 +1199,9 @@ static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
static unsigned int hw_revision(const struct comedi_device *dev,
uint16_t hw_status_bits)
{
- if (board(dev)->layout == LAYOUT_4020)
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+
+ if (thisboard->layout == LAYOUT_4020)
return (hw_status_bits >> 13) & 0x7;
return (hw_status_bits >> 12) & 0xf;
@@ -1230,7 +1211,8 @@ static void set_dac_range_bits(struct comedi_device *dev,
volatile uint16_t *bits, unsigned int channel,
unsigned int range)
{
- unsigned int code = board(dev)->ao_range_code[range];
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ unsigned int code = thisboard->ao_range_code[range];
if (channel > 1)
comedi_error(dev, "bug! bad channel?");
@@ -1246,20 +1228,86 @@ static inline int ao_cmd_is_supported(const struct pcidas64_board *board)
return board->ao_nchan && board->layout != LAYOUT_4020;
}
+static void abort_dma(struct comedi_device *dev, unsigned int channel)
+{
+ struct pcidas64_private *devpriv = dev->private;
+ unsigned long flags;
+
+ /* spinlock for plx dma control/status reg */
+ spin_lock_irqsave(&dev->spinlock, flags);
+
+ plx9080_abort_dma(devpriv->plx9080_iobase, channel);
+
+ spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+static void disable_plx_interrupts(struct comedi_device *dev)
+{
+ struct pcidas64_private *devpriv = dev->private;
+
+ devpriv->plx_intcsr_bits = 0;
+ writel(devpriv->plx_intcsr_bits,
+ devpriv->plx9080_iobase + PLX_INTRCS_REG);
+}
+
+static void disable_ai_interrupts(struct comedi_device *dev)
+{
+ struct pcidas64_private *devpriv = dev->private;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->intr_enable_bits &=
+ ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT &
+ ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT &
+ ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK;
+ writew(devpriv->intr_enable_bits,
+ devpriv->main_iobase + INTR_ENABLE_REG);
+ spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits);
+}
+
+static void enable_ai_interrupts(struct comedi_device *dev,
+ const struct comedi_cmd *cmd)
+{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
+ uint32_t bits;
+ unsigned long flags;
+
+ bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT |
+ EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT;
+ /* Use pio transfer and interrupt on end of conversion
+ * if TRIG_WAKE_EOS flag is set. */
+ if (cmd->flags & TRIG_WAKE_EOS) {
+ /* 4020 doesn't support pio transfers except for fifo dregs */
+ if (thisboard->layout != LAYOUT_4020)
+ bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT;
+ }
+ spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->intr_enable_bits |= bits;
+ writew(devpriv->intr_enable_bits,
+ devpriv->main_iobase + INTR_ENABLE_REG);
+ DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits);
+ spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
/* initialize plx9080 chip */
static void init_plx9080(struct comedi_device *dev)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
uint32_t bits;
- void __iomem *plx_iobase = priv(dev)->plx9080_iobase;
+ void __iomem *plx_iobase = devpriv->plx9080_iobase;
- priv(dev)->plx_control_bits =
- readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG);
+ devpriv->plx_control_bits =
+ readl(devpriv->plx9080_iobase + PLX_CONTROL_REG);
/* plx9080 dump */
DEBUG_PRINT(" plx interrupt status 0x%x\n",
readl(plx_iobase + PLX_INTRCS_REG));
DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG));
- DEBUG_PRINT(" plx control reg 0x%x\n", priv(dev)->plx_control_bits);
+ DEBUG_PRINT(" plx control reg 0x%x\n", devpriv->plx_control_bits);
DEBUG_PRINT(" plx mode/arbitration reg 0x%x\n",
readl(plx_iobase + PLX_MARB_REG));
DEBUG_PRINT(" plx region0 reg 0x%x\n",
@@ -1292,7 +1340,7 @@ static void init_plx9080(struct comedi_device *dev)
#else
bits = 0;
#endif
- writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG);
+ writel(bits, devpriv->plx9080_iobase + PLX_BIGEND_REG);
disable_plx_interrupts(dev);
@@ -1307,9 +1355,11 @@ static void init_plx9080(struct comedi_device *dev)
bits |= PLX_EN_BTERM_BIT;
/* enable dma chaining */
bits |= PLX_EN_CHAIN_BIT;
- /* enable interrupt on dma done (probably don't need this, since chain never finishes) */
+ /* enable interrupt on dma done
+ * (probably don't need this, since chain never finishes) */
bits |= PLX_EN_DMA_DONE_INTR_BIT;
- /* don't increment local address during transfers (we are transferring from a fixed fifo register) */
+ /* don't increment local address during transfers
+ * (we are transferring from a fixed fifo register) */
bits |= PLX_LOCAL_ADDR_CONST_BIT;
/* route dma interrupt to pci bus */
bits |= PLX_DMA_INTR_PCI_BIT;
@@ -1318,324 +1368,235 @@ static void init_plx9080(struct comedi_device *dev)
/* enable local burst mode */
bits |= PLX_DMA_LOCAL_BURST_EN_BIT;
/* 4020 uses 32 bit dma */
- if (board(dev)->layout == LAYOUT_4020) {
+ if (thisboard->layout == LAYOUT_4020)
bits |= PLX_LOCAL_BUS_32_WIDE_BITS;
- } else { /* localspace0 bus is 16 bits wide */
+ else /* localspace0 bus is 16 bits wide */
bits |= PLX_LOCAL_BUS_16_WIDE_BITS;
- }
writel(bits, plx_iobase + PLX_DMA1_MODE_REG);
- if (ao_cmd_is_supported(board(dev)))
+ if (ao_cmd_is_supported(thisboard))
writel(bits, plx_iobase + PLX_DMA0_MODE_REG);
/* enable interrupts on plx 9080 */
- priv(dev)->plx_intcsr_bits |=
+ devpriv->plx_intcsr_bits |=
ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
ICS_DMA0_E | ICS_DMA1_E;
- writel(priv(dev)->plx_intcsr_bits,
- priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+ writel(devpriv->plx_intcsr_bits,
+ devpriv->plx9080_iobase + PLX_INTRCS_REG);
}
-/* Allocate and initialize the subdevice structures.
- */
-static int setup_subdevices(struct comedi_device *dev)
+static void disable_ai_pacing(struct comedi_device *dev)
{
- struct comedi_subdevice *s;
- void __iomem *dio_8255_iobase;
- int i;
- int ret;
+ struct pcidas64_private *devpriv = dev->private;
+ unsigned long flags;
- ret = comedi_alloc_subdevices(dev, 10);
- if (ret)
- return ret;
+ disable_ai_interrupts(dev);
- s = &dev->subdevices[0];
- /* analog input subdevice */
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ;
- if (board(dev)->layout == LAYOUT_60XX)
- s->subdev_flags |= SDF_COMMON | SDF_DIFF;
- else if (board(dev)->layout == LAYOUT_64XX)
- s->subdev_flags |= SDF_DIFF;
- /* XXX Number of inputs in differential mode is ignored */
- s->n_chan = board(dev)->ai_se_chans;
- s->len_chanlist = 0x2000;
- s->maxdata = (1 << board(dev)->ai_bits) - 1;
- s->range_table = board(dev)->ai_range_table;
- s->insn_read = ai_rinsn;
- s->insn_config = ai_config_insn;
- s->do_cmd = ai_cmd;
- s->do_cmdtest = ai_cmdtest;
- s->cancel = ai_cancel;
- if (board(dev)->layout == LAYOUT_4020) {
- uint8_t data;
- /* set adc to read from inputs (not internal calibration sources) */
- priv(dev)->i2c_cal_range_bits = adc_src_4020_bits(4);
- /* set channels to +-5 volt input ranges */
- for (i = 0; i < s->n_chan; i++)
- priv(dev)->i2c_cal_range_bits |= attenuate_bit(i);
- data = priv(dev)->i2c_cal_range_bits;
- i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data));
- }
+ spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->adc_control1_bits &= ~ADC_SW_GATE_BIT;
+ writew(devpriv->adc_control1_bits,
+ devpriv->main_iobase + ADC_CONTROL1_REG);
+ spin_unlock_irqrestore(&dev->spinlock, flags);
- /* analog output subdevice */
- s = &dev->subdevices[1];
- if (board(dev)->ao_nchan) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags =
- SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
- s->n_chan = board(dev)->ao_nchan;
- s->maxdata = (1 << board(dev)->ao_bits) - 1;
- s->range_table = board(dev)->ao_range_table;
- s->insn_read = ao_readback_insn;
- s->insn_write = ao_winsn;
- if (ao_cmd_is_supported(board(dev))) {
- dev->write_subdev = s;
- s->do_cmdtest = ao_cmdtest;
- s->do_cmd = ao_cmd;
- s->len_chanlist = board(dev)->ao_nchan;
- s->cancel = ao_cancel;
- }
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
+ /* disable pacing, triggering, etc */
+ writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT,
+ devpriv->main_iobase + ADC_CONTROL0_REG);
+}
- /* digital input */
- s = &dev->subdevices[2];
- if (board(dev)->layout == LAYOUT_64XX) {
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = di_rbits;
- } else
- s->type = COMEDI_SUBD_UNUSED;
+static int set_ai_fifo_segment_length(struct comedi_device *dev,
+ unsigned int num_entries)
+{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
+ static const int increment_size = 0x100;
+ const struct hw_fifo_info *const fifo = thisboard->ai_fifo;
+ unsigned int num_increments;
+ uint16_t bits;
- /* digital output */
- if (board(dev)->layout == LAYOUT_64XX) {
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = do_wbits;
- } else
- s->type = COMEDI_SUBD_UNUSED;
+ if (num_entries < increment_size)
+ num_entries = increment_size;
+ if (num_entries > fifo->max_segment_length)
+ num_entries = fifo->max_segment_length;
- /* 8255 */
- s = &dev->subdevices[4];
- if (board(dev)->has_8255) {
- if (board(dev)->layout == LAYOUT_4020) {
- dio_8255_iobase =
- priv(dev)->main_iobase + I8255_4020_REG;
- subdev_8255_init(dev, s, dio_callback_4020,
- (unsigned long)dio_8255_iobase);
- } else {
- dio_8255_iobase =
- priv(dev)->dio_counter_iobase + DIO_8255_OFFSET;
- subdev_8255_init(dev, s, dio_callback,
- (unsigned long)dio_8255_iobase);
- }
- } else
- s->type = COMEDI_SUBD_UNUSED;
+ /* 1 == 256 entries, 2 == 512 entries, etc */
+ num_increments = (num_entries + increment_size / 2) / increment_size;
- /* 8 channel dio for 60xx */
- s = &dev->subdevices[5];
- if (board(dev)->layout == LAYOUT_60XX) {
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_config = dio_60xx_config_insn;
- s->insn_bits = dio_60xx_wbits;
- } else
- s->type = COMEDI_SUBD_UNUSED;
+ bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask;
+ devpriv->fifo_size_bits &= ~fifo->fifo_size_reg_mask;
+ devpriv->fifo_size_bits |= bits;
+ writew(devpriv->fifo_size_bits,
+ devpriv->main_iobase + FIFO_SIZE_REG);
- /* caldac */
- s = &dev->subdevices[6];
- s->type = COMEDI_SUBD_CALIB;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 8;
- if (board(dev)->layout == LAYOUT_4020)
- s->maxdata = 0xfff;
- else
- s->maxdata = 0xff;
- s->insn_read = calib_read_insn;
- s->insn_write = calib_write_insn;
- for (i = 0; i < s->n_chan; i++)
- caldac_write(dev, i, s->maxdata / 2);
+ devpriv->ai_fifo_segment_length = num_increments * increment_size;
- /* 2 channel ad8402 potentiometer */
- s = &dev->subdevices[7];
- if (board(dev)->layout == LAYOUT_64XX) {
- s->type = COMEDI_SUBD_CALIB;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 2;
- s->insn_read = ad8402_read_insn;
- s->insn_write = ad8402_write_insn;
- s->maxdata = 0xff;
- for (i = 0; i < s->n_chan; i++)
- ad8402_write(dev, i, s->maxdata / 2);
- } else
- s->type = COMEDI_SUBD_UNUSED;
+ DEBUG_PRINT("set hardware fifo segment length to %i\n",
+ devpriv->ai_fifo_segment_length);
- /* serial EEPROM, if present */
- s = &dev->subdevices[8];
- if (readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) {
- s->type = COMEDI_SUBD_MEMORY;
- s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
- s->n_chan = 128;
- s->maxdata = 0xffff;
- s->insn_read = eeprom_read_insn;
- } else
- s->type = COMEDI_SUBD_UNUSED;
+ return devpriv->ai_fifo_segment_length;
+}
- /* user counter subd XXX */
- s = &dev->subdevices[9];
- s->type = COMEDI_SUBD_UNUSED;
+/* adjusts the size of hardware fifo (which determines block size for dma xfers) */
+static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples)
+{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ unsigned int num_fifo_entries;
+ int retval;
+ const struct hw_fifo_info *const fifo = thisboard->ai_fifo;
- return 0;
+ num_fifo_entries = num_samples / fifo->sample_packing_ratio;
+
+ retval = set_ai_fifo_segment_length(dev,
+ num_fifo_entries /
+ fifo->num_segments);
+ if (retval < 0)
+ return retval;
+
+ num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio;
+
+ DEBUG_PRINT("set hardware fifo size to %i\n", num_samples);
+
+ return num_samples;
}
-static void disable_plx_interrupts(struct comedi_device *dev)
+/* query length of fifo */
+static unsigned int ai_fifo_size(struct comedi_device *dev)
{
- priv(dev)->plx_intcsr_bits = 0;
- writel(priv(dev)->plx_intcsr_bits,
- priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
+
+ return devpriv->ai_fifo_segment_length *
+ thisboard->ai_fifo->num_segments *
+ thisboard->ai_fifo->sample_packing_ratio;
}
static void init_stc_registers(struct comedi_device *dev)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
uint16_t bits;
unsigned long flags;
spin_lock_irqsave(&dev->spinlock, flags);
- /* bit should be set for 6025, although docs say boards with <= 16 chans should be cleared XXX */
+ /* bit should be set for 6025,
+ * although docs say boards with <= 16 chans should be cleared XXX */
if (1)
- priv(dev)->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT;
- writew(priv(dev)->adc_control1_bits,
- priv(dev)->main_iobase + ADC_CONTROL1_REG);
+ devpriv->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT;
+ writew(devpriv->adc_control1_bits,
+ devpriv->main_iobase + ADC_CONTROL1_REG);
/* 6402/16 manual says this register must be initialized to 0xff? */
- writew(0xff, priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
+ writew(0xff, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
bits = SLOW_DAC_BIT | DMA_CH_SELECT_BIT;
- if (board(dev)->layout == LAYOUT_4020)
+ if (thisboard->layout == LAYOUT_4020)
bits |= INTERNAL_CLOCK_4020_BITS;
- priv(dev)->hw_config_bits |= bits;
- writew(priv(dev)->hw_config_bits,
- priv(dev)->main_iobase + HW_CONFIG_REG);
+ devpriv->hw_config_bits |= bits;
+ writew(devpriv->hw_config_bits,
+ devpriv->main_iobase + HW_CONFIG_REG);
- writew(0, priv(dev)->main_iobase + DAQ_SYNC_REG);
- writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+ writew(0, devpriv->main_iobase + DAQ_SYNC_REG);
+ writew(0, devpriv->main_iobase + CALIBRATION_REG);
spin_unlock_irqrestore(&dev->spinlock, flags);
/* set fifos to maximum size */
- priv(dev)->fifo_size_bits |= DAC_FIFO_BITS;
+ devpriv->fifo_size_bits |= DAC_FIFO_BITS;
set_ai_fifo_segment_length(dev,
- board(dev)->ai_fifo->max_segment_length);
+ thisboard->ai_fifo->max_segment_length);
- priv(dev)->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT;
- priv(dev)->intr_enable_bits = /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */
- EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT;
- writew(priv(dev)->intr_enable_bits,
- priv(dev)->main_iobase + INTR_ENABLE_REG);
+ devpriv->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT;
+ devpriv->intr_enable_bits =
+ /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */
+ EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT;
+ writew(devpriv->intr_enable_bits,
+ devpriv->main_iobase + INTR_ENABLE_REG);
disable_ai_pacing(dev);
};
static int alloc_and_init_dma_members(struct comedi_device *dev)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct pcidas64_private *devpriv = dev->private;
int i;
/* alocate pci dma buffers */
- for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
- priv(dev)->ai_buffer[i] =
- pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE,
- &priv(dev)->ai_buffer_bus_addr[i]);
- if (priv(dev)->ai_buffer[i] == NULL)
+ for (i = 0; i < ai_dma_ring_count(thisboard); i++) {
+ devpriv->ai_buffer[i] =
+ pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE,
+ &devpriv->ai_buffer_bus_addr[i]);
+ if (devpriv->ai_buffer[i] == NULL)
return -ENOMEM;
}
for (i = 0; i < AO_DMA_RING_COUNT; i++) {
- if (ao_cmd_is_supported(board(dev))) {
- priv(dev)->ao_buffer[i] =
- pci_alloc_consistent(pcidev,
- DMA_BUFFER_SIZE,
- &priv(dev)->
- ao_buffer_bus_addr[i]);
- if (priv(dev)->ao_buffer[i] == NULL)
+ if (ao_cmd_is_supported(thisboard)) {
+ devpriv->ao_buffer[i] =
+ pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE,
+ &devpriv->
+ ao_buffer_bus_addr[i]);
+ if (devpriv->ao_buffer[i] == NULL)
return -ENOMEM;
}
}
/* allocate dma descriptors */
- priv(dev)->ai_dma_desc =
- pci_alloc_consistent(pcidev,
- sizeof(struct plx_dma_desc) *
- ai_dma_ring_count(board(dev)),
- &priv(dev)->ai_dma_desc_bus_addr);
- if (priv(dev)->ai_dma_desc == NULL)
+ devpriv->ai_dma_desc =
+ pci_alloc_consistent(pcidev, sizeof(struct plx_dma_desc) *
+ ai_dma_ring_count(thisboard),
+ &devpriv->ai_dma_desc_bus_addr);
+ if (devpriv->ai_dma_desc == NULL)
return -ENOMEM;
- DEBUG_PRINT("ai dma descriptors start at bus addr 0x%x\n",
- priv(dev)->ai_dma_desc_bus_addr);
- if (ao_cmd_is_supported(board(dev))) {
- priv(dev)->ao_dma_desc =
- pci_alloc_consistent(pcidev,
- sizeof(struct plx_dma_desc) *
- AO_DMA_RING_COUNT,
- &priv(dev)->ao_dma_desc_bus_addr);
- if (priv(dev)->ao_dma_desc == NULL)
+ DEBUG_PRINT("ai dma descriptors start at bus addr 0x%llx\n",
+ (unsigned long long)devpriv->ai_dma_desc_bus_addr);
+ if (ao_cmd_is_supported(thisboard)) {
+ devpriv->ao_dma_desc =
+ pci_alloc_consistent(pcidev,
+ sizeof(struct plx_dma_desc) *
+ AO_DMA_RING_COUNT,
+ &devpriv->ao_dma_desc_bus_addr);
+ if (devpriv->ao_dma_desc == NULL)
return -ENOMEM;
- DEBUG_PRINT("ao dma descriptors start at bus addr 0x%x\n",
- priv(dev)->ao_dma_desc_bus_addr);
+ DEBUG_PRINT("ao dma descriptors start at bus addr 0x%llx\n",
+ (unsigned long long)devpriv->ao_dma_desc_bus_addr);
}
/* initialize dma descriptors */
- for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
- priv(dev)->ai_dma_desc[i].pci_start_addr =
- cpu_to_le32(priv(dev)->ai_buffer_bus_addr[i]);
- if (board(dev)->layout == LAYOUT_4020)
- priv(dev)->ai_dma_desc[i].local_start_addr =
- cpu_to_le32(priv(dev)->local1_iobase +
- ADC_FIFO_REG);
+ for (i = 0; i < ai_dma_ring_count(thisboard); i++) {
+ devpriv->ai_dma_desc[i].pci_start_addr =
+ cpu_to_le32(devpriv->ai_buffer_bus_addr[i]);
+ if (thisboard->layout == LAYOUT_4020)
+ devpriv->ai_dma_desc[i].local_start_addr =
+ cpu_to_le32(devpriv->local1_iobase +
+ ADC_FIFO_REG);
else
- priv(dev)->ai_dma_desc[i].local_start_addr =
- cpu_to_le32(priv(dev)->local0_iobase +
- ADC_FIFO_REG);
- priv(dev)->ai_dma_desc[i].transfer_size = cpu_to_le32(0);
- priv(dev)->ai_dma_desc[i].next =
- cpu_to_le32((priv(dev)->ai_dma_desc_bus_addr + ((i +
- 1) %
- ai_dma_ring_count
- (board
- (dev))) *
- sizeof(priv(dev)->ai_dma_desc[0])) |
- PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
- PLX_XFER_LOCAL_TO_PCI);
+ devpriv->ai_dma_desc[i].local_start_addr =
+ cpu_to_le32(devpriv->local0_iobase +
+ ADC_FIFO_REG);
+ devpriv->ai_dma_desc[i].transfer_size = cpu_to_le32(0);
+ devpriv->ai_dma_desc[i].next =
+ cpu_to_le32((devpriv->ai_dma_desc_bus_addr +
+ ((i + 1) % ai_dma_ring_count(thisboard)) *
+ sizeof(devpriv->ai_dma_desc[0])) |
+ PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
+ PLX_XFER_LOCAL_TO_PCI);
}
- if (ao_cmd_is_supported(board(dev))) {
+ if (ao_cmd_is_supported(thisboard)) {
for (i = 0; i < AO_DMA_RING_COUNT; i++) {
- priv(dev)->ao_dma_desc[i].pci_start_addr =
- cpu_to_le32(priv(dev)->ao_buffer_bus_addr[i]);
- priv(dev)->ao_dma_desc[i].local_start_addr =
- cpu_to_le32(priv(dev)->local0_iobase +
- DAC_FIFO_REG);
- priv(dev)->ao_dma_desc[i].transfer_size =
- cpu_to_le32(0);
- priv(dev)->ao_dma_desc[i].next =
- cpu_to_le32((priv(dev)->ao_dma_desc_bus_addr +
- ((i + 1) % (AO_DMA_RING_COUNT)) *
- sizeof(priv(dev)->ao_dma_desc[0])) |
- PLX_DESC_IN_PCI_BIT |
- PLX_INTR_TERM_COUNT);
+ devpriv->ao_dma_desc[i].pci_start_addr =
+ cpu_to_le32(devpriv->ao_buffer_bus_addr[i]);
+ devpriv->ao_dma_desc[i].local_start_addr =
+ cpu_to_le32(devpriv->local0_iobase +
+ DAC_FIFO_REG);
+ devpriv->ao_dma_desc[i].transfer_size = cpu_to_le32(0);
+ devpriv->ao_dma_desc[i].next =
+ cpu_to_le32((devpriv->ao_dma_desc_bus_addr +
+ ((i + 1) % (AO_DMA_RING_COUNT)) *
+ sizeof(devpriv->ao_dma_desc[0])) |
+ PLX_DESC_IN_PCI_BIT |
+ PLX_INTR_TERM_COUNT);
}
}
return 0;
@@ -1649,216 +1610,140 @@ static inline void warn_external_queue(struct comedi_device *dev)
"Use internal AI channel queue (channels must be consecutive and use same range/aref)");
}
-static struct pci_dev *cb_pcidas64_find_pci_dev(struct comedi_device *dev,
- struct comedi_devconfig *it)
+/* Their i2c requires a huge delay on setting clock or data high for some reason */
+static const int i2c_high_udelay = 1000;
+static const int i2c_low_udelay = 10;
+
+/* set i2c data line high or low */
+static void i2c_set_sda(struct comedi_device *dev, int state)
{
- struct pci_dev *pcidev = NULL;
- int bus = it->options[0];
- int slot = it->options[1];
- int i;
+ struct pcidas64_private *devpriv = dev->private;
+ static const int data_bit = CTL_EE_W;
+ void __iomem *plx_control_addr = devpriv->plx9080_iobase +
+ PLX_CONTROL_REG;
- for_each_pci_dev(pcidev) {
- if (bus || slot) {
- if (bus != pcidev->bus->number ||
- slot != PCI_SLOT(pcidev->devfn))
- continue;
- }
- if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
- continue;
-
- for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++) {
- if (pcidas64_boards[i].device_id != pcidev->device)
- continue;
- dev->board_ptr = pcidas64_boards + i;
- return pcidev;
- }
+ if (state) {
+ /* set data line high */
+ devpriv->plx_control_bits &= ~data_bit;
+ writel(devpriv->plx_control_bits, plx_control_addr);
+ udelay(i2c_high_udelay);
+ } else { /* set data line low */
+
+ devpriv->plx_control_bits |= data_bit;
+ writel(devpriv->plx_control_bits, plx_control_addr);
+ udelay(i2c_low_udelay);
}
- dev_err(dev->class_dev,
- "No supported board found! (req. bus %d, slot %d)\n",
- bus, slot);
- return NULL;
}
-/*
- * Attach is called by the Comedi core to configure the driver
- * for a particular board.
- */
-static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
+/* set i2c clock line high or low */
+static void i2c_set_scl(struct comedi_device *dev, int state)
{
- struct pci_dev *pcidev;
- uint32_t local_range, local_decode;
- int retval;
-
-/*
- * Allocate the private structure area.
- */
- if (alloc_private(dev, sizeof(struct pcidas64_private)) < 0)
- return -ENOMEM;
+ struct pcidas64_private *devpriv = dev->private;
+ static const int clock_bit = CTL_USERO;
+ void __iomem *plx_control_addr = devpriv->plx9080_iobase +
+ PLX_CONTROL_REG;
- pcidev = cb_pcidas64_find_pci_dev(dev, it);
- if (!pcidev)
- return -EIO;
- comedi_set_hw_dev(dev, &pcidev->dev);
+ if (state) {
+ /* set clock line high */
+ devpriv->plx_control_bits &= ~clock_bit;
+ writel(devpriv->plx_control_bits, plx_control_addr);
+ udelay(i2c_high_udelay);
+ } else { /* set clock line low */
- if (comedi_pci_enable(pcidev, dev->driver->driver_name)) {
- dev_warn(dev->class_dev,
- "failed to enable PCI device and request regions\n");
- return -EIO;
+ devpriv->plx_control_bits |= clock_bit;
+ writel(devpriv->plx_control_bits, plx_control_addr);
+ udelay(i2c_low_udelay);
}
- pci_set_master(pcidev);
-
- /* Initialize dev->board_name */
- dev->board_name = board(dev)->name;
+}
- dev->iobase = pci_resource_start(pcidev, MAIN_BADDRINDEX);
+static void i2c_write_byte(struct comedi_device *dev, uint8_t byte)
+{
+ uint8_t bit;
+ unsigned int num_bits = 8;
- priv(dev)->plx9080_phys_iobase =
- pci_resource_start(pcidev, PLX9080_BADDRINDEX);
- priv(dev)->main_phys_iobase = dev->iobase;
- priv(dev)->dio_counter_phys_iobase =
- pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX);
+ DEBUG_PRINT("writing to i2c byte 0x%x\n", byte);
- /* remap, won't work with 2.0 kernels but who cares */
- priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase,
- pci_resource_len(pcidev,
- PLX9080_BADDRINDEX));
- priv(dev)->main_iobase =
- ioremap(priv(dev)->main_phys_iobase,
- pci_resource_len(pcidev, MAIN_BADDRINDEX));
- priv(dev)->dio_counter_iobase =
- ioremap(priv(dev)->dio_counter_phys_iobase,
- pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX));
-
- if (!priv(dev)->plx9080_iobase || !priv(dev)->main_iobase
- || !priv(dev)->dio_counter_iobase) {
- dev_warn(dev->class_dev, "failed to remap io memory\n");
- return -ENOMEM;
+ for (bit = 1 << (num_bits - 1); bit; bit >>= 1) {
+ i2c_set_scl(dev, 0);
+ if ((byte & bit))
+ i2c_set_sda(dev, 1);
+ else
+ i2c_set_sda(dev, 0);
+ i2c_set_scl(dev, 1);
}
+}
- DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase);
- DEBUG_PRINT(" main remapped to 0x%p\n", priv(dev)->main_iobase);
- DEBUG_PRINT(" diocounter remapped to 0x%p\n",
- priv(dev)->dio_counter_iobase);
-
- /* figure out what local addresses are */
- local_range =
- readl(priv(dev)->plx9080_iobase + PLX_LAS0RNG_REG) & LRNG_MEM_MASK;
- local_decode =
- readl(priv(dev)->plx9080_iobase +
- PLX_LAS0MAP_REG) & local_range & LMAP_MEM_MASK;
- priv(dev)->local0_iobase =
- ((uint32_t) priv(dev)->main_phys_iobase & ~local_range) |
- local_decode;
- local_range =
- readl(priv(dev)->plx9080_iobase + PLX_LAS1RNG_REG) & LRNG_MEM_MASK;
- local_decode =
- readl(priv(dev)->plx9080_iobase +
- PLX_LAS1MAP_REG) & local_range & LMAP_MEM_MASK;
- priv(dev)->local1_iobase =
- ((uint32_t) priv(dev)->dio_counter_phys_iobase & ~local_range) |
- local_decode;
-
- DEBUG_PRINT(" local 0 io addr 0x%x\n", priv(dev)->local0_iobase);
- DEBUG_PRINT(" local 1 io addr 0x%x\n", priv(dev)->local1_iobase);
-
- retval = alloc_and_init_dma_members(dev);
- if (retval < 0)
- return retval;
-
- priv(dev)->hw_revision =
- hw_revision(dev, readw(priv(dev)->main_iobase + HW_STATUS_REG));
- dev_dbg(dev->class_dev, "stc hardware revision %i\n",
- priv(dev)->hw_revision);
- init_plx9080(dev);
- init_stc_registers(dev);
- /* get irq */
- if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
- "cb_pcidas64", dev)) {
- dev_dbg(dev->class_dev, "unable to allocate irq %u\n",
- pcidev->irq);
- return -EINVAL;
- }
- dev->irq = pcidev->irq;
- dev_dbg(dev->class_dev, "irq %u\n", dev->irq);
+/* we can't really read the lines, so fake it */
+static int i2c_read_ack(struct comedi_device *dev)
+{
+ i2c_set_scl(dev, 0);
+ i2c_set_sda(dev, 1);
+ i2c_set_scl(dev, 1);
- retval = setup_subdevices(dev);
- if (retval < 0)
- return retval;
+ return 0; /* return fake acknowledge bit */
+}
+/* send start bit */
+static void i2c_start(struct comedi_device *dev)
+{
+ i2c_set_scl(dev, 1);
+ i2c_set_sda(dev, 1);
+ i2c_set_sda(dev, 0);
+}
- return 0;
+/* send stop bit */
+static void i2c_stop(struct comedi_device *dev)
+{
+ i2c_set_scl(dev, 0);
+ i2c_set_sda(dev, 0);
+ i2c_set_scl(dev, 1);
+ i2c_set_sda(dev, 1);
}
-static void detach(struct comedi_device *dev)
+static void i2c_write(struct comedi_device *dev, unsigned int address,
+ const uint8_t *data, unsigned int length)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct pcidas64_private *devpriv = dev->private;
unsigned int i;
+ uint8_t bitstream;
+ static const int read_bit = 0x1;
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (priv(dev)) {
- if (pcidev) {
- if (priv(dev)->plx9080_iobase) {
- disable_plx_interrupts(dev);
- iounmap(priv(dev)->plx9080_iobase);
- }
- if (priv(dev)->main_iobase)
- iounmap(priv(dev)->main_iobase);
- if (priv(dev)->dio_counter_iobase)
- iounmap(priv(dev)->dio_counter_iobase);
- /* free pci dma buffers */
- for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
- if (priv(dev)->ai_buffer[i])
- pci_free_consistent(pcidev,
- DMA_BUFFER_SIZE,
- priv(dev)->
- ai_buffer[i],
- priv
- (dev)->ai_buffer_bus_addr
- [i]);
- }
- for (i = 0; i < AO_DMA_RING_COUNT; i++) {
- if (priv(dev)->ao_buffer[i])
- pci_free_consistent(pcidev,
- DMA_BUFFER_SIZE,
- priv(dev)->
- ao_buffer[i],
- priv
- (dev)->ao_buffer_bus_addr
- [i]);
- }
- /* free dma descriptors */
- if (priv(dev)->ai_dma_desc)
- pci_free_consistent(pcidev,
- sizeof(struct plx_dma_desc)
- *
- ai_dma_ring_count(board
- (dev)),
- priv(dev)->ai_dma_desc,
- priv(dev)->
- ai_dma_desc_bus_addr);
- if (priv(dev)->ao_dma_desc)
- pci_free_consistent(pcidev,
- sizeof(struct plx_dma_desc)
- * AO_DMA_RING_COUNT,
- priv(dev)->ao_dma_desc,
- priv(dev)->
- ao_dma_desc_bus_addr);
- }
- }
- if (dev->subdevices)
- subdev_8255_cleanup(dev, &dev->subdevices[4]);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
+ /* XXX need mutex to prevent simultaneous attempts to access
+ * eeprom and i2c bus */
+
+ /* make sure we dont send anything to eeprom */
+ devpriv->plx_control_bits &= ~CTL_EE_CS;
+
+ i2c_stop(dev);
+ i2c_start(dev);
+
+ /* send address and write bit */
+ bitstream = (address << 1) & ~read_bit;
+ i2c_write_byte(dev, bitstream);
- pci_dev_put(pcidev);
+ /* get acknowledge */
+ if (i2c_read_ack(dev) != 0) {
+ comedi_error(dev, "i2c write failed: no acknowledge");
+ i2c_stop(dev);
+ return;
}
+ /* write data bytes */
+ for (i = 0; i < length; i++) {
+ i2c_write_byte(dev, data[i]);
+ if (i2c_read_ack(dev) != 0) {
+ comedi_error(dev, "i2c write failed: no acknowledge");
+ i2c_stop(dev);
+ return;
+ }
+ }
+ i2c_stop(dev);
}
static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
unsigned int bits = 0, n, i;
unsigned int channel, range, aref;
unsigned long flags;
@@ -1875,35 +1760,37 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
spin_lock_irqsave(&dev->spinlock, flags);
if (insn->chanspec & CR_ALT_FILTER)
- priv(dev)->adc_control1_bits |= ADC_DITHER_BIT;
+ devpriv->adc_control1_bits |= ADC_DITHER_BIT;
else
- priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT;
- writew(priv(dev)->adc_control1_bits,
- priv(dev)->main_iobase + ADC_CONTROL1_REG);
+ devpriv->adc_control1_bits &= ~ADC_DITHER_BIT;
+ writew(devpriv->adc_control1_bits,
+ devpriv->main_iobase + ADC_CONTROL1_REG);
spin_unlock_irqrestore(&dev->spinlock, flags);
- if (board(dev)->layout != LAYOUT_4020) {
+ if (thisboard->layout != LAYOUT_4020) {
/* use internal queue */
- priv(dev)->hw_config_bits &= ~EXT_QUEUE_BIT;
- writew(priv(dev)->hw_config_bits,
- priv(dev)->main_iobase + HW_CONFIG_REG);
+ devpriv->hw_config_bits &= ~EXT_QUEUE_BIT;
+ writew(devpriv->hw_config_bits,
+ devpriv->main_iobase + HW_CONFIG_REG);
/* ALT_SOURCE is internal calibration reference */
if (insn->chanspec & CR_ALT_SOURCE) {
unsigned int cal_en_bit;
DEBUG_PRINT("reading calibration source\n");
- if (board(dev)->layout == LAYOUT_60XX)
+ if (thisboard->layout == LAYOUT_60XX)
cal_en_bit = CAL_EN_60XX_BIT;
else
cal_en_bit = CAL_EN_64XX_BIT;
- /* select internal reference source to connect to channel 0 */
+ /* select internal reference source to connect
+ * to channel 0 */
writew(cal_en_bit |
- adc_src_bits(priv(dev)->calibration_source),
- priv(dev)->main_iobase + CALIBRATION_REG);
+ adc_src_bits(devpriv->calibration_source),
+ devpriv->main_iobase + CALIBRATION_REG);
} else {
- /* make sure internal calibration source is turned off */
- writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+ /* make sure internal calibration source
+ * is turned off */
+ writew(0, devpriv->main_iobase + CALIBRATION_REG);
}
/* load internal queue */
bits = 0;
@@ -1916,56 +1803,56 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
bits |= adc_chan_bits(channel);
/* set stop channel */
writew(adc_chan_bits(channel),
- priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG);
+ devpriv->main_iobase + ADC_QUEUE_HIGH_REG);
/* set start channel, and rest of settings */
- writew(bits, priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
+ writew(bits, devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
} else {
- uint8_t old_cal_range_bits = priv(dev)->i2c_cal_range_bits;
+ uint8_t old_cal_range_bits = devpriv->i2c_cal_range_bits;
- priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
+ devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
if (insn->chanspec & CR_ALT_SOURCE) {
DEBUG_PRINT("reading calibration source\n");
- priv(dev)->i2c_cal_range_bits |=
- adc_src_4020_bits(priv(dev)->calibration_source);
+ devpriv->i2c_cal_range_bits |=
+ adc_src_4020_bits(devpriv->calibration_source);
} else { /* select BNC inputs */
- priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4);
+ devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4);
}
/* select range */
if (range == 0)
- priv(dev)->i2c_cal_range_bits |= attenuate_bit(channel);
+ devpriv->i2c_cal_range_bits |= attenuate_bit(channel);
else
- priv(dev)->i2c_cal_range_bits &=
- ~attenuate_bit(channel);
- /* update calibration/range i2c register only if necessary, as it is very slow */
- if (old_cal_range_bits != priv(dev)->i2c_cal_range_bits) {
- uint8_t i2c_data = priv(dev)->i2c_cal_range_bits;
+ devpriv->i2c_cal_range_bits &= ~attenuate_bit(channel);
+ /* update calibration/range i2c register only if necessary,
+ * as it is very slow */
+ if (old_cal_range_bits != devpriv->i2c_cal_range_bits) {
+ uint8_t i2c_data = devpriv->i2c_cal_range_bits;
i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
sizeof(i2c_data));
}
- /* 4020 manual asks that sample interval register to be set before writing to convert register.
- * Using somewhat arbitrary setting of 4 master clock ticks = 0.1 usec */
- writew(0,
- priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
- writew(2,
- priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
+ /* 4020 manual asks that sample interval register to be set
+ * before writing to convert register.
+ * Using somewhat arbitrary setting of 4 master clock ticks
+ * = 0.1 usec */
+ writew(0, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
+ writew(2, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
}
for (n = 0; n < insn->n; n++) {
/* clear adc buffer (inside loop for 4020 sake) */
- writew(0, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG);
+ writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG);
/* trigger conversion, bits sent only matter for 4020 */
writew(adc_convert_chan_4020_bits(CR_CHAN(insn->chanspec)),
- priv(dev)->main_iobase + ADC_CONVERT_REG);
+ devpriv->main_iobase + ADC_CONVERT_REG);
/* wait for data */
for (i = 0; i < timeout; i++) {
- bits = readw(priv(dev)->main_iobase + HW_STATUS_REG);
+ bits = readw(devpriv->main_iobase + HW_STATUS_REG);
DEBUG_PRINT(" pipe bits 0x%x\n", pipe_full_bits(bits));
- if (board(dev)->layout == LAYOUT_4020) {
- if (readw(priv(dev)->main_iobase +
+ if (thisboard->layout == LAYOUT_4020) {
+ if (readw(devpriv->main_iobase +
ADC_WRITE_PNTR_REG))
break;
} else {
@@ -1977,16 +1864,14 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
DEBUG_PRINT(" looped %i times waiting for data\n", i);
if (i == timeout) {
comedi_error(dev, " analog input read insn timed out");
- printk(" status 0x%x\n", bits);
+ dev_info(dev->class_dev, "status 0x%x\n", bits);
return -ETIME;
}
- if (board(dev)->layout == LAYOUT_4020)
- data[n] =
- readl(priv(dev)->dio_counter_iobase +
- ADC_FIFO_REG) & 0xffff;
+ if (thisboard->layout == LAYOUT_4020)
+ data[n] = readl(devpriv->dio_counter_iobase +
+ ADC_FIFO_REG) & 0xffff;
else
- data[n] =
- readw(priv(dev)->main_iobase + PIPE1_READ_REG);
+ data[n] = readw(devpriv->main_iobase + PIPE1_READ_REG);
}
return n;
@@ -1995,10 +1880,12 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
static int ai_config_calibration_source(struct comedi_device *dev,
unsigned int *data)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
unsigned int source = data[1];
int num_calibration_sources;
- if (board(dev)->layout == LAYOUT_60XX)
+ if (thisboard->layout == LAYOUT_60XX)
num_calibration_sources = 16;
else
num_calibration_sources = 8;
@@ -2009,23 +1896,24 @@ static int ai_config_calibration_source(struct comedi_device *dev,
}
DEBUG_PRINT("setting calibration source to %i\n", source);
- priv(dev)->calibration_source = source;
+ devpriv->calibration_source = source;
return 2;
}
static int ai_config_block_size(struct comedi_device *dev, unsigned int *data)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
int fifo_size;
- const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
+ const struct hw_fifo_info *const fifo = thisboard->ai_fifo;
unsigned int block_size, requested_block_size;
int retval;
requested_block_size = data[1];
if (requested_block_size) {
- fifo_size =
- requested_block_size * fifo->num_segments / bytes_in_sample;
+ fifo_size = requested_block_size * fifo->num_segments /
+ bytes_in_sample;
retval = set_ai_fifo_size(dev, fifo_size);
if (retval < 0)
@@ -2043,6 +1931,7 @@ static int ai_config_block_size(struct comedi_device *dev, unsigned int *data)
static int ai_config_master_clock_4020(struct comedi_device *dev,
unsigned int *data)
{
+ struct pcidas64_private *devpriv = dev->private;
unsigned int divisor = data[4];
int retval = 0;
@@ -2053,8 +1942,8 @@ static int ai_config_master_clock_4020(struct comedi_device *dev,
switch (data[1]) {
case COMEDI_EV_SCAN_BEGIN:
- priv(dev)->ext_clock.divisor = divisor;
- priv(dev)->ext_clock.chanspec = data[2];
+ devpriv->ext_clock.divisor = divisor;
+ devpriv->ext_clock.chanspec = data[2];
break;
default:
return -EINVAL;
@@ -2069,8 +1958,9 @@ static int ai_config_master_clock_4020(struct comedi_device *dev,
/* XXX could add support for 60xx series */
static int ai_config_master_clock(struct comedi_device *dev, unsigned int *data)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
- switch (board(dev)->layout) {
+ switch (thisboard->layout) {
case LAYOUT_4020:
return ai_config_master_clock_4020(dev, data);
break;
@@ -2104,9 +1994,84 @@ static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
return -EINVAL;
}
+/* Gets nearest achievable timing given master clock speed, does not
+ * take into account possible minimum/maximum divisor values. Used
+ * by other timing checking functions. */
+static unsigned int get_divisor(unsigned int ns, unsigned int flags)
+{
+ unsigned int divisor;
+
+ switch (flags & TRIG_ROUND_MASK) {
+ case TRIG_ROUND_UP:
+ divisor = (ns + TIMER_BASE - 1) / TIMER_BASE;
+ break;
+ case TRIG_ROUND_DOWN:
+ divisor = ns / TIMER_BASE;
+ break;
+ case TRIG_ROUND_NEAREST:
+ default:
+ divisor = (ns + TIMER_BASE / 2) / TIMER_BASE;
+ break;
+ }
+ return divisor;
+}
+
+/* utility function that rounds desired timing to an achievable time, and
+ * sets cmd members appropriately.
+ * adc paces conversions from master clock by dividing by (x + 3) where x is 24 bit number
+ */
+static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
+{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ unsigned int convert_divisor = 0, scan_divisor;
+ static const int min_convert_divisor = 3;
+ static const int max_convert_divisor =
+ max_counter_value + min_convert_divisor;
+ static const int min_scan_divisor_4020 = 2;
+ unsigned long long max_scan_divisor, min_scan_divisor;
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (thisboard->layout == LAYOUT_4020) {
+ cmd->convert_arg = 0;
+ } else {
+ convert_divisor = get_divisor(cmd->convert_arg,
+ cmd->flags);
+ if (convert_divisor > max_convert_divisor)
+ convert_divisor = max_convert_divisor;
+ if (convert_divisor < min_convert_divisor)
+ convert_divisor = min_convert_divisor;
+ cmd->convert_arg = convert_divisor * TIMER_BASE;
+ }
+ } else if (cmd->convert_src == TRIG_NOW) {
+ cmd->convert_arg = 0;
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags);
+ if (cmd->convert_src == TRIG_TIMER) {
+ /* XXX check for integer overflows */
+ min_scan_divisor = convert_divisor * cmd->chanlist_len;
+ max_scan_divisor =
+ (convert_divisor * cmd->chanlist_len - 1) +
+ max_counter_value;
+ } else {
+ min_scan_divisor = min_scan_divisor_4020;
+ max_scan_divisor = max_counter_value + min_scan_divisor;
+ }
+ if (scan_divisor > max_scan_divisor)
+ scan_divisor = max_scan_divisor;
+ if (scan_divisor < min_scan_divisor)
+ scan_divisor = min_scan_divisor;
+ cmd->scan_begin_arg = scan_divisor * TIMER_BASE;
+ }
+
+ return;
+}
+
static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
int err = 0;
unsigned int tmp_arg, tmp_arg2;
int i;
@@ -2118,22 +2083,21 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
triggers = TRIG_TIMER;
- if (board(dev)->layout == LAYOUT_4020)
+ if (thisboard->layout == LAYOUT_4020)
triggers |= TRIG_OTHER;
else
triggers |= TRIG_FOLLOW;
err |= cfc_check_trigger_src(&cmd->scan_begin_src, triggers);
triggers = TRIG_TIMER;
- if (board(dev)->layout == LAYOUT_4020)
+ if (thisboard->layout == LAYOUT_4020)
triggers |= TRIG_NOW;
else
triggers |= TRIG_EXT;
err |= cfc_check_trigger_src(&cmd->convert_src, triggers);
-
err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
err |= cfc_check_trigger_src(&cmd->stop_src,
- TRIG_COUNT | TRIG_EXT | TRIG_NONE);
+ TRIG_COUNT | TRIG_EXT | TRIG_NONE);
if (err)
return 1;
@@ -2156,55 +2120,34 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
if (cmd->convert_src == TRIG_TIMER) {
- if (board(dev)->layout == LAYOUT_4020) {
- if (cmd->convert_arg) {
- cmd->convert_arg = 0;
- err++;
- }
+ if (thisboard->layout == LAYOUT_4020) {
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
} else {
- if (cmd->convert_arg < board(dev)->ai_speed) {
- cmd->convert_arg = board(dev)->ai_speed;
- err++;
- }
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* if scans are timed faster than conversion rate allows */
- if (cmd->convert_arg * cmd->chanlist_len >
- cmd->scan_begin_arg) {
- cmd->scan_begin_arg =
- cmd->convert_arg *
- cmd->chanlist_len;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ thisboard->ai_speed);
+ /* if scans are timed faster than conversion rate allows */
+ if (cmd->scan_begin_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(
+ &cmd->scan_begin_arg,
+ cmd->convert_arg *
+ cmd->chanlist_len);
}
}
- if (!cmd->chanlist_len) {
- cmd->chanlist_len = 1;
- err++;
- }
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
switch (cmd->stop_src) {
case TRIG_EXT:
break;
case TRIG_COUNT:
- if (!cmd->stop_arg) {
- cmd->stop_arg = 1;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
break;
case TRIG_NONE:
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
break;
default:
break;
@@ -2240,7 +2183,7 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
}
}
/* check 4020 chanlist */
- if (board(dev)->layout == LAYOUT_4020) {
+ if (thisboard->layout == LAYOUT_4020) {
unsigned int first_channel = CR_CHAN(cmd->chanlist[0]);
for (i = 1; i < cmd->chanlist_len; i++) {
if (CR_CHAN(cmd->chanlist[i]) !=
@@ -2279,89 +2222,37 @@ static int use_hw_sample_counter(struct comedi_cmd *cmd)
static void setup_sample_counters(struct comedi_device *dev,
struct comedi_cmd *cmd)
{
+ struct pcidas64_private *devpriv = dev->private;
+
if (cmd->stop_src == TRIG_COUNT) {
/* set software count */
- priv(dev)->ai_count = cmd->stop_arg * cmd->chanlist_len;
+ devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len;
}
/* load hardware conversion counter */
if (use_hw_sample_counter(cmd)) {
writew(cmd->stop_arg & 0xffff,
- priv(dev)->main_iobase + ADC_COUNT_LOWER_REG);
+ devpriv->main_iobase + ADC_COUNT_LOWER_REG);
writew((cmd->stop_arg >> 16) & 0xff,
- priv(dev)->main_iobase + ADC_COUNT_UPPER_REG);
+ devpriv->main_iobase + ADC_COUNT_UPPER_REG);
} else {
- writew(1, priv(dev)->main_iobase + ADC_COUNT_LOWER_REG);
+ writew(1, devpriv->main_iobase + ADC_COUNT_LOWER_REG);
}
}
static inline unsigned int dma_transfer_size(struct comedi_device *dev)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
unsigned int num_samples;
- num_samples =
- priv(dev)->ai_fifo_segment_length *
- board(dev)->ai_fifo->sample_packing_ratio;
+ num_samples = devpriv->ai_fifo_segment_length *
+ thisboard->ai_fifo->sample_packing_ratio;
if (num_samples > DMA_BUFFER_SIZE / sizeof(uint16_t))
num_samples = DMA_BUFFER_SIZE / sizeof(uint16_t);
return num_samples;
}
-static void disable_ai_pacing(struct comedi_device *dev)
-{
- unsigned long flags;
-
- disable_ai_interrupts(dev);
-
- spin_lock_irqsave(&dev->spinlock, flags);
- priv(dev)->adc_control1_bits &= ~ADC_SW_GATE_BIT;
- writew(priv(dev)->adc_control1_bits,
- priv(dev)->main_iobase + ADC_CONTROL1_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- /* disable pacing, triggering, etc */
- writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT,
- priv(dev)->main_iobase + ADC_CONTROL0_REG);
-}
-
-static void disable_ai_interrupts(struct comedi_device *dev)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- priv(dev)->intr_enable_bits &=
- ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT &
- ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT &
- ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK;
- writew(priv(dev)->intr_enable_bits,
- priv(dev)->main_iobase + INTR_ENABLE_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits);
-}
-
-static void enable_ai_interrupts(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- uint32_t bits;
- unsigned long flags;
-
- bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT |
- EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT;
- /* Use pio transfer and interrupt on end of conversion if TRIG_WAKE_EOS flag is set. */
- if (cmd->flags & TRIG_WAKE_EOS) {
- /* 4020 doesn't support pio transfers except for fifo dregs */
- if (board(dev)->layout != LAYOUT_4020)
- bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT;
- }
- spin_lock_irqsave(&dev->spinlock, flags);
- priv(dev)->intr_enable_bits |= bits;
- writew(priv(dev)->intr_enable_bits,
- priv(dev)->main_iobase + INTR_ENABLE_REG);
- DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
static uint32_t ai_convert_counter_6xxx(const struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
@@ -2373,12 +2264,13 @@ static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev,
struct comedi_cmd *cmd)
{
uint32_t count;
+
/* figure out how long we need to delay at end of scan */
switch (cmd->scan_begin_src) {
case TRIG_TIMER:
count = (cmd->scan_begin_arg -
- (cmd->convert_arg * (cmd->chanlist_len - 1)))
- / TIMER_BASE;
+ (cmd->convert_arg * (cmd->chanlist_len - 1))) /
+ TIMER_BASE;
break;
case TRIG_FOLLOW:
count = cmd->convert_arg / TIMER_BASE;
@@ -2393,6 +2285,7 @@ static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev,
static uint32_t ai_convert_counter_4020(struct comedi_device *dev,
struct comedi_cmd *cmd)
{
+ struct pcidas64_private *devpriv = dev->private;
unsigned int divisor;
switch (cmd->scan_begin_src) {
@@ -2400,7 +2293,7 @@ static uint32_t ai_convert_counter_4020(struct comedi_device *dev,
divisor = cmd->scan_begin_arg / TIMER_BASE;
break;
case TRIG_OTHER:
- divisor = priv(dev)->ext_clock.divisor;
+ divisor = devpriv->ext_clock.divisor;
break;
default: /* should never happen */
comedi_error(dev, "bug! failed to set ai pacing!");
@@ -2415,26 +2308,30 @@ static uint32_t ai_convert_counter_4020(struct comedi_device *dev,
static void select_master_clock_4020(struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
+ struct pcidas64_private *devpriv = dev->private;
+
/* select internal/external master clock */
- priv(dev)->hw_config_bits &= ~MASTER_CLOCK_4020_MASK;
+ devpriv->hw_config_bits &= ~MASTER_CLOCK_4020_MASK;
if (cmd->scan_begin_src == TRIG_OTHER) {
- int chanspec = priv(dev)->ext_clock.chanspec;
+ int chanspec = devpriv->ext_clock.chanspec;
if (CR_CHAN(chanspec))
- priv(dev)->hw_config_bits |= BNC_CLOCK_4020_BITS;
+ devpriv->hw_config_bits |= BNC_CLOCK_4020_BITS;
else
- priv(dev)->hw_config_bits |= EXT_CLOCK_4020_BITS;
+ devpriv->hw_config_bits |= EXT_CLOCK_4020_BITS;
} else {
- priv(dev)->hw_config_bits |= INTERNAL_CLOCK_4020_BITS;
+ devpriv->hw_config_bits |= INTERNAL_CLOCK_4020_BITS;
}
- writew(priv(dev)->hw_config_bits,
- priv(dev)->main_iobase + HW_CONFIG_REG);
+ writew(devpriv->hw_config_bits,
+ devpriv->main_iobase + HW_CONFIG_REG);
}
static void select_master_clock(struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
- switch (board(dev)->layout) {
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+
+ switch (thisboard->layout) {
case LAYOUT_4020:
select_master_clock_4020(dev, cmd);
break;
@@ -2446,6 +2343,7 @@ static void select_master_clock(struct comedi_device *dev,
static inline void dma_start_sync(struct comedi_device *dev,
unsigned int channel)
{
+ struct pcidas64_private *devpriv = dev->private;
unsigned long flags;
/* spinlock for plx dma control/status reg */
@@ -2453,23 +2351,25 @@ static inline void dma_start_sync(struct comedi_device *dev,
if (channel)
writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT |
PLX_CLEAR_DMA_INTR_BIT,
- priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ devpriv->plx9080_iobase + PLX_DMA1_CS_REG);
else
writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT |
PLX_CLEAR_DMA_INTR_BIT,
- priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
spin_unlock_irqrestore(&dev->spinlock, flags);
}
static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
uint32_t convert_counter = 0, scan_counter = 0;
check_adc_timing(dev, cmd);
select_master_clock(dev, cmd);
- if (board(dev)->layout == LAYOUT_4020) {
+ if (thisboard->layout == LAYOUT_4020) {
convert_counter = ai_convert_counter_4020(dev, cmd);
} else {
convert_counter = ai_convert_counter_6xxx(dev, cmd);
@@ -2478,23 +2378,24 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd)
/* load lower 16 bits of convert interval */
writew(convert_counter & 0xffff,
- priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
+ devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
DEBUG_PRINT("convert counter 0x%x\n", convert_counter);
/* load upper 8 bits of convert interval */
writew((convert_counter >> 16) & 0xff,
- priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
+ devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
/* load lower 16 bits of scan delay */
writew(scan_counter & 0xffff,
- priv(dev)->main_iobase + ADC_DELAY_INTERVAL_LOWER_REG);
+ devpriv->main_iobase + ADC_DELAY_INTERVAL_LOWER_REG);
/* load upper 8 bits of scan delay */
writew((scan_counter >> 16) & 0xff,
- priv(dev)->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG);
+ devpriv->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG);
DEBUG_PRINT("scan counter 0x%x\n", scan_counter);
}
static int use_internal_queue_6xxx(const struct comedi_cmd *cmd)
{
int i;
+
for (i = 0; i + 1 < cmd->chanlist_len; i++) {
if (CR_CHAN(cmd->chanlist[i + 1]) !=
CR_CHAN(cmd->chanlist[i]) + 1)
@@ -2511,14 +2412,16 @@ static int use_internal_queue_6xxx(const struct comedi_cmd *cmd)
static int setup_channel_queue(struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
unsigned short bits;
int i;
- if (board(dev)->layout != LAYOUT_4020) {
+ if (thisboard->layout != LAYOUT_4020) {
if (use_internal_queue_6xxx(cmd)) {
- priv(dev)->hw_config_bits &= ~EXT_QUEUE_BIT;
- writew(priv(dev)->hw_config_bits,
- priv(dev)->main_iobase + HW_CONFIG_REG);
+ devpriv->hw_config_bits &= ~EXT_QUEUE_BIT;
+ writew(devpriv->hw_config_bits,
+ devpriv->main_iobase + HW_CONFIG_REG);
bits = 0;
/* set channel */
bits |= adc_chan_bits(CR_CHAN(cmd->chanlist[0]));
@@ -2534,30 +2437,30 @@ static int setup_channel_queue(struct comedi_device *dev,
/* set stop channel */
writew(adc_chan_bits
(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])),
- priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG);
+ devpriv->main_iobase + ADC_QUEUE_HIGH_REG);
/* set start channel, and rest of settings */
writew(bits,
- priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
+ devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
} else {
/* use external queue */
if (dev->write_subdev && dev->write_subdev->busy) {
warn_external_queue(dev);
return -EBUSY;
}
- priv(dev)->hw_config_bits |= EXT_QUEUE_BIT;
- writew(priv(dev)->hw_config_bits,
- priv(dev)->main_iobase + HW_CONFIG_REG);
+ devpriv->hw_config_bits |= EXT_QUEUE_BIT;
+ writew(devpriv->hw_config_bits,
+ devpriv->main_iobase + HW_CONFIG_REG);
/* clear DAC buffer to prevent weird interactions */
writew(0,
- priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG);
+ devpriv->main_iobase + DAC_BUFFER_CLEAR_REG);
/* clear queue pointer */
- writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
+ writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
/* load external queue */
for (i = 0; i < cmd->chanlist_len; i++) {
bits = 0;
/* set channel */
- bits |=
- adc_chan_bits(CR_CHAN(cmd->chanlist[i]));
+ bits |= adc_chan_bits(CR_CHAN(cmd->
+ chanlist[i]));
/* set gain */
bits |= ai_range_bits_6xxx(dev,
CR_RANGE(cmd->
@@ -2573,42 +2476,42 @@ static int setup_channel_queue(struct comedi_device *dev,
/* mark end of queue */
if (i == cmd->chanlist_len - 1)
bits |= QUEUE_EOSCAN_BIT |
- QUEUE_EOSEQ_BIT;
+ QUEUE_EOSEQ_BIT;
writew(bits,
- priv(dev)->main_iobase +
+ devpriv->main_iobase +
ADC_QUEUE_FIFO_REG);
- DEBUG_PRINT
- ("wrote 0x%x to external channel queue\n",
- bits);
+ DEBUG_PRINT(
+ "wrote 0x%x to external channel queue\n",
+ bits);
}
/* doing a queue clear is not specified in board docs,
* but required for reliable operation */
- writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
+ writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
/* prime queue holding register */
- writew(0, priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
+ writew(0, devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
}
} else {
- unsigned short old_cal_range_bits =
- priv(dev)->i2c_cal_range_bits;
+ unsigned short old_cal_range_bits = devpriv->i2c_cal_range_bits;
- priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
+ devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
/* select BNC inputs */
- priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4);
+ devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4);
/* select ranges */
for (i = 0; i < cmd->chanlist_len; i++) {
unsigned int channel = CR_CHAN(cmd->chanlist[i]);
unsigned int range = CR_RANGE(cmd->chanlist[i]);
if (range == 0)
- priv(dev)->i2c_cal_range_bits |=
- attenuate_bit(channel);
+ devpriv->i2c_cal_range_bits |=
+ attenuate_bit(channel);
else
- priv(dev)->i2c_cal_range_bits &=
- ~attenuate_bit(channel);
+ devpriv->i2c_cal_range_bits &=
+ ~attenuate_bit(channel);
}
- /* update calibration/range i2c register only if necessary, as it is very slow */
- if (old_cal_range_bits != priv(dev)->i2c_cal_range_bits) {
- uint8_t i2c_data = priv(dev)->i2c_cal_range_bits;
+ /* update calibration/range i2c register only if necessary,
+ * as it is very slow */
+ if (old_cal_range_bits != devpriv->i2c_cal_range_bits) {
+ uint8_t i2c_data = devpriv->i2c_cal_range_bits;
i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
sizeof(i2c_data));
}
@@ -2620,6 +2523,8 @@ static inline void load_first_dma_descriptor(struct comedi_device *dev,
unsigned int dma_channel,
unsigned int descriptor_bits)
{
+ struct pcidas64_private *devpriv = dev->private;
+
/* The transfer size, pci address, and local address registers
* are supposedly unused during chained dma,
* but I have found that left over values from last operation
@@ -2627,25 +2532,27 @@ static inline void load_first_dma_descriptor(struct comedi_device *dev,
* block. Initializing them to zero seems to fix the problem. */
if (dma_channel) {
writel(0,
- priv(dev)->plx9080_iobase + PLX_DMA1_TRANSFER_SIZE_REG);
- writel(0, priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG);
+ devpriv->plx9080_iobase + PLX_DMA1_TRANSFER_SIZE_REG);
+ writel(0, devpriv->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG);
writel(0,
- priv(dev)->plx9080_iobase + PLX_DMA1_LOCAL_ADDRESS_REG);
+ devpriv->plx9080_iobase + PLX_DMA1_LOCAL_ADDRESS_REG);
writel(descriptor_bits,
- priv(dev)->plx9080_iobase + PLX_DMA1_DESCRIPTOR_REG);
+ devpriv->plx9080_iobase + PLX_DMA1_DESCRIPTOR_REG);
} else {
writel(0,
- priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
- writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
+ devpriv->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
+ writel(0, devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
writel(0,
- priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
+ devpriv->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
writel(descriptor_bits,
- priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
+ devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
}
}
static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
uint32_t bits;
@@ -2661,7 +2568,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
return retval;
/* make sure internal calibration source is turned off */
- writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+ writew(0, devpriv->main_iobase + CALIBRATION_REG);
set_ai_pacing(dev, cmd);
@@ -2671,50 +2578,51 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
spin_lock_irqsave(&dev->spinlock, flags);
/* set mode, allow conversions through software gate */
- priv(dev)->adc_control1_bits |= ADC_SW_GATE_BIT;
- priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT;
- if (board(dev)->layout != LAYOUT_4020) {
- priv(dev)->adc_control1_bits &= ~ADC_MODE_MASK;
+ devpriv->adc_control1_bits |= ADC_SW_GATE_BIT;
+ devpriv->adc_control1_bits &= ~ADC_DITHER_BIT;
+ if (thisboard->layout != LAYOUT_4020) {
+ devpriv->adc_control1_bits &= ~ADC_MODE_MASK;
if (cmd->convert_src == TRIG_EXT)
- priv(dev)->adc_control1_bits |= adc_mode_bits(13); /* good old mode 13 */
+ /* good old mode 13 */
+ devpriv->adc_control1_bits |= adc_mode_bits(13);
else
- priv(dev)->adc_control1_bits |= adc_mode_bits(8); /* mode 8. What else could you need? */
+ /* mode 8. What else could you need? */
+ devpriv->adc_control1_bits |= adc_mode_bits(8);
} else {
- priv(dev)->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK;
+ devpriv->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK;
if (cmd->chanlist_len == 4)
- priv(dev)->adc_control1_bits |= FOUR_CHANNEL_4020_BITS;
+ devpriv->adc_control1_bits |= FOUR_CHANNEL_4020_BITS;
else if (cmd->chanlist_len == 2)
- priv(dev)->adc_control1_bits |= TWO_CHANNEL_4020_BITS;
- priv(dev)->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK;
- priv(dev)->adc_control1_bits |=
- adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0]));
- priv(dev)->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK;
- priv(dev)->adc_control1_bits |=
- adc_hi_chan_4020_bits(CR_CHAN
- (cmd->
- chanlist[cmd->chanlist_len - 1]));
+ devpriv->adc_control1_bits |= TWO_CHANNEL_4020_BITS;
+ devpriv->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK;
+ devpriv->adc_control1_bits |=
+ adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0]));
+ devpriv->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK;
+ devpriv->adc_control1_bits |=
+ adc_hi_chan_4020_bits(CR_CHAN(cmd->chanlist
+ [cmd->chanlist_len - 1]));
}
- writew(priv(dev)->adc_control1_bits,
- priv(dev)->main_iobase + ADC_CONTROL1_REG);
- DEBUG_PRINT("control1 bits 0x%x\n", priv(dev)->adc_control1_bits);
+ writew(devpriv->adc_control1_bits,
+ devpriv->main_iobase + ADC_CONTROL1_REG);
+ DEBUG_PRINT("control1 bits 0x%x\n", devpriv->adc_control1_bits);
spin_unlock_irqrestore(&dev->spinlock, flags);
/* clear adc buffer */
- writew(0, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG);
+ writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG);
if ((cmd->flags & TRIG_WAKE_EOS) == 0 ||
- board(dev)->layout == LAYOUT_4020) {
- priv(dev)->ai_dma_index = 0;
+ thisboard->layout == LAYOUT_4020) {
+ devpriv->ai_dma_index = 0;
/* set dma transfer size */
- for (i = 0; i < ai_dma_ring_count(board(dev)); i++)
- priv(dev)->ai_dma_desc[i].transfer_size =
- cpu_to_le32(dma_transfer_size(dev) *
- sizeof(uint16_t));
+ for (i = 0; i < ai_dma_ring_count(thisboard); i++)
+ devpriv->ai_dma_desc[i].transfer_size =
+ cpu_to_le32(dma_transfer_size(dev) *
+ sizeof(uint16_t));
/* give location of first dma descriptor */
load_first_dma_descriptor(dev, 1,
- priv(dev)->ai_dma_desc_bus_addr |
+ devpriv->ai_dma_desc_bus_addr |
PLX_DESC_IN_PCI_BIT |
PLX_INTR_TERM_COUNT |
PLX_XFER_LOCAL_TO_PCI);
@@ -2722,14 +2630,14 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
dma_start_sync(dev, 1);
}
- if (board(dev)->layout == LAYOUT_4020) {
+ if (thisboard->layout == LAYOUT_4020) {
/* set source for external triggers */
bits = 0;
if (cmd->start_src == TRIG_EXT && CR_CHAN(cmd->start_arg))
bits |= EXT_START_TRIG_BNC_BIT;
if (cmd->stop_src == TRIG_EXT && CR_CHAN(cmd->stop_arg))
bits |= EXT_STOP_TRIG_BNC_BIT;
- writew(bits, priv(dev)->main_iobase + DAQ_ATRIG_LOW_4020_REG);
+ writew(bits, devpriv->main_iobase + DAQ_ATRIG_LOW_4020_REG);
}
spin_lock_irqsave(&dev->spinlock, flags);
@@ -2747,16 +2655,16 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
bits |= ADC_START_TRIG_SOFT_BITS;
if (use_hw_sample_counter(cmd))
bits |= ADC_SAMPLE_COUNTER_EN_BIT;
- writew(bits, priv(dev)->main_iobase + ADC_CONTROL0_REG);
+ writew(bits, devpriv->main_iobase + ADC_CONTROL0_REG);
DEBUG_PRINT("control0 bits 0x%x\n", bits);
- priv(dev)->ai_cmd_running = 1;
+ devpriv->ai_cmd_running = 1;
spin_unlock_irqrestore(&dev->spinlock, flags);
/* start acquisition */
if (cmd->start_src == TRIG_NOW) {
- writew(0, priv(dev)->main_iobase + ADC_START_REG);
+ writew(0, devpriv->main_iobase + ADC_START_REG);
DEBUG_PRINT("soft trig\n");
}
@@ -2766,6 +2674,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* read num_samples from 16 bit wide ai fifo */
static void pio_drain_ai_fifo_16(struct comedi_device *dev)
{
+ struct pcidas64_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
@@ -2776,18 +2685,19 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev)
do {
/* get least significant 15 bits */
- read_index =
- readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
- write_index =
- readw(priv(dev)->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
- /* Get most significant bits (grey code). Different boards use different code
- * so use a scheme that doesn't depend on encoding. This read must
+ read_index = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) &
+ 0x7fff;
+ write_index = readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) &
+ 0x7fff;
+ /* Get most significant bits (grey code).
+ * Different boards use different code so use a scheme
+ * that doesn't depend on encoding. This read must
* occur after reading least significant 15 bits to avoid race
* with fifo switching to next segment. */
- prepost_bits = readw(priv(dev)->main_iobase + PREPOST_REG);
+ prepost_bits = readw(devpriv->main_iobase + PREPOST_REG);
- /* if read and write pointers are not on the same fifo segment, read to the
- * end of the read segment */
+ /* if read and write pointers are not on the same fifo segment,
+ * read to the end of the read segment */
read_segment = adc_upper_read_ptr_code(prepost_bits);
write_segment = adc_upper_write_ptr_code(prepost_bits);
@@ -2797,17 +2707,17 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev)
if (read_segment != write_segment)
num_samples =
- priv(dev)->ai_fifo_segment_length - read_index;
+ devpriv->ai_fifo_segment_length - read_index;
else
num_samples = write_index - read_index;
if (cmd->stop_src == TRIG_COUNT) {
- if (priv(dev)->ai_count == 0)
+ if (devpriv->ai_count == 0)
break;
- if (num_samples > priv(dev)->ai_count)
- num_samples = priv(dev)->ai_count;
+ if (num_samples > devpriv->ai_count)
+ num_samples = devpriv->ai_count;
- priv(dev)->ai_count -= num_samples;
+ devpriv->ai_count -= num_samples;
}
if (num_samples < 0) {
@@ -2820,20 +2730,21 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev)
for (i = 0; i < num_samples; i++) {
cfc_write_to_buffer(s,
- readw(priv(dev)->main_iobase +
+ readw(devpriv->main_iobase +
ADC_FIFO_REG));
}
} while (read_segment != write_segment);
}
-/* Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of pointers.
- * The pci-4020 hardware only supports
- * dma transfers (it only supports the use of pio for draining the last remaining
- * points from the fifo when a data acquisition operation has completed).
+/* Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of
+ * pointers. The pci-4020 hardware only supports dma transfers (it only
+ * supports the use of pio for draining the last remaining points from the
+ * fifo when a data acquisition operation has completed).
*/
static void pio_drain_ai_fifo_32(struct comedi_device *dev)
{
+ struct pcidas64_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
@@ -2841,33 +2752,35 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev)
unsigned int max_transfer = 100000;
uint32_t fifo_data;
int write_code =
- readw(priv(dev)->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
+ readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
int read_code =
- readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
+ readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
if (cmd->stop_src == TRIG_COUNT) {
- if (max_transfer > priv(dev)->ai_count)
- max_transfer = priv(dev)->ai_count;
+ if (max_transfer > devpriv->ai_count)
+ max_transfer = devpriv->ai_count;
}
for (i = 0; read_code != write_code && i < max_transfer;) {
- fifo_data = readl(priv(dev)->dio_counter_iobase + ADC_FIFO_REG);
+ fifo_data = readl(devpriv->dio_counter_iobase + ADC_FIFO_REG);
cfc_write_to_buffer(s, fifo_data & 0xffff);
i++;
if (i < max_transfer) {
cfc_write_to_buffer(s, (fifo_data >> 16) & 0xffff);
i++;
}
- read_code =
- readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
+ read_code = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) &
+ 0x7fff;
}
- priv(dev)->ai_count -= i;
+ devpriv->ai_count -= i;
}
/* empty fifo */
static void pio_drain_ai_fifo(struct comedi_device *dev)
{
- if (board(dev)->layout == LAYOUT_4020)
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+
+ if (thisboard->layout == LAYOUT_4020)
pio_drain_ai_fifo_32(dev);
else
pio_drain_ai_fifo_16(dev);
@@ -2875,6 +2788,8 @@ static void pio_drain_ai_fifo(struct comedi_device *dev)
static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
struct comedi_async *async = dev->read_subdev->async;
uint32_t next_transfer_addr;
int j;
@@ -2883,46 +2798,47 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
if (channel)
pci_addr_reg =
- priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
+ devpriv->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
else
pci_addr_reg =
- priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
+ devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
/* loop until we have read all the full buffers */
for (j = 0, next_transfer_addr = readl(pci_addr_reg);
(next_transfer_addr <
- priv(dev)->ai_buffer_bus_addr[priv(dev)->ai_dma_index]
- || next_transfer_addr >=
- priv(dev)->ai_buffer_bus_addr[priv(dev)->ai_dma_index] +
- DMA_BUFFER_SIZE) && j < ai_dma_ring_count(board(dev)); j++) {
+ devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] ||
+ next_transfer_addr >=
+ devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] +
+ DMA_BUFFER_SIZE) && j < ai_dma_ring_count(thisboard); j++) {
/* transfer data from dma buffer to comedi buffer */
num_samples = dma_transfer_size(dev);
if (async->cmd.stop_src == TRIG_COUNT) {
- if (num_samples > priv(dev)->ai_count)
- num_samples = priv(dev)->ai_count;
- priv(dev)->ai_count -= num_samples;
+ if (num_samples > devpriv->ai_count)
+ num_samples = devpriv->ai_count;
+ devpriv->ai_count -= num_samples;
}
cfc_write_array_to_buffer(dev->read_subdev,
- priv(dev)->ai_buffer[priv(dev)->
- ai_dma_index],
+ devpriv->ai_buffer[devpriv->
+ ai_dma_index],
num_samples * sizeof(uint16_t));
- priv(dev)->ai_dma_index =
- (priv(dev)->ai_dma_index +
- 1) % ai_dma_ring_count(board(dev));
+ devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) %
+ ai_dma_ring_count(thisboard);
DEBUG_PRINT("next buffer addr 0x%lx\n",
- (unsigned long)priv(dev)->
- ai_buffer_bus_addr[priv(dev)->ai_dma_index]);
+ (unsigned long)devpriv->
+ ai_buffer_bus_addr[devpriv->ai_dma_index]);
DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr);
}
- /* XXX check for dma ring buffer overrun (use end-of-chain bit to mark last
- * unused buffer) */
+ /* XXX check for dma ring buffer overrun
+ * (use end-of-chain bit to mark last unused buffer) */
}
static void handle_ai_interrupt(struct comedi_device *dev,
unsigned short status,
unsigned int plx_status)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
@@ -2936,10 +2852,10 @@ static void handle_ai_interrupt(struct comedi_device *dev,
}
/* spin lock makes sure no one else changes plx dma control reg */
spin_lock_irqsave(&dev->spinlock, flags);
- dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ dma1_status = readb(devpriv->plx9080_iobase + PLX_DMA1_CS_REG);
if (plx_status & ICS_DMA1_A) { /* dma chan 1 interrupt */
writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
- priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ devpriv->plx9080_iobase + PLX_DMA1_CS_REG);
DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
if (dma1_status & PLX_DMA_EN_BIT)
@@ -2956,17 +2872,17 @@ static void handle_ai_interrupt(struct comedi_device *dev,
if ((status & ADC_DONE_BIT) ||
((cmd->flags & TRIG_WAKE_EOS) &&
(status & ADC_INTR_PENDING_BIT) &&
- (board(dev)->layout != LAYOUT_4020))) {
+ (thisboard->layout != LAYOUT_4020))) {
DEBUG_PRINT("pio fifo drain\n");
spin_lock_irqsave(&dev->spinlock, flags);
- if (priv(dev)->ai_cmd_running) {
+ if (devpriv->ai_cmd_running) {
spin_unlock_irqrestore(&dev->spinlock, flags);
pio_drain_ai_fifo(dev);
} else
spin_unlock_irqrestore(&dev->spinlock, flags);
}
/* if we are have all the data, then quit */
- if ((cmd->stop_src == TRIG_COUNT && (int)priv(dev)->ai_count <= 0) ||
+ if ((cmd->stop_src == TRIG_COUNT && (int)devpriv->ai_count <= 0) ||
(cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT))) {
async->events |= COMEDI_CB_EOA;
}
@@ -2976,29 +2892,31 @@ static void handle_ai_interrupt(struct comedi_device *dev,
static inline unsigned int prev_ao_dma_index(struct comedi_device *dev)
{
+ struct pcidas64_private *devpriv = dev->private;
unsigned int buffer_index;
- if (priv(dev)->ao_dma_index == 0)
+ if (devpriv->ao_dma_index == 0)
buffer_index = AO_DMA_RING_COUNT - 1;
else
- buffer_index = priv(dev)->ao_dma_index - 1;
+ buffer_index = devpriv->ao_dma_index - 1;
return buffer_index;
}
static int last_ao_dma_load_completed(struct comedi_device *dev)
{
+ struct pcidas64_private *devpriv = dev->private;
unsigned int buffer_index;
unsigned int transfer_address;
unsigned short dma_status;
buffer_index = prev_ao_dma_index(dev);
- dma_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ dma_status = readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
if ((dma_status & PLX_DMA_DONE_BIT) == 0)
return 0;
transfer_address =
- readl(priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
- if (transfer_address != priv(dev)->ao_buffer_bus_addr[buffer_index])
+ readl(devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
+ if (transfer_address != devpriv->ao_buffer_bus_addr[buffer_index])
return 0;
return 1;
@@ -3007,10 +2925,12 @@ static int last_ao_dma_load_completed(struct comedi_device *dev)
static int ao_stopped_by_error(struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
+ struct pcidas64_private *devpriv = dev->private;
+
if (cmd->stop_src == TRIG_NONE)
return 1;
if (cmd->stop_src == TRIG_COUNT) {
- if (priv(dev)->ao_count)
+ if (devpriv->ao_count)
return 1;
if (last_ao_dma_load_completed(dev) == 0)
return 1;
@@ -3032,10 +2952,11 @@ static inline int ao_dma_needs_restart(struct comedi_device *dev,
static void restart_ao_dma(struct comedi_device *dev)
{
+ struct pcidas64_private *devpriv = dev->private;
unsigned int dma_desc_bits;
dma_desc_bits =
- readl(priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
+ readl(devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
dma_desc_bits &= ~PLX_END_OF_CHAIN_BIT;
DEBUG_PRINT("restarting ao dma, descriptor reg 0x%x\n", dma_desc_bits);
load_first_dma_descriptor(dev, 0, dma_desc_bits);
@@ -3043,9 +2964,81 @@ static void restart_ao_dma(struct comedi_device *dev)
dma_start_sync(dev, 0);
}
+static unsigned int load_ao_dma_buffer(struct comedi_device *dev,
+ const struct comedi_cmd *cmd)
+{
+ struct pcidas64_private *devpriv = dev->private;
+ unsigned int num_bytes, buffer_index, prev_buffer_index;
+ unsigned int next_bits;
+
+ buffer_index = devpriv->ao_dma_index;
+ prev_buffer_index = prev_ao_dma_index(dev);
+
+ DEBUG_PRINT("attempting to load ao buffer %i (0x%llx)\n", buffer_index,
+ (unsigned long long)devpriv->ao_buffer_bus_addr[
+ buffer_index]);
+
+ num_bytes = comedi_buf_read_n_available(dev->write_subdev->async);
+ if (num_bytes > DMA_BUFFER_SIZE)
+ num_bytes = DMA_BUFFER_SIZE;
+ if (cmd->stop_src == TRIG_COUNT && num_bytes > devpriv->ao_count)
+ num_bytes = devpriv->ao_count;
+ num_bytes -= num_bytes % bytes_in_sample;
+
+ if (num_bytes == 0)
+ return 0;
+
+ DEBUG_PRINT("loading %i bytes\n", num_bytes);
+
+ num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
+ devpriv->
+ ao_buffer[buffer_index],
+ num_bytes);
+ devpriv->ao_dma_desc[buffer_index].transfer_size =
+ cpu_to_le32(num_bytes);
+ /* set end of chain bit so we catch underruns */
+ next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next);
+ next_bits |= PLX_END_OF_CHAIN_BIT;
+ devpriv->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits);
+ /* clear end of chain bit on previous buffer now that we have set it
+ * for the last buffer */
+ next_bits = le32_to_cpu(devpriv->ao_dma_desc[prev_buffer_index].next);
+ next_bits &= ~PLX_END_OF_CHAIN_BIT;
+ devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits);
+
+ devpriv->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT;
+ devpriv->ao_count -= num_bytes;
+
+ return num_bytes;
+}
+
+static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
+{
+ struct pcidas64_private *devpriv = dev->private;
+ unsigned int num_bytes;
+ unsigned int next_transfer_addr;
+ void __iomem *pci_addr_reg =
+ devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
+ unsigned int buffer_index;
+
+ do {
+ buffer_index = devpriv->ao_dma_index;
+ /* don't overwrite data that hasn't been transferred yet */
+ next_transfer_addr = readl(pci_addr_reg);
+ if (next_transfer_addr >=
+ devpriv->ao_buffer_bus_addr[buffer_index] &&
+ next_transfer_addr <
+ devpriv->ao_buffer_bus_addr[buffer_index] +
+ DMA_BUFFER_SIZE)
+ return;
+ num_bytes = load_ao_dma_buffer(dev, cmd);
+ } while (num_bytes >= DMA_BUFFER_SIZE);
+}
+
static void handle_ao_interrupt(struct comedi_device *dev,
unsigned short status, unsigned int plx_status)
{
+ struct pcidas64_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->write_subdev;
struct comedi_async *async;
struct comedi_cmd *cmd;
@@ -3060,15 +3053,15 @@ static void handle_ao_interrupt(struct comedi_device *dev,
/* spin lock makes sure no one else changes plx dma control reg */
spin_lock_irqsave(&dev->spinlock, flags);
- dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ dma0_status = readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
if (plx_status & ICS_DMA0_A) { /* dma chan 0 interrupt */
- if ((dma0_status & PLX_DMA_EN_BIT)
- && !(dma0_status & PLX_DMA_DONE_BIT))
+ if ((dma0_status & PLX_DMA_EN_BIT) &&
+ !(dma0_status & PLX_DMA_DONE_BIT))
writeb(PLX_DMA_EN_BIT | PLX_CLEAR_DMA_INTR_BIT,
- priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
else
writeb(PLX_CLEAR_DMA_INTR_BIT,
- priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
spin_unlock_irqrestore(&dev->spinlock, flags);
DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
if (dma0_status & PLX_DMA_EN_BIT) {
@@ -3078,18 +3071,19 @@ static void handle_ao_interrupt(struct comedi_device *dev,
restart_ao_dma(dev);
}
DEBUG_PRINT(" cleared dma ch0 interrupt\n");
- } else
+ } else {
spin_unlock_irqrestore(&dev->spinlock, flags);
+ }
if ((status & DAC_DONE_BIT)) {
async->events |= COMEDI_CB_EOA;
if (ao_stopped_by_error(dev, cmd))
async->events |= COMEDI_CB_ERROR;
DEBUG_PRINT("plx dma0 desc reg 0x%x\n",
- readl(priv(dev)->plx9080_iobase +
+ readl(devpriv->plx9080_iobase +
PLX_DMA0_DESCRIPTOR_REG));
DEBUG_PRINT("plx dma0 address reg 0x%x\n",
- readl(priv(dev)->plx9080_iobase +
+ readl(devpriv->plx9080_iobase +
PLX_DMA0_PCI_ADDRESS_REG));
}
cfc_handle_events(dev, s);
@@ -3098,22 +3092,21 @@ static void handle_ao_interrupt(struct comedi_device *dev,
static irqreturn_t handle_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct pcidas64_private *devpriv = dev->private;
unsigned short status;
uint32_t plx_status;
uint32_t plx_bits;
- plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
- status = readw(priv(dev)->main_iobase + HW_STATUS_REG);
+ plx_status = readl(devpriv->plx9080_iobase + PLX_INTRCS_REG);
+ status = readw(devpriv->main_iobase + HW_STATUS_REG);
- DEBUG_PRINT("cb_pcidas64: hw status 0x%x ", status);
- DEBUG_PRINT("plx status 0x%x\n", plx_status);
+ DEBUG_PRINT("hw status 0x%x, plx status 0x%x\n", status, plx_status);
/* an interrupt before all the postconfig stuff gets done could
* cause a NULL dereference if we continue through the
* interrupt handler */
if (dev->attached == 0) {
- DEBUG_PRINT("cb_pcidas64: premature interrupt, ignoring",
- status);
+ DEBUG_PRINT("premature interrupt, ignoring\n");
return IRQ_HANDLED;
}
handle_ai_interrupt(dev, status, plx_status);
@@ -3121,8 +3114,8 @@ static irqreturn_t handle_interrupt(int irq, void *d)
/* clear possible plx9080 interrupt sources */
if (plx_status & ICS_LDIA) { /* clear local doorbell interrupt */
- plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
- writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
+ plx_bits = readl(devpriv->plx9080_iobase + PLX_DBR_OUT_REG);
+ writel(plx_bits, devpriv->plx9080_iobase + PLX_DBR_OUT_REG);
DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits);
}
@@ -3131,28 +3124,17 @@ static irqreturn_t handle_interrupt(int irq, void *d)
return IRQ_HANDLED;
}
-static void abort_dma(struct comedi_device *dev, unsigned int channel)
-{
- unsigned long flags;
-
- /* spinlock for plx dma control/status reg */
- spin_lock_irqsave(&dev->spinlock, flags);
-
- plx9080_abort_dma(priv(dev)->plx9080_iobase, channel);
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct pcidas64_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&dev->spinlock, flags);
- if (priv(dev)->ai_cmd_running == 0) {
+ if (devpriv->ai_cmd_running == 0) {
spin_unlock_irqrestore(&dev->spinlock, flags);
return 0;
}
- priv(dev)->ai_cmd_running = 0;
+ devpriv->ai_cmd_running = 0;
spin_unlock_irqrestore(&dev->spinlock, flags);
disable_ai_pacing(dev);
@@ -3166,29 +3148,31 @@ static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
int chan = CR_CHAN(insn->chanspec);
int range = CR_RANGE(insn->chanspec);
/* do some initializing */
- writew(0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+ writew(0, devpriv->main_iobase + DAC_CONTROL0_REG);
/* set range */
- set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, chan, range);
- writew(priv(dev)->dac_control1_bits,
- priv(dev)->main_iobase + DAC_CONTROL1_REG);
+ set_dac_range_bits(dev, &devpriv->dac_control1_bits, chan, range);
+ writew(devpriv->dac_control1_bits,
+ devpriv->main_iobase + DAC_CONTROL1_REG);
/* write to channel */
- if (board(dev)->layout == LAYOUT_4020) {
+ if (thisboard->layout == LAYOUT_4020) {
writew(data[0] & 0xff,
- priv(dev)->main_iobase + dac_lsb_4020_reg(chan));
+ devpriv->main_iobase + dac_lsb_4020_reg(chan));
writew((data[0] >> 8) & 0xf,
- priv(dev)->main_iobase + dac_msb_4020_reg(chan));
+ devpriv->main_iobase + dac_msb_4020_reg(chan));
} else {
- writew(data[0], priv(dev)->main_iobase + dac_convert_reg(chan));
+ writew(data[0], devpriv->main_iobase + dac_convert_reg(chan));
}
/* remember output value */
- priv(dev)->ao_value[chan] = data[0];
+ devpriv->ao_value[chan] = data[0];
return 1;
}
@@ -3197,7 +3181,9 @@ static int ao_readback_insn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
- data[0] = priv(dev)->ao_value[CR_CHAN(insn->chanspec)];
+ struct pcidas64_private *devpriv = dev->private;
+
+ data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
return 1;
}
@@ -3205,8 +3191,9 @@ static int ao_readback_insn(struct comedi_device *dev,
static void set_dac_control0_reg(struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
+ struct pcidas64_private *devpriv = dev->private;
unsigned int bits = DAC_ENABLE_BIT | WAVEFORM_GATE_LEVEL_BIT |
- WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT;
+ WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT;
if (cmd->start_src == TRIG_EXT) {
bits |= WAVEFORM_TRIG_EXT_BITS;
@@ -3220,12 +3207,13 @@ static void set_dac_control0_reg(struct comedi_device *dev,
if (cmd->scan_begin_arg & CR_INVERT)
bits |= DAC_EXT_UPDATE_FALLING_BIT;
}
- writew(bits, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+ writew(bits, devpriv->main_iobase + DAC_CONTROL0_REG);
}
static void set_dac_control1_reg(struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
+ struct pcidas64_private *devpriv = dev->private;
int i;
for (i = 0; i < cmd->chanlist_len; i++) {
@@ -3233,17 +3221,18 @@ static void set_dac_control1_reg(struct comedi_device *dev,
channel = CR_CHAN(cmd->chanlist[i]);
range = CR_RANGE(cmd->chanlist[i]);
- set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, channel,
+ set_dac_range_bits(dev, &devpriv->dac_control1_bits, channel,
range);
}
- priv(dev)->dac_control1_bits |= DAC_SW_GATE_BIT;
- writew(priv(dev)->dac_control1_bits,
- priv(dev)->main_iobase + DAC_CONTROL1_REG);
+ devpriv->dac_control1_bits |= DAC_SW_GATE_BIT;
+ writew(devpriv->dac_control1_bits,
+ devpriv->main_iobase + DAC_CONTROL1_REG);
}
static void set_dac_select_reg(struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
+ struct pcidas64_private *devpriv = dev->private;
uint16_t bits;
unsigned int first_channel, last_channel;
@@ -3254,12 +3243,18 @@ static void set_dac_select_reg(struct comedi_device *dev,
bits = (first_channel & 0x7) | (last_channel & 0x7) << 3;
- writew(bits, priv(dev)->main_iobase + DAC_SELECT_REG);
+ writew(bits, devpriv->main_iobase + DAC_SELECT_REG);
+}
+
+static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags)
+{
+ return get_divisor(ns, flags) - 2;
}
static void set_dac_interval_regs(struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
+ struct pcidas64_private *devpriv = dev->private;
unsigned int divisor;
if (cmd->scan_begin_src != TRIG_TIMER)
@@ -3271,102 +3266,35 @@ static void set_dac_interval_regs(struct comedi_device *dev,
divisor = max_counter_value;
}
writew(divisor & 0xffff,
- priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG);
+ devpriv->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG);
writew((divisor >> 16) & 0xff,
- priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG);
-}
-
-static unsigned int load_ao_dma_buffer(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- unsigned int num_bytes, buffer_index, prev_buffer_index;
- unsigned int next_bits;
-
- buffer_index = priv(dev)->ao_dma_index;
- prev_buffer_index = prev_ao_dma_index(dev);
-
- DEBUG_PRINT("attempting to load ao buffer %i (0x%x)\n", buffer_index,
- priv(dev)->ao_buffer_bus_addr[buffer_index]);
-
- num_bytes = comedi_buf_read_n_available(dev->write_subdev->async);
- if (num_bytes > DMA_BUFFER_SIZE)
- num_bytes = DMA_BUFFER_SIZE;
- if (cmd->stop_src == TRIG_COUNT && num_bytes > priv(dev)->ao_count)
- num_bytes = priv(dev)->ao_count;
- num_bytes -= num_bytes % bytes_in_sample;
-
- if (num_bytes == 0)
- return 0;
-
- DEBUG_PRINT("loading %i bytes\n", num_bytes);
-
- num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
- priv(dev)->
- ao_buffer[buffer_index],
- num_bytes);
- priv(dev)->ao_dma_desc[buffer_index].transfer_size =
- cpu_to_le32(num_bytes);
- /* set end of chain bit so we catch underruns */
- next_bits = le32_to_cpu(priv(dev)->ao_dma_desc[buffer_index].next);
- next_bits |= PLX_END_OF_CHAIN_BIT;
- priv(dev)->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits);
- /* clear end of chain bit on previous buffer now that we have set it
- * for the last buffer */
- next_bits = le32_to_cpu(priv(dev)->ao_dma_desc[prev_buffer_index].next);
- next_bits &= ~PLX_END_OF_CHAIN_BIT;
- priv(dev)->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits);
-
- priv(dev)->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT;
- priv(dev)->ao_count -= num_bytes;
-
- return num_bytes;
-}
-
-static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
-{
- unsigned int num_bytes;
- unsigned int next_transfer_addr;
- void __iomem *pci_addr_reg =
- priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
- unsigned int buffer_index;
-
- do {
- buffer_index = priv(dev)->ao_dma_index;
- /* don't overwrite data that hasn't been transferred yet */
- next_transfer_addr = readl(pci_addr_reg);
- if (next_transfer_addr >=
- priv(dev)->ao_buffer_bus_addr[buffer_index]
- && next_transfer_addr <
- priv(dev)->ao_buffer_bus_addr[buffer_index] +
- DMA_BUFFER_SIZE)
- return;
- num_bytes = load_ao_dma_buffer(dev, cmd);
- } while (num_bytes >= DMA_BUFFER_SIZE);
+ devpriv->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG);
}
static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
{
+ struct pcidas64_private *devpriv = dev->private;
unsigned int num_bytes;
int i;
/* clear queue pointer too, since external queue has
* weird interactions with ao fifo */
- writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
- writew(0, priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG);
+ writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
+ writew(0, devpriv->main_iobase + DAC_BUFFER_CLEAR_REG);
num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample;
if (cmd->stop_src == TRIG_COUNT &&
- num_bytes / bytes_in_sample > priv(dev)->ao_count)
- num_bytes = priv(dev)->ao_count * bytes_in_sample;
+ num_bytes / bytes_in_sample > devpriv->ao_count)
+ num_bytes = devpriv->ao_count * bytes_in_sample;
num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
- priv(dev)->ao_bounce_buffer,
+ devpriv->ao_bounce_buffer,
num_bytes);
for (i = 0; i < num_bytes / bytes_in_sample; i++) {
- writew(priv(dev)->ao_bounce_buffer[i],
- priv(dev)->main_iobase + DAC_FIFO_REG);
+ writew(devpriv->ao_bounce_buffer[i],
+ devpriv->main_iobase + DAC_FIFO_REG);
}
- priv(dev)->ao_count -= num_bytes / bytes_in_sample;
- if (cmd->stop_src == TRIG_COUNT && priv(dev)->ao_count == 0)
+ devpriv->ao_count -= num_bytes / bytes_in_sample;
+ if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count == 0)
return 0;
num_bytes = load_ao_dma_buffer(dev, cmd);
if (num_bytes == 0)
@@ -3381,43 +3309,21 @@ static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
static inline int external_ai_queue_in_use(struct comedi_device *dev)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+
if (dev->read_subdev->busy)
return 0;
- if (board(dev)->layout == LAYOUT_4020)
+ if (thisboard->layout == LAYOUT_4020)
return 0;
else if (use_internal_queue_6xxx(&dev->read_subdev->async->cmd))
return 0;
return 1;
}
-static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (external_ai_queue_in_use(dev)) {
- warn_external_queue(dev);
- return -EBUSY;
- }
- /* disable analog output system during setup */
- writew(0x0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
-
- priv(dev)->ao_dma_index = 0;
- priv(dev)->ao_count = cmd->stop_arg * cmd->chanlist_len;
-
- set_dac_select_reg(dev, cmd);
- set_dac_interval_regs(dev, cmd);
- load_first_dma_descriptor(dev, 0, priv(dev)->ao_dma_desc_bus_addr |
- PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT);
-
- set_dac_control1_reg(dev, cmd);
- s->async->inttrig = ao_inttrig;
-
- return 0;
-}
-
static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int trig_num)
{
+ struct pcidas64_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
int retval;
@@ -3431,16 +3337,43 @@ static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
set_dac_control0_reg(dev, cmd);
if (cmd->start_src == TRIG_INT)
- writew(0, priv(dev)->main_iobase + DAC_START_REG);
+ writew(0, devpriv->main_iobase + DAC_START_REG);
s->async->inttrig = NULL;
return 0;
}
+static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ struct pcidas64_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (external_ai_queue_in_use(dev)) {
+ warn_external_queue(dev);
+ return -EBUSY;
+ }
+ /* disable analog output system during setup */
+ writew(0x0, devpriv->main_iobase + DAC_CONTROL0_REG);
+
+ devpriv->ao_dma_index = 0;
+ devpriv->ao_count = cmd->stop_arg * cmd->chanlist_len;
+
+ set_dac_select_reg(dev, cmd);
+ set_dac_interval_regs(dev, cmd);
+ load_first_dma_descriptor(dev, 0, devpriv->ao_dma_desc_bus_addr |
+ PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT);
+
+ set_dac_control1_reg(dev, cmd);
+ s->async->inttrig = ao_inttrig;
+
+ return 0;
+}
+
static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
int err = 0;
unsigned int tmp_arg;
int i;
@@ -3449,7 +3382,7 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT);
err |= cfc_check_trigger_src(&cmd->scan_begin_src,
- TRIG_TIMER | TRIG_EXT);
+ TRIG_TIMER | TRIG_EXT);
err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
@@ -3473,29 +3406,21 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->scan_begin_arg < board(dev)->ao_scan_speed) {
- cmd->scan_begin_arg = board(dev)->ao_scan_speed;
- err++;
- }
- if (get_ao_divisor(cmd->scan_begin_arg,
- cmd->flags) > max_counter_value) {
- cmd->scan_begin_arg =
- (max_counter_value + 2) * TIMER_BASE;
- err++;
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ thisboard->ao_scan_speed);
+ if (get_ao_divisor(cmd->scan_begin_arg, cmd->flags) >
+ max_counter_value) {
+ cmd->scan_begin_arg = (max_counter_value + 2) *
+ TIMER_BASE;
+ err |= -EINVAL;
}
}
- if (!cmd->chanlist_len) {
- cmd->chanlist_len = 1;
- err++;
- }
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
if (err)
return 3;
@@ -3504,8 +3429,8 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if (cmd->scan_begin_src == TRIG_TIMER) {
tmp_arg = cmd->scan_begin_arg;
- cmd->scan_begin_arg =
- get_divisor(cmd->scan_begin_arg, cmd->flags) * TIMER_BASE;
+ cmd->scan_begin_arg = get_divisor(cmd->scan_begin_arg,
+ cmd->flags) * TIMER_BASE;
if (tmp_arg != cmd->scan_begin_arg)
err++;
}
@@ -3533,7 +3458,9 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
- writew(0x0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+ struct pcidas64_private *devpriv = dev->private;
+
+ writew(0x0, devpriv->main_iobase + DAC_CONTROL0_REG);
abort_dma(dev, 0);
return 0;
}
@@ -3564,9 +3491,10 @@ static int dio_callback_4020(int dir, int port, int data, unsigned long arg)
static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcidas64_private *devpriv = dev->private;
unsigned int bits;
- bits = readb(priv(dev)->dio_counter_iobase + DI_REG);
+ bits = readb(devpriv->dio_counter_iobase + DI_REG);
bits &= 0xf;
data[1] = bits;
data[0] = 0;
@@ -3577,13 +3505,15 @@ static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
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, priv(dev)->dio_counter_iobase + DO_REG);
+ writeb(s->state, devpriv->dio_counter_iobase + DO_REG);
data[1] = s->state;
@@ -3594,6 +3524,7 @@ static int dio_60xx_config_insn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcidas64_private *devpriv = dev->private;
unsigned int mask;
mask = 1 << CR_CHAN(insn->chanspec);
@@ -3613,7 +3544,7 @@ static int dio_60xx_config_insn(struct comedi_device *dev,
}
writeb(s->io_bits,
- priv(dev)->dio_counter_iobase + DIO_DIRECTION_60XX_REG);
+ devpriv->dio_counter_iobase + DIO_DIRECTION_60XX_REG);
return 1;
}
@@ -3621,24 +3552,143 @@ static int dio_60xx_config_insn(struct comedi_device *dev,
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]);
writeb(s->state,
- priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG);
+ devpriv->dio_counter_iobase + DIO_DATA_60XX_REG);
}
- data[1] = readb(priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG);
+ data[1] = readb(devpriv->dio_counter_iobase + DIO_DATA_60XX_REG);
return insn->n;
}
+/* pci-6025 8800 caldac:
+ * address 0 == dac channel 0 offset
+ * address 1 == dac channel 0 gain
+ * address 2 == dac channel 1 offset
+ * address 3 == dac channel 1 gain
+ * address 4 == fine adc offset
+ * address 5 == coarse adc offset
+ * address 6 == coarse adc gain
+ * address 7 == fine adc gain
+ */
+/* pci-6402/16 uses all 8 channels for dac:
+ * address 0 == dac channel 0 fine gain
+ * address 1 == dac channel 0 coarse gain
+ * address 2 == dac channel 0 coarse offset
+ * address 3 == dac channel 1 coarse offset
+ * address 4 == dac channel 1 fine gain
+ * address 5 == dac channel 1 coarse gain
+ * address 6 == dac channel 0 fine offset
+ * address 7 == dac channel 1 fine offset
+*/
+
+static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
+ uint8_t value)
+{
+ struct pcidas64_private *devpriv = dev->private;
+ static const int num_caldac_channels = 8;
+ static const int bitstream_length = 11;
+ unsigned int bitstream = ((address & 0x7) << 8) | value;
+ unsigned int bit, register_bits;
+ static const int caldac_8800_udelay = 1;
+
+ if (address >= num_caldac_channels) {
+ comedi_error(dev, "illegal caldac channel");
+ return -1;
+ }
+ for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
+ register_bits = 0;
+ if (bitstream & bit)
+ register_bits |= SERIAL_DATA_IN_BIT;
+ udelay(caldac_8800_udelay);
+ writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
+ register_bits |= SERIAL_CLOCK_BIT;
+ udelay(caldac_8800_udelay);
+ writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
+ }
+ udelay(caldac_8800_udelay);
+ writew(SELECT_8800_BIT, devpriv->main_iobase + CALIBRATION_REG);
+ udelay(caldac_8800_udelay);
+ writew(0, devpriv->main_iobase + CALIBRATION_REG);
+ udelay(caldac_8800_udelay);
+ return 0;
+}
+
+/* 4020 caldacs */
+static int caldac_i2c_write(struct comedi_device *dev,
+ unsigned int caldac_channel, unsigned int value)
+{
+ uint8_t serial_bytes[3];
+ uint8_t i2c_addr;
+ enum pointer_bits {
+ /* manual has gain and offset bits switched */
+ OFFSET_0_2 = 0x1,
+ GAIN_0_2 = 0x2,
+ OFFSET_1_3 = 0x4,
+ GAIN_1_3 = 0x8,
+ };
+ enum data_bits {
+ NOT_CLEAR_REGISTERS = 0x20,
+ };
+
+ switch (caldac_channel) {
+ case 0: /* chan 0 offset */
+ i2c_addr = CALDAC0_I2C_ADDR;
+ serial_bytes[0] = OFFSET_0_2;
+ break;
+ case 1: /* chan 1 offset */
+ i2c_addr = CALDAC0_I2C_ADDR;
+ serial_bytes[0] = OFFSET_1_3;
+ break;
+ case 2: /* chan 2 offset */
+ i2c_addr = CALDAC1_I2C_ADDR;
+ serial_bytes[0] = OFFSET_0_2;
+ break;
+ case 3: /* chan 3 offset */
+ i2c_addr = CALDAC1_I2C_ADDR;
+ serial_bytes[0] = OFFSET_1_3;
+ break;
+ case 4: /* chan 0 gain */
+ i2c_addr = CALDAC0_I2C_ADDR;
+ serial_bytes[0] = GAIN_0_2;
+ break;
+ case 5: /* chan 1 gain */
+ i2c_addr = CALDAC0_I2C_ADDR;
+ serial_bytes[0] = GAIN_1_3;
+ break;
+ case 6: /* chan 2 gain */
+ i2c_addr = CALDAC1_I2C_ADDR;
+ serial_bytes[0] = GAIN_0_2;
+ break;
+ case 7: /* chan 3 gain */
+ i2c_addr = CALDAC1_I2C_ADDR;
+ serial_bytes[0] = GAIN_1_3;
+ break;
+ default:
+ comedi_error(dev, "invalid caldac channel\n");
+ return -1;
+ break;
+ }
+ serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf);
+ serial_bytes[2] = value & 0xff;
+ i2c_write(dev, i2c_addr, serial_bytes, 3);
+ return 0;
+}
+
static void caldac_write(struct comedi_device *dev, unsigned int channel,
unsigned int value)
{
- priv(dev)->caldac_state[channel] = value;
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
+
+ devpriv->caldac_state[channel] = value;
- switch (board(dev)->layout) {
+ switch (thisboard->layout) {
case LAYOUT_60XX:
case LAYOUT_64XX:
caldac_8800_write(dev, channel, value);
@@ -3655,11 +3705,12 @@ static int calib_write_insn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcidas64_private *devpriv = dev->private;
int channel = CR_CHAN(insn->chanspec);
/* return immediately if setting hasn't changed, since
* programming these things is slow */
- if (priv(dev)->caldac_state[channel] == data[0])
+ if (devpriv->caldac_state[channel] == data[0])
return 1;
caldac_write(dev, channel, data[0]);
@@ -3671,9 +3722,10 @@ static int calib_read_insn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
+ struct pcidas64_private *devpriv = dev->private;
unsigned int channel = CR_CHAN(insn->chanspec);
- data[0] = priv(dev)->caldac_state[channel];
+ data[0] = devpriv->caldac_state[channel];
return 1;
}
@@ -3681,16 +3733,17 @@ static int calib_read_insn(struct comedi_device *dev,
static void ad8402_write(struct comedi_device *dev, unsigned int channel,
unsigned int value)
{
+ struct pcidas64_private *devpriv = dev->private;
static const int bitstream_length = 10;
unsigned int bit, register_bits;
unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
static const int ad8402_udelay = 1;
- priv(dev)->ad8402_state[channel] = value;
+ devpriv->ad8402_state[channel] = value;
register_bits = SELECT_8402_64XX_BIT;
udelay(ad8402_udelay);
- writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+ writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
if (bitstream & bit)
@@ -3698,14 +3751,14 @@ static void ad8402_write(struct comedi_device *dev, unsigned int channel,
else
register_bits &= ~SERIAL_DATA_IN_BIT;
udelay(ad8402_udelay);
- writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+ writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
udelay(ad8402_udelay);
writew(register_bits | SERIAL_CLOCK_BIT,
- priv(dev)->main_iobase + CALIBRATION_REG);
+ devpriv->main_iobase + CALIBRATION_REG);
}
udelay(ad8402_udelay);
- writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+ writew(0, devpriv->main_iobase + CALIBRATION_REG);
}
/* for pci-das6402/16, channel 0 is analog input gain and channel 1 is offset */
@@ -3713,14 +3766,15 @@ static int ad8402_write_insn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcidas64_private *devpriv = dev->private;
int channel = CR_CHAN(insn->chanspec);
/* return immediately if setting hasn't changed, since
* programming these things is slow */
- if (priv(dev)->ad8402_state[channel] == data[0])
+ if (devpriv->ad8402_state[channel] == data[0])
return 1;
- priv(dev)->ad8402_state[channel] = data[0];
+ devpriv->ad8402_state[channel] = data[0];
ad8402_write(dev, channel, data[0]);
@@ -3731,62 +3785,64 @@ static int ad8402_read_insn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcidas64_private *devpriv = dev->private;
unsigned int channel = CR_CHAN(insn->chanspec);
- data[0] = priv(dev)->ad8402_state[channel];
+ data[0] = devpriv->ad8402_state[channel];
return 1;
}
static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address)
{
+ struct pcidas64_private *devpriv = dev->private;
static const int bitstream_length = 11;
static const int read_command = 0x6;
unsigned int bitstream = (read_command << 8) | address;
unsigned int bit;
void __iomem * const plx_control_addr =
- priv(dev)->plx9080_iobase + PLX_CONTROL_REG;
+ devpriv->plx9080_iobase + PLX_CONTROL_REG;
uint16_t value;
static const int value_length = 16;
static const int eeprom_udelay = 1;
udelay(eeprom_udelay);
- priv(dev)->plx_control_bits &= ~CTL_EE_CLK & ~CTL_EE_CS;
+ devpriv->plx_control_bits &= ~CTL_EE_CLK & ~CTL_EE_CS;
/* make sure we don't send anything to the i2c bus on 4020 */
- priv(dev)->plx_control_bits |= CTL_USERO;
- writel(priv(dev)->plx_control_bits, plx_control_addr);
+ devpriv->plx_control_bits |= CTL_USERO;
+ writel(devpriv->plx_control_bits, plx_control_addr);
/* activate serial eeprom */
udelay(eeprom_udelay);
- priv(dev)->plx_control_bits |= CTL_EE_CS;
- writel(priv(dev)->plx_control_bits, plx_control_addr);
+ devpriv->plx_control_bits |= CTL_EE_CS;
+ writel(devpriv->plx_control_bits, plx_control_addr);
/* write read command and desired memory address */
for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
/* set bit to be written */
udelay(eeprom_udelay);
if (bitstream & bit)
- priv(dev)->plx_control_bits |= CTL_EE_W;
+ devpriv->plx_control_bits |= CTL_EE_W;
else
- priv(dev)->plx_control_bits &= ~CTL_EE_W;
- writel(priv(dev)->plx_control_bits, plx_control_addr);
+ devpriv->plx_control_bits &= ~CTL_EE_W;
+ writel(devpriv->plx_control_bits, plx_control_addr);
/* clock in bit */
udelay(eeprom_udelay);
- priv(dev)->plx_control_bits |= CTL_EE_CLK;
- writel(priv(dev)->plx_control_bits, plx_control_addr);
+ devpriv->plx_control_bits |= CTL_EE_CLK;
+ writel(devpriv->plx_control_bits, plx_control_addr);
udelay(eeprom_udelay);
- priv(dev)->plx_control_bits &= ~CTL_EE_CLK;
- writel(priv(dev)->plx_control_bits, plx_control_addr);
+ devpriv->plx_control_bits &= ~CTL_EE_CLK;
+ writel(devpriv->plx_control_bits, plx_control_addr);
}
/* read back value from eeprom memory location */
value = 0;
for (bit = 1 << (value_length - 1); bit; bit >>= 1) {
/* clock out bit */
udelay(eeprom_udelay);
- priv(dev)->plx_control_bits |= CTL_EE_CLK;
- writel(priv(dev)->plx_control_bits, plx_control_addr);
+ devpriv->plx_control_bits |= CTL_EE_CLK;
+ writel(devpriv->plx_control_bits, plx_control_addr);
udelay(eeprom_udelay);
- priv(dev)->plx_control_bits &= ~CTL_EE_CLK;
- writel(priv(dev)->plx_control_bits, plx_control_addr);
+ devpriv->plx_control_bits &= ~CTL_EE_CLK;
+ writel(devpriv->plx_control_bits, plx_control_addr);
udelay(eeprom_udelay);
if (readl(plx_control_addr) & CTL_EE_R)
value |= bit;
@@ -3794,8 +3850,8 @@ static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address)
/* deactivate eeprom serial input */
udelay(eeprom_udelay);
- priv(dev)->plx_control_bits &= ~CTL_EE_CS;
- writel(priv(dev)->plx_control_bits, plx_control_addr);
+ devpriv->plx_control_bits &= ~CTL_EE_CS;
+ writel(devpriv->plx_control_bits, plx_control_addr);
return value;
}
@@ -3809,419 +3865,386 @@ static int eeprom_read_insn(struct comedi_device *dev,
return 1;
}
-/* utility function that rounds desired timing to an achievable time, and
- * sets cmd members appropriately.
- * adc paces conversions from master clock by dividing by (x + 3) where x is 24 bit number
+/* Allocate and initialize the subdevice structures.
*/
-static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
+static int setup_subdevices(struct comedi_device *dev)
{
- unsigned int convert_divisor = 0, scan_divisor;
- static const int min_convert_divisor = 3;
- static const int max_convert_divisor =
- max_counter_value + min_convert_divisor;
- static const int min_scan_divisor_4020 = 2;
- unsigned long long max_scan_divisor, min_scan_divisor;
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pcidas64_private *devpriv = dev->private;
+ struct comedi_subdevice *s;
+ void __iomem *dio_8255_iobase;
+ int i;
+ int ret;
- if (cmd->convert_src == TRIG_TIMER) {
- if (board(dev)->layout == LAYOUT_4020) {
- cmd->convert_arg = 0;
- } else {
- convert_divisor =
- get_divisor(cmd->convert_arg, cmd->flags);
- if (convert_divisor > max_convert_divisor)
- convert_divisor = max_convert_divisor;
- if (convert_divisor < min_convert_divisor)
- convert_divisor = min_convert_divisor;
- cmd->convert_arg = convert_divisor * TIMER_BASE;
- }
- } else if (cmd->convert_src == TRIG_NOW)
- cmd->convert_arg = 0;
+ ret = comedi_alloc_subdevices(dev, 10);
+ if (ret)
+ return ret;
- if (cmd->scan_begin_src == TRIG_TIMER) {
- scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags);
- if (cmd->convert_src == TRIG_TIMER) {
- /* XXX check for integer overflows */
- min_scan_divisor = convert_divisor * cmd->chanlist_len;
- max_scan_divisor =
- (convert_divisor * cmd->chanlist_len - 1) +
- max_counter_value;
- } else {
- min_scan_divisor = min_scan_divisor_4020;
- max_scan_divisor = max_counter_value + min_scan_divisor;
- }
- if (scan_divisor > max_scan_divisor)
- scan_divisor = max_scan_divisor;
- if (scan_divisor < min_scan_divisor)
- scan_divisor = min_scan_divisor;
- cmd->scan_begin_arg = scan_divisor * TIMER_BASE;
+ s = &dev->subdevices[0];
+ /* analog input subdevice */
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ;
+ if (thisboard->layout == LAYOUT_60XX)
+ s->subdev_flags |= SDF_COMMON | SDF_DIFF;
+ else if (thisboard->layout == LAYOUT_64XX)
+ s->subdev_flags |= SDF_DIFF;
+ /* XXX Number of inputs in differential mode is ignored */
+ s->n_chan = thisboard->ai_se_chans;
+ s->len_chanlist = 0x2000;
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = thisboard->ai_range_table;
+ s->insn_read = ai_rinsn;
+ s->insn_config = ai_config_insn;
+ s->do_cmd = ai_cmd;
+ s->do_cmdtest = ai_cmdtest;
+ s->cancel = ai_cancel;
+ if (thisboard->layout == LAYOUT_4020) {
+ uint8_t data;
+ /* set adc to read from inputs
+ * (not internal calibration sources) */
+ devpriv->i2c_cal_range_bits = adc_src_4020_bits(4);
+ /* set channels to +-5 volt input ranges */
+ for (i = 0; i < s->n_chan; i++)
+ devpriv->i2c_cal_range_bits |= attenuate_bit(i);
+ data = devpriv->i2c_cal_range_bits;
+ i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data));
}
- return;
-}
-
-/* Gets nearest achievable timing given master clock speed, does not
- * take into account possible minimum/maximum divisor values. Used
- * by other timing checking functions. */
-static unsigned int get_divisor(unsigned int ns, unsigned int flags)
-{
- unsigned int divisor;
-
- switch (flags & TRIG_ROUND_MASK) {
- case TRIG_ROUND_UP:
- divisor = (ns + TIMER_BASE - 1) / TIMER_BASE;
- break;
- case TRIG_ROUND_DOWN:
- divisor = ns / TIMER_BASE;
- break;
- case TRIG_ROUND_NEAREST:
- default:
- divisor = (ns + TIMER_BASE / 2) / TIMER_BASE;
- break;
+ /* analog output subdevice */
+ s = &dev->subdevices[1];
+ if (thisboard->ao_nchan) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE |
+ SDF_GROUND | SDF_CMD_WRITE;
+ s->n_chan = thisboard->ao_nchan;
+ s->maxdata = (1 << thisboard->ao_bits) - 1;
+ s->range_table = thisboard->ao_range_table;
+ s->insn_read = ao_readback_insn;
+ s->insn_write = ao_winsn;
+ if (ao_cmd_is_supported(thisboard)) {
+ dev->write_subdev = s;
+ s->do_cmdtest = ao_cmdtest;
+ s->do_cmd = ao_cmd;
+ s->len_chanlist = thisboard->ao_nchan;
+ s->cancel = ao_cancel;
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
}
- return divisor;
-}
-static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags)
-{
- return get_divisor(ns, flags) - 2;
-}
+ /* digital input */
+ s = &dev->subdevices[2];
+ if (thisboard->layout == LAYOUT_64XX) {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = di_rbits;
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
-/* adjusts the size of hardware fifo (which determines block size for dma xfers) */
-static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples)
-{
- unsigned int num_fifo_entries;
- int retval;
- const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
+ /* digital output */
+ if (thisboard->layout == LAYOUT_64XX) {
+ s = &dev->subdevices[3];
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = do_wbits;
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
- num_fifo_entries = num_samples / fifo->sample_packing_ratio;
+ /* 8255 */
+ s = &dev->subdevices[4];
+ if (thisboard->has_8255) {
+ if (thisboard->layout == LAYOUT_4020) {
+ dio_8255_iobase = devpriv->main_iobase + I8255_4020_REG;
+ subdev_8255_init(dev, s, dio_callback_4020,
+ (unsigned long)dio_8255_iobase);
+ } else {
+ dio_8255_iobase =
+ devpriv->dio_counter_iobase + DIO_8255_OFFSET;
+ subdev_8255_init(dev, s, dio_callback,
+ (unsigned long)dio_8255_iobase);
+ }
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
- retval = set_ai_fifo_segment_length(dev,
- num_fifo_entries /
- fifo->num_segments);
- if (retval < 0)
- return retval;
+ /* 8 channel dio for 60xx */
+ s = &dev->subdevices[5];
+ if (thisboard->layout == LAYOUT_60XX) {
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_config = dio_60xx_config_insn;
+ s->insn_bits = dio_60xx_wbits;
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
- num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio;
+ /* caldac */
+ s = &dev->subdevices[6];
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 8;
+ if (thisboard->layout == LAYOUT_4020)
+ s->maxdata = 0xfff;
+ else
+ s->maxdata = 0xff;
+ s->insn_read = calib_read_insn;
+ s->insn_write = calib_write_insn;
+ for (i = 0; i < s->n_chan; i++)
+ caldac_write(dev, i, s->maxdata / 2);
- DEBUG_PRINT("set hardware fifo size to %i\n", num_samples);
+ /* 2 channel ad8402 potentiometer */
+ s = &dev->subdevices[7];
+ if (thisboard->layout == LAYOUT_64XX) {
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 2;
+ s->insn_read = ad8402_read_insn;
+ s->insn_write = ad8402_write_insn;
+ s->maxdata = 0xff;
+ for (i = 0; i < s->n_chan; i++)
+ ad8402_write(dev, i, s->maxdata / 2);
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
- return num_samples;
-}
+ /* serial EEPROM, if present */
+ s = &dev->subdevices[8];
+ if (readl(devpriv->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) {
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+ s->n_chan = 128;
+ s->maxdata = 0xffff;
+ s->insn_read = eeprom_read_insn;
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
-/* query length of fifo */
-static unsigned int ai_fifo_size(struct comedi_device *dev)
-{
- return priv(dev)->ai_fifo_segment_length *
- board(dev)->ai_fifo->num_segments *
- board(dev)->ai_fifo->sample_packing_ratio;
+ /* user counter subd XXX */
+ s = &dev->subdevices[9];
+ s->type = COMEDI_SUBD_UNUSED;
+
+ return 0;
}
-static int set_ai_fifo_segment_length(struct comedi_device *dev,
- unsigned int num_entries)
+static const struct pcidas64_board
+*cb_pcidas64_find_pci_board(struct pci_dev *pcidev)
{
- static const int increment_size = 0x100;
- const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
- unsigned int num_increments;
- uint16_t bits;
-
- if (num_entries < increment_size)
- num_entries = increment_size;
- if (num_entries > fifo->max_segment_length)
- num_entries = fifo->max_segment_length;
-
- /* 1 == 256 entries, 2 == 512 entries, etc */
- num_increments = (num_entries + increment_size / 2) / increment_size;
-
- bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask;
- priv(dev)->fifo_size_bits &= ~fifo->fifo_size_reg_mask;
- priv(dev)->fifo_size_bits |= bits;
- writew(priv(dev)->fifo_size_bits,
- priv(dev)->main_iobase + FIFO_SIZE_REG);
-
- priv(dev)->ai_fifo_segment_length = num_increments * increment_size;
-
- DEBUG_PRINT("set hardware fifo segment length to %i\n",
- priv(dev)->ai_fifo_segment_length);
+ unsigned int i;
- return priv(dev)->ai_fifo_segment_length;
+ for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++)
+ if (pcidev->device == pcidas64_boards[i].device_id)
+ return &pcidas64_boards[i];
+ return NULL;
}
-/* pci-6025 8800 caldac:
- * address 0 == dac channel 0 offset
- * address 1 == dac channel 0 gain
- * address 2 == dac channel 1 offset
- * address 3 == dac channel 1 gain
- * address 4 == fine adc offset
- * address 5 == coarse adc offset
- * address 6 == coarse adc gain
- * address 7 == fine adc gain
- */
-/* pci-6402/16 uses all 8 channels for dac:
- * address 0 == dac channel 0 fine gain
- * address 1 == dac channel 0 coarse gain
- * address 2 == dac channel 0 coarse offset
- * address 3 == dac channel 1 coarse offset
- * address 4 == dac channel 1 fine gain
- * address 5 == dac channel 1 coarse gain
- * address 6 == dac channel 0 fine offset
- * address 7 == dac channel 1 fine offset
-*/
-
-static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
- uint8_t value)
+static int auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
- static const int num_caldac_channels = 8;
- static const int bitstream_length = 11;
- unsigned int bitstream = ((address & 0x7) << 8) | value;
- unsigned int bit, register_bits;
- static const int caldac_8800_udelay = 1;
+ const struct pcidas64_board *thisboard;
+ struct pcidas64_private *devpriv;
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ uint32_t local_range, local_decode;
+ int retval;
- if (address >= num_caldac_channels) {
- comedi_error(dev, "illegal caldac channel");
- return -1;
- }
- for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
- register_bits = 0;
- if (bitstream & bit)
- register_bits |= SERIAL_DATA_IN_BIT;
- udelay(caldac_8800_udelay);
- writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
- register_bits |= SERIAL_CLOCK_BIT;
- udelay(caldac_8800_udelay);
- writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+ dev->board_ptr = cb_pcidas64_find_pci_board(pcidev);
+ if (!dev->board_ptr) {
+ dev_err(dev->class_dev,
+ "cb_pcidas64: does not support pci %s\n",
+ pci_name(pcidev));
+ return -EINVAL;
}
- udelay(caldac_8800_udelay);
- writew(SELECT_8800_BIT, priv(dev)->main_iobase + CALIBRATION_REG);
- udelay(caldac_8800_udelay);
- writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
- udelay(caldac_8800_udelay);
- return 0;
-}
+ thisboard = comedi_board(dev);
-/* 4020 caldacs */
-static int caldac_i2c_write(struct comedi_device *dev,
- unsigned int caldac_channel, unsigned int value)
-{
- uint8_t serial_bytes[3];
- uint8_t i2c_addr;
- enum pointer_bits {
- /* manual has gain and offset bits switched */
- OFFSET_0_2 = 0x1,
- GAIN_0_2 = 0x2,
- OFFSET_1_3 = 0x4,
- GAIN_1_3 = 0x8,
- };
- enum data_bits {
- NOT_CLEAR_REGISTERS = 0x20,
- };
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
- switch (caldac_channel) {
- case 0: /* chan 0 offset */
- i2c_addr = CALDAC0_I2C_ADDR;
- serial_bytes[0] = OFFSET_0_2;
- break;
- case 1: /* chan 1 offset */
- i2c_addr = CALDAC0_I2C_ADDR;
- serial_bytes[0] = OFFSET_1_3;
- break;
- case 2: /* chan 2 offset */
- i2c_addr = CALDAC1_I2C_ADDR;
- serial_bytes[0] = OFFSET_0_2;
- break;
- case 3: /* chan 3 offset */
- i2c_addr = CALDAC1_I2C_ADDR;
- serial_bytes[0] = OFFSET_1_3;
- break;
- case 4: /* chan 0 gain */
- i2c_addr = CALDAC0_I2C_ADDR;
- serial_bytes[0] = GAIN_0_2;
- break;
- case 5: /* chan 1 gain */
- i2c_addr = CALDAC0_I2C_ADDR;
- serial_bytes[0] = GAIN_1_3;
- break;
- case 6: /* chan 2 gain */
- i2c_addr = CALDAC1_I2C_ADDR;
- serial_bytes[0] = GAIN_0_2;
- break;
- case 7: /* chan 3 gain */
- i2c_addr = CALDAC1_I2C_ADDR;
- serial_bytes[0] = GAIN_1_3;
- break;
- default:
- comedi_error(dev, "invalid caldac channel\n");
- return -1;
- break;
+ if (comedi_pci_enable(pcidev, dev->driver->driver_name)) {
+ dev_warn(dev->class_dev,
+ "failed to enable PCI device and request regions\n");
+ return -EIO;
}
- serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf);
- serial_bytes[2] = value & 0xff;
- i2c_write(dev, i2c_addr, serial_bytes, 3);
- return 0;
-}
+ pci_set_master(pcidev);
-/* Their i2c requires a huge delay on setting clock or data high for some reason */
-static const int i2c_high_udelay = 1000;
-static const int i2c_low_udelay = 10;
+ /* Initialize dev->board_name */
+ dev->board_name = thisboard->name;
-/* set i2c data line high or low */
-static void i2c_set_sda(struct comedi_device *dev, int state)
-{
- static const int data_bit = CTL_EE_W;
- void __iomem *plx_control_addr = priv(dev)->plx9080_iobase +
- PLX_CONTROL_REG;
+ dev->iobase = pci_resource_start(pcidev, MAIN_BADDRINDEX);
- if (state) {
- /* set data line high */
- priv(dev)->plx_control_bits &= ~data_bit;
- writel(priv(dev)->plx_control_bits, plx_control_addr);
- udelay(i2c_high_udelay);
- } else { /* set data line low */
+ devpriv->plx9080_phys_iobase =
+ pci_resource_start(pcidev, PLX9080_BADDRINDEX);
+ devpriv->main_phys_iobase = dev->iobase;
+ devpriv->dio_counter_phys_iobase =
+ pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX);
- priv(dev)->plx_control_bits |= data_bit;
- writel(priv(dev)->plx_control_bits, plx_control_addr);
- udelay(i2c_low_udelay);
+ /* remap, won't work with 2.0 kernels but who cares */
+ devpriv->plx9080_iobase =
+ ioremap(devpriv->plx9080_phys_iobase,
+ pci_resource_len(pcidev, PLX9080_BADDRINDEX));
+ devpriv->main_iobase =
+ ioremap(devpriv->main_phys_iobase,
+ pci_resource_len(pcidev, MAIN_BADDRINDEX));
+ devpriv->dio_counter_iobase =
+ ioremap(devpriv->dio_counter_phys_iobase,
+ pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX));
+
+ if (!devpriv->plx9080_iobase || !devpriv->main_iobase
+ || !devpriv->dio_counter_iobase) {
+ dev_warn(dev->class_dev, "failed to remap io memory\n");
+ return -ENOMEM;
}
-}
-/* set i2c clock line high or low */
-static void i2c_set_scl(struct comedi_device *dev, int state)
-{
- static const int clock_bit = CTL_USERO;
- void __iomem *plx_control_addr = priv(dev)->plx9080_iobase +
- PLX_CONTROL_REG;
-
- if (state) {
- /* set clock line high */
- priv(dev)->plx_control_bits &= ~clock_bit;
- writel(priv(dev)->plx_control_bits, plx_control_addr);
- udelay(i2c_high_udelay);
- } else { /* set clock line low */
-
- priv(dev)->plx_control_bits |= clock_bit;
- writel(priv(dev)->plx_control_bits, plx_control_addr);
- udelay(i2c_low_udelay);
- }
-}
+ DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase);
+ DEBUG_PRINT(" main remapped to 0x%p\n", devpriv->main_iobase);
+ DEBUG_PRINT(" diocounter remapped to 0x%p\n",
+ devpriv->dio_counter_iobase);
-static void i2c_write_byte(struct comedi_device *dev, uint8_t byte)
-{
- uint8_t bit;
- unsigned int num_bits = 8;
+ /* figure out what local addresses are */
+ local_range = readl(devpriv->plx9080_iobase + PLX_LAS0RNG_REG) &
+ LRNG_MEM_MASK;
+ local_decode = readl(devpriv->plx9080_iobase + PLX_LAS0MAP_REG) &
+ local_range & LMAP_MEM_MASK;
+ devpriv->local0_iobase = ((uint32_t)devpriv->main_phys_iobase &
+ ~local_range) | local_decode;
+ local_range = readl(devpriv->plx9080_iobase + PLX_LAS1RNG_REG) &
+ LRNG_MEM_MASK;
+ local_decode = readl(devpriv->plx9080_iobase + PLX_LAS1MAP_REG) &
+ local_range & LMAP_MEM_MASK;
+ devpriv->local1_iobase = ((uint32_t)devpriv->dio_counter_phys_iobase &
+ ~local_range) | local_decode;
+
+ DEBUG_PRINT(" local 0 io addr 0x%x\n", devpriv->local0_iobase);
+ DEBUG_PRINT(" local 1 io addr 0x%x\n", devpriv->local1_iobase);
- DEBUG_PRINT("writing to i2c byte 0x%x\n", byte);
+ retval = alloc_and_init_dma_members(dev);
+ if (retval < 0)
+ return retval;
- for (bit = 1 << (num_bits - 1); bit; bit >>= 1) {
- i2c_set_scl(dev, 0);
- if ((byte & bit))
- i2c_set_sda(dev, 1);
- else
- i2c_set_sda(dev, 0);
- i2c_set_scl(dev, 1);
+ devpriv->hw_revision =
+ hw_revision(dev, readw(devpriv->main_iobase + HW_STATUS_REG));
+ dev_dbg(dev->class_dev, "stc hardware revision %i\n",
+ devpriv->hw_revision);
+ init_plx9080(dev);
+ init_stc_registers(dev);
+ /* get irq */
+ if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
+ "cb_pcidas64", dev)) {
+ dev_dbg(dev->class_dev, "unable to allocate irq %u\n",
+ pcidev->irq);
+ return -EINVAL;
}
-}
-
-/* we can't really read the lines, so fake it */
-static int i2c_read_ack(struct comedi_device *dev)
-{
- i2c_set_scl(dev, 0);
- i2c_set_sda(dev, 1);
- i2c_set_scl(dev, 1);
-
- return 0; /* return fake acknowledge bit */
-}
+ dev->irq = pcidev->irq;
+ dev_dbg(dev->class_dev, "irq %u\n", dev->irq);
-/* send start bit */
-static void i2c_start(struct comedi_device *dev)
-{
- i2c_set_scl(dev, 1);
- i2c_set_sda(dev, 1);
- i2c_set_sda(dev, 0);
-}
+ retval = setup_subdevices(dev);
+ if (retval < 0)
+ return retval;
-/* send stop bit */
-static void i2c_stop(struct comedi_device *dev)
-{
- i2c_set_scl(dev, 0);
- i2c_set_sda(dev, 0);
- i2c_set_scl(dev, 1);
- i2c_set_sda(dev, 1);
+ return 0;
}
-static void i2c_write(struct comedi_device *dev, unsigned int address,
- const uint8_t *data, unsigned int length)
+static void detach(struct comedi_device *dev)
{
+ const struct pcidas64_board *thisboard = comedi_board(dev);
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct pcidas64_private *devpriv = dev->private;
unsigned int i;
- uint8_t bitstream;
- static const int read_bit = 0x1;
-
-/* XXX need mutex to prevent simultaneous attempts to access eeprom and i2c bus */
- /* make sure we dont send anything to eeprom */
- priv(dev)->plx_control_bits &= ~CTL_EE_CS;
-
- i2c_stop(dev);
- i2c_start(dev);
-
- /* send address and write bit */
- bitstream = (address << 1) & ~read_bit;
- i2c_write_byte(dev, bitstream);
-
- /* get acknowledge */
- if (i2c_read_ack(dev) != 0) {
- comedi_error(dev, "i2c write failed: no acknowledge");
- i2c_stop(dev);
- return;
- }
- /* write data bytes */
- for (i = 0; i < length; i++) {
- i2c_write_byte(dev, data[i]);
- if (i2c_read_ack(dev) != 0) {
- comedi_error(dev, "i2c write failed: no acknowledge");
- i2c_stop(dev);
- return;
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ if (devpriv) {
+ if (pcidev) {
+ if (devpriv->plx9080_iobase) {
+ disable_plx_interrupts(dev);
+ iounmap(devpriv->plx9080_iobase);
+ }
+ if (devpriv->main_iobase)
+ iounmap(devpriv->main_iobase);
+ if (devpriv->dio_counter_iobase)
+ iounmap(devpriv->dio_counter_iobase);
+ /* free pci dma buffers */
+ for (i = 0; i < ai_dma_ring_count(thisboard); i++) {
+ if (devpriv->ai_buffer[i])
+ pci_free_consistent(pcidev,
+ DMA_BUFFER_SIZE,
+ devpriv->ai_buffer[i],
+ devpriv->ai_buffer_bus_addr[i]);
+ }
+ for (i = 0; i < AO_DMA_RING_COUNT; i++) {
+ if (devpriv->ao_buffer[i])
+ pci_free_consistent(pcidev,
+ DMA_BUFFER_SIZE,
+ devpriv->ao_buffer[i],
+ devpriv->ao_buffer_bus_addr[i]);
+ }
+ /* free dma descriptors */
+ if (devpriv->ai_dma_desc)
+ pci_free_consistent(pcidev,
+ sizeof(struct plx_dma_desc) *
+ ai_dma_ring_count(thisboard),
+ devpriv->ai_dma_desc,
+ devpriv->ai_dma_desc_bus_addr);
+ if (devpriv->ao_dma_desc)
+ pci_free_consistent(pcidev,
+ sizeof(struct plx_dma_desc) *
+ AO_DMA_RING_COUNT,
+ devpriv->ao_dma_desc,
+ devpriv->ao_dma_desc_bus_addr);
}
}
- i2c_stop(dev);
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, &dev->subdevices[4]);
+ if (pcidev) {
+ if (dev->iobase)
+ comedi_pci_disable(pcidev);
+ }
}
static struct comedi_driver cb_pcidas64_driver = {
.driver_name = "cb_pcidas64",
.module = THIS_MODULE,
- .attach = attach,
+ .auto_attach = auto_attach,
.detach = detach,
};
-static int __devinit cb_pcidas64_pci_probe(struct pci_dev *dev,
+static int cb_pcidas64_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &cb_pcidas64_driver);
}
-static void __devexit cb_pcidas64_pci_remove(struct pci_dev *dev)
+static void cb_pcidas64_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
static DEFINE_PCI_DEVICE_TABLE(cb_pcidas64_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x001d) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x001e) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0035) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0036) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0037) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0052) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005d) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005e) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005f) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0061) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0062) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0063) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0064) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0066) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0067) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0068) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x006f) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0078) },
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0079) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001d) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001e) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0035) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0036) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0037) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0052) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005d) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005e) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005f) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0061) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0062) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0063) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0064) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0066) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0067) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0068) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x006f) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0078) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0079) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, cb_pcidas64_pci_table);
@@ -4230,7 +4253,7 @@ static struct pci_driver cb_pcidas64_pci_driver = {
.name = "cb_pcidas64",
.id_table = cb_pcidas64_pci_table,
.probe = cb_pcidas64_pci_probe,
- .remove = __devexit_p(cb_pcidas64_pci_remove),
+ .remove = cb_pcidas64_pci_remove,
};
module_comedi_pci_driver(cb_pcidas64_driver, cb_pcidas64_pci_driver);
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
index aef946df27e..7c6029a8c3e 100644
--- a/drivers/staging/comedi/drivers/cb_pcidda.c
+++ b/drivers/staging/comedi/drivers/cb_pcidda.c
@@ -1,90 +1,78 @@
/*
- comedi/drivers/cb_pcidda.c
- This intends to be a driver for the ComputerBoards / MeasurementComputing
- PCI-DDA series.
-
- Copyright (C) 2001 Ivan Martinez <ivanmr@altavista.com>
- Copyright (C) 2001 Frank Mori Hess <fmhess@users.sourceforge.net>
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 1997-8 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.
-
- 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.
+ * comedi/drivers/cb_pcidda.c
+ * Driver for the ComputerBoards / MeasurementComputing PCI-DDA series.
+ *
+ * Copyright (C) 2001 Ivan Martinez <ivanmr@altavista.com>
+ * Copyright (C) 2001 Frank Mori Hess <fmhess@users.sourceforge.net>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1997-8 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.
+ *
+ * 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.
+ */
-*/
/*
-Driver: cb_pcidda
-Description: MeasurementComputing PCI-DDA series
-Author: Ivan Martinez <ivanmr@altavista.com>, Frank Mori Hess <fmhess@users.sourceforge.net>
-Status: Supports 08/16, 04/16, 02/16, 08/12, 04/12, and 02/12
-Devices: [Measurement Computing] PCI-DDA08/12 (cb_pcidda), PCI-DDA04/12,
- PCI-DDA02/12, PCI-DDA08/16, PCI-DDA04/16, PCI-DDA02/16
-
-Configuration options:
- [0] - PCI bus of device (optional)
- [1] - PCI slot of device (optional)
- If bus/slot is not specified, the first available PCI
- device will be used.
-
-Only simple analog output writing is supported.
-
-So far it has only been tested with:
- - PCI-DDA08/12
-Please report success/failure with other different cards to
-<comedi@comedi.org>.
-*/
+ * Driver: cb_pcidda
+ * Description: MeasurementComputing PCI-DDA series
+ * Devices: (Measurement Computing) PCI-DDA08/12 [pci-dda08/12]
+ * (Measurement Computing) PCI-DDA04/12 [pci-dda04/12]
+ * (Measurement Computing) PCI-DDA02/12 [pci-dda02/12]
+ * (Measurement Computing) PCI-DDA08/16 [pci-dda08/16]
+ * (Measurement Computing) PCI-DDA04/16 [pci-dda04/16]
+ * (Measurement Computing) PCI-DDA02/16 [pci-dda02/16]
+ * Author: Ivan Martinez <ivanmr@altavista.com>
+ * Frank Mori Hess <fmhess@users.sourceforge.net>
+ * Status: works
+ *
+ * Configuration options: not applicable, uses PCI auto config
+ *
+ * Only simple analog output writing is supported.
+ */
#include "../comedidev.h"
#include "comedi_fc.h"
#include "8255.h"
-/* PCI vendor number of ComputerBoards */
-#define PCI_VENDOR_ID_CB 0x1307
+/*
+ * ComputerBoards PCI Device ID's supported by this driver
+ */
+#define PCI_DEVICE_ID_DDA02_12 0x0020
+#define PCI_DEVICE_ID_DDA04_12 0x0021
+#define PCI_DEVICE_ID_DDA08_12 0x0022
+#define PCI_DEVICE_ID_DDA02_16 0x0023
+#define PCI_DEVICE_ID_DDA04_16 0x0024
+#define PCI_DEVICE_ID_DDA08_16 0x0025
+
#define EEPROM_SIZE 128 /* number of entries in eeprom */
/* maximum number of ao channels for supported boards */
#define MAX_AO_CHANNELS 8
/* Digital I/O registers */
-#define PORT1A 0 /* PORT 1A DATA */
-
-#define PORT1B 1 /* PORT 1B DATA */
-
-#define PORT1C 2 /* PORT 1C DATA */
-
-#define CONTROL1 3 /* CONTROL REGISTER 1 */
-
-#define PORT2A 4 /* PORT 2A DATA */
-
-#define PORT2B 5 /* PORT 2B DATA */
-
-#define PORT2C 6 /* PORT 2C DATA */
-
-#define CONTROL2 7 /* CONTROL REGISTER 2 */
+#define CB_DDA_DIO0_8255_BASE 0x00
+#define CB_DDA_DIO1_8255_BASE 0x04
/* DAC registers */
-#define DACONTROL 0 /* D/A CONTROL REGISTER */
-#define SU 0000001 /* Simultaneous update enabled */
-#define NOSU 0000000 /* Simultaneous update disabled */
-#define ENABLEDAC 0000002 /* Enable specified DAC */
-#define DISABLEDAC 0000000 /* Disable specified DAC */
-#define RANGE2V5 0000000 /* 2.5V */
-#define RANGE5V 0000200 /* 5V */
-#define RANGE10V 0000300 /* 10V */
-#define UNIP 0000400 /* Unipolar outputs */
-#define BIP 0000000 /* Bipolar outputs */
+#define CB_DDA_DA_CTRL_REG 0x00 /* D/A Control Register */
+#define CB_DDA_DA_CTRL_SU (1 << 0) /* Simultaneous update */
+#define CB_DDA_DA_CTRL_EN (1 << 1) /* Enable specified DAC */
+#define CB_DDA_DA_CTRL_DAC(x) ((x) << 2) /* Specify DAC channel */
+#define CB_DDA_DA_CTRL_RANGE2V5 (0 << 6) /* 2.5V range */
+#define CB_DDA_DA_CTRL_RANGE5V (2 << 6) /* 5V range */
+#define CB_DDA_DA_CTRL_RANGE10V (3 << 6) /* 10V range */
+#define CB_DDA_DA_CTRL_UNIP (1 << 8) /* Unipolar range */
#define DACALIBRATION1 4 /* D/A CALIBRATION REGISTER 1 */
/* write bits */
@@ -109,107 +97,67 @@ Please report success/failure with other different cards to
/* manual says to set this bit with no explanation */
#define DUMMY_BIT 0x40
-#define DADATA 8 /* FIRST D/A DATA REGISTER (0) */
+#define CB_DDA_DA_DATA_REG(x) (0x08 + ((x) * 2))
+
+/* Offsets for the caldac channels */
+#define CB_DDA_CALDAC_FINE_GAIN 0
+#define CB_DDA_CALDAC_COURSE_GAIN 1
+#define CB_DDA_CALDAC_COURSE_OFFSET 2
+#define CB_DDA_CALDAC_FINE_OFFSET 3
static const struct comedi_lrange cb_pcidda_ranges = {
- 6,
- {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- }
+ 6, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5)
+ }
};
-/*
- * 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.
- */
struct cb_pcidda_board {
const char *name;
- char status; /* Driver status: */
-
- /*
- * 0 - tested
- * 1 - manual read, not tested
- * 2 - manual not read
- */
-
unsigned short device_id;
int ao_chans;
int ao_bits;
- const struct comedi_lrange *ranges;
};
static const struct cb_pcidda_board cb_pcidda_boards[] = {
{
- .name = "pci-dda02/12",
- .status = 1,
- .device_id = 0x20,
- .ao_chans = 2,
- .ao_bits = 12,
- .ranges = &cb_pcidda_ranges,
- },
- {
- .name = "pci-dda04/12",
- .status = 1,
- .device_id = 0x21,
- .ao_chans = 4,
- .ao_bits = 12,
- .ranges = &cb_pcidda_ranges,
- },
- {
- .name = "pci-dda08/12",
- .status = 0,
- .device_id = 0x22,
- .ao_chans = 8,
- .ao_bits = 12,
- .ranges = &cb_pcidda_ranges,
- },
- {
- .name = "pci-dda02/16",
- .status = 2,
- .device_id = 0x23,
- .ao_chans = 2,
- .ao_bits = 16,
- .ranges = &cb_pcidda_ranges,
- },
- {
- .name = "pci-dda04/16",
- .status = 2,
- .device_id = 0x24,
- .ao_chans = 4,
- .ao_bits = 16,
- .ranges = &cb_pcidda_ranges,
- },
- {
- .name = "pci-dda08/16",
- .status = 0,
- .device_id = 0x25,
- .ao_chans = 8,
- .ao_bits = 16,
- .ranges = &cb_pcidda_ranges,
- },
+ .name = "pci-dda02/12",
+ .device_id = PCI_DEVICE_ID_DDA02_12,
+ .ao_chans = 2,
+ .ao_bits = 12,
+ }, {
+ .name = "pci-dda04/12",
+ .device_id = PCI_DEVICE_ID_DDA04_12,
+ .ao_chans = 4,
+ .ao_bits = 12,
+ }, {
+ .name = "pci-dda08/12",
+ .device_id = PCI_DEVICE_ID_DDA08_12,
+ .ao_chans = 8,
+ .ao_bits = 12,
+ }, {
+ .name = "pci-dda02/16",
+ .device_id = PCI_DEVICE_ID_DDA02_16,
+ .ao_chans = 2,
+ .ao_bits = 16,
+ }, {
+ .name = "pci-dda04/16",
+ .device_id = PCI_DEVICE_ID_DDA04_16,
+ .ao_chans = 4,
+ .ao_bits = 16,
+ }, {
+ .name = "pci-dda08/16",
+ .device_id = PCI_DEVICE_ID_DDA08_16,
+ .ao_chans = 8,
+ .ao_bits = 16,
+ },
};
-/*
- * this structure is for data unique to this hardware driver. If
- * several hardware drivers keep similar information in this structure,
- * feel free to suggest moving the variable to the struct comedi_device
- * struct.
- */
struct cb_pcidda_private {
- int data;
-
- unsigned long digitalio;
- unsigned long dac;
-
- /* unsigned long control_status; */
- /* unsigned long adc_fifo; */
-
/* bits last written to da calibration register 1 */
unsigned int dac_cal1_bits;
/* current range settings for output channels */
@@ -217,181 +165,16 @@ struct cb_pcidda_private {
u16 eeprom_data[EEPROM_SIZE]; /* software copy of board's eeprom */
};
-/*
- * I will program this later... ;-)
- */
-#if 0
-static int cb_pcidda_ai_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- printk("cb_pcidda_ai_cmd\n");
- printk("subdev: %d\n", cmd->subdev);
- printk("flags: %d\n", cmd->flags);
- printk("start_src: %d\n", cmd->start_src);
- printk("start_arg: %d\n", cmd->start_arg);
- printk("scan_begin_src: %d\n", cmd->scan_begin_src);
- printk("convert_src: %d\n", cmd->convert_src);
- printk("convert_arg: %d\n", cmd->convert_arg);
- printk("scan_end_src: %d\n", cmd->scan_end_src);
- printk("scan_end_arg: %d\n", cmd->scan_end_arg);
- printk("stop_src: %d\n", cmd->stop_src);
- printk("stop_arg: %d\n", cmd->stop_arg);
- printk("chanlist_len: %d\n", cmd->chanlist_len);
-}
-#endif
-
-#if 0
-static int cb_pcidda_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
- int tmp;
-
- /* 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_TIMER | TRIG_EXT);
- err |= cfc_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_EXT);
- err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
- err |= cfc_check_trigger_is_unique(cmd->convert_src);
- err |= cfc_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* step 3: make sure arguments are trivially compatible */
-
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
-#define MAX_SPEED 10000 /* in nanoseconds */
-#define MIN_SPEED 1000000000 /* in nanoseconds */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->scan_begin_arg < MAX_SPEED) {
- cmd->scan_begin_arg = MAX_SPEED;
- err++;
- }
- if (cmd->scan_begin_arg > MIN_SPEED) {
- cmd->scan_begin_arg = MIN_SPEED;
- err++;
- }
- } else {
- /* external trigger */
- /* should be level/edge, hi/lo specification here */
- /* should specify multiple external triggers */
- if (cmd->scan_begin_arg > 9) {
- cmd->scan_begin_arg = 9;
- err++;
- }
- }
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < MAX_SPEED) {
- cmd->convert_arg = MAX_SPEED;
- err++;
- }
- if (cmd->convert_arg > MIN_SPEED) {
- cmd->convert_arg = MIN_SPEED;
- err++;
- }
- } else {
- /* external trigger */
- /* see above */
- if (cmd->convert_arg > 9) {
- cmd->convert_arg = 9;
- err++;
- }
- }
-
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) {
- if (cmd->stop_arg > 0x00ffffff) {
- cmd->stop_arg = 0x00ffffff;
- err++;
- }
- } else {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- tmp = cmd->scan_begin_arg;
- cb_pcidda_ns_to_timer(&cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
- if (tmp != cmd->scan_begin_arg)
- err++;
- }
- if (cmd->convert_src == TRIG_TIMER) {
- tmp = cmd->convert_arg;
- cb_pcidda_ns_to_timer(&cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
- 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;
- err++;
- }
- }
-
- if (err)
- return 4;
-
- return 0;
-}
-#endif
-
-/* 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. */
-#if 0
-static int cb_pcidda_ns_to_timer(unsigned int *ns, int round)
-{
- /* trivial timer */
- return *ns;
-}
-#endif
-
/* lowlevel read from eeprom */
static unsigned int cb_pcidda_serial_in(struct comedi_device *dev)
{
- struct cb_pcidda_private *devpriv = dev->private;
unsigned int value = 0;
int i;
const int value_width = 16; /* number of bits wide values are */
for (i = 1; i <= value_width; i++) {
/* read bits most significant bit first */
- if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT)
+ if (inw_p(dev->iobase + DACALIBRATION1) & SERIAL_OUT_BIT)
value |= 1 << (value_width - i);
}
@@ -411,7 +194,7 @@ static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
devpriv->dac_cal1_bits |= SERIAL_IN_BIT;
else
devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT;
- outw_p(devpriv->dac_cal1_bits, devpriv->dac + DACALIBRATION1);
+ outw_p(devpriv->dac_cal1_bits, dev->iobase + DACALIBRATION1);
}
}
@@ -419,7 +202,6 @@ static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
unsigned int address)
{
- struct cb_pcidda_private *devpriv = dev->private;
unsigned int i;
unsigned int cal2_bits;
unsigned int value;
@@ -435,7 +217,7 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
/* deactivate caldacs (one caldac for every two channels) */
for (i = 0; i < max_num_caldacs; i++)
cal2_bits |= DESELECT_CALDAC_BIT(i);
- outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+ outw_p(cal2_bits, dev->iobase + DACALIBRATION2);
/* tell eeprom we want to read */
cb_pcidda_serial_out(dev, read_instruction, instruction_length);
@@ -446,7 +228,7 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
/* deactivate eeprom */
cal2_bits &= ~SELECT_EEPROM_BIT;
- outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+ outw_p(cal2_bits, dev->iobase + DACALIBRATION2);
return value;
}
@@ -456,7 +238,6 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev,
unsigned int caldac, unsigned int channel,
unsigned int value)
{
- struct cb_pcidda_private *devpriv = dev->private;
unsigned int cal2_bits;
unsigned int i;
/* caldacs use 3 bit channel specification */
@@ -479,72 +260,10 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev,
cal2_bits |= DESELECT_CALDAC_BIT(i);
/* activate the caldac we want */
cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
- outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+ outw_p(cal2_bits, dev->iobase + DACALIBRATION2);
/* deactivate caldac */
cal2_bits |= DESELECT_CALDAC_BIT(caldac);
- outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
-}
-
-/* returns caldac that calibrates given analog out channel */
-static unsigned int caldac_number(unsigned int channel)
-{
- return channel / 2;
-}
-
-/* returns caldac channel that provides fine gain for given ao channel */
-static unsigned int fine_gain_channel(unsigned int ao_channel)
-{
- return 4 * (ao_channel % 2);
-}
-
-/* returns caldac channel that provides coarse gain for given ao channel */
-static unsigned int coarse_gain_channel(unsigned int ao_channel)
-{
- return 1 + 4 * (ao_channel % 2);
-}
-
-/* returns caldac channel that provides coarse offset for given ao channel */
-static unsigned int coarse_offset_channel(unsigned int ao_channel)
-{
- return 2 + 4 * (ao_channel % 2);
-}
-
-/* returns caldac channel that provides fine offset for given ao channel */
-static unsigned int fine_offset_channel(unsigned int ao_channel)
-{
- return 3 + 4 * (ao_channel % 2);
-}
-
-/* returns eeprom address that provides offset for given ao channel and range */
-static unsigned int offset_eeprom_address(unsigned int ao_channel,
- unsigned int range)
-{
- return 0x7 + 2 * range + 12 * ao_channel;
-}
-
-/*
- * returns eeprom address that provides gain calibration for given ao
- * channel and range
- */
-static unsigned int gain_eeprom_address(unsigned int ao_channel,
- unsigned int range)
-{
- return 0x8 + 2 * range + 12 * ao_channel;
-}
-
-/*
- * returns upper byte of eeprom entry, which gives the coarse adjustment
- * values
- */
-static unsigned int eeprom_coarse_byte(unsigned int word)
-{
- return (word >> 8) & 0xff;
-}
-
-/* returns lower byte of eeprom entry, which gives the fine adjustment values */
-static unsigned int eeprom_fine_byte(unsigned int word)
-{
- return word & 0xff;
+ outw_p(cal2_bits, dev->iobase + DACALIBRATION2);
}
/* set caldacs to eeprom values for given channel and range */
@@ -552,85 +271,68 @@ static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
unsigned int range)
{
struct cb_pcidda_private *devpriv = dev->private;
- unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain;
+ unsigned int caldac = channel / 2; /* two caldacs per channel */
+ unsigned int chan = 4 * (channel % 2); /* caldac channel base */
+ unsigned int index = 2 * range + 12 * channel;
+ unsigned int offset;
+ unsigned int gain;
- /* remember range so we can tell when we need to readjust calibration */
+ /* save range so we can tell when we need to readjust calibration */
devpriv->ao_range[channel] = range;
- /* get values from eeprom data */
- coarse_offset =
- eeprom_coarse_byte(devpriv->eeprom_data
- [offset_eeprom_address(channel, range)]);
- fine_offset =
- eeprom_fine_byte(devpriv->eeprom_data
- [offset_eeprom_address(channel, range)]);
- coarse_gain =
- eeprom_coarse_byte(devpriv->eeprom_data
- [gain_eeprom_address(channel, range)]);
- fine_gain =
- eeprom_fine_byte(devpriv->eeprom_data
- [gain_eeprom_address(channel, range)]);
-
- /* set caldacs */
- cb_pcidda_write_caldac(dev, caldac_number(channel),
- coarse_offset_channel(channel), coarse_offset);
- cb_pcidda_write_caldac(dev, caldac_number(channel),
- fine_offset_channel(channel), fine_offset);
- cb_pcidda_write_caldac(dev, caldac_number(channel),
- coarse_gain_channel(channel), coarse_gain);
- cb_pcidda_write_caldac(dev, caldac_number(channel),
- fine_gain_channel(channel), fine_gain);
+ /* get values from eeprom data */
+ offset = devpriv->eeprom_data[0x7 + index];
+ gain = devpriv->eeprom_data[0x8 + index];
+
+ /* set caldacs */
+ cb_pcidda_write_caldac(dev, caldac, chan + CB_DDA_CALDAC_COURSE_OFFSET,
+ (offset >> 8) & 0xff);
+ cb_pcidda_write_caldac(dev, caldac, chan + CB_DDA_CALDAC_FINE_OFFSET,
+ offset & 0xff);
+ cb_pcidda_write_caldac(dev, caldac, chan + CB_DDA_CALDAC_COURSE_GAIN,
+ (gain >> 8) & 0xff);
+ cb_pcidda_write_caldac(dev, caldac, chan + CB_DDA_CALDAC_FINE_GAIN,
+ gain & 0xff);
}
-static int cb_pcidda_ao_winsn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int cb_pcidda_ao_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct cb_pcidda_private *devpriv = dev->private;
- unsigned int command;
- unsigned int channel, range;
-
- channel = CR_CHAN(insn->chanspec);
- range = CR_RANGE(insn->chanspec);
+ unsigned int channel = CR_CHAN(insn->chanspec);
+ unsigned int range = CR_RANGE(insn->chanspec);
+ unsigned int ctrl;
- /* adjust calibration dacs if range has changed */
if (range != devpriv->ao_range[channel])
cb_pcidda_calibrate(dev, channel, range);
- /* output channel configuration */
- command = NOSU | ENABLEDAC;
+ ctrl = CB_DDA_DA_CTRL_EN | CB_DDA_DA_CTRL_DAC(channel);
- /* output channel range */
switch (range) {
case 0:
- command |= BIP | RANGE10V;
- break;
- case 1:
- command |= BIP | RANGE5V;
- break;
- case 2:
- command |= BIP | RANGE2V5;
- break;
case 3:
- command |= UNIP | RANGE10V;
+ ctrl |= CB_DDA_DA_CTRL_RANGE10V;
break;
+ case 1:
case 4:
- command |= UNIP | RANGE5V;
+ ctrl |= CB_DDA_DA_CTRL_RANGE5V;
break;
+ case 2:
case 5:
- command |= UNIP | RANGE2V5;
+ ctrl |= CB_DDA_DA_CTRL_RANGE2V5;
break;
}
- /* output channel specification */
- command |= channel << 2;
- outw(command, devpriv->dac + DACONTROL);
+ if (range > 2)
+ ctrl |= CB_DDA_DA_CTRL_UNIP;
- /* write data */
- outw(data[0], devpriv->dac + DADATA + channel * 2);
+ outw(ctrl, dev->iobase + CB_DDA_DA_CTRL_REG);
- /* return the number of samples read/written */
- return 1;
+ outw(data[0], dev->iobase + CB_DDA_DA_DATA_REG(channel));
+
+ return insn->n;
}
static const void *cb_pcidda_find_boardinfo(struct comedi_device *dev,
@@ -647,41 +349,33 @@ static const void *cb_pcidda_find_boardinfo(struct comedi_device *dev,
return NULL;
}
-static int cb_pcidda_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int cb_pcidda_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct cb_pcidda_board *thisboard;
struct cb_pcidda_private *devpriv;
struct comedi_subdevice *s;
- int index;
+ unsigned long iobase_8255;
+ int i;
int ret;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
thisboard = cb_pcidda_find_boardinfo(dev, pcidev);
- if (!pcidev)
+ if (!thisboard)
return -ENODEV;
dev->board_ptr = thisboard;
dev->board_name = thisboard->name;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret)
return ret;
-
- devpriv->digitalio = pci_resource_start(pcidev, 2);
- devpriv->dac = pci_resource_start(pcidev, 3);
- dev->iobase = devpriv->dac;
-
- if (thisboard->status == 2)
- printk
- ("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. "
- "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. "
- "PLEASE REPORT USAGE TO <ivanmr@altavista.com>.\n");
+ dev->iobase = pci_resource_start(pcidev, 3);
+ iobase_8255 = pci_resource_start(pcidev, 2);
ret = comedi_alloc_subdevices(dev, 3);
if (ret)
@@ -693,29 +387,24 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev,
s->subdev_flags = SDF_WRITABLE;
s->n_chan = thisboard->ao_chans;
s->maxdata = (1 << thisboard->ao_bits) - 1;
- s->range_table = thisboard->ranges;
- s->insn_write = cb_pcidda_ao_winsn;
-
- /* s->subdev_flags |= SDF_CMD_READ; */
- /* s->do_cmd = cb_pcidda_ai_cmd; */
- /* s->do_cmdtest = cb_pcidda_ai_cmdtest; */
-
- /* two 8255 digital io subdevices */
- s = &dev->subdevices[1];
- subdev_8255_init(dev, s, NULL, devpriv->digitalio);
- s = &dev->subdevices[2];
- subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A);
-
- dev_dbg(dev->class_dev, "eeprom:\n");
- for (index = 0; index < EEPROM_SIZE; index++) {
- devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index);
- dev_dbg(dev->class_dev, "%i:0x%x\n", index,
- devpriv->eeprom_data[index]);
+ s->range_table = &cb_pcidda_ranges;
+ s->insn_write = cb_pcidda_ao_insn_write;
+
+ /* two 8255 digital io subdevices */
+ for (i = 0; i < 2; i++) {
+ s = &dev->subdevices[1 + i];
+ ret = subdev_8255_init(dev, s, NULL, iobase_8255 + (i * 4));
+ if (ret)
+ return ret;
}
+ /* Read the caldac eeprom data */
+ for (i = 0; i < EEPROM_SIZE; i++)
+ devpriv->eeprom_data[i] = cb_pcidda_read_eeprom(dev, i);
+
/* set calibrations dacs */
- for (index = 0; index < thisboard->ao_chans; index++)
- cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]);
+ for (i = 0; i < thisboard->ao_chans; i++)
+ cb_pcidda_calibrate(dev, i, devpriv->ao_range[i]);
dev_info(dev->class_dev, "%s attached\n", dev->board_name);
@@ -739,28 +428,28 @@ static void cb_pcidda_detach(struct comedi_device *dev)
static struct comedi_driver cb_pcidda_driver = {
.driver_name = "cb_pcidda",
.module = THIS_MODULE,
- .attach_pci = cb_pcidda_attach_pci,
+ .auto_attach = cb_pcidda_auto_attach,
.detach = cb_pcidda_detach,
};
-static int __devinit cb_pcidda_pci_probe(struct pci_dev *dev,
+static int cb_pcidda_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &cb_pcidda_driver);
}
-static void __devexit cb_pcidda_pci_remove(struct pci_dev *dev)
+static void cb_pcidda_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0020) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0021) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0022) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0023) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0024) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0025) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA02_12) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA04_12) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA08_12) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA02_16) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA04_16) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA08_16) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table);
@@ -769,7 +458,7 @@ static struct pci_driver cb_pcidda_pci_driver = {
.name = "cb_pcidda",
.id_table = cb_pcidda_pci_table,
.probe = cb_pcidda_pci_probe,
- .remove = __devexit_p(cb_pcidda_pci_remove),
+ .remove = cb_pcidda_pci_remove,
};
module_comedi_pci_driver(cb_pcidda_driver, cb_pcidda_pci_driver);
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
index 9515b692666..b43a5f80ac2 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdas.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdas.c
@@ -51,8 +51,6 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details.
/* #define CBPCIMDAS_DEBUG */
#undef CBPCIMDAS_DEBUG
-#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307
-
/* Registers for the PCIM-DAS1602/16 */
/* sizes of io regions (bytes) */
@@ -80,44 +78,6 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details.
#define RESID_COUNT_H 13
#define RESID_COUNT_L 14
-/* Board description */
-struct cb_pcimdas_board {
- const char *name;
- unsigned short device_id;
- int ai_se_chans; /* Inputs in single-ended mode */
- int ai_diff_chans; /* Inputs in differential mode */
- int ai_bits; /* analog input resolution */
- int ai_speed; /* fastest conversion period in ns */
- int ao_nchan; /* number of analog out channels */
- int ao_bits; /* analogue output resolution */
- int has_ao_fifo; /* analog output has fifo */
- int ao_scan_speed; /* analog output speed for 1602 series (for a scan, not conversion) */
- int fifo_size; /* number of samples fifo can hold */
- int dio_bits; /* number of dio bits */
- int has_dio; /* has DIO */
- const struct comedi_lrange *ranges;
-};
-
-static const struct cb_pcimdas_board cb_pcimdas_boards[] = {
- {
- .name = "PCIM-DAS1602/16",
- .device_id = 0x56,
- .ai_se_chans = 16,
- .ai_diff_chans = 8,
- .ai_bits = 16,
- .ai_speed = 10000, /* ?? */
- .ao_nchan = 2,
- .ao_bits = 12,
- .has_ao_fifo = 0, /* ?? */
- .ao_scan_speed = 10000,
- /* ?? */
- .fifo_size = 1024,
- .dio_bits = 24,
- .has_dio = 1,
-/* .ranges = &cb_pcimdas_ranges, */
- },
-};
-
/*
* this structure is for data unique to this hardware driver. If
* several hardware drivers keep similar information in this structure,
@@ -140,7 +100,6 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
- const struct cb_pcimdas_board *thisboard = comedi_board(dev);
struct cb_pcimdas_private *devpriv = dev->private;
int n, i;
unsigned int d;
@@ -153,9 +112,9 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev,
/* check channel number */
if ((inb(devpriv->BADR3 + 2) & 0x20) == 0) /* differential mode */
- maxchans = thisboard->ai_diff_chans;
+ maxchans = s->n_chan / 2;
else
- maxchans = thisboard->ai_se_chans;
+ maxchans = s->n_chan;
if (chan > (maxchans - 1))
return -ETIMEDOUT; /* *** Wrong error code. Fixme. */
@@ -195,12 +154,7 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev,
return -ETIMEDOUT;
}
/* read data */
- d = inw(dev->iobase + 0);
-
- /* mangle the data as necessary */
- /* d ^= 1<<(thisboard->ai_bits-1); // 16 bit data from ADC, so no mangle needed. */
-
- data[n] = d;
+ data[n] = inw(dev->iobase + 0);
}
/* return the number of samples read/written */
@@ -251,51 +205,21 @@ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev,
return i;
}
-static const void *cb_pcimdas_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int cb_pcimdas_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
- const struct cb_pcimdas_board *thisboard;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(cb_pcimdas_boards); i++) {
- thisboard = &cb_pcimdas_boards[i];
- if (thisboard->device_id == pcidev->device)
- return thisboard;
- }
- return NULL;
-}
-
-static int cb_pcimdas_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct cb_pcimdas_board *thisboard;
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct cb_pcimdas_private *devpriv;
struct comedi_subdevice *s;
unsigned long iobase_8255;
int ret;
- comedi_set_hw_dev(dev, &pcidev->dev);
+ dev->board_name = dev->driver->driver_name;
- thisboard = cb_pcimdas_find_boardinfo(dev, pcidev);
- if (!thisboard)
- return -ENODEV;
- dev->board_ptr = thisboard;
- dev->board_name = thisboard->name;
-
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret)
- return ret;
- devpriv = dev->private;
-
- /* Warn about non-tested features */
- switch (thisboard->device_id) {
- case 0x56:
- break;
- default:
- dev_dbg(dev->class_dev, "THIS CARD IS UNSUPPORTED.\n");
- dev_dbg(dev->class_dev,
- "PLEASE REPORT USAGE TO <mocelet@sucs.org>\n");
- }
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret)
@@ -323,8 +247,8 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev,
/* analog input subdevice */
s->type = COMEDI_SUBD_AI;
s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = thisboard->ai_se_chans;
- s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->n_chan = 16;
+ s->maxdata = 0xffff;
s->range_table = &range_unknown;
s->len_chanlist = 1; /* This is the maximum chanlist length that */
/* the board can handle */
@@ -334,8 +258,8 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev,
/* analog output subdevice */
s->type = COMEDI_SUBD_AO;
s->subdev_flags = SDF_WRITABLE;
- s->n_chan = thisboard->ao_nchan;
- s->maxdata = 1 << thisboard->ao_bits;
+ s->n_chan = 2;
+ s->maxdata = 0xfff;
/* ranges are hardware settable, but not software readable. */
s->range_table = &range_unknown;
s->insn_write = &cb_pcimdas_ao_winsn;
@@ -343,10 +267,7 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev,
s = &dev->subdevices[2];
/* digital i/o subdevice */
- if (thisboard->has_dio)
- subdev_8255_init(dev, s, NULL, iobase_8255);
- else
- s->type = COMEDI_SUBD_UNUSED;
+ subdev_8255_init(dev, s, NULL, iobase_8255);
dev_info(dev->class_dev, "%s attached\n", dev->board_name);
@@ -368,23 +289,23 @@ static void cb_pcimdas_detach(struct comedi_device *dev)
static struct comedi_driver cb_pcimdas_driver = {
.driver_name = "cb_pcimdas",
.module = THIS_MODULE,
- .attach_pci = cb_pcimdas_attach_pci,
+ .auto_attach = cb_pcimdas_auto_attach,
.detach = cb_pcimdas_detach,
};
-static int __devinit cb_pcimdas_pci_probe(struct pci_dev *dev,
+static int cb_pcimdas_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &cb_pcimdas_driver);
}
-static void __devexit cb_pcimdas_pci_remove(struct pci_dev *dev)
+static void cb_pcimdas_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
static DEFINE_PCI_DEVICE_TABLE(cb_pcimdas_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0056) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0056) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table);
@@ -393,7 +314,7 @@ static struct pci_driver cb_pcimdas_pci_driver = {
.name = "cb_pcimdas",
.id_table = cb_pcimdas_pci_table,
.probe = cb_pcimdas_pci_probe,
- .remove = __devexit_p(cb_pcimdas_pci_remove),
+ .remove = cb_pcimdas_pci_remove,
};
module_comedi_pci_driver(cb_pcimdas_driver, cb_pcimdas_pci_driver);
diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c
index ba9f0599be2..699b84f54cc 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdda.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdda.c
@@ -84,7 +84,6 @@ Configuration Options: not applicable, uses PCI auto config
#include "8255.h"
/* device ids of the cards we support -- currently only 1 card supported */
-#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307
#define PCI_ID_PCIM_DDA06_16 0x0053
/*
@@ -152,20 +151,20 @@ static int cb_pcimdda_ao_rinsn(struct comedi_device *dev,
return insn->n;
}
-static int cb_pcimdda_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int cb_pcimdda_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct cb_pcimdda_private *devpriv;
struct comedi_subdevice *s;
int ret;
- comedi_set_hw_dev(dev, &pcidev->dev);
dev->board_name = dev->driver->driver_name;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret)
@@ -213,23 +212,23 @@ static void cb_pcimdda_detach(struct comedi_device *dev)
static struct comedi_driver cb_pcimdda_driver = {
.driver_name = "cb_pcimdda",
.module = THIS_MODULE,
- .attach_pci = cb_pcimdda_attach_pci,
+ .auto_attach = cb_pcimdda_auto_attach,
.detach = cb_pcimdda_detach,
};
-static int __devinit cb_pcimdda_pci_probe(struct pci_dev *dev,
+static int cb_pcimdda_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &cb_pcimdda_driver);
}
-static void __devexit cb_pcimdda_pci_remove(struct pci_dev *dev)
+static void cb_pcimdda_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
static DEFINE_PCI_DEVICE_TABLE(cb_pcimdda_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_ID_PCIM_DDA06_16) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_ID_PCIM_DDA06_16) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, cb_pcimdda_pci_table);
@@ -238,7 +237,7 @@ static struct pci_driver cb_pcimdda_driver_pci_driver = {
.name = "cb_pcimdda",
.id_table = cb_pcimdda_pci_table,
.probe = cb_pcimdda_pci_probe,
- .remove = __devexit_p(cb_pcimdda_pci_remove),
+ .remove = cb_pcimdda_pci_remove,
};
module_comedi_pci_driver(cb_pcimdda_driver, cb_pcimdda_driver_pci_driver);
diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c
index 5c768bc76eb..31515999bb9 100644
--- a/drivers/staging/comedi/drivers/comedi_bond.c
+++ b/drivers/staging/comedi/drivers/comedi_bond.c
@@ -304,10 +304,10 @@ static int bonding_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
/*
* Setup our bonding from config params.. sets up our private struct..
diff --git a/drivers/staging/comedi/drivers/comedi_fc.c b/drivers/staging/comedi/drivers/comedi_fc.c
index 63be619dd60..83728298eef 100644
--- a/drivers/staging/comedi/drivers/comedi_fc.c
+++ b/drivers/staging/comedi/drivers/comedi_fc.c
@@ -53,7 +53,7 @@ unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd,
retval = comedi_buf_write_alloc(async, num_bytes);
if (retval != num_bytes) {
- printk(KERN_WARNING "comedi: buffer overrun\n");
+ dev_warn(subd->device->class_dev, "comedi: buffer overrun\n");
async->events |= COMEDI_CB_OVERFLOW;
return 0;
}
diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h
index 94481c637a0..31afab79f39 100644
--- a/drivers/staging/comedi/drivers/comedi_fc.h
+++ b/drivers/staging/comedi/drivers/comedi_fc.h
@@ -105,4 +105,48 @@ static inline int cfc_check_trigger_is_unique(unsigned int src)
return 0;
}
+/**
+ * cfc_check_trigger_arg_is() - trivially validate a trigger argument
+ * @arg: pointer to the trigger arg to validate
+ * @val: the value the argument should be
+ */
+static inline int cfc_check_trigger_arg_is(unsigned int *arg, unsigned int val)
+{
+ if (*arg != val) {
+ *arg = val;
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/**
+ * cfc_check_trigger_arg_min() - trivially validate a trigger argument
+ * @arg: pointer to the trigger arg to validate
+ * @val: the minimum value the argument should be
+ */
+static inline int cfc_check_trigger_arg_min(unsigned int *arg,
+ unsigned int val)
+{
+ if (*arg < val) {
+ *arg = val;
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/**
+ * cfc_check_trigger_arg_max() - trivially validate a trigger argument
+ * @arg: pointer to the trigger arg to validate
+ * @val: the maximum value the argument should be
+ */
+static inline int cfc_check_trigger_arg_max(unsigned int *arg,
+ unsigned int val)
+{
+ if (*arg > val) {
+ *arg = val;
+ return -EINVAL;
+ }
+ return 0;
+}
+
#endif /* _COMEDI_FC_H */
diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c
index 22ef9424259..76d59dcbea0 100644
--- a/drivers/staging/comedi/drivers/comedi_parport.c
+++ b/drivers/staging/comedi/drivers/comedi_parport.c
@@ -196,28 +196,13 @@ static int parport_intr_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
- if (cmd->scan_end_arg != 1) {
- cmd->scan_end_arg = 1;
- err++;
- }
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ 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;
@@ -305,10 +290,10 @@ static int parport_attach(struct comedi_device *dev,
if (ret)
return ret;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret < 0)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
s = &dev->subdevices[0];
s->type = COMEDI_SUBD_DIO;
diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c
index 7817def1556..fb3d09323ba 100644
--- a/drivers/staging/comedi/drivers/comedi_test.c
+++ b/drivers/staging/comedi/drivers/comedi_test.c
@@ -252,55 +252,28 @@ static int waveform_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+
+ if (cmd->convert_src == TRIG_NOW)
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
- if (cmd->convert_src == TRIG_NOW) {
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
- }
if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->scan_begin_arg < nano_per_micro) {
- cmd->scan_begin_arg = nano_per_micro;
- err++;
- }
- if (cmd->convert_src == TRIG_TIMER &&
- cmd->scan_begin_arg <
- cmd->convert_arg * cmd->chanlist_len) {
- cmd->scan_begin_arg =
- cmd->convert_arg * cmd->chanlist_len;
- err++;
- }
- }
- /*
- * XXX these checks are generic and should go in core if not there
- * already
- */
- if (!cmd->chanlist_len) {
- cmd->chanlist_len = 1;
- err++;
- }
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ nano_per_micro);
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ cmd->convert_arg * cmd->chanlist_len);
}
- if (cmd->stop_src == TRIG_COUNT) {
- if (!cmd->stop_arg) {
- cmd->stop_arg = 1;
- err++;
- }
- } else { /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -414,10 +387,10 @@ static int waveform_attach(struct comedi_device *dev,
dev->board_name = dev->driver->driver_name;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret < 0)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
/* set default amplitude and period */
if (amplitude <= 0)
diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c
index 178a6a4bb7d..1a18fa37bfd 100644
--- a/drivers/staging/comedi/drivers/contec_pci_dio.c
+++ b/drivers/staging/comedi/drivers/contec_pci_dio.c
@@ -68,14 +68,13 @@ static int contec_di_insn_bits(struct comedi_device *dev,
return insn->n;
}
-static int contec_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int contec_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct comedi_subdevice *s;
int ret;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
dev->board_name = dev->driver->driver_name;
ret = comedi_pci_enable(pcidev, dev->board_name);
@@ -121,17 +120,17 @@ static void contec_detach(struct comedi_device *dev)
static struct comedi_driver contec_pci_dio_driver = {
.driver_name = "contec_pci_dio",
.module = THIS_MODULE,
- .attach_pci = contec_attach_pci,
+ .auto_attach = contec_auto_attach,
.detach = contec_detach,
};
-static int __devinit contec_pci_dio_pci_probe(struct pci_dev *dev,
+static int contec_pci_dio_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &contec_pci_dio_driver);
}
-static void __devexit contec_pci_dio_pci_remove(struct pci_dev *dev)
+static void contec_pci_dio_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -146,7 +145,7 @@ static struct pci_driver contec_pci_dio_pci_driver = {
.name = "contec_pci_dio",
.id_table = contec_pci_dio_pci_table,
.probe = contec_pci_dio_pci_probe,
- .remove = __devexit_p(contec_pci_dio_pci_remove),
+ .remove = contec_pci_dio_pci_remove,
};
module_comedi_pci_driver(contec_pci_dio_driver, contec_pci_dio_pci_driver);
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c
index d13c8c5822b..992e557e6ae 100644
--- a/drivers/staging/comedi/drivers/daqboard2000.c
+++ b/drivers/staging/comedi/drivers/daqboard2000.c
@@ -117,8 +117,6 @@ Configuration options: not applicable, uses PCI auto config
#define DAQBOARD2000_FIRMWARE "daqboard2000_firmware.bin"
-#define PCI_VENDOR_ID_IOTECH 0x1616
-
#define DAQBOARD2000_SUBSYSTEM_IDS2 0x0002 /* Daqboard/2000 - 2 Dacs */
#define DAQBOARD2000_SUBSYSTEM_IDS4 0x0004 /* Daqboard/2000 - 4 Dacs */
@@ -690,26 +688,25 @@ static const void *daqboard2000_find_boardinfo(struct comedi_device *dev,
return NULL;
}
-static int daqboard2000_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int daqboard2000_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct daq200_boardtype *board;
struct daqboard2000_private *devpriv;
struct comedi_subdevice *s;
int result;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
board = daqboard2000_find_boardinfo(dev, pcidev);
if (!board)
return -ENODEV;
dev->board_ptr = board;
dev->board_name = board->name;
- result = alloc_private(dev, sizeof(*devpriv));
- if (result < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
- devpriv = dev->private;
+ dev->private = devpriv;
result = comedi_pci_enable(pcidev, dev->driver->driver_name);
if (result < 0)
@@ -792,17 +789,17 @@ static void daqboard2000_detach(struct comedi_device *dev)
static struct comedi_driver daqboard2000_driver = {
.driver_name = "daqboard2000",
.module = THIS_MODULE,
- .attach_pci = daqboard2000_attach_pci,
+ .auto_attach = daqboard2000_auto_attach,
.detach = daqboard2000_detach,
};
-static int __devinit daqboard2000_pci_probe(struct pci_dev *dev,
+static int daqboard2000_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &daqboard2000_driver);
}
-static void __devexit daqboard2000_pci_remove(struct pci_dev *dev)
+static void daqboard2000_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -817,7 +814,7 @@ static struct pci_driver daqboard2000_pci_driver = {
.name = "daqboard2000",
.id_table = daqboard2000_pci_table,
.probe = daqboard2000_pci_probe,
- .remove = __devexit_p(daqboard2000_pci_remove),
+ .remove = daqboard2000_pci_remove,
};
module_comedi_pci_driver(daqboard2000_driver, daqboard2000_pci_driver);
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c
index c304528cfb1..b15e05808cb 100644
--- a/drivers/staging/comedi/drivers/das08.c
+++ b/drivers/staging/comedi/drivers/das08.c
@@ -65,7 +65,6 @@
#define DO_PCI IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)
#define DO_COMEDI_DRIVER_REGISTER (DO_ISA || DO_PCI)
-#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307
#define PCI_DEVICE_ID_PCIDAS08 0x29
#define PCIDAS08_SIZE 0x54
@@ -775,24 +774,29 @@ das08_find_pci_board(struct pci_dev *pdev)
}
/* only called in the PCI probe path, via comedi_pci_auto_config() */
-static int __devinit __maybe_unused
-das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev)
+static int __maybe_unused
+das08_auto_attach(struct comedi_device *dev, unsigned long context_unused)
{
+ struct pci_dev *pdev;
+ struct das08_private_struct *devpriv;
unsigned long iobase;
- int ret;
if (!DO_PCI)
return -EINVAL;
- ret = alloc_private(dev, sizeof(struct das08_private_struct));
- if (ret < 0)
- return ret;
+
+ pdev = comedi_to_pci_dev(dev);
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
dev_info(dev->class_dev, "attach pci %s\n", pci_name(pdev));
dev->board_ptr = das08_find_pci_board(pdev);
if (dev->board_ptr == NULL) {
dev_err(dev->class_dev, "BUG! cannot determine board type!\n");
return -EINVAL;
}
- comedi_set_hw_dev(dev, &pdev->dev);
+
/* enable PCI device and reserve I/O spaces */
if (comedi_pci_enable(pdev, dev->driver->driver_name)) {
dev_err(dev->class_dev,
@@ -809,13 +813,12 @@ das08_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct das08_board_struct *thisboard = comedi_board(dev);
struct das08_private_struct *devpriv;
- int ret;
unsigned long iobase;
- ret = alloc_private(dev, sizeof(struct das08_private_struct));
- if (ret < 0)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
dev_info(dev->class_dev, "attach\n");
if (is_pci_board(thisboard)) {
@@ -866,7 +869,7 @@ static struct comedi_driver das08_driver = {
.driver_name = DRV_NAME,
.module = THIS_MODULE,
.attach = das08_attach,
- .attach_pci = das08_attach_pci,
+ .auto_attach = das08_auto_attach,
.detach = das08_detach,
.board_name = &das08_boards[0].name,
.num_names = sizeof(das08_boards) / sizeof(struct das08_board_struct),
@@ -876,19 +879,19 @@ static struct comedi_driver das08_driver = {
#if DO_PCI
static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_PCIDAS08) },
{0}
};
MODULE_DEVICE_TABLE(pci, das08_pci_table);
-static int __devinit das08_pci_probe(struct pci_dev *dev,
+static int das08_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &das08_driver);
}
-static void __devexit das08_pci_remove(struct pci_dev *dev)
+static void das08_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -897,7 +900,7 @@ static struct pci_driver das08_pci_driver = {
.id_table = das08_pci_table,
.name = DRV_NAME,
.probe = &das08_pci_probe,
- .remove = __devexit_p(&das08_pci_remove)
+ .remove = &das08_pci_remove
};
#endif /* DO_PCI */
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
index e4c91e67537..024262375e3 100644
--- a/drivers/staging/comedi/drivers/das08_cs.c
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -90,13 +90,14 @@ static int das08_cs_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
const struct das08_board_struct *thisboard = comedi_board(dev);
- int ret;
+ struct das08_private_struct *devpriv;
unsigned long iobase;
struct pcmcia_device *link = cur_dev; /* XXX hack */
- ret = alloc_private(dev, sizeof(struct das08_private_struct));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
dev_info(dev->class_dev, "das08_cs: attach\n");
/* deal with a pci board */
diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c
index fcb8a32adb2..b159f44d694 100644
--- a/drivers/staging/comedi/drivers/das16.c
+++ b/drivers/staging/comedi/drivers/das16.c
@@ -392,12 +392,12 @@ struct das16_private_struct {
volatile short timer_running;
volatile short timer_mode; /* true if using timer mode */
};
-#define devpriv ((struct das16_private_struct *)(dev->private))
static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
const struct das16_board *board = comedi_board(dev);
+ struct das16_private_struct *devpriv = dev->private;
int err = 0, tmp;
int gain, start_chan, i;
int mask;
@@ -442,46 +442,27 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- /* internal trigger */
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- /* check against maximum frequency */
- if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->scan_begin_arg <
- board->ai_speed * cmd->chanlist_len) {
- cmd->scan_begin_arg =
- board->ai_speed * cmd->chanlist_len;
- err++;
- }
- }
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < board->ai_speed) {
- cmd->convert_arg = board->ai_speed;
- err++;
- }
- }
+ if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ /* check against maximum frequency */
+ if (cmd->scan_begin_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ board->ai_speed * cmd->chanlist_len);
+
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ board->ai_speed);
+
+ if (cmd->stop_src == TRIG_NONE)
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
- if (cmd->stop_src == TRIG_NONE) {
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
if (err)
return 3;
@@ -540,6 +521,7 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
+ struct das16_private_struct *devpriv = dev->private;
unsigned int size;
unsigned int freq;
@@ -581,6 +563,8 @@ static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
int rounding_flags)
{
+ struct das16_private_struct *devpriv = dev->private;
+
i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1),
&(devpriv->divisor2), &ns,
rounding_flags & TRIG_ROUND_MASK);
@@ -595,6 +579,7 @@ static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
{
const struct das16_board *board = comedi_board(dev);
+ struct das16_private_struct *devpriv = dev->private;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
unsigned int byte;
@@ -701,6 +686,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
const struct das16_board *board = comedi_board(dev);
+ struct das16_private_struct *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&dev->spinlock, flags);
@@ -738,6 +724,7 @@ static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
const struct das16_board *board = comedi_board(dev);
+ struct das16_private_struct *devpriv = dev->private;
int i, n;
int range;
int chan;
@@ -848,10 +835,12 @@ static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
*/
static int disable_dma_on_even(struct comedi_device *dev)
{
+ struct das16_private_struct *devpriv = dev->private;
int residue;
int i;
static const int disable_limit = 100;
static const int enable_timeout = 100;
+
disable_dma(devpriv->dma_chan);
residue = get_dma_residue(devpriv->dma_chan);
for (i = 0; i < disable_limit && (residue % 2); ++i) {
@@ -877,6 +866,7 @@ static int disable_dma_on_even(struct comedi_device *dev)
static void das16_interrupt(struct comedi_device *dev)
{
const struct das16_board *board = comedi_board(dev);
+ struct das16_private_struct *devpriv = dev->private;
unsigned long dma_flags, spin_flags;
struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async;
@@ -973,6 +963,7 @@ static irqreturn_t das16_dma_interrupt(int irq, void *d)
static void das16_timer_interrupt(unsigned long arg)
{
struct comedi_device *dev = (struct comedi_device *)arg;
+ struct das16_private_struct *devpriv = dev->private;
das16_interrupt(dev);
@@ -1001,6 +992,7 @@ static void reg_dump(struct comedi_device *dev)
static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct das16_board *board = comedi_board(dev);
+ struct das16_private_struct *devpriv = dev->private;
int status;
int diobits;
@@ -1035,6 +1027,7 @@ static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it)
static int das1600_mode_detect(struct comedi_device *dev)
{
+ struct das16_private_struct *devpriv = dev->private;
int status = 0;
status = inb(dev->iobase + DAS1600_STATUS_B);
@@ -1080,6 +1073,7 @@ static void das16_ai_munge(struct comedi_device *dev,
static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct das16_board *board = comedi_board(dev);
+ struct das16_private_struct *devpriv;
struct comedi_subdevice *s;
int ret;
unsigned int irq;
@@ -1114,9 +1108,10 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
}
- ret = alloc_private(dev, sizeof(struct das16_private_struct));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
if (board->size < 0x400) {
printk(" 0x%04lx-0x%04lx\n", iobase, iobase + board->size);
@@ -1353,6 +1348,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
static void das16_detach(struct comedi_device *dev)
{
const struct das16_board *board = comedi_board(dev);
+ struct das16_private_struct *devpriv = dev->private;
das16_reset(dev);
if (dev->subdevices)
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c
index 3f87d7598e5..b0a861a779b 100644
--- a/drivers/staging/comedi/drivers/das16m1.c
+++ b/drivers/staging/comedi/drivers/das16m1.c
@@ -28,7 +28,7 @@
Driver: das16m1
Description: CIO-DAS16/M1
Author: Frank Mori Hess <fmhess@users.sourceforge.net>
-Devices: [Measurement Computing] CIO-DAS16/M1 (cio-das16/m1)
+Devices: [Measurement Computing] CIO-DAS16/M1 (das16m1)
Status: works
This driver supports a single board - the CIO-DAS16/M1.
@@ -132,11 +132,6 @@ static const struct comedi_lrange range_das16m1 = { 9,
}
};
-struct das16m1_board {
- const char *name;
- unsigned int ai_speed;
-};
-
struct das16m1_private_struct {
unsigned int control_state;
volatile unsigned int adc_count; /* number of samples completed */
@@ -149,7 +144,6 @@ struct das16m1_private_struct {
unsigned int divisor1; /* divides master clock to obtain conversion speed */
unsigned int divisor2; /* divides master clock to obtain conversion speed */
};
-#define devpriv ((struct das16m1_private_struct *)(dev->private))
static inline short munge_sample(short data)
{
@@ -167,7 +161,7 @@ static void munge_sample_array(short *array, unsigned int num_elements)
static int das16m1_cmd_test(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
- const struct das16m1_board *board = comedi_board(dev);
+ struct das16m1_private_struct *devpriv = dev->private;
unsigned int err = 0, tmp, i;
/* Step 1 : check if triggers are trivially valid */
@@ -192,40 +186,23 @@ static int das16m1_cmd_test(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- /* internal trigger */
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < board->ai_speed) {
- cmd->convert_arg = board->ai_speed;
- err++;
- }
- }
+ if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 1000);
+
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
if (cmd->stop_src == TRIG_COUNT) {
/* any count is allowed */
} else {
/* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
}
if (err)
@@ -277,6 +254,8 @@ static int das16m1_cmd_test(struct comedi_device *dev,
static unsigned int das16m1_set_pacer(struct comedi_device *dev,
unsigned int ns, int rounding_flags)
{
+ 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);
@@ -293,6 +272,7 @@ static unsigned int das16m1_set_pacer(struct comedi_device *dev,
static int das16m1_cmd_exec(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct das16m1_private_struct *devpriv = dev->private;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
unsigned int byte, i;
@@ -356,6 +336,8 @@ static int das16m1_cmd_exec(struct comedi_device *dev,
static int das16m1_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct das16m1_private_struct *devpriv = dev->private;
+
devpriv->control_state &= ~INTE & ~PACER_MASK;
outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
@@ -366,6 +348,7 @@ static int das16m1_ai_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct das16m1_private_struct *devpriv = dev->private;
int i, n;
int byte;
const int timeout = 1000;
@@ -417,6 +400,7 @@ static int das16m1_do_wbits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct das16m1_private_struct *devpriv = dev->private;
unsigned int wbits;
/* only set bits that have been masked */
@@ -436,6 +420,7 @@ static int das16m1_do_wbits(struct comedi_device *dev,
static void das16m1_handler(struct comedi_device *dev, unsigned int status)
{
+ struct das16m1_private_struct *devpriv = dev->private;
struct comedi_subdevice *s;
struct comedi_async *async;
struct comedi_cmd *cmd;
@@ -582,26 +567,27 @@ static int das16m1_irq_bits(unsigned int irq)
static int das16m1_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
- const struct das16m1_board *board = comedi_board(dev);
+ struct das16m1_private_struct *devpriv;
struct comedi_subdevice *s;
int ret;
unsigned int irq;
unsigned long iobase;
- iobase = it->options[0];
+ dev->board_name = dev->driver->driver_name;
- ret = alloc_private(dev, sizeof(struct das16m1_private_struct));
- if (ret < 0)
- return ret;
+ iobase = it->options[0];
- dev->board_name = board->name;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
- if (!request_region(iobase, DAS16M1_SIZE, dev->driver->driver_name)) {
+ if (!request_region(iobase, DAS16M1_SIZE, dev->board_name)) {
comedi_error(dev, "I/O port conflict\n");
return -EIO;
}
if (!request_region(iobase + DAS16M1_82C55, DAS16M1_SIZE2,
- dev->driver->driver_name)) {
+ dev->board_name)) {
release_region(iobase, DAS16M1_SIZE);
comedi_error(dev, "I/O port conflict\n");
return -EIO;
@@ -698,21 +684,11 @@ static void das16m1_detach(struct comedi_device *dev)
}
}
-static const struct das16m1_board das16m1_boards[] = {
- {
- .name = "cio-das16/m1", /* CIO-DAS16_M1.pdf */
- .ai_speed = 1000, /* 1MHz max speed */
- },
-};
-
static struct comedi_driver das16m1_driver = {
.driver_name = "das16m1",
.module = THIS_MODULE,
.attach = das16m1_attach,
.detach = das16m1_detach,
- .board_name = &das16m1_boards[0].name,
- .num_names = ARRAY_SIZE(das16m1_boards),
- .offset = sizeof(das16m1_boards[0]),
};
module_comedi_driver(das16m1_driver);
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
index 2555f3297d7..7900f959555 100644
--- a/drivers/staging/comedi/drivers/das1800.c
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -454,8 +454,6 @@ struct das1800_private {
short ao_update_bits; /* remembers the last write to the 'update' dac */
};
-#define devpriv ((struct das1800_private *)dev->private)
-
/* analog out range for boards with basic analog out */
static const struct comedi_lrange range_ao_1 = {
1,
@@ -501,6 +499,7 @@ static void munge_data(struct comedi_device *dev, uint16_t * array,
static void das1800_handle_fifo_half_full(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct das1800_private *devpriv = dev->private;
int numPoints = 0; /* number of points to read */
struct comedi_cmd *cmd = &s->async->cmd;
@@ -520,6 +519,7 @@ static void das1800_handle_fifo_half_full(struct comedi_device *dev,
static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct das1800_private *devpriv = dev->private;
short dpnt;
int unipolar;
struct comedi_cmd *cmd = &s->async->cmd;
@@ -548,6 +548,7 @@ static void das1800_flush_dma_channel(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned int channel, uint16_t *buffer)
{
+ struct das1800_private *devpriv = dev->private;
unsigned int num_bytes, num_samples;
struct comedi_cmd *cmd = &s->async->cmd;
@@ -578,6 +579,7 @@ static void das1800_flush_dma_channel(struct comedi_device *dev,
static void das1800_flush_dma(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct das1800_private *devpriv = dev->private;
unsigned long flags;
const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
@@ -609,6 +611,7 @@ static void das1800_flush_dma(struct comedi_device *dev,
static void das1800_handle_dma(struct comedi_device *dev,
struct comedi_subdevice *s, unsigned int status)
{
+ struct das1800_private *devpriv = dev->private;
unsigned long flags;
const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
@@ -643,6 +646,8 @@ static void das1800_handle_dma(struct comedi_device *dev,
static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct das1800_private *devpriv = dev->private;
+
outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */
outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */
outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */
@@ -656,6 +661,7 @@ static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
/* the guts of the interrupt handler, that is shared with das1800_ai_poll */
static void das1800_ai_handler(struct comedi_device *dev)
{
+ struct das1800_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[0];
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
@@ -783,6 +789,7 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
+ struct das1800_private *devpriv = dev->private;
int err = 0;
unsigned int tmp_arg;
int i;
@@ -817,39 +824,23 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < thisboard->ai_speed) {
- cmd->convert_arg = thisboard->ai_speed;
- err++;
- }
- }
- if (!cmd->chanlist_len) {
- cmd->chanlist_len = 1;
- err++;
- }
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ thisboard->ai_speed);
+
+ err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
switch (cmd->stop_src) {
case TRIG_COUNT:
- if (!cmd->stop_arg) {
- cmd->stop_arg = 1;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
break;
case TRIG_NONE:
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
break;
default:
break;
@@ -1006,6 +997,7 @@ static int control_c_bits(const struct comedi_cmd *cmd)
/* loads counters with divisor1, divisor2 from private structure */
static int das1800_set_frequency(struct comedi_device *dev)
{
+ struct das1800_private *devpriv = dev->private;
int err = 0;
/* counter 1, mode 2 */
@@ -1026,6 +1018,7 @@ static int das1800_set_frequency(struct comedi_device *dev)
static int setup_counters(struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
+ struct das1800_private *devpriv = dev->private;
unsigned int period;
/* setup cascaded counters for conversion/scan frequency */
@@ -1107,6 +1100,7 @@ static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd)
/* sets up dma */
static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
{
+ struct das1800_private *devpriv = dev->private;
unsigned long lock_flags;
const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
@@ -1174,6 +1168,7 @@ static void program_chanlist(struct comedi_device *dev,
static int das1800_ai_do_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct das1800_private *devpriv = dev->private;
int ret;
int control_a, control_c;
struct comedi_async *async = s->async;
@@ -1300,6 +1295,7 @@ static int das1800_ao_winsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct das1800_private *devpriv = dev->private;
int chan = CR_CHAN(insn->chanspec);
/* int range = CR_RANGE(insn->chanspec); */
int update_chan = thisboard->ao_n_chan - 1;
@@ -1342,6 +1338,7 @@ static int das1800_do_wbits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct das1800_private *devpriv = dev->private;
unsigned int wbits;
/* only set bits that have been masked */
@@ -1361,6 +1358,7 @@ static int das1800_do_wbits(struct comedi_device *dev,
static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
unsigned int dma1)
{
+ struct das1800_private *devpriv = dev->private;
unsigned long flags;
/* need an irq to do dma */
@@ -1518,6 +1516,7 @@ static int das1800_probe(struct comedi_device *dev)
static int das1800_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
+ struct das1800_private *devpriv;
struct comedi_subdevice *s;
unsigned long iobase = it->options[0];
unsigned int irq = it->options[1];
@@ -1527,9 +1526,10 @@ static int das1800_attach(struct comedi_device *dev,
int board;
int retval;
- /* allocate and initialize dev->private */
- if (alloc_private(dev, sizeof(struct das1800_private)) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
printk(KERN_DEBUG "comedi%d: %s: io 0x%lx", dev->minor,
dev->driver->driver_name, iobase);
@@ -1699,11 +1699,13 @@ static int das1800_attach(struct comedi_device *dev,
static void das1800_detach(struct comedi_device *dev)
{
+ struct das1800_private *devpriv = dev->private;
+
if (dev->iobase)
release_region(dev->iobase, DAS1800_SIZE);
if (dev->irq)
free_irq(dev->irq, dev);
- if (dev->private) {
+ if (devpriv) {
if (devpriv->iobase2)
release_region(devpriv->iobase2, DAS1800_SIZE);
if (devpriv->dma0)
diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c
index e134c46dedf..2efddb89bbc 100644
--- a/drivers/staging/comedi/drivers/das6402.c
+++ b/drivers/staging/comedi/drivers/das6402.c
@@ -104,7 +104,6 @@ struct das6402_private {
int das6402_ignoreirq;
};
-#define devpriv ((struct das6402_private *)dev->private)
static void das6402_ai_fifo_dregs(struct comedi_device *dev,
struct comedi_subdevice *s)
@@ -152,6 +151,7 @@ static void das6402_setcounter(struct comedi_device *dev)
static irqreturn_t intr_handler(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct das6402_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[0];
if (!dev->attached || devpriv->das6402_ignoreirq) {
@@ -196,6 +196,8 @@ static void das6402_ai_fifo_read(struct comedi_device *dev, short *data, int n)
static int das6402_ai_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct das6402_private *devpriv = dev->private;
+
/*
* This function should reset the board from whatever condition it
* is in (i.e., acquiring data), to a non-active state.
@@ -217,6 +219,8 @@ static int das6402_ai_cancel(struct comedi_device *dev,
static int das6402_ai_mode2(struct comedi_device *dev,
struct comedi_subdevice *s, comedi_trig * it)
{
+ struct das6402_private *devpriv = dev->private;
+
devpriv->das6402_ignoreirq = 1;
dev_dbg(dev->class_dev, "Starting acquisition\n");
outb_p(0x03, dev->iobase + 10); /* enable external trigging */
@@ -236,6 +240,7 @@ static int das6402_ai_mode2(struct comedi_device *dev,
static int board_init(struct comedi_device *dev)
{
+ struct das6402_private *devpriv = dev->private;
BYTE b;
devpriv->das6402_ignoreirq = 1;
@@ -277,6 +282,7 @@ static int board_init(struct comedi_device *dev)
static int das6402_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
+ struct das6402_private *devpriv;
unsigned int irq;
unsigned long iobase;
int ret;
@@ -303,9 +309,11 @@ static int das6402_attach(struct comedi_device *dev,
return ret;
dev->irq = irq;
- ret = alloc_private(dev, sizeof(struct das6402_private));
- if (ret < 0)
- return ret;
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_alloc_subdevices(dev, 1);
if (ret)
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
index 215deac0a39..38f625be812 100644
--- a/drivers/staging/comedi/drivers/das800.c
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -241,8 +241,6 @@ struct das800_private {
volatile int do_bits; /* digital output bits */
};
-#define devpriv ((struct das800_private *)dev->private)
-
static int das800_attach(struct comedi_device *dev,
struct comedi_devconfig *it);
static void das800_detach(struct comedi_device *dev);
@@ -344,22 +342,7 @@ static int das800_probe(struct comedi_device *dev)
return -1;
}
-/*
- * A convenient macro that defines init_module() and cleanup_module(),
- * as necessary.
- */
-static int __init driver_das800_init_module(void)
-{
- return comedi_driver_register(&driver_das800);
-}
-
-static void __exit driver_das800_cleanup_module(void)
-{
- comedi_driver_unregister(&driver_das800);
-}
-
-module_init(driver_das800_init_module);
-module_exit(driver_das800_cleanup_module);
+module_comedi_driver(driver_das800);
/* interrupt service routine */
static irqreturn_t das800_interrupt(int irq, void *d)
@@ -367,6 +350,7 @@ static irqreturn_t das800_interrupt(int irq, void *d)
short i; /* loop index */
short dataPoint = 0;
struct comedi_device *dev = d;
+ struct das800_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev; /* analog input subdevice */
struct comedi_async *async;
int status;
@@ -461,6 +445,7 @@ static irqreturn_t das800_interrupt(int irq, void *d)
static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ struct das800_private *devpriv;
struct comedi_subdevice *s;
unsigned long iobase = it->options[0];
unsigned int irq = it->options[1];
@@ -472,9 +457,10 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (irq)
dev_dbg(dev->class_dev, "irq %u\n", irq);
- /* allocate and initialize dev->private */
- if (alloc_private(dev, sizeof(struct das800_private)) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
if (iobase == 0) {
dev_err(dev->class_dev,
@@ -569,6 +555,8 @@ static void das800_detach(struct comedi_device *dev)
static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct das800_private *devpriv = dev->private;
+
devpriv->forever = 0;
devpriv->count = 0;
disable_das800(dev);
@@ -578,7 +566,9 @@ static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
/* enable_das800 makes the card start taking hardware triggered conversions */
static void enable_das800(struct comedi_device *dev)
{
+ struct das800_private *devpriv = dev->private;
unsigned long irq_flags;
+
spin_lock_irqsave(&dev->spinlock, irq_flags);
/* enable fifo-half full interrupts for cio-das802/16 */
if (thisboard->resolution == 16)
@@ -604,6 +594,7 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
+ struct das800_private *devpriv = dev->private;
int err = 0;
int tmp;
int gain, startChan;
@@ -631,37 +622,21 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < thisboard->ai_speed) {
- cmd->convert_arg = thisboard->ai_speed;
- err++;
- }
- }
- if (!cmd->chanlist_len) {
- cmd->chanlist_len = 1;
- err++;
- }
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) {
- if (!cmd->stop_arg) {
- cmd->stop_arg = 1;
- err++;
- }
- } else { /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ thisboard->ai_speed);
+
+ err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -710,6 +685,7 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev,
static int das800_ai_do_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct das800_private *devpriv = dev->private;
int startChan, endChan, scan, gain;
int conv_bits;
unsigned long irq_flags;
@@ -793,6 +769,7 @@ static int das800_ai_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
+ struct das800_private *devpriv = dev->private;
int i, n;
int chan;
int range;
@@ -862,6 +839,7 @@ static int das800_do_wbits(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
+ struct das800_private *devpriv = dev->private;
int wbits;
unsigned long irq_flags;
@@ -885,6 +863,7 @@ static int das800_do_wbits(struct comedi_device *dev,
/* loads counters with divisor1, divisor2 from private structure */
static int das800_set_frequency(struct comedi_device *dev)
{
+ struct das800_private *devpriv = dev->private;
int err = 0;
if (i8254_load(dev->iobase + DAS800_8254, 0, 1, devpriv->divisor1, 2))
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
index 4d5c33c4750..9e2124179a0 100644
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -158,10 +158,6 @@ static const struct comedi_lrange dmm32at_aoranges = {
}
};
-struct dmm32at_board {
- const char *name;
-};
-
struct dmm32at_private {
int data;
@@ -284,33 +280,25 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
#define MAX_SCAN_SPEED 1000000 /* in nanoseconds */
#define MIN_SCAN_SPEED 1000000000 /* in nanoseconds */
if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->scan_begin_arg < MAX_SCAN_SPEED) {
- cmd->scan_begin_arg = MAX_SCAN_SPEED;
- err++;
- }
- if (cmd->scan_begin_arg > MIN_SCAN_SPEED) {
- cmd->scan_begin_arg = MIN_SCAN_SPEED;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ MAX_SCAN_SPEED);
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
+ MIN_SCAN_SPEED);
} else {
/* external trigger */
/* should be level/edge, hi/lo specification here */
/* should specify multiple external triggers */
- if (cmd->scan_begin_arg > 9) {
- cmd->scan_begin_arg = 9;
- err++;
- }
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
}
+
if (cmd->convert_src == TRIG_TIMER) {
if (cmd->convert_arg >= 17500)
cmd->convert_arg = 20000;
@@ -320,35 +308,20 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev,
cmd->convert_arg = 10000;
else
cmd->convert_arg = 5000;
-
} else {
/* external trigger */
/* see above */
- if (cmd->convert_arg > 9) {
- cmd->convert_arg = 9;
- err++;
- }
+ err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9);
}
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
if (cmd->stop_src == TRIG_COUNT) {
- if (cmd->stop_arg > 0xfffffff0) {
- cmd->stop_arg = 0xfffffff0;
- err++;
- }
- if (cmd->stop_arg == 0) {
- cmd->stop_arg = 1;
- err++;
- }
+ err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0xfffffff0);
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
} else {
/* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
}
if (err)
@@ -718,7 +691,6 @@ static int dmm32at_dio_insn_config(struct comedi_device *dev,
static int dmm32at_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
- const struct dmm32at_board *board = comedi_board(dev);
struct dmm32at_private *devpriv;
int ret;
struct comedi_subdevice *s;
@@ -726,6 +698,8 @@ static int dmm32at_attach(struct comedi_device *dev,
unsigned long iobase;
unsigned int irq;
+ dev->board_name = dev->driver->driver_name;
+
iobase = it->options[0];
irq = it->options[1];
@@ -734,7 +708,7 @@ static int dmm32at_attach(struct comedi_device *dev,
iobase, irq);
/* register address space */
- if (!request_region(iobase, DMM32AT_MEMSIZE, board->name)) {
+ if (!request_region(iobase, DMM32AT_MEMSIZE, dev->board_name)) {
printk(KERN_ERR "comedi%d: dmm32at: I/O port conflict\n",
dev->minor);
return -EIO;
@@ -788,7 +762,7 @@ static int dmm32at_attach(struct comedi_device *dev,
/* board is there, register interrupt */
if (irq) {
- ret = request_irq(irq, dmm32at_isr, 0, board->name, dev);
+ ret = request_irq(irq, dmm32at_isr, 0, dev->board_name, dev);
if (ret < 0) {
printk(KERN_ERR "dmm32at: irq conflict\n");
return ret;
@@ -796,11 +770,10 @@ static int dmm32at_attach(struct comedi_device *dev,
dev->irq = irq;
}
- dev->board_name = board->name;
-
- if (alloc_private(dev, sizeof(*devpriv)) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
- devpriv = dev->private;
+ dev->private = devpriv;
ret = comedi_alloc_subdevices(dev, 3);
if (ret)
@@ -867,20 +840,11 @@ static void dmm32at_detach(struct comedi_device *dev)
release_region(dev->iobase, DMM32AT_MEMSIZE);
}
-static const struct dmm32at_board dmm32at_boards[] = {
- {
- .name = "dmm32at",
- },
-};
-
static struct comedi_driver dmm32at_driver = {
.driver_name = "dmm32at",
.module = THIS_MODULE,
.attach = dmm32at_attach,
.detach = dmm32at_detach,
- .board_name = &dmm32at_boards[0].name,
- .offset = sizeof(struct dmm32at_board),
- .num_names = ARRAY_SIZE(dmm32at_boards),
};
module_comedi_driver(dmm32at_driver);
diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c
index c59a652a119..f6942aaf0ec 100644
--- a/drivers/staging/comedi/drivers/dt2801.c
+++ b/drivers/staging/comedi/drivers/dt2801.c
@@ -233,8 +233,6 @@ struct dt2801_private {
unsigned int ao_readback[2];
};
-#define devpriv ((struct dt2801_private *)dev->private)
-
/* These are the low-level routines:
writecommand: write a command to the board
writedata: write data byte
@@ -508,6 +506,8 @@ static int dt2801_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct dt2801_private *devpriv = dev->private;
+
data[0] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
return 1;
@@ -517,6 +517,8 @@ static int dt2801_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct dt2801_private *devpriv = dev->private;
+
dt2801_writecmd(dev, DT_C_WRITE_DAIM);
dt2801_writedata(dev, CR_CHAN(insn->chanspec));
dt2801_writedata2(dev, data[0]);
@@ -590,6 +592,7 @@ static int dt2801_dio_insn_config(struct comedi_device *dev,
*/
static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ struct dt2801_private *devpriv;
struct comedi_subdevice *s;
unsigned long iobase;
int board_code, type;
@@ -630,9 +633,10 @@ havetype:
if (ret)
goto out;
- ret = alloc_private(dev, sizeof(struct dt2801_private));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
dev->board_name = boardtype.name;
diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c
index d3a8c1aec9d..f90ecf494aa 100644
--- a/drivers/staging/comedi/drivers/dt2811.c
+++ b/drivers/staging/comedi/drivers/dt2811.c
@@ -226,8 +226,6 @@ struct dt2811_private {
unsigned int ao_readback[2];
};
-#define devpriv ((struct dt2811_private *)dev->private)
-
static const struct comedi_lrange *dac_range_types[] = {
&range_bipolar5,
&range_bipolar2_5,
@@ -242,6 +240,7 @@ static irqreturn_t dt2811_interrupt(int irq, void *d)
int lo, hi;
int data;
struct comedi_device *dev = d;
+ struct dt2811_private *devpriv = dev->private;
if (!dev->attached) {
comedi_error(dev, "spurious interrupt");
@@ -318,6 +317,7 @@ int dt2811_adtrig(kdev_t minor, comedi_adtrig *adtrig)
static int dt2811_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct dt2811_private *devpriv = dev->private;
int i;
int chan;
@@ -337,6 +337,7 @@ static int dt2811_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct dt2811_private *devpriv = dev->private;
int i;
int chan;
@@ -397,6 +398,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it)
/* long flags; */
const struct dt2811_board *board = comedi_board(dev);
+ struct dt2811_private *devpriv;
int ret;
struct comedi_subdevice *s;
unsigned long iobase;
@@ -463,9 +465,10 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (ret)
return ret;
- ret = alloc_private(dev, sizeof(struct dt2811_private));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
switch (it->options[2]) {
case 0:
diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c
index 064a8f215e4..e520dbaaa19 100644
--- a/drivers/staging/comedi/drivers/dt2814.c
+++ b/drivers/staging/comedi/drivers/dt2814.c
@@ -68,8 +68,6 @@ struct dt2814_private {
int curadchan;
};
-#define devpriv ((struct dt2814_private *)dev->private)
-
#define DT2814_TIMEOUT 10
#define DT2814_MAX_SPEED 100000 /* Arbitrary 10 khz limit */
@@ -151,36 +149,20 @@ static int dt2814_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
- if (cmd->scan_begin_arg > 1000000000) {
- cmd->scan_begin_arg = 1000000000;
- err++;
- }
- if (cmd->scan_begin_arg < DT2814_MAX_SPEED) {
- cmd->scan_begin_arg = DT2814_MAX_SPEED;
- err++;
- }
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) {
- if (cmd->stop_arg < 2) {
- cmd->stop_arg = 2;
- err++;
- }
- } else {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 1000000000);
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ DT2814_MAX_SPEED);
+
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 2);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -200,6 +182,7 @@ static int dt2814_ai_cmdtest(struct comedi_device *dev,
static int dt2814_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct dt2814_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
int chan;
int trigvar;
@@ -221,6 +204,7 @@ static irqreturn_t dt2814_interrupt(int irq, void *d)
{
int lo, hi;
struct comedi_device *dev = d;
+ struct dt2814_private *devpriv = dev->private;
struct comedi_subdevice *s;
int data;
@@ -258,6 +242,7 @@ static irqreturn_t dt2814_interrupt(int irq, void *d)
static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ struct dt2814_private *devpriv;
int i, irq;
int ret;
struct comedi_subdevice *s;
@@ -324,9 +309,10 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (ret)
return ret;
- ret = alloc_private(dev, sizeof(struct dt2814_private));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
s = &dev->subdevices[0];
dev->read_subdev = s;
diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c
index b9692ef64c4..1e0cfe4972a 100644
--- a/drivers/staging/comedi/drivers/dt2815.c
+++ b/drivers/staging/comedi/drivers/dt2815.c
@@ -78,8 +78,6 @@ struct dt2815_private {
unsigned int ao_readback[8];
};
-#define devpriv ((struct dt2815_private *)dev->private)
-
static int dt2815_wait_for_status(struct comedi_device *dev, int status)
{
int i;
@@ -95,6 +93,7 @@ static int dt2815_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct dt2815_private *devpriv = dev->private;
int i;
int chan = CR_CHAN(insn->chanspec);
@@ -107,6 +106,7 @@ static int dt2815_ao_insn_read(struct comedi_device *dev,
static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct dt2815_private *devpriv = dev->private;
int i;
int chan = CR_CHAN(insn->chanspec);
unsigned int status;
@@ -162,6 +162,7 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ struct dt2815_private *devpriv;
struct comedi_subdevice *s;
int i;
const struct comedi_lrange *current_range_type, *voltage_range_type;
@@ -182,8 +183,10 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (ret)
return ret;
- if (alloc_private(dev, sizeof(struct dt2815_private)) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
s = &dev->subdevices[0];
/* ao subdevice */
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
index 78d340716d1..122d980a95a 100644
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -248,7 +248,6 @@ struct dt282x_private {
int dma_dir;
};
-#define devpriv ((struct dt282x_private *)dev->private)
#define boardtype (*(const struct dt282x_board *)dev->board_ptr)
/*
@@ -290,6 +289,7 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2);
static void dt282x_munge(struct comedi_device *dev, short *buf,
unsigned int nbytes)
{
+ struct dt282x_private *devpriv = dev->private;
unsigned int i;
unsigned short mask = (1 << boardtype.adbits) - 1;
unsigned short sign = 1 << (boardtype.adbits - 1);
@@ -309,6 +309,7 @@ static void dt282x_munge(struct comedi_device *dev, short *buf,
static void dt282x_ao_dma_interrupt(struct comedi_device *dev)
{
+ struct dt282x_private *devpriv = dev->private;
void *ptr;
int size;
int i;
@@ -341,6 +342,7 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev)
static void dt282x_ai_dma_interrupt(struct comedi_device *dev)
{
+ struct dt282x_private *devpriv = dev->private;
void *ptr;
int size;
int i;
@@ -393,6 +395,7 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev)
static int prep_ai_dma(struct comedi_device *dev, int dma_index, int n)
{
+ struct dt282x_private *devpriv = dev->private;
int dma_chan;
unsigned long dma_ptr;
unsigned long flags;
@@ -424,6 +427,7 @@ static int prep_ai_dma(struct comedi_device *dev, int dma_index, int n)
static int prep_ao_dma(struct comedi_device *dev, int dma_index, int n)
{
+ struct dt282x_private *devpriv = dev->private;
int dma_chan;
unsigned long dma_ptr;
unsigned long flags;
@@ -447,6 +451,7 @@ static int prep_ao_dma(struct comedi_device *dev, int dma_index, int n)
static irqreturn_t dt282x_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct dt282x_private *devpriv = dev->private;
struct comedi_subdevice *s;
struct comedi_subdevice *s_ao;
unsigned int supcsr, adcsr, dacsr;
@@ -525,6 +530,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
static void dt282x_load_changain(struct comedi_device *dev, int n,
unsigned int *chanlist)
{
+ struct dt282x_private *devpriv = dev->private;
unsigned int i;
unsigned int chan, range;
@@ -548,6 +554,7 @@ static int dt282x_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct dt282x_private *devpriv = dev->private;
int i;
/* XXX should we really be enabling the ad clock here? */
@@ -604,52 +611,30 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
if (cmd->scan_begin_src == TRIG_FOLLOW) {
/* internal trigger */
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
} else {
/* external trigger */
/* should be level/edge, hi/lo specification here */
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
- }
- if (cmd->convert_arg < 4000) {
- /* XXX board dependent */
- cmd->convert_arg = 4000;
- err++;
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
}
+
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 4000);
+
#define SLOWEST_TIMER (250*(1<<15)*255)
- if (cmd->convert_arg > SLOWEST_TIMER) {
- cmd->convert_arg = SLOWEST_TIMER;
- err++;
- }
- if (cmd->convert_arg < board->ai_speed) {
- cmd->convert_arg = board->ai_speed;
- err++;
- }
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ err |= cfc_check_trigger_arg_max(&cmd->convert_arg, SLOWEST_TIMER);
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg, board->ai_speed);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
if (cmd->stop_src == TRIG_COUNT) {
/* any count is allowed */
- } else {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ } else { /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
}
if (err)
@@ -671,6 +656,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev,
static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
const struct dt282x_board *board = comedi_board(dev);
+ struct dt282x_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
int timer;
@@ -733,6 +719,8 @@ static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static void dt282x_disable_dma(struct comedi_device *dev)
{
+ struct dt282x_private *devpriv = dev->private;
+
if (devpriv->usedma) {
disable_dma(devpriv->dma[0].chan);
disable_dma(devpriv->dma[1].chan);
@@ -742,6 +730,8 @@ static void dt282x_disable_dma(struct comedi_device *dev)
static int dt282x_ai_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct dt282x_private *devpriv = dev->private;
+
dt282x_disable_dma(dev);
devpriv->adcsr = 0;
@@ -794,6 +784,8 @@ static int dt282x_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct dt282x_private *devpriv = dev->private;
+
data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
return 1;
@@ -803,6 +795,7 @@ static int dt282x_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct dt282x_private *devpriv = dev->private;
short d;
unsigned int chan;
@@ -859,33 +852,17 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 5000);
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+ err |= cfc_check_trigger_arg_max(&cmd->scan_end_arg, 2);
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
- if (cmd->scan_begin_arg < 5000 /* XXX unknown */) {
- cmd->scan_begin_arg = 5000;
- err++;
- }
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
- if (cmd->scan_end_arg > 2) {
- /* XXX chanlist stuff? */
- cmd->scan_end_arg = 2;
- err++;
- }
if (cmd->stop_src == TRIG_COUNT) {
/* any count is allowed */
- } else {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ } else { /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
}
if (err)
@@ -908,6 +885,7 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev,
static int dt282x_ao_inttrig(struct comedi_device *dev,
struct comedi_subdevice *s, unsigned int x)
{
+ struct dt282x_private *devpriv = dev->private;
int size;
if (x != 0)
@@ -937,6 +915,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev,
static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct dt282x_private *devpriv = dev->private;
int timer;
struct comedi_cmd *cmd = &s->async->cmd;
@@ -973,6 +952,8 @@ static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static int dt282x_ao_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct dt282x_private *devpriv = dev->private;
+
dt282x_disable_dma(dev);
devpriv->dacsr = 0;
@@ -1003,6 +984,7 @@ static int dt282x_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct dt282x_private *devpriv = dev->private;
int mask;
mask = (CR_CHAN(insn->chanspec) < 8) ? 0x00ff : 0xff00;
@@ -1074,6 +1056,7 @@ enum { /* i/o base, irq, dma channels */
static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2)
{
+ struct dt282x_private *devpriv = dev->private;
int ret;
devpriv->usedma = 0;
@@ -1135,6 +1118,7 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2)
static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct dt282x_board *board = comedi_board(dev);
+ struct dt282x_private *devpriv;
int i, irq;
int ret;
struct comedi_subdevice *s;
@@ -1217,9 +1201,10 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
#endif
}
- ret = alloc_private(dev, sizeof(struct dt282x_private));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = dt282x_grab_dma(dev, it->options[opt_dma1],
it->options[opt_dma2]);
@@ -1292,6 +1277,8 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
static void dt282x_detach(struct comedi_device *dev)
{
+ struct dt282x_private *devpriv = dev->private;
+
if (dev->irq)
free_irq(dev->irq, dev);
if (dev->iobase)
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c
index 43d05ef9715..960da8debe1 100644
--- a/drivers/staging/comedi/drivers/dt3000.c
+++ b/drivers/staging/comedi/drivers/dt3000.c
@@ -29,11 +29,7 @@ Devices: [Data Translation] DT3001 (dt3000), DT3001-PGL, DT3002, DT3003,
Updated: Mon, 14 Apr 2008 15:41:24 +0100
Status: works
-Configuration Options:
- [0] - PCI bus of device (optional)
- [1] - PCI slot of device (optional)
- If bus/slot is not specified, the first supported
- PCI device found will be used.
+Configuration Options: not applicable, uses PCI auto config
There is code to support AI commands, but it may not work.
@@ -65,26 +61,36 @@ AO commands are not supported.
#include "comedi_fc.h"
-#define PCI_VENDOR_ID_DT 0x1116
-
-static const struct comedi_lrange range_dt3000_ai = { 4, {
- RANGE(-10, 10),
- RANGE(-5, 5),
- RANGE(-2.5, 2.5),
- RANGE(-1.25, 1.25)
- }
+/*
+ * PCI device id's supported by this driver
+ */
+#define PCI_DEVICE_ID_DT3001 0x0022
+#define PCI_DEVICE_ID_DT3002 0x0023
+#define PCI_DEVICE_ID_DT3003 0x0024
+#define PCI_DEVICE_ID_DT3004 0x0025
+#define PCI_DEVICE_ID_DT3005 0x0026
+#define PCI_DEVICE_ID_DT3001_PGL 0x0027
+#define PCI_DEVICE_ID_DT3003_PGL 0x0028
+
+static const struct comedi_lrange range_dt3000_ai = {
+ 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25)
+ }
};
-static const struct comedi_lrange range_dt3000_ai_pgl = { 4, {
- RANGE(-10, 10),
- RANGE(-1, 1),
- RANGE(-0.1, 0.1),
- RANGE(-0.02, 0.02)
- }
+static const struct comedi_lrange range_dt3000_ai_pgl = {
+ 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.02)
+ }
};
struct dt3k_boardtype {
-
const char *name;
unsigned int device_id;
int adchan;
@@ -96,73 +102,70 @@ struct dt3k_boardtype {
};
static const struct dt3k_boardtype dt3k_boardtypes[] = {
- {.name = "dt3001",
- .device_id = 0x22,
- .adchan = 16,
- .adbits = 12,
- .adrange = &range_dt3000_ai,
- .ai_speed = 3000,
- .dachan = 2,
- .dabits = 12,
- },
- {.name = "dt3001-pgl",
- .device_id = 0x27,
- .adchan = 16,
- .adbits = 12,
- .adrange = &range_dt3000_ai_pgl,
- .ai_speed = 3000,
- .dachan = 2,
- .dabits = 12,
- },
- {.name = "dt3002",
- .device_id = 0x23,
- .adchan = 32,
- .adbits = 12,
- .adrange = &range_dt3000_ai,
- .ai_speed = 3000,
- .dachan = 0,
- .dabits = 0,
- },
- {.name = "dt3003",
- .device_id = 0x24,
- .adchan = 64,
- .adbits = 12,
- .adrange = &range_dt3000_ai,
- .ai_speed = 3000,
- .dachan = 2,
- .dabits = 12,
- },
- {.name = "dt3003-pgl",
- .device_id = 0x28,
- .adchan = 64,
- .adbits = 12,
- .adrange = &range_dt3000_ai_pgl,
- .ai_speed = 3000,
- .dachan = 2,
- .dabits = 12,
- },
- {.name = "dt3004",
- .device_id = 0x25,
- .adchan = 16,
- .adbits = 16,
- .adrange = &range_dt3000_ai,
- .ai_speed = 10000,
- .dachan = 2,
- .dabits = 12,
- },
- {.name = "dt3005", /* a.k.a. 3004-200 */
- .device_id = 0x26,
- .adchan = 16,
- .adbits = 16,
- .adrange = &range_dt3000_ai,
- .ai_speed = 5000,
- .dachan = 2,
- .dabits = 12,
- },
+ {
+ .name = "dt3001",
+ .device_id = PCI_DEVICE_ID_DT3001,
+ .adchan = 16,
+ .adbits = 12,
+ .adrange = &range_dt3000_ai,
+ .ai_speed = 3000,
+ .dachan = 2,
+ .dabits = 12,
+ }, {
+ .name = "dt3001-pgl",
+ .device_id = PCI_DEVICE_ID_DT3001_PGL,
+ .adchan = 16,
+ .adbits = 12,
+ .adrange = &range_dt3000_ai_pgl,
+ .ai_speed = 3000,
+ .dachan = 2,
+ .dabits = 12,
+ }, {
+ .name = "dt3002",
+ .device_id = PCI_DEVICE_ID_DT3002,
+ .adchan = 32,
+ .adbits = 12,
+ .adrange = &range_dt3000_ai,
+ .ai_speed = 3000,
+ }, {
+ .name = "dt3003",
+ .device_id = PCI_DEVICE_ID_DT3003,
+ .adchan = 64,
+ .adbits = 12,
+ .adrange = &range_dt3000_ai,
+ .ai_speed = 3000,
+ .dachan = 2,
+ .dabits = 12,
+ }, {
+ .name = "dt3003-pgl",
+ .device_id = PCI_DEVICE_ID_DT3003_PGL,
+ .adchan = 64,
+ .adbits = 12,
+ .adrange = &range_dt3000_ai_pgl,
+ .ai_speed = 3000,
+ .dachan = 2,
+ .dabits = 12,
+ }, {
+ .name = "dt3004",
+ .device_id = PCI_DEVICE_ID_DT3004,
+ .adchan = 16,
+ .adbits = 16,
+ .adrange = &range_dt3000_ai,
+ .ai_speed = 10000,
+ .dachan = 2,
+ .dabits = 12,
+ }, {
+ .name = "dt3005", /* a.k.a. 3004-200 */
+ .device_id = PCI_DEVICE_ID_DT3005,
+ .adchan = 16,
+ .adbits = 16,
+ .adrange = &range_dt3000_ai,
+ .ai_speed = 5000,
+ .dachan = 2,
+ .dabits = 12,
+ },
};
-#define this_board ((const struct dt3k_boardtype *)dev->board_ptr)
-
#define DT3000_SIZE (4*0x1000)
/* dual-ported RAM location definitions */
@@ -257,22 +260,29 @@ struct dt3k_private {
unsigned int ai_rear;
};
-#define devpriv ((struct dt3k_private *)dev->private)
-
-static void dt3k_ai_empty_fifo(struct comedi_device *dev,
- struct comedi_subdevice *s);
-static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *arg,
- unsigned int round_mode);
-static int dt3k_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s);
#ifdef DEBUG
-static void debug_intr_flags(unsigned int flags);
+static char *intr_flags[] = {
+ "AdFull", "AdSwError", "AdHwError", "DaEmpty",
+ "DaSwError", "DaHwError", "CtDone", "CmDone",
+};
+
+static void debug_intr_flags(unsigned int flags)
+{
+ int i;
+ printk(KERN_DEBUG "dt3k: intr_flags:");
+ for (i = 0; i < 8; i++) {
+ if (flags & (1 << i))
+ printk(KERN_CONT " %s", intr_flags[i]);
+ }
+ printk(KERN_CONT "\n");
+}
#endif
#define TIMEOUT 100
-static int dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd)
+static void dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd)
{
+ struct dt3k_private *devpriv = dev->private;
int i;
unsigned int status = 0;
@@ -284,19 +294,18 @@ static int dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd)
break;
udelay(1);
}
- if ((status & DT3000_COMPLETION_MASK) == DT3000_NOERROR)
- return 0;
-
- dev_dbg(dev->class_dev, "dt3k_send_cmd() timeout/error status=0x%04x\n",
- status);
- return -ETIME;
+ if ((status & DT3000_COMPLETION_MASK) != DT3000_NOERROR)
+ dev_dbg(dev->class_dev, "%s: timeout/error status=0x%04x\n",
+ __func__, status);
}
static unsigned int dt3k_readsingle(struct comedi_device *dev,
unsigned int subsys, unsigned int chan,
unsigned int gain)
{
+ struct dt3k_private *devpriv = dev->private;
+
writew(subsys, devpriv->io_addr + DPR_SubSys);
writew(chan, devpriv->io_addr + DPR_Params(0));
@@ -310,6 +319,8 @@ static unsigned int dt3k_readsingle(struct comedi_device *dev,
static void dt3k_writesingle(struct comedi_device *dev, unsigned int subsys,
unsigned int chan, unsigned int data)
{
+ struct dt3k_private *devpriv = dev->private;
+
writew(subsys, devpriv->io_addr + DPR_SubSys);
writew(chan, devpriv->io_addr + DPR_Params(0));
@@ -319,6 +330,47 @@ static void dt3k_writesingle(struct comedi_device *dev, unsigned int subsys,
dt3k_send_cmd(dev, CMD_WRITESINGLE);
}
+static void dt3k_ai_empty_fifo(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct dt3k_private *devpriv = dev->private;
+ int front;
+ int rear;
+ int count;
+ int i;
+ short data;
+
+ front = readw(devpriv->io_addr + DPR_AD_Buf_Front);
+ count = front - devpriv->ai_front;
+ if (count < 0)
+ count += AI_FIFO_DEPTH;
+
+ rear = devpriv->ai_rear;
+
+ for (i = 0; i < count; i++) {
+ data = readw(devpriv->io_addr + DPR_ADC_buffer + rear);
+ comedi_buf_put(s->async, data);
+ rear++;
+ if (rear >= AI_FIFO_DEPTH)
+ rear = 0;
+ }
+
+ devpriv->ai_rear = rear;
+ writew(rear, devpriv->io_addr + DPR_AD_Buf_Rear);
+}
+
+static int dt3k_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ struct dt3k_private *devpriv = dev->private;
+
+ writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+ dt3k_send_cmd(dev, CMD_STOP);
+
+ writew(0, devpriv->io_addr + DPR_Int_Mask);
+
+ return 0;
+}
+
static int debug_n_ints;
/* FIXME! Assumes shared interrupt is for this card. */
@@ -326,6 +378,7 @@ static int debug_n_ints;
static irqreturn_t dt3k_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct dt3k_private *devpriv = dev->private;
struct comedi_subdevice *s;
unsigned int status;
@@ -356,57 +409,45 @@ static irqreturn_t dt3k_interrupt(int irq, void *d)
return IRQ_HANDLED;
}
-#ifdef DEBUG
-static char *intr_flags[] = {
- "AdFull", "AdSwError", "AdHwError", "DaEmpty",
- "DaSwError", "DaHwError", "CtDone", "CmDone",
-};
-
-static void debug_intr_flags(unsigned int flags)
-{
- int i;
- printk(KERN_DEBUG "dt3k: intr_flags:");
- for (i = 0; i < 8; i++) {
- if (flags & (1 << i))
- printk(KERN_CONT " %s", intr_flags[i]);
- }
- printk(KERN_CONT "\n");
-}
-#endif
-
-static void dt3k_ai_empty_fifo(struct comedi_device *dev,
- struct comedi_subdevice *s)
+static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
+ unsigned int round_mode)
{
- int front;
- int rear;
- int count;
- int i;
- short data;
-
- front = readw(devpriv->io_addr + DPR_AD_Buf_Front);
- count = front - devpriv->ai_front;
- if (count < 0)
- count += AI_FIFO_DEPTH;
-
- dev_dbg(dev->class_dev, "reading %d samples\n", count);
+ int divider, base, prescale;
- rear = devpriv->ai_rear;
+ /* This function needs improvment */
+ /* Don't know if divider==0 works. */
- for (i = 0; i < count; i++) {
- data = readw(devpriv->io_addr + DPR_ADC_buffer + rear);
- comedi_buf_put(s->async, data);
- rear++;
- if (rear >= AI_FIFO_DEPTH)
- rear = 0;
+ for (prescale = 0; prescale < 16; prescale++) {
+ base = timer_base * (prescale + 1);
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ divider = (*nanosec + base / 2) / base;
+ break;
+ case TRIG_ROUND_DOWN:
+ divider = (*nanosec) / base;
+ break;
+ case TRIG_ROUND_UP:
+ divider = (*nanosec) / base;
+ break;
+ }
+ if (divider < 65536) {
+ *nanosec = divider * base;
+ return (prescale << 16) | (divider);
+ }
}
- devpriv->ai_rear = rear;
- writew(rear, devpriv->io_addr + DPR_AD_Buf_Rear);
+ prescale = 15;
+ base = timer_base * (1 << prescale);
+ divider = 65535;
+ *nanosec = divider * base;
+ return (prescale << 16) | (divider);
}
static int dt3k_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
+ const struct dt3k_boardtype *this_board = comedi_board(dev);
int err = 0;
int tmp;
@@ -427,54 +468,30 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->scan_begin_arg < this_board->ai_speed) {
- cmd->scan_begin_arg = this_board->ai_speed;
- err++;
- }
- if (cmd->scan_begin_arg > 100 * 16 * 65535) {
- cmd->scan_begin_arg = 100 * 16 * 65535;
- err++;
- }
- } else {
- /* not supported */
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ this_board->ai_speed);
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
+ 100 * 16 * 65535);
}
+
if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < this_board->ai_speed) {
- cmd->convert_arg = this_board->ai_speed;
- err++;
- }
- if (cmd->convert_arg > 50 * 16 * 65535) {
- cmd->convert_arg = 50 * 16 * 65535;
- err++;
- }
- } else {
- /* not supported */
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ this_board->ai_speed);
+ err |= cfc_check_trigger_arg_max(&cmd->convert_arg,
+ 50 * 16 * 65535);
}
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) {
- if (cmd->stop_arg > 0x00ffffff) {
- cmd->stop_arg = 0x00ffffff;
- err++;
- }
- } else {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -487,9 +504,8 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev,
cmd->flags & TRIG_ROUND_MASK);
if (tmp != cmd->scan_begin_arg)
err++;
- } else {
- /* not supported */
}
+
if (cmd->convert_src == TRIG_TIMER) {
tmp = cmd->convert_arg;
dt3k_ns_to_timer(50, &cmd->convert_arg,
@@ -503,8 +519,6 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev,
cmd->convert_arg * cmd->scan_end_arg;
err++;
}
- } else {
- /* not supported */
}
if (err)
@@ -513,52 +527,16 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev,
return 0;
}
-static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
- unsigned int round_mode)
-{
- int divider, base, prescale;
-
- /* This function needs improvment */
- /* Don't know if divider==0 works. */
-
- for (prescale = 0; prescale < 16; prescale++) {
- base = timer_base * (prescale + 1);
- switch (round_mode) {
- case TRIG_ROUND_NEAREST:
- default:
- divider = (*nanosec + base / 2) / base;
- break;
- case TRIG_ROUND_DOWN:
- divider = (*nanosec) / base;
- break;
- case TRIG_ROUND_UP:
- divider = (*nanosec) / base;
- break;
- }
- if (divider < 65536) {
- *nanosec = divider * base;
- return (prescale << 16) | (divider);
- }
- }
-
- prescale = 15;
- base = timer_base * (1 << prescale);
- divider = 65535;
- *nanosec = divider * base;
- return (prescale << 16) | (divider);
-}
-
static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct dt3k_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
int i;
unsigned int chan, range, aref;
unsigned int divider;
unsigned int tscandiv;
- int ret;
unsigned int mode;
- dev_dbg(dev->class_dev, "dt3k_ai_cmd:\n");
for (i = 0; i < cmd->chanlist_len; i++) {
chan = CR_CHAN(cmd->chanlist[i]);
range = CR_RANGE(cmd->chanlist[i]);
@@ -569,41 +547,29 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
aref = CR_AREF(cmd->chanlist[0]);
writew(cmd->scan_end_arg, devpriv->io_addr + DPR_Params(0));
- dev_dbg(dev->class_dev, "param[0]=0x%04x\n", cmd->scan_end_arg);
if (cmd->convert_src == TRIG_TIMER) {
divider = dt3k_ns_to_timer(50, &cmd->convert_arg,
cmd->flags & TRIG_ROUND_MASK);
writew((divider >> 16), devpriv->io_addr + DPR_Params(1));
- dev_dbg(dev->class_dev, "param[1]=0x%04x\n", divider >> 16);
writew((divider & 0xffff), devpriv->io_addr + DPR_Params(2));
- dev_dbg(dev->class_dev, "param[2]=0x%04x\n", divider & 0xffff);
- } else {
- /* not supported */
}
if (cmd->scan_begin_src == TRIG_TIMER) {
tscandiv = dt3k_ns_to_timer(100, &cmd->scan_begin_arg,
cmd->flags & TRIG_ROUND_MASK);
writew((tscandiv >> 16), devpriv->io_addr + DPR_Params(3));
- dev_dbg(dev->class_dev, "param[3]=0x%04x\n", tscandiv >> 16);
writew((tscandiv & 0xffff), devpriv->io_addr + DPR_Params(4));
- dev_dbg(dev->class_dev, "param[4]=0x%04x\n", tscandiv & 0xffff);
- } else {
- /* not supported */
}
mode = DT3000_AD_RETRIG_INTERNAL | 0 | 0;
writew(mode, devpriv->io_addr + DPR_Params(5));
- dev_dbg(dev->class_dev, "param[5]=0x%04x\n", mode);
writew(aref == AREF_DIFF, devpriv->io_addr + DPR_Params(6));
- dev_dbg(dev->class_dev, "param[6]=0x%04x\n", aref == AREF_DIFF);
writew(AI_FIFO_DEPTH / 2, devpriv->io_addr + DPR_Params(7));
- dev_dbg(dev->class_dev, "param[7]=0x%04x\n", AI_FIFO_DEPTH / 2);
writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
- ret = dt3k_send_cmd(dev, CMD_CONFIG);
+ dt3k_send_cmd(dev, CMD_CONFIG);
writew(DT3000_ADFULL | DT3000_ADSWERR | DT3000_ADHWERR,
devpriv->io_addr + DPR_Int_Mask);
@@ -611,19 +577,7 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
debug_n_ints = 0;
writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
- ret = dt3k_send_cmd(dev, CMD_START);
-
- return 0;
-}
-
-static int dt3k_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- int ret;
-
- writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
- ret = dt3k_send_cmd(dev, CMD_STOP);
-
- writew(0, devpriv->io_addr + DPR_Int_Mask);
+ dt3k_send_cmd(dev, CMD_START);
return 0;
}
@@ -648,6 +602,7 @@ static int dt3k_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
static int dt3k_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct dt3k_private *devpriv = dev->private;
int i;
unsigned int chan;
@@ -664,6 +619,7 @@ static int dt3k_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct dt3k_private *devpriv = dev->private;
int i;
unsigned int chan;
@@ -676,6 +632,8 @@ static int dt3k_ao_insn_read(struct comedi_device *dev,
static void dt3k_dio_config(struct comedi_device *dev, int bits)
{
+ struct dt3k_private *devpriv = dev->private;
+
/* XXX */
writew(SUBS_DOUT, devpriv->io_addr + DPR_SubSys);
@@ -739,6 +697,7 @@ static int dt3k_mem_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct dt3k_private *devpriv = dev->private;
unsigned int addr = CR_CHAN(insn->chanspec);
int i;
@@ -755,54 +714,42 @@ static int dt3k_mem_insn_read(struct comedi_device *dev,
return i;
}
-static struct pci_dev *dt3000_find_pci_dev(struct comedi_device *dev,
- struct comedi_devconfig *it)
+static const void *dt3000_find_boardinfo(struct comedi_device *dev,
+ struct pci_dev *pcidev)
{
- struct pci_dev *pcidev = NULL;
- int bus = it->options[0];
- int slot = it->options[1];
+ const struct dt3k_boardtype *this_board;
int i;
- for_each_pci_dev(pcidev) {
- if (bus || slot) {
- if (bus != pcidev->bus->number ||
- slot != PCI_SLOT(pcidev->devfn))
- continue;
- }
- if (pcidev->vendor != PCI_VENDOR_ID_DT)
- continue;
- for (i = 0; i < ARRAY_SIZE(dt3k_boardtypes); i++) {
- if (dt3k_boardtypes[i].device_id != pcidev->device)
- continue;
- dev->board_ptr = dt3k_boardtypes + i;
- return pcidev;
- }
+ for (i = 0; i < ARRAY_SIZE(dt3k_boardtypes); i++) {
+ this_board = &dt3k_boardtypes[i];
+ if (this_board->device_id == pcidev->device)
+ return this_board;
}
- dev_err(dev->class_dev,
- "No supported board found! (req. bus %d, slot %d)\n",
- bus, slot);
return NULL;
}
-static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int dt3000_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
- struct pci_dev *pcidev;
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ const struct dt3k_boardtype *this_board;
+ struct dt3k_private *devpriv;
struct comedi_subdevice *s;
resource_size_t pci_base;
int ret = 0;
- dev_dbg(dev->class_dev, "dt3000:\n");
-
- ret = alloc_private(dev, sizeof(struct dt3k_private));
- if (ret < 0)
- return ret;
+ this_board = dt3000_find_boardinfo(dev, pcidev);
+ if (!this_board)
+ return -ENODEV;
+ dev->board_ptr = this_board;
+ dev->board_name = this_board->name;
- pcidev = dt3000_find_pci_dev(dev, it);
- if (!pcidev)
- return -EIO;
- comedi_set_hw_dev(dev, &pcidev->dev);
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, "dt3000");
+ ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret < 0)
return ret;
dev->iobase = 1; /* the "detach" needs this */
@@ -812,14 +759,10 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (!devpriv->io_addr)
return -ENOMEM;
- dev->board_name = this_board->name;
-
- if (request_irq(pcidev->irq, dt3k_interrupt, IRQF_SHARED,
- "dt3000", dev)) {
- dev_err(dev->class_dev, "unable to allocate IRQ %u\n",
- pcidev->irq);
- return -EINVAL;
- }
+ ret = request_irq(pcidev->irq, dt3k_interrupt, IRQF_SHARED,
+ dev->board_name, dev);
+ if (ret)
+ return ret;
dev->irq = pcidev->irq;
ret = comedi_alloc_subdevices(dev, 4);
@@ -828,50 +771,49 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s = &dev->subdevices[0];
dev->read_subdev = s;
-
/* ai subdevice */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
- s->n_chan = this_board->adchan;
- s->insn_read = dt3k_ai_insn;
- s->maxdata = (1 << this_board->adbits) - 1;
- s->len_chanlist = 512;
- s->range_table = &range_dt3000_ai; /* XXX */
- s->do_cmd = dt3k_ai_cmd;
- s->do_cmdtest = dt3k_ai_cmdtest;
- s->cancel = dt3k_ai_cancel;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+ s->n_chan = this_board->adchan;
+ s->insn_read = dt3k_ai_insn;
+ s->maxdata = (1 << this_board->adbits) - 1;
+ s->len_chanlist = 512;
+ s->range_table = &range_dt3000_ai; /* XXX */
+ s->do_cmd = dt3k_ai_cmd;
+ s->do_cmdtest = dt3k_ai_cmdtest;
+ s->cancel = dt3k_ai_cancel;
s = &dev->subdevices[1];
/* ao subsystem */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->insn_read = dt3k_ao_insn_read;
- s->insn_write = dt3k_ao_insn;
- s->maxdata = (1 << this_board->dabits) - 1;
- s->len_chanlist = 1;
- s->range_table = &range_bipolar10;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->insn_read = dt3k_ao_insn_read;
+ s->insn_write = dt3k_ao_insn;
+ s->maxdata = (1 << this_board->dabits) - 1;
+ s->len_chanlist = 1;
+ s->range_table = &range_bipolar10;
s = &dev->subdevices[2];
/* dio subsystem */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 8;
- s->insn_config = dt3k_dio_insn_config;
- s->insn_bits = dt3k_dio_insn_bits;
- s->maxdata = 1;
- s->len_chanlist = 8;
- s->range_table = &range_digital;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->insn_config = dt3k_dio_insn_config;
+ s->insn_bits = dt3k_dio_insn_bits;
+ s->maxdata = 1;
+ s->len_chanlist = 8;
+ s->range_table = &range_digital;
s = &dev->subdevices[3];
/* mem subsystem */
- s->type = COMEDI_SUBD_MEMORY;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 0x1000;
- s->insn_read = dt3k_mem_insn_read;
- s->maxdata = 0xff;
- s->len_chanlist = 1;
- s->range_table = &range_unknown;
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 0x1000;
+ s->insn_read = dt3k_mem_insn_read;
+ s->maxdata = 0xff;
+ s->len_chanlist = 1;
+ s->range_table = &range_unknown;
#if 0
s = &dev->subdevices[4];
@@ -879,12 +821,15 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->type = COMEDI_SUBD_PROC;
#endif
+ dev_info(dev->class_dev, "%s attached\n", dev->board_name);
+
return 0;
}
static void dt3000_detach(struct comedi_device *dev)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct dt3k_private *devpriv = dev->private;
if (dev->irq)
free_irq(dev->irq, dev);
@@ -895,36 +840,35 @@ static void dt3000_detach(struct comedi_device *dev)
if (pcidev) {
if (dev->iobase)
comedi_pci_disable(pcidev);
- pci_dev_put(pcidev);
}
}
static struct comedi_driver dt3000_driver = {
.driver_name = "dt3000",
.module = THIS_MODULE,
- .attach = dt3000_attach,
+ .auto_attach = dt3000_auto_attach,
.detach = dt3000_detach,
};
-static int __devinit dt3000_pci_probe(struct pci_dev *dev,
+static int dt3000_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &dt3000_driver);
}
-static void __devexit dt3000_pci_remove(struct pci_dev *dev)
+static void dt3000_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
static DEFINE_PCI_DEVICE_TABLE(dt3000_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0022) },
- { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0027) },
- { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0023) },
- { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0024) },
- { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0028) },
- { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0025) },
- { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0026) },
+ { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3001) },
+ { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3001_PGL) },
+ { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3002) },
+ { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3003) },
+ { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3003_PGL) },
+ { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3004) },
+ { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3005) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, dt3000_pci_table);
@@ -933,7 +877,7 @@ static struct pci_driver dt3000_pci_driver = {
.name = "dt3000",
.id_table = dt3000_pci_table,
.probe = dt3000_pci_probe,
- .remove = __devexit_p(dt3000_pci_remove),
+ .remove = dt3000_pci_remove,
};
module_comedi_pci_driver(dt3000_driver, dt3000_pci_driver);
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index bc6f409b7e1..176799849d2 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -43,6 +43,8 @@ for my needs.
* says P1).
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
@@ -323,9 +325,6 @@ static const struct comedi_lrange dt9812_2pt5_aout_range = { 1, {
static struct slot_dt9812 dt9812[DT9812_NUM_SLOTS];
-/* Useful shorthand access to private data */
-#define devpriv ((struct comedi_dt9812 *)dev->private)
-
static inline struct usb_dt9812 *to_dt9812_dev(struct kref *d)
{
return container_of(d, struct usb_dt9812, kref);
@@ -893,6 +892,7 @@ static struct usb_driver dt9812_usb_driver = {
static int dt9812_comedi_open(struct comedi_device *dev)
{
+ struct comedi_dt9812 *devpriv = dev->private;
int result = -ENODEV;
down(&devpriv->slot->mutex);
@@ -947,6 +947,7 @@ static int dt9812_di_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
+ struct comedi_dt9812 *devpriv = dev->private;
int n;
u8 bits = 0;
@@ -960,6 +961,7 @@ static int dt9812_do_winsn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
+ struct comedi_dt9812 *devpriv = dev->private;
int n;
u8 bits = 0;
@@ -979,6 +981,7 @@ static int dt9812_ai_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
+ struct comedi_dt9812 *devpriv = dev->private;
int n;
for (n = 0; n < insn->n; n++) {
@@ -995,6 +998,7 @@ static int dt9812_ao_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
+ struct comedi_dt9812 *devpriv = dev->private;
int n;
u16 value;
@@ -1010,6 +1014,7 @@ static int dt9812_ao_winsn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
+ struct comedi_dt9812 *devpriv = dev->private;
int n;
for (n = 0; n < insn->n; n++)
@@ -1019,14 +1024,17 @@ static int dt9812_ao_winsn(struct comedi_device *dev,
static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ struct comedi_dt9812 *devpriv;
int i;
struct comedi_subdevice *s;
int ret;
dev->board_name = "dt9812";
- if (alloc_private(dev, sizeof(struct comedi_dt9812)) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
/*
* Special open routine, since USB unit may be unattached at
@@ -1077,8 +1085,7 @@ static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->insn_write = &dt9812_ao_winsn;
s->insn_read = &dt9812_ao_rinsn;
- printk(KERN_INFO "comedi%d: successfully attached to dt9812.\n",
- dev->minor);
+ dev_info(dev->class_dev, "successfully attached to dt9812.\n");
down(&dt9812_mutex);
/* Find a slot for the comedi device */
@@ -1140,17 +1147,15 @@ static int __init usb_dt9812_init(void)
/* register with the USB subsystem */
result = usb_register(&dt9812_usb_driver);
if (result) {
- printk(KERN_ERR KBUILD_MODNAME
- ": usb_register failed. Error number %d\n", result);
+ pr_err("usb_register failed. Error number %d\n", result);
return result;
}
/* register with comedi */
result = comedi_driver_register(&dt9812_comedi_driver);
if (result) {
usb_deregister(&dt9812_usb_driver);
- printk(KERN_ERR KBUILD_MODNAME
- ": comedi_driver_register failed. Error number %d\n",
- result);
+ pr_err("comedi_driver_register failed. Error number %d\n",
+ result);
}
return result;
diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c
index 6f612be1b0a..8497a36db7d 100644
--- a/drivers/staging/comedi/drivers/dyna_pci10xx.c
+++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c
@@ -40,8 +40,6 @@
#include "../comedidev.h"
#include <linux/mutex.h>
-#define PCI_VENDOR_ID_DYNALOG 0x10b5
-
#define READ_TIMEOUT 50
static const struct comedi_lrange range_pci1050_ai = { 3, {
@@ -179,21 +177,20 @@ static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev,
return insn->n;
}
-static int dyna_pci10xx_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int dyna_pci10xx_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct dyna_pci10xx_private *devpriv;
struct comedi_subdevice *s;
int ret;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
dev->board_name = dev->driver->driver_name;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret)
@@ -269,23 +266,23 @@ static void dyna_pci10xx_detach(struct comedi_device *dev)
static struct comedi_driver dyna_pci10xx_driver = {
.driver_name = "dyna_pci10xx",
.module = THIS_MODULE,
- .attach_pci = dyna_pci10xx_attach_pci,
+ .auto_attach = dyna_pci10xx_auto_attach,
.detach = dyna_pci10xx_detach,
};
-static int __devinit dyna_pci10xx_pci_probe(struct pci_dev *dev,
+static int dyna_pci10xx_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &dyna_pci10xx_driver);
}
-static void __devexit dyna_pci10xx_pci_remove(struct pci_dev *dev)
+static void dyna_pci10xx_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
static DEFINE_PCI_DEVICE_TABLE(dyna_pci10xx_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_DYNALOG, 0x1050) },
+ { PCI_DEVICE(PCI_VENDOR_ID_PLX, 0x1050) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, dyna_pci10xx_pci_table);
@@ -294,7 +291,7 @@ static struct pci_driver dyna_pci10xx_pci_driver = {
.name = "dyna_pci10xx",
.id_table = dyna_pci10xx_pci_table,
.probe = dyna_pci10xx_pci_probe,
- .remove = __devexit_p(dyna_pci10xx_pci_remove),
+ .remove = dyna_pci10xx_pci_remove,
};
module_comedi_pci_driver(dyna_pci10xx_driver, dyna_pci10xx_pci_driver);
diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c
index ae8e8f46029..019c96eda6f 100644
--- a/drivers/staging/comedi/drivers/fl512.c
+++ b/drivers/staging/comedi/drivers/fl512.c
@@ -29,8 +29,6 @@ struct fl512_private {
short ao_readback[2];
};
-#define devpriv ((struct fl512_private *) dev->private)
-
static const struct comedi_lrange range_fl512 = { 4, {
BIP_RANGE(0.5),
BIP_RANGE(1),
@@ -75,6 +73,7 @@ static int fl512_ao_insn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
+ struct fl512_private *devpriv = dev->private;
int n;
int chan = CR_CHAN(insn->chanspec); /* get chan to write */
unsigned long iobase = dev->iobase; /* get base address */
@@ -99,6 +98,7 @@ static int fl512_ao_insn_readback(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct fl512_private *devpriv = dev->private;
int n;
int chan = CR_CHAN(insn->chanspec);
@@ -110,6 +110,7 @@ static int fl512_ao_insn_readback(struct comedi_device *dev,
static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ struct fl512_private *devpriv;
unsigned long iobase;
int ret;
@@ -125,8 +126,11 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
dev->iobase = iobase;
dev->board_name = "fl512";
- if (alloc_private(dev, sizeof(struct fl512_private)) < 0)
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
#if DEBUG
printk(KERN_DEBUG "malloc ok\n");
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
index abff6603952..154598f6d5e 100644
--- a/drivers/staging/comedi/drivers/gsc_hpdi.c
+++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
@@ -26,24 +26,26 @@
************************************************************************/
/*
+ * Driver: gsc_hpdi
+ * Description: General Standards Corporation High
+ * Speed Parallel Digital Interface rs485 boards
+ * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+ * Status: only receive mode works, transmit not supported
+ * Updated: Thu, 01 Nov 2012 16:17:38 +0000
+ * Devices: [General Standards Corporation] PCI-HPDI32 (gsc_hpdi),
+ * PMC-HPDI32
+ *
+ * Configuration options:
+ * None.
+ *
+ * Manual configuration of supported devices is not supported; they are
+ * configured automatically.
+ *
+ * There are some additional hpdi models available from GSC for which
+ * support could be added to this driver.
+ */
-Driver: gsc_hpdi
-Description: General Standards Corporation High
- Speed Parallel Digital Interface rs485 boards
-Author: Frank Mori Hess <fmhess@users.sourceforge.net>
-Status: only receive mode works, transmit not supported
-Updated: 2003-02-20
-Devices: [General Standards Corporation] PCI-HPDI32 (gsc_hpdi),
- PMC-HPDI32
-
-Configuration options:
- [0] - PCI bus of device (optional)
- [1] - PCI slot of device (optional)
-
-There are some additional hpdi models available from GSC for which
-support could be added to this driver.
-
-*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/interrupt.h>
#include "../comedidev.h"
@@ -64,9 +66,9 @@ static int dio_config_block_size(struct comedi_device *dev, unsigned int *data);
/* #define HPDI_DEBUG enable debugging code */
#ifdef HPDI_DEBUG
-#define DEBUG_PRINT(format, args...) printk(format , ## args)
+#define DEBUG_PRINT(format, args...) pr_debug(format , ## args)
#else
-#define DEBUG_PRINT(format, args...)
+#define DEBUG_PRINT(format, args...) no_printk(pr_fmt(format), ## args)
#endif
#define TIMER_BASE 50 /* 20MHz master clock */
@@ -104,35 +106,11 @@ enum hpdi_registers {
INTERRUPT_POLARITY_REG = 0x54,
};
-int command_channel_valid(unsigned int channel)
-{
- if (channel == 0 || channel > 6) {
- printk(KERN_WARNING
- "gsc_hpdi: bug! invalid cable command channel\n");
- return 0;
- }
- return 1;
-}
-
/* bit definitions */
enum firmware_revision_bits {
FEATURES_REG_PRESENT_BIT = 0x8000,
};
-int firmware_revision(uint32_t fwr_bits)
-{
- return fwr_bits & 0xff;
-}
-
-int pcb_revision(uint32_t fwr_bits)
-{
- return (fwr_bits >> 8) & 0xff;
-}
-
-int hpdi_subid(uint32_t fwr_bits)
-{
- return (fwr_bits >> 16) & 0xff;
-}
enum board_control_bits {
BOARD_RESET_BIT = 0x1, /* wait 10usec before accessing fifos */
@@ -147,22 +125,6 @@ enum board_control_bits {
CABLE_THROTTLE_ENABLE_BIT = 0x20,
TEST_MODE_ENABLE_BIT = 0x80000000,
};
-uint32_t command_discrete_output_bits(unsigned int channel, int output,
- int output_value)
-{
- uint32_t bits = 0;
-
- if (command_channel_valid(channel) == 0)
- return 0;
- if (output) {
- bits |= 0x1 << (16 + channel);
- if (output_value)
- bits |= 0x1 << (24 + channel);
- } else
- bits |= 0x1 << (24 + channel);
-
- return bits;
-}
enum board_status_bits {
COMMAND_LINE_STATUS_MASK = 0x7f,
@@ -182,28 +144,17 @@ enum board_status_bits {
RX_OVERRUN_BIT = 0x800000,
};
-uint32_t almost_full_bits(unsigned int num_words)
+static uint32_t almost_full_bits(unsigned int num_words)
{
-/* XXX need to add or subtract one? */
+ /* XXX need to add or subtract one? */
return (num_words << 16) & 0xff0000;
}
-uint32_t almost_empty_bits(unsigned int num_words)
+static uint32_t almost_empty_bits(unsigned int num_words)
{
return num_words & 0xffff;
}
-unsigned int almost_full_num_words(uint32_t bits)
-{
-/* XXX need to add or subtract one? */
- return (bits >> 16) & 0xffff;
-}
-
-unsigned int almost_empty_num_words(uint32_t bits)
-{
- return bits & 0xffff;
-}
-
enum features_bits {
FIFO_SIZE_PRESENT_BIT = 0x1,
FIFO_WORDS_PRESENT_BIT = 0x2,
@@ -225,46 +176,19 @@ enum interrupt_sources {
RX_ALMOST_FULL_INTR = 14,
RX_FULL_INTR = 15,
};
-int command_intr_source(unsigned int channel)
-{
- if (command_channel_valid(channel) == 0)
- channel = 1;
- return channel + 1;
-}
-uint32_t intr_bit(int interrupt_source)
+static uint32_t intr_bit(int interrupt_source)
{
return 0x1 << interrupt_source;
}
-uint32_t tx_clock_divisor_bits(unsigned int divisor)
-{
- return divisor & 0xff;
-}
-
-unsigned int fifo_size(uint32_t fifo_size_bits)
+static unsigned int fifo_size(uint32_t fifo_size_bits)
{
return fifo_size_bits & 0xfffff;
}
-unsigned int fifo_words(uint32_t fifo_words_bits)
-{
- return fifo_words_bits & 0xfffff;
-}
-
-uint32_t intr_edge_bit(int interrupt_source)
-{
- return 0x1 << interrupt_source;
-}
-
-uint32_t intr_active_high_bit(int interrupt_source)
-{
- return 0x1 << interrupt_source;
-}
-
struct hpdi_board {
-
- char *name;
+ const char *name; /* board name */
int device_id; /* pci device id */
int subdevice_id; /* pci subdevice id */
};
@@ -284,17 +208,7 @@ static const struct hpdi_board hpdi_boards[] = {
#endif
};
-static inline struct hpdi_board *board(const struct comedi_device *dev)
-{
- return (struct hpdi_board *)dev->board_ptr;
-}
-
struct hpdi_private {
-
- struct pci_dev *hw_dev; /* pointer to board's pci_dev struct */
- /* base addresses (physical) */
- resource_size_t plx9080_phys_iobase;
- resource_size_t hpdi_phys_iobase;
/* base addresses (ioremapped) */
void __iomem *plx9080_iobase;
void __iomem *hpdi_iobase;
@@ -321,27 +235,24 @@ struct hpdi_private {
unsigned dio_config_output:1;
};
-static inline struct hpdi_private *priv(struct comedi_device *dev)
-{
- return dev->private;
-}
-
static int dio_config_insn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
+ struct hpdi_private *devpriv = dev->private;
+
switch (data[0]) {
case INSN_CONFIG_DIO_OUTPUT:
- priv(dev)->dio_config_output = 1;
+ devpriv->dio_config_output = 1;
return insn->n;
break;
case INSN_CONFIG_DIO_INPUT:
- priv(dev)->dio_config_output = 0;
+ devpriv->dio_config_output = 0;
return insn->n;
break;
case INSN_CONFIG_DIO_QUERY:
data[1] =
- priv(dev)->dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT;
+ devpriv->dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
break;
case INSN_CONFIG_BLOCK_SIZE:
@@ -356,21 +267,24 @@ static int dio_config_insn(struct comedi_device *dev,
static void disable_plx_interrupts(struct comedi_device *dev)
{
- writel(0, priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+ struct hpdi_private *devpriv = dev->private;
+
+ writel(0, devpriv->plx9080_iobase + PLX_INTRCS_REG);
}
/* initialize plx9080 chip */
static void init_plx9080(struct comedi_device *dev)
{
+ struct hpdi_private *devpriv = dev->private;
uint32_t bits;
- void __iomem *plx_iobase = priv(dev)->plx9080_iobase;
+ void __iomem *plx_iobase = devpriv->plx9080_iobase;
/* plx9080 dump */
DEBUG_PRINT(" plx interrupt status 0x%x\n",
readl(plx_iobase + PLX_INTRCS_REG));
DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG));
DEBUG_PRINT(" plx control reg 0x%x\n",
- readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG));
+ readl(devpriv->plx9080_iobase + PLX_CONTROL_REG));
DEBUG_PRINT(" plx revision 0x%x\n",
readl(plx_iobase + PLX_REVISION_REG));
@@ -396,7 +310,7 @@ static void init_plx9080(struct comedi_device *dev)
#else
bits = 0;
#endif
- writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG);
+ writel(bits, devpriv->plx9080_iobase + PLX_BIGEND_REG);
disable_plx_interrupts(dev);
@@ -457,28 +371,29 @@ static int setup_subdevices(struct comedi_device *dev)
static int init_hpdi(struct comedi_device *dev)
{
+ struct hpdi_private *devpriv = dev->private;
uint32_t plx_intcsr_bits;
- writel(BOARD_RESET_BIT, priv(dev)->hpdi_iobase + BOARD_CONTROL_REG);
+ writel(BOARD_RESET_BIT, devpriv->hpdi_iobase + BOARD_CONTROL_REG);
udelay(10);
writel(almost_empty_bits(32) | almost_full_bits(32),
- priv(dev)->hpdi_iobase + RX_PROG_ALMOST_REG);
+ devpriv->hpdi_iobase + RX_PROG_ALMOST_REG);
writel(almost_empty_bits(32) | almost_full_bits(32),
- priv(dev)->hpdi_iobase + TX_PROG_ALMOST_REG);
+ devpriv->hpdi_iobase + TX_PROG_ALMOST_REG);
- priv(dev)->tx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
+ devpriv->tx_fifo_size = fifo_size(readl(devpriv->hpdi_iobase +
TX_FIFO_SIZE_REG));
- priv(dev)->rx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
+ devpriv->rx_fifo_size = fifo_size(readl(devpriv->hpdi_iobase +
RX_FIFO_SIZE_REG));
- writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
+ writel(0, devpriv->hpdi_iobase + INTERRUPT_CONTROL_REG);
/* enable interrupts */
plx_intcsr_bits =
ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
ICS_DMA0_E;
- writel(plx_intcsr_bits, priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+ writel(plx_intcsr_bits, devpriv->plx9080_iobase + PLX_INTRCS_REG);
return 0;
}
@@ -487,6 +402,7 @@ static int init_hpdi(struct comedi_device *dev)
static int setup_dma_descriptors(struct comedi_device *dev,
unsigned int transfer_size)
{
+ struct hpdi_private *devpriv = dev->private;
unsigned int buffer_index, buffer_offset;
uint32_t next_bits = PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
PLX_XFER_LOCAL_TO_PCI;
@@ -500,25 +416,25 @@ static int setup_dma_descriptors(struct comedi_device *dev,
DEBUG_PRINT(" transfer_size %i\n", transfer_size);
DEBUG_PRINT(" descriptors at 0x%lx\n",
- (unsigned long)priv(dev)->dma_desc_phys_addr);
+ (unsigned long)devpriv->dma_desc_phys_addr);
buffer_offset = 0;
buffer_index = 0;
for (i = 0; i < NUM_DMA_DESCRIPTORS &&
buffer_index < NUM_DMA_BUFFERS; i++) {
- priv(dev)->dma_desc[i].pci_start_addr =
- cpu_to_le32(priv(dev)->dio_buffer_phys_addr[buffer_index] +
+ devpriv->dma_desc[i].pci_start_addr =
+ cpu_to_le32(devpriv->dio_buffer_phys_addr[buffer_index] +
buffer_offset);
- priv(dev)->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG);
- priv(dev)->dma_desc[i].transfer_size =
+ devpriv->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG);
+ devpriv->dma_desc[i].transfer_size =
cpu_to_le32(transfer_size);
- priv(dev)->dma_desc[i].next =
- cpu_to_le32((priv(dev)->dma_desc_phys_addr + (i +
+ devpriv->dma_desc[i].next =
+ cpu_to_le32((devpriv->dma_desc_phys_addr + (i +
1) *
- sizeof(priv(dev)->dma_desc[0])) | next_bits);
+ sizeof(devpriv->dma_desc[0])) | next_bits);
- priv(dev)->desc_dio_buffer[i] =
- priv(dev)->dio_buffer[buffer_index] +
+ devpriv->desc_dio_buffer[i] =
+ devpriv->dio_buffer[buffer_index] +
(buffer_offset / sizeof(uint32_t));
buffer_offset += transfer_size;
@@ -529,128 +445,110 @@ static int setup_dma_descriptors(struct comedi_device *dev,
DEBUG_PRINT(" desc %i\n", i);
DEBUG_PRINT(" start addr virt 0x%p, phys 0x%lx\n",
- priv(dev)->desc_dio_buffer[i],
- (unsigned long)priv(dev)->dma_desc[i].
+ devpriv->desc_dio_buffer[i],
+ (unsigned long)devpriv->dma_desc[i].
pci_start_addr);
DEBUG_PRINT(" next 0x%lx\n",
- (unsigned long)priv(dev)->dma_desc[i].next);
+ (unsigned long)devpriv->dma_desc[i].next);
}
- priv(dev)->num_dma_descriptors = i;
+ devpriv->num_dma_descriptors = i;
/* fix last descriptor to point back to first */
- priv(dev)->dma_desc[i - 1].next =
- cpu_to_le32(priv(dev)->dma_desc_phys_addr | next_bits);
+ devpriv->dma_desc[i - 1].next =
+ cpu_to_le32(devpriv->dma_desc_phys_addr | next_bits);
DEBUG_PRINT(" desc %i next fixup 0x%lx\n", i - 1,
- (unsigned long)priv(dev)->dma_desc[i - 1].next);
+ (unsigned long)devpriv->dma_desc[i - 1].next);
- priv(dev)->block_size = transfer_size;
+ devpriv->block_size = transfer_size;
return transfer_size;
}
-static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static const struct hpdi_board *hpdi_find_board(struct pci_dev *pcidev)
{
- struct pci_dev *pcidev;
- int i;
- int retval;
+ unsigned int i;
- printk(KERN_WARNING "comedi%d: gsc_hpdi\n", dev->minor);
+ for (i = 0; i < ARRAY_SIZE(hpdi_boards); i++)
+ if (pcidev->device == hpdi_boards[i].device_id &&
+ pcidev->subsystem_device == hpdi_boards[i].subdevice_id)
+ return &hpdi_boards[i];
+ return NULL;
+}
- if (alloc_private(dev, sizeof(struct hpdi_private)) < 0)
- return -ENOMEM;
+static int hpdi_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ const struct hpdi_board *thisboard;
+ struct hpdi_private *devpriv;
+ int i;
+ int retval;
- pcidev = NULL;
- for (i = 0; i < ARRAY_SIZE(hpdi_boards) &&
- dev->board_ptr == NULL; i++) {
- do {
- pcidev = pci_get_subsys(PCI_VENDOR_ID_PLX,
- hpdi_boards[i].device_id,
- PCI_VENDOR_ID_PLX,
- hpdi_boards[i].subdevice_id,
- pcidev);
- /* was a particular bus/slot requested? */
- if (it->options[0] || it->options[1]) {
- /* are we on the wrong bus/slot? */
- if (pcidev->bus->number != it->options[0] ||
- PCI_SLOT(pcidev->devfn) != it->options[1])
- continue;
- }
- if (pcidev) {
- priv(dev)->hw_dev = pcidev;
- dev->board_ptr = hpdi_boards + i;
- break;
- }
- } while (pcidev != NULL);
- }
- if (dev->board_ptr == NULL) {
- printk(KERN_WARNING "gsc_hpdi: no hpdi card found\n");
- return -EIO;
+ thisboard = hpdi_find_board(pcidev);
+ if (!thisboard) {
+ dev_err(dev->class_dev, "gsc_hpdi: pci %s not supported\n",
+ pci_name(pcidev));
+ return -EINVAL;
}
+ dev->board_ptr = thisboard;
+ dev->board_name = thisboard->name;
- printk(KERN_WARNING
- "gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name,
- pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
- if (comedi_pci_enable(pcidev, dev->driver->driver_name)) {
- printk(KERN_WARNING
- " failed enable PCI device and request regions\n");
+ if (comedi_pci_enable(pcidev, dev->board_name)) {
+ dev_warn(dev->class_dev,
+ "failed enable PCI device and request regions\n");
return -EIO;
}
+ dev->iobase = 1; /* the "detach" needs this */
pci_set_master(pcidev);
- /* Initialize dev->board_name */
- dev->board_name = board(dev)->name;
-
- priv(dev)->plx9080_phys_iobase =
- pci_resource_start(pcidev, PLX9080_BADDRINDEX);
- priv(dev)->hpdi_phys_iobase =
- pci_resource_start(pcidev, HPDI_BADDRINDEX);
-
- /* remap, won't work with 2.0 kernels but who cares */
- priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase,
- pci_resource_len(pcidev,
- PLX9080_BADDRINDEX));
- priv(dev)->hpdi_iobase =
- ioremap(priv(dev)->hpdi_phys_iobase,
- pci_resource_len(pcidev, HPDI_BADDRINDEX));
- if (!priv(dev)->plx9080_iobase || !priv(dev)->hpdi_iobase) {
- printk(KERN_WARNING " failed to remap io memory\n");
+ devpriv->plx9080_iobase =
+ ioremap(pci_resource_start(pcidev, PLX9080_BADDRINDEX),
+ pci_resource_len(pcidev, PLX9080_BADDRINDEX));
+ devpriv->hpdi_iobase =
+ ioremap(pci_resource_start(pcidev, HPDI_BADDRINDEX),
+ pci_resource_len(pcidev, HPDI_BADDRINDEX));
+ if (!devpriv->plx9080_iobase || !devpriv->hpdi_iobase) {
+ dev_warn(dev->class_dev, "failed to remap io memory\n");
return -ENOMEM;
}
- DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase);
- DEBUG_PRINT(" hpdi remapped to 0x%p\n", priv(dev)->hpdi_iobase);
+ DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase);
+ DEBUG_PRINT(" hpdi remapped to 0x%p\n", devpriv->hpdi_iobase);
init_plx9080(dev);
/* get irq */
if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
- dev->driver->driver_name, dev)) {
- printk(KERN_WARNING
- " unable to allocate irq %u\n", pcidev->irq);
+ dev->board_name, dev)) {
+ dev_warn(dev->class_dev,
+ "unable to allocate irq %u\n", pcidev->irq);
return -EINVAL;
}
dev->irq = pcidev->irq;
- printk(KERN_WARNING " irq %u\n", dev->irq);
+ dev_dbg(dev->class_dev, " irq %u\n", dev->irq);
/* allocate pci dma buffers */
for (i = 0; i < NUM_DMA_BUFFERS; i++) {
- priv(dev)->dio_buffer[i] =
- pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE,
- &priv(dev)->dio_buffer_phys_addr[i]);
+ devpriv->dio_buffer[i] =
+ pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE,
+ &devpriv->dio_buffer_phys_addr[i]);
DEBUG_PRINT("dio_buffer at virt 0x%p, phys 0x%lx\n",
- priv(dev)->dio_buffer[i],
- (unsigned long)priv(dev)->dio_buffer_phys_addr[i]);
+ devpriv->dio_buffer[i],
+ (unsigned long)devpriv->dio_buffer_phys_addr[i]);
}
/* allocate dma descriptors */
- priv(dev)->dma_desc = pci_alloc_consistent(priv(dev)->hw_dev,
- sizeof(struct plx_dma_desc) *
- NUM_DMA_DESCRIPTORS,
- &priv(dev)->
- dma_desc_phys_addr);
- if (priv(dev)->dma_desc_phys_addr & 0xf) {
- printk(KERN_WARNING
- " dma descriptors not quad-word aligned (bug)\n");
+ devpriv->dma_desc = pci_alloc_consistent(pcidev,
+ sizeof(struct plx_dma_desc) *
+ NUM_DMA_DESCRIPTORS,
+ &devpriv->dma_desc_phys_addr);
+ if (devpriv->dma_desc_phys_addr & 0xf) {
+ dev_warn(dev->class_dev,
+ " dma descriptors not quad-word aligned (bug)\n");
return -EIO;
}
@@ -667,39 +565,37 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
static void hpdi_detach(struct comedi_device *dev)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct hpdi_private *devpriv = dev->private;
unsigned int i;
if (dev->irq)
free_irq(dev->irq, dev);
- if ((priv(dev)) && (priv(dev)->hw_dev)) {
- if (priv(dev)->plx9080_iobase) {
+ if (devpriv) {
+ if (devpriv->plx9080_iobase) {
disable_plx_interrupts(dev);
- iounmap(priv(dev)->plx9080_iobase);
+ iounmap(devpriv->plx9080_iobase);
}
- if (priv(dev)->hpdi_iobase)
- iounmap(priv(dev)->hpdi_iobase);
+ if (devpriv->hpdi_iobase)
+ iounmap(devpriv->hpdi_iobase);
/* free pci dma buffers */
for (i = 0; i < NUM_DMA_BUFFERS; i++) {
- if (priv(dev)->dio_buffer[i])
- pci_free_consistent(priv(dev)->hw_dev,
+ if (devpriv->dio_buffer[i])
+ pci_free_consistent(pcidev,
DMA_BUFFER_SIZE,
- priv(dev)->
- dio_buffer[i],
- priv
- (dev)->dio_buffer_phys_addr
- [i]);
+ devpriv->dio_buffer[i],
+ devpriv->
+ dio_buffer_phys_addr[i]);
}
/* free dma descriptors */
- if (priv(dev)->dma_desc)
- pci_free_consistent(priv(dev)->hw_dev,
- sizeof(struct plx_dma_desc)
- * NUM_DMA_DESCRIPTORS,
- priv(dev)->dma_desc,
- priv(dev)->
- dma_desc_phys_addr);
- if (priv(dev)->hpdi_phys_iobase)
- comedi_pci_disable(priv(dev)->hw_dev);
- pci_dev_put(priv(dev)->hw_dev);
+ if (devpriv->dma_desc)
+ pci_free_consistent(pcidev,
+ sizeof(struct plx_dma_desc) *
+ NUM_DMA_DESCRIPTORS,
+ devpriv->dma_desc,
+ devpriv->dma_desc_phys_addr);
+ if (dev->iobase)
+ comedi_pci_disable(pcidev);
}
}
@@ -745,29 +641,20 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
if (!cmd->chanlist_len) {
cmd->chanlist_len = 32;
- err++;
- }
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
+ err |= -EINVAL;
}
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
switch (cmd->stop_src) {
case TRIG_COUNT:
- if (!cmd->stop_arg) {
- cmd->stop_arg = 1;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
break;
case TRIG_NONE:
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
break;
default:
break;
@@ -803,7 +690,9 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
- if (priv(dev)->dio_config_output)
+ struct hpdi_private *devpriv = dev->private;
+
+ if (devpriv->dio_config_output)
return -EINVAL;
else
return di_cmd_test(dev, s, cmd);
@@ -812,12 +701,15 @@ static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
static inline void hpdi_writel(struct comedi_device *dev, uint32_t bits,
unsigned int offset)
{
- writel(bits | priv(dev)->bits[offset / sizeof(uint32_t)],
- priv(dev)->hpdi_iobase + offset);
+ struct hpdi_private *devpriv = dev->private;
+
+ writel(bits | devpriv->bits[offset / sizeof(uint32_t)],
+ devpriv->hpdi_iobase + offset);
}
static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct hpdi_private *devpriv = dev->private;
uint32_t bits;
unsigned long flags;
struct comedi_async *async = s->async;
@@ -829,39 +721,39 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
abort_dma(dev, 0);
- priv(dev)->dma_desc_index = 0;
+ devpriv->dma_desc_index = 0;
/* These register are supposedly unused during chained dma,
* but I have found that left over values from last operation
* occasionally cause problems with transfer of first dma
* block. Initializing them to zero seems to fix the problem. */
- writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
- writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
- writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
+ writel(0, devpriv->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
+ writel(0, devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
+ writel(0, devpriv->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
/* give location of first dma descriptor */
bits =
- priv(dev)->dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT |
+ devpriv->dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT |
PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI;
- writel(bits, priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
+ writel(bits, devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
/* spinlock for plx dma control/status reg */
spin_lock_irqsave(&dev->spinlock, flags);
/* enable dma transfer */
writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT,
- priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
spin_unlock_irqrestore(&dev->spinlock, flags);
if (cmd->stop_src == TRIG_COUNT)
- priv(dev)->dio_count = cmd->stop_arg;
+ devpriv->dio_count = cmd->stop_arg;
else
- priv(dev)->dio_count = 1;
+ devpriv->dio_count = 1;
/* clear over/under run status flags */
writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT,
- priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
+ devpriv->hpdi_iobase + BOARD_STATUS_REG);
/* enable interrupts */
writel(intr_bit(RX_FULL_INTR),
- priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
+ devpriv->hpdi_iobase + INTERRUPT_CONTROL_REG);
DEBUG_PRINT("hpdi: starting rx\n");
hpdi_writel(dev, RX_ENABLE_BIT, BOARD_CONTROL_REG);
@@ -871,7 +763,9 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- if (priv(dev)->dio_config_output)
+ struct hpdi_private *devpriv = dev->private;
+
+ if (devpriv->dio_config_output)
return -EINVAL;
else
return di_cmd(dev, s);
@@ -879,6 +773,7 @@ static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
{
+ struct hpdi_private *devpriv = dev->private;
struct comedi_async *async = dev->read_subdev->async;
uint32_t next_transfer_addr;
int j;
@@ -887,37 +782,37 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
if (channel)
pci_addr_reg =
- priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
+ devpriv->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
else
pci_addr_reg =
- priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
+ devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
/* loop until we have read all the full buffers */
j = 0;
for (next_transfer_addr = readl(pci_addr_reg);
(next_transfer_addr <
- le32_to_cpu(priv(dev)->dma_desc[priv(dev)->dma_desc_index].
+ le32_to_cpu(devpriv->dma_desc[devpriv->dma_desc_index].
pci_start_addr)
|| next_transfer_addr >=
- le32_to_cpu(priv(dev)->dma_desc[priv(dev)->dma_desc_index].
- pci_start_addr) + priv(dev)->block_size)
- && j < priv(dev)->num_dma_descriptors; j++) {
+ le32_to_cpu(devpriv->dma_desc[devpriv->dma_desc_index].
+ pci_start_addr) + devpriv->block_size)
+ && j < devpriv->num_dma_descriptors; j++) {
/* transfer data from dma buffer to comedi buffer */
- num_samples = priv(dev)->block_size / sizeof(uint32_t);
+ num_samples = devpriv->block_size / sizeof(uint32_t);
if (async->cmd.stop_src == TRIG_COUNT) {
- if (num_samples > priv(dev)->dio_count)
- num_samples = priv(dev)->dio_count;
- priv(dev)->dio_count -= num_samples;
+ if (num_samples > devpriv->dio_count)
+ num_samples = devpriv->dio_count;
+ devpriv->dio_count -= num_samples;
}
cfc_write_array_to_buffer(dev->read_subdev,
- priv(dev)->desc_dio_buffer[priv(dev)->
+ devpriv->desc_dio_buffer[devpriv->
dma_desc_index],
num_samples * sizeof(uint32_t));
- priv(dev)->dma_desc_index++;
- priv(dev)->dma_desc_index %= priv(dev)->num_dma_descriptors;
+ devpriv->dma_desc_index++;
+ devpriv->dma_desc_index %= devpriv->num_dma_descriptors;
DEBUG_PRINT("next desc addr 0x%lx\n", (unsigned long)
- priv(dev)->dma_desc[priv(dev)->dma_desc_index].
+ devpriv->dma_desc[devpriv->dma_desc_index].
next);
DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr);
}
@@ -927,6 +822,7 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
static irqreturn_t handle_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct hpdi_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async = s->async;
uint32_t hpdi_intr_status, hpdi_board_status;
@@ -938,26 +834,26 @@ static irqreturn_t handle_interrupt(int irq, void *d)
if (!dev->attached)
return IRQ_NONE;
- plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+ plx_status = readl(devpriv->plx9080_iobase + PLX_INTRCS_REG);
if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0)
return IRQ_NONE;
- hpdi_intr_status = readl(priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
- hpdi_board_status = readl(priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
+ hpdi_intr_status = readl(devpriv->hpdi_iobase + INTERRUPT_STATUS_REG);
+ hpdi_board_status = readl(devpriv->hpdi_iobase + BOARD_STATUS_REG);
async->events = 0;
if (hpdi_intr_status) {
DEBUG_PRINT("hpdi: intr status 0x%x, ", hpdi_intr_status);
writel(hpdi_intr_status,
- priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
+ devpriv->hpdi_iobase + INTERRUPT_STATUS_REG);
}
/* spin lock makes sure no one else changes plx dma control reg */
spin_lock_irqsave(&dev->spinlock, flags);
- dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ dma0_status = readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
if (plx_status & ICS_DMA0_A) { /* dma chan 0 interrupt */
writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
- priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
if (dma0_status & PLX_DMA_EN_BIT)
@@ -968,10 +864,10 @@ static irqreturn_t handle_interrupt(int irq, void *d)
/* spin lock makes sure no one else changes plx dma control reg */
spin_lock_irqsave(&dev->spinlock, flags);
- dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ dma1_status = readb(devpriv->plx9080_iobase + PLX_DMA1_CS_REG);
if (plx_status & ICS_DMA1_A) { /* XXX *//* dma chan 1 interrupt */
writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
- priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ devpriv->plx9080_iobase + PLX_DMA1_CS_REG);
DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
DEBUG_PRINT(" cleared dma ch1 interrupt\n");
@@ -980,8 +876,8 @@ static irqreturn_t handle_interrupt(int irq, void *d)
/* clear possible plx9080 interrupt sources */
if (plx_status & ICS_LDIA) { /* clear local doorbell interrupt */
- plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
- writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
+ plx_bits = readl(devpriv->plx9080_iobase + PLX_DBR_OUT_REG);
+ writel(plx_bits, devpriv->plx9080_iobase + PLX_DBR_OUT_REG);
DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits);
}
@@ -989,7 +885,7 @@ static irqreturn_t handle_interrupt(int irq, void *d)
comedi_error(dev, "rx fifo overrun");
async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
DEBUG_PRINT("dma0_status 0x%x\n",
- (int)readb(priv(dev)->plx9080_iobase +
+ (int)readb(devpriv->plx9080_iobase +
PLX_DMA0_CS_REG));
}
@@ -998,7 +894,7 @@ static irqreturn_t handle_interrupt(int irq, void *d)
async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
}
- if (priv(dev)->dio_count == 0)
+ if (devpriv->dio_count == 0)
async->events |= COMEDI_CB_EOA;
DEBUG_PRINT("board status 0x%x, ", hpdi_board_status);
@@ -1013,21 +909,24 @@ static irqreturn_t handle_interrupt(int irq, void *d)
static void abort_dma(struct comedi_device *dev, unsigned int channel)
{
+ struct hpdi_private *devpriv = dev->private;
unsigned long flags;
/* spinlock for plx dma control/status reg */
spin_lock_irqsave(&dev->spinlock, flags);
- plx9080_abort_dma(priv(dev)->plx9080_iobase, channel);
+ plx9080_abort_dma(devpriv->plx9080_iobase, channel);
spin_unlock_irqrestore(&dev->spinlock, flags);
}
static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct hpdi_private *devpriv = dev->private;
+
hpdi_writel(dev, 0, BOARD_CONTROL_REG);
- writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
+ writel(0, devpriv->hpdi_iobase + INTERRUPT_CONTROL_REG);
abort_dma(dev, 0);
@@ -1037,17 +936,17 @@ static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
static struct comedi_driver gsc_hpdi_driver = {
.driver_name = "gsc_hpdi",
.module = THIS_MODULE,
- .attach = hpdi_attach,
+ .auto_attach = hpdi_auto_attach,
.detach = hpdi_detach,
};
-static int __devinit gsc_hpdi_pci_probe(struct pci_dev *dev,
+static int gsc_hpdi_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &gsc_hpdi_driver);
}
-static void __devexit gsc_hpdi_pci_remove(struct pci_dev *dev)
+static void gsc_hpdi_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -1063,7 +962,7 @@ static struct pci_driver gsc_hpdi_pci_driver = {
.name = "gsc_hpdi",
.id_table = gsc_hpdi_pci_table,
.probe = gsc_hpdi_pci_probe,
- .remove = __devexit_p(gsc_hpdi_pci_remove)
+ .remove = gsc_hpdi_pci_remove
};
module_comedi_pci_driver(gsc_hpdi_driver, gsc_hpdi_pci_driver);
diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c
index d696d4d51e2..a91a448ba0f 100644
--- a/drivers/staging/comedi/drivers/icp_multi.c
+++ b/drivers/staging/comedi/drivers/icp_multi.c
@@ -494,21 +494,21 @@ static int icp_multi_reset(struct comedi_device *dev)
return 0;
}
-static int icp_multi_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int icp_multi_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct icp_multi_private *devpriv;
struct comedi_subdevice *s;
resource_size_t iobase;
int ret;
- comedi_set_hw_dev(dev, &pcidev->dev);
dev->board_name = dev->driver->driver_name;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret < 0)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret)
@@ -613,17 +613,17 @@ static void icp_multi_detach(struct comedi_device *dev)
static struct comedi_driver icp_multi_driver = {
.driver_name = "icp_multi",
.module = THIS_MODULE,
- .attach_pci = icp_multi_attach_pci,
+ .auto_attach = icp_multi_auto_attach,
.detach = icp_multi_detach,
};
-static int __devinit icp_multi_pci_probe(struct pci_dev *dev,
+static int icp_multi_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &icp_multi_driver);
}
-static void __devexit icp_multi_pci_remove(struct pci_dev *dev)
+static void icp_multi_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -638,7 +638,7 @@ static struct pci_driver icp_multi_pci_driver = {
.name = "icp_multi",
.id_table = icp_multi_pci_table,
.probe = icp_multi_pci_probe,
- .remove = __devexit_p(icp_multi_pci_remove),
+ .remove = icp_multi_pci_remove,
};
module_comedi_pci_driver(icp_multi_driver, icp_multi_pci_driver);
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
index 65ff1c9b973..93584e2be35 100644
--- a/drivers/staging/comedi/drivers/ii_pci20kc.c
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -156,7 +156,6 @@ struct pci20xxx_private {
union pci20xxx_subdev_private subdev_private[PCI20000_MODULES];
};
-#define devpriv ((struct pci20xxx_private *)dev->private)
#define CHAN (CR_CHAN(it->chanlist[0]))
static int pci20006_init(struct comedi_device *dev, struct comedi_subdevice *s,
@@ -196,6 +195,7 @@ static int pci20xxx_dio_init(struct comedi_device *dev,
static int pci20xxx_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
+ struct pci20xxx_private *devpriv;
unsigned char i;
int ret;
int id;
@@ -206,22 +206,23 @@ static int pci20xxx_attach(struct comedi_device *dev,
if (ret)
return ret;
- ret = alloc_private(dev, sizeof(struct pci20xxx_private));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
devpriv->ioaddr = (void __iomem *)(unsigned long)it->options[0];
dev->board_name = "pci20kc";
/* Check PCI-20001 C-2A Carrier Board ID */
if ((readb(devpriv->ioaddr) & PCI20000_ID) != PCI20000_ID) {
- printk(KERN_WARNING "comedi%d: ii_pci20kc PCI-20001"
- " C-2A Carrier Board at base=0x%p not found !\n",
- dev->minor, devpriv->ioaddr);
+ dev_warn(dev->class_dev,
+ "PCI-20001 C-2A Carrier Board at base=0x%p not found !\n",
+ devpriv->ioaddr);
return -EINVAL;
}
- printk(KERN_INFO "comedi%d: ii_pci20kc: PCI-20001 C-2A at base=0x%p\n",
- dev->minor, devpriv->ioaddr);
+ dev_info(dev->class_dev, "PCI-20001 C-2A at base=0x%p\n",
+ devpriv->ioaddr);
for (i = 0; i < PCI20000_MODULES; i++) {
s = &dev->subdevices[i];
@@ -234,23 +235,21 @@ static int pci20xxx_attach(struct comedi_device *dev,
devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
pci20006_init(dev, s, it->options[2 * i + 2],
it->options[2 * i + 3]);
- printk(KERN_INFO "comedi%d: "
- "ii_pci20kc PCI-20006 module in slot %d\n",
- dev->minor, i + 1);
+ dev_info(dev->class_dev,
+ "PCI-20006 module in slot %d\n", i + 1);
break;
case PCI20341_ID:
sdp->pci20341.iobase =
devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
pci20341_init(dev, s, it->options[2 * i + 2],
it->options[2 * i + 3]);
- printk(KERN_INFO "comedi%d: "
- "ii_pci20kc PCI-20341 module in slot %d\n",
- dev->minor, i + 1);
+ dev_info(dev->class_dev,
+ "PCI-20341 module in slot %d\n", i + 1);
break;
default:
- printk(KERN_WARNING "ii_pci20kc: unknown module "
- "code 0x%02x in slot %d: module disabled\n",
- id, i); /* XXX this looks like a bug! i + 1 ?? */
+ dev_warn(dev->class_dev,
+ "unknown module code 0x%02x in slot %d: module disabled\n",
+ id, i); /* XXX this looks like a bug! i + 1 ?? */
/* fall through */
case PCI20xxx_EMPTY_ID:
s->type = COMEDI_SUBD_UNUSED;
@@ -346,8 +345,7 @@ static int pci20006_insn_write(struct comedi_device *dev,
writeb(0x00, sdp->iobase + PCI20006_STROBE1);
break;
default:
- printk(KERN_WARNING
- " comedi%d: pci20xxx: ao channel Error!\n", dev->minor);
+ dev_warn(dev->class_dev, "ao channel Error!\n");
return -EINVAL;
}
@@ -462,10 +460,8 @@ static int pci20341_insn_read(struct comedi_device *dev,
eoc = readb(sdp->iobase + PCI20341_STATUS_REG);
}
if (j >= 100) {
- printk(KERN_WARNING
- "comedi%d: pci20xxx: "
- "AI interrupt channel %i polling exit !\n",
- dev->minor, i);
+ dev_warn(dev->class_dev,
+ "AI interrupt channel %i polling exit !\n", i);
return -EINVAL;
}
lo = readb(sdp->iobase + PCI20341_LDATA);
@@ -541,6 +537,7 @@ static int pci20xxx_dio_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pci20xxx_private *devpriv = dev->private;
unsigned int mask = data[0];
s->state &= ~mask;
@@ -571,6 +568,7 @@ static int pci20xxx_dio_insn_bits(struct comedi_device *dev,
static void pci20xxx_dio_config(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct pci20xxx_private *devpriv = dev->private;
unsigned char control_01;
unsigned char control_23;
unsigned char buffer;
@@ -627,6 +625,8 @@ static void pci20xxx_dio_config(struct comedi_device *dev,
#if 0
static void pci20xxx_do(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct pci20xxx_private *devpriv = dev->private;
+
/* XXX if the channel is configured for input, does this
do bad things? */
/* XXX it would be a good idea to only update the registers
@@ -641,9 +641,10 @@ static void pci20xxx_do(struct comedi_device *dev, struct comedi_subdevice *s)
static unsigned int pci20xxx_di(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- /* XXX same note as above */
+ struct pci20xxx_private *devpriv = dev->private;
unsigned int bits;
+ /* XXX same note as above */
bits = readb(devpriv->ioaddr + PCI20000_DIO_0);
bits |= readb(devpriv->ioaddr + PCI20000_DIO_1) << 8;
bits |= readb(devpriv->ioaddr + PCI20000_DIO_2) << 16;
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
index 4a108ea8a9a..c756a35ce31 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.c
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -21,24 +21,26 @@
*/
/*
-Driver: jr3_pci
-Description: JR3/PCI force sensor board
-Author: Anders Blomdell <anders.blomdell@control.lth.se>
-Status: works
-Devices: [JR3] PCI force sensor board (jr3_pci)
-
- The DSP on the board requires initialization code, which can
- be loaded by placing it in /lib/firmware/comedi.
- The initialization code should be somewhere on the media you got
- with your card. One version is available from http://www.comedi.org
- in the comedi_nonfree_firmware tarball.
-
- Configuration options:
- [0] - PCI bus number - if bus number and slot number are 0,
- then driver search for first unused card
- [1] - PCI slot number
-
-*/
+ * Driver: jr3_pci
+ * Description: JR3/PCI force sensor board
+ * Author: Anders Blomdell <anders.blomdell@control.lth.se>
+ * Updated: Thu, 01 Nov 2012 17:34:55 +0000
+ * Status: works
+ * Devices: [JR3] PCI force sensor board (jr3_pci)
+ *
+ * Configuration options:
+ * None
+ *
+ * Manual configuration of comedi devices is not supported by this
+ * driver; supported PCI devices are configured as comedi devices
+ * automatically.
+ *
+ * The DSP on the board requires initialization code, which can be
+ * loaded by placing it in /lib/firmware/comedi. The initialization
+ * code should be somewhere on the media you got with your card. One
+ * version is available from http://www.comedi.org in the
+ * comedi_nonfree_firmware tarball. The file is called "jr3pci.idm".
+ */
#include "../comedidev.h"
@@ -59,22 +61,18 @@ Devices: [JR3] PCI force sensor board (jr3_pci)
#define PCI_DEVICE_ID_JR3_4_CHANNEL 0x3114
struct jr3_pci_dev_private {
-
- struct pci_dev *pci_dev;
- int pci_enabled;
- volatile struct jr3_t *iobase;
+ struct jr3_t __iomem *iobase;
int n_channels;
struct timer_list timer;
};
struct poll_delay_t {
-
int min;
int max;
};
struct jr3_pci_subdev_private {
- volatile struct jr3_channel *channel;
+ struct jr3_channel __iomem *channel;
unsigned long next_time_min;
unsigned long next_time_max;
enum { state_jr3_poll,
@@ -98,15 +96,15 @@ struct jr3_pci_subdev_private {
};
/* Hotplug firmware loading stuff */
-static int comedi_load_firmware(struct comedi_device *dev, char *name,
+static int comedi_load_firmware(struct comedi_device *dev, const char *name,
int (*cb)(struct comedi_device *dev,
const u8 *data, size_t size))
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
int result = 0;
const struct firmware *fw;
char *firmware_path;
static const char *prefix = "comedi/";
- struct jr3_pci_dev_private *devpriv = dev->private;
firmware_path = kmalloc(strlen(prefix) + strlen(name) + 1, GFP_KERNEL);
if (!firmware_path) {
@@ -115,8 +113,7 @@ static int comedi_load_firmware(struct comedi_device *dev, char *name,
firmware_path[0] = '\0';
strcat(firmware_path, prefix);
strcat(firmware_path, name);
- result = request_firmware(&fw, firmware_path,
- &devpriv->pci_dev->dev);
+ result = request_firmware(&fw, firmware_path, &pcidev->dev);
if (result == 0) {
if (!cb)
result = -EINVAL;
@@ -138,7 +135,7 @@ static struct poll_delay_t poll_delay_min_max(int min, int max)
return result;
}
-static int is_complete(volatile struct jr3_channel *channel)
+static int is_complete(struct jr3_channel __iomem *channel)
{
return get_s16(&channel->command_word0) == 0;
}
@@ -150,14 +147,13 @@ struct transform_t {
} link[8];
};
-static void set_transforms(volatile struct jr3_channel *channel,
+static void set_transforms(struct jr3_channel __iomem *channel,
struct transform_t transf, short num)
{
int i;
num &= 0x000f; /* Make sure that 0 <= num <= 15 */
for (i = 0; i < 8; i++) {
-
set_u16(&channel->transforms[num].link[i].link_type,
transf.link[i].link_type);
udelay(1);
@@ -169,18 +165,18 @@ static void set_transforms(volatile struct jr3_channel *channel,
}
}
-static void use_transform(volatile struct jr3_channel *channel,
+static void use_transform(struct jr3_channel __iomem *channel,
short transf_num)
{
set_s16(&channel->command_word0, 0x0500 + (transf_num & 0x000f));
}
-static void use_offset(volatile struct jr3_channel *channel, short offset_num)
+static void use_offset(struct jr3_channel __iomem *channel, short offset_num)
{
set_s16(&channel->command_word0, 0x0600 + (offset_num & 0x000f));
}
-static void set_offset(volatile struct jr3_channel *channel)
+static void set_offset(struct jr3_channel __iomem *channel)
{
set_s16(&channel->command_word0, 0x0700);
}
@@ -194,13 +190,9 @@ struct six_axis_t {
s16 mz;
};
-static void set_full_scales(volatile struct jr3_channel *channel,
+static void set_full_scales(struct jr3_channel __iomem *channel,
struct six_axis_t full_scale)
{
- printk("%d %d %d %d %d %d\n",
- full_scale.fx,
- full_scale.fy,
- full_scale.fz, full_scale.mx, full_scale.my, full_scale.mz);
set_s16(&channel->full_scale.fx, full_scale.fx);
set_s16(&channel->full_scale.fy, full_scale.fy);
set_s16(&channel->full_scale.fz, full_scale.fz);
@@ -210,7 +202,7 @@ static void set_full_scales(volatile struct jr3_channel *channel,
set_s16(&channel->command_word0, 0x0a00);
}
-static struct six_axis_t get_min_full_scales(volatile struct jr3_channel
+static struct six_axis_t get_min_full_scales(struct jr3_channel __iomem
*channel)
{
struct six_axis_t result;
@@ -223,7 +215,7 @@ static struct six_axis_t get_min_full_scales(volatile struct jr3_channel
return result;
}
-static struct six_axis_t get_max_full_scales(volatile struct jr3_channel
+static struct six_axis_t get_max_full_scales(struct jr3_channel __iomem
*channel)
{
struct six_axis_t result;
@@ -273,71 +265,53 @@ static int jr3_pci_ai_insn_read(struct comedi_device *dev,
} else {
int F = 0;
switch (axis) {
- case 0:{
- F = get_s16
- (&p->channel->filter
- [filter].fx);
- }
+ case 0:
+ F = get_s16(&p->channel->
+ filter[filter].fx);
break;
- case 1:{
- F = get_s16
- (&p->channel->filter
- [filter].fy);
- }
+ case 1:
+ F = get_s16(&p->channel->
+ filter[filter].fy);
break;
- case 2:{
- F = get_s16
- (&p->channel->filter
- [filter].fz);
- }
+ case 2:
+ F = get_s16(&p->channel->
+ filter[filter].fz);
break;
- case 3:{
- F = get_s16
- (&p->channel->filter
- [filter].mx);
- }
+ case 3:
+ F = get_s16(&p->channel->
+ filter[filter].mx);
break;
- case 4:{
- F = get_s16
- (&p->channel->filter
- [filter].my);
- }
+ case 4:
+ F = get_s16(&p->channel->
+ filter[filter].my);
break;
- case 5:{
- F = get_s16
- (&p->channel->filter
- [filter].mz);
- }
+ case 5:
+ F = get_s16(&p->channel->
+ filter[filter].mz);
break;
- case 6:{
- F = get_s16
- (&p->channel->filter
- [filter].v1);
- }
+ case 6:
+ F = get_s16(&p->channel->
+ filter[filter].v1);
break;
- case 7:{
- F = get_s16
- (&p->channel->filter
- [filter].v2);
- }
+ case 7:
+ F = get_s16(&p->channel->
+ filter[filter].v2);
break;
}
data[i] = F + 0x4000;
}
} else if (channel == 56) {
- if (p->state != state_jr3_done) {
+ if (p->state != state_jr3_done)
data[i] = 0;
- } else {
+ else
data[i] =
- get_u16(&p->channel->model_no);
- }
+ get_u16(&p->channel->model_no);
} else if (channel == 57) {
- if (p->state != state_jr3_done) {
+ if (p->state != state_jr3_done)
data[i] = 0;
- } else {
+ else
data[i] =
- get_u16(&p->channel->serial_no);
- }
+ get_u16(&p->channel->serial_no);
}
}
}
@@ -368,8 +342,8 @@ static int read_idm_word(const u8 *data, size_t size, int *pos,
int result = 0;
if (pos && val) {
/* Skip over non hex */
- for (; *pos < size && !isxdigit(data[*pos]); (*pos)++) {
- }
+ for (; *pos < size && !isxdigit(data[*pos]); (*pos)++)
+ ;
/* Collect value */
*val = 0;
for (; *pos < size; (*pos)++) {
@@ -378,14 +352,15 @@ static int read_idm_word(const u8 *data, size_t size, int *pos,
if (value >= 0) {
result = 1;
*val = (*val << 4) + value;
- } else
+ } else {
break;
+ }
}
}
return result;
}
-static int jr3_download_firmware(struct comedi_device *dev, const u8 * data,
+static int jr3_download_firmware(struct comedi_device *dev, const u8 *data,
size_t size)
{
/*
@@ -429,37 +404,38 @@ static int jr3_download_firmware(struct comedi_device *dev, const u8 * data,
pos = 0;
while (more) {
unsigned int count, addr;
- more = more
- && read_idm_word(data, size, &pos, &count);
+ more = more &&
+ read_idm_word(data, size, &pos, &count);
if (more && count == 0xffff)
break;
- more = more
- && read_idm_word(data, size, &pos, &addr);
+ more = more &&
+ read_idm_word(data, size, &pos, &addr);
dev_dbg(dev->class_dev,
"Loading#%d %4.4x bytes at %4.4x\n",
i, count, addr);
while (more && count > 0) {
if (addr & 0x4000) {
- /* 16 bit data, never seen in real life!! */
+ /* 16 bit data, never seen
+ * in real life!! */
unsigned int data1;
- more = more
- && read_idm_word(data,
+ more = more &&
+ read_idm_word(data,
size, &pos,
&data1);
count--;
- /* printk("jr3_data, not tested\n"); */
- /* jr3[addr + 0x20000 * pnum] = data1; */
+ /* jr3[addr + 0x20000 * pnum] =
+ data1; */
} else {
/* Download 24 bit program */
unsigned int data1, data2;
- more = more
- && read_idm_word(data,
+ more = more &&
+ read_idm_word(data,
size, &pos,
&data1);
- more = more
- && read_idm_word(data, size,
+ more = more &&
+ read_idm_word(data, size,
&pos,
&data2);
count -= 2;
@@ -474,7 +450,6 @@ static int jr3_download_firmware(struct comedi_device *dev, const u8 * data,
[i].program_high
[addr], data2);
udelay(1);
-
}
}
addr++;
@@ -492,213 +467,152 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
int i;
if (p) {
- volatile struct jr3_channel *channel = p->channel;
+ struct jr3_channel __iomem *channel = p->channel;
int errors = get_u16(&channel->errors);
- if (errors != p->errors) {
- printk("Errors: %x -> %x\n", p->errors, errors);
+ if (errors != p->errors)
p->errors = errors;
- }
- if (errors & (watch_dog | watch_dog2 | sensor_change)) {
+
+ if (errors & (watch_dog | watch_dog2 | sensor_change))
/* Sensor communication lost, force poll mode */
p->state = state_jr3_poll;
- }
switch (p->state) {
- case state_jr3_poll:{
+ case state_jr3_poll: {
u16 model_no = get_u16(&channel->model_no);
u16 serial_no = get_u16(&channel->serial_no);
if ((errors & (watch_dog | watch_dog2)) ||
model_no == 0 || serial_no == 0) {
-/*
- * Still no sensor, keep on polling. Since it takes up to 10 seconds
- * for offsets to stabilize, polling each second should suffice.
- */
+ /*
+ * Still no sensor, keep on polling.
+ * Since it takes up to 10 seconds
+ * for offsets to stabilize, polling
+ * each second should suffice.
+ */
result = poll_delay_min_max(1000, 2000);
} else {
p->retries = 0;
p->state =
- state_jr3_init_wait_for_offset;
+ state_jr3_init_wait_for_offset;
result = poll_delay_min_max(1000, 2000);
}
}
break;
- case state_jr3_init_wait_for_offset:{
- p->retries++;
- if (p->retries < 10) {
- /* Wait for offeset to stabilize (< 10 s according to manual) */
- result = poll_delay_min_max(1000, 2000);
- } else {
- struct transform_t transf;
-
- p->model_no =
- get_u16(&channel->model_no);
- p->serial_no =
- get_u16(&channel->serial_no);
-
- printk
- ("Setting transform for channel %d\n",
- p->channel_no);
- printk("Sensor Model = %i\n",
- p->model_no);
- printk("Sensor Serial = %i\n",
- p->serial_no);
-
- /* Transformation all zeros */
- for (i = 0; i < ARRAY_SIZE(transf.link); i++) {
- transf.link[i].link_type =
- (enum link_types)0;
- transf.link[i].link_amount = 0;
- }
-
- set_transforms(channel, transf, 0);
- use_transform(channel, 0);
- p->state =
- state_jr3_init_transform_complete;
- result = poll_delay_min_max(20, 100); /* Allow 20 ms for completion */
+ case state_jr3_init_wait_for_offset:
+ p->retries++;
+ if (p->retries < 10) {
+ /* Wait for offeset to stabilize
+ * (< 10 s according to manual) */
+ result = poll_delay_min_max(1000, 2000);
+ } else {
+ struct transform_t transf;
+
+ p->model_no = get_u16(&channel->model_no);
+ p->serial_no = get_u16(&channel->serial_no);
+
+ /* Transformation all zeros */
+ for (i = 0; i < ARRAY_SIZE(transf.link); i++) {
+ transf.link[i].link_type =
+ (enum link_types)0;
+ transf.link[i].link_amount = 0;
}
- } break;
- case state_jr3_init_transform_complete:{
- if (!is_complete(channel)) {
- printk
- ("state_jr3_init_transform_complete complete = %d\n",
- is_complete(channel));
- result = poll_delay_min_max(20, 100);
- } else {
- /* Set full scale */
- struct six_axis_t min_full_scale;
- struct six_axis_t max_full_scale;
-
- min_full_scale =
- get_min_full_scales(channel);
- printk("Obtained Min. Full Scales:\n");
- printk(KERN_DEBUG "%i ", (min_full_scale).fx);
- printk(KERN_CONT "%i ", (min_full_scale).fy);
- printk(KERN_CONT "%i ", (min_full_scale).fz);
- printk(KERN_CONT "%i ", (min_full_scale).mx);
- printk(KERN_CONT "%i ", (min_full_scale).my);
- printk(KERN_CONT "%i ", (min_full_scale).mz);
- printk(KERN_CONT "\n");
-
- max_full_scale =
- get_max_full_scales(channel);
- printk("Obtained Max. Full Scales:\n");
- printk(KERN_DEBUG "%i ", (max_full_scale).fx);
- printk(KERN_CONT "%i ", (max_full_scale).fy);
- printk(KERN_CONT "%i ", (max_full_scale).fz);
- printk(KERN_CONT "%i ", (max_full_scale).mx);
- printk(KERN_CONT "%i ", (max_full_scale).my);
- printk(KERN_CONT "%i ", (max_full_scale).mz);
- printk(KERN_CONT "\n");
-
- set_full_scales(channel,
- max_full_scale);
- p->state =
- state_jr3_init_set_full_scale_complete;
- result = poll_delay_min_max(20, 100); /* Allow 20 ms for completion */
- }
+ set_transforms(channel, transf, 0);
+ use_transform(channel, 0);
+ p->state = state_jr3_init_transform_complete;
+ /* Allow 20 ms for completion */
+ result = poll_delay_min_max(20, 100);
}
break;
- case state_jr3_init_set_full_scale_complete:{
- if (!is_complete(channel)) {
- printk
- ("state_jr3_init_set_full_scale_complete complete = %d\n",
- is_complete(channel));
- result = poll_delay_min_max(20, 100);
- } else {
- volatile struct force_array *full_scale;
-
- /* Use ranges in kN or we will overflow arount 2000N! */
- full_scale = &channel->full_scale;
- p->range[0].range.min =
- -get_s16(&full_scale->fx) * 1000;
- p->range[0].range.max =
- get_s16(&full_scale->fx) * 1000;
- p->range[1].range.min =
- -get_s16(&full_scale->fy) * 1000;
- p->range[1].range.max =
- get_s16(&full_scale->fy) * 1000;
- p->range[2].range.min =
- -get_s16(&full_scale->fz) * 1000;
- p->range[2].range.max =
- get_s16(&full_scale->fz) * 1000;
- p->range[3].range.min =
- -get_s16(&full_scale->mx) * 100;
- p->range[3].range.max =
- get_s16(&full_scale->mx) * 100;
- p->range[4].range.min =
- -get_s16(&full_scale->my) * 100;
- p->range[4].range.max =
- get_s16(&full_scale->my) * 100;
- p->range[5].range.min =
- -get_s16(&full_scale->mz) * 100;
- p->range[5].range.max =
- get_s16(&full_scale->mz) * 100;
- p->range[6].range.min = -get_s16(&full_scale->v1) * 100; /* ?? */
- p->range[6].range.max = get_s16(&full_scale->v1) * 100; /* ?? */
- p->range[7].range.min = -get_s16(&full_scale->v2) * 100; /* ?? */
- p->range[7].range.max = get_s16(&full_scale->v2) * 100; /* ?? */
- p->range[8].range.min = 0;
- p->range[8].range.max = 65535;
-
- {
- int i;
- for (i = 0; i < 9; i++) {
- printk("%d %d - %d\n",
- i,
- p->
- range[i].range.
- min,
- p->
- range[i].range.
- max);
- }
- }
-
- use_offset(channel, 0);
- p->state =
- state_jr3_init_use_offset_complete;
- result = poll_delay_min_max(40, 100); /* Allow 40 ms for completion */
- }
+ case state_jr3_init_transform_complete:
+ if (!is_complete(channel)) {
+ result = poll_delay_min_max(20, 100);
+ } else {
+ /* Set full scale */
+ struct six_axis_t min_full_scale;
+ struct six_axis_t max_full_scale;
+
+ min_full_scale = get_min_full_scales(channel);
+ max_full_scale = get_max_full_scales(channel);
+ set_full_scales(channel, max_full_scale);
+
+ p->state =
+ state_jr3_init_set_full_scale_complete;
+ /* Allow 20 ms for completion */
+ result = poll_delay_min_max(20, 100);
}
break;
- case state_jr3_init_use_offset_complete:{
- if (!is_complete(channel)) {
- printk
- ("state_jr3_init_use_offset_complete complete = %d\n",
- is_complete(channel));
- result = poll_delay_min_max(20, 100);
- } else {
- printk
- ("Default offsets %d %d %d %d %d %d\n",
- get_s16(&channel->offsets.fx),
- get_s16(&channel->offsets.fy),
- get_s16(&channel->offsets.fz),
- get_s16(&channel->offsets.mx),
- get_s16(&channel->offsets.my),
- get_s16(&channel->offsets.mz));
-
- set_s16(&channel->offsets.fx, 0);
- set_s16(&channel->offsets.fy, 0);
- set_s16(&channel->offsets.fz, 0);
- set_s16(&channel->offsets.mx, 0);
- set_s16(&channel->offsets.my, 0);
- set_s16(&channel->offsets.mz, 0);
-
- set_offset(channel);
-
- p->state = state_jr3_done;
- }
+ case state_jr3_init_set_full_scale_complete:
+ if (!is_complete(channel)) {
+ result = poll_delay_min_max(20, 100);
+ } else {
+ struct force_array __iomem *full_scale;
+
+ /* Use ranges in kN or we will
+ * overflow around 2000N! */
+ full_scale = &channel->full_scale;
+ p->range[0].range.min =
+ -get_s16(&full_scale->fx) * 1000;
+ p->range[0].range.max =
+ get_s16(&full_scale->fx) * 1000;
+ p->range[1].range.min =
+ -get_s16(&full_scale->fy) * 1000;
+ p->range[1].range.max =
+ get_s16(&full_scale->fy) * 1000;
+ p->range[2].range.min =
+ -get_s16(&full_scale->fz) * 1000;
+ p->range[2].range.max =
+ get_s16(&full_scale->fz) * 1000;
+ p->range[3].range.min =
+ -get_s16(&full_scale->mx) * 100;
+ p->range[3].range.max =
+ get_s16(&full_scale->mx) * 100;
+ p->range[4].range.min =
+ -get_s16(&full_scale->my) * 100;
+ p->range[4].range.max =
+ get_s16(&full_scale->my) * 100;
+ p->range[5].range.min =
+ -get_s16(&full_scale->mz) * 100;
+ p->range[5].range.max =
+ get_s16(&full_scale->mz) * 100; /* ?? */
+ p->range[6].range.min =
+ -get_s16(&full_scale->v1) * 100;/* ?? */
+ p->range[6].range.max =
+ get_s16(&full_scale->v1) * 100; /* ?? */
+ p->range[7].range.min =
+ -get_s16(&full_scale->v2) * 100;/* ?? */
+ p->range[7].range.max =
+ get_s16(&full_scale->v2) * 100; /* ?? */
+ p->range[8].range.min = 0;
+ p->range[8].range.max = 65535;
+
+ use_offset(channel, 0);
+ p->state = state_jr3_init_use_offset_complete;
+ /* Allow 40 ms for completion */
+ result = poll_delay_min_max(40, 100);
}
break;
- case state_jr3_done:{
- poll_delay_min_max(10000, 20000);
+ case state_jr3_init_use_offset_complete:
+ if (!is_complete(channel)) {
+ result = poll_delay_min_max(20, 100);
+ } else {
+ set_s16(&channel->offsets.fx, 0);
+ set_s16(&channel->offsets.fy, 0);
+ set_s16(&channel->offsets.fz, 0);
+ set_s16(&channel->offsets.mx, 0);
+ set_s16(&channel->offsets.my, 0);
+ set_s16(&channel->offsets.mz, 0);
+
+ set_offset(channel);
+
+ p->state = state_jr3_done;
}
break;
- default:{
- poll_delay_min_max(1000, 2000);
- }
+ case state_jr3_done:
+ poll_delay_min_max(10000, 20000);
+ break;
+ default:
+ poll_delay_min_max(1000, 2000);
break;
}
}
@@ -720,22 +634,21 @@ static void jr3_pci_poll_dev(unsigned long data)
/* Poll all channels that are ready to be polled */
for (i = 0; i < devpriv->n_channels; i++) {
struct jr3_pci_subdev_private *subdevpriv =
- dev->subdevices[i].private;
+ dev->subdevices[i].private;
if (now > subdevpriv->next_time_min) {
struct poll_delay_t sub_delay;
sub_delay = jr3_pci_poll_subdevice(&dev->subdevices[i]);
subdevpriv->next_time_min =
- jiffies + msecs_to_jiffies(sub_delay.min);
+ jiffies + msecs_to_jiffies(sub_delay.min);
subdevpriv->next_time_max =
- jiffies + msecs_to_jiffies(sub_delay.max);
- if (sub_delay.max && sub_delay.max < delay) {
-/*
-* Wake up as late as possible -> poll as many channels as possible
-* at once
-*/
+ jiffies + msecs_to_jiffies(sub_delay.max);
+ if (sub_delay.max && sub_delay.max < delay)
+ /*
+ * Wake up as late as possible ->
+ * poll as many channels as possible at once.
+ */
delay = sub_delay.max;
- }
}
}
spin_unlock_irqrestore(&dev->spinlock, flags);
@@ -744,17 +657,14 @@ static void jr3_pci_poll_dev(unsigned long data)
add_timer(&devpriv->timer);
}
-static int jr3_pci_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
+static int jr3_pci_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
- int result = 0;
- struct pci_dev *card = NULL;
- int opt_bus, opt_slot, i;
+ int result;
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ int i;
struct jr3_pci_dev_private *devpriv;
- opt_bus = it->options[0];
- opt_slot = it->options[1];
-
if (sizeof(struct jr3_channel) != 0xc00) {
dev_err(dev->class_dev,
"sizeof(struct jr3_channel) = %x [expected %x]\n",
@@ -762,70 +672,42 @@ static int jr3_pci_attach(struct comedi_device *dev,
return -EINVAL;
}
- result = alloc_private(dev, sizeof(struct jr3_pci_dev_private));
- if (result < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
- card = NULL;
- devpriv = dev->private;
+ dev->private = devpriv;
+
init_timer(&devpriv->timer);
- while (1) {
- card = pci_get_device(PCI_VENDOR_ID_JR3, PCI_ANY_ID, card);
- if (card == NULL) {
- /* No card found */
- break;
- } else {
- switch (card->device) {
- case PCI_DEVICE_ID_JR3_1_CHANNEL:{
- devpriv->n_channels = 1;
- }
- break;
- case PCI_DEVICE_ID_JR3_1_CHANNEL_NEW:{
- devpriv->n_channels = 1;
- }
- break;
- case PCI_DEVICE_ID_JR3_2_CHANNEL:{
- devpriv->n_channels = 2;
- }
- break;
- case PCI_DEVICE_ID_JR3_3_CHANNEL:{
- devpriv->n_channels = 3;
- }
- break;
- case PCI_DEVICE_ID_JR3_4_CHANNEL:{
- devpriv->n_channels = 4;
- }
- break;
- default:{
- devpriv->n_channels = 0;
- }
- }
- if (devpriv->n_channels >= 1) {
- if (opt_bus == 0 && opt_slot == 0) {
- /* Take first available card */
- break;
- } else if (opt_bus == card->bus->number &&
- opt_slot == PCI_SLOT(card->devfn)) {
- /* Take requested card */
- break;
- }
- }
- }
- }
- if (!card) {
- dev_err(dev->class_dev, "no jr3_pci found\n");
- return -EIO;
- } else {
- devpriv->pci_dev = card;
- dev->board_name = "jr3_pci";
+ switch (pcidev->device) {
+ case PCI_DEVICE_ID_JR3_1_CHANNEL:
+ case PCI_DEVICE_ID_JR3_1_CHANNEL_NEW:
+ devpriv->n_channels = 1;
+ break;
+ case PCI_DEVICE_ID_JR3_2_CHANNEL:
+ devpriv->n_channels = 2;
+ break;
+ case PCI_DEVICE_ID_JR3_3_CHANNEL:
+ devpriv->n_channels = 3;
+ break;
+ case PCI_DEVICE_ID_JR3_4_CHANNEL:
+ devpriv->n_channels = 4;
+ break;
+ default:
+ dev_err(dev->class_dev, "jr3_pci: pci %s not supported\n",
+ pci_name(pcidev));
+ return -EINVAL;
+ break;
}
+ dev->board_name = "jr3_pci";
- result = comedi_pci_enable(card, "jr3_pci");
+ result = comedi_pci_enable(pcidev, "jr3_pci");
if (result < 0)
- return -EIO;
+ return result;
- devpriv->pci_enabled = 1;
- devpriv->iobase = ioremap(pci_resource_start(card, 0),
- offsetof(struct jr3_t, channel[devpriv->n_channels]));
+ dev->iobase = 1; /* the "detach" needs this */
+ devpriv->iobase = ioremap(pci_resource_start(pcidev, 0),
+ offsetof(struct jr3_t,
+ channel[devpriv->n_channels]));
if (!devpriv->iobase)
return -ENOMEM;
@@ -840,7 +722,8 @@ static int jr3_pci_attach(struct comedi_device *dev,
dev->subdevices[i].n_chan = 8 * 7 + 2;
dev->subdevices[i].insn_read = jr3_pci_ai_insn_read;
dev->subdevices[i].private =
- kzalloc(sizeof(struct jr3_pci_subdev_private), GFP_KERNEL);
+ kzalloc(sizeof(struct jr3_pci_subdev_private),
+ GFP_KERNEL);
if (dev->subdevices[i].private) {
struct jr3_pci_subdev_private *p;
int j;
@@ -849,8 +732,8 @@ static int jr3_pci_attach(struct comedi_device *dev,
p->channel = &devpriv->iobase->channel[i].data;
dev_dbg(dev->class_dev, "p->channel %p %p (%tx)\n",
p->channel, devpriv->iobase,
- ((char *)(p->channel) -
- (char *)(devpriv->iobase)));
+ ((char __iomem *)p->channel -
+ (char __iomem *)devpriv->iobase));
p->channel_no = i;
for (j = 0; j < 8; j++) {
int k;
@@ -870,15 +753,15 @@ static int jr3_pci_attach(struct comedi_device *dev,
p->range[8].range.max = 65536;
p->range_table_list[56] =
- (struct comedi_lrange *)&p->range[8];
+ (struct comedi_lrange *)&p->range[8];
p->range_table_list[57] =
- (struct comedi_lrange *)&p->range[8];
+ (struct comedi_lrange *)&p->range[8];
p->maxdata_list[56] = 0xffff;
p->maxdata_list[57] = 0xffff;
/* Channel specific range and maxdata */
dev->subdevices[i].range_table = NULL;
dev->subdevices[i].range_table_list =
- p->range_table_list;
+ p->range_table_list;
dev->subdevices[i].maxdata = 0;
dev->subdevices[i].maxdata_list = p->maxdata_list;
}
@@ -891,19 +774,20 @@ static int jr3_pci_attach(struct comedi_device *dev,
dev_dbg(dev->class_dev, "Firmare load %d\n", result);
if (result < 0)
- goto out;
-/*
- * TODO: use firmware to load preferred offset tables. Suggested
- * format:
- * model serial Fx Fy Fz Mx My Mz\n
- *
- * comedi_load_firmware(dev, "jr3_offsets_table", jr3_download_firmware);
- */
+ return result;
+ /*
+ * TODO: use firmware to load preferred offset tables. Suggested
+ * format:
+ * model serial Fx Fy Fz Mx My Mz\n
+ *
+ * comedi_load_firmware(dev, "jr3_offsets_table",
+ * jr3_download_firmware);
+ */
-/*
- * It takes a few milliseconds for software to settle as much as we
- * can read firmware version
- */
+ /*
+ * It takes a few milliseconds for software to settle as much as we
+ * can read firmware version
+ */
msleep_interruptible(25);
for (i = 0; i < 0x18; i++) {
dev_dbg(dev->class_dev, "%c\n",
@@ -924,13 +808,13 @@ static int jr3_pci_attach(struct comedi_device *dev,
devpriv->timer.expires = jiffies + msecs_to_jiffies(1000);
add_timer(&devpriv->timer);
-out:
return result;
}
static void jr3_pci_detach(struct comedi_device *dev)
{
int i;
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct jr3_pci_dev_private *devpriv = dev->private;
if (devpriv) {
@@ -941,28 +825,26 @@ static void jr3_pci_detach(struct comedi_device *dev)
kfree(dev->subdevices[i].private);
}
if (devpriv->iobase)
- iounmap((void *)devpriv->iobase);
- if (devpriv->pci_enabled)
- comedi_pci_disable(devpriv->pci_dev);
- if (devpriv->pci_dev)
- pci_dev_put(devpriv->pci_dev);
+ iounmap(devpriv->iobase);
+ if (dev->iobase)
+ comedi_pci_disable(pcidev);
}
}
static struct comedi_driver jr3_pci_driver = {
.driver_name = "jr3_pci",
.module = THIS_MODULE,
- .attach = jr3_pci_attach,
+ .auto_attach = jr3_pci_auto_attach,
.detach = jr3_pci_detach,
};
-static int __devinit jr3_pci_pci_probe(struct pci_dev *dev,
+static int jr3_pci_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &jr3_pci_driver);
}
-static void __devexit jr3_pci_pci_remove(struct pci_dev *dev)
+static void jr3_pci_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -981,7 +863,7 @@ static struct pci_driver jr3_pci_pci_driver = {
.name = "jr3_pci",
.id_table = jr3_pci_pci_table,
.probe = jr3_pci_pci_probe,
- .remove = __devexit_p(jr3_pci_pci_remove),
+ .remove = jr3_pci_pci_remove,
};
module_comedi_pci_driver(jr3_pci_driver, jr3_pci_pci_driver);
diff --git a/drivers/staging/comedi/drivers/jr3_pci.h b/drivers/staging/comedi/drivers/jr3_pci.h
index 9c42653d8f1..3317f7a04c4 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.h
+++ b/drivers/staging/comedi/drivers/jr3_pci.h
@@ -2,22 +2,22 @@
* is 16 bits, but aligned on a 32 bit PCI boundary
*/
-static inline u16 get_u16(volatile const u32 * p)
+static inline u16 get_u16(const u32 __iomem *p)
{
- return (u16) readl(p);
+ return (u16)readl(p);
}
-static inline void set_u16(volatile u32 * p, u16 val)
+static inline void set_u16(u32 __iomem *p, u16 val)
{
writel(val, p);
}
-static inline s16 get_s16(volatile const s32 * p)
+static inline s16 get_s16(const s32 __iomem *p)
{
- return (s16) readl(p);
+ return (s16)readl(p);
}
-static inline void set_s16(volatile s32 * p, s16 val)
+static inline void set_s16(s32 __iomem *p, s16 val)
{
writel(val, p);
}
diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c
index e867b720f66..19c94282ac3 100644
--- a/drivers/staging/comedi/drivers/ke_counter.c
+++ b/drivers/staging/comedi/drivers/ke_counter.c
@@ -36,28 +36,8 @@ Kolter Electronic PCI Counter Card.
#include "../comedidev.h"
-#define CNT_DRIVER_NAME "ke_counter"
-#define PCI_VENDOR_ID_KOLTER 0x1001
#define CNT_CARD_DEVICE_ID 0x0014
-/*-- board specification structure ------------------------------------------*/
-
-struct cnt_board_struct {
-
- const char *name;
- int device_id;
- int cnt_channel_nbr;
- int cnt_bits;
-};
-
-static const struct cnt_board_struct cnt_boards[] = {
- {
- .name = CNT_DRIVER_NAME,
- .device_id = CNT_CARD_DEVICE_ID,
- .cnt_channel_nbr = 3,
- .cnt_bits = 24}
-};
-
/*-- counter write ----------------------------------------------------------*/
/* This should be used only for resetting the counters; maybe it is better
@@ -107,34 +87,14 @@ static int cnt_rinsn(struct comedi_device *dev,
return 1;
}
-static const void *cnt_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int cnt_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
- const struct cnt_board_struct *board;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(cnt_boards); i++) {
- board = &cnt_boards[i];
- if (board->device_id == pcidev->device)
- return board;
- }
- return NULL;
-}
-
-static int cnt_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct cnt_board_struct *board;
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct comedi_subdevice *s;
int ret;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
- board = cnt_find_boardinfo(dev, pcidev);
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
+ dev->board_name = dev->driver->driver_name;
ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret)
@@ -150,8 +110,8 @@ static int cnt_attach_pci(struct comedi_device *dev,
s->type = COMEDI_SUBD_COUNTER;
s->subdev_flags = SDF_READABLE /* | SDF_COMMON */ ;
- s->n_chan = board->cnt_channel_nbr;
- s->maxdata = (1 << board->cnt_bits) - 1;
+ s->n_chan = 3;
+ s->maxdata = 0x00ffffff;
s->insn_read = cnt_rinsn;
s->insn_write = cnt_winsn;
@@ -182,17 +142,17 @@ static void cnt_detach(struct comedi_device *dev)
static struct comedi_driver ke_counter_driver = {
.driver_name = "ke_counter",
.module = THIS_MODULE,
- .attach_pci = cnt_attach_pci,
+ .auto_attach = cnt_auto_attach,
.detach = cnt_detach,
};
-static int __devinit ke_counter_pci_probe(struct pci_dev *dev,
+static int ke_counter_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &ke_counter_driver);
}
-static void __devexit ke_counter_pci_remove(struct pci_dev *dev)
+static void ke_counter_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -207,7 +167,7 @@ static struct pci_driver ke_counter_pci_driver = {
.name = "ke_counter",
.id_table = ke_counter_pci_table,
.probe = ke_counter_pci_probe,
- .remove = __devexit_p(ke_counter_pci_remove),
+ .remove = ke_counter_pci_remove,
};
module_comedi_pci_driver(ke_counter_driver, ke_counter_pci_driver);
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index 22db35d091f..3c4b0228e8d 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -60,8 +60,6 @@ broken.
#include "me4000_fw.h"
#endif
-#define PCI_VENDOR_ID_MEILHAUS 0x1402
-
#define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650
#define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660
#define PCI_DEVICE_ID_MEILHAUS_ME4660I 0x4661
@@ -971,28 +969,23 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
if (err)
return 2;
- /*
- * Stage 3. Check if arguments are generally valid.
- */
+ /* Step 3: check if arguments are trivially valid */
+
if (cmd->chanlist_len < 1) {
- dev_err(dev->class_dev, "No channel list\n");
cmd->chanlist_len = 1;
- err++;
+ err |= -EINVAL;
}
if (init_ticks < 66) {
- dev_err(dev->class_dev, "Start arg to low\n");
cmd->start_arg = 2000;
- err++;
+ err |= -EINVAL;
}
if (scan_ticks && scan_ticks < 67) {
- dev_err(dev->class_dev, "Scan begin arg to low\n");
cmd->scan_begin_arg = 2031;
- err++;
+ err |= -EINVAL;
}
if (chan_ticks < 66) {
- dev_err(dev->class_dev, "Convert arg to low\n");
cmd->convert_arg = 2000;
- err++;
+ err |= -EINVAL;
}
if (err)
@@ -1570,26 +1563,25 @@ static const void *me4000_find_boardinfo(struct comedi_device *dev,
return NULL;
}
-static int me4000_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int me4000_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct me4000_board *thisboard;
struct me4000_info *info;
struct comedi_subdevice *s;
int result;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
thisboard = me4000_find_boardinfo(dev, pcidev);
if (!thisboard)
return -ENODEV;
dev->board_ptr = thisboard;
dev->board_name = thisboard->name;
- result = alloc_private(dev, sizeof(*info));
- if (result)
- return result;
- info = dev->private;
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+ dev->private = info;
result = comedi_pci_enable(pcidev, dev->board_name);
if (result)
@@ -1732,17 +1724,17 @@ static void me4000_detach(struct comedi_device *dev)
static struct comedi_driver me4000_driver = {
.driver_name = "me4000",
.module = THIS_MODULE,
- .attach_pci = me4000_attach_pci,
+ .auto_attach = me4000_auto_attach,
.detach = me4000_detach,
};
-static int __devinit me4000_pci_probe(struct pci_dev *dev,
+static int me4000_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &me4000_driver);
}
-static void __devexit me4000_pci_remove(struct pci_dev *dev)
+static void me4000_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -1769,7 +1761,7 @@ static struct pci_driver me4000_pci_driver = {
.name = "me4000",
.id_table = me4000_pci_table,
.probe = me4000_pci_probe,
- .remove = __devexit_p(me4000_pci_remove),
+ .remove = me4000_pci_remove,
};
module_comedi_pci_driver(me4000_driver, me4000_pci_driver);
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c
index 2ce0b14af58..ce8e3d3f135 100644
--- a/drivers/staging/comedi/drivers/me_daq.c
+++ b/drivers/staging/comedi/drivers/me_daq.c
@@ -1,47 +1,38 @@
/*
-
- comedi/drivers/me_daq.c
-
- Hardware driver for Meilhaus data acquisition cards:
-
- ME-2000i, ME-2600i, ME-3000vm1
-
- Copyright (C) 2002 Michael Hillmann <hillmann@syscongroup.de>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
+ * comedi/drivers/me_daq.c
+ * Hardware driver for Meilhaus data acquisition cards:
+ * ME-2000i, ME-2600i, ME-3000vm1
+ *
+ * Copyright (C) 2002 Michael Hillmann <hillmann@syscongroup.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
/*
-Driver: me_daq
-Description: Meilhaus PCI data acquisition cards
-Author: Michael Hillmann <hillmann@syscongroup.de>
-Devices: [Meilhaus] ME-2600i (me_daq), ME-2000i
-Status: experimental
-
-Supports:
-
- Analog Output
-
-Configuration options:
-
- [0] - PCI bus number (optional)
- [1] - PCI slot number (optional)
-
- If bus/slot is not specified, the first available PCI
- device will be used.
-*/
+ * Driver: me_daq
+ * Description: Meilhaus PCI data acquisition cards
+ * Devices: (Meilhaus) ME-2600i [me-2600i]
+ * (Meilhaus) ME-2000i [me-2000i]
+ * Author: Michael Hillmann <hillmann@syscongroup.de>
+ * Status: experimental
+ *
+ * Configuration options: not applicable, uses PCI auto config
+ *
+ * Supports:
+ * Analog Input, Analog Output, Digital I/O
+ */
#include <linux/interrupt.h>
#include <linux/sched.h>
@@ -50,7 +41,6 @@ Configuration options:
#define ME2600_FIRMWARE "me2600_firmware.bin"
-#define PCI_VENDOR_ID_MEILHAUS 0x1402
#define ME2000_DEVICE_ID 0x2000
#define ME2600_DEVICE_ID 0x2600
@@ -136,97 +126,47 @@ Configuration options:
#define ME_COUNTER_STARTDATA_B 0x0022 /* - | W */
#define ME_COUNTER_VALUE_B 0x0022 /* R | - */
-static const struct comedi_lrange me2000_ai_range = {
- 8,
- {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange me2600_ai_range = {
- 8,
- {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
+static const struct comedi_lrange me_ai_range = {
+ 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25)
+ }
};
-static const struct comedi_lrange me2600_ao_range = {
- 3,
- {
- BIP_RANGE(10),
- BIP_RANGE(5),
- UNI_RANGE(10)
- }
+static const struct comedi_lrange me_ao_range = {
+ 3, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ UNI_RANGE(10)
+ }
};
-/* Board specification structure */
struct me_board {
- const char *name; /* driver name */
+ const char *name;
int device_id;
- int ao_channel_nbr; /* DA config */
- int ao_resolution;
- int ao_resolution_mask;
- const struct comedi_lrange *ao_range_list;
- int ai_channel_nbr; /* AD config */
- int ai_resolution;
- int ai_resolution_mask;
- const struct comedi_lrange *ai_range_list;
- int dio_channel_nbr; /* DIO config */
+ int has_ao;
};
static const struct me_board me_boards[] = {
{
- .name = "me-2600i",
- .device_id = ME2600_DEVICE_ID,
- /* Analog Output */
- .ao_channel_nbr = 4,
- .ao_resolution = 12,
- .ao_resolution_mask = 0x0fff,
- .ao_range_list = &me2600_ao_range,
- .ai_channel_nbr = 16,
- /* Analog Input */
- .ai_resolution = 12,
- .ai_resolution_mask = 0x0fff,
- .ai_range_list = &me2600_ai_range,
- .dio_channel_nbr = 32,
- },
- {
- .name = "me-2000i",
- .device_id = ME2000_DEVICE_ID,
- /* Analog Output */
- .ao_channel_nbr = 0,
- .ao_resolution = 0,
- .ao_resolution_mask = 0,
- .ao_range_list = NULL,
- .ai_channel_nbr = 16,
- /* Analog Input */
- .ai_resolution = 12,
- .ai_resolution_mask = 0x0fff,
- .ai_range_list = &me2000_ai_range,
- .dio_channel_nbr = 32,
- }
+ .name = "me-2600i",
+ .device_id = ME2600_DEVICE_ID,
+ .has_ao = 1,
+ }, {
+ .name = "me-2000i",
+ .device_id = ME2000_DEVICE_ID,
+ }
};
-/* Private data structure */
struct me_private_data {
void __iomem *plx_regbase; /* PLX configuration base address */
void __iomem *me_regbase; /* Base address of the Meilhaus card */
- unsigned long plx_regbase_size; /* Size of PLX configuration space */
- unsigned long me_regbase_size; /* Size of Meilhaus space */
unsigned short control_1; /* Mirror of CONTROL_1 register */
unsigned short control_2; /* Mirror of CONTROL_2 register */
@@ -234,110 +174,101 @@ struct me_private_data {
int ao_readback[4]; /* Mirror of analog output data */
};
-#define dev_private ((struct me_private_data *)dev->private)
-
-/*
- * ------------------------------------------------------------------
- *
- * Helpful functions
- *
- * ------------------------------------------------------------------
- */
static inline void sleep(unsigned sec)
{
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(sec * HZ);
}
-/*
- * ------------------------------------------------------------------
- *
- * DIGITAL INPUT/OUTPUT SECTION
- *
- * ------------------------------------------------------------------
- */
static int me_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- int bits;
- int mask = 1 << CR_CHAN(insn->chanspec);
+ struct me_private_data *dev_private = dev->private;
+ unsigned int mask = 1 << CR_CHAN(insn->chanspec);
+ unsigned int bits;
+ unsigned int port;
- /* calculate port */
- if (mask & 0x0000ffff) { /* Port A in use */
+ if (mask & 0x0000ffff) {
bits = 0x0000ffff;
-
- /* Enable Port A */
- dev_private->control_2 |= ENABLE_PORT_A;
- writew(dev_private->control_2,
- dev_private->me_regbase + ME_CONTROL_2);
- } else { /* Port B in use */
-
+ port = ENABLE_PORT_A;
+ } else {
bits = 0xffff0000;
-
- /* Enable Port B */
- dev_private->control_2 |= ENABLE_PORT_B;
- writew(dev_private->control_2,
- dev_private->me_regbase + ME_CONTROL_2);
+ port = ENABLE_PORT_B;
}
- if (data[0]) {
- /* Config port as output */
- s->io_bits |= bits;
- } else {
- /* Config port as input */
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_INPUT:
s->io_bits &= ~bits;
+ dev_private->control_2 &= ~port;
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= bits;
+ dev_private->control_2 |= port;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
}
- return 1;
+ /* Update the port configuration */
+ writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
+
+ return insn->n;
}
-/* Digital instant input/outputs */
static int me_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 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];
- s->state &= ~mask;
- s->state |= (mask & data[1]);
-
- mask &= s->io_bits;
- if (mask & 0x0000ffff) { /* Port A */
- writew((s->state & 0xffff),
- dev_private->me_regbase + ME_DIO_PORT_A);
- } else {
- data[1] &= ~0x0000ffff;
- data[1] |= readw(dev_private->me_regbase + ME_DIO_PORT_A);
+ unsigned int bits = data[1];
+ unsigned int val;
+
+ mask &= s->io_bits; /* only update the COMEDI_OUTPUT channels */
+ if (mask) {
+ s->state &= ~mask;
+ s->state |= (bits & mask);
+
+ if (mask & 0x0000ffff)
+ writew((s->state & 0xffff), mmio_porta);
+ if (mask & 0xffff0000)
+ writew(((s->state >> 16) & 0xffff), mmio_portb);
}
- if (mask & 0xffff0000) { /* Port B */
- writew(((s->state >> 16) & 0xffff),
- dev_private->me_regbase + ME_DIO_PORT_B);
- } else {
- data[1] &= ~0xffff0000;
- data[1] |= readw(dev_private->me_regbase + ME_DIO_PORT_B) << 16;
- }
+ if (s->io_bits & 0x0000ffff)
+ val = s->state & 0xffff;
+ else
+ val = readw(mmio_porta);
+
+ if (s->io_bits & 0xffff0000)
+ val |= (s->state & 0xffff0000);
+ else
+ val |= (readw(mmio_portb) << 16);
+
+ data[1] = val;
return insn->n;
}
-/*
- * ------------------------------------------------------------------
- *
- * ANALOG INPUT SECTION
- *
- * ------------------------------------------------------------------
- */
-
-/* Analog instant input */
static int me_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned short value;
- int chan = CR_CHAN((&insn->chanspec)[0]);
- int rang = CR_RANGE((&insn->chanspec)[0]);
- int aref = CR_AREF((&insn->chanspec)[0]);
+ struct me_private_data *dev_private = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int rang = CR_RANGE(insn->chanspec);
+ unsigned int aref = CR_AREF(insn->chanspec);
+ unsigned short val;
int i;
/* stop any running conversion */
@@ -356,15 +287,11 @@ static int me_ai_insn_read(struct comedi_device *dev,
writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
/* write to channel list fifo */
- /* b3:b0 are the channel number */
- value = chan & 0x0f;
- /* b5:b4 are the channel gain */
- value |= (rang & 0x03) << 4;
- /* b6 channel polarity */
- value |= (rang & 0x04) << 4;
- /* b7 single or differential */
- value |= ((aref & AREF_DIFF) ? 0x80 : 0);
- writew(value & 0xff, dev_private->me_regbase + ME_CHANNEL_LIST);
+ val = chan & 0x0f; /* b3:b0 channel */
+ val |= (rang & 0x03) << 4; /* b5:b4 gain */
+ val |= (rang & 0x04) << 4; /* b6 polarity */
+ val |= ((aref & AREF_DIFF) ? 0x80 : 0); /* b7 differential */
+ writew(val & 0xff, dev_private->me_regbase + ME_CHANNEL_LIST);
/* set ADC mode to software trigger */
dev_private->control_1 |= SOFTWARE_TRIGGERED_ADC;
@@ -380,12 +307,11 @@ static int me_ai_insn_read(struct comedi_device *dev,
/* get value from ADC fifo */
if (i) {
- data[0] =
- (readw(dev_private->me_regbase +
- ME_READ_AD_FIFO) ^ 0x800) & 0x0FFF;
+ val = readw(dev_private->me_regbase + ME_READ_AD_FIFO);
+ val = (val ^ 0x800) & 0x0fff;
+ data[0] = val;
} else {
- printk(KERN_ERR "comedi%d: Cannot get single value\n",
- dev->minor);
+ dev_err(dev->class_dev, "Cannot get single value\n");
return -EIO;
}
@@ -396,55 +322,14 @@ static int me_ai_insn_read(struct comedi_device *dev,
return 1;
}
-/*
- * ------------------------------------------------------------------
- *
- * HARDWARE TRIGGERED ANALOG INPUT SECTION
- *
- * ------------------------------------------------------------------
- */
-
-/* Cancel analog input autoscan */
-static int me_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- /* disable interrupts */
-
- /* stop any running conversion */
- dev_private->control_1 &= 0xFFFC;
- writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1);
-
- return 0;
-}
-
-/* Test analog input command */
-static int me_ai_do_cmd_test(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- return 0;
-}
-
-/* Analog input command */
-static int me_ai_do_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- return 0;
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * ANALOG OUTPUT SECTION
- *
- * ------------------------------------------------------------------
- */
-
-/* Analog instant output */
static int me_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- int chan;
- int rang;
+ struct me_private_data *dev_private = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int rang = CR_RANGE(insn->chanspec);
int i;
/* Enable all DAC */
@@ -457,9 +342,6 @@ static int me_ao_insn_write(struct comedi_device *dev,
/* Set dac-control register */
for (i = 0; i < insn->n; i++) {
- chan = CR_CHAN((&insn->chanspec)[i]);
- rang = CR_RANGE((&insn->chanspec)[i]);
-
/* clear bits for this channel */
dev_private->dac_control &= ~(0x0880 >> chan);
if (rang == 0)
@@ -477,7 +359,6 @@ static int me_ao_insn_write(struct comedi_device *dev,
/* Set data register */
for (i = 0; i < insn->n; i++) {
- chan = CR_CHAN((&insn->chanspec)[i]);
writew((data[0] & s->maxdata),
dev_private->me_regbase + ME_DAC_DATA_A + (chan << 1));
dev_private->ao_readback[chan] = (data[0] & s->maxdata);
@@ -486,36 +367,28 @@ static int me_ao_insn_write(struct comedi_device *dev,
/* Update dac with data registers */
readw(dev_private->me_regbase + ME_DAC_UPDATE);
- return i;
+ return insn->n;
}
-/* Analog output readback */
static int me_ao_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
unsigned int *data)
{
+ struct me_private_data *dev_private = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
int i;
- for (i = 0; i < insn->n; i++) {
- data[i] =
- dev_private->ao_readback[CR_CHAN((&insn->chanspec)[i])];
- }
+ for (i = 0; i < insn->n; i++)
+ data[i] = dev_private->ao_readback[chan];
- return 1;
+ return insn->n;
}
-/*
- * ------------------------------------------------------------------
- *
- * INITIALISATION SECTION
- *
- * ------------------------------------------------------------------
- */
-
-/* Xilinx firmware download for card: ME-2600i */
static int me2600_xilinx_download(struct comedi_device *dev,
const u8 *data, size_t size)
{
+ struct me_private_data *dev_private = dev->private;
unsigned int value;
unsigned int file_length;
unsigned int i;
@@ -566,8 +439,7 @@ static int me2600_xilinx_download(struct comedi_device *dev,
if (value & 0x20) {
/* Disable interrupt */
writel(0x00, dev_private->plx_regbase + PLX_INTCSR);
- printk(KERN_ERR "comedi%d: Xilinx download failed\n",
- dev->minor);
+ dev_err(dev->class_dev, "Xilinx download failed\n");
return -EIO;
}
@@ -596,9 +468,10 @@ static int me2600_upload_firmware(struct comedi_device *dev)
return ret;
}
-/* Reset device */
static int me_reset(struct comedi_device *dev)
{
+ struct me_private_data *dev_private = dev->private;
+
/* Reset board */
writew(0x00, dev_private->me_regbase + ME_CONTROL_1);
writew(0x00, dev_private->me_regbase + ME_CONTROL_2);
@@ -627,20 +500,14 @@ static const void *me_find_boardinfo(struct comedi_device *dev,
return NULL;
}
-static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev)
+static int me_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct me_board *board;
+ struct me_private_data *dev_private;
struct comedi_subdevice *s;
- resource_size_t plx_regbase_tmp;
- unsigned long plx_regbase_size_tmp;
- resource_size_t me_regbase_tmp;
- unsigned long me_regbase_size_tmp;
- resource_size_t swap_regbase_tmp;
- unsigned long swap_regbase_size_tmp;
- resource_size_t regbase_tmp;
- int result, error;
-
- comedi_set_hw_dev(dev, &pcidev->dev);
+ int ret;
board = me_find_boardinfo(dev, pcidev);
if (!board)
@@ -648,123 +515,71 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev)
dev->board_ptr = board;
dev->board_name = board->name;
- /* Allocate private memory */
- if (alloc_private(dev, sizeof(struct me_private_data)) < 0)
+ dev_private = kzalloc(sizeof(*dev_private), GFP_KERNEL);
+ if (!dev_private)
return -ENOMEM;
+ dev->private = dev_private;
- /* Enable PCI device and request PCI regions */
- if (comedi_pci_enable(pcidev, dev->board_name) < 0) {
- printk(KERN_ERR "comedi%d: Failed to enable PCI device and "
- "request regions\n", dev->minor);
- return -EIO;
- }
+ ret = comedi_pci_enable(pcidev, dev->board_name);
+ if (ret)
+ return ret;
+ dev->iobase = 1; /* detach needs this */
- /* Read PLX register base address [PCI_BASE_ADDRESS #0]. */
- plx_regbase_tmp = pci_resource_start(pcidev, 0);
- plx_regbase_size_tmp = pci_resource_len(pcidev, 0);
- dev_private->plx_regbase =
- ioremap(plx_regbase_tmp, plx_regbase_size_tmp);
- dev_private->plx_regbase_size = plx_regbase_size_tmp;
- if (!dev_private->plx_regbase) {
- printk("comedi%d: Failed to remap I/O memory\n", dev->minor);
+ dev_private->plx_regbase = ioremap(pci_resource_start(pcidev, 0),
+ pci_resource_len(pcidev, 0));
+ if (!dev_private->plx_regbase)
return -ENOMEM;
- }
-
- /* Read Swap base address [PCI_BASE_ADDRESS #5]. */
-
- swap_regbase_tmp = pci_resource_start(pcidev, 5);
- swap_regbase_size_tmp = pci_resource_len(pcidev, 5);
-
- if (!swap_regbase_tmp)
- printk(KERN_ERR "comedi%d: Swap not present\n", dev->minor);
-
- /*---------------------------------------------- Workaround start ---*/
- if (plx_regbase_tmp & 0x0080) {
- printk(KERN_ERR "comedi%d: PLX-Bug detected\n", dev->minor);
-
- if (swap_regbase_tmp) {
- regbase_tmp = plx_regbase_tmp;
- plx_regbase_tmp = swap_regbase_tmp;
- swap_regbase_tmp = regbase_tmp;
-
- result = pci_write_config_dword(pcidev,
- PCI_BASE_ADDRESS_0,
- plx_regbase_tmp);
- if (result != PCIBIOS_SUCCESSFUL)
- return -EIO;
-
- result = pci_write_config_dword(pcidev,
- PCI_BASE_ADDRESS_5,
- swap_regbase_tmp);
- if (result != PCIBIOS_SUCCESSFUL)
- return -EIO;
- } else {
- plx_regbase_tmp -= 0x80;
- result = pci_write_config_dword(pcidev,
- PCI_BASE_ADDRESS_0,
- plx_regbase_tmp);
- if (result != PCIBIOS_SUCCESSFUL)
- return -EIO;
- }
- }
- /*--------------------------------------------- Workaround end -----*/
-
- /* Read Meilhaus register base address [PCI_BASE_ADDRESS #2]. */
- me_regbase_tmp = pci_resource_start(pcidev, 2);
- me_regbase_size_tmp = pci_resource_len(pcidev, 2);
- dev_private->me_regbase_size = me_regbase_size_tmp;
- dev_private->me_regbase = ioremap(me_regbase_tmp, me_regbase_size_tmp);
- if (!dev_private->me_regbase) {
- printk(KERN_ERR "comedi%d: Failed to remap I/O memory\n",
- dev->minor);
+ dev_private->me_regbase = ioremap(pci_resource_start(pcidev, 2),
+ pci_resource_len(pcidev, 2));
+ if (!dev_private->me_regbase)
return -ENOMEM;
- }
/* Download firmware and reset card */
if (board->device_id == ME2600_DEVICE_ID) {
- result = me2600_upload_firmware(dev);
- if (result < 0)
- return result;
+ ret = me2600_upload_firmware(dev);
+ if (ret < 0)
+ return ret;
}
me_reset(dev);
- error = comedi_alloc_subdevices(dev, 3);
- if (error)
- return error;
+ ret = comedi_alloc_subdevices(dev, 3);
+ if (ret)
+ return ret;
s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ;
- s->n_chan = board->ai_channel_nbr;
- s->maxdata = board->ai_resolution_mask;
- s->len_chanlist = board->ai_channel_nbr;
- s->range_table = board->ai_range_list;
- s->cancel = me_ai_cancel;
- s->insn_read = me_ai_insn_read;
- s->do_cmdtest = me_ai_do_cmd_test;
- s->do_cmd = me_ai_do_cmd;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_COMMON;
+ s->n_chan = 16;
+ s->maxdata = 0x0fff;
+ s->len_chanlist = 16;
+ s->range_table = &me_ai_range;
+ s->insn_read = me_ai_insn_read;
s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITEABLE | SDF_COMMON;
- s->n_chan = board->ao_channel_nbr;
- s->maxdata = board->ao_resolution_mask;
- s->len_chanlist = board->ao_channel_nbr;
- s->range_table = board->ao_range_list;
- s->insn_read = me_ao_insn_read;
- s->insn_write = me_ao_insn_write;
+ if (board->has_ao) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITEABLE | SDF_COMMON;
+ s->n_chan = 4;
+ s->maxdata = 0x0fff;
+ s->len_chanlist = 4;
+ s->range_table = &me_ao_range;
+ s->insn_read = me_ao_insn_read;
+ s->insn_write = me_ao_insn_write;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITEABLE;
- s->n_chan = board->dio_channel_nbr;
- s->maxdata = 1;
- s->len_chanlist = board->dio_channel_nbr;
- s->range_table = &range_digital;
- s->insn_bits = me_dio_insn_bits;
- s->insn_config = me_dio_insn_config;
- s->io_bits = 0;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITEABLE;
+ s->n_chan = 32;
+ s->maxdata = 1;
+ s->len_chanlist = 32;
+ 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);
@@ -775,6 +590,7 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev)
static void me_detach(struct comedi_device *dev)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct me_private_data *dev_private = dev->private;
if (dev_private) {
if (dev_private->me_regbase) {
@@ -785,26 +601,25 @@ static void me_detach(struct comedi_device *dev)
iounmap(dev_private->plx_regbase);
}
if (pcidev) {
- if (dev_private->plx_regbase_size)
+ if (dev->iobase)
comedi_pci_disable(pcidev);
- pci_dev_put(pcidev);
}
}
static struct comedi_driver me_daq_driver = {
.driver_name = "me_daq",
.module = THIS_MODULE,
- .attach_pci = me_attach_pci,
+ .auto_attach = me_auto_attach,
.detach = me_detach,
};
-static int __devinit me_daq_pci_probe(struct pci_dev *dev,
+static int me_daq_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &me_daq_driver);
}
-static void __devexit me_daq_pci_remove(struct pci_dev *dev)
+static void me_daq_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -820,7 +635,7 @@ static struct pci_driver me_daq_pci_driver = {
.name = "me_daq",
.id_table = me_daq_pci_table,
.probe = me_daq_pci_probe,
- .remove = __devexit_p(me_daq_pci_remove),
+ .remove = me_daq_pci_remove,
};
module_comedi_pci_driver(me_daq_driver, me_daq_pci_driver);
diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c
index f8b7faefc96..67dc5ad81b0 100644
--- a/drivers/staging/comedi/drivers/mpc624.c
+++ b/drivers/staging/comedi/drivers/mpc624.c
@@ -122,13 +122,12 @@ Configuration Options:
#define MPC624_SPEED_6_875_Hz \
(MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0)
/* -------------------------------------------------------------------------- */
-struct skel_private {
+struct mpc624_private {
/* set by mpc624_attach() from driver's parameters */
unsigned long int ulConvertionRate;
};
-#define devpriv ((struct skel_private *)dev->private)
/* -------------------------------------------------------------------------- */
static const struct comedi_lrange range_mpc624_bipolar1 = {
1,
@@ -155,6 +154,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
+ struct mpc624_private *devpriv = dev->private;
int n, i;
unsigned long int data_in, data_out;
unsigned char ucPort;
@@ -283,6 +283,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev,
static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ struct mpc624_private *devpriv;
struct comedi_subdevice *s;
unsigned long iobase;
int ret;
@@ -297,9 +298,10 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it)
dev->iobase = iobase;
dev->board_name = "mpc624";
- /* Private structure initialization */
- if (alloc_private(dev, sizeof(struct skel_private)) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
switch (it->options[1]) {
case 0:
diff --git a/drivers/staging/comedi/drivers/mpc8260cpm.c b/drivers/staging/comedi/drivers/mpc8260cpm.c
deleted file mode 100644
index c0c33299b7f..00000000000
--- a/drivers/staging/comedi/drivers/mpc8260cpm.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- comedi/drivers/mpc8260.c
- driver for digital I/O pins on the MPC 8260 CPM module
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 2000,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.
-
- 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.
-
-*/
-/*
-Driver: mpc8260cpm
-Description: MPC8260 CPM module generic digital I/O lines
-Devices: [Motorola] MPC8260 CPM (mpc8260cpm)
-Author: ds
-Status: experimental
-Updated: Sat, 16 Mar 2002 17:34:48 -0800
-
-This driver is specific to the Motorola MPC8260 processor, allowing
-you to access the processor's generic digital I/O lines.
-
-It is apparently missing some code.
-*/
-
-#include "../comedidev.h"
-
-extern unsigned long mpc8260_dio_reserved[4];
-
-struct mpc8260cpm_private {
-
- int data;
-
-};
-
-#define devpriv ((struct mpc8260cpm_private *)dev->private)
-
-static unsigned long *cpm_pdat(int port)
-{
- switch (port) {
- case 0:
- return &io->iop_pdata;
- case 1:
- return &io->iop_pdatb;
- case 2:
- return &io->iop_pdatc;
- case 3:
- return &io->iop_pdatd;
- }
-}
-
-static int mpc8260cpm_dio_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- int n;
- unsigned int d;
- unsigned int mask;
- int port;
-
- port = (int)s->private;
- mask = 1 << CR_CHAN(insn->chanspec);
- if (mask & cpm_reserved_bits[port]) {
- return -EINVAL;
- }
-
- switch (data[0]) {
- case INSN_CONFIG_DIO_OUTPUT:
- s->io_bits |= mask;
- break;
- case INSN_CONFIG_DIO_INPUT:
- s->io_bits &= ~mask;
- break;
- case INSN_CONFIG_DIO_QUERY:
- data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
- return insn->n;
- break;
- default:
- return -EINVAL;
- }
-
- switch (port) {
- case 0:
- return &io->iop_pdira;
- case 1:
- return &io->iop_pdirb;
- case 2:
- return &io->iop_pdirc;
- case 3:
- return &io->iop_pdird;
- }
-
- return 1;
-}
-
-static int mpc8260cpm_dio_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- int port;
- unsigned long *p;
-
- p = cpm_pdat((int)s->private);
-
- return insn->n;
-}
-
-static int mpc8260cpm_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct comedi_subdevice *s;
- int i;
- int ret;
-
- printk("comedi%d: mpc8260cpm: ", dev->minor);
-
- dev->board_ptr = mpc8260cpm_boards + dev->board;
-
- dev->board_name = thisboard->name;
-
- if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0)
- return -ENOMEM;
-
- ret =comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- for (i = 0; i < 4; i++) {
- s = &dev->subdevices[i];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 32;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_config = mpc8260cpm_dio_config;
- s->insn_bits = mpc8260cpm_dio_bits;
- }
-
- return 1;
-}
-
-static void mpc8260cpm_detach(struct comedi_device *dev)
-{
- /* Nothing to cleanup */
-}
-
-static struct comedi_driver mpc8260cpm_driver = {
- .driver_name = "mpc8260cpm",
- .module = THIS_MODULE,
- .attach = mpc8260cpm_attach,
- .detach = mpc8260cpm_detach,
-};
-module_comedi_driver(mpc8260cpm_driver);
diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c
index 4625cb4d07c..1f5f402f3d1 100644
--- a/drivers/staging/comedi/drivers/multiq3.c
+++ b/drivers/staging/comedi/drivers/multiq3.c
@@ -86,7 +86,6 @@ Devices: [Quanser Consulting] MultiQ-3 (multiq3)
struct multiq3_private {
unsigned int ao_readback[2];
};
-#define devpriv ((struct multiq3_private *)dev->private)
static int multiq3_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
@@ -129,6 +128,7 @@ static int multiq3_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct multiq3_private *devpriv = dev->private;
int i;
int chan = CR_CHAN(insn->chanspec);
@@ -142,6 +142,7 @@ static int multiq3_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct multiq3_private *devpriv = dev->private;
int i;
int chan = CR_CHAN(insn->chanspec);
@@ -230,6 +231,7 @@ static void encoder_reset(struct comedi_device *dev)
static int multiq3_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
+ struct multiq3_private *devpriv;
int result = 0;
unsigned long iobase;
unsigned int irq;
@@ -256,9 +258,10 @@ static int multiq3_attach(struct comedi_device *dev,
if (result)
return result;
- result = alloc_private(dev, sizeof(struct multiq3_private));
- if (result < 0)
- return result;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
s = &dev->subdevices[0];
/* ai subdevice */
diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c
index 51295f32ee8..5196b460ce1 100644
--- a/drivers/staging/comedi/drivers/ni_6527.c
+++ b/drivers/staging/comedi/drivers/ni_6527.c
@@ -112,12 +112,11 @@ struct ni6527_private {
unsigned int filter_enable;
};
-#define devpriv ((struct ni6527_private *)dev->private)
-
static int ni6527_di_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni6527_private *devpriv = dev->private;
int chan = CR_CHAN(insn->chanspec);
unsigned int interval;
@@ -164,6 +163,8 @@ static int ni6527_di_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni6527_private *devpriv = dev->private;
+
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;
@@ -175,6 +176,8 @@ static int ni6527_do_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
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]);
@@ -202,6 +205,7 @@ static int ni6527_do_insn_bits(struct comedi_device *dev,
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];
unsigned int status;
@@ -243,29 +247,13 @@ static int ni6527_intr_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
-
- if (cmd->scan_end_arg != 1) {
- cmd->scan_end_arg = 1;
- err++;
- }
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ 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;
@@ -281,6 +269,7 @@ static int ni6527_intr_cmdtest(struct comedi_device *dev,
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; */
writeb(ClrEdge | ClrOverflow,
@@ -295,6 +284,8 @@ static int ni6527_intr_cmd(struct comedi_device *dev,
static int ni6527_intr_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct ni6527_private *devpriv = dev->private;
+
writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
return 0;
@@ -312,6 +303,8 @@ static int ni6527_intr_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni6527_private *devpriv = dev->private;
+
if (insn->n < 1)
return -EINVAL;
if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
@@ -348,15 +341,18 @@ ni6527_find_boardinfo(struct pci_dev *pcidev)
return NULL;
}
-static int __devinit ni6527_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int ni6527_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct ni6527_private *devpriv;
struct comedi_subdevice *s;
int ret;
- ret = alloc_private(dev, sizeof(struct ni6527_private));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
dev->board_ptr = ni6527_find_boardinfo(pcidev);
if (!dev->board_ptr)
@@ -430,6 +426,8 @@ static int __devinit ni6527_attach_pci(struct comedi_device *dev,
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);
@@ -444,17 +442,17 @@ static void ni6527_detach(struct comedi_device *dev)
static struct comedi_driver ni6527_driver = {
.driver_name = DRIVER_NAME,
.module = THIS_MODULE,
- .attach_pci = ni6527_attach_pci,
+ .auto_attach = ni6527_auto_attach,
.detach = ni6527_detach,
};
-static int __devinit ni6527_pci_probe(struct pci_dev *dev,
+static int ni6527_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &ni6527_driver);
}
-static void __devexit ni6527_pci_remove(struct pci_dev *dev)
+static void ni6527_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -463,7 +461,7 @@ static struct pci_driver ni6527_pci_driver = {
.name = DRIVER_NAME,
.id_table = ni6527_pci_table,
.probe = ni6527_pci_probe,
- .remove = __devexit_p(ni6527_pci_remove)
+ .remove = ni6527_pci_remove
};
module_comedi_pci_driver(ni6527_driver, ni6527_pci_driver);
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
index 2a73ff57a2f..2fb4b7790ae 100644
--- a/drivers/staging/comedi/drivers/ni_65xx.c
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -48,7 +48,6 @@ except maybe the 6514.
*/
-#define _GNU_SOURCE
#define DEBUG 1
#define DEBUG_FLAGS
#include <linux/interrupt.h>
@@ -291,11 +290,6 @@ struct ni_65xx_private {
unsigned short dio_direction[NI_65XX_MAX_NUM_PORTS];
};
-static inline struct ni_65xx_private *private(struct comedi_device *dev)
-{
- return dev->private;
-}
-
struct ni_65xx_subdevice_private {
unsigned base_port;
};
@@ -319,6 +313,7 @@ static int ni_65xx_config_filter(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_65xx_private *devpriv = dev->private;
const unsigned chan = CR_CHAN(insn->chanspec);
const unsigned port =
sprivate(s)->base_port + ni_65xx_port_by_channel(chan);
@@ -335,22 +330,22 @@ static int ni_65xx_config_filter(struct comedi_device *dev,
interval = max_filter_interval;
data[1] = interval * filter_resolution_ns;
- if (interval != private(dev)->filter_interval) {
+ if (interval != devpriv->filter_interval) {
writeb(interval,
- private(dev)->mite->daq_io_addr +
+ devpriv->mite->daq_io_addr +
Filter_Interval);
- private(dev)->filter_interval = interval;
+ devpriv->filter_interval = interval;
}
- private(dev)->filter_enable[port] |=
+ devpriv->filter_enable[port] |=
1 << (chan % ni_65xx_channels_per_port);
} else {
- private(dev)->filter_enable[port] &=
+ devpriv->filter_enable[port] &=
~(1 << (chan % ni_65xx_channels_per_port));
}
- writeb(private(dev)->filter_enable[port],
- private(dev)->mite->daq_io_addr + Filter_Enable(port));
+ writeb(devpriv->filter_enable[port],
+ devpriv->mite->daq_io_addr + Filter_Enable(port));
return 2;
}
@@ -359,6 +354,7 @@ static int ni_65xx_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_65xx_private *devpriv = dev->private;
unsigned port;
if (insn->n < 1)
@@ -372,21 +368,21 @@ static int ni_65xx_dio_insn_config(struct comedi_device *dev,
case INSN_CONFIG_DIO_OUTPUT:
if (s->type != COMEDI_SUBD_DIO)
return -EINVAL;
- private(dev)->dio_direction[port] = COMEDI_OUTPUT;
- writeb(0, private(dev)->mite->daq_io_addr + Port_Select(port));
+ devpriv->dio_direction[port] = COMEDI_OUTPUT;
+ writeb(0, devpriv->mite->daq_io_addr + Port_Select(port));
return 1;
break;
case INSN_CONFIG_DIO_INPUT:
if (s->type != COMEDI_SUBD_DIO)
return -EINVAL;
- private(dev)->dio_direction[port] = COMEDI_INPUT;
- writeb(1, private(dev)->mite->daq_io_addr + Port_Select(port));
+ devpriv->dio_direction[port] = COMEDI_INPUT;
+ writeb(1, devpriv->mite->daq_io_addr + Port_Select(port));
return 1;
break;
case INSN_CONFIG_DIO_QUERY:
if (s->type != COMEDI_SUBD_DIO)
return -EINVAL;
- data[1] = private(dev)->dio_direction[port];
+ data[1] = devpriv->dio_direction[port];
return insn->n;
break;
default:
@@ -399,6 +395,7 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_65xx_private *devpriv = dev->private;
unsigned base_bitfield_channel;
const unsigned max_ports_per_bitfield = 5;
unsigned read_bits = 0;
@@ -432,18 +429,18 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
port_data &= 0xff;
if (port_mask) {
unsigned bits;
- private(dev)->output_bits[port] &= ~port_mask;
- private(dev)->output_bits[port] |=
+ devpriv->output_bits[port] &= ~port_mask;
+ devpriv->output_bits[port] |=
port_data & port_mask;
- bits = private(dev)->output_bits[port];
+ bits = devpriv->output_bits[port];
if (board(dev)->invert_outputs)
bits = ~bits;
writeb(bits,
- private(dev)->mite->daq_io_addr +
+ devpriv->mite->daq_io_addr +
Port_Data(port));
}
port_read_bits =
- readb(private(dev)->mite->daq_io_addr + Port_Data(port));
+ readb(devpriv->mite->daq_io_addr + Port_Data(port));
if (s->type == COMEDI_SUBD_DO && board(dev)->invert_outputs) {
/* Outputs inverted, so invert value read back from
* DO subdevice. (Does not apply to boards with DIO
@@ -464,17 +461,18 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
static irqreturn_t ni_65xx_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct ni_65xx_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[2];
unsigned int status;
- status = readb(private(dev)->mite->daq_io_addr + Change_Status);
+ status = readb(devpriv->mite->daq_io_addr + Change_Status);
if ((status & MasterInterruptStatus) == 0)
return IRQ_NONE;
if ((status & EdgeStatus) == 0)
return IRQ_NONE;
writeb(ClrEdge | ClrOverflow,
- private(dev)->mite->daq_io_addr + Clear_Register);
+ devpriv->mite->daq_io_addr + Clear_Register);
comedi_buf_put(s->async, 0);
s->async->events |= COMEDI_CB_EOS;
@@ -505,29 +503,13 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
-
- if (cmd->scan_end_arg != 1) {
- cmd->scan_end_arg = 1;
- err++;
- }
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ 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;
@@ -543,13 +525,14 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev,
static int ni_65xx_intr_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct ni_65xx_private *devpriv = dev->private;
/* struct comedi_cmd *cmd = &s->async->cmd; */
writeb(ClrEdge | ClrOverflow,
- private(dev)->mite->daq_io_addr + Clear_Register);
+ devpriv->mite->daq_io_addr + Clear_Register);
writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
MasterInterruptEnable | EdgeIntEnable,
- private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
+ devpriv->mite->daq_io_addr + Master_Interrupt_Control);
return 0;
}
@@ -557,8 +540,9 @@ static int ni_65xx_intr_cmd(struct comedi_device *dev,
static int ni_65xx_intr_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- writeb(0x00,
- private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
+ struct ni_65xx_private *devpriv = dev->private;
+
+ writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
return 0;
}
@@ -576,35 +560,37 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct ni_65xx_private *devpriv = dev->private;
+
if (insn->n < 1)
return -EINVAL;
if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
return -EINVAL;
writeb(data[1],
- private(dev)->mite->daq_io_addr +
+ devpriv->mite->daq_io_addr +
Rising_Edge_Detection_Enable(0));
writeb(data[1] >> 8,
- private(dev)->mite->daq_io_addr +
+ devpriv->mite->daq_io_addr +
Rising_Edge_Detection_Enable(0x10));
writeb(data[1] >> 16,
- private(dev)->mite->daq_io_addr +
+ devpriv->mite->daq_io_addr +
Rising_Edge_Detection_Enable(0x20));
writeb(data[1] >> 24,
- private(dev)->mite->daq_io_addr +
+ devpriv->mite->daq_io_addr +
Rising_Edge_Detection_Enable(0x30));
writeb(data[2],
- private(dev)->mite->daq_io_addr +
+ devpriv->mite->daq_io_addr +
Falling_Edge_Detection_Enable(0));
writeb(data[2] >> 8,
- private(dev)->mite->daq_io_addr +
+ devpriv->mite->daq_io_addr +
Falling_Edge_Detection_Enable(0x10));
writeb(data[2] >> 16,
- private(dev)->mite->daq_io_addr +
+ devpriv->mite->daq_io_addr +
Falling_Edge_Detection_Enable(0x20));
writeb(data[2] >> 24,
- private(dev)->mite->daq_io_addr +
+ devpriv->mite->daq_io_addr +
Falling_Edge_Detection_Enable(0x30));
return 2;
@@ -624,35 +610,38 @@ ni_65xx_find_boardinfo(struct pci_dev *pcidev)
return NULL;
}
-static int __devinit ni_65xx_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int ni_65xx_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct ni_65xx_private *devpriv;
struct comedi_subdevice *s;
unsigned i;
int ret;
- ret = alloc_private(dev, sizeof(struct ni_65xx_private));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
dev->board_ptr = ni_65xx_find_boardinfo(pcidev);
if (!dev->board_ptr)
return -ENODEV;
- private(dev)->mite = mite_alloc(pcidev);
- if (!private(dev)->mite)
+ devpriv->mite = mite_alloc(pcidev);
+ if (!devpriv->mite)
return -ENOMEM;
- ret = mite_setup(private(dev)->mite);
+ ret = mite_setup(devpriv->mite);
if (ret < 0) {
dev_warn(dev->class_dev, "error setting up mite\n");
return ret;
}
dev->board_name = board(dev)->name;
- dev->irq = mite_irq(private(dev)->mite);
+ dev->irq = mite_irq(devpriv->mite);
dev_info(dev->class_dev, "board: %s, ID=0x%02x", dev->board_name,
- readb(private(dev)->mite->daq_io_addr + ID_Register));
+ readb(devpriv->mite->daq_io_addr + ID_Register));
ret = comedi_alloc_subdevices(dev, 4);
if (ret)
@@ -710,7 +699,7 @@ static int __devinit ni_65xx_attach_pci(struct comedi_device *dev,
for (i = 0; i < board(dev)->num_dio_ports; ++i) {
/* configure all ports for input */
writeb(0x1,
- private(dev)->mite->daq_io_addr +
+ devpriv->mite->daq_io_addr +
Port_Select(i));
}
} else {
@@ -732,21 +721,21 @@ static int __devinit ni_65xx_attach_pci(struct comedi_device *dev,
for (i = 0; i < ni_65xx_total_num_ports(board(dev)); ++i) {
writeb(0x00,
- private(dev)->mite->daq_io_addr + Filter_Enable(i));
+ devpriv->mite->daq_io_addr + Filter_Enable(i));
if (board(dev)->invert_outputs)
writeb(0x01,
- private(dev)->mite->daq_io_addr + Port_Data(i));
+ devpriv->mite->daq_io_addr + Port_Data(i));
else
writeb(0x00,
- private(dev)->mite->daq_io_addr + Port_Data(i));
+ devpriv->mite->daq_io_addr + Port_Data(i));
}
writeb(ClrEdge | ClrOverflow,
- private(dev)->mite->daq_io_addr + Clear_Register);
+ devpriv->mite->daq_io_addr + Clear_Register);
writeb(0x00,
- private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
+ devpriv->mite->daq_io_addr + Master_Interrupt_Control);
/* Set filter interval to 0 (32bit reg) */
- writeb(0x00000000, private(dev)->mite->daq_io_addr + Filter_Interval);
+ writeb(0x00000000, devpriv->mite->daq_io_addr + Filter_Interval);
ret = request_irq(dev->irq, ni_65xx_interrupt, IRQF_SHARED,
"ni_65xx", dev);
@@ -760,15 +749,16 @@ static int __devinit ni_65xx_attach_pci(struct comedi_device *dev,
static void ni_65xx_detach(struct comedi_device *dev)
{
- if (private(dev) && private(dev)->mite
- && private(dev)->mite->daq_io_addr) {
+ struct ni_65xx_private *devpriv = dev->private;
+
+ if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) {
writeb(0x00,
- private(dev)->mite->daq_io_addr +
+ devpriv->mite->daq_io_addr +
Master_Interrupt_Control);
}
if (dev->irq)
free_irq(dev->irq, dev);
- if (private(dev)) {
+ if (devpriv) {
struct comedi_subdevice *s;
unsigned i;
@@ -777,9 +767,9 @@ static void ni_65xx_detach(struct comedi_device *dev)
kfree(s->private);
s->private = NULL;
}
- if (private(dev)->mite) {
- mite_unsetup(private(dev)->mite);
- mite_free(private(dev)->mite);
+ if (devpriv->mite) {
+ mite_unsetup(devpriv->mite);
+ mite_free(devpriv->mite);
}
}
}
@@ -787,17 +777,17 @@ static void ni_65xx_detach(struct comedi_device *dev)
static struct comedi_driver ni_65xx_driver = {
.driver_name = "ni_65xx",
.module = THIS_MODULE,
- .attach_pci = ni_65xx_attach_pci,
+ .auto_attach = ni_65xx_auto_attach,
.detach = ni_65xx_detach,
};
-static int __devinit ni_65xx_pci_probe(struct pci_dev *dev,
+static int ni_65xx_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &ni_65xx_driver);
}
-static void __devexit ni_65xx_pci_remove(struct pci_dev *dev)
+static void ni_65xx_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -806,7 +796,7 @@ static struct pci_driver ni_65xx_pci_driver = {
.name = "ni_65xx",
.id_table = ni_65xx_pci_table,
.probe = ni_65xx_pci_probe,
- .remove = __devexit_p(ni_65xx_pci_remove)
+ .remove = ni_65xx_pci_remove
};
module_comedi_pci_driver(ni_65xx_driver, ni_65xx_pci_driver);
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c
index df2f3b0bab4..26baf9c96ff 100644
--- a/drivers/staging/comedi/drivers/ni_660x.c
+++ b/drivers/staging/comedi/drivers/ni_660x.c
@@ -419,16 +419,6 @@ static const struct ni_660x_board ni_660x_boards[] = {
#define NI_660X_MAX_NUM_CHIPS 2
#define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip)
-static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = {
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c60)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1310)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1360)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2cc0)},
- {0}
-};
-
-MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
-
struct ni_660x_private {
struct mite_struct *mite;
struct ni_gpct_device *counter_dev;
@@ -443,78 +433,11 @@ struct ni_660x_private {
unsigned short pfi_output_selects[NUM_PFI_CHANNELS];
};
-static inline struct ni_660x_private *private(struct comedi_device *dev)
-{
- return dev->private;
-}
-
-/* initialized in ni_660x_attach_pci() */
-static inline const struct ni_660x_board *board(struct comedi_device *dev)
-{
- return dev->board_ptr;
-}
-
-static int ni_660x_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev);
-static void ni_660x_detach(struct comedi_device *dev);
-static void init_tio_chip(struct comedi_device *dev, int chipset);
-static void ni_660x_select_pfi_output(struct comedi_device *dev,
- unsigned pfi_channel,
- unsigned output_select);
-
-static struct comedi_driver ni_660x_driver = {
- .driver_name = "ni_660x",
- .module = THIS_MODULE,
- .attach_pci = ni_660x_attach_pci,
- .detach = ni_660x_detach,
-};
-
-static int __devinit ni_660x_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
-{
- return comedi_pci_auto_config(dev, &ni_660x_driver);
-}
-
-static void __devexit ni_660x_pci_remove(struct pci_dev *dev)
-{
- comedi_pci_auto_unconfig(dev);
-}
-
-static struct pci_driver ni_660x_pci_driver = {
- .name = "ni_660x",
- .id_table = ni_660x_pci_table,
- .probe = ni_660x_pci_probe,
- .remove = __devexit_p(ni_660x_pci_remove)
-};
-module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver);
-
-static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan,
- unsigned source);
-
-/* Possible instructions for a GPCT */
-static int ni_660x_GPCT_rinsn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_660x_GPCT_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-static int ni_660x_GPCT_winsn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-/* Possible instructions for Digital IO */
-static int ni_660x_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-static int ni_660x_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
static inline unsigned ni_660x_num_counters(struct comedi_device *dev)
{
- return board(dev)->n_chips * counters_per_chip;
+ const struct ni_660x_board *board = comedi_board(dev);
+
+ return board->n_chips * counters_per_chip;
}
static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
@@ -737,8 +660,9 @@ static inline void ni_660x_write_register(struct comedi_device *dev,
unsigned chip_index, unsigned bits,
enum NI_660x_Register reg)
{
+ struct ni_660x_private *devpriv = dev->private;
void __iomem *write_address =
- private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
+ devpriv->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
registerData[reg].offset;
switch (registerData[reg].size) {
@@ -758,8 +682,9 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev,
unsigned chip_index,
enum NI_660x_Register reg)
{
+ struct ni_660x_private *devpriv = dev->private;
void __iomem *read_address =
- private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
+ devpriv->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
registerData[reg].offset;
switch (registerData[reg].size) {
@@ -806,54 +731,56 @@ static inline void ni_660x_set_dma_channel(struct comedi_device *dev,
unsigned mite_channel,
struct ni_gpct *counter)
{
+ struct ni_660x_private *devpriv = dev->private;
unsigned long flags;
- spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
- private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
+
+ spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
+ devpriv->dma_configuration_soft_copies[counter->chip_index] &=
~dma_select_mask(mite_channel);
- private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
+ devpriv->dma_configuration_soft_copies[counter->chip_index] |=
dma_select_bits(mite_channel,
dma_selection_counter(counter->counter_index));
ni_660x_write_register(dev, counter->chip_index,
- private(dev)->
- dma_configuration_soft_copies
+ devpriv->dma_configuration_soft_copies
[counter->chip_index] |
dma_reset_bit(mite_channel), DMAConfigRegister);
mmiowb();
- spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags);
+ spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
}
static inline void ni_660x_unset_dma_channel(struct comedi_device *dev,
unsigned mite_channel,
struct ni_gpct *counter)
{
+ struct ni_660x_private *devpriv = dev->private;
unsigned long flags;
- spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
- private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
+
+ spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
+ devpriv->dma_configuration_soft_copies[counter->chip_index] &=
~dma_select_mask(mite_channel);
- private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
+ devpriv->dma_configuration_soft_copies[counter->chip_index] |=
dma_select_bits(mite_channel, dma_selection_none);
ni_660x_write_register(dev, counter->chip_index,
- private(dev)->
- dma_configuration_soft_copies
+ devpriv->dma_configuration_soft_copies
[counter->chip_index], DMAConfigRegister);
mmiowb();
- spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags);
+ spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
}
static int ni_660x_request_mite_channel(struct comedi_device *dev,
struct ni_gpct *counter,
enum comedi_io_direction direction)
{
+ struct ni_660x_private *devpriv = dev->private;
unsigned long flags;
struct mite_channel *mite_chan;
- spin_lock_irqsave(&private(dev)->mite_channel_lock, flags);
+ spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
BUG_ON(counter->mite_chan);
- mite_chan =
- mite_request_channel(private(dev)->mite, mite_ring(private(dev),
- counter));
+ mite_chan = mite_request_channel(devpriv->mite,
+ mite_ring(devpriv, counter));
if (mite_chan == NULL) {
- spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
+ spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
comedi_error(dev,
"failed to reserve mite dma channel for counter.");
return -EBUSY;
@@ -861,16 +788,17 @@ static int ni_660x_request_mite_channel(struct comedi_device *dev,
mite_chan->dir = direction;
ni_tio_set_mite_channel(counter, mite_chan);
ni_660x_set_dma_channel(dev, mite_chan->channel, counter);
- spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
+ spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
return 0;
}
static void ni_660x_release_mite_channel(struct comedi_device *dev,
struct ni_gpct *counter)
{
+ struct ni_660x_private *devpriv = dev->private;
unsigned long flags;
- spin_lock_irqsave(&private(dev)->mite_channel_lock, flags);
+ spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
if (counter->mite_chan) {
struct mite_channel *mite_chan = counter->mite_chan;
@@ -878,7 +806,7 @@ static void ni_660x_release_mite_channel(struct comedi_device *dev,
ni_tio_set_mite_channel(counter, NULL);
mite_release_channel(mite_chan);
}
- spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
+ spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
}
static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -947,6 +875,7 @@ static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev,
static irqreturn_t ni_660x_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct ni_660x_private *devpriv = dev->private;
struct comedi_subdevice *s;
unsigned i;
unsigned long flags;
@@ -954,24 +883,26 @@ static irqreturn_t ni_660x_interrupt(int irq, void *d)
if (dev->attached == 0)
return IRQ_NONE;
/* lock to avoid race with comedi_poll */
- spin_lock_irqsave(&private(dev)->interrupt_lock, flags);
+ spin_lock_irqsave(&devpriv->interrupt_lock, flags);
smp_mb();
for (i = 0; i < ni_660x_num_counters(dev); ++i) {
s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)];
ni_660x_handle_gpct_interrupt(dev, s);
}
- spin_unlock_irqrestore(&private(dev)->interrupt_lock, flags);
+ spin_unlock_irqrestore(&devpriv->interrupt_lock, flags);
return IRQ_HANDLED;
}
static int ni_660x_input_poll(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct ni_660x_private *devpriv = dev->private;
unsigned long flags;
+
/* lock to avoid race with comedi_poll */
- spin_lock_irqsave(&private(dev)->interrupt_lock, flags);
+ spin_lock_irqsave(&devpriv->interrupt_lock, flags);
mite_sync_input_dma(subdev_to_counter(s)->mite_chan, s->async);
- spin_unlock_irqrestore(&private(dev)->interrupt_lock, flags);
+ spin_unlock_irqrestore(&devpriv->interrupt_lock, flags);
return comedi_buf_read_n_available(s->async);
}
@@ -979,9 +910,10 @@ static int ni_660x_buf_change(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned long new_size)
{
+ struct ni_660x_private *devpriv = dev->private;
int ret;
- ret = mite_buf_change(mite_ring(private(dev), subdev_to_counter(s)),
+ ret = mite_buf_change(mite_ring(devpriv, subdev_to_counter(s)),
s->async);
if (ret < 0)
return ret;
@@ -991,32 +923,35 @@ static int ni_660x_buf_change(struct comedi_device *dev,
static int ni_660x_allocate_private(struct comedi_device *dev)
{
- int retval;
+ struct ni_660x_private *devpriv;
unsigned i;
- retval = alloc_private(dev, sizeof(struct ni_660x_private));
- if (retval < 0)
- return retval;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
- spin_lock_init(&private(dev)->mite_channel_lock);
- spin_lock_init(&private(dev)->interrupt_lock);
- spin_lock_init(&private(dev)->soft_reg_copy_lock);
+ spin_lock_init(&devpriv->mite_channel_lock);
+ spin_lock_init(&devpriv->interrupt_lock);
+ spin_lock_init(&devpriv->soft_reg_copy_lock);
for (i = 0; i < NUM_PFI_CHANNELS; ++i)
- private(dev)->pfi_output_selects[i] = pfi_output_select_counter;
+ devpriv->pfi_output_selects[i] = pfi_output_select_counter;
return 0;
}
static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
{
+ const struct ni_660x_board *board = comedi_board(dev);
+ struct ni_660x_private *devpriv = dev->private;
unsigned i;
unsigned j;
- for (i = 0; i < board(dev)->n_chips; ++i) {
+ for (i = 0; i < board->n_chips; ++i) {
for (j = 0; j < counters_per_chip; ++j) {
- private(dev)->mite_rings[i][j] =
- mite_alloc_ring(private(dev)->mite);
- if (private(dev)->mite_rings[i][j] == NULL)
+ devpriv->mite_rings[i][j] =
+ mite_alloc_ring(devpriv->mite);
+ if (devpriv->mite_rings[i][j] == NULL)
return -ENOMEM;
}
}
@@ -1025,12 +960,14 @@ static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
static void ni_660x_free_mite_rings(struct comedi_device *dev)
{
+ const struct ni_660x_board *board = comedi_board(dev);
+ struct ni_660x_private *devpriv = dev->private;
unsigned i;
unsigned j;
- for (i = 0; i < board(dev)->n_chips; ++i) {
+ for (i = 0; i < board->n_chips; ++i) {
for (j = 0; j < counters_per_chip; ++j)
- mite_free_ring(private(dev)->mite_rings[i][j]);
+ mite_free_ring(devpriv->mite_rings[i][j]);
}
}
@@ -1048,145 +985,6 @@ ni_660x_find_boardinfo(struct pci_dev *pcidev)
return NULL;
}
-static int __devinit ni_660x_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- struct comedi_subdevice *s;
- int ret;
- unsigned i;
- unsigned global_interrupt_config_bits;
-
- ret = ni_660x_allocate_private(dev);
- if (ret < 0)
- return ret;
- dev->board_ptr = ni_660x_find_boardinfo(pcidev);
- if (!dev->board_ptr)
- return -ENODEV;
- private(dev)->mite = mite_alloc(pcidev);
- if (!private(dev)->mite)
- return -ENOMEM;
-
- dev->board_name = board(dev)->name;
-
- ret = mite_setup2(private(dev)->mite, 1);
- if (ret < 0) {
- dev_warn(dev->class_dev, "error setting up mite\n");
- return ret;
- }
- comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev);
- ret = ni_660x_alloc_mite_rings(dev);
- if (ret < 0)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, 2 + NI_660X_MAX_NUM_COUNTERS);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */
- s->type = COMEDI_SUBD_UNUSED;
-
- s = &dev->subdevices[NI_660X_DIO_SUBDEV];
- /* DIGITAL I/O SUBDEVICE */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = NUM_PFI_CHANNELS;
- s->maxdata = 1;
- 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);
-
- private(dev)->counter_dev = ni_gpct_device_construct(dev,
- &ni_gpct_write_register,
- &ni_gpct_read_register,
- ni_gpct_variant_660x,
- ni_660x_num_counters
- (dev));
- if (private(dev)->counter_dev == NULL)
- return -ENOMEM;
- for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) {
- s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)];
- if (i < ni_660x_num_counters(dev)) {
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags =
- SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL |
- SDF_CMD_READ /* | SDF_CMD_WRITE */ ;
- s->n_chan = 3;
- s->maxdata = 0xffffffff;
- s->insn_read = ni_660x_GPCT_rinsn;
- s->insn_write = ni_660x_GPCT_winsn;
- s->insn_config = ni_660x_GPCT_insn_config;
- s->do_cmd = &ni_660x_cmd;
- s->len_chanlist = 1;
- s->do_cmdtest = &ni_660x_cmdtest;
- s->cancel = &ni_660x_cancel;
- s->poll = &ni_660x_input_poll;
- s->async_dma_dir = DMA_BIDIRECTIONAL;
- s->buf_change = &ni_660x_buf_change;
- s->private = &private(dev)->counter_dev->counters[i];
-
- private(dev)->counter_dev->counters[i].chip_index =
- i / counters_per_chip;
- private(dev)->counter_dev->counters[i].counter_index =
- i % counters_per_chip;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
- }
- for (i = 0; i < board(dev)->n_chips; ++i)
- init_tio_chip(dev, i);
-
- for (i = 0; i < ni_660x_num_counters(dev); ++i)
- ni_tio_init_counter(&private(dev)->counter_dev->counters[i]);
-
- for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
- if (i < min_counter_pfi_chan)
- ni_660x_set_pfi_routing(dev, i, pfi_output_select_do);
- else
- ni_660x_set_pfi_routing(dev, i,
- pfi_output_select_counter);
- ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z);
- }
- /* to be safe, set counterswap bits on tio chips after all the counter
- outputs have been set to high impedance mode */
- for (i = 0; i < board(dev)->n_chips; ++i)
- set_tio_counterswap(dev, i);
-
- ret = request_irq(mite_irq(private(dev)->mite), ni_660x_interrupt,
- IRQF_SHARED, "ni_660x", dev);
- if (ret < 0) {
- dev_warn(dev->class_dev, " irq not available\n");
- return ret;
- }
- dev->irq = mite_irq(private(dev)->mite);
- global_interrupt_config_bits = Global_Int_Enable_Bit;
- if (board(dev)->n_chips > 1)
- global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
- ni_660x_write_register(dev, 0, global_interrupt_config_bits,
- GlobalInterruptConfigRegister);
- dev_info(dev->class_dev, "ni_660x: %s attached\n", dev->board_name);
- return 0;
-}
-
-static void ni_660x_detach(struct comedi_device *dev)
-{
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->private) {
- if (private(dev)->counter_dev)
- ni_gpct_device_destroy(private(dev)->counter_dev);
- if (private(dev)->mite) {
- ni_660x_free_mite_rings(dev);
- mite_unsetup(private(dev)->mite);
- mite_free(private(dev)->mite);
- }
- }
-}
-
static int
ni_660x_GPCT_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
@@ -1196,17 +994,17 @@ ni_660x_GPCT_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
static void init_tio_chip(struct comedi_device *dev, int chipset)
{
+ struct ni_660x_private *devpriv = dev->private;
unsigned i;
/* init dma configuration register */
- private(dev)->dma_configuration_soft_copies[chipset] = 0;
+ devpriv->dma_configuration_soft_copies[chipset] = 0;
for (i = 0; i < MAX_DMA_CHANNEL; ++i) {
- private(dev)->dma_configuration_soft_copies[chipset] |=
+ devpriv->dma_configuration_soft_copies[chipset] |=
dma_select_bits(i, dma_selection_none) & dma_select_mask(i);
}
ni_660x_write_register(dev, chipset,
- private(dev)->
- dma_configuration_soft_copies[chipset],
+ devpriv->dma_configuration_soft_copies[chipset],
DMAConfigRegister);
for (i = 0; i < NUM_PFI_CHANNELS; ++i)
ni_660x_write_register(dev, chipset, 0, IOConfigReg(i));
@@ -1251,6 +1049,7 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev,
unsigned pfi_channel,
unsigned output_select)
{
+ const struct ni_660x_board *board = comedi_board(dev);
static const unsigned counter_4_7_first_pfi = 8;
static const unsigned counter_4_7_last_pfi = 23;
unsigned active_chipset = 0;
@@ -1258,7 +1057,7 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev,
unsigned active_bits;
unsigned idle_bits;
- if (board(dev)->n_chips > 1) {
+ if (board->n_chips > 1) {
if (output_select == pfi_output_select_counter &&
pfi_channel >= counter_4_7_first_pfi &&
pfi_channel <= counter_4_7_last_pfi) {
@@ -1294,6 +1093,8 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev,
static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan,
unsigned source)
{
+ struct ni_660x_private *devpriv = dev->private;
+
if (source > num_pfi_output_selects)
return -EINVAL;
if (source == pfi_output_select_high_Z)
@@ -1305,76 +1106,249 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan,
if (source == pfi_output_select_do)
return -EINVAL;
}
- BUG_ON(chan >= NUM_PFI_CHANNELS);
- private(dev)->pfi_output_selects[chan] = source;
- if (private(dev)->pfi_direction_bits & (((uint64_t) 1) << chan))
+ devpriv->pfi_output_selects[chan] = source;
+ if (devpriv->pfi_direction_bits & (((uint64_t) 1) << chan))
ni_660x_select_pfi_output(dev, chan,
- private(dev)->
- pfi_output_selects[chan]);
+ devpriv->pfi_output_selects[chan]);
return 0;
}
-static unsigned ni_660x_get_pfi_routing(struct comedi_device *dev,
- unsigned chan)
-{
- BUG_ON(chan >= NUM_PFI_CHANNELS);
- return private(dev)->pfi_output_selects[chan];
-}
-
-static void ni660x_config_filter(struct comedi_device *dev,
- unsigned pfi_channel,
- enum ni_gpct_filter_select filter)
-{
- unsigned bits = ni_660x_read_register(dev, 0, IOConfigReg(pfi_channel));
- bits &= ~pfi_input_select_mask(pfi_channel);
- bits |= pfi_input_select_bits(pfi_channel, filter);
- ni_660x_write_register(dev, 0, bits, IOConfigReg(pfi_channel));
-}
-
static int ni_660x_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- int chan = CR_CHAN(insn->chanspec);
-
- /* The input or output configuration of each digital line is
- * configured by a special insn_config instruction. chanspec
- * contains the channel to be changed, and data[0] contains the
- * value COMEDI_INPUT or COMEDI_OUTPUT. */
+ struct ni_660x_private *devpriv = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ uint64_t bit = 1ULL << chan;
+ unsigned int val;
+ int ret;
switch (data[0]) {
case INSN_CONFIG_DIO_OUTPUT:
- private(dev)->pfi_direction_bits |= ((uint64_t) 1) << chan;
+ devpriv->pfi_direction_bits |= bit;
ni_660x_select_pfi_output(dev, chan,
- private(dev)->
- pfi_output_selects[chan]);
+ devpriv->pfi_output_selects[chan]);
break;
+
case INSN_CONFIG_DIO_INPUT:
- private(dev)->pfi_direction_bits &= ~(((uint64_t) 1) << chan);
+ devpriv->pfi_direction_bits &= ~bit;
ni_660x_select_pfi_output(dev, chan, pfi_output_select_high_Z);
break;
+
case INSN_CONFIG_DIO_QUERY:
- data[1] =
- (private(dev)->pfi_direction_bits &
- (((uint64_t) 1) << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
- return 0;
+ data[1] = (devpriv->pfi_direction_bits & bit) ? COMEDI_OUTPUT
+ : COMEDI_INPUT;
+ break;
+
case INSN_CONFIG_SET_ROUTING:
- return ni_660x_set_pfi_routing(dev, chan, data[1]);
+ ret = ni_660x_set_pfi_routing(dev, chan, data[1]);
+ if (ret)
+ return ret;
break;
+
case INSN_CONFIG_GET_ROUTING:
- data[1] = ni_660x_get_pfi_routing(dev, chan);
+ data[1] = devpriv->pfi_output_selects[chan];
break;
+
case INSN_CONFIG_FILTER:
- ni660x_config_filter(dev, chan, data[1]);
+ val = ni_660x_read_register(dev, 0, IOConfigReg(chan));
+ val &= ~pfi_input_select_mask(chan);
+ val |= pfi_input_select_bits(chan, data[1]);
+ ni_660x_write_register(dev, 0, val, IOConfigReg(chan));
break;
+
default:
return -EINVAL;
- break;
}
+
+ return insn->n;
+}
+
+static int ni_660x_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ const struct ni_660x_board *board;
+ struct ni_660x_private *devpriv;
+ struct comedi_subdevice *s;
+ int ret;
+ unsigned i;
+ unsigned global_interrupt_config_bits;
+
+ ret = ni_660x_allocate_private(dev);
+ if (ret < 0)
+ return ret;
+ devpriv = dev->private;
+
+ dev->board_ptr = ni_660x_find_boardinfo(pcidev);
+ if (!dev->board_ptr)
+ return -ENODEV;
+ board = comedi_board(dev);
+
+ devpriv->mite = mite_alloc(pcidev);
+ if (!devpriv->mite)
+ return -ENOMEM;
+
+ dev->board_name = board->name;
+
+ ret = mite_setup2(devpriv->mite, 1);
+ if (ret < 0) {
+ dev_warn(dev->class_dev, "error setting up mite\n");
+ return ret;
+ }
+
+ ret = ni_660x_alloc_mite_rings(dev);
+ if (ret < 0)
+ return ret;
+
+ ret = comedi_alloc_subdevices(dev, 2 + NI_660X_MAX_NUM_COUNTERS);
+ if (ret)
+ return ret;
+
+ s = &dev->subdevices[0];
+ /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */
+ s->type = COMEDI_SUBD_UNUSED;
+
+ s = &dev->subdevices[NI_660X_DIO_SUBDEV];
+ /* DIGITAL I/O SUBDEVICE */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = NUM_PFI_CHANNELS;
+ s->maxdata = 1;
+ 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);
+
+ devpriv->counter_dev = ni_gpct_device_construct(dev,
+ &ni_gpct_write_register,
+ &ni_gpct_read_register,
+ ni_gpct_variant_660x,
+ ni_660x_num_counters
+ (dev));
+ if (devpriv->counter_dev == NULL)
+ return -ENOMEM;
+ for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) {
+ s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)];
+ if (i < ni_660x_num_counters(dev)) {
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL |
+ SDF_CMD_READ /* | SDF_CMD_WRITE */ ;
+ s->n_chan = 3;
+ s->maxdata = 0xffffffff;
+ s->insn_read = ni_660x_GPCT_rinsn;
+ s->insn_write = ni_660x_GPCT_winsn;
+ s->insn_config = ni_660x_GPCT_insn_config;
+ s->do_cmd = &ni_660x_cmd;
+ s->len_chanlist = 1;
+ s->do_cmdtest = &ni_660x_cmdtest;
+ s->cancel = &ni_660x_cancel;
+ s->poll = &ni_660x_input_poll;
+ s->async_dma_dir = DMA_BIDIRECTIONAL;
+ s->buf_change = &ni_660x_buf_change;
+ s->private = &devpriv->counter_dev->counters[i];
+
+ devpriv->counter_dev->counters[i].chip_index =
+ i / counters_per_chip;
+ devpriv->counter_dev->counters[i].counter_index =
+ i % counters_per_chip;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ }
+ for (i = 0; i < board->n_chips; ++i)
+ init_tio_chip(dev, i);
+
+ for (i = 0; i < ni_660x_num_counters(dev); ++i)
+ ni_tio_init_counter(&devpriv->counter_dev->counters[i]);
+
+ for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
+ if (i < min_counter_pfi_chan)
+ ni_660x_set_pfi_routing(dev, i, pfi_output_select_do);
+ else
+ ni_660x_set_pfi_routing(dev, i,
+ pfi_output_select_counter);
+ ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z);
+ }
+ /* to be safe, set counterswap bits on tio chips after all the counter
+ outputs have been set to high impedance mode */
+ for (i = 0; i < board->n_chips; ++i)
+ set_tio_counterswap(dev, i);
+
+ ret = request_irq(mite_irq(devpriv->mite), ni_660x_interrupt,
+ IRQF_SHARED, "ni_660x", dev);
+ if (ret < 0) {
+ dev_warn(dev->class_dev, " irq not available\n");
+ return ret;
+ }
+ dev->irq = mite_irq(devpriv->mite);
+ global_interrupt_config_bits = Global_Int_Enable_Bit;
+ if (board->n_chips > 1)
+ global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
+ ni_660x_write_register(dev, 0, global_interrupt_config_bits,
+ GlobalInterruptConfigRegister);
+ dev_info(dev->class_dev, "ni_660x: %s attached\n", dev->board_name);
return 0;
}
+static void ni_660x_detach(struct comedi_device *dev)
+{
+ struct ni_660x_private *devpriv = dev->private;
+
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ if (devpriv) {
+ if (devpriv->counter_dev)
+ ni_gpct_device_destroy(devpriv->counter_dev);
+ if (devpriv->mite) {
+ ni_660x_free_mite_rings(dev);
+ mite_unsetup(devpriv->mite);
+ mite_free(devpriv->mite);
+ }
+ }
+}
+
+static struct comedi_driver ni_660x_driver = {
+ .driver_name = "ni_660x",
+ .module = THIS_MODULE,
+ .auto_attach = ni_660x_auto_attach,
+ .detach = ni_660x_detach,
+};
+
+static int ni_660x_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ return comedi_pci_auto_config(dev, &ni_660x_driver);
+}
+
+static void ni_660x_pci_remove(struct pci_dev *dev)
+{
+ comedi_pci_auto_unconfig(dev);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = {
+ {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c60)},
+ {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1310)},
+ {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1360)},
+ {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2cc0)},
+ {0}
+};
+MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
+
+static struct pci_driver ni_660x_pci_driver = {
+ .name = "ni_660x",
+ .id_table = ni_660x_pci_table,
+ .probe = ni_660x_pci_probe,
+ .remove = ni_660x_pci_remove,
+};
+module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver);
+
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c
index eac6dc047bb..272caeb6ece 100644
--- a/drivers/staging/comedi/drivers/ni_670x.c
+++ b/drivers/staging/comedi/drivers/ni_670x.c
@@ -201,19 +201,21 @@ ni_670x_find_boardinfo(struct pci_dev *pcidev)
return NULL;
}
-static int __devinit ni_670x_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int ni_670x_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct ni_670x_board *thisboard;
struct ni_670x_private *devpriv;
struct comedi_subdevice *s;
int ret;
int i;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret < 0)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
dev->board_ptr = ni_670x_find_boardinfo(pcidev);
if (!dev->board_ptr)
return -ENODEV;
@@ -297,17 +299,17 @@ static void ni_670x_detach(struct comedi_device *dev)
static struct comedi_driver ni_670x_driver = {
.driver_name = "ni_670x",
.module = THIS_MODULE,
- .attach_pci = ni_670x_attach_pci,
+ .auto_attach = ni_670x_auto_attach,
.detach = ni_670x_detach,
};
-static int __devinit ni_670x_pci_probe(struct pci_dev *dev,
+static int ni_670x_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &ni_670x_driver);
}
-static void __devexit ni_670x_pci_remove(struct pci_dev *dev)
+static void ni_670x_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -320,10 +322,10 @@ static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = {
MODULE_DEVICE_TABLE(pci, ni_670x_pci_table);
static struct pci_driver ni_670x_pci_driver = {
- .name ="ni_670x",
+ .name = "ni_670x",
.id_table = ni_670x_pci_table,
.probe = ni_670x_pci_probe,
- .remove = __devexit_p(ni_670x_pci_remove),
+ .remove = ni_670x_pci_remove,
};
module_comedi_pci_driver(ni_670x_driver, ni_670x_pci_driver);
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
index 83950807b67..06de25bb2f5 100644
--- a/drivers/staging/comedi/drivers/ni_at_a2150.c
+++ b/drivers/staging/comedi/drivers/ni_at_a2150.c
@@ -169,8 +169,6 @@ struct a2150_private {
int config_bits; /* config register bits */
};
-#define devpriv ((struct a2150_private *)dev->private)
-
static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
@@ -182,6 +180,8 @@ static int a2150_set_chanlist(struct comedi_device *dev,
static void ni_dump_regs(struct comedi_device *dev)
{
+ struct a2150_private *devpriv = dev->private;
+
printk("config bits 0x%x\n", devpriv->config_bits);
printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits);
printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG));
@@ -196,6 +196,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
int status;
unsigned long flags;
struct comedi_device *dev = d;
+ struct a2150_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async;
struct comedi_cmd *cmd;
@@ -300,6 +301,8 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct a2150_private *devpriv = dev->private;
+
/* disable dma on card */
devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
@@ -342,37 +345,21 @@ static int a2150_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < thisboard->ai_speed) {
- cmd->convert_arg = thisboard->ai_speed;
- err++;
- }
- }
- if (!cmd->chanlist_len) {
- cmd->chanlist_len = 1;
- err++;
- }
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) {
- if (!cmd->stop_arg) {
- cmd->stop_arg = 1;
- err++;
- }
- } else { /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ thisboard->ai_speed);
+
+ err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -425,6 +412,7 @@ static int a2150_ai_cmdtest(struct comedi_device *dev,
static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct a2150_private *devpriv = dev->private;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
unsigned long lock_flags;
@@ -536,6 +524,7 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct a2150_private *devpriv = dev->private;
unsigned int i, n;
static const int timeout = 100000;
static const int filter_delay = 36;
@@ -615,6 +604,7 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
int flags)
{
+ struct a2150_private *devpriv = dev->private;
int lub, glb, temp;
int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
int i, j;
@@ -689,6 +679,8 @@ static int a2150_set_chanlist(struct comedi_device *dev,
unsigned int start_channel,
unsigned int num_channels)
{
+ struct a2150_private *devpriv = dev->private;
+
if (start_channel + num_channels > 4)
return -1;
@@ -727,6 +719,7 @@ static int a2150_probe(struct comedi_device *dev)
static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ struct a2150_private *devpriv;
struct comedi_subdevice *s;
unsigned long iobase = it->options[0];
unsigned int irq = it->options[1];
@@ -749,9 +742,10 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
printk("\n");
- /* allocate and initialize dev->private */
- if (alloc_private(dev, sizeof(struct a2150_private)) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
if (iobase == 0) {
printk(" io base address required\n");
@@ -855,6 +849,8 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
static void a2150_detach(struct comedi_device *dev)
{
+ struct a2150_private *devpriv = dev->private;
+
if (dev->iobase) {
outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
release_region(dev->iobase, A2150_SIZE);
diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c
index 93938cec93e..907f65cdbdc 100644
--- a/drivers/staging/comedi/drivers/ni_at_ao.c
+++ b/drivers/staging/comedi/drivers/ni_at_ao.c
@@ -167,10 +167,10 @@ struct atao_private {
unsigned int ao_readback[10];
};
-#define devpriv ((struct atao_private *)dev->private)
-
static void atao_reset(struct comedi_device *dev)
{
+ struct atao_private *devpriv = dev->private;
+
/* This is the reset sequence described in the manual */
devpriv->cfg1 = 0;
@@ -202,6 +202,7 @@ static void atao_reset(struct comedi_device *dev)
static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct atao_private *devpriv = dev->private;
int i;
int chan = CR_CHAN(insn->chanspec);
short bits;
@@ -226,6 +227,7 @@ static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
static int atao_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct atao_private *devpriv = dev->private;
int i;
int chan = CR_CHAN(insn->chanspec);
@@ -254,6 +256,7 @@ static int atao_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct atao_private *devpriv = dev->private;
int chan = CR_CHAN(insn->chanspec);
unsigned int mask, bit;
@@ -309,6 +312,7 @@ 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 bitstring, bit;
unsigned int chan = CR_CHAN(insn->chanspec);
@@ -331,6 +335,7 @@ static int atao_calib_insn_write(struct comedi_device *dev,
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;
unsigned long iobase;
int ao_unipolar;
@@ -351,8 +356,10 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
dev->board_name = board->name;
- if (alloc_private(dev, sizeof(struct atao_private)) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_alloc_subdevices(dev, 4);
if (ret)
diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c
index cac25572f6b..2cc29965e15 100644
--- a/drivers/staging/comedi/drivers/ni_atmio.c
+++ b/drivers/staging/comedi/drivers/ni_atmio.c
@@ -284,8 +284,6 @@ struct ni_private {
};
-#define devpriv ((struct ni_private *)dev->private)
-
/* How we access registers */
#define ni_writel(a, b) (outl((a), (b)+dev->iobase))
@@ -303,6 +301,7 @@ struct ni_private {
static void ni_atmio_win_out(struct comedi_device *dev, uint16_t data, int addr)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->window_lock, flags);
@@ -317,6 +316,7 @@ static void ni_atmio_win_out(struct comedi_device *dev, uint16_t data, int addr)
static uint16_t ni_atmio_win_in(struct comedi_device *dev, int addr)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
uint16_t ret;
@@ -406,16 +406,17 @@ static int ni_getboardtype(struct comedi_device *dev)
static int ni_atmio_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
+ struct ni_private *devpriv;
struct pnp_dev *isapnp_dev;
int ret;
unsigned long iobase;
int board;
unsigned int irq;
- /* allocate private area */
ret = ni_alloc_private(dev);
- if (ret < 0)
+ if (ret)
return ret;
+ devpriv = dev->private;
devpriv->stc_writew = &ni_atmio_win_out;
devpriv->stc_readw = &ni_atmio_win_in;
@@ -499,6 +500,8 @@ static int ni_atmio_attach(struct comedi_device *dev,
static void ni_atmio_detach(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
+
mio_common_detach(dev);
if (dev->iobase)
release_region(dev->iobase, NI_SIZE);
diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c
index e91a620f9db..4a17494f55e 100644
--- a/drivers/staging/comedi/drivers/ni_atmio16d.c
+++ b/drivers/staging/comedi/drivers/ni_atmio16d.c
@@ -102,7 +102,6 @@ Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d)
#define CLOCK_100_HZ 0x8F25
/* Other miscellaneous defines */
#define ATMIO16D_SIZE 32 /* bus address range */
-#define devpriv ((struct atmio16d_private *)dev->private)
#define ATMIO16D_TIMEOUT 10
struct atmio16_board_t {
@@ -202,6 +201,7 @@ static void reset_counters(struct comedi_device *dev)
static void reset_atmio16d(struct comedi_device *dev)
{
+ struct atmio16d_private *devpriv = dev->private;
int i;
/* now we need to initialize the board */
@@ -271,51 +271,32 @@ static int atmio16d_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
if (cmd->scan_begin_src == TRIG_FOLLOW) {
/* internal trigger */
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
} else {
#if 0
/* external trigger */
/* should be level/edge, hi/lo specification here */
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
#endif
}
- if (cmd->convert_arg < 10000) {
- cmd->convert_arg = 10000;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000);
#if 0
- if (cmd->convert_arg > SLOWEST_TIMER) {
- cmd->convert_arg = SLOWEST_TIMER;
- err++;
- }
+ err |= cfc_check_trigger_arg_max(&cmd->convert_arg, SLOWEST_TIMER);
#endif
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
if (cmd->stop_src == TRIG_COUNT) {
/* any count is allowed */
- } else {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ } else { /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
}
if (err)
@@ -327,6 +308,7 @@ static int atmio16d_ai_cmdtest(struct comedi_device *dev,
static int atmio16d_ai_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct atmio16d_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
unsigned int timer, base_clock;
unsigned int sample_count, tmp, chan, gain;
@@ -486,6 +468,7 @@ static int atmio16d_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct atmio16d_private *devpriv = dev->private;
int i, t;
int chan;
int gain;
@@ -539,6 +522,7 @@ static int atmio16d_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct atmio16d_private *devpriv = dev->private;
int i;
for (i = 0; i < insn->n; i++)
@@ -550,6 +534,7 @@ static int atmio16d_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct atmio16d_private *devpriv = dev->private;
int i;
int chan;
int d;
@@ -596,6 +581,7 @@ static int atmio16d_dio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct atmio16d_private *devpriv = dev->private;
int i;
int mask;
@@ -651,6 +637,7 @@ static int atmio16d_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
const struct atmio16_board_t *board = comedi_board(dev);
+ struct atmio16d_private *devpriv;
unsigned int irq;
unsigned long iobase;
int ret;
@@ -672,9 +659,10 @@ static int atmio16d_attach(struct comedi_device *dev,
if (ret)
return ret;
- ret = alloc_private(dev, sizeof(struct atmio16d_private));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
/* reset the atmio16d hardware */
reset_atmio16d(dev);
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
index 0ca222bbcbe..7b333353c5d 100644
--- a/drivers/staging/comedi/drivers/ni_daq_dio24.c
+++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c
@@ -96,8 +96,6 @@ struct dio24_private {
int data; /* number of data points left to be taken */
};
-#define devpriv ((struct dio24_private *)dev->private)
-
static struct comedi_driver driver_dio24 = {
.driver_name = "ni_daq_dio24",
.module = THIS_MODULE,
@@ -110,6 +108,7 @@ static struct comedi_driver driver_dio24 = {
static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ struct dio24_private *devpriv;
struct comedi_subdevice *s;
unsigned long iobase = 0;
#ifdef incomplete
@@ -118,9 +117,10 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct pcmcia_device *link;
int ret;
- /* allocate and initialize dev->private */
- if (alloc_private(dev, sizeof(struct dio24_private)) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
/* get base address, irq etc. based on bustype */
switch (thisboard->bustype) {
@@ -202,7 +202,7 @@ static int dio24_cs_attach(struct pcmcia_device *link)
{
struct local_info_t *local;
- printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n");
+ dev_info(&link->dev, "ni_daq_dio24: HOLA SOY YO - CS-attach!\n");
dev_dbg(&link->dev, "dio24_cs_attach()\n");
@@ -242,7 +242,7 @@ static void dio24_config(struct pcmcia_device *link)
{
int ret;
- printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
+ dev_info(&link->dev, "ni_daq_dio24: HOLA SOY YO! - config\n");
dev_dbg(&link->dev, "dio24_config\n");
@@ -265,7 +265,7 @@ static void dio24_config(struct pcmcia_device *link)
return;
failed:
- printk(KERN_INFO "Fallo");
+ dev_info(&link->dev, "Fallo");
dio24_release(link);
} /* dio24_config */
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index b5a19a0863f..d29c4d761ba 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -487,8 +487,6 @@ static const int dma_buffer_size = 0xff00;
/* 2 bytes per sample */
static const int sample_size = 2;
-#define devpriv ((struct labpc_private *)dev->private)
-
static inline int labpc_counter_load(struct comedi_device *dev,
unsigned long base_address,
unsigned int counter_number,
@@ -504,6 +502,7 @@ static inline int labpc_counter_load(struct comedi_device *dev,
int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
unsigned int irq, unsigned int dma_chan)
{
+ struct labpc_private *devpriv = dev->private;
struct comedi_subdevice *s;
int i;
unsigned long isr_flags;
@@ -697,18 +696,23 @@ labpc_pci_find_boardinfo(struct pci_dev *pcidev)
return NULL;
}
-static int __devinit labpc_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int labpc_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct labpc_private *devpriv;
unsigned long iobase;
unsigned int irq;
int ret;
if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS))
return -ENODEV;
- ret = alloc_private(dev, sizeof(struct labpc_private));
- if (ret < 0)
- return ret;
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
dev->board_ptr = labpc_pci_find_boardinfo(pcidev);
if (!dev->board_ptr)
return -ENODEV;
@@ -725,13 +729,15 @@ static int __devinit labpc_attach_pci(struct comedi_device *dev,
static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ struct labpc_private *devpriv;
unsigned long iobase = 0;
unsigned int irq = 0;
unsigned int dma_chan = 0;
- /* allocate and initialize dev->private */
- if (alloc_private(dev, sizeof(struct labpc_private)) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
/* get base address, irq etc. based on bustype */
switch (thisboard->bustype) {
@@ -770,6 +776,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
void labpc_common_detach(struct comedi_device *dev)
{
+ struct labpc_private *devpriv = dev->private;
struct comedi_subdevice *s;
if (!thisboard)
@@ -799,6 +806,8 @@ EXPORT_SYMBOL_GPL(labpc_common_detach);
static void labpc_clear_adc_fifo(const struct comedi_device *dev)
{
+ struct labpc_private *devpriv = dev->private;
+
devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
@@ -806,6 +815,7 @@ static void labpc_clear_adc_fifo(const struct comedi_device *dev)
static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct labpc_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&dev->spinlock, flags);
@@ -1016,56 +1026,34 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg == TRIG_NOW && cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ if (cmd->start_arg == TRIG_NOW)
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
if (!cmd->chanlist_len)
- err++;
+ err |= -EINVAL;
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ thisboard->ai_speed);
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < thisboard->ai_speed) {
- cmd->convert_arg = thisboard->ai_speed;
- err++;
- }
- }
/* make sure scan timing is not too fast */
if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->convert_src == TRIG_TIMER &&
- cmd->scan_begin_arg <
- cmd->convert_arg * cmd->chanlist_len) {
- cmd->scan_begin_arg =
- cmd->convert_arg * cmd->chanlist_len;
- err++;
- }
- if (cmd->scan_begin_arg <
- thisboard->ai_speed * cmd->chanlist_len) {
- cmd->scan_begin_arg =
- thisboard->ai_speed * cmd->chanlist_len;
- err++;
- }
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ cmd->convert_arg * cmd->chanlist_len);
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ thisboard->ai_speed * cmd->chanlist_len);
}
- /* stop source */
+
switch (cmd->stop_src) {
case TRIG_COUNT:
- if (!cmd->stop_arg) {
- cmd->stop_arg = 1;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
break;
case TRIG_NONE:
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
break;
/*
* TRIG_EXT doesn't care since it doesn't
@@ -1098,6 +1086,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct labpc_private *devpriv = dev->private;
int channel, range, aref;
#ifdef CONFIG_ISA_DMA_API
unsigned long irq_flags;
@@ -1365,6 +1354,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static irqreturn_t labpc_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct labpc_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async;
struct comedi_cmd *cmd;
@@ -1453,6 +1443,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
/* read all available samples from ai fifo */
static int labpc_drain_fifo(struct comedi_device *dev)
{
+ struct labpc_private *devpriv = dev->private;
unsigned int lsb, msb;
short data;
struct comedi_async *async = dev->read_subdev->async;
@@ -1488,6 +1479,7 @@ static int labpc_drain_fifo(struct comedi_device *dev)
#ifdef CONFIG_ISA_DMA_API
static void labpc_drain_dma(struct comedi_device *dev)
{
+ struct labpc_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async = s->async;
int status;
@@ -1541,6 +1533,8 @@ static void labpc_drain_dma(struct comedi_device *dev)
static void handle_isa_dma(struct comedi_device *dev)
{
+ struct labpc_private *devpriv = dev->private;
+
labpc_drain_dma(dev);
enable_dma(devpriv->dma_chan);
@@ -1555,6 +1549,8 @@ static void handle_isa_dma(struct comedi_device *dev)
static void labpc_drain_dregs(struct comedi_device *dev)
{
#ifdef CONFIG_ISA_DMA_API
+ struct labpc_private *devpriv = dev->private;
+
if (devpriv->current_transfer == isa_dma_transfer)
labpc_drain_dma(dev);
#endif
@@ -1565,6 +1561,7 @@ static void labpc_drain_dregs(struct comedi_device *dev)
static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct labpc_private *devpriv = dev->private;
int i, n;
int chan, range;
int lsb, msb;
@@ -1654,6 +1651,7 @@ static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct labpc_private *devpriv = dev->private;
int channel, range;
unsigned long flags;
int lsb, msb;
@@ -1695,6 +1693,8 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
static int labpc_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct labpc_private *devpriv = dev->private;
+
data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
return 1;
@@ -1704,6 +1704,8 @@ static int labpc_calib_read_insn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct labpc_private *devpriv = dev->private;
+
data[0] = devpriv->caldac[CR_CHAN(insn->chanspec)];
return 1;
@@ -1723,6 +1725,8 @@ static int labpc_eeprom_read_insn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct labpc_private *devpriv = dev->private;
+
data[0] = devpriv->eeprom_data[CR_CHAN(insn->chanspec)];
return 1;
@@ -1779,6 +1783,7 @@ static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd)
static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
enum scan_mode mode)
{
+ struct labpc_private *devpriv = dev->private;
/* max value for 16 bit counter in mode 2 */
const int max_counter_value = 0x10000;
/* min value for 16 bit counter in mode 2 */
@@ -1885,6 +1890,7 @@ static int labpc_dio_mem_callback(int dir, int port, int data,
static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
unsigned int value_width)
{
+ struct labpc_private *devpriv = dev->private;
int i;
for (i = 1; i <= value_width; i++) {
@@ -1909,6 +1915,7 @@ static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
/* lowlevel read from eeprom */
static unsigned int labpc_serial_in(struct comedi_device *dev)
{
+ struct labpc_private *devpriv = dev->private;
unsigned int value = 0;
int i;
const int value_width = 8; /* number of bits wide values are */
@@ -1938,6 +1945,7 @@ static unsigned int labpc_serial_in(struct comedi_device *dev)
static unsigned int labpc_eeprom_read(struct comedi_device *dev,
unsigned int address)
{
+ struct labpc_private *devpriv = dev->private;
unsigned int value;
/* bits to tell eeprom to expect a read */
const int read_instruction = 0x3;
@@ -1970,6 +1978,7 @@ static unsigned int labpc_eeprom_read(struct comedi_device *dev,
static int labpc_eeprom_write(struct comedi_device *dev,
unsigned int address, unsigned int value)
{
+ struct labpc_private *devpriv = dev->private;
const int write_enable_instruction = 0x6;
const int write_instruction = 0x2;
const int write_length = 8; /* 8 bit write lengths to eeprom */
@@ -2027,6 +2036,7 @@ static int labpc_eeprom_write(struct comedi_device *dev,
static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
{
+ struct labpc_private *devpriv = dev->private;
unsigned int value;
const int read_status_instruction = 0x5;
const int write_length = 8; /* 8 bit write lengths to eeprom */
@@ -2056,6 +2066,8 @@ static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
static void write_caldac(struct comedi_device *dev, unsigned int channel,
unsigned int value)
{
+ struct labpc_private *devpriv = dev->private;
+
if (value == devpriv->caldac[channel])
return;
devpriv->caldac[channel] = value;
@@ -2084,7 +2096,7 @@ static struct comedi_driver labpc_driver = {
.driver_name = DRV_NAME,
.module = THIS_MODULE,
.attach = labpc_attach,
- .attach_pci = labpc_attach_pci,
+ .auto_attach = labpc_auto_attach,
.detach = labpc_common_detach,
.num_names = ARRAY_SIZE(labpc_boards),
.board_name = &labpc_boards[0].name,
@@ -2098,13 +2110,13 @@ static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = {
};
MODULE_DEVICE_TABLE(pci, labpc_pci_table);
-static int __devinit labpc_pci_probe(struct pci_dev *dev,
+static int labpc_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &labpc_driver);
}
-static void __devexit labpc_pci_remove(struct pci_dev *dev)
+static void labpc_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -2113,7 +2125,7 @@ static struct pci_driver labpc_pci_driver = {
.name = DRV_NAME,
.id_table = labpc_pci_table,
.probe = labpc_pci_probe,
- .remove = __devexit_p(labpc_pci_remove)
+ .remove = labpc_pci_remove
};
module_comedi_pci_driver(labpc_driver, labpc_pci_driver);
#else
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
index eb0417eb6d7..bfe19fa7d66 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_cs.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c
@@ -127,13 +127,15 @@ static struct comedi_driver driver_labpc_cs = {
static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ struct labpc_private *devpriv;
unsigned long iobase = 0;
unsigned int irq = 0;
struct pcmcia_device *link;
- /* allocate and initialize dev->private */
- if (alloc_private(dev, sizeof(struct labpc_private)) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
/* get base address, irq etc. based on bustype */
switch (thisboard->bustype) {
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index 3e5fdae9316..56dc59908d3 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -410,6 +410,7 @@ static void get_last_sample_6143(struct comedi_device *dev);
static inline void ni_set_bitfield(struct comedi_device *dev, int reg,
unsigned bit_mask, unsigned bit_values)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
@@ -506,6 +507,7 @@ static inline void ni_set_gpct_dma_channel(struct comedi_device *dev,
static inline void ni_set_cdo_dma_channel(struct comedi_device *dev,
int mite_channel)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
@@ -525,6 +527,7 @@ static inline void ni_set_cdo_dma_channel(struct comedi_device *dev,
static int ni_request_ai_mite_channel(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
@@ -545,6 +548,7 @@ static int ni_request_ai_mite_channel(struct comedi_device *dev)
static int ni_request_ao_mite_channel(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
@@ -567,6 +571,7 @@ static int ni_request_gpct_mite_channel(struct comedi_device *dev,
unsigned gpct_index,
enum comedi_io_direction direction)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
struct mite_channel *mite_chan;
@@ -595,6 +600,7 @@ static int ni_request_gpct_mite_channel(struct comedi_device *dev,
static int ni_request_cdo_mite_channel(struct comedi_device *dev)
{
#ifdef PCIDMA
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
@@ -617,6 +623,7 @@ static int ni_request_cdo_mite_channel(struct comedi_device *dev)
static void ni_release_ai_mite_channel(struct comedi_device *dev)
{
#ifdef PCIDMA
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
@@ -632,6 +639,7 @@ static void ni_release_ai_mite_channel(struct comedi_device *dev)
static void ni_release_ao_mite_channel(struct comedi_device *dev)
{
#ifdef PCIDMA
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
@@ -648,6 +656,7 @@ static void ni_release_ao_mite_channel(struct comedi_device *dev)
static void ni_release_gpct_mite_channel(struct comedi_device *dev,
unsigned gpct_index)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
BUG_ON(gpct_index >= NUM_GPCT);
@@ -669,6 +678,7 @@ static void ni_release_gpct_mite_channel(struct comedi_device *dev,
static void ni_release_cdo_mite_channel(struct comedi_device *dev)
{
#ifdef PCIDMA
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
@@ -686,6 +696,8 @@ static void ni_release_cdo_mite_channel(struct comedi_device *dev)
static void ni_e_series_enable_second_irq(struct comedi_device *dev,
unsigned gpct_index, short enable)
{
+ struct ni_private *devpriv = dev->private;
+
if (boardtype.reg_type & ni_reg_m_series_mask)
return;
switch (gpct_index) {
@@ -716,6 +728,8 @@ static void ni_e_series_enable_second_irq(struct comedi_device *dev,
static void ni_clear_ai_fifo(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
+
if (boardtype.reg_type == ni_reg_6143) {
/* Flush the 6143 data FIFO */
ni_writel(0x10, AIFIFO_Control_6143); /* Flush fifo */
@@ -742,13 +756,17 @@ static void ni_clear_ai_fifo(struct comedi_device *dev)
static void win_out2(struct comedi_device *dev, uint32_t data, int reg)
{
+ struct ni_private *devpriv = dev->private;
+
devpriv->stc_writew(dev, data >> 16, reg);
devpriv->stc_writew(dev, data & 0xffff, reg + 1);
}
static uint32_t win_in2(struct comedi_device *dev, int reg)
{
+ struct ni_private *devpriv = dev->private;
uint32_t bits;
+
bits = devpriv->stc_readw(dev, reg) << 16;
bits |= devpriv->stc_readw(dev, reg + 1);
return bits;
@@ -758,6 +776,7 @@ static uint32_t win_in2(struct comedi_device *dev, int reg)
static inline void ni_ao_win_outw(struct comedi_device *dev, uint16_t data,
int addr)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->window_lock, flags);
@@ -769,6 +788,7 @@ static inline void ni_ao_win_outw(struct comedi_device *dev, uint16_t data,
static inline void ni_ao_win_outl(struct comedi_device *dev, uint32_t data,
int addr)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->window_lock, flags);
@@ -779,6 +799,7 @@ static inline void ni_ao_win_outl(struct comedi_device *dev, uint32_t data,
static inline unsigned short ni_ao_win_inw(struct comedi_device *dev, int addr)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
unsigned short data;
@@ -814,6 +835,7 @@ static inline void ni_set_bits(struct comedi_device *dev, int reg,
static irqreturn_t ni_E_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct ni_private *devpriv = dev->private;
unsigned short a_status;
unsigned short b_status;
unsigned int ai_mite_status = 0;
@@ -872,6 +894,7 @@ static irqreturn_t ni_E_interrupt(int irq, void *d)
#ifdef PCIDMA
static void ni_sync_ai_dma(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
unsigned long flags;
@@ -884,6 +907,7 @@ static void ni_sync_ai_dma(struct comedi_device *dev)
static void mite_handle_b_linkc(struct mite_struct *mite,
struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV];
unsigned long flags;
@@ -896,6 +920,7 @@ static void mite_handle_b_linkc(struct mite_struct *mite,
static int ni_ao_wait_for_dma_load(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
static const int timeout = 10000;
int i;
for (i = 0; i < timeout; i++) {
@@ -918,6 +943,8 @@ static int ni_ao_wait_for_dma_load(struct comedi_device *dev)
#endif /* PCIDMA */
static void ni_handle_eos(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct ni_private *devpriv = dev->private;
+
if (devpriv->aimode == AIMODE_SCAN) {
#ifdef PCIDMA
static const int timeout = 10;
@@ -984,6 +1011,7 @@ static void handle_gpct_interrupt(struct comedi_device *dev,
unsigned short counter_index)
{
#ifdef PCIDMA
+ struct ni_private *devpriv = dev->private;
struct comedi_subdevice *s;
s = &dev->subdevices[NI_GPCT_SUBDEV(counter_index)];
@@ -997,6 +1025,7 @@ static void handle_gpct_interrupt(struct comedi_device *dev,
static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status)
{
+ struct ni_private *devpriv = dev->private;
unsigned short ack = 0;
if (a_status & AI_SC_TC_St) {
@@ -1019,6 +1048,7 @@ static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status)
static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
unsigned ai_mite_status)
{
+ struct ni_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
/* 67xx boards don't have ai subdevice, but their gpct0 might generate an a interrupt */
@@ -1122,7 +1152,9 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status)
{
+ struct ni_private *devpriv = dev->private;
unsigned short ack = 0;
+
if (b_status & AO_BC_TC_St) {
ack |= AO_BC_TC_Interrupt_Ack;
}
@@ -1151,8 +1183,10 @@ static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status)
static void handle_b_interrupt(struct comedi_device *dev,
unsigned short b_status, unsigned ao_mite_status)
{
+ struct ni_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV];
/* unsigned short ack=0; */
+
#ifdef DEBUG_INTERRUPT
printk("ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n",
b_status, ao_mite_status);
@@ -1340,6 +1374,7 @@ static int ni_ao_fifo_half_empty(struct comedi_device *dev,
static int ni_ao_prep_fifo(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct ni_private *devpriv = dev->private;
int n;
/* reset fifo */
@@ -1364,6 +1399,7 @@ static int ni_ao_prep_fifo(struct comedi_device *dev,
static void ni_ai_fifo_read(struct comedi_device *dev,
struct comedi_subdevice *s, int n)
{
+ struct ni_private *devpriv = dev->private;
struct comedi_async *async = s->async;
int i;
@@ -1434,6 +1470,7 @@ static void ni_handle_fifo_half_full(struct comedi_device *dev)
#ifdef PCIDMA
static int ni_ai_drain_dma(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
int i;
static const int timeout = 10000;
unsigned long flags;
@@ -1471,6 +1508,7 @@ static int ni_ai_drain_dma(struct comedi_device *dev)
*/
static void ni_handle_fifo_dregs(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
short data[2];
u32 dl;
@@ -1535,6 +1573,7 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev)
static void get_last_sample_611x(struct comedi_device *dev)
{
+ struct ni_private *devpriv __maybe_unused = dev->private;
struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
short data;
u32 dl;
@@ -1552,6 +1591,7 @@ static void get_last_sample_611x(struct comedi_device *dev)
static void get_last_sample_6143(struct comedi_device *dev)
{
+ struct ni_private *devpriv __maybe_unused = dev->private;
struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
short data;
u32 dl;
@@ -1574,11 +1614,13 @@ static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
void *data, unsigned int num_bytes,
unsigned int chan_index)
{
+ struct ni_private *devpriv = dev->private;
struct comedi_async *async = s->async;
unsigned int i;
unsigned int length = num_bytes / bytes_per_sample(s);
short *array = data;
unsigned int *larray = data;
+
for (i = 0; i < length; i++) {
#ifdef PCIDMA
if (s->subdev_flags & SDF_LSAMPL)
@@ -1599,6 +1641,7 @@ static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
static int ni_ai_setup_MITE_dma(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
int retval;
unsigned long flags;
@@ -1638,6 +1681,7 @@ static int ni_ai_setup_MITE_dma(struct comedi_device *dev)
static int ni_ao_setup_MITE_dma(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV];
int retval;
unsigned long flags;
@@ -1676,6 +1720,8 @@ static int ni_ao_setup_MITE_dma(struct comedi_device *dev)
static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct ni_private *devpriv = dev->private;
+
ni_release_ai_mite_channel(dev);
/* ai configuration */
devpriv->stc_writew(dev, AI_Configuration_Start | AI_Reset,
@@ -1786,6 +1832,7 @@ static int ni_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
int i, n;
const unsigned int mask = (1 << boardtype.adbits) - 1;
unsigned signbits;
@@ -1881,7 +1928,9 @@ static int ni_ai_insn_read(struct comedi_device *dev,
static void ni_prime_channelgain_list(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
int i;
+
devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register);
for (i = 0; i < NI_TIMEOUT; ++i) {
if (!(devpriv->stc_readw(dev,
@@ -1899,6 +1948,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
unsigned int n_chan,
unsigned int *list)
{
+ struct ni_private *devpriv = dev->private;
unsigned int chan, range, aref;
unsigned int i;
unsigned offset;
@@ -2004,6 +2054,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
static void ni_load_channelgain_list(struct comedi_device *dev,
unsigned int n_chan, unsigned int *list)
{
+ struct ni_private *devpriv = dev->private;
unsigned int chan, range, aref;
unsigned int i;
unsigned int hi, lo;
@@ -2122,7 +2173,9 @@ static void ni_load_channelgain_list(struct comedi_device *dev,
static int ni_ns_to_timer(const struct comedi_device *dev, unsigned nanosec,
int round_mode)
{
+ struct ni_private *devpriv = dev->private;
int divider;
+
switch (round_mode) {
case TRIG_ROUND_NEAREST:
default:
@@ -2140,6 +2193,8 @@ static int ni_ns_to_timer(const struct comedi_device *dev, unsigned nanosec,
static unsigned ni_timer_to_ns(const struct comedi_device *dev, int timer)
{
+ struct ni_private *devpriv = dev->private;
+
return devpriv->clock_ns * (timer + 1);
}
@@ -2162,6 +2217,7 @@ static unsigned ni_min_ai_scan_period_ns(struct comedi_device *dev,
static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
+ struct ni_private *devpriv = dev->private;
int err = 0;
int tmp;
unsigned int sources;
@@ -2200,7 +2256,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
if (cmd->start_src == TRIG_EXT) {
/* external trigger */
@@ -2209,30 +2265,17 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if (tmp > 16)
tmp = 16;
tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
- if (cmd->start_arg != tmp) {
- cmd->start_arg = tmp;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, tmp);
} else {
- if (cmd->start_arg != 0) {
- /* true for both TRIG_NOW and TRIG_INT */
- cmd->start_arg = 0;
- err++;
- }
+ /* true for both TRIG_NOW and TRIG_INT */
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
}
+
if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->scan_begin_arg < ni_min_ai_scan_period_ns(dev,
- cmd->
- chanlist_len))
- {
- cmd->scan_begin_arg =
- ni_min_ai_scan_period_ns(dev, cmd->chanlist_len);
- err++;
- }
- if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) {
- cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ ni_min_ai_scan_period_ns(dev, cmd->chanlist_len));
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
+ devpriv->clock_ns * 0xffffff);
} else if (cmd->scan_begin_src == TRIG_EXT) {
/* external trigger */
unsigned int tmp = CR_CHAN(cmd->scan_begin_arg);
@@ -2240,32 +2283,20 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if (tmp > 16)
tmp = 16;
tmp |= (cmd->scan_begin_arg & (CR_INVERT | CR_EDGE));
- if (cmd->scan_begin_arg != tmp) {
- cmd->scan_begin_arg = tmp;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, tmp);
} else { /* TRIG_OTHER */
- if (cmd->scan_begin_arg) {
- cmd->scan_begin_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
}
+
if (cmd->convert_src == TRIG_TIMER) {
if ((boardtype.reg_type == ni_reg_611x)
|| (boardtype.reg_type == ni_reg_6143)) {
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
} else {
- if (cmd->convert_arg < boardtype.ai_speed) {
- cmd->convert_arg = boardtype.ai_speed;
- err++;
- }
- if (cmd->convert_arg > devpriv->clock_ns * 0xffff) {
- cmd->convert_arg = devpriv->clock_ns * 0xffff;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ boardtype.ai_speed);
+ err |= cfc_check_trigger_arg_max(&cmd->convert_arg,
+ devpriv->clock_ns * 0xffff);
}
} else if (cmd->convert_src == TRIG_EXT) {
/* external trigger */
@@ -2274,40 +2305,23 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if (tmp > 16)
tmp = 16;
tmp |= (cmd->convert_arg & (CR_ALT_FILTER | CR_INVERT));
- if (cmd->convert_arg != tmp) {
- cmd->convert_arg = tmp;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, tmp);
} else if (cmd->convert_src == TRIG_NOW) {
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
}
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
if (cmd->stop_src == TRIG_COUNT) {
unsigned int max_count = 0x01000000;
if (boardtype.reg_type == ni_reg_611x)
max_count -= num_adc_stages_611x;
- if (cmd->stop_arg > max_count) {
- cmd->stop_arg = max_count;
- err++;
- }
- if (cmd->stop_arg < 1) {
- cmd->stop_arg = 1;
- err++;
- }
+ err |= cfc_check_trigger_arg_max(&cmd->stop_arg, max_count);
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
} else {
/* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
}
if (err)
@@ -2356,6 +2370,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct ni_private *devpriv = dev->private;
const struct comedi_cmd *cmd = &s->async->cmd;
int timer;
int mode1 = 0; /* mode1 is needed for both stop and convert */
@@ -2662,6 +2677,8 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static int ni_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int trignum)
{
+ struct ni_private *devpriv = dev->private;
+
if (trignum != 0)
return -EINVAL;
@@ -2681,6 +2698,8 @@ static int ni_ai_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
+
if (insn->n < 1)
return -EINVAL;
@@ -2734,6 +2753,7 @@ static int ni_ai_config_analog_trig(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
unsigned int a, b, modebits;
int err = 0;
@@ -2857,6 +2877,7 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
unsigned int chanspec[],
unsigned int n_chans, int timed)
{
+ struct ni_private *devpriv = dev->private;
unsigned int range;
unsigned int chan;
unsigned int conf;
@@ -2928,6 +2949,7 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev,
unsigned int chanspec[],
unsigned int n_chans)
{
+ struct ni_private *devpriv = dev->private;
unsigned int range;
unsigned int chan;
unsigned int conf;
@@ -2984,6 +3006,8 @@ static int ni_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
+
data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
return 1;
@@ -2993,6 +3017,7 @@ static int ni_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int invert;
@@ -3013,6 +3038,7 @@ static int ni_ao_insn_write_671x(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int invert;
@@ -3031,6 +3057,8 @@ static int ni_ao_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
+
switch (data[0]) {
case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE:
switch (data[1]) {
@@ -3057,6 +3085,7 @@ static int ni_ao_insn_config(struct comedi_device *dev,
static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int trignum)
{
+ struct ni_private *devpriv = dev->private;
int ret;
int interrupt_b_bits;
int i;
@@ -3126,6 +3155,7 @@ static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct ni_private *devpriv = dev->private;
const struct comedi_cmd *cmd = &s->async->cmd;
int bits;
int i;
@@ -3330,6 +3360,7 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
+ struct ni_private *devpriv = dev->private;
int err = 0;
int tmp;
@@ -3359,7 +3390,7 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
if (cmd->start_src == TRIG_EXT) {
/* external trigger */
@@ -3368,48 +3399,27 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if (tmp > 18)
tmp = 18;
tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
- if (cmd->start_arg != tmp) {
- cmd->start_arg = tmp;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, tmp);
} else {
- if (cmd->start_arg != 0) {
- /* true for both TRIG_NOW and TRIG_INT */
- cmd->start_arg = 0;
- err++;
- }
+ /* true for both TRIG_NOW and TRIG_INT */
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
}
+
if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->scan_begin_arg < boardtype.ao_speed) {
- cmd->scan_begin_arg = boardtype.ao_speed;
- err++;
- }
- if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) { /* XXX check */
- cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff;
- err++;
- }
- }
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) { /* XXX check */
- if (cmd->stop_arg > 0x00ffffff) {
- cmd->stop_arg = 0x00ffffff;
- err++;
- }
- } else {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ boardtype.ao_speed);
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
+ devpriv->clock_ns * 0xffffff);
}
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
+
if (err)
return 3;
@@ -3438,6 +3448,8 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct ni_private *devpriv = dev->private;
+
/* devpriv->ao0p=0x0000; */
/* ni_writew(devpriv->ao0p,AO_Configuration); */
@@ -3491,6 +3503,8 @@ static int ni_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
+
#ifdef DEBUG_DIO
printk("ni_dio_insn_config() chan=%d io=%d\n",
CR_CHAN(insn->chanspec), data[0]);
@@ -3524,6 +3538,8 @@ static int ni_dio_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
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
@@ -3552,6 +3568,8 @@ static int ni_m_series_dio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct ni_private *devpriv __maybe_unused = dev->private;
+
#ifdef DEBUG_DIO
printk("ni_m_series_dio_insn_config() chan=%d io=%d\n",
CR_CHAN(insn->chanspec), data[0]);
@@ -3584,6 +3602,8 @@ static int ni_m_series_dio_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ 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]);
@@ -3623,39 +3643,18 @@ static int ni_cdio_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
- if (cmd->start_src == TRIG_INT) {
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
- }
- if (cmd->scan_begin_src == TRIG_EXT) {
- tmp = cmd->scan_begin_arg;
- tmp &= CR_PACK_FLAGS(CDO_Sample_Source_Select_Mask, 0, 0,
- CR_INVERT);
- if (tmp != cmd->scan_begin_arg) {
- err++;
- }
- }
- if (cmd->convert_src == TRIG_NOW) {
- if (cmd->convert_arg) {
- cmd->convert_arg = 0;
- err++;
- }
- }
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->stop_src == TRIG_NONE) {
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ tmp = cmd->scan_begin_arg;
+ tmp &= CR_PACK_FLAGS(CDO_Sample_Source_Select_Mask, 0, 0, CR_INVERT);
+ if (tmp != cmd->scan_begin_arg)
+ err |= -EINVAL;
+
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -3680,6 +3679,7 @@ static int ni_cdio_cmdtest(struct comedi_device *dev,
static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct ni_private *devpriv __maybe_unused = dev->private;
const struct comedi_cmd *cmd = &s->async->cmd;
unsigned cdo_mode_bits = CDO_FIFO_Mode_Bit | CDO_Halt_On_Error_Bit;
int retval;
@@ -3719,6 +3719,7 @@ static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int trignum)
{
#ifdef PCIDMA
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
#endif
int retval = 0;
@@ -3766,6 +3767,8 @@ static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct ni_private *devpriv __maybe_unused = dev->private;
+
ni_writel(CDO_Disarm_Bit | CDO_Error_Interrupt_Enable_Clear_Bit |
CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit |
CDO_FIFO_Request_Interrupt_Enable_Clear_Bit,
@@ -3781,6 +3784,7 @@ static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
static void handle_cdio_interrupt(struct comedi_device *dev)
{
+ struct ni_private *devpriv __maybe_unused = dev->private;
unsigned cdio_status;
struct comedi_subdevice *s = &dev->subdevices[NI_DIO_SUBDEV];
#ifdef PCIDMA
@@ -3824,6 +3828,7 @@ static int ni_serial_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
int err = insn->n;
unsigned char byte_out, byte_in = 0;
@@ -3920,6 +3925,7 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev,
unsigned char data_out,
unsigned char *data_in)
{
+ struct ni_private *devpriv = dev->private;
unsigned int status1;
int err = 0, count = 20;
@@ -3978,6 +3984,7 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev,
unsigned char data_out,
unsigned char *data_in)
{
+ struct ni_private *devpriv = dev->private;
unsigned char mask, input = 0;
#ifdef DEBUG_DIO
@@ -4031,9 +4038,10 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev,
static void mio_common_detach(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
struct comedi_subdevice *s;
- if (dev->private) {
+ if (devpriv) {
if (devpriv->counter_dev) {
ni_gpct_device_destroy(devpriv->counter_dev);
}
@@ -4151,6 +4159,7 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
enum ni_gpct_register reg)
{
struct comedi_device *dev = counter->counter_dev->dev;
+ struct ni_private *devpriv = dev->private;
unsigned stc_register;
/* bits in the join reset register which are relevant to counters */
static const unsigned gpct_joint_reset_mask = G0_Reset | G1_Reset;
@@ -4219,7 +4228,9 @@ static unsigned ni_gpct_read_register(struct ni_gpct *counter,
enum ni_gpct_register reg)
{
struct comedi_device *dev = counter->counter_dev->dev;
+ struct ni_private *devpriv = dev->private;
unsigned stc_register;
+
switch (reg) {
/* m-series only registers */
case NITIO_G0_DMA_Status_Reg:
@@ -4251,6 +4262,8 @@ static int ni_freq_out_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
+
data[0] = devpriv->clock_and_fout & FOUT_Divider_mask;
return 1;
}
@@ -4259,6 +4272,8 @@ static int ni_freq_out_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
+
devpriv->clock_and_fout &= ~FOUT_Enable;
devpriv->stc_writew(dev, devpriv->clock_and_fout,
Clock_and_FOUT_Register);
@@ -4273,6 +4288,8 @@ static int ni_freq_out_insn_write(struct comedi_device *dev,
static int ni_set_freq_out_clock(struct comedi_device *dev,
unsigned int clock_source)
{
+ struct ni_private *devpriv = dev->private;
+
switch (clock_source) {
case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC:
devpriv->clock_and_fout &= ~FOUT_Timebase_Select;
@@ -4292,6 +4309,8 @@ static void ni_get_freq_out_clock(struct comedi_device *dev,
unsigned int *clock_source,
unsigned int *clock_period_ns)
{
+ struct ni_private *devpriv = dev->private;
+
if (devpriv->clock_and_fout & FOUT_Timebase_Select) {
*clock_source = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC;
*clock_period_ns = TIMEBASE_2_NS;
@@ -4320,11 +4339,12 @@ static int ni_freq_out_insn_config(struct comedi_device *dev,
static int ni_alloc_private(struct comedi_device *dev)
{
- int ret;
+ struct ni_private *devpriv;
- ret = alloc_private(dev, sizeof(struct ni_private));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
spin_lock_init(&devpriv->window_lock);
spin_lock_init(&devpriv->soft_reg_copy_lock);
@@ -4335,6 +4355,7 @@ static int ni_alloc_private(struct comedi_device *dev)
static int ni_E_init(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
struct comedi_subdevice *s;
unsigned j;
enum ni_gpct_variant counter_variant;
@@ -4661,6 +4682,7 @@ static int ni_E_init(struct comedi_device *dev)
static int ni_8255_callback(int dir, int port, int data, unsigned long arg)
{
struct comedi_device *dev = (struct comedi_device *)arg;
+ struct ni_private *devpriv __maybe_unused = dev->private;
if (dir) {
ni_writeb(data, Port_A + 2 * port);
@@ -4689,6 +4711,7 @@ static int ni_eeprom_insn_read(struct comedi_device *dev,
static int ni_read_eeprom(struct comedi_device *dev, int addr)
{
+ struct ni_private *devpriv __maybe_unused = dev->private;
int bit;
int bitstring;
@@ -4716,6 +4739,8 @@ static int ni_m_series_eeprom_insn_read(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
+
data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)];
return 1;
@@ -4723,6 +4748,8 @@ static int ni_m_series_eeprom_insn_read(struct comedi_device *dev,
static int ni_get_pwm_config(struct comedi_device *dev, unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
+
data[1] = devpriv->pwm_up_count * devpriv->clock_ns;
data[2] = devpriv->pwm_down_count * devpriv->clock_ns;
return 3;
@@ -4732,7 +4759,9 @@ static int ni_m_series_pwm_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
unsigned up_count, down_count;
+
switch (data[0]) {
case INSN_CONFIG_PWM_OUTPUT:
switch (data[1]) {
@@ -4798,7 +4827,9 @@ static int ni_6143_pwm_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
unsigned up_count, down_count;
+
switch (data[0]) {
case INSN_CONFIG_PWM_OUTPUT:
switch (data[1]) {
@@ -4875,6 +4906,8 @@ static int ni_calib_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
+
data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
return 1;
@@ -4905,6 +4938,7 @@ static struct caldac_struct caldacs[] = {
static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct ni_private *devpriv = dev->private;
int i, j;
int n_dacs;
int n_chans = 0;
@@ -4958,6 +4992,7 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
static void ni_write_caldac(struct comedi_device *dev, int addr, int val)
{
+ struct ni_private *devpriv = dev->private;
unsigned int loadbit = 0, bits = 0, bit, bitstring = 0;
int i;
int type;
@@ -5211,8 +5246,10 @@ static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
static int ni_m_series_set_pfi_routing(struct comedi_device *dev, unsigned chan,
unsigned source)
{
+ struct ni_private *devpriv = dev->private;
unsigned pfi_reg_index;
unsigned array_offset;
+
if ((source & 0x1f) != source)
return -EINVAL;
pfi_reg_index = 1 + chan / 3;
@@ -5247,7 +5284,9 @@ static int ni_set_pfi_routing(struct comedi_device *dev, unsigned chan,
static unsigned ni_m_series_get_pfi_routing(struct comedi_device *dev,
unsigned chan)
{
+ struct ni_private *devpriv = dev->private;
const unsigned array_offset = chan / 3;
+
return MSeries_PFI_Output_Select_Source(chan,
devpriv->
pfi_output_select_reg
@@ -5306,7 +5345,9 @@ static unsigned ni_get_pfi_routing(struct comedi_device *dev, unsigned chan)
static int ni_config_filter(struct comedi_device *dev, unsigned pfi_channel,
enum ni_pfi_filter_select filter)
{
+ struct ni_private *devpriv __maybe_unused = dev->private;
unsigned bits;
+
if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
return -ENOTSUPP;
}
@@ -5321,6 +5362,8 @@ static int ni_pfi_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_private *devpriv __maybe_unused = dev->private;
+
if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
return -ENOTSUPP;
}
@@ -5337,6 +5380,7 @@ static int ni_pfi_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
unsigned int chan;
if (insn->n < 1)
@@ -5379,6 +5423,8 @@ static int ni_pfi_insn_config(struct comedi_device *dev,
*/
static void ni_rtsi_init(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
+
/* Initialises the RTSI bus signal switch to a default state */
/* Set clock mode to internal */
@@ -5480,6 +5526,7 @@ static inline unsigned num_configurable_rtsi_channels(struct comedi_device *dev)
static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
unsigned source, unsigned period_ns)
{
+ struct ni_private *devpriv = dev->private;
static const unsigned min_period_ns = 50;
static const unsigned max_period_ns = 1000;
static const unsigned timeout = 1000;
@@ -5488,6 +5535,7 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
unsigned freq_multiplier;
unsigned i;
int retval;
+
if (source == NI_MIO_PLL_PXI10_CLOCK)
period_ns = 100;
/* these limits are somewhat arbitrary, but NI advertises 1 to 20MHz range so we'll use that */
@@ -5581,6 +5629,8 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
unsigned period_ns)
{
+ struct ni_private *devpriv = dev->private;
+
if (source == NI_MIO_INTERNAL_CLOCK) {
devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
@@ -5666,6 +5716,8 @@ static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan,
static int ni_set_rtsi_routing(struct comedi_device *dev, unsigned chan,
unsigned source)
{
+ struct ni_private *devpriv = dev->private;
+
if (ni_valid_rtsi_output_source(dev, chan, source) == 0)
return -EINVAL;
if (chan < 4) {
@@ -5686,6 +5738,8 @@ static int ni_set_rtsi_routing(struct comedi_device *dev, unsigned chan,
static unsigned ni_get_rtsi_routing(struct comedi_device *dev, unsigned chan)
{
+ struct ni_private *devpriv = dev->private;
+
if (chan < 4) {
return RTSI_Trig_Output_Source(chan,
devpriv->rtsi_trig_a_output_reg);
@@ -5704,7 +5758,9 @@ static int ni_rtsi_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
+
switch (data[0]) {
case INSN_CONFIG_DIO_OUTPUT:
if (chan < num_configurable_rtsi_channels(dev)) {
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
index ca4f8e06e75..76c6a13ea9d 100644
--- a/drivers/staging/comedi/drivers/ni_mio_cs.c
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -175,9 +175,7 @@ struct ni_private {
struct pcmcia_device *link;
- NI_PRIVATE_COMMON};
-
-#define devpriv ((struct ni_private *)dev->private)
+NI_PRIVATE_COMMON};
/* How we access registers */
@@ -196,6 +194,7 @@ struct ni_private {
static void mio_cs_win_out(struct comedi_device *dev, uint16_t data, int addr)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->window_lock, flags);
@@ -210,6 +209,7 @@ static void mio_cs_win_out(struct comedi_device *dev, uint16_t data, int addr)
static uint16_t mio_cs_win_in(struct comedi_device *dev, int addr)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
uint16_t ret;
@@ -251,7 +251,7 @@ static void mio_cs_config(struct pcmcia_device *link);
static void cs_release(struct pcmcia_device *link);
static void cs_detach(struct pcmcia_device *);
-static struct pcmcia_device *cur_dev = NULL;
+static struct pcmcia_device *cur_dev;
static int cs_attach(struct pcmcia_device *link)
{
@@ -324,6 +324,7 @@ static void mio_cs_config(struct pcmcia_device *link)
static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ struct ni_private *devpriv;
struct pcmcia_device *link;
unsigned int irq;
int ret;
@@ -339,13 +340,15 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
irq = link->irq;
- printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ",
- dev->minor, dev->driver->driver_name, dev->iobase, irq);
+ dev->board_ptr = ni_boards + ni_getboardtype(dev, link);
#if 0
{
int i;
+ printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ",
+ dev->minor, dev->driver->driver_name, dev->iobase, irq);
+
printk(" board fingerprint:");
for (i = 0; i < 32; i += 2) {
printk(" %04x %02x", inw(dev->iobase + i),
@@ -356,26 +359,25 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
for (i = 0; i < 10; i++)
printk(" 0x%04x", win_in(i));
printk("\n");
+
+ printk("boardtype.name: %s\n", boardtype.name);
}
#endif
- dev->board_ptr = ni_boards + ni_getboardtype(dev, link);
-
- printk(" %s", boardtype.name);
dev->board_name = boardtype.name;
ret = request_irq(irq, ni_E_interrupt, NI_E_IRQ_FLAGS,
"ni_mio_cs", dev);
if (ret < 0) {
- printk(" irq not available\n");
+ dev_err(dev->class_dev, "irq not available\n");
return -EINVAL;
}
dev->irq = irq;
- /* allocate private area */
ret = ni_alloc_private(dev);
- if (ret < 0)
+ if (ret)
return ret;
+ devpriv = dev->private;
devpriv->stc_writew = &mio_cs_win_out;
devpriv->stc_readw = &mio_cs_win_in;
@@ -400,7 +402,8 @@ static int ni_getboardtype(struct comedi_device *dev,
return i;
}
- printk("unknown board 0x%04x -- pretend it is a ", link->card_id);
+ dev_err(dev->class_dev,
+ "unknown board 0x%04x -- pretend it is a ", link->card_id);
return 0;
}
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index bc9313ec985..084ebea33ab 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -310,7 +310,6 @@ struct nidio96_private {
struct mite_dma_descriptor_ring *di_mite_ring;
spinlock_t mite_channel_lock;
};
-#define devpriv ((struct nidio96_private *)dev->private)
static int ni_pcidio_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
@@ -332,6 +331,7 @@ static void ni_pcidio_print_status(unsigned int status);
static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
{
+ struct nidio96_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
@@ -355,6 +355,7 @@ static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev)
{
+ struct nidio96_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
@@ -384,6 +385,7 @@ static void ni_pcidio_event(struct comedi_device *dev,
static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct nidio96_private *devpriv = dev->private;
unsigned long irq_flags;
int count;
@@ -400,6 +402,7 @@ static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s)
static irqreturn_t nidio_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct nidio96_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[0];
struct comedi_async *async = s->async;
struct mite_struct *mite = devpriv->mite;
@@ -609,6 +612,7 @@ static void ni_pcidio_print_status(unsigned int flags)
#ifdef unused
static void debug_int(struct comedi_device *dev)
{
+ struct nidio96_private *devpriv = dev->private;
int a, b;
static int n_int;
struct timeval tv;
@@ -640,6 +644,8 @@ static int ni_pcidio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct nidio96_private *devpriv = dev->private;
+
if (insn->n != 1)
return -EINVAL;
switch (data[0]) {
@@ -668,6 +674,8 @@ static int ni_pcidio_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
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]);
@@ -707,46 +715,32 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->start_arg != 0) {
- /* same for both TRIG_INT and TRIG_NOW */
- cmd->start_arg = 0;
- err++;
- }
#define MAX_SPEED (TIMER_BASE) /* in nanoseconds */
if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->scan_begin_arg < MAX_SPEED) {
- cmd->scan_begin_arg = MAX_SPEED;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ MAX_SPEED);
/* no minimum speed */
} else {
/* TRIG_EXT */
/* should be level/edge, hi/lo specification here */
if ((cmd->scan_begin_arg & ~(CR_EDGE | CR_INVERT)) != 0) {
cmd->scan_begin_arg &= (CR_EDGE | CR_INVERT);
- err++;
+ err |= -EINVAL;
}
}
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
if (cmd->stop_src == TRIG_COUNT) {
/* no limit */
- } else {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ } else { /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
}
if (err)
@@ -793,6 +787,7 @@ static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode)
static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct nidio96_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
/* XXX configure ports for input */
@@ -910,6 +905,7 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct nidio96_private *devpriv = dev->private;
int retval;
unsigned long flags;
@@ -934,6 +930,8 @@ static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
static int ni_pcidio_inttrig(struct comedi_device *dev,
struct comedi_subdevice *s, unsigned int trignum)
{
+ struct nidio96_private *devpriv = dev->private;
+
if (trignum != 0)
return -EINVAL;
@@ -946,6 +944,8 @@ static int ni_pcidio_inttrig(struct comedi_device *dev,
static int ni_pcidio_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct nidio96_private *devpriv = dev->private;
+
writeb(0x00,
devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
ni_pcidio_release_di_mite_channel(dev);
@@ -956,6 +956,7 @@ static int ni_pcidio_cancel(struct comedi_device *dev,
static int ni_pcidio_change(struct comedi_device *dev,
struct comedi_subdevice *s, unsigned long new_size)
{
+ struct nidio96_private *devpriv = dev->private;
int ret;
ret = mite_buf_change(devpriv->di_mite_ring, s->async);
@@ -970,6 +971,7 @@ static int ni_pcidio_change(struct comedi_device *dev,
static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index,
const u8 *data, size_t data_len)
{
+ struct nidio96_private *devpriv = dev->private;
static const int timeout = 1000;
int i;
size_t j;
@@ -1033,8 +1035,10 @@ static int pci_6534_reset_fpga(struct comedi_device *dev, int fpga_index)
static int pci_6534_reset_fpgas(struct comedi_device *dev)
{
+ struct nidio96_private *devpriv = dev->private;
int ret;
int i;
+
writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
for (i = 0; i < 3; ++i) {
ret = pci_6534_reset_fpga(dev, i);
@@ -1047,6 +1051,8 @@ static int pci_6534_reset_fpgas(struct comedi_device *dev)
static void pci_6534_init_main_fpga(struct comedi_device *dev)
{
+ struct nidio96_private *devpriv = dev->private;
+
writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register);
writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register);
writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register);
@@ -1057,6 +1063,7 @@ static void pci_6534_init_main_fpga(struct comedi_device *dev)
static int pci_6534_upload_firmware(struct comedi_device *dev)
{
+ struct nidio96_private *devpriv = dev->private;
int ret;
const struct firmware *fw;
static const char *const fw_file[3] = {
@@ -1099,16 +1106,20 @@ nidio_find_boardinfo(struct pci_dev *pcidev)
return NULL;
}
-static int __devinit nidio_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int nidio_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct nidio96_private *devpriv;
struct comedi_subdevice *s;
int ret;
unsigned int irq;
- ret = alloc_private(dev, sizeof(struct nidio96_private));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
spin_lock_init(&devpriv->mite_channel_lock);
dev->board_ptr = nidio_find_boardinfo(pcidev);
@@ -1123,7 +1134,7 @@ static int __devinit nidio_attach_pci(struct comedi_device *dev,
dev_warn(dev->class_dev, "error setting up mite\n");
return ret;
}
- comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
+
devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
if (devpriv->di_mite_ring == NULL)
return -ENOMEM;
@@ -1184,6 +1195,8 @@ static int __devinit nidio_attach_pci(struct comedi_device *dev,
static void nidio_detach(struct comedi_device *dev)
{
+ struct nidio96_private *devpriv = dev->private;
+
if (dev->irq)
free_irq(dev->irq, dev);
if (devpriv) {
@@ -1201,17 +1214,17 @@ static void nidio_detach(struct comedi_device *dev)
static struct comedi_driver ni_pcidio_driver = {
.driver_name = "ni_pcidio",
.module = THIS_MODULE,
- .attach_pci = nidio_attach_pci,
+ .auto_attach = nidio_auto_attach,
.detach = nidio_detach,
};
-static int __devinit ni_pcidio_pci_probe(struct pci_dev *dev,
+static int ni_pcidio_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &ni_pcidio_driver);
}
-static void __devexit ni_pcidio_pci_remove(struct pci_dev *dev)
+static void ni_pcidio_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -1228,7 +1241,7 @@ static struct pci_driver ni_pcidio_pci_driver = {
.name = "ni_pcidio",
.id_table = ni_pcidio_pci_table,
.probe = ni_pcidio_pci_probe,
- .remove = __devexit_p(ni_pcidio_pci_remove),
+ .remove = ni_pcidio_pci_remove,
};
module_comedi_pci_driver(ni_pcidio_driver, ni_pcidio_pci_driver);
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c
index f284a90720e..aaac0b2cc9e 100644
--- a/drivers/staging/comedi/drivers/ni_pcimio.c
+++ b/drivers/staging/comedi/drivers/ni_pcimio.c
@@ -1190,7 +1190,6 @@ static const struct ni_board_struct ni_boards[] = {
struct ni_private {
NI_PRIVATE_COMMON};
-#define devpriv ((struct ni_private *)dev->private)
/* How we access registers */
@@ -1213,6 +1212,7 @@ NI_PRIVATE_COMMON};
static void e_series_win_out(struct comedi_device *dev, uint16_t data, int reg)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
spin_lock_irqsave(&devpriv->window_lock, flags);
@@ -1223,6 +1223,7 @@ static void e_series_win_out(struct comedi_device *dev, uint16_t data, int reg)
static uint16_t e_series_win_in(struct comedi_device *dev, int reg)
{
+ struct ni_private *devpriv = dev->private;
unsigned long flags;
uint16_t ret;
@@ -1237,7 +1238,9 @@ static uint16_t e_series_win_in(struct comedi_device *dev, int reg)
static void m_series_stc_writew(struct comedi_device *dev, uint16_t data,
int reg)
{
+ struct ni_private *devpriv = dev->private;
unsigned offset;
+
switch (reg) {
case ADC_FIFO_Clear:
offset = M_Offset_AI_FIFO_Clear;
@@ -1381,8 +1384,9 @@ static void m_series_stc_writew(struct comedi_device *dev, uint16_t data,
/* FIXME: DIO_Output_Register (16 bit reg) is replaced by M_Offset_Static_Digital_Output (32 bit)
and M_Offset_SCXI_Serial_Data_Out (8 bit) */
default:
- printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n",
- __func__, reg);
+ dev_warn(dev->class_dev,
+ "%s: bug! unhandled register=0x%x in switch.\n",
+ __func__, reg);
BUG();
return;
break;
@@ -1392,7 +1396,9 @@ static void m_series_stc_writew(struct comedi_device *dev, uint16_t data,
static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg)
{
+ struct ni_private *devpriv = dev->private;
unsigned offset;
+
switch (reg) {
case AI_Status_1_Register:
offset = M_Offset_AI_Status_1;
@@ -1416,8 +1422,9 @@ static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg)
offset = M_Offset_G01_Status;
break;
default:
- printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n",
- __func__, reg);
+ dev_warn(dev->class_dev,
+ "%s: bug! unhandled register=0x%x in switch.\n",
+ __func__, reg);
BUG();
return 0;
break;
@@ -1428,7 +1435,9 @@ static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg)
static void m_series_stc_writel(struct comedi_device *dev, uint32_t data,
int reg)
{
+ struct ni_private *devpriv = dev->private;
unsigned offset;
+
switch (reg) {
case AI_SC_Load_A_Registers:
offset = M_Offset_AI_SC_Load_A;
@@ -1458,8 +1467,9 @@ static void m_series_stc_writel(struct comedi_device *dev, uint32_t data,
offset = M_Offset_G1_Load_B;
break;
default:
- printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n",
- __func__, reg);
+ dev_warn(dev->class_dev,
+ "%s: bug! unhandled register=0x%x in switch.\n",
+ __func__, reg);
BUG();
return;
break;
@@ -1469,7 +1479,9 @@ static void m_series_stc_writel(struct comedi_device *dev, uint32_t data,
static uint32_t m_series_stc_readl(struct comedi_device *dev, int reg)
{
+ struct ni_private *devpriv = dev->private;
unsigned offset;
+
switch (reg) {
case G_HW_Save_Register(0):
offset = M_Offset_G0_HW_Save;
@@ -1484,8 +1496,9 @@ static uint32_t m_series_stc_readl(struct comedi_device *dev, int reg)
offset = M_Offset_G1_Save;
break;
default:
- printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n",
- __func__, reg);
+ dev_warn(dev->class_dev,
+ "%s: bug! unhandled register=0x%x in switch.\n",
+ __func__, reg);
BUG();
return 0;
break;
@@ -1516,6 +1529,7 @@ static int pcimio_dio_change(struct comedi_device *dev,
static void m_series_init_eeprom_buffer(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
static const int Start_Cal_EEPROM = 0x400;
static const unsigned window_size = 10;
static const int serial_number_eeprom_offset = 0x4;
@@ -1553,6 +1567,8 @@ static void m_series_init_eeprom_buffer(struct comedi_device *dev)
static void init_6143(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
+
/* Disable interrupts */
devpriv->stc_writew(dev, 0, Interrupt_Control_Register);
@@ -1572,10 +1588,12 @@ static void init_6143(struct comedi_device *dev)
static void pcimio_detach(struct comedi_device *dev)
{
+ struct ni_private *devpriv = dev->private;
+
mio_common_detach(dev);
if (dev->irq)
free_irq(dev->irq, dev);
- if (dev->private) {
+ if (devpriv) {
mite_free_ring(devpriv->ai_mite_ring);
mite_free_ring(devpriv->ao_mite_ring);
mite_free_ring(devpriv->cdo_mite_ring);
@@ -1602,16 +1620,19 @@ pcimio_find_boardinfo(struct pci_dev *pcidev)
return NULL;
}
-static int __devinit pcimio_attach_pci(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static int pcimio_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct ni_private *devpriv;
int ret;
dev_info(dev->class_dev, "ni_pcimio: attach %s\n", pci_name(pcidev));
ret = ni_alloc_private(dev);
- if (ret < 0)
+ if (ret)
return ret;
+ devpriv = dev->private;
dev->board_ptr = pcimio_find_boardinfo(pcidev);
if (!dev->board_ptr)
@@ -1641,7 +1662,7 @@ static int __devinit pcimio_attach_pci(struct comedi_device *dev,
pr_warn("error setting up mite\n");
return ret;
}
- comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
+
devpriv->ai_mite_ring = mite_alloc_ring(devpriv->mite);
if (devpriv->ai_mite_ring == NULL)
return -ENOMEM;
@@ -1693,6 +1714,7 @@ static int __devinit pcimio_attach_pci(struct comedi_device *dev,
static int pcimio_ai_change(struct comedi_device *dev,
struct comedi_subdevice *s, unsigned long new_size)
{
+ struct ni_private *devpriv = dev->private;
int ret;
ret = mite_buf_change(devpriv->ai_mite_ring, s->async);
@@ -1705,6 +1727,7 @@ static int pcimio_ai_change(struct comedi_device *dev,
static int pcimio_ao_change(struct comedi_device *dev,
struct comedi_subdevice *s, unsigned long new_size)
{
+ struct ni_private *devpriv = dev->private;
int ret;
ret = mite_buf_change(devpriv->ao_mite_ring, s->async);
@@ -1718,6 +1741,7 @@ static int pcimio_gpct0_change(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned long new_size)
{
+ struct ni_private *devpriv = dev->private;
int ret;
ret = mite_buf_change(devpriv->gpct_mite_ring[0], s->async);
@@ -1731,6 +1755,7 @@ static int pcimio_gpct1_change(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned long new_size)
{
+ struct ni_private *devpriv = dev->private;
int ret;
ret = mite_buf_change(devpriv->gpct_mite_ring[1], s->async);
@@ -1743,6 +1768,7 @@ static int pcimio_gpct1_change(struct comedi_device *dev,
static int pcimio_dio_change(struct comedi_device *dev,
struct comedi_subdevice *s, unsigned long new_size)
{
+ struct ni_private *devpriv = dev->private;
int ret;
ret = mite_buf_change(devpriv->cdo_mite_ring, s->async);
@@ -1755,17 +1781,17 @@ static int pcimio_dio_change(struct comedi_device *dev,
static struct comedi_driver ni_pcimio_driver = {
.driver_name = "ni_pcimio",
.module = THIS_MODULE,
- .attach_pci = pcimio_attach_pci,
+ .auto_attach = pcimio_auto_attach,
.detach = pcimio_detach,
};
-static int __devinit ni_pcimio_pci_probe(struct pci_dev *dev,
+static int ni_pcimio_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &ni_pcimio_driver);
}
-static void __devexit ni_pcimio_pci_remove(struct pci_dev *dev)
+static void ni_pcimio_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -1832,7 +1858,7 @@ static struct pci_driver ni_pcimio_pci_driver = {
.name = "ni_pcimio",
.id_table = ni_pcimio_pci_table,
.probe = ni_pcimio_pci_probe,
- .remove = __devexit_p(ni_pcimio_pci_remove)
+ .remove = ni_pcimio_pci_remove
};
module_comedi_pci_driver(ni_pcimio_driver, ni_pcimio_pci_driver);
diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h
index b0588202e5a..8572996539f 100644
--- a/drivers/staging/comedi/drivers/ni_tio.h
+++ b/drivers/staging/comedi/drivers/ni_tio.h
@@ -120,9 +120,9 @@ struct ni_gpct {
struct ni_gpct_device {
struct comedi_device *dev;
- void (*write_register) (struct ni_gpct * counter, unsigned bits,
+ void (*write_register) (struct ni_gpct *counter, unsigned bits,
enum ni_gpct_register reg);
- unsigned (*read_register) (struct ni_gpct * counter,
+ unsigned (*read_register) (struct ni_gpct *counter,
enum ni_gpct_register reg);
enum ni_gpct_variant variant;
struct ni_gpct *counters;
diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c
index 8ee93d359be..0c991b99da1 100644
--- a/drivers/staging/comedi/drivers/ni_tiocmd.c
+++ b/drivers/staging/comedi/drivers/ni_tiocmd.c
@@ -173,7 +173,8 @@ static int ni_tio_input_cmd(struct ni_gpct *counter, struct comedi_async *async)
static int ni_tio_output_cmd(struct ni_gpct *counter,
struct comedi_async *async)
{
- printk(KERN_ERR "ni_tio: output commands not yet implemented.\n");
+ dev_err(counter->counter_dev->dev->class_dev,
+ "output commands not yet implemented.\n");
return -ENOTSUPP;
counter->mite_chan->dir = COMEDI_OUTPUT;
@@ -219,7 +220,10 @@ int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async)
spin_lock_irqsave(&counter->lock, flags);
if (counter->mite_chan == NULL) {
- printk(KERN_ERR "ni_tio: commands only supported with DMA. Interrupt-driven commands not yet implemented.\n");
+ dev_err(counter->counter_dev->dev->class_dev,
+ "commands only supported with DMA. ");
+ dev_err(counter->counter_dev->dev->class_dev,
+ "Interrupt-driven commands not yet implemented.\n");
retval = -EIO;
} else {
retval = ni_tio_cmd_setup(counter, async);
@@ -271,37 +275,19 @@ int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd *cmd)
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
- if (cmd->start_src != TRIG_EXT) {
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
- }
- if (cmd->scan_begin_src != TRIG_EXT) {
- if (cmd->scan_begin_arg) {
- cmd->scan_begin_arg = 0;
- err++;
- }
- }
- if (cmd->convert_src != TRIG_EXT) {
- if (cmd->convert_arg) {
- cmd->convert_arg = 0;
- err++;
- }
- }
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ if (cmd->start_src != TRIG_EXT)
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->stop_src == TRIG_NONE) {
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ if (cmd->scan_begin_src != TRIG_EXT)
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+
+ if (cmd->convert_src != TRIG_EXT)
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -427,8 +413,9 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
NITIO_Gxx_Joint_Status2_Reg
(counter->counter_index)) &
Gi_Permanent_Stale_Bit(counter->counter_index)) {
- printk(KERN_INFO "%s: Gi_Permanent_Stale_Data detected.\n",
- __func__);
+ dev_info(counter->counter_dev->dev->class_dev,
+ "%s: Gi_Permanent_Stale_Data detected.\n",
+ __func__);
if (perm_stale_data)
*perm_stale_data = 1;
}
@@ -448,7 +435,8 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter,
ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error,
&perm_stale_data, NULL);
if (gate_error) {
- printk(KERN_NOTICE "%s: Gi_Gate_Error detected.\n", __func__);
+ dev_notice(counter->counter_dev->dev->class_dev,
+ "%s: Gi_Gate_Error detected.\n", __func__);
s->async->events |= COMEDI_CB_OVERFLOW;
}
if (perm_stale_data)
@@ -459,8 +447,8 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter,
if (read_register(counter,
NITIO_Gi_DMA_Status_Reg
(counter->counter_index)) & Gi_DRQ_Error_Bit) {
- printk(KERN_NOTICE "%s: Gi_DRQ_Error detected.\n",
- __func__);
+ dev_notice(counter->counter_dev->dev->class_dev,
+ "%s: Gi_DRQ_Error detected.\n", __func__);
s->async->events |= COMEDI_CB_OVERFLOW;
}
break;
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
index 89305a14eb5..6ee5da24a96 100644
--- a/drivers/staging/comedi/drivers/pcl711.c
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -161,14 +161,13 @@ struct pcl711_private {
unsigned int divisor2;
};
-#define devpriv ((struct pcl711_private *)dev->private)
-
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];
if (!dev->attached) {
@@ -264,6 +263,7 @@ ok:
static int pcl711_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
+ struct pcl711_private *devpriv = dev->private;
int tmp;
int err = 0;
@@ -289,38 +289,24 @@ static int pcl711_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3 */
+ /* Step 3: check if arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
if (cmd->scan_begin_src == TRIG_EXT) {
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
} else {
#define MAX_SPEED 1000
#define TIMER_BASE 100
- if (cmd->scan_begin_arg < MAX_SPEED) {
- cmd->scan_begin_arg = MAX_SPEED;
- err++;
- }
- }
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ MAX_SPEED);
}
+
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
if (cmd->stop_src == TRIG_NONE) {
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
} else {
/* ignore */
}
@@ -349,6 +335,7 @@ 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;
@@ -398,6 +385,7 @@ static int pcl711_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static int pcl711_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcl711_private *devpriv = dev->private;
int n;
int chan = CR_CHAN(insn->chanspec);
@@ -417,6 +405,7 @@ static int pcl711_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcl711_private *devpriv = dev->private;
int n;
int chan = CR_CHAN(insn->chanspec);
@@ -460,6 +449,7 @@ static int pcl711_do_insn_bits(struct comedi_device *dev,
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 long iobase;
unsigned int irq;
@@ -499,9 +489,10 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (ret)
return ret;
- ret = alloc_private(dev, sizeof(struct pcl711_private));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
s = &dev->subdevices[0];
/* AI subdevice */
diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c
index 07e72de982a..50e01968f19 100644
--- a/drivers/staging/comedi/drivers/pcl726.c
+++ b/drivers/staging/comedi/drivers/pcl726.c
@@ -152,11 +152,10 @@ struct pcl726_private {
unsigned int ao_readback[12];
};
-#define devpriv ((struct pcl726_private *)dev->private)
-
static int pcl726_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcl726_private *devpriv = dev->private;
int hi, lo;
int n;
int chan = CR_CHAN(insn->chanspec);
@@ -183,6 +182,7 @@ static int pcl726_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcl726_private *devpriv = dev->private;
int chan = CR_CHAN(insn->chanspec);
int n;
@@ -226,6 +226,7 @@ static int pcl726_do_insn_bits(struct comedi_device *dev,
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;
unsigned long iobase;
unsigned int iorange;
@@ -247,9 +248,10 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it)
dev->board_name = board->name;
- ret = alloc_private(dev, sizeof(struct pcl726_private));
- if (ret < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
for (i = 0; i < 12; i++) {
devpriv->bipolar[i] = 0;
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
index 3cf55ff9308..560930e6a8e 100644
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -369,8 +369,6 @@ struct pcl812_private {
unsigned int ao_readback[2]; /* data for AO readback */
};
-#define devpriv ((struct pcl812_private *)dev->private)
-
/*
==============================================================================
*/
@@ -388,6 +386,7 @@ static int pcl812_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcl812_private *devpriv = dev->private;
int n;
int timeout, hi;
@@ -465,6 +464,7 @@ static int pcl812_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcl812_private *devpriv = dev->private;
int chan = CR_CHAN(insn->chanspec);
int i;
@@ -486,6 +486,7 @@ static int pcl812_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcl812_private *devpriv = dev->private;
int chan = CR_CHAN(insn->chanspec);
int i;
@@ -533,6 +534,7 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
const struct pcl812_board *board = comedi_board(dev);
+ struct pcl812_private *devpriv = dev->private;
int err = 0;
unsigned int flags;
int tmp, divisor1, divisor2;
@@ -563,53 +565,25 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ board->ai_ns_min);
+ else /* TRIG_EXT */
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < board->ai_ns_min) {
- cmd->convert_arg = board->ai_ns_min;
- err++;
- }
- } else { /* TRIG_EXT */
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
+ err |= cfc_check_trigger_arg_max(&cmd->chanlist_len, MAX_CHANLIST_LEN);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
- if (!cmd->chanlist_len) {
- cmd->chanlist_len = 1;
- err++;
- }
- if (cmd->chanlist_len > MAX_CHANLIST_LEN) {
- cmd->chanlist_len = board->n_aichan;
- err++;
- }
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) {
- if (!cmd->stop_arg) {
- cmd->stop_arg = 1;
- err++;
- }
- } else { /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -639,6 +613,7 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev,
static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
const struct pcl812_board *board = comedi_board(dev);
+ struct pcl812_private *devpriv = dev->private;
unsigned int divisor1 = 0, divisor2 = 0, i, dma_flags, bytes;
struct comedi_cmd *cmd = &s->async->cmd;
@@ -789,6 +764,7 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
char err = 1;
unsigned int mask, timeout;
struct comedi_device *dev = d;
+ struct pcl812_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[0];
unsigned int next_chan;
@@ -862,6 +838,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev,
struct comedi_subdevice *s, short *ptr,
unsigned int bufptr, unsigned int len)
{
+ struct pcl812_private *devpriv = dev->private;
unsigned int i;
s->async->events = 0;
@@ -892,6 +869,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev,
static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct pcl812_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[0];
unsigned long dma_flags;
int len, bufptr;
@@ -938,6 +916,7 @@ static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d)
static irqreturn_t interrupt_pcl812(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct pcl812_private *devpriv = dev->private;
if (!dev->attached) {
comedi_error(dev, "spurious interrupt");
@@ -954,6 +933,7 @@ static irqreturn_t interrupt_pcl812(int irq, void *d)
*/
static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct pcl812_private *devpriv = dev->private;
unsigned long flags;
unsigned int top1, top2, i;
@@ -1002,6 +982,7 @@ static void setup_range_channel(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned int rangechan, char wait)
{
+ struct pcl812_private *devpriv = dev->private;
unsigned char chan_reg = CR_CHAN(rangechan); /* normal board */
/* gain index */
unsigned char gain_reg = CR_RANGE(rangechan) +
@@ -1063,8 +1044,9 @@ static void start_pacer(struct comedi_device *dev, int mode,
static void free_resources(struct comedi_device *dev)
{
const struct pcl812_board *board = comedi_board(dev);
+ struct pcl812_private *devpriv = dev->private;
- if (dev->private) {
+ if (devpriv) {
if (devpriv->dmabuf[0])
free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
if (devpriv->dmabuf[1])
@@ -1084,6 +1066,8 @@ static void free_resources(struct comedi_device *dev)
static int pcl812_ai_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct pcl812_private *devpriv = dev->private;
+
if (devpriv->ai_dma)
disable_dma(devpriv->dma);
outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */
@@ -1100,6 +1084,7 @@ static int pcl812_ai_cancel(struct comedi_device *dev,
static void pcl812_reset(struct comedi_device *dev)
{
const struct pcl812_board *board = comedi_board(dev);
+ struct pcl812_private *devpriv = dev->private;
outb(0, dev->iobase + PCL812_MUX);
outb(0 + devpriv->range_correction, dev->iobase + PCL812_GAIN);
@@ -1135,6 +1120,7 @@ static void pcl812_reset(struct comedi_device *dev)
static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct pcl812_board *board = comedi_board(dev);
+ struct pcl812_private *devpriv;
int ret, subdev;
unsigned long iobase;
unsigned int irq;
@@ -1153,11 +1139,12 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
dev->iobase = iobase;
- ret = alloc_private(dev, sizeof(struct pcl812_private));
- if (ret < 0) {
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv) {
free_resources(dev);
- return ret; /* Can't alloc mem */
+ return -ENOMEM;
}
+ dev->private = devpriv;
dev->board_name = board->name;
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index 0822de058e4..f625fdab335 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -126,8 +126,6 @@ struct pcl816_board {
int i8254_osc_base; /* 1/frequency of on board oscilator in ns */
};
-#define devpriv ((struct pcl816_private *)dev->private)
-
#ifdef unused
static int RTC_lock; /* RTC lock */
static int RTC_timer_lock; /* RTC int lock */
@@ -259,6 +257,7 @@ static int pcl816_ai_insn_read(struct comedi_device *dev,
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;
int timeout = 50; /* wait max 50us */
@@ -315,6 +314,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev,
struct comedi_subdevice *s, short *ptr,
unsigned int bufptr, unsigned int len)
{
+ struct pcl816_private *devpriv = dev->private;
int i;
s->async->events = 0;
@@ -350,6 +350,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev,
static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct pcl816_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[0];
int len, bufptr, this_dma_buf;
unsigned long dma_flags;
@@ -398,6 +399,8 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d)
static irqreturn_t interrupt_pcl816(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct pcl816_private *devpriv = dev->private;
+
DPRINTK("<I>");
if (!dev->attached) {
@@ -481,43 +484,23 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
return 2;
- /* step 3: make sure arguments are trivially compatible */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < board->ai_ns_min) {
- cmd->convert_arg = board->ai_ns_min;
- err++;
- }
- } else { /* TRIG_EXT */
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) {
- if (!cmd->stop_arg) {
- cmd->stop_arg = 1;
- err++;
- }
- } else { /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ board->ai_ns_min);
+ else /* TRIG_EXT */
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -554,6 +537,7 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
const struct pcl816_board *board = comedi_board(dev);
+ struct pcl816_private *devpriv = dev->private;
unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq;
struct comedi_cmd *cmd = &s->async->cmd;
unsigned int seglen;
@@ -682,6 +666,7 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct pcl816_private *devpriv = dev->private;
unsigned long flags;
unsigned int top1, top2, i;
@@ -727,6 +712,8 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
static int pcl816_ai_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct pcl816_private *devpriv = dev->private;
+
/* DEBUG(printk("pcl816_ai_cancel()\n");) */
if (devpriv->irq_blocked > 0) {
@@ -932,6 +919,7 @@ setup_channel_list(struct comedi_device *dev,
struct comedi_subdevice *s, unsigned int *chanlist,
unsigned int seglen)
{
+ struct pcl816_private *devpriv = dev->private;
unsigned int i;
devpriv->ai_act_chanlist_len = seglen;
@@ -991,6 +979,7 @@ static int set_rtc_irq_bit(unsigned char bit)
static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct pcl816_board *board = comedi_board(dev);
+ struct pcl816_private *devpriv;
int ret;
unsigned long iobase;
unsigned int irq, dma;
@@ -1015,9 +1004,10 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return -EIO;
}
- ret = alloc_private(dev, sizeof(struct pcl816_private));
- if (ret < 0)
- return ret; /* Can't alloc mem */
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
dev->board_name = board->name;
@@ -1216,6 +1206,7 @@ case COMEDI_SUBD_DO:
static void pcl816_detach(struct comedi_device *dev)
{
const struct pcl816_board *board = comedi_board(dev);
+ struct pcl816_private *devpriv = dev->private;
if (dev->private) {
pcl816_ai_cancel(dev, devpriv->sub_ai);
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index d4b0859d81f..06127a5f62a 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -326,8 +326,6 @@ static const unsigned int muxonechan[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
};
-#define devpriv ((struct pcl818_private *)dev->private)
-
/*
==============================================================================
*/
@@ -406,6 +404,7 @@ static int pcl818_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcl818_private *devpriv = dev->private;
int n;
int chan = CR_CHAN(insn->chanspec);
@@ -419,6 +418,7 @@ static int pcl818_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcl818_private *devpriv = dev->private;
int n;
int chan = CR_CHAN(insn->chanspec);
@@ -478,6 +478,7 @@ static int pcl818_do_insn_bits(struct comedi_device *dev,
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;
int timeout = 50; /* wait max 50us */
@@ -537,6 +538,7 @@ conv_finish:
static irqreturn_t interrupt_pcl818_ai_mode13_dma(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, bufptr;
unsigned long flags;
@@ -616,6 +618,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct pcl818_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[0];
unsigned long tmp;
unsigned int top1, top2, i, bufptr;
@@ -721,6 +724,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d)
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;
@@ -795,6 +799,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
static irqreturn_t interrupt_pcl818(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct pcl818_private *devpriv = dev->private;
if (!dev->attached) {
comedi_error(dev, "premature interrupt");
@@ -861,6 +866,7 @@ static irqreturn_t interrupt_pcl818(int irq, void *d)
static void pcl818_ai_mode13dma_int(int mode, struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct pcl818_private *devpriv = dev->private;
unsigned int flags;
unsigned int bytes;
@@ -902,6 +908,7 @@ static void pcl818_ai_mode13dma_int(int mode, struct comedi_device *dev,
static void pcl818_ai_mode13dma_rtc(int mode, struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct pcl818_private *devpriv = dev->private;
unsigned int flags;
short *pole;
@@ -943,6 +950,7 @@ static void pcl818_ai_mode13dma_rtc(int mode, struct comedi_device *dev,
static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct pcl818_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
int divisor1 = 0, divisor2 = 0;
unsigned int seglen;
@@ -1063,6 +1071,7 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev,
static int pcl818_ao_mode13(int mode, struct comedi_device *dev,
struct comedi_subdevice *s, comedi_trig * it)
{
+ struct pcl818_private *devpriv = dev->private;
int divisor1 = 0, divisor2 = 0;
if (!dev->irq) {
@@ -1222,6 +1231,7 @@ static void setup_channel_list(struct comedi_device *dev,
unsigned int *chanlist, unsigned int n_chan,
unsigned int seglen)
{
+ struct pcl818_private *devpriv = dev->private;
int i;
devpriv->act_chanlist_len = seglen;
@@ -1259,6 +1269,7 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
const struct pcl818_board *board = comedi_board(dev);
+ struct pcl818_private *devpriv = dev->private;
int err = 0;
int tmp, divisor1 = 0, divisor2 = 0;
@@ -1283,45 +1294,23 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ board->ns_min);
+ else /* TRIG_EXT */
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < board->ns_min) {
- cmd->convert_arg = board->ns_min;
- err++;
- }
- } else { /* TRIG_EXT */
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) {
- if (!cmd->stop_arg) {
- cmd->stop_arg = 1;
- err++;
- }
- } else { /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -1358,6 +1347,7 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
*/
static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ struct pcl818_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
int retval;
@@ -1397,6 +1387,8 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static int pcl818_ai_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct pcl818_private *devpriv = dev->private;
+
if (devpriv->irq_blocked > 0) {
dev_dbg(dev->class_dev, "pcl818_ai_cancel()\n");
devpriv->irq_was_now_closed = 1;
@@ -1482,6 +1474,7 @@ static int pcl818_check(unsigned long iobase)
static void pcl818_reset(struct comedi_device *dev)
{
const struct pcl818_board *board = comedi_board(dev);
+ struct pcl818_private *devpriv = dev->private;
if (devpriv->usefifo) { /* FIFO shutdown */
outb(0, dev->iobase + PCL818_FI_INTCLR);
@@ -1552,6 +1545,7 @@ static int set_rtc_irq_bit(unsigned char bit)
static void rtc_dropped_irq(unsigned long data)
{
struct comedi_device *dev = (void *)data;
+ struct pcl818_private *devpriv = dev->private;
unsigned long flags, tmp;
switch (devpriv->int818_mode) {
@@ -1601,6 +1595,7 @@ static int rtc_setfreq_irq(int freq)
static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct pcl818_board *board = comedi_board(dev);
+ struct pcl818_private *devpriv;
int ret;
unsigned long iobase;
unsigned int irq;
@@ -1608,9 +1603,10 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
unsigned long pages;
struct comedi_subdevice *s;
- ret = alloc_private(dev, sizeof(struct pcl818_private));
- if (ret < 0)
- return ret; /* Can't alloc mem */
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
/* claim our I/O space */
iobase = it->options[0];
@@ -1892,7 +1888,9 @@ no_dma:
static void pcl818_detach(struct comedi_device *dev)
{
- if (dev->private) {
+ struct pcl818_private *devpriv = dev->private;
+
+ if (devpriv) {
pcl818_ai_cancel(dev, devpriv->sub_ai);
pcl818_reset(dev);
if (devpriv->dma)
diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c
index 4102547dc6a..5f062df1ead 100644
--- a/drivers/staging/comedi/drivers/pcm3724.c
+++ b/drivers/staging/comedi/drivers/pcm3724.c
@@ -62,14 +62,6 @@ Copy/pasted/hacked from pcm724.c
#define CR_A_MODE(a) ((a)<<5)
#define CR_CW 0x80
-struct pcm3724_board {
- const char *name; /* driver name */
- int dio; /* num of DIO */
- int numofports; /* num of 8255 subdevices */
- unsigned int IRQbits; /* allowed interrupts */
- unsigned int io_range; /* len of IO space */
-};
-
/* used to track configured dios */
struct priv_pcm3724 {
int dio_1;
@@ -156,13 +148,12 @@ static void do_3724_config(struct comedi_device *dev,
static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s,
int chanspec)
{
+ struct priv_pcm3724 *priv = dev->private;
struct comedi_subdevice *s_dio1 = &dev->subdevices[0];
unsigned int mask;
int gatecfg;
- struct priv_pcm3724 *priv;
gatecfg = 0;
- priv = dev->private;
mask = 1 << CR_CHAN(chanspec);
if (s == s_dio1)
@@ -233,36 +224,33 @@ static int subdev_3724_insn_config(struct comedi_device *dev,
static int pcm3724_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
- const struct pcm3724_board *board = comedi_board(dev);
+ struct priv_pcm3724 *priv;
struct comedi_subdevice *s;
unsigned long iobase;
unsigned int iorange;
- int ret, i, n_subdevices;
+ int ret, i;
+
+ dev->board_name = dev->driver->driver_name;
iobase = it->options[0];
- iorange = board->io_range;
+ iorange = PCM3724_SIZE;
- ret = alloc_private(dev, sizeof(struct priv_pcm3724));
- if (ret < 0)
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
return -ENOMEM;
-
- ((struct priv_pcm3724 *)(dev->private))->dio_1 = 0;
- ((struct priv_pcm3724 *)(dev->private))->dio_2 = 0;
+ dev->private = priv;
printk(KERN_INFO "comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor,
- board->name, iobase);
+ dev->board_name, iobase);
if (!iobase || !request_region(iobase, iorange, "pcm3724")) {
printk("I/O port conflict\n");
return -EIO;
}
dev->iobase = iobase;
- dev->board_name = board->name;
printk(KERN_INFO "\n");
- n_subdevices = board->numofports;
-
- ret = comedi_alloc_subdevices(dev, n_subdevices);
+ ret = comedi_alloc_subdevices(dev, 2);
if (ret)
return ret;
@@ -277,7 +265,6 @@ static int pcm3724_attach(struct comedi_device *dev,
static void pcm3724_detach(struct comedi_device *dev)
{
- const struct pcm3724_board *board = comedi_board(dev);
struct comedi_subdevice *s;
int i;
@@ -288,21 +275,14 @@ static void pcm3724_detach(struct comedi_device *dev)
}
}
if (dev->iobase)
- release_region(dev->iobase, board->io_range);
+ release_region(dev->iobase, PCM3724_SIZE);
}
-static const struct pcm3724_board boardtypes[] = {
- { "pcm3724", 48, 2, 0x00fc, PCM3724_SIZE, },
-};
-
static struct comedi_driver pcm3724_driver = {
.driver_name = "pcm3724",
.module = THIS_MODULE,
.attach = pcm3724_attach,
.detach = pcm3724_detach,
- .board_name = &boardtypes[0].name,
- .num_names = ARRAY_SIZE(boardtypes),
- .offset = sizeof(struct pcm3724_board),
};
module_comedi_driver(pcm3724_driver);
diff --git a/drivers/staging/comedi/drivers/pcm_common.c b/drivers/staging/comedi/drivers/pcm_common.c
index 85ee05ece9c..8a718aea6f3 100644
--- a/drivers/staging/comedi/drivers/pcm_common.c
+++ b/drivers/staging/comedi/drivers/pcm_common.c
@@ -29,41 +29,19 @@ int comedi_pcm_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
-
- /* cmd->scan_begin_src == TRIG_EXT */
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
-
- /* cmd->convert_src == TRIG_NOW */
- if (cmd->convert_arg != 0) {
- cmd->convert_arg = 0;
- err++;
- }
-
- /* cmd->scan_end_src == TRIG_COUNT */
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ 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, cmd->chanlist_len);
switch (cmd->stop_src) {
case TRIG_COUNT:
/* any count allowed */
break;
case TRIG_NONE:
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
break;
default:
break;
diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c
index 5efeb9205c2..13e84215fac 100644
--- a/drivers/staging/comedi/drivers/pcmad.c
+++ b/drivers/staging/comedi/drivers/pcmad.c
@@ -62,7 +62,6 @@ struct pcmad_priv_struct {
int differential;
int twos_comp;
};
-#define devpriv ((struct pcmad_priv_struct *)dev->private)
#define TIMEOUT 100
@@ -71,6 +70,7 @@ static int pcmad_ai_insn_read(struct comedi_device *dev,
struct comedi_insn *insn, unsigned int *data)
{
const struct pcmad_board_struct *board = comedi_board(dev);
+ struct pcmad_priv_struct *devpriv = dev->private;
int i;
int chan;
int n;
@@ -104,6 +104,7 @@ static int pcmad_ai_insn_read(struct comedi_device *dev,
static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct pcmad_board_struct *board = comedi_board(dev);
+ struct pcmad_priv_struct *devpriv;
int ret;
struct comedi_subdevice *s;
unsigned long iobase;
@@ -121,9 +122,10 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (ret)
return ret;
- ret = alloc_private(dev, sizeof(struct pcmad_priv_struct));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
dev->board_name = board->name;
diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c
index 28af8f6873e..0882dafaf57 100644
--- a/drivers/staging/comedi/drivers/pcmda12.c
+++ b/drivers/staging/comedi/drivers/pcmda12.c
@@ -64,13 +64,6 @@ Configuration Options:
#define MSB_PORT(chan) (LSB_PORT(chan)+1)
#define BITS 12
-/*
- * Bords
- */
-struct pcmda12_board {
- const char *name;
-};
-
/* note these have no effect and are merely here for reference..
these are configured by jumpering the board! */
static const struct comedi_lrange pcmda12_ranges = {
@@ -86,8 +79,6 @@ struct pcmda12_private {
int simultaneous_xfer_mode;
};
-#define devpriv ((struct pcmda12_private *)(dev->private))
-
static void zero_chans(struct comedi_device *dev)
{ /* sets up an
ASIC chip to defaults */
@@ -104,6 +95,7 @@ static void zero_chans(struct comedi_device *dev)
static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcmda12_private *devpriv = dev->private;
int i;
int chan = CR_CHAN(insn->chanspec);
@@ -146,6 +138,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct pcmda12_private *devpriv = dev->private;
int i;
int chan = CR_CHAN(insn->chanspec);
@@ -162,7 +155,7 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
static int pcmda12_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
- const struct pcmda12_board *board = comedi_board(dev);
+ struct pcmda12_private *devpriv;
struct comedi_subdevice *s;
unsigned long iobase;
int ret;
@@ -178,16 +171,12 @@ static int pcmda12_attach(struct comedi_device *dev,
}
dev->iobase = iobase;
- dev->board_name = board->name;
+ dev->board_name = dev->driver->driver_name;
-/*
- * Allocate the private structure area. alloc_private() is a
- * convenient macro defined in comedidev.h.
- */
- if (alloc_private(dev, sizeof(struct pcmda12_private)) < 0) {
- printk(KERN_ERR "cannot allocate private data structure\n");
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
- }
+ dev->private = devpriv;
devpriv->simultaneous_xfer_mode = it->options[1];
@@ -218,20 +207,11 @@ static void pcmda12_detach(struct comedi_device *dev)
release_region(dev->iobase, IOSIZE);
}
-static const struct pcmda12_board pcmda12_boards[] = {
- {
- .name = "pcmda12",
- },
-};
-
static struct comedi_driver pcmda12_driver = {
.driver_name = "pcmda12",
.module = THIS_MODULE,
.attach = pcmda12_attach,
.detach = pcmda12_detach,
- .board_name = &pcmda12_boards[0].name,
- .offset = sizeof(struct pcmda12_board),
- .num_names = ARRAY_SIZE(pcmda12_boards),
};
module_comedi_driver(pcmda12_driver);
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c
index a10bf0a2987..7522bfb6db0 100644
--- a/drivers/staging/comedi/drivers/pcmmio.c
+++ b/drivers/staging/comedi/drivers/pcmmio.c
@@ -145,35 +145,6 @@ Configuration Options:
#define PAGE_ENAB 2
#define PAGE_INT_ID 3
-/*
- * 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.
- */
-struct pcmmio_board {
- const char *name;
- const int dio_num_asics;
- const int dio_num_ports;
- const int total_iosize;
- const int ai_bits;
- const int ao_bits;
- const int n_ai_chans;
- const int n_ao_chans;
- const struct comedi_lrange *ai_range_table, *ao_range_table;
- int (*ai_rinsn) (struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
- int (*ao_rinsn) (struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
- int (*ao_winsn) (struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-};
-
static const struct comedi_lrange ranges_ai = {
4, {RANGE(-5., 5.), RANGE(-10., 10.), RANGE(0., 5.), RANGE(0., 10.)}
};
@@ -258,11 +229,6 @@ struct pcmmio_private {
struct pcmmio_subdev_private *sprivs;
};
-/*
- * most drivers define the following macro to make it easy to
- * access the private structure.
- */
-#define devpriv ((struct pcmmio_private *)dev->private)
#define subpriv ((struct pcmmio_subdev_private *)s->private)
/* DIO devices are slightly special. Although it is possible to
@@ -416,9 +382,9 @@ static int pcmmio_dio_insn_config(struct comedi_device *dev,
static void switch_page(struct comedi_device *dev, int asic, int page)
{
- const struct pcmmio_board *board = comedi_board(dev);
+ struct pcmmio_private *devpriv = dev->private;
- if (asic < 0 || asic >= board->dio_num_asics)
+ if (asic < 0 || asic >= 1)
return; /* paranoia */
if (page < 0 || page >= NUM_PAGES)
return; /* more paranoia */
@@ -434,10 +400,10 @@ static void switch_page(struct comedi_device *dev, int asic, int page)
static void init_asics(struct comedi_device *dev)
{ /* sets up an
ASIC chip to defaults */
- const struct pcmmio_board *board = comedi_board(dev);
+ struct pcmmio_private *devpriv = dev->private;
int asic;
- for (asic = 0; asic < board->dio_num_asics; ++asic) {
+ for (asic = 0; asic < 1; ++asic) {
int port, page;
unsigned long baseaddr = devpriv->asics[asic].iobase;
@@ -472,9 +438,9 @@ static void init_asics(struct comedi_device *dev)
#ifdef notused
static void lock_port(struct comedi_device *dev, int asic, int port)
{
- const struct pcmmio_board *board = comedi_board(dev);
+ struct pcmmio_private *devpriv = dev->private;
- if (asic < 0 || asic >= board->dio_num_asics)
+ if (asic < 0 || asic >= 1)
return; /* paranoia */
if (port < 0 || port >= PORTS_PER_ASIC)
return; /* more paranoia */
@@ -488,9 +454,9 @@ static void lock_port(struct comedi_device *dev, int asic, int port)
static void unlock_port(struct comedi_device *dev, int asic, int port)
{
- const struct pcmmio_board *board = comedi_board(dev);
+ struct pcmmio_private *devpriv = dev->private;
- if (asic < 0 || asic >= board->dio_num_asics)
+ if (asic < 0 || asic >= 1)
return; /* paranoia */
if (port < 0 || port >= PORTS_PER_ASIC)
return; /* more paranoia */
@@ -504,6 +470,7 @@ static void unlock_port(struct comedi_device *dev, int asic, int port)
static void pcmmio_stop_intr(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct pcmmio_private *devpriv = dev->private;
int nports, firstport, asic, port;
asic = subpriv->dio.intr.asic;
@@ -526,6 +493,7 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d)
{
int asic, got1 = 0;
struct comedi_device *dev = (struct comedi_device *)d;
+ struct pcmmio_private *devpriv = dev->private;
int i;
for (asic = 0; asic < MAX_ASICS; ++asic) {
@@ -685,6 +653,8 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d)
static int pcmmio_start_intr(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct pcmmio_private *devpriv = dev->private;
+
if (!subpriv->dio.intr.continuous && subpriv->dio.intr.stop_count == 0) {
/* An empty acquisition! */
s->async->events |= COMEDI_CB_EOA;
@@ -1012,7 +982,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- const struct pcmmio_board *board = comedi_board(dev);
+ struct pcmmio_private *devpriv;
struct comedi_subdevice *s;
int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic,
thisasic_chanct = 0;
@@ -1020,32 +990,25 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
unsigned int irq[MAX_ASICS];
int ret;
+ dev->board_name = dev->driver->driver_name;
+
iobase = it->options[0];
irq[0] = it->options[1];
printk(KERN_INFO "comedi%d: %s: io: %lx attaching...\n", dev->minor,
- dev->driver->driver_name, iobase);
+ dev->board_name, iobase);
dev->iobase = iobase;
- if (!iobase || !request_region(iobase,
- board->total_iosize,
- dev->driver->driver_name)) {
+ if (!iobase || !request_region(iobase, 32, dev->board_name)) {
printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor);
return -EIO;
}
- dev->board_name = board->name;
-
-/*
- * Allocate the private structure area. alloc_private() is a
- * convenient macro defined in comedidev.h.
- */
- if (alloc_private(dev, sizeof(struct pcmmio_private)) < 0) {
- printk(KERN_ERR "comedi%d: cannot allocate private data structure\n",
- dev->minor);
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
- }
+ dev->private = devpriv;
for (asic = 0; asic < MAX_ASICS; ++asic) {
devpriv->asics[asic].num = asic;
@@ -1059,7 +1022,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
spin_lock_init(&devpriv->asics[asic].spinlock);
}
- chans_left = CHANS_PER_ASIC * board->dio_num_asics;
+ chans_left = CHANS_PER_ASIC * 1;
n_dio_subdevs = CALC_N_DIO_SUBDEVS(chans_left);
n_subdevs = n_dio_subdevs + 2;
devpriv->sprivs =
@@ -1078,13 +1041,13 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
/* First, AI */
s = &dev->subdevices[0];
s->private = &devpriv->sprivs[0];
- s->maxdata = (1 << board->ai_bits) - 1;
- s->range_table = board->ai_range_table;
+ s->maxdata = 0xffff;
+ s->range_table = &ranges_ai;
s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
s->type = COMEDI_SUBD_AI;
- s->n_chan = board->n_ai_chans;
+ s->n_chan = 16;
s->len_chanlist = s->n_chan;
- s->insn_read = board->ai_rinsn;
+ s->insn_read = ai_rinsn;
subpriv->iobase = dev->iobase + 0;
/* initialize the resource enable register by clearing it */
outb(0, subpriv->iobase + 3);
@@ -1093,14 +1056,14 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
/* Next, AO */
s = &dev->subdevices[1];
s->private = &devpriv->sprivs[1];
- s->maxdata = (1 << board->ao_bits) - 1;
- s->range_table = board->ao_range_table;
+ s->maxdata = 0xffff;
+ s->range_table = &ranges_ao;
s->subdev_flags = SDF_READABLE;
s->type = COMEDI_SUBD_AO;
- s->n_chan = board->n_ao_chans;
+ s->n_chan = 8;
s->len_chanlist = s->n_chan;
- s->insn_read = board->ao_rinsn;
- s->insn_write = board->ao_winsn;
+ s->insn_read = ao_rinsn;
+ s->insn_write = ao_winsn;
subpriv->iobase = dev->iobase + 8;
/* initialize the resource enable register by clearing it */
outb(0, subpriv->iobase + 3);
@@ -1180,7 +1143,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) {
if (irq[asic]
&& request_irq(irq[asic], interrupt_pcmmio,
- IRQF_SHARED, board->name, dev)) {
+ IRQF_SHARED, dev->board_name, dev)) {
int i;
/* unroll the allocated irqs.. */
for (i = asic - 1; i >= 0; --i) {
@@ -1204,11 +1167,11 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
static void pcmmio_detach(struct comedi_device *dev)
{
- const struct pcmmio_board *board = comedi_board(dev);
+ struct pcmmio_private *devpriv = dev->private;
int i;
if (dev->iobase)
- release_region(dev->iobase, board->total_iosize);
+ release_region(dev->iobase, 32);
for (i = 0; i < MAX_ASICS; ++i) {
if (devpriv && devpriv->asics[i].irq)
free_irq(devpriv->asics[i].irq, dev);
@@ -1217,32 +1180,11 @@ static void pcmmio_detach(struct comedi_device *dev)
kfree(devpriv->sprivs);
}
-static const struct pcmmio_board pcmmio_boards[] = {
- {
- .name = "pcmmio",
- .dio_num_asics = 1,
- .dio_num_ports = 6,
- .total_iosize = 32,
- .ai_bits = 16,
- .ao_bits = 16,
- .n_ai_chans = 16,
- .n_ao_chans = 8,
- .ai_range_table = &ranges_ai,
- .ao_range_table = &ranges_ao,
- .ai_rinsn = ai_rinsn,
- .ao_rinsn = ao_rinsn,
- .ao_winsn = ao_winsn
- },
-};
-
static struct comedi_driver pcmmio_driver = {
.driver_name = "pcmmio",
.module = THIS_MODULE,
.attach = pcmmio_attach,
.detach = pcmmio_detach,
- .board_name = &pcmmio_boards[0].name,
- .offset = sizeof(struct pcmmio_board),
- .num_names = ARRAY_SIZE(pcmmio_boards),
};
module_comedi_driver(pcmmio_driver);
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
index 0e32119bc3f..31ea20c2d39 100644
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -194,11 +194,6 @@ struct pcmuio_private {
struct pcmuio_subdev_private *sprivs;
};
-/*
- * most drivers define the following macro to make it easy to
- * access the private structure.
- */
-#define devpriv ((struct pcmuio_private *)dev->private)
#define subpriv ((struct pcmuio_subdev_private *)s->private)
/* DIO devices are slightly special. Although it is possible to
@@ -348,6 +343,7 @@ static int pcmuio_dio_insn_config(struct comedi_device *dev,
static void switch_page(struct comedi_device *dev, int asic, int page)
{
const struct pcmuio_board *board = comedi_board(dev);
+ struct pcmuio_private *devpriv = dev->private;
if (asic < 0 || asic >= board->num_asics)
return; /* paranoia */
@@ -404,6 +400,7 @@ static void init_asics(struct comedi_device *dev)
static void lock_port(struct comedi_device *dev, int asic, int port)
{
const struct pcmuio_board *board = comedi_board(dev);
+ struct pcmuio_private *devpriv = dev->private;
if (asic < 0 || asic >= board->num_asics)
return; /* paranoia */
@@ -419,6 +416,7 @@ static void lock_port(struct comedi_device *dev, int asic, int port)
static void unlock_port(struct comedi_device *dev, int asic, int port)
{
const struct pcmuio_board *board = comedi_board(dev);
+ struct pcmuio_private *devpriv = dev->private;
if (asic < 0 || asic >= board->num_asics)
return; /* paranoia */
@@ -435,6 +433,7 @@ static void pcmuio_stop_intr(struct comedi_device *dev,
struct comedi_subdevice *s)
{
int nports, firstport, asic, port;
+ struct pcmuio_private *devpriv = dev->private;
asic = subpriv->intr.asic;
if (asic < 0)
@@ -456,6 +455,7 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d)
{
int asic, got1 = 0;
struct comedi_device *dev = (struct comedi_device *)d;
+ struct pcmuio_private *devpriv = dev->private;
int i;
for (asic = 0; asic < MAX_ASICS; ++asic) {
@@ -607,6 +607,8 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d)
static int pcmuio_start_intr(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ struct pcmuio_private *devpriv = dev->private;
+
if (!subpriv->intr.continuous && subpriv->intr.stop_count == 0) {
/* An empty acquisition! */
s->async->events |= COMEDI_CB_EOA;
@@ -748,6 +750,7 @@ pcmuio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct pcmuio_board *board = comedi_board(dev);
+ struct pcmuio_private *devpriv;
struct comedi_subdevice *s;
int sdev_no, chans_left, n_subdevs, port, asic, thisasic_chanct = 0;
unsigned long iobase;
@@ -772,15 +775,10 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
dev->board_name = board->name;
-/*
- * Allocate the private structure area. alloc_private() is a
- * convenient macro defined in comedidev.h.
- */
- if (alloc_private(dev, sizeof(struct pcmuio_private)) < 0) {
- dev_warn(dev->class_dev,
- "cannot allocate private data structure\n");
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
- }
+ dev->private = devpriv;
for (asic = 0; asic < MAX_ASICS; ++asic) {
devpriv->asics[asic].num = asic;
@@ -905,6 +903,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
static void pcmuio_detach(struct comedi_device *dev)
{
const struct pcmuio_board *board = comedi_board(dev);
+ struct pcmuio_private *devpriv = dev->private;
int i;
if (dev->iobase)
diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c
index 78dfe167b14..d7842c95d98 100644
--- a/drivers/staging/comedi/drivers/poc.c
+++ b/drivers/staging/comedi/drivers/poc.c
@@ -57,13 +57,18 @@ struct boarddef_struct {
const struct comedi_lrange *range;
};
+struct poc_private {
+ unsigned int ao_readback[32];
+};
+
static int readback_insn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct poc_private *devpriv = dev->private;
int chan;
chan = CR_CHAN(insn->chanspec);
- data[0] = ((unsigned int *)dev->private)[chan];
+ data[0] = devpriv->ao_readback[chan];
return 1;
}
@@ -75,12 +80,13 @@ static int readback_insn(struct comedi_device *dev, struct comedi_subdevice *s,
static int dac02_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct poc_private *devpriv = dev->private;
int temp;
int chan;
int output;
chan = CR_CHAN(insn->chanspec);
- ((unsigned int *)dev->private)[chan] = data[0];
+ devpriv->ao_readback[chan] = data[0];
output = data[0];
#ifdef wrong
/* convert to complementary binary if range is bipolar */
@@ -131,6 +137,7 @@ static int pcl734_insn_bits(struct comedi_device *dev,
static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct boarddef_struct *board = comedi_board(dev);
+ struct poc_private *devpriv;
struct comedi_subdevice *s;
unsigned long iobase;
unsigned int iosize;
@@ -160,8 +167,10 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (ret)
return ret;
- if (alloc_private(dev, sizeof(unsigned int) * board->n_chan) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
/* analog output subdevice */
s = &dev->subdevices[0];
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
index 3e276f7a338..ef0cdaa7f02 100644
--- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -47,6 +47,8 @@ Status: works
Devices: [Quatech] DAQP-208 (daqp), DAQP-308
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "../comedidev.h"
#include <linux/semaphore.h>
@@ -195,8 +197,8 @@ static struct comedi_driver driver_daqp = {
static void daqp_dump(struct comedi_device *dev)
{
- printk(KERN_INFO "DAQP: status %02x; aux status %02x\n",
- inb(dev->iobase + DAQP_STATUS), inb(dev->iobase + DAQP_AUX));
+ dev_info(dev->class_dev, "status %02x; aux status %02x\n",
+ inb(dev->iobase + DAQP_STATUS), inb(dev->iobase + DAQP_AUX));
}
static void hex_dump(char *str, void *ptr, int len)
@@ -255,33 +257,29 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id)
int status;
if (local == NULL) {
- printk(KERN_WARNING
- "daqp_interrupt(): irq %d for unknown device.\n", irq);
+ pr_warn("irq %d for unknown device.\n", irq);
return IRQ_NONE;
}
dev = local->dev;
if (dev == NULL) {
- printk(KERN_WARNING "daqp_interrupt(): NULL comedi_device.\n");
+ pr_warn("NULL comedi_device.\n");
return IRQ_NONE;
}
if (!dev->attached) {
- printk(KERN_WARNING
- "daqp_interrupt(): struct comedi_device not yet attached.\n");
+ pr_warn("struct comedi_device not yet attached.\n");
return IRQ_NONE;
}
s = local->s;
if (s == NULL) {
- printk(KERN_WARNING
- "daqp_interrupt(): NULL comedi_subdevice.\n");
+ pr_warn("NULL comedi_subdevice.\n");
return IRQ_NONE;
}
if ((struct local_info_t *)s->private != local) {
- printk(KERN_WARNING
- "daqp_interrupt(): invalid comedi_subdevice.\n");
+ pr_warn("invalid comedi_subdevice.\n");
return IRQ_NONE;
}
@@ -302,7 +300,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id)
if (status & DAQP_STATUS_DATA_LOST) {
s->async->events |=
COMEDI_CB_EOA | COMEDI_CB_OVERFLOW;
- printk("daqp: data lost\n");
+ dev_warn(dev->class_dev, "data lost\n");
daqp_ai_cancel(dev, s);
break;
}
@@ -331,8 +329,8 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id)
}
if (loop_limit <= 0) {
- printk(KERN_WARNING
- "loop_limit reached in daqp_interrupt()\n");
+ dev_warn(dev->class_dev,
+ "loop_limit reached in daqp_interrupt()\n");
daqp_ai_cancel(dev, s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
}
@@ -397,9 +395,11 @@ static int daqp_ai_insn_read(struct comedi_device *dev,
*/
while (--counter
- && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
+ && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS))
+ ;
if (!counter) {
- printk("daqp: couldn't clear interrupts in status register\n");
+ dev_err(dev->class_dev,
+ "couldn't clear interrupts in status register\n");
return -1;
}
@@ -482,19 +482,15 @@ static int daqp_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
#define MAX_SPEED 10000 /* 100 kHz - in nanoseconds */
- if (cmd->scan_begin_src == TRIG_TIMER
- && cmd->scan_begin_arg < MAX_SPEED) {
- cmd->scan_begin_arg = MAX_SPEED;
- err++;
- }
+ if (cmd->scan_begin_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ MAX_SPEED);
/* If both scan_begin and convert are both timer values, the only
* way that can make sense is if the scan time is the number of
@@ -503,30 +499,18 @@ static int daqp_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER && cmd->convert_src == TRIG_TIMER
&& cmd->scan_begin_arg != cmd->convert_arg * cmd->scan_end_arg) {
- err++;
+ err |= -EINVAL;
}
- if (cmd->convert_src == TRIG_TIMER && cmd->convert_arg < MAX_SPEED) {
- cmd->convert_arg = MAX_SPEED;
- err++;
- }
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg, MAX_SPEED);
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) {
- if (cmd->stop_arg > 0x00ffffff) {
- cmd->stop_arg = 0x00ffffff;
- err++;
- }
- } else {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -734,10 +718,11 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
*/
counter = 100;
while (--counter
- && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
+ && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS))
+ ;
if (!counter) {
- printk(KERN_ERR
- "daqp: couldn't clear interrupts in status register\n");
+ dev_err(dev->class_dev,
+ "couldn't clear interrupts in status register\n");
return -1;
}
@@ -824,8 +809,8 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
if (it->options[0] < 0 || it->options[0] >= MAX_DEV || !local) {
- printk("comedi%d: No such daqp device %d\n",
- dev->minor, it->options[0]);
+ dev_err(dev->class_dev, "No such daqp device %d\n",
+ it->options[0]);
return -EIO;
}
@@ -852,8 +837,8 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (ret)
return ret;
- printk(KERN_INFO "comedi%d: attaching daqp%d (io 0x%04lx)\n",
- dev->minor, it->options[0], dev->iobase);
+ dev_info(dev->class_dev, "attaching daqp%d (io 0x%04lx)\n",
+ it->options[0], dev->iobase);
s = &dev->subdevices[0];
dev->read_subdev = s;
@@ -958,7 +943,7 @@ static int daqp_cs_attach(struct pcmcia_device *link)
if (dev_table[i] == NULL)
break;
if (i == MAX_DEV) {
- printk(KERN_NOTICE "daqp_cs: no devices available\n");
+ dev_notice(&link->dev, "no devices available\n");
return -ENODEV;
}
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
index 41d24b08913..8d7c948a919 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -107,14 +107,12 @@ Configuration options:
#include "../comedidev.h"
#include "comedi_fc.h"
-
-#define DRV_NAME "rtd520"
+#include "rtd520.h"
+#include "plx9080.h"
/*======================================================================
Driver specific stuff (tunable)
======================================================================*/
-/* Enable this to test the new DMA support. You may get hard lock ups */
-/*#define USE_DMA*/
/* We really only need 2 buffers. More than that means being much
smarter about knowing which ones are full. */
@@ -147,20 +145,6 @@ Configuration options:
Board specific stuff
======================================================================*/
-/* registers */
-#define PCI_VENDOR_ID_RTD 0x1435
-/*
- The board has three memory windows: las0, las1, and lcfg (the PCI chip)
- Las1 has the data and can be burst DMAed 32bits at a time.
-*/
-#define LCFG_PCIINDEX 0
-/* PCI region 1 is a 256 byte IO space mapping. Use??? */
-#define LAS0_PCIINDEX 2 /* PCI memory resources */
-#define LAS1_PCIINDEX 3
-#define LCFG_PCISIZE 0x100
-#define LAS0_PCISIZE 0x200
-#define LAS1_PCISIZE 0x10
-
#define RTD_CLOCK_RATE 8000000 /* 8Mhz onboard clock */
#define RTD_CLOCK_BASE 125 /* clock period in ns */
@@ -173,9 +157,6 @@ Configuration options:
/* min speed when only 1 channel (no burst counter) */
#define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */
-#include "rtd520.h"
-#include "plx9080.h"
-
/* Setup continuous ring of 1/2 FIFO transfers. See RTD manual p91 */
#define DMA_MODE_BITS (\
PLX_LOCAL_BUS_16_WIDE_BITS \
@@ -270,30 +251,24 @@ static const struct comedi_lrange rtd_ao_range = {
struct rtdBoard {
const char *name;
int device_id;
- int aiChans;
- int aiBits;
- int aiMaxGain;
int range10Start; /* start of +-10V range */
int rangeUniStart; /* start of +10V range */
+ const struct comedi_lrange *ai_range;
};
static const struct rtdBoard rtd520Boards[] = {
{
.name = "DM7520",
.device_id = 0x7520,
- .aiChans = 16,
- .aiBits = 12,
- .aiMaxGain = 32,
.range10Start = 6,
.rangeUniStart = 12,
+ .ai_range = &rtd_ai_7520_range,
}, {
.name = "PCI4520",
.device_id = 0x4520,
- .aiChans = 16,
- .aiBits = 12,
- .aiMaxGain = 128,
.range10Start = 8,
.rangeUniStart = 16,
+ .ai_range = &rtd_ai_4520_range,
},
};
@@ -307,7 +282,6 @@ struct rtdPrivate {
void __iomem *las1;
void __iomem *lcfg;
- unsigned long intCount; /* interrupt count */
long aiCount; /* total transfer size (samples) */
int transCount; /* # to transfer data. 0->1/2FIFO */
int flags; /* flag event modes */
@@ -328,21 +302,6 @@ struct rtdPrivate {
u16 intClearMask; /* interrupt clear mask */
u8 utcCtrl[4]; /* crtl mode for 3 utc + read back */
u8 dioStatus; /* could be read back (dio0Ctrl) */
-#ifdef USE_DMA
- /*
- * Always DMA 1/2 FIFO. Buffer (dmaBuff?) is (at least) twice that
- * size. After transferring, interrupt processes 1/2 FIFO and
- * passes to comedi
- */
- s16 dma0Offset; /* current processing offset (0, 1/2) */
- uint16_t *dma0Buff[DMA_CHAIN_COUNT]; /* DMA buffers (for ADC) */
- dma_addr_t dma0BuffPhysAddr[DMA_CHAIN_COUNT]; /* physical addresses */
- struct plx_dma_desc *dma0Chain; /* DMA descriptor ring for dmaBuff */
- dma_addr_t dma0ChainPhysAddr; /* physical addresses */
- /* shadow registers */
- u8 dma0Control;
- u8 dma1Control;
-#endif /* USE_DMA */
unsigned fifoLen;
};
@@ -365,9 +324,9 @@ struct rtdPrivate {
Sets the original period to be the true value.
Note: you have to check if the value is larger than the counter range!
*/
-static int rtd_ns_to_timer_base(unsigned int *nanosec, /* desired period (in ns) */
+static int rtd_ns_to_timer_base(unsigned int *nanosec,
int round_mode, int base)
-{ /* clock period (in ns) */
+{
int divider;
switch (round_mode) {
@@ -420,18 +379,19 @@ static unsigned short rtdConvertChanGain(struct comedi_device *dev,
r |= chan & 0xf;
/* Note: we also setup the channel list bipolar flag array */
- if (range < thisboard->range10Start) { /* first batch are +-5 */
- r |= 0x000; /* +-5 range */
- r |= (range & 0x7) << 4; /* gain */
+ if (range < thisboard->range10Start) {
+ /* +-5 range */
+ r |= 0x000;
+ r |= (range & 0x7) << 4;
CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex);
- } else if (range < thisboard->rangeUniStart) { /* second batch are +-10 */
- r |= 0x100; /* +-10 range */
- /* gain */
+ } else if (range < thisboard->rangeUniStart) {
+ /* +-10 range */
+ r |= 0x100;
r |= ((range - thisboard->range10Start) & 0x7) << 4;
CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex);
- } else { /* last batch is +10 */
- r |= 0x200; /* +10 range */
- /* gain */
+ } else {
+ /* +10 range */
+ r |= 0x200;
r |= ((range - thisboard->rangeUniStart) & 0x7) << 4;
CHAN_ARRAY_CLEAR(devpriv->chanBipolar, chanIndex);
}
@@ -507,15 +467,14 @@ static int rtd520_probe_fifo_depth(struct comedi_device *dev)
}
}
if (i == limit) {
- printk(KERN_INFO "\ncomedi: %s: failed to probe fifo size.\n",
- DRV_NAME);
+ dev_info(dev->class_dev, "failed to probe fifo size.\n");
return -EIO;
}
writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
if (fifo_size != 0x400 && fifo_size != 0x2000) {
- printk
- (KERN_INFO "\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n",
- DRV_NAME, fifo_size);
+ dev_info(dev->class_dev,
+ "unexpected fifo size of %i, expected 1024 or 8192.\n",
+ fifo_size);
return -EIO;
}
return fifo_size;
@@ -558,12 +517,8 @@ static int rtd_ai_rinsn(struct comedi_device *dev,
break;
WAIT_QUIETLY;
}
- if (ii >= RTD_ADC_TIMEOUT) {
- DPRINTK
- ("rtd520: Error: ADC never finished! FifoStatus=0x%x\n",
- stat ^ 0x6666);
+ if (ii >= RTD_ADC_TIMEOUT)
return -ETIMEDOUT;
- }
/* read data */
d = readw(devpriv->las1 + LAS1_ADC_FIFO);
@@ -600,15 +555,8 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
d = readw(devpriv->las1 + LAS1_ADC_FIFO);
continue;
}
-#if 0
- if (!(readl(devpriv->las0 + LAS0_ADC) & FS_ADC_NOT_EMPTY)) {
- DPRINTK("comedi: READ OOPS on %d of %d\n", ii + 1,
- count);
- break;
- }
-#endif
- d = readw(devpriv->las1 + LAS1_ADC_FIFO);
+ d = readw(devpriv->las1 + LAS1_ADC_FIFO);
d = d >> 3; /* low 3 bits are marker lines */
if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
/* convert to comedi unsigned data */
@@ -656,125 +604,6 @@ static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
return 0;
}
-#ifdef USE_DMA
-/*
- Terminate a DMA transfer and wait for everything to quiet down
-*/
-void abort_dma(struct comedi_device *dev, unsigned int channel)
-{ /* DMA channel 0, 1 */
- struct rtdPrivate *devpriv = dev->private;
- unsigned long dma_cs_addr; /* the control/status register */
- uint8_t status;
- unsigned int ii;
- /* unsigned long flags; */
-
- dma_cs_addr = (unsigned long)devpriv->lcfg
- + ((channel == 0) ? LCFG_DMACSR0 : LCFG_DMACSR1);
-
- /* spinlock for plx dma control/status reg */
- /* spin_lock_irqsave( &dev->spinlock, flags ); */
-
- /* abort dma transfer if necessary */
- status = readb(dma_cs_addr);
- if ((status & PLX_DMA_EN_BIT) == 0) { /* not enabled (Error?) */
- DPRINTK("rtd520: AbortDma on non-active channel %d (0x%x)\n",
- channel, status);
- goto abortDmaExit;
- }
-
- /* wait to make sure done bit is zero (needed?) */
- for (ii = 0; (status & PLX_DMA_DONE_BIT) && ii < RTD_DMA_TIMEOUT; ii++) {
- WAIT_QUIETLY;
- status = readb(dma_cs_addr);
- }
- if (status & PLX_DMA_DONE_BIT) {
- printk("rtd520: Timeout waiting for dma %i done clear\n",
- channel);
- goto abortDmaExit;
- }
-
- /* disable channel (required) */
- writeb(0, dma_cs_addr);
- udelay(1); /* needed?? */
- /* set abort bit for channel */
- writeb(PLX_DMA_ABORT_BIT, dma_cs_addr);
-
- /* wait for dma done bit to be set */
- status = readb(dma_cs_addr);
- for (ii = 0;
- (status & PLX_DMA_DONE_BIT) == 0 && ii < RTD_DMA_TIMEOUT; ii++) {
- status = readb(dma_cs_addr);
- WAIT_QUIETLY;
- }
- if ((status & PLX_DMA_DONE_BIT) == 0) {
- printk("rtd520: Timeout waiting for dma %i done set\n",
- channel);
- }
-
-abortDmaExit:
- /* spin_unlock_irqrestore( &dev->spinlock, flags ); */
-}
-
-/*
- Process what is in the DMA transfer buffer and pass to comedi
- Note: this is not re-entrant
-*/
-static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct rtdPrivate *devpriv = dev->private;
- int ii, n;
- s16 *dp;
-
- if (devpriv->aiCount == 0) /* transfer already complete */
- return 0;
-
- dp = devpriv->dma0Buff[devpriv->dma0Offset];
- for (ii = 0; ii < devpriv->fifoLen / 2;) { /* convert samples */
- short sample;
-
- if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
- sample = (*dp >> 3) + 2048; /* convert to comedi unsigned data */
- else
- sample = *dp >> 3; /* low 3 bits are marker lines */
-
- *dp++ = sample; /* put processed value back */
-
- if (++s->async->cur_chan >= s->async->cmd.chanlist_len)
- s->async->cur_chan = 0;
-
- ++ii; /* number ready to transfer */
- if (devpriv->aiCount > 0) { /* < 0, means read forever */
- if (--devpriv->aiCount == 0) { /* done */
- /*DPRINTK ("rtd520: Final %d samples\n", ii); */
- break;
- }
- }
- }
-
- /* now pass the whole array to the comedi buffer */
- dp = devpriv->dma0Buff[devpriv->dma0Offset];
- n = comedi_buf_write_alloc(s->async, ii * sizeof(s16));
- if (n < (ii * sizeof(s16))) { /* any residual is an error */
- DPRINTK("rtd520:ai_process_dma buffer overflow %d samples!\n",
- ii - (n / sizeof(s16)));
- s->async->events |= COMEDI_CB_ERROR;
- return -1;
- }
- comedi_buf_memcpy_to(s->async, 0, dp, n);
- comedi_buf_write_free(s->async, n);
-
- /*
- * always at least 1 scan -- 1/2 FIFO is larger than our max scan list
- */
- s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
-
- if (++devpriv->dma0Offset >= DMA_CHAIN_COUNT) { /* next buffer */
- devpriv->dma0Offset = 0;
- }
- return 0;
-}
-#endif /* USE_DMA */
-
/*
Handle all rtd520 interrupts.
Runs atomically and is never re-entered.
@@ -794,47 +623,10 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */
if (!dev->attached)
return IRQ_NONE;
- devpriv->intCount++; /* DEBUG statistics */
-
fifoStatus = readl(devpriv->las0 + LAS0_ADC);
/* check for FIFO full, this automatically halts the ADC! */
- if (!(fifoStatus & FS_ADC_NOT_FULL)) { /* 0 -> full */
- DPRINTK("rtd520: FIFO full! fifo_status=0x%x\n", (fifoStatus ^ 0x6666) & 0x7777); /* should be all 0s */
+ if (!(fifoStatus & FS_ADC_NOT_FULL)) /* 0 -> full */
goto abortTransfer;
- }
-#ifdef USE_DMA
- if (devpriv->flags & DMA0_ACTIVE) { /* Check DMA */
- u32 istatus = readl(devpriv->lcfg + LCFG_ITCSR);
-
- if (istatus & ICS_DMA0_A) {
- if (ai_process_dma(dev, s) < 0) {
- DPRINTK
- ("rtd520: comedi read buffer overflow (DMA) with %ld to go!\n",
- devpriv->aiCount);
- devpriv->dma0Control &= ~PLX_DMA_START_BIT;
- devpriv->dma0Control |= PLX_CLEAR_DMA_INTR_BIT;
- writeb(devpriv->dma0Control,
- devpriv->lcfg + LCFG_DMACSR0);
- goto abortTransfer;
- }
-
- /*DPRINTK ("rtd520: DMA transfer: %ld to go, istatus %x\n",
- devpriv->aiCount, istatus); */
- devpriv->dma0Control &= ~PLX_DMA_START_BIT;
- devpriv->dma0Control |= PLX_CLEAR_DMA_INTR_BIT;
- writeb(devpriv->dma0Control,
- devpriv->lcfg + LCFG_DMACSR0);
- if (0 == devpriv->aiCount) { /* counted down */
- DPRINTK("rtd520: Samples Done (DMA).\n");
- goto transferDone;
- }
- comedi_event(dev, s);
- } else {
- /*DPRINTK ("rtd520: No DMA ready: istatus %x\n", istatus); */
- }
- }
- /* Fall through and check for other interrupt sources */
-#endif /* USE_DMA */
status = readw(devpriv->las0 + LAS0_IT);
/* if interrupt was not caused by our board, or handled above */
@@ -842,57 +634,38 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */
return IRQ_HANDLED;
if (status & IRQM_ADC_ABOUT_CNT) { /* sample count -> read FIFO */
- /* since the priority interrupt controller may have queued a sample
- counter interrupt, even though we have already finished,
- we must handle the possibility that there is no data here */
- if (!(fifoStatus & FS_ADC_HEMPTY)) { /* 0 -> 1/2 full */
- /*DPRINTK("rtd520: Sample int, reading 1/2FIFO. fifo_status 0x%x\n",
- (fifoStatus ^ 0x6666) & 0x7777); */
- if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0) {
- DPRINTK
- ("rtd520: comedi read buffer overflow (1/2FIFO) with %ld to go!\n",
- devpriv->aiCount);
+ /*
+ * since the priority interrupt controller may have queued
+ * a sample counter interrupt, even though we have already
+ * finished, we must handle the possibility that there is
+ * no data here
+ */
+ if (!(fifoStatus & FS_ADC_HEMPTY)) {
+ /* FIFO half full */
+ if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0)
goto abortTransfer;
- }
- if (0 == devpriv->aiCount) { /* counted down */
- DPRINTK("rtd520: Samples Done (1/2). fifo_status was 0x%x\n", (fifoStatus ^ 0x6666) & 0x7777); /* should be all 0s */
+
+ if (0 == devpriv->aiCount)
goto transferDone;
- }
+
comedi_event(dev, s);
- } else if (devpriv->transCount > 0) { /* read often */
- /*DPRINTK("rtd520: Sample int, reading %d fifo_status 0x%x\n",
- devpriv->transCount, (fifoStatus ^ 0x6666) & 0x7777); */
- if (fifoStatus & FS_ADC_NOT_EMPTY) { /* 1 -> not empty */
- if (ai_read_n(dev, s, devpriv->transCount) < 0) {
- DPRINTK
- ("rtd520: comedi read buffer overflow (N) with %ld to go!\n",
- devpriv->aiCount);
+ } else if (devpriv->transCount > 0) {
+ if (fifoStatus & FS_ADC_NOT_EMPTY) {
+ /* FIFO not empty */
+ if (ai_read_n(dev, s, devpriv->transCount) < 0)
goto abortTransfer;
- }
- if (0 == devpriv->aiCount) { /* counted down */
- DPRINTK
- ("rtd520: Samples Done (N). fifo_status was 0x%x\n",
- (fifoStatus ^ 0x6666) & 0x7777);
+
+ if (0 == devpriv->aiCount)
goto transferDone;
- }
+
comedi_event(dev, s);
}
- } else { /* wait for 1/2 FIFO (old) */
- DPRINTK
- ("rtd520: Sample int. Wait for 1/2. fifo_status 0x%x\n",
- (fifoStatus ^ 0x6666) & 0x7777);
}
- } else {
- DPRINTK("rtd520: unknown interrupt source!\n");
}
overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
- if (overrun) {
- DPRINTK
- ("rtd520: Interrupt overrun with %ld to go! over_status=0x%x\n",
- devpriv->aiCount, overrun);
+ if (overrun)
goto abortTransfer;
- }
/* clear the interrupt */
devpriv->intClearMask = status;
@@ -913,23 +686,9 @@ transferDone:
writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
devpriv->intMask = 0;
writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
-#ifdef USE_DMA
- if (devpriv->flags & DMA0_ACTIVE) {
- writel(readl(devpriv->lcfg + LCFG_ITCSR) & ~ICS_DMA0_E,
- devpriv->lcfg + LCFG_ITCSR);
- abort_dma(dev, 0);
- devpriv->flags &= ~DMA0_ACTIVE;
- /* if Using DMA, then we should have read everything by now */
- if (devpriv->aiCount > 0) {
- DPRINTK("rtd520: Lost DMA data! %ld remain\n",
- devpriv->aiCount);
- }
- }
-#endif /* USE_DMA */
if (devpriv->aiCount > 0) { /* there shouldn't be anything left */
fifoStatus = readl(devpriv->las0 + LAS0_ADC);
- DPRINTK("rtd520: Finishing up. %ld remain, fifoStat=%x\n", devpriv->aiCount, (fifoStatus ^ 0x6666) & 0x7777); /* should read all 0s */
ai_read_dregs(dev, s); /* read anything left in FIFO */
}
@@ -944,25 +703,10 @@ transferDone:
fifoStatus = readl(devpriv->las0 + LAS0_ADC);
overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
- DPRINTK
- ("rtd520: Acquisition complete. %ld ints, intStat=%x, overStat=%x\n",
- devpriv->intCount, status, overrun);
return IRQ_HANDLED;
}
-#if 0
-/*
- return the number of samples available
-*/
-static int rtd_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- /* TODO: This needs to mask interrupts, read_dregs, and then re-enable */
- /* Not sure what to do if DMA is active */
- return s->async->buf_write_count - s->async->buf_read_count;
-}
-#endif
-
/*
cmdtest tests a particular command to see if it is valid.
Using the cmdtest ioctl, a user can create a valid cmd
@@ -1001,103 +745,85 @@ static int rtd_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
if (cmd->scan_begin_src == TRIG_TIMER) {
/* Note: these are time periods, not actual rates */
if (1 == cmd->chanlist_len) { /* no scanning */
- if (cmd->scan_begin_arg < RTD_MAX_SPEED_1) {
- cmd->scan_begin_arg = RTD_MAX_SPEED_1;
+ if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ RTD_MAX_SPEED_1)) {
rtd_ns_to_timer(&cmd->scan_begin_arg,
TRIG_ROUND_UP);
- err++;
+ err |= -EINVAL;
}
- if (cmd->scan_begin_arg > RTD_MIN_SPEED_1) {
- cmd->scan_begin_arg = RTD_MIN_SPEED_1;
+ if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
+ RTD_MIN_SPEED_1)) {
rtd_ns_to_timer(&cmd->scan_begin_arg,
TRIG_ROUND_DOWN);
- err++;
+ err |= -EINVAL;
}
} else {
- if (cmd->scan_begin_arg < RTD_MAX_SPEED) {
- cmd->scan_begin_arg = RTD_MAX_SPEED;
+ if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ RTD_MAX_SPEED)) {
rtd_ns_to_timer(&cmd->scan_begin_arg,
TRIG_ROUND_UP);
- err++;
+ err |= -EINVAL;
}
- if (cmd->scan_begin_arg > RTD_MIN_SPEED) {
- cmd->scan_begin_arg = RTD_MIN_SPEED;
+ if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
+ RTD_MIN_SPEED)) {
rtd_ns_to_timer(&cmd->scan_begin_arg,
TRIG_ROUND_DOWN);
- err++;
+ err |= -EINVAL;
}
}
} else {
/* external trigger */
/* should be level/edge, hi/lo specification here */
/* should specify multiple external triggers */
- if (cmd->scan_begin_arg > 9) {
- cmd->scan_begin_arg = 9;
- err++;
- }
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
}
+
if (cmd->convert_src == TRIG_TIMER) {
if (1 == cmd->chanlist_len) { /* no scanning */
- if (cmd->convert_arg < RTD_MAX_SPEED_1) {
- cmd->convert_arg = RTD_MAX_SPEED_1;
+ if (cfc_check_trigger_arg_min(&cmd->convert_arg,
+ RTD_MAX_SPEED_1)) {
rtd_ns_to_timer(&cmd->convert_arg,
TRIG_ROUND_UP);
- err++;
+ err |= -EINVAL;
}
- if (cmd->convert_arg > RTD_MIN_SPEED_1) {
- cmd->convert_arg = RTD_MIN_SPEED_1;
+ if (cfc_check_trigger_arg_max(&cmd->convert_arg,
+ RTD_MIN_SPEED_1)) {
rtd_ns_to_timer(&cmd->convert_arg,
TRIG_ROUND_DOWN);
- err++;
+ err |= -EINVAL;
}
} else {
- if (cmd->convert_arg < RTD_MAX_SPEED) {
- cmd->convert_arg = RTD_MAX_SPEED;
+ if (cfc_check_trigger_arg_min(&cmd->convert_arg,
+ RTD_MAX_SPEED)) {
rtd_ns_to_timer(&cmd->convert_arg,
TRIG_ROUND_UP);
- err++;
+ err |= -EINVAL;
}
- if (cmd->convert_arg > RTD_MIN_SPEED) {
- cmd->convert_arg = RTD_MIN_SPEED;
+ if (cfc_check_trigger_arg_max(&cmd->convert_arg,
+ RTD_MIN_SPEED)) {
rtd_ns_to_timer(&cmd->convert_arg,
TRIG_ROUND_DOWN);
- err++;
+ err |= -EINVAL;
}
}
} else {
/* external trigger */
/* see above */
- if (cmd->convert_arg > 9) {
- cmd->convert_arg = 9;
- err++;
- }
+ err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9);
}
-#if 0
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
-#endif
if (cmd->stop_src == TRIG_COUNT) {
/* TODO check for rounding error due to counter wrap */
-
} else {
/* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
}
if (err)
@@ -1159,28 +885,8 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
devpriv->intMask = 0;
writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
-#ifdef USE_DMA
- if (devpriv->flags & DMA0_ACTIVE) { /* cancel anything running */
- writel(readl(devpriv->lcfg + LCFG_ITCSR) & ~ICS_DMA0_E,
- devpriv->lcfg + LCFG_ITCSR);
- abort_dma(dev, 0);
- devpriv->flags &= ~DMA0_ACTIVE;
- if (readl(devpriv->lcfg + LCFG_ITCSR) & ICS_DMA0_A) {
- devpriv->dma0Control = PLX_CLEAR_DMA_INTR_BIT;
- writeb(devpriv->dma0Control,
- devpriv->lcfg + LCFG_DMACSR0);
- }
- }
- writel(0, devpriv->las0 + LAS0_DMA0_RESET);
-#endif /* USE_DMA */
writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
writel(0, devpriv->las0 + LAS0_OVERRUN);
- devpriv->intCount = 0;
-
- if (!dev->irq) { /* we need interrupts for this */
- DPRINTK("rtd520: ERROR! No interrupt available!\n");
- return -ENXIO;
- }
/* start configuration */
/* load channel list and reset CGT */
@@ -1188,7 +894,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* setup the common case and override if needed */
if (cmd->chanlist_len > 1) {
- /*DPRINTK ("rtd520: Multi channel setup\n"); */
/* pacer start source: SOFTWARE */
writel(0, devpriv->las0 + LAS0_PACER_START);
/* burst trigger source: PACER */
@@ -1196,7 +901,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* ADC conversion trigger source: BURST */
writel(2, devpriv->las0 + LAS0_ADC_CONVERSION);
} else { /* single channel */
- /*DPRINTK ("rtd520: single channel setup\n"); */
/* pacer start source: SOFTWARE */
writel(0, devpriv->las0 + LAS0_PACER_START);
/* ADC conversion trigger source: PACER */
@@ -1208,8 +912,11 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* scan_begin_arg is in nanoseconds */
/* find out how many samples to wait before transferring */
if (cmd->flags & TRIG_WAKE_EOS) {
- /* this may generate un-sustainable interrupt rates */
- /* the application is responsible for doing the right thing */
+ /*
+ * this may generate un-sustainable interrupt rates
+ * the application is responsible for doing the
+ * right thing
+ */
devpriv->transCount = cmd->chanlist_len;
devpriv->flags |= SEND_EOS;
} else {
@@ -1239,11 +946,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
writel((devpriv->transCount - 1) & 0xffff,
devpriv->las0 + LAS0_ACNT);
}
-
- DPRINTK
- ("rtd520: scanLen=%d transferCount=%d fifoLen=%d\n scanTime(ns)=%d flags=0x%x\n",
- cmd->chanlist_len, devpriv->transCount, devpriv->fifoLen,
- cmd->scan_begin_arg, devpriv->flags);
} else { /* unknown timing, just use 1/2 FIFO */
devpriv->transCount = 0;
devpriv->flags &= ~SEND_EOS;
@@ -1268,10 +970,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
case TRIG_NONE: /* stop when cancel is called */
devpriv->aiCount = -1; /* read forever */
break;
-
- default:
- DPRINTK("rtd520: Warning! ignoring stop_src mode %d\n",
- cmd->stop_src);
}
/* Scan timing */
@@ -1280,7 +978,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
TRIG_ROUND_NEAREST);
/* set PACER clock */
- /*DPRINTK ("rtd520: loading %d into pacer\n", timer); */
writel(timer & 0xffffff, devpriv->las0 + LAS0_PCLK);
break;
@@ -1289,20 +986,16 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* pacer start source: EXTERNAL */
writel(1, devpriv->las0 + LAS0_PACER_START);
break;
-
- default:
- DPRINTK("rtd520: Warning! ignoring scan_begin_src mode %d\n",
- cmd->scan_begin_src);
}
/* Sample timing within a scan */
switch (cmd->convert_src) {
case TRIG_TIMER: /* periodic */
- if (cmd->chanlist_len > 1) { /* only needed for multi-channel */
+ if (cmd->chanlist_len > 1) {
+ /* only needed for multi-channel */
timer = rtd_ns_to_timer(&cmd->convert_arg,
TRIG_ROUND_NEAREST);
/* setup BURST clock */
- /*DPRINTK ("rtd520: loading %d into burst\n", timer); */
writel(timer & 0x3ff, devpriv->las0 + LAS0_BCLK);
}
@@ -1312,10 +1005,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* burst trigger source: EXTERNAL */
writel(2, devpriv->las0 + LAS0_BURST_START);
break;
-
- default:
- DPRINTK("rtd520: Warning! ignoring convert_src mode %d\n",
- cmd->convert_src);
}
/* end configuration */
@@ -1329,34 +1018,9 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
if (devpriv->transCount > 0) { /* transfer every N samples */
devpriv->intMask = IRQM_ADC_ABOUT_CNT;
writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
- DPRINTK("rtd520: Transferring every %d\n", devpriv->transCount);
} else { /* 1/2 FIFO transfers */
-#ifdef USE_DMA
- devpriv->flags |= DMA0_ACTIVE;
-
- /* point to first transfer in ring */
- devpriv->dma0Offset = 0;
- writel(DMA_MODE_BITS, devpriv->lcfg + LCFG_DMAMODE0);
- /* point to first block */
- writel(devpriv->dma0Chain[DMA_CHAIN_COUNT - 1].next,
- devpriv->lcfg + LCFG_DMADPR0);
- writel(DMAS_ADFIFO_HALF_FULL, devpriv->las0 + LAS0_DMA0_SRC);
- writel(readl(devpriv->lcfg + LCFG_ITCSR) | ICS_DMA0_E,
- devpriv->lcfg + LCFG_ITCSR);
- /* Must be 2 steps. See PLX app note about "Starting a DMA transfer" */
- devpriv->dma0Control = PLX_DMA_EN_BIT;
- writeb(devpriv->dma0Control,
- devpriv->lcfg + LCFG_DMACSR0);
- devpriv->dma0Control |= PLX_DMA_START_BIT;
- writeb(devpriv->dma0Control,
- devpriv->lcfg + LCFG_DMACSR0);
- DPRINTK("rtd520: Using DMA0 transfers. plxInt %x RtdInt %x\n",
- readl(devpriv->lcfg + LCFG_ITCSR), devpriv->intMask);
-#else /* USE_DMA */
devpriv->intMask = IRQM_ADC_ABOUT_CNT;
writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
- DPRINTK("rtd520: Transferring every 1/2 FIFO\n");
-#endif /* USE_DMA */
}
/* BUG: start_src is ASSUMED to be TRIG_NOW */
@@ -1381,19 +1045,8 @@ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->intMask = 0;
writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
devpriv->aiCount = 0; /* stop and don't transfer any more */
-#ifdef USE_DMA
- if (devpriv->flags & DMA0_ACTIVE) {
- writel(readl(devpriv->lcfg + LCFG_ITCSR) & ~ICS_DMA0_E,
- devpriv->lcfg + LCFG_ITCSR);
- abort_dma(dev, 0);
- devpriv->flags &= ~DMA0_ACTIVE;
- }
-#endif /* USE_DMA */
status = readw(devpriv->las0 + LAS0_IT);
overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
- DPRINTK
- ("rtd520: Acquisition canceled. %ld ints, intStat=%x, overStat=%x\n",
- devpriv->intCount, status, overrun);
return 0;
}
@@ -1430,14 +1083,11 @@ static int rtd_ao_winsn(struct comedi_device *dev,
val = data[i] << 3;
}
- DPRINTK
- ("comedi: rtd520 DAC chan=%d range=%d writing %d as 0x%x\n",
- chan, range, data[i], val);
-
/* a typical programming sequence */
writew(val, devpriv->las1 +
((chan == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO));
- writew(0, devpriv->las0 + ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2));
+ writew(0, devpriv->las0 +
+ ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2));
devpriv->aoValue[chan] = data[i]; /* save for read back */
@@ -1449,12 +1099,8 @@ static int rtd_ao_winsn(struct comedi_device *dev,
break;
WAIT_QUIETLY;
}
- if (ii >= RTD_DAC_TIMEOUT) {
- DPRINTK
- ("rtd520: Error: DAC never finished! FifoStatus=0x%x\n",
- stat ^ 0x6666);
+ if (ii >= RTD_DAC_TIMEOUT)
return -ETIMEDOUT;
- }
}
/* return the number of samples read/written */
@@ -1507,8 +1153,6 @@ static int rtd_dio_insn_bits(struct comedi_device *dev,
* input lines. */
data[1] = readw(devpriv->las0 + LAS0_DIO0) & 0xff;
- /*DPRINTK("rtd520:port_0 wrote: 0x%x read: 0x%x\n", s->state, data[1]); */
-
return insn->n;
}
@@ -1542,7 +1186,6 @@ static int rtd_dio_insn_config(struct comedi_device *dev,
return -EINVAL;
}
- DPRINTK("rtd520: port_0_direction=0x%x (1 means out)\n", s->io_bits);
/* TODO support digital match interrupts and strobes */
devpriv->dioStatus = 0x01; /* set direction */
writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS);
@@ -1557,356 +1200,194 @@ static int rtd_dio_insn_config(struct comedi_device *dev,
return 1;
}
-static struct pci_dev *rtd_find_pci(struct comedi_device *dev,
- struct comedi_devconfig *it)
+static void rtd_reset(struct comedi_device *dev)
+{
+ struct rtdPrivate *devpriv = dev->private;
+
+ writel(0, devpriv->las0 + LAS0_BOARD_RESET);
+ udelay(100); /* needed? */
+ writel(0, devpriv->lcfg + LCFG_ITCSR);
+ devpriv->intMask = 0;
+ writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
+ devpriv->intClearMask = ~0;
+ writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR);
+ readw(devpriv->las0 + LAS0_CLEAR);
+}
+
+/*
+ * initialize board, per RTD spec
+ * also, initialize shadow registers
+ */
+static void rtd_init_board(struct comedi_device *dev)
+{
+ struct rtdPrivate *devpriv = dev->private;
+
+ rtd_reset(dev);
+
+ writel(0, devpriv->las0 + LAS0_OVERRUN);
+ writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
+ writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
+ writel(0, devpriv->las0 + LAS0_DAC1_RESET);
+ writel(0, devpriv->las0 + LAS0_DAC2_RESET);
+ /* clear digital IO fifo */
+ devpriv->dioStatus = 0;
+ writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS);
+ devpriv->utcCtrl[0] = (0 << 6) | 0x30;
+ devpriv->utcCtrl[1] = (1 << 6) | 0x30;
+ devpriv->utcCtrl[2] = (2 << 6) | 0x30;
+ devpriv->utcCtrl[3] = (3 << 6) | 0x00;
+ writeb(devpriv->utcCtrl[0], devpriv->las0 + LAS0_UTC_CTRL);
+ writeb(devpriv->utcCtrl[1], devpriv->las0 + LAS0_UTC_CTRL);
+ writeb(devpriv->utcCtrl[2], devpriv->las0 + LAS0_UTC_CTRL);
+ writeb(devpriv->utcCtrl[3], devpriv->las0 + LAS0_UTC_CTRL);
+ /* TODO: set user out source ??? */
+}
+
+/* The RTD driver does this */
+static void rtd_pci_latency_quirk(struct comedi_device *dev,
+ struct pci_dev *pcidev)
+{
+ unsigned char pci_latency;
+
+ pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency);
+ if (pci_latency < 32) {
+ dev_info(dev->class_dev,
+ "PCI latency changed from %d to %d\n",
+ pci_latency, 32);
+ pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32);
+ }
+}
+
+static const void *rtd_find_boardinfo(struct comedi_device *dev,
+ struct pci_dev *pcidev)
{
const struct rtdBoard *thisboard;
- struct pci_dev *pcidev = NULL;
- int bus = it->options[0];
- int slot = it->options[1];
int i;
- for_each_pci_dev(pcidev) {
- if (pcidev->vendor != PCI_VENDOR_ID_RTD)
- continue;
- if (bus || slot) {
- if (pcidev->bus->number != bus ||
- PCI_SLOT(pcidev->devfn) != slot)
- continue;
- }
- for (i = 0; i < ARRAY_SIZE(rtd520Boards); i++) {
- thisboard = &rtd520Boards[i];
- if (pcidev->device == thisboard->device_id) {
- dev->board_ptr = thisboard;
- return pcidev;
- }
- }
+ for (i = 0; i < ARRAY_SIZE(rtd520Boards); i++) {
+ thisboard = &rtd520Boards[i];
+ if (pcidev->device == thisboard->device_id)
+ return thisboard;
}
- dev_warn(dev->class_dev,
- "no supported board found! (req. bus/slot: %d/%d)\n",
- bus, slot);
return NULL;
}
-static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{ /* board name and options flags */
+static int rtd_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct rtdBoard *thisboard;
struct rtdPrivate *devpriv;
- struct pci_dev *pcidev;
struct comedi_subdevice *s;
- resource_size_t pci_base;
int ret;
-#ifdef USE_DMA
- int index;
-#endif
- printk(KERN_INFO "comedi%d: rtd520 attaching.\n", dev->minor);
-
-#if defined(CONFIG_COMEDI_DEBUG) && defined(USE_DMA)
- /* You can set this a load time: modprobe comedi comedi_debug=1 */
- if (0 == comedi_debug) /* force DMA debug printks */
- comedi_debug = 1;
-#endif
+ thisboard = rtd_find_boardinfo(dev, pcidev);
+ if (!thisboard)
+ return -ENODEV;
+ dev->board_ptr = thisboard;
+ dev->board_name = thisboard->name;
- /*
- * Allocate the private structure area. alloc_private() is a
- * convenient macro defined in comedidev.h.
- */
- if (alloc_private(dev, sizeof(struct rtdPrivate)) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
- devpriv = dev->private;
+ dev->private = devpriv;
- pcidev = rtd_find_pci(dev, it);
- if (!pcidev)
- return -EIO;
- comedi_set_hw_dev(dev, &pcidev->dev);
- thisboard = comedi_board(dev);
-
- dev->board_name = thisboard->name;
-
- ret = comedi_pci_enable(pcidev, DRV_NAME);
- if (ret < 0) {
- printk(KERN_INFO "Failed to enable PCI device and request regions.\n");
+ ret = comedi_pci_enable(pcidev, dev->board_name);
+ if (ret)
return ret;
- }
dev->iobase = 1; /* the "detach" needs this */
- /* Initialize the base addresses */
- pci_base = pci_resource_start(pcidev, LAS0_PCIINDEX);
- devpriv->las0 = ioremap_nocache(pci_base, LAS0_PCISIZE);
- pci_base = pci_resource_start(pcidev, LAS1_PCIINDEX);
- devpriv->las1 = ioremap_nocache(pci_base, LAS1_PCISIZE);
- pci_base = pci_resource_start(pcidev, LCFG_PCIINDEX);
- devpriv->lcfg = ioremap_nocache(pci_base, LCFG_PCISIZE);
+ devpriv->las0 = ioremap_nocache(pci_resource_start(pcidev, 2),
+ pci_resource_len(pcidev, 2));
+ devpriv->las1 = ioremap_nocache(pci_resource_start(pcidev, 3),
+ pci_resource_len(pcidev, 3));
+ devpriv->lcfg = ioremap_nocache(pci_resource_start(pcidev, 0),
+ pci_resource_len(pcidev, 0));
if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg)
return -ENOMEM;
- { /* The RTD driver does this */
- unsigned char pci_latency;
- u16 revision;
- /*uint32_t epld_version; */
-
- pci_read_config_word(pcidev, PCI_REVISION_ID,
- &revision);
- DPRINTK("%s: PCI revision %d.\n", dev->board_name, revision);
-
- pci_read_config_byte(pcidev,
- PCI_LATENCY_TIMER, &pci_latency);
- if (pci_latency < 32) {
- printk(KERN_INFO "%s: PCI latency changed from %d to %d\n",
- dev->board_name, pci_latency, 32);
- pci_write_config_byte(pcidev,
- PCI_LATENCY_TIMER, 32);
- } else {
- DPRINTK("rtd520: PCI latency = %d\n", pci_latency);
- }
+ rtd_pci_latency_quirk(dev, pcidev);
- /*
- * Undocumented EPLD version (doesn't match RTD driver results)
- */
- /*DPRINTK ("rtd520: Reading epld from %p\n",
- devpriv->las0+0);
- epld_version = readl (devpriv->las0+0);
- if ((epld_version & 0xF0) >> 4 == 0x0F) {
- DPRINTK("rtd520: pre-v8 EPLD. (%x)\n", epld_version);
- } else {
- DPRINTK("rtd520: EPLD version %x.\n", epld_version >> 4);
- } */
+ if (pcidev->irq) {
+ ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED,
+ dev->board_name, dev);
+ if (ret == 0)
+ dev->irq = pcidev->irq;
}
- /* Show board configuration */
- printk(KERN_INFO "%s:", dev->board_name);
-
ret = comedi_alloc_subdevices(dev, 4);
if (ret)
return ret;
s = &dev->subdevices[0];
- dev->read_subdev = s;
/* analog input subdevice */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags =
- SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ;
- s->n_chan = thisboard->aiChans;
- s->maxdata = (1 << thisboard->aiBits) - 1;
- if (thisboard->aiMaxGain <= 32)
- s->range_table = &rtd_ai_7520_range;
- else
- s->range_table = &rtd_ai_4520_range;
-
- s->len_chanlist = RTD_MAX_CHANLIST; /* devpriv->fifoLen */
- s->insn_read = rtd_ai_rinsn;
- s->do_cmd = rtd_ai_cmd;
- s->do_cmdtest = rtd_ai_cmdtest;
- s->cancel = rtd_ai_cancel;
- /* s->poll = rtd_ai_poll; *//* not ready yet */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
+ s->n_chan = 16;
+ s->maxdata = 0x0fff;
+ s->range_table = thisboard->ai_range;
+ s->len_chanlist = RTD_MAX_CHANLIST;
+ s->insn_read = rtd_ai_rinsn;
+ if (dev->irq) {
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmd = rtd_ai_cmd;
+ s->do_cmdtest = rtd_ai_cmdtest;
+ s->cancel = rtd_ai_cancel;
+ }
s = &dev->subdevices[1];
/* analog output subdevice */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = (1 << thisboard->aiBits) - 1;
- s->range_table = &rtd_ao_range;
- s->insn_write = rtd_ao_winsn;
- s->insn_read = rtd_ao_rinsn;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->maxdata = 0x0fff;
+ s->range_table = &rtd_ao_range;
+ s->insn_write = rtd_ao_winsn;
+ s->insn_read = rtd_ao_rinsn;
s = &dev->subdevices[2];
/* digital i/o subdevice */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
/* we only support port 0 right now. Ignoring port 1 and user IO */
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = rtd_dio_insn_bits;
- s->insn_config = rtd_dio_insn_config;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = rtd_dio_insn_bits;
+ s->insn_config = rtd_dio_insn_config;
/* timer/counter subdevices (not currently supported) */
s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 3;
- s->maxdata = 0xffff;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 3;
+ s->maxdata = 0xffff;
- /* initialize board, per RTD spec */
- /* also, initialize shadow registers */
- writel(0, devpriv->las0 + LAS0_BOARD_RESET);
- udelay(100); /* needed? */
- writel(0, devpriv->lcfg + LCFG_ITCSR);
- devpriv->intMask = 0;
- writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
- devpriv->intClearMask = ~0;
- writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR);
- readw(devpriv->las0 + LAS0_CLEAR);
- writel(0, devpriv->las0 + LAS0_OVERRUN);
- writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
- writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
- writel(0, devpriv->las0 + LAS0_DAC1_RESET);
- writel(0, devpriv->las0 + LAS0_DAC2_RESET);
- /* clear digital IO fifo */
- devpriv->dioStatus = 0;
- writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS);
- devpriv->utcCtrl[0] = (0 << 6) | 0x30;
- devpriv->utcCtrl[1] = (1 << 6) | 0x30;
- devpriv->utcCtrl[2] = (2 << 6) | 0x30;
- devpriv->utcCtrl[3] = (3 << 6) | 0x00;
- writeb(devpriv->utcCtrl[0], devpriv->las0 + LAS0_UTC_CTRL);
- writeb(devpriv->utcCtrl[1], devpriv->las0 + LAS0_UTC_CTRL);
- writeb(devpriv->utcCtrl[2], devpriv->las0 + LAS0_UTC_CTRL);
- writeb(devpriv->utcCtrl[3], devpriv->las0 + LAS0_UTC_CTRL);
- /* TODO: set user out source ??? */
-
- /* check if our interrupt is available and get it */
- ret = request_irq(pcidev->irq, rtd_interrupt,
- IRQF_SHARED, DRV_NAME, dev);
-
- if (ret < 0) {
- printk("Could not get interrupt! (%u)\n",
- pcidev->irq);
- return ret;
- }
- dev->irq = pcidev->irq;
- printk(KERN_INFO "( irq=%u )", dev->irq);
+ rtd_init_board(dev);
ret = rtd520_probe_fifo_depth(dev);
if (ret < 0)
return ret;
-
devpriv->fifoLen = ret;
- printk("( fifoLen=%d )", devpriv->fifoLen);
-
-#ifdef USE_DMA
- if (dev->irq > 0) {
- printk("( DMA buff=%d )\n", DMA_CHAIN_COUNT);
- /*
- * The PLX9080 has 2 DMA controllers, but there could be
- * 4 sources: ADC, digital, DAC1, and DAC2. Since only the
- * ADC supports cmd mode right now, this isn't an issue (yet)
- */
- devpriv->dma0Offset = 0;
-
- for (index = 0; index < DMA_CHAIN_COUNT; index++) {
- devpriv->dma0Buff[index] =
- pci_alloc_consistent(pcidev,
- sizeof(u16) *
- devpriv->fifoLen / 2,
- &devpriv->
- dma0BuffPhysAddr[index]);
- if (devpriv->dma0Buff[index] == NULL) {
- ret = -ENOMEM;
- goto rtd_attach_die_error;
- }
- /*DPRINTK ("buff[%d] @ %p virtual, %x PCI\n",
- index,
- devpriv->dma0Buff[index],
- devpriv->dma0BuffPhysAddr[index]); */
- }
-
- /*
- * setup DMA descriptor ring (use cpu_to_le32 for byte
- * ordering?)
- */
- devpriv->dma0Chain =
- pci_alloc_consistent(pcidev,
- sizeof(struct plx_dma_desc) *
- DMA_CHAIN_COUNT,
- &devpriv->dma0ChainPhysAddr);
- for (index = 0; index < DMA_CHAIN_COUNT; index++) {
- devpriv->dma0Chain[index].pci_start_addr =
- devpriv->dma0BuffPhysAddr[index];
- devpriv->dma0Chain[index].local_start_addr =
- DMALADDR_ADC;
- devpriv->dma0Chain[index].transfer_size =
- sizeof(u16) * devpriv->fifoLen / 2;
- devpriv->dma0Chain[index].next =
- (devpriv->dma0ChainPhysAddr + ((index +
- 1) %
- (DMA_CHAIN_COUNT))
- * sizeof(devpriv->dma0Chain[0]))
- | DMA_TRANSFER_BITS;
- /*DPRINTK ("ring[%d] @%lx PCI: %x, local: %x, N: 0x%x, next: %x\n",
- index,
- ((long)devpriv->dma0ChainPhysAddr
- + (index * sizeof(devpriv->dma0Chain[0]))),
- devpriv->dma0Chain[index].pci_start_addr,
- devpriv->dma0Chain[index].local_start_addr,
- devpriv->dma0Chain[index].transfer_size,
- devpriv->dma0Chain[index].next); */
- }
-
- if (devpriv->dma0Chain == NULL) {
- ret = -ENOMEM;
- goto rtd_attach_die_error;
- }
-
- writel(DMA_MODE_BITS, devpriv->lcfg + LCFG_DMAMODE0);
- /* set DMA trigger source */
- writel(DMAS_ADFIFO_HALF_FULL, devpriv->las0 + LAS0_DMA0_SRC);
- } else {
- printk(KERN_INFO "( no IRQ->no DMA )");
- }
-#endif /* USE_DMA */
if (dev->irq)
writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + LCFG_ITCSR);
- printk("\ncomedi%d: rtd520 driver attached.\n", dev->minor);
+ dev_info(dev->class_dev, "%s attached\n", dev->board_name);
- return 1;
+ return 0;
}
static void rtd_detach(struct comedi_device *dev)
{
struct rtdPrivate *devpriv = dev->private;
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-#ifdef USE_DMA
- int index;
-#endif
if (devpriv) {
/* Shut down any board ops by resetting it */
-#ifdef USE_DMA
- if (devpriv->lcfg) {
- devpriv->dma0Control = 0;
- devpriv->dma1Control = 0;
- writeb(devpriv->dma0Control,
- devpriv->lcfg + LCFG_DMACSR0);
- writeb(devpriv->dma1Control,
- devpriv->lcfg + LCFG_DMACSR1);
- writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + LCFG_ITCSR);
- }
-#endif /* USE_DMA */
- if (devpriv->las0) {
- writel(0, devpriv->las0 + LAS0_BOARD_RESET);
- devpriv->intMask = 0;
- writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
- devpriv->intClearMask = ~0;
- writew(devpriv->intClearMask,
- devpriv->las0 + LAS0_CLEAR);
- readw(devpriv->las0 + LAS0_CLEAR);
- }
-#ifdef USE_DMA
- /* release DMA */
- for (index = 0; index < DMA_CHAIN_COUNT; index++) {
- if (NULL != devpriv->dma0Buff[index]) {
- pci_free_consistent(pcidev,
- sizeof(u16) *
- devpriv->fifoLen / 2,
- devpriv->dma0Buff[index],
- devpriv->
- dma0BuffPhysAddr[index]);
- devpriv->dma0Buff[index] = NULL;
- }
- }
- if (NULL != devpriv->dma0Chain) {
- pci_free_consistent(pcidev,
- sizeof(struct plx_dma_desc) *
- DMA_CHAIN_COUNT, devpriv->dma0Chain,
- devpriv->dma0ChainPhysAddr);
- devpriv->dma0Chain = NULL;
- }
-#endif /* USE_DMA */
+ if (devpriv->las0 && devpriv->lcfg)
+ rtd_reset(dev);
if (dev->irq) {
writel(readl(devpriv->lcfg + LCFG_ITCSR) &
~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E),
@@ -1923,24 +1404,23 @@ static void rtd_detach(struct comedi_device *dev)
if (pcidev) {
if (dev->iobase)
comedi_pci_disable(pcidev);
- pci_dev_put(pcidev);
}
}
static struct comedi_driver rtd520_driver = {
.driver_name = "rtd520",
.module = THIS_MODULE,
- .attach = rtd_attach,
+ .auto_attach = rtd_auto_attach,
.detach = rtd_detach,
};
-static int __devinit rtd520_pci_probe(struct pci_dev *dev,
+static int rtd520_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &rtd520_driver);
}
-static void __devexit rtd520_pci_remove(struct pci_dev *dev)
+static void rtd520_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -1956,7 +1436,7 @@ static struct pci_driver rtd520_pci_driver = {
.name = "rtd520",
.id_table = rtd520_pci_table,
.probe = rtd520_pci_probe,
- .remove = __devexit_p(rtd520_pci_remove),
+ .remove = rtd520_pci_remove,
};
module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver);
diff --git a/drivers/staging/comedi/drivers/rtd520.h b/drivers/staging/comedi/drivers/rtd520.h
index a3ec2599c4b..25188a58145 100644
--- a/drivers/staging/comedi/drivers/rtd520.h
+++ b/drivers/staging/comedi/drivers/rtd520.h
@@ -26,163 +26,132 @@
*/
/*
- LAS0 Runtime Area
- Local Address Space 0 Offset Read Function Write Function
-*/
-#define LAS0_SPARE_00 0x0000 /* - - */
-#define LAS0_SPARE_04 0x0004 /* - - */
-#define LAS0_USER_IO 0x0008 /* Read User Inputs Write User Outputs */
-#define LAS0_SPARE_0C 0x000C /* - - */
-#define LAS0_ADC 0x0010 /* Read FIFO Status Software A/D Start */
-#define LAS0_DAC1 0x0014 /* - Software D/A1 Update */
-#define LAS0_DAC2 0x0018 /* - Software D/A2 Update */
-#define LAS0_SPARE_1C 0x001C /* - - */
-#define LAS0_SPARE_20 0x0020 /* - - */
-#define LAS0_DAC 0x0024 /* - Software Simultaneous D/A1 and D/A2 Update */
-#define LAS0_PACER 0x0028 /* Software Pacer Start Software Pacer Stop */
-#define LAS0_TIMER 0x002C /* Read Timer Counters Status HDIN Software Trigger */
-#define LAS0_IT 0x0030 /* Read Interrupt Status Write Interrupt Enable Mask Register */
-#define LAS0_CLEAR 0x0034 /* Clear ITs set by Clear Mask Set Interrupt Clear Mask */
-#define LAS0_OVERRUN 0x0038 /* Read pending interrupts Clear Overrun Register */
-#define LAS0_SPARE_3C 0x003C /* - - */
+ * Local Address Space 0 Offsets
+ */
+#define LAS0_USER_IO 0x0008 /* User I/O */
+#define LAS0_ADC 0x0010 /* FIFO Status/Software A/D Start */
+#define LAS0_DAC1 0x0014 /* Software D/A1 Update (w) */
+#define LAS0_DAC2 0x0018 /* Software D/A2 Update (w) */
+#define LAS0_DAC 0x0024 /* Software Simultaneous Update (w) */
+#define LAS0_PACER 0x0028 /* Software Pacer Start/Stop */
+#define LAS0_TIMER 0x002c /* Timer Status/HDIN Software Trig. */
+#define LAS0_IT 0x0030 /* Interrupt Status/Enable */
+#define LAS0_CLEAR 0x0034 /* Clear/Set Interrupt Clear Mask */
+#define LAS0_OVERRUN 0x0038 /* Pending interrupts/Clear Overrun */
+#define LAS0_PCLK 0x0040 /* Pacer Clock (24bit) */
+#define LAS0_BCLK 0x0044 /* Burst Clock (10bit) */
+#define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter (10bit) */
+#define LAS0_DAC1_UCNT 0x004c /* D/A1 Update counter (10 bit) */
+#define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter (10 bit) */
+#define LAS0_DCNT 0x0054 /* Delay counter (16 bit) */
+#define LAS0_ACNT 0x0058 /* About counter (16 bit) */
+#define LAS0_DAC_CLK 0x005c /* DAC clock (16bit) */
+#define LAS0_UTC0 0x0060 /* 8254 TC Counter 0 */
+#define LAS0_UTC1 0x0064 /* 8254 TC Counter 1 */
+#define LAS0_UTC2 0x0068 /* 8254 TC Counter 2 */
+#define LAS0_UTC_CTRL 0x006c /* 8254 TC Control */
+#define LAS0_DIO0 0x0070 /* Digital I/O Port 0 */
+#define LAS0_DIO1 0x0074 /* Digital I/O Port 1 */
+#define LAS0_DIO0_CTRL 0x0078 /* Digital I/O Control */
+#define LAS0_DIO_STATUS 0x007c /* Digital I/O Status */
+#define LAS0_BOARD_RESET 0x0100 /* Board reset */
+#define LAS0_DMA0_SRC 0x0104 /* DMA 0 Sources select */
+#define LAS0_DMA1_SRC 0x0108 /* DMA 1 Sources select */
+#define LAS0_ADC_CONVERSION 0x010c /* A/D Conversion Signal select */
+#define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */
+#define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */
+#define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */
+#define LAS0_ACNT_STOP_ENABLE 0x011c /* About Counter Stop Enable */
+#define LAS0_PACER_REPEAT 0x0120 /* Pacer Start Trigger Mode select */
+#define LAS0_DIN_START 0x0124 /* HiSpd DI Sampling Signal select */
+#define LAS0_DIN_FIFO_CLEAR 0x0128 /* Digital Input FIFO Clear */
+#define LAS0_ADC_FIFO_CLEAR 0x012c /* A/D FIFO Clear */
+#define LAS0_CGT_WRITE 0x0130 /* Channel Gain Table Write */
+#define LAS0_CGL_WRITE 0x0134 /* Channel Gain Latch Write */
+#define LAS0_CG_DATA 0x0138 /* Digital Table Write */
+#define LAS0_CGT_ENABLE 0x013c /* Channel Gain Table Enable */
+#define LAS0_CG_ENABLE 0x0140 /* Digital Table Enable */
+#define LAS0_CGT_PAUSE 0x0144 /* Table Pause Enable */
+#define LAS0_CGT_RESET 0x0148 /* Reset Channel Gain Table */
+#define LAS0_CGT_CLEAR 0x014c /* Clear Channel Gain Table */
+#define LAS0_DAC1_CTRL 0x0150 /* D/A1 output type/range */
+#define LAS0_DAC1_SRC 0x0154 /* D/A1 update source */
+#define LAS0_DAC1_CYCLE 0x0158 /* D/A1 cycle mode */
+#define LAS0_DAC1_RESET 0x015c /* D/A1 FIFO reset */
+#define LAS0_DAC1_FIFO_CLEAR 0x0160 /* D/A1 FIFO clear */
+#define LAS0_DAC2_CTRL 0x0164 /* D/A2 output type/range */
+#define LAS0_DAC2_SRC 0x0168 /* D/A2 update source */
+#define LAS0_DAC2_CYCLE 0x016c /* D/A2 cycle mode */
+#define LAS0_DAC2_RESET 0x0170 /* D/A2 FIFO reset */
+#define LAS0_DAC2_FIFO_CLEAR 0x0174 /* D/A2 FIFO clear */
+#define LAS0_ADC_SCNT_SRC 0x0178 /* A/D Sample Counter Source select */
+#define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */
+#define LAS0_SBUS0_SRC 0x0184 /* SyncBus 0 Source select */
+#define LAS0_SBUS0_ENABLE 0x0188 /* SyncBus 0 enable */
+#define LAS0_SBUS1_SRC 0x018c /* SyncBus 1 Source select */
+#define LAS0_SBUS1_ENABLE 0x0190 /* SyncBus 1 enable */
+#define LAS0_SBUS2_SRC 0x0198 /* SyncBus 2 Source select */
+#define LAS0_SBUS2_ENABLE 0x019c /* SyncBus 2 enable */
+#define LAS0_ETRG_POLARITY 0x01a4 /* Ext. Trigger polarity select */
+#define LAS0_EINT_POLARITY 0x01a8 /* Ext. Interrupt polarity select */
+#define LAS0_UTC0_CLOCK 0x01ac /* UTC0 Clock select */
+#define LAS0_UTC0_GATE 0x01b0 /* UTC0 Gate select */
+#define LAS0_UTC1_CLOCK 0x01b4 /* UTC1 Clock select */
+#define LAS0_UTC1_GATE 0x01b8 /* UTC1 Gate select */
+#define LAS0_UTC2_CLOCK 0x01bc /* UTC2 Clock select */
+#define LAS0_UTC2_GATE 0x01c0 /* UTC2 Gate select */
+#define LAS0_UOUT0_SELECT 0x01c4 /* User Output 0 source select */
+#define LAS0_UOUT1_SELECT 0x01c8 /* User Output 1 source select */
+#define LAS0_DMA0_RESET 0x01cc /* DMA0 Request state machine reset */
+#define LAS0_DMA1_RESET 0x01d0 /* DMA1 Request state machine reset */
/*
- LAS0 Runtime Area Timer/Counter,Dig.IO
- Name Local Address Function
-*/
-#define LAS0_PCLK 0x0040 /* Pacer Clock value (24bit) Pacer Clock load (24bit) */
-#define LAS0_BCLK 0x0044 /* Burst Clock value (10bit) Burst Clock load (10bit) */
-#define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter value (10bit) A/D Sample counter load (10bit) */
-#define LAS0_DAC1_UCNT 0x004C /* D/A1 Update counter value (10 bit) D/A1 Update counter load (10bit) */
-#define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter value (10 bit) D/A2 Update counter load (10bit) */
-#define LAS0_DCNT 0x0054 /* Delay counter value (16 bit) Delay counter load (16bit) */
-#define LAS0_ACNT 0x0058 /* About counter value (16 bit) About counter load (16bit) */
-#define LAS0_DAC_CLK 0x005C /* DAC clock value (16bit) DAC clock load (16bit) */
-#define LAS0_UTC0 0x0060 /* 8254 TC Counter 0 User TC 0 value Load count in TC Counter 0 */
-#define LAS0_UTC1 0x0064 /* 8254 TC Counter 1 User TC 1 value Load count in TC Counter 1 */
-#define LAS0_UTC2 0x0068 /* 8254 TC Counter 2 User TC 2 value Load count in TC Counter 2 */
-#define LAS0_UTC_CTRL 0x006C /* 8254 TC Control Word Program counter mode for TC */
-#define LAS0_DIO0 0x0070 /* Digital I/O Port 0 Read Port Digital I/O Port 0 Write Port */
-#define LAS0_DIO1 0x0074 /* Digital I/O Port 1 Read Port Digital I/O Port 1 Write Port */
-#define LAS0_DIO0_CTRL 0x0078 /* Clear digital IRQ status flag/read Clear digital chip/program Port 0 */
-#define LAS0_DIO_STATUS 0x007C /* Read Digital I/O Status word Program digital control register & */
-
-/*
- LAS0 Setup Area
- Name Local Address Function
-*/
-#define LAS0_BOARD_RESET 0x0100 /* Board reset */
-#define LAS0_DMA0_SRC 0x0104 /* DMA 0 Sources select */
-#define LAS0_DMA1_SRC 0x0108 /* DMA 1 Sources select */
-#define LAS0_ADC_CONVERSION 0x010C /* A/D Conversion Signal select */
-#define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */
-#define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */
-#define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */
-#define LAS0_ACNT_STOP_ENABLE 0x011C /* About Counter Stop Enable */
-#define LAS0_PACER_REPEAT 0x0120 /* Pacer Start Trigger Mode select */
-#define LAS0_DIN_START 0x0124 /* High Speed Digital Input Sampling Signal select */
-#define LAS0_DIN_FIFO_CLEAR 0x0128 /* Digital Input FIFO Clear */
-#define LAS0_ADC_FIFO_CLEAR 0x012C /* A/D FIFO Clear */
-#define LAS0_CGT_WRITE 0x0130 /* Channel Gain Table Write */
-#define LAS0_CGL_WRITE 0x0134 /* Channel Gain Latch Write */
-#define LAS0_CG_DATA 0x0138 /* Digital Table Write */
-#define LAS0_CGT_ENABLE 0x013C /* Channel Gain Table Enable */
-#define LAS0_CG_ENABLE 0x0140 /* Digital Table Enable */
-#define LAS0_CGT_PAUSE 0x0144 /* Table Pause Enable */
-#define LAS0_CGT_RESET 0x0148 /* Reset Channel Gain Table */
-#define LAS0_CGT_CLEAR 0x014C /* Clear Channel Gain Table */
-#define LAS0_DAC1_CTRL 0x0150 /* D/A1 output type/range */
-#define LAS0_DAC1_SRC 0x0154 /* D/A1 update source */
-#define LAS0_DAC1_CYCLE 0x0158 /* D/A1 cycle mode */
-#define LAS0_DAC1_RESET 0x015C /* D/A1 FIFO reset */
-#define LAS0_DAC1_FIFO_CLEAR 0x0160 /* D/A1 FIFO clear */
-#define LAS0_DAC2_CTRL 0x0164 /* D/A2 output type/range */
-#define LAS0_DAC2_SRC 0x0168 /* D/A2 update source */
-#define LAS0_DAC2_CYCLE 0x016C /* D/A2 cycle mode */
-#define LAS0_DAC2_RESET 0x0170 /* D/A2 FIFO reset */
-#define LAS0_DAC2_FIFO_CLEAR 0x0174 /* D/A2 FIFO clear */
-#define LAS0_ADC_SCNT_SRC 0x0178 /* A/D Sample Counter Source select */
-#define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */
-#define LAS0_SBUS0_SRC 0x0184 /* SyncBus 0 Source select */
-#define LAS0_SBUS0_ENABLE 0x0188 /* SyncBus 0 enable */
-#define LAS0_SBUS1_SRC 0x018C /* SyncBus 1 Source select */
-#define LAS0_SBUS1_ENABLE 0x0190 /* SyncBus 1 enable */
-#define LAS0_SBUS2_SRC 0x0198 /* SyncBus 2 Source select */
-#define LAS0_SBUS2_ENABLE 0x019C /* SyncBus 2 enable */
-#define LAS0_ETRG_POLARITY 0x01A4 /* External Trigger polarity select */
-#define LAS0_EINT_POLARITY 0x01A8 /* External Interrupt polarity select */
-#define LAS0_UTC0_CLOCK 0x01AC /* UTC0 Clock select */
-#define LAS0_UTC0_GATE 0x01B0 /* UTC0 Gate select */
-#define LAS0_UTC1_CLOCK 0x01B4 /* UTC1 Clock select */
-#define LAS0_UTC1_GATE 0x01B8 /* UTC1 Gate select */
-#define LAS0_UTC2_CLOCK 0x01BC /* UTC2 Clock select */
-#define LAS0_UTC2_GATE 0x01C0 /* UTC2 Gate select */
-#define LAS0_UOUT0_SELECT 0x01C4 /* User Output 0 source select */
-#define LAS0_UOUT1_SELECT 0x01C8 /* User Output 1 source select */
-#define LAS0_DMA0_RESET 0x01CC /* DMA0 Request state machine reset */
-#define LAS0_DMA1_RESET 0x01D0 /* DMA1 Request state machine reset */
+ * Local Address Space 1 Offsets
+ */
+#define LAS1_ADC_FIFO 0x0000 /* A/D FIFO (16bit) */
+#define LAS1_HDIO_FIFO 0x0004 /* HiSpd DI FIFO (16bit) */
+#define LAS1_DAC1_FIFO 0x0008 /* D/A1 FIFO (16bit) */
+#define LAS1_DAC2_FIFO 0x000c /* D/A2 FIFO (16bit) */
/*
- LAS1
- Name Local Address Function
-*/
-#define LAS1_ADC_FIFO 0x0000 /* Read A/D FIFO (16bit) - */
-#define LAS1_HDIO_FIFO 0x0004 /* Read High Speed Digital Input FIFO (16bit) - */
-#define LAS1_DAC1_FIFO 0x0008 /* - Write D/A1 FIFO (16bit) */
-#define LAS1_DAC2_FIFO 0x000C /* - Write D/A2 FIFO (16bit) */
-
-/*
- LCFG: PLX 9080 local config & runtime registers
- Name Local Address Function
-*/
-#define LCFG_ITCSR 0x0068 /* INTCSR, Interrupt Control/Status Register */
-#define LCFG_DMAMODE0 0x0080 /* DMA Channel 0 Mode Register */
-#define LCFG_DMAPADR0 0x0084 /* DMA Channel 0 PCI Address Register */
-#define LCFG_DMALADR0 0x0088 /* DMA Channel 0 Local Address Reg */
-#define LCFG_DMASIZ0 0x008C /* DMA Channel 0 Transfer Size (Bytes) Register */
-#define LCFG_DMADPR0 0x0090 /* DMA Channel 0 Descriptor Pointer Register */
-#define LCFG_DMAMODE1 0x0094 /* DMA Channel 1 Mode Register */
-#define LCFG_DMAPADR1 0x0098 /* DMA Channel 1 PCI Address Register */
-#define LCFG_DMALADR1 0x009C /* DMA Channel 1 Local Address Register */
-#define LCFG_DMASIZ1 0x00A0 /* DMA Channel 1 Transfer Size (Bytes) Register */
-#define LCFG_DMADPR1 0x00A4 /* DMA Channel 1 Descriptor Pointer Register */
-#define LCFG_DMACSR0 0x00A8 /* DMA Channel 0 Command/Status Register */
-#define LCFG_DMACSR1 0x00A9 /* DMA Channel 0 Command/Status Register */
-#define LCFG_DMAARB 0x00AC /* DMA Arbitration Register */
-#define LCFG_DMATHR 0x00B0 /* DMA Threshold Register */
-
-/*======================================================================
- Resister bit definitions
-======================================================================*/
+ * PLX 9080 local config & runtime registers
+ */
+#define LCFG_ITCSR 0x0068 /* Interrupt Control/Status */
+#define LCFG_DMAMODE0 0x0080 /* DMA0 Mode */
+#define LCFG_DMAPADR0 0x0084 /* DMA0 PCI Address */
+#define LCFG_DMALADR0 0x0088 /* DMA0 Local Address */
+#define LCFG_DMASIZ0 0x008c /* DMA0 Transfer Size (Bytes) */
+#define LCFG_DMADPR0 0x0090 /* DMA0 Descriptor Pointer */
+#define LCFG_DMAMODE1 0x0094 /* DMA1 Mode */
+#define LCFG_DMAPADR1 0x0098 /* DMA1 PCI Address */
+#define LCFG_DMALADR1 0x009c /* DMA1 Local Address */
+#define LCFG_DMASIZ1 0x00a0 /* DMA1 Transfer Size (Bytes) */
+#define LCFG_DMADPR1 0x00a4 /* DMA1 Descriptor Pointer */
+#define LCFG_DMACSR0 0x00a8 /* DMA0 Command/Status */
+#define LCFG_DMACSR1 0x00a9 /* DMA0 Command/Status */
+#define LCFG_DMAARB 0x00ac /* DMA Arbitration */
+#define LCFG_DMATHR 0x00b0 /* DMA Threshold */
/* FIFO Status Word Bits (RtdFifoStatus) */
-#define FS_DAC1_NOT_EMPTY 0x0001 /* D0 - DAC1 FIFO not empty */
-#define FS_DAC1_HEMPTY 0x0002 /* D1 - DAC1 FIFO half empty */
-#define FS_DAC1_NOT_FULL 0x0004 /* D2 - DAC1 FIFO not full */
-#define FS_DAC2_NOT_EMPTY 0x0010 /* D4 - DAC2 FIFO not empty */
-#define FS_DAC2_HEMPTY 0x0020 /* D5 - DAC2 FIFO half empty */
-#define FS_DAC2_NOT_FULL 0x0040 /* D6 - DAC2 FIFO not full */
-#define FS_ADC_NOT_EMPTY 0x0100 /* D8 - ADC FIFO not empty */
-#define FS_ADC_HEMPTY 0x0200 /* D9 - ADC FIFO half empty */
-#define FS_ADC_NOT_FULL 0x0400 /* D10 - ADC FIFO not full */
-#define FS_DIN_NOT_EMPTY 0x1000 /* D12 - DIN FIFO not empty */
-#define FS_DIN_HEMPTY 0x2000 /* D13 - DIN FIFO half empty */
-#define FS_DIN_NOT_FULL 0x4000 /* D14 - DIN FIFO not full */
+#define FS_DAC1_NOT_EMPTY (1 << 0) /* DAC1 FIFO not empty */
+#define FS_DAC1_HEMPTY (1 << 1) /* DAC1 FIFO half empty */
+#define FS_DAC1_NOT_FULL (1 << 2) /* DAC1 FIFO not full */
+#define FS_DAC2_NOT_EMPTY (1 << 4) /* DAC2 FIFO not empty */
+#define FS_DAC2_HEMPTY (1 << 5) /* DAC2 FIFO half empty */
+#define FS_DAC2_NOT_FULL (1 << 6) /* DAC2 FIFO not full */
+#define FS_ADC_NOT_EMPTY (1 << 8) /* ADC FIFO not empty */
+#define FS_ADC_HEMPTY (1 << 9) /* ADC FIFO half empty */
+#define FS_ADC_NOT_FULL (1 << 10) /* ADC FIFO not full */
+#define FS_DIN_NOT_EMPTY (1 << 12) /* DIN FIFO not empty */
+#define FS_DIN_HEMPTY (1 << 13) /* DIN FIFO half empty */
+#define FS_DIN_NOT_FULL (1 << 14) /* DIN FIFO not full */
/* Timer Status Word Bits (GetTimerStatus) */
-#define TS_PCLK_GATE 0x0001
-/* D0 - Pacer Clock Gate [0 - gated, 1 - enabled] */
-#define TS_BCLK_GATE 0x0002
-/* D1 - Burst Clock Gate [0 - disabled, 1 - running] */
-#define TS_DCNT_GATE 0x0004
-/* D2 - Pacer Clock Delayed Start Trigger [0 - delay over, 1 - delay in */
-/* progress] */
-#define TS_ACNT_GATE 0x0008
-/* D3 - Pacer Clock About Trigger [0 - completed, 1 - in progress] */
-#define TS_PCLK_RUN 0x0010
-/* D4 - Pacer Clock Shutdown Flag [0 - Pacer Clock cannot be start */
-/* triggered only by Software Pacer Start Command, 1 - Pacer Clock can */
-/* be start triggered] */
+#define TS_PCLK_GATE (1 << 0) /* Pacer Clock Gate enabled */
+#define TS_BCLK_GATE (1 << 1) /* Burst Clock Gate running */
+#define TS_DCNT_GATE (1 << 2) /* Pacer Clock Delayed Start Trig. */
+#define TS_ACNT_GATE (1 << 3) /* Pacer Clock About Trig. */
+#define TS_PCLK_RUN (1 << 4) /* Pacer Clock Shutdown Flag */
/* External Trigger polarity select */
/* External Interrupt polarity select */
diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c
index 137885b1681..7e577e44490 100644
--- a/drivers/staging/comedi/drivers/rti800.c
+++ b/drivers/staging/comedi/drivers/rti800.c
@@ -161,8 +161,6 @@ struct rti800_private {
int muxgain_bits;
};
-#define devpriv ((struct rti800_private *)dev->private)
-
#define RTI800_TIMEOUT 100
static irqreturn_t rti800_interrupt(int irq, void *dev)
@@ -177,6 +175,7 @@ static int rti800_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct rti800_private *devpriv = dev->private;
int i, t;
int status;
int chan = CR_CHAN(insn->chanspec);
@@ -229,6 +228,7 @@ static int rti800_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct rti800_private *devpriv = dev->private;
int i;
int chan = CR_CHAN(insn->chanspec);
@@ -242,6 +242,7 @@ static int rti800_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct rti800_private *devpriv = dev->private;
int chan = CR_CHAN(insn->chanspec);
int d;
int i;
@@ -303,6 +304,7 @@ static int rti800_do_insn_bits(struct comedi_device *dev,
static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct rti800_board *board = comedi_board(dev);
+ struct rti800_private *devpriv;
unsigned int irq;
unsigned long iobase;
int ret;
@@ -347,9 +349,10 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (ret)
return ret;
- ret = alloc_private(dev, sizeof(struct rti800_private));
- if (ret < 0)
- return ret;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
devpriv->adc_mux = it->options[2];
devpriv->adc_range = it->options[3];
diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c
index 3f9d0278be5..2185ca1bcf0 100644
--- a/drivers/staging/comedi/drivers/rti802.c
+++ b/drivers/staging/comedi/drivers/rti802.c
@@ -55,12 +55,11 @@ struct rti802_private {
unsigned int ao_readback[8];
};
-#define devpriv ((struct rti802_private *)dev->private)
-
static int rti802_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct rti802_private *devpriv = dev->private;
int i;
for (i = 0; i < insn->n; i++)
@@ -73,6 +72,7 @@ static int rti802_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct rti802_private *devpriv = dev->private;
int i, d;
int chan = CR_CHAN(insn->chanspec);
@@ -89,6 +89,7 @@ static int rti802_ao_insn_write(struct comedi_device *dev,
static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ struct rti802_private *devpriv;
struct comedi_subdevice *s;
int i;
unsigned long iobase;
@@ -104,8 +105,10 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it)
dev->board_name = "rti802";
- if (alloc_private(dev, sizeof(struct rti802_private)))
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_alloc_subdevices(dev, 1);
if (ret)
diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c
index a1e256293bd..39232b35945 100644
--- a/drivers/staging/comedi/drivers/s526.c
+++ b/drivers/staging/comedi/drivers/s526.c
@@ -564,10 +564,10 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
dev->iobase = iobase;
- ret = alloc_private(dev, sizeof(*devpriv));
- if (ret)
- return ret;
- devpriv = dev->private;
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_alloc_subdevices(dev, 4);
if (ret)
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index 551d68b7837..6dc1d281286 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -161,7 +161,6 @@ static struct dio_private *dio_private_word[]={
};
*/
-#define devpriv ((struct s626_private *)dev->private)
#define diopriv ((struct dio_private *)s->private)
/* COUNTER OBJECT ------------------------------------------------ */
@@ -232,6 +231,8 @@ static const struct comedi_lrange s626_range_table = { 2, {
/* critical section. */
static void DEBItransfer(struct comedi_device *dev)
{
+ struct s626_private *devpriv = dev->private;
+
/* Initiate upload of shadow RAM to DEBI control register. */
MC_ENABLE(P_MC2, MC2_UPLD_DEBI);
@@ -249,6 +250,7 @@ static void DEBItransfer(struct comedi_device *dev)
static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr)
{
+ struct s626_private *devpriv = dev->private;
uint16_t retval;
/* Set up DEBI control register value in shadow RAM. */
@@ -267,6 +269,7 @@ static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr)
/* Write a value to a gate array register. */
static void DEBIwrite(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. */
WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr);
@@ -283,6 +286,7 @@ static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata)
static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
uint16_t wdata)
{
+ struct s626_private *devpriv = dev->private;
/* Copy target gate array register into P_DEBIAD register. */
WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr);
@@ -302,6 +306,8 @@ static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val)
{
+ struct s626_private *devpriv = dev->private;
+
/* Write I2C command to I2C Transfer Control shadow register. */
WR7146(P_I2CCTRL, val);
@@ -324,6 +330,7 @@ static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val)
/* Read uint8_t from EEPROM. */
static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr)
{
+ struct s626_private *devpriv = dev->private;
uint8_t rtnval;
/* Send EEPROM target address. */
@@ -375,6 +382,7 @@ static uint8_t trimadrs[] = { 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x
*/
static void SendDAC(struct comedi_device *dev, uint32_t val)
{
+ struct s626_private *devpriv = dev->private;
/* START THE SERIAL CLOCK RUNNING ------------- */
@@ -496,6 +504,7 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
/* Private helper function: Write setpoint to an application DAC channel. */
static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata)
{
+ struct s626_private *devpriv = dev->private;
register uint16_t signmask;
register uint32_t WSImage;
@@ -553,6 +562,7 @@ static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata)
static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
uint8_t DacData)
{
+ struct s626_private *devpriv = dev->private;
uint32_t chan;
/* Save the new setpoint in case the application needs to read it back later. */
@@ -735,6 +745,7 @@ static int s626_dio_clear_irq(struct comedi_device *dev)
static irqreturn_t s626_irq_handler(int irq, void *d)
{
struct comedi_device *dev = d;
+ struct s626_private *devpriv = dev->private;
struct comedi_subdevice *s;
struct comedi_cmd *cmd;
struct enc_private *k;
@@ -968,6 +979,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d)
*/
static void ResetADC(struct comedi_device *dev, uint8_t *ppl)
{
+ struct s626_private *devpriv = dev->private;
register uint32_t *pRPS;
uint32_t JmpAdrs;
uint16_t i;
@@ -1163,6 +1175,7 @@ static int s626_ai_insn_config(struct comedi_device *dev,
/* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) */
/* { */
+/* struct s626_private *devpriv = dev->private; */
/* register uint8_t i; */
/* register int32_t *readaddr; */
@@ -1191,6 +1204,7 @@ static int s626_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct s626_private *devpriv = dev->private;
uint16_t chan = CR_CHAN(insn->chanspec);
uint16_t range = CR_RANGE(insn->chanspec);
uint16_t AdcSpec = 0;
@@ -1302,6 +1316,8 @@ static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd)
static int s626_ai_inttrig(struct comedi_device *dev,
struct comedi_subdevice *s, unsigned int trignum)
{
+ struct s626_private *devpriv = dev->private;
+
if (trignum != 0)
return -EINVAL;
@@ -1378,7 +1394,7 @@ static void s626_timer_load(struct comedi_device *dev, struct enc_private *k,
/* 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;
@@ -1533,80 +1549,46 @@ static int s626_ai_cmdtest(struct comedi_device *dev,
/* step 3: make sure arguments are trivially compatible */
- if (cmd->start_src != TRIG_EXT && cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ if (cmd->start_src != TRIG_EXT)
+ 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->start_src == TRIG_EXT && cmd->start_arg > 39) {
- cmd->start_arg = 39;
- err++;
- }
+ if (cmd->scan_begin_src == TRIG_EXT)
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 39);
- if (cmd->scan_begin_src == TRIG_EXT && cmd->scan_begin_arg > 39) {
- cmd->scan_begin_arg = 39;
- err++;
- }
+ if (cmd->convert_src == TRIG_EXT)
+ err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 39);
- if (cmd->convert_src == TRIG_EXT && cmd->convert_arg > 39) {
- cmd->convert_arg = 39;
- err++;
- }
#define MAX_SPEED 200000 /* in nanoseconds */
#define MIN_SPEED 2000000000 /* in nanoseconds */
if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->scan_begin_arg < MAX_SPEED) {
- cmd->scan_begin_arg = MAX_SPEED;
- err++;
- }
- if (cmd->scan_begin_arg > MIN_SPEED) {
- cmd->scan_begin_arg = MIN_SPEED;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ MAX_SPEED);
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
+ MIN_SPEED);
} else {
/* external trigger */
/* should be level/edge, hi/lo specification here */
/* should specify multiple external triggers */
-/* if(cmd->scan_begin_arg>9){ */
-/* cmd->scan_begin_arg=9; */
-/* err++; */
-/* } */
+/* err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); */
}
if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < MAX_SPEED) {
- cmd->convert_arg = MAX_SPEED;
- err++;
- }
- if (cmd->convert_arg > MIN_SPEED) {
- cmd->convert_arg = MIN_SPEED;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg, MAX_SPEED);
+ err |= cfc_check_trigger_arg_max(&cmd->convert_arg, MIN_SPEED);
} else {
/* external trigger */
/* see above */
-/* if(cmd->convert_arg>9){ */
-/* cmd->convert_arg=9; */
-/* err++; */
-/* } */
+/* err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); */
}
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) {
- if (cmd->stop_arg > 0x00ffffff) {
- cmd->stop_arg = 0x00ffffff;
- err++;
- }
- } else {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -1643,6 +1625,8 @@ static int s626_ai_cmdtest(struct comedi_device *dev,
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. */
MC_DISABLE(P_MC1, MC1_ERPS1);
@@ -1657,7 +1641,7 @@ static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
-
+ struct s626_private *devpriv = dev->private;
int i;
uint16_t chan = CR_CHAN(insn->chanspec);
int16_t dacdata;
@@ -1676,6 +1660,7 @@ static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct s626_private *devpriv = dev->private;
int i;
for (i = 0; i < insn->n; i++)
@@ -1974,6 +1959,7 @@ static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k)
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. */
@@ -2032,6 +2018,7 @@ static void SetMode_A(struct comedi_device *dev, struct enc_private *k,
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. */
@@ -2165,6 +2152,8 @@ static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k)
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, (uint16_t) (~CRBMSK_INTCTRL),
CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
@@ -2182,6 +2171,7 @@ static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
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. */
@@ -2412,6 +2402,7 @@ static void CountersInit(struct comedi_device *dev)
static int s626_allocate_dma_buffers(struct comedi_device *dev)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct s626_private *devpriv = dev->private;
void *addr;
dma_addr_t appdma;
@@ -2432,6 +2423,7 @@ 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;
uint16_t chan;
int i;
@@ -2665,16 +2657,20 @@ static void s626_initialize(struct comedi_device *dev)
/* writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER); */
}
-static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev)
+static int s626_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct s626_private *devpriv;
struct comedi_subdevice *s;
int ret;
- comedi_set_hw_dev(dev, &pcidev->dev);
dev->board_name = dev->driver->driver_name;
- if (alloc_private(dev, sizeof(struct s626_private)) < 0)
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
ret = comedi_pci_enable(pcidev, dev->board_name);
if (ret)
@@ -2794,6 +2790,7 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev)
static void s626_detach(struct comedi_device *dev)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct s626_private *devpriv = dev->private;
if (devpriv) {
/* stop ai_command */
@@ -2829,17 +2826,17 @@ static void s626_detach(struct comedi_device *dev)
static struct comedi_driver s626_driver = {
.driver_name = "s626",
.module = THIS_MODULE,
- .attach_pci = s626_attach_pci,
+ .auto_attach = s626_auto_attach,
.detach = s626_detach,
};
-static int __devinit s626_pci_probe(struct pci_dev *dev,
+static int s626_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, &s626_driver);
}
-static void __devexit s626_pci_remove(struct pci_dev *dev)
+static void s626_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
@@ -2860,7 +2857,7 @@ static struct pci_driver s626_pci_driver = {
.name = "s626",
.id_table = s626_pci_table,
.probe = s626_pci_probe,
- .remove = __devexit_p(s626_pci_remove),
+ .remove = s626_pci_remove,
};
module_comedi_pci_driver(s626_driver, s626_pci_driver);
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
index 5bf84cfbdce..e6177b48cca 100644
--- a/drivers/staging/comedi/drivers/serial2002.c
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -31,6 +31,8 @@ Status: in development
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "../comedidev.h"
#include <linux/delay.h>
@@ -43,10 +45,6 @@ Status: in development
#include <linux/serial.h>
#include <linux/poll.h>
-struct serial2002_board {
- const char *name;
-};
-
struct serial2002_range_table_t {
/* HACK... */
@@ -68,12 +66,6 @@ struct serial2002_private {
struct serial2002_range_table_t in_range[32], out_range[32];
};
-/*
- * most drivers define the following macro to make it easy to
- * access the private structure.
- */
-#define devpriv ((struct serial2002_private *)dev->private)
-
struct serial_data {
enum { is_invalid, is_digital, is_channel } kind;
int index;
@@ -282,7 +274,7 @@ static struct serial_data serial_read(struct file *f, int timeout)
length++;
if (data < 0) {
- printk(KERN_ERR "serial2002 error\n");
+ pr_err("Failed to read serial.\n");
break;
} else if (data & 0x80) {
result.value = (result.value << 7) | (data & 0x7f);
@@ -348,6 +340,7 @@ static void serial_write(struct file *f, struct serial_data data)
static int serial_2002_open(struct comedi_device *dev)
{
+ struct serial2002_private *devpriv = dev->private;
int result;
char port[20];
@@ -355,7 +348,7 @@ static int serial_2002_open(struct comedi_device *dev)
devpriv->tty = filp_open(port, O_RDWR, 0);
if (IS_ERR(devpriv->tty)) {
result = (int)PTR_ERR(devpriv->tty);
- printk(KERN_ERR "serial_2002: file open error = %d\n", result);
+ dev_err(dev->class_dev, "file open error = %d\n", result);
} else {
struct config_t {
@@ -655,6 +648,8 @@ err_alloc_configs:
static void serial_2002_close(struct comedi_device *dev)
{
+ struct serial2002_private *devpriv = dev->private;
+
if (!IS_ERR(devpriv->tty) && devpriv->tty)
filp_close(devpriv->tty, NULL);
}
@@ -663,6 +658,7 @@ static int serial2002_di_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct serial2002_private *devpriv = dev->private;
int n;
int chan;
@@ -685,6 +681,7 @@ static int serial2002_do_winsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct serial2002_private *devpriv = dev->private;
int n;
int chan;
@@ -704,6 +701,7 @@ static int serial2002_ai_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct serial2002_private *devpriv = dev->private;
int n;
int chan;
@@ -726,6 +724,7 @@ static int serial2002_ao_winsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct serial2002_private *devpriv = dev->private;
int n;
int chan;
@@ -746,6 +745,7 @@ static int serial2002_ao_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct serial2002_private *devpriv = dev->private;
int n;
int chan = CR_CHAN(insn->chanspec);
@@ -759,6 +759,7 @@ static int serial2002_ei_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct serial2002_private *devpriv = dev->private;
int n;
int chan;
@@ -780,14 +781,18 @@ static int serial2002_ei_rinsn(struct comedi_device *dev,
static int serial2002_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
- const struct serial2002_board *board = comedi_board(dev);
+ struct serial2002_private *devpriv;
struct comedi_subdevice *s;
int ret;
dev_dbg(dev->class_dev, "serial2002: attach\n");
- dev->board_name = board->name;
- if (alloc_private(dev, sizeof(struct serial2002_private)) < 0)
+ dev->board_name = dev->driver->driver_name;
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
return -ENOMEM;
+ dev->private = devpriv;
+
dev->open = serial_2002_open;
dev->close = serial_2002_close;
devpriv->port = it->options[0];
@@ -860,20 +865,11 @@ static void serial2002_detach(struct comedi_device *dev)
}
}
-static const struct serial2002_board serial2002_boards[] = {
- {
- .name = "serial2002"
- },
-};
-
static struct comedi_driver serial2002_driver = {
.driver_name = "serial2002",
.module = THIS_MODULE,
.attach = serial2002_attach,
.detach = serial2002_detach,
- .board_name = &serial2002_boards[0].name,
- .offset = sizeof(struct serial2002_board),
- .num_names = ARRAY_SIZE(serial2002_boards),
};
module_comedi_driver(serial2002_driver);
diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c
index b70cdf300bb..e2d79700a61 100644
--- a/drivers/staging/comedi/drivers/skel.c
+++ b/drivers/staging/comedi/drivers/skel.c
@@ -92,6 +92,7 @@ Configuration Options:
*/
struct skel_board {
const char *name;
+ unsigned int devid;
int ai_chans;
int ai_bits;
int have_dio;
@@ -100,36 +101,20 @@ struct skel_board {
static const struct skel_board skel_boards[] = {
{
.name = "skel-100",
+ .devid = 0x100,
.ai_chans = 16,
.ai_bits = 12,
.have_dio = 1,
},
{
.name = "skel-200",
+ .devid = 0x200,
.ai_chans = 8,
.ai_bits = 16,
.have_dio = 0,
},
};
-/* This is used by modprobe to translate PCI IDs to drivers. Should
- * only be used for PCI and ISA-PnP devices */
-/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
- * upstream. */
-#define PCI_VENDOR_ID_SKEL 0xdafe
-static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0100) },
- { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0200) },
- { 0 }
-};
-
-MODULE_DEVICE_TABLE(pci, skel_pci_table);
-
-/*
- * Useful for shorthand access to the particular board structure
- */
-#define thisboard ((const struct skel_board *)dev->board_ptr)
-
/* this structure is for data unique to this hardware driver. If
several hardware drivers keep similar information in this structure,
feel free to suggest moving the variable to the struct comedi_device struct.
@@ -138,165 +123,25 @@ struct skel_private {
int data;
- /* would be useful for a PCI device */
- struct pci_dev *pci_dev;
-
/* Used for AO readback */
unsigned int ao_readback[2];
};
-/*
- * most drivers define the following macro to make it easy to
- * access the private structure.
- */
-#define devpriv ((struct skel_private *)dev->private)
-
-/*
- * The struct comedi_driver structure tells the Comedi core module
- * which functions to call to configure/deconfigure (attach/detach)
- * the board, and also about the kernel module that contains
- * the device code.
- */
-static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it);
-static void skel_detach(struct comedi_device *dev);
-static struct comedi_driver driver_skel = {
- .driver_name = "dummy",
- .module = THIS_MODULE,
- .attach = skel_attach,
- .detach = skel_detach,
-/* It is not necessary to implement the following members if you are
- * writing a driver for a ISA PnP or PCI card */
- /* Most drivers will support multiple types of boards by
- * having an array of board structures. These were defined
- * in skel_boards[] above. Note that the element 'name'
- * was first in the structure -- Comedi uses this fact to
- * extract the name of the board without knowing any details
- * about the structure except for its length.
- * When a device is attached (by comedi_config), the name
- * of the device is given to Comedi, and Comedi tries to
- * match it by going through the list of board names. If
- * there is a match, the address of the pointer is put
- * into dev->board_ptr and driver->attach() is called.
- *
- * Note that these are not necessary if you can determine
- * the type of board in software. ISA PnP, PCI, and PCMCIA
- * devices are such boards.
- */
- .board_name = &skel_boards[0].name,
- .offset = sizeof(struct skel_board),
- .num_names = ARRAY_SIZE(skel_boards),
-};
-
-static int skel_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int skel_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int skel_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int skel_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int skel_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int skel_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd);
-static int skel_ns_to_timer(unsigned int *ns, int round);
-
-/*
- * Attach is called by the Comedi core to configure the driver
- * for a particular board. If you specified a board_name array
- * in the driver structure, dev->board_ptr contains that
- * address.
- */
-static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+/* 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. */
+static int skel_ns_to_timer(unsigned int *ns, int round)
{
- struct comedi_subdevice *s;
- int ret;
-
- pr_info("comedi%d: skel: ", dev->minor);
-
-/*
- * If you can probe the device to determine what device in a series
- * it is, this is the place to do it. Otherwise, dev->board_ptr
- * should already be initialized.
- */
- /* dev->board_ptr = skel_probe(dev, it); */
-
-/*
- * Initialize dev->board_name. Note that we can use the "thisboard"
- * macro now, since we just initialized it in the last line.
- */
- dev->board_name = thisboard->name;
-
-/*
- * Allocate the private structure area. alloc_private() is a
- * convenient macro defined in comedidev.h.
- */
- if (alloc_private(dev, sizeof(struct skel_private)) < 0)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* dev->read_subdev=s; */
- /* analog input subdevice */
- s->type = COMEDI_SUBD_AI;
- /* we support single-ended (ground) and differential */
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
- s->n_chan = thisboard->ai_chans;
- s->maxdata = (1 << thisboard->ai_bits) - 1;
- s->range_table = &range_bipolar10;
- s->len_chanlist = 16; /* This is the maximum chanlist length that
- the board can handle */
- s->insn_read = skel_ai_rinsn;
-/*
-* s->subdev_flags |= SDF_CMD_READ;
-* s->do_cmd = skel_ai_cmd;
-*/
- s->do_cmdtest = skel_ai_cmdtest;
-
- s = &dev->subdevices[1];
- /* analog output subdevice */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 1;
- s->maxdata = 0xffff;
- s->range_table = &range_bipolar5;
- s->insn_write = skel_ao_winsn;
- s->insn_read = skel_ao_rinsn;
-
- s = &dev->subdevices[2];
- /* digital i/o subdevice */
- if (thisboard->have_dio) {
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = skel_dio_insn_bits;
- s->insn_config = skel_dio_insn_config;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- pr_info("attached\n");
-
- return 0;
-}
+ /* trivial timer */
+ /* if your timing is done through two cascaded timers, the
+ * i8253_cascade_ns_to_timer() function in 8253.h can be
+ * very helpful. There are also i8254_load() and i8254_mm_load()
+ * which can be used to load values into the ubiquitous 8254 counters
+ */
-/*
- * _detach is called to deconfigure a device. It should deallocate
- * resources.
- * This function is also called when _attach() fails, so it should be
- * careful not to release resources that were not necessarily
- * allocated by _attach(). dev->private and dev->subdevices are
- * deallocated automatically by the core.
- */
-static void skel_detach(struct comedi_device *dev)
-{
+ return *ns;
}
/*
@@ -306,6 +151,7 @@ static void skel_detach(struct comedi_device *dev)
static int skel_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct skel_board *thisboard = comedi_board(dev);
int n, i;
unsigned int d;
unsigned int status;
@@ -331,9 +177,7 @@ static int skel_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
break;
}
if (i == TIMEOUT) {
- /* printk() should be used instead of printk()
- * whenever the code can be called from real-time. */
- pr_info("timeout\n");
+ dev_warn(dev->class_dev, "ai timeout\n");
return -ETIMEDOUT;
}
@@ -389,67 +233,40 @@ static int skel_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
#define MAX_SPEED 10000 /* in nanoseconds */
#define MIN_SPEED 1000000000 /* in nanoseconds */
if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->scan_begin_arg < MAX_SPEED) {
- cmd->scan_begin_arg = MAX_SPEED;
- err++;
- }
- if (cmd->scan_begin_arg > MIN_SPEED) {
- cmd->scan_begin_arg = MIN_SPEED;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ MAX_SPEED);
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
+ MIN_SPEED);
} else {
/* external trigger */
/* should be level/edge, hi/lo specification here */
/* should specify multiple external triggers */
- if (cmd->scan_begin_arg > 9) {
- cmd->scan_begin_arg = 9;
- err++;
- }
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
}
+
if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < MAX_SPEED) {
- cmd->convert_arg = MAX_SPEED;
- err++;
- }
- if (cmd->convert_arg > MIN_SPEED) {
- cmd->convert_arg = MIN_SPEED;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg, MAX_SPEED);
+ err |= cfc_check_trigger_arg_max(&cmd->convert_arg, MIN_SPEED);
} else {
/* external trigger */
/* see above */
- if (cmd->convert_arg > 9) {
- cmd->convert_arg = 9;
- err++;
- }
+ err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
}
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
- if (cmd->stop_src == TRIG_COUNT) {
- if (cmd->stop_arg > 0x00ffffff) {
- cmd->stop_arg = 0x00ffffff;
- err++;
- }
- } else {
- /* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff);
+ else /* TRIG_NONE */
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -484,30 +301,13 @@ static int skel_ai_cmdtest(struct comedi_device *dev,
return 0;
}
-/* 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. */
-static int skel_ns_to_timer(unsigned int *ns, int round)
-{
- /* trivial timer */
- /* if your timing is done through two cascaded timers, the
- * i8253_cascade_ns_to_timer() function in 8253.h can be
- * very helpful. There are also i8254_load() and i8254_mm_load()
- * which can be used to load values into the ubiquitous 8254 counters
- */
-
- return *ns;
-}
-
static int skel_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct skel_private *devpriv = dev->private;
int i;
int chan = CR_CHAN(insn->chanspec);
- pr_info("skel_ao_winsn\n");
/* Writing a list of values to an AO channel is probably not
* very useful, but that's how the interface is defined. */
for (i = 0; i < insn->n; i++) {
@@ -525,6 +325,7 @@ static int skel_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
static int skel_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct skel_private *devpriv = dev->private;
int i;
int chan = CR_CHAN(insn->chanspec);
@@ -593,57 +394,332 @@ static int skel_dio_insn_config(struct comedi_device *dev,
return insn->n;
}
-#ifdef CONFIG_COMEDI_PCI_DRIVERS
-static int __devinit driver_skel_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+static const struct skel_board *skel_find_pci_board(struct pci_dev *pcidev)
{
- return comedi_pci_auto_config(dev, &driver_skel);
+ unsigned int i;
+
+/*
+ * This example code assumes all the entries in skel_boards[] are PCI boards
+ * and all use the same PCI vendor ID. If skel_boards[] contains a mixture
+ * of PCI and non-PCI boards, this loop should skip over the non-PCI boards.
+ */
+ for (i = 0; i < ARRAY_SIZE(skel_boards); i++)
+ if (/* skel_boards[i].bustype == pci_bustype && */
+ pcidev->device == skel_boards[i].devid)
+ return &skel_boards[i];
+ return NULL;
}
-static void __devexit driver_skel_pci_remove(struct pci_dev *dev)
+/*
+ * Handle common part of skel_attach() and skel_auto_attach().
+ */
+static int skel_common_attach(struct comedi_device *dev)
{
- comedi_pci_auto_unconfig(dev);
+ const struct skel_board *thisboard = comedi_board(dev);
+ struct comedi_subdevice *s;
+ int ret;
+
+ ret = comedi_alloc_subdevices(dev, 3);
+ if (ret)
+ return ret;
+
+ s = &dev->subdevices[0];
+ /* dev->read_subdev=s; */
+ /* analog input subdevice */
+ s->type = COMEDI_SUBD_AI;
+ /* we support single-ended (ground) and differential */
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
+ s->n_chan = thisboard->ai_chans;
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = &range_bipolar10;
+ s->len_chanlist = 16; /* This is the maximum chanlist length that
+ the board can handle */
+ s->insn_read = skel_ai_rinsn;
+/*
+* s->subdev_flags |= SDF_CMD_READ;
+* s->do_cmd = skel_ai_cmd;
+*/
+ s->do_cmdtest = skel_ai_cmdtest;
+
+ s = &dev->subdevices[1];
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 1;
+ s->maxdata = 0xffff;
+ s->range_table = &range_bipolar5;
+ s->insn_write = skel_ao_winsn;
+ s->insn_read = skel_ao_rinsn;
+
+ s = &dev->subdevices[2];
+ /* digital i/o subdevice */
+ if (thisboard->have_dio) {
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = skel_dio_insn_bits;
+ s->insn_config = skel_dio_insn_config;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ dev_info(dev->class_dev, "skel: attached\n");
+
+ return 0;
}
-static struct pci_driver driver_skel_pci_driver = {
- .id_table = skel_pci_table,
- .probe = &driver_skel_pci_probe,
- .remove = __devexit_p(&driver_skel_pci_remove)
-};
+/*
+ * _attach is called by the Comedi core to configure the driver
+ * for a particular board in response to the COMEDI_DEVCONFIG ioctl for
+ * a matching board or driver name. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that address.
+ *
+ * Drivers that handle only PCI or USB devices do not usually support
+ * manual attachment of those devices via the COMEDI_DEVCONFIG ioctl, so
+ * those drivers do not have an _attach function; they just have an
+ * _auto_attach function instead. (See skel_auto_attach() for an example
+ * of such a function.)
+ */
+static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+{
+ const struct skel_board *thisboard;
+ struct skel_private *devpriv;
+
+/*
+ * If you can probe the device to determine what device in a series
+ * it is, this is the place to do it. Otherwise, dev->board_ptr
+ * should already be initialized.
+ */
+ /* dev->board_ptr = skel_probe(dev, it); */
+
+ thisboard = comedi_board(dev);
+
+/*
+ * Initialize dev->board_name.
+ */
+ dev->board_name = thisboard->name;
+
+ /* Allocate the private data */
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
+/*
+ * Supported boards are usually either auto-attached via the
+ * Comedi driver's _auto_attach routine, or manually attached via the
+ * Comedi driver's _attach routine. In most cases, attempts to
+ * manual attach boards that are usually auto-attached should be
+ * rejected by this function.
+ */
+/*
+ * if (thisboard->bustype == pci_bustype) {
+ * dev_err(dev->class_dev,
+ * "Manual attachment of PCI board '%s' not supported\n",
+ * thisboard->name);
+ * }
+ */
+
+/*
+ * For ISA boards, get the i/o base address from it->options[],
+ * request the i/o region and set dev->iobase * from it->options[].
+ * If using interrupts, get the IRQ number from it->options[].
+ */
+
+ /*
+ * Call a common function to handle the remaining things to do for
+ * attaching ISA or PCI boards. (Extra parameters could be added
+ * to pass additional information such as IRQ number.)
+ */
+ return skel_common_attach(dev);
+}
-static int __init driver_skel_init_module(void)
+/*
+ * _auto_attach is called via comedi_pci_auto_config() (or
+ * comedi_usb_auto_config(), etc.) to handle devices that can be attached
+ * to the Comedi core automatically without the COMEDI_DEVCONFIG ioctl.
+ *
+ * The context parameter is usually unused, but if the driver called
+ * comedi_auto_config() directly instead of the comedi_pci_auto_config()
+ * wrapper function, this will be a copy of the context passed to
+ * comedi_auto_config().
+ */
+static int skel_auto_attach(struct comedi_device *dev,
+ unsigned long context)
{
- int retval;
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ const struct skel_board *thisboard;
+ struct skel_private *devpriv;
+ int ret;
+
+ /* Hack to allow unused code to be optimized out. */
+ if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS))
+ return -EINVAL;
+
+ /* Find a matching board in skel_boards[]. */
+ thisboard = skel_find_pci_board(pcidev);
+ if (!thisboard) {
+ dev_err(dev->class_dev, "BUG! cannot determine board type!\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Point the struct comedi_device to the matching board info
+ * and set the board name.
+ */
+ dev->board_ptr = thisboard;
+ dev->board_name = thisboard->name;
+
+ /* Allocate the private data */
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
- retval = comedi_driver_register(&driver_skel);
- if (retval < 0)
- return retval;
+ /* Enable the PCI device. */
+ ret = comedi_pci_enable(pcidev, dev->board_name);
+ if (ret)
+ return ret;
+
+ /*
+ * Record the fact that the PCI device is enabled so that it can
+ * be disabled during _detach().
+ *
+ * For this example driver, we assume PCI BAR 0 is the main I/O
+ * region for the board registers and use dev->iobase to hold the
+ * I/O base address and to indicate that the PCI device has been
+ * enabled.
+ *
+ * (For boards with memory-mapped registers, dev->iobase is not
+ * usually needed for register access, so can just be set to 1
+ * to indicate that the PCI device has been enabled.)
+ */
+ dev->iobase = pci_resource_start(pcidev, 0);
- driver_skel_pci_driver.name = (char *)driver_skel.driver_name;
- return pci_register_driver(&driver_skel_pci_driver);
+ /*
+ * Call a common function to handle the remaining things to do for
+ * attaching ISA or PCI boards. (Extra parameters could be added
+ * to pass additional information such as IRQ number.)
+ */
+ return skel_common_attach(dev);
}
-static void __exit driver_skel_cleanup_module(void)
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static void skel_detach(struct comedi_device *dev)
{
- pci_unregister_driver(&driver_skel_pci_driver);
- comedi_driver_unregister(&driver_skel);
+ const struct skel_board *thisboard = comedi_board(dev);
+ struct skel_private *devpriv = dev->private;
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+
+ if (!thisboard || !devpriv)
+ return;
+
+/*
+ * Do common stuff such as freeing IRQ, unmapping remapped memory
+ * regions, etc., being careful to check that the stuff is valid given
+ * that _detach() is called even when _attach() or _auto_attach() return
+ * an error.
+ */
+
+ if (IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS) /* &&
+ thisboard->bustype == pci_bustype */) {
+ /*
+ * PCI board
+ *
+ * If PCI device enabled by _auto_attach() (or _attach()),
+ * disable it here.
+ */
+ if (pcidev && dev->iobase)
+ comedi_pci_disable(pcidev);
+ } else {
+ /*
+ * ISA board
+ *
+ * If I/O regions successfully requested by _attach(),
+ * release them here.
+ */
+ if (dev->iobase)
+ release_region(dev->iobase, SKEL_SIZE);
+ }
}
-module_init(driver_skel_init_module);
-module_exit(driver_skel_cleanup_module);
-#else
-static int __init driver_skel_init_module(void)
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static struct comedi_driver skel_driver = {
+ .driver_name = "dummy",
+ .module = THIS_MODULE,
+ .attach = skel_attach,
+ .auto_attach = skel_auto_attach,
+ .detach = skel_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+ /* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in skel_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+ .board_name = &skel_boards[0].name,
+ .offset = sizeof(struct skel_board),
+ .num_names = ARRAY_SIZE(skel_boards),
+};
+
+#ifdef CONFIG_COMEDI_PCI_DRIVERS
+
+/* This is used by modprobe to translate PCI IDs to drivers. Should
+ * only be used for PCI and ISA-PnP devices */
+/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
+ * upstream. */
+#define PCI_VENDOR_ID_SKEL 0xdafe
+static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0100) },
+ { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0200) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, skel_pci_table);
+
+static int skel_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
{
- return comedi_driver_register(&driver_skel);
+ return comedi_pci_auto_config(dev, &skel_driver);
}
-static void __exit driver_skel_cleanup_module(void)
+static void skel_pci_remove(struct pci_dev *dev)
{
- comedi_driver_unregister(&driver_skel);
+ comedi_pci_auto_unconfig(dev);
}
-module_init(driver_skel_init_module);
-module_exit(driver_skel_cleanup_module);
+static struct pci_driver skel_pci_driver = {
+ .id_table = skel_pci_table,
+ .probe = &skel_pci_probe,
+ .remove = &skel_pci_remove
+};
+module_comedi_pci_driver(skel_driver, skel_pci_driver);
+#else
+module_comedi_driver(skel_driver);
#endif
MODULE_AUTHOR("Comedi http://www.comedi.org");
diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c
index ae3aa1c5cae..afa4016f906 100644
--- a/drivers/staging/comedi/drivers/ssv_dnp.c
+++ b/drivers/staging/comedi/drivers/ssv_dnp.c
@@ -50,15 +50,6 @@ Status: unknown
#define PCMR 0xa3 /* Port C Mode Register */
#define PCDR 0xa7 /* Port C Data Register */
-/* This data structure holds information about the supported boards -------- */
-
-struct dnp_board {
- const char *name;
- int ai_chans;
- int ai_bits;
- int have_dio;
-};
-
/* ------------------------------------------------------------------------- */
/* 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 */
@@ -173,11 +164,10 @@ static int dnp_dio_insn_config(struct comedi_device *dev,
static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- const struct dnp_board *board = comedi_board(dev);
struct comedi_subdevice *s;
int ret;
- dev->board_name = board->name;
+ dev->board_name = dev->driver->driver_name;
ret = comedi_alloc_subdevices(dev, 1);
if (ret)
@@ -219,23 +209,11 @@ static void dnp_detach(struct comedi_device *dev)
outb((inb(CSCDR) & 0xAA), CSCDR);
}
-static const struct dnp_board dnp_boards[] = {
- {
- .name = "dnp-1486",
- .ai_chans = 16,
- .ai_bits = 12,
- .have_dio = 1,
- },
-};
-
static struct comedi_driver dnp_driver = {
- .driver_name = "ssv_dnp",
+ .driver_name = "dnp-1486",
.module = THIS_MODULE,
.attach = dnp_attach,
.detach = dnp_detach,
- .board_name = &dnp_boards[0].name,
- .offset = sizeof(struct dnp_board),
- .num_names = ARRAY_SIZE(dnp_boards),
};
module_comedi_driver(dnp_driver);
diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c
index 9f1fdec62dc..c9ded938314 100644
--- a/drivers/staging/comedi/drivers/unioxx5.c
+++ b/drivers/staging/comedi/drivers/unioxx5.c
@@ -42,6 +42,8 @@ Devices: [Fastwel] UNIOxx-5 (unioxx5),
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "../comedidev.h"
#include <linux/ioport.h>
#include <linux/slab.h>
@@ -144,8 +146,7 @@ static int __unioxx5_digital_read(struct unioxx5_subd_priv *usp,
channel_offset = __unioxx5_define_chan_offset(channel);
if (channel_offset < 0) {
- printk(KERN_ERR
- "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+ pr_err("comedi%d: undefined channel %d. channel range is 0 .. 23\n",
minor, channel);
return 0;
}
@@ -171,8 +172,7 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp,
/* defining if given module can work on input */
if (usp->usp_module_type[module_no] & MODULE_OUTPUT_MASK) {
- printk(KERN_ERR
- "comedi%d: module in position %d with id 0x%02x is for output only",
+ pr_err("comedi%d: module in position %d with id 0x%02x is for output only",
minor, module_no, usp->usp_module_type[module_no]);
return 0;
}
@@ -209,8 +209,7 @@ static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp,
channel_offset = __unioxx5_define_chan_offset(channel);
if (channel_offset < 0) {
- printk(KERN_ERR
- "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+ pr_err("comedi%d: undefined channel %d. channel range is 0 .. 23\n",
minor, channel);
return 0;
}
@@ -240,8 +239,7 @@ static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp,
/* defining if given module can work on output */
if (!(usp->usp_module_type[module] & MODULE_OUTPUT_MASK)) {
- printk(KERN_ERR
- "comedi%d: module in position %d with id 0x%0x is for input only!\n",
+ pr_err("comedi%d: module in position %d with id 0x%0x is for input only!\n",
minor, module, usp->usp_module_type[module]);
return 0;
}
@@ -323,17 +321,17 @@ static int unioxx5_insn_config(struct comedi_device *dev,
type = usp->usp_module_type[channel / 2];
if (type != MODULE_DIGITAL) {
- printk(KERN_ERR
- "comedi%d: channel configuration accessible only for digital modules\n",
- dev->minor);
+ dev_err(dev->class_dev,
+ "comedi%d: channel configuration accessible only for digital modules\n",
+ dev->minor);
return -1;
}
channel_offset = __unioxx5_define_chan_offset(channel);
if (channel_offset < 0) {
- printk(KERN_ERR
- "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
- dev->minor, channel);
+ dev_err(dev->class_dev,
+ "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+ dev->minor, channel);
return -1;
}
@@ -348,7 +346,8 @@ static int unioxx5_insn_config(struct comedi_device *dev,
flags |= mask;
break;
default:
- printk(KERN_ERR "comedi%d: unknown flag\n", dev->minor);
+ dev_err(dev->class_dev,
+ "comedi%d: unknown flag\n", dev->minor);
return -1;
}
@@ -375,19 +374,21 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev,
int i, to, ndef_flag = 0;
if (!request_region(subdev_iobase, UNIOXX5_SIZE, DRIVER_NAME)) {
- printk(KERN_ERR "comedi%d: I/O port conflict\n", minor);
+ dev_err(subdev->class_dev,
+ "comedi%d: I/O port conflict\n", minor);
return -EIO;
}
usp = kzalloc(sizeof(*usp), GFP_KERNEL);
if (usp == NULL) {
- printk(KERN_ERR "comedi%d: error! --> out of memory!\n", minor);
+ dev_err(subdev->class_dev,
+ "comedi%d: error! --> out of memory!\n", minor);
return -1;
}
usp->usp_iobase = subdev_iobase;
- printk(KERN_INFO "comedi%d: |", minor);
+ dev_info(subdev->class_dev, "comedi%d: |", minor);
/* defining modules types */
for (i = 0; i < 12; i++) {
@@ -433,8 +434,6 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev,
/* for digital modules only!!! */
subdev->insn_config = unioxx5_insn_config;
- printk(KERN_INFO "subdevice configured\n");
-
return 0;
}
@@ -464,8 +463,8 @@ static int unioxx5_attach(struct comedi_device *dev,
/* unioxx5 can has from two to four subdevices */
if (n_subd < 2) {
- printk(KERN_ERR
- "your card must has at least 2 'g01' subdevices\n");
+ dev_err(dev->class_dev,
+ "your card must has at least 2 'g01' subdevices\n");
return -1;
}
@@ -480,7 +479,6 @@ static int unioxx5_attach(struct comedi_device *dev,
return -1;
}
- printk(KERN_INFO "attached\n");
return 0;
}
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index b536bba7435..78f3a2e013c 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -938,9 +938,6 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
if (!(this_usbduxsub->probed))
return -ENODEV;
- dev_dbg(&this_usbduxsub->interface->dev,
- "comedi%d: usbdux_ai_cmdtest\n", dev->minor);
-
/* Step 1 : check if triggers are trivially valid */
err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
@@ -962,19 +959,12 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- /* internal trigger */
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
if (cmd->scan_begin_src == TRIG_TIMER) {
if (this_usbduxsub->high_speed) {
@@ -989,51 +979,35 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
while (i < (cmd->chanlist_len))
i = i * 2;
- if (cmd->scan_begin_arg < (1000000 / 8 * i)) {
- cmd->scan_begin_arg = 1000000 / 8 * i;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ 1000000 / 8 * i);
/* now calc the real sampling rate with all the
* rounding errors */
tmpTimer =
((unsigned int)(cmd->scan_begin_arg / 125000)) *
125000;
- if (cmd->scan_begin_arg != tmpTimer) {
- cmd->scan_begin_arg = tmpTimer;
- err++;
- }
} else {
/* full speed */
/* 1kHz scans every USB frame */
- if (cmd->scan_begin_arg < 1000000) {
- cmd->scan_begin_arg = 1000000;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ 1000000);
/*
* calc the real sampling rate with the rounding errors
*/
tmpTimer = ((unsigned int)(cmd->scan_begin_arg /
1000000)) * 1000000;
- if (cmd->scan_begin_arg != tmpTimer) {
- cmd->scan_begin_arg = tmpTimer;
- err++;
- }
}
- }
- /* the same argument */
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
+ tmpTimer);
}
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
if (cmd->stop_src == TRIG_COUNT) {
/* any count is allowed */
} else {
/* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
}
if (err)
@@ -1472,9 +1446,6 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev,
if (!(this_usbduxsub->probed))
return -ENODEV;
- dev_dbg(&this_usbduxsub->interface->dev,
- "comedi%d: usbdux_ao_cmdtest\n", dev->minor);
-
/* Step 1 : check if triggers are trivially valid */
err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
@@ -1519,57 +1490,30 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- /* internal trigger */
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
- }
+ if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+
+ if (cmd->scan_begin_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ 1000000);
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* timer */
- if (cmd->scan_begin_arg < 1000000) {
- cmd->scan_begin_arg = 1000000;
- err++;
- }
- }
/* not used now, is for later use */
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < 125000) {
- cmd->convert_arg = 125000;
- err++;
- }
- }
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
- /* the same argument */
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
if (cmd->stop_src == TRIG_COUNT) {
/* any count is allowed */
} else {
/* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
}
- dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: err=%d, "
- "scan_begin_src=%d, scan_begin_arg=%d, convert_src=%d, "
- "convert_arg=%d\n", dev->minor, err, cmd->scan_begin_src,
- cmd->scan_begin_arg, cmd->convert_src, cmd->convert_arg);
-
if (err)
return 3;
@@ -2375,9 +2319,10 @@ static int usbdux_attach_common(struct comedi_device *dev,
return 0;
}
-static int usbdux_attach_usb(struct comedi_device *dev,
- struct usb_interface *uinterf)
+static int usbdux_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct usb_interface *uinterf = comedi_to_usb_interface(dev);
int ret;
struct usbduxsub *this_usbduxsub;
@@ -2386,14 +2331,12 @@ static int usbdux_attach_usb(struct comedi_device *dev,
down(&start_stop_sem);
this_usbduxsub = usb_get_intfdata(uinterf);
if (!this_usbduxsub || !this_usbduxsub->probed) {
- printk(KERN_ERR
- "comedi%d: usbdux: error: attach_usb failed, not connected\n",
- dev->minor);
+ dev_err(dev->class_dev,
+ "usbdux: error: auto_attach failed, not connected\n");
ret = -ENODEV;
} else if (this_usbduxsub->attached) {
- printk(KERN_ERR
- "comedi%d: usbdux: error: attach_usb failed, already attached\n",
- dev->minor);
+ dev_err(dev->class_dev,
+ "error: auto_attach failed, already attached\n");
ret = -ENODEV;
} else
ret = usbdux_attach_common(dev, this_usbduxsub);
@@ -2417,7 +2360,7 @@ static void usbdux_detach(struct comedi_device *dev)
static struct comedi_driver usbdux_driver = {
.driver_name = "usbdux",
.module = THIS_MODULE,
- .attach_usb = usbdux_attach_usb,
+ .auto_attach = usbdux_auto_attach,
.detach = usbdux_detach,
};
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index 1154a7e2895..4e19f6186f2 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -37,6 +37,8 @@
* udev coldplug problem
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/firmware.h>
#include <linux/module.h>
@@ -216,8 +218,9 @@ static int send_dux_commands(struct usbduxfastsub_s *udfs, int cmd_type)
usb_sndbulkpipe(udfs->usbdev, CHANNELLISTEP),
udfs->dux_commands, SIZEOFDUXBUFFER, &nsent, 10000);
if (tmp < 0)
- printk(KERN_ERR "comedi%d: could not transmit dux_commands to"
- "the usb-device, err=%d\n", udfs->comedidev->minor, tmp);
+ dev_err(&udfs->interface->dev,
+ "could not transmit dux_commands to the usb-device, err=%d\n",
+ tmp);
return tmp;
}
@@ -252,7 +255,7 @@ static int usbduxfast_ai_stop(struct usbduxfastsub_s *udfs, int do_unlink)
int ret = 0;
if (!udfs) {
- printk(KERN_ERR "comedi?: usbduxfast_ai_stop: udfs=NULL!\n");
+ pr_err("%s: udfs=NULL!\n", __func__);
return -EFAULT;
}
#ifdef CONFIG_COMEDI_DEBUG
@@ -284,7 +287,7 @@ static int usbduxfast_ai_cancel(struct comedi_device *dev,
#endif
udfs = dev->private;
if (!udfs) {
- printk(KERN_ERR "comedi: usbduxfast_ai_cancel: udfs=NULL\n");
+ dev_err(dev->class_dev, "%s: udfs=NULL\n", __func__);
return -EFAULT;
}
down(&udfs->sem);
@@ -309,26 +312,22 @@ static void usbduxfastsub_ai_Irq(struct urb *urb)
struct usbduxfastsub_s *udfs;
struct comedi_device *this_comedidev;
struct comedi_subdevice *s;
- uint16_t *p;
/* sanity checks - is the urb there? */
if (!urb) {
- printk(KERN_ERR "comedi_: usbduxfast_: ao int-handler called "
- "with urb=NULL!\n");
+ pr_err("ao int-handler called with urb=NULL!\n");
return;
}
/* the context variable points to the subdevice */
this_comedidev = urb->context;
if (!this_comedidev) {
- printk(KERN_ERR "comedi_: usbduxfast_: urb context is a NULL "
- "pointer!\n");
+ pr_err("urb context is a NULL pointer!\n");
return;
}
/* the private structure of the subdevice is usbduxfastsub_s */
udfs = this_comedidev->private;
if (!udfs) {
- printk(KERN_ERR "comedi_: usbduxfast_: private of comedi "
- "subdev is a NULL pointer!\n");
+ pr_err("private of comedi subdev is a NULL pointer!\n");
return;
}
/* are we running a command? */
@@ -370,9 +369,8 @@ static void usbduxfastsub_ai_Irq(struct urb *urb)
return;
default:
- printk("comedi%d: usbduxfast: non-zero urb status received in "
- "ai intr context: %d\n",
- udfs->comedidev->minor, urb->status);
+ pr_err("non-zero urb status received in ai intr context: %d\n",
+ urb->status);
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
comedi_event(udfs->comedidev, s);
@@ -380,7 +378,6 @@ static void usbduxfastsub_ai_Irq(struct urb *urb)
return;
}
- p = urb->transfer_buffer;
if (!udfs->ignore) {
if (!udfs->ai_continous) {
/* not continuous, fixed number of samples */
@@ -427,8 +424,8 @@ static void usbduxfastsub_ai_Irq(struct urb *urb)
urb->status = 0;
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
- printk(KERN_ERR "comedi%d: usbduxfast: urb resubm failed: %d",
- udfs->comedidev->minor, err);
+ dev_err(&urb->dev->dev,
+ "urb resubm failed: %d", err);
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
comedi_event(udfs->comedidev, s);
@@ -454,7 +451,8 @@ static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
1, /* Length */
EZTIMEOUT); /* Timeout */
if (ret < 0) {
- printk("comedi_: usbduxfast_: control msg failed (start)\n");
+ dev_err(&udfs->interface->dev,
+ "control msg failed (start)\n");
return ret;
}
@@ -477,8 +475,8 @@ static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
local_transfer_buffer, 1, /* Length */
EZTIMEOUT); /* Timeout */
if (ret < 0) {
- printk(KERN_ERR "comedi_: usbduxfast: control msg failed "
- "(stop)\n");
+ dev_err(&udfs->interface->dev,
+ "control msg failed (stop)\n");
return ret;
}
@@ -512,7 +510,7 @@ static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs,
#endif
if (ret < 0) {
- printk(KERN_ERR "comedi_: usbduxfast: uppload failed\n");
+ dev_err(&udfs->interface->dev, "uppload failed\n");
return ret;
}
@@ -538,8 +536,8 @@ static int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs)
#endif
ret = usb_submit_urb(udfs->urbIn, GFP_ATOMIC);
if (ret) {
- printk(KERN_ERR "comedi_: usbduxfast: ai: usb_submit_urb error"
- " %d\n", ret);
+ dev_err(&udfs->interface->dev,
+ "ai: usb_submit_urb error %d\n", ret);
return ret;
}
return 0;
@@ -557,12 +555,6 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
if (!udfs->probed)
return -ENODEV;
-#ifdef CONFIG_COMEDI_DEBUG
- printk(KERN_DEBUG "comedi%d: usbduxfast_ai_cmdtest\n", dev->minor);
- printk(KERN_DEBUG "comedi%d: usbduxfast: convert_arg=%u "
- "scan_begin_arg=%u\n",
- dev->minor, cmd->convert_arg, cmd->scan_begin_arg);
-#endif
/* Step 1 : check if triggers are trivially valid */
err |= cfc_check_trigger_src(&cmd->start_src,
@@ -592,20 +584,15 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_src == TRIG_NOW && cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ if (cmd->start_src == TRIG_NOW)
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
if (!cmd->chanlist_len)
- err++;
+ err |= -EINVAL;
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
if (cmd->chanlist_len == 1)
minSamplPer = 1;
@@ -622,28 +609,19 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
/* calc arg again */
tmp = steps / 30;
- if (cmd->convert_arg != tmp) {
- cmd->convert_arg = tmp;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, tmp);
}
if (cmd->scan_begin_src == TRIG_TIMER)
- err++;
+ err |= -EINVAL;
/* stop source */
switch (cmd->stop_src) {
case TRIG_COUNT:
- if (!cmd->stop_arg) {
- cmd->stop_arg = 1;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
break;
case TRIG_NONE:
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
break;
/*
* TRIG_EXT doesn't care since it doesn't trigger
@@ -682,8 +660,7 @@ static int usbduxfast_ai_inttrig(struct comedi_device *dev,
#endif
if (trignum != 0) {
- printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: invalid"
- " trignum\n", dev->minor);
+ dev_err(dev->class_dev, "%s: invalid trignum\n", __func__);
up(&udfs->sem);
return -EINVAL;
}
@@ -691,16 +668,16 @@ static int usbduxfast_ai_inttrig(struct comedi_device *dev,
udfs->ai_cmd_running = 1;
ret = usbduxfastsub_submit_InURBs(udfs);
if (ret < 0) {
- printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: "
- "urbSubmit: err=%d\n", dev->minor, ret);
+ dev_err(dev->class_dev,
+ "%s: urbSubmit: err=%d\n", __func__, ret);
udfs->ai_cmd_running = 0;
up(&udfs->sem);
return ret;
}
s->async->inttrig = NULL;
} else {
- printk(KERN_ERR "comedi%d: ai_inttrig but acqu is already"
- " running\n", dev->minor);
+ dev_err(dev->class_dev,
+ "ai_inttrig but acqu is already running\n");
}
up(&udfs->sem);
return 1;
@@ -738,8 +715,8 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
return -ENODEV;
}
if (udfs->ai_cmd_running) {
- printk(KERN_ERR "comedi%d: ai_cmd not possible. Another ai_cmd"
- " is running.\n", dev->minor);
+ dev_err(dev->class_dev,
+ "ai_cmd not possible. Another ai_cmd is running.\n");
up(&udfs->sem);
return -EBUSY;
}
@@ -757,31 +734,29 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
for (i = 0; i < cmd->chanlist_len; ++i) {
chan = CR_CHAN(cmd->chanlist[i]);
if (chan != i) {
- printk(KERN_ERR "comedi%d: cmd is accepting "
- "only consecutive channels.\n",
- dev->minor);
+ dev_err(dev->class_dev,
+ "cmd is accepting only consecutive channels.\n");
up(&udfs->sem);
return -EINVAL;
}
if ((gain != CR_RANGE(cmd->chanlist[i]))
&& (cmd->chanlist_len > 3)) {
- printk(KERN_ERR "comedi%d: the gain must be"
- " the same for all channels.\n",
- dev->minor);
+ dev_err(dev->class_dev,
+ "the gain must be the same for all channels.\n");
up(&udfs->sem);
return -EINVAL;
}
if (i >= NUMCHANNELS) {
- printk(KERN_ERR "comedi%d: channel list too"
- " long\n", dev->minor);
+ dev_err(dev->class_dev,
+ "channel list too long\n");
break;
}
}
}
steps = 0;
if (cmd->scan_begin_src == TRIG_TIMER) {
- printk(KERN_ERR "comedi%d: usbduxfast: "
- "scan_begin_src==TRIG_TIMER not valid.\n", dev->minor);
+ dev_err(dev->class_dev,
+ "scan_begin_src==TRIG_TIMER not valid.\n");
up(&udfs->sem);
return -EINVAL;
}
@@ -789,22 +764,21 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
steps = (cmd->convert_arg * 30) / 1000;
if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) {
- printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: steps=%ld, "
- "scan_begin_arg=%d. Not properly tested by cmdtest?\n",
- dev->minor, steps, cmd->scan_begin_arg);
+ dev_err(dev->class_dev,
+ "ai_cmd: steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n",
+ steps, cmd->scan_begin_arg);
up(&udfs->sem);
return -EINVAL;
}
if (steps > MAX_SAMPLING_PERIOD) {
- printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: sampling rate "
- "too low.\n", dev->minor);
+ dev_err(dev->class_dev, "ai_cmd: sampling rate too low.\n");
up(&udfs->sem);
return -EINVAL;
}
if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
&& (cmd->chanlist_len != 16)) {
- printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: TRIG_EXT only"
- " with 1 or 16 channels possible.\n", dev->minor);
+ dev_err(dev->class_dev,
+ "ai_cmd: TRIG_EXT only with 1 or 16 channels possible.\n");
up(&udfs->sem);
return -EINVAL;
}
@@ -1121,8 +1095,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
break;
default:
- printk(KERN_ERR "comedi %d: unsupported combination of "
- "channels\n", dev->minor);
+ dev_err(dev->class_dev, "unsupported combination of channels\n");
up(&udfs->sem);
return -EFAULT;
}
@@ -1134,17 +1107,16 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
/* 0 means that the AD commands are sent */
result = send_dux_commands(udfs, SENDADCOMMANDS);
if (result < 0) {
- printk(KERN_ERR "comedi%d: adc command could not be submitted."
- "Aborting...\n", dev->minor);
+ dev_err(dev->class_dev,
+ "adc command could not be submitted. Aborting...\n");
up(&udfs->sem);
return result;
}
if (cmd->stop_src == TRIG_COUNT) {
udfs->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg;
if (udfs->ai_sample_count < 1) {
- printk(KERN_ERR "comedi%d: "
- "(cmd->stop_arg)*(cmd->scan_end_arg)<1, "
- "aborting.\n", dev->minor);
+ dev_err(dev->class_dev,
+ "(cmd->stop_arg)*(cmd->scan_end_arg)<1, aborting.\n");
up(&udfs->sem);
return -EFAULT;
}
@@ -1193,8 +1165,7 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev,
udfs = dev->private;
if (!udfs) {
- printk(KERN_ERR "comedi%d: ai_insn_read: no usb dev.\n",
- dev->minor);
+ dev_err(dev->class_dev, "%s: no usb dev.\n", __func__);
return -ENODEV;
}
#ifdef CONFIG_COMEDI_DEBUG
@@ -1207,8 +1178,8 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev,
return -ENODEV;
}
if (udfs->ai_cmd_running) {
- printk(KERN_ERR "comedi%d: ai_insn_read not possible. Async "
- "Command is running.\n", dev->minor);
+ dev_err(dev->class_dev,
+ "ai_insn_read not possible. Async Command is running.\n");
up(&udfs->sem);
return -EBUSY;
}
@@ -1268,8 +1239,8 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev,
/* 0 means that the AD commands are sent */
err = send_dux_commands(udfs, SENDADCOMMANDS);
if (err < 0) {
- printk(KERN_ERR "comedi%d: adc command could not be submitted."
- "Aborting...\n", dev->minor);
+ dev_err(dev->class_dev,
+ "adc command could not be submitted. Aborting...\n");
up(&udfs->sem);
return err;
}
@@ -1284,8 +1255,7 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev,
udfs->transfer_buffer, SIZEINBUF,
&actual_length, 10000);
if (err < 0) {
- printk(KERN_ERR "comedi%d: insn timeout. No data.\n",
- dev->minor);
+ dev_err(dev->class_dev, "insn timeout. No data.\n");
up(&udfs->sem);
return err;
}
@@ -1297,15 +1267,13 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev,
udfs->transfer_buffer, SIZEINBUF,
&actual_length, 10000);
if (err < 0) {
- printk(KERN_ERR "comedi%d: insn data error: %d\n",
- dev->minor, err);
+ dev_err(dev->class_dev, "insn data error: %d\n", err);
up(&udfs->sem);
return err;
}
n = actual_length / sizeof(uint16_t);
if ((n % 16) != 0) {
- printk(KERN_ERR "comedi%d: insn data packet "
- "corrupted.\n", dev->minor);
+ dev_err(dev->class_dev, "insn data packet corrupted.\n");
up(&udfs->sem);
return -EINVAL;
}
@@ -1454,9 +1422,10 @@ static int usbduxfast_attach_common(struct comedi_device *dev,
return 0;
}
-static int usbduxfast_attach_usb(struct comedi_device *dev,
- struct usb_interface *uinterf)
+static int usbduxfast_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct usb_interface *uinterf = comedi_to_usb_interface(dev);
int ret;
struct usbduxfastsub_s *udfs;
@@ -1465,11 +1434,11 @@ static int usbduxfast_attach_usb(struct comedi_device *dev,
udfs = usb_get_intfdata(uinterf);
if (!udfs || !udfs->probed) {
dev_err(dev->class_dev,
- "usbduxfast: error: attach_usb failed, not connected\n");
+ "usbduxfast: error: auto_attach failed, not connected\n");
ret = -ENODEV;
} else if (udfs->attached) {
dev_err(dev->class_dev,
- "usbduxfast: error: attach_usb failed, already attached\n");
+ "usbduxfast: error: auto_attach failed, already attached\n");
ret = -ENODEV;
} else
ret = usbduxfast_attach_common(dev, udfs);
@@ -1495,7 +1464,7 @@ static void usbduxfast_detach(struct comedi_device *dev)
static struct comedi_driver usbduxfast_driver = {
.driver_name = "usbduxfast",
.module = THIS_MODULE,
- .attach_usb = usbduxfast_attach_usb,
+ .auto_attach = usbduxfast_auto_attach,
.detach = usbduxfast_detach,
};
@@ -1535,8 +1504,8 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf,
int ret;
if (udev->speed != USB_SPEED_HIGH) {
- printk(KERN_ERR "comedi_: usbduxfast_: This driver needs"
- "USB 2.0 to operate. Aborting...\n");
+ dev_err(&uinterf->dev,
+ "This driver needs USB 2.0 to operate. Aborting...\n");
return -ENODEV;
}
#ifdef CONFIG_COMEDI_DEBUG
@@ -1555,7 +1524,8 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf,
/* no more space */
if (index == -1) {
- printk(KERN_ERR "Too many usbduxfast-devices connected.\n");
+ dev_err(&uinterf->dev,
+ "Too many usbduxfast-devices connected.\n");
up(&start_stop_sem);
return -EMFILE;
}
@@ -1586,8 +1556,8 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf,
usbduxfastsub[index].dux_commands = kmalloc(SIZEOFDUXBUFFER,
GFP_KERNEL);
if (!usbduxfastsub[index].dux_commands) {
- printk(KERN_ERR "comedi_: usbduxfast: error alloc space for "
- "dac commands\n");
+ dev_err(&uinterf->dev,
+ "error alloc space for dac commands\n");
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENOMEM;
@@ -1595,8 +1565,8 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf,
/* create space of the instruction buffer */
usbduxfastsub[index].insnBuffer = kmalloc(SIZEINSNBUF, GFP_KERNEL);
if (!usbduxfastsub[index].insnBuffer) {
- printk(KERN_ERR "comedi_: usbduxfast: could not alloc space "
- "for insnBuffer\n");
+ dev_err(&uinterf->dev,
+ "could not alloc space for insnBuffer\n");
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENOMEM;
@@ -1605,24 +1575,25 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf,
i = usb_set_interface(usbduxfastsub[index].usbdev,
usbduxfastsub[index].ifnum, 1);
if (i < 0) {
- printk(KERN_ERR "comedi_: usbduxfast%d: could not switch to "
- "alternate setting 1.\n", index);
+ dev_err(&uinterf->dev,
+ "usbduxfast%d: could not switch to alternate setting 1.\n",
+ index);
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENODEV;
}
usbduxfastsub[index].urbIn = usb_alloc_urb(0, GFP_KERNEL);
if (!usbduxfastsub[index].urbIn) {
- printk(KERN_ERR "comedi_: usbduxfast%d: Could not alloc."
- "urb\n", index);
+ dev_err(&uinterf->dev,
+ "usbduxfast%d: Could not alloc. urb\n", index);
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
usbduxfastsub[index].transfer_buffer = kmalloc(SIZEINBUF, GFP_KERNEL);
if (!usbduxfastsub[index].transfer_buffer) {
- printk(KERN_ERR "comedi_: usbduxfast%d: could not alloc. "
- "transb.\n", index);
+ dev_err(&uinterf->dev,
+ "usbduxfast%d: could not alloc. transb.\n", index);
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENOMEM;
@@ -1640,12 +1611,12 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf,
usbduxfast_firmware_request_complete_handler);
if (ret) {
- dev_err(&udev->dev, "could not load firmware (err=%d)\n", ret);
+ dev_err(&uinterf->dev, "could not load firmware (err=%d)\n", ret);
return ret;
}
- printk(KERN_INFO "comedi_: usbduxfast%d has been successfully "
- "initialized.\n", index);
+ dev_info(&uinterf->dev,
+ "usbduxfast%d has been successfully initialized.\n", index);
/* success */
return 0;
}
@@ -1656,13 +1627,11 @@ static void usbduxfast_usb_disconnect(struct usb_interface *intf)
struct usb_device *udev = interface_to_usbdev(intf);
if (!udfs) {
- printk(KERN_ERR "comedi_: usbduxfast: disconnect called with "
- "null pointer.\n");
+ dev_err(&intf->dev, "disconnect called with null pointer.\n");
return;
}
if (udfs->usbdev != udev) {
- printk(KERN_ERR "comedi_: usbduxfast: BUG! called with wrong "
- "ptr!!!\n");
+ dev_err(&intf->dev, "BUG! called with wrong ptr!!!\n");
return;
}
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c
index b1694121f84..cdd279b1f61 100644
--- a/drivers/staging/comedi/drivers/usbduxsigma.c
+++ b/drivers/staging/comedi/drivers/usbduxsigma.c
@@ -904,9 +904,6 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
if (!(this_usbduxsub->probed))
return -ENODEV;
- dev_dbg(&this_usbduxsub->interface->dev,
- "comedi%d: usbdux_ai_cmdtest\n", dev->minor);
-
/* Step 1 : check if triggers are trivially valid */
err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
@@ -928,19 +925,12 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- /* internal trigger */
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
if (cmd->scan_begin_src == TRIG_TIMER) {
if (this_usbduxsub->high_speed) {
@@ -951,51 +941,35 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
* are in the channel list the more time we need.
*/
i = chanToInterval(cmd->chanlist_len);
- if (cmd->scan_begin_arg < (1000000 / 8 * i)) {
- cmd->scan_begin_arg = 1000000 / 8 * i;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ (1000000 / 8 * i));
/* now calc the real sampling rate with all the
* rounding errors */
tmpTimer =
((unsigned int)(cmd->scan_begin_arg / 125000)) *
125000;
- if (cmd->scan_begin_arg != tmpTimer) {
- cmd->scan_begin_arg = tmpTimer;
- err++;
- }
} else {
/* full speed */
/* 1kHz scans every USB frame */
- if (cmd->scan_begin_arg < 1000000) {
- cmd->scan_begin_arg = 1000000;
- err++;
- }
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ 1000000);
/*
* calc the real sampling rate with the rounding errors
*/
tmpTimer = ((unsigned int)(cmd->scan_begin_arg /
1000000)) * 1000000;
- if (cmd->scan_begin_arg != tmpTimer) {
- cmd->scan_begin_arg = tmpTimer;
- err++;
- }
}
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
+ tmpTimer);
}
- /* the same argument */
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
if (cmd->stop_src == TRIG_COUNT) {
/* any count is allowed */
} else {
/* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
}
if (err)
@@ -1576,57 +1550,30 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev,
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg != 0) {
- cmd->start_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- /* internal trigger */
- if (cmd->scan_begin_arg != 0) {
- cmd->scan_begin_arg = 0;
- err++;
- }
- }
+ if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+
+ if (cmd->scan_begin_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ 1000000);
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* timer */
- if (cmd->scan_begin_arg < 1000000) {
- cmd->scan_begin_arg = 1000000;
- err++;
- }
- }
/* not used now, is for later use */
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->convert_arg < 125000) {
- cmd->convert_arg = 125000;
- err++;
- }
- }
+ if (cmd->convert_src == TRIG_TIMER)
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
- /* the same argument */
- if (cmd->scan_end_arg != cmd->chanlist_len) {
- cmd->scan_end_arg = cmd->chanlist_len;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
if (cmd->stop_src == TRIG_COUNT) {
/* any count is allowed */
} else {
/* TRIG_NONE */
- if (cmd->stop_arg != 0) {
- cmd->stop_arg = 0;
- err++;
- }
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
}
- dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: err=%d, "
- "scan_begin_src=%d, scan_begin_arg=%d, convert_src=%d, "
- "convert_arg=%d\n", dev->minor, err, cmd->scan_begin_src,
- cmd->scan_begin_arg, cmd->convert_src, cmd->convert_arg);
-
if (err)
return 3;
@@ -2359,9 +2306,10 @@ static int usbduxsigma_attach_common(struct comedi_device *dev,
return 0;
}
-static int usbduxsigma_attach_usb(struct comedi_device *dev,
- struct usb_interface *uinterf)
+static int usbduxsigma_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
{
+ struct usb_interface *uinterf = comedi_to_usb_interface(dev);
int ret;
struct usbduxsub *uds;
@@ -2370,11 +2318,11 @@ static int usbduxsigma_attach_usb(struct comedi_device *dev,
uds = usb_get_intfdata(uinterf);
if (!uds || !uds->probed) {
dev_err(dev->class_dev,
- "usbduxsigma: error: attach_usb failed, not connected\n");
+ "usbduxsigma: error: auto_attach failed, not connected\n");
ret = -ENODEV;
} else if (uds->attached) {
dev_err(dev->class_dev,
- "usbduxsigma: error: attach_usb failed, already attached\n");
+ "usbduxsigma: error: auto_attach failed, already attached\n");
ret = -ENODEV;
} else
ret = usbduxsigma_attach_common(dev, uds);
@@ -2398,7 +2346,7 @@ static void usbduxsigma_detach(struct comedi_device *dev)
static struct comedi_driver usbduxsigma_driver = {
.driver_name = "usbduxsigma",
.module = THIS_MODULE,
- .attach_usb = usbduxsigma_attach_usb,
+ .auto_attach = usbduxsigma_auto_attach,
.detach = usbduxsigma_detach,
};
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index df277aa591b..609dc691599 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -1209,9 +1209,10 @@ static int vmk80xx_attach(struct comedi_device *cdev,
}
/* called via comedi_usb_auto_config() */
-static int vmk80xx_attach_usb(struct comedi_device *cdev,
- struct usb_interface *intf)
+static int vmk80xx_auto_attach(struct comedi_device *cdev,
+ unsigned long context_unused)
{
+ struct usb_interface *intf = comedi_to_usb_interface(cdev);
int i;
int ret;
@@ -1246,7 +1247,7 @@ static struct comedi_driver vmk80xx_driver = {
.driver_name = "vmk80xx",
.attach = vmk80xx_attach,
.detach = vmk80xx_detach,
- .attach_usb = vmk80xx_attach_usb,
+ .auto_attach = vmk80xx_auto_attach,
};
static int vmk80xx_usb_probe(struct usb_interface *intf,
@@ -1371,12 +1372,11 @@ static int vmk80xx_usb_probe(struct usb_interface *intf,
if (dev->board.model == VMK8061_MODEL) {
vmk80xx_read_eeprom(dev, IC3_VERSION);
- printk(KERN_INFO "comedi#: vmk80xx: %s\n", dev->fw.ic3_vers);
+ dev_info(&intf->dev, "%s\n", dev->fw.ic3_vers);
if (vmk80xx_check_data_link(dev)) {
vmk80xx_read_eeprom(dev, IC6_VERSION);
- printk(KERN_INFO "comedi#: vmk80xx: %s\n",
- dev->fw.ic6_vers);
+ dev_info(&intf->dev, "%s\n", dev->fw.ic6_vers);
} else {
dbgcm("comedi#: vmk80xx: no conn. to CPU\n");
}
@@ -1387,8 +1387,8 @@ static int vmk80xx_usb_probe(struct usb_interface *intf,
dev->probed = 1;
- printk(KERN_INFO "comedi#: vmk80xx: board #%d [%s] now attached\n",
- dev->count, dev->board.name);
+ dev_info(&intf->dev, "board #%d [%s] now attached\n",
+ dev->count, dev->board.name);
mutex_unlock(&glb_mutex);
@@ -1422,8 +1422,8 @@ static void vmk80xx_usb_disconnect(struct usb_interface *intf)
kfree(dev->usb_rx_buf);
kfree(dev->usb_tx_buf);
- printk(KERN_INFO "comedi#: vmk80xx: board #%d [%s] now detached\n",
- dev->count, dev->board.name);
+ dev_info(&intf->dev, "board #%d [%s] now detached\n",
+ dev->count, dev->board.name);
up(&dev->limit_sem);
mutex_unlock(&glb_mutex);
diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
index 3f20ea55b8d..4dc09a21088 100644
--- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
+++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
@@ -21,7 +21,6 @@
*/
-#define __NO_VERSION__
#include <linux/module.h>
#include <linux/errno.h>
@@ -95,7 +94,8 @@ static int comedi_do_insn(struct comedi_device *dev,
s = &dev->subdevices[insn->subdev];
if (s->type == COMEDI_SUBD_UNUSED) {
- printk(KERN_ERR "%d not useable subdevice\n", insn->subdev);
+ dev_err(dev->class_dev,
+ "%d not useable subdevice\n", insn->subdev);
ret = -EIO;
goto error;
}
@@ -104,7 +104,7 @@ static int comedi_do_insn(struct comedi_device *dev,
ret = comedi_check_chanlist(s, 1, &insn->chanspec);
if (ret < 0) {
- printk(KERN_ERR "bad chanspec\n");
+ dev_err(dev->class_dev, "bad chanspec\n");
ret = -EINVAL;
goto error;
}
diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c
index bb7e70e3e94..01acbe97653 100644
--- a/drivers/staging/comedi/proc.c
+++ b/drivers/staging/comedi/proc.c
@@ -28,7 +28,6 @@
was cool.
*/
-#define __NO_VERSION__
#include "comedidev.h"
#include "comedi_internal.h"
#include <linux/proc_fs.h>
diff --git a/drivers/staging/crystalhd/crystalhd_cmds.c b/drivers/staging/crystalhd/crystalhd_cmds.c
index 05fe78748df..ed99daa6ef4 100644
--- a/drivers/staging/crystalhd/crystalhd_cmds.c
+++ b/drivers/staging/crystalhd/crystalhd_cmds.c
@@ -308,9 +308,9 @@ static enum BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx,
sts = crystalhd_download_fw(ctx->adp, (uint8_t *)idata->add_cdata,
idata->add_cdata_sz);
- if (sts != BC_STS_SUCCESS) {
+ if (sts != BC_STS_SUCCESS)
BCMLOG_ERR("Firmware Download Failure!! - %d\n", sts);
- } else
+ else
ctx->state |= BC_LINK_INIT;
return sts;
@@ -951,7 +951,7 @@ enum BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_
*
* Called at the time of driver load.
*/
-enum BC_STATUS __devinit crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx,
+enum BC_STATUS crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx,
struct crystalhd_adp *adp)
{
int i = 0;
@@ -986,7 +986,7 @@ enum BC_STATUS __devinit crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx,
*
* Called at the time of driver un-load.
*/
-enum BC_STATUS __devexit crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx)
+enum BC_STATUS crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx)
{
BCMLOG(BCMLOG_DBG, "Deleting Command context..\n");
diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c
index 166203aeb7b..85f51fb1842 100644
--- a/drivers/staging/crystalhd/crystalhd_lnx.c
+++ b/drivers/staging/crystalhd/crystalhd_lnx.c
@@ -353,7 +353,7 @@ static const struct file_operations chd_dec_fops = {
.llseek = noop_llseek,
};
-static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp)
+static int chd_dec_init_chdev(struct crystalhd_adp *adp)
{
struct crystalhd_ioctl_data *temp;
struct device *dev;
@@ -418,7 +418,7 @@ fail:
return rc;
}
-static void __devexit chd_dec_release_chdev(struct crystalhd_adp *adp)
+static void chd_dec_release_chdev(struct crystalhd_adp *adp)
{
struct crystalhd_ioctl_data *temp = NULL;
if (!adp)
@@ -443,7 +443,7 @@ static void __devexit chd_dec_release_chdev(struct crystalhd_adp *adp)
crystalhd_delete_elem_pool(adp);
}
-static int __devinit chd_pci_reserve_mem(struct crystalhd_adp *pinfo)
+static int chd_pci_reserve_mem(struct crystalhd_adp *pinfo)
{
int rc;
unsigned long bar2 = pci_resource_start(pinfo->pdev, 2);
@@ -496,7 +496,7 @@ static int __devinit chd_pci_reserve_mem(struct crystalhd_adp *pinfo)
return 0;
}
-static void __devexit chd_pci_release_mem(struct crystalhd_adp *pinfo)
+static void chd_pci_release_mem(struct crystalhd_adp *pinfo)
{
if (!pinfo)
return;
@@ -511,7 +511,7 @@ static void __devexit chd_pci_release_mem(struct crystalhd_adp *pinfo)
}
-static void __devexit chd_dec_pci_remove(struct pci_dev *pdev)
+static void chd_dec_pci_remove(struct pci_dev *pdev)
{
struct crystalhd_adp *pinfo;
enum BC_STATUS sts = BC_STS_SUCCESS;
@@ -537,7 +537,7 @@ static void __devexit chd_dec_pci_remove(struct pci_dev *pdev)
g_adp_info = NULL;
}
-static int __devinit chd_dec_pci_probe(struct pci_dev *pdev,
+static int chd_dec_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *entry)
{
struct crystalhd_adp *pinfo;
@@ -711,7 +711,7 @@ MODULE_DEVICE_TABLE(pci, chd_dec_pci_id_table);
static struct pci_driver bc_chd_70012_driver = {
.name = "Broadcom 70012 Decoder",
.probe = chd_dec_pci_probe,
- .remove = __devexit_p(chd_dec_pci_remove),
+ .remove = chd_dec_pci_remove,
.id_table = chd_dec_pci_id_table,
#ifdef CONFIG_PM
.suspend = chd_dec_pci_suspend,
diff --git a/drivers/staging/crystalhd/crystalhd_misc.c b/drivers/staging/crystalhd/crystalhd_misc.c
index b3a637814a1..a5f109c632d 100644
--- a/drivers/staging/crystalhd/crystalhd_misc.c
+++ b/drivers/staging/crystalhd/crystalhd_misc.c
@@ -960,7 +960,7 @@ void crystalhd_destroy_dio_pool(struct crystalhd_adp *adp)
* Create general purpose list element pool to hold pending,
* and active requests.
*/
-int __devinit crystalhd_create_elem_pool(struct crystalhd_adp *adp,
+int crystalhd_create_elem_pool(struct crystalhd_adp *adp,
uint32_t pool_size)
{
uint32_t i;
diff --git a/drivers/staging/csr/Makefile b/drivers/staging/csr/Makefile
index ab626edc5ba..dbd135a8b17 100644
--- a/drivers/staging/csr/Makefile
+++ b/drivers/staging/csr/Makefile
@@ -70,5 +70,4 @@ csr_helper-y := csr_time.o \
csr_framework_ext.o \
csr_wifi_serialize_primitive_types.o \
csr_serialize_primitive_types.o \
- csr_msgconv.o \
- csr_panic.o
+ csr_msgconv.o
diff --git a/drivers/staging/csr/bh.c b/drivers/staging/csr/bh.c
index addee05a451..1a1f5c79822 100644
--- a/drivers/staging/csr/bh.c
+++ b/drivers/staging/csr/bh.c
@@ -228,20 +228,19 @@ handle_bh_error(unifi_priv_t *priv)
*
* ---------------------------------------------------------------------------
*/
-static int
-bh_thread_function(void *arg)
+static int bh_thread_function(void *arg)
{
- unifi_priv_t *priv = (unifi_priv_t*)arg;
- CsrResult csrResult;
- long ret;
- u32 timeout, t;
- struct uf_thread *this_thread;
+ unifi_priv_t *priv = (unifi_priv_t *)arg;
+ CsrResult csrResult;
+ long ret;
+ u32 timeout, t;
+ struct uf_thread *this_thread;
- unifi_trace(priv, UDBG2, "bh_thread_function starting\n");
+ unifi_trace(priv, UDBG2, "bh_thread_function starting\n");
- this_thread = &priv->bh_thread;
+ this_thread = &priv->bh_thread;
- t = timeout = 0;
+ t = timeout = 0;
while (!kthread_should_stop()) {
/* wait until an error occurs, or we need to process something. */
unifi_trace(priv, UDBG3, "bh_thread goes to sleep.\n");
diff --git a/drivers/staging/csr/csr_framework_ext.c b/drivers/staging/csr/csr_framework_ext.c
index f91a4bf4e68..2aabb6c6b0a 100644
--- a/drivers/staging/csr/csr_framework_ext.c
+++ b/drivers/staging/csr/csr_framework_ext.c
@@ -9,7 +9,6 @@
*****************************************************************************/
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/freezer.h>
@@ -18,102 +17,6 @@
#include <linux/bitops.h>
#include "csr_framework_ext.h"
-#include "csr_panic.h"
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrMutexCreate
- *
- * DESCRIPTION
- * Create a mutex and return a handle to the created mutex.
- *
- * RETURNS
- * Possible values:
- * CSR_RESULT_SUCCESS in case of success
- * CSR_FE_RESULT_NO_MORE_MUTEXES in case of out of mutex resources
- * CSR_FE_RESULT_INVALID_POINTER in case the mutexHandle pointer is invalid
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrMutexCreate(CsrMutexHandle *mutexHandle)
-{
- if (mutexHandle == NULL)
- {
- return CSR_FE_RESULT_INVALID_POINTER;
- }
-
- sema_init(mutexHandle, 1);
-
- return CSR_RESULT_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrMutexDestroy
- *
- * DESCRIPTION
- * Destroy the previously created mutex.
- *
- * RETURNS
- * void
- *
- *----------------------------------------------------------------------------*/
-void CsrMutexDestroy(CsrMutexHandle *mutexHandle)
-{
-}
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrMutexLock
- *
- * DESCRIPTION
- * Lock the mutex refered to by the provided handle.
- *
- * RETURNS
- * Possible values:
- * CSR_RESULT_SUCCESS in case of success
- * CSR_FE_RESULT_INVALID_HANDLE in case the mutexHandle is invalid
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrMutexLock(CsrMutexHandle *mutexHandle)
-{
- if (mutexHandle == NULL)
- {
- return CSR_FE_RESULT_INVALID_POINTER;
- }
-
- if (down_interruptible(mutexHandle))
- {
- CsrPanic(CSR_TECH_FW, CSR_PANIC_FW_UNEXPECTED_VALUE, "CsrMutexLock Failed");
- return CSR_FE_RESULT_INVALID_POINTER;
- }
-
- return CSR_RESULT_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrMutexUnlock
- *
- * DESCRIPTION
- * Unlock the mutex refered to by the provided handle.
- *
- * RETURNS
- * Possible values:
- * CSR_RESULT_SUCCESS in case of success
- * CSR_FE_RESULT_INVALID_HANDLE in case the mutexHandle is invalid
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrMutexUnlock(CsrMutexHandle *mutexHandle)
-{
- if (mutexHandle == NULL)
- {
- return CSR_FE_RESULT_INVALID_POINTER;
- }
-
- up(mutexHandle);
-
- return CSR_RESULT_SUCCESS;
-}
/*----------------------------------------------------------------------------*
* NAME
diff --git a/drivers/staging/csr/csr_framework_ext.h b/drivers/staging/csr/csr_framework_ext.h
index 66973e93a6b..e8ae490c09d 100644
--- a/drivers/staging/csr/csr_framework_ext.h
+++ b/drivers/staging/csr/csr_framework_ext.h
@@ -13,10 +13,6 @@
#include "csr_result.h"
#include "csr_framework_ext_types.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Result codes */
#define CSR_FE_RESULT_NO_MORE_EVENTS ((CsrResult) 0x0001)
#define CSR_FE_RESULT_INVALID_POINTER ((CsrResult) 0x0002)
@@ -34,215 +30,6 @@ extern "C" {
#define CSR_EVENT_WAIT_INFINITE ((u16) 0xFFFF)
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrEventCreate
- *
- * DESCRIPTION
- * Creates an event and returns a handle to the created event.
- *
- * RETURNS
- * Possible values:
- * CSR_RESULT_SUCCESS in case of success
- * CSR_FE_RESULT_NO_MORE_EVENTS in case of out of event resources
- * CSR_FE_RESULT_INVALID_POINTER in case the eventHandle pointer is invalid
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrEventCreate(CsrEventHandle *eventHandle);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrEventWait
- *
- * DESCRIPTION
- * Wait fore one or more of the event bits to be set.
- *
- * RETURNS
- * Possible values:
- * CSR_RESULT_SUCCESS in case of success
- * CSR_FE_RESULT_TIMEOUT in case of timeout
- * CSR_FE_RESULT_INVALID_HANDLE in case the eventHandle is invalid
- * CSR_FE_RESULT_INVALID_POINTER in case the eventBits pointer is invalid
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrEventWait(CsrEventHandle *eventHandle, u16 timeoutInMs, u32 *eventBits);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrEventSet
- *
- * DESCRIPTION
- * Set an event.
- *
- * RETURNS
- * Possible values:
- * CSR_RESULT_SUCCESS in case of success
- * CSR_FE_RESULT_INVALID_HANDLE in case the eventHandle is invalid
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrEventSet(CsrEventHandle *eventHandle, u32 eventBits);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrEventDestroy
- *
- * DESCRIPTION
- * Destroy the event associated.
- *
- * RETURNS
- * void
- *
- *----------------------------------------------------------------------------*/
-void CsrEventDestroy(CsrEventHandle *eventHandle);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrMutexCreate
- *
- * DESCRIPTION
- * Create a mutex and return a handle to the created mutex.
- *
- * RETURNS
- * Possible values:
- * CSR_RESULT_SUCCESS in case of success
- * CSR_FE_RESULT_NO_MORE_MUTEXES in case of out of mutex resources
- * CSR_FE_RESULT_INVALID_POINTER in case the mutexHandle pointer is invalid
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrMutexCreate(CsrMutexHandle *mutexHandle);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrMutexLock
- *
- * DESCRIPTION
- * Lock the mutex refered to by the provided handle.
- *
- * RETURNS
- * Possible values:
- * CSR_RESULT_SUCCESS in case of success
- * CSR_FE_RESULT_INVALID_HANDLE in case the mutexHandle is invalid
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrMutexLock(CsrMutexHandle *mutexHandle);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrMutexUnlock
- *
- * DESCRIPTION
- * Unlock the mutex refered to by the provided handle.
- *
- * RETURNS
- * Possible values:
- * CSR_RESULT_SUCCESS in case of success
- * CSR_FE_RESULT_INVALID_HANDLE in case the mutexHandle is invalid
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrMutexUnlock(CsrMutexHandle *mutexHandle);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrMutexDestroy
- *
- * DESCRIPTION
- * Destroy the previously created mutex.
- *
- * RETURNS
- * void
- *
- *----------------------------------------------------------------------------*/
-void CsrMutexDestroy(CsrMutexHandle *mutexHandle);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrGlobalMutexLock
- *
- * DESCRIPTION
- * Lock the global mutex. The global mutex is a single pre-initialised
- * shared mutex, spinlock or similar that does not need to be created prior
- * to use. The limitation is that there is only one single lock shared
- * between all code. Consequently, it must only be used very briefly to
- * either protect simple one-time initialisation or to protect the creation
- * of a dedicated mutex by calling CsrMutexCreate.
- *
- *----------------------------------------------------------------------------*/
-void CsrGlobalMutexLock(void);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrGlobalMutexUnlock
- *
- * DESCRIPTION
- * Unlock the global mutex.
- *
- *----------------------------------------------------------------------------*/
-void CsrGlobalMutexUnlock(void);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrThreadCreate
- *
- * DESCRIPTION
- * Create thread function and return a handle to the created thread.
- *
- * RETURNS
- * Possible values:
- * CSR_RESULT_SUCCESS in case of success
- * CSR_FE_RESULT_NO_MORE_THREADS in case of out of thread resources
- * CSR_FE_RESULT_INVALID_POINTER in case one of the supplied pointers is invalid
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrThreadCreate(void (*threadFunction)(void *pointer), void *pointer,
- u32 stackSize, u16 priority,
- const char *threadName, CsrThreadHandle *threadHandle);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrThreadGetHandle
- *
- * DESCRIPTION
- * Return thread handle of calling thread.
- *
- * RETURNS
- * Possible values:
- * CSR_RESULT_SUCCESS in case of success
- * CSR_FE_RESULT_INVALID_POINTER in case the threadHandle pointer is invalid
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrThreadGetHandle(CsrThreadHandle *threadHandle);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrThreadEqual
- *
- * DESCRIPTION
- * Compare thread handles
- *
- * RETURNS
- * Possible values:
- * CSR_RESULT_SUCCESS in case thread handles are identical
- * CSR_FE_RESULT_INVALID_POINTER in case either threadHandle pointer is invalid
- * CSR_RESULT_FAILURE otherwise
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrThreadEqual(CsrThreadHandle *threadHandle1, CsrThreadHandle *threadHandle2);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrThreadSleep
- *
- * DESCRIPTION
- * Sleep for a given period.
- *
- * RETURNS
- * void
- *
- *----------------------------------------------------------------------------*/
void CsrThreadSleep(u16 sleepTimeInMs);
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/drivers/staging/csr/csr_framework_ext_types.h b/drivers/staging/csr/csr_framework_ext_types.h
index 57194ee911e..575598cf69b 100644
--- a/drivers/staging/csr/csr_framework_ext_types.h
+++ b/drivers/staging/csr/csr_framework_ext_types.h
@@ -2,11 +2,11 @@
#define CSR_FRAMEWORK_EXT_TYPES_H__
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2010
- All rights reserved and confidential information of CSR
+ (c) Cambridge Silicon Radio Limited 2010
+ All rights reserved and confidential information of CSR
- Refer to LICENSE.txt included with this source for details
- on the license terms.
+ Refer to LICENSE.txt included with this source for details
+ on the license terms.
*****************************************************************************/
@@ -17,47 +17,14 @@
#include <pthread.h>
#endif
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
#ifdef __KERNEL__
-struct CsrThread
-{
- struct task_struct *thread_task;
- char name[16];
-};
-
-struct CsrEvent
-{
- /* wait_queue for waking the kernel thread */
- wait_queue_head_t wakeup_q;
- unsigned int wakeup_flag;
-};
-
-typedef struct CsrEvent CsrEventHandle;
typedef struct semaphore CsrMutexHandle;
-typedef struct CsrThread CsrThreadHandle;
#else /* __KERNEL __ */
-struct CsrEvent
-{
- pthread_cond_t event;
- pthread_mutex_t mutex;
- u32 eventBits;
-};
-
-typedef struct CsrEvent CsrEventHandle;
typedef pthread_mutex_t CsrMutexHandle;
-typedef pthread_t CsrThreadHandle;
#endif /* __KERNEL__ */
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/drivers/staging/csr/csr_lib.h b/drivers/staging/csr/csr_lib.h
deleted file mode 100644
index b1a57d5d06f..00000000000
--- a/drivers/staging/csr/csr_lib.h
+++ /dev/null
@@ -1,188 +0,0 @@
-#ifndef CSR_LIB_H__
-#define CSR_LIB_H__
-/*****************************************************************************
-
- (c) Cambridge Silicon Radio Limited 2010
- All rights reserved and confidential information of CSR
-
- Refer to LICENSE.txt included with this source for details
- on the license terms.
-
-*****************************************************************************/
-
-#include "csr_prim_defs.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct
-{
- CsrPrim type;
-} CsrEvent;
-
-/*----------------------------------------------------------------------------*
- * CsrEvent_struct
- *
- * DESCRIPTION
- * Generic message creator.
- * Allocates and fills in a message with the signature CsrEvent
- *
- *----------------------------------------------------------------------------*/
-CsrEvent *CsrEvent_struct(u16 primtype, u16 msgtype);
-
-typedef struct
-{
- CsrPrim type;
- u8 value;
-} CsrEventCsrUint8;
-
-/*----------------------------------------------------------------------------*
- * CsrEventCsrUint8_struct
- *
- * DESCRIPTION
- * Generic message creator.
- * Allocates and fills in a message with the signature CsrEventCsrUint8
- *
- *----------------------------------------------------------------------------*/
-CsrEventCsrUint8 *CsrEventCsrUint8_struct(u16 primtype, u16 msgtype, u8 value);
-
-typedef struct
-{
- CsrPrim type;
- u16 value;
-} CsrEventCsrUint16;
-
-/*----------------------------------------------------------------------------*
- * CsrEventCsrUint16_struct
- *
- * DESCRIPTION
- * Generic message creator.
- * Allocates and fills in a message with the signature CsrEventCsrUint16
- *
- *----------------------------------------------------------------------------*/
-CsrEventCsrUint16 *CsrEventCsrUint16_struct(u16 primtype, u16 msgtype, u16 value);
-
-typedef struct
-{
- CsrPrim type;
- u16 value1;
- u8 value2;
-} CsrEventCsrUint16CsrUint8;
-
-/*----------------------------------------------------------------------------*
- * CsrEventCsrUint16CsrUint8_struct
- *
- * DESCRIPTION
- * Generic message creator.
- * Allocates and fills in a message with the signature CsrEventCsrUint16CsrUint8
- *
- *----------------------------------------------------------------------------*/
-CsrEventCsrUint16CsrUint8 *CsrEventCsrUint16CsrUint8_struct(u16 primtype, u16 msgtype, u16 value1, u8 value2);
-
-typedef struct
-{
- CsrPrim type;
- u16 value1;
- u16 value2;
-} CsrEventCsrUint16CsrUint16;
-
-/*----------------------------------------------------------------------------*
- * CsrEventCsrUint16CsrUint16_struct
- *
- * DESCRIPTION
- * Generic message creator.
- * Allocates and fills in a message with the signature CsrEventCsrUint16CsrUint16
- *
- *----------------------------------------------------------------------------*/
-CsrEventCsrUint16CsrUint16 *CsrEventCsrUint16CsrUint16_struct(u16 primtype, u16 msgtype, u16 value1, u16 value2);
-
-typedef struct
-{
- CsrPrim type;
- u16 value1;
- u32 value2;
-} CsrEventCsrUint16CsrUint32;
-
-/*----------------------------------------------------------------------------*
- * CsrEventCsrUint16_struct
- *
- * DESCRIPTION
- * Generic message creator.
- * Allocates and fills in a message with the signature CsrEventCsrUint16
- *
- *----------------------------------------------------------------------------*/
-CsrEventCsrUint16CsrUint32 *CsrEventCsrUint16CsrUint32_struct(u16 primtype, u16 msgtype, u16 value1, u32 value2);
-
-typedef struct
-{
- CsrPrim type;
- u16 value1;
- char *value2;
-} CsrEventCsrUint16CsrCharString;
-
-/*----------------------------------------------------------------------------*
- * CsrEventCsrUint16CsrCharString_struct
- *
- * DESCRIPTION
- * Generic message creator.
- * Allocates and fills in a message with the signature CsrEventCsrUint16CsrCharString
- *
- *----------------------------------------------------------------------------*/
-CsrEventCsrUint16CsrCharString *CsrEventCsrUint16CsrCharString_struct(u16 primtype, u16 msgtype, u16 value1, char *value2);
-
-typedef struct
-{
- CsrPrim type;
- u32 value;
-} CsrEventCsrUint32;
-
-/*----------------------------------------------------------------------------*
- * CsrEventCsrUint32_struct
- *
- * DESCRIPTION
- * Generic message creator.
- * Allocates and fills in a message with the signature CsrEventCsrUint32
- *
- *----------------------------------------------------------------------------*/
-CsrEventCsrUint32 *CsrEventCsrUint32_struct(u16 primtype, u16 msgtype, u32 value);
-
-typedef struct
-{
- CsrPrim type;
- u32 value1;
- u16 value2;
-} CsrEventCsrUint32CsrUint16;
-
-/*----------------------------------------------------------------------------*
- * CsrEventCsrUint32CsrUint16_struct
- *
- * DESCRIPTION
- * Generic message creator.
- * Allocates and fills in a message with the signature CsrEventCsrUint32CsrUint16
- *
- *----------------------------------------------------------------------------*/
-CsrEventCsrUint32CsrUint16 *CsrEventCsrUint32CsrUint16_struct(u16 primtype, u16 msgtype, u32 value1, u32 value2);
-
-typedef struct
-{
- CsrPrim type;
- u32 value1;
- char *value2;
-} CsrEventCsrUint32CsrCharString;
-
-/*----------------------------------------------------------------------------*
- * CsrEventCsrUint32CsrCharString_struct
- *
- * DESCRIPTION
- * Generic message creator.
- * Allocates and fills in a message with the signature CsrEventCsrUint32CsrCharString
- *
- *----------------------------------------------------------------------------*/
-CsrEventCsrUint32CsrCharString *CsrEventCsrUint32CsrCharString_struct(u16 primtype, u16 msgtype, u32 value1, char *value2);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* CSR_LIB_H__ */
diff --git a/drivers/staging/csr/csr_log.h b/drivers/staging/csr/csr_log.h
index b2808569f8d..5de5650767d 100644
--- a/drivers/staging/csr/csr_log.h
+++ b/drivers/staging/csr/csr_log.h
@@ -2,23 +2,18 @@
#define CSR_LOG_H__
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2010
- All rights reserved and confidential information of CSR
+ (c) Cambridge Silicon Radio Limited 2010
+ All rights reserved and confidential information of CSR
- Refer to LICENSE.txt included with this source for details
- on the license terms.
+ Refer to LICENSE.txt included with this source for details
+ on the license terms.
*****************************************************************************/
#include "csr_sched.h"
-#include "csr_panic.h"
#include "csr_prim_defs.h"
#include "csr_msgconv.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
* Log filtering
*/
@@ -77,34 +72,19 @@ u8 CsrLogTaskIsFiltered(CsrSchedQid taskId, CsrLogLevelTask level);
/*
* Logging stuff
*/
-#define CSR_LOG_STRINGIFY_REAL(a) #a
+#define CSR_LOG_STRINGIFY_REAL(a) (#a)
#define CSR_LOG_STRINGIFY(a) CSR_LOG_STRINGIFY_REAL(a)
-#ifdef CSR_LOG_ASSERT_ENABLE
-#define CSR_LOG_ASSERT(cond) \
- do { \
- if (!(cond)) \
- { \
- char *panic_arg = "[" __FILE__ ":" CSR_LOG_STRINGIFY(__LINE__) "] - " CSR_LOG_STRINGIFY(cond); \
- CsrPanic(CSR_TECH_FW, CSR_PANIC_FW_ASSERTION_FAIL, panic_arg); \
- } \
- } while (0)
-#else
-#define CSR_LOG_ASSERT(cond)
-#endif
-
-typedef struct
-{
- u16 primitiveType;
- const char *primitiveName;
- CsrMsgConvMsgEntry *messageConv; /* Private - do not use */
+typedef struct {
+ u16 primitiveType;
+ const char *primitiveName;
+ CsrMsgConvMsgEntry *messageConv; /* Private - do not use */
} CsrLogPrimitiveInformation;
-typedef struct
-{
- const char *techVer;
- u32 primitiveInfoCount;
- CsrLogPrimitiveInformation *primitiveInfo;
+typedef struct {
+ const char *techVer;
+ u32 primitiveInfoCount;
+ CsrLogPrimitiveInformation *primitiveInfo;
} CsrLogTechInformation;
/*---------------------------------*/
@@ -118,21 +98,19 @@ typedef u32 bitmask32_t;
#ifdef CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER
/* DEPRECATED - replaced by csr_log_text.h */
#define CSR_LOG_TEXT(text) \
- do { \
- if (!CsrLogTaskIsFiltered(CsrSchedTaskQueueGet(), CSR_LOG_LEVEL_TASK_TEXT)) \
- { \
- CsrLogTaskText(text, __LINE__, __FILE__); \
- } \
- } while (0)
+ do { \
+ if (!CsrLogTaskIsFiltered(CsrSchedTaskQueueGet(), CSR_LOG_LEVEL_TASK_TEXT)) { \
+ CsrLogTaskText(text, __LINE__, __FILE__); \
+ } \
+ } while (0)
#else
/* DEPRECATED - replaced by csr_log_text.h */
#define CSR_LOG_TEXT(text) \
- do { \
- if (!CsrLogTaskIsFiltered(CsrSchedTaskQueueGet(), CSR_LOG_LEVEL_TASK_TEXT)) \
- { \
- CsrLogTaskText(text, 0, NULL); \
- } \
- } while (0)
+ do { \
+ if (!CsrLogTaskIsFiltered(CsrSchedTaskQueueGet(), CSR_LOG_LEVEL_TASK_TEXT)) { \
+ CsrLogTaskText(text, 0, NULL); \
+ } \
+ } while (0)
#endif
#else
#define CSR_LOG_TEXT(text)
@@ -140,8 +118,8 @@ typedef u32 bitmask32_t;
/* DEPRECATED - replaced by csr_log_text.h */
void CsrLogTaskText(const char *text,
- u32 line,
- const char *file);
+ u32 line,
+ const char *file);
#define CSR_LOG_STATE_TRANSITION_MASK_FSM_NAME (0x001)
#define CSR_LOG_STATE_TRANSITION_MASK_NEXT_STATE (0x002)
@@ -153,16 +131,16 @@ void CsrLogTaskText(const char *text,
/* DEPRECATED - replaced by csr_log_text.h */
void CsrLogStateTransition(bitmask16_t mask,
- u32 identifier,
- const char *fsm_name,
- u32 prev_state,
- const char *prev_state_str,
- u32 in_event,
- const char *in_event_str,
- u32 next_state,
- const char *next_state_str,
- u32 line,
- const char *file);
+ u32 identifier,
+ const char *fsm_name,
+ u32 prev_state,
+ const char *prev_state_str,
+ u32 in_event,
+ const char *in_event_str,
+ u32 next_state,
+ const char *next_state_str,
+ u32 line,
+ const char *file);
/*---------------------------------*/
/* BSP logging */
@@ -183,67 +161,63 @@ void CsrLogDeactivate(CsrSchedQid tskid);
#define SYNERGY_SERIALIZER_TYPE_SER (0x001)
void CsrLogMessagePut(u32 line,
- const char *file,
- CsrSchedQid src_task_id,
- CsrSchedQid dst_taskid,
- CsrSchedMsgId msg_id,
- u16 prim_type,
- const void *msg);
+ const char *file,
+ CsrSchedQid src_task_id,
+ CsrSchedQid dst_taskid,
+ CsrSchedMsgId msg_id,
+ u16 prim_type,
+ const void *msg);
void CsrLogMessageGet(CsrSchedQid src_task_id,
- CsrSchedQid dst_taskid,
- u8 get_res,
- CsrSchedMsgId msg_id,
- u16 prim_type,
- const void *msg);
+ CsrSchedQid dst_taskid,
+ u8 get_res,
+ CsrSchedMsgId msg_id,
+ u16 prim_type,
+ const void *msg);
void CsrLogTimedEventIn(u32 line,
- const char *file,
- CsrSchedQid task_id,
- CsrSchedTid tid,
- CsrTime requested_delay,
- u16 fniarg,
- const void *fnvarg);
+ const char *file,
+ CsrSchedQid task_id,
+ CsrSchedTid tid,
+ u32 requested_delay,
+ u16 fniarg,
+ const void *fnvarg);
void CsrLogTimedEventFire(CsrSchedQid task_id,
- CsrSchedTid tid);
+ CsrSchedTid tid);
void CsrLogTimedEventDone(CsrSchedQid task_id,
- CsrSchedTid tid);
+ CsrSchedTid tid);
void CsrLogTimedEventCancel(u32 line,
- const char *file,
- CsrSchedQid task_id,
- CsrSchedTid tid,
- u8 cancel_res);
+ const char *file,
+ CsrSchedQid task_id,
+ CsrSchedTid tid,
+ u8 cancel_res);
void CsrLogBgintRegister(u8 thread_id,
- CsrSchedBgint irq,
- const char *callback,
- const void *ptr);
+ CsrSchedBgint irq,
+ const char *callback,
+ const void *ptr);
void CsrLogBgintUnregister(CsrSchedBgint irq);
void CsrLogBgintSet(CsrSchedBgint irq);
void CsrLogBgintServiceStart(CsrSchedBgint irq);
void CsrLogBgintServiceDone(CsrSchedBgint irq);
void CsrLogExceptionStateEvent(u16 prim_type,
- CsrPrim msg_type,
- u16 state,
- u32 line,
- const char *file);
+ CsrPrim msg_type,
+ u16 state,
+ u32 line,
+ const char *file);
void CsrLogExceptionGeneral(u16 prim_type,
- u16 state,
- const char *text,
- u32 line,
- const char *file);
+ u16 state,
+ const char *text,
+ u32 line,
+ const char *file);
void CsrLogExceptionWarning(u16 prim_type,
- u16 state,
- const char *text,
- u32 line,
- const char *file);
-
-#ifdef __cplusplus
-}
-#endif
+ u16 state,
+ const char *text,
+ u32 line,
+ const char *file);
#endif
diff --git a/drivers/staging/csr/csr_log_configure.h b/drivers/staging/csr/csr_log_configure.h
index 8842e4bf461..283647cf970 100644
--- a/drivers/staging/csr/csr_log_configure.h
+++ b/drivers/staging/csr/csr_log_configure.h
@@ -2,45 +2,16 @@
#define CSR_LOG_CONFIGURE_H__
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2010
- All rights reserved and confidential information of CSR
+ (c) Cambridge Silicon Radio Limited 2010
+ All rights reserved and confidential information of CSR
- Refer to LICENSE.txt included with this source for details
- on the license terms.
+ Refer to LICENSE.txt included with this source for details
+ on the license terms.
-*****************************************************************************/
+ *****************************************************************************/
#include "csr_log.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*---------------------------------*/
-/* Log init/deinit */
-/*---------------------------------*/
-void CsrLogInit(u8 size);
-void CsrLogDeinit(void);
-
-/*---------------------------------*/
-/* Log Framework Tech info */
-/*---------------------------------*/
-void CsrLogTechInfoRegister(void);
-
-/* Set the logging level for the environment outside the scheduler context */
-void CsrLogLevelEnvironmentSet(CsrLogLevelEnvironment environmentLogLevel);
-
-
-/* Set the logging level for all scheduler tasks */
-/* This function call takes precedence over all previous calls to CsrLogLevelTaskSetSpecific() */
-void CsrLogLevelTaskSetAll(CsrLogLevelTask tasksLogLevelMask);
-
-/* Set the logging level for a given Task */
-/* This function can be used as a complement to CsrLogLevelTaskSetAll() to add more _or_ less log from a given task than what is set
-generally with CsrLogLevelTaskSetAll(). */
-void CsrLogLevelTaskSetSpecific(CsrSchedQid taskId, CsrLogLevelTask taskLogLevelMask);
-
-
/*--------------------------------------------*/
/* Filtering on log text warning levels */
/*--------------------------------------------*/
@@ -65,70 +36,4 @@ typedef u32 CsrLogLevelText;
* taskId's in the range 0x0600xxxx to 0x06FFxxxx. And so on for other technologies. */
typedef u32 CsrLogTextTaskId;
-/* Set the text logging level for all Tasks */
-/* This function call takes precedence over all previous calls to CsrLogLevelTextSetTask() and CsrLogLevelTextSetTaskSubOrigin() */
-void CsrLogLevelTextSetAll(CsrLogLevelText warningLevelMask);
-
-/* Set the text logging level for a given Task */
-/* This function call takes precedence over all previous calls to CsrLogLevelTextSetTaskSubOrigin(), but it can be used as a complement to
- * CsrLogLevelTextSetAll() to add more _or_ less log from a given task than what is set generally with CsrLogLevelTextSetAll(). */
-void CsrLogLevelTextSetTask(CsrLogTextTaskId taskId, CsrLogLevelText warningLevelMask);
-
-/* Set the text logging level for a given tasks subOrigin */
-/* This function can be used as a complement to CsrLogLevelTextSetAll() and CsrLogLevelTextSetTask() to add more _or_ less log from a given
- * subOrigin within a task than what is set generally with CsrLogLevelTextSetAll() _or_ CsrLogLevelTextSetTask(). */
-void CsrLogLevelTextSetTaskSubOrigin(CsrLogTextTaskId taskId, u16 subOrigin, CsrLogLevelText warningLevelMask);
-
-/*******************************************************************************
-
- NAME
- CsrLogLevelTextSet
-
- DESCRIPTION
- Set the text logging level for a given origin and optionally sub origin
- by name. If either string is NULL or zero length, it is interpreted as
- all origins and/or all sub origins respectively. If originName is NULL
- or zero length, subOriginName is ignored.
-
- Passing NULL or zero length strings in both originName and subOriginName
- is equivalent to calling CsrLogLevelTextSetAll, and overrides all
- previous filter configurations for all origins and sub origins.
-
- Passing NULL or a zero length string in subOriginName overrides all
- previous filter configurations for all sub origins of the specified
- origin.
-
- Note: the supplied strings may be accessed after the function returns
- and must remain valid and constant until CsrLogDeinit is called.
-
- Note: when specifying an origin (originName is not NULL and not zero
- length), this function can only be used for origins that use the
- csr_log_text_2.h interface for registration and logging. Filtering for
- origins that use the legacy csr_log_text.h interface must be be
- configured using the legacy filter configuration functions that accept
- a CsrLogTextTaskId as origin specifier. However, when not specifying an
- origin this function also affects origins that have been registered with
- the legacy csr_log_text.h interface. Furthermore, using this function
- and the legacy filter configuration functions on the same origin is not
- allowed.
-
- PARAMETERS
- originName - a string containing the name of the origin. Can be NULL or
- zero length to set the log level for all origins. In this case, the
- subOriginName parameter will be ignored.
- subOriginName - a string containing the name of the sub origin. Can be
- NULL or zero length to set the log level for all sub origins of the
- specified origin.
- warningLevelMask - The desired log level for the specified origin(s) and
- sub origin(s).
-
-*******************************************************************************/
-void CsrLogLevelTextSet(const char *originName,
- const char *subOriginName,
- CsrLogLevelText warningLevelMask);
-
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/drivers/staging/csr/csr_log_text.h b/drivers/staging/csr/csr_log_text.h
index 9fe6c90244c..cfcf64aa622 100644
--- a/drivers/staging/csr/csr_log_text.h
+++ b/drivers/staging/csr/csr_log_text.h
@@ -12,10 +12,6 @@
#include "csr_log_configure.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct CsrLogSubOrigin
{
u16 subOriginNumber; /* Id of the given SubOrigin */
@@ -125,8 +121,4 @@ void CsrLogTextBufferDebug(CsrLogTextTaskId taskId, u16 subOrigin, size_t buffer
#define CSR_LOG_TEXT_UNHANDLED_PRIMITIVE(origin, suborigin, primClass, primType)
#endif
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/drivers/staging/csr/csr_macro.h b/drivers/staging/csr/csr_macro.h
index 57cbfcb0619..c47f1d91b6f 100644
--- a/drivers/staging/csr/csr_macro.h
+++ b/drivers/staging/csr/csr_macro.h
@@ -12,26 +12,10 @@
#include <linux/types.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#define FALSE (0)
#define TRUE (1)
/*------------------------------------------------------------------*/
-/* Bits - intended to operate on u32 values */
-/*------------------------------------------------------------------*/
-#define CSR_MASK_IS_SET(val, mask) (((val) & (mask)) == (mask))
-#define CSR_MASK_IS_UNSET(val, mask) ((((val) & (mask)) ^ mask) == (mask))
-#define CSR_MASK_SET(val, mask) ((val) |= (mask))
-#define CSR_MASK_UNSET(val, mask) ((val) = ((val) ^ (mask)) & (val)) /* Unsets the bits in val that are set in mask */
-#define CSR_BIT_IS_SET(val, bit) ((u8) ((((val) & (1UL << (bit))) != 0)))
-#define CSR_BIT_SET(val, bit) ((val) |= (1UL << (bit)))
-#define CSR_BIT_UNSET(val, bit) ((val) &= ~(1UL << (bit)))
-#define CSR_BIT_TOGGLE(val, bit) ((val) ^= (1UL << (bit)))
-
-/*------------------------------------------------------------------*/
/* Endian conversion */
/*------------------------------------------------------------------*/
#define CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr) (((u16) ((u8 *) (ptr))[0]) | ((u16) ((u8 *) (ptr))[1]) << 8)
@@ -43,72 +27,13 @@ extern "C" {
((u8 *) (ptr))[1] = ((u8) (((uint) >> 8) & 0x000000FF)); \
((u8 *) (ptr))[2] = ((u8) (((uint) >> 16) & 0x000000FF)); \
((u8 *) (ptr))[3] = ((u8) (((uint) >> 24) & 0x000000FF))
-#define CSR_GET_UINT16_FROM_BIG_ENDIAN(ptr) (((u16) ((u8 *) (ptr))[1]) | ((u16) ((u8 *) (ptr))[0]) << 8)
-#define CSR_GET_UINT24_FROM_BIG_ENDIAN(ptr) (((u32) ((u8 *) (ptr))[2]) | \
- ((u32) ((u8 *) (ptr))[1]) << 8 | ((u32) ((u8 *) (ptr))[0]) << 16)
-#define CSR_GET_UINT32_FROM_BIG_ENDIAN(ptr) (((u32) ((u8 *) (ptr))[3]) | ((u32) ((u8 *) (ptr))[2]) << 8 | \
- ((u32) ((u8 *) (ptr))[1]) << 16 | ((u32) ((u8 *) (ptr))[0]) << 24)
-#define CSR_COPY_UINT16_TO_BIG_ENDIAN(uint, ptr) ((u8 *) (ptr))[1] = ((u8) ((uint) & 0x00FF)); \
- ((u8 *) (ptr))[0] = ((u8) ((uint) >> 8))
-#define CSR_COPY_UINT24_TO_BIG_ENDIAN(uint, ptr) ((u8 *) (ptr))[2] = ((u8) ((uint) & 0x000000FF)); \
- ((u8 *) (ptr))[1] = ((u8) (((uint) >> 8) & 0x000000FF)); \
- ((u8 *) (ptr))[0] = ((u8) (((uint) >> 16) & 0x000000FF))
-#define CSR_COPY_UINT32_TO_BIG_ENDIAN(uint, ptr) ((u8 *) (ptr))[3] = ((u8) ((uint) & 0x000000FF)); \
- ((u8 *) (ptr))[2] = ((u8) (((uint) >> 8) & 0x000000FF)); \
- ((u8 *) (ptr))[1] = ((u8) (((uint) >> 16) & 0x000000FF)); \
- ((u8 *) (ptr))[0] = ((u8) (((uint) >> 24) & 0x000000FF))
-
-/*------------------------------------------------------------------*/
-/* XAP conversion macros */
-/*------------------------------------------------------------------*/
-
-#define CSR_LSB16(a) ((u8) ((a) & 0x00ff))
-#define CSR_MSB16(b) ((u8) ((b) >> 8))
-
-#define CSR_CONVERT_8_FROM_XAP(output, input) \
- (output) = ((u8) (input));(input) += 2
-
-#define CSR_CONVERT_16_FROM_XAP(output, input) \
- (output) = (u16) ((((u16) (input)[1]) << 8) | \
- ((u16) (input)[0]));(input) += 2
-
-#define CSR_CONVERT_32_FROM_XAP(output, input) \
- (output) = (((u32) (input)[1]) << 24) | \
- (((u32) (input)[0]) << 16) | \
- (((u32) (input)[3]) << 8) | \
- ((u32) (input)[2]);input += 4
-
-#define CSR_ADD_UINT8_TO_XAP(output, input) \
- (output)[0] = (input); \
- (output)[1] = 0;(output) += 2
-
-#define CSR_ADD_UINT16_TO_XAP(output, input) \
- (output)[0] = ((u8) ((input) & 0x00FF)); \
- (output)[1] = ((u8) ((input) >> 8));(output) += 2
-
-#define CSR_ADD_UINT32_TO_XAP(output, input) \
- (output)[0] = ((u8) (((input) >> 16) & 0x00FF)); \
- (output)[1] = ((u8) ((input) >> 24)); \
- (output)[2] = ((u8) ((input) & 0x00FF)); \
- (output)[3] = ((u8) (((input) >> 8) & 0x00FF));(output) += 4
/*------------------------------------------------------------------*/
/* Misc */
/*------------------------------------------------------------------*/
-#define CSRMAX(a, b) (((a) > (b)) ? (a) : (b))
-#define CSRMIN(a, b) (((a) < (b)) ? (a) : (b))
-
/* Use this macro on unused local variables that cannot be removed (such as
unused function parameters). This will quell warnings from certain compilers
and static code analysis tools like Lint and Valgrind. */
#define CSR_UNUSED(x) ((void) (x))
-#define CSR_TOUPPER(character) (((character) >= 'a') && ((character) <= 'z') ? ((character) - 0x20) : (character))
-#define CSR_TOLOWER(character) (((character) >= 'A') && ((character) <= 'Z') ? ((character) + 0x20) : (character))
-#define CSR_ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
-
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/drivers/staging/csr/csr_msg_transport.h b/drivers/staging/csr/csr_msg_transport.h
index b0095b02381..8d88e783656 100644
--- a/drivers/staging/csr/csr_msg_transport.h
+++ b/drivers/staging/csr/csr_msg_transport.h
@@ -10,16 +10,8 @@
*****************************************************************************/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef CsrMsgTransport
#define CsrMsgTransport CsrSchedMessagePut
#endif
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_MSG_TRANSPORT */
diff --git a/drivers/staging/csr/csr_msgconv.c b/drivers/staging/csr/csr_msgconv.c
index 0081a255e91..db5e845e60f 100644
--- a/drivers/staging/csr/csr_msgconv.c
+++ b/drivers/staging/csr/csr_msgconv.c
@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/slab.h>
-#include "csr_panic.h"
#include "csr_sched.h"
#include "csr_msgconv.h"
#include "csr_macro.h"
diff --git a/drivers/staging/csr/csr_msgconv.h b/drivers/staging/csr/csr_msgconv.h
index 09489f38e52..7e4dd388ae3 100644
--- a/drivers/staging/csr/csr_msgconv.h
+++ b/drivers/staging/csr/csr_msgconv.h
@@ -15,10 +15,6 @@
#include "csr_prim_defs.h"
#include "csr_sched.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef size_t (CsrMsgSizeofFunc)(void *msg);
typedef u8 *(CsrMsgSerializeFunc)(u8 *buffer, size_t *length, void *msg);
typedef void (CsrMsgFreeFunc)(void *msg);
@@ -79,9 +75,4 @@ void CsrUint32Des(u32 *value, u8 *buffer, size_t *offset);
void CsrMemCpyDes(void *value, u8 *buffer, size_t *offset, size_t length);
void CsrCharStringDes(char **value, u8 *buffer, size_t *offset);
-
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/drivers/staging/csr/csr_panic.c b/drivers/staging/csr/csr_panic.c
deleted file mode 100644
index 095f7fa3ae2..00000000000
--- a/drivers/staging/csr/csr_panic.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*****************************************************************************
-
- (c) Cambridge Silicon Radio Limited 2010
- All rights reserved and confidential information of CSR
-
- Refer to LICENSE.txt included with this source for details
- on the license terms.
-
-*****************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "csr_panic.h"
-
-void CsrPanic(u8 tech, u16 reason, const char *p)
-{
- BUG_ON(1);
-}
-EXPORT_SYMBOL_GPL(CsrPanic);
diff --git a/drivers/staging/csr/csr_panic.h b/drivers/staging/csr/csr_panic.h
deleted file mode 100644
index 37989fc15bb..00000000000
--- a/drivers/staging/csr/csr_panic.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef CSR_PANIC_H__
-#define CSR_PANIC_H__
-/*****************************************************************************
-
- (c) Cambridge Silicon Radio Limited 2010
- All rights reserved and confidential information of CSR
-
- Refer to LICENSE.txt included with this source for details
- on the license terms.
-
-*****************************************************************************/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Synergy techonology ID definitions */
-#define CSR_TECH_FW 0
-#define CSR_TECH_BT 1
-#define CSR_TECH_WIFI 2
-#define CSR_TECH_GPS 3
-#define CSR_TECH_NFC 4
-
-/* Panic type ID definitions for technology type CSR_TECH_FW */
-#define CSR_PANIC_FW_UNEXPECTED_VALUE 0
-#define CSR_PANIC_FW_HEAP_EXHAUSTION 1
-#define CSR_PANIC_FW_INVALID_PFREE_POINTER 2
-#define CSR_PANIC_FW_EXCEPTION 3
-#define CSR_PANIC_FW_ASSERTION_FAIL 4
-#define CSR_PANIC_FW_NULL_TASK_HANDLER 5
-#define CSR_PANIC_FW_UNKNOWN_TASK 6
-#define CSR_PANIC_FW_QUEUE_ACCESS_VIOLATION 7
-#define CSR_PANIC_FW_TOO_MANY_MESSAGES 8
-#define CSR_PANIC_FW_TOO_MANY_TIMED_EVENTS 9
-#define CSR_PANIC_FW_ABCSP_SYNC_LOST 10
-#define CSR_PANIC_FW_OVERSIZE_ABCSP_PRIM 11
-#define CSR_PANIC_FW_H4_CORRUPTION 12
-#define CSR_PANIC_FW_H4_SYNC_LOST 13
-#define CSR_PANIC_FW_H4_RX_OVERRUN 14
-#define CSR_PANIC_FW_H4_TX_OVERRUN 15
-#define CSR_PANIC_FW_TM_BC_RESTART_FAIL 16
-#define CSR_PANIC_FW_TM_BC_START_FAIL 17
-#define CSR_PANIC_FW_TM_BC_BAD_STATE 18
-#define CSR_PANIC_FW_TM_BC_TRANSPORT_LOST 19
-
-/* Panic interface used by technologies */
-/* DEPRECATED - replaced by csr_log_text.h */
-void CsrPanic(u8 tech, u16 reason, const char *p);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* CSR_PANIC_H__ */
diff --git a/drivers/staging/csr/csr_prim_defs.h b/drivers/staging/csr/csr_prim_defs.h
index 6a7f73dbb70..81a1eaac30d 100644
--- a/drivers/staging/csr/csr_prim_defs.h
+++ b/drivers/staging/csr/csr_prim_defs.h
@@ -9,9 +9,6 @@
on the license terms.
*****************************************************************************/
-#ifdef __cplusplus
-extern "C" {
-#endif
/************************************************************************************
* Segmentation of primitives in upstream and downstream segment
@@ -55,8 +52,4 @@ typedef u16 CsrPrim;
#define CSR_ENV_PRIM ((u16) (0x00FF | CSR_SYNERGY_EVENT_CLASS_MISC_BASE))
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_PRIM_DEFS_H__ */
diff --git a/drivers/staging/csr/csr_result.h b/drivers/staging/csr/csr_result.h
index c7c36d6b59e..cbb607d943c 100644
--- a/drivers/staging/csr/csr_result.h
+++ b/drivers/staging/csr/csr_result.h
@@ -10,16 +10,8 @@
*****************************************************************************/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef u16 CsrResult;
#define CSR_RESULT_SUCCESS ((CsrResult) 0x0000)
#define CSR_RESULT_FAILURE ((CsrResult) 0xFFFF)
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/drivers/staging/csr/csr_sched.h b/drivers/staging/csr/csr_sched.h
index cc1b8bf6607..c7d672c59f5 100644
--- a/drivers/staging/csr/csr_sched.h
+++ b/drivers/staging/csr/csr_sched.h
@@ -12,10 +12,6 @@
#include <linux/types.h>
#include "csr_time.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* An identifier issued by the scheduler. */
typedef u32 CsrSchedIdentifier;
@@ -24,7 +20,6 @@ typedef u16 CsrSchedTaskId;
/* A queue identifier */
typedef u16 CsrSchedQid;
-#define CSR_SCHED_QID_INVALID ((CsrSchedQid) 0xFFFF)
/* A message identifier */
typedef CsrSchedIdentifier CsrSchedMsgId;
@@ -33,14 +28,11 @@ typedef CsrSchedIdentifier CsrSchedMsgId;
typedef CsrSchedIdentifier CsrSchedTid;
#define CSR_SCHED_TID_INVALID ((CsrSchedTid) 0)
-/* Scheduler entry functions share this structure */
-typedef void (*schedEntryFunction_t)(void **inst);
-
/* Time constants. */
-#define CSR_SCHED_TIME_MAX ((CsrTime) 0xFFFFFFFF)
-#define CSR_SCHED_MILLISECOND ((CsrTime) (1000))
-#define CSR_SCHED_SECOND ((CsrTime) (1000 * CSR_SCHED_MILLISECOND))
-#define CSR_SCHED_MINUTE ((CsrTime) (60 * CSR_SCHED_SECOND))
+#define CSR_SCHED_TIME_MAX (0xFFFFFFFF)
+#define CSR_SCHED_MILLISECOND (1000)
+#define CSR_SCHED_SECOND (1000 * CSR_SCHED_MILLISECOND)
+#define CSR_SCHED_MINUTE (60 * CSR_SCHED_SECOND)
/* Queue and primitive that identifies the environment */
#define CSR_SCHED_TASK_ID 0xFFFF
@@ -53,60 +45,6 @@ typedef void (*schedEntryFunction_t)(void **inst);
typedef u16 CsrSchedBgint;
#define CSR_SCHED_BGINT_INVALID ((CsrSchedBgint) 0xFFFF)
-typedef void (*CsrSchedBgintHandler)(void *);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrSchedBgintReg
- *
- * DESCRIPTION
- * Register a background interrupt handler function with the scheduler.
- * When CsrSchedBgint() is called from the foreground (e.g. an interrupt
- * routine) the registered function is called.
- *
- * If "cb" is null then the interrupt is effectively disabled. If a
- * no bgints are available, CSR_SCHED_BGINT_INVALID is returned, otherwise
- * a CsrSchedBgint value is returned to be used in subsequent calls to
- * CsrSchedBgint(). id is a possibly NULL identifier used for logging
- * purposes only.
- *
- * RETURNS
- * CsrSchedBgint -- CSR_SCHED_BGINT_INVALID denotes failure to obtain a CsrSchedBgintSet.
- *
- *----------------------------------------------------------------------------*/
-CsrSchedBgint CsrSchedBgintReg(CsrSchedBgintHandler cb,
- void *context,
- const char *id);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrSchedBgintUnreg
- *
- * DESCRIPTION
- * Unregister a background interrupt handler function.
- *
- * ``irq'' is a background interrupt handle previously obtained
- * from a call to CsrSchedBgintReg().
- *
- * RETURNS
- * void.
- *
- *----------------------------------------------------------------------------*/
-void CsrSchedBgintUnreg(CsrSchedBgint bgint);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrSchedBgintSet
- *
- * DESCRIPTION
- * Set background interrupt.
- *
- * RETURNS
- * void.
- *
- *----------------------------------------------------------------------------*/
-void CsrSchedBgintSet(CsrSchedBgint bgint);
-
/*----------------------------------------------------------------------------*
* NAME
* CsrSchedMessagePut
@@ -144,149 +82,4 @@ void CsrSchedMessagePut(CsrSchedQid q,
void *mv);
#endif
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrSchedMessageBroadcast
- *
- * DESCRIPTION
- * Sends a message to all tasks.
- *
- * The user must supply a "factory function" that is called once
- * for every task that exists. The "factory function", msg_build_func,
- * must allocate and initialise the message and set the msg_build_ptr
- * to point to the message when done.
- *
- * NOTE
- * N/A
- *
- * RETURNS
- * void
- *
- *----------------------------------------------------------------------------*/
-#if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER)
-void CsrSchedMessageBroadcastStringLog(u16 mi,
- void *(*msg_build_func)(void *),
- void *msg_build_ptr,
- u32 line,
- const char *file);
-#define CsrSchedMessageBroadcast(mi, fn, ptr) CsrSchedMessageBroadcastStringLog((mi), (fn), (ptr), __LINE__, __FILE__)
-#else
-void CsrSchedMessageBroadcast(u16 mi,
- void *(*msg_build_func)(void *),
- void *msg_build_ptr);
-#endif
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrSchedMessageGet
- *
- * DESCRIPTION
- * Obtains a message from the message queue belonging to the calling task.
- * The message consists of one or both of a u16 and a void *.
- *
- * RETURNS
- * u8 - TRUE if a message has been obtained from the queue, else FALSE.
- * If a message is taken from the queue, then "*pmi" and "*pmv" are set to
- * the "mi" and "mv" passed to CsrSchedMessagePut() respectively.
- *
- * "pmi" and "pmv" can be null, in which case the corresponding value from
- * them message is discarded.
- *
- *----------------------------------------------------------------------------*/
-u8 CsrSchedMessageGet(u16 *pmi, void **pmv);
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrSchedTimerSet
- *
- * DESCRIPTION
- * Causes the void function "fn" to be called with the arguments
- * "fniarg" and "fnvarg" after "delay" has elapsed.
- *
- * "delay" must be less than half the range of a CsrTime.
- *
- * CsrSchedTimerSet() does nothing with "fniarg" and "fnvarg" except
- * deliver them via a call to "fn()". (Unless CsrSchedTimerCancel()
- * is used to prevent delivery.)
- *
- * NOTE
- * The function will be called at or after "delay"; the actual delay will
- * depend on the timing behaviour of the scheduler's tasks.
- *
- * RETURNS
- * CsrSchedTid - A timed event identifier, can be used in CsrSchedTimerCancel().
- *
- *----------------------------------------------------------------------------*/
-#if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER)
-CsrSchedTid CsrSchedTimerSetStringLog(CsrTime delay,
- void (*fn)(u16 mi, void *mv),
- u16 fniarg,
- void *fnvarg,
- u32 line,
- const char *file);
-#define CsrSchedTimerSet(d, fn, fni, fnv) CsrSchedTimerSetStringLog((d), (fn), (fni), (fnv), __LINE__, __FILE__)
-#else
-CsrSchedTid CsrSchedTimerSet(CsrTime delay,
- void (*fn)(u16 mi, void *mv),
- u16 fniarg,
- void *fnvarg);
-#endif
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrSchedTimerCancel
- *
- * DESCRIPTION
- * Attempts to prevent the timed event with identifier "eventid" from
- * occurring.
- *
- * RETURNS
- * u8 - TRUE if cancelled, FALSE if the event has already occurred.
- *
- *----------------------------------------------------------------------------*/
-#if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER)
-u8 CsrSchedTimerCancelStringLog(CsrSchedTid eventid,
- u16 *pmi,
- void **pmv,
- u32 line,
- const char *file);
-#define CsrSchedTimerCancel(e, pmi, pmv) CsrSchedTimerCancelStringLog((e), (pmi), (pmv), __LINE__, __FILE__)
-#else
-u8 CsrSchedTimerCancel(CsrSchedTid eventid,
- u16 *pmi,
- void **pmv);
-#endif
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrSchedTaskQueueGet
- *
- * DESCRIPTION
- * Return the queue identifier for the currently running queue
- *
- * RETURNS
- * CsrSchedQid - The current task queue identifier, or 0xFFFF if not available.
- *
- *----------------------------------------------------------------------------*/
-CsrSchedQid CsrSchedTaskQueueGet(void);
-
-
-/*----------------------------------------------------------------------------*
- * NAME
- * CsrSchedTaskQueueGet
- *
- * DESCRIPTION
- * Return the queue identifier for the currently running queue
- *
- * RETURNS
- * char - The current task queue identifier, or 0xFFFF if not available.
- *
- *----------------------------------------------------------------------------*/
-char* CsrSchedTaskNameGet(CsrSchedQid );
-
-
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/drivers/staging/csr/csr_sdio.h b/drivers/staging/csr/csr_sdio.h
index f0cda84f6a0..624a53fa1d7 100644
--- a/drivers/staging/csr/csr_sdio.h
+++ b/drivers/staging/csr/csr_sdio.h
@@ -12,10 +12,6 @@
#include "csr_result.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Result Codes */
#define CSR_SDIO_RESULT_INVALID_VALUE ((CsrResult) 1) /* Invalid argument value */
#define CSR_SDIO_RESULT_NO_DEVICE ((CsrResult) 2) /* The specified device is no longer present */
@@ -724,8 +720,4 @@ CsrResult CsrSdioHardReset(CsrSdioFunction *function);
void CsrSdioFunctionActive(CsrSdioFunction *function);
void CsrSdioFunctionIdle(CsrSdioFunction *function);
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/drivers/staging/csr/csr_serialize_primitive_types.c b/drivers/staging/csr/csr_serialize_primitive_types.c
index bf5e4ab9f95..9713b9afef6 100644
--- a/drivers/staging/csr/csr_serialize_primitive_types.c
+++ b/drivers/staging/csr/csr_serialize_primitive_types.c
@@ -13,7 +13,6 @@
#include "csr_prim_defs.h"
#include "csr_msgconv.h"
#include "csr_macro.h"
-#include "csr_lib.h"
void CsrUint8Des(u8 *value, u8 *buffer, size_t *offset)
{
diff --git a/drivers/staging/csr/csr_time.c b/drivers/staging/csr/csr_time.c
index 7b597f7622a..f3f4a9c9c67 100644
--- a/drivers/staging/csr/csr_time.c
+++ b/drivers/staging/csr/csr_time.c
@@ -9,25 +9,24 @@
*****************************************************************************/
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/time.h>
#include <linux/module.h>
#include "csr_time.h"
-CsrTime CsrTimeGet(CsrTime *high)
+u32 CsrTimeGet(u32 *high)
{
struct timespec ts;
u64 time;
- CsrTime low;
+ u32 low;
ts = current_kernel_time();
time = (u64) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
if (high != NULL)
- *high = (CsrTime) ((time >> 32) & 0xFFFFFFFF);
+ *high = (u32) ((time >> 32) & 0xFFFFFFFF);
- low = (CsrTime) (time & 0xFFFFFFFF);
+ low = (u32) (time & 0xFFFFFFFF);
return low;
}
diff --git a/drivers/staging/csr/csr_time.h b/drivers/staging/csr/csr_time.h
index 2a45f3e4024..fc29e8e5e47 100644
--- a/drivers/staging/csr/csr_time.h
+++ b/drivers/staging/csr/csr_time.h
@@ -2,77 +2,43 @@
#define CSR_TIME_H__
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2010
- All rights reserved and confidential information of CSR
+(c) Cambridge Silicon Radio Limited 2010
+All rights reserved and confidential information of CSR
- Refer to LICENSE.txt included with this source for details
- on the license terms.
+Refer to LICENSE.txt included with this source for details
+on the license terms.
*****************************************************************************/
#include <linux/types.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*******************************************************************************
-
- NAME
- CsrTime
-
- DESCRIPTION
- Type to hold a value describing the current system time, which is a
- measure of time elapsed since some arbitrarily defined fixed time
- reference, usually associated with system startup.
-
-*******************************************************************************/
-typedef u32 CsrTime;
-
-
/*******************************************************************************
- NAME
- CsrTimeUtc
+NAME
+ CsrTimeGet
- DESCRIPTION
- Type to hold a value describing a UTC wallclock time expressed in
- seconds and milliseconds elapsed since midnight January 1st 1970.
+DESCRIPTION
+ Returns the current system time in a low and a high part. The low part
+ is expressed in microseconds. The high part is incremented when the low
+ part wraps to provide an extended range.
-*******************************************************************************/
-typedef struct
-{
- u32 sec;
- u16 msec;
-} CsrTimeUtc;
-
-
-/*******************************************************************************
-
- NAME
- CsrTimeGet
+ The caller may provide a NULL pointer as the high parameter.
+ In this case the function just returns the low part and ignores the
+ high parameter.
- DESCRIPTION
- Returns the current system time in a low and a high part. The low part
- is expressed in microseconds. The high part is incremented when the low
- part wraps to provide an extended range.
+ Although the time is expressed in microseconds the actual resolution is
+ platform dependent and can be less. It is recommended that the
+ resolution is at least 10 milliseconds.
- The caller may provide a NULL pointer as the high parameter. In this case
- the function just returns the low part and ignores the high parameter.
+PARAMETERS
+ high - Pointer to variable that will receive the high part of the
+ current system time. Passing NULL is valid.
- Although the time is expressed in microseconds the actual resolution is
- platform dependent and can be less. It is recommended that the
- resolution is at least 10 milliseconds.
-
- PARAMETERS
- high - Pointer to variable that will receive the high part of the
- current system time. Passing NULL is valid.
-
- RETURNS
- Low part of current system time in microseconds.
+RETURNS
+ Low part of current system time in microseconds.
*******************************************************************************/
-CsrTime CsrTimeGet(CsrTime *high);
+u32 CsrTimeGet(u32 *high);
/*------------------------------------------------------------------*/
@@ -107,8 +73,4 @@ CsrTime CsrTimeGet(CsrTime *high);
*----------------------------------------------------------------------------*/
#define CsrTimeSub(t1, t2) ((s32) (t1) - (s32) (t2))
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/drivers/staging/csr/csr_wifi_common.h b/drivers/staging/csr/csr_wifi_common.h
index cc41a94b8f2..efc43a525a3 100644
--- a/drivers/staging/csr/csr_wifi_common.h
+++ b/drivers/staging/csr/csr_wifi_common.h
@@ -14,10 +14,6 @@
#include <linux/types.h>
#include "csr_result.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* MAC address */
typedef struct
{
@@ -101,9 +97,5 @@ typedef struct
#define CSR_WIFI_VERSION "5.1.0.0"
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/drivers/staging/csr/csr_wifi_fsm.h b/drivers/staging/csr/csr_wifi_fsm.h
index 073e2f8b553..fde1508c1ea 100644
--- a/drivers/staging/csr/csr_wifi_fsm.h
+++ b/drivers/staging/csr/csr_wifi_fsm.h
@@ -11,10 +11,6 @@
#ifndef CSR_WIFI_FSM_H
#define CSR_WIFI_FSM_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include "csr_prim_defs.h"
#include "csr_log_text.h"
#include "csr_wifi_fsm_event.h"
@@ -240,9 +236,5 @@ extern u8 CsrWifiFsmHasEvents(CsrWifiFsmContext *context);
*/
extern void CsrWifiFsmInstallWakeupCallback(CsrWifiFsmContext *context, CsrWifiFsmExternalWakupCallbackPtr callback);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_FSM_H */
diff --git a/drivers/staging/csr/csr_wifi_fsm_event.h b/drivers/staging/csr/csr_wifi_fsm_event.h
index 57a5cafd40b..0690ca955ef 100644
--- a/drivers/staging/csr/csr_wifi_fsm_event.h
+++ b/drivers/staging/csr/csr_wifi_fsm_event.h
@@ -11,10 +11,6 @@
#ifndef CSR_WIFI_FSM_EVENT_H
#define CSR_WIFI_FSM_EVENT_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include "csr_prim_defs.h"
#include "csr_sched.h"
@@ -42,9 +38,5 @@ typedef struct CsrWifiFsmEvent
struct CsrWifiFsmEvent *next;
} CsrWifiFsmEvent;
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_FSM_EVENT_H */
diff --git a/drivers/staging/csr/csr_wifi_fsm_types.h b/drivers/staging/csr/csr_wifi_fsm_types.h
index 26752bf316e..d21c60a81fc 100644
--- a/drivers/staging/csr/csr_wifi_fsm_types.h
+++ b/drivers/staging/csr/csr_wifi_fsm_types.h
@@ -11,13 +11,8 @@
#ifndef CSR_WIFI_FSM_TYPES_H
#define CSR_WIFI_FSM_TYPES_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include <linux/types.h>
#include "csr_macro.h"
-#include "csr_panic.h"
#include "csr_sched.h"
#ifdef CSR_WIFI_FSM_MUTEX_ENABLE
@@ -432,9 +427,4 @@ struct CsrWifiFsmContext
#endif
};
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_FSM_TYPES_H */
diff --git a/drivers/staging/csr/csr_wifi_hip_card.h b/drivers/staging/csr/csr_wifi_hip_card.h
index 9caf88c7887..bd47f606e0d 100644
--- a/drivers/staging/csr/csr_wifi_hip_card.h
+++ b/drivers/staging/csr/csr_wifi_hip_card.h
@@ -21,10 +21,6 @@
#ifndef __CARD_H__
#define __CARD_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include "csr_wifi_hip_card_sdio.h"
#include "csr_wifi_hip_signals.h"
#include "csr_wifi_hip_unifi_udi.h"
@@ -115,9 +111,4 @@ void unifi_debug_string_to_buf(const char *str);
void unifi_debug_hex_to_buf(const char *buff, u16 length);
#endif
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __CARD_H__ */
diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio.c b/drivers/staging/csr/csr_wifi_hip_card_sdio.c
index cf148a0fec6..25cabf3234c 100644
--- a/drivers/staging/csr/csr_wifi_hip_card_sdio.c
+++ b/drivers/staging/csr/csr_wifi_hip_card_sdio.c
@@ -70,8 +70,6 @@ card_t* unifi_alloc_card(CsrSdioFunction *sdio, void *ospriv)
card_t *card;
u32 i;
- func_enter();
-
card = kzalloc(sizeof(card_t), GFP_KERNEL);
if (card == NULL)
@@ -148,7 +146,6 @@ card_t* unifi_alloc_card(CsrSdioFunction *sdio, void *ospriv)
}
}
#endif
- func_exit();
return card;
} /* unifi_alloc_card() */
@@ -171,35 +168,29 @@ CsrResult unifi_init_card(card_t *card, s32 led_mask)
{
CsrResult r;
- func_enter();
if (card == NULL)
{
- func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE);
return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
}
r = unifi_init(card);
if (r != CSR_RESULT_SUCCESS)
{
- func_exit_r(r);
return r;
}
r = unifi_hip_init(card);
if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
{
- func_exit_r(r);
return r;
}
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to start host protocol.\n");
- func_exit_r(r);
return r;
}
- func_exit();
return CSR_RESULT_SUCCESS;
}
@@ -223,11 +214,8 @@ CsrResult unifi_init(card_t *card)
CsrResult r;
CsrResult csrResult;
- func_enter();
-
if (card == NULL)
{
- func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE);
return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
}
@@ -250,7 +238,6 @@ CsrResult unifi_init(card_t *card)
if (csrResult != CSR_RESULT_SUCCESS)
{
r = ConvertCsrSdioToCsrHipResult(card, csrResult);
- func_exit_r(r);
return r;
}
card->sdio_clock_speed = UNIFI_SDIO_CLOCK_SAFE_HZ;
@@ -268,7 +255,6 @@ CsrResult unifi_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to reset UniFi\n");
- func_exit_r(r);
return r;
}
@@ -278,7 +264,6 @@ CsrResult unifi_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to set power save mode\n");
- func_exit_r(r);
return r;
}
@@ -298,7 +283,6 @@ CsrResult unifi_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to write SHARED_DMEM_PAGE\n");
- func_exit_r(r);
return r;
}
r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW2_PAGE(card->helper) * 2, 0);
@@ -309,7 +293,6 @@ CsrResult unifi_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to write PROG_MEM2_PAGE\n");
- func_exit_r(r);
return r;
}
@@ -338,7 +321,6 @@ CsrResult unifi_init(card_t *card)
unifi_error(card->ospriv, "Probe for Flash failed\n");
}
- func_exit_r(r);
return r;
} /* unifi_init() */
@@ -363,11 +345,8 @@ CsrResult unifi_download(card_t *card, s32 led_mask)
CsrResult r;
void *dlpriv;
- func_enter();
-
if (card == NULL)
{
- func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE);
return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
}
@@ -380,7 +359,6 @@ CsrResult unifi_download(card_t *card, s32 led_mask)
dlpriv = unifi_dl_fw_read_start(card, UNIFI_FW_STA);
if (dlpriv == NULL)
{
- func_exit_r(CSR_WIFI_HIP_RESULT_NOT_FOUND);
return CSR_WIFI_HIP_RESULT_NOT_FOUND;
}
@@ -389,15 +367,12 @@ CsrResult unifi_download(card_t *card, s32 led_mask)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to download firmware\n");
- func_exit_r(r);
return r;
}
/* Free the firmware file information. */
unifi_fw_read_stop(card->ospriv, dlpriv);
- func_exit();
-
return CSR_RESULT_SUCCESS;
} /* unifi_download() */
@@ -425,8 +400,6 @@ static CsrResult unifi_hip_init(card_t *card)
CsrResult r;
CsrResult csrResult;
- func_enter();
-
r = card_hw_init(card);
if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
{
@@ -435,7 +408,6 @@ static CsrResult unifi_hip_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to establish communication with UniFi\n");
- func_exit_r(r);
return r;
}
#ifdef CSR_PRE_ALLOC_NET_DATA
@@ -455,7 +427,6 @@ static CsrResult unifi_hip_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Init slots failed: %d\n", r);
- func_exit_r(r);
return r;
}
@@ -464,7 +435,6 @@ static CsrResult unifi_hip_init(card_t *card)
r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
if (r != CSR_RESULT_SUCCESS)
{
- func_exit_r(r);
return r;
}
@@ -479,12 +449,9 @@ static CsrResult unifi_hip_init(card_t *card)
r = CardGenInt(card);
if (r != CSR_RESULT_SUCCESS)
{
- func_exit_r(r);
return r;
}
- func_exit();
-
return CSR_RESULT_SUCCESS;
} /* unifi_hip_init() */
@@ -609,8 +576,6 @@ static CsrResult card_hw_init(card_t *card)
s16 search_4slut_again;
CsrResult csrResult;
- func_enter();
-
/*
* The device revision from the TPLMID_MANF and TPLMID_CARD fields
* of the CIS are available as
@@ -635,7 +600,6 @@ static CsrResult card_hw_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Firmware hasn't started\n");
- func_exit_r(r);
return r;
}
unifi_trace(card->ospriv, UDBG4, "SLUT addr 0x%lX\n", slut_address);
@@ -652,7 +616,6 @@ static CsrResult card_hw_init(card_t *card)
if (csrResult != CSR_RESULT_SUCCESS)
{
r = ConvertCsrSdioToCsrHipResult(card, csrResult);
- func_exit_r(r);
return r;
}
card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ;
@@ -671,14 +634,12 @@ static CsrResult card_hw_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to read SLUT finger print\n");
- func_exit_r(r);
return r;
}
if (finger_print != SLUT_FINGERPRINT)
{
unifi_error(card->ospriv, "Failed to find Symbol lookup table fingerprint\n");
- func_exit_r(CSR_RESULT_FAILURE);
return CSR_RESULT_FAILURE;
}
@@ -696,7 +657,6 @@ static CsrResult card_hw_init(card_t *card)
r = unifi_card_read16(card, slut_address, &s);
if (r != CSR_RESULT_SUCCESS)
{
- func_exit_r(r);
return r;
}
slut_address += 2;
@@ -710,7 +670,6 @@ static CsrResult card_hw_init(card_t *card)
r = unifi_read32(card, slut_address, &l);
if (r != CSR_RESULT_SUCCESS)
{
- func_exit_r(r);
return r;
}
slut_address += 4;
@@ -739,7 +698,6 @@ static CsrResult card_hw_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to read config data\n");
- func_exit_r(r);
return r;
}
/* .. and then we copy the data to the host structure */
@@ -753,7 +711,6 @@ static CsrResult card_hw_init(card_t *card)
{
unifi_error(card->ospriv, "From host data slots %d\n", cfg_data->num_fromhost_data_slots);
unifi_error(card->ospriv, "need to be (queues * x + 2) (UNIFI_RESERVED_COMMAND_SLOTS for commands)\n");
- func_exit_r(CSR_RESULT_FAILURE);
return CSR_RESULT_FAILURE;
}
@@ -781,7 +738,6 @@ static CsrResult card_hw_init(card_t *card)
if ((card->sdio_io_block_size % cfg_data->sig_frag_size) != 0)
{
unifi_error(card->ospriv, "Configuration error: Can not pad to-host signals.\n");
- func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE);
return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
}
cfg_data->tohost_signal_padding = (u16) (card->sdio_io_block_size / cfg_data->sig_frag_size);
@@ -795,7 +751,6 @@ static CsrResult card_hw_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to write To-Host Signal Padding Fragments\n");
- func_exit_r(r);
return r;
}
}
@@ -818,7 +773,6 @@ static CsrResult card_hw_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to read build id\n");
- func_exit_r(r);
return r;
}
card->build_id = n;
@@ -835,7 +789,6 @@ static CsrResult card_hw_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to read build string\n");
- func_exit_r(r);
return r;
}
break;
@@ -853,7 +806,6 @@ static CsrResult card_hw_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to write loader load image command\n");
- func_exit_r(r);
return r;
}
@@ -871,7 +823,6 @@ static CsrResult card_hw_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to patch firmware\n");
- func_exit_r(r);
return r;
}
}
@@ -882,7 +833,6 @@ static CsrResult card_hw_init(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to write loader restart command\n");
- func_exit_r(r);
return r;
}
@@ -913,7 +863,6 @@ static CsrResult card_hw_init(card_t *card)
if (cfg_data == NULL)
{
unifi_error(card->ospriv, "Failed to find SDIO_SLOT_CONFIG Symbol\n");
- func_exit_r(CSR_RESULT_FAILURE);
return CSR_RESULT_FAILURE;
}
@@ -930,12 +879,10 @@ static CsrResult card_hw_init(card_t *card)
{
unifi_error(card->ospriv, "Failed to read init flag at %08lx\n",
card->init_flag_addr);
- func_exit_r(r);
return r;
}
if (initialised != 0)
{
- func_exit_r(CSR_RESULT_FAILURE);
return CSR_RESULT_FAILURE;
}
@@ -957,7 +904,6 @@ static CsrResult card_hw_init(card_t *card)
unifi_error(card->ospriv, "UniFi f/w protocol major version (%d) is different from driver (v%d.%d)\n",
major, UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION);
#ifndef CSR_WIFI_DISABLE_HIP_VERSION_CHECK
- func_exit_r(CSR_RESULT_FAILURE);
return CSR_RESULT_FAILURE;
#endif
}
@@ -967,7 +913,6 @@ static CsrResult card_hw_init(card_t *card)
major, minor,
UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION);
#ifndef CSR_WIFI_DISABLE_HIP_VERSION_CHECK
- func_exit_r(CSR_RESULT_FAILURE);
return CSR_RESULT_FAILURE;
#endif
}
@@ -978,7 +923,6 @@ static CsrResult card_hw_init(card_t *card)
*/
unifi_read_panic(card);
- func_exit();
return CSR_RESULT_SUCCESS;
} /* card_hw_init() */
@@ -1004,8 +948,6 @@ static CsrResult card_wait_for_unifi_to_reset(card_t *card)
u8 io_enable;
CsrResult csrResult;
- func_enter();
-
r = CSR_RESULT_SUCCESS;
for (i = 0; i < MAILBOX2_ATTEMPTS; i++)
{
@@ -1107,7 +1049,6 @@ static CsrResult card_wait_for_unifi_to_reset(card_t *card)
r = CSR_RESULT_FAILURE;
}
- func_exit();
return r;
} /* card_wait_for_unifi_to_reset() */
@@ -1136,14 +1077,11 @@ static CsrResult card_wait_for_unifi_to_disable(card_t *card)
u8 io_enable;
CsrResult csrResult;
- func_enter();
-
if (card->chip_id <= SDIO_CARD_ID_UNIFI_2)
{
unifi_error(card->ospriv,
"Function reset method not supported for chip_id=%d\n",
card->chip_id);
- func_exit();
return CSR_RESULT_FAILURE;
}
@@ -1210,7 +1148,6 @@ static CsrResult card_wait_for_unifi_to_disable(card_t *card)
r = CSR_RESULT_FAILURE;
}
- func_exit();
return r;
} /* card_wait_for_unifi_to_reset() */
@@ -1238,8 +1175,6 @@ CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr)
u16 mbox0, mbox1;
CsrResult r;
- func_enter();
-
/*
* Wait for UniFi to initialise its data structures by polling
* the SHARED_MAILBOX1 register.
@@ -1277,7 +1212,6 @@ CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to read UniFi Mailbox1 register for second time\n");
- func_exit_r(r);
return r;
}
unifi_trace(card->ospriv, UDBG1, "MAILBOX1 value=0x%04X\n", mbox1);
@@ -1296,7 +1230,6 @@ CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr)
{
unifi_trace(card->ospriv, UDBG1, "Timeout waiting for firmware to start, Mailbox1 still 0 after %d ms\n",
MAILBOX1_ATTEMPTS * MAILBOX1_TIMEOUT);
- func_exit_r(CSR_RESULT_FAILURE);
return CSR_RESULT_FAILURE;
}
@@ -1312,7 +1245,6 @@ CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to write f/w startup handshake to MAILBOX2\n");
- func_exit_r(r);
return r;
}
@@ -1330,13 +1262,11 @@ CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to read UniFi Mailbox0 register\n");
- func_exit_r(r);
return r;
}
*paddr = (((u32)mbox1 << 16) | mbox0);
- func_exit();
return CSR_RESULT_SUCCESS;
} /* card_wait_for_firmware_to_start() */
@@ -1358,14 +1288,12 @@ CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr)
*/
CsrResult unifi_capture_panic(card_t *card)
{
- func_enter();
/* The firmware must have previously initialised to read the panic addresses
* from the SLUT
*/
if (!card->panic_data_phy_addr || !card->panic_data_mac_addr)
{
- func_exit();
return CSR_RESULT_SUCCESS;
}
@@ -1380,7 +1308,6 @@ CsrResult unifi_capture_panic(card_t *card)
unifi_info(card->ospriv, "Unable to read panic codes");
}
- func_exit();
return CSR_RESULT_SUCCESS;
}
@@ -1405,8 +1332,6 @@ static CsrResult card_access_panic(card_t *card)
s32 i;
CsrResult r, sr;
- func_enter();
-
/* A chip version of zero means that the version never got succesfully read
* during reset. In this case give up because it will not be possible to
* verify the chip version.
@@ -1513,7 +1438,6 @@ static CsrResult card_access_panic(card_t *card)
}
r = ConvertCsrSdioToCsrHipResult(card, sr);
- func_exit_r(r);
return r;
}
@@ -1536,8 +1460,6 @@ void unifi_read_panic(card_t *card)
CsrResult r;
u16 p_code, p_arg;
- func_enter();
-
/* The firmware must have previously initialised to read the panic addresses
* from the SLUT
*/
@@ -1584,7 +1506,6 @@ void unifi_read_panic(card_t *card)
card->last_mac_panic_arg = p_arg;
}
- func_exit();
}
@@ -1607,8 +1528,6 @@ static CsrResult card_allocate_memory_resources(card_t *card)
s16 n, i, k, r;
sdio_config_data_t *cfg_data;
- func_enter();
-
/* Reset any state carried forward from a previous life */
card->fh_command_queue.q_rd_ptr = 0;
card->fh_command_queue.q_wr_ptr = 0;
@@ -1634,7 +1553,6 @@ static CsrResult card_allocate_memory_resources(card_t *card)
if (card->fh_buffer.buf == NULL)
{
unifi_error(card->ospriv, "Failed to allocate memory for F-H signals\n");
- func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY);
return CSR_WIFI_HIP_RESULT_NO_MEMORY;
}
card->fh_buffer.bufsize = UNIFI_FH_BUF_SIZE;
@@ -1645,7 +1563,6 @@ static CsrResult card_allocate_memory_resources(card_t *card)
if (card->th_buffer.buf == NULL)
{
unifi_error(card->ospriv, "Failed to allocate memory for T-H signals\n");
- func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY);
return CSR_WIFI_HIP_RESULT_NO_MEMORY;
}
card->th_buffer.bufsize = UNIFI_FH_BUF_SIZE;
@@ -1667,7 +1584,6 @@ static CsrResult card_allocate_memory_resources(card_t *card)
if (card->from_host_data == NULL)
{
unifi_error(card->ospriv, "Failed to allocate memory for F-H bulk data array\n");
- func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY);
return CSR_WIFI_HIP_RESULT_NO_MEMORY;
}
@@ -1683,7 +1599,6 @@ static CsrResult card_allocate_memory_resources(card_t *card)
if (card->fh_slot_host_tag_record == NULL)
{
unifi_error(card->ospriv, "Failed to allocate memory for F-H slot host tag mapping array\n");
- func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY);
return CSR_WIFI_HIP_RESULT_NO_MEMORY;
}
@@ -1702,7 +1617,6 @@ static CsrResult card_allocate_memory_resources(card_t *card)
if (card->to_host_data == NULL)
{
unifi_error(card->ospriv, "Failed to allocate memory for T-H bulk data array\n");
- func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY);
return CSR_WIFI_HIP_RESULT_NO_MEMORY;
}
@@ -1736,7 +1650,6 @@ static CsrResult card_allocate_memory_resources(card_t *card)
card->memory_resources_allocated = 1;
- func_exit();
return CSR_RESULT_SUCCESS;
} /* card_allocate_memory_resources() */
@@ -1781,7 +1694,6 @@ static void unifi_free_bulk_data(card_t *card, bulk_data_desc_t *bulk_data_slot)
*/
static void card_free_memory_resources(card_t *card)
{
- func_enter();
unifi_trace(card->ospriv, UDBG1, "Freeing card memory resources.\n");
@@ -1812,7 +1724,6 @@ static void card_free_memory_resources(card_t *card)
card->memory_resources_allocated = 0;
- func_exit();
} /* card_free_memory_resources() */
@@ -1820,8 +1731,6 @@ static void card_init_soft_queues(card_t *card)
{
s16 i;
- func_enter();
-
unifi_trace(card->ospriv, UDBG1, "Initialising internal signal queues.\n");
/* Reset any state carried forward from a previous life */
card->fh_command_queue.q_rd_ptr = 0;
@@ -1838,7 +1747,6 @@ static void card_init_soft_queues(card_t *card)
#ifndef CSR_WIFI_HIP_TA_DISABLE
unifi_ta_sampling_init(card);
#endif
- func_exit();
}
@@ -1858,7 +1766,6 @@ static void card_init_soft_queues(card_t *card)
void unifi_cancel_pending_signals(card_t *card)
{
s16 i, n, r;
- func_enter();
unifi_trace(card->ospriv, UDBG1, "Canceling pending signals.\n");
@@ -1927,7 +1834,6 @@ void unifi_cancel_pending_signals(card_t *card)
card_init_soft_queues(card);
- func_exit();
} /* unifi_cancel_pending_signals() */
@@ -1951,7 +1857,6 @@ void unifi_cancel_pending_signals(card_t *card)
*/
void unifi_free_card(card_t *card)
{
- func_enter();
#ifdef CSR_PRE_ALLOC_NET_DATA
prealloc_netdata_free(card);
#endif
@@ -1967,7 +1872,6 @@ void unifi_free_card(card_t *card)
kfree(card);
- func_exit();
} /* unifi_free_card() */
@@ -1989,8 +1893,6 @@ static CsrResult card_init_slots(card_t *card)
CsrResult r;
u8 i;
- func_enter();
-
/* Allocate the buffers we need, only once. */
if (card->memory_resources_allocated == 1)
{
@@ -2007,14 +1909,12 @@ static CsrResult card_init_slots(card_t *card)
{
unifi_error(card->ospriv, "Failed to allocate card memory resources.\n");
card_free_memory_resources(card);
- func_exit_r(r);
return r;
}
if (card->sdio_ctrl_addr == 0)
{
unifi_error(card->ospriv, "Failed to find config struct!\n");
- func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE);
return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
}
@@ -2037,7 +1937,6 @@ static CsrResult card_init_slots(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to read from-host sig written count\n");
- func_exit_r(r);
return r;
}
card->from_host_signals_w = (s16)s;
@@ -2051,7 +1950,6 @@ static CsrResult card_init_slots(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to read to-host sig read count\n");
- func_exit_r(r);
return r;
}
card->to_host_signals_r = (s16)s;
@@ -2066,7 +1964,6 @@ static CsrResult card_init_slots(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to write initialised flag\n");
- func_exit_r(r);
return r;
}
@@ -2082,7 +1979,6 @@ static CsrResult card_init_slots(card_t *card)
card->dynamic_slot_data.packets_interval = UNIFI_PACKETS_INTERVAL;
- func_exit();
return CSR_RESULT_SUCCESS;
} /* card_init_slots() */
@@ -2153,8 +2049,6 @@ static void CardReassignDynamicReservation(card_t *card)
{
u8 i;
- func_enter();
-
unifi_trace(card->ospriv, UDBG5, "Packets Txed %d %d %d %d\n",
card->dynamic_slot_data.packets_txed[0],
card->dynamic_slot_data.packets_txed[1],
@@ -2176,7 +2070,6 @@ static void CardReassignDynamicReservation(card_t *card)
}
card->dynamic_slot_data.total_packets_txed = 0;
- func_exit();
}
@@ -2206,8 +2099,6 @@ static void CardCheckDynamicReservation(card_t *card, unifi_TrafficQueue queue)
q_t *sigq;
u16 num_data_slots = card->config_data.num_fromhost_data_slots - UNIFI_RESERVED_COMMAND_SLOTS;
- func_enter();
-
/* Calculate the pending queue length */
sigq = &card->fh_traffic_queue[queue];
q_len = CSR_WIFI_HIP_Q_SLOTS_USED(sigq);
@@ -2215,7 +2106,6 @@ static void CardCheckDynamicReservation(card_t *card, unifi_TrafficQueue queue)
if (q_len <= card->dynamic_slot_data.from_host_reserved_slots[queue])
{
unifi_trace(card->ospriv, UDBG5, "queue %d q_len %d already has that many reserved slots, exiting\n", queue, q_len);
- func_exit();
return;
}
@@ -2313,7 +2203,6 @@ static void CardCheckDynamicReservation(card_t *card, unifi_TrafficQueue queue)
card->dynamic_slot_data.from_host_max_slots[i]);
}
- func_exit();
}
@@ -2336,14 +2225,11 @@ void CardClearFromHostDataSlot(card_t *card, const s16 slot)
u8 queue = card->from_host_data[slot].queue;
const void *os_data_ptr = card->from_host_data[slot].bd.os_data_ptr;
- func_enter();
-
if (card->from_host_data[slot].bd.data_length == 0)
{
unifi_warning(card->ospriv,
"Surprise: request to clear an already free FH data slot: %d\n",
slot);
- func_exit();
return;
}
@@ -2379,7 +2265,6 @@ void CardClearFromHostDataSlot(card_t *card, const s16 slot)
unifi_trace(card->ospriv, UDBG4, "CardClearFromHostDataSlot: slot %d recycled %p\n", slot, os_data_ptr);
- func_exit();
} /* CardClearFromHostDataSlot() */
@@ -2457,8 +2342,6 @@ u16 CardGetFreeFromHostDataSlots(card_t *card)
{
u16 i, n = 0;
- func_enter();
-
/* First two slots reserved for MLME */
for (i = 0; i < card->config_data.num_fromhost_data_slots; i++)
{
@@ -2469,7 +2352,6 @@ u16 CardGetFreeFromHostDataSlots(card_t *card)
}
}
- func_exit();
return n;
} /* CardGetFreeFromHostDataSlots() */
@@ -2506,7 +2388,6 @@ u16 CardAreAllFromHostDataSlotsEmpty(card_t *card)
static CsrResult unifi_identify_hw(card_t *card)
{
- func_enter();
card->chip_id = card->sdio_if->sdioId.cardId;
card->function = card->sdio_if->sdioId.sdioFunction;
@@ -2530,7 +2411,6 @@ static CsrResult unifi_identify_hw(card_t *card)
ChipHelper_MarketingName(card->helper),
ChipHelper_FriendlyName(card->helper));
- func_exit();
return CSR_RESULT_SUCCESS;
} /* unifi_identify_hw() */
@@ -2541,8 +2421,6 @@ static CsrResult unifi_prepare_hw(card_t *card)
CsrResult csrResult;
enum unifi_host_state old_state = card->host_state;
- func_enter();
-
r = unifi_identify_hw(card);
if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
{
@@ -2551,7 +2429,6 @@ static CsrResult unifi_prepare_hw(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to identify hw\n");
- func_exit_r(r);
return r;
}
@@ -2576,7 +2453,6 @@ static CsrResult unifi_prepare_hw(card_t *card)
if (csrResult != CSR_RESULT_SUCCESS)
{
r = ConvertCsrSdioToCsrHipResult(card, csrResult);
- func_exit_r(r);
return r;
}
card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ;
@@ -2596,7 +2472,6 @@ static CsrResult unifi_prepare_hw(card_t *card)
r = ConvertCsrSdioToCsrHipResult(card, csrResult);
/* Can't enable WLAN function. Try resetting the SDIO block. */
unifi_error(card->ospriv, "Failed to re-enable function %d.\n", card->function);
- func_exit_r(r);
return r;
}
@@ -2610,11 +2485,9 @@ static CsrResult unifi_prepare_hw(card_t *card)
r = unifi_read_chip_version(card);
if (r != CSR_RESULT_SUCCESS)
{
- func_exit_r(r);
return r;
}
- func_exit();
return CSR_RESULT_SUCCESS;
} /* unifi_prepare_hw() */
@@ -2625,8 +2498,6 @@ static CsrResult unifi_read_chip_version(card_t *card)
CsrResult r;
u16 ver;
- func_enter();
-
gbl_chip_version = ChipHelper_GBL_CHIP_VERSION(card->helper);
/* Try to read the chip version from register. */
@@ -2640,7 +2511,6 @@ static CsrResult unifi_read_chip_version(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to read GBL_CHIP_VERSION\n");
- func_exit_r(r);
return r;
}
card->chip_version = ver;
@@ -2653,7 +2523,6 @@ static CsrResult unifi_read_chip_version(card_t *card)
unifi_info(card->ospriv, "Chip Version 0x%04X\n", card->chip_version);
- func_exit_r(r);
return r;
} /* unifi_read_chip_version() */
@@ -2684,8 +2553,6 @@ static CsrResult unifi_reset_hardware(card_t *card)
u16 new_block_size = UNIFI_IO_BLOCK_SIZE;
CsrResult csrResult;
- func_enter();
-
/* Errors returned by unifi_prepare_hw() are not critical at this point */
r = unifi_prepare_hw(card);
if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
@@ -2709,7 +2576,6 @@ static CsrResult unifi_reset_hardware(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "unifi_prepare_hw failed after hard reset\n");
- func_exit_r(r);
return r;
}
}
@@ -2729,7 +2595,6 @@ static CsrResult unifi_reset_hardware(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "software hard reset failed\n");
- func_exit_r(r);
return r;
}
@@ -2742,7 +2607,6 @@ static CsrResult unifi_reset_hardware(card_t *card)
r = unifi_read_chip_version(card);
if (r != CSR_RESULT_SUCCESS)
{
- func_exit_r(r);
return r;
}
}
@@ -2792,7 +2656,6 @@ static CsrResult unifi_reset_hardware(card_t *card)
}
- func_exit_r(r);
return r;
} /* unifi_reset_hardware() */
@@ -2818,8 +2681,6 @@ static CsrResult card_reset_method_io_enable(card_t *card)
CsrResult r;
CsrResult csrResult;
- func_enter();
-
/*
* This resets only function 1, so should be used in
* preference to the method below (CSR_FUNC_EN)
@@ -2869,7 +2730,6 @@ static CsrResult card_reset_method_io_enable(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_warning(card->ospriv, "SDIO error writing SDIO_CSR_FUNC_EN: %d\n", r);
- func_exit_r(r);
return r;
}
else
@@ -2890,7 +2750,6 @@ static CsrResult card_reset_method_io_enable(card_t *card)
unifi_warning(card->ospriv, "card_reset_method_io_enable failed to reset UniFi\n");
}
- func_exit();
return r;
} /* card_reset_method_io_enable() */
@@ -2915,8 +2774,6 @@ static CsrResult card_reset_method_dbg_reset(card_t *card)
{
CsrResult r;
- func_enter();
-
/*
* Prepare UniFi for h/w reset
*/
@@ -2930,7 +2787,6 @@ static CsrResult card_reset_method_dbg_reset(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to set UNIFI_HOST_STATE_DROWSY\n");
- func_exit_r(r);
return r;
}
CsrThreadSleep(5);
@@ -2944,7 +2800,6 @@ static CsrResult card_reset_method_dbg_reset(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Can't stop processors\n");
- func_exit();
return r;
}
@@ -2963,7 +2818,6 @@ static CsrResult card_reset_method_dbg_reset(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_warning(card->ospriv, "SDIO error writing DBG_RESET: %d\n", r);
- func_exit_r(r);
return r;
}
@@ -2980,7 +2834,6 @@ static CsrResult card_reset_method_dbg_reset(card_t *card)
unifi_warning(card->ospriv, "card_reset_method_dbg_reset failed to reset UniFi\n");
}
- func_exit();
return r;
} /* card_reset_method_dbg_reset() */
@@ -3008,8 +2861,6 @@ CsrResult unifi_card_hard_reset(card_t *card)
const struct chip_helper_reset_values *init_data;
u32 chunks;
- func_enter();
-
/* Clear cache of page registers */
card->proc_select = (u32)(-1);
card->dmem_page = (u32)(-1);
@@ -3028,7 +2879,6 @@ CsrResult unifi_card_hard_reset(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "unifi_card_hard_reset failed to identify h/w\n");
- func_exit();
return r;
}
@@ -3039,7 +2889,6 @@ CsrResult unifi_card_hard_reset(card_t *card)
unifi_error(card->ospriv,
"Hard reset (Code download) is unsupported\n");
- func_exit_r(CSR_RESULT_FAILURE);
return CSR_RESULT_FAILURE;
}
@@ -3058,7 +2907,6 @@ CsrResult unifi_card_hard_reset(card_t *card)
}
if (r == CSR_RESULT_SUCCESS)
{
- func_exit();
return r;
}
}
@@ -3066,7 +2914,6 @@ CsrResult unifi_card_hard_reset(card_t *card)
/* Software hard reset */
r = card_reset_method_dbg_reset(card);
- func_exit_r(r);
return r;
} /* unifi_card_hard_reset() */
@@ -3097,8 +2944,6 @@ CsrResult CardGenInt(card_t *card)
{
CsrResult r;
- func_enter();
-
if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
{
r = sdio_write_f0(card, SDIO_CSR_FROM_HOST_SCRATCH0,
@@ -3117,13 +2962,11 @@ CsrResult CardGenInt(card_t *card)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "SDIO error writing UNIFI_SHARED_IO_INTERRUPT: %d\n", r);
- func_exit_r(r);
return r;
}
card->unifi_interrupt_seq++;
- func_exit();
return CSR_RESULT_SUCCESS;
} /* CardGenInt() */
@@ -3388,8 +3231,6 @@ CsrResult CardWriteBulkData(card_t *card, card_signal_t *csptr, unifi_TrafficQue
bulk_data_desc_t *bulkdata = csptr->bulkdata;
s16 h, nslots;
- func_enter();
-
/* Count the number of slots required */
for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
{
@@ -3470,7 +3311,6 @@ CsrResult CardWriteBulkData(card_t *card, card_signal_t *csptr, unifi_TrafficQue
{
unifi_trace(card->ospriv, UDBG5, "fh data slot %d: %d\n", i, card->from_host_data[i].bd.data_length);
}
- func_exit();
return CSR_RESULT_FAILURE;
}
}
@@ -3523,8 +3363,6 @@ CsrResult CardWriteBulkData(card_t *card, card_signal_t *csptr, unifi_TrafficQue
}
}
- func_exit();
-
return CSR_RESULT_SUCCESS;
} /* CardWriteBulkData() */
diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio.h b/drivers/staging/csr/csr_wifi_hip_card_sdio.h
index dc2ed70f7ed..a9b9ec42732 100644
--- a/drivers/staging/csr/csr_wifi_hip_card_sdio.h
+++ b/drivers/staging/csr/csr_wifi_hip_card_sdio.h
@@ -20,10 +20,6 @@
#ifndef __CARD_SDIO_H__
#define __CARD_SDIO_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include "csr_wifi_hip_unifi.h"
#include "csr_wifi_hip_unifi_udi.h"
#include "csr_wifi_hip_unifihw.h"
@@ -695,8 +691,4 @@ CsrResult prealloc_netdata_alloc(card_t *card);
void dump(void *mem, u16 len);
void dump16(void *mem, u16 len);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __CARD_SDIO_H__ */
diff --git a/drivers/staging/csr/csr_wifi_hip_chiphelper.h b/drivers/staging/csr/csr_wifi_hip_chiphelper.h
index 24737ae8a2d..b6b67ee11db 100644
--- a/drivers/staging/csr/csr_wifi_hip_chiphelper.h
+++ b/drivers/staging/csr/csr_wifi_hip_chiphelper.h
@@ -14,10 +14,6 @@
#include <linux/types.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* The age of the BlueCore chip. This is probably not useful, if
you know the age then you can probably work out the version directly. */
enum chip_helper_bluecore_age
@@ -408,64 +404,4 @@ s32 ChipHelper_DecodeWindow(ChipDescript *chip_help,
u32 offset,
u16 *page, u16 *addr, u32 *len);
-#ifdef __cplusplus
-/* Close the extern "C" */
-}
-
-/*
- * This is the C++ API.
- */
-
-class ChipHelper
-{
-public:
- /* If this constructor is used then a GetVersionXXX function
- should be called next. */
- ChipHelper();
-
- /* copy constructor */
- ChipHelper(ChipDescript * desc);
-
- /* The default constructor assume a BC7 / UF105x series chip
- and that the number given is the value of UNIFI_GBL_CHIP_VERSION
- (0xFE81) */
- ChipHelper(u16 version);
-
- /* This returns the C interface magic token from a C++ instance. */
- ChipDescript* GetDescript() const
- {
- return m_desc;
- }
-
-
- /* Clear out theis class (set it to the null token). */
- void ClearVersion();
-
- /* Load this class with data for a specific chip. */
- void GetVersionAny(u16 from_FF9A, u16 from_FE81);
- void GetVersionUniFi(u16 version);
- void GetVersionBlueCore(chip_helper_bluecore_age age, u16 version);
- void GetVersionSdio(u8 sdio_version);
-
- /* Helpers to build the definitions of the member functions. */
-#define CHIP_HELPER_DEF0_CPP_DEC(ret_type, name, info) \
- ret_type name() const;
-#define CHIP_HELPER_DEF1_CPP_DEC(ret_type, name, type1, name1) \
- ret_type name(type1 name1) const;
-
- CHIP_HELPER_LIST(CPP_DEC)
-
-
- /* The DecodeWindow function, see the description of the C version. */
- s32 DecodeWindow(chip_helper_window_index window,
- chip_helper_window_type type,
- u32 offset,
- u16 &page, u16 &addr, u32 &len) const;
-
-private:
- ChipDescript *m_desc;
-};
-
-#endif /* __cplusplus */
-
#endif
diff --git a/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h b/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h
index cb0ea4b63e6..e5e57991255 100644
--- a/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h
+++ b/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h
@@ -14,10 +14,6 @@
#include "csr_wifi_hip_chiphelper.h"
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
/* This GP stuff should be somewhere else? */
/* Memory spaces encoded in top byte of Generic Pointer type */
@@ -201,8 +197,4 @@ struct chip_device_desc_t
const struct window_info_t *windows[CHIP_HELPER_WINDOW_COUNT];
};
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
#endif /* CSR_WIFI_HIP_CHIPHELPER_PRIVATE_H__ */
diff --git a/drivers/staging/csr/csr_wifi_hip_conversions.h b/drivers/staging/csr/csr_wifi_hip_conversions.h
index 7d045c06936..bf7a52e8299 100644
--- a/drivers/staging/csr/csr_wifi_hip_conversions.h
+++ b/drivers/staging/csr/csr_wifi_hip_conversions.h
@@ -23,10 +23,6 @@
#ifndef __CSR_WIFI_HIP_CONVERSIONS_H__
#define __CSR_WIFI_HIP_CONVERSIONS_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#define SIZEOF_UINT16 2
#define SIZEOF_UINT32 4
#define SIZEOF_UINT64 8
@@ -73,9 +69,5 @@ s32 get_packed_struct_size(const u8 *buf);
CsrResult read_unpack_signal(const u8 *ptr, CSR_SIGNAL *sig);
CsrResult write_pack(const CSR_SIGNAL *sig, u8 *ptr, u16 *sig_len);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __CSR_WIFI_HIP_CONVERSIONS_H__ */
diff --git a/drivers/staging/csr/csr_wifi_hip_download.c b/drivers/staging/csr/csr_wifi_hip_download.c
index 6db672caaa0..2f44a383d2c 100644
--- a/drivers/staging/csr/csr_wifi_hip_download.c
+++ b/drivers/staging/csr/csr_wifi_hip_download.c
@@ -68,7 +68,6 @@ static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Firmware hasn't started\n");
- func_exit_r(r);
return r;
}
*pslut = slut_address;
@@ -81,7 +80,6 @@ static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut)
if (csrResult != CSR_RESULT_SUCCESS)
{
r = ConvertCsrSdioToCsrHipResult(card, csrResult);
- func_exit_r(r);
return r;
}
card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ;
@@ -106,14 +104,12 @@ static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut)
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Failed to read SLUT finger print\n");
- func_exit_r(r);
return r;
}
if (finger_print != SLUT_FINGERPRINT)
{
unifi_error(card->ospriv, "Failed to find SLUT fingerprint\n");
- func_exit_r(CSR_RESULT_FAILURE);
return CSR_RESULT_FAILURE;
}
@@ -128,7 +124,6 @@ static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut)
r = unifi_card_read16(card, slut_address, &id);
if (r != CSR_RESULT_SUCCESS)
{
- func_exit_r(r);
return r;
}
slut_address += 2;
@@ -143,7 +138,6 @@ static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut)
r = unifi_read32(card, slut_address, &obj);
if (r != CSR_RESULT_SUCCESS)
{
- func_exit_r(r);
return r;
}
slut_address += 4;
@@ -161,7 +155,6 @@ static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut)
}
}
- func_exit_r(r);
return r;
}
@@ -279,7 +272,6 @@ static CsrResult do_patch_convert_download(card_t *card, void *dlpriv, xbv1_t *p
if (r != CSR_RESULT_SUCCESS)
{
unifi_error(card->ospriv, "Converted patch download failed\n");
- func_exit_r(r);
return r;
}
else
@@ -294,7 +286,6 @@ static CsrResult do_patch_convert_download(card_t *card, void *dlpriv, xbv1_t *p
unifi_error(card->ospriv, "Failed to write loader restart cmd\n");
}
- func_exit_r(r);
return r;
}
}
@@ -327,8 +318,6 @@ CsrResult unifi_dl_firmware(card_t *card, void *dlpriv)
xbv1_t *fwinfo;
CsrResult r;
- func_enter();
-
fwinfo = kmalloc(sizeof(xbv1_t), GFP_KERNEL);
if (fwinfo == NULL)
{
@@ -376,7 +365,6 @@ CsrResult unifi_dl_firmware(card_t *card, void *dlpriv)
}
kfree(fwinfo);
- func_exit_r(r);
return r;
} /* unifi_dl_firmware() */
@@ -407,15 +395,12 @@ CsrResult unifi_dl_patch(card_t *card, void *dlpriv, u32 boot_ctrl)
xbv1_t *fwinfo;
CsrResult r;
- func_enter();
-
unifi_info(card->ospriv, "unifi_dl_patch %p %08x\n", dlpriv, boot_ctrl);
fwinfo = kmalloc(sizeof(xbv1_t), GFP_KERNEL);
if (fwinfo == NULL)
{
unifi_error(card->ospriv, "Failed to allocate memory for patches\n");
- func_exit();
return CSR_WIFI_HIP_RESULT_NO_MEMORY;
}
@@ -431,7 +416,6 @@ CsrResult unifi_dl_patch(card_t *card, void *dlpriv, u32 boot_ctrl)
{
kfree(fwinfo);
unifi_error(card->ospriv, "Failed to read in patch file\n");
- func_exit();
return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
}
@@ -446,7 +430,6 @@ CsrResult unifi_dl_patch(card_t *card, void *dlpriv, u32 boot_ctrl)
card->build_id, fwinfo->build_id);
kfree(fwinfo);
#ifndef CSR_WIFI_IGNORE_PATCH_VERSION_MISMATCH
- func_exit();
return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
#else
fwinfo = NULL;
@@ -463,7 +446,6 @@ CsrResult unifi_dl_patch(card_t *card, void *dlpriv, u32 boot_ctrl)
kfree(fwinfo);
- func_exit_r(r);
return r;
} /* unifi_dl_patch() */
diff --git a/drivers/staging/csr/csr_wifi_hip_dump.c b/drivers/staging/csr/csr_wifi_hip_dump.c
index d67b460e7a8..7b7eec49d02 100644
--- a/drivers/staging/csr/csr_wifi_hip_dump.c
+++ b/drivers/staging/csr/csr_wifi_hip_dump.c
@@ -40,7 +40,7 @@
typedef struct coredump_buf
{
u16 count; /* serial number of dump */
- CsrTime timestamp; /* host's system time at capture */
+ u32 timestamp; /* host's system time at capture */
s16 requestor; /* request: 0=auto dump, 1=manual */
u16 chip_ver;
u32 fw_ver;
@@ -104,8 +104,6 @@ CsrResult unifi_coredump_request_at_next_reset(card_t *card, s8 enable)
{
CsrResult r;
- func_enter();
-
if (enable)
{
unifi_trace(card->ospriv, UDBG2, "Mini-coredump requested after reset\n");
@@ -121,7 +119,6 @@ CsrResult unifi_coredump_request_at_next_reset(card_t *card, s8 enable)
r = CSR_RESULT_SUCCESS;
}
- func_exit_r(r);
return r;
}
@@ -145,8 +142,6 @@ CsrResult unifi_coredump_handle_request(card_t *card)
{
CsrResult r = CSR_RESULT_SUCCESS;
- func_enter();
-
if (card == NULL)
{
r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
@@ -160,7 +155,6 @@ CsrResult unifi_coredump_handle_request(card_t *card)
}
}
- func_exit_r(r);
return r;
}
@@ -192,9 +186,7 @@ CsrResult unifi_coredump_capture(card_t *card, struct unifi_coredump_req *req)
{
CsrResult r = CSR_RESULT_SUCCESS;
static u16 dump_seq_no = 1;
- CsrTime time_of_capture;
-
- func_enter();
+ u32 time_of_capture;
if (card->dump_next_write == NULL)
{
@@ -269,7 +261,6 @@ CsrResult unifi_coredump_capture(card_t *card, struct unifi_coredump_req *req)
}
done:
- func_exit_r(r);
return r;
} /* unifi_coredump_capture() */
@@ -358,8 +349,6 @@ CsrResult unifi_coredump_get_value(card_t *card, struct unifi_coredump_req *req)
s32 i = 0;
coredump_buffer *find_dump = NULL;
- func_enter();
-
if (req == NULL || card == NULL)
{
r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
@@ -452,7 +441,6 @@ CsrResult unifi_coredump_get_value(card_t *card, struct unifi_coredump_req *req)
req->serial = find_dump->count;
done:
- func_exit_r(r);
return r;
} /* unifi_coredump_get_value() */
@@ -481,8 +469,6 @@ static CsrResult unifi_coredump_read_zone(card_t *card, u16 *zonebuf, const stru
{
CsrResult r;
- func_enter();
-
if (zonebuf == NULL || def == NULL)
{
r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
@@ -521,7 +507,6 @@ static CsrResult unifi_coredump_read_zone(card_t *card, u16 *zonebuf, const stru
}
done:
- func_exit_r(r);
return r;
}
@@ -551,8 +536,6 @@ static CsrResult unifi_coredump_read_zones(card_t *card, coredump_buffer *dump_b
CsrResult r = CSR_RESULT_SUCCESS;
s32 i;
- func_enter();
-
/* Walk the table of coredump zone definitions and read them from the chip */
for (i = 0;
(i < HIP_CDUMP_NUM_ZONES) && (r == 0);
@@ -561,7 +544,6 @@ static CsrResult unifi_coredump_read_zones(card_t *card, coredump_buffer *dump_b
r = unifi_coredump_read_zone(card, dump_buf->zone[i], &zonedef_table[i]);
}
- func_exit_r(r);
return r;
}
@@ -590,8 +572,6 @@ static CsrResult unifi_coredump_from_sdio(card_t *card, coredump_buffer *dump_bu
CsrResult r;
u32 sdio_addr;
- func_enter();
-
if (dump_buf == NULL)
{
r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
@@ -634,7 +614,6 @@ static CsrResult unifi_coredump_from_sdio(card_t *card, coredump_buffer *dump_bu
}
done:
- func_exit_r(r);
return r;
} /* unifi_coredump_from_sdio() */
@@ -743,8 +722,6 @@ CsrResult unifi_coredump_init(card_t *card, u16 num_dump_buffers)
u32 i = 0;
#endif
- func_enter();
-
card->request_coredump_on_reset = 0;
card->dump_next_write = NULL;
card->dump_cur_read = NULL;
@@ -790,7 +767,6 @@ CsrResult unifi_coredump_init(card_t *card, u16 num_dump_buffers)
done:
#endif
- func_exit();
return CSR_RESULT_SUCCESS;
#ifndef UNIFI_DISABLE_COREDUMP
@@ -798,7 +774,6 @@ fail:
/* Unwind what we allocated so far */
unifi_error(ospriv, "Out of memory allocating core dump node %d\n", i);
unifi_coredump_free(card);
- func_exit();
return CSR_WIFI_HIP_RESULT_NO_MEMORY;
#endif
} /* unifi_coreump_init() */
@@ -826,7 +801,6 @@ void unifi_coredump_free(card_t *card)
s16 i = 0;
s16 j;
- func_enter();
unifi_trace(ospriv, UDBG2, "Core dump de-configured\n");
if (card->dump_buf == NULL)
@@ -858,8 +832,6 @@ void unifi_coredump_free(card_t *card)
card->dump_buf = NULL;
card->dump_next_write = NULL;
card->dump_cur_read = NULL;
-
- func_exit();
} /* unifi_coredump_free() */
diff --git a/drivers/staging/csr/csr_wifi_hip_send.c b/drivers/staging/csr/csr_wifi_hip_send.c
index 86aa23cefe3..76429e5e77c 100644
--- a/drivers/staging/csr/csr_wifi_hip_send.c
+++ b/drivers/staging/csr/csr_wifi_hip_send.c
@@ -270,8 +270,6 @@ static CsrResult send_signal(card_t *card, const u8 *sigptr, u32 siglen,
}
}
- func_exit();
-
return CSR_RESULT_SUCCESS;
} /* send_signal() */
diff --git a/drivers/staging/csr/csr_wifi_hip_signals.h b/drivers/staging/csr/csr_wifi_hip_signals.h
index 5f841556bbe..ca4d0774195 100644
--- a/drivers/staging/csr/csr_wifi_hip_signals.h
+++ b/drivers/staging/csr/csr_wifi_hip_signals.h
@@ -1,10 +1,10 @@
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
- All rights reserved and confidential information of CSR
+ (c) Cambridge Silicon Radio Limited 2011
+ All rights reserved and confidential information of CSR
- Refer to LICENSE.txt included with this source for details
- on the license terms.
+ Refer to LICENSE.txt included with this source for details
+ on the license terms.
*****************************************************************************/
@@ -101,10 +101,6 @@
/* FUNCTION DECLARATIONS */
/******************************************************************************/
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
/******************************************************************************
* SigGetNumDataRefs - Retrieve pointers to data-refs from a signal.
*
@@ -129,9 +125,4 @@ s32 SigGetDataRefs(CSR_SIGNAL *aSignal, CSR_DATAREF **aDataRef);
*/
s32 SigGetSize(const CSR_SIGNAL *aSignal);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
#endif /* __CSR_WIFI_HIP_SIGNALS_H__ */
diff --git a/drivers/staging/csr/csr_wifi_hip_sigs.h b/drivers/staging/csr/csr_wifi_hip_sigs.h
index 2b9f51d7f29..6112cc3e87f 100644
--- a/drivers/staging/csr/csr_wifi_hip_sigs.h
+++ b/drivers/staging/csr/csr_wifi_hip_sigs.h
@@ -16,10 +16,6 @@
#ifndef CSR_WIFI_HIP_SIGS_H
#define CSR_WIFI_HIP_SIGS_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef s16 csr_place_holding_type;
typedef u16 CSR_ASSOCIATION_ID;
@@ -1418,8 +1414,4 @@ typedef struct CSR_SIGNAL_PRIMITIVE
u32 SigGetFilterPos(u16 aSigID);
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/drivers/staging/csr/csr_wifi_hip_ta_sampling.h b/drivers/staging/csr/csr_wifi_hip_ta_sampling.h
index 46c630b4bee..aa684c654d0 100644
--- a/drivers/staging/csr/csr_wifi_hip_ta_sampling.h
+++ b/drivers/staging/csr/csr_wifi_hip_ta_sampling.h
@@ -21,10 +21,6 @@
#ifndef __TA_SAMPLING_H__
#define __TA_SAMPLING_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include "csr_wifi_hip_unifi.h"
typedef struct ta_l4stats
@@ -67,9 +63,4 @@ typedef struct ta_data
void unifi_ta_sampling_init(card_t *card);
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __TA_SAMPLING_H__ */
diff --git a/drivers/staging/csr/csr_wifi_hip_unifi.h b/drivers/staging/csr/csr_wifi_hip_unifi.h
index 2923e2ef12f..c2a2231680f 100644
--- a/drivers/staging/csr/csr_wifi_hip_unifi.h
+++ b/drivers/staging/csr/csr_wifi_hip_unifi.h
@@ -20,10 +20,6 @@
#ifndef __CSR_WIFI_HIP_UNIFI_H__
#define __CSR_WIFI_HIP_UNIFI_H__ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef CSR_WIFI_HIP_TA_DISABLE
#include "csr_wifi_router_ctrl_prim.h"
#include "csr_wifi_router_prim.h"
@@ -228,7 +224,7 @@ typedef struct unifi_coredump_req
u32 chip_ver; /* Chip version */
u32 fw_ver; /* Firmware version */
s32 requestor; /* Requestor: 0=auto dump, 1=manual */
- CsrTime timestamp; /* time of capture by driver */
+ u32 timestamp; /* time of capture by driver */
u32 serial; /* capture serial number */
s32 value; /* register value */
} unifi_coredump_req_t; /* mini-coredumped reg value request */
@@ -872,8 +868,4 @@ CsrResult unifi_coredump_request_at_next_reset(card_t *card, s8 enable);
CsrResult unifi_coredump_init(card_t *card, u16 num_dump_buffers);
void unifi_coredump_free(card_t *card);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __CSR_WIFI_HIP_UNIFI_H__ */
diff --git a/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c b/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c
index 7c13df295c1..9a3528599f3 100644
--- a/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c
+++ b/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c
@@ -10,37 +10,32 @@
#include "csr_wifi_hip_unifi.h"
-struct sig_name
-{
- s16 id;
- const char *name;
+struct sig_name {
+ s16 id;
+ const char *name;
};
static const struct sig_name Unifi_bulkcmd_names[] = {
- { 0, "SignalCmd" },
- { 1, "CopyToHost" },
- { 2, "CopyToHostAck" },
- { 3, "CopyFromHost" },
- { 4, "CopyFromHostAck" },
- { 5, "ClearSlot" },
- { 6, "CopyOverlay" },
- { 7, "CopyOverlayAck" },
- { 8, "CopyFromHostAndClearSlot" },
- { 15, "Padding" }
+ { 0, "SignalCmd" },
+ { 1, "CopyToHost" },
+ { 2, "CopyToHostAck" },
+ { 3, "CopyFromHost" },
+ { 4, "CopyFromHostAck" },
+ { 5, "ClearSlot" },
+ { 6, "CopyOverlay" },
+ { 7, "CopyOverlayAck" },
+ { 8, "CopyFromHostAndClearSlot" },
+ { 15, "Padding" }
};
-const char* lookup_bulkcmd_name(u16 id)
+const char *lookup_bulkcmd_name(u16 id)
{
- if (id < 9)
- {
- return Unifi_bulkcmd_names[id].name;
- }
- if (id == 15)
- {
- return "Padding";
- }
-
- return "UNKNOWN";
+ if (id < 9)
+ return Unifi_bulkcmd_names[id].name;
+ if (id == 15)
+ return "Padding";
+
+ return "UNKNOWN";
}
diff --git a/drivers/staging/csr/csr_wifi_hip_unifi_udi.h b/drivers/staging/csr/csr_wifi_hip_unifi_udi.h
index 83032d0b4ec..9d85cfd5761 100644
--- a/drivers/staging/csr/csr_wifi_hip_unifi_udi.h
+++ b/drivers/staging/csr/csr_wifi_hip_unifi_udi.h
@@ -20,10 +20,6 @@
#ifndef __CSR_WIFI_HIP_UNIFI_UDI_H__
#define __CSR_WIFI_HIP_UNIFI_UDI_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include "csr_wifi_hip_unifi.h"
#include "csr_wifi_hip_signals.h"
@@ -68,9 +64,4 @@ s32 unifi_print_status(card_t *card, char *str, s32 *remain);
} \
} while (0)
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __CSR_WIFI_HIP_UNIFI_UDI_H__ */
diff --git a/drivers/staging/csr/csr_wifi_hip_unifihw.h b/drivers/staging/csr/csr_wifi_hip_unifihw.h
index 5ffd6ba38d3..3f9fcbd55b5 100644
--- a/drivers/staging/csr/csr_wifi_hip_unifihw.h
+++ b/drivers/staging/csr/csr_wifi_hip_unifihw.h
@@ -20,10 +20,6 @@
#ifndef __UNIFIHW_H__
#define __UNIFIHW_H__ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Symbol Look Up Table fingerprint. IDs are in sigs.h */
#define SLUT_FINGERPRINT 0xD397
@@ -60,8 +56,4 @@ extern "C" {
#define UNIFI_GP_OFFSET(GP) ((GP) & 0xFFFFFF)
#define UNIFI_GP_SPACE(GP) (((GP) >> 24) & 0xFF)
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __UNIFIHW_H__ */
diff --git a/drivers/staging/csr/csr_wifi_hip_unifiversion.h b/drivers/staging/csr/csr_wifi_hip_unifiversion.h
index e1fdbb27a46..d1c66783f32 100644
--- a/drivers/staging/csr/csr_wifi_hip_unifiversion.h
+++ b/drivers/staging/csr/csr_wifi_hip_unifiversion.h
@@ -21,18 +21,10 @@
#ifndef __UNIFIVERSION_H__
#define __UNIFIVERSION_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
* The minimum version of Host Interface Protocol required by the driver.
*/
#define UNIFI_HIP_MAJOR_VERSION 9
#define UNIFI_HIP_MINOR_VERSION 1
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __UNIFIVERSION_H__ */
diff --git a/drivers/staging/csr/csr_wifi_hip_xbv.c b/drivers/staging/csr/csr_wifi_hip_xbv.c
index 071f80a49f1..050a15fbadf 100644
--- a/drivers/staging/csr/csr_wifi_hip_xbv.c
+++ b/drivers/staging/csr/csr_wifi_hip_xbv.c
@@ -758,7 +758,7 @@ static u32 write_fwdl_to_ptdl(void *buf, const u32 offset, fwreadfn_t readfn,
while (left)
{
/* Calculate amount to be transferred */
- sec_data_len = CSRMIN(left, PTDL_MAX_SIZE - PTDL_HDR_SIZE);
+ sec_data_len = min_t(u32, left, PTDL_MAX_SIZE - PTDL_HDR_SIZE);
sec_len = sec_data_len + PTDL_HDR_SIZE;
/* Write PTDL header + entire PTDL size */
diff --git a/drivers/staging/csr/csr_wifi_hip_xbv.h b/drivers/staging/csr/csr_wifi_hip_xbv.h
index 9b60a7e2dc7..3c507235323 100644
--- a/drivers/staging/csr/csr_wifi_hip_xbv.h
+++ b/drivers/staging/csr/csr_wifi_hip_xbv.h
@@ -21,10 +21,6 @@
#ifndef __XBV_H__
#define __XBV_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef CSR_WIFI_XBV_TEST
/* Driver includes */
#include "csr_wifi_hip_unifi.h"
@@ -120,8 +116,4 @@ s32 xbv1_read_slut(card_t *card, fwreadfn_t readfn, void *dlpriv, xbv1_t *fwinfo
void* xbv_to_patch(card_t *card, fwreadfn_t readfn, const void *fw_buf, const xbv1_t *fwinfo,
u32 *size);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __XBV_H__ */
diff --git a/drivers/staging/csr/csr_wifi_hostio_prim.h b/drivers/staging/csr/csr_wifi_hostio_prim.h
index bf7c55c6e84..cfb3e272e35 100644
--- a/drivers/staging/csr/csr_wifi_hostio_prim.h
+++ b/drivers/staging/csr/csr_wifi_hostio_prim.h
@@ -12,16 +12,7 @@
#ifndef CSR_WIFI_HOSTIO_H
#define CSR_WIFI_HOSTIO_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
#define CSR_WIFI_HOSTIO_PRIM 0x0453
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_HOSTIO_H */
diff --git a/drivers/staging/csr/csr_wifi_lib.h b/drivers/staging/csr/csr_wifi_lib.h
index eb56f620887..5fde0efb5dc 100644
--- a/drivers/staging/csr/csr_wifi_lib.h
+++ b/drivers/staging/csr/csr_wifi_lib.h
@@ -12,11 +12,6 @@
#include "csr_wifi_fsm_event.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*----------------------------------------------------------------------------*
* CsrWifiFsmEventInit
*
@@ -105,8 +100,4 @@ typedef struct
*----------------------------------------------------------------------------*/
CsrWifiEventCsrUint16CsrUint8* CsrWifiEventCsrUint16CsrUint8_struct(u16 primtype, u16 msgtype, CsrSchedQid dst, CsrSchedQid src, u16 value16, u8 value8);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_LIB_H__ */
diff --git a/drivers/staging/csr/csr_wifi_msgconv.h b/drivers/staging/csr/csr_wifi_msgconv.h
index 7ec35d70e14..f8b402947a0 100644
--- a/drivers/staging/csr/csr_wifi_msgconv.h
+++ b/drivers/staging/csr/csr_wifi_msgconv.h
@@ -14,11 +14,6 @@
#include "csr_prim_defs.h"
#include "csr_sched.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
void CsrUint16SerBigEndian(u8 *ptr, size_t *len, u16 v);
void CsrUint24SerBigEndian(u8 *ptr, size_t *len, u32 v);
void CsrUint32SerBigEndian(u8 *ptr, size_t *len, u32 v);
@@ -51,8 +46,4 @@ size_t CsrWifiEventCsrUint16CsrUint8Sizeof(void *msg);
u8* CsrWifiEventCsrUint16CsrUint8Ser(u8 *ptr, size_t *len, void *msg);
void* CsrWifiEventCsrUint16CsrUint8Des(u8 *buffer, size_t length);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_MSGCONV_H__ */
diff --git a/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h b/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h
index 4072c06a152..b89d7c7f8e2 100644
--- a/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h
+++ b/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h
@@ -13,10 +13,6 @@
#ifndef CSR_WIFI_NME_AP_CONVERTER_INIT_H__
#define CSR_WIFI_NME_AP_CONVERTER_INIT_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef CSR_WIFI_NME_ENABLE
#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_converter_init.h
#endif
@@ -42,8 +38,4 @@ extern void CsrWifiNmeApConverterInit(void);
#endif /* EXCLUDE_CSR_WIFI_NME_AP_MODULE */
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_NME_AP_CONVERTER_INIT_H__ */
diff --git a/drivers/staging/csr/csr_wifi_nme_ap_lib.h b/drivers/staging/csr/csr_wifi_nme_ap_lib.h
index d4014709112..6d8df836681 100644
--- a/drivers/staging/csr/csr_wifi_nme_ap_lib.h
+++ b/drivers/staging/csr/csr_wifi_nme_ap_lib.h
@@ -22,11 +22,6 @@
#include "csr_wifi_nme_ap_prim.h"
#include "csr_wifi_nme_task.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef CSR_WIFI_NME_ENABLE
#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_lib.h
#endif
@@ -58,24 +53,6 @@ void CsrWifiNmeApFreeUpstreamMessageContents(u16 eventClass, void *message);
*----------------------------------------------------------------------------*/
void CsrWifiNmeApFreeDownstreamMessageContents(u16 eventClass, void *message);
-/*----------------------------------------------------------------------------*
- * Enum to string functions
- *----------------------------------------------------------------------------*/
-const char* CsrWifiNmeApPersCredentialTypeToString(CsrWifiNmeApPersCredentialType value);
-
-
-/*----------------------------------------------------------------------------*
- * CsrPrim Type toString function.
- * Converts a message type to the String name of the Message
- *----------------------------------------------------------------------------*/
-const char* CsrWifiNmeApPrimTypeToString(CsrPrim msgType);
-
-/*----------------------------------------------------------------------------*
- * Lookup arrays for PrimType name Strings
- *----------------------------------------------------------------------------*/
-extern const char *CsrWifiNmeApUpstreamPrimNames[CSR_WIFI_NME_AP_PRIM_UPSTREAM_COUNT];
-extern const char *CsrWifiNmeApDownstreamPrimNames[CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_COUNT];
-
/*******************************************************************************
NAME
@@ -515,9 +492,4 @@ extern const char *CsrWifiNmeApDownstreamPrimNames[CSR_WIFI_NME_AP_PRIM_DOWNSTRE
#define CsrWifiNmeApWpsRegisterCfmSend(dst__, interfaceTag__, status__) \
CsrWifiNmeApWpsRegisterCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__)
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_NME_AP_LIB_H__ */
diff --git a/drivers/staging/csr/csr_wifi_nme_ap_prim.h b/drivers/staging/csr/csr_wifi_nme_ap_prim.h
index fc44560b28b..b32bdbc7e22 100644
--- a/drivers/staging/csr/csr_wifi_nme_ap_prim.h
+++ b/drivers/staging/csr/csr_wifi_nme_ap_prim.h
@@ -22,10 +22,6 @@
#include "csr_wifi_sme_ap_prim.h"
#include "csr_wifi_nme_prim.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef CSR_WIFI_NME_ENABLE
#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_prim.h
#endif
@@ -494,10 +490,5 @@ typedef struct
CsrWifiMacAddress peerDeviceAddress;
} CsrWifiNmeApStationInd;
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_NME_AP_PRIM_H__ */
diff --git a/drivers/staging/csr/csr_wifi_nme_ap_sef.h b/drivers/staging/csr/csr_wifi_nme_ap_sef.h
index 3f353633fa5..3daaa0944db 100644
--- a/drivers/staging/csr/csr_wifi_nme_ap_sef.h
+++ b/drivers/staging/csr/csr_wifi_nme_ap_sef.h
@@ -11,11 +11,6 @@
#include "csr_wifi_nme_prim.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
void CsrWifiNmeApUpstreamStateHandlers(void* drvpriv, CsrWifiFsmEvent* msg);
@@ -23,9 +18,4 @@ extern void CsrWifiNmeApConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
extern void CsrWifiNmeApStartCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
extern void CsrWifiNmeApStopCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_NME_H__ */
diff --git a/drivers/staging/csr/csr_wifi_nme_ap_serialize.h b/drivers/staging/csr/csr_wifi_nme_ap_serialize.h
index 0f578294722..c04585e7246 100644
--- a/drivers/staging/csr/csr_wifi_nme_ap_serialize.h
+++ b/drivers/staging/csr/csr_wifi_nme_ap_serialize.h
@@ -17,10 +17,6 @@
#include "csr_wifi_nme_ap_prim.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef CSR_WIFI_NME_ENABLE
#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_serialize.h
#endif
@@ -95,9 +91,4 @@ extern void* CsrWifiNmeApStationIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiNmeApStationIndSizeof(void *msg);
#define CsrWifiNmeApStationIndSerFree CsrWifiNmeApPfree
-
-#ifdef __cplusplus
-}
-#endif
#endif /* CSR_WIFI_NME_AP_SERIALIZE_H__ */
-
diff --git a/drivers/staging/csr/csr_wifi_nme_converter_init.h b/drivers/staging/csr/csr_wifi_nme_converter_init.h
index 6661914fb40..85e6f5f5713 100644
--- a/drivers/staging/csr/csr_wifi_nme_converter_init.h
+++ b/drivers/staging/csr/csr_wifi_nme_converter_init.h
@@ -13,10 +13,6 @@
#ifndef CSR_WIFI_NME_CONVERTER_INIT_H__
#define CSR_WIFI_NME_CONVERTER_INIT_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef CSR_WIFI_NME_ENABLE
#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_converter_init.h
#endif
@@ -39,8 +35,4 @@ extern void CsrWifiNmeConverterInit(void);
#endif /* EXCLUDE_CSR_WIFI_NME_MODULE */
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_NME_CONVERTER_INIT_H__ */
diff --git a/drivers/staging/csr/csr_wifi_nme_lib.h b/drivers/staging/csr/csr_wifi_nme_lib.h
index 709ece46497..5a1f132009b 100644
--- a/drivers/staging/csr/csr_wifi_nme_lib.h
+++ b/drivers/staging/csr/csr_wifi_nme_lib.h
@@ -23,68 +23,10 @@
#include "csr_wifi_nme_task.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef CSR_WIFI_NME_ENABLE
#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_lib.h
#endif
-/*----------------------------------------------------------------------------*
- * CsrWifiNmeFreeUpstreamMessageContents
- *
- * DESCRIPTION
- * Free the allocated memory in a CSR_WIFI_NME upstream message. Does not
- * free the message itself, and can only be used for upstream messages.
- *
- * PARAMETERS
- * Deallocates the resources in a CSR_WIFI_NME upstream message
- *----------------------------------------------------------------------------*/
-void CsrWifiNmeFreeUpstreamMessageContents(u16 eventClass, void *message);
-
-/*----------------------------------------------------------------------------*
- * CsrWifiNmeFreeDownstreamMessageContents
- *
- * DESCRIPTION
- * Free the allocated memory in a CSR_WIFI_NME downstream message. Does not
- * free the message itself, and can only be used for downstream messages.
- *
- * PARAMETERS
- * Deallocates the resources in a CSR_WIFI_NME downstream message
- *----------------------------------------------------------------------------*/
-void CsrWifiNmeFreeDownstreamMessageContents(u16 eventClass, void *message);
-
-/*----------------------------------------------------------------------------*
- * Enum to string functions
- *----------------------------------------------------------------------------*/
-const char* CsrWifiNmeAuthModeToString(CsrWifiNmeAuthMode value);
-const char* CsrWifiNmeBssTypeToString(CsrWifiNmeBssType value);
-const char* CsrWifiNmeCcxOptionsMaskToString(CsrWifiNmeCcxOptionsMask value);
-const char* CsrWifiNmeConfigActionToString(CsrWifiNmeConfigAction value);
-const char* CsrWifiNmeConnectionStatusToString(CsrWifiNmeConnectionStatus value);
-const char* CsrWifiNmeCredentialTypeToString(CsrWifiNmeCredentialType value);
-const char* CsrWifiNmeEapMethodToString(CsrWifiNmeEapMethod value);
-const char* CsrWifiNmeEncryptionToString(CsrWifiNmeEncryption value);
-const char* CsrWifiNmeIndicationsToString(CsrWifiNmeIndications value);
-const char* CsrWifiNmeSecErrorToString(CsrWifiNmeSecError value);
-const char* CsrWifiNmeSimCardTypeToString(CsrWifiNmeSimCardType value);
-const char* CsrWifiNmeUmtsAuthResultToString(CsrWifiNmeUmtsAuthResult value);
-const char* CsrWifiNmeWmmQosInfoToString(CsrWifiNmeWmmQosInfo value);
-
-
-/*----------------------------------------------------------------------------*
- * CsrPrim Type toString function.
- * Converts a message type to the String name of the Message
- *----------------------------------------------------------------------------*/
-const char* CsrWifiNmePrimTypeToString(CsrPrim msgType);
-
-/*----------------------------------------------------------------------------*
- * Lookup arrays for PrimType name Strings
- *----------------------------------------------------------------------------*/
-extern const char *CsrWifiNmeUpstreamPrimNames[CSR_WIFI_NME_PRIM_UPSTREAM_COUNT];
-extern const char *CsrWifiNmeDownstreamPrimNames[CSR_WIFI_NME_PRIM_DOWNSTREAM_COUNT];
-
/*******************************************************************************
NAME
@@ -1046,9 +988,4 @@ extern const char *CsrWifiNmeDownstreamPrimNames[CSR_WIFI_NME_PRIM_DOWNSTREAM_CO
#define CsrWifiNmeWpsReqSend(src__, interfaceTag__, pin__, ssid__, bssid__) \
CsrWifiNmeWpsReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__, pin__, ssid__, bssid__)
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_NME_LIB_H__ */
diff --git a/drivers/staging/csr/csr_wifi_nme_prim.h b/drivers/staging/csr/csr_wifi_nme_prim.h
index 20dc77971f9..9a7927a117e 100644
--- a/drivers/staging/csr/csr_wifi_nme_prim.h
+++ b/drivers/staging/csr/csr_wifi_nme_prim.h
@@ -21,10 +21,6 @@
#include "csr_wifi_fsm_event.h"
#include "csr_wifi_sme_prim.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef CSR_WIFI_NME_ENABLE
#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_prim.h
#endif
@@ -1657,10 +1653,5 @@ typedef struct
CsrResult status;
} CsrWifiNmeEventMaskSetCfm;
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_NME_PRIM_H__ */
diff --git a/drivers/staging/csr/csr_wifi_nme_serialize.h b/drivers/staging/csr/csr_wifi_nme_serialize.h
index c6b163660a3..ebac484419c 100644
--- a/drivers/staging/csr/csr_wifi_nme_serialize.h
+++ b/drivers/staging/csr/csr_wifi_nme_serialize.h
@@ -16,10 +16,6 @@
#include "csr_wifi_msgconv.h"
#include "csr_wifi_nme_prim.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef CSR_WIFI_NME_ENABLE
#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_serialize.h
#endif
@@ -166,9 +162,5 @@ extern size_t CsrWifiNmeSimUmtsAuthIndSizeof(void *msg);
#define CsrWifiNmeEventMaskSetCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiNmeEventMaskSetCfmSerFree CsrWifiNmePfree
-
-#ifdef __cplusplus
-}
-#endif
#endif /* CSR_WIFI_NME_SERIALIZE_H__ */
diff --git a/drivers/staging/csr/csr_wifi_nme_task.h b/drivers/staging/csr/csr_wifi_nme_task.h
index 76f44dbe26a..84e973a59bb 100644
--- a/drivers/staging/csr/csr_wifi_nme_task.h
+++ b/drivers/staging/csr/csr_wifi_nme_task.h
@@ -16,23 +16,12 @@
#include <linux/types.h>
#include "csr_sched.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef CSR_WIFI_NME_ENABLE
#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_task.h
#endif
#define CSR_WIFI_NME_LOG_ID 0x1203FFFF
extern CsrSchedQid CSR_WIFI_NME_IFACEQUEUE;
-void CsrWifiNmeInit(void **gash);
-void CsrWifiNmeDeinit(void **gash);
-void CsrWifiNmeHandler(void **gash);
-
-#ifdef __cplusplus
-}
-#endif
#endif /* CSR_WIFI_NME_TASK_H__ */
diff --git a/drivers/staging/csr/csr_wifi_private_common.h b/drivers/staging/csr/csr_wifi_private_common.h
index 47309984e2a..ee3bd51b934 100644
--- a/drivers/staging/csr/csr_wifi_private_common.h
+++ b/drivers/staging/csr/csr_wifi_private_common.h
@@ -11,10 +11,6 @@
#ifndef CSR_WIFI_PRIVATE_COMMON_H__
#define CSR_WIFI_PRIVATE_COMMON_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/**
* @brief maximum number of STAs allowed to be connected
*
@@ -81,9 +77,5 @@ typedef u8 CsrWifiInterfaceMode;
#define CSR_WIFI_MODE_WPS_ENROLLEE ((CsrWifiInterfaceMode) 0x06)
#define CSR_WIFI_MODE_IBSS ((CsrWifiInterfaceMode) 0x07)
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/drivers/staging/csr/csr_wifi_result.h b/drivers/staging/csr/csr_wifi_result.h
index 2f87cda9003..3c394c7e5fa 100644
--- a/drivers/staging/csr/csr_wifi_result.h
+++ b/drivers/staging/csr/csr_wifi_result.h
@@ -13,10 +13,6 @@
#include "csr_result.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* THIS FILE SHOULD CONTAIN ONLY RESULT CODES */
/* Result Codes */
@@ -27,9 +23,5 @@ extern "C" {
#define CSR_WIFI_HIP_RESULT_RANGE ((CsrResult) 5) /* Request exceeds the range of a file or a buffer */
#define CSR_WIFI_HIP_RESULT_NOT_FOUND ((CsrResult) 6) /* A file (typically a f/w patch) is not found */
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_RESULT_H__ */
diff --git a/drivers/staging/csr/csr_wifi_router_converter_init.h b/drivers/staging/csr/csr_wifi_router_converter_init.h
index 2a293e457ff..478327b75c1 100644
--- a/drivers/staging/csr/csr_wifi_router_converter_init.h
+++ b/drivers/staging/csr/csr_wifi_router_converter_init.h
@@ -13,10 +13,6 @@
#ifndef CSR_WIFI_ROUTER_CONVERTER_INIT_H__
#define CSR_WIFI_ROUTER_CONVERTER_INIT_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef EXCLUDE_CSR_WIFI_ROUTER_MODULE
#include "csr_msgconv.h"
@@ -35,8 +31,4 @@ extern void CsrWifiRouterConverterInit(void);
#endif /* EXCLUDE_CSR_WIFI_ROUTER_MODULE */
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_ROUTER_CONVERTER_INIT_H__ */
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h b/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h
index 0c9d26b7a0b..c9845891282 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h
@@ -13,10 +13,6 @@
#ifndef CSR_WIFI_ROUTER_CTRL_CONVERTER_INIT_H__
#define CSR_WIFI_ROUTER_CTRL_CONVERTER_INIT_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef EXCLUDE_CSR_WIFI_ROUTER_CTRL_MODULE
#include "csr_msgconv.h"
@@ -35,8 +31,4 @@ extern void CsrWifiRouterCtrlConverterInit(void);
#endif /* EXCLUDE_CSR_WIFI_ROUTER_CTRL_MODULE */
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_ROUTER_CTRL_CONVERTER_INIT_H__ */
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_lib.h b/drivers/staging/csr/csr_wifi_router_ctrl_lib.h
index 93d0fadf5e6..f235153c42a 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_lib.h
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_lib.h
@@ -22,11 +22,6 @@
#include "csr_wifi_router_ctrl_prim.h"
#include "csr_wifi_router_task.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*----------------------------------------------------------------------------*
* CsrWifiRouterCtrlFreeUpstreamMessageContents
*
@@ -2084,9 +2079,4 @@ extern const char *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER_CTRL_PRI
#define CsrWifiRouterCtrlWifiOnCfmSend(dst__, clientData__, status__) \
CsrWifiRouterCtrlWifiOnCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, status__)
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_ROUTER_CTRL_LIB_H__ */
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_prim.h b/drivers/staging/csr/csr_wifi_router_ctrl_prim.h
index ec972ac0b5a..1312a335dd7 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_prim.h
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_prim.h
@@ -20,10 +20,6 @@
#include "csr_result.h"
#include "csr_wifi_fsm_event.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#define CSR_WIFI_ROUTER_CTRL_PRIM (0x0401)
typedef CsrPrim CsrWifiRouterCtrlPrim;
@@ -2113,10 +2109,5 @@ typedef struct
u8 *data;
} CsrWifiRouterCtrlWapiUnicastTxEncryptInd;
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_ROUTER_CTRL_PRIM_H__ */
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_sef.c b/drivers/staging/csr/csr_wifi_router_ctrl_sef.c
index 33d92b698c5..99cf93061d1 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_sef.c
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_sef.c
@@ -9,37 +9,38 @@
*****************************************************************************/
#include "csr_wifi_router_ctrl_sef.h"
-const CsrWifiRouterCtrlStateHandlerType CsrWifiRouterCtrlDownstreamStateHandlers[CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT] =
-{
- /* 0x0000 */ CsrWifiRouterCtrlConfigurePowerModeReqHandler,
- /* 0x0001 */ CsrWifiRouterCtrlHipReqHandler,
- /* 0x0002 */ CsrWifiRouterCtrlMediaStatusReqHandler,
- /* 0x0003 */ CsrWifiRouterCtrlMulticastAddressResHandler,
- /* 0x0004 */ CsrWifiRouterCtrlPortConfigureReqHandler,
- /* 0x0005 */ CsrWifiRouterCtrlQosControlReqHandler,
- /* 0x0006 */ CsrWifiRouterCtrlSuspendResHandler,
- /* 0x0007 */ CsrWifiRouterCtrlTclasAddReqHandler,
- /* 0x0008 */ CsrWifiRouterCtrlResumeResHandler,
- /* 0x0009 */ CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler,
- /* 0x000A */ CsrWifiRouterCtrlRawSdioInitialiseReqHandler,
- /* 0x000B */ CsrWifiRouterCtrlTclasDelReqHandler,
- /* 0x000C */ CsrWifiRouterCtrlTrafficClassificationReqHandler,
- /* 0x000D */ CsrWifiRouterCtrlTrafficConfigReqHandler,
- /* 0x000E */ CsrWifiRouterCtrlWifiOffReqHandler,
- /* 0x000F */ CsrWifiRouterCtrlWifiOffResHandler,
- /* 0x0010 */ CsrWifiRouterCtrlWifiOnReqHandler,
- /* 0x0011 */ CsrWifiRouterCtrlWifiOnResHandler,
- /* 0x0012 */ CsrWifiRouterCtrlM4TransmitReqHandler,
- /* 0x0013 */ CsrWifiRouterCtrlModeSetReqHandler,
- /* 0x0014 */ CsrWifiRouterCtrlPeerAddReqHandler,
- /* 0x0015 */ CsrWifiRouterCtrlPeerDelReqHandler,
- /* 0x0016 */ CsrWifiRouterCtrlPeerUpdateReqHandler,
- /* 0x0017 */ CsrWifiRouterCtrlCapabilitiesReqHandler,
- /* 0x0018 */ CsrWifiRouterCtrlBlockAckEnableReqHandler,
- /* 0x0019 */ CsrWifiRouterCtrlBlockAckDisableReqHandler,
- /* 0x001A */ CsrWifiRouterCtrlWapiRxPktReqHandler,
- /* 0x001B */ CsrWifiRouterCtrlWapiMulticastFilterReqHandler,
- /* 0x001C */ CsrWifiRouterCtrlWapiUnicastFilterReqHandler,
- /* 0x001D */ CsrWifiRouterCtrlWapiUnicastTxPktReqHandler,
- /* 0x001E */ CsrWifiRouterCtrlWapiFilterReqHandler,
+const CsrWifiRouterCtrlStateHandlerType
+ CsrWifiRouterCtrlDownstreamStateHandlers
+ [CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT] = {
+ /* 0x0000 */ CsrWifiRouterCtrlConfigurePowerModeReqHandler,
+ /* 0x0001 */ CsrWifiRouterCtrlHipReqHandler,
+ /* 0x0002 */ CsrWifiRouterCtrlMediaStatusReqHandler,
+ /* 0x0003 */ CsrWifiRouterCtrlMulticastAddressResHandler,
+ /* 0x0004 */ CsrWifiRouterCtrlPortConfigureReqHandler,
+ /* 0x0005 */ CsrWifiRouterCtrlQosControlReqHandler,
+ /* 0x0006 */ CsrWifiRouterCtrlSuspendResHandler,
+ /* 0x0007 */ CsrWifiRouterCtrlTclasAddReqHandler,
+ /* 0x0008 */ CsrWifiRouterCtrlResumeResHandler,
+ /* 0x0009 */ CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler,
+ /* 0x000A */ CsrWifiRouterCtrlRawSdioInitialiseReqHandler,
+ /* 0x000B */ CsrWifiRouterCtrlTclasDelReqHandler,
+ /* 0x000C */ CsrWifiRouterCtrlTrafficClassificationReqHandler,
+ /* 0x000D */ CsrWifiRouterCtrlTrafficConfigReqHandler,
+ /* 0x000E */ CsrWifiRouterCtrlWifiOffReqHandler,
+ /* 0x000F */ CsrWifiRouterCtrlWifiOffResHandler,
+ /* 0x0010 */ CsrWifiRouterCtrlWifiOnReqHandler,
+ /* 0x0011 */ CsrWifiRouterCtrlWifiOnResHandler,
+ /* 0x0012 */ CsrWifiRouterCtrlM4TransmitReqHandler,
+ /* 0x0013 */ CsrWifiRouterCtrlModeSetReqHandler,
+ /* 0x0014 */ CsrWifiRouterCtrlPeerAddReqHandler,
+ /* 0x0015 */ CsrWifiRouterCtrlPeerDelReqHandler,
+ /* 0x0016 */ CsrWifiRouterCtrlPeerUpdateReqHandler,
+ /* 0x0017 */ CsrWifiRouterCtrlCapabilitiesReqHandler,
+ /* 0x0018 */ CsrWifiRouterCtrlBlockAckEnableReqHandler,
+ /* 0x0019 */ CsrWifiRouterCtrlBlockAckDisableReqHandler,
+ /* 0x001A */ CsrWifiRouterCtrlWapiRxPktReqHandler,
+ /* 0x001B */ CsrWifiRouterCtrlWapiMulticastFilterReqHandler,
+ /* 0x001C */ CsrWifiRouterCtrlWapiUnicastFilterReqHandler,
+ /* 0x001D */ CsrWifiRouterCtrlWapiUnicastTxPktReqHandler,
+ /* 0x001E */ CsrWifiRouterCtrlWapiFilterReqHandler,
};
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_sef.h b/drivers/staging/csr/csr_wifi_router_ctrl_sef.h
index e0ee5cf45f9..2fb4937bc90 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_sef.h
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_sef.h
@@ -12,10 +12,6 @@
#include "csr_wifi_router_ctrl_prim.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef void (*CsrWifiRouterCtrlStateHandlerType)(void* drvpriv, CsrWifiFsmEvent* msg);
extern const CsrWifiRouterCtrlStateHandlerType CsrWifiRouterCtrlDownstreamStateHandlers[CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT];
@@ -51,8 +47,5 @@ extern "C" {
extern void CsrWifiRouterCtrlWapiUnicastTxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
extern void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
extern void CsrWifiRouterCtrlWapiFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-#ifdef __cplusplus
-}
-#endif
#endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_CTRL_H__ */
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h
index 2c2a229f4bf..c9048386cfc 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h
@@ -17,10 +17,6 @@
#include "csr_wifi_router_ctrl_prim.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
extern void CsrWifiRouterCtrlPfree(void *ptr);
extern u8* CsrWifiRouterCtrlConfigurePowerModeReqSer(u8 *ptr, size_t *len, void *msg);
@@ -333,9 +329,5 @@ extern void* CsrWifiRouterCtrlWapiUnicastTxEncryptIndDes(u8 *buffer, size_t len)
extern size_t CsrWifiRouterCtrlWapiUnicastTxEncryptIndSizeof(void *msg);
extern void CsrWifiRouterCtrlWapiUnicastTxEncryptIndSerFree(void *msg);
-
-#ifdef __cplusplus
-}
-#endif
#endif /* CSR_WIFI_ROUTER_CTRL_SERIALIZE_H__ */
diff --git a/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c b/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c
index de1086d7158..4cd126338e2 100644
--- a/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c
+++ b/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c
@@ -1,10 +1,10 @@
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
- All rights reserved and confidential information of CSR
+ (c) Cambridge Silicon Radio Limited 2011
+ All rights reserved and confidential information of CSR
- Refer to LICENSE.txt included with this source for details
- on the license terms.
+ Refer to LICENSE.txt included with this source for details
+ on the license terms.
*****************************************************************************/
@@ -26,28 +26,22 @@
*----------------------------------------------------------------------------*/
void CsrWifiRouterFreeUpstreamMessageContents(u16 eventClass, void *message)
{
- if (eventClass != CSR_WIFI_ROUTER_PRIM)
- {
- return;
- }
- if (NULL == message)
- {
- return;
- }
-
- switch (*((CsrWifiRouterPrim *) message))
- {
- case CSR_WIFI_ROUTER_MA_PACKET_IND:
- {
- CsrWifiRouterMaPacketInd *p = (CsrWifiRouterMaPacketInd *)message;
- kfree(p->frame);
- p->frame = NULL;
- break;
- }
-
- default:
- break;
- }
+ if (eventClass != CSR_WIFI_ROUTER_PRIM)
+ return;
+ if (NULL == message)
+ return;
+ switch (*((CsrWifiRouterPrim *) message)) {
+ case CSR_WIFI_ROUTER_MA_PACKET_IND:
+ {
+ CsrWifiRouterMaPacketInd *p =
+ (CsrWifiRouterMaPacketInd *) message;
+ kfree(p->frame);
+ p->frame = NULL;
+ break;
+ }
+ default:
+ break;
+ }
}
diff --git a/drivers/staging/csr/csr_wifi_router_lib.h b/drivers/staging/csr/csr_wifi_router_lib.h
index 06a2214714b..b0477c413aa 100644
--- a/drivers/staging/csr/csr_wifi_router_lib.h
+++ b/drivers/staging/csr/csr_wifi_router_lib.h
@@ -22,11 +22,6 @@
#include "csr_wifi_router_prim.h"
#include "csr_wifi_router_task.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*----------------------------------------------------------------------------*
* CsrWifiRouterFreeUpstreamMessageContents
*
@@ -419,9 +414,4 @@ extern const char *CsrWifiRouterDownstreamPrimNames[CSR_WIFI_ROUTER_PRIM_DOWNSTR
#define CsrWifiRouterMaPacketUnsubscribeCfmSend(dst__, interfaceTag__, status__) \
CsrWifiRouterMaPacketUnsubscribeCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, interfaceTag__, status__)
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_ROUTER_LIB_H__ */
diff --git a/drivers/staging/csr/csr_wifi_router_prim.h b/drivers/staging/csr/csr_wifi_router_prim.h
index c61486fbb6d..c52344b51f2 100644
--- a/drivers/staging/csr/csr_wifi_router_prim.h
+++ b/drivers/staging/csr/csr_wifi_router_prim.h
@@ -20,10 +20,6 @@
#include "csr_result.h"
#include "csr_wifi_fsm_event.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#define CSR_WIFI_ROUTER_PRIM (0x0400)
typedef CsrPrim CsrWifiRouterPrim;
@@ -421,10 +417,5 @@ typedef struct
u16 rate;
} CsrWifiRouterMaPacketInd;
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_ROUTER_PRIM_H__ */
diff --git a/drivers/staging/csr/csr_wifi_router_sef.h b/drivers/staging/csr/csr_wifi_router_sef.h
index 49dd158fa98..86692c7780c 100644
--- a/drivers/staging/csr/csr_wifi_router_sef.h
+++ b/drivers/staging/csr/csr_wifi_router_sef.h
@@ -12,10 +12,6 @@
#include "csr_wifi_router_prim.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef void (*CsrWifiRouterStateHandlerType)(void* drvpriv, CsrWifiFsmEvent* msg);
extern const CsrWifiRouterStateHandlerType CsrWifiRouterDownstreamStateHandlers[CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT];
@@ -26,8 +22,4 @@ extern "C" {
extern void CsrWifiRouterMaPacketResHandler(void* drvpriv, CsrWifiFsmEvent* msg);
extern void CsrWifiRouterMaPacketCancelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_H__ */
diff --git a/drivers/staging/csr/csr_wifi_router_serialize.h b/drivers/staging/csr/csr_wifi_router_serialize.h
index 07e21b2b436..94ccdac5606 100644
--- a/drivers/staging/csr/csr_wifi_router_serialize.h
+++ b/drivers/staging/csr/csr_wifi_router_serialize.h
@@ -16,10 +16,6 @@
#include "csr_wifi_msgconv.h"
#include "csr_wifi_router_prim.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
extern void CsrWifiRouterPfree(void *ptr);
extern u8* CsrWifiRouterMaPacketSubscribeReqSer(u8 *ptr, size_t *len, void *msg);
@@ -67,9 +63,5 @@ extern void* CsrWifiRouterMaPacketIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiRouterMaPacketIndSizeof(void *msg);
extern void CsrWifiRouterMaPacketIndSerFree(void *msg);
-
-#ifdef __cplusplus
-}
-#endif
#endif /* CSR_WIFI_ROUTER_SERIALIZE_H__ */
diff --git a/drivers/staging/csr/csr_wifi_router_task.h b/drivers/staging/csr/csr_wifi_router_task.h
index 4e51fae4cda..9ba892f34e6 100644
--- a/drivers/staging/csr/csr_wifi_router_task.h
+++ b/drivers/staging/csr/csr_wifi_router_task.h
@@ -15,19 +15,11 @@
#include "csr_sched.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#define CSR_WIFI_ROUTER_LOG_ID 0x1201FFFF
extern CsrSchedQid CSR_WIFI_ROUTER_IFACEQUEUE;
void CsrWifiRouterInit(void **gash);
void CsrWifiRouterDeinit(void **gash);
void CsrWifiRouterHandler(void **gash);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_ROUTER_TASK_H__ */
diff --git a/drivers/staging/csr/csr_wifi_sme_ap_lib.h b/drivers/staging/csr/csr_wifi_sme_ap_lib.h
index 350cb9ec301..48ea9143f59 100644
--- a/drivers/staging/csr/csr_wifi_sme_ap_lib.h
+++ b/drivers/staging/csr/csr_wifi_sme_ap_lib.h
@@ -22,11 +22,6 @@
#include "csr_wifi_sme_ap_prim.h"
#include "csr_wifi_sme_task.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef CSR_WIFI_AP_ENABLE
#error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_sme_ap_lib.h
#endif
@@ -776,8 +771,4 @@ extern const char *CsrWifiSmeApDownstreamPrimNames[CSR_WIFI_SME_AP_PRIM_DOWNSTRE
CsrWifiSmeApWpsRegistrationStartedCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__)
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_SME_AP_LIB_H__ */
diff --git a/drivers/staging/csr/csr_wifi_sme_ap_prim.h b/drivers/staging/csr/csr_wifi_sme_ap_prim.h
index 93b64e9154c..3c4bcbc1612 100644
--- a/drivers/staging/csr/csr_wifi_sme_ap_prim.h
+++ b/drivers/staging/csr/csr_wifi_sme_ap_prim.h
@@ -20,10 +20,6 @@
#include "csr_wifi_fsm_event.h"
#include "csr_wifi_sme_prim.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef CSR_WIFI_AP_ENABLE
#error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_sme_ap_prim.h
#endif
@@ -1030,9 +1026,5 @@ typedef struct
} CsrWifiSmeApBaDeleteCfm;
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_SME_AP_PRIM_H__ */
diff --git a/drivers/staging/csr/csr_wifi_sme_converter_init.h b/drivers/staging/csr/csr_wifi_sme_converter_init.h
index fb895dec768..ba5e4b44bb6 100644
--- a/drivers/staging/csr/csr_wifi_sme_converter_init.h
+++ b/drivers/staging/csr/csr_wifi_sme_converter_init.h
@@ -13,10 +13,6 @@
#ifndef CSR_WIFI_SME_CONVERTER_INIT_H__
#define CSR_WIFI_SME_CONVERTER_INIT_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef EXCLUDE_CSR_WIFI_SME_MODULE
#include "csr_msgconv.h"
@@ -35,8 +31,4 @@ extern void CsrWifiSmeConverterInit(void);
#endif /* EXCLUDE_CSR_WIFI_SME_MODULE */
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_SME_CONVERTER_INIT_H__ */
diff --git a/drivers/staging/csr/csr_wifi_sme_lib.h b/drivers/staging/csr/csr_wifi_sme_lib.h
index 3ca74560825..53cf1268286 100644
--- a/drivers/staging/csr/csr_wifi_sme_lib.h
+++ b/drivers/staging/csr/csr_wifi_sme_lib.h
@@ -32,11 +32,6 @@
# endif
#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*----------------------------------------------------------------------------*
* CsrWifiSmeFreeUpstreamMessageContents
*
@@ -4305,9 +4300,4 @@ extern const char *CsrWifiSmeDownstreamPrimNames[CSR_WIFI_SME_PRIM_DOWNSTREAM_CO
#define CsrWifiSmeWpsConfigurationCfmSend(dst__, status__) \
CsrWifiSmeWpsConfigurationCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_SME_LIB_H__ */
diff --git a/drivers/staging/csr/csr_wifi_sme_prim.h b/drivers/staging/csr/csr_wifi_sme_prim.h
index 55cac5059bf..17ec79c77e5 100644
--- a/drivers/staging/csr/csr_wifi_sme_prim.h
+++ b/drivers/staging/csr/csr_wifi_sme_prim.h
@@ -20,10 +20,6 @@
#include "csr_result.h"
#include "csr_wifi_fsm_event.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#define CSR_WIFI_SME_PRIM (0x0404)
typedef CsrPrim CsrWifiSmePrim;
@@ -6510,10 +6506,5 @@ typedef struct
CsrResult status;
} CsrWifiSmeWpsConfigurationCfm;
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_SME_PRIM_H__ */
diff --git a/drivers/staging/csr/csr_wifi_sme_sef.h b/drivers/staging/csr/csr_wifi_sme_sef.h
index c8741811b2e..78b88c06723 100644
--- a/drivers/staging/csr/csr_wifi_sme_sef.h
+++ b/drivers/staging/csr/csr_wifi_sme_sef.h
@@ -1,10 +1,10 @@
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2010
- Confidential information of CSR
+ (c) Cambridge Silicon Radio Limited 2010
+ Confidential information of CSR
- Refer to LICENSE.txt included with this source for details
- on the license terms.
+ Refer to LICENSE.txt included with this source for details
+ on the license terms.
*****************************************************************************/
#ifndef CSR_WIFI_ROUTER_SEF_CSR_WIFI_SME_H__
@@ -12,90 +12,131 @@
#include "csr_wifi_sme_prim.h"
+typedef void (*CsrWifiSmeStateHandlerType)(void *drvpriv, CsrWifiFsmEvent *msg);
-#ifdef __cplusplus
-extern "C" {
-#endif
+extern const CsrWifiSmeStateHandlerType
+ CsrWifiSmeUpstreamStateHandlers[CSR_WIFI_SME_PRIM_UPSTREAM_COUNT];
-typedef void (*CsrWifiSmeStateHandlerType)(void* drvpriv, CsrWifiFsmEvent* msg);
-extern const CsrWifiSmeStateHandlerType CsrWifiSmeUpstreamStateHandlers[CSR_WIFI_SME_PRIM_UPSTREAM_COUNT];
-
-
-extern void CsrWifiSmeActivateCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeAdhocConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeAdhocConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeAssociationCompleteIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeAssociationStartIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeBlacklistCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeCalibrationDataGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeCalibrationDataSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeCcxConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeCcxConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeCoexConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeCoexConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeCoexInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeConnectCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeConnectionConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeConnectionInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeConnectionQualityIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeConnectionStatsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeDeactivateCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeDisconnectCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeEventMaskSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeHostConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeHostConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeIbssStationIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeKeyCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeLinkQualityGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeMediaStatusIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeMibConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeMibConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeMibGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeMibGetNextCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeMibSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeMicFailureIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeMulticastAddressCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmePacketFilterSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmePermanentMacAddressGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmePmkidCandidateListIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmePmkidCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmePowerConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmePowerConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeRegulatoryDomainInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeRoamCompleteIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeRoamStartIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeRoamingConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeRoamingConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeScanConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeScanConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeScanFullCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeScanResultIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeScanResultsFlushCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeScanResultsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeSmeStaConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeSmeStaConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeStationMacAddressGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeTspecIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeTspecCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeVersionsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeWifiFlightmodeCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeWifiOffIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeWifiOffCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeWifiOnCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeCloakedSsidsSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeCloakedSsidsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeWifiOnIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeSmeCommonConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeSmeCommonConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeGetInterfaceCapabilityCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeErrorIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeInfoIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeCoreDumpIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiSmeAmpStatusChangeIndHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-
-#ifdef __cplusplus
-}
-#endif
+extern void CsrWifiSmeActivateCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeAdhocConfigGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeAdhocConfigSetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeAssociationCompleteIndHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeAssociationStartIndHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeBlacklistCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeCalibrationDataGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeCalibrationDataSetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeCcxConfigGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeCcxConfigSetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeCoexConfigGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeCoexConfigSetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeCoexInfoGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeConnectCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeConnectionConfigGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeConnectionInfoGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeConnectionQualityIndHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeConnectionStatsGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeDeactivateCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeDisconnectCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeEventMaskSetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeHostConfigGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeHostConfigSetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeIbssStationIndHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeKeyCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeLinkQualityGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeMediaStatusIndHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeMibConfigGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeMibConfigSetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeMibGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeMibGetNextCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeMibSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeMicFailureIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeMulticastAddressCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmePacketFilterSetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmePermanentMacAddressGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmePmkidCandidateListIndHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmePmkidCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmePowerConfigGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmePowerConfigSetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeRegulatoryDomainInfoGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeRoamCompleteIndHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeRoamStartIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeRoamingConfigGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeRoamingConfigSetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeScanConfigGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeScanConfigSetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeScanFullCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeScanResultIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeScanResultsFlushCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeScanResultsGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeSmeStaConfigGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeSmeStaConfigSetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeStationMacAddressGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeTspecIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeTspecCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeVersionsGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeWifiFlightmodeCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeWifiOffIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeWifiOffCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeWifiOnCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeCloakedSsidsSetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeCloakedSsidsGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeWifiOnIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeSmeCommonConfigGetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeSmeCommonConfigSetCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeGetInterfaceCapabilityCfmHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeErrorIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeInfoIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeCoreDumpIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
+extern void CsrWifiSmeAmpStatusChangeIndHandler(void *drvpriv,
+ CsrWifiFsmEvent *msg);
#endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_SME_H__ */
diff --git a/drivers/staging/csr/csr_wifi_sme_serialize.h b/drivers/staging/csr/csr_wifi_sme_serialize.h
index 4f3af0a6be7..f8526269b20 100644
--- a/drivers/staging/csr/csr_wifi_sme_serialize.h
+++ b/drivers/staging/csr/csr_wifi_sme_serialize.h
@@ -1,10 +1,10 @@
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2012
- All rights reserved and confidential information of CSR
+ (c) Cambridge Silicon Radio Limited 2012
+ All rights reserved and confidential information of CSR
- Refer to LICENSE.txt included with this source for details
- on the license terms.
+ Refer to LICENSE.txt included with this source for details
+ on the license terms.
*****************************************************************************/
@@ -16,10 +16,6 @@
#include "csr_wifi_msgconv.h"
#include "csr_wifi_sme_prim.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
extern void CsrWifiSmePfree(void *ptr);
#define CsrWifiSmeActivateReqSer CsrWifiEventSer
@@ -32,13 +28,13 @@ extern void CsrWifiSmePfree(void *ptr);
#define CsrWifiSmeAdhocConfigGetReqSizeof CsrWifiEventSizeof
#define CsrWifiSmeAdhocConfigGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeAdhocConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeAdhocConfigSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeAdhocConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeAdhocConfigSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeAdhocConfigSetReqSizeof(void *msg);
#define CsrWifiSmeAdhocConfigSetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeBlacklistReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeBlacklistReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeBlacklistReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeBlacklistReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeBlacklistReqSizeof(void *msg);
extern void CsrWifiSmeBlacklistReqSerFree(void *msg);
@@ -47,8 +43,8 @@ extern void CsrWifiSmeBlacklistReqSerFree(void *msg);
#define CsrWifiSmeCalibrationDataGetReqSizeof CsrWifiEventSizeof
#define CsrWifiSmeCalibrationDataGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeCalibrationDataSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeCalibrationDataSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeCalibrationDataSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeCalibrationDataSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeCalibrationDataSetReqSizeof(void *msg);
extern void CsrWifiSmeCalibrationDataSetReqSerFree(void *msg);
@@ -57,8 +53,8 @@ extern void CsrWifiSmeCalibrationDataSetReqSerFree(void *msg);
#define CsrWifiSmeCcxConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeCcxConfigGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeCcxConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeCcxConfigSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeCcxConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeCcxConfigSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeCcxConfigSetReqSizeof(void *msg);
#define CsrWifiSmeCcxConfigSetReqSerFree CsrWifiSmePfree
@@ -67,8 +63,8 @@ extern size_t CsrWifiSmeCcxConfigSetReqSizeof(void *msg);
#define CsrWifiSmeCoexConfigGetReqSizeof CsrWifiEventSizeof
#define CsrWifiSmeCoexConfigGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeCoexConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeCoexConfigSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeCoexConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeCoexConfigSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeCoexConfigSetReqSizeof(void *msg);
#define CsrWifiSmeCoexConfigSetReqSerFree CsrWifiSmePfree
@@ -77,8 +73,8 @@ extern size_t CsrWifiSmeCoexConfigSetReqSizeof(void *msg);
#define CsrWifiSmeCoexInfoGetReqSizeof CsrWifiEventSizeof
#define CsrWifiSmeCoexInfoGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeConnectReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeConnectReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeConnectReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeConnectReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeConnectReqSizeof(void *msg);
extern void CsrWifiSmeConnectReqSerFree(void *msg);
@@ -117,13 +113,13 @@ extern void CsrWifiSmeConnectReqSerFree(void *msg);
#define CsrWifiSmeHostConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeHostConfigGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeHostConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeHostConfigSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeHostConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeHostConfigSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeHostConfigSetReqSizeof(void *msg);
#define CsrWifiSmeHostConfigSetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeKeyReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeKeyReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeKeyReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeKeyReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeKeyReqSizeof(void *msg);
#define CsrWifiSmeKeyReqSerFree CsrWifiSmePfree
@@ -137,33 +133,33 @@ extern size_t CsrWifiSmeKeyReqSizeof(void *msg);
#define CsrWifiSmeMibConfigGetReqSizeof CsrWifiEventSizeof
#define CsrWifiSmeMibConfigGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeMibConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeMibConfigSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeMibConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeMibConfigSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeMibConfigSetReqSizeof(void *msg);
#define CsrWifiSmeMibConfigSetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeMibGetNextReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeMibGetNextReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeMibGetNextReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeMibGetNextReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeMibGetNextReqSizeof(void *msg);
extern void CsrWifiSmeMibGetNextReqSerFree(void *msg);
-extern u8* CsrWifiSmeMibGetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeMibGetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeMibGetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeMibGetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeMibGetReqSizeof(void *msg);
extern void CsrWifiSmeMibGetReqSerFree(void *msg);
-extern u8* CsrWifiSmeMibSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeMibSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeMibSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeMibSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeMibSetReqSizeof(void *msg);
extern void CsrWifiSmeMibSetReqSerFree(void *msg);
-extern u8* CsrWifiSmeMulticastAddressReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeMulticastAddressReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeMulticastAddressReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeMulticastAddressReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeMulticastAddressReqSizeof(void *msg);
extern void CsrWifiSmeMulticastAddressReqSerFree(void *msg);
-extern u8* CsrWifiSmePacketFilterSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmePacketFilterSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmePacketFilterSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmePacketFilterSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmePacketFilterSetReqSizeof(void *msg);
extern void CsrWifiSmePacketFilterSetReqSerFree(void *msg);
@@ -172,8 +168,8 @@ extern void CsrWifiSmePacketFilterSetReqSerFree(void *msg);
#define CsrWifiSmePermanentMacAddressGetReqSizeof CsrWifiEventSizeof
#define CsrWifiSmePermanentMacAddressGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmePmkidReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmePmkidReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmePmkidReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmePmkidReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmePmkidReqSizeof(void *msg);
extern void CsrWifiSmePmkidReqSerFree(void *msg);
@@ -182,8 +178,8 @@ extern void CsrWifiSmePmkidReqSerFree(void *msg);
#define CsrWifiSmePowerConfigGetReqSizeof CsrWifiEventSizeof
#define CsrWifiSmePowerConfigGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmePowerConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmePowerConfigSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmePowerConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmePowerConfigSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmePowerConfigSetReqSizeof(void *msg);
#define CsrWifiSmePowerConfigSetReqSerFree CsrWifiSmePfree
@@ -197,8 +193,8 @@ extern size_t CsrWifiSmePowerConfigSetReqSizeof(void *msg);
#define CsrWifiSmeRoamingConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeRoamingConfigGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeRoamingConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeRoamingConfigSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeRoamingConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeRoamingConfigSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeRoamingConfigSetReqSizeof(void *msg);
#define CsrWifiSmeRoamingConfigSetReqSerFree CsrWifiSmePfree
@@ -207,13 +203,13 @@ extern size_t CsrWifiSmeRoamingConfigSetReqSizeof(void *msg);
#define CsrWifiSmeScanConfigGetReqSizeof CsrWifiEventSizeof
#define CsrWifiSmeScanConfigGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeScanConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeScanConfigSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeScanConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeScanConfigSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeScanConfigSetReqSizeof(void *msg);
extern void CsrWifiSmeScanConfigSetReqSerFree(void *msg);
-extern u8* CsrWifiSmeScanFullReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeScanFullReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeScanFullReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeScanFullReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeScanFullReqSizeof(void *msg);
extern void CsrWifiSmeScanFullReqSerFree(void *msg);
@@ -232,8 +228,8 @@ extern void CsrWifiSmeScanFullReqSerFree(void *msg);
#define CsrWifiSmeSmeStaConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeSmeStaConfigGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeSmeStaConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeSmeStaConfigSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeSmeStaConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeSmeStaConfigSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeSmeStaConfigSetReqSizeof(void *msg);
#define CsrWifiSmeSmeStaConfigSetReqSerFree CsrWifiSmePfree
@@ -242,8 +238,8 @@ extern size_t CsrWifiSmeSmeStaConfigSetReqSizeof(void *msg);
#define CsrWifiSmeStationMacAddressGetReqSizeof CsrWifiEventSizeof
#define CsrWifiSmeStationMacAddressGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeTspecReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeTspecReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeTspecReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeTspecReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeTspecReqSizeof(void *msg);
extern void CsrWifiSmeTspecReqSerFree(void *msg);
@@ -252,8 +248,8 @@ extern void CsrWifiSmeTspecReqSerFree(void *msg);
#define CsrWifiSmeVersionsGetReqSizeof CsrWifiEventSizeof
#define CsrWifiSmeVersionsGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeWifiFlightmodeReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeWifiFlightmodeReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeWifiFlightmodeReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeWifiFlightmodeReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeWifiFlightmodeReqSizeof(void *msg);
extern void CsrWifiSmeWifiFlightmodeReqSerFree(void *msg);
@@ -262,13 +258,13 @@ extern void CsrWifiSmeWifiFlightmodeReqSerFree(void *msg);
#define CsrWifiSmeWifiOffReqSizeof CsrWifiEventSizeof
#define CsrWifiSmeWifiOffReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeWifiOnReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeWifiOnReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeWifiOnReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeWifiOnReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeWifiOnReqSizeof(void *msg);
extern void CsrWifiSmeWifiOnReqSerFree(void *msg);
-extern u8* CsrWifiSmeCloakedSsidsSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeCloakedSsidsSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeCloakedSsidsSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeCloakedSsidsSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeCloakedSsidsSetReqSizeof(void *msg);
extern void CsrWifiSmeCloakedSsidsSetReqSerFree(void *msg);
@@ -282,8 +278,8 @@ extern void CsrWifiSmeCloakedSsidsSetReqSerFree(void *msg);
#define CsrWifiSmeSmeCommonConfigGetReqSizeof CsrWifiEventSizeof
#define CsrWifiSmeSmeCommonConfigGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeSmeCommonConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeSmeCommonConfigSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeSmeCommonConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeSmeCommonConfigSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeSmeCommonConfigSetReqSizeof(void *msg);
#define CsrWifiSmeSmeCommonConfigSetReqSerFree CsrWifiSmePfree
@@ -292,13 +288,13 @@ extern size_t CsrWifiSmeSmeCommonConfigSetReqSizeof(void *msg);
#define CsrWifiSmeInterfaceCapabilityGetReqSizeof CsrWifiEventSizeof
#define CsrWifiSmeInterfaceCapabilityGetReqSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeWpsConfigurationReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeWpsConfigurationReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeWpsConfigurationReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeWpsConfigurationReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeWpsConfigurationReqSizeof(void *msg);
extern void CsrWifiSmeWpsConfigurationReqSerFree(void *msg);
-extern u8* CsrWifiSmeSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeSetReqDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeSetReqSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeSetReqDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeSetReqSizeof(void *msg);
extern void CsrWifiSmeSetReqSerFree(void *msg);
@@ -307,8 +303,8 @@ extern void CsrWifiSmeSetReqSerFree(void *msg);
#define CsrWifiSmeActivateCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeActivateCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeAdhocConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeAdhocConfigGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeAdhocConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeAdhocConfigGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeAdhocConfigGetCfmSizeof(void *msg);
#define CsrWifiSmeAdhocConfigGetCfmSerFree CsrWifiSmePfree
@@ -317,23 +313,23 @@ extern size_t CsrWifiSmeAdhocConfigGetCfmSizeof(void *msg);
#define CsrWifiSmeAdhocConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeAdhocConfigSetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeAssociationCompleteIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeAssociationCompleteIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeAssociationCompleteIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeAssociationCompleteIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeAssociationCompleteIndSizeof(void *msg);
extern void CsrWifiSmeAssociationCompleteIndSerFree(void *msg);
-extern u8* CsrWifiSmeAssociationStartIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeAssociationStartIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeAssociationStartIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeAssociationStartIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeAssociationStartIndSizeof(void *msg);
#define CsrWifiSmeAssociationStartIndSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeBlacklistCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeBlacklistCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeBlacklistCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeBlacklistCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeBlacklistCfmSizeof(void *msg);
extern void CsrWifiSmeBlacklistCfmSerFree(void *msg);
-extern u8* CsrWifiSmeCalibrationDataGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeCalibrationDataGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeCalibrationDataGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeCalibrationDataGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeCalibrationDataGetCfmSizeof(void *msg);
extern void CsrWifiSmeCalibrationDataGetCfmSerFree(void *msg);
@@ -342,18 +338,18 @@ extern void CsrWifiSmeCalibrationDataGetCfmSerFree(void *msg);
#define CsrWifiSmeCalibrationDataSetCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeCalibrationDataSetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeCcxConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeCcxConfigGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeCcxConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeCcxConfigGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeCcxConfigGetCfmSizeof(void *msg);
#define CsrWifiSmeCcxConfigGetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeCcxConfigSetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeCcxConfigSetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeCcxConfigSetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeCcxConfigSetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeCcxConfigSetCfmSizeof(void *msg);
#define CsrWifiSmeCcxConfigSetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeCoexConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeCoexConfigGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeCoexConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeCoexConfigGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeCoexConfigGetCfmSizeof(void *msg);
#define CsrWifiSmeCoexConfigGetCfmSerFree CsrWifiSmePfree
@@ -362,33 +358,33 @@ extern size_t CsrWifiSmeCoexConfigGetCfmSizeof(void *msg);
#define CsrWifiSmeCoexConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeCoexConfigSetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeCoexInfoGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeCoexInfoGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeCoexInfoGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeCoexInfoGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeCoexInfoGetCfmSizeof(void *msg);
#define CsrWifiSmeCoexInfoGetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeConnectCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeConnectCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeConnectCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeConnectCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeConnectCfmSizeof(void *msg);
#define CsrWifiSmeConnectCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeConnectionConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeConnectionConfigGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeConnectionConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeConnectionConfigGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeConnectionConfigGetCfmSizeof(void *msg);
extern void CsrWifiSmeConnectionConfigGetCfmSerFree(void *msg);
-extern u8* CsrWifiSmeConnectionInfoGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeConnectionInfoGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeConnectionInfoGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeConnectionInfoGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeConnectionInfoGetCfmSizeof(void *msg);
extern void CsrWifiSmeConnectionInfoGetCfmSerFree(void *msg);
-extern u8* CsrWifiSmeConnectionQualityIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeConnectionQualityIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeConnectionQualityIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeConnectionQualityIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeConnectionQualityIndSizeof(void *msg);
#define CsrWifiSmeConnectionQualityIndSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeConnectionStatsGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeConnectionStatsGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeConnectionStatsGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeConnectionStatsGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeConnectionStatsGetCfmSizeof(void *msg);
#define CsrWifiSmeConnectionStatsGetCfmSerFree CsrWifiSmePfree
@@ -397,8 +393,8 @@ extern size_t CsrWifiSmeConnectionStatsGetCfmSizeof(void *msg);
#define CsrWifiSmeDeactivateCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeDeactivateCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeDisconnectCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeDisconnectCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeDisconnectCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeDisconnectCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeDisconnectCfmSizeof(void *msg);
#define CsrWifiSmeDisconnectCfmSerFree CsrWifiSmePfree
@@ -407,38 +403,38 @@ extern size_t CsrWifiSmeDisconnectCfmSizeof(void *msg);
#define CsrWifiSmeEventMaskSetCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeEventMaskSetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeHostConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeHostConfigGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeHostConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeHostConfigGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeHostConfigGetCfmSizeof(void *msg);
#define CsrWifiSmeHostConfigGetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeHostConfigSetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeHostConfigSetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeHostConfigSetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeHostConfigSetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeHostConfigSetCfmSizeof(void *msg);
#define CsrWifiSmeHostConfigSetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeIbssStationIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeIbssStationIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeIbssStationIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeIbssStationIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeIbssStationIndSizeof(void *msg);
#define CsrWifiSmeIbssStationIndSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeKeyCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeKeyCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeKeyCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeKeyCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeKeyCfmSizeof(void *msg);
#define CsrWifiSmeKeyCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeLinkQualityGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeLinkQualityGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeLinkQualityGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeLinkQualityGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeLinkQualityGetCfmSizeof(void *msg);
#define CsrWifiSmeLinkQualityGetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeMediaStatusIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeMediaStatusIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeMediaStatusIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeMediaStatusIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeMediaStatusIndSizeof(void *msg);
extern void CsrWifiSmeMediaStatusIndSerFree(void *msg);
-extern u8* CsrWifiSmeMibConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeMibConfigGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeMibConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeMibConfigGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeMibConfigGetCfmSizeof(void *msg);
#define CsrWifiSmeMibConfigGetCfmSerFree CsrWifiSmePfree
@@ -447,13 +443,13 @@ extern size_t CsrWifiSmeMibConfigGetCfmSizeof(void *msg);
#define CsrWifiSmeMibConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeMibConfigSetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeMibGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeMibGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeMibGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeMibGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeMibGetCfmSizeof(void *msg);
extern void CsrWifiSmeMibGetCfmSerFree(void *msg);
-extern u8* CsrWifiSmeMibGetNextCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeMibGetNextCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeMibGetNextCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeMibGetNextCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeMibGetNextCfmSizeof(void *msg);
extern void CsrWifiSmeMibGetNextCfmSerFree(void *msg);
@@ -462,38 +458,39 @@ extern void CsrWifiSmeMibGetNextCfmSerFree(void *msg);
#define CsrWifiSmeMibSetCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeMibSetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeMicFailureIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeMicFailureIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeMicFailureIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeMicFailureIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeMicFailureIndSizeof(void *msg);
#define CsrWifiSmeMicFailureIndSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeMulticastAddressCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeMulticastAddressCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeMulticastAddressCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeMulticastAddressCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeMulticastAddressCfmSizeof(void *msg);
extern void CsrWifiSmeMulticastAddressCfmSerFree(void *msg);
-extern u8* CsrWifiSmePacketFilterSetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmePacketFilterSetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmePacketFilterSetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmePacketFilterSetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmePacketFilterSetCfmSizeof(void *msg);
#define CsrWifiSmePacketFilterSetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmePermanentMacAddressGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmePermanentMacAddressGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmePermanentMacAddressGetCfmSer(u8 *ptr, size_t *len,
+ void *msg);
+extern void *CsrWifiSmePermanentMacAddressGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmePermanentMacAddressGetCfmSizeof(void *msg);
#define CsrWifiSmePermanentMacAddressGetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmePmkidCandidateListIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmePmkidCandidateListIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmePmkidCandidateListIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmePmkidCandidateListIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmePmkidCandidateListIndSizeof(void *msg);
extern void CsrWifiSmePmkidCandidateListIndSerFree(void *msg);
-extern u8* CsrWifiSmePmkidCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmePmkidCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmePmkidCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmePmkidCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmePmkidCfmSizeof(void *msg);
extern void CsrWifiSmePmkidCfmSerFree(void *msg);
-extern u8* CsrWifiSmePowerConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmePowerConfigGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmePowerConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmePowerConfigGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmePowerConfigGetCfmSizeof(void *msg);
#define CsrWifiSmePowerConfigGetCfmSerFree CsrWifiSmePfree
@@ -502,33 +499,34 @@ extern size_t CsrWifiSmePowerConfigGetCfmSizeof(void *msg);
#define CsrWifiSmePowerConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmePowerConfigSetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeRegulatoryDomainInfoGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeRegulatoryDomainInfoGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeRegulatoryDomainInfoGetCfmSer(u8 *ptr, size_t *len,
+ void *msg);
+extern void *CsrWifiSmeRegulatoryDomainInfoGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeRegulatoryDomainInfoGetCfmSizeof(void *msg);
#define CsrWifiSmeRegulatoryDomainInfoGetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeRoamCompleteIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeRoamCompleteIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeRoamCompleteIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeRoamCompleteIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeRoamCompleteIndSizeof(void *msg);
#define CsrWifiSmeRoamCompleteIndSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeRoamStartIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeRoamStartIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeRoamStartIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeRoamStartIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeRoamStartIndSizeof(void *msg);
#define CsrWifiSmeRoamStartIndSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeRoamingConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeRoamingConfigGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeRoamingConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeRoamingConfigGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeRoamingConfigGetCfmSizeof(void *msg);
#define CsrWifiSmeRoamingConfigGetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeRoamingConfigSetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeRoamingConfigSetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeRoamingConfigSetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeRoamingConfigSetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeRoamingConfigSetCfmSizeof(void *msg);
#define CsrWifiSmeRoamingConfigSetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeScanConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeScanConfigGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeScanConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeScanConfigGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeScanConfigGetCfmSizeof(void *msg);
extern void CsrWifiSmeScanConfigGetCfmSerFree(void *msg);
@@ -542,8 +540,8 @@ extern void CsrWifiSmeScanConfigGetCfmSerFree(void *msg);
#define CsrWifiSmeScanFullCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeScanFullCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeScanResultIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeScanResultIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeScanResultIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeScanResultIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeScanResultIndSizeof(void *msg);
extern void CsrWifiSmeScanResultIndSerFree(void *msg);
@@ -552,38 +550,39 @@ extern void CsrWifiSmeScanResultIndSerFree(void *msg);
#define CsrWifiSmeScanResultsFlushCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeScanResultsFlushCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeScanResultsGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeScanResultsGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeScanResultsGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeScanResultsGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeScanResultsGetCfmSizeof(void *msg);
extern void CsrWifiSmeScanResultsGetCfmSerFree(void *msg);
-extern u8* CsrWifiSmeSmeStaConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeSmeStaConfigGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeSmeStaConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeSmeStaConfigGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeSmeStaConfigGetCfmSizeof(void *msg);
#define CsrWifiSmeSmeStaConfigGetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeSmeStaConfigSetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeSmeStaConfigSetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeSmeStaConfigSetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeSmeStaConfigSetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeSmeStaConfigSetCfmSizeof(void *msg);
#define CsrWifiSmeSmeStaConfigSetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeStationMacAddressGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeStationMacAddressGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeStationMacAddressGetCfmSer(u8 *ptr, size_t *len,
+ void *msg);
+extern void *CsrWifiSmeStationMacAddressGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeStationMacAddressGetCfmSizeof(void *msg);
#define CsrWifiSmeStationMacAddressGetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeTspecIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeTspecIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeTspecIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeTspecIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeTspecIndSizeof(void *msg);
extern void CsrWifiSmeTspecIndSerFree(void *msg);
-extern u8* CsrWifiSmeTspecCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeTspecCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeTspecCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeTspecCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeTspecCfmSizeof(void *msg);
extern void CsrWifiSmeTspecCfmSerFree(void *msg);
-extern u8* CsrWifiSmeVersionsGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeVersionsGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeVersionsGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeVersionsGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeVersionsGetCfmSizeof(void *msg);
extern void CsrWifiSmeVersionsGetCfmSerFree(void *msg);
@@ -612,18 +611,18 @@ extern void CsrWifiSmeVersionsGetCfmSerFree(void *msg);
#define CsrWifiSmeCloakedSsidsSetCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeCloakedSsidsSetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeCloakedSsidsGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeCloakedSsidsGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeCloakedSsidsGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeCloakedSsidsGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeCloakedSsidsGetCfmSizeof(void *msg);
extern void CsrWifiSmeCloakedSsidsGetCfmSerFree(void *msg);
-extern u8* CsrWifiSmeWifiOnIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeWifiOnIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeWifiOnIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeWifiOnIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeWifiOnIndSizeof(void *msg);
#define CsrWifiSmeWifiOnIndSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeSmeCommonConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeSmeCommonConfigGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeSmeCommonConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeSmeCommonConfigGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeSmeCommonConfigGetCfmSizeof(void *msg);
#define CsrWifiSmeSmeCommonConfigGetCfmSerFree CsrWifiSmePfree
@@ -632,23 +631,24 @@ extern size_t CsrWifiSmeSmeCommonConfigGetCfmSizeof(void *msg);
#define CsrWifiSmeSmeCommonConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeSmeCommonConfigSetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeInterfaceCapabilityGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeInterfaceCapabilityGetCfmDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeInterfaceCapabilityGetCfmSer(u8 *ptr, size_t *len,
+ void *msg);
+extern void *CsrWifiSmeInterfaceCapabilityGetCfmDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeInterfaceCapabilityGetCfmSizeof(void *msg);
#define CsrWifiSmeInterfaceCapabilityGetCfmSerFree CsrWifiSmePfree
-extern u8* CsrWifiSmeErrorIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeErrorIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeErrorIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeErrorIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeErrorIndSizeof(void *msg);
extern void CsrWifiSmeErrorIndSerFree(void *msg);
-extern u8* CsrWifiSmeInfoIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeInfoIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeInfoIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeInfoIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeInfoIndSizeof(void *msg);
extern void CsrWifiSmeInfoIndSerFree(void *msg);
-extern u8* CsrWifiSmeCoreDumpIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiSmeCoreDumpIndDes(u8 *buffer, size_t len);
+extern u8 *CsrWifiSmeCoreDumpIndSer(u8 *ptr, size_t *len, void *msg);
+extern void *CsrWifiSmeCoreDumpIndDes(u8 *buffer, size_t len);
extern size_t CsrWifiSmeCoreDumpIndSizeof(void *msg);
extern void CsrWifiSmeCoreDumpIndSerFree(void *msg);
@@ -662,9 +662,5 @@ extern void CsrWifiSmeCoreDumpIndSerFree(void *msg);
#define CsrWifiSmeWpsConfigurationCfmSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiSmeWpsConfigurationCfmSerFree CsrWifiSmePfree
-
-#ifdef __cplusplus
-}
-#endif
#endif /* CSR_WIFI_SME_SERIALIZE_H__ */
diff --git a/drivers/staging/csr/csr_wifi_sme_task.h b/drivers/staging/csr/csr_wifi_sme_task.h
index 0f725e45493..1e938c1fa96 100644
--- a/drivers/staging/csr/csr_wifi_sme_task.h
+++ b/drivers/staging/csr/csr_wifi_sme_task.h
@@ -1,10 +1,10 @@
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
- All rights reserved and confidential information of CSR
+ (c) Cambridge Silicon Radio Limited 2011
+ All rights reserved and confidential information of CSR
- Refer to LICENSE.txt included with this source for details
- on the license terms.
+ Refer to LICENSE.txt included with this source for details
+ on the license terms.
*****************************************************************************/
@@ -15,19 +15,11 @@
#include "csr_sched.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#define CSR_WIFI_SME_LOG_ID 0x1202FFFF
extern CsrSchedQid CSR_WIFI_SME_IFACEQUEUE;
void CsrWifiSmeInit(void **gash);
void CsrWifiSmeDeinit(void **gash);
void CsrWifiSmeHandler(void **gash);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_SME_TASK_H__ */
diff --git a/drivers/staging/csr/csr_wifi_vif_utils.h b/drivers/staging/csr/csr_wifi_vif_utils.h
index 523172d1ac9..8ff97888996 100644
--- a/drivers/staging/csr/csr_wifi_vif_utils.h
+++ b/drivers/staging/csr/csr_wifi_vif_utils.h
@@ -11,10 +11,6 @@
#ifndef CSR_WIFI_VIF_UTILS_H
#define CSR_WIFI_VIF_UTILS_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* STANDARD INCLUDES ********************************************************/
/* PROJECT INCLUDES *********************************************************/
@@ -27,82 +23,5 @@ extern "C" {
#define CSR_WIFI_NUM_INTERFACES (u8)0x1
#define CSR_WIFI_INTERFACE_IN_USE (u16)0x0
-/* This is used at places where interface Id isn't available*/
-#define CSR_WIFI_INTERFACE_ZERO 0
-#define CSR_WIFI_INTERFACE_STA 0
-#define CSR_WIFI_INTERFACE_AMP 0
-
-
-#define CSR_WIFI_VIF_UTILS_UNDEFINED_TAG 0xFFFF
-
-/* Extract the Interface Id from the event */
-#define CsrWifiVifUtilsGetVifTagFromEvent(msg) \
- ((u16) * ((u16 *) ((u8 *) (msg) + sizeof(CsrWifiFsmEvent))))
-
-/* The HPI Vif combines the type and the interface id */
-#define CsrWifiVifUtilsGetVifTagFromHipEvent(msg) \
- ((msg)->virtualInterfaceIdentifier & 0x00FF)
-
-#define CsrWifiVifUtilsPackHipEventVif(type, interfaceId) \
- ((u16)((interfaceId) | ((type) << 8)))
-
-
-/* TYPES DEFINITIONS ********************************************************/
-
-/* GLOBAL VARIABLE DECLARATIONS *********************************************/
-
-/* PUBLIC FUNCTION PROTOTYPES ***********************************************/
-
-/**
- * @brief
- * First checks if the mode is supported capability bitmap of the interface.
- * If this succeeds, then checks if running this mode on this interface is allowed.
- *
- * @param[in] u8 : interface capability bitmap
- * @param[in] u8* : pointer to the array of current interface modes
- * @param[in] u16 : interfaceTag
- * @param[in] CsrWifiInterfaceMode : mode
- *
- * @return
- * u8 : returns true if the interface is allowed to operate in the mode otherwise false.
- */
-extern u8 CsrWifiVifUtilsCheckCompatibility(u8 interfaceCapability,
- u8 *currentInterfaceModes,
- u16 interfaceTag,
- CsrWifiInterfaceMode mode);
-
-/**
- * @brief
- * Checks if the specified interface is supported.
- * NOTE: Only checks that the interface is supported, no checks are made to
- * determine whether a supported interface may be made active.
- *
- * @param[in] u16 : interfaceTag
- *
- * @return
- * u8 : returns true if the interface is supported, otherwise false.
- */
-extern u8 CsrWifiVifUtilsIsSupported(u16 interfaceTag);
-
-#ifdef CSR_LOG_ENABLE
-/**
- * @brief
- * Registers the virtual interface utils logging details.
- * Should only be called once at initialisation.
- *
- * @param[in/out] None
- *
- * @return
- * None
- */
-void CsrWifiVifUtilsLogTextRegister(void);
-#else
-#define CsrWifiVifUtilsLogTextRegister()
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* CSR_WIFI_VIF_UTILS_H */
diff --git a/drivers/staging/csr/data_tx.c b/drivers/staging/csr/data_tx.c
index 8ed7a7845cc..9e3d8b8ab02 100644
--- a/drivers/staging/csr/data_tx.c
+++ b/drivers/staging/csr/data_tx.c
@@ -18,33 +18,30 @@
int
uf_verify_m4(unifi_priv_t *priv, const unsigned char *packet, unsigned int length)
{
- const unsigned char *p = packet;
- u16 keyinfo;
+ const unsigned char *p = packet;
+ u16 keyinfo;
- if (length < (4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1 + 8)) {
- return 1;
- }
+ if (length < (4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1 + 8))
+ return 1;
- p += 8;
- keyinfo = p[5] << 8 | p[6]; /* big-endian */
- if (
- (p[0] == 1 || p[0] == 2) /* protocol version 802.1X-2001 (WPA) or -2004 (WPA2) */ &&
- p[1] == 3 /* EAPOL-Key */ &&
- /* don't bother checking p[2] p[3] (hh ll, packet body length) */
- (p[4] == 254 || p[4] == 2) /* descriptor type P802.1i-D3.0 (WPA) or 802.11i-2004 (WPA2) */ &&
- ((keyinfo & 0x0007) == 1 || (keyinfo & 0x0007) == 2) /* key descriptor version */ &&
- (keyinfo & ~0x0207U) == 0x0108 && /* key info for 4/4 or 4/2 -- ignore key desc version and sec bit (since varies in WPA 4/4) */
- (p[4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 0] == 0 && /* key data length (2 octets) 0 for 4/4 only */
- p[4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1] == 0)
- ) {
- unifi_trace(priv, UDBG1, "uf_verify_m4: M4 detected \n");
- return 0;
- }
- else
- {
- return 1;
- }
+ p += 8;
+ keyinfo = p[5] << 8 | p[6]; /* big-endian */
+ if (
+ (p[0] == 1 || p[0] == 2) /* protocol version 802.1X-2001 (WPA) or -2004 (WPA2) */ &&
+ p[1] == 3 /* EAPOL-Key */ &&
+ /* don't bother checking p[2] p[3] (hh ll, packet body length) */
+ (p[4] == 254 || p[4] == 2) /* descriptor type P802.1i-D3.0 (WPA) or 802.11i-2004 (WPA2) */ &&
+ ((keyinfo & 0x0007) == 1 || (keyinfo & 0x0007) == 2) /* key descriptor version */ &&
+ (keyinfo & ~0x0207U) == 0x0108 && /* key info for 4/4 or 4/2 -- ignore key desc version and sec bit (since varies in WPA 4/4) */
+ (p[4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 0] == 0 && /* key data length (2 octets) 0 for 4/4 only */
+ p[4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1] == 0)
+ ) {
+ unifi_trace(priv, UDBG1, "uf_verify_m4: M4 detected\n");
+ return 0;
+ } else {
+ return 1;
+ }
}
/*
diff --git a/drivers/staging/csr/drv.c b/drivers/staging/csr/drv.c
index 249758076a7..4780c32c2fe 100644
--- a/drivers/staging/csr/drv.c
+++ b/drivers/staging/csr/drv.c
@@ -166,33 +166,32 @@ s32 CsrHipResultToStatus(CsrResult csrResult)
static const char*
trace_putest_cmdid(unifi_putest_command_t putest_cmd)
{
- switch (putest_cmd)
- {
- case UNIFI_PUTEST_START:
- return "START";
- case UNIFI_PUTEST_STOP:
- return "STOP";
- case UNIFI_PUTEST_SET_SDIO_CLOCK:
- return "SET CLOCK";
- case UNIFI_PUTEST_CMD52_READ:
- return "CMD52R";
- case UNIFI_PUTEST_CMD52_BLOCK_READ:
- return "CMD52BR";
- case UNIFI_PUTEST_CMD52_WRITE:
- return "CMD52W";
- case UNIFI_PUTEST_DL_FW:
- return "D/L FW";
- case UNIFI_PUTEST_DL_FW_BUFF:
- return "D/L FW BUFFER";
- case UNIFI_PUTEST_COREDUMP_PREPARE:
- return "PREPARE COREDUMP";
- case UNIFI_PUTEST_GP_READ16:
- return "GP16R";
- case UNIFI_PUTEST_GP_WRITE16:
- return "GP16W";
- default:
- return "ERROR: unrecognised command";
- }
+ switch (putest_cmd) {
+ case UNIFI_PUTEST_START:
+ return "START";
+ case UNIFI_PUTEST_STOP:
+ return "STOP";
+ case UNIFI_PUTEST_SET_SDIO_CLOCK:
+ return "SET CLOCK";
+ case UNIFI_PUTEST_CMD52_READ:
+ return "CMD52R";
+ case UNIFI_PUTEST_CMD52_BLOCK_READ:
+ return "CMD52BR";
+ case UNIFI_PUTEST_CMD52_WRITE:
+ return "CMD52W";
+ case UNIFI_PUTEST_DL_FW:
+ return "D/L FW";
+ case UNIFI_PUTEST_DL_FW_BUFF:
+ return "D/L FW BUFFER";
+ case UNIFI_PUTEST_COREDUMP_PREPARE:
+ return "PREPARE COREDUMP";
+ case UNIFI_PUTEST_GP_READ16:
+ return "GP16R";
+ case UNIFI_PUTEST_GP_WRITE16:
+ return "GP16W";
+ default:
+ return "ERROR: unrecognised command";
+ }
}
#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
@@ -266,8 +265,6 @@ unifi_open(struct inode *inode, struct file *file)
unifi_priv_t *priv;
ul_client_t *udi_cli;
- func_enter();
-
devno = MINOR(inode->i_rdev) >> 1;
/*
@@ -278,7 +275,6 @@ unifi_open(struct inode *inode, struct file *file)
priv = uf_get_instance(devno);
if (priv == NULL) {
unifi_error(NULL, "unifi_open: No device present\n");
- func_exit();
return -ENODEV;
}
@@ -290,7 +286,6 @@ unifi_open(struct inode *inode, struct file *file)
/* Too many clients already using this device */
unifi_error(priv, "Too many clients already open\n");
uf_put_instance(devno);
- func_exit();
return -ENOSPC;
}
unifi_trace(priv, UDBG1, "Client is registered to /dev/unifiudi%d\n", devno);
@@ -310,7 +305,6 @@ unifi_open(struct inode *inode, struct file *file)
uf_put_instance(devno);
unifi_info(priv, "There is already a configuration client using the character device\n");
- func_exit();
return -EBUSY;
}
#endif /* CSR_SME_USERSPACE */
@@ -331,7 +325,6 @@ unifi_open(struct inode *inode, struct file *file)
uf_put_instance(devno);
unifi_error(priv, "Too many clients already open\n");
- func_exit();
return -ENOSPC;
}
@@ -357,7 +350,6 @@ unifi_open(struct inode *inode, struct file *file)
*/
file->private_data = udi_cli;
- func_exit();
return 0;
} /* unifi_open() */
@@ -369,8 +361,6 @@ unifi_release(struct inode *inode, struct file *filp)
int devno;
unifi_priv_t *priv;
- func_enter();
-
priv = uf_find_instance(udi_cli->instance);
if (!priv) {
unifi_error(priv, "unifi_close: instance for device not found\n");
@@ -465,8 +455,6 @@ unifi_read(struct file *filp, char *p, size_t len, loff_t *poff)
struct list_head *l;
int msglen;
- func_enter();
-
priv = uf_find_instance(pcli->instance);
if (!priv) {
unifi_error(priv, "invalid priv\n");
@@ -527,7 +515,6 @@ unifi_read(struct file *filp, char *p, size_t len, loff_t *poff)
/* It is our resposibility to free the message buffer. */
kfree(logptr);
- func_exit_r(msglen);
return msglen;
} /* unifi_read() */
@@ -615,7 +602,6 @@ udi_send_signal_unpacked(unifi_priv_t *priv, unsigned char* data, uint data_len)
unifi_net_data_free(priv, &bulk_data.d[i]);
}
}
- func_exit();
return -EIO;
}
@@ -654,8 +640,6 @@ udi_send_signal_raw(unifi_priv_t *priv, unsigned char *buf, int buflen)
int bytecount;
CsrResult csrResult;
- func_enter();
-
/*
* The signal is the first thing in buf, the signal id is the
* first 16 bits of the signal.
@@ -668,7 +652,6 @@ udi_send_signal_raw(unifi_priv_t *priv, unsigned char *buf, int buflen)
if ((signal_size <= 0) || (signal_size > buflen)) {
unifi_error(priv, "udi_send_signal_raw - Couldn't find length of signal 0x%x\n",
sig_id);
- func_exit();
return -EINVAL;
}
unifi_trace(priv, UDBG2, "udi_send_signal_raw: signal 0x%.4X len:%d\n",
@@ -713,7 +696,6 @@ udi_send_signal_raw(unifi_priv_t *priv, unsigned char *buf, int buflen)
if (bytecount > buflen) {
unifi_error(priv, "udi_send_signal_raw: Not enough data (%d instead of %d)\n", buflen, bytecount);
- func_exit();
return -EINVAL;
}
@@ -721,7 +703,6 @@ udi_send_signal_raw(unifi_priv_t *priv, unsigned char *buf, int buflen)
r = ul_send_signal_raw(priv, buf, signal_size, &data_ptrs);
if (r < 0) {
unifi_error(priv, "udi_send_signal_raw: send failed (%d)\n", r);
- func_exit();
return -EIO;
}
@@ -746,8 +727,6 @@ udi_send_signal_raw(unifi_priv_t *priv, unsigned char *buf, int buflen)
}
#endif
- func_exit_r(bytecount);
-
return bytecount;
} /* udi_send_signal_raw */
@@ -784,8 +763,6 @@ unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff)
bulk_data_param_t bulkdata;
CsrResult csrResult;
- func_enter();
-
priv = uf_find_instance(pcli->instance);
if (!priv) {
unifi_error(priv, "invalid priv\n");
@@ -812,7 +789,6 @@ unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff)
csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], len);
if (csrResult != CSR_RESULT_SUCCESS) {
unifi_error(priv, "unifi_write: failed to allocate request_data.\n");
- func_exit();
return -ENOMEM;
}
@@ -822,7 +798,6 @@ unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff)
if (copy_from_user((void*)user_data_buf, p, len)) {
unifi_error(priv, "unifi_write: copy from user failed\n");
unifi_net_data_free(priv, &bulkdata.d[0]);
- func_exit();
return -EFAULT;
}
@@ -838,7 +813,6 @@ unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff)
unifi_error(priv, "unifi_write - Couldn't find length of signal 0x%x\n",
sig_id);
unifi_net_data_free(priv, &bulkdata.d[0]);
- func_exit();
return -EINVAL;
}
@@ -849,7 +823,6 @@ unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff)
signal_buf = kmalloc(signal_size, GFP_KERNEL);
if (!signal_buf) {
unifi_net_data_free(priv, &bulkdata.d[0]);
- func_exit();
return -ENOMEM;
}
@@ -948,8 +921,6 @@ unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff)
kfree(buf);
- func_exit_r(bytes_written);
-
return bytes_written;
} /* unifi_write() */
@@ -1657,8 +1628,6 @@ unifi_poll(struct file *filp, poll_table *wait)
unsigned int mask = 0;
int ready;
- func_enter();
-
ready = !list_empty(&pcli->udi_log);
poll_wait(filp, &pcli->udi_wq, wait);
@@ -1667,8 +1636,6 @@ unifi_poll(struct file *filp, poll_table *wait)
mask |= POLLIN | POLLRDNORM; /* readable */
}
- func_exit();
-
return mask;
} /* unifi_poll() */
@@ -1784,8 +1751,6 @@ udi_log_event(ul_client_t *pcli,
unsigned long n_1000;
#endif
- func_enter();
-
/* Just a sanity check */
if ((signal == NULL) || (signal_len <= 0)) {
return;
@@ -1901,7 +1866,6 @@ udi_log_event(ul_client_t *pcli,
if (down_interruptible(&pcli->udi_sem)) {
printk(KERN_WARNING "udi_log_event_q: Failed to get udi sem\n");
kfree(logptr);
- func_exit();
return;
}
list_add_tail(&logptr->q, &pcli->udi_log);
@@ -1910,7 +1874,6 @@ udi_log_event(ul_client_t *pcli,
/* Wake any waiting user process */
wake_up_interruptible(&pcli->udi_wq);
- func_exit();
} /* udi_log_event() */
#ifdef CSR_SME_USERSPACE
@@ -1921,8 +1884,6 @@ uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length)
udi_msg_t *msgptr;
u8 *p;
- func_enter();
-
/* Just a sanity check */
if ((buffer == NULL) || (length <= 0)) {
return -EINVAL;
@@ -1968,8 +1929,6 @@ uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length)
/* It is our responsibility to free the buffer allocated in build_packed_*() */
kfree(buffer);
- func_exit();
-
return 0;
} /* uf_sme_queue_message() */
@@ -2059,10 +2018,10 @@ int uf_create_device_nodes(unifi_priv_t *priv, int bus_id)
void uf_destroy_device_nodes(unifi_priv_t *priv)
{
- device_destroy(unifi_class, priv->unifiudi_cdev.dev);
- device_destroy(unifi_class, priv->unifi_cdev.dev);
- cdev_del(&priv->unifiudi_cdev);
- cdev_del(&priv->unifi_cdev);
+ device_destroy(unifi_class, priv->unifiudi_cdev.dev);
+ device_destroy(unifi_class, priv->unifi_cdev.dev);
+ cdev_del(&priv->unifiudi_cdev);
+ cdev_del(&priv->unifi_cdev);
}
diff --git a/drivers/staging/csr/firmware.c b/drivers/staging/csr/firmware.c
index b6d8a6e5291..b42a4d6a0c3 100644
--- a/drivers/staging/csr/firmware.c
+++ b/drivers/staging/csr/firmware.c
@@ -62,8 +62,6 @@ unifi_fw_read_start(void *ospriv, s8 is_fw, const card_info_t *info)
unifi_priv_t *priv = (unifi_priv_t*)ospriv;
CSR_UNUSED(info);
- func_enter();
-
if (is_fw == UNIFI_FW_STA) {
/* F/w may have been released after a previous successful download. */
if (priv->fw_sta.dl_data == NULL) {
@@ -72,7 +70,6 @@ unifi_fw_read_start(void *ospriv, s8 is_fw, const card_info_t *info)
}
/* Set up callback struct for readfunc() */
if (priv->fw_sta.dl_data != NULL) {
- func_exit();
return &priv->fw_sta;
}
@@ -80,7 +77,6 @@ unifi_fw_read_start(void *ospriv, s8 is_fw, const card_info_t *info)
unifi_error(priv, "downloading firmware... unknown request: %d\n", is_fw);
}
- func_exit();
return NULL;
} /* unifi_fw_read_start() */
@@ -105,7 +101,6 @@ unifi_fw_read_stop(void *ospriv, void *dlpriv)
{
unifi_priv_t *priv = (unifi_priv_t*)ospriv;
struct dlpriv *dl_struct = (struct dlpriv *)dlpriv;
- func_enter();
if (dl_struct != NULL) {
if (dl_struct->dl_data != NULL) {
@@ -115,7 +110,6 @@ unifi_fw_read_stop(void *ospriv, void *dlpriv)
uf_release_firmware(priv, dl_struct);
}
- func_exit();
} /* unifi_fw_read_stop() */
@@ -143,17 +137,14 @@ void *
unifi_fw_open_buffer(void *ospriv, void *fwbuf, u32 len)
{
unifi_priv_t *priv = (unifi_priv_t*)ospriv;
- func_enter();
if (fwbuf == NULL) {
- func_exit();
return NULL;
}
priv->fw_conv.dl_data = fwbuf;
priv->fw_conv.dl_len = len;
priv->fw_conv.fw_desc = NULL; /* No OS f/w resource is associated */
- func_exit();
return &priv->fw_conv;
}
@@ -242,8 +233,6 @@ unifi_fw_read(void *ospriv, void *arg, u32 offset, void *buf, u32 len)
int
uf_run_unifihelper(unifi_priv_t *priv)
{
-#ifdef CONFIG_HOTPLUG
-
#ifdef ANDROID_BUILD
char *prog = "/system/bin/unififw";
#else
@@ -289,10 +278,6 @@ uf_run_unifihelper(unifi_priv_t *priv)
r = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
return r;
-#else
- unifi_trace(priv, UDBG1, "Can't automatically download firmware because kernel does not have HOTPLUG\n");
- return -1;
-#endif
} /* uf_run_unifihelper() */
#ifdef CSR_WIFI_SPLIT_PATCH
diff --git a/drivers/staging/csr/inet.c b/drivers/staging/csr/inet.c
index b4acb54ecc6..b3ef818fef3 100644
--- a/drivers/staging/csr/inet.c
+++ b/drivers/staging/csr/inet.c
@@ -93,14 +93,12 @@ static struct notifier_block uf_inetaddr_notifier = {
void uf_register_inet_notifier(void)
{
- if (atomic_inc_return(&inet_notif_refs) == 1) {
- register_inetaddr_notifier(&uf_inetaddr_notifier);
- }
+ if (atomic_inc_return(&inet_notif_refs) == 1)
+ register_inetaddr_notifier(&uf_inetaddr_notifier);
}
void uf_unregister_inet_notifier(void)
{
- if (atomic_dec_return(&inet_notif_refs) == 0) {
- unregister_inetaddr_notifier(&uf_inetaddr_notifier);
- }
+ if (atomic_dec_return(&inet_notif_refs) == 0)
+ unregister_inetaddr_notifier(&uf_inetaddr_notifier);
}
diff --git a/drivers/staging/csr/io.c b/drivers/staging/csr/io.c
index caf48e3120c..af9c28f073b 100644
--- a/drivers/staging/csr/io.c
+++ b/drivers/staging/csr/io.c
@@ -31,7 +31,6 @@
* ---------------------------------------------------------------------------
*/
#include <linux/proc_fs.h>
-#include <linux/version.h>
#include "csr_wifi_hip_unifi.h"
#include "csr_wifi_hip_unifiversion.h"
@@ -86,7 +85,6 @@ static int uf_read_proc(char *page, char **start, off_t offset, int count,
static CsrResult signal_buffer_init(unifi_priv_t * priv, int size)
{
int i;
- func_enter();
priv->rxSignalBuffer.writePointer =
priv->rxSignalBuffer.readPointer = 0;
@@ -106,11 +104,9 @@ static CsrResult signal_buffer_init(unifi_priv_t * priv, int size)
kfree(priv->rxSignalBuffer.rx_buff[j].bufptr);
priv->rxSignalBuffer.rx_buff[j].bufptr = NULL;
}
- func_exit();
return -1;
}
}
- func_exit();
return 0;
}
@@ -265,8 +261,6 @@ register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev)
int r = -1;
CsrResult csrResult;
- func_enter();
-
if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) {
unifi_error(priv, "register_unifi_sdio: invalid device %d\n",
bus_id);
@@ -415,7 +409,6 @@ register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev)
up(&Unifi_instance_mutex);
- func_exit();
return priv;
failed4:
@@ -449,7 +442,6 @@ failed0:
up(&Unifi_instance_mutex);
- func_exit();
return NULL;
} /* register_unifi_sdio() */
@@ -473,7 +465,6 @@ failed0:
static void
ask_unifi_sdio_cleanup(unifi_priv_t *priv)
{
- func_enter();
/*
* Now clear the flag that says the old instance is in use.
@@ -486,8 +477,6 @@ ask_unifi_sdio_cleanup(unifi_priv_t *priv)
unifi_trace(NULL, UDBG5, "ask_unifi_sdio_cleanup: wake up cleanup workqueue.\n");
wake_up(&Unifi_cleanup_wq);
- func_exit();
-
} /* ask_unifi_sdio_cleanup() */
@@ -511,8 +500,6 @@ cleanup_unifi_sdio(unifi_priv_t *priv)
int i;
static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
- func_enter();
-
/* Remove the device nodes */
uf_destroy_device_nodes(priv);
@@ -604,8 +591,6 @@ cleanup_unifi_sdio(unifi_priv_t *priv)
unifi_trace(NULL, UDBG5, "cleanup_unifi_sdio: DONE.\n");
- func_exit();
-
} /* cleanup_unifi_sdio() */
@@ -639,7 +624,6 @@ unregister_unifi_sdio(int bus_id)
if (priv == NULL) {
unifi_error(priv, "unregister_unifi_sdio: device %d is not registered\n",
bus_id);
- func_exit();
return;
}
@@ -1016,37 +1000,37 @@ uf_remove_os_device(int bus_id)
static void
uf_sdio_inserted(CsrSdioFunction *sdio_ctx)
{
- unifi_priv_t *priv;
+ unifi_priv_t *priv;
- unifi_trace(NULL, UDBG5, "uf_sdio_inserted(0x%p), slot_id=%d, dev=%p\n",
- sdio_ctx, active_slot, os_devices[active_slot]);
+ unifi_trace(NULL, UDBG5, "uf_sdio_inserted(0x%p), slot_id=%d, dev=%p\n",
+ sdio_ctx, active_slot, os_devices[active_slot]);
- priv = register_unifi_sdio(sdio_ctx, active_slot, os_devices[active_slot]);
- if (priv == NULL) {
- CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_FAILURE);
- return;
- }
+ priv = register_unifi_sdio(sdio_ctx, active_slot, os_devices[active_slot]);
+ if (priv == NULL) {
+ CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_FAILURE);
+ return;
+ }
- sdio_ctx->driverData = priv;
+ sdio_ctx->driverData = priv;
- CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS);
+ CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS);
} /* uf_sdio_inserted() */
static void
uf_sdio_removed(CsrSdioFunction *sdio_ctx)
{
- unregister_unifi_sdio(active_slot);
- CsrSdioRemovedAcknowledge(sdio_ctx);
+ unregister_unifi_sdio(active_slot);
+ CsrSdioRemovedAcknowledge(sdio_ctx);
} /* uf_sdio_removed() */
static void
uf_sdio_dsr_handler(CsrSdioFunction *sdio_ctx)
{
- unifi_priv_t *priv = sdio_ctx->driverData;
+ unifi_priv_t *priv = sdio_ctx->driverData;
- unifi_sdio_interrupt_handler(priv->card);
+ unifi_sdio_interrupt_handler(priv->card);
} /* uf_sdio_dsr_handler() */
/*
@@ -1068,7 +1052,7 @@ uf_sdio_dsr_handler(CsrSdioFunction *sdio_ctx)
static CsrSdioInterruptDsrCallback
uf_sdio_int_handler(CsrSdioFunction *sdio_ctx)
{
- return uf_sdio_dsr_handler;
+ return uf_sdio_dsr_handler;
} /* uf_sdio_int_handler() */
@@ -1076,18 +1060,18 @@ uf_sdio_int_handler(CsrSdioFunction *sdio_ctx)
static CsrSdioFunctionId unifi_ids[] =
{
- {
- .manfId = SDIO_MANF_ID_CSR,
- .cardId = SDIO_CARD_ID_UNIFI_3,
- .sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_3,
- .sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE,
- },
- {
- .manfId = SDIO_MANF_ID_CSR,
- .cardId = SDIO_CARD_ID_UNIFI_4,
- .sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_4,
- .sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE,
- }
+ {
+ .manfId = SDIO_MANF_ID_CSR,
+ .cardId = SDIO_CARD_ID_UNIFI_3,
+ .sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_3,
+ .sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE,
+ },
+ {
+ .manfId = SDIO_MANF_ID_CSR,
+ .cardId = SDIO_CARD_ID_UNIFI_4,
+ .sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_4,
+ .sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE,
+ }
};
@@ -1096,14 +1080,14 @@ static CsrSdioFunctionId unifi_ids[] =
*/
static CsrSdioFunctionDriver unifi_sdioFunction_drv =
{
- .inserted = uf_sdio_inserted,
- .removed = uf_sdio_removed,
- .intr = uf_sdio_int_handler,
- .suspend = uf_lx_suspend,
- .resume = uf_lx_resume,
-
- .ids = unifi_ids,
- .idsCount = sizeof(unifi_ids) / sizeof(unifi_ids[0])
+ .inserted = uf_sdio_inserted,
+ .removed = uf_sdio_removed,
+ .intr = uf_sdio_int_handler,
+ .suspend = uf_lx_suspend,
+ .resume = uf_lx_resume,
+
+ .ids = unifi_ids,
+ .idsCount = sizeof(unifi_ids) / sizeof(unifi_ids[0])
};
@@ -1126,15 +1110,15 @@ static CsrSdioFunctionDriver unifi_sdioFunction_drv =
int __init
uf_sdio_load(void)
{
- CsrResult csrResult;
+ CsrResult csrResult;
- csrResult = CsrSdioFunctionDriverRegister(&unifi_sdioFunction_drv);
- if (csrResult != CSR_RESULT_SUCCESS) {
- unifi_error(NULL, "Failed to register UniFi SDIO driver: csrResult=%d\n", csrResult);
- return -EIO;
- }
+ csrResult = CsrSdioFunctionDriverRegister(&unifi_sdioFunction_drv);
+ if (csrResult != CSR_RESULT_SUCCESS) {
+ unifi_error(NULL, "Failed to register UniFi SDIO driver: csrResult=%d\n", csrResult);
+ return -EIO;
+ }
- return 0;
+ return 0;
} /* uf_sdio_load() */
@@ -1142,6 +1126,6 @@ uf_sdio_load(void)
void __exit
uf_sdio_unload(void)
{
- CsrSdioFunctionDriverUnregister(&unifi_sdioFunction_drv);
+ CsrSdioFunctionDriverUnregister(&unifi_sdioFunction_drv);
} /* uf_sdio_unload() */
diff --git a/drivers/staging/csr/mlme.c b/drivers/staging/csr/mlme.c
index ed767eccbb3..861d6b7687c 100644
--- a/drivers/staging/csr/mlme.c
+++ b/drivers/staging/csr/mlme.c
@@ -154,8 +154,6 @@ unifi_mlme_blocking_request(unifi_priv_t *priv, ul_client_t *pcli,
{
int r;
- func_enter();
-
if (sig->SignalPrimitiveHeader.SignalId == 0) {
unifi_error(priv, "unifi_mlme_blocking_request: Invalid Signal Id (0x%x)\n",
sig->SignalPrimitiveHeader.SignalId);
@@ -199,7 +197,6 @@ unifi_mlme_blocking_request(unifi_priv_t *priv, ul_client_t *pcli,
return r;
}
- func_exit();
return 0;
} /* unifi_mlme_blocking_request() */
diff --git a/drivers/staging/csr/monitor.c b/drivers/staging/csr/monitor.c
index 7c524a18958..c8e20e4c611 100644
--- a/drivers/staging/csr/monitor.c
+++ b/drivers/staging/csr/monitor.c
@@ -10,7 +10,6 @@
* ---------------------------------------------------------------------------
*/
-#include <linux/version.h>
#include "unifi_priv.h"
#ifdef UNIFI_SNIFF_ARPHRD
@@ -122,8 +121,6 @@ netrx_radiotap(unifi_priv_t *priv,
struct unifi_rx_radiotap_header *unifi_rt;
int signal, noise, snr;
- func_enter();
-
if (ind_data_len <= 0) {
unifi_error(priv, "Invalid length in CSR_MA_SNIFFDATA_INDICATION.\n");
return;
@@ -205,7 +202,6 @@ netrx_radiotap(unifi_priv_t *priv,
priv->stats.rx_packets++;
priv->stats.rx_bytes += ind_data_len;
- func_exit();
} /* netrx_radiotap() */
#endif /* RADIOTAP */
@@ -256,8 +252,6 @@ netrx_prism(unifi_priv_t *priv,
} *avs;
int signal, noise, snr;
- func_enter();
-
if (ind_data_len <= 0) {
unifi_error(priv, "Invalid length in CSR_MA_SNIFFDATA_INDICATION.\n");
return;
@@ -319,7 +313,6 @@ netrx_prism(unifi_priv_t *priv,
priv->stats.rx_packets++;
priv->stats.rx_bytes += ind_data_len;
- func_exit();
} /* netrx_prism() */
#endif /* PRISM */
@@ -351,11 +344,8 @@ ma_sniffdata_ind(void *ospriv,
struct net_device *dev = priv->netdev;
struct sk_buff *skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
- func_enter();
-
if (bulkdata->d[0].data_length == 0) {
unifi_warning(priv, "rx: MA-SNIFFDATA indication with zero bulk data\n");
- func_exit();
return;
}
diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c
index 9a52ab408e1..7dad26f7017 100644
--- a/drivers/staging/csr/netdev.c
+++ b/drivers/staging/csr/netdev.c
@@ -47,7 +47,6 @@
#include <linux/etherdevice.h>
#include <linux/mutex.h>
#include <linux/semaphore.h>
-#include <linux/version.h>
#include <linux/vmalloc.h>
#include "csr_wifi_hip_unifi.h"
#include "csr_wifi_hip_conversions.h"
@@ -55,7 +54,7 @@
#include <net/pkt_sched.h>
-/* Wext handler is suported only if CSR_SUPPORT_WEXT is defined */
+/* Wext handler is supported only if CSR_SUPPORT_WEXT is defined */
#ifdef CSR_SUPPORT_WEXT
extern struct iw_handler_def unifi_iw_handler_def;
#endif /* CSR_SUPPORT_WEXT */
@@ -89,7 +88,7 @@ typedef int (*tx_signal_handler)(unifi_priv_t *priv, struct sk_buff *skb, const
/*
* The driver uses the qdisc interface to buffer and control all
* outgoing traffic. We create a root qdisc, register our qdisc operations
- * and later we create two subsiduary pfifo queues for the uncontrolled
+ * and later we create two subsidiary pfifo queues for the uncontrolled
* and controlled ports.
*
* The network stack delivers all outgoing packets in our enqueue handler.
@@ -478,8 +477,6 @@ uf_free_netdevice(unifi_priv_t *priv)
int i;
unsigned long flags;
- func_enter();
-
unifi_trace(priv, UDBG1, "uf_free_netdevice\n");
if (!priv) {
@@ -554,7 +551,6 @@ uf_free_netdevice(unifi_priv_t *priv)
}
}
- func_exit();
return 0;
} /* uf_free_netdevice() */
@@ -578,8 +574,6 @@ uf_net_open(struct net_device *dev)
netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
unifi_priv_t *priv = interfacePriv->privPtr;
- func_enter();
-
/* If we haven't finished UniFi initialisation, we can't start */
if (priv->init_progress != UNIFI_INIT_COMPLETED) {
unifi_warning(priv, "%s: unifi not ready, failing net_open\n", __FUNCTION__);
@@ -615,7 +609,6 @@ uf_net_open(struct net_device *dev)
netif_tx_start_all_queues(dev);
- func_exit();
return 0;
} /* uf_net_open() */
@@ -627,8 +620,6 @@ uf_net_stop(struct net_device *dev)
netInterface_priv_t *interfacePriv = (netInterface_priv_t*)netdev_priv(dev);
unifi_priv_t *priv = interfacePriv->privPtr;
- func_enter();
-
/* Stop sniffing if in Monitor mode */
if (priv->wext_conf.mode == IW_MODE_MONITOR) {
if (priv->card) {
@@ -639,13 +630,10 @@ uf_net_stop(struct net_device *dev)
}
}
}
-#else
- func_enter();
#endif
netif_tx_stop_all_queues(dev);
- func_exit();
return 0;
} /* uf_net_stop() */
@@ -675,7 +663,6 @@ static CSR_PRIORITY uf_get_packet_priority(unifi_priv_t *priv, netInterface_priv
{
CSR_PRIORITY priority = CSR_CONTENTION;
- func_enter();
priority = (CSR_PRIORITY) (skb->priority >> 5);
if (priority == CSR_QOS_UP0) { /* 0 */
@@ -721,7 +708,6 @@ static CSR_PRIORITY uf_get_packet_priority(unifi_priv_t *priv, netInterface_priv
unifi_trace(priv, UDBG5, "Packet priority = %d\n", priority);
- func_exit();
return priority;
}
@@ -750,8 +736,6 @@ get_packet_priority(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr
u8 interfaceMode = interfacePriv->interfaceMode;
- func_enter();
-
/* Priority Mapping for all the Modes */
switch(interfaceMode)
{
@@ -788,7 +772,6 @@ get_packet_priority(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr
}
unifi_trace(priv, UDBG5, "priority = %x\n", priority);
- func_exit();
return priority;
}
@@ -816,8 +799,6 @@ uf_net_select_queue(struct net_device *dev, struct sk_buff *skb)
int proto;
CSR_PRIORITY priority;
- func_enter();
-
memcpy(&ehdr, skb->data, ETH_HLEN);
proto = ntohs(ehdr.h_proto);
@@ -836,7 +817,6 @@ uf_net_select_queue(struct net_device *dev, struct sk_buff *skb)
}
- func_exit();
return (u16)queue;
} /* uf_net_select_queue() */
@@ -1582,7 +1562,7 @@ send_ma_pkt_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr
return -1;
}
- /* RA adrress must contain the immediate destination MAC address that is similiar to
+ /* RA address must contain the immediate destination MAC address that is similar to
* the Address 1 field of 802.11 Mac header here 4 is: (sizeof(framecontrol) + sizeof (durationID))
* which is address 1 field
*/
@@ -1760,8 +1740,6 @@ uf_net_xmit(struct sk_buff *skb, struct net_device *dev)
CSR_PRIORITY priority;
CsrWifiRouterCtrlPortAction port_action;
- func_enter();
-
unifi_trace(priv, UDBG5, "unifi_net_xmit: skb = %x\n", skb);
memcpy(&ehdr, skb->data, ETH_HLEN);
@@ -1805,7 +1783,6 @@ uf_net_xmit(struct sk_buff *skb, struct net_device *dev)
interfacePriv->stats.tx_dropped++;
kfree_skb(skb);
- func_exit();
return NETDEV_TX_OK;
}
@@ -1848,7 +1825,6 @@ uf_net_xmit(struct sk_buff *skb, struct net_device *dev)
/* The skb will have been freed by send_XXX_request() */
- func_exit();
return result;
} /* uf_net_xmit() */
@@ -1877,7 +1853,6 @@ unifi_pause_xmit(void *ospriv, unifi_TrafficQueue queue)
unifi_priv_t *priv = ospriv;
int i; /* used as a loop counter */
- func_enter();
unifi_trace(priv, UDBG2, "Stopping queue %d\n", queue);
for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
@@ -1897,7 +1872,6 @@ unifi_pause_xmit(void *ospriv, unifi_TrafficQueue queue)
unifi_error(priv, "Start buffering %d defaulting to 0\n", queue);
}
#endif
- func_exit();
} /* unifi_pause_xmit() */
@@ -1907,7 +1881,6 @@ unifi_restart_xmit(void *ospriv, unifi_TrafficQueue queue)
unifi_priv_t *priv = ospriv;
int i=0; /* used as a loop counter */
- func_enter();
unifi_trace(priv, UDBG2, "Waking queue %d\n", queue);
for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
@@ -1927,7 +1900,6 @@ unifi_restart_xmit(void *ospriv, unifi_TrafficQueue queue)
uf_send_buffered_frames(priv,0);
}
#endif
- func_exit();
} /* unifi_restart_xmit() */
@@ -1963,7 +1935,6 @@ indicate_rx_skb(unifi_priv_t *priv, u16 ifTag, u8* dst_a, u8* src_a, struct sk_b
priv->interfacePriv[ifTag]->stats.rx_frame_errors++;
unifi_net_data_free(priv, &bulkdata->d[0]);
unifi_notice(priv, "indicate_rx_skb: Discard unknown frame.\n");
- func_exit();
return;
}
@@ -1975,7 +1946,6 @@ indicate_rx_skb(unifi_priv_t *priv, u16 ifTag, u8* dst_a, u8* src_a, struct sk_b
unifi_net_data_free(priv, &bulkdata->d[0]);
unifi_trace(priv, UDBG5, "indicate_rx_skb: Data given to subscription"
"API, not being given to kernel\n");
- func_exit();
return;
}
@@ -1998,7 +1968,6 @@ indicate_rx_skb(unifi_priv_t *priv, u16 ifTag, u8* dst_a, u8* src_a, struct sk_b
priv->interfacePriv[ifTag]->stats.rx_errors++;
priv->interfacePriv[ifTag]->stats.rx_length_errors++;
unifi_net_data_free(priv, &bulkdata->d[0]);
- func_exit();
return;
}
@@ -2025,7 +1994,6 @@ indicate_rx_skb(unifi_priv_t *priv, u16 ifTag, u8* dst_a, u8* src_a, struct sk_b
priv->interfacePriv[ifTag]->stats.rx_packets++;
priv->interfacePriv[ifTag]->stats.rx_bytes += bulkdata->d[0].data_length;
- func_exit();
return;
}
@@ -2178,8 +2146,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
netInterface_priv_t *interfacePriv;
struct ethhdr ehdr;
- func_enter();
-
interfaceTag = (pkt_ind->VirtualInterfaceIdentifier & 0xff);
interfacePriv = priv->interfacePriv[interfaceTag];
@@ -2188,7 +2154,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
{
unifi_error(priv, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
unifi_net_data_free(priv,&bulkdata->d[0]);
- func_exit();
return;
}
@@ -2197,14 +2162,12 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
{
unifi_error(priv, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__, interfaceTag);
unifi_net_data_free(priv, &bulkdata->d[0]);
- func_exit();
return;
}
if (bulkdata->d[0].data_length == 0) {
unifi_warning(priv, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__);
unifi_net_data_free(priv,&bulkdata->d[0]);
- func_exit();
return;
}
@@ -2326,7 +2289,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
unifi_net_data_free(priv, &bulkdata->d[0]);
- func_exit();
return;
}
@@ -2343,7 +2305,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
unifi_net_data_free(priv, &bulkdata->d[0]);
unifi_notice(priv, "%s: Dropping packet, proto=0x%04x, %s port\n", __FUNCTION__,
proto, queue ? "Controlled" : "Un-controlled");
- func_exit();
return;
}
@@ -2351,7 +2312,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
if((dataFrameType == QOS_DATA_NULL) || (dataFrameType == DATA_NULL)){
unifi_trace(priv, UDBG5, "%s: Null Frame Received and Freed\n", __FUNCTION__);
unifi_net_data_free(priv, &bulkdata->d[0]);
- func_exit();
return;
}
@@ -2366,7 +2326,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
bulkdata,
macHeaderLengthInBytes)))
{
- func_exit();
return;
}
unifi_trace(priv, UDBG5, "unifi_rx: no specific AP handling process as normal frame, MAC Header len %d\n",macHeaderLengthInBytes);
@@ -2389,7 +2348,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
unifi_trace(priv, UDBG1, "Zero length frame, but not null-data %04x\n", frameControl);
}
unifi_net_data_free(priv, &bulkdata->d[0]);
- func_exit();
return;
}
@@ -2399,7 +2357,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
unifi_net_data_free(priv, &bulkdata->d[0]);
unifi_notice(priv, "%s: Dropping packet, proto=0x%04x, %s port\n",
__FUNCTION__, proto, queue ? "controlled" : "uncontrolled");
- func_exit();
return;
} else if ( (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK) ||
(interfacePriv->connected != UnifiConnected) ) {
@@ -2415,7 +2372,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
__FUNCTION__, sizeof(rx_buffered_packets_t));
interfacePriv->stats.rx_dropped++;
unifi_net_data_free(priv, &bulkdata->d[0]);
- func_exit();
return;
}
@@ -2439,15 +2395,12 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
list_add_tail(&rx_q_item->q, rx_list);
up(&priv->rx_q_sem);
- func_exit();
return;
}
indicate_rx_skb(priv, interfaceTag, da, sa, skb, signal, bulkdata);
- func_exit();
-
} /* unifi_rx() */
static void process_ma_packet_cfm(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
@@ -2456,7 +2409,6 @@ static void process_ma_packet_cfm(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d
const CSR_MA_PACKET_CONFIRM *pkt_cfm = &signal->u.MaPacketConfirm;
netInterface_priv_t *interfacePriv;
- func_enter();
interfaceTag = (pkt_cfm->VirtualInterfaceIdentifier & 0xff);
interfacePriv = priv->interfacePriv[interfaceTag];
@@ -2464,7 +2416,6 @@ static void process_ma_packet_cfm(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d
if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
{
unifi_error(priv, "%s: MA-PACKET confirm with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
- func_exit();
return;
}
#ifdef CSR_SUPPORT_SME
@@ -2487,7 +2438,6 @@ static void process_ma_packet_cfm(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d
interfacePriv->m4_hostTag = 0xffffffff;
}
#endif
- func_exit();
return;
}
@@ -2528,8 +2478,6 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d
#endif
- func_enter();
-
interfaceTag = (pkt_ind->VirtualInterfaceIdentifier & 0xff);
interfacePriv = priv->interfacePriv[interfaceTag];
@@ -2539,7 +2487,6 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d
{
unifi_error(priv, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
unifi_net_data_free(priv,&bulkdata->d[0]);
- func_exit();
return;
}
@@ -2548,24 +2495,21 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d
{
unifi_error(priv, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__, interfaceTag);
unifi_net_data_free(priv, &bulkdata->d[0]);
- func_exit();
return;
}
if (bulkdata->d[0].data_length == 0) {
unifi_warning(priv, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__);
unifi_net_data_free(priv,&bulkdata->d[0]);
- func_exit();
return;
}
/* For monitor mode we need to pass this indication to the registered application
- handle this seperately*/
+ handle this separately*/
/* MIC failure is already taken care of so no need to send the PDUs which are not successfully received in non-monitor mode*/
if(pkt_ind->ReceptionStatus != CSR_RX_SUCCESS)
{
unifi_warning(priv, "%s: MA-PACKET indication with status = %d\n",__FUNCTION__, pkt_ind->ReceptionStatus);
unifi_net_data_free(priv,&bulkdata->d[0]);
- func_exit();
return;
}
@@ -2613,13 +2557,11 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d
}
#endif
unifi_net_data_free(priv,&bulkdata->d[0]);
- func_exit();
return;
}
if(frameType != IEEE802_11_FRAMETYPE_DATA) {
unifi_warning(priv, "%s: Non control Non Data frame is received\n",__FUNCTION__);
unifi_net_data_free(priv,&bulkdata->d[0]);
- func_exit();
return;
}
@@ -2637,7 +2579,6 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d
sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
unifi_net_data_free(priv, &bulkdata->d[0]);
- func_exit();
return;
}
@@ -2743,7 +2684,6 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d
up(&priv->ba_mutex);
process_ba_complete(priv, interfacePriv);
- func_exit();
}
/*
* ---------------------------------------------------------------------------
@@ -2836,8 +2776,6 @@ netdev_mlme_event_handler(ul_client_t *pcli, const u8 *sig_packed, int sig_len,
int id, r;
bulk_data_param_t bulkdata;
- func_enter();
-
/* Just a sanity check */
if (sig_packed == NULL) {
return;
@@ -2902,7 +2840,6 @@ netdev_mlme_event_handler(ul_client_t *pcli, const u8 *sig_packed, int sig_len,
break;
}
- func_exit();
} /* netdev_mlme_event_handler() */
@@ -3100,13 +3037,13 @@ static void update_expected_sn(unifi_priv_t *priv,
u16 gap;
gap = (sn - ba_session->expected_sn) & 0xFFF;
- unifi_trace(priv, UDBG6, "%s: proccess the frames up to new_expected_sn = %d gap = %d\n", __FUNCTION__, sn, gap);
+ unifi_trace(priv, UDBG6, "%s: process the frames up to new_expected_sn = %d gap = %d\n", __FUNCTION__, sn, gap);
for(j = 0; j < gap && j < ba_session->wind_size; j++) {
i = SN_TO_INDEX(ba_session, ba_session->expected_sn);
- unifi_trace(priv, UDBG6, "%s: proccess the slot index = %d\n", __FUNCTION__, i);
+ unifi_trace(priv, UDBG6, "%s: process the slot index = %d\n", __FUNCTION__, i);
if(ba_session->buffer[i].active) {
add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]);
- unifi_trace(priv, UDBG6, "%s: proccess the frame at index = %d expected_sn = %d\n", __FUNCTION__, i, ba_session->expected_sn);
+ unifi_trace(priv, UDBG6, "%s: process the frame at index = %d expected_sn = %d\n", __FUNCTION__, i, ba_session->expected_sn);
FREE_BUFFER_SLOT(ba_session, i);
} else {
unifi_trace(priv, UDBG6, "%s: empty slot at index = %d\n", __FUNCTION__, i);
@@ -3247,8 +3184,8 @@ static void check_ba_frame_age_timeout( unifi_priv_t *priv,
netInterface_priv_t *interfacePriv,
ba_session_rx_struct *ba_session)
{
- CsrTime now;
- CsrTime age;
+ u32 now;
+ u32 age;
u8 i, j;
u16 sn_temp;
@@ -3283,11 +3220,11 @@ static void check_ba_frame_age_timeout( unifi_priv_t *priv,
if (ba_session->buffer[i].recv_time > now)
{
/* timer wrap */
- age = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, ba_session->buffer[i].recv_time), now);
+ age = CsrTimeAdd((u32)CsrTimeSub(CSR_SCHED_TIME_MAX, ba_session->buffer[i].recv_time), now);
}
else
{
- age = (CsrTime)CsrTimeSub(now, ba_session->buffer[i].recv_time);
+ age = (u32)CsrTimeSub(now, ba_session->buffer[i].recv_time);
}
if (age >= CSR_WIFI_BA_MPDU_FRAME_AGE_TIMEOUT)
@@ -3331,8 +3268,6 @@ static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal,
CSR_PRIORITY UserPriority;
CSR_SEQUENCE_NUMBER sn;
- func_enter();
-
interfaceTag = (pkt_err_ind->VirtualInterfaceIdentifier & 0xff);
@@ -3340,7 +3275,6 @@ static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal,
if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
{
unifi_error(priv, "%s: MaPacketErrorIndication indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
- func_exit();
return;
}
@@ -3348,7 +3282,6 @@ static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal,
UserPriority = pkt_err_ind->UserPriority;
if(UserPriority > 15) {
unifi_error(priv, "%s: MaPacketErrorIndication indication with bad UserPriority=%d\n", __FUNCTION__, UserPriority);
- func_exit();
}
sn = pkt_err_ind->SequenceNumber;
@@ -3369,7 +3302,6 @@ static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal,
up(&priv->ba_mutex);
process_ba_complete(priv, interfacePriv);
- func_exit();
}
diff --git a/drivers/staging/csr/os.c b/drivers/staging/csr/os.c
index 35dc9087d79..37ec59df358 100644
--- a/drivers/staging/csr/os.c
+++ b/drivers/staging/csr/os.c
@@ -412,9 +412,8 @@ dump(void *mem, u16 len)
return;
}
for (i = 0; i < len; i++) {
- if (col == 0) {
+ if (col == 0)
printk("0x%02X: ", i);
- }
printk(" %02X", pdata[i]);
@@ -423,9 +422,8 @@ dump(void *mem, u16 len)
col = 0;
}
}
- if (col) {
+ if (col)
printk("\n");
- }
} /* dump() */
@@ -438,9 +436,8 @@ dump16(void *mem, u16 len)
printk("timestamp %s \n", print_time());
#endif /* ANDROID_TIMESTAMP */
for (i = 0; i < len; i+=2) {
- if (col == 0) {
+ if (col == 0)
printk("0x%02X: ", i);
- }
printk(" %04X", *p++);
@@ -449,9 +446,8 @@ dump16(void *mem, u16 len)
col = 0;
}
}
- if (col) {
+ if (col)
printk("\n");
- }
}
@@ -459,7 +455,7 @@ dump16(void *mem, u16 len)
void
dump_str(void *mem, u16 len)
{
- int i, col = 0;
+ int i;
unsigned char *pdata = (unsigned char *)mem;
#ifdef ANDROID_TIMESTAMP
printk("timestamp %s \n", print_time());
@@ -467,9 +463,7 @@ dump_str(void *mem, u16 len)
for (i = 0; i < len; i++) {
printk("%c", pdata[i]);
}
- if (col) {
- printk("\n");
- }
+ printk("\n");
} /* dump_str() */
#endif /* CSR_ONLY_NOTES */
diff --git a/drivers/staging/csr/sdio_mmc.c b/drivers/staging/csr/sdio_mmc.c
index af3e40bb501..b6a16de08f4 100644
--- a/drivers/staging/csr/sdio_mmc.c
+++ b/drivers/staging/csr/sdio_mmc.c
@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/gfp.h>
-#include <linux/version.h>
#include <linux/mmc/core.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
@@ -152,7 +151,6 @@ CsrSdioRead8(CsrSdioFunction *function, u32 address, u8 *data)
_sdio_release_host(func);
if (err) {
- func_exit_r(err);
return ConvertSdioToCsrSdioResult(err);
}
@@ -170,7 +168,6 @@ CsrSdioWrite8(CsrSdioFunction *function, u32 address, u8 data)
_sdio_release_host(func);
if (err) {
- func_exit_r(err);
return ConvertSdioToCsrSdioResult(err);
}
@@ -246,7 +243,6 @@ CsrSdioF0Read8(CsrSdioFunction *function, u32 address, u8 *data)
_sdio_release_host(func);
if (err) {
- func_exit_r(err);
return ConvertSdioToCsrSdioResult(err);
}
@@ -268,7 +264,6 @@ CsrSdioF0Write8(CsrSdioFunction *function, u32 address, u8 data)
_sdio_release_host(func);
if (err) {
- func_exit_r(err);
return ConvertSdioToCsrSdioResult(err);
}
@@ -287,7 +282,6 @@ CsrSdioRead(CsrSdioFunction *function, u32 address, void *data, u32 length)
_sdio_release_host(func);
if (err) {
- func_exit_r(err);
return ConvertSdioToCsrSdioResult(err);
}
@@ -305,7 +299,6 @@ CsrSdioWrite(CsrSdioFunction *function, u32 address, const void *data, u32 lengt
_sdio_release_host(func);
if (err) {
- func_exit_r(err);
return ConvertSdioToCsrSdioResult(err);
}
@@ -480,7 +473,6 @@ CsrSdioInterruptEnable(CsrSdioFunction *function)
#endif
_sdio_release_host(func);
- func_exit();
if (err) {
printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err);
return ConvertSdioToCsrSdioResult(err);
@@ -507,7 +499,6 @@ CsrSdioInterruptDisable(CsrSdioFunction *function)
#endif
_sdio_release_host(func);
- func_exit();
if (err) {
printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err);
return ConvertSdioToCsrSdioResult(err);
@@ -541,8 +532,6 @@ CsrSdioFunctionEnable(CsrSdioFunction *function)
struct sdio_func *func = (struct sdio_func *)function->priv;
int err;
- func_enter();
-
/* Enable UniFi function 1 (the 802.11 part). */
_sdio_claim_host(func);
err = sdio_enable_func(func);
@@ -551,7 +540,6 @@ CsrSdioFunctionEnable(CsrSdioFunction *function)
unifi_error(NULL, "Failed to enable SDIO function %d\n", func->num);
}
- func_exit();
return ConvertSdioToCsrSdioResult(err);
} /* CsrSdioFunctionEnable() */
@@ -575,8 +563,6 @@ CsrSdioFunctionDisable(CsrSdioFunction *function)
struct sdio_func *func = (struct sdio_func *)function->priv;
int err;
- func_enter();
-
/* Disable UniFi function 1 (the 802.11 part). */
_sdio_claim_host(func);
err = sdio_disable_func(func);
@@ -585,7 +571,6 @@ CsrSdioFunctionDisable(CsrSdioFunction *function)
unifi_error(NULL, "Failed to disable SDIO function %d\n", func->num);
}
- func_exit();
return ConvertSdioToCsrSdioResult(err);
} /* CsrSdioFunctionDisable() */
@@ -1034,8 +1019,6 @@ uf_glue_sdio_probe(struct sdio_func *func,
int instance;
CsrSdioFunction *sdio_ctx;
- func_enter();
-
/* First of all claim the SDIO driver */
sdio_claim_host(func);
@@ -1103,7 +1086,6 @@ uf_glue_sdio_probe(struct sdio_func *func,
wake_lock(&unifi_sdio_wake_lock);
#endif
- func_exit();
return 0;
} /* uf_glue_sdio_probe() */
@@ -1131,8 +1113,6 @@ uf_glue_sdio_remove(struct sdio_func *func)
return;
}
- func_enter();
-
unifi_info(NULL, "UniFi card removed\n");
/* Clean up the SDIO function driver */
@@ -1148,8 +1128,6 @@ uf_glue_sdio_remove(struct sdio_func *func)
kfree(sdio_ctx);
- func_exit();
-
} /* uf_glue_sdio_remove */
@@ -1183,11 +1161,8 @@ MODULE_DEVICE_TABLE(sdio, unifi_ids);
static int
uf_glue_sdio_suspend(struct device *dev)
{
- func_enter();
-
unifi_trace(NULL, UDBG1, "uf_glue_sdio_suspend");
- func_exit();
return 0;
} /* uf_glue_sdio_suspend */
@@ -1208,8 +1183,6 @@ uf_glue_sdio_suspend(struct device *dev)
static int
uf_glue_sdio_resume(struct device *dev)
{
- func_enter();
-
unifi_trace(NULL, UDBG1, "uf_glue_sdio_resume");
#ifdef ANDROID_BUILD
@@ -1217,7 +1190,6 @@ uf_glue_sdio_resume(struct device *dev)
wake_lock(&unifi_sdio_wake_lock);
#endif
- func_exit();
return 0;
} /* uf_glue_sdio_resume */
diff --git a/drivers/staging/csr/sme_blocking.c b/drivers/staging/csr/sme_blocking.c
index 543e8f2c407..d88ccd5bd42 100644
--- a/drivers/staging/csr/sme_blocking.c
+++ b/drivers/staging/csr/sme_blocking.c
@@ -270,17 +270,15 @@ int sme_mgt_wifi_off(unifi_priv_t *priv)
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
/* Stop the SME */
CsrWifiSmeWifiOffReqSend(0);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
unifi_trace(priv, UDBG4,
"sme_mgt_wifi_off: unifi_mgt_wifi_off_req <-- (r=%d, status=%d)\n",
@@ -300,16 +298,14 @@ int sme_mgt_key(unifi_priv_t *priv, CsrWifiSmeKey *sme_key,
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeKeyReqSend(0, CSR_WIFI_INTERFACE_IN_USE, action, *sme_key);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
return convert_sme_error(priv->sme_reply.reply_status);
}
@@ -332,9 +328,8 @@ int sme_mgt_scan_full(unifi_priv_t *priv,
unifi_trace(priv, UDBG4, "sme_mgt_scan_full: -->\n");
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
/* If a channel list is provided, do an active scan */
if (is_active) {
@@ -354,16 +349,14 @@ int sme_mgt_scan_full(unifi_priv_t *priv,
0, NULL);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
unifi_trace(priv, UDBG4, "sme_mgt_scan_full: <-- (status=%d)\n", priv->sme_reply.reply_status);
- if (priv->sme_reply.reply_status == CSR_WIFI_RESULT_UNAVAILABLE) {
+ if (priv->sme_reply.reply_status == CSR_WIFI_RESULT_UNAVAILABLE)
return 0; /* initial scan already underway */
- } else {
+ else
return convert_sme_error(priv->sme_reply.reply_status);
- }
}
@@ -385,15 +378,13 @@ int sme_mgt_scan_results_get_async(unifi_priv_t *priv,
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeScanResultsGetReqSend(0);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
scan_result_list_count = priv->sme_reply.reply_scan_results_count;
scan_result_list = priv->sme_reply.reply_scan_results;
@@ -454,20 +445,17 @@ int sme_mgt_connect(unifi_priv_t *priv)
priv->connection_config.ssid.ssid);
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeConnectReqSend(0, CSR_WIFI_INTERFACE_IN_USE, priv->connection_config);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
- if (priv->sme_reply.reply_status) {
+ if (priv->sme_reply.reply_status)
unifi_trace(priv, UDBG1, "sme_mgt_connect: failed with SME status %d\n",
priv->sme_reply.reply_status);
- }
return convert_sme_error(priv->sme_reply.reply_status);
}
@@ -483,15 +471,13 @@ int sme_mgt_disconnect(unifi_priv_t *priv)
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeDisconnectReqSend(0, CSR_WIFI_INTERFACE_IN_USE);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
unifi_trace(priv, UDBG4, "sme_mgt_disconnect: <-- (status=%d)\n", priv->sme_reply.reply_status);
return convert_sme_error(priv->sme_reply.reply_status);
@@ -510,16 +496,14 @@ int sme_mgt_pmkid(unifi_priv_t *priv,
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmePmkidReqSend(0, CSR_WIFI_INTERFACE_IN_USE, action,
pmkid_list->pmkidsCount, pmkid_list->pmkids);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
unifi_trace(priv, UDBG4, "sme_mgt_pmkid: <-- (status=%d)\n", priv->sme_reply.reply_status);
return convert_sme_error(priv->sme_reply.reply_status);
@@ -537,9 +521,8 @@ int sme_mgt_mib_get(unifi_priv_t *priv,
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
priv->mib_cfm_buffer = varbind;
priv->mib_cfm_buffer_length = MAX_VARBIND_LENGTH;
@@ -571,15 +554,13 @@ int sme_mgt_mib_set(unifi_priv_t *priv,
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeMibSetReqSend(0, length, varbind);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
unifi_trace(priv, UDBG4, "sme_mgt_mib_set: <-- (status=%d)\n", priv->sme_reply.reply_status);
return convert_sme_error(priv->sme_reply.reply_status);
@@ -598,16 +579,14 @@ int sme_mgt_power_config_set(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerCon
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmePowerConfigSetReqSend(0, *powerConfig);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
unifi_trace(priv, UDBG4,
"sme_mgt_set_value_async: unifi_mgt_set_value_req <-- (r=%d status=%d)\n",
@@ -637,29 +616,26 @@ int sme_mgt_sme_config_set(unifi_priv_t *priv, CsrWifiSmeStaConfig *staConfig, C
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeSmeStaConfigSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE, *staConfig);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
+
unifi_trace(priv, UDBG4,
"sme_mgt_sme_config_set: CsrWifiSmeSmeStaConfigSetReq <-- (r=%d status=%d)\n",
r, priv->sme_reply.reply_status);
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeSmeCommonConfigSetReqSend(0, *deviceConfig);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
unifi_trace(priv, UDBG4,
"sme_mgt_sme_config_set: CsrWifiSmeSmeCommonConfigSetReq <-- (r=%d status=%d)\n",
@@ -693,16 +669,14 @@ int sme_mgt_mib_config_set(unifi_priv_t *priv, CsrWifiSmeMibConfig *mibConfig)
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeMibConfigSetReqSend(0, *mibConfig);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
unifi_trace(priv, UDBG4,
"sme_mgt_mib_config_set: unifi_mgt_set_mib_config_req <-- (r=%d status=%d)\n",
@@ -732,16 +706,14 @@ int sme_mgt_coex_config_set(unifi_priv_t *priv, CsrWifiSmeCoexConfig *coexConfig
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeCoexConfigSetReqSend(0, *coexConfig);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
unifi_trace(priv, UDBG4,
"sme_mgt_coex_config_set: unifi_mgt_set_mib_config_req <-- (r=%d status=%d)\n",
@@ -773,16 +745,14 @@ int sme_mgt_host_config_set(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeHostConfigSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE, *hostConfig);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
unifi_trace(priv, UDBG4,
"sme_mgt_host_config_set: unifi_mgt_set_host_config_req <-- (r=%d status=%d)\n",
@@ -815,16 +785,14 @@ int sme_mgt_versions_get(unifi_priv_t *priv, CsrWifiSmeVersions *versions)
unifi_trace(priv, UDBG4, "sme_mgt_versions_get: unifi_mgt_versions_get_req -->\n");
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeVersionsGetReqSend(0);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
/* store the reply */
if (versions != NULL) {
@@ -861,16 +829,14 @@ int sme_mgt_power_config_get(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerCon
unifi_trace(priv, UDBG4, "sme_mgt_power_config_get: unifi_mgt_power_config_req -->\n");
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmePowerConfigGetReqSend(0);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
/* store the reply */
if (powerConfig != NULL) {
@@ -905,23 +871,20 @@ int sme_mgt_host_config_get(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig
unifi_trace(priv, UDBG4, "sme_mgt_host_config_get: unifi_mgt_host_config_get_req -->\n");
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeHostConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
/* store the reply */
- if (hostConfig != NULL) {
+ if (hostConfig != NULL)
memcpy((unsigned char*)hostConfig,
(unsigned char*)&priv->sme_reply.hostConfig,
sizeof(CsrWifiSmeHostConfig));
- }
unifi_trace(priv, UDBG4,
"sme_mgt_host_config_get: unifi_mgt_host_config_get_req <-- (r=%d status=%d)\n",
@@ -951,41 +914,35 @@ int sme_mgt_sme_config_get(unifi_priv_t *priv, CsrWifiSmeStaConfig *staConfig, C
/* Common device config */
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeSmeCommonConfigGetReqSend(0);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
/* store the reply */
- if (deviceConfig != NULL) {
+ if (deviceConfig != NULL)
memcpy((unsigned char*)deviceConfig,
(unsigned char*)&priv->sme_reply.deviceConfig,
sizeof(CsrWifiSmeDeviceConfig));
- }
/* STA config */
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeSmeStaConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
/* store the reply */
- if (staConfig != NULL) {
+ if (staConfig != NULL)
memcpy((unsigned char*)staConfig,
(unsigned char*)&priv->sme_reply.staConfig,
sizeof(CsrWifiSmeStaConfig));
- }
unifi_trace(priv, UDBG4,
"sme_mgt_sme_config_get: unifi_mgt_sme_config_get_req <-- (r=%d status=%d)\n",
@@ -1014,23 +971,20 @@ int sme_mgt_coex_info_get(unifi_priv_t *priv, CsrWifiSmeCoexInfo *coexInfo)
unifi_trace(priv, UDBG4, "sme_mgt_coex_info_get: unifi_mgt_coex_info_get_req -->\n");
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeCoexInfoGetReqSend(0);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
/* store the reply */
- if (coexInfo != NULL) {
+ if (coexInfo != NULL)
memcpy((unsigned char*)coexInfo,
(unsigned char*)&priv->sme_reply.coexInfo,
sizeof(CsrWifiSmeCoexInfo));
- }
unifi_trace(priv, UDBG4,
"sme_mgt_coex_info_get: unifi_mgt_coex_info_get_req <-- (r=%d status=%d)\n",
@@ -1060,23 +1014,20 @@ int sme_mgt_coex_config_get(unifi_priv_t *priv, CsrWifiSmeCoexConfig *coexConfig
unifi_trace(priv, UDBG4, "sme_mgt_coex_config_get: unifi_mgt_coex_config_get_req -->\n");
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeCoexConfigGetReqSend(0);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
/* store the reply */
- if (coexConfig != NULL) {
+ if (coexConfig != NULL)
memcpy((unsigned char*)coexConfig,
(unsigned char*)&priv->sme_reply.coexConfig,
sizeof(CsrWifiSmeCoexConfig));
- }
unifi_trace(priv, UDBG4,
"sme_mgt_coex_config_get: unifi_mgt_coex_config_get_req <-- (r=%d status=%d)\n",
@@ -1104,23 +1055,20 @@ int sme_mgt_mib_config_get(unifi_priv_t *priv, CsrWifiSmeMibConfig *mibConfig)
unifi_trace(priv, UDBG4, "sme_mgt_mib_config_get: unifi_mgt_mib_config_get_req -->\n");
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeMibConfigGetReqSend(0);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
/* store the reply */
- if (mibConfig != NULL) {
+ if (mibConfig != NULL)
memcpy((unsigned char*)mibConfig,
(unsigned char*)&priv->sme_reply.mibConfig,
sizeof(CsrWifiSmeMibConfig));
- }
unifi_trace(priv, UDBG4,
"sme_mgt_mib_config_get: unifi_mgt_mib_config_get_req <-- (r=%d status=%d)\n",
@@ -1148,23 +1096,20 @@ int sme_mgt_connection_info_get(unifi_priv_t *priv, CsrWifiSmeConnectionInfo *co
unifi_trace(priv, UDBG4, "sme_mgt_connection_info_get: unifi_mgt_connection_info_get_req -->\n");
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeConnectionInfoGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
/* store the reply */
- if (connectionInfo != NULL) {
+ if (connectionInfo != NULL)
memcpy((unsigned char*)connectionInfo,
(unsigned char*)&priv->sme_reply.connectionInfo,
sizeof(CsrWifiSmeConnectionInfo));
- }
unifi_trace(priv, UDBG4,
"sme_mgt_connection_info_get: unifi_mgt_connection_info_get_req <-- (r=%d status=%d)\n",
@@ -1192,23 +1137,20 @@ int sme_mgt_connection_config_get(unifi_priv_t *priv, CsrWifiSmeConnectionConfig
unifi_trace(priv, UDBG4, "sme_mgt_connection_config_get: unifi_mgt_connection_config_get_req -->\n");
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeConnectionConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
/* store the reply */
- if (connectionConfig != NULL) {
+ if (connectionConfig != NULL)
memcpy((unsigned char*)connectionConfig,
(unsigned char*)&priv->sme_reply.connectionConfig,
sizeof(CsrWifiSmeConnectionConfig));
- }
unifi_trace(priv, UDBG4,
"sme_mgt_connection_config_get: unifi_mgt_connection_config_get_req <-- (r=%d status=%d)\n",
@@ -1236,23 +1178,20 @@ int sme_mgt_connection_stats_get(unifi_priv_t *priv, CsrWifiSmeConnectionStats *
unifi_trace(priv, UDBG4, "sme_mgt_connection_stats_get: unifi_mgt_connection_stats_get_req -->\n");
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiSmeConnectionStatsGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
/* store the reply */
- if (connectionStats != NULL) {
+ if (connectionStats != NULL)
memcpy((unsigned char*)connectionStats,
(unsigned char*)&priv->sme_reply.connectionStats,
sizeof(CsrWifiSmeConnectionStats));
- }
unifi_trace(priv, UDBG4,
"sme_mgt_connection_stats_get: unifi_mgt_connection_stats_get_req <-- (r=%d status=%d)\n",
@@ -1272,58 +1211,56 @@ int sme_mgt_connection_stats_get(unifi_priv_t *priv, CsrWifiSmeConnectionStats *
int sme_mgt_packet_filter_set(unifi_priv_t *priv)
{
- CsrWifiIp4Address ipAddress = {{0xFF, 0xFF, 0xFF, 0xFF }};
- if (priv->smepriv == NULL) {
- unifi_error(priv, "sme_mgt_packet_filter_set: invalid smepriv\n");
- return -EIO;
- }
- if (priv->packet_filters.arp_filter) {
- ipAddress.a[0] = (priv->sta_ip_address ) & 0xFF;
- ipAddress.a[1] = (priv->sta_ip_address >> 8) & 0xFF;
- ipAddress.a[2] = (priv->sta_ip_address >> 16) & 0xFF;
- ipAddress.a[3] = (priv->sta_ip_address >> 24) & 0xFF;
- }
-
- unifi_trace(priv, UDBG5,
- "sme_mgt_packet_filter_set: IP address %d.%d.%d.%d\n",
- ipAddress.a[0], ipAddress.a[1],
- ipAddress.a[2], ipAddress.a[3]);
-
- /* Doesn't block for a confirm */
- CsrWifiSmePacketFilterSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE,
- priv->packet_filters.tclas_ies_length,
- priv->filter_tclas_ies,
- priv->packet_filters.filter_mode,
- ipAddress);
- return 0;
+ CsrWifiIp4Address ipAddress = {{0xFF, 0xFF, 0xFF, 0xFF }};
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_packet_filter_set: invalid smepriv\n");
+ return -EIO;
+ }
+ if (priv->packet_filters.arp_filter) {
+ ipAddress.a[0] = (priv->sta_ip_address ) & 0xFF;
+ ipAddress.a[1] = (priv->sta_ip_address >> 8) & 0xFF;
+ ipAddress.a[2] = (priv->sta_ip_address >> 16) & 0xFF;
+ ipAddress.a[3] = (priv->sta_ip_address >> 24) & 0xFF;
+ }
+
+ unifi_trace(priv, UDBG5,
+ "sme_mgt_packet_filter_set: IP address %d.%d.%d.%d\n",
+ ipAddress.a[0], ipAddress.a[1],
+ ipAddress.a[2], ipAddress.a[3]);
+
+ /* Doesn't block for a confirm */
+ CsrWifiSmePacketFilterSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE,
+ priv->packet_filters.tclas_ies_length,
+ priv->filter_tclas_ies,
+ priv->packet_filters.filter_mode,
+ ipAddress);
+ return 0;
}
int sme_mgt_tspec(unifi_priv_t *priv, CsrWifiSmeListAction action,
u32 tid, CsrWifiSmeDataBlock *tspec, CsrWifiSmeDataBlock *tclas)
{
- int r;
-
- if (priv->smepriv == NULL) {
- unifi_error(priv, "sme_mgt_tspec: invalid smepriv\n");
- return -EIO;
- }
-
- r = sme_init_request(priv);
- if (r) {
- return -EIO;
- }
-
- CsrWifiSmeTspecReqSend(0, CSR_WIFI_INTERFACE_IN_USE,
- action, tid, TRUE, 0,
- tspec->length, tspec->data,
- tclas->length, tclas->data);
- r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
- return r;
- }
-
- unifi_trace(priv, UDBG4, "sme_mgt_tspec: <-- (status=%d)\n", priv->sme_reply.reply_status);
- return convert_sme_error(priv->sme_reply.reply_status);
+ int r;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_tspec: invalid smepriv\n");
+ return -EIO;
+ }
+
+ r = sme_init_request(priv);
+ if (r)
+ return -EIO;
+
+ CsrWifiSmeTspecReqSend(0, CSR_WIFI_INTERFACE_IN_USE,
+ action, tid, TRUE, 0,
+ tspec->length, tspec->data,
+ tclas->length, tclas->data);
+ r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
+ if (r)
+ return r;
+
+ unifi_trace(priv, UDBG4, "sme_mgt_tspec: <-- (status=%d)\n", priv->sme_reply.reply_status);
+ return convert_sme_error(priv->sme_reply.reply_status);
}
@@ -1339,9 +1276,8 @@ int sme_sys_suspend(unifi_priv_t *priv)
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
/* Suspend the SME, which MAY cause it to power down UniFi */
CsrWifiRouterCtrlSuspendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, 0, priv->wol_suspend);
@@ -1427,17 +1363,15 @@ int sme_sys_resume(unifi_priv_t *priv)
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiRouterCtrlResumeIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, priv->wol_suspend);
r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT);
- if (r) {
+ if (r)
unifi_notice(priv,
"resume: SME did not reply, return success anyway\n");
- }
return 0;
}
@@ -1453,16 +1387,14 @@ int sme_ap_stop(unifi_priv_t *priv,u16 interface_tag)
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiNmeApStopReqSend(0,interface_tag);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
unifi_trace(priv, UDBG4,
"sme_ap_stop <-- (r=%d status=%d)\n",
@@ -1484,9 +1416,8 @@ int sme_ap_start(unifi_priv_t *priv,u16 interface_tag,
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiNmeApStartReqSend(0,interface_tag,CSR_WIFI_AP_TYPE_LEGACY,FALSE,
ap_config->ssid,1,ap_config->channel,
@@ -1494,9 +1425,8 @@ int sme_ap_start(unifi_priv_t *priv,u16 interface_tag,
p2p_go_param,FALSE);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
- if (r) {
+ if (r)
return r;
- }
unifi_trace(priv, UDBG4,
"sme_ap_start <-- (r=%d status=%d)\n",
@@ -1518,14 +1448,15 @@ int sme_ap_config(unifi_priv_t *priv,
}
r = sme_init_request(priv);
- if (r) {
+ if (r)
return -EIO;
- }
CsrWifiNmeApConfigSetReqSend(0,*group_security_config,
*ap_mac_config);
r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
+ if (r)
+ return r;
unifi_trace(priv, UDBG4,
"sme_ap_config <-- (r=%d status=%d)\n",
diff --git a/drivers/staging/csr/sme_native.c b/drivers/staging/csr/sme_native.c
index d7a5125d9a8..525fe1bce0e 100644
--- a/drivers/staging/csr/sme_native.c
+++ b/drivers/staging/csr/sme_native.c
@@ -12,7 +12,6 @@
*/
#include <linux/netdevice.h>
-#include <linux/version.h>
#include "unifi_priv.h"
#include "csr_wifi_hip_unifi.h"
#include "csr_wifi_hip_conversions.h"
@@ -22,23 +21,17 @@ static const unsigned char wildcard_address[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00,
int
uf_sme_init(unifi_priv_t *priv)
{
- func_enter();
-
sema_init(&priv->mlme_blocking_mutex, 1);
#ifdef CSR_SUPPORT_WEXT
{
int r = uf_init_wext_interface(priv);
if (r != 0) {
- func_exit();
return r;
}
}
#endif
-
-
- func_exit();
return 0;
} /* uf_sme_init() */
@@ -47,8 +40,6 @@ void
uf_sme_deinit(unifi_priv_t *priv)
{
- func_enter();
-
/* Free memory allocated for the scan table */
/* unifi_clear_scan_table(priv); */
@@ -59,8 +50,6 @@ uf_sme_deinit(unifi_priv_t *priv)
uf_deinit_wext_interface(priv);
#endif
-
- func_exit();
} /* uf_sme_deinit() */
@@ -222,8 +211,6 @@ sme_native_log_event(ul_client_t *pcli,
CSR_SIGNAL signal;
ul_client_t *client = pcli;
- func_enter();
-
if (client == NULL) {
unifi_error(NULL, "sme_native_log_event: client has exited\n");
return;
@@ -334,8 +321,6 @@ sme_native_log_event(ul_client_t *pcli,
/* Wake any waiting user process */
wake_up_interruptible(&client->udi_wq);
- func_exit();
-
} /* sme_native_log_event() */
@@ -461,8 +446,6 @@ sme_native_mlme_event_handler(ul_client_t *pcli,
unifi_priv_t *priv = uf_find_instance(pcli->instance);
int id, r;
- func_enter();
-
/* Just a sanity check */
if ((sig_packed == NULL) || (sig_len <= 0)) {
return;
@@ -542,7 +525,6 @@ sme_native_mlme_event_handler(ul_client_t *pcli,
break;
}
- func_exit();
} /* sme_native_mlme_event_handler() */
@@ -574,14 +556,11 @@ unifi_reset_state(unifi_priv_t *priv, unsigned char *macaddr,
{
int r = 0;
- func_enter();
-
#ifdef CSR_SUPPORT_WEXT
/* The reset clears any 802.11 association. */
priv->wext_conf.flag_associated = 0;
#endif
- func_exit();
return r;
} /* unifi_reset_state() */
diff --git a/drivers/staging/csr/sme_sys.c b/drivers/staging/csr/sme_sys.c
index 5b26c41c01f..2b068197ed4 100644
--- a/drivers/staging/csr/sme_sys.c
+++ b/drivers/staging/csr/sme_sys.c
@@ -14,7 +14,6 @@
* ---------------------------------------------------------------------------
*/
-#include <linux/version.h>
#include "csr_wifi_hip_unifiversion.h"
#include "unifi_priv.h"
#include "csr_wifi_hip_conversions.h"
@@ -413,8 +412,6 @@ uf_send_gratuitous_arp(unifi_priv_t *priv, u16 interfaceTag)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xc0, 0xa8, 0x00, 0x02};
- func_enter();
-
csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], sizeof(arp_req));
if (csrResult != CSR_RESULT_SUCCESS)
{
@@ -480,8 +477,6 @@ uf_send_gratuitous_arp(unifi_priv_t *priv, u16 interfaceTag)
return;
}
- func_exit();
-
}
#endif /* CSR_WIFI_SEND_GRATUITOUS_ARP */
@@ -2102,7 +2097,7 @@ static int peer_add_new_record(unifi_priv_t *priv,CsrWifiRouterCtrlPeerAddReq *r
u8 freeSlotFound = FALSE;
CsrWifiRouterCtrlStaInfo_t *newRecord = NULL;
netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
- CsrTime currentTime, currentTimeHi;
+ u32 currentTime, currentTimeHi;
unsigned long lock_flags;
if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
@@ -2296,8 +2291,8 @@ static void check_inactivity_timer_expire_func(unsigned long data)
struct unifi_priv *priv;
CsrWifiRouterCtrlStaInfo_t *sta_record = NULL;
u8 i = 0;
- CsrTime now;
- CsrTime inactive_time;
+ u32 now;
+ u32 inactive_time;
netInterface_priv_t *interfacePriv = (netInterface_priv_t *) data;
if (!interfacePriv)
@@ -2329,11 +2324,11 @@ static void check_inactivity_timer_expire_func(unsigned long data)
if (sta_record->lastActivity > now)
{
/* simple timer wrap (for 1 wrap) */
- inactive_time = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, sta_record->lastActivity), now);
+ inactive_time = CsrTimeAdd((u32)CsrTimeSub(CSR_SCHED_TIME_MAX, sta_record->lastActivity), now);
}
else
{
- inactive_time = (CsrTime)CsrTimeSub(now, sta_record->lastActivity);
+ inactive_time = (u32)CsrTimeSub(now, sta_record->lastActivity);
}
if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL)
@@ -2411,8 +2406,6 @@ void uf_send_disconnected_ind_wq(struct work_struct *work)
struct list_head send_cfm_list;
u8 j;
- func_enter();
-
if(!staInfo) {
return;
}
diff --git a/drivers/staging/csr/sme_userspace.h b/drivers/staging/csr/sme_userspace.h
index 7816b15b4b5..ebe371c732b 100644
--- a/drivers/staging/csr/sme_userspace.h
+++ b/drivers/staging/csr/sme_userspace.h
@@ -32,7 +32,7 @@ int uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length);
#include "csr_wifi_sme_lib.h"
void CsrWifiRouterTransportInit(unifi_priv_t *priv);
-void CsrWifiRouterTransportRecv(unifi_priv_t *priv, u8* buffer, size_t bufferLength);
+void CsrWifiRouterTransportRecv(unifi_priv_t *priv, u8 *buffer, size_t bufferLength);
void CsrWifiRouterTransportDeInit(unifi_priv_t *priv);
#endif /* __LINUX_SME_USERSPACE_H__ */
diff --git a/drivers/staging/csr/sme_wext.c b/drivers/staging/csr/sme_wext.c
index b58c0c6b171..5e06a380b40 100644
--- a/drivers/staging/csr/sme_wext.c
+++ b/drivers/staging/csr/sme_wext.c
@@ -800,7 +800,6 @@ iwprivsconfwapi(struct net_device *dev, struct iw_request_info *info,
u8 enable;
netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
unifi_priv_t *priv = interfacePriv->privPtr;
- func_enter();
unifi_trace(priv, UDBG1, "iwprivsconfwapi\n" );
@@ -824,7 +823,6 @@ iwprivsconfwapi(struct net_device *dev, struct iw_request_info *info,
~(CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_SMS4 | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_SMS4);
}
- func_exit();
return 0;
}
@@ -837,7 +835,6 @@ iwprivswpikey(struct net_device *dev, struct iw_request_info *info,
unifiio_wapi_key_t inKey;
netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
unifi_priv_t *priv = interfacePriv->privPtr;
- func_enter();
unifi_trace(priv, UDBG1, "iwprivswpikey\n" );
@@ -882,7 +879,6 @@ iwprivswpikey(struct net_device *dev, struct iw_request_info *info,
return convert_sme_error(r);
}
- func_exit();
return r;
}
#endif
@@ -914,7 +910,6 @@ unifi_siwfreq(struct net_device *dev, struct iw_request_info *info,
unifi_priv_t *priv = interfacePriv->privPtr;
struct iw_freq *freq = (struct iw_freq *)wrqu;
- func_enter();
unifi_trace(priv, UDBG2, "unifi_siwfreq\n");
if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
@@ -935,7 +930,6 @@ unifi_siwfreq(struct net_device *dev, struct iw_request_info *info,
priv->connection_config.adhocChannel = wext_freq_to_channel(freq->m, freq->e);
}
- func_exit();
return 0;
} /* unifi_siwfreq() */
@@ -950,7 +944,6 @@ unifi_giwfreq(struct net_device *dev, struct iw_request_info *info,
int err = 0;
CsrWifiSmeConnectionInfo connectionInfo;
- func_enter();
unifi_trace(priv, UDBG2, "unifi_giwfreq\n");
CHECK_INITED(priv);
@@ -970,7 +963,6 @@ unifi_giwfreq(struct net_device *dev, struct iw_request_info *info,
(connectionInfo.networkType80211 == CSR_WIFI_SME_RADIO_IF_GHZ_5_0));
freq->e = 6;
- func_exit();
return convert_sme_error(err);
} /* unifi_giwfreq() */
@@ -982,7 +974,6 @@ unifi_siwmode(struct net_device *dev, struct iw_request_info *info,
netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
unifi_priv_t *priv = interfacePriv->privPtr;
- func_enter();
unifi_trace(priv, UDBG2, "unifi_siwmode\n");
if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
@@ -1011,7 +1002,6 @@ unifi_siwmode(struct net_device *dev, struct iw_request_info *info,
priv->connection_config.ssid.length = 0;
memset(priv->connection_config.bssid.a, 0xFF, ETH_ALEN);
- func_exit();
return 0;
} /* unifi_siwmode() */
@@ -1026,7 +1016,6 @@ unifi_giwmode(struct net_device *dev, struct iw_request_info *info,
unifi_priv_t *priv = interfacePriv->privPtr;
CsrWifiSmeConnectionConfig connectionConfig;
- func_enter();
unifi_trace(priv, UDBG2, "unifi_giwmode\n");
CHECK_INITED(priv);
@@ -1069,7 +1058,6 @@ unifi_giwmode(struct net_device *dev, struct iw_request_info *info,
}
unifi_trace(priv, UDBG4, "unifi_giwmode: mode = 0x%x\n", wrqu->mode);
- func_exit();
return r;
} /* unifi_giwmode() */
@@ -1192,8 +1180,6 @@ unifi_siwap(struct net_device *dev, struct iw_request_info *info,
unifi_priv_t *priv = interfacePriv->privPtr;
int err = 0;
- func_enter();
-
CHECK_INITED(priv);
if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
@@ -1235,11 +1221,9 @@ unifi_siwap(struct net_device *dev, struct iw_request_info *info,
err = sme_mgt_connect(priv);
if (err) {
unifi_error(priv, "unifi_siwap: Join failed, status %d\n", err);
- func_exit();
return convert_sme_error(err);
}
}
- func_exit();
return 0;
} /* unifi_siwap() */
@@ -1255,8 +1239,6 @@ unifi_giwap(struct net_device *dev, struct iw_request_info *info,
int r = 0;
u8 *bssid;
- func_enter();
-
CHECK_INITED(priv);
unifi_trace(priv, UDBG2, "unifi_giwap\n");
@@ -1281,7 +1263,6 @@ unifi_giwap(struct net_device *dev, struct iw_request_info *info,
memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
}
- func_exit();
return 0;
} /* unifi_giwap() */
@@ -1302,8 +1283,6 @@ unifi_siwscan(struct net_device *dev, struct iw_request_info *info,
struct iw_scan_req *req = (struct iw_scan_req *) extra;
#endif
- func_enter();
-
CHECK_INITED(priv);
if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
@@ -1366,7 +1345,6 @@ unifi_siwscan(struct net_device *dev, struct iw_request_info *info,
kfree(channel_list);
}
- func_exit();
return r;
} /* unifi_siwscan() */
@@ -1707,7 +1685,6 @@ unifi_siwessid(struct net_device *dev, struct iw_request_info *info,
int len;
int err = 0;
- func_enter();
CHECK_INITED(priv);
if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
@@ -1760,11 +1737,9 @@ unifi_siwessid(struct net_device *dev, struct iw_request_info *info,
UF_RTNL_LOCK();
if (err) {
unifi_error(priv, "unifi_siwessid: Join failed, status %d\n", err);
- func_exit();
return convert_sme_error(err);
}
- func_exit();
return 0;
} /* unifi_siwessid() */
@@ -1779,7 +1754,6 @@ unifi_giwessid(struct net_device *dev, struct iw_request_info *info,
CsrWifiSmeConnectionInfo connectionInfo;
int r = 0;
- func_enter();
unifi_trace(priv, UDBG2, "unifi_giwessid\n");
CHECK_INITED(priv);
@@ -1805,7 +1779,6 @@ unifi_giwessid(struct net_device *dev, struct iw_request_info *info,
data->length, essid);
}
- func_exit();
return 0;
} /* unifi_giwessid() */
@@ -1821,8 +1794,6 @@ unifi_siwrate(struct net_device *dev, struct iw_request_info *info,
CsrWifiSmeMibConfig mibConfig;
int r;
- func_enter();
-
CHECK_INITED(priv);
unifi_trace(priv, UDBG2, "unifi_siwrate\n");
@@ -1863,7 +1834,6 @@ unifi_siwrate(struct net_device *dev, struct iw_request_info *info,
return r;
}
- func_exit();
return 0;
} /* unifi_siwrate() */
@@ -1882,7 +1852,6 @@ unifi_giwrate(struct net_device *dev, struct iw_request_info *info,
CsrWifiSmeMibConfig mibConfig;
CsrWifiSmeConnectionStats connectionStats;
- func_enter();
unifi_trace(priv, UDBG2, "unifi_giwrate\n");
CHECK_INITED(priv);
@@ -1913,8 +1882,6 @@ unifi_giwrate(struct net_device *dev, struct iw_request_info *info,
args->value = bitrate * 500000;
args->fixed = !flag;
- func_exit();
-
return 0;
} /* unifi_giwrate() */
@@ -2081,7 +2048,6 @@ unifi_siwencode(struct net_device *dev, struct iw_request_info *info,
int privacy = -1;
CsrWifiSmeKey sme_key;
- func_enter();
unifi_trace(priv, UDBG2, "unifi_siwencode\n");
CHECK_INITED(priv);
@@ -2236,7 +2202,6 @@ unifi_siwencode(struct net_device *dev, struct iw_request_info *info,
CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE;
}
- func_exit_r(rc);
return convert_sme_error(rc);
} /* unifi_siwencode() */
@@ -2467,7 +2432,6 @@ unifi_siwmlme(struct net_device *dev, struct iw_request_info *info,
netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
unifi_priv_t *priv = interfacePriv->privPtr;
struct iw_mlme *mlme = (struct iw_mlme *)extra;
- func_enter();
unifi_trace(priv, UDBG2, "unifi_siwmlme\n");
CHECK_INITED(priv);
@@ -2488,11 +2452,9 @@ unifi_siwmlme(struct net_device *dev, struct iw_request_info *info,
UF_RTNL_LOCK();
break;
default:
- func_exit_r(-EOPNOTSUPP);
return -EOPNOTSUPP;
}
- func_exit();
return 0;
} /* unifi_siwmlme() */
@@ -2529,7 +2491,6 @@ unifi_siwgenie(struct net_device *dev, struct iw_request_info *info,
unifi_priv_t *priv = interfacePriv->privPtr;
int len;
- func_enter();
unifi_trace(priv, UDBG2, "unifi_siwgenie\n");
if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
@@ -2548,20 +2509,17 @@ unifi_siwgenie(struct net_device *dev, struct iw_request_info *info,
len = wrqu->data.length;
if (len == 0) {
- func_exit();
return 0;
}
priv->connection_config.mlmeAssociateReqInformationElements = kmalloc(len, GFP_KERNEL);
if (priv->connection_config.mlmeAssociateReqInformationElements == NULL) {
- func_exit();
return -ENOMEM;
}
priv->connection_config.mlmeAssociateReqInformationElementsLength = len;
memcpy( priv->connection_config.mlmeAssociateReqInformationElements, extra, len);
- func_exit();
return 0;
} /* unifi_siwgenie() */
@@ -2574,7 +2532,6 @@ unifi_giwgenie(struct net_device *dev, struct iw_request_info *info,
unifi_priv_t *priv = interfacePriv->privPtr;
int len;
- func_enter();
unifi_trace(priv, UDBG2, "unifi_giwgenie\n");
if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
@@ -2599,7 +2556,6 @@ unifi_giwgenie(struct net_device *dev, struct iw_request_info *info,
wrqu->data.length = len;
memcpy(extra, priv->connection_config.mlmeAssociateReqInformationElements, len);
- func_exit();
return 0;
} /* unifi_giwgenie() */
@@ -2627,7 +2583,6 @@ _unifi_siwauth(struct net_device *dev, struct iw_request_info *info,
unifi_priv_t *priv = interfacePriv->privPtr;
CsrWifiSmeAuthModeMask new_auth;
- func_enter();
unifi_trace(priv, UDBG2, "unifi_siwauth\n");
if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
@@ -2848,7 +2803,6 @@ _unifi_siwauth(struct net_device *dev, struct iw_request_info *info,
}
unifi_trace(priv, UDBG2, "authModeMask = %d", priv->connection_config.authModeMask);
- func_exit();
return 0;
} /* _unifi_siwauth() */
@@ -2911,8 +2865,6 @@ _unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info,
CsrWifiSmeKey sme_key;
CsrWifiSmeKeyType key_type;
- func_enter();
-
CHECK_INITED(priv);
if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
@@ -3061,7 +3013,6 @@ _unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info,
return convert_sme_error(r);
}
- func_exit();
return r;
} /* _unifi_siwencodeext() */
diff --git a/drivers/staging/csr/ul_int.c b/drivers/staging/csr/ul_int.c
index 4013d021ebb..0fae6f48f79 100644
--- a/drivers/staging/csr/ul_int.c
+++ b/drivers/staging/csr/ul_int.c
@@ -12,7 +12,6 @@
*
* ***************************************************************************
*/
-#include <linux/version.h>
#include "csr_wifi_hip_unifi.h"
#include "csr_wifi_hip_conversions.h"
#include "unifi_priv.h"
diff --git a/drivers/staging/csr/unifi_event.c b/drivers/staging/csr/unifi_event.c
index c27b23daf39..e81a9987827 100644
--- a/drivers/staging/csr/unifi_event.c
+++ b/drivers/staging/csr/unifi_event.c
@@ -376,8 +376,6 @@ unifi_process_receive_event(void *ospriv,
s16 signal_id;
u8 pktIndToSme = FALSE, freeBulkData = FALSE;
- func_enter();
-
unifi_trace(priv, UDBG5, "unifi_process_receive_event: "
"%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n",
CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*0) & 0xFFFF,
@@ -523,7 +521,6 @@ unifi_process_receive_event(void *ospriv,
unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
}
}
- func_exit();
return;
}
} /* CSR_MA_PACKET_INDICATION_ID */
@@ -573,7 +570,6 @@ unifi_process_receive_event(void *ospriv,
}
}
- func_exit();
} /* unifi_process_receive_event() */
@@ -587,7 +583,6 @@ void unifi_rx_queue_flush(void *ospriv)
{
unifi_priv_t *priv = (unifi_priv_t*)ospriv;
- func_enter();
unifi_trace(priv, UDBG4, "rx_wq_handler: RdPtr = %d WritePtr = %d\n",
priv->rxSignalBuffer.readPointer,priv->rxSignalBuffer.writePointer);
if(priv != NULL) {
@@ -605,7 +600,6 @@ void unifi_rx_queue_flush(void *ospriv)
}
priv->rxSignalBuffer.readPointer = readPointer;
}
- func_exit();
}
void rx_wq_handler(struct work_struct *work)
@@ -655,7 +649,6 @@ unifi_receive_event(void *ospriv,
u8 writePointer;
int i;
rx_buff_struct_t * rx_buff;
- func_enter();
unifi_trace(priv, UDBG5, "unifi_receive_event: "
"%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n",
@@ -695,6 +688,5 @@ unifi_receive_event(void *ospriv,
#else
unifi_process_receive_event(ospriv, sigdata, siglen, bulkdata);
#endif
- func_exit();
} /* unifi_receive_event() */
diff --git a/drivers/staging/csr/unifi_os.h b/drivers/staging/csr/unifi_os.h
index 4e63a942f1a..56a26982070 100644
--- a/drivers/staging/csr/unifi_os.h
+++ b/drivers/staging/csr/unifi_os.h
@@ -61,26 +61,6 @@ extern int unifi_debug;
* etc.
*/
-#define func_enter() \
- do { \
- if (unifi_debug >= 5) { \
- printk("unifi: => %s\n", __FUNCTION__); \
- } \
- } while (0)
-#define func_exit() \
- do { \
- if (unifi_debug >= 5) { \
- printk("unifi: <= %s\n", __FUNCTION__); \
- } \
- } while (0)
-#define func_exit_r(_rc) \
- do { \
- if (unifi_debug >= 5) { \
- printk("unifi: <= %s %d\n", __FUNCTION__, (int)(_rc)); \
- } \
- } while (0)
-
-
#define ASSERT(cond) \
do { \
if (!(cond)) { \
@@ -107,9 +87,6 @@ void unifi_trace(void* ospriv, int level, const char *fmt, ...);
#else
/* Stubs */
-#define func_enter()
-#define func_exit()
-#define func_exit_r(_rc)
#define ASSERT(cond)
diff --git a/drivers/staging/csr/unifi_pdu_processing.c b/drivers/staging/csr/unifi_pdu_processing.c
index ae7c8fc9409..95efc360cc2 100644
--- a/drivers/staging/csr/unifi_pdu_processing.c
+++ b/drivers/staging/csr/unifi_pdu_processing.c
@@ -14,7 +14,6 @@
* ---------------------------------------------------------------------------
*/
-#include <linux/version.h>
#include <linux/types.h>
#include <linux/etherdevice.h>
#include <linux/vmalloc.h>
@@ -409,7 +408,6 @@ CsrResult enque_tx_data_pdu(unifi_priv_t *priv, bulk_data_param_t *bulkdata,
unifi_error(priv,
"Failed to allocate %d bytes for tx packet record\n",
sizeof(tx_buffered_packets_t));
- func_exit();
return CSR_RESULT_FAILURE;
}
@@ -1117,8 +1115,8 @@ void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv,u16 interfaceTag, const CSR
staRecord->nullDataHostTag = INVALID_HOST_TAG;
if(pkt_cfm->TransmissionStatus == CSR_TX_RETRY_LIMIT){
- CsrTime now;
- CsrTime inactive_time;
+ u32 now;
+ u32 inactive_time;
unifi_trace(priv, UDBG1, "Nulldata to probe STA ALIVE Failed with retry limit\n");
/* Recheck if there is some activity after null data is sent.
@@ -1134,12 +1132,12 @@ void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv,u16 interfaceTag, const CSR
if (staRecord->lastActivity > now)
{
/* simple timer wrap (for 1 wrap) */
- inactive_time = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, staRecord->lastActivity),
+ inactive_time = CsrTimeAdd((u32)CsrTimeSub(CSR_SCHED_TIME_MAX, staRecord->lastActivity),
now);
}
else
{
- inactive_time = (CsrTime)CsrTimeSub(now, staRecord->lastActivity);
+ inactive_time = (u32)CsrTimeSub(now, staRecord->lastActivity);
}
if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL)
@@ -2024,7 +2022,6 @@ u8 send_multicast_frames(unifi_priv_t *priv, u16 interfaceTag)
netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
u32 hostTag = 0xffffffff;
- func_enter();
if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_VO)) {
while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastMgtFrames))) {
buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK);
@@ -2124,7 +2121,6 @@ void uf_process_ma_vif_availibility_ind(unifi_priv_t *priv,u8 *sigdata,
CSR_RESULT_CODE resultCode = CSR_RC_SUCCESS;
netInterface_priv_t *interfacePriv;
- func_enter();
unifi_trace(priv, UDBG3,
"uf_process_ma_vif_availibility_ind: Process signal 0x%.4X\n",
*((u16*)sigdata));
@@ -2134,7 +2130,6 @@ void uf_process_ma_vif_availibility_ind(unifi_priv_t *priv,u8 *sigdata,
unifi_error(priv,
"uf_process_ma_vif_availibility_ind: Received unknown signal 0x%.4X.\n",
CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata));
- func_exit();
return;
}
ind = &signal.u.MaVifAvailabilityIndication;
@@ -2369,8 +2364,6 @@ void uf_send_buffered_data_from_ac(unifi_priv_t *priv,
u8 moreData = FALSE;
s8 r =0;
- func_enter();
-
unifi_trace(priv,UDBG2,"uf_send_buffered_data_from_ac :\n");
while(!isRouterBufferEnabled(priv,queue) &&
@@ -2399,8 +2392,6 @@ void uf_send_buffered_data_from_ac(unifi_priv_t *priv,
}
}
- func_exit();
-
}
void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q)
@@ -2416,7 +2407,6 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q)
if(!((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) ||
(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)))
return;
- func_enter();
queue = (q<=3)?q:0;
@@ -2451,7 +2441,6 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q)
interfacePriv->dtimActive = FALSE;
}
}
- func_exit();
return;
}
if(priv->pausedStaHandle[queue] > 7) {
@@ -2542,7 +2531,6 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q)
*/
unifi_trace(priv, UDBG4, "csrWifiHipSendBufferedFrames: UAPSD Resume Q=%x\n", queue);
resume_suspended_uapsd(priv, interfaceTag);
- func_exit();
}
@@ -2770,7 +2758,6 @@ void uf_send_qos_null(unifi_priv_t * priv,u16 interfaceTag, const u8 *da,CSR_PRI
CSR_RATE transmitRate = 0;
- func_enter();
/* Send a Null Frame to Peer,
* 32= size of mac header */
csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], MAC_HEADER_SIZE + QOS_CONTROL_HEADER_SIZE);
@@ -2823,7 +2810,6 @@ void uf_send_qos_null(unifi_priv_t * priv,u16 interfaceTag, const u8 *da,CSR_PRI
unifi_net_data_free(priv, &bulkdata.d[0]);
}
- func_exit();
return;
}
@@ -2842,7 +2828,6 @@ void uf_send_nulldata(unifi_priv_t * priv,u16 interfaceTag, const u8 *da,CSR_PRI
CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
unsigned long lock_flags;
- func_enter();
/* Send a Null Frame to Peer, size = 24 for MAC header */
csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], MAC_HEADER_SIZE);
@@ -2909,7 +2894,6 @@ void uf_send_nulldata(unifi_priv_t * priv,u16 interfaceTag, const u8 *da,CSR_PRI
srcStaInfo->nullDataHostTag = INVALID_HOST_TAG;
}
- func_exit();
return;
}
@@ -3327,8 +3311,6 @@ void uf_prepare_send_cfm_list_for_queued_pkts(unifi_priv_t * priv,
struct list_head *placeHolder;
unsigned long lock_flags;
- func_enter();
-
spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
/* Search through the list and if confirmation required for any frames,
@@ -3357,7 +3339,6 @@ void uf_prepare_send_cfm_list_for_queued_pkts(unifi_priv_t * priv,
spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
- func_exit();
}
@@ -3492,11 +3473,11 @@ CsrWifiRouterCtrlStaInfo_t * CsrWifiRouterCtrlGetStationRecordFromHandle(unifi_p
}
/* Function to do inactivity */
-void uf_check_inactivity(unifi_priv_t *priv, u16 interfaceTag, CsrTime currentTime)
+void uf_check_inactivity(unifi_priv_t *priv, u16 interfaceTag, u32 currentTime)
{
u32 i;
CsrWifiRouterCtrlStaInfo_t *staInfo;
- CsrTime elapsedTime; /* Time in microseconds */
+ u32 elapsedTime; /* Time in microseconds */
netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
CsrWifiMacAddress peerMacAddress;
unsigned long lock_flags;
@@ -3543,8 +3524,8 @@ void uf_check_inactivity(unifi_priv_t *priv, u16 interfaceTag, CsrTime currentTi
/* Function to update activity of a station */
void uf_update_sta_activity(unifi_priv_t *priv, u16 interfaceTag, const u8 *peerMacAddress)
{
- CsrTime elapsedTime, currentTime; /* Time in microseconds */
- CsrTime timeHi; /* Not used - Time in microseconds */
+ u32 elapsedTime, currentTime; /* Time in microseconds */
+ u32 timeHi; /* Not used - Time in microseconds */
CsrWifiRouterCtrlStaInfo_t *staInfo;
netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
unsigned long lock_flags;
@@ -3595,7 +3576,6 @@ void resume_unicast_buffered_frames(unifi_priv_t *priv, u16 interfaceTag)
int r;
unsigned long lock_flags;
- func_enter();
while(!isRouterBufferEnabled(priv,3) &&
((buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMgtFrames))!=NULL)) {
buffered_pkt->transmissionControl &=
@@ -3672,7 +3652,6 @@ void resume_unicast_buffered_frames(unifi_priv_t *priv, u16 interfaceTag)
}
}
}
- func_exit();
}
void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,u16 interfaceTag)
{
@@ -3683,7 +3662,6 @@ void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,u16 interface
struct list_head *placeHolder;
tx_buffered_packets_t *tx_q_item;
- func_enter();
if (interfacePriv->noOfbroadcastPktQueued) {
/* Update the EOSP to the HEAD of b/c list
@@ -3700,7 +3678,6 @@ void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,u16 interface
}
spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
}
- func_exit();
}
/*
diff --git a/drivers/staging/csr/unifi_priv.h b/drivers/staging/csr/unifi_priv.h
index aec8e28fb60..d20d74ce56c 100644
--- a/drivers/staging/csr/unifi_priv.h
+++ b/drivers/staging/csr/unifi_priv.h
@@ -17,7 +17,6 @@
#ifndef __LINUX_UNIFI_PRIV_H__
#define __LINUX_UNIFI_PRIV_H__ 1
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/errno.h>
@@ -313,7 +312,7 @@ typedef struct CsrWifiRouterCtrlStaInfo_t {
CSR_CLIENT_TAG nullDataHostTag;
/* Activity timestamps for the station */
- CsrTime lastActivity;
+ u32 lastActivity;
/* during m/c transmission sp suspended */
u8 uspSuspend;
@@ -653,7 +652,7 @@ typedef struct {
bulk_data_param_t bulkdata;
CSR_SIGNAL signal;
u16 sn;
- CsrTime recv_time;
+ u32 recv_time;
} frame_desc_struct;
typedef struct {
@@ -736,7 +735,7 @@ typedef struct netInterface_priv
u8 sta_activity_check_enabled;
/* Timestamp when the last inactivity check was done */
- CsrTime last_inactivity_check;
+ u32 last_inactivity_check;
/*number of multicast or borad cast packets queued*/
u16 noOfbroadcastPktQueued;
diff --git a/drivers/staging/csr/unifi_sme.c b/drivers/staging/csr/unifi_sme.c
index ff639d47d07..7c6c4138fc7 100644
--- a/drivers/staging/csr/unifi_sme.c
+++ b/drivers/staging/csr/unifi_sme.c
@@ -78,23 +78,19 @@ sme_log_event(ul_client_t *pcli,
CsrResult result = CSR_RESULT_SUCCESS;
int r;
- func_enter();
/* Just a sanity check */
if ((signal == NULL) || (signal_len <= 0)) {
- func_exit();
return;
}
priv = uf_find_instance(pcli->instance);
if (!priv) {
unifi_error(priv, "sme_log_event: invalid priv\n");
- func_exit();
return;
}
if (priv->smepriv == NULL) {
unifi_error(priv, "sme_log_event: invalid smepriv\n");
- func_exit();
return;
}
@@ -109,7 +105,6 @@ sme_log_event(ul_client_t *pcli,
if ((unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_DEBUG_STRING_INDICATION_ID) ||
(unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_DEBUG_WORD16_INDICATION_ID))
{
- func_exit();
return;
}
if (unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_INDICATION_ID)
@@ -171,7 +166,6 @@ sme_log_event(ul_client_t *pcli,
if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
{
unifi_error(priv, "Bad MA_PACKET_CONFIRM interfaceTag %d\n", interfaceTag);
- func_exit();
return;
}
@@ -219,7 +213,6 @@ sme_log_event(ul_client_t *pcli,
} else {
unifi_trace(priv, UDBG1, "%s: M4 received from netdevice\n", __FUNCTION__);
}
- func_exit();
return;
}
}
@@ -248,7 +241,6 @@ sme_log_event(ul_client_t *pcli,
dataref1.length, dataref1.data,
dataref2.length, dataref2.data);
- func_exit();
} /* sme_log_event() */
@@ -1158,8 +1150,6 @@ uf_send_m4_ready_wq(struct work_struct *work)
CsrWifiMacAddress peer;
unsigned long flags;
- func_enter();
-
/* The peer address was stored in the signal */
spin_lock_irqsave(&priv->m4_lock, flags);
memcpy(peer.a, req->Ra.x, sizeof(peer.a));
@@ -1171,8 +1161,6 @@ uf_send_m4_ready_wq(struct work_struct *work)
unifi_trace(priv, UDBG1, "M4ReadyToSendInd sent for peer %pMF\n",
peer.a);
- func_exit();
-
} /* uf_send_m4_ready_wq() */
#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
@@ -1204,8 +1192,6 @@ void uf_send_pkt_to_encrypt(struct work_struct *work)
if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) {
- func_enter();
-
pktBulkDataLength = interfacePriv->wapi_unicast_bulk_data.data_length;
if (pktBulkDataLength > 0) {
@@ -1231,7 +1217,6 @@ void uf_send_pkt_to_encrypt(struct work_struct *work)
kfree(pktBulkData); /* Would have been copied over by the SME Handler */
- func_exit();
} else {
unifi_warning(priv, "uf_send_pkt_to_encrypt() is NOT applicable for interface mode - %d\n",interfacePriv->interfaceMode);
}
diff --git a/drivers/staging/csr/unifi_wext.h b/drivers/staging/csr/unifi_wext.h
index 6834c43abfb..beba089e2e3 100644
--- a/drivers/staging/csr/unifi_wext.h
+++ b/drivers/staging/csr/unifi_wext.h
@@ -16,7 +16,6 @@
#define __LINUX_UNIFI_WEXT_H__ 1
#include <linux/kernel.h>
-#include <linux/version.h>
#include <net/iw_handler.h>
#include "csr_wifi_sme_prim.h"
diff --git a/drivers/staging/cxt1e1/musycc.c b/drivers/staging/cxt1e1/musycc.c
index ba721c60406..b2cc68a1fe8 100644
--- a/drivers/staging/cxt1e1/musycc.c
+++ b/drivers/staging/cxt1e1/musycc.c
@@ -55,26 +55,26 @@ extern int cxt1e1_max_mtu;
extern int max_rxdesc_used;
extern int max_txdesc_used;
extern ci_t *CI; /* dummy pointr to board ZEROE's data - DEBUG
- * USAGE */
+ * USAGE */
/*******************************************************************/
/* forward references */
-void c4_fifo_free (mpi_t *, int);
-void c4_wk_chan_restart (mch_t *);
-void musycc_bh_tx_eom (mpi_t *, int);
-int musycc_chan_up (ci_t *, int);
-status_t __init musycc_init (ci_t *);
-STATIC void __init musycc_init_port (mpi_t *);
-void musycc_intr_bh_tasklet (ci_t *);
-void musycc_serv_req (mpi_t *, u_int32_t);
-void musycc_update_timeslots (mpi_t *);
+void c4_fifo_free(mpi_t *, int);
+void c4_wk_chan_restart(mch_t *);
+void musycc_bh_tx_eom(mpi_t *, int);
+int musycc_chan_up(ci_t *, int);
+status_t __init musycc_init(ci_t *);
+STATIC void __init musycc_init_port(mpi_t *);
+void musycc_intr_bh_tasklet(ci_t *);
+void musycc_serv_req(mpi_t *, u_int32_t);
+void musycc_update_timeslots(mpi_t *);
/*******************************************************************/
#if 1
STATIC int
-musycc_dump_rxbuffer_ring (mch_t * ch, int lockit)
+musycc_dump_rxbuffer_ring(mch_t * ch, int lockit)
{
struct mdesc *m;
unsigned long flags = 0;
@@ -83,71 +83,64 @@ musycc_dump_rxbuffer_ring (mch_t * ch, int lockit)
int n;
if (lockit)
- {
- spin_lock_irqsave (&ch->ch_rxlock, flags);
- }
+ spin_lock_irqsave(&ch->ch_rxlock, flags);
if (ch->rxd_num == 0)
- {
- pr_info(" ZERO receive buffers allocated for this channel.");
- } else
- {
- FLUSH_MEM_READ ();
- m = &ch->mdr[ch->rxix_irq_srv];
- for (n = ch->rxd_num; n; n--)
- {
- status = le32_to_cpu (m->status);
- {
- pr_info("%c %08lx[%2d]: sts %08x (%c%c%c%c:%d.) Data [%08x] Next [%08x]\n",
- (m == &ch->mdr[ch->rxix_irq_srv]) ? 'F' : ' ',
- (unsigned long) m, n,
- status,
- m->data ? (status & HOST_RX_OWNED ? 'H' : 'M') : '-',
- status & POLL_DISABLED ? 'P' : '-',
- status & EOBIRQ_ENABLE ? 'b' : '-',
- status & EOMIRQ_ENABLE ? 'm' : '-',
- status & LENGTH_MASK,
- le32_to_cpu (m->data), le32_to_cpu (m->next));
+ pr_info(" ZERO receive buffers allocated for this channel.");
+ else {
+ FLUSH_MEM_READ();
+ m = &ch->mdr[ch->rxix_irq_srv];
+ for (n = ch->rxd_num; n; n--) {
+ status = le32_to_cpu(m->status);
+ {
+ pr_info("%c %08lx[%2d]: sts %08x (%c%c%c%c:%d.) Data [%08x] Next [%08x]\n",
+ (m == &ch->mdr[ch->rxix_irq_srv]) ? 'F' : ' ',
+ (unsigned long) m, n,
+ status,
+ m->data ? (status & HOST_RX_OWNED ? 'H' : 'M') : '-',
+ status & POLL_DISABLED ? 'P' : '-',
+ status & EOBIRQ_ENABLE ? 'b' : '-',
+ status & EOMIRQ_ENABLE ? 'm' : '-',
+ status & LENGTH_MASK,
+ le32_to_cpu(m->data), le32_to_cpu(m->next));
#ifdef RLD_DUMP_BUFDATA
- {
- u_int32_t *dp;
- int len = status & LENGTH_MASK;
+ {
+ u_int32_t *dp;
+ int len = status & LENGTH_MASK;
#if 1
- if (m->data && (status & HOST_RX_OWNED))
+ if (m->data && (status & HOST_RX_OWNED))
#else
- if (m->data) /* always dump regardless of valid RX
- * data */
+ if (m->data) /* always dump regardless of valid RX
+ * data */
#endif
- {
- dp = (u_int32_t *) OS_phystov ((void *) (le32_to_cpu (m->data)));
- if (len >= 0x10)
- pr_info(" %x[%x]: %08X %08X %08X %08x\n", (u_int32_t) dp, len,
- *dp, *(dp + 1), *(dp + 2), *(dp + 3));
- else if (len >= 0x08)
- pr_info(" %x[%x]: %08X %08X\n", (u_int32_t) dp, len,
- *dp, *(dp + 1));
- else
- pr_info(" %x[%x]: %08X\n", (u_int32_t) dp, len, *dp);
- }
- }
+ {
+ dp = (u_int32_t *) OS_phystov((void *) (le32_to_cpu(m->data)));
+ if (len >= 0x10)
+ pr_info(" %x[%x]: %08X %08X %08X %08x\n", (u_int32_t) dp, len,
+ *dp, *(dp + 1), *(dp + 2), *(dp + 3));
+ else if (len >= 0x08)
+ pr_info(" %x[%x]: %08X %08X\n", (u_int32_t) dp, len,
+ *dp, *(dp + 1));
+ else
+ pr_info(" %x[%x]: %08X\n", (u_int32_t) dp, len, *dp);
+ }
+ }
#endif
- }
- m = m->snext;
- }
+ }
+ m = m->snext;
+ }
} /* -for- */
pr_info("\n");
if (lockit)
- {
- spin_unlock_irqrestore (&ch->ch_rxlock, flags);
- }
+ spin_unlock_irqrestore(&ch->ch_rxlock, flags);
return 0;
}
#endif
#if 1
STATIC int
-musycc_dump_txbuffer_ring (mch_t * ch, int lockit)
+musycc_dump_txbuffer_ring(mch_t * ch, int lockit)
{
struct mdesc *m;
unsigned long flags = 0;
@@ -155,60 +148,52 @@ musycc_dump_txbuffer_ring (mch_t * ch, int lockit)
int n;
if (lockit)
- {
- spin_lock_irqsave (&ch->ch_txlock, flags);
- }
+ spin_lock_irqsave(&ch->ch_txlock, flags);
if (ch->txd_num == 0)
- {
- pr_info(" ZERO transmit buffers allocated for this channel.");
- } else
- {
- FLUSH_MEM_READ ();
- m = ch->txd_irq_srv;
- for (n = ch->txd_num; n; n--)
- {
- status = le32_to_cpu (m->status);
- {
- pr_info("%c%c %08lx[%2d]: sts %08x (%c%c%c%c:%d.) Data [%08x] Next [%08x]\n",
- (m == ch->txd_usr_add) ? 'F' : ' ',
- (m == ch->txd_irq_srv) ? 'L' : ' ',
- (unsigned long) m, n,
- status,
- m->data ? (status & MUSYCC_TX_OWNED ? 'M' : 'H') : '-',
- status & POLL_DISABLED ? 'P' : '-',
- status & EOBIRQ_ENABLE ? 'b' : '-',
- status & EOMIRQ_ENABLE ? 'm' : '-',
- status & LENGTH_MASK,
- le32_to_cpu (m->data), le32_to_cpu (m->next));
+ pr_info(" ZERO transmit buffers allocated for this channel.");
+ else {
+ FLUSH_MEM_READ();
+ m = ch->txd_irq_srv;
+ for (n = ch->txd_num; n; n--) {
+ status = le32_to_cpu(m->status);
+ {
+ pr_info("%c%c %08lx[%2d]: sts %08x (%c%c%c%c:%d.) Data [%08x] Next [%08x]\n",
+ (m == ch->txd_usr_add) ? 'F' : ' ',
+ (m == ch->txd_irq_srv) ? 'L' : ' ',
+ (unsigned long) m, n,
+ status,
+ m->data ? (status & MUSYCC_TX_OWNED ? 'M' : 'H') : '-',
+ status & POLL_DISABLED ? 'P' : '-',
+ status & EOBIRQ_ENABLE ? 'b' : '-',
+ status & EOMIRQ_ENABLE ? 'm' : '-',
+ status & LENGTH_MASK,
+ le32_to_cpu(m->data), le32_to_cpu(m->next));
#ifdef RLD_DUMP_BUFDATA
- {
- u_int32_t *dp;
- int len = status & LENGTH_MASK;
-
- if (m->data)
- {
- dp = (u_int32_t *) OS_phystov ((void *) (le32_to_cpu (m->data)));
- if (len >= 0x10)
- pr_info(" %x[%x]: %08X %08X %08X %08x\n", (u_int32_t) dp, len,
- *dp, *(dp + 1), *(dp + 2), *(dp + 3));
- else if (len >= 0x08)
- pr_info(" %x[%x]: %08X %08X\n", (u_int32_t) dp, len,
- *dp, *(dp + 1));
- else
- pr_info(" %x[%x]: %08X\n", (u_int32_t) dp, len, *dp);
- }
- }
+ {
+ u_int32_t *dp;
+ int len = status & LENGTH_MASK;
+
+ if (m->data) {
+ dp = (u_int32_t *) OS_phystov((void *) (le32_to_cpu(m->data)));
+ if (len >= 0x10)
+ pr_info(" %x[%x]: %08X %08X %08X %08x\n", (u_int32_t) dp, len,
+ *dp, *(dp + 1), *(dp + 2), *(dp + 3));
+ else if (len >= 0x08)
+ pr_info(" %x[%x]: %08X %08X\n", (u_int32_t) dp, len,
+ *dp, *(dp + 1));
+ else
+ pr_info(" %x[%x]: %08X\n", (u_int32_t) dp, len, *dp);
+ }
+ }
#endif
- }
- m = m->snext;
- }
+ }
+ m = m->snext;
+ }
} /* -for- */
pr_info("\n");
if (lockit)
- {
- spin_unlock_irqrestore (&ch->ch_txlock, flags);
- }
+ spin_unlock_irqrestore(&ch->ch_txlock, flags);
return 0;
}
#endif
@@ -220,58 +205,55 @@ musycc_dump_txbuffer_ring (mch_t * ch, int lockit)
*/
status_t
-musycc_dump_ring (ci_t * ci, unsigned int chan)
+musycc_dump_ring(ci_t * ci, unsigned int chan)
{
mch_t *ch;
if (chan >= MAX_CHANS_USED)
+ return SBE_DRVR_FAIL; /* E2BIG */
{
- return SBE_DRVR_FAIL; /* E2BIG */
- }
- {
- int bh;
-
- bh = atomic_read (&ci->bh_pending);
- pr_info(">> bh_pend %d [%d] ihead %d itail %d [%d] th_cnt %d bh_cnt %d wdcnt %d note %d\n",
- bh, max_bh, ci->iqp_headx, ci->iqp_tailx, max_intcnt,
- ci->intlog.drvr_intr_thcount,
- ci->intlog.drvr_intr_bhcount,
- ci->wdcount, ci->wd_notify);
- max_bh = 0; /* reset counter */
- max_intcnt = 0; /* reset counter */
+ int bh;
+
+ bh = atomic_read(&ci->bh_pending);
+ pr_info(">> bh_pend %d [%d] ihead %d itail %d [%d] th_cnt %d bh_cnt %d wdcnt %d note %d\n",
+ bh, max_bh, ci->iqp_headx, ci->iqp_tailx, max_intcnt,
+ ci->intlog.drvr_intr_thcount,
+ ci->intlog.drvr_intr_bhcount,
+ ci->wdcount, ci->wd_notify);
+ max_bh = 0; /* reset counter */
+ max_intcnt = 0; /* reset counter */
}
- if (!(ch = sd_find_chan (dummy, chan)))
- {
- pr_info(">> musycc_dump_ring: channel %d not up.\n", chan);
- return ENOENT;
+ if (!(ch = sd_find_chan(dummy, chan))) {
+ pr_info(">> musycc_dump_ring: channel %d not up.\n", chan);
+ return ENOENT;
}
pr_info(">> CI %p CHANNEL %3d @ %p: state %x status/p %x/%x\n", ci, chan, ch, ch->state,
- ch->status, ch->p.status);
+ ch->status, ch->p.status);
pr_info("--------------------------------\nTX Buffer Ring - Channel %d, txd_num %d. (bd/ch pend %d %d), TXD required %d, txpkt %lu\n",
- chan, ch->txd_num,
- (u_int32_t) atomic_read (&ci->tx_pending), (u_int32_t) atomic_read (&ch->tx_pending), ch->txd_required, ch->s.tx_packets);
+ chan, ch->txd_num,
+ (u_int32_t) atomic_read(&ci->tx_pending), (u_int32_t) atomic_read(&ch->tx_pending), ch->txd_required, ch->s.tx_packets);
pr_info("++ User 0x%p IRQ_SRV 0x%p USR_ADD 0x%p QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n",
- ch->user, ch->txd_irq_srv, ch->txd_usr_add,
- sd_queue_stopped (ch->user),
- ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode);
- musycc_dump_txbuffer_ring (ch, 1);
+ ch->user, ch->txd_irq_srv, ch->txd_usr_add,
+ sd_queue_stopped(ch->user),
+ ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode);
+ musycc_dump_txbuffer_ring(ch, 1);
pr_info("RX Buffer Ring - Channel %d, rxd_num %d. IRQ_SRV[%d] 0x%p, start_rx %x rxpkt %lu\n",
- chan, ch->rxd_num, ch->rxix_irq_srv,
- &ch->mdr[ch->rxix_irq_srv], ch->ch_start_rx, ch->s.rx_packets);
- musycc_dump_rxbuffer_ring (ch, 1);
+ chan, ch->rxd_num, ch->rxix_irq_srv,
+ &ch->mdr[ch->rxix_irq_srv], ch->ch_start_rx, ch->s.rx_packets);
+ musycc_dump_rxbuffer_ring(ch, 1);
return SBE_DRVR_SUCCESS;
}
status_t
-musycc_dump_rings (ci_t * ci, unsigned int start_chan)
+musycc_dump_rings(ci_t * ci, unsigned int start_chan)
{
unsigned int chan;
for (chan = start_chan; chan < (start_chan + 5); chan++)
- musycc_dump_ring (ci, chan);
+ musycc_dump_ring(ci, chan);
return SBE_DRVR_SUCCESS;
}
@@ -282,7 +264,7 @@ musycc_dump_rings (ci_t * ci, unsigned int start_chan)
*/
void
-musycc_init_mdt (mpi_t * pi)
+musycc_init_mdt(mpi_t * pi)
{
u_int32_t *addr, cfg;
int i;
@@ -299,56 +281,50 @@ musycc_init_mdt (mpi_t * pi)
cfg = CFG_CH_FLAG_7E << IDLE_CODE;
for (i = 0; i < 32; addr++, i++)
- {
- pci_write_32 (addr, cfg);
- }
+ pci_write_32(addr, cfg);
}
/* Set TX thp to the next unprocessed md */
void
-musycc_update_tx_thp (mch_t * ch)
+musycc_update_tx_thp(mch_t * ch)
{
struct mdesc *md;
unsigned long flags;
- spin_lock_irqsave (&ch->ch_txlock, flags);
- while (1)
- {
- md = ch->txd_irq_srv;
- FLUSH_MEM_READ ();
- if (!md->data)
- {
- /* No MDs with buffers to process */
- spin_unlock_irqrestore (&ch->ch_txlock, flags);
- return;
- }
- if ((le32_to_cpu (md->status)) & MUSYCC_TX_OWNED)
- {
- /* this is the MD to restart TX with */
- break;
- }
- /*
- * Otherwise, we have a valid, host-owned message descriptor which
- * has been successfully transmitted and whose buffer can be freed,
- * so... process this MD, it's owned by the host. (This might give
- * as a new, updated txd_irq_srv.)
- */
- musycc_bh_tx_eom (ch->up, ch->gchan);
+ spin_lock_irqsave(&ch->ch_txlock, flags);
+ while (1) {
+ md = ch->txd_irq_srv;
+ FLUSH_MEM_READ();
+ if (!md->data) {
+ /* No MDs with buffers to process */
+ spin_unlock_irqrestore(&ch->ch_txlock, flags);
+ return;
+ }
+ if ((le32_to_cpu(md->status)) & MUSYCC_TX_OWNED) {
+ /* this is the MD to restart TX with */
+ break;
+ }
+ /*
+ * Otherwise, we have a valid, host-owned message descriptor which
+ * has been successfully transmitted and whose buffer can be freed,
+ * so... process this MD, it's owned by the host. (This might give
+ * as a new, updated txd_irq_srv.)
+ */
+ musycc_bh_tx_eom(ch->up, ch->gchan);
}
md = ch->txd_irq_srv;
- ch->up->regram->thp[ch->gchan] = cpu_to_le32 (OS_vtophys (md));
- FLUSH_MEM_WRITE ();
-
- if (ch->tx_full)
- {
- ch->tx_full = 0;
- ch->txd_required = 0;
- sd_enable_xmit (ch->user); /* re-enable to catch flow controlled
- * channel */
+ ch->up->regram->thp[ch->gchan] = cpu_to_le32(OS_vtophys(md));
+ FLUSH_MEM_WRITE();
+
+ if (ch->tx_full) {
+ ch->tx_full = 0;
+ ch->txd_required = 0;
+ sd_enable_xmit(ch->user); /* re-enable to catch flow controlled
+ * channel */
}
- spin_unlock_irqrestore (&ch->ch_txlock, flags);
+ spin_unlock_irqrestore(&ch->ch_txlock, flags);
#ifdef RLD_TRANS_DEBUG
pr_info("++ musycc_update_tx_thp[%d]: setting thp = %p, sts %x\n", ch->channum, md, md->status);
@@ -366,7 +342,7 @@ musycc_update_tx_thp (mch_t * ch)
*/
void
-musycc_wq_chan_restart (void *arg) /* channel private structure */
+musycc_wq_chan_restart(void *arg) /* channel private structure */
{
mch_t *ch;
mpi_t *pi;
@@ -380,7 +356,7 @@ musycc_wq_chan_restart (void *arg) /* channel private structure */
#ifdef RLD_TRANS_DEBUG
pr_info("wq_chan_restart[%d]: start_RT[%d/%d] status %x\n",
- ch->channum, ch->ch_start_rx, ch->ch_start_tx, ch->status);
+ ch->channum, ch->ch_start_rx, ch->ch_start_tx, ch->status);
#endif
@@ -388,80 +364,74 @@ musycc_wq_chan_restart (void *arg) /* channel private structure */
/** check for RX restart request **/
/**********************************/
- if ((ch->ch_start_rx) && (ch->status & RX_ENABLED))
- {
+ if ((ch->ch_start_rx) && (ch->status & RX_ENABLED)) {
- ch->ch_start_rx = 0;
+ ch->ch_start_rx = 0;
#if defined(RLD_TRANS_DEBUG) || defined(RLD_RXACT_DEBUG)
- {
- static int hereb4 = 7;
+ {
+ static int hereb4 = 7;
- if (hereb4) /* RLD DEBUG */
- {
- hereb4--;
+ if (hereb4) { /* RLD DEBUG */
+ hereb4--;
#ifdef RLD_TRANS_DEBUG
- md = &ch->mdr[ch->rxix_irq_srv];
- pr_info("++ musycc_wq_chan_restart[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n",
- ch->channum, ch->rxix_irq_srv, md, le32_to_cpu (md->status),
- ch->s.rx_packets);
+ md = &ch->mdr[ch->rxix_irq_srv];
+ pr_info("++ musycc_wq_chan_restart[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n",
+ ch->channum, ch->rxix_irq_srv, md, le32_to_cpu(md->status),
+ ch->s.rx_packets);
#elif defined(RLD_RXACT_DEBUG)
- md = &ch->mdr[ch->rxix_irq_srv];
- pr_info("++ musycc_wq_chan_restart[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n",
- ch->channum, ch->rxix_irq_srv, md, le32_to_cpu (md->status),
- ch->s.rx_packets);
- musycc_dump_rxbuffer_ring (ch, 1); /* RLD DEBUG */
+ md = &ch->mdr[ch->rxix_irq_srv];
+ pr_info("++ musycc_wq_chan_restart[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n",
+ ch->channum, ch->rxix_irq_srv, md, le32_to_cpu(md->status),
+ ch->s.rx_packets);
+ musycc_dump_rxbuffer_ring(ch, 1); /* RLD DEBUG */
#endif
- }
- }
+ }
+ }
#endif
- musycc_serv_req (pi, SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION | ch->gchan);
+ musycc_serv_req(pi, SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION | ch->gchan);
}
/**********************************/
/** check for TX restart request **/
/**********************************/
- if ((ch->ch_start_tx) && (ch->status & TX_ENABLED))
- {
- /* find next unprocessed message, then set TX thp to it */
- musycc_update_tx_thp (ch);
+ if ((ch->ch_start_tx) && (ch->status & TX_ENABLED)) {
+ /* find next unprocessed message, then set TX thp to it */
+ musycc_update_tx_thp(ch);
#if 0
- spin_lock_irqsave (&ch->ch_txlock, flags);
+ spin_lock_irqsave(&ch->ch_txlock, flags);
#endif
- md = ch->txd_irq_srv;
- if (!md)
- {
+ md = ch->txd_irq_srv;
+ if (!md) {
#ifdef RLD_TRANS_DEBUG
- pr_info("-- musycc_wq_chan_restart[%d]: WARNING, starting NULL md\n", ch->channum);
+ pr_info("-- musycc_wq_chan_restart[%d]: WARNING, starting NULL md\n", ch->channum);
#endif
#if 0
- spin_unlock_irqrestore (&ch->ch_txlock, flags);
+ spin_unlock_irqrestore(&ch->ch_txlock, flags);
#endif
- } else if (md->data && ((le32_to_cpu (md->status)) & MUSYCC_TX_OWNED))
- {
- ch->ch_start_tx = 0;
+ } else if (md->data && ((le32_to_cpu(md->status)) & MUSYCC_TX_OWNED)) {
+ ch->ch_start_tx = 0;
#if 0
- spin_unlock_irqrestore (&ch->ch_txlock, flags); /* allow interrupts for service request */
+ spin_unlock_irqrestore(&ch->ch_txlock, flags); /* allow interrupts for service request */
#endif
#ifdef RLD_TRANS_DEBUG
- pr_info("++ musycc_wq_chan_restart() CHAN TX ACTIVATE: chan %d txd_irq_srv %p = sts %x, txpkt %lu\n",
- ch->channum, ch->txd_irq_srv, ch->txd_irq_srv->status, ch->s.tx_packets);
+ pr_info("++ musycc_wq_chan_restart() CHAN TX ACTIVATE: chan %d txd_irq_srv %p = sts %x, txpkt %lu\n",
+ ch->channum, ch->txd_irq_srv, ch->txd_irq_srv->status, ch->s.tx_packets);
#endif
- musycc_serv_req (pi, SR_CHANNEL_ACTIVATE | SR_TX_DIRECTION | ch->gchan);
- }
+ musycc_serv_req(pi, SR_CHANNEL_ACTIVATE | SR_TX_DIRECTION | ch->gchan);
+ }
#ifdef RLD_RESTART_DEBUG
- else
- {
- /* retain request to start until retried and we have data to xmit */
- pr_info("-- musycc_wq_chan_restart[%d]: DELAYED due to md %p sts %x data %x, start_tx %x\n",
- ch->channum, md,
- le32_to_cpu (md->status),
- le32_to_cpu (md->data), ch->ch_start_tx);
- musycc_dump_txbuffer_ring (ch, 0);
+ else {
+ /* retain request to start until retried and we have data to xmit */
+ pr_info("-- musycc_wq_chan_restart[%d]: DELAYED due to md %p sts %x data %x, start_tx %x\n",
+ ch->channum, md,
+ le32_to_cpu(md->status),
+ le32_to_cpu(md->data), ch->ch_start_tx);
+ musycc_dump_txbuffer_ring(ch, 0);
#if 0
- spin_unlock_irqrestore (&ch->ch_txlock, flags); /* allow interrupts for service request */
+ spin_unlock_irqrestore(&ch->ch_txlock, flags); /* allow interrupts for service request */
#endif
- }
+ }
#endif
}
}
@@ -473,41 +443,41 @@ musycc_wq_chan_restart (void *arg) /* channel private structure */
*/
void
-musycc_chan_restart (mch_t * ch)
+musycc_chan_restart(mch_t * ch)
{
#ifdef RLD_RESTART_DEBUG
pr_info("++ musycc_chan_restart[%d]: txd_irq_srv @ %p = sts %x\n",
- ch->channum, ch->txd_irq_srv, ch->txd_irq_srv->status);
+ ch->channum, ch->txd_irq_srv, ch->txd_irq_srv->status);
#endif
/* 2.6 - find next unprocessed message, then set TX thp to it */
#ifdef RLD_RESTART_DEBUG
pr_info(">> musycc_chan_restart: scheduling Chan %x workQ @ %p\n", ch->channum, &ch->ch_work);
#endif
- c4_wk_chan_restart (ch); /* work queue mechanism fires off: Ref:
- * musycc_wq_chan_restart () */
+ c4_wk_chan_restart(ch); /* work queue mechanism fires off: Ref:
+ * musycc_wq_chan_restart () */
}
void
-rld_put_led (mpi_t * pi, u_int32_t ledval)
+rld_put_led(mpi_t * pi, u_int32_t ledval)
{
static u_int32_t led = 0;
if (ledval == 0)
- led = 0;
+ led = 0;
else
- led |= ledval;
+ led |= ledval;
- pci_write_32 ((u_int32_t *) &pi->up->cpldbase->leds, led); /* RLD DEBUG TRANHANG */
+ pci_write_32((u_int32_t *) &pi->up->cpldbase->leds, led); /* RLD DEBUG TRANHANG */
}
#define MUSYCC_SR_RETRY_CNT 9
void
-musycc_serv_req (mpi_t * pi, u_int32_t req)
+musycc_serv_req(mpi_t * pi, u_int32_t req)
{
volatile u_int32_t r;
int rcnt;
@@ -520,49 +490,46 @@ musycc_serv_req (mpi_t * pi, u_int32_t req)
* acknowledged."
*/
- SD_SEM_TAKE (&pi->sr_sem_busy, "serv"); /* only 1 thru here, per
- * group */
+ SD_SEM_TAKE(&pi->sr_sem_busy, "serv"); /* only 1 thru here, per
+ * group */
- if (pi->sr_last == req)
- {
+ if (pi->sr_last == req) {
#ifdef RLD_TRANS_DEBUG
- pr_info(">> same SR, Port %d Req %x\n", pi->portnum, req);
+ pr_info(">> same SR, Port %d Req %x\n", pi->portnum, req);
#endif
- /*
- * The most likely repeated request is the channel activation command
- * which follows the occurrence of a Transparent mode TX ONR or a
- * BUFF error. If the previous command was a CHANNEL ACTIVATE,
- * precede it with a NOOP command in order maintain coherent control
- * of this current (re)ACTIVATE.
- */
-
- r = (pi->sr_last & ~SR_GCHANNEL_MASK);
- if ((r == (SR_CHANNEL_ACTIVATE | SR_TX_DIRECTION)) ||
- (r == (SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION)))
- {
+ /*
+ * The most likely repeated request is the channel activation command
+ * which follows the occurrence of a Transparent mode TX ONR or a
+ * BUFF error. If the previous command was a CHANNEL ACTIVATE,
+ * precede it with a NOOP command in order maintain coherent control
+ * of this current (re)ACTIVATE.
+ */
+
+ r = (pi->sr_last & ~SR_GCHANNEL_MASK);
+ if ((r == (SR_CHANNEL_ACTIVATE | SR_TX_DIRECTION)) ||
+ (r == (SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION))) {
#ifdef RLD_TRANS_DEBUG
- pr_info(">> same CHAN ACT SR, Port %d Req %x => issue SR_NOOP CMD\n", pi->portnum, req);
+ pr_info(">> same CHAN ACT SR, Port %d Req %x => issue SR_NOOP CMD\n", pi->portnum, req);
#endif
- SD_SEM_GIVE (&pi->sr_sem_busy); /* allow this next request */
- musycc_serv_req (pi, SR_NOOP);
- SD_SEM_TAKE (&pi->sr_sem_busy, "serv"); /* relock & continue w/
- * original req */
- } else if (req == SR_NOOP)
- {
- /* no need to issue back-to-back SR_NOOP commands at this time */
+ SD_SEM_GIVE(&pi->sr_sem_busy); /* allow this next request */
+ musycc_serv_req(pi, SR_NOOP);
+ SD_SEM_TAKE(&pi->sr_sem_busy, "serv"); /* relock & continue w/
+ * original req */
+ } else if (req == SR_NOOP) {
+ /* no need to issue back-to-back SR_NOOP commands at this time */
#ifdef RLD_TRANS_DEBUG
- pr_info(">> same Port SR_NOOP skipped, Port %d\n", pi->portnum);
+ pr_info(">> same Port SR_NOOP skipped, Port %d\n", pi->portnum);
#endif
- SD_SEM_GIVE (&pi->sr_sem_busy); /* allow this next request */
- return;
- }
+ SD_SEM_GIVE(&pi->sr_sem_busy); /* allow this next request */
+ return;
+ }
}
rcnt = 0;
pi->sr_last = req;
rewrite:
- pci_write_32 ((u_int32_t *) &pi->reg->srd, req);
- FLUSH_MEM_WRITE ();
+ pci_write_32((u_int32_t *) &pi->reg->srd, req);
+ FLUSH_MEM_WRITE();
/*
* Per MUSYCC Manual, Section 6.1,2 - "When writing an SCR service
@@ -572,120 +539,108 @@ rewrite:
* the host follow any SCR write with another operation which reads from
* the same address."
*/
- r = pci_read_32 ((u_int32_t *) &pi->reg->srd); /* adhere to write
- * timing imposition */
-
-
- if ((r != req) && (req != SR_CHIP_RESET) && (++rcnt <= MUSYCC_SR_RETRY_CNT))
- {
- if (cxt1e1_log_level >= LOG_MONITOR)
- pr_info("%s: %d - reissue srv req/last %x/%x (hdw reads %x), Chan %d.\n",
- pi->up->devname, rcnt, req, pi->sr_last, r,
- (pi->portnum * MUSYCC_NCHANS) + (req & 0x1f));
- OS_uwait_dummy (); /* this delay helps reduce reissue counts
- * (reason not yet researched) */
- goto rewrite;
+ r = pci_read_32((u_int32_t *) &pi->reg->srd); /* adhere to write
+ * timing imposition */
+
+
+ if ((r != req) && (req != SR_CHIP_RESET) && (++rcnt <= MUSYCC_SR_RETRY_CNT)) {
+ if (cxt1e1_log_level >= LOG_MONITOR)
+ pr_info("%s: %d - reissue srv req/last %x/%x (hdw reads %x), Chan %d.\n",
+ pi->up->devname, rcnt, req, pi->sr_last, r,
+ (pi->portnum * MUSYCC_NCHANS) + (req & 0x1f));
+ OS_uwait_dummy(); /* this delay helps reduce reissue counts
+ * (reason not yet researched) */
+ goto rewrite;
}
- if (rcnt > MUSYCC_SR_RETRY_CNT)
- {
- pr_warning("%s: failed service request (#%d)= %x, group %d.\n",
- pi->up->devname, MUSYCC_SR_RETRY_CNT, req, pi->portnum);
- SD_SEM_GIVE (&pi->sr_sem_busy); /* allow any next request */
- return;
+ if (rcnt > MUSYCC_SR_RETRY_CNT) {
+ pr_warning("%s: failed service request (#%d)= %x, group %d.\n",
+ pi->up->devname, MUSYCC_SR_RETRY_CNT, req, pi->portnum);
+ SD_SEM_GIVE(&pi->sr_sem_busy); /* allow any next request */
+ return;
}
- if (req == SR_CHIP_RESET)
- {
- /*
- * PORT NOTE: the CHIP_RESET command is NOT ack'd by the MUSYCC, thus
- * the upcoming delay is used. Though the MUSYCC documentation
- * suggests a read-after-write would supply the required delay, it's
- * unclear what CPU/BUS clock speeds might have been assumed when
- * suggesting this 'lack of ACK' workaround. Thus the use of uwait.
- */
- OS_uwait (100000, "icard"); /* 100ms */
- } else
- {
- FLUSH_MEM_READ ();
- SD_SEM_TAKE (&pi->sr_sem_wait, "sakack"); /* sleep until SACK
- * interrupt occurs */
+ if (req == SR_CHIP_RESET) {
+ /*
+ * PORT NOTE: the CHIP_RESET command is NOT ack'd by the MUSYCC, thus
+ * the upcoming delay is used. Though the MUSYCC documentation
+ * suggests a read-after-write would supply the required delay, it's
+ * unclear what CPU/BUS clock speeds might have been assumed when
+ * suggesting this 'lack of ACK' workaround. Thus the use of uwait.
+ */
+ OS_uwait(100000, "icard"); /* 100ms */
+ } else {
+ FLUSH_MEM_READ();
+ SD_SEM_TAKE(&pi->sr_sem_wait, "sakack"); /* sleep until SACK
+ * interrupt occurs */
}
- SD_SEM_GIVE (&pi->sr_sem_busy); /* allow any next request */
+ SD_SEM_GIVE(&pi->sr_sem_busy); /* allow any next request */
}
#ifdef SBE_PMCC4_ENABLE
void
-musycc_update_timeslots (mpi_t * pi)
+musycc_update_timeslots(mpi_t * pi)
{
int i, ch;
- char e1mode = IS_FRAME_ANY_E1 (pi->p.port_mode);
-
- for (i = 0; i < 32; i++)
- {
- int usedby = 0, last = 0, ts, j, bits[8];
-
- u_int8_t lastval = 0;
-
- if (((i == 0) && e1mode) || /* disable if E1 mode */
- ((i == 16) && ((pi->p.port_mode == CFG_FRAME_E1CRC_CAS) || (pi->p.port_mode == CFG_FRAME_E1CRC_CAS_AMI)))
- || ((i > 23) && (!e1mode))) /* disable if T1 mode */
- {
- pi->tsm[i] = 0xff; /* make tslot unavailable for this mode */
- } else
- {
- pi->tsm[i] = 0x00; /* make tslot available for assignment */
- }
- for (j = 0; j < 8; j++)
- bits[j] = -1;
- for (ch = 0; ch < MUSYCC_NCHANS; ch++)
- {
- if ((pi->chan[ch]->state == UP) && (pi->chan[ch]->p.bitmask[i]))
- {
- usedby++;
- last = ch;
- lastval = pi->chan[ch]->p.bitmask[i];
- for (j = 0; j < 8; j++)
- if (lastval & (1 << j))
- bits[j] = ch;
- pi->tsm[i] |= lastval;
- }
- }
- if (!usedby)
- ts = 0;
- else if ((usedby == 1) && (lastval == 0xff))
- ts = (4 << 5) | last;
- else if ((usedby == 1) && (lastval == 0x7f))
- ts = (5 << 5) | last;
- else
- {
- int idx;
-
- if (bits[0] < 0)
- ts = (6 << 5) | (idx = last);
- else
- ts = (7 << 5) | (idx = bits[0]);
- for (j = 1; j < 8; j++)
- {
- pi->regram->rscm[idx * 8 + j] = (bits[j] < 0) ? 0 : (0x80 | bits[j]);
- pi->regram->tscm[idx * 8 + j] = (bits[j] < 0) ? 0 : (0x80 | bits[j]);
- }
- }
- pi->regram->rtsm[i] = ts;
- pi->regram->ttsm[i] = ts;
+ char e1mode = IS_FRAME_ANY_E1(pi->p.port_mode);
+
+ for (i = 0; i < 32; i++) {
+ int usedby = 0, last = 0, ts, j, bits[8];
+
+ u_int8_t lastval = 0;
+
+ if (((i == 0) && e1mode) || /* disable if E1 mode */
+ ((i == 16) && ((pi->p.port_mode == CFG_FRAME_E1CRC_CAS) || (pi->p.port_mode == CFG_FRAME_E1CRC_CAS_AMI)))
+ || ((i > 23) && (!e1mode))) /* disable if T1 mode */
+ pi->tsm[i] = 0xff; /* make tslot unavailable for this mode */
+ else
+ pi->tsm[i] = 0x00; /* make tslot available for assignment */
+ for (j = 0; j < 8; j++)
+ bits[j] = -1;
+ for (ch = 0; ch < MUSYCC_NCHANS; ch++) {
+ if ((pi->chan[ch]->state == UP) && (pi->chan[ch]->p.bitmask[i])) {
+ usedby++;
+ last = ch;
+ lastval = pi->chan[ch]->p.bitmask[i];
+ for (j = 0; j < 8; j++)
+ if (lastval & (1 << j))
+ bits[j] = ch;
+ pi->tsm[i] |= lastval;
+ }
+ }
+ if (!usedby)
+ ts = 0;
+ else if ((usedby == 1) && (lastval == 0xff))
+ ts = (4 << 5) | last;
+ else if ((usedby == 1) && (lastval == 0x7f))
+ ts = (5 << 5) | last;
+ else {
+ int idx;
+
+ if (bits[0] < 0)
+ ts = (6 << 5) | (idx = last);
+ else
+ ts = (7 << 5) | (idx = bits[0]);
+ for (j = 1; j < 8; j++) {
+ pi->regram->rscm[idx * 8 + j] = (bits[j] < 0) ? 0 : (0x80 | bits[j]);
+ pi->regram->tscm[idx * 8 + j] = (bits[j] < 0) ? 0 : (0x80 | bits[j]);
+ }
+ }
+ pi->regram->rtsm[i] = ts;
+ pi->regram->ttsm[i] = ts;
}
- FLUSH_MEM_WRITE ();
+ FLUSH_MEM_WRITE();
- musycc_serv_req (pi, SR_TIMESLOT_MAP | SR_RX_DIRECTION);
- musycc_serv_req (pi, SR_TIMESLOT_MAP | SR_TX_DIRECTION);
- musycc_serv_req (pi, SR_SUBCHANNEL_MAP | SR_RX_DIRECTION);
- musycc_serv_req (pi, SR_SUBCHANNEL_MAP | SR_TX_DIRECTION);
+ musycc_serv_req(pi, SR_TIMESLOT_MAP | SR_RX_DIRECTION);
+ musycc_serv_req(pi, SR_TIMESLOT_MAP | SR_TX_DIRECTION);
+ musycc_serv_req(pi, SR_SUBCHANNEL_MAP | SR_RX_DIRECTION);
+ musycc_serv_req(pi, SR_SUBCHANNEL_MAP | SR_TX_DIRECTION);
}
#endif
#ifdef SBE_WAN256T3_ENABLE
void
-musycc_update_timeslots (mpi_t * pi)
+musycc_update_timeslots(mpi_t * pi)
{
mch_t *ch;
@@ -699,21 +654,20 @@ musycc_update_timeslots (mpi_t * pi)
#ifdef SBE_WAN256T3_ENABLE
hmask = (0x1f << hyperdummy) & 0x1f;
#endif
- for (i = 0; i < 128; i++)
- {
- gchan = ((pi->portnum * MUSYCC_NCHANS) + (i & hmask)) % MUSYCC_NCHANS;
- ch = pi->chan[gchan];
- if (ch->p.mode_56k)
- tsen = MODE_56KBPS;
- else
- tsen = MODE_64KBPS; /* also the default */
- ts = ((pi->portnum % 4) == (i / 32)) ? (tsen << 5) | (i & hmask) : 0;
- pi->regram->rtsm[i] = ts;
- pi->regram->ttsm[i] = ts;
+ for (i = 0; i < 128; i++) {
+ gchan = ((pi->portnum * MUSYCC_NCHANS) + (i & hmask)) % MUSYCC_NCHANS;
+ ch = pi->chan[gchan];
+ if (ch->p.mode_56k)
+ tsen = MODE_56KBPS;
+ else
+ tsen = MODE_64KBPS; /* also the default */
+ ts = ((pi->portnum % 4) == (i / 32)) ? (tsen << 5) | (i & hmask) : 0;
+ pi->regram->rtsm[i] = ts;
+ pi->regram->ttsm[i] = ts;
}
- FLUSH_MEM_WRITE ();
- musycc_serv_req (pi, SR_TIMESLOT_MAP | SR_RX_DIRECTION);
- musycc_serv_req (pi, SR_TIMESLOT_MAP | SR_TX_DIRECTION);
+ FLUSH_MEM_WRITE();
+ musycc_serv_req(pi, SR_TIMESLOT_MAP | SR_RX_DIRECTION);
+ musycc_serv_req(pi, SR_TIMESLOT_MAP | SR_TX_DIRECTION);
}
#endif
@@ -723,26 +677,25 @@ musycc_update_timeslots (mpi_t * pi)
* into a hardware specific register value (IE. MUSYCC CCD Register).
*/
u_int32_t
-musycc_chan_proto (int proto)
+musycc_chan_proto(int proto)
{
int reg;
- switch (proto)
- {
+ switch (proto) {
case CFG_CH_PROTO_TRANS: /* 0 */
- reg = MUSYCC_CCD_TRANS;
- break;
+ reg = MUSYCC_CCD_TRANS;
+ break;
case CFG_CH_PROTO_SS7: /* 1 */
- reg = MUSYCC_CCD_SS7;
- break;
+ reg = MUSYCC_CCD_SS7;
+ break;
default:
case CFG_CH_PROTO_ISLP_MODE: /* 4 */
case CFG_CH_PROTO_HDLC_FCS16: /* 2 */
- reg = MUSYCC_CCD_HDLC_FCS16;
- break;
+ reg = MUSYCC_CCD_HDLC_FCS16;
+ break;
case CFG_CH_PROTO_HDLC_FCS32: /* 3 */
- reg = MUSYCC_CCD_HDLC_FCS32;
- break;
+ reg = MUSYCC_CCD_HDLC_FCS32;
+ break;
}
return reg;
@@ -750,46 +703,46 @@ musycc_chan_proto (int proto)
#ifdef SBE_WAN256T3_ENABLE
STATIC void __init
-musycc_init_port (mpi_t * pi)
+musycc_init_port(mpi_t * pi)
{
- pci_write_32 ((u_int32_t *) &pi->reg->gbp, OS_vtophys (pi->regram));
+ pci_write_32((u_int32_t *) &pi->reg->gbp, OS_vtophys(pi->regram));
pi->regram->grcd =
- __constant_cpu_to_le32 (MUSYCC_GRCD_RX_ENABLE |
- MUSYCC_GRCD_TX_ENABLE |
- MUSYCC_GRCD_SF_ALIGN |
- MUSYCC_GRCD_SUBCHAN_DISABLE |
- MUSYCC_GRCD_OOFMP_DISABLE |
- MUSYCC_GRCD_COFAIRQ_DISABLE |
- MUSYCC_GRCD_MC_ENABLE |
- (MUSYCC_GRCD_POLLTH_32 << MUSYCC_GRCD_POLLTH_SHIFT));
+ __constant_cpu_to_le32(MUSYCC_GRCD_RX_ENABLE |
+ MUSYCC_GRCD_TX_ENABLE |
+ MUSYCC_GRCD_SF_ALIGN |
+ MUSYCC_GRCD_SUBCHAN_DISABLE |
+ MUSYCC_GRCD_OOFMP_DISABLE |
+ MUSYCC_GRCD_COFAIRQ_DISABLE |
+ MUSYCC_GRCD_MC_ENABLE |
+ (MUSYCC_GRCD_POLLTH_32 << MUSYCC_GRCD_POLLTH_SHIFT));
pi->regram->pcd =
- __constant_cpu_to_le32 (MUSYCC_PCD_E1X4_MODE |
- MUSYCC_PCD_TXDATA_RISING |
- MUSYCC_PCD_TX_DRIVEN);
+ __constant_cpu_to_le32(MUSYCC_PCD_E1X4_MODE |
+ MUSYCC_PCD_TXDATA_RISING |
+ MUSYCC_PCD_TX_DRIVEN);
/* Message length descriptor */
- pi->regram->mld = __constant_cpu_to_le32 (cxt1e1_max_mru | (cxt1e1_max_mru << 16));
- FLUSH_MEM_WRITE ();
+ pi->regram->mld = __constant_cpu_to_le32(cxt1e1_max_mru | (cxt1e1_max_mru << 16));
+ FLUSH_MEM_WRITE();
- musycc_serv_req (pi, SR_GROUP_INIT | SR_RX_DIRECTION);
- musycc_serv_req (pi, SR_GROUP_INIT | SR_TX_DIRECTION);
+ musycc_serv_req(pi, SR_GROUP_INIT | SR_RX_DIRECTION);
+ musycc_serv_req(pi, SR_GROUP_INIT | SR_TX_DIRECTION);
- musycc_init_mdt (pi);
+ musycc_init_mdt(pi);
- musycc_update_timeslots (pi);
+ musycc_update_timeslots(pi);
}
#endif
status_t __init
-musycc_init (ci_t * ci)
+musycc_init(ci_t * ci)
{
char *regaddr; /* temp for address boundary calculations */
int i, gchan;
- OS_sem_init (&ci->sem_wdbusy, SEM_AVAILABLE); /* watchdog exclusion */
+ OS_sem_init(&ci->sem_wdbusy, SEM_AVAILABLE); /* watchdog exclusion */
/*
* Per MUSYCC manual, Section 6.3.4 - "The host must allocate a dword
@@ -798,87 +751,80 @@ musycc_init (ci_t * ci)
#define INT_QUEUE_BOUNDARY 4
- regaddr = OS_kmalloc ((INT_QUEUE_SIZE + 1) * sizeof (u_int32_t));
+ regaddr = OS_kmalloc((INT_QUEUE_SIZE + 1) * sizeof(u_int32_t));
if (regaddr == 0)
- return ENOMEM;
+ 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
- * closest boundary */
+ (~(INT_QUEUE_BOUNDARY - 1))); /* this calculates
+ * closest boundary */
for (i = 0; i < INT_QUEUE_SIZE; i++)
- {
- ci->iqd_p[i] = __constant_cpu_to_le32 (INT_EMPTY_ENTRY);
- }
+ ci->iqd_p[i] = __constant_cpu_to_le32(INT_EMPTY_ENTRY);
- for (i = 0; i < ci->max_port; i++)
- {
- mpi_t *pi = &ci->port[i];
+ for (i = 0; i < ci->max_port; i++) {
+ mpi_t *pi = &ci->port[i];
- /*
- * Per MUSYCC manual, Section 6.3.2 - "The host must allocate a 2KB
- * bound memory segment for Channel Group 0."
- */
+ /*
+ * Per MUSYCC manual, Section 6.3.2 - "The host must allocate a 2KB
+ * bound memory segment for Channel Group 0."
+ */
#define GROUP_BOUNDARY 0x800
- regaddr = OS_kmalloc (sizeof (struct musycc_groupr) + GROUP_BOUNDARY);
- if (regaddr == 0)
- {
- for (gchan = 0; gchan < i; gchan++)
- {
- pi = &ci->port[gchan];
- OS_kfree (pi->reg);
- pi->reg = 0;
- }
- return ENOMEM;
- }
- pi->regram_saved = regaddr; /* save orig value for free's usage */
- pi->regram = (struct musycc_groupr *) ((unsigned long) (regaddr + GROUP_BOUNDARY - 1) &
- (~(GROUP_BOUNDARY - 1))); /* this calculates
- * closest boundary */
+ regaddr = OS_kmalloc(sizeof(struct musycc_groupr) + GROUP_BOUNDARY);
+ if (regaddr == 0) {
+ for (gchan = 0; gchan < i; gchan++) {
+ pi = &ci->port[gchan];
+ OS_kfree(pi->reg);
+ pi->reg = 0;
+ }
+ return ENOMEM;
+ }
+ pi->regram_saved = regaddr; /* save orig value for free's usage */
+ pi->regram = (struct musycc_groupr *) ((unsigned long) (regaddr + GROUP_BOUNDARY - 1) &
+ (~(GROUP_BOUNDARY - 1))); /* this calculates
+ * closest boundary */
}
/* any board centric MUSYCC commands will use group ZERO as its "home" */
ci->regram = ci->port[0].regram;
- musycc_serv_req (&ci->port[0], SR_CHIP_RESET);
+ musycc_serv_req(&ci->port[0], SR_CHIP_RESET);
- pci_write_32 ((u_int32_t *) &ci->reg->gbp, OS_vtophys (ci->regram));
- pci_flush_write (ci);
+ pci_write_32((u_int32_t *) &ci->reg->gbp, OS_vtophys(ci->regram));
+ pci_flush_write(ci);
#ifdef CONFIG_SBE_PMCC4_NCOMM
- ci->regram->__glcd = __constant_cpu_to_le32 (GCD_MAGIC);
+ ci->regram->__glcd = __constant_cpu_to_le32(GCD_MAGIC);
#else
/* standard driver POLLS for INTB via CPLD register */
- ci->regram->__glcd = __constant_cpu_to_le32 (GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE);
+ ci->regram->__glcd = __constant_cpu_to_le32(GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE);
#endif
- ci->regram->__iqp = cpu_to_le32 (OS_vtophys (&ci->iqd_p[0]));
- ci->regram->__iql = __constant_cpu_to_le32 (INT_QUEUE_SIZE - 1);
- pci_write_32 ((u_int32_t *) &ci->reg->dacbp, 0);
- FLUSH_MEM_WRITE ();
+ ci->regram->__iqp = cpu_to_le32(OS_vtophys(&ci->iqd_p[0]));
+ ci->regram->__iql = __constant_cpu_to_le32(INT_QUEUE_SIZE - 1);
+ pci_write_32((u_int32_t *) &ci->reg->dacbp, 0);
+ FLUSH_MEM_WRITE();
ci->state = C_RUNNING; /* mark as full interrupt processing
- * available */
+ * available */
- musycc_serv_req (&ci->port[0], SR_GLOBAL_INIT); /* FIRST INTERRUPT ! */
+ musycc_serv_req(&ci->port[0], SR_GLOBAL_INIT); /* FIRST INTERRUPT ! */
/* sanity check settable parameters */
- if (cxt1e1_max_mru > 0xffe)
- {
- pr_warning("Maximum allowed MRU exceeded, resetting %d to %d.\n",
- cxt1e1_max_mru, 0xffe);
- cxt1e1_max_mru = 0xffe;
+ if (cxt1e1_max_mru > 0xffe) {
+ pr_warning("Maximum allowed MRU exceeded, resetting %d to %d.\n",
+ cxt1e1_max_mru, 0xffe);
+ cxt1e1_max_mru = 0xffe;
}
- if (cxt1e1_max_mtu > 0xffe)
- {
- pr_warning("Maximum allowed MTU exceeded, resetting %d to %d.\n",
- cxt1e1_max_mtu, 0xffe);
- cxt1e1_max_mtu = 0xffe;
+ if (cxt1e1_max_mtu > 0xffe) {
+ pr_warning("Maximum allowed MTU exceeded, resetting %d to %d.\n",
+ cxt1e1_max_mtu, 0xffe);
+ cxt1e1_max_mtu = 0xffe;
}
#ifdef SBE_WAN256T3_ENABLE
for (i = 0; i < MUSYCC_NPORTS; i++)
- musycc_init_port (&ci->port[i]);
+ musycc_init_port(&ci->port[i]);
#endif
return SBE_DRVR_SUCCESS; /* no error */
@@ -886,7 +832,7 @@ musycc_init (ci_t * ci)
void
-musycc_bh_tx_eom (mpi_t * pi, int gchan)
+musycc_bh_tx_eom(mpi_t * pi, int gchan)
{
mch_t *ch;
struct mdesc *md;
@@ -900,128 +846,117 @@ 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 (cxt1e1_log_level >= LOG_ERROR)
- pr_info("%s: intr: xmit EOM on uninitialized channel %d\n",
- pi->up->devname, gchan);
+ if (ch == 0 || 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)
- return; /* note: mdt==0 implies a malloc()
- * failure w/in chan_up() routine */
+ return; /* note: mdt==0 implies a malloc()
+ * failure w/in chan_up() routine */
#if 0
#ifdef SBE_ISR_INLINE
- spin_lock_irq (&ch->ch_txlock);
+ spin_lock_irq(&ch->ch_txlock);
#else
- spin_lock_irqsave (&ch->ch_txlock, flags);
+ spin_lock_irqsave(&ch->ch_txlock, flags);
#endif
#endif
- do
- {
- FLUSH_MEM_READ ();
- md = ch->txd_irq_srv;
- status = le32_to_cpu (md->status);
-
- /*
- * Note: Per MUSYCC Ref 6.4.9, the host does not poll a host-owned
- * Transmit Buffer Descriptor during Transparent Mode.
- */
- if (status & MUSYCC_TX_OWNED)
- {
- int readCount, loopCount;
-
- /***********************************************************/
- /* HW Bug Fix */
- /* ---------- */
- /* Under certain PCI Bus loading conditions, the data */
- /* associated with an update of Shared Memory is delayed */
- /* relative to its PCI Interrupt. This is caught when */
- /* the host determines it does not yet OWN the descriptor. */
- /***********************************************************/
-
- readCount = 0;
- while (status & MUSYCC_TX_OWNED)
- {
- for (loopCount = 0; loopCount < 0x30; loopCount++)
- OS_uwait_dummy (); /* use call to avoid optimization
- * removal of dummy delay */
- FLUSH_MEM_READ ();
- status = le32_to_cpu (md->status);
- if (readCount++ > 40)
- break; /* don't wait any longer */
- }
- if (status & MUSYCC_TX_OWNED)
- {
- if (cxt1e1_log_level >= LOG_MONITOR)
- {
- pr_info("%s: Port %d Chan %2d - unexpected TX msg ownership intr (md %p sts %x)\n",
- pi->up->devname, pi->portnum, ch->channum,
- md, status);
- pr_info("++ User 0x%p IRQ_SRV 0x%p USR_ADD 0x%p QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n",
- ch->user, ch->txd_irq_srv, ch->txd_usr_add,
- sd_queue_stopped (ch->user),
- ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode);
- musycc_dump_txbuffer_ring (ch, 0);
- }
- break; /* Not our mdesc, done */
- } else
- {
- if (cxt1e1_log_level >= LOG_MONITOR)
- pr_info("%s: Port %d Chan %2d - recovered TX msg ownership [%d] (md %p sts %x)\n",
- pi->up->devname, pi->portnum, ch->channum, readCount, md, status);
- }
- }
- ch->txd_irq_srv = md->snext;
-
- md->data = 0;
- if (md->mem_token != 0)
- {
- /* upcount channel */
- atomic_sub (OS_mem_token_tlen (md->mem_token), &ch->tx_pending);
- /* upcount card */
- atomic_sub (OS_mem_token_tlen (md->mem_token), &pi->up->tx_pending);
+ do {
+ FLUSH_MEM_READ();
+ md = ch->txd_irq_srv;
+ status = le32_to_cpu(md->status);
+
+ /*
+ * Note: Per MUSYCC Ref 6.4.9, the host does not poll a host-owned
+ * Transmit Buffer Descriptor during Transparent Mode.
+ */
+ if (status & MUSYCC_TX_OWNED) {
+ int readCount, loopCount;
+
+ /***********************************************************/
+ /* HW Bug Fix */
+ /* ---------- */
+ /* Under certain PCI Bus loading conditions, the data */
+ /* associated with an update of Shared Memory is delayed */
+ /* relative to its PCI Interrupt. This is caught when */
+ /* the host determines it does not yet OWN the descriptor. */
+ /***********************************************************/
+
+ readCount = 0;
+ while (status & MUSYCC_TX_OWNED) {
+ for (loopCount = 0; loopCount < 0x30; loopCount++)
+ OS_uwait_dummy(); /* use call to avoid optimization
+ * removal of dummy delay */
+ FLUSH_MEM_READ();
+ status = le32_to_cpu(md->status);
+ if (readCount++ > 40)
+ break; /* don't wait any longer */
+ }
+ if (status & MUSYCC_TX_OWNED) {
+ if (cxt1e1_log_level >= LOG_MONITOR) {
+ pr_info("%s: Port %d Chan %2d - unexpected TX msg ownership intr (md %p sts %x)\n",
+ pi->up->devname, pi->portnum, ch->channum,
+ md, status);
+ pr_info("++ User 0x%p IRQ_SRV 0x%p USR_ADD 0x%p QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n",
+ ch->user, ch->txd_irq_srv, ch->txd_usr_add,
+ sd_queue_stopped(ch->user),
+ ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode);
+ musycc_dump_txbuffer_ring(ch, 0);
+ }
+ break; /* Not our mdesc, done */
+ } else {
+ if (cxt1e1_log_level >= LOG_MONITOR)
+ pr_info("%s: Port %d Chan %2d - recovered TX msg ownership [%d] (md %p sts %x)\n",
+ pi->up->devname, pi->portnum, ch->channum, readCount, md, status);
+ }
+ }
+ ch->txd_irq_srv = md->snext;
+
+ md->data = 0;
+ if (md->mem_token != 0) {
+ /* upcount channel */
+ atomic_sub(OS_mem_token_tlen(md->mem_token), &ch->tx_pending);
+ /* upcount card */
+ atomic_sub(OS_mem_token_tlen(md->mem_token), &pi->up->tx_pending);
#ifdef SBE_WAN256T3_ENABLE
- if (!atomic_read (&pi->up->tx_pending))
- wan256t3_led (pi->up, LED_TX, 0);
+ if (!atomic_read(&pi->up->tx_pending))
+ wan256t3_led(pi->up, LED_TX, 0);
#endif
#ifdef CONFIG_SBE_WAN256T3_NCOMM
- /* callback that our packet was sent */
- {
- int hdlcnum = (pi->portnum * 32 + gchan);
-
- if (hdlcnum >= 228)
- {
- if (nciProcess_TX_complete)
- (*nciProcess_TX_complete) (hdlcnum,
- getuserbychan (gchan));
- }
- }
+ /* callback that our packet was sent */
+ {
+ int hdlcnum = (pi->portnum * 32 + gchan);
+
+ if (hdlcnum >= 228) {
+ if (nciProcess_TX_complete)
+ (*nciProcess_TX_complete) (hdlcnum,
+ getuserbychan(gchan));
+ }
+ }
#endif /*** CONFIG_SBE_WAN256T3_NCOMM ***/
- OS_mem_token_free_irq (md->mem_token);
- md->mem_token = 0;
- }
- md->status = 0;
+ OS_mem_token_free_irq(md->mem_token);
+ md->mem_token = 0;
+ }
+ md->status = 0;
#ifdef RLD_TXFULL_DEBUG
- if (cxt1e1_log_level >= LOG_MONITOR2)
- pr_info("~~ tx_eom: tx_full %x txd_free %d -> %d\n",
- ch->tx_full, ch->txd_free, ch->txd_free + 1);
+ if (cxt1e1_log_level >= LOG_MONITOR2)
+ pr_info("~~ tx_eom: tx_full %x txd_free %d -> %d\n",
+ ch->tx_full, ch->txd_free, ch->txd_free + 1);
#endif
- ++ch->txd_free;
- FLUSH_MEM_WRITE ();
-
- if ((ch->p.chan_mode != CFG_CH_PROTO_TRANS) && (status & EOBIRQ_ENABLE))
- {
- if (cxt1e1_log_level >= LOG_MONITOR)
- pr_info("%s: Mode (%x) incorrect EOB status (%x)\n",
- pi->up->devname, ch->p.chan_mode, status);
- if ((status & EOMIRQ_ENABLE) == 0)
- break;
- }
- }
- while ((ch->p.chan_mode != CFG_CH_PROTO_TRANS) && ((status & EOMIRQ_ENABLE) == 0));
+ ++ch->txd_free;
+ FLUSH_MEM_WRITE();
+
+ if ((ch->p.chan_mode != CFG_CH_PROTO_TRANS) && (status & EOBIRQ_ENABLE)) {
+ if (cxt1e1_log_level >= LOG_MONITOR)
+ pr_info("%s: Mode (%x) incorrect EOB status (%x)\n",
+ pi->up->devname, ch->p.chan_mode, status);
+ if ((status & EOMIRQ_ENABLE) == 0)
+ break;
+ }
+ } while ((ch->p.chan_mode != CFG_CH_PROTO_TRANS) && ((status & EOMIRQ_ENABLE) == 0));
/*
* NOTE: (The above 'while' is coupled w/ previous 'do', way above.) Each
* Transparent data buffer has the EOB bit, and NOT the EOM bit, set and
@@ -1029,56 +964,53 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan)
* buffer.
*/
- FLUSH_MEM_READ ();
+ FLUSH_MEM_READ();
/*
* Smooth flow control hysterisis by maintaining task stoppage until half
* the available write buffers are available.
*/
- if (ch->tx_full && (ch->txd_free >= (ch->txd_num / 2)))
- {
- /*
- * Then, only releave task stoppage if we actually have enough
- * buffers to service the last requested packet. It may require MORE
- * than half the available!
- */
- if (ch->txd_free >= ch->txd_required)
- {
+ if (ch->tx_full && (ch->txd_free >= (ch->txd_num / 2))) {
+ /*
+ * Then, only releave task stoppage if we actually have enough
+ * buffers to service the last requested packet. It may require MORE
+ * than half the available!
+ */
+ if (ch->txd_free >= ch->txd_required) {
#ifdef RLD_TXFULL_DEBUG
- if (cxt1e1_log_level >= LOG_MONITOR2)
- pr_info("tx_eom[%d]: enable xmit tx_full no more, txd_free %d txd_num/2 %d\n",
- ch->channum,
- ch->txd_free, ch->txd_num / 2);
+ if (cxt1e1_log_level >= LOG_MONITOR2)
+ pr_info("tx_eom[%d]: enable xmit tx_full no more, txd_free %d txd_num/2 %d\n",
+ ch->channum,
+ ch->txd_free, ch->txd_num / 2);
#endif
- ch->tx_full = 0;
- ch->txd_required = 0;
- sd_enable_xmit (ch->user); /* re-enable to catch flow controlled
- * channel */
- }
+ ch->tx_full = 0;
+ ch->txd_required = 0;
+ sd_enable_xmit(ch->user); /* re-enable to catch flow controlled
+ * channel */
+ }
}
#ifdef RLD_TXFULL_DEBUG
- else if (ch->tx_full)
- {
- if (cxt1e1_log_level >= LOG_MONITOR2)
- pr_info("tx_eom[%d]: bypass TX enable though room available? (txd_free %d txd_num/2 %d)\n",
- ch->channum,
- ch->txd_free, ch->txd_num / 2);
+ else if (ch->tx_full) {
+ if (cxt1e1_log_level >= LOG_MONITOR2)
+ pr_info("tx_eom[%d]: bypass TX enable though room available? (txd_free %d txd_num/2 %d)\n",
+ ch->channum,
+ ch->txd_free, ch->txd_num / 2);
}
#endif
- FLUSH_MEM_WRITE ();
+ FLUSH_MEM_WRITE();
#if 0
#ifdef SBE_ISR_INLINE
- spin_unlock_irq (&ch->ch_txlock);
+ spin_unlock_irq(&ch->ch_txlock);
#else
- spin_unlock_irqrestore (&ch->ch_txlock, flags);
+ spin_unlock_irqrestore(&ch->ch_txlock, flags);
#endif
#endif
}
STATIC void
-musycc_bh_rx_eom (mpi_t * pi, int gchan)
+musycc_bh_rx_eom(mpi_t * pi, int gchan)
{
mch_t *ch;
void *m, *m2;
@@ -1087,89 +1019,76 @@ musycc_bh_rx_eom (mpi_t * pi, int gchan)
u_int32_t error;
ch = pi->chan[gchan];
- if (ch == 0 || 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 == 0 || 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)
- return; /* can this happen ? */
-
- for (;;)
- {
- FLUSH_MEM_READ ();
- md = &ch->mdr[ch->rxix_irq_srv];
- status = le32_to_cpu (md->status);
- if (!(status & HOST_RX_OWNED))
- break; /* Not our mdesc, done */
- m = md->mem_token;
- error = (status >> 16) & 0xf;
- if (error == 0)
- {
+ return; /* can this happen ? */
+
+ for (;;) {
+ FLUSH_MEM_READ();
+ md = &ch->mdr[ch->rxix_irq_srv];
+ status = le32_to_cpu(md->status);
+ if (!(status & HOST_RX_OWNED))
+ break; /* Not our mdesc, done */
+ m = md->mem_token;
+ error = (status >> 16) & 0xf;
+ if (error == 0) {
#ifdef CONFIG_SBE_WAN256T3_NCOMM
- int hdlcnum = (pi->portnum * 32 + gchan);
-
- /*
- * if the packet number belongs to NCOMM, then send it to the TMS
- * driver
- */
- if (hdlcnum >= 228)
- {
- if (nciProcess_RX_packet)
- (*nciProcess_RX_packet) (hdlcnum, status & 0x3fff, m, ch->user);
- } else
+ int hdlcnum = (pi->portnum * 32 + gchan);
+
+ /*
+ * if the packet number belongs to NCOMM, then send it to the TMS
+ * driver
+ */
+ if (hdlcnum >= 228) {
+ if (nciProcess_RX_packet)
+ (*nciProcess_RX_packet) (hdlcnum, status & 0x3fff, m, ch->user);
+ } else
#endif /*** CONFIG_SBE_WAN256T3_NCOMM ***/
- {
- if ((m2 = OS_mem_token_alloc (cxt1e1_max_mru)))
- {
- /* substitute the mbuf+cluster */
- md->mem_token = m2;
- md->data = cpu_to_le32 (OS_vtophys (OS_mem_token_data (m2)));
-
- /* pass the received mbuf upward */
- sd_recv_consume (m, status & LENGTH_MASK, ch->user);
- ch->s.rx_packets++;
- ch->s.rx_bytes += status & LENGTH_MASK;
- } else
- {
- ch->s.rx_dropped++;
- }
- }
- } else if (error == ERR_FCS)
- {
- ch->s.rx_crc_errors++;
- } else if (error == ERR_ALIGN)
- {
- ch->s.rx_missed_errors++;
- } else if (error == ERR_ABT)
- {
- ch->s.rx_missed_errors++;
- } else if (error == ERR_LNG)
- {
- ch->s.rx_length_errors++;
- } else if (error == ERR_SHT)
- {
- ch->s.rx_length_errors++;
- }
- FLUSH_MEM_WRITE ();
- status = cxt1e1_max_mru;
- if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
- status |= EOBIRQ_ENABLE;
- md->status = cpu_to_le32 (status);
-
- /* Check next mdesc in the ring */
- if (++ch->rxix_irq_srv >= ch->rxd_num)
- ch->rxix_irq_srv = 0;
- FLUSH_MEM_WRITE ();
+ {
+ if ((m2 = OS_mem_token_alloc(cxt1e1_max_mru))) {
+ /* substitute the mbuf+cluster */
+ md->mem_token = m2;
+ md->data = cpu_to_le32(OS_vtophys(OS_mem_token_data(m2)));
+
+ /* pass the received mbuf upward */
+ sd_recv_consume(m, status & LENGTH_MASK, ch->user);
+ ch->s.rx_packets++;
+ ch->s.rx_bytes += status & LENGTH_MASK;
+ } else
+ ch->s.rx_dropped++;
+ }
+ } else if (error == ERR_FCS)
+ ch->s.rx_crc_errors++;
+ else if (error == ERR_ALIGN)
+ ch->s.rx_missed_errors++;
+ else if (error == ERR_ABT)
+ ch->s.rx_missed_errors++;
+ else if (error == ERR_LNG)
+ ch->s.rx_length_errors++;
+ else if (error == ERR_SHT)
+ ch->s.rx_length_errors++;
+ FLUSH_MEM_WRITE();
+ status = cxt1e1_max_mru;
+ if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
+ status |= EOBIRQ_ENABLE;
+ md->status = cpu_to_le32(status);
+
+ /* Check next mdesc in the ring */
+ if (++ch->rxix_irq_srv >= ch->rxd_num)
+ ch->rxix_irq_srv = 0;
+ FLUSH_MEM_WRITE();
}
}
irqreturn_t
-musycc_intr_th_handler (void *devp)
+musycc_intr_th_handler(void *devp)
{
ci_t *ci = (ci_t *) devp;
volatile u_int32_t status, currInt = 0;
@@ -1180,28 +1099,25 @@ musycc_intr_th_handler (void *devp)
* might be shared, just return.
*/
if (ci->state == C_INIT)
- {
- return IRQ_NONE;
- }
+ return IRQ_NONE;
/*
* Marked as hardware available. Don't service interrupts, just clear the
* event.
*/
- if (ci->state == C_IDLE)
- {
- status = pci_read_32 ((u_int32_t *) &ci->reg->isd);
+ if (ci->state == C_IDLE) {
+ status = pci_read_32((u_int32_t *) &ci->reg->isd);
- /* clear the interrupt but process nothing else */
- pci_write_32 ((u_int32_t *) &ci->reg->isd, status);
- return IRQ_HANDLED;
+ /* clear the interrupt but process nothing else */
+ pci_write_32((u_int32_t *) &ci->reg->isd, status);
+ return IRQ_HANDLED;
}
- FLUSH_PCI_READ ();
- FLUSH_MEM_READ ();
+ FLUSH_PCI_READ();
+ FLUSH_MEM_READ();
- status = pci_read_32 ((u_int32_t *) &ci->reg->isd);
- nextInt = INTRPTS_NEXTINT (status);
- intCnt = INTRPTS_INTCNT (status);
+ status = pci_read_32((u_int32_t *) &ci->reg->isd);
+ nextInt = INTRPTS_NEXTINT(status);
+ intCnt = INTRPTS_INTCNT(status);
ci->intlog.drvr_intr_thcount++;
/*********************************************************/
@@ -1218,22 +1134,20 @@ musycc_intr_th_handler (void *devp)
/* incorrect ISD's are encountered. */
/*********************************************************/
- if (nextInt != INTRPTS_NEXTINT (ci->intlog.this_status_new))
- {
- if (cxt1e1_log_level >= LOG_MONITOR)
- {
- pr_info("%s: note - updated ISD from %08x to %08x\n",
- ci->devname, status,
- (status & (~INTRPTS_NEXTINT_M)) | ci->intlog.this_status_new);
- }
- /*
- * Replace bogus status with software corrected value.
- *
- * It's not known whether, during this problem occurrence, if the
- * INTFULL bit is correctly reported or not.
- */
- status = (status & (~INTRPTS_NEXTINT_M)) | (ci->intlog.this_status_new);
- nextInt = INTRPTS_NEXTINT (status);
+ if (nextInt != INTRPTS_NEXTINT(ci->intlog.this_status_new)) {
+ if (cxt1e1_log_level >= LOG_MONITOR) {
+ pr_info("%s: note - updated ISD from %08x to %08x\n",
+ ci->devname, status,
+ (status & (~INTRPTS_NEXTINT_M)) | ci->intlog.this_status_new);
+ }
+ /*
+ * Replace bogus status with software corrected value.
+ *
+ * It's not known whether, during this problem occurrence, if the
+ * INTFULL bit is correctly reported or not.
+ */
+ status = (status & (~INTRPTS_NEXTINT_M)) | (ci->intlog.this_status_new);
+ nextInt = INTRPTS_NEXTINT(status);
}
/**********************************************/
/* Cn847x Bug Fix */
@@ -1243,43 +1157,40 @@ musycc_intr_th_handler (void *devp)
/**********************************************/
if (intCnt == INT_QUEUE_SIZE)
- {
- currInt = ((intCnt - 1) + nextInt) & (INT_QUEUE_SIZE - 1);
- } else
- /************************************************/
- /* Interrupt Write Location Issues */
- /* ------------------------------- */
- /* When the interrupt status descriptor is */
- /* written, the interrupt line is de-asserted */
- /* by the Cn847x. In the case of MIPS */
- /* microprocessors, this must occur at the */
- /* beginning of the interrupt handler so that */
- /* the interrupt handle is not re-entered due */
- /* to interrupt dis-assertion latency. */
- /* In the case of all other processors, this */
- /* action should occur at the end of the */
- /* interrupt handler to avoid overwriting the */
- /* interrupt queue. */
- /************************************************/
+ currInt = ((intCnt - 1) + nextInt) & (INT_QUEUE_SIZE - 1);
+ else
+ /************************************************/
+ /* Interrupt Write Location Issues */
+ /* ------------------------------- */
+ /* When the interrupt status descriptor is */
+ /* written, the interrupt line is de-asserted */
+ /* by the Cn847x. In the case of MIPS */
+ /* microprocessors, this must occur at the */
+ /* beginning of the interrupt handler so that */
+ /* the interrupt handle is not re-entered due */
+ /* to interrupt dis-assertion latency. */
+ /* In the case of all other processors, this */
+ /* action should occur at the end of the */
+ /* interrupt handler to avoid overwriting the */
+ /* interrupt queue. */
+ /************************************************/
if (intCnt)
- {
- currInt = (intCnt + nextInt) & (INT_QUEUE_SIZE - 1);
- } else
- {
- /*
- * NOTE: Servicing an interrupt whose ISD contains a count of ZERO
- * can be indicative of a Shared Interrupt chain. Our driver can be
- * called from the system's interrupt handler as a matter of the OS
- * walking the chain. As the chain is walked, the interrupt will
- * eventually be serviced by the correct driver/handler.
- */
+ currInt = (intCnt + nextInt) & (INT_QUEUE_SIZE - 1);
+ else {
+ /*
+ * NOTE: Servicing an interrupt whose ISD contains a count of ZERO
+ * can be indicative of a Shared Interrupt chain. Our driver can be
+ * called from the system's interrupt handler as a matter of the OS
+ * walking the chain. As the chain is walked, the interrupt will
+ * eventually be serviced by the correct driver/handler.
+ */
#if 0
- /* chained interrupt = not ours */
- pr_info(">> %s: intCnt NULL, sts %x, possibly a chained interrupt!\n",
- ci->devname, status);
+ /* chained interrupt = not ours */
+ pr_info(">> %s: intCnt NULL, sts %x, possibly a chained interrupt!\n",
+ ci->devname, status);
#endif
- return IRQ_NONE;
+ return IRQ_NONE;
}
ci->iqp_tailx = currInt;
@@ -1289,27 +1200,25 @@ musycc_intr_th_handler (void *devp)
ci->intlog.this_status_new = currInt;
if ((cxt1e1_log_level >= LOG_WARN) && (status & INTRPTS_INTFULL_M))
- {
- pr_info("%s: Interrupt queue full condition occurred\n", ci->devname);
- }
+ pr_info("%s: Interrupt queue full condition occurred\n", ci->devname);
if (cxt1e1_log_level >= LOG_DEBUG)
- pr_info("%s: interrupts pending, isd @ 0x%p: %x curr %d cnt %d NEXT %d\n",
- ci->devname, &ci->reg->isd,
- status, nextInt, intCnt, (intCnt + nextInt) & (INT_QUEUE_SIZE - 1));
+ pr_info("%s: interrupts pending, isd @ 0x%p: %x curr %d cnt %d NEXT %d\n",
+ ci->devname, &ci->reg->isd,
+ status, nextInt, intCnt, (intCnt + nextInt) & (INT_QUEUE_SIZE - 1));
- FLUSH_MEM_WRITE ();
+ FLUSH_MEM_WRITE();
#if defined(SBE_ISR_TASKLET)
- pci_write_32 ((u_int32_t *) &ci->reg->isd, currInt);
- atomic_inc (&ci->bh_pending);
- tasklet_schedule (&ci->ci_musycc_isr_tasklet);
+ pci_write_32((u_int32_t *) &ci->reg->isd, currInt);
+ atomic_inc(&ci->bh_pending);
+ tasklet_schedule(&ci->ci_musycc_isr_tasklet);
#elif defined(SBE_ISR_IMMEDIATE)
- pci_write_32 ((u_int32_t *) &ci->reg->isd, currInt);
- atomic_inc (&ci->bh_pending);
- queue_task (&ci->ci_musycc_isr_tq, &tq_immediate);
- mark_bh (IMMEDIATE_BH);
+ pci_write_32((u_int32_t *) &ci->reg->isd, currInt);
+ atomic_inc(&ci->bh_pending);
+ queue_task(&ci->ci_musycc_isr_tq, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
#elif defined(SBE_ISR_INLINE)
- (void) musycc_intr_bh_tasklet (ci);
- pci_write_32 ((u_int32_t *) &ci->reg->isd, currInt);
+ (void) musycc_intr_bh_tasklet(ci);
+ pci_write_32((u_int32_t *) &ci->reg->isd, currInt);
#endif
return IRQ_HANDLED;
}
@@ -1320,7 +1229,7 @@ unsigned long
#else
void
#endif
-musycc_intr_bh_tasklet (ci_t * ci)
+musycc_intr_bh_tasklet(ci_t * ci)
{
mpi_t *pi;
mch_t *ch;
@@ -1336,21 +1245,19 @@ musycc_intr_bh_tasklet (ci_t * ci)
* Hardware not available, potential interrupt hang. But since interrupt
* might be shared, just return.
*/
- if ((drvr_state != SBE_DRVR_AVAILABLE) || (ci->state == C_INIT))
- {
+ if ((drvr_state != SBE_DRVR_AVAILABLE) || (ci->state == C_INIT)) {
#if defined(SBE_ISR_IMMEDIATE)
- return 0L;
+ return 0L;
#else
- return;
+ return;
#endif
}
#if defined(SBE_ISR_TASKLET) || defined(SBE_ISR_IMMEDIATE)
- if (drvr_state != SBE_DRVR_AVAILABLE)
- {
+ if (drvr_state != SBE_DRVR_AVAILABLE) {
#if defined(SBE_ISR_TASKLET)
- return;
+ return;
#elif defined(SBE_ISR_IMMEDIATE)
- return 0L;
+ return 0L;
#endif
}
#elif defined(SBE_ISR_INLINE)
@@ -1358,273 +1265,249 @@ musycc_intr_bh_tasklet (ci_t * ci)
#endif
ci->intlog.drvr_intr_bhcount++;
- FLUSH_MEM_READ ();
+ FLUSH_MEM_READ();
{
- unsigned int bh = atomic_read (&ci->bh_pending);
+ unsigned int bh = atomic_read(&ci->bh_pending);
- max_bh = max (bh, max_bh);
+ max_bh = max(bh, max_bh);
}
- atomic_set (&ci->bh_pending, 0);/* if here, no longer pending */
- while ((headx = ci->iqp_headx) != (tailx = ci->iqp_tailx))
- {
- intCnt = (tailx >= headx) ? (tailx - headx) : (tailx - headx + INT_QUEUE_SIZE);
- currInt = le32_to_cpu (ci->iqd_p[headx]);
-
- max_intcnt = max (intCnt, max_intcnt); /* RLD DEBUG */
-
- /**************************************************/
- /* HW Bug Fix */
- /* ---------- */
- /* The following code checks for the condition */
- /* of interrupt assertion before interrupt */
- /* queue update. This is a problem on several */
- /* PCI-Local bridge chips found on some products. */
- /**************************************************/
-
- readCount = 0;
- if ((currInt == badInt) || (currInt == badInt2))
- ci->intlog.drvr_int_failure++;
-
- while ((currInt == badInt) || (currInt == badInt2))
- {
- for (loopCount = 0; loopCount < 0x30; loopCount++)
- OS_uwait_dummy (); /* use call to avoid optimization removal
- * of dummy delay */
- FLUSH_MEM_READ ();
- currInt = le32_to_cpu (ci->iqd_p[headx]);
- if (readCount++ > 20)
- break;
- }
-
- if ((currInt == badInt) || (currInt == badInt2)) /* catch failure of Bug
- * Fix checking */
- {
- if (cxt1e1_log_level >= LOG_WARN)
- pr_info("%s: Illegal Interrupt Detected @ 0x%p, mod %d.)\n",
- ci->devname, &ci->iqd_p[headx], headx);
-
- /*
- * If the descriptor has not recovered, then leaving the EMPTY
- * entry set will not signal to the MUSYCC that this descriptor
- * has been serviced. The Interrupt Queue can then start losing
- * available descriptors and MUSYCC eventually encounters and
- * reports the INTFULL condition. Per manual, changing any bit
- * marks descriptor as available, thus the use of different
- * EMPTY_ENTRY values.
- */
-
- if (currInt == badInt)
- {
- ci->iqd_p[headx] = __constant_cpu_to_le32 (INT_EMPTY_ENTRY2);
- } else
- {
- ci->iqd_p[headx] = __constant_cpu_to_le32 (INT_EMPTY_ENTRY);
- }
- ci->iqp_headx = (headx + 1) & (INT_QUEUE_SIZE - 1); /* insure wrapness */
- FLUSH_MEM_WRITE ();
- FLUSH_MEM_READ ();
- continue;
- }
- group = INTRPT_GRP (currInt);
- gchan = INTRPT_CH (currInt);
- event = INTRPT_EVENT (currInt);
- err = INTRPT_ERROR (currInt);
- tx = currInt & INTRPT_DIR_M;
-
- ci->iqd_p[headx] = __constant_cpu_to_le32 (INT_EMPTY_ENTRY);
- FLUSH_MEM_WRITE ();
-
- if (cxt1e1_log_level >= LOG_DEBUG)
- {
- if (err != 0)
- pr_info(" %08x -> err: %2d,", currInt, err);
-
- pr_info("+ interrupt event: %d, grp: %d, chan: %2d, side: %cX\n",
- event, group, gchan, tx ? 'T' : 'R');
- }
- pi = &ci->port[group]; /* notice that here we assume 1-1 group -
- * port mapping */
- ch = pi->chan[gchan];
- switch (event)
- {
- case EVE_SACK: /* Service Request Acknowledge */
- if (cxt1e1_log_level >= LOG_DEBUG)
- {
- volatile u_int32_t r;
-
- r = pci_read_32 ((u_int32_t *) &pi->reg->srd);
- pr_info("- SACK cmd: %08x (hdw= %08x)\n", pi->sr_last, r);
- }
- SD_SEM_GIVE (&pi->sr_sem_wait); /* wake up waiting process */
- break;
- case EVE_CHABT: /* Change To Abort Code (0x7e -> 0xff) */
- case EVE_CHIC: /* Change To Idle Code (0xff -> 0x7e) */
- break;
- case EVE_EOM: /* End Of Message */
- case EVE_EOB: /* End Of Buffer (Transparent mode) */
- if (tx)
- {
- musycc_bh_tx_eom (pi, gchan);
- } else
- {
- musycc_bh_rx_eom (pi, gchan);
- }
+ atomic_set(&ci->bh_pending, 0);/* if here, no longer pending */
+ while ((headx = ci->iqp_headx) != (tailx = ci->iqp_tailx)) {
+ intCnt = (tailx >= headx) ? (tailx - headx) : (tailx - headx + INT_QUEUE_SIZE);
+ currInt = le32_to_cpu(ci->iqd_p[headx]);
+
+ max_intcnt = max(intCnt, max_intcnt); /* RLD DEBUG */
+
+ /**************************************************/
+ /* HW Bug Fix */
+ /* ---------- */
+ /* The following code checks for the condition */
+ /* of interrupt assertion before interrupt */
+ /* queue update. This is a problem on several */
+ /* PCI-Local bridge chips found on some products. */
+ /**************************************************/
+
+ readCount = 0;
+ if ((currInt == badInt) || (currInt == badInt2))
+ ci->intlog.drvr_int_failure++;
+
+ while ((currInt == badInt) || (currInt == badInt2)) {
+ for (loopCount = 0; loopCount < 0x30; loopCount++)
+ OS_uwait_dummy(); /* use call to avoid optimization removal
+ * of dummy delay */
+ FLUSH_MEM_READ();
+ currInt = le32_to_cpu(ci->iqd_p[headx]);
+ if (readCount++ > 20)
+ break;
+ }
+
+ if ((currInt == badInt) || (currInt == badInt2)) { /* catch failure of Bug
+ * Fix checking */
+ if (cxt1e1_log_level >= LOG_WARN)
+ pr_info("%s: Illegal Interrupt Detected @ 0x%p, mod %d.)\n",
+ ci->devname, &ci->iqd_p[headx], headx);
+
+ /*
+ * If the descriptor has not recovered, then leaving the EMPTY
+ * entry set will not signal to the MUSYCC that this descriptor
+ * has been serviced. The Interrupt Queue can then start losing
+ * available descriptors and MUSYCC eventually encounters and
+ * reports the INTFULL condition. Per manual, changing any bit
+ * marks descriptor as available, thus the use of different
+ * EMPTY_ENTRY values.
+ */
+
+ if (currInt == badInt)
+ ci->iqd_p[headx] = __constant_cpu_to_le32(INT_EMPTY_ENTRY2);
+ else
+ ci->iqd_p[headx] = __constant_cpu_to_le32(INT_EMPTY_ENTRY);
+ ci->iqp_headx = (headx + 1) & (INT_QUEUE_SIZE - 1); /* insure wrapness */
+ FLUSH_MEM_WRITE();
+ FLUSH_MEM_READ();
+ continue;
+ }
+ group = INTRPT_GRP(currInt);
+ gchan = INTRPT_CH(currInt);
+ event = INTRPT_EVENT(currInt);
+ err = INTRPT_ERROR(currInt);
+ tx = currInt & INTRPT_DIR_M;
+
+ ci->iqd_p[headx] = __constant_cpu_to_le32(INT_EMPTY_ENTRY);
+ FLUSH_MEM_WRITE();
+
+ if (cxt1e1_log_level >= LOG_DEBUG) {
+ if (err != 0)
+ pr_info(" %08x -> err: %2d,", currInt, err);
+
+ pr_info("+ interrupt event: %d, grp: %d, chan: %2d, side: %cX\n",
+ event, group, gchan, tx ? 'T' : 'R');
+ }
+ pi = &ci->port[group]; /* notice that here we assume 1-1 group -
+ * port mapping */
+ ch = pi->chan[gchan];
+ switch (event) {
+ case EVE_SACK: /* Service Request Acknowledge */
+ if (cxt1e1_log_level >= LOG_DEBUG) {
+ volatile u_int32_t r;
+
+ r = pci_read_32((u_int32_t *) &pi->reg->srd);
+ pr_info("- SACK cmd: %08x (hdw= %08x)\n", pi->sr_last, r);
+ }
+ SD_SEM_GIVE(&pi->sr_sem_wait); /* wake up waiting process */
+ break;
+ case EVE_CHABT: /* Change To Abort Code (0x7e -> 0xff) */
+ case EVE_CHIC: /* Change To Idle Code (0xff -> 0x7e) */
+ break;
+ case EVE_EOM: /* End Of Message */
+ case EVE_EOB: /* End Of Buffer (Transparent mode) */
+ if (tx)
+ musycc_bh_tx_eom(pi, gchan);
+ else
+ musycc_bh_rx_eom(pi, gchan);
#if 0
- break;
+ break;
#else
- /*
- * MUSYCC Interrupt Descriptor section states that EOB and EOM
- * can be combined with the NONE error (as well as others). So
- * drop thru to catch this...
- */
+ /*
+ * MUSYCC Interrupt Descriptor section states that EOB and EOM
+ * can be combined with the NONE error (as well as others). So
+ * drop thru to catch this...
+ */
#endif
- case EVE_NONE:
- if (err == ERR_SHT)
- {
- ch->s.rx_length_errors++;
- }
- break;
- default:
- if (cxt1e1_log_level >= LOG_WARN)
- pr_info("%s: unexpected interrupt event: %d, iqd[%d]: %08x, port: %d\n", ci->devname,
- event, headx, currInt, group);
- break;
- } /* switch on event */
-
-
- /*
- * Per MUSYCC Manual, Section 6.4.8.3 [Transmit Errors], TX errors
- * are service-affecting and require action to resume normal
- * bit-level processing.
- */
-
- switch (err)
- {
- case ERR_ONR:
- /*
- * Per MUSYCC manual, Section 6.4.8.3 [Transmit Errors], this
- * error requires Transmit channel reactivation.
- *
- * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors], this error
- * requires Receive channel reactivation.
- */
- if (tx)
- {
-
- /*
- * TX ONR Error only occurs when channel is configured for
- * Transparent Mode. However, this code will catch and
- * re-activate on ANY TX ONR error.
- */
-
- /*
- * Set flag to re-enable on any next transmit attempt.
- */
- ch->ch_start_tx = CH_START_TX_ONR;
-
- {
+ case EVE_NONE:
+ if (err == ERR_SHT)
+ ch->s.rx_length_errors++;
+ break;
+ default:
+ if (cxt1e1_log_level >= LOG_WARN)
+ pr_info("%s: unexpected interrupt event: %d, iqd[%d]: %08x, port: %d\n", ci->devname,
+ event, headx, currInt, group);
+ break;
+ } /* switch on event */
+
+
+ /*
+ * Per MUSYCC Manual, Section 6.4.8.3 [Transmit Errors], TX errors
+ * are service-affecting and require action to resume normal
+ * bit-level processing.
+ */
+
+ switch (err) {
+ case ERR_ONR:
+ /*
+ * Per MUSYCC manual, Section 6.4.8.3 [Transmit Errors], this
+ * error requires Transmit channel reactivation.
+ *
+ * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors], this error
+ * requires Receive channel reactivation.
+ */
+ if (tx) {
+
+ /*
+ * TX ONR Error only occurs when channel is configured for
+ * Transparent Mode. However, this code will catch and
+ * re-activate on ANY TX ONR error.
+ */
+
+ /*
+ * Set flag to re-enable on any next transmit attempt.
+ */
+ ch->ch_start_tx = CH_START_TX_ONR;
+
+ {
#ifdef RLD_TRANS_DEBUG
- if (1 || cxt1e1_log_level >= LOG_MONITOR)
+ if (1 || cxt1e1_log_level >= LOG_MONITOR)
#else
- if (cxt1e1_log_level >= LOG_MONITOR)
+ if (cxt1e1_log_level >= LOG_MONITOR)
#endif
- {
- pr_info("%s: TX buffer underflow [ONR] on channel %d, mode %x QStopped %x free %d\n",
- ci->devname, ch->channum, ch->p.chan_mode, sd_queue_stopped (ch->user), ch->txd_free);
+ {
+ pr_info("%s: TX buffer underflow [ONR] on channel %d, mode %x QStopped %x free %d\n",
+ ci->devname, ch->channum, ch->p.chan_mode, sd_queue_stopped(ch->user), ch->txd_free);
#ifdef RLD_DEBUG
- if (ch->p.chan_mode == 2) /* problem = ONR on HDLC
- * mode */
- {
- pr_info("++ Failed Last %x Next %x QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n",
- (u_int32_t) ch->txd_irq_srv, (u_int32_t) ch->txd_usr_add,
- sd_queue_stopped (ch->user),
- ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode);
- musycc_dump_txbuffer_ring (ch, 0);
- }
+ if (ch->p.chan_mode == 2) { /* problem = ONR on HDLC
+ * mode */
+ pr_info("++ Failed Last %x Next %x QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n",
+ (u_int32_t) ch->txd_irq_srv, (u_int32_t) ch->txd_usr_add,
+ sd_queue_stopped(ch->user),
+ ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode);
+ musycc_dump_txbuffer_ring(ch, 0);
+ }
#endif
- }
- }
- } else /* RX buffer overrun */
- {
- /*
- * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors],
- * channel recovery for this RX ONR error IS required. It is
- * also suggested to increase the number of receive buffers
- * for this channel. Receive channel reactivation IS
- * required, and data has been lost.
- */
- ch->s.rx_over_errors++;
- ch->ch_start_rx = CH_START_RX_ONR;
-
- if (cxt1e1_log_level >= LOG_WARN)
- {
- pr_info("%s: RX buffer overflow [ONR] on channel %d, mode %x\n",
- ci->devname, ch->channum, ch->p.chan_mode);
- //musycc_dump_rxbuffer_ring (ch, 0); /* RLD DEBUG */
- }
- }
- musycc_chan_restart (ch);
- break;
- case ERR_BUF:
- if (tx)
- {
- ch->s.tx_fifo_errors++;
- ch->ch_start_tx = CH_START_TX_BUF;
- /*
- * Per MUSYCC manual, Section 6.4.8.3 [Transmit Errors],
- * this BUFF error requires Transmit channel reactivation.
- */
- if (cxt1e1_log_level >= LOG_MONITOR)
- pr_info("%s: TX buffer underrun [BUFF] on channel %d, mode %x\n",
- ci->devname, ch->channum, ch->p.chan_mode);
- } else /* RX buffer overrun */
- {
- ch->s.rx_over_errors++;
- /*
- * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors], HDLC
- * mode requires NO recovery for this RX BUFF error is
- * required. It is suggested to increase the FIFO buffer
- * space for this channel. Receive channel reactivation is
- * not required, but data has been lost.
- */
- if (cxt1e1_log_level >= LOG_WARN)
- pr_info("%s: RX buffer overrun [BUFF] on channel %d, mode %x\n",
- ci->devname, ch->channum, ch->p.chan_mode);
- /*
- * Per MUSYCC manual, Section 6.4.9.4 [Receive Errors],
- * Transparent mode DOES require recovery for the RX BUFF
- * error. It is suggested to increase the FIFO buffer space
- * for this channel. Receive channel reactivation IS
- * required and data has been lost.
- */
- if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
- ch->ch_start_rx = CH_START_RX_BUF;
- }
-
- if (tx || (ch->p.chan_mode == CFG_CH_PROTO_TRANS))
- musycc_chan_restart (ch);
- break;
- default:
- break;
- } /* switch on err */
-
- /* Check for interrupt lost condition */
- if ((currInt & INTRPT_ILOST_M) && (cxt1e1_log_level >= LOG_ERROR))
- {
- pr_info("%s: Interrupt queue overflow - ILOST asserted\n",
- ci->devname);
- }
- ci->iqp_headx = (headx + 1) & (INT_QUEUE_SIZE - 1); /* insure wrapness */
- FLUSH_MEM_WRITE ();
- FLUSH_MEM_READ ();
+ }
+ }
+ } else { /* RX buffer overrun */
+ /*
+ * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors],
+ * channel recovery for this RX ONR error IS required. It is
+ * also suggested to increase the number of receive buffers
+ * for this channel. Receive channel reactivation IS
+ * required, and data has been lost.
+ */
+ ch->s.rx_over_errors++;
+ ch->ch_start_rx = CH_START_RX_ONR;
+
+ if (cxt1e1_log_level >= LOG_WARN) {
+ pr_info("%s: RX buffer overflow [ONR] on channel %d, mode %x\n",
+ ci->devname, ch->channum, ch->p.chan_mode);
+ //musycc_dump_rxbuffer_ring (ch, 0); /* RLD DEBUG */
+ }
+ }
+ musycc_chan_restart(ch);
+ break;
+ case ERR_BUF:
+ if (tx) {
+ ch->s.tx_fifo_errors++;
+ ch->ch_start_tx = CH_START_TX_BUF;
+ /*
+ * Per MUSYCC manual, Section 6.4.8.3 [Transmit Errors],
+ * this BUFF error requires Transmit channel reactivation.
+ */
+ if (cxt1e1_log_level >= LOG_MONITOR)
+ pr_info("%s: TX buffer underrun [BUFF] on channel %d, mode %x\n",
+ ci->devname, ch->channum, ch->p.chan_mode);
+ } else { /* RX buffer overrun */
+ ch->s.rx_over_errors++;
+ /*
+ * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors], HDLC
+ * mode requires NO recovery for this RX BUFF error is
+ * required. It is suggested to increase the FIFO buffer
+ * space for this channel. Receive channel reactivation is
+ * not required, but data has been lost.
+ */
+ if (cxt1e1_log_level >= LOG_WARN)
+ pr_info("%s: RX buffer overrun [BUFF] on channel %d, mode %x\n",
+ ci->devname, ch->channum, ch->p.chan_mode);
+ /*
+ * Per MUSYCC manual, Section 6.4.9.4 [Receive Errors],
+ * Transparent mode DOES require recovery for the RX BUFF
+ * error. It is suggested to increase the FIFO buffer space
+ * for this channel. Receive channel reactivation IS
+ * required and data has been lost.
+ */
+ if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
+ ch->ch_start_rx = CH_START_RX_BUF;
+ }
+
+ if (tx || (ch->p.chan_mode == CFG_CH_PROTO_TRANS))
+ musycc_chan_restart(ch);
+ break;
+ default:
+ break;
+ } /* switch on err */
+
+ /* Check for interrupt lost condition */
+ if ((currInt & INTRPT_ILOST_M) && (cxt1e1_log_level >= LOG_ERROR))
+ pr_info("%s: Interrupt queue overflow - ILOST asserted\n",
+ ci->devname);
+ ci->iqp_headx = (headx + 1) & (INT_QUEUE_SIZE - 1); /* insure wrapness */
+ FLUSH_MEM_WRITE();
+ FLUSH_MEM_READ();
} /* while */
- if ((cxt1e1_log_level >= LOG_MONITOR2) && (ci->iqp_headx != ci->iqp_tailx))
- {
- int bh;
+ if ((cxt1e1_log_level >= LOG_MONITOR2) && (ci->iqp_headx != ci->iqp_tailx)) {
+ int bh;
- bh = atomic_read (&CI->bh_pending);
- pr_info("_bh_: late arrivals, head %d != tail %d, pending %d\n",
- ci->iqp_headx, ci->iqp_tailx, bh);
+ bh = atomic_read(&CI->bh_pending);
+ pr_info("_bh_: late arrivals, head %d != tail %d, pending %d\n",
+ ci->iqp_headx, ci->iqp_tailx, bh);
}
#if defined(SBE_ISR_IMMEDIATE)
return 0L;
@@ -1634,14 +1517,14 @@ musycc_intr_bh_tasklet (ci_t * ci)
#if 0
int __init
-musycc_new_chan (ci_t * ci, int channum, void *user)
+musycc_new_chan(ci_t * ci, int channum, void *user)
{
mch_t *ch;
ch = ci->port[channum / MUSYCC_NCHANS].chan[channum % MUSYCC_NCHANS];
if (ch->state != UNASSIGNED)
- return EEXIST;
+ return EEXIST;
/* NOTE: mch_t already cleared during OS_kmalloc() */
ch->state = DOWN;
ch->user = user;
@@ -1653,8 +1536,8 @@ musycc_new_chan (ci_t * ci, int channum, void *user)
ch->p.chan_mode = CFG_CH_PROTO_HDLC_FCS16;
ch->p.idlecode = CFG_CH_FLAG_7E;
ch->p.pad_fill_count = 2;
- spin_lock_init (&ch->ch_rxlock);
- spin_lock_init (&ch->ch_txlock);
+ spin_lock_init(&ch->ch_rxlock);
+ spin_lock_init(&ch->ch_txlock);
return 0;
}
@@ -1663,53 +1546,49 @@ musycc_new_chan (ci_t * ci, int channum, void *user)
#ifdef SBE_PMCC4_ENABLE
status_t
-musycc_chan_down (ci_t * dummy, int channum)
+musycc_chan_down(ci_t * dummy, int channum)
{
mpi_t *pi;
mch_t *ch;
int i, gchan;
- if (!(ch = sd_find_chan (dummy, channum)))
- return EINVAL;
+ if (!(ch = sd_find_chan(dummy, channum)))
+ return EINVAL;
pi = ch->up;
gchan = ch->gchan;
/* Deactivate the channel */
- musycc_serv_req (pi, SR_CHANNEL_DEACTIVATE | SR_RX_DIRECTION | gchan);
+ musycc_serv_req(pi, SR_CHANNEL_DEACTIVATE | SR_RX_DIRECTION | gchan);
ch->ch_start_rx = 0;
- musycc_serv_req (pi, SR_CHANNEL_DEACTIVATE | SR_TX_DIRECTION | gchan);
+ musycc_serv_req(pi, SR_CHANNEL_DEACTIVATE | SR_TX_DIRECTION | gchan);
ch->ch_start_tx = 0;
if (ch->state == DOWN)
- return 0;
+ return 0;
ch->state = DOWN;
pi->regram->thp[gchan] = 0;
pi->regram->tmp[gchan] = 0;
pi->regram->rhp[gchan] = 0;
pi->regram->rmp[gchan] = 0;
- FLUSH_MEM_WRITE ();
+ FLUSH_MEM_WRITE();
for (i = 0; i < ch->txd_num; i++)
- {
- if (ch->mdt[i].mem_token != 0)
- OS_mem_token_free (ch->mdt[i].mem_token);
- }
+ if (ch->mdt[i].mem_token != 0)
+ OS_mem_token_free(ch->mdt[i].mem_token);
for (i = 0; i < ch->rxd_num; i++)
- {
- if (ch->mdr[i].mem_token != 0)
- OS_mem_token_free (ch->mdr[i].mem_token);
- }
+ if (ch->mdr[i].mem_token != 0)
+ OS_mem_token_free(ch->mdr[i].mem_token);
- OS_kfree (ch->mdr);
+ OS_kfree(ch->mdr);
ch->mdr = 0;
ch->rxd_num = 0;
- OS_kfree (ch->mdt);
+ OS_kfree(ch->mdt);
ch->mdt = 0;
ch->txd_num = 0;
- musycc_update_timeslots (pi);
- c4_fifo_free (pi, ch->gchan);
+ musycc_update_timeslots(pi);
+ c4_fifo_free(pi, ch->gchan);
pi->openchans--;
return 0;
@@ -1718,38 +1597,38 @@ musycc_chan_down (ci_t * dummy, int channum)
int
-musycc_del_chan (ci_t * ci, int channum)
+musycc_del_chan(ci_t * ci, int channum)
{
mch_t *ch;
if ((channum < 0) || (channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS))) /* sanity chk param */
- return ECHRNG;
- if (!(ch = sd_find_chan (ci, channum)))
- return ENOENT;
+ return ECHRNG;
+ if (!(ch = sd_find_chan(ci, channum)))
+ return ENOENT;
if (ch->state == UP)
- musycc_chan_down (ci, channum);
+ musycc_chan_down(ci, channum);
ch->state = UNASSIGNED;
return 0;
}
int
-musycc_del_chan_stats (ci_t * ci, int channum)
+musycc_del_chan_stats(ci_t * ci, int channum)
{
mch_t *ch;
if (channum < 0 || channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS)) /* sanity chk param */
- return ECHRNG;
- if (!(ch = sd_find_chan (ci, channum)))
- return ENOENT;
+ return ECHRNG;
+ if (!(ch = sd_find_chan(ci, channum)))
+ return ENOENT;
- memset (&ch->s, 0, sizeof (struct sbecom_chan_stats));
+ memset(&ch->s, 0, sizeof(struct sbecom_chan_stats));
return 0;
}
int
-musycc_start_xmit (ci_t * ci, int channum, void *mem_token)
+musycc_start_xmit(ci_t * ci, int channum, void *mem_token)
{
mch_t *ch;
struct mdesc *md;
@@ -1760,16 +1639,16 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token)
int txd_need_cnt;
u_int32_t len;
- if (!(ch = sd_find_chan (ci, channum)))
- return -ENOENT;
+ if (!(ch = sd_find_chan(ci, channum)))
+ return -ENOENT;
if (ci->state != C_RUNNING) /* full interrupt processing available */
- return -EINVAL;
+ return -EINVAL;
if (ch->state != UP)
- return -EINVAL;
+ return -EINVAL;
if (!(ch->status & TX_ENABLED))
- return -EROFS; /* how else to flag unwritable state ? */
+ return -EROFS; /* how else to flag unwritable state ? */
#ifdef RLD_TRANS_DEBUGx
if (1 || cxt1e1_log_level >= LOG_MONITOR2)
@@ -1777,66 +1656,58 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token)
if (cxt1e1_log_level >= LOG_MONITOR2)
#endif
{
- pr_info("++ start_xmt[%d]: state %x start %x full %d free %d required %d stopped %x\n",
- channum, ch->state, ch->ch_start_tx, ch->tx_full,
- ch->txd_free, ch->txd_required, sd_queue_stopped (ch->user));
+ pr_info("++ start_xmt[%d]: state %x start %x full %d free %d required %d stopped %x\n",
+ channum, ch->state, ch->ch_start_tx, ch->tx_full,
+ ch->txd_free, ch->txd_required, sd_queue_stopped(ch->user));
}
/***********************************************/
/** Determine total amount of data to be sent **/
/***********************************************/
m2 = mem_token;
txd_need_cnt = 0;
- for (len = OS_mem_token_tlen (m2); len > 0;
- m2 = (void *) OS_mem_token_next (m2))
- {
- if (!OS_mem_token_len (m2))
- continue;
- txd_need_cnt++;
- len -= OS_mem_token_len (m2);
+ for (len = OS_mem_token_tlen(m2); len > 0;
+ m2 = (void *) OS_mem_token_next(m2)) {
+ if (!OS_mem_token_len(m2))
+ continue;
+ txd_need_cnt++;
+ len -= OS_mem_token_len(m2);
}
- if (txd_need_cnt == 0)
- {
- if (cxt1e1_log_level >= LOG_MONITOR2)
- pr_info("%s channel %d: no TX data in User buffer\n", ci->devname, channum);
- OS_mem_token_free (mem_token);
- return 0; /* no data to send */
+ if (txd_need_cnt == 0) {
+ if (cxt1e1_log_level >= LOG_MONITOR2)
+ pr_info("%s channel %d: no TX data in User buffer\n", ci->devname, channum);
+ OS_mem_token_free(mem_token);
+ return 0; /* no data to send */
}
/*************************************************/
/** Are there sufficient descriptors available? **/
/*************************************************/
- if (txd_need_cnt > ch->txd_num) /* never enough descriptors for this
- * large a buffer */
- {
- if (cxt1e1_log_level >= LOG_DEBUG)
- {
- pr_info("start_xmit: discarding buffer, insufficient descriptor cnt %d, need %d.\n",
- ch->txd_num, txd_need_cnt + 1);
- }
- ch->s.tx_dropped++;
- OS_mem_token_free (mem_token);
- return 0;
+ if (txd_need_cnt > ch->txd_num) { /* never enough descriptors for this
+ * large a buffer */
+ if (cxt1e1_log_level >= LOG_DEBUG)
+ pr_info("start_xmit: discarding buffer, insufficient descriptor cnt %d, need %d.\n",
+ ch->txd_num, txd_need_cnt + 1);
+ ch->s.tx_dropped++;
+ OS_mem_token_free(mem_token);
+ return 0;
}
#if 0
- spin_lock_irqsave (&ch->ch_txlock, flags);
+ spin_lock_irqsave(&ch->ch_txlock, flags);
#endif
/************************************************************/
/** flow control the line if not enough descriptors remain **/
/************************************************************/
- if (txd_need_cnt > ch->txd_free)
- {
- if (cxt1e1_log_level >= LOG_MONITOR2)
- {
- pr_info("start_xmit[%d]: EBUSY - need more descriptors, have %d of %d need %d\n",
- channum, ch->txd_free, ch->txd_num, txd_need_cnt);
- }
- ch->tx_full = 1;
- ch->txd_required = txd_need_cnt;
- sd_disable_xmit (ch->user);
+ if (txd_need_cnt > ch->txd_free) {
+ if (cxt1e1_log_level >= LOG_MONITOR2)
+ pr_info("start_xmit[%d]: EBUSY - need more descriptors, have %d of %d need %d\n",
+ channum, ch->txd_free, ch->txd_num, txd_need_cnt);
+ ch->tx_full = 1;
+ ch->txd_required = txd_need_cnt;
+ sd_disable_xmit(ch->user);
#if 0
- spin_unlock_irqrestore (&ch->ch_txlock, flags);
+ spin_unlock_irqrestore(&ch->ch_txlock, flags);
#endif
- return -EBUSY; /* tell user to try again later */
+ return -EBUSY; /* tell user to try again later */
}
/**************************************************/
/** Put the user data into MUSYCC data buffer(s) **/
@@ -1844,74 +1715,71 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token)
m2 = mem_token;
md = ch->txd_usr_add; /* get current available descriptor */
- for (len = OS_mem_token_tlen (m2); len > 0; m2 = OS_mem_token_next (m2))
- {
- int u = OS_mem_token_len (m2);
-
- if (!u)
- continue;
- len -= u;
-
- /*
- * Enable following chunks, yet wait to enable the FIRST chunk until
- * after ALL subsequent chunks are setup.
- */
- if (md != ch->txd_usr_add) /* not first chunk */
- u |= MUSYCC_TX_OWNED; /* transfer ownership from HOST to MUSYCC */
-
- if (len) /* not last chunk */
- u |= EOBIRQ_ENABLE;
- else if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
- {
- /*
- * Per MUSYCC Ref 6.4.9 for Transparent Mode, the host must
- * always clear EOMIRQ_ENABLE in every Transmit Buffer Descriptor
- * (IE. don't set herein).
- */
- u |= EOBIRQ_ENABLE;
- } else
- u |= EOMIRQ_ENABLE; /* EOM, last HDLC chunk */
-
-
- /* last chunk in hdlc mode */
- u |= (ch->p.idlecode << IDLE_CODE);
- if (ch->p.pad_fill_count)
- {
+ for (len = OS_mem_token_tlen(m2); len > 0; m2 = OS_mem_token_next(m2)) {
+ int u = OS_mem_token_len(m2);
+
+ if (!u)
+ continue;
+ len -= u;
+
+ /*
+ * Enable following chunks, yet wait to enable the FIRST chunk until
+ * after ALL subsequent chunks are setup.
+ */
+ if (md != ch->txd_usr_add) /* not first chunk */
+ u |= MUSYCC_TX_OWNED; /* transfer ownership from HOST to MUSYCC */
+
+ if (len) /* not last chunk */
+ u |= EOBIRQ_ENABLE;
+ else if (ch->p.chan_mode == CFG_CH_PROTO_TRANS) {
+ /*
+ * Per MUSYCC Ref 6.4.9 for Transparent Mode, the host must
+ * always clear EOMIRQ_ENABLE in every Transmit Buffer Descriptor
+ * (IE. don't set herein).
+ */
+ u |= EOBIRQ_ENABLE;
+ } else
+ u |= EOMIRQ_ENABLE; /* EOM, last HDLC chunk */
+
+
+ /* last chunk in hdlc mode */
+ u |= (ch->p.idlecode << IDLE_CODE);
+ if (ch->p.pad_fill_count) {
#if 0
- /* NOOP NOTE: u_int8_t cannot be > 0xFF */
- /* sanitize pad_fill_count for maximums allowed by hardware */
- if (ch->p.pad_fill_count > EXTRA_FLAGS_MASK)
- ch->p.pad_fill_count = EXTRA_FLAGS_MASK;
+ /* NOOP NOTE: u_int8_t cannot be > 0xFF */
+ /* sanitize pad_fill_count for maximums allowed by hardware */
+ if (ch->p.pad_fill_count > EXTRA_FLAGS_MASK)
+ ch->p.pad_fill_count = EXTRA_FLAGS_MASK;
#endif
- u |= (PADFILL_ENABLE | (ch->p.pad_fill_count << EXTRA_FLAGS));
- }
- md->mem_token = len ? 0 : mem_token; /* Fill in mds on last
- * segment, others set ZERO
- * so that entire token is
- * removed ONLY when ALL
- * segments have been
- * transmitted. */
-
- md->data = cpu_to_le32 (OS_vtophys (OS_mem_token_data (m2)));
- FLUSH_MEM_WRITE ();
- md->status = cpu_to_le32 (u);
- --ch->txd_free;
- md = md->snext;
+ u |= (PADFILL_ENABLE | (ch->p.pad_fill_count << EXTRA_FLAGS));
+ }
+ md->mem_token = len ? 0 : mem_token; /* Fill in mds on last
+ * segment, others set ZERO
+ * so that entire token is
+ * removed ONLY when ALL
+ * segments have been
+ * transmitted. */
+
+ md->data = cpu_to_le32(OS_vtophys(OS_mem_token_data(m2)));
+ FLUSH_MEM_WRITE();
+ md->status = cpu_to_le32(u);
+ --ch->txd_free;
+ md = md->snext;
}
- FLUSH_MEM_WRITE ();
+ FLUSH_MEM_WRITE();
/*
* Now transfer ownership of first chunk from HOST to MUSYCC in order to
* fire-off this XMIT.
*/
- ch->txd_usr_add->status |= __constant_cpu_to_le32 (MUSYCC_TX_OWNED);
- FLUSH_MEM_WRITE ();
+ ch->txd_usr_add->status |= __constant_cpu_to_le32(MUSYCC_TX_OWNED);
+ FLUSH_MEM_WRITE();
ch->txd_usr_add = md;
- len = OS_mem_token_tlen (mem_token);
- atomic_add (len, &ch->tx_pending);
- atomic_add (len, &ci->tx_pending);
+ len = OS_mem_token_tlen(mem_token);
+ atomic_add(len, &ch->tx_pending);
+ atomic_add(len, &ci->tx_pending);
ch->s.tx_packets++;
ch->s.tx_bytes += len;
/*
@@ -1919,11 +1787,9 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token)
* transmission.
*/
if (ch->ch_start_tx)
- {
- musycc_chan_restart (ch);
- }
+ musycc_chan_restart(ch);
#ifdef SBE_WAN256T3_ENABLE
- wan256t3_led (ci, LED_TX, LEDV_G);
+ wan256t3_led(ci, LED_TX, LEDV_G);
#endif
return 0;
}
diff --git a/drivers/staging/cxt1e1/musycc.h b/drivers/staging/cxt1e1/musycc.h
index cf6b54e1568..56fb42f0f64 100644
--- a/drivers/staging/cxt1e1/musycc.h
+++ b/drivers/staging/cxt1e1/musycc.h
@@ -48,59 +48,57 @@
#define INT_QUEUE_SIZE MUSYCC_NIQD
/* RAM image of MUSYCC registers laid out as a C structure */
- struct musycc_groupr
- {
- VINT32 thp[32]; /* Transmit Head Pointer [5-29] */
- VINT32 tmp[32]; /* Transmit Message Pointer [5-30] */
- VINT32 rhp[32]; /* Receive Head Pointer [5-29] */
- VINT32 rmp[32]; /* Receive Message Pointer [5-30] */
- VINT8 ttsm[128]; /* Time Slot Map [5-22] */
- VINT8 tscm[256]; /* Subchannel Map [5-24] */
- VINT32 tcct[32]; /* Channel Configuration [5-26] */
- VINT8 rtsm[128]; /* Time Slot Map [5-22] */
- VINT8 rscm[256]; /* Subchannel Map [5-24] */
- VINT32 rcct[32]; /* Channel Configuration [5-26] */
- VINT32 __glcd; /* Global Configuration Descriptor [5-10] */
- VINT32 __iqp; /* Interrupt Queue Pointer [5-36] */
- VINT32 __iql; /* Interrupt Queue Length [5-36] */
- VINT32 grcd; /* Group Configuration Descriptor [5-16] */
- VINT32 mpd; /* Memory Protection Descriptor [5-18] */
- VINT32 mld; /* Message Length Descriptor [5-20] */
- VINT32 pcd; /* Port Configuration Descriptor [5-19] */
- };
+struct musycc_groupr {
+ VINT32 thp[32]; /* Transmit Head Pointer [5-29] */
+ VINT32 tmp[32]; /* Transmit Message Pointer [5-30] */
+ VINT32 rhp[32]; /* Receive Head Pointer [5-29] */
+ VINT32 rmp[32]; /* Receive Message Pointer [5-30] */
+ VINT8 ttsm[128]; /* Time Slot Map [5-22] */
+ VINT8 tscm[256]; /* Subchannel Map [5-24] */
+ VINT32 tcct[32]; /* Channel Configuration [5-26] */
+ VINT8 rtsm[128]; /* Time Slot Map [5-22] */
+ VINT8 rscm[256]; /* Subchannel Map [5-24] */
+ VINT32 rcct[32]; /* Channel Configuration [5-26] */
+ VINT32 __glcd; /* Global Configuration Descriptor [5-10] */
+ VINT32 __iqp; /* Interrupt Queue Pointer [5-36] */
+ VINT32 __iql; /* Interrupt Queue Length [5-36] */
+ VINT32 grcd; /* Group Configuration Descriptor [5-16] */
+ VINT32 mpd; /* Memory Protection Descriptor [5-18] */
+ VINT32 mld; /* Message Length Descriptor [5-20] */
+ VINT32 pcd; /* Port Configuration Descriptor [5-19] */
+};
/* hardware MUSYCC registers laid out as a C structure */
- struct musycc_globalr
- {
- VINT32 gbp; /* Group Base Pointer */
- VINT32 dacbp; /* Dual Address Cycle Base Pointer */
- VINT32 srd; /* Service Request Descriptor */
- VINT32 isd; /* Interrupt Service Descriptor */
- /*
- * adjust __thp due to above 4 registers, which are not contained
- * within musycc_groupr[]. All __XXX[] are just place holders,
- * anyhow.
- */
- VINT32 __thp[32 - 4]; /* Transmit Head Pointer [5-29] */
- VINT32 __tmp[32]; /* Transmit Message Pointer [5-30] */
- VINT32 __rhp[32]; /* Receive Head Pointer [5-29] */
- VINT32 __rmp[32]; /* Receive Message Pointer [5-30] */
- VINT8 ttsm[128]; /* Time Slot Map [5-22] */
- VINT8 tscm[256]; /* Subchannel Map [5-24] */
- VINT32 tcct[32]; /* Channel Configuration [5-26] */
- VINT8 rtsm[128]; /* Time Slot Map [5-22] */
- VINT8 rscm[256]; /* Subchannel Map [5-24] */
- VINT32 rcct[32]; /* Channel Configuration [5-26] */
- VINT32 glcd; /* Global Configuration Descriptor [5-10] */
- VINT32 iqp; /* Interrupt Queue Pointer [5-36] */
- VINT32 iql; /* Interrupt Queue Length [5-36] */
- VINT32 grcd; /* Group Configuration Descriptor [5-16] */
- VINT32 mpd; /* Memory Protection Descriptor [5-18] */
- VINT32 mld; /* Message Length Descriptor [5-20] */
- VINT32 pcd; /* Port Configuration Descriptor [5-19] */
- VINT32 rbist; /* Receive BIST status [5-4] */
- VINT32 tbist; /* Receive BIST status [5-4] */
- };
+struct musycc_globalr {
+ VINT32 gbp; /* Group Base Pointer */
+ VINT32 dacbp; /* Dual Address Cycle Base Pointer */
+ VINT32 srd; /* Service Request Descriptor */
+ VINT32 isd; /* Interrupt Service Descriptor */
+ /*
+ * adjust __thp due to above 4 registers, which are not contained
+ * within musycc_groupr[]. All __XXX[] are just place holders,
+ * anyhow.
+ */
+ VINT32 __thp[32 - 4]; /* Transmit Head Pointer [5-29] */
+ VINT32 __tmp[32]; /* Transmit Message Pointer [5-30] */
+ VINT32 __rhp[32]; /* Receive Head Pointer [5-29] */
+ VINT32 __rmp[32]; /* Receive Message Pointer [5-30] */
+ VINT8 ttsm[128]; /* Time Slot Map [5-22] */
+ VINT8 tscm[256]; /* Subchannel Map [5-24] */
+ VINT32 tcct[32]; /* Channel Configuration [5-26] */
+ VINT8 rtsm[128]; /* Time Slot Map [5-22] */
+ VINT8 rscm[256]; /* Subchannel Map [5-24] */
+ VINT32 rcct[32]; /* Channel Configuration [5-26] */
+ VINT32 glcd; /* Global Configuration Descriptor [5-10] */
+ VINT32 iqp; /* Interrupt Queue Pointer [5-36] */
+ VINT32 iql; /* Interrupt Queue Length [5-36] */
+ VINT32 grcd; /* Group Configuration Descriptor [5-16] */
+ VINT32 mpd; /* Memory Protection Descriptor [5-18] */
+ VINT32 mld; /* Message Length Descriptor [5-20] */
+ VINT32 pcd; /* Port Configuration Descriptor [5-19] */
+ VINT32 rbist; /* Receive BIST status [5-4] */
+ VINT32 tbist; /* Receive BIST status [5-4] */
+};
/* Global Config Descriptor bit macros */
#define MUSYCC_GCD_ECLK_ENABLE 0x00000800 /* EBUS clock enable */
@@ -108,18 +106,18 @@
#define MUSYCC_GCD_INTA_DISABLE 0x00000008 /* PCI INTA disable */
#define MUSYCC_GCD_INTB_DISABLE 0x00000004 /* PCI INTB disable */
#define MUSYCC_GCD_BLAPSE 12 /* Position index for BLAPSE bit
- * field */
+ * field */
#define MUSYCC_GCD_ALAPSE 8 /* Position index for ALAPSE bit
- * field */
+ * field */
#define MUSYCC_GCD_ELAPSE 4 /* Position index for ELAPSE bit
- * field */
+ * field */
#define MUSYCC_GCD_PORTMAP_3 3 /* Reserved */
#define MUSYCC_GCD_PORTMAP_2 2 /* Port 0=>Grp 0,1,2,3; Port 1=>Grp
- * 4,5,6,7 */
+ * 4,5,6,7 */
#define MUSYCC_GCD_PORTMAP_1 1 /* Port 0=>Grp 0,1; Port 1=>Grp 2,3,
- * etc... */
+ * etc... */
#define MUSYCC_GCD_PORTMAP_0 0 /* Port 0=>Grp 0; Port 1=>Grp 2,
- * etc... */
+ * etc... */
/* and board specific assignments... */
#ifdef SBE_WAN256T3_ENABLE
@@ -137,57 +135,57 @@
#endif
#define GCD_MAGIC (((BLAPSE_VAL)<<(MUSYCC_GCD_BLAPSE)) | \
- ((ALAPSE_VAL)<<(MUSYCC_GCD_ALAPSE)) | \
- ((ELAPSE_VAL)<<(MUSYCC_GCD_ELAPSE)) | \
- (MUSYCC_GCD_ECLK_ENABLE) | PORTMAP_VAL)
+ ((ALAPSE_VAL)<<(MUSYCC_GCD_ALAPSE)) | \
+ ((ELAPSE_VAL)<<(MUSYCC_GCD_ELAPSE)) | \
+ (MUSYCC_GCD_ECLK_ENABLE) | PORTMAP_VAL)
/* Group Config Descriptor bit macros */
#define MUSYCC_GRCD_RX_ENABLE 0x00000001 /* Enable receive processing */
#define MUSYCC_GRCD_TX_ENABLE 0x00000002 /* Enable transmit processing */
#define MUSYCC_GRCD_SUBCHAN_DISABLE 0x00000004 /* Master disable for
- * subchanneling */
+ * subchanneling */
#define MUSYCC_GRCD_OOFMP_DISABLE 0x00000008 /* Out of Frame message
- * processing disabled all
- * channels */
+ * processing disabled all
+ * channels */
#define MUSYCC_GRCD_OOFIRQ_DISABLE 0x00000010 /* Out of Frame/In Frame irqs
- * disabled */
+ * disabled */
#define MUSYCC_GRCD_COFAIRQ_DISABLE 0x00000020 /* Change of Frame Alignment
- * irq disabled */
+ * irq disabled */
#define MUSYCC_GRCD_INHRBSD 0x00000100 /* Receive Buffer Status
- * overwrite disabled */
+ * overwrite disabled */
#define MUSYCC_GRCD_INHTBSD 0x00000200 /* Transmit Buffer Status
- * overwrite disabled */
+ * overwrite disabled */
#define MUSYCC_GRCD_SF_ALIGN 0x00008000 /* External frame sync */
#define MUSYCC_GRCD_MC_ENABLE 0x00000040 /* Message configuration bits
- * copy enable. Conexant sez
- * turn this on */
+ * copy enable. Conexant sez
+ * turn this on */
#define MUSYCC_GRCD_POLLTH_16 0x00000001 /* Poll every 16th frame */
#define MUSYCC_GRCD_POLLTH_32 0x00000002 /* Poll every 32nd frame */
#define MUSYCC_GRCD_POLLTH_64 0x00000003 /* Poll every 64th frame */
#define MUSYCC_GRCD_POLLTH_SHIFT 10 /* Position index for poll throttle
- * bit field */
+ * bit field */
#define MUSYCC_GRCD_SUERM_THRESH_SHIFT 16 /* Position index for SUERM
- * count threshold */
+ * count threshold */
/* Port Config Descriptor bit macros */
#define MUSYCC_PCD_E1X2_MODE 2 /* Port mode in bits 0-2. T1 and E1 */
#define MUSYCC_PCD_E1X4_MODE 3 /* are defined in cn847x.h */
#define MUSYCC_PCD_NX64_MODE 4
#define MUSYCC_PCD_TXDATA_RISING 0x00000010 /* Sample Tx data on TCLK
- * rising edge */
+ * rising edge */
#define MUSYCC_PCD_TXSYNC_RISING 0x00000020 /* Sample Tx frame sync on
- * TCLK rising edge */
+ * TCLK rising edge */
#define MUSYCC_PCD_RXDATA_RISING 0x00000040 /* Sample Rx data on RCLK
- * rising edge */
+ * rising edge */
#define MUSYCC_PCD_RXSYNC_RISING 0x00000080 /* Sample Rx frame sync on
- * RCLK rising edge */
+ * RCLK rising edge */
#define MUSYCC_PCD_ROOF_RISING 0x00000100 /* Sample Rx Out Of Frame
- * signal on RCLK rising edge */
+ * signal on RCLK rising edge */
#define MUSYCC_PCD_TX_DRIVEN 0x00000200 /* No mapped timeslots causes
- * logic 1 on output, else
- * tristate */
+ * logic 1 on output, else
+ * tristate */
#define MUSYCC_PCD_PORTMODE_MASK 0xfffffff8 /* For changing the port mode
- * between E1 and T1 */
+ * between E1 and T1 */
/* Time Slot Descriptor bit macros */
#define MUSYCC_TSD_MODE_64KBPS 4
@@ -202,17 +200,17 @@
#define MUSYCC_CCD_BUFIRQ_DISABLE 0x00000002 /* BUFF and ONR irqs disabled */
#define MUSYCC_CCD_EOMIRQ_DISABLE 0x00000004 /* EOM irq disabled */
#define MUSYCC_CCD_MSGIRQ_DISABLE 0x00000008 /* LNG, FCS, ALIGN, and ABT
- * irqs disabled */
+ * irqs disabled */
#define MUSYCC_CCD_IDLEIRQ_DISABLE 0x00000010 /* CHABT, CHIC, and SHT irqs
- * disabled */
+ * disabled */
#define MUSYCC_CCD_FILTIRQ_DISABLE 0x00000020 /* SFILT irq disabled */
#define MUSYCC_CCD_SDECIRQ_DISABLE 0x00000040 /* SDEC irq disabled */
#define MUSYCC_CCD_SINCIRQ_DISABLE 0x00000080 /* SINC irq disabled */
#define MUSYCC_CCD_SUERIRQ_DISABLE 0x00000100 /* SUERR irq disabled */
#define MUSYCC_CCD_FCS_XFER 0x00000200 /* Propagate FCS along with
- * received data */
+ * received data */
#define MUSYCC_CCD_PROTO_SHIFT 12 /* Position index for protocol bit
- * field */
+ * field */
#define MUSYCC_CCD_TRANS 0 /* Protocol mode in bits 12-14 */
#define MUSYCC_CCD_SS7 1
#define MUSYCC_CCD_HDLC_FCS16 2
@@ -220,11 +218,11 @@
#define MUSYCC_CCD_EOPIRQ_DISABLE 0x00008000 /* EOP irq disabled */
#define MUSYCC_CCD_INVERT_DATA 0x00800000 /* Invert data */
#define MUSYCC_CCD_MAX_LENGTH 10 /* Position index for max length bit
- * field */
+ * field */
#define MUSYCC_CCD_BUFFER_LENGTH 16 /* Position index for internal data
- * buffer length */
+ * buffer length */
#define MUSYCC_CCD_BUFFER_LOC 24 /* Position index for internal data
- * buffer starting location */
+ * buffer starting location */
/****************************************************************************
* Interrupt Descriptor Information */
@@ -266,7 +264,7 @@
#define INTRPT_GRP_S 29
#define INTRPT_GRP_MSB_S 12
#define INTRPT_GRP(x) (((x & INTRPT_GRP_M) >> INTRPT_GRP_S) | \
- ((x & INTRPT_GRP_MSB_M) >> INTRPT_GRP_MSB_S))
+ ((x & INTRPT_GRP_MSB_M) >> INTRPT_GRP_MSB_S))
#define INTRPT_CH_M 0x1F000000
#define INTRPT_CH_S 24
@@ -295,82 +293,82 @@
/* Buffer Descriptor bit macros */
#define OWNER_BIT 0x80000000 /* Set for MUSYCC owner on xmit, host
- * owner on receive */
+ * owner on receive */
#define HOST_TX_OWNED 0x00000000 /* Host owns descriptor */
#define MUSYCC_TX_OWNED 0x80000000 /* MUSYCC owns descriptor */
#define HOST_RX_OWNED 0x80000000 /* Host owns descriptor */
#define MUSYCC_RX_OWNED 0x00000000 /* MUSYCC owns descriptor */
#define POLL_DISABLED 0x40000000 /* MUSYCC not allowed to poll buffer
- * for ownership */
+ * for ownership */
#define EOMIRQ_ENABLE 0x20000000 /* This buffer contains the end of
- * the message */
+ * the message */
#define EOBIRQ_ENABLE 0x10000000 /* EOB irq enabled */
#define PADFILL_ENABLE 0x01000000 /* Enable padfill */
#define REPEAT_BIT 0x00008000 /* Bit on for FISU descriptor */
#define LENGTH_MASK 0X3fff /* This part of status descriptor is
- * length */
+ * length */
#define IDLE_CODE 25 /* Position index for idle code (2
- * bits) */
+ * bits) */
#define EXTRA_FLAGS 16 /* Position index for minimum flags
- * between messages (8 bits) */
+ * between messages (8 bits) */
#define IDLE_CODE_MASK 0x03 /* Gets rid of garbage before the
- * pattern is OR'd in */
+ * pattern is OR'd in */
#define EXTRA_FLAGS_MASK 0xff /* Gets rid of garbage before the
- * pattern is OR'd in */
+ * pattern is OR'd in */
#define PCI_PERMUTED_OWNER_BIT 0x00000080 /* For flipping the bit on
- * the polled mode descriptor */
+ * the polled mode descriptor */
/* Service Request Descriptor bit macros */
#define SREQ 8 /* Position index for service request bit
- * field */
+ * field */
#define SR_NOOP (0<<(SREQ)) /* No Operation. Generates SACK */
#define SR_CHIP_RESET (1<<(SREQ)) /* Soft chip reset */
#define SR_GROUP_RESET (2<<(SREQ)) /* Group reset */
#define SR_GLOBAL_INIT (4<<(SREQ)) /* Global init: read global
- * config deswc and interrupt
- * queue desc */
+ * config deswc and interrupt
+ * queue desc */
#define SR_GROUP_INIT (5<<(SREQ)) /* Group init: read Timeslot
- * and Subchannel maps,
- * Channel Config, */
+ * and Subchannel maps,
+ * Channel Config, */
/*
* Group Config, Memory Protect, Message Length, and Port Config
* Descriptors
*/
#define SR_CHANNEL_ACTIVATE (8<<(SREQ)) /* Init channel, read Head
- * Pointer, process first
- * Message Descriptor */
+ * Pointer, process first
+ * Message Descriptor */
#define SR_GCHANNEL_MASK 0x001F /* channel portion (gchan) */
#define SR_CHANNEL_DEACTIVATE (9<<(SREQ)) /* Stop channel processing */
#define SR_JUMP (10<<(SREQ)) /* a: Process new Message
- * List */
+ * List */
#define SR_CHANNEL_CONFIG (11<<(SREQ)) /* b: Read channel
- * Configuration Descriptor */
+ * Configuration Descriptor */
#define SR_GLOBAL_CONFIG (16<<(SREQ)) /* 10: Read Global
- * Configuration Descriptor */
+ * Configuration Descriptor */
#define SR_INTERRUPT_Q (17<<(SREQ)) /* 11: Read Interrupt Queue
- * Descriptor */
+ * Descriptor */
#define SR_GROUP_CONFIG (18<<(SREQ)) /* 12: Read Group
- * Configuration Descriptor */
+ * Configuration Descriptor */
#define SR_MEMORY_PROTECT (19<<(SREQ)) /* 13: Read Memory Protection
- * Descriptor */
+ * Descriptor */
#define SR_MESSAGE_LENGTH (20<<(SREQ)) /* 14: Read Message Length
- * Descriptor */
+ * Descriptor */
#define SR_PORT_CONFIG (21<<(SREQ)) /* 15: Read Port
- * Configuration Descriptor */
+ * Configuration Descriptor */
#define SR_TIMESLOT_MAP (24<<(SREQ)) /* 18: Read Timeslot Map */
#define SR_SUBCHANNEL_MAP (25<<(SREQ)) /* 19: Read Subchannel Map */
#define SR_CHAN_CONFIG_TABLE (26<<(SREQ)) /* 20: Read Channel
- * Configuration Table for
- * the group */
+ * Configuration Table for
+ * the group */
#define SR_TX_DIRECTION 0x00000020 /* Transmit direction bit.
- * Bit off indicates receive
- * direction */
+ * Bit off indicates receive
+ * direction */
#define SR_RX_DIRECTION 0x00000000
/* Interrupt Descriptor bit macros */
#define GROUP10 29 /* Position index for the 2 LS group
- * bits */
+ * bits */
#define CHANNEL 24 /* Position index for channel bits */
#define INT_IQD_TX 0x80000000
#define INT_IQD_GRP 0x60000000
@@ -384,7 +382,7 @@
/* Interrupt Descriptor Events */
#define EVE_EVENT 20 /* Position index for event bits */
#define EVE_NONE 0 /* No event to report in this
- * interrupt */
+ * interrupt */
#define EVE_SACK 1 /* Service Request acknowledge */
#define EVE_EOB 2 /* End of Buffer */
#define EVE_EOM 3 /* End of Message */
@@ -411,12 +409,12 @@
#define ERR_PERR 15 /* PCI Parity Error */
/* Other Stuff */
#define TRANSMIT_DIRECTION 0x80000000 /* Transmit direction bit. Bit off
- * indicates receive direction */
+ * indicates receive direction */
#define ILOST 0x00008000 /* Interrupt Lost */
#define GROUPMSB 0x00004000 /* Group number MSB */
#define SACK_IMAGE 0x00100000 /* Used in IRQ for semaphore test */
#define INITIAL_STATUS 0x10000 /* IRQ status should be this after
- * reset */
+ * reset */
/* This must be defined on an entire channel group (Port) basis */
#define SUERM_THRESHOLD 0x1f
diff --git a/drivers/staging/cxt1e1/sbecrc.c b/drivers/staging/cxt1e1/sbecrc.c
index 3f3cd60ac36..87512a53f72 100644
--- a/drivers/staging/cxt1e1/sbecrc.c
+++ b/drivers/staging/cxt1e1/sbecrc.c
@@ -44,25 +44,23 @@ static u_int32_t CRCTable[CRC_TABLE_ENTRIES];
***************************************************************************/
static void
-genCrcTable (u_int32_t *CRCTable)
+genCrcTable(u_int32_t *CRCTable)
{
- int ii, jj;
- u_int32_t crc;
-
- for (ii = 0; ii < CRC_TABLE_ENTRIES; ii++)
- {
- crc = ii;
- for (jj = 8; jj > 0; jj--)
- {
- if (crc & 1)
- crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
- else
- crc >>= 1;
- }
- CRCTable[ii] = crc;
- }
-
- crcTableInit++;
+ int ii, jj;
+ u_int32_t crc;
+
+ for (ii = 0; ii < CRC_TABLE_ENTRIES; ii++) {
+ crc = ii;
+ for (jj = 8; jj > 0; jj--) {
+ if (crc & 1)
+ crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
+ else
+ crc >>= 1;
+ }
+ CRCTable[ii] = crc;
+ }
+
+ crcTableInit++;
}
@@ -85,52 +83,49 @@ genCrcTable (u_int32_t *CRCTable)
*/
void
-sbeCrc (u_int8_t *buffer, /* data buffer to crc */
- u_int32_t count, /* length of block in bytes */
- u_int32_t initialCrc, /* starting CRC */
- u_int32_t *result)
+sbeCrc(u_int8_t *buffer, /* data buffer to crc */
+ u_int32_t count, /* length of block in bytes */
+ u_int32_t initialCrc, /* starting CRC */
+ u_int32_t *result)
{
- u_int32_t *tbl = 0;
- u_int32_t temp1, temp2, crc;
-
- /*
- * if table not yet created, do so. Don't care about "extra" time
- * checking this every time sbeCrc() is called, since CRC calculations are
- * already time consuming
- */
- if (!crcTableInit)
- {
+ u_int32_t *tbl = 0;
+ u_int32_t temp1, temp2, crc;
+
+ /*
+ * if table not yet created, do so. Don't care about "extra" time
+ * checking this every time sbeCrc() is called, since CRC calculations
+ * are already time consuming
+ */
+ if (!crcTableInit) {
#ifdef STATIC_CRC_TABLE
- tbl = &CRCTable;
- genCrcTable (tbl);
+ tbl = &CRCTable;
+ genCrcTable(tbl);
#else
- tbl = (u_int32_t *) OS_kmalloc (CRC_TABLE_ENTRIES * sizeof (u_int32_t));
- if (tbl == 0)
- {
- *result = 0; /* dummy up return value due to malloc
- * failure */
- return;
- }
- genCrcTable (tbl);
+ tbl = (u_int32_t *) OS_kmalloc(CRC_TABLE_ENTRIES * sizeof(u_int32_t));
+ if (tbl == 0) {
+ *result = 0; /* dummy up return value due to malloc
+ * failure */
+ return;
+ }
+ genCrcTable(tbl);
#endif
- }
- /* inverting bits makes ZMODEM & PKZIP compatible */
- crc = initialCrc ^ 0xFFFFFFFFL;
+ }
+ /* inverting bits makes ZMODEM & PKZIP compatible */
+ crc = initialCrc ^ 0xFFFFFFFFL;
- while (count-- != 0)
- {
- temp1 = (crc >> 8) & 0x00FFFFFFL;
- temp2 = tbl[((int) crc ^ *buffer++) & 0xff];
- crc = temp1 ^ temp2;
- }
+ while (count-- != 0) {
+ temp1 = (crc >> 8) & 0x00FFFFFFL;
+ temp2 = tbl[((int) crc ^ *buffer++) & 0xff];
+ crc = temp1 ^ temp2;
+ }
- crc ^= 0xFFFFFFFFL;
+ crc ^= 0xFFFFFFFFL;
- *result = crc;
+ *result = crc;
#ifndef STATIC_CRC_TABLE
- crcTableInit = 0;
- OS_kfree (tbl);
+ crcTableInit = 0;
+ OS_kfree(tbl);
#endif
}
diff --git a/drivers/staging/dgrp/dgrp_common.h b/drivers/staging/dgrp/dgrp_common.h
index 05ff338471a..0583fe9c7b0 100644
--- a/drivers/staging/dgrp/dgrp_common.h
+++ b/drivers/staging/dgrp/dgrp_common.h
@@ -31,7 +31,6 @@
* All global storage allocation.
************************************************************************/
-extern int dgrp_rawreadok; /* Allow raw writing of input */
extern int dgrp_register_cudevices; /* enable legacy cu devices */
extern int dgrp_register_prdevices; /* enable transparent print devices */
extern int dgrp_poll_tick; /* Poll interval - in ms */
diff --git a/drivers/staging/dgrp/dgrp_dpa_ops.c b/drivers/staging/dgrp/dgrp_dpa_ops.c
index 49e670915e5..021cca498f2 100644
--- a/drivers/staging/dgrp/dgrp_dpa_ops.c
+++ b/drivers/staging/dgrp/dgrp_dpa_ops.c
@@ -387,7 +387,7 @@ static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd,
port = getchan.ch_port;
- if (port < 0 || port > nd->nd_chan_count)
+ if (port > nd->nd_chan_count)
return -EINVAL;
ch = nd->nd_chan + port;
diff --git a/drivers/staging/dgrp/dgrp_driver.c b/drivers/staging/dgrp/dgrp_driver.c
index 6e4a0ebc074..aa262588e9b 100644
--- a/drivers/staging/dgrp/dgrp_driver.c
+++ b/drivers/staging/dgrp/dgrp_driver.c
@@ -39,14 +39,10 @@ MODULE_VERSION(DIGI_VERSION);
struct list_head nd_struct_list;
struct dgrp_poll_data dgrp_poll_data;
-int dgrp_rawreadok = 1; /* Bypass flipbuf on input */
int dgrp_register_cudevices = 1;/* Turn on/off registering legacy cu devices */
int dgrp_register_prdevices = 1;/* Turn on/off registering transparent print */
int dgrp_poll_tick = 20; /* Poll interval - in ms */
-module_param_named(rawreadok, dgrp_rawreadok, int, 0644);
-MODULE_PARM_DESC(rawreadok, "Bypass flip buffers on input");
-
module_param_named(register_cudevices, dgrp_register_cudevices, int, 0644);
MODULE_PARM_DESC(register_cudevices, "Turn on/off registering legacy cu devices");
diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c
index ab839ea3b44..2d1bbfd5b67 100644
--- a/drivers/staging/dgrp/dgrp_net_ops.c
+++ b/drivers/staging/dgrp/dgrp_net_ops.c
@@ -151,20 +151,15 @@ static void dgrp_read_data_block(struct ch_struct *ch, u8 *flipbuf,
* Copys the rbuf to the flipbuf and sends to line discipline.
* Sends input buffer data to the line discipline.
*
- * There are several modes to consider here:
- * rawreadok, tty->real_raw, and IF_PARMRK
*/
static void dgrp_input(struct ch_struct *ch)
{
struct nd_struct *nd;
struct tty_struct *tty;
- int remain;
int data_len;
int len;
- int flip_len;
int tty_count;
ulong lock_flags;
- struct tty_ldisc *ld;
u8 *myflipbuf;
u8 *myflipflagbuf;
@@ -212,37 +207,11 @@ static void dgrp_input(struct ch_struct *ch)
spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
- /* Decide how much data we can send into the tty layer */
- if (dgrp_rawreadok && tty->real_raw)
- flip_len = MYFLIPLEN;
- else
- flip_len = TTY_FLIPBUF_SIZE;
-
/* data_len should be the number of chars that we read in */
data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK;
- remain = data_len;
/* len is the amount of data we are going to transfer here */
- len = min(data_len, flip_len);
-
- /* take into consideration length of ldisc */
- len = min(len, (N_TTY_BUF_SIZE - 1) - tty->read_cnt);
-
- ld = tty_ldisc_ref(tty);
-
- /*
- * If we were unable to get a reference to the ld,
- * don't flush our buffer, and act like the ld doesn't
- * have any space to put the data right now.
- */
- if (!ld) {
- len = 0;
- } else if (!ld->ops->receive_buf) {
- spin_lock_irqsave(&nd->nd_lock, lock_flags);
- ch->ch_rout = ch->ch_rin;
- spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
- len = 0;
- }
+ len = tty_buffer_request_room(tty, data_len);
/* Check DPA flow control */
if ((nd->nd_dpa_debug) &&
@@ -254,42 +223,22 @@ static void dgrp_input(struct ch_struct *ch)
dgrp_read_data_block(ch, myflipbuf, len);
- /*
- * In high performance mode, we don't have to update
- * flag_buf or any of the counts or pointers into flip buf.
- */
- if (!dgrp_rawreadok || !tty->real_raw) {
- if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty))
- parity_scan(ch, myflipbuf, myflipflagbuf, &len);
- else
- memset(myflipflagbuf, TTY_NORMAL, len);
- }
+ if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty))
+ parity_scan(ch, myflipbuf, myflipflagbuf, &len);
+ else
+ memset(myflipflagbuf, TTY_NORMAL, len);
if ((nd->nd_dpa_debug) &&
(nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty)))))
dgrp_dpa_data(nd, 1, myflipbuf, len);
- /*
- * If we're doing raw reads, jam it right into the
- * line disc bypassing the flip buffers.
- */
- if (dgrp_rawreadok && tty->real_raw)
- ld->ops->receive_buf(tty, myflipbuf, NULL, len);
- else {
- len = tty_buffer_request_room(tty, len);
- tty_insert_flip_string_flags(tty, myflipbuf,
- myflipflagbuf, len);
-
- /* Tell the tty layer its okay to "eat" the data now */
- tty_flip_buffer_push(tty);
- }
+ tty_insert_flip_string_flags(tty, myflipbuf,
+ myflipflagbuf, len);
+ tty_flip_buffer_push(tty);
ch->ch_rxcount += len;
}
- if (ld)
- tty_ldisc_deref(ld);
-
/*
* Wake up any sleepers (maybe dgrp close) that might be waiting
* for a channel flag state change.
@@ -1057,13 +1006,13 @@ static int dgrp_net_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);
-done:
down(&nd->nd_net_semaphore);
dgrp_monitor_message(nd, "Net Close");
up(&nd->nd_net_semaphore);
+done:
module_put(THIS_MODULE);
file->private_data = NULL;
return 0;
@@ -1671,6 +1620,9 @@ static int dgrp_send(struct nd_struct *nd, long tmax)
* do the job.
*/
+ /* FIXME: jiffies - ch->ch_waketime can never
+ be < 0. Someone needs to work out what is
+ actually intended here */
if (ch->ch_pun.un_open_count &&
(ch->ch_pun.un_flag &
(UN_EMPTY|UN_TIME|UN_LOW|UN_PWAIT)) != 0) {
@@ -2546,7 +2498,7 @@ data:
/*
* Fabricate and insert a data packet header to
- * preceed the remaining data when it comes in.
+ * preced the remaining data when it comes in.
*/
if (remain < plen) {
@@ -2715,7 +2667,7 @@ data:
}
/*
- * Handle delayed response arrival preceeding
+ * Handle delayed response arrival preceding
* the open response we are waiting for.
*/
@@ -3553,7 +3505,7 @@ void dgrp_poll_handler(unsigned long arg)
/*
* Decrement statistics. These are only for use with
* KME, so don't worry that the operations are done
- * unlocked, and so the results are occassionally wrong.
+ * unlocked, and so the results are occasionally wrong.
*/
nd->nd_read_count -= (nd->nd_read_count +
diff --git a/drivers/staging/dgrp/dgrp_specproc.c b/drivers/staging/dgrp/dgrp_specproc.c
index 24327c3bad8..c214078a89e 100644
--- a/drivers/staging/dgrp/dgrp_specproc.c
+++ b/drivers/staging/dgrp/dgrp_specproc.c
@@ -629,8 +629,6 @@ static int info_proc_show(struct seq_file *m, void *v)
{
seq_printf(m, "version: %s\n", DIGI_VERSION);
seq_puts(m, "register_with_sysfs: 1\n");
- seq_printf(m, "rawreadok: 0x%08x\t(%d)\n",
- dgrp_rawreadok, dgrp_rawreadok);
seq_printf(m, "pollrate: 0x%08x\t(%d)\n",
dgrp_poll_tick, dgrp_poll_tick);
@@ -754,6 +752,8 @@ static int dgrp_add_id(long id)
return 0;
+ /* FIXME this guy should free the tty driver stored in nd and destroy
+ * all channel ports */
error_out:
kfree(nd);
return ret;
diff --git a/drivers/staging/dgrp/dgrp_sysfs.c b/drivers/staging/dgrp/dgrp_sysfs.c
index e5a3c88d016..be179adfb7c 100644
--- a/drivers/staging/dgrp/dgrp_sysfs.c
+++ b/drivers/staging/dgrp/dgrp_sysfs.c
@@ -17,7 +17,6 @@
#include "dgrp_common.h"
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/string.h>
@@ -55,23 +54,6 @@ static DEVICE_ATTR(register_with_sysfs, 0400,
dgrp_class_register_with_sysfs_show, NULL);
-static ssize_t dgrp_class_rawreadok_show(struct device *c,
- struct device_attribute *attr,
- char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_rawreadok);
-}
-static ssize_t dgrp_class_rawreadok_store(struct device *c,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- sscanf(buf, "0x%x\n", &dgrp_rawreadok);
- return count;
-}
-static DEVICE_ATTR(rawreadok, 0600, dgrp_class_rawreadok_show,
- dgrp_class_rawreadok_store);
-
-
static ssize_t dgrp_class_pollrate_show(struct device *c,
struct device_attribute *attr,
char *buf)
@@ -91,7 +73,6 @@ static DEVICE_ATTR(pollrate, 0600, dgrp_class_pollrate_show,
static struct attribute *dgrp_sysfs_global_settings_entries[] = {
&dev_attr_pollrate.attr,
- &dev_attr_rawreadok.attr,
&dev_attr_register_with_sysfs.attr,
NULL
};
@@ -177,7 +158,7 @@ static ssize_t dgrp_node_description_show(struct device *c,
if (!nd)
return 0;
- if (nd->nd_state == NS_READY && nd->nd_ps_desc)
+ if (nd->nd_state == NS_READY)
return snprintf(buf, PAGE_SIZE, "%s\n", nd->nd_ps_desc);
return 0;
}
diff --git a/drivers/staging/dgrp/dgrp_tty.c b/drivers/staging/dgrp/dgrp_tty.c
index e125b03598d..51d3ed3dca2 100644
--- a/drivers/staging/dgrp/dgrp_tty.c
+++ b/drivers/staging/dgrp/dgrp_tty.c
@@ -432,7 +432,7 @@ static void drp_param(struct ch_struct *ch)
/*
* From the POSIX.1 spec (7.1.2.6): "If {_POSIX_VDISABLE}
* is defined for the terminal device file, and the value
- * of one of the changable special control characters (see
+ * of one of the changeable special control characters (see
* 7.1.1.9) is {_POSIX_VDISABLE}, that function shall be
* disabled, that is, no input data shall be recognized as
* the disabled special character."
@@ -2265,9 +2265,7 @@ static int get_modem_info(struct ch_struct *ch, unsigned int *value)
| ((mlast & DM_RI) ? TIOCM_RNG : 0)
| ((mlast & DM_DSR) ? TIOCM_DSR : 0)
| ((mlast & DM_CTS) ? TIOCM_CTS : 0);
- put_user(mlast, (unsigned int __user *) value);
-
- return 0;
+ return put_user(mlast, (unsigned int __user *) value);
}
/*
@@ -2285,7 +2283,8 @@ static int set_modem_info(struct ch_struct *ch, unsigned int command,
if (error == 0)
return -EFAULT;
- get_user(arg, (unsigned int __user *) value);
+ if (get_user(arg, (unsigned int __user *) value))
+ return -EFAULT;
mval |= ((arg & TIOCM_RTS) ? DM_RTS : 0)
| ((arg & TIOCM_DTR) ? DM_DTR : 0);
@@ -2615,21 +2614,6 @@ static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
*/
return 0;
- case TIOCGSOFTCAR:
- rc = access_ok(VERIFY_WRITE, (void __user *) arg,
- sizeof(long));
- if (rc == 0)
- return -EFAULT;
- put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) arg);
- return 0;
-
- case TIOCSSOFTCAR:
- get_user(arg, (unsigned long __user *) arg);
- tty->termios.c_cflag =
- ((tty->termios.c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
- return 0;
-
case TIOCMGET:
rc = access_ok(VERIFY_WRITE, (void __user *) arg,
sizeof(unsigned int));
@@ -2699,7 +2683,7 @@ static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
- looking at the tty_ioctl code, these command all call our
tty_set_termios at the driver's end, when a TCSETA* is sent,
it is expecting the tty to have a termio structure,
- NOT a termios stucture. These two structures differ in size
+ NOT a termios structure. These two structures differ in size
and the tty_ioctl code does a conversion before processing them both.
- we should treat the TCSETAW TCSETAF ioctls the same, and let
the tty_ioctl code do the conversion stuff.
@@ -2851,17 +2835,16 @@ static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
break;
case DIGI_GETCUSTOMBAUD:
- rc = access_ok(VERIFY_WRITE, (void __user *) arg, sizeof(int));
- if (rc == 0)
+ if (put_user(ch->ch_custom_speed, (unsigned int __user *) arg))
return -EFAULT;
- put_user(ch->ch_custom_speed, (unsigned int __user *) arg);
break;
case DIGI_SETCUSTOMBAUD:
{
int new_rate;
- get_user(new_rate, (unsigned int __user *) arg);
+ if (get_user(new_rate, (unsigned int __user *) arg))
+ return -EFAULT;
dgrp_set_custom_speed(ch, new_rate);
break;
@@ -2996,7 +2979,7 @@ static void dgrp_tty_start(struct tty_struct *tty)
}
/*
- * Stop the reciever
+ * Stop the receiver
*/
static void dgrp_tty_input_stop(struct tty_struct *tty)
{
@@ -3119,6 +3102,7 @@ static void dgrp_tty_hangup(struct tty_struct *tty)
void
dgrp_tty_uninit(struct nd_struct *nd)
{
+ unsigned int i;
char id[3];
ID_TO_CHAR(nd->nd_ID, id);
@@ -3152,6 +3136,8 @@ dgrp_tty_uninit(struct nd_struct *nd)
put_tty_driver(nd->nd_xprint_ttdriver);
nd->nd_ttdriver_flags &= ~XPRINT_TTDRV_REG;
}
+ for (i = 0; i < CHAN_MAX; i++)
+ tty_port_destroy(&nd->nd_chan[i].port);
}
@@ -3335,7 +3321,6 @@ dgrp_tty_init(struct nd_struct *nd)
init_waitqueue_head(&(ch->ch_pun.un_open_wait));
init_waitqueue_head(&(ch->ch_pun.un_close_wait));
tty_port_init(&ch->port);
- tty_port_init(&ch->port);
}
return 0;
}
diff --git a/drivers/staging/et131x/README b/drivers/staging/et131x/README
index 82657233c8b..38537d4c4e1 100644
--- a/drivers/staging/et131x/README
+++ b/drivers/staging/et131x/README
@@ -8,7 +8,7 @@ Note, the powermanagement options were removed from the vendor provided
driver as they did not build properly at the time.
TODO:
- - Use of kmem_cache seems a bit unusual
+ - some rx packets have CRC/code/frame errors
Please send patches to:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c
index 413da0d6b9f..84bbcd48e26 100644
--- a/drivers/staging/et131x/et131x.c
+++ b/drivers/staging/et131x/et131x.c
@@ -143,7 +143,6 @@ MODULE_DESCRIPTION("10/100/1000 Base-T Ethernet Driver for the ET1310 by Agere S
#define fMP_DEST_BROAD 0x00000002
/* MP_ADAPTER flags */
-#define fMP_ADAPTER_RECV_LOOKASIDE 0x00000004
#define fMP_ADAPTER_INTERRUPT_IN_USE 0x00000008
/* MP_SHARED flags */
@@ -176,22 +175,14 @@ MODULE_DESCRIPTION("10/100/1000 Base-T Ethernet Driver for the ET1310 by Agere S
#define PARM_DMA_CACHE_DEF 0
/* RX defines */
-#define USE_FBR0 1
-#define FBR_CHUNKS 32
-#define MAX_DESC_PER_RING_RX 1024
+#define FBR_CHUNKS 32
+#define MAX_DESC_PER_RING_RX 1024
/* number of RFDs - default and min */
-#ifdef USE_FBR0
#define RFD_LOW_WATER_MARK 40
#define NIC_DEFAULT_NUM_RFD 1024
#define NUM_FBRS 2
-#else
-#define RFD_LOW_WATER_MARK 20
-#define NIC_DEFAULT_NUM_RFD 256
-#define NUM_FBRS 1
-#endif
-#define NIC_MIN_NUM_RFD 64
#define NUM_PACKETS_HANDLED 256
#define ALCATEL_MULTICAST_PKT 0x01000000
@@ -291,29 +282,20 @@ struct rx_status_block {
*/
struct fbr_lookup {
void *virt[MAX_DESC_PER_RING_RX];
- void *buffer1[MAX_DESC_PER_RING_RX];
- void *buffer2[MAX_DESC_PER_RING_RX];
u32 bus_high[MAX_DESC_PER_RING_RX];
u32 bus_low[MAX_DESC_PER_RING_RX];
void *ring_virtaddr;
dma_addr_t ring_physaddr;
void *mem_virtaddrs[MAX_DESC_PER_RING_RX / FBR_CHUNKS];
dma_addr_t mem_physaddrs[MAX_DESC_PER_RING_RX / FBR_CHUNKS];
- u64 real_physaddr;
- u64 offset;
u32 local_full;
u32 num_entries;
- u32 buffsize;
+ dma_addr_t buffsize;
};
/*
* struct rx_ring is the sructure representing the adaptor's local
* reference(s) to the rings
- *
- ******************************************************************************
- * IMPORTANT NOTE :- fbr_lookup *fbr[NUM_FBRS] uses index 0 to refer to FBR1
- * and index 1 to refer to FRB0
- ******************************************************************************
*/
struct rx_ring {
struct fbr_lookup *fbr[NUM_FBRS];
@@ -332,9 +314,6 @@ struct rx_ring {
u32 num_rfd;
bool unfinished_receives;
-
- /* lookaside lists */
- struct kmem_cache *recv_lookaside;
};
/* TX defines */
@@ -866,28 +845,27 @@ static void et131x_rx_dma_enable(struct et131x_adapter *adapter)
/* Setup the receive dma configuration register for normal operation */
u32 csr = 0x2000; /* FBR1 enable */
- if (adapter->rx_ring.fbr[0]->buffsize == 4096)
+ if (adapter->rx_ring.fbr[1]->buffsize == 4096)
csr |= 0x0800;
- else if (adapter->rx_ring.fbr[0]->buffsize == 8192)
+ else if (adapter->rx_ring.fbr[1]->buffsize == 8192)
csr |= 0x1000;
- else if (adapter->rx_ring.fbr[0]->buffsize == 16384)
+ else if (adapter->rx_ring.fbr[1]->buffsize == 16384)
csr |= 0x1800;
-#ifdef USE_FBR0
+
csr |= 0x0400; /* FBR0 enable */
- if (adapter->rx_ring.fbr[1]->buffsize == 256)
+ if (adapter->rx_ring.fbr[0]->buffsize == 256)
csr |= 0x0100;
- else if (adapter->rx_ring.fbr[1]->buffsize == 512)
+ else if (adapter->rx_ring.fbr[0]->buffsize == 512)
csr |= 0x0200;
- else if (adapter->rx_ring.fbr[1]->buffsize == 1024)
+ else if (adapter->rx_ring.fbr[0]->buffsize == 1024)
csr |= 0x0300;
-#endif
writel(csr, &adapter->regs->rxdma.csr);
csr = readl(&adapter->regs->rxdma.csr);
- if ((csr & 0x00020000) != 0) {
+ if (csr & 0x00020000) {
udelay(5);
csr = readl(&adapter->regs->rxdma.csr);
- if ((csr & 0x00020000) != 0) {
+ if (csr & 0x00020000) {
dev_err(&adapter->pdev->dev,
"RX Dma failed to exit halt state. CSR 0x%08x\n",
csr);
@@ -1758,22 +1736,8 @@ static void et1310_phy_power_down(struct et131x_adapter *adapter, bool down)
*/
static void et131x_xcvr_init(struct et131x_adapter *adapter)
{
- u16 imr;
- u16 isr;
u16 lcr2;
- et131x_mii_read(adapter, PHY_INTERRUPT_STATUS, &isr);
- et131x_mii_read(adapter, PHY_INTERRUPT_MASK, &imr);
-
- /* Set the link status interrupt only. Bad behavior when link status
- * and auto neg are set, we run into a nested interrupt problem
- */
- imr |= (ET_PHY_INT_MASK_AUTONEGSTAT |
- ET_PHY_INT_MASK_LINKSTAT |
- ET_PHY_INT_MASK_ENABLE);
-
- et131x_mii_write(adapter, PHY_INTERRUPT_MASK, imr);
-
/* Set the LED behavior such that LED 1 indicates speed (off =
* 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates
* link and activity (on for link, blink off for activity).
@@ -1798,7 +1762,7 @@ static void et131x_xcvr_init(struct et131x_adapter *adapter)
}
/**
- * et131x_configure_global_regs - configure JAGCore global regs
+ * et131x_configure_global_regs - configure JAGCore global regs
* @adapter: pointer to our adapter structure
*
* Used to configure the global registers on the JAGCore
@@ -1856,29 +1820,22 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter)
u32 entry;
u32 psr_num_des;
unsigned long flags;
+ u8 id;
/* Halt RXDMA to perform the reconfigure. */
et131x_rx_dma_disable(adapter);
- /* Load the completion writeback physical address
- *
- * NOTE : dma_alloc_coherent(), used above to alloc DMA regions,
- * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
- * are ever returned, make sure the high part is retrieved here
- * before storing the adjusted address.
- */
- writel((u32) ((u64)rx_local->rx_status_bus >> 32),
- &rx_dma->dma_wb_base_hi);
- writel((u32) rx_local->rx_status_bus, &rx_dma->dma_wb_base_lo);
+ /* Load the completion writeback physical address */
+ writel(upper_32_bits(rx_local->rx_status_bus), &rx_dma->dma_wb_base_hi);
+ writel(lower_32_bits(rx_local->rx_status_bus), &rx_dma->dma_wb_base_lo);
memset(rx_local->rx_status_block, 0, sizeof(struct rx_status_block));
/* Set the address and parameters of the packet status ring into the
* 1310's registers
*/
- writel((u32) ((u64)rx_local->ps_ring_physaddr >> 32),
- &rx_dma->psr_base_hi);
- writel((u32) rx_local->ps_ring_physaddr, &rx_dma->psr_base_lo);
+ writel(upper_32_bits(rx_local->ps_ring_physaddr), &rx_dma->psr_base_hi);
+ writel(lower_32_bits(rx_local->ps_ring_physaddr), &rx_dma->psr_base_lo);
writel(rx_local->psr_num_entries - 1, &rx_dma->psr_num_des);
writel(0, &rx_dma->psr_full_offset);
@@ -1891,56 +1848,56 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter)
/* These local variables track the PSR in the adapter structure */
rx_local->local_psr_full = 0;
- /* Now's the best time to initialize FBR1 contents */
- fbr_entry = (struct fbr_desc *) rx_local->fbr[0]->ring_virtaddr;
- for (entry = 0; entry < rx_local->fbr[0]->num_entries; entry++) {
- fbr_entry->addr_hi = rx_local->fbr[0]->bus_high[entry];
- fbr_entry->addr_lo = rx_local->fbr[0]->bus_low[entry];
- fbr_entry->word2 = entry;
- fbr_entry++;
- }
-
- /* Set the address and parameters of Free buffer ring 1 (and 0 if
- * required) into the 1310's registers
- */
- writel((u32) (rx_local->fbr[0]->real_physaddr >> 32),
- &rx_dma->fbr1_base_hi);
- writel((u32) rx_local->fbr[0]->real_physaddr, &rx_dma->fbr1_base_lo);
- writel(rx_local->fbr[0]->num_entries - 1, &rx_dma->fbr1_num_des);
- writel(ET_DMA10_WRAP, &rx_dma->fbr1_full_offset);
-
- /* This variable tracks the free buffer ring 1 full position, so it
- * has to match the above.
- */
- rx_local->fbr[0]->local_full = ET_DMA10_WRAP;
- writel(
- ((rx_local->fbr[0]->num_entries * LO_MARK_PERCENT_FOR_RX) / 100) - 1,
- &rx_dma->fbr1_min_des);
-
-#ifdef USE_FBR0
- /* Now's the best time to initialize FBR0 contents */
- fbr_entry = (struct fbr_desc *) rx_local->fbr[1]->ring_virtaddr;
- for (entry = 0; entry < rx_local->fbr[1]->num_entries; entry++) {
- fbr_entry->addr_hi = rx_local->fbr[1]->bus_high[entry];
- fbr_entry->addr_lo = rx_local->fbr[1]->bus_low[entry];
- fbr_entry->word2 = entry;
- fbr_entry++;
- }
+ for (id = 0; id < NUM_FBRS; id++) {
+ u32 *num_des;
+ u32 *full_offset;
+ u32 *min_des;
+ u32 *base_hi;
+ u32 *base_lo;
+
+ if (id == 0) {
+ num_des = &rx_dma->fbr0_num_des;
+ full_offset = &rx_dma->fbr0_full_offset;
+ min_des = &rx_dma->fbr0_min_des;
+ base_hi = &rx_dma->fbr0_base_hi;
+ base_lo = &rx_dma->fbr0_base_lo;
+ } else {
+ num_des = &rx_dma->fbr1_num_des;
+ full_offset = &rx_dma->fbr1_full_offset;
+ min_des = &rx_dma->fbr1_min_des;
+ base_hi = &rx_dma->fbr1_base_hi;
+ base_lo = &rx_dma->fbr1_base_lo;
+ }
- writel((u32) (rx_local->fbr[1]->real_physaddr >> 32),
- &rx_dma->fbr0_base_hi);
- writel((u32) rx_local->fbr[1]->real_physaddr, &rx_dma->fbr0_base_lo);
- writel(rx_local->fbr[1]->num_entries - 1, &rx_dma->fbr0_num_des);
- writel(ET_DMA10_WRAP, &rx_dma->fbr0_full_offset);
+ /* Now's the best time to initialize FBR contents */
+ fbr_entry =
+ (struct fbr_desc *) rx_local->fbr[id]->ring_virtaddr;
+ for (entry = 0;
+ entry < rx_local->fbr[id]->num_entries; entry++) {
+ fbr_entry->addr_hi = rx_local->fbr[id]->bus_high[entry];
+ fbr_entry->addr_lo = rx_local->fbr[id]->bus_low[entry];
+ fbr_entry->word2 = entry;
+ fbr_entry++;
+ }
- /* This variable tracks the free buffer ring 0 full position, so it
- * has to match the above.
- */
- rx_local->fbr[1]->local_full = ET_DMA10_WRAP;
- writel(
- ((rx_local->fbr[1]->num_entries * LO_MARK_PERCENT_FOR_RX) / 100) - 1,
- &rx_dma->fbr0_min_des);
-#endif
+ /* Set the address and parameters of Free buffer ring 1 and 0
+ * into the 1310's registers
+ */
+ writel(upper_32_bits(rx_local->fbr[id]->ring_physaddr),
+ base_hi);
+ writel(lower_32_bits(rx_local->fbr[id]->ring_physaddr),
+ base_lo);
+ writel(rx_local->fbr[id]->num_entries - 1, num_des);
+ writel(ET_DMA10_WRAP, full_offset);
+
+ /* This variable tracks the free buffer ring 1 full position,
+ * so it has to match the above.
+ */
+ rx_local->fbr[id]->local_full = ET_DMA10_WRAP;
+ writel(((rx_local->fbr[id]->num_entries *
+ LO_MARK_PERCENT_FOR_RX) / 100) - 1,
+ min_des);
+ }
/* Program the number of packets we will receive before generating an
* interrupt.
@@ -1971,18 +1928,19 @@ static void et131x_config_tx_dma_regs(struct et131x_adapter *adapter)
struct txdma_regs __iomem *txdma = &adapter->regs->txdma;
/* Load the hardware with the start of the transmit descriptor ring. */
- writel((u32) ((u64)adapter->tx_ring.tx_desc_ring_pa >> 32),
+ writel(upper_32_bits(adapter->tx_ring.tx_desc_ring_pa),
&txdma->pr_base_hi);
- writel((u32) adapter->tx_ring.tx_desc_ring_pa,
+ writel(lower_32_bits(adapter->tx_ring.tx_desc_ring_pa),
&txdma->pr_base_lo);
/* Initialise the transmit DMA engine */
writel(NUM_DESC_PER_RING_TX - 1, &txdma->pr_num_des);
/* Load the completion writeback physical address */
- writel((u32)((u64)adapter->tx_ring.tx_status_pa >> 32),
- &txdma->dma_wb_base_hi);
- writel((u32)adapter->tx_ring.tx_status_pa, &txdma->dma_wb_base_lo);
+ writel(upper_32_bits(adapter->tx_ring.tx_status_pa),
+ &txdma->dma_wb_base_hi);
+ writel(lower_32_bits(adapter->tx_ring.tx_status_pa),
+ &txdma->dma_wb_base_lo);
*adapter->tx_ring.tx_status = 0;
@@ -2267,31 +2225,6 @@ static inline u32 bump_free_buff_ring(u32 *free_buff_ring, u32 limit)
}
/**
- * et131x_align_allocated_memory - Align allocated memory on a given boundary
- * @adapter: pointer to our adapter structure
- * @phys_addr: pointer to Physical address
- * @offset: pointer to the offset variable
- * @mask: correct mask
- */
-static void et131x_align_allocated_memory(struct et131x_adapter *adapter,
- u64 *phys_addr, u64 *offset,
- u64 mask)
-{
- u64 new_addr = *phys_addr & ~mask;
-
- *offset = 0;
-
- if (new_addr != *phys_addr) {
- /* Move to next aligned block */
- new_addr += mask + 1;
- /* Return offset for adjusting virt addr */
- *offset = new_addr - *phys_addr;
- /* Return new physical address */
- *phys_addr = new_addr;
- }
-}
-
-/**
* et131x_rx_dma_memory_alloc
* @adapter: pointer to our private adapter structure
*
@@ -2302,19 +2235,19 @@ static void et131x_align_allocated_memory(struct et131x_adapter *adapter,
*/
static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
{
+ u8 id;
u32 i, j;
u32 bufsize;
- u32 pktstat_ringsize, fbr_chunksize;
+ u32 pktstat_ringsize;
+ u32 fbr_chunksize;
struct rx_ring *rx_ring;
/* Setup some convenience pointers */
rx_ring = &adapter->rx_ring;
/* Alloc memory for the lookup table */
-#ifdef USE_FBR0
- rx_ring->fbr[1] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL);
-#endif
rx_ring->fbr[0] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL);
+ rx_ring->fbr[1] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL);
/* The first thing we will do is configure the sizes of the buffer
* rings. These will change based on jumbo packet support. Larger
@@ -2335,211 +2268,85 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
*/
if (adapter->registry_jumbo_packet < 2048) {
-#ifdef USE_FBR0
- rx_ring->fbr[1]->buffsize = 256;
- rx_ring->fbr[1]->num_entries = 512;
-#endif
- rx_ring->fbr[0]->buffsize = 2048;
+ rx_ring->fbr[0]->buffsize = 256;
rx_ring->fbr[0]->num_entries = 512;
+ rx_ring->fbr[1]->buffsize = 2048;
+ rx_ring->fbr[1]->num_entries = 512;
} else if (adapter->registry_jumbo_packet < 4096) {
-#ifdef USE_FBR0
- rx_ring->fbr[1]->buffsize = 512;
- rx_ring->fbr[1]->num_entries = 1024;
-#endif
- rx_ring->fbr[0]->buffsize = 4096;
- rx_ring->fbr[0]->num_entries = 512;
+ rx_ring->fbr[0]->buffsize = 512;
+ rx_ring->fbr[0]->num_entries = 1024;
+ rx_ring->fbr[1]->buffsize = 4096;
+ rx_ring->fbr[1]->num_entries = 512;
} else {
-#ifdef USE_FBR0
- rx_ring->fbr[1]->buffsize = 1024;
- rx_ring->fbr[1]->num_entries = 768;
-#endif
- rx_ring->fbr[0]->buffsize = 16384;
- rx_ring->fbr[0]->num_entries = 128;
+ rx_ring->fbr[0]->buffsize = 1024;
+ rx_ring->fbr[0]->num_entries = 768;
+ rx_ring->fbr[1]->buffsize = 16384;
+ rx_ring->fbr[1]->num_entries = 128;
}
-#ifdef USE_FBR0
adapter->rx_ring.psr_num_entries =
- adapter->rx_ring.fbr[1]->num_entries +
- adapter->rx_ring.fbr[0]->num_entries;
-#else
- adapter->rx_ring.psr_num_entries = adapter->rx_ring.fbr[0]->num_entries;
-#endif
+ adapter->rx_ring.fbr[0]->num_entries +
+ adapter->rx_ring.fbr[1]->num_entries;
- /* Allocate an area of memory for Free Buffer Ring 1 */
- bufsize = (sizeof(struct fbr_desc) * rx_ring->fbr[0]->num_entries) +
- 0xfff;
- rx_ring->fbr[0]->ring_virtaddr = dma_alloc_coherent(&adapter->pdev->dev,
+ for (id = 0; id < NUM_FBRS; id++) {
+ /* Allocate an area of memory for Free Buffer Ring */
+ bufsize =
+ (sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries);
+ rx_ring->fbr[id]->ring_virtaddr =
+ dma_alloc_coherent(&adapter->pdev->dev,
bufsize,
- &rx_ring->fbr[0]->ring_physaddr,
+ &rx_ring->fbr[id]->ring_physaddr,
GFP_KERNEL);
- if (!rx_ring->fbr[0]->ring_virtaddr) {
- dev_err(&adapter->pdev->dev,
- "Cannot alloc memory for Free Buffer Ring 1\n");
- return -ENOMEM;
- }
-
- /* Save physical address
- *
- * NOTE: dma_alloc_coherent(), used above to alloc DMA regions,
- * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
- * are ever returned, make sure the high part is retrieved here
- * before storing the adjusted address.
- */
- rx_ring->fbr[0]->real_physaddr = rx_ring->fbr[0]->ring_physaddr;
-
- /* Align Free Buffer Ring 1 on a 4K boundary */
- et131x_align_allocated_memory(adapter,
- &rx_ring->fbr[0]->real_physaddr,
- &rx_ring->fbr[0]->offset, 0x0FFF);
-
- rx_ring->fbr[0]->ring_virtaddr =
- (void *)((u8 *) rx_ring->fbr[0]->ring_virtaddr +
- rx_ring->fbr[0]->offset);
-
-#ifdef USE_FBR0
- /* Allocate an area of memory for Free Buffer Ring 0 */
- bufsize = (sizeof(struct fbr_desc) * rx_ring->fbr[1]->num_entries) +
- 0xfff;
- rx_ring->fbr[1]->ring_virtaddr = dma_alloc_coherent(&adapter->pdev->dev,
- bufsize,
- &rx_ring->fbr[1]->ring_physaddr,
- GFP_KERNEL);
- if (!rx_ring->fbr[1]->ring_virtaddr) {
- dev_err(&adapter->pdev->dev,
- "Cannot alloc memory for Free Buffer Ring 0\n");
- return -ENOMEM;
- }
-
- /* Save physical address
- *
- * NOTE: dma_alloc_coherent(), used above to alloc DMA regions,
- * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
- * are ever returned, make sure the high part is retrieved here before
- * storing the adjusted address.
- */
- rx_ring->fbr[1]->real_physaddr = rx_ring->fbr[1]->ring_physaddr;
-
- /* Align Free Buffer Ring 0 on a 4K boundary */
- et131x_align_allocated_memory(adapter,
- &rx_ring->fbr[1]->real_physaddr,
- &rx_ring->fbr[1]->offset, 0x0FFF);
-
- rx_ring->fbr[1]->ring_virtaddr =
- (void *)((u8 *) rx_ring->fbr[1]->ring_virtaddr +
- rx_ring->fbr[1]->offset);
-#endif
- for (i = 0; i < (rx_ring->fbr[0]->num_entries / FBR_CHUNKS); i++) {
- u64 fbr1_tmp_physaddr;
- u64 fbr1_offset;
- u32 fbr1_align;
-
- /* This code allocates an area of memory big enough for N
- * free buffers + (buffer_size - 1) so that the buffers can
- * be aligned on 4k boundaries. If each buffer were aligned
- * to a buffer_size boundary, the effect would be to double
- * the size of FBR0. By allocating N buffers at once, we
- * reduce this overhead.
- */
- if (rx_ring->fbr[0]->buffsize > 4096)
- fbr1_align = 4096;
- else
- fbr1_align = rx_ring->fbr[0]->buffsize;
-
- fbr_chunksize =
- (FBR_CHUNKS * rx_ring->fbr[0]->buffsize) + fbr1_align - 1;
- rx_ring->fbr[0]->mem_virtaddrs[i] =
- dma_alloc_coherent(&adapter->pdev->dev, fbr_chunksize,
- &rx_ring->fbr[0]->mem_physaddrs[i],
- GFP_KERNEL);
-
- if (!rx_ring->fbr[0]->mem_virtaddrs[i]) {
+ if (!rx_ring->fbr[id]->ring_virtaddr) {
dev_err(&adapter->pdev->dev,
- "Could not alloc memory\n");
+ "Cannot alloc memory for Free Buffer Ring %d\n", id);
return -ENOMEM;
}
-
- /* See NOTE in "Save Physical Address" comment above */
- fbr1_tmp_physaddr = rx_ring->fbr[0]->mem_physaddrs[i];
-
- et131x_align_allocated_memory(adapter,
- &fbr1_tmp_physaddr,
- &fbr1_offset, (fbr1_align - 1));
-
- for (j = 0; j < FBR_CHUNKS; j++) {
- u32 index = (i * FBR_CHUNKS) + j;
-
- /* Save the Virtual address of this index for quick
- * access later
- */
- rx_ring->fbr[0]->virt[index] =
- (u8 *) rx_ring->fbr[0]->mem_virtaddrs[i] +
- (j * rx_ring->fbr[0]->buffsize) + fbr1_offset;
-
- /* now store the physical address in the descriptor
- * so the device can access it
- */
- rx_ring->fbr[0]->bus_high[index] =
- (u32) (fbr1_tmp_physaddr >> 32);
- rx_ring->fbr[0]->bus_low[index] =
- (u32) fbr1_tmp_physaddr;
-
- fbr1_tmp_physaddr += rx_ring->fbr[0]->buffsize;
-
- rx_ring->fbr[0]->buffer1[index] =
- rx_ring->fbr[0]->virt[index];
- rx_ring->fbr[0]->buffer2[index] =
- rx_ring->fbr[0]->virt[index] - 4;
- }
}
-#ifdef USE_FBR0
- /* Same for FBR0 (if in use) */
- for (i = 0; i < (rx_ring->fbr[1]->num_entries / FBR_CHUNKS); i++) {
- u64 fbr0_tmp_physaddr;
- u64 fbr0_offset;
+ for (id = 0; id < NUM_FBRS; id++) {
+ fbr_chunksize = (FBR_CHUNKS * rx_ring->fbr[id]->buffsize);
- fbr_chunksize =
- ((FBR_CHUNKS + 1) * rx_ring->fbr[1]->buffsize) - 1;
- rx_ring->fbr[1]->mem_virtaddrs[i] =
- dma_alloc_coherent(&adapter->pdev->dev, fbr_chunksize,
- &rx_ring->fbr[1]->mem_physaddrs[i],
- GFP_KERNEL);
+ for (i = 0;
+ i < (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); i++) {
+ dma_addr_t fbr_tmp_physaddr;
- if (!rx_ring->fbr[1]->mem_virtaddrs[i]) {
- dev_err(&adapter->pdev->dev,
- "Could not alloc memory\n");
- return -ENOMEM;
- }
-
- /* See NOTE in "Save Physical Address" comment above */
- fbr0_tmp_physaddr = rx_ring->fbr[1]->mem_physaddrs[i];
+ rx_ring->fbr[id]->mem_virtaddrs[i] = dma_alloc_coherent(
+ &adapter->pdev->dev, fbr_chunksize,
+ &rx_ring->fbr[id]->mem_physaddrs[i],
+ GFP_KERNEL);
- et131x_align_allocated_memory(adapter,
- &fbr0_tmp_physaddr,
- &fbr0_offset,
- rx_ring->fbr[1]->buffsize - 1);
+ if (!rx_ring->fbr[id]->mem_virtaddrs[i]) {
+ dev_err(&adapter->pdev->dev,
+ "Could not alloc memory\n");
+ return -ENOMEM;
+ }
- for (j = 0; j < FBR_CHUNKS; j++) {
- u32 index = (i * FBR_CHUNKS) + j;
+ /* See NOTE in "Save Physical Address" comment above */
+ fbr_tmp_physaddr = rx_ring->fbr[id]->mem_physaddrs[i];
- rx_ring->fbr[1]->virt[index] =
- (u8 *) rx_ring->fbr[1]->mem_virtaddrs[i] +
- (j * rx_ring->fbr[1]->buffsize) + fbr0_offset;
+ for (j = 0; j < FBR_CHUNKS; j++) {
+ u32 index = (i * FBR_CHUNKS) + j;
- rx_ring->fbr[1]->bus_high[index] =
- (u32) (fbr0_tmp_physaddr >> 32);
- rx_ring->fbr[1]->bus_low[index] =
- (u32) fbr0_tmp_physaddr;
+ /* Save the Virtual address of this index for
+ * quick access later
+ */
+ rx_ring->fbr[id]->virt[index] =
+ (u8 *) rx_ring->fbr[id]->mem_virtaddrs[i] +
+ (j * rx_ring->fbr[id]->buffsize);
- fbr0_tmp_physaddr += rx_ring->fbr[1]->buffsize;
+ /* now store the physical address in the
+ * descriptor so the device can access it
+ */
+ rx_ring->fbr[id]->bus_high[index] =
+ upper_32_bits(fbr_tmp_physaddr);
+ rx_ring->fbr[id]->bus_low[index] =
+ lower_32_bits(fbr_tmp_physaddr);
- rx_ring->fbr[1]->buffer1[index] =
- rx_ring->fbr[1]->virt[index];
- rx_ring->fbr[1]->buffer2[index] =
- rx_ring->fbr[1]->virt[index] - 4;
+ fbr_tmp_physaddr += rx_ring->fbr[id]->buffsize;
+ }
}
}
-#endif
/* Allocate an area of memory for FIFO of Packet Status ring entries */
pktstat_ringsize =
@@ -2578,21 +2385,6 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
rx_ring->num_rfd = NIC_DEFAULT_NUM_RFD;
pr_info("PRS %llx\n", (unsigned long long)rx_ring->rx_status_bus);
- /* Recv
- * kmem_cache_create initializes a lookaside list. After successful
- * creation, nonpaged fixed-size blocks can be allocated from and
- * freed to the lookaside list.
- * RFDs will be allocated from this pool.
- */
- rx_ring->recv_lookaside = kmem_cache_create(adapter->netdev->name,
- sizeof(struct rfd),
- 0,
- SLAB_CACHE_DMA |
- SLAB_HWCACHE_ALIGN,
- NULL);
-
- adapter->flags |= fMP_ADAPTER_RECV_LOOKASIDE;
-
/* The RFDs are going to be put on lists later on, so initialize the
* lists now.
*/
@@ -2606,6 +2398,7 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
*/
static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
{
+ u8 id;
u32 index;
u32 bufsize;
u32 pktstat_ringsize;
@@ -2624,92 +2417,45 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
list_del(&rfd->list_node);
rfd->skb = NULL;
- kmem_cache_free(adapter->rx_ring.recv_lookaside, rfd);
+ kfree(rfd);
}
- /* Free Free Buffer Ring 1 */
- if (rx_ring->fbr[0]->ring_virtaddr) {
- /* First the packet memory */
- for (index = 0; index <
- (rx_ring->fbr[0]->num_entries / FBR_CHUNKS); index++) {
- if (rx_ring->fbr[0]->mem_virtaddrs[index]) {
- u32 fbr1_align;
-
- if (rx_ring->fbr[0]->buffsize > 4096)
- fbr1_align = 4096;
- else
- fbr1_align = rx_ring->fbr[0]->buffsize;
-
- bufsize =
- (rx_ring->fbr[0]->buffsize * FBR_CHUNKS) +
- fbr1_align - 1;
-
- dma_free_coherent(&adapter->pdev->dev,
- bufsize,
- rx_ring->fbr[0]->mem_virtaddrs[index],
- rx_ring->fbr[0]->mem_physaddrs[index]);
-
- rx_ring->fbr[0]->mem_virtaddrs[index] = NULL;
- }
- }
-
- /* Now the FIFO itself */
- rx_ring->fbr[0]->ring_virtaddr = (void *)((u8 *)
- rx_ring->fbr[0]->ring_virtaddr - rx_ring->fbr[0]->offset);
-
- bufsize =
- (sizeof(struct fbr_desc) * rx_ring->fbr[0]->num_entries) +
- 0xfff;
-
- dma_free_coherent(&adapter->pdev->dev, bufsize,
- rx_ring->fbr[0]->ring_virtaddr,
- rx_ring->fbr[0]->ring_physaddr);
-
- rx_ring->fbr[0]->ring_virtaddr = NULL;
- }
+ /* Free Free Buffer Rings */
+ for (id = 0; id < NUM_FBRS; id++) {
+ if (!rx_ring->fbr[id]->ring_virtaddr)
+ continue;
-#ifdef USE_FBR0
- /* Now the same for Free Buffer Ring 0 */
- if (rx_ring->fbr[1]->ring_virtaddr) {
/* First the packet memory */
- for (index = 0; index <
- (rx_ring->fbr[1]->num_entries / FBR_CHUNKS); index++) {
- if (rx_ring->fbr[1]->mem_virtaddrs[index]) {
+ for (index = 0;
+ index < (rx_ring->fbr[id]->num_entries / FBR_CHUNKS);
+ index++) {
+ if (rx_ring->fbr[id]->mem_virtaddrs[index]) {
bufsize =
- (rx_ring->fbr[1]->buffsize *
- (FBR_CHUNKS + 1)) - 1;
+ rx_ring->fbr[id]->buffsize * FBR_CHUNKS;
dma_free_coherent(&adapter->pdev->dev,
bufsize,
- rx_ring->fbr[1]->mem_virtaddrs[index],
- rx_ring->fbr[1]->mem_physaddrs[index]);
+ rx_ring->fbr[id]->mem_virtaddrs[index],
+ rx_ring->fbr[id]->mem_physaddrs[index]);
- rx_ring->fbr[1]->mem_virtaddrs[index] = NULL;
+ rx_ring->fbr[id]->mem_virtaddrs[index] = NULL;
}
}
- /* Now the FIFO itself */
- rx_ring->fbr[1]->ring_virtaddr = (void *)((u8 *)
- rx_ring->fbr[1]->ring_virtaddr - rx_ring->fbr[1]->offset);
-
bufsize =
- (sizeof(struct fbr_desc) * rx_ring->fbr[1]->num_entries) +
- 0xfff;
+ sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries;
- dma_free_coherent(&adapter->pdev->dev,
- bufsize,
- rx_ring->fbr[1]->ring_virtaddr,
- rx_ring->fbr[1]->ring_physaddr);
+ dma_free_coherent(&adapter->pdev->dev, bufsize,
+ rx_ring->fbr[id]->ring_virtaddr,
+ rx_ring->fbr[id]->ring_physaddr);
- rx_ring->fbr[1]->ring_virtaddr = NULL;
+ rx_ring->fbr[id]->ring_virtaddr = NULL;
}
-#endif
/* Free Packet Status Ring */
if (rx_ring->ps_ring_virtaddr) {
- pktstat_ringsize =
- sizeof(struct pkt_stat_desc) *
- adapter->rx_ring.psr_num_entries;
+ pktstat_ringsize = sizeof(struct pkt_stat_desc) *
+ adapter->rx_ring.psr_num_entries;
dma_free_coherent(&adapter->pdev->dev, pktstat_ringsize,
rx_ring->ps_ring_virtaddr,
@@ -2726,18 +2472,9 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
rx_ring->rx_status_block = NULL;
}
- /* Destroy the lookaside (RFD) pool */
- if (adapter->flags & fMP_ADAPTER_RECV_LOOKASIDE) {
- kmem_cache_destroy(rx_ring->recv_lookaside);
- adapter->flags &= ~fMP_ADAPTER_RECV_LOOKASIDE;
- }
-
/* Free the FBR Lookup Table */
-#ifdef USE_FBR0
- kfree(rx_ring->fbr[1]);
-#endif
-
kfree(rx_ring->fbr[0]);
+ kfree(rx_ring->fbr[1]);
/* Reset Counters */
rx_ring->num_ready_recv = 0;
@@ -2751,8 +2488,7 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
*/
static int et131x_init_recv(struct et131x_adapter *adapter)
{
- int status = -ENOMEM;
- struct rfd *rfd = NULL;
+ struct rfd *rfd;
u32 rfdct;
u32 numrfd = 0;
struct rx_ring *rx_ring;
@@ -2762,14 +2498,11 @@ static int et131x_init_recv(struct et131x_adapter *adapter)
/* Setup each RFD */
for (rfdct = 0; rfdct < rx_ring->num_rfd; rfdct++) {
- rfd = kmem_cache_alloc(rx_ring->recv_lookaside,
- GFP_ATOMIC | GFP_DMA);
+ rfd = kzalloc(sizeof(struct rfd), GFP_ATOMIC | GFP_DMA);
if (!rfd) {
- dev_err(&adapter->pdev->dev,
- "Couldn't alloc RFD out of kmem_cache\n");
- status = -ENOMEM;
- continue;
+ dev_err(&adapter->pdev->dev, "Couldn't alloc RFD\n");
+ return -ENOMEM;
}
rfd->skb = NULL;
@@ -2782,17 +2515,7 @@ static int et131x_init_recv(struct et131x_adapter *adapter)
numrfd++;
}
- if (numrfd > NIC_MIN_NUM_RFD)
- status = 0;
-
- rx_ring->num_rfd = numrfd;
-
- if (status != 0) {
- kmem_cache_free(rx_ring->recv_lookaside, rfd);
- dev_err(&adapter->pdev->dev,
- "Allocation problems in et131x_init_recv\n");
- }
- return status;
+ return 0;
}
/**
@@ -2831,51 +2554,34 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd)
/* We don't use any of the OOB data besides status. Otherwise, we
* need to clean up OOB data
*/
- if (
-#ifdef USE_FBR0
- (ring_index == 0 && buff_index < rx_local->fbr[1]->num_entries) ||
-#endif
- (ring_index == 1 && buff_index < rx_local->fbr[0]->num_entries)) {
+ if (buff_index < rx_local->fbr[ring_index]->num_entries) {
+ u32 *offset;
+ struct fbr_desc *next;
+
spin_lock_irqsave(&adapter->fbr_lock, flags);
- if (ring_index == 1) {
- struct fbr_desc *next = (struct fbr_desc *)
- (rx_local->fbr[0]->ring_virtaddr) +
- INDEX10(rx_local->fbr[0]->local_full);
+ if (ring_index == 0)
+ offset = &rx_dma->fbr0_full_offset;
+ else
+ offset = &rx_dma->fbr1_full_offset;
- /* Handle the Free Buffer Ring advancement here. Write
- * the PA / Buffer Index for the returned buffer into
- * the oldest (next to be freed)FBR entry
- */
- next->addr_hi = rx_local->fbr[0]->bus_high[buff_index];
- next->addr_lo = rx_local->fbr[0]->bus_low[buff_index];
- next->word2 = buff_index;
-
- writel(bump_free_buff_ring(
- &rx_local->fbr[0]->local_full,
- rx_local->fbr[0]->num_entries - 1),
- &rx_dma->fbr1_full_offset);
- }
-#ifdef USE_FBR0
- else {
- struct fbr_desc *next = (struct fbr_desc *)
- rx_local->fbr[1]->ring_virtaddr +
- INDEX10(rx_local->fbr[1]->local_full);
+ next = (struct fbr_desc *)
+ (rx_local->fbr[ring_index]->ring_virtaddr) +
+ INDEX10(rx_local->fbr[ring_index]->local_full);
+
+ /* Handle the Free Buffer Ring advancement here. Write
+ * the PA / Buffer Index for the returned buffer into
+ * the oldest (next to be freed)FBR entry
+ */
+ next->addr_hi = rx_local->fbr[ring_index]->bus_high[buff_index];
+ next->addr_lo = rx_local->fbr[ring_index]->bus_low[buff_index];
+ next->word2 = buff_index;
+
+ writel(bump_free_buff_ring(
+ &rx_local->fbr[ring_index]->local_full,
+ rx_local->fbr[ring_index]->num_entries - 1),
+ offset);
- /* Handle the Free Buffer Ring advancement here. Write
- * the PA / Buffer Index for the returned buffer into
- * the oldest (next to be freed) FBR entry
- */
- next->addr_hi = rx_local->fbr[1]->bus_high[buff_index];
- next->addr_lo = rx_local->fbr[1]->bus_low[buff_index];
- next->word2 = buff_index;
-
- writel(bump_free_buff_ring(
- &rx_local->fbr[1]->local_full,
- rx_local->fbr[1]->num_entries - 1),
- &rx_dma->fbr0_full_offset);
- }
-#endif
spin_unlock_irqrestore(&adapter->fbr_lock, flags);
} else {
dev_err(&adapter->pdev->dev,
@@ -2919,6 +2625,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter)
u32 len;
u32 word0;
u32 word1;
+ struct sk_buff *skb;
/* RX Status block is written by the DMA engine prior to every
* interrupt. It contains the next to be used entry in the Packet
@@ -2929,16 +2636,14 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter)
/* Check the PSR and wrap bits do not match */
if ((word1 & 0x1FFF) == (rx_local->local_psr_full & 0x1FFF))
- /* Looks like this ring is not updated yet */
- return NULL;
+ return NULL; /* Looks like this ring is not updated yet */
/* The packet status ring indicates that data is available. */
psr = (struct pkt_stat_desc *) (rx_local->ps_ring_virtaddr) +
(rx_local->local_psr_full & 0xFFF);
- /* Grab any information that is required once the PSR is
- * advanced, since we can no longer rely on the memory being
- * accurate
+ /* Grab any information that is required once the PSR is advanced,
+ * since we can no longer rely on the memory being accurate
*/
len = psr->word1 & 0xFFFF;
ring_index = (psr->word1 >> 26) & 0x03;
@@ -2955,40 +2660,24 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter)
rx_local->local_psr_full ^= 0x1000;
}
- writel(rx_local->local_psr_full,
- &adapter->regs->rxdma.psr_full_offset);
-
-#ifndef USE_FBR0
- if (ring_index != 1)
- return NULL;
-#endif
+ writel(rx_local->local_psr_full, &adapter->regs->rxdma.psr_full_offset);
-#ifdef USE_FBR0
if (ring_index > 1 ||
- (ring_index == 0 &&
- buff_index > rx_local->fbr[1]->num_entries - 1) ||
- (ring_index == 1 &&
- buff_index > rx_local->fbr[0]->num_entries - 1)) {
-#else
- if (ring_index != 1 || buff_index > rx_local->fbr[0]->num_entries - 1) {
-#endif
+ buff_index > rx_local->fbr[ring_index]->num_entries - 1) {
/* Illegal buffer or ring index cannot be used by S/W*/
dev_err(&adapter->pdev->dev,
- "NICRxPkts PSR Entry %d indicates "
- "length of %d and/or bad bi(%d)\n",
- rx_local->local_psr_full & 0xFFF,
- len, buff_index);
+ "NICRxPkts PSR Entry %d indicates length of %d and/or bad bi(%d)\n",
+ rx_local->local_psr_full & 0xFFF, len, buff_index);
return NULL;
}
/* Get and fill the RFD. */
spin_lock_irqsave(&adapter->rcv_lock, flags);
- rfd = NULL;
element = rx_local->recv_list.next;
rfd = (struct rfd *) list_entry(element, struct rfd, list_node);
- if (rfd == NULL) {
+ if (!rfd) {
spin_unlock_irqrestore(&adapter->rcv_lock, flags);
return NULL;
}
@@ -3001,119 +2690,95 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter)
rfd->bufferindex = buff_index;
rfd->ringindex = ring_index;
- /* In V1 silicon, there is a bug which screws up filtering of
- * runt packets. Therefore runt packet filtering is disabled
- * in the MAC and the packets are dropped here. They are
- * also counted here.
+ /* In V1 silicon, there is a bug which screws up filtering of runt
+ * packets. Therefore runt packet filtering is disabled in the MAC and
+ * the packets are dropped here. They are also counted here.
*/
if (len < (NIC_MIN_PACKET_SIZE + 4)) {
adapter->stats.rx_other_errs++;
len = 0;
}
- if (len) {
- /* Determine if this is a multicast packet coming in */
- if ((word0 & ALCATEL_MULTICAST_PKT) &&
- !(word0 & ALCATEL_BROADCAST_PKT)) {
- /* Promiscuous mode and Multicast mode are
- * not mutually exclusive as was first
- * thought. I guess Promiscuous is just
- * considered a super-set of the other
- * filters. Generally filter is 0x2b when in
- * promiscuous mode.
- */
- if ((adapter->packet_filter &
- ET131X_PACKET_TYPE_MULTICAST)
- && !(adapter->packet_filter &
- ET131X_PACKET_TYPE_PROMISCUOUS)
- && !(adapter->packet_filter &
+ if (len == 0) {
+ rfd->len = 0;
+ goto out;
+ }
+
+ /* Determine if this is a multicast packet coming in */
+ if ((word0 & ALCATEL_MULTICAST_PKT) &&
+ !(word0 & ALCATEL_BROADCAST_PKT)) {
+ /* Promiscuous mode and Multicast mode are not mutually
+ * exclusive as was first thought. I guess Promiscuous is just
+ * considered a super-set of the other filters. Generally filter
+ * is 0x2b when in promiscuous mode.
+ */
+ if ((adapter->packet_filter & ET131X_PACKET_TYPE_MULTICAST)
+ && !(adapter->packet_filter & ET131X_PACKET_TYPE_PROMISCUOUS)
+ && !(adapter->packet_filter &
ET131X_PACKET_TYPE_ALL_MULTICAST)) {
- /*
- * Note - ring_index for fbr[] array is reversed
- * 1 for FBR0 etc
- */
- buf = rx_local->fbr[(ring_index == 0 ? 1 : 0)]->
- virt[buff_index];
+ buf = rx_local->fbr[ring_index]->virt[buff_index];
- /* Loop through our list to see if the
- * destination address of this packet
- * matches one in our list.
- */
- for (i = 0; i < adapter->multicast_addr_count;
- i++) {
- if (buf[0] ==
- adapter->multicast_list[i][0]
- && buf[1] ==
- adapter->multicast_list[i][1]
- && buf[2] ==
- adapter->multicast_list[i][2]
- && buf[3] ==
- adapter->multicast_list[i][3]
- && buf[4] ==
- adapter->multicast_list[i][4]
- && buf[5] ==
- adapter->multicast_list[i][5]) {
- break;
- }
+ /* Loop through our list to see if the destination
+ * address of this packet matches one in our list.
+ */
+ for (i = 0; i < adapter->multicast_addr_count; i++) {
+ if (buf[0] == adapter->multicast_list[i][0]
+ && buf[1] == adapter->multicast_list[i][1]
+ && buf[2] == adapter->multicast_list[i][2]
+ && buf[3] == adapter->multicast_list[i][3]
+ && buf[4] == adapter->multicast_list[i][4]
+ && buf[5] == adapter->multicast_list[i][5]) {
+ break;
}
-
- /* If our index is equal to the number
- * of Multicast address we have, then
- * this means we did not find this
- * packet's matching address in our
- * list. Set the len to zero,
- * so we free our RFD when we return
- * from this function.
- */
- if (i == adapter->multicast_addr_count)
- len = 0;
}
- if (len > 0)
- adapter->stats.multicast_pkts_rcvd++;
- } else if (word0 & ALCATEL_BROADCAST_PKT)
- adapter->stats.broadcast_pkts_rcvd++;
- else
- /* Not sure what this counter measures in
- * promiscuous mode. Perhaps we should check
- * the MAC address to see if it is directed
- * to us in promiscuous mode.
+ /* If our index is equal to the number of Multicast
+ * address we have, then this means we did not find this
+ * packet's matching address in our list. Set the len to
+ * zero, so we free our RFD when we return from this
+ * function.
*/
- adapter->stats.unicast_pkts_rcvd++;
- }
+ if (i == adapter->multicast_addr_count)
+ len = 0;
+ }
- if (len > 0) {
- struct sk_buff *skb = NULL;
+ if (len > 0)
+ adapter->stats.multicast_pkts_rcvd++;
+ } else if (word0 & ALCATEL_BROADCAST_PKT) {
+ adapter->stats.broadcast_pkts_rcvd++;
+ } else {
+ /* Not sure what this counter measures in promiscuous mode.
+ * Perhaps we should check the MAC address to see if it is
+ * directed to us in promiscuous mode.
+ */
+ adapter->stats.unicast_pkts_rcvd++;
+ }
- /*rfd->len = len - 4; */
- rfd->len = len;
+ if (len == 0) {
+ rfd->len = 0;
+ goto out;
+ }
- skb = dev_alloc_skb(rfd->len + 2);
- if (!skb) {
- dev_err(&adapter->pdev->dev,
- "Couldn't alloc an SKB for Rx\n");
- return NULL;
- }
+ rfd->len = len;
- adapter->net_stats.rx_bytes += rfd->len;
+ skb = dev_alloc_skb(rfd->len + 2);
+ if (!skb) {
+ dev_err(&adapter->pdev->dev, "Couldn't alloc an SKB for Rx\n");
+ return NULL;
+ }
- /*
- * Note - ring_index for fbr[] array is reversed,
- * 1 for FBR0 etc
- */
- memcpy(skb_put(skb, rfd->len),
- rx_local->fbr[(ring_index == 0 ? 1 : 0)]->virt[buff_index],
- rfd->len);
+ adapter->net_stats.rx_bytes += rfd->len;
- skb->dev = adapter->netdev;
- skb->protocol = eth_type_trans(skb, adapter->netdev);
- skb->ip_summed = CHECKSUM_NONE;
+ memcpy(skb_put(skb, rfd->len),
+ rx_local->fbr[ring_index]->virt[buff_index],
+ rfd->len);
- netif_rx_ni(skb);
- } else {
- rfd->len = 0;
- }
+ skb->dev = adapter->netdev;
+ skb->protocol = eth_type_trans(skb, adapter->netdev);
+ skb->ip_summed = CHECKSUM_NONE;
+ netif_rx_ni(skb);
+out:
nic_return_rfd(adapter, rfd);
return rfd;
}
@@ -3198,10 +2863,7 @@ static int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter)
return -ENOMEM;
}
- /* Allocate enough memory for the Tx descriptor ring, and allocate
- * some extra so that the ring can be aligned on a 4k boundary.
- */
- desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX) + 4096 - 1;
+ desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX);
tx_ring->tx_desc_ring =
(struct tx_desc *) dma_alloc_coherent(&adapter->pdev->dev,
desc_size,
@@ -3245,8 +2907,7 @@ static void et131x_tx_dma_memory_free(struct et131x_adapter *adapter)
if (adapter->tx_ring.tx_desc_ring) {
/* Free memory relating to Tx rings here */
- desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX)
- + 4096 - 1;
+ desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX);
dma_free_coherent(&adapter->pdev->dev,
desc_size,
adapter->tx_ring.tx_desc_ring,
@@ -3285,6 +2946,7 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb)
struct skb_frag_struct *frags = &skb_shinfo(skb)->frags[0];
unsigned long flags;
struct phy_device *phydev = adapter->phydev;
+ dma_addr_t dma_addr;
/* Part of the optimizations of this send routine restrict us to
* sending 24 fragments at a pass. In practice we should never see
@@ -3313,85 +2975,47 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb)
* This will work until we determine why the hardware
* doesn't seem to like large fragments.
*/
- if ((skb->len - skb->data_len) <= 1514) {
- desc[frag].addr_hi = 0;
+ if (skb_headlen(skb) <= 1514) {
/* Low 16bits are length, high is vlan and
unused currently so zero */
- desc[frag].len_vlan =
- skb->len - skb->data_len;
-
- /* NOTE: Here, the dma_addr_t returned from
- * dma_map_single() is implicitly cast as a
- * u32. Although dma_addr_t can be
- * 64-bit, the address returned by
- * dma_map_single() is always 32-bit
- * addressable (as defined by the pci/dma
- * subsystem)
- */
- desc[frag++].addr_lo =
- dma_map_single(&adapter->pdev->dev,
- skb->data,
- skb->len -
- skb->data_len,
- DMA_TO_DEVICE);
+ desc[frag].len_vlan = skb_headlen(skb);
+ dma_addr = dma_map_single(&adapter->pdev->dev,
+ skb->data,
+ skb_headlen(skb),
+ DMA_TO_DEVICE);
+ desc[frag].addr_lo = lower_32_bits(dma_addr);
+ desc[frag].addr_hi = upper_32_bits(dma_addr);
+ frag++;
} else {
- desc[frag].addr_hi = 0;
- desc[frag].len_vlan =
- (skb->len - skb->data_len) / 2;
-
- /* NOTE: Here, the dma_addr_t returned from
- * dma_map_single() is implicitly cast as a
- * u32. Although dma_addr_t can be
- * 64-bit, the address returned by
- * dma_map_single() is always 32-bit
- * addressable (as defined by the pci/dma
- * subsystem)
- */
- desc[frag++].addr_lo =
- dma_map_single(&adapter->pdev->dev,
- skb->data,
- ((skb->len -
- skb->data_len) / 2),
- DMA_TO_DEVICE);
- desc[frag].addr_hi = 0;
-
- desc[frag].len_vlan =
- (skb->len - skb->data_len) / 2;
-
- /* NOTE: Here, the dma_addr_t returned from
- * dma_map_single() is implicitly cast as a
- * u32. Although dma_addr_t can be
- * 64-bit, the address returned by
- * dma_map_single() is always 32-bit
- * addressable (as defined by the pci/dma
- * subsystem)
- */
- desc[frag++].addr_lo =
- dma_map_single(&adapter->pdev->dev,
- skb->data +
- ((skb->len -
- skb->data_len) / 2),
- ((skb->len -
- skb->data_len) / 2),
- DMA_TO_DEVICE);
+ desc[frag].len_vlan = skb_headlen(skb) / 2;
+ dma_addr = dma_map_single(&adapter->pdev->dev,
+ skb->data,
+ (skb_headlen(skb) / 2),
+ DMA_TO_DEVICE);
+ desc[frag].addr_lo = lower_32_bits(dma_addr);
+ desc[frag].addr_hi = upper_32_bits(dma_addr);
+ frag++;
+
+ desc[frag].len_vlan = skb_headlen(skb) / 2;
+ dma_addr = dma_map_single(&adapter->pdev->dev,
+ skb->data +
+ (skb_headlen(skb) / 2),
+ (skb_headlen(skb) / 2),
+ DMA_TO_DEVICE);
+ desc[frag].addr_lo = lower_32_bits(dma_addr);
+ desc[frag].addr_hi = upper_32_bits(dma_addr);
+ frag++;
}
} else {
- desc[frag].addr_hi = 0;
- desc[frag].len_vlan =
- frags[i - 1].size;
-
- /* NOTE: Here, the dma_addr_t returned from
- * dma_map_page() is implicitly cast as a u32.
- * Although dma_addr_t can be 64-bit, the address
- * returned by dma_map_page() is always 32-bit
- * addressable (as defined by the pci/dma subsystem)
- */
- desc[frag++].addr_lo = skb_frag_dma_map(
- &adapter->pdev->dev,
- &frags[i - 1],
- 0,
- frags[i - 1].size,
- DMA_TO_DEVICE);
+ desc[frag].len_vlan = frags[i - 1].size;
+ dma_addr = skb_frag_dma_map(&adapter->pdev->dev,
+ &frags[i - 1],
+ 0,
+ frags[i - 1].size,
+ DMA_TO_DEVICE);
+ desc[frag].addr_lo = lower_32_bits(dma_addr);
+ desc[frag].addr_hi = upper_32_bits(dma_addr);
+ frag++;
}
}
@@ -3521,7 +3145,7 @@ static int send_packet(struct sk_buff *skb, struct et131x_adapter *adapter)
tcb->skb = skb;
- if (skb->data != NULL && skb->len - skb->data_len >= 6) {
+ if (skb->data != NULL && skb_headlen(skb) >= 6) {
shbufva = (u16 *) skb->data;
if ((shbufva[0] == 0xffff) &&
@@ -3618,6 +3242,7 @@ static inline void free_send_packet(struct et131x_adapter *adapter,
unsigned long flags;
struct tx_desc *desc = NULL;
struct net_device_stats *stats = &adapter->net_stats;
+ u64 dma_addr;
if (tcb->flags & fMP_DEST_BROAD)
atomic_inc(&adapter->stats.broadcast_pkts_xmtd);
@@ -3638,8 +3263,11 @@ static inline void free_send_packet(struct et131x_adapter *adapter,
(adapter->tx_ring.tx_desc_ring +
INDEX10(tcb->index_start));
+ dma_addr = desc->addr_lo;
+ dma_addr |= (u64)desc->addr_hi << 32;
+
dma_unmap_single(&adapter->pdev->dev,
- desc->addr_lo,
+ dma_addr,
desc->len_vlan, DMA_TO_DEVICE);
add_10bit(&tcb->index_start, 1);
@@ -3830,7 +3458,12 @@ static void et131x_get_regs(struct net_device *netdev,
et131x_mii_read(adapter, 0x08, (u16 *)&regs_buff[num++]);
et131x_mii_read(adapter, MII_CTRL1000, (u16 *)&regs_buff[num++]);
et131x_mii_read(adapter, MII_STAT1000, (u16 *)&regs_buff[num++]);
+ et131x_mii_read(adapter, 0x0b, (u16 *)&regs_buff[num++]);
+ et131x_mii_read(adapter, 0x0c, (u16 *)&regs_buff[num++]);
+ et131x_mii_read(adapter, MII_MMD_CTRL, (u16 *)&regs_buff[num++]);
+ et131x_mii_read(adapter, MII_MMD_DATA, (u16 *)&regs_buff[num++]);
et131x_mii_read(adapter, MII_ESTATUS, (u16 *)&regs_buff[num++]);
+
et131x_mii_read(adapter, PHY_INDEX_REG, (u16 *)&regs_buff[num++]);
et131x_mii_read(adapter, PHY_DATA_REG, (u16 *)&regs_buff[num++]);
et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG,
@@ -3839,6 +3472,7 @@ static void et131x_get_regs(struct net_device *netdev,
(u16 *)&regs_buff[num++]);
et131x_mii_read(adapter, PHY_LOOPBACK_CONTROL+1,
(u16 *)&regs_buff[num++]);
+
et131x_mii_read(adapter, PHY_REGISTER_MGMT_CONTROL,
(u16 *)&regs_buff[num++]);
et131x_mii_read(adapter, PHY_CONFIG, (u16 *)&regs_buff[num++]);
@@ -3943,7 +3577,7 @@ static struct ethtool_ops et131x_ethtool_ops = {
.get_drvinfo = et131x_get_drvinfo,
.get_regs_len = et131x_get_regs_len,
.get_regs = et131x_get_regs,
- .get_link = ethtool_op_get_link,
+ .get_link = ethtool_op_get_link,
};
/**
* et131x_hwaddr_init - set up the MAC Address on the ET1310
@@ -4110,8 +3744,18 @@ static void et131x_error_timer_handler(unsigned long data)
}
/* This is a periodic timer, so reschedule */
- mod_timer(&adapter->error_timer, jiffies +
- TX_ERROR_PERIOD * HZ / 1000);
+ mod_timer(&adapter->error_timer, jiffies + TX_ERROR_PERIOD * HZ / 1000);
+}
+
+/**
+ * et131x_adapter_memory_free - Free all memory allocated for use by Tx & Rx
+ * @adapter: pointer to our private adapter structure
+ */
+static void et131x_adapter_memory_free(struct et131x_adapter *adapter)
+{
+ /* Free DMA memory */
+ et131x_tx_dma_memory_free(adapter);
+ et131x_rx_dma_memory_free(adapter);
}
/**
@@ -4144,26 +3788,14 @@ static int et131x_adapter_memory_alloc(struct et131x_adapter *adapter)
/* Init receive data structures */
status = et131x_init_recv(adapter);
- if (status != 0) {
+ if (status) {
dev_err(&adapter->pdev->dev,
"et131x_init_recv FAILED\n");
- et131x_tx_dma_memory_free(adapter);
- et131x_rx_dma_memory_free(adapter);
+ et131x_adapter_memory_free(adapter);
}
return status;
}
-/**
- * et131x_adapter_memory_free - Free all memory allocated for use by Tx & Rx
- * @adapter: pointer to our private adapter structure
- */
-static void et131x_adapter_memory_free(struct et131x_adapter *adapter)
-{
- /* Free DMA memory */
- et131x_tx_dma_memory_free(adapter);
- et131x_rx_dma_memory_free(adapter);
-}
-
static void et131x_adjust_link(struct net_device *netdev)
{
struct et131x_adapter *adapter = netdev_priv(netdev);
@@ -4358,7 +3990,7 @@ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev,
* PCI subsystem detects that a PCI device which matches the information
* contained in the pci_device_id table has been removed.
*/
-static void __devexit et131x_pci_remove(struct pci_dev *pdev)
+static void et131x_pci_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct et131x_adapter *adapter = netdev_priv(netdev);
@@ -4558,182 +4190,169 @@ static void et131x_isr_handler(struct work_struct *work)
status &= 0xffffffd7;
- if (status) {
- /* Handle the TXDMA Error interrupt */
- if (status & ET_INTR_TXDMA_ERR) {
- u32 txdma_err;
-
- /* Following read also clears the register (COR) */
- txdma_err = readl(&iomem->txdma.tx_dma_error);
+ if (!status)
+ goto out;
- dev_warn(&adapter->pdev->dev,
- "TXDMA_ERR interrupt, error = %d\n",
- txdma_err);
- }
+ /* Handle the TXDMA Error interrupt */
+ if (status & ET_INTR_TXDMA_ERR) {
+ u32 txdma_err;
- /* Handle Free Buffer Ring 0 and 1 Low interrupt */
- if (status &
- (ET_INTR_RXDMA_FB_R0_LOW | ET_INTR_RXDMA_FB_R1_LOW)) {
- /*
- * This indicates the number of unused buffers in
- * RXDMA free buffer ring 0 is <= the limit you
- * programmed. Free buffer resources need to be
- * returned. Free buffers are consumed as packets
- * are passed from the network to the host. The host
- * becomes aware of the packets from the contents of
- * the packet status ring. This ring is queried when
- * the packet done interrupt occurs. Packets are then
- * passed to the OS. When the OS is done with the
- * packets the resources can be returned to the
- * ET1310 for re-use. This interrupt is one method of
- * returning resources.
- */
+ /* Following read also clears the register (COR) */
+ txdma_err = readl(&iomem->txdma.tx_dma_error);
- /* If the user has flow control on, then we will
- * send a pause packet, otherwise just exit
- */
- if (adapter->flowcontrol == FLOW_TXONLY ||
- adapter->flowcontrol == FLOW_BOTH) {
- u32 pm_csr;
+ dev_warn(&adapter->pdev->dev,
+ "TXDMA_ERR interrupt, error = %d\n",
+ txdma_err);
+ }
- /* Tell the device to send a pause packet via
- * the back pressure register (bp req and
- * bp xon/xoff)
- */
- pm_csr = readl(&iomem->global.pm_csr);
- if (!et1310_in_phy_coma(adapter))
- writel(3, &iomem->txmac.bp_ctrl);
- }
- }
+ /* Handle Free Buffer Ring 0 and 1 Low interrupt */
+ if (status & (ET_INTR_RXDMA_FB_R0_LOW | ET_INTR_RXDMA_FB_R1_LOW)) {
+ /*
+ * This indicates the number of unused buffers in RXDMA free
+ * buffer ring 0 is <= the limit you programmed. Free buffer
+ * resources need to be returned. Free buffers are consumed as
+ * packets are passed from the network to the host. The host
+ * becomes aware of the packets from the contents of the packet
+ * status ring. This ring is queried when the packet done
+ * interrupt occurs. Packets are then passed to the OS. When
+ * the OS is done with the packets the resources can be
+ * returned to the ET1310 for re-use. This interrupt is one
+ * method of returning resources.
+ */
- /* Handle Packet Status Ring Low Interrupt */
- if (status & ET_INTR_RXDMA_STAT_LOW) {
+ /*
+ * If the user has flow control on, then we will
+ * send a pause packet, otherwise just exit
+ */
+ if (adapter->flowcontrol == FLOW_TXONLY ||
+ adapter->flowcontrol == FLOW_BOTH) {
+ u32 pm_csr;
/*
- * Same idea as with the two Free Buffer Rings.
- * Packets going from the network to the host each
- * consume a free buffer resource and a packet status
- * resource. These resoures are passed to the OS.
- * When the OS is done with the resources, they need
- * to be returned to the ET1310. This is one method
- * of returning the resources.
+ * Tell the device to send a pause packet via the back
+ * pressure register (bp req and bp xon/xoff)
*/
+ pm_csr = readl(&iomem->global.pm_csr);
+ if (!et1310_in_phy_coma(adapter))
+ writel(3, &iomem->txmac.bp_ctrl);
}
+ }
- /* Handle RXDMA Error Interrupt */
- if (status & ET_INTR_RXDMA_ERR) {
- /*
- * The rxdma_error interrupt is sent when a time-out
- * on a request issued by the JAGCore has occurred or
- * a completion is returned with an un-successful
- * status. In both cases the request is considered
- * complete. The JAGCore will automatically re-try the
- * request in question. Normally information on events
- * like these are sent to the host using the "Advanced
- * Error Reporting" capability. This interrupt is
- * another way of getting similar information. The
- * only thing required is to clear the interrupt by
- * reading the ISR in the global resources. The
- * JAGCore will do a re-try on the request. Normally
- * you should never see this interrupt. If you start
- * to see this interrupt occurring frequently then
- * something bad has occurred. A reset might be the
- * thing to do.
- */
- /* TRAP();*/
+ /* Handle Packet Status Ring Low Interrupt */
+ if (status & ET_INTR_RXDMA_STAT_LOW) {
+ /*
+ * Same idea as with the two Free Buffer Rings. Packets going
+ * from the network to the host each consume a free buffer
+ * resource and a packet status resource. These resoures are
+ * passed to the OS. When the OS is done with the resources,
+ * they need to be returned to the ET1310. This is one method
+ * of returning the resources.
+ */
+ }
- dev_warn(&adapter->pdev->dev,
- "RxDMA_ERR interrupt, error %x\n",
- readl(&iomem->txmac.tx_test));
- }
+ /* Handle RXDMA Error Interrupt */
+ if (status & ET_INTR_RXDMA_ERR) {
+ /*
+ * The rxdma_error interrupt is sent when a time-out on a
+ * request issued by the JAGCore has occurred or a completion is
+ * returned with an un-successful status. In both cases the
+ * request is considered complete. The JAGCore will
+ * automatically re-try the request in question. Normally
+ * information on events like these are sent to the host using
+ * the "Advanced Error Reporting" capability. This interrupt is
+ * another way of getting similar information. The only thing
+ * required is to clear the interrupt by reading the ISR in the
+ * global resources. The JAGCore will do a re-try on the
+ * request. Normally you should never see this interrupt. If
+ * you start to see this interrupt occurring frequently then
+ * something bad has occurred. A reset might be the thing to do.
+ */
+ /* TRAP();*/
- /* Handle the Wake on LAN Event */
- if (status & ET_INTR_WOL) {
- /*
- * This is a secondary interrupt for wake on LAN.
- * The driver should never see this, if it does,
- * something serious is wrong. We will TRAP the
- * message when we are in DBG mode, otherwise we
- * will ignore it.
- */
- dev_err(&adapter->pdev->dev, "WAKE_ON_LAN interrupt\n");
- }
+ dev_warn(&adapter->pdev->dev,
+ "RxDMA_ERR interrupt, error %x\n",
+ readl(&iomem->txmac.tx_test));
+ }
- /* Let's move on to the TxMac */
- if (status & ET_INTR_TXMAC) {
- u32 err = readl(&iomem->txmac.err);
+ /* Handle the Wake on LAN Event */
+ if (status & ET_INTR_WOL) {
+ /*
+ * This is a secondary interrupt for wake on LAN. The driver
+ * should never see this, if it does, something serious is
+ * wrong. We will TRAP the message when we are in DBG mode,
+ * otherwise we will ignore it.
+ */
+ dev_err(&adapter->pdev->dev, "WAKE_ON_LAN interrupt\n");
+ }
- /*
- * When any of the errors occur and TXMAC generates
- * an interrupt to report these errors, it usually
- * means that TXMAC has detected an error in the data
- * stream retrieved from the on-chip Tx Q. All of
- * these errors are catastrophic and TXMAC won't be
- * able to recover data when these errors occur. In
- * a nutshell, the whole Tx path will have to be reset
- * and re-configured afterwards.
- */
- dev_warn(&adapter->pdev->dev,
- "TXMAC interrupt, error 0x%08x\n",
- err);
+ /* Let's move on to the TxMac */
+ if (status & ET_INTR_TXMAC) {
+ u32 err = readl(&iomem->txmac.err);
- /* If we are debugging, we want to see this error,
- * otherwise we just want the device to be reset and
- * continue
- */
- }
+ /*
+ * When any of the errors occur and TXMAC generates an
+ * interrupt to report these errors, it usually means that
+ * TXMAC has detected an error in the data stream retrieved
+ * from the on-chip Tx Q. All of these errors are catastrophic
+ * and TXMAC won't be able to recover data when these errors
+ * occur. In a nutshell, the whole Tx path will have to be reset
+ * and re-configured afterwards.
+ */
+ dev_warn(&adapter->pdev->dev,
+ "TXMAC interrupt, error 0x%08x\n",
+ err);
- /* Handle RXMAC Interrupt */
- if (status & ET_INTR_RXMAC) {
- /*
- * These interrupts are catastrophic to the device,
- * what we need to do is disable the interrupts and
- * set the flag to cause us to reset so we can solve
- * this issue.
- */
- /* MP_SET_FLAG( adapter,
- fMP_ADAPTER_HARDWARE_ERROR); */
+ /*
+ * If we are debugging, we want to see this error, otherwise we
+ * just want the device to be reset and continue
+ */
+ }
- dev_warn(&adapter->pdev->dev,
- "RXMAC interrupt, error 0x%08x. Requesting reset\n",
- readl(&iomem->rxmac.err_reg));
+ /* Handle RXMAC Interrupt */
+ if (status & ET_INTR_RXMAC) {
+ /*
+ * These interrupts are catastrophic to the device, what we need
+ * to do is disable the interrupts and set the flag to cause us
+ * to reset so we can solve this issue.
+ */
+ /* MP_SET_FLAG( adapter, fMP_ADAPTER_HARDWARE_ERROR); */
- dev_warn(&adapter->pdev->dev,
- "Enable 0x%08x, Diag 0x%08x\n",
- readl(&iomem->rxmac.ctrl),
- readl(&iomem->rxmac.rxq_diag));
+ dev_warn(&adapter->pdev->dev,
+ "RXMAC interrupt, error 0x%08x. Requesting reset\n",
+ readl(&iomem->rxmac.err_reg));
- /*
- * If we are debugging, we want to see this error,
- * otherwise we just want the device to be reset and
- * continue
- */
- }
+ dev_warn(&adapter->pdev->dev,
+ "Enable 0x%08x, Diag 0x%08x\n",
+ readl(&iomem->rxmac.ctrl),
+ readl(&iomem->rxmac.rxq_diag));
- /* Handle MAC_STAT Interrupt */
- if (status & ET_INTR_MAC_STAT) {
- /*
- * This means at least one of the un-masked counters
- * in the MAC_STAT block has rolled over. Use this
- * to maintain the top, software managed bits of the
- * counter(s).
- */
- et1310_handle_macstat_interrupt(adapter);
- }
+ /*
+ * If we are debugging, we want to see this error, otherwise we
+ * just want the device to be reset and continue
+ */
+ }
- /* Handle SLV Timeout Interrupt */
- if (status & ET_INTR_SLV_TIMEOUT) {
- /*
- * This means a timeout has occurred on a read or
- * write request to one of the JAGCore registers. The
- * Global Resources block has terminated the request
- * and on a read request, returned a "fake" value.
- * The most likely reasons are: Bad Address or the
- * addressed module is in a power-down state and
- * can't respond.
- */
- }
+ /* Handle MAC_STAT Interrupt */
+ if (status & ET_INTR_MAC_STAT) {
+ /*
+ * This means at least one of the un-masked counters in the
+ * MAC_STAT block has rolled over. Use this to maintain the top,
+ * software managed bits of the counter(s).
+ */
+ et1310_handle_macstat_interrupt(adapter);
}
+
+ /* Handle SLV Timeout Interrupt */
+ if (status & ET_INTR_SLV_TIMEOUT) {
+ /*
+ * This means a timeout has occurred on a read or write request
+ * to one of the JAGCore registers. The Global Resources block
+ * has terminated the request and on a read request, returned a
+ * "fake" value. The most likely reasons are: Bad Address or the
+ * addressed module is in a power-down state and can't respond.
+ */
+ }
+out:
et131x_enable_interrupts(adapter);
}
@@ -5221,7 +4840,7 @@ static const struct net_device_ops et131x_netdev_ops = {
* contained in the pci_device_id table. This routine is the equivalent to
* a device insertion routine.
*/
-static int __devinit et131x_pci_setup(struct pci_dev *pdev,
+static int et131x_pci_setup(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct net_device *netdev;
@@ -5423,7 +5042,7 @@ static struct pci_driver et131x_driver = {
.name = DRIVER_NAME,
.id_table = et131x_pci_table,
.probe = et131x_pci_setup,
- .remove = __devexit_p(et131x_pci_remove),
+ .remove = et131x_pci_remove,
.driver.pm = ET131X_PM_OPS,
};
diff --git a/drivers/staging/et131x/et131x.h b/drivers/staging/et131x/et131x.h
index 864379b4e8d..347e63ddde1 100644
--- a/drivers/staging/et131x/et131x.h
+++ b/drivers/staging/et131x/et131x.h
@@ -1538,10 +1538,6 @@ struct address_map {
* 0: int_en
*/
-#define ET_PHY_INT_MASK_AUTONEGSTAT 0x0100
-#define ET_PHY_INT_MASK_LINKSTAT 0x0004
-#define ET_PHY_INT_MASK_ENABLE 0x0001
-
/* MI Register 25: Interrupt Status Reg(0x19)
* 15-10: reserved
* 9: mdio_sync_lost
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c
index 5ae39671613..1edaddba816 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c
@@ -205,7 +205,7 @@ int ft1000_init_proc(struct net_device *dev)
{
struct ft1000_info *info;
struct proc_dir_entry *ft1000_proc_file;
- int ret = 0;
+ int ret = -EINVAL;
info = netdev_priv(dev);
@@ -213,7 +213,6 @@ int ft1000_init_proc(struct net_device *dev)
if (info->ft1000_proc_dir == NULL) {
printk(KERN_WARNING "Unable to create %s dir.\n",
FT1000_PROC_DIR);
- ret = -EINVAL;
goto fail;
}
@@ -223,7 +222,6 @@ int ft1000_init_proc(struct net_device *dev)
if (ft1000_proc_file == NULL) {
printk(KERN_WARNING "Unable to create /proc entry.\n");
- ret = -EINVAL;
goto fail_entry;
}
diff --git a/drivers/staging/fwserial/Kconfig b/drivers/staging/fwserial/Kconfig
new file mode 100644
index 00000000000..580406cb180
--- /dev/null
+++ b/drivers/staging/fwserial/Kconfig
@@ -0,0 +1,9 @@
+config FIREWIRE_SERIAL
+ tristate "TTY over Firewire"
+ depends on FIREWIRE
+ help
+ This enables TTY over IEEE 1394, providing high-speed serial
+ connectivity to cabled peers.
+
+ To compile this driver as a module, say M here: the module will
+ be called firewire-serial.
diff --git a/drivers/staging/fwserial/Makefile b/drivers/staging/fwserial/Makefile
new file mode 100644
index 00000000000..2170869a19b
--- /dev/null
+++ b/drivers/staging/fwserial/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_FIREWIRE_SERIAL) += firewire-serial.o
+firewire-serial-objs := fwserial.o dma_fifo.o
diff --git a/drivers/staging/fwserial/TODO b/drivers/staging/fwserial/TODO
new file mode 100644
index 00000000000..726900548ea
--- /dev/null
+++ b/drivers/staging/fwserial/TODO
@@ -0,0 +1,37 @@
+TODOs
+-----
+1. Implement retries for RCODE_BUSY, RCODE_NO_ACK and RCODE_SEND_ERROR
+ - I/O is handled asynchronously which presents some issues when error
+ conditions occur.
+2. Implement _robust_ console on top of this. The existing prototype console
+ driver is not ready for the big leagues yet.
+3. Expose means of controlling attach/detach of peers via sysfs. Include
+ GUID-to-port matching/whitelist/blacklist.
+
+-- Issues with firewire stack --
+1. This driver uses the same unregistered vendor id that the firewire core does
+ (0xd00d1e). Perhaps this could be exposed as a define in
+ firewire-constants.h?
+2. MAX_ASYNC_PAYLOAD needs to be publicly exposed by core/ohci
+ - otherwise how will this driver know the max size of address window to
+ open for one packet write?
+3. Maybe device_max_receive() and link_speed_to_max_payload() should be
+ taken up by the firewire core?
+4. To avoid dropping rx data while still limiting the maximum buffering,
+ the size of the AR context must be known. How to expose this to drivers?
+5. Explore if bigger AR context will reduce RCODE_BUSY responses
+ (or auto-grow to certain max size -- but this would require major surgery
+ as the current AR is contiguously mapped)
+
+-- Issues with TTY core --
+ 1. Hack for alternate device name scheme
+ - because udev no longer allows device renaming, devices should have
+ their proper names on creation. This is an issue for creating the
+ fwloop<n> device with the fwtty<n> devices because although duplicating
+ roughly the same operations as tty_port_register_device() isn't difficult,
+ access to the tty_class & tty_fops is restricted in scope.
+
+ This is currently being worked around in create_loop_device() by
+ extracting the tty_class ptr and tty_fops ptr from the previously created
+ tty devices. Perhaps an add'l api can be added -- eg.,
+ tty_{port_}register_named_device().
diff --git a/drivers/staging/fwserial/dma_fifo.c b/drivers/staging/fwserial/dma_fifo.c
new file mode 100644
index 00000000000..5e846344550
--- /dev/null
+++ b/drivers/staging/fwserial/dma_fifo.c
@@ -0,0 +1,307 @@
+/*
+ * DMA-able FIFO implementation
+ *
+ * Copyright (C) 2012 Peter Hurley <peter@hurleysoftware.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/bug.h>
+
+#include "dma_fifo.h"
+
+#ifdef DEBUG_TRACING
+#define df_trace(s, args...) pr_debug(s, ##args)
+#else
+#define df_trace(s, args...)
+#endif
+
+#define FAIL(fifo, condition, format...) ({ \
+ fifo->corrupt = !!(condition); \
+ WARN(fifo->corrupt, format); \
+})
+
+/*
+ * private helper fn to determine if check is in open interval (lo,hi)
+ */
+static bool addr_check(unsigned check, unsigned lo, unsigned hi)
+{
+ return check - (lo + 1) < (hi - 1) - lo;
+}
+
+/**
+ * dma_fifo_init: initialize the fifo to a valid but inoperative state
+ * @fifo: address of in-place "struct dma_fifo" object
+ */
+void dma_fifo_init(struct dma_fifo *fifo)
+{
+ memset(fifo, 0, sizeof(*fifo));
+ INIT_LIST_HEAD(&fifo->pending);
+}
+
+/**
+ * dma_fifo_alloc - initialize and allocate dma_fifo
+ * @fifo: address of in-place "struct dma_fifo" object
+ * @size: 'apparent' size, in bytes, of fifo
+ * @align: dma alignment to maintain (should be at least cpu cache alignment),
+ * must be power of 2
+ * @tx_limit: maximum # of bytes transmissable per dma (rounded down to
+ * multiple of alignment, but at least align size)
+ * @open_limit: maximum # of outstanding dma transactions allowed
+ * @gfp_mask: get_free_pages mask, passed to kmalloc()
+ *
+ * The 'apparent' size will be rounded up to next greater aligned size.
+ * Returns 0 if no error, otherwise an error code
+ */
+int dma_fifo_alloc(struct dma_fifo *fifo, int size, unsigned align,
+ int tx_limit, int open_limit, gfp_t gfp_mask)
+{
+ int capacity;
+
+ if (!is_power_of_2(align) || size < 0)
+ return -EINVAL;
+
+ size = round_up(size, align);
+ capacity = size + align * open_limit + align * DMA_FIFO_GUARD;
+ fifo->data = kmalloc(capacity, gfp_mask);
+ if (!fifo->data)
+ return -ENOMEM;
+
+ fifo->in = 0;
+ fifo->out = 0;
+ fifo->done = 0;
+ fifo->size = size;
+ fifo->avail = size;
+ fifo->align = align;
+ fifo->tx_limit = max_t(int, round_down(tx_limit, align), align);
+ fifo->open = 0;
+ fifo->open_limit = open_limit;
+ fifo->guard = size + align * open_limit;
+ fifo->capacity = capacity;
+ fifo->corrupt = 0;
+
+ return 0;
+}
+
+/**
+ * dma_fifo_free - frees the fifo
+ * @fifo: address of in-place "struct dma_fifo" to free
+ *
+ * Also reinits the fifo to a valid but inoperative state. This
+ * allows the fifo to be reused with a different target requiring
+ * different fifo parameters.
+ */
+void dma_fifo_free(struct dma_fifo *fifo)
+{
+ struct dma_pending *pending, *next;
+
+ if (fifo->data == NULL)
+ return;
+
+ list_for_each_entry_safe(pending, next, &fifo->pending, link)
+ list_del_init(&pending->link);
+ kfree(fifo->data);
+ fifo->data = NULL;
+}
+
+/**
+ * dma_fifo_reset - dumps the fifo contents and reinits for reuse
+ * @fifo: address of in-place "struct dma_fifo" to reset
+ */
+void dma_fifo_reset(struct dma_fifo *fifo)
+{
+ struct dma_pending *pending, *next;
+
+ if (fifo->data == NULL)
+ return;
+
+ list_for_each_entry_safe(pending, next, &fifo->pending, link)
+ list_del_init(&pending->link);
+ fifo->in = 0;
+ fifo->out = 0;
+ fifo->done = 0;
+ fifo->avail = fifo->size;
+ fifo->open = 0;
+ fifo->corrupt = 0;
+}
+
+/**
+ * dma_fifo_in - copies data into the fifo
+ * @fifo: address of in-place "struct dma_fifo" to write to
+ * @src: buffer to copy from
+ * @n: # of bytes to copy
+ *
+ * Returns the # of bytes actually copied, which can be less than requested if
+ * the fifo becomes full. If < 0, return is error code.
+ */
+int dma_fifo_in(struct dma_fifo *fifo, const void *src, int n)
+{
+ int ofs, l;
+
+ if (fifo->data == NULL)
+ return -ENOENT;
+ if (fifo->corrupt)
+ return -ENXIO;
+
+ if (n > fifo->avail)
+ n = fifo->avail;
+ if (n <= 0)
+ return 0;
+
+ ofs = fifo->in % fifo->capacity;
+ l = min(n, fifo->capacity - ofs);
+ memcpy(fifo->data + ofs, src, l);
+ memcpy(fifo->data, src + l, n - l);
+
+ if (FAIL(fifo, addr_check(fifo->done, fifo->in, fifo->in + n) ||
+ fifo->avail < n,
+ "fifo corrupt: in:%u out:%u done:%u n:%d avail:%d",
+ fifo->in, fifo->out, fifo->done, n, fifo->avail))
+ return -ENXIO;
+
+ fifo->in += n;
+ fifo->avail -= n;
+
+ df_trace("in:%u out:%u done:%u n:%d avail:%d", fifo->in, fifo->out,
+ fifo->done, n, fifo->avail);
+
+ return n;
+}
+
+/**
+ * dma_fifo_out_pend - gets address/len of next avail read and marks as pended
+ * @fifo: address of in-place "struct dma_fifo" to read from
+ * @pended: address of structure to fill with read address/len
+ * The data/len fields will be NULL/0 if no dma is pended.
+ *
+ * Returns the # of used bytes remaining in fifo (ie, if > 0, more data
+ * remains in the fifo that was not pended). If < 0, return is error code.
+ */
+int dma_fifo_out_pend(struct dma_fifo *fifo, struct dma_pending *pended)
+{
+ unsigned len, n, ofs, l, limit;
+
+ if (fifo->data == NULL)
+ return -ENOENT;
+ if (fifo->corrupt)
+ return -ENXIO;
+
+ pended->len = 0;
+ pended->data = NULL;
+ pended->out = fifo->out;
+
+ len = fifo->in - fifo->out;
+ if (!len)
+ return -ENODATA;
+ if (fifo->open == fifo->open_limit)
+ return -EAGAIN;
+
+ n = len;
+ ofs = fifo->out % fifo->capacity;
+ l = fifo->capacity - ofs;
+ limit = min_t(unsigned, l, fifo->tx_limit);
+ if (n > limit) {
+ n = limit;
+ fifo->out += limit;
+ } else if (ofs + n > fifo->guard) {
+ fifo->out += l;
+ fifo->in = fifo->out;
+ } else {
+ fifo->out += round_up(n, fifo->align);
+ fifo->in = fifo->out;
+ }
+
+ df_trace("in: %u out: %u done: %u n: %d len: %u avail: %d", fifo->in,
+ fifo->out, fifo->done, n, len, fifo->avail);
+
+ pended->len = n;
+ pended->data = fifo->data + ofs;
+ pended->next = fifo->out;
+ list_add_tail(&pended->link, &fifo->pending);
+ ++fifo->open;
+
+ if (FAIL(fifo, fifo->open > fifo->open_limit,
+ "past open limit:%d (limit:%d)",
+ fifo->open, fifo->open_limit))
+ return -ENXIO;
+ if (FAIL(fifo, fifo->out & (fifo->align - 1),
+ "fifo out unaligned:%u (align:%u)",
+ fifo->out, fifo->align))
+ return -ENXIO;
+
+ return len - n;
+}
+
+/**
+ * dma_fifo_out_complete - marks pended dma as completed
+ * @fifo: address of in-place "struct dma_fifo" which was read from
+ * @complete: address of structure for previously pended dma to mark completed
+ */
+int dma_fifo_out_complete(struct dma_fifo *fifo, struct dma_pending *complete)
+{
+ struct dma_pending *pending, *next, *tmp;
+
+ if (fifo->data == NULL)
+ return -ENOENT;
+ if (fifo->corrupt)
+ return -ENXIO;
+ if (list_empty(&fifo->pending) && fifo->open == 0)
+ return -EINVAL;
+
+ if (FAIL(fifo, list_empty(&fifo->pending) != (fifo->open == 0),
+ "pending list disagrees with open count:%d",
+ fifo->open))
+ return -ENXIO;
+
+ tmp = complete->data;
+ *tmp = *complete;
+ list_replace(&complete->link, &tmp->link);
+ dp_mark_completed(tmp);
+
+ /* Only update the fifo in the original pended order */
+ list_for_each_entry_safe(pending, next, &fifo->pending, link) {
+ if (!dp_is_completed(pending)) {
+ df_trace("still pending: saved out: %u len: %d",
+ pending->out, pending->len);
+ break;
+ }
+
+ if (FAIL(fifo, pending->out != fifo->done ||
+ addr_check(fifo->in, fifo->done, pending->next),
+ "in:%u out:%u done:%u saved:%u next:%u",
+ fifo->in, fifo->out, fifo->done, pending->out,
+ pending->next))
+ return -ENXIO;
+
+ list_del_init(&pending->link);
+ fifo->done = pending->next;
+ fifo->avail += pending->len;
+ --fifo->open;
+
+ df_trace("in: %u out: %u done: %u len: %u avail: %d", fifo->in,
+ fifo->out, fifo->done, pending->len, fifo->avail);
+ }
+
+ if (FAIL(fifo, fifo->open < 0, "open dma:%d < 0", fifo->open))
+ return -ENXIO;
+ if (FAIL(fifo, fifo->avail > fifo->size, "fifo avail:%d > size:%d",
+ fifo->avail, fifo->size))
+ return -ENXIO;
+
+ return 0;
+}
diff --git a/drivers/staging/fwserial/dma_fifo.h b/drivers/staging/fwserial/dma_fifo.h
new file mode 100644
index 00000000000..a113fe1e6f1
--- /dev/null
+++ b/drivers/staging/fwserial/dma_fifo.h
@@ -0,0 +1,130 @@
+/*
+ * DMA-able FIFO interface
+ *
+ * Copyright (C) 2012 Peter Hurley <peter@hurleysoftware.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _DMA_FIFO_H_
+#define _DMA_FIFO_H_
+
+/**
+ * The design basis for the DMA FIFO is to provide an output side that
+ * complies with the streaming DMA API design that can be DMA'd from directly
+ * (without additional copying), coupled with an input side that maintains a
+ * logically consistent 'apparent' size (ie, bytes in + bytes avail is static
+ * for the lifetime of the FIFO).
+ *
+ * DMA output transactions originate on a cache line boundary and can be
+ * variably-sized. DMA output transactions can be retired out-of-order but
+ * the FIFO will only advance the output in the original input sequence.
+ * This means the FIFO will eventually stall if a transaction is never retired.
+ *
+ * Chunking the output side into cache line multiples means that some FIFO
+ * memory is unused. For example, if all the avail input has been pended out,
+ * then the in and out markers are re-aligned to the next cache line.
+ * The maximum possible waste is
+ * (cache line alignment - 1) * (max outstanding dma transactions)
+ * This potential waste requires additional hidden capacity within the FIFO
+ * to be able to accept input while the 'apparent' size has not been reached.
+ *
+ * Additional cache lines (ie, guard area) are used to minimize DMA
+ * fragmentation when wrapping at the end of the FIFO. Input is allowed into the
+ * guard area, but the in and out FIFO markers are wrapped when DMA is pended.
+ */
+
+#define DMA_FIFO_GUARD 3 /* # of cache lines to reserve for the guard area */
+
+struct dma_fifo {
+ unsigned in;
+ unsigned out; /* updated when dma is pended */
+ unsigned done; /* updated upon dma completion */
+ struct {
+ unsigned corrupt:1;
+ };
+ int size; /* 'apparent' size of fifo */
+ int guard; /* ofs of guard area */
+ int capacity; /* size + reserved */
+ int avail; /* # of unused bytes in fifo */
+ unsigned align; /* must be power of 2 */
+ int tx_limit; /* max # of bytes per dma transaction */
+ int open_limit; /* max # of outstanding allowed */
+ int open; /* # of outstanding dma transactions */
+ struct list_head pending; /* fifo markers for outstanding dma */
+ void *data;
+};
+
+struct dma_pending {
+ struct list_head link;
+ void *data;
+ unsigned len;
+ unsigned next;
+ unsigned out;
+};
+
+static inline void dp_mark_completed(struct dma_pending *dp)
+{
+ dp->data += 1;
+}
+
+static inline bool dp_is_completed(struct dma_pending *dp)
+{
+ return (unsigned long)dp->data & 1UL;
+}
+
+extern void dma_fifo_init(struct dma_fifo *fifo);
+extern int dma_fifo_alloc(struct dma_fifo *fifo, int size, unsigned align,
+ int tx_limit, int open_limit, gfp_t gfp_mask);
+extern void dma_fifo_free(struct dma_fifo *fifo);
+extern void dma_fifo_reset(struct dma_fifo *fifo);
+extern int dma_fifo_in(struct dma_fifo *fifo, const void *src, int n);
+extern int dma_fifo_out_pend(struct dma_fifo *fifo, struct dma_pending *pended);
+extern int dma_fifo_out_complete(struct dma_fifo *fifo,
+ struct dma_pending *complete);
+
+/* returns the # of used bytes in the fifo */
+static inline int dma_fifo_level(struct dma_fifo *fifo)
+{
+ return fifo->size - fifo->avail;
+}
+
+/* returns the # of bytes ready for output in the fifo */
+static inline int dma_fifo_out_level(struct dma_fifo *fifo)
+{
+ return fifo->in - fifo->out;
+}
+
+/* returns the # of unused bytes in the fifo */
+static inline int dma_fifo_avail(struct dma_fifo *fifo)
+{
+ return fifo->avail;
+}
+
+/* returns true if fifo has max # of outstanding dmas */
+static inline bool dma_fifo_busy(struct dma_fifo *fifo)
+{
+ return fifo->open == fifo->open_limit;
+}
+
+/* changes the max size of dma returned from dma_fifo_out_pend() */
+static inline int dma_fifo_change_tx_limit(struct dma_fifo *fifo, int tx_limit)
+{
+ tx_limit = round_down(tx_limit, fifo->align);
+ fifo->tx_limit = max_t(int, tx_limit, fifo->align);
+ return 0;
+}
+
+#endif /* _DMA_FIFO_H_ */
diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c
new file mode 100644
index 00000000000..61ee29083b2
--- /dev/null
+++ b/drivers/staging/fwserial/fwserial.c
@@ -0,0 +1,2943 @@
+/*
+ * FireWire Serial driver
+ *
+ * Copyright (C) 2012 Peter Hurley <peter@hurleysoftware.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/rculist.h>
+#include <linux/workqueue.h>
+#include <linux/ratelimit.h>
+#include <linux/bug.h>
+#include <linux/uaccess.h>
+
+#include "fwserial.h"
+
+#define be32_to_u64(hi, lo) ((u64)be32_to_cpu(hi) << 32 | be32_to_cpu(lo))
+
+#define LINUX_VENDOR_ID 0xd00d1eU /* same id used in card root directory */
+#define FWSERIAL_VERSION 0x00e81cU /* must be unique within LINUX_VENDOR_ID */
+
+/* configurable options */
+static int num_ttys = 4; /* # of std ttys to create per fw_card */
+ /* - doubles as loopback port index */
+static bool auto_connect = true; /* try to VIRT_CABLE to every peer */
+static bool create_loop_dev = true; /* create a loopback device for each card */
+bool limit_bw; /* limit async bandwidth to 20% of max */
+
+module_param_named(ttys, num_ttys, int, S_IRUGO | S_IWUSR);
+module_param_named(auto, auto_connect, bool, S_IRUGO | S_IWUSR);
+module_param_named(loop, create_loop_dev, bool, S_IRUGO | S_IWUSR);
+module_param(limit_bw, bool, S_IRUGO | S_IWUSR);
+
+/*
+ * Threshold below which the tty is woken for writing
+ * - should be equal to WAKEUP_CHARS in drivers/tty/n_tty.c because
+ * even if the writer is woken, n_tty_poll() won't set POLLOUT until
+ * our fifo is below this level
+ */
+#define WAKEUP_CHARS 256
+
+/**
+ * fwserial_list: list of every fw_serial created for each fw_card
+ * See discussion in fwserial_probe.
+ */
+static LIST_HEAD(fwserial_list);
+static DEFINE_MUTEX(fwserial_list_mutex);
+
+/**
+ * port_table: array of tty ports allocated to each fw_card
+ *
+ * tty ports are allocated during probe when an fw_serial is first
+ * created for a given fw_card. Ports are allocated in a contiguous block,
+ * each block consisting of 'num_ports' ports.
+ */
+static struct fwtty_port *port_table[MAX_TOTAL_PORTS];
+static DEFINE_MUTEX(port_table_lock);
+static bool port_table_corrupt;
+#define FWTTY_INVALID_INDEX MAX_TOTAL_PORTS
+
+/* total # of tty ports created per fw_card */
+static int num_ports;
+
+/* slab used as pool for struct fwtty_transactions */
+static struct kmem_cache *fwtty_txn_cache;
+
+struct fwtty_transaction;
+typedef void (*fwtty_transaction_cb)(struct fw_card *card, int rcode,
+ void *data, size_t length,
+ struct fwtty_transaction *txn);
+
+struct fwtty_transaction {
+ struct fw_transaction fw_txn;
+ fwtty_transaction_cb callback;
+ struct fwtty_port *port;
+ union {
+ struct dma_pending dma_pended;
+ };
+};
+
+#define to_device(a, b) (a->b)
+#define fwtty_err(p, s, v...) dev_err(to_device(p, device), s, ##v)
+#define fwtty_info(p, s, v...) dev_info(to_device(p, device), s, ##v)
+#define fwtty_notice(p, s, v...) dev_notice(to_device(p, device), s, ##v)
+#define fwtty_dbg(p, s, v...) \
+ dev_dbg(to_device(p, device), "%s: " s, __func__, ##v)
+#define fwtty_err_ratelimited(p, s, v...) \
+ dev_err_ratelimited(to_device(p, device), s, ##v)
+
+#ifdef DEBUG
+static inline void debug_short_write(struct fwtty_port *port, int c, int n)
+{
+ int avail;
+
+ if (n < c) {
+ spin_lock_bh(&port->lock);
+ avail = dma_fifo_avail(&port->tx_fifo);
+ spin_unlock_bh(&port->lock);
+ fwtty_dbg(port, "short write: avail:%d req:%d wrote:%d",
+ avail, c, n);
+ }
+}
+#else
+#define debug_short_write(port, c, n)
+#endif
+
+static struct fwtty_peer *__fwserial_peer_by_node_id(struct fw_card *card,
+ int generation, int id);
+
+#ifdef FWTTY_PROFILING
+
+static void profile_fifo_avail(struct fwtty_port *port, unsigned *stat)
+{
+ spin_lock_bh(&port->lock);
+ profile_size_distrib(stat, dma_fifo_avail(&port->tx_fifo));
+ spin_unlock_bh(&port->lock);
+}
+
+static void dump_profile(struct seq_file *m, struct stats *stats)
+{
+ /* for each stat, print sum of 0 to 2^k, then individually */
+ int k = 4;
+ unsigned sum;
+ int j;
+ char t[10];
+
+ snprintf(t, 10, "< %d", 1 << k);
+ seq_printf(m, "\n%14s %6s", " ", t);
+ for (j = k + 1; j < DISTRIBUTION_MAX_INDEX; ++j)
+ seq_printf(m, "%6d", 1 << j);
+
+ ++k;
+ for (j = 0, sum = 0; j <= k; ++j)
+ sum += stats->reads[j];
+ seq_printf(m, "\n%14s: %6d", "reads", sum);
+ for (j = k + 1; j <= DISTRIBUTION_MAX_INDEX; ++j)
+ seq_printf(m, "%6d", stats->reads[j]);
+
+ for (j = 0, sum = 0; j <= k; ++j)
+ sum += stats->writes[j];
+ seq_printf(m, "\n%14s: %6d", "writes", sum);
+ for (j = k + 1; j <= DISTRIBUTION_MAX_INDEX; ++j)
+ seq_printf(m, "%6d", stats->writes[j]);
+
+ for (j = 0, sum = 0; j <= k; ++j)
+ sum += stats->txns[j];
+ seq_printf(m, "\n%14s: %6d", "txns", sum);
+ for (j = k + 1; j <= DISTRIBUTION_MAX_INDEX; ++j)
+ seq_printf(m, "%6d", stats->txns[j]);
+
+ for (j = 0, sum = 0; j <= k; ++j)
+ sum += stats->unthrottle[j];
+ seq_printf(m, "\n%14s: %6d", "avail @ unthr", sum);
+ for (j = k + 1; j <= DISTRIBUTION_MAX_INDEX; ++j)
+ seq_printf(m, "%6d", stats->unthrottle[j]);
+}
+
+#else
+#define profile_fifo_avail(port, stat)
+#define dump_profile(m, stats)
+#endif
+
+/* Returns the max receive packet size for the given card */
+static inline int device_max_receive(struct fw_device *fw_device)
+{
+ return 1 << (clamp_t(int, fw_device->max_rec, 8U, 13U) + 1);
+}
+
+static void fwtty_log_tx_error(struct fwtty_port *port, int rcode)
+{
+ switch (rcode) {
+ case RCODE_SEND_ERROR:
+ fwtty_err_ratelimited(port, "card busy");
+ break;
+ case RCODE_ADDRESS_ERROR:
+ fwtty_err_ratelimited(port, "bad unit addr or write length");
+ break;
+ case RCODE_DATA_ERROR:
+ fwtty_err_ratelimited(port, "failed rx");
+ break;
+ case RCODE_NO_ACK:
+ fwtty_err_ratelimited(port, "missing ack");
+ break;
+ case RCODE_BUSY:
+ fwtty_err_ratelimited(port, "remote busy");
+ break;
+ default:
+ fwtty_err_ratelimited(port, "failed tx: %d", rcode);
+ }
+}
+
+static void fwtty_txn_constructor(void *this)
+{
+ struct fwtty_transaction *txn = this;
+
+ init_timer(&txn->fw_txn.split_timeout_timer);
+}
+
+static void fwtty_common_callback(struct fw_card *card, int rcode,
+ void *payload, size_t len, void *cb_data)
+{
+ struct fwtty_transaction *txn = cb_data;
+ struct fwtty_port *port = txn->port;
+
+ if (port && rcode != RCODE_COMPLETE)
+ fwtty_log_tx_error(port, rcode);
+ if (txn->callback)
+ txn->callback(card, rcode, payload, len, txn);
+ kmem_cache_free(fwtty_txn_cache, txn);
+}
+
+static int fwtty_send_data_async(struct fwtty_peer *peer, int tcode,
+ unsigned long long addr, void *payload,
+ size_t len, fwtty_transaction_cb callback,
+ struct fwtty_port *port)
+{
+ struct fwtty_transaction *txn;
+ int generation;
+
+ txn = kmem_cache_alloc(fwtty_txn_cache, GFP_ATOMIC);
+ if (!txn)
+ return -ENOMEM;
+
+ txn->callback = callback;
+ txn->port = port;
+
+ generation = peer->generation;
+ smp_rmb();
+ fw_send_request(peer->serial->card, &txn->fw_txn, tcode,
+ peer->node_id, generation, peer->speed, addr, payload,
+ len, fwtty_common_callback, txn);
+ return 0;
+}
+
+static void fwtty_send_txn_async(struct fwtty_peer *peer,
+ struct fwtty_transaction *txn, int tcode,
+ unsigned long long addr, void *payload,
+ size_t len, fwtty_transaction_cb callback,
+ struct fwtty_port *port)
+{
+ int generation;
+
+ txn->callback = callback;
+ txn->port = port;
+
+ generation = peer->generation;
+ smp_rmb();
+ fw_send_request(peer->serial->card, &txn->fw_txn, tcode,
+ peer->node_id, generation, peer->speed, addr, payload,
+ len, fwtty_common_callback, txn);
+}
+
+
+static void __fwtty_restart_tx(struct fwtty_port *port)
+{
+ int len, avail;
+
+ len = dma_fifo_out_level(&port->tx_fifo);
+ if (len)
+ schedule_delayed_work(&port->drain, 0);
+ avail = dma_fifo_avail(&port->tx_fifo);
+
+ fwtty_dbg(port, "fifo len: %d avail: %d", len, avail);
+}
+
+static void fwtty_restart_tx(struct fwtty_port *port)
+{
+ spin_lock_bh(&port->lock);
+ __fwtty_restart_tx(port);
+ spin_unlock_bh(&port->lock);
+}
+
+/**
+ * fwtty_update_port_status - decodes & dispatches line status changes
+ *
+ * Note: in loopback, the port->lock is being held. Only use functions that
+ * don't attempt to reclaim the port->lock.
+ */
+static void fwtty_update_port_status(struct fwtty_port *port, unsigned status)
+{
+ unsigned delta;
+ struct tty_struct *tty;
+
+ /* simulated LSR/MSR status from remote */
+ status &= ~MCTRL_MASK;
+ delta = (port->mstatus ^ status) & ~MCTRL_MASK;
+ delta &= ~(status & TIOCM_RNG);
+ port->mstatus = status;
+
+ if (delta & TIOCM_RNG)
+ ++port->icount.rng;
+ if (delta & TIOCM_DSR)
+ ++port->icount.dsr;
+ if (delta & TIOCM_CAR)
+ ++port->icount.dcd;
+ if (delta & TIOCM_CTS)
+ ++port->icount.cts;
+
+ fwtty_dbg(port, "status: %x delta: %x", status, delta);
+
+ if (delta & TIOCM_CAR) {
+ tty = tty_port_tty_get(&port->port);
+ if (tty && !C_CLOCAL(tty)) {
+ if (status & TIOCM_CAR)
+ wake_up_interruptible(&port->port.open_wait);
+ else
+ schedule_work(&port->hangup);
+ }
+ tty_kref_put(tty);
+ }
+
+ if (delta & TIOCM_CTS) {
+ tty = tty_port_tty_get(&port->port);
+ if (tty && C_CRTSCTS(tty)) {
+ if (tty->hw_stopped) {
+ if (status & TIOCM_CTS) {
+ tty->hw_stopped = 0;
+ if (port->loopback)
+ __fwtty_restart_tx(port);
+ else
+ fwtty_restart_tx(port);
+ }
+ } else {
+ if (~status & TIOCM_CTS)
+ tty->hw_stopped = 1;
+ }
+ }
+ tty_kref_put(tty);
+
+ } else if (delta & OOB_TX_THROTTLE) {
+ tty = tty_port_tty_get(&port->port);
+ if (tty) {
+ if (tty->hw_stopped) {
+ if (~status & OOB_TX_THROTTLE) {
+ tty->hw_stopped = 0;
+ if (port->loopback)
+ __fwtty_restart_tx(port);
+ else
+ fwtty_restart_tx(port);
+ }
+ } else {
+ if (status & OOB_TX_THROTTLE)
+ tty->hw_stopped = 1;
+ }
+ }
+ tty_kref_put(tty);
+ }
+
+ if (delta & (UART_LSR_BI << 24)) {
+ if (status & (UART_LSR_BI << 24)) {
+ port->break_last = jiffies;
+ schedule_delayed_work(&port->emit_breaks, 0);
+ } else {
+ /* run emit_breaks one last time (if pending) */
+ mod_delayed_work(system_wq, &port->emit_breaks, 0);
+ }
+ }
+
+ if (delta & (TIOCM_DSR | TIOCM_CAR | TIOCM_CTS | TIOCM_RNG))
+ wake_up_interruptible(&port->port.delta_msr_wait);
+}
+
+/**
+ * __fwtty_port_line_status - generate 'line status' for indicated port
+ *
+ * This function returns a remote 'MSR' state based on the local 'MCR' state,
+ * as if a null modem cable was attached. The actual status is a mangling
+ * of TIOCM_* bits suitable for sending to a peer's status_addr.
+ *
+ * Note: caller must be holding port lock
+ */
+static unsigned __fwtty_port_line_status(struct fwtty_port *port)
+{
+ unsigned status = 0;
+
+ /* TODO: add module param to tie RNG to DTR as well */
+
+ if (port->mctrl & TIOCM_DTR)
+ status |= TIOCM_DSR | TIOCM_CAR;
+ if (port->mctrl & TIOCM_RTS)
+ status |= TIOCM_CTS;
+ if (port->mctrl & OOB_RX_THROTTLE)
+ status |= OOB_TX_THROTTLE;
+ /* emulate BRK as add'l line status */
+ if (port->break_ctl)
+ status |= UART_LSR_BI << 24;
+
+ return status;
+}
+
+/**
+ * __fwtty_write_port_status - send the port line status to peer
+ *
+ * Note: caller must be holding the port lock.
+ */
+static int __fwtty_write_port_status(struct fwtty_port *port)
+{
+ struct fwtty_peer *peer;
+ int err = -ENOENT;
+ unsigned status = __fwtty_port_line_status(port);
+
+ rcu_read_lock();
+ peer = rcu_dereference(port->peer);
+ if (peer) {
+ err = fwtty_send_data_async(peer, TCODE_WRITE_QUADLET_REQUEST,
+ peer->status_addr, &status,
+ sizeof(status), NULL, port);
+ }
+ rcu_read_unlock();
+
+ return err;
+}
+
+/**
+ * fwtty_write_port_status - same as above but locked by port lock
+ */
+static int fwtty_write_port_status(struct fwtty_port *port)
+{
+ int err;
+
+ spin_lock_bh(&port->lock);
+ err = __fwtty_write_port_status(port);
+ spin_unlock_bh(&port->lock);
+ return err;
+}
+
+static void __fwtty_throttle(struct fwtty_port *port, struct tty_struct *tty)
+{
+ unsigned old;
+
+ old = port->mctrl;
+ port->mctrl |= OOB_RX_THROTTLE;
+ if (C_CRTSCTS(tty))
+ port->mctrl &= ~TIOCM_RTS;
+ if (~old & OOB_RX_THROTTLE)
+ __fwtty_write_port_status(port);
+}
+
+/**
+ * fwtty_do_hangup - wait for ldisc to deliver all pending rx; only then hangup
+ *
+ * When the remote has finished tx, and all in-flight rx has been received and
+ * and pushed to the flip buffer, the remote may close its device. This will
+ * drop DTR on the remote which will drop carrier here. Typically, the tty is
+ * hung up when carrier is dropped or lost.
+ *
+ * However, there is a race between the hang up and the line discipline
+ * delivering its data to the reader. A hangup will cause the ldisc to flush
+ * (ie., clear) the read buffer and flip buffer. Because of firewire's
+ * relatively high throughput, the ldisc frequently lags well behind the driver,
+ * resulting in lost data (which has already been received and written to
+ * the flip buffer) when the remote closes its end.
+ *
+ * Unfortunately, since the flip buffer offers no direct method for determining
+ * if it holds data, ensuring the ldisc has delivered all data is problematic.
+ */
+
+/* FIXME: drop this workaround when __tty_hangup waits for ldisc completion */
+static void fwtty_do_hangup(struct work_struct *work)
+{
+ struct fwtty_port *port = to_port(work, hangup);
+ struct tty_struct *tty;
+
+ schedule_timeout_uninterruptible(msecs_to_jiffies(50));
+
+ tty = tty_port_tty_get(&port->port);
+ if (tty)
+ tty_vhangup(tty);
+ tty_kref_put(tty);
+}
+
+
+static void fwtty_emit_breaks(struct work_struct *work)
+{
+ struct fwtty_port *port = to_port(to_delayed_work(work), emit_breaks);
+ struct tty_struct *tty;
+ static const char buf[16];
+ unsigned long now = jiffies;
+ unsigned long elapsed = now - port->break_last;
+ int n, t, c, brk = 0;
+
+ tty = tty_port_tty_get(&port->port);
+ if (!tty)
+ return;
+
+ /* generate breaks at the line rate (but at least 1) */
+ n = (elapsed * port->cps) / HZ + 1;
+ port->break_last = now;
+
+ fwtty_dbg(port, "sending %d brks", n);
+
+ while (n) {
+ t = min(n, 16);
+ c = tty_insert_flip_string_fixed_flag(tty, buf, TTY_BREAK, t);
+ n -= c;
+ brk += c;
+ if (c < t)
+ break;
+ }
+ tty_flip_buffer_push(tty);
+
+ tty_kref_put(tty);
+
+ if (port->mstatus & (UART_LSR_BI << 24))
+ schedule_delayed_work(&port->emit_breaks, FREQ_BREAKS);
+ port->icount.brk += brk;
+}
+
+static void fwtty_pushrx(struct work_struct *work)
+{
+ struct fwtty_port *port = to_port(work, push);
+ struct tty_struct *tty;
+ struct buffered_rx *buf, *next;
+ int n, c = 0;
+
+ tty = tty_port_tty_get(&port->port);
+ if (!tty)
+ return;
+
+ spin_lock_bh(&port->lock);
+ list_for_each_entry_safe(buf, next, &port->buf_list, list) {
+ n = tty_insert_flip_string_fixed_flag(tty, buf->data,
+ TTY_NORMAL, buf->n);
+ c += n;
+ port->buffered -= n;
+ if (n < buf->n) {
+ if (n > 0) {
+ memmove(buf->data, buf->data + n, buf->n - n);
+ buf->n -= n;
+ }
+ __fwtty_throttle(port, tty);
+ break;
+ } else {
+ list_del(&buf->list);
+ kfree(buf);
+ }
+ }
+ if (c > 0)
+ tty_flip_buffer_push(tty);
+
+ if (list_empty(&port->buf_list))
+ clear_bit(BUFFERING_RX, &port->flags);
+ spin_unlock_bh(&port->lock);
+
+ tty_kref_put(tty);
+}
+
+static int fwtty_buffer_rx(struct fwtty_port *port, unsigned char *d, size_t n)
+{
+ struct buffered_rx *buf;
+ size_t size = (n + sizeof(struct buffered_rx) + 0xFF) & ~0xFF;
+
+ if (port->buffered + n > HIGH_WATERMARK)
+ return 0;
+ buf = kmalloc(size, GFP_ATOMIC);
+ if (!buf)
+ return 0;
+ INIT_LIST_HEAD(&buf->list);
+ buf->n = n;
+ memcpy(buf->data, d, n);
+
+ spin_lock_bh(&port->lock);
+ list_add_tail(&buf->list, &port->buf_list);
+ port->buffered += n;
+ if (port->buffered > port->stats.watermark)
+ port->stats.watermark = port->buffered;
+ set_bit(BUFFERING_RX, &port->flags);
+ spin_unlock_bh(&port->lock);
+
+ return n;
+}
+
+static int fwtty_rx(struct fwtty_port *port, unsigned char *data, size_t len)
+{
+ struct tty_struct *tty;
+ int c, n = len;
+ unsigned lsr;
+ int err = 0;
+
+ tty = tty_port_tty_get(&port->port);
+ if (!tty)
+ return -ENOENT;
+
+ fwtty_dbg(port, "%d", n);
+ profile_size_distrib(port->stats.reads, n);
+
+ if (port->write_only) {
+ n = 0;
+ goto out;
+ }
+
+ /* disregard break status; breaks are generated by emit_breaks work */
+ lsr = (port->mstatus >> 24) & ~UART_LSR_BI;
+
+ if (port->overrun)
+ lsr |= UART_LSR_OE;
+
+ if (lsr & UART_LSR_OE)
+ ++port->icount.overrun;
+
+ lsr &= port->status_mask;
+ if (lsr & ~port->ignore_mask & UART_LSR_OE) {
+ if (!tty_insert_flip_char(tty, 0, TTY_OVERRUN)) {
+ err = -EIO;
+ goto out;
+ }
+ }
+ port->overrun = false;
+
+ if (lsr & port->ignore_mask & ~UART_LSR_OE) {
+ /* TODO: don't drop SAK and Magic SysRq here */
+ n = 0;
+ goto out;
+ }
+
+ if (!test_bit(BUFFERING_RX, &port->flags)) {
+ c = tty_insert_flip_string_fixed_flag(tty, data, TTY_NORMAL, n);
+ if (c > 0)
+ tty_flip_buffer_push(tty);
+ n -= c;
+
+ if (n) {
+ /* start buffering and throttling */
+ n -= fwtty_buffer_rx(port, &data[c], n);
+
+ spin_lock_bh(&port->lock);
+ __fwtty_throttle(port, tty);
+ spin_unlock_bh(&port->lock);
+ }
+ } else
+ n -= fwtty_buffer_rx(port, data, n);
+
+ if (n) {
+ port->overrun = true;
+ err = -EIO;
+ }
+
+out:
+ tty_kref_put(tty);
+
+ port->icount.rx += len;
+ port->stats.lost += n;
+ return err;
+}
+
+/**
+ * fwtty_port_handler - bus address handler for port reads/writes
+ * @parameters: fw_address_callback_t as specified by firewire core interface
+ *
+ * This handler is responsible for handling inbound read/write dma from remotes.
+ */
+static void fwtty_port_handler(struct fw_card *card,
+ struct fw_request *request,
+ int tcode, int destination, int source,
+ int generation,
+ unsigned long long addr,
+ void *data, size_t len,
+ void *callback_data)
+{
+ struct fwtty_port *port = callback_data;
+ struct fwtty_peer *peer;
+ int err;
+ int rcode;
+
+ /* Only accept rx from the peer virtual-cabled to this port */
+ rcu_read_lock();
+ peer = __fwserial_peer_by_node_id(card, generation, source);
+ rcu_read_unlock();
+ if (!peer || peer != rcu_access_pointer(port->peer)) {
+ rcode = RCODE_ADDRESS_ERROR;
+ fwtty_err_ratelimited(port, "ignoring unauthenticated data");
+ goto respond;
+ }
+
+ switch (tcode) {
+ case TCODE_WRITE_QUADLET_REQUEST:
+ if (addr != port->rx_handler.offset || len != 4)
+ rcode = RCODE_ADDRESS_ERROR;
+ else {
+ fwtty_update_port_status(port, *(unsigned *)data);
+ rcode = RCODE_COMPLETE;
+ }
+ break;
+
+ case TCODE_WRITE_BLOCK_REQUEST:
+ if (addr != port->rx_handler.offset + 4 ||
+ len > port->rx_handler.length - 4) {
+ rcode = RCODE_ADDRESS_ERROR;
+ } else {
+ err = fwtty_rx(port, data, len);
+ switch (err) {
+ case 0:
+ rcode = RCODE_COMPLETE;
+ break;
+ case -EIO:
+ rcode = RCODE_DATA_ERROR;
+ break;
+ default:
+ rcode = RCODE_CONFLICT_ERROR;
+ break;
+ }
+ }
+ break;
+
+ default:
+ rcode = RCODE_TYPE_ERROR;
+ }
+
+respond:
+ fw_send_response(card, request, rcode);
+}
+
+/**
+ * fwtty_tx_complete - callback for tx dma
+ * @data: ignored, has no meaning for write txns
+ * @length: ignored, has no meaning for write txns
+ *
+ * The writer must be woken here if the fifo has been emptied because it
+ * may have slept if chars_in_buffer was != 0
+ */
+static void fwtty_tx_complete(struct fw_card *card, int rcode,
+ void *data, size_t length,
+ struct fwtty_transaction *txn)
+{
+ struct fwtty_port *port = txn->port;
+ struct tty_struct *tty;
+ int len;
+
+ fwtty_dbg(port, "rcode: %d", rcode);
+
+ switch (rcode) {
+ case RCODE_COMPLETE:
+ spin_lock_bh(&port->lock);
+ dma_fifo_out_complete(&port->tx_fifo, &txn->dma_pended);
+ len = dma_fifo_level(&port->tx_fifo);
+ spin_unlock_bh(&port->lock);
+
+ port->icount.tx += txn->dma_pended.len;
+ break;
+
+ default:
+ /* TODO: implement retries */
+ spin_lock_bh(&port->lock);
+ dma_fifo_out_complete(&port->tx_fifo, &txn->dma_pended);
+ len = dma_fifo_level(&port->tx_fifo);
+ spin_unlock_bh(&port->lock);
+
+ port->stats.dropped += txn->dma_pended.len;
+ }
+
+ if (len < WAKEUP_CHARS) {
+ tty = tty_port_tty_get(&port->port);
+ if (tty) {
+ tty_wakeup(tty);
+ tty_kref_put(tty);
+ }
+ }
+}
+
+static int fwtty_tx(struct fwtty_port *port, bool drain)
+{
+ struct fwtty_peer *peer;
+ struct fwtty_transaction *txn;
+ struct tty_struct *tty;
+ int n, len;
+
+ tty = tty_port_tty_get(&port->port);
+ if (!tty)
+ return -ENOENT;
+
+ rcu_read_lock();
+ peer = rcu_dereference(port->peer);
+ if (!peer) {
+ n = -EIO;
+ goto out;
+ }
+
+ if (test_and_set_bit(IN_TX, &port->flags)) {
+ n = -EALREADY;
+ goto out;
+ }
+
+ /* try to write as many dma transactions out as possible */
+ n = -EAGAIN;
+ while (!tty->stopped && !tty->hw_stopped &&
+ !test_bit(STOP_TX, &port->flags)) {
+ txn = kmem_cache_alloc(fwtty_txn_cache, GFP_ATOMIC);
+ if (!txn) {
+ n = -ENOMEM;
+ break;
+ }
+
+ spin_lock_bh(&port->lock);
+ n = dma_fifo_out_pend(&port->tx_fifo, &txn->dma_pended);
+ spin_unlock_bh(&port->lock);
+
+ fwtty_dbg(port, "out: %u rem: %d", txn->dma_pended.len, n);
+
+ if (n < 0) {
+ kmem_cache_free(fwtty_txn_cache, txn);
+ if (n == -EAGAIN)
+ ++port->stats.tx_stall;
+ else if (n == -ENODATA)
+ profile_size_distrib(port->stats.txns, 0);
+ else {
+ ++port->stats.fifo_errs;
+ fwtty_err_ratelimited(port, "fifo err: %d", n);
+ }
+ break;
+ }
+
+ profile_size_distrib(port->stats.txns, txn->dma_pended.len);
+
+ fwtty_send_txn_async(peer, txn, TCODE_WRITE_BLOCK_REQUEST,
+ peer->fifo_addr, txn->dma_pended.data,
+ txn->dma_pended.len, fwtty_tx_complete,
+ port);
+ ++port->stats.sent;
+
+ /*
+ * Stop tx if the 'last view' of the fifo is empty or if
+ * this is the writer and there's not enough data to bother
+ */
+ if (n == 0 || (!drain && n < WRITER_MINIMUM))
+ break;
+ }
+
+ if (n >= 0 || n == -EAGAIN || n == -ENOMEM || n == -ENODATA) {
+ spin_lock_bh(&port->lock);
+ len = dma_fifo_out_level(&port->tx_fifo);
+ if (len) {
+ unsigned long delay = (n == -ENOMEM) ? HZ : 1;
+ schedule_delayed_work(&port->drain, delay);
+ }
+ len = dma_fifo_level(&port->tx_fifo);
+ spin_unlock_bh(&port->lock);
+
+ /* wakeup the writer */
+ if (drain && len < WAKEUP_CHARS)
+ tty_wakeup(tty);
+ }
+
+ clear_bit(IN_TX, &port->flags);
+ wake_up_interruptible(&port->wait_tx);
+
+out:
+ rcu_read_unlock();
+ tty_kref_put(tty);
+ return n;
+}
+
+static void fwtty_drain_tx(struct work_struct *work)
+{
+ struct fwtty_port *port = to_port(to_delayed_work(work), drain);
+
+ fwtty_tx(port, true);
+}
+
+static void fwtty_write_xchar(struct fwtty_port *port, char ch)
+{
+ struct fwtty_peer *peer;
+
+ ++port->stats.xchars;
+
+ fwtty_dbg(port, "%02x", ch);
+
+ rcu_read_lock();
+ peer = rcu_dereference(port->peer);
+ if (peer) {
+ fwtty_send_data_async(peer, TCODE_WRITE_BLOCK_REQUEST,
+ peer->fifo_addr, &ch, sizeof(ch),
+ NULL, port);
+ }
+ rcu_read_unlock();
+}
+
+struct fwtty_port *fwtty_port_get(unsigned index)
+{
+ struct fwtty_port *port;
+
+ if (index >= MAX_TOTAL_PORTS)
+ return NULL;
+
+ mutex_lock(&port_table_lock);
+ port = port_table[index];
+ if (port)
+ kref_get(&port->serial->kref);
+ mutex_unlock(&port_table_lock);
+ return port;
+}
+EXPORT_SYMBOL(fwtty_port_get);
+
+static int fwtty_ports_add(struct fw_serial *serial)
+{
+ int err = -EBUSY;
+ int i, j;
+
+ if (port_table_corrupt)
+ return err;
+
+ mutex_lock(&port_table_lock);
+ for (i = 0; i + num_ports <= MAX_TOTAL_PORTS; i += num_ports) {
+ if (!port_table[i]) {
+ for (j = 0; j < num_ports; ++i, ++j) {
+ serial->ports[j]->index = i;
+ port_table[i] = serial->ports[j];
+ }
+ err = 0;
+ break;
+ }
+ }
+ mutex_unlock(&port_table_lock);
+ return err;
+}
+
+static void fwserial_destroy(struct kref *kref)
+{
+ struct fw_serial *serial = to_serial(kref, kref);
+ struct fwtty_port **ports = serial->ports;
+ int j, i = ports[0]->index;
+
+ synchronize_rcu();
+
+ mutex_lock(&port_table_lock);
+ for (j = 0; j < num_ports; ++i, ++j) {
+ port_table_corrupt |= port_table[i] != ports[j];
+ WARN_ONCE(port_table_corrupt, "port_table[%d]: %p != ports[%d]: %p",
+ i, port_table[i], j, ports[j]);
+
+ port_table[i] = NULL;
+ }
+ mutex_unlock(&port_table_lock);
+
+ for (j = 0; j < num_ports; ++j) {
+ fw_core_remove_address_handler(&ports[j]->rx_handler);
+ tty_port_destroy(&ports[j]->port);
+ kfree(ports[j]);
+ }
+ kfree(serial);
+}
+
+void fwtty_port_put(struct fwtty_port *port)
+{
+ kref_put(&port->serial->kref, fwserial_destroy);
+}
+EXPORT_SYMBOL(fwtty_port_put);
+
+static void fwtty_port_dtr_rts(struct tty_port *tty_port, int on)
+{
+ struct fwtty_port *port = to_port(tty_port, port);
+
+ fwtty_dbg(port, "on/off: %d", on);
+
+ spin_lock_bh(&port->lock);
+ /* Don't change carrier state if this is a console */
+ if (!port->port.console) {
+ if (on)
+ port->mctrl |= TIOCM_DTR | TIOCM_RTS;
+ else
+ port->mctrl &= ~(TIOCM_DTR | TIOCM_RTS);
+ }
+
+ __fwtty_write_port_status(port);
+ spin_unlock_bh(&port->lock);
+}
+
+/**
+ * fwtty_port_carrier_raised: required tty_port operation
+ *
+ * This port operation is polled after a tty has been opened and is waiting for
+ * carrier detect -- see drivers/tty/tty_port:tty_port_block_til_ready().
+ */
+static int fwtty_port_carrier_raised(struct tty_port *tty_port)
+{
+ struct fwtty_port *port = to_port(tty_port, port);
+ int rc;
+
+ rc = (port->mstatus & TIOCM_CAR);
+
+ fwtty_dbg(port, "%d", rc);
+
+ return rc;
+}
+
+static unsigned set_termios(struct fwtty_port *port, struct tty_struct *tty)
+{
+ unsigned baud, frame;
+
+ baud = tty_termios_baud_rate(&tty->termios);
+ tty_termios_encode_baud_rate(&tty->termios, baud, baud);
+
+ /* compute bit count of 2 frames */
+ frame = 12 + ((C_CSTOPB(tty)) ? 4 : 2) + ((C_PARENB(tty)) ? 2 : 0);
+
+ switch (C_CSIZE(tty)) {
+ case CS5:
+ frame -= (C_CSTOPB(tty)) ? 1 : 0;
+ break;
+ case CS6:
+ frame += 2;
+ break;
+ case CS7:
+ frame += 4;
+ break;
+ case CS8:
+ frame += 6;
+ break;
+ }
+
+ port->cps = (baud << 1) / frame;
+
+ port->status_mask = UART_LSR_OE;
+ if (_I_FLAG(tty, BRKINT | PARMRK))
+ port->status_mask |= UART_LSR_BI;
+
+ port->ignore_mask = 0;
+ if (I_IGNBRK(tty)) {
+ port->ignore_mask |= UART_LSR_BI;
+ if (I_IGNPAR(tty))
+ port->ignore_mask |= UART_LSR_OE;
+ }
+
+ port->write_only = !C_CREAD(tty);
+
+ /* turn off echo and newline xlat if loopback */
+ if (port->loopback) {
+ tty->termios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHOKE |
+ ECHONL | ECHOPRT | ECHOCTL);
+ tty->termios.c_oflag &= ~ONLCR;
+ }
+
+ return baud;
+}
+
+static int fwtty_port_activate(struct tty_port *tty_port,
+ struct tty_struct *tty)
+{
+ struct fwtty_port *port = to_port(tty_port, port);
+ unsigned baud;
+ int err;
+
+ set_bit(TTY_IO_ERROR, &tty->flags);
+
+ err = dma_fifo_alloc(&port->tx_fifo, FWTTY_PORT_TXFIFO_LEN,
+ cache_line_size(),
+ port->max_payload,
+ FWTTY_PORT_MAX_PEND_DMA,
+ GFP_KERNEL);
+ if (err)
+ return err;
+
+ spin_lock_bh(&port->lock);
+
+ baud = set_termios(port, tty);
+
+ /* if console, don't change carrier state */
+ if (!port->port.console) {
+ port->mctrl = 0;
+ if (baud != 0)
+ port->mctrl = TIOCM_DTR | TIOCM_RTS;
+ }
+
+ if (C_CRTSCTS(tty) && ~port->mstatus & TIOCM_CTS)
+ tty->hw_stopped = 1;
+
+ __fwtty_write_port_status(port);
+ spin_unlock_bh(&port->lock);
+
+ clear_bit(TTY_IO_ERROR, &tty->flags);
+
+ return 0;
+}
+
+/**
+ * fwtty_port_shutdown
+ *
+ * Note: the tty port core ensures this is not the console and
+ * manages TTY_IO_ERROR properly
+ */
+static void fwtty_port_shutdown(struct tty_port *tty_port)
+{
+ struct fwtty_port *port = to_port(tty_port, port);
+ struct buffered_rx *buf, *next;
+
+ /* TODO: cancel outstanding transactions */
+
+ cancel_delayed_work_sync(&port->emit_breaks);
+ cancel_delayed_work_sync(&port->drain);
+ cancel_work_sync(&port->push);
+
+ spin_lock_bh(&port->lock);
+ list_for_each_entry_safe(buf, next, &port->buf_list, list) {
+ list_del(&buf->list);
+ kfree(buf);
+ }
+ port->buffered = 0;
+ port->flags = 0;
+ port->break_ctl = 0;
+ port->overrun = 0;
+ __fwtty_write_port_status(port);
+ dma_fifo_free(&port->tx_fifo);
+ spin_unlock_bh(&port->lock);
+}
+
+static int fwtty_open(struct tty_struct *tty, struct file *fp)
+{
+ struct fwtty_port *port = tty->driver_data;
+
+ return tty_port_open(&port->port, tty, fp);
+}
+
+static void fwtty_close(struct tty_struct *tty, struct file *fp)
+{
+ struct fwtty_port *port = tty->driver_data;
+
+ tty_port_close(&port->port, tty, fp);
+}
+
+static void fwtty_hangup(struct tty_struct *tty)
+{
+ struct fwtty_port *port = tty->driver_data;
+
+ tty_port_hangup(&port->port);
+}
+
+static void fwtty_cleanup(struct tty_struct *tty)
+{
+ struct fwtty_port *port = tty->driver_data;
+
+ tty->driver_data = NULL;
+ fwtty_port_put(port);
+}
+
+static int fwtty_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+ struct fwtty_port *port = fwtty_port_get(tty->index);
+ int err;
+
+ err = tty_standard_install(driver, tty);
+ if (!err)
+ tty->driver_data = port;
+ else
+ fwtty_port_put(port);
+ return err;
+}
+
+static int fwtty_write(struct tty_struct *tty, const unsigned char *buf, int c)
+{
+ struct fwtty_port *port = tty->driver_data;
+ int n, len;
+
+ fwtty_dbg(port, "%d", c);
+ profile_size_distrib(port->stats.writes, c);
+
+ spin_lock_bh(&port->lock);
+ n = dma_fifo_in(&port->tx_fifo, buf, c);
+ len = dma_fifo_out_level(&port->tx_fifo);
+ if (len < DRAIN_THRESHOLD)
+ schedule_delayed_work(&port->drain, 1);
+ spin_unlock_bh(&port->lock);
+
+ if (len >= DRAIN_THRESHOLD)
+ fwtty_tx(port, false);
+
+ debug_short_write(port, c, n);
+
+ return (n < 0) ? 0 : n;
+}
+
+static int fwtty_write_room(struct tty_struct *tty)
+{
+ struct fwtty_port *port = tty->driver_data;
+ int n;
+
+ spin_lock_bh(&port->lock);
+ n = dma_fifo_avail(&port->tx_fifo);
+ spin_unlock_bh(&port->lock);
+
+ fwtty_dbg(port, "%d", n);
+
+ return n;
+}
+
+static int fwtty_chars_in_buffer(struct tty_struct *tty)
+{
+ struct fwtty_port *port = tty->driver_data;
+ int n;
+
+ spin_lock_bh(&port->lock);
+ n = dma_fifo_level(&port->tx_fifo);
+ spin_unlock_bh(&port->lock);
+
+ fwtty_dbg(port, "%d", n);
+
+ return n;
+}
+
+static void fwtty_send_xchar(struct tty_struct *tty, char ch)
+{
+ struct fwtty_port *port = tty->driver_data;
+
+ fwtty_dbg(port, "%02x", ch);
+
+ fwtty_write_xchar(port, ch);
+}
+
+static void fwtty_throttle(struct tty_struct *tty)
+{
+ struct fwtty_port *port = tty->driver_data;
+
+ /*
+ * Ignore throttling (but not unthrottling).
+ * It only makes sense to throttle when data will no longer be
+ * accepted by the tty flip buffer. For example, it is
+ * possible for received data to overflow the tty buffer long
+ * before the line discipline ever has a chance to throttle the driver.
+ * Additionally, the driver may have already completed the I/O
+ * but the tty buffer is still emptying, so the line discipline is
+ * throttling and unthrottling nothing.
+ */
+
+ ++port->stats.throttled;
+}
+
+static void fwtty_unthrottle(struct tty_struct *tty)
+{
+ struct fwtty_port *port = tty->driver_data;
+
+ fwtty_dbg(port, "CRTSCTS: %d", (C_CRTSCTS(tty) != 0));
+
+ profile_fifo_avail(port, port->stats.unthrottle);
+
+ schedule_work(&port->push);
+
+ spin_lock_bh(&port->lock);
+ port->mctrl &= ~OOB_RX_THROTTLE;
+ if (C_CRTSCTS(tty))
+ port->mctrl |= TIOCM_RTS;
+ __fwtty_write_port_status(port);
+ spin_unlock_bh(&port->lock);
+}
+
+static int check_msr_delta(struct fwtty_port *port, unsigned long mask,
+ struct async_icount *prev)
+{
+ struct async_icount now;
+ int delta;
+
+ now = port->icount;
+
+ delta = ((mask & TIOCM_RNG && prev->rng != now.rng) ||
+ (mask & TIOCM_DSR && prev->dsr != now.dsr) ||
+ (mask & TIOCM_CAR && prev->dcd != now.dcd) ||
+ (mask & TIOCM_CTS && prev->cts != now.cts));
+
+ *prev = now;
+
+ return delta;
+}
+
+static int wait_msr_change(struct fwtty_port *port, unsigned long mask)
+{
+ struct async_icount prev;
+
+ prev = port->icount;
+
+ return wait_event_interruptible(port->port.delta_msr_wait,
+ check_msr_delta(port, mask, &prev));
+}
+
+static int get_serial_info(struct fwtty_port *port,
+ struct serial_struct __user *info)
+{
+ struct serial_struct tmp;
+
+ memset(&tmp, 0, sizeof(tmp));
+
+ tmp.type = PORT_UNKNOWN;
+ tmp.line = port->port.tty->index;
+ tmp.flags = port->port.flags;
+ tmp.xmit_fifo_size = FWTTY_PORT_TXFIFO_LEN;
+ tmp.baud_base = 400000000;
+ tmp.close_delay = port->port.close_delay;
+
+ return (copy_to_user(info, &tmp, sizeof(*info))) ? -EFAULT : 0;
+}
+
+static int set_serial_info(struct fwtty_port *port,
+ struct serial_struct __user *info)
+{
+ struct serial_struct tmp;
+
+ if (copy_from_user(&tmp, info, sizeof(tmp)))
+ return -EFAULT;
+
+ if (tmp.irq != 0 || tmp.port != 0 || tmp.custom_divisor != 0 ||
+ tmp.baud_base != 400000000)
+ return -EPERM;
+
+ if (!capable(CAP_SYS_ADMIN)) {
+ if (((tmp.flags & ~ASYNC_USR_MASK) !=
+ (port->port.flags & ~ASYNC_USR_MASK)))
+ return -EPERM;
+ } else
+ port->port.close_delay = tmp.close_delay * HZ / 100;
+
+ return 0;
+}
+
+static int fwtty_ioctl(struct tty_struct *tty, unsigned cmd,
+ unsigned long arg)
+{
+ struct fwtty_port *port = tty->driver_data;
+ int err;
+
+ switch (cmd) {
+ case TIOCGSERIAL:
+ mutex_lock(&port->port.mutex);
+ err = get_serial_info(port, (void __user *)arg);
+ mutex_unlock(&port->port.mutex);
+ break;
+
+ case TIOCSSERIAL:
+ mutex_lock(&port->port.mutex);
+ err = set_serial_info(port, (void __user *)arg);
+ mutex_unlock(&port->port.mutex);
+ break;
+
+ case TIOCMIWAIT:
+ err = wait_msr_change(port, arg);
+ break;
+
+ default:
+ err = -ENOIOCTLCMD;
+ }
+
+ return err;
+}
+
+static void fwtty_set_termios(struct tty_struct *tty, struct ktermios *old)
+{
+ struct fwtty_port *port = tty->driver_data;
+ unsigned baud;
+
+ spin_lock_bh(&port->lock);
+ baud = set_termios(port, tty);
+
+ if ((baud == 0) && (old->c_cflag & CBAUD))
+ port->mctrl &= ~(TIOCM_DTR | TIOCM_RTS);
+ else if ((baud != 0) && !(old->c_cflag & CBAUD)) {
+ if (C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags))
+ port->mctrl |= TIOCM_DTR | TIOCM_RTS;
+ else
+ port->mctrl |= TIOCM_DTR;
+ }
+ __fwtty_write_port_status(port);
+ spin_unlock_bh(&port->lock);
+
+ if (old->c_cflag & CRTSCTS) {
+ if (!C_CRTSCTS(tty)) {
+ tty->hw_stopped = 0;
+ fwtty_restart_tx(port);
+ }
+ } else if (C_CRTSCTS(tty) && ~port->mstatus & TIOCM_CTS) {
+ tty->hw_stopped = 1;
+ }
+}
+
+/**
+ * fwtty_break_ctl - start/stop sending breaks
+ *
+ * Signals the remote to start or stop generating simulated breaks.
+ * First, stop dequeueing from the fifo and wait for writer/drain to leave tx
+ * before signalling the break line status. This guarantees any pending rx will
+ * be queued to the line discipline before break is simulated on the remote.
+ * Conversely, turning off break_ctl requires signalling the line status change,
+ * then enabling tx.
+ */
+static int fwtty_break_ctl(struct tty_struct *tty, int state)
+{
+ struct fwtty_port *port = tty->driver_data;
+ long ret;
+
+ fwtty_dbg(port, "%d", state);
+
+ if (state == -1) {
+ set_bit(STOP_TX, &port->flags);
+ ret = wait_event_interruptible_timeout(port->wait_tx,
+ !test_bit(IN_TX, &port->flags),
+ 10);
+ if (ret == 0 || ret == -ERESTARTSYS) {
+ clear_bit(STOP_TX, &port->flags);
+ fwtty_restart_tx(port);
+ return -EINTR;
+ }
+ }
+
+ spin_lock_bh(&port->lock);
+ port->break_ctl = (state == -1);
+ __fwtty_write_port_status(port);
+ spin_unlock_bh(&port->lock);
+
+ if (state == 0) {
+ spin_lock_bh(&port->lock);
+ dma_fifo_reset(&port->tx_fifo);
+ clear_bit(STOP_TX, &port->flags);
+ spin_unlock_bh(&port->lock);
+ }
+ return 0;
+}
+
+static int fwtty_tiocmget(struct tty_struct *tty)
+{
+ struct fwtty_port *port = tty->driver_data;
+ unsigned tiocm;
+
+ spin_lock_bh(&port->lock);
+ tiocm = (port->mctrl & MCTRL_MASK) | (port->mstatus & ~MCTRL_MASK);
+ spin_unlock_bh(&port->lock);
+
+ fwtty_dbg(port, "%x", tiocm);
+
+ return tiocm;
+}
+
+static int fwtty_tiocmset(struct tty_struct *tty, unsigned set, unsigned clear)
+{
+ struct fwtty_port *port = tty->driver_data;
+
+ fwtty_dbg(port, "set: %x clear: %x", set, clear);
+
+ /* TODO: simulate loopback if TIOCM_LOOP set */
+
+ spin_lock_bh(&port->lock);
+ port->mctrl &= ~(clear & MCTRL_MASK & 0xffff);
+ port->mctrl |= set & MCTRL_MASK & 0xffff;
+ __fwtty_write_port_status(port);
+ spin_unlock_bh(&port->lock);
+ return 0;
+}
+
+static int fwtty_get_icount(struct tty_struct *tty,
+ struct serial_icounter_struct *icount)
+{
+ struct fwtty_port *port = tty->driver_data;
+ struct stats stats;
+
+ memcpy(&stats, &port->stats, sizeof(stats));
+ if (port->port.console)
+ (*port->fwcon_ops->stats)(&stats, port->con_data);
+
+ icount->cts = port->icount.cts;
+ icount->dsr = port->icount.dsr;
+ icount->rng = port->icount.rng;
+ icount->dcd = port->icount.dcd;
+ icount->rx = port->icount.rx;
+ icount->tx = port->icount.tx + stats.xchars;
+ icount->frame = port->icount.frame;
+ icount->overrun = port->icount.overrun;
+ icount->parity = port->icount.parity;
+ icount->brk = port->icount.brk;
+ icount->buf_overrun = port->icount.overrun;
+ return 0;
+}
+
+static void fwtty_proc_show_port(struct seq_file *m, struct fwtty_port *port)
+{
+ struct stats stats;
+
+ memcpy(&stats, &port->stats, sizeof(stats));
+ if (port->port.console)
+ (*port->fwcon_ops->stats)(&stats, port->con_data);
+
+ seq_printf(m, " tx:%d rx:%d", port->icount.tx + stats.xchars,
+ port->icount.rx);
+ seq_printf(m, " cts:%d dsr:%d rng:%d dcd:%d", port->icount.cts,
+ port->icount.dsr, port->icount.rng, port->icount.dcd);
+ seq_printf(m, " fe:%d oe:%d pe:%d brk:%d", port->icount.frame,
+ port->icount.overrun, port->icount.parity, port->icount.brk);
+ seq_printf(m, " dr:%d st:%d err:%d lost:%d", stats.dropped,
+ stats.tx_stall, stats.fifo_errs, stats.lost);
+ seq_printf(m, " pkts:%d thr:%d wtrmk:%d", stats.sent, stats.throttled,
+ stats.watermark);
+ seq_printf(m, " addr:%012llx", port->rx_handler.offset);
+
+ if (port->port.console) {
+ seq_printf(m, "\n ");
+ (*port->fwcon_ops->proc_show)(m, port->con_data);
+ }
+
+ dump_profile(m, &port->stats);
+}
+
+static void fwtty_proc_show_peer(struct seq_file *m, struct fwtty_peer *peer)
+{
+ int generation = peer->generation;
+
+ smp_rmb();
+ seq_printf(m, " %s:", dev_name(&peer->unit->device));
+ seq_printf(m, " node:%04x gen:%d", peer->node_id, generation);
+ seq_printf(m, " sp:%d max:%d guid:%016llx", peer->speed,
+ peer->max_payload, (unsigned long long) peer->guid);
+
+ if (capable(CAP_SYS_ADMIN)) {
+ seq_printf(m, " mgmt:%012llx",
+ (unsigned long long) peer->mgmt_addr);
+ seq_printf(m, " addr:%012llx",
+ (unsigned long long) peer->status_addr);
+ }
+ seq_putc(m, '\n');
+}
+
+static int fwtty_proc_show(struct seq_file *m, void *v)
+{
+ struct fwtty_port *port;
+ struct fw_serial *serial;
+ struct fwtty_peer *peer;
+ int i;
+
+ seq_puts(m, "fwserinfo: 1.0 driver: 1.0\n");
+ for (i = 0; i < MAX_TOTAL_PORTS && (port = fwtty_port_get(i)); ++i) {
+ seq_printf(m, "%2d:", i);
+ if (capable(CAP_SYS_ADMIN))
+ fwtty_proc_show_port(m, port);
+ fwtty_port_put(port);
+ seq_printf(m, "\n");
+ }
+ seq_putc(m, '\n');
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(serial, &fwserial_list, list) {
+ seq_printf(m, "card: %s guid: %016llx\n",
+ dev_name(serial->card->device),
+ (unsigned long long) serial->card->guid);
+ list_for_each_entry_rcu(peer, &serial->peer_list, list)
+ fwtty_proc_show_peer(m, peer);
+ }
+ rcu_read_unlock();
+ return 0;
+}
+
+static int fwtty_proc_open(struct inode *inode, struct file *fp)
+{
+ return single_open(fp, fwtty_proc_show, NULL);
+}
+
+static const struct file_operations fwtty_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = fwtty_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static const struct tty_port_operations fwtty_port_ops = {
+ .dtr_rts = fwtty_port_dtr_rts,
+ .carrier_raised = fwtty_port_carrier_raised,
+ .shutdown = fwtty_port_shutdown,
+ .activate = fwtty_port_activate,
+};
+
+static const struct tty_operations fwtty_ops = {
+ .open = fwtty_open,
+ .close = fwtty_close,
+ .hangup = fwtty_hangup,
+ .cleanup = fwtty_cleanup,
+ .install = fwtty_install,
+ .write = fwtty_write,
+ .write_room = fwtty_write_room,
+ .chars_in_buffer = fwtty_chars_in_buffer,
+ .send_xchar = fwtty_send_xchar,
+ .throttle = fwtty_throttle,
+ .unthrottle = fwtty_unthrottle,
+ .ioctl = fwtty_ioctl,
+ .set_termios = fwtty_set_termios,
+ .break_ctl = fwtty_break_ctl,
+ .tiocmget = fwtty_tiocmget,
+ .tiocmset = fwtty_tiocmset,
+ .get_icount = fwtty_get_icount,
+ .proc_fops = &fwtty_proc_fops,
+};
+
+static inline int mgmt_pkt_expected_len(__be16 code)
+{
+ static const struct fwserial_mgmt_pkt pkt;
+
+ switch (be16_to_cpu(code)) {
+ case FWSC_VIRT_CABLE_PLUG:
+ return sizeof(pkt.hdr) + sizeof(pkt.plug_req);
+
+ case FWSC_VIRT_CABLE_PLUG_RSP: /* | FWSC_RSP_OK */
+ return sizeof(pkt.hdr) + sizeof(pkt.plug_rsp);
+
+
+ case FWSC_VIRT_CABLE_UNPLUG:
+ case FWSC_VIRT_CABLE_UNPLUG_RSP:
+ case FWSC_VIRT_CABLE_PLUG_RSP | FWSC_RSP_NACK:
+ case FWSC_VIRT_CABLE_UNPLUG_RSP | FWSC_RSP_NACK:
+ return sizeof(pkt.hdr);
+
+ default:
+ return -1;
+ }
+}
+
+static inline void fill_plug_params(struct virt_plug_params *params,
+ struct fwtty_port *port)
+{
+ u64 status_addr = port->rx_handler.offset;
+ u64 fifo_addr = port->rx_handler.offset + 4;
+ size_t fifo_len = port->rx_handler.length - 4;
+
+ params->status_hi = cpu_to_be32(status_addr >> 32);
+ params->status_lo = cpu_to_be32(status_addr);
+ params->fifo_hi = cpu_to_be32(fifo_addr >> 32);
+ params->fifo_lo = cpu_to_be32(fifo_addr);
+ params->fifo_len = cpu_to_be32(fifo_len);
+}
+
+static inline void fill_plug_req(struct fwserial_mgmt_pkt *pkt,
+ struct fwtty_port *port)
+{
+ pkt->hdr.code = cpu_to_be16(FWSC_VIRT_CABLE_PLUG);
+ pkt->hdr.len = cpu_to_be16(mgmt_pkt_expected_len(pkt->hdr.code));
+ fill_plug_params(&pkt->plug_req, port);
+}
+
+static inline void fill_plug_rsp_ok(struct fwserial_mgmt_pkt *pkt,
+ struct fwtty_port *port)
+{
+ pkt->hdr.code = cpu_to_be16(FWSC_VIRT_CABLE_PLUG_RSP);
+ pkt->hdr.len = cpu_to_be16(mgmt_pkt_expected_len(pkt->hdr.code));
+ fill_plug_params(&pkt->plug_rsp, port);
+}
+
+static inline void fill_plug_rsp_nack(struct fwserial_mgmt_pkt *pkt)
+{
+ pkt->hdr.code = cpu_to_be16(FWSC_VIRT_CABLE_PLUG_RSP | FWSC_RSP_NACK);
+ pkt->hdr.len = cpu_to_be16(mgmt_pkt_expected_len(pkt->hdr.code));
+}
+
+static inline void fill_unplug_req(struct fwserial_mgmt_pkt *pkt)
+{
+ pkt->hdr.code = cpu_to_be16(FWSC_VIRT_CABLE_UNPLUG);
+ pkt->hdr.len = cpu_to_be16(mgmt_pkt_expected_len(pkt->hdr.code));
+}
+
+static inline void fill_unplug_rsp_nack(struct fwserial_mgmt_pkt *pkt)
+{
+ pkt->hdr.code = cpu_to_be16(FWSC_VIRT_CABLE_UNPLUG_RSP | FWSC_RSP_NACK);
+ pkt->hdr.len = cpu_to_be16(mgmt_pkt_expected_len(pkt->hdr.code));
+}
+
+static inline void fill_unplug_rsp_ok(struct fwserial_mgmt_pkt *pkt)
+{
+ pkt->hdr.code = cpu_to_be16(FWSC_VIRT_CABLE_UNPLUG_RSP);
+ pkt->hdr.len = cpu_to_be16(mgmt_pkt_expected_len(pkt->hdr.code));
+}
+
+static void fwserial_virt_plug_complete(struct fwtty_peer *peer,
+ struct virt_plug_params *params)
+{
+ struct fwtty_port *port = peer->port;
+
+ peer->status_addr = be32_to_u64(params->status_hi, params->status_lo);
+ peer->fifo_addr = be32_to_u64(params->fifo_hi, params->fifo_lo);
+ peer->fifo_len = be32_to_cpu(params->fifo_len);
+ peer_set_state(peer, FWPS_ATTACHED);
+
+ /* reconfigure tx_fifo optimally for this peer */
+ spin_lock_bh(&port->lock);
+ port->max_payload = min3(peer->max_payload, peer->fifo_len,
+ MAX_ASYNC_PAYLOAD);
+ dma_fifo_change_tx_limit(&port->tx_fifo, port->max_payload);
+ spin_unlock_bh(&peer->port->lock);
+
+ if (port->port.console && port->fwcon_ops->notify != NULL)
+ (*port->fwcon_ops->notify)(FWCON_NOTIFY_ATTACH, port->con_data);
+
+ fwtty_info(&peer->unit, "peer (guid:%016llx) connected on %s",
+ (unsigned long long)peer->guid, dev_name(port->device));
+}
+
+static inline int fwserial_send_mgmt_sync(struct fwtty_peer *peer,
+ struct fwserial_mgmt_pkt *pkt)
+{
+ int generation;
+ int rcode, tries = 5;
+
+ do {
+ generation = peer->generation;
+ smp_rmb();
+
+ rcode = fw_run_transaction(peer->serial->card,
+ TCODE_WRITE_BLOCK_REQUEST,
+ peer->node_id,
+ generation, peer->speed,
+ peer->mgmt_addr,
+ pkt, be16_to_cpu(pkt->hdr.len));
+ if (rcode == RCODE_BUSY || rcode == RCODE_SEND_ERROR ||
+ rcode == RCODE_GENERATION) {
+ fwtty_dbg(&peer->unit, "mgmt write error: %d", rcode);
+ continue;
+ } else
+ break;
+ } while (--tries > 0);
+ return rcode;
+}
+
+/**
+ * fwserial_claim_port - attempt to claim port @ index for peer
+ *
+ * Returns ptr to claimed port or error code (as ERR_PTR())
+ * Can sleep - must be called from process context
+ */
+static struct fwtty_port *fwserial_claim_port(struct fwtty_peer *peer,
+ int index)
+{
+ struct fwtty_port *port;
+
+ if (index < 0 || index >= num_ports)
+ return ERR_PTR(-EINVAL);
+
+ /* must guarantee that previous port releases have completed */
+ synchronize_rcu();
+
+ port = peer->serial->ports[index];
+ spin_lock_bh(&port->lock);
+ if (!rcu_access_pointer(port->peer))
+ rcu_assign_pointer(port->peer, peer);
+ else
+ port = ERR_PTR(-EBUSY);
+ spin_unlock_bh(&port->lock);
+
+ return port;
+}
+
+/**
+ * fwserial_find_port - find avail port and claim for peer
+ *
+ * Returns ptr to claimed port or NULL if none avail
+ * Can sleep - must be called from process context
+ */
+static struct fwtty_port *fwserial_find_port(struct fwtty_peer *peer)
+{
+ struct fwtty_port **ports = peer->serial->ports;
+ int i;
+
+ /* must guarantee that previous port releases have completed */
+ synchronize_rcu();
+
+ /* TODO: implement optional GUID-to-specific port # matching */
+
+ /* find an unattached port (but not the loopback port, if present) */
+ for (i = 0; i < num_ttys; ++i) {
+ spin_lock_bh(&ports[i]->lock);
+ if (!ports[i]->peer) {
+ /* claim port */
+ rcu_assign_pointer(ports[i]->peer, peer);
+ spin_unlock_bh(&ports[i]->lock);
+ return ports[i];
+ }
+ spin_unlock_bh(&ports[i]->lock);
+ }
+ return NULL;
+}
+
+static void fwserial_release_port(struct fwtty_port *port)
+{
+ /* drop carrier (and all other line status) */
+ fwtty_update_port_status(port, 0);
+
+ spin_lock_bh(&port->lock);
+
+ /* reset dma fifo max transmission size back to S100 */
+ port->max_payload = link_speed_to_max_payload(SCODE_100);
+ dma_fifo_change_tx_limit(&port->tx_fifo, port->max_payload);
+
+ rcu_assign_pointer(port->peer, NULL);
+ spin_unlock_bh(&port->lock);
+
+ if (port->port.console && port->fwcon_ops->notify != NULL)
+ (*port->fwcon_ops->notify)(FWCON_NOTIFY_DETACH, port->con_data);
+}
+
+static void fwserial_plug_timeout(unsigned long data)
+{
+ struct fwtty_peer *peer = (struct fwtty_peer *) data;
+ struct fwtty_port *port;
+
+ spin_lock_bh(&peer->lock);
+ if (peer->state != FWPS_PLUG_PENDING) {
+ spin_unlock_bh(&peer->lock);
+ return;
+ }
+
+ port = peer_revert_state(peer);
+ spin_unlock_bh(&peer->lock);
+
+ if (port)
+ fwserial_release_port(port);
+}
+
+/**
+ * fwserial_connect_peer - initiate virtual cable with peer
+ *
+ * Returns 0 if VIRT_CABLE_PLUG request was successfully sent,
+ * otherwise error code. Must be called from process context.
+ */
+static int fwserial_connect_peer(struct fwtty_peer *peer)
+{
+ struct fwtty_port *port;
+ struct fwserial_mgmt_pkt *pkt;
+ int err, rcode;
+
+ pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
+ if (!pkt)
+ return -ENOMEM;
+
+ port = fwserial_find_port(peer);
+ if (!port) {
+ fwtty_err(&peer->unit, "avail ports in use");
+ err = -EBUSY;
+ goto free_pkt;
+ }
+
+ spin_lock_bh(&peer->lock);
+
+ /* only initiate VIRT_CABLE_PLUG if peer is currently not attached */
+ if (peer->state != FWPS_NOT_ATTACHED) {
+ err = -EBUSY;
+ goto release_port;
+ }
+
+ peer->port = port;
+ peer_set_state(peer, FWPS_PLUG_PENDING);
+
+ fill_plug_req(pkt, peer->port);
+
+ setup_timer(&peer->timer, fwserial_plug_timeout, (unsigned long)peer);
+ mod_timer(&peer->timer, jiffies + VIRT_CABLE_PLUG_TIMEOUT);
+ spin_unlock_bh(&peer->lock);
+
+ rcode = fwserial_send_mgmt_sync(peer, pkt);
+
+ spin_lock_bh(&peer->lock);
+ if (peer->state == FWPS_PLUG_PENDING && rcode != RCODE_COMPLETE) {
+ if (rcode == RCODE_CONFLICT_ERROR)
+ err = -EAGAIN;
+ else
+ err = -EIO;
+ goto cancel_timer;
+ }
+ spin_unlock_bh(&peer->lock);
+
+ kfree(pkt);
+ return 0;
+
+cancel_timer:
+ del_timer(&peer->timer);
+ peer_revert_state(peer);
+release_port:
+ spin_unlock_bh(&peer->lock);
+ fwserial_release_port(port);
+free_pkt:
+ kfree(pkt);
+ return err;
+}
+
+/**
+ * fwserial_close_port -
+ * HUP the tty (if the tty exists) and unregister the tty device.
+ * Only used by the unit driver upon unit removal to disconnect and
+ * cleanup all attached ports
+ *
+ * The port reference is put by fwtty_cleanup (if a reference was
+ * ever taken).
+ */
+static void fwserial_close_port(struct fwtty_port *port)
+{
+ struct tty_struct *tty;
+
+ mutex_lock(&port->port.mutex);
+ tty = tty_port_tty_get(&port->port);
+ if (tty) {
+ tty_vhangup(tty);
+ tty_kref_put(tty);
+ }
+ mutex_unlock(&port->port.mutex);
+
+ tty_unregister_device(fwtty_driver, port->index);
+}
+
+/**
+ * fwserial_lookup - finds first fw_serial associated with card
+ * @card: fw_card to match
+ *
+ * NB: caller must be holding fwserial_list_mutex
+ */
+static struct fw_serial *fwserial_lookup(struct fw_card *card)
+{
+ struct fw_serial *serial;
+
+ list_for_each_entry(serial, &fwserial_list, list) {
+ if (card == serial->card)
+ return serial;
+ }
+
+ return NULL;
+}
+
+/**
+ * __fwserial_lookup_rcu - finds first fw_serial associated with card
+ * @card: fw_card to match
+ *
+ * NB: caller must be inside rcu_read_lock() section
+ */
+static struct fw_serial *__fwserial_lookup_rcu(struct fw_card *card)
+{
+ struct fw_serial *serial;
+
+ list_for_each_entry_rcu(serial, &fwserial_list, list) {
+ if (card == serial->card)
+ return serial;
+ }
+
+ return NULL;
+}
+
+/**
+ * __fwserial_peer_by_node_id - finds a peer matching the given generation + id
+ *
+ * If a matching peer could not be found for the specified generation/node id,
+ * this could be because:
+ * a) the generation has changed and one of the nodes hasn't updated yet
+ * b) the remote node has created its remote unit device before this
+ * local node has created its corresponding remote unit device
+ * In either case, the remote node should retry
+ *
+ * Note: caller must be in rcu_read_lock() section
+ */
+static struct fwtty_peer *__fwserial_peer_by_node_id(struct fw_card *card,
+ int generation, int id)
+{
+ struct fw_serial *serial;
+ struct fwtty_peer *peer;
+
+ serial = __fwserial_lookup_rcu(card);
+ if (!serial) {
+ /*
+ * Something is very wrong - there should be a matching
+ * fw_serial structure for every fw_card. Maybe the remote node
+ * has created its remote unit device before this driver has
+ * been probed for any unit devices...
+ */
+ fwtty_err(card, "unknown card (guid %016llx)",
+ (unsigned long long) card->guid);
+ return NULL;
+ }
+
+ list_for_each_entry_rcu(peer, &serial->peer_list, list) {
+ int g = peer->generation;
+ smp_rmb();
+ if (generation == g && id == peer->node_id)
+ return peer;
+ }
+
+ return NULL;
+}
+
+#ifdef DEBUG
+static void __dump_peer_list(struct fw_card *card)
+{
+ struct fw_serial *serial;
+ struct fwtty_peer *peer;
+
+ serial = __fwserial_lookup_rcu(card);
+ if (!serial)
+ return;
+
+ list_for_each_entry_rcu(peer, &serial->peer_list, list) {
+ int g = peer->generation;
+ smp_rmb();
+ fwtty_dbg(card, "peer(%d:%x) guid: %016llx\n", g,
+ peer->node_id, (unsigned long long) peer->guid);
+ }
+}
+#else
+#define __dump_peer_list(s)
+#endif
+
+static void fwserial_auto_connect(struct work_struct *work)
+{
+ struct fwtty_peer *peer = to_peer(to_delayed_work(work), connect);
+ int err;
+
+ err = fwserial_connect_peer(peer);
+ if (err == -EAGAIN && ++peer->connect_retries < MAX_CONNECT_RETRIES)
+ schedule_delayed_work(&peer->connect, CONNECT_RETRY_DELAY);
+}
+
+/**
+ * fwserial_add_peer - add a newly probed 'serial' unit device as a 'peer'
+ * @serial: aggregate representing the specific fw_card to add the peer to
+ * @unit: 'peer' to create and add to peer_list of serial
+ *
+ * Adds a 'peer' (ie, a local or remote 'serial' unit device) to the list of
+ * peers for a specific fw_card. Optionally, auto-attach this peer to an
+ * available tty port. This function is called either directly or indirectly
+ * as a result of a 'serial' unit device being created & probed.
+ *
+ * Note: this function is serialized with fwserial_remove_peer() by the
+ * fwserial_list_mutex held in fwserial_probe().
+ *
+ * A 1:1 correspondence between an fw_unit and an fwtty_peer is maintained
+ * via the dev_set_drvdata() for the device of the fw_unit.
+ */
+static int fwserial_add_peer(struct fw_serial *serial, struct fw_unit *unit)
+{
+ struct device *dev = &unit->device;
+ struct fw_device *parent = fw_parent_device(unit);
+ struct fwtty_peer *peer;
+ struct fw_csr_iterator ci;
+ int key, val;
+ int generation;
+
+ peer = kzalloc(sizeof(*peer), GFP_KERNEL);
+ if (!peer)
+ return -ENOMEM;
+
+ peer_set_state(peer, FWPS_NOT_ATTACHED);
+
+ dev_set_drvdata(dev, peer);
+ peer->unit = unit;
+ peer->guid = (u64)parent->config_rom[3] << 32 | parent->config_rom[4];
+ peer->speed = parent->max_speed;
+ peer->max_payload = min(device_max_receive(parent),
+ link_speed_to_max_payload(peer->speed));
+
+ generation = parent->generation;
+ smp_rmb();
+ peer->node_id = parent->node_id;
+ smp_wmb();
+ peer->generation = generation;
+
+ /* retrieve the mgmt bus addr from the unit directory */
+ fw_csr_iterator_init(&ci, unit->directory);
+ while (fw_csr_iterator_next(&ci, &key, &val)) {
+ if (key == (CSR_OFFSET | CSR_DEPENDENT_INFO)) {
+ peer->mgmt_addr = CSR_REGISTER_BASE + 4 * val;
+ break;
+ }
+ }
+ if (peer->mgmt_addr == 0ULL) {
+ /*
+ * No mgmt address effectively disables VIRT_CABLE_PLUG -
+ * this peer will not be able to attach to a remote
+ */
+ peer_set_state(peer, FWPS_NO_MGMT_ADDR);
+ }
+
+ spin_lock_init(&peer->lock);
+ peer->port = NULL;
+
+ init_timer(&peer->timer);
+ INIT_WORK(&peer->work, NULL);
+ INIT_DELAYED_WORK(&peer->connect, fwserial_auto_connect);
+
+ /* associate peer with specific fw_card */
+ peer->serial = serial;
+ list_add_rcu(&peer->list, &serial->peer_list);
+
+ fwtty_info(&peer->unit, "peer added (guid:%016llx)",
+ (unsigned long long)peer->guid);
+
+ /* identify the local unit & virt cable to loopback port */
+ if (parent->is_local) {
+ serial->self = peer;
+ if (create_loop_dev) {
+ struct fwtty_port *port;
+ port = fwserial_claim_port(peer, num_ttys);
+ if (!IS_ERR(port)) {
+ struct virt_plug_params params;
+
+ spin_lock_bh(&peer->lock);
+ peer->port = port;
+ fill_plug_params(&params, port);
+ fwserial_virt_plug_complete(peer, &params);
+ spin_unlock_bh(&peer->lock);
+
+ fwtty_write_port_status(port);
+ }
+ }
+
+ } else if (auto_connect) {
+ /* auto-attach to remote units only (if policy allows) */
+ schedule_delayed_work(&peer->connect, 1);
+ }
+
+ return 0;
+}
+
+/**
+ * fwserial_remove_peer - remove a 'serial' unit device as a 'peer'
+ *
+ * Remove a 'peer' from its list of peers. This function is only
+ * called by fwserial_remove() on bus removal of the unit device.
+ *
+ * Note: this function is serialized with fwserial_add_peer() by the
+ * fwserial_list_mutex held in fwserial_remove().
+ */
+static void fwserial_remove_peer(struct fwtty_peer *peer)
+{
+ struct fwtty_port *port;
+
+ spin_lock_bh(&peer->lock);
+ peer_set_state(peer, FWPS_GONE);
+ spin_unlock_bh(&peer->lock);
+
+ cancel_delayed_work_sync(&peer->connect);
+ cancel_work_sync(&peer->work);
+
+ spin_lock_bh(&peer->lock);
+ /* if this unit is the local unit, clear link */
+ if (peer == peer->serial->self)
+ peer->serial->self = NULL;
+
+ /* cancel the request timeout timer (if running) */
+ del_timer(&peer->timer);
+
+ port = peer->port;
+ peer->port = NULL;
+
+ list_del_rcu(&peer->list);
+
+ fwtty_info(&peer->unit, "peer removed (guid:%016llx)",
+ (unsigned long long)peer->guid);
+
+ spin_unlock_bh(&peer->lock);
+
+ if (port)
+ fwserial_release_port(port);
+
+ synchronize_rcu();
+ kfree(peer);
+}
+
+/**
+ * create_loop_device - create a loopback tty device
+ * @tty_driver: tty_driver to own loopback device
+ * @prototype: ptr to already-assigned 'prototype' tty port
+ * @index: index to associate this device with the tty port
+ * @parent: device to child to
+ *
+ * HACK - this is basically tty_port_register_device() with an
+ * alternate naming scheme. Suggest tty_port_register_named_device()
+ * helper api.
+ *
+ * Creates a loopback tty device named 'fwloop<n>' which is attached to
+ * the local unit in fwserial_add_peer(). Note that <n> in the device
+ * name advances in increments of port allocation blocks, ie., for port
+ * indices 0..3, the device name will be 'fwloop0'; for 4..7, 'fwloop1',
+ * and so on.
+ *
+ * Only one loopback device should be created per fw_card.
+ */
+static void release_loop_device(struct device *dev)
+{
+ kfree(dev);
+}
+
+static struct device *create_loop_device(struct tty_driver *driver,
+ struct fwtty_port *prototype,
+ struct fwtty_port *port,
+ struct device *parent)
+{
+ char name[64];
+ int index = port->index;
+ dev_t devt = MKDEV(driver->major, driver->minor_start) + index;
+ struct device *dev = NULL;
+ int err;
+
+ if (index >= fwtty_driver->num)
+ return ERR_PTR(-EINVAL);
+
+ snprintf(name, 64, "%s%d", loop_dev_name, index / num_ports);
+
+ tty_port_link_device(&port->port, driver, index);
+
+ cdev_init(&driver->cdevs[index], driver->cdevs[prototype->index].ops);
+ driver->cdevs[index].owner = driver->owner;
+ err = cdev_add(&driver->cdevs[index], devt, 1);
+ if (err)
+ return ERR_PTR(err);
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ cdev_del(&driver->cdevs[index]);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ dev->devt = devt;
+ dev->class = prototype->device->class;
+ dev->parent = parent;
+ dev->release = release_loop_device;
+ dev_set_name(dev, "%s", name);
+ dev->groups = NULL;
+ dev_set_drvdata(dev, NULL);
+
+ err = device_register(dev);
+ if (err) {
+ put_device(dev);
+ cdev_del(&driver->cdevs[index]);
+ return ERR_PTR(err);
+ }
+
+ return dev;
+}
+
+/**
+ * fwserial_create - init everything to create TTYs for a specific fw_card
+ * @unit: fw_unit for first 'serial' unit device probed for this fw_card
+ *
+ * This function inits the aggregate structure (an fw_serial instance)
+ * used to manage the TTY ports registered by a specific fw_card. Also, the
+ * unit device is added as the first 'peer'.
+ *
+ * This unit device may represent a local unit device (as specified by the
+ * config ROM unit directory) or it may represent a remote unit device
+ * (as specified by the reading of the remote node's config ROM).
+ *
+ * Returns 0 to indicate "ownership" of the unit device, or a negative errno
+ * value to indicate which error.
+ */
+static int fwserial_create(struct fw_unit *unit)
+{
+ struct fw_device *parent = fw_parent_device(unit);
+ struct fw_card *card = parent->card;
+ struct fw_serial *serial;
+ struct fwtty_port *port;
+ struct device *tty_dev;
+ int i, j;
+ int err;
+
+ serial = kzalloc(sizeof(*serial), GFP_KERNEL);
+ if (!serial)
+ return -ENOMEM;
+
+ kref_init(&serial->kref);
+ serial->card = card;
+ INIT_LIST_HEAD(&serial->peer_list);
+
+ for (i = 0; i < num_ports; ++i) {
+ port = kzalloc(sizeof(*port), GFP_KERNEL);
+ if (!port) {
+ err = -ENOMEM;
+ goto free_ports;
+ }
+ tty_port_init(&port->port);
+ port->index = FWTTY_INVALID_INDEX;
+ port->port.ops = &fwtty_port_ops;
+ port->serial = serial;
+
+ spin_lock_init(&port->lock);
+ INIT_DELAYED_WORK(&port->drain, fwtty_drain_tx);
+ INIT_DELAYED_WORK(&port->emit_breaks, fwtty_emit_breaks);
+ INIT_WORK(&port->hangup, fwtty_do_hangup);
+ INIT_WORK(&port->push, fwtty_pushrx);
+ INIT_LIST_HEAD(&port->buf_list);
+ init_waitqueue_head(&port->wait_tx);
+ port->max_payload = link_speed_to_max_payload(SCODE_100);
+ dma_fifo_init(&port->tx_fifo);
+
+ rcu_assign_pointer(port->peer, NULL);
+ serial->ports[i] = port;
+
+ /* get unique bus addr region for port's status & recv fifo */
+ port->rx_handler.length = FWTTY_PORT_RXFIFO_LEN + 4;
+ port->rx_handler.address_callback = fwtty_port_handler;
+ port->rx_handler.callback_data = port;
+ /*
+ * XXX: use custom memory region above cpu physical memory addrs
+ * this will ease porting to 64-bit firewire adapters
+ */
+ err = fw_core_add_address_handler(&port->rx_handler,
+ &fw_high_memory_region);
+ if (err) {
+ kfree(port);
+ goto free_ports;
+ }
+ }
+ /* preserve i for error cleanup */
+
+ err = fwtty_ports_add(serial);
+ if (err) {
+ fwtty_err(&unit, "no space in port table");
+ goto free_ports;
+ }
+
+ for (j = 0; j < num_ttys; ++j) {
+ tty_dev = tty_port_register_device(&serial->ports[j]->port,
+ fwtty_driver,
+ serial->ports[j]->index,
+ card->device);
+ if (IS_ERR(tty_dev)) {
+ err = PTR_ERR(tty_dev);
+ fwtty_err(&unit, "register tty device error (%d)", err);
+ goto unregister_ttys;
+ }
+
+ serial->ports[j]->device = tty_dev;
+ }
+ /* preserve j for error cleanup */
+
+ if (create_loop_dev) {
+ struct device *loop_dev;
+
+ loop_dev = create_loop_device(fwtty_driver,
+ serial->ports[0],
+ serial->ports[num_ttys],
+ card->device);
+ if (IS_ERR(loop_dev)) {
+ err = PTR_ERR(loop_dev);
+ fwtty_err(&unit, "create loop device failed (%d)", err);
+ goto unregister_ttys;
+ }
+ serial->ports[num_ttys]->device = loop_dev;
+ serial->ports[num_ttys]->loopback = true;
+ }
+
+ list_add_rcu(&serial->list, &fwserial_list);
+
+ fwtty_notice(&unit, "TTY over FireWire on device %s (guid %016llx)",
+ dev_name(card->device), (unsigned long long) card->guid);
+
+ err = fwserial_add_peer(serial, unit);
+ if (!err)
+ return 0;
+
+ fwtty_err(&unit, "unable to add peer unit device (%d)", err);
+
+ /* fall-through to error processing */
+ list_del_rcu(&serial->list);
+unregister_ttys:
+ for (--j; j >= 0; --j)
+ tty_unregister_device(fwtty_driver, serial->ports[j]->index);
+ kref_put(&serial->kref, fwserial_destroy);
+ return err;
+
+free_ports:
+ for (--i; i >= 0; --i) {
+ tty_port_destroy(&serial->ports[i]->port);
+ kfree(serial->ports[i]);
+ }
+ kfree(serial);
+ return err;
+}
+
+/**
+ * fwserial_probe: bus probe function for firewire 'serial' unit devices
+ *
+ * A 'serial' unit device is created and probed as a result of:
+ * - declaring a ieee1394 bus id table for 'devices' matching a fabricated
+ * 'serial' unit specifier id
+ * - adding a unit directory to the config ROM(s) for a 'serial' unit
+ *
+ * The firewire core registers unit devices by enumerating unit directories
+ * of a node's config ROM after reading the config ROM when a new node is
+ * added to the bus topology after a bus reset.
+ *
+ * The practical implications of this are:
+ * - this probe is called for both local and remote nodes that have a 'serial'
+ * unit directory in their config ROM (that matches the specifiers in
+ * fwserial_id_table).
+ * - no specific order is enforced for local vs. remote unit devices
+ *
+ * This unit driver copes with the lack of specific order in the same way the
+ * firewire net driver does -- each probe, for either a local or remote unit
+ * device, is treated as a 'peer' (has a struct fwtty_peer instance) and the
+ * first peer created for a given fw_card (tracked by the global fwserial_list)
+ * creates the underlying TTYs (aggregated in a fw_serial instance).
+ *
+ * NB: an early attempt to differentiate local & remote unit devices by creating
+ * peers only for remote units and fw_serial instances (with their
+ * associated TTY devices) only for local units was discarded. Managing
+ * the peer lifetimes on device removal proved too complicated.
+ *
+ * fwserial_probe/fwserial_remove are effectively serialized by the
+ * fwserial_list_mutex. This is necessary because the addition of the first peer
+ * for a given fw_card will trigger the creation of the fw_serial for that
+ * fw_card, which must not simultaneously contend with the removal of the
+ * last peer for a given fw_card triggering the destruction of the same
+ * fw_serial for the same fw_card.
+ */
+static int fwserial_probe(struct device *dev)
+{
+ struct fw_unit *unit = fw_unit(dev);
+ struct fw_serial *serial;
+ int err;
+
+ mutex_lock(&fwserial_list_mutex);
+ serial = fwserial_lookup(fw_parent_device(unit)->card);
+ if (!serial)
+ err = fwserial_create(unit);
+ else
+ err = fwserial_add_peer(serial, unit);
+ mutex_unlock(&fwserial_list_mutex);
+ return err;
+}
+
+/**
+ * fwserial_remove: bus removal function for firewire 'serial' unit devices
+ *
+ * The corresponding 'peer' for this unit device is removed from the list of
+ * peers for the associated fw_serial (which has a 1:1 correspondence with a
+ * specific fw_card). If this is the last peer being removed, then trigger
+ * the destruction of the underlying TTYs.
+ */
+static int fwserial_remove(struct device *dev)
+{
+ struct fwtty_peer *peer = dev_get_drvdata(dev);
+ struct fw_serial *serial = peer->serial;
+ int i;
+
+ mutex_lock(&fwserial_list_mutex);
+ fwserial_remove_peer(peer);
+
+ if (list_empty(&serial->peer_list)) {
+ /* unlink from the fwserial_list here */
+ list_del_rcu(&serial->list);
+
+ for (i = 0; i < num_ports; ++i)
+ fwserial_close_port(serial->ports[i]);
+ kref_put(&serial->kref, fwserial_destroy);
+ }
+ mutex_unlock(&fwserial_list_mutex);
+
+ return 0;
+}
+
+/**
+ * fwserial_update: bus update function for 'firewire' serial unit devices
+ *
+ * Updates the new node_id and bus generation for this peer. Note that locking
+ * is unnecessary; but careful memory barrier usage is important to enforce the
+ * load and store order of generation & node_id.
+ *
+ * The fw-core orders the write of node_id before generation in the parent
+ * fw_device to ensure that a stale node_id cannot be used with a current
+ * bus generation. So the generation value must be read before the node_id.
+ *
+ * In turn, this orders the write of node_id before generation in the peer to
+ * also ensure a stale node_id cannot be used with a current bus generation.
+ */
+static void fwserial_update(struct fw_unit *unit)
+{
+ struct fw_device *parent = fw_parent_device(unit);
+ struct fwtty_peer *peer = dev_get_drvdata(&unit->device);
+ int generation;
+
+ generation = parent->generation;
+ smp_rmb();
+ peer->node_id = parent->node_id;
+ smp_wmb();
+ peer->generation = generation;
+}
+
+static const struct ieee1394_device_id fwserial_id_table[] = {
+ {
+ .match_flags = IEEE1394_MATCH_SPECIFIER_ID |
+ IEEE1394_MATCH_VERSION,
+ .specifier_id = LINUX_VENDOR_ID,
+ .version = FWSERIAL_VERSION,
+ },
+ { }
+};
+
+static struct fw_driver fwserial_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = KBUILD_MODNAME,
+ .bus = &fw_bus_type,
+ .probe = fwserial_probe,
+ .remove = fwserial_remove,
+ },
+ .update = fwserial_update,
+ .id_table = fwserial_id_table,
+};
+
+#define FW_UNIT_SPECIFIER(id) ((CSR_SPECIFIER_ID << 24) | (id))
+#define FW_UNIT_VERSION(ver) ((CSR_VERSION << 24) | (ver))
+#define FW_UNIT_ADDRESS(ofs) (((CSR_OFFSET | CSR_DEPENDENT_INFO) << 24) \
+ | (((ofs) - CSR_REGISTER_BASE) >> 2))
+/* XXX: config ROM definitons could be improved with semi-automated offset
+ * and length calculation
+ */
+#define FW_ROM_DESCRIPTOR(ofs) (((CSR_LEAF | CSR_DESCRIPTOR) << 24) | (ofs))
+
+struct fwserial_unit_directory_data {
+ u16 crc;
+ u16 len;
+ u32 unit_specifier;
+ u32 unit_sw_version;
+ u32 unit_addr_offset;
+ u32 desc1_ofs;
+ u16 desc1_crc;
+ u16 desc1_len;
+ u32 desc1_data[5];
+} __packed;
+
+static struct fwserial_unit_directory_data fwserial_unit_directory_data = {
+ .len = 4,
+ .unit_specifier = FW_UNIT_SPECIFIER(LINUX_VENDOR_ID),
+ .unit_sw_version = FW_UNIT_VERSION(FWSERIAL_VERSION),
+ .desc1_ofs = FW_ROM_DESCRIPTOR(1),
+ .desc1_len = 5,
+ .desc1_data = {
+ 0x00000000, /* type = text */
+ 0x00000000, /* enc = ASCII, lang EN */
+ 0x4c696e75, /* 'Linux TTY' */
+ 0x78205454,
+ 0x59000000,
+ },
+};
+
+static struct fw_descriptor fwserial_unit_directory = {
+ .length = sizeof(fwserial_unit_directory_data) / sizeof(u32),
+ .key = (CSR_DIRECTORY | CSR_UNIT) << 24,
+ .data = (u32 *)&fwserial_unit_directory_data,
+};
+
+/*
+ * The management address is in the unit space region but above other known
+ * address users (to keep wild writes from causing havoc)
+ */
+const struct fw_address_region fwserial_mgmt_addr_region = {
+ .start = CSR_REGISTER_BASE + 0x1e0000ULL,
+ .end = 0x1000000000000ULL,
+};
+
+static struct fw_address_handler fwserial_mgmt_addr_handler;
+
+/**
+ * fwserial_handle_plug_req - handle VIRT_CABLE_PLUG request work
+ * @work: ptr to peer->work
+ *
+ * Attempts to complete the VIRT_CABLE_PLUG handshake sequence for this peer.
+ *
+ * This checks for a collided request-- ie, that a VIRT_CABLE_PLUG request was
+ * already sent to this peer. If so, the collision is resolved by comparing
+ * guid values; the loser sends the plug response.
+ *
+ * Note: if an error prevents a response, don't do anything -- the
+ * remote will timeout its request.
+ */
+static void fwserial_handle_plug_req(struct work_struct *work)
+{
+ struct fwtty_peer *peer = to_peer(work, work);
+ struct virt_plug_params *plug_req = &peer->work_params.plug_req;
+ struct fwtty_port *port;
+ struct fwserial_mgmt_pkt *pkt;
+ int rcode;
+
+ pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
+ if (!pkt)
+ return;
+
+ port = fwserial_find_port(peer);
+
+ spin_lock_bh(&peer->lock);
+
+ switch (peer->state) {
+ case FWPS_NOT_ATTACHED:
+ if (!port) {
+ fwtty_err(&peer->unit, "no more ports avail");
+ fill_plug_rsp_nack(pkt);
+ } else {
+ peer->port = port;
+ fill_plug_rsp_ok(pkt, peer->port);
+ peer_set_state(peer, FWPS_PLUG_RESPONDING);
+ /* don't release claimed port */
+ port = NULL;
+ }
+ break;
+
+ case FWPS_PLUG_PENDING:
+ if (peer->serial->card->guid > peer->guid)
+ goto cleanup;
+
+ /* We lost - hijack the already-claimed port and send ok */
+ del_timer(&peer->timer);
+ fill_plug_rsp_ok(pkt, peer->port);
+ peer_set_state(peer, FWPS_PLUG_RESPONDING);
+ break;
+
+ default:
+ fill_plug_rsp_nack(pkt);
+ }
+
+ spin_unlock_bh(&peer->lock);
+ if (port)
+ fwserial_release_port(port);
+
+ rcode = fwserial_send_mgmt_sync(peer, pkt);
+
+ spin_lock_bh(&peer->lock);
+ if (peer->state == FWPS_PLUG_RESPONDING) {
+ if (rcode == RCODE_COMPLETE) {
+ struct fwtty_port *tmp = peer->port;
+
+ fwserial_virt_plug_complete(peer, plug_req);
+ spin_unlock_bh(&peer->lock);
+
+ fwtty_write_port_status(tmp);
+ spin_lock_bh(&peer->lock);
+ } else {
+ fwtty_err(&peer->unit, "PLUG_RSP error (%d)", rcode);
+ port = peer_revert_state(peer);
+ }
+ }
+cleanup:
+ spin_unlock_bh(&peer->lock);
+ if (port)
+ fwserial_release_port(port);
+ kfree(pkt);
+ return;
+}
+
+static void fwserial_handle_unplug_req(struct work_struct *work)
+{
+ struct fwtty_peer *peer = to_peer(work, work);
+ struct fwtty_port *port = NULL;
+ struct fwserial_mgmt_pkt *pkt;
+ int rcode;
+
+ pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
+ if (!pkt)
+ return;
+
+ spin_lock_bh(&peer->lock);
+
+ switch (peer->state) {
+ case FWPS_ATTACHED:
+ fill_unplug_rsp_ok(pkt);
+ peer_set_state(peer, FWPS_UNPLUG_RESPONDING);
+ break;
+
+ case FWPS_UNPLUG_PENDING:
+ if (peer->serial->card->guid > peer->guid)
+ goto cleanup;
+
+ /* We lost - send unplug rsp */
+ del_timer(&peer->timer);
+ fill_unplug_rsp_ok(pkt);
+ peer_set_state(peer, FWPS_UNPLUG_RESPONDING);
+ break;
+
+ default:
+ fill_unplug_rsp_nack(pkt);
+ }
+
+ spin_unlock_bh(&peer->lock);
+
+ rcode = fwserial_send_mgmt_sync(peer, pkt);
+
+ spin_lock_bh(&peer->lock);
+ if (peer->state == FWPS_UNPLUG_RESPONDING) {
+ if (rcode == RCODE_COMPLETE)
+ port = peer_revert_state(peer);
+ else
+ fwtty_err(&peer->unit, "UNPLUG_RSP error (%d)", rcode);
+ }
+cleanup:
+ spin_unlock_bh(&peer->lock);
+ if (port)
+ fwserial_release_port(port);
+ kfree(pkt);
+ return;
+}
+
+static int fwserial_parse_mgmt_write(struct fwtty_peer *peer,
+ struct fwserial_mgmt_pkt *pkt,
+ unsigned long long addr,
+ size_t len)
+{
+ struct fwtty_port *port = NULL;
+ int rcode;
+
+ if (addr != fwserial_mgmt_addr_handler.offset || len < sizeof(pkt->hdr))
+ return RCODE_ADDRESS_ERROR;
+
+ if (len != be16_to_cpu(pkt->hdr.len) ||
+ len != mgmt_pkt_expected_len(pkt->hdr.code))
+ return RCODE_DATA_ERROR;
+
+ spin_lock_bh(&peer->lock);
+ if (peer->state == FWPS_GONE) {
+ /*
+ * This should never happen - it would mean that the
+ * remote unit that just wrote this transaction was
+ * already removed from the bus -- and the removal was
+ * processed before we rec'd this transaction
+ */
+ fwtty_err(&peer->unit, "peer already removed");
+ spin_unlock_bh(&peer->lock);
+ return RCODE_ADDRESS_ERROR;
+ }
+
+ rcode = RCODE_COMPLETE;
+
+ fwtty_dbg(&peer->unit, "mgmt: hdr.code: %04hx", pkt->hdr.code);
+
+ switch (be16_to_cpu(pkt->hdr.code) & FWSC_CODE_MASK) {
+ case FWSC_VIRT_CABLE_PLUG:
+ if (work_pending(&peer->work)) {
+ fwtty_err(&peer->unit, "plug req: busy");
+ rcode = RCODE_CONFLICT_ERROR;
+
+ } else {
+ peer->work_params.plug_req = pkt->plug_req;
+ PREPARE_WORK(&peer->work, fwserial_handle_plug_req);
+ queue_work(system_unbound_wq, &peer->work);
+ }
+ break;
+
+ case FWSC_VIRT_CABLE_PLUG_RSP:
+ if (peer->state != FWPS_PLUG_PENDING) {
+ rcode = RCODE_CONFLICT_ERROR;
+
+ } else if (be16_to_cpu(pkt->hdr.code) & FWSC_RSP_NACK) {
+ fwtty_notice(&peer->unit, "NACK plug rsp");
+ port = peer_revert_state(peer);
+
+ } else {
+ struct fwtty_port *tmp = peer->port;
+
+ fwserial_virt_plug_complete(peer, &pkt->plug_rsp);
+ spin_unlock_bh(&peer->lock);
+
+ fwtty_write_port_status(tmp);
+ spin_lock_bh(&peer->lock);
+ }
+ break;
+
+ case FWSC_VIRT_CABLE_UNPLUG:
+ if (work_pending(&peer->work)) {
+ fwtty_err(&peer->unit, "unplug req: busy");
+ rcode = RCODE_CONFLICT_ERROR;
+ } else {
+ PREPARE_WORK(&peer->work, fwserial_handle_unplug_req);
+ queue_work(system_unbound_wq, &peer->work);
+ }
+ break;
+
+ case FWSC_VIRT_CABLE_UNPLUG_RSP:
+ if (peer->state != FWPS_UNPLUG_PENDING)
+ rcode = RCODE_CONFLICT_ERROR;
+ else {
+ if (be16_to_cpu(pkt->hdr.code) & FWSC_RSP_NACK)
+ fwtty_notice(&peer->unit, "NACK unplug?");
+ port = peer_revert_state(peer);
+ }
+ break;
+
+ default:
+ fwtty_err(&peer->unit, "unknown mgmt code %d",
+ be16_to_cpu(pkt->hdr.code));
+ rcode = RCODE_DATA_ERROR;
+ }
+ spin_unlock_bh(&peer->lock);
+
+ if (port)
+ fwserial_release_port(port);
+
+ return rcode;
+}
+
+/**
+ * fwserial_mgmt_handler: bus address handler for mgmt requests
+ * @parameters: fw_address_callback_t as specified by firewire core interface
+ *
+ * This handler is responsible for handling virtual cable requests from remotes
+ * for all cards.
+ */
+static void fwserial_mgmt_handler(struct fw_card *card,
+ struct fw_request *request,
+ int tcode, int destination, int source,
+ int generation,
+ unsigned long long addr,
+ void *data, size_t len,
+ void *callback_data)
+{
+ struct fwserial_mgmt_pkt *pkt = data;
+ struct fwtty_peer *peer;
+ int rcode;
+
+ rcu_read_lock();
+ peer = __fwserial_peer_by_node_id(card, generation, source);
+ if (!peer) {
+ fwtty_dbg(card, "peer(%d:%x) not found", generation, source);
+ __dump_peer_list(card);
+ rcode = RCODE_CONFLICT_ERROR;
+
+ } else {
+ switch (tcode) {
+ case TCODE_WRITE_BLOCK_REQUEST:
+ rcode = fwserial_parse_mgmt_write(peer, pkt, addr, len);
+ break;
+
+ default:
+ rcode = RCODE_TYPE_ERROR;
+ }
+ }
+
+ rcu_read_unlock();
+ fw_send_response(card, request, rcode);
+}
+
+static int __init fwserial_init(void)
+{
+ int err, num_loops = !!(create_loop_dev);
+
+ /* num_ttys/num_ports must not be set above the static alloc avail */
+ if (num_ttys + num_loops > MAX_CARD_PORTS)
+ num_ttys = MAX_CARD_PORTS - num_loops;
+ num_ports = num_ttys + num_loops;
+
+ fwtty_driver = alloc_tty_driver(MAX_TOTAL_PORTS);
+ if (!fwtty_driver) {
+ err = -ENOMEM;
+ return err;
+ }
+
+ fwtty_driver->driver_name = KBUILD_MODNAME;
+ fwtty_driver->name = tty_dev_name;
+ fwtty_driver->major = 0;
+ fwtty_driver->minor_start = 0;
+ fwtty_driver->type = TTY_DRIVER_TYPE_SERIAL;
+ fwtty_driver->subtype = SERIAL_TYPE_NORMAL;
+ fwtty_driver->flags = TTY_DRIVER_REAL_RAW |
+ TTY_DRIVER_DYNAMIC_DEV;
+
+ fwtty_driver->init_termios = tty_std_termios;
+ fwtty_driver->init_termios.c_cflag |= CLOCAL;
+ tty_set_operations(fwtty_driver, &fwtty_ops);
+
+ err = tty_register_driver(fwtty_driver);
+ if (err) {
+ driver_err("register tty driver failed (%d)", err);
+ goto put_tty;
+ }
+
+ fwtty_txn_cache = kmem_cache_create("fwtty_txn_cache",
+ sizeof(struct fwtty_transaction),
+ 0, 0, fwtty_txn_constructor);
+ if (!fwtty_txn_cache) {
+ err = -ENOMEM;
+ goto unregister_driver;
+ }
+
+ /*
+ * Ideally, this address handler would be registered per local node
+ * (rather than the same handler for all local nodes). However,
+ * since the firewire core requires the config rom descriptor *before*
+ * the local unit device(s) are created, a single management handler
+ * must suffice for all local serial units.
+ */
+ fwserial_mgmt_addr_handler.length = sizeof(struct fwserial_mgmt_pkt);
+ fwserial_mgmt_addr_handler.address_callback = fwserial_mgmt_handler;
+
+ err = fw_core_add_address_handler(&fwserial_mgmt_addr_handler,
+ &fwserial_mgmt_addr_region);
+ if (err) {
+ driver_err("add management handler failed (%d)", err);
+ goto destroy_cache;
+ }
+
+ fwserial_unit_directory_data.unit_addr_offset =
+ FW_UNIT_ADDRESS(fwserial_mgmt_addr_handler.offset);
+ err = fw_core_add_descriptor(&fwserial_unit_directory);
+ if (err) {
+ driver_err("add unit descriptor failed (%d)", err);
+ goto remove_handler;
+ }
+
+ err = driver_register(&fwserial_driver.driver);
+ if (err) {
+ driver_err("register fwserial driver failed (%d)", err);
+ goto remove_descriptor;
+ }
+
+ return 0;
+
+remove_descriptor:
+ fw_core_remove_descriptor(&fwserial_unit_directory);
+remove_handler:
+ fw_core_remove_address_handler(&fwserial_mgmt_addr_handler);
+destroy_cache:
+ kmem_cache_destroy(fwtty_txn_cache);
+unregister_driver:
+ tty_unregister_driver(fwtty_driver);
+put_tty:
+ put_tty_driver(fwtty_driver);
+ return err;
+}
+
+static void __exit fwserial_exit(void)
+{
+ driver_unregister(&fwserial_driver.driver);
+ fw_core_remove_descriptor(&fwserial_unit_directory);
+ fw_core_remove_address_handler(&fwserial_mgmt_addr_handler);
+ kmem_cache_destroy(fwtty_txn_cache);
+ tty_unregister_driver(fwtty_driver);
+ put_tty_driver(fwtty_driver);
+}
+
+module_init(fwserial_init);
+module_exit(fwserial_exit);
+
+MODULE_AUTHOR("Peter Hurley (peter@hurleysoftware.com)");
+MODULE_DESCRIPTION("FireWire Serial TTY Driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(ieee1394, fwserial_id_table);
+MODULE_PARM_DESC(ttys, "Number of ttys to create for each local firewire node");
+MODULE_PARM_DESC(auto, "Auto-connect a tty to each firewire node discovered");
+MODULE_PARM_DESC(loop, "Create a loopback device, fwloop<n>, with ttys");
+MODULE_PARM_DESC(limit_bw, "Limit bandwidth utilization to 20%.");
diff --git a/drivers/staging/fwserial/fwserial.h b/drivers/staging/fwserial/fwserial.h
new file mode 100644
index 00000000000..8b572edf956
--- /dev/null
+++ b/drivers/staging/fwserial/fwserial.h
@@ -0,0 +1,387 @@
+#ifndef _FIREWIRE_FWSERIAL_H
+#define _FIREWIRE_FWSERIAL_H
+
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/list.h>
+#include <linux/firewire.h>
+#include <linux/firewire-constants.h>
+#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
+#include <linux/mutex.h>
+#include <linux/serial.h>
+#include <linux/serial_reg.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+
+#include "dma_fifo.h"
+
+#ifdef FWTTY_PROFILING
+#define DISTRIBUTION_MAX_SIZE 8192
+#define DISTRIBUTION_MAX_INDEX (ilog2(DISTRIBUTION_MAX_SIZE) + 1)
+static inline void profile_size_distrib(unsigned stat[], unsigned val)
+{
+ int n = (val) ? min(ilog2(val) + 1, DISTRIBUTION_MAX_INDEX) : 0;
+ ++stat[n];
+}
+#else
+#define DISTRIBUTION_MAX_INDEX 0
+#define profile_size_distrib(st, n)
+#endif
+
+/* Parameters for both VIRT_CABLE_PLUG & VIRT_CABLE_PLUG_RSP mgmt codes */
+struct virt_plug_params {
+ __be32 status_hi;
+ __be32 status_lo;
+ __be32 fifo_hi;
+ __be32 fifo_lo;
+ __be32 fifo_len;
+};
+
+struct peer_work_params {
+ union {
+ struct virt_plug_params plug_req;
+ };
+};
+
+/**
+ * fwtty_peer: structure representing local & remote unit devices
+ * @unit: unit child device of fw_device node
+ * @serial: back pointer to associated fw_serial aggregate
+ * @guid: unique 64-bit guid for this unit device
+ * @generation: most recent bus generation
+ * @node_id: most recent node_id
+ * @speed: link speed of peer (0 = S100, 2 = S400, ... 5 = S3200)
+ * @mgmt_addr: bus addr region to write mgmt packets to
+ * @status_addr: bus addr register to write line status to
+ * @fifo_addr: bus addr region to write serial output to
+ * @fifo_len: max length for single write to fifo_addr
+ * @list: link for insertion into fw_serial's peer_list
+ * @rcu: for deferring peer reclamation
+ * @lock: spinlock to synchonize changes to state & port fields
+ * @work: only one work item can be queued at any one time
+ * Note: pending work is canceled prior to removal, so this
+ * peer is valid for at least the lifetime of the work function
+ * @work_params: parameter block for work functions
+ * @timer: timer for resetting peer state if remote request times out
+ * @state: current state
+ * @connect: work item for auto-connecting
+ * @connect_retries: # of connections already attempted
+ * @port: associated tty_port (usable if state == FWSC_ATTACHED)
+ */
+struct fwtty_peer {
+ struct fw_unit *unit;
+ struct fw_serial *serial;
+ u64 guid;
+ int generation;
+ int node_id;
+ unsigned speed;
+ int max_payload;
+ u64 mgmt_addr;
+
+ /* these are usable only if state == FWSC_ATTACHED */
+ u64 status_addr;
+ u64 fifo_addr;
+ int fifo_len;
+
+ struct list_head list;
+ struct rcu_head rcu;
+
+ spinlock_t lock;
+ struct work_struct work;
+ struct peer_work_params work_params;
+ struct timer_list timer;
+ int state;
+ struct delayed_work connect;
+ int connect_retries;
+
+ struct fwtty_port *port;
+};
+
+#define to_peer(ptr, field) (container_of(ptr, struct fwtty_peer, field))
+
+/* state values for fwtty_peer.state field */
+enum fwtty_peer_state {
+ FWPS_GONE,
+ FWPS_NOT_ATTACHED,
+ FWPS_ATTACHED,
+ FWPS_PLUG_PENDING,
+ FWPS_PLUG_RESPONDING,
+ FWPS_UNPLUG_PENDING,
+ FWPS_UNPLUG_RESPONDING,
+
+ FWPS_NO_MGMT_ADDR = -1,
+};
+
+#define CONNECT_RETRY_DELAY HZ
+#define MAX_CONNECT_RETRIES 10
+
+/* must be holding peer lock for these state funclets */
+static inline void peer_set_state(struct fwtty_peer *peer, int new)
+{
+ peer->state = new;
+}
+
+static inline struct fwtty_port *peer_revert_state(struct fwtty_peer *peer)
+{
+ struct fwtty_port *port = peer->port;
+
+ peer->port = NULL;
+ peer_set_state(peer, FWPS_NOT_ATTACHED);
+ return port;
+}
+
+struct fwserial_mgmt_pkt {
+ struct {
+ __be16 len;
+ __be16 code;
+ } hdr;
+ union {
+ struct virt_plug_params plug_req;
+ struct virt_plug_params plug_rsp;
+ };
+} __packed;
+
+/* fwserial_mgmt_packet codes */
+#define FWSC_RSP_OK 0x0000
+#define FWSC_RSP_NACK 0x8000
+#define FWSC_CODE_MASK 0x0fff
+
+#define FWSC_VIRT_CABLE_PLUG 1
+#define FWSC_VIRT_CABLE_UNPLUG 2
+#define FWSC_VIRT_CABLE_PLUG_RSP 3
+#define FWSC_VIRT_CABLE_UNPLUG_RSP 4
+
+/* 1 min. plug timeout -- suitable for userland authorization */
+#define VIRT_CABLE_PLUG_TIMEOUT (60 * HZ)
+
+struct stats {
+ unsigned xchars;
+ unsigned dropped;
+ unsigned tx_stall;
+ unsigned fifo_errs;
+ unsigned sent;
+ unsigned lost;
+ unsigned throttled;
+ unsigned watermark;
+ unsigned reads[DISTRIBUTION_MAX_INDEX + 1];
+ unsigned writes[DISTRIBUTION_MAX_INDEX + 1];
+ unsigned txns[DISTRIBUTION_MAX_INDEX + 1];
+ unsigned unthrottle[DISTRIBUTION_MAX_INDEX + 1];
+};
+
+struct fwconsole_ops {
+ void (*notify)(int code, void *data);
+ void (*stats)(struct stats *stats, void *data);
+ void (*proc_show)(struct seq_file *m, void *data);
+};
+
+/* codes for console ops notify */
+#define FWCON_NOTIFY_ATTACH 1
+#define FWCON_NOTIFY_DETACH 2
+
+struct buffered_rx {
+ struct list_head list;
+ size_t n;
+ unsigned char data[0];
+};
+
+/**
+ * fwtty_port: structure used to track/represent underlying tty_port
+ * @port: underlying tty_port
+ * @device: tty device
+ * @index: index into port_table for this particular port
+ * note: minor = index + FWSERIAL_TTY_START_MINOR
+ * @serial: back pointer to the containing fw_serial
+ * @rx_handler: bus address handler for unique addr region used by remotes
+ * to communicate with this port. Every port uses
+ * fwtty_port_handler() for per port transactions.
+ * @fwcon_ops: ops for attached fw_console (if any)
+ * @con_data: private data for fw_console
+ * @wait_tx: waitqueue for sleeping until writer/drain completes tx
+ * @emit_breaks: delayed work responsible for generating breaks when the
+ * break line status is active
+ * @cps : characters per second computed from the termios settings
+ * @break_last: timestamp in jiffies from last emit_breaks
+ * @hangup: work responsible for HUPing when carrier is dropped/lost
+ * @mstatus: loose virtualization of LSR/MSR
+ * bits 15..0 correspond to TIOCM_* bits
+ * bits 19..16 reserved for mctrl
+ * bit 20 OOB_TX_THROTTLE
+ * bits 23..21 reserved
+ * bits 31..24 correspond to UART_LSR_* bits
+ * @lock: spinlock for protecting concurrent access to fields below it
+ * @mctrl: loose virtualization of MCR
+ * bits 15..0 correspond to TIOCM_* bits
+ * bit 16 OOB_RX_THROTTLE
+ * bits 19..17 reserved
+ * bits 31..20 reserved for mstatus
+ * @drain: delayed work scheduled to ensure that writes are flushed.
+ * The work can race with the writer but concurrent sending is
+ * prevented with the IN_TX flag. Scheduled under lock to
+ * limit scheduling when fifo has just been drained.
+ * @push: work responsible for pushing buffered rx to the ldisc.
+ * rx can become buffered if the tty buffer is filled before the
+ * ldisc throttles the sender.
+ * @buf_list: list of buffered rx yet to be sent to ldisc
+ * @buffered: byte count of buffered rx
+ * @tx_fifo: fifo used to store & block-up writes for dma to remote
+ * @max_payload: max bytes transmissable per dma (based on peer's max_payload)
+ * @status_mask: UART_LSR_* bitmask significant to rx (based on termios)
+ * @ignore_mask: UART_LSR_* bitmask of states to ignore (also based on termios)
+ * @break_ctl: if set, port is 'sending break' to remote
+ * @write_only: self-explanatory
+ * @overrun: previous rx was lost (partially or completely)
+ * @loopback: if set, port is in loopback mode
+ * @flags: atomic bit flags
+ * bit 0: IN_TX - gate to allow only one cpu to send from the dma fifo
+ * at a time.
+ * bit 1: STOP_TX - force tx to exit while sending
+ * @peer: rcu-pointer to associated fwtty_peer (if attached)
+ * NULL if no peer attached
+ * @icount: predefined statistics reported by the TIOCGICOUNT ioctl
+ * @stats: additional statistics reported in /proc/tty/driver/firewire_serial
+ */
+struct fwtty_port {
+ struct tty_port port;
+ struct device *device;
+ unsigned index;
+ struct fw_serial *serial;
+ struct fw_address_handler rx_handler;
+
+ struct fwconsole_ops *fwcon_ops;
+ void *con_data;
+
+ wait_queue_head_t wait_tx;
+ struct delayed_work emit_breaks;
+ unsigned cps;
+ unsigned long break_last;
+
+ struct work_struct hangup;
+
+ unsigned mstatus;
+
+ spinlock_t lock;
+ unsigned mctrl;
+ struct delayed_work drain;
+ struct work_struct push;
+ struct list_head buf_list;
+ int buffered;
+ struct dma_fifo tx_fifo;
+ int max_payload;
+ unsigned status_mask;
+ unsigned ignore_mask;
+ unsigned break_ctl:1,
+ write_only:1,
+ overrun:1,
+ loopback:1;
+ unsigned long flags;
+
+ struct fwtty_peer *peer;
+
+ struct async_icount icount;
+ struct stats stats;
+};
+
+#define to_port(ptr, field) (container_of(ptr, struct fwtty_port, field))
+
+/* bit #s for flags field */
+#define IN_TX 0
+#define STOP_TX 1
+#define BUFFERING_RX 2
+
+/* bitmasks for special mctrl/mstatus bits */
+#define OOB_RX_THROTTLE 0x00010000
+#define MCTRL_RSRVD 0x000e0000
+#define OOB_TX_THROTTLE 0x00100000
+#define MSTATUS_RSRVD 0x00e00000
+
+#define MCTRL_MASK (TIOCM_DTR | TIOCM_RTS | TIOCM_OUT1 | TIOCM_OUT2 | \
+ TIOCM_LOOP | OOB_RX_THROTTLE | MCTRL_RSRVD)
+
+/* XXX even every 1/50th secs. may be unnecessarily accurate */
+/* delay in jiffies between brk emits */
+#define FREQ_BREAKS (HZ / 50)
+
+/* Ports are allocated in blocks of num_ports for each fw_card */
+#define MAX_CARD_PORTS 32 /* max # of ports per card */
+#define MAX_TOTAL_PORTS 64 /* max # of ports total */
+
+/* tuning parameters */
+#define FWTTY_PORT_TXFIFO_LEN 4096
+#define FWTTY_PORT_MAX_PEND_DMA 8 /* costs a cache line per pend */
+#define DRAIN_THRESHOLD 1024
+#define MAX_ASYNC_PAYLOAD 4096 /* ohci-defined limit */
+#define WRITER_MINIMUM 128
+/* TODO: how to set watermark to AR context size? see fwtty_rx() */
+#define HIGH_WATERMARK 32768 /* AR context is 32K */
+
+/*
+ * Size of bus addr region above 4GB used per port as the recv addr
+ * - must be at least as big as the MAX_ASYNC_PAYLOAD
+ */
+#define FWTTY_PORT_RXFIFO_LEN MAX_ASYNC_PAYLOAD
+
+/**
+ * fw_serial: aggregate used to associate tty ports with specific fw_card
+ * @card: fw_card associated with this fw_serial device (1:1 association)
+ * @kref: reference-counted multi-port management allows delayed destroy
+ * @self: local unit device as 'peer'. Not valid until local unit device
+ * is enumerated.
+ * @list: link for insertion into fwserial_list
+ * @peer_list: list of local & remote unit devices attached to this card
+ * @ports: fixed array of tty_ports provided by this serial device
+ */
+struct fw_serial {
+ struct fw_card *card;
+ struct kref kref;
+
+ struct fwtty_peer *self;
+
+ struct list_head list;
+ struct list_head peer_list;
+
+ struct fwtty_port *ports[MAX_CARD_PORTS];
+};
+
+#define to_serial(ptr, field) (container_of(ptr, struct fw_serial, field))
+
+#define TTY_DEV_NAME "fwtty" /* ttyFW was taken */
+static const char tty_dev_name[] = TTY_DEV_NAME;
+static const char loop_dev_name[] = "fwloop";
+extern bool limit_bw;
+
+struct tty_driver *fwtty_driver;
+
+#define driver_err(s, v...) pr_err(KBUILD_MODNAME ": " s, ##v)
+
+struct fwtty_port *fwtty_port_get(unsigned index);
+void fwtty_port_put(struct fwtty_port *port);
+
+static inline void fwtty_bind_console(struct fwtty_port *port,
+ struct fwconsole_ops *fwcon_ops,
+ void *data)
+{
+ port->con_data = data;
+ port->fwcon_ops = fwcon_ops;
+}
+
+/*
+ * Returns the max send async payload size in bytes based on the unit device
+ * link speed - if set to limit bandwidth to max 20%, use lookup table
+ */
+static inline int link_speed_to_max_payload(unsigned speed)
+{
+ static const int max_async[] = { 307, 614, 1229, 2458, 4916, 9832, };
+ BUILD_BUG_ON(ARRAY_SIZE(max_async) - 1 != SCODE_3200);
+
+ speed = clamp(speed, (unsigned) SCODE_100, (unsigned) SCODE_3200);
+ if (limit_bw)
+ return max_async[speed];
+ else
+ return 1 << (speed + 9);
+}
+
+#endif /* _FIREWIRE_FWSERIAL_H */
diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c
index e26c6a8b262..1e630312372 100644
--- a/drivers/staging/gdm72xx/gdm_qos.c
+++ b/drivers/staging/gdm72xx/gdm_qos.c
@@ -11,6 +11,8 @@
* GNU General Public License for more details.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/etherdevice.h>
#include <asm/byteorder.h>
@@ -24,15 +26,6 @@
#define B2H(x) __be16_to_cpu(x)
-#undef dprintk
-#define dprintk(fmt, args ...) printk(KERN_DEBUG "[QoS] " fmt, ## args)
-#undef wprintk
-#define wprintk(fmt, args ...) \
- printk(KERN_WARNING "[QoS WARNING] " fmt, ## args)
-#undef eprintk
-#define eprintk(fmt, args ...) printk(KERN_ERR "[QoS ERROR] " fmt, ## args)
-
-
#define MAX_FREE_LIST_CNT 32
static struct {
struct list_head head;
@@ -95,7 +88,7 @@ static void free_qos_entry_list(struct list_head *free_list)
total_free++;
}
- dprintk("%s: total_free_cnt=%d\n", __func__, total_free);
+ pr_debug("%s: total_free_cnt=%d\n", __func__, total_free);
}
void gdm_qos_init(void *nic_ptr)
@@ -240,7 +233,9 @@ static u32 extract_qos_list(struct nic *nic, struct list_head *head)
qcb->csr[i].qos_buf_count++;
if (!list_empty(&qcb->qos_list[i]))
- wprintk("QoS Index(%d) is piled!!\n", i);
+ netdev_warn(nic->netdev,
+ "Index(%d) is piled!!\n",
+ i);
}
}
}
@@ -280,7 +275,8 @@ int gdm_qos_send_hci_pkt(struct sk_buff *skb, struct net_device *dev)
entry = alloc_qos_entry();
entry->skb = skb;
entry->dev = dev;
- dprintk("qcb->qos_list_cnt=%d\n", qcb->qos_list_cnt);
+ netdev_dbg(dev, "qcb->qos_list_cnt=%d\n",
+ qcb->qos_list_cnt);
}
spin_lock_irqsave(&qcb->qos_lock, flags);
@@ -362,7 +358,7 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size)
index = get_csr(qcb, SFID, 0);
if (index == -1) {
spin_unlock_irqrestore(&qcb->qos_lock, flags);
- eprintk("QoS ERROR: No SF\n");
+ netdev_err(nic->netdev, "QoS ERROR: No SF\n");
return;
}
qcb->csr[index].qos_buf_count = buf[(i*5)+10];
@@ -383,11 +379,12 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size)
index = get_csr(qcb, SFID, 1);
if (index == -1) {
- eprintk("QoS ERROR: csr Update Error\n");
+ netdev_err(nic->netdev, "QoS ERROR: csr Update Error\n");
return;
}
- dprintk("QOS_ADD SFID = 0x%x, index=%d\n", SFID, index);
+ netdev_dbg(nic->netdev, "QOS_ADD SFID = 0x%x, index=%d\n",
+ SFID, index);
spin_lock_irqsave(&qcb->qos_lock, flags);
qcb->csr[index].SFID = SFID;
@@ -435,11 +432,13 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size)
SFID += (buf[pos++]);
index = get_csr(qcb, SFID, 1);
if (index == -1) {
- eprintk("QoS ERROR: Wrong index(%d)\n", index);
+ netdev_err(nic->netdev, "QoS ERROR: Wrong index(%d)\n",
+ index);
return;
}
- dprintk("QOS_CHANGE_DEL SFID = 0x%x, index=%d\n", SFID, index);
+ netdev_dbg(nic->netdev, "QOS_CHANGE_DEL SFID = 0x%x, index=%d\n",
+ SFID, index);
INIT_LIST_HEAD(&free_list);
diff --git a/drivers/staging/gdm72xx/gdm_sdio.c b/drivers/staging/gdm72xx/gdm_sdio.c
index ca38d719a1f..8b8ed981d10 100644
--- a/drivers/staging/gdm72xx/gdm_sdio.c
+++ b/drivers/staging/gdm72xx/gdm_sdio.c
@@ -157,7 +157,7 @@ static int init_sdio(struct sdiowm_dev *sdev)
tx->sdu_buf = kmalloc(SDU_TX_BUF_SIZE, GFP_KERNEL);
if (tx->sdu_buf == NULL) {
- printk(KERN_ERR "Failed to allocate SDU tx buffer.\n");
+ dev_err(&sdev->func->dev, "Failed to allocate SDU tx buffer.\n");
goto fail;
}
@@ -186,7 +186,7 @@ static int init_sdio(struct sdiowm_dev *sdev)
rx->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL);
if (rx->rx_buf == NULL) {
- printk(KERN_ERR "Failed to allocate rx buffer.\n");
+ dev_err(&sdev->func->dev, "Failed to allocate rx buffer.\n");
goto fail;
}
@@ -246,7 +246,8 @@ static void send_sdio_pkt(struct sdio_func *func, u8 *data, int len)
ret = sdio_memcpy_toio(func, 0, data, n);
if (ret < 0) {
if (ret != -ENOMEDIUM)
- printk(KERN_ERR "gdmwms: %s error: ret = %d\n",
+ dev_err(&func->dev,
+ "gdmwms: %s error: ret = %d\n",
__func__, ret);
goto end_io;
}
@@ -259,7 +260,8 @@ static void send_sdio_pkt(struct sdio_func *func, u8 *data, int len)
ret = sdio_memcpy_toio(func, 0, data + n, remain);
if (ret < 0) {
if (ret != -ENOMEDIUM)
- printk(KERN_ERR "gdmwms: %s error: ret = %d\n",
+ dev_err(&func->dev,
+ "gdmwms: %s error: ret = %d\n",
__func__, ret);
goto end_io;
}
@@ -522,13 +524,14 @@ static void gdm_sdio_irq(struct sdio_func *func)
ret = sdio_memcpy_fromio(func, hdr, 0x0, TYPE_A_LOOKAHEAD_SIZE);
if (ret) {
- printk(KERN_ERR "Cannot read from function %d\n", func->num);
+ dev_err(&func->dev,
+ "Cannot read from function %d\n", func->num);
goto done;
}
len = (hdr[2] << 16) | (hdr[1] << 8) | hdr[0];
if (len > (RX_BUF_SIZE - TYPE_A_HEADER_SIZE)) {
- printk(KERN_ERR "Too big Type-A size: %d\n", len);
+ dev_err(&func->dev, "Too big Type-A size: %d\n", len);
goto done;
}
@@ -562,8 +565,8 @@ static void gdm_sdio_irq(struct sdio_func *func)
n = blocks * func->cur_blksize;
ret = sdio_memcpy_fromio(func, buf, 0x0, n);
if (ret) {
- printk(KERN_ERR "Cannot read from function %d\n",
- func->num);
+ dev_err(&func->dev,
+ "Cannot read from function %d\n", func->num);
goto done;
}
buf += n;
@@ -573,8 +576,8 @@ static void gdm_sdio_irq(struct sdio_func *func)
if (remain) {
ret = sdio_memcpy_fromio(func, buf, 0x0, remain);
if (ret) {
- printk(KERN_ERR "Cannot read from function %d\n",
- func->num);
+ dev_err(&func->dev,
+ "Cannot read from function %d\n", func->num);
goto done;
}
}
@@ -637,9 +640,9 @@ static int sdio_wimax_probe(struct sdio_func *func,
struct phy_dev *phy_dev = NULL;
struct sdiowm_dev *sdev = NULL;
- printk(KERN_INFO "Found GDM SDIO VID = 0x%04x PID = 0x%04x...\n",
- func->vendor, func->device);
- printk(KERN_INFO "GCT WiMax driver version %s\n", DRIVER_VERSION);
+ dev_info(&func->dev, "Found GDM SDIO VID = 0x%04x PID = 0x%04x...\n",
+ func->vendor, func->device);
+ dev_info(&func->dev, "GCT WiMax driver version %s\n", DRIVER_VERSION);
sdio_claim_host(func);
sdio_enable_func(func);
diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c
index 0c9e8958009..bce6104bbab 100644
--- a/drivers/staging/gdm72xx/gdm_usb.c
+++ b/drivers/staging/gdm72xx/gdm_usb.c
@@ -186,6 +186,7 @@ static int init_usb(struct usbwm_dev *udev)
struct rx_cxt *rx = &udev->rx;
struct usb_tx *t;
struct usb_rx *r;
+ unsigned long flags;
INIT_LIST_HEAD(&tx->free_list);
INIT_LIST_HEAD(&tx->sdu_list);
@@ -200,14 +201,17 @@ static int init_usb(struct usbwm_dev *udev)
spin_lock_init(&tx->lock);
spin_lock_init(&rx->lock);
+ spin_lock_irqsave(&tx->lock, flags);
for (i = 0; i < MAX_NR_SDU_BUF; i++) {
t = alloc_tx_struct(tx);
if (t == NULL) {
+ spin_unlock_irqrestore(&tx->lock, flags);
ret = -ENOMEM;
goto fail;
}
list_add(&t->list, &tx->free_list);
}
+ spin_unlock_irqrestore(&tx->lock, flags);
r = alloc_rx_struct(rx);
if (r == NULL) {
@@ -215,7 +219,9 @@ static int init_usb(struct usbwm_dev *udev)
goto fail;
}
+ spin_lock_irqsave(&rx->lock, flags);
list_add(&r->list, &rx->free_list);
+ spin_unlock_irqrestore(&rx->lock, flags);
return ret;
fail:
@@ -229,6 +235,9 @@ static void release_usb(struct usbwm_dev *udev)
struct rx_cxt *rx = &udev->rx;
struct usb_tx *t, *t_next;
struct usb_rx *r, *r_next;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tx->lock, flags);
list_for_each_entry_safe(t, t_next, &tx->sdu_list, list) {
list_del(&t->list);
@@ -245,6 +254,10 @@ static void release_usb(struct usbwm_dev *udev)
free_tx_struct(t);
}
+ spin_unlock_irqrestore(&tx->lock, flags);
+
+ spin_lock_irqsave(&rx->lock, flags);
+
list_for_each_entry_safe(r, r_next, &rx->free_list, list) {
list_del(&r->list);
free_rx_struct(r);
@@ -254,6 +267,8 @@ static void release_usb(struct usbwm_dev *udev)
list_del(&r->list);
free_rx_struct(r);
}
+
+ spin_unlock_irqrestore(&rx->lock, flags);
}
static void __gdm_usb_send_complete(struct urb *urb)
@@ -303,9 +318,12 @@ static int gdm_usb_send(void *priv_dev, void *data, int len,
u8 *pkt = data;
u16 cmd_evt;
unsigned long flags;
+#ifdef CONFIG_WIMAX_GDM72XX_K_MODE
+ unsigned long flags2;
+#endif /* CONFIG_WIMAX_GDM72XX_K_MODE */
if (!udev->usbdev) {
- printk(KERN_ERR "%s: No such device\n", __func__);
+ dev_err(&usbdev->dev, "%s: No such device\n", __func__);
return -ENODEV;
}
@@ -371,13 +389,16 @@ static int gdm_usb_send(void *priv_dev, void *data, int len,
rx = &udev->rx;
+ spin_lock_irqsave(&rx->lock, flags2);
list_for_each_entry(r, &rx->used_list, list)
usb_unlink_urb(r->urb);
+ spin_unlock_irqrestore(&rx->lock, flags2);
+
udev->bw_switch = 1;
- spin_lock(&k_lock);
+ spin_lock_irqsave(&k_lock, flags2);
list_add_tail(&udev->list, &k_list);
- spin_unlock(&k_lock);
+ spin_unlock_irqrestore(&k_lock, flags2);
wake_up(&k_wait);
}
@@ -416,7 +437,7 @@ static void gdm_usb_rcv_complete(struct urb *urb)
struct tx_cxt *tx = &udev->tx;
struct usb_tx *t;
u16 cmd_evt;
- unsigned long flags;
+ unsigned long flags, flags2;
#ifdef CONFIG_WIMAX_GDM72XX_USB_PM
struct usb_device *dev = urb->dev;
@@ -462,9 +483,9 @@ static void gdm_usb_rcv_complete(struct urb *urb)
if (!urb->status && r->callback)
r->callback(r->cb_data, r->buf, urb->actual_length);
- spin_lock(&rx->lock);
+ spin_lock_irqsave(&rx->lock, flags2);
put_rx_struct(rx, r);
- spin_unlock(&rx->lock);
+ spin_unlock_irqrestore(&rx->lock, flags2);
spin_unlock_irqrestore(&tx->lock, flags);
@@ -484,7 +505,7 @@ static int gdm_usb_receive(void *priv_dev,
unsigned long flags;
if (!udev->usbdev) {
- printk(KERN_ERR "%s: No such device\n", __func__);
+ dev_err(&usbdev->dev, "%s: No such device\n", __func__);
return -ENODEV;
}
@@ -559,9 +580,9 @@ static int gdm_usb_probe(struct usb_interface *intf,
idProduct = L2H(usbdev->descriptor.idProduct);
bcdDevice = L2H(usbdev->descriptor.bcdDevice);
- printk(KERN_INFO "Found GDM USB VID = 0x%04x PID = 0x%04x...\n",
- idVendor, idProduct);
- printk(KERN_INFO "GCT WiMax driver version %s\n", DRIVER_VERSION);
+ dev_info(&intf->dev, "Found GDM USB VID = 0x%04x PID = 0x%04x...\n",
+ idVendor, idProduct);
+ dev_info(&intf->dev, "GCT WiMax driver version %s\n", DRIVER_VERSION);
if (idProduct == EMERGENCY_PID) {
@@ -619,8 +640,9 @@ out:
if (ret) {
kfree(phy_dev);
kfree(udev);
+ } else {
+ usb_set_intfdata(intf, phy_dev);
}
- usb_set_intfdata(intf, phy_dev);
return ret;
}
@@ -660,14 +682,22 @@ static int gdm_suspend(struct usb_interface *intf, pm_message_t pm_msg)
struct usbwm_dev *udev;
struct rx_cxt *rx;
struct usb_rx *r;
+ unsigned long flags;
phy_dev = usb_get_intfdata(intf);
+ if (!phy_dev)
+ return 0;
+
udev = phy_dev->priv_dev;
rx = &udev->rx;
+ spin_lock_irqsave(&rx->lock, flags);
+
list_for_each_entry(r, &rx->used_list, list)
usb_unlink_urb(r->urb);
+ spin_unlock_irqrestore(&rx->lock, flags);
+
return 0;
}
@@ -677,14 +707,22 @@ static int gdm_resume(struct usb_interface *intf)
struct usbwm_dev *udev;
struct rx_cxt *rx;
struct usb_rx *r;
+ unsigned long flags;
phy_dev = usb_get_intfdata(intf);
+ if (!phy_dev)
+ return 0;
+
udev = phy_dev->priv_dev;
rx = &udev->rx;
+ spin_lock_irqsave(&rx->lock, flags);
+
list_for_each_entry(r, &rx->used_list, list)
usb_submit_urb(r->urb, GFP_ATOMIC);
+ spin_unlock_irqrestore(&rx->lock, flags);
+
return 0;
}
@@ -719,9 +757,13 @@ static int k_mode_thread(void *arg)
while (jiffies < expire)
schedule_timeout(K_WAIT_TIME);
+ spin_lock_irqsave(&rx->lock, flags);
+
list_for_each_entry(r, &rx->used_list, list)
usb_submit_urb(r->urb, GFP_ATOMIC);
+ spin_unlock_irqrestore(&rx->lock, flags);
+
spin_lock_irqsave(&tx->lock, flags);
list_for_each_entry_safe(t, temp, &tx->pending_list,
diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c
index 6cb810701a3..41efbeeb62f 100644
--- a/drivers/staging/gdm72xx/gdm_wimax.c
+++ b/drivers/staging/gdm72xx/gdm_wimax.c
@@ -11,6 +11,8 @@
* GNU General Public License for more details.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/etherdevice.h>
#include <asm/byteorder.h>
#include <linux/ip.h>
@@ -166,21 +168,13 @@ static void dump_eth_packet(const char *title, u8 *data, int len)
get_ip_protocol_name(ip_protocol),
get_port_name(port));
- #if 1
if (!(data[0] == 0xff && data[1] == 0xff)) {
if (protocol == ETH_P_IP) {
- printk(KERN_DEBUG " src=%u.%u.%u.%u\n",
- NIPQUAD(ih->saddr));
+ printk(KERN_DEBUG " src=%pI4\n", &ih->saddr);
} else if (protocol == ETH_P_IPV6) {
- #ifdef NIP6
- printk(KERN_DEBUG " src=%x:%x:%x:%x:%x:%x:%x:%x\n",
- NIP6(ih->saddr));
- #else
printk(KERN_DEBUG " src=%pI6\n", &ih->saddr);
- #endif
}
}
- #endif
#if (DUMP_PACKET & DUMP_SDU_ALL)
printk_hex(data, len);
@@ -271,7 +265,7 @@ static int gdm_wimax_event_init(void)
return 0;
}
- printk(KERN_ERR "Creating WiMax Event netlink is failed\n");
+ pr_err("Creating WiMax Event netlink is failed\n");
return -1;
}
@@ -367,7 +361,7 @@ static int gdm_wimax_event_send(struct net_device *dev, char *buf, int size)
e = get_event_entry();
if (!e) {
- printk(KERN_ERR "%s: No memory for event\n", __func__);
+ netdev_err(dev, "%s: No memory for event\n", __func__);
spin_unlock_irqrestore(&wm_event.evt_lock, flags);
return -ENOMEM;
}
@@ -433,10 +427,10 @@ static int gdm_wimax_tx(struct sk_buff *skb, struct net_device *dev)
#if !defined(LOOPBACK_TEST)
if (!fsm)
- printk(KERN_ERR "ASSERTION ERROR: fsm is NULL!!\n");
+ netdev_err(dev, "ASSERTION ERROR: fsm is NULL!!\n");
else if (fsm->m_status != M_CONNECTED) {
- printk(KERN_EMERG "ASSERTION ERROR: Device is NOT ready. status=%d\n",
- fsm->m_status);
+ netdev_emerg(dev, "ASSERTION ERROR: Device is NOT ready. status=%d\n",
+ fsm->m_status);
kfree_skb(skb);
return 0;
}
@@ -622,9 +616,8 @@ static int gdm_wimax_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
case SIOCG_DATA:
case SIOCS_DATA:
if (req->data_id >= SIOC_DATA_MAX) {
- printk(KERN_ERR
- "%s error: data-index(%d) is invalid!!\n",
- __func__, req->data_id);
+ netdev_err(dev, "%s error: data-index(%d) is invalid!!\n",
+ __func__, req->data_id);
return -EOPNOTSUPP;
}
if (req->cmd == SIOCG_DATA) {
@@ -646,7 +639,7 @@ static int gdm_wimax_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
}
break;
default:
- printk(KERN_ERR "%s: %x unknown ioctl\n", __func__, cmd);
+ netdev_err(dev, "%s: %x unknown ioctl\n", __func__, cmd);
return -EOPNOTSUPP;
}
@@ -692,7 +685,7 @@ static void gdm_wimax_prepare_device(struct net_device *dev)
hci->length = H2B(len);
gdm_wimax_send(nic, hci, HCI_HEADER_SIZE+len);
- printk(KERN_INFO "GDM WiMax Set CAPABILITY: 0x%08X\n", DB2H(val));
+ netdev_info(dev, "GDM WiMax Set CAPABILITY: 0x%08X\n", DB2H(val));
}
static int gdm_wimax_hci_get_tlv(u8 *buf, u8 *T, u16 *L, u8 **V)
@@ -726,28 +719,28 @@ static int gdm_wimax_get_prepared_info(struct net_device *dev, char *buf,
cmd_len = B2H(*(u16 *)&buf[2]);
if (len < cmd_len + HCI_HEADER_SIZE) {
- printk(KERN_ERR "%s: invalid length [%d/%d]\n", __func__,
- cmd_len + HCI_HEADER_SIZE, len);
+ netdev_err(dev, "%s: invalid length [%d/%d]\n", __func__,
+ cmd_len + HCI_HEADER_SIZE, len);
return -1;
}
if (cmd_evt == WIMAX_GET_INFO_RESULT) {
if (cmd_len < 2) {
- printk(KERN_ERR "%s: len is too short [%x/%d]\n",
- __func__, cmd_evt, len);
+ netdev_err(dev, "%s: len is too short [%x/%d]\n",
+ __func__, cmd_evt, len);
return -1;
}
pos += gdm_wimax_hci_get_tlv(&buf[pos], &T, &L, &V);
if (T == TLV_T(T_MAC_ADDRESS)) {
if (L != dev->addr_len) {
- printk(KERN_ERR
- "%s Invalid inofrmation result T/L "
- "[%x/%d]\n", __func__, T, L);
+ netdev_err(dev,
+ "%s Invalid inofrmation result T/L [%x/%d]\n",
+ __func__, T, L);
return -1;
}
- printk(KERN_INFO "MAC change [%pM]->[%pM]\n",
- dev->dev_addr, V);
+ netdev_info(dev, "MAC change [%pM]->[%pM]\n",
+ dev->dev_addr, V);
memcpy(dev->dev_addr, V, dev->addr_len);
return 1;
}
@@ -769,7 +762,7 @@ static void gdm_wimax_netif_rx(struct net_device *dev, char *buf, int len)
skb = dev_alloc_skb(len + 2);
if (!skb) {
- printk(KERN_ERR "%s: dev_alloc_skb failed!\n", __func__);
+ netdev_err(dev, "%s: dev_alloc_skb failed!\n", __func__);
return;
}
skb_reserve(skb, 2);
@@ -784,7 +777,7 @@ static void gdm_wimax_netif_rx(struct net_device *dev, char *buf, int len)
ret = in_interrupt() ? netif_rx(skb) : netif_rx_ni(skb);
if (ret == NET_RX_DROP)
- printk(KERN_ERR "%s skb dropped\n", __func__);
+ netdev_err(dev, "%s skb dropped\n", __func__);
}
static void gdm_wimax_transmit_aggr_pkt(struct net_device *dev, char *buf,
@@ -799,8 +792,8 @@ static void gdm_wimax_transmit_aggr_pkt(struct net_device *dev, char *buf,
hci = (struct hci_s *) buf;
if (B2H(hci->cmd_evt) != WIMAX_RX_SDU) {
- printk(KERN_ERR "Wrong cmd_evt(0x%04X)\n",
- B2H(hci->cmd_evt));
+ netdev_err(dev, "Wrong cmd_evt(0x%04X)\n",
+ B2H(hci->cmd_evt));
break;
}
@@ -834,8 +827,8 @@ static void gdm_wimax_transmit_pkt(struct net_device *dev, char *buf, int len)
if (len < cmd_len + HCI_HEADER_SIZE) {
if (len)
- printk(KERN_ERR "%s: invalid length [%d/%d]\n",
- __func__, cmd_len + HCI_HEADER_SIZE, len);
+ netdev_err(dev, "%s: invalid length [%d/%d]\n",
+ __func__, cmd_len + HCI_HEADER_SIZE, len);
return;
}
@@ -915,7 +908,8 @@ static void prepare_rx_complete(void *arg, void *data, int len)
gdm_wimax_rcv_with_cb(nic, rx_complete, nic);
else {
if (ret < 0)
- printk(KERN_ERR "get_prepared_info failed(%d)\n", ret);
+ netdev_err(nic->netdev,
+ "get_prepared_info failed(%d)\n", ret);
gdm_wimax_rcv_with_cb(nic, prepare_rx_complete, nic);
#if 0
/* Re-prepare WiMax device */
@@ -949,7 +943,7 @@ int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev)
"wm%d", ether_setup);
if (dev == NULL) {
- printk(KERN_ERR "alloc_etherdev failed\n");
+ pr_err("alloc_etherdev failed\n");
return -ENOMEM;
}
@@ -969,7 +963,7 @@ int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev)
/* event socket init */
ret = gdm_wimax_event_init();
if (ret < 0) {
- printk(KERN_ERR "Cannot create event.\n");
+ pr_err("Cannot create event.\n");
goto cleanup;
}
@@ -996,7 +990,7 @@ int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev)
return 0;
cleanup:
- printk(KERN_ERR "register_netdev failed\n");
+ pr_err("register_netdev failed\n");
free_netdev(dev);
return ret;
}
diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c
index 20d0aec52e7..52c25ba5831 100644
--- a/drivers/staging/gdm72xx/netlink_k.c
+++ b/drivers/staging/gdm72xx/netlink_k.c
@@ -11,6 +11,8 @@
* GNU General Public License for more details.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/etherdevice.h>
#include <linux/netlink.h>
@@ -54,8 +56,8 @@ static void netlink_rcv_cb(struct sk_buff *skb)
if (skb->len < nlh->nlmsg_len ||
nlh->nlmsg_len > ND_MAX_MSG_LEN) {
- printk(KERN_ERR "Invalid length (%d,%d)\n", skb->len,
- nlh->nlmsg_len);
+ netdev_err(skb->dev, "Invalid length (%d,%d)\n",
+ skb->len, nlh->nlmsg_len);
return;
}
@@ -69,10 +71,11 @@ static void netlink_rcv_cb(struct sk_buff *skb)
rcv_cb(dev, nlh->nlmsg_type, msg, mlen);
dev_put(dev);
} else
- printk(KERN_ERR "dev_get_by_index(%d) "
- "is not found.\n", ifindex);
+ netdev_err(skb->dev,
+ "dev_get_by_index(%d) is not found.\n",
+ ifindex);
} else
- printk(KERN_ERR "Unregistered Callback\n");
+ netdev_err(skb->dev, "Unregistered Callback\n");
}
}
@@ -116,14 +119,14 @@ int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len)
int ret = 0;
if (group > ND_MAX_GROUP) {
- printk(KERN_ERR "Group %d is invalied.\n", group);
- printk(KERN_ERR "Valid group is 0 ~ %d.\n", ND_MAX_GROUP);
+ pr_err("Group %d is invalied.\n", group);
+ pr_err("Valid group is 0 ~ %d.\n", ND_MAX_GROUP);
return -EINVAL;
}
skb = alloc_skb(NLMSG_SPACE(len), GFP_ATOMIC);
if (!skb) {
- printk(KERN_ERR "netlink_broadcast ret=%d\n", ret);
+ pr_err("netlink_broadcast ret=%d\n", ret);
return -ENOMEM;
}
@@ -144,8 +147,8 @@ int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len)
return len;
else {
if (ret != -ESRCH) {
- printk(KERN_ERR "netlink_broadcast g=%d, t=%d, l=%d, r=%d\n",
- group, type, len, ret);
+ pr_err("netlink_broadcast g=%d, t=%d, l=%d, r=%d\n",
+ group, type, len, ret);
}
ret = 0;
}
diff --git a/drivers/staging/gdm72xx/sdio_boot.c b/drivers/staging/gdm72xx/sdio_boot.c
index 65624bca8b3..6291829dcdc 100644
--- a/drivers/staging/gdm72xx/sdio_boot.c
+++ b/drivers/staging/gdm72xx/sdio_boot.c
@@ -24,15 +24,18 @@
#include <linux/mmc/card.h>
#include <linux/mmc/sdio_func.h>
+#include <linux/firmware.h>
+
#include "gdm_sdio.h"
#define TYPE_A_HEADER_SIZE 4
#define TYPE_A_LOOKAHEAD_SIZE 16
-#define YMEM0_SIZE 0x8000 /* 32kbytes */
+#define YMEM0_SIZE 0x8000 /* 32kbytes */
#define DOWNLOAD_SIZE (YMEM0_SIZE - TYPE_A_HEADER_SIZE)
-#define KRN_PATH "/lib/firmware/gdm72xx/gdmskrn.bin"
-#define RFS_PATH "/lib/firmware/gdm72xx/gdmsrfs.bin"
+#define FW_DIR "gdm72xx/"
+#define FW_KRN "gdmskrn.bin"
+#define FW_RFS "gdmsrfs.bin"
static u8 *tx_buf;
@@ -52,106 +55,109 @@ static int ack_ready(struct sdio_func *func)
return 0;
}
-static int download_image(struct sdio_func *func, char *img_name)
+static int download_image(struct sdio_func *func, const char *img_name)
{
- int ret = 0, len, size, pno;
- struct file *filp = NULL;
- struct inode *inode = NULL;
+ int ret = 0, len, pno;
u8 *buf = tx_buf;
loff_t pos = 0;
-
- filp = filp_open(img_name, O_RDONLY | O_LARGEFILE, 0);
- if (IS_ERR(filp)) {
- printk(KERN_ERR "Can't find %s.\n", img_name);
- return -ENOENT;
+ int img_len;
+ const struct firmware *firm;
+
+ ret = request_firmware(&firm, img_name, &func->dev);
+ if (ret < 0) {
+ dev_err(&func->dev,
+ "requesting firmware %s failed with error %d\n",
+ img_name, ret);
+ return ret;
}
- inode = filp->f_dentry->d_inode;
- if (!S_ISREG(inode->i_mode)) {
- printk(KERN_ERR "Invalid file type: %s\n", img_name);
- ret = -EINVAL;
- goto out;
+ buf = kmalloc(DOWNLOAD_SIZE + TYPE_A_HEADER_SIZE, GFP_KERNEL);
+ if (buf == NULL) {
+ dev_err(&func->dev, "Error: kmalloc\n");
+ return -ENOMEM;
}
- size = i_size_read(inode->i_mapping->host);
- if (size <= 0) {
- printk(KERN_ERR "Unable to find file size: %s\n", img_name);
- ret = size;
+ img_len = firm->size;
+
+ if (img_len <= 0) {
+ ret = -1;
goto out;
}
pno = 0;
- while ((len = filp->f_op->read(filp, buf + TYPE_A_HEADER_SIZE,
- DOWNLOAD_SIZE, &pos))) {
- if (len < 0) {
- ret = -1;
- goto out;
+ while (img_len > 0) {
+ if (img_len > DOWNLOAD_SIZE) {
+ len = DOWNLOAD_SIZE;
+ buf[3] = 0;
+ } else {
+ len = img_len; /* the last packet */
+ buf[3] = 2;
}
buf[0] = len & 0xff;
buf[1] = (len >> 8) & 0xff;
buf[2] = (len >> 16) & 0xff;
- if (pos >= size) /* The last packet */
- buf[3] = 2;
- else
- buf[3] = 0;
-
+ memcpy(buf+TYPE_A_HEADER_SIZE, firm->data + pos, len);
ret = sdio_memcpy_toio(func, 0, buf, len + TYPE_A_HEADER_SIZE);
if (ret < 0) {
- printk(KERN_ERR "gdmwm: send image error: "
- "packet number = %d ret = %d\n", pno, ret);
+ dev_err(&func->dev,
+ "send image error: packet number = %d ret = %d\n",
+ pno, ret);
goto out;
}
+
if (buf[3] == 2) /* The last packet */
break;
if (!ack_ready(func)) {
ret = -EIO;
- printk(KERN_ERR "gdmwm: Ack is not ready.\n");
+ dev_err(&func->dev, "Ack is not ready.\n");
goto out;
}
ret = sdio_memcpy_fromio(func, buf, 0, TYPE_A_LOOKAHEAD_SIZE);
if (ret < 0) {
- printk(KERN_ERR "gdmwm: receive ack error: "
- "packet number = %d ret = %d\n", pno, ret);
+ dev_err(&func->dev,
+ "receive ack error: packet number = %d ret = %d\n",
+ pno, ret);
goto out;
}
sdio_writeb(func, 0x01, 0x13, &ret);
sdio_writeb(func, 0x00, 0x10, &ret); /* PCRRT */
+ img_len -= DOWNLOAD_SIZE;
+ pos += DOWNLOAD_SIZE;
pno++;
}
+
out:
- filp_close(filp, NULL);
+ kfree(buf);
return ret;
}
int sdio_boot(struct sdio_func *func)
{
- static mm_segment_t fs;
int ret;
+ const char *krn_name = FW_DIR FW_KRN;
+ const char *rfs_name = FW_DIR FW_RFS;
tx_buf = kmalloc(YMEM0_SIZE, GFP_KERNEL);
if (tx_buf == NULL) {
- printk(KERN_ERR "Error: kmalloc: %s %d\n", __func__, __LINE__);
+ dev_err(&func->dev, "Error: kmalloc: %s %d\n",
+ __func__, __LINE__);
return -ENOMEM;
}
- fs = get_fs();
- set_fs(get_ds());
-
- ret = download_image(func, KRN_PATH);
+ ret = download_image(func, krn_name);
if (ret)
goto restore_fs;
- printk(KERN_INFO "GCT: Kernel download success.\n");
+ dev_info(&func->dev, "GCT: Kernel download success.\n");
- ret = download_image(func, RFS_PATH);
+ ret = download_image(func, rfs_name);
if (ret)
goto restore_fs;
- printk(KERN_INFO "GCT: Filesystem download success.\n");
+ dev_info(&func->dev, "GCT: Filesystem download success.\n");
restore_fs:
- set_fs(fs);
kfree(tx_buf);
return ret;
}
diff --git a/drivers/staging/gdm72xx/usb_boot.c b/drivers/staging/gdm72xx/usb_boot.c
index 0787188728a..3e2103ae4ea 100644
--- a/drivers/staging/gdm72xx/usb_boot.c
+++ b/drivers/staging/gdm72xx/usb_boot.c
@@ -82,7 +82,8 @@ static int gdm_wibro_send(struct usb_device *usbdev, void *data, int len)
&actual, 1000);
if (ret < 0) {
- printk(KERN_ERR "Error : usb_bulk_msg ( result = %d )\n", ret);
+ dev_err(&usbdev->dev, "Error : usb_bulk_msg ( result = %d )\n",
+ ret);
return ret;
}
return 0;
@@ -97,8 +98,8 @@ static int gdm_wibro_recv(struct usb_device *usbdev, void *data, int len)
&actual, 5000);
if (ret < 0) {
- printk(KERN_ERR "Error : usb_bulk_msg(recv) ( result = %d )\n",
- ret);
+ dev_err(&usbdev->dev,
+ "Error : usb_bulk_msg(recv) ( result = %d )\n", ret);
return ret;
}
return 0;
@@ -150,20 +151,20 @@ int usb_boot(struct usb_device *usbdev, u16 pid)
ret = request_firmware(&firm, img_name, &usbdev->dev);
if (ret < 0) {
- printk(KERN_ERR
- "requesting firmware %s failed with error %d\n",
+ dev_err(&usbdev->dev,
+ "requesting firmware %s failed with error %d\n",
img_name, ret);
return ret;
}
tx_buf = kmalloc(DOWNLOAD_SIZE, GFP_KERNEL);
if (tx_buf == NULL) {
- printk(KERN_ERR "Error: kmalloc\n");
+ dev_err(&usbdev->dev, "Error: kmalloc\n");
return -ENOMEM;
}
if (firm->size < sizeof(hdr)) {
- printk(KERN_ERR "gdmwm: Cannot read the image info.\n");
+ dev_err(&usbdev->dev, "Cannot read the image info.\n");
ret = -EIO;
goto out;
}
@@ -172,23 +173,22 @@ int usb_boot(struct usb_device *usbdev, u16 pid)
array_le32_to_cpu((u32 *)&hdr, 19);
#if 0
if (hdr.magic_code != 0x10767fff) {
- printk(KERN_ERR "gdmwm: Invalid magic code 0x%08x\n",
+ dev_err(&usbdev->dev, "Invalid magic code 0x%08x\n",
hdr.magic_code);
ret = -EINVAL;
goto out;
}
#endif
if (hdr.count > MAX_IMG_CNT) {
- printk(KERN_ERR "gdmwm: Too many images. %d\n", hdr.count);
+ dev_err(&usbdev->dev, "Too many images. %d\n", hdr.count);
ret = -EINVAL;
goto out;
}
for (i = 0; i < hdr.count; i++) {
if (hdr.offset[i] > hdr.len) {
- printk(KERN_ERR "gdmwm: Invalid offset. "
- "Entry = %d Offset = 0x%08x "
- "Image length = 0x%08x\n",
+ dev_err(&usbdev->dev,
+ "Invalid offset. Entry = %d Offset = 0x%08x Image length = 0x%08x\n",
i, hdr.offset[i], hdr.len);
ret = -EINVAL;
goto out;
@@ -196,7 +196,7 @@ int usb_boot(struct usb_device *usbdev, u16 pid)
pos = hdr.offset[i];
if (firm->size < sizeof(fw_info) + pos) {
- printk(KERN_ERR "gdmwm: Cannot read the FW info.\n");
+ dev_err(&usbdev->dev, "Cannot read the FW info.\n");
ret = -EIO;
goto out;
}
@@ -205,7 +205,7 @@ int usb_boot(struct usb_device *usbdev, u16 pid)
array_le32_to_cpu((u32 *)&fw_info, 8);
#if 0
if ((fw_info.id & 0xfffff000) != 0x10767000) {
- printk(KERN_ERR "gdmwm: Invalid FW id. 0x%08x\n",
+ dev_err(&usbdev->dev, "Invalid FW id. 0x%08x\n",
fw_info.id);
ret = -EIO;
goto out;
@@ -217,7 +217,7 @@ int usb_boot(struct usb_device *usbdev, u16 pid)
pos = hdr.offset[i] + fw_info.kernel_offset;
if (firm->size < fw_info.kernel_len + pos) {
- printk(KERN_ERR "gdmwm: Kernel FW is too small.\n");
+ dev_err(&usbdev->dev, "Kernel FW is too small.\n");
goto out;
}
@@ -225,24 +225,25 @@ int usb_boot(struct usb_device *usbdev, u16 pid)
fw_info.kernel_len, DN_KERNEL_MAGIC_NUMBER);
if (ret < 0)
goto out;
- printk(KERN_INFO "GCT: Kernel download success.\n");
+ dev_info(&usbdev->dev, "GCT: Kernel download success.\n");
pos = hdr.offset[i] + fw_info.rootfs_offset;
if (firm->size < fw_info.rootfs_len + pos) {
- printk(KERN_ERR "gdmwm: Filesystem FW is too small.\n");
+ dev_err(&usbdev->dev, "Filesystem FW is too small.\n");
goto out;
}
ret = download_image(usbdev, firm, pos, fw_info.rootfs_len,
DN_ROOTFS_MAGIC_NUMBER);
if (ret < 0)
goto out;
- printk(KERN_INFO "GCT: Filesystem download success.\n");
+ dev_info(&usbdev->dev, "GCT: Filesystem download success.\n");
break;
}
if (i == hdr.count) {
- printk(KERN_ERR "Firmware for gsk%x is not installed.\n", pid);
+ dev_err(&usbdev->dev, "Firmware for gsk%x is not installed.\n",
+ pid);
ret = -EINVAL;
}
out:
@@ -293,15 +294,15 @@ static int em_download_image(struct usb_device *usbdev, const char *img_name,
ret = request_firmware(&firm, img_name, &usbdev->dev);
if (ret < 0) {
- printk(KERN_ERR
- "requesting firmware %s failed with error %d\n",
+ dev_err(&usbdev->dev,
+ "requesting firmware %s failed with error %d\n",
img_name, ret);
return ret;
}
buf = kmalloc(DOWNLOAD_CHUCK + pad_size, GFP_KERNEL);
if (buf == NULL) {
- printk(KERN_ERR "Error: kmalloc\n");
+ dev_err(&usbdev->dev, "Error: kmalloc\n");
return -ENOMEM;
}
@@ -366,12 +367,12 @@ int usb_emergency(struct usb_device *usbdev)
ret = em_download_image(usbdev, kern_name, KERNEL_TYPE_STRING);
if (ret < 0)
return ret;
- printk(KERN_INFO "GCT Emergency: Kernel download success.\n");
+ dev_err(&usbdev->dev, "GCT Emergency: Kernel download success.\n");
ret = em_download_image(usbdev, fs_name, FS_TYPE_STRING);
if (ret < 0)
return ret;
- printk(KERN_INFO "GCT Emergency: Filesystem download success.\n");
+ dev_info(&usbdev->dev, "GCT Emergency: Filesystem download success.\n");
ret = em_fw_reset(usbdev);
diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig
index 5ab71670b70..2b54430f2d9 100644
--- a/drivers/staging/iio/accel/Kconfig
+++ b/drivers/staging/iio/accel/Kconfig
@@ -6,8 +6,8 @@ menu "Accelerometers"
config ADIS16201
tristate "Analog Devices ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer"
depends on SPI
- select IIO_TRIGGER if IIO_BUFFER
- select IIO_SW_RING if IIO_BUFFER
+ select IIO_ADIS_LIB
+ select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
help
Say yes here to build support for Analog Devices adis16201 dual-axis
digital inclinometer and accelerometer.
@@ -15,8 +15,8 @@ config ADIS16201
config ADIS16203
tristate "Analog Devices ADIS16203 Programmable 360 Degrees Inclinometer"
depends on SPI
- select IIO_TRIGGER if IIO_BUFFER
- select IIO_SW_RING if IIO_BUFFER
+ select IIO_ADIS_LIB
+ select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
help
Say yes here to build support for Analog Devices adis16203 Programmable
360 Degrees Inclinometer.
@@ -24,8 +24,8 @@ config ADIS16203
config ADIS16204
tristate "Analog Devices ADIS16204 Programmable High-g Digital Impact Sensor and Recorder"
depends on SPI
- select IIO_TRIGGER if IIO_BUFFER
- select IIO_SW_RING if IIO_BUFFER
+ select IIO_ADIS_LIB
+ select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
help
Say yes here to build support for Analog Devices adis16204 Programmable
High-g Digital Impact Sensor and Recorder.
@@ -33,8 +33,8 @@ config ADIS16204
config ADIS16209
tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer"
depends on SPI
- select IIO_TRIGGER if IIO_BUFFER
- select IIO_SW_RING if IIO_BUFFER
+ select IIO_ADIS_LIB
+ select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
help
Say yes here to build support for Analog Devices adis16209 dual-axis digital inclinometer
and accelerometer.
@@ -42,6 +42,7 @@ config ADIS16209
config ADIS16220
tristate "Analog Devices ADIS16220 Programmable Digital Vibration Sensor"
depends on SPI
+ select IIO_ADIS_LIB
help
Say yes here to build support for Analog Devices adis16220 programmable
digital vibration sensor.
@@ -49,8 +50,8 @@ config ADIS16220
config ADIS16240
tristate "Analog Devices ADIS16240 Programmable Impact Sensor and Recorder"
depends on SPI
- select IIO_TRIGGER if IIO_BUFFER
- select IIO_SW_RING if IIO_BUFFER
+ select IIO_ADIS_LIB
+ select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
help
Say yes here to build support for Analog Devices adis16240 programmable
impact Sensor and recorder.
diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile
index 95c66661e70..8e7ee036851 100644
--- a/drivers/staging/iio/accel/Makefile
+++ b/drivers/staging/iio/accel/Makefile
@@ -3,26 +3,21 @@
#
adis16201-y := adis16201_core.o
-adis16201-$(CONFIG_IIO_BUFFER) += adis16201_ring.o adis16201_trigger.o
obj-$(CONFIG_ADIS16201) += adis16201.o
adis16203-y := adis16203_core.o
-adis16203-$(CONFIG_IIO_BUFFER) += adis16203_ring.o adis16203_trigger.o
obj-$(CONFIG_ADIS16203) += adis16203.o
adis16204-y := adis16204_core.o
-adis16204-$(CONFIG_IIO_BUFFER) += adis16204_ring.o adis16204_trigger.o
obj-$(CONFIG_ADIS16204) += adis16204.o
adis16209-y := adis16209_core.o
-adis16209-$(CONFIG_IIO_BUFFER) += adis16209_ring.o adis16209_trigger.o
obj-$(CONFIG_ADIS16209) += adis16209.o
adis16220-y := adis16220_core.o
obj-$(CONFIG_ADIS16220) += adis16220.o
adis16240-y := adis16240_core.o
-adis16240-$(CONFIG_IIO_BUFFER) += adis16240_ring.o adis16240_trigger.o
obj-$(CONFIG_ADIS16240) += adis16240.o
obj-$(CONFIG_KXSD9) += kxsd9.o
diff --git a/drivers/staging/iio/accel/adis16201.h b/drivers/staging/iio/accel/adis16201.h
index 72750f7f3a8..8747de5a980 100644
--- a/drivers/staging/iio/accel/adis16201.h
+++ b/drivers/staging/iio/accel/adis16201.h
@@ -3,9 +3,6 @@
#define ADIS16201_STARTUP_DELAY 220 /* ms */
-#define ADIS16201_READ_REG(a) a
-#define ADIS16201_WRITE_REG(a) ((a) | 0x80)
-
#define ADIS16201_FLASH_CNT 0x00 /* Flash memory write count */
#define ADIS16201_SUPPLY_OUT 0x02 /* Output, power supply */
#define ADIS16201_XACCL_OUT 0x04 /* Output, x-axis accelerometer */
@@ -36,8 +33,6 @@
#define ADIS16201_DIAG_STAT 0x3C /* Diagnostics, system status register */
#define ADIS16201_GLOB_CMD 0x3E /* Operation, system command register */
-#define ADIS16201_OUTPUTS 7
-
/* MSC_CTRL */
#define ADIS16201_MSC_CTRL_SELF_TEST_EN (1 << 8) /* Self-test enable */
#define ADIS16201_MSC_CTRL_DATA_RDY_EN (1 << 2) /* Data-ready enable: 1 = enabled, 0 = disabled */
@@ -47,95 +42,25 @@
/* DIAG_STAT */
#define ADIS16201_DIAG_STAT_ALARM2 (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
#define ADIS16201_DIAG_STAT_ALARM1 (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
-#define ADIS16201_DIAG_STAT_SPI_FAIL (1<<3) /* SPI communications failure */
-#define ADIS16201_DIAG_STAT_FLASH_UPT (1<<2) /* Flash update failure */
-#define ADIS16201_DIAG_STAT_POWER_HIGH (1<<1) /* Power supply above 3.625 V */
-#define ADIS16201_DIAG_STAT_POWER_LOW (1<<0) /* Power supply below 3.15 V */
+#define ADIS16201_DIAG_STAT_SPI_FAIL_BIT 3 /* SPI communications failure */
+#define ADIS16201_DIAG_STAT_FLASH_UPT_BIT 2 /* Flash update failure */
+#define ADIS16201_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply above 3.625 V */
+#define ADIS16201_DIAG_STAT_POWER_LOW_BIT 0 /* Power supply below 3.15 V */
/* GLOB_CMD */
#define ADIS16201_GLOB_CMD_SW_RESET (1<<7)
#define ADIS16201_GLOB_CMD_FACTORY_CAL (1<<1)
-#define ADIS16201_MAX_TX 14
-#define ADIS16201_MAX_RX 14
-
#define ADIS16201_ERROR_ACTIVE (1<<14)
-/**
- * struct adis16201_state - device instance specific data
- * @us: actual spi_device
- * @trig: data ready trigger registered with iio
- * @tx: transmit buffer
- * @rx: receive buffer
- * @buf_lock: mutex to protect tx and rx
- **/
-struct adis16201_state {
- struct spi_device *us;
- struct iio_trigger *trig;
- struct mutex buf_lock;
- u8 tx[14] ____cacheline_aligned;
- u8 rx[14];
-};
-
-int adis16201_set_irq(struct iio_dev *indio_dev, bool enable);
-
enum adis16201_scan {
- ADIS16201_SCAN_SUPPLY,
ADIS16201_SCAN_ACC_X,
ADIS16201_SCAN_ACC_Y,
- ADIS16201_SCAN_AUX_ADC,
- ADIS16201_SCAN_TEMP,
ADIS16201_SCAN_INCLI_X,
ADIS16201_SCAN_INCLI_Y,
+ ADIS16201_SCAN_SUPPLY,
+ ADIS16201_SCAN_AUX_ADC,
+ ADIS16201_SCAN_TEMP,
};
-#ifdef CONFIG_IIO_BUFFER
-void adis16201_remove_trigger(struct iio_dev *indio_dev);
-int adis16201_probe_trigger(struct iio_dev *indio_dev);
-
-ssize_t adis16201_read_data_from_ring(struct device *dev,
- struct device_attribute *attr,
- char *buf);
-
-int adis16201_configure_ring(struct iio_dev *indio_dev);
-void adis16201_unconfigure_ring(struct iio_dev *indio_dev);
-
-#else /* CONFIG_IIO_BUFFER */
-
-static inline void adis16201_remove_trigger(struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis16201_probe_trigger(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline ssize_t
-adis16201_read_data_from_ring(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return 0;
-}
-
-static int adis16201_configure_ring(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void adis16201_unconfigure_ring(struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis16201_initialize_ring(struct iio_ring_buffer *ring)
-{
- return 0;
-}
-
-static inline void adis16201_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-}
-
-#endif /* CONFIG_IIO_BUFFER */
#endif /* SPI_ADIS16201_H_ */
diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c
index b12ca68cd9e..9e5791ff2a0 100644
--- a/drivers/staging/iio/accel/adis16201_core.c
+++ b/drivers/staging/iio/accel/adis16201_core.c
@@ -18,258 +18,15 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
#include "adis16201.h"
-enum adis16201_chan {
- in_supply,
- temp,
- accel_x,
- accel_y,
- incli_x,
- incli_y,
- in_aux,
-};
-
-/**
- * adis16201_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the register to be written
- * @val: the value to write
- **/
-static int adis16201_spi_write_reg_8(struct iio_dev *indio_dev,
- u8 reg_address,
- u8 val)
-{
- int ret;
- struct adis16201_state *st = iio_priv(indio_dev);
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16201_WRITE_REG(reg_address);
- st->tx[1] = val;
-
- ret = spi_write(st->us, st->tx, 2);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16201_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @indio_dev: iio device associated with child of actual device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: value to be written
- **/
-static int adis16201_spi_write_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 value)
-{
- int ret;
- struct spi_message msg;
- struct adis16201_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- }, {
- .tx_buf = st->tx + 2,
- .bits_per_word = 8,
- .len = 2,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16201_WRITE_REG(lower_reg_address);
- st->tx[1] = value & 0xFF;
- st->tx[2] = ADIS16201_WRITE_REG(lower_reg_address + 1);
- st->tx[3] = (value >> 8) & 0xFF;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16201_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @indio_dev: iio device associated with child of actual device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: somewhere to pass back the value read
- **/
-static int adis16201_spi_read_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 *val)
-{
- struct spi_message msg;
- struct adis16201_state *st = iio_priv(indio_dev);
- int ret;
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- .delay_usecs = 20,
- }, {
- .rx_buf = st->rx,
- .bits_per_word = 8,
- .len = 2,
- .delay_usecs = 20,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16201_READ_REG(lower_reg_address);
- st->tx[1] = 0;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- if (ret) {
- dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
- lower_reg_address);
- goto error_ret;
- }
- *val = (st->rx[0] << 8) | st->rx[1];
-
-error_ret:
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
-static int adis16201_reset(struct iio_dev *indio_dev)
-{
- int ret;
- struct adis16201_state *st = iio_priv(indio_dev);
-
- ret = adis16201_spi_write_reg_8(indio_dev,
- ADIS16201_GLOB_CMD,
- ADIS16201_GLOB_CMD_SW_RESET);
- if (ret)
- dev_err(&st->us->dev, "problem resetting device");
-
- return ret;
-}
-
-int adis16201_set_irq(struct iio_dev *indio_dev, bool enable)
-{
- int ret = 0;
- u16 msc;
-
- ret = adis16201_spi_read_reg_16(indio_dev, ADIS16201_MSC_CTRL, &msc);
- if (ret)
- goto error_ret;
-
- msc |= ADIS16201_MSC_CTRL_ACTIVE_HIGH;
- msc &= ~ADIS16201_MSC_CTRL_DATA_RDY_DIO1;
- if (enable)
- msc |= ADIS16201_MSC_CTRL_DATA_RDY_EN;
- else
- msc &= ~ADIS16201_MSC_CTRL_DATA_RDY_EN;
-
- ret = adis16201_spi_write_reg_16(indio_dev, ADIS16201_MSC_CTRL, msc);
-
-error_ret:
- return ret;
-}
-
-static int adis16201_check_status(struct iio_dev *indio_dev)
-{
- u16 status;
- int ret;
-
- ret = adis16201_spi_read_reg_16(indio_dev,
- ADIS16201_DIAG_STAT, &status);
- if (ret < 0) {
- dev_err(&indio_dev->dev, "Reading status failed\n");
- goto error_ret;
- }
- ret = status & 0xF;
- if (ret)
- ret = -EFAULT;
-
- if (status & ADIS16201_DIAG_STAT_SPI_FAIL)
- dev_err(&indio_dev->dev, "SPI failure\n");
- if (status & ADIS16201_DIAG_STAT_FLASH_UPT)
- dev_err(&indio_dev->dev, "Flash update failed\n");
- if (status & ADIS16201_DIAG_STAT_POWER_HIGH)
- dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
- if (status & ADIS16201_DIAG_STAT_POWER_LOW)
- dev_err(&indio_dev->dev, "Power supply below 3.15V\n");
-
-error_ret:
- return ret;
-}
-
-static int adis16201_self_test(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16201_spi_write_reg_16(indio_dev,
- ADIS16201_MSC_CTRL,
- ADIS16201_MSC_CTRL_SELF_TEST_EN);
- if (ret) {
- dev_err(&indio_dev->dev, "problem starting self test");
- goto err_ret;
- }
-
- ret = adis16201_check_status(indio_dev);
-
-err_ret:
- return ret;
-}
-
-static int adis16201_initial_setup(struct iio_dev *indio_dev)
-{
- int ret;
- struct device *dev = &indio_dev->dev;
-
- /* Disable IRQ */
- ret = adis16201_set_irq(indio_dev, false);
- if (ret) {
- dev_err(dev, "disable irq failed");
- goto err_ret;
- }
-
- /* Do self test */
- ret = adis16201_self_test(indio_dev);
- if (ret) {
- dev_err(dev, "self test failure");
- goto err_ret;
- }
-
- /* Read status register to check the result */
- ret = adis16201_check_status(indio_dev);
- if (ret) {
- adis16201_reset(indio_dev);
- dev_err(dev, "device not playing ball -> reset");
- msleep(ADIS16201_STARTUP_DELAY);
- ret = adis16201_check_status(indio_dev);
- if (ret) {
- dev_err(dev, "giving up");
- goto err_ret;
- }
- }
-
-err_ret:
- return ret;
-}
-
-static u8 adis16201_addresses[7][2] = {
- [in_supply] = { ADIS16201_SUPPLY_OUT, },
- [temp] = { ADIS16201_TEMP_OUT },
- [accel_x] = { ADIS16201_XACCL_OUT, ADIS16201_XACCL_OFFS },
- [accel_y] = { ADIS16201_YACCL_OUT, ADIS16201_YACCL_OFFS },
- [in_aux] = { ADIS16201_AUX_ADC },
- [incli_x] = { ADIS16201_XINCL_OUT },
- [incli_y] = { ADIS16201_YINCL_OUT },
+static const u8 adis16201_addresses[] = {
+ [ADIS16201_SCAN_ACC_X] = ADIS16201_XACCL_OFFS,
+ [ADIS16201_SCAN_ACC_Y] = ADIS16201_YACCL_OFFS,
+ [ADIS16201_SCAN_INCLI_X] = ADIS16201_XINCL_OFFS,
+ [ADIS16201_SCAN_INCLI_Y] = ADIS16201_YINCL_OFFS,
};
static int adis16201_read_raw(struct iio_dev *indio_dev,
@@ -277,6 +34,7 @@ static int adis16201_read_raw(struct iio_dev *indio_dev,
int *val, int *val2,
long mask)
{
+ struct adis *st = iio_priv(indio_dev);
int ret;
int bits;
u8 addr;
@@ -284,29 +42,8 @@ static int adis16201_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
- mutex_lock(&indio_dev->mlock);
- addr = adis16201_addresses[chan->address][0];
- ret = adis16201_spi_read_reg_16(indio_dev, addr, &val16);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
-
- if (val16 & ADIS16201_ERROR_ACTIVE) {
- ret = adis16201_check_status(indio_dev);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
- }
- val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
- if (chan->scan_type.sign == 's')
- val16 = (s16)(val16 <<
- (16 - chan->scan_type.realbits)) >>
- (16 - chan->scan_type.realbits);
- *val = val16;
- mutex_unlock(&indio_dev->mlock);
- return IIO_VAL_INT;
+ return adis_single_conversion(indio_dev, chan,
+ ADIS16201_ERROR_ACTIVE, val);
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_VOLTAGE:
@@ -347,10 +84,10 @@ static int adis16201_read_raw(struct iio_dev *indio_dev,
break;
default:
return -EINVAL;
- };
+ }
mutex_lock(&indio_dev->mlock);
- addr = adis16201_addresses[chan->address][1];
- ret = adis16201_spi_read_reg_16(indio_dev, addr, &val16);
+ addr = adis16201_addresses[chan->scan_index];
+ ret = adis_read_reg_16(st, addr, &val16);
if (ret) {
mutex_unlock(&indio_dev->mlock);
return ret;
@@ -370,6 +107,7 @@ static int adis16201_write_raw(struct iio_dev *indio_dev,
int val2,
long mask)
{
+ struct adis *st = iio_priv(indio_dev);
int bits;
s16 val16;
u8 addr;
@@ -384,126 +122,63 @@ static int adis16201_write_raw(struct iio_dev *indio_dev,
break;
default:
return -EINVAL;
- };
+ }
val16 = val & ((1 << bits) - 1);
- addr = adis16201_addresses[chan->address][1];
- return adis16201_spi_write_reg_16(indio_dev, addr, val16);
+ addr = adis16201_addresses[chan->scan_index];
+ return adis_write_reg_16(st, addr, val16);
}
return -EINVAL;
}
static const struct iio_chan_spec adis16201_channels[] = {
- {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 0,
- .extend_name = "supply",
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in_supply,
- .scan_index = ADIS16201_SCAN_SUPPLY,
- .scan_type = {
- .sign = 'u',
- .realbits = 12,
- .storagebits = 16,
- },
- }, {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
- IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
- .address = temp,
- .scan_index = ADIS16201_SCAN_TEMP,
- .scan_type = {
- .sign = 'u',
- .realbits = 12,
- .storagebits = 16,
- },
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
- .address = accel_x,
- .scan_index = ADIS16201_SCAN_ACC_X,
- .scan_type = {
- .sign = 's',
- .realbits = 14,
- .storagebits = 16,
- },
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
- .address = accel_y,
- .scan_index = ADIS16201_SCAN_ACC_Y,
- .scan_type = {
- .sign = 's',
- .realbits = 14,
- .storagebits = 16,
- },
- }, {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 1,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in_aux,
- .scan_index = ADIS16201_SCAN_AUX_ADC,
- .scan_type = {
- .sign = 'u',
- .realbits = 12,
- .storagebits = 16,
- },
- }, {
- .type = IIO_INCLI,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
- .address = incli_x,
- .scan_index = ADIS16201_SCAN_INCLI_X,
- .scan_type = {
- .sign = 's',
- .realbits = 14,
- .storagebits = 16,
- },
- }, {
- .type = IIO_INCLI,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
- .address = incli_y,
- .scan_index = ADIS16201_SCAN_INCLI_Y,
- .scan_type = {
- .sign = 's',
- .realbits = 14,
- .storagebits = 16,
- },
- },
+ ADIS_SUPPLY_CHAN(ADIS16201_SUPPLY_OUT, ADIS16201_SCAN_SUPPLY, 12),
+ ADIS_TEMP_CHAN(ADIS16201_TEMP_OUT, ADIS16201_SCAN_TEMP, 12),
+ ADIS_ACCEL_CHAN(X, ADIS16201_XACCL_OUT, ADIS16201_SCAN_ACC_X,
+ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14),
+ ADIS_ACCEL_CHAN(Y, ADIS16201_YACCL_OUT, ADIS16201_SCAN_ACC_Y,
+ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14),
+ ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC, ADIS16201_SCAN_AUX_ADC, 12),
+ ADIS_INCLI_CHAN(X, ADIS16201_XINCL_OUT, ADIS16201_SCAN_INCLI_X,
+ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14),
+ ADIS_INCLI_CHAN(X, ADIS16201_YINCL_OUT, ADIS16201_SCAN_INCLI_Y,
+ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14),
IIO_CHAN_SOFT_TIMESTAMP(7)
};
static const struct iio_info adis16201_info = {
.read_raw = &adis16201_read_raw,
.write_raw = &adis16201_write_raw,
+ .update_scan_mode = adis_update_scan_mode,
.driver_module = THIS_MODULE,
};
-static int __devinit adis16201_probe(struct spi_device *spi)
+static const char * const adis16201_status_error_msgs[] = {
+ [ADIS16201_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure",
+ [ADIS16201_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed",
+ [ADIS16201_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V",
+ [ADIS16201_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V",
+};
+
+static const struct adis_data adis16201_data = {
+ .read_delay = 20,
+ .msc_ctrl_reg = ADIS16201_MSC_CTRL,
+ .glob_cmd_reg = ADIS16201_GLOB_CMD,
+ .diag_stat_reg = ADIS16201_DIAG_STAT,
+
+ .self_test_mask = ADIS16201_MSC_CTRL_SELF_TEST_EN,
+ .startup_delay = ADIS16201_STARTUP_DELAY,
+
+ .status_error_msgs = adis16201_status_error_msgs,
+ .status_error_mask = BIT(ADIS16201_DIAG_STAT_SPI_FAIL_BIT) |
+ BIT(ADIS16201_DIAG_STAT_FLASH_UPT_BIT) |
+ BIT(ADIS16201_DIAG_STAT_POWER_HIGH_BIT) |
+ BIT(ADIS16201_DIAG_STAT_POWER_LOW_BIT),
+};
+
+static int adis16201_probe(struct spi_device *spi)
{
int ret;
- struct adis16201_state *st;
+ struct adis *st;
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
@@ -516,9 +191,6 @@ static int __devinit adis16201_probe(struct spi_device *spi)
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
- st->us = spi;
- mutex_init(&st->buf_lock);
-
indio_dev->name = spi->dev.driver->name;
indio_dev->dev.parent = &spi->dev;
indio_dev->info = &adis16201_info;
@@ -527,54 +199,38 @@ static int __devinit adis16201_probe(struct spi_device *spi)
indio_dev->num_channels = ARRAY_SIZE(adis16201_channels);
indio_dev->modes = INDIO_DIRECT_MODE;
- ret = adis16201_configure_ring(indio_dev);
+ ret = adis_init(st, indio_dev, spi, &adis16201_data);
+ if (ret)
+ goto error_free_dev;
+ ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL);
if (ret)
goto error_free_dev;
-
- ret = iio_buffer_register(indio_dev,
- adis16201_channels,
- ARRAY_SIZE(adis16201_channels));
- if (ret) {
- printk(KERN_ERR "failed to initialize the ring\n");
- goto error_unreg_ring_funcs;
- }
-
- if (spi->irq) {
- ret = adis16201_probe_trigger(indio_dev);
- if (ret)
- goto error_uninitialize_ring;
- }
/* Get the device into a sane initial state */
- ret = adis16201_initial_setup(indio_dev);
+ ret = adis_initial_startup(st);
if (ret)
- goto error_remove_trigger;
+ goto error_cleanup_buffer_trigger;
ret = iio_device_register(indio_dev);
if (ret < 0)
- goto error_remove_trigger;
+ goto error_cleanup_buffer_trigger;
return 0;
-error_remove_trigger:
- adis16201_remove_trigger(indio_dev);
-error_uninitialize_ring:
- iio_buffer_unregister(indio_dev);
-error_unreg_ring_funcs:
- adis16201_unconfigure_ring(indio_dev);
+error_cleanup_buffer_trigger:
+ adis_cleanup_buffer_and_trigger(st, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
-static int __devexit adis16201_remove(struct spi_device *spi)
+static int adis16201_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct adis *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- adis16201_remove_trigger(indio_dev);
- iio_buffer_unregister(indio_dev);
- adis16201_unconfigure_ring(indio_dev);
+ adis_cleanup_buffer_and_trigger(st, indio_dev);
iio_device_free(indio_dev);
return 0;
@@ -586,7 +242,7 @@ static struct spi_driver adis16201_driver = {
.owner = THIS_MODULE,
},
.probe = adis16201_probe,
- .remove = __devexit_p(adis16201_remove),
+ .remove = adis16201_remove,
};
module_spi_driver(adis16201_driver);
diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c
deleted file mode 100644
index 97c09f0c26a..00000000000
--- a/drivers/staging/iio/accel/adis16201_ring.c
+++ /dev/null
@@ -1,136 +0,0 @@
-#include <linux/export.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-
-#include <linux/iio/iio.h>
-#include "../ring_sw.h"
-#include <linux/iio/trigger_consumer.h>
-#include "adis16201.h"
-
-
-/**
- * adis16201_read_ring_data() read data registers which will be placed into ring
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @rx: somewhere to pass back the value read
- **/
-static int adis16201_read_ring_data(struct iio_dev *indio_dev, u8 *rx)
-{
- struct spi_message msg;
- struct adis16201_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[ADIS16201_OUTPUTS + 1];
- int ret;
- int i;
-
- mutex_lock(&st->buf_lock);
-
- spi_message_init(&msg);
-
- memset(xfers, 0, sizeof(xfers));
- for (i = 0; i <= ADIS16201_OUTPUTS; i++) {
- xfers[i].bits_per_word = 8;
- xfers[i].cs_change = 1;
- xfers[i].len = 2;
- xfers[i].delay_usecs = 20;
- if (i < ADIS16201_OUTPUTS) {
- xfers[i].tx_buf = st->tx + 2 * i;
- st->tx[2 * i] = ADIS16201_READ_REG(ADIS16201_SUPPLY_OUT +
- 2 * i);
- st->tx[2 * i + 1] = 0;
- }
- if (i >= 1)
- xfers[i].rx_buf = rx + 2 * (i - 1);
- spi_message_add_tail(&xfers[i], &msg);
- }
-
- ret = spi_sync(st->us, &msg);
- if (ret)
- dev_err(&st->us->dev, "problem when burst reading");
-
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
- * specific to be rolled into the core.
- */
-static irqreturn_t adis16201_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct adis16201_state *st = iio_priv(indio_dev);
-
- int i = 0;
- s16 *data;
-
- data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
- if (data == NULL) {
- dev_err(&st->us->dev, "memory alloc failed in ring bh");
- goto done;
- }
-
- if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)
- && adis16201_read_ring_data(indio_dev, st->rx) >= 0)
- for (; i < bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength); i++)
- data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
-
- /* Guaranteed to be aligned with 8 byte boundary */
- if (indio_dev->scan_timestamp)
- *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
-
- iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
-
- kfree(data);
-done:
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-void adis16201_unconfigure_ring(struct iio_dev *indio_dev)
-{
- iio_dealloc_pollfunc(indio_dev->pollfunc);
- iio_sw_rb_free(indio_dev->buffer);
-}
-
-static const struct iio_buffer_setup_ops adis16201_ring_setup_ops = {
- .preenable = &iio_sw_buffer_preenable,
- .postenable = &iio_triggered_buffer_postenable,
- .predisable = &iio_triggered_buffer_predisable,
-};
-
-int adis16201_configure_ring(struct iio_dev *indio_dev)
-{
- int ret = 0;
- struct iio_buffer *ring;
-
- ring = iio_sw_rb_allocate(indio_dev);
- if (!ring) {
- ret = -ENOMEM;
- return ret;
- }
- indio_dev->buffer = ring;
- ring->scan_timestamp = true;
- indio_dev->setup_ops = &adis16201_ring_setup_ops;
-
- indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
- &adis16201_trigger_handler,
- IRQF_ONESHOT,
- indio_dev,
- "adis16201_consumer%d",
- indio_dev->id);
- if (indio_dev->pollfunc == NULL) {
- ret = -ENOMEM;
- goto error_iio_sw_rb_free;
- }
-
- indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
- return 0;
-error_iio_sw_rb_free:
- iio_sw_rb_free(indio_dev->buffer);
- return ret;
-}
diff --git a/drivers/staging/iio/accel/adis16201_trigger.c b/drivers/staging/iio/accel/adis16201_trigger.c
deleted file mode 100644
index 96fdabbac20..00000000000
--- a/drivers/staging/iio/accel/adis16201_trigger.c
+++ /dev/null
@@ -1,71 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/export.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/trigger.h>
-#include "adis16201.h"
-
-/**
- * adis16201_data_rdy_trigger_set_state() set datardy interrupt state
- **/
-static int adis16201_data_rdy_trigger_set_state(struct iio_trigger *trig,
- bool state)
-{
- struct iio_dev *indio_dev = trig->private_data;
-
- dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
- return adis16201_set_irq(indio_dev, state);
-}
-
-static const struct iio_trigger_ops adis16201_trigger_ops = {
- .owner = THIS_MODULE,
- .set_trigger_state = &adis16201_data_rdy_trigger_set_state,
-};
-
-int adis16201_probe_trigger(struct iio_dev *indio_dev)
-{
- int ret;
- struct adis16201_state *st = iio_priv(indio_dev);
-
- st->trig = iio_trigger_alloc("adis16201-dev%d", indio_dev->id);
- if (st->trig == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
- ret = request_irq(st->us->irq,
- &iio_trigger_generic_data_rdy_poll,
- IRQF_TRIGGER_RISING,
- "adis16201",
- st->trig);
- if (ret)
- goto error_free_trig;
- st->trig->dev.parent = &st->us->dev;
- st->trig->ops = &adis16201_trigger_ops;
- st->trig->private_data = indio_dev;
- ret = iio_trigger_register(st->trig);
-
- /* select default trigger */
- indio_dev->trig = st->trig;
- if (ret)
- goto error_free_irq;
-
- return 0;
-
-error_free_irq:
- free_irq(st->us->irq, st->trig);
-error_free_trig:
- iio_trigger_free(st->trig);
-error_ret:
- return ret;
-}
-
-void adis16201_remove_trigger(struct iio_dev *indio_dev)
-{
- struct adis16201_state *state = iio_priv(indio_dev);
-
- iio_trigger_unregister(state->trig);
- free_irq(state->us->irq, state->trig);
- iio_trigger_free(state->trig);
-}
diff --git a/drivers/staging/iio/accel/adis16203.h b/drivers/staging/iio/accel/adis16203.h
index 3f96ad3bbd6..acc688d7ea9 100644
--- a/drivers/staging/iio/accel/adis16203.h
+++ b/drivers/staging/iio/accel/adis16203.h
@@ -3,9 +3,6 @@
#define ADIS16203_STARTUP_DELAY 220 /* ms */
-#define ADIS16203_READ_REG(a) a
-#define ADIS16203_WRITE_REG(a) ((a) | 0x80)
-
#define ADIS16203_FLASH_CNT 0x00 /* Flash memory write count */
#define ADIS16203_SUPPLY_OUT 0x02 /* Output, power supply */
#define ADIS16203_AUX_ADC 0x08 /* Output, auxiliary ADC input */
@@ -27,8 +24,6 @@
#define ADIS16203_DIAG_STAT 0x3C /* Diagnostics, system status register */
#define ADIS16203_GLOB_CMD 0x3E /* Operation, system command register */
-#define ADIS16203_OUTPUTS 5
-
/* MSC_CTRL */
#define ADIS16203_MSC_CTRL_PWRUP_SELF_TEST (1 << 10) /* Self-test at power-on: 1 = disabled, 0 = enabled */
#define ADIS16203_MSC_CTRL_REVERSE_ROT_EN (1 << 9) /* Reverses rotation of both inclination outputs */
@@ -40,86 +35,25 @@
/* DIAG_STAT */
#define ADIS16203_DIAG_STAT_ALARM2 (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
#define ADIS16203_DIAG_STAT_ALARM1 (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
-#define ADIS16203_DIAG_STAT_SELFTEST_FAIL (1<<5) /* Self-test diagnostic error flag */
-#define ADIS16203_DIAG_STAT_SPI_FAIL (1<<3) /* SPI communications failure */
-#define ADIS16203_DIAG_STAT_FLASH_UPT (1<<2) /* Flash update failure */
-#define ADIS16203_DIAG_STAT_POWER_HIGH (1<<1) /* Power supply above 3.625 V */
-#define ADIS16203_DIAG_STAT_POWER_LOW (1<<0) /* Power supply below 3.15 V */
+#define ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT 5 /* Self-test diagnostic error flag */
+#define ADIS16203_DIAG_STAT_SPI_FAIL_BIT 3 /* SPI communications failure */
+#define ADIS16203_DIAG_STAT_FLASH_UPT_BIT 2 /* Flash update failure */
+#define ADIS16203_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply above 3.625 V */
+#define ADIS16203_DIAG_STAT_POWER_LOW_BIT 0 /* Power supply below 3.15 V */
/* GLOB_CMD */
#define ADIS16203_GLOB_CMD_SW_RESET (1<<7)
#define ADIS16203_GLOB_CMD_CLEAR_STAT (1<<4)
#define ADIS16203_GLOB_CMD_FACTORY_CAL (1<<1)
-#define ADIS16203_MAX_TX 12
-#define ADIS16203_MAX_RX 10
-
#define ADIS16203_ERROR_ACTIVE (1<<14)
-/**
- * struct adis16203_state - device instance specific data
- * @us: actual spi_device
- * @trig: data ready trigger registered with iio
- * @tx: transmit buffer
- * @rx: receive buffer
- * @buf_lock: mutex to protect tx and rx
- **/
-struct adis16203_state {
- struct spi_device *us;
- struct iio_trigger *trig;
- struct mutex buf_lock;
- u8 tx[ADIS16203_MAX_TX] ____cacheline_aligned;
- u8 rx[ADIS16203_MAX_RX];
-};
-
-int adis16203_set_irq(struct iio_dev *indio_dev, bool enable);
-
enum adis16203_scan {
+ ADIS16203_SCAN_INCLI_X,
+ ADIS16203_SCAN_INCLI_Y,
ADIS16203_SCAN_SUPPLY,
ADIS16203_SCAN_AUX_ADC,
ADIS16203_SCAN_TEMP,
- ADIS16203_SCAN_INCLI_X,
- ADIS16203_SCAN_INCLI_Y,
};
-#ifdef CONFIG_IIO_BUFFER
-void adis16203_remove_trigger(struct iio_dev *indio_dev);
-int adis16203_probe_trigger(struct iio_dev *indio_dev);
-
-ssize_t adis16203_read_data_from_ring(struct device *dev,
- struct device_attribute *attr,
- char *buf);
-
-int adis16203_configure_ring(struct iio_dev *indio_dev);
-void adis16203_unconfigure_ring(struct iio_dev *indio_dev);
-
-#else /* CONFIG_IIO_BUFFER */
-
-static inline void adis16203_remove_trigger(struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis16203_probe_trigger(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline ssize_t
-adis16203_read_data_from_ring(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return 0;
-}
-
-static int adis16203_configure_ring(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void adis16203_unconfigure_ring(struct iio_dev *indio_dev)
-{
-}
-
-#endif /* CONFIG_IIO_BUFFER */
#endif /* SPI_ADIS16203_H_ */
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c
index e7b3441115a..8c235273ff1 100644
--- a/drivers/staging/iio/accel/adis16203_core.c
+++ b/drivers/staging/iio/accel/adis16203_core.c
@@ -1,7 +1,7 @@
/*
* ADIS16203 Programmable Digital Vibration Sensor driver
*
- * Copyright 2010 Analog Devices Inc.
+ * Copyright 2030 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -18,254 +18,14 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
#include "adis16203.h"
#define DRIVER_NAME "adis16203"
-/**
- * adis16203_spi_write_reg_8() - write single byte to a register
- * @indio_dev: iio device associated with child of actual device
- * @reg_address: the address of the register to be written
- * @val: the value to write
- **/
-static int adis16203_spi_write_reg_8(struct iio_dev *indio_dev,
- u8 reg_address,
- u8 val)
-{
- int ret;
- struct adis16203_state *st = iio_priv(indio_dev);
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16203_WRITE_REG(reg_address);
- st->tx[1] = val;
-
- ret = spi_write(st->us, st->tx, 2);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16203_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @indio_dev: iio device associated with child of actual device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: value to be written
- **/
-static int adis16203_spi_write_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 value)
-{
- int ret;
- struct spi_message msg;
- struct adis16203_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- }, {
- .tx_buf = st->tx + 2,
- .bits_per_word = 8,
- .len = 2,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16203_WRITE_REG(lower_reg_address);
- st->tx[1] = value & 0xFF;
- st->tx[2] = ADIS16203_WRITE_REG(lower_reg_address + 1);
- st->tx[3] = (value >> 8) & 0xFF;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16203_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @indio_dev: iio device associated with child of actual device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: somewhere to pass back the value read
- **/
-static int adis16203_spi_read_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 *val)
-{
- struct spi_message msg;
- struct adis16203_state *st = iio_priv(indio_dev);
- int ret;
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- .delay_usecs = 20,
- }, {
- .rx_buf = st->rx,
- .bits_per_word = 8,
- .len = 2,
- .delay_usecs = 20,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16203_READ_REG(lower_reg_address);
- st->tx[1] = 0;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- if (ret) {
- dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
- lower_reg_address);
- goto error_ret;
- }
- *val = (st->rx[0] << 8) | st->rx[1];
-
-error_ret:
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
-static int adis16203_check_status(struct iio_dev *indio_dev)
-{
- u16 status;
- int ret;
-
- ret = adis16203_spi_read_reg_16(indio_dev,
- ADIS16203_DIAG_STAT,
- &status);
- if (ret < 0) {
- dev_err(&indio_dev->dev, "Reading status failed\n");
- goto error_ret;
- }
- ret = status & 0x1F;
-
- if (status & ADIS16203_DIAG_STAT_SELFTEST_FAIL)
- dev_err(&indio_dev->dev, "Self test failure\n");
- if (status & ADIS16203_DIAG_STAT_SPI_FAIL)
- dev_err(&indio_dev->dev, "SPI failure\n");
- if (status & ADIS16203_DIAG_STAT_FLASH_UPT)
- dev_err(&indio_dev->dev, "Flash update failed\n");
- if (status & ADIS16203_DIAG_STAT_POWER_HIGH)
- dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
- if (status & ADIS16203_DIAG_STAT_POWER_LOW)
- dev_err(&indio_dev->dev, "Power supply below 3.15V\n");
-
-error_ret:
- return ret;
-}
-
-static int adis16203_reset(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16203_spi_write_reg_8(indio_dev,
- ADIS16203_GLOB_CMD,
- ADIS16203_GLOB_CMD_SW_RESET);
- if (ret)
- dev_err(&indio_dev->dev, "problem resetting device");
-
- return ret;
-}
-
-int adis16203_set_irq(struct iio_dev *indio_dev, bool enable)
-{
- int ret = 0;
- u16 msc;
-
- ret = adis16203_spi_read_reg_16(indio_dev, ADIS16203_MSC_CTRL, &msc);
- if (ret)
- goto error_ret;
-
- msc |= ADIS16203_MSC_CTRL_ACTIVE_HIGH;
- msc &= ~ADIS16203_MSC_CTRL_DATA_RDY_DIO1;
- if (enable)
- msc |= ADIS16203_MSC_CTRL_DATA_RDY_EN;
- else
- msc &= ~ADIS16203_MSC_CTRL_DATA_RDY_EN;
-
- ret = adis16203_spi_write_reg_16(indio_dev, ADIS16203_MSC_CTRL, msc);
-
-error_ret:
- return ret;
-}
-
-static int adis16203_self_test(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16203_spi_write_reg_16(indio_dev,
- ADIS16203_MSC_CTRL,
- ADIS16203_MSC_CTRL_SELF_TEST_EN);
- if (ret) {
- dev_err(&indio_dev->dev, "problem starting self test");
- goto err_ret;
- }
-
- adis16203_check_status(indio_dev);
-
-err_ret:
- return ret;
-}
-
-static int adis16203_initial_setup(struct iio_dev *indio_dev)
-{
- int ret;
-
- /* Disable IRQ */
- ret = adis16203_set_irq(indio_dev, false);
- if (ret) {
- dev_err(&indio_dev->dev, "disable irq failed");
- goto err_ret;
- }
-
- /* Do self test */
- ret = adis16203_self_test(indio_dev);
- if (ret) {
- dev_err(&indio_dev->dev, "self test failure");
- goto err_ret;
- }
-
- /* Read status register to check the result */
- ret = adis16203_check_status(indio_dev);
- if (ret) {
- adis16203_reset(indio_dev);
- dev_err(&indio_dev->dev, "device not playing ball -> reset");
- msleep(ADIS16203_STARTUP_DELAY);
- ret = adis16203_check_status(indio_dev);
- if (ret) {
- dev_err(&indio_dev->dev, "giving up");
- goto err_ret;
- }
- }
-
-err_ret:
- return ret;
-}
-
-enum adis16203_chan {
- in_supply,
- in_aux,
- incli_x,
- incli_y,
- temp,
-};
-
-static u8 adis16203_addresses[5][2] = {
- [in_supply] = { ADIS16203_SUPPLY_OUT },
- [in_aux] = { ADIS16203_AUX_ADC },
- [incli_x] = { ADIS16203_XINCL_OUT, ADIS16203_INCL_NULL},
- [incli_y] = { ADIS16203_YINCL_OUT },
- [temp] = { ADIS16203_TEMP_OUT }
+static const u8 adis16203_addresses[] = {
+ [ADIS16203_SCAN_INCLI_X] = ADIS16203_INCL_NULL,
};
static int adis16203_write_raw(struct iio_dev *indio_dev,
@@ -274,9 +34,10 @@ static int adis16203_write_raw(struct iio_dev *indio_dev,
int val2,
long mask)
{
+ struct adis *st = iio_priv(indio_dev);
/* currently only one writable parameter which keeps this simple */
- u8 addr = adis16203_addresses[chan->address][1];
- return adis16203_spi_write_reg_16(indio_dev, addr, val & 0x3FFF);
+ u8 addr = adis16203_addresses[chan->scan_index];
+ return adis_write_reg_16(st, addr, val & 0x3FFF);
}
static int adis16203_read_raw(struct iio_dev *indio_dev,
@@ -284,35 +45,15 @@ static int adis16203_read_raw(struct iio_dev *indio_dev,
int *val, int *val2,
long mask)
{
+ struct adis *st = iio_priv(indio_dev);
int ret;
int bits;
u8 addr;
s16 val16;
switch (mask) {
case IIO_CHAN_INFO_RAW:
- mutex_lock(&indio_dev->mlock);
- addr = adis16203_addresses[chan->address][0];
- ret = adis16203_spi_read_reg_16(indio_dev, addr, &val16);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
-
- if (val16 & ADIS16203_ERROR_ACTIVE) {
- ret = adis16203_check_status(indio_dev);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
- }
- val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
- if (chan->scan_type.sign == 's')
- val16 = (s16)(val16 <<
- (16 - chan->scan_type.realbits)) >>
- (16 - chan->scan_type.realbits);
- *val = val16;
- mutex_unlock(&indio_dev->mlock);
- return IIO_VAL_INT;
+ return adis_single_conversion(indio_dev, chan,
+ ADIS16203_ERROR_ACTIVE, val);
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_VOLTAGE:
@@ -341,8 +82,8 @@ static int adis16203_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_CALIBBIAS:
bits = 14;
mutex_lock(&indio_dev->mlock);
- addr = adis16203_addresses[chan->address][1];
- ret = adis16203_spi_read_reg_16(indio_dev, addr, &val16);
+ addr = adis16203_addresses[chan->scan_index];
+ ret = adis_read_reg_16(st, addr, &val16);
if (ret) {
mutex_unlock(&indio_dev->mlock);
return ret;
@@ -358,89 +99,53 @@ static int adis16203_read_raw(struct iio_dev *indio_dev,
}
static const struct iio_chan_spec adis16203_channels[] = {
- {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 0,
- .extend_name = "supply",
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in_supply,
- .scan_index = ADIS16203_SCAN_SUPPLY,
- .scan_type = {
- .sign = 'u',
- .realbits = 12,
- .storagebits = 16,
- },
- }, {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 1,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in_aux,
- .scan_index = ADIS16203_SCAN_AUX_ADC,
- .scan_type = {
- .sign = 'u',
- .realbits = 12,
- .storagebits = 16,
- },
- }, {
- .type = IIO_INCLI,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
- .address = incli_x,
- .scan_index = ADIS16203_SCAN_INCLI_X,
- .scan_type = {
- .sign = 's',
- .realbits = 14,
- .storagebits = 16,
- },
- }, { /* Fixme: Not what it appears to be - see data sheet */
- .type = IIO_INCLI,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT,
- .address = incli_y,
- .scan_index = ADIS16203_SCAN_INCLI_Y,
- .scan_type = {
- .sign = 's',
- .realbits = 14,
- .storagebits = 16,
- },
- }, {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
- IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
- .address = temp,
- .scan_index = ADIS16203_SCAN_TEMP,
- .scan_type = {
- .sign = 'u',
- .realbits = 12,
- .storagebits = 16,
- },
- },
+ ADIS_SUPPLY_CHAN(ADIS16203_SUPPLY_OUT, ADIS16203_SCAN_SUPPLY, 12),
+ ADIS_AUX_ADC_CHAN(ADIS16203_AUX_ADC, ADIS16203_SCAN_AUX_ADC, 12),
+ ADIS_INCLI_CHAN(X, ADIS16203_XINCL_OUT, ADIS16203_SCAN_INCLI_X,
+ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14),
+ /* Fixme: Not what it appears to be - see data sheet */
+ ADIS_INCLI_CHAN(Y, ADIS16203_YINCL_OUT, ADIS16203_SCAN_INCLI_Y, 0, 14),
+ ADIS_TEMP_CHAN(ADIS16203_TEMP_OUT, ADIS16203_SCAN_TEMP, 12),
IIO_CHAN_SOFT_TIMESTAMP(5),
};
static const struct iio_info adis16203_info = {
.read_raw = &adis16203_read_raw,
.write_raw = &adis16203_write_raw,
+ .update_scan_mode = adis_update_scan_mode,
.driver_module = THIS_MODULE,
};
-static int __devinit adis16203_probe(struct spi_device *spi)
+static const char * const adis16203_status_error_msgs[] = {
+ [ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT] = "Self test failure",
+ [ADIS16203_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure",
+ [ADIS16203_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed",
+ [ADIS16203_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V",
+ [ADIS16203_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V",
+};
+
+static const struct adis_data adis16203_data = {
+ .read_delay = 20,
+ .msc_ctrl_reg = ADIS16203_MSC_CTRL,
+ .glob_cmd_reg = ADIS16203_GLOB_CMD,
+ .diag_stat_reg = ADIS16203_DIAG_STAT,
+
+ .self_test_mask = ADIS16203_MSC_CTRL_SELF_TEST_EN,
+ .startup_delay = ADIS16203_STARTUP_DELAY,
+
+ .status_error_msgs = adis16203_status_error_msgs,
+ .status_error_mask = BIT(ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT) |
+ BIT(ADIS16203_DIAG_STAT_SPI_FAIL_BIT) |
+ BIT(ADIS16203_DIAG_STAT_FLASH_UPT_BIT) |
+ BIT(ADIS16203_DIAG_STAT_POWER_HIGH_BIT) |
+ BIT(ADIS16203_DIAG_STAT_POWER_LOW_BIT),
+};
+
+static int adis16203_probe(struct spi_device *spi)
{
int ret;
struct iio_dev *indio_dev;
- struct adis16203_state *st;
+ struct adis *st;
/* setup the industrialio driver allocated elements */
indio_dev = iio_device_alloc(sizeof(*st));
@@ -451,8 +156,6 @@ static int __devinit adis16203_probe(struct spi_device *spi)
st = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
- st->us = spi;
- mutex_init(&st->buf_lock);
indio_dev->name = spi->dev.driver->name;
indio_dev->dev.parent = &spi->dev;
@@ -461,55 +164,40 @@ static int __devinit adis16203_probe(struct spi_device *spi)
indio_dev->info = &adis16203_info;
indio_dev->modes = INDIO_DIRECT_MODE;
- ret = adis16203_configure_ring(indio_dev);
+ ret = adis_init(st, indio_dev, spi, &adis16203_data);
if (ret)
goto error_free_dev;
- ret = iio_buffer_register(indio_dev,
- adis16203_channels,
- ARRAY_SIZE(adis16203_channels));
- if (ret) {
- printk(KERN_ERR "failed to initialize the ring\n");
- goto error_unreg_ring_funcs;
- }
-
- if (spi->irq) {
- ret = adis16203_probe_trigger(indio_dev);
- if (ret)
- goto error_uninitialize_ring;
- }
+ ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL);
+ if (ret)
+ goto error_free_dev;
/* Get the device into a sane initial state */
- ret = adis16203_initial_setup(indio_dev);
+ ret = adis_initial_startup(st);
if (ret)
- goto error_remove_trigger;
+ goto error_cleanup_buffer_trigger;
ret = iio_device_register(indio_dev);
if (ret)
- goto error_remove_trigger;
+ goto error_cleanup_buffer_trigger;
return 0;
-error_remove_trigger:
- adis16203_remove_trigger(indio_dev);
-error_uninitialize_ring:
- iio_buffer_unregister(indio_dev);
-error_unreg_ring_funcs:
- adis16203_unconfigure_ring(indio_dev);
+error_cleanup_buffer_trigger:
+ adis_cleanup_buffer_and_trigger(st, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
-static int __devexit adis16203_remove(struct spi_device *spi)
+static int adis16203_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct adis *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- adis16203_remove_trigger(indio_dev);
- iio_buffer_unregister(indio_dev);
- adis16203_unconfigure_ring(indio_dev);
+ adis_cleanup_buffer_and_trigger(st, indio_dev);
iio_device_free(indio_dev);
return 0;
@@ -521,7 +209,7 @@ static struct spi_driver adis16203_driver = {
.owner = THIS_MODULE,
},
.probe = adis16203_probe,
- .remove = __devexit_p(adis16203_remove),
+ .remove = adis16203_remove,
};
module_spi_driver(adis16203_driver);
diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c
deleted file mode 100644
index 7507e1a0459..00000000000
--- a/drivers/staging/iio/accel/adis16203_ring.c
+++ /dev/null
@@ -1,136 +0,0 @@
-#include <linux/export.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-
-#include <linux/iio/iio.h>
-#include "../ring_sw.h"
-#include <linux/iio/trigger_consumer.h>
-#include "adis16203.h"
-
-/**
- * adis16203_read_ring_data() read data registers which will be placed into ring
- * @indio_dev: the IIO device
- * @rx: somewhere to pass back the value read
- **/
-static int adis16203_read_ring_data(struct iio_dev *indio_dev, u8 *rx)
-{
- struct spi_message msg;
- struct adis16203_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[ADIS16203_OUTPUTS + 1];
- int ret;
- int i;
-
- mutex_lock(&st->buf_lock);
-
- spi_message_init(&msg);
-
- memset(xfers, 0, sizeof(xfers));
- for (i = 0; i <= ADIS16203_OUTPUTS; i++) {
- xfers[i].bits_per_word = 8;
- xfers[i].cs_change = 1;
- xfers[i].len = 2;
- xfers[i].delay_usecs = 20;
- xfers[i].tx_buf = st->tx + 2 * i;
- if (i < 1) /* SUPPLY_OUT: 0x02, AUX_ADC: 0x08 */
- st->tx[2 * i] = ADIS16203_READ_REG(ADIS16203_SUPPLY_OUT + 2 * i);
- else
- st->tx[2 * i] = ADIS16203_READ_REG(ADIS16203_SUPPLY_OUT + 2 * i + 6);
- st->tx[2 * i + 1] = 0;
- if (i >= 1)
- xfers[i].rx_buf = rx + 2 * (i - 1);
- spi_message_add_tail(&xfers[i], &msg);
- }
-
- ret = spi_sync(st->us, &msg);
- if (ret)
- dev_err(&st->us->dev, "problem when burst reading");
-
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
- * specific to be rolled into the core.
- */
-static irqreturn_t adis16203_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct adis16203_state *st = iio_priv(indio_dev);
-
- int i = 0;
- s16 *data;
-
- data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
- if (data == NULL) {
- dev_err(&st->us->dev, "memory alloc failed in ring bh");
- goto done;
- }
-
- if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
- adis16203_read_ring_data(indio_dev, st->rx) >= 0)
- for (; i < bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength); i++)
- data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
-
- /* Guaranteed to be aligned with 8 byte boundary */
- if (indio_dev->scan_timestamp)
- *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
-
- iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
-
- kfree(data);
-done:
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-void adis16203_unconfigure_ring(struct iio_dev *indio_dev)
-{
- iio_dealloc_pollfunc(indio_dev->pollfunc);
- iio_sw_rb_free(indio_dev->buffer);
-}
-
-static const struct iio_buffer_setup_ops adis16203_ring_setup_ops = {
- .preenable = &iio_sw_buffer_preenable,
- .postenable = &iio_triggered_buffer_postenable,
- .predisable = &iio_triggered_buffer_predisable,
-};
-
-int adis16203_configure_ring(struct iio_dev *indio_dev)
-{
- int ret = 0;
- struct iio_buffer *ring;
-
- ring = iio_sw_rb_allocate(indio_dev);
- if (!ring) {
- ret = -ENOMEM;
- return ret;
- }
- indio_dev->buffer = ring;
- ring->scan_timestamp = true;
- indio_dev->setup_ops = &adis16203_ring_setup_ops;
-
- indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
- &adis16203_trigger_handler,
- IRQF_ONESHOT,
- indio_dev,
- "adis16203_consumer%d",
- indio_dev->id);
- if (indio_dev->pollfunc == NULL) {
- ret = -ENOMEM;
- goto error_iio_sw_rb_free;
- }
-
- indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
- return 0;
-
-error_iio_sw_rb_free:
- iio_sw_rb_free(indio_dev->buffer);
- return ret;
-}
diff --git a/drivers/staging/iio/accel/adis16203_trigger.c b/drivers/staging/iio/accel/adis16203_trigger.c
deleted file mode 100644
index b8a04073d6d..00000000000
--- a/drivers/staging/iio/accel/adis16203_trigger.c
+++ /dev/null
@@ -1,73 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/export.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/trigger.h>
-#include "adis16203.h"
-
-/**
- * adis16203_data_rdy_trigger_set_state() set datardy interrupt state
- **/
-static int adis16203_data_rdy_trigger_set_state(struct iio_trigger *trig,
- bool state)
-{
- struct iio_dev *indio_dev = trig->private_data;
-
- dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
- return adis16203_set_irq(indio_dev, state);
-}
-
-static const struct iio_trigger_ops adis16203_trigger_ops = {
- .owner = THIS_MODULE,
- .set_trigger_state = &adis16203_data_rdy_trigger_set_state,
-};
-
-int adis16203_probe_trigger(struct iio_dev *indio_dev)
-{
- int ret;
- struct adis16203_state *st = iio_priv(indio_dev);
-
- st->trig = iio_trigger_alloc("adis16203-dev%d", indio_dev->id);
- if (st->trig == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
-
- ret = request_irq(st->us->irq,
- &iio_trigger_generic_data_rdy_poll,
- IRQF_TRIGGER_RISING,
- "adis16203",
- st->trig);
- if (ret)
- goto error_free_trig;
-
- st->trig->dev.parent = &st->us->dev;
- st->trig->ops = &adis16203_trigger_ops;
- st->trig->private_data = indio_dev;
- ret = iio_trigger_register(st->trig);
-
- /* select default trigger */
- indio_dev->trig = st->trig;
- if (ret)
- goto error_free_irq;
-
- return 0;
-
-error_free_irq:
- free_irq(st->us->irq, st->trig);
-error_free_trig:
- iio_trigger_free(st->trig);
-error_ret:
- return ret;
-}
-
-void adis16203_remove_trigger(struct iio_dev *indio_dev)
-{
- struct adis16203_state *st = iio_priv(indio_dev);
-
- iio_trigger_unregister(st->trig);
- free_irq(st->us->irq, st->trig);
- iio_trigger_free(st->trig);
-}
diff --git a/drivers/staging/iio/accel/adis16204.h b/drivers/staging/iio/accel/adis16204.h
index 7cf4e91f83a..9ff950c1e8d 100644
--- a/drivers/staging/iio/accel/adis16204.h
+++ b/drivers/staging/iio/accel/adis16204.h
@@ -3,9 +3,6 @@
#define ADIS16204_STARTUP_DELAY 220 /* ms */
-#define ADIS16204_READ_REG(a) a
-#define ADIS16204_WRITE_REG(a) ((a) | 0x80)
-
#define ADIS16204_FLASH_CNT 0x00 /* Flash memory write count */
#define ADIS16204_SUPPLY_OUT 0x02 /* Output, power supply */
#define ADIS16204_XACCL_OUT 0x04 /* Output, x-axis accelerometer */
@@ -35,8 +32,6 @@
#define ADIS16204_DIAG_STAT 0x3C /* Diagnostics, system status register */
#define ADIS16204_GLOB_CMD 0x3E /* Operation, system command register */
-#define ADIS16204_OUTPUTS 5
-
/* MSC_CTRL */
#define ADIS16204_MSC_CTRL_PWRUP_SELF_TEST (1 << 10) /* Self-test at power-on: 1 = disabled, 0 = enabled */
#define ADIS16204_MSC_CTRL_SELF_TEST_EN (1 << 8) /* Self-test enable */
@@ -47,87 +42,27 @@
/* DIAG_STAT */
#define ADIS16204_DIAG_STAT_ALARM2 (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
#define ADIS16204_DIAG_STAT_ALARM1 (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
-#define ADIS16204_DIAG_STAT_SELFTEST_FAIL (1<<5) /* Self-test diagnostic error flag: 1 = error condition,
+#define ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT 5 /* Self-test diagnostic error flag: 1 = error condition,
0 = normal operation */
-#define ADIS16204_DIAG_STAT_SPI_FAIL (1<<3) /* SPI communications failure */
-#define ADIS16204_DIAG_STAT_FLASH_UPT (1<<2) /* Flash update failure */
-#define ADIS16204_DIAG_STAT_POWER_HIGH (1<<1) /* Power supply above 3.625 V */
-#define ADIS16204_DIAG_STAT_POWER_LOW (1<<0) /* Power supply below 2.975 V */
+#define ADIS16204_DIAG_STAT_SPI_FAIL_BIT 3 /* SPI communications failure */
+#define ADIS16204_DIAG_STAT_FLASH_UPT_BIT 2 /* Flash update failure */
+#define ADIS16204_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply above 3.625 V */
+#define ADIS16204_DIAG_STAT_POWER_LOW_BIT 0 /* Power supply below 2.975 V */
/* GLOB_CMD */
#define ADIS16204_GLOB_CMD_SW_RESET (1<<7)
#define ADIS16204_GLOB_CMD_CLEAR_STAT (1<<4)
#define ADIS16204_GLOB_CMD_FACTORY_CAL (1<<1)
-#define ADIS16204_MAX_TX 24
-#define ADIS16204_MAX_RX 24
-
#define ADIS16204_ERROR_ACTIVE (1<<14)
-/**
- * struct adis16204_state - device instance specific data
- * @us: actual spi_device
- * @trig: data ready trigger registered with iio
- * @tx: transmit buffer
- * @rx: receive buffer
- * @buf_lock: mutex to protect tx and rx
- **/
-struct adis16204_state {
- struct spi_device *us;
- struct iio_trigger *trig;
- struct mutex buf_lock;
- u8 tx[ADIS16204_MAX_TX] ____cacheline_aligned;
- u8 rx[ADIS16204_MAX_RX];
-};
-
-int adis16204_set_irq(struct iio_dev *indio_dev, bool enable);
-
enum adis16204_scan {
- ADIS16204_SCAN_SUPPLY,
ADIS16204_SCAN_ACC_X,
ADIS16204_SCAN_ACC_Y,
+ ADIS16204_SCAN_ACC_XY,
+ ADIS16204_SCAN_SUPPLY,
ADIS16204_SCAN_AUX_ADC,
ADIS16204_SCAN_TEMP,
};
-#ifdef CONFIG_IIO_BUFFER
-void adis16204_remove_trigger(struct iio_dev *indio_dev);
-int adis16204_probe_trigger(struct iio_dev *indio_dev);
-
-ssize_t adis16204_read_data_from_ring(struct device *dev,
- struct device_attribute *attr,
- char *buf);
-
-int adis16204_configure_ring(struct iio_dev *indio_dev);
-void adis16204_unconfigure_ring(struct iio_dev *indio_dev);
-
-#else /* CONFIG_IIO_BUFFER */
-
-static inline void adis16204_remove_trigger(struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis16204_probe_trigger(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline ssize_t
-adis16204_read_data_from_ring(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return 0;
-}
-
-static int adis16204_configure_ring(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void adis16204_unconfigure_ring(struct iio_dev *indio_dev)
-{
-}
-
-#endif /* CONFIG_IIO_BUFFER */
#endif /* SPI_ADIS16204_H_ */
diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c
index c6234c2f46a..f3592668e06 100644
--- a/drivers/staging/iio/accel/adis16204_core.c
+++ b/drivers/staging/iio/accel/adis16204_core.c
@@ -21,261 +21,16 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
#include "adis16204.h"
-#define DRIVER_NAME "adis16204"
-
-/**
- * adis16204_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the register to be written
- * @val: the value to write
- **/
-static int adis16204_spi_write_reg_8(struct iio_dev *indio_dev,
- u8 reg_address,
- u8 val)
-{
- int ret;
- struct adis16204_state *st = iio_priv(indio_dev);
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16204_WRITE_REG(reg_address);
- st->tx[1] = val;
-
- ret = spi_write(st->us, st->tx, 2);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16204_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @indio_dev: iio device associated with child of actual device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: value to be written
- **/
-static int adis16204_spi_write_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 value)
-{
- int ret;
- struct spi_message msg;
- struct adis16204_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- }, {
- .tx_buf = st->tx + 2,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16204_WRITE_REG(lower_reg_address);
- st->tx[1] = value & 0xFF;
- st->tx[2] = ADIS16204_WRITE_REG(lower_reg_address + 1);
- st->tx[3] = (value >> 8) & 0xFF;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16204_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @indio_dev: iio device associated with child of actual device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: somewhere to pass back the value read
- **/
-static int adis16204_spi_read_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 *val)
-{
- struct spi_message msg;
- struct adis16204_state *st = iio_priv(indio_dev);
- int ret;
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- .delay_usecs = 20,
- }, {
- .rx_buf = st->rx,
- .bits_per_word = 8,
- .len = 2,
- .delay_usecs = 20,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16204_READ_REG(lower_reg_address);
- st->tx[1] = 0;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- if (ret) {
- dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
- lower_reg_address);
- goto error_ret;
- }
- *val = (st->rx[0] << 8) | st->rx[1];
-
-error_ret:
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
-static int adis16204_check_status(struct iio_dev *indio_dev)
-{
- u16 status;
- int ret;
-
- ret = adis16204_spi_read_reg_16(indio_dev,
- ADIS16204_DIAG_STAT, &status);
- if (ret < 0) {
- dev_err(&indio_dev->dev, "Reading status failed\n");
- goto error_ret;
- }
- ret = status & 0x1F;
-
- if (status & ADIS16204_DIAG_STAT_SELFTEST_FAIL)
- dev_err(&indio_dev->dev, "Self test failure\n");
- if (status & ADIS16204_DIAG_STAT_SPI_FAIL)
- dev_err(&indio_dev->dev, "SPI failure\n");
- if (status & ADIS16204_DIAG_STAT_FLASH_UPT)
- dev_err(&indio_dev->dev, "Flash update failed\n");
- if (status & ADIS16204_DIAG_STAT_POWER_HIGH)
- dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
- if (status & ADIS16204_DIAG_STAT_POWER_LOW)
- dev_err(&indio_dev->dev, "Power supply below 2.975V\n");
-
-error_ret:
- return ret;
-}
-
-static int adis16204_reset(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16204_spi_write_reg_8(indio_dev,
- ADIS16204_GLOB_CMD,
- ADIS16204_GLOB_CMD_SW_RESET);
- if (ret)
- dev_err(&indio_dev->dev, "problem resetting device");
-
- return ret;
-}
-
-int adis16204_set_irq(struct iio_dev *indio_dev, bool enable)
-{
- int ret = 0;
- u16 msc;
-
- ret = adis16204_spi_read_reg_16(indio_dev, ADIS16204_MSC_CTRL, &msc);
- if (ret)
- goto error_ret;
-
- msc |= ADIS16204_MSC_CTRL_ACTIVE_HIGH;
- msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_DIO2;
- if (enable)
- msc |= ADIS16204_MSC_CTRL_DATA_RDY_EN;
- else
- msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_EN;
-
- ret = adis16204_spi_write_reg_16(indio_dev, ADIS16204_MSC_CTRL, msc);
-
-error_ret:
- return ret;
-}
-
-static int adis16204_self_test(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16204_spi_write_reg_16(indio_dev,
- ADIS16204_MSC_CTRL,
- ADIS16204_MSC_CTRL_SELF_TEST_EN);
- if (ret) {
- dev_err(&indio_dev->dev, "problem starting self test");
- goto err_ret;
- }
-
- adis16204_check_status(indio_dev);
-
-err_ret:
- return ret;
-}
-
-static int adis16204_initial_setup(struct iio_dev *indio_dev)
-{
- int ret;
-
- /* Disable IRQ */
- ret = adis16204_set_irq(indio_dev, false);
- if (ret) {
- dev_err(&indio_dev->dev, "disable irq failed");
- goto err_ret;
- }
-
- /* Do self test */
- ret = adis16204_self_test(indio_dev);
- if (ret) {
- dev_err(&indio_dev->dev, "self test failure");
- goto err_ret;
- }
-
- /* Read status register to check the result */
- ret = adis16204_check_status(indio_dev);
- if (ret) {
- adis16204_reset(indio_dev);
- dev_err(&indio_dev->dev, "device not playing ball -> reset");
- msleep(ADIS16204_STARTUP_DELAY);
- ret = adis16204_check_status(indio_dev);
- if (ret) {
- dev_err(&indio_dev->dev, "giving up");
- goto err_ret;
- }
- }
-
-err_ret:
- return ret;
-}
-
/* Unique to this driver currently */
-enum adis16204_channel {
- in_supply,
- in_aux,
- temp,
- accel_x,
- accel_y,
- accel_xy,
-};
-
-static u8 adis16204_addresses[6][3] = {
- [in_supply] = { ADIS16204_SUPPLY_OUT },
- [in_aux] = { ADIS16204_AUX_ADC },
- [temp] = { ADIS16204_TEMP_OUT },
- [accel_x] = { ADIS16204_XACCL_OUT, ADIS16204_XACCL_NULL,
- ADIS16204_X_PEAK_OUT },
- [accel_y] = { ADIS16204_XACCL_OUT, ADIS16204_YACCL_NULL,
- ADIS16204_Y_PEAK_OUT },
- [accel_xy] = { ADIS16204_XY_RSS_OUT, 0,
- ADIS16204_XY_PEAK_OUT },
+static const u8 adis16204_addresses[][2] = {
+ [ADIS16204_SCAN_ACC_X] = { ADIS16204_XACCL_NULL, ADIS16204_X_PEAK_OUT },
+ [ADIS16204_SCAN_ACC_Y] = { ADIS16204_YACCL_NULL, ADIS16204_Y_PEAK_OUT },
+ [ADIS16204_SCAN_ACC_XY] = { 0, ADIS16204_XY_PEAK_OUT },
};
static int adis16204_read_raw(struct iio_dev *indio_dev,
@@ -283,6 +38,7 @@ static int adis16204_read_raw(struct iio_dev *indio_dev,
int *val, int *val2,
long mask)
{
+ struct adis *st = iio_priv(indio_dev);
int ret;
int bits;
u8 addr;
@@ -291,29 +47,8 @@ static int adis16204_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
- mutex_lock(&indio_dev->mlock);
- addr = adis16204_addresses[chan->address][0];
- ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
-
- if (val16 & ADIS16204_ERROR_ACTIVE) {
- ret = adis16204_check_status(indio_dev);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
- }
- val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
- if (chan->scan_type.sign == 's')
- val16 = (s16)(val16 <<
- (16 - chan->scan_type.realbits)) >>
- (16 - chan->scan_type.realbits);
- *val = val16;
- mutex_unlock(&indio_dev->mlock);
- return IIO_VAL_INT;
+ return adis_single_conversion(indio_dev, chan,
+ ADIS16204_ERROR_ACTIVE, val);
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_VOLTAGE:
@@ -353,14 +88,14 @@ static int adis16204_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_PEAK:
if (mask == IIO_CHAN_INFO_CALIBBIAS) {
bits = 12;
- addrind = 1;
+ addrind = 0;
} else { /* PEAK_SEPARATE */
bits = 14;
- addrind = 2;
+ addrind = 1;
}
mutex_lock(&indio_dev->mlock);
- addr = adis16204_addresses[chan->address][addrind];
- ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16);
+ addr = adis16204_addresses[chan->scan_index][addrind];
+ ret = adis_read_reg_16(st, addr, &val16);
if (ret) {
mutex_unlock(&indio_dev->mlock);
return ret;
@@ -380,6 +115,7 @@ static int adis16204_write_raw(struct iio_dev *indio_dev,
int val2,
long mask)
{
+ struct adis *st = iio_priv(indio_dev);
int bits;
s16 val16;
u8 addr;
@@ -391,114 +127,65 @@ static int adis16204_write_raw(struct iio_dev *indio_dev,
break;
default:
return -EINVAL;
- };
+ }
val16 = val & ((1 << bits) - 1);
- addr = adis16204_addresses[chan->address][1];
- return adis16204_spi_write_reg_16(indio_dev, addr, val16);
+ addr = adis16204_addresses[chan->scan_index][1];
+ return adis_write_reg_16(st, addr, val16);
}
return -EINVAL;
}
static const struct iio_chan_spec adis16204_channels[] = {
- {
- .type = IIO_VOLTAGE,
- .indexed = 1, /* Note was not previously indexed */
- .channel = 0,
- .extend_name = "supply",
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in_supply,
- .scan_index = ADIS16204_SCAN_SUPPLY,
- .scan_type = {
- .sign = 'u',
- .realbits = 12,
- .storagebits = 16,
- },
- }, {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 1,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in_aux,
- .scan_index = ADIS16204_SCAN_AUX_ADC,
- .scan_type = {
- .sign = 'u',
- .realbits = 12,
- .storagebits = 16,
- },
- }, {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
- IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
- .address = temp,
- .scan_index = ADIS16204_SCAN_TEMP,
- .scan_type = {
- .sign = 'u',
- .realbits = 12,
- .storagebits = 16,
- },
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+ ADIS_SUPPLY_CHAN(ADIS16204_SUPPLY_OUT, ADIS16204_SCAN_SUPPLY, 12),
+ ADIS_AUX_ADC_CHAN(ADIS16204_AUX_ADC, ADIS16204_SCAN_AUX_ADC, 12),
+ ADIS_TEMP_CHAN(ADIS16204_TEMP_OUT, ADIS16204_SCAN_TEMP, 12),
+ ADIS_ACCEL_CHAN(X, ADIS16204_XACCL_OUT, ADIS16204_SCAN_ACC_X,
IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_PEAK_SEPARATE_BIT,
- .address = accel_x,
- .scan_index = ADIS16204_SCAN_ACC_X,
- .scan_type = {
- .sign = 's',
- .realbits = 14,
- .storagebits = 16,
- },
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+ IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 14),
+ ADIS_ACCEL_CHAN(Y, ADIS16204_YACCL_OUT, ADIS16204_SCAN_ACC_Y,
IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_PEAK_SEPARATE_BIT,
- .address = accel_y,
- .scan_index = ADIS16204_SCAN_ACC_Y,
- .scan_type = {
- .sign = 's',
- .realbits = 14,
- .storagebits = 16,
- },
- },
+ IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 14),
+ ADIS_ACCEL_CHAN(ROOT_SUM_SQUARED_X_Y, ADIS16204_XY_RSS_OUT,
+ ADIS16204_SCAN_ACC_XY, IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 14),
IIO_CHAN_SOFT_TIMESTAMP(5),
- {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_ROOT_SUM_SQUARED_X_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
- IIO_CHAN_INFO_PEAK_SEPARATE_BIT,
- .address = accel_xy,
- .scan_type = {
- .sign = 'u',
- .realbits = 14,
- .storagebits = 16,
- },
- }
};
static const struct iio_info adis16204_info = {
.read_raw = &adis16204_read_raw,
.write_raw = &adis16204_write_raw,
+ .update_scan_mode = adis_update_scan_mode,
.driver_module = THIS_MODULE,
};
-static int __devinit adis16204_probe(struct spi_device *spi)
+static const char * const adis16204_status_error_msgs[] = {
+ [ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT] = "Self test failure",
+ [ADIS16204_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure",
+ [ADIS16204_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed",
+ [ADIS16204_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V",
+ [ADIS16204_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.975V",
+};
+
+static const struct adis_data adis16204_data = {
+ .read_delay = 20,
+ .msc_ctrl_reg = ADIS16204_MSC_CTRL,
+ .glob_cmd_reg = ADIS16204_GLOB_CMD,
+ .diag_stat_reg = ADIS16204_DIAG_STAT,
+
+ .self_test_mask = ADIS16204_MSC_CTRL_SELF_TEST_EN,
+ .startup_delay = ADIS16204_STARTUP_DELAY,
+
+ .status_error_msgs = adis16204_status_error_msgs,
+ .status_error_mask = BIT(ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT) |
+ BIT(ADIS16204_DIAG_STAT_SPI_FAIL_BIT) |
+ BIT(ADIS16204_DIAG_STAT_FLASH_UPT_BIT) |
+ BIT(ADIS16204_DIAG_STAT_POWER_HIGH_BIT) |
+ BIT(ADIS16204_DIAG_STAT_POWER_LOW_BIT),
+};
+
+static int adis16204_probe(struct spi_device *spi)
{
int ret;
- struct adis16204_state *st;
+ struct adis *st;
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
@@ -510,8 +197,6 @@ static int __devinit adis16204_probe(struct spi_device *spi)
st = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
- st->us = spi;
- mutex_init(&st->buf_lock);
indio_dev->name = spi->dev.driver->name;
indio_dev->dev.parent = &spi->dev;
@@ -520,54 +205,39 @@ static int __devinit adis16204_probe(struct spi_device *spi)
indio_dev->num_channels = ARRAY_SIZE(adis16204_channels);
indio_dev->modes = INDIO_DIRECT_MODE;
- ret = adis16204_configure_ring(indio_dev);
+ ret = adis_init(st, indio_dev, spi, &adis16204_data);
if (ret)
goto error_free_dev;
- ret = iio_buffer_register(indio_dev,
- adis16204_channels,
- 6);
- if (ret) {
- printk(KERN_ERR "failed to initialize the ring\n");
- goto error_unreg_ring_funcs;
- }
-
- if (spi->irq) {
- ret = adis16204_probe_trigger(indio_dev);
- if (ret)
- goto error_uninitialize_ring;
- }
+ ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL);
+ if (ret)
+ goto error_free_dev;
/* Get the device into a sane initial state */
- ret = adis16204_initial_setup(indio_dev);
+ ret = adis_initial_startup(st);
if (ret)
- goto error_remove_trigger;
+ goto error_cleanup_buffer_trigger;
ret = iio_device_register(indio_dev);
if (ret)
- goto error_remove_trigger;
+ goto error_cleanup_buffer_trigger;
return 0;
-error_remove_trigger:
- adis16204_remove_trigger(indio_dev);
-error_uninitialize_ring:
- iio_buffer_unregister(indio_dev);
-error_unreg_ring_funcs:
- adis16204_unconfigure_ring(indio_dev);
+error_cleanup_buffer_trigger:
+ adis_cleanup_buffer_and_trigger(st, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
-static int __devexit adis16204_remove(struct spi_device *spi)
+static int adis16204_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct adis *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- adis16204_remove_trigger(indio_dev);
- iio_buffer_unregister(indio_dev);
- adis16204_unconfigure_ring(indio_dev);
+ adis_cleanup_buffer_and_trigger(st, indio_dev);
iio_device_free(indio_dev);
return 0;
@@ -579,7 +249,7 @@ static struct spi_driver adis16204_driver = {
.owner = THIS_MODULE,
},
.probe = adis16204_probe,
- .remove = __devexit_p(adis16204_remove),
+ .remove = adis16204_remove,
};
module_spi_driver(adis16204_driver);
diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c
deleted file mode 100644
index 4c976bec986..00000000000
--- a/drivers/staging/iio/accel/adis16204_ring.c
+++ /dev/null
@@ -1,134 +0,0 @@
-#include <linux/export.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-
-#include <linux/iio/iio.h>
-#include "../ring_sw.h"
-#include <linux/iio/trigger_consumer.h>
-#include "adis16204.h"
-
-/**
- * adis16204_read_ring_data() read data registers which will be placed into ring
- * @indio_dev: the IIO device
- * @rx: somewhere to pass back the value read
- **/
-static int adis16204_read_ring_data(struct iio_dev *indio_dev, u8 *rx)
-{
- struct spi_message msg;
- struct adis16204_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[ADIS16204_OUTPUTS + 1];
- int ret;
- int i;
-
- mutex_lock(&st->buf_lock);
-
- spi_message_init(&msg);
-
- memset(xfers, 0, sizeof(xfers));
- for (i = 0; i <= ADIS16204_OUTPUTS; i++) {
- xfers[i].bits_per_word = 8;
- xfers[i].cs_change = 1;
- xfers[i].len = 2;
- xfers[i].delay_usecs = 20;
- xfers[i].tx_buf = st->tx + 2 * i;
- st->tx[2 * i]
- = ADIS16204_READ_REG(ADIS16204_SUPPLY_OUT + 2 * i);
- st->tx[2 * i + 1] = 0;
- if (i >= 1)
- xfers[i].rx_buf = rx + 2 * (i - 1);
- spi_message_add_tail(&xfers[i], &msg);
- }
-
- ret = spi_sync(st->us, &msg);
- if (ret)
- dev_err(&st->us->dev, "problem when burst reading");
-
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
- * specific to be rolled into the core.
- */
-static irqreturn_t adis16204_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct adis16204_state *st = iio_priv(indio_dev);
- int i = 0;
- s16 *data;
-
- data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
- if (data == NULL) {
- dev_err(&st->us->dev, "memory alloc failed in ring bh");
- goto done;
- }
-
- if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
- adis16204_read_ring_data(indio_dev, st->rx) >= 0)
- for (; i < bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength); i++)
- data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
-
- /* Guaranteed to be aligned with 8 byte boundary */
- if (indio_dev->scan_timestamp)
- *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
-
- iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
-
- kfree(data);
-done:
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-void adis16204_unconfigure_ring(struct iio_dev *indio_dev)
-{
- iio_dealloc_pollfunc(indio_dev->pollfunc);
- iio_sw_rb_free(indio_dev->buffer);
-}
-
-static const struct iio_buffer_setup_ops adis16204_ring_setup_ops = {
- .preenable = &iio_sw_buffer_preenable,
- .postenable = &iio_triggered_buffer_postenable,
- .predisable = &iio_triggered_buffer_predisable,
-};
-
-int adis16204_configure_ring(struct iio_dev *indio_dev)
-{
- int ret = 0;
- struct iio_buffer *ring;
-
- ring = iio_sw_rb_allocate(indio_dev);
- if (!ring) {
- ret = -ENOMEM;
- return ret;
- }
- indio_dev->buffer = ring;
- ring->scan_timestamp = true;
- indio_dev->setup_ops = &adis16204_ring_setup_ops;
-
- indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
- &adis16204_trigger_handler,
- IRQF_ONESHOT,
- indio_dev,
- "%s_consumer%d",
- indio_dev->name,
- indio_dev->id);
- if (indio_dev->pollfunc == NULL) {
- ret = -ENOMEM;
- goto error_iio_sw_rb_free;
- }
-
- indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
- return 0;
-
-error_iio_sw_rb_free:
- iio_sw_rb_free(indio_dev->buffer);
- return ret;
-}
diff --git a/drivers/staging/iio/accel/adis16204_trigger.c b/drivers/staging/iio/accel/adis16204_trigger.c
deleted file mode 100644
index 408a1682368..00000000000
--- a/drivers/staging/iio/accel/adis16204_trigger.c
+++ /dev/null
@@ -1,73 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/export.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/trigger.h>
-#include "adis16204.h"
-
-/**
- * adis16204_data_rdy_trigger_set_state() set datardy interrupt state
- **/
-static int adis16204_data_rdy_trigger_set_state(struct iio_trigger *trig,
- bool state)
-{
- struct iio_dev *indio_dev = trig->private_data;
-
- dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
- return adis16204_set_irq(indio_dev, state);
-}
-
-static const struct iio_trigger_ops adis16204_trigger_ops = {
- .owner = THIS_MODULE,
- .set_trigger_state = &adis16204_data_rdy_trigger_set_state,
-};
-
-int adis16204_probe_trigger(struct iio_dev *indio_dev)
-{
- int ret;
- struct adis16204_state *st = iio_priv(indio_dev);
-
- st->trig = iio_trigger_alloc("adis16204-dev%d", indio_dev->id);
- if (st->trig == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
-
- ret = request_irq(st->us->irq,
- &iio_trigger_generic_data_rdy_poll,
- IRQF_TRIGGER_RISING,
- "adis16204",
- st->trig);
- if (ret)
- goto error_free_trig;
-
- st->trig->dev.parent = &st->us->dev;
- st->trig->ops = &adis16204_trigger_ops;
- st->trig->private_data = indio_dev;
- ret = iio_trigger_register(st->trig);
-
- /* select default trigger */
- indio_dev->trig = st->trig;
- if (ret)
- goto error_free_irq;
-
- return 0;
-
-error_free_irq:
- free_irq(st->us->irq, st->trig);
-error_free_trig:
- iio_trigger_free(st->trig);
-error_ret:
- return ret;
-}
-
-void adis16204_remove_trigger(struct iio_dev *indio_dev)
-{
- struct adis16204_state *state = iio_priv(indio_dev);
-
- iio_trigger_unregister(state->trig);
- free_irq(state->us->irq, state->trig);
- iio_trigger_free(state->trig);
-}
diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h
index 3c88b86e7b8..ad3945a0629 100644
--- a/drivers/staging/iio/accel/adis16209.h
+++ b/drivers/staging/iio/accel/adis16209.h
@@ -3,9 +3,6 @@
#define ADIS16209_STARTUP_DELAY 220 /* ms */
-#define ADIS16209_READ_REG(a) a
-#define ADIS16209_WRITE_REG(a) ((a) | 0x80)
-
/* Flash memory write count */
#define ADIS16209_FLASH_CNT 0x00
/* Output, power supply */
@@ -61,8 +58,6 @@
/* Operation, system command register */
#define ADIS16209_GLOB_CMD 0x3E
-#define ADIS16209_OUTPUTS 8
-
/* MSC_CTRL */
/* Self-test at power-on: 1 = disabled, 0 = enabled */
#define ADIS16209_MSC_CTRL_PWRUP_SELF_TEST (1 << 10)
@@ -81,44 +76,23 @@
/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
#define ADIS16209_DIAG_STAT_ALARM1 (1<<8)
/* Self-test diagnostic error flag: 1 = error condition, 0 = normal operation */
-#define ADIS16209_DIAG_STAT_SELFTEST_FAIL (1<<5)
+#define ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT 5
/* SPI communications failure */
-#define ADIS16209_DIAG_STAT_SPI_FAIL (1<<3)
+#define ADIS16209_DIAG_STAT_SPI_FAIL_BIT 3
/* Flash update failure */
-#define ADIS16209_DIAG_STAT_FLASH_UPT (1<<2)
+#define ADIS16209_DIAG_STAT_FLASH_UPT_BIT 2
/* Power supply above 3.625 V */
-#define ADIS16209_DIAG_STAT_POWER_HIGH (1<<1)
+#define ADIS16209_DIAG_STAT_POWER_HIGH_BIT 1
/* Power supply below 3.15 V */
-#define ADIS16209_DIAG_STAT_POWER_LOW (1<<0)
+#define ADIS16209_DIAG_STAT_POWER_LOW_BIT 0
/* GLOB_CMD */
#define ADIS16209_GLOB_CMD_SW_RESET (1<<7)
#define ADIS16209_GLOB_CMD_CLEAR_STAT (1<<4)
#define ADIS16209_GLOB_CMD_FACTORY_CAL (1<<1)
-#define ADIS16209_MAX_TX 24
-#define ADIS16209_MAX_RX 24
-
#define ADIS16209_ERROR_ACTIVE (1<<14)
-/**
- * struct adis16209_state - device instance specific data
- * @us: actual spi_device
- * @trig: data ready trigger registered with iio
- * @tx: transmit buffer
- * @rx: receive buffer
- * @buf_lock: mutex to protect tx and rx
- **/
-struct adis16209_state {
- struct spi_device *us;
- struct iio_trigger *trig;
- struct mutex buf_lock;
- u8 tx[ADIS16209_MAX_TX] ____cacheline_aligned;
- u8 rx[ADIS16209_MAX_RX];
-};
-
-int adis16209_set_irq(struct iio_dev *indio_dev, bool enable);
-
#define ADIS16209_SCAN_SUPPLY 0
#define ADIS16209_SCAN_ACC_X 1
#define ADIS16209_SCAN_ACC_Y 2
@@ -128,45 +102,4 @@ int adis16209_set_irq(struct iio_dev *indio_dev, bool enable);
#define ADIS16209_SCAN_INCLI_Y 6
#define ADIS16209_SCAN_ROT 7
-#ifdef CONFIG_IIO_BUFFER
-
-void adis16209_remove_trigger(struct iio_dev *indio_dev);
-int adis16209_probe_trigger(struct iio_dev *indio_dev);
-
-ssize_t adis16209_read_data_from_ring(struct device *dev,
- struct device_attribute *attr,
- char *buf);
-
-int adis16209_configure_ring(struct iio_dev *indio_dev);
-void adis16209_unconfigure_ring(struct iio_dev *indio_dev);
-
-#else /* CONFIG_IIO_BUFFER */
-
-static inline void adis16209_remove_trigger(struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis16209_probe_trigger(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline ssize_t
-adis16209_read_data_from_ring(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return 0;
-}
-
-static int adis16209_configure_ring(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
-{
-}
-
-#endif /* CONFIG_IIO_BUFFER */
#endif /* SPI_ADIS16209_H_ */
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index 7ee974b45d7..69c50ee44ce 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -19,262 +19,19 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
#include "adis16209.h"
-#define DRIVER_NAME "adis16209"
-
-/**
- * adis16209_spi_write_reg_8() - write single byte to a register
- * @indio_dev: iio device associated with actual device
- * @reg_address: the address of the register to be written
- * @val: the value to write
- **/
-static int adis16209_spi_write_reg_8(struct iio_dev *indio_dev,
- u8 reg_address,
- u8 val)
-{
- int ret;
- struct adis16209_state *st = iio_priv(indio_dev);
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16209_WRITE_REG(reg_address);
- st->tx[1] = val;
-
- ret = spi_write(st->us, st->tx, 2);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16209_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @indio_dev: iio device associated actual device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: value to be written
- **/
-static int adis16209_spi_write_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 value)
-{
- int ret;
- struct spi_message msg;
- struct adis16209_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- .delay_usecs = 30,
- }, {
- .tx_buf = st->tx + 2,
- .bits_per_word = 8,
- .len = 2,
- .delay_usecs = 30,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16209_WRITE_REG(lower_reg_address);
- st->tx[1] = value & 0xFF;
- st->tx[2] = ADIS16209_WRITE_REG(lower_reg_address + 1);
- st->tx[3] = (value >> 8) & 0xFF;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16209_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @indio_dev: iio device associated with device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: somewhere to pass back the value read
- **/
-static int adis16209_spi_read_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 *val)
-{
- struct spi_message msg;
- struct adis16209_state *st = iio_priv(indio_dev);
- int ret;
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- .delay_usecs = 30,
- }, {
- .rx_buf = st->rx,
- .bits_per_word = 8,
- .len = 2,
- .delay_usecs = 30,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16209_READ_REG(lower_reg_address);
- st->tx[1] = 0;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- if (ret) {
- dev_err(&st->us->dev,
- "problem when reading 16 bit register 0x%02X",
- lower_reg_address);
- goto error_ret;
- }
- *val = (st->rx[0] << 8) | st->rx[1];
-
-error_ret:
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
-static int adis16209_reset(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16209_spi_write_reg_8(indio_dev,
- ADIS16209_GLOB_CMD,
- ADIS16209_GLOB_CMD_SW_RESET);
- if (ret)
- dev_err(&indio_dev->dev, "problem resetting device");
-
- return ret;
-}
-
-int adis16209_set_irq(struct iio_dev *indio_dev, bool enable)
-{
- int ret = 0;
- u16 msc;
-
- ret = adis16209_spi_read_reg_16(indio_dev, ADIS16209_MSC_CTRL, &msc);
- if (ret)
- goto error_ret;
-
- msc |= ADIS16209_MSC_CTRL_ACTIVE_HIGH;
- msc &= ~ADIS16209_MSC_CTRL_DATA_RDY_DIO2;
- if (enable)
- msc |= ADIS16209_MSC_CTRL_DATA_RDY_EN;
- else
- msc &= ~ADIS16209_MSC_CTRL_DATA_RDY_EN;
-
- ret = adis16209_spi_write_reg_16(indio_dev, ADIS16209_MSC_CTRL, msc);
-
-error_ret:
- return ret;
-}
-
-static int adis16209_check_status(struct iio_dev *indio_dev)
-{
- u16 status;
- int ret;
-
- ret = adis16209_spi_read_reg_16(indio_dev,
- ADIS16209_DIAG_STAT, &status);
- if (ret < 0) {
- dev_err(&indio_dev->dev, "Reading status failed\n");
- goto error_ret;
- }
- ret = status & 0x1F;
-
- if (status & ADIS16209_DIAG_STAT_SELFTEST_FAIL)
- dev_err(&indio_dev->dev, "Self test failure\n");
- if (status & ADIS16209_DIAG_STAT_SPI_FAIL)
- dev_err(&indio_dev->dev, "SPI failure\n");
- if (status & ADIS16209_DIAG_STAT_FLASH_UPT)
- dev_err(&indio_dev->dev, "Flash update failed\n");
- if (status & ADIS16209_DIAG_STAT_POWER_HIGH)
- dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
- if (status & ADIS16209_DIAG_STAT_POWER_LOW)
- dev_err(&indio_dev->dev, "Power supply below 3.15V\n");
-
-error_ret:
- return ret;
-}
-
-static int adis16209_self_test(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16209_spi_write_reg_16(indio_dev,
- ADIS16209_MSC_CTRL,
- ADIS16209_MSC_CTRL_SELF_TEST_EN);
- if (ret) {
- dev_err(&indio_dev->dev, "problem starting self test");
- goto err_ret;
- }
-
- adis16209_check_status(indio_dev);
-
-err_ret:
- return ret;
-}
-
-static int adis16209_initial_setup(struct iio_dev *indio_dev)
-{
- int ret;
-
- /* Disable IRQ */
- ret = adis16209_set_irq(indio_dev, false);
- if (ret) {
- dev_err(&indio_dev->dev, "disable irq failed");
- goto err_ret;
- }
-
- /* Do self test */
- ret = adis16209_self_test(indio_dev);
- if (ret) {
- dev_err(&indio_dev->dev, "self test failure");
- goto err_ret;
- }
-
- /* Read status register to check the result */
- ret = adis16209_check_status(indio_dev);
- if (ret) {
- adis16209_reset(indio_dev);
- dev_err(&indio_dev->dev, "device not playing ball -> reset");
- msleep(ADIS16209_STARTUP_DELAY);
- ret = adis16209_check_status(indio_dev);
- if (ret) {
- dev_err(&indio_dev->dev, "giving up");
- goto err_ret;
- }
- }
-
-err_ret:
- return ret;
-}
-
-enum adis16209_chan {
- in_supply,
- temp,
- accel_x,
- accel_y,
- incli_x,
- incli_y,
- in_aux,
- rot,
-};
-
-static const u8 adis16209_addresses[8][2] = {
- [in_supply] = { ADIS16209_SUPPLY_OUT },
- [in_aux] = { ADIS16209_AUX_ADC },
- [accel_x] = { ADIS16209_XACCL_OUT, ADIS16209_XACCL_NULL },
- [accel_y] = { ADIS16209_YACCL_OUT, ADIS16209_YACCL_NULL },
- [incli_x] = { ADIS16209_XINCL_OUT, ADIS16209_XINCL_NULL },
- [incli_y] = { ADIS16209_YINCL_OUT, ADIS16209_YINCL_NULL },
- [rot] = { ADIS16209_ROT_OUT },
- [temp] = { ADIS16209_TEMP_OUT },
+static const u8 adis16209_addresses[8][1] = {
+ [ADIS16209_SCAN_SUPPLY] = { },
+ [ADIS16209_SCAN_AUX_ADC] = { },
+ [ADIS16209_SCAN_ACC_X] = { ADIS16209_XACCL_NULL },
+ [ADIS16209_SCAN_ACC_Y] = { ADIS16209_YACCL_NULL },
+ [ADIS16209_SCAN_INCLI_X] = { ADIS16209_XINCL_NULL },
+ [ADIS16209_SCAN_INCLI_Y] = { ADIS16209_YINCL_NULL },
+ [ADIS16209_SCAN_ROT] = { },
+ [ADIS16209_SCAN_TEMP] = { },
};
static int adis16209_write_raw(struct iio_dev *indio_dev,
@@ -283,6 +40,7 @@ static int adis16209_write_raw(struct iio_dev *indio_dev,
int val2,
long mask)
{
+ struct adis *st = iio_priv(indio_dev);
int bits;
s16 val16;
u8 addr;
@@ -295,10 +53,10 @@ static int adis16209_write_raw(struct iio_dev *indio_dev,
break;
default:
return -EINVAL;
- };
+ }
val16 = val & ((1 << bits) - 1);
- addr = adis16209_addresses[chan->address][1];
- return adis16209_spi_write_reg_16(indio_dev, addr, val16);
+ addr = adis16209_addresses[chan->scan_index][0];
+ return adis_write_reg_16(st, addr, val16);
}
return -EINVAL;
}
@@ -308,6 +66,7 @@ static int adis16209_read_raw(struct iio_dev *indio_dev,
int *val, int *val2,
long mask)
{
+ struct adis *st = iio_priv(indio_dev);
int ret;
int bits;
u8 addr;
@@ -315,29 +74,8 @@ static int adis16209_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
- mutex_lock(&indio_dev->mlock);
- addr = adis16209_addresses[chan->address][0];
- ret = adis16209_spi_read_reg_16(indio_dev, addr, &val16);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
-
- if (val16 & ADIS16209_ERROR_ACTIVE) {
- ret = adis16209_check_status(indio_dev);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
- }
- val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
- if (chan->scan_type.sign == 's')
- val16 = (s16)(val16 <<
- (16 - chan->scan_type.realbits)) >>
- (16 - chan->scan_type.realbits);
- *val = val16;
- mutex_unlock(&indio_dev->mlock);
- return IIO_VAL_INT;
+ return adis_single_conversion(indio_dev, chan,
+ ADIS16209_ERROR_ACTIVE, val);
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_VOLTAGE:
@@ -374,10 +112,10 @@ static int adis16209_read_raw(struct iio_dev *indio_dev,
break;
default:
return -EINVAL;
- };
+ }
mutex_lock(&indio_dev->mlock);
- addr = adis16209_addresses[chan->address][1];
- ret = adis16209_spi_read_reg_16(indio_dev, addr, &val16);
+ addr = adis16209_addresses[chan->scan_index][0];
+ ret = adis_read_reg_16(st, addr, &val16);
if (ret) {
mutex_unlock(&indio_dev->mlock);
return ret;
@@ -392,128 +130,56 @@ static int adis16209_read_raw(struct iio_dev *indio_dev,
}
static const struct iio_chan_spec adis16209_channels[] = {
- {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 0,
- .extend_name = "supply",
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in_supply,
- .scan_index = ADIS16209_SCAN_SUPPLY,
- .scan_type = {
- .sign = 'u',
- .realbits = 14,
- .storagebits = 16,
- },
- }, {
- .type = IIO_TEMP,
- .indexed = 0,
- .channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
- IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
- .address = temp,
- .scan_index = ADIS16209_SCAN_TEMP,
- .scan_type = {
- .sign = 'u',
- .realbits = 12,
- .storagebits = 16,
- },
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
- .address = accel_x,
- .scan_index = ADIS16209_SCAN_ACC_X,
- .scan_type = {
- .sign = 's',
- .realbits = 14,
- .storagebits = 16,
- },
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
- .address = accel_y,
- .scan_index = ADIS16209_SCAN_ACC_Y,
- .scan_type = {
- .sign = 's',
- .realbits = 14,
- .storagebits = 16,
- },
- }, {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 1,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in_aux,
- .scan_index = ADIS16209_SCAN_AUX_ADC,
- .scan_type = {
- .sign = 'u',
- .realbits = 12,
- .storagebits = 16,
- },
- }, {
- .type = IIO_INCLI,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT,
- .address = incli_x,
- .scan_index = ADIS16209_SCAN_INCLI_X,
- .scan_type = {
- .sign = 's',
- .realbits = 14,
- .storagebits = 16,
- },
- }, {
- .type = IIO_INCLI,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT,
- .address = incli_y,
- .scan_index = ADIS16209_SCAN_INCLI_Y,
- .scan_type = {
- .sign = 's',
- .realbits = 14,
- .storagebits = 16,
- },
- }, {
- .type = IIO_ROT,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
- IIO_CHAN_INFO_SCALE_SHARED_BIT,
- .address = rot,
- .scan_index = ADIS16209_SCAN_ROT,
- .scan_type = {
- .sign = 's',
- .realbits = 14,
- .storagebits = 16,
- },
- },
+ ADIS_SUPPLY_CHAN(ADIS16209_SUPPLY_OUT, ADIS16209_SCAN_SUPPLY, 14),
+ ADIS_TEMP_CHAN(ADIS16209_TEMP_OUT, ADIS16209_SCAN_TEMP, 12),
+ ADIS_ACCEL_CHAN(X, ADIS16209_XACCL_OUT, ADIS16209_SCAN_ACC_X,
+ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14),
+ ADIS_ACCEL_CHAN(Y, ADIS16209_YACCL_OUT, ADIS16209_SCAN_ACC_Y,
+ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14),
+ ADIS_AUX_ADC_CHAN(ADIS16209_AUX_ADC, ADIS16209_SCAN_AUX_ADC, 12),
+ ADIS_INCLI_CHAN(X, ADIS16209_XINCL_OUT, ADIS16209_SCAN_INCLI_X, 0, 14),
+ ADIS_INCLI_CHAN(Y, ADIS16209_YINCL_OUT, ADIS16209_SCAN_INCLI_Y, 0, 14),
+ ADIS_ROT_CHAN(X, ADIS16209_ROT_OUT, ADIS16209_SCAN_ROT, 0, 14),
IIO_CHAN_SOFT_TIMESTAMP(8)
};
static const struct iio_info adis16209_info = {
.read_raw = &adis16209_read_raw,
.write_raw = &adis16209_write_raw,
+ .update_scan_mode = adis_update_scan_mode,
.driver_module = THIS_MODULE,
};
-static int __devinit adis16209_probe(struct spi_device *spi)
+static const char * const adis16209_status_error_msgs[] = {
+ [ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT] = "Self test failure",
+ [ADIS16209_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure",
+ [ADIS16209_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed",
+ [ADIS16209_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V",
+ [ADIS16209_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V",
+};
+
+static const struct adis_data adis16209_data = {
+ .read_delay = 30,
+ .msc_ctrl_reg = ADIS16209_MSC_CTRL,
+ .glob_cmd_reg = ADIS16209_GLOB_CMD,
+ .diag_stat_reg = ADIS16209_DIAG_STAT,
+
+ .self_test_mask = ADIS16209_MSC_CTRL_SELF_TEST_EN,
+ .startup_delay = ADIS16209_STARTUP_DELAY,
+
+ .status_error_msgs = adis16209_status_error_msgs,
+ .status_error_mask = BIT(ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT) |
+ BIT(ADIS16209_DIAG_STAT_SPI_FAIL_BIT) |
+ BIT(ADIS16209_DIAG_STAT_FLASH_UPT_BIT) |
+ BIT(ADIS16209_DIAG_STAT_POWER_HIGH_BIT) |
+ BIT(ADIS16209_DIAG_STAT_POWER_LOW_BIT),
+};
+
+
+static int adis16209_probe(struct spi_device *spi)
{
int ret;
- struct adis16209_state *st;
+ struct adis *st;
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
@@ -525,8 +191,6 @@ static int __devinit adis16209_probe(struct spi_device *spi)
st = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
- st->us = spi;
- mutex_init(&st->buf_lock);
indio_dev->name = spi->dev.driver->name;
indio_dev->dev.parent = &spi->dev;
@@ -535,54 +199,38 @@ static int __devinit adis16209_probe(struct spi_device *spi)
indio_dev->num_channels = ARRAY_SIZE(adis16209_channels);
indio_dev->modes = INDIO_DIRECT_MODE;
- ret = adis16209_configure_ring(indio_dev);
+ ret = adis_init(st, indio_dev, spi, &adis16209_data);
+ if (ret)
+ goto error_free_dev;
+ ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL);
if (ret)
goto error_free_dev;
-
- ret = iio_buffer_register(indio_dev,
- adis16209_channels,
- ARRAY_SIZE(adis16209_channels));
- if (ret) {
- printk(KERN_ERR "failed to initialize the ring\n");
- goto error_unreg_ring_funcs;
- }
-
- if (spi->irq) {
- ret = adis16209_probe_trigger(indio_dev);
- if (ret)
- goto error_uninitialize_ring;
- }
/* Get the device into a sane initial state */
- ret = adis16209_initial_setup(indio_dev);
+ ret = adis_initial_startup(st);
if (ret)
- goto error_remove_trigger;
+ goto error_cleanup_buffer_trigger;
ret = iio_device_register(indio_dev);
if (ret)
- goto error_remove_trigger;
+ goto error_cleanup_buffer_trigger;
return 0;
-error_remove_trigger:
- adis16209_remove_trigger(indio_dev);
-error_uninitialize_ring:
- iio_buffer_unregister(indio_dev);
-error_unreg_ring_funcs:
- adis16209_unconfigure_ring(indio_dev);
+error_cleanup_buffer_trigger:
+ adis_cleanup_buffer_and_trigger(st, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
-static int __devexit adis16209_remove(struct spi_device *spi)
+static int adis16209_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct adis *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- adis16209_remove_trigger(indio_dev);
- iio_buffer_unregister(indio_dev);
- adis16209_unconfigure_ring(indio_dev);
+ adis_cleanup_buffer_and_trigger(st, indio_dev);
iio_device_free(indio_dev);
return 0;
@@ -594,7 +242,7 @@ static struct spi_driver adis16209_driver = {
.owner = THIS_MODULE,
},
.probe = adis16209_probe,
- .remove = __devexit_p(adis16209_remove),
+ .remove = adis16209_remove,
};
module_spi_driver(adis16209_driver);
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
deleted file mode 100644
index f939e29d6c8..00000000000
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ /dev/null
@@ -1,134 +0,0 @@
-#include <linux/export.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-
-#include <linux/iio/iio.h>
-#include "../ring_sw.h"
-#include <linux/iio/trigger_consumer.h>
-#include "adis16209.h"
-
-/**
- * adis16209_read_ring_data() read data registers which will be placed into ring
- * @indio_dev: the IIO device
- * @rx: somewhere to pass back the value read
- **/
-static int adis16209_read_ring_data(struct iio_dev *indio_dev, u8 *rx)
-{
- struct spi_message msg;
- struct adis16209_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[ADIS16209_OUTPUTS + 1];
- int ret;
- int i;
-
- mutex_lock(&st->buf_lock);
-
- spi_message_init(&msg);
-
- memset(xfers, 0, sizeof(xfers));
- for (i = 0; i <= ADIS16209_OUTPUTS; i++) {
- xfers[i].bits_per_word = 8;
- xfers[i].cs_change = 1;
- xfers[i].len = 2;
- xfers[i].delay_usecs = 30;
- xfers[i].tx_buf = st->tx + 2 * i;
- st->tx[2 * i]
- = ADIS16209_READ_REG(ADIS16209_SUPPLY_OUT + 2 * i);
- st->tx[2 * i + 1] = 0;
- if (i >= 1)
- xfers[i].rx_buf = rx + 2 * (i - 1);
- spi_message_add_tail(&xfers[i], &msg);
- }
-
- ret = spi_sync(st->us, &msg);
- if (ret)
- dev_err(&st->us->dev, "problem when burst reading");
-
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
- * specific to be rolled into the core.
- */
-static irqreturn_t adis16209_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct adis16209_state *st = iio_priv(indio_dev);
- int i = 0;
- s16 *data;
-
- data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
- if (data == NULL) {
- dev_err(&st->us->dev, "memory alloc failed in ring bh");
- goto done;
- }
-
- if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
- adis16209_read_ring_data(indio_dev, st->rx) >= 0)
- for (; i < bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength); i++)
- data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
-
- /* Guaranteed to be aligned with 8 byte boundary */
- if (indio_dev->scan_timestamp)
- *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
-
- iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
-
- kfree(data);
-done:
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
-{
- iio_dealloc_pollfunc(indio_dev->pollfunc);
- iio_sw_rb_free(indio_dev->buffer);
-}
-
-static const struct iio_buffer_setup_ops adis16209_ring_setup_ops = {
- .preenable = &iio_sw_buffer_preenable,
- .postenable = &iio_triggered_buffer_postenable,
- .predisable = &iio_triggered_buffer_predisable,
-};
-
-int adis16209_configure_ring(struct iio_dev *indio_dev)
-{
- int ret = 0;
- struct iio_buffer *ring;
-
- ring = iio_sw_rb_allocate(indio_dev);
- if (!ring) {
- ret = -ENOMEM;
- return ret;
- }
- indio_dev->buffer = ring;
- ring->scan_timestamp = true;
- indio_dev->setup_ops = &adis16209_ring_setup_ops;
-
- indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
- &adis16209_trigger_handler,
- IRQF_ONESHOT,
- indio_dev,
- "%s_consumer%d",
- indio_dev->name,
- indio_dev->id);
- if (indio_dev->pollfunc == NULL) {
- ret = -ENOMEM;
- goto error_iio_sw_rb_free;
- }
-
- indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
- return 0;
-
-error_iio_sw_rb_free:
- iio_sw_rb_free(indio_dev->buffer);
- return ret;
-}
diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c
deleted file mode 100644
index 2ad93dcaf40..00000000000
--- a/drivers/staging/iio/accel/adis16209_trigger.c
+++ /dev/null
@@ -1,81 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/export.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/trigger.h>
-#include "adis16209.h"
-
-/**
- * adis16209_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static irqreturn_t adis16209_data_rdy_trig_poll(int irq, void *trig)
-{
- iio_trigger_poll(trig, iio_get_time_ns());
- return IRQ_HANDLED;
-}
-
-/**
- * adis16209_data_rdy_trigger_set_state() set datardy interrupt state
- **/
-static int adis16209_data_rdy_trigger_set_state(struct iio_trigger *trig,
- bool state)
-{
- struct iio_dev *indio_dev = trig->private_data;
-
- dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
- return adis16209_set_irq(indio_dev, state);
-}
-
-static const struct iio_trigger_ops adis16209_trigger_ops = {
- .owner = THIS_MODULE,
- .set_trigger_state = &adis16209_data_rdy_trigger_set_state,
-};
-
-int adis16209_probe_trigger(struct iio_dev *indio_dev)
-{
- int ret;
- struct adis16209_state *st = iio_priv(indio_dev);
-
- st->trig = iio_trigger_alloc("adis16209-dev%d", indio_dev->id);
- if (st->trig == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
-
- ret = request_irq(st->us->irq,
- adis16209_data_rdy_trig_poll,
- IRQF_TRIGGER_RISING,
- "adis16209",
- st->trig);
- if (ret)
- goto error_free_trig;
- st->trig->dev.parent = &st->us->dev;
- st->trig->ops = &adis16209_trigger_ops;
- st->trig->private_data = indio_dev;
- ret = iio_trigger_register(st->trig);
-
- /* select default trigger */
- indio_dev->trig = st->trig;
- if (ret)
- goto error_free_irq;
-
- return 0;
-
-error_free_irq:
- free_irq(st->us->irq, st->trig);
-error_free_trig:
- iio_trigger_free(st->trig);
-error_ret:
- return ret;
-}
-
-void adis16209_remove_trigger(struct iio_dev *indio_dev)
-{
- struct adis16209_state *st = iio_priv(indio_dev);
-
- iio_trigger_unregister(st->trig);
- free_irq(st->us->irq, st->trig);
- iio_trigger_free(st->trig);
-}
diff --git a/drivers/staging/iio/accel/adis16220.h b/drivers/staging/iio/accel/adis16220.h
index 024313cf5cf..a894ad7fb26 100644
--- a/drivers/staging/iio/accel/adis16220.h
+++ b/drivers/staging/iio/accel/adis16220.h
@@ -1,10 +1,9 @@
#ifndef SPI_ADIS16220_H_
#define SPI_ADIS16220_H_
-#define ADIS16220_STARTUP_DELAY 220 /* ms */
+#include <linux/iio/imu/adis.h>
-#define ADIS16220_READ_REG(a) a
-#define ADIS16220_WRITE_REG(a) ((a) | 0x80)
+#define ADIS16220_STARTUP_DELAY 220 /* ms */
/* Flash memory write count */
#define ADIS16220_FLASH_CNT 0x00
@@ -102,15 +101,15 @@
#define ADIS16220_DIAG_STAT_FLASH_CHK (1<<6)
#define ADIS16220_DIAG_STAT_SELF_TEST (1<<5)
/* Capture period violation/interruption */
-#define ADIS16220_DIAG_STAT_VIOLATION (1<<4)
+#define ADIS16220_DIAG_STAT_VIOLATION_BIT 4
/* SPI communications failure */
-#define ADIS16220_DIAG_STAT_SPI_FAIL (1<<3)
+#define ADIS16220_DIAG_STAT_SPI_FAIL_BIT 3
/* Flash update failure */
-#define ADIS16220_DIAG_STAT_FLASH_UPT (1<<2)
+#define ADIS16220_DIAG_STAT_FLASH_UPT_BIT 2
/* Power supply above 3.625 V */
-#define ADIS16220_DIAG_STAT_POWER_HIGH (1<<1)
+#define ADIS16220_DIAG_STAT_POWER_HIGH_BIT 1
/* Power supply below 3.15 V */
-#define ADIS16220_DIAG_STAT_POWER_LOW (1<<0)
+#define ADIS16220_DIAG_STAT_POWER_LOW_BIT 0
/* GLOB_CMD */
#define ADIS16220_GLOB_CMD_SW_RESET (1<<7)
@@ -125,13 +124,14 @@
/**
* struct adis16220_state - device instance specific data
- * @us: actual spi_device
+ * @adis: adis device
* @tx: transmit buffer
* @rx: receive buffer
* @buf_lock: mutex to protect tx and rx
**/
struct adis16220_state {
- struct spi_device *us;
+ struct adis adis;
+
struct mutex buf_lock;
u8 tx[ADIS16220_MAX_TX] ____cacheline_aligned;
u8 rx[ADIS16220_MAX_RX];
diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c
index eaadd9df3f7..370b01aa767 100644
--- a/drivers/staging/iio/accel/adis16220_core.c
+++ b/drivers/staging/iio/accel/adis16220_core.c
@@ -20,138 +20,19 @@
#include "adis16220.h"
-#define DRIVER_NAME "adis16220"
-
-/**
- * adis16220_spi_write_reg_8() - write single byte to a register
- * @indio_dev: iio device associated with child of actual device
- * @reg_address: the address of the register to be written
- * @val: the value to write
- **/
-static int adis16220_spi_write_reg_8(struct iio_dev *indio_dev,
- u8 reg_address,
- u8 val)
-{
- int ret;
- struct adis16220_state *st = iio_priv(indio_dev);
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16220_WRITE_REG(reg_address);
- st->tx[1] = val;
-
- ret = spi_write(st->us, st->tx, 2);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16220_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @indio_dev: iio device associated with child of actual device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: value to be written
- **/
-static int adis16220_spi_write_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 value)
-{
- int ret;
- struct spi_message msg;
- struct adis16220_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- .delay_usecs = 35,
- }, {
- .tx_buf = st->tx + 2,
- .bits_per_word = 8,
- .len = 2,
- .delay_usecs = 35,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16220_WRITE_REG(lower_reg_address);
- st->tx[1] = value & 0xFF;
- st->tx[2] = ADIS16220_WRITE_REG(lower_reg_address + 1);
- st->tx[3] = (value >> 8) & 0xFF;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16220_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @indio_dev: iio device associated with child of actual device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: somewhere to pass back the value read
- **/
-static int adis16220_spi_read_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 *val)
-{
- struct spi_message msg;
- struct adis16220_state *st = iio_priv(indio_dev);
- int ret;
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- .delay_usecs = 35,
- }, {
- .rx_buf = st->rx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- .delay_usecs = 35,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16220_READ_REG(lower_reg_address);
- st->tx[1] = 0;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- if (ret) {
- dev_err(&st->us->dev,
- "problem when reading 16 bit register 0x%02X",
- lower_reg_address);
- goto error_ret;
- }
- *val = (st->rx[0] << 8) | st->rx[1];
-
-error_ret:
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
static ssize_t adis16220_read_16bit(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct adis16220_state *st = iio_priv(indio_dev);
ssize_t ret;
s16 val = 0;
/* Take the iio_dev status lock */
mutex_lock(&indio_dev->mlock);
- ret = adis16220_spi_read_reg_16(indio_dev, this_attr->address,
+ ret = adis_read_reg_16(&st->adis, this_attr->address,
(u16 *)&val);
mutex_unlock(&indio_dev->mlock);
if (ret)
@@ -166,13 +47,14 @@ static ssize_t adis16220_write_16bit(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ struct adis16220_state *st = iio_priv(indio_dev);
int ret;
u16 val;
ret = kstrtou16(buf, 10, &val);
if (ret)
goto error_ret;
- ret = adis16220_spi_write_reg_16(indio_dev, this_attr->address, val);
+ ret = adis_write_reg_16(&st->adis, this_attr->address, val);
error_ret:
return ret ? ret : len;
@@ -180,10 +62,11 @@ error_ret:
static int adis16220_capture(struct iio_dev *indio_dev)
{
+ struct adis16220_state *st = iio_priv(indio_dev);
int ret;
- ret = adis16220_spi_write_reg_16(indio_dev,
- ADIS16220_GLOB_CMD,
- 0xBF08); /* initiates a manual data capture */
+
+ /* initiates a manual data capture */
+ ret = adis_write_reg_16(&st->adis, ADIS16220_GLOB_CMD, 0xBF08);
if (ret)
dev_err(&indio_dev->dev, "problem beginning capture");
@@ -192,18 +75,6 @@ static int adis16220_capture(struct iio_dev *indio_dev)
return ret;
}
-static int adis16220_reset(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16220_spi_write_reg_8(indio_dev,
- ADIS16220_GLOB_CMD,
- ADIS16220_GLOB_CMD_SW_RESET);
- if (ret)
- dev_err(&indio_dev->dev, "problem resetting device");
-
- return ret;
-}
-
static ssize_t adis16220_write_capture(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
@@ -224,81 +95,6 @@ static ssize_t adis16220_write_capture(struct device *dev,
return len;
}
-static int adis16220_check_status(struct iio_dev *indio_dev)
-{
- u16 status;
- int ret;
-
- ret = adis16220_spi_read_reg_16(indio_dev, ADIS16220_DIAG_STAT,
- &status);
-
- if (ret < 0) {
- dev_err(&indio_dev->dev, "Reading status failed\n");
- goto error_ret;
- }
- ret = status & 0x7F;
-
- if (status & ADIS16220_DIAG_STAT_VIOLATION)
- dev_err(&indio_dev->dev,
- "Capture period violation/interruption\n");
- if (status & ADIS16220_DIAG_STAT_SPI_FAIL)
- dev_err(&indio_dev->dev, "SPI failure\n");
- if (status & ADIS16220_DIAG_STAT_FLASH_UPT)
- dev_err(&indio_dev->dev, "Flash update failed\n");
- if (status & ADIS16220_DIAG_STAT_POWER_HIGH)
- dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
- if (status & ADIS16220_DIAG_STAT_POWER_LOW)
- dev_err(&indio_dev->dev, "Power supply below 3.15V\n");
-
-error_ret:
- return ret;
-}
-
-static int adis16220_self_test(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16220_spi_write_reg_16(indio_dev,
- ADIS16220_MSC_CTRL,
- ADIS16220_MSC_CTRL_SELF_TEST_EN);
- if (ret) {
- dev_err(&indio_dev->dev, "problem starting self test");
- goto err_ret;
- }
-
- adis16220_check_status(indio_dev);
-
-err_ret:
- return ret;
-}
-
-static int adis16220_initial_setup(struct iio_dev *indio_dev)
-{
- int ret;
-
- /* Do self test */
- ret = adis16220_self_test(indio_dev);
- if (ret) {
- dev_err(&indio_dev->dev, "self test failure");
- goto err_ret;
- }
-
- /* Read status register to check the result */
- ret = adis16220_check_status(indio_dev);
- if (ret) {
- adis16220_reset(indio_dev);
- dev_err(&indio_dev->dev, "device not playing ball -> reset");
- msleep(ADIS16220_STARTUP_DELAY);
- ret = adis16220_check_status(indio_dev);
- if (ret) {
- dev_err(&indio_dev->dev, "giving up");
- goto err_ret;
- }
- }
-
-err_ret:
- return ret;
-}
-
static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
char *buf,
loff_t off,
@@ -335,7 +131,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
count = ADIS16220_CAPTURE_SIZE - off;
/* write the begin position of capture buffer */
- ret = adis16220_spi_write_reg_16(indio_dev,
+ ret = adis_write_reg_16(&st->adis,
ADIS16220_CAPT_PNTR,
off > 1);
if (ret)
@@ -344,8 +140,9 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
/* read count/2 values from capture buffer */
mutex_lock(&st->buf_lock);
+
for (i = 0; i < count; i += 2) {
- st->tx[i] = ADIS16220_READ_REG(addr);
+ st->tx[i] = ADIS_READ_REG(addr);
st->tx[i + 1] = 0;
}
xfers[1].len = count;
@@ -353,7 +150,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
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(st->adis.spi, &msg);
if (ret) {
mutex_unlock(&st->buf_lock);
@@ -474,6 +271,8 @@ static int adis16220_read_raw(struct iio_dev *indio_dev,
int *val, int *val2,
long mask)
{
+ struct adis16220_state *st = iio_priv(indio_dev);
+ const struct adis16220_address_spec *addr;
int ret = -EINVAL;
int addrind = 0;
u16 uval;
@@ -518,28 +317,21 @@ static int adis16220_read_raw(struct iio_dev *indio_dev,
default:
return -EINVAL;
}
- if (adis16220_addresses[chan->address][addrind].sign) {
- ret = adis16220_spi_read_reg_16(indio_dev,
- adis16220_addresses[chan
- ->address]
- [addrind].addr,
- &sval);
+ addr = &adis16220_addresses[chan->address][addrind];
+ if (addr->sign) {
+ ret = adis_read_reg_16(&st->adis, addr->addr, &sval);
if (ret)
return ret;
- bits = adis16220_addresses[chan->address][addrind].bits;
+ bits = addr->bits;
sval &= (1 << bits) - 1;
sval = (s16)(sval << (16 - bits)) >> (16 - bits);
*val = sval;
return IIO_VAL_INT;
} else {
- ret = adis16220_spi_read_reg_16(indio_dev,
- adis16220_addresses[chan
- ->address]
- [addrind].addr,
- &uval);
+ ret = adis_read_reg_16(&st->adis, addr->addr, &uval);
if (ret)
return ret;
- bits = adis16220_addresses[chan->address][addrind].bits;
+ bits = addr->bits;
uval &= (1 << bits) - 1;
*val = uval;
return IIO_VAL_INT;
@@ -603,7 +395,33 @@ static const struct iio_info adis16220_info = {
.read_raw = &adis16220_read_raw,
};
-static int __devinit adis16220_probe(struct spi_device *spi)
+static const char * const adis16220_status_error_msgs[] = {
+ [ADIS16220_DIAG_STAT_VIOLATION_BIT] = "Capture period violation/interruption",
+ [ADIS16220_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure",
+ [ADIS16220_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed",
+ [ADIS16220_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V",
+ [ADIS16220_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V",
+};
+
+static const struct adis_data adis16220_data = {
+ .read_delay = 35,
+ .write_delay = 35,
+ .msc_ctrl_reg = ADIS16220_MSC_CTRL,
+ .glob_cmd_reg = ADIS16220_GLOB_CMD,
+ .diag_stat_reg = ADIS16220_DIAG_STAT,
+
+ .self_test_mask = ADIS16220_MSC_CTRL_SELF_TEST_EN,
+ .startup_delay = ADIS16220_STARTUP_DELAY,
+
+ .status_error_msgs = adis16220_status_error_msgs,
+ .status_error_mask = BIT(ADIS16220_DIAG_STAT_VIOLATION_BIT) |
+ BIT(ADIS16220_DIAG_STAT_SPI_FAIL_BIT) |
+ BIT(ADIS16220_DIAG_STAT_FLASH_UPT_BIT) |
+ BIT(ADIS16220_DIAG_STAT_POWER_HIGH_BIT) |
+ BIT(ADIS16220_DIAG_STAT_POWER_LOW_BIT),
+};
+
+static int adis16220_probe(struct spi_device *spi)
{
int ret;
struct adis16220_state *st;
@@ -620,9 +438,6 @@ static int __devinit adis16220_probe(struct spi_device *spi)
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
- st->us = spi;
- mutex_init(&st->buf_lock);
-
indio_dev->name = spi->dev.driver->name;
indio_dev->dev.parent = &spi->dev;
indio_dev->info = &adis16220_info;
@@ -646,8 +461,11 @@ static int __devinit adis16220_probe(struct spi_device *spi)
if (ret)
goto error_rm_adc1_bin;
+ ret = adis_init(&st->adis, indio_dev, spi, &adis16220_data);
+ if (ret)
+ goto error_rm_adc2_bin;
/* Get the device into a sane initial state */
- ret = adis16220_initial_setup(indio_dev);
+ ret = adis_initial_startup(&st->adis);
if (ret)
goto error_rm_adc2_bin;
return 0;
@@ -666,7 +484,7 @@ error_ret:
return ret;
}
-static int __devexit adis16220_remove(struct spi_device *spi)
+static int adis16220_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
@@ -685,7 +503,7 @@ static struct spi_driver adis16220_driver = {
.owner = THIS_MODULE,
},
.probe = adis16220_probe,
- .remove = __devexit_p(adis16220_remove),
+ .remove = adis16220_remove,
};
module_spi_driver(adis16220_driver);
diff --git a/drivers/staging/iio/accel/adis16240.h b/drivers/staging/iio/accel/adis16240.h
index 3fabcc0b347..d442d49f51f 100644
--- a/drivers/staging/iio/accel/adis16240.h
+++ b/drivers/staging/iio/accel/adis16240.h
@@ -3,9 +3,6 @@
#define ADIS16240_STARTUP_DELAY 220 /* ms */
-#define ADIS16240_READ_REG(a) a
-#define ADIS16240_WRITE_REG(a) ((a) | 0x80)
-
/* Flash memory write count */
#define ADIS16240_FLASH_CNT 0x00
/* Output, power supply */
@@ -75,8 +72,6 @@
/* System command */
#define ADIS16240_GLOB_CMD 0x4A
-#define ADIS16240_OUTPUTS 6
-
/* MSC_CTRL */
/* Enables sum-of-squares output (XYZPEAK_OUT) */
#define ADIS16240_MSC_CTRL_XYZPEAK_OUT_EN (1 << 15)
@@ -101,17 +96,17 @@
/* Flash test, checksum flag: 1 = mismatch, 0 = match */
#define ADIS16240_DIAG_STAT_CHKSUM (1<<6)
/* Power-on, self-test flag: 1 = failure, 0 = pass */
-#define ADIS16240_DIAG_STAT_PWRON_FAIL (1<<5)
+#define ADIS16240_DIAG_STAT_PWRON_FAIL_BIT 5
/* Power-on self-test: 1 = in-progress, 0 = complete */
#define ADIS16240_DIAG_STAT_PWRON_BUSY (1<<4)
/* SPI communications failure */
-#define ADIS16240_DIAG_STAT_SPI_FAIL (1<<3)
+#define ADIS16240_DIAG_STAT_SPI_FAIL_BIT 3
/* Flash update failure */
-#define ADIS16240_DIAG_STAT_FLASH_UPT (1<<2)
+#define ADIS16240_DIAG_STAT_FLASH_UPT_BIT 2
/* Power supply above 3.625 V */
-#define ADIS16240_DIAG_STAT_POWER_HIGH (1<<1)
+#define ADIS16240_DIAG_STAT_POWER_HIGH_BIT 1
/* Power supply below 3.15 V */
-#define ADIS16240_DIAG_STAT_POWER_LOW (1<<0)
+#define ADIS16240_DIAG_STAT_POWER_LOW_BIT 0
/* GLOB_CMD */
#define ADIS16240_GLOB_CMD_RESUME (1<<8)
@@ -120,77 +115,15 @@
#define ADIS16240_ERROR_ACTIVE (1<<14)
-#define ADIS16240_MAX_TX 24
-#define ADIS16240_MAX_RX 24
-
-/**
- * struct adis16240_state - device instance specific data
- * @us: actual spi_device
- * @trig: data ready trigger registered with iio
- * @tx: transmit buffer
- * @rx: receive buffer
- * @buf_lock: mutex to protect tx and rx
- **/
-struct adis16240_state {
- struct spi_device *us;
- struct iio_trigger *trig;
- struct mutex buf_lock;
- u8 tx[ADIS16240_MAX_TX] ____cacheline_aligned;
- u8 rx[ADIS16240_MAX_RX];
-};
-
-int adis16240_set_irq(struct iio_dev *indio_dev, bool enable);
-
/* At the moment triggers are only used for ring buffer
* filling. This may change!
*/
-#define ADIS16240_SCAN_SUPPLY 0
-#define ADIS16240_SCAN_ACC_X 1
-#define ADIS16240_SCAN_ACC_Y 2
-#define ADIS16240_SCAN_ACC_Z 3
+#define ADIS16240_SCAN_ACC_X 0
+#define ADIS16240_SCAN_ACC_Y 1
+#define ADIS16240_SCAN_ACC_Z 2
+#define ADIS16240_SCAN_SUPPLY 3
#define ADIS16240_SCAN_AUX_ADC 4
#define ADIS16240_SCAN_TEMP 5
-#ifdef CONFIG_IIO_BUFFER
-void adis16240_remove_trigger(struct iio_dev *indio_dev);
-int adis16240_probe_trigger(struct iio_dev *indio_dev);
-
-ssize_t adis16240_read_data_from_ring(struct device *dev,
- struct device_attribute *attr,
- char *buf);
-
-
-int adis16240_configure_ring(struct iio_dev *indio_dev);
-void adis16240_unconfigure_ring(struct iio_dev *indio_dev);
-
-#else /* CONFIG_IIO_BUFFER */
-
-static inline void adis16240_remove_trigger(struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis16240_probe_trigger(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline ssize_t
-adis16240_read_data_from_ring(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return 0;
-}
-
-static int adis16240_configure_ring(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void adis16240_unconfigure_ring(struct iio_dev *indio_dev)
-{
-}
-
-#endif /* CONFIG_IIO_BUFFER */
#endif /* SPI_ADIS16240_H_ */
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
index 35e093973d5..e97fa0b0233 100644
--- a/drivers/staging/iio/accel/adis16240_core.c
+++ b/drivers/staging/iio/accel/adis16240_core.c
@@ -22,151 +22,29 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
#include "adis16240.h"
-#define DRIVER_NAME "adis16240"
-
-static int adis16240_check_status(struct iio_dev *indio_dev);
-
-/**
- * adis16240_spi_write_reg_8() - write single byte to a register
- * @indio_dev: iio_dev associated with device
- * @reg_address: the address of the register to be written
- * @val: the value to write
- **/
-static int adis16240_spi_write_reg_8(struct iio_dev *indio_dev,
- u8 reg_address,
- u8 val)
-{
- int ret;
- struct adis16240_state *st = iio_priv(indio_dev);
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16240_WRITE_REG(reg_address);
- st->tx[1] = val;
-
- ret = spi_write(st->us, st->tx, 2);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16240_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @indio_dev: iio_dev for this device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: value to be written
- **/
-static int adis16240_spi_write_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 value)
-{
- int ret;
- struct spi_message msg;
- struct adis16240_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- .delay_usecs = 35,
- }, {
- .tx_buf = st->tx + 2,
- .bits_per_word = 8,
- .len = 2,
- .delay_usecs = 35,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16240_WRITE_REG(lower_reg_address);
- st->tx[1] = value & 0xFF;
- st->tx[2] = ADIS16240_WRITE_REG(lower_reg_address + 1);
- st->tx[3] = (value >> 8) & 0xFF;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16240_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @indio_dev: iio_dev for this device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: somewhere to pass back the value read
- **/
-static int adis16240_spi_read_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 *val)
-{
- struct spi_message msg;
- struct adis16240_state *st = iio_priv(indio_dev);
- int ret;
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- .delay_usecs = 35,
- }, {
- .rx_buf = st->rx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- .delay_usecs = 35,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16240_READ_REG(lower_reg_address);
- st->tx[1] = 0;
- st->tx[2] = 0;
- st->tx[3] = 0;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- if (ret) {
- dev_err(&st->us->dev,
- "problem when reading 16 bit register 0x%02X",
- lower_reg_address);
- goto error_ret;
- }
- *val = (st->rx[0] << 8) | st->rx[1];
-
-error_ret:
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
static ssize_t adis16240_spi_read_signed(struct device *dev,
struct device_attribute *attr,
char *buf,
unsigned bits)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct adis *st = iio_priv(indio_dev);
int ret;
s16 val = 0;
unsigned shift = 16 - bits;
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- ret = adis16240_spi_read_reg_16(indio_dev,
+ ret = adis_read_reg_16(st,
this_attr->address, (u16 *)&val);
if (ret)
return ret;
if (val & ADIS16240_ERROR_ACTIVE)
- adis16240_check_status(indio_dev);
+ adis_check_status(st);
val = ((s16)(val << shift) >> shift);
return sprintf(buf, "%d\n", val);
@@ -187,152 +65,16 @@ static ssize_t adis16240_read_12bit_signed(struct device *dev,
return ret;
}
-static int adis16240_reset(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16240_spi_write_reg_8(indio_dev,
- ADIS16240_GLOB_CMD,
- ADIS16240_GLOB_CMD_SW_RESET);
- if (ret)
- dev_err(&indio_dev->dev, "problem resetting device");
-
- return ret;
-}
-
-int adis16240_set_irq(struct iio_dev *indio_dev, bool enable)
-{
- int ret = 0;
- u16 msc;
-
- ret = adis16240_spi_read_reg_16(indio_dev,
- ADIS16240_MSC_CTRL, &msc);
- if (ret)
- goto error_ret;
-
- msc |= ADIS16240_MSC_CTRL_ACTIVE_HIGH;
- msc &= ~ADIS16240_MSC_CTRL_DATA_RDY_DIO2;
- if (enable)
- msc |= ADIS16240_MSC_CTRL_DATA_RDY_EN;
- else
- msc &= ~ADIS16240_MSC_CTRL_DATA_RDY_EN;
-
- ret = adis16240_spi_write_reg_16(indio_dev,
- ADIS16240_MSC_CTRL, msc);
-
-error_ret:
- return ret;
-}
-
-static int adis16240_self_test(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16240_spi_write_reg_16(indio_dev,
- ADIS16240_MSC_CTRL,
- ADIS16240_MSC_CTRL_SELF_TEST_EN);
- if (ret) {
- dev_err(&indio_dev->dev, "problem starting self test");
- goto err_ret;
- }
-
- msleep(ADIS16240_STARTUP_DELAY);
-
- adis16240_check_status(indio_dev);
-
-err_ret:
- return ret;
-}
-
-static int adis16240_check_status(struct iio_dev *indio_dev)
-{
- u16 status;
- int ret;
- struct device *dev = &indio_dev->dev;
-
- ret = adis16240_spi_read_reg_16(indio_dev,
- ADIS16240_DIAG_STAT, &status);
-
- if (ret < 0) {
- dev_err(dev, "Reading status failed\n");
- goto error_ret;
- }
-
- ret = status & 0x2F;
- if (status & ADIS16240_DIAG_STAT_PWRON_FAIL)
- dev_err(dev, "Power-on, self-test fail\n");
- if (status & ADIS16240_DIAG_STAT_SPI_FAIL)
- dev_err(dev, "SPI failure\n");
- if (status & ADIS16240_DIAG_STAT_FLASH_UPT)
- dev_err(dev, "Flash update failed\n");
- if (status & ADIS16240_DIAG_STAT_POWER_HIGH)
- dev_err(dev, "Power supply above 3.625V\n");
- if (status & ADIS16240_DIAG_STAT_POWER_LOW)
- dev_err(dev, "Power supply below 2.225V\n");
-
-error_ret:
- return ret;
-}
-
-static int adis16240_initial_setup(struct iio_dev *indio_dev)
-{
- int ret;
- struct device *dev = &indio_dev->dev;
-
- /* Disable IRQ */
- ret = adis16240_set_irq(indio_dev, false);
- if (ret) {
- dev_err(dev, "disable irq failed");
- goto err_ret;
- }
-
- /* Do self test */
- ret = adis16240_self_test(indio_dev);
- if (ret) {
- dev_err(dev, "self test failure");
- goto err_ret;
- }
-
- /* Read status register to check the result */
- ret = adis16240_check_status(indio_dev);
- if (ret) {
- adis16240_reset(indio_dev);
- dev_err(dev, "device not playing ball -> reset");
- msleep(ADIS16240_STARTUP_DELAY);
- ret = adis16240_check_status(indio_dev);
- if (ret) {
- dev_err(dev, "giving up");
- goto err_ret;
- }
- }
-
-err_ret:
- return ret;
-}
-
static IIO_DEVICE_ATTR(in_accel_xyz_squared_peak_raw, S_IRUGO,
adis16240_read_12bit_signed, NULL,
ADIS16240_XYZPEAK_OUT);
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("4096");
-enum adis16240_chan {
- in_supply,
- in_aux,
- accel_x,
- accel_y,
- accel_z,
- temp,
-};
-
-static const u8 adis16240_addresses[6][3] = {
- [in_supply] = { ADIS16240_SUPPLY_OUT },
- [in_aux] = { ADIS16240_AUX_ADC },
- [accel_x] = { ADIS16240_XACCL_OUT, ADIS16240_XACCL_OFF,
- ADIS16240_XPEAK_OUT },
- [accel_y] = { ADIS16240_YACCL_OUT, ADIS16240_YACCL_OFF,
- ADIS16240_YPEAK_OUT },
- [accel_z] = { ADIS16240_ZACCL_OUT, ADIS16240_ZACCL_OFF,
- ADIS16240_ZPEAK_OUT },
- [temp] = { ADIS16240_TEMP_OUT },
+static const u8 adis16240_addresses[][2] = {
+ [ADIS16240_SCAN_ACC_X] = { ADIS16240_XACCL_OFF, ADIS16240_XPEAK_OUT },
+ [ADIS16240_SCAN_ACC_Y] = { ADIS16240_YACCL_OFF, ADIS16240_YPEAK_OUT },
+ [ADIS16240_SCAN_ACC_Z] = { ADIS16240_ZACCL_OFF, ADIS16240_ZPEAK_OUT },
};
static int adis16240_read_raw(struct iio_dev *indio_dev,
@@ -340,6 +82,7 @@ static int adis16240_read_raw(struct iio_dev *indio_dev,
int *val, int *val2,
long mask)
{
+ struct adis *st = iio_priv(indio_dev);
int ret;
int bits;
u8 addr;
@@ -347,29 +90,8 @@ static int adis16240_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
- mutex_lock(&indio_dev->mlock);
- addr = adis16240_addresses[chan->address][0];
- ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
-
- if (val16 & ADIS16240_ERROR_ACTIVE) {
- ret = adis16240_check_status(indio_dev);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
- }
- val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
- if (chan->scan_type.sign == 's')
- val16 = (s16)(val16 <<
- (16 - chan->scan_type.realbits)) >>
- (16 - chan->scan_type.realbits);
- *val = val16;
- mutex_unlock(&indio_dev->mlock);
- return IIO_VAL_INT;
+ return adis_single_conversion(indio_dev, chan,
+ ADIS16240_ERROR_ACTIVE, val);
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_VOLTAGE:
@@ -402,8 +124,8 @@ static int adis16240_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_CALIBBIAS:
bits = 10;
mutex_lock(&indio_dev->mlock);
- addr = adis16240_addresses[chan->address][1];
- ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16);
+ addr = adis16240_addresses[chan->scan_index][0];
+ ret = adis_read_reg_16(st, addr, &val16);
if (ret) {
mutex_unlock(&indio_dev->mlock);
return ret;
@@ -416,8 +138,8 @@ static int adis16240_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_PEAK:
bits = 10;
mutex_lock(&indio_dev->mlock);
- addr = adis16240_addresses[chan->address][2];
- ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16);
+ addr = adis16240_addresses[chan->scan_index][1];
+ ret = adis_read_reg_16(st, addr, &val16);
if (ret) {
mutex_unlock(&indio_dev->mlock);
return ret;
@@ -437,104 +159,32 @@ static int adis16240_write_raw(struct iio_dev *indio_dev,
int val2,
long mask)
{
+ struct adis *st = iio_priv(indio_dev);
int bits = 10;
s16 val16;
u8 addr;
switch (mask) {
case IIO_CHAN_INFO_CALIBBIAS:
val16 = val & ((1 << bits) - 1);
- addr = adis16240_addresses[chan->address][1];
- return adis16240_spi_write_reg_16(indio_dev, addr, val16);
+ addr = adis16240_addresses[chan->scan_index][0];
+ return adis_write_reg_16(st, addr, val16);
}
return -EINVAL;
}
static const struct iio_chan_spec adis16240_channels[] = {
- {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 0,
- .extend_name = "supply",
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in_supply,
- .scan_index = ADIS16240_SCAN_SUPPLY,
- .scan_type = {
- .sign = 'u',
- .realbits = 10,
- .storagebits = 16,
- },
- }, {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 1,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
- .address = in_aux,
- .scan_index = ADIS16240_SCAN_AUX_ADC,
- .scan_type = {
- .sign = 'u',
- .realbits = 10,
- .storagebits = 16,
- },
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
+ ADIS_SUPPLY_CHAN(ADIS16240_SUPPLY_OUT, ADIS16240_SCAN_SUPPLY, 10),
+ ADIS_AUX_ADC_CHAN(ADIS16240_AUX_ADC, ADIS16240_SCAN_AUX_ADC, 10),
+ ADIS_ACCEL_CHAN(X, ADIS16240_XACCL_OUT, ADIS16240_SCAN_ACC_X,
IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_PEAK_SEPARATE_BIT,
- .address = accel_x,
- .scan_index = ADIS16240_SCAN_ACC_X,
- .scan_type = {
- .sign = 's',
- .realbits = 10,
- .storagebits = 16,
- },
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
+ IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 10),
+ ADIS_ACCEL_CHAN(Y, ADIS16240_YACCL_OUT, ADIS16240_SCAN_ACC_Y,
IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_PEAK_SEPARATE_BIT,
- .address = accel_y,
- .scan_index = ADIS16240_SCAN_ACC_Y,
- .scan_type = {
- .sign = 's',
- .realbits = 10,
- .storagebits = 16,
- },
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_Z,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
+ IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 10),
+ ADIS_ACCEL_CHAN(Z, ADIS16240_ZACCL_OUT, ADIS16240_SCAN_ACC_Z,
IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_PEAK_SEPARATE_BIT,
- .address = accel_z,
- .scan_index = ADIS16240_SCAN_ACC_Z,
- .scan_type = {
- .sign = 's',
- .realbits = 10,
- .storagebits = 16,
- },
- }, {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = temp,
- .scan_index = ADIS16240_SCAN_TEMP,
- .scan_type = {
- .sign = 'u',
- .realbits = 10,
- .storagebits = 16,
- },
- },
+ IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 10),
+ ADIS_TEMP_CHAN(ADIS16240_TEMP_OUT, ADIS16240_SCAN_TEMP, 10),
IIO_CHAN_SOFT_TIMESTAMP(6)
};
@@ -552,13 +202,40 @@ static const struct iio_info adis16240_info = {
.attrs = &adis16240_attribute_group,
.read_raw = &adis16240_read_raw,
.write_raw = &adis16240_write_raw,
+ .update_scan_mode = adis_update_scan_mode,
.driver_module = THIS_MODULE,
};
-static int __devinit adis16240_probe(struct spi_device *spi)
+static const char * const adis16240_status_error_msgs[] = {
+ [ADIS16240_DIAG_STAT_PWRON_FAIL_BIT] = "Power on, self-test failed",
+ [ADIS16240_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure",
+ [ADIS16240_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed",
+ [ADIS16240_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V",
+ [ADIS16240_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.225V",
+};
+
+static const struct adis_data adis16240_data = {
+ .write_delay = 35,
+ .read_delay = 35,
+ .msc_ctrl_reg = ADIS16240_MSC_CTRL,
+ .glob_cmd_reg = ADIS16240_GLOB_CMD,
+ .diag_stat_reg = ADIS16240_DIAG_STAT,
+
+ .self_test_mask = ADIS16240_MSC_CTRL_SELF_TEST_EN,
+ .startup_delay = ADIS16240_STARTUP_DELAY,
+
+ .status_error_msgs = adis16240_status_error_msgs,
+ .status_error_mask = BIT(ADIS16240_DIAG_STAT_PWRON_FAIL_BIT) |
+ BIT(ADIS16240_DIAG_STAT_SPI_FAIL_BIT) |
+ BIT(ADIS16240_DIAG_STAT_FLASH_UPT_BIT) |
+ BIT(ADIS16240_DIAG_STAT_POWER_HIGH_BIT) |
+ BIT(ADIS16240_DIAG_STAT_POWER_LOW_BIT),
+};
+
+static int adis16240_probe(struct spi_device *spi)
{
int ret;
- struct adis16240_state *st;
+ struct adis *st;
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
@@ -571,9 +248,6 @@ static int __devinit adis16240_probe(struct spi_device *spi)
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
- st->us = spi;
- mutex_init(&st->buf_lock);
-
indio_dev->name = spi->dev.driver->name;
indio_dev->dev.parent = &spi->dev;
indio_dev->info = &adis16240_info;
@@ -581,54 +255,37 @@ static int __devinit adis16240_probe(struct spi_device *spi)
indio_dev->num_channels = ARRAY_SIZE(adis16240_channels);
indio_dev->modes = INDIO_DIRECT_MODE;
- ret = adis16240_configure_ring(indio_dev);
+ ret = adis_init(st, indio_dev, spi, &adis16240_data);
+ if (ret)
+ goto error_free_dev;
+ ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL);
if (ret)
goto error_free_dev;
-
- ret = iio_buffer_register(indio_dev,
- adis16240_channels,
- ARRAY_SIZE(adis16240_channels));
- if (ret) {
- printk(KERN_ERR "failed to initialize the ring\n");
- goto error_unreg_ring_funcs;
- }
-
- if (spi->irq) {
- ret = adis16240_probe_trigger(indio_dev);
- if (ret)
- goto error_uninitialize_ring;
- }
/* Get the device into a sane initial state */
- ret = adis16240_initial_setup(indio_dev);
+ ret = adis_initial_startup(st);
if (ret)
- goto error_remove_trigger;
+ goto error_cleanup_buffer_trigger;
ret = iio_device_register(indio_dev);
if (ret)
- goto error_remove_trigger;
+ goto error_cleanup_buffer_trigger;
return 0;
-error_remove_trigger:
- adis16240_remove_trigger(indio_dev);
-error_uninitialize_ring:
- iio_buffer_unregister(indio_dev);
-error_unreg_ring_funcs:
- adis16240_unconfigure_ring(indio_dev);
+error_cleanup_buffer_trigger:
+ adis_cleanup_buffer_and_trigger(st, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
-static int __devexit adis16240_remove(struct spi_device *spi)
+static int adis16240_remove(struct spi_device *spi)
{
-
struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct adis *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- adis16240_remove_trigger(indio_dev);
- iio_buffer_unregister(indio_dev);
- adis16240_unconfigure_ring(indio_dev);
+ adis_cleanup_buffer_and_trigger(st, indio_dev);
iio_device_free(indio_dev);
return 0;
@@ -640,7 +297,7 @@ static struct spi_driver adis16240_driver = {
.owner = THIS_MODULE,
},
.probe = adis16240_probe,
- .remove = __devexit_p(adis16240_remove),
+ .remove = adis16240_remove,
};
module_spi_driver(adis16240_driver);
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
deleted file mode 100644
index caff8e25e0a..00000000000
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ /dev/null
@@ -1,132 +0,0 @@
-#include <linux/export.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-
-#include <linux/iio/iio.h>
-#include "../ring_sw.h"
-#include <linux/iio/trigger_consumer.h>
-#include "adis16240.h"
-
-/**
- * adis16240_read_ring_data() read data registers which will be placed into ring
- * @indio_dev: the IIO device
- * @rx: somewhere to pass back the value read
- **/
-static int adis16240_read_ring_data(struct iio_dev *indio_dev, u8 *rx)
-{
- struct spi_message msg;
- struct adis16240_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[ADIS16240_OUTPUTS + 1];
- int ret;
- int i;
-
- mutex_lock(&st->buf_lock);
-
- spi_message_init(&msg);
-
- memset(xfers, 0, sizeof(xfers));
- for (i = 0; i <= ADIS16240_OUTPUTS; i++) {
- xfers[i].bits_per_word = 8;
- xfers[i].cs_change = 1;
- xfers[i].len = 2;
- xfers[i].delay_usecs = 30;
- xfers[i].tx_buf = st->tx + 2 * i;
- st->tx[2 * i]
- = ADIS16240_READ_REG(ADIS16240_SUPPLY_OUT + 2 * i);
- st->tx[2 * i + 1] = 0;
- if (i >= 1)
- xfers[i].rx_buf = rx + 2 * (i - 1);
- spi_message_add_tail(&xfers[i], &msg);
- }
-
- ret = spi_sync(st->us, &msg);
- if (ret)
- dev_err(&st->us->dev, "problem when burst reading");
-
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-static irqreturn_t adis16240_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct adis16240_state *st = iio_priv(indio_dev);
-
- int i = 0;
- s16 *data;
-
- data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
- if (data == NULL) {
- dev_err(&st->us->dev, "memory alloc failed in ring bh");
- goto done;
- }
-
- if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
- adis16240_read_ring_data(indio_dev, st->rx) >= 0)
- for (; i < bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength); i++)
- data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
-
- /* Guaranteed to be aligned with 8 byte boundary */
- if (indio_dev->scan_timestamp)
- *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
-
- iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
-
- kfree(data);
-done:
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-void adis16240_unconfigure_ring(struct iio_dev *indio_dev)
-{
- iio_dealloc_pollfunc(indio_dev->pollfunc);
- iio_sw_rb_free(indio_dev->buffer);
-}
-
-static const struct iio_buffer_setup_ops adis16240_ring_setup_ops = {
- .preenable = &iio_sw_buffer_preenable,
- .postenable = &iio_triggered_buffer_postenable,
- .predisable = &iio_triggered_buffer_predisable,
-};
-
-int adis16240_configure_ring(struct iio_dev *indio_dev)
-{
- int ret = 0;
- struct iio_buffer *ring;
-
- ring = iio_sw_rb_allocate(indio_dev);
- if (!ring) {
- ret = -ENOMEM;
- return ret;
- }
- indio_dev->buffer = ring;
- ring->scan_timestamp = true;
- indio_dev->setup_ops = &adis16240_ring_setup_ops;
-
- indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
- &adis16240_trigger_handler,
- IRQF_ONESHOT,
- indio_dev,
- "%s_consumer%d",
- indio_dev->name,
- indio_dev->id);
- if (indio_dev->pollfunc == NULL) {
- ret = -ENOMEM;
- goto error_iio_sw_rb_free;
- }
-
- indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
- return 0;
-
-error_iio_sw_rb_free:
- iio_sw_rb_free(indio_dev->buffer);
- return ret;
-}
diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c
deleted file mode 100644
index fa90a22b143..00000000000
--- a/drivers/staging/iio/accel/adis16240_trigger.c
+++ /dev/null
@@ -1,82 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/export.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/trigger.h>
-#include "adis16240.h"
-
-/**
- * adis16240_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static irqreturn_t adis16240_data_rdy_trig_poll(int irq, void *trig)
-{
- iio_trigger_poll(trig, iio_get_time_ns());
- return IRQ_HANDLED;
-}
-
-/**
- * adis16240_data_rdy_trigger_set_state() set datardy interrupt state
- **/
-static int adis16240_data_rdy_trigger_set_state(struct iio_trigger *trig,
- bool state)
-{
- struct iio_dev *indio_dev = trig->private_data;
-
- dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
- return adis16240_set_irq(indio_dev, state);
-}
-
-static const struct iio_trigger_ops adis16240_trigger_ops = {
- .owner = THIS_MODULE,
- .set_trigger_state = &adis16240_data_rdy_trigger_set_state,
-};
-
-int adis16240_probe_trigger(struct iio_dev *indio_dev)
-{
- int ret;
- struct adis16240_state *st = iio_priv(indio_dev);
-
- st->trig = iio_trigger_alloc("adis16240-dev%d", indio_dev->id);
- if (st->trig == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
-
- ret = request_irq(st->us->irq,
- adis16240_data_rdy_trig_poll,
- IRQF_TRIGGER_RISING,
- "adis16240",
- st->trig);
- if (ret)
- goto error_free_trig;
-
- st->trig->dev.parent = &st->us->dev;
- st->trig->ops = &adis16240_trigger_ops;
- st->trig->private_data = indio_dev;
- ret = iio_trigger_register(st->trig);
-
- /* select default trigger */
- indio_dev->trig = st->trig;
- if (ret)
- goto error_free_irq;
-
- return 0;
-
-error_free_irq:
- free_irq(st->us->irq, st->trig);
-error_free_trig:
- iio_trigger_free(st->trig);
-error_ret:
- return ret;
-}
-
-void adis16240_remove_trigger(struct iio_dev *indio_dev)
-{
- struct adis16240_state *st = iio_priv(indio_dev);
-
- iio_trigger_unregister(st->trig);
- free_irq(st->us->irq, st->trig);
- iio_trigger_free(st->trig);
-}
diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c
index fdd5fbded66..318331f08d9 100644
--- a/drivers/staging/iio/accel/kxsd9.c
+++ b/drivers/staging/iio/accel/kxsd9.c
@@ -171,7 +171,7 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev,
*val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK];
ret = IIO_VAL_INT_PLUS_MICRO;
break;
- };
+ }
error_ret:
return ret;
@@ -200,7 +200,7 @@ static const struct attribute_group kxsd9_attribute_group = {
.attrs = kxsd9_attributes,
};
-static int __devinit kxsd9_power_up(struct kxsd9_state *st)
+static int kxsd9_power_up(struct kxsd9_state *st)
{
int ret;
@@ -222,7 +222,7 @@ static const struct iio_info kxsd9_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit kxsd9_probe(struct spi_device *spi)
+static int kxsd9_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
struct kxsd9_state *st;
@@ -261,7 +261,7 @@ error_ret:
return ret;
}
-static int __devexit kxsd9_remove(struct spi_device *spi)
+static int kxsd9_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
@@ -281,7 +281,7 @@ static struct spi_driver kxsd9_driver = {
.owner = THIS_MODULE,
},
.probe = kxsd9_probe,
- .remove = __devexit_p(kxsd9_remove),
+ .remove = kxsd9_remove,
.id_table = kxsd9_id,
};
module_spi_driver(kxsd9_driver);
diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index f9bcd41f718..2bac7221837 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -158,6 +158,7 @@ struct lis3l02dq_state {
struct spi_device *us;
struct iio_trigger *trig;
struct mutex buf_lock;
+ int gpio;
bool trigger_on;
u8 tx[LIS3L02DQ_MAX_RX] ____cacheline_aligned;
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 21b0469f8bc..37ed1b8ebb6 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/gpio.h>
+#include <linux/of_gpio.h>
#include <linux/mutex.h>
#include <linux/device.h>
#include <linux/kernel.h>
@@ -674,7 +675,7 @@ static const struct iio_info lis3l02dq_info = {
.attrs = &lis3l02dq_attribute_group,
};
-static int __devinit lis3l02dq_probe(struct spi_device *spi)
+static int lis3l02dq_probe(struct spi_device *spi)
{
int ret;
struct lis3l02dq_state *st;
@@ -690,6 +691,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
spi_set_drvdata(spi, indio_dev);
st->us = spi;
+ st->gpio = of_get_gpio(spi->dev.of_node, 0);
mutex_init(&st->buf_lock);
indio_dev->name = spi->dev.driver->name;
indio_dev->dev.parent = &spi->dev;
@@ -711,7 +713,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
goto error_unreg_buffer_funcs;
}
- if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
+ if (spi->irq) {
ret = request_threaded_irq(st->us->irq,
&lis3l02dq_th,
&lis3l02dq_event_handler,
@@ -738,10 +740,10 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
return 0;
error_remove_trigger:
- if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)))
+ if (spi->irq)
lis3l02dq_remove_trigger(indio_dev);
error_free_interrupt:
- if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+ if (spi->irq)
free_irq(st->us->irq, indio_dev);
error_uninitialize_buffer:
iio_buffer_unregister(indio_dev);
@@ -780,7 +782,7 @@ err_ret:
}
/* fixme, confirm ordering in this function */
-static int __devexit lis3l02dq_remove(struct spi_device *spi)
+static int lis3l02dq_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct lis3l02dq_state *st = iio_priv(indio_dev);
@@ -790,7 +792,7 @@ static int __devexit lis3l02dq_remove(struct spi_device *spi)
lis3l02dq_disable_all_events(indio_dev);
lis3l02dq_stop_device(indio_dev);
- if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+ if (spi->irq)
free_irq(st->us->irq, indio_dev);
lis3l02dq_remove_trigger(indio_dev);
@@ -808,7 +810,7 @@ static struct spi_driver lis3l02dq_driver = {
.owner = THIS_MODULE,
},
.probe = lis3l02dq_probe,
- .remove = __devexit_p(lis3l02dq_remove),
+ .remove = lis3l02dq_remove,
};
module_spi_driver(lis3l02dq_driver);
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index fa4190d9624..bc38651c315 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -154,7 +154,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
= pf->timestamp;
- iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
+ iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data);
done:
@@ -237,7 +237,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
u8 t;
__lis3l02dq_write_data_ready_config(indio_dev, state);
- if (state == false) {
+ if (!state) {
/*
* A possible quirk with the handler is currently worked around
* by ensuring outstanding read events are cleared.
@@ -263,7 +263,7 @@ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
/* If gpio still high (or high again)
* In theory possible we will need to do this several times */
for (i = 0; i < 5; i++)
- if (gpio_get_value(irq_to_gpio(st->us->irq)))
+ if (gpio_get_value(st->gpio))
lis3l02dq_read_all(indio_dev, NULL);
else
break;
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index ffd1697a9db..414d3cad55a 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -1139,7 +1139,7 @@ static const struct iio_info sca3000_info_with_temp = {
.driver_module = THIS_MODULE,
};
-static int __devinit sca3000_probe(struct spi_device *spi)
+static int sca3000_probe(struct spi_device *spi)
{
int ret;
struct sca3000_state *st;
@@ -1233,7 +1233,7 @@ error_ret:
return ret;
}
-static int __devexit sca3000_remove(struct spi_device *spi)
+static int sca3000_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct sca3000_state *st = iio_priv(indio_dev);
@@ -1265,7 +1265,7 @@ static struct spi_driver sca3000_driver = {
.owner = THIS_MODULE,
},
.probe = sca3000_probe,
- .remove = __devexit_p(sca3000_remove),
+ .remove = sca3000_remove,
.id_table = sca3000_id,
};
module_spi_driver(sca3000_driver);
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index a525143ecbe..fb8c239b0c8 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -10,17 +10,6 @@ config AD7291
Say yes here to build support for Analog Devices AD7291
8 Channel ADC with temperature sensor.
-config AD7298
- tristate "Analog Devices AD7298 ADC driver"
- depends on SPI
- select IIO_TRIGGERED_BUFFER if IIO_BUFFER
- help
- Say yes here to build support for Analog Devices AD7298
- 8 Channel ADC with temperature sensor.
-
- To compile this driver as a module, choose M here: the
- module will be called ad7298.
-
config AD7606
tristate "Analog Devices AD7606 ADC driver"
depends on GPIOLIB
@@ -68,19 +57,6 @@ config AD799X_RING_BUFFER
Say yes here to include ring buffer support in the AD799X
ADC driver.
-config AD7887
- tristate "Analog Devices AD7887 ADC driver"
- depends on SPI
- select IIO_BUFFER
- select IIO_TRIGGERED_BUFFER
- help
- Say yes here to build support for Analog Devices
- AD7887 SPI analog to digital converter (ADC).
- If unsure, say N (but it's safe to say "Y").
-
- To compile this driver as a module, choose M here: the
- module will be called ad7887.
-
config AD7780
tristate "Analog Devices AD7780 and similar ADCs driver"
depends on SPI
@@ -94,18 +70,6 @@ config AD7780
To compile this driver as a module, choose M here: the
module will be called ad7780.
-config AD7793
- tristate "Analog Devices AD7793 and similar ADCs driver"
- depends on SPI
- select AD_SIGMA_DELTA
- help
- Say yes here to build support for Analog Devices AD7785, AD7792, AD7793,
- AD7794 and AD7795 SPI analog to digital converters (ADC).
- If unsure, say N (but it's safe to say "Y").
-
- To compile this driver as a module, choose M here: the
- module will be called AD7793.
-
config AD7816
tristate "Analog Devices AD7816/7/8 temperature sensor and ADC driver"
depends on SPI
@@ -126,18 +90,11 @@ config AD7192
To compile this driver as a module, choose M here: the
module will be called ad7192.
-config ADT7310
- tristate "Analog Devices ADT7310 temperature sensor driver"
- depends on SPI
- help
- Say yes here to build support for Analog Devices ADT7310
- temperature sensors.
-
config ADT7410
- tristate "Analog Devices ADT7410 temperature sensor driver"
- depends on I2C
+ tristate "Analog Devices ADT7310/ADT7410 temperature sensor driver"
+ depends on I2C || SPI_MASTER
help
- Say yes here to build support for Analog Devices ADT7410
+ Say yes here to build support for Analog Devices ADT7310/ADT7410
temperature sensors.
config AD7280
@@ -150,30 +107,6 @@ config AD7280
To compile this driver as a module, choose M here: the
module will be called ad7280a
-config MAX1363
- tristate "Maxim max1363 ADC driver"
- depends on I2C
- select IIO_TRIGGER if IIO_BUFFER
- select MAX1363_RING_BUFFER
- help
- Say yes here to build support for many Maxim i2c analog to digital
- converters (ADC). (max1361, max1362, max1363, max1364, max1036,
- max1037, max1038, max1039, max1136, max1136, max1137, max1138,
- max1139, max1236, max1237, max11238, max1239, max11600, max11601,
- max11602, max11603, max11604, max11605, max11606, max11607,
- max11608, max11609, max11610, max11611, max11612, max11613,
- max11614, max11615, max11616, max11617, max11644, max11645,
- max11646, max11647) Provides direct access via sysfs.
-
-config MAX1363_RING_BUFFER
- bool "Maxim max1363: use ring buffer"
- depends on MAX1363
- select IIO_BUFFER
- select IIO_SW_RING
- help
- Say yes here to include ring buffer support in the MAX1363
- ADC driver.
-
config LPC32XX_ADC
tristate "NXP LPC32XX ADC"
depends on ARCH_LPC32XX
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
index 62ee02e80cf..d285596272a 100644
--- a/drivers/staging/iio/adc/Makefile
+++ b/drivers/staging/iio/adc/Makefile
@@ -2,11 +2,6 @@
# Makefile for industrial I/O ADC drivers
#
-max1363-y := max1363_core.o
-max1363-y += max1363_ring.o
-
-obj-$(CONFIG_MAX1363) += max1363.o
-
ad7606-y := ad7606_core.o
ad7606-$(CONFIG_IIO_BUFFER) += ad7606_ring.o
ad7606-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o
@@ -17,20 +12,10 @@ ad799x-y := ad799x_core.o
ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o
obj-$(CONFIG_AD799X) += ad799x.o
-ad7887-y := ad7887_core.o
-ad7887-$(CONFIG_IIO_BUFFER) += ad7887_ring.o
-obj-$(CONFIG_AD7887) += ad7887.o
-
-ad7298-y := ad7298_core.o
-ad7298-$(CONFIG_IIO_BUFFER) += ad7298_ring.o
-obj-$(CONFIG_AD7298) += ad7298.o
-
obj-$(CONFIG_AD7291) += ad7291.o
obj-$(CONFIG_AD7780) += ad7780.o
-obj-$(CONFIG_AD7793) += ad7793.o
obj-$(CONFIG_AD7816) += ad7816.o
obj-$(CONFIG_AD7192) += ad7192.o
-obj-$(CONFIG_ADT7310) += adt7310.o
obj-$(CONFIG_ADT7410) += adt7410.o
obj-$(CONFIG_AD7280) += ad7280a.o
obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index aeaa61d49f5..50470194058 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -606,7 +606,7 @@ static const struct iio_chan_spec ad7192_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(8),
};
-static int __devinit ad7192_probe(struct spi_device *spi)
+static int ad7192_probe(struct spi_device *spi)
{
const struct ad7192_platform_data *pdata = spi->dev.platform_data;
struct ad7192_state *st;
@@ -686,7 +686,7 @@ error_put_reg:
return ret;
}
-static int __devexit ad7192_remove(struct spi_device *spi)
+static int ad7192_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ad7192_state *st = iio_priv(indio_dev);
@@ -716,7 +716,7 @@ static struct spi_driver ad7192_driver = {
.owner = THIS_MODULE,
},
.probe = ad7192_probe,
- .remove = __devexit_p(ad7192_remove),
+ .remove = ad7192_remove,
.id_table = ad7192_id,
};
module_spi_driver(ad7192_driver);
diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c
index cfc39a70312..fa81a491e79 100644
--- a/drivers/staging/iio/adc/ad7280a.c
+++ b/drivers/staging/iio/adc/ad7280a.c
@@ -117,7 +117,7 @@
*/
#define POLYNOM 0x2F
#define POLYNOM_ORDER 8
-#define HIGHBIT 1 << (POLYNOM_ORDER - 1);
+#define HIGHBIT (1 << (POLYNOM_ORDER - 1))
struct ad7280_state {
struct spi_device *spi;
@@ -832,7 +832,7 @@ static const struct ad7280_platform_data ad7793_default_pdata = {
.thermistor_term_en = true,
};
-static int __devinit ad7280_probe(struct spi_device *spi)
+static int ad7280_probe(struct spi_device *spi)
{
const struct ad7280_platform_data *pdata = spi->dev.platform_data;
struct ad7280_state *st;
@@ -950,7 +950,7 @@ error_free_device:
return ret;
}
-static int __devexit ad7280_remove(struct spi_device *spi)
+static int ad7280_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ad7280_state *st = iio_priv(indio_dev);
@@ -981,7 +981,7 @@ static struct spi_driver ad7280_driver = {
.owner = THIS_MODULE,
},
.probe = ad7280_probe,
- .remove = __devexit_p(ad7280_remove),
+ .remove = ad7280_remove,
.id_table = ad7280_id,
};
module_spi_driver(ad7280_driver);
diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c
index 029b39c0ba6..6e58e36d242 100644
--- a/drivers/staging/iio/adc/ad7291.c
+++ b/drivers/staging/iio/adc/ad7291.c
@@ -580,7 +580,7 @@ static const struct iio_info ad7291_info = {
.event_attrs = &ad7291_event_attribute_group,
};
-static int __devinit ad7291_probe(struct i2c_client *client,
+static int ad7291_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ad7291_chip_info *chip;
@@ -674,7 +674,7 @@ error_ret:
return ret;
}
-static int __devexit ad7291_remove(struct i2c_client *client)
+static int ad7291_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct ad7291_chip_info *chip = iio_priv(indio_dev);
@@ -706,7 +706,7 @@ static struct i2c_driver ad7291_driver = {
.name = KBUILD_MODNAME,
},
.probe = ad7291_probe,
- .remove = __devexit_p(ad7291_remove),
+ .remove = ad7291_remove,
.id_table = ad7291_id,
};
module_i2c_driver(ad7291_driver);
diff --git a/drivers/staging/iio/adc/ad7298.h b/drivers/staging/iio/adc/ad7298.h
deleted file mode 100644
index 18f27872300..00000000000
--- a/drivers/staging/iio/adc/ad7298.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * AD7298 SPI ADC driver
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#ifndef IIO_ADC_AD7298_H_
-#define IIO_ADC_AD7298_H_
-
-#define AD7298_WRITE (1 << 15) /* write to the control register */
-#define AD7298_REPEAT (1 << 14) /* repeated conversion enable */
-#define AD7298_CH(x) (1 << (13 - (x))) /* channel select */
-#define AD7298_TSENSE (1 << 5) /* temperature conversion enable */
-#define AD7298_EXTREF (1 << 2) /* external reference enable */
-#define AD7298_TAVG (1 << 1) /* temperature sensor averaging enable */
-#define AD7298_PDD (1 << 0) /* partial power down enable */
-
-#define AD7298_MAX_CHAN 8
-#define AD7298_BITS 12
-#define AD7298_STORAGE_BITS 16
-#define AD7298_INTREF_mV 2500
-
-#define AD7298_CH_TEMP 9
-
-#define RES_MASK(bits) ((1 << (bits)) - 1)
-
-/*
- * TODO: struct ad7298_platform_data needs to go into include/linux/iio
- */
-
-struct ad7298_platform_data {
- /* External Vref voltage applied */
- u16 vref_mv;
-};
-
-struct ad7298_state {
- struct spi_device *spi;
- struct regulator *reg;
- u16 int_vref_mv;
- unsigned ext_ref;
- struct spi_transfer ring_xfer[10];
- struct spi_transfer scan_single_xfer[3];
- struct spi_message ring_msg;
- struct spi_message scan_single_msg;
- /*
- * DMA (thus cache coherency maintenance) requires the
- * transfer buffers to live in their own cache lines.
- */
- unsigned short rx_buf[8] ____cacheline_aligned;
- unsigned short tx_buf[2];
-};
-
-#ifdef CONFIG_IIO_BUFFER
-int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev);
-void ad7298_ring_cleanup(struct iio_dev *indio_dev);
-int ad7298_update_scan_mode(struct iio_dev *indio_dev,
- const unsigned long *active_scan_mask);
-#else /* CONFIG_IIO_BUFFER */
-
-static inline int
-ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void ad7298_ring_cleanup(struct iio_dev *indio_dev)
-{
-}
-
-#define ad7298_update_scan_mode NULL
-
-#endif /* CONFIG_IIO_BUFFER */
-#endif /* IIO_ADC_AD7298_H_ */
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c
deleted file mode 100644
index c2906a85fed..00000000000
--- a/drivers/staging/iio/adc/ad7298_ring.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * AD7298 SPI ADC driver
- *
- * Copyright 2011-2012 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/spi/spi.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/buffer.h>
-#include <linux/iio/trigger_consumer.h>
-#include <linux/iio/triggered_buffer.h>
-
-#include "ad7298.h"
-
-/**
- * ad7298_update_scan_mode() setup the spi transfer buffer for the new scan mask
- **/
-int ad7298_update_scan_mode(struct iio_dev *indio_dev,
- const unsigned long *active_scan_mask)
-{
- struct ad7298_state *st = iio_priv(indio_dev);
- int i, m;
- unsigned short command;
- int scan_count;
-
- /* Now compute overall size */
- scan_count = bitmap_weight(active_scan_mask, indio_dev->masklength);
-
- command = AD7298_WRITE | st->ext_ref;
-
- for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1)
- if (test_bit(i, active_scan_mask))
- command |= m;
-
- st->tx_buf[0] = cpu_to_be16(command);
-
- /* build spi ring message */
- st->ring_xfer[0].tx_buf = &st->tx_buf[0];
- st->ring_xfer[0].len = 2;
- st->ring_xfer[0].cs_change = 1;
- st->ring_xfer[1].tx_buf = &st->tx_buf[1];
- st->ring_xfer[1].len = 2;
- st->ring_xfer[1].cs_change = 1;
-
- spi_message_init(&st->ring_msg);
- spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg);
- spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg);
-
- for (i = 0; i < scan_count; i++) {
- st->ring_xfer[i + 2].rx_buf = &st->rx_buf[i];
- st->ring_xfer[i + 2].len = 2;
- st->ring_xfer[i + 2].cs_change = 1;
- spi_message_add_tail(&st->ring_xfer[i + 2], &st->ring_msg);
- }
- /* make sure last transfer cs_change is not set */
- st->ring_xfer[i + 1].cs_change = 0;
-
- return 0;
-}
-
-/**
- * ad7298_trigger_handler() bh of trigger launched polling to ring buffer
- *
- * Currently there is no option in this driver to disable the saving of
- * timestamps within the ring.
- **/
-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;
- __u16 buf[16];
- int b_sent, i;
-
- 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 *)buf + indio_dev->scan_bytes - sizeof(s64),
- &time_ns, sizeof(time_ns));
- }
-
- for (i = 0; i < bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength); i++)
- buf[i] = be16_to_cpu(st->rx_buf[i]);
-
- iio_push_to_buffer(indio_dev->buffer, (u8 *)buf);
-
-done:
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return iio_triggered_buffer_setup(indio_dev, NULL,
- &ad7298_trigger_handler, NULL);
-}
-
-void ad7298_ring_cleanup(struct iio_dev *indio_dev)
-{
- iio_triggered_buffer_cleanup(indio_dev);
-}
diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/staging/iio/adc/ad7606_par.c
index a53faafec07..58cfddea963 100644
--- a/drivers/staging/iio/adc/ad7606_par.c
+++ b/drivers/staging/iio/adc/ad7606_par.c
@@ -47,7 +47,7 @@ static const struct ad7606_bus_ops ad7606_par8_bops = {
.read_block = ad7606_par8_read_block,
};
-static int __devinit ad7606_par_probe(struct platform_device *pdev)
+static int ad7606_par_probe(struct platform_device *pdev)
{
struct resource *res;
struct iio_dev *indio_dev;
@@ -100,7 +100,7 @@ out1:
return ret;
}
-static int __devexit ad7606_par_remove(struct platform_device *pdev)
+static int ad7606_par_remove(struct platform_device *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct resource *res;
@@ -164,7 +164,7 @@ MODULE_DEVICE_TABLE(platform, ad7606_driver_ids);
static struct platform_driver ad7606_driver = {
.probe = ad7606_par_probe,
- .remove = __devexit_p(ad7606_par_remove),
+ .remove = ad7606_par_remove,
.id_table = ad7606_driver_ids,
.driver = {
.name = "ad7606",
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index ba04d0ffd4f..2b25cb07fe4 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -83,7 +83,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
if (indio_dev->scan_timestamp)
*((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns;
- iio_push_to_buffer(indio_dev->buffer, buf);
+ iio_push_to_buffers(indio_dev, buf);
done:
gpio_set_value(st->pdata->gpio_convst, 0);
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/adc/ad7606_spi.c b/drivers/staging/iio/adc/ad7606_spi.c
index 099d347da52..6a8ecd73a1a 100644
--- a/drivers/staging/iio/adc/ad7606_spi.c
+++ b/drivers/staging/iio/adc/ad7606_spi.c
@@ -39,7 +39,7 @@ static const struct ad7606_bus_ops ad7606_spi_bops = {
.read_block = ad7606_spi_read_block,
};
-static int __devinit ad7606_spi_probe(struct spi_device *spi)
+static int ad7606_spi_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
@@ -55,7 +55,7 @@ static int __devinit ad7606_spi_probe(struct spi_device *spi)
return 0;
}
-static int __devexit ad7606_spi_remove(struct spi_device *spi)
+static int ad7606_spi_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = dev_get_drvdata(&spi->dev);
@@ -106,7 +106,7 @@ static struct spi_driver ad7606_driver = {
.pm = AD7606_SPI_PM_OPS,
},
.probe = ad7606_spi_probe,
- .remove = __devexit_p(ad7606_spi_remove),
+ .remove = ad7606_spi_remove,
.id_table = ad7606_id,
};
module_spi_driver(ad7606_driver);
diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c
index 0a1328b8657..e1f88603d7e 100644
--- a/drivers/staging/iio/adc/ad7780.c
+++ b/drivers/staging/iio/adc/ad7780.c
@@ -164,7 +164,7 @@ static const struct iio_info ad7780_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit ad7780_probe(struct spi_device *spi)
+static int ad7780_probe(struct spi_device *spi)
{
struct ad7780_platform_data *pdata = spi->dev.platform_data;
struct ad7780_state *st;
@@ -248,7 +248,7 @@ error_put_reg:
return ret;
}
-static int __devexit ad7780_remove(struct spi_device *spi)
+static int ad7780_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ad7780_state *st = iio_priv(indio_dev);
@@ -283,7 +283,7 @@ static struct spi_driver ad7780_driver = {
.owner = THIS_MODULE,
},
.probe = ad7780_probe,
- .remove = __devexit_p(ad7780_remove),
+ .remove = ad7780_remove,
.id_table = ad7780_id,
};
module_spi_driver(ad7780_driver);
diff --git a/drivers/staging/iio/adc/ad7793.h b/drivers/staging/iio/adc/ad7793.h
deleted file mode 100644
index 8fdd450a2cd..00000000000
--- a/drivers/staging/iio/adc/ad7793.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * AD7792/AD7793 SPI ADC driver
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-#ifndef IIO_ADC_AD7793_H_
-#define IIO_ADC_AD7793_H_
-
-/*
- * TODO: struct ad7793_platform_data needs to go into include/linux/iio
- */
-
-/* Registers */
-#define AD7793_REG_COMM 0 /* Communications Register (WO, 8-bit) */
-#define AD7793_REG_STAT 0 /* Status Register (RO, 8-bit) */
-#define AD7793_REG_MODE 1 /* Mode Register (RW, 16-bit */
-#define AD7793_REG_CONF 2 /* Configuration Register (RW, 16-bit) */
-#define AD7793_REG_DATA 3 /* Data Register (RO, 16-/24-bit) */
-#define AD7793_REG_ID 4 /* ID Register (RO, 8-bit) */
-#define AD7793_REG_IO 5 /* IO Register (RO, 8-bit) */
-#define AD7793_REG_OFFSET 6 /* Offset Register (RW, 16-bit
- * (AD7792)/24-bit (AD7793)) */
-#define AD7793_REG_FULLSALE 7 /* Full-Scale Register
- * (RW, 16-bit (AD7792)/24-bit (AD7793)) */
-
-/* Communications Register Bit Designations (AD7793_REG_COMM) */
-#define AD7793_COMM_WEN (1 << 7) /* Write Enable */
-#define AD7793_COMM_WRITE (0 << 6) /* Write Operation */
-#define AD7793_COMM_READ (1 << 6) /* Read Operation */
-#define AD7793_COMM_ADDR(x) (((x) & 0x7) << 3) /* Register Address */
-#define AD7793_COMM_CREAD (1 << 2) /* Continuous Read of Data Register */
-
-/* Status Register Bit Designations (AD7793_REG_STAT) */
-#define AD7793_STAT_RDY (1 << 7) /* Ready */
-#define AD7793_STAT_ERR (1 << 6) /* Error (Overrange, Underrange) */
-#define AD7793_STAT_CH3 (1 << 2) /* Channel 3 */
-#define AD7793_STAT_CH2 (1 << 1) /* Channel 2 */
-#define AD7793_STAT_CH1 (1 << 0) /* Channel 1 */
-
-/* Mode Register Bit Designations (AD7793_REG_MODE) */
-#define AD7793_MODE_SEL(x) (((x) & 0x7) << 13) /* Operation Mode Select */
-#define AD7793_MODE_SEL_MASK (0x7 << 13) /* Operation Mode Select mask */
-#define AD7793_MODE_CLKSRC(x) (((x) & 0x3) << 6) /* ADC Clock Source Select */
-#define AD7793_MODE_RATE(x) ((x) & 0xF) /* Filter Update Rate Select */
-
-#define AD7793_MODE_CONT 0 /* Continuous Conversion Mode */
-#define AD7793_MODE_SINGLE 1 /* Single Conversion Mode */
-#define AD7793_MODE_IDLE 2 /* Idle Mode */
-#define AD7793_MODE_PWRDN 3 /* Power-Down Mode */
-#define AD7793_MODE_CAL_INT_ZERO 4 /* Internal Zero-Scale Calibration */
-#define AD7793_MODE_CAL_INT_FULL 5 /* Internal Full-Scale Calibration */
-#define AD7793_MODE_CAL_SYS_ZERO 6 /* System Zero-Scale Calibration */
-#define AD7793_MODE_CAL_SYS_FULL 7 /* System Full-Scale Calibration */
-
-#define AD7793_CLK_INT 0 /* Internal 64 kHz Clock not
- * available at the CLK pin */
-#define AD7793_CLK_INT_CO 1 /* Internal 64 kHz Clock available
- * at the CLK pin */
-#define AD7793_CLK_EXT 2 /* External 64 kHz Clock */
-#define AD7793_CLK_EXT_DIV2 3 /* External Clock divided by 2 */
-
-/* Configuration Register Bit Designations (AD7793_REG_CONF) */
-#define AD7793_CONF_VBIAS(x) (((x) & 0x3) << 14) /* Bias Voltage
- * Generator Enable */
-#define AD7793_CONF_BO_EN (1 << 13) /* Burnout Current Enable */
-#define AD7793_CONF_UNIPOLAR (1 << 12) /* Unipolar/Bipolar Enable */
-#define AD7793_CONF_BOOST (1 << 11) /* Boost Enable */
-#define AD7793_CONF_GAIN(x) (((x) & 0x7) << 8) /* Gain Select */
-#define AD7793_CONF_REFSEL (1 << 7) /* INT/EXT Reference Select */
-#define AD7793_CONF_BUF (1 << 4) /* Buffered Mode Enable */
-#define AD7793_CONF_CHAN(x) ((x) & 0xf) /* Channel select */
-#define AD7793_CONF_CHAN_MASK 0xf /* Channel select mask */
-
-#define AD7793_CH_AIN1P_AIN1M 0 /* AIN1(+) - AIN1(-) */
-#define AD7793_CH_AIN2P_AIN2M 1 /* AIN2(+) - AIN2(-) */
-#define AD7793_CH_AIN3P_AIN3M 2 /* AIN3(+) - AIN3(-) */
-#define AD7793_CH_AIN1M_AIN1M 3 /* AIN1(-) - AIN1(-) */
-#define AD7793_CH_TEMP 6 /* Temp Sensor */
-#define AD7793_CH_AVDD_MONITOR 7 /* AVDD Monitor */
-
-#define AD7795_CH_AIN4P_AIN4M 4 /* AIN4(+) - AIN4(-) */
-#define AD7795_CH_AIN5P_AIN5M 5 /* AIN5(+) - AIN5(-) */
-#define AD7795_CH_AIN6P_AIN6M 6 /* AIN6(+) - AIN6(-) */
-#define AD7795_CH_AIN1M_AIN1M 8 /* AIN1(-) - AIN1(-) */
-
-/* ID Register Bit Designations (AD7793_REG_ID) */
-#define AD7792_ID 0xA
-#define AD7793_ID 0xB
-#define AD7795_ID 0xF
-#define AD7793_ID_MASK 0xF
-
-/* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */
-#define AD7793_IO_IEXC1_IOUT1_IEXC2_IOUT2 0 /* IEXC1 connect to IOUT1,
- * IEXC2 connect to IOUT2 */
-#define AD7793_IO_IEXC1_IOUT2_IEXC2_IOUT1 1 /* IEXC1 connect to IOUT2,
- * IEXC2 connect to IOUT1 */
-#define AD7793_IO_IEXC1_IEXC2_IOUT1 2 /* Both current sources
- * IEXC1,2 connect to IOUT1 */
-#define AD7793_IO_IEXC1_IEXC2_IOUT2 3 /* Both current sources
- * IEXC1,2 connect to IOUT2 */
-
-#define AD7793_IO_IXCEN_10uA (1 << 0) /* Excitation Current 10uA */
-#define AD7793_IO_IXCEN_210uA (2 << 0) /* Excitation Current 210uA */
-#define AD7793_IO_IXCEN_1mA (3 << 0) /* Excitation Current 1mA */
-
-struct ad7793_platform_data {
- u16 vref_mv;
- u16 mode;
- u16 conf;
- u8 io;
-};
-
-#endif /* IIO_ADC_AD7793_H_ */
diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index c5fb9476a2d..928477146c2 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -341,7 +341,7 @@ static const struct iio_info ad7816_info = {
* device probe and remove
*/
-static int __devinit ad7816_probe(struct spi_device *spi_dev)
+static int ad7816_probe(struct spi_device *spi_dev)
{
struct ad7816_chip_info *chip;
struct iio_dev *indio_dev;
@@ -431,7 +431,7 @@ error_ret:
return ret;
}
-static int __devexit ad7816_remove(struct spi_device *spi_dev)
+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);
@@ -463,7 +463,7 @@ static struct spi_driver ad7816_driver = {
.owner = THIS_MODULE,
},
.probe = ad7816_probe,
- .remove = __devexit_p(ad7816_remove),
+ .remove = ad7816_remove,
.id_table = ad7816_id,
};
module_spi_driver(ad7816_driver);
diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h
deleted file mode 100644
index 2e09e54fc9c..00000000000
--- a/drivers/staging/iio/adc/ad7887.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * AD7887 SPI ADC driver
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-#ifndef IIO_ADC_AD7887_H_
-#define IIO_ADC_AD7887_H_
-
-#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */
-#define AD7887_DUAL (1 << 4) /* dual-channel mode */
-#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */
-#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */
-#define AD7887_PM_MODE1 (0) /* CS based shutdown */
-#define AD7887_PM_MODE2 (1) /* full on */
-#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */
-#define AD7887_PM_MODE4 (3) /* standby mode */
-
-enum ad7887_channels {
- AD7887_CH0,
- AD7887_CH0_CH1,
- AD7887_CH1,
-};
-
-#define RES_MASK(bits) ((1 << (bits)) - 1) /* TODO: move this into a common header */
-
-/*
- * TODO: struct ad7887_platform_data needs to go into include/linux/iio
- */
-
-struct ad7887_platform_data {
- /* External Vref voltage applied */
- u16 vref_mv;
- /*
- * AD7887:
- * In single channel mode en_dual = flase, AIN1/Vref pins assumes its
- * Vref function. In dual channel mode en_dual = true, AIN1 becomes the
- * second input channel, and Vref is internally connected to Vdd.
- */
- bool en_dual;
- /*
- * AD7887:
- * use_onchip_ref = true, the Vref is internally connected to the 2.500V
- * Voltage reference. If use_onchip_ref = false, the reference voltage
- * is supplied by AIN1/Vref
- */
- bool use_onchip_ref;
-};
-
-/**
- * struct ad7887_chip_info - chip specifc information
- * @int_vref_mv: the internal reference voltage
- * @channel: channel specification
- */
-
-struct ad7887_chip_info {
- u16 int_vref_mv;
- struct iio_chan_spec channel[3];
-};
-
-struct ad7887_state {
- struct spi_device *spi;
- const struct ad7887_chip_info *chip_info;
- struct regulator *reg;
- u16 int_vref_mv;
- struct spi_transfer xfer[4];
- struct spi_message msg[3];
- struct spi_message *ring_msg;
- unsigned char tx_cmd_buf[8];
-
- /*
- * DMA (thus cache coherency maintenance) requires the
- * transfer buffers to live in their own cache lines.
- */
-
- unsigned char data[4] ____cacheline_aligned;
-};
-
-enum ad7887_supported_device_ids {
- ID_AD7887
-};
-
-#ifdef CONFIG_IIO_BUFFER
-int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev);
-void ad7887_ring_cleanup(struct iio_dev *indio_dev);
-#else /* CONFIG_IIO_BUFFER */
-
-static inline int
-ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void ad7887_ring_cleanup(struct iio_dev *indio_dev)
-{
-}
-#endif /* CONFIG_IIO_BUFFER */
-#endif /* IIO_ADC_AD7887_H_ */
diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c
deleted file mode 100644
index b39923bbeed..00000000000
--- a/drivers/staging/iio/adc/ad7887_ring.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2010-2012 Analog Devices Inc.
- * Copyright (C) 2008 Jonathan Cameron
- *
- * Licensed under the GPL-2.
- *
- * ad7887_ring.c
- */
-
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/spi/spi.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/buffer.h>
-#include <linux/iio/trigger_consumer.h>
-#include <linux/iio/triggered_buffer.h>
-
-#include "ad7887.h"
-
-/**
- * ad7887_ring_preenable() setup the parameters of the ring before enabling
- *
- * The complex nature of the setting of the nuber of bytes per datum is due
- * to this driver currently ensuring that the timestamp is stored at an 8
- * byte boundary.
- **/
-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) {
- case (1 << 0):
- st->ring_msg = &st->msg[AD7887_CH0];
- break;
- case (1 << 1):
- st->ring_msg = &st->msg[AD7887_CH1];
- /* Dummy read: push CH1 setting down to hardware */
- spi_sync(st->spi, st->ring_msg);
- break;
- case ((1 << 1) | (1 << 0)):
- st->ring_msg = &st->msg[AD7887_CH0_CH1];
- break;
- }
-
- return 0;
-}
-
-static int ad7887_ring_postdisable(struct iio_dev *indio_dev)
-{
- struct ad7887_state *st = iio_priv(indio_dev);
-
- /* dummy read: restore default CH0 settin */
- return spi_sync(st->spi, &st->msg[AD7887_CH0]);
-}
-
-/**
- * ad7887_trigger_handler() bh of trigger launched polling to ring buffer
- *
- * Currently there is no option in this driver to disable the saving of
- * timestamps within the ring.
- **/
-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;
- __u8 *buf;
- int b_sent;
-
- unsigned int bytes = bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength) *
- st->chip_info->channel[0].scan_type.storagebits / 8;
-
- buf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
- if (buf == NULL)
- goto done;
-
- b_sent = spi_sync(st->spi, st->ring_msg);
- if (b_sent)
- goto done;
-
- time_ns = iio_get_time_ns();
-
- memcpy(buf, st->data, bytes);
- if (indio_dev->scan_timestamp)
- memcpy(buf + indio_dev->scan_bytes - sizeof(s64),
- &time_ns, sizeof(time_ns));
-
- iio_push_to_buffer(indio_dev->buffer, buf);
-done:
- kfree(buf);
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-static const struct iio_buffer_setup_ops ad7887_ring_setup_ops = {
- .preenable = &ad7887_ring_preenable,
- .postenable = &iio_triggered_buffer_postenable,
- .predisable = &iio_triggered_buffer_predisable,
- .postdisable = &ad7887_ring_postdisable,
-};
-
-int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
- &ad7887_trigger_handler, &ad7887_ring_setup_ops);
-}
-
-void ad7887_ring_cleanup(struct iio_dev *indio_dev)
-{
- iio_triggered_buffer_cleanup(indio_dev);
-}
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c
index 990050700af..077eedbd0a0 100644
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -854,7 +854,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
},
};
-static int __devinit ad799x_probe(struct i2c_client *client,
+static int ad799x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret;
@@ -932,7 +932,7 @@ error_put_reg:
return ret;
}
-static __devexit int ad799x_remove(struct i2c_client *client)
+static int ad799x_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct ad799x_state *st = iio_priv(indio_dev);
@@ -970,7 +970,7 @@ static struct i2c_driver ad799x_driver = {
.name = "ad799x",
},
.probe = ad799x_probe,
- .remove = __devexit_p(ad799x_remove),
+ .remove = ad799x_remove,
.id_table = ad799x_id,
};
module_i2c_driver(ad799x_driver);
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index 86026d9b20b..2c5f38475a8 100644
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ b/drivers/staging/iio/adc/ad799x_ring.c
@@ -77,7 +77,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64),
&time_ns, sizeof(time_ns));
- iio_push_to_buffer(indio_dev->buffer, rxbuf);
+ iio_push_to_buffers(indio_dev, rxbuf);
done:
kfree(rxbuf);
out:
diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c
deleted file mode 100644
index 72460b6dc2f..00000000000
--- a/drivers/staging/iio/adc/adt7310.c
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * ADT7310 digital temperature sensor driver supporting ADT7310
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-#include <linux/spi/spi.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/events.h>
-/*
- * ADT7310 registers definition
- */
-
-#define ADT7310_STATUS 0
-#define ADT7310_CONFIG 1
-#define ADT7310_TEMPERATURE 2
-#define ADT7310_ID 3
-#define ADT7310_T_CRIT 4
-#define ADT7310_T_HYST 5
-#define ADT7310_T_ALARM_HIGH 6
-#define ADT7310_T_ALARM_LOW 7
-
-/*
- * ADT7310 status
- */
-#define ADT7310_STAT_T_LOW 0x10
-#define ADT7310_STAT_T_HIGH 0x20
-#define ADT7310_STAT_T_CRIT 0x40
-#define ADT7310_STAT_NOT_RDY 0x80
-
-/*
- * ADT7310 config
- */
-#define ADT7310_FAULT_QUEUE_MASK 0x3
-#define ADT7310_CT_POLARITY 0x4
-#define ADT7310_INT_POLARITY 0x8
-#define ADT7310_EVENT_MODE 0x10
-#define ADT7310_MODE_MASK 0x60
-#define ADT7310_ONESHOT 0x20
-#define ADT7310_SPS 0x40
-#define ADT7310_PD 0x60
-#define ADT7310_RESOLUTION 0x80
-
-/*
- * ADT7310 masks
- */
-#define ADT7310_T16_VALUE_SIGN 0x8000
-#define ADT7310_T16_VALUE_FLOAT_OFFSET 7
-#define ADT7310_T16_VALUE_FLOAT_MASK 0x7F
-#define ADT7310_T13_VALUE_SIGN 0x1000
-#define ADT7310_T13_VALUE_OFFSET 3
-#define ADT7310_T13_VALUE_FLOAT_OFFSET 4
-#define ADT7310_T13_VALUE_FLOAT_MASK 0xF
-#define ADT7310_T_HYST_MASK 0xF
-#define ADT7310_DEVICE_ID_MASK 0x7
-#define ADT7310_MANUFACTORY_ID_MASK 0xF8
-#define ADT7310_MANUFACTORY_ID_OFFSET 3
-
-
-#define ADT7310_CMD_REG_MASK 0x28
-#define ADT7310_CMD_REG_OFFSET 3
-#define ADT7310_CMD_READ 0x40
-#define ADT7310_CMD_CON_READ 0x4
-
-#define ADT7310_IRQS 2
-
-/*
- * struct adt7310_chip_info - chip specifc information
- */
-
-struct adt7310_chip_info {
- struct spi_device *spi_dev;
- u8 config;
-};
-
-/*
- * adt7310 register access by SPI
- */
-
-static int adt7310_spi_read_word(struct adt7310_chip_info *chip, u8 reg, u16 *data)
-{
- struct spi_device *spi_dev = chip->spi_dev;
- u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
- int ret = 0;
-
- command |= ADT7310_CMD_READ;
- ret = spi_write(spi_dev, &command, sizeof(command));
- if (ret < 0) {
- dev_err(&spi_dev->dev, "SPI write command error\n");
- return ret;
- }
-
- ret = spi_read(spi_dev, (u8 *)data, sizeof(*data));
- if (ret < 0) {
- dev_err(&spi_dev->dev, "SPI read word error\n");
- return ret;
- }
-
- *data = be16_to_cpu(*data);
-
- return 0;
-}
-
-static int adt7310_spi_write_word(struct adt7310_chip_info *chip, u8 reg, u16 data)
-{
- struct spi_device *spi_dev = chip->spi_dev;
- u8 buf[3];
- int ret = 0;
-
- buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
- buf[1] = (u8)(data >> 8);
- buf[2] = (u8)(data & 0xFF);
-
- ret = spi_write(spi_dev, buf, 3);
- if (ret < 0) {
- dev_err(&spi_dev->dev, "SPI write word error\n");
- return ret;
- }
-
- return ret;
-}
-
-static int adt7310_spi_read_byte(struct adt7310_chip_info *chip, u8 reg, u8 *data)
-{
- struct spi_device *spi_dev = chip->spi_dev;
- u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
- int ret = 0;
-
- command |= ADT7310_CMD_READ;
- ret = spi_write(spi_dev, &command, sizeof(command));
- if (ret < 0) {
- dev_err(&spi_dev->dev, "SPI write command error\n");
- return ret;
- }
-
- ret = spi_read(spi_dev, data, sizeof(*data));
- if (ret < 0) {
- dev_err(&spi_dev->dev, "SPI read byte error\n");
- return ret;
- }
-
- return 0;
-}
-
-static int adt7310_spi_write_byte(struct adt7310_chip_info *chip, u8 reg, u8 data)
-{
- struct spi_device *spi_dev = chip->spi_dev;
- u8 buf[2];
- int ret = 0;
-
- buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
- buf[1] = data;
-
- ret = spi_write(spi_dev, buf, 2);
- if (ret < 0) {
- dev_err(&spi_dev->dev, "SPI write byte error\n");
- return ret;
- }
-
- return ret;
-}
-
-static ssize_t adt7310_show_mode(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7310_chip_info *chip = iio_priv(dev_info);
- u8 config;
-
- config = chip->config & ADT7310_MODE_MASK;
-
- switch (config) {
- case ADT7310_PD:
- return sprintf(buf, "power-down\n");
- case ADT7310_ONESHOT:
- return sprintf(buf, "one-shot\n");
- case ADT7310_SPS:
- return sprintf(buf, "sps\n");
- default:
- return sprintf(buf, "full\n");
- }
-}
-
-static ssize_t adt7310_store_mode(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7310_chip_info *chip = iio_priv(dev_info);
- u16 config;
- int ret;
-
- ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
- if (ret)
- return -EIO;
-
- config = chip->config & (~ADT7310_MODE_MASK);
- if (strcmp(buf, "power-down"))
- config |= ADT7310_PD;
- else if (strcmp(buf, "one-shot"))
- config |= ADT7310_ONESHOT;
- else if (strcmp(buf, "sps"))
- config |= ADT7310_SPS;
-
- ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
- if (ret)
- return -EIO;
-
- chip->config = config;
-
- return len;
-}
-
-static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
- adt7310_show_mode,
- adt7310_store_mode,
- 0);
-
-static ssize_t adt7310_show_available_modes(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return sprintf(buf, "full\none-shot\nsps\npower-down\n");
-}
-
-static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7310_show_available_modes, NULL, 0);
-
-static ssize_t adt7310_show_resolution(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7310_chip_info *chip = iio_priv(dev_info);
- int ret;
- int bits;
-
- ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
- if (ret)
- return -EIO;
-
- if (chip->config & ADT7310_RESOLUTION)
- bits = 16;
- else
- bits = 13;
-
- return sprintf(buf, "%d bits\n", bits);
-}
-
-static ssize_t adt7310_store_resolution(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7310_chip_info *chip = iio_priv(dev_info);
- unsigned long data;
- u16 config;
- int ret;
-
- ret = strict_strtoul(buf, 10, &data);
- if (ret)
- return -EINVAL;
-
- ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
- if (ret)
- return -EIO;
-
- config = chip->config & (~ADT7310_RESOLUTION);
- if (data)
- config |= ADT7310_RESOLUTION;
-
- ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
- if (ret)
- return -EIO;
-
- chip->config = config;
-
- return len;
-}
-
-static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR,
- adt7310_show_resolution,
- adt7310_store_resolution,
- 0);
-
-static ssize_t adt7310_show_id(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7310_chip_info *chip = iio_priv(dev_info);
- u8 id;
- int ret;
-
- ret = adt7310_spi_read_byte(chip, ADT7310_ID, &id);
- if (ret)
- return -EIO;
-
- return sprintf(buf, "device id: 0x%x\nmanufactory id: 0x%x\n",
- id & ADT7310_DEVICE_ID_MASK,
- (id & ADT7310_MANUFACTORY_ID_MASK) >> ADT7310_MANUFACTORY_ID_OFFSET);
-}
-
-static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR,
- adt7310_show_id,
- NULL,
- 0);
-
-static ssize_t adt7310_convert_temperature(struct adt7310_chip_info *chip,
- u16 data, char *buf)
-{
- char sign = ' ';
-
- if (chip->config & ADT7310_RESOLUTION) {
- if (data & ADT7310_T16_VALUE_SIGN) {
- /* convert supplement to positive value */
- data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data);
- sign = '-';
- }
- return sprintf(buf, "%c%d.%.7d\n", sign,
- (data >> ADT7310_T16_VALUE_FLOAT_OFFSET),
- (data & ADT7310_T16_VALUE_FLOAT_MASK) * 78125);
- } else {
- if (data & ADT7310_T13_VALUE_SIGN) {
- /* convert supplement to positive value */
- data >>= ADT7310_T13_VALUE_OFFSET;
- data = (ADT7310_T13_VALUE_SIGN << 1) - data;
- sign = '-';
- }
- return sprintf(buf, "%c%d.%.4d\n", sign,
- (data >> ADT7310_T13_VALUE_FLOAT_OFFSET),
- (data & ADT7310_T13_VALUE_FLOAT_MASK) * 625);
- }
-}
-
-static ssize_t adt7310_show_value(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7310_chip_info *chip = iio_priv(dev_info);
- u8 status;
- u16 data;
- int ret, i = 0;
-
- do {
- ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status);
- if (ret)
- return -EIO;
- i++;
- if (i == 10000)
- return -EIO;
- } while (status & ADT7310_STAT_NOT_RDY);
-
- ret = adt7310_spi_read_word(chip, ADT7310_TEMPERATURE, &data);
- if (ret)
- return -EIO;
-
- return adt7310_convert_temperature(chip, data, buf);
-}
-
-static IIO_DEVICE_ATTR(value, S_IRUGO, adt7310_show_value, NULL, 0);
-
-static struct attribute *adt7310_attributes[] = {
- &iio_dev_attr_available_modes.dev_attr.attr,
- &iio_dev_attr_mode.dev_attr.attr,
- &iio_dev_attr_resolution.dev_attr.attr,
- &iio_dev_attr_id.dev_attr.attr,
- &iio_dev_attr_value.dev_attr.attr,
- NULL,
-};
-
-static const struct attribute_group adt7310_attribute_group = {
- .attrs = adt7310_attributes,
-};
-
-static irqreturn_t adt7310_event_handler(int irq, void *private)
-{
- struct iio_dev *indio_dev = private;
- struct adt7310_chip_info *chip = iio_priv(indio_dev);
- s64 timestamp = iio_get_time_ns();
- u8 status;
- int ret;
-
- ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status);
- if (ret)
- goto done;
-
- if (status & ADT7310_STAT_T_HIGH)
- iio_push_event(indio_dev,
- IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
- IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_RISING),
- timestamp);
- if (status & ADT7310_STAT_T_LOW)
- iio_push_event(indio_dev,
- IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
- IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_FALLING),
- timestamp);
- if (status & ADT7310_STAT_T_CRIT)
- iio_push_event(indio_dev,
- IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
- IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_RISING),
- timestamp);
-
-done:
- return IRQ_HANDLED;
-}
-
-static ssize_t adt7310_show_event_mode(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7310_chip_info *chip = iio_priv(dev_info);
- int ret;
-
- ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
- if (ret)
- return -EIO;
-
- if (chip->config & ADT7310_EVENT_MODE)
- return sprintf(buf, "interrupt\n");
- else
- return sprintf(buf, "comparator\n");
-}
-
-static ssize_t adt7310_set_event_mode(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7310_chip_info *chip = iio_priv(dev_info);
- u16 config;
- int ret;
-
- ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
- if (ret)
- return -EIO;
-
- config = chip->config &= ~ADT7310_EVENT_MODE;
- if (strcmp(buf, "comparator") != 0)
- config |= ADT7310_EVENT_MODE;
-
- ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
- if (ret)
- return -EIO;
-
- chip->config = config;
-
- return len;
-}
-
-static ssize_t adt7310_show_available_event_modes(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return sprintf(buf, "comparator\ninterrupt\n");
-}
-
-static ssize_t adt7310_show_fault_queue(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7310_chip_info *chip = iio_priv(dev_info);
- int ret;
-
- ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
- if (ret)
- return -EIO;
-
- return sprintf(buf, "%d\n", chip->config & ADT7310_FAULT_QUEUE_MASK);
-}
-
-static ssize_t adt7310_set_fault_queue(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7310_chip_info *chip = iio_priv(dev_info);
- unsigned long data;
- int ret;
- u8 config;
-
- ret = strict_strtoul(buf, 10, &data);
- if (ret || data > 3)
- return -EINVAL;
-
- ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
- if (ret)
- return -EIO;
-
- config = chip->config & ~ADT7310_FAULT_QUEUE_MASK;
- config |= data;
- ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
- if (ret)
- return -EIO;
-
- chip->config = config;
-
- return len;
-}
-
-static inline ssize_t adt7310_show_t_bound(struct device *dev,
- struct device_attribute *attr,
- u8 bound_reg,
- char *buf)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7310_chip_info *chip = iio_priv(dev_info);
- u16 data;
- int ret;
-
- ret = adt7310_spi_read_word(chip, bound_reg, &data);
- if (ret)
- return -EIO;
-
- return adt7310_convert_temperature(chip, data, buf);
-}
-
-static inline ssize_t adt7310_set_t_bound(struct device *dev,
- struct device_attribute *attr,
- u8 bound_reg,
- const char *buf,
- size_t len)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7310_chip_info *chip = iio_priv(dev_info);
- long tmp1, tmp2;
- u16 data;
- char *pos;
- int ret;
-
- pos = strchr(buf, '.');
-
- ret = strict_strtol(buf, 10, &tmp1);
-
- if (ret || tmp1 > 127 || tmp1 < -128)
- return -EINVAL;
-
- if (pos) {
- len = strlen(pos);
-
- if (chip->config & ADT7310_RESOLUTION) {
- if (len > ADT7310_T16_VALUE_FLOAT_OFFSET)
- len = ADT7310_T16_VALUE_FLOAT_OFFSET;
- pos[len] = 0;
- ret = strict_strtol(pos, 10, &tmp2);
-
- if (!ret)
- tmp2 = (tmp2 / 78125) * 78125;
- } else {
- if (len > ADT7310_T13_VALUE_FLOAT_OFFSET)
- len = ADT7310_T13_VALUE_FLOAT_OFFSET;
- pos[len] = 0;
- ret = strict_strtol(pos, 10, &tmp2);
-
- if (!ret)
- tmp2 = (tmp2 / 625) * 625;
- }
- }
-
- if (tmp1 < 0)
- data = (u16)(-tmp1);
- else
- data = (u16)tmp1;
-
- if (chip->config & ADT7310_RESOLUTION) {
- data = (data << ADT7310_T16_VALUE_FLOAT_OFFSET) |
- (tmp2 & ADT7310_T16_VALUE_FLOAT_MASK);
-
- if (tmp1 < 0)
- /* convert positive value to supplyment */
- data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data);
- } else {
- data = (data << ADT7310_T13_VALUE_FLOAT_OFFSET) |
- (tmp2 & ADT7310_T13_VALUE_FLOAT_MASK);
-
- if (tmp1 < 0)
- /* convert positive value to supplyment */
- data = (ADT7310_T13_VALUE_SIGN << 1) - data;
- data <<= ADT7310_T13_VALUE_OFFSET;
- }
-
- ret = adt7310_spi_write_word(chip, bound_reg, data);
- if (ret)
- return -EIO;
-
- return len;
-}
-
-static ssize_t adt7310_show_t_alarm_high(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return adt7310_show_t_bound(dev, attr,
- ADT7310_T_ALARM_HIGH, buf);
-}
-
-static inline ssize_t adt7310_set_t_alarm_high(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- return adt7310_set_t_bound(dev, attr,
- ADT7310_T_ALARM_HIGH, buf, len);
-}
-
-static ssize_t adt7310_show_t_alarm_low(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return adt7310_show_t_bound(dev, attr,
- ADT7310_T_ALARM_LOW, buf);
-}
-
-static inline ssize_t adt7310_set_t_alarm_low(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- return adt7310_set_t_bound(dev, attr,
- ADT7310_T_ALARM_LOW, buf, len);
-}
-
-static ssize_t adt7310_show_t_crit(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return adt7310_show_t_bound(dev, attr,
- ADT7310_T_CRIT, buf);
-}
-
-static inline ssize_t adt7310_set_t_crit(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- return adt7310_set_t_bound(dev, attr,
- ADT7310_T_CRIT, buf, len);
-}
-
-static ssize_t adt7310_show_t_hyst(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7310_chip_info *chip = iio_priv(dev_info);
- int ret;
- u8 t_hyst;
-
- ret = adt7310_spi_read_byte(chip, ADT7310_T_HYST, &t_hyst);
- if (ret)
- return -EIO;
-
- return sprintf(buf, "%d\n", t_hyst & ADT7310_T_HYST_MASK);
-}
-
-static inline ssize_t adt7310_set_t_hyst(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7310_chip_info *chip = iio_priv(dev_info);
- int ret;
- unsigned long data;
- u8 t_hyst;
-
- ret = strict_strtol(buf, 10, &data);
-
- if (ret || data > ADT7310_T_HYST_MASK)
- return -EINVAL;
-
- t_hyst = (u8)data;
-
- ret = adt7310_spi_write_byte(chip, ADT7310_T_HYST, t_hyst);
- if (ret)
- return -EIO;
-
- return len;
-}
-
-static IIO_DEVICE_ATTR(event_mode,
- S_IRUGO | S_IWUSR,
- adt7310_show_event_mode, adt7310_set_event_mode, 0);
-static IIO_DEVICE_ATTR(available_event_modes,
- S_IRUGO | S_IWUSR,
- adt7310_show_available_event_modes, NULL, 0);
-static IIO_DEVICE_ATTR(fault_queue,
- S_IRUGO | S_IWUSR,
- adt7310_show_fault_queue, adt7310_set_fault_queue, 0);
-static IIO_DEVICE_ATTR(t_alarm_high,
- S_IRUGO | S_IWUSR,
- adt7310_show_t_alarm_high, adt7310_set_t_alarm_high, 0);
-static IIO_DEVICE_ATTR(t_alarm_low,
- S_IRUGO | S_IWUSR,
- adt7310_show_t_alarm_low, adt7310_set_t_alarm_low, 0);
-static IIO_DEVICE_ATTR(t_crit,
- S_IRUGO | S_IWUSR,
- adt7310_show_t_crit, adt7310_set_t_crit, 0);
-static IIO_DEVICE_ATTR(t_hyst,
- S_IRUGO | S_IWUSR,
- adt7310_show_t_hyst, adt7310_set_t_hyst, 0);
-
-static struct attribute *adt7310_event_int_attributes[] = {
- &iio_dev_attr_event_mode.dev_attr.attr,
- &iio_dev_attr_available_event_modes.dev_attr.attr,
- &iio_dev_attr_fault_queue.dev_attr.attr,
- &iio_dev_attr_t_alarm_high.dev_attr.attr,
- &iio_dev_attr_t_alarm_low.dev_attr.attr,
- &iio_dev_attr_t_crit.dev_attr.attr,
- &iio_dev_attr_t_hyst.dev_attr.attr,
- NULL,
-};
-
-static struct attribute_group adt7310_event_attribute_group = {
- .attrs = adt7310_event_int_attributes,
- .name = "events",
-};
-
-static const struct iio_info adt7310_info = {
- .attrs = &adt7310_attribute_group,
- .event_attrs = &adt7310_event_attribute_group,
- .driver_module = THIS_MODULE,
-};
-
-/*
- * device probe and remove
- */
-
-static int __devinit adt7310_probe(struct spi_device *spi_dev)
-{
- struct adt7310_chip_info *chip;
- struct iio_dev *indio_dev;
- int ret = 0;
- unsigned long *adt7310_platform_data = spi_dev->dev.platform_data;
- unsigned long irq_flags;
-
- indio_dev = iio_device_alloc(sizeof(*chip));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
- chip = iio_priv(indio_dev);
- /* this is only used for device removal purposes */
- dev_set_drvdata(&spi_dev->dev, indio_dev);
-
- chip->spi_dev = spi_dev;
-
- indio_dev->dev.parent = &spi_dev->dev;
- indio_dev->name = spi_get_device_id(spi_dev)->name;
- indio_dev->info = &adt7310_info;
- indio_dev->modes = INDIO_DIRECT_MODE;
-
- /* CT critcal temperature event. line 0 */
- if (spi_dev->irq) {
- if (adt7310_platform_data[2])
- irq_flags = adt7310_platform_data[2];
- else
- irq_flags = IRQF_TRIGGER_LOW;
- ret = request_threaded_irq(spi_dev->irq,
- NULL,
- &adt7310_event_handler,
- irq_flags | IRQF_ONESHOT,
- indio_dev->name,
- indio_dev);
- if (ret)
- goto error_free_dev;
- }
-
- /* INT bound temperature alarm event. line 1 */
- if (adt7310_platform_data[0]) {
- ret = request_threaded_irq(adt7310_platform_data[0],
- NULL,
- &adt7310_event_handler,
- adt7310_platform_data[1] |
- IRQF_ONESHOT,
- indio_dev->name,
- indio_dev);
- if (ret)
- goto error_unreg_ct_irq;
- }
-
- if (spi_dev->irq && adt7310_platform_data[0]) {
- ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
- if (ret) {
- ret = -EIO;
- goto error_unreg_int_irq;
- }
-
- /* set irq polarity low level */
- chip->config &= ~ADT7310_CT_POLARITY;
-
- if (adt7310_platform_data[1] & IRQF_TRIGGER_HIGH)
- chip->config |= ADT7310_INT_POLARITY;
- else
- chip->config &= ~ADT7310_INT_POLARITY;
-
- ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, chip->config);
- if (ret) {
- ret = -EIO;
- goto error_unreg_int_irq;
- }
- }
-
- ret = iio_device_register(indio_dev);
- if (ret)
- goto error_unreg_int_irq;
-
- dev_info(&spi_dev->dev, "%s temperature sensor registered.\n",
- indio_dev->name);
-
- return 0;
-
-error_unreg_int_irq:
- free_irq(adt7310_platform_data[0], indio_dev);
-error_unreg_ct_irq:
- free_irq(spi_dev->irq, indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
- return ret;
-}
-
-static int __devexit adt7310_remove(struct spi_device *spi_dev)
-{
- struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev);
- unsigned long *adt7310_platform_data = spi_dev->dev.platform_data;
-
- iio_device_unregister(indio_dev);
- dev_set_drvdata(&spi_dev->dev, NULL);
- if (adt7310_platform_data[0])
- free_irq(adt7310_platform_data[0], indio_dev);
- if (spi_dev->irq)
- free_irq(spi_dev->irq, indio_dev);
- iio_device_free(indio_dev);
-
- return 0;
-}
-
-static const struct spi_device_id adt7310_id[] = {
- { "adt7310", 0 },
- {}
-};
-
-MODULE_DEVICE_TABLE(spi, adt7310_id);
-
-static struct spi_driver adt7310_driver = {
- .driver = {
- .name = "adt7310",
- .owner = THIS_MODULE,
- },
- .probe = adt7310_probe,
- .remove = __devexit_p(adt7310_remove),
- .id_table = adt7310_id,
-};
-module_spi_driver(adt7310_driver);
-
-MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
-MODULE_DESCRIPTION("Analog Devices ADT7310 digital"
- " temperature sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c
index 4157596ea3b..35455e16094 100644
--- a/drivers/staging/iio/adc/adt7410.c
+++ b/drivers/staging/iio/adc/adt7410.c
@@ -1,5 +1,5 @@
/*
- * ADT7410 digital temperature sensor driver supporting ADT7410
+ * ADT7410 digital temperature sensor driver supporting ADT7310/ADT7410
*
* Copyright 2010 Analog Devices Inc.
*
@@ -13,6 +13,7 @@
#include <linux/sysfs.h>
#include <linux/list.h>
#include <linux/i2c.h>
+#include <linux/spi/spi.h>
#include <linux/module.h>
#include <linux/iio/iio.h>
@@ -34,6 +35,19 @@
#define ADT7410_RESET 0x2F
/*
+ * ADT7310 registers definition
+ */
+
+#define ADT7310_STATUS 0
+#define ADT7310_CONFIG 1
+#define ADT7310_TEMPERATURE 2
+#define ADT7310_ID 3
+#define ADT7310_T_CRIT 4
+#define ADT7310_T_HYST 5
+#define ADT7310_T_ALARM_HIGH 6
+#define ADT7310_T_ALARM_LOW 7
+
+/*
* ADT7410 status
*/
#define ADT7410_STAT_T_LOW 0x10
@@ -69,75 +83,52 @@
#define ADT7410_MANUFACTORY_ID_MASK 0xF0
#define ADT7410_MANUFACTORY_ID_OFFSET 4
+
+#define ADT7310_CMD_REG_MASK 0x28
+#define ADT7310_CMD_REG_OFFSET 3
+#define ADT7310_CMD_READ 0x40
+#define ADT7310_CMD_CON_READ 0x4
+
#define ADT7410_IRQS 2
/*
* struct adt7410_chip_info - chip specifc information
*/
+struct adt7410_chip_info;
+
+struct adt7410_ops {
+ int (*read_word)(struct adt7410_chip_info *, u8 reg, u16 *data);
+ int (*write_word)(struct adt7410_chip_info *, u8 reg, u16 data);
+ int (*read_byte)(struct adt7410_chip_info *, u8 reg, u8 *data);
+ int (*write_byte)(struct adt7410_chip_info *, u8 reg, u8 data);
+};
+
struct adt7410_chip_info {
- struct i2c_client *client;
+ struct device *dev;
u8 config;
-};
-/*
- * adt7410 register access by I2C
- */
+ const struct adt7410_ops *ops;
+};
-static int adt7410_i2c_read_word(struct adt7410_chip_info *chip, u8 reg, u16 *data)
+static int adt7410_read_word(struct adt7410_chip_info *chip, u8 reg, u16 *data)
{
- struct i2c_client *client = chip->client;
- int ret = 0;
-
- ret = i2c_smbus_read_word_data(client, reg);
- if (ret < 0) {
- dev_err(&client->dev, "I2C read error\n");
- return ret;
- }
-
- *data = swab16((u16)ret);
-
- return 0;
+ return chip->ops->read_word(chip, reg, data);
}
-static int adt7410_i2c_write_word(struct adt7410_chip_info *chip, u8 reg, u16 data)
+static int adt7410_write_word(struct adt7410_chip_info *chip, u8 reg, u16 data)
{
- struct i2c_client *client = chip->client;
- int ret = 0;
-
- ret = i2c_smbus_write_word_data(client, reg, swab16(data));
- if (ret < 0)
- dev_err(&client->dev, "I2C write error\n");
-
- return ret;
+ return chip->ops->write_word(chip, reg, data);
}
-static int adt7410_i2c_read_byte(struct adt7410_chip_info *chip, u8 reg, u8 *data)
+static int adt7410_read_byte(struct adt7410_chip_info *chip, u8 reg, u8 *data)
{
- struct i2c_client *client = chip->client;
- int ret = 0;
-
- ret = i2c_smbus_read_byte_data(client, reg);
- if (ret < 0) {
- dev_err(&client->dev, "I2C read error\n");
- return ret;
- }
-
- *data = (u8)ret;
-
- return 0;
+ return chip->ops->read_byte(chip, reg, data);
}
-static int adt7410_i2c_write_byte(struct adt7410_chip_info *chip, u8 reg, u8 data)
+static int adt7410_write_byte(struct adt7410_chip_info *chip, u8 reg, u8 data)
{
- struct i2c_client *client = chip->client;
- int ret = 0;
-
- ret = i2c_smbus_write_byte_data(client, reg, data);
- if (ret < 0)
- dev_err(&client->dev, "I2C write error\n");
-
- return ret;
+ return chip->ops->write_byte(chip, reg, data);
}
static ssize_t adt7410_show_mode(struct device *dev,
@@ -172,7 +163,7 @@ static ssize_t adt7410_store_mode(struct device *dev,
u16 config;
int ret;
- ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+ ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
if (ret)
return -EIO;
@@ -184,13 +175,13 @@ static ssize_t adt7410_store_mode(struct device *dev,
else if (strcmp(buf, "sps"))
config |= ADT7410_SPS;
- ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
+ ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
if (ret)
return -EIO;
chip->config = config;
- return ret;
+ return len;
}
static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
@@ -216,7 +207,7 @@ static ssize_t adt7410_show_resolution(struct device *dev,
int ret;
int bits;
- ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+ ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
if (ret)
return -EIO;
@@ -243,7 +234,7 @@ static ssize_t adt7410_store_resolution(struct device *dev,
if (ret)
return -EINVAL;
- ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+ ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
if (ret)
return -EIO;
@@ -251,7 +242,7 @@ static ssize_t adt7410_store_resolution(struct device *dev,
if (data)
config |= ADT7410_RESOLUTION;
- ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
+ ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
if (ret)
return -EIO;
@@ -274,7 +265,7 @@ static ssize_t adt7410_show_id(struct device *dev,
u8 id;
int ret;
- ret = adt7410_i2c_read_byte(chip, ADT7410_ID, &id);
+ ret = adt7410_read_byte(chip, ADT7410_ID, &id);
if (ret)
return -EIO;
@@ -317,7 +308,7 @@ static ssize_t adt7410_show_value(struct device *dev,
int ret, i = 0;
do {
- ret = adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status);
+ ret = adt7410_read_byte(chip, ADT7410_STATUS, &status);
if (ret)
return -EIO;
i++;
@@ -325,7 +316,7 @@ static ssize_t adt7410_show_value(struct device *dev,
return -EIO;
} while (status & ADT7410_STAT_NOT_RDY);
- ret = adt7410_i2c_read_word(chip, ADT7410_TEMPERATURE, &data);
+ ret = adt7410_read_word(chip, ADT7410_TEMPERATURE, &data);
if (ret)
return -EIO;
@@ -354,7 +345,7 @@ static irqreturn_t adt7410_event_handler(int irq, void *private)
s64 timestamp = iio_get_time_ns();
u8 status;
- if (adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status))
+ if (adt7410_read_byte(chip, ADT7410_STATUS, &status))
return IRQ_HANDLED;
if (status & ADT7410_STAT_T_HIGH)
@@ -387,7 +378,7 @@ static ssize_t adt7410_show_event_mode(struct device *dev,
struct adt7410_chip_info *chip = iio_priv(dev_info);
int ret;
- ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+ ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
if (ret)
return -EIO;
@@ -407,7 +398,7 @@ static ssize_t adt7410_set_event_mode(struct device *dev,
u16 config;
int ret;
- ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+ ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
if (ret)
return -EIO;
@@ -415,7 +406,7 @@ static ssize_t adt7410_set_event_mode(struct device *dev,
if (strcmp(buf, "comparator") != 0)
config |= ADT7410_EVENT_MODE;
- ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
+ ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
if (ret)
return -EIO;
@@ -439,7 +430,7 @@ static ssize_t adt7410_show_fault_queue(struct device *dev,
struct adt7410_chip_info *chip = iio_priv(dev_info);
int ret;
- ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+ ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
if (ret)
return -EIO;
@@ -461,13 +452,13 @@ static ssize_t adt7410_set_fault_queue(struct device *dev,
if (ret || data > 3)
return -EINVAL;
- ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+ ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
if (ret)
return -EIO;
config = chip->config & ~ADT7410_FAULT_QUEUE_MASK;
config |= data;
- ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
+ ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
if (ret)
return -EIO;
@@ -486,7 +477,7 @@ static inline ssize_t adt7410_show_t_bound(struct device *dev,
u16 data;
int ret;
- ret = adt7410_i2c_read_word(chip, bound_reg, &data);
+ ret = adt7410_read_word(chip, bound_reg, &data);
if (ret)
return -EIO;
@@ -557,7 +548,7 @@ static inline ssize_t adt7410_set_t_bound(struct device *dev,
data <<= ADT7410_T13_VALUE_OFFSET;
}
- ret = adt7410_i2c_write_word(chip, bound_reg, data);
+ ret = adt7410_write_word(chip, bound_reg, data);
if (ret)
return -EIO;
@@ -624,7 +615,7 @@ static ssize_t adt7410_show_t_hyst(struct device *dev,
int ret;
u8 t_hyst;
- ret = adt7410_i2c_read_byte(chip, ADT7410_T_HYST, &t_hyst);
+ ret = adt7410_read_byte(chip, ADT7410_T_HYST, &t_hyst);
if (ret)
return -EIO;
@@ -649,7 +640,7 @@ static inline ssize_t adt7410_set_t_hyst(struct device *dev,
t_hyst = (u8)data;
- ret = adt7410_i2c_write_byte(chip, ADT7410_T_HYST, t_hyst);
+ ret = adt7410_write_byte(chip, ADT7410_T_HYST, t_hyst);
if (ret)
return -EIO;
@@ -704,14 +695,14 @@ static const struct iio_info adt7410_info = {
* device probe and remove
*/
-static int __devinit adt7410_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int adt7410_probe(struct device *dev, int irq,
+ const char *name, const struct adt7410_ops *ops)
{
+ unsigned long *adt7410_platform_data = dev->platform_data;
+ unsigned long local_pdata[] = {0, 0};
struct adt7410_chip_info *chip;
struct iio_dev *indio_dev;
int ret = 0;
- unsigned long *adt7410_platform_data = client->dev.platform_data;
- unsigned long local_pdata[] = {0, 0};
indio_dev = iio_device_alloc(sizeof(*chip));
if (indio_dev == NULL) {
@@ -720,12 +711,13 @@ static int __devinit adt7410_probe(struct i2c_client *client,
}
chip = iio_priv(indio_dev);
/* this is only used for device removal purposes */
- i2c_set_clientdata(client, indio_dev);
+ dev_set_drvdata(dev, indio_dev);
- chip->client = client;
+ chip->dev = dev;
+ chip->ops = ops;
- indio_dev->name = id->name;
- indio_dev->dev.parent = &client->dev;
+ indio_dev->name = name;
+ indio_dev->dev.parent = dev;
indio_dev->info = &adt7410_info;
indio_dev->modes = INDIO_DIRECT_MODE;
@@ -733,12 +725,12 @@ static int __devinit adt7410_probe(struct i2c_client *client,
adt7410_platform_data = local_pdata;
/* CT critcal temperature event. line 0 */
- if (client->irq) {
- ret = request_threaded_irq(client->irq,
+ if (irq) {
+ ret = request_threaded_irq(irq,
NULL,
&adt7410_event_handler,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- id->name,
+ name,
indio_dev);
if (ret)
goto error_free_dev;
@@ -751,13 +743,13 @@ static int __devinit adt7410_probe(struct i2c_client *client,
&adt7410_event_handler,
adt7410_platform_data[1] |
IRQF_ONESHOT,
- id->name,
+ name,
indio_dev);
if (ret)
goto error_unreg_ct_irq;
}
- ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+ ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
if (ret) {
ret = -EIO;
goto error_unreg_int_irq;
@@ -765,7 +757,7 @@ static int __devinit adt7410_probe(struct i2c_client *client,
chip->config |= ADT7410_RESOLUTION;
- if (client->irq && adt7410_platform_data[0]) {
+ if (irq && adt7410_platform_data[0]) {
/* set irq polarity low level */
chip->config &= ~ADT7410_CT_POLARITY;
@@ -776,7 +768,7 @@ static int __devinit adt7410_probe(struct i2c_client *client,
chip->config &= ~ADT7410_INT_POLARITY;
}
- ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, chip->config);
+ ret = adt7410_write_byte(chip, ADT7410_CONFIG, chip->config);
if (ret) {
ret = -EIO;
goto error_unreg_int_irq;
@@ -785,36 +777,117 @@ static int __devinit adt7410_probe(struct i2c_client *client,
if (ret)
goto error_unreg_int_irq;
- dev_info(&client->dev, "%s temperature sensor registered.\n",
- id->name);
+ dev_info(dev, "%s temperature sensor registered.\n",
+ name);
return 0;
error_unreg_int_irq:
free_irq(adt7410_platform_data[0], indio_dev);
error_unreg_ct_irq:
- free_irq(client->irq, indio_dev);
+ free_irq(irq, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
-static int __devexit adt7410_remove(struct i2c_client *client)
+static int adt7410_remove(struct device *dev, int irq)
{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
- unsigned long *adt7410_platform_data = client->dev.platform_data;
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ unsigned long *adt7410_platform_data = dev->platform_data;
iio_device_unregister(indio_dev);
if (adt7410_platform_data[0])
free_irq(adt7410_platform_data[0], indio_dev);
- if (client->irq)
- free_irq(client->irq, indio_dev);
+ if (irq)
+ free_irq(irq, indio_dev);
iio_device_free(indio_dev);
return 0;
}
+#if IS_ENABLED(CONFIG_I2C)
+
+static int adt7410_i2c_read_word(struct adt7410_chip_info *chip, u8 reg,
+ u16 *data)
+{
+ struct i2c_client *client = to_i2c_client(chip->dev);
+ int ret = 0;
+
+ ret = i2c_smbus_read_word_data(client, reg);
+ if (ret < 0) {
+ dev_err(&client->dev, "I2C read error\n");
+ return ret;
+ }
+
+ *data = swab16((u16)ret);
+
+ return 0;
+}
+
+static int adt7410_i2c_write_word(struct adt7410_chip_info *chip, u8 reg,
+ u16 data)
+{
+ struct i2c_client *client = to_i2c_client(chip->dev);
+ int ret = 0;
+
+ ret = i2c_smbus_write_word_data(client, reg, swab16(data));
+ if (ret < 0)
+ dev_err(&client->dev, "I2C write error\n");
+
+ return ret;
+}
+
+static int adt7410_i2c_read_byte(struct adt7410_chip_info *chip, u8 reg,
+ u8 *data)
+{
+ struct i2c_client *client = to_i2c_client(chip->dev);
+ int ret = 0;
+
+ ret = i2c_smbus_read_byte_data(client, reg);
+ if (ret < 0) {
+ dev_err(&client->dev, "I2C read error\n");
+ return ret;
+ }
+
+ *data = (u8)ret;
+
+ return 0;
+}
+
+static int adt7410_i2c_write_byte(struct adt7410_chip_info *chip, u8 reg,
+ u8 data)
+{
+ struct i2c_client *client = to_i2c_client(chip->dev);
+ int ret = 0;
+
+ ret = i2c_smbus_write_byte_data(client, reg, data);
+ if (ret < 0)
+ dev_err(&client->dev, "I2C write error\n");
+
+ return ret;
+}
+
+static const struct adt7410_ops adt7410_i2c_ops = {
+ .read_word = adt7410_i2c_read_word,
+ .write_word = adt7410_i2c_write_word,
+ .read_byte = adt7410_i2c_read_byte,
+ .write_byte = adt7410_i2c_write_byte,
+};
+
+static int adt7410_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ return adt7410_probe(&client->dev, client->irq, id->name,
+ &adt7410_i2c_ops);
+}
+
+static int adt7410_i2c_remove(struct i2c_client *client)
+{
+ return adt7410_remove(&client->dev, client->irq);
+}
+
static const struct i2c_device_id adt7410_id[] = {
{ "adt7410", 0 },
{}
@@ -826,13 +899,204 @@ static struct i2c_driver adt7410_driver = {
.driver = {
.name = "adt7410",
},
- .probe = adt7410_probe,
- .remove = __devexit_p(adt7410_remove),
+ .probe = adt7410_i2c_probe,
+ .remove = adt7410_i2c_remove,
.id_table = adt7410_id,
};
-module_i2c_driver(adt7410_driver);
+
+static int __init adt7410_i2c_init(void)
+{
+ return i2c_add_driver(&adt7410_driver);
+}
+
+static void __exit adt7410_i2c_exit(void)
+{
+ i2c_del_driver(&adt7410_driver);
+}
+
+#else
+
+static int __init adt7410_i2c_init(void) { return 0; };
+static void __exit adt7410_i2c_exit(void) {};
+
+#endif
+
+#if IS_ENABLED(CONFIG_SPI_MASTER)
+
+static const u8 adt7371_reg_table[] = {
+ [ADT7410_TEMPERATURE] = ADT7310_TEMPERATURE,
+ [ADT7410_STATUS] = ADT7310_STATUS,
+ [ADT7410_CONFIG] = ADT7310_CONFIG,
+ [ADT7410_T_ALARM_HIGH] = ADT7310_T_ALARM_HIGH,
+ [ADT7410_T_ALARM_LOW] = ADT7310_T_ALARM_LOW,
+ [ADT7410_T_CRIT] = ADT7310_T_CRIT,
+ [ADT7410_T_HYST] = ADT7310_T_HYST,
+ [ADT7410_ID] = ADT7310_ID,
+};
+
+#define AD7310_COMMAND(reg) (adt7371_reg_table[(reg)] << ADT7310_CMD_REG_OFFSET)
+
+static int adt7310_spi_read_word(struct adt7410_chip_info *chip,
+ u8 reg, u16 *data)
+{
+ struct spi_device *spi = to_spi_device(chip->dev);
+ u8 command = AD7310_COMMAND(reg);
+ int ret = 0;
+
+ command |= ADT7310_CMD_READ;
+ ret = spi_write(spi, &command, sizeof(command));
+ if (ret < 0) {
+ dev_err(&spi->dev, "SPI write command error\n");
+ return ret;
+ }
+
+ ret = spi_read(spi, (u8 *)data, sizeof(*data));
+ if (ret < 0) {
+ dev_err(&spi->dev, "SPI read word error\n");
+ return ret;
+ }
+
+ *data = be16_to_cpu(*data);
+
+ return 0;
+}
+
+static int adt7310_spi_write_word(struct adt7410_chip_info *chip, u8 reg,
+ u16 data)
+{
+ struct spi_device *spi = to_spi_device(chip->dev);
+ u8 buf[3];
+ int ret = 0;
+
+ buf[0] = AD7310_COMMAND(reg);
+ buf[1] = (u8)(data >> 8);
+ buf[2] = (u8)(data & 0xFF);
+
+ ret = spi_write(spi, buf, 3);
+ if (ret < 0) {
+ dev_err(&spi->dev, "SPI write word error\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+static int adt7310_spi_read_byte(struct adt7410_chip_info *chip, u8 reg,
+ u8 *data)
+{
+ struct spi_device *spi = to_spi_device(chip->dev);
+ u8 command = AD7310_COMMAND(reg);
+ int ret = 0;
+
+ command |= ADT7310_CMD_READ;
+ ret = spi_write(spi, &command, sizeof(command));
+ if (ret < 0) {
+ dev_err(&spi->dev, "SPI write command error\n");
+ return ret;
+ }
+
+ ret = spi_read(spi, data, sizeof(*data));
+ if (ret < 0) {
+ dev_err(&spi->dev, "SPI read byte error\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int adt7310_spi_write_byte(struct adt7410_chip_info *chip, u8 reg,
+ u8 data)
+{
+ struct spi_device *spi = to_spi_device(chip->dev);
+ u8 buf[2];
+ int ret = 0;
+
+ buf[0] = AD7310_COMMAND(reg);
+ buf[1] = data;
+
+ ret = spi_write(spi, buf, 2);
+ if (ret < 0) {
+ dev_err(&spi->dev, "SPI write byte error\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+static const struct adt7410_ops adt7310_spi_ops = {
+ .read_word = adt7310_spi_read_word,
+ .write_word = adt7310_spi_write_word,
+ .read_byte = adt7310_spi_read_byte,
+ .write_byte = adt7310_spi_write_byte,
+};
+
+static int adt7310_spi_probe(struct spi_device *spi)
+{
+ return adt7410_probe(&spi->dev, spi->irq,
+ spi_get_device_id(spi)->name, &adt7310_spi_ops);
+}
+
+static int adt7310_spi_remove(struct spi_device *spi)
+{
+ return adt7410_remove(&spi->dev, spi->irq);
+}
+
+static const struct spi_device_id adt7310_id[] = {
+ { "adt7310", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(spi, adt7310_id);
+
+static struct spi_driver adt7310_driver = {
+ .driver = {
+ .name = "adt7310",
+ .owner = THIS_MODULE,
+ },
+ .probe = adt7310_spi_probe,
+ .remove = adt7310_spi_remove,
+ .id_table = adt7310_id,
+};
+
+static int __init adt7310_spi_init(void)
+{
+ return spi_register_driver(&adt7310_driver);
+}
+
+static void adt7310_spi_exit(void)
+{
+ spi_unregister_driver(&adt7310_driver);
+}
+
+#else
+
+static int __init adt7310_spi_init(void) { return 0; };
+static void adt7310_spi_exit(void) {};
+
+#endif
+
+static int __init adt7410_init(void)
+{
+ int ret;
+
+ ret = adt7310_spi_init();
+ if (ret)
+ return ret;
+
+ ret = adt7410_i2c_init();
+ if (ret)
+ adt7310_spi_exit();
+
+ return ret;
+}
+module_init(adt7410_init);
+
+static void __exit adt7410_exit(void)
+{
+ adt7410_i2c_exit();
+ adt7310_spi_exit();
+}
+module_exit(adt7410_exit);
MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
-MODULE_DESCRIPTION("Analog Devices ADT7410 digital"
- " temperature sensor driver");
+MODULE_DESCRIPTION("Analog Devices ADT7310/ADT7410 digital temperature sensor driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c
index 7e9bd0001cc..0bf2a6cc79e 100644
--- a/drivers/staging/iio/adc/lpc32xx_adc.c
+++ b/drivers/staging/iio/adc/lpc32xx_adc.c
@@ -126,7 +126,7 @@ static irqreturn_t lpc32xx_adc_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __devinit lpc32xx_adc_probe(struct platform_device *pdev)
+static int lpc32xx_adc_probe(struct platform_device *pdev)
{
struct lpc32xx_adc_info *info = NULL;
struct resource *res;
@@ -150,7 +150,7 @@ static int __devinit lpc32xx_adc_probe(struct platform_device *pdev)
info = iio_priv(iodev);
- info->adc_base = ioremap(res->start, res->end - res->start + 1);
+ info->adc_base = ioremap(res->start, resource_size(res));
if (!info->adc_base) {
dev_err(&pdev->dev, "failed mapping memory\n");
retval = -EBUSY;
@@ -207,7 +207,7 @@ errout1:
return retval;
}
-static int __devexit lpc32xx_adc_remove(struct platform_device *pdev)
+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);
@@ -233,7 +233,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_adc_match);
static struct platform_driver lpc32xx_adc_driver = {
.probe = lpc32xx_adc_probe,
- .remove = __devexit_p(lpc32xx_adc_remove),
+ .remove = lpc32xx_adc_remove,
.driver = {
.name = MOD_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h
deleted file mode 100644
index c746918683f..00000000000
--- a/drivers/staging/iio/adc/max1363.h
+++ /dev/null
@@ -1,177 +0,0 @@
-#ifndef _MAX1363_H_
-#define _MAX1363_H_
-
-#define MAX1363_SETUP_BYTE(a) ((a) | 0x80)
-
-/* There is a fair bit more defined here than currently
- * used, but the intention is to support everything these
- * chips do in the long run */
-
-/* see data sheets */
-/* max1363 and max1236, max1237, max1238, max1239 */
-#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD 0x00
-#define MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF 0x20
-#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT 0x40
-#define MAX1363_SETUP_AIN3_IS_REF_REF_IS_INT 0x60
-#define MAX1363_SETUP_POWER_UP_INT_REF 0x10
-#define MAX1363_SETUP_POWER_DOWN_INT_REF 0x00
-
-/* think about includeing max11600 etc - more settings */
-#define MAX1363_SETUP_EXT_CLOCK 0x08
-#define MAX1363_SETUP_INT_CLOCK 0x00
-#define MAX1363_SETUP_UNIPOLAR 0x00
-#define MAX1363_SETUP_BIPOLAR 0x04
-#define MAX1363_SETUP_RESET 0x00
-#define MAX1363_SETUP_NORESET 0x02
-/* max1363 only - though don't care on others.
- * For now monitor modes are not implemented as the relevant
- * line is not connected on my test board.
- * The definitions are here as I intend to add this soon.
- */
-#define MAX1363_SETUP_MONITOR_SETUP 0x01
-
-/* Specific to the max1363 */
-#define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4))
-#define MAX1363_MON_INT_ENABLE 0x01
-
-/* defined for readability reasons */
-/* All chips */
-#define MAX1363_CONFIG_BYTE(a) ((a))
-
-#define MAX1363_CONFIG_SE 0x01
-#define MAX1363_CONFIG_DE 0x00
-#define MAX1363_CONFIG_SCAN_TO_CS 0x00
-#define MAX1363_CONFIG_SCAN_SINGLE_8 0x20
-#define MAX1363_CONFIG_SCAN_MONITOR_MODE 0x40
-#define MAX1363_CONFIG_SCAN_SINGLE_1 0x60
-/* max123{6-9} only */
-#define MAX1236_SCAN_MID_TO_CHANNEL 0x40
-
-/* max1363 only - merely part of channel selects or don't care for others*/
-#define MAX1363_CONFIG_EN_MON_MODE_READ 0x18
-
-#define MAX1363_CHANNEL_SEL(a) ((a) << 1)
-
-/* max1363 strictly 0x06 - but doesn't matter */
-#define MAX1363_CHANNEL_SEL_MASK 0x1E
-#define MAX1363_SCAN_MASK 0x60
-#define MAX1363_SE_DE_MASK 0x01
-
-#define MAX1363_MAX_CHANNELS 25
-/**
- * struct max1363_mode - scan mode information
- * @conf: The corresponding value of the configuration register
- * @modemask: Bit mask corresponding to channels enabled in this mode
- */
-struct max1363_mode {
- int8_t conf;
- DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS);
-};
-
-/* This must be maintained along side the max1363_mode_table in max1363_core */
-enum max1363_modes {
- /* Single read of a single channel */
- _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11,
- /* Differential single read */
- d0m1, d2m3, d4m5, d6m7, d8m9, d10m11,
- d1m0, d3m2, d5m4, d7m6, d9m8, d11m10,
- /* Scan to channel and mid to channel where overlapping */
- s0to1, s0to2, s2to3, s0to3, s0to4, s0to5, s0to6,
- s6to7, s0to7, s6to8, s0to8, s6to9,
- s0to9, s6to10, s0to10, s6to11, s0to11,
- /* Differential scan to channel and mid to channel where overlapping */
- d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9,
- d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2,
- d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8,
- d7m6to11m10, d1m0to11m10,
-};
-
-/**
- * struct max1363_chip_info - chip specifc information
- * @name: indentification string for chip
- * @bits: accuracy of the adc in bits
- * @int_vref_mv: the internal reference voltage
- * @info: iio core function callbacks structure
- * @mode_list: array of available scan modes
- * @num_modes: the number of scan modes available
- * @default_mode: the scan mode in which the chip starts up
- * @channel: channel specification
- * @num_channels: number of channels
- */
-struct max1363_chip_info {
- const struct iio_info *info;
- const struct iio_chan_spec *channels;
- int num_channels;
- const enum max1363_modes *mode_list;
- enum max1363_modes default_mode;
- u16 int_vref_mv;
- u8 num_modes;
- u8 bits;
-};
-
-/**
- * struct max1363_state - driver instance specific data
- * @client: i2c_client
- * @setupbyte: cache of current device setup byte
- * @configbyte: cache of current device config byte
- * @chip_info: chip model specific constants, available modes etc
- * @current_mode: the scan mode of this chip
- * @requestedmask: a valid requested set of channels
- * @reg: supply regulator
- * @monitor_on: whether monitor mode is enabled
- * @monitor_speed: parameter corresponding to device monitor speed setting
- * @mask_high: bitmask for enabled high thresholds
- * @mask_low: bitmask for enabled low thresholds
- * @thresh_high: high threshold values
- * @thresh_low: low threshold values
- */
-struct max1363_state {
- struct i2c_client *client;
- u8 setupbyte;
- u8 configbyte;
- const struct max1363_chip_info *chip_info;
- const struct max1363_mode *current_mode;
- u32 requestedmask;
- struct regulator *reg;
-
- /* Using monitor modes and buffer at the same time is
- currently not supported */
- bool monitor_on;
- unsigned int monitor_speed:3;
- u8 mask_high;
- u8 mask_low;
- /* 4x unipolar first then the fours bipolar ones */
- s16 thresh_high[8];
- s16 thresh_low[8];
-};
-
-const struct max1363_mode
-*max1363_match_mode(const unsigned long *mask,
- const struct max1363_chip_info *ci);
-
-int max1363_set_scan_mode(struct max1363_state *st);
-
-#ifdef CONFIG_MAX1363_RING_BUFFER
-int max1363_update_scan_mode(struct iio_dev *indio_dev,
- const unsigned long *scan_mask);
-int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev);
-void max1363_ring_cleanup(struct iio_dev *indio_dev);
-
-#else /* CONFIG_MAX1363_RING_BUFFER */
-int max1363_update_scan_mode(struct iio_dev *indio_dev,
- const long *scan_mask)
-{
- return 0;
-}
-
-static inline int
-max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void max1363_ring_cleanup(struct iio_dev *indio_dev)
-{
-}
-#endif /* CONFIG_MAX1363_RING_BUFFER */
-#endif /* _MAX1363_H_ */
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
deleted file mode 100644
index 5f74f3b7671..00000000000
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2008 Jonathan Cameron
- *
- * 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.
- *
- * max1363_ring.c
- */
-
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/bitops.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/buffer.h>
-#include "../ring_sw.h"
-#include <linux/iio/trigger_consumer.h>
-
-#include "max1363.h"
-
-int max1363_update_scan_mode(struct iio_dev *indio_dev,
- const unsigned long *scan_mask)
-{
- struct max1363_state *st = iio_priv(indio_dev);
-
- /*
- * Need to figure out the current mode based upon the requested
- * scan mask in iio_dev
- */
- st->current_mode = max1363_match_mode(scan_mask, st->chip_info);
- if (!st->current_mode)
- return -EINVAL;
- max1363_set_scan_mode(st);
- return 0;
-}
-
-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;
- unsigned long numvals = bitmap_weight(st->current_mode->modemask,
- MAX1363_MAX_CHANNELS);
-
- /* Ensure the timestamp is 8 byte aligned */
- if (st->chip_info->bits != 8)
- d_size = numvals*2;
- else
- d_size = numvals;
- if (indio_dev->scan_timestamp) {
- d_size += sizeof(s64);
- if (d_size % sizeof(s64))
- d_size += sizeof(s64) - (d_size % sizeof(s64));
- }
- /* Monitor mode prevents reading. Whilst not currently implemented
- * might as well have this test in here in the meantime as it does
- * no harm.
- */
- if (numvals == 0)
- goto done;
-
- rxbuf = kmalloc(d_size, GFP_KERNEL);
- if (rxbuf == NULL)
- goto done;
- if (st->chip_info->bits != 8)
- b_sent = i2c_master_recv(st->client, rxbuf, numvals*2);
- else
- b_sent = i2c_master_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_buffer(indio_dev->buffer, rxbuf);
-
-done_free:
- kfree(rxbuf);
-done:
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-static const struct iio_buffer_setup_ops max1363_ring_setup_ops = {
- .postenable = &iio_triggered_buffer_postenable,
- .preenable = &iio_sw_buffer_preenable,
- .predisable = &iio_triggered_buffer_predisable,
-};
-
-int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- struct max1363_state *st = iio_priv(indio_dev);
- int ret = 0;
-
- indio_dev->buffer = iio_sw_rb_allocate(indio_dev);
- if (!indio_dev->buffer) {
- ret = -ENOMEM;
- goto error_ret;
- }
- indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
- &max1363_trigger_handler,
- IRQF_ONESHOT,
- indio_dev,
- "%s_consumer%d",
- st->client->name,
- indio_dev->id);
- if (indio_dev->pollfunc == NULL) {
- ret = -ENOMEM;
- goto error_deallocate_sw_rb;
- }
- /* Ring buffer functions - here trigger setup related */
- indio_dev->setup_ops = &max1363_ring_setup_ops;
-
- /* Flag that polled ring buffering is possible */
- indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
-
- return 0;
-
-error_deallocate_sw_rb:
- iio_sw_rb_free(indio_dev->buffer);
-error_ret:
- return ret;
-}
-
-void max1363_ring_cleanup(struct iio_dev *indio_dev)
-{
- /* ensure that the trigger has been detached */
- iio_dealloc_pollfunc(indio_dev->pollfunc);
- iio_sw_rb_free(indio_dev->buffer);
-}
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index ca7c1fa88e7..fb31b457a56 100644
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -237,7 +237,6 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *iio = pf->indio_dev;
struct mxs_lradc *lradc = iio_priv(iio);
- struct iio_buffer *buffer = iio->buffer;
const uint32_t chan_value = LRADC_CH_ACCUMULATE |
((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET);
int i, j = 0;
@@ -256,7 +255,7 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p)
*timestamp = pf->timestamp;
}
- iio_push_to_buffer(buffer, (u8 *)lradc->buffer);
+ iio_push_to_buffers(iio, (u8 *)lradc->buffer);
iio_trigger_notify_done(iio->trig);
@@ -351,7 +350,7 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
writel(chan_value, lradc->base + LRADC_CH(ofs));
enable |= 1 << ofs;
ofs++;
- };
+ }
writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK,
lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR);
@@ -467,7 +466,7 @@ static void mxs_lradc_hw_stop(struct mxs_lradc *lradc)
writel(0, lradc->base + LRADC_DELAY(i));
}
-static int __devinit mxs_lradc_probe(struct platform_device *pdev)
+static int mxs_lradc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mxs_lradc *lradc;
@@ -552,7 +551,7 @@ err_addr:
return ret;
}
-static int __devexit mxs_lradc_remove(struct platform_device *pdev)
+static int mxs_lradc_remove(struct platform_device *pdev)
{
struct iio_dev *iio = platform_get_drvdata(pdev);
struct mxs_lradc *lradc = iio_priv(iio);
@@ -580,7 +579,7 @@ static struct platform_driver mxs_lradc_driver = {
.of_match_table = mxs_lradc_dt_ids,
},
.probe = mxs_lradc_probe,
- .remove = __devexit_p(mxs_lradc_remove),
+ .remove = mxs_lradc_remove,
};
module_platform_driver(mxs_lradc_driver);
diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c
index 0b83e2e1f41..13052ceb2f2 100644
--- a/drivers/staging/iio/adc/spear_adc.c
+++ b/drivers/staging/iio/adc/spear_adc.c
@@ -291,7 +291,7 @@ static const struct iio_info spear_adc_iio_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit spear_adc_probe(struct platform_device *pdev)
+static int spear_adc_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
@@ -401,7 +401,7 @@ errout1:
return ret;
}
-static int __devexit spear_adc_remove(struct platform_device *pdev)
+static int spear_adc_remove(struct platform_device *pdev)
{
struct iio_dev *iodev = platform_get_drvdata(pdev);
struct spear_adc_info *info = iio_priv(iodev);
@@ -424,7 +424,7 @@ MODULE_DEVICE_TABLE(of, spear_adc_dt_ids);
static struct platform_driver spear_adc_driver = {
.probe = spear_adc_probe,
- .remove = __devexit_p(spear_adc_remove),
+ .remove = spear_adc_remove,
.driver = {
.name = MOD_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c
index 9e128dd7d45..ce7d91cb331 100644
--- a/drivers/staging/iio/addac/adt7316-i2c.c
+++ b/drivers/staging/iio/addac/adt7316-i2c.c
@@ -92,7 +92,7 @@ static int adt7316_i2c_multi_write(void *client, u8 reg, u8 count, u8 *data)
* device probe and remove
*/
-static int __devinit adt7316_i2c_probe(struct i2c_client *client,
+static int adt7316_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adt7316_bus bus = {
@@ -108,7 +108,7 @@ static int __devinit adt7316_i2c_probe(struct i2c_client *client,
return adt7316_probe(&client->dev, &bus, id->name);
}
-static int __devexit adt7316_i2c_remove(struct i2c_client *client)
+static int adt7316_i2c_remove(struct i2c_client *client)
{
return adt7316_remove(&client->dev);
}
@@ -132,7 +132,7 @@ static struct i2c_driver adt7316_driver = {
.owner = THIS_MODULE,
},
.probe = adt7316_i2c_probe,
- .remove = __devexit_p(adt7316_i2c_remove),
+ .remove = adt7316_i2c_remove,
.id_table = adt7316_i2c_id,
};
module_i2c_driver(adt7316_driver);
diff --git a/drivers/staging/iio/addac/adt7316-spi.c b/drivers/staging/iio/addac/adt7316-spi.c
index 985f7d8a6eb..0db8ef5835a 100644
--- a/drivers/staging/iio/addac/adt7316-spi.c
+++ b/drivers/staging/iio/addac/adt7316-spi.c
@@ -89,7 +89,7 @@ static int adt7316_spi_write(void *client, u8 reg, u8 val)
* device probe and remove
*/
-static int __devinit adt7316_spi_probe(struct spi_device *spi_dev)
+static int adt7316_spi_probe(struct spi_device *spi_dev)
{
struct adt7316_bus bus = {
.client = spi_dev,
@@ -116,7 +116,7 @@ static int __devinit adt7316_spi_probe(struct spi_device *spi_dev)
return adt7316_probe(&spi_dev->dev, &bus, spi_dev->modalias);
}
-static int __devexit adt7316_spi_remove(struct spi_device *spi_dev)
+static int adt7316_spi_remove(struct spi_device *spi_dev)
{
return adt7316_remove(&spi_dev->dev);
}
@@ -140,7 +140,7 @@ static struct spi_driver adt7316_driver = {
.owner = THIS_MODULE,
},
.probe = adt7316_spi_probe,
- .remove = __devexit_p(adt7316_spi_remove),
+ .remove = adt7316_spi_remove,
.id_table = adt7316_spi_id,
};
module_spi_driver(adt7316_driver);
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index 8fb014a046a..0b431bc4f62 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -2125,7 +2125,7 @@ static const struct iio_info adt7516_info = {
/*
* device probe and remove
*/
-int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus,
+int adt7316_probe(struct device *dev, struct adt7316_bus *bus,
const char *name)
{
struct adt7316_chip_info *chip;
@@ -2216,7 +2216,7 @@ error_ret:
}
EXPORT_SYMBOL(adt7316_probe);
-int __devexit adt7316_remove(struct device *dev)
+int adt7316_remove(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct adt7316_chip_info *chip = iio_priv(indio_dev);
diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c
index 6a4041417d4..3c608c14dd9 100644
--- a/drivers/staging/iio/cdc/ad7150.c
+++ b/drivers/staging/iio/cdc/ad7150.c
@@ -156,7 +156,7 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev, u64 event_code)
return !adaptive && (threshtype == 0x1);
else
return !adaptive && (threshtype == 0x0);
- };
+ }
return -EINVAL;
}
@@ -194,7 +194,7 @@ static int ad7150_write_event_params(struct iio_dev *indio_dev, u64 event_code)
break;
default:
return -EINVAL;
- };
+ }
ret = i2c_smbus_write_byte_data(chip->client,
ad7150_addresses[chan][4],
sens);
@@ -257,7 +257,7 @@ static int ad7150_write_event_config(struct iio_dev *indio_dev,
default:
ret = -EINVAL;
goto error_ret;
- };
+ }
cfg |= (!adaptive << 7) | (thresh_type << 5);
@@ -327,7 +327,7 @@ static int ad7150_write_event_value(struct iio_dev *indio_dev,
default:
ret = -EINVAL;
goto error_ret;
- };
+ }
/* write back if active */
ret = ad7150_write_event_params(indio_dev, event_code);
@@ -360,7 +360,7 @@ static ssize_t ad7150_show_timeout(struct device *dev,
break;
default:
return -EINVAL;
- };
+ }
return sprintf(buf, "%d\n", value);
}
@@ -394,7 +394,7 @@ static ssize_t ad7150_store_timeout(struct device *dev,
default:
ret = -EINVAL;
goto error_ret;
- };
+ }
ret = ad7150_write_event_params(indio_dev, this_attr->address);
error_ret:
@@ -551,7 +551,7 @@ static const struct iio_info ad7150_info = {
* device probe and remove
*/
-static int __devinit ad7150_probe(struct i2c_client *client,
+static int ad7150_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret;
@@ -628,7 +628,7 @@ error_ret:
return ret;
}
-static int __devexit ad7150_remove(struct i2c_client *client)
+static int ad7150_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
@@ -658,7 +658,7 @@ static struct i2c_driver ad7150_driver = {
.name = "ad7150",
},
.probe = ad7150_probe,
- .remove = __devexit_p(ad7150_remove),
+ .remove = ad7150_remove,
.id_table = ad7150_id,
};
module_i2c_driver(ad7150_driver);
diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c
index 98c3015116a..3c92ba3722a 100644
--- a/drivers/staging/iio/cdc/ad7152.c
+++ b/drivers/staging/iio/cdc/ad7152.c
@@ -405,7 +405,7 @@ static int ad7152_read_raw(struct iio_dev *indio_dev,
break;
default:
ret = -EINVAL;
- };
+ }
out:
mutex_unlock(&indio_dev->mlock);
return ret;
@@ -474,7 +474,7 @@ static const struct iio_chan_spec ad7152_channels[] = {
* device probe and remove
*/
-static int __devinit ad7152_probe(struct i2c_client *client,
+static int ad7152_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret = 0;
@@ -518,7 +518,7 @@ error_ret:
return ret;
}
-static int __devexit ad7152_remove(struct i2c_client *client)
+static int ad7152_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
@@ -541,7 +541,7 @@ static struct i2c_driver ad7152_driver = {
.name = KBUILD_MODNAME,
},
.probe = ad7152_probe,
- .remove = __devexit_p(ad7152_remove),
+ .remove = ad7152_remove,
.id_table = ad7152_id,
};
module_i2c_driver(ad7152_driver);
diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c
index 754e11e8719..466b82ecfbe 100644
--- a/drivers/staging/iio/cdc/ad7746.c
+++ b/drivers/staging/iio/cdc/ad7746.c
@@ -677,7 +677,7 @@ static int ad7746_read_raw(struct iio_dev *indio_dev,
break;
default:
ret = -EINVAL;
- };
+ }
out:
mutex_unlock(&indio_dev->mlock);
return ret;
@@ -694,7 +694,7 @@ static const struct iio_info ad7746_info = {
* device probe and remove
*/
-static int __devinit ad7746_probe(struct i2c_client *client,
+static int ad7746_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ad7746_platform_data *pdata = client->dev.platform_data;
@@ -768,7 +768,7 @@ error_ret:
return ret;
}
-static int __devexit ad7746_remove(struct i2c_client *client)
+static int ad7746_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
@@ -792,7 +792,7 @@ static struct i2c_driver ad7746_driver = {
.name = KBUILD_MODNAME,
},
.probe = ad7746_probe,
- .remove = __devexit_p(ad7746_remove),
+ .remove = ad7746_remove,
.id_table = ad7746_id,
};
module_i2c_driver(ad7746_driver);
diff --git a/drivers/staging/iio/frequency/ad5930.c b/drivers/staging/iio/frequency/ad5930.c
index 2d541d0eebe..23777be38b1 100644
--- a/drivers/staging/iio/frequency/ad5930.c
+++ b/drivers/staging/iio/frequency/ad5930.c
@@ -91,7 +91,7 @@ static const struct iio_info ad5930_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit ad5930_probe(struct spi_device *spi)
+static int ad5930_probe(struct spi_device *spi)
{
struct ad5930_state *st;
struct iio_dev *idev;
@@ -127,7 +127,7 @@ error_ret:
return ret;
}
-static int __devexit ad5930_remove(struct spi_device *spi)
+static int ad5930_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
@@ -141,7 +141,7 @@ static struct spi_driver ad5930_driver = {
.owner = THIS_MODULE,
},
.probe = ad5930_probe,
- .remove = __devexit_p(ad5930_remove),
+ .remove = ad5930_remove,
};
module_spi_driver(ad5930_driver);
diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c
index fed39404e34..4e18380c514 100644
--- a/drivers/staging/iio/frequency/ad9832.c
+++ b/drivers/staging/iio/frequency/ad9832.c
@@ -201,7 +201,7 @@ static const struct iio_info ad9832_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit ad9832_probe(struct spi_device *spi)
+static int ad9832_probe(struct spi_device *spi)
{
struct ad9832_platform_data *pdata = spi->dev.platform_data;
struct iio_dev *indio_dev;
@@ -324,7 +324,7 @@ error_put_reg:
return ret;
}
-static int __devexit ad9832_remove(struct spi_device *spi)
+static int ad9832_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ad9832_state *st = iio_priv(indio_dev);
@@ -352,7 +352,7 @@ static struct spi_driver ad9832_driver = {
.owner = THIS_MODULE,
},
.probe = ad9832_probe,
- .remove = __devexit_p(ad9832_remove),
+ .remove = ad9832_remove,
.id_table = ad9832_id,
};
module_spi_driver(ad9832_driver);
diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c
index 1b2dc741d2c..5cba3c01f41 100644
--- a/drivers/staging/iio/frequency/ad9834.c
+++ b/drivers/staging/iio/frequency/ad9834.c
@@ -314,7 +314,7 @@ static const struct iio_info ad9833_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit ad9834_probe(struct spi_device *spi)
+static int ad9834_probe(struct spi_device *spi)
{
struct ad9834_platform_data *pdata = spi->dev.platform_data;
struct ad9834_state *st;
@@ -424,7 +424,7 @@ error_put_reg:
return ret;
}
-static int __devexit ad9834_remove(struct spi_device *spi)
+static int ad9834_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ad9834_state *st = iio_priv(indio_dev);
@@ -454,7 +454,7 @@ static struct spi_driver ad9834_driver = {
.owner = THIS_MODULE,
},
.probe = ad9834_probe,
- .remove = __devexit_p(ad9834_remove),
+ .remove = ad9834_remove,
.id_table = ad9834_id,
};
module_spi_driver(ad9834_driver);
diff --git a/drivers/staging/iio/frequency/ad9850.c b/drivers/staging/iio/frequency/ad9850.c
index 74abee054ac..104f7a4905a 100644
--- a/drivers/staging/iio/frequency/ad9850.c
+++ b/drivers/staging/iio/frequency/ad9850.c
@@ -77,7 +77,7 @@ static const struct iio_info ad9850_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit ad9850_probe(struct spi_device *spi)
+static int ad9850_probe(struct spi_device *spi)
{
struct ad9850_state *st;
struct iio_dev *idev;
@@ -113,7 +113,7 @@ error_ret:
return ret;
}
-static int __devexit ad9850_remove(struct spi_device *spi)
+static int ad9850_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
@@ -127,7 +127,7 @@ static struct spi_driver ad9850_driver = {
.owner = THIS_MODULE,
},
.probe = ad9850_probe,
- .remove = __devexit_p(ad9850_remove),
+ .remove = ad9850_remove,
};
module_spi_driver(ad9850_driver);
diff --git a/drivers/staging/iio/frequency/ad9852.c b/drivers/staging/iio/frequency/ad9852.c
index fd9d14a413a..17ac825b3d2 100644
--- a/drivers/staging/iio/frequency/ad9852.c
+++ b/drivers/staging/iio/frequency/ad9852.c
@@ -226,7 +226,7 @@ static const struct iio_info ad9852_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit ad9852_probe(struct spi_device *spi)
+static int ad9852_probe(struct spi_device *spi)
{
struct ad9852_state *st;
struct iio_dev *idev;
@@ -264,7 +264,7 @@ error_ret:
return ret;
}
-static int __devexit ad9852_remove(struct spi_device *spi)
+static int ad9852_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
@@ -278,7 +278,7 @@ static struct spi_driver ad9852_driver = {
.owner = THIS_MODULE,
},
.probe = ad9852_probe,
- .remove = __devexit_p(ad9852_remove),
+ .remove = ad9852_remove,
};
module_spi_driver(ad9852_driver);
diff --git a/drivers/staging/iio/frequency/ad9910.c b/drivers/staging/iio/frequency/ad9910.c
index 5a7ba305b75..e48f874c1fc 100644
--- a/drivers/staging/iio/frequency/ad9910.c
+++ b/drivers/staging/iio/frequency/ad9910.c
@@ -361,7 +361,7 @@ static const struct iio_info ad9910_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit ad9910_probe(struct spi_device *spi)
+static int ad9910_probe(struct spi_device *spi)
{
struct ad9910_state *st;
struct iio_dev *idev;
@@ -397,7 +397,7 @@ error_ret:
return ret;
}
-static int __devexit ad9910_remove(struct spi_device *spi)
+static int ad9910_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
@@ -411,7 +411,7 @@ static struct spi_driver ad9910_driver = {
.owner = THIS_MODULE,
},
.probe = ad9910_probe,
- .remove = __devexit_p(ad9910_remove),
+ .remove = ad9910_remove,
};
module_spi_driver(ad9910_driver);
diff --git a/drivers/staging/iio/frequency/ad9951.c b/drivers/staging/iio/frequency/ad9951.c
index ba6f49ff09a..8234e3c915c 100644
--- a/drivers/staging/iio/frequency/ad9951.c
+++ b/drivers/staging/iio/frequency/ad9951.c
@@ -170,7 +170,7 @@ static const struct iio_info ad9951_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit ad9951_probe(struct spi_device *spi)
+static int ad9951_probe(struct spi_device *spi)
{
struct ad9951_state *st;
struct iio_dev *idev;
@@ -208,7 +208,7 @@ error_ret:
return ret;
}
-static int __devexit ad9951_remove(struct spi_device *spi)
+static int ad9951_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
@@ -222,7 +222,7 @@ static struct spi_driver ad9951_driver = {
.owner = THIS_MODULE,
},
.probe = ad9951_probe,
- .remove = __devexit_p(ad9951_remove),
+ .remove = ad9951_remove,
};
module_spi_driver(ad9951_driver);
diff --git a/drivers/staging/iio/gyro/Makefile b/drivers/staging/iio/gyro/Makefile
index 9ba5ec15170..1303569e5c8 100644
--- a/drivers/staging/iio/gyro/Makefile
+++ b/drivers/staging/iio/gyro/Makefile
@@ -12,7 +12,6 @@ adis16130-y := adis16130_core.o
obj-$(CONFIG_ADIS16130) += adis16130.o
adis16260-y := adis16260_core.o
-adis16260-$(CONFIG_IIO_BUFFER) += adis16260_ring.o adis16260_trigger.o
obj-$(CONFIG_ADIS16260) += adis16260.o
adis16251-y := adis16251_core.o
diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c
index 87151a7cff0..687c151f984 100644
--- a/drivers/staging/iio/gyro/adis16060_core.c
+++ b/drivers/staging/iio/gyro/adis16060_core.c
@@ -145,7 +145,7 @@ static const struct iio_chan_spec adis16060_channels[] = {
}
};
-static int __devinit adis16060_r_probe(struct spi_device *spi)
+static int adis16060_r_probe(struct spi_device *spi)
{
int ret;
struct adis16060_state *st;
@@ -184,7 +184,7 @@ error_ret:
}
/* fixme, confirm ordering in this function */
-static int __devexit adis16060_r_remove(struct spi_device *spi)
+static int adis16060_r_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
@@ -192,7 +192,7 @@ static int __devexit adis16060_r_remove(struct spi_device *spi)
return 0;
}
-static int __devinit adis16060_w_probe(struct spi_device *spi)
+static int adis16060_w_probe(struct spi_device *spi)
{
int ret;
struct iio_dev *indio_dev = adis16060_iio_dev;
@@ -210,7 +210,7 @@ error_ret:
return ret;
}
-static int __devexit adis16060_w_remove(struct spi_device *spi)
+static int adis16060_w_remove(struct spi_device *spi)
{
return 0;
}
@@ -221,7 +221,7 @@ static struct spi_driver adis16060_r_driver = {
.owner = THIS_MODULE,
},
.probe = adis16060_r_probe,
- .remove = __devexit_p(adis16060_r_remove),
+ .remove = adis16060_r_remove,
};
static struct spi_driver adis16060_w_driver = {
@@ -230,7 +230,7 @@ static struct spi_driver adis16060_w_driver = {
.owner = THIS_MODULE,
},
.probe = adis16060_w_probe,
- .remove = __devexit_p(adis16060_w_remove),
+ .remove = adis16060_w_remove,
};
static __init int adis16060_init(void)
diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c
index a73902573f7..3525a68d6a7 100644
--- a/drivers/staging/iio/gyro/adis16080_core.c
+++ b/drivers/staging/iio/gyro/adis16080_core.c
@@ -138,7 +138,7 @@ static const struct iio_info adis16080_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit adis16080_probe(struct spi_device *spi)
+static int adis16080_probe(struct spi_device *spi)
{
int ret;
struct adis16080_state *st;
@@ -177,7 +177,7 @@ error_ret:
}
/* fixme, confirm ordering in this function */
-static int __devexit adis16080_remove(struct spi_device *spi)
+static int adis16080_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
@@ -191,7 +191,7 @@ static struct spi_driver adis16080_driver = {
.owner = THIS_MODULE,
},
.probe = adis16080_probe,
- .remove = __devexit_p(adis16080_remove),
+ .remove = adis16080_remove,
};
module_spi_driver(adis16080_driver);
diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c
index fbf96b0b6ee..835801ee7e8 100644
--- a/drivers/staging/iio/gyro/adis16130_core.c
+++ b/drivers/staging/iio/gyro/adis16130_core.c
@@ -116,7 +116,7 @@ static const struct iio_info adis16130_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit adis16130_probe(struct spi_device *spi)
+static int adis16130_probe(struct spi_device *spi)
{
int ret;
struct adis16130_state *st;
@@ -154,7 +154,7 @@ error_ret:
}
/* fixme, confirm ordering in this function */
-static int __devexit adis16130_remove(struct spi_device *spi)
+static int adis16130_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
@@ -168,7 +168,7 @@ static struct spi_driver adis16130_driver = {
.owner = THIS_MODULE,
},
.probe = adis16130_probe,
- .remove = __devexit_p(adis16130_remove),
+ .remove = adis16130_remove,
};
module_spi_driver(adis16130_driver);
diff --git a/drivers/staging/iio/gyro/adis16260.h b/drivers/staging/iio/gyro/adis16260.h
index 4c4b25129c6..df3c0b7e954 100644
--- a/drivers/staging/iio/gyro/adis16260.h
+++ b/drivers/staging/iio/gyro/adis16260.h
@@ -1,12 +1,11 @@
#ifndef SPI_ADIS16260_H_
#define SPI_ADIS16260_H_
+
#include "adis16260_platform_data.h"
+#include <linux/iio/imu/adis.h>
#define ADIS16260_STARTUP_DELAY 220 /* ms */
-#define ADIS16260_READ_REG(a) a
-#define ADIS16260_WRITE_REG(a) ((a) | 0x80)
-
#define ADIS16260_FLASH_CNT 0x00 /* Flash memory write count */
#define ADIS16260_SUPPLY_OUT 0x02 /* Power supply measurement */
#define ADIS16260_GYRO_OUT 0x04 /* X-axis gyroscope output */
@@ -34,8 +33,6 @@
* convert to decimal = 16,265/16,260 */
#define ADIS16260_SERIAL_NUM 0x58 /* Serial number */
-#define ADIS16260_OUTPUTS 5
-
#define ADIS16260_ERROR_ACTIVE (1<<14)
#define ADIS16260_NEW_DATA (1<<15)
@@ -60,13 +57,13 @@
/* DIAG_STAT */
#define ADIS16260_DIAG_STAT_ALARM2 (1<<9)
#define ADIS16260_DIAG_STAT_ALARM1 (1<<8)
-#define ADIS16260_DIAG_STAT_FLASH_CHK (1<<6)
-#define ADIS16260_DIAG_STAT_SELF_TEST (1<<5)
-#define ADIS16260_DIAG_STAT_OVERFLOW (1<<4)
-#define ADIS16260_DIAG_STAT_SPI_FAIL (1<<3)
-#define ADIS16260_DIAG_STAT_FLASH_UPT (1<<2)
-#define ADIS16260_DIAG_STAT_POWER_HIGH (1<<1)
-#define ADIS16260_DIAG_STAT_POWER_LOW (1<<0)
+#define ADIS16260_DIAG_STAT_FLASH_CHK_BIT 6
+#define ADIS16260_DIAG_STAT_SELF_TEST_BIT 5
+#define ADIS16260_DIAG_STAT_OVERFLOW_BIT 4
+#define ADIS16260_DIAG_STAT_SPI_FAIL_BIT 3
+#define ADIS16260_DIAG_STAT_FLASH_UPT_BIT 2
+#define ADIS16260_DIAG_STAT_POWER_HIGH_BIT 1
+#define ADIS16260_DIAG_STAT_POWER_LOW_BIT 0
/* GLOB_CMD */
#define ADIS16260_GLOB_CMD_SW_RESET (1<<7)
@@ -75,82 +72,27 @@
#define ADIS16260_GLOB_CMD_FAC_CALIB (1<<1)
#define ADIS16260_GLOB_CMD_AUTO_NULL (1<<0)
-#define ADIS16260_MAX_TX 24
-#define ADIS16260_MAX_RX 24
-
#define ADIS16260_SPI_SLOW (u32)(300 * 1000)
#define ADIS16260_SPI_BURST (u32)(1000 * 1000)
#define ADIS16260_SPI_FAST (u32)(2000 * 1000)
/**
* struct adis16260_state - device instance specific data
- * @us: actual spi_device
- * @trig: data ready trigger registered with iio
- * @buf_lock: mutex to protect tx and rx
* @negate: negate the scale parameter
- * @tx: transmit buffer
- * @rx: receive buffer
**/
struct adis16260_state {
- struct spi_device *us;
- struct iio_trigger *trig;
- struct mutex buf_lock;
- unsigned negate:1;
- u8 tx[ADIS16260_MAX_TX] ____cacheline_aligned;
- u8 rx[ADIS16260_MAX_RX];
+ unsigned negate:1;
+ struct adis adis;
};
-int adis16260_set_irq(struct iio_dev *indio_dev, bool enable);
-
/* At the moment triggers are only used for ring buffer
* filling. This may change!
*/
-#define ADIS16260_SCAN_SUPPLY 0
-#define ADIS16260_SCAN_GYRO 1
+#define ADIS16260_SCAN_GYRO 0
+#define ADIS16260_SCAN_SUPPLY 1
#define ADIS16260_SCAN_AUX_ADC 2
#define ADIS16260_SCAN_TEMP 3
#define ADIS16260_SCAN_ANGL 4
-#ifdef CONFIG_IIO_BUFFER
-void adis16260_remove_trigger(struct iio_dev *indio_dev);
-int adis16260_probe_trigger(struct iio_dev *indio_dev);
-
-ssize_t adis16260_read_data_from_ring(struct device *dev,
- struct device_attribute *attr,
- char *buf);
-
-
-int adis16260_configure_ring(struct iio_dev *indio_dev);
-void adis16260_unconfigure_ring(struct iio_dev *indio_dev);
-
-#else /* CONFIG_IIO_BUFFER */
-
-static inline void adis16260_remove_trigger(struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis16260_probe_trigger(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline ssize_t
-adis16260_read_data_from_ring(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return 0;
-}
-
-static int adis16260_configure_ring(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void adis16260_unconfigure_ring(struct iio_dev *indio_dev)
-{
-}
-
-#endif /* CONFIG_IIO_BUFFER */
#endif /* SPI_ADIS16260_H_ */
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c
index aa964a2d829..6e80b8c768a 100644
--- a/drivers/staging/iio/gyro/adis16260_core.c
+++ b/drivers/staging/iio/gyro/adis16260_core.c
@@ -24,134 +24,13 @@
#include "adis16260.h"
-#define DRIVER_NAME "adis16260"
-
-static int adis16260_check_status(struct iio_dev *indio_dev);
-
-/**
- * adis16260_spi_write_reg_8() - write single byte to a register
- * @indio_dev: iio_dev for the device
- * @reg_address: the address of the register to be written
- * @val: the value to write
- **/
-static int adis16260_spi_write_reg_8(struct iio_dev *indio_dev,
- u8 reg_address,
- u8 val)
-{
- int ret;
- struct adis16260_state *st = iio_priv(indio_dev);
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16260_WRITE_REG(reg_address);
- st->tx[1] = val;
-
- ret = spi_write(st->us, st->tx, 2);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16260_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @indio_dev: iio_dev for the device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: value to be written
- **/
-static int adis16260_spi_write_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 value)
-{
- int ret;
- struct spi_message msg;
- struct adis16260_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- .delay_usecs = 20,
- }, {
- .tx_buf = st->tx + 2,
- .bits_per_word = 8,
- .len = 2,
- .delay_usecs = 20,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16260_WRITE_REG(lower_reg_address);
- st->tx[1] = value & 0xFF;
- st->tx[2] = ADIS16260_WRITE_REG(lower_reg_address + 1);
- st->tx[3] = (value >> 8) & 0xFF;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16260_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @indio_dev: iio_dev for the device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: somewhere to pass back the value read
- **/
-static int adis16260_spi_read_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 *val)
-{
- struct spi_message msg;
- struct adis16260_state *st = iio_priv(indio_dev);
- int ret;
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- .delay_usecs = 30,
- }, {
- .rx_buf = st->rx,
- .bits_per_word = 8,
- .len = 2,
- .delay_usecs = 30,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16260_READ_REG(lower_reg_address);
- st->tx[1] = 0;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- if (ret) {
- dev_err(&st->us->dev,
- "problem when reading 16 bit register 0x%02X",
- lower_reg_address);
- goto error_ret;
- }
- *val = (st->rx[0] << 8) | st->rx[1];
-
-error_ret:
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
static ssize_t adis16260_read_frequency_available(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct adis16260_state *st = iio_priv(indio_dev);
- if (spi_get_device_id(st->us)->driver_data)
+ if (spi_get_device_id(st->adis.spi)->driver_data)
return sprintf(buf, "%s\n", "0.129 ~ 256");
else
return sprintf(buf, "%s\n", "256 2048");
@@ -166,13 +45,11 @@ static ssize_t adis16260_read_frequency(struct device *dev,
int ret, len = 0;
u16 t;
int sps;
- ret = adis16260_spi_read_reg_16(indio_dev,
- ADIS16260_SMPL_PRD,
- &t);
+ ret = adis_read_reg_16(&st->adis, ADIS16260_SMPL_PRD, &t);
if (ret)
return ret;
- if (spi_get_device_id(st->us)->driver_data) /* If an adis16251 */
+ if (spi_get_device_id(st->adis.spi)->driver_data) /* If an adis16251 */
sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 8 : 256;
else
sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 66 : 2048;
@@ -199,7 +76,7 @@ static ssize_t adis16260_write_frequency(struct device *dev,
return -EINVAL;
mutex_lock(&indio_dev->mlock);
- if (spi_get_device_id(st->us)) {
+ if (spi_get_device_id(st->adis.spi)->driver_data) {
t = (256 / val);
if (t > 0)
t--;
@@ -211,10 +88,10 @@ static ssize_t adis16260_write_frequency(struct device *dev,
t &= ADIS16260_SMPL_PRD_DIV_MASK;
}
if ((t & ADIS16260_SMPL_PRD_DIV_MASK) >= 0x0A)
- st->us->max_speed_hz = ADIS16260_SPI_SLOW;
+ st->adis.spi->max_speed_hz = ADIS16260_SPI_SLOW;
else
- st->us->max_speed_hz = ADIS16260_SPI_FAST;
- ret = adis16260_spi_write_reg_8(indio_dev,
+ st->adis.spi->max_speed_hz = ADIS16260_SPI_FAST;
+ ret = adis_write_reg_8(&st->adis,
ADIS16260_SMPL_PRD,
t);
@@ -223,140 +100,20 @@ static ssize_t adis16260_write_frequency(struct device *dev,
return ret ? ret : len;
}
-static int adis16260_reset(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16260_spi_write_reg_8(indio_dev,
- ADIS16260_GLOB_CMD,
- ADIS16260_GLOB_CMD_SW_RESET);
- if (ret)
- dev_err(&indio_dev->dev, "problem resetting device");
-
- return ret;
-}
-
-int adis16260_set_irq(struct iio_dev *indio_dev, bool enable)
-{
- int ret;
- u16 msc;
- ret = adis16260_spi_read_reg_16(indio_dev, ADIS16260_MSC_CTRL, &msc);
- if (ret)
- goto error_ret;
-
- msc |= ADIS16260_MSC_CTRL_DATA_RDY_POL_HIGH;
- if (enable)
- msc |= ADIS16260_MSC_CTRL_DATA_RDY_EN;
- else
- msc &= ~ADIS16260_MSC_CTRL_DATA_RDY_EN;
-
- ret = adis16260_spi_write_reg_16(indio_dev, ADIS16260_MSC_CTRL, msc);
- if (ret)
- goto error_ret;
-
-error_ret:
- return ret;
-}
-
/* Power down the device */
static int adis16260_stop_device(struct iio_dev *indio_dev)
{
+ struct adis16260_state *st = iio_priv(indio_dev);
int ret;
u16 val = ADIS16260_SLP_CNT_POWER_OFF;
- ret = adis16260_spi_write_reg_16(indio_dev, ADIS16260_SLP_CNT, val);
+ ret = adis_write_reg_16(&st->adis, ADIS16260_SLP_CNT, val);
if (ret)
dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT");
return ret;
}
-static int adis16260_self_test(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16260_spi_write_reg_16(indio_dev,
- ADIS16260_MSC_CTRL,
- ADIS16260_MSC_CTRL_MEM_TEST);
- if (ret) {
- dev_err(&indio_dev->dev, "problem starting self test");
- goto err_ret;
- }
-
- adis16260_check_status(indio_dev);
-
-err_ret:
- return ret;
-}
-
-static int adis16260_check_status(struct iio_dev *indio_dev)
-{
- u16 status;
- int ret;
- struct device *dev = &indio_dev->dev;
-
- ret = adis16260_spi_read_reg_16(indio_dev,
- ADIS16260_DIAG_STAT,
- &status);
-
- if (ret < 0) {
- dev_err(dev, "Reading status failed\n");
- goto error_ret;
- }
- ret = status & 0x7F;
- if (status & ADIS16260_DIAG_STAT_FLASH_CHK)
- dev_err(dev, "Flash checksum error\n");
- if (status & ADIS16260_DIAG_STAT_SELF_TEST)
- dev_err(dev, "Self test error\n");
- if (status & ADIS16260_DIAG_STAT_OVERFLOW)
- dev_err(dev, "Sensor overrange\n");
- if (status & ADIS16260_DIAG_STAT_SPI_FAIL)
- dev_err(dev, "SPI failure\n");
- if (status & ADIS16260_DIAG_STAT_FLASH_UPT)
- dev_err(dev, "Flash update failed\n");
- if (status & ADIS16260_DIAG_STAT_POWER_HIGH)
- dev_err(dev, "Power supply above 5.25V\n");
- if (status & ADIS16260_DIAG_STAT_POWER_LOW)
- dev_err(dev, "Power supply below 4.75V\n");
-
-error_ret:
- return ret;
-}
-
-static int adis16260_initial_setup(struct iio_dev *indio_dev)
-{
- int ret;
- struct device *dev = &indio_dev->dev;
-
- /* Disable IRQ */
- ret = adis16260_set_irq(indio_dev, false);
- if (ret) {
- dev_err(dev, "disable irq failed");
- goto err_ret;
- }
-
- /* Do self test */
- ret = adis16260_self_test(indio_dev);
- if (ret) {
- dev_err(dev, "self test failure");
- goto err_ret;
- }
-
- /* Read status register to check the result */
- ret = adis16260_check_status(indio_dev);
- if (ret) {
- adis16260_reset(indio_dev);
- dev_err(dev, "device not playing ball -> reset");
- msleep(ADIS16260_STARTUP_DELAY);
- ret = adis16260_check_status(indio_dev);
- if (ret) {
- dev_err(dev, "giving up");
- goto err_ret;
- }
- }
-
-err_ret:
- return ret;
-}
-
static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
adis16260_read_frequency,
adis16260_write_frequency);
@@ -364,100 +121,26 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
static IIO_DEVICE_ATTR(sampling_frequency_available,
S_IRUGO, adis16260_read_frequency_available, NULL, 0);
-enum adis16260_channel {
- gyro,
- temp,
- in_supply,
- in_aux,
- angle,
-};
#define ADIS16260_GYRO_CHANNEL_SET(axis, mod) \
- struct iio_chan_spec adis16260_channels_##axis[] = { \
- { \
- .type = IIO_ANGL_VEL, \
- .modified = 1, \
- .channel2 = mod, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \
- IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
- .address = gyro, \
- .scan_index = ADIS16260_SCAN_GYRO, \
- .scan_type = { \
- .sign = 's', \
- .realbits = 14, \
- .storagebits = 16, \
- }, \
- }, { \
- .type = IIO_ANGL, \
- .modified = 1, \
- .channel2 = mod, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \
- .address = angle, \
- .scan_index = ADIS16260_SCAN_ANGL, \
- .scan_type = { \
- .sign = 'u', \
- .realbits = 14, \
- .storagebits = 16, \
- }, \
- }, { \
- .type = IIO_TEMP, \
- .indexed = 1, \
- .channel = 0, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
- .address = temp, \
- .scan_index = ADIS16260_SCAN_TEMP, \
- .scan_type = { \
- .sign = 'u', \
- .realbits = 12, \
- .storagebits = 16, \
- }, \
- }, { \
- .type = IIO_VOLTAGE, \
- .indexed = 1, \
- .channel = 0, \
- .extend_name = "supply", \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
- .address = in_supply, \
- .scan_index = ADIS16260_SCAN_SUPPLY, \
- .scan_type = { \
- .sign = 'u', \
- .realbits = 12, \
- .storagebits = 16, \
- }, \
- }, { \
- .type = IIO_VOLTAGE, \
- .indexed = 1, \
- .channel = 1, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
- .address = in_aux, \
- .scan_index = ADIS16260_SCAN_AUX_ADC, \
- .scan_type = { \
- .sign = 'u', \
- .realbits = 12, \
- .storagebits = 16, \
- }, \
- }, \
- IIO_CHAN_SOFT_TIMESTAMP(5), \
- }
+struct iio_chan_spec adis16260_channels_##axis[] = { \
+ ADIS_GYRO_CHAN(mod, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO, \
+ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \
+ IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, 14), \
+ ADIS_INCLI_CHAN(mod, ADIS16260_ANGL_OUT, ADIS16260_SCAN_ANGL, 0, 14), \
+ ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP, 12), \
+ ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY, 12), \
+ ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC, 12), \
+ IIO_CHAN_SOFT_TIMESTAMP(5), \
+}
+
+static const ADIS16260_GYRO_CHANNEL_SET(x, X);
+static const ADIS16260_GYRO_CHANNEL_SET(y, Y);
+static const ADIS16260_GYRO_CHANNEL_SET(z, Z);
-static const ADIS16260_GYRO_CHANNEL_SET(x, IIO_MOD_X);
-static const ADIS16260_GYRO_CHANNEL_SET(y, IIO_MOD_Y);
-static const ADIS16260_GYRO_CHANNEL_SET(z, IIO_MOD_Z);
-
-static const u8 adis16260_addresses[5][3] = {
- [gyro] = { ADIS16260_GYRO_OUT,
- ADIS16260_GYRO_OFF,
- ADIS16260_GYRO_SCALE },
- [angle] = { ADIS16260_ANGL_OUT },
- [in_supply] = { ADIS16260_SUPPLY_OUT },
- [in_aux] = { ADIS16260_AUX_ADC },
- [temp] = { ADIS16260_TEMP_OUT },
+static const u8 adis16260_addresses[][2] = {
+ [ADIS16260_SCAN_GYRO] = { ADIS16260_GYRO_OFF, ADIS16260_GYRO_SCALE },
};
+
static int adis16260_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2,
@@ -471,34 +154,13 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
- mutex_lock(&indio_dev->mlock);
- addr = adis16260_addresses[chan->address][0];
- ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
-
- if (val16 & ADIS16260_ERROR_ACTIVE) {
- ret = adis16260_check_status(indio_dev);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
- }
- val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
- if (chan->scan_type.sign == 's')
- val16 = (s16)(val16 <<
- (16 - chan->scan_type.realbits)) >>
- (16 - chan->scan_type.realbits);
- *val = val16;
- mutex_unlock(&indio_dev->mlock);
- return IIO_VAL_INT;
+ return adis_single_conversion(indio_dev, chan,
+ ADIS16260_ERROR_ACTIVE, val);
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_ANGL_VEL:
*val = 0;
- if (spi_get_device_id(st->us)->driver_data) {
+ if (spi_get_device_id(st->adis.spi)->driver_data) {
/* 0.01832 degree / sec */
*val2 = IIO_DEGREE_TO_RAD(18320);
} else {
@@ -533,10 +195,10 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
break;
default:
return -EINVAL;
- };
+ }
mutex_lock(&indio_dev->mlock);
- addr = adis16260_addresses[chan->address][1];
- ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16);
+ addr = adis16260_addresses[chan->scan_index][0];
+ ret = adis_read_reg_16(&st->adis, addr, &val16);
if (ret) {
mutex_unlock(&indio_dev->mlock);
return ret;
@@ -553,10 +215,10 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
break;
default:
return -EINVAL;
- };
+ }
mutex_lock(&indio_dev->mlock);
- addr = adis16260_addresses[chan->address][2];
- ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16);
+ addr = adis16260_addresses[chan->scan_index][1];
+ ret = adis_read_reg_16(&st->adis, addr, &val16);
if (ret) {
mutex_unlock(&indio_dev->mlock);
return ret;
@@ -574,18 +236,19 @@ static int adis16260_write_raw(struct iio_dev *indio_dev,
int val2,
long mask)
{
+ struct adis16260_state *st = iio_priv(indio_dev);
int bits = 12;
s16 val16;
u8 addr;
switch (mask) {
case IIO_CHAN_INFO_CALIBBIAS:
val16 = val & ((1 << bits) - 1);
- addr = adis16260_addresses[chan->address][1];
- return adis16260_spi_write_reg_16(indio_dev, addr, val16);
+ addr = adis16260_addresses[chan->scan_index][0];
+ return adis_write_reg_16(&st->adis, addr, val16);
case IIO_CHAN_INFO_CALIBSCALE:
val16 = val & ((1 << bits) - 1);
- addr = adis16260_addresses[chan->address][2];
- return adis16260_spi_write_reg_16(indio_dev, addr, val16);
+ addr = adis16260_addresses[chan->scan_index][1];
+ return adis_write_reg_16(&st->adis, addr, val16);
}
return -EINVAL;
}
@@ -604,10 +267,41 @@ static const struct iio_info adis16260_info = {
.attrs = &adis16260_attribute_group,
.read_raw = &adis16260_read_raw,
.write_raw = &adis16260_write_raw,
+ .update_scan_mode = adis_update_scan_mode,
.driver_module = THIS_MODULE,
};
-static int __devinit adis16260_probe(struct spi_device *spi)
+static const char * const adis1620_status_error_msgs[] = {
+ [ADIS16260_DIAG_STAT_FLASH_CHK_BIT] = "Flash checksum error",
+ [ADIS16260_DIAG_STAT_SELF_TEST_BIT] = "Self test error",
+ [ADIS16260_DIAG_STAT_OVERFLOW_BIT] = "Sensor overrange",
+ [ADIS16260_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure",
+ [ADIS16260_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed",
+ [ADIS16260_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 5.25",
+ [ADIS16260_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 4.75",
+};
+
+static const struct adis_data adis16260_data = {
+ .write_delay = 30,
+ .read_delay = 30,
+ .msc_ctrl_reg = ADIS16260_MSC_CTRL,
+ .glob_cmd_reg = ADIS16260_GLOB_CMD,
+ .diag_stat_reg = ADIS16260_DIAG_STAT,
+
+ .self_test_mask = ADIS16260_MSC_CTRL_MEM_TEST,
+ .startup_delay = ADIS16260_STARTUP_DELAY,
+
+ .status_error_msgs = adis1620_status_error_msgs,
+ .status_error_mask = BIT(ADIS16260_DIAG_STAT_FLASH_CHK_BIT) |
+ BIT(ADIS16260_DIAG_STAT_SELF_TEST_BIT) |
+ BIT(ADIS16260_DIAG_STAT_OVERFLOW_BIT) |
+ BIT(ADIS16260_DIAG_STAT_SPI_FAIL_BIT) |
+ BIT(ADIS16260_DIAG_STAT_FLASH_UPT_BIT) |
+ BIT(ADIS16260_DIAG_STAT_POWER_HIGH_BIT) |
+ BIT(ADIS16260_DIAG_STAT_POWER_LOW_BIT),
+};
+
+static int adis16260_probe(struct spi_device *spi)
{
int ret;
struct adis16260_platform_data *pd = spi->dev.platform_data;
@@ -626,10 +320,7 @@ static int __devinit adis16260_probe(struct spi_device *spi)
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
- st->us = spi;
- mutex_init(&st->buf_lock);
-
- indio_dev->name = spi_get_device_id(st->us)->name;
+ indio_dev->name = spi_get_device_id(spi)->name;
indio_dev->dev.parent = &spi->dev;
indio_dev->info = &adis16260_info;
indio_dev->num_channels
@@ -653,17 +344,14 @@ static int __devinit adis16260_probe(struct spi_device *spi)
indio_dev->num_channels = ARRAY_SIZE(adis16260_channels_x);
indio_dev->modes = INDIO_DIRECT_MODE;
- ret = adis16260_configure_ring(indio_dev);
+ ret = adis_init(&st->adis, indio_dev, spi, &adis16260_data);
+ if (ret)
+ goto error_free_dev;
+
+ ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
if (ret)
goto error_free_dev;
- ret = iio_buffer_register(indio_dev,
- indio_dev->channels,
- ARRAY_SIZE(adis16260_channels_x));
- if (ret) {
- printk(KERN_ERR "failed to initialize the ring\n");
- goto error_unreg_ring_funcs;
- }
if (indio_dev->buffer) {
/* Set default scan mode */
iio_scan_mask_set(indio_dev, indio_dev->buffer,
@@ -677,43 +365,33 @@ static int __devinit adis16260_probe(struct spi_device *spi)
iio_scan_mask_set(indio_dev, indio_dev->buffer,
ADIS16260_SCAN_ANGL);
}
- if (spi->irq) {
- ret = adis16260_probe_trigger(indio_dev);
- if (ret)
- goto error_uninitialize_ring;
- }
/* Get the device into a sane initial state */
- ret = adis16260_initial_setup(indio_dev);
+ ret = adis_initial_startup(&st->adis);
if (ret)
- goto error_remove_trigger;
+ goto error_cleanup_buffer_trigger;
ret = iio_device_register(indio_dev);
if (ret)
- goto error_remove_trigger;
+ goto error_cleanup_buffer_trigger;
return 0;
-error_remove_trigger:
- adis16260_remove_trigger(indio_dev);
-error_uninitialize_ring:
- iio_buffer_unregister(indio_dev);
-error_unreg_ring_funcs:
- adis16260_unconfigure_ring(indio_dev);
+error_cleanup_buffer_trigger:
+ adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
-static int __devexit adis16260_remove(struct spi_device *spi)
+static int adis16260_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct adis16260_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
adis16260_stop_device(indio_dev);
- adis16260_remove_trigger(indio_dev);
- iio_buffer_unregister(indio_dev);
- adis16260_unconfigure_ring(indio_dev);
+ adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
iio_device_free(indio_dev);
return 0;
@@ -739,7 +417,7 @@ static struct spi_driver adis16260_driver = {
.owner = THIS_MODULE,
},
.probe = adis16260_probe,
- .remove = __devexit_p(adis16260_remove),
+ .remove = adis16260_remove,
.id_table = adis16260_id,
};
module_spi_driver(adis16260_driver);
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
deleted file mode 100644
index e294cb49736..00000000000
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ /dev/null
@@ -1,136 +0,0 @@
-#include <linux/export.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-
-#include <linux/iio/iio.h>
-#include "../ring_sw.h"
-#include <linux/iio/trigger_consumer.h>
-#include "adis16260.h"
-
-/**
- * adis16260_read_ring_data() read data registers which will be placed into ring
- * @indio_dev: the IIO device
- * @rx: somewhere to pass back the value read
- **/
-static int adis16260_read_ring_data(struct iio_dev *indio_dev, u8 *rx)
-{
- struct spi_message msg;
- struct adis16260_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[ADIS16260_OUTPUTS + 1];
- int ret;
- int i;
-
- mutex_lock(&st->buf_lock);
-
- spi_message_init(&msg);
-
- memset(xfers, 0, sizeof(xfers));
- for (i = 0; i <= ADIS16260_OUTPUTS; i++) {
- xfers[i].bits_per_word = 8;
- xfers[i].cs_change = 1;
- xfers[i].len = 2;
- xfers[i].delay_usecs = 30;
- xfers[i].tx_buf = st->tx + 2 * i;
- if (i < 2) /* SUPPLY_OUT:0x02 GYRO_OUT:0x04 */
- st->tx[2 * i]
- = ADIS16260_READ_REG(ADIS16260_SUPPLY_OUT
- + 2 * i);
- else /* 0x06 to 0x09 is reserved */
- st->tx[2 * i]
- = ADIS16260_READ_REG(ADIS16260_SUPPLY_OUT
- + 2 * i + 4);
- st->tx[2 * i + 1] = 0;
- if (i >= 1)
- xfers[i].rx_buf = rx + 2 * (i - 1);
- spi_message_add_tail(&xfers[i], &msg);
- }
-
- ret = spi_sync(st->us, &msg);
- if (ret)
- dev_err(&st->us->dev, "problem when burst reading");
-
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-static irqreturn_t adis16260_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct adis16260_state *st = iio_priv(indio_dev);
- int i = 0;
- s16 *data;
-
- data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
- if (data == NULL) {
- dev_err(&st->us->dev, "memory alloc failed in ring bh");
- goto done;
- }
-
- if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
- adis16260_read_ring_data(indio_dev, st->rx) >= 0)
- for (; i < bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength); i++)
- data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
-
- /* Guaranteed to be aligned with 8 byte boundary */
- if (indio_dev->scan_timestamp)
- *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
-
- iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
-
- kfree(data);
-done:
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-void adis16260_unconfigure_ring(struct iio_dev *indio_dev)
-{
- iio_dealloc_pollfunc(indio_dev->pollfunc);
- iio_sw_rb_free(indio_dev->buffer);
-}
-
-static const struct iio_buffer_setup_ops adis16260_ring_setup_ops = {
- .preenable = &iio_sw_buffer_preenable,
- .postenable = &iio_triggered_buffer_postenable,
- .predisable = &iio_triggered_buffer_predisable,
-};
-
-int adis16260_configure_ring(struct iio_dev *indio_dev)
-{
- int ret = 0;
- struct iio_buffer *ring;
-
- ring = iio_sw_rb_allocate(indio_dev);
- if (!ring) {
- ret = -ENOMEM;
- return ret;
- }
- indio_dev->buffer = ring;
- ring->scan_timestamp = true;
- indio_dev->setup_ops = &adis16260_ring_setup_ops;
-
- indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
- &adis16260_trigger_handler,
- IRQF_ONESHOT,
- indio_dev,
- "adis16260_consumer%d",
- indio_dev->id);
- if (indio_dev->pollfunc == NULL) {
- ret = -ENOMEM;
- goto error_iio_sw_rb_free;
- }
-
- indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
- return 0;
-
-error_iio_sw_rb_free:
- iio_sw_rb_free(indio_dev->buffer);
- return ret;
-}
diff --git a/drivers/staging/iio/gyro/adis16260_trigger.c b/drivers/staging/iio/gyro/adis16260_trigger.c
deleted file mode 100644
index 034559e4d5b..00000000000
--- a/drivers/staging/iio/gyro/adis16260_trigger.c
+++ /dev/null
@@ -1,75 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/export.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/trigger.h>
-#include "adis16260.h"
-
-/**
- * adis16260_data_rdy_trigger_set_state() set datardy interrupt state
- **/
-static int adis16260_data_rdy_trigger_set_state(struct iio_trigger *trig,
- bool state)
-{
- struct iio_dev *indio_dev = trig->private_data;
-
- dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
- return adis16260_set_irq(indio_dev, state);
-}
-
-static const struct iio_trigger_ops adis16260_trigger_ops = {
- .owner = THIS_MODULE,
- .set_trigger_state = &adis16260_data_rdy_trigger_set_state,
-};
-
-int adis16260_probe_trigger(struct iio_dev *indio_dev)
-{
- int ret;
- struct adis16260_state *st = iio_priv(indio_dev);
-
- st->trig = iio_trigger_alloc("%s-dev%d",
- spi_get_device_id(st->us)->name,
- indio_dev->id);
- if (st->trig == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
-
- ret = request_irq(st->us->irq,
- &iio_trigger_generic_data_rdy_poll,
- IRQF_TRIGGER_RISING,
- "adis16260",
- st->trig);
- if (ret)
- goto error_free_trig;
-
- st->trig->dev.parent = &st->us->dev;
- st->trig->ops = &adis16260_trigger_ops;
- st->trig->private_data = indio_dev;
- ret = iio_trigger_register(st->trig);
-
- /* select default trigger */
- indio_dev->trig = st->trig;
- if (ret)
- goto error_free_irq;
-
- return 0;
-
-error_free_irq:
- free_irq(st->us->irq, st->trig);
-error_free_trig:
- iio_trigger_free(st->trig);
-error_ret:
- return ret;
-}
-
-void adis16260_remove_trigger(struct iio_dev *indio_dev)
-{
- struct adis16260_state *st = iio_priv(indio_dev);
-
- iio_trigger_unregister(st->trig);
- free_irq(st->us->irq, st->trig);
- iio_trigger_free(st->trig);
-}
diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/staging/iio/gyro/adxrs450_core.c
index d93527d1591..f0ce81da8ac 100644
--- a/drivers/staging/iio/gyro/adxrs450_core.c
+++ b/drivers/staging/iio/gyro/adxrs450_core.c
@@ -365,7 +365,7 @@ static const struct iio_info adxrs450_info = {
.write_raw = &adxrs450_write_raw,
};
-static int __devinit adxrs450_probe(struct spi_device *spi)
+static int adxrs450_probe(struct spi_device *spi)
{
int ret;
struct adxrs450_state *st;
@@ -409,7 +409,7 @@ error_ret:
return ret;
}
-static int __devexit adxrs450_remove(struct spi_device *spi)
+static int adxrs450_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
@@ -430,7 +430,7 @@ static struct spi_driver adxrs450_driver = {
.owner = THIS_MODULE,
},
.probe = adxrs450_probe,
- .remove = __devexit_p(adxrs450_remove),
+ .remove = adxrs450_remove,
.id_table = adxrs450_id,
};
module_spi_driver(adxrs450_driver);
diff --git a/drivers/staging/iio/iio_dummy_evgen.c b/drivers/staging/iio/iio_dummy_evgen.c
index 74e24e8aa87..132d278c501 100644
--- a/drivers/staging/iio/iio_dummy_evgen.c
+++ b/drivers/staging/iio/iio_dummy_evgen.c
@@ -108,7 +108,7 @@ int iio_dummy_evgen_get_irq(void)
mutex_lock(&iio_evgen->lock);
for (i = 0; i < IIO_EVENTGEN_NO; i++)
- if (iio_evgen->inuse[i] == false) {
+ if (!iio_evgen->inuse[i]) {
ret = iio_evgen->base + i;
iio_evgen->inuse[i] = true;
break;
diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c
index 5d491227e01..c7a5f97576c 100644
--- a/drivers/staging/iio/iio_hwmon.c
+++ b/drivers/staging/iio/iio_hwmon.c
@@ -69,7 +69,7 @@ static void iio_hwmon_free_attrs(struct iio_hwmon_state *st)
}
}
-static int __devinit iio_hwmon_probe(struct platform_device *pdev)
+static int iio_hwmon_probe(struct platform_device *pdev)
{
struct iio_hwmon_state *st;
struct sensor_device_attribute *a;
@@ -170,7 +170,7 @@ error_ret:
return ret;
}
-static int __devexit iio_hwmon_remove(struct platform_device *pdev)
+static int iio_hwmon_remove(struct platform_device *pdev)
{
struct iio_hwmon_state *st = platform_get_drvdata(pdev);
@@ -189,7 +189,7 @@ static struct platform_driver __refdata iio_hwmon_driver = {
.owner = THIS_MODULE,
},
.probe = iio_hwmon_probe,
- .remove = __devexit_p(iio_hwmon_remove),
+ .remove = iio_hwmon_remove,
};
module_platform_driver(iio_hwmon_driver);
diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
index dc6c728ea47..a865adf8193 100644
--- a/drivers/staging/iio/iio_simple_dummy.c
+++ b/drivers/staging/iio/iio_simple_dummy.c
@@ -378,7 +378,7 @@ static int iio_dummy_init_device(struct iio_dev *indio_dev)
* const struct i2c_device_id *id)
* SPI: iio_dummy_probe(struct spi_device *spi)
*/
-static int __devinit iio_dummy_probe(int index)
+static int iio_dummy_probe(int index)
{
int ret;
struct iio_dev *indio_dev;
diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c
index 697d9700db2..dee16f0e757 100644
--- a/drivers/staging/iio/iio_simple_dummy_buffer.c
+++ b/drivers/staging/iio/iio_simple_dummy_buffer.c
@@ -46,7 +46,6 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
- struct iio_buffer *buffer = indio_dev->buffer;
int len = 0;
u16 *data;
@@ -76,7 +75,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
i < bitmap_weight(indio_dev->active_scan_mask,
indio_dev->masklength);
i++, j++) {
- j = find_next_bit(buffer->scan_mask,
+ j = find_next_bit(indio_dev->active_scan_mask,
indio_dev->masklength, j);
/* random access read from the 'device' */
data[i] = fakedata[j];
@@ -87,7 +86,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
= iio_get_time_ns();
- iio_push_to_buffer(buffer, (u8 *)data);
+ iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data);
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index de21d47f33e..779243d24de 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -647,7 +647,6 @@ static void ad5933_work(struct work_struct *work)
struct ad5933_state *st = container_of(work,
struct ad5933_state, work.work);
struct iio_dev *indio_dev = i2c_get_clientdata(st->client);
- struct iio_buffer *ring = indio_dev->buffer;
signed short buf[2];
unsigned char status;
@@ -677,8 +676,7 @@ static void ad5933_work(struct work_struct *work)
} else {
buf[0] = be16_to_cpu(buf[0]);
}
- /* save datum to the ring */
- iio_push_to_buffer(ring, (u8 *)buf);
+ iio_push_to_buffers(indio_dev, (u8 *)buf);
} else {
/* no data available - try again later */
schedule_delayed_work(&st->work, st->poll_time_jiffies);
@@ -699,7 +697,7 @@ static void ad5933_work(struct work_struct *work)
mutex_unlock(&indio_dev->mlock);
}
-static int __devinit ad5933_probe(struct i2c_client *client,
+static int ad5933_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret, voltage_uv = 0;
@@ -789,7 +787,7 @@ error_put_reg:
return ret;
}
-static __devexit int ad5933_remove(struct i2c_client *client)
+static int ad5933_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct ad5933_state *st = iio_priv(indio_dev);
@@ -819,7 +817,7 @@ static struct i2c_driver ad5933_driver = {
.name = "ad5933",
},
.probe = ad5933_probe,
- .remove = __devexit_p(ad5933_remove),
+ .remove = ad5933_remove,
.id_table = ad5933_id,
};
module_i2c_driver(ad5933_driver);
diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h
index 77c601da184..7a105e96646 100644
--- a/drivers/staging/iio/imu/adis16400.h
+++ b/drivers/staging/iio/imu/adis16400.h
@@ -123,6 +123,9 @@
/* SLP_CNT */
#define ADIS16400_SLP_CNT_POWER_OFF (1<<8)
+#define ADIS16334_RATE_DIV_SHIFT 8
+#define ADIS16334_RATE_INT_CLK BIT(0)
+
#define ADIS16400_MAX_TX 24
#define ADIS16400_MAX_RX 24
@@ -130,18 +133,21 @@
#define ADIS16400_SPI_BURST (u32)(1000 * 1000)
#define ADIS16400_SPI_FAST (u32)(2000 * 1000)
-#define ADIS16400_HAS_PROD_ID 1
-#define ADIS16400_NO_BURST 2
+#define ADIS16400_HAS_PROD_ID BIT(0)
+#define ADIS16400_NO_BURST BIT(1)
+#define ADIS16400_HAS_SLOW_MODE BIT(2)
+
struct adis16400_chip_info {
const struct iio_chan_spec *channels;
const int num_channels;
- const int product_id;
const long flags;
unsigned int gyro_scale_micro;
unsigned int accel_scale_micro;
int temp_scale_nano;
int temp_offset;
unsigned long default_scan_mask;
+ int (*set_freq)(struct iio_dev *indio_dev, unsigned int freq);
+ int (*get_freq)(struct iio_dev *indio_dev);
};
/**
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index 3144a7b1e1c..9c8f5ab7e13 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -38,7 +38,6 @@ enum adis16400_chip_variant {
ADIS16360,
ADIS16362,
ADIS16364,
- ADIS16365,
ADIS16400,
};
@@ -161,10 +160,39 @@ error_ret:
return ret;
}
-static int adis16400_get_freq(struct iio_dev *indio_dev)
+static int adis16334_get_freq(struct iio_dev *indio_dev)
{
+ int ret;
u16 t;
+
+ ret = adis16400_spi_read_reg_16(indio_dev, ADIS16400_SMPL_PRD, &t);
+ if (ret < 0)
+ return ret;
+
+ t >>= ADIS16334_RATE_DIV_SHIFT;
+
+ return (8192 >> t) / 10;
+}
+
+static int adis16334_set_freq(struct iio_dev *indio_dev, unsigned int freq)
+{
+ unsigned int t;
+
+ t = ilog2(8192 / (freq * 10));
+
+ if (t > 0x31)
+ t = 0x31;
+
+ t <<= ADIS16334_RATE_DIV_SHIFT;
+ t |= ADIS16334_RATE_INT_CLK;
+
+ return adis16400_spi_write_reg_16(indio_dev, ADIS16400_SMPL_PRD, t);
+}
+
+static int adis16400_get_freq(struct iio_dev *indio_dev)
+{
int sps, ret;
+ u16 t;
ret = adis16400_spi_read_reg_16(indio_dev, ADIS16400_SMPL_PRD, &t);
if (ret < 0)
@@ -175,13 +203,33 @@ static int adis16400_get_freq(struct iio_dev *indio_dev)
return sps;
}
+static int adis16400_set_freq(struct iio_dev *indio_dev, unsigned int freq)
+{
+ struct adis16400_state *st = iio_priv(indio_dev);
+ unsigned int t;
+
+ t = 1638 / freq;
+ if (t > 0)
+ t--;
+ t &= ADIS16400_SMPL_PRD_DIV_MASK;
+ if ((t & ADIS16400_SMPL_PRD_DIV_MASK) >= 0x0A)
+ st->us->max_speed_hz = ADIS16400_SPI_SLOW;
+ else
+ st->us->max_speed_hz = ADIS16400_SPI_FAST;
+
+ return adis16400_spi_write_reg_8(indio_dev,
+ ADIS16400_SMPL_PRD, t);
+}
+
static ssize_t adis16400_read_frequency(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct adis16400_state *st = iio_priv(indio_dev);
int ret, len = 0;
- ret = adis16400_get_freq(indio_dev);
+
+ ret = st->variant->get_freq(indio_dev);
if (ret < 0)
return ret;
len = sprintf(buf, "%d SPS\n", ret);
@@ -229,7 +277,6 @@ static ssize_t adis16400_write_frequency(struct device *dev,
struct adis16400_state *st = iio_priv(indio_dev);
long val;
int ret;
- u8 t;
ret = strict_strtol(buf, 10, &val);
if (ret)
@@ -239,18 +286,7 @@ static ssize_t adis16400_write_frequency(struct device *dev,
mutex_lock(&indio_dev->mlock);
- t = (1638 / val);
- if (t > 0)
- t--;
- t &= ADIS16400_SMPL_PRD_DIV_MASK;
- if ((t & ADIS16400_SMPL_PRD_DIV_MASK) >= 0x0A)
- st->us->max_speed_hz = ADIS16400_SPI_SLOW;
- else
- st->us->max_speed_hz = ADIS16400_SPI_FAST;
-
- ret = adis16400_spi_write_reg_8(indio_dev,
- ADIS16400_SMPL_PRD,
- t);
+ st->variant->set_freq(indio_dev, val);
/* Also update the filter */
mutex_unlock(&indio_dev->mlock);
@@ -378,10 +414,14 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev)
{
int ret;
u16 prod_id, smp_prd;
+ unsigned int device_id;
struct adis16400_state *st = iio_priv(indio_dev);
- /* use low spi speed for init */
- st->us->max_speed_hz = ADIS16400_SPI_SLOW;
+ /* use low spi speed for init if the device has a slow mode */
+ if (st->variant->flags & ADIS16400_HAS_SLOW_MODE)
+ st->us->max_speed_hz = ADIS16400_SPI_SLOW;
+ else
+ st->us->max_speed_hz = ADIS16400_SPI_FAST;
st->us->mode = SPI_MODE_3;
spi_setup(st->us);
@@ -414,19 +454,27 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev)
if (ret)
goto err_ret;
- if ((prod_id & 0xF000) != st->variant->product_id)
- dev_warn(&indio_dev->dev, "incorrect id");
+ sscanf(indio_dev->name, "adis%u\n", &device_id);
+
+ if (prod_id != device_id)
+ dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.",
+ device_id, prod_id);
dev_info(&indio_dev->dev, "%s: prod_id 0x%04x at CS%d (irq %d)\n",
indio_dev->name, prod_id,
st->us->chip_select, st->us->irq);
}
/* use high spi speed if possible */
- ret = adis16400_spi_read_reg_16(indio_dev,
- ADIS16400_SMPL_PRD, &smp_prd);
- if (!ret && (smp_prd & ADIS16400_SMPL_PRD_DIV_MASK) < 0x0A) {
- st->us->max_speed_hz = ADIS16400_SPI_SLOW;
- spi_setup(st->us);
+ if (st->variant->flags & ADIS16400_HAS_SLOW_MODE) {
+ ret = adis16400_spi_read_reg_16(indio_dev,
+ ADIS16400_SMPL_PRD, &smp_prd);
+ if (ret)
+ goto err_ret;
+
+ if ((smp_prd & ADIS16400_SMPL_PRD_DIV_MASK) < 0x0A) {
+ st->us->max_speed_hz = ADIS16400_SPI_FAST;
+ spi_setup(st->us);
+ }
}
err_ret:
@@ -503,7 +551,7 @@ static int adis16400_write_raw(struct iio_dev *indio_dev,
mutex_lock(&indio_dev->mlock);
st->filt_int = val;
/* Work out update to current value */
- sps = adis16400_get_freq(indio_dev);
+ sps = st->variant->get_freq(indio_dev);
if (sps < 0) {
mutex_unlock(&indio_dev->mlock);
return sps;
@@ -601,7 +649,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
mutex_unlock(&indio_dev->mlock);
return ret;
}
- ret = adis16400_get_freq(indio_dev);
+ val16 = st->variant->get_freq(indio_dev);
if (ret > 0)
*val = ret/adis16400_3db_divisors[val16 & 0x03];
*val2 = 0;
@@ -624,7 +672,7 @@ static const struct iio_chan_spec adis16400_channels[] = {
IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
.address = in_supply,
.scan_index = ADIS16400_SCAN_SUPPLY,
- .scan_type = IIO_ST('u', 14, 16, 0)
+ .scan_type = IIO_ST('u', 14, 16, 0),
}, {
.type = IIO_ANGL_VEL,
.modified = 1,
@@ -635,7 +683,7 @@ static const struct iio_chan_spec adis16400_channels[] = {
IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
.address = gyro_x,
.scan_index = ADIS16400_SCAN_GYRO_X,
- .scan_type = IIO_ST('s', 14, 16, 0)
+ .scan_type = IIO_ST('s', 14, 16, 0),
}, {
.type = IIO_ANGL_VEL,
.modified = 1,
@@ -754,7 +802,7 @@ static const struct iio_chan_spec adis16350_channels[] = {
IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
.address = in_supply,
.scan_index = ADIS16400_SCAN_SUPPLY,
- .scan_type = IIO_ST('u', 12, 16, 0)
+ .scan_type = IIO_ST('u', 12, 16, 0),
}, {
.type = IIO_ANGL_VEL,
.modified = 1,
@@ -765,7 +813,7 @@ static const struct iio_chan_spec adis16350_channels[] = {
IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
.address = gyro_x,
.scan_index = ADIS16400_SCAN_GYRO_X,
- .scan_type = IIO_ST('s', 14, 16, 0)
+ .scan_type = IIO_ST('s', 14, 16, 0),
}, {
.type = IIO_ANGL_VEL,
.modified = 1,
@@ -879,7 +927,7 @@ static const struct iio_chan_spec adis16300_channels[] = {
IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
.address = in_supply,
.scan_index = ADIS16400_SCAN_SUPPLY,
- .scan_type = IIO_ST('u', 12, 16, 0)
+ .scan_type = IIO_ST('u', 12, 16, 0),
}, {
.type = IIO_ANGL_VEL,
.modified = 1,
@@ -1060,6 +1108,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
[ADIS16300] = {
.channels = adis16300_channels,
.num_channels = ARRAY_SIZE(adis16300_channels),
+ .flags = ADIS16400_HAS_SLOW_MODE,
.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
.accel_scale_micro = 5884,
.temp_scale_nano = 140000000, /* 0.14 C */
@@ -1070,10 +1119,13 @@ static struct adis16400_chip_info adis16400_chips[] = {
(1 << ADIS16400_SCAN_TEMP) | (1 << ADIS16400_SCAN_ADC_0) |
(1 << ADIS16300_SCAN_INCLI_X) | (1 << ADIS16300_SCAN_INCLI_Y) |
(1 << 14),
+ .set_freq = adis16400_set_freq,
+ .get_freq = adis16400_get_freq,
},
[ADIS16334] = {
.channels = adis16334_channels,
.num_channels = ARRAY_SIZE(adis16334_channels),
+ .flags = ADIS16400_HAS_PROD_ID,
.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
.accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */
.temp_scale_nano = 67850000, /* 0.06785 C */
@@ -1082,6 +1134,8 @@ static struct adis16400_chip_info adis16400_chips[] = {
(1 << ADIS16400_SCAN_GYRO_Y) | (1 << ADIS16400_SCAN_GYRO_Z) |
(1 << ADIS16400_SCAN_ACC_X) | (1 << ADIS16400_SCAN_ACC_Y) |
(1 << ADIS16400_SCAN_ACC_Z),
+ .set_freq = adis16334_set_freq,
+ .get_freq = adis16334_get_freq,
},
[ADIS16350] = {
.channels = adis16350_channels,
@@ -1091,62 +1145,57 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_scale_nano = 145300000, /* 0.1453 C */
.temp_offset = 25000000 / 145300, /* 25 C = 0x00 */
.default_scan_mask = 0x7FF,
- .flags = ADIS16400_NO_BURST,
+ .flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE,
+ .set_freq = adis16400_set_freq,
+ .get_freq = adis16400_get_freq,
},
[ADIS16360] = {
.channels = adis16350_channels,
.num_channels = ARRAY_SIZE(adis16350_channels),
- .flags = ADIS16400_HAS_PROD_ID,
- .product_id = 0x3FE8,
+ .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
.accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */
.temp_scale_nano = 136000000, /* 0.136 C */
.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
.default_scan_mask = 0x7FF,
+ .set_freq = adis16400_set_freq,
+ .get_freq = adis16400_get_freq,
},
[ADIS16362] = {
.channels = adis16350_channels,
.num_channels = ARRAY_SIZE(adis16350_channels),
- .flags = ADIS16400_HAS_PROD_ID,
- .product_id = 0x3FEA,
+ .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
.accel_scale_micro = IIO_G_TO_M_S_2(333), /* 0.333 mg */
.temp_scale_nano = 136000000, /* 0.136 C */
.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
.default_scan_mask = 0x7FF,
+ .set_freq = adis16400_set_freq,
+ .get_freq = adis16400_get_freq,
},
[ADIS16364] = {
.channels = adis16350_channels,
.num_channels = ARRAY_SIZE(adis16350_channels),
- .flags = ADIS16400_HAS_PROD_ID,
- .product_id = 0x3FEC,
- .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
- .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */
- .temp_scale_nano = 136000000, /* 0.136 C */
- .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
- .default_scan_mask = 0x7FF,
- },
- [ADIS16365] = {
- .channels = adis16350_channels,
- .num_channels = ARRAY_SIZE(adis16350_channels),
- .flags = ADIS16400_HAS_PROD_ID,
- .product_id = 0x3FED,
+ .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
.accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */
.temp_scale_nano = 136000000, /* 0.136 C */
.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
.default_scan_mask = 0x7FF,
+ .set_freq = adis16400_set_freq,
+ .get_freq = adis16400_get_freq,
},
[ADIS16400] = {
.channels = adis16400_channels,
.num_channels = ARRAY_SIZE(adis16400_channels),
- .flags = ADIS16400_HAS_PROD_ID,
- .product_id = 0x4015,
+ .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
.accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */
.default_scan_mask = 0xFFF,
.temp_scale_nano = 140000000, /* 0.14 C */
.temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
+ .set_freq = adis16400_set_freq,
+ .get_freq = adis16400_get_freq,
}
};
@@ -1157,7 +1206,7 @@ static const struct iio_info adis16400_info = {
.attrs = &adis16400_attribute_group,
};
-static int __devinit adis16400_probe(struct spi_device *spi)
+static int adis16400_probe(struct spi_device *spi)
{
int ret;
struct adis16400_state *st;
@@ -1224,7 +1273,7 @@ error_ret:
}
/* fixme, confirm ordering in this function */
-static int __devexit adis16400_remove(struct spi_device *spi)
+static int adis16400_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
@@ -1248,7 +1297,7 @@ static const struct spi_device_id adis16400_id[] = {
{"adis16360", ADIS16360},
{"adis16362", ADIS16362},
{"adis16364", ADIS16364},
- {"adis16365", ADIS16365},
+ {"adis16365", ADIS16360},
{"adis16400", ADIS16400},
{"adis16405", ADIS16400},
{}
@@ -1262,7 +1311,7 @@ static struct spi_driver adis16400_driver = {
},
.id_table = adis16400_id,
.probe = adis16400_probe,
- .remove = __devexit_p(adis16400_remove),
+ .remove = adis16400_remove,
};
module_spi_driver(adis16400_driver);
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index 260bdd1a468..d46c1e38cf7 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -114,7 +114,6 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16400_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
int i = 0, j, ret = 0;
s16 *data;
@@ -148,9 +147,9 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
}
}
/* Guaranteed to be aligned with 8 byte boundary */
- if (ring->scan_timestamp)
+ if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- iio_push_to_buffer(ring, (u8 *) data);
+ iio_push_to_buffers(indio_dev, (u8 *) data);
done:
kfree(data);
diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c
index 6ee5567d981..b0adac0bf5d 100644
--- a/drivers/staging/iio/light/isl29018.c
+++ b/drivers/staging/iio/light/isl29018.c
@@ -67,6 +67,7 @@ struct isl29018_chip {
unsigned int range;
unsigned int adc_bit;
int prox_scheme;
+ bool suspended;
};
static int isl29018_set_range(struct isl29018_chip *chip, unsigned long range,
@@ -355,7 +356,7 @@ static int isl29018_write_raw(struct iio_dev *indio_dev,
}
mutex_unlock(&chip->lock);
- return 0;
+ return ret;
}
static int isl29018_read_raw(struct iio_dev *indio_dev,
@@ -368,6 +369,10 @@ static int isl29018_read_raw(struct iio_dev *indio_dev,
struct isl29018_chip *chip = iio_priv(indio_dev);
mutex_lock(&chip->lock);
+ if (chip->suspended) {
+ mutex_unlock(&chip->lock);
+ return -EBUSY;
+ }
switch (mask) {
case IIO_CHAN_INFO_RAW:
case IIO_CHAN_INFO_PROCESSED:
@@ -538,7 +543,7 @@ static const struct regmap_config isl29018_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
-static int __devinit isl29018_probe(struct i2c_client *client,
+static int isl29018_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct isl29018_chip *chip;
@@ -561,6 +566,7 @@ static int __devinit isl29018_probe(struct i2c_client *client,
chip->lux_scale = 1;
chip->range = 1000;
chip->adc_bit = 16;
+ chip->suspended = false;
chip->regmap = devm_regmap_init_i2c(client, &isl29018_regmap_config);
if (IS_ERR(chip->regmap)) {
@@ -592,7 +598,7 @@ exit:
return err;
}
-static int __devexit isl29018_remove(struct i2c_client *client)
+static int isl29018_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
@@ -603,6 +609,44 @@ static int __devexit isl29018_remove(struct i2c_client *client)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int isl29018_suspend(struct device *dev)
+{
+ struct isl29018_chip *chip = iio_priv(dev_get_drvdata(dev));
+
+ mutex_lock(&chip->lock);
+
+ /* Since this driver uses only polling commands, we are by default in
+ * auto shutdown (ie, power-down) mode.
+ * So we do not have much to do here.
+ */
+ chip->suspended = true;
+
+ mutex_unlock(&chip->lock);
+ return 0;
+}
+
+static int isl29018_resume(struct device *dev)
+{
+ struct isl29018_chip *chip = iio_priv(dev_get_drvdata(dev));
+ int err;
+
+ mutex_lock(&chip->lock);
+
+ err = isl29018_chip_init(chip);
+ if (!err)
+ chip->suspended = false;
+
+ mutex_unlock(&chip->lock);
+ return err;
+}
+
+static SIMPLE_DEV_PM_OPS(isl29018_pm_ops, isl29018_suspend, isl29018_resume);
+#define ISL29018_PM_OPS (&isl29018_pm_ops)
+#else
+#define ISL29018_PM_OPS NULL
+#endif
+
static const struct i2c_device_id isl29018_id[] = {
{"isl29018", 0},
{}
@@ -620,11 +664,12 @@ static struct i2c_driver isl29018_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "isl29018",
+ .pm = ISL29018_PM_OPS,
.owner = THIS_MODULE,
.of_match_table = isl29018_of_match,
},
.probe = isl29018_probe,
- .remove = __devexit_p(isl29018_remove),
+ .remove = isl29018_remove,
.id_table = isl29018_id,
};
module_i2c_driver(isl29018_driver);
diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c
index 33a4c3f94a1..e52af77f778 100644
--- a/drivers/staging/iio/light/isl29028.c
+++ b/drivers/staging/iio/light/isl29028.c
@@ -475,7 +475,7 @@ static const struct regmap_config isl29028_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
-static int __devinit isl29028_probe(struct i2c_client *client,
+static int isl29028_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct isl29028_chip *chip;
@@ -526,7 +526,7 @@ exit_iio_free:
return ret;
}
-static int __devexit isl29028_remove(struct i2c_client *client)
+static int isl29028_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
@@ -555,7 +555,7 @@ static struct i2c_driver isl29028_driver = {
.of_match_table = isl29028_of_match,
},
.probe = isl29028_probe,
- .remove = __devexit_p(isl29028_remove),
+ .remove = isl29028_remove,
.id_table = isl29028_id,
};
diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c
index 954ca2c172c..1a9adc020f6 100644
--- a/drivers/staging/iio/light/tsl2563.c
+++ b/drivers/staging/iio/light/tsl2563.c
@@ -652,7 +652,7 @@ static int tsl2563_write_interrupt_config(struct iio_dev *indio_dev,
}
if (!state && (chip->intr & 0x30)) {
- chip->intr |= ~0x30;
+ chip->intr &= ~0x30;
ret = i2c_smbus_write_byte_data(chip->client,
TSL2563_CMD | TSL2563_REG_INT,
chip->intr);
@@ -705,7 +705,7 @@ static const struct iio_info tsl2563_info = {
.write_event_config = &tsl2563_write_interrupt_config,
};
-static int __devinit tsl2563_probe(struct i2c_client *client,
+static int tsl2563_probe(struct i2c_client *client,
const struct i2c_device_id *device_id)
{
struct iio_dev *indio_dev;
@@ -805,7 +805,7 @@ fail1:
return err;
}
-static int __devexit tsl2563_remove(struct i2c_client *client)
+static int tsl2563_remove(struct i2c_client *client)
{
struct tsl2563_chip *chip = i2c_get_clientdata(client);
struct iio_dev *indio_dev = iio_priv_to_dev(chip);
@@ -814,7 +814,7 @@ static int __devexit tsl2563_remove(struct i2c_client *client)
if (!chip->int_enabled)
cancel_delayed_work(&chip->poweroff_work);
/* Ensure that interrupts are disabled - then flush any bottom halves */
- chip->intr |= ~0x30;
+ chip->intr &= ~0x30;
i2c_smbus_write_byte_data(chip->client, TSL2563_CMD | TSL2563_REG_INT,
chip->intr);
flush_scheduled_work();
@@ -889,7 +889,7 @@ static struct i2c_driver tsl2563_i2c_driver = {
.pm = TSL2563_PM_OPS,
},
.probe = tsl2563_probe,
- .remove = __devexit_p(tsl2563_remove),
+ .remove = tsl2563_remove,
.id_table = tsl2563_id,
};
module_i2c_driver(tsl2563_i2c_driver);
diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c
index 6d2f4c659e5..b377dd3b76a 100644
--- a/drivers/staging/iio/light/tsl2583.c
+++ b/drivers/staging/iio/light/tsl2583.c
@@ -799,7 +799,7 @@ static const struct iio_info tsl2583_info = {
* Client probe function - When a valid device is found, the driver's device
* data structure is updated, and initialization completes successfully.
*/
-static int __devinit taos_probe(struct i2c_client *clientp,
+static int taos_probe(struct i2c_client *clientp,
const struct i2c_device_id *idp)
{
int i, ret;
@@ -923,7 +923,7 @@ static SIMPLE_DEV_PM_OPS(taos_pm_ops, taos_suspend, taos_resume);
#define TAOS_PM_OPS NULL
#endif
-static int __devexit taos_remove(struct i2c_client *client)
+static int taos_remove(struct i2c_client *client)
{
iio_device_unregister(i2c_get_clientdata(client));
iio_device_free(i2c_get_clientdata(client));
@@ -947,7 +947,7 @@ static struct i2c_driver taos_driver = {
},
.id_table = taos_idtable,
.probe = taos_probe,
- .remove = __devexit_p(taos_remove),
+ .remove = taos_remove,
};
module_i2c_driver(taos_driver);
diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c
index 497a977ae41..9e50fbbadf9 100644
--- a/drivers/staging/iio/light/tsl2x7x_core.c
+++ b/drivers/staging/iio/light/tsl2x7x_core.c
@@ -1897,7 +1897,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
},
};
-static int __devinit tsl2x7x_probe(struct i2c_client *clientp,
+static int tsl2x7x_probe(struct i2c_client *clientp,
const struct i2c_device_id *id)
{
int ret;
@@ -2026,7 +2026,7 @@ static int tsl2x7x_resume(struct device *dev)
return ret;
}
-static int __devexit tsl2x7x_remove(struct i2c_client *client)
+static int tsl2x7x_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
@@ -2070,7 +2070,7 @@ static struct i2c_driver tsl2x7x_driver = {
},
.id_table = tsl2x7x_idtable,
.probe = tsl2x7x_probe,
- .remove = __devexit_p(tsl2x7x_remove),
+ .remove = tsl2x7x_remove,
};
module_i2c_driver(tsl2x7x_driver);
diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c
index 01b4b07c227..28f080e9eee 100644
--- a/drivers/staging/iio/magnetometer/ak8975.c
+++ b/drivers/staging/iio/magnetometer/ak8975.c
@@ -409,7 +409,7 @@ static const struct iio_info ak8975_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit ak8975_probe(struct i2c_client *client,
+static int ak8975_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ak8975_data *data;
@@ -475,7 +475,7 @@ exit:
return err;
}
-static int __devexit ak8975_remove(struct i2c_client *client)
+static int ak8975_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct ak8975_data *data = iio_priv(indio_dev);
@@ -510,7 +510,7 @@ static struct i2c_driver ak8975_driver = {
.of_match_table = ak8975_of_match,
},
.probe = ak8975_probe,
- .remove = __devexit_p(ak8975_remove),
+ .remove = ak8975_remove,
.id_table = ak8975_id,
};
module_i2c_driver(ak8975_driver);
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
index 10e095486e5..1a520ecfa3e 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843.c
@@ -555,7 +555,7 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev,
*val = 0;
*val2 = data->variant->regval_to_nanoscale[data->range];
return IIO_VAL_INT_PLUS_NANO;
- };
+ }
return -EINVAL;
}
@@ -665,7 +665,7 @@ static const struct iio_info hmc5843_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit hmc5843_probe(struct i2c_client *client,
+static int hmc5843_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct hmc5843_data *data;
@@ -704,7 +704,7 @@ exit:
return err;
}
-static int __devexit hmc5843_remove(struct i2c_client *client)
+static int hmc5843_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
@@ -755,7 +755,7 @@ static struct i2c_driver hmc5843_driver = {
},
.id_table = hmc5843_id,
.probe = hmc5843_probe,
- .remove = __devexit_p(hmc5843_remove),
+ .remove = hmc5843_remove,
.detect = hmc5843_detect,
.address_list = normal_i2c,
};
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c
index 8b9eceb66b3..51c3bdece78 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -512,7 +512,7 @@ static const struct iio_info ade7753_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit ade7753_probe(struct spi_device *spi)
+static int ade7753_probe(struct spi_device *spi)
{
int ret;
struct ade7753_state *st;
@@ -555,7 +555,7 @@ error_ret:
}
/* fixme, confirm ordering in this function */
-static int __devexit ade7753_remove(struct spi_device *spi)
+static int ade7753_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
@@ -572,7 +572,7 @@ static struct spi_driver ade7753_driver = {
.owner = THIS_MODULE,
},
.probe = ade7753_probe,
- .remove = __devexit_p(ade7753_remove),
+ .remove = ade7753_remove,
};
module_spi_driver(ade7753_driver);
diff --git a/drivers/staging/iio/meter/ade7753.h b/drivers/staging/iio/meter/ade7753.h
index 3f059d3d939..a9d93cc1c41 100644
--- a/drivers/staging/iio/meter/ade7753.h
+++ b/drivers/staging/iio/meter/ade7753.h
@@ -55,8 +55,6 @@
#define ADE7753_SPI_BURST (u32)(1000 * 1000)
#define ADE7753_SPI_FAST (u32)(2000 * 1000)
-#define DRIVER_NAME "ade7753"
-
/**
* struct ade7753_state - device instance specific data
* @us: actual spi_device
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index 76e0adee96e..b50c89e9399 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -535,7 +535,7 @@ static const struct iio_info ade7754_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit ade7754_probe(struct spi_device *spi)
+static int ade7754_probe(struct spi_device *spi)
{
int ret;
struct ade7754_state *st;
@@ -577,7 +577,7 @@ error_ret:
}
/* fixme, confirm ordering in this function */
-static int __devexit ade7754_remove(struct spi_device *spi)
+static int ade7754_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
@@ -594,7 +594,7 @@ static struct spi_driver ade7754_driver = {
.owner = THIS_MODULE,
},
.probe = ade7754_probe,
- .remove = __devexit_p(ade7754_remove),
+ .remove = ade7754_remove,
};
module_spi_driver(ade7754_driver);
diff --git a/drivers/staging/iio/meter/ade7754.h b/drivers/staging/iio/meter/ade7754.h
index 6121125520f..e42ffc387a1 100644
--- a/drivers/staging/iio/meter/ade7754.h
+++ b/drivers/staging/iio/meter/ade7754.h
@@ -73,8 +73,6 @@
#define ADE7754_SPI_BURST (u32)(1000 * 1000)
#define ADE7754_SPI_FAST (u32)(2000 * 1000)
-#define DRIVER_NAME "ade7754"
-
/**
* struct ade7754_state - device instance specific data
* @us: actual spi_device
diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h
index 1e11ad5ae5a..07318203a83 100644
--- a/drivers/staging/iio/meter/ade7758.h
+++ b/drivers/staging/iio/meter/ade7758.h
@@ -105,9 +105,6 @@
#define AD7758_APP_PWR 4
#define AD7758_WT(p, w) (((w) << 2) | (p))
-#define DRIVER_NAME "ade7758"
-
-
/**
* struct ade7758_state - device instance specific data
* @us: actual spi_device
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index a0fef77d8e5..3454e5154ed 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -881,7 +881,7 @@ static const struct iio_info ade7758_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit ade7758_probe(struct spi_device *spi)
+static int ade7758_probe(struct spi_device *spi)
{
int ret;
struct ade7758_state *st;
@@ -962,7 +962,7 @@ error_ret:
return ret;
}
-static int __devexit ade7758_remove(struct spi_device *spi)
+static int ade7758_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ade7758_state *st = iio_priv(indio_dev);
@@ -992,7 +992,7 @@ static struct spi_driver ade7758_driver = {
.owner = THIS_MODULE,
},
.probe = ade7758_probe,
- .remove = __devexit_p(ade7758_remove),
+ .remove = ade7758_remove,
.id_table = ade7758_id,
};
module_spi_driver(ade7758_driver);
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index 9e49baccf66..4552a4c7fe3 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -73,7 +73,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
dat64[1] = pf->timestamp;
- iio_push_to_buffer(indio_dev->buffer, (u8 *)dat64);
+ iio_push_to_buffers(indio_dev, (u8 *)dat64);
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
index cb0707cbc34..10b911bd385 100644
--- a/drivers/staging/iio/meter/ade7759.c
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -458,7 +458,7 @@ static const struct iio_info ade7759_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit ade7759_probe(struct spi_device *spi)
+static int ade7759_probe(struct spi_device *spi)
{
int ret;
struct ade7759_state *st;
@@ -499,7 +499,7 @@ error_ret:
}
/* fixme, confirm ordering in this function */
-static int __devexit ade7759_remove(struct spi_device *spi)
+static int ade7759_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
@@ -516,7 +516,7 @@ static struct spi_driver ade7759_driver = {
.owner = THIS_MODULE,
},
.probe = ade7759_probe,
- .remove = __devexit_p(ade7759_remove),
+ .remove = ade7759_remove,
};
module_spi_driver(ade7759_driver);
diff --git a/drivers/staging/iio/meter/ade7759.h b/drivers/staging/iio/meter/ade7759.h
index c81d23d730d..f9ff1f8e737 100644
--- a/drivers/staging/iio/meter/ade7759.h
+++ b/drivers/staging/iio/meter/ade7759.h
@@ -36,8 +36,6 @@
#define ADE7759_SPI_BURST (u32)(1000 * 1000)
#define ADE7759_SPI_FAST (u32)(2000 * 1000)
-#define DRIVER_NAME "ade7759"
-
/**
* struct ade7759_state - device instance specific data
* @us: actual spi_device
diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c
index 06090465fa5..db9ef6c86c1 100644
--- a/drivers/staging/iio/meter/ade7854-i2c.c
+++ b/drivers/staging/iio/meter/ade7854-i2c.c
@@ -201,7 +201,7 @@ out:
return ret;
}
-static int __devinit ade7854_i2c_probe(struct i2c_client *client,
+static int ade7854_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret;
@@ -231,7 +231,7 @@ static int __devinit ade7854_i2c_probe(struct i2c_client *client,
return ret;
}
-static int __devexit ade7854_i2c_remove(struct i2c_client *client)
+static int ade7854_i2c_remove(struct i2c_client *client)
{
return ade7854_remove(i2c_get_clientdata(client));
}
@@ -250,7 +250,7 @@ static struct i2c_driver ade7854_i2c_driver = {
.name = "ade7854",
},
.probe = ade7854_i2c_probe,
- .remove = __devexit_p(ade7854_i2c_remove),
+ .remove = ade7854_i2c_remove,
.id_table = ade7854_id,
};
module_i2c_driver(ade7854_i2c_driver);
diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c
index 7dae0357342..f0984fa1cbb 100644
--- a/drivers/staging/iio/meter/ade7854-spi.c
+++ b/drivers/staging/iio/meter/ade7854-spi.c
@@ -300,7 +300,7 @@ error_ret:
return ret;
}
-static int __devinit ade7854_spi_probe(struct spi_device *spi)
+static int ade7854_spi_probe(struct spi_device *spi)
{
int ret;
struct ade7854_state *st;
@@ -330,7 +330,7 @@ static int __devinit ade7854_spi_probe(struct spi_device *spi)
return 0;
}
-static int __devexit ade7854_spi_remove(struct spi_device *spi)
+static int ade7854_spi_remove(struct spi_device *spi)
{
ade7854_remove(spi_get_drvdata(spi));
@@ -351,7 +351,7 @@ static struct spi_driver ade7854_driver = {
.owner = THIS_MODULE,
},
.probe = ade7854_spi_probe,
- .remove = __devexit_p(ade7854_spi_remove),
+ .remove = ade7854_spi_remove,
.id_table = ade7854_id,
};
module_spi_driver(ade7854_driver);
diff --git a/drivers/staging/iio/meter/ade7854.h b/drivers/staging/iio/meter/ade7854.h
index 2c96e8695d5..06534577f6c 100644
--- a/drivers/staging/iio/meter/ade7854.h
+++ b/drivers/staging/iio/meter/ade7854.h
@@ -142,8 +142,6 @@
#define ADE7854_SPI_BURST (u32)(1000 * 1000)
#define ADE7854_SPI_FAST (u32)(2000 * 1000)
-#define DRIVER_NAME "ade7854"
-
/**
* struct ade7854_state - device instance specific data
* @spi: actual spi_device
diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c
index 8b71eb0e16f..4fe349914f9 100644
--- a/drivers/staging/iio/resolver/ad2s1200.c
+++ b/drivers/staging/iio/resolver/ad2s1200.c
@@ -99,7 +99,7 @@ static const struct iio_info ad2s1200_info = {
.driver_module = THIS_MODULE,
};
-static int __devinit ad2s1200_probe(struct spi_device *spi)
+static int ad2s1200_probe(struct spi_device *spi)
{
struct ad2s1200_state *st;
struct iio_dev *indio_dev;
@@ -149,7 +149,7 @@ error_ret:
return ret;
}
-static int __devexit ad2s1200_remove(struct spi_device *spi)
+static int ad2s1200_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
@@ -170,7 +170,7 @@ static struct spi_driver ad2s1200_driver = {
.owner = THIS_MODULE,
},
.probe = ad2s1200_probe,
- .remove = __devexit_p(ad2s1200_remove),
+ .remove = ad2s1200_remove,
.id_table = ad2s1200_id,
};
module_spi_driver(ad2s1200_driver);
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 4ba4d05ed42..ed07a348eb5 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -610,7 +610,7 @@ static const struct attribute_group ad2s1210_attribute_group = {
.attrs = ad2s1210_attributes,
};
-static int __devinit ad2s1210_initial(struct ad2s1210_state *st)
+static int ad2s1210_initial(struct ad2s1210_state *st)
{
unsigned char data;
int ret;
@@ -681,7 +681,7 @@ static void ad2s1210_free_gpios(struct ad2s1210_state *st)
gpio_free_array(ad2s1210_gpios, ARRAY_SIZE(ad2s1210_gpios));
}
-static int __devinit ad2s1210_probe(struct spi_device *spi)
+static int ad2s1210_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
struct ad2s1210_state *st;
@@ -736,7 +736,7 @@ error_ret:
return ret;
}
-static int __devexit ad2s1210_remove(struct spi_device *spi)
+static int ad2s1210_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
@@ -759,7 +759,7 @@ static struct spi_driver ad2s1210_driver = {
.owner = THIS_MODULE,
},
.probe = ad2s1210_probe,
- .remove = __devexit_p(ad2s1210_remove),
+ .remove = ad2s1210_remove,
.id_table = ad2s1210_id,
};
module_spi_driver(ad2s1210_driver);
diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c
index a8057228dca..0aecfbcdb99 100644
--- a/drivers/staging/iio/resolver/ad2s90.c
+++ b/drivers/staging/iio/resolver/ad2s90.c
@@ -58,7 +58,7 @@ static const struct iio_chan_spec ad2s90_chan = {
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
};
-static int __devinit ad2s90_probe(struct spi_device *spi)
+static int ad2s90_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
struct ad2s90_state *st;
@@ -98,7 +98,7 @@ error_ret:
return ret;
}
-static int __devexit ad2s90_remove(struct spi_device *spi)
+static int ad2s90_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
@@ -118,7 +118,7 @@ static struct spi_driver ad2s90_driver = {
.owner = THIS_MODULE,
},
.probe = ad2s90_probe,
- .remove = __devexit_p(ad2s90_remove),
+ .remove = ad2s90_remove,
.id_table = ad2s90_id,
};
module_spi_driver(ad2s90_driver);
diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
index 52062d786f8..42798da575c 100644
--- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
+++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
@@ -180,7 +180,7 @@ static const struct iio_trigger_ops iio_bfin_tmr_trigger_ops = {
.set_trigger_state = iio_bfin_tmr_set_state,
};
-static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev)
+static int iio_bfin_tmr_trigger_probe(struct platform_device *pdev)
{
struct iio_bfin_timer_trigger_pdata *pdata = pdev->dev.platform_data;
struct bfin_tmr_state *st;
@@ -275,7 +275,7 @@ out:
return ret;
}
-static int __devexit iio_bfin_tmr_trigger_remove(struct platform_device *pdev)
+static int iio_bfin_tmr_trigger_remove(struct platform_device *pdev)
{
struct bfin_tmr_state *st = platform_get_drvdata(pdev);
@@ -296,7 +296,7 @@ static struct platform_driver iio_bfin_tmr_trigger_driver = {
.owner = THIS_MODULE,
},
.probe = iio_bfin_tmr_trigger_probe,
- .remove = __devexit_p(iio_bfin_tmr_trigger_remove),
+ .remove = iio_bfin_tmr_trigger_remove,
};
module_platform_driver(iio_bfin_tmr_trigger_driver);
diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c
index 5ff4d7fa20f..fcc4cb048c9 100644
--- a/drivers/staging/iio/trigger/iio-trig-gpio.c
+++ b/drivers/staging/iio/trigger/iio-trig-gpio.c
@@ -51,7 +51,7 @@ static const struct iio_trigger_ops iio_gpio_trigger_ops = {
.owner = THIS_MODULE,
};
-static int __devinit iio_gpio_trigger_probe(struct platform_device *pdev)
+static int iio_gpio_trigger_probe(struct platform_device *pdev)
{
struct iio_gpio_trigger_info *trig_info;
struct iio_trigger *trig, *trig2;
@@ -130,7 +130,7 @@ error_free_completed_registrations:
return ret;
}
-static int __devexit iio_gpio_trigger_remove(struct platform_device *pdev)
+static int iio_gpio_trigger_remove(struct platform_device *pdev)
{
struct iio_trigger *trig, *trig2;
struct iio_gpio_trigger_info *trig_info;
@@ -153,7 +153,7 @@ static int __devexit iio_gpio_trigger_remove(struct platform_device *pdev)
static struct platform_driver iio_gpio_trigger_driver = {
.probe = iio_gpio_trigger_probe,
- .remove = __devexit_p(iio_gpio_trigger_remove),
+ .remove = iio_gpio_trigger_remove,
.driver = {
.name = "iio_gpio_trigger",
.owner = THIS_MODULE,
diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
index a3de76d70cd..9102b1ba253 100644
--- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
+++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
@@ -101,7 +101,7 @@ static const struct iio_trigger_ops iio_prtc_trigger_ops = {
.set_trigger_state = &iio_trig_periodic_rtc_set_state,
};
-static int __devinit iio_trig_periodic_rtc_probe(struct platform_device *dev)
+static int iio_trig_periodic_rtc_probe(struct platform_device *dev)
{
char **pdata = dev->dev.platform_data;
struct iio_prtc_trigger_info *trig_info;
@@ -167,7 +167,7 @@ error_free_completed_registrations:
return ret;
}
-static int __devexit iio_trig_periodic_rtc_remove(struct platform_device *dev)
+static int iio_trig_periodic_rtc_remove(struct platform_device *dev)
{
struct iio_trigger *trig, *trig2;
struct iio_prtc_trigger_info *trig_info;
@@ -188,7 +188,7 @@ static int __devexit iio_trig_periodic_rtc_remove(struct platform_device *dev)
static struct platform_driver iio_trig_periodic_rtc_driver = {
.probe = iio_trig_periodic_rtc_probe,
- .remove = __devexit_p(iio_trig_periodic_rtc_remove),
+ .remove = iio_trig_periodic_rtc_remove,
.driver = {
.name = "iio_prtc_trigger",
.owner = THIS_MODULE,
diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig
index 14b4449df23..be7e2e30ac1 100644
--- a/drivers/staging/imx-drm/Kconfig
+++ b/drivers/staging/imx-drm/Kconfig
@@ -3,7 +3,7 @@ config DRM_IMX
select DRM_KMS_HELPER
select DRM_GEM_CMA_HELPER
select DRM_KMS_CMA_HELPER
- depends on DRM && ARCH_MXC
+ depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM)
help
enable i.MX graphics support
diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c
index 1913199ba16..ecf0f44bc70 100644
--- a/drivers/staging/imx-drm/imx-drm-core.c
+++ b/drivers/staging/imx-drm/imx-drm-core.c
@@ -824,7 +824,7 @@ static int imx_drm_platform_remove(struct platform_device *pdev)
static struct platform_driver imx_drm_pdrv = {
.probe = imx_drm_platform_probe,
- .remove = __devexit_p(imx_drm_platform_remove),
+ .remove = imx_drm_platform_remove,
.driver = {
.owner = THIS_MODULE,
.name = "imx-drm",
diff --git a/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h
index 74158dd7375..99d1cceaa3d 100644
--- a/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h
+++ b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h
@@ -16,7 +16,6 @@
#include <linux/videodev2.h>
#include <linux/bitmap.h>
#include <linux/fb.h>
-#include <linux/videodev2.h>
struct ipu_soc;
@@ -293,6 +292,7 @@ static inline void ipu_cpmem_interlaced_scan(struct ipu_ch_param *p,
void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem *p, u32 pixel_format,
int stride, int height);
+void ipu_cpmem_set_yuv_interleaved(struct ipu_ch_param *p, u32 pixel_format);
void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem *p,
u32 pixel_format, int stride, int u_offset, int v_offset);
int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat);
diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c
index f381960f42b..677e665ca86 100644
--- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c
+++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c
@@ -225,6 +225,23 @@ int ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem *p,
}
EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_passthrough);
+void ipu_cpmem_set_yuv_interleaved(struct ipu_ch_param *p, u32 pixel_format)
+{
+ switch (pixel_format) {
+ case V4L2_PIX_FMT_UYVY:
+ ipu_ch_param_write_field(p, IPU_FIELD_BPP, 3); /* bits/pixel */
+ ipu_ch_param_write_field(p, IPU_FIELD_PFS, 0xA); /* pix format */
+ ipu_ch_param_write_field(p, IPU_FIELD_NPB, 31); /* burst size */
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ ipu_ch_param_write_field(p, IPU_FIELD_BPP, 3); /* bits/pixel */
+ ipu_ch_param_write_field(p, IPU_FIELD_PFS, 0x8); /* pix format */
+ ipu_ch_param_write_field(p, IPU_FIELD_NPB, 31); /* burst size */
+ break;
+ }
+}
+EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_interleaved);
+
void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem *p,
u32 pixel_format, int stride, int u_offset, int v_offset)
{
@@ -234,6 +251,11 @@ void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem *p,
ipu_ch_param_write_field(p, IPU_FIELD_UBO, u_offset / 8);
ipu_ch_param_write_field(p, IPU_FIELD_VBO, v_offset / 8);
break;
+ case V4L2_PIX_FMT_YVU420:
+ ipu_ch_param_write_field(p, IPU_FIELD_SLUV, (stride / 2) - 1);
+ ipu_ch_param_write_field(p, IPU_FIELD_UBO, v_offset / 8);
+ ipu_ch_param_write_field(p, IPU_FIELD_VBO, u_offset / 8);
+ break;
}
}
EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full);
@@ -246,10 +268,11 @@ void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem *p, u32 pixel_format,
switch (pixel_format) {
case V4L2_PIX_FMT_YUV420:
+ case V4L2_PIX_FMT_YVU420:
uv_stride = stride / 2;
u_offset = stride * height;
v_offset = u_offset + (uv_stride * height / 2);
- ipu_cpmem_set_yuv_planar_full(p, V4L2_PIX_FMT_YUV420, stride,
+ ipu_cpmem_set_yuv_planar_full(p, pixel_format, stride,
u_offset, v_offset);
break;
}
@@ -307,6 +330,7 @@ int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat)
{
switch (pixelformat) {
case V4L2_PIX_FMT_YUV420:
+ case V4L2_PIX_FMT_YVU420:
/* pix format */
ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 2);
/* burst size */
@@ -369,6 +393,7 @@ int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem,
switch (pix->pixelformat) {
case V4L2_PIX_FMT_YUV420:
+ case V4L2_PIX_FMT_YVU420:
y_offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
u_offset = U_OFFSET(pix, image->rect.left,
image->rect.top) - y_offset;
@@ -380,6 +405,7 @@ int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem,
ipu_cpmem_set_buffer(cpmem, 0, image->phys + y_offset);
break;
case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_YUYV:
ipu_cpmem_set_buffer(cpmem, 0, image->phys +
image->rect.left * 2 +
image->rect.top * image->pix.bytesperline);
@@ -413,8 +439,9 @@ enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat)
{
switch (pixelformat) {
case V4L2_PIX_FMT_YUV420:
+ case V4L2_PIX_FMT_YVU420:
case V4L2_PIX_FMT_UYVY:
- case V4L2_PIX_FMT_YVYU:
+ case V4L2_PIX_FMT_YUYV:
return IPUV3_COLORSPACE_YUV;
case V4L2_PIX_FMT_RGB32:
case V4L2_PIX_FMT_BGR32:
@@ -646,8 +673,6 @@ static int ipu_reset(struct ipu_soc *ipu)
cpu_relax();
}
- mdelay(300);
-
return 0;
}
@@ -988,7 +1013,7 @@ static void ipu_irq_exit(struct ipu_soc *ipu)
irq_free_descs(ipu->irq_start, IPU_NUM_IRQS);
}
-static int __devinit ipu_probe(struct platform_device *pdev)
+static int ipu_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
of_match_device(imx_ipu_dt_ids, &pdev->dev);
@@ -1000,13 +1025,11 @@ static int __devinit ipu_probe(struct platform_device *pdev)
devtype = of_id->data;
- dev_info(&pdev->dev, "Initializing %s\n", devtype->name);
-
irq_sync = platform_get_irq(pdev, 0);
irq_err = platform_get_irq(pdev, 1);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- dev_info(&pdev->dev, "irq_sync: %d irq_err: %d\n",
+ dev_dbg(&pdev->dev, "irq_sync: %d irq_err: %d\n",
irq_sync, irq_err);
if (!res || irq_sync < 0 || irq_err < 0)
@@ -1026,27 +1049,27 @@ static int __devinit ipu_probe(struct platform_device *pdev)
spin_lock_init(&ipu->lock);
mutex_init(&ipu->channel_lock);
- dev_info(&pdev->dev, "cm_reg: 0x%08lx\n",
+ dev_dbg(&pdev->dev, "cm_reg: 0x%08lx\n",
ipu_base + devtype->cm_ofs);
- dev_info(&pdev->dev, "idmac: 0x%08lx\n",
+ dev_dbg(&pdev->dev, "idmac: 0x%08lx\n",
ipu_base + devtype->cm_ofs + IPU_CM_IDMAC_REG_OFS);
- dev_info(&pdev->dev, "cpmem: 0x%08lx\n",
+ dev_dbg(&pdev->dev, "cpmem: 0x%08lx\n",
ipu_base + devtype->cpmem_ofs);
- dev_info(&pdev->dev, "disp0: 0x%08lx\n",
+ dev_dbg(&pdev->dev, "disp0: 0x%08lx\n",
ipu_base + devtype->disp0_ofs);
- dev_info(&pdev->dev, "disp1: 0x%08lx\n",
+ dev_dbg(&pdev->dev, "disp1: 0x%08lx\n",
ipu_base + devtype->disp1_ofs);
- dev_info(&pdev->dev, "srm: 0x%08lx\n",
+ dev_dbg(&pdev->dev, "srm: 0x%08lx\n",
ipu_base + devtype->srm_ofs);
- dev_info(&pdev->dev, "tpm: 0x%08lx\n",
+ dev_dbg(&pdev->dev, "tpm: 0x%08lx\n",
ipu_base + devtype->tpm_ofs);
- dev_info(&pdev->dev, "dc: 0x%08lx\n",
+ dev_dbg(&pdev->dev, "dc: 0x%08lx\n",
ipu_base + devtype->cm_ofs + IPU_CM_DC_REG_OFS);
- dev_info(&pdev->dev, "ic: 0x%08lx\n",
+ dev_dbg(&pdev->dev, "ic: 0x%08lx\n",
ipu_base + devtype->cm_ofs + IPU_CM_IC_REG_OFS);
- dev_info(&pdev->dev, "dmfc: 0x%08lx\n",
+ dev_dbg(&pdev->dev, "dmfc: 0x%08lx\n",
ipu_base + devtype->cm_ofs + IPU_CM_DMFC_REG_OFS);
- dev_info(&pdev->dev, "vdi: 0x%08lx\n",
+ dev_dbg(&pdev->dev, "vdi: 0x%08lx\n",
ipu_base + devtype->vdi_ofs);
ipu->cm_reg = devm_ioremap(&pdev->dev,
@@ -1098,6 +1121,8 @@ static int __devinit ipu_probe(struct platform_device *pdev)
goto failed_add_clients;
}
+ dev_info(&pdev->dev, "%s probed\n", devtype->name);
+
return 0;
failed_add_clients:
@@ -1111,7 +1136,7 @@ failed_ioremap:
return ret;
}
-static int __devexit ipu_remove(struct platform_device *pdev)
+static int ipu_remove(struct platform_device *pdev)
{
struct ipu_soc *ipu = platform_get_drvdata(pdev);
struct resource *res;
@@ -1133,7 +1158,7 @@ static struct platform_driver imx_ipu_driver = {
.of_match_table = imx_ipu_dt_ids,
},
.probe = ipu_probe,
- .remove = __devexit_p(ipu_remove),
+ .remove = ipu_remove,
};
module_platform_driver(imx_ipu_driver);
diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c
index 78d3edac75c..1892006526b 100644
--- a/drivers/staging/imx-drm/ipuv3-crtc.c
+++ b/drivers/staging/imx-drm/ipuv3-crtc.c
@@ -116,7 +116,7 @@ static void ipu_crtc_dpms(struct drm_crtc *crtc, int mode)
{
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
- dev_info(ipu_crtc->dev, "%s mode: %d\n", __func__, mode);
+ dev_dbg(ipu_crtc->dev, "%s mode: %d\n", __func__, mode);
switch (mode) {
case DRM_MODE_DPMS_ON:
@@ -530,7 +530,7 @@ err_put_resources:
return ret;
}
-static int __devinit ipu_drm_probe(struct platform_device *pdev)
+static int ipu_drm_probe(struct platform_device *pdev)
{
struct ipu_client_platformdata *pdata = pdev->dev.platform_data;
struct ipu_crtc *ipu_crtc;
@@ -554,7 +554,7 @@ static int __devinit ipu_drm_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit ipu_drm_remove(struct platform_device *pdev)
+static int ipu_drm_remove(struct platform_device *pdev)
{
struct ipu_crtc *ipu_crtc = platform_get_drvdata(pdev);
@@ -570,7 +570,7 @@ static struct platform_driver ipu_drm_driver = {
.name = "imx-ipuv3-crtc",
},
.probe = ipu_drm_probe,
- .remove = __devexit_p(ipu_drm_remove),
+ .remove = ipu_drm_remove,
};
module_platform_driver(ipu_drm_driver);
diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/staging/imx-drm/parallel-display.c
index 9b51d732eef..a8064fcc03d 100644
--- a/drivers/staging/imx-drm/parallel-display.c
+++ b/drivers/staging/imx-drm/parallel-display.c
@@ -23,6 +23,7 @@
#include <drm/drm_fb_helper.h>
#include <drm/drm_crtc_helper.h>
#include <linux/videodev2.h>
+#include <linux/pinctrl/consumer.h>
#include "imx-drm.h"
@@ -188,18 +189,27 @@ static int imx_pd_register(struct imx_parallel_display *imxpd)
return 0;
}
-static int __devinit imx_pd_probe(struct platform_device *pdev)
+static int imx_pd_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
const u8 *edidp;
struct imx_parallel_display *imxpd;
int ret;
const char *fmt;
+ struct pinctrl *pinctrl;
imxpd = devm_kzalloc(&pdev->dev, sizeof(*imxpd), GFP_KERNEL);
if (!imxpd)
return -ENOMEM;
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl)) {
+ ret = PTR_ERR(pinctrl);
+ dev_warn(&pdev->dev, "pinctrl_get_select_default failed with %d",
+ ret);
+ return ret;
+ }
+
edidp = of_get_property(np, "edid", &imxpd->edid_len);
if (edidp)
imxpd->edid = kmemdup(edidp, imxpd->edid_len, GFP_KERNEL);
@@ -225,7 +235,7 @@ static int __devinit imx_pd_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit imx_pd_remove(struct platform_device *pdev)
+static int imx_pd_remove(struct platform_device *pdev)
{
struct imx_parallel_display *imxpd = platform_get_drvdata(pdev);
struct drm_connector *connector = &imxpd->connector;
@@ -246,7 +256,7 @@ static const struct of_device_id imx_pd_dt_ids[] = {
static struct platform_driver imx_pd_driver = {
.probe = imx_pd_probe,
- .remove = __devexit_p(imx_pd_remove),
+ .remove = imx_pd_remove,
.driver = {
.of_match_table = imx_pd_dt_ids,
.name = "imx-parallel-display",
diff --git a/drivers/staging/ipack/Kconfig b/drivers/staging/ipack/Kconfig
deleted file mode 100644
index 4cf47066140..00000000000
--- a/drivers/staging/ipack/Kconfig
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# IPACK configuration.
-#
-
-menuconfig IPACK_BUS
- tristate "IndustryPack bus support"
- depends on HAS_IOMEM
- ---help---
- If you say Y here you get support for the IndustryPack Framework
- for drivers for many types of boards that support this industrial
- bus. The IndustryPack Framework is a virtual bus allowing to
- communicate between carrier and mezzanine cards connected through
- this bus.
-
-if IPACK_BUS
-
-source "drivers/staging/ipack/bridges/Kconfig"
-
-source "drivers/staging/ipack/devices/Kconfig"
-
-endif # IPACK
diff --git a/drivers/staging/ipack/TODO b/drivers/staging/ipack/TODO
deleted file mode 100644
index ffafe6911a7..00000000000
--- a/drivers/staging/ipack/TODO
+++ /dev/null
@@ -1,22 +0,0 @@
- TODO
- ====
-Introduction
-============
-
-These drivers add support for IndustryPack devices: carrier and IP module
-boards.
-
-The ipack driver is just an abstraction of the bus providing the common
-operations between the two kind of boards.
-
-TODO
-====
-
-checkpatch.pl warnings
-cleanup
-
-Contact
-=======
-
-Contact: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
-Mailing List: industrypack-devel@lists.sourceforge.net
diff --git a/drivers/staging/ipack/bridges/Kconfig b/drivers/staging/ipack/bridges/Kconfig
deleted file mode 100644
index 97c837ea7a0..00000000000
--- a/drivers/staging/ipack/bridges/Kconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-config BOARD_TPCI200
- tristate "TEWS TPCI-200 support for IndustryPack bus"
- depends on IPACK_BUS
- depends on PCI
- help
- This driver supports the TEWS TPCI200 device for the IndustryPack bus.
- default n
-
diff --git a/drivers/staging/ipack/ipack_ids.h b/drivers/staging/ipack/ipack_ids.h
deleted file mode 100644
index 8153fee3f2f..00000000000
--- a/drivers/staging/ipack/ipack_ids.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * IndustryPack Fromat, Vendor and Device IDs.
- */
-
-/* ID section format versions */
-#define IPACK_ID_VERSION_INVALID 0x00
-#define IPACK_ID_VERSION_1 0x01
-#define IPACK_ID_VERSION_2 0x02
-
-/* Vendors and devices. Sort key: vendor first, device next. */
-#define IPACK1_VENDOR_ID_RESERVED1 0x00
-#define IPACK1_VENDOR_ID_RESERVED2 0xFF
-#define IPACK1_VENDOR_ID_UNREGISTRED01 0x01
-#define IPACK1_VENDOR_ID_UNREGISTRED02 0x02
-#define IPACK1_VENDOR_ID_UNREGISTRED03 0x03
-#define IPACK1_VENDOR_ID_UNREGISTRED04 0x04
-#define IPACK1_VENDOR_ID_UNREGISTRED05 0x05
-#define IPACK1_VENDOR_ID_UNREGISTRED06 0x06
-#define IPACK1_VENDOR_ID_UNREGISTRED07 0x07
-#define IPACK1_VENDOR_ID_UNREGISTRED08 0x08
-#define IPACK1_VENDOR_ID_UNREGISTRED09 0x09
-#define IPACK1_VENDOR_ID_UNREGISTRED10 0x0A
-#define IPACK1_VENDOR_ID_UNREGISTRED11 0x0B
-#define IPACK1_VENDOR_ID_UNREGISTRED12 0x0C
-#define IPACK1_VENDOR_ID_UNREGISTRED13 0x0D
-#define IPACK1_VENDOR_ID_UNREGISTRED14 0x0E
-#define IPACK1_VENDOR_ID_UNREGISTRED15 0x0F
-
-#define IPACK1_VENDOR_ID_SBS 0xF0
-#define IPACK1_DEVICE_ID_SBS_OCTAL_232 0x22
-#define IPACK1_DEVICE_ID_SBS_OCTAL_422 0x2A
-#define IPACK1_DEVICE_ID_SBS_OCTAL_485 0x48
diff --git a/drivers/staging/line6/Kconfig b/drivers/staging/line6/Kconfig
index 43120ff2ab7..b63543658b2 100644
--- a/drivers/staging/line6/Kconfig
+++ b/drivers/staging/line6/Kconfig
@@ -23,32 +23,6 @@ menuconfig LINE6_USB
if LINE6_USB
-config LINE6_USB_DEBUG
- bool "print debug messages"
- default n
- help
- Say Y here to write debug messages to the syslog.
-
- If unsure, say N.
-
-config LINE6_USB_DUMP_CTRL
- bool "dump control messages"
- default n
- help
- Say Y here to write control messages sent to and received from
- Line6 devices to the syslog.
-
- If unsure, say N.
-
-config LINE6_USB_DUMP_MIDI
- bool "dump MIDI messages"
- default n
- help
- Say Y here to write MIDI messages sent to and received from
- Line6 devices to the syslog.
-
- If unsure, say N.
-
config LINE6_USB_DUMP_PCM
bool "dump PCM data"
default n
@@ -59,17 +33,6 @@ config LINE6_USB_DUMP_PCM
If unsure, say N.
-config LINE6_USB_RAW
- bool "raw data communication"
- default n
- help
- Say Y here to create special files which allow to send raw data
- to the device. This bypasses any sanity checks, so if you discover
- the code to erase the firmware, feel free to render your device
- useless, but only after reading the GPL section "NO WARRANTY".
-
- If unsure, say N.
-
config LINE6_USB_IMPULSE_RESPONSE
bool "measure impulse response"
default n
diff --git a/drivers/staging/line6/Makefile b/drivers/staging/line6/Makefile
index 34a2ddacc7e..ae5c374b0f8 100644
--- a/drivers/staging/line6/Makefile
+++ b/drivers/staging/line6/Makefile
@@ -3,9 +3,7 @@ obj-$(CONFIG_LINE6_USB) += line6usb.o
line6usb-y := \
audio.o \
capture.o \
- control.o \
driver.o \
- dumprequest.o \
midi.o \
midibuf.o \
pcm.o \
diff --git a/drivers/staging/line6/audio.c b/drivers/staging/line6/audio.c
index 8e7398393a5..a92e21f7d55 100644
--- a/drivers/staging/line6/audio.c
+++ b/drivers/staging/line6/audio.c
@@ -16,20 +16,16 @@
#include "driver.h"
#include "audio.h"
-static int line6_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *line6_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-
/*
Initialize the Line6 USB audio system.
*/
int line6_init_audio(struct usb_line6 *line6)
{
- static int dev;
struct snd_card *card;
int err;
- err = snd_card_create(line6_index[dev], line6_id[dev], THIS_MODULE, 0,
- &card);
+ err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+ THIS_MODULE, 0, &card);
if (err < 0)
return err;
diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c
index c85c5b6bffb..389c41fd1b7 100644
--- a/drivers/staging/line6/capture.c
+++ b/drivers/staging/line6/capture.c
@@ -256,8 +256,8 @@ static void audio_in_callback(struct urb *urb)
#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE))
#endif
- if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, &line6pcm->flags)
- && (fsize > 0))
+ if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM,
+ &line6pcm->flags) && (fsize > 0))
line6_capture_copy(line6pcm, fbuf, fsize);
}
@@ -274,7 +274,8 @@ static void audio_in_callback(struct urb *urb)
#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE))
#endif
- if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, &line6pcm->flags))
+ if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM,
+ &line6pcm->flags))
line6_capture_check_period(line6pcm, length);
}
}
@@ -356,7 +357,8 @@ int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd)
#ifdef CONFIG_PM
case SNDRV_PCM_TRIGGER_RESUME:
#endif
- err = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
+ err = line6_pcm_acquire(line6pcm,
+ LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
if (err < 0)
return err;
@@ -367,7 +369,8 @@ int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd)
#ifdef CONFIG_PM
case SNDRV_PCM_TRIGGER_SUSPEND:
#endif
- err = line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
+ err = line6_pcm_release(line6pcm,
+ LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
if (err < 0)
return err;
diff --git a/drivers/staging/line6/control.c b/drivers/staging/line6/control.c
deleted file mode 100644
index f8326f587e3..00000000000
--- a/drivers/staging/line6/control.c
+++ /dev/null
@@ -1,995 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- * 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.
- *
- */
-
-#include <linux/usb.h>
-
-#include "control.h"
-#include "driver.h"
-#include "pod.h"
-#include "usbdefs.h"
-#include "variax.h"
-
-#define DEVICE_ATTR2(_name1, _name2, _mode, _show, _store) \
-struct device_attribute dev_attr_##_name1 = __ATTR(_name2, _mode, _show, _store)
-
-#define LINE6_PARAM_R(PREFIX, prefix, type, param) \
-static ssize_t prefix##_get_##param(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- return prefix##_get_param_##type(dev, buf, PREFIX##_##param); \
-}
-
-#define LINE6_PARAM_RW(PREFIX, prefix, type, param) \
-LINE6_PARAM_R(PREFIX, prefix, type, param); \
-static ssize_t prefix##_set_##param(struct device *dev, \
- struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- return prefix##_set_param_##type(dev, buf, count, PREFIX##_##param); \
-}
-
-#define POD_PARAM_R(type, param) LINE6_PARAM_R(POD, pod, type, param)
-#define POD_PARAM_RW(type, param) LINE6_PARAM_RW(POD, pod, type, param)
-#define VARIAX_PARAM_R(type, param) LINE6_PARAM_R(VARIAX, variax, type, param)
-#define VARIAX_PARAM_RW(type, param) LINE6_PARAM_RW(VARIAX, variax, type, param)
-
-static ssize_t pod_get_param_int(struct device *dev, char *buf, int param)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- int retval = line6_dump_wait_interruptible(&pod->dumpreq);
- if (retval < 0)
- return retval;
- return sprintf(buf, "%d\n", pod->prog_data.control[param]);
-}
-
-static ssize_t pod_set_param_int(struct device *dev, const char *buf,
- size_t count, int param)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- u8 value;
- int retval;
-
- retval = kstrtou8(buf, 10, &value);
- if (retval)
- return retval;
-
- line6_pod_transmit_parameter(pod, param, value);
- return count;
-}
-
-static ssize_t variax_get_param_int(struct device *dev, char *buf, int param)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_variax *variax = usb_get_intfdata(interface);
- int retval = line6_dump_wait_interruptible(&variax->dumpreq);
- if (retval < 0)
- return retval;
- return sprintf(buf, "%d\n", variax->model_data.control[param]);
-}
-
-static ssize_t variax_get_param_float(struct device *dev, char *buf, int param)
-{
- /*
- We do our own floating point handling here since at the time
- this code was written (Jan 2006) it was highly discouraged to
- use floating point arithmetic in the kernel. If you think that
- this no longer applies, feel free to replace this by generic
- floating point code.
- */
-
- static const int BIAS = 0x7f;
- static const int OFFSET = 0xf;
- static const int PRECISION = 1000;
-
- int len = 0;
- unsigned part_int, part_frac;
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_variax *variax = usb_get_intfdata(interface);
- const unsigned char *p = variax->model_data.control + param;
- int retval = line6_dump_wait_interruptible(&variax->dumpreq);
- if (retval < 0)
- return retval;
-
- if ((p[0] == 0) && (p[1] == 0) && (p[2] == 0))
- part_int = part_frac = 0;
- else {
- int exponent = (((p[0] & 0x7f) << 1) | (p[1] >> 7)) - BIAS;
- unsigned mantissa = (p[1] << 8) | p[2] | 0x8000;
- exponent -= OFFSET;
-
- if (exponent >= 0) {
- part_int = mantissa << exponent;
- part_frac = 0;
- } else {
- part_int = mantissa >> -exponent;
- part_frac = (mantissa << (32 + exponent)) & 0xffffffff;
- }
-
- part_frac =
- (part_frac / ((1UL << 31) / (PRECISION / 2 * 10)) + 5) / 10;
- }
-
- len +=
- sprintf(buf + len, "%s%d.%03d\n", ((p[0] & 0x80) ? "-" : ""),
- part_int, part_frac);
- return len;
-}
-
-POD_PARAM_RW(int, tweak);
-POD_PARAM_RW(int, wah_position);
-POD_PARAM_RW(int, compression_gain);
-POD_PARAM_RW(int, vol_pedal_position);
-POD_PARAM_RW(int, compression_threshold);
-POD_PARAM_RW(int, pan);
-POD_PARAM_RW(int, amp_model_setup);
-POD_PARAM_RW(int, amp_model);
-POD_PARAM_RW(int, drive);
-POD_PARAM_RW(int, bass);
-POD_PARAM_RW(int, mid);
-POD_PARAM_RW(int, lowmid);
-POD_PARAM_RW(int, treble);
-POD_PARAM_RW(int, highmid);
-POD_PARAM_RW(int, chan_vol);
-POD_PARAM_RW(int, reverb_mix);
-POD_PARAM_RW(int, effect_setup);
-POD_PARAM_RW(int, band_1_frequency);
-POD_PARAM_RW(int, presence);
-POD_PARAM_RW(int, treble__bass);
-POD_PARAM_RW(int, noise_gate_enable);
-POD_PARAM_RW(int, gate_threshold);
-POD_PARAM_RW(int, gate_decay_time);
-POD_PARAM_RW(int, stomp_enable);
-POD_PARAM_RW(int, comp_enable);
-POD_PARAM_RW(int, stomp_time);
-POD_PARAM_RW(int, delay_enable);
-POD_PARAM_RW(int, mod_param_1);
-POD_PARAM_RW(int, delay_param_1);
-POD_PARAM_RW(int, delay_param_1_note_value);
-POD_PARAM_RW(int, band_2_frequency__bass);
-POD_PARAM_RW(int, delay_param_2);
-POD_PARAM_RW(int, delay_volume_mix);
-POD_PARAM_RW(int, delay_param_3);
-POD_PARAM_RW(int, reverb_enable);
-POD_PARAM_RW(int, reverb_type);
-POD_PARAM_RW(int, reverb_decay);
-POD_PARAM_RW(int, reverb_tone);
-POD_PARAM_RW(int, reverb_pre_delay);
-POD_PARAM_RW(int, reverb_pre_post);
-POD_PARAM_RW(int, band_2_frequency);
-POD_PARAM_RW(int, band_3_frequency__bass);
-POD_PARAM_RW(int, wah_enable);
-POD_PARAM_RW(int, modulation_lo_cut);
-POD_PARAM_RW(int, delay_reverb_lo_cut);
-POD_PARAM_RW(int, volume_pedal_minimum);
-POD_PARAM_RW(int, eq_pre_post);
-POD_PARAM_RW(int, volume_pre_post);
-POD_PARAM_RW(int, di_model);
-POD_PARAM_RW(int, di_delay);
-POD_PARAM_RW(int, mod_enable);
-POD_PARAM_RW(int, mod_param_1_note_value);
-POD_PARAM_RW(int, mod_param_2);
-POD_PARAM_RW(int, mod_param_3);
-POD_PARAM_RW(int, mod_param_4);
-POD_PARAM_RW(int, mod_param_5);
-POD_PARAM_RW(int, mod_volume_mix);
-POD_PARAM_RW(int, mod_pre_post);
-POD_PARAM_RW(int, modulation_model);
-POD_PARAM_RW(int, band_3_frequency);
-POD_PARAM_RW(int, band_4_frequency__bass);
-POD_PARAM_RW(int, mod_param_1_double_precision);
-POD_PARAM_RW(int, delay_param_1_double_precision);
-POD_PARAM_RW(int, eq_enable);
-POD_PARAM_RW(int, tap);
-POD_PARAM_RW(int, volume_tweak_pedal_assign);
-POD_PARAM_RW(int, band_5_frequency);
-POD_PARAM_RW(int, tuner);
-POD_PARAM_RW(int, mic_selection);
-POD_PARAM_RW(int, cabinet_model);
-POD_PARAM_RW(int, stomp_model);
-POD_PARAM_RW(int, roomlevel);
-POD_PARAM_RW(int, band_4_frequency);
-POD_PARAM_RW(int, band_6_frequency);
-POD_PARAM_RW(int, stomp_param_1_note_value);
-POD_PARAM_RW(int, stomp_param_2);
-POD_PARAM_RW(int, stomp_param_3);
-POD_PARAM_RW(int, stomp_param_4);
-POD_PARAM_RW(int, stomp_param_5);
-POD_PARAM_RW(int, stomp_param_6);
-POD_PARAM_RW(int, amp_switch_select);
-POD_PARAM_RW(int, delay_param_4);
-POD_PARAM_RW(int, delay_param_5);
-POD_PARAM_RW(int, delay_pre_post);
-POD_PARAM_RW(int, delay_model);
-POD_PARAM_RW(int, delay_verb_model);
-POD_PARAM_RW(int, tempo_msb);
-POD_PARAM_RW(int, tempo_lsb);
-POD_PARAM_RW(int, wah_model);
-POD_PARAM_RW(int, bypass_volume);
-POD_PARAM_RW(int, fx_loop_on_off);
-POD_PARAM_RW(int, tweak_param_select);
-POD_PARAM_RW(int, amp1_engage);
-POD_PARAM_RW(int, band_1_gain);
-POD_PARAM_RW(int, band_2_gain__bass);
-POD_PARAM_RW(int, band_2_gain);
-POD_PARAM_RW(int, band_3_gain__bass);
-POD_PARAM_RW(int, band_3_gain);
-POD_PARAM_RW(int, band_4_gain__bass);
-POD_PARAM_RW(int, band_5_gain__bass);
-POD_PARAM_RW(int, band_4_gain);
-POD_PARAM_RW(int, band_6_gain__bass);
-VARIAX_PARAM_R(int, body);
-VARIAX_PARAM_R(int, pickup1_enable);
-VARIAX_PARAM_R(int, pickup1_type);
-VARIAX_PARAM_R(float, pickup1_position);
-VARIAX_PARAM_R(float, pickup1_angle);
-VARIAX_PARAM_R(float, pickup1_level);
-VARIAX_PARAM_R(int, pickup2_enable);
-VARIAX_PARAM_R(int, pickup2_type);
-VARIAX_PARAM_R(float, pickup2_position);
-VARIAX_PARAM_R(float, pickup2_angle);
-VARIAX_PARAM_R(float, pickup2_level);
-VARIAX_PARAM_R(int, pickup_phase);
-VARIAX_PARAM_R(float, capacitance);
-VARIAX_PARAM_R(float, tone_resistance);
-VARIAX_PARAM_R(float, volume_resistance);
-VARIAX_PARAM_R(int, taper);
-VARIAX_PARAM_R(float, tone_dump);
-VARIAX_PARAM_R(int, save_tone);
-VARIAX_PARAM_R(float, volume_dump);
-VARIAX_PARAM_R(int, tuning_enable);
-VARIAX_PARAM_R(int, tuning6);
-VARIAX_PARAM_R(int, tuning5);
-VARIAX_PARAM_R(int, tuning4);
-VARIAX_PARAM_R(int, tuning3);
-VARIAX_PARAM_R(int, tuning2);
-VARIAX_PARAM_R(int, tuning1);
-VARIAX_PARAM_R(float, detune6);
-VARIAX_PARAM_R(float, detune5);
-VARIAX_PARAM_R(float, detune4);
-VARIAX_PARAM_R(float, detune3);
-VARIAX_PARAM_R(float, detune2);
-VARIAX_PARAM_R(float, detune1);
-VARIAX_PARAM_R(float, mix6);
-VARIAX_PARAM_R(float, mix5);
-VARIAX_PARAM_R(float, mix4);
-VARIAX_PARAM_R(float, mix3);
-VARIAX_PARAM_R(float, mix2);
-VARIAX_PARAM_R(float, mix1);
-VARIAX_PARAM_R(int, pickup_wiring);
-
-static DEVICE_ATTR(tweak, S_IWUSR | S_IRUGO, pod_get_tweak, pod_set_tweak);
-static DEVICE_ATTR(wah_position, S_IWUSR | S_IRUGO, pod_get_wah_position,
- pod_set_wah_position);
-static DEVICE_ATTR(compression_gain, S_IWUSR | S_IRUGO,
- pod_get_compression_gain, pod_set_compression_gain);
-static DEVICE_ATTR(vol_pedal_position, S_IWUSR | S_IRUGO,
- pod_get_vol_pedal_position, pod_set_vol_pedal_position);
-static DEVICE_ATTR(compression_threshold, S_IWUSR | S_IRUGO,
- pod_get_compression_threshold,
- pod_set_compression_threshold);
-static DEVICE_ATTR(pan, S_IWUSR | S_IRUGO, pod_get_pan, pod_set_pan);
-static DEVICE_ATTR(amp_model_setup, S_IWUSR | S_IRUGO, pod_get_amp_model_setup,
- pod_set_amp_model_setup);
-static DEVICE_ATTR(amp_model, S_IWUSR | S_IRUGO, pod_get_amp_model,
- pod_set_amp_model);
-static DEVICE_ATTR(drive, S_IWUSR | S_IRUGO, pod_get_drive, pod_set_drive);
-static DEVICE_ATTR(bass, S_IWUSR | S_IRUGO, pod_get_bass, pod_set_bass);
-static DEVICE_ATTR(mid, S_IWUSR | S_IRUGO, pod_get_mid, pod_set_mid);
-static DEVICE_ATTR(lowmid, S_IWUSR | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
-static DEVICE_ATTR(treble, S_IWUSR | S_IRUGO, pod_get_treble, pod_set_treble);
-static DEVICE_ATTR(highmid, S_IWUSR | S_IRUGO, pod_get_highmid,
- pod_set_highmid);
-static DEVICE_ATTR(chan_vol, S_IWUSR | S_IRUGO, pod_get_chan_vol,
- pod_set_chan_vol);
-static DEVICE_ATTR(reverb_mix, S_IWUSR | S_IRUGO, pod_get_reverb_mix,
- pod_set_reverb_mix);
-static DEVICE_ATTR(effect_setup, S_IWUSR | S_IRUGO, pod_get_effect_setup,
- pod_set_effect_setup);
-static DEVICE_ATTR(band_1_frequency, S_IWUSR | S_IRUGO,
- pod_get_band_1_frequency, pod_set_band_1_frequency);
-static DEVICE_ATTR(presence, S_IWUSR | S_IRUGO, pod_get_presence,
- pod_set_presence);
-static DEVICE_ATTR2(treble__bass, treble, S_IWUSR | S_IRUGO,
- pod_get_treble__bass, pod_set_treble__bass);
-static DEVICE_ATTR(noise_gate_enable, S_IWUSR | S_IRUGO,
- pod_get_noise_gate_enable, pod_set_noise_gate_enable);
-static DEVICE_ATTR(gate_threshold, S_IWUSR | S_IRUGO, pod_get_gate_threshold,
- pod_set_gate_threshold);
-static DEVICE_ATTR(gate_decay_time, S_IWUSR | S_IRUGO, pod_get_gate_decay_time,
- pod_set_gate_decay_time);
-static DEVICE_ATTR(stomp_enable, S_IWUSR | S_IRUGO, pod_get_stomp_enable,
- pod_set_stomp_enable);
-static DEVICE_ATTR(comp_enable, S_IWUSR | S_IRUGO, pod_get_comp_enable,
- pod_set_comp_enable);
-static DEVICE_ATTR(stomp_time, S_IWUSR | S_IRUGO, pod_get_stomp_time,
- pod_set_stomp_time);
-static DEVICE_ATTR(delay_enable, S_IWUSR | S_IRUGO, pod_get_delay_enable,
- pod_set_delay_enable);
-static DEVICE_ATTR(mod_param_1, S_IWUSR | S_IRUGO, pod_get_mod_param_1,
- pod_set_mod_param_1);
-static DEVICE_ATTR(delay_param_1, S_IWUSR | S_IRUGO, pod_get_delay_param_1,
- pod_set_delay_param_1);
-static DEVICE_ATTR(delay_param_1_note_value, S_IWUSR | S_IRUGO,
- pod_get_delay_param_1_note_value,
- pod_set_delay_param_1_note_value);
-static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUSR | S_IRUGO,
- pod_get_band_2_frequency__bass,
- pod_set_band_2_frequency__bass);
-static DEVICE_ATTR(delay_param_2, S_IWUSR | S_IRUGO, pod_get_delay_param_2,
- pod_set_delay_param_2);
-static DEVICE_ATTR(delay_volume_mix, S_IWUSR | S_IRUGO,
- pod_get_delay_volume_mix, pod_set_delay_volume_mix);
-static DEVICE_ATTR(delay_param_3, S_IWUSR | S_IRUGO, pod_get_delay_param_3,
- pod_set_delay_param_3);
-static DEVICE_ATTR(reverb_enable, S_IWUSR | S_IRUGO, pod_get_reverb_enable,
- pod_set_reverb_enable);
-static DEVICE_ATTR(reverb_type, S_IWUSR | S_IRUGO, pod_get_reverb_type,
- pod_set_reverb_type);
-static DEVICE_ATTR(reverb_decay, S_IWUSR | S_IRUGO, pod_get_reverb_decay,
- pod_set_reverb_decay);
-static DEVICE_ATTR(reverb_tone, S_IWUSR | S_IRUGO, pod_get_reverb_tone,
- pod_set_reverb_tone);
-static DEVICE_ATTR(reverb_pre_delay, S_IWUSR | S_IRUGO,
- pod_get_reverb_pre_delay, pod_set_reverb_pre_delay);
-static DEVICE_ATTR(reverb_pre_post, S_IWUSR | S_IRUGO, pod_get_reverb_pre_post,
- pod_set_reverb_pre_post);
-static DEVICE_ATTR(band_2_frequency, S_IWUSR | S_IRUGO,
- pod_get_band_2_frequency, pod_set_band_2_frequency);
-static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUSR | S_IRUGO,
- pod_get_band_3_frequency__bass,
- pod_set_band_3_frequency__bass);
-static DEVICE_ATTR(wah_enable, S_IWUSR | S_IRUGO, pod_get_wah_enable,
- pod_set_wah_enable);
-static DEVICE_ATTR(modulation_lo_cut, S_IWUSR | S_IRUGO,
- pod_get_modulation_lo_cut, pod_set_modulation_lo_cut);
-static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUSR | S_IRUGO,
- pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut);
-static DEVICE_ATTR(volume_pedal_minimum, S_IWUSR | S_IRUGO,
- pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum);
-static DEVICE_ATTR(eq_pre_post, S_IWUSR | S_IRUGO, pod_get_eq_pre_post,
- pod_set_eq_pre_post);
-static DEVICE_ATTR(volume_pre_post, S_IWUSR | S_IRUGO, pod_get_volume_pre_post,
- pod_set_volume_pre_post);
-static DEVICE_ATTR(di_model, S_IWUSR | S_IRUGO, pod_get_di_model,
- pod_set_di_model);
-static DEVICE_ATTR(di_delay, S_IWUSR | S_IRUGO, pod_get_di_delay,
- pod_set_di_delay);
-static DEVICE_ATTR(mod_enable, S_IWUSR | S_IRUGO, pod_get_mod_enable,
- pod_set_mod_enable);
-static DEVICE_ATTR(mod_param_1_note_value, S_IWUSR | S_IRUGO,
- pod_get_mod_param_1_note_value,
- pod_set_mod_param_1_note_value);
-static DEVICE_ATTR(mod_param_2, S_IWUSR | S_IRUGO, pod_get_mod_param_2,
- pod_set_mod_param_2);
-static DEVICE_ATTR(mod_param_3, S_IWUSR | S_IRUGO, pod_get_mod_param_3,
- pod_set_mod_param_3);
-static DEVICE_ATTR(mod_param_4, S_IWUSR | S_IRUGO, pod_get_mod_param_4,
- pod_set_mod_param_4);
-static DEVICE_ATTR(mod_param_5, S_IWUSR | S_IRUGO, pod_get_mod_param_5,
- pod_set_mod_param_5);
-static DEVICE_ATTR(mod_volume_mix, S_IWUSR | S_IRUGO, pod_get_mod_volume_mix,
- pod_set_mod_volume_mix);
-static DEVICE_ATTR(mod_pre_post, S_IWUSR | S_IRUGO, pod_get_mod_pre_post,
- pod_set_mod_pre_post);
-static DEVICE_ATTR(modulation_model, S_IWUSR | S_IRUGO,
- pod_get_modulation_model, pod_set_modulation_model);
-static DEVICE_ATTR(band_3_frequency, S_IWUSR | S_IRUGO,
- pod_get_band_3_frequency, pod_set_band_3_frequency);
-static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUSR | S_IRUGO,
- pod_get_band_4_frequency__bass,
- pod_set_band_4_frequency__bass);
-static DEVICE_ATTR(mod_param_1_double_precision, S_IWUSR | S_IRUGO,
- pod_get_mod_param_1_double_precision,
- pod_set_mod_param_1_double_precision);
-static DEVICE_ATTR(delay_param_1_double_precision, S_IWUSR | S_IRUGO,
- pod_get_delay_param_1_double_precision,
- pod_set_delay_param_1_double_precision);
-static DEVICE_ATTR(eq_enable, S_IWUSR | S_IRUGO, pod_get_eq_enable,
- pod_set_eq_enable);
-static DEVICE_ATTR(tap, S_IWUSR | S_IRUGO, pod_get_tap, pod_set_tap);
-static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUSR | S_IRUGO,
- pod_get_volume_tweak_pedal_assign,
- pod_set_volume_tweak_pedal_assign);
-static DEVICE_ATTR(band_5_frequency, S_IWUSR | S_IRUGO,
- pod_get_band_5_frequency, pod_set_band_5_frequency);
-static DEVICE_ATTR(tuner, S_IWUSR | S_IRUGO, pod_get_tuner, pod_set_tuner);
-static DEVICE_ATTR(mic_selection, S_IWUSR | S_IRUGO, pod_get_mic_selection,
- pod_set_mic_selection);
-static DEVICE_ATTR(cabinet_model, S_IWUSR | S_IRUGO, pod_get_cabinet_model,
- pod_set_cabinet_model);
-static DEVICE_ATTR(stomp_model, S_IWUSR | S_IRUGO, pod_get_stomp_model,
- pod_set_stomp_model);
-static DEVICE_ATTR(roomlevel, S_IWUSR | S_IRUGO, pod_get_roomlevel,
- pod_set_roomlevel);
-static DEVICE_ATTR(band_4_frequency, S_IWUSR | S_IRUGO,
- pod_get_band_4_frequency, pod_set_band_4_frequency);
-static DEVICE_ATTR(band_6_frequency, S_IWUSR | S_IRUGO,
- pod_get_band_6_frequency, pod_set_band_6_frequency);
-static DEVICE_ATTR(stomp_param_1_note_value, S_IWUSR | S_IRUGO,
- pod_get_stomp_param_1_note_value,
- pod_set_stomp_param_1_note_value);
-static DEVICE_ATTR(stomp_param_2, S_IWUSR | S_IRUGO, pod_get_stomp_param_2,
- pod_set_stomp_param_2);
-static DEVICE_ATTR(stomp_param_3, S_IWUSR | S_IRUGO, pod_get_stomp_param_3,
- pod_set_stomp_param_3);
-static DEVICE_ATTR(stomp_param_4, S_IWUSR | S_IRUGO, pod_get_stomp_param_4,
- pod_set_stomp_param_4);
-static DEVICE_ATTR(stomp_param_5, S_IWUSR | S_IRUGO, pod_get_stomp_param_5,
- pod_set_stomp_param_5);
-static DEVICE_ATTR(stomp_param_6, S_IWUSR | S_IRUGO, pod_get_stomp_param_6,
- pod_set_stomp_param_6);
-static DEVICE_ATTR(amp_switch_select, S_IWUSR | S_IRUGO,
- pod_get_amp_switch_select, pod_set_amp_switch_select);
-static DEVICE_ATTR(delay_param_4, S_IWUSR | S_IRUGO, pod_get_delay_param_4,
- pod_set_delay_param_4);
-static DEVICE_ATTR(delay_param_5, S_IWUSR | S_IRUGO, pod_get_delay_param_5,
- pod_set_delay_param_5);
-static DEVICE_ATTR(delay_pre_post, S_IWUSR | S_IRUGO, pod_get_delay_pre_post,
- pod_set_delay_pre_post);
-static DEVICE_ATTR(delay_model, S_IWUSR | S_IRUGO, pod_get_delay_model,
- pod_set_delay_model);
-static DEVICE_ATTR(delay_verb_model, S_IWUSR | S_IRUGO,
- pod_get_delay_verb_model, pod_set_delay_verb_model);
-static DEVICE_ATTR(tempo_msb, S_IWUSR | S_IRUGO, pod_get_tempo_msb,
- pod_set_tempo_msb);
-static DEVICE_ATTR(tempo_lsb, S_IWUSR | S_IRUGO, pod_get_tempo_lsb,
- pod_set_tempo_lsb);
-static DEVICE_ATTR(wah_model, S_IWUSR | S_IRUGO, pod_get_wah_model,
- pod_set_wah_model);
-static DEVICE_ATTR(bypass_volume, S_IWUSR | S_IRUGO, pod_get_bypass_volume,
- pod_set_bypass_volume);
-static DEVICE_ATTR(fx_loop_on_off, S_IWUSR | S_IRUGO, pod_get_fx_loop_on_off,
- pod_set_fx_loop_on_off);
-static DEVICE_ATTR(tweak_param_select, S_IWUSR | S_IRUGO,
- pod_get_tweak_param_select, pod_set_tweak_param_select);
-static DEVICE_ATTR(amp1_engage, S_IWUSR | S_IRUGO, pod_get_amp1_engage,
- pod_set_amp1_engage);
-static DEVICE_ATTR(band_1_gain, S_IWUSR | S_IRUGO, pod_get_band_1_gain,
- pod_set_band_1_gain);
-static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUSR | S_IRUGO,
- pod_get_band_2_gain__bass, pod_set_band_2_gain__bass);
-static DEVICE_ATTR(band_2_gain, S_IWUSR | S_IRUGO, pod_get_band_2_gain,
- pod_set_band_2_gain);
-static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUSR | S_IRUGO,
- pod_get_band_3_gain__bass, pod_set_band_3_gain__bass);
-static DEVICE_ATTR(band_3_gain, S_IWUSR | S_IRUGO, pod_get_band_3_gain,
- pod_set_band_3_gain);
-static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUSR | S_IRUGO,
- pod_get_band_4_gain__bass, pod_set_band_4_gain__bass);
-static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUSR | S_IRUGO,
- pod_get_band_5_gain__bass, pod_set_band_5_gain__bass);
-static DEVICE_ATTR(band_4_gain, S_IWUSR | S_IRUGO, pod_get_band_4_gain,
- pod_set_band_4_gain);
-static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUSR | S_IRUGO,
- pod_get_band_6_gain__bass, pod_set_band_6_gain__bass);
-static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write);
-static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable,
- line6_nop_write);
-static DEVICE_ATTR(pickup1_type, S_IRUGO, variax_get_pickup1_type,
- line6_nop_write);
-static DEVICE_ATTR(pickup1_position, S_IRUGO, variax_get_pickup1_position,
- line6_nop_write);
-static DEVICE_ATTR(pickup1_angle, S_IRUGO, variax_get_pickup1_angle,
- line6_nop_write);
-static DEVICE_ATTR(pickup1_level, S_IRUGO, variax_get_pickup1_level,
- line6_nop_write);
-static DEVICE_ATTR(pickup2_enable, S_IRUGO, variax_get_pickup2_enable,
- line6_nop_write);
-static DEVICE_ATTR(pickup2_type, S_IRUGO, variax_get_pickup2_type,
- line6_nop_write);
-static DEVICE_ATTR(pickup2_position, S_IRUGO, variax_get_pickup2_position,
- line6_nop_write);
-static DEVICE_ATTR(pickup2_angle, S_IRUGO, variax_get_pickup2_angle,
- line6_nop_write);
-static DEVICE_ATTR(pickup2_level, S_IRUGO, variax_get_pickup2_level,
- line6_nop_write);
-static DEVICE_ATTR(pickup_phase, S_IRUGO, variax_get_pickup_phase,
- line6_nop_write);
-static DEVICE_ATTR(capacitance, S_IRUGO, variax_get_capacitance,
- line6_nop_write);
-static DEVICE_ATTR(tone_resistance, S_IRUGO, variax_get_tone_resistance,
- line6_nop_write);
-static DEVICE_ATTR(volume_resistance, S_IRUGO, variax_get_volume_resistance,
- line6_nop_write);
-static DEVICE_ATTR(taper, S_IRUGO, variax_get_taper, line6_nop_write);
-static DEVICE_ATTR(tone_dump, S_IRUGO, variax_get_tone_dump, line6_nop_write);
-static DEVICE_ATTR(save_tone, S_IRUGO, variax_get_save_tone, line6_nop_write);
-static DEVICE_ATTR(volume_dump, S_IRUGO, variax_get_volume_dump,
- line6_nop_write);
-static DEVICE_ATTR(tuning_enable, S_IRUGO, variax_get_tuning_enable,
- line6_nop_write);
-static DEVICE_ATTR(tuning6, S_IRUGO, variax_get_tuning6, line6_nop_write);
-static DEVICE_ATTR(tuning5, S_IRUGO, variax_get_tuning5, line6_nop_write);
-static DEVICE_ATTR(tuning4, S_IRUGO, variax_get_tuning4, line6_nop_write);
-static DEVICE_ATTR(tuning3, S_IRUGO, variax_get_tuning3, line6_nop_write);
-static DEVICE_ATTR(tuning2, S_IRUGO, variax_get_tuning2, line6_nop_write);
-static DEVICE_ATTR(tuning1, S_IRUGO, variax_get_tuning1, line6_nop_write);
-static DEVICE_ATTR(detune6, S_IRUGO, variax_get_detune6, line6_nop_write);
-static DEVICE_ATTR(detune5, S_IRUGO, variax_get_detune5, line6_nop_write);
-static DEVICE_ATTR(detune4, S_IRUGO, variax_get_detune4, line6_nop_write);
-static DEVICE_ATTR(detune3, S_IRUGO, variax_get_detune3, line6_nop_write);
-static DEVICE_ATTR(detune2, S_IRUGO, variax_get_detune2, line6_nop_write);
-static DEVICE_ATTR(detune1, S_IRUGO, variax_get_detune1, line6_nop_write);
-static DEVICE_ATTR(mix6, S_IRUGO, variax_get_mix6, line6_nop_write);
-static DEVICE_ATTR(mix5, S_IRUGO, variax_get_mix5, line6_nop_write);
-static DEVICE_ATTR(mix4, S_IRUGO, variax_get_mix4, line6_nop_write);
-static DEVICE_ATTR(mix3, S_IRUGO, variax_get_mix3, line6_nop_write);
-static DEVICE_ATTR(mix2, S_IRUGO, variax_get_mix2, line6_nop_write);
-static DEVICE_ATTR(mix1, S_IRUGO, variax_get_mix1, line6_nop_write);
-static DEVICE_ATTR(pickup_wiring, S_IRUGO, variax_get_pickup_wiring,
- line6_nop_write);
-
-int line6_pod_create_files(int firmware, int type, struct device *dev)
-{
- int err;
- CHECK_RETURN(device_create_file(dev, &dev_attr_tweak));
- CHECK_RETURN(device_create_file(dev, &dev_attr_wah_position));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_compression_gain));
- CHECK_RETURN(device_create_file(dev, &dev_attr_vol_pedal_position));
- CHECK_RETURN(device_create_file(dev, &dev_attr_compression_threshold));
- CHECK_RETURN(device_create_file(dev, &dev_attr_pan));
- CHECK_RETURN(device_create_file(dev, &dev_attr_amp_model_setup));
- if (firmware >= 200)
- CHECK_RETURN(device_create_file(dev, &dev_attr_amp_model));
- CHECK_RETURN(device_create_file(dev, &dev_attr_drive));
- CHECK_RETURN(device_create_file(dev, &dev_attr_bass));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_mid));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_lowmid));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_treble));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_highmid));
- CHECK_RETURN(device_create_file(dev, &dev_attr_chan_vol));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_mix));
- CHECK_RETURN(device_create_file(dev, &dev_attr_effect_setup));
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_1_frequency));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_presence));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_treble__bass));
- CHECK_RETURN(device_create_file(dev, &dev_attr_noise_gate_enable));
- CHECK_RETURN(device_create_file(dev, &dev_attr_gate_threshold));
- CHECK_RETURN(device_create_file(dev, &dev_attr_gate_decay_time));
- CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_enable));
- CHECK_RETURN(device_create_file(dev, &dev_attr_comp_enable));
- CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_time));
- CHECK_RETURN(device_create_file(dev, &dev_attr_delay_enable));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1));
- CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1));
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_delay_param_1_note_value));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_2_frequency__bass));
- CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_2));
- CHECK_RETURN(device_create_file(dev, &dev_attr_delay_volume_mix));
- CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_3));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_enable));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_type));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_decay));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_tone));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_reverb_pre_delay));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_reverb_pre_post));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_2_frequency));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_3_frequency__bass));
- CHECK_RETURN(device_create_file(dev, &dev_attr_wah_enable));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_modulation_lo_cut));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_delay_reverb_lo_cut));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_volume_pedal_minimum));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_eq_pre_post));
- CHECK_RETURN(device_create_file(dev, &dev_attr_volume_pre_post));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_di_model));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_di_delay));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mod_enable));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1_note_value));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_2));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_3));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_4));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_5));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mod_volume_mix));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mod_pre_post));
- CHECK_RETURN(device_create_file(dev, &dev_attr_modulation_model));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_3_frequency));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_4_frequency__bass));
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_mod_param_1_double_precision));
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_delay_param_1_double_precision));
- if (firmware >= 200)
- CHECK_RETURN(device_create_file(dev, &dev_attr_eq_enable));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tap));
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_volume_tweak_pedal_assign));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_5_frequency));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuner));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mic_selection));
- CHECK_RETURN(device_create_file(dev, &dev_attr_cabinet_model));
- CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_model));
- CHECK_RETURN(device_create_file(dev, &dev_attr_roomlevel));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_4_frequency));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_6_frequency));
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_stomp_param_1_note_value));
- CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_2));
- CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_3));
- CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_4));
- CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_5));
- CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_6));
- if ((type & (LINE6_BITS_LIVE)) != 0)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_amp_switch_select));
- CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_4));
- CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_5));
- CHECK_RETURN(device_create_file(dev, &dev_attr_delay_pre_post));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_delay_model));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_delay_verb_model));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tempo_msb));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tempo_lsb));
- if (firmware >= 300)
- CHECK_RETURN(device_create_file(dev, &dev_attr_wah_model));
- if (firmware >= 214)
- CHECK_RETURN(device_create_file(dev, &dev_attr_bypass_volume));
- if ((type & (LINE6_BITS_PRO)) != 0)
- CHECK_RETURN(device_create_file(dev, &dev_attr_fx_loop_on_off));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tweak_param_select));
- CHECK_RETURN(device_create_file(dev, &dev_attr_amp1_engage));
- if (firmware >= 200)
- CHECK_RETURN(device_create_file(dev, &dev_attr_band_1_gain));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_2_gain__bass));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_2_gain));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_3_gain__bass));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_3_gain));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_4_gain__bass));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_5_gain__bass));
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_4_gain));
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- CHECK_RETURN(device_create_file
- (dev, &dev_attr_band_6_gain__bass));
- return 0;
-}
-
-void line6_pod_remove_files(int firmware, int type, struct device *dev)
-{
- device_remove_file(dev, &dev_attr_tweak);
- device_remove_file(dev, &dev_attr_wah_position);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_compression_gain);
- device_remove_file(dev, &dev_attr_vol_pedal_position);
- device_remove_file(dev, &dev_attr_compression_threshold);
- device_remove_file(dev, &dev_attr_pan);
- device_remove_file(dev, &dev_attr_amp_model_setup);
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_amp_model);
- device_remove_file(dev, &dev_attr_drive);
- device_remove_file(dev, &dev_attr_bass);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_mid);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_lowmid);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_treble);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_highmid);
- device_remove_file(dev, &dev_attr_chan_vol);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_reverb_mix);
- device_remove_file(dev, &dev_attr_effect_setup);
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_1_frequency);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_presence);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_treble__bass);
- device_remove_file(dev, &dev_attr_noise_gate_enable);
- device_remove_file(dev, &dev_attr_gate_threshold);
- device_remove_file(dev, &dev_attr_gate_decay_time);
- device_remove_file(dev, &dev_attr_stomp_enable);
- device_remove_file(dev, &dev_attr_comp_enable);
- device_remove_file(dev, &dev_attr_stomp_time);
- device_remove_file(dev, &dev_attr_delay_enable);
- device_remove_file(dev, &dev_attr_mod_param_1);
- device_remove_file(dev, &dev_attr_delay_param_1);
- device_remove_file(dev, &dev_attr_delay_param_1_note_value);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev,
- &dev_attr_band_2_frequency__bass);
- device_remove_file(dev, &dev_attr_delay_param_2);
- device_remove_file(dev, &dev_attr_delay_volume_mix);
- device_remove_file(dev, &dev_attr_delay_param_3);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_reverb_enable);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_reverb_type);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_reverb_decay);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_reverb_tone);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_reverb_pre_delay);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_reverb_pre_post);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_2_frequency);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev,
- &dev_attr_band_3_frequency__bass);
- device_remove_file(dev, &dev_attr_wah_enable);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_modulation_lo_cut);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_delay_reverb_lo_cut);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_volume_pedal_minimum);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_eq_pre_post);
- device_remove_file(dev, &dev_attr_volume_pre_post);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_di_model);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_di_delay);
- device_remove_file(dev, &dev_attr_mod_enable);
- device_remove_file(dev, &dev_attr_mod_param_1_note_value);
- device_remove_file(dev, &dev_attr_mod_param_2);
- device_remove_file(dev, &dev_attr_mod_param_3);
- device_remove_file(dev, &dev_attr_mod_param_4);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_mod_param_5);
- device_remove_file(dev, &dev_attr_mod_volume_mix);
- device_remove_file(dev, &dev_attr_mod_pre_post);
- device_remove_file(dev, &dev_attr_modulation_model);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_3_frequency);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev,
- &dev_attr_band_4_frequency__bass);
- device_remove_file(dev, &dev_attr_mod_param_1_double_precision);
- device_remove_file(dev, &dev_attr_delay_param_1_double_precision);
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_eq_enable);
- device_remove_file(dev, &dev_attr_tap);
- device_remove_file(dev, &dev_attr_volume_tweak_pedal_assign);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_5_frequency);
- device_remove_file(dev, &dev_attr_tuner);
- device_remove_file(dev, &dev_attr_mic_selection);
- device_remove_file(dev, &dev_attr_cabinet_model);
- device_remove_file(dev, &dev_attr_stomp_model);
- device_remove_file(dev, &dev_attr_roomlevel);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_4_frequency);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_6_frequency);
- device_remove_file(dev, &dev_attr_stomp_param_1_note_value);
- device_remove_file(dev, &dev_attr_stomp_param_2);
- device_remove_file(dev, &dev_attr_stomp_param_3);
- device_remove_file(dev, &dev_attr_stomp_param_4);
- device_remove_file(dev, &dev_attr_stomp_param_5);
- device_remove_file(dev, &dev_attr_stomp_param_6);
- if ((type & (LINE6_BITS_LIVE)) != 0)
- device_remove_file(dev, &dev_attr_amp_switch_select);
- device_remove_file(dev, &dev_attr_delay_param_4);
- device_remove_file(dev, &dev_attr_delay_param_5);
- device_remove_file(dev, &dev_attr_delay_pre_post);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_delay_model);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- device_remove_file(dev, &dev_attr_delay_verb_model);
- device_remove_file(dev, &dev_attr_tempo_msb);
- device_remove_file(dev, &dev_attr_tempo_lsb);
- if (firmware >= 300)
- device_remove_file(dev, &dev_attr_wah_model);
- if (firmware >= 214)
- device_remove_file(dev, &dev_attr_bypass_volume);
- if ((type & (LINE6_BITS_PRO)) != 0)
- device_remove_file(dev, &dev_attr_fx_loop_on_off);
- device_remove_file(dev, &dev_attr_tweak_param_select);
- device_remove_file(dev, &dev_attr_amp1_engage);
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_1_gain);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_2_gain__bass);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_2_gain);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_3_gain__bass);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_3_gain);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_4_gain__bass);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_5_gain__bass);
- if ((type & (LINE6_BITS_PODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_4_gain);
- if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
- if (firmware >= 200)
- device_remove_file(dev, &dev_attr_band_6_gain__bass);
-}
-
-int line6_variax_create_files(int firmware, int type, struct device *dev)
-{
- int err;
- CHECK_RETURN(device_create_file(dev, &dev_attr_body));
- CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_enable));
- CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_type));
- CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_position));
- CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_angle));
- CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_level));
- CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_enable));
- CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_type));
- CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_position));
- CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_angle));
- CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_level));
- CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_phase));
- CHECK_RETURN(device_create_file(dev, &dev_attr_capacitance));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tone_resistance));
- CHECK_RETURN(device_create_file(dev, &dev_attr_volume_resistance));
- CHECK_RETURN(device_create_file(dev, &dev_attr_taper));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tone_dump));
- CHECK_RETURN(device_create_file(dev, &dev_attr_save_tone));
- CHECK_RETURN(device_create_file(dev, &dev_attr_volume_dump));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuning_enable));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuning6));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuning5));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuning4));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuning3));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuning2));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuning1));
- CHECK_RETURN(device_create_file(dev, &dev_attr_detune6));
- CHECK_RETURN(device_create_file(dev, &dev_attr_detune5));
- CHECK_RETURN(device_create_file(dev, &dev_attr_detune4));
- CHECK_RETURN(device_create_file(dev, &dev_attr_detune3));
- CHECK_RETURN(device_create_file(dev, &dev_attr_detune2));
- CHECK_RETURN(device_create_file(dev, &dev_attr_detune1));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mix6));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mix5));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mix4));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mix3));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mix2));
- CHECK_RETURN(device_create_file(dev, &dev_attr_mix1));
- CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_wiring));
- return 0;
-}
-
-void line6_variax_remove_files(int firmware, int type, struct device *dev)
-{
- device_remove_file(dev, &dev_attr_body);
- device_remove_file(dev, &dev_attr_pickup1_enable);
- device_remove_file(dev, &dev_attr_pickup1_type);
- device_remove_file(dev, &dev_attr_pickup1_position);
- device_remove_file(dev, &dev_attr_pickup1_angle);
- device_remove_file(dev, &dev_attr_pickup1_level);
- device_remove_file(dev, &dev_attr_pickup2_enable);
- device_remove_file(dev, &dev_attr_pickup2_type);
- device_remove_file(dev, &dev_attr_pickup2_position);
- device_remove_file(dev, &dev_attr_pickup2_angle);
- device_remove_file(dev, &dev_attr_pickup2_level);
- device_remove_file(dev, &dev_attr_pickup_phase);
- device_remove_file(dev, &dev_attr_capacitance);
- device_remove_file(dev, &dev_attr_tone_resistance);
- device_remove_file(dev, &dev_attr_volume_resistance);
- device_remove_file(dev, &dev_attr_taper);
- device_remove_file(dev, &dev_attr_tone_dump);
- device_remove_file(dev, &dev_attr_save_tone);
- device_remove_file(dev, &dev_attr_volume_dump);
- device_remove_file(dev, &dev_attr_tuning_enable);
- device_remove_file(dev, &dev_attr_tuning6);
- device_remove_file(dev, &dev_attr_tuning5);
- device_remove_file(dev, &dev_attr_tuning4);
- device_remove_file(dev, &dev_attr_tuning3);
- device_remove_file(dev, &dev_attr_tuning2);
- device_remove_file(dev, &dev_attr_tuning1);
- device_remove_file(dev, &dev_attr_detune6);
- device_remove_file(dev, &dev_attr_detune5);
- device_remove_file(dev, &dev_attr_detune4);
- device_remove_file(dev, &dev_attr_detune3);
- device_remove_file(dev, &dev_attr_detune2);
- device_remove_file(dev, &dev_attr_detune1);
- device_remove_file(dev, &dev_attr_mix6);
- device_remove_file(dev, &dev_attr_mix5);
- device_remove_file(dev, &dev_attr_mix4);
- device_remove_file(dev, &dev_attr_mix3);
- device_remove_file(dev, &dev_attr_mix2);
- device_remove_file(dev, &dev_attr_mix1);
- device_remove_file(dev, &dev_attr_pickup_wiring);
-}
diff --git a/drivers/staging/line6/control.h b/drivers/staging/line6/control.h
deleted file mode 100644
index e4c5d2ce2aa..00000000000
--- a/drivers/staging/line6/control.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- * 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.
- *
- */
-
-#ifndef LINE6_CONTROL_H
-#define LINE6_CONTROL_H
-
-/**
- List of PODxt Pro controls.
- See Appendix C of the "PODxt (Pro) Pilot's Handbook" by Line6.
- Comments after the number refer to the PODxt Pro firmware version required
- for this feature.
-
- Please *don't* reformat this file since "control.c" is created automatically
- from "control.h", and this process depends on the exact formatting of the
- code and the comments below!
-*/
-
-/* *INDENT-OFF* */
-
-enum {
- POD_tweak = 1,
- POD_wah_position = 4,
- POD_compression_gain = 5, /* device: LINE6_BITS_PODXTALL */
- POD_vol_pedal_position = 7,
- POD_compression_threshold = 9,
- POD_pan = 10,
- POD_amp_model_setup = 11,
- POD_amp_model = 12, /* firmware: 2.0 */
- POD_drive = 13,
- POD_bass = 14,
- POD_mid = 15, /* device: LINE6_BITS_PODXTALL */
- POD_lowmid = 15, /* device: LINE6_BITS_BASSPODXTALL */
- POD_treble = 16, /* device: LINE6_BITS_PODXTALL */
- POD_highmid = 16, /* device: LINE6_BITS_BASSPODXTALL */
- POD_chan_vol = 17,
- POD_reverb_mix = 18, /* device: LINE6_BITS_PODXTALL */
- POD_effect_setup = 19,
- POD_band_1_frequency = 20, /* firmware: 2.0 */
- POD_presence = 21, /* device: LINE6_BITS_PODXTALL */
- POD_treble__bass = 21, /* device: LINE6_BITS_BASSPODXTALL */
- POD_noise_gate_enable = 22,
- POD_gate_threshold = 23,
- POD_gate_decay_time = 24,
- POD_stomp_enable = 25,
- POD_comp_enable = 26,
- POD_stomp_time = 27,
- POD_delay_enable = 28,
- POD_mod_param_1 = 29,
- POD_delay_param_1 = 30,
- POD_delay_param_1_note_value = 31,
- POD_band_2_frequency__bass = 32, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
- POD_delay_param_2 = 33,
- POD_delay_volume_mix = 34,
- POD_delay_param_3 = 35,
- POD_reverb_enable = 36, /* device: LINE6_BITS_PODXTALL */
- POD_reverb_type = 37, /* device: LINE6_BITS_PODXTALL */
- POD_reverb_decay = 38, /* device: LINE6_BITS_PODXTALL */
- POD_reverb_tone = 39, /* device: LINE6_BITS_PODXTALL */
- POD_reverb_pre_delay = 40, /* device: LINE6_BITS_PODXTALL */
- POD_reverb_pre_post = 41, /* device: LINE6_BITS_PODXTALL */
- POD_band_2_frequency = 42, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
- POD_band_3_frequency__bass = 42, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
- POD_wah_enable = 43,
- POD_modulation_lo_cut = 44, /* device: LINE6_BITS_BASSPODXTALL */
- POD_delay_reverb_lo_cut = 45, /* device: LINE6_BITS_BASSPODXTALL */
- POD_volume_pedal_minimum = 46, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
- POD_eq_pre_post = 46, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
- POD_volume_pre_post = 47,
- POD_di_model = 48, /* device: LINE6_BITS_BASSPODXTALL */
- POD_di_delay = 49, /* device: LINE6_BITS_BASSPODXTALL */
- POD_mod_enable = 50,
- POD_mod_param_1_note_value = 51,
- POD_mod_param_2 = 52,
- POD_mod_param_3 = 53,
- POD_mod_param_4 = 54,
- POD_mod_param_5 = 55, /* device: LINE6_BITS_BASSPODXTALL */
- POD_mod_volume_mix = 56,
- POD_mod_pre_post = 57,
- POD_modulation_model = 58,
- POD_band_3_frequency = 60, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
- POD_band_4_frequency__bass = 60, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
- POD_mod_param_1_double_precision = 61,
- POD_delay_param_1_double_precision = 62,
- POD_eq_enable = 63, /* firmware: 2.0 */
- POD_tap = 64,
- POD_volume_tweak_pedal_assign = 65,
- POD_band_5_frequency = 68, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
- POD_tuner = 69,
- POD_mic_selection = 70,
- POD_cabinet_model = 71,
- POD_stomp_model = 75,
- POD_roomlevel = 76,
- POD_band_4_frequency = 77, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
- POD_band_6_frequency = 77, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
- POD_stomp_param_1_note_value = 78,
- POD_stomp_param_2 = 79,
- POD_stomp_param_3 = 80,
- POD_stomp_param_4 = 81,
- POD_stomp_param_5 = 82,
- POD_stomp_param_6 = 83,
- POD_amp_switch_select = 84, /* device: LINE6_BITS_LIVE */
- POD_delay_param_4 = 85,
- POD_delay_param_5 = 86,
- POD_delay_pre_post = 87,
- POD_delay_model = 88, /* device: LINE6_BITS_PODXTALL */
- POD_delay_verb_model = 88, /* device: LINE6_BITS_BASSPODXTALL */
- POD_tempo_msb = 89,
- POD_tempo_lsb = 90,
- POD_wah_model = 91, /* firmware: 3.0 */
- POD_bypass_volume = 105, /* firmware: 2.14 */
- POD_fx_loop_on_off = 107, /* device: LINE6_BITS_PRO */
- POD_tweak_param_select = 108,
- POD_amp1_engage = 111,
- POD_band_1_gain = 114, /* firmware: 2.0 */
- POD_band_2_gain__bass = 115, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
- POD_band_2_gain = 116, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
- POD_band_3_gain__bass = 116, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
- POD_band_3_gain = 117, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
- POD_band_4_gain__bass = 117, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
- POD_band_5_gain__bass = 118, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
- POD_band_4_gain = 119, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
- POD_band_6_gain__bass = 119 /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
-};
-
-/**
- List of Variax workbench controls (dump).
-*/
-enum {
- VARIAX_body = 3,
- VARIAX_pickup1_enable = 4, /* 0: enabled, 1: disabled */
- VARIAX_pickup1_type = 8,
- VARIAX_pickup1_position = 9, /* type: 24 bit float */
- VARIAX_pickup1_angle = 12, /* type: 24 bit float */
- VARIAX_pickup1_level = 15, /* type: 24 bit float */
- VARIAX_pickup2_enable = 18, /* 0: enabled, 1: disabled */
- VARIAX_pickup2_type = 22,
- VARIAX_pickup2_position = 23, /* type: 24 bit float */
- VARIAX_pickup2_angle = 26, /* type: 24 bit float */
- VARIAX_pickup2_level = 29, /* type: 24 bit float */
- VARIAX_pickup_phase = 32, /* 0: in phase, 1: out of phase */
- VARIAX_capacitance = 33, /* type: 24 bit float */
- VARIAX_tone_resistance = 36, /* type: 24 bit float */
- VARIAX_volume_resistance = 39, /* type: 24 bit float */
- VARIAX_taper = 42, /* 0: Linear, 1: Audio */
- VARIAX_tone_dump = 43, /* type: 24 bit float */
- VARIAX_save_tone = 46,
- VARIAX_volume_dump = 47, /* type: 24 bit float */
- VARIAX_tuning_enable = 50,
- VARIAX_tuning6 = 51,
- VARIAX_tuning5 = 52,
- VARIAX_tuning4 = 53,
- VARIAX_tuning3 = 54,
- VARIAX_tuning2 = 55,
- VARIAX_tuning1 = 56,
- VARIAX_detune6 = 57, /* type: 24 bit float */
- VARIAX_detune5 = 60, /* type: 24 bit float */
- VARIAX_detune4 = 63, /* type: 24 bit float */
- VARIAX_detune3 = 66, /* type: 24 bit float */
- VARIAX_detune2 = 69, /* type: 24 bit float */
- VARIAX_detune1 = 72, /* type: 24 bit float */
- VARIAX_mix6 = 75, /* type: 24 bit float */
- VARIAX_mix5 = 78, /* type: 24 bit float */
- VARIAX_mix4 = 81, /* type: 24 bit float */
- VARIAX_mix3 = 84, /* type: 24 bit float */
- VARIAX_mix2 = 87, /* type: 24 bit float */
- VARIAX_mix1 = 90, /* type: 24 bit float */
- VARIAX_pickup_wiring = 96 /* 0: parallel, 1: series */
-};
-
-/**
- List of Variax workbench controls (MIDI).
-*/
-enum {
- VARIAXMIDI_volume = 7,
- VARIAXMIDI_tone = 79,
-};
-
-/* *INDENT-ON* */
-
-extern int line6_pod_create_files(int firmware, int type, struct device *dev);
-extern void line6_pod_remove_files(int firmware, int type, struct device *dev);
-extern int line6_variax_create_files(int firmware, int type,
- struct device *dev);
-extern void line6_variax_remove_files(int firmware, int type,
- struct device *dev);
-
-#endif
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
index b8358ca71bd..1e4ce50069a 100644
--- a/drivers/staging/line6/driver.c
+++ b/drivers/staging/line6/driver.c
@@ -16,7 +16,6 @@
#include "audio.h"
#include "capture.h"
-#include "control.h"
#include "driver.h"
#include "midi.h"
#include "playback.h"
@@ -96,8 +95,6 @@ static const char line6_request_version[] = {
0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7
};
-struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
-
/**
Class for asynchronous messages.
*/
@@ -179,22 +176,6 @@ void line6_write_hexdump(struct usb_line6 *line6, char dir,
}
#endif
-#ifdef CONFIG_LINE6_USB_DUMP_CTRL
-/*
- Dump URB data to syslog.
-*/
-static void line6_dump_urb(struct urb *urb)
-{
- struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
-
- if (urb->status < 0)
- return;
-
- line6_write_hexdump(line6, 'R', (unsigned char *)urb->transfer_buffer,
- urb->actual_length);
-}
-#endif
-
/*
Send raw message in pieces of wMaxPacketSize bytes.
*/
@@ -203,10 +184,6 @@ int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
{
int i, done = 0;
-#ifdef CONFIG_LINE6_USB_DUMP_CTRL
- line6_write_hexdump(line6, 'S', buffer, size);
-#endif
-
for (i = 0; i < size; i += line6->max_packet_size) {
int partial;
const char *frag_buf = buffer + i;
@@ -261,10 +238,6 @@ static int line6_send_raw_message_async_part(struct message *msg,
(char *)msg->buffer + done, bytes,
line6_async_request_sent, msg, line6->interval);
-#ifdef CONFIG_LINE6_USB_DUMP_CTRL
- line6_write_hexdump(line6, 'S', (char *)msg->buffer + done, bytes);
-#endif
-
msg->done += bytes;
retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -405,19 +378,13 @@ static void line6_data_received(struct urb *urb)
if (urb->status == -ESHUTDOWN)
return;
-#ifdef CONFIG_LINE6_USB_DUMP_CTRL
- line6_dump_urb(urb);
-#endif
-
done =
line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
if (done < urb->actual_length) {
line6_midibuf_ignore(mb, done);
- DEBUG_MESSAGES(dev_err
- (line6->ifcdev,
- "%d %d buffer overflow - message skipped\n",
- done, urb->actual_length));
+ dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n",
+ done, urb->actual_length);
}
for (;;) {
@@ -428,15 +395,7 @@ static void line6_data_received(struct urb *urb)
if (done == 0)
break;
- /* MIDI input filter */
- if (line6_midibuf_skip_message
- (mb, line6->line6midi->midi_mask_receive))
- continue;
-
line6->message_length = done;
-#ifdef CONFIG_LINE6_USB_DUMP_MIDI
- line6_write_hexdump(line6, 'r', line6->buffer_message, done);
-#endif
line6_midi_receive(line6, line6->buffer_message, done);
switch (line6->usbdev->descriptor.idProduct) {
@@ -506,10 +465,6 @@ int line6_send_program(struct usb_line6 *line6, u8 value)
buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;
buffer[1] = value;
-#ifdef CONFIG_LINE6_USB_DUMP_CTRL
- line6_write_hexdump(line6, 'S', buffer, 2);
-#endif
-
retval = usb_interrupt_msg(line6->usbdev,
usb_sndintpipe(line6->usbdev,
line6->ep_control_write),
@@ -543,10 +498,6 @@ int line6_transmit_parameter(struct usb_line6 *line6, int param, u8 value)
buffer[1] = param;
buffer[2] = value;
-#ifdef CONFIG_LINE6_USB_DUMP_CTRL
- line6_write_hexdump(line6, 'S', buffer, 3);
-#endif
-
retval = usb_interrupt_msg(line6->usbdev,
usb_sndintpipe(line6->usbdev,
line6->ep_control_write),
@@ -690,20 +641,6 @@ ssize_t line6_nop_write(struct device *dev, struct device_attribute *attr,
}
/*
- "write" request on "raw" special file.
-*/
-#ifdef CONFIG_LINE6_USB_RAW
-ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6 *line6 = usb_get_intfdata(interface);
- line6_send_raw_message(line6, buf, count);
- return count;
-}
-#endif
-
-/*
Generic destructor.
*/
static void line6_destruct(struct usb_interface *interface)
@@ -740,7 +677,6 @@ static int line6_probe(struct usb_interface *interface,
struct usb_device *usbdev;
struct usb_line6 *line6;
const struct line6_properties *properties;
- int devnum;
int interface_number, alternate = 0;
int product;
int size = 0;
@@ -774,16 +710,6 @@ static int line6_probe(struct usb_interface *interface,
goto err_put;
}
- /* find free slot in device table: */
- for (devnum = 0; devnum < LINE6_MAX_DEVICES; ++devnum)
- if (line6_devices[devnum] == NULL)
- break;
-
- if (devnum == LINE6_MAX_DEVICES) {
- ret = -ENODEV;
- goto err_put;
- }
-
/* initialize device info: */
properties = &line6_properties_table[devtype];
dev_info(&interface->dev, "Line6 %s found\n", properties->name);
@@ -1112,7 +1038,6 @@ static int line6_probe(struct usb_interface *interface,
dev_info(&interface->dev, "Line6 %s now attached\n",
line6->properties->name);
- line6_devices[devnum] = line6;
switch (product) {
case LINE6_DEVID_PODX3:
@@ -1141,7 +1066,7 @@ static void line6_disconnect(struct usb_interface *interface)
{
struct usb_line6 *line6;
struct usb_device *usbdev;
- int interface_number, i;
+ int interface_number;
if (interface == NULL)
return;
@@ -1214,10 +1139,6 @@ static void line6_disconnect(struct usb_interface *interface)
dev_info(&interface->dev, "Line6 %s now disconnected\n",
line6->properties->name);
-
- for (i = LINE6_MAX_DEVICES; i--;)
- if (line6_devices[i] == line6)
- line6_devices[i] = NULL;
}
line6_destruct(interface);
diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h
index a3029eb223d..f0be5a2adab 100644
--- a/drivers/staging/line6/driver.h
+++ b/drivers/staging/line6/driver.h
@@ -20,12 +20,11 @@
#define DRIVER_NAME "line6usb"
-#if defined(CONFIG_LINE6_USB_DUMP_CTRL) || defined(CONFIG_LINE6_USB_DUMP_MIDI) || defined(CONFIG_LINE6_USB_DUMP_PCM)
+#if defined(CONFIG_LINE6_USB_DUMP_PCM)
#define CONFIG_LINE6_USB_DUMP_ANY
#endif
#define LINE6_TIMEOUT 1
-#define LINE6_MAX_DEVICES 8
#define LINE6_BUFSIZE_LISTEN 32
#define LINE6_MESSAGE_MAXLEN 256
@@ -53,12 +52,6 @@
#define LINE6_CHANNEL_MASK 0x0f
-#ifdef CONFIG_LINE6_USB_DEBUG
-#define DEBUG_MESSAGES(x) (x)
-#else
-#define DEBUG_MESSAGES(x)
-#endif
-
#define MISSING_CASE \
printk(KERN_ERR "line6usb driver bug: missing case in %s:%d\n", \
__FILE__, __LINE__)
@@ -78,7 +71,6 @@ do { \
} while (0)
extern const unsigned char line6_midi_id[3];
-extern struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3;
static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4;
diff --git a/drivers/staging/line6/dumprequest.c b/drivers/staging/line6/dumprequest.c
deleted file mode 100644
index 60c7bae3ad3..00000000000
--- a/drivers/staging/line6/dumprequest.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- * 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.
- *
- */
-
-#include <linux/slab.h>
-
-#include "driver.h"
-#include "dumprequest.h"
-
-/*
- Set "dump in progress" flag.
-*/
-void line6_dump_started(struct line6_dump_request *l6dr, int dest)
-{
- l6dr->in_progress = dest;
-}
-
-/*
- Invalidate current channel, i.e., set "dump in progress" flag.
- Reading from the "dump" special file blocks until dump is completed.
-*/
-void line6_invalidate_current(struct line6_dump_request *l6dr)
-{
- line6_dump_started(l6dr, LINE6_DUMP_CURRENT);
-}
-
-/*
- Clear "dump in progress" flag and notify waiting processes.
-*/
-void line6_dump_finished(struct line6_dump_request *l6dr)
-{
- l6dr->in_progress = LINE6_DUMP_NONE;
- wake_up(&l6dr->wait);
-}
-
-/*
- Send an asynchronous channel dump request.
-*/
-int line6_dump_request_async(struct line6_dump_request *l6dr,
- struct usb_line6 *line6, int num, int dest)
-{
- int ret;
- line6_dump_started(l6dr, dest);
- ret = line6_send_raw_message_async(line6, l6dr->reqbufs[num].buffer,
- l6dr->reqbufs[num].length);
-
- if (ret < 0)
- line6_dump_finished(l6dr);
-
- return ret;
-}
-
-/*
- Wait for completion (interruptible).
-*/
-int line6_dump_wait_interruptible(struct line6_dump_request *l6dr)
-{
- return wait_event_interruptible(l6dr->wait,
- l6dr->in_progress == LINE6_DUMP_NONE);
-}
-
-/*
- Wait for completion.
-*/
-void line6_dump_wait(struct line6_dump_request *l6dr)
-{
- wait_event(l6dr->wait, l6dr->in_progress == LINE6_DUMP_NONE);
-}
-
-/*
- Wait for completion (with timeout).
-*/
-int line6_dump_wait_timeout(struct line6_dump_request *l6dr, long timeout)
-{
- return wait_event_timeout(l6dr->wait,
- l6dr->in_progress == LINE6_DUMP_NONE,
- timeout);
-}
-
-/*
- Initialize dump request buffer.
-*/
-int line6_dumpreq_initbuf(struct line6_dump_request *l6dr, const void *buf,
- size_t len, int num)
-{
- l6dr->reqbufs[num].buffer = kmemdup(buf, len, GFP_KERNEL);
- if (l6dr->reqbufs[num].buffer == NULL)
- return -ENOMEM;
- l6dr->reqbufs[num].length = len;
- return 0;
-}
-
-/*
- Initialize dump request data structure (including one buffer).
-*/
-int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf,
- size_t len)
-{
- int ret;
- ret = line6_dumpreq_initbuf(l6dr, buf, len, 0);
- if (ret < 0)
- return ret;
- init_waitqueue_head(&l6dr->wait);
- return 0;
-}
-
-/*
- Destruct dump request data structure.
-*/
-void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num)
-{
- if (l6dr == NULL)
- return;
- if (l6dr->reqbufs[num].buffer == NULL)
- return;
- kfree(l6dr->reqbufs[num].buffer);
- l6dr->reqbufs[num].buffer = NULL;
-}
-
-/*
- Destruct dump request data structure.
-*/
-void line6_dumpreq_destruct(struct line6_dump_request *l6dr)
-{
- if (l6dr->reqbufs[0].buffer == NULL)
- return;
- line6_dumpreq_destructbuf(l6dr, 0);
-}
diff --git a/drivers/staging/line6/dumprequest.h b/drivers/staging/line6/dumprequest.h
deleted file mode 100644
index c17a262fad2..00000000000
--- a/drivers/staging/line6/dumprequest.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- * 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.
- *
- */
-
-#ifndef DUMPREQUEST_H
-#define DUMPREQUEST_H
-
-#include <linux/usb.h>
-#include <linux/wait.h>
-#include <sound/core.h>
-
-enum {
- LINE6_DUMP_NONE,
- LINE6_DUMP_CURRENT
-};
-
-struct line6_dump_reqbuf {
- /**
- Buffer for dump requests.
- */
- unsigned char *buffer;
-
- /**
- Size of dump request.
- */
- size_t length;
-};
-
-/**
- Provides the functionality to request channel/model/... dump data from a
- Line6 device.
-*/
-struct line6_dump_request {
- /**
- Wait queue for access to program dump data.
- */
- wait_queue_head_t wait;
-
- /**
- Indicates an unfinished program dump request.
- 0: no dump
- 1: dump current settings
- Other device-specific values are also allowed.
- */
- int in_progress;
-
- /**
- Dump request buffers
- */
- struct line6_dump_reqbuf reqbufs[1];
-};
-
-extern void line6_dump_finished(struct line6_dump_request *l6dr);
-extern int line6_dump_request_async(struct line6_dump_request *l6dr,
- struct usb_line6 *line6, int num, int dest);
-extern void line6_dump_started(struct line6_dump_request *l6dr, int dest);
-extern void line6_dumpreq_destruct(struct line6_dump_request *l6dr);
-extern void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num);
-extern int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf,
- size_t len);
-extern int line6_dumpreq_initbuf(struct line6_dump_request *l6dr,
- const void *buf, size_t len, int num);
-extern void line6_invalidate_current(struct line6_dump_request *l6dr);
-extern void line6_dump_wait(struct line6_dump_request *l6dr);
-extern int line6_dump_wait_interruptible(struct line6_dump_request *l6dr);
-extern int line6_dump_wait_timeout(struct line6_dump_request *l6dr,
- long timeout);
-
-#endif
diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c
index 50407294fbd..6982eca661b 100644
--- a/drivers/staging/line6/midi.c
+++ b/drivers/staging/line6/midi.c
@@ -59,9 +59,6 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
if (done == 0)
break;
-#ifdef CONFIG_LINE6_USB_DUMP_MIDI
- line6_write_hexdump(line6, 's', chunk, done);
-#endif
line6_midibuf_write(mb, chunk, done);
snd_rawmidi_transmit_ack(substream, done);
}
@@ -72,10 +69,6 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
if (done == 0)
break;
- if (line6_midibuf_skip_message
- (mb, line6midi->midi_mask_transmit))
- continue;
-
send_midi_async(line6, chunk, done);
}
@@ -131,9 +124,6 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
dev_err(line6->ifcdev, "Out of memory\n");
return -ENOMEM;
}
-#ifdef CONFIG_LINE6_USB_DUMP_CTRL
- line6_write_hexdump(line6, 'S', data, length);
-#endif
transfer_buffer = kmemdup(data, length, GFP_ATOMIC);
@@ -158,28 +148,6 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
}
++line6->line6midi->num_active_send_urbs;
-
- switch (line6->usbdev->descriptor.idProduct) {
- case LINE6_DEVID_BASSPODXT:
- case LINE6_DEVID_BASSPODXTLIVE:
- case LINE6_DEVID_BASSPODXTPRO:
- case LINE6_DEVID_PODXT:
- case LINE6_DEVID_PODXTLIVE:
- case LINE6_DEVID_PODXTPRO:
- case LINE6_DEVID_POCKETPOD:
- line6_pod_midi_postprocess((struct usb_line6_pod *)line6, data,
- length);
- break;
-
- case LINE6_DEVID_VARIAX:
- case LINE6_DEVID_PODHD300:
- case LINE6_DEVID_PODHD500:
- break;
-
- default:
- MISSING_CASE;
- }
-
return 0;
}
@@ -287,83 +255,10 @@ static int snd_line6_new_midi(struct snd_line6_midi *line6midi)
return 0;
}
-/*
- "read" request on "midi_mask_transmit" special file.
-*/
-static ssize_t midi_get_midi_mask_transmit(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6 *line6 = usb_get_intfdata(interface);
- return sprintf(buf, "%d\n", line6->line6midi->midi_mask_transmit);
-}
-
-/*
- "write" request on "midi_mask" special file.
-*/
-static ssize_t midi_set_midi_mask_transmit(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6 *line6 = usb_get_intfdata(interface);
- unsigned short value;
- int ret;
-
- ret = kstrtou16(buf, 10, &value);
- if (ret)
- return ret;
-
- line6->line6midi->midi_mask_transmit = value;
- return count;
-}
-
-/*
- "read" request on "midi_mask_receive" special file.
-*/
-static ssize_t midi_get_midi_mask_receive(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6 *line6 = usb_get_intfdata(interface);
- return sprintf(buf, "%d\n", line6->line6midi->midi_mask_receive);
-}
-
-/*
- "write" request on "midi_mask" special file.
-*/
-static ssize_t midi_set_midi_mask_receive(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6 *line6 = usb_get_intfdata(interface);
- unsigned short value;
- int ret;
-
- ret = kstrtou16(buf, 10, &value);
- if (ret)
- return ret;
-
- line6->line6midi->midi_mask_receive = value;
- return count;
-}
-
-static DEVICE_ATTR(midi_mask_transmit, S_IWUSR | S_IRUGO,
- midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
-static DEVICE_ATTR(midi_mask_receive, S_IWUSR | S_IRUGO,
- midi_get_midi_mask_receive, midi_set_midi_mask_receive);
-
/* MIDI device destructor */
static int snd_line6_midi_free(struct snd_device *device)
{
struct snd_line6_midi *line6midi = device->device_data;
- device_remove_file(line6midi->line6->ifcdev,
- &dev_attr_midi_mask_transmit);
- device_remove_file(line6midi->line6->ifcdev,
- &dev_attr_midi_mask_receive);
line6_midibuf_destroy(&line6midi->midibuf_in);
line6_midibuf_destroy(&line6midi->midibuf_out);
return 0;
@@ -405,19 +300,6 @@ int line6_init_midi(struct usb_line6 *line6)
}
line6midi->line6 = line6;
-
- switch (line6->product) {
- case LINE6_DEVID_PODHD300:
- case LINE6_DEVID_PODHD500:
- line6midi->midi_mask_transmit = 1;
- line6midi->midi_mask_receive = 1;
- break;
-
- default:
- line6midi->midi_mask_transmit = 1;
- line6midi->midi_mask_receive = 4;
- }
-
line6->line6midi = line6midi;
err = snd_device_new(line6->card, SNDRV_DEV_RAWMIDI, line6midi,
@@ -431,14 +313,6 @@ int line6_init_midi(struct usb_line6 *line6)
if (err < 0)
return err;
- err = device_create_file(line6->ifcdev, &dev_attr_midi_mask_transmit);
- if (err < 0)
- return err;
-
- err = device_create_file(line6->ifcdev, &dev_attr_midi_mask_receive);
- if (err < 0)
- return err;
-
init_waitqueue_head(&line6midi->send_wait);
spin_lock_init(&line6midi->send_urb_lock);
spin_lock_init(&line6midi->midi_transmit_lock);
diff --git a/drivers/staging/line6/midi.h b/drivers/staging/line6/midi.h
index 4a9e9f94729..19dabd54051 100644
--- a/drivers/staging/line6/midi.h
+++ b/drivers/staging/line6/midi.h
@@ -55,16 +55,6 @@ struct snd_line6_midi {
wait_queue_head_t send_wait;
/**
- Bit mask for output MIDI channels.
- */
- unsigned short midi_mask_transmit;
-
- /**
- Bit mask for input MIDI channels.
- */
- unsigned short midi_mask_receive;
-
- /**
Buffer for incoming MIDI stream.
*/
struct MidiBuffer midibuf_in;
diff --git a/drivers/staging/line6/midibuf.c b/drivers/staging/line6/midibuf.c
index 836e8c847c5..968e0de83da 100644
--- a/drivers/staging/line6/midibuf.c
+++ b/drivers/staging/line6/midibuf.c
@@ -64,9 +64,9 @@ int line6_midibuf_init(struct MidiBuffer *this, int size, int split)
void line6_midibuf_status(struct MidiBuffer *this)
{
- pr_debug("midibuf size=%d split=%d pos_read=%d pos_write=%d "
- "full=%d command_prev=%02x\n", this->size, this->split,
- this->pos_read, this->pos_write, this->full, this->command_prev);
+ pr_debug("midibuf size=%d split=%d pos_read=%d pos_write=%d full=%d command_prev=%02x\n",
+ this->size, this->split, this->pos_read, this->pos_write,
+ this->full, this->command_prev);
}
int line6_midibuf_bytes_free(struct MidiBuffer *this)
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
index 7fe44a6fd0e..6c1e31335d1 100644
--- a/drivers/staging/line6/pcm.c
+++ b/drivers/staging/line6/pcm.c
@@ -109,7 +109,7 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
line6pcm->prev_fbuf = NULL;
if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) {
- /* We may be invoked multiple times in a row so allocate once only */
+ /* Invoked multiple times in a row so allocate once only */
if (!line6pcm->buffer_in) {
line6pcm->buffer_in =
kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
@@ -148,7 +148,7 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
}
if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) {
- /* We may be invoked multiple times in a row so allocate once only */
+ /* Invoked multiple times in a row so allocate once only */
if (!line6pcm->buffer_out) {
line6pcm->buffer_out =
kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h
index 5210ec8dbe1..6aa0d46a289 100644
--- a/drivers/staging/line6/pcm.h
+++ b/drivers/staging/line6/pcm.h
@@ -167,7 +167,7 @@ enum {
#endif
LINE6_BIT_PCM_ALSA_CAPTURE_STREAM |
LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM,
-
+
LINE6_BITS_STREAM =
LINE6_BITS_PLAYBACK_STREAM |
LINE6_BITS_CAPTURE_STREAM
diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c
index a0ab9d0493f..4cf23af9c62 100644
--- a/drivers/staging/line6/playback.c
+++ b/drivers/staging/line6/playback.c
@@ -185,7 +185,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
if (urb_size == 0) {
/* can't determine URB size */
spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
- dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n"); /* this is somewhat paranoid */
+ dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n");
return -EINVAL;
}
@@ -218,7 +218,8 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
len * bytes_per_frame, runtime->dma_area,
(urb_frames - len) * bytes_per_frame);
} else
- dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", len); /* this is somewhat paranoid */
+ dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n",
+ len);
} else {
memcpy(urb_out->transfer_buffer,
runtime->dma_area +
@@ -319,7 +320,8 @@ void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm)
}
/*
- Wait until unlinking of all currently active playback URBs has been finished.
+ Wait until unlinking of all currently active playback URBs has been
+ finished.
*/
void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
{
@@ -413,7 +415,8 @@ static void audio_out_callback(struct urb *urb)
if (!shutdown) {
submit_audio_out_urb(line6pcm);
- if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags)) {
+ if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM,
+ &line6pcm->flags)) {
line6pcm->bytes_out += length;
if (line6pcm->bytes_out >= line6pcm->period_out) {
line6pcm->bytes_out %= line6pcm->period_out;
@@ -499,7 +502,8 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd)
#ifdef CONFIG_PM
case SNDRV_PCM_TRIGGER_RESUME:
#endif
- err = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM);
+ err = line6_pcm_acquire(line6pcm,
+ LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM);
if (err < 0)
return err;
@@ -510,7 +514,8 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd)
#ifdef CONFIG_PM
case SNDRV_PCM_TRIGGER_SUSPEND:
#endif
- err = line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM);
+ err = line6_pcm_release(line6pcm,
+ LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM);
if (err < 0)
return err;
diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c
index 9edd053fb9a..e542540d0db 100644
--- a/drivers/staging/line6/pod.c
+++ b/drivers/staging/line6/pod.c
@@ -15,7 +15,6 @@
#include "audio.h"
#include "capture.h"
-#include "control.h"
#include "driver.h"
#include "playback.h"
#include "pod.h"
@@ -26,7 +25,6 @@
/* *INDENT-OFF* */
enum {
- POD_SYSEX_CLIP = 0x0f,
POD_SYSEX_SAVE = 0x24,
POD_SYSEX_SYSTEM = 0x56,
POD_SYSEX_SYSTEMREQ = 0x57,
@@ -41,11 +39,6 @@ enum {
enum {
POD_monitor_level = 0x04,
- POD_routing = 0x05,
- POD_tuner_mute = 0x13,
- POD_tuner_freq = 0x15,
- POD_tuner_note = 0x16,
- POD_tuner_pitch = 0x17,
POD_system_invalid = 0x10000
};
@@ -118,10 +111,6 @@ static struct line6_pcm_properties pod_pcm_properties = {
.bytes_per_frame = POD_BYTES_PER_FRAME
};
-static const char pod_request_channel[] = {
- 0xf0, 0x00, 0x01, 0x0c, 0x03, 0x75, 0xf7
-};
-
static const char pod_version_header[] = {
0xf2, 0x7e, 0x7f, 0x06, 0x02
};
@@ -129,18 +118,6 @@ static const char pod_version_header[] = {
/* forward declarations: */
static void pod_startup2(unsigned long data);
static void pod_startup3(struct usb_line6_pod *pod);
-static void pod_startup4(struct usb_line6_pod *pod);
-
-/*
- Mark all parameters as dirty and notify waiting processes.
-*/
-static void pod_mark_batch_all_dirty(struct usb_line6_pod *pod)
-{
- int i;
-
- for (i = 0; i < POD_CONTROL_SIZE; i++)
- set_bit(i, pod->param_dirty);
-}
static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
int size)
@@ -150,45 +127,6 @@ static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
}
/*
- Send channel dump data to the PODxt Pro.
-*/
-static void pod_dump(struct usb_line6_pod *pod, const unsigned char *data)
-{
- int size = 1 + sizeof(pod->prog_data);
- char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMP, size);
- if (!sysex)
- return;
- /* Don't know what this is good for, but PODxt Pro transmits it, so we
- * also do... */
- sysex[SYSEX_DATA_OFS] = 5;
- memcpy(sysex + SYSEX_DATA_OFS + 1, data, sizeof(pod->prog_data));
- line6_send_sysex_message(&pod->line6, sysex, size);
- memcpy(&pod->prog_data, data, sizeof(pod->prog_data));
- pod_mark_batch_all_dirty(pod);
- kfree(sysex);
-}
-
-/*
- Store parameter value in driver memory and mark it as dirty.
-*/
-static void pod_store_parameter(struct usb_line6_pod *pod, int param, int value)
-{
- pod->prog_data.control[param] = value;
- set_bit(param, pod->param_dirty);
- pod->dirty = 1;
-}
-
-/*
- Handle SAVE button.
-*/
-static void pod_save_button_pressed(struct usb_line6_pod *pod, int type,
- int index)
-{
- pod->dirty = 0;
- set_bit(POD_SAVE_PRESSED, &pod->atomic_flags);
-}
-
-/*
Process a completely received message.
*/
void line6_pod_process_message(struct usb_line6_pod *pod)
@@ -209,25 +147,11 @@ void line6_pod_process_message(struct usb_line6_pod *pod)
/* process all remaining messages */
switch (buf[0]) {
case LINE6_PARAM_CHANGE | LINE6_CHANNEL_DEVICE:
- pod_store_parameter(pod, buf[1], buf[2]);
- /* intentionally no break here! */
-
case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
- if ((buf[1] == POD_amp_model_setup) ||
- (buf[1] == POD_effect_setup))
- /* these also affect other settings */
- line6_dump_request_async(&pod->dumpreq, &pod->line6, 0,
- LINE6_DUMP_CURRENT);
-
break;
case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
- pod->channel_num = buf[1];
- pod->dirty = 0;
- set_bit(POD_CHANNEL_DIRTY, &pod->atomic_flags);
- line6_dump_request_async(&pod->dumpreq, &pod->line6, 0,
- LINE6_DUMP_CURRENT);
break;
case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE:
@@ -235,43 +159,6 @@ void line6_pod_process_message(struct usb_line6_pod *pod)
if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) == 0) {
switch (buf[5]) {
case POD_SYSEX_DUMP:
- if (pod->line6.message_length ==
- sizeof(pod->prog_data) + 7) {
- switch (pod->dumpreq.in_progress) {
- case LINE6_DUMP_CURRENT:
- memcpy(&pod->prog_data, buf + 7,
- sizeof(pod->prog_data));
- pod_mark_batch_all_dirty(pod);
- break;
-
- case POD_DUMP_MEMORY:
- memcpy(&pod->prog_data_buf,
- buf + 7,
- sizeof
- (pod->prog_data_buf));
- break;
-
- default:
- DEBUG_MESSAGES(dev_err
- (pod->
- line6.ifcdev,
- "unknown dump code %02X\n",
- pod->
- dumpreq.in_progress));
- }
-
- line6_dump_finished(&pod->dumpreq);
- pod_startup3(pod);
- } else
- DEBUG_MESSAGES(dev_err
- (pod->line6.ifcdev,
- "wrong size of channel dump message (%d instead of %d)\n",
- pod->
- line6.message_length,
- (int)
- sizeof(pod->prog_data) +
- 7));
-
break;
case POD_SYSEX_SYSTEM:{
@@ -280,35 +167,8 @@ void line6_pod_process_message(struct usb_line6_pod *pod)
<< 8) |
((int)buf[9] << 4) | (int)buf[10];
-#define PROCESS_SYSTEM_PARAM(x) \
- case POD_ ## x: \
- pod->x.value = value; \
- wake_up(&pod->x.wait); \
- break;
-
- switch (buf[6]) {
- PROCESS_SYSTEM_PARAM
- (monitor_level);
- PROCESS_SYSTEM_PARAM(routing);
- PROCESS_SYSTEM_PARAM
- (tuner_mute);
- PROCESS_SYSTEM_PARAM
- (tuner_freq);
- PROCESS_SYSTEM_PARAM
- (tuner_note);
- PROCESS_SYSTEM_PARAM
- (tuner_pitch);
-
-#undef PROCESS_SYSTEM_PARAM
-
- default:
- DEBUG_MESSAGES(dev_err
- (pod->
- line6.ifcdev,
- "unknown tuner/system response %02X\n",
- buf[6]));
- }
-
+ if (buf[6] == POD_monitor_level)
+ pod->monitor_level = value;
break;
}
@@ -317,29 +177,18 @@ void line6_pod_process_message(struct usb_line6_pod *pod)
break;
case POD_SYSEX_SAVE:
- pod_save_button_pressed(pod, buf[6], buf[7]);
- break;
-
- case POD_SYSEX_CLIP:
- DEBUG_MESSAGES(dev_err
- (pod->line6.ifcdev,
- "audio clipped\n"));
- pod->clipping.value = 1;
- wake_up(&pod->clipping.wait);
break;
case POD_SYSEX_STORE:
- DEBUG_MESSAGES(dev_err
- (pod->line6.ifcdev,
- "message %02X not yet implemented\n",
- buf[5]));
+ dev_dbg(pod->line6.ifcdev,
+ "message %02X not yet implemented\n",
+ buf[5]);
break;
default:
- DEBUG_MESSAGES(dev_err
- (pod->line6.ifcdev,
- "unknown sysex message %02X\n",
- buf[5]));
+ dev_dbg(pod->line6.ifcdev,
+ "unknown sysex message %02X\n",
+ buf[5]);
}
} else
if (memcmp
@@ -350,11 +199,9 @@ void line6_pod_process_message(struct usb_line6_pod *pod)
pod->device_id =
((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)
buf[10];
- pod_startup4(pod);
+ pod_startup3(pod);
} else
- DEBUG_MESSAGES(dev_err
- (pod->line6.ifcdev,
- "unknown sysex header\n"));
+ dev_dbg(pod->line6.ifcdev, "unknown sysex header\n");
break;
@@ -362,349 +209,22 @@ void line6_pod_process_message(struct usb_line6_pod *pod)
break;
default:
- DEBUG_MESSAGES(dev_err
- (pod->line6.ifcdev,
- "POD: unknown message %02X\n", buf[0]));
+ dev_dbg(pod->line6.ifcdev, "POD: unknown message %02X\n",
+ buf[0]);
}
}
/*
- Detect some cases that require a channel dump after sending a command to the
- device. Important notes:
- *) The actual dump request can not be sent here since we are not allowed to
- wait for the completion of the first message in this context, and sending
- the dump request before completion of the previous message leaves the POD
- in an undefined state. The dump request will be sent when the echoed
- commands are received.
- *) This method fails if a param change message is "chopped" after the first
- byte.
-*/
-void line6_pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data,
- int length)
-{
- int i;
-
- if (!pod->midi_postprocess)
- return;
-
- for (i = 0; i < length; ++i) {
- if (data[i] == (LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST)) {
- line6_invalidate_current(&pod->dumpreq);
- break;
- } else
- if ((data[i] == (LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST))
- && (i < length - 1))
- if ((data[i + 1] == POD_amp_model_setup)
- || (data[i + 1] == POD_effect_setup)) {
- line6_invalidate_current(&pod->dumpreq);
- break;
- }
- }
-}
-
-/*
- Send channel number (i.e., switch to a different sound).
-*/
-static void pod_send_channel(struct usb_line6_pod *pod, u8 value)
-{
- line6_invalidate_current(&pod->dumpreq);
-
- if (line6_send_program(&pod->line6, value) == 0)
- pod->channel_num = value;
- else
- line6_dump_finished(&pod->dumpreq);
-}
-
-/*
Transmit PODxt Pro control parameter.
*/
void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
u8 value)
{
- if (line6_transmit_parameter(&pod->line6, param, value) == 0)
- pod_store_parameter(pod, param, value);
-
- if ((param == POD_amp_model_setup) || (param == POD_effect_setup)) /* these also affect other settings */
- line6_invalidate_current(&pod->dumpreq);
-}
-
-/*
- Resolve value to memory location.
-*/
-static int pod_resolve(const char *buf, short block0, short block1,
- unsigned char *location)
-{
- u8 value;
- short block;
- int ret;
-
- ret = kstrtou8(buf, 10, &value);
- if (ret)
- return ret;
-
- block = (value < 0x40) ? block0 : block1;
- value &= 0x3f;
- location[0] = block >> 7;
- location[1] = value | (block & 0x7f);
- return 0;
-}
-
-/*
- Send command to store channel/effects setup/amp setup to PODxt Pro.
-*/
-static ssize_t pod_send_store_command(struct device *dev, const char *buf,
- size_t count, short block0, short block1)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- int ret;
- int size = 3 + sizeof(pod->prog_data_buf);
- char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_STORE, size);
-
- if (!sysex)
- return 0;
-
- sysex[SYSEX_DATA_OFS] = 5; /* see pod_dump() */
- ret = pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS + 1);
- if (ret) {
- kfree(sysex);
- return ret;
- }
-
- memcpy(sysex + SYSEX_DATA_OFS + 3, &pod->prog_data_buf,
- sizeof(pod->prog_data_buf));
-
- line6_send_sysex_message(&pod->line6, sysex, size);
- kfree(sysex);
- /* needs some delay here on AMD64 platform */
- return count;
-}
-
-/*
- Send command to retrieve channel/effects setup/amp setup to PODxt Pro.
-*/
-static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf,
- size_t count, short block0,
- short block1)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- int ret;
- int size = 4;
- char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMPMEM, size);
-
- if (!sysex)
- return 0;
-
- ret = pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS);
- if (ret) {
- kfree(sysex);
- return ret;
- }
- sysex[SYSEX_DATA_OFS + 2] = 0;
- sysex[SYSEX_DATA_OFS + 3] = 0;
- line6_dump_started(&pod->dumpreq, POD_DUMP_MEMORY);
-
- if (line6_send_sysex_message(&pod->line6, sysex, size) < size)
- line6_dump_finished(&pod->dumpreq);
-
- kfree(sysex);
- /* needs some delay here on AMD64 platform */
- return count;
-}
-
-/*
- Generic get name function.
-*/
-static ssize_t get_name_generic(struct usb_line6_pod *pod, const char *str,
- char *buf)
-{
- int length = 0;
- const char *p1;
- char *p2;
- char *last_non_space = buf;
-
- int retval = line6_dump_wait_interruptible(&pod->dumpreq);
- if (retval < 0)
- return retval;
-
- for (p1 = str, p2 = buf; *p1; ++p1, ++p2) {
- *p2 = *p1;
- if (*p2 != ' ')
- last_non_space = p2;
- if (++length == POD_NAME_LENGTH)
- break;
- }
-
- *(last_non_space + 1) = '\n';
- return last_non_space - buf + 2;
-}
-
-/*
- "read" request on "channel" special file.
-*/
-static ssize_t pod_get_channel(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- return sprintf(buf, "%d\n", pod->channel_num);
-}
-
-/*
- "write" request on "channel" special file.
-*/
-static ssize_t pod_set_channel(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- u8 value;
- int ret;
-
- ret = kstrtou8(buf, 10, &value);
- if (ret)
- return ret;
-
- pod_send_channel(pod, value);
- return count;
-}
-
-/*
- "read" request on "name" special file.
-*/
-static ssize_t pod_get_name(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- return get_name_generic(pod, pod->prog_data.header + POD_NAME_OFFSET,
- buf);
-}
-
-/*
- "read" request on "name" special file.
-*/
-static ssize_t pod_get_name_buf(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- return get_name_generic(pod,
- pod->prog_data_buf.header + POD_NAME_OFFSET,
- buf);
-}
-
-/*
- "read" request on "dump" special file.
-*/
-static ssize_t pod_get_dump(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- int retval = line6_dump_wait_interruptible(&pod->dumpreq);
- if (retval < 0)
- return retval;
- memcpy(buf, &pod->prog_data, sizeof(pod->prog_data));
- return sizeof(pod->prog_data);
-}
-
-/*
- "write" request on "dump" special file.
-*/
-static ssize_t pod_set_dump(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
-
- if (count != sizeof(pod->prog_data)) {
- dev_err(pod->line6.ifcdev,
- "data block must be exactly %d bytes\n",
- (int)sizeof(pod->prog_data));
- return -EINVAL;
- }
-
- pod_dump(pod, buf);
- return sizeof(pod->prog_data);
-}
-
-/*
- Identify system parameters related to the tuner.
-*/
-static bool pod_is_tuner(int code)
-{
- return
- (code == POD_tuner_mute) ||
- (code == POD_tuner_freq) ||
- (code == POD_tuner_note) || (code == POD_tuner_pitch);
-}
-
-/*
- Get system parameter (as integer).
- @param tuner non-zero, if code refers to a tuner parameter
-*/
-static int pod_get_system_param_int(struct usb_line6_pod *pod, int *value,
- int code, struct ValueWait *param, int sign)
-{
- char *sysex;
- static const int size = 1;
- int retval = 0;
-
- if (((pod->prog_data.control[POD_tuner] & 0x40) == 0)
- && pod_is_tuner(code))
- return -ENODEV;
-
- /* send value request to device: */
- param->value = POD_system_invalid;
- sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEMREQ, size);
-
- if (!sysex)
- return -ENOMEM;
-
- sysex[SYSEX_DATA_OFS] = code;
- line6_send_sysex_message(&pod->line6, sysex, size);
- kfree(sysex);
-
- /* wait for device to respond: */
- retval =
- wait_event_interruptible(param->wait,
- param->value != POD_system_invalid);
-
- if (retval < 0)
- return retval;
-
- *value = sign ? (int)(signed short)param->value : (int)(unsigned short)
- param->value;
-
- if (*value == POD_system_invalid)
- *value = 0; /* don't report uninitialized values */
-
- return 0;
-}
-
-/*
- Get system parameter (as string).
- @param tuner non-zero, if code refers to a tuner parameter
-*/
-static ssize_t pod_get_system_param_string(struct usb_line6_pod *pod, char *buf,
- int code, struct ValueWait *param,
- int sign)
-{
- int retval, value = 0;
- retval = pod_get_system_param_int(pod, &value, code, param, sign);
-
- if (retval < 0)
- return retval;
-
- return sprintf(buf, "%d\n", value);
+ line6_transmit_parameter(&pod->line6, param, value);
}
/*
Send system parameter (from integer).
- @param tuner non-zero, if code refers to a tuner parameter
*/
static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
int code)
@@ -712,11 +232,6 @@ static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
char *sysex;
static const int size = 5;
- if (((pod->prog_data.control[POD_tuner] & 0x40) == 0)
- && pod_is_tuner(code))
- return -EINVAL;
-
- /* send value to tuner: */
sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
if (!sysex)
return -ENOMEM;
@@ -731,179 +246,6 @@ static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
}
/*
- Send system parameter (from string).
- @param tuner non-zero, if code refers to a tuner parameter
-*/
-static ssize_t pod_set_system_param_string(struct usb_line6_pod *pod,
- const char *buf, int count, int code,
- unsigned short mask)
-{
- int retval;
- unsigned short value = simple_strtoul(buf, NULL, 10) & mask;
- retval = pod_set_system_param_int(pod, value, code);
- return (retval < 0) ? retval : count;
-}
-
-/*
- "read" request on "dump_buf" special file.
-*/
-static ssize_t pod_get_dump_buf(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- int retval = line6_dump_wait_interruptible(&pod->dumpreq);
- if (retval < 0)
- return retval;
- memcpy(buf, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
- return sizeof(pod->prog_data_buf);
-}
-
-/*
- "write" request on "dump_buf" special file.
-*/
-static ssize_t pod_set_dump_buf(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
-
- if (count != sizeof(pod->prog_data)) {
- dev_err(pod->line6.ifcdev,
- "data block must be exactly %d bytes\n",
- (int)sizeof(pod->prog_data));
- return -EINVAL;
- }
-
- memcpy(&pod->prog_data_buf, buf, sizeof(pod->prog_data));
- return sizeof(pod->prog_data);
-}
-
-/*
- "write" request on "finish" special file.
-*/
-static ssize_t pod_set_finish(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- int size = 0;
- char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_FINISH, size);
- if (!sysex)
- return 0;
- line6_send_sysex_message(&pod->line6, sysex, size);
- kfree(sysex);
- return count;
-}
-
-/*
- "write" request on "store_channel" special file.
-*/
-static ssize_t pod_set_store_channel(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return pod_send_store_command(dev, buf, count, 0x0000, 0x00c0);
-}
-
-/*
- "write" request on "store_effects_setup" special file.
-*/
-static ssize_t pod_set_store_effects_setup(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return pod_send_store_command(dev, buf, count, 0x0080, 0x0080);
-}
-
-/*
- "write" request on "store_amp_setup" special file.
-*/
-static ssize_t pod_set_store_amp_setup(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return pod_send_store_command(dev, buf, count, 0x0040, 0x0100);
-}
-
-/*
- "write" request on "retrieve_channel" special file.
-*/
-static ssize_t pod_set_retrieve_channel(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return pod_send_retrieve_command(dev, buf, count, 0x0000, 0x00c0);
-}
-
-/*
- "write" request on "retrieve_effects_setup" special file.
-*/
-static ssize_t pod_set_retrieve_effects_setup(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return pod_send_retrieve_command(dev, buf, count, 0x0080, 0x0080);
-}
-
-/*
- "write" request on "retrieve_amp_setup" special file.
-*/
-static ssize_t pod_set_retrieve_amp_setup(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return pod_send_retrieve_command(dev, buf, count, 0x0040, 0x0100);
-}
-
-/*
- "read" request on "dirty" special file.
-*/
-static ssize_t pod_get_dirty(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- buf[0] = pod->dirty ? '1' : '0';
- buf[1] = '\n';
- return 2;
-}
-
-/*
- "read" request on "midi_postprocess" special file.
-*/
-static ssize_t pod_get_midi_postprocess(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- return sprintf(buf, "%d\n", pod->midi_postprocess);
-}
-
-/*
- "write" request on "midi_postprocess" special file.
-*/
-static ssize_t pod_set_midi_postprocess(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- u8 value;
- int ret;
-
- ret = kstrtou8(buf, 10, &value);
- if (ret)
- return ret;
-
- pod->midi_postprocess = value ? 1 : 0;
- return count;
-}
-
-/*
"read" request on "serial_number" special file.
*/
static ssize_t pod_get_serial_number(struct device *dev,
@@ -939,18 +281,6 @@ static ssize_t pod_get_device_id(struct device *dev,
}
/*
- "read" request on "clip" special file.
-*/
-static ssize_t pod_wait_for_clip(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- return wait_event_interruptible(pod->clipping.wait,
- pod->clipping.value != 0);
-}
-
-/*
POD startup procedure.
This is a sequence of functions with special requirements (e.g., must
not run immediately after initialization, must not run in interrupt
@@ -969,22 +299,6 @@ static void pod_startup1(struct usb_line6_pod *pod)
static void pod_startup2(unsigned long data)
{
struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
-
- /* schedule another startup procedure until startup is complete: */
- if (pod->startup_progress >= POD_STARTUP_LAST)
- return;
-
- pod->startup_progress = POD_STARTUP_DUMPREQ;
- line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
- (unsigned long)pod);
-
- /* current channel dump: */
- line6_dump_request_async(&pod->dumpreq, &pod->line6, 0,
- LINE6_DUMP_CURRENT);
-}
-
-static void pod_startup3(struct usb_line6_pod *pod)
-{
struct usb_line6 *line6 = &pod->line6;
CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
@@ -992,7 +306,7 @@ static void pod_startup3(struct usb_line6_pod *pod)
line6_version_request_async(line6);
}
-static void pod_startup4(struct usb_line6_pod *pod)
+static void pod_startup3(struct usb_line6_pod *pod)
{
CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
@@ -1000,7 +314,7 @@ static void pod_startup4(struct usb_line6_pod *pod)
schedule_work(&pod->startup_work);
}
-static void pod_startup5(struct work_struct *work)
+static void pod_startup4(struct work_struct *work)
{
struct usb_line6_pod *pod =
container_of(work, struct usb_line6_pod, startup_work);
@@ -1013,87 +327,14 @@ static void pod_startup5(struct work_struct *work)
/* ALSA audio interface: */
line6_register_audio(line6);
-
- /* device files: */
- line6_pod_create_files(pod->firmware_version,
- line6->properties->device_bit, line6->ifcdev);
-}
-
-#define POD_GET_SYSTEM_PARAM(code, sign) \
-static ssize_t pod_get_ ## code(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *interface = to_usb_interface(dev); \
- struct usb_line6_pod *pod = usb_get_intfdata(interface); \
- return pod_get_system_param_string(pod, buf, POD_ ## code, \
- &pod->code, sign); \
-}
-
-#define POD_GET_SET_SYSTEM_PARAM(code, mask, sign) \
-POD_GET_SYSTEM_PARAM(code, sign) \
-static ssize_t pod_set_ ## code(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- struct usb_interface *interface = to_usb_interface(dev); \
- struct usb_line6_pod *pod = usb_get_intfdata(interface); \
- return pod_set_system_param_string(pod, buf, count, POD_ ## code, mask); \
}
-POD_GET_SET_SYSTEM_PARAM(monitor_level, 0xffff, 0);
-POD_GET_SET_SYSTEM_PARAM(routing, 0x0003, 0);
-POD_GET_SET_SYSTEM_PARAM(tuner_mute, 0x0001, 0);
-POD_GET_SET_SYSTEM_PARAM(tuner_freq, 0xffff, 0);
-POD_GET_SYSTEM_PARAM(tuner_note, 1);
-POD_GET_SYSTEM_PARAM(tuner_pitch, 1);
-
-#undef GET_SET_SYSTEM_PARAM
-#undef GET_SYSTEM_PARAM
-
/* POD special files: */
-static DEVICE_ATTR(channel, S_IWUSR | S_IRUGO, pod_get_channel,
- pod_set_channel);
-static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write);
static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
-static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write);
-static DEVICE_ATTR(dump, S_IWUSR | S_IRUGO, pod_get_dump, pod_set_dump);
-static DEVICE_ATTR(dump_buf, S_IWUSR | S_IRUGO, pod_get_dump_buf,
- pod_set_dump_buf);
-static DEVICE_ATTR(finish, S_IWUSR, line6_nop_read, pod_set_finish);
static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
line6_nop_write);
-static DEVICE_ATTR(midi_postprocess, S_IWUSR | S_IRUGO,
- pod_get_midi_postprocess, pod_set_midi_postprocess);
-static DEVICE_ATTR(monitor_level, S_IWUSR | S_IRUGO, pod_get_monitor_level,
- pod_set_monitor_level);
-static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
-static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
-static DEVICE_ATTR(retrieve_amp_setup, S_IWUSR, line6_nop_read,
- pod_set_retrieve_amp_setup);
-static DEVICE_ATTR(retrieve_channel, S_IWUSR, line6_nop_read,
- pod_set_retrieve_channel);
-static DEVICE_ATTR(retrieve_effects_setup, S_IWUSR, line6_nop_read,
- pod_set_retrieve_effects_setup);
-static DEVICE_ATTR(routing, S_IWUSR | S_IRUGO, pod_get_routing,
- pod_set_routing);
static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
line6_nop_write);
-static DEVICE_ATTR(store_amp_setup, S_IWUSR, line6_nop_read,
- pod_set_store_amp_setup);
-static DEVICE_ATTR(store_channel, S_IWUSR, line6_nop_read,
- pod_set_store_channel);
-static DEVICE_ATTR(store_effects_setup, S_IWUSR, line6_nop_read,
- pod_set_store_effects_setup);
-static DEVICE_ATTR(tuner_freq, S_IWUSR | S_IRUGO, pod_get_tuner_freq,
- pod_set_tuner_freq);
-static DEVICE_ATTR(tuner_mute, S_IWUSR | S_IRUGO, pod_get_tuner_mute,
- pod_set_tuner_mute);
-static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
-static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
-
-#ifdef CONFIG_LINE6_USB_RAW
-static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
-#endif
/* control info callback */
static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
@@ -1112,7 +353,7 @@ static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
{
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
- ucontrol->value.integer.value[0] = pod->monitor_level.value;
+ ucontrol->value.integer.value[0] = pod->monitor_level;
return 0;
}
@@ -1123,10 +364,10 @@ static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
- if (ucontrol->value.integer.value[0] == pod->monitor_level.value)
+ if (ucontrol->value.integer.value[0] == pod->monitor_level)
return 0;
- pod->monitor_level.value = ucontrol->value.integer.value[0];
+ pod->monitor_level = ucontrol->value.integer.value[0];
pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
POD_monitor_level);
return 1;
@@ -1156,9 +397,6 @@ static void pod_destruct(struct usb_interface *interface)
del_timer(&pod->startup_timer);
cancel_work_sync(&pod->startup_work);
-
- /* free dump request data: */
- line6_dumpreq_destruct(&pod->dumpreq);
}
/*
@@ -1168,35 +406,9 @@ static int pod_create_files2(struct device *dev)
{
int err;
- CHECK_RETURN(device_create_file(dev, &dev_attr_channel));
- CHECK_RETURN(device_create_file(dev, &dev_attr_clip));
CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
- CHECK_RETURN(device_create_file(dev, &dev_attr_dirty));
- CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
- CHECK_RETURN(device_create_file(dev, &dev_attr_dump_buf));
- CHECK_RETURN(device_create_file(dev, &dev_attr_finish));
CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
- CHECK_RETURN(device_create_file(dev, &dev_attr_midi_postprocess));
- CHECK_RETURN(device_create_file(dev, &dev_attr_monitor_level));
- CHECK_RETURN(device_create_file(dev, &dev_attr_name));
- CHECK_RETURN(device_create_file(dev, &dev_attr_name_buf));
- CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_amp_setup));
- CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_channel));
- CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_effects_setup));
- CHECK_RETURN(device_create_file(dev, &dev_attr_routing));
CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
- CHECK_RETURN(device_create_file(dev, &dev_attr_store_amp_setup));
- CHECK_RETURN(device_create_file(dev, &dev_attr_store_channel));
- CHECK_RETURN(device_create_file(dev, &dev_attr_store_effects_setup));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_freq));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_mute));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_note));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_pitch));
-
-#ifdef CONFIG_LINE6_USB_RAW
- CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
-#endif
-
return 0;
}
@@ -1210,32 +422,11 @@ static int pod_try_init(struct usb_interface *interface,
struct usb_line6 *line6 = &pod->line6;
init_timer(&pod->startup_timer);
- INIT_WORK(&pod->startup_work, pod_startup5);
+ INIT_WORK(&pod->startup_work, pod_startup4);
if ((interface == NULL) || (pod == NULL))
return -ENODEV;
- pod->channel_num = 255;
-
- /* initialize wait queues: */
- init_waitqueue_head(&pod->monitor_level.wait);
- init_waitqueue_head(&pod->routing.wait);
- init_waitqueue_head(&pod->tuner_mute.wait);
- init_waitqueue_head(&pod->tuner_freq.wait);
- init_waitqueue_head(&pod->tuner_note.wait);
- init_waitqueue_head(&pod->tuner_pitch.wait);
- init_waitqueue_head(&pod->clipping.wait);
-
- memset(pod->param_dirty, 0xff, sizeof(pod->param_dirty));
-
- /* initialize USB buffers: */
- err = line6_dumpreq_init(&pod->dumpreq, pod_request_channel,
- sizeof(pod_request_channel));
- if (err < 0) {
- dev_err(&interface->dev, "Out of memory\n");
- return -ENOMEM;
- }
-
/* create sysfs entries: */
err = pod_create_files2(&interface->dev);
if (err < 0)
@@ -1269,7 +460,7 @@ static int pod_try_init(struct usb_interface *interface,
*/
if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
- pod->monitor_level.value = POD_system_invalid;
+ pod->monitor_level = POD_system_invalid;
/* initiate startup procedure: */
pod_startup1(pod);
@@ -1311,39 +502,9 @@ void line6_pod_disconnect(struct usb_interface *interface)
if (dev != NULL) {
/* remove sysfs entries: */
- line6_pod_remove_files(pod->firmware_version,
- pod->line6.
- properties->device_bit, dev);
-
- device_remove_file(dev, &dev_attr_channel);
- device_remove_file(dev, &dev_attr_clip);
device_remove_file(dev, &dev_attr_device_id);
- device_remove_file(dev, &dev_attr_dirty);
- device_remove_file(dev, &dev_attr_dump);
- device_remove_file(dev, &dev_attr_dump_buf);
- device_remove_file(dev, &dev_attr_finish);
device_remove_file(dev, &dev_attr_firmware_version);
- device_remove_file(dev, &dev_attr_midi_postprocess);
- device_remove_file(dev, &dev_attr_monitor_level);
- device_remove_file(dev, &dev_attr_name);
- device_remove_file(dev, &dev_attr_name_buf);
- device_remove_file(dev, &dev_attr_retrieve_amp_setup);
- device_remove_file(dev, &dev_attr_retrieve_channel);
- device_remove_file(dev,
- &dev_attr_retrieve_effects_setup);
- device_remove_file(dev, &dev_attr_routing);
device_remove_file(dev, &dev_attr_serial_number);
- device_remove_file(dev, &dev_attr_store_amp_setup);
- device_remove_file(dev, &dev_attr_store_channel);
- device_remove_file(dev, &dev_attr_store_effects_setup);
- device_remove_file(dev, &dev_attr_tuner_freq);
- device_remove_file(dev, &dev_attr_tuner_mute);
- device_remove_file(dev, &dev_attr_tuner_note);
- device_remove_file(dev, &dev_attr_tuner_pitch);
-
-#ifdef CONFIG_LINE6_USB_RAW
- device_remove_file(dev, &dev_attr_raw);
-#endif
}
}
diff --git a/drivers/staging/line6/pod.h b/drivers/staging/line6/pod.h
index 47e0d1a1c4b..3e3f1671337 100644
--- a/drivers/staging/line6/pod.h
+++ b/drivers/staging/line6/pod.h
@@ -15,12 +15,10 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
-#include <linux/wait.h>
#include <sound/core.h>
#include "driver.h"
-#include "dumprequest.h"
/*
PODxt Live interfaces
@@ -46,37 +44,12 @@
*/
enum {
POD_STARTUP_INIT = 1,
- POD_STARTUP_DUMPREQ,
POD_STARTUP_VERSIONREQ,
POD_STARTUP_WORKQUEUE,
POD_STARTUP_SETUP,
POD_STARTUP_LAST = POD_STARTUP_SETUP - 1
};
-/**
- Data structure for values that need to be requested explicitly.
- This is the case for system and tuner settings.
-*/
-struct ValueWait {
- int value;
- wait_queue_head_t wait;
-};
-
-/**
- Binary PODxt Pro program dump
-*/
-struct pod_program {
- /**
- Header information (including program name).
- */
- unsigned char header[0x20];
-
- /**
- Program parameters.
- */
- unsigned char control[POD_CONTROL_SIZE];
-};
-
struct usb_line6_pod {
/**
Generic Line6 USB data.
@@ -84,63 +57,9 @@ struct usb_line6_pod {
struct usb_line6 line6;
/**
- Dump request structure.
- */
- struct line6_dump_request dumpreq;
-
- /**
- Current program number.
- */
- unsigned char channel_num;
-
- /**
- Current program settings.
- */
- struct pod_program prog_data;
-
- /**
- Buffer for data retrieved from or to be stored on PODxt Pro.
- */
- struct pod_program prog_data_buf;
-
- /**
- Tuner mute mode.
- */
- struct ValueWait tuner_mute;
-
- /**
- Tuner base frequency (typically 440Hz).
- */
- struct ValueWait tuner_freq;
-
- /**
- Note received from tuner.
- */
- struct ValueWait tuner_note;
-
- /**
- Pitch value received from tuner.
- */
- struct ValueWait tuner_pitch;
-
- /**
Instrument monitor level.
*/
- struct ValueWait monitor_level;
-
- /**
- Audio routing mode.
- 0: send processed guitar
- 1: send clean guitar
- 2: send clean guitar re-amp playback
- 3: send re-amp playback
- */
- struct ValueWait routing;
-
- /**
- Wait for audio clipping event.
- */
- struct ValueWait clipping;
+ int monitor_level;
/**
Timer for device initializaton.
@@ -158,16 +77,6 @@ struct usb_line6_pod {
int startup_progress;
/**
- Dirty flags for access to parameter data.
- */
- unsigned long param_dirty[POD_CONTROL_SIZE / sizeof(unsigned long)];
-
- /**
- Some atomic flags.
- */
- unsigned long atomic_flags;
-
- /**
Serial number of device.
*/
int serial_number;
@@ -181,23 +90,11 @@ struct usb_line6_pod {
Device ID.
*/
int device_id;
-
- /**
- Flag to indicate modification of current program settings.
- */
- char dirty;
-
- /**
- Flag to enable MIDI postprocessing.
- */
- char midi_postprocess;
};
extern void line6_pod_disconnect(struct usb_interface *interface);
extern int line6_pod_init(struct usb_interface *interface,
struct usb_line6_pod *pod);
-extern void line6_pod_midi_postprocess(struct usb_line6_pod *pod,
- unsigned char *data, int length);
extern void line6_pod_process_message(struct usb_line6_pod *pod);
extern void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
u8 value);
diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c
index 31b624b6342..a529dd3d604 100644
--- a/drivers/staging/line6/toneport.c
+++ b/drivers/staging/line6/toneport.c
@@ -127,13 +127,11 @@ static ssize_t toneport_set_led_red(struct device *dev,
const char *buf, size_t count)
{
int retval;
- long value;
- retval = strict_strtol(buf, 10, &value);
+ retval = kstrtoint(buf, 10, &led_red);
if (retval)
return retval;
- led_red = value;
toneport_update_led(dev);
return count;
}
@@ -143,13 +141,11 @@ static ssize_t toneport_set_led_green(struct device *dev,
const char *buf, size_t count)
{
int retval;
- long value;
- retval = strict_strtol(buf, 10, &value);
+ retval = kstrtoint(buf, 10, &led_green);
if (retval)
return retval;
- led_green = value;
toneport_update_led(dev);
return count;
}
diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h
index 353d59d77b0..43eb54008a2 100644
--- a/drivers/staging/line6/usbdefs.h
+++ b/drivers/staging/line6/usbdefs.h
@@ -83,11 +83,15 @@ enum {
LINE6_BIT(VARIAX),
LINE6_BITS_PRO = LINE6_BIT_BASSPODXTPRO | LINE6_BIT_PODXTPRO,
- LINE6_BITS_LIVE = LINE6_BIT_BASSPODXTLIVE | LINE6_BIT_PODXTLIVE | LINE6_BIT_PODX3LIVE,
- LINE6_BITS_PODXTALL = LINE6_BIT_PODXT | LINE6_BIT_PODXTLIVE | LINE6_BIT_PODXTPRO,
+ LINE6_BITS_LIVE = LINE6_BIT_BASSPODXTLIVE | LINE6_BIT_PODXTLIVE |
+ LINE6_BIT_PODX3LIVE,
+ LINE6_BITS_PODXTALL = LINE6_BIT_PODXT | LINE6_BIT_PODXTLIVE |
+ LINE6_BIT_PODXTPRO,
LINE6_BITS_PODX3ALL = LINE6_BIT_PODX3 | LINE6_BIT_PODX3LIVE,
LINE6_BITS_PODHDALL = LINE6_BIT_PODHD300 | LINE6_BIT_PODHD500,
- LINE6_BITS_BASSPODXTALL = LINE6_BIT_BASSPODXT | LINE6_BIT_BASSPODXTLIVE | LINE6_BIT_BASSPODXTPRO
+ LINE6_BITS_BASSPODXTALL = LINE6_BIT_BASSPODXT |
+ LINE6_BIT_BASSPODXTLIVE |
+ LINE6_BIT_BASSPODXTPRO
};
/* device supports settings parameter via USB */
diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c
index f97416b1de5..4fca58f1124 100644
--- a/drivers/staging/line6/variax.c
+++ b/drivers/staging/line6/variax.c
@@ -12,28 +12,13 @@
#include <linux/slab.h>
#include "audio.h"
-#include "control.h"
#include "driver.h"
#include "variax.h"
-#define VARIAX_SYSEX_CODE 7
-#define VARIAX_SYSEX_PARAM 0x3b
-#define VARIAX_SYSEX_ACTIVATE 0x2a
-#define VARIAX_MODEL_HEADER_LENGTH 7
-#define VARIAX_MODEL_MESSAGE_LENGTH 199
#define VARIAX_OFFSET_ACTIVATE 7
/*
This message is sent by the device during initialization and identifies
- the connected guitar model.
-*/
-static const char variax_init_model[] = {
- 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x69, 0x02,
- 0x00
-};
-
-/*
- This message is sent by the device during initialization and identifies
the connected guitar version.
*/
static const char variax_init_version[] = {
@@ -53,43 +38,11 @@ static const char variax_activate[] = {
0xf7
};
-static const char variax_request_bank[] = {
- 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7
-};
-
-static const char variax_request_model1[] = {
- 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x03,
- 0x00, 0x00, 0x00, 0xf7
-};
-
-static const char variax_request_model2[] = {
- 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03,
- 0x00, 0x00, 0x00, 0xf7
-};
-
/* forward declarations: */
-static int variax_create_files2(struct device *dev);
static void variax_startup2(unsigned long data);
static void variax_startup4(unsigned long data);
static void variax_startup5(unsigned long data);
-/*
- Decode data transmitted by workbench.
-*/
-static void variax_decode(const unsigned char *raw_data, unsigned char *data,
- int raw_size)
-{
- for (; raw_size > 0; raw_size -= 6) {
- data[2] = raw_data[0] | (raw_data[1] << 4);
- data[1] = raw_data[2] | (raw_data[3] << 4);
- data[0] = raw_data[4] | (raw_data[5] << 4);
- raw_data += 6;
- data += 3;
- }
-}
-
static void variax_activate_async(struct usb_line6_variax *variax, int a)
{
variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a;
@@ -155,37 +108,21 @@ static void variax_startup5(unsigned long data)
{
struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
CHECK_STARTUP_PROGRESS(variax->startup_progress,
- VARIAX_STARTUP_DUMPREQ);
-
- /* current model dump: */
- line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
- VARIAX_DUMP_PASS1);
- /* passes 2 and 3 are performed implicitly before entering variax_startup6 */
-}
-
-static void variax_startup6(struct usb_line6_variax *variax)
-{
- CHECK_STARTUP_PROGRESS(variax->startup_progress,
VARIAX_STARTUP_WORKQUEUE);
/* schedule work for global work queue: */
schedule_work(&variax->startup_work);
}
-static void variax_startup7(struct work_struct *work)
+static void variax_startup6(struct work_struct *work)
{
struct usb_line6_variax *variax =
container_of(work, struct usb_line6_variax, startup_work);
- struct usb_line6 *line6 = &variax->line6;
CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);
/* ALSA audio interface: */
line6_register_audio(&variax->line6);
-
- /* device files: */
- line6_variax_create_files(0, 0, line6->ifcdev);
- variax_create_files2(line6->ifcdev);
}
/*
@@ -197,22 +134,10 @@ void line6_variax_process_message(struct usb_line6_variax *variax)
switch (buf[0]) {
case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
- switch (buf[1]) {
- case VARIAXMIDI_volume:
- variax->volume = buf[2];
- break;
-
- case VARIAXMIDI_tone:
- variax->tone = buf[2];
- }
-
break;
case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
- variax->model = buf[1];
- line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
- VARIAX_DUMP_PASS1);
break;
case LINE6_RESET:
@@ -220,352 +145,25 @@ void line6_variax_process_message(struct usb_line6_variax *variax)
break;
case LINE6_SYSEX_BEGIN:
- if (memcmp(buf + 1, variax_request_model1 + 1,
- VARIAX_MODEL_HEADER_LENGTH - 1) == 0) {
- if (variax->line6.message_length ==
- VARIAX_MODEL_MESSAGE_LENGTH) {
- switch (variax->dumpreq.in_progress) {
- case VARIAX_DUMP_PASS1:
- variax_decode(buf +
- VARIAX_MODEL_HEADER_LENGTH,
- (unsigned char *)
- &variax->model_data,
- (sizeof
- (variax->model_data.
- name) +
- sizeof(variax->
- model_data.
- control)
- / 2) * 2);
- line6_dump_request_async
- (&variax->dumpreq, &variax->line6,
- 1, VARIAX_DUMP_PASS2);
- break;
-
- case VARIAX_DUMP_PASS2:
- /* model name is transmitted twice, so skip it here: */
- variax_decode(buf +
- VARIAX_MODEL_HEADER_LENGTH,
- (unsigned char *)
- &variax->
- model_data.control +
- sizeof(variax->model_data.
- control)
- / 2,
- sizeof(variax->model_data.
- control)
- / 2 * 2);
- line6_dump_request_async
- (&variax->dumpreq, &variax->line6,
- 2, VARIAX_DUMP_PASS3);
- }
- } else {
- DEBUG_MESSAGES(dev_err
- (variax->line6.ifcdev,
- "illegal length %d of model data\n",
- variax->line6.message_length));
- line6_dump_finished(&variax->dumpreq);
- }
- } else if (memcmp(buf + 1, variax_request_bank + 1,
- sizeof(variax_request_bank) - 2) == 0) {
- memcpy(variax->bank,
- buf + sizeof(variax_request_bank) - 1,
- sizeof(variax->bank));
- line6_dump_finished(&variax->dumpreq);
- variax_startup6(variax);
- } else if (memcmp(buf + 1, variax_init_model + 1,
- sizeof(variax_init_model) - 1) == 0) {
- memcpy(variax->guitar,
- buf + sizeof(variax_init_model),
- sizeof(variax->guitar));
- } else if (memcmp(buf + 1, variax_init_version + 1,
- sizeof(variax_init_version) - 1) == 0) {
+ if (memcmp(buf + 1, variax_init_version + 1,
+ sizeof(variax_init_version) - 1) == 0) {
variax_startup3(variax);
} else if (memcmp(buf + 1, variax_init_done + 1,
sizeof(variax_init_done) - 1) == 0) {
/* notify of complete initialization: */
variax_startup4((unsigned long)variax);
}
-
break;
case LINE6_SYSEX_END:
break;
default:
- DEBUG_MESSAGES(dev_err
- (variax->line6.ifcdev,
- "Variax: unknown message %02X\n", buf[0]));
- }
-}
-
-/*
- "read" request on "volume" special file.
-*/
-static ssize_t variax_get_volume(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_line6_variax *variax =
- usb_get_intfdata(to_usb_interface(dev));
- return sprintf(buf, "%d\n", variax->volume);
-}
-
-/*
- "write" request on "volume" special file.
-*/
-static ssize_t variax_set_volume(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_line6_variax *variax =
- usb_get_intfdata(to_usb_interface(dev));
- u8 value;
- int ret;
-
- ret = kstrtou8(buf, 10, &value);
- if (ret)
- return ret;
-
- if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_volume,
- value) == 0)
- variax->volume = value;
-
- return count;
-}
-
-/*
- "read" request on "model" special file.
-*/
-static ssize_t variax_get_model(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_line6_variax *variax =
- usb_get_intfdata(to_usb_interface(dev));
- return sprintf(buf, "%d\n", variax->model);
-}
-
-/*
- "write" request on "model" special file.
-*/
-static ssize_t variax_set_model(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_line6_variax *variax =
- usb_get_intfdata(to_usb_interface(dev));
- u8 value;
- int ret;
-
- ret = kstrtou8(buf, 10, &value);
- if (ret)
- return ret;
-
- if (line6_send_program(&variax->line6, value) == 0)
- variax->model = value;
-
- return count;
-}
-
-/*
- "read" request on "active" special file.
-*/
-static ssize_t variax_get_active(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_line6_variax *variax =
- usb_get_intfdata(to_usb_interface(dev));
- return sprintf(buf, "%d\n",
- variax->buffer_activate[VARIAX_OFFSET_ACTIVATE]);
-}
-
-/*
- "write" request on "active" special file.
-*/
-static ssize_t variax_set_active(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_line6_variax *variax =
- usb_get_intfdata(to_usb_interface(dev));
- u8 value;
- int ret;
-
- ret = kstrtou8(buf, 10, &value);
- if (ret)
- return ret;
-
- variax_activate_async(variax, value ? 1 : 0);
- return count;
-}
-
-/*
- "read" request on "tone" special file.
-*/
-static ssize_t variax_get_tone(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_line6_variax *variax =
- usb_get_intfdata(to_usb_interface(dev));
- return sprintf(buf, "%d\n", variax->tone);
-}
-
-/*
- "write" request on "tone" special file.
-*/
-static ssize_t variax_set_tone(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_line6_variax *variax =
- usb_get_intfdata(to_usb_interface(dev));
- u8 value;
- int ret;
-
- ret = kstrtou8(buf, 10, &value);
- if (ret)
- return ret;
-
- if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_tone,
- value) == 0)
- variax->tone = value;
-
- return count;
-}
-
-static ssize_t get_string(char *buf, const char *data, int length)
-{
- int i;
- memcpy(buf, data, length);
-
- for (i = length; i--;) {
- char c = buf[i];
-
- if ((c != 0) && (c != ' '))
- break;
- }
-
- buf[i + 1] = '\n';
- return i + 2;
-}
-
-/*
- "read" request on "name" special file.
-*/
-static ssize_t variax_get_name(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_line6_variax *variax =
- usb_get_intfdata(to_usb_interface(dev));
- line6_dump_wait_interruptible(&variax->dumpreq);
- return get_string(buf, variax->model_data.name,
- sizeof(variax->model_data.name));
-}
-
-/*
- "read" request on "bank" special file.
-*/
-static ssize_t variax_get_bank(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_line6_variax *variax =
- usb_get_intfdata(to_usb_interface(dev));
- line6_dump_wait_interruptible(&variax->dumpreq);
- return get_string(buf, variax->bank, sizeof(variax->bank));
-}
-
-/*
- "read" request on "dump" special file.
-*/
-static ssize_t variax_get_dump(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_line6_variax *variax =
- usb_get_intfdata(to_usb_interface(dev));
- int retval;
- retval = line6_dump_wait_interruptible(&variax->dumpreq);
- if (retval < 0)
- return retval;
- memcpy(buf, &variax->model_data.control,
- sizeof(variax->model_data.control));
- return sizeof(variax->model_data.control);
-}
-
-/*
- "read" request on "guitar" special file.
-*/
-static ssize_t variax_get_guitar(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_line6_variax *variax =
- usb_get_intfdata(to_usb_interface(dev));
- return sprintf(buf, "%s\n", variax->guitar);
-}
-
-#ifdef CONFIG_LINE6_USB_RAW
-
-static char *variax_alloc_sysex_buffer(struct usb_line6_variax *variax,
- int code, int size)
-{
- return line6_alloc_sysex_buffer(&variax->line6, VARIAX_SYSEX_CODE, code,
- size);
-}
-
-/*
- "write" request on "raw" special file.
-*/
-static ssize_t variax_set_raw2(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_line6_variax *variax =
- usb_get_intfdata(to_usb_interface(dev));
- int size;
- int i;
- char *sysex;
-
- count -= count % 3;
- size = count * 2;
- sysex = variax_alloc_sysex_buffer(variax, VARIAX_SYSEX_PARAM, size);
-
- if (!sysex)
- return 0;
-
- for (i = 0; i < count; i += 3) {
- const unsigned char *p1 = buf + i;
- char *p2 = sysex + SYSEX_DATA_OFS + i * 2;
- p2[0] = p1[2] & 0x0f;
- p2[1] = p1[2] >> 4;
- p2[2] = p1[1] & 0x0f;
- p2[3] = p1[1] >> 4;
- p2[4] = p1[0] & 0x0f;
- p2[5] = p1[0] >> 4;
+ dev_dbg(variax->line6.ifcdev,
+ "Variax: unknown message %02X\n", buf[0]);
}
-
- line6_send_sysex_message(&variax->line6, sysex, size);
- kfree(sysex);
- return count;
}
-#endif
-
-/* Variax workbench special files: */
-static DEVICE_ATTR(model, S_IWUSR | S_IRUGO, variax_get_model,
- variax_set_model);
-static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO, variax_get_volume,
- variax_set_volume);
-static DEVICE_ATTR(tone, S_IWUSR | S_IRUGO, variax_get_tone, variax_set_tone);
-static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
-static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
-static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
-static DEVICE_ATTR(active, S_IWUSR | S_IRUGO, variax_get_active,
- variax_set_active);
-static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write);
-
-#ifdef CONFIG_LINE6_USB_RAW
-static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
-static DEVICE_ATTR(raw2, S_IWUSR, line6_nop_read, variax_set_raw2);
-#endif
-
/*
Variax destructor.
*/
@@ -581,36 +179,10 @@ static void variax_destruct(struct usb_interface *interface)
del_timer(&variax->startup_timer2);
cancel_work_sync(&variax->startup_work);
- /* free dump request data: */
- line6_dumpreq_destructbuf(&variax->dumpreq, 2);
- line6_dumpreq_destructbuf(&variax->dumpreq, 1);
- line6_dumpreq_destruct(&variax->dumpreq);
-
kfree(variax->buffer_activate);
}
/*
- Create sysfs entries.
-*/
-static int variax_create_files2(struct device *dev)
-{
- int err;
- CHECK_RETURN(device_create_file(dev, &dev_attr_model));
- CHECK_RETURN(device_create_file(dev, &dev_attr_volume));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tone));
- CHECK_RETURN(device_create_file(dev, &dev_attr_name));
- CHECK_RETURN(device_create_file(dev, &dev_attr_bank));
- CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
- CHECK_RETURN(device_create_file(dev, &dev_attr_active));
- CHECK_RETURN(device_create_file(dev, &dev_attr_guitar));
-#ifdef CONFIG_LINE6_USB_RAW
- CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
- CHECK_RETURN(device_create_file(dev, &dev_attr_raw2));
-#endif
- return 0;
-}
-
-/*
Try to init workbench device.
*/
static int variax_try_init(struct usb_interface *interface,
@@ -620,36 +192,12 @@ static int variax_try_init(struct usb_interface *interface,
init_timer(&variax->startup_timer1);
init_timer(&variax->startup_timer2);
- INIT_WORK(&variax->startup_work, variax_startup7);
+ INIT_WORK(&variax->startup_work, variax_startup6);
if ((interface == NULL) || (variax == NULL))
return -ENODEV;
/* initialize USB buffers: */
- err = line6_dumpreq_init(&variax->dumpreq, variax_request_model1,
- sizeof(variax_request_model1));
-
- if (err < 0) {
- dev_err(&interface->dev, "Out of memory\n");
- return err;
- }
-
- err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_model2,
- sizeof(variax_request_model2), 1);
-
- if (err < 0) {
- dev_err(&interface->dev, "Out of memory\n");
- return err;
- }
-
- err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_bank,
- sizeof(variax_request_bank), 2);
-
- if (err < 0) {
- dev_err(&interface->dev, "Out of memory\n");
- return err;
- }
-
variax->buffer_activate = kmemdup(variax_activate,
sizeof(variax_activate), GFP_KERNEL);
@@ -692,28 +240,8 @@ int line6_variax_init(struct usb_interface *interface,
*/
void line6_variax_disconnect(struct usb_interface *interface)
{
- struct device *dev;
-
if (interface == NULL)
return;
- dev = &interface->dev;
-
- if (dev != NULL) {
- /* remove sysfs entries: */
- line6_variax_remove_files(0, 0, dev);
- device_remove_file(dev, &dev_attr_model);
- device_remove_file(dev, &dev_attr_volume);
- device_remove_file(dev, &dev_attr_tone);
- device_remove_file(dev, &dev_attr_name);
- device_remove_file(dev, &dev_attr_bank);
- device_remove_file(dev, &dev_attr_dump);
- device_remove_file(dev, &dev_attr_active);
- device_remove_file(dev, &dev_attr_guitar);
-#ifdef CONFIG_LINE6_USB_RAW
- device_remove_file(dev, &dev_attr_raw);
- device_remove_file(dev, &dev_attr_raw2);
-#endif
- }
variax_destruct(interface);
}
diff --git a/drivers/staging/line6/variax.h b/drivers/staging/line6/variax.h
index e2999ab41b0..24de79620d8 100644
--- a/drivers/staging/line6/variax.h
+++ b/drivers/staging/line6/variax.h
@@ -18,7 +18,6 @@
#include <sound/core.h>
#include "driver.h"
-#include "dumprequest.h"
#define VARIAX_STARTUP_DELAY1 1000
#define VARIAX_STARTUP_DELAY3 100
@@ -32,33 +31,11 @@ enum {
VARIAX_STARTUP_VERSIONREQ,
VARIAX_STARTUP_WAIT,
VARIAX_STARTUP_ACTIVATE,
- VARIAX_STARTUP_DUMPREQ,
VARIAX_STARTUP_WORKQUEUE,
VARIAX_STARTUP_SETUP,
VARIAX_STARTUP_LAST = VARIAX_STARTUP_SETUP - 1
};
-enum {
- VARIAX_DUMP_PASS1 = LINE6_DUMP_CURRENT,
- VARIAX_DUMP_PASS2,
- VARIAX_DUMP_PASS3
-};
-
-/**
- Binary Variax model dump
-*/
-struct variax_model {
- /**
- Header information (including program name).
- */
- unsigned char name[18];
-
- /**
- Model parameters.
- */
- unsigned char control[78 * 2];
-};
-
struct usb_line6_variax {
/**
Generic Line6 USB data.
@@ -66,48 +43,11 @@ struct usb_line6_variax {
struct usb_line6 line6;
/**
- Dump request structure.
- Append two extra buffers for 3-pass data query.
- */
- struct line6_dump_request dumpreq;
- struct line6_dump_reqbuf extrabuf[2];
-
- /**
Buffer for activation code.
*/
unsigned char *buffer_activate;
/**
- Model number.
- */
- int model;
-
- /**
- Current model settings.
- */
- struct variax_model model_data;
-
- /**
- Name of connected guitar.
- */
- unsigned char guitar[18];
-
- /**
- Name of current model bank.
- */
- unsigned char bank[18];
-
- /**
- Position of volume dial.
- */
- int volume;
-
- /**
- Position of tone control dial.
- */
- int tone;
-
- /**
Handler for device initializaton.
*/
struct work_struct startup_work;
diff --git a/drivers/staging/media/dt3155v4l/dt3155v4l.c b/drivers/staging/media/dt3155v4l/dt3155v4l.c
index 2e7b711c850..238910373f5 100644
--- a/drivers/staging/media/dt3155v4l/dt3155v4l.c
+++ b/drivers/staging/media/dt3155v4l/dt3155v4l.c
@@ -718,7 +718,7 @@ static const struct v4l2_ioctl_ops dt3155_ioctl_ops = {
*/
};
-static int __devinit
+static int
dt3155_init_board(struct pci_dev *pdev)
{
struct dt3155_priv *pd = pci_get_drvdata(pdev);
@@ -836,7 +836,7 @@ struct dma_coherent_mem {
unsigned long *bitmap;
};
-static int __devinit
+static int
dt3155_alloc_coherent(struct device *dev, size_t size, int flags)
{
struct dma_coherent_mem *mem;
@@ -877,7 +877,7 @@ out:
return 0;
}
-static void __devexit
+static void
dt3155_free_coherent(struct device *dev)
{
struct dma_coherent_mem *mem = dev->dma_mem;
@@ -891,7 +891,7 @@ dt3155_free_coherent(struct device *dev)
kfree(mem);
}
-static int __devinit
+static int
dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
int err;
@@ -956,7 +956,7 @@ err_video_device_alloc:
return err;
}
-static void __devexit
+static void
dt3155_remove(struct pci_dev *pdev)
{
struct dt3155_priv *pd = pci_get_drvdata(pdev);
@@ -983,7 +983,7 @@ static struct pci_driver pci_driver = {
.name = DT3155_NAME,
.id_table = pci_ids,
.probe = dt3155_probe,
- .remove = __devexit_p(dt3155_remove),
+ .remove = dt3155_remove,
};
module_pci_driver(pci_driver);
diff --git a/drivers/staging/media/lirc/lirc_parallel.c b/drivers/staging/media/lirc/lirc_parallel.c
index dd2bca7b56f..ec14bc81851 100644
--- a/drivers/staging/media/lirc/lirc_parallel.c
+++ b/drivers/staging/media/lirc/lirc_parallel.c
@@ -583,12 +583,12 @@ static struct lirc_driver driver = {
static struct platform_device *lirc_parallel_dev;
-static int __devinit lirc_parallel_probe(struct platform_device *dev)
+static int lirc_parallel_probe(struct platform_device *dev)
{
return 0;
}
-static int __devexit lirc_parallel_remove(struct platform_device *dev)
+static int lirc_parallel_remove(struct platform_device *dev)
{
return 0;
}
@@ -606,7 +606,7 @@ static int lirc_parallel_resume(struct platform_device *dev)
static struct platform_driver lirc_parallel_driver = {
.probe = lirc_parallel_probe,
- .remove = __devexit_p(lirc_parallel_remove),
+ .remove = lirc_parallel_remove,
.suspend = lirc_parallel_suspend,
.resume = lirc_parallel_resume,
.driver = {
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
index 97ef67036e3..71e3bf2937f 100644
--- a/drivers/staging/media/lirc/lirc_serial.c
+++ b/drivers/staging/media/lirc/lirc_serial.c
@@ -841,7 +841,7 @@ static int hardware_init_port(void)
return 0;
}
-static int __devinit lirc_serial_probe(struct platform_device *dev)
+static int lirc_serial_probe(struct platform_device *dev)
{
int i, nlow, nhigh, result;
@@ -927,7 +927,7 @@ exit_free_irq:
return result;
}
-static int __devexit lirc_serial_remove(struct platform_device *dev)
+static int lirc_serial_remove(struct platform_device *dev)
{
free_irq(irq, (void *)&hardware);
@@ -1148,7 +1148,7 @@ static int lirc_serial_resume(struct platform_device *dev)
static struct platform_driver lirc_serial_driver = {
.probe = lirc_serial_probe,
- .remove = __devexit_p(lirc_serial_remove),
+ .remove = lirc_serial_remove,
.suspend = lirc_serial_suspend,
.resume = lirc_serial_resume,
.driver = {
diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c
index 4afc3b41973..a45799874a2 100644
--- a/drivers/staging/media/lirc/lirc_sir.c
+++ b/drivers/staging/media/lirc/lirc_sir.c
@@ -1218,19 +1218,19 @@ static int init_lirc_sir(void)
return 0;
}
-static int __devinit lirc_sir_probe(struct platform_device *dev)
+static int lirc_sir_probe(struct platform_device *dev)
{
return 0;
}
-static int __devexit lirc_sir_remove(struct platform_device *dev)
+static int lirc_sir_remove(struct platform_device *dev)
{
return 0;
}
static struct platform_driver lirc_sir_driver = {
.probe = lirc_sir_probe,
- .remove = __devexit_p(lirc_sir_remove),
+ .remove = lirc_sir_remove,
.driver = {
.name = "lirc_sir",
.owner = THIS_MODULE,
diff --git a/drivers/staging/media/solo6x10/core.c b/drivers/staging/media/solo6x10/core.c
index 3ee9b125797..fd83d6d028b 100644
--- a/drivers/staging/media/solo6x10/core.c
+++ b/drivers/staging/media/solo6x10/core.c
@@ -129,7 +129,7 @@ static void free_solo_dev(struct solo_dev *solo_dev)
kfree(solo_dev);
}
-static int __devinit solo_pci_probe(struct pci_dev *pdev,
+static int solo_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct solo_dev *solo_dev;
@@ -284,7 +284,7 @@ fail_probe:
return ret;
}
-static void __devexit solo_pci_remove(struct pci_dev *pdev)
+static void solo_pci_remove(struct pci_dev *pdev)
{
struct solo_dev *solo_dev = pci_get_drvdata(pdev);
diff --git a/drivers/staging/net/pc300_drv.c b/drivers/staging/net/pc300_drv.c
index cb0f8d932b0..7281797ffe9 100644
--- a/drivers/staging/net/pc300_drv.c
+++ b/drivers/staging/net/pc300_drv.c
@@ -3409,7 +3409,7 @@ static void cpc_init_card(pc300_t * card)
board_nbr++;
}
-static int __devinit
+static int
cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int err, eeprom_outdated = 0;
@@ -3607,7 +3607,7 @@ err_disable_dev:
return err;
}
-static void __devexit cpc_remove_one(struct pci_dev *pdev)
+static void cpc_remove_one(struct pci_dev *pdev)
{
pc300_t *card = pci_get_drvdata(pdev);
@@ -3646,7 +3646,7 @@ static struct pci_driver cpc_driver = {
.name = "pc300",
.id_table = cpc_pci_dev_id,
.probe = cpc_init_one,
- .remove = __devexit_p(cpc_remove_one),
+ .remove = cpc_remove_one,
};
static int __init cpc_init(void)
diff --git a/drivers/staging/nvec/Kconfig b/drivers/staging/nvec/Kconfig
index 1235a7897d0..f779fdc3427 100644
--- a/drivers/staging/nvec/Kconfig
+++ b/drivers/staging/nvec/Kconfig
@@ -1,6 +1,7 @@
config MFD_NVEC
bool "NV Tegra Embedded Controller SMBus Interface"
depends on I2C && GPIOLIB && ARCH_TEGRA
+ select MFD_CORE
help
Say Y here to enable support for a nVidia compliant embedded
controller.
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c
index 094fdc366f3..c59b7b299d3 100644
--- a/drivers/staging/nvec/nvec.c
+++ b/drivers/staging/nvec/nvec.c
@@ -716,7 +716,7 @@ static void nvec_power_off(void)
nvec_write_async(nvec_power_handle, "\x04\x01", 2);
}
-static int __devinit tegra_nvec_probe(struct platform_device *pdev)
+static int tegra_nvec_probe(struct platform_device *pdev)
{
int err, ret;
struct clk *i2c_clk;
@@ -853,7 +853,7 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit tegra_nvec_remove(struct platform_device *pdev)
+static int tegra_nvec_remove(struct platform_device *pdev)
{
struct nvec_chip *nvec = platform_get_drvdata(pdev);
@@ -901,7 +901,7 @@ static int nvec_resume(struct device *dev)
static const SIMPLE_DEV_PM_OPS(nvec_pm_ops, nvec_suspend, nvec_resume);
/* Match table for of_platform binding */
-static const struct of_device_id nvidia_nvec_of_match[] __devinitconst = {
+static const struct of_device_id nvidia_nvec_of_match[] = {
{ .compatible = "nvidia,nvec", },
{},
};
@@ -909,7 +909,7 @@ MODULE_DEVICE_TABLE(of, nvidia_nvec_of_match);
static struct platform_driver nvec_device_driver = {
.probe = tegra_nvec_probe,
- .remove = __devexit_p(tegra_nvec_remove),
+ .remove = tegra_nvec_remove,
.driver = {
.name = "nvec",
.owner = THIS_MODULE,
diff --git a/drivers/staging/nvec/nvec_kbd.c b/drivers/staging/nvec/nvec_kbd.c
index 6cc30dcd830..7cb149bf3d3 100644
--- a/drivers/staging/nvec/nvec_kbd.c
+++ b/drivers/staging/nvec/nvec_kbd.c
@@ -100,7 +100,7 @@ static int nvec_kbd_event(struct input_dev *dev, unsigned int type,
return 0;
}
-static int __devinit nvec_kbd_probe(struct platform_device *pdev)
+static int nvec_kbd_probe(struct platform_device *pdev)
{
struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent);
int i, j, err;
@@ -159,7 +159,7 @@ fail:
return err;
}
-static int __devexit nvec_kbd_remove(struct platform_device *pdev)
+static int nvec_kbd_remove(struct platform_device *pdev)
{
input_unregister_device(keys_dev.input);
input_free_device(keys_dev.input);
@@ -169,7 +169,7 @@ static int __devexit nvec_kbd_remove(struct platform_device *pdev)
static struct platform_driver nvec_kbd_driver = {
.probe = nvec_kbd_probe,
- .remove = __devexit_p(nvec_kbd_remove),
+ .remove = nvec_kbd_remove,
.driver = {
.name = "nvec-kbd",
.owner = THIS_MODULE,
diff --git a/drivers/staging/nvec/nvec_paz00.c b/drivers/staging/nvec/nvec_paz00.c
index b747e39ff94..934b796222a 100644
--- a/drivers/staging/nvec/nvec_paz00.c
+++ b/drivers/staging/nvec/nvec_paz00.c
@@ -43,7 +43,7 @@ static void nvec_led_brightness_set(struct led_classdev *led_cdev,
}
-static int __devinit nvec_paz00_probe(struct platform_device *pdev)
+static int nvec_paz00_probe(struct platform_device *pdev)
{
struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent);
struct nvec_led *led;
@@ -72,7 +72,7 @@ static int __devinit nvec_paz00_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit nvec_paz00_remove(struct platform_device *pdev)
+static int nvec_paz00_remove(struct platform_device *pdev)
{
struct nvec_led *led = platform_get_drvdata(pdev);
@@ -83,7 +83,7 @@ static int __devexit nvec_paz00_remove(struct platform_device *pdev)
static struct platform_driver nvec_paz00_driver = {
.probe = nvec_paz00_probe,
- .remove = __devexit_p(nvec_paz00_remove),
+ .remove = nvec_paz00_remove,
.driver = {
.name = "nvec-paz00",
.owner = THIS_MODULE,
diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c
index cc8ccd75e7f..b7b6d54f58e 100644
--- a/drivers/staging/nvec/nvec_power.c
+++ b/drivers/staging/nvec/nvec_power.c
@@ -368,7 +368,7 @@ static void nvec_power_poll(struct work_struct *work)
schedule_delayed_work(to_delayed_work(work), msecs_to_jiffies(5000));
};
-static int __devinit nvec_power_probe(struct platform_device *pdev)
+static int nvec_power_probe(struct platform_device *pdev)
{
struct power_supply *psy;
struct nvec_power *power;
@@ -407,7 +407,7 @@ static int __devinit nvec_power_probe(struct platform_device *pdev)
return power_supply_register(&pdev->dev, psy);
}
-static int __devexit nvec_power_remove(struct platform_device *pdev)
+static int nvec_power_remove(struct platform_device *pdev)
{
struct nvec_power *power = platform_get_drvdata(pdev);
@@ -425,7 +425,7 @@ static int __devexit nvec_power_remove(struct platform_device *pdev)
static struct platform_driver nvec_power_driver = {
.probe = nvec_power_probe,
- .remove = __devexit_p(nvec_power_remove),
+ .remove = nvec_power_remove,
.driver = {
.name = "nvec-power",
.owner = THIS_MODULE,
diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c
index d7c65110213..88dd288bf3d 100644
--- a/drivers/staging/nvec/nvec_ps2.c
+++ b/drivers/staging/nvec/nvec_ps2.c
@@ -93,7 +93,7 @@ static int nvec_ps2_notifier(struct notifier_block *nb,
return NOTIFY_DONE;
}
-static int __devinit nvec_mouse_probe(struct platform_device *pdev)
+static int nvec_mouse_probe(struct platform_device *pdev)
{
struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent);
struct serio *ser_dev;
@@ -123,7 +123,7 @@ static int __devinit nvec_mouse_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit nvec_mouse_remove(struct platform_device *pdev)
+static int nvec_mouse_remove(struct platform_device *pdev)
{
serio_unregister_port(ps2_dev.ser_dev);
@@ -164,7 +164,7 @@ static const SIMPLE_DEV_PM_OPS(nvec_mouse_pm_ops, nvec_mouse_suspend,
static struct platform_driver nvec_mouse_driver = {
.probe = nvec_mouse_probe,
- .remove = __devexit_p(nvec_mouse_remove),
+ .remove = nvec_mouse_remove,
.driver = {
.name = "nvec-mouse",
.owner = THIS_MODULE,
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index 683bedc74dd..ef32dc1bbc8 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -169,7 +169,7 @@ static void cvm_oct_periodic_worker(struct work_struct *work)
queue_delayed_work(cvm_oct_poll_queue, &priv->port_periodic_work, HZ);
}
-static __devinit void cvm_oct_configure_common_hw(void)
+static void cvm_oct_configure_common_hw(void)
{
/* Setup the FPA */
cvmx_fpa_enable();
@@ -586,7 +586,7 @@ static const struct net_device_ops cvm_oct_pow_netdev_ops = {
extern void octeon_mdiobus_force_mod_depencency(void);
-static struct device_node * __devinit cvm_oct_of_get_child(const struct device_node *parent,
+static struct device_node *cvm_oct_of_get_child(const struct device_node *parent,
int reg_val)
{
struct device_node *node = NULL;
@@ -604,7 +604,7 @@ static struct device_node * __devinit cvm_oct_of_get_child(const struct device_n
return node;
}
-static struct device_node * __devinit cvm_oct_node_for_port(struct device_node *pip,
+static struct device_node *cvm_oct_node_for_port(struct device_node *pip,
int interface, int port)
{
struct device_node *ni, *np;
@@ -619,7 +619,7 @@ static struct device_node * __devinit cvm_oct_node_for_port(struct device_node *
return np;
}
-static int __devinit cvm_oct_probe(struct platform_device *pdev)
+static int cvm_oct_probe(struct platform_device *pdev)
{
int num_interfaces;
int interface;
@@ -813,7 +813,7 @@ static int __devinit cvm_oct_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit cvm_oct_remove(struct platform_device *pdev)
+static int cvm_oct_remove(struct platform_device *pdev)
{
int port;
@@ -874,7 +874,7 @@ MODULE_DEVICE_TABLE(of, cvm_oct_match);
static struct platform_driver cvm_oct_driver = {
.probe = cvm_oct_probe,
- .remove = __devexit_p(cvm_oct_remove),
+ .remove = cvm_oct_remove,
.driver = {
.owner = THIS_MODULE,
.name = KBUILD_MODNAME,
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c
index d49c32a9569..54ed6f69e3d 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon.c
@@ -39,10 +39,6 @@
static ushort resumeline = 898;
module_param(resumeline, ushort, 0444);
-/* Default off since it doesn't work on DCON ASIC in B-test OLPC board */
-static int useaa = 1;
-module_param(useaa, int, 0444);
-
static struct dcon_platform_data *pdata;
/* I2C structures */
@@ -50,8 +46,6 @@ static struct dcon_platform_data *pdata;
/* Platform devices */
static struct platform_device *dcon_device;
-static DECLARE_WAIT_QUEUE_HEAD(dcon_wait_queue);
-
static unsigned short normal_i2c[] = { 0x0d, I2C_CLIENT_END };
static s32 dcon_write(struct dcon_priv *dcon, u8 reg, u16 val)
@@ -103,9 +97,7 @@ static int dcon_hw_init(struct dcon_priv *dcon, int is_init)
/* Colour swizzle, AA, no passthrough, backlight */
if (is_init) {
dcon->disp_mode = MODE_PASSTHRU | MODE_BL_ENABLE |
- MODE_CSWIZZLE;
- if (useaa)
- dcon->disp_mode |= MODE_COL_AA;
+ MODE_CSWIZZLE | MODE_COL_AA;
}
dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode);
@@ -191,9 +183,7 @@ static int dcon_set_mono_mode(struct dcon_priv *dcon, bool enable_mono)
dcon->disp_mode |= MODE_MONO_LUMA;
} else {
dcon->disp_mode &= ~(MODE_MONO_LUMA);
- dcon->disp_mode |= MODE_CSWIZZLE;
- if (useaa)
- dcon->disp_mode |= MODE_COL_AA;
+ dcon->disp_mode |= MODE_CSWIZZLE | MODE_COL_AA;
}
dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode);
@@ -288,7 +278,6 @@ static void dcon_source_switch(struct work_struct *work)
{
struct dcon_priv *dcon = container_of(work, struct dcon_priv,
switch_source);
- DECLARE_WAITQUEUE(wait, current);
int source = dcon->pending_src;
if (dcon->curr_src == source)
@@ -305,11 +294,9 @@ static void dcon_source_switch(struct work_struct *work)
if (dcon_write(dcon, DCON_REG_MODE,
dcon->disp_mode | MODE_SCAN_INT))
pr_err("couldn't enable scanline interrupt!\n");
- else {
+ else
/* Wait up to one second for the scanline interrupt */
- wait_event_timeout(dcon_wait_queue,
- dcon->switched == true, HZ);
- }
+ wait_event_timeout(dcon->waitq, dcon->switched, HZ);
if (!dcon->switched)
pr_err("Timeout entering CPU mode; expect a screen glitch.\n");
@@ -340,21 +327,15 @@ static void dcon_source_switch(struct work_struct *work)
break;
case DCON_SOURCE_DCON:
{
- int t;
struct timespec delta_t;
pr_info("dcon_source_switch to DCON\n");
- add_wait_queue(&dcon_wait_queue, &wait);
- set_current_state(TASK_UNINTERRUPTIBLE);
-
/* Clear DCONLOAD - this implies that the DCON is in control */
pdata->set_dconload(0);
getnstimeofday(&dcon->load_time);
- t = schedule_timeout(HZ/2);
- remove_wait_queue(&dcon_wait_queue, &wait);
- set_current_state(TASK_RUNNING);
+ wait_event_timeout(dcon->waitq, dcon->switched, HZ/2);
if (!dcon->switched) {
pr_err("Timeout entering DCON mode; expect a screen glitch.\n");
@@ -539,6 +520,10 @@ static int dcon_bl_update(struct backlight_device *dev)
if (level != dcon->bl_val)
dcon_set_backlight(dcon, level);
+ /* power down the DCON when the screen is blanked */
+ if (!dcon->ignore_fb_events)
+ dcon_sleep(dcon, !!(dev->props.state & BL_CORE_FBBLANK));
+
return 0;
}
@@ -584,24 +569,6 @@ static struct notifier_block dcon_panic_nb = {
.notifier_call = unfreeze_on_panic,
};
-/*
- * When the framebuffer sleeps due to external sources (e.g. user idle), power
- * down the DCON as well. Power it back up when the fb comes back to life.
- */
-static int dcon_fb_notifier(struct notifier_block *self,
- unsigned long event, void *data)
-{
- struct fb_event *evdata = data;
- struct dcon_priv *dcon = container_of(self, struct dcon_priv,
- fbevent_nb);
- int *blank = (int *)evdata->data;
- if (((event != FB_EVENT_BLANK) && (event != FB_EVENT_CONBLANK)) ||
- dcon->ignore_fb_events)
- return 0;
- dcon_sleep(dcon, *blank ? true : false);
- return 0;
-}
-
static int dcon_detect(struct i2c_client *client, struct i2c_board_info *info)
{
strlcpy(info->type, "olpc_dcon", I2C_NAME_SIZE);
@@ -622,10 +589,10 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id)
return -ENOMEM;
dcon->client = client;
+ init_waitqueue_head(&dcon->waitq);
INIT_WORK(&dcon->switch_source, dcon_source_switch);
dcon->reboot_nb.notifier_call = dcon_reboot_notify;
dcon->reboot_nb.priority = -1;
- dcon->fbevent_nb.notifier_call = dcon_fb_notifier;
i2c_set_clientdata(client, dcon);
@@ -680,7 +647,6 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id)
register_reboot_notifier(&dcon->reboot_nb);
atomic_notifier_chain_register(&panic_notifier_list, &dcon_panic_nb);
- fb_register_client(&dcon->fbevent_nb);
return 0;
@@ -701,7 +667,6 @@ static int dcon_remove(struct i2c_client *client)
{
struct dcon_priv *dcon = i2c_get_clientdata(client);
- fb_unregister_client(&dcon->fbevent_nb);
unregister_reboot_notifier(&dcon->reboot_nb);
atomic_notifier_chain_unregister(&panic_notifier_list, &dcon_panic_nb);
@@ -720,8 +685,9 @@ static int dcon_remove(struct i2c_client *client)
}
#ifdef CONFIG_PM
-static int dcon_suspend(struct i2c_client *client, pm_message_t state)
+static int dcon_suspend(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct dcon_priv *dcon = i2c_get_clientdata(client);
if (!dcon->asleep) {
@@ -732,8 +698,9 @@ static int dcon_suspend(struct i2c_client *client, pm_message_t state)
return 0;
}
-static int dcon_resume(struct i2c_client *client)
+static int dcon_resume(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct dcon_priv *dcon = i2c_get_clientdata(client);
if (!dcon->asleep) {
@@ -744,7 +711,12 @@ static int dcon_resume(struct i2c_client *client)
return 0;
}
-#endif
+#else
+
+#define dcon_suspend NULL
+#define dcon_resume NULL
+
+#endif /* CONFIG_PM */
irqreturn_t dcon_interrupt(int irq, void *id)
@@ -764,7 +736,7 @@ irqreturn_t dcon_interrupt(int irq, void *id)
case 1: /* switch to CPU mode */
dcon->switched = true;
getnstimeofday(&dcon->irq_time);
- wake_up(&dcon_wait_queue);
+ wake_up(&dcon->waitq);
break;
case 0:
@@ -778,7 +750,7 @@ irqreturn_t dcon_interrupt(int irq, void *id)
if (dcon->curr_src != dcon->pending_src && !dcon->switched) {
dcon->switched = true;
getnstimeofday(&dcon->irq_time);
- wake_up(&dcon_wait_queue);
+ wake_up(&dcon->waitq);
pr_debug("switching w/ status 0/0\n");
} else {
pr_debug("scanline interrupt w/CPU\n");
@@ -788,27 +760,28 @@ irqreturn_t dcon_interrupt(int irq, void *id)
return IRQ_HANDLED;
}
+static const struct dev_pm_ops dcon_pm_ops = {
+ .suspend = dcon_suspend,
+ .resume = dcon_resume,
+};
+
static const struct i2c_device_id dcon_idtable[] = {
{ "olpc_dcon", 0 },
{ }
};
-
MODULE_DEVICE_TABLE(i2c, dcon_idtable);
struct i2c_driver dcon_driver = {
.driver = {
.name = "olpc_dcon",
+ .pm = &dcon_pm_ops,
},
.class = I2C_CLASS_DDC | I2C_CLASS_HWMON,
.id_table = dcon_idtable,
.probe = dcon_probe,
- .remove = __devexit_p(dcon_remove),
+ .remove = dcon_remove,
.detect = dcon_detect,
.address_list = normal_i2c,
-#ifdef CONFIG_PM
- .suspend = dcon_suspend,
- .resume = dcon_resume,
-#endif
};
static int __init olpc_dcon_init(void)
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h
index 167a41778be..997bded2949 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon.h
+++ b/drivers/staging/olpc_dcon/olpc_dcon.h
@@ -52,9 +52,9 @@ struct dcon_priv {
struct fb_info *fbinfo;
struct backlight_device *bl_dev;
+ wait_queue_head_t waitq;
struct work_struct switch_source;
struct notifier_block reboot_nb;
- struct notifier_block fbevent_nb;
/* Shadow register for the DCON_REG_MODE register */
u8 disp_mode;
diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
index 352dd3db013..6a4d379c16a 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
@@ -10,7 +10,6 @@
#include <linux/acpi.h>
#include <linux/delay.h>
-#include <linux/pci.h>
#include <linux/gpio.h>
#include <asm/olpc.h>
@@ -62,33 +61,6 @@ static int dcon_was_irq(void)
static int dcon_init_xo_1_5(struct dcon_priv *dcon)
{
unsigned int irq;
- u_int8_t tmp;
- struct pci_dev *pdev;
-
- pdev = pci_get_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VX855, NULL);
- if (!pdev) {
- pr_err("cannot find VX855 PCI ID\n");
- return 1;
- }
-
- pci_read_config_byte(pdev, 0x95, &tmp);
- pci_write_config_byte(pdev, 0x95, tmp|0x0c);
-
- /* Set GPIO8 to GPIO mode, not SSPICLK */
- pci_read_config_byte(pdev, 0xe3, &tmp);
- pci_write_config_byte(pdev, 0xe3, tmp | 0x04);
-
- /* Set GPI10/GPI11 to GPI mode, not SSPISDI/SSPISS */
- pci_read_config_byte(pdev, 0xe4, &tmp);
- pci_write_config_byte(pdev, 0xe4, tmp|0x08);
-
- /* clear PMU_RxE1[6] to select SCI on GPIO12 */
- /* clear PMU_RxE0[6] to choose falling edge */
- pci_read_config_byte(pdev, 0xe1, &tmp);
- pci_write_config_byte(pdev, 0xe1, tmp & ~BIT_GPIO12);
- pci_read_config_byte(pdev, 0xe0, &tmp);
- pci_write_config_byte(pdev, 0xe0, tmp & ~BIT_GPIO12);
dcon_clear_irq();
@@ -101,8 +73,6 @@ static int dcon_init_xo_1_5(struct dcon_priv *dcon)
DCON_SOURCE_CPU : DCON_SOURCE_DCON;
dcon->pending_src = dcon->curr_src;
- pci_dev_put(pdev);
-
/* we're sharing the IRQ with ACPI */
irq = acpi_gbl_FADT.sci_interrupt;
if (request_irq(irq, &dcon_interrupt, IRQF_SHARED, "DCON", dcon)) {
diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c
index 368a2e19b2d..8346e3450f8 100644
--- a/drivers/staging/omap-thermal/omap-bandgap.c
+++ b/drivers/staging/omap-thermal/omap-bandgap.c
@@ -38,6 +38,7 @@
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_irq.h>
+#include <linux/io.h>
#include "omap-bandgap.h"
@@ -112,6 +113,11 @@ static irqreturn_t talert_irq_handler(int irq, void *data)
omap_bandgap_writel(bg_ptr, ctrl, tsr->bgap_mask_ctrl);
+ dev_dbg(bg_ptr->dev,
+ "%s: IRQ from %s sensor: hotevent %d coldevent %d\n",
+ __func__, bg_ptr->conf->sensors[i].domain,
+ t_hot, t_cold);
+
/* read temperature */
temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
temp &= tsr->bgap_dtemp_mask;
@@ -843,7 +849,7 @@ static struct omap_bandgap *omap_bandgap_build(struct platform_device *pdev)
}
static
-int __devinit omap_bandgap_probe(struct platform_device *pdev)
+int omap_bandgap_probe(struct platform_device *pdev)
{
struct omap_bandgap *bg_ptr;
int clk_rate, ret = 0, i;
@@ -992,7 +998,7 @@ free_irqs:
}
static
-int __devexit omap_bandgap_remove(struct platform_device *pdev)
+int omap_bandgap_remove(struct platform_device *pdev)
{
struct omap_bandgap *bg_ptr = platform_get_drvdata(pdev);
int i;
@@ -1059,7 +1065,6 @@ static int omap_bandgap_save_ctxt(struct omap_bandgap *bg_ptr)
static int omap_bandgap_restore_ctxt(struct omap_bandgap *bg_ptr)
{
int i;
- u32 temp = 0;
for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
struct temp_sensor_registers *tsr;
@@ -1072,41 +1077,27 @@ static int omap_bandgap_restore_ctxt(struct omap_bandgap *bg_ptr)
if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER))
val = omap_bandgap_readl(bg_ptr, tsr->bgap_counter);
- if (val == 0) {
- if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT_CONFIG))
- omap_bandgap_writel(bg_ptr,
- rval->tshut_threshold,
- tsr->tshut_threshold);
- /* Force immediate temperature measurement and update
- * of the DTEMP field
- */
- omap_bandgap_force_single_read(bg_ptr, i);
-
- if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER))
- omap_bandgap_writel(bg_ptr, rval->bg_counter,
- tsr->bgap_counter);
- if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG))
- omap_bandgap_writel(bg_ptr, rval->bg_mode_ctrl,
- tsr->bgap_mode_ctrl);
- if (OMAP_BANDGAP_HAS(bg_ptr, TALERT)) {
- omap_bandgap_writel(bg_ptr,
- rval->bg_threshold,
- tsr->bgap_threshold);
- omap_bandgap_writel(bg_ptr, rval->bg_ctrl,
- tsr->bgap_mask_ctrl);
- }
- } else {
- temp = omap_bandgap_readl(bg_ptr,
- tsr->temp_sensor_ctrl);
- temp &= (tsr->bgap_dtemp_mask);
- omap_bandgap_force_single_read(bg_ptr, i);
- if (temp == 0 && OMAP_BANDGAP_HAS(bg_ptr, TALERT)) {
- temp = omap_bandgap_readl(bg_ptr,
- tsr->bgap_mask_ctrl);
- temp |= 1 << __ffs(tsr->mode_ctrl_mask);
- omap_bandgap_writel(bg_ptr, temp,
- tsr->bgap_mask_ctrl);
- }
+ if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT_CONFIG))
+ omap_bandgap_writel(bg_ptr,
+ rval->tshut_threshold,
+ tsr->tshut_threshold);
+ /* Force immediate temperature measurement and update
+ * of the DTEMP field
+ */
+ omap_bandgap_force_single_read(bg_ptr, i);
+
+ if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER))
+ omap_bandgap_writel(bg_ptr, rval->bg_counter,
+ tsr->bgap_counter);
+ if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG))
+ omap_bandgap_writel(bg_ptr, rval->bg_mode_ctrl,
+ tsr->bgap_mode_ctrl);
+ if (OMAP_BANDGAP_HAS(bg_ptr, TALERT)) {
+ omap_bandgap_writel(bg_ptr,
+ rval->bg_threshold,
+ tsr->bgap_threshold);
+ omap_bandgap_writel(bg_ptr, rval->bg_ctrl,
+ tsr->bgap_mask_ctrl);
}
}
diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h
index 78aed7535f4..2bb14bd7c6d 100644
--- a/drivers/staging/omap-thermal/omap-bandgap.h
+++ b/drivers/staging/omap-thermal/omap-bandgap.h
@@ -336,14 +336,6 @@ struct temp_sensor_regval {
};
/**
- * struct thermal_cooling_conf - description on how to cool a thermal zone
- * @freq_clip_count: size of freq_data
- */
-struct thermal_cooling_conf {
- int freq_clip_count;
-};
-
-/**
* struct omap_temp_sensor - bandgap temperature sensor platform data
* @ts_data: pointer to struct with thresholds, limits of temperature sensor
* @registers: pointer to the list of register offsets and bitfields
@@ -365,7 +357,6 @@ struct omap_temp_sensor {
struct temp_sensor_registers *registers;
struct temp_sensor_regval regval;
char *domain;
- struct thermal_cooling_conf cooling_data;
/* for hotspot extrapolation */
const int slope;
const int constant;
diff --git a/drivers/staging/omap-thermal/omap-thermal-common.c b/drivers/staging/omap-thermal/omap-thermal-common.c
index 5c0c203b887..15e9723ba4d 100644
--- a/drivers/staging/omap-thermal/omap-thermal-common.c
+++ b/drivers/staging/omap-thermal/omap-thermal-common.c
@@ -29,6 +29,7 @@
#include <linux/workqueue.h>
#include <linux/thermal.h>
#include <linux/cpufreq.h>
+#include <linux/cpumask.h>
#include <linux/cpu_cooling.h>
#include "omap-thermal.h"
@@ -112,7 +113,7 @@ static int omap_thermal_bind(struct thermal_zone_device *thermal,
struct thermal_cooling_device *cdev)
{
struct omap_thermal_data *data = thermal->devdata;
- int max, id;
+ int id;
if (IS_ERR_OR_NULL(data))
return -ENODEV;
@@ -122,7 +123,6 @@ static int omap_thermal_bind(struct thermal_zone_device *thermal,
return 0;
id = data->sensor_id;
- max = data->bg_ptr->conf->sensors[id].cooling_data.freq_clip_count;
/* TODO: bind with min and max states */
/* Simple thing, two trips, one passive another critical */
@@ -256,12 +256,12 @@ static struct omap_thermal_data
int omap_thermal_expose_sensor(struct omap_bandgap *bg_ptr, int id,
char *domain)
{
- struct omap_thermal_pdata pdata;
+ struct omap_thermal_data *data;
data = omap_bandgap_get_sensor_data(bg_ptr, id);
if (!data)
- data = omap_thermal_build_pdata(bg_ptr, id);
+ data = omap_thermal_build_data(bg_ptr, id);
if (!data)
return -EINVAL;
@@ -304,81 +304,24 @@ int omap_thermal_report_sensor_temperature(struct omap_bandgap *bg_ptr, int id)
return 0;
}
-static int omap_thermal_build_cpufreq_clip(struct omap_bandgap *bg_ptr,
- struct freq_clip_table **tab_ptr,
- int *tab_size)
-{
- struct cpufreq_frequency_table *freq_table;
- struct freq_clip_table *tab;
- int i, count = 0;
-
- freq_table = cpufreq_frequency_get_table(0);
- if (IS_ERR_OR_NULL(freq_table)) {
- dev_err(bg_ptr->dev,
- "%s: failed to get cpufreq table (%p)\n",
- __func__, freq_table);
- return -EINVAL;
- }
-
- for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
- unsigned int freq = freq_table[i].frequency;
- if (freq == CPUFREQ_ENTRY_INVALID)
- continue;
- count++;
- }
-
- tab = devm_kzalloc(bg_ptr->dev, sizeof(*tab) * count, GFP_KERNEL);
- if (!tab) {
- dev_err(bg_ptr->dev,
- "%s: no memory available\n", __func__);
- return -ENOMEM;
- }
-
- for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
- unsigned int freq = freq_table[i].frequency;
-
- if (freq == CPUFREQ_ENTRY_INVALID)
- continue;
-
- tab[count - i - 1].freq_clip_max = freq;
- tab[count - i - 1].temp_level = OMAP_TRIP_HOT;
- tab[count - i - 1].mask_val = cpumask_of(0);
- }
-
- *tab_ptr = tab;
- *tab_size = count;
-
- return 0;
-}
-
int omap_thermal_register_cpu_cooling(struct omap_bandgap *bg_ptr, int id)
{
struct omap_thermal_data *data;
- struct freq_clip_table *tab_ptr;
- int tab_size, ret;
data = omap_bandgap_get_sensor_data(bg_ptr, id);
if (!data)
- data = omap_thermal_build_pdata(bg_ptr, id);
+ data = omap_thermal_build_data(bg_ptr, id);
if (!data)
return -EINVAL;
- ret = omap_thermal_build_cpufreq_clip(bg_ptr, &tab_ptr, &tab_size);
- if (ret < 0) {
- dev_err(bg_ptr->dev,
- "%s: failed to build cpufreq clip table\n", __func__);
- return ret;
- }
-
/* Register cooling device */
- data->cool_dev = cpufreq_cooling_register(tab_ptr, tab_size);
+ data->cool_dev = cpufreq_cooling_register(cpu_present_mask);
if (IS_ERR_OR_NULL(data->cool_dev)) {
dev_err(bg_ptr->dev,
"Failed to register cpufreq cooling device\n");
return PTR_ERR(data->cool_dev);
}
- bg_ptr->conf->sensors[id].cooling_data.freq_clip_count = tab_size;
omap_bandgap_set_sensor_data(bg_ptr, id, data);
return 0;
diff --git a/drivers/staging/omapdrm/Kconfig b/drivers/staging/omapdrm/Kconfig
index 81a7cba4a0c..b724a413143 100644
--- a/drivers/staging/omapdrm/Kconfig
+++ b/drivers/staging/omapdrm/Kconfig
@@ -2,7 +2,7 @@
config DRM_OMAP
tristate "OMAP DRM"
depends on DRM && !CONFIG_FB_OMAP2
- depends on ARCH_OMAP2PLUS
+ depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM
select DRM_KMS_HELPER
select OMAP2_DSS
select FB_SYS_FILLRECT
diff --git a/drivers/staging/omapdrm/omap_connector.c b/drivers/staging/omapdrm/omap_connector.c
index 38be186c249..91edb3f9697 100644
--- a/drivers/staging/omapdrm/omap_connector.c
+++ b/drivers/staging/omapdrm/omap_connector.c
@@ -146,11 +146,10 @@ enum drm_connector_status omap_connector_detect(
enum drm_connector_status ret;
if (dssdrv->detect) {
- if (dssdrv->detect(dssdev)) {
+ if (dssdrv->detect(dssdev))
ret = connector_status_connected;
- } else {
+ else
ret = connector_status_disconnected;
- }
} else {
ret = connector_status_unknown;
}
@@ -383,9 +382,8 @@ struct drm_connector *omap_connector_init(struct drm_device *dev,
return connector;
fail:
- if (connector) {
+ if (connector)
omap_connector_destroy(connector);
- }
return NULL;
}
diff --git a/drivers/staging/omapdrm/omap_crtc.c b/drivers/staging/omapdrm/omap_crtc.c
index 732f2ad3403..d87bd84257b 100644
--- a/drivers/staging/omapdrm/omap_crtc.c
+++ b/drivers/staging/omapdrm/omap_crtc.c
@@ -19,7 +19,7 @@
#include "omap_drv.h"
-#include "drm_mode.h"
+#include <drm/drm_mode.h>
#include "drm_crtc.h"
#include "drm_crtc_helper.h"
@@ -114,7 +114,7 @@ static void omap_crtc_load_lut(struct drm_crtc *crtc)
static void vblank_cb(void *arg)
{
- static uint32_t sequence = 0;
+ static uint32_t sequence;
struct drm_crtc *crtc = arg;
struct drm_device *dev = crtc->dev;
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
@@ -263,8 +263,8 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
return crtc;
fail:
- if (crtc) {
+ if (crtc)
omap_crtc_destroy(crtc);
- }
+
return NULL;
}
diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h b/drivers/staging/omapdrm/omap_dmm_priv.h
index 08b22e9f0ed..273ec12c028 100644
--- a/drivers/staging/omapdrm/omap_dmm_priv.h
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -141,8 +141,7 @@ struct refill_engine {
/* only one trans per engine for now */
struct dmm_txn txn;
- /* offset to lut associated with container */
- u32 *lut_offset;
+ bool async;
wait_queue_head_t wait_for_refill;
@@ -161,10 +160,11 @@ struct dmm {
dma_addr_t refill_pa;
/* refill engines */
- struct semaphore engine_sem;
+ wait_queue_head_t engine_queue;
struct list_head idle_head;
struct refill_engine *engines;
int num_engines;
+ atomic_t engine_counter;
/* container information */
int container_width;
@@ -176,9 +176,6 @@ struct dmm {
/* array of LUT - TCM containers */
struct tcm **tcm;
- /* LUT table storage */
- u32 *lut;
-
/* allocation list and lock */
struct list_head alloc_head;
};
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c
index 3ae39554df1..59bf43899fc 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -29,7 +29,6 @@
#include <linux/mm.h>
#include <linux/time.h>
#include <linux/list.h>
-#include <linux/semaphore.h>
#include "omap_dmm_tiler.h"
#include "omap_dmm_priv.h"
@@ -120,6 +119,18 @@ static int wait_status(struct refill_engine *engine, uint32_t wait_mask)
return 0;
}
+static void release_engine(struct refill_engine *engine)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&list_lock, flags);
+ list_add(&engine->idle_node, &omap_dmm->idle_head);
+ spin_unlock_irqrestore(&list_lock, flags);
+
+ atomic_inc(&omap_dmm->engine_counter);
+ wake_up_interruptible(&omap_dmm->engine_queue);
+}
+
static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
{
struct dmm *dmm = arg;
@@ -130,9 +141,13 @@ static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
writel(status, dmm->base + DMM_PAT_IRQSTATUS);
for (i = 0; i < dmm->num_engines; i++) {
- if (status & DMM_IRQSTAT_LST)
+ if (status & DMM_IRQSTAT_LST) {
wake_up_interruptible(&dmm->engines[i].wait_for_refill);
+ if (dmm->engines[i].async)
+ release_engine(&dmm->engines[i]);
+ }
+
status >>= 8;
}
@@ -146,17 +161,24 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct tcm *tcm)
{
struct dmm_txn *txn = NULL;
struct refill_engine *engine = NULL;
+ int ret;
+ unsigned long flags;
- down(&dmm->engine_sem);
+
+ /* wait until an engine is available */
+ ret = wait_event_interruptible(omap_dmm->engine_queue,
+ atomic_add_unless(&omap_dmm->engine_counter, -1, 0));
+ if (ret)
+ return ERR_PTR(ret);
/* grab an idle engine */
- spin_lock(&list_lock);
+ spin_lock_irqsave(&list_lock, flags);
if (!list_empty(&dmm->idle_head)) {
engine = list_entry(dmm->idle_head.next, struct refill_engine,
idle_node);
list_del(&engine->idle_node);
}
- spin_unlock(&list_lock);
+ spin_unlock_irqrestore(&list_lock, flags);
BUG_ON(!engine);
@@ -174,7 +196,7 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct tcm *tcm)
* Add region to DMM transaction. If pages or pages[i] is NULL, then the
* corresponding slot is cleared (ie. dummy_pa is programmed)
*/
-static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
+static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
struct page **pages, uint32_t npages, uint32_t roll)
{
dma_addr_t pat_pa = 0;
@@ -184,9 +206,6 @@ static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
int columns = (1 + area->x1 - area->x0);
int rows = (1 + area->y1 - area->y0);
int i = columns*rows;
- u32 *lut = omap_dmm->lut + (engine->tcm->lut_id * omap_dmm->lut_width *
- omap_dmm->lut_height) +
- (area->y0 * omap_dmm->lut_width) + area->x0;
pat = alloc_dma(txn, sizeof(struct pat), &pat_pa);
@@ -209,13 +228,9 @@ static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
page_to_phys(pages[n]) : engine->dmm->dummy_pa;
}
- /* fill in lut with new addresses */
- for (i = 0; i < rows; i++, lut += omap_dmm->lut_width)
- memcpy(lut, &data[i*columns], columns * sizeof(u32));
-
txn->last_pat = pat;
- return 0;
+ return;
}
/**
@@ -245,6 +260,9 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
goto cleanup;
}
+ /* mark whether it is async to denote list management in IRQ handler */
+ engine->async = wait ? false : true;
+
/* kick reload */
writel(engine->refill_pa,
dmm->base + reg[PAT_DESCR][engine->id]);
@@ -259,11 +277,10 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
}
cleanup:
- spin_lock(&list_lock);
- list_add(&engine->idle_node, &dmm->idle_head);
- spin_unlock(&list_lock);
+ /* only place engine back on list if we are done with it */
+ if (ret || wait)
+ release_engine(engine);
- up(&omap_dmm->engine_sem);
return ret;
}
@@ -279,7 +296,7 @@ static int fill(struct tcm_area *area, struct page **pages,
txn = dmm_txn_init(omap_dmm, area->tcm);
if (IS_ERR_OR_NULL(txn))
- return PTR_ERR(txn);
+ return -ENOMEM;
tcm_for_each_slice(slice, *area, area_s) {
struct pat_area p_area = {
@@ -287,16 +304,13 @@ static int fill(struct tcm_area *area, struct page **pages,
.x1 = slice.p1.x, .y1 = slice.p1.y,
};
- ret = dmm_txn_append(txn, &p_area, pages, npages, roll);
- if (ret)
- goto fail;
+ dmm_txn_append(txn, &p_area, pages, npages, roll);
roll += tcm_sizeof(slice);
}
ret = dmm_txn_commit(txn, wait);
-fail:
return ret;
}
@@ -333,6 +347,7 @@ struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, uint16_t w,
struct tiler_block *block = kzalloc(sizeof(*block), GFP_KERNEL);
u32 min_align = 128;
int ret;
+ unsigned long flags;
BUG_ON(!validfmt(fmt));
@@ -354,9 +369,9 @@ struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, uint16_t w,
}
/* add to allocation list */
- spin_lock(&list_lock);
+ spin_lock_irqsave(&list_lock, flags);
list_add(&block->alloc_node, &omap_dmm->alloc_head);
- spin_unlock(&list_lock);
+ spin_unlock_irqrestore(&list_lock, flags);
return block;
}
@@ -365,6 +380,7 @@ struct tiler_block *tiler_reserve_1d(size_t size)
{
struct tiler_block *block = kzalloc(sizeof(*block), GFP_KERNEL);
int num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ unsigned long flags;
if (!block)
return ERR_PTR(-ENOMEM);
@@ -377,9 +393,9 @@ struct tiler_block *tiler_reserve_1d(size_t size)
return ERR_PTR(-ENOMEM);
}
- spin_lock(&list_lock);
+ spin_lock_irqsave(&list_lock, flags);
list_add(&block->alloc_node, &omap_dmm->alloc_head);
- spin_unlock(&list_lock);
+ spin_unlock_irqrestore(&list_lock, flags);
return block;
}
@@ -388,13 +404,14 @@ struct tiler_block *tiler_reserve_1d(size_t size)
int tiler_release(struct tiler_block *block)
{
int ret = tcm_free(&block->area);
+ unsigned long flags;
if (block->area.tcm)
dev_err(omap_dmm->dev, "failed to release block\n");
- spin_lock(&list_lock);
+ spin_lock_irqsave(&list_lock, flags);
list_del(&block->alloc_node);
- spin_unlock(&list_lock);
+ spin_unlock_irqrestore(&list_lock, flags);
kfree(block);
return ret;
@@ -505,7 +522,7 @@ size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h)
return round_up(geom[fmt].cpp * w, PAGE_SIZE) * h;
}
-bool dmm_is_initialized(void)
+bool dmm_is_available(void)
{
return omap_dmm ? true : false;
}
@@ -514,16 +531,17 @@ static int omap_dmm_remove(struct platform_device *dev)
{
struct tiler_block *block, *_block;
int i;
+ unsigned long flags;
if (omap_dmm) {
/* free all area regions */
- spin_lock(&list_lock);
+ spin_lock_irqsave(&list_lock, flags);
list_for_each_entry_safe(block, _block, &omap_dmm->alloc_head,
alloc_node) {
list_del(&block->alloc_node);
kfree(block);
}
- spin_unlock(&list_lock);
+ spin_unlock_irqrestore(&list_lock, flags);
for (i = 0; i < omap_dmm->num_lut; i++)
if (omap_dmm->tcm && omap_dmm->tcm[i])
@@ -532,15 +550,13 @@ static int omap_dmm_remove(struct platform_device *dev)
kfree(omap_dmm->engines);
if (omap_dmm->refill_va)
- dma_free_coherent(omap_dmm->dev,
+ dma_free_writecombine(omap_dmm->dev,
REFILL_BUFFER_SIZE * omap_dmm->num_engines,
omap_dmm->refill_va,
omap_dmm->refill_pa);
if (omap_dmm->dummy_page)
__free_page(omap_dmm->dummy_page);
- vfree(omap_dmm->lut);
-
if (omap_dmm->irq > 0)
free_irq(omap_dmm->irq, omap_dmm);
@@ -556,7 +572,7 @@ static int omap_dmm_probe(struct platform_device *dev)
{
int ret = -EFAULT, i;
struct tcm_area area = {0};
- u32 hwinfo, pat_geom, lut_table_size;
+ u32 hwinfo, pat_geom;
struct resource *mem;
omap_dmm = kzalloc(sizeof(*omap_dmm), GFP_KERNEL);
@@ -569,6 +585,8 @@ static int omap_dmm_probe(struct platform_device *dev)
INIT_LIST_HEAD(&omap_dmm->alloc_head);
INIT_LIST_HEAD(&omap_dmm->idle_head);
+ init_waitqueue_head(&omap_dmm->engine_queue);
+
/* lookup hwmod data - base address and irq */
mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!mem) {
@@ -597,6 +615,8 @@ static int omap_dmm_probe(struct platform_device *dev)
omap_dmm->container_width = 256;
omap_dmm->container_height = 128;
+ atomic_set(&omap_dmm->engine_counter, omap_dmm->num_engines);
+
/* read out actual LUT width and height */
pat_geom = readl(omap_dmm->base + DMM_PAT_GEOMETRY);
omap_dmm->lut_width = ((pat_geom >> 16) & 0xF) << 5;
@@ -628,16 +648,6 @@ static int omap_dmm_probe(struct platform_device *dev)
*/
writel(0x7e7e7e7e, omap_dmm->base + DMM_PAT_IRQENABLE_SET);
- lut_table_size = omap_dmm->lut_width * omap_dmm->lut_height *
- omap_dmm->num_lut;
-
- omap_dmm->lut = vmalloc(lut_table_size * sizeof(*omap_dmm->lut));
- if (!omap_dmm->lut) {
- dev_err(&dev->dev, "could not allocate lut table\n");
- ret = -ENOMEM;
- goto fail;
- }
-
omap_dmm->dummy_page = alloc_page(GFP_KERNEL | __GFP_DMA32);
if (!omap_dmm->dummy_page) {
dev_err(&dev->dev, "could not allocate dummy page\n");
@@ -652,7 +662,7 @@ static int omap_dmm_probe(struct platform_device *dev)
omap_dmm->dummy_pa = page_to_phys(omap_dmm->dummy_page);
/* alloc refill memory */
- omap_dmm->refill_va = dma_alloc_coherent(&dev->dev,
+ omap_dmm->refill_va = dma_alloc_writecombine(&dev->dev,
REFILL_BUFFER_SIZE * omap_dmm->num_engines,
&omap_dmm->refill_pa, GFP_KERNEL);
if (!omap_dmm->refill_va) {
@@ -670,7 +680,6 @@ static int omap_dmm_probe(struct platform_device *dev)
goto fail;
}
- sema_init(&omap_dmm->engine_sem, omap_dmm->num_engines);
for (i = 0; i < omap_dmm->num_engines; i++) {
omap_dmm->engines[i].id = i;
omap_dmm->engines[i].dmm = omap_dmm;
@@ -720,9 +729,6 @@ static int omap_dmm_probe(struct platform_device *dev)
.p1.y = omap_dmm->container_height - 1,
};
- for (i = 0; i < lut_table_size; i++)
- omap_dmm->lut[i] = omap_dmm->dummy_pa;
-
/* initialize all LUTs to dummy page entries */
for (i = 0; i < omap_dmm->num_lut; i++) {
area.tcm = omap_dmm->tcm[i];
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.h b/drivers/staging/omapdrm/omap_dmm_tiler.h
index 740911df5fc..4fdd61e54bd 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.h
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.h
@@ -16,7 +16,6 @@
#ifndef OMAP_DMM_TILER_H
#define OMAP_DMM_TILER_H
-#include <plat/cpu.h>
#include "omap_drv.h"
#include "tcm.h"
@@ -107,7 +106,7 @@ uint32_t tiler_stride(enum tiler_fmt fmt, uint32_t orient);
size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h);
size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h);
void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h);
-bool dmm_is_initialized(void);
+bool dmm_is_available(void);
extern struct platform_driver omap_dmm_driver;
@@ -139,9 +138,4 @@ static inline bool validfmt(enum tiler_fmt fmt)
}
}
-static inline int dmm_is_available(void)
-{
- return cpu_is_omap44xx();
-}
-
#endif
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index ebdb0b67673..d4823fd6776 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -30,8 +30,6 @@
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 0
-struct drm_device *drm_device;
-
static int num_crtc = CONFIG_DRM_OMAP_NUM_CRTCS;
MODULE_PARM_DESC(num_crtc, "Number of overlays to use as CRTCs");
@@ -53,9 +51,8 @@ static void omap_fb_output_poll_changed(struct drm_device *dev)
{
struct omap_drm_private *priv = dev->dev_private;
DBG("dev=%p", dev);
- if (priv->fbdev) {
+ if (priv->fbdev)
drm_fb_helper_hotplug_event(priv->fbdev);
- }
}
static const struct drm_mode_config_funcs omap_mode_config_funcs = {
@@ -87,9 +84,9 @@ static int omap_drm_notifier(struct notifier_block *nb,
case OMAP_DSS_HOTPLUG_DISCONNECT: {
struct drm_device *dev = drm_device;
DBG("hotplug event: evt=%d, dev=%p", evt, dev);
- if (dev) {
+ if (dev)
drm_sysfs_hotplug_event(dev);
- }
+
return NOTIFY_OK;
}
default: /* don't care about other events for now */
@@ -213,9 +210,9 @@ static int create_crtc(struct drm_device *dev, struct omap_overlay *ovl,
struct drm_encoder *encoder =
omap_connector_attached_encoder(
priv->connectors[*j]);
- if (encoder) {
+ if (encoder)
mgr = omap_encoder_get_manager(encoder);
- }
+
}
(*j)++;
}
@@ -234,9 +231,9 @@ static int create_crtc(struct drm_device *dev, struct omap_overlay *ovl,
struct drm_encoder *encoder =
omap_connector_attached_encoder(
priv->connectors[idx]);
- if (encoder) {
+ if (encoder)
mgr = omap_encoder_get_manager(encoder);
- }
+
}
(*j)++;
}
@@ -355,9 +352,8 @@ static int omap_modeset_init(struct drm_device *dev)
*/
int max_overlays = min(omap_dss_get_num_overlays(), num_crtc);
- for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) {
+ for (i = 0; i < omap_dss_get_num_overlay_managers(); i++)
create_encoder(dev, omap_dss_get_overlay_manager(i));
- }
for_each_dss_dev(dssdev) {
create_connector(dev, dssdev);
@@ -419,13 +415,14 @@ static void omap_modeset_free(struct drm_device *dev)
static int ioctl_get_param(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
+ struct omap_drm_private *priv = dev->dev_private;
struct drm_omap_param *args = data;
DBG("%p: param=%llu", dev, args->param);
switch (args->param) {
case OMAP_PARAM_CHIPSET_ID:
- args->value = GET_OMAP_TYPE;
+ args->value = priv->omaprev;
break;
default:
DBG("unknown parameter %lld", args->param);
@@ -469,15 +466,13 @@ static int ioctl_gem_cpu_prep(struct drm_device *dev, void *data,
VERB("%p:%p: handle=%d, op=%x", dev, file_priv, args->handle, args->op);
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
- if (!obj) {
+ if (!obj)
return -ENOENT;
- }
ret = omap_gem_op_sync(obj, args->op);
- if (!ret) {
+ if (!ret)
ret = omap_gem_op_start(obj, args->op);
- }
drm_gem_object_unreference_unlocked(obj);
@@ -494,16 +489,14 @@ static int ioctl_gem_cpu_fini(struct drm_device *dev, void *data,
VERB("%p:%p: handle=%d", dev, file_priv, args->handle);
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
- if (!obj) {
+ if (!obj)
return -ENOENT;
- }
/* XXX flushy, flushy */
ret = 0;
- if (!ret) {
+ if (!ret)
ret = omap_gem_op_finish(obj, args->op);
- }
drm_gem_object_unreference_unlocked(obj);
@@ -520,9 +513,8 @@ static int ioctl_gem_info(struct drm_device *dev, void *data,
DBG("%p:%p: handle=%d", dev, file_priv, args->handle);
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
- if (!obj) {
+ if (!obj)
return -ENOENT;
- }
args->size = omap_gem_mmap_size(obj);
args->offset = omap_gem_mmap_offset(obj);
@@ -557,19 +549,20 @@ struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = {
*/
static int dev_load(struct drm_device *dev, unsigned long flags)
{
+ struct omap_drm_platform_data *pdata = dev->dev->platform_data;
struct omap_drm_private *priv;
int ret;
DBG("load: dev=%p", dev);
- drm_device = dev;
-
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
dev_err(dev->dev, "could not allocate priv\n");
return -ENOMEM;
}
+ priv->omaprev = pdata->omaprev;
+
dev->dev_private = priv;
priv->wq = alloc_ordered_workqueue("omapdrm", 0);
@@ -595,9 +588,8 @@ static int dev_load(struct drm_device *dev, unsigned long flags)
drm_kms_helper_poll_init(dev);
ret = drm_vblank_init(dev, priv->num_crtcs);
- if (ret) {
+ if (ret)
dev_warn(dev->dev, "could not init vblank\n");
- }
return 0;
}
@@ -659,19 +651,22 @@ static void dev_lastclose(struct drm_device *dev)
DBG("lastclose: dev=%p", dev);
- /* need to restore default rotation state.. not sure if there is
- * a cleaner way to restore properties to default state? Maybe
- * a flag that properties should automatically be restored to
- * default state on lastclose?
- */
- for (i = 0; i < priv->num_crtcs; i++) {
- drm_object_property_set_value(&priv->crtcs[i]->base,
- priv->rotation_prop, 0);
- }
+ if (priv->rotation_prop) {
+ /* need to restore default rotation state.. not sure
+ * if there is a cleaner way to restore properties to
+ * default state? Maybe a flag that properties should
+ * automatically be restored to default state on
+ * lastclose?
+ */
+ for (i = 0; i < priv->num_crtcs; i++) {
+ drm_object_property_set_value(&priv->crtcs[i]->base,
+ priv->rotation_prop, 0);
+ }
- for (i = 0; i < priv->num_planes; i++) {
- drm_object_property_set_value(&priv->planes[i]->base,
- priv->rotation_prop, 0);
+ for (i = 0; i < priv->num_planes; i++) {
+ drm_object_property_set_value(&priv->planes[i]->base,
+ priv->rotation_prop, 0);
+ }
}
ret = drm_fb_helper_restore_fbdev_mode(priv->fbdev);
diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h
index 9dc72d143ff..1d4aea53b75 100644
--- a/drivers/staging/omapdrm/omap_drv.h
+++ b/drivers/staging/omapdrm/omap_drv.h
@@ -40,6 +40,8 @@
#define MAX_MAPPERS 2
struct omap_drm_private {
+ uint32_t omaprev;
+
unsigned int num_crtcs;
struct drm_crtc *crtcs[8];
@@ -189,9 +191,9 @@ size_t omap_gem_mmap_size(struct drm_gem_object *obj);
int omap_gem_tiled_size(struct drm_gem_object *obj, uint16_t *w, uint16_t *h);
int omap_gem_tiled_stride(struct drm_gem_object *obj, uint32_t orient);
-struct dma_buf * omap_gem_prime_export(struct drm_device *dev,
+struct dma_buf *omap_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *obj, int flags);
-struct drm_gem_object * omap_gem_prime_import(struct drm_device *dev,
+struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
struct dma_buf *buffer);
static inline int align_pitch(int pitch, int width, int bpp)
@@ -216,17 +218,17 @@ static inline int objects_lookup(struct drm_device *dev,
for (i = 0; i < n; i++) {
bos[i] = drm_gem_object_lookup(dev, filp, handles[i]);
- if (!bos[i]) {
+ if (!bos[i])
goto fail;
- }
+
}
return 0;
fail:
- while (--i > 0) {
+ while (--i > 0)
drm_gem_object_unreference_unlocked(bos[i]);
- }
+
return -ENOENT;
}
diff --git a/drivers/staging/omapdrm/omap_encoder.c b/drivers/staging/omapdrm/omap_encoder.c
index 31c735d3921..5341d5e3e31 100644
--- a/drivers/staging/omapdrm/omap_encoder.c
+++ b/drivers/staging/omapdrm/omap_encoder.c
@@ -72,9 +72,9 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
for (i = 0; i < priv->num_connectors; i++) {
struct drm_connector *connector = priv->connectors[i];
- if (connector->encoder == encoder) {
+ if (connector->encoder == encoder)
omap_connector_mode_set(connector, mode);
- }
+
}
}
@@ -163,9 +163,8 @@ struct drm_encoder *omap_encoder_init(struct drm_device *dev,
return encoder;
fail:
- if (encoder) {
+ if (encoder)
omap_encoder_destroy(encoder);
- }
return NULL;
}
diff --git a/drivers/staging/omapdrm/omap_fb.c b/drivers/staging/omapdrm/omap_fb.c
index 446801d6300..09028e9c109 100644
--- a/drivers/staging/omapdrm/omap_fb.c
+++ b/drivers/staging/omapdrm/omap_fb.c
@@ -253,6 +253,7 @@ int omap_framebuffer_replace(struct drm_framebuffer *a,
int ret = 0, i, na, nb;
struct omap_framebuffer *ofba = to_omap_framebuffer(a);
struct omap_framebuffer *ofbb = to_omap_framebuffer(b);
+ uint32_t pinned_mask = 0;
na = a ? drm_format_num_planes(a->pixel_format) : 0;
nb = b ? drm_format_num_planes(b->pixel_format) : 0;
@@ -263,25 +264,24 @@ int omap_framebuffer_replace(struct drm_framebuffer *a,
pa = (i < na) ? &ofba->planes[i] : NULL;
pb = (i < nb) ? &ofbb->planes[i] : NULL;
- if (pa) {
+ if (pa)
unpin(arg, pa->bo);
- pa->paddr = 0;
- }
if (pb && !ret) {
ret = omap_gem_get_paddr(pb->bo, &pb->paddr, true);
- if (!ret)
+ if (!ret) {
omap_gem_dma_sync(pb->bo, DMA_TO_DEVICE);
+ pinned_mask |= (1 << i);
+ }
}
}
if (ret) {
/* something went wrong.. unpin what has been pinned */
for (i = 0; i < nb; i++) {
- struct plane *pb = &ofba->planes[i];
- if (pb->paddr) {
+ if (pinned_mask & (1 << i)) {
+ struct plane *pb = &ofba->planes[i];
unpin(arg, pb->bo);
- pb->paddr = 0;
}
}
}
@@ -307,17 +307,16 @@ struct drm_connector *omap_framebuffer_get_next_connector(
struct list_head *connector_list = &dev->mode_config.connector_list;
struct drm_connector *connector = from;
- if (!from) {
+ if (!from)
return list_first_entry(connector_list, typeof(*from), head);
- }
list_for_each_entry_from(connector, connector_list, head) {
if (connector != from) {
struct drm_encoder *encoder = connector->encoder;
struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
- if (crtc && crtc->fb == fb) {
+ if (crtc && crtc->fb == fb)
return connector;
- }
+
}
}
@@ -466,8 +465,8 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
return fb;
fail:
- if (fb) {
+ if (fb)
omap_framebuffer_destroy(fb);
- }
+
return ERR_PTR(ret);
}
diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c
index 66e2c2f8a23..c38992b76fc 100644
--- a/drivers/staging/omapdrm/omap_gem.c
+++ b/drivers/staging/omapdrm/omap_gem.c
@@ -25,7 +25,7 @@
#include "omap_dmm_tiler.h"
/* remove these once drm core helpers are merged */
-struct page ** _drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask);
+struct page **_drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask);
void _drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
bool dirty, bool accessed);
int _drm_gem_create_mmap_offset_size(struct drm_gem_object *obj, size_t size);
@@ -521,9 +521,8 @@ int omap_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
/* if a shmem backed object, make sure we have pages attached now */
ret = get_pages(obj, &pages);
- if (ret) {
+ if (ret)
goto fail;
- }
/* where should we do corresponding put_pages().. we are mapping
* the original page, rather than thru a GART, so we can't rely
@@ -953,7 +952,7 @@ int omap_gem_put_pages(struct drm_gem_object *obj)
void *omap_gem_vaddr(struct drm_gem_object *obj)
{
struct omap_gem_object *omap_obj = to_omap_bo(obj);
- WARN_ON(! mutex_is_locked(&obj->dev->struct_mutex));
+ WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex));
if (!omap_obj->vaddr) {
struct page **pages;
int ret = get_pages(obj, &pages);
@@ -972,7 +971,7 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
struct omap_gem_object *omap_obj = to_omap_bo(obj);
uint64_t off = 0;
- WARN_ON(! mutex_is_locked(&dev->struct_mutex));
+ WARN_ON(!mutex_is_locked(&dev->struct_mutex));
if (obj->map_list.map)
off = (uint64_t)obj->map_list.hash.key;
@@ -1146,9 +1145,8 @@ int omap_gem_op_sync(struct drm_gem_object *obj, enum omap_gem_op op)
struct omap_gem_sync_waiter *waiter =
kzalloc(sizeof(*waiter), GFP_KERNEL);
- if (!waiter) {
+ if (!waiter)
return -ENOMEM;
- }
waiter->omap_obj = omap_obj;
waiter->op = op;
@@ -1177,9 +1175,8 @@ int omap_gem_op_sync(struct drm_gem_object *obj, enum omap_gem_op op)
}
spin_unlock(&sync_lock);
- if (waiter) {
+ if (waiter)
kfree(waiter);
- }
}
return ret;
}
@@ -1201,9 +1198,8 @@ int omap_gem_op_async(struct drm_gem_object *obj, enum omap_gem_op op,
struct omap_gem_sync_waiter *waiter =
kzalloc(sizeof(*waiter), GFP_ATOMIC);
- if (!waiter) {
+ if (!waiter)
return -ENOMEM;
- }
waiter->omap_obj = omap_obj;
waiter->op = op;
@@ -1285,9 +1281,8 @@ void omap_gem_free_object(struct drm_gem_object *obj)
list_del(&omap_obj->mm_list);
- if (obj->map_list.map) {
+ if (obj->map_list.map)
drm_gem_free_mmap_offset(obj);
- }
/* this means the object is still pinned.. which really should
* not happen. I think..
@@ -1296,9 +1291,9 @@ void omap_gem_free_object(struct drm_gem_object *obj)
/* don't free externally allocated backing memory */
if (!(omap_obj->flags & OMAP_BO_EXT_MEM)) {
- if (omap_obj->pages) {
+ if (omap_obj->pages)
omap_gem_detach_pages(obj);
- }
+
if (!is_shmem(obj)) {
dma_free_writecombine(dev->dev, obj->size,
omap_obj->vaddr, omap_obj->paddr);
@@ -1308,9 +1303,8 @@ void omap_gem_free_object(struct drm_gem_object *obj)
}
/* don't free externally allocated syncobj */
- if (!(omap_obj->flags & OMAP_BO_EXT_SYNC)) {
+ if (!(omap_obj->flags & OMAP_BO_EXT_SYNC))
kfree(omap_obj->sync);
- }
drm_gem_object_release(obj);
@@ -1395,9 +1389,9 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
*/
omap_obj->vaddr = dma_alloc_writecombine(dev->dev, size,
&omap_obj->paddr, GFP_KERNEL);
- if (omap_obj->vaddr) {
+ if (omap_obj->vaddr)
flags |= OMAP_BO_DMA;
- }
+
}
omap_obj->flags = flags;
@@ -1407,22 +1401,20 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
omap_obj->height = gsize.tiled.height;
}
- if (flags & (OMAP_BO_DMA|OMAP_BO_EXT_MEM)) {
+ if (flags & (OMAP_BO_DMA|OMAP_BO_EXT_MEM))
ret = drm_gem_private_object_init(dev, obj, size);
- } else {
+ else
ret = drm_gem_object_init(dev, obj, size);
- }
- if (ret) {
+ if (ret)
goto fail;
- }
return obj;
fail:
- if (obj) {
+ if (obj)
omap_gem_free_object(obj);
- }
+
return NULL;
}
@@ -1435,7 +1427,7 @@ void omap_gem_init(struct drm_device *dev)
};
int i, j;
- if (!dmm_is_initialized()) {
+ if (!dmm_is_available()) {
/* DMM only supported on OMAP4 and later, so this isn't fatal */
dev_warn(dev->dev, "DMM not available, disable DMM support\n");
return;
diff --git a/drivers/staging/omapdrm/omap_gem_dmabuf.c b/drivers/staging/omapdrm/omap_gem_dmabuf.c
index c6f3ef6f57b..9a302062b03 100644
--- a/drivers/staging/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/staging/omapdrm/omap_gem_dmabuf.c
@@ -191,13 +191,13 @@ struct dma_buf_ops omap_dmabuf_ops = {
.mmap = omap_gem_dmabuf_mmap,
};
-struct dma_buf * omap_gem_prime_export(struct drm_device *dev,
+struct dma_buf *omap_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *obj, int flags)
{
return dma_buf_export(obj, &omap_dmabuf_ops, obj->size, 0600);
}
-struct drm_gem_object * omap_gem_prime_import(struct drm_device *dev,
+struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
struct dma_buf *buffer)
{
struct drm_gem_object *obj;
diff --git a/drivers/staging/omapdrm/omap_gem_helpers.c b/drivers/staging/omapdrm/omap_gem_helpers.c
index f895363a5e5..ffb8cceaeb4 100644
--- a/drivers/staging/omapdrm/omap_gem_helpers.c
+++ b/drivers/staging/omapdrm/omap_gem_helpers.c
@@ -32,7 +32,7 @@
* @obj: obj in question
* @gfpmask: gfp mask of requested pages
*/
-struct page ** _drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask)
+struct page **_drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask)
{
struct inode *inode;
struct address_space *mapping;
@@ -80,9 +80,9 @@ struct page ** _drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask)
return pages;
fail:
- while (i--) {
+ while (i--)
page_cache_release(pages[i]);
- }
+
drm_free_large(pages);
return ERR_CAST(p);
}
diff --git a/drivers/staging/omapdrm/omap_plane.c b/drivers/staging/omapdrm/omap_plane.c
index 4bde639dd02..2a8e5bab49c 100644
--- a/drivers/staging/omapdrm/omap_plane.c
+++ b/drivers/staging/omapdrm/omap_plane.c
@@ -416,26 +416,28 @@ void omap_plane_install_properties(struct drm_plane *plane,
struct omap_drm_private *priv = dev->dev_private;
struct drm_property *prop;
- prop = priv->rotation_prop;
- if (!prop) {
- const struct drm_prop_enum_list props[] = {
- { DRM_ROTATE_0, "rotate-0" },
- { DRM_ROTATE_90, "rotate-90" },
- { DRM_ROTATE_180, "rotate-180" },
- { DRM_ROTATE_270, "rotate-270" },
- { DRM_REFLECT_X, "reflect-x" },
- { DRM_REFLECT_Y, "reflect-y" },
- };
- prop = drm_property_create_bitmask(dev, 0, "rotation",
- props, ARRAY_SIZE(props));
- if (prop == NULL)
- return;
- priv->rotation_prop = prop;
+ if (priv->has_dmm) {
+ prop = priv->rotation_prop;
+ if (!prop) {
+ const struct drm_prop_enum_list props[] = {
+ { DRM_ROTATE_0, "rotate-0" },
+ { DRM_ROTATE_90, "rotate-90" },
+ { DRM_ROTATE_180, "rotate-180" },
+ { DRM_ROTATE_270, "rotate-270" },
+ { DRM_REFLECT_X, "reflect-x" },
+ { DRM_REFLECT_Y, "reflect-y" },
+ };
+ prop = drm_property_create_bitmask(dev, 0, "rotation",
+ props, ARRAY_SIZE(props));
+ if (prop == NULL)
+ return;
+ priv->rotation_prop = prop;
+ }
+ drm_object_attach_property(obj, prop, 0);
}
- drm_object_attach_property(obj, prop, 0);
- prop = priv->zorder_prop;
- if (!prop) {
+ prop = priv->zorder_prop;
+ if (!prop) {
prop = drm_property_create_range(dev, 0, "zorder", 0, 3);
if (prop == NULL)
return;
@@ -549,8 +551,8 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
return plane;
fail:
- if (plane) {
+ if (plane)
omap_plane_destroy(plane);
- }
+
return NULL;
}
diff --git a/drivers/staging/ozwpan/ozevent.c b/drivers/staging/ozwpan/ozevent.c
index a48498bd9b5..50578ba0061 100644
--- a/drivers/staging/ozwpan/ozevent.c
+++ b/drivers/staging/ozwpan/ozevent.c
@@ -79,6 +79,7 @@ void oz_event_log2(u8 evt, u8 ctx1, u16 ctx2, void *ctx3, unsigned ctx4)
/*------------------------------------------------------------------------------
* Context: process
*/
+#ifdef CONFIG_DEBUG_FS
static void oz_events_clear(struct oz_evtdev *dev)
{
unsigned long irqstate;
@@ -88,7 +89,6 @@ static void oz_events_clear(struct oz_evtdev *dev)
dev->missed_events = 0;
spin_unlock_irqrestore(&dev->lock, irqstate);
}
-#ifdef CONFIG_DEBUG_FS
/*------------------------------------------------------------------------------
* Context: process
*/
diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c
index 2e087acf157..b2d77df2a52 100644
--- a/drivers/staging/ozwpan/ozhcd.c
+++ b/drivers/staging/ozwpan/ozhcd.c
@@ -278,8 +278,7 @@ static void oz_free_urb_link(struct oz_urb_link *urbl)
g_link_pool_size++;
}
spin_unlock_irqrestore(&g_link_lock, irq_state);
- if (urbl)
- kfree(urbl);
+ kfree(urbl);
}
}
/*------------------------------------------------------------------------------
@@ -2304,8 +2303,8 @@ error:
*/
void oz_hcd_term(void)
{
- tasklet_disable(&g_urb_process_tasklet);
- tasklet_disable(&g_urb_cancel_tasklet);
+ tasklet_kill(&g_urb_process_tasklet);
+ tasklet_kill(&g_urb_cancel_tasklet);
platform_device_unregister(g_plat_dev);
platform_driver_unregister(&g_oz_plat_drv);
oz_trace("Pending urbs:%d\n", atomic_read(&g_pending_urbs));
diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c
index 0b3648ce968..118a4db74de 100644
--- a/drivers/staging/ozwpan/ozpd.c
+++ b/drivers/staging/ozwpan/ozpd.c
@@ -402,8 +402,7 @@ static void oz_tx_frame_free(struct oz_pd *pd, struct oz_tx_frame *f)
f = 0;
}
spin_unlock_bh(&pd->tx_frame_lock);
- if (f)
- kfree(f);
+ kfree(f);
}
/*------------------------------------------------------------------------------
* Context: softirq-serialized
@@ -737,8 +736,7 @@ int oz_isoc_stream_create(struct oz_pd *pd, u8 ep_num)
st = 0;
}
spin_unlock_bh(&pd->stream_lock);
- if (st)
- kfree(st);
+ kfree(st);
return 0;
}
/*------------------------------------------------------------------------------
diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c
index cfb5160d1eb..e00a53915da 100644
--- a/drivers/staging/ozwpan/ozproto.c
+++ b/drivers/staging/ozwpan/ozproto.c
@@ -566,8 +566,7 @@ static void oz_protocol_timer(unsigned long arg)
}
spin_unlock_bh(&g_polling_lock);
oz_pd_put(pd);
- if (t)
- kfree(t);
+ kfree(t);
t = t2;
} while (t);
g_timer_state = OZ_TIMER_IDLE;
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index 6e9f7090c45..e3113ecefef 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -1758,7 +1758,7 @@ static inline int input_state_high(struct logical_input *input)
char *press_str = input->u.kbd.press_str;
if (press_str[0])
keypad_send_key(press_str,
- sizeof(press_str));
+ sizeof(input->u.kbd.press_str));
}
if (input->u.kbd.repeat_str[0]) {
@@ -1766,7 +1766,7 @@ static inline int input_state_high(struct logical_input *input)
if (input->high_timer >= KEYPAD_REP_START) {
input->high_timer -= KEYPAD_REP_DELAY;
keypad_send_key(repeat_str,
- sizeof(repeat_str));
+ sizeof(input->u.kbd.repeat_str));
}
/* we will need to come back here soon */
inputs_stable = 0;
@@ -1805,7 +1805,7 @@ static inline void input_state_falling(struct logical_input *input)
if (input->high_timer >= KEYPAD_REP_START)
input->high_timer -= KEYPAD_REP_DELAY;
keypad_send_key(repeat_str,
- sizeof(repeat_str));
+ sizeof(input->u.kbd.repeat_str));
/* we will need to come back here soon */
inputs_stable = 0;
}
@@ -1824,7 +1824,7 @@ static inline void input_state_falling(struct logical_input *input)
char *release_str = input->u.kbd.release_str;
if (release_str[0])
keypad_send_key(release_str,
- sizeof(release_str));
+ sizeof(input->u.kbd.release_str));
}
input->state = INPUT_ST_LOW;
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
index 5f5a30223d5..8fc9f588b05 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
@@ -1221,7 +1221,7 @@ static inline void *ieee80211_priv(struct net_device *dev)
return ((struct ieee80211_device *)netdev_priv(dev))->priv;
}
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
{
/* Single white space is for Linksys APs */
if (essid_len == 1 && essid[0] == ' ')
@@ -1237,7 +1237,7 @@ extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
return 1;
}
-extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
+static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
{
/*
* It is possible for both access points and our device to support
@@ -1263,7 +1263,7 @@ extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mod
return 0;
}
-extern inline int ieee80211_get_hdrlen(u16 fc)
+static inline int ieee80211_get_hdrlen(u16 fc)
{
int hdrlen = 24;
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
index b3882ae9d97..694eae3d4fd 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
@@ -11,12 +11,14 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
//#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
-#include <asm/string.h>
-#include <asm/errno.h>
+#include <linux/string.h>
+#include <linux/errno.h>
#include "ieee80211.h"
@@ -66,8 +68,7 @@ void ieee80211_crypt_deinit_handler(unsigned long data)
spin_lock_irqsave(&ieee->lock, flags);
ieee80211_crypt_deinit_entries(ieee, 0);
if (!list_empty(&ieee->crypt_deinit_list)) {
- printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
- "deletion list\n", ieee->dev->name);
+ pr_debug("entries remaining in delayed crypt deletion list\n");
ieee->crypt_deinit_timer.expires = jiffies + HZ;
add_timer(&ieee->crypt_deinit_timer);
}
@@ -118,8 +119,7 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
list_add(&alg->list, &hcrypt->algs);
spin_unlock_irqrestore(&hcrypt->lock, flags);
- printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
- ops->name);
+ pr_debug("registered algorithm '%s'\n", ops->name);
return 0;
}
@@ -146,8 +146,7 @@ int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
spin_unlock_irqrestore(&hcrypt->lock, flags);
if (del_alg) {
- printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
- "'%s'\n", ops->name);
+ pr_debug("unregistered algorithm '%s'\n", ops->name);
kfree(del_alg);
}
@@ -155,7 +154,7 @@ int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
}
-struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
+struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
{
unsigned long flags;
struct list_head *ptr;
@@ -182,7 +181,7 @@ struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
}
-static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
+static void *ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
static void ieee80211_crypt_null_deinit(void *priv) {}
static struct ieee80211_crypto_ops ieee80211_crypt_null = {
@@ -234,9 +233,8 @@ void ieee80211_crypto_deinit(void)
alg = list_entry(ptr, struct ieee80211_crypto_alg, list);
if (alg) {
list_del(ptr);
- printk(KERN_DEBUG
- "ieee80211_crypt: unregistered algorithm '%s' (deinit)\n",
- alg->ops->name);
+ pr_debug("unregistered algorithm '%s' (deinit)\n",
+ alg->ops->name);
kfree(alg);
}
}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h
index b58a3bcc0dc..0b4ea431982 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h
@@ -77,7 +77,7 @@ struct ieee80211_crypt_data {
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);
+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,
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
index 6aaaa2fd57f..f5949e89e5c 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
@@ -9,6 +9,8 @@
* more details.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
//#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -18,7 +20,7 @@
#include <linux/netdevice.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
-#include <asm/string.h>
+#include <linux/string.h>
#include <linux/wireless.h>
#include "ieee80211.h"
@@ -64,7 +66,7 @@ void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
crypto_cipher_encrypt_one((void *)tfm, ct, pt);
}
-static void * ieee80211_ccmp_init(int key_idx)
+static void *ieee80211_ccmp_init(int key_idx)
{
struct ieee80211_ccmp_data *priv;
@@ -75,8 +77,7 @@ static void * ieee80211_ccmp_init(int key_idx)
priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tfm)) {
- printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
- "crypto API aes\n");
+ pr_debug("could not allocate crypto API aes\n");
priv->tfm = NULL;
goto fail;
}
@@ -128,7 +129,7 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
/*
qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
(WLAN_FC_GET_STYPE(fc) & 0x08));
- */
+ */
// fixed by David :2006.9.6
qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
(WLAN_FC_GET_STYPE(fc) & 0x80));
@@ -282,23 +283,22 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
keyidx = pos[3];
if (!(keyidx & (1 << 5))) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: received packet without ExtIV"
- " flag from %pM\n", hdr->addr2);
+ pr_debug("received packet without ExtIV flag from %pM\n",
+ hdr->addr2);
}
key->dot11RSNAStatsCCMPFormatErrors++;
return -2;
}
keyidx >>= 6;
if (key->key_idx != keyidx) {
- printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
- "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
+ pr_debug("RX tkey->key_idx=%d frame keyidx=%d priv=%p\n",
+ key->key_idx, keyidx, priv);
return -6;
}
if (!key->key_set) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: received packet from %pM"
- " with keyid=%d that does not have a configured"
- " key\n", hdr->addr2, keyidx);
+ pr_debug("received packet from %pM with keyid=%d that does not have a configured key\n",
+ hdr->addr2, keyidx);
}
return -3;
}
@@ -313,9 +313,8 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
- " previous PN %pm received PN %pm\n",
- hdr->addr2, key->rx_pn, pn);
+ pr_debug("replay detected: STA=%pM previous PN %pm received PN %pm\n",
+ hdr->addr2, key->rx_pn, pn);
}
key->dot11RSNAStatsCCMPReplays++;
return -4;
@@ -341,10 +340,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: decrypt failed: STA="
- "%pM\n", hdr->addr2);
- }
+ if (net_ratelimit())
+ pr_debug("decrypt failed: STA=%pM\n", hdr->addr2);
+
key->dot11RSNAStatsCCMPDecryptErrors++;
return -5;
}
@@ -415,7 +413,7 @@ static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
}
-static char * ieee80211_ccmp_print_stats(char *p, void *priv)
+static char *ieee80211_ccmp_print_stats(char *p, void *priv)
{
struct ieee80211_ccmp_data *ccmp = priv;
p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c
index 58f3eeb2143..bba77141d9a 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c
@@ -9,13 +9,15 @@
* more details.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
//#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/skbuff.h>
-#include <asm/string.h>
+#include <linux/string.h>
#include "ieee80211.h"
@@ -40,7 +42,7 @@ struct prism2_wep_data {
};
-static void * prism2_wep_init(int keyidx)
+static void *prism2_wep_init(int keyidx)
{
struct prism2_wep_data *priv;
@@ -50,15 +52,13 @@ static void * prism2_wep_init(int keyidx)
priv->key_idx = keyidx;
priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tx_tfm)) {
- printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
- "crypto API arc4\n");
+ pr_debug("could not allocate crypto API arc4\n");
priv->tx_tfm = NULL;
goto fail;
}
priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->rx_tfm)) {
- printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
- "crypto API arc4\n");
+ pr_debug("could not allocate crypto API arc4\n");
priv->rx_tfm = NULL;
goto fail;
}
@@ -217,7 +217,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
memmove(skb->data + 4, skb->data, hdr_len);
skb_pull(skb, 4);
skb_trim(skb, skb->len - 4);
- return 0;
+ return 0;
}
@@ -248,7 +248,7 @@ static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
}
-static char * prism2_wep_print_stats(char *p, void *priv)
+static char *prism2_wep_print_stats(char *p, void *priv)
{
struct prism2_wep_data *wep = priv;
p += sprintf(p, "key[%d] alg=WEP len=%d\n",
@@ -289,5 +289,5 @@ void ieee80211_crypto_wep_exit(void)
void ieee80211_wep_null(void)
{
// printk("============>%s()\n", __func__);
- return;
+ return;
}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
index 9422573bfea..4358c4b0ca6 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
@@ -48,7 +48,7 @@
#include <linux/types.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <net/arp.h>
#include <net/net_namespace.h>
@@ -69,8 +69,7 @@ static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
MAX_NETWORK_COUNT, sizeof(struct ieee80211_network),
GFP_KERNEL);
if (!ieee->networks) {
- printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
- ieee->dev->name);
+ netdev_warn(ieee->dev, "Out of memory allocating beacons\n");
return -ENOMEM;
}
@@ -100,7 +99,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
{
struct ieee80211_device *ieee;
struct net_device *dev;
- int i,err;
+ int i, err;
IEEE80211_DEBUG_INFO("Initializing...\n");
@@ -140,11 +139,11 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
spin_lock_init(&ieee->wpax_suitlist_lock);
ieee->wpax_type_set = 0;
- ieee->wpa_enabled = 0;
- ieee->tkip_countermeasures = 0;
- ieee->drop_unencrypted = 0;
- ieee->privacy_invoked = 0;
- ieee->ieee802_1x = 1;
+ ieee->wpa_enabled = 0;
+ ieee->tkip_countermeasures = 0;
+ ieee->drop_unencrypted = 0;
+ ieee->privacy_invoked = 0;
+ ieee->ieee802_1x = 1;
ieee->raw_tx = 0;
ieee80211_softmac_init(ieee);
@@ -153,9 +152,9 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
for (i = 0; i < 17; i++) {
- ieee->last_rxseq_num[i] = -1;
- ieee->last_rxfrag_num[i] = -1;
- ieee->last_packet_time[i] = 0;
+ ieee->last_rxseq_num[i] = -1;
+ ieee->last_rxfrag_num[i] = -1;
+ ieee->last_packet_time[i] = 0;
}
//These function were added to load crypte module autoly
ieee80211_tkip_null();
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
index 3a724496e74..446f15ec639 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
@@ -39,7 +39,7 @@
#include <linux/types.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/ctype.h>
#include "ieee80211.h"
@@ -65,7 +65,7 @@ static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
/* Called only as a tasklet (software IRQ) */
static struct ieee80211_frag_entry *
ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
- unsigned int frag, u8 tid,u8 *src, u8 *dst)
+ unsigned int frag, u8 tid, u8 *src, u8 *dst)
{
struct ieee80211_frag_entry *entry;
int i;
@@ -107,18 +107,18 @@ ieee80211_frag_cache_get(struct ieee80211_device *ieee,
struct ieee80211_hdr_4addrqos *hdr_4addrqos;
u8 tid;
- if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid ++;
+ if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) {
+ hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
+ tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
+ tid = UP2AC(tid);
+ tid++;
} else if (IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid ++;
+ hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
+ tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
+ tid = UP2AC(tid);
+ tid++;
} else {
- tid = 0;
+ tid = 0;
}
if (frag == 0) {
@@ -129,7 +129,7 @@ ieee80211_frag_cache_get(struct ieee80211_device *ieee,
2 /* alignment */ +
8 /* WEP */ +
ETH_ALEN /* WDS */ +
- (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
+ (IEEE80211_QOS_HAS_SEQ(fc) ? 2 : 0) /* QOS Control */);
if (skb == NULL)
return NULL;
@@ -150,7 +150,7 @@ ieee80211_frag_cache_get(struct ieee80211_device *ieee,
} else {
/* received a fragment of a frame for which the head fragment
* should have already been received */
- entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2,
+ entry = ieee80211_frag_cache_find(ieee, seq, frag, tid, hdr->addr2,
hdr->addr1);
if (entry != NULL) {
entry->last_frag = frag;
@@ -174,21 +174,21 @@ static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
struct ieee80211_hdr_4addrqos *hdr_4addrqos;
u8 tid;
- if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid ++;
+ if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) {
+ hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
+ tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
+ tid = UP2AC(tid);
+ tid++;
} else if (IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid ++;
+ hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
+ tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
+ tid = UP2AC(tid);
+ tid++;
} else {
- tid = 0;
+ tid = 0;
}
- entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
+ entry = ieee80211_frag_cache_find(ieee, seq, -1, tid, hdr->addr2,
hdr->addr1);
if (entry == NULL) {
@@ -227,7 +227,7 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
ieee80211_rx_mgt(ieee, (struct ieee80211_hdr_4addr *)skb->data,
rx_stats);
- if((ieee->state == IEEE80211_LINKED)&&(memcmp(hdr->addr3,ieee->current_network.bssid,ETH_ALEN))) {
+ if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN))) {
dev_kfree_skb_any(skb);
return 0;
}
@@ -244,11 +244,9 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
-static unsigned char rfc1042_header[] =
-{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+static unsigned char rfc1042_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
-static unsigned char bridge_tunnel_header[] =
-{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
+static unsigned char bridge_tunnel_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
/* No encapsulation header if EtherType < 0x600 (=length) */
/* Called by ieee80211_rx_frame_decrypt */
@@ -294,7 +292,7 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
/* Called only as a tasklet (software IRQ), by ieee80211_rx */
static inline int
-ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
+ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_crypt_data *crypt)
{
struct ieee80211_hdr_4addr *hdr;
@@ -310,9 +308,9 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
if (ieee->tkip_countermeasures &&
strcmp(crypt->ops->name, "TKIP") == 0) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "received packet from %pM\n",
- ieee->dev->name, hdr->addr2);
+ netdev_dbg(ieee->dev,
+ "TKIP countermeasures: dropped received packet from %pM\n",
+ ieee->dev->name, hdr->addr2);
}
return -1;
}
@@ -339,7 +337,7 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
/* Called only as a tasklet (software IRQ), by ieee80211_rx */
static inline int
-ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
+ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, struct sk_buff *skb,
int keyidx, struct ieee80211_crypt_data *crypt)
{
struct ieee80211_hdr_4addr *hdr;
@@ -355,9 +353,9 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
atomic_dec(&crypt->refcnt);
if (res < 0) {
- printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
- " (SA=%pM keyidx=%d)\n",
- ieee->dev->name, hdr->addr2, keyidx);
+ netdev_dbg(ieee->dev,
+ "MSDU decryption/MIC verification failed (SA=%pM keyidx=%d)\n",
+ hdr->addr2, keyidx);
return -1;
}
@@ -381,18 +379,18 @@ static int is_duplicate_packet(struct ieee80211_device *ieee,
u8 tid;
//TO2DS and QoS
- if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)header;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid ++;
- } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
- hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)header;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid ++;
+ if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) {
+ hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)header;
+ tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
+ tid = UP2AC(tid);
+ tid++;
+ } else if (IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
+ hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)header;
+ tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
+ tid = UP2AC(tid);
+ tid++;
} else { // no QoS
- tid = 0;
+ tid = 0;
}
switch (ieee->iw_mode) {
case IW_MODE_ADHOC:
@@ -411,7 +409,8 @@ static int is_duplicate_packet(struct ieee80211_device *ieee,
if (p == &ieee->ibss_mac_hash[index]) {
entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
if (!entry) {
- printk(KERN_WARNING "Cannot malloc new mac entry\n");
+ netdev_warn(ieee->dev,
+ "Cannot malloc new mac entry\n");
return 0;
}
memcpy(entry->mac, mac, ETH_ALEN);
@@ -442,7 +441,7 @@ static int is_duplicate_packet(struct ieee80211_device *ieee,
// }
if ((*last_seq == seq) &&
time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
- if (*last_frag == frag){
+ if (*last_frag == frag) {
//printk(KERN_WARNING "[1] go drop!\n");
goto drop;
@@ -493,8 +492,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
stats = &ieee->stats;
if (skb->len < 10) {
- printk(KERN_INFO "%s: SKB length < 10\n",
- dev->name);
+ netdev_info(ieee->dev, "SKB length < 10\n");
goto rx_dropped;
}
@@ -506,19 +504,12 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
frag = WLAN_GET_SEQ_FRAG(sc);
//YJ,add,080828,for keep alive
- if((fc & IEEE80211_FCTL_TODS) != IEEE80211_FCTL_TODS)
- {
- if(!memcmp(hdr->addr1,dev->dev_addr, ETH_ALEN))
- {
+ if ((fc & IEEE80211_FCTL_TODS) != IEEE80211_FCTL_TODS) {
+ if (!memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN))
ieee->NumRxUnicast++;
- }
- }
- else
- {
- if(!memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN))
- {
+ } else {
+ if (!memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN))
ieee->NumRxUnicast++;
- }
}
//YJ,add,080828,for keep alive,end
@@ -577,12 +568,12 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
case IEEE80211_FCTL_FROMDS:
memcpy(dst, hdr->addr1, ETH_ALEN);
memcpy(src, hdr->addr3, ETH_ALEN);
- memcpy(bssid,hdr->addr2,ETH_ALEN);
+ memcpy(bssid, hdr->addr2, ETH_ALEN);
break;
case IEEE80211_FCTL_TODS:
memcpy(dst, hdr->addr3, ETH_ALEN);
memcpy(src, hdr->addr2, ETH_ALEN);
- memcpy(bssid,hdr->addr1,ETH_ALEN);
+ memcpy(bssid, hdr->addr1, ETH_ALEN);
break;
case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
if (skb->len < IEEE80211_DATA_HDR4_LEN)
@@ -594,7 +585,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
case 0:
memcpy(dst, hdr->addr1, ETH_ALEN);
memcpy(src, hdr->addr2, ETH_ALEN);
- memcpy(bssid,hdr->addr3,ETH_ALEN);
+ memcpy(bssid, hdr->addr3, ETH_ALEN);
break;
}
@@ -607,7 +598,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
if (stype != IEEE80211_STYPE_DATA &&
stype != IEEE80211_STYPE_DATA_CFACK &&
stype != IEEE80211_STYPE_DATA_CFPOLL &&
- stype != IEEE80211_STYPE_DATA_CFACKPOLL&&
+ stype != IEEE80211_STYPE_DATA_CFACKPOLL &&
stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
) {
if (stype != IEEE80211_STYPE_NULLFUNC)
@@ -618,9 +609,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
type, stype, skb->len);
goto rx_dropped;
}
- if(memcmp(bssid,ieee->current_network.bssid,ETH_ALEN)) {
+ if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN))
goto rx_dropped;
- }
ieee->NumRxDataInPeriod++;
ieee->NumRxOkTotal++;
@@ -653,9 +643,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
flen -= hdrlen;
if (frag_skb->tail + flen > frag_skb->end) {
- printk(KERN_WARNING "%s: host decrypted and "
- "reassembled frame did not fit skb\n",
- dev->name);
+ netdev_warn(ieee->dev,
+ "host decrypted and reassembled frame did not fit skb\n");
ieee80211_frag_cache_invalidate(ieee, hdr);
goto rx_dropped;
}
@@ -804,7 +793,7 @@ static inline int ieee80211_is_ofdm_rate(u8 rate)
case IEEE80211_OFDM_RATE_54MB:
return 1;
}
- return 0;
+ return 0;
}
static inline int ieee80211_SignalStrengthTranslate(
@@ -814,46 +803,27 @@ static inline int ieee80211_SignalStrengthTranslate(
int RetSS;
// Step 1. Scale mapping.
- if(CurrSS >= 71 && CurrSS <= 100)
- {
+ if (CurrSS >= 71 && CurrSS <= 100)
RetSS = 90 + ((CurrSS - 70) / 3);
- }
- else if(CurrSS >= 41 && CurrSS <= 70)
- {
+ else if (CurrSS >= 41 && CurrSS <= 70)
RetSS = 78 + ((CurrSS - 40) / 3);
- }
- else if(CurrSS >= 31 && CurrSS <= 40)
- {
+ else if (CurrSS >= 31 && CurrSS <= 40)
RetSS = 66 + (CurrSS - 30);
- }
- else if(CurrSS >= 21 && CurrSS <= 30)
- {
+ else if (CurrSS >= 21 && CurrSS <= 30)
RetSS = 54 + (CurrSS - 20);
- }
- else if(CurrSS >= 5 && CurrSS <= 20)
- {
+ else if (CurrSS >= 5 && CurrSS <= 20)
RetSS = 42 + (((CurrSS - 5) * 2) / 3);
- }
- else if(CurrSS == 4)
- {
+ else if (CurrSS == 4)
RetSS = 36;
- }
- else if(CurrSS == 3)
- {
+ else if (CurrSS == 3)
RetSS = 27;
- }
- else if(CurrSS == 2)
- {
+ else if (CurrSS == 2)
RetSS = 18;
- }
- else if(CurrSS == 1)
- {
+ else if (CurrSS == 1)
RetSS = 9;
- }
else
- {
RetSS = CurrSS;
- }
+
//RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
// Step 2. Smoothing.
@@ -867,20 +837,16 @@ static inline void ieee80211_extract_country_ie(
struct ieee80211_device *ieee,
struct ieee80211_info_element *info_element,
struct ieee80211_network *network,
- u8 * addr2
+ u8 *addr2
)
{
- if(IS_DOT11D_ENABLE(ieee))
- {
- if(info_element->len!= 0)
- {
+ if (IS_DOT11D_ENABLE(ieee)) {
+ if (info_element->len != 0) {
memcpy(network->CountryIeBuf, info_element->data, info_element->len);
network->CountryIeLen = info_element->len;
- if(!IS_COUNTRY_IE_VALID(ieee))
- {
+ if (!IS_COUNTRY_IE_VALID(ieee))
Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
- }
}
//
@@ -888,10 +854,8 @@ static inline void ieee80211_extract_country_ie(
// some AP (e.g. Cisco 1242) don't include country IE in their
// probe response frame.
//
- if(IS_EQUAL_CIE_SRC(ieee, addr2) )
- {
+ if (IS_EQUAL_CIE_SRC(ieee, addr2))
UPDATE_CIE_WATCHDOG(ieee);
- }
}
}
@@ -920,10 +884,10 @@ inline int ieee80211_network_init(
char *p;
#endif
struct ieee80211_info_element *info_element;
- u16 left;
+ u16 left;
u8 i;
short offset;
- u8 curRate = 0,hOpRate = 0,curRate_ex = 0;
+ u8 curRate = 0, hOpRate = 0, curRate_ex = 0;
/* Pull out fixed field data */
memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
@@ -953,10 +917,10 @@ inline int ieee80211_network_init(
} else
network->flags |= NETWORK_HAS_CCK;
- network->wpa_ie_len = 0;
- network->rsn_ie_len = 0;
+ network->wpa_ie_len = 0;
+ network->rsn_ie_len = 0;
- info_element = &beacon->info_element;
+ info_element = &beacon->info_element;
left = stats->len - ((void *)info_element - (void *)beacon);
while (left >= sizeof(struct ieee80211_info_element_hdr)) {
if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
@@ -964,7 +928,7 @@ inline int ieee80211_network_init(
info_element->len + sizeof(struct ieee80211_info_element),
left);
return 1;
- }
+ }
switch (info_element->id) {
case MFIE_TYPE_SSID:
@@ -977,8 +941,8 @@ inline int ieee80211_network_init(
network->ssid_len = min(info_element->len,
(u8)IW_ESSID_MAX_SIZE);
memcpy(network->ssid, info_element->data, network->ssid_len);
- if (network->ssid_len < IW_ESSID_MAX_SIZE)
- memset(network->ssid + network->ssid_len, 0,
+ if (network->ssid_len < IW_ESSID_MAX_SIZE)
+ memset(network->ssid + network->ssid_len, 0,
IW_ESSID_MAX_SIZE - network->ssid_len);
IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
@@ -993,7 +957,7 @@ inline int ieee80211_network_init(
for (i = 0; i < network->rates_len; i++) {
network->rates[i] = info_element->data[i];
curRate = network->rates[i] & 0x7f;
- if( hOpRate < curRate )
+ if (hOpRate < curRate)
hOpRate = curRate;
#ifdef CONFIG_IEEE80211_DEBUG
p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
@@ -1019,7 +983,7 @@ inline int ieee80211_network_init(
for (i = 0; i < network->rates_ex_len; i++) {
network->rates_ex[i] = info_element->data[i];
curRate_ex = network->rates_ex[i] & 0x7f;
- if( hOpRate < curRate_ex )
+ if (hOpRate < curRate_ex)
hOpRate = curRate_ex;
#ifdef CONFIG_IEEE80211_DEBUG
p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
@@ -1038,14 +1002,14 @@ inline int ieee80211_network_init(
break;
case MFIE_TYPE_DS_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
+ IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
info_element->data[0]);
if (stats->freq == IEEE80211_24GHZ_BAND)
network->channel = info_element->data[0];
break;
- case MFIE_TYPE_FH_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
+ case MFIE_TYPE_FH_SET:
+ IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
break;
case MFIE_TYPE_CF_SET:
@@ -1054,12 +1018,12 @@ inline int ieee80211_network_init(
case MFIE_TYPE_TIM:
- if(info_element->len < 4)
+ if (info_element->len < 4)
break;
network->dtim_period = info_element->data[1];
- if(ieee->state != IEEE80211_LINKED)
+ if (ieee->state != IEEE80211_LINKED)
break;
network->last_dtim_sta_time[0] = jiffies;
@@ -1067,10 +1031,10 @@ inline int ieee80211_network_init(
network->dtim_data = IEEE80211_DTIM_VALID;
- if(info_element->data[0] != 0)
+ if (info_element->data[0] != 0)
break;
- if(info_element->data[2] & 1)
+ if (info_element->data[2] & 1)
network->dtim_data |= IEEE80211_DTIM_MBCAST;
offset = (info_element->data[2] >> 1)*2;
@@ -1078,8 +1042,8 @@ inline int ieee80211_network_init(
//printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
/* add and modified for ps 2008.1.22 */
- if(ieee->assoc_id < 8*offset ||
- ieee->assoc_id > 8*(offset + info_element->len -3)) {
+ if (ieee->assoc_id < 8*offset ||
+ ieee->assoc_id > 8*(offset + info_element->len - 3)) {
break;
}
@@ -1089,9 +1053,9 @@ inline int ieee80211_network_init(
// info_element->data[3+offset] ,
// info_element->data[3+offset] & (1<<(ieee->assoc_id%8)));
- if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8))) {
+ if (info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
network->dtim_data |= IEEE80211_DTIM_UCAST;
- }
+
break;
case MFIE_TYPE_IBSS_SET:
@@ -1125,9 +1089,8 @@ inline int ieee80211_network_init(
info_element->data[4] == 0x02) {
network->Turbo_Enable = 1;
}
- if (1 == stats->nic_type) {//nic 87
+ if (1 == stats->nic_type) //nic 87
break;
- }
if (info_element->len >= 5 &&
info_element->data[0] == 0x00 &&
@@ -1152,7 +1115,7 @@ inline int ieee80211_network_init(
//printk(KERN_WARNING "wmm info&param updated: %x\n", info_element->data[6]);
network->wmm_info = info_element->data[6];
//WMM Parameter Element
- memcpy(network->wmm_param, (u8 *)(info_element->data + 8),(info_element->len - 8));
+ memcpy(network->wmm_param, (u8 *)(info_element->data + 8), (info_element->len - 8));
network->QoS_Enable = 1;
}
break;
@@ -1174,14 +1137,14 @@ inline int ieee80211_network_init(
default:
IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
info_element->id);
- break;
- }
+ break;
+ }
left -= sizeof(struct ieee80211_info_element_hdr) +
info_element->len;
info_element = (struct ieee80211_info_element *)
- &info_element->data[info_element->len];
- }
+ &info_element->data[info_element->len];
+ }
//by amy 080312
network->HighestOperaRate = hOpRate;
//by amy 080312
@@ -1217,7 +1180,7 @@ inline int ieee80211_network_init(
static inline int is_same_network(struct ieee80211_network *src,
struct ieee80211_network *dst,
- struct ieee80211_device * ieee)
+ struct ieee80211_device *ieee)
{
/* A network is only a duplicate if the channel, BSSID, ESSID
* and the capability field (in particular IBSS and BSS) all match.
@@ -1241,12 +1204,11 @@ inline void update_network(struct ieee80211_network *dst,
unsigned char quality = src->stats.signalstrength;
unsigned char signal = 0;
unsigned char noise = 0;
- if(dst->stats.signalstrength > 0) {
- quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6;
- }
+ if (dst->stats.signalstrength > 0)
+ quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6;
signal = ieee80211_TranslateToDbm(quality);
//noise = signal - src->stats.noise;
- if(dst->stats.noise > 0)
+ if (dst->stats.noise > 0)
noise = (dst->stats.noise * 5 + src->stats.noise)/6;
//if(strcmp(dst->ssid, "linksys_lzm000") == 0)
// printk("ssid:%s, quality:%d, signal:%d\n", dst->ssid, quality, signal);
@@ -1262,12 +1224,11 @@ inline void update_network(struct ieee80211_network *dst,
dst->rates_len = src->rates_len;
memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
dst->rates_ex_len = src->rates_ex_len;
- dst->HighestOperaRate= src->HighestOperaRate;
+ dst->HighestOperaRate = src->HighestOperaRate;
//printk("==========>in %s: src->ssid is %s,chan is %d\n",__func__,src->ssid,src->channel);
//YJ,add,080819,for hidden ap
- if(src->ssid_len > 0)
- {
+ if (src->ssid_len > 0) {
//if(src->ssid_len == 13)
// printk("=====================>>>>>>>> Dst ssid: %s Src ssid: %s\n", dst->ssid, src->ssid);
memset(dst->ssid, 0, dst->ssid_len);
@@ -1305,11 +1266,11 @@ inline void update_network(struct ieee80211_network *dst,
memcpy(dst->wmm_param, src->wmm_param, IEEE80211_AC_PRAM_LEN);
}
*/
- if(src->wmm_param[0].ac_aci_acm_aifsn|| \
- src->wmm_param[1].ac_aci_acm_aifsn|| \
- src->wmm_param[2].ac_aci_acm_aifsn|| \
+ if (src->wmm_param[0].ac_aci_acm_aifsn || \
+ src->wmm_param[1].ac_aci_acm_aifsn || \
+ src->wmm_param[2].ac_aci_acm_aifsn || \
src->wmm_param[3].ac_aci_acm_aifsn) {
- memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
+ memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
}
dst->QoS_Enable = src->QoS_Enable;
#else
@@ -1336,7 +1297,7 @@ inline void ieee80211_process_probe_response(
unsigned long flags;
short renew;
u8 wmm_info;
- u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)? 1:0; //YJ,add,080819,for hidden ap
+ u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON) ? 1 : 0; //YJ,add,080819,for hidden ap
memset(&network, 0, sizeof(struct ieee80211_network));
@@ -1378,48 +1339,36 @@ inline void ieee80211_process_probe_response(
// (2) If there is no any country code in beacon,
// then wireless adapter should do active scan from ch1~11 and
// passive scan from ch12~14
- if(ieee->bGlobalDomain)
- {
- if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
- {
+ if (ieee->bGlobalDomain) {
+ if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP) {
// Case 1: Country code
- if(IS_COUNTRY_IE_VALID(ieee) )
- {
- if( !IsLegalChannel(ieee, network.channel) )
- {
+ if (IS_COUNTRY_IE_VALID(ieee)) {
+ if (!IsLegalChannel(ieee, network.channel)) {
printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
return;
}
}
// Case 2: No any country code.
- else
- {
+ else {
// Filter over channel ch12~14
- if(network.channel > 11)
- {
+ if (network.channel > 11) {
printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
return;
}
}
- }
- else
- {
+ } else {
// Case 1: Country code
- if(IS_COUNTRY_IE_VALID(ieee) )
- {
- if( !IsLegalChannel(ieee, network.channel) )
- {
- printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel);
+ if (IS_COUNTRY_IE_VALID(ieee)) {
+ if (!IsLegalChannel(ieee, network.channel)) {
+ printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n", network.channel);
return;
}
}
// Case 2: No any country code.
- else
- {
+ else {
// Filter over channel ch12~14
- if(network.channel > 14)
- {
- printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel);
+ if (network.channel > 14) {
+ printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n", network.channel);
return;
}
}
@@ -1437,12 +1386,12 @@ inline void ieee80211_process_probe_response(
spin_lock_irqsave(&ieee->lock, flags);
- if(is_same_network(&ieee->current_network, &network, ieee)) {
+ if (is_same_network(&ieee->current_network, &network, ieee)) {
wmm_info = ieee->current_network.wmm_info;
//YJ,add,080819,for hidden ap
- if(is_beacon == 0)
+ if (is_beacon == 0)
network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
- else if(ieee->state == IEEE80211_LINKED)
+ else if (ieee->state == IEEE80211_LINKED)
ieee->NumRxBcnInPeriod++;
//YJ,add,080819,for hidden ap,end
//printk("====>network.ssid=%s cur_ssid=%s\n", network.ssid, ieee->current_network.ssid);
@@ -1504,13 +1453,13 @@ inline void ieee80211_process_probe_response(
*/
renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
//YJ,add,080819,for hidden ap
- if(is_beacon == 0)
+ if (is_beacon == 0)
network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
//if(strncmp(network.ssid, "linksys-c",9) == 0)
// printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
- if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
+ if (((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
&& (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
- ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK))))
+ || ((ieee->current_network.ssid_len == network.ssid_len) && (strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0) && (ieee->state == IEEE80211_NOLINK))))
renew = 1;
//YJ,add,080819,for hidden ap,end
update_network(target, &network);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
index 1ef8fd61273..d9add5305e2 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
@@ -32,11 +32,11 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info
union iwreq_data *wrqu, char *b)
{
int ret;
- struct iw_freq *fwrq = & wrqu->freq;
+ struct iw_freq *fwrq = &wrqu->freq;
// printk("in %s\n",__func__);
down(&ieee->wx_sem);
- if(ieee->iw_mode == IW_MODE_INFRA){
+ if (ieee->iw_mode == IW_MODE_INFRA) {
ret = -EOPNOTSUPP;
goto out;
}
@@ -57,21 +57,20 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info
}
}
- if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){
+ if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1) {
ret = -EOPNOTSUPP;
goto out;
- }else { /* Set the channel */
+ } else { /* Set the channel */
ieee->current_network.channel = fwrq->m;
ieee->set_chan(ieee->dev, ieee->current_network.channel);
- if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
- if(ieee->state == IEEE80211_LINKED){
-
- ieee80211_stop_send_beacons(ieee);
- ieee80211_start_send_beacons(ieee);
+ if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
+ if (ieee->state == IEEE80211_LINKED) {
+ ieee80211_stop_send_beacons(ieee);
+ ieee80211_start_send_beacons(ieee);
}
}
@@ -86,7 +85,7 @@ int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
- struct iw_freq *fwrq = & wrqu->freq;
+ struct iw_freq *fwrq = &wrqu->freq;
if (ieee->current_network.channel == 0)
return -1;
@@ -143,12 +142,12 @@ int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
down(&ieee->wx_sem);
/* use ifconfig hw ether */
- if (ieee->iw_mode == IW_MODE_MASTER){
+ if (ieee->iw_mode == IW_MODE_MASTER) {
ret = -1;
goto out;
}
- if (temp->sa_family != ARPHRD_ETHER){
+ if (temp->sa_family != ARPHRD_ETHER) {
ret = -EINVAL;
goto out;
}
@@ -175,9 +174,10 @@ out:
return ret;
}
- int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b)
+int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,
+ union iwreq_data *wrqu, char *b)
{
- int len,ret = 0;
+ int len, ret = 0;
unsigned long flags;
if (ieee->iw_mode == IW_MODE_MONITOR)
@@ -200,7 +200,7 @@ out:
}
len = ieee->current_network.ssid_len;
wrqu->essid.length = len;
- strncpy(b,ieee->current_network.ssid,len);
+ strncpy(b, ieee->current_network.ssid, len);
wrqu->essid.flags = 1;
out:
@@ -218,11 +218,11 @@ int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
u32 target_rate = wrqu->bitrate.value;
//added by lizhaoming for auto mode
- if(target_rate == -1){
- ieee->rate = 110;
- } else {
- ieee->rate = target_rate/100000;
- }
+ if (target_rate == -1)
+ ieee->rate = 110;
+ else
+ ieee->rate = target_rate/100000;
+
//FIXME: we might want to limit rate also in management protocols.
return 0;
}
@@ -250,16 +250,14 @@ int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info
if (wrqu->mode == ieee->iw_mode)
goto out;
- if (wrqu->mode == IW_MODE_MONITOR){
-
+ if (wrqu->mode == IW_MODE_MONITOR)
ieee->dev->type = ARPHRD_IEEE80211;
- }else{
+ else
ieee->dev->type = ARPHRD_ETHER;
- }
- if (!ieee->proto_started){
+ if (!ieee->proto_started) {
ieee->iw_mode = wrqu->mode;
- }else{
+ } else {
ieee80211_stop_protocol(ieee);
ieee->iw_mode = wrqu->mode;
ieee80211_start_protocol(ieee);
@@ -296,7 +294,7 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work)
if (ieee->data_hard_resume)
ieee->data_hard_resume(ieee->dev);
- if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
+ if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
ieee80211_start_send_beacons(ieee);
//YJ,add,080828, In prevent of lossing ping packet during scanning
@@ -314,7 +312,7 @@ int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info
down(&ieee->wx_sem);
- if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){
+ if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)) {
ret = -1;
goto out;
}
@@ -323,7 +321,7 @@ int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info
//ieee80211_sta_ps_send_null_frame(ieee, true);
//YJ,add,080828,end
- if ( ieee->state == IEEE80211_LINKED){
+ if (ieee->state == IEEE80211_LINKED) {
queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
/* intentionally forget to up sem */
return 0;
@@ -339,7 +337,7 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
union iwreq_data *wrqu, char *extra)
{
- int ret=0,len;
+ int ret = 0, len;
short proto_started;
unsigned long flags;
@@ -349,17 +347,17 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
proto_started = ieee->proto_started;
- if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
- ret= -E2BIG;
+ if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
+ ret = -E2BIG;
goto out;
}
- if (ieee->iw_mode == IW_MODE_MONITOR){
- ret= -1;
+ if (ieee->iw_mode == IW_MODE_MONITOR) {
+ ret = -1;
goto out;
}
- if(proto_started)
+ if (proto_started)
ieee80211_stop_protocol(ieee);
/* this is just to be sure that the GET wx callback
@@ -377,13 +375,12 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
//YJ,modified,080819,end
//YJ,add,080819,for hidden ap
- if(len == 0){
+ if (len == 0) {
memset(ieee->current_network.bssid, 0, ETH_ALEN);
ieee->current_network.capability = 0;
}
//YJ,add,080819,for hidden ap,end
- }
- else{
+ } else {
ieee->ssid_set = 0;
ieee->current_network.ssid[0] = '\0';
ieee->current_network.ssid_len = 0;
@@ -398,7 +395,7 @@ out:
return ret;
}
- int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
+int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
@@ -406,7 +403,7 @@ out:
return 0;
}
- int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
+int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
@@ -417,24 +414,23 @@ out:
down(&ieee->wx_sem);
- if(enable)
+ if (enable)
ieee->raw_tx = 1;
else
ieee->raw_tx = 0;
- printk(KERN_INFO"raw TX is %s\n",
- ieee->raw_tx ? "enabled" : "disabled");
+ netdev_info(ieee->dev, "raw TX is %s\n",
+ ieee->raw_tx ? "enabled" : "disabled");
- if(ieee->iw_mode == IW_MODE_MONITOR)
- {
- if(prev == 0 && ieee->raw_tx){
+ if (ieee->iw_mode == IW_MODE_MONITOR) {
+ if (prev == 0 && ieee->raw_tx) {
if (ieee->data_hard_resume)
ieee->data_hard_resume(ieee->dev);
netif_carrier_on(ieee->dev);
}
- if(prev && ieee->raw_tx == 1)
+ if (prev && ieee->raw_tx == 1)
netif_carrier_off(ieee->dev);
}
@@ -448,18 +444,18 @@ int ieee80211_wx_get_name(struct ieee80211_device *ieee,
union iwreq_data *wrqu, char *extra)
{
strlcpy(wrqu->name, "802.11", IFNAMSIZ);
- if(ieee->modulation & IEEE80211_CCK_MODULATION){
+ if (ieee->modulation & IEEE80211_CCK_MODULATION) {
strlcat(wrqu->name, "b", IFNAMSIZ);
- if(ieee->modulation & IEEE80211_OFDM_MODULATION)
+ if (ieee->modulation & IEEE80211_OFDM_MODULATION)
strlcat(wrqu->name, "/g", IFNAMSIZ);
- }else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
+ } else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
strlcat(wrqu->name, "g", IFNAMSIZ);
- if((ieee->state == IEEE80211_LINKED) ||
+ if ((ieee->state == IEEE80211_LINKED) ||
(ieee->state == IEEE80211_LINKED_SCANNING))
- strlcat(wrqu->name," link", IFNAMSIZ);
- else if(ieee->state != IEEE80211_NOLINK)
- strlcat(wrqu->name," .....", IFNAMSIZ);
+ strlcat(wrqu->name, " link", IFNAMSIZ);
+ else if (ieee->state != IEEE80211_NOLINK)
+ strlcat(wrqu->name, " .....", IFNAMSIZ);
return 0;
@@ -473,11 +469,10 @@ int ieee80211_wx_set_power(struct ieee80211_device *ieee,
{
int ret = 0;
- if(
- (!ieee->sta_wake_up) ||
- (!ieee->ps_request_tx_ack) ||
- (!ieee->enter_sleep_state) ||
- (!ieee->ps_is_queue_empty)){
+ if ((!ieee->sta_wake_up) ||
+ (!ieee->ps_request_tx_ack) ||
+ (!ieee->enter_sleep_state) ||
+ (!ieee->ps_is_queue_empty)) {
printk("ERROR. PS mode tried to be use but driver missed a callback\n\n");
@@ -486,7 +481,7 @@ int ieee80211_wx_set_power(struct ieee80211_device *ieee,
down(&ieee->wx_sem);
- if (wrqu->power.disabled){
+ if (wrqu->power.disabled) {
ieee->ps = IEEE80211_PS_DISABLED;
goto exit;
@@ -512,7 +507,7 @@ int ieee80211_wx_set_power(struct ieee80211_device *ieee,
if (wrqu->power.flags & IW_POWER_TIMEOUT) {
ieee->ps_timeout = wrqu->power.value / 1000;
- printk("Timeout %d\n",ieee->ps_timeout);
+ printk("Timeout %d\n", ieee->ps_timeout);
}
if (wrqu->power.flags & IW_POWER_PERIOD) {
@@ -533,11 +528,11 @@ int ieee80211_wx_get_power(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
- int ret =0;
+ int ret = 0;
down(&ieee->wx_sem);
- if(ieee->ps == IEEE80211_PS_DISABLED){
+ if (ieee->ps == IEEE80211_PS_DISABLED) {
wrqu->power.disabled = 1;
goto exit;
}
diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h
index 2682afbac4f..70ea4145b4c 100644
--- a/drivers/staging/rtl8187se/r8180.h
+++ b/drivers/staging/rtl8187se/r8180.h
@@ -327,12 +327,8 @@ typedef struct r8180_priv
int irq;
struct ieee80211_device *ieee80211;
- short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */
- short enable_gpio0;
- short hw_plcp_len;
short plcp_preamble_mode; // 0:auto 1:short 2:long
- spinlock_t irq_lock;
spinlock_t irq_th_lock;
spinlock_t tx_lock;
spinlock_t ps_lock;
@@ -350,7 +346,6 @@ typedef struct r8180_priv
u8 channel_plan; // it's the channel plan index
short up;
short crcmon; //if 1 allow bad crc frame reception in monitor mode
- short prism_hdr;
struct timer_list scan_timer;
/*short scanpending;
@@ -359,14 +354,11 @@ typedef struct r8180_priv
u8 active_probe;
//u8 active_scan_num;
struct semaphore wx_sem;
- struct semaphore rf_state;
short hw_wep;
short digphy;
short antb;
short diversity;
- u8 cs_treshold;
- short rcr_csense;
u32 key0[4];
short (*rf_set_sens)(struct net_device *dev,short sens);
void (*rf_set_chan)(struct net_device *dev,short ch);
@@ -491,7 +483,6 @@ typedef struct r8180_priv
RT_RF_POWER_STATE eRFPowerState;
u32 RfOffReason;
bool RFChangeInProgress;
- bool bInHctTest;
bool SetRFPowerStateInProgress;
u8 RFProgType;
bool bLeisurePs;
@@ -618,17 +609,11 @@ typedef struct r8180_priv
// struct workqueue_struct *workqueue;
struct work_struct reset_wq;
struct work_struct watch_dog_wq;
- struct work_struct tx_irq_wq;
short ack_tx_to_ieee;
- u8 PowerProfile;
- u32 CSMethod;
- u8 cck_txpwr_base;
- u8 ofdm_txpwr_base;
u8 dma_poll_stop_mask;
//u8 RegThreeWireMode;
- u8 MWIEnable;
u16 ShortRetryLimit;
u16 LongRetryLimit;
u16 EarlyRxThreshold;
@@ -667,35 +652,22 @@ void write_nic_dword(struct net_device *dev, int x,u32 y);
void force_pci_posting(struct net_device *dev);
void rtl8180_rtx_disable(struct net_device *);
-void rtl8180_rx_enable(struct net_device *);
-void rtl8180_tx_enable(struct net_device *);
-void rtl8180_start_scanning(struct net_device *dev);
-void rtl8180_start_scanning_s(struct net_device *dev);
-void rtl8180_stop_scanning(struct net_device *dev);
-void rtl8180_disassociate(struct net_device *dev);
-//void fix_rx_fifo(struct net_device *dev);
void rtl8180_set_anaparam(struct net_device *dev,u32 a);
void rtl8185_set_anaparam2(struct net_device *dev,u32 a);
void rtl8180_set_hw_wep(struct net_device *dev);
void rtl8180_no_hw_wep(struct net_device *dev);
void rtl8180_update_msr(struct net_device *dev);
-//void rtl8180_BSS_create(struct net_device *dev);
void rtl8180_beacon_tx_disable(struct net_device *dev);
void rtl8180_beacon_rx_disable(struct net_device *dev);
-void rtl8180_conttx_enable(struct net_device *dev);
-void rtl8180_conttx_disable(struct net_device *dev);
int rtl8180_down(struct net_device *dev);
int rtl8180_up(struct net_device *dev);
void rtl8180_commit(struct net_device *dev);
void rtl8180_set_chan(struct net_device *dev,short ch);
-void rtl8180_set_master_essid(struct net_device *dev,char *essid);
-void rtl8180_update_beacon_security(struct net_device *dev);
void write_phy(struct net_device *dev, u8 adr, u8 data);
void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
void rtl8185_rf_pins_enable(struct net_device *dev);
-void IBSS_randomize_cell(struct net_device *dev);
void IPSEnter(struct net_device *dev);
void IPSLeave(struct net_device *dev);
int get_curr_tx_free_desc(struct net_device *dev, int priority);
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index 20e5fb58f52..ae38475854b 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -27,6 +27,8 @@
Written by Mariusz Matuszek.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#undef RX_DONT_PASS_UL
#undef DUMMY_RX
@@ -44,7 +46,7 @@
#include "ieee80211/dot11d.h"
-static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = {
+static struct pci_device_id rtl8180_pci_id_tbl[] = {
{
.vendor = PCI_VENDOR_ID_REALTEK,
.device = 0x8199,
@@ -61,33 +63,23 @@ static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = {
}
};
-
static char ifname[IFNAMSIZ] = "wlan%d";
-static int hwseqnum = 0;
-static int hwwep = 0;
-static int channels = 0x3fff;
+static int hwwep;
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, rtl8180_pci_id_tbl);
MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
-MODULE_DESCRIPTION("Linux driver for Realtek RTL8180 / RTL8185 WiFi cards");
-
+MODULE_DESCRIPTION("Linux driver for Realtek RTL8187SE WiFi cards");
module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR);
-module_param(hwseqnum, int, S_IRUGO|S_IWUSR);
module_param(hwwep, int, S_IRUGO|S_IWUSR);
-module_param(channels, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(devname, " Net interface name, wlan%d=default");
-MODULE_PARM_DESC(hwseqnum, " Try to use hardware 802.11 header sequence numbers. Zero=default");
MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support. Still broken and not available on all cards");
-MODULE_PARM_DESC(channels, " Channel bitmask for specific locales. NYI");
-
-static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
+static int rtl8180_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id);
-static void __devexit rtl8180_pci_remove(struct pci_dev *pdev);
+static void rtl8180_pci_remove(struct pci_dev *pdev);
static void rtl8180_shutdown(struct pci_dev *pdev)
{
@@ -126,8 +118,7 @@ static int rtl8180_resume(struct pci_dev *pdev)
err = pci_enable_device(pdev);
if (err) {
- printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
- dev->name);
+ dev_err(&pdev->dev, "pci_enable_device failed on resume\n");
return err;
}
@@ -159,7 +150,7 @@ static struct pci_driver rtl8180_pci_driver = {
.name = RTL8180_MODULE_NAME,
.id_table = rtl8180_pci_id_tbl,
.probe = rtl8180_pci_probe,
- .remove = __devexit_p(rtl8180_pci_remove),
+ .remove = rtl8180_pci_remove,
.suspend = rtl8180_suspend,
.resume = rtl8180_resume,
.shutdown = rtl8180_shutdown,
@@ -211,7 +202,7 @@ static struct net_device_stats *rtl8180_stats(struct net_device *dev);
void rtl8180_commit(struct net_device *dev);
void rtl8180_start_tx_beacon(struct net_device *dev);
-static struct proc_dir_entry *rtl8180_proc = NULL;
+static struct proc_dir_entry *rtl8180_proc;
static int proc_get_registers(char *page, char **start,
off_t offset, int count,
@@ -323,7 +314,6 @@ void rtl8180_proc_remove_one(struct net_device *dev)
remove_proc_entry("stats-tx", priv->dir_dev);
remove_proc_entry("stats-rx", priv->dir_dev);
remove_proc_entry("registers", priv->dir_dev);
- remove_proc_entry(dev->name, rtl8180_proc);
priv->dir_dev = NULL;
}
}
@@ -444,24 +434,6 @@ void buffer_free(struct net_device *dev, struct buffer **buffer, int len, short
*buffer = NULL;
}
-void print_buffer(u32 *buffer, int len)
-{
- int i;
- u8 *buf = (u8 *)buffer;
-
- printk("ASCII BUFFER DUMP (len: %x):\n", len);
-
- for (i = 0; i < len; i++)
- printk("%c", buf[i]);
-
- printk("\nBINARY BUFFER DUMP (len: %x):\n", len);
-
- for (i = 0; i < len; i++)
- printk("%02x", buf[i]);
-
- printk("\n");
-}
-
int get_curr_tx_free_desc(struct net_device *dev, int priority)
{
struct r8180_priv *priv = ieee80211_priv(dev);
@@ -635,74 +607,6 @@ void fix_rx_fifo(struct net_device *dev)
set_nic_rxring(dev);
}
-unsigned char QUALITY_MAP[] = {
- 0x64, 0x64, 0x64, 0x63, 0x63, 0x62, 0x62, 0x61,
- 0x61, 0x60, 0x60, 0x5f, 0x5f, 0x5e, 0x5d, 0x5c,
- 0x5b, 0x5a, 0x59, 0x57, 0x56, 0x54, 0x52, 0x4f,
- 0x4c, 0x49, 0x45, 0x41, 0x3c, 0x37, 0x31, 0x29,
- 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
- 0x20, 0x20, 0x20, 0x1f, 0x1f, 0x1e, 0x1e, 0x1e,
- 0x1d, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a, 0x19, 0x19,
- 0x18, 0x17, 0x16, 0x15, 0x14, 0x12, 0x11, 0x0f,
- 0x0e, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x01, 0x00
-};
-
-unsigned char STRENGTH_MAP[] = {
- 0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e,
- 0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50,
- 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f,
- 0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b,
- 0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17,
- 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13,
- 0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f,
- 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
- 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07,
- 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, 0x00
-};
-
-void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual)
-{
- u32 temp;
- u32 temp2;
- u32 q;
- u32 orig_qual;
- u8 _rssi;
-
- q = *qual;
- orig_qual = *qual;
- _rssi = 0; /* avoid gcc complains.. */
-
- if (q <= 0x4e) {
- temp = QUALITY_MAP[q];
- } else {
- if (q & 0x80)
- temp = 0x32;
- else
- temp = 1;
- }
-
- *qual = temp;
- temp2 = *rssi;
-
- if (_rssi < 0x64) {
- if (_rssi == 0)
- *rssi = 1;
- } else {
- *rssi = 0x64;
- }
-
- return;
-}
-
-void rtl8180_irq_enable(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- priv->irq_enabled = 1;
- write_nic_word(dev, INTA_MASK, priv->irq_mask);
-}
-
void rtl8180_irq_disable(struct net_device *dev)
{
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
@@ -724,7 +628,6 @@ void rtl8180_set_mode(struct net_device *dev, int mode)
write_nic_byte(dev, EPROM_CMD, ecmd);
}
-void rtl8180_adapter_start(struct net_device *dev);
void rtl8180_beacon_tx_enable(struct net_device *dev);
void rtl8180_update_msr(struct net_device *dev)
@@ -771,57 +674,6 @@ void rtl8180_set_chan(struct net_device *dev, short ch)
priv->rf_set_chan(dev, priv->chan);
}
-void rtl8180_rx_enable(struct net_device *dev)
-{
- u8 cmd;
- u32 rxconf;
- /* for now we accept data, management & ctl frame*/
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- rxconf = read_nic_dword(dev, RX_CONF);
- rxconf = rxconf & ~MAC_FILTER_MASK;
- rxconf = rxconf | (1<<ACCEPT_MNG_FRAME_SHIFT);
- rxconf = rxconf | (1<<ACCEPT_DATA_FRAME_SHIFT);
- rxconf = rxconf | (1<<ACCEPT_BCAST_FRAME_SHIFT);
- rxconf = rxconf | (1<<ACCEPT_MCAST_FRAME_SHIFT);
- if (dev->flags & IFF_PROMISC)
- DMESG("NIC in promisc mode");
-
- if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
- dev->flags & IFF_PROMISC) {
- rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
- } else {
- rxconf = rxconf | (1<<ACCEPT_NICMAC_FRAME_SHIFT);
- }
-
- if (priv->ieee80211->iw_mode == IW_MODE_MONITOR) {
- rxconf = rxconf | (1<<ACCEPT_CTL_FRAME_SHIFT);
- rxconf = rxconf | (1<<ACCEPT_ICVERR_FRAME_SHIFT);
- rxconf = rxconf | (1<<ACCEPT_PWR_FRAME_SHIFT);
- }
-
- if (priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
- rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
-
- rxconf = rxconf & ~RX_FIFO_THRESHOLD_MASK;
- rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE << RX_FIFO_THRESHOLD_SHIFT);
-
- rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
- rxconf = rxconf & ~MAX_RX_DMA_MASK;
- rxconf = rxconf | (MAX_RX_DMA_2048<<MAX_RX_DMA_SHIFT);
-
- rxconf = rxconf | RCR_ONLYERLPKT;
-
- rxconf = rxconf & ~RCR_CS_MASK;
-
- write_nic_dword(dev, RX_CONF, rxconf);
-
- fix_rx_fifo(dev);
-
- cmd = read_nic_byte(dev, CMD);
- write_nic_byte(dev, CMD, cmd | (1<<CMD_RX_ENABLE_SHIFT));
-}
-
void set_nic_txring(struct net_device *dev)
{
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
@@ -835,80 +687,6 @@ void set_nic_txring(struct net_device *dev)
write_nic_dword(dev, TX_BEACON_RING_ADDR, priv->txbeaconringdma);
}
-void rtl8180_conttx_enable(struct net_device *dev)
-{
- u32 txconf;
-
- txconf = read_nic_dword(dev, TX_CONF);
- txconf = txconf & ~TX_LOOPBACK_MASK;
- txconf = txconf | (TX_LOOPBACK_CONTINUE<<TX_LOOPBACK_SHIFT);
- write_nic_dword(dev, TX_CONF, txconf);
-}
-
-void rtl8180_conttx_disable(struct net_device *dev)
-{
- u32 txconf;
-
- txconf = read_nic_dword(dev, TX_CONF);
- txconf = txconf & ~TX_LOOPBACK_MASK;
- txconf = txconf | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT);
- write_nic_dword(dev, TX_CONF, txconf);
-}
-
-void rtl8180_tx_enable(struct net_device *dev)
-{
- u8 cmd;
- u8 tx_agc_ctl;
- u8 byte;
- u32 txconf;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- txconf = read_nic_dword(dev, TX_CONF);
-
- byte = read_nic_byte(dev, CW_CONF);
- byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
- byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
- write_nic_byte(dev, CW_CONF, byte);
-
- tx_agc_ctl = read_nic_byte(dev, TX_AGC_CTL);
- tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
- tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
- tx_agc_ctl |= (1<<TX_AGC_CTL_FEEDBACK_ANT);
- write_nic_byte(dev, TX_AGC_CTL, tx_agc_ctl);
- write_nic_byte(dev, 0xec, 0x3f); /* Disable early TX */
-
- txconf = txconf & ~(1<<TCR_PROBE_NOTIMESTAMP_SHIFT);
-
- txconf = txconf & ~TX_LOOPBACK_MASK;
- txconf = txconf | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT);
- txconf = txconf & ~TCR_DPRETRY_MASK;
- txconf = txconf & ~TCR_RTSRETRY_MASK;
- txconf = txconf | (priv->retry_data<<TX_DPRETRY_SHIFT);
- txconf = txconf | (priv->retry_rts<<TX_RTSRETRY_SHIFT);
- txconf = txconf & ~(1<<TX_NOCRC_SHIFT);
-
- if (priv->hw_plcp_len)
- txconf = txconf & ~TCR_PLCP_LEN;
- else
- txconf = txconf | TCR_PLCP_LEN;
-
- txconf = txconf & ~TCR_MXDMA_MASK;
- txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
- txconf = txconf | TCR_CWMIN;
- txconf = txconf | TCR_DISCW;
-
- txconf = txconf | (1 << TX_NOICV_SHIFT);
-
- write_nic_dword(dev, TX_CONF, txconf);
-
- fix_tx_fifo(dev);
-
- cmd = read_nic_byte(dev, CMD);
- write_nic_byte(dev, CMD, cmd | (1<<CMD_TX_ENABLE_SHIFT));
-
- write_nic_dword(dev, TX_CONF, txconf);
-}
-
void rtl8180_beacon_tx_enable(struct net_device *dev)
{
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
@@ -936,8 +714,8 @@ void rtl8180_rtx_disable(struct net_device *dev)
struct r8180_priv *priv = ieee80211_priv(dev);
cmd = read_nic_byte(dev, CMD);
- write_nic_byte(dev, CMD, cmd & ~\
- ((1<<CMD_RX_ENABLE_SHIFT)|(1<<CMD_TX_ENABLE_SHIFT)));
+ write_nic_byte(dev, CMD, cmd &
+ ~((1<<CMD_RX_ENABLE_SHIFT)|(1<<CMD_TX_ENABLE_SHIFT)));
force_pci_posting(dev);
mdelay(10);
@@ -1481,8 +1259,7 @@ void rtl8180_rx(struct net_device *dev)
pci_dma_sync_single_for_cpu(priv->pdev,
priv->rxbuffer->dma,
- priv->rxbuffersize * \
- sizeof(u8),
+ priv->rxbuffersize * sizeof(u8),
PCI_DMA_FROMDEVICE);
first = *(priv->rxringtail) & (1<<29) ? 1 : 0;
@@ -1660,14 +1437,9 @@ void rtl8180_rx(struct net_device *dev)
dev_kfree_skb_any(priv->rx_skb);
priv->stats.rxnolast++;
}
- /* support for prism header has been originally added by Christian */
- if (priv->prism_hdr && priv->ieee80211->iw_mode == IW_MODE_MONITOR) {
-
- } else {
- priv->rx_skb = dev_alloc_skb(len+2);
- if (!priv->rx_skb)
- goto drop;
- }
+ priv->rx_skb = dev_alloc_skb(len+2);
+ if (!priv->rx_skb)
+ goto drop;
priv->rx_skb_complete = 0;
priv->rx_skb->dev = dev;
@@ -1718,8 +1490,7 @@ void rtl8180_rx(struct net_device *dev)
pci_dma_sync_single_for_device(priv->pdev,
priv->rxbuffer->dma,
- priv->rxbuffersize * \
- sizeof(u8),
+ priv->rxbuffersize * sizeof(u8),
PCI_DMA_FROMDEVICE);
drop: /* this is used when we have not enough mem */
@@ -1929,7 +1700,7 @@ void rtl8180_prepare_beacon(struct net_device *dev)
* descriptor in the ring buffer, copyes the frame in a TX buffer
* and kicks the NIC to ensure it does the DMA transfer.
*/
-short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
+short rtl8180_tx(struct net_device *dev, u8 *txbuf, int len, int priority,
short morefrag, short descfrag, int rate)
{
struct r8180_priv *priv = ieee80211_priv(dev);
@@ -1940,8 +1711,6 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
int remain;
int buflen;
int count;
- u16 duration;
- short ext;
struct buffer *buflist;
struct ieee80211_hdr_3addr *frag_hdr = (struct ieee80211_hdr_3addr *)txbuf;
u8 dest[ETH_ALEN];
@@ -2137,15 +1906,6 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
*tail = *tail | ((rate&0xf) << 24);
- /* hw_plcp_len is not used for rtl8180 chip */
- /* FIXME */
- if (!priv->hw_plcp_len) {
- duration = rtl8180_len2duration(len, rate, &ext);
- *(tail+1) = *(tail+1) | ((duration & 0x7fff)<<16);
- if (ext)
- *(tail+1) = *(tail+1) | (1<<31); /* plcp length extension */
- }
-
if (morefrag)
*tail = (*tail) | (1<<17); /* more fragment */
if (!remain)
@@ -2223,10 +1983,10 @@ void rtl8180_link_change(struct net_device *dev)
write_nic_dword(dev, BSSID, ((u32 *)net->bssid)[0]);
write_nic_word(dev, BSSID+4, ((u16 *)net->bssid)[2]);
- beacon_interval = read_nic_dword(dev, BEACON_INTERVAL);
+ beacon_interval = read_nic_word(dev, BEACON_INTERVAL);
beacon_interval &= ~BEACON_INTERVAL_MASK;
beacon_interval |= net->beacon_interval;
- write_nic_dword(dev, BEACON_INTERVAL, beacon_interval);
+ write_nic_word(dev, BEACON_INTERVAL, beacon_interval);
rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
@@ -2279,8 +2039,6 @@ short rtl8180_is_tx_queue_empty(struct net_device *dev)
return 0;
return 1;
}
-/* FIXME FIXME 5msecs is random */
-#define HW_WAKE_DELAY 5
void rtl8180_hw_wakeup(struct net_device *dev)
{
@@ -2397,7 +2155,8 @@ void rtl8180_wmm_param_update(struct work_struct *work)
write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
break;
default:
- printk(KERN_WARNING "SetHwReg8185():invalid ACI: %d!\n", eACI);
+ pr_warn("SetHwReg8185():invalid ACI: %d!\n",
+ eACI);
break;
}
}
@@ -2436,7 +2195,8 @@ void rtl8180_wmm_param_update(struct work_struct *work)
write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
break;
default:
- printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
+ pr_warn("SetHwReg8185(): invalid ACI: %d !\n",
+ eACI);
break;
}
}
@@ -2444,7 +2204,6 @@ void rtl8180_wmm_param_update(struct work_struct *work)
}
}
-void rtl8180_tx_irq_wq(struct work_struct *work);
void rtl8180_restart_wq(struct work_struct *work);
/* void rtl8180_rq_tx_ack(struct work_struct *work); */
void rtl8180_watch_dog_wq(struct work_struct *work);
@@ -2455,7 +2214,7 @@ void rtl8180_watch_dog(struct net_device *dev);
void watch_dog_adaptive(unsigned long data)
{
- struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
+ struct r8180_priv *priv = ieee80211_priv((struct net_device *)data);
if (!priv->up) {
DMESG("<----watch_dog_adaptive():driver is not up!\n");
@@ -2601,8 +2360,7 @@ short rtl8180_init(struct net_device *dev)
{
struct r8180_priv *priv = ieee80211_priv(dev);
u16 word;
- u16 version;
- u32 usValue;
+ u16 usValue;
u16 tmpu16;
int i, j;
struct eeprom_93cx6 eeprom;
@@ -2634,7 +2392,6 @@ short rtl8180_init(struct net_device *dev)
priv->RFChangeInProgress = false;
priv->SetRFPowerStateInProgress = false;
priv->RFProgType = 0;
- priv->bInHctTest = false;
priv->irq_enabled = 0;
@@ -2658,14 +2415,12 @@ short rtl8180_init(struct net_device *dev)
priv->ieee80211->ps_is_queue_empty = rtl8180_is_tx_queue_empty;
priv->hw_wep = hwwep;
- priv->prism_hdr = 0;
priv->dev = dev;
priv->retry_rts = DEFAULT_RETRY_RTS;
priv->retry_data = DEFAULT_RETRY_DATA;
priv->RFChangeInProgress = false;
priv->SetRFPowerStateInProgress = false;
priv->RFProgType = 0;
- priv->bInHctTest = false;
priv->bInactivePs = true; /* false; */
priv->ieee80211->bInactivePs = priv->bInactivePs;
priv->bSwRfProcessing = false;
@@ -2726,7 +2481,6 @@ short rtl8180_init(struct net_device *dev)
priv->NumTxOkTotal = 0;
priv->NumTxUnicast = 0;
priv->keepAliveLevel = DEFAULT_KEEP_ALIVE_LEVEL;
- priv->PowerProfile = POWER_PROFILE_AC;
priv->CurrRetryCnt = 0;
priv->LastRetryCnt = 0;
priv->LastTxokCnt = 0;
@@ -2748,15 +2502,12 @@ short rtl8180_init(struct net_device *dev)
priv->RegBModeGainStage = 1;
priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
- spin_lock_init(&priv->irq_lock);
spin_lock_init(&priv->irq_th_lock);
spin_lock_init(&priv->tx_lock);
spin_lock_init(&priv->ps_lock);
spin_lock_init(&priv->rf_ps_lock);
sema_init(&priv->wx_sem, 1);
- sema_init(&priv->rf_state, 1);
INIT_WORK(&priv->reset_wq, (void *)rtl8180_restart_wq);
- INIT_WORK(&priv->tx_irq_wq, (void *)rtl8180_tx_irq_wq);
INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,
(void *)rtl8180_hw_wakeup_wq);
INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,
@@ -2798,19 +2549,14 @@ short rtl8180_init(struct net_device *dev)
priv->ieee80211->stop_send_beacons = rtl8180_beacon_tx_disable;
priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
- priv->MWIEnable = 0;
-
priv->ShortRetryLimit = 7;
priv->LongRetryLimit = 7;
priv->EarlyRxThreshold = 7;
- priv->CSMethod = (0x01 << 29);
-
- priv->TransmitConfig = TCR_DurProcMode_OFFSET |
+ priv->TransmitConfig = (1<<TCR_DurProcMode_OFFSET) |
(7<<TCR_MXDMA_OFFSET) |
(priv->ShortRetryLimit<<TCR_SRL_OFFSET) |
- (priv->LongRetryLimit<<TCR_LRL_OFFSET) |
- (0 ? TCR_SAT : 0);
+ (priv->LongRetryLimit<<TCR_LRL_OFFSET);
priv->ReceiveConfig = RCR_AMF | RCR_ADF | RCR_ACF |
RCR_AB | RCR_AM | RCR_APM |
@@ -2832,47 +2578,35 @@ short rtl8180_init(struct net_device *dev)
priv->InitialGain = 6;
DMESG("MAC controller is a RTL8187SE b/g");
- priv->phy_ver = 2;
priv->ieee80211->modulation |= IEEE80211_OFDM_MODULATION;
priv->ieee80211->short_slot = 1;
- /* just for sync 85 */
- priv->enable_gpio0 = 0;
-
- eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &eeprom_val);
- usValue = eeprom_val;
- DMESG("usValue is 0x%x\n", usValue);
+ eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &usValue);
+ DMESG("usValue is %#hx\n", usValue);
/* 3Read AntennaDiversity */
/* SW Antenna Diversity. */
- if ((usValue & EEPROM_SW_AD_MASK) != EEPROM_SW_AD_ENABLE)
- priv->EEPROMSwAntennaDiversity = false;
- else
- priv->EEPROMSwAntennaDiversity = true;
+ priv->EEPROMSwAntennaDiversity = (usValue & EEPROM_SW_AD_MASK) ==
+ EEPROM_SW_AD_ENABLE;
/* Default Antenna to use. */
- if ((usValue & EEPROM_DEF_ANT_MASK) != EEPROM_DEF_ANT_1)
- priv->EEPROMDefaultAntenna1 = false;
- else
- priv->EEPROMDefaultAntenna1 = true;
+ priv->EEPROMDefaultAntenna1 = (usValue & EEPROM_DEF_ANT_MASK) ==
+ EEPROM_DEF_ANT_1;
if (priv->RegSwAntennaDiversityMechanism == 0) /* Auto */
/* 0: default from EEPROM. */
priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity;
else
/* 1:disable antenna diversity, 2: enable antenna diversity. */
- priv->bSwAntennaDiverity = ((priv->RegSwAntennaDiversityMechanism == 1) ? false : true);
+ priv->bSwAntennaDiverity = priv->RegSwAntennaDiversityMechanism == 2;
if (priv->RegDefaultAntenna == 0)
/* 0: default from EEPROM. */
priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1;
else
/* 1: main, 2: aux. */
- priv->bDefaultAntenna1 = ((priv->RegDefaultAntenna == 2) ? true : false);
-
- /* rtl8185 can calc plcp len in HW. */
- priv->hw_plcp_len = 1;
+ priv->bDefaultAntenna1 = priv->RegDefaultAntenna == 2;
priv->plcp_preamble_mode = 2;
/* the eeprom type is stored in RCR register bit #6 */
@@ -2909,18 +2643,6 @@ short rtl8180_init(struct net_device *dev)
if ((tmpu16 & EEPROM_THERMAL_METER_ENABLE) >> 13)
priv->bTxPowerTrack = true;
- eeprom_93cx6_read(&eeprom, EPROM_TXPW_BASE, &word);
- priv->cck_txpwr_base = word & 0xf;
- priv->ofdm_txpwr_base = (word>>4) & 0xf;
-
- eeprom_93cx6_read(&eeprom, EPROM_VERSION, &version);
- DMESG("EEPROM version %x", version);
- priv->rcr_csense = 3;
-
- eeprom_93cx6_read(&eeprom, ENERGY_TRESHOLD, &eeprom_val);
- priv->cs_treshold = (eeprom_val & 0xff00) >> 8;
-
- eeprom_93cx6_read(&eeprom, RFCHIPID, &eeprom_val);
priv->rf_sleep = rtl8225z4_rf_sleep;
priv->rf_wakeup = rtl8225z4_rf_wakeup;
DMESGW("**PLEASE** REPORT SUCCESSFUL/UNSUCCESSFUL TO Realtek!");
@@ -3084,100 +2806,6 @@ void write_phy_cck(struct net_device *dev, u8 adr, u32 data)
rtl8185_write_phy(dev, adr, data | 0x10000);
}
-void rtl8185_set_rate(struct net_device *dev)
-{
- int i;
- u16 word;
- int basic_rate, min_rr_rate, max_rr_rate;
-
- basic_rate = ieeerate2rtlrate(240);
- min_rr_rate = ieeerate2rtlrate(60);
- max_rr_rate = ieeerate2rtlrate(240);
-
- write_nic_byte(dev, RESP_RATE,
- max_rr_rate<<MAX_RESP_RATE_SHIFT |
- min_rr_rate<<MIN_RESP_RATE_SHIFT);
-
- word = read_nic_word(dev, BRSR);
- word &= ~BRSR_MBR_8185;
-
- for (i = 0; i <= basic_rate; i++)
- word |= (1<<i);
-
- write_nic_word(dev, BRSR, word);
-}
-
-void rtl8180_adapter_start(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- rtl8180_rtx_disable(dev);
- rtl8180_reset(dev);
-
- /* enable beacon timeout, beacon TX ok and err
- * LP tx ok and err, HP TX ok and err, NP TX ok and err,
- * RX ok and ERR, and GP timer
- */
- priv->irq_mask = 0x6fcf;
-
- priv->dma_poll_mask = 0;
-
- rtl8180_beacon_tx_disable(dev);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]);
- write_nic_word(dev, MAC4, ((u32 *)dev->dev_addr)[1] & 0xffff);
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
- rtl8180_update_msr(dev);
-
- /* These might be unnecessary since we do in rx_enable / tx_enable */
- fix_rx_fifo(dev);
- fix_tx_fifo(dev);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-
- /*
- * The following is very strange. seems to be that 1 means test mode,
- * but we need to acknowledges the nic when a packet is ready
- * although we set it to 0
- */
-
- write_nic_byte(dev,
- CONFIG2, read_nic_byte(dev, CONFIG2) & ~\
- (1<<CONFIG2_DMA_POLLING_MODE_SHIFT));
- /* ^the nic isn't in test mode */
- write_nic_byte(dev,
- CONFIG2, read_nic_byte(dev, CONFIG2)|(1<<4));
-
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
- write_nic_dword(dev, INT_TIMEOUT, 0);
-
- write_nic_byte(dev, WPA_CONFIG, 0);
-
- rtl8180_no_hw_wep(dev);
-
- rtl8185_set_rate(dev);
- write_nic_byte(dev, RATE_FALLBACK, 0x81);
-
- write_nic_byte(dev, GP_ENABLE, read_nic_byte(dev, GP_ENABLE) & ~(1<<6));
-
- /* FIXME cfg 3 ClkRun enable - isn't it ReadOnly ? */
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- write_nic_byte(dev, CONFIG3, read_nic_byte(dev, CONFIG3)
- | (1 << CONFIG3_CLKRUN_SHIFT));
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
- priv->rf_init(dev);
-
- if (priv->rf_set_sens != NULL)
- priv->rf_set_sens(dev, priv->sens);
- rtl8180_irq_enable(dev);
-
- netif_start_queue(dev);
-}
-
/*
* This configures registers for beacon tx and enables it via
* rtl8180_beacon_tx_enable(). rtl8180_beacon_tx_disable() might
@@ -3299,8 +2927,6 @@ static void MgntLinkKeepAlive(struct r8180_priv *priv)
}
}
-static u8 read_acadapter_file(char *filename);
-
void rtl8180_watch_dog(struct net_device *dev)
{
struct r8180_priv *priv = ieee80211_priv(dev);
@@ -3333,12 +2959,7 @@ void rtl8180_watch_dog(struct net_device *dev)
MgntLinkKeepAlive(priv);
/* YJ,add,080828,for LPS */
- if (priv->PowerProfile == POWER_PROFILE_BATTERY)
- priv->bLeisurePs = true;
- else if (priv->PowerProfile == POWER_PROFILE_AC) {
- LeisurePSLeave(priv);
- priv->bLeisurePs = false;
- }
+ LeisurePSLeave(priv);
if (priv->ieee80211->state == IEEE80211_LINKED) {
priv->link_detect.NumRxOkInPeriod = priv->ieee80211->NumRxDataInPeriod;
@@ -3555,7 +3176,7 @@ static const struct net_device_ops rtl8180_netdev_ops = {
.ndo_start_xmit = ieee80211_rtl_xmit,
};
-static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
+static int rtl8180_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
unsigned long ioaddr = 0;
@@ -3638,7 +3259,8 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
netif_carrier_off(dev);
- register_netdev(dev);
+ if (register_netdev(dev))
+ goto fail1;
rtl8180_proc_init_one(dev);
@@ -3667,7 +3289,7 @@ fail_free:
return ret;
}
-static void __devexit rtl8180_pci_remove(struct pci_dev *pdev)
+static void rtl8180_pci_remove(struct pci_dev *pdev)
{
struct r8180_priv *priv;
struct net_device *dev = pci_get_drvdata(pdev);
@@ -3721,27 +3343,27 @@ static int __init rtl8180_pci_module_init(void)
ret = ieee80211_crypto_init();
if (ret) {
- printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
+ pr_err("ieee80211_crypto_init() failed %d\n", ret);
return ret;
}
ret = ieee80211_crypto_tkip_init();
if (ret) {
- printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n", ret);
+ pr_err("ieee80211_crypto_tkip_init() failed %d\n", ret);
return ret;
}
ret = ieee80211_crypto_ccmp_init();
if (ret) {
- printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n", ret);
+ pr_err("ieee80211_crypto_ccmp_init() failed %d\n", ret);
return ret;
}
ret = ieee80211_crypto_wep_init();
if (ret) {
- printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
+ pr_err("ieee80211_crypto_wep_init() failed %d\n", ret);
return ret;
}
- printk(KERN_INFO "\nLinux kernel driver for RTL8180 / RTL8185 based WLAN cards\n");
- printk(KERN_INFO "Copyright (c) 2004-2005, Andrea Merello\n");
+ pr_info("\nLinux kernel driver for RTL8180 / RTL8185 based WLAN cards\n");
+ pr_info("Copyright (c) 2004-2005, Andrea Merello\n");
DMESG("Initializing module");
DMESG("Wireless extensions version %d", WIRELESS_EXT);
rtl8180_proc_module_init();
@@ -3844,7 +3466,7 @@ void rtl8180_tx_isr(struct net_device *dev, int pri, short error)
return ;
}
- nicv = (u32 *)((nic - nicbegin) + (u8*)begin);
+ nicv = (u32 *)((nic - nicbegin) + (u8 *)begin);
if ((head <= tail && (nicv > tail || nicv < head)) ||
(head > tail && (nicv > tail && nicv < head))) {
DMESGW("nic has lost pointer");
@@ -3932,15 +3554,6 @@ void rtl8180_tx_isr(struct net_device *dev, int pri, short error)
spin_unlock_irqrestore(&priv->tx_lock, flag);
}
-void rtl8180_tx_irq_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device * ieee = (struct ieee80211_device *)
- container_of(dwork, struct ieee80211_device, watch_dog_wq);
- struct net_device *dev = ieee->dev;
-
- rtl8180_tx_isr(dev, MANAGE_PRIORITY, 0);
-}
irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) netdev;
@@ -4013,7 +3626,7 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs)
priv->stats.txbkperr++;
priv->ieee80211->stats.tx_errors++;
rtl8180_tx_isr(dev, BK_PRIORITY, 1);
- rtl8180_try_wake_queue(dev, BE_PRIORITY);
+ rtl8180_try_wake_queue(dev, BK_PRIORITY);
}
if (inta & ISR_TBEDER) { /* corresponding to BE_PRIORITY */
@@ -4067,6 +3680,7 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs)
priv->link_detect.NumTxOkInPeriod++; /* YJ,add,080828 */
priv->stats.txnpokint++;
rtl8180_tx_isr(dev, NORM_PRIORITY, 0);
+ rtl8180_try_wake_queue(dev, NORM_PRIORITY);
}
if (inta & ISR_TLPDOK) { /* Low priority tx ok */
@@ -4113,10 +3727,7 @@ void GPIOChangeRFWorkItemCallBack(struct work_struct *work)
char *argv[3];
static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh";
static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL};
- static int readf_count = 0;
-
- if (readf_count % 10 == 0)
- priv->PowerProfile = read_acadapter_file("/proc/acpi/ac_adapter/AC0/state");
+ static int readf_count;
readf_count = (readf_count+1)%0xffff;
/* We should turn off LED before polling FF51[4]. */
@@ -4162,10 +3773,5 @@ void GPIOChangeRFWorkItemCallBack(struct work_struct *work)
}
}
-static u8 read_acadapter_file(char *filename)
-{
- return 0;
-}
-
module_init(rtl8180_pci_module_init);
module_exit(rtl8180_pci_module_exit);
diff --git a/drivers/staging/rtl8187se/r8180_dm.h b/drivers/staging/rtl8187se/r8180_dm.h
index b7758254ad7..732c06ac102 100644
--- a/drivers/staging/rtl8187se/r8180_dm.h
+++ b/drivers/staging/rtl8187se/r8180_dm.h
@@ -13,10 +13,10 @@ bool CheckDig(struct net_device *dev);
bool CheckHighPower(struct net_device *dev);
void rtl8180_hw_dig_wq(struct work_struct *work);
void rtl8180_tx_pw_wq(struct work_struct *work);
-void rtl8180_rate_adapter(struct work_struct * work);
+void rtl8180_rate_adapter(struct work_struct *work);
void TxPwrTracking87SE(struct net_device *dev);
bool CheckTxPwrTracking(struct net_device *dev);
-void rtl8180_rate_adapter(struct work_struct * work);
+void rtl8180_rate_adapter(struct work_struct *work);
void timer_rate_adaptive(unsigned long data);
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225.h b/drivers/staging/rtl8187se/r8180_rtl8225.h
index 494ea8619e7..c6f2128e755 100644
--- a/drivers/staging/rtl8187se/r8180_rtl8225.h
+++ b/drivers/staging/rtl8187se/r8180_rtl8225.h
@@ -23,8 +23,8 @@ void rtl8225z2_rf_init(struct net_device *dev);
void rtl8225z2_rf_set_chan(struct net_device *dev, short ch);
void rtl8225z2_rf_close(struct net_device *dev);
-void RF_WriteReg(struct net_device *dev, u8 offset, u32 data);
-u32 RF_ReadReg(struct net_device *dev, u8 offset);
+void RF_WriteReg(struct net_device *dev, u8 offset, u16 data);
+u16 RF_ReadReg(struct net_device *dev, u8 offset);
void rtl8180_set_mode(struct net_device *dev, int mode);
void rtl8180_set_mode(struct net_device *dev, int mode);
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
index d28c1d99608..c592f7936dd 100644
--- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c
+++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
@@ -15,7 +15,6 @@
#include "ieee80211/dot11d.h"
-
static void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
{
int i;
@@ -76,22 +75,6 @@ static void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
rtl8185_rf_pins_enable(dev);
}
-static const u16 rtl8225bcd_rxgain[] = {
- 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
- 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
- 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
- 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
- 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
- 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
- 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
- 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
- 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
- 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
- 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
- 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
-
-};
-
static const u8 rtl8225_agc[] = {
0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
@@ -111,122 +94,12 @@ static const u8 rtl8225_agc[] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
};
-static const u8 rtl8225_gain[] = {
- 0x23, 0x88, 0x7c, 0xa5, /* -82dBm */
- 0x23, 0x88, 0x7c, 0xb5, /* -82dBm */
- 0x23, 0x88, 0x7c, 0xc5, /* -82dBm */
- 0x33, 0x80, 0x79, 0xc5, /* -78dBm */
- 0x43, 0x78, 0x76, 0xc5, /* -74dBm */
- 0x53, 0x60, 0x73, 0xc5, /* -70dBm */
- 0x63, 0x58, 0x70, 0xc5, /* -66dBm */
-};
-
-static const u8 rtl8225_tx_gain_cck_ofdm[] = {
- 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
-};
-
-static const u8 rtl8225_tx_power_cck[] = {
- 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
- 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
- 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
- 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
- 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
- 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
-};
-
-static const u8 rtl8225_tx_power_cck_ch14[] = {
- 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
- 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
- 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
- 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
- 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
-};
-
-static const u8 rtl8225_tx_power_ofdm[] = {
- 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
-};
-
static const u32 rtl8225_chan[] = {
0,
0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380,
0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x074A,
};
-static void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int GainIdx;
- int GainSetting;
- int i;
- u8 power;
- const u8 *cck_power_table;
- u8 max_cck_power_level;
- u8 max_ofdm_power_level;
- u8 min_ofdm_power_level;
- u8 cck_power_level = 0xff & priv->chtxpwr[ch];
- u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
-
- max_cck_power_level = 35;
- max_ofdm_power_level = 35;
- min_ofdm_power_level = 0;
-
- if (cck_power_level > max_cck_power_level)
- cck_power_level = max_cck_power_level;
-
- GainIdx = cck_power_level % 6;
- GainSetting = cck_power_level / 6;
-
- if (ch == 14)
- cck_power_table = rtl8225_tx_power_cck_ch14;
- else
- cck_power_table = rtl8225_tx_power_cck;
-
- write_nic_byte(dev, TX_GAIN_CCK,
- rtl8225_tx_gain_cck_ofdm[GainSetting] >> 1);
-
- for (i = 0; i < 8; i++) {
- power = cck_power_table[GainIdx * 8 + i];
- write_phy_cck(dev, 0x44 + i, power);
- }
-
- /* FIXME Is this delay really needed ? */
- force_pci_posting(dev);
- mdelay(1);
-
- if (ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
- ofdm_power_level = max_ofdm_power_level;
- else
- ofdm_power_level += min_ofdm_power_level;
-
- if (ofdm_power_level > 35)
- ofdm_power_level = 35;
-
- GainIdx = ofdm_power_level % 6;
- GainSetting = ofdm_power_level / 6;
-
- rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
-
- write_phy_ofdm(dev, 2, 0x42);
- write_phy_ofdm(dev, 6, 0x00);
- write_phy_ofdm(dev, 8, 0x00);
-
- write_nic_byte(dev, TX_GAIN_OFDM,
- rtl8225_tx_gain_cck_ofdm[GainSetting] >> 1);
-
- power = rtl8225_tx_power_ofdm[GainIdx];
-
- write_phy_ofdm(dev, 5, power);
- write_phy_ofdm(dev, 7, power);
-
- force_pci_posting(dev);
- mdelay(1);
-}
-
-static const u8 rtl8225z2_threshold[] = {
- 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
-};
-
static const u8 rtl8225z2_gain_bg[] = {
0x23, 0x15, 0xa5, /* -82-1dBm */
0x23, 0x15, 0xb5, /* -82-2dBm */
@@ -259,29 +132,8 @@ static const u16 rtl8225z2_rxgain[] = {
0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
- 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
-
-};
+ 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb
-static const u8 ZEBRA2_CCK_OFDM_GAIN_SETTING[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
- 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
- 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
- 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
- 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
-};
-
-static const u8 rtl8225z2_tx_power_ofdm[] = {
- 0x42, 0x00, 0x40, 0x00, 0x40
-};
-
-static const u8 rtl8225z2_tx_power_cck_ch14[] = {
- 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
-};
-
-static const u8 rtl8225z2_tx_power_cck[] = {
- 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
};
void rtl8225z2_set_gain(struct net_device *dev, short gain)
@@ -412,22 +264,6 @@ static u32 read_rtl8225(struct net_device *dev, u8 adr)
return dataRead;
}
-short rtl8225_is_V_z2(struct net_device *dev)
-{
- short vz2 = 1;
-
- if (read_rtl8225(dev, 8) != 0x588)
- vz2 = 0;
- else /* reg 9 pg 1 = 24 */
- if (read_rtl8225(dev, 9) != 0x700)
- vz2 = 0;
-
- /* sw back to pg 0 */
- write_rtl8225(dev, 0, 0xb7);
-
- return vz2;
-}
-
void rtl8225z2_rf_close(struct net_device *dev)
{
RF_WriteReg(dev, 0x4, 0x1f);
@@ -524,8 +360,7 @@ void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch)
if (cck_power_level > 35)
cck_power_level = 35;
- write_nic_byte(dev, CCK_TXAGC,
- (ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)cck_power_level]));
+ write_nic_byte(dev, CCK_TXAGC, cck_power_level);
force_pci_posting(dev);
mdelay(1);
@@ -540,8 +375,7 @@ void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch)
write_phy_ofdm(dev, 8, 0x40);
}
- write_nic_byte(dev, OFDM_TXAGC,
- ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)ofdm_power_level]);
+ write_nic_byte(dev, OFDM_TXAGC, ofdm_power_level);
if (ofdm_power_level <= 11) {
write_phy_ofdm(dev, 0x07, 0x5c);
@@ -592,50 +426,13 @@ static void rtl8225_host_pci_init(struct net_device *dev)
write_nic_word(dev, GP_ENABLE, 0xff & (~(1 << 6)));
}
-static void rtl8225_rf_set_chan(struct net_device *dev, short ch)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
- ieee80211_is_54g(&priv->ieee80211->current_network)) ||
- priv->ieee80211->iw_mode == IW_MODE_MONITOR;
-
- rtl8225_SetTXPowerLevel(dev, ch);
-
- write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
-
- force_pci_posting(dev);
- mdelay(10);
-
- if (gset) {
- write_nic_byte(dev, SIFS, 0x22);
- write_nic_byte(dev, DIFS, 0x14);
- } else {
- write_nic_byte(dev, SIFS, 0x44);
- write_nic_byte(dev, DIFS, 0x24);
- }
-
- if (priv->ieee80211->state == IEEE80211_LINKED &&
- ieee80211_is_shortslot(&priv->ieee80211->current_network))
- write_nic_byte(dev, SLOT, 0x9);
- else
- write_nic_byte(dev, SLOT, 0x14);
-
- if (gset) {
- write_nic_byte(dev, EIFS, 81);
- write_nic_byte(dev, CW_VAL, 0x73);
- } else {
- write_nic_byte(dev, EIFS, 81);
- write_nic_byte(dev, CW_VAL, 0xa5);
- }
-}
-
void rtl8225z2_rf_init(struct net_device *dev)
{
struct r8180_priv *priv = ieee80211_priv(dev);
int i;
short channel = 1;
- u16 brsr;
- u32 data, addr;
+ u16 brsr;
+ u32 data;
priv->chan = channel;
@@ -676,8 +473,8 @@ void rtl8225z2_rf_init(struct net_device *dev)
write_rtl8225(dev, 0x0, 0x1b7);
- for (i = 0; i < 95; i++) {
- write_rtl8225(dev, 0x1, (u8)(i + 1));
+ for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
+ write_rtl8225(dev, 0x1, i + 1);
write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]);
}
@@ -707,14 +504,12 @@ void rtl8225z2_rf_init(struct net_device *dev)
write_rtl8225(dev, 0x0, 0x2bf);
- for (i = 0; i < 128; i++) {
- data = rtl8225_agc[i];
-
- addr = i + 0x80; /* enable writing AGC table */
- write_phy_ofdm(dev, 0xb, data);
+ for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
+ write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
mdelay(1);
- write_phy_ofdm(dev, 0xa, addr);
+ /* enable writing AGC table */
+ write_phy_ofdm(dev, 0xa, i + 0x80);
mdelay(1);
}
@@ -808,7 +603,7 @@ void rtl8225z2_rf_init(struct net_device *dev)
write_nic_dword(dev, 0x94, 0x15c00002);
rtl8185_rf_pins_enable(dev);
- rtl8225_rf_set_chan(dev, priv->chan);
+ rtl8225z2_rf_set_chan(dev, priv->chan);
}
void rtl8225z2_rf_set_mode(struct net_device *dev)
diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c
index 52f63d75d24..156b7588229 100644
--- a/drivers/staging/rtl8187se/r8180_wx.c
+++ b/drivers/staging/rtl8187se/r8180_wx.c
@@ -59,8 +59,6 @@ int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info,
if (priv->ieee80211->bHwRadioOff)
return 0;
- if (erq->flags & IW_ENCODE_DISABLED)
-
if (erq->length > 0) {
u32* tkey = (u32*) key;
priv->key0[0] = tkey[0];
diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c
index bf343199bd2..f1db9e401c8 100644
--- a/drivers/staging/rtl8187se/r8185b_init.c
+++ b/drivers/staging/rtl8187se/r8185b_init.c
@@ -207,156 +207,84 @@ void SetOutputEnableOfRfPins(struct net_device *dev)
write_nic_word(dev, RFPinsEnable, 0x1bff);
}
-static int HwHSSIThreeWire(struct net_device *dev,
- u8 *pDataBuf,
- u8 nDataBufBitCnt,
- int bSI,
- int bWrite)
+static bool HwHSSIThreeWire(struct net_device *dev,
+ u8 *pDataBuf,
+ bool write)
{
- int bResult = 1;
u8 TryCnt;
u8 u1bTmp;
- do {
- /* Check if WE and RE are cleared. */
- for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
- u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
- if ((u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0)
- break;
-
- udelay(10);
- }
- if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) {
- printk(KERN_ERR "rtl8187se: HwThreeWire(): CmdReg:"
- " %#X RE|WE bits are not clear!!\n", u1bTmp);
- dump_stack();
- return 0;
- }
-
- /* RTL8187S HSSI Read/Write Function */
- u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
-
- if (bSI)
- u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */
-
- else
- u1bTmp &= ~RF_SW_CFG_SI; /* reg08[1]=0 Parallel Interface(PI) */
-
-
- write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
-
- if (bSI) {
- /* jong: HW SI read must set reg84[3]=0. */
- u1bTmp = read_nic_byte(dev, RFPinsSelect);
- u1bTmp &= ~BIT3;
- write_nic_byte(dev, RFPinsSelect, u1bTmp);
- }
- /* Fill up data buffer for write operation. */
-
- if (bWrite) {
- if (nDataBufBitCnt == 16) {
- write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
- } else if (nDataBufBitCnt == 64) {
- /* RTL8187S shouldn't enter this case */
- write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf));
- write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4)));
- } else {
- int idx;
- int ByteCnt = nDataBufBitCnt / 8;
- /* printk("%d\n",nDataBufBitCnt); */
- if ((nDataBufBitCnt % 8) != 0) {
- printk(KERN_ERR "rtl8187se: "
- "HwThreeWire(): nDataBufBitCnt(%d)"
- " should be multiple of 8!!!\n",
- nDataBufBitCnt);
- dump_stack();
- nDataBufBitCnt += 8;
- nDataBufBitCnt &= ~7;
- }
-
- if (nDataBufBitCnt > 64) {
- printk(KERN_ERR "rtl8187se: HwThreeWire():"
- " nDataBufBitCnt(%d) should <= 64!!!\n",
- nDataBufBitCnt);
- dump_stack();
- nDataBufBitCnt = 64;
- }
+ /* Check if WE and RE are cleared. */
+ for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
+ u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
+ if ((u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0)
+ break;
- for (idx = 0; idx < ByteCnt; idx++)
- write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
+ udelay(10);
+ }
+ if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) {
+ netdev_err(dev,
+ "HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n",
+ u1bTmp);
+ return false;
+ }
- }
- } else { /* read */
- if (bSI) {
- /* SI - reg274[3:0] : RF register's Address */
- write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
- } else {
- /* PI - reg274[15:12] : RF register's Address */
- write_nic_word(dev, SW_3W_DB0, (*((u16 *)pDataBuf)) << 12);
- }
- }
+ /* RTL8187S HSSI Read/Write Function */
+ u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
+ u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */
+ write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
- /* Set up command: WE or RE. */
- if (bWrite)
- write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
+ /* jong: HW SI read must set reg84[3]=0. */
+ u1bTmp = read_nic_byte(dev, RFPinsSelect);
+ u1bTmp &= ~BIT3;
+ write_nic_byte(dev, RFPinsSelect, u1bTmp);
+ /* Fill up data buffer for write operation. */
- else
- write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
+ /* SI - reg274[3:0] : RF register's Address */
+ if (write)
+ write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
+ else
+ write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
+ /* Set up command: WE or RE. */
+ if (write)
+ write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
+ else
+ write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
- /* Check if DONE is set. */
- for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
- u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
- if ((u1bTmp & SW_3W_CMD1_DONE) != 0)
- break;
- udelay(10);
- }
+ /* Check if DONE is set. */
+ for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
+ u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
+ if (u1bTmp & SW_3W_CMD1_DONE)
+ break;
- write_nic_byte(dev, SW_3W_CMD1, 0);
+ udelay(10);
+ }
- /* Read back data for read operation. */
- if (bWrite == 0) {
- if (bSI) {
- /* Serial Interface : reg363_362[11:0] */
- *((u16 *)pDataBuf) = read_nic_word(dev, SI_DATA_READ) ;
- } else {
- /* Parallel Interface : reg361_360[11:0] */
- *((u16 *)pDataBuf) = read_nic_word(dev, PI_DATA_READ);
- }
+ write_nic_byte(dev, SW_3W_CMD1, 0);
- *((u16 *)pDataBuf) &= 0x0FFF;
- }
-
- } while (0);
+ /* Read back data for read operation. */
+ if (!write) {
+ /* Serial Interface : reg363_362[11:0] */
+ *((u16 *)pDataBuf) = read_nic_word(dev, SI_DATA_READ);
+ *((u16 *)pDataBuf) &= 0x0FFF;
+ }
- return bResult;
+ return true;
}
-void RF_WriteReg(struct net_device *dev, u8 offset, u32 data)
+void RF_WriteReg(struct net_device *dev, u8 offset, u16 data)
{
- u32 data2Write;
- u8 len;
-
- /* Pure HW 3-wire. */
- data2Write = (data << 4) | (u32)(offset & 0x0f);
- len = 16;
-
- HwHSSIThreeWire(dev, (u8 *)(&data2Write), len, 1, 1);
+ u16 reg = (data << 4) | (offset & 0x0f);
+ HwHSSIThreeWire(dev, (u8 *)&reg, true);
}
-u32 RF_ReadReg(struct net_device *dev, u8 offset)
+u16 RF_ReadReg(struct net_device *dev, u8 offset)
{
- u32 data2Write;
- u8 wlen;
- u32 dataRead;
-
- data2Write = ((u32)(offset & 0x0f));
- wlen = 16;
- HwHSSIThreeWire(dev, (u8 *)(&data2Write), wlen, 1, 0);
- dataRead = data2Write;
-
- return dataRead;
+ u16 reg = offset & 0x0f;
+ HwHSSIThreeWire(dev, (u8 *)&reg, false);
+ return reg;
}
@@ -472,7 +400,8 @@ void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev)
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
u32 i;
u32 addr, data;
- u32 u4bRegOffset, u4bRegValue, u4bRF23, u4bRF24;
+ u32 u4bRegOffset, u4bRegValue;
+ u16 u4bRF23, u4bRF24;
u8 u1b24E;
int d_cut = 0;
@@ -491,7 +420,7 @@ void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev)
if (u4bRF23 == 0x818 && u4bRF24 == 0x70C) {
d_cut = 1;
- printk(KERN_INFO "rtl8187se: card type changed from C- to D-cut\n");
+ netdev_info(dev, "card type changed from C- to D-cut\n");
}
/* Page0 : reg0-reg15 */
@@ -930,10 +859,7 @@ static void MacConfig_85BASIC(struct net_device *dev)
u8 GetSupportedWirelessMode8185(struct net_device *dev)
{
- u8 btSupportedWirelessMode = 0;
-
- btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
- return btSupportedWirelessMode;
+ return WIRELESS_MODE_B | WIRELESS_MODE_G;
}
void ActUpdateChannelAccessSetting(struct net_device *dev,
@@ -1130,13 +1056,13 @@ void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode)
ieee->mode = (WIRELESS_MODE)btWirelessMode;
/* 3. Change related setting. */
- if( ieee->mode == WIRELESS_MODE_A ) {
+ if (ieee->mode == WIRELESS_MODE_A)
DMESG("WIRELESS_MODE_A\n");
- } else if( ieee->mode == WIRELESS_MODE_B ) {
+ else if (ieee->mode == WIRELESS_MODE_B)
DMESG("WIRELESS_MODE_B\n");
- } else if( ieee->mode == WIRELESS_MODE_G ) {
+ else if (ieee->mode == WIRELESS_MODE_G)
DMESG("WIRELESS_MODE_G\n");
- }
+
ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting);
}
@@ -1148,18 +1074,11 @@ void rtl8185b_irq_enable(struct net_device *dev)
write_nic_dword(dev, IMR, priv->IntrMask);
}
-void DrvIFIndicateDisassociation(struct net_device *dev, u16 reason)
-{
- /* nothing is needed after disassociation request. */
-}
-
void MgntDisconnectIBSS(struct net_device *dev)
{
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
u8 i;
- DrvIFIndicateDisassociation(dev, unspec_reason);
-
for (i = 0; i < 6 ; i++)
priv->ieee80211->current_network.bssid[i] = 0x55;
@@ -1190,8 +1109,6 @@ void MlmeDisassociateRequest(struct net_device *dev, u8 *asSta, u8 asRsn)
if (memcmp(priv->ieee80211->current_network.bssid, asSta, 6) == 0) {
/* ShuChen TODO: change media status. */
- /* ShuChen TODO: What to do when disassociate. */
- DrvIFIndicateDisassociation(dev, unspec_reason);
for (i = 0; i < 6; i++)
priv->ieee80211->current_network.bssid[i] = 0x22;
@@ -1267,14 +1184,6 @@ bool SetRFPowerState(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState)
return bResult;
}
-void HalEnableRx8185Dummy(struct net_device *dev)
-{
-}
-
-void HalDisableRx8185Dummy(struct net_device *dev)
-{
-}
-
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);
@@ -1323,11 +1232,9 @@ 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 && !priv->bInHctTest)
+ if (rtState == eRfOff && ChangeSource >= RF_CHANGE_BY_HW)
bConnectBySSID = true;
-
- } else
- ;
+ }
break;
case eRfOff:
@@ -1359,18 +1266,6 @@ bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u
if (bActionAllowed) {
/* Config HW to the specified mode. */
SetRFPowerState(dev, StateToSet);
-
- /* Turn on RF. */
- if (StateToSet == eRfOn) {
- HalEnableRx8185Dummy(dev);
- if (bConnectBySSID) {
- /* by amy not supported */
- }
- }
- /* Turn off RF. */
- else if (StateToSet == eRfOff)
- HalDisableRx8185Dummy(dev);
-
}
/* Release RF spinlock */
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
index 81134d312ee..1a70f324552 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
@@ -82,7 +82,7 @@ static struct rtl819x_ops rtl819xp_ops = {
.RxCheckStuckHandler = rtl8192_HalRxCheckStuck,
};
-static struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = {
+static struct pci_device_id rtl8192_pci_id_tbl[] = {
{RTL_PCI_DEVICE(0x10ec, 0x8192, rtl819xp_ops)},
{RTL_PCI_DEVICE(0x07aa, 0x0044, rtl819xp_ops)},
{RTL_PCI_DEVICE(0x07aa, 0x0047, rtl819xp_ops)},
@@ -91,15 +91,15 @@ static struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl);
-static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
+static int rtl8192_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id);
-static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev);
+static void rtl8192_pci_disconnect(struct pci_dev *pdev);
static struct pci_driver rtl8192_pci_driver = {
.name = DRV_NAME, /* Driver name */
.id_table = rtl8192_pci_id_tbl, /* PCI_ID table */
.probe = rtl8192_pci_probe, /* probe fn */
- .remove = __devexit_p(rtl8192_pci_disconnect), /* remove fn */
+ .remove = rtl8192_pci_disconnect, /* remove fn */
.suspend = rtl8192E_suspend, /* PM suspend fn */
.resume = rtl8192E_resume, /* PM resume fn */
};
@@ -2846,7 +2846,7 @@ static const struct net_device_ops rtl8192_netdev_ops = {
.ndo_start_xmit = rtllib_xmit,
};
-static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
+static int rtl8192_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
unsigned long ioaddr = 0;
@@ -2955,7 +2955,8 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
netif_carrier_off(dev);
netif_stop_queue(dev);
- register_netdev(dev);
+ if (register_netdev(dev))
+ goto err_free_irq;
RT_TRACE(COMP_INIT, "dev name: %s\n", dev->name);
rtl8192_proc_init_one(dev);
@@ -2981,7 +2982,7 @@ err_pci_disable:
return err;
}
-static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev)
+static void rtl8192_pci_disconnect(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct r8192_priv *priv ;
diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h
index 9ac8d8ea4ae..3485ef1dfab 100644
--- a/drivers/staging/rtl8192e/rtllib.h
+++ b/drivers/staging/rtl8192e/rtllib.h
@@ -2567,7 +2567,7 @@ static inline void *rtllib_priv(struct net_device *dev)
return ((struct rtllib_device *)netdev_priv(dev))->priv;
}
-extern inline int rtllib_is_empty_essid(const char *essid, int essid_len)
+static inline int rtllib_is_empty_essid(const char *essid, int essid_len)
{
/* Single white space is for Linksys APs */
if (essid_len == 1 && essid[0] == ' ')
@@ -2583,7 +2583,7 @@ extern inline int rtllib_is_empty_essid(const char *essid, int essid_len)
return 1;
}
-extern inline int rtllib_is_valid_mode(struct rtllib_device *ieee, int mode)
+static inline int rtllib_is_valid_mode(struct rtllib_device *ieee, int mode)
{
/*
* It is possible for both access points and our device to support
@@ -2609,7 +2609,7 @@ extern inline int rtllib_is_valid_mode(struct rtllib_device *ieee, int mode)
return 0;
}
-extern inline int rtllib_get_hdrlen(u16 fc)
+static inline int rtllib_get_hdrlen(u16 fc)
{
int hdrlen = RTLLIB_3ADDR_LEN;
diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c
index 42900ee4825..759d7c7d78e 100644
--- a/drivers/staging/rtl8192e/rtllib_tx.c
+++ b/drivers/staging/rtl8192e/rtllib_tx.c
@@ -287,7 +287,7 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee,
{
struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
struct tx_ts_record *pTxTs = NULL;
- struct rtllib_hdr_1addr* hdr = (struct rtllib_hdr_1addr *)skb->data;
+ struct rtllib_hdr_1addr *hdr = (struct rtllib_hdr_1addr *)skb->data;
if (rtllib_act_scanning(ieee, false))
return;
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
index 13f45c3125c..502bfdbcc84 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
@@ -235,7 +235,10 @@ enum _ReasonCode{
-#define aSifsTime ((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 10
+#define aSifsTime ((priv->ieee80211->current_network.mode == IEEE_A || \
+ priv->ieee80211->current_network.mode == IEEE_N_24G || \
+ priv->ieee80211->current_network.mode == IEEE_N_5G) ? \
+ 16 : 10)
#define MGMT_QUEUE_NUM 5
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c
index 5a2fab9fa77..56367f23112 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -144,9 +144,9 @@ MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
-static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
+static int rtl8192_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id);
-static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
+static void rtl8192_usb_disconnect(struct usb_interface *intf);
static struct usb_driver rtl8192_usb_driver = {
@@ -5739,7 +5739,7 @@ static const struct net_device_ops rtl8192_netdev_ops = {
---------------------------- USB_STUFF---------------------------
*****************************************************************************/
-static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
+static int rtl8192_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
// unsigned long ioaddr = 0;
@@ -5826,7 +5826,7 @@ void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
}
-static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
+static void rtl8192_usb_disconnect(struct usb_interface *intf)
{
struct net_device *dev = usb_get_intfdata(intf);
diff --git a/drivers/staging/rtl8712/mlme_linux.c b/drivers/staging/rtl8712/mlme_linux.c
index abf96c14df9..7279854c86a 100644
--- a/drivers/staging/rtl8712/mlme_linux.c
+++ b/drivers/staging/rtl8712/mlme_linux.c
@@ -156,7 +156,7 @@ void r8712_report_sec_ie(struct _adapter *adapter, u8 authmode, u8 *sec_ie)
p = buff;
p += sprintf(p, "ASSOCINFO(ReqIEs=");
len = sec_ie[1] + 2;
- len = (len < IW_CUSTOM_MAX) ? len : IW_CUSTOM_MAX;
+ len = (len < IW_CUSTOM_MAX) ? len : IW_CUSTOM_MAX - 1;
for (i = 0; i < len; i++)
p += sprintf(p, "%02x", sec_ie[i]);
p += sprintf(p, ")");
diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c
index 659683e022b..31f31dbf7f3 100644
--- a/drivers/staging/rtl8712/rtl871x_cmd.c
+++ b/drivers/staging/rtl8712/rtl871x_cmd.c
@@ -814,7 +814,7 @@ u8 r8712_setassocsta_cmd(struct _adapter *padapter, u8 *mac_addr)
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
struct cmd_obj *ph2c;
struct set_assocsta_parm *psetassocsta_para;
- struct set_stakey_rsp *psetassocsta_rsp = NULL;
+ struct set_assocsta_rsp *psetassocsta_rsp = NULL;
ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
if (ph2c == NULL)
@@ -825,7 +825,7 @@ u8 r8712_setassocsta_cmd(struct _adapter *padapter, u8 *mac_addr)
kfree((u8 *) ph2c);
return _FAIL;
}
- psetassocsta_rsp = (struct set_stakey_rsp *)_malloc(
+ psetassocsta_rsp = (struct set_assocsta_rsp *)_malloc(
sizeof(struct set_assocsta_rsp));
if (psetassocsta_rsp == NULL) {
kfree((u8 *)ph2c);
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
index c9a6a7fbb89..3a647906451 100644
--- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
@@ -2110,10 +2110,10 @@ static int r871x_wps_start(struct net_device *dev,
struct iw_point *pdata = &wrqu->data;
u32 u32wps_start = 0;
- if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
- return -EFAULT;
if ((padapter->bDriverStopped) || (pdata == NULL))
return -EINVAL;
+ if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
+ return -EFAULT;
if (u32wps_start == 0)
u32wps_start = *extra;
if (u32wps_start == 1) /* WPS Start */
diff --git a/drivers/staging/rts5139/Makefile b/drivers/staging/rts5139/Makefile
index 82b8958e8d3..75dd31224e6 100644
--- a/drivers/staging/rts5139/Makefile
+++ b/drivers/staging/rts5139/Makefile
@@ -25,13 +25,19 @@
# Makefile for the RTS51xx USB Card Reader drivers.
#
-TARGET_MODULE := rts5139
+obj-$(CONFIG_RTS5139) := rts5139.o
-EXTRA_CFLAGS := -Idrivers/scsi -I$(PWD)
+ccflags-y := -Idrivers/scsi
-obj-m += $(TARGET_MODULE).o
-
-common-obj := rts51x_transport.o rts51x_scsi.o rts51x_fop.o
-
-$(TARGET_MODULE)-objs := $(common-obj) rts51x.o rts51x_chip.o rts51x_card.o \
- xd.o sd.o ms.o sd_cprm.o ms_mg.o
+rts5139-y := \
+ rts51x_transport.o \
+ rts51x_scsi.o \
+ rts51x_fop.o \
+ rts51x.o \
+ rts51x_chip.o \
+ rts51x_card.o \
+ xd.o \
+ sd.o \
+ ms.o \
+ sd_cprm.o \
+ ms_mg.o
diff --git a/drivers/staging/rts5139/ms.c b/drivers/staging/rts5139/ms.c
index 6eef33b03f5..a27f7e224e0 100644
--- a/drivers/staging/rts5139/ms.c
+++ b/drivers/staging/rts5139/ms.c
@@ -160,7 +160,7 @@ int ms_transfer_data(struct rts51x_chip *chip, u8 trans_mode, u8 tpc,
rts51x_add_cmd(chip, WRITE_REG_CMD, MS_CFG, MS_2K_SECTOR_MODE,
0);
- trans_dma_enable(dir, chip, sec_cnt * 512, DMA_512);
+ rts51x_trans_dma_enable(dir, chip, sec_cnt * 512, DMA_512);
rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF,
MS_TRANSFER_START | trans_mode);
@@ -602,7 +602,7 @@ static int ms_prepare_reset(struct rts51x_chip *chip)
if (!chip->option.FT2_fast_mode) {
wait_timeout(250);
- card_power_on(chip, MS_CARD);
+ rts51x_card_power_on(chip, MS_CARD);
wait_timeout(150);
#ifdef SUPPORT_OCP
@@ -872,7 +872,7 @@ static int msxc_change_power(struct rts51x_chip *chip, u8 mode)
int retval;
u8 buf[6];
- ms_cleanup_work(chip);
+ rts51x_ms_cleanup_work(chip);
/* Set Parameter Register */
retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6);
@@ -2600,14 +2600,14 @@ BUILD_FAIL:
return STATUS_FAIL;
}
-int reset_ms_card(struct rts51x_chip *chip)
+int rts51x_reset_ms_card(struct rts51x_chip *chip)
{
struct ms_info *ms_card = &(chip->ms_card);
int retval;
memset(ms_card, 0, sizeof(struct ms_info));
- enable_card_clock(chip, MS_CARD);
+ rts51x_enable_card_clock(chip, MS_CARD);
retval = rts51x_select_card(chip, MS_CARD);
if (retval != STATUS_SUCCESS)
@@ -2936,7 +2936,7 @@ static int mspro_read_format_progress(struct rts51x_chip *chip,
return STATUS_SUCCESS;
}
-void mspro_polling_format_status(struct rts51x_chip *chip)
+void rts51x_mspro_polling_format_status(struct rts51x_chip *chip)
{
struct ms_info *ms_card = &(chip->ms_card);
int i;
@@ -2952,25 +2952,25 @@ void mspro_polling_format_status(struct rts51x_chip *chip)
return;
}
-void mspro_format_sense(struct rts51x_chip *chip, unsigned int lun)
+void rts51x_mspro_format_sense(struct rts51x_chip *chip, unsigned int lun)
{
struct ms_info *ms_card = &(chip->ms_card);
if (CHK_FORMAT_STATUS(ms_card, FORMAT_SUCCESS)) {
- set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
ms_card->pro_under_formatting = 0;
ms_card->progress = 0;
} else if (CHK_FORMAT_STATUS(ms_card, FORMAT_IN_PROGRESS)) {
- set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04,
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04,
0, (u16) (ms_card->progress));
} else {
- set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED);
ms_card->pro_under_formatting = 0;
ms_card->progress = 0;
}
}
-int mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip,
+int rts51x_mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip,
int short_data_len, int quick_format)
{
struct ms_info *ms_card = &(chip->ms_card);
@@ -3035,7 +3035,7 @@ int mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip,
ms_card->pro_under_formatting = 0;
ms_card->progress = 0;
ms_card->format_status = FORMAT_SUCCESS;
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_NO_SENSE);
+ rts51x_set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_NO_SENSE);
return STATUS_SUCCESS;
}
@@ -3103,7 +3103,7 @@ static int ms_read_multiple_pages(struct rts51x_chip *chip, u16 phy_blk,
rts51x_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_H, 0xFF, 0);
rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, READ_PAGE_DATA);
- trans_dma_enable(DMA_FROM_DEVICE, chip, 512 * page_cnt, DMA_512);
+ rts51x_trans_dma_enable(DMA_FROM_DEVICE, chip, 512 * page_cnt, DMA_512);
rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF,
MS_TRANSFER_START | MS_TM_MULTI_READ);
@@ -3307,7 +3307,7 @@ static int ms_write_multiple_pages(struct rts51x_chip *chip, u16 old_blk,
rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01,
RING_BUFFER);
- trans_dma_enable(DMA_TO_DEVICE, chip, 512 * page_cnt, DMA_512);
+ rts51x_trans_dma_enable(DMA_TO_DEVICE, chip, 512 * page_cnt, DMA_512);
rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF,
MS_TRANSFER_START | MS_TM_MULTI_WRITE);
@@ -3467,7 +3467,7 @@ static int ms_read_multiple_pages(struct rts51x_chip *chip, u16 phy_blk,
rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF,
trans_cfg);
- trans_dma_enable(DMA_FROM_DEVICE, chip, 512, DMA_512);
+ rts51x_trans_dma_enable(DMA_FROM_DEVICE, chip, 512, DMA_512);
rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF,
MS_TRANSFER_START | MS_TM_NORMAL_READ);
@@ -3670,7 +3670,7 @@ static int ms_write_multiple_pages(struct rts51x_chip *chip, u16 old_blk,
rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF,
WAIT_INT);
- trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512);
+ rts51x_trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512);
rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF,
MS_TRANSFER_START | MS_TM_NORMAL_WRITE);
@@ -3803,10 +3803,10 @@ static int ms_prepare_write(struct rts51x_chip *chip, u16 old_blk, u16 new_blk,
return STATUS_SUCCESS;
}
-int ms_delay_write(struct rts51x_chip *chip)
+int rts51x_ms_delay_write(struct rts51x_chip *chip)
{
struct ms_info *ms_card = &(chip->ms_card);
- struct ms_delay_write_tag *delay_write = &(ms_card->delay_write);
+ struct rts51x_ms_delay_write_tag *delay_write = &(ms_card->delay_write);
int retval;
if (delay_write->delay_write_flag) {
@@ -3827,16 +3827,16 @@ int ms_delay_write(struct rts51x_chip *chip)
return STATUS_SUCCESS;
}
-static inline void ms_rw_fail(struct scsi_cmnd *srb, struct rts51x_chip *chip)
+static inline void rts51x_ms_rw_fail(struct scsi_cmnd *srb, struct rts51x_chip *chip)
{
if (srb->sc_data_direction == DMA_FROM_DEVICE)
- set_sense_type(chip, SCSI_LUN(srb),
+ rts51x_set_sense_type(chip, SCSI_LUN(srb),
SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
else
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
+ rts51x_set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
}
-static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip,
+static int rts51x_ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip,
u32 start_sector, u16 sector_cnt)
{
struct ms_info *ms_card = &(chip->ms_card);
@@ -3847,7 +3847,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip,
u8 start_page, end_page = 0, page_cnt;
u8 *buf;
void *ptr = NULL;
- struct ms_delay_write_tag *delay_write = &(ms_card->delay_write);
+ struct rts51x_ms_delay_write_tag *delay_write = &(ms_card->delay_write);
ms_set_err_code(chip, MS_NO_ERROR);
@@ -3857,7 +3857,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip,
retval = ms_switch_clock(chip);
if (retval != STATUS_SUCCESS) {
- ms_rw_fail(srb, chip);
+ rts51x_ms_rw_fail(srb, chip);
TRACE_RET(chip, retval);
}
@@ -3873,7 +3873,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip,
retval = ms_build_l2p_tbl(chip, seg_no);
if (retval != STATUS_SUCCESS) {
chip->card_fail |= MS_CARD;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, retval);
}
}
@@ -3898,7 +3898,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip,
start_page);
#endif
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_WRITE_ERR);
TRACE_RET(chip, retval);
}
@@ -3911,9 +3911,9 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip,
old_blk = delay_write->old_phyblock;
new_blk = delay_write->new_phyblock;
} else {
- retval = ms_delay_write(chip);
+ retval = rts51x_ms_delay_write(chip);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_WRITE_ERR);
TRACE_RET(chip, retval);
}
@@ -3922,7 +3922,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip,
log_blk - ms_start_idx[seg_no]);
new_blk = ms_get_unused_block(chip, seg_no);
if ((old_blk == 0xFFFF) || (new_blk == 0xFFFF)) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_WRITE_ERR);
TRACE_RET(chip, STATUS_FAIL);
}
@@ -3933,26 +3933,26 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip,
if (retval != STATUS_SUCCESS) {
if (monitor_card_cd(chip, MS_CARD) ==
CD_NOT_EXIST) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, STATUS_FAIL);
}
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_WRITE_ERR);
TRACE_RET(chip, retval);
}
}
} else {
- retval = ms_delay_write(chip);
+ retval = rts51x_ms_delay_write(chip);
if (retval != STATUS_SUCCESS) {
if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, STATUS_FAIL);
}
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
TRACE_RET(chip, retval);
}
@@ -3960,7 +3960,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip,
ms_get_l2p_tbl(chip, seg_no,
log_blk - ms_start_idx[seg_no]);
if (old_blk == 0xFFFF) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
TRACE_RET(chip, STATUS_FAIL);
}
@@ -3993,12 +3993,12 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip,
if (retval != STATUS_SUCCESS) {
if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, STATUS_FAIL);
}
- ms_rw_fail(srb, chip);
+ rts51x_ms_rw_fail(srb, chip);
TRACE_RET(chip, retval);
}
/* Update L2P table if need */
@@ -4030,7 +4030,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip,
retval = ms_build_l2p_tbl(chip, seg_no);
if (retval != STATUS_SUCCESS) {
chip->card_fail |= MS_CARD;
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, retval);
}
@@ -4040,14 +4040,14 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip,
ms_get_l2p_tbl(chip, seg_no,
log_blk - ms_start_idx[seg_no]);
if (old_blk == 0xFFFF) {
- ms_rw_fail(srb, chip);
+ rts51x_ms_rw_fail(srb, chip);
TRACE_RET(chip, STATUS_FAIL);
}
if (srb->sc_data_direction == DMA_TO_DEVICE) {
new_blk = ms_get_unused_block(chip, seg_no);
if (new_blk == 0xFFFF) {
- ms_rw_fail(srb, chip);
+ rts51x_ms_rw_fail(srb, chip);
TRACE_RET(chip, STATUS_FAIL);
}
}
@@ -4073,7 +4073,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip,
return STATUS_SUCCESS;
}
-int ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
+int rts51x_ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
u16 sector_cnt)
{
struct ms_info *ms_card = &(chip->ms_card);
@@ -4084,12 +4084,12 @@ int ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
mspro_rw_multi_sector(srb, chip, start_sector, sector_cnt);
else
retval =
- ms_rw_multi_sector(srb, chip, start_sector, sector_cnt);
+ rts51x_ms_rw_multi_sector(srb, chip, start_sector, sector_cnt);
return retval;
}
-void ms_free_l2p_tbl(struct rts51x_chip *chip)
+void rts51x_ms_free_l2p_tbl(struct rts51x_chip *chip)
{
struct ms_info *ms_card = &(chip->ms_card);
int i = 0;
@@ -4110,7 +4110,7 @@ void ms_free_l2p_tbl(struct rts51x_chip *chip)
}
}
-void ms_cleanup_work(struct rts51x_chip *chip)
+void rts51x_ms_cleanup_work(struct rts51x_chip *chip)
{
struct ms_info *ms_card = &(chip->ms_card);
@@ -4130,7 +4130,7 @@ void ms_cleanup_work(struct rts51x_chip *chip)
} else if ((!CHK_MSPRO(ms_card))
&& ms_card->delay_write.delay_write_flag) {
RTS51X_DEBUGP("MS: delay write\n");
- ms_delay_write(chip);
+ rts51x_ms_delay_write(chip);
ms_card->counter = 0;
}
}
@@ -4161,12 +4161,12 @@ static int ms_power_off_card3v3(struct rts51x_chip *chip)
return STATUS_SUCCESS;
}
-int release_ms_card(struct rts51x_chip *chip)
+int rts51x_release_ms_card(struct rts51x_chip *chip)
{
struct ms_info *ms_card = &(chip->ms_card);
int retval;
- RTS51X_DEBUGP("release_ms_card\n");
+ RTS51X_DEBUGP("rts51x_release_ms_card\n");
ms_card->delay_write.delay_write_flag = 0;
ms_card->pro_under_formatting = 0;
@@ -4175,7 +4175,7 @@ int release_ms_card(struct rts51x_chip *chip)
chip->card_fail &= ~MS_CARD;
chip->card_wp &= ~MS_CARD;
- ms_free_l2p_tbl(chip);
+ rts51x_ms_free_l2p_tbl(chip);
rts51x_write_register(chip, SFSM_ED, HW_CMD_STOP, HW_CMD_STOP);
diff --git a/drivers/staging/rts5139/ms.h b/drivers/staging/rts5139/ms.h
index 0321d06e776..857c1974ef2 100644
--- a/drivers/staging/rts5139/ms.h
+++ b/drivers/staging/rts5139/ms.h
@@ -231,18 +231,18 @@
(((retval) != STATUS_SUCCESS) || \
(chip->rsp_buf[0] & MS_TRANSFER_ERR))
-void mspro_polling_format_status(struct rts51x_chip *chip);
-void mspro_format_sense(struct rts51x_chip *chip, unsigned int lun);
+void rts51x_mspro_polling_format_status(struct rts51x_chip *chip);
+void rts51x_mspro_format_sense(struct rts51x_chip *chip, unsigned int lun);
-int reset_ms_card(struct rts51x_chip *chip);
-int ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
+int rts51x_reset_ms_card(struct rts51x_chip *chip);
+int rts51x_ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
u16 sector_cnt);
-int mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip,
+int rts51x_mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip,
int short_data_len, int quick_format);
-void ms_free_l2p_tbl(struct rts51x_chip *chip);
-void ms_cleanup_work(struct rts51x_chip *chip);
-int release_ms_card(struct rts51x_chip *chip);
-int ms_delay_write(struct rts51x_chip *chip);
+void rts51x_ms_free_l2p_tbl(struct rts51x_chip *chip);
+void rts51x_ms_cleanup_work(struct rts51x_chip *chip);
+int rts51x_release_ms_card(struct rts51x_chip *chip);
+int rts51x_ms_delay_write(struct rts51x_chip *chip);
#ifdef SUPPORT_MAGIC_GATE
diff --git a/drivers/staging/rts5139/ms_mg.c b/drivers/staging/rts5139/ms_mg.c
index 057d96c1a93..54cfd85259a 100644
--- a/drivers/staging/rts5139/ms_mg.c
+++ b/drivers/staging/rts5139/ms_mg.c
@@ -119,7 +119,7 @@ int mg_set_tpc_para_sub(struct rts51x_chip *chip, int type, u8 mg_entry_num)
* 2. send SET_ID TPC command to medium with Leaf ID released by host
* in this SCSI CMD.
*/
-int mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip)
+int rts51x_mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip)
{
int retval;
int i;
@@ -129,10 +129,10 @@ int mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip)
RTS51X_DEBUGP("--%s--\n", __func__);
if (scsi_bufflen(srb) < 12) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, STATUS_FAIL);
}
- ms_cleanup_work(chip);
+ rts51x_ms_cleanup_work(chip);
retval = ms_switch_clock(chip);
if (retval != STATUS_SUCCESS)
@@ -140,7 +140,7 @@ int mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip)
retval = mg_send_ex_cmd(chip, MG_SET_LID, 0);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
TRACE_RET(chip, retval);
}
@@ -151,12 +151,12 @@ int mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip)
retval =
ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf1, 32);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
TRACE_RET(chip, retval);
}
retval = mg_check_int_error(chip);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
TRACE_RET(chip, retval);
}
@@ -170,7 +170,7 @@ int mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip)
* data(1536 bytes totally) from medium by using READ_LONG_DATA TPC
* for 3 times, and report data to host with data-length is 1052 bytes.
*/
-int mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip)
+int rts51x_mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip)
{
int retval = STATUS_FAIL;
int bufflen;
@@ -179,7 +179,7 @@ int mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip)
RTS51X_DEBUGP("--%s--\n", __func__);
- ms_cleanup_work(chip);
+ rts51x_ms_cleanup_work(chip);
retval = ms_switch_clock(chip);
if (retval != STATUS_SUCCESS)
@@ -196,21 +196,21 @@ int mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip)
retval = mg_send_ex_cmd(chip, MG_GET_LEKB, 0);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
TRACE_GOTO(chip, GetEKBFinish);
}
retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA,
3, WAIT_INT, 0, 0, buf + 4, 1536);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
rts51x_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR,
MS_STOP | MS_CLR_ERR);
TRACE_GOTO(chip, GetEKBFinish);
}
retval = mg_check_int_error(chip);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
TRACE_GOTO(chip, GetEKBFinish);
}
@@ -229,7 +229,7 @@ GetEKBFinish:
* TPC commands to the medium for writing 8-bytes data as challenge
* by host within a short data packet.
*/
-int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip)
+int rts51x_mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip)
{
struct ms_info *ms_card = &(chip->ms_card);
int retval;
@@ -240,7 +240,7 @@ int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip)
RTS51X_DEBUGP("--%s--\n", __func__);
- ms_cleanup_work(chip);
+ rts51x_ms_cleanup_work(chip);
retval = ms_switch_clock(chip);
if (retval != STATUS_SUCCESS)
@@ -248,19 +248,19 @@ int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip)
retval = mg_send_ex_cmd(chip, MG_GET_ID, 0);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
TRACE_RET(chip, retval);
}
retval =
ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, buf, 32);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
TRACE_RET(chip, retval);
}
retval = mg_check_int_error(chip);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
TRACE_RET(chip, retval);
}
@@ -276,13 +276,13 @@ int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip)
}
if (i == 2500) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
TRACE_RET(chip, STATUS_FAIL);
}
retval = mg_send_ex_cmd(chip, MG_SET_RD, 0);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
TRACE_RET(chip, retval);
}
@@ -296,12 +296,12 @@ int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip)
retval =
ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf, 32);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
TRACE_RET(chip, retval);
}
retval = mg_check_int_error(chip);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
TRACE_RET(chip, retval);
}
@@ -320,7 +320,7 @@ int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip)
* The paremeter MagicGateID is the one that adapter has obtained from
* the medium by TPC commands in Set Leaf ID command phase previously.
*/
-int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip)
+int rts51x_mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip)
{
struct ms_info *ms_card = &(chip->ms_card);
int retval, i;
@@ -330,7 +330,7 @@ int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip)
RTS51X_DEBUGP("--%s--\n", __func__);
- ms_cleanup_work(chip);
+ rts51x_ms_cleanup_work(chip);
retval = ms_switch_clock(chip);
if (retval != STATUS_SUCCESS)
@@ -338,19 +338,19 @@ int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip)
retval = mg_send_ex_cmd(chip, MG_MAKE_RMS, 0);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
TRACE_RET(chip, retval);
}
retval =
ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, buf1, 32);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
TRACE_RET(chip, retval);
}
retval = mg_check_int_error(chip);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
TRACE_RET(chip, retval);
}
@@ -375,7 +375,7 @@ int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip)
}
if (i == 2500) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
TRACE_RET(chip, STATUS_FAIL);
}
@@ -389,7 +389,7 @@ int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip)
* issues TPC commands to the medium for writing 8-bytes data as
* challenge by host within a short data packet.
*/
-int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip)
+int rts51x_mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip)
{
struct ms_info *ms_card = &(chip->ms_card);
int retval;
@@ -400,7 +400,7 @@ int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip)
RTS51X_DEBUGP("--%s--\n", __func__);
- ms_cleanup_work(chip);
+ rts51x_ms_cleanup_work(chip);
retval = ms_switch_clock(chip);
if (retval != STATUS_SUCCESS)
@@ -408,7 +408,7 @@ int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip)
retval = mg_send_ex_cmd(chip, MG_MAKE_KSE, 0);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
TRACE_RET(chip, retval);
}
@@ -422,12 +422,12 @@ int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip)
retval =
ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf, 32);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
TRACE_RET(chip, retval);
}
retval = mg_check_int_error(chip);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
TRACE_RET(chip, retval);
}
@@ -447,7 +447,7 @@ int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip)
* precedes data transmission from medium to Ring buffer by DMA mechanism
* in order to get maximum performance and minimum code size simultaneously.
*/
-int mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip)
+int rts51x_mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip)
{
struct ms_info *ms_card = &(chip->ms_card);
int retval;
@@ -457,7 +457,7 @@ int mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip)
RTS51X_DEBUGP("--%s--\n", __func__);
- ms_cleanup_work(chip);
+ rts51x_ms_cleanup_work(chip);
retval = ms_switch_clock(chip);
if (retval != STATUS_SUCCESS)
@@ -474,21 +474,21 @@ int mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip)
retval = mg_send_ex_cmd(chip, MG_GET_IBD, ms_card->mg_entry_num);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
TRACE_GOTO(chip, GetICVFinish);
}
retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA,
2, WAIT_INT, 0, 0, buf + 4, 1024);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
rts51x_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR,
MS_STOP | MS_CLR_ERR);
TRACE_GOTO(chip, GetICVFinish);
}
retval = mg_check_int_error(chip);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
TRACE_GOTO(chip, GetICVFinish);
}
@@ -511,7 +511,7 @@ GetICVFinish:
* that sent by host, and it should be skipped by shifting DMA pointer
* before writing 1024 bytes to medium.
*/
-int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip)
+int rts51x_mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip)
{
struct ms_info *ms_card = &(chip->ms_card);
int retval;
@@ -524,7 +524,7 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip)
RTS51X_DEBUGP("--%s--\n", __func__);
- ms_cleanup_work(chip);
+ rts51x_ms_cleanup_work(chip);
retval = ms_switch_clock(chip);
if (retval != STATUS_SUCCESS)
@@ -541,13 +541,13 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip)
if (retval != STATUS_SUCCESS) {
if (ms_card->mg_auth == 0) {
if ((buf[5] & 0xC0) != 0)
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
else
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MG_WRITE_ERR);
} else {
- set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR);
}
TRACE_GOTO(chip, SetICVFinish);
}
@@ -563,7 +563,7 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip)
rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF,
WAIT_INT);
- trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512);
+ rts51x_trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512);
rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF,
MS_TRANSFER_START | MS_TM_NORMAL_WRITE);
@@ -572,7 +572,7 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip)
retval = rts51x_send_cmd(chip, MODE_CDOR, 100);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR);
TRACE_GOTO(chip, SetICVFinish);
}
@@ -583,13 +583,13 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip)
rts51x_clear_ms_error(chip);
if (ms_card->mg_auth == 0) {
if ((buf[5] & 0xC0) != 0)
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
else
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MG_WRITE_ERR);
} else {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MG_WRITE_ERR);
}
retval = STATUS_FAIL;
@@ -602,13 +602,13 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip)
rts51x_clear_ms_error(chip);
if (ms_card->mg_auth == 0) {
if ((buf[5] & 0xC0) != 0)
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
else
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MG_WRITE_ERR);
} else {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MG_WRITE_ERR);
}
retval = STATUS_FAIL;
@@ -622,13 +622,13 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip)
rts51x_clear_ms_error(chip);
if (ms_card->mg_auth == 0) {
if ((buf[5] & 0xC0) != 0)
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
else
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MG_WRITE_ERR);
} else {
- set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR);
}
TRACE_GOTO(chip, SetICVFinish);
}
diff --git a/drivers/staging/rts5139/ms_mg.h b/drivers/staging/rts5139/ms_mg.h
index e2ca55085f9..d15733a992a 100644
--- a/drivers/staging/rts5139/ms_mg.h
+++ b/drivers/staging/rts5139/ms_mg.h
@@ -30,12 +30,12 @@
#include "rts51x_chip.h"
#include "ms.h"
-int mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip);
-int mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip);
-int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip);
-int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip);
-int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip);
-int mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip);
-int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip);
+int rts51x_mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip);
+int rts51x_mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip);
+int rts51x_mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip);
+int rts51x_mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip);
+int rts51x_mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip);
+int rts51x_mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip);
+int rts51x_mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip);
#endif /* __RTS51X_MS_MG_H */
diff --git a/drivers/staging/rts5139/rts51x.c b/drivers/staging/rts5139/rts51x.c
index c3fe7dda1f4..04213463123 100644
--- a/drivers/staging/rts5139/rts51x.c
+++ b/drivers/staging/rts5139/rts51x.c
@@ -306,7 +306,7 @@ static int rts51x_control_thread(void *__chip)
/* we've got a command, let's do it! */
else {
- RTS51X_DEBUG(scsi_show_command(chip->srb));
+ RTS51X_DEBUG(rts51x_scsi_show_command(chip->srb));
rts51x_invoke_transport(chip->srb, chip);
}
@@ -397,7 +397,7 @@ static int rts51x_polling_thread(void *__chip)
}
#endif
- mspro_polling_format_status(chip);
+ rts51x_mspro_polling_format_status(chip);
/* lock the device pointers */
mutex_lock(&(chip->usb->dev_mutex));
@@ -478,7 +478,7 @@ static void rts51x_init_options(struct rts51x_chip *chip)
{
struct rts51x_option *option = &(chip->option);
- option->mspro_formatter_enable = 1;
+ option->rts51x_mspro_formatter_enable = 1;
option->fpga_sd_sdr104_clk = CLK_100;
option->fpga_sd_sdr50_clk = CLK_100;
@@ -510,7 +510,7 @@ static void rts51x_init_options(struct rts51x_chip *chip)
option->FT2_fast_mode = 0;
option->pwr_delay = 800;
- option->xd_rw_step = 0;
+ option->rts51x_xd_rw_step = 0;
option->D3318_off_delay = 50;
option->delink_delay = 100;
option->rts5129_D3318_off_enable = 0;
@@ -518,7 +518,7 @@ static void rts51x_init_options(struct rts51x_chip *chip)
option->reset_or_rw_fail_set_pad_drive = 1;
option->debounce_num = 2;
option->led_toggle_interval = 6;
- option->xd_rwn_step = 0;
+ option->rts51x_xd_rwn_step = 0;
option->sd_send_status_en = 0;
option->sdr50_tx_phase = 0x01;
option->sdr50_rx_phase = 0x05;
diff --git a/drivers/staging/rts5139/rts51x_card.c b/drivers/staging/rts5139/rts51x_card.c
index 50be42ac592..509d83e623a 100644
--- a/drivers/staging/rts5139/rts51x_card.c
+++ b/drivers/staging/rts5139/rts51x_card.c
@@ -41,7 +41,7 @@
#include "sd.h"
#include "ms.h"
-void do_remaining_work(struct rts51x_chip *chip)
+void rts51x_do_remaining_work(struct rts51x_chip *chip)
{
struct sd_info *sd_card = &(chip->sd_card);
struct xd_info *xd_card = &(chip->xd_card);
@@ -84,27 +84,27 @@ void do_remaining_work(struct rts51x_chip *chip)
}
if (sd_card->counter > POLLING_WAIT_CNT)
- sd_cleanup_work(chip);
+ rts51x_sd_cleanup_work(chip);
if (xd_card->counter > POLLING_WAIT_CNT)
- xd_cleanup_work(chip);
+ rts51x_xd_cleanup_work(chip);
if (ms_card->counter > POLLING_WAIT_CNT)
- ms_cleanup_work(chip);
+ rts51x_ms_cleanup_work(chip);
}
-static void do_reset_xd_card(struct rts51x_chip *chip)
+static void do_rts51x_reset_xd_card(struct rts51x_chip *chip)
{
int retval;
if (chip->card2lun[XD_CARD] >= MAX_ALLOWED_LUN_CNT)
return;
- retval = reset_xd_card(chip);
+ retval = rts51x_reset_xd_card(chip);
if (retval == STATUS_SUCCESS) {
chip->card_ready |= XD_CARD;
chip->card_fail &= ~XD_CARD;
- chip->rw_card[chip->card2lun[XD_CARD]] = xd_rw;
+ chip->rw_card[chip->card2lun[XD_CARD]] = rts51x_xd_rw;
} else {
chip->card_ready &= ~XD_CARD;
chip->card_fail |= XD_CARD;
@@ -120,18 +120,18 @@ static void do_reset_xd_card(struct rts51x_chip *chip)
}
}
-void do_reset_sd_card(struct rts51x_chip *chip)
+void rts51x_do_rts51x_reset_sd_card(struct rts51x_chip *chip)
{
int retval;
if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT)
return;
- retval = reset_sd_card(chip);
+ retval = rts51x_reset_sd_card(chip);
if (retval == STATUS_SUCCESS) {
chip->card_ready |= SD_CARD;
chip->card_fail &= ~SD_CARD;
- chip->rw_card[chip->card2lun[SD_CARD]] = sd_rw;
+ chip->rw_card[chip->card2lun[SD_CARD]] = rts51x_sd_rw;
} else {
chip->card_ready &= ~SD_CARD;
chip->card_fail |= SD_CARD;
@@ -147,18 +147,18 @@ void do_reset_sd_card(struct rts51x_chip *chip)
}
}
-static void do_reset_ms_card(struct rts51x_chip *chip)
+static void do_rts51x_reset_ms_card(struct rts51x_chip *chip)
{
int retval;
if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT)
return;
- retval = reset_ms_card(chip);
+ retval = rts51x_reset_ms_card(chip);
if (retval == STATUS_SUCCESS) {
chip->card_ready |= MS_CARD;
chip->card_fail &= ~MS_CARD;
- chip->rw_card[chip->card2lun[MS_CARD]] = ms_rw;
+ chip->rw_card[chip->card2lun[MS_CARD]] = rts51x_ms_rw;
} else {
chip->card_ready &= ~MS_CARD;
chip->card_fail |= MS_CARD;
@@ -301,7 +301,7 @@ void rts51x_init_cards(struct rts51x_chip *chip)
chip->card_exist &= ~XD_CARD;
chip->card_ejected = 0;
if (chip->card_ready & XD_CARD) {
- release_xd_card(chip);
+ rts51x_release_xd_card(chip);
chip->rw_card[chip->card2lun[XD_CARD]] = NULL;
clear_bit(chip->card2lun[XD_CARD],
&(chip->lun_mc));
@@ -312,7 +312,7 @@ void rts51x_init_cards(struct rts51x_chip *chip)
chip->card_exist &= ~SD_CARD;
chip->card_ejected = 0;
if (chip->card_ready & SD_CARD) {
- release_sd_card(chip);
+ rts51x_release_sd_card(chip);
chip->rw_card[chip->card2lun[SD_CARD]] = NULL;
clear_bit(chip->card2lun[SD_CARD],
&(chip->lun_mc));
@@ -323,7 +323,7 @@ void rts51x_init_cards(struct rts51x_chip *chip)
chip->card_exist &= ~MS_CARD;
chip->card_ejected = 0;
if (chip->card_ready & MS_CARD) {
- release_ms_card(chip);
+ rts51x_release_ms_card(chip);
chip->rw_card[chip->card2lun[MS_CARD]] = NULL;
clear_bit(chip->card2lun[MS_CARD],
&(chip->lun_mc));
@@ -339,13 +339,13 @@ void rts51x_init_cards(struct rts51x_chip *chip)
if (need_reset & XD_CARD) {
chip->card_exist |= XD_CARD;
- do_reset_xd_card(chip);
+ do_rts51x_reset_xd_card(chip);
} else if (need_reset & SD_CARD) {
chip->card_exist |= SD_CARD;
- do_reset_sd_card(chip);
+ rts51x_do_rts51x_reset_sd_card(chip);
} else if (need_reset & MS_CARD) {
chip->card_exist |= MS_CARD;
- do_reset_ms_card(chip);
+ do_rts51x_reset_ms_card(chip);
}
}
}
@@ -353,20 +353,20 @@ void rts51x_init_cards(struct rts51x_chip *chip)
void rts51x_release_cards(struct rts51x_chip *chip)
{
if (chip->card_ready & SD_CARD) {
- sd_cleanup_work(chip);
- release_sd_card(chip);
+ rts51x_sd_cleanup_work(chip);
+ rts51x_release_sd_card(chip);
chip->card_ready &= ~SD_CARD;
}
if (chip->card_ready & XD_CARD) {
- xd_cleanup_work(chip);
- release_xd_card(chip);
+ rts51x_xd_cleanup_work(chip);
+ rts51x_release_xd_card(chip);
chip->card_ready &= ~XD_CARD;
}
if (chip->card_ready & MS_CARD) {
- ms_cleanup_work(chip);
- release_ms_card(chip);
+ rts51x_ms_cleanup_work(chip);
+ rts51x_release_ms_card(chip);
chip->card_ready &= ~MS_CARD;
}
}
@@ -376,7 +376,7 @@ static inline u8 double_depth(u8 depth)
return ((depth > 1) ? (depth - 1) : depth);
}
-int switch_ssc_clock(struct rts51x_chip *chip, int clk)
+int rts51x_switch_ssc_clock(struct rts51x_chip *chip, int clk)
{
struct sd_info *sd_card = &(chip->sd_card);
struct ms_info *ms_card = &(chip->ms_card);
@@ -513,7 +513,7 @@ int switch_ssc_clock(struct rts51x_chip *chip, int clk)
return STATUS_SUCCESS;
}
-int switch_normal_clock(struct rts51x_chip *chip, int clk)
+int rts51x_switch_normal_clock(struct rts51x_chip *chip, int clk)
{
int retval;
u8 sel, div, mcu_cnt;
@@ -653,7 +653,7 @@ int switch_normal_clock(struct rts51x_chip *chip, int clk)
return STATUS_SUCCESS;
}
-int card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr,
+int rts51x_card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr,
u16 sec_cnt)
{
int retval;
@@ -688,7 +688,7 @@ int card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr,
return retval;
}
-u8 get_lun_card(struct rts51x_chip *chip, unsigned int lun)
+u8 rts51x_get_lun_card(struct rts51x_chip *chip, unsigned int lun)
{
if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD)
return (u8) XD_CARD;
@@ -744,24 +744,24 @@ int rts51x_select_card(struct rts51x_chip *chip, int card)
return STATUS_SUCCESS;
}
-void eject_card(struct rts51x_chip *chip, unsigned int lun)
+void rts51x_eject_card(struct rts51x_chip *chip, unsigned int lun)
{
RTS51X_DEBUGP("eject card\n");
RTS51X_SET_STAT(chip, STAT_RUN);
- do_remaining_work(chip);
+ rts51x_do_remaining_work(chip);
if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) {
- release_sd_card(chip);
+ rts51x_release_sd_card(chip);
chip->card_ejected |= SD_CARD;
chip->card_ready &= ~SD_CARD;
chip->capacity[lun] = 0;
} else if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) {
- release_xd_card(chip);
+ rts51x_release_xd_card(chip);
chip->card_ejected |= XD_CARD;
chip->card_ready &= ~XD_CARD;
chip->capacity[lun] = 0;
} else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) {
- release_ms_card(chip);
+ rts51x_release_ms_card(chip);
chip->card_ejected |= MS_CARD;
chip->card_ready &= ~MS_CARD;
chip->capacity[lun] = 0;
@@ -770,7 +770,7 @@ void eject_card(struct rts51x_chip *chip, unsigned int lun)
XD_INT | MS_INT | SD_INT);
}
-void trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip,
+void rts51x_trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip,
u32 byte_cnt, u8 pack_size)
{
if (pack_size > DMA_1024)
@@ -798,7 +798,7 @@ void trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip,
}
}
-int enable_card_clock(struct rts51x_chip *chip, u8 card)
+int rts51x_enable_card_clock(struct rts51x_chip *chip, u8 card)
{
u8 clk_en = 0;
@@ -814,7 +814,7 @@ int enable_card_clock(struct rts51x_chip *chip, u8 card)
return STATUS_SUCCESS;
}
-int card_power_on(struct rts51x_chip *chip, u8 card)
+int rts51x_card_power_on(struct rts51x_chip *chip, u8 card)
{
u8 mask, val1, val2;
@@ -863,7 +863,7 @@ int monitor_card_cd(struct rts51x_chip *chip, u8 card)
return CD_NOT_EXIST;
}
-int toggle_gpio(struct rts51x_chip *chip, u8 gpio)
+int rts51x_toggle_gpio(struct rts51x_chip *chip, u8 gpio)
{
int retval;
u8 temp_reg;
@@ -898,7 +898,7 @@ int toggle_gpio(struct rts51x_chip *chip, u8 gpio)
return STATUS_SUCCESS;
}
-int turn_on_led(struct rts51x_chip *chip, u8 gpio)
+int rts51x_turn_on_led(struct rts51x_chip *chip, u8 gpio)
{
int retval;
u8 gpio_oe[4] = {
@@ -917,7 +917,7 @@ int turn_on_led(struct rts51x_chip *chip, u8 gpio)
return STATUS_SUCCESS;
}
-int turn_off_led(struct rts51x_chip *chip, u8 gpio)
+int rts51x_turn_off_led(struct rts51x_chip *chip, u8 gpio)
{
int retval;
u8 gpio_output[4] = {
diff --git a/drivers/staging/rts5139/rts51x_card.h b/drivers/staging/rts5139/rts51x_card.h
index c5c03cce98b..e62b25c3141 100644
--- a/drivers/staging/rts5139/rts51x_card.h
+++ b/drivers/staging/rts5139/rts51x_card.h
@@ -737,24 +737,24 @@
int monitor_card_cd(struct rts51x_chip *chip, u8 card);
-void do_remaining_work(struct rts51x_chip *chip);
-void do_reset_sd_card(struct rts51x_chip *chip);
+void rts51x_do_remaining_work(struct rts51x_chip *chip);
+void rts51x_do_rts51x_reset_sd_card(struct rts51x_chip *chip);
void rts51x_init_cards(struct rts51x_chip *chip);
void rts51x_release_cards(struct rts51x_chip *chip);
-int switch_ssc_clock(struct rts51x_chip *chip, int clk);
-int switch_normal_clock(struct rts51x_chip *chip, int clk);
-int card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr,
+int rts51x_switch_ssc_clock(struct rts51x_chip *chip, int clk);
+int rts51x_switch_normal_clock(struct rts51x_chip *chip, int clk);
+int rts51x_card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr,
u16 sec_cnt);
-u8 get_lun_card(struct rts51x_chip *chip, unsigned int lun);
+u8 rts51x_get_lun_card(struct rts51x_chip *chip, unsigned int lun);
int rts51x_select_card(struct rts51x_chip *chip, int card);
-void eject_card(struct rts51x_chip *chip, unsigned int lun);
-void trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip,
+void rts51x_eject_card(struct rts51x_chip *chip, unsigned int lun);
+void rts51x_trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip,
u32 byte_cnt, u8 pack_size);
-int enable_card_clock(struct rts51x_chip *chip, u8 card);
-int card_power_on(struct rts51x_chip *chip, u8 card);
-int toggle_gpio(struct rts51x_chip *chip, u8 gpio);
-int turn_on_led(struct rts51x_chip *chip, u8 gpio);
-int turn_off_led(struct rts51x_chip *chip, u8 gpio);
+int rts51x_enable_card_clock(struct rts51x_chip *chip, u8 card);
+int rts51x_card_power_on(struct rts51x_chip *chip, u8 card);
+int rts51x_toggle_gpio(struct rts51x_chip *chip, u8 gpio);
+int rts51x_turn_on_led(struct rts51x_chip *chip, u8 gpio);
+int rts51x_turn_off_led(struct rts51x_chip *chip, u8 gpio);
static inline int check_card_ready(struct rts51x_chip *chip, unsigned int lun)
{
@@ -830,9 +830,9 @@ static inline int switch_clock(struct rts51x_chip *chip, int clk)
int retval = 0;
if (chip->asic_code)
- retval = switch_ssc_clock(chip, clk);
+ retval = rts51x_switch_ssc_clock(chip, clk);
else
- retval = switch_normal_clock(chip, clk);
+ retval = rts51x_switch_normal_clock(chip, clk);
return retval;
}
diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c
index 08dcae8db63..7d7510de170 100644
--- a/drivers/staging/rts5139/rts51x_chip.c
+++ b/drivers/staging/rts5139/rts51x_chip.c
@@ -132,7 +132,7 @@ int rts51x_reset_chip(struct rts51x_chip *chip)
}
#endif
if (chip->option.FT2_fast_mode) {
- card_power_on(chip, SD_CARD | MS_CARD | XD_CARD);
+ rts51x_card_power_on(chip, SD_CARD | MS_CARD | XD_CARD);
wait_timeout(10);
}
@@ -212,8 +212,8 @@ int rts51x_init_chip(struct rts51x_chip *chip)
int rts51x_release_chip(struct rts51x_chip *chip)
{
- xd_free_l2p_tbl(chip);
- ms_free_l2p_tbl(chip);
+ rts51x_xd_free_l2p_tbl(chip);
+ rts51x_ms_free_l2p_tbl(chip);
chip->card_ready = 0;
return STATUS_SUCCESS;
}
@@ -227,7 +227,7 @@ static inline void rts51x_blink_led(struct rts51x_chip *chip)
chip->led_toggle_counter++;
} else {
chip->led_toggle_counter = 0;
- toggle_gpio(chip, LED_GPIO);
+ rts51x_toggle_gpio(chip, LED_GPIO);
}
}
}
@@ -325,14 +325,14 @@ void rts51x_polling_func(struct rts51x_chip *chip)
&& (chip->card_exist &
(SD_CARD | MS_CARD | XD_CARD))
&& (!chip->card_ejected)) {
- turn_on_led(chip, LED_GPIO);
+ rts51x_turn_on_led(chip, LED_GPIO);
} else {
if (chip->rts5179) {
rts51x_ep0_write_register(chip,
CARD_GPIO,
0x03, 0x00);
} else {
- turn_off_led(chip, LED_GPIO);
+ rts51x_turn_off_led(chip, LED_GPIO);
}
}
@@ -353,7 +353,7 @@ void rts51x_polling_func(struct rts51x_chip *chip)
switch (RTS51X_GET_STAT(chip)) {
case STAT_RUN:
rts51x_blink_led(chip);
- do_remaining_work(chip);
+ rts51x_do_remaining_work(chip);
break;
case STAT_IDLE:
@@ -707,7 +707,7 @@ void rts51x_do_before_power_down(struct rts51x_chip *chip)
if (chip->rts5179)
rts51x_ep0_write_register(chip, CARD_GPIO, 0x03, 0x00);
else
- turn_off_led(chip, LED_GPIO);
+ rts51x_turn_off_led(chip, LED_GPIO);
chip->cur_clk = 0;
chip->card_exist = 0;
@@ -797,7 +797,7 @@ void rts51x_pp_status(struct rts51x_chip *chip, unsigned int lun, u8 *status,
{
struct sd_info *sd_card = &(chip->sd_card);
struct ms_info *ms_card = &(chip->ms_card);
- u8 card = get_lun_card(chip, lun);
+ u8 card = rts51x_get_lun_card(chip, lun);
#ifdef SUPPORT_OC
u8 oc_now_mask = 0, oc_ever_mask = 0;
#endif
@@ -958,9 +958,9 @@ void rts51x_read_status(struct rts51x_chip *chip, unsigned int lun,
rts51x_status[12] = 0;
/* Detailed Type */
- if (get_lun_card(chip, lun) == XD_CARD) {
+ if (rts51x_get_lun_card(chip, lun) == XD_CARD) {
rts51x_status[13] = 0x40;
- } else if (get_lun_card(chip, lun) == SD_CARD) {
+ } else if (rts51x_get_lun_card(chip, lun) == SD_CARD) {
struct sd_info *sd_card = &(chip->sd_card);
rts51x_status[13] = 0x20;
@@ -976,7 +976,7 @@ void rts51x_read_status(struct rts51x_chip *chip, unsigned int lun,
if (CHK_MMC_SECTOR_MODE(sd_card))
rts51x_status[13] |= 0x04; /* Hi capacity */
}
- } else if (get_lun_card(chip, lun) == MS_CARD) {
+ } else if (rts51x_get_lun_card(chip, lun) == MS_CARD) {
struct ms_info *ms_card = &(chip->ms_card);
if (CHK_MSPRO(ms_card)) {
diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h
index 64257caf2f3..12deb24cfbb 100644
--- a/drivers/staging/rts5139/rts51x_chip.h
+++ b/drivers/staging/rts5139/rts51x_chip.h
@@ -253,7 +253,7 @@ struct sense_data_t {
#define SUPPORT_UHS50_MMC44 0x40
struct rts51x_option {
- int mspro_formatter_enable;
+ int rts51x_mspro_formatter_enable;
/* card clock expected by user for fpga platform */
int fpga_sd_sdr104_clk;
@@ -308,7 +308,7 @@ struct rts51x_option {
* add for config delay between 1/4 PMOS and 3/4 PMOS */
int pwr_delay;
- int xd_rw_step; /* add to tune xd tRP */
+ int rts51x_xd_rw_step; /* add to tune xd tRP */
int D3318_off_delay; /* add to tune D3318 off delay time */
int delink_delay; /* add to tune delink delay time */
/* add for rts5129 to enable/disable D3318 off */
@@ -320,7 +320,7 @@ struct rts51x_option {
u8 debounce_num; /* debounce number */
u8 led_toggle_interval; /* used to control led toggle speed */
- int xd_rwn_step;
+ int rts51x_xd_rwn_step;
u8 sd_send_status_en;
/* used to store default phase which is
* used when phase tune all pass. */
@@ -337,11 +337,11 @@ struct rts51x_option {
u8 dv18_voltage; /* add to tune dv18 voltage */
};
-#define MS_FORMATTER_ENABLED(chip) ((chip)->option.mspro_formatter_enable)
+#define MS_FORMATTER_ENABLED(chip) ((chip)->option.rts51x_mspro_formatter_enable)
struct rts51x_chip;
-typedef int (*card_rw_func) (struct scsi_cmnd *srb, struct rts51x_chip *chip,
+typedef int (*rts51x_card_rw_func) (struct scsi_cmnd *srb, struct rts51x_chip *chip,
u32 sec_addr, u16 sec_cnt);
/* For MS Card */
@@ -564,7 +564,7 @@ struct sd_info {
#define CHK_MS8BIT(ms_card) (((ms_card)->ms_type & MS_8BIT))
#define CHK_MS4BIT(ms_card) (((ms_card)->ms_type & MS_4BIT))
-struct ms_delay_write_tag {
+struct rts51x_ms_delay_write_tag {
u16 old_phyblock;
u16 new_phyblock;
u16 logblock;
@@ -605,7 +605,7 @@ struct ms_info {
u32 total_sec_cnt;
u8 last_rw_int;
- struct ms_delay_write_tag delay_write;
+ struct rts51x_ms_delay_write_tag delay_write;
int counter;
@@ -671,7 +671,7 @@ struct rts51x_chip {
u32 capacity[MAX_ALLOWED_LUN_CNT];
/* read/write card function pointer */
- card_rw_func rw_card[MAX_ALLOWED_LUN_CNT];
+ rts51x_card_rw_func rw_card[MAX_ALLOWED_LUN_CNT];
/* read/write capacity, used for GPIO Toggle */
u32 rw_cap[MAX_ALLOWED_LUN_CNT];
/* card to lun mapping table */
diff --git a/drivers/staging/rts5139/rts51x_fop.c b/drivers/staging/rts5139/rts51x_fop.c
index bf1a9e64e87..dee7d8af564 100644
--- a/drivers/staging/rts5139/rts51x_fop.c
+++ b/drivers/staging/rts5139/rts51x_fop.c
@@ -70,7 +70,7 @@ static int rts51x_sd_direct_cmnd(struct rts51x_chip *chip,
switch (dir) {
case 0:
/* No data */
- retval = ext_sd_execute_no_data(chip, chip->card2lun[SD_CARD],
+ retval = ext_rts51x_sd_execute_no_data(chip, chip->card2lun[SD_CARD],
cmd_idx, standby, acmd,
rsp_code, arg);
if (retval != TRANSPORT_GOOD)
@@ -83,7 +83,7 @@ static int rts51x_sd_direct_cmnd(struct rts51x_chip *chip,
if (!buf)
TRACE_RET(chip, STATUS_NOMEM);
- retval = ext_sd_execute_read_data(chip, chip->card2lun[SD_CARD],
+ retval = ext_rts51x_sd_execute_read_data(chip, chip->card2lun[SD_CARD],
cmd_idx, cmd12, standby, acmd,
rsp_code, arg, len, buf,
cmnd->buf_len, 0);
@@ -117,7 +117,7 @@ static int rts51x_sd_direct_cmnd(struct rts51x_chip *chip,
}
retval =
- ext_sd_execute_write_data(chip, chip->card2lun[SD_CARD],
+ ext_rts51x_sd_execute_write_data(chip, chip->card2lun[SD_CARD],
cmd_idx, cmd12, standby, acmd,
rsp_code, arg, len, buf,
cmnd->buf_len, 0);
diff --git a/drivers/staging/rts5139/rts51x_scsi.c b/drivers/staging/rts5139/rts51x_scsi.c
index e07a1f4f58c..052911c9310 100644
--- a/drivers/staging/rts5139/rts51x_scsi.c
+++ b/drivers/staging/rts5139/rts51x_scsi.c
@@ -44,7 +44,7 @@
#include "ms_mg.h"
#include "trace.h"
-void scsi_show_command(struct scsi_cmnd *srb)
+void rts51x_scsi_show_command(struct scsi_cmnd *srb)
{
char *what = NULL;
int i, unknown_cmd = 0;
@@ -333,72 +333,72 @@ void scsi_show_command(struct scsi_cmnd *srb)
}
}
-void set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type)
+void rts51x_set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type)
{
switch (sense_type) {
case SENSE_TYPE_MEDIA_CHANGE:
- set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0);
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0);
break;
case SENSE_TYPE_MEDIA_NOT_PRESENT:
- set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0);
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0);
break;
case SENSE_TYPE_MEDIA_LBA_OVER_RANGE:
- set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0);
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0);
break;
case SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT:
- set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0);
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0);
break;
case SENSE_TYPE_MEDIA_WRITE_PROTECT:
- set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0);
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0);
break;
case SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR:
- set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0);
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0);
break;
case SENSE_TYPE_MEDIA_WRITE_ERR:
- set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0);
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0);
break;
case SENSE_TYPE_MEDIA_INVALID_CMD_FIELD:
- set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0,
+ rts51x_set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0,
ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1);
break;
case SENSE_TYPE_FORMAT_CMD_FAILED:
- set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0);
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0);
break;
#ifdef SUPPORT_MAGIC_GATE
case SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB:
- set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0);
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0);
break;
case SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN:
- set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0);
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0);
break;
case SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM:
- set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0);
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0);
break;
case SENSE_TYPE_MG_WRITE_ERR:
- set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0);
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0);
break;
#endif
case SENSE_TYPE_NO_SENSE:
default:
- set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0);
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0);
break;
}
}
-void set_sense_data(struct rts51x_chip *chip, unsigned int lun, u8 err_code,
+void rts51x_set_sense_data(struct rts51x_chip *chip, unsigned int lun, u8 err_code,
u8 sense_key, u32 info, u8 asc, u8 ascq, u8 sns_key_info0,
u16 sns_key_info1)
{
@@ -428,13 +428,13 @@ static int test_unit_ready(struct scsi_cmnd *srb, struct rts51x_chip *chip)
rts51x_init_cards(chip);
if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
return TRANSPORT_FAILED;
}
if (!check_lun_mc(chip, lun)) {
set_lun_mc(chip, lun);
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
return TRANSPORT_FAILED;
}
@@ -457,7 +457,7 @@ static int inquiry(struct scsi_cmnd *srb, struct rts51x_chip *chip)
char *inquiry_string;
unsigned char sendbytes;
unsigned char *buf;
- u8 card = get_lun_card(chip, lun);
+ u8 card = rts51x_get_lun_card(chip, lun);
int pro_formatter_flag = 0;
unsigned char inquiry_buf[] = {
QULIFIRE | DRCT_ACCESS_DEV,
@@ -532,7 +532,7 @@ static int start_stop_unit(struct scsi_cmnd *srb, struct rts51x_chip *chip)
case UNLOAD_MEDIUM:
/* Media shall be unload */
if (check_card_ready(chip, lun))
- eject_card(chip, lun);
+ rts51x_eject_card(chip, lun);
return TRANSPORT_GOOD;
case MAKE_MEDIUM_READY:
@@ -540,7 +540,7 @@ static int start_stop_unit(struct scsi_cmnd *srb, struct rts51x_chip *chip)
if (check_card_ready(chip, lun)) {
return TRANSPORT_GOOD;
} else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -559,7 +559,7 @@ static int allow_medium_removal(struct scsi_cmnd *srb, struct rts51x_chip *chip)
scsi_set_resid(srb, 0);
if (prevent) {
- set_sense_type(chip, SCSI_LUN(srb),
+ rts51x_set_sense_type(chip, SCSI_LUN(srb),
SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -663,10 +663,10 @@ static int mode_sense(struct scsi_cmnd *srb, struct rts51x_chip *chip)
int status;
int pro_formatter_flag;
unsigned char pageCode, *buf;
- u8 card = get_lun_card(chip, lun);
+ u8 card = rts51x_get_lun_card(chip, lun);
if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
scsi_set_resid(srb, scsi_bufflen(srb));
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -678,7 +678,7 @@ static int mode_sense(struct scsi_cmnd *srb, struct rts51x_chip *chip)
if ((get_lun2card(chip, lun) & MS_CARD)) {
if (!card || (card == MS_CARD)) {
dataSize = 108;
- if (chip->option.mspro_formatter_enable)
+ if (chip->option.rts51x_mspro_formatter_enable)
pro_formatter_flag = 1;
}
}
@@ -725,7 +725,7 @@ static int mode_sense(struct scsi_cmnd *srb, struct rts51x_chip *chip)
}
status = TRANSPORT_GOOD;
} else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
scsi_set_resid(srb, scsi_bufflen(srb));
status = TRANSPORT_FAILED;
}
@@ -749,9 +749,9 @@ static int request_sense(struct scsi_cmnd *srb, struct rts51x_chip *chip)
sense = &(chip->sense_buffer[lun]);
- if ((get_lun_card(chip, lun) == MS_CARD)
+ if ((rts51x_get_lun_card(chip, lun) == MS_CARD)
&& PRO_UNDER_FORMATTING(ms_card)) {
- mspro_format_sense(chip, lun);
+ rts51x_mspro_format_sense(chip, lun);
}
buf = vmalloc(scsi_bufflen(srb));
@@ -766,7 +766,7 @@ static int request_sense(struct scsi_cmnd *srb, struct rts51x_chip *chip)
scsi_set_resid(srb, 0);
/* Reset Sense Data */
- set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
return TRANSPORT_GOOD;
}
@@ -778,13 +778,13 @@ static int read_write(struct scsi_cmnd *srb, struct rts51x_chip *chip)
u16 sec_cnt;
if (!check_card_ready(chip, lun) || (chip->capacity[lun] == 0)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if (!check_lun_mc(chip, lun)) {
set_lun_mc(chip, lun);
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
return TRANSPORT_FAILED;
}
@@ -812,13 +812,13 @@ static int read_write(struct scsi_cmnd *srb, struct rts51x_chip *chip)
((u32) srb->cmnd[7]);
sec_cnt = ((u16) (srb->cmnd[9]) << 8) | srb->cmnd[10];
} else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if ((start_sec > chip->capacity[lun]) ||
((start_sec + sec_cnt) > chip->capacity[lun])) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LBA_OVER_RANGE);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LBA_OVER_RANGE);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -830,17 +830,17 @@ static int read_write(struct scsi_cmnd *srb, struct rts51x_chip *chip)
if ((srb->sc_data_direction == DMA_TO_DEVICE)
&& check_card_wp(chip, lun)) {
RTS51X_DEBUGP("Write protected card!\n");
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
- retval = card_rw(srb, chip, start_sec, sec_cnt);
+ retval = rts51x_card_rw(srb, chip, start_sec, sec_cnt);
if (retval != STATUS_SUCCESS) {
if (srb->sc_data_direction == DMA_FROM_DEVICE) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
} else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
}
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -855,13 +855,13 @@ static int read_format_capacity(struct scsi_cmnd *srb, struct rts51x_chip *chip)
unsigned char *buf;
unsigned int lun = SCSI_LUN(srb);
unsigned int buf_len;
- u8 card = get_lun_card(chip, lun);
+ u8 card = rts51x_get_lun_card(chip, lun);
int desc_cnt;
int i = 0;
if (!check_card_ready(chip, lun)) {
- if (!chip->option.mspro_formatter_enable) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ if (!chip->option.rts51x_mspro_formatter_enable) {
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
}
@@ -877,7 +877,7 @@ static int read_format_capacity(struct scsi_cmnd *srb, struct rts51x_chip *chip)
buf[i++] = 0;
/* Capacity List Length */
- if ((buf_len > 12) && chip->option.mspro_formatter_enable &&
+ if ((buf_len > 12) && chip->option.rts51x_mspro_formatter_enable &&
(chip->lun2card[lun] & MS_CARD) && (!card || (card == MS_CARD))) {
buf[i++] = 0x10;
desc_cnt = 2;
@@ -933,13 +933,13 @@ static int read_capacity(struct scsi_cmnd *srb, struct rts51x_chip *chip)
unsigned int lun = SCSI_LUN(srb);
if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if (!check_lun_mc(chip, lun)) {
set_lun_mc(chip, lun);
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
return TRANSPORT_FAILED;
}
@@ -1021,7 +1021,7 @@ static int read_mem(struct scsi_cmnd *srb, struct rts51x_chip *chip)
retval = rts51x_ep0_read_register(chip, addr + i, buf + i);
if (retval != STATUS_SUCCESS) {
vfree(buf);
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1066,7 +1066,7 @@ static int write_mem(struct scsi_cmnd *srb, struct rts51x_chip *chip)
rts51x_ep0_write_register(chip, addr + i, 0xFF, buf[i]);
if (retval != STATUS_SUCCESS) {
vfree(buf);
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
TRACE_RET(chip, TRANSPORT_FAILED);
}
}
@@ -1083,12 +1083,12 @@ static int get_sd_csd(struct scsi_cmnd *srb, struct rts51x_chip *chip)
unsigned int lun = SCSI_LUN(srb);
if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
- if (get_lun_card(chip, lun) != SD_CARD) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+ if (rts51x_get_lun_card(chip, lun) != SD_CARD) {
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1120,7 +1120,7 @@ static int read_phy_register(struct scsi_cmnd *srb, struct rts51x_chip *chip)
rts51x_read_phy_register(chip, addr + i, buf + i);
if (retval != STATUS_SUCCESS) {
vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb),
+ rts51x_set_sense_type(chip, SCSI_LUN(srb),
SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1163,7 +1163,7 @@ static int write_phy_register(struct scsi_cmnd *srb, struct rts51x_chip *chip)
rts51x_write_phy_register(chip, addr + i, buf[i]);
if (retval != STATUS_SUCCESS) {
vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb),
+ rts51x_set_sense_type(chip, SCSI_LUN(srb),
SENSE_TYPE_MEDIA_WRITE_ERR);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1181,15 +1181,15 @@ static int get_card_bus_width(struct scsi_cmnd *srb, struct rts51x_chip *chip)
u8 card, bus_width;
if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
- card = get_lun_card(chip, lun);
+ card = rts51x_get_lun_card(chip, lun);
if ((card == SD_CARD) || (card == MS_CARD)) {
bus_width = chip->card_bus_width[lun];
} else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1211,7 +1211,7 @@ static int trace_msg_cmd(struct scsi_cmnd *srb, struct rts51x_chip *chip)
((2 + MSG_FUNC_LEN + MSG_FILE_LEN + TIME_VAL_LEN) * TRACE_ITEM_CNT);
if ((scsi_bufflen(srb) < buf_len) || (scsi_sglist(srb) == NULL)) {
- set_sense_type(chip, SCSI_LUN(srb),
+ rts51x_set_sense_type(chip, SCSI_LUN(srb),
SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1251,7 +1251,7 @@ static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rts51x_chip *chip)
case ADD_BATCHCMD:
cmd_type = srb->cmnd[4];
if (cmd_type > 2) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1274,13 +1274,13 @@ static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rts51x_chip *chip)
[9]);
retval = rts51x_send_cmd(chip, mode, 1000);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if (mode & STAGE_R) {
retval = rts51x_get_rsp(chip, len, timeout);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1291,7 +1291,7 @@ static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rts51x_chip *chip)
idx = srb->cmnd[4];
value = chip->rsp_buf[idx];
if (scsi_bufflen(srb) < 1) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1300,12 +1300,12 @@ static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rts51x_chip *chip)
break;
default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1357,7 +1357,7 @@ static int app_cmd(struct scsi_cmnd *srb, struct rts51x_chip *chip)
break;
default:
- set_sense_type(chip, SCSI_LUN(srb),
+ rts51x_set_sense_type(chip, SCSI_LUN(srb),
SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1401,7 +1401,7 @@ static int vendor_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip)
break;
default:
- set_sense_type(chip, SCSI_LUN(srb),
+ rts51x_set_sense_type(chip, SCSI_LUN(srb),
SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1415,15 +1415,15 @@ static int ms_format_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip)
unsigned int lun = SCSI_LUN(srb);
int retval, quick_format;
- if (get_lun_card(chip, lun) != MS_CARD) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
+ if (rts51x_get_lun_card(chip, lun) != MS_CARD) {
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if ((srb->cmnd[3] != 0x4D) || (srb->cmnd[4] != 0x47)
|| (srb->cmnd[5] != 0x66) || (srb->cmnd[6] != 0x6D)
|| (srb->cmnd[7] != 0x74)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1433,26 +1433,26 @@ static int ms_format_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip)
quick_format = 1;
if (!(chip->card_ready & MS_CARD)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if (chip->card_wp & MS_CARD) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if (!CHK_MSPRO(ms_card)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
rts51x_prepare_run(chip);
RTS51X_SET_STAT(chip, STAT_RUN);
- retval = mspro_format(srb, chip, MS_SHORT_DATA_LEN, quick_format);
+ retval = rts51x_mspro_format(srb, chip, MS_SHORT_DATA_LEN, quick_format);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1471,18 +1471,18 @@ static int get_ms_information(struct scsi_cmnd *srb, struct rts51x_chip *chip)
int i;
if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
- if ((get_lun_card(chip, lun) != MS_CARD)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
+ if ((rts51x_get_lun_card(chip, lun) != MS_CARD)) {
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if ((srb->cmnd[2] != 0xB0) || (srb->cmnd[4] != 0x4D) ||
(srb->cmnd[5] != 0x53) || (srb->cmnd[6] != 0x49) ||
(srb->cmnd[7] != 0x44)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1490,7 +1490,7 @@ static int get_ms_information(struct scsi_cmnd *srb, struct rts51x_chip *chip)
if ((CHK_MSXC(ms_card) && (dev_info_id == 0x10)) ||
(!CHK_MSXC(ms_card) && (dev_info_id == 0x13)) ||
!CHK_MSPRO(ms_card)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1576,44 +1576,44 @@ static int sd_extention_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip)
rts51x_prepare_run(chip);
RTS51X_SET_STAT(chip, STAT_RUN);
- sd_cleanup_work(chip);
+ rts51x_sd_cleanup_work(chip);
if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
- if ((get_lun_card(chip, lun) != SD_CARD)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
+ if ((rts51x_get_lun_card(chip, lun) != SD_CARD)) {
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
switch (srb->cmnd[0]) {
case SD_PASS_THRU_MODE:
- result = sd_pass_thru_mode(srb, chip);
+ result = rts51x_sd_pass_thru_mode(srb, chip);
break;
case SD_EXECUTE_NO_DATA:
- result = sd_execute_no_data(srb, chip);
+ result = rts51x_sd_execute_no_data(srb, chip);
break;
case SD_EXECUTE_READ:
- result = sd_execute_read_data(srb, chip);
+ result = rts51x_sd_execute_read_data(srb, chip);
break;
case SD_EXECUTE_WRITE:
- result = sd_execute_write_data(srb, chip);
+ result = rts51x_sd_execute_write_data(srb, chip);
break;
case SD_GET_RSP:
- result = sd_get_cmd_rsp(srb, chip);
+ result = rts51x_sd_get_cmd_rsp(srb, chip);
break;
case SD_HW_RST:
- result = sd_hw_rst(srb, chip);
+ result = rts51x_sd_hw_rst(srb, chip);
break;
default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1632,24 +1632,24 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip)
rts51x_prepare_run(chip);
RTS51X_SET_STAT(chip, STAT_RUN);
- ms_cleanup_work(chip);
+ rts51x_ms_cleanup_work(chip);
if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
- if ((get_lun_card(chip, lun) != MS_CARD)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
+ if ((rts51x_get_lun_card(chip, lun) != MS_CARD)) {
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if (srb->cmnd[7] != KC_MG_R_PRO) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if (!CHK_MSPRO(ms_card)) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1659,11 +1659,11 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip)
case KF_GET_LOC_EKB:
if ((scsi_bufflen(srb) == 0x41C) &&
(srb->cmnd[8] == 0x04) && (srb->cmnd[9] == 0x1C)) {
- retval = mg_get_local_EKB(srb, chip);
+ retval = rts51x_mg_get_local_EKB(srb, chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, TRANSPORT_FAILED);
} else {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1672,11 +1672,11 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip)
case KF_RSP_CHG:
if ((scsi_bufflen(srb) == 0x24) &&
(srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x24)) {
- retval = mg_get_rsp_chg(srb, chip);
+ retval = rts51x_mg_get_rsp_chg(srb, chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, TRANSPORT_FAILED);
} else {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1690,18 +1690,18 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip)
(srb->cmnd[2] == 0x00) &&
(srb->cmnd[3] == 0x00) &&
(srb->cmnd[4] == 0x00) && (srb->cmnd[5] < 32)) {
- retval = mg_get_ICV(srb, chip);
+ retval = rts51x_mg_get_ICV(srb, chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, TRANSPORT_FAILED);
} else {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
break;
default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1719,28 +1719,28 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip)
rts51x_prepare_run(chip);
RTS51X_SET_STAT(chip, STAT_RUN);
- ms_cleanup_work(chip);
+ rts51x_ms_cleanup_work(chip);
if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if (check_card_wp(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
- if ((get_lun_card(chip, lun) != MS_CARD)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
+ if ((rts51x_get_lun_card(chip, lun) != MS_CARD)) {
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if (srb->cmnd[7] != KC_MG_R_PRO) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if (!CHK_MSPRO(ms_card)) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1750,11 +1750,11 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip)
case KF_SET_LEAF_ID:
if ((scsi_bufflen(srb) == 0x0C) &&
(srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) {
- retval = mg_set_leaf_id(srb, chip);
+ retval = rts51x_mg_set_leaf_id(srb, chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, TRANSPORT_FAILED);
} else {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1763,11 +1763,11 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip)
case KF_CHG_HOST:
if ((scsi_bufflen(srb) == 0x0C) &&
(srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) {
- retval = mg_chg(srb, chip);
+ retval = rts51x_mg_chg(srb, chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, TRANSPORT_FAILED);
} else {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1776,11 +1776,11 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip)
case KF_RSP_HOST:
if ((scsi_bufflen(srb) == 0x0C) &&
(srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) {
- retval = mg_rsp(srb, chip);
+ retval = rts51x_mg_rsp(srb, chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, TRANSPORT_FAILED);
} else {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1794,18 +1794,18 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip)
(srb->cmnd[2] == 0x00) &&
(srb->cmnd[3] == 0x00) &&
(srb->cmnd[4] == 0x00) && (srb->cmnd[5] < 32)) {
- retval = mg_set_ICV(srb, chip);
+ retval = rts51x_mg_set_ICV(srb, chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, TRANSPORT_FAILED);
} else {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
break;
default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1820,12 +1820,12 @@ int rts51x_scsi_handler(struct scsi_cmnd *srb, struct rts51x_chip *chip)
unsigned int lun = SCSI_LUN(srb);
int result = TRANSPORT_GOOD;
- if ((get_lun_card(chip, lun) == MS_CARD) &&
+ if ((rts51x_get_lun_card(chip, lun) == MS_CARD) &&
(ms_card->format_status == FORMAT_IN_PROGRESS)) {
if ((srb->cmnd[0] != REQUEST_SENSE)
&& (srb->cmnd[0] != INQUIRY)) {
/* Logical Unit Not Ready Format in Progress */
- set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04,
+ rts51x_set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04,
0, (u16) (ms_card->progress));
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1908,7 +1908,7 @@ int rts51x_scsi_handler(struct scsi_cmnd *srb, struct rts51x_chip *chip)
break;
default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
result = TRANSPORT_FAILED;
}
diff --git a/drivers/staging/rts5139/rts51x_scsi.h b/drivers/staging/rts5139/rts51x_scsi.h
index 9042bc98a9a..cdfe550371c 100644
--- a/drivers/staging/rts5139/rts51x_scsi.h
+++ b/drivers/staging/rts5139/rts51x_scsi.h
@@ -133,9 +133,9 @@ struct rts51x_chip;
#define SCSI 0x00 /* Interface ID */
-void scsi_show_command(struct scsi_cmnd *srb);
-void set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type);
-void set_sense_data(struct rts51x_chip *chip, unsigned int lun, u8 err_code,
+void rts51x_scsi_show_command(struct scsi_cmnd *srb);
+void rts51x_set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type);
+void rts51x_set_sense_data(struct rts51x_chip *chip, unsigned int lun, u8 err_code,
u8 sense_key, u32 info, u8 asc, u8 ascq, u8 sns_key_info0,
u16 sns_key_info1);
diff --git a/drivers/staging/rts5139/sd.c b/drivers/staging/rts5139/sd.c
index b739f26f78c..4283b0917f2 100644
--- a/drivers/staging/rts5139/sd.c
+++ b/drivers/staging/rts5139/sd.c
@@ -680,7 +680,7 @@ static int sd_set_init_para(struct rts51x_chip *chip)
return STATUS_SUCCESS;
}
-int sd_select_card(struct rts51x_chip *chip, int select)
+int rts51x_sd_select_card(struct rts51x_chip *chip, int select)
{
struct sd_info *sd_card = &(chip->sd_card);
int retval;
@@ -1747,7 +1747,7 @@ static int mmc_ddr_tuning(struct rts51x_chip *chip)
return STATUS_SUCCESS;
}
-int sd_switch_clock(struct rts51x_chip *chip)
+int rts51x_sd_switch_clock(struct rts51x_chip *chip)
{
struct sd_info *sd_card = &(chip->sd_card);
int retval;
@@ -1913,7 +1913,7 @@ static int sd_init_power(struct rts51x_chip *chip)
#endif
/* Power on card */
- retval = card_power_on(chip, SD_CARD);
+ retval = rts51x_card_power_on(chip, SD_CARD);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, retval);
@@ -2139,7 +2139,7 @@ RTY_CMD55:
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, retval);
/* Select SD card */
- retval = sd_select_card(chip, 1);
+ retval = rts51x_sd_select_card(chip, 1);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, retval);
@@ -2656,7 +2656,7 @@ RTY_MMC_RST:
spec_ver = (sd_card->raw_csd[0] & 0x3C) >> 2;
/* Select MMC card */
- retval = sd_select_card(chip, 1);
+ retval = rts51x_sd_select_card(chip, 1);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, retval);
@@ -2748,7 +2748,7 @@ RTY_MMC_RST:
return STATUS_SUCCESS;
}
-int reset_sd_card(struct rts51x_chip *chip)
+int rts51x_reset_sd_card(struct rts51x_chip *chip)
{
struct sd_info *sd_card = &(chip->sd_card);
int retval;
@@ -2764,7 +2764,7 @@ int reset_sd_card(struct rts51x_chip *chip)
sd_card->sd_switch_fail = 0;
sd_clear_reset_fail(chip);
- enable_card_clock(chip, SD_CARD);
+ rts51x_enable_card_clock(chip, SD_CARD);
sd_init_power(chip);
@@ -2891,7 +2891,7 @@ static void sd_stop_seq_mode(struct rts51x_chip *chip)
int retval;
if (sd_card->seq_mode) {
- retval = sd_switch_clock(chip);
+ retval = rts51x_sd_switch_clock(chip);
if (retval != STATUS_SUCCESS)
return;
@@ -2923,14 +2923,14 @@ static inline int sd_auto_tune_clock(struct rts51x_chip *chip)
sd_card->sd_clock = CLK_50;
}
- retval = sd_switch_clock(chip);
+ retval = rts51x_sd_switch_clock(chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, retval);
return STATUS_SUCCESS;
}
-int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
+int rts51x_sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
u16 sector_cnt)
{
struct sd_info *sd_card = &(chip->sd_card);
@@ -2947,11 +2947,11 @@ int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
else
data_addr = start_sector;
- RTS51X_DEBUGP("sd_rw, data_addr = 0x%x\n", data_addr);
+ RTS51X_DEBUGP("rts51x_sd_rw, data_addr = 0x%x\n", data_addr);
sd_clr_err_code(chip);
- retval = sd_switch_clock(chip);
+ retval = rts51x_sd_switch_clock(chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, retval);
@@ -3020,7 +3020,7 @@ int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 |
SD_RSP_LEN_0);
- trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512,
+ rts51x_trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512,
DMA_512);
if (srb->sc_data_direction == DMA_FROM_DEVICE) {
@@ -3058,7 +3058,7 @@ int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 |
SD_RSP_LEN_6);
- trans_dma_enable(srb->sc_data_direction, chip,
+ rts51x_trans_dma_enable(srb->sc_data_direction, chip,
sector_cnt * 512, DMA_512);
rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
@@ -3099,7 +3099,7 @@ int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 |
SD_RSP_LEN_0);
- trans_dma_enable(srb->sc_data_direction, chip,
+ rts51x_trans_dma_enable(srb->sc_data_direction, chip,
sector_cnt * 512, DMA_512);
rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
@@ -3168,7 +3168,7 @@ int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
return STATUS_SUCCESS;
}
-void sd_cleanup_work(struct rts51x_chip *chip)
+void rts51x_sd_cleanup_work(struct rts51x_chip *chip)
{
struct sd_info *sd_card = &(chip->sd_card);
@@ -3220,12 +3220,12 @@ static int sd_power_off_card3v3(struct rts51x_chip *chip)
return STATUS_SUCCESS;
}
-int release_sd_card(struct rts51x_chip *chip)
+int rts51x_release_sd_card(struct rts51x_chip *chip)
{
struct sd_info *sd_card = &(chip->sd_card);
int retval;
- RTS51X_DEBUGP("release_sd_card\n");
+ RTS51X_DEBUGP("rts51x_release_sd_card\n");
chip->card_ready &= ~SD_CARD;
chip->card_fail &= ~SD_CARD;
diff --git a/drivers/staging/rts5139/sd.h b/drivers/staging/rts5139/sd.h
index de155d8e682..7dd943f54c7 100644
--- a/drivers/staging/rts5139/sd.h
+++ b/drivers/staging/rts5139/sd.h
@@ -256,13 +256,13 @@ struct timing_phase_path {
int len;
};
-int sd_select_card(struct rts51x_chip *chip, int select);
-int reset_sd_card(struct rts51x_chip *chip);
-int sd_switch_clock(struct rts51x_chip *chip);
-int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
+int rts51x_sd_select_card(struct rts51x_chip *chip, int select);
+int rts51x_reset_sd_card(struct rts51x_chip *chip);
+int rts51x_sd_switch_clock(struct rts51x_chip *chip);
+int rts51x_sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
u16 sector_cnt);
-void sd_cleanup_work(struct rts51x_chip *chip);
-int release_sd_card(struct rts51x_chip *chip);
+void rts51x_sd_cleanup_work(struct rts51x_chip *chip);
+int rts51x_release_sd_card(struct rts51x_chip *chip);
#ifdef SUPPORT_CPRM
extern int reset_sd(struct rts51x_chip *chip);
diff --git a/drivers/staging/rts5139/sd_cprm.c b/drivers/staging/rts5139/sd_cprm.c
index 0167f7f35c2..d4689839e15 100644
--- a/drivers/staging/rts5139/sd_cprm.c
+++ b/drivers/staging/rts5139/sd_cprm.c
@@ -269,7 +269,7 @@ static int ext_sd_get_rsp(struct rts51x_chip *chip, int len,
return STATUS_SUCCESS;
}
-int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun,
+int ext_rts51x_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun,
u8 cmd_idx, u8 standby, u8 acmd, u8 rsp_code,
u32 arg)
{
@@ -277,30 +277,30 @@ int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun,
int retval, rsp_len;
u8 rsp_type;
- retval = sd_switch_clock(chip);
+ retval = rts51x_sd_switch_clock(chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, TRANSPORT_FAILED);
if (sd_card->pre_cmd_err) {
sd_card->pre_cmd_err = 0;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
TRACE_RET(chip, TRANSPORT_FAILED);
}
retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
sd_card->last_rsp_type = rsp_type;
- retval = sd_switch_clock(chip);
+ retval = rts51x_sd_switch_clock(chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, TRANSPORT_FAILED);
/* Set H/W SD/MMC Bus Width */
rts51x_write_register(chip, SD_CFG1, 0x03, SD_BUS_WIDTH_4);
if (standby) {
- retval = sd_select_card(chip, 0);
+ retval = rts51x_sd_select_card(chip, 0);
if (retval != STATUS_SUCCESS)
TRACE_GOTO(chip, SD_Execute_Cmd_Failed);
}
@@ -319,7 +319,7 @@ int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun,
TRACE_GOTO(chip, SD_Execute_Cmd_Failed);
if (standby) {
- retval = sd_select_card(chip, 1);
+ retval = rts51x_sd_select_card(chip, 1);
if (retval != STATUS_SUCCESS)
TRACE_GOTO(chip, SD_Execute_Cmd_Failed);
}
@@ -328,16 +328,16 @@ int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun,
SD_Execute_Cmd_Failed:
sd_card->pre_cmd_err = 1;
- set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
- release_sd_card(chip);
- do_reset_sd_card(chip);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
+ rts51x_release_sd_card(chip);
+ rts51x_do_rts51x_reset_sd_card(chip);
if (!(chip->card_ready & SD_CARD))
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
-int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun,
+int ext_rts51x_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun,
u8 cmd_idx, u8 cmd12, u8 standby,
u8 acmd, u8 rsp_code, u32 arg, u32 data_len,
void *data_buf, unsigned int buf_len, int use_sg)
@@ -349,21 +349,21 @@ int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun,
if (sd_card->pre_cmd_err) {
sd_card->pre_cmd_err = 0;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
TRACE_RET(chip, TRANSPORT_FAILED);
}
- retval = sd_switch_clock(chip);
+ retval = rts51x_sd_switch_clock(chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, STATUS_FAIL);
retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
sd_card->last_rsp_type = rsp_type;
- retval = sd_switch_clock(chip);
+ retval = rts51x_sd_switch_clock(chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, TRANSPORT_FAILED);
bus_width = SD_BUS_WIDTH_4;
@@ -376,7 +376,7 @@ int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun,
}
if (standby) {
- retval = sd_select_card(chip, 0);
+ retval = rts51x_sd_select_card(chip, 0);
if (retval != STATUS_SUCCESS)
TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
}
@@ -448,7 +448,7 @@ int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun,
rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8) arg);
rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, bus_width);
rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type);
- trans_dma_enable(DMA_FROM_DEVICE, chip, data_len, DMA_512);
+ rts51x_trans_dma_enable(DMA_FROM_DEVICE, chip, data_len, DMA_512);
rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
SD_TM_AUTO_READ_2 | SD_TRANSFER_START);
rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER,
@@ -490,7 +490,7 @@ int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun,
TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
if (standby) {
- retval = sd_select_card(chip, 1);
+ retval = rts51x_sd_select_card(chip, 1);
if (retval != STATUS_SUCCESS)
TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
}
@@ -531,18 +531,18 @@ int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun,
SD_Execute_Read_Cmd_Failed:
sd_card->pre_cmd_err = 1;
- set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
if (read_err)
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- release_sd_card(chip);
- do_reset_sd_card(chip);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
+ rts51x_release_sd_card(chip);
+ rts51x_do_rts51x_reset_sd_card(chip);
if (!(chip->card_ready & SD_CARD))
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
-int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun,
+int ext_rts51x_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun,
u8 cmd_idx, u8 cmd12, u8 standby, u8 acmd,
u8 rsp_code, u32 arg, u32 data_len,
void *data_buf, unsigned int buf_len, int use_sg)
@@ -555,22 +555,22 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun,
if (sd_card->pre_cmd_err) {
sd_card->pre_cmd_err = 0;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
TRACE_RET(chip, TRANSPORT_FAILED);
}
- retval = sd_switch_clock(chip);
+ retval = rts51x_sd_switch_clock(chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, STATUS_FAIL);
retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
sd_card->last_rsp_type = rsp_type;
- retval = sd_switch_clock(chip);
+ retval = rts51x_sd_switch_clock(chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, TRANSPORT_FAILED);
rts51x_write_register(chip, SD_CFG1, 0x03, SD_BUS_WIDTH_4);
@@ -583,7 +583,7 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun,
}
if (standby) {
- retval = sd_select_card(chip, 0);
+ retval = rts51x_sd_select_card(chip, 0);
if (retval != STATUS_SUCCESS)
TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
}
@@ -690,7 +690,7 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun,
rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L,
0xFF, (u8) ((data_len & 0x0001FE00) >> 9));
- trans_dma_enable(DMA_TO_DEVICE, chip, data_len, DMA_512);
+ rts51x_trans_dma_enable(DMA_TO_DEVICE, chip, data_len, DMA_512);
rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START);
@@ -724,7 +724,7 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun,
}
if (standby) {
- retval = sd_select_card(chip, 1);
+ retval = rts51x_sd_select_card(chip, 1);
if (retval != STATUS_SUCCESS)
TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
}
@@ -767,18 +767,18 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun,
SD_Execute_Write_Cmd_Failed:
sd_card->pre_cmd_err = 1;
- set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
if (write_err)
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
- release_sd_card(chip);
- do_reset_sd_card(chip);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
+ rts51x_release_sd_card(chip);
+ rts51x_do_rts51x_reset_sd_card(chip);
if (!(chip->card_ready & SD_CARD))
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, TRANSPORT_FAILED);
}
-int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip)
+int rts51x_sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip)
{
struct sd_info *sd_card = &(chip->sd_card);
unsigned int lun = SCSI_LUN(srb);
@@ -808,7 +808,7 @@ int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip)
if (!(CHK_BIT(chip->lun_mc, lun))) {
SET_BIT(chip->lun_mc, lun);
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -816,7 +816,7 @@ int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip)
|| (0x20 != srb->cmnd[4]) || (0x43 != srb->cmnd[5])
|| (0x61 != srb->cmnd[6]) || (0x72 != srb->cmnd[7])
|| (0x64 != srb->cmnd[8])) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -830,7 +830,7 @@ int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip)
break;
default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -850,7 +850,7 @@ int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip)
return TRANSPORT_GOOD;
}
-int sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip)
+int rts51x_sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip)
{
struct sd_info *sd_card = &(chip->sd_card);
unsigned int lun = SCSI_LUN(srb);
@@ -860,7 +860,7 @@ int sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip)
u32 arg;
if (!sd_card->sd_pass_thru_en) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -876,13 +876,13 @@ int sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip)
rsp_code = srb->cmnd[10];
retval =
- ext_sd_execute_no_data(chip, lun, cmd_idx, standby, acmd, rsp_code,
+ ext_rts51x_sd_execute_no_data(chip, lun, cmd_idx, standby, acmd, rsp_code,
arg);
scsi_set_resid(srb, 0);
return retval;
}
-int sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip)
+int rts51x_sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip)
{
struct sd_info *sd_card = &(chip->sd_card);
int retval;
@@ -891,7 +891,7 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip)
u32 arg, data_len;
if (!sd_card->sd_pass_thru_en) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -912,7 +912,7 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip)
rsp_code = srb->cmnd[10];
retval =
- ext_sd_execute_read_data(chip, lun, cmd_idx, send_cmd12, standby,
+ ext_rts51x_sd_execute_read_data(chip, lun, cmd_idx, send_cmd12, standby,
acmd, rsp_code, arg, data_len,
scsi_sglist(srb), scsi_bufflen(srb),
scsi_sg_count(srb));
@@ -920,7 +920,7 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip)
return retval;
}
-int sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip)
+int rts51x_sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip)
{
struct sd_info *sd_card = &(chip->sd_card);
int retval;
@@ -929,7 +929,7 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip)
u32 data_len, arg;
if (!sd_card->sd_pass_thru_en) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -950,7 +950,7 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip)
rsp_code = srb->cmnd[10];
retval =
- ext_sd_execute_write_data(chip, lun, cmd_idx, send_cmd12, standby,
+ ext_rts51x_sd_execute_write_data(chip, lun, cmd_idx, send_cmd12, standby,
acmd, rsp_code, arg, data_len,
scsi_sglist(srb), scsi_bufflen(srb),
scsi_sg_count(srb));
@@ -958,7 +958,7 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip)
return retval;
}
-int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip)
+int rts51x_sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip)
{
struct sd_info *sd_card = &(chip->sd_card);
unsigned int lun = SCSI_LUN(srb);
@@ -966,20 +966,20 @@ int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip)
u16 data_len;
if (!sd_card->sd_pass_thru_en) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if (sd_card->pre_cmd_err) {
sd_card->pre_cmd_err = 0;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
TRACE_RET(chip, TRANSPORT_FAILED);
}
data_len = ((u16) srb->cmnd[7] << 8) | srb->cmnd[8];
if (sd_card->last_rsp_type == SD_RSP_TYPE_R0) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
} else if (sd_card->last_rsp_type == SD_RSP_TYPE_R2) {
count = (data_len < 17) ? data_len : 17;
@@ -997,20 +997,20 @@ int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip)
return TRANSPORT_GOOD;
}
-int sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip)
+int rts51x_sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip)
{
struct sd_info *sd_card = &(chip->sd_card);
unsigned int lun = SCSI_LUN(srb);
int retval;
if (!sd_card->sd_pass_thru_en) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if (sd_card->pre_cmd_err) {
sd_card->pre_cmd_err = 0;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1018,16 +1018,16 @@ int sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip)
|| (0x20 != srb->cmnd[4]) || (0x43 != srb->cmnd[5])
|| (0x61 != srb->cmnd[6]) || (0x72 != srb->cmnd[7])
|| (0x64 != srb->cmnd[8])) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
switch (srb->cmnd[1] & 0x0F) {
case 0:
/* SD Card Power Off -> ON and Initialization */
- retval = reset_sd_card(chip);
+ retval = rts51x_reset_sd_card(chip);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
sd_card->pre_cmd_err = 1;
TRACE_RET(chip, TRANSPORT_FAILED);
}
@@ -1038,14 +1038,14 @@ int sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip)
* (without SD Card Power Off -> ON) */
retval = reset_sd(chip);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
sd_card->pre_cmd_err = 1;
TRACE_RET(chip, TRANSPORT_FAILED);
}
break;
default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, TRANSPORT_FAILED);
}
diff --git a/drivers/staging/rts5139/sd_cprm.h b/drivers/staging/rts5139/sd_cprm.h
index 75e263b6594..79dfd27db41 100644
--- a/drivers/staging/rts5139/sd_cprm.h
+++ b/drivers/staging/rts5139/sd_cprm.h
@@ -31,24 +31,24 @@
#include "sd.h"
#ifdef SUPPORT_CPRM
-int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun,
+int ext_rts51x_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun,
u8 cmd_idx, u8 standby, u8 acmd, u8 rsp_code,
u32 arg);
-int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun,
+int ext_rts51x_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun,
u8 cmd_idx, u8 cmd12, u8 standby, u8 acmd,
u8 rsp_code, u32 arg, u32 data_len, void *data_buf,
unsigned int buf_len, int use_sg);
-int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun,
+int ext_rts51x_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun,
u8 cmd_idx, u8 cmd12, u8 standby, u8 acmd,
u8 rsp_code, u32 arg, u32 data_len,
void *data_buf, unsigned int buf_len, int use_sg);
-int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip);
-int sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip);
-int sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip);
-int sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip);
-int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip);
-int sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip);
+int rts51x_sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip);
+int rts51x_sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip);
+int rts51x_sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip);
+int rts51x_sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip);
+int rts51x_sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip);
+int rts51x_sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip);
#endif
#endif /* __RTS51X_SD_CPRM_H */
diff --git a/drivers/staging/rts5139/xd.c b/drivers/staging/rts5139/xd.c
index 58f8ba24cae..10fea7e16ac 100644
--- a/drivers/staging/rts5139/xd.c
+++ b/drivers/staging/rts5139/xd.c
@@ -425,7 +425,7 @@ static int reset_xd(struct rts51x_chip *chip)
}
#endif
- retval = card_power_on(chip, XD_CARD);
+ retval = rts51x_card_power_on(chip, XD_CARD);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, retval);
#ifdef SUPPORT_OCP
@@ -472,8 +472,8 @@ static int reset_xd(struct rts51x_chip *chip)
rts51x_init_cmd(chip);
rts51x_add_cmd(chip, WRITE_REG_CMD, XD_DTCTL, 0xFF,
XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP *
- (2 + i + chip->option.xd_rw_step)
- + XD_TIME_RWN_STEP * (i + chip->option.xd_rwn_step));
+ (2 + i + chip->option.rts51x_xd_rw_step)
+ + XD_TIME_RWN_STEP * (i + chip->option.rts51x_xd_rwn_step));
rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CATCTL, 0xFF,
XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP * (4 +
i) + XD_TIME_RWN_STEP * (3 + i));
@@ -905,7 +905,7 @@ static u32 xd_get_l2p_tbl(struct rts51x_chip *chip, int zone_no, u16 log_off)
return (u32) zone->l2p_table[log_off] + ((u32) (zone_no) << 10);
}
-int reset_xd_card(struct rts51x_chip *chip)
+int rts51x_reset_xd_card(struct rts51x_chip *chip)
{
struct xd_info *xd_card = &(chip->xd_card);
int retval;
@@ -920,7 +920,7 @@ int reset_xd_card(struct rts51x_chip *chip)
xd_card->cis_block = 0xFFFF;
xd_card->delay_write.delay_write_flag = 0;
- enable_card_clock(chip, XD_CARD);
+ rts51x_enable_card_clock(chip, XD_CARD);
retval = reset_xd(chip);
if (retval != STATUS_SUCCESS) {
@@ -1526,7 +1526,7 @@ static int xd_read_multiple_pages(struct rts51x_chip *chip, u32 phy_blk,
rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS,
XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS);
- trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512,
+ rts51x_trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512,
DMA_512);
rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
@@ -1745,7 +1745,7 @@ static int xd_write_multiple_pages(struct rts51x_chip *chip, u32 old_blk,
rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01,
RING_BUFFER);
- trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512,
+ rts51x_trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512,
DMA_512);
rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
@@ -1842,7 +1842,7 @@ static int xd_delay_write(struct rts51x_chip *chip)
return STATUS_SUCCESS;
}
-int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
+int rts51x_xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
u16 sector_cnt)
{
struct xd_info *xd_card = &(chip->xd_card);
@@ -1860,7 +1860,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
xd_card->counter = 0;
- RTS51X_DEBUGP("xd_rw: scsi_bufflen = %d, scsi_sg_count = %d\n",
+ RTS51X_DEBUGP("rts51x_xd_rw: scsi_bufflen = %d, scsi_sg_count = %d\n",
scsi_bufflen(srb), scsi_sg_count(srb));
RTS51X_DEBUGP("Data direction: %s\n",
(srb->sc_data_direction ==
@@ -1883,7 +1883,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
retval = xd_build_l2p_tbl(chip, zone_no);
if (retval != STATUS_SUCCESS) {
chip->card_fail |= XD_CARD;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
+ rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, retval);
}
}
@@ -1900,7 +1900,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
delay_write->pageoff,
start_page);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_WRITE_ERR);
TRACE_RET(chip, retval);
}
@@ -1916,7 +1916,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
} else {
retval = xd_delay_write(chip);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_WRITE_ERR);
TRACE_RET(chip, retval);
}
@@ -1924,7 +1924,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
new_blk = xd_get_unused_block(chip, zone_no);
if ((old_blk == BLK_NOT_FOUND)
|| (new_blk == BLK_NOT_FOUND)) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_WRITE_ERR);
TRACE_RET(chip, retval);
}
@@ -1935,11 +1935,11 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
if (retval != STATUS_SUCCESS) {
if (monitor_card_cd(chip, XD_CARD) ==
CD_NOT_EXIST) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, STATUS_FAIL);
}
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_WRITE_ERR);
TRACE_RET(chip, retval);
}
@@ -1948,18 +1948,18 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
retval = xd_delay_write(chip);
if (retval != STATUS_SUCCESS) {
if (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, STATUS_FAIL);
}
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
TRACE_RET(chip, retval);
}
old_blk = xd_get_l2p_tbl(chip, zone_no, log_off);
if (old_blk == BLK_NOT_FOUND) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
TRACE_RET(chip, STATUS_FAIL);
}
@@ -1980,7 +1980,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
start_page, end_page,
buf, &ptr, &offset);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
TRACE_RET(chip, STATUS_FAIL);
}
@@ -1991,7 +1991,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
end_page, buf, &ptr,
&offset);
if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_WRITE_ERR);
TRACE_RET(chip, STATUS_FAIL);
}
@@ -2010,7 +2010,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
retval = xd_build_l2p_tbl(chip, zone_no);
if (retval != STATUS_SUCCESS) {
chip->card_fail |= XD_CARD;
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_NOT_PRESENT);
TRACE_RET(chip, retval);
}
@@ -2019,10 +2019,10 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
old_blk = xd_get_l2p_tbl(chip, zone_no, log_off);
if (old_blk == BLK_NOT_FOUND) {
if (srb->sc_data_direction == DMA_FROM_DEVICE) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
} else {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_WRITE_ERR);
}
TRACE_RET(chip, STATUS_FAIL);
@@ -2031,7 +2031,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
if (srb->sc_data_direction == DMA_TO_DEVICE) {
new_blk = xd_get_unused_block(chip, zone_no);
if (new_blk == BLK_NOT_FOUND) {
- set_sense_type(chip, lun,
+ rts51x_set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_WRITE_ERR);
TRACE_RET(chip, STATUS_FAIL);
}
@@ -2054,7 +2054,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
return STATUS_SUCCESS;
}
-void xd_free_l2p_tbl(struct rts51x_chip *chip)
+void rts51x_xd_free_l2p_tbl(struct rts51x_chip *chip)
{
struct xd_info *xd_card = &(chip->xd_card);
int i = 0;
@@ -2075,7 +2075,7 @@ void xd_free_l2p_tbl(struct rts51x_chip *chip)
}
}
-void xd_cleanup_work(struct rts51x_chip *chip)
+void rts51x_xd_cleanup_work(struct rts51x_chip *chip)
{
struct xd_info *xd_card = &(chip->xd_card);
@@ -2115,12 +2115,12 @@ static int xd_power_off_card3v3(struct rts51x_chip *chip)
return STATUS_SUCCESS;
}
-int release_xd_card(struct rts51x_chip *chip)
+int rts51x_release_xd_card(struct rts51x_chip *chip)
{
struct xd_info *xd_card = &(chip->xd_card);
int retval;
- RTS51X_DEBUGP("release_xd_card\n");
+ RTS51X_DEBUGP("rts51x_release_xd_card\n");
chip->card_ready &= ~XD_CARD;
chip->card_fail &= ~XD_CARD;
@@ -2128,7 +2128,7 @@ int release_xd_card(struct rts51x_chip *chip)
xd_card->delay_write.delay_write_flag = 0;
- xd_free_l2p_tbl(chip);
+ rts51x_xd_free_l2p_tbl(chip);
rts51x_write_register(chip, SFSM_ED, HW_CMD_STOP, HW_CMD_STOP);
diff --git a/drivers/staging/rts5139/xd.h b/drivers/staging/rts5139/xd.h
index 55e4205e23f..695a0b4d7e5 100644
--- a/drivers/staging/rts5139/xd.h
+++ b/drivers/staging/rts5139/xd.h
@@ -181,11 +181,11 @@
#define CIS1_8 (256 + 8)
#define CIS1_9 (256 + 9)
-int reset_xd_card(struct rts51x_chip *chip);
-int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
+int rts51x_reset_xd_card(struct rts51x_chip *chip);
+int rts51x_xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector,
u16 sector_cnt);
-void xd_free_l2p_tbl(struct rts51x_chip *chip);
-void xd_cleanup_work(struct rts51x_chip *chip);
-int release_xd_card(struct rts51x_chip *chip);
+void rts51x_xd_free_l2p_tbl(struct rts51x_chip *chip);
+void rts51x_xd_cleanup_work(struct rts51x_chip *chip);
+int rts51x_release_xd_card(struct rts51x_chip *chip);
#endif /* __RTS51X_XD_H */
diff --git a/drivers/staging/rts_pstor/Kconfig b/drivers/staging/rts_pstor/Kconfig
deleted file mode 100644
index 4d66a99fba8..00000000000
--- a/drivers/staging/rts_pstor/Kconfig
+++ /dev/null
@@ -1,16 +0,0 @@
-config RTS_PSTOR
- tristate "RealTek PCI-E Card Reader support"
- depends on PCI && SCSI
- help
- Say Y here to include driver code to support the Realtek
- PCI-E card readers.
-
- If this driver is compiled as a module, it will be named rts_pstor.
-
-config RTS_PSTOR_DEBUG
- bool "Realtek PCI-E Card Reader verbose debug"
- depends on RTS_PSTOR
- help
- Say Y here in order to have the rts_pstor code generate
- verbose debugging messages.
-
diff --git a/drivers/staging/rts_pstor/Makefile b/drivers/staging/rts_pstor/Makefile
deleted file mode 100644
index 42533d39c07..00000000000
--- a/drivers/staging/rts_pstor/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-ccflags := -Idrivers/scsi
-
-obj-$(CONFIG_RTS_PSTOR) := rts_pstor.o
-
-rts_pstor-y := \
- rtsx.o \
- rtsx_chip.o \
- rtsx_transport.o \
- rtsx_scsi.o \
- rtsx_card.o \
- general.o \
- sd.o \
- xd.o \
- ms.o \
- spi.o
-
diff --git a/drivers/staging/rts_pstor/TODO b/drivers/staging/rts_pstor/TODO
deleted file mode 100644
index becb95e4f2c..00000000000
--- a/drivers/staging/rts_pstor/TODO
+++ /dev/null
@@ -1,9 +0,0 @@
-TODO:
-- support more pcie card reader of Realtek family
-- use kernel coding style
-- checkpatch.pl fixes
-- stop having thousands of lines of code duplicated with staging/rts5139
-- This driver contains an entire SD/MMC stack -- it should use the stack in
- drivers/mmc instead, as a host driver e.g. drivers/mmc/host/realtek-pci.c;
- see drivers/mmc/host/via-sdmmc.c as an example.
-- This driver presents cards as SCSI devices, but they should be MMC devices.
diff --git a/drivers/staging/rts_pstor/general.c b/drivers/staging/rts_pstor/general.c
deleted file mode 100644
index 056e98d2475..00000000000
--- a/drivers/staging/rts_pstor/general.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#include "general.h"
-
-int bit1cnt_long(u32 data)
-{
- int i, cnt = 0;
- for (i = 0; i < 32; i++) {
- if (data & 0x01)
- cnt++;
- data >>= 1;
- }
- return cnt;
-}
-
diff --git a/drivers/staging/rts_pstor/ms.c b/drivers/staging/rts_pstor/ms.c
deleted file mode 100644
index 16a5c16fb6a..00000000000
--- a/drivers/staging/rts_pstor/ms.c
+++ /dev/null
@@ -1,4051 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#include <linux/blkdev.h>
-#include <linux/kthread.h>
-#include <linux/sched.h>
-#include <linux/vmalloc.h>
-
-#include "rtsx.h"
-#include "rtsx_transport.h"
-#include "rtsx_scsi.h"
-#include "rtsx_card.h"
-#include "ms.h"
-
-static inline void ms_set_err_code(struct rtsx_chip *chip, u8 err_code)
-{
- struct ms_info *ms_card = &(chip->ms_card);
-
- ms_card->err_code = err_code;
-}
-
-static inline int ms_check_err_code(struct rtsx_chip *chip, u8 err_code)
-{
- struct ms_info *ms_card = &(chip->ms_card);
-
- return (ms_card->err_code == err_code);
-}
-
-static int ms_parse_err_code(struct rtsx_chip *chip)
-{
- TRACE_RET(chip, STATUS_FAIL);
-}
-
-static int ms_transfer_tpc(struct rtsx_chip *chip, u8 trans_mode, u8 tpc, u8 cnt, u8 cfg)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
- u8 *ptr;
-
- RTSX_DEBUGP("ms_transfer_tpc: tpc = 0x%x\n", tpc);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | trans_mode);
- rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END);
-
- rtsx_add_cmd(chip, READ_REG_CMD, MS_TRANS_CFG, 0, 0);
-
- retval = rtsx_send_cmd(chip, MS_CARD, 5000);
- if (retval < 0) {
- rtsx_clear_ms_error(chip);
- ms_set_err_code(chip, MS_TO_ERROR);
- TRACE_RET(chip, ms_parse_err_code(chip));
- }
-
- ptr = rtsx_get_cmd_data(chip) + 1;
-
- if (!(tpc & 0x08)) { /* Read Packet */
- if (*ptr & MS_CRC16_ERR) {
- ms_set_err_code(chip, MS_CRC16_ERROR);
- TRACE_RET(chip, ms_parse_err_code(chip));
- }
- } else { /* Write Packet */
- if (CHK_MSPRO(ms_card) && !(*ptr & 0x80)) {
- if (*ptr & (MS_INT_ERR | MS_INT_CMDNK)) {
- ms_set_err_code(chip, MS_CMD_NK);
- TRACE_RET(chip, ms_parse_err_code(chip));
- }
- }
- }
-
- if (*ptr & MS_RDY_TIMEOUT) {
- rtsx_clear_ms_error(chip);
- ms_set_err_code(chip, MS_TO_ERROR);
- TRACE_RET(chip, ms_parse_err_code(chip));
- }
-
- return STATUS_SUCCESS;
-}
-
-static int ms_transfer_data(struct rtsx_chip *chip, u8 trans_mode, u8 tpc, u16 sec_cnt,
- u8 cfg, int mode_2k, int use_sg, void *buf, int buf_len)
-{
- int retval;
- u8 val, err_code = 0;
- enum dma_data_direction dir;
-
- if (!buf || !buf_len)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (trans_mode == MS_TM_AUTO_READ) {
- dir = DMA_FROM_DEVICE;
- err_code = MS_FLASH_READ_ERROR;
- } else if (trans_mode == MS_TM_AUTO_WRITE) {
- dir = DMA_TO_DEVICE;
- err_code = MS_FLASH_WRITE_ERROR;
- } else {
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
- rtsx_add_cmd(chip, WRITE_REG_CMD,
- MS_SECTOR_CNT_H, 0xFF, (u8)(sec_cnt >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_L, 0xFF, (u8)sec_cnt);
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
-
- if (mode_2k) {
- rtsx_add_cmd(chip, WRITE_REG_CMD,
- MS_CFG, MS_2K_SECTOR_MODE, MS_2K_SECTOR_MODE);
- } else {
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_CFG, MS_2K_SECTOR_MODE, 0);
- }
-
- trans_dma_enable(dir, chip, sec_cnt * 512, DMA_512);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD,
- MS_TRANSFER, 0xFF, MS_TRANSFER_START | trans_mode);
- rtsx_add_cmd(chip, CHECK_REG_CMD,
- MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END);
-
- rtsx_send_cmd_no_wait(chip);
-
- retval = rtsx_transfer_data(chip, MS_CARD, buf, buf_len,
- use_sg, dir, chip->mspro_timeout);
- if (retval < 0) {
- ms_set_err_code(chip, err_code);
- if (retval == -ETIMEDOUT)
- retval = STATUS_TIMEDOUT;
- else
- retval = STATUS_FAIL;
-
- TRACE_RET(chip, retval);
- }
-
- RTSX_READ_REG(chip, MS_TRANS_CFG, &val);
- if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT))
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int ms_write_bytes(struct rtsx_chip *chip,
- u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, i;
-
- if (!data || (data_len < cnt))
- TRACE_RET(chip, STATUS_ERROR);
-
- rtsx_init_cmd(chip);
-
- for (i = 0; i < cnt; i++) {
- rtsx_add_cmd(chip, WRITE_REG_CMD,
- PPBUF_BASE2 + i, 0xFF, data[i]);
- }
- if (cnt % 2)
- rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, 0xFF, 0xFF);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD,
- MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES);
- rtsx_add_cmd(chip, CHECK_REG_CMD,
- MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END);
-
- retval = rtsx_send_cmd(chip, MS_CARD, 5000);
- if (retval < 0) {
- u8 val = 0;
-
- rtsx_read_register(chip, MS_TRANS_CFG, &val);
- RTSX_DEBUGP("MS_TRANS_CFG: 0x%02x\n", val);
-
- rtsx_clear_ms_error(chip);
-
- if (!(tpc & 0x08)) {
- if (val & MS_CRC16_ERR) {
- ms_set_err_code(chip, MS_CRC16_ERROR);
- TRACE_RET(chip, ms_parse_err_code(chip));
- }
- } else {
- if (CHK_MSPRO(ms_card) && !(val & 0x80)) {
- if (val & (MS_INT_ERR | MS_INT_CMDNK)) {
- ms_set_err_code(chip, MS_CMD_NK);
- TRACE_RET(chip, ms_parse_err_code(chip));
- }
- }
- }
-
- if (val & MS_RDY_TIMEOUT) {
- ms_set_err_code(chip, MS_TO_ERROR);
- TRACE_RET(chip, ms_parse_err_code(chip));
- }
-
- ms_set_err_code(chip, MS_TO_ERROR);
- TRACE_RET(chip, ms_parse_err_code(chip));
- }
-
- return STATUS_SUCCESS;
-}
-
-static int ms_read_bytes(struct rtsx_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, i;
- u8 *ptr;
-
- if (!data)
- TRACE_RET(chip, STATUS_ERROR);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_READ_BYTES);
- rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END);
-
- for (i = 0; i < data_len - 1; i++)
- rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0);
-
- if (data_len % 2)
- rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len, 0, 0);
- else
- rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len - 1, 0, 0);
-
- retval = rtsx_send_cmd(chip, MS_CARD, 5000);
- if (retval < 0) {
- u8 val = 0;
-
- rtsx_read_register(chip, MS_TRANS_CFG, &val);
- rtsx_clear_ms_error(chip);
-
- if (!(tpc & 0x08)) {
- if (val & MS_CRC16_ERR) {
- ms_set_err_code(chip, MS_CRC16_ERROR);
- TRACE_RET(chip, ms_parse_err_code(chip));
- }
- } else {
- if (CHK_MSPRO(ms_card) && !(val & 0x80)) {
- if (val & (MS_INT_ERR | MS_INT_CMDNK)) {
- ms_set_err_code(chip, MS_CMD_NK);
- TRACE_RET(chip, ms_parse_err_code(chip));
- }
- }
- }
-
- if (val & MS_RDY_TIMEOUT) {
- ms_set_err_code(chip, MS_TO_ERROR);
- TRACE_RET(chip, ms_parse_err_code(chip));
- }
-
- ms_set_err_code(chip, MS_TO_ERROR);
- TRACE_RET(chip, ms_parse_err_code(chip));
- }
-
- ptr = rtsx_get_cmd_data(chip) + 1;
-
- for (i = 0; i < data_len; i++)
- data[i] = ptr[i];
-
- if ((tpc == PRO_READ_SHORT_DATA) && (data_len == 8)) {
- RTSX_DEBUGP("Read format progress:\n");
- RTSX_DUMP(ptr, cnt);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int ms_set_rw_reg_addr(struct rtsx_chip *chip,
- u8 read_start, u8 read_cnt, u8 write_start, u8 write_cnt)
-{
- int retval, i;
- u8 data[4];
-
- data[0] = read_start;
- data[1] = read_cnt;
- data[2] = write_start;
- data[3] = write_cnt;
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_write_bytes(chip, SET_RW_REG_ADRS, 4,
- NO_WAIT_INT, data, 4);
- if (retval == STATUS_SUCCESS)
- return STATUS_SUCCESS;
- rtsx_clear_ms_error(chip);
- }
-
- TRACE_RET(chip, STATUS_FAIL);
-}
-
-static int ms_send_cmd(struct rtsx_chip *chip, u8 cmd, u8 cfg)
-{
- u8 data[2];
-
- data[0] = cmd;
- data[1] = 0;
-
- return ms_write_bytes(chip, PRO_SET_CMD, 1, cfg, data, 1);
-}
-
-static int ms_set_init_para(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
-
- if (CHK_HG8BIT(ms_card)) {
- if (chip->asic_code)
- ms_card->ms_clock = chip->asic_ms_hg_clk;
- else
- ms_card->ms_clock = chip->fpga_ms_hg_clk;
-
- } else if (CHK_MSPRO(ms_card) || CHK_MS4BIT(ms_card)) {
- if (chip->asic_code)
- ms_card->ms_clock = chip->asic_ms_4bit_clk;
- else
- ms_card->ms_clock = chip->fpga_ms_4bit_clk;
-
- } else {
- if (chip->asic_code)
- ms_card->ms_clock = chip->asic_ms_1bit_clk;
- else
- ms_card->ms_clock = chip->fpga_ms_1bit_clk;
- }
-
- retval = switch_clock(chip, ms_card->ms_clock);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = select_card(chip, MS_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int ms_switch_clock(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
-
- retval = select_card(chip, MS_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = switch_clock(chip, ms_card->ms_clock);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int ms_pull_ctl_disable(struct rtsx_chip *chip)
-{
- if (CHECK_PID(chip, 0x5209)) {
- RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x55);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, 0x55);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, 0x15);
- } else if (CHECK_PID(chip, 0x5208)) {
- RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF,
- MS_D1_PD | MS_D2_PD | MS_CLK_PD | MS_D6_PD);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF,
- MS_D3_PD | MS_D0_PD | MS_BS_PD | XD_D4_PD);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF,
- MS_D7_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF,
- XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF,
- MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF,
- MS_D5_PD | MS_D4_PD);
- } else if (CHECK_PID(chip, 0x5288)) {
- if (CHECK_BARO_PKG(chip, QFN)) {
- RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69);
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-static int ms_pull_ctl_enable(struct rtsx_chip *chip)
-{
- int retval;
-
- rtsx_init_cmd(chip);
-
- if (CHECK_PID(chip, 0x5209)) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x15);
- } else if (CHECK_PID(chip, 0x5208)) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF,
- MS_D1_PD | MS_D2_PD | MS_CLK_NP | MS_D6_PD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF,
- MS_D3_PD | MS_D0_PD | MS_BS_NP | XD_D4_PD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF,
- MS_D7_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF,
- XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF,
- MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF,
- MS_D5_PD | MS_D4_PD);
- } else if (CHECK_PID(chip, 0x5288)) {
- if (CHECK_BARO_PKG(chip, QFN)) {
- rtsx_add_cmd(chip, WRITE_REG_CMD,
- CARD_PULL_CTL1, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD,
- CARD_PULL_CTL2, 0xFF, 0x45);
- rtsx_add_cmd(chip, WRITE_REG_CMD,
- CARD_PULL_CTL3, 0xFF, 0x4B);
- rtsx_add_cmd(chip, WRITE_REG_CMD,
- CARD_PULL_CTL4, 0xFF, 0x29);
- }
- }
-
- retval = rtsx_send_cmd(chip, MS_CARD, 100);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int ms_prepare_reset(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
- u8 oc_mask = 0;
-
- ms_card->ms_type = 0;
- ms_card->check_ms_flow = 0;
- ms_card->switch_8bit_fail = 0;
- ms_card->delay_write.delay_write_flag = 0;
-
- ms_card->pro_under_formatting = 0;
-
- retval = ms_power_off_card3v3(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (!chip->ft2_fast_mode)
- wait_timeout(250);
-
- retval = enable_card_clock(chip, MS_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (chip->asic_code) {
- retval = ms_pull_ctl_enable(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_MS_PULL_CTL_BIT | 0x20, 0);
- }
-
- if (!chip->ft2_fast_mode) {
- retval = card_power_on(chip, MS_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- wait_timeout(150);
-
-#ifdef SUPPORT_OCP
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN))
- oc_mask = MS_OC_NOW | MS_OC_EVER;
- else
- oc_mask = SD_OC_NOW | SD_OC_EVER;
-
- if (chip->ocp_stat & oc_mask) {
- RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n",
- chip->ocp_stat);
- TRACE_RET(chip, STATUS_FAIL);
- }
-#endif
- }
-
- RTSX_WRITE_REG(chip, CARD_OE, MS_OUTPUT_EN, MS_OUTPUT_EN);
-
- if (chip->asic_code) {
- RTSX_WRITE_REG(chip, MS_CFG, 0xFF,
- SAMPLE_TIME_RISING | PUSH_TIME_DEFAULT |
- NO_EXTEND_TOGGLE | MS_BUS_WIDTH_1);
- } else {
- RTSX_WRITE_REG(chip, MS_CFG, 0xFF,
- SAMPLE_TIME_FALLING | PUSH_TIME_DEFAULT |
- NO_EXTEND_TOGGLE | MS_BUS_WIDTH_1);
- }
- RTSX_WRITE_REG(chip, MS_TRANS_CFG, 0xFF, NO_WAIT_INT | NO_AUTO_READ_INT_REG);
- RTSX_WRITE_REG(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR);
-
- retval = ms_set_init_para(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, i;
- u8 val;
-
- retval = ms_set_rw_reg_addr(chip, Pro_StatusReg, 6, SystemParm, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, READ_REG, 6, NO_WAIT_INT);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (i == MS_MAX_RETRY_COUNT)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_READ_REG(chip, PPBUF_BASE2 + 2, &val);
- RTSX_DEBUGP("Type register: 0x%x\n", val);
- if (val != 0x01) {
- if (val != 0x02)
- ms_card->check_ms_flow = 1;
-
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- RTSX_READ_REG(chip, PPBUF_BASE2 + 4, &val);
- RTSX_DEBUGP("Category register: 0x%x\n", val);
- if (val != 0) {
- ms_card->check_ms_flow = 1;
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- RTSX_READ_REG(chip, PPBUF_BASE2 + 5, &val);
- RTSX_DEBUGP("Class register: 0x%x\n", val);
- if (val == 0) {
- RTSX_READ_REG(chip, PPBUF_BASE2, &val);
- if (val & WRT_PRTCT)
- chip->card_wp |= MS_CARD;
- else
- chip->card_wp &= ~MS_CARD;
-
- } else if ((val == 0x01) || (val == 0x02) || (val == 0x03)) {
- chip->card_wp |= MS_CARD;
- } else {
- ms_card->check_ms_flow = 1;
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- ms_card->ms_type |= TYPE_MSPRO;
-
- RTSX_READ_REG(chip, PPBUF_BASE2 + 3, &val);
- RTSX_DEBUGP("IF Mode register: 0x%x\n", val);
- if (val == 0) {
- ms_card->ms_type &= 0x0F;
- } else if (val == 7) {
- if (switch_8bit_bus)
- ms_card->ms_type |= MS_HG;
- else
- ms_card->ms_type &= 0x0F;
-
- } else {
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int ms_confirm_cpu_startup(struct rtsx_chip *chip)
-{
- int retval, i, k;
- u8 val;
-
- /* Confirm CPU StartUp */
- k = 0;
- do {
- if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
- ms_set_err_code(chip, MS_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (i == MS_MAX_RETRY_COUNT)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (k > 100)
- TRACE_RET(chip, STATUS_FAIL);
-
- k++;
- wait_timeout(100);
- } while (!(val & INT_REG_CED));
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (i == MS_MAX_RETRY_COUNT)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (val & INT_REG_ERR) {
- if (val & INT_REG_CMDNK)
- chip->card_wp |= (MS_CARD);
- else
- TRACE_RET(chip, STATUS_FAIL);
- }
- /* -- end confirm CPU startup */
-
- return STATUS_SUCCESS;
-}
-
-static int ms_switch_parallel_bus(struct rtsx_chip *chip)
-{
- int retval, i;
- u8 data[2];
-
- data[0] = PARALLEL_4BIT_IF;
- data[1] = 0;
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_write_bytes(chip, WRITE_REG, 1, NO_WAIT_INT, data, 2);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int ms_switch_8bit_bus(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, i;
- u8 data[2];
-
- data[0] = PARALLEL_8BIT_IF;
- data[1] = 0;
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_write_bytes(chip, WRITE_REG, 1, NO_WAIT_INT, data, 2);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, MS_CFG, 0x98, MS_BUS_WIDTH_8 | SAMPLE_TIME_FALLING);
- ms_card->ms_type |= MS_8BIT;
- retval = ms_set_init_para(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1, NO_WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int ms_pro_reset_flow(struct rtsx_chip *chip, int switch_8bit_bus)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, i;
-
- for (i = 0; i < 3; i++) {
- retval = ms_prepare_reset(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_identify_media_type(chip, switch_8bit_bus);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_confirm_cpu_startup(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_switch_parallel_bus(chip);
- if (retval != STATUS_SUCCESS) {
- if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
- ms_set_err_code(chip, MS_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
- continue;
- } else {
- break;
- }
- }
-
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- /* Switch MS-PRO into Parallel mode */
- RTSX_WRITE_REG(chip, MS_CFG, 0x18, MS_BUS_WIDTH_4);
- RTSX_WRITE_REG(chip, MS_CFG, PUSH_TIME_ODD, PUSH_TIME_ODD);
-
- retval = ms_set_init_para(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- /* If MSPro HG Card, We shall try to switch to 8-bit bus */
- if (CHK_MSHG(ms_card) && chip->support_ms_8bit && switch_8bit_bus) {
- retval = ms_switch_8bit_bus(chip);
- if (retval != STATUS_SUCCESS) {
- ms_card->switch_8bit_fail = 1;
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-#ifdef XC_POWERCLASS
-static int msxc_change_power(struct rtsx_chip *chip, u8 mode)
-{
- int retval;
- u8 buf[6];
-
- ms_cleanup_work(chip);
-
- retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- buf[0] = 0;
- buf[1] = mode;
- buf[2] = 0;
- buf[3] = 0;
- buf[4] = 0;
- buf[5] = 0;
-
- retval = ms_write_bytes(chip, PRO_WRITE_REG , 6, NO_WAIT_INT, buf, 6);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_send_cmd(chip, XC_CHG_POWER, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_READ_REG(chip, MS_TRANS_CFG, buf);
- if (buf[0] & (MS_INT_CMDNK | MS_INT_ERR))
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-#endif
-
-static int ms_read_attribute_info(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, i;
- u8 val, *buf, class_code, device_type, sub_class, data[16];
- u16 total_blk = 0, blk_size = 0;
-#ifdef SUPPORT_MSXC
- u32 xc_total_blk = 0, xc_blk_size = 0;
-#endif
- u32 sys_info_addr = 0, sys_info_size;
-#ifdef SUPPORT_PCGL_1P18
- u32 model_name_addr = 0, model_name_size;
- int found_sys_info = 0, found_model_name = 0;
-#endif
-
- retval = ms_set_rw_reg_addr(chip, Pro_IntReg, 2, Pro_SystemParm, 7);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHK_MS8BIT(ms_card))
- data[0] = PARALLEL_8BIT_IF;
- else
- data[0] = PARALLEL_4BIT_IF;
-
- data[1] = 0;
-
- data[2] = 0x40;
- data[3] = 0;
- data[4] = 0;
- data[5] = 0;
- data[6] = 0;
- data[7] = 0;
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_write_bytes(chip, PRO_WRITE_REG, 7, NO_WAIT_INT, data, 8);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- buf = kmalloc(64 * 512, GFP_KERNEL);
- if (buf == NULL)
- TRACE_RET(chip, STATUS_ERROR);
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_send_cmd(chip, PRO_READ_ATRB, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- continue;
-
- retval = rtsx_read_register(chip, MS_TRANS_CFG, &val);
- if (retval != STATUS_SUCCESS) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (!(val & MS_INT_BREQ)) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
- retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA,
- 0x40, WAIT_INT, 0, 0, buf, 64 * 512);
- if (retval == STATUS_SUCCESS)
- break;
- else
- rtsx_clear_ms_error(chip);
- }
- if (retval != STATUS_SUCCESS) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- i = 0;
- do {
- retval = rtsx_read_register(chip, MS_TRANS_CFG, &val);
- if (retval != STATUS_SUCCESS) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if ((val & MS_INT_CED) || !(val & MS_INT_BREQ))
- break;
-
- retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, PRO_READ_LONG_DATA, 0, WAIT_INT);
- if (retval != STATUS_SUCCESS) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- i++;
- } while (i < 1024);
-
- if (retval != STATUS_SUCCESS) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if ((buf[0] != 0xa5) && (buf[1] != 0xc3)) {
- /* Signature code is wrong */
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if ((buf[4] < 1) || (buf[4] > 12)) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- for (i = 0; i < buf[4]; i++) {
- int cur_addr_off = 16 + i * 12;
-
-#ifdef SUPPORT_MSXC
- if ((buf[cur_addr_off + 8] == 0x10) || (buf[cur_addr_off + 8] == 0x13))
-#else
- if (buf[cur_addr_off + 8] == 0x10)
-#endif
- {
- sys_info_addr = ((u32)buf[cur_addr_off + 0] << 24) |
- ((u32)buf[cur_addr_off + 1] << 16) |
- ((u32)buf[cur_addr_off + 2] << 8) | buf[cur_addr_off + 3];
- sys_info_size = ((u32)buf[cur_addr_off + 4] << 24) |
- ((u32)buf[cur_addr_off + 5] << 16) |
- ((u32)buf[cur_addr_off + 6] << 8) | buf[cur_addr_off + 7];
- RTSX_DEBUGP("sys_info_addr = 0x%x, sys_info_size = 0x%x\n",
- sys_info_addr, sys_info_size);
- if (sys_info_size != 96) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (sys_info_addr < 0x1A0) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if ((sys_info_size + sys_info_addr) > 0x8000) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
-#ifdef SUPPORT_MSXC
- if (buf[cur_addr_off + 8] == 0x13)
- ms_card->ms_type |= MS_XC;
-#endif
-#ifdef SUPPORT_PCGL_1P18
- found_sys_info = 1;
-#else
- break;
-#endif
- }
-#ifdef SUPPORT_PCGL_1P18
- if (buf[cur_addr_off + 8] == 0x15) {
- model_name_addr = ((u32)buf[cur_addr_off + 0] << 24) |
- ((u32)buf[cur_addr_off + 1] << 16) |
- ((u32)buf[cur_addr_off + 2] << 8) | buf[cur_addr_off + 3];
- model_name_size = ((u32)buf[cur_addr_off + 4] << 24) |
- ((u32)buf[cur_addr_off + 5] << 16) |
- ((u32)buf[cur_addr_off + 6] << 8) | buf[cur_addr_off + 7];
- RTSX_DEBUGP("model_name_addr = 0x%x, model_name_size = 0x%x\n",
- model_name_addr, model_name_size);
- if (model_name_size != 48) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (model_name_addr < 0x1A0) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if ((model_name_size + model_name_addr) > 0x8000) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- found_model_name = 1;
- }
-
- if (found_sys_info && found_model_name)
- break;
-#endif
- }
-
- if (i == buf[4]) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- class_code = buf[sys_info_addr + 0];
- device_type = buf[sys_info_addr + 56];
- sub_class = buf[sys_info_addr + 46];
-#ifdef SUPPORT_MSXC
- if (CHK_MSXC(ms_card)) {
- xc_total_blk = ((u32)buf[sys_info_addr + 6] << 24) |
- ((u32)buf[sys_info_addr + 7] << 16) |
- ((u32)buf[sys_info_addr + 8] << 8) |
- buf[sys_info_addr + 9];
- xc_blk_size = ((u32)buf[sys_info_addr + 32] << 24) |
- ((u32)buf[sys_info_addr + 33] << 16) |
- ((u32)buf[sys_info_addr + 34] << 8) |
- buf[sys_info_addr + 35];
- RTSX_DEBUGP("xc_total_blk = 0x%x, xc_blk_size = 0x%x\n", xc_total_blk, xc_blk_size);
- } else {
- total_blk = ((u16)buf[sys_info_addr + 6] << 8) | buf[sys_info_addr + 7];
- blk_size = ((u16)buf[sys_info_addr + 2] << 8) | buf[sys_info_addr + 3];
- RTSX_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n", total_blk, blk_size);
- }
-#else
- total_blk = ((u16)buf[sys_info_addr + 6] << 8) | buf[sys_info_addr + 7];
- blk_size = ((u16)buf[sys_info_addr + 2] << 8) | buf[sys_info_addr + 3];
- RTSX_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n", total_blk, blk_size);
-#endif
-
- RTSX_DEBUGP("class_code = 0x%x, device_type = 0x%x, sub_class = 0x%x\n",
- class_code, device_type, sub_class);
-
- memcpy(ms_card->raw_sys_info, buf + sys_info_addr, 96);
-#ifdef SUPPORT_PCGL_1P18
- memcpy(ms_card->raw_model_name, buf + model_name_addr, 48);
-#endif
-
- kfree(buf);
-
-#ifdef SUPPORT_MSXC
- if (CHK_MSXC(ms_card)) {
- if (class_code != 0x03)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- if (class_code != 0x02)
- TRACE_RET(chip, STATUS_FAIL);
- }
-#else
- if (class_code != 0x02)
- TRACE_RET(chip, STATUS_FAIL);
-#endif
-
- if (device_type != 0x00) {
- if ((device_type == 0x01) || (device_type == 0x02) ||
- (device_type == 0x03)) {
- chip->card_wp |= MS_CARD;
- } else {
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- if (sub_class & 0xC0)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_DEBUGP("class_code: 0x%x, device_type: 0x%x, sub_class: 0x%x\n",
- class_code, device_type, sub_class);
-
-#ifdef SUPPORT_MSXC
- if (CHK_MSXC(ms_card)) {
- chip->capacity[chip->card2lun[MS_CARD]] =
- ms_card->capacity = xc_total_blk * xc_blk_size;
- } else {
- chip->capacity[chip->card2lun[MS_CARD]] =
- ms_card->capacity = total_blk * blk_size;
- }
-#else
- chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity = total_blk * blk_size;
-#endif
-
- return STATUS_SUCCESS;
-}
-
-#ifdef SUPPORT_MAGIC_GATE
-static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type, u8 mg_entry_num);
-#endif
-
-static int reset_ms_pro(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
-#ifdef XC_POWERCLASS
- u8 change_power_class;
-
- if (chip->ms_power_class_en & 0x02)
- change_power_class = 2;
- else if (chip->ms_power_class_en & 0x01)
- change_power_class = 1;
- else
- change_power_class = 0;
-#endif
-
-#ifdef XC_POWERCLASS
-Retry:
-#endif
- retval = ms_pro_reset_flow(chip, 1);
- if (retval != STATUS_SUCCESS) {
- if (ms_card->switch_8bit_fail) {
- retval = ms_pro_reset_flow(chip, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- retval = ms_read_attribute_info(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
-#ifdef XC_POWERCLASS
- if (CHK_HG8BIT(ms_card))
- change_power_class = 0;
-
- if (change_power_class && CHK_MSXC(ms_card)) {
- u8 power_class_en = chip->ms_power_class_en;
-
- RTSX_DEBUGP("power_class_en = 0x%x\n", power_class_en);
- RTSX_DEBUGP("change_power_class = %d\n", change_power_class);
-
- if (change_power_class)
- power_class_en &= (1 << (change_power_class - 1));
- else
- power_class_en = 0;
-
- if (power_class_en) {
- u8 power_class_mode = (ms_card->raw_sys_info[46] & 0x18) >> 3;
- RTSX_DEBUGP("power_class_mode = 0x%x", power_class_mode);
- if (change_power_class > power_class_mode)
- change_power_class = power_class_mode;
- if (change_power_class) {
- retval = msxc_change_power(chip, change_power_class);
- if (retval != STATUS_SUCCESS) {
- change_power_class--;
- goto Retry;
- }
- }
- }
- }
-#endif
-
-#ifdef SUPPORT_MAGIC_GATE
- retval = mg_set_tpc_para_sub(chip, 0, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-#endif
-
- if (CHK_HG8BIT(ms_card))
- chip->card_bus_width[chip->card2lun[MS_CARD]] = 8;
- else
- chip->card_bus_width[chip->card2lun[MS_CARD]] = 4;
-
- return STATUS_SUCCESS;
-}
-
-static int ms_read_status_reg(struct rtsx_chip *chip)
-{
- int retval;
- u8 val[2];
-
- retval = ms_set_rw_reg_addr(chip, StatusReg0, 2, 0, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_read_bytes(chip, READ_REG, 2, NO_WAIT_INT, val, 2);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (val[1] & (STS_UCDT | STS_UCEX | STS_UCFG)) {
- ms_set_err_code(chip, MS_FLASH_READ_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static int ms_read_extra_data(struct rtsx_chip *chip,
- u16 block_addr, u8 page_num, u8 *buf, int buf_len)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, i;
- u8 val, data[10];
-
- retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHK_MS4BIT(ms_card)) {
- /* Parallel interface */
- data[0] = 0x88;
- } else {
- /* Serial interface */
- data[0] = 0x80;
- }
- data[1] = 0;
- data[2] = (u8)(block_addr >> 8);
- data[3] = (u8)block_addr;
- data[4] = 0x40;
- data[5] = page_num;
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (i == MS_MAX_RETRY_COUNT)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (i == MS_MAX_RETRY_COUNT)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (val & INT_REG_CMDNK) {
- ms_set_err_code(chip, MS_CMD_NK);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (val & INT_REG_CED) {
- if (val & INT_REG_ERR) {
- retval = ms_read_status_reg(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- retval = ms_read_bytes(chip, READ_REG, MS_EXTRA_SIZE, NO_WAIT_INT, data, MS_EXTRA_SIZE);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (buf && buf_len) {
- if (buf_len > MS_EXTRA_SIZE)
- buf_len = MS_EXTRA_SIZE;
- memcpy(buf, data, buf_len);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int ms_write_extra_data(struct rtsx_chip *chip,
- u16 block_addr, u8 page_num, u8 *buf, int buf_len)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, i;
- u8 val, data[16];
-
- if (!buf || (buf_len < MS_EXTRA_SIZE))
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6 + MS_EXTRA_SIZE);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHK_MS4BIT(ms_card))
- data[0] = 0x88;
- else
- data[0] = 0x80;
-
- data[1] = 0;
- data[2] = (u8)(block_addr >> 8);
- data[3] = (u8)block_addr;
- data[4] = 0x40;
- data[5] = page_num;
-
- for (i = 6; i < MS_EXTRA_SIZE + 6; i++)
- data[i] = buf[i - 6];
-
- retval = ms_write_bytes(chip, WRITE_REG , (6+MS_EXTRA_SIZE), NO_WAIT_INT, data, 16);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (val & INT_REG_CMDNK) {
- ms_set_err_code(chip, MS_CMD_NK);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (val & INT_REG_CED) {
- if (val & INT_REG_ERR) {
- ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
- u8 val, data[6];
-
- retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHK_MS4BIT(ms_card))
- data[0] = 0x88;
- else
- data[0] = 0x80;
-
- data[1] = 0;
- data[2] = (u8)(block_addr >> 8);
- data[3] = (u8)block_addr;
- data[4] = 0x20;
- data[5] = page_num;
-
- retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT, data, 6);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (val & INT_REG_CMDNK) {
- ms_set_err_code(chip, MS_CMD_NK);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (val & INT_REG_CED) {
- if (val & INT_REG_ERR) {
- if (!(val & INT_REG_BREQ)) {
- ms_set_err_code(chip, MS_FLASH_READ_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- retval = ms_read_status_reg(chip);
- if (retval != STATUS_SUCCESS)
- ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
-
- } else {
- if (!(val & INT_REG_BREQ)) {
- ms_set_err_code(chip, MS_BREQ_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
- }
-
- retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA, 0, NO_WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR))
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-
-static int ms_set_bad_block(struct rtsx_chip *chip, u16 phy_blk)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
- u8 val, data[8], extra[MS_EXTRA_SIZE];
-
- retval = ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
-
- if (CHK_MS4BIT(ms_card))
- data[0] = 0x88;
- else
- data[0] = 0x80;
-
- data[1] = 0;
- data[2] = (u8)(phy_blk >> 8);
- data[3] = (u8)phy_blk;
- data[4] = 0x80;
- data[5] = 0;
- data[6] = extra[0] & 0x7F;
- data[7] = 0xFF;
-
- retval = ms_write_bytes(chip, WRITE_REG , 7, NO_WAIT_INT, data, 7);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (val & INT_REG_CMDNK) {
- ms_set_err_code(chip, MS_CMD_NK);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (val & INT_REG_CED) {
- if (val & INT_REG_ERR) {
- ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static int ms_erase_block(struct rtsx_chip *chip, u16 phy_blk)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, i = 0;
- u8 val, data[6];
-
- retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
-
- if (CHK_MS4BIT(ms_card))
- data[0] = 0x88;
- else
- data[0] = 0x80;
-
- data[1] = 0;
- data[2] = (u8)(phy_blk >> 8);
- data[3] = (u8)phy_blk;
- data[4] = 0;
- data[5] = 0;
-
- retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
-ERASE_RTY:
- retval = ms_send_cmd(chip, BLOCK_ERASE, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (val & INT_REG_CMDNK) {
- if (i < 3) {
- i++;
- goto ERASE_RTY;
- }
-
- ms_set_err_code(chip, MS_CMD_NK);
- ms_set_bad_block(chip, phy_blk);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (val & INT_REG_CED) {
- if (val & INT_REG_ERR) {
- ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static void ms_set_page_status(u16 log_blk, u8 type, u8 *extra, int extra_len)
-{
- if (!extra || (extra_len < MS_EXTRA_SIZE))
- return;
-
- memset(extra, 0xFF, MS_EXTRA_SIZE);
-
- if (type == setPS_NG) {
- /* set page status as 1:NG,and block status keep 1:OK */
- extra[0] = 0xB8;
- } else {
- /* set page status as 0:Data Error,and block status keep 1:OK */
- extra[0] = 0x98;
- }
-
- extra[2] = (u8)(log_blk >> 8);
- extra[3] = (u8)log_blk;
-}
-
-static int ms_init_page(struct rtsx_chip *chip, u16 phy_blk, u16 log_blk, u8 start_page, u8 end_page)
-{
- int retval;
- u8 extra[MS_EXTRA_SIZE], i;
-
- memset(extra, 0xff, MS_EXTRA_SIZE);
-
- extra[0] = 0xf8; /* Block, page OK, data erased */
- extra[1] = 0xff;
- extra[2] = (u8)(log_blk >> 8);
- extra[3] = (u8)log_blk;
-
- for (i = start_page; i < end_page; i++) {
- if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
- ms_set_err_code(chip, MS_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = ms_write_extra_data(chip, phy_blk, i, extra, MS_EXTRA_SIZE);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
- u16 log_blk, u8 start_page, u8 end_page)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, rty_cnt, uncorrect_flag = 0;
- u8 extra[MS_EXTRA_SIZE], val, i, j, data[16];
-
- RTSX_DEBUGP("Copy page from 0x%x to 0x%x, logical block is 0x%x\n",
- old_blk, new_blk, log_blk);
- RTSX_DEBUGP("start_page = %d, end_page = %d\n", start_page, end_page);
-
- retval = ms_read_extra_data(chip, new_blk, 0, extra, MS_EXTRA_SIZE);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_read_status_reg(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_READ_REG(chip, PPBUF_BASE2, &val);
-
- if (val & BUF_FULL) {
- retval = ms_send_cmd(chip, CLEAR_BUF, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (!(val & INT_REG_CED)) {
- ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- for (i = start_page; i < end_page; i++) {
- if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
- ms_set_err_code(chip, MS_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- ms_read_extra_data(chip, old_blk, i, extra, MS_EXTRA_SIZE);
-
- retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
-
- if (CHK_MS4BIT(ms_card))
- data[0] = 0x88;
- else
- data[0] = 0x80;
-
- data[1] = 0;
- data[2] = (u8)(old_blk >> 8);
- data[3] = (u8)old_blk;
- data[4] = 0x20;
- data[5] = i;
-
- retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT, data, 6);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (val & INT_REG_CMDNK) {
- ms_set_err_code(chip, MS_CMD_NK);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (val & INT_REG_CED) {
- if (val & INT_REG_ERR) {
- retval = ms_read_status_reg(chip);
- if (retval != STATUS_SUCCESS) {
- uncorrect_flag = 1;
- RTSX_DEBUGP("Uncorrectable error\n");
- } else {
- uncorrect_flag = 0;
- }
-
- retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA, 0, NO_WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (uncorrect_flag) {
- ms_set_page_status(log_blk, setPS_NG, extra, MS_EXTRA_SIZE);
- if (i == 0)
- extra[0] &= 0xEF;
-
- ms_write_extra_data(chip, old_blk, i, extra, MS_EXTRA_SIZE);
- RTSX_DEBUGP("page %d : extra[0] = 0x%x\n", i, extra[0]);
- MS_SET_BAD_BLOCK_FLG(ms_card);
-
- ms_set_page_status(log_blk, setPS_Error, extra, MS_EXTRA_SIZE);
- ms_write_extra_data(chip, new_blk, i, extra, MS_EXTRA_SIZE);
- continue;
- }
-
- for (rty_cnt = 0; rty_cnt < MS_MAX_RETRY_COUNT; rty_cnt++) {
- retval = ms_transfer_tpc(chip, MS_TM_NORMAL_WRITE,
- WRITE_PAGE_DATA, 0, NO_WAIT_INT);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (rty_cnt == MS_MAX_RETRY_COUNT)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (!(val & INT_REG_BREQ)) {
- ms_set_err_code(chip, MS_BREQ_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- retval = ms_set_rw_reg_addr(chip, OverwriteFlag,
- MS_EXTRA_SIZE, SystemParm, (6+MS_EXTRA_SIZE));
-
- ms_set_err_code(chip, MS_NO_ERROR);
-
- if (CHK_MS4BIT(ms_card))
- data[0] = 0x88;
- else
- data[0] = 0x80;
-
- data[1] = 0;
- data[2] = (u8)(new_blk >> 8);
- data[3] = (u8)new_blk;
- data[4] = 0x20;
- data[5] = i;
-
- if ((extra[0] & 0x60) != 0x60)
- data[6] = extra[0];
- else
- data[6] = 0xF8;
-
- data[6 + 1] = 0xFF;
- data[6 + 2] = (u8)(log_blk >> 8);
- data[6 + 3] = (u8)log_blk;
-
- for (j = 4; j <= MS_EXTRA_SIZE; j++)
- data[6 + j] = 0xFF;
-
- retval = ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE), NO_WAIT_INT, data, 16);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (val & INT_REG_CMDNK) {
- ms_set_err_code(chip, MS_CMD_NK);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (val & INT_REG_CED) {
- if (val & INT_REG_ERR) {
- ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- if (i == 0) {
- retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
-
- if (CHK_MS4BIT(ms_card))
- data[0] = 0x88;
- else
- data[0] = 0x80;
-
- data[1] = 0;
- data[2] = (u8)(old_blk >> 8);
- data[3] = (u8)old_blk;
- data[4] = 0x80;
- data[5] = 0;
- data[6] = 0xEF;
- data[7] = 0xFF;
-
- retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, data, 8);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (val & INT_REG_CMDNK) {
- ms_set_err_code(chip, MS_CMD_NK);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (val & INT_REG_CED) {
- if (val & INT_REG_ERR) {
- ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static int reset_ms(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
- u16 i, reg_addr, block_size;
- u8 val, extra[MS_EXTRA_SIZE], j, *ptr;
-#ifndef SUPPORT_MAGIC_GATE
- u16 eblock_cnt;
-#endif
-
- retval = ms_prepare_reset(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_card->ms_type |= TYPE_MS;
-
- retval = ms_send_cmd(chip, MS_RESET, NO_WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_read_status_reg(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_READ_REG(chip, PPBUF_BASE2, &val);
- if (val & WRT_PRTCT)
- chip->card_wp |= MS_CARD;
- else
- chip->card_wp &= ~MS_CARD;
-
- i = 0;
-
-RE_SEARCH:
- /* Search Boot Block */
- while (i < (MAX_DEFECTIVE_BLOCK + 2)) {
- if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
- ms_set_err_code(chip, MS_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = ms_read_extra_data(chip, i, 0, extra, MS_EXTRA_SIZE);
- if (retval != STATUS_SUCCESS) {
- i++;
- continue;
- }
-
- if (extra[0] & BLOCK_OK) {
- if (!(extra[1] & NOT_BOOT_BLOCK)) {
- ms_card->boot_block = i;
- break;
- }
- }
- i++;
- }
-
- if (i == (MAX_DEFECTIVE_BLOCK + 2)) {
- RTSX_DEBUGP("No boot block found!");
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- for (j = 0; j < 3; j++) {
- retval = ms_read_page(chip, ms_card->boot_block, j);
- if (retval != STATUS_SUCCESS) {
- if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) {
- i = ms_card->boot_block + 1;
- ms_set_err_code(chip, MS_NO_ERROR);
- goto RE_SEARCH;
- }
- }
- }
-
- retval = ms_read_page(chip, ms_card->boot_block, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- /* Read MS system information as sys_info */
- rtsx_init_cmd(chip);
-
- for (i = 0; i < 96; i++)
- rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 0x1A0 + i, 0, 0);
-
- retval = rtsx_send_cmd(chip, MS_CARD, 100);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- ptr = rtsx_get_cmd_data(chip);
- memcpy(ms_card->raw_sys_info, ptr, 96);
-
- /* Read useful block contents */
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID0, 0, 0);
- rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID1, 0, 0);
-
- for (reg_addr = DISABLED_BLOCK0; reg_addr <= DISABLED_BLOCK3; reg_addr++)
- rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0);
-
- for (reg_addr = BLOCK_SIZE_0; reg_addr <= PAGE_SIZE_1; reg_addr++)
- rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0);
-
- rtsx_add_cmd(chip, READ_REG_CMD, MS_Device_Type, 0, 0);
- rtsx_add_cmd(chip, READ_REG_CMD, MS_4bit_Support, 0, 0);
-
- retval = rtsx_send_cmd(chip, MS_CARD, 100);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- ptr = rtsx_get_cmd_data(chip);
-
- RTSX_DEBUGP("Boot block data:\n");
- RTSX_DUMP(ptr, 16);
-
- /* Block ID error
- * HEADER_ID0, HEADER_ID1
- */
- if (ptr[0] != 0x00 || ptr[1] != 0x01) {
- i = ms_card->boot_block + 1;
- goto RE_SEARCH;
- }
-
- /* Page size error
- * PAGE_SIZE_0, PAGE_SIZE_1
- */
- if (ptr[12] != 0x02 || ptr[13] != 0x00) {
- i = ms_card->boot_block + 1;
- goto RE_SEARCH;
- }
-
- if ((ptr[14] == 1) || (ptr[14] == 3))
- chip->card_wp |= MS_CARD;
-
- /* BLOCK_SIZE_0, BLOCK_SIZE_1 */
- block_size = ((u16)ptr[6] << 8) | ptr[7];
- if (block_size == 0x0010) {
- /* Block size 16KB */
- ms_card->block_shift = 5;
- ms_card->page_off = 0x1F;
- } else if (block_size == 0x0008) {
- /* Block size 8KB */
- ms_card->block_shift = 4;
- ms_card->page_off = 0x0F;
- }
-
- /* BLOCK_COUNT_0, BLOCK_COUNT_1 */
- ms_card->total_block = ((u16)ptr[8] << 8) | ptr[9];
-
-#ifdef SUPPORT_MAGIC_GATE
- j = ptr[10];
-
- if (ms_card->block_shift == 4) { /* 4MB or 8MB */
- if (j < 2) { /* Effective block for 4MB: 0x1F0 */
- ms_card->capacity = 0x1EE0;
- } else { /* Effective block for 8MB: 0x3E0 */
- ms_card->capacity = 0x3DE0;
- }
- } else { /* 16MB, 32MB, 64MB or 128MB */
- if (j < 5) { /* Effective block for 16MB: 0x3E0 */
- ms_card->capacity = 0x7BC0;
- } else if (j < 0xA) { /* Effective block for 32MB: 0x7C0 */
- ms_card->capacity = 0xF7C0;
- } else if (j < 0x11) { /* Effective block for 64MB: 0xF80 */
- ms_card->capacity = 0x1EF80;
- } else { /* Effective block for 128MB: 0x1F00 */
- ms_card->capacity = 0x3DF00;
- }
- }
-#else
- /* EBLOCK_COUNT_0, EBLOCK_COUNT_1 */
- eblock_cnt = ((u16)ptr[10] << 8) | ptr[11];
-
- ms_card->capacity = ((u32)eblock_cnt - 2) << ms_card->block_shift;
-#endif
-
- chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity;
-
- /* Switch I/F Mode */
- if (ptr[15]) {
- retval = ms_set_rw_reg_addr(chip, 0, 0, SystemParm, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, PPBUF_BASE2, 0xFF, 0x88);
- RTSX_WRITE_REG(chip, PPBUF_BASE2 + 1, 0xFF, 0);
-
- retval = ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG , 1, NO_WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, MS_CFG, 0x58 | MS_NO_CHECK_INT,
- MS_BUS_WIDTH_4 | PUSH_TIME_ODD | MS_NO_CHECK_INT);
-
- ms_card->ms_type |= MS_4BIT;
- }
-
- if (CHK_MS4BIT(ms_card))
- chip->card_bus_width[chip->card2lun[MS_CARD]] = 4;
- else
- chip->card_bus_width[chip->card2lun[MS_CARD]] = 1;
-
- return STATUS_SUCCESS;
-}
-
-static int ms_init_l2p_tbl(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int size, i, seg_no, retval;
- u16 defect_block, reg_addr;
- u8 val1, val2;
-
- ms_card->segment_cnt = ms_card->total_block >> 9;
- RTSX_DEBUGP("ms_card->segment_cnt = %d\n", ms_card->segment_cnt);
-
- size = ms_card->segment_cnt * sizeof(struct zone_entry);
- ms_card->segment = vzalloc(size);
- if (ms_card->segment == NULL)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_read_page(chip, ms_card->boot_block, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, INIT_FAIL);
-
- reg_addr = PPBUF_BASE2;
- for (i = 0; i < (((ms_card->total_block >> 9) * 10) + 1); i++) {
- retval = rtsx_read_register(chip, reg_addr++, &val1);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, INIT_FAIL);
-
- retval = rtsx_read_register(chip, reg_addr++, &val2);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, INIT_FAIL);
-
- defect_block = ((u16)val1 << 8) | val2;
- if (defect_block == 0xFFFF)
- break;
-
- seg_no = defect_block / 512;
- ms_card->segment[seg_no].defect_list[ms_card->segment[seg_no].disable_count++] = defect_block;
- }
-
- for (i = 0; i < ms_card->segment_cnt; i++) {
- ms_card->segment[i].build_flag = 0;
- ms_card->segment[i].l2p_table = NULL;
- ms_card->segment[i].free_table = NULL;
- ms_card->segment[i].get_index = 0;
- ms_card->segment[i].set_index = 0;
- ms_card->segment[i].unused_blk_cnt = 0;
-
- RTSX_DEBUGP("defective block count of segment %d is %d\n",
- i, ms_card->segment[i].disable_count);
- }
-
- return STATUS_SUCCESS;
-
-INIT_FAIL:
- if (ms_card->segment) {
- vfree(ms_card->segment);
- ms_card->segment = NULL;
- }
-
- return STATUS_FAIL;
-}
-
-static u16 ms_get_l2p_tbl(struct rtsx_chip *chip, int seg_no, u16 log_off)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- struct zone_entry *segment;
-
- if (ms_card->segment == NULL)
- return 0xFFFF;
-
- segment = &(ms_card->segment[seg_no]);
-
- if (segment->l2p_table)
- return segment->l2p_table[log_off];
-
- return 0xFFFF;
-}
-
-static void ms_set_l2p_tbl(struct rtsx_chip *chip, int seg_no, u16 log_off, u16 phy_blk)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- struct zone_entry *segment;
-
- if (ms_card->segment == NULL)
- return;
-
- segment = &(ms_card->segment[seg_no]);
- if (segment->l2p_table)
- segment->l2p_table[log_off] = phy_blk;
-}
-
-static void ms_set_unused_block(struct rtsx_chip *chip, u16 phy_blk)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- struct zone_entry *segment;
- int seg_no;
-
- seg_no = (int)phy_blk >> 9;
- segment = &(ms_card->segment[seg_no]);
-
- segment->free_table[segment->set_index++] = phy_blk;
- if (segment->set_index >= MS_FREE_TABLE_CNT)
- segment->set_index = 0;
-
- segment->unused_blk_cnt++;
-}
-
-static u16 ms_get_unused_block(struct rtsx_chip *chip, int seg_no)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- struct zone_entry *segment;
- u16 phy_blk;
-
- segment = &(ms_card->segment[seg_no]);
-
- if (segment->unused_blk_cnt <= 0)
- return 0xFFFF;
-
- phy_blk = segment->free_table[segment->get_index];
- segment->free_table[segment->get_index++] = 0xFFFF;
- if (segment->get_index >= MS_FREE_TABLE_CNT)
- segment->get_index = 0;
-
- segment->unused_blk_cnt--;
-
- return phy_blk;
-}
-
-static const unsigned short ms_start_idx[] = {0, 494, 990, 1486, 1982, 2478, 2974, 3470,
- 3966, 4462, 4958, 5454, 5950, 6446, 6942, 7438, 7934};
-
-static int ms_arbitrate_l2p(struct rtsx_chip *chip, u16 phy_blk, u16 log_off, u8 us1, u8 us2)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- struct zone_entry *segment;
- int seg_no;
- u16 tmp_blk;
-
- seg_no = (int)phy_blk >> 9;
- segment = &(ms_card->segment[seg_no]);
- tmp_blk = segment->l2p_table[log_off];
-
- if (us1 != us2) {
- if (us1 == 0) {
- if (!(chip->card_wp & MS_CARD))
- ms_erase_block(chip, tmp_blk);
-
- ms_set_unused_block(chip, tmp_blk);
- segment->l2p_table[log_off] = phy_blk;
- } else {
- if (!(chip->card_wp & MS_CARD))
- ms_erase_block(chip, phy_blk);
-
- ms_set_unused_block(chip, phy_blk);
- }
- } else {
- if (phy_blk < tmp_blk) {
- if (!(chip->card_wp & MS_CARD))
- ms_erase_block(chip, phy_blk);
-
- ms_set_unused_block(chip, phy_blk);
- } else {
- if (!(chip->card_wp & MS_CARD))
- ms_erase_block(chip, tmp_blk);
-
- ms_set_unused_block(chip, tmp_blk);
- segment->l2p_table[log_off] = phy_blk;
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- struct zone_entry *segment;
- int retval, table_size, disable_cnt, defect_flag, i;
- u16 start, end, phy_blk, log_blk, tmp_blk;
- u8 extra[MS_EXTRA_SIZE], us1, us2;
-
- RTSX_DEBUGP("ms_build_l2p_tbl: %d\n", seg_no);
-
- if (ms_card->segment == NULL) {
- retval = ms_init_l2p_tbl(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, retval);
- }
-
- if (ms_card->segment[seg_no].build_flag) {
- RTSX_DEBUGP("l2p table of segment %d has been built\n", seg_no);
- return STATUS_SUCCESS;
- }
-
- if (seg_no == 0)
- table_size = 494;
- else
- table_size = 496;
-
- segment = &(ms_card->segment[seg_no]);
-
- if (segment->l2p_table == NULL) {
- segment->l2p_table = (u16 *)vmalloc(table_size * 2);
- if (segment->l2p_table == NULL)
- TRACE_GOTO(chip, BUILD_FAIL);
- }
- memset((u8 *)(segment->l2p_table), 0xff, table_size * 2);
-
- if (segment->free_table == NULL) {
- segment->free_table = (u16 *)vmalloc(MS_FREE_TABLE_CNT * 2);
- if (segment->free_table == NULL)
- TRACE_GOTO(chip, BUILD_FAIL);
- }
- memset((u8 *)(segment->free_table), 0xff, MS_FREE_TABLE_CNT * 2);
-
- start = (u16)seg_no << 9;
- end = (u16)(seg_no + 1) << 9;
-
- disable_cnt = segment->disable_count;
-
- segment->get_index = segment->set_index = 0;
- segment->unused_blk_cnt = 0;
-
- for (phy_blk = start; phy_blk < end; phy_blk++) {
- if (disable_cnt) {
- defect_flag = 0;
- for (i = 0; i < segment->disable_count; i++) {
- if (phy_blk == segment->defect_list[i]) {
- defect_flag = 1;
- break;
- }
- }
- if (defect_flag) {
- disable_cnt--;
- continue;
- }
- }
-
- retval = ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE);
- if (retval != STATUS_SUCCESS) {
- RTSX_DEBUGP("read extra data fail\n");
- ms_set_bad_block(chip, phy_blk);
- continue;
- }
-
- if (seg_no == ms_card->segment_cnt - 1) {
- if (!(extra[1] & NOT_TRANSLATION_TABLE)) {
- if (!(chip->card_wp & MS_CARD)) {
- retval = ms_erase_block(chip, phy_blk);
- if (retval != STATUS_SUCCESS)
- continue;
- extra[2] = 0xff;
- extra[3] = 0xff;
- }
- }
- }
-
- if (!(extra[0] & BLOCK_OK))
- continue;
- if (!(extra[1] & NOT_BOOT_BLOCK))
- continue;
- if ((extra[0] & PAGE_OK) != PAGE_OK)
- continue;
-
- log_blk = ((u16)extra[2] << 8) | extra[3];
-
- if (log_blk == 0xFFFF) {
- if (!(chip->card_wp & MS_CARD)) {
- retval = ms_erase_block(chip, phy_blk);
- if (retval != STATUS_SUCCESS)
- continue;
- }
- ms_set_unused_block(chip, phy_blk);
- continue;
- }
-
- if ((log_blk < ms_start_idx[seg_no]) ||
- (log_blk >= ms_start_idx[seg_no+1])) {
- if (!(chip->card_wp & MS_CARD)) {
- retval = ms_erase_block(chip, phy_blk);
- if (retval != STATUS_SUCCESS)
- continue;
- }
- ms_set_unused_block(chip, phy_blk);
- continue;
- }
-
- if (segment->l2p_table[log_blk - ms_start_idx[seg_no]] == 0xFFFF) {
- segment->l2p_table[log_blk - ms_start_idx[seg_no]] = phy_blk;
- continue;
- }
-
- us1 = extra[0] & 0x10;
- tmp_blk = segment->l2p_table[log_blk - ms_start_idx[seg_no]];
- retval = ms_read_extra_data(chip, tmp_blk, 0, extra, MS_EXTRA_SIZE);
- if (retval != STATUS_SUCCESS)
- continue;
- us2 = extra[0] & 0x10;
-
- (void)ms_arbitrate_l2p(chip, phy_blk, log_blk-ms_start_idx[seg_no], us1, us2);
- continue;
- }
-
- segment->build_flag = 1;
-
- RTSX_DEBUGP("unused block count: %d\n", segment->unused_blk_cnt);
-
- /* Logical Address Confirmation Process */
- if (seg_no == ms_card->segment_cnt - 1) {
- if (segment->unused_blk_cnt < 2)
- chip->card_wp |= MS_CARD;
- } else {
- if (segment->unused_blk_cnt < 1)
- chip->card_wp |= MS_CARD;
- }
-
- if (chip->card_wp & MS_CARD)
- return STATUS_SUCCESS;
-
- for (log_blk = ms_start_idx[seg_no]; log_blk < ms_start_idx[seg_no + 1]; log_blk++) {
- if (segment->l2p_table[log_blk-ms_start_idx[seg_no]] == 0xFFFF) {
- phy_blk = ms_get_unused_block(chip, seg_no);
- if (phy_blk == 0xFFFF) {
- chip->card_wp |= MS_CARD;
- return STATUS_SUCCESS;
- }
- retval = ms_init_page(chip, phy_blk, log_blk, 0, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, BUILD_FAIL);
-
- segment->l2p_table[log_blk-ms_start_idx[seg_no]] = phy_blk;
- if (seg_no == ms_card->segment_cnt - 1) {
- if (segment->unused_blk_cnt < 2) {
- chip->card_wp |= MS_CARD;
- return STATUS_SUCCESS;
- }
- } else {
- if (segment->unused_blk_cnt < 1) {
- chip->card_wp |= MS_CARD;
- return STATUS_SUCCESS;
- }
- }
- }
- }
-
- /* Make boot block be the first normal block */
- if (seg_no == 0) {
- for (log_blk = 0; log_blk < 494; log_blk++) {
- tmp_blk = segment->l2p_table[log_blk];
- if (tmp_blk < ms_card->boot_block) {
- RTSX_DEBUGP("Boot block is not the first normal block.\n");
-
- if (chip->card_wp & MS_CARD)
- break;
-
- phy_blk = ms_get_unused_block(chip, 0);
- retval = ms_copy_page(chip, tmp_blk, phy_blk,
- log_blk, 0, ms_card->page_off + 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- segment->l2p_table[log_blk] = phy_blk;
-
- retval = ms_set_bad_block(chip, tmp_blk);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
- }
-
- return STATUS_SUCCESS;
-
-BUILD_FAIL:
- segment->build_flag = 0;
- if (segment->l2p_table) {
- vfree(segment->l2p_table);
- segment->l2p_table = NULL;
- }
- if (segment->free_table) {
- vfree(segment->free_table);
- segment->free_table = NULL;
- }
-
- return STATUS_FAIL;
-}
-
-
-int reset_ms_card(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
-
- memset(ms_card, 0, sizeof(struct ms_info));
-
- retval = enable_card_clock(chip, MS_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = select_card(chip, MS_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_card->ms_type = 0;
-
- retval = reset_ms_pro(chip);
- if (retval != STATUS_SUCCESS) {
- if (ms_card->check_ms_flow) {
- retval = reset_ms(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- retval = ms_set_init_para(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (!CHK_MSPRO(ms_card)) {
- /* Build table for the last segment,
- * to check if L2P table block exists, erasing it
- */
- retval = ms_build_l2p_tbl(chip, ms_card->total_block / 512 - 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- RTSX_DEBUGP("ms_card->ms_type = 0x%x\n", ms_card->ms_type);
-
- return STATUS_SUCCESS;
-}
-
-static int mspro_set_rw_cmd(struct rtsx_chip *chip, u32 start_sec, u16 sec_cnt, u8 cmd)
-{
- int retval, i;
- u8 data[8];
-
- data[0] = cmd;
- data[1] = (u8)(sec_cnt >> 8);
- data[2] = (u8)sec_cnt;
- data[3] = (u8)(start_sec >> 24);
- data[4] = (u8)(start_sec >> 16);
- data[5] = (u8)(start_sec >> 8);
- data[6] = (u8)start_sec;
- data[7] = 0;
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_write_bytes(chip, PRO_EX_SET_CMD, 7, WAIT_INT, data, 8);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (i == MS_MAX_RETRY_COUNT)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-
-void mspro_stop_seq_mode(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
-
- RTSX_DEBUGP("--%s--\n", __func__);
-
- if (ms_card->seq_mode) {
- retval = ms_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- return;
-
- ms_card->seq_mode = 0;
- ms_card->total_sec_cnt = 0;
- ms_send_cmd(chip, PRO_STOP, WAIT_INT);
-
- rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH);
- }
-}
-
-static inline int ms_auto_tune_clock(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
-
- RTSX_DEBUGP("--%s--\n", __func__);
-
- if (chip->asic_code) {
- if (ms_card->ms_clock > 30)
- ms_card->ms_clock -= 20;
- } else {
- if (ms_card->ms_clock == CLK_80)
- ms_card->ms_clock = CLK_60;
- else if (ms_card->ms_clock == CLK_60)
- ms_card->ms_clock = CLK_40;
- }
-
- retval = ms_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int mspro_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, mode_2k = 0;
- u16 count;
- u8 val, trans_mode, rw_tpc, rw_cmd;
-
- ms_set_err_code(chip, MS_NO_ERROR);
-
- ms_card->cleanup_counter = 0;
-
- if (CHK_MSHG(ms_card)) {
- if ((start_sector % 4) || (sector_cnt % 4)) {
- if (srb->sc_data_direction == DMA_FROM_DEVICE) {
- rw_tpc = PRO_READ_LONG_DATA;
- rw_cmd = PRO_READ_DATA;
- } else {
- rw_tpc = PRO_WRITE_LONG_DATA;
- rw_cmd = PRO_WRITE_DATA;
- }
- } else {
- if (srb->sc_data_direction == DMA_FROM_DEVICE) {
- rw_tpc = PRO_READ_QUAD_DATA;
- rw_cmd = PRO_READ_2K_DATA;
- } else {
- rw_tpc = PRO_WRITE_QUAD_DATA;
- rw_cmd = PRO_WRITE_2K_DATA;
- }
- mode_2k = 1;
- }
- } else {
- if (srb->sc_data_direction == DMA_FROM_DEVICE) {
- rw_tpc = PRO_READ_LONG_DATA;
- rw_cmd = PRO_READ_DATA;
- } else {
- rw_tpc = PRO_WRITE_LONG_DATA;
- rw_cmd = PRO_WRITE_DATA;
- }
- }
-
- retval = ms_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (srb->sc_data_direction == DMA_FROM_DEVICE)
- trans_mode = MS_TM_AUTO_READ;
- else
- trans_mode = MS_TM_AUTO_WRITE;
-
- RTSX_READ_REG(chip, MS_TRANS_CFG, &val);
-
- if (ms_card->seq_mode) {
- if ((ms_card->pre_dir != srb->sc_data_direction)
- || ((ms_card->pre_sec_addr + ms_card->pre_sec_cnt) != start_sector)
- || (mode_2k && (ms_card->seq_mode & MODE_512_SEQ))
- || (!mode_2k && (ms_card->seq_mode & MODE_2K_SEQ))
- || !(val & MS_INT_BREQ)
- || ((ms_card->total_sec_cnt + sector_cnt) > 0xFE00)) {
- ms_card->seq_mode = 0;
- ms_card->total_sec_cnt = 0;
- if (val & MS_INT_BREQ) {
- retval = ms_send_cmd(chip, PRO_STOP, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH);
- }
- }
- }
-
- if (!ms_card->seq_mode) {
- ms_card->total_sec_cnt = 0;
- if (sector_cnt >= SEQ_START_CRITERIA) {
- if ((ms_card->capacity - start_sector) > 0xFE00)
- count = 0xFE00;
- else
- count = (u16)(ms_card->capacity - start_sector);
-
- if (count > sector_cnt) {
- if (mode_2k)
- ms_card->seq_mode |= MODE_2K_SEQ;
- else
- ms_card->seq_mode |= MODE_512_SEQ;
- }
- } else {
- count = sector_cnt;
- }
- retval = mspro_set_rw_cmd(chip, start_sector, count, rw_cmd);
- if (retval != STATUS_SUCCESS) {
- ms_card->seq_mode = 0;
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- retval = ms_transfer_data(chip, trans_mode, rw_tpc, sector_cnt, WAIT_INT, mode_2k,
- scsi_sg_count(srb), scsi_sglist(srb), scsi_bufflen(srb));
- if (retval != STATUS_SUCCESS) {
- ms_card->seq_mode = 0;
- rtsx_read_register(chip, MS_TRANS_CFG, &val);
- rtsx_clear_ms_error(chip);
-
- if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
- chip->rw_need_retry = 0;
- RTSX_DEBUGP("No card exist, exit mspro_rw_multi_sector\n");
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (val & MS_INT_BREQ)
- ms_send_cmd(chip, PRO_STOP, WAIT_INT);
-
- if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) {
- RTSX_DEBUGP("MSPro CRC error, tune clock!\n");
- chip->rw_need_retry = 1;
- ms_auto_tune_clock(chip);
- }
-
- TRACE_RET(chip, retval);
- }
-
- if (ms_card->seq_mode) {
- ms_card->pre_sec_addr = start_sector;
- ms_card->pre_sec_cnt = sector_cnt;
- ms_card->pre_dir = srb->sc_data_direction;
- ms_card->total_sec_cnt += sector_cnt;
- }
-
- return STATUS_SUCCESS;
-}
-
-static int mspro_read_format_progress(struct rtsx_chip *chip, const int short_data_len)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, i;
- u32 total_progress, cur_progress;
- u8 cnt, tmp;
- u8 data[8];
-
- RTSX_DEBUGP("mspro_read_format_progress, short_data_len = %d\n", short_data_len);
-
- retval = ms_switch_clock(chip);
- if (retval != STATUS_SUCCESS) {
- ms_card->format_status = FORMAT_FAIL;
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp);
- if (retval != STATUS_SUCCESS) {
- ms_card->format_status = FORMAT_FAIL;
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (!(tmp & MS_INT_BREQ)) {
- if ((tmp & (MS_INT_CED | MS_INT_BREQ | MS_INT_CMDNK | MS_INT_ERR)) == MS_INT_CED) {
- ms_card->format_status = FORMAT_SUCCESS;
- return STATUS_SUCCESS;
- }
- ms_card->format_status = FORMAT_FAIL;
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (short_data_len >= 256)
- cnt = 0;
- else
- cnt = (u8)short_data_len;
-
- retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT, MS_NO_CHECK_INT);
- if (retval != STATUS_SUCCESS) {
- ms_card->format_status = FORMAT_FAIL;
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, cnt, WAIT_INT, data, 8);
- if (retval != STATUS_SUCCESS) {
- ms_card->format_status = FORMAT_FAIL;
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- total_progress = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- cur_progress = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
-
- RTSX_DEBUGP("total_progress = %d, cur_progress = %d\n",
- total_progress, cur_progress);
-
- if (total_progress == 0) {
- ms_card->progress = 0;
- } else {
- u64 ulltmp = (u64)cur_progress * (u64)65535;
- do_div(ulltmp, total_progress);
- ms_card->progress = (u16)ulltmp;
- }
- RTSX_DEBUGP("progress = %d\n", ms_card->progress);
-
- for (i = 0; i < 5000; i++) {
- retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp);
- if (retval != STATUS_SUCCESS) {
- ms_card->format_status = FORMAT_FAIL;
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (tmp & (MS_INT_CED | MS_INT_CMDNK | MS_INT_BREQ | MS_INT_ERR))
- break;
-
- wait_timeout(1);
- }
-
- retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT, 0);
- if (retval != STATUS_SUCCESS) {
- ms_card->format_status = FORMAT_FAIL;
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (i == 5000) {
- ms_card->format_status = FORMAT_FAIL;
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) {
- ms_card->format_status = FORMAT_FAIL;
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (tmp & MS_INT_CED) {
- ms_card->format_status = FORMAT_SUCCESS;
- ms_card->pro_under_formatting = 0;
- } else if (tmp & MS_INT_BREQ) {
- ms_card->format_status = FORMAT_IN_PROGRESS;
- } else {
- ms_card->format_status = FORMAT_FAIL;
- ms_card->pro_under_formatting = 0;
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-void mspro_polling_format_status(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int i;
-
- if (ms_card->pro_under_formatting && (rtsx_get_stat(chip) != RTSX_STAT_SS)) {
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- for (i = 0; i < 65535; i++) {
- mspro_read_format_progress(chip, MS_SHORT_DATA_LEN);
- if (ms_card->format_status != FORMAT_IN_PROGRESS)
- break;
- }
- }
-
- return;
-}
-
-int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, int short_data_len, int quick_format)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, i;
- u8 buf[8], tmp;
- u16 para;
-
- RTSX_DEBUGP("--%s--\n", __func__);
-
- retval = ms_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_set_rw_reg_addr(chip, 0x00, 0x00, Pro_TPCParm, 0x01);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- memset(buf, 0, 2);
- switch (short_data_len) {
- case 32:
- buf[0] = 0;
- break;
- case 64:
- buf[0] = 1;
- break;
- case 128:
- buf[0] = 2;
- break;
- case 256:
- default:
- buf[0] = 3;
- break;
- }
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_write_bytes(chip, PRO_WRITE_REG, 1, NO_WAIT_INT, buf, 2);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (i == MS_MAX_RETRY_COUNT)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (quick_format)
- para = 0x0000;
- else
- para = 0x0001;
-
- retval = mspro_set_rw_cmd(chip, 0, para, PRO_FORMAT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_READ_REG(chip, MS_TRANS_CFG, &tmp);
-
- if (tmp & (MS_INT_CMDNK | MS_INT_ERR))
- TRACE_RET(chip, STATUS_FAIL);
-
- if ((tmp & (MS_INT_BREQ | MS_INT_CED)) == MS_INT_BREQ) {
- ms_card->pro_under_formatting = 1;
- ms_card->progress = 0;
- ms_card->format_status = FORMAT_IN_PROGRESS;
- return STATUS_SUCCESS;
- }
-
- if (tmp & MS_INT_CED) {
- ms_card->pro_under_formatting = 0;
- ms_card->progress = 0;
- ms_card->format_status = FORMAT_SUCCESS;
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_NO_SENSE);
- return STATUS_SUCCESS;
- }
-
- TRACE_RET(chip, STATUS_FAIL);
-}
-
-
-static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk, u16 log_blk,
- u8 start_page, u8 end_page, u8 *buf, unsigned int *index, unsigned int *offset)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, i;
- u8 extra[MS_EXTRA_SIZE], page_addr, val, trans_cfg, data[6];
- u8 *ptr;
-
- retval = ms_read_extra_data(chip, phy_blk, start_page, extra, MS_EXTRA_SIZE);
- if (retval == STATUS_SUCCESS) {
- if ((extra[1] & 0x30) != 0x30) {
- ms_set_err_code(chip, MS_FLASH_READ_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHK_MS4BIT(ms_card))
- data[0] = 0x88;
- else
- data[0] = 0x80;
-
- data[1] = 0;
- data[2] = (u8)(phy_blk >> 8);
- data[3] = (u8)phy_blk;
- data[4] = 0;
- data[5] = start_page;
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (i == MS_MAX_RETRY_COUNT)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
-
- retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ptr = buf;
-
- for (page_addr = start_page; page_addr < end_page; page_addr++) {
- ms_set_err_code(chip, MS_NO_ERROR);
-
- if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
- ms_set_err_code(chip, MS_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (val & INT_REG_CMDNK) {
- ms_set_err_code(chip, MS_CMD_NK);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (val & INT_REG_ERR) {
- if (val & INT_REG_BREQ) {
- retval = ms_read_status_reg(chip);
- if (retval != STATUS_SUCCESS) {
- if (!(chip->card_wp & MS_CARD)) {
- reset_ms(chip);
- ms_set_page_status(log_blk, setPS_NG, extra, MS_EXTRA_SIZE);
- ms_write_extra_data(chip, phy_blk,
- page_addr, extra, MS_EXTRA_SIZE);
- }
- ms_set_err_code(chip, MS_FLASH_READ_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- } else {
- ms_set_err_code(chip, MS_FLASH_READ_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- } else {
- if (!(val & INT_REG_BREQ)) {
- ms_set_err_code(chip, MS_BREQ_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- if (page_addr == (end_page - 1)) {
- if (!(val & INT_REG_CED)) {
- retval = ms_send_cmd(chip, BLOCK_END, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (!(val & INT_REG_CED)) {
- ms_set_err_code(chip, MS_FLASH_READ_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- trans_cfg = NO_WAIT_INT;
- } else {
- trans_cfg = WAIT_INT;
- }
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, READ_PAGE_DATA);
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, trans_cfg);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
-
- trans_dma_enable(DMA_FROM_DEVICE, chip, 512, DMA_512);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF,
- MS_TRANSFER_START | MS_TM_NORMAL_READ);
- rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END);
-
- rtsx_send_cmd_no_wait(chip);
-
- retval = rtsx_transfer_data_partial(chip, MS_CARD, ptr, 512, scsi_sg_count(chip->srb),
- index, offset, DMA_FROM_DEVICE, chip->ms_timeout);
- if (retval < 0) {
- if (retval == -ETIMEDOUT) {
- ms_set_err_code(chip, MS_TO_ERROR);
- rtsx_clear_ms_error(chip);
- TRACE_RET(chip, STATUS_TIMEDOUT);
- }
-
- retval = rtsx_read_register(chip, MS_TRANS_CFG, &val);
- if (retval != STATUS_SUCCESS) {
- ms_set_err_code(chip, MS_TO_ERROR);
- rtsx_clear_ms_error(chip);
- TRACE_RET(chip, STATUS_TIMEDOUT);
- }
- if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) {
- ms_set_err_code(chip, MS_CRC16_ERROR);
- rtsx_clear_ms_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- if (scsi_sg_count(chip->srb) == 0)
- ptr += 512;
- }
-
- return STATUS_SUCCESS;
-}
-
-static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
- u16 log_blk, u8 start_page, u8 end_page, u8 *buf,
- unsigned int *index, unsigned int *offset)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, i;
- u8 page_addr, val, data[16];
- u8 *ptr;
-
- if (!start_page) {
- retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHK_MS4BIT(ms_card))
- data[0] = 0x88;
- else
- data[0] = 0x80;
-
- data[1] = 0;
- data[2] = (u8)(old_blk >> 8);
- data[3] = (u8)old_blk;
- data[4] = 0x80;
- data[5] = 0;
- data[6] = 0xEF;
- data[7] = 0xFF;
-
- retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, data, 8);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
- retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1, NO_WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, (6 + MS_EXTRA_SIZE));
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ms_set_err_code(chip, MS_NO_ERROR);
-
- if (CHK_MS4BIT(ms_card))
- data[0] = 0x88;
- else
- data[0] = 0x80;
-
- data[1] = 0;
- data[2] = (u8)(new_blk >> 8);
- data[3] = (u8)new_blk;
- if ((end_page - start_page) == 1)
- data[4] = 0x20;
- else
- data[4] = 0;
-
- data[5] = start_page;
- data[6] = 0xF8;
- data[7] = 0xFF;
- data[8] = (u8)(log_blk >> 8);
- data[9] = (u8)log_blk;
-
- for (i = 0x0A; i < 0x10; i++)
- data[i] = 0xFF;
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_write_bytes(chip, WRITE_REG, 6 + MS_EXTRA_SIZE, NO_WAIT_INT, data, 16);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (i == MS_MAX_RETRY_COUNT)
- TRACE_RET(chip, STATUS_FAIL);
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (i == MS_MAX_RETRY_COUNT)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- ptr = buf;
- for (page_addr = start_page; page_addr < end_page; page_addr++) {
- ms_set_err_code(chip, MS_NO_ERROR);
-
- if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
- ms_set_err_code(chip, MS_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (val & INT_REG_CMDNK) {
- ms_set_err_code(chip, MS_CMD_NK);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (val & INT_REG_ERR) {
- ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (!(val & INT_REG_BREQ)) {
- ms_set_err_code(chip, MS_BREQ_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- udelay(30);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, WRITE_PAGE_DATA);
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, WAIT_INT);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
-
- trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF,
- MS_TRANSFER_START | MS_TM_NORMAL_WRITE);
- rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END);
-
- rtsx_send_cmd_no_wait(chip);
-
- retval = rtsx_transfer_data_partial(chip, MS_CARD, ptr, 512, scsi_sg_count(chip->srb),
- index, offset, DMA_TO_DEVICE, chip->ms_timeout);
- if (retval < 0) {
- ms_set_err_code(chip, MS_TO_ERROR);
- rtsx_clear_ms_error(chip);
-
- if (retval == -ETIMEDOUT)
- TRACE_RET(chip, STATUS_TIMEDOUT);
- else
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if ((end_page - start_page) == 1) {
- if (!(val & INT_REG_CED)) {
- ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- } else {
- if (page_addr == (end_page - 1)) {
- if (!(val & INT_REG_CED)) {
- retval = ms_send_cmd(chip, BLOCK_END, WAIT_INT);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if ((page_addr == (end_page - 1)) || (page_addr == ms_card->page_off)) {
- if (!(val & INT_REG_CED)) {
- ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
- }
-
- if (scsi_sg_count(chip->srb) == 0)
- ptr += 512;
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static int ms_finish_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
- u16 log_blk, u8 page_off)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval, seg_no;
-
- retval = ms_copy_page(chip, old_blk, new_blk, log_blk,
- page_off, ms_card->page_off + 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- seg_no = old_blk >> 9;
-
- if (MS_TST_BAD_BLOCK_FLG(ms_card)) {
- MS_CLR_BAD_BLOCK_FLG(ms_card);
- ms_set_bad_block(chip, old_blk);
- } else {
- retval = ms_erase_block(chip, old_blk);
- if (retval == STATUS_SUCCESS)
- ms_set_unused_block(chip, old_blk);
- }
-
- ms_set_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no], new_blk);
-
- return STATUS_SUCCESS;
-}
-
-static int ms_prepare_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
- u16 log_blk, u8 start_page)
-{
- int retval;
-
- if (start_page) {
- retval = ms_copy_page(chip, old_blk, new_blk, log_blk, 0, start_page);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-#ifdef MS_DELAY_WRITE
-int ms_delay_write(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- struct ms_delay_write_tag *delay_write = &(ms_card->delay_write);
- int retval;
-
- if (delay_write->delay_write_flag) {
- retval = ms_set_init_para(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- delay_write->delay_write_flag = 0;
- retval = ms_finish_write(chip,
- delay_write->old_phyblock, delay_write->new_phyblock,
- delay_write->logblock, delay_write->pageoff);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-#endif
-
-static inline void ms_rw_fail(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- if (srb->sc_data_direction == DMA_FROM_DEVICE)
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- else
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
-}
-
-static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- unsigned int lun = SCSI_LUN(srb);
- int retval, seg_no;
- unsigned int index = 0, offset = 0;
- u16 old_blk = 0, new_blk = 0, log_blk, total_sec_cnt = sector_cnt;
- u8 start_page, end_page = 0, page_cnt;
- u8 *ptr;
-#ifdef MS_DELAY_WRITE
- struct ms_delay_write_tag *delay_write = &(ms_card->delay_write);
-#endif
-
- ms_set_err_code(chip, MS_NO_ERROR);
-
- ms_card->cleanup_counter = 0;
-
- ptr = (u8 *)scsi_sglist(srb);
-
- retval = ms_switch_clock(chip);
- if (retval != STATUS_SUCCESS) {
- ms_rw_fail(srb, chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- log_blk = (u16)(start_sector >> ms_card->block_shift);
- start_page = (u8)(start_sector & ms_card->page_off);
-
- for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; seg_no++) {
- if (log_blk < ms_start_idx[seg_no+1])
- break;
- }
-
- if (ms_card->segment[seg_no].build_flag == 0) {
- retval = ms_build_l2p_tbl(chip, seg_no);
- if (retval != STATUS_SUCCESS) {
- chip->card_fail |= MS_CARD;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- if (srb->sc_data_direction == DMA_TO_DEVICE) {
-#ifdef MS_DELAY_WRITE
- if (delay_write->delay_write_flag &&
- (delay_write->logblock == log_blk) &&
- (start_page > delay_write->pageoff)) {
- delay_write->delay_write_flag = 0;
- retval = ms_copy_page(chip,
- delay_write->old_phyblock,
- delay_write->new_phyblock, log_blk,
- delay_write->pageoff, start_page);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- old_blk = delay_write->old_phyblock;
- new_blk = delay_write->new_phyblock;
- } else if (delay_write->delay_write_flag &&
- (delay_write->logblock == log_blk) &&
- (start_page == delay_write->pageoff)) {
- delay_write->delay_write_flag = 0;
- old_blk = delay_write->old_phyblock;
- new_blk = delay_write->new_phyblock;
- } else {
- retval = ms_delay_write(chip);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-#endif
- old_blk = ms_get_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no]);
- new_blk = ms_get_unused_block(chip, seg_no);
- if ((old_blk == 0xFFFF) || (new_blk == 0xFFFF)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = ms_prepare_write(chip, old_blk, new_blk, log_blk, start_page);
- if (retval != STATUS_SUCCESS) {
- if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, STATUS_FAIL);
- }
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-#ifdef MS_DELAY_WRITE
- }
-#endif
- } else {
-#ifdef MS_DELAY_WRITE
- retval = ms_delay_write(chip);
- if (retval != STATUS_SUCCESS) {
- if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, STATUS_FAIL);
- }
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-#endif
- old_blk = ms_get_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no]);
- if (old_blk == 0xFFFF) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- RTSX_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", seg_no, old_blk, new_blk);
-
- while (total_sec_cnt) {
- if ((start_page + total_sec_cnt) > (ms_card->page_off + 1))
- end_page = ms_card->page_off + 1;
- else
- end_page = start_page + (u8)total_sec_cnt;
-
- page_cnt = end_page - start_page;
-
- RTSX_DEBUGP("start_page = %d, end_page = %d, page_cnt = %d\n",
- start_page, end_page, page_cnt);
-
- if (srb->sc_data_direction == DMA_FROM_DEVICE) {
- retval = ms_read_multiple_pages(chip,
- old_blk, log_blk, start_page, end_page,
- ptr, &index, &offset);
- } else {
- retval = ms_write_multiple_pages(chip, old_blk,
- new_blk, log_blk, start_page, end_page,
- ptr, &index, &offset);
- }
-
- if (retval != STATUS_SUCCESS) {
- toggle_gpio(chip, 1);
- if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, STATUS_FAIL);
- }
- ms_rw_fail(srb, chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (srb->sc_data_direction == DMA_TO_DEVICE) {
- if (end_page == (ms_card->page_off + 1)) {
- retval = ms_erase_block(chip, old_blk);
- if (retval == STATUS_SUCCESS)
- ms_set_unused_block(chip, old_blk);
-
- ms_set_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no], new_blk);
- }
- }
-
- total_sec_cnt -= page_cnt;
- if (scsi_sg_count(srb) == 0)
- ptr += page_cnt * 512;
-
- if (total_sec_cnt == 0)
- break;
-
- log_blk++;
-
- for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1;
- seg_no++) {
- if (log_blk < ms_start_idx[seg_no+1])
- break;
- }
-
- if (ms_card->segment[seg_no].build_flag == 0) {
- retval = ms_build_l2p_tbl(chip, seg_no);
- if (retval != STATUS_SUCCESS) {
- chip->card_fail |= MS_CARD;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- old_blk = ms_get_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no]);
- if (old_blk == 0xFFFF) {
- ms_rw_fail(srb, chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (srb->sc_data_direction == DMA_TO_DEVICE) {
- new_blk = ms_get_unused_block(chip, seg_no);
- if (new_blk == 0xFFFF) {
- ms_rw_fail(srb, chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- RTSX_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", seg_no, old_blk, new_blk);
-
- start_page = 0;
- }
-
- if (srb->sc_data_direction == DMA_TO_DEVICE) {
- if (end_page < (ms_card->page_off + 1)) {
-#ifdef MS_DELAY_WRITE
- delay_write->delay_write_flag = 1;
- delay_write->old_phyblock = old_blk;
- delay_write->new_phyblock = new_blk;
- delay_write->logblock = log_blk;
- delay_write->pageoff = end_page;
-#else
- retval = ms_finish_write(chip, old_blk, new_blk, log_blk, end_page);
- if (retval != STATUS_SUCCESS) {
- if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- ms_rw_fail(srb, chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-#endif
- }
- }
-
- scsi_set_resid(srb, 0);
-
- return STATUS_SUCCESS;
-}
-
-int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
-
- if (CHK_MSPRO(ms_card))
- retval = mspro_rw_multi_sector(srb, chip, start_sector, sector_cnt);
- else
- retval = ms_rw_multi_sector(srb, chip, start_sector, sector_cnt);
-
- return retval;
-}
-
-
-void ms_free_l2p_tbl(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int i = 0;
-
- if (ms_card->segment != NULL) {
- for (i = 0; i < ms_card->segment_cnt; i++) {
- if (ms_card->segment[i].l2p_table != NULL) {
- vfree(ms_card->segment[i].l2p_table);
- ms_card->segment[i].l2p_table = NULL;
- }
- if (ms_card->segment[i].free_table != NULL) {
- vfree(ms_card->segment[i].free_table);
- ms_card->segment[i].free_table = NULL;
- }
- }
- vfree(ms_card->segment);
- ms_card->segment = NULL;
- }
-}
-
-#ifdef SUPPORT_MAGIC_GATE
-
-#ifdef READ_BYTES_WAIT_INT
-static int ms_poll_int(struct rtsx_chip *chip)
-{
- int retval;
- u8 val;
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANS_CFG, MS_INT_CED, MS_INT_CED);
-
- retval = rtsx_send_cmd(chip, MS_CARD, 5000);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- val = *rtsx_get_cmd_data(chip);
- if (val & MS_INT_ERR)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-#endif
-
-#ifdef MS_SAMPLE_INT_ERR
-static int check_ms_err(struct rtsx_chip *chip)
-{
- int retval;
- u8 val;
-
- retval = rtsx_read_register(chip, MS_TRANSFER, &val);
- if (retval != STATUS_SUCCESS)
- return 1;
- if (val & MS_TRANSFER_ERR)
- return 1;
-
- retval = rtsx_read_register(chip, MS_TRANS_CFG, &val);
- if (retval != STATUS_SUCCESS)
- return 1;
-
- if (val & (MS_INT_ERR | MS_INT_CMDNK))
- return 1;
-
- return 0;
-}
-#else
-static int check_ms_err(struct rtsx_chip *chip)
-{
- int retval;
- u8 val;
-
- retval = rtsx_read_register(chip, MS_TRANSFER, &val);
- if (retval != STATUS_SUCCESS)
- return 1;
- if (val & MS_TRANSFER_ERR)
- return 1;
-
- return 0;
-}
-#endif
-
-static int mg_send_ex_cmd(struct rtsx_chip *chip, u8 cmd, u8 entry_num)
-{
- int retval, i;
- u8 data[8];
-
- data[0] = cmd;
- data[1] = 0;
- data[2] = 0;
- data[3] = 0;
- data[4] = 0;
- data[5] = 0;
- data[6] = entry_num;
- data[7] = 0;
-
- for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
- retval = ms_write_bytes(chip, PRO_EX_SET_CMD, 7, WAIT_INT, data, 8);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (i == MS_MAX_RETRY_COUNT)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (check_ms_err(chip)) {
- rtsx_clear_ms_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type, u8 mg_entry_num)
-{
- int retval;
- u8 buf[6];
-
- RTSX_DEBUGP("--%s--\n", __func__);
-
- if (type == 0)
- retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_TPCParm, 1);
- else
- retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6);
-
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- buf[0] = 0;
- buf[1] = 0;
- if (type == 1) {
- buf[2] = 0;
- buf[3] = 0;
- buf[4] = 0;
- buf[5] = mg_entry_num;
- }
- retval = ms_write_bytes(chip, PRO_WRITE_REG, (type == 0) ? 1 : 6, NO_WAIT_INT, buf, 6);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int retval;
- int i;
- unsigned int lun = SCSI_LUN(srb);
- u8 buf1[32], buf2[12];
-
- RTSX_DEBUGP("--%s--\n", __func__);
-
- if (scsi_bufflen(srb) < 12) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- ms_cleanup_work(chip);
-
- retval = ms_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = mg_send_ex_cmd(chip, MG_SET_LID, 0);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- memset(buf1, 0, 32);
- rtsx_stor_get_xfer_buf(buf2, min(12, (int)scsi_bufflen(srb)), srb);
- for (i = 0; i < 8; i++)
- buf1[8+i] = buf2[4+i];
-
- retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf1, 32);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (check_ms_err(chip)) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
- rtsx_clear_ms_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int retval = STATUS_FAIL;
- int bufflen;
- unsigned int lun = SCSI_LUN(srb);
- u8 *buf = NULL;
-
- RTSX_DEBUGP("--%s--\n", __func__);
-
- ms_cleanup_work(chip);
-
- retval = ms_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- buf = kmalloc(1540, GFP_KERNEL);
- if (!buf)
- TRACE_RET(chip, STATUS_ERROR);
-
- buf[0] = 0x04;
- buf[1] = 0x1A;
- buf[2] = 0x00;
- buf[3] = 0x00;
-
- retval = mg_send_ex_cmd(chip, MG_GET_LEKB, 0);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
- TRACE_GOTO(chip, GetEKBFinish);
- }
-
- retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA,
- 3, WAIT_INT, 0, 0, buf + 4, 1536);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
- rtsx_clear_ms_error(chip);
- TRACE_GOTO(chip, GetEKBFinish);
- }
- if (check_ms_err(chip)) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
- rtsx_clear_ms_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- bufflen = min(1052, (int)scsi_bufflen(srb));
- rtsx_stor_set_xfer_buf(buf, bufflen, srb);
-
-GetEKBFinish:
- kfree(buf);
- return retval;
-}
-
-int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
- int bufflen;
- int i;
- unsigned int lun = SCSI_LUN(srb);
- u8 buf[32];
-
- RTSX_DEBUGP("--%s--\n", __func__);
-
- ms_cleanup_work(chip);
-
- retval = ms_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = mg_send_ex_cmd(chip, MG_GET_ID, 0);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, buf, 32);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (check_ms_err(chip)) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
- rtsx_clear_ms_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- memcpy(ms_card->magic_gate_id, buf, 16);
-
-#ifdef READ_BYTES_WAIT_INT
- retval = ms_poll_int(chip);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
- TRACE_RET(chip, STATUS_FAIL);
- }
-#endif
-
- retval = mg_send_ex_cmd(chip, MG_SET_RD, 0);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- bufflen = min(12, (int)scsi_bufflen(srb));
- rtsx_stor_get_xfer_buf(buf, bufflen, srb);
-
- for (i = 0; i < 8; i++)
- buf[i] = buf[4+i];
-
- for (i = 0; i < 24; i++)
- buf[8+i] = 0;
-
- retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA,
- 32, WAIT_INT, buf, 32);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (check_ms_err(chip)) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
- rtsx_clear_ms_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- ms_card->mg_auth = 0;
-
- return STATUS_SUCCESS;
-}
-
-int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
- int bufflen;
- unsigned int lun = SCSI_LUN(srb);
- u8 buf1[32], buf2[36];
-
- RTSX_DEBUGP("--%s--\n", __func__);
-
- ms_cleanup_work(chip);
-
- retval = ms_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = mg_send_ex_cmd(chip, MG_MAKE_RMS, 0);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, buf1, 32);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (check_ms_err(chip)) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
- rtsx_clear_ms_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- buf2[0] = 0x00;
- buf2[1] = 0x22;
- buf2[2] = 0x00;
- buf2[3] = 0x00;
-
- memcpy(buf2 + 4, ms_card->magic_gate_id, 16);
- memcpy(buf2 + 20, buf1, 16);
-
- bufflen = min(36, (int)scsi_bufflen(srb));
- rtsx_stor_set_xfer_buf(buf2, bufflen, srb);
-
-#ifdef READ_BYTES_WAIT_INT
- retval = ms_poll_int(chip);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
- TRACE_RET(chip, STATUS_FAIL);
- }
-#endif
-
- return STATUS_SUCCESS;
-}
-
-int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
- int i;
- int bufflen;
- unsigned int lun = SCSI_LUN(srb);
- u8 buf[32];
-
- RTSX_DEBUGP("--%s--\n", __func__);
-
- ms_cleanup_work(chip);
-
- retval = ms_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = mg_send_ex_cmd(chip, MG_MAKE_KSE, 0);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- bufflen = min(12, (int)scsi_bufflen(srb));
- rtsx_stor_get_xfer_buf(buf, bufflen, srb);
-
- for (i = 0; i < 8; i++)
- buf[i] = buf[4+i];
-
- for (i = 0; i < 24; i++)
- buf[8+i] = 0;
-
- retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf, 32);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (check_ms_err(chip)) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
- rtsx_clear_ms_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- ms_card->mg_auth = 1;
-
- return STATUS_SUCCESS;
-}
-
-int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
- int bufflen;
- unsigned int lun = SCSI_LUN(srb);
- u8 *buf = NULL;
-
- RTSX_DEBUGP("--%s--\n", __func__);
-
- ms_cleanup_work(chip);
-
- retval = ms_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- buf = kmalloc(1028, GFP_KERNEL);
- if (!buf)
- TRACE_RET(chip, STATUS_ERROR);
-
- buf[0] = 0x04;
- buf[1] = 0x02;
- buf[2] = 0x00;
- buf[3] = 0x00;
-
- retval = mg_send_ex_cmd(chip, MG_GET_IBD, ms_card->mg_entry_num);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_GOTO(chip, GetICVFinish);
- }
-
- retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA,
- 2, WAIT_INT, 0, 0, buf + 4, 1024);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- rtsx_clear_ms_error(chip);
- TRACE_GOTO(chip, GetICVFinish);
- }
- if (check_ms_err(chip)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- rtsx_clear_ms_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- bufflen = min(1028, (int)scsi_bufflen(srb));
- rtsx_stor_set_xfer_buf(buf, bufflen, srb);
-
-GetICVFinish:
- kfree(buf);
- return retval;
-}
-
-int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
- int bufflen;
-#ifdef MG_SET_ICV_SLOW
- int i;
-#endif
- unsigned int lun = SCSI_LUN(srb);
- u8 *buf = NULL;
-
- RTSX_DEBUGP("--%s--\n", __func__);
-
- ms_cleanup_work(chip);
-
- retval = ms_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- buf = kmalloc(1028, GFP_KERNEL);
- if (!buf)
- TRACE_RET(chip, STATUS_ERROR);
-
- bufflen = min(1028, (int)scsi_bufflen(srb));
- rtsx_stor_get_xfer_buf(buf, bufflen, srb);
-
- retval = mg_send_ex_cmd(chip, MG_SET_IBD, ms_card->mg_entry_num);
- if (retval != STATUS_SUCCESS) {
- if (ms_card->mg_auth == 0) {
- if ((buf[5] & 0xC0) != 0)
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
- else
- set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR);
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR);
- }
- TRACE_GOTO(chip, SetICVFinish);
- }
-
-#ifdef MG_SET_ICV_SLOW
- for (i = 0; i < 2; i++) {
- udelay(50);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, PRO_WRITE_LONG_DATA);
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, WAIT_INT);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
-
- trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF,
- MS_TRANSFER_START | MS_TM_NORMAL_WRITE);
- rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END);
-
- rtsx_send_cmd_no_wait(chip);
-
- retval = rtsx_transfer_data(chip, MS_CARD, buf + 4 + i*512, 512, 0, DMA_TO_DEVICE, 3000);
- if ((retval < 0) || check_ms_err(chip)) {
- rtsx_clear_ms_error(chip);
- if (ms_card->mg_auth == 0) {
- if ((buf[5] & 0xC0) != 0)
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
- else
- set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR);
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR);
- }
- retval = STATUS_FAIL;
- TRACE_GOTO(chip, SetICVFinish);
- }
- }
-#else
- retval = ms_transfer_data(chip, MS_TM_AUTO_WRITE, PRO_WRITE_LONG_DATA,
- 2, WAIT_INT, 0, 0, buf + 4, 1024);
- if ((retval != STATUS_SUCCESS) || check_ms_err(chip)) {
- rtsx_clear_ms_error(chip);
- if (ms_card->mg_auth == 0) {
- if ((buf[5] & 0xC0) != 0)
- set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB);
- else
- set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR);
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR);
- }
- TRACE_GOTO(chip, SetICVFinish);
- }
-#endif
-
-SetICVFinish:
- kfree(buf);
- return retval;
-}
-
-#endif /* SUPPORT_MAGIC_GATE */
-
-void ms_cleanup_work(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
-
- if (CHK_MSPRO(ms_card)) {
- if (ms_card->seq_mode) {
- RTSX_DEBUGP("MS Pro: stop transmission\n");
- mspro_stop_seq_mode(chip);
- ms_card->cleanup_counter = 0;
- }
- if (CHK_MSHG(ms_card)) {
- rtsx_write_register(chip, MS_CFG,
- MS_2K_SECTOR_MODE, 0x00);
- }
- }
-#ifdef MS_DELAY_WRITE
- else if ((!CHK_MSPRO(ms_card)) && ms_card->delay_write.delay_write_flag) {
- RTSX_DEBUGP("MS: delay write\n");
- ms_delay_write(chip);
- ms_card->cleanup_counter = 0;
- }
-#endif
-}
-
-int ms_power_off_card3v3(struct rtsx_chip *chip)
-{
- int retval;
-
- retval = disable_card_clock(chip, MS_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (chip->asic_code) {
- retval = ms_pull_ctl_disable(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- RTSX_WRITE_REG(chip, FPGA_PULL_CTL,
- FPGA_MS_PULL_CTL_BIT | 0x20, FPGA_MS_PULL_CTL_BIT);
- }
- RTSX_WRITE_REG(chip, CARD_OE, MS_OUTPUT_EN, 0);
- if (!chip->ft2_fast_mode) {
- retval = card_power_off(chip, MS_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-int release_ms_card(struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
-
- RTSX_DEBUGP("release_ms_card\n");
-
-#ifdef MS_DELAY_WRITE
- ms_card->delay_write.delay_write_flag = 0;
-#endif
- ms_card->pro_under_formatting = 0;
-
- chip->card_ready &= ~MS_CARD;
- chip->card_fail &= ~MS_CARD;
- chip->card_wp &= ~MS_CARD;
-
- ms_free_l2p_tbl(chip);
-
- memset(ms_card->raw_sys_info, 0, 96);
-#ifdef SUPPORT_PCGL_1P18
- memset(ms_card->raw_model_name, 0, 48);
-#endif
-
- retval = ms_power_off_card3v3(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
diff --git a/drivers/staging/rts_pstor/ms.h b/drivers/staging/rts_pstor/ms.h
deleted file mode 100644
index 53701987613..00000000000
--- a/drivers/staging/rts_pstor/ms.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- * Header file
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#ifndef __REALTEK_RTSX_MS_H
-#define __REALTEK_RTSX_MS_H
-
-#define MS_DELAY_WRITE
-
-#define MS_MAX_RETRY_COUNT 3
-
-#define MS_EXTRA_SIZE 0x9
-
-#define WRT_PRTCT 0x01
-
-/* Error Code */
-#define MS_NO_ERROR 0x00
-#define MS_CRC16_ERROR 0x80
-#define MS_TO_ERROR 0x40
-#define MS_NO_CARD 0x20
-#define MS_NO_MEMORY 0x10
-#define MS_CMD_NK 0x08
-#define MS_FLASH_READ_ERROR 0x04
-#define MS_FLASH_WRITE_ERROR 0x02
-#define MS_BREQ_ERROR 0x01
-#define MS_NOT_FOUND 0x03
-
-/* Transfer Protocol Command */
-#define READ_PAGE_DATA 0x02
-#define READ_REG 0x04
-#define GET_INT 0x07
-#define WRITE_PAGE_DATA 0x0D
-#define WRITE_REG 0x0B
-#define SET_RW_REG_ADRS 0x08
-#define SET_CMD 0x0E
-
-#define PRO_READ_LONG_DATA 0x02
-#define PRO_READ_SHORT_DATA 0x03
-#define PRO_READ_REG 0x04
-#define PRO_READ_QUAD_DATA 0x05
-#define PRO_GET_INT 0x07
-#define PRO_WRITE_LONG_DATA 0x0D
-#define PRO_WRITE_SHORT_DATA 0x0C
-#define PRO_WRITE_QUAD_DATA 0x0A
-#define PRO_WRITE_REG 0x0B
-#define PRO_SET_RW_REG_ADRS 0x08
-#define PRO_SET_CMD 0x0E
-#define PRO_EX_SET_CMD 0x09
-
-#ifdef SUPPORT_MAGIC_GATE
-
-#define MG_GET_ID 0x40
-#define MG_SET_LID 0x41
-#define MG_GET_LEKB 0x42
-#define MG_SET_RD 0x43
-#define MG_MAKE_RMS 0x44
-#define MG_MAKE_KSE 0x45
-#define MG_SET_IBD 0x46
-#define MG_GET_IBD 0x47
-
-#endif
-
-#ifdef XC_POWERCLASS
-#define XC_CHG_POWER 0x16
-#endif
-
-#define BLOCK_READ 0xAA
-#define BLOCK_WRITE 0x55
-#define BLOCK_END 0x33
-#define BLOCK_ERASE 0x99
-#define FLASH_STOP 0xCC
-
-#define SLEEP 0x5A
-#define CLEAR_BUF 0xC3
-#define MS_RESET 0x3C
-
-#define PRO_READ_DATA 0x20
-#define PRO_WRITE_DATA 0x21
-#define PRO_READ_ATRB 0x24
-#define PRO_STOP 0x25
-#define PRO_ERASE 0x26
-#define PRO_READ_2K_DATA 0x27
-#define PRO_WRITE_2K_DATA 0x28
-
-#define PRO_FORMAT 0x10
-#define PRO_SLEEP 0x11
-
-#define IntReg 0x01
-#define StatusReg0 0x02
-#define StatusReg1 0x03
-
-#define SystemParm 0x10
-#define BlockAdrs 0x11
-#define CMDParm 0x14
-#define PageAdrs 0x15
-
-#define OverwriteFlag 0x16
-#define ManagemenFlag 0x17
-#define LogicalAdrs 0x18
-#define ReserveArea 0x1A
-
-#define Pro_IntReg 0x01
-#define Pro_StatusReg 0x02
-#define Pro_TypeReg 0x04
-#define Pro_IFModeReg 0x05
-#define Pro_CatagoryReg 0x06
-#define Pro_ClassReg 0x07
-
-
-#define Pro_SystemParm 0x10
-#define Pro_DataCount1 0x11
-#define Pro_DataCount0 0x12
-#define Pro_DataAddr3 0x13
-#define Pro_DataAddr2 0x14
-#define Pro_DataAddr1 0x15
-#define Pro_DataAddr0 0x16
-
-#define Pro_TPCParm 0x17
-#define Pro_CMDParm 0x18
-
-#define INT_REG_CED 0x80
-#define INT_REG_ERR 0x40
-#define INT_REG_BREQ 0x20
-#define INT_REG_CMDNK 0x01
-
-#define BLOCK_BOOT 0xC0
-#define BLOCK_OK 0x80
-#define PAGE_OK 0x60
-#define DATA_COMPL 0x10
-
-#define NOT_BOOT_BLOCK 0x4
-#define NOT_TRANSLATION_TABLE 0x8
-
-#define HEADER_ID0 PPBUF_BASE2
-#define HEADER_ID1 (PPBUF_BASE2 + 1)
-#define DISABLED_BLOCK0 (PPBUF_BASE2 + 0x170 + 4)
-#define DISABLED_BLOCK1 (PPBUF_BASE2 + 0x170 + 5)
-#define DISABLED_BLOCK2 (PPBUF_BASE2 + 0x170 + 6)
-#define DISABLED_BLOCK3 (PPBUF_BASE2 + 0x170 + 7)
-#define BLOCK_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 2)
-#define BLOCK_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 3)
-#define BLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 4)
-#define BLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 5)
-#define EBLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 6)
-#define EBLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 7)
-#define PAGE_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 8)
-#define PAGE_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 9)
-
-#define MS_Device_Type (PPBUF_BASE2 + 0x1D8)
-
-#define MS_4bit_Support (PPBUF_BASE2 + 0x1D3)
-
-#define setPS_NG 1
-#define setPS_Error 0
-
-#define PARALLEL_8BIT_IF 0x40
-#define PARALLEL_4BIT_IF 0x00
-#define SERIAL_IF 0x80
-
-#define BUF_FULL 0x10
-#define BUF_EMPTY 0x20
-
-#define MEDIA_BUSY 0x80
-#define FLASH_BUSY 0x40
-#define DATA_ERROR 0x20
-#define STS_UCDT 0x10
-#define EXTRA_ERROR 0x08
-#define STS_UCEX 0x04
-#define FLAG_ERROR 0x02
-#define STS_UCFG 0x01
-
-#define MS_SHORT_DATA_LEN 32
-
-#define FORMAT_SUCCESS 0
-#define FORMAT_FAIL 1
-#define FORMAT_IN_PROGRESS 2
-
-#define MS_SET_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag |= 0x80)
-#define MS_CLR_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag &= 0x7F)
-#define MS_TST_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag & 0x80)
-
-void mspro_polling_format_status(struct rtsx_chip *chip);
-
-void mspro_stop_seq_mode(struct rtsx_chip *chip);
-int reset_ms_card(struct rtsx_chip *chip);
-int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt);
-int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, int short_data_len, int quick_format);
-void ms_free_l2p_tbl(struct rtsx_chip *chip);
-void ms_cleanup_work(struct rtsx_chip *chip);
-int ms_power_off_card3v3(struct rtsx_chip *chip);
-int release_ms_card(struct rtsx_chip *chip);
-#ifdef MS_DELAY_WRITE
-int ms_delay_write(struct rtsx_chip *chip);
-#endif
-
-#ifdef SUPPORT_MAGIC_GATE
-int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-#endif
-
-#endif /* __REALTEK_RTSX_MS_H */
diff --git a/drivers/staging/rts_pstor/rtsx.c b/drivers/staging/rts_pstor/rtsx.c
deleted file mode 100644
index afe9c2e763d..00000000000
--- a/drivers/staging/rts_pstor/rtsx.c
+++ /dev/null
@@ -1,1105 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/blkdev.h>
-#include <linux/kthread.h>
-#include <linux/sched.h>
-#include <linux/workqueue.h>
-
-#include "rtsx.h"
-#include "rtsx_chip.h"
-#include "rtsx_transport.h"
-#include "rtsx_scsi.h"
-#include "rtsx_card.h"
-#include "general.h"
-
-#include "ms.h"
-#include "sd.h"
-#include "xd.h"
-
-#define DRIVER_VERSION "v1.10"
-
-MODULE_DESCRIPTION("Realtek PCI-Express card reader driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
-
-static unsigned int delay_use = 1;
-module_param(delay_use, uint, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device");
-
-static int ss_en;
-module_param(ss_en, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(ss_en, "enable selective suspend");
-
-static int ss_interval = 50;
-module_param(ss_interval, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(ss_interval, "Interval to enter ss state in seconds");
-
-static int auto_delink_en;
-module_param(auto_delink_en, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(auto_delink_en, "enable auto delink");
-
-static unsigned char aspm_l0s_l1_en;
-module_param(aspm_l0s_l1_en, byte, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(aspm_l0s_l1_en, "enable device aspm");
-
-static int msi_en;
-module_param(msi_en, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(msi_en, "enable msi");
-
-static irqreturn_t rtsx_interrupt(int irq, void *dev_id);
-
-/***********************************************************************
- * Host functions
- ***********************************************************************/
-
-static const char *host_info(struct Scsi_Host *host)
-{
- return "SCSI emulation for PCI-Express Mass Storage devices";
-}
-
-static int slave_alloc(struct scsi_device *sdev)
-{
- /*
- * Set the INQUIRY transfer length to 36. We don't use any of
- * the extra data and many devices choke if asked for more or
- * less than 36 bytes.
- */
- sdev->inquiry_len = 36;
- return 0;
-}
-
-static int slave_configure(struct scsi_device *sdev)
-{
- /* Scatter-gather buffers (all but the last) must have a length
- * divisible by the bulk maxpacket size. Otherwise a data packet
- * would end up being short, causing a premature end to the data
- * transfer. Since high-speed bulk pipes have a maxpacket size
- * of 512, we'll use that as the scsi device queue's DMA alignment
- * mask. Guaranteeing proper alignment of the first buffer will
- * have the desired effect because, except at the beginning and
- * the end, scatter-gather buffers follow page boundaries. */
- blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
-
- /* Set the SCSI level to at least 2. We'll leave it at 3 if that's
- * what is originally reported. We need this to avoid confusing
- * the SCSI layer with devices that report 0 or 1, but need 10-byte
- * commands (ala ATAPI devices behind certain bridges, or devices
- * which simply have broken INQUIRY data).
- *
- * NOTE: This means /dev/sg programs (ala cdrecord) will get the
- * actual information. This seems to be the preference for
- * programs like that.
- *
- * NOTE: This also means that /proc/scsi/scsi and sysfs may report
- * the actual value or the modified one, depending on where the
- * data comes from.
- */
- if (sdev->scsi_level < SCSI_2)
- sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2;
-
- return 0;
-}
-
-
-/***********************************************************************
- * /proc/scsi/ functions
- ***********************************************************************/
-
-/* we use this macro to help us write into the buffer */
-#undef SPRINTF
-#define SPRINTF(args...) \
- do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
-
-static int proc_info(struct Scsi_Host *host, char *buffer,
- char **start, off_t offset, int length, int inout)
-{
- char *pos = buffer;
-
- /* if someone is sending us data, just throw it away */
- if (inout)
- return length;
-
- /* print the controller name */
- SPRINTF(" Host scsi%d: %s\n", host->host_no, CR_DRIVER_NAME);
-
- /* print product, vendor, and driver version strings */
- SPRINTF(" Vendor: Realtek Corp.\n");
- SPRINTF(" Product: PCIE Card Reader\n");
- SPRINTF(" Version: %s\n", DRIVER_VERSION);
-
- /*
- * Calculate start of next buffer, and return value.
- */
- *start = buffer + offset;
-
- if ((pos - buffer) < offset)
- return 0;
- else if ((pos - buffer - offset) < length)
- return pos - buffer - offset;
- else
- return length;
-}
-
-/* queue a command */
-/* This is always called with scsi_lock(host) held */
-static int queuecommand_lck(struct scsi_cmnd *srb,
- void (*done)(struct scsi_cmnd *))
-{
- struct rtsx_dev *dev = host_to_rtsx(srb->device->host);
- struct rtsx_chip *chip = dev->chip;
-
- /* check for state-transition errors */
- if (chip->srb != NULL) {
- dev_err(&dev->pci->dev, "Error in %s: chip->srb = %p\n",
- __func__, chip->srb);
- return SCSI_MLQUEUE_HOST_BUSY;
- }
-
- /* fail the command if we are disconnecting */
- if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) {
- dev_info(&dev->pci->dev, "Fail command during disconnect\n");
- srb->result = DID_NO_CONNECT << 16;
- done(srb);
- return 0;
- }
-
- /* enqueue the command and wake up the control thread */
- srb->scsi_done = done;
- chip->srb = srb;
- complete(&dev->cmnd_ready);
-
- return 0;
-}
-
-static DEF_SCSI_QCMD(queuecommand)
-
-/***********************************************************************
- * Error handling functions
- ***********************************************************************/
-
-/* Command timeout and abort */
-static int command_abort(struct scsi_cmnd *srb)
-{
- struct Scsi_Host *host = srb->device->host;
- struct rtsx_dev *dev = host_to_rtsx(host);
- struct rtsx_chip *chip = dev->chip;
-
- dev_info(&dev->pci->dev, "%s called\n", __func__);
-
- scsi_lock(host);
-
- /* Is this command still active? */
- if (chip->srb != srb) {
- scsi_unlock(host);
- dev_info(&dev->pci->dev, "-- nothing to abort\n");
- return FAILED;
- }
-
- rtsx_set_stat(chip, RTSX_STAT_ABORT);
-
- scsi_unlock(host);
-
- /* Wait for the aborted command to finish */
- wait_for_completion(&dev->notify);
-
- return SUCCESS;
-}
-
-/* This invokes the transport reset mechanism to reset the state of the
- * device */
-static int device_reset(struct scsi_cmnd *srb)
-{
- int result = 0;
- struct rtsx_dev *dev = host_to_rtsx(srb->device->host);
-
- dev_info(&dev->pci->dev, "%s called\n", __func__);
-
- return result < 0 ? FAILED : SUCCESS;
-}
-
-/* Simulate a SCSI bus reset by resetting the device's USB port. */
-static int bus_reset(struct scsi_cmnd *srb)
-{
- int result = 0;
- struct rtsx_dev *dev = host_to_rtsx(srb->device->host);
-
- dev_info(&dev->pci->dev, "%s called\n", __func__);
-
- return result < 0 ? FAILED : SUCCESS;
-}
-
-
-/*
- * this defines our host template, with which we'll allocate hosts
- */
-
-static struct scsi_host_template rtsx_host_template = {
- /* basic userland interface stuff */
- .name = CR_DRIVER_NAME,
- .proc_name = CR_DRIVER_NAME,
- .proc_info = proc_info,
- .info = host_info,
-
- /* command interface -- queued only */
- .queuecommand = queuecommand,
-
- /* error and abort handlers */
- .eh_abort_handler = command_abort,
- .eh_device_reset_handler = device_reset,
- .eh_bus_reset_handler = bus_reset,
-
- /* queue commands only, only one command per LUN */
- .can_queue = 1,
- .cmd_per_lun = 1,
-
- /* unknown initiator id */
- .this_id = -1,
-
- .slave_alloc = slave_alloc,
- .slave_configure = slave_configure,
-
- /* lots of sg segments can be handled */
- .sg_tablesize = SG_ALL,
-
- /* limit the total size of a transfer to 120 KB */
- .max_sectors = 240,
-
- /* merge commands... this seems to help performance, but
- * periodically someone should test to see which setting is more
- * optimal.
- */
- .use_clustering = 1,
-
- /* emulated HBA */
- .emulated = 1,
-
- /* we do our own delay after a device or bus reset */
- .skip_settle_delay = 1,
-
- /* module management */
- .module = THIS_MODULE
-};
-
-
-static int rtsx_acquire_irq(struct rtsx_dev *dev)
-{
- struct rtsx_chip *chip = dev->chip;
-
- dev_info(&dev->pci->dev, "%s: chip->msi_en = %d, pci->irq = %d\n",
- __func__, chip->msi_en, dev->pci->irq);
-
- if (request_irq(dev->pci->irq, rtsx_interrupt,
- chip->msi_en ? 0 : IRQF_SHARED,
- CR_DRIVER_NAME, dev)) {
- dev_err(&dev->pci->dev,
- "rtsx: unable to grab IRQ %d, disabling device\n",
- dev->pci->irq);
- return -1;
- }
-
- dev->irq = dev->pci->irq;
- pci_intx(dev->pci, !chip->msi_en);
-
- return 0;
-}
-
-
-int rtsx_read_pci_cfg_byte(u8 bus, u8 dev, u8 func, u8 offset, u8 *val)
-{
- struct pci_dev *pdev;
- u8 data;
- u8 devfn = (dev << 3) | func;
-
- pdev = pci_get_bus_and_slot(bus, devfn);
- if (!pdev)
- return -1;
-
- pci_read_config_byte(pdev, offset, &data);
- if (val)
- *val = data;
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-/*
- * power management
- */
-static int rtsx_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci);
- struct rtsx_chip *chip;
-
- if (!dev)
- return 0;
-
- /* lock the device pointers */
- mutex_lock(&(dev->dev_mutex));
-
- chip = dev->chip;
-
- rtsx_do_before_power_down(chip, PM_S3);
-
- if (dev->irq >= 0) {
- synchronize_irq(dev->irq);
- free_irq(dev->irq, (void *)dev);
- dev->irq = -1;
- }
-
- if (chip->msi_en)
- pci_disable_msi(pci);
-
- pci_save_state(pci);
- pci_enable_wake(pci, pci_choose_state(pci, state), 1);
- pci_disable_device(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
-
- /* unlock the device pointers */
- mutex_unlock(&dev->dev_mutex);
-
- return 0;
-}
-
-static int rtsx_resume(struct pci_dev *pci)
-{
- struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci);
- struct rtsx_chip *chip;
-
- if (!dev)
- return 0;
-
- chip = dev->chip;
-
- /* lock the device pointers */
- mutex_lock(&(dev->dev_mutex));
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- dev_err(&dev->pci->dev,
- "%s: pci_enable_device failed, disabling device\n",
- CR_DRIVER_NAME);
- /* unlock the device pointers */
- mutex_unlock(&dev->dev_mutex);
- return -EIO;
- }
- pci_set_master(pci);
-
- if (chip->msi_en) {
- if (pci_enable_msi(pci) < 0)
- chip->msi_en = 0;
- }
-
- if (rtsx_acquire_irq(dev) < 0) {
- /* unlock the device pointers */
- mutex_unlock(&dev->dev_mutex);
- return -EIO;
- }
-
- rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 0x00);
- rtsx_init_chip(chip);
-
- /* unlock the device pointers */
- mutex_unlock(&dev->dev_mutex);
-
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static void rtsx_shutdown(struct pci_dev *pci)
-{
- struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci);
- struct rtsx_chip *chip;
-
- if (!dev)
- return;
-
- chip = dev->chip;
-
- rtsx_do_before_power_down(chip, PM_S1);
-
- if (dev->irq >= 0) {
- synchronize_irq(dev->irq);
- free_irq(dev->irq, (void *)dev);
- dev->irq = -1;
- }
-
- if (chip->msi_en)
- pci_disable_msi(pci);
-
- pci_disable_device(pci);
-
- return;
-}
-
-static int rtsx_control_thread(void *__dev)
-{
- struct rtsx_dev *dev = (struct rtsx_dev *)__dev;
- struct rtsx_chip *chip = dev->chip;
- struct Scsi_Host *host = rtsx_to_host(dev);
-
- for (;;) {
- if (wait_for_completion_interruptible(&dev->cmnd_ready))
- break;
-
- /* lock the device pointers */
- mutex_lock(&(dev->dev_mutex));
-
- /* if the device has disconnected, we are free to exit */
- if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) {
- dev_info(&dev->pci->dev, "-- rtsx-control exiting\n");
- mutex_unlock(&dev->dev_mutex);
- break;
- }
-
- /* lock access to the state */
- scsi_lock(host);
-
- /* has the command aborted ? */
- if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) {
- chip->srb->result = DID_ABORT << 16;
- goto SkipForAbort;
- }
-
- scsi_unlock(host);
-
- /* reject the command if the direction indicator
- * is UNKNOWN
- */
- if (chip->srb->sc_data_direction == DMA_BIDIRECTIONAL) {
- dev_err(&dev->pci->dev, "UNKNOWN data direction\n");
- chip->srb->result = DID_ERROR << 16;
- }
-
- /* reject if target != 0 or if LUN is higher than
- * the maximum known LUN
- */
- else if (chip->srb->device->id) {
- dev_err(&dev->pci->dev, "Bad target number (%d:%d)\n",
- chip->srb->device->id,
- chip->srb->device->lun);
- chip->srb->result = DID_BAD_TARGET << 16;
- }
-
- else if (chip->srb->device->lun > chip->max_lun) {
- dev_err(&dev->pci->dev, "Bad LUN (%d:%d)\n",
- chip->srb->device->id,
- chip->srb->device->lun);
- chip->srb->result = DID_BAD_TARGET << 16;
- }
-
- /* we've got a command, let's do it! */
- else {
- RTSX_DEBUG(scsi_show_command(chip->srb));
- rtsx_invoke_transport(chip->srb, chip);
- }
-
- /* lock access to the state */
- scsi_lock(host);
-
- /* did the command already complete because of a disconnect? */
- if (!chip->srb)
- ; /* nothing to do */
-
- /* indicate that the command is done */
- else if (chip->srb->result != DID_ABORT << 16) {
- chip->srb->scsi_done(chip->srb);
- } else {
-SkipForAbort:
- dev_err(&dev->pci->dev, "scsi command aborted\n");
- }
-
- if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) {
- complete(&(dev->notify));
-
- rtsx_set_stat(chip, RTSX_STAT_IDLE);
- }
-
- /* finished working on this command */
- chip->srb = NULL;
- scsi_unlock(host);
-
- /* unlock the device pointers */
- mutex_unlock(&dev->dev_mutex);
- } /* for (;;) */
-
- /* notify the exit routine that we're actually exiting now
- *
- * complete()/wait_for_completion() is similar to up()/down(),
- * except that complete() is safe in the case where the structure
- * is getting deleted in a parallel mode of execution (i.e. just
- * after the down() -- that's necessary for the thread-shutdown
- * case.
- *
- * complete_and_exit() goes even further than this -- it is safe in
- * the case that the thread of the caller is going away (not just
- * the structure) -- this is necessary for the module-remove case.
- * This is important in preemption kernels, which transfer the flow
- * of execution immediately upon a complete().
- */
- complete_and_exit(&dev->control_exit, 0);
-}
-
-
-static int rtsx_polling_thread(void *__dev)
-{
- struct rtsx_dev *dev = (struct rtsx_dev *)__dev;
- struct rtsx_chip *chip = dev->chip;
- struct sd_info *sd_card = &(chip->sd_card);
- struct xd_info *xd_card = &(chip->xd_card);
- struct ms_info *ms_card = &(chip->ms_card);
-
- sd_card->cleanup_counter = 0;
- xd_card->cleanup_counter = 0;
- ms_card->cleanup_counter = 0;
-
- /* Wait until SCSI scan finished */
- wait_timeout((delay_use + 5) * 1000);
-
- for (;;) {
-
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(POLLING_INTERVAL);
-
- /* lock the device pointers */
- mutex_lock(&(dev->dev_mutex));
-
- /* if the device has disconnected, we are free to exit */
- if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) {
- dev_info(&dev->pci->dev, "-- rtsx-polling exiting\n");
- mutex_unlock(&dev->dev_mutex);
- break;
- }
-
- mutex_unlock(&dev->dev_mutex);
-
- mspro_polling_format_status(chip);
-
- /* lock the device pointers */
- mutex_lock(&(dev->dev_mutex));
-
- rtsx_polling_func(chip);
-
- /* unlock the device pointers */
- mutex_unlock(&dev->dev_mutex);
- }
-
- complete_and_exit(&dev->polling_exit, 0);
-}
-
-/*
- * interrupt handler
- */
-static irqreturn_t rtsx_interrupt(int irq, void *dev_id)
-{
- struct rtsx_dev *dev = dev_id;
- struct rtsx_chip *chip;
- int retval;
- u32 status;
-
- if (dev)
- chip = dev->chip;
- else
- return IRQ_NONE;
-
- if (!chip)
- return IRQ_NONE;
-
- spin_lock(&dev->reg_lock);
-
- retval = rtsx_pre_handle_interrupt(chip);
- if (retval == STATUS_FAIL) {
- spin_unlock(&dev->reg_lock);
- if (chip->int_reg == 0xFFFFFFFF)
- return IRQ_HANDLED;
- else
- return IRQ_NONE;
- }
-
- status = chip->int_reg;
-
- if (dev->check_card_cd) {
- if (!(dev->check_card_cd & status)) {
- /* card not exist, return TRANS_RESULT_FAIL */
- dev->trans_result = TRANS_RESULT_FAIL;
- if (dev->done)
- complete(dev->done);
- goto Exit;
- }
- }
-
- if (status & (NEED_COMPLETE_INT | DELINK_INT)) {
- if (status & (TRANS_FAIL_INT | DELINK_INT)) {
- if (status & DELINK_INT)
- RTSX_SET_DELINK(chip);
- dev->trans_result = TRANS_RESULT_FAIL;
- if (dev->done)
- complete(dev->done);
- } else if (status & TRANS_OK_INT) {
- dev->trans_result = TRANS_RESULT_OK;
- if (dev->done)
- complete(dev->done);
- } else if (status & DATA_DONE_INT) {
- dev->trans_result = TRANS_NOT_READY;
- if (dev->done && (dev->trans_state == STATE_TRANS_SG))
- complete(dev->done);
- }
- }
-
-Exit:
- spin_unlock(&dev->reg_lock);
- return IRQ_HANDLED;
-}
-
-
-/* Release all our dynamic resources */
-static void rtsx_release_resources(struct rtsx_dev *dev)
-{
- dev_info(&dev->pci->dev, "-- %s\n", __func__);
-
- /* Tell the control thread to exit. The SCSI host must
- * already have been removed so it won't try to queue
- * any more commands.
- */
- dev_info(&dev->pci->dev, "-- sending exit command to thread\n");
- complete(&dev->cmnd_ready);
- if (dev->ctl_thread)
- wait_for_completion(&dev->control_exit);
- if (dev->polling_thread)
- wait_for_completion(&dev->polling_exit);
-
- wait_timeout(200);
-
- if (dev->rtsx_resv_buf) {
- dma_free_coherent(&(dev->pci->dev), RTSX_RESV_BUF_LEN,
- dev->rtsx_resv_buf, dev->rtsx_resv_buf_addr);
- dev->chip->host_cmds_ptr = NULL;
- dev->chip->host_sg_tbl_ptr = NULL;
- }
-
- if (dev->irq > 0)
- free_irq(dev->irq, (void *)dev);
- if (dev->chip->msi_en)
- pci_disable_msi(dev->pci);
- if (dev->remap_addr)
- iounmap(dev->remap_addr);
-
- pci_disable_device(dev->pci);
- pci_release_regions(dev->pci);
-
- rtsx_release_chip(dev->chip);
- kfree(dev->chip);
-}
-
-/* First stage of disconnect processing: stop all commands and remove
- * the host */
-static void quiesce_and_remove_host(struct rtsx_dev *dev)
-{
- struct Scsi_Host *host = rtsx_to_host(dev);
- struct rtsx_chip *chip = dev->chip;
-
- /* Prevent new transfers, stop the current command, and
- * interrupt a SCSI-scan or device-reset delay */
- mutex_lock(&dev->dev_mutex);
- scsi_lock(host);
- rtsx_set_stat(chip, RTSX_STAT_DISCONNECT);
- scsi_unlock(host);
- mutex_unlock(&dev->dev_mutex);
- wake_up(&dev->delay_wait);
- wait_for_completion(&dev->scanning_done);
-
- /* Wait some time to let other threads exist */
- wait_timeout(100);
-
- /* queuecommand won't accept any new commands and the control
- * thread won't execute a previously-queued command. If there
- * is such a command pending, complete it with an error. */
- mutex_lock(&dev->dev_mutex);
- if (chip->srb) {
- chip->srb->result = DID_NO_CONNECT << 16;
- scsi_lock(host);
- chip->srb->scsi_done(dev->chip->srb);
- chip->srb = NULL;
- scsi_unlock(host);
- }
- mutex_unlock(&dev->dev_mutex);
-
- /* Now we own no commands so it's safe to remove the SCSI host */
- scsi_remove_host(host);
-}
-
-/* Second stage of disconnect processing: deallocate all resources */
-static void release_everything(struct rtsx_dev *dev)
-{
- rtsx_release_resources(dev);
-
- /* Drop our reference to the host; the SCSI core will free it
- * when the refcount becomes 0. */
- scsi_host_put(rtsx_to_host(dev));
-}
-
-/* Thread to carry out delayed SCSI-device scanning */
-static int rtsx_scan_thread(void *__dev)
-{
- struct rtsx_dev *dev = (struct rtsx_dev *)__dev;
- struct rtsx_chip *chip = dev->chip;
-
- /* Wait for the timeout to expire or for a disconnect */
- if (delay_use > 0) {
- dev_info(&dev->pci->dev,
- "%s: waiting for device to settle before scanning\n",
- CR_DRIVER_NAME);
- wait_event_interruptible_timeout(dev->delay_wait,
- rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT),
- delay_use * HZ);
- }
-
- /* If the device is still connected, perform the scanning */
- if (!rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) {
- scsi_scan_host(rtsx_to_host(dev));
- dev_info(&dev->pci->dev, "%s: device scan complete\n",
- CR_DRIVER_NAME);
-
- /* Should we unbind if no devices were detected? */
- }
-
- complete_and_exit(&dev->scanning_done, 0);
-}
-
-static void rtsx_init_options(struct rtsx_chip *chip)
-{
- chip->vendor_id = chip->rtsx->pci->vendor;
- chip->product_id = chip->rtsx->pci->device;
- chip->adma_mode = 1;
- chip->lun_mc = 0;
- chip->driver_first_load = 1;
-#ifdef HW_AUTO_SWITCH_SD_BUS
- chip->sdio_in_charge = 0;
-#endif
-
- chip->mspro_formatter_enable = 1;
- chip->ignore_sd = 0;
- chip->use_hw_setting = 0;
- chip->lun_mode = DEFAULT_SINGLE;
- chip->auto_delink_en = auto_delink_en;
- chip->ss_en = ss_en;
- chip->ss_idle_period = ss_interval * 1000;
- chip->remote_wakeup_en = 0;
- chip->aspm_l0s_l1_en = aspm_l0s_l1_en;
- chip->dynamic_aspm = 1;
- chip->fpga_sd_sdr104_clk = CLK_200;
- chip->fpga_sd_ddr50_clk = CLK_100;
- chip->fpga_sd_sdr50_clk = CLK_100;
- chip->fpga_sd_hs_clk = CLK_100;
- chip->fpga_mmc_52m_clk = CLK_80;
- chip->fpga_ms_hg_clk = CLK_80;
- chip->fpga_ms_4bit_clk = CLK_80;
- chip->fpga_ms_1bit_clk = CLK_40;
- chip->asic_sd_sdr104_clk = 203;
- chip->asic_sd_sdr50_clk = 98;
- chip->asic_sd_ddr50_clk = 98;
- chip->asic_sd_hs_clk = 98;
- chip->asic_mmc_52m_clk = 98;
- chip->asic_ms_hg_clk = 117;
- chip->asic_ms_4bit_clk = 78;
- chip->asic_ms_1bit_clk = 39;
- chip->ssc_depth_sd_sdr104 = SSC_DEPTH_2M;
- chip->ssc_depth_sd_sdr50 = SSC_DEPTH_2M;
- chip->ssc_depth_sd_ddr50 = SSC_DEPTH_1M;
- chip->ssc_depth_sd_hs = SSC_DEPTH_1M;
- chip->ssc_depth_mmc_52m = SSC_DEPTH_1M;
- chip->ssc_depth_ms_hg = SSC_DEPTH_1M;
- chip->ssc_depth_ms_4bit = SSC_DEPTH_512K;
- chip->ssc_depth_low_speed = SSC_DEPTH_512K;
- chip->ssc_en = 1;
- chip->sd_speed_prior = 0x01040203;
- chip->sd_current_prior = 0x00010203;
- chip->sd_ctl = SD_PUSH_POINT_AUTO |
- SD_SAMPLE_POINT_AUTO |
- SUPPORT_MMC_DDR_MODE;
- chip->sd_ddr_tx_phase = 0;
- chip->mmc_ddr_tx_phase = 1;
- chip->sd_default_tx_phase = 15;
- chip->sd_default_rx_phase = 15;
- chip->pmos_pwr_on_interval = 200;
- chip->sd_voltage_switch_delay = 1000;
- chip->ms_power_class_en = 3;
-
- chip->sd_400mA_ocp_thd = 1;
- chip->sd_800mA_ocp_thd = 5;
- chip->ms_ocp_thd = 2;
-
- chip->card_drive_sel = 0x55;
- chip->sd30_drive_sel_1v8 = 0x03;
- chip->sd30_drive_sel_3v3 = 0x01;
-
- chip->do_delink_before_power_down = 1;
- chip->auto_power_down = 1;
- chip->polling_config = 0;
-
- chip->force_clkreq_0 = 1;
- chip->ft2_fast_mode = 0;
-
- chip->sdio_retry_cnt = 1;
-
- chip->xd_timeout = 2000;
- chip->sd_timeout = 10000;
- chip->ms_timeout = 2000;
- chip->mspro_timeout = 15000;
-
- chip->power_down_in_ss = 1;
-
- chip->sdr104_en = 1;
- chip->sdr50_en = 1;
- chip->ddr50_en = 1;
-
- chip->delink_stage1_step = 100;
- chip->delink_stage2_step = 40;
- chip->delink_stage3_step = 20;
-
- chip->auto_delink_in_L1 = 1;
- chip->blink_led = 1;
- chip->msi_en = msi_en;
- chip->hp_watch_bios_hotplug = 0;
- chip->max_payload = 0;
- chip->phy_voltage = 0;
-
- chip->support_ms_8bit = 1;
- chip->s3_pwr_off_delay = 1000;
-}
-
-static int __devinit rtsx_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- struct Scsi_Host *host;
- struct rtsx_dev *dev;
- int err = 0;
- struct task_struct *th;
-
- RTSX_DEBUGP("Realtek PCI-E card reader detected\n");
-
- err = pci_enable_device(pci);
- if (err < 0) {
- dev_err(&pci->dev, "PCI enable device failed!\n");
- return err;
- }
-
- err = pci_request_regions(pci, CR_DRIVER_NAME);
- if (err < 0) {
- dev_err(&pci->dev, "PCI request regions for %s failed!\n",
- CR_DRIVER_NAME);
- pci_disable_device(pci);
- return err;
- }
-
- /*
- * Ask the SCSI layer to allocate a host structure, with extra
- * space at the end for our private rtsx_dev structure.
- */
- host = scsi_host_alloc(&rtsx_host_template, sizeof(*dev));
- if (!host) {
- dev_err(&pci->dev, "Unable to allocate the scsi host\n");
- pci_release_regions(pci);
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- dev = host_to_rtsx(host);
- memset(dev, 0, sizeof(struct rtsx_dev));
-
- dev->chip = kzalloc(sizeof(struct rtsx_chip), GFP_KERNEL);
- if (dev->chip == NULL)
- goto errout;
-
- spin_lock_init(&dev->reg_lock);
- mutex_init(&(dev->dev_mutex));
- init_completion(&dev->cmnd_ready);
- init_completion(&dev->control_exit);
- init_completion(&dev->polling_exit);
- init_completion(&(dev->notify));
- init_completion(&dev->scanning_done);
- init_waitqueue_head(&dev->delay_wait);
-
- dev->pci = pci;
- dev->irq = -1;
-
- dev_info(&pci->dev, "Resource length: 0x%x\n",
- (unsigned int)pci_resource_len(pci, 0));
- dev->addr = pci_resource_start(pci, 0);
- dev->remap_addr = ioremap_nocache(dev->addr, pci_resource_len(pci, 0));
- if (dev->remap_addr == NULL) {
- dev_err(&pci->dev, "ioremap error\n");
- err = -ENXIO;
- goto errout;
- }
-
- /*
- * Using "unsigned long" cast here to eliminate gcc warning in
- * 64-bit system
- */
- dev_info(&pci->dev, "Original address: 0x%lx, remapped address: 0x%lx\n",
- (unsigned long)(dev->addr), (unsigned long)(dev->remap_addr));
-
- dev->rtsx_resv_buf = dma_alloc_coherent(&(pci->dev), RTSX_RESV_BUF_LEN,
- &(dev->rtsx_resv_buf_addr), GFP_KERNEL);
- if (dev->rtsx_resv_buf == NULL) {
- dev_err(&pci->dev, "alloc dma buffer fail\n");
- err = -ENXIO;
- goto errout;
- }
- dev->chip->host_cmds_ptr = dev->rtsx_resv_buf;
- dev->chip->host_cmds_addr = dev->rtsx_resv_buf_addr;
- dev->chip->host_sg_tbl_ptr = dev->rtsx_resv_buf + HOST_CMDS_BUF_LEN;
- dev->chip->host_sg_tbl_addr = dev->rtsx_resv_buf_addr +
- HOST_CMDS_BUF_LEN;
-
- dev->chip->rtsx = dev;
-
- rtsx_init_options(dev->chip);
-
- dev_info(&pci->dev, "pci->irq = %d\n", pci->irq);
-
- if (dev->chip->msi_en) {
- if (pci_enable_msi(pci) < 0)
- dev->chip->msi_en = 0;
- }
-
- if (rtsx_acquire_irq(dev) < 0) {
- err = -EBUSY;
- goto errout;
- }
-
- pci_set_master(pci);
- synchronize_irq(dev->irq);
-
- rtsx_init_chip(dev->chip);
-
- /* set the supported max_lun and max_id for the scsi host
- * NOTE: the minimal value of max_id is 1 */
- host->max_id = 1;
- host->max_lun = dev->chip->max_lun;
-
- /* Start up our control thread */
- th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME);
- if (IS_ERR(th)) {
- dev_err(&pci->dev, "Unable to start control thread\n");
- err = PTR_ERR(th);
- goto errout;
- }
- dev->ctl_thread = th;
-
- err = scsi_add_host(host, &pci->dev);
- if (err) {
- dev_err(&pci->dev, "Unable to add the scsi host\n");
- goto errout;
- }
-
- /* Start up the thread for delayed SCSI-device scanning */
- th = kthread_run(rtsx_scan_thread, dev, "rtsx-scan");
- if (IS_ERR(th)) {
- dev_err(&pci->dev, "Unable to start the device-scanning thread\n");
- complete(&dev->scanning_done);
- quiesce_and_remove_host(dev);
- err = PTR_ERR(th);
- goto errout;
- }
-
- /* Start up the thread for polling thread */
- th = kthread_run(rtsx_polling_thread, dev, "rtsx-polling");
- if (IS_ERR(th)) {
- dev_err(&pci->dev, "Unable to start the device-polling thread\n");
- quiesce_and_remove_host(dev);
- err = PTR_ERR(th);
- goto errout;
- }
- dev->polling_thread = th;
-
- pci_set_drvdata(pci, dev);
-
- return 0;
-
- /* We come here if there are any problems */
-errout:
- dev_err(&pci->dev, "rtsx_probe() failed\n");
- release_everything(dev);
-
- return err;
-}
-
-
-static void __devexit rtsx_remove(struct pci_dev *pci)
-{
- struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci);
-
- dev_info(&pci->dev, "rtsx_remove() called\n");
-
- quiesce_and_remove_host(dev);
- release_everything(dev);
-
- pci_set_drvdata(pci, NULL);
-}
-
-/* PCI IDs */
-static DEFINE_PCI_DEVICE_TABLE(rtsx_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5208), PCI_CLASS_OTHERS << 16, 0xFF0000 },
- { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5209), PCI_CLASS_OTHERS << 16, 0xFF0000 },
- { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5288), PCI_CLASS_OTHERS << 16, 0xFF0000 },
- { 0, },
-};
-
-MODULE_DEVICE_TABLE(pci, rtsx_ids);
-
-/* pci_driver definition */
-static struct pci_driver driver = {
- .name = CR_DRIVER_NAME,
- .id_table = rtsx_ids,
- .probe = rtsx_probe,
- .remove = __devexit_p(rtsx_remove),
-#ifdef CONFIG_PM
- .suspend = rtsx_suspend,
- .resume = rtsx_resume,
-#endif
- .shutdown = rtsx_shutdown,
-};
-
-static int __init rtsx_init(void)
-{
- pr_info("Initializing Realtek PCIE storage driver...\n");
-
- return pci_register_driver(&driver);
-}
-
-static void __exit rtsx_exit(void)
-{
- pr_info("rtsx_exit() called\n");
-
- pci_unregister_driver(&driver);
-
- pr_info("%s module exit\n", CR_DRIVER_NAME);
-}
-
-module_init(rtsx_init)
-module_exit(rtsx_exit)
-
diff --git a/drivers/staging/rts_pstor/rtsx.h b/drivers/staging/rts_pstor/rtsx.h
deleted file mode 100644
index 1ab42fcc47d..00000000000
--- a/drivers/staging/rts_pstor/rtsx.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- * Header file
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#ifndef __REALTEK_RTSX_H
-#define __REALTEK_RTSX_H
-
-#include <linux/io.h>
-#include <linux/bitops.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/mutex.h>
-#include <linux/cdrom.h>
-#include <linux/workqueue.h>
-#include <linux/timer.h>
-#include <linux/time.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_devinfo.h>
-#include <scsi/scsi_eh.h>
-#include <scsi/scsi_host.h>
-
-#include "debug.h"
-#include "trace.h"
-#include "general.h"
-
-#define CR_DRIVER_NAME "rts_pstor"
-
-#define pci_get_bus_and_slot(bus, devfn) \
- pci_get_domain_bus_and_slot(0, (bus), (devfn))
-
-/*
- * macros for easy use
- */
-#define rtsx_writel(chip, reg, value) \
- iowrite32(value, (chip)->rtsx->remap_addr + reg)
-#define rtsx_readl(chip, reg) \
- ioread32((chip)->rtsx->remap_addr + reg)
-#define rtsx_writew(chip, reg, value) \
- iowrite16(value, (chip)->rtsx->remap_addr + reg)
-#define rtsx_readw(chip, reg) \
- ioread16((chip)->rtsx->remap_addr + reg)
-#define rtsx_writeb(chip, reg, value) \
- iowrite8(value, (chip)->rtsx->remap_addr + reg)
-#define rtsx_readb(chip, reg) \
- ioread8((chip)->rtsx->remap_addr + reg)
-
-#define rtsx_read_config_byte(chip, where, val) \
- pci_read_config_byte((chip)->rtsx->pci, where, val)
-
-#define rtsx_write_config_byte(chip, where, val) \
- pci_write_config_byte((chip)->rtsx->pci, where, val)
-
-#define wait_timeout_x(task_state, msecs) \
-do { \
- set_current_state((task_state)); \
- schedule_timeout((msecs) * HZ / 1000); \
-} while (0)
-#define wait_timeout(msecs) wait_timeout_x(TASK_INTERRUPTIBLE, (msecs))
-
-
-#define STATE_TRANS_NONE 0
-#define STATE_TRANS_CMD 1
-#define STATE_TRANS_BUF 2
-#define STATE_TRANS_SG 3
-
-#define TRANS_NOT_READY 0
-#define TRANS_RESULT_OK 1
-#define TRANS_RESULT_FAIL 2
-
-#define SCSI_LUN(srb) ((srb)->device->lun)
-
-typedef unsigned long DELAY_PARA_T;
-
-struct rtsx_chip;
-
-struct rtsx_dev {
- struct pci_dev *pci;
-
- /* pci resources */
- unsigned long addr;
- void __iomem *remap_addr;
- int irq;
-
- /* locks */
- spinlock_t reg_lock;
-
- struct task_struct *ctl_thread; /* the control thread */
- struct task_struct *polling_thread; /* the polling thread */
-
- /* mutual exclusion and synchronization structures */
- struct completion cmnd_ready; /* to sleep thread on */
- struct completion control_exit; /* control thread exit */
- struct completion polling_exit; /* polling thread exit */
- struct completion notify; /* thread begin/end */
- struct completion scanning_done; /* wait for scan thread */
-
- wait_queue_head_t delay_wait; /* wait during scan, reset */
- struct mutex dev_mutex;
-
- /* host reserved buffer */
- void *rtsx_resv_buf;
- dma_addr_t rtsx_resv_buf_addr;
-
- char trans_result;
- char trans_state;
-
- struct completion *done;
- /* Whether interrupt handler should care card cd info */
- u32 check_card_cd;
-
- struct rtsx_chip *chip;
-};
-
-typedef struct rtsx_dev rtsx_dev_t;
-
-/* Convert between rtsx_dev and the corresponding Scsi_Host */
-static inline struct Scsi_Host *rtsx_to_host(struct rtsx_dev *dev)
-{
- return container_of((void *) dev, struct Scsi_Host, hostdata);
-}
-static inline struct rtsx_dev *host_to_rtsx(struct Scsi_Host *host)
-{
- return (struct rtsx_dev *) host->hostdata;
-}
-
-static inline void get_current_time(u8 *timeval_buf, int buf_len)
-{
- struct timeval tv;
-
- if (!timeval_buf || (buf_len < 8))
- return;
-
- do_gettimeofday(&tv);
-
- timeval_buf[0] = (u8)(tv.tv_sec >> 24);
- timeval_buf[1] = (u8)(tv.tv_sec >> 16);
- timeval_buf[2] = (u8)(tv.tv_sec >> 8);
- timeval_buf[3] = (u8)(tv.tv_sec);
- timeval_buf[4] = (u8)(tv.tv_usec >> 24);
- timeval_buf[5] = (u8)(tv.tv_usec >> 16);
- timeval_buf[6] = (u8)(tv.tv_usec >> 8);
- timeval_buf[7] = (u8)(tv.tv_usec);
-}
-
-/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the
- * single queue element srb for write access */
-#define scsi_unlock(host) spin_unlock_irq(host->host_lock)
-#define scsi_lock(host) spin_lock_irq(host->host_lock)
-
-#define lock_state(chip) spin_lock_irq(&((chip)->rtsx->reg_lock))
-#define unlock_state(chip) spin_unlock_irq(&((chip)->rtsx->reg_lock))
-
-/* struct scsi_cmnd transfer buffer access utilities */
-enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF};
-
-int rtsx_read_pci_cfg_byte(u8 bus, u8 dev, u8 func, u8 offset, u8 *val);
-
-#endif /* __REALTEK_RTSX_H */
diff --git a/drivers/staging/rts_pstor/rtsx_card.c b/drivers/staging/rts_pstor/rtsx_card.c
deleted file mode 100644
index 539aa6a2778..00000000000
--- a/drivers/staging/rts_pstor/rtsx_card.c
+++ /dev/null
@@ -1,1233 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#include <linux/blkdev.h>
-#include <linux/kthread.h>
-#include <linux/sched.h>
-#include <linux/workqueue.h>
-#include <linux/kernel.h>
-
-#include "rtsx.h"
-#include "rtsx_transport.h"
-#include "rtsx_scsi.h"
-#include "rtsx_card.h"
-
-#include "rtsx_sys.h"
-#include "general.h"
-
-#include "sd.h"
-#include "xd.h"
-#include "ms.h"
-
-void do_remaining_work(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
-#ifdef XD_DELAY_WRITE
- struct xd_info *xd_card = &(chip->xd_card);
-#endif
- struct ms_info *ms_card = &(chip->ms_card);
-
- if (chip->card_ready & SD_CARD) {
- if (sd_card->seq_mode) {
- rtsx_set_stat(chip, RTSX_STAT_RUN);
- sd_card->cleanup_counter++;
- } else {
- sd_card->cleanup_counter = 0;
- }
- }
-
-#ifdef XD_DELAY_WRITE
- if (chip->card_ready & XD_CARD) {
- if (xd_card->delay_write.delay_write_flag) {
- rtsx_set_stat(chip, RTSX_STAT_RUN);
- xd_card->cleanup_counter++;
- } else {
- xd_card->cleanup_counter = 0;
- }
- }
-#endif
-
- if (chip->card_ready & MS_CARD) {
- if (CHK_MSPRO(ms_card)) {
- if (ms_card->seq_mode) {
- rtsx_set_stat(chip, RTSX_STAT_RUN);
- ms_card->cleanup_counter++;
- } else {
- ms_card->cleanup_counter = 0;
- }
- } else {
-#ifdef MS_DELAY_WRITE
- if (ms_card->delay_write.delay_write_flag) {
- rtsx_set_stat(chip, RTSX_STAT_RUN);
- ms_card->cleanup_counter++;
- } else {
- ms_card->cleanup_counter = 0;
- }
-#endif
- }
- }
-
- if (sd_card->cleanup_counter > POLLING_WAIT_CNT)
- sd_cleanup_work(chip);
-
- if (xd_card->cleanup_counter > POLLING_WAIT_CNT)
- xd_cleanup_work(chip);
-
- if (ms_card->cleanup_counter > POLLING_WAIT_CNT)
- ms_cleanup_work(chip);
-}
-
-void try_to_switch_sdio_ctrl(struct rtsx_chip *chip)
-{
- u8 reg1 = 0, reg2 = 0;
-
- rtsx_read_register(chip, 0xFF34, &reg1);
- rtsx_read_register(chip, 0xFF38, &reg2);
- RTSX_DEBUGP("reg 0xFF34: 0x%x, reg 0xFF38: 0x%x\n", reg1, reg2);
- if ((reg1 & 0xC0) && (reg2 & 0xC0)) {
- chip->sd_int = 1;
- rtsx_write_register(chip, SDIO_CTRL, 0xFF, SDIO_BUS_CTRL | SDIO_CD_CTRL);
- rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON);
- }
-}
-
-#ifdef SUPPORT_SDIO_ASPM
-void dynamic_configure_sdio_aspm(struct rtsx_chip *chip)
-{
- u8 buf[12], reg;
- int i;
-
- for (i = 0; i < 12; i++)
- rtsx_read_register(chip, 0xFF08 + i, &buf[i]);
- rtsx_read_register(chip, 0xFF25, &reg);
- if ((memcmp(buf, chip->sdio_raw_data, 12) != 0) || (reg & 0x03)) {
- chip->sdio_counter = 0;
- chip->sdio_idle = 0;
- } else {
- if (!chip->sdio_idle) {
- chip->sdio_counter++;
- if (chip->sdio_counter >= SDIO_IDLE_COUNT) {
- chip->sdio_counter = 0;
- chip->sdio_idle = 1;
- }
- }
- }
- memcpy(chip->sdio_raw_data, buf, 12);
-
- if (chip->sdio_idle) {
- if (!chip->sdio_aspm) {
- RTSX_DEBUGP("SDIO enter ASPM!\n");
- rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC,
- 0x30 | (chip->aspm_level[1] << 2));
- chip->sdio_aspm = 1;
- }
- } else {
- if (chip->sdio_aspm) {
- RTSX_DEBUGP("SDIO exit ASPM!\n");
- rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, 0x30);
- chip->sdio_aspm = 0;
- }
- }
-}
-#endif
-
-void do_reset_sd_card(struct rtsx_chip *chip)
-{
- int retval;
-
- RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__,
- chip->sd_reset_counter, chip->card2lun[SD_CARD]);
-
- if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT) {
- clear_bit(SD_NR, &(chip->need_reset));
- chip->sd_reset_counter = 0;
- chip->sd_show_cnt = 0;
- return;
- }
-
- chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0;
-
- rtsx_set_stat(chip, RTSX_STAT_RUN);
- rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0);
-
- retval = reset_sd_card(chip);
- if (chip->need_release & SD_CARD)
- return;
- if (retval == STATUS_SUCCESS) {
- clear_bit(SD_NR, &(chip->need_reset));
- chip->sd_reset_counter = 0;
- chip->sd_show_cnt = 0;
- chip->card_ready |= SD_CARD;
- chip->card_fail &= ~SD_CARD;
- chip->rw_card[chip->card2lun[SD_CARD]] = sd_rw;
- } else {
- if (chip->sd_io || (chip->sd_reset_counter >= MAX_RESET_CNT)) {
- clear_bit(SD_NR, &(chip->need_reset));
- chip->sd_reset_counter = 0;
- chip->sd_show_cnt = 0;
- } else {
- chip->sd_reset_counter++;
- }
- chip->card_ready &= ~SD_CARD;
- chip->card_fail |= SD_CARD;
- chip->capacity[chip->card2lun[SD_CARD]] = 0;
- chip->rw_card[chip->card2lun[SD_CARD]] = NULL;
-
- rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0);
- if (!chip->ft2_fast_mode)
- card_power_off(chip, SD_CARD);
- if (chip->sd_io) {
- chip->sd_int = 0;
- try_to_switch_sdio_ctrl(chip);
- } else {
- disable_card_clock(chip, SD_CARD);
- }
- }
-}
-
-void do_reset_xd_card(struct rtsx_chip *chip)
-{
- int retval;
-
- RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__,
- chip->xd_reset_counter, chip->card2lun[XD_CARD]);
-
- if (chip->card2lun[XD_CARD] >= MAX_ALLOWED_LUN_CNT) {
- clear_bit(XD_NR, &(chip->need_reset));
- chip->xd_reset_counter = 0;
- chip->xd_show_cnt = 0;
- return;
- }
-
- chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0;
-
- rtsx_set_stat(chip, RTSX_STAT_RUN);
- rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0);
-
- retval = reset_xd_card(chip);
- if (chip->need_release & XD_CARD)
- return;
- if (retval == STATUS_SUCCESS) {
- clear_bit(XD_NR, &(chip->need_reset));
- chip->xd_reset_counter = 0;
- chip->card_ready |= XD_CARD;
- chip->card_fail &= ~XD_CARD;
- chip->rw_card[chip->card2lun[XD_CARD]] = xd_rw;
- } else {
- if (chip->xd_reset_counter >= MAX_RESET_CNT) {
- clear_bit(XD_NR, &(chip->need_reset));
- chip->xd_reset_counter = 0;
- chip->xd_show_cnt = 0;
- } else {
- chip->xd_reset_counter++;
- }
- chip->card_ready &= ~XD_CARD;
- chip->card_fail |= XD_CARD;
- chip->capacity[chip->card2lun[XD_CARD]] = 0;
- chip->rw_card[chip->card2lun[XD_CARD]] = NULL;
-
- rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0);
- if (!chip->ft2_fast_mode)
- card_power_off(chip, XD_CARD);
- disable_card_clock(chip, XD_CARD);
- }
-}
-
-void do_reset_ms_card(struct rtsx_chip *chip)
-{
- int retval;
-
- RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__,
- chip->ms_reset_counter, chip->card2lun[MS_CARD]);
-
- if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT) {
- clear_bit(MS_NR, &(chip->need_reset));
- chip->ms_reset_counter = 0;
- chip->ms_show_cnt = 0;
- return;
- }
-
- chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0;
-
- rtsx_set_stat(chip, RTSX_STAT_RUN);
- rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0);
-
- retval = reset_ms_card(chip);
- if (chip->need_release & MS_CARD)
- return;
- if (retval == STATUS_SUCCESS) {
- clear_bit(MS_NR, &(chip->need_reset));
- chip->ms_reset_counter = 0;
- chip->card_ready |= MS_CARD;
- chip->card_fail &= ~MS_CARD;
- chip->rw_card[chip->card2lun[MS_CARD]] = ms_rw;
- } else {
- if (chip->ms_reset_counter >= MAX_RESET_CNT) {
- clear_bit(MS_NR, &(chip->need_reset));
- chip->ms_reset_counter = 0;
- chip->ms_show_cnt = 0;
- } else {
- chip->ms_reset_counter++;
- }
- chip->card_ready &= ~MS_CARD;
- chip->card_fail |= MS_CARD;
- chip->capacity[chip->card2lun[MS_CARD]] = 0;
- chip->rw_card[chip->card2lun[MS_CARD]] = NULL;
-
- rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0);
- if (!chip->ft2_fast_mode)
- card_power_off(chip, MS_CARD);
- disable_card_clock(chip, MS_CARD);
- }
-}
-
-static void release_sdio(struct rtsx_chip *chip)
-{
- if (chip->sd_io) {
- rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR,
- SD_STOP | SD_CLR_ERR);
-
- if (chip->chip_insert_with_sdio) {
- chip->chip_insert_with_sdio = 0;
-
- if (CHECK_PID(chip, 0x5288))
- rtsx_write_register(chip, 0xFE5A, 0x08, 0x00);
- else
- rtsx_write_register(chip, 0xFE70, 0x80, 0x00);
- }
-
- rtsx_write_register(chip, SDIO_CTRL, SDIO_CD_CTRL, 0);
- chip->sd_io = 0;
- }
-}
-
-void rtsx_power_off_card(struct rtsx_chip *chip)
-{
- if ((chip->card_ready & SD_CARD) || chip->sd_io) {
- sd_cleanup_work(chip);
- sd_power_off_card3v3(chip);
- }
-
- if (chip->card_ready & XD_CARD) {
- xd_cleanup_work(chip);
- xd_power_off_card3v3(chip);
- }
-
- if (chip->card_ready & MS_CARD) {
- ms_cleanup_work(chip);
- ms_power_off_card3v3(chip);
- }
-}
-
-void rtsx_release_cards(struct rtsx_chip *chip)
-{
- chip->int_reg = rtsx_readl(chip, RTSX_BIPR);
-
- if ((chip->card_ready & SD_CARD) || chip->sd_io) {
- if (chip->int_reg & SD_EXIST)
- sd_cleanup_work(chip);
- release_sd_card(chip);
- }
-
- if (chip->card_ready & XD_CARD) {
- if (chip->int_reg & XD_EXIST)
- xd_cleanup_work(chip);
- release_xd_card(chip);
- }
-
- if (chip->card_ready & MS_CARD) {
- if (chip->int_reg & MS_EXIST)
- ms_cleanup_work(chip);
- release_ms_card(chip);
- }
-}
-
-void rtsx_reset_cards(struct rtsx_chip *chip)
-{
- if (!chip->need_reset)
- return;
-
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL);
-
- rtsx_disable_aspm(chip);
-
- if ((chip->need_reset & SD_CARD) && chip->chip_insert_with_sdio)
- clear_bit(SD_NR, &(chip->need_reset));
-
- if (chip->need_reset & XD_CARD) {
- chip->card_exist |= XD_CARD;
-
- if (chip->xd_show_cnt >= MAX_SHOW_CNT)
- do_reset_xd_card(chip);
- else
- chip->xd_show_cnt++;
- }
- if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) {
- if (chip->card_exist & XD_CARD) {
- clear_bit(SD_NR, &(chip->need_reset));
- clear_bit(MS_NR, &(chip->need_reset));
- }
- }
- if (chip->need_reset & SD_CARD) {
- chip->card_exist |= SD_CARD;
-
- if (chip->sd_show_cnt >= MAX_SHOW_CNT) {
- rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH);
- do_reset_sd_card(chip);
- } else {
- chip->sd_show_cnt++;
- }
- }
- if (chip->need_reset & MS_CARD) {
- chip->card_exist |= MS_CARD;
-
- if (chip->ms_show_cnt >= MAX_SHOW_CNT)
- do_reset_ms_card(chip);
- else
- chip->ms_show_cnt++;
- }
-}
-
-void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip)
-{
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL);
-
- if (reset_chip)
- rtsx_reset_chip(chip);
-
- chip->int_reg = rtsx_readl(chip, RTSX_BIPR);
-
- if ((chip->int_reg & SD_EXIST) && (chip->need_reinit & SD_CARD)) {
- release_sdio(chip);
- release_sd_card(chip);
-
- wait_timeout(100);
-
- chip->card_exist |= SD_CARD;
- do_reset_sd_card(chip);
- }
-
- if ((chip->int_reg & XD_EXIST) && (chip->need_reinit & XD_CARD)) {
- release_xd_card(chip);
-
- wait_timeout(100);
-
- chip->card_exist |= XD_CARD;
- do_reset_xd_card(chip);
- }
-
- if ((chip->int_reg & MS_EXIST) && (chip->need_reinit & MS_CARD)) {
- release_ms_card(chip);
-
- wait_timeout(100);
-
- chip->card_exist |= MS_CARD;
- do_reset_ms_card(chip);
- }
-
- chip->need_reinit = 0;
-}
-
-#ifdef DISABLE_CARD_INT
-void card_cd_debounce(struct rtsx_chip *chip, unsigned long *need_reset, unsigned long *need_release)
-{
- u8 release_map = 0, reset_map = 0;
-
- chip->int_reg = rtsx_readl(chip, RTSX_BIPR);
-
- if (chip->card_exist) {
- if (chip->card_exist & XD_CARD) {
- if (!(chip->int_reg & XD_EXIST))
- release_map |= XD_CARD;
- } else if (chip->card_exist & SD_CARD) {
- if (!(chip->int_reg & SD_EXIST))
- release_map |= SD_CARD;
- } else if (chip->card_exist & MS_CARD) {
- if (!(chip->int_reg & MS_EXIST))
- release_map |= MS_CARD;
- }
- } else {
- if (chip->int_reg & XD_EXIST)
- reset_map |= XD_CARD;
- else if (chip->int_reg & SD_EXIST)
- reset_map |= SD_CARD;
- else if (chip->int_reg & MS_EXIST)
- reset_map |= MS_CARD;
- }
-
- if (reset_map) {
- int xd_cnt = 0, sd_cnt = 0, ms_cnt = 0;
- int i;
-
- for (i = 0; i < (DEBOUNCE_CNT); i++) {
- chip->int_reg = rtsx_readl(chip, RTSX_BIPR);
-
- if (chip->int_reg & XD_EXIST)
- xd_cnt++;
- else
- xd_cnt = 0;
-
- if (chip->int_reg & SD_EXIST)
- sd_cnt++;
- else
- sd_cnt = 0;
-
- if (chip->int_reg & MS_EXIST)
- ms_cnt++;
- else
- ms_cnt = 0;
-
- wait_timeout(30);
- }
-
- reset_map = 0;
- if (!(chip->card_exist & XD_CARD) && (xd_cnt > (DEBOUNCE_CNT-1)))
- reset_map |= XD_CARD;
- if (!(chip->card_exist & SD_CARD) && (sd_cnt > (DEBOUNCE_CNT-1)))
- reset_map |= SD_CARD;
- if (!(chip->card_exist & MS_CARD) && (ms_cnt > (DEBOUNCE_CNT-1)))
- reset_map |= MS_CARD;
- }
-
- if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN))
- rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0x00);
-
- if (need_reset)
- *need_reset = reset_map;
- if (need_release)
- *need_release = release_map;
-}
-#endif
-
-void rtsx_init_cards(struct rtsx_chip *chip)
-{
- if (RTSX_TST_DELINK(chip) && (rtsx_get_stat(chip) != RTSX_STAT_SS)) {
- RTSX_DEBUGP("Reset chip in polling thread!\n");
- rtsx_reset_chip(chip);
- RTSX_CLR_DELINK(chip);
- }
-
-#ifdef DISABLE_CARD_INT
- card_cd_debounce(chip, &(chip->need_reset), &(chip->need_release));
-#endif
-
- if (chip->need_release) {
- if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) {
- if (chip->int_reg & XD_EXIST) {
- clear_bit(SD_NR, &(chip->need_release));
- clear_bit(MS_NR, &(chip->need_release));
- }
- }
-
- if (!(chip->card_exist & SD_CARD) && !chip->sd_io)
- clear_bit(SD_NR, &(chip->need_release));
- if (!(chip->card_exist & XD_CARD))
- clear_bit(XD_NR, &(chip->need_release));
- if (!(chip->card_exist & MS_CARD))
- clear_bit(MS_NR, &(chip->need_release));
-
- RTSX_DEBUGP("chip->need_release = 0x%x\n", (unsigned int)(chip->need_release));
-
-#ifdef SUPPORT_OCP
- if (chip->need_release) {
- if (CHECK_PID(chip, 0x5209)) {
- u8 mask = 0, val = 0;
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
- if (chip->ocp_stat & (MS_OC_NOW | MS_OC_EVER)) {
- mask |= MS_OCP_INT_CLR | MS_OC_CLR;
- val |= MS_OCP_INT_CLR | MS_OC_CLR;
- }
- }
- if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
- mask |= SD_OCP_INT_CLR | SD_OC_CLR;
- val |= SD_OCP_INT_CLR | SD_OC_CLR;
- }
- if (mask)
- rtsx_write_register(chip, OCPCTL, mask, val);
- } else {
- if (chip->ocp_stat & (CARD_OC_NOW | CARD_OC_EVER))
- rtsx_write_register(chip, OCPCLR,
- CARD_OC_INT_CLR | CARD_OC_CLR,
- CARD_OC_INT_CLR | CARD_OC_CLR);
- }
- chip->ocp_stat = 0;
- }
-#endif
- if (chip->need_release) {
- rtsx_set_stat(chip, RTSX_STAT_RUN);
- rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL);
- }
-
- if (chip->need_release & SD_CARD) {
- clear_bit(SD_NR, &(chip->need_release));
- chip->card_exist &= ~SD_CARD;
- chip->card_ejected &= ~SD_CARD;
- chip->card_fail &= ~SD_CARD;
- CLR_BIT(chip->lun_mc, chip->card2lun[SD_CARD]);
- chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0;
- rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH);
-
- release_sdio(chip);
- release_sd_card(chip);
- }
-
- if (chip->need_release & XD_CARD) {
- clear_bit(XD_NR, &(chip->need_release));
- chip->card_exist &= ~XD_CARD;
- chip->card_ejected &= ~XD_CARD;
- chip->card_fail &= ~XD_CARD;
- CLR_BIT(chip->lun_mc, chip->card2lun[XD_CARD]);
- chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0;
-
- release_xd_card(chip);
-
- if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN))
- rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0xC0);
- }
-
- if (chip->need_release & MS_CARD) {
- clear_bit(MS_NR, &(chip->need_release));
- chip->card_exist &= ~MS_CARD;
- chip->card_ejected &= ~MS_CARD;
- chip->card_fail &= ~MS_CARD;
- CLR_BIT(chip->lun_mc, chip->card2lun[MS_CARD]);
- chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0;
-
- release_ms_card(chip);
- }
-
- RTSX_DEBUGP("chip->card_exist = 0x%x\n", chip->card_exist);
-
- if (!chip->card_exist)
- turn_off_led(chip, LED_GPIO);
- }
-
- if (chip->need_reset) {
- RTSX_DEBUGP("chip->need_reset = 0x%x\n", (unsigned int)(chip->need_reset));
-
- rtsx_reset_cards(chip);
- }
-
- if (chip->need_reinit) {
- RTSX_DEBUGP("chip->need_reinit = 0x%x\n", (unsigned int)(chip->need_reinit));
-
- rtsx_reinit_cards(chip, 0);
- }
-}
-
-static inline u8 double_depth(u8 depth)
-{
- return ((depth > 1) ? (depth - 1) : depth);
-}
-
-int switch_ssc_clock(struct rtsx_chip *chip, int clk)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
- u8 N = (u8)(clk - 2), min_N, max_N;
- u8 mcu_cnt, div, max_div, ssc_depth, ssc_depth_mask;
- int sd_vpclk_phase_reset = 0;
-
- if (chip->cur_clk == clk)
- return STATUS_SUCCESS;
-
- if (CHECK_PID(chip, 0x5209)) {
- min_N = 80;
- max_N = 208;
- max_div = CLK_DIV_8;
- } else {
- min_N = 60;
- max_N = 120;
- max_div = CLK_DIV_4;
- }
-
- if (CHECK_PID(chip, 0x5209) && (chip->cur_card == SD_CARD)) {
- struct sd_info *sd_card = &(chip->sd_card);
- if (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card))
- sd_vpclk_phase_reset = 1;
- }
-
- RTSX_DEBUGP("Switch SSC clock to %dMHz (cur_clk = %d)\n", clk, chip->cur_clk);
-
- if ((clk <= 2) || (N > max_N))
- TRACE_RET(chip, STATUS_FAIL);
-
- mcu_cnt = (u8)(125/clk + 3);
- if (CHECK_PID(chip, 0x5209)) {
- if (mcu_cnt > 15)
- mcu_cnt = 15;
- } else {
- if (mcu_cnt > 7)
- mcu_cnt = 7;
- }
-
- div = CLK_DIV_1;
- while ((N < min_N) && (div < max_div)) {
- N = (N + 2) * 2 - 2;
- div++;
- }
- RTSX_DEBUGP("N = %d, div = %d\n", N, div);
-
- if (chip->ssc_en) {
- if (CHECK_PID(chip, 0x5209)) {
- if (chip->cur_card == SD_CARD) {
- if (CHK_SD_SDR104(sd_card))
- ssc_depth = chip->ssc_depth_sd_sdr104;
- else if (CHK_SD_SDR50(sd_card))
- ssc_depth = chip->ssc_depth_sd_sdr50;
- else if (CHK_SD_DDR50(sd_card))
- ssc_depth = double_depth(chip->ssc_depth_sd_ddr50);
- else if (CHK_SD_HS(sd_card))
- ssc_depth = double_depth(chip->ssc_depth_sd_hs);
- else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card))
- ssc_depth = double_depth(chip->ssc_depth_mmc_52m);
- else
- ssc_depth = double_depth(chip->ssc_depth_low_speed);
- } else if (chip->cur_card == MS_CARD) {
- if (CHK_MSPRO(ms_card)) {
- if (CHK_HG8BIT(ms_card))
- ssc_depth = double_depth(chip->ssc_depth_ms_hg);
- else
- ssc_depth = double_depth(chip->ssc_depth_ms_4bit);
- } else {
- if (CHK_MS4BIT(ms_card))
- ssc_depth = double_depth(chip->ssc_depth_ms_4bit);
- else
- ssc_depth = double_depth(chip->ssc_depth_low_speed);
- }
- } else {
- ssc_depth = double_depth(chip->ssc_depth_low_speed);
- }
-
- if (ssc_depth) {
- if (div == CLK_DIV_2) {
- if (ssc_depth > 1)
- ssc_depth -= 1;
- else
- ssc_depth = SSC_DEPTH_4M;
-
- } else if (div == CLK_DIV_4) {
- if (ssc_depth > 2)
- ssc_depth -= 2;
- else
- ssc_depth = SSC_DEPTH_4M;
-
- } else if (div == CLK_DIV_8) {
- if (ssc_depth > 3)
- ssc_depth -= 3;
- else
- ssc_depth = SSC_DEPTH_4M;
-
- }
- }
- } else {
- ssc_depth = 0x01;
- N -= 2;
- }
- } else {
- ssc_depth = 0;
- }
-
- if (CHECK_PID(chip, 0x5209))
- ssc_depth_mask = SSC_DEPTH_MASK;
- else
- ssc_depth_mask = 0x03;
-
- RTSX_DEBUGP("ssc_depth = %d\n", ssc_depth);
-
- rtsx_init_cmd(chip);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0xFF, (div << 4) | mcu_cnt);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, ssc_depth_mask, ssc_depth);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB);
- if (sd_vpclk_phase_reset) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET);
- }
-
- retval = rtsx_send_cmd(chip, 0, WAIT_TIME);
- if (retval < 0)
- TRACE_RET(chip, STATUS_ERROR);
-
- udelay(10);
- RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0);
-
- chip->cur_clk = clk;
-
- return STATUS_SUCCESS;
-}
-
-int switch_normal_clock(struct rtsx_chip *chip, int clk)
-{
- u8 sel, div, mcu_cnt;
- int sd_vpclk_phase_reset = 0;
-
- if (chip->cur_clk == clk)
- return STATUS_SUCCESS;
-
- if (CHECK_PID(chip, 0x5209) && (chip->cur_card == SD_CARD)) {
- struct sd_info *sd_card = &(chip->sd_card);
- if (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card))
- sd_vpclk_phase_reset = 1;
- }
-
- switch (clk) {
- case CLK_20:
- RTSX_DEBUGP("Switch clock to 20MHz\n");
- sel = SSC_80;
- div = CLK_DIV_4;
- mcu_cnt = 7;
- break;
-
- case CLK_30:
- RTSX_DEBUGP("Switch clock to 30MHz\n");
- sel = SSC_120;
- div = CLK_DIV_4;
- mcu_cnt = 7;
- break;
-
- case CLK_40:
- RTSX_DEBUGP("Switch clock to 40MHz\n");
- sel = SSC_80;
- div = CLK_DIV_2;
- mcu_cnt = 7;
- break;
-
- case CLK_50:
- RTSX_DEBUGP("Switch clock to 50MHz\n");
- sel = SSC_100;
- div = CLK_DIV_2;
- mcu_cnt = 6;
- break;
-
- case CLK_60:
- RTSX_DEBUGP("Switch clock to 60MHz\n");
- sel = SSC_120;
- div = CLK_DIV_2;
- mcu_cnt = 6;
- break;
-
- case CLK_80:
- RTSX_DEBUGP("Switch clock to 80MHz\n");
- sel = SSC_80;
- div = CLK_DIV_1;
- mcu_cnt = 5;
- break;
-
- case CLK_100:
- RTSX_DEBUGP("Switch clock to 100MHz\n");
- sel = SSC_100;
- div = CLK_DIV_1;
- mcu_cnt = 5;
- break;
-
- case CLK_120:
- RTSX_DEBUGP("Switch clock to 120MHz\n");
- sel = SSC_120;
- div = CLK_DIV_1;
- mcu_cnt = 5;
- break;
-
- case CLK_150:
- RTSX_DEBUGP("Switch clock to 150MHz\n");
- sel = SSC_150;
- div = CLK_DIV_1;
- mcu_cnt = 4;
- break;
-
- case CLK_200:
- RTSX_DEBUGP("Switch clock to 200MHz\n");
- sel = SSC_200;
- div = CLK_DIV_1;
- mcu_cnt = 4;
- break;
-
- default:
- RTSX_DEBUGP("Try to switch to an illegal clock (%d)\n", clk);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- RTSX_WRITE_REG(chip, CLK_CTL, 0xFF, CLK_LOW_FREQ);
- if (sd_vpclk_phase_reset) {
- RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0);
- RTSX_WRITE_REG(chip, SD_VPCLK1_CTL, PHASE_NOT_RESET, 0);
- }
- RTSX_WRITE_REG(chip, CLK_DIV, 0xFF, (div << 4) | mcu_cnt);
- RTSX_WRITE_REG(chip, CLK_SEL, 0xFF, sel);
-
- if (sd_vpclk_phase_reset) {
- udelay(200);
- RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET);
- RTSX_WRITE_REG(chip, SD_VPCLK1_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET);
- udelay(200);
- }
- RTSX_WRITE_REG(chip, CLK_CTL, 0xFF, 0);
-
- chip->cur_clk = clk;
-
- return STATUS_SUCCESS;
-}
-
-void trans_dma_enable(enum dma_data_direction dir, struct rtsx_chip *chip, u32 byte_cnt, u8 pack_size)
-{
- if (pack_size > DMA_1024)
- pack_size = DMA_512;
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, IRQSTAT0, DMA_DONE_INT, DMA_DONE_INT);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC3, 0xFF, (u8)(byte_cnt >> 24));
- rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC2, 0xFF, (u8)(byte_cnt >> 16));
- rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC1, 0xFF, (u8)(byte_cnt >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC0, 0xFF, (u8)byte_cnt);
-
- if (dir == DMA_FROM_DEVICE) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, 0x03 | DMA_PACK_SIZE_MASK,
- DMA_DIR_FROM_CARD | DMA_EN | pack_size);
- } else {
- rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, 0x03 | DMA_PACK_SIZE_MASK,
- DMA_DIR_TO_CARD | DMA_EN | pack_size);
- }
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
-}
-
-int enable_card_clock(struct rtsx_chip *chip, u8 card)
-{
- u8 clk_en = 0;
-
- if (card & XD_CARD)
- clk_en |= XD_CLK_EN;
- if (card & SD_CARD)
- clk_en |= SD_CLK_EN;
- if (card & MS_CARD)
- clk_en |= MS_CLK_EN;
-
- RTSX_WRITE_REG(chip, CARD_CLK_EN, clk_en, clk_en);
-
- return STATUS_SUCCESS;
-}
-
-int disable_card_clock(struct rtsx_chip *chip, u8 card)
-{
- u8 clk_en = 0;
-
- if (card & XD_CARD)
- clk_en |= XD_CLK_EN;
- if (card & SD_CARD)
- clk_en |= SD_CLK_EN;
- if (card & MS_CARD)
- clk_en |= MS_CLK_EN;
-
- RTSX_WRITE_REG(chip, CARD_CLK_EN, clk_en, 0);
-
- return STATUS_SUCCESS;
-}
-
-int card_power_on(struct rtsx_chip *chip, u8 card)
-{
- int retval;
- u8 mask, val1, val2;
-
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) {
- mask = MS_POWER_MASK;
- val1 = MS_PARTIAL_POWER_ON;
- val2 = MS_POWER_ON;
- } else {
- mask = SD_POWER_MASK;
- val1 = SD_PARTIAL_POWER_ON;
- val2 = SD_POWER_ON;
- }
-
- rtsx_init_cmd(chip);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val1);
- if (CHECK_PID(chip, 0x5209) && (card == SD_CARD))
- rtsx_add_cmd(chip, WRITE_REG_CMD, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_SUSPEND);
-
- retval = rtsx_send_cmd(chip, 0, 100);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- udelay(chip->pmos_pwr_on_interval);
-
- rtsx_init_cmd(chip);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val2);
- if (CHECK_PID(chip, 0x5209) && (card == SD_CARD))
- rtsx_add_cmd(chip, WRITE_REG_CMD, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON);
-
- retval = rtsx_send_cmd(chip, 0, 100);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-int card_power_off(struct rtsx_chip *chip, u8 card)
-{
- u8 mask, val;
-
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) {
- mask = MS_POWER_MASK;
- val = MS_POWER_OFF;
- } else {
- mask = SD_POWER_MASK;
- val = SD_POWER_OFF;
- }
- if (CHECK_PID(chip, 0x5209)) {
- mask |= PMOS_STRG_MASK;
- val |= PMOS_STRG_400mA;
- }
-
- RTSX_WRITE_REG(chip, CARD_PWR_CTL, mask, val);
- if (CHECK_PID(chip, 0x5209) && (card == SD_CARD))
- RTSX_WRITE_REG(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF);
-
- return STATUS_SUCCESS;
-}
-
-int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec_cnt)
-{
- int retval;
- unsigned int lun = SCSI_LUN(srb);
- int i;
-
- if (chip->rw_card[lun] == NULL)
- TRACE_RET(chip, STATUS_FAIL);
-
- for (i = 0; i < 3; i++) {
- chip->rw_need_retry = 0;
-
- retval = chip->rw_card[lun](srb, chip, sec_addr, sec_cnt);
- if (retval != STATUS_SUCCESS) {
- if (rtsx_check_chip_exist(chip) != STATUS_SUCCESS) {
- rtsx_release_chip(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (detect_card_cd(chip, chip->cur_card) != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (!chip->rw_need_retry) {
- RTSX_DEBUGP("RW fail, but no need to retry\n");
- break;
- }
- } else {
- chip->rw_need_retry = 0;
- break;
- }
-
- RTSX_DEBUGP("Retry RW, (i = %d)\n", i);
- }
-
- return retval;
-}
-
-int card_share_mode(struct rtsx_chip *chip, int card)
-{
- u8 mask, value;
-
- if (CHECK_PID(chip, 0x5209) || CHECK_PID(chip, 0x5208)) {
- mask = CARD_SHARE_MASK;
- if (card == SD_CARD)
- value = CARD_SHARE_48_SD;
- else if (card == MS_CARD)
- value = CARD_SHARE_48_MS;
- else if (card == XD_CARD)
- value = CARD_SHARE_48_XD;
- else
- TRACE_RET(chip, STATUS_FAIL);
-
- } else if (CHECK_PID(chip, 0x5288)) {
- mask = 0x03;
- if (card == SD_CARD)
- value = CARD_SHARE_BAROSSA_SD;
- else if (card == MS_CARD)
- value = CARD_SHARE_BAROSSA_MS;
- else if (card == XD_CARD)
- value = CARD_SHARE_BAROSSA_XD;
- else
- TRACE_RET(chip, STATUS_FAIL);
-
- } else {
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- RTSX_WRITE_REG(chip, CARD_SHARE_MODE, mask, value);
-
- return STATUS_SUCCESS;
-}
-
-
-int select_card(struct rtsx_chip *chip, int card)
-{
- int retval;
-
- if (chip->cur_card != card) {
- u8 mod;
-
- if (card == SD_CARD)
- mod = SD_MOD_SEL;
- else if (card == MS_CARD)
- mod = MS_MOD_SEL;
- else if (card == XD_CARD)
- mod = XD_MOD_SEL;
- else if (card == SPI_CARD)
- mod = SPI_MOD_SEL;
- else
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, CARD_SELECT, 0x07, mod);
- chip->cur_card = card;
-
- retval = card_share_mode(chip, card);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-void toggle_gpio(struct rtsx_chip *chip, u8 gpio)
-{
- u8 temp_reg;
-
- rtsx_read_register(chip, CARD_GPIO, &temp_reg);
- temp_reg ^= (0x01 << gpio);
- rtsx_write_register(chip, CARD_GPIO, 0xFF, temp_reg);
-}
-
-void turn_on_led(struct rtsx_chip *chip, u8 gpio)
-{
- if (CHECK_PID(chip, 0x5288))
- rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), (u8)(1 << gpio));
- else
- rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0);
-}
-
-void turn_off_led(struct rtsx_chip *chip, u8 gpio)
-{
- if (CHECK_PID(chip, 0x5288))
- rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0);
- else
- rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), (u8)(1 << gpio));
-}
-
-int detect_card_cd(struct rtsx_chip *chip, int card)
-{
- u32 card_cd, status;
-
- if (card == SD_CARD) {
- card_cd = SD_EXIST;
- } else if (card == MS_CARD) {
- card_cd = MS_EXIST;
- } else if (card == XD_CARD) {
- card_cd = XD_EXIST;
- } else {
- RTSX_DEBUGP("Wrong card type: 0x%x\n", card);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- status = rtsx_readl(chip, RTSX_BIPR);
- if (!(status & card_cd))
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-int check_card_exist(struct rtsx_chip *chip, unsigned int lun)
-{
- if (chip->card_exist & chip->lun2card[lun])
- return 1;
-
- return 0;
-}
-
-int check_card_ready(struct rtsx_chip *chip, unsigned int lun)
-{
- if (chip->card_ready & chip->lun2card[lun])
- return 1;
-
- return 0;
-}
-
-int check_card_wp(struct rtsx_chip *chip, unsigned int lun)
-{
- if (chip->card_wp & chip->lun2card[lun])
- return 1;
-
- return 0;
-}
-
-int check_card_fail(struct rtsx_chip *chip, unsigned int lun)
-{
- if (chip->card_fail & chip->lun2card[lun])
- return 1;
-
- return 0;
-}
-
-int check_card_ejected(struct rtsx_chip *chip, unsigned int lun)
-{
- if (chip->card_ejected & chip->lun2card[lun])
- return 1;
-
- return 0;
-}
-
-u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun)
-{
- if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD)
- return (u8)XD_CARD;
- else if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD)
- return (u8)SD_CARD;
- else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD)
- return (u8)MS_CARD;
-
- return 0;
-}
-
-void eject_card(struct rtsx_chip *chip, unsigned int lun)
-{
- do_remaining_work(chip);
-
- if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) {
- release_sd_card(chip);
- chip->card_ejected |= SD_CARD;
- chip->card_ready &= ~SD_CARD;
- chip->capacity[lun] = 0;
- } else if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) {
- release_xd_card(chip);
- chip->card_ejected |= XD_CARD;
- chip->card_ready &= ~XD_CARD;
- chip->capacity[lun] = 0;
- } else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) {
- release_ms_card(chip);
- chip->card_ejected |= MS_CARD;
- chip->card_ready &= ~MS_CARD;
- chip->capacity[lun] = 0;
- }
-}
diff --git a/drivers/staging/rts_pstor/rtsx_card.h b/drivers/staging/rts_pstor/rtsx_card.h
deleted file mode 100644
index 3f727767620..00000000000
--- a/drivers/staging/rts_pstor/rtsx_card.h
+++ /dev/null
@@ -1,1093 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- * Header file
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#ifndef __REALTEK_RTSX_CARD_H
-#define __REALTEK_RTSX_CARD_H
-
-#include "debug.h"
-#include "rtsx.h"
-#include "rtsx_chip.h"
-#include "rtsx_transport.h"
-#include "sd.h"
-
-#define SSC_POWER_DOWN 0x01
-#define SD_OC_POWER_DOWN 0x02
-#define MS_OC_POWER_DOWN 0x04
-#define ALL_POWER_DOWN 0x07
-#define OC_POWER_DOWN 0x06
-
-#define PMOS_STRG_MASK 0x10
-#define PMOS_STRG_800mA 0x10
-#define PMOS_STRG_400mA 0x00
-
-#define POWER_OFF 0x03
-#define PARTIAL_POWER_ON 0x01
-#define POWER_ON 0x00
-
-#define MS_POWER_OFF 0x0C
-#define MS_PARTIAL_POWER_ON 0x04
-#define MS_POWER_ON 0x00
-#define MS_POWER_MASK 0x0C
-
-#define SD_POWER_OFF 0x03
-#define SD_PARTIAL_POWER_ON 0x01
-#define SD_POWER_ON 0x00
-#define SD_POWER_MASK 0x03
-
-#define XD_OUTPUT_EN 0x02
-#define SD_OUTPUT_EN 0x04
-#define MS_OUTPUT_EN 0x08
-#define SPI_OUTPUT_EN 0x10
-
-#define CLK_LOW_FREQ 0x01
-
-#define CLK_DIV_1 0x01
-#define CLK_DIV_2 0x02
-#define CLK_DIV_4 0x03
-#define CLK_DIV_8 0x04
-
-#define SSC_80 0
-#define SSC_100 1
-#define SSC_120 2
-#define SSC_150 3
-#define SSC_200 4
-
-#define XD_CLK_EN 0x02
-#define SD_CLK_EN 0x04
-#define MS_CLK_EN 0x08
-#define SPI_CLK_EN 0x10
-
-#define XD_MOD_SEL 1
-#define SD_MOD_SEL 2
-#define MS_MOD_SEL 3
-#define SPI_MOD_SEL 4
-
-#define CHANGE_CLK 0x01
-
-#define SD_CRC7_ERR 0x80
-#define SD_CRC16_ERR 0x40
-#define SD_CRC_WRITE_ERR 0x20
-#define SD_CRC_WRITE_ERR_MASK 0x1C
-#define GET_CRC_TIME_OUT 0x02
-#define SD_TUNING_COMPARE_ERR 0x01
-
-#define SD_RSP_80CLK_TIMEOUT 0x01
-
-#define SD_CLK_TOGGLE_EN 0x80
-#define SD_CLK_FORCE_STOP 0x40
-#define SD_DAT3_STATUS 0x10
-#define SD_DAT2_STATUS 0x08
-#define SD_DAT1_STATUS 0x04
-#define SD_DAT0_STATUS 0x02
-#define SD_CMD_STATUS 0x01
-
-#define SD_IO_USING_1V8 0x80
-#define SD_IO_USING_3V3 0x7F
-#define TYPE_A_DRIVING 0x00
-#define TYPE_B_DRIVING 0x01
-#define TYPE_C_DRIVING 0x02
-#define TYPE_D_DRIVING 0x03
-
-#define DDR_FIX_RX_DAT 0x00
-#define DDR_VAR_RX_DAT 0x80
-#define DDR_FIX_RX_DAT_EDGE 0x00
-#define DDR_FIX_RX_DAT_14_DELAY 0x40
-#define DDR_FIX_RX_CMD 0x00
-#define DDR_VAR_RX_CMD 0x20
-#define DDR_FIX_RX_CMD_POS_EDGE 0x00
-#define DDR_FIX_RX_CMD_14_DELAY 0x10
-#define SD20_RX_POS_EDGE 0x00
-#define SD20_RX_14_DELAY 0x08
-#define SD20_RX_SEL_MASK 0x08
-
-#define DDR_FIX_TX_CMD_DAT 0x00
-#define DDR_VAR_TX_CMD_DAT 0x80
-#define DDR_FIX_TX_DAT_14_TSU 0x00
-#define DDR_FIX_TX_DAT_12_TSU 0x40
-#define DDR_FIX_TX_CMD_NEG_EDGE 0x00
-#define DDR_FIX_TX_CMD_14_AHEAD 0x20
-#define SD20_TX_NEG_EDGE 0x00
-#define SD20_TX_14_AHEAD 0x10
-#define SD20_TX_SEL_MASK 0x10
-#define DDR_VAR_SDCLK_POL_SWAP 0x01
-
-#define SD_TRANSFER_START 0x80
-#define SD_TRANSFER_END 0x40
-#define SD_STAT_IDLE 0x20
-#define SD_TRANSFER_ERR 0x10
-#define SD_TM_NORMAL_WRITE 0x00
-#define SD_TM_AUTO_WRITE_3 0x01
-#define SD_TM_AUTO_WRITE_4 0x02
-#define SD_TM_AUTO_READ_3 0x05
-#define SD_TM_AUTO_READ_4 0x06
-#define SD_TM_CMD_RSP 0x08
-#define SD_TM_AUTO_WRITE_1 0x09
-#define SD_TM_AUTO_WRITE_2 0x0A
-#define SD_TM_NORMAL_READ 0x0C
-#define SD_TM_AUTO_READ_1 0x0D
-#define SD_TM_AUTO_READ_2 0x0E
-#define SD_TM_AUTO_TUNING 0x0F
-
-#define PHASE_CHANGE 0x80
-#define PHASE_NOT_RESET 0x40
-
-#define DCMPS_CHANGE 0x80
-#define DCMPS_CHANGE_DONE 0x40
-#define DCMPS_ERROR 0x20
-#define DCMPS_CURRENT_PHASE 0x1F
-
-#define SD_CLK_DIVIDE_0 0x00
-#define SD_CLK_DIVIDE_256 0xC0
-#define SD_CLK_DIVIDE_128 0x80
-#define SD_BUS_WIDTH_1 0x00
-#define SD_BUS_WIDTH_4 0x01
-#define SD_BUS_WIDTH_8 0x02
-#define SD_ASYNC_FIFO_NOT_RST 0x10
-#define SD_20_MODE 0x00
-#define SD_DDR_MODE 0x04
-#define SD_30_MODE 0x08
-
-#define SD_CLK_DIVIDE_MASK 0xC0
-
-#define SD_CMD_IDLE 0x80
-
-#define SD_DATA_IDLE 0x80
-
-#define DCM_RESET 0x08
-#define DCM_LOCKED 0x04
-#define DCM_208M 0x00
-#define DCM_TX 0x01
-#define DCM_RX 0x02
-
-#define DRP_START 0x80
-#define DRP_DONE 0x40
-
-#define DRP_WRITE 0x80
-#define DRP_READ 0x00
-#define DCM_WRITE_ADDRESS_50 0x50
-#define DCM_WRITE_ADDRESS_51 0x51
-#define DCM_READ_ADDRESS_00 0x00
-#define DCM_READ_ADDRESS_51 0x51
-
-#define SD_CALCULATE_CRC7 0x00
-#define SD_NO_CALCULATE_CRC7 0x80
-#define SD_CHECK_CRC16 0x00
-#define SD_NO_CHECK_CRC16 0x40
-#define SD_NO_CHECK_WAIT_CRC_TO 0x20
-#define SD_WAIT_BUSY_END 0x08
-#define SD_NO_WAIT_BUSY_END 0x00
-#define SD_CHECK_CRC7 0x00
-#define SD_NO_CHECK_CRC7 0x04
-#define SD_RSP_LEN_0 0x00
-#define SD_RSP_LEN_6 0x01
-#define SD_RSP_LEN_17 0x02
-#define SD_RSP_TYPE_R0 0x04
-#define SD_RSP_TYPE_R1 0x01
-#define SD_RSP_TYPE_R1b 0x09
-#define SD_RSP_TYPE_R2 0x02
-#define SD_RSP_TYPE_R3 0x05
-#define SD_RSP_TYPE_R4 0x05
-#define SD_RSP_TYPE_R5 0x01
-#define SD_RSP_TYPE_R6 0x01
-#define SD_RSP_TYPE_R7 0x01
-
-#define SD_RSP_80CLK_TIMEOUT_EN 0x01
-
-#define SAMPLE_TIME_RISING 0x00
-#define SAMPLE_TIME_FALLING 0x80
-#define PUSH_TIME_DEFAULT 0x00
-#define PUSH_TIME_ODD 0x40
-#define NO_EXTEND_TOGGLE 0x00
-#define EXTEND_TOGGLE_CHK 0x20
-#define MS_BUS_WIDTH_1 0x00
-#define MS_BUS_WIDTH_4 0x10
-#define MS_BUS_WIDTH_8 0x18
-#define MS_2K_SECTOR_MODE 0x04
-#define MS_512_SECTOR_MODE 0x00
-#define MS_TOGGLE_TIMEOUT_EN 0x00
-#define MS_TOGGLE_TIMEOUT_DISEN 0x01
-#define MS_NO_CHECK_INT 0x02
-
-#define WAIT_INT 0x80
-#define NO_WAIT_INT 0x00
-#define NO_AUTO_READ_INT_REG 0x00
-#define AUTO_READ_INT_REG 0x40
-#define MS_CRC16_ERR 0x20
-#define MS_RDY_TIMEOUT 0x10
-#define MS_INT_CMDNK 0x08
-#define MS_INT_BREQ 0x04
-#define MS_INT_ERR 0x02
-#define MS_INT_CED 0x01
-
-#define MS_TRANSFER_START 0x80
-#define MS_TRANSFER_END 0x40
-#define MS_TRANSFER_ERR 0x20
-#define MS_BS_STATE 0x10
-#define MS_TM_READ_BYTES 0x00
-#define MS_TM_NORMAL_READ 0x01
-#define MS_TM_WRITE_BYTES 0x04
-#define MS_TM_NORMAL_WRITE 0x05
-#define MS_TM_AUTO_READ 0x08
-#define MS_TM_AUTO_WRITE 0x0C
-
-#define CARD_SHARE_MASK 0x0F
-#define CARD_SHARE_MULTI_LUN 0x00
-#define CARD_SHARE_NORMAL 0x00
-#define CARD_SHARE_48_XD 0x02
-#define CARD_SHARE_48_SD 0x04
-#define CARD_SHARE_48_MS 0x08
-#define CARD_SHARE_BAROSSA_XD 0x00
-#define CARD_SHARE_BAROSSA_SD 0x01
-#define CARD_SHARE_BAROSSA_MS 0x02
-
-#define MS_DRIVE_8 0x00
-#define MS_DRIVE_4 0x40
-#define MS_DRIVE_12 0x80
-#define SD_DRIVE_8 0x00
-#define SD_DRIVE_4 0x10
-#define SD_DRIVE_12 0x20
-#define XD_DRIVE_8 0x00
-#define XD_DRIVE_4 0x04
-#define XD_DRIVE_12 0x08
-
-#define SPI_STOP 0x01
-#define XD_STOP 0x02
-#define SD_STOP 0x04
-#define MS_STOP 0x08
-#define SPI_CLR_ERR 0x10
-#define XD_CLR_ERR 0x20
-#define SD_CLR_ERR 0x40
-#define MS_CLR_ERR 0x80
-
-#define CRC_FIX_CLK (0x00 << 0)
-#define CRC_VAR_CLK0 (0x01 << 0)
-#define CRC_VAR_CLK1 (0x02 << 0)
-#define SD30_FIX_CLK (0x00 << 2)
-#define SD30_VAR_CLK0 (0x01 << 2)
-#define SD30_VAR_CLK1 (0x02 << 2)
-#define SAMPLE_FIX_CLK (0x00 << 4)
-#define SAMPLE_VAR_CLK0 (0x01 << 4)
-#define SAMPLE_VAR_CLK1 (0x02 << 4)
-
-#define SDIO_VER_20 0x80
-#define SDIO_VER_10 0x00
-#define SDIO_VER_CHG 0x40
-#define SDIO_BUS_AUTO_SWITCH 0x10
-
-#define PINGPONG_BUFFER 0x01
-#define RING_BUFFER 0x00
-
-#define RB_FLUSH 0x80
-
-#define DMA_DONE_INT_EN 0x80
-#define SUSPEND_INT_EN 0x40
-#define LINK_RDY_INT_EN 0x20
-#define LINK_DOWN_INT_EN 0x10
-
-#define DMA_DONE_INT 0x80
-#define SUSPEND_INT 0x40
-#define LINK_RDY_INT 0x20
-#define LINK_DOWN_INT 0x10
-
-#define MRD_ERR_INT_EN 0x40
-#define MWR_ERR_INT_EN 0x20
-#define SCSI_CMD_INT_EN 0x10
-#define TLP_RCV_INT_EN 0x08
-#define TLP_TRSMT_INT_EN 0x04
-#define MRD_COMPLETE_INT_EN 0x02
-#define MWR_COMPLETE_INT_EN 0x01
-
-#define MRD_ERR_INT 0x40
-#define MWR_ERR_INT 0x20
-#define SCSI_CMD_INT 0x10
-#define TLP_RX_INT 0x08
-#define TLP_TX_INT 0x04
-#define MRD_COMPLETE_INT 0x02
-#define MWR_COMPLETE_INT 0x01
-
-#define MSG_RX_INT_EN 0x08
-#define MRD_RX_INT_EN 0x04
-#define MWR_RX_INT_EN 0x02
-#define CPLD_RX_INT_EN 0x01
-
-#define MSG_RX_INT 0x08
-#define MRD_RX_INT 0x04
-#define MWR_RX_INT 0x02
-#define CPLD_RX_INT 0x01
-
-#define MSG_TX_INT_EN 0x08
-#define MRD_TX_INT_EN 0x04
-#define MWR_TX_INT_EN 0x02
-#define CPLD_TX_INT_EN 0x01
-
-#define MSG_TX_INT 0x08
-#define MRD_TX_INT 0x04
-#define MWR_TX_INT 0x02
-#define CPLD_TX_INT 0x01
-
-#define DMA_RST 0x80
-#define DMA_BUSY 0x04
-#define DMA_DIR_TO_CARD 0x00
-#define DMA_DIR_FROM_CARD 0x02
-#define DMA_EN 0x01
-#define DMA_128 (0 << 4)
-#define DMA_256 (1 << 4)
-#define DMA_512 (2 << 4)
-#define DMA_1024 (3 << 4)
-#define DMA_PACK_SIZE_MASK 0x30
-
-#define XD_PWR_OFF_DELAY0 0x00
-#define XD_PWR_OFF_DELAY1 0x02
-#define XD_PWR_OFF_DELAY2 0x04
-#define XD_PWR_OFF_DELAY3 0x06
-#define XD_AUTO_PWR_OFF_EN 0xF7
-#define XD_NO_AUTO_PWR_OFF 0x08
-
-#define XD_TIME_RWN_1 0x00
-#define XD_TIME_RWN_STEP 0x20
-#define XD_TIME_RW_1 0x00
-#define XD_TIME_RW_STEP 0x04
-#define XD_TIME_SETUP_1 0x00
-#define XD_TIME_SETUP_STEP 0x01
-
-#define XD_ECC2_UNCORRECTABLE 0x80
-#define XD_ECC2_ERROR 0x40
-#define XD_ECC1_UNCORRECTABLE 0x20
-#define XD_ECC1_ERROR 0x10
-#define XD_RDY 0x04
-#define XD_CE_EN 0xFD
-#define XD_CE_DISEN 0x02
-#define XD_WP_EN 0xFE
-#define XD_WP_DISEN 0x01
-
-#define XD_TRANSFER_START 0x80
-#define XD_TRANSFER_END 0x40
-#define XD_PPB_EMPTY 0x20
-#define XD_RESET 0x00
-#define XD_ERASE 0x01
-#define XD_READ_STATUS 0x02
-#define XD_READ_ID 0x03
-#define XD_READ_REDUNDANT 0x04
-#define XD_READ_PAGES 0x05
-#define XD_SET_CMD 0x06
-#define XD_NORMAL_READ 0x07
-#define XD_WRITE_PAGES 0x08
-#define XD_NORMAL_WRITE 0x09
-#define XD_WRITE_REDUNDANT 0x0A
-#define XD_SET_ADDR 0x0B
-
-#define XD_PPB_TO_SIE 0x80
-#define XD_TO_PPB_ONLY 0x00
-#define XD_BA_TRANSFORM 0x40
-#define XD_BA_NO_TRANSFORM 0x00
-#define XD_NO_CALC_ECC 0x20
-#define XD_CALC_ECC 0x00
-#define XD_IGNORE_ECC 0x10
-#define XD_CHECK_ECC 0x00
-#define XD_DIRECT_TO_RB 0x08
-#define XD_ADDR_LENGTH_0 0x00
-#define XD_ADDR_LENGTH_1 0x01
-#define XD_ADDR_LENGTH_2 0x02
-#define XD_ADDR_LENGTH_3 0x03
-#define XD_ADDR_LENGTH_4 0x04
-
-#define XD_GPG 0xFF
-#define XD_BPG 0x00
-
-#define XD_GBLK 0xFF
-#define XD_LATER_BBLK 0xF0
-
-#define XD_ECC2_ALL1 0x80
-#define XD_ECC1_ALL1 0x40
-#define XD_BA2_ALL0 0x20
-#define XD_BA1_ALL0 0x10
-#define XD_BA1_BA2_EQL 0x04
-#define XD_BA2_VALID 0x02
-#define XD_BA1_VALID 0x01
-
-#define XD_PGSTS_ZEROBIT_OVER4 0x00
-#define XD_PGSTS_NOT_FF 0x02
-#define XD_AUTO_CHK_DATA_STATUS 0x01
-
-#define RSTB_MODE_DETECT 0x80
-#define MODE_OUT_VLD 0x40
-#define MODE_OUT_0_NONE 0x00
-#define MODE_OUT_10_NONE 0x04
-#define MODE_OUT_10_47 0x05
-#define MODE_OUT_10_180 0x06
-#define MODE_OUT_10_680 0x07
-#define MODE_OUT_16_NONE 0x08
-#define MODE_OUT_16_47 0x09
-#define MODE_OUT_16_180 0x0A
-#define MODE_OUT_16_680 0x0B
-#define MODE_OUT_NONE_NONE 0x0C
-#define MODE_OUT_NONE_47 0x0D
-#define MODE_OUT_NONE_180 0x0E
-#define MODE_OUT_NONE_680 0x0F
-
-#define CARD_OC_INT_EN 0x20
-#define CARD_DETECT_EN 0x08
-
-#define MS_DETECT_EN 0x80
-#define MS_OCP_INT_EN 0x40
-#define MS_OCP_INT_CLR 0x20
-#define MS_OC_CLR 0x10
-#define SD_DETECT_EN 0x08
-#define SD_OCP_INT_EN 0x04
-#define SD_OCP_INT_CLR 0x02
-#define SD_OC_CLR 0x01
-
-#define CARD_OCP_DETECT 0x80
-#define CARD_OC_NOW 0x08
-#define CARD_OC_EVER 0x04
-
-#define MS_OCP_DETECT 0x80
-#define MS_OC_NOW 0x40
-#define MS_OC_EVER 0x20
-#define SD_OCP_DETECT 0x08
-#define SD_OC_NOW 0x04
-#define SD_OC_EVER 0x02
-
-#define CARD_OC_INT_CLR 0x08
-#define CARD_OC_CLR 0x02
-
-#define SD_OCP_GLITCH_MASK 0x07
-#define SD_OCP_GLITCH_6_4 0x00
-#define SD_OCP_GLITCH_64 0x01
-#define SD_OCP_GLITCH_640 0x02
-#define SD_OCP_GLITCH_1000 0x03
-#define SD_OCP_GLITCH_2000 0x04
-#define SD_OCP_GLITCH_4000 0x05
-#define SD_OCP_GLITCH_8000 0x06
-#define SD_OCP_GLITCH_10000 0x07
-
-#define MS_OCP_GLITCH_MASK 0x70
-#define MS_OCP_GLITCH_6_4 (0x00 << 4)
-#define MS_OCP_GLITCH_64 (0x01 << 4)
-#define MS_OCP_GLITCH_640 (0x02 << 4)
-#define MS_OCP_GLITCH_1000 (0x03 << 4)
-#define MS_OCP_GLITCH_2000 (0x04 << 4)
-#define MS_OCP_GLITCH_4000 (0x05 << 4)
-#define MS_OCP_GLITCH_8000 (0x06 << 4)
-#define MS_OCP_GLITCH_10000 (0x07 << 4)
-
-#define OCP_TIME_60 0x00
-#define OCP_TIME_100 (0x01 << 3)
-#define OCP_TIME_200 (0x02 << 3)
-#define OCP_TIME_400 (0x03 << 3)
-#define OCP_TIME_600 (0x04 << 3)
-#define OCP_TIME_800 (0x05 << 3)
-#define OCP_TIME_1100 (0x06 << 3)
-#define OCP_TIME_MASK 0x38
-
-#define MS_OCP_TIME_60 0x00
-#define MS_OCP_TIME_100 (0x01 << 4)
-#define MS_OCP_TIME_200 (0x02 << 4)
-#define MS_OCP_TIME_400 (0x03 << 4)
-#define MS_OCP_TIME_600 (0x04 << 4)
-#define MS_OCP_TIME_800 (0x05 << 4)
-#define MS_OCP_TIME_1100 (0x06 << 4)
-#define MS_OCP_TIME_MASK 0x70
-
-#define SD_OCP_TIME_60 0x00
-#define SD_OCP_TIME_100 0x01
-#define SD_OCP_TIME_200 0x02
-#define SD_OCP_TIME_400 0x03
-#define SD_OCP_TIME_600 0x04
-#define SD_OCP_TIME_800 0x05
-#define SD_OCP_TIME_1100 0x06
-#define SD_OCP_TIME_MASK 0x07
-
-#define OCP_THD_315_417 0x00
-#define OCP_THD_283_783 (0x01 << 6)
-#define OCP_THD_244_946 (0x02 << 6)
-#define OCP_THD_191_1080 (0x03 << 6)
-#define OCP_THD_MASK 0xC0
-
-#define MS_OCP_THD_450 0x00
-#define MS_OCP_THD_550 (0x01 << 4)
-#define MS_OCP_THD_650 (0x02 << 4)
-#define MS_OCP_THD_750 (0x03 << 4)
-#define MS_OCP_THD_850 (0x04 << 4)
-#define MS_OCP_THD_950 (0x05 << 4)
-#define MS_OCP_THD_1050 (0x06 << 4)
-#define MS_OCP_THD_1150 (0x07 << 4)
-#define MS_OCP_THD_MASK 0x70
-
-#define SD_OCP_THD_450 0x00
-#define SD_OCP_THD_550 0x01
-#define SD_OCP_THD_650 0x02
-#define SD_OCP_THD_750 0x03
-#define SD_OCP_THD_850 0x04
-#define SD_OCP_THD_950 0x05
-#define SD_OCP_THD_1050 0x06
-#define SD_OCP_THD_1150 0x07
-#define SD_OCP_THD_MASK 0x07
-
-#define FPGA_MS_PULL_CTL_EN 0xEF
-#define FPGA_SD_PULL_CTL_EN 0xF7
-#define FPGA_XD_PULL_CTL_EN1 0xFE
-#define FPGA_XD_PULL_CTL_EN2 0xFD
-#define FPGA_XD_PULL_CTL_EN3 0xFB
-
-#define FPGA_MS_PULL_CTL_BIT 0x10
-#define FPGA_SD_PULL_CTL_BIT 0x08
-
-#define BLINK_EN 0x08
-#define LED_GPIO0 (0 << 4)
-#define LED_GPIO1 (1 << 4)
-#define LED_GPIO2 (2 << 4)
-
-#define SDIO_BUS_CTRL 0x01
-#define SDIO_CD_CTRL 0x02
-
-#define SSC_RSTB 0x80
-#define SSC_8X_EN 0x40
-#define SSC_FIX_FRAC 0x20
-#define SSC_SEL_1M 0x00
-#define SSC_SEL_2M 0x08
-#define SSC_SEL_4M 0x10
-#define SSC_SEL_8M 0x18
-
-#define SSC_DEPTH_MASK 0x07
-#define SSC_DEPTH_DISALBE 0x00
-#define SSC_DEPTH_4M 0x01
-#define SSC_DEPTH_2M 0x02
-#define SSC_DEPTH_1M 0x03
-#define SSC_DEPTH_512K 0x04
-#define SSC_DEPTH_256K 0x05
-#define SSC_DEPTH_128K 0x06
-#define SSC_DEPTH_64K 0x07
-
-#define XD_D3_NP 0x00
-#define XD_D3_PD (0x01 << 6)
-#define XD_D3_PU (0x02 << 6)
-#define XD_D2_NP 0x00
-#define XD_D2_PD (0x01 << 4)
-#define XD_D2_PU (0x02 << 4)
-#define XD_D1_NP 0x00
-#define XD_D1_PD (0x01 << 2)
-#define XD_D1_PU (0x02 << 2)
-#define XD_D0_NP 0x00
-#define XD_D0_PD 0x01
-#define XD_D0_PU 0x02
-
-#define SD_D7_NP 0x00
-#define SD_D7_PD (0x01 << 4)
-#define SD_DAT7_PU (0x02 << 4)
-#define SD_CLK_NP 0x00
-#define SD_CLK_PD (0x01 << 2)
-#define SD_CLK_PU (0x02 << 2)
-#define SD_D5_NP 0x00
-#define SD_D5_PD 0x01
-#define SD_D5_PU 0x02
-
-#define MS_D1_NP 0x00
-#define MS_D1_PD (0x01 << 6)
-#define MS_D1_PU (0x02 << 6)
-#define MS_D2_NP 0x00
-#define MS_D2_PD (0x01 << 4)
-#define MS_D2_PU (0x02 << 4)
-#define MS_CLK_NP 0x00
-#define MS_CLK_PD (0x01 << 2)
-#define MS_CLK_PU (0x02 << 2)
-#define MS_D6_NP 0x00
-#define MS_D6_PD 0x01
-#define MS_D6_PU 0x02
-
-#define XD_D7_NP 0x00
-#define XD_D7_PD (0x01 << 6)
-#define XD_D7_PU (0x02 << 6)
-#define XD_D6_NP 0x00
-#define XD_D6_PD (0x01 << 4)
-#define XD_D6_PU (0x02 << 4)
-#define XD_D5_NP 0x00
-#define XD_D5_PD (0x01 << 2)
-#define XD_D5_PU (0x02 << 2)
-#define XD_D4_NP 0x00
-#define XD_D4_PD 0x01
-#define XD_D4_PU 0x02
-
-#define SD_D6_NP 0x00
-#define SD_D6_PD (0x01 << 6)
-#define SD_D6_PU (0x02 << 6)
-#define SD_D0_NP 0x00
-#define SD_D0_PD (0x01 << 4)
-#define SD_D0_PU (0x02 << 4)
-#define SD_D1_NP 0x00
-#define SD_D1_PD 0x01
-#define SD_D1_PU 0x02
-
-#define MS_D3_NP 0x00
-#define MS_D3_PD (0x01 << 6)
-#define MS_D3_PU (0x02 << 6)
-#define MS_D0_NP 0x00
-#define MS_D0_PD (0x01 << 4)
-#define MS_D0_PU (0x02 << 4)
-#define MS_BS_NP 0x00
-#define MS_BS_PD (0x01 << 2)
-#define MS_BS_PU (0x02 << 2)
-
-#define XD_WP_NP 0x00
-#define XD_WP_PD (0x01 << 6)
-#define XD_WP_PU (0x02 << 6)
-#define XD_CE_NP 0x00
-#define XD_CE_PD (0x01 << 3)
-#define XD_CE_PU (0x02 << 3)
-#define XD_CLE_NP 0x00
-#define XD_CLE_PD (0x01 << 1)
-#define XD_CLE_PU (0x02 << 1)
-#define XD_CD_PD 0x00
-#define XD_CD_PU 0x01
-
-#define SD_D4_NP 0x00
-#define SD_D4_PD (0x01 << 6)
-#define SD_D4_PU (0x02 << 6)
-
-#define MS_D7_NP 0x00
-#define MS_D7_PD (0x01 << 6)
-#define MS_D7_PU (0x02 << 6)
-
-#define XD_RDY_NP 0x00
-#define XD_RDY_PD (0x01 << 6)
-#define XD_RDY_PU (0x02 << 6)
-#define XD_WE_NP 0x00
-#define XD_WE_PD (0x01 << 4)
-#define XD_WE_PU (0x02 << 4)
-#define XD_RE_NP 0x00
-#define XD_RE_PD (0x01 << 2)
-#define XD_RE_PU (0x02 << 2)
-#define XD_ALE_NP 0x00
-#define XD_ALE_PD 0x01
-#define XD_ALE_PU 0x02
-
-#define SD_D3_NP 0x00
-#define SD_D3_PD (0x01 << 4)
-#define SD_D3_PU (0x02 << 4)
-#define SD_D2_NP 0x00
-#define SD_D2_PD (0x01 << 2)
-#define SD_D2_PU (0x02 << 2)
-
-#define MS_INS_PD 0x00
-#define MS_INS_PU (0x01 << 7)
-#define SD_WP_NP 0x00
-#define SD_WP_PD (0x01 << 5)
-#define SD_WP_PU (0x02 << 5)
-#define SD_CD_PD 0x00
-#define SD_CD_PU (0x01 << 4)
-#define SD_CMD_NP 0x00
-#define SD_CMD_PD (0x01 << 2)
-#define SD_CMD_PU (0x02 << 2)
-
-#define MS_D5_NP 0x00
-#define MS_D5_PD (0x01 << 2)
-#define MS_D5_PU (0x02 << 2)
-#define MS_D4_NP 0x00
-#define MS_D4_PD 0x01
-#define MS_D4_PU 0x02
-
-#define FORCE_PM_CLOCK 0x10
-#define EN_CLOCK_PM 0x01
-
-#define HOST_ENTER_S3 0x02
-#define HOST_ENTER_S1 0x01
-
-#define AUX_PWR_DETECTED 0x01
-
-#define PHY_DEBUG_MODE 0x01
-
-#define SPI_COMMAND_BIT_8 0xE0
-#define SPI_ADDRESS_BIT_24 0x17
-#define SPI_ADDRESS_BIT_32 0x1F
-
-#define SPI_TRANSFER0_START 0x80
-#define SPI_TRANSFER0_END 0x40
-#define SPI_C_MODE0 0x00
-#define SPI_CA_MODE0 0x01
-#define SPI_CDO_MODE0 0x02
-#define SPI_CDI_MODE0 0x03
-#define SPI_CADO_MODE0 0x04
-#define SPI_CADI_MODE0 0x05
-#define SPI_POLLING_MODE0 0x06
-
-#define SPI_TRANSFER1_START 0x80
-#define SPI_TRANSFER1_END 0x40
-#define SPI_DO_MODE1 0x00
-#define SPI_DI_MODE1 0x01
-
-#define CS_POLARITY_HIGH 0x40
-#define CS_POLARITY_LOW 0x00
-#define DTO_MSB_FIRST 0x00
-#define DTO_LSB_FIRST 0x20
-#define SPI_MASTER 0x00
-#define SPI_SLAVE 0x10
-#define SPI_MODE0 0x00
-#define SPI_MODE1 0x04
-#define SPI_MODE2 0x08
-#define SPI_MODE3 0x0C
-#define SPI_MANUAL 0x00
-#define SPI_HALF_AUTO 0x01
-#define SPI_AUTO 0x02
-#define SPI_EEPROM_AUTO 0x03
-
-#define EDO_TIMING_MASK 0x03
-#define SAMPLE_RISING 0x00
-#define SAMPLE_DELAY_HALF 0x01
-#define SAMPLE_DELAY_ONE 0x02
-#define SAPMLE_DELAY_ONE_HALF 0x03
-#define TCS_MASK 0x0C
-
-#define NOT_BYPASS_SD 0x02
-#define DISABLE_SDIO_FUNC 0x04
-#define SELECT_1LUN 0x08
-
-#define PWR_GATE_EN 0x01
-#define LDO3318_PWR_MASK 0x06
-#define LDO_ON 0x00
-#define LDO_SUSPEND 0x04
-#define LDO_OFF 0x06
-
-#define SD_CFG1 0xFDA0
-#define SD_CFG2 0xFDA1
-#define SD_CFG3 0xFDA2
-#define SD_STAT1 0xFDA3
-#define SD_STAT2 0xFDA4
-#define SD_BUS_STAT 0xFDA5
-#define SD_PAD_CTL 0xFDA6
-#define SD_SAMPLE_POINT_CTL 0xFDA7
-#define SD_PUSH_POINT_CTL 0xFDA8
-#define SD_CMD0 0xFDA9
-#define SD_CMD1 0xFDAA
-#define SD_CMD2 0xFDAB
-#define SD_CMD3 0xFDAC
-#define SD_CMD4 0xFDAD
-#define SD_CMD5 0xFDAE
-#define SD_BYTE_CNT_L 0xFDAF
-#define SD_BYTE_CNT_H 0xFDB0
-#define SD_BLOCK_CNT_L 0xFDB1
-#define SD_BLOCK_CNT_H 0xFDB2
-#define SD_TRANSFER 0xFDB3
-#define SD_CMD_STATE 0xFDB5
-#define SD_DATA_STATE 0xFDB6
-
-#define DCM_DRP_CTL 0xFC23
-#define DCM_DRP_TRIG 0xFC24
-#define DCM_DRP_CFG 0xFC25
-#define DCM_DRP_WR_DATA_L 0xFC26
-#define DCM_DRP_WR_DATA_H 0xFC27
-#define DCM_DRP_RD_DATA_L 0xFC28
-#define DCM_DRP_RD_DATA_H 0xFC29
-#define SD_VPCLK0_CTL 0xFC2A
-#define SD_VPCLK1_CTL 0xFC2B
-#define SD_DCMPS0_CTL 0xFC2C
-#define SD_DCMPS1_CTL 0xFC2D
-#define SD_VPTX_CTL SD_VPCLK0_CTL
-#define SD_VPRX_CTL SD_VPCLK1_CTL
-#define SD_DCMPS_TX_CTL SD_DCMPS0_CTL
-#define SD_DCMPS_RX_CTL SD_DCMPS1_CTL
-
-#define CARD_CLK_SOURCE 0xFC2E
-
-#define CARD_PWR_CTL 0xFD50
-#define CARD_CLK_SWITCH 0xFD51
-#define CARD_SHARE_MODE 0xFD52
-#define CARD_DRIVE_SEL 0xFD53
-#define CARD_STOP 0xFD54
-#define CARD_OE 0xFD55
-#define CARD_AUTO_BLINK 0xFD56
-#define CARD_GPIO_DIR 0xFD57
-#define CARD_GPIO 0xFD58
-
-#define CARD_DATA_SOURCE 0xFD5B
-#define CARD_SELECT 0xFD5C
-#define SD30_DRIVE_SEL 0xFD5E
-
-#define CARD_CLK_EN 0xFD69
-
-#define SDIO_CTRL 0xFD6B
-
-#define FPDCTL 0xFC00
-#define PDINFO 0xFC01
-
-#define CLK_CTL 0xFC02
-#define CLK_DIV 0xFC03
-#define CLK_SEL 0xFC04
-
-#define SSC_DIV_N_0 0xFC0F
-#define SSC_DIV_N_1 0xFC10
-
-#define RCCTL 0xFC14
-
-#define FPGA_PULL_CTL 0xFC1D
-
-#define CARD_PULL_CTL1 0xFD60
-#define CARD_PULL_CTL2 0xFD61
-#define CARD_PULL_CTL3 0xFD62
-#define CARD_PULL_CTL4 0xFD63
-#define CARD_PULL_CTL5 0xFD64
-#define CARD_PULL_CTL6 0xFD65
-
-#define IRQEN0 0xFE20
-#define IRQSTAT0 0xFE21
-#define IRQEN1 0xFE22
-#define IRQSTAT1 0xFE23
-#define TLPRIEN 0xFE24
-#define TLPRISTAT 0xFE25
-#define TLPTIEN 0xFE26
-#define TLPTISTAT 0xFE27
-#define DMATC0 0xFE28
-#define DMATC1 0xFE29
-#define DMATC2 0xFE2A
-#define DMATC3 0xFE2B
-#define DMACTL 0xFE2C
-#define BCTL 0xFE2D
-#define RBBC0 0xFE2E
-#define RBBC1 0xFE2F
-#define RBDAT 0xFE30
-#define RBCTL 0xFE34
-#define CFGADDR0 0xFE35
-#define CFGADDR1 0xFE36
-#define CFGDATA0 0xFE37
-#define CFGDATA1 0xFE38
-#define CFGDATA2 0xFE39
-#define CFGDATA3 0xFE3A
-#define CFGRWCTL 0xFE3B
-#define PHYRWCTL 0xFE3C
-#define PHYDATA0 0xFE3D
-#define PHYDATA1 0xFE3E
-#define PHYADDR 0xFE3F
-#define MSGRXDATA0 0xFE40
-#define MSGRXDATA1 0xFE41
-#define MSGRXDATA2 0xFE42
-#define MSGRXDATA3 0xFE43
-#define MSGTXDATA0 0xFE44
-#define MSGTXDATA1 0xFE45
-#define MSGTXDATA2 0xFE46
-#define MSGTXDATA3 0xFE47
-#define MSGTXCTL 0xFE48
-#define PETXCFG 0xFE49
-
-#define CDRESUMECTL 0xFE52
-#define WAKE_SEL_CTL 0xFE54
-#define PME_FORCE_CTL 0xFE56
-#define ASPM_FORCE_CTL 0xFE57
-#define PM_CLK_FORCE_CTL 0xFE58
-#define PERST_GLITCH_WIDTH 0xFE5C
-#define CHANGE_LINK_STATE 0xFE5B
-#define RESET_LOAD_REG 0xFE5E
-#define HOST_SLEEP_STATE 0xFE60
-#define MAIN_PWR_OFF_CTL 0xFE70 /* RTS5208 */
-#define SDIO_CFG 0xFE70 /* RTS5209 */
-
-#define NFTS_TX_CTRL 0xFE72
-
-#define PWR_GATE_CTRL 0xFE75
-#define PWD_SUSPEND_EN 0xFE76
-
-#define EFUSE_CONTENT 0xFE5F
-
-#define XD_INIT 0xFD10
-#define XD_DTCTL 0xFD11
-#define XD_CTL 0xFD12
-#define XD_TRANSFER 0xFD13
-#define XD_CFG 0xFD14
-#define XD_ADDRESS0 0xFD15
-#define XD_ADDRESS1 0xFD16
-#define XD_ADDRESS2 0xFD17
-#define XD_ADDRESS3 0xFD18
-#define XD_ADDRESS4 0xFD19
-#define XD_DAT 0xFD1A
-#define XD_PAGE_CNT 0xFD1B
-#define XD_PAGE_STATUS 0xFD1C
-#define XD_BLOCK_STATUS 0xFD1D
-#define XD_BLOCK_ADDR1_L 0xFD1E
-#define XD_BLOCK_ADDR1_H 0xFD1F
-#define XD_BLOCK_ADDR2_L 0xFD20
-#define XD_BLOCK_ADDR2_H 0xFD21
-#define XD_BYTE_CNT_L 0xFD22
-#define XD_BYTE_CNT_H 0xFD23
-#define XD_PARITY 0xFD24
-#define XD_ECC_BIT1 0xFD25
-#define XD_ECC_BYTE1 0xFD26
-#define XD_ECC_BIT2 0xFD27
-#define XD_ECC_BYTE2 0xFD28
-#define XD_RESERVED0 0xFD29
-#define XD_RESERVED1 0xFD2A
-#define XD_RESERVED2 0xFD2B
-#define XD_RESERVED3 0xFD2C
-#define XD_CHK_DATA_STATUS 0xFD2D
-#define XD_CATCTL 0xFD2E
-
-#define MS_CFG 0xFD40
-#define MS_TPC 0xFD41
-#define MS_TRANS_CFG 0xFD42
-#define MS_TRANSFER 0xFD43
-#define MS_INT_REG 0xFD44
-#define MS_BYTE_CNT 0xFD45
-#define MS_SECTOR_CNT_L 0xFD46
-#define MS_SECTOR_CNT_H 0xFD47
-#define MS_DBUS_H 0xFD48
-
-#define SSC_CTL1 0xFC11
-#define SSC_CTL2 0xFC12
-
-#define OCPCTL 0xFC15
-#define OCPSTAT 0xFC16
-#define OCPCLR 0xFC17 /* 5208 */
-#define OCPGLITCH 0xFC17 /* 5209 */
-#define OCPPARA1 0xFC18
-#define OCPPARA2 0xFC19
-
-#define EFUSE_OP 0xFC20
-#define EFUSE_CTRL 0xFC21
-#define EFUSE_DATA 0xFC22
-
-#define SPI_COMMAND 0xFD80
-#define SPI_ADDR0 0xFD81
-#define SPI_ADDR1 0xFD82
-#define SPI_ADDR2 0xFD83
-#define SPI_ADDR3 0xFD84
-#define SPI_CA_NUMBER 0xFD85
-#define SPI_LENGTH0 0xFD86
-#define SPI_LENGTH1 0xFD87
-#define SPI_DATA 0xFD88
-#define SPI_DATA_NUMBER 0xFD89
-#define SPI_TRANSFER0 0xFD90
-#define SPI_TRANSFER1 0xFD91
-#define SPI_CONTROL 0xFD92
-#define SPI_SIG 0xFD93
-#define SPI_TCTL 0xFD94
-#define SPI_SLAVE_NUM 0xFD95
-#define SPI_CLK_DIVIDER0 0xFD96
-#define SPI_CLK_DIVIDER1 0xFD97
-
-#define SRAM_BASE 0xE600
-#define RBUF_BASE 0xF400
-#define PPBUF_BASE1 0xF800
-#define PPBUF_BASE2 0xFA00
-#define IMAGE_FLAG_ADDR0 0xCE80
-#define IMAGE_FLAG_ADDR1 0xCE81
-
-#define READ_OP 1
-#define WRITE_OP 2
-
-#define LCTLR 0x80
-
-#define POLLING_WAIT_CNT 1
-#define IDLE_MAX_COUNT 10
-#define SDIO_IDLE_COUNT 10
-
-#define DEBOUNCE_CNT 5
-
-void do_remaining_work(struct rtsx_chip *chip);
-void try_to_switch_sdio_ctrl(struct rtsx_chip *chip);
-void do_reset_sd_card(struct rtsx_chip *chip);
-void do_reset_xd_card(struct rtsx_chip *chip);
-void do_reset_ms_card(struct rtsx_chip *chip);
-void rtsx_power_off_card(struct rtsx_chip *chip);
-void rtsx_release_cards(struct rtsx_chip *chip);
-void rtsx_reset_cards(struct rtsx_chip *chip);
-void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip);
-void rtsx_init_cards(struct rtsx_chip *chip);
-int switch_ssc_clock(struct rtsx_chip *chip, int clk);
-int switch_normal_clock(struct rtsx_chip *chip, int clk);
-int enable_card_clock(struct rtsx_chip *chip, u8 card);
-int disable_card_clock(struct rtsx_chip *chip, u8 card);
-int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec_cnt);
-void trans_dma_enable(enum dma_data_direction dir, struct rtsx_chip *chip, u32 byte_cnt, u8 pack_size);
-void toggle_gpio(struct rtsx_chip *chip, u8 gpio);
-void turn_on_led(struct rtsx_chip *chip, u8 gpio);
-void turn_off_led(struct rtsx_chip *chip, u8 gpio);
-
-int card_share_mode(struct rtsx_chip *chip, int card);
-int select_card(struct rtsx_chip *chip, int card);
-int detect_card_cd(struct rtsx_chip *chip, int card);
-int check_card_exist(struct rtsx_chip *chip, unsigned int lun);
-int check_card_ready(struct rtsx_chip *chip, unsigned int lun);
-int check_card_wp(struct rtsx_chip *chip, unsigned int lun);
-int check_card_fail(struct rtsx_chip *chip, unsigned int lun);
-int check_card_ejected(struct rtsx_chip *chip, unsigned int lun);
-void eject_card(struct rtsx_chip *chip, unsigned int lun);
-u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun);
-
-static inline u32 get_card_size(struct rtsx_chip *chip, unsigned int lun)
-{
-#ifdef SUPPORT_SD_LOCK
- struct sd_info *sd_card = &(chip->sd_card);
-
- if ((get_lun_card(chip, lun) == SD_CARD) && (sd_card->sd_lock_status & SD_LOCKED))
- return 0;
- else
- return chip->capacity[lun];
-#else
- return chip->capacity[lun];
-#endif
-}
-
-static inline int switch_clock(struct rtsx_chip *chip, int clk)
-{
- int retval = 0;
-
- if (chip->asic_code)
- retval = switch_ssc_clock(chip, clk);
- else
- retval = switch_normal_clock(chip, clk);
-
- return retval;
-}
-
-int card_power_on(struct rtsx_chip *chip, u8 card);
-int card_power_off(struct rtsx_chip *chip, u8 card);
-
-static inline int card_power_off_all(struct rtsx_chip *chip)
-{
- RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0x0F, 0x0F);
-
- return STATUS_SUCCESS;
-}
-
-static inline void rtsx_clear_xd_error(struct rtsx_chip *chip)
-{
- rtsx_write_register(chip, CARD_STOP, XD_STOP | XD_CLR_ERR, XD_STOP | XD_CLR_ERR);
-}
-
-static inline void rtsx_clear_sd_error(struct rtsx_chip *chip)
-{
- rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR);
-}
-
-static inline void rtsx_clear_ms_error(struct rtsx_chip *chip)
-{
- rtsx_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR);
-}
-
-static inline void rtsx_clear_spi_error(struct rtsx_chip *chip)
-{
- rtsx_write_register(chip, CARD_STOP, SPI_STOP | SPI_CLR_ERR, SPI_STOP | SPI_CLR_ERR);
-}
-
-#ifdef SUPPORT_SDIO_ASPM
-void dynamic_configure_sdio_aspm(struct rtsx_chip *chip);
-#endif
-
-#endif /* __REALTEK_RTSX_CARD_H */
diff --git a/drivers/staging/rts_pstor/rtsx_chip.c b/drivers/staging/rts_pstor/rtsx_chip.c
deleted file mode 100644
index d8e691b9902..00000000000
--- a/drivers/staging/rts_pstor/rtsx_chip.c
+++ /dev/null
@@ -1,2264 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#include <linux/blkdev.h>
-#include <linux/kthread.h>
-#include <linux/sched.h>
-#include <linux/workqueue.h>
-#include <linux/vmalloc.h>
-
-#include "rtsx.h"
-#include "rtsx_transport.h"
-#include "rtsx_scsi.h"
-#include "rtsx_card.h"
-#include "rtsx_chip.h"
-#include "rtsx_sys.h"
-#include "general.h"
-
-#include "sd.h"
-#include "xd.h"
-#include "ms.h"
-
-static void rtsx_calibration(struct rtsx_chip *chip)
-{
- rtsx_write_phy_register(chip, 0x1B, 0x135E);
- wait_timeout(10);
- rtsx_write_phy_register(chip, 0x00, 0x0280);
- rtsx_write_phy_register(chip, 0x01, 0x7112);
- rtsx_write_phy_register(chip, 0x01, 0x7110);
- rtsx_write_phy_register(chip, 0x01, 0x7112);
- rtsx_write_phy_register(chip, 0x01, 0x7113);
- rtsx_write_phy_register(chip, 0x00, 0x0288);
-}
-
-void rtsx_disable_card_int(struct rtsx_chip *chip)
-{
- u32 reg = rtsx_readl(chip, RTSX_BIER);
-
- reg &= ~(XD_INT_EN | SD_INT_EN | MS_INT_EN);
- rtsx_writel(chip, RTSX_BIER, reg);
-}
-
-void rtsx_enable_card_int(struct rtsx_chip *chip)
-{
- u32 reg = rtsx_readl(chip, RTSX_BIER);
- int i;
-
- for (i = 0; i <= chip->max_lun; i++) {
- if (chip->lun2card[i] & XD_CARD)
- reg |= XD_INT_EN;
- if (chip->lun2card[i] & SD_CARD)
- reg |= SD_INT_EN;
- if (chip->lun2card[i] & MS_CARD)
- reg |= MS_INT_EN;
- }
- if (chip->hw_bypass_sd)
- reg &= ~((u32)SD_INT_EN);
-
- rtsx_writel(chip, RTSX_BIER, reg);
-}
-
-void rtsx_enable_bus_int(struct rtsx_chip *chip)
-{
- u32 reg = 0;
-#ifndef DISABLE_CARD_INT
- int i;
-#endif
-
- reg = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN;
-
-#ifndef DISABLE_CARD_INT
- for (i = 0; i <= chip->max_lun; i++) {
- RTSX_DEBUGP("lun2card[%d] = 0x%02x\n", i, chip->lun2card[i]);
-
- if (chip->lun2card[i] & XD_CARD)
- reg |= XD_INT_EN;
- if (chip->lun2card[i] & SD_CARD)
- reg |= SD_INT_EN;
- if (chip->lun2card[i] & MS_CARD)
- reg |= MS_INT_EN;
- }
- if (chip->hw_bypass_sd)
- reg &= ~((u32)SD_INT_EN);
-#endif
-
- if (chip->ic_version >= IC_VER_C)
- reg |= DELINK_INT_EN;
-#ifdef SUPPORT_OCP
- if (CHECK_PID(chip, 0x5209)) {
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN))
- reg |= MS_OC_INT_EN | SD_OC_INT_EN;
- else
- reg |= SD_OC_INT_EN;
- } else {
- reg |= OC_INT_EN;
- }
-#endif
- if (!chip->adma_mode)
- reg |= DATA_DONE_INT_EN;
-
- /* Enable Bus Interrupt */
- rtsx_writel(chip, RTSX_BIER, reg);
-
- RTSX_DEBUGP("RTSX_BIER: 0x%08x\n", reg);
-}
-
-void rtsx_disable_bus_int(struct rtsx_chip *chip)
-{
- rtsx_writel(chip, RTSX_BIER, 0);
-}
-
-static int rtsx_pre_handle_sdio_old(struct rtsx_chip *chip)
-{
- if (chip->ignore_sd && CHK_SDIO_EXIST(chip)) {
- if (chip->asic_code) {
- RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF,
- MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU);
- } else {
- RTSX_WRITE_REG(chip, FPGA_PULL_CTL, 0xFF, FPGA_SD_PULL_CTL_EN);
- }
- RTSX_WRITE_REG(chip, CARD_SHARE_MODE, 0xFF, CARD_SHARE_48_SD);
-
- /* Enable SDIO internal clock */
- RTSX_WRITE_REG(chip, 0xFF2C, 0x01, 0x01);
-
- RTSX_WRITE_REG(chip, SDIO_CTRL, 0xFF, SDIO_BUS_CTRL | SDIO_CD_CTRL);
-
- chip->sd_int = 1;
- chip->sd_io = 1;
- } else {
- chip->need_reset |= SD_CARD;
- }
-
- return STATUS_SUCCESS;
-}
-
-#ifdef HW_AUTO_SWITCH_SD_BUS
-static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip)
-{
- u8 tmp;
- int sw_bypass_sd = 0;
- int retval;
-
- if (chip->driver_first_load) {
- if (CHECK_PID(chip, 0x5288)) {
- RTSX_READ_REG(chip, 0xFE5A, &tmp);
- if (tmp & 0x08)
- sw_bypass_sd = 1;
- } else if (CHECK_PID(chip, 0x5208)) {
- RTSX_READ_REG(chip, 0xFE70, &tmp);
- if (tmp & 0x80)
- sw_bypass_sd = 1;
- } else if (CHECK_PID(chip, 0x5209)) {
- RTSX_READ_REG(chip, SDIO_CFG, &tmp);
- if (tmp & SDIO_BUS_AUTO_SWITCH)
- sw_bypass_sd = 1;
- }
- } else {
- if (chip->sdio_in_charge)
- sw_bypass_sd = 1;
- }
- RTSX_DEBUGP("chip->sdio_in_charge = %d\n", chip->sdio_in_charge);
- RTSX_DEBUGP("chip->driver_first_load = %d\n", chip->driver_first_load);
- RTSX_DEBUGP("sw_bypass_sd = %d\n", sw_bypass_sd);
-
- if (sw_bypass_sd) {
- u8 cd_toggle_mask = 0;
-
- RTSX_READ_REG(chip, TLPTISTAT, &tmp);
- if (CHECK_PID(chip, 0x5209))
- cd_toggle_mask = 0x10;
- else
- cd_toggle_mask = 0x08;
-
- if (tmp & cd_toggle_mask) {
- /* Disable sdio_bus_auto_switch */
- if (CHECK_PID(chip, 0x5288))
- RTSX_WRITE_REG(chip, 0xFE5A, 0x08, 0x00);
- else if (CHECK_PID(chip, 0x5208))
- RTSX_WRITE_REG(chip, 0xFE70, 0x80, 0x00);
- else
- RTSX_WRITE_REG(chip, SDIO_CFG, SDIO_BUS_AUTO_SWITCH, 0);
-
- RTSX_WRITE_REG(chip, TLPTISTAT, 0xFF, tmp);
-
- chip->need_reset |= SD_CARD;
- } else {
- RTSX_DEBUGP("Chip inserted with SDIO!\n");
-
- if (chip->asic_code) {
- retval = sd_pull_ctl_enable(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_SD_PULL_CTL_BIT | 0x20, 0);
- }
- retval = card_share_mode(chip, SD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- /* Enable sdio_bus_auto_switch */
- if (CHECK_PID(chip, 0x5288)) {
- RTSX_WRITE_REG(chip, 0xFE5A, 0x08, 0x08);
- } else if (CHECK_PID(chip, 0x5208)) {
- RTSX_WRITE_REG(chip, 0xFE70, 0x80, 0x80);
- } else {
- RTSX_WRITE_REG(chip, SDIO_CFG,
- SDIO_BUS_AUTO_SWITCH, SDIO_BUS_AUTO_SWITCH);
- }
- chip->chip_insert_with_sdio = 1;
- chip->sd_io = 1;
- }
- } else {
- if (CHECK_PID(chip, 0x5209))
- RTSX_WRITE_REG(chip, TLPTISTAT, 0x10, 0x10);
- else
- RTSX_WRITE_REG(chip, TLPTISTAT, 0x08, 0x08);
-
- chip->need_reset |= SD_CARD;
- }
-
- return STATUS_SUCCESS;
-}
-#endif
-
-int rtsx_reset_chip(struct rtsx_chip *chip)
-{
- int retval;
-
- rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr);
-
- rtsx_disable_aspm(chip);
-
- if (CHECK_PID(chip, 0x5209) && chip->asic_code) {
- u16 val;
-
- /* optimize PHY */
- retval = rtsx_write_phy_register(chip, 0x00, 0xB966);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = rtsx_write_phy_register(chip, 0x01, 0x713F);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = rtsx_write_phy_register(chip, 0x03, 0xA549);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = rtsx_write_phy_register(chip, 0x06, 0xB235);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = rtsx_write_phy_register(chip, 0x07, 0xEF40);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = rtsx_write_phy_register(chip, 0x1E, 0xF8EB);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = rtsx_write_phy_register(chip, 0x19, 0xFE6C);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- wait_timeout(1);
- retval = rtsx_write_phy_register(chip, 0x0A, 0x05C0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
-
- retval = rtsx_write_cfg_dw(chip, 1, 0x110, 0xFFFF, 0xFFFF);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = rtsx_read_phy_register(chip, 0x08, &val);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_DEBUGP("Read from phy 0x08: 0x%04x\n", val);
-
- if (chip->phy_voltage) {
- chip->phy_voltage &= 0x3F;
- RTSX_DEBUGP("chip->phy_voltage = 0x%x\n", chip->phy_voltage);
- val &= ~0x3F;
- val |= chip->phy_voltage;
- RTSX_DEBUGP("Write to phy 0x08: 0x%04x\n", val);
- retval = rtsx_write_phy_register(chip, 0x08, val);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- } else {
- chip->phy_voltage = (u8)(val & 0x3F);
- RTSX_DEBUGP("Default, chip->phy_voltage = 0x%x\n", chip->phy_voltage);
- }
- }
-
- RTSX_WRITE_REG(chip, HOST_SLEEP_STATE, 0x03, 0x00);
-
- /* Disable card clock */
- RTSX_WRITE_REG(chip, CARD_CLK_EN, 0x1E, 0);
-
-#ifdef SUPPORT_OCP
- /* SSC power on, OCD power on */
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN))
- RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, 0);
- else
- RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, MS_OC_POWER_DOWN);
-
- if (CHECK_PID(chip, 0x5209)) {
- RTSX_WRITE_REG(chip, OCPPARA1, SD_OCP_TIME_MASK | MS_OCP_TIME_MASK,
- SD_OCP_TIME_800 | MS_OCP_TIME_800);
- RTSX_WRITE_REG(chip, OCPPARA2, SD_OCP_THD_MASK | MS_OCP_THD_MASK,
- chip->sd_400mA_ocp_thd | (chip->ms_ocp_thd << 4));
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
- RTSX_WRITE_REG(chip, OCPGLITCH, SD_OCP_GLITCH_MASK | MS_OCP_GLITCH_MASK,
- SD_OCP_GLITCH_10000 | MS_OCP_GLITCH_10000);
- } else {
- RTSX_WRITE_REG(chip, OCPGLITCH, SD_OCP_GLITCH_MASK, SD_OCP_GLITCH_10000);
- }
- RTSX_WRITE_REG(chip, OCPCTL, 0xFF,
- SD_OCP_INT_EN | SD_DETECT_EN | MS_OCP_INT_EN | MS_DETECT_EN);
- } else {
- RTSX_WRITE_REG(chip, OCPPARA1, OCP_TIME_MASK, OCP_TIME_800);
- RTSX_WRITE_REG(chip, OCPPARA2, OCP_THD_MASK, OCP_THD_244_946);
- RTSX_WRITE_REG(chip, OCPCTL, 0xFF, CARD_OC_INT_EN | CARD_DETECT_EN);
- }
-#else
- /* OC power down */
- RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, OC_POWER_DOWN);
-#endif
-
- if (!CHECK_PID(chip, 0x5288))
- RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0xFF, 0x03);
-
- /* Turn off LED */
- RTSX_WRITE_REG(chip, CARD_GPIO, 0xFF, 0x03);
-
- /* Reset delink mode */
- RTSX_WRITE_REG(chip, CHANGE_LINK_STATE, 0x0A, 0);
-
- /* Card driving select */
- RTSX_WRITE_REG(chip, CARD_DRIVE_SEL, 0xFF, chip->card_drive_sel);
- if (CHECK_PID(chip, 0x5209))
- RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07, chip->sd30_drive_sel_3v3);
-
-#ifdef LED_AUTO_BLINK
- RTSX_WRITE_REG(chip, CARD_AUTO_BLINK, 0xFF,
- LED_BLINK_SPEED | BLINK_EN | LED_GPIO0);
-#endif
-
- if (chip->asic_code) {
- /* Enable SSC Clock */
- RTSX_WRITE_REG(chip, SSC_CTL1, 0xFF, SSC_8X_EN | SSC_SEL_4M);
- RTSX_WRITE_REG(chip, SSC_CTL2, 0xFF, 0x12);
- }
-
- /* Disable cd_pwr_save (u_force_rst_core_en=0, u_cd_rst_core_en=0)
- 0xFE5B
- bit[1] u_cd_rst_core_en rst_value = 0
- bit[2] u_force_rst_core_en rst_value = 0
- bit[5] u_mac_phy_rst_n_dbg rst_value = 1
- bit[4] u_non_sticky_rst_n_dbg rst_value = 0
- */
- RTSX_WRITE_REG(chip, CHANGE_LINK_STATE, 0x16, 0x10);
-
- /* Enable ASPM */
- if (chip->aspm_l0s_l1_en) {
- if (chip->dynamic_aspm) {
- if (CHK_SDIO_EXIST(chip)) {
- if (CHECK_PID(chip, 0x5209)) {
- retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF, chip->aspm_l0s_l1_en);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- } else if (CHECK_PID(chip, 0x5288)) {
- retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
- } else {
- if (CHECK_PID(chip, 0x5208))
- RTSX_WRITE_REG(chip, ASPM_FORCE_CTL, 0xFF, 0x3F);
-
- retval = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- chip->aspm_level[0] = chip->aspm_l0s_l1_en;
- if (CHK_SDIO_EXIST(chip)) {
- chip->aspm_level[1] = chip->aspm_l0s_l1_en;
- if (CHECK_PID(chip, 0x5288))
- retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en);
- else
- retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF, chip->aspm_l0s_l1_en);
-
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- }
-
- chip->aspm_enabled = 1;
- }
- } else {
- if (chip->asic_code && CHECK_PID(chip, 0x5208)) {
- retval = rtsx_write_phy_register(chip, 0x07, 0x0129);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
- retval = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = rtsx_write_config_byte(chip, 0x81, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHK_SDIO_EXIST(chip)) {
- if (CHECK_PID(chip, 0x5288))
- retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF00, 0x0100);
- else
- retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF00, 0x0100);
-
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- }
-
- if (CHECK_PID(chip, 0x5209)) {
- retval = rtsx_write_cfg_dw(chip, 0, 0x70C, 0xFF000000, 0x5B);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (CHECK_PID(chip, 0x5288)) {
- if (!CHK_SDIO_EXIST(chip)) {
- retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, 0x0103);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = rtsx_write_cfg_dw(chip, 2, 0x84, 0xFF, 0x03);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- }
- }
-
- RTSX_WRITE_REG(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT);
-
- RTSX_WRITE_REG(chip, PERST_GLITCH_WIDTH, 0xFF, 0x80);
-
- if (CHECK_PID(chip, 0x5209)) {
- RTSX_WRITE_REG(chip, PWD_SUSPEND_EN, 0xFF, 0xFF);
- RTSX_WRITE_REG(chip, PWR_GATE_CTRL, PWR_GATE_EN, PWR_GATE_EN);
- }
-
- /* Enable PCIE interrupt */
- if (chip->asic_code) {
- if (CHECK_PID(chip, 0x5208)) {
- if (chip->phy_debug_mode) {
- RTSX_WRITE_REG(chip, CDRESUMECTL, 0x77, 0);
- rtsx_disable_bus_int(chip);
- } else {
- rtsx_enable_bus_int(chip);
- }
-
- if (chip->ic_version >= IC_VER_D) {
- u16 reg;
- retval = rtsx_read_phy_register(chip, 0x00, &reg);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- reg &= 0xFE7F;
- reg |= 0x80;
- retval = rtsx_write_phy_register(chip, 0x00, reg);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = rtsx_read_phy_register(chip, 0x1C, &reg);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- reg &= 0xFFF7;
- retval = rtsx_write_phy_register(chip, 0x1C, reg);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- }
-
- if (chip->driver_first_load && (chip->ic_version < IC_VER_C))
- rtsx_calibration(chip);
-
- } else {
- rtsx_enable_bus_int(chip);
- }
- } else {
- rtsx_enable_bus_int(chip);
- }
-
-#ifdef HW_INT_WRITE_CLR
- if (CHECK_PID(chip, 0x5209)) {
- /* Set interrupt write clear */
- RTSX_WRITE_REG(chip, NFTS_TX_CTRL, 0x02, 0);
- }
-#endif
-
- chip->need_reset = 0;
-
- chip->int_reg = rtsx_readl(chip, RTSX_BIPR);
-#ifdef HW_INT_WRITE_CLR
- if (CHECK_PID(chip, 0x5209)) {
- /* Clear interrupt flag */
- rtsx_writel(chip, RTSX_BIPR, chip->int_reg);
- }
-#endif
- if (chip->hw_bypass_sd)
- goto NextCard;
- RTSX_DEBUGP("In rtsx_reset_chip, chip->int_reg = 0x%x\n", chip->int_reg);
- if (chip->int_reg & SD_EXIST) {
-#ifdef HW_AUTO_SWITCH_SD_BUS
- if (CHECK_PID(chip, 0x5208) && (chip->ic_version < IC_VER_C))
- retval = rtsx_pre_handle_sdio_old(chip);
- else
- retval = rtsx_pre_handle_sdio_new(chip);
-
- RTSX_DEBUGP("chip->need_reset = 0x%x (rtsx_reset_chip)\n", (unsigned int)(chip->need_reset));
-#else /* HW_AUTO_SWITCH_SD_BUS */
- retval = rtsx_pre_handle_sdio_old(chip);
-#endif /* HW_AUTO_SWITCH_SD_BUS */
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- } else {
- chip->sd_io = 0;
- RTSX_WRITE_REG(chip, SDIO_CTRL, SDIO_BUS_CTRL | SDIO_CD_CTRL, 0);
- }
-
-NextCard:
- if (chip->int_reg & XD_EXIST)
- chip->need_reset |= XD_CARD;
- if (chip->int_reg & MS_EXIST)
- chip->need_reset |= MS_CARD;
- if (chip->int_reg & CARD_EXIST)
- RTSX_WRITE_REG(chip, SSC_CTL1, SSC_RSTB, SSC_RSTB);
-
- RTSX_DEBUGP("In rtsx_init_chip, chip->need_reset = 0x%x\n", (unsigned int)(chip->need_reset));
-
- RTSX_WRITE_REG(chip, RCCTL, 0x01, 0x00);
-
- if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) {
- /* Turn off main power when entering S3/S4 state */
- RTSX_WRITE_REG(chip, MAIN_PWR_OFF_CTL, 0x03, 0x03);
- }
-
- if (chip->remote_wakeup_en && !chip->auto_delink_en) {
- RTSX_WRITE_REG(chip, WAKE_SEL_CTL, 0x07, 0x07);
- if (chip->aux_pwr_exist)
- RTSX_WRITE_REG(chip, PME_FORCE_CTL, 0xFF, 0x33);
- } else {
- RTSX_WRITE_REG(chip, WAKE_SEL_CTL, 0x07, 0x04);
- RTSX_WRITE_REG(chip, PME_FORCE_CTL, 0xFF, 0x30);
- }
-
- if (CHECK_PID(chip, 0x5208) && (chip->ic_version >= IC_VER_D)) {
- RTSX_WRITE_REG(chip, PETXCFG, 0x1C, 0x14);
- } else if (CHECK_PID(chip, 0x5209)) {
- if (chip->force_clkreq_0)
- RTSX_WRITE_REG(chip, PETXCFG, 0x08, 0x08);
- else
- RTSX_WRITE_REG(chip, PETXCFG, 0x08, 0x00);
- }
-
- if (chip->asic_code && CHECK_PID(chip, 0x5208)) {
- retval = rtsx_clr_phy_reg_bit(chip, 0x1C, 2);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (chip->ft2_fast_mode) {
- RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF, MS_PARTIAL_POWER_ON | SD_PARTIAL_POWER_ON);
- udelay(chip->pmos_pwr_on_interval);
- RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF, MS_POWER_ON | SD_POWER_ON);
-
- wait_timeout(200);
- }
-
- /* Reset card */
- rtsx_reset_detected_cards(chip, 0);
-
- chip->driver_first_load = 0;
-
- return STATUS_SUCCESS;
-}
-
-static inline int check_sd_speed_prior(u32 sd_speed_prior)
-{
- int i, fake_para = 0;
-
- for (i = 0; i < 4; i++) {
- u8 tmp = (u8)(sd_speed_prior >> (i*8));
- if ((tmp < 0x01) || (tmp > 0x04)) {
- fake_para = 1;
- break;
- }
- }
-
- return !fake_para;
-}
-
-static inline int check_sd_current_prior(u32 sd_current_prior)
-{
- int i, fake_para = 0;
-
- for (i = 0; i < 4; i++) {
- u8 tmp = (u8)(sd_current_prior >> (i*8));
- if (tmp > 0x03) {
- fake_para = 1;
- break;
- }
- }
-
- return !fake_para;
-}
-
-static int rts5209_init(struct rtsx_chip *chip)
-{
- int retval;
- u32 lval = 0;
- u8 val = 0;
-
- val = rtsx_readb(chip, 0x1C);
- if ((val & 0x10) == 0)
- chip->asic_code = 1;
- else
- chip->asic_code = 0;
-
- chip->ic_version = val & 0x0F;
- chip->phy_debug_mode = 0;
-
- chip->aux_pwr_exist = 0;
-
- chip->ms_power_class_en = 0x03;
-
- retval = rtsx_read_cfg_dw(chip, 0, 0x724, &lval);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_DEBUGP("dw in 0x724: 0x%x\n", lval);
- val = (u8)lval;
- if (!(val & 0x80)) {
- if (val & 0x08)
- chip->lun_mode = DEFAULT_SINGLE;
- else
- chip->lun_mode = SD_MS_2LUN;
-
- if (val & 0x04)
- SET_SDIO_EXIST(chip);
- else
- CLR_SDIO_EXIST(chip);
-
- if (val & 0x02)
- chip->hw_bypass_sd = 0;
- else
- chip->hw_bypass_sd = 1;
-
- } else {
- SET_SDIO_EXIST(chip);
- chip->hw_bypass_sd = 0;
- }
-
- if (chip->use_hw_setting) {
- u8 clk;
-
- chip->aspm_l0s_l1_en = (val >> 5) & 0x03;
-
- val = (u8)(lval >> 8);
-
- clk = (val >> 5) & 0x07;
- if (clk != 0x07)
- chip->asic_sd_sdr50_clk = 98 - clk * 2;
-
- if (val & 0x10)
- chip->auto_delink_en = 1;
- else
- chip->auto_delink_en = 0;
-
- if (chip->ss_en == 2) {
- chip->ss_en = 0;
- } else {
- if (val & 0x08)
- chip->ss_en = 1;
- else
- chip->ss_en = 0;
- }
-
- clk = val & 0x07;
- if (clk != 0x07)
- chip->asic_ms_hg_clk = (59 - clk) * 2;
-
- val = (u8)(lval >> 16);
-
- clk = (val >> 6) & 0x03;
- if (clk != 0x03) {
- chip->asic_sd_hs_clk = (49 - clk * 2) * 2;
- chip->asic_mmc_52m_clk = (49 - clk * 2) * 2;
- }
-
- clk = (val >> 4) & 0x03;
- if (clk != 0x03)
- chip->asic_sd_ddr50_clk = (48 - clk * 2) * 2;
-
- if (val & 0x01)
- chip->sdr104_en = 1;
- else
- chip->sdr104_en = 0;
-
- if (val & 0x02)
- chip->ddr50_en = 1;
- else
- chip->ddr50_en = 0;
-
- if (val & 0x04)
- chip->sdr50_en = 1;
- else
- chip->sdr50_en = 0;
-
-
- val = (u8)(lval >> 24);
-
- clk = (val >> 5) & 0x07;
- if (clk != 0x07)
- chip->asic_sd_sdr104_clk = 206 - clk * 3;
-
- if (val & 0x10)
- chip->power_down_in_ss = 1;
- else
- chip->power_down_in_ss = 0;
-
- chip->ms_power_class_en = val & 0x03;
- }
-
- if (chip->hp_watch_bios_hotplug && chip->auto_delink_en) {
- u8 reg58, reg5b;
-
- retval = rtsx_read_pci_cfg_byte(0x00,
- 0x1C, 0x02, 0x58, &reg58);
- if (retval < 0)
- return STATUS_SUCCESS;
-
- retval = rtsx_read_pci_cfg_byte(0x00,
- 0x1C, 0x02, 0x5B, &reg5b);
- if (retval < 0)
- return STATUS_SUCCESS;
-
- RTSX_DEBUGP("reg58 = 0x%x, reg5b = 0x%x\n", reg58, reg5b);
-
- if ((reg58 == 0x00) && (reg5b == 0x01))
- chip->auto_delink_en = 0;
-
- }
-
- return STATUS_SUCCESS;
-}
-
-static int rts5208_init(struct rtsx_chip *chip)
-{
- int retval;
- u16 reg = 0;
- u8 val = 0;
-
- RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03);
- RTSX_READ_REG(chip, CLK_SEL, &val);
- if (val == 0)
- chip->asic_code = 1;
- else
- chip->asic_code = 0;
-
- if (chip->asic_code) {
- retval = rtsx_read_phy_register(chip, 0x1C, &reg);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_DEBUGP("Value of phy register 0x1C is 0x%x\n", reg);
- chip->ic_version = (reg >> 4) & 0x07;
- if (reg & PHY_DEBUG_MODE)
- chip->phy_debug_mode = 1;
- else
- chip->phy_debug_mode = 0;
-
- } else {
- RTSX_READ_REG(chip, 0xFE80, &val);
- chip->ic_version = val;
- chip->phy_debug_mode = 0;
- }
-
- RTSX_READ_REG(chip, PDINFO, &val);
- RTSX_DEBUGP("PDINFO: 0x%x\n", val);
- if (val & AUX_PWR_DETECTED)
- chip->aux_pwr_exist = 1;
- else
- chip->aux_pwr_exist = 0;
-
- RTSX_READ_REG(chip, 0xFE50, &val);
- if (val & 0x01)
- chip->hw_bypass_sd = 1;
- else
- chip->hw_bypass_sd = 0;
-
- rtsx_read_config_byte(chip, 0x0E, &val);
- if (val & 0x80)
- SET_SDIO_EXIST(chip);
- else
- CLR_SDIO_EXIST(chip);
-
- if (chip->use_hw_setting) {
- RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val);
- if (val & 0x80)
- chip->auto_delink_en = 1;
- else
- chip->auto_delink_en = 0;
- }
-
- return STATUS_SUCCESS;
-}
-
-static int rts5288_init(struct rtsx_chip *chip)
-{
- int retval;
- u8 val = 0, max_func;
- u32 lval = 0;
-
- RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03);
- RTSX_READ_REG(chip, CLK_SEL, &val);
- if (val == 0)
- chip->asic_code = 1;
- else
- chip->asic_code = 0;
-
- chip->ic_version = 0;
- chip->phy_debug_mode = 0;
-
- RTSX_READ_REG(chip, PDINFO, &val);
- RTSX_DEBUGP("PDINFO: 0x%x\n", val);
- if (val & AUX_PWR_DETECTED)
- chip->aux_pwr_exist = 1;
- else
- chip->aux_pwr_exist = 0;
-
- RTSX_READ_REG(chip, CARD_SHARE_MODE, &val);
- RTSX_DEBUGP("CARD_SHARE_MODE: 0x%x\n", val);
- if (val & 0x04)
- chip->baro_pkg = QFN;
- else
- chip->baro_pkg = LQFP;
-
- RTSX_READ_REG(chip, 0xFE5A, &val);
- if (val & 0x10)
- chip->hw_bypass_sd = 1;
- else
- chip->hw_bypass_sd = 0;
-
- retval = rtsx_read_cfg_dw(chip, 0, 0x718, &lval);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- max_func = (u8)((lval >> 29) & 0x07);
- RTSX_DEBUGP("Max function number: %d\n", max_func);
- if (max_func == 0x02)
- SET_SDIO_EXIST(chip);
- else
- CLR_SDIO_EXIST(chip);
-
- if (chip->use_hw_setting) {
- RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val);
- if (val & 0x80)
- chip->auto_delink_en = 1;
- else
- chip->auto_delink_en = 0;
-
- if (CHECK_BARO_PKG(chip, LQFP))
- chip->lun_mode = SD_MS_1LUN;
- else
- chip->lun_mode = DEFAULT_SINGLE;
-
- }
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_init_chip(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- struct xd_info *xd_card = &(chip->xd_card);
- struct ms_info *ms_card = &(chip->ms_card);
- int retval;
- unsigned int i;
-
- RTSX_DEBUGP("Vendor ID: 0x%04x, Product ID: 0x%04x\n",
- chip->vendor_id, chip->product_id);
-
- chip->ic_version = 0;
-
-#ifdef _MSG_TRACE
- chip->msg_idx = 0;
-#endif
-
- memset(xd_card, 0, sizeof(struct xd_info));
- memset(sd_card, 0, sizeof(struct sd_info));
- memset(ms_card, 0, sizeof(struct ms_info));
-
- chip->xd_reset_counter = 0;
- chip->sd_reset_counter = 0;
- chip->ms_reset_counter = 0;
-
- chip->xd_show_cnt = MAX_SHOW_CNT;
- chip->sd_show_cnt = MAX_SHOW_CNT;
- chip->ms_show_cnt = MAX_SHOW_CNT;
-
- chip->sd_io = 0;
- chip->auto_delink_cnt = 0;
- chip->auto_delink_allowed = 1;
- rtsx_set_stat(chip, RTSX_STAT_INIT);
-
- chip->aspm_enabled = 0;
- chip->chip_insert_with_sdio = 0;
- chip->sdio_aspm = 0;
- chip->sdio_idle = 0;
- chip->sdio_counter = 0;
- chip->cur_card = 0;
- chip->phy_debug_mode = 0;
- chip->sdio_func_exist = 0;
- memset(chip->sdio_raw_data, 0, 12);
-
- for (i = 0; i < MAX_ALLOWED_LUN_CNT; i++) {
- set_sense_type(chip, i, SENSE_TYPE_NO_SENSE);
- chip->rw_fail_cnt[i] = 0;
- }
-
- if (!check_sd_speed_prior(chip->sd_speed_prior))
- chip->sd_speed_prior = 0x01040203;
-
- RTSX_DEBUGP("sd_speed_prior = 0x%08x\n", chip->sd_speed_prior);
-
- if (!check_sd_current_prior(chip->sd_current_prior))
- chip->sd_current_prior = 0x00010203;
-
- RTSX_DEBUGP("sd_current_prior = 0x%08x\n", chip->sd_current_prior);
-
- if ((chip->sd_ddr_tx_phase > 31) || (chip->sd_ddr_tx_phase < 0))
- chip->sd_ddr_tx_phase = 0;
-
- if ((chip->mmc_ddr_tx_phase > 31) || (chip->mmc_ddr_tx_phase < 0))
- chip->mmc_ddr_tx_phase = 0;
-
- RTSX_WRITE_REG(chip, FPDCTL, SSC_POWER_DOWN, 0);
- wait_timeout(200);
- RTSX_WRITE_REG(chip, CLK_DIV, 0x07, 0x07);
- RTSX_DEBUGP("chip->use_hw_setting = %d\n", chip->use_hw_setting);
-
- if (CHECK_PID(chip, 0x5209)) {
- retval = rts5209_init(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- } else if (CHECK_PID(chip, 0x5208)) {
- retval = rts5208_init(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- } else if (CHECK_PID(chip, 0x5288)) {
- retval = rts5288_init(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- }
-
- if (chip->ss_en == 2)
- chip->ss_en = 0;
-
- RTSX_DEBUGP("chip->asic_code = %d\n", chip->asic_code);
- RTSX_DEBUGP("chip->ic_version = 0x%x\n", chip->ic_version);
- RTSX_DEBUGP("chip->phy_debug_mode = %d\n", chip->phy_debug_mode);
- RTSX_DEBUGP("chip->aux_pwr_exist = %d\n", chip->aux_pwr_exist);
- RTSX_DEBUGP("chip->sdio_func_exist = %d\n", chip->sdio_func_exist);
- RTSX_DEBUGP("chip->hw_bypass_sd = %d\n", chip->hw_bypass_sd);
- RTSX_DEBUGP("chip->aspm_l0s_l1_en = %d\n", chip->aspm_l0s_l1_en);
- RTSX_DEBUGP("chip->lun_mode = %d\n", chip->lun_mode);
- RTSX_DEBUGP("chip->auto_delink_en = %d\n", chip->auto_delink_en);
- RTSX_DEBUGP("chip->ss_en = %d\n", chip->ss_en);
- RTSX_DEBUGP("chip->baro_pkg = %d\n", chip->baro_pkg);
-
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
- chip->card2lun[SD_CARD] = 0;
- chip->card2lun[MS_CARD] = 1;
- chip->card2lun[XD_CARD] = 0xFF;
- chip->lun2card[0] = SD_CARD;
- chip->lun2card[1] = MS_CARD;
- chip->max_lun = 1;
- SET_SDIO_IGNORED(chip);
- } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) {
- chip->card2lun[SD_CARD] = 0;
- chip->card2lun[MS_CARD] = 0;
- chip->card2lun[XD_CARD] = 0xFF;
- chip->lun2card[0] = SD_CARD | MS_CARD;
- chip->max_lun = 0;
- } else {
- chip->card2lun[XD_CARD] = 0;
- chip->card2lun[SD_CARD] = 0;
- chip->card2lun[MS_CARD] = 0;
- chip->lun2card[0] = XD_CARD | SD_CARD | MS_CARD;
- chip->max_lun = 0;
- }
-
- retval = rtsx_reset_chip(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-void rtsx_release_chip(struct rtsx_chip *chip)
-{
- xd_free_l2p_tbl(chip);
- ms_free_l2p_tbl(chip);
- chip->card_exist = 0;
- chip->card_ready = 0;
-}
-
-#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK)
-static inline void rtsx_blink_led(struct rtsx_chip *chip)
-{
- if (chip->card_exist && chip->blink_led) {
- if (chip->led_toggle_counter < LED_TOGGLE_INTERVAL) {
- chip->led_toggle_counter++;
- } else {
- chip->led_toggle_counter = 0;
- toggle_gpio(chip, LED_GPIO);
- }
- }
-}
-#endif
-
-static void rtsx_monitor_aspm_config(struct rtsx_chip *chip)
-{
- int maybe_support_aspm, reg_changed;
- u32 tmp = 0;
- u8 reg0 = 0, reg1 = 0;
-
- maybe_support_aspm = 0;
- reg_changed = 0;
- rtsx_read_config_byte(chip, LCTLR, &reg0);
- if (chip->aspm_level[0] != reg0) {
- reg_changed = 1;
- chip->aspm_level[0] = reg0;
- }
- if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) {
- rtsx_read_cfg_dw(chip, 1, 0xC0, &tmp);
- reg1 = (u8)tmp;
- if (chip->aspm_level[1] != reg1) {
- reg_changed = 1;
- chip->aspm_level[1] = reg1;
- }
-
- if ((reg0 & 0x03) && (reg1 & 0x03))
- maybe_support_aspm = 1;
-
- } else {
- if (reg0 & 0x03)
- maybe_support_aspm = 1;
-
- }
-
- if (reg_changed) {
- if (maybe_support_aspm)
- chip->aspm_l0s_l1_en = 0x03;
-
- RTSX_DEBUGP("aspm_level[0] = 0x%02x, aspm_level[1] = 0x%02x\n",
- chip->aspm_level[0], chip->aspm_level[1]);
-
- if (chip->aspm_l0s_l1_en) {
- chip->aspm_enabled = 1;
- } else {
- chip->aspm_enabled = 0;
- chip->sdio_aspm = 0;
- }
- rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFF,
- 0x30 | chip->aspm_level[0] | (chip->aspm_level[1] << 2));
- }
-}
-
-void rtsx_polling_func(struct rtsx_chip *chip)
-{
-#ifdef SUPPORT_SD_LOCK
- struct sd_info *sd_card = &(chip->sd_card);
-#endif
- int ss_allowed;
-
- if (rtsx_chk_stat(chip, RTSX_STAT_SUSPEND))
- return;
-
- if (rtsx_chk_stat(chip, RTSX_STAT_DELINK))
- goto Delink_Stage;
-
- if (chip->polling_config) {
- u8 val;
- rtsx_read_config_byte(chip, 0, &val);
- }
-
- if (rtsx_chk_stat(chip, RTSX_STAT_SS))
- return;
-
-#ifdef SUPPORT_OCP
- if (chip->ocp_int) {
- rtsx_read_register(chip, OCPSTAT, &(chip->ocp_stat));
-
- if (CHECK_PID(chip, 0x5209) &&
- CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
- if (chip->ocp_int & SD_OC_INT)
- sd_power_off_card3v3(chip);
- if (chip->ocp_int & MS_OC_INT)
- ms_power_off_card3v3(chip);
- } else {
- if (chip->card_exist & SD_CARD)
- sd_power_off_card3v3(chip);
- else if (chip->card_exist & MS_CARD)
- ms_power_off_card3v3(chip);
- else if (chip->card_exist & XD_CARD)
- xd_power_off_card3v3(chip);
-
- }
-
- chip->ocp_int = 0;
- }
-#endif
-
-#ifdef SUPPORT_SD_LOCK
- if (sd_card->sd_erase_status) {
- if (chip->card_exist & SD_CARD) {
- u8 val;
- if (CHECK_PID(chip, 0x5209)) {
- rtsx_read_register(chip, SD_BUS_STAT, &val);
- if (val & SD_DAT0_STATUS) {
- sd_card->sd_erase_status = SD_NOT_ERASE;
- sd_card->sd_lock_notify = 1;
- chip->need_reinit |= SD_CARD;
- }
- } else {
- rtsx_read_register(chip, 0xFD30, &val);
- if (val & 0x02) {
- sd_card->sd_erase_status = SD_NOT_ERASE;
- sd_card->sd_lock_notify = 1;
- chip->need_reinit |= SD_CARD;
- }
- }
- } else {
- sd_card->sd_erase_status = SD_NOT_ERASE;
- }
- }
-#endif
-
- rtsx_init_cards(chip);
-
- if (chip->ss_en) {
- ss_allowed = 1;
-
- if (CHECK_PID(chip, 0x5288)) {
- ss_allowed = 0;
- } else {
- if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) {
- u32 val;
- rtsx_read_cfg_dw(chip, 1, 0x04, &val);
- if (val & 0x07)
- ss_allowed = 0;
-
- }
- }
- } else {
- ss_allowed = 0;
- }
-
- if (ss_allowed && !chip->sd_io) {
- if (rtsx_get_stat(chip) != RTSX_STAT_IDLE) {
- chip->ss_counter = 0;
- } else {
- if (chip->ss_counter <
- (chip->ss_idle_period / POLLING_INTERVAL)) {
- chip->ss_counter++;
- } else {
- rtsx_exclusive_enter_ss(chip);
- return;
- }
- }
- }
-
- if (CHECK_PID(chip, 0x5208)) {
- rtsx_monitor_aspm_config(chip);
-
-#ifdef SUPPORT_SDIO_ASPM
- if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) &&
- chip->aspm_l0s_l1_en && chip->dynamic_aspm) {
- if (chip->sd_io) {
- dynamic_configure_sdio_aspm(chip);
- } else {
- if (!chip->sdio_aspm) {
- RTSX_DEBUGP("SDIO enter ASPM!\n");
- rtsx_write_register(chip,
- ASPM_FORCE_CTL, 0xFC,
- 0x30 | (chip->aspm_level[1] << 2));
- chip->sdio_aspm = 1;
- }
- }
- }
-#endif
- }
-
- if (chip->idle_counter < IDLE_MAX_COUNT) {
- chip->idle_counter++;
- } else {
- if (rtsx_get_stat(chip) != RTSX_STAT_IDLE) {
- RTSX_DEBUGP("Idle state!\n");
- rtsx_set_stat(chip, RTSX_STAT_IDLE);
-
-#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK)
- chip->led_toggle_counter = 0;
-#endif
- rtsx_force_power_on(chip, SSC_PDCTL);
-
- turn_off_led(chip, LED_GPIO);
-
- if (chip->auto_power_down && !chip->card_ready && !chip->sd_io)
- rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL);
-
- }
- }
-
- switch (rtsx_get_stat(chip)) {
- case RTSX_STAT_RUN:
-#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK)
- rtsx_blink_led(chip);
-#endif
- do_remaining_work(chip);
- break;
-
- case RTSX_STAT_IDLE:
- if (chip->sd_io && !chip->sd_int)
- try_to_switch_sdio_ctrl(chip);
-
- rtsx_enable_aspm(chip);
- break;
-
- default:
- break;
- }
-
-
-#ifdef SUPPORT_OCP
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
-#ifdef CONFIG_RTS_PSTOR_DEBUG
- if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER | MS_OC_NOW | MS_OC_EVER))
- RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat);
-#endif
-
- if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
- if (chip->card_exist & SD_CARD) {
- rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0);
- card_power_off(chip, SD_CARD);
- chip->card_fail |= SD_CARD;
- }
- }
- if (chip->ocp_stat & (MS_OC_NOW | MS_OC_EVER)) {
- if (chip->card_exist & MS_CARD) {
- rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0);
- card_power_off(chip, MS_CARD);
- chip->card_fail |= MS_CARD;
- }
- }
- } else {
- if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
- RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat);
- if (chip->card_exist & SD_CARD) {
- rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0);
- chip->card_fail |= SD_CARD;
- } else if (chip->card_exist & MS_CARD) {
- rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0);
- chip->card_fail |= MS_CARD;
- } else if (chip->card_exist & XD_CARD) {
- rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0);
- chip->card_fail |= XD_CARD;
- }
- card_power_off(chip, SD_CARD);
- }
- }
-#endif
-
-Delink_Stage:
- if (chip->auto_delink_en && chip->auto_delink_allowed &&
- !chip->card_ready && !chip->card_ejected && !chip->sd_io) {
- int enter_L1 = chip->auto_delink_in_L1 && (chip->aspm_l0s_l1_en || chip->ss_en);
- int delink_stage1_cnt = chip->delink_stage1_step;
- int delink_stage2_cnt = delink_stage1_cnt + chip->delink_stage2_step;
- int delink_stage3_cnt = delink_stage2_cnt + chip->delink_stage3_step;
-
- if (chip->auto_delink_cnt <= delink_stage3_cnt) {
- if (chip->auto_delink_cnt == delink_stage1_cnt) {
- rtsx_set_stat(chip, RTSX_STAT_DELINK);
-
- if (chip->asic_code && CHECK_PID(chip, 0x5208))
- rtsx_set_phy_reg_bit(chip, 0x1C, 2);
-
- if (chip->card_exist) {
- RTSX_DEBUGP("False card inserted, do force delink\n");
-
- if (enter_L1)
- rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1);
-
- rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x0A);
-
- if (enter_L1)
- rtsx_enter_L1(chip);
-
- chip->auto_delink_cnt = delink_stage3_cnt + 1;
- } else {
- RTSX_DEBUGP("No card inserted, do delink\n");
-
- if (enter_L1)
- rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1);
-
-#ifdef HW_INT_WRITE_CLR
- if (CHECK_PID(chip, 0x5209)) {
- rtsx_writel(chip, RTSX_BIPR, 0xFFFFFFFF);
- RTSX_DEBUGP("RTSX_BIPR: 0x%x\n", rtsx_readl(chip, RTSX_BIPR));
- }
-#endif
- rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0x02);
-
- if (enter_L1)
- rtsx_enter_L1(chip);
-
- }
- }
-
- if (chip->auto_delink_cnt == delink_stage2_cnt) {
- RTSX_DEBUGP("Try to do force delink\n");
-
- if (enter_L1)
- rtsx_exit_L1(chip);
-
- if (chip->asic_code && CHECK_PID(chip, 0x5208))
- rtsx_set_phy_reg_bit(chip, 0x1C, 2);
-
- rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x0A);
- }
-
- chip->auto_delink_cnt++;
- }
- } else {
- chip->auto_delink_cnt = 0;
- }
-}
-
-void rtsx_undo_delink(struct rtsx_chip *chip)
-{
- chip->auto_delink_allowed = 0;
- rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x00);
-}
-
-/**
- * rtsx_stop_cmd - stop command transfer and DMA transfer
- * @chip: Realtek's card reader chip
- * @card: flash card type
- *
- * Stop command transfer and DMA transfer.
- * This function is called in error handler.
- */
-void rtsx_stop_cmd(struct rtsx_chip *chip, int card)
-{
- int i;
-
- for (i = 0; i <= 8; i++) {
- int addr = RTSX_HCBAR + i * 4;
- u32 reg;
- reg = rtsx_readl(chip, addr);
- RTSX_DEBUGP("BAR (0x%02x): 0x%08x\n", addr, reg);
- }
- rtsx_writel(chip, RTSX_HCBCTLR, STOP_CMD);
- rtsx_writel(chip, RTSX_HDBCTLR, STOP_DMA);
-
- for (i = 0; i < 16; i++) {
- u16 addr = 0xFE20 + (u16)i;
- u8 val;
- rtsx_read_register(chip, addr, &val);
- RTSX_DEBUGP("0x%04X: 0x%02x\n", addr, val);
- }
-
- rtsx_write_register(chip, DMACTL, 0x80, 0x80);
- rtsx_write_register(chip, RBCTL, 0x80, 0x80);
-}
-
-#define MAX_RW_REG_CNT 1024
-
-int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data)
-{
- int i;
- u32 val = 3 << 30;
-
- val |= (u32)(addr & 0x3FFF) << 16;
- val |= (u32)mask << 8;
- val |= (u32)data;
-
- rtsx_writel(chip, RTSX_HAIMR, val);
-
- for (i = 0; i < MAX_RW_REG_CNT; i++) {
- val = rtsx_readl(chip, RTSX_HAIMR);
- if ((val & (1 << 31)) == 0) {
- if (data != (u8)val)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
- }
- }
-
- TRACE_RET(chip, STATUS_TIMEDOUT);
-}
-
-int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data)
-{
- u32 val = 2 << 30;
- int i;
-
- if (data)
- *data = 0;
-
- val |= (u32)(addr & 0x3FFF) << 16;
-
- rtsx_writel(chip, RTSX_HAIMR, val);
-
- for (i = 0; i < MAX_RW_REG_CNT; i++) {
- val = rtsx_readl(chip, RTSX_HAIMR);
- if ((val & (1 << 31)) == 0)
- break;
- }
-
- if (i >= MAX_RW_REG_CNT)
- TRACE_RET(chip, STATUS_TIMEDOUT);
-
- if (data)
- *data = (u8)(val & 0xFF);
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask, u32 val)
-{
- u8 mode = 0, tmp;
- int i;
-
- for (i = 0; i < 4; i++) {
- if (mask & 0xFF) {
- RTSX_WRITE_REG(chip, CFGDATA0 + i,
- 0xFF, (u8)(val & mask & 0xFF));
- mode |= (1 << i);
- }
- mask >>= 8;
- val >>= 8;
- }
-
- if (mode) {
- RTSX_WRITE_REG(chip, CFGADDR0, 0xFF, (u8)addr);
- RTSX_WRITE_REG(chip, CFGADDR1, 0xFF, (u8)(addr >> 8));
-
- RTSX_WRITE_REG(chip, CFGRWCTL, 0xFF,
- 0x80 | mode | ((func_no & 0x03) << 4));
-
- for (i = 0; i < MAX_RW_REG_CNT; i++) {
- RTSX_READ_REG(chip, CFGRWCTL, &tmp);
- if ((tmp & 0x80) == 0)
- break;
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val)
-{
- int i;
- u8 tmp;
- u32 data = 0;
-
- RTSX_WRITE_REG(chip, CFGADDR0, 0xFF, (u8)addr);
- RTSX_WRITE_REG(chip, CFGADDR1, 0xFF, (u8)(addr >> 8));
- RTSX_WRITE_REG(chip, CFGRWCTL, 0xFF, 0x80 | ((func_no & 0x03) << 4));
-
- for (i = 0; i < MAX_RW_REG_CNT; i++) {
- RTSX_READ_REG(chip, CFGRWCTL, &tmp);
- if ((tmp & 0x80) == 0)
- break;
- }
-
- for (i = 0; i < 4; i++) {
- RTSX_READ_REG(chip, CFGDATA0 + i, &tmp);
- data |= (u32)tmp << (i * 8);
- }
-
- if (val)
- *val = data;
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int len)
-{
- u32 *data, *mask;
- u16 offset = addr % 4;
- u16 aligned_addr = addr - offset;
- int dw_len, i, j;
- int retval;
-
- RTSX_DEBUGP("%s\n", __func__);
-
- if (!buf)
- TRACE_RET(chip, STATUS_NOMEM);
-
- if ((len + offset) % 4)
- dw_len = (len + offset) / 4 + 1;
- else
- dw_len = (len + offset) / 4;
-
- RTSX_DEBUGP("dw_len = %d\n", dw_len);
-
- data = vzalloc(dw_len * 4);
- if (!data)
- TRACE_RET(chip, STATUS_NOMEM);
-
- mask = vzalloc(dw_len * 4);
- if (!mask) {
- vfree(data);
- TRACE_RET(chip, STATUS_NOMEM);
- }
-
- j = 0;
- for (i = 0; i < len; i++) {
- mask[j] |= 0xFF << (offset * 8);
- data[j] |= buf[i] << (offset * 8);
- if (++offset == 4) {
- j++;
- offset = 0;
- }
- }
-
- RTSX_DUMP(mask, dw_len * 4);
- RTSX_DUMP(data, dw_len * 4);
-
- for (i = 0; i < dw_len; i++) {
- retval = rtsx_write_cfg_dw(chip, func, aligned_addr + i * 4, mask[i], data[i]);
- if (retval != STATUS_SUCCESS) {
- vfree(data);
- vfree(mask);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- vfree(data);
- vfree(mask);
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int len)
-{
- u32 *data;
- u16 offset = addr % 4;
- u16 aligned_addr = addr - offset;
- int dw_len, i, j;
- int retval;
-
- RTSX_DEBUGP("%s\n", __func__);
-
- if ((len + offset) % 4)
- dw_len = (len + offset) / 4 + 1;
- else
- dw_len = (len + offset) / 4;
-
- RTSX_DEBUGP("dw_len = %d\n", dw_len);
-
- data = (u32 *)vmalloc(dw_len * 4);
- if (!data)
- TRACE_RET(chip, STATUS_NOMEM);
-
- for (i = 0; i < dw_len; i++) {
- retval = rtsx_read_cfg_dw(chip, func, aligned_addr + i * 4, data + i);
- if (retval != STATUS_SUCCESS) {
- vfree(data);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- if (buf) {
- j = 0;
-
- for (i = 0; i < len; i++) {
- buf[i] = (u8)(data[j] >> (offset * 8));
- if (++offset == 4) {
- j++;
- offset = 0;
- }
- }
- }
-
- vfree(data);
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val)
-{
- int i, finished = 0;
- u8 tmp;
-
- RTSX_WRITE_REG(chip, PHYDATA0, 0xFF, (u8)val);
- RTSX_WRITE_REG(chip, PHYDATA1, 0xFF, (u8)(val >> 8));
- RTSX_WRITE_REG(chip, PHYADDR, 0xFF, addr);
- RTSX_WRITE_REG(chip, PHYRWCTL, 0xFF, 0x81);
-
- for (i = 0; i < 100000; i++) {
- RTSX_READ_REG(chip, PHYRWCTL, &tmp);
- if (!(tmp & 0x80)) {
- finished = 1;
- break;
- }
- }
-
- if (!finished)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val)
-{
- int i, finished = 0;
- u16 data = 0;
- u8 tmp;
-
- RTSX_WRITE_REG(chip, PHYADDR, 0xFF, addr);
- RTSX_WRITE_REG(chip, PHYRWCTL, 0xFF, 0x80);
-
- for (i = 0; i < 100000; i++) {
- RTSX_READ_REG(chip, PHYRWCTL, &tmp);
- if (!(tmp & 0x80)) {
- finished = 1;
- break;
- }
- }
-
- if (!finished)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_READ_REG(chip, PHYDATA0, &tmp);
- data = tmp;
- RTSX_READ_REG(chip, PHYDATA1, &tmp);
- data |= (u16)tmp << 8;
-
- if (val)
- *val = data;
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val)
-{
- int i;
- u8 data = 0;
-
- RTSX_WRITE_REG(chip, EFUSE_CTRL, 0xFF, 0x80|addr);
-
- for (i = 0; i < 100; i++) {
- RTSX_READ_REG(chip, EFUSE_CTRL, &data);
- if (!(data & 0x80))
- break;
- udelay(1);
- }
-
- if (data & 0x80)
- TRACE_RET(chip, STATUS_TIMEDOUT);
-
- RTSX_READ_REG(chip, EFUSE_DATA, &data);
- if (val)
- *val = data;
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val)
-{
- int i, j;
- u8 data = 0, tmp = 0xFF;
-
- for (i = 0; i < 8; i++) {
- if (val & (u8)(1 << i))
- continue;
-
- tmp &= (~(u8)(1 << i));
- RTSX_DEBUGP("Write 0x%x to 0x%x\n", tmp, addr);
-
- RTSX_WRITE_REG(chip, EFUSE_DATA, 0xFF, tmp);
- RTSX_WRITE_REG(chip, EFUSE_CTRL, 0xFF, 0xA0|addr);
-
- for (j = 0; j < 100; j++) {
- RTSX_READ_REG(chip, EFUSE_CTRL, &data);
- if (!(data & 0x80))
- break;
- wait_timeout(3);
- }
-
- if (data & 0x80)
- TRACE_RET(chip, STATUS_TIMEDOUT);
-
- wait_timeout(5);
- }
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit)
-{
- int retval;
- u16 value;
-
- retval = rtsx_read_phy_register(chip, reg, &value);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (value & (1 << bit)) {
- value &= ~(1 << bit);
- retval = rtsx_write_phy_register(chip, reg, value);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit)
-{
- int retval;
- u16 value;
-
- retval = rtsx_read_phy_register(chip, reg, &value);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (0 == (value & (1 << bit))) {
- value |= (1 << bit);
- retval = rtsx_write_phy_register(chip, reg, value);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_check_link_ready(struct rtsx_chip *chip)
-{
- u8 val;
-
- RTSX_READ_REG(chip, IRQSTAT0, &val);
-
- RTSX_DEBUGP("IRQSTAT0: 0x%x\n", val);
- if (val & LINK_RDY_INT) {
- RTSX_DEBUGP("Delinked!\n");
- rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT);
- return STATUS_FAIL;
- }
-
- return STATUS_SUCCESS;
-}
-
-static void rtsx_handle_pm_dstate(struct rtsx_chip *chip, u8 dstate)
-{
- u32 ultmp;
-
- RTSX_DEBUGP("%04x set pm_dstate to %d\n", chip->product_id, dstate);
-
- if (CHK_SDIO_EXIST(chip)) {
- u8 func_no;
-
- if (CHECK_PID(chip, 0x5288))
- func_no = 2;
- else
- func_no = 1;
-
- rtsx_read_cfg_dw(chip, func_no, 0x84, &ultmp);
- RTSX_DEBUGP("pm_dstate of function %d: 0x%x\n", (int)func_no, ultmp);
- rtsx_write_cfg_dw(chip, func_no, 0x84, 0xFF, dstate);
- }
-
- rtsx_write_config_byte(chip, 0x44, dstate);
- rtsx_write_config_byte(chip, 0x45, 0);
-}
-
-void rtsx_enter_L1(struct rtsx_chip *chip)
-{
- rtsx_handle_pm_dstate(chip, 2);
-}
-
-void rtsx_exit_L1(struct rtsx_chip *chip)
-{
- rtsx_write_config_byte(chip, 0x44, 0);
- rtsx_write_config_byte(chip, 0x45, 0);
-}
-
-void rtsx_enter_ss(struct rtsx_chip *chip)
-{
- RTSX_DEBUGP("Enter Selective Suspend State!\n");
-
- rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT);
-
- if (chip->power_down_in_ss) {
- rtsx_power_off_card(chip);
- rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL);
- }
-
- if (CHK_SDIO_EXIST(chip)) {
- if (CHECK_PID(chip, 0x5288))
- rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF00, 0x0100);
- else
- rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF00, 0x0100);
- }
-
- if (chip->auto_delink_en) {
- rtsx_write_register(chip, HOST_SLEEP_STATE, 0x01, 0x01);
- } else {
- if (!chip->phy_debug_mode) {
- u32 tmp;
- tmp = rtsx_readl(chip, RTSX_BIER);
- tmp |= CARD_INT;
- rtsx_writel(chip, RTSX_BIER, tmp);
- }
-
- rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0);
- }
-
- rtsx_enter_L1(chip);
-
- RTSX_CLR_DELINK(chip);
- rtsx_set_stat(chip, RTSX_STAT_SS);
-}
-
-void rtsx_exit_ss(struct rtsx_chip *chip)
-{
- RTSX_DEBUGP("Exit Selective Suspend State!\n");
-
- rtsx_exit_L1(chip);
-
- if (chip->power_down_in_ss) {
- rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL);
- udelay(1000);
- }
-
- if (RTSX_TST_DELINK(chip)) {
- chip->need_reinit = SD_CARD | MS_CARD | XD_CARD;
- rtsx_reinit_cards(chip, 1);
- RTSX_CLR_DELINK(chip);
- } else if (chip->power_down_in_ss) {
- chip->need_reinit = SD_CARD | MS_CARD | XD_CARD;
- rtsx_reinit_cards(chip, 0);
- }
-}
-
-int rtsx_pre_handle_interrupt(struct rtsx_chip *chip)
-{
- u32 status, int_enable;
- int exit_ss = 0;
-#ifdef SUPPORT_OCP
- u32 ocp_int = 0;
-
- if (CHECK_PID(chip, 0x5209)) {
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN))
- ocp_int = MS_OC_INT | SD_OC_INT;
- else
- ocp_int = SD_OC_INT;
-
- } else {
- ocp_int = OC_INT;
- }
-#endif
-
- if (chip->ss_en) {
- chip->ss_counter = 0;
- if (rtsx_get_stat(chip) == RTSX_STAT_SS) {
- exit_ss = 1;
- rtsx_exit_L1(chip);
- rtsx_set_stat(chip, RTSX_STAT_RUN);
- }
- }
-
- int_enable = rtsx_readl(chip, RTSX_BIER);
- chip->int_reg = rtsx_readl(chip, RTSX_BIPR);
-
-#ifdef HW_INT_WRITE_CLR
- if (CHECK_PID(chip, 0x5209))
- rtsx_writel(chip, RTSX_BIPR, chip->int_reg);
-#endif
-
- if (((chip->int_reg & int_enable) == 0) || (chip->int_reg == 0xFFFFFFFF))
- return STATUS_FAIL;
-
- if (!chip->msi_en) {
- if (CHECK_PID(chip, 0x5209)) {
- u8 val;
- rtsx_read_config_byte(chip, 0x05, &val);
- if (val & 0x04)
- return STATUS_FAIL;
- }
- }
-
- status = chip->int_reg &= (int_enable | 0x7FFFFF);
-
- if (status & CARD_INT) {
- chip->auto_delink_cnt = 0;
-
- if (status & SD_INT) {
- if (status & SD_EXIST) {
- set_bit(SD_NR, &(chip->need_reset));
- } else {
- set_bit(SD_NR, &(chip->need_release));
- chip->sd_reset_counter = 0;
- chip->sd_show_cnt = 0;
- clear_bit(SD_NR, &(chip->need_reset));
- }
- } else {
- /* If multi-luns, it's possible that
- when plugging/unplugging one card
- there is another card which still
- exists in the slot. In this case,
- all existed cards should be reset.
- */
- if (exit_ss && (status & SD_EXIST))
- set_bit(SD_NR, &(chip->need_reinit));
- }
- if (!CHECK_PID(chip, 0x5288) || CHECK_BARO_PKG(chip, QFN)) {
- if (status & XD_INT) {
- if (status & XD_EXIST) {
- set_bit(XD_NR, &(chip->need_reset));
- } else {
- set_bit(XD_NR, &(chip->need_release));
- chip->xd_reset_counter = 0;
- chip->xd_show_cnt = 0;
- clear_bit(XD_NR, &(chip->need_reset));
- }
- } else {
- if (exit_ss && (status & XD_EXIST))
- set_bit(XD_NR, &(chip->need_reinit));
- }
- }
- if (status & MS_INT) {
- if (status & MS_EXIST) {
- set_bit(MS_NR, &(chip->need_reset));
- } else {
- set_bit(MS_NR, &(chip->need_release));
- chip->ms_reset_counter = 0;
- chip->ms_show_cnt = 0;
- clear_bit(MS_NR, &(chip->need_reset));
- }
- } else {
- if (exit_ss && (status & MS_EXIST))
- set_bit(MS_NR, &(chip->need_reinit));
- }
- }
-
-#ifdef SUPPORT_OCP
- chip->ocp_int = ocp_int & status;
-#endif
-
- if (chip->sd_io) {
- if (chip->int_reg & DATA_DONE_INT)
- chip->int_reg &= ~(u32)DATA_DONE_INT;
- }
-
- return STATUS_SUCCESS;
-}
-
-void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat)
-{
- int retval;
-
- RTSX_DEBUGP("rtsx_do_before_power_down, pm_stat = %d\n", pm_stat);
-
- rtsx_set_stat(chip, RTSX_STAT_SUSPEND);
-
- retval = rtsx_force_power_on(chip, SSC_PDCTL);
- if (retval != STATUS_SUCCESS)
- return;
-
- rtsx_release_cards(chip);
- rtsx_disable_bus_int(chip);
- turn_off_led(chip, LED_GPIO);
-
-#ifdef HW_AUTO_SWITCH_SD_BUS
- if (chip->sd_io) {
- chip->sdio_in_charge = 1;
- if (CHECK_PID(chip, 0x5208)) {
- rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08);
- /* Enable sdio_bus_auto_switch */
- rtsx_write_register(chip, 0xFE70, 0x80, 0x80);
- } else if (CHECK_PID(chip, 0x5288)) {
- rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08);
- /* Enable sdio_bus_auto_switch */
- rtsx_write_register(chip, 0xFE5A, 0x08, 0x08);
- } else if (CHECK_PID(chip, 0x5209)) {
- rtsx_write_register(chip, TLPTISTAT, 0x10, 0x10);
- /* Enable sdio_bus_auto_switch */
- rtsx_write_register(chip, SDIO_CFG, SDIO_BUS_AUTO_SWITCH, SDIO_BUS_AUTO_SWITCH);
- }
- }
-#endif
-
- if (CHECK_PID(chip, 0x5208) && (chip->ic_version >= IC_VER_D)) {
- /* u_force_clkreq_0 */
- rtsx_write_register(chip, PETXCFG, 0x08, 0x08);
- } else if (CHECK_PID(chip, 0x5209)) {
- /* u_force_clkreq_0 */
- rtsx_write_register(chip, PETXCFG, 0x08, 0x08);
- }
-
- if (pm_stat == PM_S1) {
- RTSX_DEBUGP("Host enter S1\n");
- rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, HOST_ENTER_S1);
- } else if (pm_stat == PM_S3) {
- if (chip->s3_pwr_off_delay > 0)
- wait_timeout(chip->s3_pwr_off_delay);
-
- RTSX_DEBUGP("Host enter S3\n");
- rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, HOST_ENTER_S3);
- }
-
- if (chip->do_delink_before_power_down && chip->auto_delink_en)
- rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 2);
-
- rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL);
-
- chip->cur_clk = 0;
- chip->cur_card = 0;
- chip->card_exist = 0;
-}
-
-void rtsx_enable_aspm(struct rtsx_chip *chip)
-{
- if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) {
- if (!chip->aspm_enabled) {
- RTSX_DEBUGP("Try to enable ASPM\n");
- chip->aspm_enabled = 1;
-
- if (chip->asic_code && CHECK_PID(chip, 0x5208))
- rtsx_write_phy_register(chip, 0x07, 0);
- if (CHECK_PID(chip, 0x5208)) {
- rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3,
- 0x30 | chip->aspm_level[0]);
- } else {
- rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en);
- }
-
- if (CHK_SDIO_EXIST(chip)) {
- u16 val = chip->aspm_l0s_l1_en | 0x0100;
- if (CHECK_PID(chip, 0x5288))
- rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, val);
- else
- rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFFFF, val);
- }
- }
- }
-
- return;
-}
-
-void rtsx_disable_aspm(struct rtsx_chip *chip)
-{
- if (CHECK_PID(chip, 0x5208))
- rtsx_monitor_aspm_config(chip);
-
- if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) {
- if (chip->aspm_enabled) {
- RTSX_DEBUGP("Try to disable ASPM\n");
- chip->aspm_enabled = 0;
-
- if (chip->asic_code && CHECK_PID(chip, 0x5208))
- rtsx_write_phy_register(chip, 0x07, 0x0129);
- if (CHECK_PID(chip, 0x5208))
- rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3, 0x30);
- else
- rtsx_write_config_byte(chip, LCTLR, 0x00);
-
- wait_timeout(1);
- }
- }
-
- return;
-}
-
-int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
-{
- int retval;
- int i, j;
- u16 reg_addr;
- u8 *ptr;
-
- if (!buf)
- TRACE_RET(chip, STATUS_ERROR);
-
- ptr = buf;
- reg_addr = PPBUF_BASE2;
- for (i = 0; i < buf_len/256; i++) {
- rtsx_init_cmd(chip);
-
- for (j = 0; j < 256; j++)
- rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0);
-
- retval = rtsx_send_cmd(chip, 0, 250);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- memcpy(ptr, rtsx_get_cmd_data(chip), 256);
- ptr += 256;
- }
-
- if (buf_len%256) {
- rtsx_init_cmd(chip);
-
- for (j = 0; j < buf_len%256; j++)
- rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0);
-
- retval = rtsx_send_cmd(chip, 0, 250);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- memcpy(ptr, rtsx_get_cmd_data(chip), buf_len%256);
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
-{
- int retval;
- int i, j;
- u16 reg_addr;
- u8 *ptr;
-
- if (!buf)
- TRACE_RET(chip, STATUS_ERROR);
-
- ptr = buf;
- reg_addr = PPBUF_BASE2;
- for (i = 0; i < buf_len/256; i++) {
- rtsx_init_cmd(chip);
-
- for (j = 0; j < 256; j++) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, *ptr);
- ptr++;
- }
-
- retval = rtsx_send_cmd(chip, 0, 250);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (buf_len%256) {
- rtsx_init_cmd(chip);
-
- for (j = 0; j < buf_len%256; j++) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, *ptr);
- ptr++;
- }
-
- retval = rtsx_send_cmd(chip, 0, 250);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_check_chip_exist(struct rtsx_chip *chip)
-{
- if (rtsx_readl(chip, 0) == 0xFFFFFFFF)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl)
-{
- int retval;
- u8 mask = 0;
-
- if (ctl & SSC_PDCTL)
- mask |= SSC_POWER_DOWN;
-
-#ifdef SUPPORT_OCP
- if (ctl & OC_PDCTL) {
- mask |= SD_OC_POWER_DOWN;
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN))
- mask |= MS_OC_POWER_DOWN;
- }
-#endif
-
- if (mask) {
- retval = rtsx_write_register(chip, FPDCTL, mask, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHECK_PID(chip, 0x5288))
- wait_timeout(200);
- }
-
- return STATUS_SUCCESS;
-}
-
-int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl)
-{
- int retval;
- u8 mask = 0, val = 0;
-
- if (ctl & SSC_PDCTL)
- mask |= SSC_POWER_DOWN;
-
-#ifdef SUPPORT_OCP
- if (ctl & OC_PDCTL) {
- mask |= SD_OC_POWER_DOWN;
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN))
- mask |= MS_OC_POWER_DOWN;
- }
-#endif
-
- if (mask) {
- val = mask;
- retval = rtsx_write_register(chip, FPDCTL, mask, val);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
diff --git a/drivers/staging/rts_pstor/rtsx_chip.h b/drivers/staging/rts_pstor/rtsx_chip.h
deleted file mode 100644
index 9f7cd82a154..00000000000
--- a/drivers/staging/rts_pstor/rtsx_chip.h
+++ /dev/null
@@ -1,989 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- * Header file
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#ifndef __REALTEK_RTSX_CHIP_H
-#define __REALTEK_RTSX_CHIP_H
-
-#include "rtsx.h"
-
-#define SUPPORT_CPRM
-#define SUPPORT_OCP
-#define SUPPORT_SDIO_ASPM
-#define SUPPORT_MAGIC_GATE
-#define SUPPORT_MSXC
-#define SUPPORT_SD_LOCK
-/* Hardware switch bus_ctl and cd_ctl automatically */
-#define HW_AUTO_SWITCH_SD_BUS
-/* Enable hardware interrupt write clear */
-#define HW_INT_WRITE_CLR
-/* #define LED_AUTO_BLINK */
-/* #define DISABLE_CARD_INT */
-
-#ifdef SUPPORT_MAGIC_GATE
- /* Using NORMAL_WRITE instead of AUTO_WRITE to set ICV */
- #define MG_SET_ICV_SLOW
- /* HW may miss ERR/CMDNK signal when sampling INT status. */
- #define MS_SAMPLE_INT_ERR
- /* HW DO NOT support Wait_INT function during READ_BYTES transfer mode */
- #define READ_BYTES_WAIT_INT
-#endif
-
-#ifdef SUPPORT_MSXC
-#define XC_POWERCLASS
-#define SUPPORT_PCGL_1P18
-#endif
-
-#ifndef LED_AUTO_BLINK
-#define REGULAR_BLINK
-#endif
-
-#define LED_BLINK_SPEED 5
-#define LED_TOGGLE_INTERVAL 6
-#define GPIO_TOGGLE_THRESHOLD 1024
-#define LED_GPIO 0
-
-#define POLLING_INTERVAL 30
-
-#define TRACE_ITEM_CNT 64
-
-#ifndef STATUS_SUCCESS
-#define STATUS_SUCCESS 0
-#endif
-#ifndef STATUS_FAIL
-#define STATUS_FAIL 1
-#endif
-#ifndef STATUS_TIMEDOUT
-#define STATUS_TIMEDOUT 2
-#endif
-#ifndef STATUS_NOMEM
-#define STATUS_NOMEM 3
-#endif
-#ifndef STATUS_READ_FAIL
-#define STATUS_READ_FAIL 4
-#endif
-#ifndef STATUS_WRITE_FAIL
-#define STATUS_WRITE_FAIL 5
-#endif
-#ifndef STATUS_ERROR
-#define STATUS_ERROR 10
-#endif
-
-#define PM_S1 1
-#define PM_S3 3
-
-/*
- * Transport return codes
- */
-
-#define TRANSPORT_GOOD 0 /* Transport good, command good */
-#define TRANSPORT_FAILED 1 /* Transport good, command failed */
-#define TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */
-#define TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */
-
-
-/*-----------------------------------
- Start-Stop-Unit
------------------------------------*/
-#define STOP_MEDIUM 0x00 /* access disable */
-#define MAKE_MEDIUM_READY 0x01 /* access enable */
-#define UNLOAD_MEDIUM 0x02 /* unload */
-#define LOAD_MEDIUM 0x03 /* load */
-
-/*-----------------------------------
- STANDARD_INQUIRY
------------------------------------*/
-#define QULIFIRE 0x00
-#define AENC_FNC 0x00
-#define TRML_IOP 0x00
-#define REL_ADR 0x00
-#define WBUS_32 0x00
-#define WBUS_16 0x00
-#define SYNC 0x00
-#define LINKED 0x00
-#define CMD_QUE 0x00
-#define SFT_RE 0x00
-
-#define VEN_ID_LEN 8 /* Vendor ID Length */
-#define PRDCT_ID_LEN 16 /* Product ID Length */
-#define PRDCT_REV_LEN 4 /* Product LOT Length */
-
-/* Dynamic flag definitions: used in set_bit() etc. */
-#define RTSX_FLIDX_TRANS_ACTIVE 18 /* 0x00040000 transfer is active */
-#define RTSX_FLIDX_ABORTING 20 /* 0x00100000 abort is in progress */
-#define RTSX_FLIDX_DISCONNECTING 21 /* 0x00200000 disconnect in progress */
-#define ABORTING_OR_DISCONNECTING ((1UL << US_FLIDX_ABORTING) | \
- (1UL << US_FLIDX_DISCONNECTING))
-#define RTSX_FLIDX_RESETTING 22 /* 0x00400000 device reset in progress */
-#define RTSX_FLIDX_TIMED_OUT 23 /* 0x00800000 SCSI midlayer timed out */
-
-#define DRCT_ACCESS_DEV 0x00 /* Direct Access Device */
-#define RMB_DISC 0x80 /* The Device is Removable */
-#define ANSI_SCSI2 0x02 /* Based on ANSI-SCSI2 */
-
-#define SCSI 0x00 /* Interface ID */
-
-#define WRITE_PROTECTED_MEDIA 0x07
-
-/*---- sense key ----*/
-#define ILI 0x20 /* ILI bit is on */
-
-#define NO_SENSE 0x00 /* not exist sense key */
-#define RECOVER_ERR 0x01 /* Target/Logical unit is recoverd */
-#define NOT_READY 0x02 /* Logical unit is not ready */
-#define MEDIA_ERR 0x03 /* medium/data error */
-#define HARDWARE_ERR 0x04 /* hardware error */
-#define ILGAL_REQ 0x05 /* CDB/parameter/identify msg error */
-#define UNIT_ATTENTION 0x06 /* unit attention condition occur */
-#define DAT_PRTCT 0x07 /* read/write is desable */
-#define BLNC_CHK 0x08 /* find blank/DOF in read */
- /* write to unblank area */
-#define CPY_ABRT 0x0a /* Copy/Compare/Copy&Verify illgal */
-#define ABRT_CMD 0x0b /* Target make the command in error */
-#define EQUAL 0x0c /* Search Data end with Equal */
-#define VLM_OVRFLW 0x0d /* Some data are left in buffer */
-#define MISCMP 0x0e /* find inequality */
-
-#define READ_ERR -1
-#define WRITE_ERR -2
-
-#define FIRST_RESET 0x01
-#define USED_EXIST 0x02
-
-/*-----------------------------------
- SENSE_DATA
------------------------------------*/
-/*---- valid ----*/
-#define SENSE_VALID 0x80 /* Sense data is valid as SCSI2 */
-#define SENSE_INVALID 0x00 /* Sense data is invalid as SCSI2 */
-
-/*---- error code ----*/
-#define CUR_ERR 0x70 /* current error */
-#define DEF_ERR 0x71 /* specific command error */
-
-/*---- sense key Information ----*/
-#define SNSKEYINFO_LEN 3 /* length of sense key information */
-
-#define SKSV 0x80
-#define CDB_ILLEGAL 0x40
-#define DAT_ILLEGAL 0x00
-#define BPV 0x08
-#define BIT_ILLEGAL0 0 /* bit0 is illegal */
-#define BIT_ILLEGAL1 1 /* bit1 is illegal */
-#define BIT_ILLEGAL2 2 /* bit2 is illegal */
-#define BIT_ILLEGAL3 3 /* bit3 is illegal */
-#define BIT_ILLEGAL4 4 /* bit4 is illegal */
-#define BIT_ILLEGAL5 5 /* bit5 is illegal */
-#define BIT_ILLEGAL6 6 /* bit6 is illegal */
-#define BIT_ILLEGAL7 7 /* bit7 is illegal */
-
-/*---- ASC ----*/
-#define ASC_NO_INFO 0x00
-#define ASC_MISCMP 0x1d
-#define ASC_INVLD_CDB 0x24
-#define ASC_INVLD_PARA 0x26
-#define ASC_LU_NOT_READY 0x04
-#define ASC_WRITE_ERR 0x0c
-#define ASC_READ_ERR 0x11
-#define ASC_LOAD_EJCT_ERR 0x53
-#define ASC_MEDIA_NOT_PRESENT 0x3A
-#define ASC_MEDIA_CHANGED 0x28
-#define ASC_MEDIA_IN_PROCESS 0x04
-#define ASC_WRITE_PROTECT 0x27
-#define ASC_LUN_NOT_SUPPORTED 0x25
-
-/*---- ASQC ----*/
-#define ASCQ_NO_INFO 0x00
-#define ASCQ_MEDIA_IN_PROCESS 0x01
-#define ASCQ_MISCMP 0x00
-#define ASCQ_INVLD_CDB 0x00
-#define ASCQ_INVLD_PARA 0x02
-#define ASCQ_LU_NOT_READY 0x02
-#define ASCQ_WRITE_ERR 0x02
-#define ASCQ_READ_ERR 0x00
-#define ASCQ_LOAD_EJCT_ERR 0x00
-#define ASCQ_WRITE_PROTECT 0x00
-
-
-struct sense_data_t {
- unsigned char err_code; /* error code */
- /* bit7 : valid */
- /* (1 : SCSI2) */
- /* (0 : Vendor specific) */
- /* bit6-0 : error code */
- /* (0x70 : current error) */
- /* (0x71 : specific command error) */
- unsigned char seg_no; /* segment No. */
- unsigned char sense_key; /* byte5 : ILI */
- /* bit3-0 : sense key */
- unsigned char info[4]; /* information */
- unsigned char ad_sense_len; /* additional sense data length */
- unsigned char cmd_info[4]; /* command specific information */
- unsigned char asc; /* ASC */
- unsigned char ascq; /* ASCQ */
- unsigned char rfu; /* FRU */
- unsigned char sns_key_info[3]; /* sense key specific information */
-};
-
-/* PCI Operation Register Address */
-#define RTSX_HCBAR 0x00
-#define RTSX_HCBCTLR 0x04
-#define RTSX_HDBAR 0x08
-#define RTSX_HDBCTLR 0x0C
-#define RTSX_HAIMR 0x10
-#define RTSX_BIPR 0x14
-#define RTSX_BIER 0x18
-
-/* Host command buffer control register */
-#define STOP_CMD (0x01 << 28)
-
-/* Host data buffer control register */
-#define SDMA_MODE 0x00
-#define ADMA_MODE (0x02 << 26)
-#define STOP_DMA (0x01 << 28)
-#define TRIG_DMA (0x01 << 31)
-
-/* Bus interrupt pending register */
-#define CMD_DONE_INT (1 << 31)
-#define DATA_DONE_INT (1 << 30)
-#define TRANS_OK_INT (1 << 29)
-#define TRANS_FAIL_INT (1 << 28)
-#define XD_INT (1 << 27)
-#define MS_INT (1 << 26)
-#define SD_INT (1 << 25)
-#define GPIO0_INT (1 << 24)
-#define OC_INT (1 << 23)
-#define SD_WRITE_PROTECT (1 << 19)
-#define XD_EXIST (1 << 18)
-#define MS_EXIST (1 << 17)
-#define SD_EXIST (1 << 16)
-#define DELINK_INT GPIO0_INT
-#define MS_OC_INT (1 << 23)
-#define SD_OC_INT (1 << 22)
-
-#define CARD_INT (XD_INT | MS_INT | SD_INT)
-#define NEED_COMPLETE_INT (DATA_DONE_INT | TRANS_OK_INT | TRANS_FAIL_INT)
-#define RTSX_INT (CMD_DONE_INT | NEED_COMPLETE_INT | CARD_INT | GPIO0_INT | OC_INT)
-
-#define CARD_EXIST (XD_EXIST | MS_EXIST | SD_EXIST)
-
-/* Bus interrupt enable register */
-#define CMD_DONE_INT_EN (1 << 31)
-#define DATA_DONE_INT_EN (1 << 30)
-#define TRANS_OK_INT_EN (1 << 29)
-#define TRANS_FAIL_INT_EN (1 << 28)
-#define XD_INT_EN (1 << 27)
-#define MS_INT_EN (1 << 26)
-#define SD_INT_EN (1 << 25)
-#define GPIO0_INT_EN (1 << 24)
-#define OC_INT_EN (1 << 23)
-#define DELINK_INT_EN GPIO0_INT_EN
-#define MS_OC_INT_EN (1 << 23)
-#define SD_OC_INT_EN (1 << 22)
-
-
-#define READ_REG_CMD 0
-#define WRITE_REG_CMD 1
-#define CHECK_REG_CMD 2
-
-#define HOST_TO_DEVICE 0
-#define DEVICE_TO_HOST 1
-
-
-#define RTSX_RESV_BUF_LEN 4096
-#define HOST_CMDS_BUF_LEN 1024
-#define HOST_SG_TBL_BUF_LEN (RTSX_RESV_BUF_LEN - HOST_CMDS_BUF_LEN)
-
-#define SD_NR 2
-#define MS_NR 3
-#define XD_NR 4
-#define SPI_NR 7
-#define SD_CARD (1 << SD_NR)
-#define MS_CARD (1 << MS_NR)
-#define XD_CARD (1 << XD_NR)
-#define SPI_CARD (1 << SPI_NR)
-
-#define MAX_ALLOWED_LUN_CNT 8
-
-#define XD_FREE_TABLE_CNT 1200
-#define MS_FREE_TABLE_CNT 512
-
-
-/* Bit Operation */
-#define SET_BIT(data, idx) ((data) |= 1 << (idx))
-#define CLR_BIT(data, idx) ((data) &= ~(1 << (idx)))
-#define CHK_BIT(data, idx) ((data) & (1 << (idx)))
-
-/* SG descriptor */
-#define SG_INT 0x04
-#define SG_END 0x02
-#define SG_VALID 0x01
-
-#define SG_NO_OP 0x00
-#define SG_TRANS_DATA (0x02 << 4)
-#define SG_LINK_DESC (0x03 << 4)
-
-struct rtsx_chip;
-
-typedef int (*card_rw_func)(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec_cnt);
-
-/* Supported Clock */
-enum card_clock {CLK_20 = 1, CLK_30, CLK_40, CLK_50, CLK_60, CLK_80, CLK_100, CLK_120, CLK_150, CLK_200};
-
-enum RTSX_STAT {RTSX_STAT_INIT, RTSX_STAT_IDLE, RTSX_STAT_RUN, RTSX_STAT_SS,
- RTSX_STAT_DELINK, RTSX_STAT_SUSPEND, RTSX_STAT_ABORT, RTSX_STAT_DISCONNECT};
-enum IC_VER {IC_VER_AB, IC_VER_C = 2, IC_VER_D = 3};
-
-#define MAX_RESET_CNT 3
-
-/* For MS Card */
-#define MAX_DEFECTIVE_BLOCK 10
-
-struct zone_entry {
- u16 *l2p_table;
- u16 *free_table;
- u16 defect_list[MAX_DEFECTIVE_BLOCK]; /* For MS card only */
- int set_index;
- int get_index;
- int unused_blk_cnt;
- int disable_count;
- /* To indicate whether the L2P table of this zone has been built. */
- int build_flag;
-};
-
-#define TYPE_SD 0x0000
-#define TYPE_MMC 0x0001
-
-/* TYPE_SD */
-#define SD_HS 0x0100
-#define SD_SDR50 0x0200
-#define SD_DDR50 0x0400
-#define SD_SDR104 0x0800
-#define SD_HCXC 0x1000
-
-/* TYPE_MMC */
-#define MMC_26M 0x0100
-#define MMC_52M 0x0200
-#define MMC_4BIT 0x0400
-#define MMC_8BIT 0x0800
-#define MMC_SECTOR_MODE 0x1000
-#define MMC_DDR52 0x2000
-
-/* SD card */
-#define CHK_SD(sd_card) (((sd_card)->sd_type & 0xFF) == TYPE_SD)
-#define CHK_SD_HS(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_HS))
-#define CHK_SD_SDR50(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_SDR50))
-#define CHK_SD_DDR50(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_DDR50))
-#define CHK_SD_SDR104(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_SDR104))
-#define CHK_SD_HCXC(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_HCXC))
-#define CHK_SD_HC(sd_card) (CHK_SD_HCXC(sd_card) && ((sd_card)->capacity <= 0x4000000))
-#define CHK_SD_XC(sd_card) (CHK_SD_HCXC(sd_card) && ((sd_card)->capacity > 0x4000000))
-#define CHK_SD30_SPEED(sd_card) (CHK_SD_SDR50(sd_card) || CHK_SD_DDR50(sd_card) || CHK_SD_SDR104(sd_card))
-
-#define SET_SD(sd_card) ((sd_card)->sd_type = TYPE_SD)
-#define SET_SD_HS(sd_card) ((sd_card)->sd_type |= SD_HS)
-#define SET_SD_SDR50(sd_card) ((sd_card)->sd_type |= SD_SDR50)
-#define SET_SD_DDR50(sd_card) ((sd_card)->sd_type |= SD_DDR50)
-#define SET_SD_SDR104(sd_card) ((sd_card)->sd_type |= SD_SDR104)
-#define SET_SD_HCXC(sd_card) ((sd_card)->sd_type |= SD_HCXC)
-
-#define CLR_SD_HS(sd_card) ((sd_card)->sd_type &= ~SD_HS)
-#define CLR_SD_SDR50(sd_card) ((sd_card)->sd_type &= ~SD_SDR50)
-#define CLR_SD_DDR50(sd_card) ((sd_card)->sd_type &= ~SD_DDR50)
-#define CLR_SD_SDR104(sd_card) ((sd_card)->sd_type &= ~SD_SDR104)
-#define CLR_SD_HCXC(sd_card) ((sd_card)->sd_type &= ~SD_HCXC)
-
-/* MMC card */
-#define CHK_MMC(sd_card) (((sd_card)->sd_type & 0xFF) == TYPE_MMC)
-#define CHK_MMC_26M(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_26M))
-#define CHK_MMC_52M(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_52M))
-#define CHK_MMC_4BIT(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_4BIT))
-#define CHK_MMC_8BIT(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_8BIT))
-#define CHK_MMC_SECTOR_MODE(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_SECTOR_MODE))
-#define CHK_MMC_DDR52(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_DDR52))
-
-#define SET_MMC(sd_card) ((sd_card)->sd_type = TYPE_MMC)
-#define SET_MMC_26M(sd_card) ((sd_card)->sd_type |= MMC_26M)
-#define SET_MMC_52M(sd_card) ((sd_card)->sd_type |= MMC_52M)
-#define SET_MMC_4BIT(sd_card) ((sd_card)->sd_type |= MMC_4BIT)
-#define SET_MMC_8BIT(sd_card) ((sd_card)->sd_type |= MMC_8BIT)
-#define SET_MMC_SECTOR_MODE(sd_card) ((sd_card)->sd_type |= MMC_SECTOR_MODE)
-#define SET_MMC_DDR52(sd_card) ((sd_card)->sd_type |= MMC_DDR52)
-
-#define CLR_MMC_26M(sd_card) ((sd_card)->sd_type &= ~MMC_26M)
-#define CLR_MMC_52M(sd_card) ((sd_card)->sd_type &= ~MMC_52M)
-#define CLR_MMC_4BIT(sd_card) ((sd_card)->sd_type &= ~MMC_4BIT)
-#define CLR_MMC_8BIT(sd_card) ((sd_card)->sd_type &= ~MMC_8BIT)
-#define CLR_MMC_SECTOR_MODE(sd_card) ((sd_card)->sd_type &= ~MMC_SECTOR_MODE)
-#define CLR_MMC_DDR52(sd_card) ((sd_card)->sd_type &= ~MMC_DDR52)
-
-#define CHK_MMC_HS(sd_card) (CHK_MMC_52M(sd_card) && CHK_MMC_26M(sd_card))
-#define CLR_MMC_HS(sd_card) \
-do { \
- CLR_MMC_DDR52(sd_card); \
- CLR_MMC_52M(sd_card); \
- CLR_MMC_26M(sd_card); \
-} while (0)
-
-#define SD_SUPPORT_CLASS_TEN 0x01
-#define SD_SUPPORT_1V8 0x02
-
-#define SD_SET_CLASS_TEN(sd_card) ((sd_card)->sd_setting |= SD_SUPPORT_CLASS_TEN)
-#define SD_CHK_CLASS_TEN(sd_card) ((sd_card)->sd_setting & SD_SUPPORT_CLASS_TEN)
-#define SD_CLR_CLASS_TEN(sd_card) ((sd_card)->sd_setting &= ~SD_SUPPORT_CLASS_TEN)
-#define SD_SET_1V8(sd_card) ((sd_card)->sd_setting |= SD_SUPPORT_1V8)
-#define SD_CHK_1V8(sd_card) ((sd_card)->sd_setting & SD_SUPPORT_1V8)
-#define SD_CLR_1V8(sd_card) ((sd_card)->sd_setting &= ~SD_SUPPORT_1V8)
-
-struct sd_info {
- u16 sd_type;
- u8 err_code;
- u8 sd_data_buf_ready;
- u32 sd_addr;
- u32 capacity;
-
- u8 raw_csd[16];
- u8 raw_scr[8];
-
- /* Sequential RW */
- int seq_mode;
- enum dma_data_direction pre_dir;
- u32 pre_sec_addr;
- u16 pre_sec_cnt;
-
- int cleanup_counter;
-
- int sd_clock;
-
- int mmc_dont_switch_bus;
-
-#ifdef SUPPORT_CPRM
- int sd_pass_thru_en;
- int pre_cmd_err;
- u8 last_rsp_type;
- u8 rsp[17];
-#endif
-
- u8 func_group1_mask;
- u8 func_group2_mask;
- u8 func_group3_mask;
- u8 func_group4_mask;
-
- u8 sd_switch_fail;
- u8 sd_read_phase;
-
-#ifdef SUPPORT_SD_LOCK
- u8 sd_lock_status;
- u8 sd_erase_status;
- u8 sd_lock_notify;
-#endif
- int need_retune;
-};
-
-struct xd_delay_write_tag {
- u32 old_phyblock;
- u32 new_phyblock;
- u32 logblock;
- u8 pageoff;
- u8 delay_write_flag;
-};
-
-struct xd_info {
- u8 maker_code;
- u8 device_code;
- u8 block_shift;
- u8 page_off;
- u8 addr_cycle;
- u16 cis_block;
- u8 multi_flag;
- u8 err_code;
- u32 capacity;
-
- struct zone_entry *zone;
- int zone_cnt;
-
- struct xd_delay_write_tag delay_write;
- int cleanup_counter;
-
- int xd_clock;
-};
-
-#define MODE_512_SEQ 0x01
-#define MODE_2K_SEQ 0x02
-
-#define TYPE_MS 0x0000
-#define TYPE_MSPRO 0x0001
-
-#define MS_4BIT 0x0100
-#define MS_8BIT 0x0200
-#define MS_HG 0x0400
-#define MS_XC 0x0800
-
-#define HG8BIT (MS_HG | MS_8BIT)
-
-#define CHK_MSPRO(ms_card) (((ms_card)->ms_type & 0xFF) == TYPE_MSPRO)
-#define CHK_HG8BIT(ms_card) (CHK_MSPRO(ms_card) && (((ms_card)->ms_type & HG8BIT) == HG8BIT))
-#define CHK_MSXC(ms_card) (CHK_MSPRO(ms_card) && ((ms_card)->ms_type & MS_XC))
-#define CHK_MSHG(ms_card) (CHK_MSPRO(ms_card) && ((ms_card)->ms_type & MS_HG))
-
-#define CHK_MS8BIT(ms_card) (((ms_card)->ms_type & MS_8BIT))
-#define CHK_MS4BIT(ms_card) (((ms_card)->ms_type & MS_4BIT))
-
-struct ms_delay_write_tag {
- u16 old_phyblock;
- u16 new_phyblock;
- u16 logblock;
- u8 pageoff;
- u8 delay_write_flag;
-};
-
-struct ms_info {
- u16 ms_type;
- u8 block_shift;
- u8 page_off;
- u16 total_block;
- u16 boot_block;
- u32 capacity;
-
- u8 check_ms_flow;
- u8 switch_8bit_fail;
- u8 err_code;
-
- struct zone_entry *segment;
- int segment_cnt;
-
- int pro_under_formatting;
- int format_status;
- u16 progress;
- u8 raw_sys_info[96];
-#ifdef SUPPORT_PCGL_1P18
- u8 raw_model_name[48];
-#endif
-
- u8 multi_flag;
-
- /* Sequential RW */
- u8 seq_mode;
- enum dma_data_direction pre_dir;
- u32 pre_sec_addr;
- u16 pre_sec_cnt;
- u32 total_sec_cnt;
-
- struct ms_delay_write_tag delay_write;
-
- int cleanup_counter;
-
- int ms_clock;
-
-#ifdef SUPPORT_MAGIC_GATE
- u8 magic_gate_id[16];
- u8 mg_entry_num;
- int mg_auth; /* flag to indicate authentication process */
-#endif
-};
-
-struct spi_info {
- u8 use_clk;
- u8 write_en;
- u16 clk_div;
- u8 err_code;
-
- int spi_clock;
-};
-
-
-#ifdef _MSG_TRACE
-struct trace_msg_t {
- u16 line;
-#define MSG_FUNC_LEN 64
- char func[MSG_FUNC_LEN];
-#define MSG_FILE_LEN 32
- char file[MSG_FILE_LEN];
-#define TIME_VAL_LEN 16
- u8 timeval_buf[TIME_VAL_LEN];
- u8 valid;
-};
-#endif
-
-/************/
-/* LUN mode */
-/************/
-/* Single LUN, support xD/SD/MS */
-#define DEFAULT_SINGLE 0
-/* 2 LUN mode, support SD/MS */
-#define SD_MS_2LUN 1
-/* Single LUN, but only support SD/MS, for Barossa LQFP */
-#define SD_MS_1LUN 2
-
-#define LAST_LUN_MODE 2
-
-/* Barossa package */
-#define QFN 0
-#define LQFP 1
-
-/******************/
-/* sd_ctl bit map */
-/******************/
-/* SD push point control, bit 0, 1 */
-#define SD_PUSH_POINT_CTL_MASK 0x03
-#define SD_PUSH_POINT_DELAY 0x01
-#define SD_PUSH_POINT_AUTO 0x02
-/* SD sample point control, bit 2, 3 */
-#define SD_SAMPLE_POINT_CTL_MASK 0x0C
-#define SD_SAMPLE_POINT_DELAY 0x04
-#define SD_SAMPLE_POINT_AUTO 0x08
-/* SD DDR Tx phase set by user, bit 4 */
-#define SD_DDR_TX_PHASE_SET_BY_USER 0x10
-/* MMC DDR Tx phase set by user, bit 5 */
-#define MMC_DDR_TX_PHASE_SET_BY_USER 0x20
-/* Support MMC DDR mode, bit 6 */
-#define SUPPORT_MMC_DDR_MODE 0x40
-/* Reset MMC at first */
-#define RESET_MMC_FIRST 0x80
-
-#define SEQ_START_CRITERIA 0x20
-
-/* MS Power Class En */
-#define POWER_CLASS_2_EN 0x02
-#define POWER_CLASS_1_EN 0x01
-
-#define MAX_SHOW_CNT 10
-#define MAX_RESET_CNT 3
-
-#define SDIO_EXIST 0x01
-#define SDIO_IGNORED 0x02
-
-#define CHK_SDIO_EXIST(chip) ((chip)->sdio_func_exist & SDIO_EXIST)
-#define SET_SDIO_EXIST(chip) ((chip)->sdio_func_exist |= SDIO_EXIST)
-#define CLR_SDIO_EXIST(chip) ((chip)->sdio_func_exist &= ~SDIO_EXIST)
-
-#define CHK_SDIO_IGNORED(chip) ((chip)->sdio_func_exist & SDIO_IGNORED)
-#define SET_SDIO_IGNORED(chip) ((chip)->sdio_func_exist |= SDIO_IGNORED)
-#define CLR_SDIO_IGNORED(chip) ((chip)->sdio_func_exist &= ~SDIO_IGNORED)
-
-struct rtsx_chip {
- rtsx_dev_t *rtsx;
-
- u32 int_reg; /* Bus interrupt pending register */
- char max_lun;
- void *context;
-
- void *host_cmds_ptr; /* host commands buffer pointer */
- dma_addr_t host_cmds_addr;
- int ci; /* Command Index */
-
- void *host_sg_tbl_ptr; /* SG descriptor table */
- dma_addr_t host_sg_tbl_addr;
- int sgi; /* SG entry index */
-
- struct scsi_cmnd *srb; /* current srb */
- struct sense_data_t sense_buffer[MAX_ALLOWED_LUN_CNT];
-
- int cur_clk; /* current card clock */
-
- /* Current accessed card */
- int cur_card;
-
- unsigned long need_release; /* need release bit map */
- unsigned long need_reset; /* need reset bit map */
- /* Flag to indicate that this card is just resumed from SS state,
- * and need released before being resetted
- */
- unsigned long need_reinit;
-
- int rw_need_retry;
-
-#ifdef SUPPORT_OCP
- u32 ocp_int;
- u8 ocp_stat;
-#endif
-
- u8 card_exist; /* card exist bit map (physical exist) */
- u8 card_ready; /* card ready bit map (reset successfully) */
- u8 card_fail; /* card reset fail bit map */
- u8 card_ejected; /* card ejected bit map */
- u8 card_wp; /* card write protected bit map */
-
- u8 lun_mc; /* flag to indicate whether to answer MediaChange */
-
-#ifndef LED_AUTO_BLINK
- int led_toggle_counter;
-#endif
-
- int sd_reset_counter;
- int xd_reset_counter;
- int ms_reset_counter;
-
- /* card bus width */
- u8 card_bus_width[MAX_ALLOWED_LUN_CNT];
- /* card capacity */
- u32 capacity[MAX_ALLOWED_LUN_CNT];
- /* read/write card function pointer */
- card_rw_func rw_card[MAX_ALLOWED_LUN_CNT];
- /* read/write capacity, used for GPIO Toggle */
- u32 rw_cap[MAX_ALLOWED_LUN_CNT];
- /* card to lun mapping table */
- u8 card2lun[32];
- /* lun to card mapping table */
- u8 lun2card[MAX_ALLOWED_LUN_CNT];
-
- int rw_fail_cnt[MAX_ALLOWED_LUN_CNT];
-
- int sd_show_cnt;
- int xd_show_cnt;
- int ms_show_cnt;
-
- /* card information */
- struct sd_info sd_card;
- struct xd_info xd_card;
- struct ms_info ms_card;
-
- struct spi_info spi;
-
-#ifdef _MSG_TRACE
- struct trace_msg_t trace_msg[TRACE_ITEM_CNT];
- int msg_idx;
-#endif
-
- int auto_delink_cnt;
- int auto_delink_allowed;
-
- int aspm_enabled;
-
- int sdio_aspm;
- int sdio_idle;
- int sdio_counter;
- u8 sdio_raw_data[12];
-
- u8 sd_io;
- u8 sd_int;
-
- u8 rtsx_flag;
-
- int ss_counter;
- int idle_counter;
- enum RTSX_STAT rtsx_stat;
-
- u16 vendor_id;
- u16 product_id;
- u8 ic_version;
-
- int driver_first_load;
-
-#ifdef HW_AUTO_SWITCH_SD_BUS
- int sdio_in_charge;
-#endif
-
- u8 aspm_level[2];
-
- int chip_insert_with_sdio;
-
- /* Options */
-
- int adma_mode;
-
- int auto_delink_en;
- int ss_en;
- u8 lun_mode;
- u8 aspm_l0s_l1_en;
-
- int power_down_in_ss;
-
- int sdr104_en;
- int ddr50_en;
- int sdr50_en;
-
- int baro_pkg;
-
- int asic_code;
- int phy_debug_mode;
- int hw_bypass_sd;
- int sdio_func_exist;
- int aux_pwr_exist;
- u8 ms_power_class_en;
-
- int mspro_formatter_enable;
-
- int remote_wakeup_en;
-
- int ignore_sd;
- int use_hw_setting;
-
- int ss_idle_period;
-
- int dynamic_aspm;
-
- int fpga_sd_sdr104_clk;
- int fpga_sd_ddr50_clk;
- int fpga_sd_sdr50_clk;
- int fpga_sd_hs_clk;
- int fpga_mmc_52m_clk;
- int fpga_ms_hg_clk;
- int fpga_ms_4bit_clk;
- int fpga_ms_1bit_clk;
-
- int asic_sd_sdr104_clk;
- int asic_sd_ddr50_clk;
- int asic_sd_sdr50_clk;
- int asic_sd_hs_clk;
- int asic_mmc_52m_clk;
- int asic_ms_hg_clk;
- int asic_ms_4bit_clk;
- int asic_ms_1bit_clk;
-
- u8 ssc_depth_sd_sdr104;
- u8 ssc_depth_sd_ddr50;
- u8 ssc_depth_sd_sdr50;
- u8 ssc_depth_sd_hs;
- u8 ssc_depth_mmc_52m;
- u8 ssc_depth_ms_hg;
- u8 ssc_depth_ms_4bit;
- u8 ssc_depth_low_speed;
-
- u8 card_drive_sel;
- u8 sd30_drive_sel_1v8;
- u8 sd30_drive_sel_3v3;
-
- u8 sd_400mA_ocp_thd;
- u8 sd_800mA_ocp_thd;
- u8 ms_ocp_thd;
-
- int ssc_en;
- int msi_en;
-
- int xd_timeout;
- int sd_timeout;
- int ms_timeout;
- int mspro_timeout;
-
- int auto_power_down;
-
- int sd_ddr_tx_phase;
- int mmc_ddr_tx_phase;
- int sd_default_tx_phase;
- int sd_default_rx_phase;
-
- int pmos_pwr_on_interval;
- int sd_voltage_switch_delay;
- int s3_pwr_off_delay;
-
- int force_clkreq_0;
- int ft2_fast_mode;
-
- int do_delink_before_power_down;
- int polling_config;
- int sdio_retry_cnt;
-
- int delink_stage1_step;
- int delink_stage2_step;
- int delink_stage3_step;
-
- int auto_delink_in_L1;
- int hp_watch_bios_hotplug;
- int support_ms_8bit;
-
- u8 blink_led;
- u8 phy_voltage;
- u8 max_payload;
-
- u32 sd_speed_prior;
- u32 sd_current_prior;
- u32 sd_ctl;
-};
-
-#define rtsx_set_stat(chip, stat) \
-do { \
- if ((stat) != RTSX_STAT_IDLE) { \
- (chip)->idle_counter = 0; \
- } \
- (chip)->rtsx_stat = (enum RTSX_STAT)(stat); \
-} while (0)
-#define rtsx_get_stat(chip) ((chip)->rtsx_stat)
-#define rtsx_chk_stat(chip, stat) ((chip)->rtsx_stat == (stat))
-
-#define RTSX_SET_DELINK(chip) ((chip)->rtsx_flag |= 0x01)
-#define RTSX_CLR_DELINK(chip) ((chip)->rtsx_flag &= 0xFE)
-#define RTSX_TST_DELINK(chip) ((chip)->rtsx_flag & 0x01)
-
-#define CHECK_PID(chip, pid) ((chip)->product_id == (pid))
-#define CHECK_BARO_PKG(chip, pkg) ((chip)->baro_pkg == (pkg))
-#define CHECK_LUN_MODE(chip, mode) ((chip)->lun_mode == (mode))
-
-/* Power down control */
-#define SSC_PDCTL 0x01
-#define OC_PDCTL 0x02
-
-int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl);
-int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl);
-
-void rtsx_disable_card_int(struct rtsx_chip *chip);
-void rtsx_enable_card_int(struct rtsx_chip *chip);
-void rtsx_enable_bus_int(struct rtsx_chip *chip);
-void rtsx_disable_bus_int(struct rtsx_chip *chip);
-int rtsx_reset_chip(struct rtsx_chip *chip);
-int rtsx_init_chip(struct rtsx_chip *chip);
-void rtsx_release_chip(struct rtsx_chip *chip);
-void rtsx_polling_func(struct rtsx_chip *chip);
-void rtsx_undo_delink(struct rtsx_chip *chip);
-void rtsx_stop_cmd(struct rtsx_chip *chip, int card);
-int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data);
-int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data);
-int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask, u32 val);
-int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val);
-int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int len);
-int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int len);
-int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val);
-int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val);
-int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val);
-int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val);
-int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit);
-int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit);
-int rtsx_check_link_ready(struct rtsx_chip *chip);
-void rtsx_enter_ss(struct rtsx_chip *chip);
-void rtsx_exit_ss(struct rtsx_chip *chip);
-int rtsx_pre_handle_interrupt(struct rtsx_chip *chip);
-void rtsx_enter_L1(struct rtsx_chip *chip);
-void rtsx_exit_L1(struct rtsx_chip *chip);
-void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat);
-void rtsx_enable_aspm(struct rtsx_chip *chip);
-void rtsx_disable_aspm(struct rtsx_chip *chip);
-int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len);
-int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len);
-int rtsx_check_chip_exist(struct rtsx_chip *chip);
-
-#define RTSX_WRITE_REG(chip, addr, mask, data) \
-do { \
- int retval = rtsx_write_register((chip), (addr), (mask), (data)); \
- if (retval != STATUS_SUCCESS) { \
- TRACE_RET((chip), retval); \
- } \
-} while (0)
-
-#define RTSX_READ_REG(chip, addr, data) \
-do { \
- int retval = rtsx_read_register((chip), (addr), (data)); \
- if (retval != STATUS_SUCCESS) { \
- TRACE_RET((chip), retval); \
- } \
-} while (0)
-
-#endif /* __REALTEK_RTSX_CHIP_H */
diff --git a/drivers/staging/rts_pstor/rtsx_scsi.c b/drivers/staging/rts_pstor/rtsx_scsi.c
deleted file mode 100644
index 86c41b3a42a..00000000000
--- a/drivers/staging/rts_pstor/rtsx_scsi.c
+++ /dev/null
@@ -1,3137 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#include <linux/blkdev.h>
-#include <linux/kthread.h>
-#include <linux/sched.h>
-#include <linux/vmalloc.h>
-
-#include "rtsx.h"
-#include "rtsx_transport.h"
-#include "rtsx_sys.h"
-#include "rtsx_card.h"
-#include "rtsx_chip.h"
-#include "rtsx_scsi.h"
-#include "sd.h"
-#include "ms.h"
-#include "spi.h"
-
-void scsi_show_command(struct scsi_cmnd *srb)
-{
- char *what = NULL;
- int i, unknown_cmd = 0;
-
- switch (srb->cmnd[0]) {
- case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break;
- case REZERO_UNIT: what = "REZERO_UNIT"; break;
- case REQUEST_SENSE: what = "REQUEST_SENSE"; break;
- case FORMAT_UNIT: what = "FORMAT_UNIT"; break;
- case READ_BLOCK_LIMITS: what = "READ_BLOCK_LIMITS"; break;
- case REASSIGN_BLOCKS: what = "REASSIGN_BLOCKS"; break;
- case READ_6: what = "READ_6"; break;
- case WRITE_6: what = "WRITE_6"; break;
- case SEEK_6: what = "SEEK_6"; break;
- case READ_REVERSE: what = "READ_REVERSE"; break;
- case WRITE_FILEMARKS: what = "WRITE_FILEMARKS"; break;
- case SPACE: what = "SPACE"; break;
- case INQUIRY: what = "INQUIRY"; break;
- case RECOVER_BUFFERED_DATA: what = "RECOVER_BUFFERED_DATA"; break;
- case MODE_SELECT: what = "MODE_SELECT"; break;
- case RESERVE: what = "RESERVE"; break;
- case RELEASE: what = "RELEASE"; break;
- case COPY: what = "COPY"; break;
- case ERASE: what = "ERASE"; break;
- case MODE_SENSE: what = "MODE_SENSE"; break;
- case START_STOP: what = "START_STOP"; break;
- case RECEIVE_DIAGNOSTIC: what = "RECEIVE_DIAGNOSTIC"; break;
- case SEND_DIAGNOSTIC: what = "SEND_DIAGNOSTIC"; break;
- case ALLOW_MEDIUM_REMOVAL: what = "ALLOW_MEDIUM_REMOVAL"; break;
- case SET_WINDOW: what = "SET_WINDOW"; break;
- case READ_CAPACITY: what = "READ_CAPACITY"; break;
- case READ_10: what = "READ_10"; break;
- case WRITE_10: what = "WRITE_10"; break;
- case SEEK_10: what = "SEEK_10"; break;
- case WRITE_VERIFY: what = "WRITE_VERIFY"; break;
- case VERIFY: what = "VERIFY"; break;
- case SEARCH_HIGH: what = "SEARCH_HIGH"; break;
- case SEARCH_EQUAL: what = "SEARCH_EQUAL"; break;
- case SEARCH_LOW: what = "SEARCH_LOW"; break;
- case SET_LIMITS: what = "SET_LIMITS"; break;
- case READ_POSITION: what = "READ_POSITION"; break;
- case SYNCHRONIZE_CACHE: what = "SYNCHRONIZE_CACHE"; break;
- case LOCK_UNLOCK_CACHE: what = "LOCK_UNLOCK_CACHE"; break;
- case READ_DEFECT_DATA: what = "READ_DEFECT_DATA"; break;
- case MEDIUM_SCAN: what = "MEDIUM_SCAN"; break;
- case COMPARE: what = "COMPARE"; break;
- case COPY_VERIFY: what = "COPY_VERIFY"; break;
- case WRITE_BUFFER: what = "WRITE_BUFFER"; break;
- case READ_BUFFER: what = "READ_BUFFER"; break;
- case UPDATE_BLOCK: what = "UPDATE_BLOCK"; break;
- case READ_LONG: what = "READ_LONG"; break;
- case WRITE_LONG: what = "WRITE_LONG"; break;
- case CHANGE_DEFINITION: what = "CHANGE_DEFINITION"; break;
- case WRITE_SAME: what = "WRITE_SAME"; break;
- case GPCMD_READ_SUBCHANNEL: what = "READ SUBCHANNEL"; break;
- case READ_TOC: what = "READ_TOC"; break;
- case GPCMD_READ_HEADER: what = "READ HEADER"; break;
- case GPCMD_PLAY_AUDIO_10: what = "PLAY AUDIO (10)"; break;
- case GPCMD_PLAY_AUDIO_MSF: what = "PLAY AUDIO MSF"; break;
- case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
- what = "GET EVENT/STATUS NOTIFICATION"; break;
- case GPCMD_PAUSE_RESUME: what = "PAUSE/RESUME"; break;
- case LOG_SELECT: what = "LOG_SELECT"; break;
- case LOG_SENSE: what = "LOG_SENSE"; break;
- case GPCMD_STOP_PLAY_SCAN: what = "STOP PLAY/SCAN"; break;
- case GPCMD_READ_DISC_INFO: what = "READ DISC INFORMATION"; break;
- case GPCMD_READ_TRACK_RZONE_INFO:
- what = "READ TRACK INFORMATION"; break;
- case GPCMD_RESERVE_RZONE_TRACK: what = "RESERVE TRACK"; break;
- case GPCMD_SEND_OPC: what = "SEND OPC"; break;
- case MODE_SELECT_10: what = "MODE_SELECT_10"; break;
- case GPCMD_REPAIR_RZONE_TRACK: what = "REPAIR TRACK"; break;
- case 0x59: what = "READ MASTER CUE"; break;
- case MODE_SENSE_10: what = "MODE_SENSE_10"; break;
- case GPCMD_CLOSE_TRACK: what = "CLOSE TRACK/SESSION"; break;
- case 0x5C: what = "READ BUFFER CAPACITY"; break;
- case 0x5D: what = "SEND CUE SHEET"; break;
- case GPCMD_BLANK: what = "BLANK"; break;
- case REPORT_LUNS: what = "REPORT LUNS"; break;
- case MOVE_MEDIUM: what = "MOVE_MEDIUM or PLAY AUDIO (12)"; break;
- case READ_12: what = "READ_12"; break;
- case WRITE_12: what = "WRITE_12"; break;
- case WRITE_VERIFY_12: what = "WRITE_VERIFY_12"; break;
- case SEARCH_HIGH_12: what = "SEARCH_HIGH_12"; break;
- case SEARCH_EQUAL_12: what = "SEARCH_EQUAL_12"; break;
- case SEARCH_LOW_12: what = "SEARCH_LOW_12"; break;
- case SEND_VOLUME_TAG: what = "SEND_VOLUME_TAG"; break;
- case READ_ELEMENT_STATUS: what = "READ_ELEMENT_STATUS"; break;
- case GPCMD_READ_CD_MSF: what = "READ CD MSF"; break;
- case GPCMD_SCAN: what = "SCAN"; break;
- case GPCMD_SET_SPEED: what = "SET CD SPEED"; break;
- case GPCMD_MECHANISM_STATUS: what = "MECHANISM STATUS"; break;
- case GPCMD_READ_CD: what = "READ CD"; break;
- case 0xE1: what = "WRITE CONTINUE"; break;
- case WRITE_LONG_2: what = "WRITE_LONG_2"; break;
- case VENDOR_CMND: what = "Realtek's vendor command"; break;
- default: what = "(unknown command)"; unknown_cmd = 1; break;
- }
-
- if (srb->cmnd[0] != TEST_UNIT_READY)
- RTSX_DEBUGP("Command %s (%d bytes)\n", what, srb->cmd_len);
-
- if (unknown_cmd) {
- RTSX_DEBUGP("");
- for (i = 0; i < srb->cmd_len && i < 16; i++)
- RTSX_DEBUGPN(" %02x", srb->cmnd[i]);
- RTSX_DEBUGPN("\n");
- }
-}
-
-void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type)
-{
- switch (sense_type) {
- case SENSE_TYPE_MEDIA_CHANGE:
- set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0);
- break;
-
- case SENSE_TYPE_MEDIA_NOT_PRESENT:
- set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0);
- break;
-
- case SENSE_TYPE_MEDIA_LBA_OVER_RANGE:
- set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0);
- break;
-
- case SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT:
- set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0);
- break;
-
- case SENSE_TYPE_MEDIA_WRITE_PROTECT:
- set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0);
- break;
-
- case SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR:
- set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0);
- break;
-
- case SENSE_TYPE_MEDIA_WRITE_ERR:
- set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0);
- break;
-
- case SENSE_TYPE_MEDIA_INVALID_CMD_FIELD:
- set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0,
- ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1);
- break;
-
- case SENSE_TYPE_FORMAT_IN_PROGRESS:
- set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 0, 0);
- break;
-
- case SENSE_TYPE_FORMAT_CMD_FAILED:
- set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0);
- break;
-
-#ifdef SUPPORT_MAGIC_GATE
- case SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB:
- set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0);
- break;
-
- case SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN:
- set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0);
- break;
-
- case SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM:
- set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0);
- break;
-
- case SENSE_TYPE_MG_WRITE_ERR:
- set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0);
- break;
-#endif
-
-#ifdef SUPPORT_SD_LOCK
- case SENSE_TYPE_MEDIA_READ_FORBIDDEN:
- set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x11, 0x13, 0, 0);
- break;
-#endif
-
- case SENSE_TYPE_NO_SENSE:
- default:
- set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0);
- break;
- }
-}
-
-void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, u8 sense_key,
- u32 info, u8 asc, u8 ascq, u8 sns_key_info0, u16 sns_key_info1)
-{
- struct sense_data_t *sense = &(chip->sense_buffer[lun]);
-
- sense->err_code = err_code;
- sense->sense_key = sense_key;
- sense->info[0] = (u8)(info >> 24);
- sense->info[1] = (u8)(info >> 16);
- sense->info[2] = (u8)(info >> 8);
- sense->info[3] = (u8)info;
-
- sense->ad_sense_len = sizeof(struct sense_data_t) - 8;
- sense->asc = asc;
- sense->ascq = ascq;
- if (sns_key_info0 != 0) {
- sense->sns_key_info[0] = SKSV | sns_key_info0;
- sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 8;
- sense->sns_key_info[2] = sns_key_info1 & 0x0f;
- }
-}
-
-static int test_unit_ready(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned int lun = SCSI_LUN(srb);
-
- if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- return TRANSPORT_FAILED;
- }
-
- if (!(CHK_BIT(chip->lun_mc, lun))) {
- SET_BIT(chip->lun_mc, lun);
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
- return TRANSPORT_FAILED;
- }
-
-#ifdef SUPPORT_SD_LOCK
- if (get_lun_card(chip, SCSI_LUN(srb)) == SD_CARD) {
- struct sd_info *sd_card = &(chip->sd_card);
- if (sd_card->sd_lock_notify) {
- sd_card->sd_lock_notify = 0;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
- return TRANSPORT_FAILED;
- } else if (sd_card->sd_lock_status & SD_LOCKED) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN);
- return TRANSPORT_FAILED;
- }
- }
-#endif
-
- return TRANSPORT_GOOD;
-}
-
-static unsigned char formatter_inquiry_str[20] = {
- 'M', 'E', 'M', 'O', 'R', 'Y', 'S', 'T', 'I', 'C', 'K',
-#ifdef SUPPORT_MAGIC_GATE
- '-', 'M', 'G', /* Byte[47:49] */
-#else
- 0x20, 0x20, 0x20, /* Byte[47:49] */
-#endif
-
-#ifdef SUPPORT_MAGIC_GATE
- 0x0B, /* Byte[50]: MG, MS, MSPro, MSXC */
-#else
- 0x09, /* Byte[50]: MS, MSPro, MSXC */
-#endif
- 0x00, /* Byte[51]: Category Specific Commands */
- 0x00, /* Byte[52]: Access Control and feature */
- 0x20, 0x20, 0x20, /* Byte[53:55] */
-};
-
-static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned int lun = SCSI_LUN(srb);
- char *inquiry_default = (char *)"Generic-xD/SD/M.S. 1.00 ";
- char *inquiry_sdms = (char *)"Generic-SD/MemoryStick 1.00 ";
- char *inquiry_sd = (char *)"Generic-SD/MMC 1.00 ";
- char *inquiry_ms = (char *)"Generic-MemoryStick 1.00 ";
- char *inquiry_string;
- unsigned char sendbytes;
- unsigned char *buf;
- u8 card = get_lun_card(chip, lun);
- int pro_formatter_flag = 0;
- unsigned char inquiry_buf[] = {
- QULIFIRE|DRCT_ACCESS_DEV,
- RMB_DISC|0x0D,
- 0x00,
- 0x01,
- 0x1f,
- 0x02,
- 0,
- REL_ADR|WBUS_32|WBUS_16|SYNC|LINKED|CMD_QUE|SFT_RE,
- };
-
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
- if (chip->lun2card[lun] == SD_CARD)
- inquiry_string = inquiry_sd;
- else
- inquiry_string = inquiry_ms;
-
- } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) {
- inquiry_string = inquiry_sdms;
- } else {
- inquiry_string = inquiry_default;
- }
-
- buf = vmalloc(scsi_bufflen(srb));
- if (buf == NULL)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
-#ifdef SUPPORT_MAGIC_GATE
- if ((chip->mspro_formatter_enable) &&
- (chip->lun2card[lun] & MS_CARD))
-#else
- if (chip->mspro_formatter_enable)
-#endif
- {
- if (!card || (card == MS_CARD))
- pro_formatter_flag = 1;
- }
-
- if (pro_formatter_flag) {
- if (scsi_bufflen(srb) < 56)
- sendbytes = (unsigned char)(scsi_bufflen(srb));
- else
- sendbytes = 56;
-
- } else {
- if (scsi_bufflen(srb) < 36)
- sendbytes = (unsigned char)(scsi_bufflen(srb));
- else
- sendbytes = 36;
- }
-
- if (sendbytes > 8) {
- memcpy(buf, inquiry_buf, 8);
- memcpy(buf + 8, inquiry_string, sendbytes - 8);
- if (pro_formatter_flag) {
- /* Additional Length */
- buf[4] = 0x33;
- }
- } else {
- memcpy(buf, inquiry_buf, sendbytes);
- }
-
- if (pro_formatter_flag) {
- if (sendbytes > 36)
- memcpy(buf + 36, formatter_inquiry_str, sendbytes - 36);
- }
-
- scsi_set_resid(srb, 0);
-
- rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb);
- vfree(buf);
-
- return TRANSPORT_GOOD;
-}
-
-
-static int start_stop_unit(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned int lun = SCSI_LUN(srb);
-
- scsi_set_resid(srb, scsi_bufflen(srb));
-
- if (srb->cmnd[1] == 1)
- return TRANSPORT_GOOD;
-
- switch (srb->cmnd[0x4]) {
- case STOP_MEDIUM:
- /* Media disabled */
- return TRANSPORT_GOOD;
-
- case UNLOAD_MEDIUM:
- /* Media shall be unload */
- if (check_card_ready(chip, lun))
- eject_card(chip, lun);
- return TRANSPORT_GOOD;
-
- case MAKE_MEDIUM_READY:
- case LOAD_MEDIUM:
- if (check_card_ready(chip, lun)) {
- return TRANSPORT_GOOD;
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- break;
- }
-
- TRACE_RET(chip, TRANSPORT_ERROR);
-}
-
-
-static int allow_medium_removal(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int prevent;
-
- prevent = srb->cmnd[4] & 0x1;
-
- scsi_set_resid(srb, 0);
-
- if (prevent) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- return TRANSPORT_GOOD;
-}
-
-
-static int request_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct sense_data_t *sense;
- unsigned int lun = SCSI_LUN(srb);
- struct ms_info *ms_card = &(chip->ms_card);
- unsigned char *tmp, *buf;
-
- sense = &(chip->sense_buffer[lun]);
-
- if ((get_lun_card(chip, lun) == MS_CARD) && ms_card->pro_under_formatting) {
- if (ms_card->format_status == FORMAT_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
- ms_card->pro_under_formatting = 0;
- ms_card->progress = 0;
- } else if (ms_card->format_status == FORMAT_IN_PROGRESS) {
- /* Logical Unit Not Ready Format in Progress */
- set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04,
- 0, (u16)(ms_card->progress));
- } else {
- /* Format Command Failed */
- set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED);
- ms_card->pro_under_formatting = 0;
- ms_card->progress = 0;
- }
-
- rtsx_set_stat(chip, RTSX_STAT_RUN);
- }
-
- buf = vmalloc(scsi_bufflen(srb));
- if (buf == NULL)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- tmp = (unsigned char *)sense;
- memcpy(buf, tmp, scsi_bufflen(srb));
-
- rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb);
- vfree(buf);
-
- scsi_set_resid(srb, 0);
- /* Reset Sense Data */
- set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
- return TRANSPORT_GOOD;
-}
-
-static void ms_mode_sense(struct rtsx_chip *chip, u8 cmd,
- int lun, u8 *buf, int buf_len)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- int sys_info_offset;
- int data_size = buf_len;
- int support_format = 0;
- int i = 0;
-
- if (cmd == MODE_SENSE) {
- sys_info_offset = 8;
- if (data_size > 0x68)
- data_size = 0x68;
-
- buf[i++] = 0x67; /* Mode Data Length */
- } else {
- sys_info_offset = 12;
- if (data_size > 0x6C)
- data_size = 0x6C;
-
- buf[i++] = 0x00; /* Mode Data Length (MSB) */
- buf[i++] = 0x6A; /* Mode Data Length (LSB) */
- }
-
- /* Medium Type Code */
- if (check_card_ready(chip, lun)) {
- if (CHK_MSXC(ms_card)) {
- support_format = 1;
- buf[i++] = 0x40;
- } else if (CHK_MSPRO(ms_card)) {
- support_format = 1;
- buf[i++] = 0x20;
- } else {
- buf[i++] = 0x10;
- }
-
- /* WP */
- if (check_card_wp(chip, lun))
- buf[i++] = 0x80;
- else
- buf[i++] = 0x00;
-
- } else {
- buf[i++] = 0x00; /* MediaType */
- buf[i++] = 0x00; /* WP */
- }
-
- buf[i++] = 0x00; /* Reserved */
-
- if (cmd == MODE_SENSE_10) {
- buf[i++] = 0x00; /* Reserved */
- buf[i++] = 0x00; /* Block descriptor length(MSB) */
- buf[i++] = 0x00; /* Block descriptor length(LSB) */
-
- /* The Following Data is the content of "Page 0x20" */
- if (data_size >= 9)
- buf[i++] = 0x20; /* Page Code */
- if (data_size >= 10)
- buf[i++] = 0x62; /* Page Length */
- if (data_size >= 11)
- buf[i++] = 0x00; /* No Access Control */
- if (data_size >= 12) {
- if (support_format)
- buf[i++] = 0xC0; /* SF, SGM */
- else
- buf[i++] = 0x00;
- }
- } else {
- /* The Following Data is the content of "Page 0x20" */
- if (data_size >= 5)
- buf[i++] = 0x20; /* Page Code */
- if (data_size >= 6)
- buf[i++] = 0x62; /* Page Length */
- if (data_size >= 7)
- buf[i++] = 0x00; /* No Access Control */
- if (data_size >= 8) {
- if (support_format)
- buf[i++] = 0xC0; /* SF, SGM */
- else
- buf[i++] = 0x00;
- }
- }
-
- if (data_size > sys_info_offset) {
- /* 96 Bytes Attribute Data */
- int len = data_size - sys_info_offset;
- len = (len < 96) ? len : 96;
-
- memcpy(buf + sys_info_offset, ms_card->raw_sys_info, len);
- }
-}
-
-static int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned int lun = SCSI_LUN(srb);
- unsigned int dataSize;
- int status;
- int pro_formatter_flag;
- unsigned char pageCode, *buf;
- u8 card = get_lun_card(chip, lun);
-
-#ifndef SUPPORT_MAGIC_GATE
- if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- scsi_set_resid(srb, scsi_bufflen(srb));
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-#endif
-
- pro_formatter_flag = 0;
- dataSize = 8;
-#ifdef SUPPORT_MAGIC_GATE
- if ((chip->lun2card[lun] & MS_CARD)) {
- if (!card || (card == MS_CARD)) {
- dataSize = 108;
- if (chip->mspro_formatter_enable)
- pro_formatter_flag = 1;
- }
- }
-#else
- if (card == MS_CARD) {
- if (chip->mspro_formatter_enable) {
- pro_formatter_flag = 1;
- dataSize = 108;
- }
- }
-#endif
-
- buf = kmalloc(dataSize, GFP_KERNEL);
- if (buf == NULL)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- pageCode = srb->cmnd[2] & 0x3f;
-
- if ((pageCode == 0x3F) || (pageCode == 0x1C) ||
- (pageCode == 0x00) ||
- (pro_formatter_flag && (pageCode == 0x20))) {
- if (srb->cmnd[0] == MODE_SENSE) {
- if ((pageCode == 0x3F) || (pageCode == 0x20)) {
- ms_mode_sense(chip, srb->cmnd[0],
- lun, buf, dataSize);
- } else {
- dataSize = 4;
- buf[0] = 0x03;
- buf[1] = 0x00;
- if (check_card_wp(chip, lun))
- buf[2] = 0x80;
- else
- buf[2] = 0x00;
-
- buf[3] = 0x00;
- }
- } else {
- if ((pageCode == 0x3F) || (pageCode == 0x20)) {
- ms_mode_sense(chip, srb->cmnd[0],
- lun, buf, dataSize);
- } else {
- dataSize = 8;
- buf[0] = 0x00;
- buf[1] = 0x06;
- buf[2] = 0x00;
- if (check_card_wp(chip, lun))
- buf[3] = 0x80;
- else
- buf[3] = 0x00;
- buf[4] = 0x00;
- buf[5] = 0x00;
- buf[6] = 0x00;
- buf[7] = 0x00;
- }
- }
- status = TRANSPORT_GOOD;
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- scsi_set_resid(srb, scsi_bufflen(srb));
- status = TRANSPORT_FAILED;
- }
-
- if (status == TRANSPORT_GOOD) {
- unsigned int len = min(scsi_bufflen(srb), dataSize);
- rtsx_stor_set_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
- }
- kfree(buf);
-
- return status;
-}
-
-static int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
-#ifdef SUPPORT_SD_LOCK
- struct sd_info *sd_card = &(chip->sd_card);
-#endif
- unsigned int lun = SCSI_LUN(srb);
- int retval;
- u32 start_sec;
- u16 sec_cnt;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- if (!check_card_ready(chip, lun) || (get_card_size(chip, lun) == 0)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (!(CHK_BIT(chip->lun_mc, lun))) {
- SET_BIT(chip->lun_mc, lun);
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
- return TRANSPORT_FAILED;
- }
-
-#ifdef SUPPORT_SD_LOCK
- if (sd_card->sd_erase_status) {
- /* Accessing to any card is forbidden
- * until the erase procedure of SD is completed
- */
- RTSX_DEBUGP("SD card being erased!\n");
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (get_lun_card(chip, lun) == SD_CARD) {
- if (sd_card->sd_lock_status & SD_LOCKED) {
- RTSX_DEBUGP("SD card locked!\n");
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
-#endif
-
- if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) {
- start_sec = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) |
- ((u32)srb->cmnd[4] << 8) | ((u32)srb->cmnd[5]);
- sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
- } else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) {
- start_sec = ((u32)(srb->cmnd[1] & 0x1F) << 16) |
- ((u32)srb->cmnd[2] << 8) | ((u32)srb->cmnd[3]);
- sec_cnt = srb->cmnd[4];
- } else if ((srb->cmnd[0] == VENDOR_CMND) && (srb->cmnd[1] == SCSI_APP_CMD) &&
- ((srb->cmnd[2] == PP_READ10) || (srb->cmnd[2] == PP_WRITE10))) {
- start_sec = ((u32)srb->cmnd[4] << 24) | ((u32)srb->cmnd[5] << 16) |
- ((u32)srb->cmnd[6] << 8) | ((u32)srb->cmnd[7]);
- sec_cnt = ((u16)(srb->cmnd[9]) << 8) | srb->cmnd[10];
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- /* In some test, we will receive a start_sec like 0xFFFFFFFF.
- * In this situation, start_sec + sec_cnt will overflow, so we
- * need to judge start_sec at first
- */
- if ((start_sec > get_card_size(chip, lun)) ||
- ((start_sec + sec_cnt) > get_card_size(chip, lun))) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LBA_OVER_RANGE);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (sec_cnt == 0) {
- scsi_set_resid(srb, 0);
- return TRANSPORT_GOOD;
- }
-
- if (chip->rw_fail_cnt[lun] == 3) {
- RTSX_DEBUGP("read/write fail three times in succession\n");
- if (srb->sc_data_direction == DMA_FROM_DEVICE)
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- else
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
-
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (srb->sc_data_direction == DMA_TO_DEVICE) {
- if (check_card_wp(chip, lun)) {
- RTSX_DEBUGP("Write protected card!\n");
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- if (CHECK_PID(chip, 0x5209) && chip->max_payload) {
- u8 val = 0x10 | (chip->max_payload << 5);
- retval = rtsx_write_cfg_dw(chip, 0, 0x78, 0xFF, val);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_ERROR);
- }
- }
-
- retval = card_rw(srb, chip, start_sec, sec_cnt);
- if (retval != STATUS_SUCCESS) {
- if (chip->need_release & chip->lun2card[lun]) {
- chip->rw_fail_cnt[lun] = 0;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- } else {
- chip->rw_fail_cnt[lun]++;
- if (srb->sc_data_direction == DMA_FROM_DEVICE)
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- else
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
- }
- retval = TRANSPORT_FAILED;
- TRACE_GOTO(chip, Exit);
- } else {
- chip->rw_fail_cnt[lun] = 0;
- retval = TRANSPORT_GOOD;
- }
-
- scsi_set_resid(srb, 0);
-
-Exit:
- if (srb->sc_data_direction == DMA_TO_DEVICE) {
- if (CHECK_PID(chip, 0x5209) && chip->max_payload) {
- retval = rtsx_write_cfg_dw(chip, 0, 0x78, 0xFF, 0x10);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_ERROR);
- }
- }
-
- return retval;
-}
-
-static int read_format_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned char *buf;
- unsigned int lun = SCSI_LUN(srb);
- unsigned int buf_len;
- u8 card = get_lun_card(chip, lun);
- u32 card_size;
- int desc_cnt;
- int i = 0;
-
- if (!check_card_ready(chip, lun)) {
- if (!chip->mspro_formatter_enable) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
-
- buf_len = (scsi_bufflen(srb) > 12) ? 0x14 : 12;
-
- buf = kmalloc(buf_len, GFP_KERNEL);
- if (buf == NULL)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- buf[i++] = 0;
- buf[i++] = 0;
- buf[i++] = 0;
-
- /* Capacity List Length */
- if ((buf_len > 12) && chip->mspro_formatter_enable &&
- (chip->lun2card[lun] & MS_CARD) &&
- (!card || (card == MS_CARD))) {
- buf[i++] = 0x10;
- desc_cnt = 2;
- } else {
- buf[i++] = 0x08;
- desc_cnt = 1;
- }
-
- while (desc_cnt) {
- if (check_card_ready(chip, lun)) {
- card_size = get_card_size(chip, lun);
- buf[i++] = (unsigned char)(card_size >> 24);
- buf[i++] = (unsigned char)(card_size >> 16);
- buf[i++] = (unsigned char)(card_size >> 8);
- buf[i++] = (unsigned char)card_size;
-
- if (desc_cnt == 2)
- buf[i++] = 2;
- else
- buf[i++] = 0;
- } else {
- buf[i++] = 0xFF;
- buf[i++] = 0xFF;
- buf[i++] = 0xFF;
- buf[i++] = 0xFF;
-
- if (desc_cnt == 2)
- buf[i++] = 3;
- else
- buf[i++] = 0;
- }
-
- buf[i++] = 0x00;
- buf[i++] = 0x02;
- buf[i++] = 0x00;
-
- desc_cnt--;
- }
-
- buf_len = min(scsi_bufflen(srb), buf_len);
- rtsx_stor_set_xfer_buf(buf, buf_len, srb);
- kfree(buf);
-
- scsi_set_resid(srb, scsi_bufflen(srb) - buf_len);
-
- return TRANSPORT_GOOD;
-}
-
-static int read_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned char *buf;
- unsigned int lun = SCSI_LUN(srb);
- u32 card_size;
-
- if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (!(CHK_BIT(chip->lun_mc, lun))) {
- SET_BIT(chip->lun_mc, lun);
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
- return TRANSPORT_FAILED;
- }
-
- buf = kmalloc(8, GFP_KERNEL);
- if (buf == NULL)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- card_size = get_card_size(chip, lun);
- buf[0] = (unsigned char)((card_size - 1) >> 24);
- buf[1] = (unsigned char)((card_size - 1) >> 16);
- buf[2] = (unsigned char)((card_size - 1) >> 8);
- buf[3] = (unsigned char)(card_size - 1);
-
- buf[4] = 0x00;
- buf[5] = 0x00;
- buf[6] = 0x02;
- buf[7] = 0x00;
-
- rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb);
- kfree(buf);
-
- scsi_set_resid(srb, 0);
-
- return TRANSPORT_GOOD;
-}
-
-static int read_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned short len, i;
- int retval;
- u8 *buf;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
-
- buf = (u8 *)vmalloc(len);
- if (!buf)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- retval = rtsx_force_power_on(chip, SSC_PDCTL);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- for (i = 0; i < len; i++) {
- retval = spi_read_eeprom(chip, i, buf + i);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
-
- len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len);
- rtsx_stor_set_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
-
- vfree(buf);
-
- return TRANSPORT_GOOD;
-}
-
-static int write_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned short len, i;
- int retval;
- u8 *buf;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
-
- retval = rtsx_force_power_on(chip, SSC_PDCTL);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (len == 511) {
- retval = spi_erase_eeprom_chip(chip);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- } else {
- len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len);
- buf = (u8 *)vmalloc(len);
- if (buf == NULL)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- rtsx_stor_get_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
-
- for (i = 0; i < len; i++) {
- retval = spi_write_eeprom(chip, i, buf[i]);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
-
- vfree(buf);
- }
-
- return TRANSPORT_GOOD;
-}
-
-static int read_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned short addr, len, i;
- int retval;
- u8 *buf;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3];
- len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
-
- if (addr < 0xFC00) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- buf = (u8 *)vmalloc(len);
- if (!buf)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- retval = rtsx_force_power_on(chip, SSC_PDCTL);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- for (i = 0; i < len; i++) {
- retval = rtsx_read_register(chip, addr + i, buf + i);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
-
- len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len);
- rtsx_stor_set_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
-
- vfree(buf);
-
- return TRANSPORT_GOOD;
-}
-
-static int write_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned short addr, len, i;
- int retval;
- u8 *buf;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3];
- len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
-
- if (addr < 0xFC00) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len);
- buf = (u8 *)vmalloc(len);
- if (buf == NULL)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- rtsx_stor_get_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
-
- retval = rtsx_force_power_on(chip, SSC_PDCTL);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- for (i = 0; i < len; i++) {
- retval = rtsx_write_register(chip, addr + i, 0xFF, buf[i]);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
-
- vfree(buf);
-
- return TRANSPORT_GOOD;
-}
-
-static int get_sd_csd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- unsigned int lun = SCSI_LUN(srb);
-
- if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (get_lun_card(chip, lun) != SD_CARD) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- scsi_set_resid(srb, 0);
- rtsx_stor_set_xfer_buf(sd_card->raw_csd, scsi_bufflen(srb), srb);
-
- return TRANSPORT_GOOD;
-}
-
-static int toggle_gpio_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- u8 gpio = srb->cmnd[2];
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- if (gpio > 3)
- gpio = 1;
- toggle_gpio(chip, gpio);
-
- return TRANSPORT_GOOD;
-}
-
-#ifdef _MSG_TRACE
-static int trace_msg_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned char *ptr, *buf = NULL;
- int i, msg_cnt;
- u8 clear;
- unsigned int buf_len;
-
- buf_len = 4 + ((2 + MSG_FUNC_LEN + MSG_FILE_LEN + TIME_VAL_LEN) * TRACE_ITEM_CNT);
-
- if ((scsi_bufflen(srb) < buf_len) || (scsi_sglist(srb) == NULL)) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- clear = srb->cmnd[2];
-
- buf = (unsigned char *)vmalloc(scsi_bufflen(srb));
- if (buf == NULL)
- TRACE_RET(chip, TRANSPORT_ERROR);
- ptr = buf;
-
- if (chip->trace_msg[chip->msg_idx].valid)
- msg_cnt = TRACE_ITEM_CNT;
- else
- msg_cnt = chip->msg_idx;
-
- *(ptr++) = (u8)(msg_cnt >> 24);
- *(ptr++) = (u8)(msg_cnt >> 16);
- *(ptr++) = (u8)(msg_cnt >> 8);
- *(ptr++) = (u8)msg_cnt;
- RTSX_DEBUGP("Trace message count is %d\n", msg_cnt);
-
- for (i = 1; i <= msg_cnt; i++) {
- int j, idx;
-
- idx = chip->msg_idx - i;
- if (idx < 0)
- idx += TRACE_ITEM_CNT;
-
- *(ptr++) = (u8)(chip->trace_msg[idx].line >> 8);
- *(ptr++) = (u8)(chip->trace_msg[idx].line);
- for (j = 0; j < MSG_FUNC_LEN; j++)
- *(ptr++) = chip->trace_msg[idx].func[j];
-
- for (j = 0; j < MSG_FILE_LEN; j++)
- *(ptr++) = chip->trace_msg[idx].file[j];
-
- for (j = 0; j < TIME_VAL_LEN; j++)
- *(ptr++) = chip->trace_msg[idx].timeval_buf[j];
- }
-
- rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb);
- vfree(buf);
-
- if (clear) {
- chip->msg_idx = 0;
- for (i = 0; i < TRACE_ITEM_CNT; i++)
- chip->trace_msg[i].valid = 0;
- }
-
- scsi_set_resid(srb, 0);
- return TRANSPORT_GOOD;
-}
-#endif
-
-static int read_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- u8 addr, buf[4];
- u32 val;
- unsigned int len;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- addr = srb->cmnd[4];
-
- val = rtsx_readl(chip, addr);
- RTSX_DEBUGP("Host register (0x%x): 0x%x\n", addr, val);
-
- buf[0] = (u8)(val >> 24);
- buf[1] = (u8)(val >> 16);
- buf[2] = (u8)(val >> 8);
- buf[3] = (u8)val;
-
- len = min(scsi_bufflen(srb), (unsigned int)4);
- rtsx_stor_set_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
-
- return TRANSPORT_GOOD;
-}
-
-static int write_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- u8 addr, buf[4];
- u32 val;
- unsigned int len;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- addr = srb->cmnd[4];
-
- len = min(scsi_bufflen(srb), (unsigned int)4);
- rtsx_stor_get_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
-
- val = ((u32)buf[0] << 24) | ((u32)buf[1] << 16) | ((u32)buf[2] << 8) | buf[3];
-
- rtsx_writel(chip, addr, val);
-
- return TRANSPORT_GOOD;
-}
-
-static int set_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned lun = SCSI_LUN(srb);
-
- if (srb->cmnd[3] == 1) {
- /* Variable Clock */
- struct xd_info *xd_card = &(chip->xd_card);
- struct sd_info *sd_card = &(chip->sd_card);
- struct ms_info *ms_card = &(chip->ms_card);
-
- switch (srb->cmnd[4]) {
- case XD_CARD:
- xd_card->xd_clock = srb->cmnd[5];
- break;
-
- case SD_CARD:
- sd_card->sd_clock = srb->cmnd[5];
- break;
-
- case MS_CARD:
- ms_card->ms_clock = srb->cmnd[5];
- break;
-
- default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- } else if (srb->cmnd[3] == 2) {
- if (srb->cmnd[4]) {
- chip->blink_led = 1;
- } else {
- int retval;
-
- chip->blink_led = 0;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- retval = rtsx_force_power_on(chip, SSC_PDCTL);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- turn_off_led(chip, LED_GPIO);
- }
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- return TRANSPORT_GOOD;
-}
-
-static int get_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned int lun = SCSI_LUN(srb);
-
- if (srb->cmnd[3] == 1) {
- struct xd_info *xd_card = &(chip->xd_card);
- struct sd_info *sd_card = &(chip->sd_card);
- struct ms_info *ms_card = &(chip->ms_card);
- u8 tmp;
-
- switch (srb->cmnd[4]) {
- case XD_CARD:
- tmp = (u8)(xd_card->xd_clock);
- break;
-
- case SD_CARD:
- tmp = (u8)(sd_card->sd_clock);
- break;
-
- case MS_CARD:
- tmp = (u8)(ms_card->ms_clock);
- break;
-
- default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- rtsx_stor_set_xfer_buf(&tmp, 1, srb);
- } else if (srb->cmnd[3] == 2) {
- u8 tmp = chip->blink_led;
- rtsx_stor_set_xfer_buf(&tmp, 1, srb);
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- return TRANSPORT_GOOD;
-}
-
-static int dma_access_ring_buffer(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int retval;
- unsigned int lun = SCSI_LUN(srb);
- u16 len;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- len = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
- len = min(len, (u16)scsi_bufflen(srb));
-
- if (srb->sc_data_direction == DMA_FROM_DEVICE)
- RTSX_DEBUGP("Read from device\n");
- else
- RTSX_DEBUGP("Write to device\n");
-
- retval = rtsx_transfer_data(chip, 0, scsi_sglist(srb), len,
- scsi_sg_count(srb), srb->sc_data_direction, 1000);
- if (retval < 0) {
- if (srb->sc_data_direction == DMA_FROM_DEVICE)
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- else
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
-
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- scsi_set_resid(srb, 0);
-
- return TRANSPORT_GOOD;
-}
-
-static int get_dev_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- struct ms_info *ms_card = &(chip->ms_card);
- int buf_len;
- unsigned int lun = SCSI_LUN(srb);
- u8 card = get_lun_card(chip, lun);
- u8 status[32];
-#ifdef SUPPORT_OCP
- u8 oc_now_mask = 0, oc_ever_mask = 0;
-#endif
-
- memset(status, 0, 32);
-
- status[0] = (u8)(chip->product_id);
- status[1] = chip->ic_version;
-
- if (chip->auto_delink_en)
- status[2] = 0x10;
- else
- status[2] = 0x00;
-
- status[3] = 20;
- status[4] = 10;
- status[5] = 05;
- status[6] = 21;
-
- if (chip->card_wp)
- status[7] = 0x20;
- else
- status[7] = 0x00;
-
-#ifdef SUPPORT_OCP
- status[8] = 0;
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (chip->lun2card[lun] == MS_CARD)) {
- oc_now_mask = MS_OC_NOW;
- oc_ever_mask = MS_OC_EVER;
- } else {
- oc_now_mask = SD_OC_NOW;
- oc_ever_mask = SD_OC_EVER;
- }
-
- if (chip->ocp_stat & oc_now_mask)
- status[8] |= 0x02;
-
- if (chip->ocp_stat & oc_ever_mask)
- status[8] |= 0x01;
-#endif
-
- if (card == SD_CARD) {
- if (CHK_SD(sd_card)) {
- if (CHK_SD_HCXC(sd_card)) {
- if (sd_card->capacity > 0x4000000)
- status[0x0E] = 0x02;
- else
- status[0x0E] = 0x01;
- } else {
- status[0x0E] = 0x00;
- }
-
- if (CHK_SD_SDR104(sd_card))
- status[0x0F] = 0x03;
- else if (CHK_SD_DDR50(sd_card))
- status[0x0F] = 0x04;
- else if (CHK_SD_SDR50(sd_card))
- status[0x0F] = 0x02;
- else if (CHK_SD_HS(sd_card))
- status[0x0F] = 0x01;
- else
- status[0x0F] = 0x00;
- } else {
- if (CHK_MMC_SECTOR_MODE(sd_card))
- status[0x0E] = 0x01;
- else
- status[0x0E] = 0x00;
-
- if (CHK_MMC_DDR52(sd_card))
- status[0x0F] = 0x03;
- else if (CHK_MMC_52M(sd_card))
- status[0x0F] = 0x02;
- else if (CHK_MMC_26M(sd_card))
- status[0x0F] = 0x01;
- else
- status[0x0F] = 0x00;
- }
- } else if (card == MS_CARD) {
- if (CHK_MSPRO(ms_card)) {
- if (CHK_MSXC(ms_card))
- status[0x0E] = 0x01;
- else
- status[0x0E] = 0x00;
-
- if (CHK_HG8BIT(ms_card))
- status[0x0F] = 0x01;
- else
- status[0x0F] = 0x00;
- }
- }
-
-#ifdef SUPPORT_SD_LOCK
- if (card == SD_CARD) {
- status[0x17] = 0x80;
- if (sd_card->sd_erase_status)
- status[0x17] |= 0x01;
- if (sd_card->sd_lock_status & SD_LOCKED) {
- status[0x17] |= 0x02;
- status[0x07] |= 0x40;
- }
- if (sd_card->sd_lock_status & SD_PWD_EXIST)
- status[0x17] |= 0x04;
- } else {
- status[0x17] = 0x00;
- }
-
- RTSX_DEBUGP("status[0x17] = 0x%x\n", status[0x17]);
-#endif
-
- status[0x18] = 0x8A;
- status[0x1A] = 0x28;
-#ifdef SUPPORT_SD_LOCK
- status[0x1F] = 0x01;
-#endif
-
- buf_len = min(scsi_bufflen(srb), (unsigned int)sizeof(status));
- rtsx_stor_set_xfer_buf(status, buf_len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - buf_len);
-
- return TRANSPORT_GOOD;
-}
-
-static int set_chip_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int phy_debug_mode;
- int retval;
- u16 reg;
-
- if (!CHECK_PID(chip, 0x5208)) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- phy_debug_mode = (int)(srb->cmnd[3]);
-
- if (phy_debug_mode) {
- chip->phy_debug_mode = 1;
- retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- rtsx_disable_bus_int(chip);
-
- retval = rtsx_read_phy_register(chip, 0x1C, &reg);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- reg |= 0x0001;
- retval = rtsx_write_phy_register(chip, 0x1C, reg);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
- } else {
- chip->phy_debug_mode = 0;
- retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0x77);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- rtsx_enable_bus_int(chip);
-
- retval = rtsx_read_phy_register(chip, 0x1C, &reg);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- reg &= 0xFFFE;
- retval = rtsx_write_phy_register(chip, 0x1C, reg);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- return TRANSPORT_GOOD;
-}
-
-static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int retval = STATUS_SUCCESS;
- unsigned int lun = SCSI_LUN(srb);
- u8 cmd_type, mask, value, idx;
- u16 addr;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- switch (srb->cmnd[3]) {
- case INIT_BATCHCMD:
- rtsx_init_cmd(chip);
- break;
-
- case ADD_BATCHCMD:
- cmd_type = srb->cmnd[4];
- if (cmd_type > 2) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- addr = (srb->cmnd[5] << 8) | srb->cmnd[6];
- mask = srb->cmnd[7];
- value = srb->cmnd[8];
- rtsx_add_cmd(chip, cmd_type, addr, mask, value);
- break;
-
- case SEND_BATCHCMD:
- retval = rtsx_send_cmd(chip, 0, 1000);
- break;
-
- case GET_BATCHRSP:
- idx = srb->cmnd[4];
- value = *(rtsx_get_cmd_data(chip) + idx);
- if (scsi_bufflen(srb) < 1) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- rtsx_stor_set_xfer_buf(&value, 1, srb);
- scsi_set_resid(srb, 0);
- break;
-
- default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- return TRANSPORT_GOOD;
-}
-
-static int suit_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int result;
-
- switch (srb->cmnd[3]) {
- case INIT_BATCHCMD:
- case ADD_BATCHCMD:
- case SEND_BATCHCMD:
- case GET_BATCHRSP:
- result = rw_mem_cmd_buf(srb, chip);
- break;
- default:
- result = TRANSPORT_ERROR;
- }
-
- return result;
-}
-
-static int read_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned short addr, len, i;
- int retval;
- u8 *buf;
- u16 val;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
- len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7];
-
- if (len % 2)
- len -= len % 2;
-
- if (len) {
- buf = (u8 *)vmalloc(len);
- if (!buf)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- retval = rtsx_force_power_on(chip, SSC_PDCTL);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- for (i = 0; i < len / 2; i++) {
- retval = rtsx_read_phy_register(chip, addr + i, &val);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- buf[2*i] = (u8)(val >> 8);
- buf[2*i+1] = (u8)val;
- }
-
- len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len);
- rtsx_stor_set_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
-
- vfree(buf);
- }
-
- return TRANSPORT_GOOD;
-}
-
-static int write_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned short addr, len, i;
- int retval;
- u8 *buf;
- u16 val;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
- len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7];
-
- if (len % 2)
- len -= len % 2;
-
- if (len) {
- len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len);
-
- buf = (u8 *)vmalloc(len);
- if (buf == NULL)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- rtsx_stor_get_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
-
- retval = rtsx_force_power_on(chip, SSC_PDCTL);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- for (i = 0; i < len / 2; i++) {
- val = ((u16)buf[2*i] << 8) | buf[2*i+1];
- retval = rtsx_write_phy_register(chip, addr + i, val);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
-
- vfree(buf);
- }
-
- return TRANSPORT_GOOD;
-}
-
-static int erase_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned short addr;
- int retval;
- u8 mode;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- retval = rtsx_force_power_on(chip, SSC_PDCTL);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- mode = srb->cmnd[3];
- addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
-
- if (mode == 0) {
- retval = spi_erase_eeprom_chip(chip);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- } else if (mode == 1) {
- retval = spi_erase_eeprom_byte(chip, addr);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- } else {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- return TRANSPORT_GOOD;
-}
-
-static int read_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned short addr, len, i;
- int retval;
- u8 *buf;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
- len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7];
-
- buf = (u8 *)vmalloc(len);
- if (!buf)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- retval = rtsx_force_power_on(chip, SSC_PDCTL);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- for (i = 0; i < len; i++) {
- retval = spi_read_eeprom(chip, addr + i, buf + i);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
-
- len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len);
- rtsx_stor_set_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
-
- vfree(buf);
-
- return TRANSPORT_GOOD;
-}
-
-static int write_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned short addr, len, i;
- int retval;
- u8 *buf;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
- len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7];
-
- len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len);
- buf = (u8 *)vmalloc(len);
- if (buf == NULL)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- rtsx_stor_get_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
-
- retval = rtsx_force_power_on(chip, SSC_PDCTL);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- for (i = 0; i < len; i++) {
- retval = spi_write_eeprom(chip, addr + i, buf[i]);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
-
- vfree(buf);
-
- return TRANSPORT_GOOD;
-}
-
-static int read_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int retval;
- u8 addr, len, i;
- u8 *buf;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- addr = srb->cmnd[4];
- len = srb->cmnd[5];
-
- buf = (u8 *)vmalloc(len);
- if (!buf)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- retval = rtsx_force_power_on(chip, SSC_PDCTL);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- for (i = 0; i < len; i++) {
- retval = rtsx_read_efuse(chip, addr + i, buf + i);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
-
- len = (u8)min(scsi_bufflen(srb), (unsigned int)len);
- rtsx_stor_set_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
-
- vfree(buf);
-
- return TRANSPORT_GOOD;
-}
-
-static int write_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int retval, result = TRANSPORT_GOOD;
- u16 val;
- u8 addr, len, i;
- u8 *buf;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- addr = srb->cmnd[4];
- len = srb->cmnd[5];
-
- len = (u8)min(scsi_bufflen(srb), (unsigned int)len);
- buf = (u8 *)vmalloc(len);
- if (buf == NULL)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- rtsx_stor_get_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
-
- retval = rtsx_force_power_on(chip, SSC_PDCTL);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- TRACE_RET(chip, TRANSPORT_ERROR);
- }
-
- if (chip->asic_code) {
- retval = rtsx_read_phy_register(chip, 0x08, &val);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- TRACE_RET(chip, TRANSPORT_ERROR);
- }
-
- retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- TRACE_RET(chip, TRANSPORT_ERROR);
- }
-
- wait_timeout(600);
-
- retval = rtsx_write_phy_register(chip, 0x08, 0x4C00 | chip->phy_voltage);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- TRACE_RET(chip, TRANSPORT_ERROR);
- }
-
- retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- TRACE_RET(chip, TRANSPORT_ERROR);
- }
-
- wait_timeout(600);
- }
-
- retval = card_power_on(chip, SPI_CARD);
- if (retval != STATUS_SUCCESS) {
- vfree(buf);
- TRACE_RET(chip, TRANSPORT_ERROR);
- }
-
- wait_timeout(50);
-
- for (i = 0; i < len; i++) {
- retval = rtsx_write_efuse(chip, addr + i, buf[i]);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- result = TRANSPORT_FAILED;
- TRACE_GOTO(chip, Exit);
- }
- }
-
-Exit:
- vfree(buf);
-
- retval = card_power_off(chip, SPI_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- if (chip->asic_code) {
- retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- wait_timeout(600);
-
- retval = rtsx_write_phy_register(chip, 0x08, val);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_ERROR);
- }
-
- return result;
-}
-
-static int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int retval;
- u8 func, func_max;
- u16 addr, len;
- u8 *buf;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- func = srb->cmnd[3];
- addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
- len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7];
-
- RTSX_DEBUGP("%s: func = %d, addr = 0x%x, len = %d\n", __func__, func, addr, len);
-
- if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip))
- func_max = 1;
- else
- func_max = 0;
-
- if (func > func_max) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- buf = (u8 *)vmalloc(len);
- if (!buf)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- retval = rtsx_read_cfg_seq(chip, func, addr, buf, len);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- vfree(buf);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- len = (u16)min(scsi_bufflen(srb), (unsigned int)len);
- rtsx_stor_set_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
-
- vfree(buf);
-
- return TRANSPORT_GOOD;
-}
-
-static int write_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int retval;
- u8 func, func_max;
- u16 addr, len;
- u8 *buf;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- func = srb->cmnd[3];
- addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
- len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7];
-
- RTSX_DEBUGP("%s: func = %d, addr = 0x%x\n", __func__, func, addr);
-
- if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip))
- func_max = 1;
- else
- func_max = 0;
-
- if (func > func_max) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len);
- buf = (u8 *)vmalloc(len);
- if (!buf)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- rtsx_stor_get_xfer_buf(buf, len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - len);
-
- retval = rtsx_write_cfg_seq(chip, func, addr, buf, len);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR);
- vfree(buf);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- vfree(buf);
-
- return TRANSPORT_GOOD;
-}
-
-static int app_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int result;
-
- switch (srb->cmnd[2]) {
- case PP_READ10:
- case PP_WRITE10:
- result = read_write(srb, chip);
- break;
-
- case READ_HOST_REG:
- result = read_host_reg(srb, chip);
- break;
-
- case WRITE_HOST_REG:
- result = write_host_reg(srb, chip);
- break;
-
- case GET_VAR:
- result = get_variable(srb, chip);
- break;
-
- case SET_VAR:
- result = set_variable(srb, chip);
- break;
-
- case DMA_READ:
- case DMA_WRITE:
- result = dma_access_ring_buffer(srb, chip);
- break;
-
- case READ_PHY:
- result = read_phy_register(srb, chip);
- break;
-
- case WRITE_PHY:
- result = write_phy_register(srb, chip);
- break;
-
- case ERASE_EEPROM2:
- result = erase_eeprom2(srb, chip);
- break;
-
- case READ_EEPROM2:
- result = read_eeprom2(srb, chip);
- break;
-
- case WRITE_EEPROM2:
- result = write_eeprom2(srb, chip);
- break;
-
- case READ_EFUSE:
- result = read_efuse(srb, chip);
- break;
-
- case WRITE_EFUSE:
- result = write_efuse(srb, chip);
- break;
-
- case READ_CFG:
- result = read_cfg_byte(srb, chip);
- break;
-
- case WRITE_CFG:
- result = write_cfg_byte(srb, chip);
- break;
-
- case SET_CHIP_MODE:
- result = set_chip_mode(srb, chip);
- break;
-
- case SUIT_CMD:
- result = suit_cmd(srb, chip);
- break;
-
- case GET_DEV_STATUS:
- result = get_dev_status(srb, chip);
- break;
-
- default:
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- return result;
-}
-
-
-static int read_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- u8 rtsx_status[16];
- int buf_len;
- unsigned int lun = SCSI_LUN(srb);
-
- rtsx_status[0] = (u8)(chip->vendor_id >> 8);
- rtsx_status[1] = (u8)(chip->vendor_id);
-
- rtsx_status[2] = (u8)(chip->product_id >> 8);
- rtsx_status[3] = (u8)(chip->product_id);
-
- rtsx_status[4] = (u8)lun;
-
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
- if (chip->lun2card[lun] == SD_CARD)
- rtsx_status[5] = 2;
- else
- rtsx_status[5] = 3;
- } else {
- if (chip->card_exist) {
- if (chip->card_exist & XD_CARD)
- rtsx_status[5] = 4;
- else if (chip->card_exist & SD_CARD)
- rtsx_status[5] = 2;
- else if (chip->card_exist & MS_CARD)
- rtsx_status[5] = 3;
- else
- rtsx_status[5] = 7;
- } else {
- rtsx_status[5] = 7;
- }
- }
-
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN))
- rtsx_status[6] = 2;
- else
- rtsx_status[6] = 1;
-
- rtsx_status[7] = (u8)(chip->product_id);
- rtsx_status[8] = chip->ic_version;
-
- if (check_card_exist(chip, lun))
- rtsx_status[9] = 1;
- else
- rtsx_status[9] = 0;
-
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN))
- rtsx_status[10] = 0;
- else
- rtsx_status[10] = 1;
-
- if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
- if (chip->lun2card[lun] == SD_CARD)
- rtsx_status[11] = SD_CARD;
- else
- rtsx_status[11] = MS_CARD;
- } else {
- rtsx_status[11] = XD_CARD | SD_CARD | MS_CARD;
- }
-
- if (check_card_ready(chip, lun))
- rtsx_status[12] = 1;
- else
- rtsx_status[12] = 0;
-
- if (get_lun_card(chip, lun) == XD_CARD) {
- rtsx_status[13] = 0x40;
- } else if (get_lun_card(chip, lun) == SD_CARD) {
- struct sd_info *sd_card = &(chip->sd_card);
-
- rtsx_status[13] = 0x20;
- if (CHK_SD(sd_card)) {
- if (CHK_SD_HCXC(sd_card))
- rtsx_status[13] |= 0x04;
- if (CHK_SD_HS(sd_card))
- rtsx_status[13] |= 0x02;
- } else {
- rtsx_status[13] |= 0x08;
- if (CHK_MMC_52M(sd_card))
- rtsx_status[13] |= 0x02;
- if (CHK_MMC_SECTOR_MODE(sd_card))
- rtsx_status[13] |= 0x04;
- }
- } else if (get_lun_card(chip, lun) == MS_CARD) {
- struct ms_info *ms_card = &(chip->ms_card);
-
- if (CHK_MSPRO(ms_card)) {
- rtsx_status[13] = 0x38;
- if (CHK_HG8BIT(ms_card))
- rtsx_status[13] |= 0x04;
-#ifdef SUPPORT_MSXC
- if (CHK_MSXC(ms_card))
- rtsx_status[13] |= 0x01;
-#endif
- } else {
- rtsx_status[13] = 0x30;
- }
- } else {
- if (CHECK_LUN_MODE(chip, DEFAULT_SINGLE)) {
-#ifdef SUPPORT_SDIO
- if (chip->sd_io && chip->sd_int)
- rtsx_status[13] = 0x60;
- else
- rtsx_status[13] = 0x70;
-#else
- rtsx_status[13] = 0x70;
-#endif
- } else {
- if (chip->lun2card[lun] == SD_CARD)
- rtsx_status[13] = 0x20;
- else
- rtsx_status[13] = 0x30;
- }
- }
-
- rtsx_status[14] = 0x78;
- if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip))
- rtsx_status[15] = 0x83;
- else
- rtsx_status[15] = 0x82;
-
- buf_len = min(scsi_bufflen(srb), (unsigned int)sizeof(rtsx_status));
- rtsx_stor_set_xfer_buf(rtsx_status, buf_len, srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - buf_len);
-
- return TRANSPORT_GOOD;
-}
-
-static int get_card_bus_width(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned int lun = SCSI_LUN(srb);
- u8 card, bus_width;
-
- if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- card = get_lun_card(chip, lun);
- if ((card == SD_CARD) || (card == MS_CARD)) {
- bus_width = chip->card_bus_width[lun];
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- scsi_set_resid(srb, 0);
- rtsx_stor_set_xfer_buf(&bus_width, scsi_bufflen(srb), srb);
-
- return TRANSPORT_GOOD;
-}
-
-static int spi_vendor_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int result;
- unsigned int lun = SCSI_LUN(srb);
- u8 gpio_dir;
-
- if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- rtsx_force_power_on(chip, SSC_PDCTL);
-
- rtsx_read_register(chip, CARD_GPIO_DIR, &gpio_dir);
- rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir & 0x06);
-
- switch (srb->cmnd[2]) {
- case SCSI_SPI_GETSTATUS:
- result = spi_get_status(srb, chip);
- break;
-
- case SCSI_SPI_SETPARAMETER:
- result = spi_set_parameter(srb, chip);
- break;
-
- case SCSI_SPI_READFALSHID:
- result = spi_read_flash_id(srb, chip);
- break;
-
- case SCSI_SPI_READFLASH:
- result = spi_read_flash(srb, chip);
- break;
-
- case SCSI_SPI_WRITEFLASH:
- result = spi_write_flash(srb, chip);
- break;
-
- case SCSI_SPI_WRITEFLASHSTATUS:
- result = spi_write_flash_status(srb, chip);
- break;
-
- case SCSI_SPI_ERASEFLASH:
- result = spi_erase_flash(srb, chip);
- break;
-
- default:
- rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir);
-
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir);
-
- if (result != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- return TRANSPORT_GOOD;
-}
-
-static int vendor_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int result;
-
- switch (srb->cmnd[1]) {
- case READ_STATUS:
- result = read_status(srb, chip);
- break;
-
- case READ_MEM:
- result = read_mem(srb, chip);
- break;
-
- case WRITE_MEM:
- result = write_mem(srb, chip);
- break;
-
- case READ_EEPROM:
- result = read_eeprom(srb, chip);
- break;
-
- case WRITE_EEPROM:
- result = write_eeprom(srb, chip);
- break;
-
- case TOGGLE_GPIO:
- result = toggle_gpio_cmd(srb, chip);
- break;
-
- case GET_SD_CSD:
- result = get_sd_csd(srb, chip);
- break;
-
- case GET_BUS_WIDTH:
- result = get_card_bus_width(srb, chip);
- break;
-
-#ifdef _MSG_TRACE
- case TRACE_MSG:
- result = trace_msg_cmd(srb, chip);
- break;
-#endif
-
- case SCSI_APP_CMD:
- result = app_cmd(srb, chip);
- break;
-
- case SPI_VENDOR_COMMAND:
- result = spi_vendor_cmd(srb, chip);
- break;
-
- default:
- set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- return result;
-}
-
-#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK)
-void led_shine(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned int lun = SCSI_LUN(srb);
- u16 sec_cnt;
-
- if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10))
- sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
- else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6))
- sec_cnt = srb->cmnd[4];
- else
- return;
-
- if (chip->rw_cap[lun] >= GPIO_TOGGLE_THRESHOLD) {
- toggle_gpio(chip, LED_GPIO);
- chip->rw_cap[lun] = 0;
- } else {
- chip->rw_cap[lun] += sec_cnt;
- }
-}
-#endif
-
-static int ms_format_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- unsigned int lun = SCSI_LUN(srb);
- int retval, quick_format;
-
- if (get_lun_card(chip, lun) != MS_CARD) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if ((srb->cmnd[3] != 0x4D) || (srb->cmnd[4] != 0x47) ||
- (srb->cmnd[5] != 0x66) || (srb->cmnd[6] != 0x6D) ||
- (srb->cmnd[7] != 0x74)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
-
- if (!check_card_ready(chip, lun) ||
- (get_card_size(chip, lun) == 0)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- if (srb->cmnd[8] & 0x01)
- quick_format = 0;
- else
- quick_format = 1;
-
- if (!(chip->card_ready & MS_CARD)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (chip->card_wp & MS_CARD) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (!CHK_MSPRO(ms_card)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- retval = mspro_format(srb, chip, MS_SHORT_DATA_LEN, quick_format);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- scsi_set_resid(srb, 0);
- return TRANSPORT_GOOD;
-}
-
-#ifdef SUPPORT_PCGL_1P18
-static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- unsigned int lun = SCSI_LUN(srb);
- u8 dev_info_id, data_len;
- u8 *buf;
- unsigned int buf_len;
- int i;
-
- if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- if ((get_lun_card(chip, lun) != MS_CARD)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if ((srb->cmnd[2] != 0xB0) || (srb->cmnd[4] != 0x4D) ||
- (srb->cmnd[5] != 0x53) || (srb->cmnd[6] != 0x49) ||
- (srb->cmnd[7] != 0x44)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- dev_info_id = srb->cmnd[3];
- if ((CHK_MSXC(ms_card) && (dev_info_id == 0x10)) ||
- (!CHK_MSXC(ms_card) && (dev_info_id == 0x13)) ||
- !CHK_MSPRO(ms_card)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (dev_info_id == 0x15)
- buf_len = data_len = 0x3A;
- else
- buf_len = data_len = 0x6A;
-
- buf = kmalloc(buf_len, GFP_KERNEL);
- if (!buf)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- i = 0;
- /* GET Memory Stick Media Information Response Header */
- buf[i++] = 0x00; /* Data length MSB */
- buf[i++] = data_len; /* Data length LSB */
- /* Device Information Type Code */
- if (CHK_MSXC(ms_card))
- buf[i++] = 0x03;
- else
- buf[i++] = 0x02;
-
- /* SGM bit */
- buf[i++] = 0x01;
- /* Reserved */
- buf[i++] = 0x00;
- buf[i++] = 0x00;
- buf[i++] = 0x00;
- /* Number of Device Information */
- buf[i++] = 0x01;
-
- /* Device Information Body */
-
- /* Device Information ID Number */
- buf[i++] = dev_info_id;
- /* Device Information Length */
- if (dev_info_id == 0x15)
- data_len = 0x31;
- else
- data_len = 0x61;
-
- buf[i++] = 0x00; /* Data length MSB */
- buf[i++] = data_len; /* Data length LSB */
- /* Valid Bit */
- buf[i++] = 0x80;
- if ((dev_info_id == 0x10) || (dev_info_id == 0x13)) {
- /* System Information */
- memcpy(buf+i, ms_card->raw_sys_info, 96);
- } else {
- /* Model Name */
- memcpy(buf+i, ms_card->raw_model_name, 48);
- }
-
- rtsx_stor_set_xfer_buf(buf, buf_len, srb);
-
- if (dev_info_id == 0x15)
- scsi_set_resid(srb, scsi_bufflen(srb)-0x3C);
- else
- scsi_set_resid(srb, scsi_bufflen(srb)-0x6C);
-
- kfree(buf);
- return STATUS_SUCCESS;
-}
-#endif
-
-static int ms_sp_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int retval = TRANSPORT_ERROR;
-
- if (srb->cmnd[2] == MS_FORMAT)
- retval = ms_format_cmnd(srb, chip);
-#ifdef SUPPORT_PCGL_1P18
- else if (srb->cmnd[2] == GET_MS_INFORMATION)
- retval = get_ms_information(srb, chip);
-#endif
-
- return retval;
-}
-
-#ifdef SUPPORT_CPRM
-static int sd_extention_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- unsigned int lun = SCSI_LUN(srb);
- int result;
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- sd_cleanup_work(chip);
-
- if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- if ((get_lun_card(chip, lun) != SD_CARD)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- switch (srb->cmnd[0]) {
- case SD_PASS_THRU_MODE:
- result = sd_pass_thru_mode(srb, chip);
- break;
-
- case SD_EXECUTE_NO_DATA:
- result = sd_execute_no_data(srb, chip);
- break;
-
- case SD_EXECUTE_READ:
- result = sd_execute_read_data(srb, chip);
- break;
-
- case SD_EXECUTE_WRITE:
- result = sd_execute_write_data(srb, chip);
- break;
-
- case SD_GET_RSP:
- result = sd_get_cmd_rsp(srb, chip);
- break;
-
- case SD_HW_RST:
- result = sd_hw_rst(srb, chip);
- break;
-
- default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- return result;
-}
-#endif
-
-#ifdef SUPPORT_MAGIC_GATE
-static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- unsigned int lun = SCSI_LUN(srb);
- int retval;
- u8 key_format;
-
- RTSX_DEBUGP("--%s--\n", __func__);
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- ms_cleanup_work(chip);
-
- if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- if ((get_lun_card(chip, lun) != MS_CARD)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (srb->cmnd[7] != KC_MG_R_PRO) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (!CHK_MSPRO(ms_card)) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- key_format = srb->cmnd[10] & 0x3F;
- RTSX_DEBUGP("key_format = 0x%x\n", key_format);
-
- switch (key_format) {
- case KF_GET_LOC_EKB:
- if ((scsi_bufflen(srb) == 0x41C) &&
- (srb->cmnd[8] == 0x04) &&
- (srb->cmnd[9] == 0x1C)) {
- retval = mg_get_local_EKB(srb, chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- break;
-
- case KF_RSP_CHG:
- if ((scsi_bufflen(srb) == 0x24) &&
- (srb->cmnd[8] == 0x00) &&
- (srb->cmnd[9] == 0x24)) {
- retval = mg_get_rsp_chg(srb, chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- break;
-
- case KF_GET_ICV:
- ms_card->mg_entry_num = srb->cmnd[5];
- if ((scsi_bufflen(srb) == 0x404) &&
- (srb->cmnd[8] == 0x04) &&
- (srb->cmnd[9] == 0x04) &&
- (srb->cmnd[2] == 0x00) &&
- (srb->cmnd[3] == 0x00) &&
- (srb->cmnd[4] == 0x00) &&
- (srb->cmnd[5] < 32)) {
- retval = mg_get_ICV(srb, chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- break;
-
- default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- scsi_set_resid(srb, 0);
- return TRANSPORT_GOOD;
-}
-
-static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct ms_info *ms_card = &(chip->ms_card);
- unsigned int lun = SCSI_LUN(srb);
- int retval;
- u8 key_format;
-
- RTSX_DEBUGP("--%s--\n", __func__);
-
- rtsx_disable_aspm(chip);
-
- if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
- rtsx_exit_ss(chip);
- wait_timeout(100);
- }
- rtsx_set_stat(chip, RTSX_STAT_RUN);
-
- ms_cleanup_work(chip);
-
- if (!check_card_ready(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- if (check_card_wp(chip, lun)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- if ((get_lun_card(chip, lun) != MS_CARD)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (srb->cmnd[7] != KC_MG_R_PRO) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (!CHK_MSPRO(ms_card)) {
- set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- key_format = srb->cmnd[10] & 0x3F;
- RTSX_DEBUGP("key_format = 0x%x\n", key_format);
-
- switch (key_format) {
- case KF_SET_LEAF_ID:
- if ((scsi_bufflen(srb) == 0x0C) &&
- (srb->cmnd[8] == 0x00) &&
- (srb->cmnd[9] == 0x0C)) {
- retval = mg_set_leaf_id(srb, chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- break;
-
- case KF_CHG_HOST:
- if ((scsi_bufflen(srb) == 0x0C) &&
- (srb->cmnd[8] == 0x00) &&
- (srb->cmnd[9] == 0x0C)) {
- retval = mg_chg(srb, chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- break;
-
- case KF_RSP_HOST:
- if ((scsi_bufflen(srb) == 0x0C) &&
- (srb->cmnd[8] == 0x00) &&
- (srb->cmnd[9] == 0x0C)) {
- retval = mg_rsp(srb, chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- break;
-
- case KF_SET_ICV:
- ms_card->mg_entry_num = srb->cmnd[5];
- if ((scsi_bufflen(srb) == 0x404) &&
- (srb->cmnd[8] == 0x04) &&
- (srb->cmnd[9] == 0x04) &&
- (srb->cmnd[2] == 0x00) &&
- (srb->cmnd[3] == 0x00) &&
- (srb->cmnd[4] == 0x00) &&
- (srb->cmnd[5] < 32)) {
- retval = mg_set_ICV(srb, chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- } else {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- break;
-
- default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- scsi_set_resid(srb, 0);
- return TRANSPORT_GOOD;
-}
-#endif
-
-int rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
-#ifdef SUPPORT_SD_LOCK
- struct sd_info *sd_card = &(chip->sd_card);
-#endif
- struct ms_info *ms_card = &(chip->ms_card);
- unsigned int lun = SCSI_LUN(srb);
- int result;
-
-#ifdef SUPPORT_SD_LOCK
- if (sd_card->sd_erase_status) {
- /* Block all SCSI command except for
- * REQUEST_SENSE and rs_ppstatus
- */
- if (!((srb->cmnd[0] == VENDOR_CMND) &&
- (srb->cmnd[1] == SCSI_APP_CMD) &&
- (srb->cmnd[2] == GET_DEV_STATUS)) &&
- (srb->cmnd[0] != REQUEST_SENSE)) {
- /* Logical Unit Not Ready Format in Progress */
- set_sense_data(chip, lun, CUR_ERR,
- 0x02, 0, 0x04, 0x04, 0, 0);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
-#endif
-
- if ((get_lun_card(chip, lun) == MS_CARD) &&
- (ms_card->format_status == FORMAT_IN_PROGRESS)) {
- if ((srb->cmnd[0] != REQUEST_SENSE) && (srb->cmnd[0] != INQUIRY)) {
- /* Logical Unit Not Ready Format in Progress */
- set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04,
- 0, (u16)(ms_card->progress));
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
-
- switch (srb->cmnd[0]) {
- case READ_10:
- case WRITE_10:
- case READ_6:
- case WRITE_6:
- result = read_write(srb, chip);
-#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK)
- led_shine(srb, chip);
-#endif
- break;
-
- case TEST_UNIT_READY:
- result = test_unit_ready(srb, chip);
- break;
-
- case INQUIRY:
- result = inquiry(srb, chip);
- break;
-
- case READ_CAPACITY:
- result = read_capacity(srb, chip);
- break;
-
- case START_STOP:
- result = start_stop_unit(srb, chip);
- break;
-
- case ALLOW_MEDIUM_REMOVAL:
- result = allow_medium_removal(srb, chip);
- break;
-
- case REQUEST_SENSE:
- result = request_sense(srb, chip);
- break;
-
- case MODE_SENSE:
- case MODE_SENSE_10:
- result = mode_sense(srb, chip);
- break;
-
- case 0x23:
- result = read_format_capacity(srb, chip);
- break;
-
- case VENDOR_CMND:
- result = vendor_cmnd(srb, chip);
- break;
-
- case MS_SP_CMND:
- result = ms_sp_cmnd(srb, chip);
- break;
-
-#ifdef SUPPORT_CPRM
- case SD_PASS_THRU_MODE:
- case SD_EXECUTE_NO_DATA:
- case SD_EXECUTE_READ:
- case SD_EXECUTE_WRITE:
- case SD_GET_RSP:
- case SD_HW_RST:
- result = sd_extention_cmnd(srb, chip);
- break;
-#endif
-
-#ifdef SUPPORT_MAGIC_GATE
- case CMD_MSPRO_MG_RKEY:
- result = mg_report_key(srb, chip);
- break;
-
- case CMD_MSPRO_MG_SKEY:
- result = mg_send_key(srb, chip);
- break;
-#endif
-
- case FORMAT_UNIT:
- case MODE_SELECT:
- case VERIFY:
- result = TRANSPORT_GOOD;
- break;
-
- default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- result = TRANSPORT_FAILED;
- }
-
- return result;
-}
diff --git a/drivers/staging/rts_pstor/rtsx_scsi.h b/drivers/staging/rts_pstor/rtsx_scsi.h
deleted file mode 100644
index 64b84992fdb..00000000000
--- a/drivers/staging/rts_pstor/rtsx_scsi.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- * Header file
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#ifndef __REALTEK_RTSX_SCSI_H
-#define __REALTEK_RTSX_SCSI_H
-
-#include "rtsx.h"
-#include "rtsx_chip.h"
-
-#define MS_SP_CMND 0xFA
-#define MS_FORMAT 0xA0
-#define GET_MS_INFORMATION 0xB0
-
-#define VENDOR_CMND 0xF0
-
-#define READ_STATUS 0x09
-
-#define READ_EEPROM 0x04
-#define WRITE_EEPROM 0x05
-#define READ_MEM 0x0D
-#define WRITE_MEM 0x0E
-#define GET_BUS_WIDTH 0x13
-#define GET_SD_CSD 0x14
-#define TOGGLE_GPIO 0x15
-#define TRACE_MSG 0x18
-
-#define SCSI_APP_CMD 0x10
-
-#define PP_READ10 0x1A
-#define PP_WRITE10 0x0A
-#define READ_HOST_REG 0x1D
-#define WRITE_HOST_REG 0x0D
-#define SET_VAR 0x05
-#define GET_VAR 0x15
-#define DMA_READ 0x16
-#define DMA_WRITE 0x06
-#define GET_DEV_STATUS 0x10
-#define SET_CHIP_MODE 0x27
-#define SUIT_CMD 0xE0
-#define WRITE_PHY 0x07
-#define READ_PHY 0x17
-#define WRITE_EEPROM2 0x03
-#define READ_EEPROM2 0x13
-#define ERASE_EEPROM2 0x23
-#define WRITE_EFUSE 0x04
-#define READ_EFUSE 0x14
-#define WRITE_CFG 0x0E
-#define READ_CFG 0x1E
-
-#define SPI_VENDOR_COMMAND 0x1C
-
-#define SCSI_SPI_GETSTATUS 0x00
-#define SCSI_SPI_SETPARAMETER 0x01
-#define SCSI_SPI_READFALSHID 0x02
-#define SCSI_SPI_READFLASH 0x03
-#define SCSI_SPI_WRITEFLASH 0x04
-#define SCSI_SPI_WRITEFLASHSTATUS 0x05
-#define SCSI_SPI_ERASEFLASH 0x06
-
-#define INIT_BATCHCMD 0x41
-#define ADD_BATCHCMD 0x42
-#define SEND_BATCHCMD 0x43
-#define GET_BATCHRSP 0x44
-
-#define CHIP_NORMALMODE 0x00
-#define CHIP_DEBUGMODE 0x01
-
-/* SD Pass Through Command Extension */
-#define SD_PASS_THRU_MODE 0xD0
-#define SD_EXECUTE_NO_DATA 0xD1
-#define SD_EXECUTE_READ 0xD2
-#define SD_EXECUTE_WRITE 0xD3
-#define SD_GET_RSP 0xD4
-#define SD_HW_RST 0xD6
-
-#ifdef SUPPORT_MAGIC_GATE
-#define CMD_MSPRO_MG_RKEY 0xA4 /* Report Key Command */
-#define CMD_MSPRO_MG_SKEY 0xA3 /* Send Key Command */
-
-/* CBWCB field: key class */
-#define KC_MG_R_PRO 0xBE /* MG-R PRO*/
-
-/* CBWCB field: key format */
-#define KF_SET_LEAF_ID 0x31 /* Set Leaf ID */
-#define KF_GET_LOC_EKB 0x32 /* Get Local EKB */
-#define KF_CHG_HOST 0x33 /* Challenge (host) */
-#define KF_RSP_CHG 0x34 /* Response and Challenge (device) */
-#define KF_RSP_HOST 0x35 /* Response (host) */
-#define KF_GET_ICV 0x36 /* Get ICV */
-#define KF_SET_ICV 0x37 /* SSet ICV */
-#endif
-
-/* Sense type */
-#define SENSE_TYPE_NO_SENSE 0
-#define SENSE_TYPE_MEDIA_CHANGE 1
-#define SENSE_TYPE_MEDIA_NOT_PRESENT 2
-#define SENSE_TYPE_MEDIA_LBA_OVER_RANGE 3
-#define SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT 4
-#define SENSE_TYPE_MEDIA_WRITE_PROTECT 5
-#define SENSE_TYPE_MEDIA_INVALID_CMD_FIELD 6
-#define SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR 7
-#define SENSE_TYPE_MEDIA_WRITE_ERR 8
-#define SENSE_TYPE_FORMAT_IN_PROGRESS 9
-#define SENSE_TYPE_FORMAT_CMD_FAILED 10
-#ifdef SUPPORT_MAGIC_GATE
-#define SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB 0x0b
-#define SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN 0x0c
-#define SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM 0x0d
-#define SENSE_TYPE_MG_WRITE_ERR 0x0e
-#endif
-#ifdef SUPPORT_SD_LOCK
-#define SENSE_TYPE_MEDIA_READ_FORBIDDEN 0x10 /* FOR Locked SD card*/
-#endif
-
-void scsi_show_command(struct scsi_cmnd *srb);
-void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type);
-void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, u8 sense_key,
- u32 info, u8 asc, u8 ascq, u8 sns_key_info0, u16 sns_key_info1);
-int rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-
-#endif /* __REALTEK_RTSX_SCSI_H */
-
diff --git a/drivers/staging/rts_pstor/rtsx_sys.h b/drivers/staging/rts_pstor/rtsx_sys.h
deleted file mode 100644
index 8e55a3a8b00..00000000000
--- a/drivers/staging/rts_pstor/rtsx_sys.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- * Header file
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#ifndef __RTSX_SYS_H
-#define __RTSX_SYS_H
-
-#include "rtsx.h"
-#include "rtsx_chip.h"
-#include "rtsx_card.h"
-
-typedef dma_addr_t ULONG_PTR;
-
-static inline void rtsx_exclusive_enter_ss(struct rtsx_chip *chip)
-{
- struct rtsx_dev *dev = chip->rtsx;
-
- spin_lock(&(dev->reg_lock));
- rtsx_enter_ss(chip);
- spin_unlock(&(dev->reg_lock));
-}
-
-static inline void rtsx_reset_detected_cards(struct rtsx_chip *chip, int flag)
-{
- rtsx_reset_cards(chip);
-}
-
-#define RTSX_MSG_IN_INT(x)
-
-#endif /* __RTSX_SYS_H */
-
diff --git a/drivers/staging/rts_pstor/rtsx_transport.c b/drivers/staging/rts_pstor/rtsx_transport.c
deleted file mode 100644
index 1f9a4248044..00000000000
--- a/drivers/staging/rts_pstor/rtsx_transport.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#include <linux/blkdev.h>
-#include <linux/kthread.h>
-#include <linux/sched.h>
-
-#include "rtsx.h"
-#include "rtsx_scsi.h"
-#include "rtsx_transport.h"
-#include "rtsx_chip.h"
-#include "rtsx_card.h"
-#include "debug.h"
-
-/***********************************************************************
- * Scatter-gather transfer buffer access routines
- ***********************************************************************/
-
-/* Copy a buffer of length buflen to/from the srb's transfer buffer.
- * (Note: for scatter-gather transfers (srb->use_sg > 0), srb->request_buffer
- * points to a list of s-g entries and we ignore srb->request_bufflen.
- * For non-scatter-gather transfers, srb->request_buffer points to the
- * transfer buffer itself and srb->request_bufflen is the buffer's length.)
- * Update the *index and *offset variables so that the next copy will
- * pick up from where this one left off. */
-
-unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer,
- unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index,
- unsigned int *offset, enum xfer_buf_dir dir)
-{
- unsigned int cnt;
-
- /* If not using scatter-gather, just transfer the data directly.
- * Make certain it will fit in the available buffer space. */
- if (scsi_sg_count(srb) == 0) {
- if (*offset >= scsi_bufflen(srb))
- return 0;
- cnt = min(buflen, scsi_bufflen(srb) - *offset);
- if (dir == TO_XFER_BUF)
- memcpy((unsigned char *) scsi_sglist(srb) + *offset,
- buffer, cnt);
- else
- memcpy(buffer, (unsigned char *) scsi_sglist(srb) +
- *offset, cnt);
- *offset += cnt;
-
- /* Using scatter-gather. We have to go through the list one entry
- * at a time. Each s-g entry contains some number of pages, and
- * each page has to be kmap()'ed separately. If the page is already
- * in kernel-addressable memory then kmap() will return its address.
- * If the page is not directly accessible -- such as a user buffer
- * located in high memory -- then kmap() will map it to a temporary
- * position in the kernel's virtual address space. */
- } else {
- struct scatterlist *sg =
- (struct scatterlist *) scsi_sglist(srb)
- + *index;
-
- /* This loop handles a single s-g list entry, which may
- * include multiple pages. Find the initial page structure
- * and the starting offset within the page, and update
- * the *offset and *index values for the next loop. */
- cnt = 0;
- while (cnt < buflen && *index < scsi_sg_count(srb)) {
- struct page *page = sg_page(sg) +
- ((sg->offset + *offset) >> PAGE_SHIFT);
- unsigned int poff =
- (sg->offset + *offset) & (PAGE_SIZE-1);
- unsigned int sglen = sg->length - *offset;
-
- if (sglen > buflen - cnt) {
-
- /* Transfer ends within this s-g entry */
- sglen = buflen - cnt;
- *offset += sglen;
- } else {
-
- /* Transfer continues to next s-g entry */
- *offset = 0;
- ++*index;
- ++sg;
- }
-
- /* Transfer the data for all the pages in this
- * s-g entry. For each page: call kmap(), do the
- * transfer, and call kunmap() immediately after. */
- while (sglen > 0) {
- unsigned int plen = min(sglen, (unsigned int)
- PAGE_SIZE - poff);
- unsigned char *ptr = kmap(page);
-
- if (dir == TO_XFER_BUF)
- memcpy(ptr + poff, buffer + cnt, plen);
- else
- memcpy(buffer + cnt, ptr + poff, plen);
- kunmap(page);
-
- /* Start at the beginning of the next page */
- poff = 0;
- ++page;
- cnt += plen;
- sglen -= plen;
- }
- }
- }
-
- /* Return the amount actually transferred */
- return cnt;
-}
-
-/* Store the contents of buffer into srb's transfer buffer and set the
-* SCSI residue. */
-void rtsx_stor_set_xfer_buf(unsigned char *buffer,
- unsigned int buflen, struct scsi_cmnd *srb)
-{
- unsigned int index = 0, offset = 0;
-
- rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset,
- TO_XFER_BUF);
- if (buflen < scsi_bufflen(srb))
- scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
-}
-
-void rtsx_stor_get_xfer_buf(unsigned char *buffer,
- unsigned int buflen, struct scsi_cmnd *srb)
-{
- unsigned int index = 0, offset = 0;
-
- rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset,
- FROM_XFER_BUF);
- if (buflen < scsi_bufflen(srb))
- scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
-}
-
-
-/***********************************************************************
- * Transport routines
- ***********************************************************************/
-
-/* Invoke the transport and basic error-handling/recovery methods
- *
- * This is used to send the message to the device and receive the response.
- */
-void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int result;
-
- result = rtsx_scsi_handler(srb, chip);
-
- /* if the command gets aborted by the higher layers, we need to
- * short-circuit all other processing
- */
- if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) {
- RTSX_DEBUGP("-- command was aborted\n");
- srb->result = DID_ABORT << 16;
- goto Handle_Errors;
- }
-
- /* if there is a transport error, reset and don't auto-sense */
- if (result == TRANSPORT_ERROR) {
- RTSX_DEBUGP("-- transport indicates error, resetting\n");
- srb->result = DID_ERROR << 16;
- goto Handle_Errors;
- }
-
- srb->result = SAM_STAT_GOOD;
-
- /*
- * If we have a failure, we're going to do a REQUEST_SENSE
- * automatically. Note that we differentiate between a command
- * "failure" and an "error" in the transport mechanism.
- */
- if (result == TRANSPORT_FAILED) {
- /* set the result so the higher layers expect this data */
- srb->result = SAM_STAT_CHECK_CONDITION;
- memcpy(srb->sense_buffer,
- (unsigned char *)&(chip->sense_buffer[SCSI_LUN(srb)]),
- sizeof(struct sense_data_t));
- }
-
- return;
-
- /* Error and abort processing: try to resynchronize with the device
- * by issuing a port reset. If that fails, try a class-specific
- * device reset. */
-Handle_Errors:
- return;
-}
-
-void rtsx_add_cmd(struct rtsx_chip *chip,
- u8 cmd_type, u16 reg_addr, u8 mask, u8 data)
-{
- u32 *cb = (u32 *)(chip->host_cmds_ptr);
- u32 val = 0;
-
- val |= (u32)(cmd_type & 0x03) << 30;
- val |= (u32)(reg_addr & 0x3FFF) << 16;
- val |= (u32)mask << 8;
- val |= (u32)data;
-
- spin_lock_irq(&chip->rtsx->reg_lock);
- if (chip->ci < (HOST_CMDS_BUF_LEN / 4))
- cb[(chip->ci)++] = cpu_to_le32(val);
-
- spin_unlock_irq(&chip->rtsx->reg_lock);
-}
-
-void rtsx_send_cmd_no_wait(struct rtsx_chip *chip)
-{
- u32 val = 1 << 31;
-
- rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr);
-
- val |= (u32)(chip->ci * 4) & 0x00FFFFFF;
- /* Hardware Auto Response */
- val |= 0x40000000;
- rtsx_writel(chip, RTSX_HCBCTLR, val);
-}
-
-int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout)
-{
- struct rtsx_dev *rtsx = chip->rtsx;
- struct completion trans_done;
- u32 val = 1 << 31;
- long timeleft;
- int err = 0;
-
- if (card == SD_CARD)
- rtsx->check_card_cd = SD_EXIST;
- else if (card == MS_CARD)
- rtsx->check_card_cd = MS_EXIST;
- else if (card == XD_CARD)
- rtsx->check_card_cd = XD_EXIST;
- else
- rtsx->check_card_cd = 0;
-
- spin_lock_irq(&rtsx->reg_lock);
-
- /* set up data structures for the wakeup system */
- rtsx->done = &trans_done;
- rtsx->trans_result = TRANS_NOT_READY;
- init_completion(&trans_done);
- rtsx->trans_state = STATE_TRANS_CMD;
-
- rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr);
-
- val |= (u32)(chip->ci * 4) & 0x00FFFFFF;
- /* Hardware Auto Response */
- val |= 0x40000000;
- rtsx_writel(chip, RTSX_HCBCTLR, val);
-
- spin_unlock_irq(&rtsx->reg_lock);
-
- /* Wait for TRANS_OK_INT */
- timeleft = wait_for_completion_interruptible_timeout(
- &trans_done, timeout * HZ / 1000);
- if (timeleft <= 0) {
- RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
- err = -ETIMEDOUT;
- TRACE_GOTO(chip, finish_send_cmd);
- }
-
- spin_lock_irq(&rtsx->reg_lock);
- if (rtsx->trans_result == TRANS_RESULT_FAIL)
- err = -EIO;
- else if (rtsx->trans_result == TRANS_RESULT_OK)
- err = 0;
-
- spin_unlock_irq(&rtsx->reg_lock);
-
-finish_send_cmd:
- rtsx->done = NULL;
- rtsx->trans_state = STATE_TRANS_NONE;
-
- if (err < 0)
- rtsx_stop_cmd(chip, card);
-
- return err;
-}
-
-static inline void rtsx_add_sg_tbl(
- struct rtsx_chip *chip, u32 addr, u32 len, u8 option)
-{
- u64 *sgb = (u64 *)(chip->host_sg_tbl_ptr);
- u64 val = 0;
- u32 temp_len = 0;
- u8 temp_opt = 0;
-
- do {
- if (len > 0x80000) {
- temp_len = 0x80000;
- temp_opt = option & (~SG_END);
- } else {
- temp_len = len;
- temp_opt = option;
- }
- val = ((u64)addr << 32) | ((u64)temp_len << 12) | temp_opt;
-
- if (chip->sgi < (HOST_SG_TBL_BUF_LEN / 8))
- sgb[(chip->sgi)++] = cpu_to_le64(val);
-
- len -= temp_len;
- addr += temp_len;
- } while (len);
-}
-
-static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
- struct scatterlist *sg, int num_sg, unsigned int *index,
- unsigned int *offset, int size,
- enum dma_data_direction dma_dir, int timeout)
-{
- struct rtsx_dev *rtsx = chip->rtsx;
- struct completion trans_done;
- u8 dir;
- int sg_cnt, i, resid;
- int err = 0;
- long timeleft;
- struct scatterlist *sg_ptr;
- u32 val = TRIG_DMA;
-
- if ((sg == NULL) || (num_sg <= 0) || !offset || !index)
- return -EIO;
-
- if (dma_dir == DMA_TO_DEVICE)
- dir = HOST_TO_DEVICE;
- else if (dma_dir == DMA_FROM_DEVICE)
- dir = DEVICE_TO_HOST;
- else
- return -ENXIO;
-
- if (card == SD_CARD)
- rtsx->check_card_cd = SD_EXIST;
- else if (card == MS_CARD)
- rtsx->check_card_cd = MS_EXIST;
- else if (card == XD_CARD)
- rtsx->check_card_cd = XD_EXIST;
- else
- rtsx->check_card_cd = 0;
-
- spin_lock_irq(&rtsx->reg_lock);
-
- /* set up data structures for the wakeup system */
- rtsx->done = &trans_done;
-
- rtsx->trans_state = STATE_TRANS_SG;
- rtsx->trans_result = TRANS_NOT_READY;
-
- spin_unlock_irq(&rtsx->reg_lock);
-
- sg_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir);
-
- resid = size;
- sg_ptr = sg;
- chip->sgi = 0;
- /* Usually the next entry will be @sg@ + 1, but if this sg element
- * is part of a chained scatterlist, it could jump to the start of
- * a new scatterlist array. So here we use sg_next to move to
- * the proper sg
- */
- for (i = 0; i < *index; i++)
- sg_ptr = sg_next(sg_ptr);
- for (i = *index; i < sg_cnt; i++) {
- dma_addr_t addr;
- unsigned int len;
- u8 option;
-
- addr = sg_dma_address(sg_ptr);
- len = sg_dma_len(sg_ptr);
-
- RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n",
- (unsigned int)addr, len);
- RTSX_DEBUGP("*index = %d, *offset = %d\n", *index, *offset);
-
- addr += *offset;
-
- if ((len - *offset) > resid) {
- *offset += resid;
- len = resid;
- resid = 0;
- } else {
- resid -= (len - *offset);
- len -= *offset;
- *offset = 0;
- *index = *index + 1;
- }
- if ((i == (sg_cnt - 1)) || !resid)
- option = SG_VALID | SG_END | SG_TRANS_DATA;
- else
- option = SG_VALID | SG_TRANS_DATA;
-
- rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option);
-
- if (!resid)
- break;
-
- sg_ptr = sg_next(sg_ptr);
- }
-
- RTSX_DEBUGP("SG table count = %d\n", chip->sgi);
-
- val |= (u32)(dir & 0x01) << 29;
- val |= ADMA_MODE;
-
- spin_lock_irq(&rtsx->reg_lock);
-
- init_completion(&trans_done);
-
- rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr);
- rtsx_writel(chip, RTSX_HDBCTLR, val);
-
- spin_unlock_irq(&rtsx->reg_lock);
-
- timeleft = wait_for_completion_interruptible_timeout(
- &trans_done, timeout * HZ / 1000);
- if (timeleft <= 0) {
- RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
- RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
- err = -ETIMEDOUT;
- goto out;
- }
-
- spin_lock_irq(&rtsx->reg_lock);
- if (rtsx->trans_result == TRANS_RESULT_FAIL) {
- err = -EIO;
- spin_unlock_irq(&rtsx->reg_lock);
- goto out;
- }
- spin_unlock_irq(&rtsx->reg_lock);
-
- /* Wait for TRANS_OK_INT */
- spin_lock_irq(&rtsx->reg_lock);
- if (rtsx->trans_result == TRANS_NOT_READY) {
- init_completion(&trans_done);
- spin_unlock_irq(&rtsx->reg_lock);
- timeleft = wait_for_completion_interruptible_timeout(
- &trans_done, timeout * HZ / 1000);
- if (timeleft <= 0) {
- RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
- RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
- err = -ETIMEDOUT;
- goto out;
- }
- } else {
- spin_unlock_irq(&rtsx->reg_lock);
- }
-
- spin_lock_irq(&rtsx->reg_lock);
- if (rtsx->trans_result == TRANS_RESULT_FAIL)
- err = -EIO;
- else if (rtsx->trans_result == TRANS_RESULT_OK)
- err = 0;
-
- spin_unlock_irq(&rtsx->reg_lock);
-
-out:
- rtsx->done = NULL;
- rtsx->trans_state = STATE_TRANS_NONE;
- dma_unmap_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir);
-
- if (err < 0)
- rtsx_stop_cmd(chip, card);
-
- return err;
-}
-
-static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card,
- struct scatterlist *sg, int num_sg,
- enum dma_data_direction dma_dir, int timeout)
-{
- struct rtsx_dev *rtsx = chip->rtsx;
- struct completion trans_done;
- u8 dir;
- int buf_cnt, i;
- int err = 0;
- long timeleft;
- struct scatterlist *sg_ptr;
-
- if ((sg == NULL) || (num_sg <= 0))
- return -EIO;
-
- if (dma_dir == DMA_TO_DEVICE)
- dir = HOST_TO_DEVICE;
- else if (dma_dir == DMA_FROM_DEVICE)
- dir = DEVICE_TO_HOST;
- else
- return -ENXIO;
-
- if (card == SD_CARD)
- rtsx->check_card_cd = SD_EXIST;
- else if (card == MS_CARD)
- rtsx->check_card_cd = MS_EXIST;
- else if (card == XD_CARD)
- rtsx->check_card_cd = XD_EXIST;
- else
- rtsx->check_card_cd = 0;
-
- spin_lock_irq(&rtsx->reg_lock);
-
- /* set up data structures for the wakeup system */
- rtsx->done = &trans_done;
-
- rtsx->trans_state = STATE_TRANS_SG;
- rtsx->trans_result = TRANS_NOT_READY;
-
- spin_unlock_irq(&rtsx->reg_lock);
-
- buf_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir);
-
- sg_ptr = sg;
-
- for (i = 0; i <= buf_cnt / (HOST_SG_TBL_BUF_LEN / 8); i++) {
- u32 val = TRIG_DMA;
- int sg_cnt, j;
-
- if (i == buf_cnt / (HOST_SG_TBL_BUF_LEN / 8))
- sg_cnt = buf_cnt % (HOST_SG_TBL_BUF_LEN / 8);
- else
- sg_cnt = (HOST_SG_TBL_BUF_LEN / 8);
-
- chip->sgi = 0;
- for (j = 0; j < sg_cnt; j++) {
- dma_addr_t addr = sg_dma_address(sg_ptr);
- unsigned int len = sg_dma_len(sg_ptr);
- u8 option;
-
- RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n",
- (unsigned int)addr, len);
-
- if (j == (sg_cnt - 1))
- option = SG_VALID | SG_END | SG_TRANS_DATA;
- else
- option = SG_VALID | SG_TRANS_DATA;
-
- rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option);
-
- sg_ptr = sg_next(sg_ptr);
- }
-
- RTSX_DEBUGP("SG table count = %d\n", chip->sgi);
-
- val |= (u32)(dir & 0x01) << 29;
- val |= ADMA_MODE;
-
- spin_lock_irq(&rtsx->reg_lock);
-
- init_completion(&trans_done);
-
- rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr);
- rtsx_writel(chip, RTSX_HDBCTLR, val);
-
- spin_unlock_irq(&rtsx->reg_lock);
-
- timeleft = wait_for_completion_interruptible_timeout(
- &trans_done, timeout * HZ / 1000);
- if (timeleft <= 0) {
- RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
- RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
- err = -ETIMEDOUT;
- goto out;
- }
-
- spin_lock_irq(&rtsx->reg_lock);
- if (rtsx->trans_result == TRANS_RESULT_FAIL) {
- err = -EIO;
- spin_unlock_irq(&rtsx->reg_lock);
- goto out;
- }
- spin_unlock_irq(&rtsx->reg_lock);
-
- sg_ptr += sg_cnt;
- }
-
- /* Wait for TRANS_OK_INT */
- spin_lock_irq(&rtsx->reg_lock);
- if (rtsx->trans_result == TRANS_NOT_READY) {
- init_completion(&trans_done);
- spin_unlock_irq(&rtsx->reg_lock);
- timeleft = wait_for_completion_interruptible_timeout(
- &trans_done, timeout * HZ / 1000);
- if (timeleft <= 0) {
- RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
- RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
- err = -ETIMEDOUT;
- goto out;
- }
- } else {
- spin_unlock_irq(&rtsx->reg_lock);
- }
-
- spin_lock_irq(&rtsx->reg_lock);
- if (rtsx->trans_result == TRANS_RESULT_FAIL)
- err = -EIO;
- else if (rtsx->trans_result == TRANS_RESULT_OK)
- err = 0;
-
- spin_unlock_irq(&rtsx->reg_lock);
-
-out:
- rtsx->done = NULL;
- rtsx->trans_state = STATE_TRANS_NONE;
- dma_unmap_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir);
-
- if (err < 0)
- rtsx_stop_cmd(chip, card);
-
- return err;
-}
-
-static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, size_t len,
- enum dma_data_direction dma_dir, int timeout)
-{
- struct rtsx_dev *rtsx = chip->rtsx;
- struct completion trans_done;
- dma_addr_t addr;
- u8 dir;
- int err = 0;
- u32 val = (1 << 31);
- long timeleft;
-
- if ((buf == NULL) || (len <= 0))
- return -EIO;
-
- if (dma_dir == DMA_TO_DEVICE)
- dir = HOST_TO_DEVICE;
- else if (dma_dir == DMA_FROM_DEVICE)
- dir = DEVICE_TO_HOST;
- else
- return -ENXIO;
-
- addr = dma_map_single(&(rtsx->pci->dev), buf, len, dma_dir);
- if (!addr)
- return -ENOMEM;
-
- if (card == SD_CARD)
- rtsx->check_card_cd = SD_EXIST;
- else if (card == MS_CARD)
- rtsx->check_card_cd = MS_EXIST;
- else if (card == XD_CARD)
- rtsx->check_card_cd = XD_EXIST;
- else
- rtsx->check_card_cd = 0;
-
- val |= (u32)(dir & 0x01) << 29;
- val |= (u32)(len & 0x00FFFFFF);
-
- spin_lock_irq(&rtsx->reg_lock);
-
- /* set up data structures for the wakeup system */
- rtsx->done = &trans_done;
-
- init_completion(&trans_done);
-
- rtsx->trans_state = STATE_TRANS_BUF;
- rtsx->trans_result = TRANS_NOT_READY;
-
- rtsx_writel(chip, RTSX_HDBAR, addr);
- rtsx_writel(chip, RTSX_HDBCTLR, val);
-
- spin_unlock_irq(&rtsx->reg_lock);
-
- /* Wait for TRANS_OK_INT */
- timeleft = wait_for_completion_interruptible_timeout(
- &trans_done, timeout * HZ / 1000);
- if (timeleft <= 0) {
- RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
- RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
- err = -ETIMEDOUT;
- goto out;
- }
-
- spin_lock_irq(&rtsx->reg_lock);
- if (rtsx->trans_result == TRANS_RESULT_FAIL)
- err = -EIO;
- else if (rtsx->trans_result == TRANS_RESULT_OK)
- err = 0;
-
- spin_unlock_irq(&rtsx->reg_lock);
-
-out:
- rtsx->done = NULL;
- rtsx->trans_state = STATE_TRANS_NONE;
- dma_unmap_single(&(rtsx->pci->dev), addr, len, dma_dir);
-
- if (err < 0)
- rtsx_stop_cmd(chip, card);
-
- return err;
-}
-
-int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card,
- void *buf, size_t len, int use_sg, unsigned int *index,
- unsigned int *offset, enum dma_data_direction dma_dir,
- int timeout)
-{
- int err = 0;
-
- /* don't transfer data during abort processing */
- if (rtsx_chk_stat(chip, RTSX_STAT_ABORT))
- return -EIO;
-
- if (use_sg) {
- err = rtsx_transfer_sglist_adma_partial(chip, card,
- (struct scatterlist *)buf, use_sg,
- index, offset, (int)len, dma_dir, timeout);
- } else {
- err = rtsx_transfer_buf(chip, card,
- buf, len, dma_dir, timeout);
- }
-
- if (err < 0) {
- if (RTSX_TST_DELINK(chip)) {
- RTSX_CLR_DELINK(chip);
- chip->need_reinit = SD_CARD | MS_CARD | XD_CARD;
- rtsx_reinit_cards(chip, 1);
- }
- }
-
- return err;
-}
-
-int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len,
- int use_sg, enum dma_data_direction dma_dir, int timeout)
-{
- int err = 0;
-
- RTSX_DEBUGP("use_sg = %d\n", use_sg);
-
- /* don't transfer data during abort processing */
- if (rtsx_chk_stat(chip, RTSX_STAT_ABORT))
- return -EIO;
-
- if (use_sg) {
- err = rtsx_transfer_sglist_adma(chip, card,
- (struct scatterlist *)buf,
- use_sg, dma_dir, timeout);
- } else {
- err = rtsx_transfer_buf(chip, card, buf, len, dma_dir, timeout);
- }
-
- if (err < 0) {
- if (RTSX_TST_DELINK(chip)) {
- RTSX_CLR_DELINK(chip);
- chip->need_reinit = SD_CARD | MS_CARD | XD_CARD;
- rtsx_reinit_cards(chip, 1);
- }
- }
-
- return err;
-}
-
diff --git a/drivers/staging/rts_pstor/rtsx_transport.h b/drivers/staging/rts_pstor/rtsx_transport.h
deleted file mode 100644
index 41f1ea05a8d..00000000000
--- a/drivers/staging/rts_pstor/rtsx_transport.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- * Header file
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#ifndef __REALTEK_RTSX_TRANSPORT_H
-#define __REALTEK_RTSX_TRANSPORT_H
-
-#include "rtsx.h"
-#include "rtsx_chip.h"
-
-#define WAIT_TIME 2000
-
-unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer,
- unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index,
- unsigned int *offset, enum xfer_buf_dir dir);
-void rtsx_stor_set_xfer_buf(unsigned char *buffer,
- unsigned int buflen, struct scsi_cmnd *srb);
-void rtsx_stor_get_xfer_buf(unsigned char *buffer,
- unsigned int buflen, struct scsi_cmnd *srb);
-void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-
-
-#define rtsx_init_cmd(chip) ((chip)->ci = 0)
-
-void rtsx_add_cmd(struct rtsx_chip *chip,
- u8 cmd_type, u16 reg_addr, u8 mask, u8 data);
-void rtsx_send_cmd_no_wait(struct rtsx_chip *chip);
-int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout);
-
-extern inline u8 *rtsx_get_cmd_data(struct rtsx_chip *chip)
-{
-#ifdef CMD_USING_SG
- return (u8 *)(chip->host_sg_tbl_ptr);
-#else
- return (u8 *)(chip->host_cmds_ptr);
-#endif
-}
-
-int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len,
- int use_sg, enum dma_data_direction dma_dir, int timeout);
-
-int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, void *buf, size_t len,
- int use_sg, unsigned int *index, unsigned int *offset,
- enum dma_data_direction dma_dir, int timeout);
-
-#endif /* __REALTEK_RTSX_TRANSPORT_H */
-
diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c
deleted file mode 100644
index c6a581c47cb..00000000000
--- a/drivers/staging/rts_pstor/sd.c
+++ /dev/null
@@ -1,4570 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#include <linux/blkdev.h>
-#include <linux/kthread.h>
-#include <linux/sched.h>
-
-#include "rtsx.h"
-#include "rtsx_transport.h"
-#include "rtsx_scsi.h"
-#include "rtsx_card.h"
-#include "sd.h"
-
-#define SD_MAX_RETRY_COUNT 3
-
-static u16 REG_SD_CFG1;
-static u16 REG_SD_CFG2;
-static u16 REG_SD_CFG3;
-static u16 REG_SD_STAT1;
-static u16 REG_SD_STAT2;
-static u16 REG_SD_BUS_STAT;
-static u16 REG_SD_PAD_CTL;
-static u16 REG_SD_SAMPLE_POINT_CTL;
-static u16 REG_SD_PUSH_POINT_CTL;
-static u16 REG_SD_CMD0;
-static u16 REG_SD_CMD1;
-static u16 REG_SD_CMD2;
-static u16 REG_SD_CMD3;
-static u16 REG_SD_CMD4;
-static u16 REG_SD_CMD5;
-static u16 REG_SD_BYTE_CNT_L;
-static u16 REG_SD_BYTE_CNT_H;
-static u16 REG_SD_BLOCK_CNT_L;
-static u16 REG_SD_BLOCK_CNT_H;
-static u16 REG_SD_TRANSFER;
-static u16 REG_SD_VPCLK0_CTL;
-static u16 REG_SD_VPCLK1_CTL;
-static u16 REG_SD_DCMPS0_CTL;
-static u16 REG_SD_DCMPS1_CTL;
-
-static inline void sd_set_err_code(struct rtsx_chip *chip, u8 err_code)
-{
- struct sd_info *sd_card = &(chip->sd_card);
-
- sd_card->err_code |= err_code;
-}
-
-static inline void sd_clr_err_code(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
-
- sd_card->err_code = 0;
-}
-
-static inline int sd_check_err_code(struct rtsx_chip *chip, u8 err_code)
-{
- struct sd_info *sd_card = &(chip->sd_card);
-
- return sd_card->err_code & err_code;
-}
-
-static void sd_init_reg_addr(struct rtsx_chip *chip)
-{
- if (CHECK_PID(chip, 0x5209)) {
- REG_SD_CFG1 = SD_CFG1;
- REG_SD_CFG2 = SD_CFG2;
- REG_SD_CFG3 = SD_CFG3;
- REG_SD_STAT1 = SD_STAT1;
- REG_SD_STAT2 = SD_STAT2;
- REG_SD_BUS_STAT = SD_BUS_STAT;
- REG_SD_PAD_CTL = SD_PAD_CTL;
- REG_SD_SAMPLE_POINT_CTL = SD_SAMPLE_POINT_CTL;
- REG_SD_PUSH_POINT_CTL = SD_PUSH_POINT_CTL;
- REG_SD_CMD0 = SD_CMD0;
- REG_SD_CMD1 = SD_CMD1;
- REG_SD_CMD2 = SD_CMD2;
- REG_SD_CMD3 = SD_CMD3;
- REG_SD_CMD4 = SD_CMD4;
- REG_SD_CMD5 = SD_CMD5;
- REG_SD_BYTE_CNT_L = SD_BYTE_CNT_L;
- REG_SD_BYTE_CNT_H = SD_BYTE_CNT_H;
- REG_SD_BLOCK_CNT_L = SD_BLOCK_CNT_L;
- REG_SD_BLOCK_CNT_H = SD_BLOCK_CNT_H;
- REG_SD_TRANSFER = SD_TRANSFER;
- REG_SD_VPCLK0_CTL = SD_VPCLK0_CTL;
- REG_SD_VPCLK1_CTL = SD_VPCLK1_CTL;
- REG_SD_DCMPS0_CTL = SD_DCMPS0_CTL;
- REG_SD_DCMPS1_CTL = SD_DCMPS1_CTL;
- } else {
- REG_SD_CFG1 = 0xFD31;
- REG_SD_CFG2 = 0xFD33;
- REG_SD_CFG3 = 0xFD3E;
- REG_SD_STAT1 = 0xFD30;
- REG_SD_STAT2 = 0;
- REG_SD_BUS_STAT = 0;
- REG_SD_PAD_CTL = 0;
- REG_SD_SAMPLE_POINT_CTL = 0;
- REG_SD_PUSH_POINT_CTL = 0;
- REG_SD_CMD0 = 0xFD34;
- REG_SD_CMD1 = 0xFD35;
- REG_SD_CMD2 = 0xFD36;
- REG_SD_CMD3 = 0xFD37;
- REG_SD_CMD4 = 0xFD38;
- REG_SD_CMD5 = 0xFD5A;
- REG_SD_BYTE_CNT_L = 0xFD39;
- REG_SD_BYTE_CNT_H = 0xFD3A;
- REG_SD_BLOCK_CNT_L = 0xFD3B;
- REG_SD_BLOCK_CNT_H = 0xFD3C;
- REG_SD_TRANSFER = 0xFD32;
- REG_SD_VPCLK0_CTL = 0;
- REG_SD_VPCLK1_CTL = 0;
- REG_SD_DCMPS0_CTL = 0;
- REG_SD_DCMPS1_CTL = 0;
- }
-}
-
-static int sd_check_data0_status(struct rtsx_chip *chip)
-{
- u8 stat;
-
- if (CHECK_PID(chip, 0x5209))
- RTSX_READ_REG(chip, REG_SD_BUS_STAT, &stat);
- else
- RTSX_READ_REG(chip, REG_SD_STAT1, &stat);
-
- if (!(stat & SD_DAT0_STATUS)) {
- sd_set_err_code(chip, SD_BUSY);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx,
- u32 arg, u8 rsp_type, u8 *rsp, int rsp_len)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- int timeout = 100;
- u16 reg_addr;
- u8 *ptr;
- int stat_idx = 0;
- int rty_cnt = 0;
-
- sd_clr_err_code(chip);
-
- RTSX_DEBUGP("SD/MMC CMD %d, arg = 0x%08x\n", cmd_idx, arg);
-
- if (rsp_type == SD_RSP_TYPE_R1b)
- timeout = 3000;
-
-RTY_SEND_CMD:
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(arg >> 24));
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(arg >> 16));
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(arg >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)arg);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
- 0x01, PINGPONG_BUFFER);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER,
- 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START);
- rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER,
- SD_TRANSFER_END | SD_STAT_IDLE, SD_TRANSFER_END | SD_STAT_IDLE);
-
- if (rsp_type == SD_RSP_TYPE_R2) {
- for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; reg_addr++)
- rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0);
-
- stat_idx = 16;
- } else if (rsp_type != SD_RSP_TYPE_R0) {
- for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++)
- rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0);
-
- stat_idx = 5;
- }
-
- rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_STAT1, 0, 0);
-
- retval = rtsx_send_cmd(chip, SD_CARD, timeout);
- if (retval < 0) {
- u8 val;
-
- rtsx_read_register(chip, REG_SD_STAT1, &val);
- RTSX_DEBUGP("SD_STAT1: 0x%x\n", val);
-
- if (CHECK_PID(chip, 0x5209)) {
- rtsx_read_register(chip, REG_SD_STAT2, &val);
- RTSX_DEBUGP("SD_STAT2: 0x%x\n", val);
-
- if (val & SD_RSP_80CLK_TIMEOUT) {
- rtsx_clear_sd_error(chip);
- sd_set_err_code(chip, SD_RSP_TIMEOUT);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- rtsx_read_register(chip, REG_SD_BUS_STAT, &val);
- RTSX_DEBUGP("SD_BUS_STAT: 0x%x\n", val);
- } else {
- rtsx_read_register(chip, REG_SD_CFG3, &val);
- RTSX_DEBUGP("SD_CFG3: 0x%x\n", val);
- }
-
- if (retval == -ETIMEDOUT) {
- if (rsp_type & SD_WAIT_BUSY_END) {
- retval = sd_check_data0_status(chip);
- if (retval != STATUS_SUCCESS) {
- rtsx_clear_sd_error(chip);
- TRACE_RET(chip, retval);
- }
- } else {
- sd_set_err_code(chip, SD_TO_ERR);
- }
- retval = STATUS_TIMEDOUT;
- } else {
- retval = STATUS_FAIL;
- }
- rtsx_clear_sd_error(chip);
-
- TRACE_RET(chip, retval);
- }
-
- if (rsp_type == SD_RSP_TYPE_R0)
- return STATUS_SUCCESS;
-
- ptr = rtsx_get_cmd_data(chip) + 1;
-
- if ((ptr[0] & 0xC0) != 0) {
- sd_set_err_code(chip, SD_STS_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (!(rsp_type & SD_NO_CHECK_CRC7)) {
- if (ptr[stat_idx] & SD_CRC7_ERR) {
- if (cmd_idx == WRITE_MULTIPLE_BLOCK) {
- sd_set_err_code(chip, SD_CRC_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (rty_cnt < SD_MAX_RETRY_COUNT) {
- wait_timeout(20);
- rty_cnt++;
- goto RTY_SEND_CMD;
- } else {
- sd_set_err_code(chip, SD_CRC_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
- }
-
- if ((rsp_type == SD_RSP_TYPE_R1) || (rsp_type == SD_RSP_TYPE_R1b)) {
- if ((cmd_idx != SEND_RELATIVE_ADDR) && (cmd_idx != SEND_IF_COND)) {
- if (cmd_idx != STOP_TRANSMISSION) {
- if (ptr[1] & 0x80)
- TRACE_RET(chip, STATUS_FAIL);
- }
-#ifdef SUPPORT_SD_LOCK
- if (ptr[1] & 0x7D)
-#else
- if (ptr[1] & 0x7F)
-#endif
- {
- RTSX_DEBUGP("ptr[1]: 0x%02x\n", ptr[1]);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (ptr[2] & 0xFF) {
- RTSX_DEBUGP("ptr[2]: 0x%02x\n", ptr[2]);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (ptr[3] & 0x80) {
- RTSX_DEBUGP("ptr[3]: 0x%02x\n", ptr[3]);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (ptr[3] & 0x01)
- sd_card->sd_data_buf_ready = 1;
- else
- sd_card->sd_data_buf_ready = 0;
- }
- }
-
- if (rsp && rsp_len)
- memcpy(rsp, ptr, rsp_len);
-
- return STATUS_SUCCESS;
-}
-
-static int sd_read_data(struct rtsx_chip *chip,
- u8 trans_mode, u8 *cmd, int cmd_len, u16 byte_cnt,
- u16 blk_cnt, u8 bus_width, u8 *buf, int buf_len,
- int timeout)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- int i;
-
- sd_clr_err_code(chip);
-
- if (!buf)
- buf_len = 0;
-
- if (buf_len > 512)
- TRACE_RET(chip, STATUS_FAIL);
-
- rtsx_init_cmd(chip);
-
- if (cmd_len) {
- RTSX_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40);
- for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++)
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0 + i, 0xFF, cmd[i]);
- }
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, (u8)(byte_cnt >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, (u8)blk_cnt);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, (u8)(blk_cnt >> 8));
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF,
- SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END |
- SD_CHECK_CRC7 | SD_RSP_LEN_6);
- if (trans_mode != SD_TM_AUTO_TUNING)
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, trans_mode | SD_TRANSFER_START);
- rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END);
-
- retval = rtsx_send_cmd(chip, SD_CARD, timeout);
- if (retval < 0) {
- if (retval == -ETIMEDOUT) {
- sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
- SD_RSP_TYPE_R1, NULL, 0);
- }
-
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (buf && buf_len) {
- retval = rtsx_read_ppbuf(chip, buf, buf_len);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int sd_write_data(struct rtsx_chip *chip, u8 trans_mode,
- u8 *cmd, int cmd_len, u16 byte_cnt, u16 blk_cnt, u8 bus_width,
- u8 *buf, int buf_len, int timeout)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- int i;
-
- sd_clr_err_code(chip);
-
- if (!buf)
- buf_len = 0;
-
- if (buf_len > 512) {
- /* This function can't write data more than one page */
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (buf && buf_len) {
- retval = rtsx_write_ppbuf(chip, buf, buf_len);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- rtsx_init_cmd(chip);
-
- if (cmd_len) {
- RTSX_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40);
- for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) {
- rtsx_add_cmd(chip, WRITE_REG_CMD,
- REG_SD_CMD0 + i, 0xFF, cmd[i]);
- }
- }
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, (u8)(byte_cnt >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, (u8)blk_cnt);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, (u8)(blk_cnt >> 8));
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF,
- SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END |
- SD_CHECK_CRC7 | SD_RSP_LEN_6);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, trans_mode | SD_TRANSFER_START);
- rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END);
-
- retval = rtsx_send_cmd(chip, SD_CARD, timeout);
- if (retval < 0) {
- if (retval == -ETIMEDOUT) {
- sd_send_cmd_get_rsp(chip, SEND_STATUS,
- sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
- }
-
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int sd_check_csd(struct rtsx_chip *chip, char check_wp)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- int i;
- u8 csd_ver, trans_speed;
- u8 rsp[16];
-
- for (i = 0; i < 6; i++) {
- if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
- sd_set_err_code(chip, SD_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = sd_send_cmd_get_rsp(chip, SEND_CSD, sd_card->sd_addr, SD_RSP_TYPE_R2, rsp, 16);
- if (retval == STATUS_SUCCESS)
- break;
- }
-
- if (i == 6)
- TRACE_RET(chip, STATUS_FAIL);
-
- memcpy(sd_card->raw_csd, rsp + 1, 15);
-
- if (CHECK_PID(chip, 0x5209))
- RTSX_READ_REG(chip, REG_SD_CMD5, sd_card->raw_csd + 15);
-
- RTSX_DEBUGP("CSD Response:\n");
- RTSX_DUMP(sd_card->raw_csd, 16);
-
- csd_ver = (rsp[1] & 0xc0) >> 6;
- RTSX_DEBUGP("csd_ver = %d\n", csd_ver);
-
- trans_speed = rsp[4];
- if ((trans_speed & 0x07) == 0x02) {
- if ((trans_speed & 0xf8) >= 0x30) {
- if (chip->asic_code)
- sd_card->sd_clock = 47;
- else
- sd_card->sd_clock = CLK_50;
-
- } else if ((trans_speed & 0xf8) == 0x28) {
- if (chip->asic_code)
- sd_card->sd_clock = 39;
- else
- sd_card->sd_clock = CLK_40;
-
- } else if ((trans_speed & 0xf8) == 0x20) {
- if (chip->asic_code)
- sd_card->sd_clock = 29;
- else
- sd_card->sd_clock = CLK_30;
-
- } else if ((trans_speed & 0xf8) >= 0x10) {
- if (chip->asic_code)
- sd_card->sd_clock = 23;
- else
- sd_card->sd_clock = CLK_20;
-
- } else if ((trans_speed & 0x08) >= 0x08) {
- if (chip->asic_code)
- sd_card->sd_clock = 19;
- else
- sd_card->sd_clock = CLK_20;
- } else {
- TRACE_RET(chip, STATUS_FAIL);
- }
- } else {
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (CHK_MMC_SECTOR_MODE(sd_card)) {
- sd_card->capacity = 0;
- } else {
- if ((!CHK_SD_HCXC(sd_card)) || (csd_ver == 0)) {
- u8 blk_size, c_size_mult;
- u16 c_size;
- blk_size = rsp[6] & 0x0F;
- c_size = ((u16)(rsp[7] & 0x03) << 10)
- + ((u16)rsp[8] << 2)
- + ((u16)(rsp[9] & 0xC0) >> 6);
- c_size_mult = (u8)((rsp[10] & 0x03) << 1);
- c_size_mult += (rsp[11] & 0x80) >> 7;
- sd_card->capacity = (((u32)(c_size + 1)) * (1 << (c_size_mult + 2))) << (blk_size - 9);
- } else {
- u32 total_sector = 0;
- total_sector = (((u32)rsp[8] & 0x3f) << 16) |
- ((u32)rsp[9] << 8) | (u32)rsp[10];
- sd_card->capacity = (total_sector + 1) << 10;
- }
- }
-
- if (check_wp) {
- if (rsp[15] & 0x30)
- chip->card_wp |= SD_CARD;
-
- RTSX_DEBUGP("CSD WP Status: 0x%x\n", rsp[15]);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int sd_set_sample_push_timing(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
-
- if (CHECK_PID(chip, 0x5209)) {
- if (CHK_SD_SDR104(sd_card) || CHK_SD_SDR50(sd_card)) {
- RTSX_WRITE_REG(chip, SD_CFG1, 0x0C | SD_ASYNC_FIFO_NOT_RST,
- SD_30_MODE | SD_ASYNC_FIFO_NOT_RST);
- RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ);
- RTSX_WRITE_REG(chip, CARD_CLK_SOURCE, 0xFF,
- CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
- RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0);
- } else if (CHK_SD_DDR50(sd_card) || CHK_MMC_DDR52(sd_card)) {
- RTSX_WRITE_REG(chip, SD_CFG1, 0x0C | SD_ASYNC_FIFO_NOT_RST,
- SD_DDR_MODE | SD_ASYNC_FIFO_NOT_RST);
- RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ);
- RTSX_WRITE_REG(chip, CARD_CLK_SOURCE, 0xFF,
- CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
- RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0);
- RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, DDR_VAR_TX_CMD_DAT,
- DDR_VAR_TX_CMD_DAT);
- RTSX_WRITE_REG(chip, SD_SAMPLE_POINT_CTL, DDR_VAR_RX_DAT | DDR_VAR_RX_CMD,
- DDR_VAR_RX_DAT | DDR_VAR_RX_CMD);
- } else {
- u8 val = 0;
-
- RTSX_WRITE_REG(chip, SD_CFG1, 0x0C, SD_20_MODE);
- RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ);
- RTSX_WRITE_REG(chip, CARD_CLK_SOURCE, 0xFF,
- CRC_FIX_CLK | SD30_VAR_CLK0 | SAMPLE_VAR_CLK1);
- RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0);
-
- if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_AUTO)
- val = SD20_TX_NEG_EDGE;
- else if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_DELAY)
- val = SD20_TX_14_AHEAD;
- else
- val = SD20_TX_NEG_EDGE;
-
- RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, SD20_TX_SEL_MASK, val);
-
- if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_AUTO) {
- if (chip->asic_code) {
- if (CHK_SD_HS(sd_card) || CHK_MMC_52M(sd_card))
- val = SD20_RX_14_DELAY;
- else
- val = SD20_RX_POS_EDGE;
- } else {
- val = SD20_RX_14_DELAY;
- }
- } else if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_DELAY) {
- val = SD20_RX_14_DELAY;
- } else {
- val = SD20_RX_POS_EDGE;
- }
- RTSX_WRITE_REG(chip, SD_SAMPLE_POINT_CTL, SD20_RX_SEL_MASK, val);
- }
- } else {
- u8 val = 0;
-
- if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_DELAY)
- val |= 0x10;
-
- if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_AUTO) {
- if (chip->asic_code) {
- if (CHK_SD_HS(sd_card) || CHK_MMC_52M(sd_card)) {
- if (val & 0x10)
- val |= 0x04;
- else
- val |= 0x08;
- }
- } else {
- if (val & 0x10)
- val |= 0x04;
- else
- val |= 0x08;
- }
- } else if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_DELAY) {
- if (val & 0x10)
- val |= 0x04;
- else
- val |= 0x08;
- }
-
- RTSX_WRITE_REG(chip, REG_SD_CFG1, 0x1C, val);
- }
-
- return STATUS_SUCCESS;
-}
-
-static void sd_choose_proper_clock(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
-
- if (CHK_SD_SDR104(sd_card)) {
- if (chip->asic_code)
- sd_card->sd_clock = chip->asic_sd_sdr104_clk;
- else
- sd_card->sd_clock = chip->fpga_sd_sdr104_clk;
-
- } else if (CHK_SD_DDR50(sd_card)) {
- if (chip->asic_code)
- sd_card->sd_clock = chip->asic_sd_ddr50_clk;
- else
- sd_card->sd_clock = chip->fpga_sd_ddr50_clk;
-
- } else if (CHK_SD_SDR50(sd_card)) {
- if (chip->asic_code)
- sd_card->sd_clock = chip->asic_sd_sdr50_clk;
- else
- sd_card->sd_clock = chip->fpga_sd_sdr50_clk;
-
- } else if (CHK_SD_HS(sd_card)) {
- if (chip->asic_code)
- sd_card->sd_clock = chip->asic_sd_hs_clk;
- else
- sd_card->sd_clock = chip->fpga_sd_hs_clk;
-
- } else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) {
- if (chip->asic_code)
- sd_card->sd_clock = chip->asic_mmc_52m_clk;
- else
- sd_card->sd_clock = chip->fpga_mmc_52m_clk;
-
- } else if (CHK_MMC_26M(sd_card)) {
- if (chip->asic_code)
- sd_card->sd_clock = 48;
- else
- sd_card->sd_clock = CLK_50;
- }
-}
-
-static int sd_set_clock_divider(struct rtsx_chip *chip, u8 clk_div)
-{
- u8 mask = 0, val = 0;
-
- if (CHECK_PID(chip, 0x5209)) {
- mask = SD_CLK_DIVIDE_MASK;
- val = clk_div;
- } else {
- mask = 0x60;
- if (clk_div == SD_CLK_DIVIDE_0)
- val = 0x00;
- else if (clk_div == SD_CLK_DIVIDE_128)
- val = 0x40;
- else if (clk_div == SD_CLK_DIVIDE_256)
- val = 0x20;
- }
-
- RTSX_WRITE_REG(chip, REG_SD_CFG1, mask, val);
-
- return STATUS_SUCCESS;
-}
-
-static int sd_set_init_para(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
-
- retval = sd_set_sample_push_timing(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- sd_choose_proper_clock(chip);
-
- retval = switch_clock(chip, sd_card->sd_clock);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-int sd_select_card(struct rtsx_chip *chip, int select)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- u8 cmd_idx, cmd_type;
- u32 addr;
-
- if (select) {
- cmd_idx = SELECT_CARD;
- cmd_type = SD_RSP_TYPE_R1;
- addr = sd_card->sd_addr;
- } else {
- cmd_idx = DESELECT_CARD;
- cmd_type = SD_RSP_TYPE_R0;
- addr = 0;
- }
-
- retval = sd_send_cmd_get_rsp(chip, cmd_idx, addr, cmd_type, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-#ifdef SUPPORT_SD_LOCK
-static int sd_update_lock_status(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- u8 rsp[5];
-
- retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, rsp, 5);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (rsp[1] & 0x02)
- sd_card->sd_lock_status |= SD_LOCKED;
- else
- sd_card->sd_lock_status &= ~SD_LOCKED;
-
- RTSX_DEBUGP("sd_card->sd_lock_status = 0x%x\n", sd_card->sd_lock_status);
-
- if (rsp[1] & 0x01)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-#endif
-
-static int sd_wait_state_data_ready(struct rtsx_chip *chip, u8 state, u8 data_ready, int polling_cnt)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval, i;
- u8 rsp[5];
-
- for (i = 0; i < polling_cnt; i++) {
- retval = sd_send_cmd_get_rsp(chip, SEND_STATUS,
- sd_card->sd_addr, SD_RSP_TYPE_R1, rsp, 5);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (((rsp[3] & 0x1E) == state) && ((rsp[3] & 0x01) == data_ready))
- return STATUS_SUCCESS;
- }
-
- TRACE_RET(chip, STATUS_FAIL);
-}
-
-static int sd_change_bank_voltage(struct rtsx_chip *chip, u8 voltage)
-{
- int retval;
-
- if (voltage == SD_IO_3V3) {
- if (chip->asic_code) {
- retval = rtsx_write_phy_register(chip, 0x08, 0x4FC0 | chip->phy_voltage);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- RTSX_WRITE_REG(chip, SD_PAD_CTL, SD_IO_USING_1V8, 0);
- }
- } else if (voltage == SD_IO_1V8) {
- if (chip->asic_code) {
- retval = rtsx_write_phy_register(chip, 0x08, 0x4C40 | chip->phy_voltage);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- RTSX_WRITE_REG(chip, SD_PAD_CTL, SD_IO_USING_1V8, SD_IO_USING_1V8);
- }
- } else {
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int sd_voltage_switch(struct rtsx_chip *chip)
-{
- int retval;
- u8 stat;
-
- RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, SD_CLK_TOGGLE_EN);
-
- retval = sd_send_cmd_get_rsp(chip, VOLTAGE_SWITCH, 0, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- udelay(chip->sd_voltage_switch_delay);
-
- RTSX_READ_REG(chip, SD_BUS_STAT, &stat);
- if (stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
- SD_DAT1_STATUS | SD_DAT0_STATUS)) {
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- RTSX_WRITE_REG(chip, SD_BUS_STAT, 0xFF, SD_CLK_FORCE_STOP);
- retval = sd_change_bank_voltage(chip, SD_IO_1V8);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- wait_timeout(50);
-
- RTSX_WRITE_REG(chip, SD_BUS_STAT, 0xFF, SD_CLK_TOGGLE_EN);
- wait_timeout(10);
-
- RTSX_READ_REG(chip, SD_BUS_STAT, &stat);
- if ((stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
- SD_DAT1_STATUS | SD_DAT0_STATUS)) !=
- (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
- SD_DAT1_STATUS | SD_DAT0_STATUS)) {
- RTSX_DEBUGP("SD_BUS_STAT: 0x%x\n", stat);
- rtsx_write_register(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
- rtsx_write_register(chip, CARD_CLK_EN, 0xFF, 0);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
-
- return STATUS_SUCCESS;
-}
-
-static int sd_reset_dcm(struct rtsx_chip *chip, u8 tune_dir)
-{
- if (tune_dir == TUNE_RX) {
- RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RESET | DCM_RX);
- RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RX);
- } else {
- RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RESET | DCM_TX);
- RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_TX);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- u16 SD_VP_CTL, SD_DCMPS_CTL;
- u8 val;
- int retval;
- int ddr_rx = 0;
-
- RTSX_DEBUGP("sd_change_phase (sample_point = %d, tune_dir = %d)\n",
- sample_point, tune_dir);
-
- if (tune_dir == TUNE_RX) {
- SD_VP_CTL = SD_VPRX_CTL;
- SD_DCMPS_CTL = SD_DCMPS_RX_CTL;
- if (CHK_SD_DDR50(sd_card))
- ddr_rx = 1;
- } else {
- SD_VP_CTL = SD_VPTX_CTL;
- SD_DCMPS_CTL = SD_DCMPS_TX_CTL;
- }
-
- if (chip->asic_code) {
- RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, CHANGE_CLK);
- RTSX_WRITE_REG(chip, SD_VP_CTL, 0x1F, sample_point);
- RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0);
- RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET);
- RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0);
- } else {
-#ifdef CONFIG_RTS_PSTOR_DEBUG
- rtsx_read_register(chip, SD_VP_CTL, &val);
- RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val);
- rtsx_read_register(chip, SD_DCMPS_CTL, &val);
- RTSX_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val);
-#endif
-
- if (ddr_rx) {
- RTSX_WRITE_REG(chip, SD_VP_CTL, PHASE_CHANGE, PHASE_CHANGE);
- udelay(50);
- RTSX_WRITE_REG(chip, SD_VP_CTL, 0xFF,
- PHASE_CHANGE | PHASE_NOT_RESET | sample_point);
- } else {
- RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, CHANGE_CLK);
- udelay(50);
- RTSX_WRITE_REG(chip, SD_VP_CTL, 0xFF,
- PHASE_NOT_RESET | sample_point);
- }
- udelay(100);
-
- rtsx_init_cmd(chip);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SD_DCMPS_CTL, DCMPS_CHANGE, DCMPS_CHANGE);
- rtsx_add_cmd(chip, CHECK_REG_CMD, SD_DCMPS_CTL, DCMPS_CHANGE_DONE, DCMPS_CHANGE_DONE);
- retval = rtsx_send_cmd(chip, SD_CARD, 100);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, Fail);
-
- val = *rtsx_get_cmd_data(chip);
- if (val & DCMPS_ERROR)
- TRACE_GOTO(chip, Fail);
-
- if ((val & DCMPS_CURRENT_PHASE) != sample_point)
- TRACE_GOTO(chip, Fail);
-
- RTSX_WRITE_REG(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0);
- if (ddr_rx)
- RTSX_WRITE_REG(chip, SD_VP_CTL, PHASE_CHANGE, 0);
- else
- RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0);
-
- udelay(50);
- }
-
- RTSX_WRITE_REG(chip, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0);
-
- return STATUS_SUCCESS;
-
-Fail:
-#ifdef CONFIG_RTS_PSTOR_DEBUG
- rtsx_read_register(chip, SD_VP_CTL, &val);
- RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val);
- rtsx_read_register(chip, SD_DCMPS_CTL, &val);
- RTSX_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val);
-#endif
-
- rtsx_write_register(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0);
- rtsx_write_register(chip, SD_VP_CTL, PHASE_CHANGE, 0);
- wait_timeout(10);
- sd_reset_dcm(chip, tune_dir);
- return STATUS_FAIL;
-}
-
-static int sd_check_spec(struct rtsx_chip *chip, u8 bus_width)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- u8 cmd[5], buf[8];
-
- retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- cmd[0] = 0x40 | SEND_SCR;
- cmd[1] = 0;
- cmd[2] = 0;
- cmd[3] = 0;
- cmd[4] = 0;
-
- retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 8, 1, bus_width, buf, 8, 250);
- if (retval != STATUS_SUCCESS) {
- rtsx_clear_sd_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- memcpy(sd_card->raw_scr, buf, 8);
-
- if ((buf[0] & 0x0F) == 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int sd_query_switch_result(struct rtsx_chip *chip, u8 func_group, u8 func_to_switch,
- u8 *buf, int buf_len)
-{
- u8 support_mask = 0, query_switch = 0, switch_busy = 0;
- int support_offset = 0, query_switch_offset = 0, check_busy_offset = 0;
-
- if (func_group == SD_FUNC_GROUP_1) {
- support_offset = FUNCTION_GROUP1_SUPPORT_OFFSET;
- query_switch_offset = FUNCTION_GROUP1_QUERY_SWITCH_OFFSET;
- check_busy_offset = FUNCTION_GROUP1_CHECK_BUSY_OFFSET;
-
- switch (func_to_switch) {
- case HS_SUPPORT:
- support_mask = HS_SUPPORT_MASK;
- query_switch = HS_QUERY_SWITCH_OK;
- switch_busy = HS_SWITCH_BUSY;
- break;
-
- case SDR50_SUPPORT:
- support_mask = SDR50_SUPPORT_MASK;
- query_switch = SDR50_QUERY_SWITCH_OK;
- switch_busy = SDR50_SWITCH_BUSY;
- break;
-
- case SDR104_SUPPORT:
- support_mask = SDR104_SUPPORT_MASK;
- query_switch = SDR104_QUERY_SWITCH_OK;
- switch_busy = SDR104_SWITCH_BUSY;
- break;
-
- case DDR50_SUPPORT:
- support_mask = DDR50_SUPPORT_MASK;
- query_switch = DDR50_QUERY_SWITCH_OK;
- switch_busy = DDR50_SWITCH_BUSY;
- break;
-
- default:
- TRACE_RET(chip, STATUS_FAIL);
- }
- } else if (func_group == SD_FUNC_GROUP_3) {
- support_offset = FUNCTION_GROUP3_SUPPORT_OFFSET;
- query_switch_offset = FUNCTION_GROUP3_QUERY_SWITCH_OFFSET;
- check_busy_offset = FUNCTION_GROUP3_CHECK_BUSY_OFFSET;
-
- switch (func_to_switch) {
- case DRIVING_TYPE_A:
- support_mask = DRIVING_TYPE_A_MASK;
- query_switch = TYPE_A_QUERY_SWITCH_OK;
- switch_busy = TYPE_A_SWITCH_BUSY;
- break;
-
- case DRIVING_TYPE_C:
- support_mask = DRIVING_TYPE_C_MASK;
- query_switch = TYPE_C_QUERY_SWITCH_OK;
- switch_busy = TYPE_C_SWITCH_BUSY;
- break;
-
- case DRIVING_TYPE_D:
- support_mask = DRIVING_TYPE_D_MASK;
- query_switch = TYPE_D_QUERY_SWITCH_OK;
- switch_busy = TYPE_D_SWITCH_BUSY;
- break;
-
- default:
- TRACE_RET(chip, STATUS_FAIL);
- }
- } else if (func_group == SD_FUNC_GROUP_4) {
- support_offset = FUNCTION_GROUP4_SUPPORT_OFFSET;
- query_switch_offset = FUNCTION_GROUP4_QUERY_SWITCH_OFFSET;
- check_busy_offset = FUNCTION_GROUP4_CHECK_BUSY_OFFSET;
-
- switch (func_to_switch) {
- case CURRENT_LIMIT_400:
- support_mask = CURRENT_LIMIT_400_MASK;
- query_switch = CURRENT_LIMIT_400_QUERY_SWITCH_OK;
- switch_busy = CURRENT_LIMIT_400_SWITCH_BUSY;
- break;
-
- case CURRENT_LIMIT_600:
- support_mask = CURRENT_LIMIT_600_MASK;
- query_switch = CURRENT_LIMIT_600_QUERY_SWITCH_OK;
- switch_busy = CURRENT_LIMIT_600_SWITCH_BUSY;
- break;
-
- case CURRENT_LIMIT_800:
- support_mask = CURRENT_LIMIT_800_MASK;
- query_switch = CURRENT_LIMIT_800_QUERY_SWITCH_OK;
- switch_busy = CURRENT_LIMIT_800_SWITCH_BUSY;
- break;
-
- default:
- TRACE_RET(chip, STATUS_FAIL);
- }
- } else {
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (func_group == SD_FUNC_GROUP_1) {
- if (!(buf[support_offset] & support_mask) ||
- ((buf[query_switch_offset] & 0x0F) != query_switch)) {
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- /* Check 'Busy Status' */
- if ((buf[DATA_STRUCTURE_VER_OFFSET] == 0x01) &&
- ((buf[check_busy_offset] & switch_busy) == switch_busy)) {
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode,
- u8 func_group, u8 func_to_switch, u8 bus_width)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- u8 cmd[5], buf[64];
-
- RTSX_DEBUGP("sd_check_switch_mode (mode = %d, func_group = %d, func_to_switch = %d)\n",
- mode, func_group, func_to_switch);
-
- cmd[0] = 0x40 | SWITCH;
- cmd[1] = mode;
-
- if (func_group == SD_FUNC_GROUP_1) {
- cmd[2] = 0xFF;
- cmd[3] = 0xFF;
- cmd[4] = 0xF0 + func_to_switch;
- } else if (func_group == SD_FUNC_GROUP_3) {
- cmd[2] = 0xFF;
- cmd[3] = 0xF0 + func_to_switch;
- cmd[4] = 0xFF;
- } else if (func_group == SD_FUNC_GROUP_4) {
- cmd[2] = 0xFF;
- cmd[3] = 0x0F + (func_to_switch << 4);
- cmd[4] = 0xFF;
- } else {
- cmd[1] = SD_CHECK_MODE;
- cmd[2] = 0xFF;
- cmd[3] = 0xFF;
- cmd[4] = 0xFF;
- }
-
- retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, bus_width, buf, 64, 250);
- if (retval != STATUS_SUCCESS) {
- rtsx_clear_sd_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- RTSX_DUMP(buf, 64);
-
- if (func_group == NO_ARGUMENT) {
- sd_card->func_group1_mask = buf[0x0D];
- sd_card->func_group2_mask = buf[0x0B];
- sd_card->func_group3_mask = buf[0x09];
- sd_card->func_group4_mask = buf[0x07];
-
- RTSX_DEBUGP("func_group1_mask = 0x%02x\n", buf[0x0D]);
- RTSX_DEBUGP("func_group2_mask = 0x%02x\n", buf[0x0B]);
- RTSX_DEBUGP("func_group3_mask = 0x%02x\n", buf[0x09]);
- RTSX_DEBUGP("func_group4_mask = 0x%02x\n", buf[0x07]);
- } else {
- /* Maximum current consumption, check whether current is acceptable;
- * bit[511:496] = 0x0000 means some error happened.
- */
- u16 cc = ((u16)buf[0] << 8) | buf[1];
- RTSX_DEBUGP("Maximum current consumption: %dmA\n", cc);
- if ((cc == 0) || (cc > 800))
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_query_switch_result(chip, func_group, func_to_switch, buf, 64);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if ((cc > 400) || (func_to_switch > CURRENT_LIMIT_400)) {
- RTSX_WRITE_REG(chip, OCPPARA2, SD_OCP_THD_MASK, chip->sd_800mA_ocp_thd);
- RTSX_WRITE_REG(chip, CARD_PWR_CTL, PMOS_STRG_MASK, PMOS_STRG_800mA);
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-static u8 downgrade_switch_mode(u8 func_group, u8 func_to_switch)
-{
- if (func_group == SD_FUNC_GROUP_1) {
- if (func_to_switch > HS_SUPPORT)
- func_to_switch--;
-
- } else if (func_group == SD_FUNC_GROUP_4) {
- if (func_to_switch > CURRENT_LIMIT_200)
- func_to_switch--;
- }
-
- return func_to_switch;
-}
-
-static int sd_check_switch(struct rtsx_chip *chip,
- u8 func_group, u8 func_to_switch, u8 bus_width)
-{
- int retval;
- int i;
- int switch_good = 0;
-
- for (i = 0; i < 3; i++) {
- if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
- sd_set_err_code(chip, SD_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = sd_check_switch_mode(chip, SD_CHECK_MODE, func_group,
- func_to_switch, bus_width);
- if (retval == STATUS_SUCCESS) {
- u8 stat;
-
- retval = sd_check_switch_mode(chip, SD_SWITCH_MODE,
- func_group, func_to_switch, bus_width);
- if (retval == STATUS_SUCCESS) {
- switch_good = 1;
- break;
- }
-
- RTSX_READ_REG(chip, SD_STAT1, &stat);
- if (stat & SD_CRC16_ERR) {
- RTSX_DEBUGP("SD CRC16 error when switching mode\n");
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- func_to_switch = downgrade_switch_mode(func_group, func_to_switch);
-
- wait_timeout(20);
- }
-
- if (!switch_good)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- int i;
- u8 func_to_switch = 0;
-
- /* Get supported functions */
- retval = sd_check_switch_mode(chip, SD_CHECK_MODE,
- NO_ARGUMENT, NO_ARGUMENT, bus_width);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- sd_card->func_group1_mask &= ~(sd_card->sd_switch_fail);
-
- /* Function Group 1: Access Mode */
- for (i = 0; i < 4; i++) {
- switch ((u8)(chip->sd_speed_prior >> (i*8))) {
- case SDR104_SUPPORT:
- if ((sd_card->func_group1_mask & SDR104_SUPPORT_MASK)
- && chip->sdr104_en) {
- func_to_switch = SDR104_SUPPORT;
- }
- break;
-
- case DDR50_SUPPORT:
- if ((sd_card->func_group1_mask & DDR50_SUPPORT_MASK)
- && chip->ddr50_en) {
- func_to_switch = DDR50_SUPPORT;
- }
- break;
-
- case SDR50_SUPPORT:
- if ((sd_card->func_group1_mask & SDR50_SUPPORT_MASK)
- && chip->sdr50_en) {
- func_to_switch = SDR50_SUPPORT;
- }
- break;
-
- case HS_SUPPORT:
- if (sd_card->func_group1_mask & HS_SUPPORT_MASK)
- func_to_switch = HS_SUPPORT;
-
- break;
-
- default:
- continue;
- }
-
-
- if (func_to_switch)
- break;
-
- }
- RTSX_DEBUGP("SD_FUNC_GROUP_1: func_to_switch = 0x%02x", func_to_switch);
-
-#ifdef SUPPORT_SD_LOCK
- if ((sd_card->sd_lock_status & SD_SDR_RST)
- && (DDR50_SUPPORT == func_to_switch)
- && (sd_card->func_group1_mask & SDR50_SUPPORT_MASK)) {
- func_to_switch = SDR50_SUPPORT;
- RTSX_DEBUGP("Using SDR50 instead of DDR50 for SD Lock\n");
- }
-#endif
-
- if (func_to_switch) {
- retval = sd_check_switch(chip, SD_FUNC_GROUP_1, func_to_switch, bus_width);
- if (retval != STATUS_SUCCESS) {
- if (func_to_switch == SDR104_SUPPORT) {
- sd_card->sd_switch_fail = SDR104_SUPPORT_MASK;
- } else if (func_to_switch == DDR50_SUPPORT) {
- sd_card->sd_switch_fail =
- SDR104_SUPPORT_MASK | DDR50_SUPPORT_MASK;
- } else if (func_to_switch == SDR50_SUPPORT) {
- sd_card->sd_switch_fail =
- SDR104_SUPPORT_MASK | DDR50_SUPPORT_MASK |
- SDR50_SUPPORT_MASK;
- }
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (func_to_switch == SDR104_SUPPORT)
- SET_SD_SDR104(sd_card);
- else if (func_to_switch == DDR50_SUPPORT)
- SET_SD_DDR50(sd_card);
- else if (func_to_switch == SDR50_SUPPORT)
- SET_SD_SDR50(sd_card);
- else
- SET_SD_HS(sd_card);
- }
-
- if (CHK_SD_DDR50(sd_card)) {
- RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0x06, 0x04);
- retval = sd_set_sample_push_timing(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (!func_to_switch || (func_to_switch == HS_SUPPORT)) {
- /* Do not try to switch current limit if the card doesn't
- * support UHS mode or we don't want it to support UHS mode
- */
- return STATUS_SUCCESS;
- }
-
- /* Function Group 4: Current Limit */
- func_to_switch = 0xFF;
-
- for (i = 0; i < 4; i++) {
- switch ((u8)(chip->sd_current_prior >> (i*8))) {
- case CURRENT_LIMIT_800:
- if (sd_card->func_group4_mask & CURRENT_LIMIT_800_MASK)
- func_to_switch = CURRENT_LIMIT_800;
-
- break;
-
- case CURRENT_LIMIT_600:
- if (sd_card->func_group4_mask & CURRENT_LIMIT_600_MASK)
- func_to_switch = CURRENT_LIMIT_600;
-
- break;
-
- case CURRENT_LIMIT_400:
- if (sd_card->func_group4_mask & CURRENT_LIMIT_400_MASK)
- func_to_switch = CURRENT_LIMIT_400;
-
- break;
-
- case CURRENT_LIMIT_200:
- if (sd_card->func_group4_mask & CURRENT_LIMIT_200_MASK)
- func_to_switch = CURRENT_LIMIT_200;
-
- break;
-
- default:
- continue;
- }
-
- if (func_to_switch != 0xFF)
- break;
- }
-
- RTSX_DEBUGP("SD_FUNC_GROUP_4: func_to_switch = 0x%02x", func_to_switch);
-
- if (func_to_switch <= CURRENT_LIMIT_800) {
- retval = sd_check_switch(chip, SD_FUNC_GROUP_4, func_to_switch, bus_width);
- if (retval != STATUS_SUCCESS) {
- if (sd_check_err_code(chip, SD_NO_CARD))
- TRACE_RET(chip, STATUS_FAIL);
- }
- RTSX_DEBUGP("Switch current limit finished! (%d)\n", retval);
- }
-
- if (CHK_SD_DDR50(sd_card))
- RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0x06, 0);
-
- return STATUS_SUCCESS;
-}
-
-static int sd_wait_data_idle(struct rtsx_chip *chip)
-{
- int retval = STATUS_TIMEDOUT;
- int i;
- u8 val = 0;
-
- for (i = 0; i < 100; i++) {
- RTSX_READ_REG(chip, SD_DATA_STATE, &val);
- if (val & SD_DATA_IDLE) {
- retval = STATUS_SUCCESS;
- break;
- }
- udelay(100);
- }
- RTSX_DEBUGP("SD_DATA_STATE: 0x%02x\n", val);
-
- return retval;
-}
-
-static int sd_sdr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point)
-{
- int retval;
- u8 cmd[5];
-
- retval = sd_change_phase(chip, sample_point, TUNE_RX);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- cmd[0] = 0x40 | SEND_TUNING_PATTERN;
- cmd[1] = 0;
- cmd[2] = 0;
- cmd[3] = 0;
- cmd[4] = 0;
-
- retval = sd_read_data(chip, SD_TM_AUTO_TUNING,
- cmd, 5, 0x40, 1, SD_BUS_WIDTH_4, NULL, 0, 100);
- if (retval != STATUS_SUCCESS) {
- (void)sd_wait_data_idle(chip);
-
- rtsx_clear_sd_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int sd_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- u8 cmd[5];
-
- retval = sd_change_phase(chip, sample_point, TUNE_RX);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_DEBUGP("sd ddr tuning rx\n");
-
- retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- cmd[0] = 0x40 | SD_STATUS;
- cmd[1] = 0;
- cmd[2] = 0;
- cmd[3] = 0;
- cmd[4] = 0;
-
- retval = sd_read_data(chip, SD_TM_NORMAL_READ,
- cmd, 5, 64, 1, SD_BUS_WIDTH_4, NULL, 0, 100);
- if (retval != STATUS_SUCCESS) {
- (void)sd_wait_data_idle(chip);
-
- rtsx_clear_sd_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int mmc_ddr_tunning_rx_cmd(struct rtsx_chip *chip, u8 sample_point)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- u8 cmd[5], bus_width;
-
- if (CHK_MMC_8BIT(sd_card))
- bus_width = SD_BUS_WIDTH_8;
- else if (CHK_MMC_4BIT(sd_card))
- bus_width = SD_BUS_WIDTH_4;
- else
- bus_width = SD_BUS_WIDTH_1;
-
- retval = sd_change_phase(chip, sample_point, TUNE_RX);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_DEBUGP("mmc ddr tuning rx\n");
-
- cmd[0] = 0x40 | SEND_EXT_CSD;
- cmd[1] = 0;
- cmd[2] = 0;
- cmd[3] = 0;
- cmd[4] = 0;
-
- retval = sd_read_data(chip, SD_TM_NORMAL_READ,
- cmd, 5, 0x200, 1, bus_width, NULL, 0, 100);
- if (retval != STATUS_SUCCESS) {
- (void)sd_wait_data_idle(chip);
-
- rtsx_clear_sd_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int sd_sdr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
-
- retval = sd_change_phase(chip, sample_point, TUNE_TX);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, SD_RSP_80CLK_TIMEOUT_EN);
-
- retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
- SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS) {
- if (sd_check_err_code(chip, SD_RSP_TIMEOUT)) {
- rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0);
-
- return STATUS_SUCCESS;
-}
-
-static int sd_ddr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- u8 cmd[5], bus_width;
-
- retval = sd_change_phase(chip, sample_point, TUNE_TX);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHK_SD(sd_card)) {
- bus_width = SD_BUS_WIDTH_4;
- } else {
- if (CHK_MMC_8BIT(sd_card))
- bus_width = SD_BUS_WIDTH_8;
- else if (CHK_MMC_4BIT(sd_card))
- bus_width = SD_BUS_WIDTH_4;
- else
- bus_width = SD_BUS_WIDTH_1;
- }
-
- retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, SD_RSP_80CLK_TIMEOUT_EN);
-
- cmd[0] = 0x40 | PROGRAM_CSD;
- cmd[1] = 0;
- cmd[2] = 0;
- cmd[3] = 0;
- cmd[4] = 0;
-
- retval = sd_write_data(chip, SD_TM_AUTO_WRITE_2,
- cmd, 5, 16, 1, bus_width, sd_card->raw_csd, 16, 100);
- if (retval != STATUS_SUCCESS) {
- rtsx_clear_sd_error(chip);
- rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0);
-
- sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
-
- return STATUS_SUCCESS;
-}
-
-static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map, u8 tune_dir)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- struct timing_phase_path path[MAX_PHASE + 1];
- int i, j, cont_path_cnt;
- int new_block, max_len, final_path_idx;
- u8 final_phase = 0xFF;
-
- if (phase_map == 0xFFFFFFFF) {
- if (tune_dir == TUNE_RX)
- final_phase = (u8)chip->sd_default_rx_phase;
- else
- final_phase = (u8)chip->sd_default_tx_phase;
-
- goto Search_Finish;
- }
-
- cont_path_cnt = 0;
- new_block = 1;
- j = 0;
- for (i = 0; i < MAX_PHASE + 1; i++) {
- if (phase_map & (1 << i)) {
- if (new_block) {
- new_block = 0;
- j = cont_path_cnt++;
- path[j].start = i;
- path[j].end = i;
- } else {
- path[j].end = i;
- }
- } else {
- new_block = 1;
- if (cont_path_cnt) {
- int idx = cont_path_cnt - 1;
- path[idx].len = path[idx].end - path[idx].start + 1;
- path[idx].mid = path[idx].start + path[idx].len / 2;
- }
- }
- }
-
- if (cont_path_cnt == 0) {
- RTSX_DEBUGP("No continuous phase path\n");
- goto Search_Finish;
- } else {
- int idx = cont_path_cnt - 1;
- path[idx].len = path[idx].end - path[idx].start + 1;
- path[idx].mid = path[idx].start + path[idx].len / 2;
- }
-
- if ((path[0].start == 0) && (path[cont_path_cnt - 1].end == MAX_PHASE)) {
- path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1;
- path[0].len += path[cont_path_cnt - 1].len;
- path[0].mid = path[0].start + path[0].len / 2;
- if (path[0].mid < 0)
- path[0].mid += MAX_PHASE + 1;
-
- cont_path_cnt--;
- }
-
- max_len = 0;
- final_phase = 0;
- final_path_idx = 0;
- for (i = 0; i < cont_path_cnt; i++) {
- if (path[i].len > max_len) {
- max_len = path[i].len;
- final_phase = (u8)path[i].mid;
- final_path_idx = i;
- }
-
- RTSX_DEBUGP("path[%d].start = %d\n", i, path[i].start);
- RTSX_DEBUGP("path[%d].end = %d\n", i, path[i].end);
- RTSX_DEBUGP("path[%d].len = %d\n", i, path[i].len);
- RTSX_DEBUGP("path[%d].mid = %d\n", i, path[i].mid);
- RTSX_DEBUGP("\n");
- }
-
- if (tune_dir == TUNE_TX) {
- if (CHK_SD_SDR104(sd_card)) {
- if (max_len > 15) {
- int temp_mid = (max_len - 16) / 2;
- int temp_final_phase =
- path[final_path_idx].end - (max_len - (6 + temp_mid));
-
- if (temp_final_phase < 0)
- final_phase = (u8)(temp_final_phase + MAX_PHASE + 1);
- else
- final_phase = (u8)temp_final_phase;
- }
- } else if (CHK_SD_SDR50(sd_card)) {
- if (max_len > 12) {
- int temp_mid = (max_len - 13) / 2;
- int temp_final_phase =
- path[final_path_idx].end - (max_len - (3 + temp_mid));
-
- if (temp_final_phase < 0)
- final_phase = (u8)(temp_final_phase + MAX_PHASE + 1);
- else
- final_phase = (u8)temp_final_phase;
- }
- }
- }
-
-Search_Finish:
- RTSX_DEBUGP("Final chosen phase: %d\n", final_phase);
- return final_phase;
-}
-
-static int sd_tuning_rx(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- int i, j;
- u32 raw_phase_map[3], phase_map;
- u8 final_phase;
- int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point);
-
- if (CHK_SD(sd_card)) {
- if (CHK_SD_DDR50(sd_card))
- tuning_cmd = sd_ddr_tuning_rx_cmd;
- else
- tuning_cmd = sd_sdr_tuning_rx_cmd;
-
- } else {
- if (CHK_MMC_DDR52(sd_card))
- tuning_cmd = mmc_ddr_tunning_rx_cmd;
- else
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- for (i = 0; i < 3; i++) {
- raw_phase_map[i] = 0;
- for (j = MAX_PHASE; j >= 0; j--) {
- if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
- sd_set_err_code(chip, SD_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = tuning_cmd(chip, (u8)j);
- if (retval == STATUS_SUCCESS)
- raw_phase_map[i] |= 1 << j;
- }
- }
-
- phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2];
- for (i = 0; i < 3; i++)
- RTSX_DEBUGP("RX raw_phase_map[%d] = 0x%08x\n", i, raw_phase_map[i]);
-
- RTSX_DEBUGP("RX phase_map = 0x%08x\n", phase_map);
-
- final_phase = sd_search_final_phase(chip, phase_map, TUNE_RX);
- if (final_phase == 0xFF)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_change_phase(chip, final_phase, TUNE_RX);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int sd_ddr_pre_tuning_tx(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- int i;
- u32 phase_map;
- u8 final_phase;
-
- RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, SD_RSP_80CLK_TIMEOUT_EN);
-
- phase_map = 0;
- for (i = MAX_PHASE; i >= 0; i--) {
- if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
- sd_set_err_code(chip, SD_NO_CARD);
- rtsx_write_register(chip, SD_CFG3,
- SD_RSP_80CLK_TIMEOUT_EN, 0);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = sd_change_phase(chip, (u8)i, TUNE_TX);
- if (retval != STATUS_SUCCESS)
- continue;
-
- retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
- SD_RSP_TYPE_R1, NULL, 0);
- if ((retval == STATUS_SUCCESS) || !sd_check_err_code(chip, SD_RSP_TIMEOUT))
- phase_map |= 1 << i;
- }
-
- RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0);
-
- RTSX_DEBUGP("DDR TX pre tune phase_map = 0x%08x\n", phase_map);
-
- final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX);
- if (final_phase == 0xFF)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_change_phase(chip, final_phase, TUNE_TX);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_DEBUGP("DDR TX pre tune phase: %d\n", (int)final_phase);
-
- return STATUS_SUCCESS;
-}
-
-static int sd_tuning_tx(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- int i, j;
- u32 raw_phase_map[3], phase_map;
- u8 final_phase;
- int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point);
-
- if (CHK_SD(sd_card)) {
- if (CHK_SD_DDR50(sd_card))
- tuning_cmd = sd_ddr_tuning_tx_cmd;
- else
- tuning_cmd = sd_sdr_tuning_tx_cmd;
-
- } else {
- if (CHK_MMC_DDR52(sd_card))
- tuning_cmd = sd_ddr_tuning_tx_cmd;
- else
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- for (i = 0; i < 3; i++) {
- raw_phase_map[i] = 0;
- for (j = MAX_PHASE; j >= 0; j--) {
- if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
- sd_set_err_code(chip, SD_NO_CARD);
- rtsx_write_register(chip, SD_CFG3,
- SD_RSP_80CLK_TIMEOUT_EN, 0);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = tuning_cmd(chip, (u8)j);
- if (retval == STATUS_SUCCESS)
- raw_phase_map[i] |= 1 << j;
- }
- }
-
- phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2];
- for (i = 0; i < 3; i++)
- RTSX_DEBUGP("TX raw_phase_map[%d] = 0x%08x\n", i, raw_phase_map[i]);
-
- RTSX_DEBUGP("TX phase_map = 0x%08x\n", phase_map);
-
- final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX);
- if (final_phase == 0xFF)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_change_phase(chip, final_phase, TUNE_TX);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int sd_sdr_tuning(struct rtsx_chip *chip)
-{
- int retval;
-
- retval = sd_tuning_tx(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_tuning_rx(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int sd_ddr_tuning(struct rtsx_chip *chip)
-{
- int retval;
-
- if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) {
- retval = sd_ddr_pre_tuning_tx(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- retval = sd_change_phase(chip, (u8)chip->sd_ddr_tx_phase, TUNE_TX);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = sd_tuning_rx(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) {
- retval = sd_tuning_tx(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int mmc_ddr_tuning(struct rtsx_chip *chip)
-{
- int retval;
-
- if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) {
- retval = sd_ddr_pre_tuning_tx(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- retval = sd_change_phase(chip, (u8)chip->mmc_ddr_tx_phase, TUNE_TX);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = sd_tuning_rx(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) {
- retval = sd_tuning_tx(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-int sd_switch_clock(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- int re_tuning = 0;
-
- retval = select_card(chip, SD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHECK_PID(chip, 0x5209) &&
- (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card))) {
- if (sd_card->need_retune && (sd_card->sd_clock != chip->cur_clk)) {
- re_tuning = 1;
- sd_card->need_retune = 0;
- }
- }
-
- retval = switch_clock(chip, sd_card->sd_clock);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (re_tuning) {
- if (CHK_SD(sd_card)) {
- if (CHK_SD_DDR50(sd_card))
- retval = sd_ddr_tuning(chip);
- else
- retval = sd_sdr_tuning(chip);
- } else {
- if (CHK_MMC_DDR52(sd_card))
- retval = mmc_ddr_tuning(chip);
- }
-
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int sd_prepare_reset(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
-
- if (chip->asic_code)
- sd_card->sd_clock = 29;
- else
- sd_card->sd_clock = CLK_30;
-
- sd_card->sd_type = 0;
- sd_card->seq_mode = 0;
- sd_card->sd_data_buf_ready = 0;
- sd_card->capacity = 0;
-
-#ifdef SUPPORT_SD_LOCK
- sd_card->sd_lock_status = 0;
- sd_card->sd_erase_status = 0;
-#endif
-
- chip->capacity[chip->card2lun[SD_CARD]] = 0;
- chip->sd_io = 0;
-
- retval = sd_set_init_para(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, retval);
-
- if (CHECK_PID(chip, 0x5209)) {
- RTSX_WRITE_REG(chip, REG_SD_CFG1, 0xFF,
- SD_CLK_DIVIDE_128 | SD_20_MODE | SD_BUS_WIDTH_1);
- RTSX_WRITE_REG(chip, SD_SAMPLE_POINT_CTL, 0xFF, SD20_RX_POS_EDGE);
- RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0xFF, 0);
- } else {
- RTSX_WRITE_REG(chip, REG_SD_CFG1, 0xFF, 0x40);
- }
-
- RTSX_WRITE_REG(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR);
-
- retval = select_card(chip, SD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int sd_pull_ctl_disable(struct rtsx_chip *chip)
-{
- if (CHECK_PID(chip, 0x5209)) {
- RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0xD5);
- } else if (CHECK_PID(chip, 0x5208)) {
- RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF,
- XD_D3_PD | SD_D7_PD | SD_CLK_PD | SD_D5_PD);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF,
- SD_D6_PD | SD_D0_PD | SD_D1_PD | XD_D5_PD);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF,
- SD_D4_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF,
- XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF,
- MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD);
- } else if (CHECK_PID(chip, 0x5288)) {
- if (CHECK_BARO_PKG(chip, QFN)) {
- RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69);
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-int sd_pull_ctl_enable(struct rtsx_chip *chip)
-{
- int retval;
-
- rtsx_init_cmd(chip);
-
- if (CHECK_PID(chip, 0x5209)) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xAA);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0xAA);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xE9);
- } else if (CHECK_PID(chip, 0x5208)) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF,
- XD_D3_PD | SD_DAT7_PU | SD_CLK_NP | SD_D5_PU);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF,
- SD_D6_PU | SD_D0_PU | SD_D1_PU | XD_D5_PD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF,
- SD_D4_PU | XD_CE_PD | XD_CLE_PD | XD_CD_PU);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF,
- XD_RDY_PD | SD_D3_PU | SD_D2_PU | XD_ALE_PD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF,
- MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD);
- } else if (CHECK_PID(chip, 0x5288)) {
- if (CHECK_BARO_PKG(chip, QFN)) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xA8);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x5A);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0xAA);
- }
- }
-
- retval = rtsx_send_cmd(chip, SD_CARD, 100);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int sd_init_power(struct rtsx_chip *chip)
-{
- int retval;
-
- if (CHECK_PID(chip, 0x5209))
- RTSX_WRITE_REG(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF);
-
- retval = sd_power_off_card3v3(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (!chip->ft2_fast_mode)
- wait_timeout(250);
-
- retval = enable_card_clock(chip, SD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (chip->asic_code) {
- retval = sd_pull_ctl_enable(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_SD_PULL_CTL_BIT | 0x20, 0);
- }
-
- if (chip->ft2_fast_mode) {
- if (CHECK_PID(chip, 0x5209))
- RTSX_WRITE_REG(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON);
-
- } else {
- retval = card_power_on(chip, SD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- wait_timeout(260);
-
-#ifdef SUPPORT_OCP
- if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
- RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat);
- TRACE_RET(chip, STATUS_FAIL);
- }
-#endif
- }
-
- RTSX_WRITE_REG(chip, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN);
-
- return STATUS_SUCCESS;
-}
-
-static int sd_dummy_clock(struct rtsx_chip *chip)
-{
- if (CHECK_PID(chip, 0x5209)) {
- RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN, SD_CLK_TOGGLE_EN);
- wait_timeout(5);
- RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0x00);
- } else {
- RTSX_WRITE_REG(chip, REG_SD_CFG3, 0x01, 0x01);
- wait_timeout(5);
- RTSX_WRITE_REG(chip, REG_SD_CFG3, 0x01, 0);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int sd_read_lba0(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- u8 cmd[5], bus_width;
-
- cmd[0] = 0x40 | READ_SINGLE_BLOCK;
- cmd[1] = 0;
- cmd[2] = 0;
- cmd[3] = 0;
- cmd[4] = 0;
-
- if (CHK_SD(sd_card)) {
- bus_width = SD_BUS_WIDTH_4;
- } else {
- if (CHK_MMC_8BIT(sd_card))
- bus_width = SD_BUS_WIDTH_8;
- else if (CHK_MMC_4BIT(sd_card))
- bus_width = SD_BUS_WIDTH_4;
- else
- bus_width = SD_BUS_WIDTH_1;
- }
-
- retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd,
- 5, 512, 1, bus_width, NULL, 0, 100);
- if (retval != STATUS_SUCCESS) {
- rtsx_clear_sd_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int sd_check_wp_state(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- u32 val;
- u16 sd_card_type;
- u8 cmd[5], buf[64];
-
- retval = sd_send_cmd_get_rsp(chip, APP_CMD,
- sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- cmd[0] = 0x40 | SD_STATUS;
- cmd[1] = 0;
- cmd[2] = 0;
- cmd[3] = 0;
- cmd[4] = 0;
-
- retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, SD_BUS_WIDTH_4, buf, 64, 250);
- if (retval != STATUS_SUCCESS) {
- rtsx_clear_sd_error(chip);
-
- sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- RTSX_DEBUGP("ACMD13:\n");
- RTSX_DUMP(buf, 64);
-
- sd_card_type = ((u16)buf[2] << 8) | buf[3];
- RTSX_DEBUGP("sd_card_type = 0x%04x\n", sd_card_type);
- if ((sd_card_type == 0x0001) || (sd_card_type == 0x0002)) {
- /* ROM card or OTP */
- chip->card_wp |= SD_CARD;
- }
-
- /* Check SD Machanical Write-Protect Switch */
- val = rtsx_readl(chip, RTSX_BIPR);
- if (val & SD_WRITE_PROTECT)
- chip->card_wp |= SD_CARD;
-
- return STATUS_SUCCESS;
-}
-
-static int reset_sd(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval, i = 0, j = 0, k = 0, hi_cap_flow = 0;
- int sd_dont_switch = 0;
- int support_1v8 = 0;
- int try_sdio = 1;
- u8 rsp[16];
- u8 switch_bus_width;
- u32 voltage = 0;
- int sd20_mode = 0;
-
- SET_SD(sd_card);
-
-Switch_Fail:
-
- i = 0;
- j = 0;
- k = 0;
- hi_cap_flow = 0;
-
-#ifdef SUPPORT_SD_LOCK
- if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON)
- goto SD_UNLOCK_ENTRY;
-#endif
-
- retval = sd_prepare_reset(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_dummy_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) && try_sdio) {
- int rty_cnt = 0;
-
- for (; rty_cnt < chip->sdio_retry_cnt; rty_cnt++) {
- if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
- sd_set_err_code(chip, SD_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = sd_send_cmd_get_rsp(chip, IO_SEND_OP_COND, 0, SD_RSP_TYPE_R4, rsp, 5);
- if (retval == STATUS_SUCCESS) {
- int func_num = (rsp[1] >> 4) & 0x07;
- if (func_num) {
- RTSX_DEBUGP("SD_IO card (Function number: %d)!\n", func_num);
- chip->sd_io = 1;
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- break;
- }
-
- sd_init_power(chip);
-
- sd_dummy_clock(chip);
- }
-
- RTSX_DEBUGP("Normal card!\n");
- }
-
- /* Start Initialization Process of SD Card */
-RTY_SD_RST:
- retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- wait_timeout(20);
-
- retval = sd_send_cmd_get_rsp(chip, SEND_IF_COND, 0x000001AA, SD_RSP_TYPE_R7, rsp, 5);
- if (retval == STATUS_SUCCESS) {
- if ((rsp[4] == 0xAA) && ((rsp[3] & 0x0f) == 0x01)) {
- hi_cap_flow = 1;
- if (CHECK_PID(chip, 0x5209)) {
- if (sd20_mode) {
- voltage = SUPPORT_VOLTAGE |
- SUPPORT_HIGH_AND_EXTENDED_CAPACITY;
- } else {
- voltage = SUPPORT_VOLTAGE |
- SUPPORT_HIGH_AND_EXTENDED_CAPACITY |
- SUPPORT_MAX_POWER_PERMANCE | SUPPORT_1V8;
- }
- } else {
- voltage = SUPPORT_VOLTAGE | 0x40000000;
- }
- }
- }
-
- if (!hi_cap_flow) {
- voltage = SUPPORT_VOLTAGE;
-
- retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- wait_timeout(20);
- }
-
- do {
- retval = sd_send_cmd_get_rsp(chip, APP_CMD, 0, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS) {
- if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
- sd_set_err_code(chip, SD_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- j++;
- if (j < 3)
- goto RTY_SD_RST;
- else
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = sd_send_cmd_get_rsp(chip, SD_APP_OP_COND, voltage, SD_RSP_TYPE_R3, rsp, 5);
- if (retval != STATUS_SUCCESS) {
- k++;
- if (k < 3)
- goto RTY_SD_RST;
- else
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- i++;
- wait_timeout(20);
- } while (!(rsp[1] & 0x80) && (i < 255));
-
- if (i == 255)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (hi_cap_flow) {
- if (rsp[1] & 0x40)
- SET_SD_HCXC(sd_card);
- else
- CLR_SD_HCXC(sd_card);
-
- if (CHECK_PID(chip, 0x5209) && CHK_SD_HCXC(sd_card) && !sd20_mode)
- support_1v8 = (rsp[1] & 0x01) ? 1 : 0;
- else
- support_1v8 = 0;
- } else {
- CLR_SD_HCXC(sd_card);
- support_1v8 = 0;
- }
- RTSX_DEBUGP("support_1v8 = %d\n", support_1v8);
-
- if (support_1v8) {
- retval = sd_voltage_switch(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- for (i = 0; i < 3; i++) {
- retval = sd_send_cmd_get_rsp(chip, SEND_RELATIVE_ADDR, 0, SD_RSP_TYPE_R6, rsp, 5);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- sd_card->sd_addr = (u32)rsp[1] << 24;
- sd_card->sd_addr += (u32)rsp[2] << 16;
-
- if (sd_card->sd_addr)
- break;
- }
-
- retval = sd_check_csd(chip, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_select_card(chip, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
-#ifdef SUPPORT_SD_LOCK
-SD_UNLOCK_ENTRY:
- retval = sd_update_lock_status(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (sd_card->sd_lock_status & SD_LOCKED) {
- sd_card->sd_lock_status |= (SD_LOCK_1BIT_MODE | SD_PWD_EXIST);
- return STATUS_SUCCESS;
- } else if (!(sd_card->sd_lock_status & SD_UNLOCK_POW_ON)) {
- sd_card->sd_lock_status &= ~SD_PWD_EXIST;
- }
-#endif
-
- retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_send_cmd_get_rsp(chip, SET_CLR_CARD_DETECT, 0, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (support_1v8) {
- retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- switch_bus_width = SD_BUS_WIDTH_4;
- } else {
- switch_bus_width = SD_BUS_WIDTH_1;
- }
-
- retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (!(sd_card->raw_csd[4] & 0x40))
- sd_dont_switch = 1;
-
- if (!sd_dont_switch) {
- if (sd20_mode) {
- /* Set sd_switch_fail here, because we needn't
- * switch to UHS mode
- */
- sd_card->sd_switch_fail = SDR104_SUPPORT_MASK |
- DDR50_SUPPORT_MASK | SDR50_SUPPORT_MASK;
- }
-
- /* Check the card whether follow SD1.1 spec or higher */
- retval = sd_check_spec(chip, switch_bus_width);
- if (retval == STATUS_SUCCESS) {
- retval = sd_switch_function(chip, switch_bus_width);
- if (retval != STATUS_SUCCESS) {
- if (CHECK_PID(chip, 0x5209))
- sd_change_bank_voltage(chip, SD_IO_3V3);
-
- sd_init_power(chip);
- sd_dont_switch = 1;
- try_sdio = 0;
-
- goto Switch_Fail;
- }
- } else {
- if (support_1v8) {
- if (CHECK_PID(chip, 0x5209))
- sd_change_bank_voltage(chip, SD_IO_3V3);
-
- sd_init_power(chip);
- sd_dont_switch = 1;
- try_sdio = 0;
-
- goto Switch_Fail;
- }
- }
- }
-
- if (!support_1v8) {
- retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
-#ifdef SUPPORT_SD_LOCK
- sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE;
-#endif
-
- if (!sd20_mode && CHK_SD30_SPEED(sd_card)) {
- int read_lba0 = 1;
-
- RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07, chip->sd30_drive_sel_1v8);
-
- retval = sd_set_init_para(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHK_SD_DDR50(sd_card))
- retval = sd_ddr_tuning(chip);
- else
- retval = sd_sdr_tuning(chip);
-
- if (retval != STATUS_SUCCESS) {
- if (sd20_mode) {
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- retval = sd_init_power(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- try_sdio = 0;
- sd20_mode = 1;
- goto Switch_Fail;
- }
- }
-
- sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
-
- if (CHK_SD_DDR50(sd_card)) {
- retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000);
- if (retval != STATUS_SUCCESS)
- read_lba0 = 0;
- }
-
- if (read_lba0) {
- retval = sd_read_lba0(chip);
- if (retval != STATUS_SUCCESS) {
- if (sd20_mode) {
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- retval = sd_init_power(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- try_sdio = 0;
- sd20_mode = 1;
- goto Switch_Fail;
- }
- }
- }
- }
-
- retval = sd_check_wp_state(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- chip->card_bus_width[chip->card2lun[SD_CARD]] = 4;
-
-#ifdef SUPPORT_SD_LOCK
- if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) {
- RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_H, 0xFF, 0x02);
- RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_L, 0xFF, 0x00);
- }
-#endif
-
- return STATUS_SUCCESS;
-}
-
-
-static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- u8 buf[8] = {0}, bus_width, *ptr;
- u16 byte_cnt;
- int len;
-
- retval = sd_send_cmd_get_rsp(chip, BUSTEST_W, 0, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, SWITCH_FAIL);
-
- if (width == MMC_8BIT_BUS) {
- buf[0] = 0x55;
- buf[1] = 0xAA;
- len = 8;
- byte_cnt = 8;
- bus_width = SD_BUS_WIDTH_8;
- } else {
- buf[0] = 0x5A;
- len = 4;
- byte_cnt = 4;
- bus_width = SD_BUS_WIDTH_4;
- }
-
- if (!CHECK_PID(chip, 0x5209)) {
- retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0x02);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, SWITCH_ERR);
- }
-
- retval = sd_write_data(chip, SD_TM_AUTO_WRITE_3,
- NULL, 0, byte_cnt, 1, bus_width, buf, len, 100);
- if (retval != STATUS_SUCCESS) {
- if (CHECK_PID(chip, 0x5209)) {
- u8 val1 = 0, val2 = 0;
- rtsx_read_register(chip, REG_SD_STAT1, &val1);
- rtsx_read_register(chip, REG_SD_STAT2, &val2);
- rtsx_clear_sd_error(chip);
- if ((val1 & 0xE0) || val2)
- TRACE_RET(chip, SWITCH_ERR);
- } else {
- rtsx_clear_sd_error(chip);
- rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0);
- TRACE_RET(chip, SWITCH_ERR);
- }
- }
-
- if (!CHECK_PID(chip, 0x5209)) {
- retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, SWITCH_ERR);
- }
-
- RTSX_DEBUGP("SD/MMC CMD %d\n", BUSTEST_R);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | BUSTEST_R);
-
- if (width == MMC_8BIT_BUS)
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x08);
- else
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x04);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF,
- SD_CALCULATE_CRC7 | SD_NO_CHECK_CRC16 | SD_NO_WAIT_BUSY_END |
- SD_CHECK_CRC7 | SD_RSP_LEN_6);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, SD_TM_NORMAL_READ | SD_TRANSFER_START);
- rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END);
-
- rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2, 0, 0);
- if (width == MMC_8BIT_BUS)
- rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 1, 0, 0);
-
- retval = rtsx_send_cmd(chip, SD_CARD, 100);
- if (retval < 0) {
- rtsx_clear_sd_error(chip);
- TRACE_RET(chip, SWITCH_ERR);
- }
-
- ptr = rtsx_get_cmd_data(chip) + 1;
-
- if (width == MMC_8BIT_BUS) {
- RTSX_DEBUGP("BUSTEST_R [8bits]: 0x%02x 0x%02x\n", ptr[0], ptr[1]);
- if ((ptr[0] == 0xAA) && (ptr[1] == 0x55)) {
- u8 rsp[5];
- u32 arg;
-
- if (CHK_MMC_DDR52(sd_card))
- arg = 0x03B70600;
- else
- arg = 0x03B70200;
-
- retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, SD_RSP_TYPE_R1b, rsp, 5);
- if ((retval == STATUS_SUCCESS) && !(rsp[4] & MMC_SWITCH_ERR))
- return SWITCH_SUCCESS;
- }
- } else {
- RTSX_DEBUGP("BUSTEST_R [4bits]: 0x%02x\n", ptr[0]);
- if (ptr[0] == 0xA5) {
- u8 rsp[5];
- u32 arg;
-
- if (CHK_MMC_DDR52(sd_card))
- arg = 0x03B70500;
- else
- arg = 0x03B70100;
-
- retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, SD_RSP_TYPE_R1b, rsp, 5);
- if ((retval == STATUS_SUCCESS) && !(rsp[4] & MMC_SWITCH_ERR))
- return SWITCH_SUCCESS;
- }
- }
-
- TRACE_RET(chip, SWITCH_FAIL);
-}
-
-
-static int mmc_switch_timing_bus(struct rtsx_chip *chip, int switch_ddr)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
- u8 *ptr, card_type, card_type_mask = 0;
-
- CLR_MMC_HS(sd_card);
-
- RTSX_DEBUGP("SD/MMC CMD %d\n", SEND_EXT_CSD);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | SEND_EXT_CSD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, 0);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, 0);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, 0);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, 0);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 2);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF,
- SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END |
- SD_CHECK_CRC7 | SD_RSP_LEN_6);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, SD_TM_NORMAL_READ | SD_TRANSFER_START);
- rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END);
-
- rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 196, 0xFF, 0);
- rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 212, 0xFF, 0);
- rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 213, 0xFF, 0);
- rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 214, 0xFF, 0);
- rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 215, 0xFF, 0);
-
- retval = rtsx_send_cmd(chip, SD_CARD, 1000);
- if (retval < 0) {
- if (retval == -ETIMEDOUT) {
- rtsx_clear_sd_error(chip);
- sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
- SD_RSP_TYPE_R1, NULL, 0);
- }
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- ptr = rtsx_get_cmd_data(chip);
- if (ptr[0] & SD_TRANSFER_ERR) {
- sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (CHK_MMC_SECTOR_MODE(sd_card)) {
- sd_card->capacity = ((u32)ptr[5] << 24) | ((u32)ptr[4] << 16) |
- ((u32)ptr[3] << 8) | ((u32)ptr[2]);
- }
-
- if (CHECK_PID(chip, 0x5209)) {
-#ifdef SUPPORT_SD_LOCK
- if (!(sd_card->sd_lock_status & SD_SDR_RST) &&
- (chip->sd_ctl & SUPPORT_MMC_DDR_MODE)) {
- card_type_mask = 0x07;
- } else {
- card_type_mask = 0x03;
- }
-#else
- if (chip->sd_ctl & SUPPORT_MMC_DDR_MODE)
- card_type_mask = 0x07;
- else
- card_type_mask = 0x03;
-#endif
- } else {
- card_type_mask = 0x03;
- }
- card_type = ptr[1] & card_type_mask;
- if (card_type) {
- u8 rsp[5];
-
- if (card_type & 0x04) {
- if (switch_ddr)
- SET_MMC_DDR52(sd_card);
- else
- SET_MMC_52M(sd_card);
- } else if (card_type & 0x02) {
- SET_MMC_52M(sd_card);
- } else {
- SET_MMC_26M(sd_card);
- }
-
- retval = sd_send_cmd_get_rsp(chip, SWITCH,
- 0x03B90100, SD_RSP_TYPE_R1b, rsp, 5);
- if ((retval != STATUS_SUCCESS) || (rsp[4] & MMC_SWITCH_ERR))
- CLR_MMC_HS(sd_card);
- }
-
- sd_choose_proper_clock(chip);
- retval = switch_clock(chip, sd_card->sd_clock);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- /* Test Bus Procedure */
- retval = mmc_test_switch_bus(chip, MMC_8BIT_BUS);
- if (retval == SWITCH_SUCCESS) {
- SET_MMC_8BIT(sd_card);
- chip->card_bus_width[chip->card2lun[SD_CARD]] = 8;
-#ifdef SUPPORT_SD_LOCK
- sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE;
-#endif
- } else if (retval == SWITCH_FAIL) {
- retval = mmc_test_switch_bus(chip, MMC_4BIT_BUS);
- if (retval == SWITCH_SUCCESS) {
- SET_MMC_4BIT(sd_card);
- chip->card_bus_width[chip->card2lun[SD_CARD]] = 4;
-#ifdef SUPPORT_SD_LOCK
- sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE;
-#endif
- } else if (retval == SWITCH_FAIL) {
- CLR_MMC_8BIT(sd_card);
- CLR_MMC_4BIT(sd_card);
- } else {
- TRACE_RET(chip, STATUS_FAIL);
- }
- } else {
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static int reset_mmc(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval, i = 0, j = 0, k = 0;
- int switch_ddr = 1;
- u8 rsp[16];
- u8 spec_ver = 0;
- u32 temp;
-
-#ifdef SUPPORT_SD_LOCK
- if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON)
- goto MMC_UNLOCK_ENTRY;
-#endif
-
-Switch_Fail:
- retval = sd_prepare_reset(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, retval);
-
- SET_MMC(sd_card);
-
-RTY_MMC_RST:
- retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- do {
- if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
- sd_set_err_code(chip, SD_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = sd_send_cmd_get_rsp(chip, SEND_OP_COND,
- (SUPPORT_VOLTAGE|0x40000000), SD_RSP_TYPE_R3, rsp, 5);
- if (retval != STATUS_SUCCESS) {
- if (sd_check_err_code(chip, SD_BUSY) || sd_check_err_code(chip, SD_TO_ERR)) {
- k++;
- if (k < 20) {
- sd_clr_err_code(chip);
- goto RTY_MMC_RST;
- } else {
- TRACE_RET(chip, STATUS_FAIL);
- }
- } else {
- j++;
- if (j < 100) {
- sd_clr_err_code(chip);
- goto RTY_MMC_RST;
- } else {
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
- }
-
- wait_timeout(20);
- i++;
- } while (!(rsp[1] & 0x80) && (i < 255));
-
- if (i == 255)
- TRACE_RET(chip, STATUS_FAIL);
-
- if ((rsp[1] & 0x60) == 0x40)
- SET_MMC_SECTOR_MODE(sd_card);
- else
- CLR_MMC_SECTOR_MODE(sd_card);
-
- retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- sd_card->sd_addr = 0x00100000;
- retval = sd_send_cmd_get_rsp(chip, SET_RELATIVE_ADDR, sd_card->sd_addr, SD_RSP_TYPE_R6, rsp, 5);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_check_csd(chip, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- spec_ver = (sd_card->raw_csd[0] & 0x3C) >> 2;
-
- retval = sd_select_card(chip, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
-#ifdef SUPPORT_SD_LOCK
-MMC_UNLOCK_ENTRY:
- retval = sd_update_lock_status(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-#endif
-
- retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- chip->card_bus_width[chip->card2lun[SD_CARD]] = 1;
-
- if (!sd_card->mmc_dont_switch_bus) {
- if (spec_ver == 4) {
- /* MMC 4.x Cards */
- retval = mmc_switch_timing_bus(chip, switch_ddr);
- if (retval != STATUS_SUCCESS) {
- retval = sd_init_power(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- sd_card->mmc_dont_switch_bus = 1;
- TRACE_GOTO(chip, Switch_Fail);
- }
- }
-
- if (CHK_MMC_SECTOR_MODE(sd_card) && (sd_card->capacity == 0))
- TRACE_RET(chip, STATUS_FAIL);
-
- if (switch_ddr && CHK_MMC_DDR52(sd_card)) {
- retval = sd_set_init_para(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = mmc_ddr_tuning(chip);
- if (retval != STATUS_SUCCESS) {
- retval = sd_init_power(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- switch_ddr = 0;
- TRACE_GOTO(chip, Switch_Fail);
- }
-
- retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000);
- if (retval == STATUS_SUCCESS) {
- retval = sd_read_lba0(chip);
- if (retval != STATUS_SUCCESS) {
- retval = sd_init_power(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- switch_ddr = 0;
- TRACE_GOTO(chip, Switch_Fail);
- }
- }
- }
- }
-
-#ifdef SUPPORT_SD_LOCK
- if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) {
- RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_H, 0xFF, 0x02);
- RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_L, 0xFF, 0x00);
- }
-#endif
-
- temp = rtsx_readl(chip, RTSX_BIPR);
- if (temp & SD_WRITE_PROTECT)
- chip->card_wp |= SD_CARD;
-
- return STATUS_SUCCESS;
-}
-
-int reset_sd_card(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
-
- sd_init_reg_addr(chip);
-
- memset(sd_card, 0, sizeof(struct sd_info));
- chip->capacity[chip->card2lun[SD_CARD]] = 0;
-
- retval = enable_card_clock(chip, SD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (chip->ignore_sd && CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) {
- if (chip->asic_code) {
- retval = sd_pull_ctl_enable(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- retval = rtsx_write_register(chip, FPGA_PULL_CTL,
- FPGA_SD_PULL_CTL_BIT | 0x20, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
- retval = card_share_mode(chip, SD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- chip->sd_io = 1;
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = sd_init_power(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (chip->sd_ctl & RESET_MMC_FIRST) {
- retval = reset_mmc(chip);
- if (retval != STATUS_SUCCESS) {
- if (sd_check_err_code(chip, SD_NO_CARD))
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = reset_sd(chip);
- if (retval != STATUS_SUCCESS) {
- if (CHECK_PID(chip, 0x5209))
- sd_change_bank_voltage(chip, SD_IO_3V3);
-
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
- } else {
- retval = reset_sd(chip);
- if (retval != STATUS_SUCCESS) {
- if (sd_check_err_code(chip, SD_NO_CARD))
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHECK_PID(chip, 0x5209)) {
- retval = sd_change_bank_voltage(chip, SD_IO_3V3);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (chip->sd_io) {
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- retval = reset_mmc(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
- }
-
- retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_L, 0xFF, 0);
- RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_H, 0xFF, 2);
-
- chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity;
-
- retval = sd_set_init_para(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_DEBUGP("sd_card->sd_type = 0x%x\n", sd_card->sd_type);
-
- return STATUS_SUCCESS;
-}
-
-static int reset_mmc_only(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
-
- sd_card->sd_type = 0;
- sd_card->seq_mode = 0;
- sd_card->sd_data_buf_ready = 0;
- sd_card->capacity = 0;
- sd_card->sd_switch_fail = 0;
-
-#ifdef SUPPORT_SD_LOCK
- sd_card->sd_lock_status = 0;
- sd_card->sd_erase_status = 0;
-#endif
-
- chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity = 0;
-
- retval = enable_card_clock(chip, SD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_init_power(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = reset_mmc(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_L, 0xFF, 0);
- RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_H, 0xFF, 2);
-
- chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity;
-
- retval = sd_set_init_para(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_DEBUGP("In reset_mmc_only, sd_card->sd_type = 0x%x\n", sd_card->sd_type);
-
- return STATUS_SUCCESS;
-}
-
-#define WAIT_DATA_READY_RTY_CNT 255
-
-static int wait_data_buf_ready(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int i, retval;
-
- for (i = 0; i < WAIT_DATA_READY_RTY_CNT; i++) {
- if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
- sd_set_err_code(chip, SD_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- sd_card->sd_data_buf_ready = 0;
-
- retval = sd_send_cmd_get_rsp(chip, SEND_STATUS,
- sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (sd_card->sd_data_buf_ready) {
- return sd_send_cmd_get_rsp(chip, SEND_STATUS,
- sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
- }
- }
-
- sd_set_err_code(chip, SD_TO_ERR);
-
- TRACE_RET(chip, STATUS_FAIL);
-}
-
-void sd_stop_seq_mode(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
-
- if (sd_card->seq_mode) {
- retval = sd_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- return;
-
- retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0,
- SD_RSP_TYPE_R1b, NULL, 0);
- if (retval != STATUS_SUCCESS)
- sd_set_err_code(chip, SD_STS_ERR);
-
- retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000);
- if (retval != STATUS_SUCCESS)
- sd_set_err_code(chip, SD_STS_ERR);
-
- sd_card->seq_mode = 0;
-
- rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH);
- }
-}
-
-static inline int sd_auto_tune_clock(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
-
- if (chip->asic_code) {
- if (sd_card->sd_clock > 30)
- sd_card->sd_clock -= 20;
- } else {
- switch (sd_card->sd_clock) {
- case CLK_200:
- sd_card->sd_clock = CLK_150;
- break;
-
- case CLK_150:
- sd_card->sd_clock = CLK_120;
- break;
-
- case CLK_120:
- sd_card->sd_clock = CLK_100;
- break;
-
- case CLK_100:
- sd_card->sd_clock = CLK_80;
- break;
-
- case CLK_80:
- sd_card->sd_clock = CLK_60;
- break;
-
- case CLK_60:
- sd_card->sd_clock = CLK_50;
- break;
-
- default:
- break;
- }
- }
-
- retval = sd_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- u32 data_addr;
- u8 cfg2;
- int retval;
-
- if (srb->sc_data_direction == DMA_FROM_DEVICE) {
- RTSX_DEBUGP("sd_rw: Read %d %s from 0x%x\n", sector_cnt,
- (sector_cnt > 1) ? "sectors" : "sector", start_sector);
- } else {
- RTSX_DEBUGP("sd_rw: Write %d %s to 0x%x\n", sector_cnt,
- (sector_cnt > 1) ? "sectors" : "sector", start_sector);
- }
-
- sd_card->cleanup_counter = 0;
-
- if (!(chip->card_ready & SD_CARD)) {
- sd_card->seq_mode = 0;
-
- retval = reset_sd_card(chip);
- if (retval == STATUS_SUCCESS) {
- chip->card_ready |= SD_CARD;
- chip->card_fail &= ~SD_CARD;
- } else {
- chip->card_ready &= ~SD_CARD;
- chip->card_fail |= SD_CARD;
- chip->capacity[chip->card2lun[SD_CARD]] = 0;
- chip->rw_need_retry = 1;
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- if (!CHK_SD_HCXC(sd_card) && !CHK_MMC_SECTOR_MODE(sd_card))
- data_addr = start_sector << 9;
- else
- data_addr = start_sector;
-
- sd_clr_err_code(chip);
-
- retval = sd_switch_clock(chip);
- if (retval != STATUS_SUCCESS) {
- sd_set_err_code(chip, SD_IO_ERR);
- TRACE_GOTO(chip, RW_FAIL);
- }
-
- if (sd_card->seq_mode && ((sd_card->pre_dir != srb->sc_data_direction)
- || ((sd_card->pre_sec_addr + sd_card->pre_sec_cnt) != start_sector))) {
- if ((sd_card->pre_sec_cnt < 0x80)
- && (sd_card->pre_dir == DMA_FROM_DEVICE)
- && !CHK_SD30_SPEED(sd_card)
- && !CHK_SD_HS(sd_card)
- && !CHK_MMC_HS(sd_card)) {
- sd_send_cmd_get_rsp(chip, SEND_STATUS,
- sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
- }
-
- retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION,
- 0, SD_RSP_TYPE_R1b, NULL, 0);
- if (retval != STATUS_SUCCESS) {
- chip->rw_need_retry = 1;
- sd_set_err_code(chip, SD_STS_ERR);
- TRACE_GOTO(chip, RW_FAIL);
- }
-
- sd_card->seq_mode = 0;
-
- retval = rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH);
- if (retval != STATUS_SUCCESS) {
- sd_set_err_code(chip, SD_IO_ERR);
- TRACE_GOTO(chip, RW_FAIL);
- }
-
- if ((sd_card->pre_sec_cnt < 0x80)
- && !CHK_SD30_SPEED(sd_card)
- && !CHK_SD_HS(sd_card)
- && !CHK_MMC_HS(sd_card)) {
- sd_send_cmd_get_rsp(chip, SEND_STATUS,
- sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0);
- }
- }
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x00);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 0x02);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, (u8)sector_cnt);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, (u8)(sector_cnt >> 8));
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
-
- if (CHK_MMC_8BIT(sd_card))
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_8);
- else if (CHK_MMC_4BIT(sd_card) || CHK_SD(sd_card))
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4);
- else
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_1);
-
- if (sd_card->seq_mode) {
- cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END |
- SD_NO_CHECK_CRC7 | SD_RSP_LEN_0;
- if (CHECK_PID(chip, 0x5209)) {
- if (!CHK_SD30_SPEED(sd_card))
- cfg2 |= SD_NO_CHECK_WAIT_CRC_TO;
- }
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2);
-
- trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, DMA_512);
-
- if (srb->sc_data_direction == DMA_FROM_DEVICE) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
- SD_TM_AUTO_READ_3 | SD_TRANSFER_START);
- } else {
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
- SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START);
- }
-
- rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END);
-
- rtsx_send_cmd_no_wait(chip);
- } else {
- if (srb->sc_data_direction == DMA_FROM_DEVICE) {
- RTSX_DEBUGP("SD/MMC CMD %d\n", READ_MULTIPLE_BLOCK);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF,
- 0x40 | READ_MULTIPLE_BLOCK);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(data_addr >> 24));
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(data_addr >> 16));
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(data_addr >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)data_addr);
-
- cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END |
- SD_CHECK_CRC7 | SD_RSP_LEN_6;
- if (CHECK_PID(chip, 0x5209)) {
- if (!CHK_SD30_SPEED(sd_card))
- cfg2 |= SD_NO_CHECK_WAIT_CRC_TO;
- }
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2);
-
- trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, DMA_512);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
- SD_TM_AUTO_READ_2 | SD_TRANSFER_START);
- rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER,
- SD_TRANSFER_END, SD_TRANSFER_END);
-
- rtsx_send_cmd_no_wait(chip);
- } else {
- retval = rtsx_send_cmd(chip, SD_CARD, 50);
- if (retval < 0) {
- rtsx_clear_sd_error(chip);
-
- chip->rw_need_retry = 1;
- sd_set_err_code(chip, SD_TO_ERR);
- TRACE_GOTO(chip, RW_FAIL);
- }
-
- retval = wait_data_buf_ready(chip);
- if (retval != STATUS_SUCCESS) {
- chip->rw_need_retry = 1;
- sd_set_err_code(chip, SD_TO_ERR);
- TRACE_GOTO(chip, RW_FAIL);
- }
-
- retval = sd_send_cmd_get_rsp(chip, WRITE_MULTIPLE_BLOCK,
- data_addr, SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS) {
- chip->rw_need_retry = 1;
- TRACE_GOTO(chip, RW_FAIL);
- }
-
- rtsx_init_cmd(chip);
-
- cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END |
- SD_NO_CHECK_CRC7 | SD_RSP_LEN_0;
- if (CHECK_PID(chip, 0x5209)) {
- if (!CHK_SD30_SPEED(sd_card))
- cfg2 |= SD_NO_CHECK_WAIT_CRC_TO;
- }
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2);
-
- trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, DMA_512);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
- SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START);
- rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER,
- SD_TRANSFER_END, SD_TRANSFER_END);
-
- rtsx_send_cmd_no_wait(chip);
- }
-
- sd_card->seq_mode = 1;
- }
-
- retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), scsi_bufflen(srb),
- scsi_sg_count(srb), srb->sc_data_direction, chip->sd_timeout);
- if (retval < 0) {
- u8 stat = 0;
- int err;
-
- sd_card->seq_mode = 0;
-
- if (retval == -ETIMEDOUT)
- err = STATUS_TIMEDOUT;
- else
- err = STATUS_FAIL;
-
- rtsx_read_register(chip, REG_SD_STAT1, &stat);
- rtsx_clear_sd_error(chip);
- if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
- chip->rw_need_retry = 0;
- RTSX_DEBUGP("No card exist, exit sd_rw\n");
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- chip->rw_need_retry = 1;
-
- retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, SD_RSP_TYPE_R1b, NULL, 0);
- if (retval != STATUS_SUCCESS) {
- sd_set_err_code(chip, SD_STS_ERR);
- TRACE_GOTO(chip, RW_FAIL);
- }
-
- if (stat & (SD_CRC7_ERR | SD_CRC16_ERR | SD_CRC_WRITE_ERR)) {
- RTSX_DEBUGP("SD CRC error, tune clock!\n");
- sd_set_err_code(chip, SD_CRC_ERR);
- TRACE_GOTO(chip, RW_FAIL);
- }
-
- if (err == STATUS_TIMEDOUT) {
- sd_set_err_code(chip, SD_TO_ERR);
- TRACE_GOTO(chip, RW_FAIL);
- }
-
- TRACE_RET(chip, err);
- }
-
- sd_card->pre_sec_addr = start_sector;
- sd_card->pre_sec_cnt = sector_cnt;
- sd_card->pre_dir = srb->sc_data_direction;
-
- return STATUS_SUCCESS;
-
-RW_FAIL:
- sd_card->seq_mode = 0;
-
- if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
- chip->rw_need_retry = 0;
- RTSX_DEBUGP("No card exist, exit sd_rw\n");
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (sd_check_err_code(chip, SD_CRC_ERR)) {
- if (CHK_MMC_4BIT(sd_card) || CHK_MMC_8BIT(sd_card)) {
- sd_card->mmc_dont_switch_bus = 1;
- reset_mmc_only(chip);
- sd_card->mmc_dont_switch_bus = 0;
- } else {
- sd_card->need_retune = 1;
- sd_auto_tune_clock(chip);
- }
- } else if (sd_check_err_code(chip, SD_TO_ERR | SD_STS_ERR)) {
- retval = reset_sd_card(chip);
- if (retval != STATUS_SUCCESS) {
- chip->card_ready &= ~SD_CARD;
- chip->card_fail |= SD_CARD;
- chip->capacity[chip->card2lun[SD_CARD]] = 0;
- }
- }
-
- TRACE_RET(chip, STATUS_FAIL);
-}
-
-#ifdef SUPPORT_CPRM
-int soft_reset_sd_card(struct rtsx_chip *chip)
-{
- return reset_sd(chip);
-}
-
-int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx,
- u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check)
-{
- int retval;
- int timeout = 100;
- u16 reg_addr;
- u8 *ptr;
- int stat_idx = 0;
- int rty_cnt = 0;
-
- RTSX_DEBUGP("EXT SD/MMC CMD %d\n", cmd_idx);
-
- if (rsp_type == SD_RSP_TYPE_R1b)
- timeout = 3000;
-
-RTY_SEND_CMD:
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(arg >> 24));
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(arg >> 16));
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(arg >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)arg);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
- 0x01, PINGPONG_BUFFER);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER,
- 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START);
- rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END);
-
- if (rsp_type == SD_RSP_TYPE_R2) {
- for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; reg_addr++)
- rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0);
-
- stat_idx = 17;
- } else if (rsp_type != SD_RSP_TYPE_R0) {
- for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++)
- rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0);
-
- stat_idx = 6;
- }
- rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0, 0);
-
- rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_STAT1, 0, 0);
-
- retval = rtsx_send_cmd(chip, SD_CARD, timeout);
- if (retval < 0) {
- if (retval == -ETIMEDOUT) {
- rtsx_clear_sd_error(chip);
-
- if (rsp_type & SD_WAIT_BUSY_END) {
- retval = sd_check_data0_status(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, retval);
- } else {
- sd_set_err_code(chip, SD_TO_ERR);
- }
- }
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (rsp_type == SD_RSP_TYPE_R0)
- return STATUS_SUCCESS;
-
- ptr = rtsx_get_cmd_data(chip) + 1;
-
- if ((ptr[0] & 0xC0) != 0) {
- sd_set_err_code(chip, SD_STS_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (!(rsp_type & SD_NO_CHECK_CRC7)) {
- if (ptr[stat_idx] & SD_CRC7_ERR) {
- if (cmd_idx == WRITE_MULTIPLE_BLOCK) {
- sd_set_err_code(chip, SD_CRC_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (rty_cnt < SD_MAX_RETRY_COUNT) {
- wait_timeout(20);
- rty_cnt++;
- goto RTY_SEND_CMD;
- } else {
- sd_set_err_code(chip, SD_CRC_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
- }
-
- if ((cmd_idx == SELECT_CARD) || (cmd_idx == APP_CMD) ||
- (cmd_idx == SEND_STATUS) || (cmd_idx == STOP_TRANSMISSION)) {
- if ((cmd_idx != STOP_TRANSMISSION) && (special_check == 0)) {
- if (ptr[1] & 0x80)
- TRACE_RET(chip, STATUS_FAIL);
- }
-#ifdef SUPPORT_SD_LOCK
- if (ptr[1] & 0x7D)
-#else
- if (ptr[1] & 0x7F)
-#endif
- {
- TRACE_RET(chip, STATUS_FAIL);
- }
- if (ptr[2] & 0xF8)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (cmd_idx == SELECT_CARD) {
- if (rsp_type == SD_RSP_TYPE_R2) {
- if ((ptr[3] & 0x1E) != 0x04)
- TRACE_RET(chip, STATUS_FAIL);
-
- } else if (rsp_type == SD_RSP_TYPE_R0) {
- if ((ptr[3] & 0x1E) != 0x03)
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
- }
-
- if (rsp && rsp_len)
- memcpy(rsp, ptr, rsp_len);
-
- return STATUS_SUCCESS;
-}
-
-int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type)
-{
- int retval, rsp_len;
- u16 reg_addr;
-
- if (rsp_type == SD_RSP_TYPE_R0)
- return STATUS_SUCCESS;
-
- rtsx_init_cmd(chip);
-
- if (rsp_type == SD_RSP_TYPE_R2) {
- for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; reg_addr++)
- rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0);
-
- rsp_len = 17;
- } else if (rsp_type != SD_RSP_TYPE_R0) {
- for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++)
- rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0);
-
- rsp_len = 6;
- }
- rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0xFF, 0);
-
- retval = rtsx_send_cmd(chip, SD_CARD, 100);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (rsp) {
- int min_len = (rsp_len < len) ? rsp_len : len;
-
- memcpy(rsp, rtsx_get_cmd_data(chip), min_len);
-
- RTSX_DEBUGP("min_len = %d\n", min_len);
- RTSX_DEBUGP("Response in cmd buf: 0x%x 0x%x 0x%x 0x%x\n",
- rsp[0], rsp[1], rsp[2], rsp[3]);
- }
-
- return STATUS_SUCCESS;
-}
-
-int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- unsigned int lun = SCSI_LUN(srb);
- int len;
- u8 buf[18] = {
- 0x00,
- 0x00,
- 0x00,
- 0x0E,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x53,
- 0x44,
- 0x20,
- 0x43,
- 0x61,
- 0x72,
- 0x64,
- 0x00,
- 0x00,
- 0x00,
- };
-
- sd_card->pre_cmd_err = 0;
-
- if (!(CHK_BIT(chip->lun_mc, lun))) {
- SET_BIT(chip->lun_mc, lun);
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) || (0x20 != srb->cmnd[4]) ||
- (0x43 != srb->cmnd[5]) || (0x61 != srb->cmnd[6]) ||
- (0x72 != srb->cmnd[7]) || (0x64 != srb->cmnd[8])) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- switch (srb->cmnd[1] & 0x0F) {
- case 0:
- sd_card->sd_pass_thru_en = 0;
- break;
-
- case 1:
- sd_card->sd_pass_thru_en = 1;
- break;
-
- default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- buf[5] = (1 == CHK_SD(sd_card)) ? 0x01 : 0x02;
- if (chip->card_wp & SD_CARD)
- buf[5] |= 0x80;
-
- buf[6] = (u8)(sd_card->sd_addr >> 16);
- buf[7] = (u8)(sd_card->sd_addr >> 24);
-
- buf[15] = chip->max_lun;
-
- len = min(18, (int)scsi_bufflen(srb));
- rtsx_stor_set_xfer_buf(buf, len, srb);
-
- return TRANSPORT_GOOD;
-}
-
-static inline int get_rsp_type(struct scsi_cmnd *srb, u8 *rsp_type, int *rsp_len)
-{
- if (!rsp_type || !rsp_len)
- return STATUS_FAIL;
-
- switch (srb->cmnd[10]) {
- case 0x03:
- *rsp_type = SD_RSP_TYPE_R0;
- *rsp_len = 0;
- break;
-
- case 0x04:
- *rsp_type = SD_RSP_TYPE_R1;
- *rsp_len = 6;
- break;
-
- case 0x05:
- *rsp_type = SD_RSP_TYPE_R1b;
- *rsp_len = 6;
- break;
-
- case 0x06:
- *rsp_type = SD_RSP_TYPE_R2;
- *rsp_len = 17;
- break;
-
- case 0x07:
- *rsp_type = SD_RSP_TYPE_R3;
- *rsp_len = 6;
- break;
-
- default:
- return STATUS_FAIL;
- }
-
- return STATUS_SUCCESS;
-}
-
-int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- unsigned int lun = SCSI_LUN(srb);
- int retval, rsp_len;
- u8 cmd_idx, rsp_type;
- u8 standby = 0, acmd = 0;
- u32 arg;
-
- if (!sd_card->sd_pass_thru_en) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- retval = sd_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- if (sd_card->pre_cmd_err) {
- sd_card->pre_cmd_err = 0;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- cmd_idx = srb->cmnd[2] & 0x3F;
- if (srb->cmnd[1] & 0x02)
- standby = 1;
-
- if (srb->cmnd[1] & 0x01)
- acmd = 1;
-
- arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) |
- ((u32)srb->cmnd[5] << 8) | srb->cmnd[6];
-
- retval = get_rsp_type(srb, &rsp_type, &rsp_len);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- sd_card->last_rsp_type = rsp_type;
-
- retval = sd_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
-#ifdef SUPPORT_SD_LOCK
- if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) {
- if (CHK_MMC_8BIT(sd_card)) {
- retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_8);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) {
- retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
-#else
- retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-#endif
-
- if (standby) {
- retval = sd_select_card(chip, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Cmd_Failed);
- }
-
- if (acmd) {
- retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
- SD_RSP_TYPE_R1, NULL, 0, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Cmd_Failed);
- }
-
- retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type,
- sd_card->rsp, rsp_len, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Cmd_Failed);
-
- if (standby) {
- retval = sd_select_card(chip, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Cmd_Failed);
- }
-
-#ifdef SUPPORT_SD_LOCK
- retval = sd_update_lock_status(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Cmd_Failed);
-#endif
-
- scsi_set_resid(srb, 0);
- return TRANSPORT_GOOD;
-
-SD_Execute_Cmd_Failed:
- sd_card->pre_cmd_err = 1;
- set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
- release_sd_card(chip);
- do_reset_sd_card(chip);
- if (!(chip->card_ready & SD_CARD))
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
-
- TRACE_RET(chip, TRANSPORT_FAILED);
-}
-
-int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- unsigned int lun = SCSI_LUN(srb);
- int retval, rsp_len, i;
- int cmd13_checkbit = 0, read_err = 0;
- u8 cmd_idx, rsp_type, bus_width;
- u8 send_cmd12 = 0, standby = 0, acmd = 0;
- u32 data_len;
-
- if (!sd_card->sd_pass_thru_en) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (sd_card->pre_cmd_err) {
- sd_card->pre_cmd_err = 0;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- retval = sd_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- cmd_idx = srb->cmnd[2] & 0x3F;
- if (srb->cmnd[1] & 0x04)
- send_cmd12 = 1;
-
- if (srb->cmnd[1] & 0x02)
- standby = 1;
-
- if (srb->cmnd[1] & 0x01)
- acmd = 1;
-
- data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] << 8) | srb->cmnd[9];
-
- retval = get_rsp_type(srb, &rsp_type, &rsp_len);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- sd_card->last_rsp_type = rsp_type;
-
- retval = sd_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
-#ifdef SUPPORT_SD_LOCK
- if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) {
- if (CHK_MMC_8BIT(sd_card))
- bus_width = SD_BUS_WIDTH_8;
- else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card))
- bus_width = SD_BUS_WIDTH_4;
- else
- bus_width = SD_BUS_WIDTH_1;
- } else {
- bus_width = SD_BUS_WIDTH_4;
- }
- RTSX_DEBUGP("bus_width = %d\n", bus_width);
-#else
- bus_width = SD_BUS_WIDTH_4;
-#endif
-
- if (data_len < 512) {
- retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len,
- SD_RSP_TYPE_R1, NULL, 0, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
- }
-
- if (standby) {
- retval = sd_select_card(chip, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
- }
-
- if (acmd) {
- retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
- SD_RSP_TYPE_R1, NULL, 0, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
- }
-
- if (data_len <= 512) {
- int min_len;
- u8 *buf;
- u16 byte_cnt, blk_cnt;
- u8 cmd[5];
-
- byte_cnt = ((u16)(srb->cmnd[8] & 0x03) << 8) | srb->cmnd[9];
- blk_cnt = 1;
-
- cmd[0] = 0x40 | cmd_idx;
- cmd[1] = srb->cmnd[3];
- cmd[2] = srb->cmnd[4];
- cmd[3] = srb->cmnd[5];
- cmd[4] = srb->cmnd[6];
-
- buf = kmalloc(data_len, GFP_KERNEL);
- if (buf == NULL)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, byte_cnt,
- blk_cnt, bus_width, buf, data_len, 2000);
- if (retval != STATUS_SUCCESS) {
- read_err = 1;
- kfree(buf);
- rtsx_clear_sd_error(chip);
- TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
- }
-
- min_len = min(data_len, scsi_bufflen(srb));
- rtsx_stor_set_xfer_buf(buf, min_len, srb);
-
- kfree(buf);
- } else if (!(data_len & 0x1FF)) {
- rtsx_init_cmd(chip);
-
- trans_dma_enable(DMA_FROM_DEVICE, chip, data_len, DMA_512);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 0x02);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x00);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H,
- 0xFF, (srb->cmnd[7] & 0xFE) >> 1);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L,
- 0xFF, (u8)((data_len & 0x0001FE00) >> 9));
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, srb->cmnd[3]);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, srb->cmnd[4]);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, srb->cmnd[5]);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, srb->cmnd[6]);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER,
- 0xFF, SD_TM_AUTO_READ_2 | SD_TRANSFER_START);
- rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END);
-
- rtsx_send_cmd_no_wait(chip);
-
- retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), scsi_bufflen(srb),
- scsi_sg_count(srb), DMA_FROM_DEVICE, 10000);
- if (retval < 0) {
- read_err = 1;
- rtsx_clear_sd_error(chip);
- TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
- }
-
- } else {
- TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
- }
-
- retval = ext_sd_get_rsp(chip, rsp_len, sd_card->rsp, rsp_type);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
-
- if (standby) {
- retval = sd_select_card(chip, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
- }
-
- if (send_cmd12) {
- retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION,
- 0, SD_RSP_TYPE_R1b, NULL, 0, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
- }
-
- if (data_len < 512) {
- retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200,
- SD_RSP_TYPE_R1, NULL, 0, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
-
- retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
-
- retval = rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
- }
-
- if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04))
- cmd13_checkbit = 1;
-
- for (i = 0; i < 3; i++) {
- retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
- SD_RSP_TYPE_R1, NULL, 0, cmd13_checkbit);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed);
-
- scsi_set_resid(srb, 0);
- return TRANSPORT_GOOD;
-
-SD_Execute_Read_Cmd_Failed:
- sd_card->pre_cmd_err = 1;
- set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
- if (read_err)
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
-
- release_sd_card(chip);
- do_reset_sd_card(chip);
- if (!(chip->card_ready & SD_CARD))
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
-
- TRACE_RET(chip, TRANSPORT_FAILED);
-}
-
-int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- unsigned int lun = SCSI_LUN(srb);
- int retval, rsp_len, i;
- int cmd13_checkbit = 0, write_err = 0;
- u8 cmd_idx, rsp_type;
- u8 send_cmd12 = 0, standby = 0, acmd = 0;
- u32 data_len, arg;
-#ifdef SUPPORT_SD_LOCK
- int lock_cmd_fail = 0;
- u8 sd_lock_state = 0;
- u8 lock_cmd_type = 0;
-#endif
-
- if (!sd_card->sd_pass_thru_en) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (sd_card->pre_cmd_err) {
- sd_card->pre_cmd_err = 0;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- retval = sd_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- cmd_idx = srb->cmnd[2] & 0x3F;
- if (srb->cmnd[1] & 0x04)
- send_cmd12 = 1;
-
- if (srb->cmnd[1] & 0x02)
- standby = 1;
-
- if (srb->cmnd[1] & 0x01)
- acmd = 1;
-
- data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] << 8) | srb->cmnd[9];
- arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) |
- ((u32)srb->cmnd[5] << 8) | srb->cmnd[6];
-
-#ifdef SUPPORT_SD_LOCK
- if (cmd_idx == LOCK_UNLOCK) {
- sd_lock_state = sd_card->sd_lock_status;
- sd_lock_state &= SD_LOCKED;
- }
-#endif
-
- retval = get_rsp_type(srb, &rsp_type, &rsp_len);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- sd_card->last_rsp_type = rsp_type;
-
- retval = sd_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
-#ifdef SUPPORT_SD_LOCK
- if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) {
- if (CHK_MMC_8BIT(sd_card)) {
- retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_8);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-
- } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) {
- retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- }
-#else
- retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, TRANSPORT_FAILED);
-#endif
-
- if (data_len < 512) {
- retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len,
- SD_RSP_TYPE_R1, NULL, 0, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
- }
-
- if (standby) {
- retval = sd_select_card(chip, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
- }
-
- if (acmd) {
- retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
- SD_RSP_TYPE_R1, NULL, 0, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
- }
-
- retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type,
- sd_card->rsp, rsp_len, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
-
- if (data_len <= 512) {
- u16 i;
- u8 *buf;
-
- buf = kmalloc(data_len, GFP_KERNEL);
- if (buf == NULL)
- TRACE_RET(chip, TRANSPORT_ERROR);
-
- rtsx_stor_get_xfer_buf(buf, data_len, srb);
-
-#ifdef SUPPORT_SD_LOCK
- if (cmd_idx == LOCK_UNLOCK)
- lock_cmd_type = buf[0] & 0x0F;
-#endif
-
- if (data_len > 256) {
- rtsx_init_cmd(chip);
- for (i = 0; i < 256; i++) {
- rtsx_add_cmd(chip, WRITE_REG_CMD,
- PPBUF_BASE2 + i, 0xFF, buf[i]);
- }
- retval = rtsx_send_cmd(chip, 0, 250);
- if (retval != STATUS_SUCCESS) {
- kfree(buf);
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
- }
-
- rtsx_init_cmd(chip);
- for (i = 256; i < data_len; i++) {
- rtsx_add_cmd(chip, WRITE_REG_CMD,
- PPBUF_BASE2 + i, 0xFF, buf[i]);
- }
- retval = rtsx_send_cmd(chip, 0, 250);
- if (retval != STATUS_SUCCESS) {
- kfree(buf);
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
- }
- } else {
- rtsx_init_cmd(chip);
- for (i = 0; i < data_len; i++) {
- rtsx_add_cmd(chip, WRITE_REG_CMD,
- PPBUF_BASE2 + i, 0xFF, buf[i]);
- }
- retval = rtsx_send_cmd(chip, 0, 250);
- if (retval != STATUS_SUCCESS) {
- kfree(buf);
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
- }
- }
-
- kfree(buf);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, srb->cmnd[8] & 0x03);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, srb->cmnd[9]);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0x00);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 0x01);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF,
- SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START);
- rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END);
-
- retval = rtsx_send_cmd(chip, SD_CARD, 250);
- } else if (!(data_len & 0x1FF)) {
- rtsx_init_cmd(chip);
-
- trans_dma_enable(DMA_TO_DEVICE, chip, data_len, DMA_512);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 0x02);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x00);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H,
- 0xFF, (srb->cmnd[7] & 0xFE) >> 1);
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L,
- 0xFF, (u8)((data_len & 0x0001FE00) >> 9));
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START);
- rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END);
-
- rtsx_send_cmd_no_wait(chip);
-
- retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), scsi_bufflen(srb),
- scsi_sg_count(srb), DMA_TO_DEVICE, 10000);
-
- } else {
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
- }
-
- if (retval < 0) {
- write_err = 1;
- rtsx_clear_sd_error(chip);
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
- }
-
-#ifdef SUPPORT_SD_LOCK
- if (cmd_idx == LOCK_UNLOCK) {
- if (lock_cmd_type == SD_ERASE) {
- sd_card->sd_erase_status = SD_UNDER_ERASING;
- scsi_set_resid(srb, 0);
- return TRANSPORT_GOOD;
- }
-
- rtsx_init_cmd(chip);
- if (CHECK_PID(chip, 0x5209))
- rtsx_add_cmd(chip, CHECK_REG_CMD, SD_BUS_STAT, SD_DAT0_STATUS, SD_DAT0_STATUS);
- else
- rtsx_add_cmd(chip, CHECK_REG_CMD, 0xFD30, 0x02, 0x02);
-
- rtsx_send_cmd(chip, SD_CARD, 250);
-
- retval = sd_update_lock_status(chip);
- if (retval != STATUS_SUCCESS) {
- RTSX_DEBUGP("Lock command fail!\n");
- lock_cmd_fail = 1;
- }
- }
-#endif /* SUPPORT_SD_LOCK */
-
- if (standby) {
- retval = sd_select_card(chip, 1);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
- }
-
- if (send_cmd12) {
- retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION,
- 0, SD_RSP_TYPE_R1b, NULL, 0, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
- }
-
- if (data_len < 512) {
- retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200,
- SD_RSP_TYPE_R1, NULL, 0, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
-
- retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
-
- rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00);
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
- }
-
- if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04))
- cmd13_checkbit = 1;
-
- for (i = 0; i < 3; i++) {
- retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
- SD_RSP_TYPE_R1, NULL, 0, cmd13_checkbit);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (retval != STATUS_SUCCESS)
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
-
-#ifdef SUPPORT_SD_LOCK
- if (cmd_idx == LOCK_UNLOCK) {
- if (!lock_cmd_fail) {
- RTSX_DEBUGP("lock_cmd_type = 0x%x\n", lock_cmd_type);
- if (lock_cmd_type & SD_CLR_PWD)
- sd_card->sd_lock_status &= ~SD_PWD_EXIST;
-
- if (lock_cmd_type & SD_SET_PWD)
- sd_card->sd_lock_status |= SD_PWD_EXIST;
- }
-
- RTSX_DEBUGP("sd_lock_state = 0x%x, sd_card->sd_lock_status = 0x%x\n",
- sd_lock_state, sd_card->sd_lock_status);
- if (sd_lock_state ^ (sd_card->sd_lock_status & SD_LOCKED)) {
- sd_card->sd_lock_notify = 1;
- if (sd_lock_state) {
- if (sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) {
- sd_card->sd_lock_status |= (SD_UNLOCK_POW_ON | SD_SDR_RST);
- if (CHK_SD(sd_card)) {
- retval = reset_sd(chip);
- if (retval != STATUS_SUCCESS) {
- sd_card->sd_lock_status &= ~(SD_UNLOCK_POW_ON | SD_SDR_RST);
- TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed);
- }
- }
-
- sd_card->sd_lock_status &= ~(SD_UNLOCK_POW_ON | SD_SDR_RST);
- }
- }
- }
- }
-
- if (lock_cmd_fail) {
- scsi_set_resid(srb, 0);
- set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-#endif /* SUPPORT_SD_LOCK */
-
- scsi_set_resid(srb, 0);
- return TRANSPORT_GOOD;
-
-SD_Execute_Write_Cmd_Failed:
- sd_card->pre_cmd_err = 1;
- set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE);
- if (write_err)
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
-
- release_sd_card(chip);
- do_reset_sd_card(chip);
- if (!(chip->card_ready & SD_CARD))
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
-
- TRACE_RET(chip, TRANSPORT_FAILED);
-}
-
-int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- unsigned int lun = SCSI_LUN(srb);
- int count;
- u16 data_len;
-
- if (!sd_card->sd_pass_thru_en) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (sd_card->pre_cmd_err) {
- sd_card->pre_cmd_err = 0;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- data_len = ((u16)srb->cmnd[7] << 8) | srb->cmnd[8];
-
- if (sd_card->last_rsp_type == SD_RSP_TYPE_R0) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- } else if (sd_card->last_rsp_type == SD_RSP_TYPE_R2) {
- count = (data_len < 17) ? data_len : 17;
- } else {
- count = (data_len < 6) ? data_len : 6;
- }
- rtsx_stor_set_xfer_buf(sd_card->rsp, count, srb);
-
- RTSX_DEBUGP("Response length: %d\n", data_len);
- RTSX_DEBUGP("Response: 0x%x 0x%x 0x%x 0x%x\n",
- sd_card->rsp[0], sd_card->rsp[1], sd_card->rsp[2], sd_card->rsp[3]);
-
- scsi_set_resid(srb, 0);
- return TRANSPORT_GOOD;
-}
-
-int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- unsigned int lun = SCSI_LUN(srb);
- int retval;
-
- if (!sd_card->sd_pass_thru_en) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if (sd_card->pre_cmd_err) {
- sd_card->pre_cmd_err = 0;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) || (0x20 != srb->cmnd[4]) ||
- (0x43 != srb->cmnd[5]) || (0x61 != srb->cmnd[6]) ||
- (0x72 != srb->cmnd[7]) || (0x64 != srb->cmnd[8])) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- switch (srb->cmnd[1] & 0x0F) {
- case 0:
-#ifdef SUPPORT_SD_LOCK
- if (0x64 == srb->cmnd[9])
- sd_card->sd_lock_status |= SD_SDR_RST;
-#endif
- retval = reset_sd_card(chip);
- if (retval != STATUS_SUCCESS) {
-#ifdef SUPPORT_SD_LOCK
- sd_card->sd_lock_status &= ~SD_SDR_RST;
-#endif
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- sd_card->pre_cmd_err = 1;
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-#ifdef SUPPORT_SD_LOCK
- sd_card->sd_lock_status &= ~SD_SDR_RST;
-#endif
- break;
-
- case 1:
- retval = soft_reset_sd_card(chip);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- sd_card->pre_cmd_err = 1;
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
- break;
-
- default:
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
- TRACE_RET(chip, TRANSPORT_FAILED);
- }
-
- scsi_set_resid(srb, 0);
- return TRANSPORT_GOOD;
-}
-#endif
-
-void sd_cleanup_work(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
-
- if (sd_card->seq_mode) {
- RTSX_DEBUGP("SD: stop transmission\n");
- sd_stop_seq_mode(chip);
- sd_card->cleanup_counter = 0;
- }
-}
-
-int sd_power_off_card3v3(struct rtsx_chip *chip)
-{
- int retval;
-
- retval = disable_card_clock(chip, SD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, CARD_OE, SD_OUTPUT_EN, 0);
-
- if (!chip->ft2_fast_mode) {
- retval = card_power_off(chip, SD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- wait_timeout(50);
- }
-
- if (chip->asic_code) {
- retval = sd_pull_ctl_disable(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- RTSX_WRITE_REG(chip, FPGA_PULL_CTL,
- FPGA_SD_PULL_CTL_BIT | 0x20, FPGA_SD_PULL_CTL_BIT);
- }
-
- return STATUS_SUCCESS;
-}
-
-int release_sd_card(struct rtsx_chip *chip)
-{
- struct sd_info *sd_card = &(chip->sd_card);
- int retval;
-
- RTSX_DEBUGP("release_sd_card\n");
-
- chip->card_ready &= ~SD_CARD;
- chip->card_fail &= ~SD_CARD;
- chip->card_wp &= ~SD_CARD;
-
- chip->sd_io = 0;
- chip->sd_int = 0;
-
-#ifdef SUPPORT_SD_LOCK
- sd_card->sd_lock_status = 0;
- sd_card->sd_erase_status = 0;
-#endif
-
- memset(sd_card->raw_csd, 0, 16);
- memset(sd_card->raw_scr, 0, 8);
-
- retval = sd_power_off_card3v3(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHECK_PID(chip, 0x5209)) {
- retval = sd_change_bank_voltage(chip, SD_IO_3V3);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (CHK_SD30_SPEED(sd_card))
- RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07, chip->sd30_drive_sel_3v3);
-
- RTSX_WRITE_REG(chip, OCPPARA2, SD_OCP_THD_MASK, chip->sd_400mA_ocp_thd);
- }
-
- return STATUS_SUCCESS;
-}
diff --git a/drivers/staging/rts_pstor/sd.h b/drivers/staging/rts_pstor/sd.h
deleted file mode 100644
index 1df1aa75e93..00000000000
--- a/drivers/staging/rts_pstor/sd.h
+++ /dev/null
@@ -1,300 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- * Header file
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#ifndef __REALTEK_RTSX_SD_H
-#define __REALTEK_RTSX_SD_H
-
-#include "rtsx_chip.h"
-
-#define SUPPORT_VOLTAGE 0x003C0000
-
-/* Error Code */
-#define SD_NO_ERROR 0x0
-#define SD_CRC_ERR 0x80
-#define SD_TO_ERR 0x40
-#define SD_NO_CARD 0x20
-#define SD_BUSY 0x10
-#define SD_STS_ERR 0x08
-#define SD_RSP_TIMEOUT 0x04
-#define SD_IO_ERR 0x02
-
-/* Return code for MMC switch bus */
-#define SWITCH_SUCCESS 0
-#define SWITCH_ERR 1
-#define SWITCH_FAIL 2
-
-/* MMC/SD Command Index */
-/* Basic command (class 0) */
-#define GO_IDLE_STATE 0
-#define SEND_OP_COND 1
-#define ALL_SEND_CID 2
-#define SET_RELATIVE_ADDR 3
-#define SEND_RELATIVE_ADDR 3
-#define SET_DSR 4
-#define IO_SEND_OP_COND 5
-#define SWITCH 6
-#define SELECT_CARD 7
-#define DESELECT_CARD 7
-/* CMD8 is "SEND_EXT_CSD" for MMC4.x Spec
- * while is "SEND_IF_COND" for SD 2.0
- */
-#define SEND_EXT_CSD 8
-#define SEND_IF_COND 8
-
-#define SEND_CSD 9
-#define SEND_CID 10
-#define VOLTAGE_SWITCH 11
-#define READ_DAT_UTIL_STOP 11
-#define STOP_TRANSMISSION 12
-#define SEND_STATUS 13
-#define GO_INACTIVE_STATE 15
-
-#define SET_BLOCKLEN 16
-#define READ_SINGLE_BLOCK 17
-#define READ_MULTIPLE_BLOCK 18
-#define SEND_TUNING_PATTERN 19
-
-#define BUSTEST_R 14
-#define BUSTEST_W 19
-
-#define WRITE_BLOCK 24
-#define WRITE_MULTIPLE_BLOCK 25
-#define PROGRAM_CSD 27
-
-#define ERASE_WR_BLK_START 32
-#define ERASE_WR_BLK_END 33
-#define ERASE_CMD 38
-
-#define LOCK_UNLOCK 42
-#define IO_RW_DIRECT 52
-
-#define APP_CMD 55
-#define GEN_CMD 56
-
-#define SET_BUS_WIDTH 6
-#define SD_STATUS 13
-#define SEND_NUM_WR_BLOCKS 22
-#define SET_WR_BLK_ERASE_COUNT 23
-#define SD_APP_OP_COND 41
-#define SET_CLR_CARD_DETECT 42
-#define SEND_SCR 51
-
-#define SD_READ_COMPLETE 0x00
-#define SD_READ_TO 0x01
-#define SD_READ_ADVENCE 0x02
-
-#define SD_CHECK_MODE 0x00
-#define SD_SWITCH_MODE 0x80
-#define SD_FUNC_GROUP_1 0x01
-#define SD_FUNC_GROUP_2 0x02
-#define SD_FUNC_GROUP_3 0x03
-#define SD_FUNC_GROUP_4 0x04
-#define SD_CHECK_SPEC_V1_1 0xFF
-
-#define NO_ARGUMENT 0x00
-#define CHECK_PATTERN 0x000000AA
-#define VOLTAGE_SUPPLY_RANGE 0x00000100
-#define SUPPORT_HIGH_AND_EXTENDED_CAPACITY 0x40000000
-#define SUPPORT_MAX_POWER_PERMANCE 0x10000000
-#define SUPPORT_1V8 0x01000000
-
-#define SWTICH_NO_ERR 0x00
-#define CARD_NOT_EXIST 0x01
-#define SPEC_NOT_SUPPORT 0x02
-#define CHECK_MODE_ERR 0x03
-#define CHECK_NOT_READY 0x04
-#define SWITCH_CRC_ERR 0x05
-#define SWITCH_MODE_ERR 0x06
-#define SWITCH_PASS 0x07
-
-#ifdef SUPPORT_SD_LOCK
-#define SD_ERASE 0x08
-#define SD_LOCK 0x04
-#define SD_UNLOCK 0x00
-#define SD_CLR_PWD 0x02
-#define SD_SET_PWD 0x01
-
-#define SD_PWD_LEN 0x10
-
-#define SD_LOCKED 0x80
-#define SD_LOCK_1BIT_MODE 0x40
-#define SD_PWD_EXIST 0x20
-#define SD_UNLOCK_POW_ON 0x01
-#define SD_SDR_RST 0x02
-
-#define SD_NOT_ERASE 0x00
-#define SD_UNDER_ERASING 0x01
-#define SD_COMPLETE_ERASE 0x02
-
-#define SD_RW_FORBIDDEN 0x0F
-
-#endif
-
-#define HS_SUPPORT 0x01
-#define SDR50_SUPPORT 0x02
-#define SDR104_SUPPORT 0x03
-#define DDR50_SUPPORT 0x04
-
-#define HS_SUPPORT_MASK 0x02
-#define SDR50_SUPPORT_MASK 0x04
-#define SDR104_SUPPORT_MASK 0x08
-#define DDR50_SUPPORT_MASK 0x10
-
-#define HS_QUERY_SWITCH_OK 0x01
-#define SDR50_QUERY_SWITCH_OK 0x02
-#define SDR104_QUERY_SWITCH_OK 0x03
-#define DDR50_QUERY_SWITCH_OK 0x04
-
-#define HS_SWITCH_BUSY 0x02
-#define SDR50_SWITCH_BUSY 0x04
-#define SDR104_SWITCH_BUSY 0x08
-#define DDR50_SWITCH_BUSY 0x10
-
-#define FUNCTION_GROUP1_SUPPORT_OFFSET 0x0D
-#define FUNCTION_GROUP1_QUERY_SWITCH_OFFSET 0x10
-#define FUNCTION_GROUP1_CHECK_BUSY_OFFSET 0x1D
-
-#define DRIVING_TYPE_A 0x01
-#define DRIVING_TYPE_B 0x00
-#define DRIVING_TYPE_C 0x02
-#define DRIVING_TYPE_D 0x03
-
-#define DRIVING_TYPE_A_MASK 0x02
-#define DRIVING_TYPE_B_MASK 0x01
-#define DRIVING_TYPE_C_MASK 0x04
-#define DRIVING_TYPE_D_MASK 0x08
-
-#define TYPE_A_QUERY_SWITCH_OK 0x01
-#define TYPE_B_QUERY_SWITCH_OK 0x00
-#define TYPE_C_QUERY_SWITCH_OK 0x02
-#define TYPE_D_QUERY_SWITCH_OK 0x03
-
-#define TYPE_A_SWITCH_BUSY 0x02
-#define TYPE_B_SWITCH_BUSY 0x01
-#define TYPE_C_SWITCH_BUSY 0x04
-#define TYPE_D_SWITCH_BUSY 0x08
-
-#define FUNCTION_GROUP3_SUPPORT_OFFSET 0x09
-#define FUNCTION_GROUP3_QUERY_SWITCH_OFFSET 0x0F
-#define FUNCTION_GROUP3_CHECK_BUSY_OFFSET 0x19
-
-#define CURRENT_LIMIT_200 0x00
-#define CURRENT_LIMIT_400 0x01
-#define CURRENT_LIMIT_600 0x02
-#define CURRENT_LIMIT_800 0x03
-
-#define CURRENT_LIMIT_200_MASK 0x01
-#define CURRENT_LIMIT_400_MASK 0x02
-#define CURRENT_LIMIT_600_MASK 0x04
-#define CURRENT_LIMIT_800_MASK 0x08
-
-#define CURRENT_LIMIT_200_QUERY_SWITCH_OK 0x00
-#define CURRENT_LIMIT_400_QUERY_SWITCH_OK 0x01
-#define CURRENT_LIMIT_600_QUERY_SWITCH_OK 0x02
-#define CURRENT_LIMIT_800_QUERY_SWITCH_OK 0x03
-
-#define CURRENT_LIMIT_200_SWITCH_BUSY 0x01
-#define CURRENT_LIMIT_400_SWITCH_BUSY 0x02
-#define CURRENT_LIMIT_600_SWITCH_BUSY 0x04
-#define CURRENT_LIMIT_800_SWITCH_BUSY 0x08
-
-#define FUNCTION_GROUP4_SUPPORT_OFFSET 0x07
-#define FUNCTION_GROUP4_QUERY_SWITCH_OFFSET 0x0F
-#define FUNCTION_GROUP4_CHECK_BUSY_OFFSET 0x17
-
-#define DATA_STRUCTURE_VER_OFFSET 0x11
-
-#define MAX_PHASE 31
-
-#define MMC_8BIT_BUS 0x0010
-#define MMC_4BIT_BUS 0x0020
-
-#define MMC_SWITCH_ERR 0x80
-
-#define SD_IO_3V3 0
-#define SD_IO_1V8 1
-
-#define TUNE_TX 0x00
-#define TUNE_RX 0x01
-
-#define CHANGE_TX 0x00
-#define CHANGE_RX 0x01
-
-#define DCM_HIGH_FREQUENCY_MODE 0x00
-#define DCM_LOW_FREQUENCY_MODE 0x01
-
-#define DCM_HIGH_FREQUENCY_MODE_SET 0x0C
-#define DCM_Low_FREQUENCY_MODE_SET 0x00
-
-#define MULTIPLY_BY_1 0x00
-#define MULTIPLY_BY_2 0x01
-#define MULTIPLY_BY_3 0x02
-#define MULTIPLY_BY_4 0x03
-#define MULTIPLY_BY_5 0x04
-#define MULTIPLY_BY_6 0x05
-#define MULTIPLY_BY_7 0x06
-#define MULTIPLY_BY_8 0x07
-#define MULTIPLY_BY_9 0x08
-#define MULTIPLY_BY_10 0x09
-
-#define DIVIDE_BY_2 0x01
-#define DIVIDE_BY_3 0x02
-#define DIVIDE_BY_4 0x03
-#define DIVIDE_BY_5 0x04
-#define DIVIDE_BY_6 0x05
-#define DIVIDE_BY_7 0x06
-#define DIVIDE_BY_8 0x07
-#define DIVIDE_BY_9 0x08
-#define DIVIDE_BY_10 0x09
-
-struct timing_phase_path {
- int start;
- int end;
- int mid;
- int len;
-};
-
-int sd_select_card(struct rtsx_chip *chip, int select);
-int sd_pull_ctl_enable(struct rtsx_chip *chip);
-int reset_sd_card(struct rtsx_chip *chip);
-int sd_switch_clock(struct rtsx_chip *chip);
-void sd_stop_seq_mode(struct rtsx_chip *chip);
-int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt);
-void sd_cleanup_work(struct rtsx_chip *chip);
-int sd_power_off_card3v3(struct rtsx_chip *chip);
-int release_sd_card(struct rtsx_chip *chip);
-#ifdef SUPPORT_CPRM
-int soft_reset_sd_card(struct rtsx_chip *chip);
-int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx,
- u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check);
-int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type);
-
-int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-#endif
-
-#endif /* __REALTEK_RTSX_SD_H */
diff --git a/drivers/staging/rts_pstor/spi.c b/drivers/staging/rts_pstor/spi.c
deleted file mode 100644
index 6b36cc532a8..00000000000
--- a/drivers/staging/rts_pstor/spi.c
+++ /dev/null
@@ -1,812 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#include <linux/blkdev.h>
-#include <linux/kthread.h>
-#include <linux/sched.h>
-
-#include "rtsx.h"
-#include "rtsx_transport.h"
-#include "rtsx_scsi.h"
-#include "rtsx_card.h"
-#include "spi.h"
-
-static inline void spi_set_err_code(struct rtsx_chip *chip, u8 err_code)
-{
- struct spi_info *spi = &(chip->spi);
-
- spi->err_code = err_code;
-}
-
-static int spi_init(struct rtsx_chip *chip)
-{
- RTSX_WRITE_REG(chip, SPI_CONTROL, 0xFF,
- CS_POLARITY_LOW | DTO_MSB_FIRST | SPI_MASTER | SPI_MODE0 | SPI_AUTO);
- RTSX_WRITE_REG(chip, SPI_TCTL, EDO_TIMING_MASK, SAMPLE_DELAY_HALF);
-
- return STATUS_SUCCESS;
-}
-
-static int spi_set_init_para(struct rtsx_chip *chip)
-{
- struct spi_info *spi = &(chip->spi);
- int retval;
-
- RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, (u8)(spi->clk_div >> 8));
- RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, (u8)(spi->clk_div));
-
- retval = switch_clock(chip, spi->spi_clock);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = select_card(chip, SPI_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN);
- RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN);
-
- wait_timeout(10);
-
- retval = spi_init(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int sf_polling_status(struct rtsx_chip *chip, int msec)
-{
- int retval;
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, SPI_RDSR);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_POLLING_MODE0);
- rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
-
- retval = rtsx_send_cmd(chip, 0, msec);
- if (retval < 0) {
- rtsx_clear_spi_error(chip);
- spi_set_err_code(chip, SPI_BUSY_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int sf_enable_write(struct rtsx_chip *chip, u8 ins)
-{
- struct spi_info *spi = &(chip->spi);
- int retval;
-
- if (!spi->write_en)
- return STATUS_SUCCESS;
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0);
- rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
-
- retval = rtsx_send_cmd(chip, 0, 100);
- if (retval < 0) {
- rtsx_clear_spi_error(chip);
- spi_set_err_code(chip, SPI_HW_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int sf_disable_write(struct rtsx_chip *chip, u8 ins)
-{
- struct spi_info *spi = &(chip->spi);
- int retval;
-
- if (!spi->write_en)
- return STATUS_SUCCESS;
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0);
- rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
-
- retval = rtsx_send_cmd(chip, 0, 100);
- if (retval < 0) {
- rtsx_clear_spi_error(chip);
- spi_set_err_code(chip, SPI_HW_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static void sf_program(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr, u16 len)
-{
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)len);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(len >> 8));
- if (addr_mode) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16));
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CADO_MODE0);
- } else {
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CDO_MODE0);
- }
- rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
-}
-
-static int sf_erase(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr)
-{
- int retval;
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
- if (addr_mode) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16));
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0);
- } else {
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0);
- }
- rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
-
- retval = rtsx_send_cmd(chip, 0, 100);
- if (retval < 0) {
- rtsx_clear_spi_error(chip);
- spi_set_err_code(chip, SPI_HW_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int spi_init_eeprom(struct rtsx_chip *chip)
-{
- int retval;
- int clk;
-
- if (chip->asic_code)
- clk = 30;
- else
- clk = CLK_30;
-
- RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, 0x00);
- RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, 0x27);
-
- retval = switch_clock(chip, clk);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = select_card(chip, SPI_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN);
- RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN);
-
- wait_timeout(10);
-
- RTSX_WRITE_REG(chip, SPI_CONTROL, 0xFF, CS_POLARITY_HIGH | SPI_EEPROM_AUTO);
- RTSX_WRITE_REG(chip, SPI_TCTL, EDO_TIMING_MASK, SAMPLE_DELAY_HALF);
-
- return STATUS_SUCCESS;
-}
-
-static int spi_eeprom_program_enable(struct rtsx_chip *chip)
-{
- int retval;
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x86);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x13);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0);
- rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
-
- retval = rtsx_send_cmd(chip, 0, 100);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-int spi_erase_eeprom_chip(struct rtsx_chip *chip)
-{
- int retval;
-
- retval = spi_init_eeprom(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = spi_eeprom_program_enable(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x12);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x84);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0);
- rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
-
- retval = rtsx_send_cmd(chip, 0, 100);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
-
- return STATUS_SUCCESS;
-}
-
-int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr)
-{
- int retval;
-
- retval = spi_init_eeprom(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = spi_eeprom_program_enable(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x07);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0);
- rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
-
- retval = rtsx_send_cmd(chip, 0, 100);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
-
- return STATUS_SUCCESS;
-}
-
-
-int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val)
-{
- int retval;
- u8 data;
-
- retval = spi_init_eeprom(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x06);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CADI_MODE0);
- rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
-
- retval = rtsx_send_cmd(chip, 0, 100);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- wait_timeout(5);
- RTSX_READ_REG(chip, SPI_DATA, &data);
-
- if (val)
- *val = data;
-
- RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
-
- return STATUS_SUCCESS;
-}
-
-int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val)
-{
- int retval;
-
- retval = spi_init_eeprom(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = spi_eeprom_program_enable(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x05);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, val);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x4E);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0);
- rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
-
- retval = rtsx_send_cmd(chip, 0, 100);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
-
- return STATUS_SUCCESS;
-}
-
-
-int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct spi_info *spi = &(chip->spi);
-
- RTSX_DEBUGP("spi_get_status: err_code = 0x%x\n", spi->err_code);
- rtsx_stor_set_xfer_buf(&(spi->err_code), min((int)scsi_bufflen(srb), 1), srb);
- scsi_set_resid(srb, scsi_bufflen(srb) - 1);
-
- return STATUS_SUCCESS;
-}
-
-int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- struct spi_info *spi = &(chip->spi);
-
- spi_set_err_code(chip, SPI_NO_ERR);
-
- if (chip->asic_code)
- spi->spi_clock = ((u16)(srb->cmnd[8]) << 8) | srb->cmnd[9];
- else
- spi->spi_clock = srb->cmnd[3];
-
- spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
- spi->write_en = srb->cmnd[6];
-
- RTSX_DEBUGP("spi_set_parameter: spi_clock = %d, clk_div = %d, write_en = %d\n",
- spi->spi_clock, spi->clk_div, spi->write_en);
-
- return STATUS_SUCCESS;
-}
-
-int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int retval;
- u16 len;
- u8 *buf;
-
- spi_set_err_code(chip, SPI_NO_ERR);
-
- len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
- if (len > 512) {
- spi_set_err_code(chip, SPI_INVALID_COMMAND);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = spi_set_init_para(chip);
- if (retval != STATUS_SUCCESS) {
- spi_set_err_code(chip, SPI_HW_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, srb->cmnd[3]);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, srb->cmnd[4]);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, srb->cmnd[5]);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, srb->cmnd[6]);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, srb->cmnd[7]);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, srb->cmnd[8]);
-
- if (len == 0) {
- if (srb->cmnd[9]) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0,
- 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0);
- } else {
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0,
- 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0);
- }
- } else {
- if (srb->cmnd[9]) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0,
- 0xFF, SPI_TRANSFER0_START | SPI_CADI_MODE0);
- } else {
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0,
- 0xFF, SPI_TRANSFER0_START | SPI_CDI_MODE0);
- }
- }
-
- rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
-
- retval = rtsx_send_cmd(chip, 0, 100);
- if (retval < 0) {
- rtsx_clear_spi_error(chip);
- spi_set_err_code(chip, SPI_HW_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (len) {
- buf = kmalloc(len, GFP_KERNEL);
- if (!buf)
- TRACE_RET(chip, STATUS_ERROR);
-
- retval = rtsx_read_ppbuf(chip, buf, len);
- if (retval != STATUS_SUCCESS) {
- spi_set_err_code(chip, SPI_READ_ERR);
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb);
- scsi_set_resid(srb, 0);
-
- kfree(buf);
- }
-
- return STATUS_SUCCESS;
-}
-
-int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int retval;
- unsigned int index = 0, offset = 0;
- u8 ins, slow_read;
- u32 addr;
- u16 len;
- u8 *buf;
-
- spi_set_err_code(chip, SPI_NO_ERR);
-
- ins = srb->cmnd[3];
- addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6];
- len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
- slow_read = srb->cmnd[9];
-
- retval = spi_set_init_para(chip);
- if (retval != STATUS_SUCCESS) {
- spi_set_err_code(chip, SPI_HW_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL);
- if (buf == NULL)
- TRACE_RET(chip, STATUS_ERROR);
-
- while (len) {
- u16 pagelen = SF_PAGE_LEN - (u8)addr;
-
- if (pagelen > len)
- pagelen = len;
-
- rtsx_init_cmd(chip);
-
- trans_dma_enable(DMA_FROM_DEVICE, chip, 256, DMA_256);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
-
- if (slow_read) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16));
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
- } else {
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR3, 0xFF, (u8)(addr >> 16));
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_32);
- }
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(pagelen >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)pagelen);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CADI_MODE0);
- rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
-
- rtsx_send_cmd_no_wait(chip);
-
- retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, DMA_FROM_DEVICE, 10000);
- if (retval < 0) {
- kfree(buf);
- rtsx_clear_spi_error(chip);
- spi_set_err_code(chip, SPI_HW_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset, TO_XFER_BUF);
-
- addr += pagelen;
- len -= pagelen;
- }
-
- scsi_set_resid(srb, 0);
- kfree(buf);
-
- return STATUS_SUCCESS;
-}
-
-int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int retval;
- u8 ins, program_mode;
- u32 addr;
- u16 len;
- u8 *buf;
- unsigned int index = 0, offset = 0;
-
- spi_set_err_code(chip, SPI_NO_ERR);
-
- ins = srb->cmnd[3];
- addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6];
- len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
- program_mode = srb->cmnd[9];
-
- retval = spi_set_init_para(chip);
- if (retval != STATUS_SUCCESS) {
- spi_set_err_code(chip, SPI_HW_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (program_mode == BYTE_PROGRAM) {
- buf = kmalloc(4, GFP_KERNEL);
- if (!buf)
- TRACE_RET(chip, STATUS_ERROR);
-
- while (len) {
- retval = sf_enable_write(chip, SPI_WREN);
- if (retval != STATUS_SUCCESS) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, FROM_XFER_BUF);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
- rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, buf[0]);
- sf_program(chip, ins, 1, addr, 1);
-
- retval = rtsx_send_cmd(chip, 0, 100);
- if (retval < 0) {
- kfree(buf);
- rtsx_clear_spi_error(chip);
- spi_set_err_code(chip, SPI_HW_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = sf_polling_status(chip, 100);
- if (retval != STATUS_SUCCESS) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- addr++;
- len--;
- }
-
- kfree(buf);
-
- } else if (program_mode == AAI_PROGRAM) {
- int first_byte = 1;
-
- retval = sf_enable_write(chip, SPI_WREN);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- buf = kmalloc(4, GFP_KERNEL);
- if (!buf)
- TRACE_RET(chip, STATUS_ERROR);
-
- while (len) {
- rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, FROM_XFER_BUF);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
- rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, buf[0]);
- if (first_byte) {
- sf_program(chip, ins, 1, addr, 1);
- first_byte = 0;
- } else {
- sf_program(chip, ins, 0, 0, 1);
- }
-
- retval = rtsx_send_cmd(chip, 0, 100);
- if (retval < 0) {
- kfree(buf);
- rtsx_clear_spi_error(chip);
- spi_set_err_code(chip, SPI_HW_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = sf_polling_status(chip, 100);
- if (retval != STATUS_SUCCESS) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- len--;
- }
-
- kfree(buf);
-
- retval = sf_disable_write(chip, SPI_WRDI);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sf_polling_status(chip, 100);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else if (program_mode == PAGE_PROGRAM) {
- buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL);
- if (!buf)
- TRACE_RET(chip, STATUS_NOMEM);
-
- while (len) {
- u16 pagelen = SF_PAGE_LEN - (u8)addr;
-
- if (pagelen > len)
- pagelen = len;
-
- retval = sf_enable_write(chip, SPI_WREN);
- if (retval != STATUS_SUCCESS) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- rtsx_init_cmd(chip);
-
- trans_dma_enable(DMA_TO_DEVICE, chip, 256, DMA_256);
- sf_program(chip, ins, 1, addr, pagelen);
-
- rtsx_send_cmd_no_wait(chip);
-
- rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset, FROM_XFER_BUF);
-
- retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, DMA_TO_DEVICE, 100);
- if (retval < 0) {
- kfree(buf);
- rtsx_clear_spi_error(chip);
- spi_set_err_code(chip, SPI_HW_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = sf_polling_status(chip, 100);
- if (retval != STATUS_SUCCESS) {
- kfree(buf);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- addr += pagelen;
- len -= pagelen;
- }
-
- kfree(buf);
- } else {
- spi_set_err_code(chip, SPI_INVALID_COMMAND);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int retval;
- u8 ins, erase_mode;
- u32 addr;
-
- spi_set_err_code(chip, SPI_NO_ERR);
-
- ins = srb->cmnd[3];
- addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6];
- erase_mode = srb->cmnd[9];
-
- retval = spi_set_init_para(chip);
- if (retval != STATUS_SUCCESS) {
- spi_set_err_code(chip, SPI_HW_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (erase_mode == PAGE_ERASE) {
- retval = sf_enable_write(chip, SPI_WREN);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sf_erase(chip, ins, 1, addr);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else if (erase_mode == CHIP_ERASE) {
- retval = sf_enable_write(chip, SPI_WREN);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = sf_erase(chip, ins, 0, 0);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- spi_set_err_code(chip, SPI_INVALID_COMMAND);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
-{
- int retval;
- u8 ins, status, ewsr;
-
- ins = srb->cmnd[3];
- status = srb->cmnd[4];
- ewsr = srb->cmnd[5];
-
- retval = spi_set_init_para(chip);
- if (retval != STATUS_SUCCESS) {
- spi_set_err_code(chip, SPI_HW_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = sf_enable_write(chip, ewsr);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, 0);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1);
- rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, status);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CDO_MODE0);
- rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
-
- retval = rtsx_send_cmd(chip, 0, 100);
- if (retval != STATUS_SUCCESS) {
- rtsx_clear_spi_error(chip);
- spi_set_err_code(chip, SPI_HW_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
diff --git a/drivers/staging/rts_pstor/spi.h b/drivers/staging/rts_pstor/spi.h
deleted file mode 100644
index b59291f8b20..00000000000
--- a/drivers/staging/rts_pstor/spi.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- * Header file
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#ifndef __REALTEK_RTSX_SPI_H
-#define __REALTEK_RTSX_SPI_H
-
-/* SPI operation error */
-#define SPI_NO_ERR 0x00
-#define SPI_HW_ERR 0x01
-#define SPI_INVALID_COMMAND 0x02
-#define SPI_READ_ERR 0x03
-#define SPI_WRITE_ERR 0x04
-#define SPI_ERASE_ERR 0x05
-#define SPI_BUSY_ERR 0x06
-
-/* Serial flash instruction */
-#define SPI_READ 0x03
-#define SPI_FAST_READ 0x0B
-#define SPI_WREN 0x06
-#define SPI_WRDI 0x04
-#define SPI_RDSR 0x05
-
-#define SF_PAGE_LEN 256
-
-#define BYTE_PROGRAM 0
-#define AAI_PROGRAM 1
-#define PAGE_PROGRAM 2
-
-#define PAGE_ERASE 0
-#define CHIP_ERASE 1
-
-int spi_erase_eeprom_chip(struct rtsx_chip *chip);
-int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr);
-int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val);
-int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val);
-int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-
-
-#endif /* __REALTEK_RTSX_SPI_H */
diff --git a/drivers/staging/rts_pstor/trace.h b/drivers/staging/rts_pstor/trace.h
deleted file mode 100644
index cf60a1b872b..00000000000
--- a/drivers/staging/rts_pstor/trace.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- * Header file
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#ifndef __REALTEK_RTSX_TRACE_H
-#define __REALTEK_RTSX_TRACE_H
-
-#define _MSG_TRACE
-
-#ifdef _MSG_TRACE
-static inline char *filename(char *path)
-{
- char *ptr;
-
- if (path == NULL)
- return NULL;
-
- ptr = path;
-
- while (*ptr != '\0') {
- if ((*ptr == '\\') || (*ptr == '/'))
- path = ptr + 1;
-
- ptr++;
- }
-
- return path;
-}
-
-#define TRACE_RET(chip, ret) \
-do { \
- char *_file = filename(__FILE__); \
- RTSX_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \
- (chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \
- strncpy((chip)->trace_msg[(chip)->msg_idx].func, __func__, MSG_FUNC_LEN-1); \
- strncpy((chip)->trace_msg[(chip)->msg_idx].file, _file, MSG_FILE_LEN-1); \
- get_current_time((chip)->trace_msg[(chip)->msg_idx].timeval_buf, TIME_VAL_LEN); \
- (chip)->trace_msg[(chip)->msg_idx].valid = 1; \
- (chip)->msg_idx++; \
- if ((chip)->msg_idx >= TRACE_ITEM_CNT) { \
- (chip)->msg_idx = 0; \
- } \
- return ret; \
-} while (0)
-
-#define TRACE_GOTO(chip, label) \
-do { \
- char *_file = filename(__FILE__); \
- RTSX_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \
- (chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \
- strncpy((chip)->trace_msg[(chip)->msg_idx].func, __func__, MSG_FUNC_LEN-1); \
- strncpy((chip)->trace_msg[(chip)->msg_idx].file, _file, MSG_FILE_LEN-1); \
- get_current_time((chip)->trace_msg[(chip)->msg_idx].timeval_buf, TIME_VAL_LEN); \
- (chip)->trace_msg[(chip)->msg_idx].valid = 1; \
- (chip)->msg_idx++; \
- if ((chip)->msg_idx >= TRACE_ITEM_CNT) { \
- (chip)->msg_idx = 0; \
- } \
- goto label; \
-} while (0)
-#else
-#define TRACE_RET(chip, ret) return ret
-#define TRACE_GOTO(chip, label) goto label
-#endif
-
-#ifdef CONFIG_RTS_PSTOR_DEBUG
-#define RTSX_DUMP(buf, buf_len) \
- print_hex_dump(KERN_DEBUG, RTSX_STOR, DUMP_PREFIX_NONE, \
- 16, 1, (buf), (buf_len), false)
-#else
-#define RTSX_DUMP(buf, buf_len)
-#endif
-
-#endif /* __REALTEK_RTSX_TRACE_H */
diff --git a/drivers/staging/rts_pstor/xd.c b/drivers/staging/rts_pstor/xd.c
deleted file mode 100644
index 9bba5b11a82..00000000000
--- a/drivers/staging/rts_pstor/xd.c
+++ /dev/null
@@ -1,2052 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#include <linux/blkdev.h>
-#include <linux/kthread.h>
-#include <linux/sched.h>
-#include <linux/vmalloc.h>
-
-#include "rtsx.h"
-#include "rtsx_transport.h"
-#include "rtsx_scsi.h"
-#include "rtsx_card.h"
-#include "xd.h"
-
-static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no);
-static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, u16 logoff, u8 start_page, u8 end_page);
-
-static inline void xd_set_err_code(struct rtsx_chip *chip, u8 err_code)
-{
- struct xd_info *xd_card = &(chip->xd_card);
-
- xd_card->err_code = err_code;
-}
-
-static inline int xd_check_err_code(struct rtsx_chip *chip, u8 err_code)
-{
- struct xd_info *xd_card = &(chip->xd_card);
-
- return (xd_card->err_code == err_code);
-}
-
-static int xd_set_init_para(struct rtsx_chip *chip)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- int retval;
-
- if (chip->asic_code)
- xd_card->xd_clock = 47;
- else
- xd_card->xd_clock = CLK_50;
-
- retval = switch_clock(chip, xd_card->xd_clock);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int xd_switch_clock(struct rtsx_chip *chip)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- int retval;
-
- retval = select_card(chip, XD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = switch_clock(chip, xd_card->xd_clock);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int xd_read_id(struct rtsx_chip *chip, u8 id_cmd, u8 *id_buf, u8 buf_len)
-{
- int retval, i;
- u8 *ptr;
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, id_cmd);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_ID);
- rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END);
-
- for (i = 0; i < 4; i++)
- rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_ADDRESS1 + i), 0, 0);
-
- retval = rtsx_send_cmd(chip, XD_CARD, 20);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- ptr = rtsx_get_cmd_data(chip) + 1;
- if (id_buf && buf_len) {
- if (buf_len > 4)
- buf_len = 4;
- memcpy(id_buf, ptr, buf_len);
- }
-
- return STATUS_SUCCESS;
-}
-
-static void xd_assign_phy_addr(struct rtsx_chip *chip, u32 addr, u8 mode)
-{
- struct xd_info *xd_card = &(chip->xd_card);
-
- switch (mode) {
- case XD_RW_ADDR:
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, 0);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, (u8)addr);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, 0xFF, (u8)(addr >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS3, 0xFF, (u8)(addr >> 16));
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF,
- xd_card->addr_cycle | XD_CALC_ECC | XD_BA_NO_TRANSFORM);
- break;
-
- case XD_ERASE_ADDR:
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, (u8)addr);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, (u8)(addr >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, 0xFF, (u8)(addr >> 16));
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF,
- (xd_card->addr_cycle - 1) | XD_CALC_ECC | XD_BA_NO_TRANSFORM);
- break;
-
- default:
- break;
- }
-}
-
-static int xd_read_redundant(struct rtsx_chip *chip, u32 page_addr, u8 *buf, int buf_len)
-{
- int retval, i;
-
- rtsx_init_cmd(chip);
-
- xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_REDUNDANT);
- rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END);
-
- for (i = 0; i < 6; i++)
- rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_PAGE_STATUS + i), 0, 0);
- for (i = 0; i < 4; i++)
- rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_RESERVED0 + i), 0, 0);
- rtsx_add_cmd(chip, READ_REG_CMD, XD_PARITY, 0, 0);
-
- retval = rtsx_send_cmd(chip, XD_CARD, 500);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (buf && buf_len) {
- u8 *ptr = rtsx_get_cmd_data(chip) + 1;
-
- if (buf_len > 11)
- buf_len = 11;
- memcpy(buf, ptr, buf_len);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int xd_read_data_from_ppb(struct rtsx_chip *chip, int offset, u8 *buf, int buf_len)
-{
- int retval, i;
-
- if (!buf || (buf_len < 0))
- TRACE_RET(chip, STATUS_FAIL);
-
- rtsx_init_cmd(chip);
-
- for (i = 0; i < buf_len; i++)
- rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + offset + i, 0, 0);
-
- retval = rtsx_send_cmd(chip, 0, 250);
- if (retval < 0) {
- rtsx_clear_xd_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- memcpy(buf, rtsx_get_cmd_data(chip), buf_len);
-
- return STATUS_SUCCESS;
-}
-
-static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf, int buf_len)
-{
- int retval;
- u8 reg;
-
- if (!buf || (buf_len < 10))
- TRACE_RET(chip, STATUS_FAIL);
-
- rtsx_init_cmd(chip);
-
- xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_PAGES);
- rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END);
-
- retval = rtsx_send_cmd(chip, XD_CARD, 250);
- if (retval == -ETIMEDOUT) {
- rtsx_clear_xd_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- RTSX_READ_REG(chip, XD_PAGE_STATUS, &reg);
- if (reg != XD_GPG) {
- rtsx_clear_xd_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- RTSX_READ_REG(chip, XD_CTL, &reg);
- if (!(reg & XD_ECC1_ERROR) || !(reg & XD_ECC1_UNCORRECTABLE)) {
- retval = xd_read_data_from_ppb(chip, 0, buf, buf_len);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- if (reg & XD_ECC1_ERROR) {
- u8 ecc_bit, ecc_byte;
-
- RTSX_READ_REG(chip, XD_ECC_BIT1, &ecc_bit);
- RTSX_READ_REG(chip, XD_ECC_BYTE1, &ecc_byte);
-
- RTSX_DEBUGP("ECC_BIT1 = 0x%x, ECC_BYTE1 = 0x%x\n", ecc_bit, ecc_byte);
- if (ecc_byte < buf_len) {
- RTSX_DEBUGP("Before correct: 0x%x\n", buf[ecc_byte]);
- buf[ecc_byte] ^= (1 << ecc_bit);
- RTSX_DEBUGP("After correct: 0x%x\n", buf[ecc_byte]);
- }
- }
- } else if (!(reg & XD_ECC2_ERROR) || !(reg & XD_ECC2_UNCORRECTABLE)) {
- rtsx_clear_xd_error(chip);
-
- retval = xd_read_data_from_ppb(chip, 256, buf, buf_len);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- if (reg & XD_ECC2_ERROR) {
- u8 ecc_bit, ecc_byte;
-
- RTSX_READ_REG(chip, XD_ECC_BIT2, &ecc_bit);
- RTSX_READ_REG(chip, XD_ECC_BYTE2, &ecc_byte);
-
- RTSX_DEBUGP("ECC_BIT2 = 0x%x, ECC_BYTE2 = 0x%x\n", ecc_bit, ecc_byte);
- if (ecc_byte < buf_len) {
- RTSX_DEBUGP("Before correct: 0x%x\n", buf[ecc_byte]);
- buf[ecc_byte] ^= (1 << ecc_bit);
- RTSX_DEBUGP("After correct: 0x%x\n", buf[ecc_byte]);
- }
- }
- } else {
- rtsx_clear_xd_error(chip);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static void xd_fill_pull_ctl_disable(struct rtsx_chip *chip)
-{
- if (CHECK_PID(chip, 0x5209)) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xD5);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x15);
- } else if (CHECK_PID(chip, 0x5208)) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF,
- XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF,
- XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF,
- XD_WP_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF,
- XD_RDY_PD | XD_WE_PD | XD_RE_PD | XD_ALE_PD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF,
- MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD);
- } else if (CHECK_PID(chip, 0x5288)) {
- if (CHECK_BARO_PKG(chip, QFN)) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x4B);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x69);
- }
- }
-}
-
-static void xd_fill_pull_ctl_stage1_barossa(struct rtsx_chip *chip)
-{
- if (CHECK_BARO_PKG(chip, QFN)) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x4B);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55);
- }
-}
-
-static void xd_fill_pull_ctl_enable(struct rtsx_chip *chip)
-{
- if (CHECK_PID(chip, 0x5209)) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xAA);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xD5);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x15);
- } else if (CHECK_PID(chip, 0x5208)) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF,
- XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF,
- XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF,
- XD_WP_PD | XD_CE_PU | XD_CLE_PD | XD_CD_PU);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF,
- XD_RDY_PU | XD_WE_PU | XD_RE_PU | XD_ALE_PD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF,
- MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD);
- } else if (CHECK_PID(chip, 0x5288)) {
- if (CHECK_BARO_PKG(chip, QFN)) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x53);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0xA9);
- }
- }
-}
-
-static int xd_pull_ctl_disable(struct rtsx_chip *chip)
-{
- if (CHECK_PID(chip, 0x5209)) {
- RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0xD5);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x55);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, 0x55);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, 0x15);
- } else if (CHECK_PID(chip, 0x5208)) {
- RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF,
- XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF,
- XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF,
- XD_WP_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF,
- XD_RDY_PD | XD_WE_PD | XD_RE_PD | XD_ALE_PD);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF,
- MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD);
- } else if (CHECK_PID(chip, 0x5288)) {
- if (CHECK_BARO_PKG(chip, QFN)) {
- RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B);
- RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69);
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-static void xd_clear_dma_buffer(struct rtsx_chip *chip)
-{
- if (CHECK_PID(chip, 0x5209)) {
- int retval;
- u8 *buf;
-
- RTSX_DEBUGP("xD ECC error, dummy write!\n");
-
- buf = kmalloc(512, GFP_KERNEL);
- if (!buf)
- return;
-
- rtsx_init_cmd(chip);
-
- trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_SELECT, 0x07, SD_MOD_SEL);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, SD_CLK_EN, SD_CLK_EN);
- if (chip->asic_code) {
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0xAA);
- } else {
- rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL,
- FPGA_SD_PULL_CTL_BIT, 0);
- }
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, SD_BUS_WIDTH_4);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
- SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START);
- rtsx_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END);
-
- rtsx_send_cmd_no_wait(chip);
-
- retval = rtsx_transfer_data(chip, SD_CARD, buf, 512, 0, DMA_TO_DEVICE, 100);
- if (retval < 0) {
- u8 val;
-
- rtsx_read_register(chip, SD_STAT1, &val);
- RTSX_DEBUGP("SD_STAT1: 0x%x\n", val);
-
- rtsx_read_register(chip, SD_STAT2, &val);
- RTSX_DEBUGP("SD_STAT2: 0x%x\n", val);
-
- rtsx_read_register(chip, SD_BUS_STAT, &val);
- RTSX_DEBUGP("SD_BUS_STAT: 0x%x\n", val);
-
- rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR);
- }
-
- kfree(buf);
-
- if (chip->asic_code) {
- rtsx_write_register(chip, CARD_PULL_CTL2, 0xFF, 0x55);
- } else {
- rtsx_write_register(chip, FPGA_PULL_CTL,
- FPGA_SD_PULL_CTL_BIT, FPGA_SD_PULL_CTL_BIT);
- }
- rtsx_write_register(chip, CARD_SELECT, 0x07, XD_MOD_SEL);
- rtsx_write_register(chip, CARD_CLK_EN, SD_CLK_EN, 0);
- }
-}
-
-static int reset_xd(struct rtsx_chip *chip)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- int retval, i, j;
- u8 *ptr, id_buf[4], redunt[11];
-
- retval = select_card(chip, XD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, 0xFF, XD_PGSTS_NOT_FF);
- if (chip->asic_code) {
- if (!CHECK_PID(chip, 0x5288))
- xd_fill_pull_ctl_disable(chip);
- else
- xd_fill_pull_ctl_stage1_barossa(chip);
- } else {
- rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF,
- (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN3) | 0x20);
- }
-
- if (!chip->ft2_fast_mode)
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_INIT, XD_NO_AUTO_PWR_OFF, 0);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0);
-
- retval = rtsx_send_cmd(chip, XD_CARD, 100);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (!chip->ft2_fast_mode) {
- retval = card_power_off(chip, XD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- wait_timeout(250);
-
- if (CHECK_PID(chip, 0x5209))
- RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0xAA);
-
- rtsx_init_cmd(chip);
-
- if (chip->asic_code) {
- xd_fill_pull_ctl_enable(chip);
- } else {
- rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF,
- (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN2) | 0x20);
- }
-
- retval = rtsx_send_cmd(chip, XD_CARD, 100);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = card_power_on(chip, XD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
-#ifdef SUPPORT_OCP
- wait_timeout(50);
- if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
- RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat);
- TRACE_RET(chip, STATUS_FAIL);
- }
-#endif
- }
-
- rtsx_init_cmd(chip);
-
- if (chip->ft2_fast_mode) {
- if (chip->asic_code) {
- xd_fill_pull_ctl_enable(chip);
- } else {
- rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF,
- (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN2) | 0x20);
- }
- }
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, XD_OUTPUT_EN);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CTL, XD_CE_DISEN, XD_CE_DISEN);
-
- retval = rtsx_send_cmd(chip, XD_CARD, 100);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (!chip->ft2_fast_mode)
- wait_timeout(200);
-
- retval = xd_set_init_para(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- /* Read ID to check if the timing setting is right */
- for (i = 0; i < 4; i++) {
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DTCTL, 0xFF,
- XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP * (2 + i) + XD_TIME_RWN_STEP * i);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CATCTL, 0xFF,
- XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP * (4 + i) + XD_TIME_RWN_STEP * (3 + i));
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_RESET);
- rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END);
-
- rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0);
- rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0);
-
- retval = rtsx_send_cmd(chip, XD_CARD, 100);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- ptr = rtsx_get_cmd_data(chip) + 1;
-
- RTSX_DEBUGP("XD_DAT: 0x%x, XD_CTL: 0x%x\n", ptr[0], ptr[1]);
-
- if (((ptr[0] & READY_FLAG) != READY_STATE) || !(ptr[1] & XD_RDY))
- continue;
-
- retval = xd_read_id(chip, READ_ID, id_buf, 4);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_DEBUGP("READ_ID: 0x%x 0x%x 0x%x 0x%x\n",
- id_buf[0], id_buf[1], id_buf[2], id_buf[3]);
-
- xd_card->device_code = id_buf[1];
-
- /* Check if the xD card is supported */
- switch (xd_card->device_code) {
- case XD_4M_X8_512_1:
- case XD_4M_X8_512_2:
- xd_card->block_shift = 4;
- xd_card->page_off = 0x0F;
- xd_card->addr_cycle = 3;
- xd_card->zone_cnt = 1;
- xd_card->capacity = 8000;
- XD_SET_4MB(xd_card);
- break;
- case XD_8M_X8_512:
- xd_card->block_shift = 4;
- xd_card->page_off = 0x0F;
- xd_card->addr_cycle = 3;
- xd_card->zone_cnt = 1;
- xd_card->capacity = 16000;
- break;
- case XD_16M_X8_512:
- XD_PAGE_512(xd_card);
- xd_card->addr_cycle = 3;
- xd_card->zone_cnt = 1;
- xd_card->capacity = 32000;
- break;
- case XD_32M_X8_512:
- XD_PAGE_512(xd_card);
- xd_card->addr_cycle = 3;
- xd_card->zone_cnt = 2;
- xd_card->capacity = 64000;
- break;
- case XD_64M_X8_512:
- XD_PAGE_512(xd_card);
- xd_card->addr_cycle = 4;
- xd_card->zone_cnt = 4;
- xd_card->capacity = 128000;
- break;
- case XD_128M_X8_512:
- XD_PAGE_512(xd_card);
- xd_card->addr_cycle = 4;
- xd_card->zone_cnt = 8;
- xd_card->capacity = 256000;
- break;
- case XD_256M_X8_512:
- XD_PAGE_512(xd_card);
- xd_card->addr_cycle = 4;
- xd_card->zone_cnt = 16;
- xd_card->capacity = 512000;
- break;
- case XD_512M_X8:
- XD_PAGE_512(xd_card);
- xd_card->addr_cycle = 4;
- xd_card->zone_cnt = 32;
- xd_card->capacity = 1024000;
- break;
- case xD_1G_X8_512:
- XD_PAGE_512(xd_card);
- xd_card->addr_cycle = 4;
- xd_card->zone_cnt = 64;
- xd_card->capacity = 2048000;
- break;
- case xD_2G_X8_512:
- XD_PAGE_512(xd_card);
- xd_card->addr_cycle = 4;
- xd_card->zone_cnt = 128;
- xd_card->capacity = 4096000;
- break;
- default:
- continue;
- }
-
- /* Confirm timing setting */
- for (j = 0; j < 10; j++) {
- retval = xd_read_id(chip, READ_ID, id_buf, 4);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if (id_buf[1] != xd_card->device_code)
- break;
- }
-
- if (j == 10)
- break;
- }
-
- if (i == 4) {
- xd_card->block_shift = 0;
- xd_card->page_off = 0;
- xd_card->addr_cycle = 0;
- xd_card->capacity = 0;
-
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = xd_read_id(chip, READ_xD_ID, id_buf, 4);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- RTSX_DEBUGP("READ_xD_ID: 0x%x 0x%x 0x%x 0x%x\n",
- id_buf[0], id_buf[1], id_buf[2], id_buf[3]);
- if (id_buf[2] != XD_ID_CODE)
- TRACE_RET(chip, STATUS_FAIL);
-
- /* Search CIS block */
- for (i = 0; i < 24; i++) {
- u32 page_addr;
-
- if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- page_addr = (u32)i << xd_card->block_shift;
-
- for (j = 0; j < 3; j++) {
- retval = xd_read_redundant(chip, page_addr, redunt, 11);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (j == 3)
- continue;
-
- if (redunt[BLOCK_STATUS] != XD_GBLK)
- continue;
-
- j = 0;
- if (redunt[PAGE_STATUS] != XD_GPG) {
- for (j = 1; j <= 8; j++) {
- retval = xd_read_redundant(chip, page_addr + j, redunt, 11);
- if (retval == STATUS_SUCCESS) {
- if (redunt[PAGE_STATUS] == XD_GPG)
- break;
- }
- }
-
- if (j == 9)
- break;
- }
-
- /* Check CIS data */
- if ((redunt[BLOCK_STATUS] == XD_GBLK) && (redunt[PARITY] & XD_BA1_ALL0)) {
- u8 buf[10];
-
- page_addr += j;
-
- retval = xd_read_cis(chip, page_addr, buf, 10);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- if ((buf[0] == 0x01) && (buf[1] == 0x03) && (buf[2] == 0xD9)
- && (buf[3] == 0x01) && (buf[4] == 0xFF)
- && (buf[5] == 0x18) && (buf[6] == 0x02)
- && (buf[7] == 0xDF) && (buf[8] == 0x01)
- && (buf[9] == 0x20)) {
- xd_card->cis_block = (u16)i;
- }
- }
-
- break;
- }
-
- RTSX_DEBUGP("CIS block: 0x%x\n", xd_card->cis_block);
- if (xd_card->cis_block == 0xFFFF)
- TRACE_RET(chip, STATUS_FAIL);
-
- chip->capacity[chip->card2lun[XD_CARD]] = xd_card->capacity;
-
- return STATUS_SUCCESS;
-}
-
-static int xd_check_data_blank(u8 *redunt)
-{
- int i;
-
- for (i = 0; i < 6; i++) {
- if (redunt[PAGE_STATUS + i] != 0xFF)
- return 0;
- }
-
- if ((redunt[PARITY] & (XD_ECC1_ALL1 | XD_ECC2_ALL1)) != (XD_ECC1_ALL1 | XD_ECC2_ALL1))
- return 0;
-
-
- for (i = 0; i < 4; i++) {
- if (redunt[RESERVED0 + i] != 0xFF)
- return 0;
- }
-
- return 1;
-}
-
-static u16 xd_load_log_block_addr(u8 *redunt)
-{
- u16 addr = 0xFFFF;
-
- if (redunt[PARITY] & XD_BA1_BA2_EQL)
- addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) | redunt[BLOCK_ADDR1_L];
- else if (redunt[PARITY] & XD_BA1_VALID)
- addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) | redunt[BLOCK_ADDR1_L];
- else if (redunt[PARITY] & XD_BA2_VALID)
- addr = ((u16)redunt[BLOCK_ADDR2_H] << 8) | redunt[BLOCK_ADDR2_L];
-
- return addr;
-}
-
-static int xd_init_l2p_tbl(struct rtsx_chip *chip)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- int size, i;
-
- RTSX_DEBUGP("xd_init_l2p_tbl: zone_cnt = %d\n", xd_card->zone_cnt);
-
- if (xd_card->zone_cnt < 1)
- TRACE_RET(chip, STATUS_FAIL);
-
- size = xd_card->zone_cnt * sizeof(struct zone_entry);
- RTSX_DEBUGP("Buffer size for l2p table is %d\n", size);
-
- xd_card->zone = (struct zone_entry *)vmalloc(size);
- if (!xd_card->zone)
- TRACE_RET(chip, STATUS_ERROR);
-
- for (i = 0; i < xd_card->zone_cnt; i++) {
- xd_card->zone[i].build_flag = 0;
- xd_card->zone[i].l2p_table = NULL;
- xd_card->zone[i].free_table = NULL;
- xd_card->zone[i].get_index = 0;
- xd_card->zone[i].set_index = 0;
- xd_card->zone[i].unused_blk_cnt = 0;
- }
-
- return STATUS_SUCCESS;
-}
-
-static inline void free_zone(struct zone_entry *zone)
-{
- RTSX_DEBUGP("free_zone\n");
-
- if (!zone)
- return;
-
- zone->build_flag = 0;
- zone->set_index = 0;
- zone->get_index = 0;
- zone->unused_blk_cnt = 0;
- if (zone->l2p_table) {
- vfree(zone->l2p_table);
- zone->l2p_table = NULL;
- }
- if (zone->free_table) {
- vfree(zone->free_table);
- zone->free_table = NULL;
- }
-}
-
-static void xd_set_unused_block(struct rtsx_chip *chip, u32 phy_blk)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- struct zone_entry *zone;
- int zone_no;
-
- zone_no = (int)phy_blk >> 10;
- if (zone_no >= xd_card->zone_cnt) {
- RTSX_DEBUGP("Set unused block to invalid zone (zone_no = %d, zone_cnt = %d)\n",
- zone_no, xd_card->zone_cnt);
- return;
- }
- zone = &(xd_card->zone[zone_no]);
-
- if (zone->free_table == NULL) {
- if (xd_build_l2p_tbl(chip, zone_no) != STATUS_SUCCESS)
- return;
- }
-
- if ((zone->set_index >= XD_FREE_TABLE_CNT)
- || (zone->set_index < 0)) {
- free_zone(zone);
- RTSX_DEBUGP("Set unused block fail, invalid set_index\n");
- return;
- }
-
- RTSX_DEBUGP("Set unused block to index %d\n", zone->set_index);
-
- zone->free_table[zone->set_index++] = (u16) (phy_blk & 0x3ff);
- if (zone->set_index >= XD_FREE_TABLE_CNT)
- zone->set_index = 0;
- zone->unused_blk_cnt++;
-}
-
-static u32 xd_get_unused_block(struct rtsx_chip *chip, int zone_no)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- struct zone_entry *zone;
- u32 phy_blk;
-
- if (zone_no >= xd_card->zone_cnt) {
- RTSX_DEBUGP("Get unused block from invalid zone (zone_no = %d, zone_cnt = %d)\n",
- zone_no, xd_card->zone_cnt);
- return BLK_NOT_FOUND;
- }
- zone = &(xd_card->zone[zone_no]);
-
- if ((zone->unused_blk_cnt == 0) || (zone->set_index == zone->get_index)) {
- free_zone(zone);
- RTSX_DEBUGP("Get unused block fail, no unused block available\n");
- return BLK_NOT_FOUND;
- }
- if ((zone->get_index >= XD_FREE_TABLE_CNT) || (zone->get_index < 0)) {
- free_zone(zone);
- RTSX_DEBUGP("Get unused block fail, invalid get_index\n");
- return BLK_NOT_FOUND;
- }
-
- RTSX_DEBUGP("Get unused block from index %d\n", zone->get_index);
-
- phy_blk = zone->free_table[zone->get_index];
- zone->free_table[zone->get_index++] = 0xFFFF;
- if (zone->get_index >= XD_FREE_TABLE_CNT)
- zone->get_index = 0;
- zone->unused_blk_cnt--;
-
- phy_blk += ((u32)(zone_no) << 10);
- return phy_blk;
-}
-
-static void xd_set_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off, u16 phy_off)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- struct zone_entry *zone;
-
- zone = &(xd_card->zone[zone_no]);
- zone->l2p_table[log_off] = phy_off;
-}
-
-static u32 xd_get_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- struct zone_entry *zone;
- int retval;
-
- zone = &(xd_card->zone[zone_no]);
- if (zone->l2p_table[log_off] == 0xFFFF) {
- u32 phy_blk = 0;
- int i;
-
-#ifdef XD_DELAY_WRITE
- retval = xd_delay_write(chip);
- if (retval != STATUS_SUCCESS) {
- RTSX_DEBUGP("In xd_get_l2p_tbl, delay write fail!\n");
- return BLK_NOT_FOUND;
- }
-#endif
-
- if (zone->unused_blk_cnt <= 0) {
- RTSX_DEBUGP("No unused block!\n");
- return BLK_NOT_FOUND;
- }
-
- for (i = 0; i < zone->unused_blk_cnt; i++) {
- phy_blk = xd_get_unused_block(chip, zone_no);
- if (phy_blk == BLK_NOT_FOUND) {
- RTSX_DEBUGP("No unused block available!\n");
- return BLK_NOT_FOUND;
- }
-
- retval = xd_init_page(chip, phy_blk, log_off, 0, xd_card->page_off + 1);
- if (retval == STATUS_SUCCESS)
- break;
- }
- if (i >= zone->unused_blk_cnt) {
- RTSX_DEBUGP("No good unused block available!\n");
- return BLK_NOT_FOUND;
- }
-
- xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(phy_blk & 0x3FF));
- return phy_blk;
- }
-
- return (u32)zone->l2p_table[log_off] + ((u32)(zone_no) << 10);
-}
-
-int reset_xd_card(struct rtsx_chip *chip)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- int retval;
-
- memset(xd_card, 0, sizeof(struct xd_info));
-
- xd_card->block_shift = 0;
- xd_card->page_off = 0;
- xd_card->addr_cycle = 0;
- xd_card->capacity = 0;
- xd_card->zone_cnt = 0;
- xd_card->cis_block = 0xFFFF;
- xd_card->delay_write.delay_write_flag = 0;
-
- retval = enable_card_clock(chip, XD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = reset_xd(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- retval = xd_init_l2p_tbl(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int xd_mark_bad_block(struct rtsx_chip *chip, u32 phy_blk)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- int retval;
- u32 page_addr;
- u8 reg = 0;
-
- RTSX_DEBUGP("mark block 0x%x as bad block\n", phy_blk);
-
- if (phy_blk == BLK_NOT_FOUND)
- TRACE_RET(chip, STATUS_FAIL);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_LATER_BBLK);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, 0xFF);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, 0xFF);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_H, 0xFF, 0xFF);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_L, 0xFF, 0xFF);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED0, 0xFF, 0xFF);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED1, 0xFF, 0xFF);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED2, 0xFF, 0xFF);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED3, 0xFF, 0xFF);
-
- page_addr = phy_blk << xd_card->block_shift;
-
- xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, xd_card->page_off + 1);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_WRITE_REDUNDANT);
- rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END);
-
- retval = rtsx_send_cmd(chip, XD_CARD, 500);
- if (retval < 0) {
- rtsx_clear_xd_error(chip);
- rtsx_read_register(chip, XD_DAT, &reg);
- if (reg & PROGRAM_ERROR)
- xd_set_err_code(chip, XD_PRG_ERROR);
- else
- xd_set_err_code(chip, XD_TO_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, u16 logoff, u8 start_page, u8 end_page)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- int retval;
- u32 page_addr;
- u8 reg = 0;
-
- RTSX_DEBUGP("Init block 0x%x\n", phy_blk);
-
- if (start_page > end_page)
- TRACE_RET(chip, STATUS_FAIL);
- if (phy_blk == BLK_NOT_FOUND)
- TRACE_RET(chip, STATUS_FAIL);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, 0xFF);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, 0xFF);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, (u8)(logoff >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)logoff);
-
- page_addr = (phy_blk << xd_card->block_shift) + start_page;
-
- xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM, XD_BA_TRANSFORM);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, (end_page - start_page));
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_WRITE_REDUNDANT);
- rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END);
-
- retval = rtsx_send_cmd(chip, XD_CARD, 500);
- if (retval < 0) {
- rtsx_clear_xd_error(chip);
- rtsx_read_register(chip, XD_DAT, &reg);
- if (reg & PROGRAM_ERROR) {
- xd_mark_bad_block(chip, phy_blk);
- xd_set_err_code(chip, XD_PRG_ERROR);
- } else {
- xd_set_err_code(chip, XD_TO_ERROR);
- }
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk, u8 start_page, u8 end_page)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- u32 old_page, new_page;
- u8 i, reg = 0;
- int retval;
-
- RTSX_DEBUGP("Copy page from block 0x%x to block 0x%x\n", old_blk, new_blk);
-
- if (start_page > end_page)
- TRACE_RET(chip, STATUS_FAIL);
-
- if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND))
- TRACE_RET(chip, STATUS_FAIL);
-
- old_page = (old_blk << xd_card->block_shift) + start_page;
- new_page = (new_blk << xd_card->block_shift) + start_page;
-
- XD_CLR_BAD_NEWBLK(xd_card);
-
- RTSX_WRITE_REG(chip, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
-
- for (i = start_page; i < end_page; i++) {
- if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
- rtsx_clear_xd_error(chip);
- xd_set_err_code(chip, XD_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- rtsx_init_cmd(chip);
-
- xd_assign_phy_addr(chip, old_page, XD_RW_ADDR);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS, 0);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_PAGES);
- rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END);
-
- retval = rtsx_send_cmd(chip, XD_CARD, 500);
- if (retval < 0) {
- rtsx_clear_xd_error(chip);
- reg = 0;
- rtsx_read_register(chip, XD_CTL, &reg);
- if (reg & (XD_ECC1_ERROR | XD_ECC2_ERROR)) {
- wait_timeout(100);
-
- if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
- xd_set_err_code(chip, XD_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (((reg & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) ==
- (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE))
- || ((reg & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE)) ==
- (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) {
- rtsx_write_register(chip, XD_PAGE_STATUS, 0xFF, XD_BPG);
- rtsx_write_register(chip, XD_BLOCK_STATUS, 0xFF, XD_GBLK);
- XD_SET_BAD_OLDBLK(xd_card);
- RTSX_DEBUGP("old block 0x%x ecc error\n", old_blk);
- }
- } else {
- xd_set_err_code(chip, XD_TO_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- if (XD_CHK_BAD_OLDBLK(xd_card))
- rtsx_clear_xd_error(chip);
-
- rtsx_init_cmd(chip);
-
- xd_assign_phy_addr(chip, new_page, XD_RW_ADDR);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
- XD_TRANSFER_START | XD_WRITE_PAGES);
- rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END);
-
- retval = rtsx_send_cmd(chip, XD_CARD, 300);
- if (retval < 0) {
- rtsx_clear_xd_error(chip);
- reg = 0;
- rtsx_read_register(chip, XD_DAT, &reg);
- if (reg & PROGRAM_ERROR) {
- xd_mark_bad_block(chip, new_blk);
- xd_set_err_code(chip, XD_PRG_ERROR);
- XD_SET_BAD_NEWBLK(xd_card);
- } else {
- xd_set_err_code(chip, XD_TO_ERROR);
- }
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- old_page++;
- new_page++;
- }
-
- return STATUS_SUCCESS;
-}
-
-static int xd_reset_cmd(struct rtsx_chip *chip)
-{
- int retval;
- u8 *ptr;
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_RESET);
- rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END);
- rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0);
- rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0);
-
- retval = rtsx_send_cmd(chip, XD_CARD, 100);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- ptr = rtsx_get_cmd_data(chip) + 1;
- if (((ptr[0] & READY_FLAG) == READY_STATE) && (ptr[1] & XD_RDY))
- return STATUS_SUCCESS;
-
- TRACE_RET(chip, STATUS_FAIL);
-}
-
-static int xd_erase_block(struct rtsx_chip *chip, u32 phy_blk)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- u32 page_addr;
- u8 reg = 0, *ptr;
- int i, retval;
-
- if (phy_blk == BLK_NOT_FOUND)
- TRACE_RET(chip, STATUS_FAIL);
-
- page_addr = phy_blk << xd_card->block_shift;
-
- for (i = 0; i < 3; i++) {
- rtsx_init_cmd(chip);
-
- xd_assign_phy_addr(chip, page_addr, XD_ERASE_ADDR);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_ERASE);
- rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END);
- rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0);
-
- retval = rtsx_send_cmd(chip, XD_CARD, 250);
- if (retval < 0) {
- rtsx_clear_xd_error(chip);
- rtsx_read_register(chip, XD_DAT, &reg);
- if (reg & PROGRAM_ERROR) {
- xd_mark_bad_block(chip, phy_blk);
- xd_set_err_code(chip, XD_PRG_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- xd_set_err_code(chip, XD_ERASE_FAIL);
- }
- retval = xd_reset_cmd(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- continue;
- }
-
- ptr = rtsx_get_cmd_data(chip) + 1;
- if (*ptr & PROGRAM_ERROR) {
- xd_mark_bad_block(chip, phy_blk);
- xd_set_err_code(chip, XD_PRG_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
- }
-
- xd_mark_bad_block(chip, phy_blk);
- xd_set_err_code(chip, XD_ERASE_FAIL);
- TRACE_RET(chip, STATUS_FAIL);
-}
-
-
-static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- struct zone_entry *zone;
- int retval;
- u32 start, end, i;
- u16 max_logoff, cur_fst_page_logoff, cur_lst_page_logoff, ent_lst_page_logoff;
- u8 redunt[11];
-
- RTSX_DEBUGP("xd_build_l2p_tbl: %d\n", zone_no);
-
- if (xd_card->zone == NULL) {
- retval = xd_init_l2p_tbl(chip);
- if (retval != STATUS_SUCCESS)
- return retval;
- }
-
- if (xd_card->zone[zone_no].build_flag) {
- RTSX_DEBUGP("l2p table of zone %d has been built\n", zone_no);
- return STATUS_SUCCESS;
- }
-
- zone = &(xd_card->zone[zone_no]);
-
- if (zone->l2p_table == NULL) {
- zone->l2p_table = (u16 *)vmalloc(2000);
- if (zone->l2p_table == NULL)
- TRACE_GOTO(chip, Build_Fail);
- }
- memset((u8 *)(zone->l2p_table), 0xff, 2000);
-
- if (zone->free_table == NULL) {
- zone->free_table = (u16 *)vmalloc(XD_FREE_TABLE_CNT * 2);
- if (zone->free_table == NULL)
- TRACE_GOTO(chip, Build_Fail);
- }
- memset((u8 *)(zone->free_table), 0xff, XD_FREE_TABLE_CNT * 2);
-
- if (zone_no == 0) {
- if (xd_card->cis_block == 0xFFFF)
- start = 0;
- else
- start = xd_card->cis_block + 1;
- if (XD_CHK_4MB(xd_card)) {
- end = 0x200;
- max_logoff = 499;
- } else {
- end = 0x400;
- max_logoff = 999;
- }
- } else {
- start = (u32)(zone_no) << 10;
- end = (u32)(zone_no + 1) << 10;
- max_logoff = 999;
- }
-
- RTSX_DEBUGP("start block 0x%x, end block 0x%x\n", start, end);
-
- zone->set_index = zone->get_index = 0;
- zone->unused_blk_cnt = 0;
-
- for (i = start; i < end; i++) {
- u32 page_addr = i << xd_card->block_shift;
- u32 phy_block;
-
- retval = xd_read_redundant(chip, page_addr, redunt, 11);
- if (retval != STATUS_SUCCESS)
- continue;
-
- if (redunt[BLOCK_STATUS] != 0xFF) {
- RTSX_DEBUGP("bad block\n");
- continue;
- }
-
- if (xd_check_data_blank(redunt)) {
- RTSX_DEBUGP("blank block\n");
- xd_set_unused_block(chip, i);
- continue;
- }
-
- cur_fst_page_logoff = xd_load_log_block_addr(redunt);
- if ((cur_fst_page_logoff == 0xFFFF) || (cur_fst_page_logoff > max_logoff)) {
- retval = xd_erase_block(chip, i);
- if (retval == STATUS_SUCCESS)
- xd_set_unused_block(chip, i);
- continue;
- }
-
- if ((zone_no == 0) && (cur_fst_page_logoff == 0) && (redunt[PAGE_STATUS] != XD_GPG))
- XD_SET_MBR_FAIL(xd_card);
-
- if (zone->l2p_table[cur_fst_page_logoff] == 0xFFFF) {
- zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF);
- continue;
- }
-
- phy_block = zone->l2p_table[cur_fst_page_logoff] + ((u32)((zone_no) << 10));
-
- page_addr = ((i + 1) << xd_card->block_shift) - 1;
-
- retval = xd_read_redundant(chip, page_addr, redunt, 11);
- if (retval != STATUS_SUCCESS)
- continue;
-
- cur_lst_page_logoff = xd_load_log_block_addr(redunt);
- if (cur_lst_page_logoff == cur_fst_page_logoff) {
- int m;
-
- page_addr = ((phy_block + 1) << xd_card->block_shift) - 1;
-
- for (m = 0; m < 3; m++) {
- retval = xd_read_redundant(chip, page_addr, redunt, 11);
- if (retval == STATUS_SUCCESS)
- break;
- }
-
- if (m == 3) {
- zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF);
- retval = xd_erase_block(chip, phy_block);
- if (retval == STATUS_SUCCESS)
- xd_set_unused_block(chip, phy_block);
- continue;
- }
-
- ent_lst_page_logoff = xd_load_log_block_addr(redunt);
- if (ent_lst_page_logoff != cur_fst_page_logoff) {
- zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF);
- retval = xd_erase_block(chip, phy_block);
- if (retval == STATUS_SUCCESS)
- xd_set_unused_block(chip, phy_block);
- continue;
- } else {
- retval = xd_erase_block(chip, i);
- if (retval == STATUS_SUCCESS)
- xd_set_unused_block(chip, i);
- }
- } else {
- retval = xd_erase_block(chip, i);
- if (retval == STATUS_SUCCESS)
- xd_set_unused_block(chip, i);
- }
- }
-
- if (XD_CHK_4MB(xd_card))
- end = 500;
- else
- end = 1000;
-
- i = 0;
- for (start = 0; start < end; start++) {
- if (zone->l2p_table[start] == 0xFFFF)
- i++;
- }
-
- RTSX_DEBUGP("Block count %d, invalid L2P entry %d\n", end, i);
- RTSX_DEBUGP("Total unused block: %d\n", zone->unused_blk_cnt);
-
- if ((zone->unused_blk_cnt - i) < 1)
- chip->card_wp |= XD_CARD;
-
- zone->build_flag = 1;
-
- return STATUS_SUCCESS;
-
-Build_Fail:
- if (zone->l2p_table) {
- vfree(zone->l2p_table);
- zone->l2p_table = NULL;
- }
- if (zone->free_table) {
- vfree(zone->free_table);
- zone->free_table = NULL;
- }
-
- return STATUS_FAIL;
-}
-
-static int xd_send_cmd(struct rtsx_chip *chip, u8 cmd)
-{
- int retval;
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, cmd);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_SET_CMD);
- rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END);
-
- retval = rtsx_send_cmd(chip, XD_CARD, 200);
- if (retval < 0)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
-
-static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk, u32 log_blk,
- u8 start_page, u8 end_page, u8 *buf, unsigned int *index, unsigned int *offset)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- u32 page_addr, new_blk;
- u16 log_off;
- u8 reg_val, page_cnt;
- int zone_no, retval, i;
-
- if (start_page > end_page)
- TRACE_RET(chip, STATUS_FAIL);
-
- page_cnt = end_page - start_page;
- zone_no = (int)(log_blk / 1000);
- log_off = (u16)(log_blk % 1000);
-
- if ((phy_blk & 0x3FF) == 0x3FF) {
- for (i = 0; i < 256; i++) {
- page_addr = ((u32)i) << xd_card->block_shift;
-
- retval = xd_read_redundant(chip, page_addr, NULL, 0);
- if (retval == STATUS_SUCCESS)
- break;
-
- if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
- xd_set_err_code(chip, XD_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
- }
-
- page_addr = (phy_blk << xd_card->block_shift) + start_page;
-
- rtsx_init_cmd(chip);
-
- xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_PPB_TO_SIE, XD_PPB_TO_SIE);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS,
- XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS);
-
- trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512, DMA_512);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_PAGES);
- rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
- XD_TRANSFER_END | XD_PPB_EMPTY, XD_TRANSFER_END | XD_PPB_EMPTY);
-
- rtsx_send_cmd_no_wait(chip);
-
- retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512, scsi_sg_count(chip->srb),
- index, offset, DMA_FROM_DEVICE, chip->xd_timeout);
- if (retval < 0) {
- rtsx_clear_xd_error(chip);
- xd_clear_dma_buffer(chip);
-
- if (retval == -ETIMEDOUT) {
- xd_set_err_code(chip, XD_TO_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- TRACE_GOTO(chip, Fail);
- }
- }
-
- return STATUS_SUCCESS;
-
-Fail:
- RTSX_READ_REG(chip, XD_PAGE_STATUS, &reg_val);
-
- if (reg_val != XD_GPG)
- xd_set_err_code(chip, XD_PRG_ERROR);
-
- RTSX_READ_REG(chip, XD_CTL, &reg_val);
-
- if (((reg_val & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE))
- == (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE))
- || ((reg_val & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))
- == (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) {
- wait_timeout(100);
-
- if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
- xd_set_err_code(chip, XD_NO_CARD);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- xd_set_err_code(chip, XD_ECC_ERROR);
-
- new_blk = xd_get_unused_block(chip, zone_no);
- if (new_blk == NO_NEW_BLK) {
- XD_CLR_BAD_OLDBLK(xd_card);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = xd_copy_page(chip, phy_blk, new_blk, 0, xd_card->page_off + 1);
- if (retval != STATUS_SUCCESS) {
- if (!XD_CHK_BAD_NEWBLK(xd_card)) {
- retval = xd_erase_block(chip, new_blk);
- if (retval == STATUS_SUCCESS)
- xd_set_unused_block(chip, new_blk);
- } else {
- XD_CLR_BAD_NEWBLK(xd_card);
- }
- XD_CLR_BAD_OLDBLK(xd_card);
- TRACE_RET(chip, STATUS_FAIL);
- }
- xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF));
- xd_erase_block(chip, phy_blk);
- xd_mark_bad_block(chip, phy_blk);
- XD_CLR_BAD_OLDBLK(xd_card);
- }
-
- TRACE_RET(chip, STATUS_FAIL);
-}
-
-static int xd_finish_write(struct rtsx_chip *chip,
- u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- int retval, zone_no;
- u16 log_off;
-
- RTSX_DEBUGP("xd_finish_write, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n",
- old_blk, new_blk, log_blk);
-
- if (page_off > xd_card->page_off)
- TRACE_RET(chip, STATUS_FAIL);
-
- zone_no = (int)(log_blk / 1000);
- log_off = (u16)(log_blk % 1000);
-
- if (old_blk == BLK_NOT_FOUND) {
- retval = xd_init_page(chip, new_blk, log_off,
- page_off, xd_card->page_off + 1);
- if (retval != STATUS_SUCCESS) {
- retval = xd_erase_block(chip, new_blk);
- if (retval == STATUS_SUCCESS)
- xd_set_unused_block(chip, new_blk);
- TRACE_RET(chip, STATUS_FAIL);
- }
- } else {
- retval = xd_copy_page(chip, old_blk, new_blk,
- page_off, xd_card->page_off + 1);
- if (retval != STATUS_SUCCESS) {
- if (!XD_CHK_BAD_NEWBLK(xd_card)) {
- retval = xd_erase_block(chip, new_blk);
- if (retval == STATUS_SUCCESS)
- xd_set_unused_block(chip, new_blk);
- }
- XD_CLR_BAD_NEWBLK(xd_card);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = xd_erase_block(chip, old_blk);
- if (retval == STATUS_SUCCESS) {
- if (XD_CHK_BAD_OLDBLK(xd_card)) {
- xd_mark_bad_block(chip, old_blk);
- XD_CLR_BAD_OLDBLK(xd_card);
- } else {
- xd_set_unused_block(chip, old_blk);
- }
- } else {
- xd_set_err_code(chip, XD_NO_ERROR);
- XD_CLR_BAD_OLDBLK(xd_card);
- }
- }
-
- xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF));
-
- return STATUS_SUCCESS;
-}
-
-static int xd_prepare_write(struct rtsx_chip *chip,
- u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off)
-{
- int retval;
-
- RTSX_DEBUGP("%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x, page_off = %d\n",
- __func__, old_blk, new_blk, log_blk, (int)page_off);
-
- if (page_off) {
- retval = xd_copy_page(chip, old_blk, new_blk, 0, page_off);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk, u32 new_blk, u32 log_blk,
- u8 start_page, u8 end_page, u8 *buf, unsigned int *index, unsigned int *offset)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- u32 page_addr;
- int zone_no, retval;
- u16 log_off;
- u8 page_cnt, reg_val;
-
- RTSX_DEBUGP("%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n",
- __func__, old_blk, new_blk, log_blk);
-
- if (start_page > end_page)
- TRACE_RET(chip, STATUS_FAIL);
-
- page_cnt = end_page - start_page;
- zone_no = (int)(log_blk / 1000);
- log_off = (u16)(log_blk % 1000);
-
- page_addr = (new_blk << xd_card->block_shift) + start_page;
-
- retval = xd_send_cmd(chip, READ1_1);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- rtsx_init_cmd(chip);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, (u8)(log_off >> 8));
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)log_off);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_GBLK);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG);
-
- xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM, XD_BA_TRANSFORM);
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt);
- rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
-
- trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512, DMA_512);
-
- rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_WRITE_PAGES);
- rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END);
-
- rtsx_send_cmd_no_wait(chip);
-
- retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512, scsi_sg_count(chip->srb),
- index, offset, DMA_TO_DEVICE, chip->xd_timeout);
- if (retval < 0) {
- rtsx_clear_xd_error(chip);
-
- if (retval == -ETIMEDOUT) {
- xd_set_err_code(chip, XD_TO_ERROR);
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- TRACE_GOTO(chip, Fail);
- }
- }
-
- if (end_page == (xd_card->page_off + 1)) {
- xd_card->delay_write.delay_write_flag = 0;
-
- if (old_blk != BLK_NOT_FOUND) {
- retval = xd_erase_block(chip, old_blk);
- if (retval == STATUS_SUCCESS) {
- if (XD_CHK_BAD_OLDBLK(xd_card)) {
- xd_mark_bad_block(chip, old_blk);
- XD_CLR_BAD_OLDBLK(xd_card);
- } else {
- xd_set_unused_block(chip, old_blk);
- }
- } else {
- xd_set_err_code(chip, XD_NO_ERROR);
- XD_CLR_BAD_OLDBLK(xd_card);
- }
- }
- xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF));
- }
-
- return STATUS_SUCCESS;
-
-Fail:
- RTSX_READ_REG(chip, XD_DAT, &reg_val);
- if (reg_val & PROGRAM_ERROR) {
- xd_set_err_code(chip, XD_PRG_ERROR);
- xd_mark_bad_block(chip, new_blk);
- }
-
- TRACE_RET(chip, STATUS_FAIL);
-}
-
-#ifdef XD_DELAY_WRITE
-int xd_delay_write(struct rtsx_chip *chip)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- struct xd_delay_write_tag *delay_write = &(xd_card->delay_write);
- int retval;
-
- if (delay_write->delay_write_flag) {
- RTSX_DEBUGP("xd_delay_write\n");
- retval = xd_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- delay_write->delay_write_flag = 0;
- retval = xd_finish_write(chip,
- delay_write->old_phyblock, delay_write->new_phyblock,
- delay_write->logblock, delay_write->pageoff);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- return STATUS_SUCCESS;
-}
-#endif
-
-int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- unsigned int lun = SCSI_LUN(srb);
-#ifdef XD_DELAY_WRITE
- struct xd_delay_write_tag *delay_write = &(xd_card->delay_write);
-#endif
- int retval, zone_no;
- unsigned int index = 0, offset = 0;
- u32 log_blk, old_blk = 0, new_blk = 0;
- u16 log_off, total_sec_cnt = sector_cnt;
- u8 start_page, end_page = 0, page_cnt;
- u8 *ptr;
-
- xd_set_err_code(chip, XD_NO_ERROR);
-
- xd_card->cleanup_counter = 0;
-
- RTSX_DEBUGP("xd_rw: scsi_sg_count = %d\n", scsi_sg_count(srb));
-
- ptr = (u8 *)scsi_sglist(srb);
-
- retval = xd_switch_clock(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
-
- if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
- chip->card_fail |= XD_CARD;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- log_blk = start_sector >> xd_card->block_shift;
- start_page = (u8)start_sector & xd_card->page_off;
- zone_no = (int)(log_blk / 1000);
- log_off = (u16)(log_blk % 1000);
-
- if (xd_card->zone[zone_no].build_flag == 0) {
- retval = xd_build_l2p_tbl(chip, zone_no);
- if (retval != STATUS_SUCCESS) {
- chip->card_fail |= XD_CARD;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- if (srb->sc_data_direction == DMA_TO_DEVICE) {
-#ifdef XD_DELAY_WRITE
- if (delay_write->delay_write_flag &&
- (delay_write->logblock == log_blk) &&
- (start_page > delay_write->pageoff)) {
- delay_write->delay_write_flag = 0;
- if (delay_write->old_phyblock != BLK_NOT_FOUND) {
- retval = xd_copy_page(chip,
- delay_write->old_phyblock,
- delay_write->new_phyblock,
- delay_write->pageoff, start_page);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
- old_blk = delay_write->old_phyblock;
- new_blk = delay_write->new_phyblock;
- } else if (delay_write->delay_write_flag &&
- (delay_write->logblock == log_blk) &&
- (start_page == delay_write->pageoff)) {
- delay_write->delay_write_flag = 0;
- old_blk = delay_write->old_phyblock;
- new_blk = delay_write->new_phyblock;
- } else {
- retval = xd_delay_write(chip);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-#endif
- old_blk = xd_get_l2p_tbl(chip, zone_no, log_off);
- new_blk = xd_get_unused_block(chip, zone_no);
- if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = xd_prepare_write(chip, old_blk, new_blk, log_blk, start_page);
- if (retval != STATUS_SUCCESS) {
- if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, STATUS_FAIL);
- }
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-#ifdef XD_DELAY_WRITE
- }
-#endif
- } else {
-#ifdef XD_DELAY_WRITE
- retval = xd_delay_write(chip);
- if (retval != STATUS_SUCCESS) {
- if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, STATUS_FAIL);
- }
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-#endif
-
- old_blk = xd_get_l2p_tbl(chip, zone_no, log_off);
- if (old_blk == BLK_NOT_FOUND) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- RTSX_DEBUGP("old_blk = 0x%x\n", old_blk);
-
- while (total_sec_cnt) {
- if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
- chip->card_fail |= XD_CARD;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if ((start_page + total_sec_cnt) > (xd_card->page_off + 1))
- end_page = xd_card->page_off + 1;
- else
- end_page = start_page + (u8)total_sec_cnt;
-
- page_cnt = end_page - start_page;
- if (srb->sc_data_direction == DMA_FROM_DEVICE) {
- retval = xd_read_multiple_pages(chip, old_blk, log_blk,
- start_page, end_page, ptr, &index, &offset);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- } else {
- retval = xd_write_multiple_pages(chip, old_blk, new_blk, log_blk,
- start_page, end_page, ptr, &index, &offset);
- if (retval != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- total_sec_cnt -= page_cnt;
- if (scsi_sg_count(srb) == 0)
- ptr += page_cnt * 512;
-
- if (total_sec_cnt == 0)
- break;
-
- log_blk++;
- zone_no = (int)(log_blk / 1000);
- log_off = (u16)(log_blk % 1000);
-
- if (xd_card->zone[zone_no].build_flag == 0) {
- retval = xd_build_l2p_tbl(chip, zone_no);
- if (retval != STATUS_SUCCESS) {
- chip->card_fail |= XD_CARD;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- old_blk = xd_get_l2p_tbl(chip, zone_no, log_off);
- if (old_blk == BLK_NOT_FOUND) {
- if (srb->sc_data_direction == DMA_FROM_DEVICE)
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
- else
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
-
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- if (srb->sc_data_direction == DMA_TO_DEVICE) {
- new_blk = xd_get_unused_block(chip, zone_no);
- if (new_blk == BLK_NOT_FOUND) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
- }
-
- start_page = 0;
- }
-
- if ((srb->sc_data_direction == DMA_TO_DEVICE) &&
- (end_page != (xd_card->page_off + 1))) {
-#ifdef XD_DELAY_WRITE
- delay_write->delay_write_flag = 1;
- delay_write->old_phyblock = old_blk;
- delay_write->new_phyblock = new_blk;
- delay_write->logblock = log_blk;
- delay_write->pageoff = end_page;
-#else
- if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
- chip->card_fail |= XD_CARD;
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, STATUS_FAIL);
- }
-
- retval = xd_finish_write(chip, old_blk, new_blk, log_blk, end_page);
- if (retval != STATUS_SUCCESS) {
- if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
- TRACE_RET(chip, STATUS_FAIL);
- }
- set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
- TRACE_RET(chip, STATUS_FAIL);
- }
-#endif
- }
-
- scsi_set_resid(srb, 0);
-
- return STATUS_SUCCESS;
-}
-
-void xd_free_l2p_tbl(struct rtsx_chip *chip)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- int i = 0;
-
- if (xd_card->zone != NULL) {
- for (i = 0; i < xd_card->zone_cnt; i++) {
- if (xd_card->zone[i].l2p_table != NULL) {
- vfree(xd_card->zone[i].l2p_table);
- xd_card->zone[i].l2p_table = NULL;
- }
- if (xd_card->zone[i].free_table != NULL) {
- vfree(xd_card->zone[i].free_table);
- xd_card->zone[i].free_table = NULL;
- }
- }
- vfree(xd_card->zone);
- xd_card->zone = NULL;
- }
-}
-
-void xd_cleanup_work(struct rtsx_chip *chip)
-{
-#ifdef XD_DELAY_WRITE
- struct xd_info *xd_card = &(chip->xd_card);
-
- if (xd_card->delay_write.delay_write_flag) {
- RTSX_DEBUGP("xD: delay write\n");
- xd_delay_write(chip);
- xd_card->cleanup_counter = 0;
- }
-#endif
-}
-
-int xd_power_off_card3v3(struct rtsx_chip *chip)
-{
- int retval;
-
- retval = disable_card_clock(chip, XD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- RTSX_WRITE_REG(chip, CARD_OE, XD_OUTPUT_EN, 0);
-
- if (!chip->ft2_fast_mode) {
- retval = card_power_off(chip, XD_CARD);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- wait_timeout(50);
- }
-
- if (chip->asic_code) {
- retval = xd_pull_ctl_disable(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
- } else {
- RTSX_WRITE_REG(chip, FPGA_PULL_CTL, 0xFF, 0xDF);
- }
-
- return STATUS_SUCCESS;
-}
-
-int release_xd_card(struct rtsx_chip *chip)
-{
- struct xd_info *xd_card = &(chip->xd_card);
- int retval;
-
- RTSX_DEBUGP("release_xd_card\n");
-
- chip->card_ready &= ~XD_CARD;
- chip->card_fail &= ~XD_CARD;
- chip->card_wp &= ~XD_CARD;
-
- xd_card->delay_write.delay_write_flag = 0;
-
- xd_free_l2p_tbl(chip);
-
- retval = xd_power_off_card3v3(chip);
- if (retval != STATUS_SUCCESS)
- TRACE_RET(chip, STATUS_FAIL);
-
- return STATUS_SUCCESS;
-}
diff --git a/drivers/staging/rts_pstor/xd.h b/drivers/staging/rts_pstor/xd.h
deleted file mode 100644
index cd9fbc1f96d..00000000000
--- a/drivers/staging/rts_pstor/xd.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- * Header file
- *
- * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author:
- * wwang (wei_wang@realsil.com.cn)
- * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
- */
-
-#ifndef __REALTEK_RTSX_XD_H
-#define __REALTEK_RTSX_XD_H
-
-#define XD_DELAY_WRITE
-
-/* Error Codes */
-#define XD_NO_ERROR 0x00
-#define XD_NO_MEMORY 0x80
-#define XD_PRG_ERROR 0x40
-#define XD_NO_CARD 0x20
-#define XD_READ_FAIL 0x10
-#define XD_ERASE_FAIL 0x08
-#define XD_WRITE_FAIL 0x04
-#define XD_ECC_ERROR 0x02
-#define XD_TO_ERROR 0x01
-
-/* XD Commands */
-#define READ1_1 0x00
-#define READ1_2 0x01
-#define READ2 0x50
-#define READ_ID 0x90
-#define RESET 0xff
-#define PAGE_PRG_1 0x80
-#define PAGE_PRG_2 0x10
-#define BLK_ERASE_1 0x60
-#define BLK_ERASE_2 0xD0
-#define READ_STS 0x70
-#define READ_xD_ID 0x9A
-#define COPY_BACK_512 0x8A
-#define COPY_BACK_2K 0x85
-#define READ1_1_2 0x30
-#define READ1_1_3 0x35
-#define CHG_DAT_OUT_1 0x05
-#define RDM_DAT_OUT_1 0x05
-#define CHG_DAT_OUT_2 0xE0
-#define RDM_DAT_OUT_2 0xE0
-#define CHG_DAT_OUT_2 0xE0
-#define CHG_DAT_IN_1 0x85
-#define CACHE_PRG 0x15
-
-/* Redundant Area Related */
-#define XD_EXTRA_SIZE 0x10
-#define XD_2K_EXTRA_SIZE 0x40
-
-#define NOT_WRITE_PROTECTED 0x80
-#define READY_STATE 0x40
-#define PROGRAM_ERROR 0x01
-#define PROGRAM_ERROR_N_1 0x02
-#define INTERNAL_READY 0x20
-#define READY_FLAG 0x5F
-
-#define XD_8M_X8_512 0xE6
-#define XD_16M_X8_512 0x73
-#define XD_32M_X8_512 0x75
-#define XD_64M_X8_512 0x76
-#define XD_128M_X8_512 0x79
-#define XD_256M_X8_512 0x71
-#define XD_128M_X8_2048 0xF1
-#define XD_256M_X8_2048 0xDA
-#define XD_512M_X8 0xDC
-#define XD_128M_X16_2048 0xC1
-#define XD_4M_X8_512_1 0xE3
-#define XD_4M_X8_512_2 0xE5
-#define xD_1G_X8_512 0xD3
-#define xD_2G_X8_512 0xD5
-
-#define XD_ID_CODE 0xB5
-
-#define VENDOR_BLOCK 0xEFFF
-#define CIS_BLOCK 0xDFFF
-
-#define BLK_NOT_FOUND 0xFFFFFFFF
-
-#define NO_NEW_BLK 0xFFFFFFFF
-
-#define PAGE_CORRECTABLE 0x0
-#define PAGE_NOTCORRECTABLE 0x1
-
-#define NO_OFFSET 0x0
-#define WITH_OFFSET 0x1
-
-#define Sect_Per_Page 4
-#define XD_ADDR_MODE_2C XD_ADDR_MODE_2A
-
-#define ZONE0_BAD_BLOCK 23
-#define NOT_ZONE0_BAD_BLOCK 24
-
-#define XD_RW_ADDR 0x01
-#define XD_ERASE_ADDR 0x02
-
-#define XD_PAGE_512(xd_card) \
-do { \
- (xd_card)->block_shift = 5; \
- (xd_card)->page_off = 0x1F; \
-} while (0)
-
-#define XD_SET_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag |= 0x01)
-#define XD_CLR_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag &= ~0x01)
-#define XD_CHK_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag & 0x01)
-
-#define XD_SET_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag |= 0x02)
-#define XD_CLR_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag &= ~0x02)
-#define XD_CHK_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag & 0x02)
-
-#define XD_SET_MBR_FAIL(xd_card) ((xd_card)->multi_flag |= 0x04)
-#define XD_CLR_MBR_FAIL(xd_card) ((xd_card)->multi_flag &= ~0x04)
-#define XD_CHK_MBR_FAIL(xd_card) ((xd_card)->multi_flag & 0x04)
-
-#define XD_SET_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag |= 0x08)
-#define XD_CLR_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag &= ~0x08)
-#define XD_CHK_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag & 0x08)
-
-#define XD_SET_4MB(xd_card) ((xd_card)->multi_flag |= 0x10)
-#define XD_CLR_4MB(xd_card) ((xd_card)->multi_flag &= ~0x10)
-#define XD_CHK_4MB(xd_card) ((xd_card)->multi_flag & 0x10)
-
-#define XD_SET_ECC_ERR(xd_card) ((xd_card)->multi_flag |= 0x40)
-#define XD_CLR_ECC_ERR(xd_card) ((xd_card)->multi_flag &= ~0x40)
-#define XD_CHK_ECC_ERR(xd_card) ((xd_card)->multi_flag & 0x40)
-
-#define PAGE_STATUS 0
-#define BLOCK_STATUS 1
-#define BLOCK_ADDR1_L 2
-#define BLOCK_ADDR1_H 3
-#define BLOCK_ADDR2_L 4
-#define BLOCK_ADDR2_H 5
-#define RESERVED0 6
-#define RESERVED1 7
-#define RESERVED2 8
-#define RESERVED3 9
-#define PARITY 10
-
-#define CIS0_0 0
-#define CIS0_1 1
-#define CIS0_2 2
-#define CIS0_3 3
-#define CIS0_4 4
-#define CIS0_5 5
-#define CIS0_6 6
-#define CIS0_7 7
-#define CIS0_8 8
-#define CIS0_9 9
-#define CIS1_0 256
-#define CIS1_1 (256 + 1)
-#define CIS1_2 (256 + 2)
-#define CIS1_3 (256 + 3)
-#define CIS1_4 (256 + 4)
-#define CIS1_5 (256 + 5)
-#define CIS1_6 (256 + 6)
-#define CIS1_7 (256 + 7)
-#define CIS1_8 (256 + 8)
-#define CIS1_9 (256 + 9)
-
-int reset_xd_card(struct rtsx_chip *chip);
-#ifdef XD_DELAY_WRITE
-int xd_delay_write(struct rtsx_chip *chip);
-#endif
-int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt);
-void xd_free_l2p_tbl(struct rtsx_chip *chip);
-void xd_cleanup_work(struct rtsx_chip *chip);
-int xd_power_off_card3v3(struct rtsx_chip *chip);
-int release_xd_card(struct rtsx_chip *chip);
-
-#endif /* __REALTEK_RTSX_XD_H */
-
diff --git a/drivers/staging/sb105x/Kconfig b/drivers/staging/sb105x/Kconfig
new file mode 100644
index 00000000000..ac87c5e38de
--- /dev/null
+++ b/drivers/staging/sb105x/Kconfig
@@ -0,0 +1,9 @@
+config SB105X
+ tristate "SystemBase PCI Multiport UART"
+ select SERIAL_CORE
+ depends on PCI
+ help
+ A driver for the SystemBase Multi-2/PCI serial card
+
+ To compile this driver a module, choose M here: the module
+ will be called "sb105x".
diff --git a/drivers/staging/sb105x/Makefile b/drivers/staging/sb105x/Makefile
new file mode 100644
index 00000000000..b1bf3779aca
--- /dev/null
+++ b/drivers/staging/sb105x/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SB105X) += sb105x.o
+
+sb105x-y := sb_pci_mp.o
diff --git a/drivers/staging/sb105x/sb_mp_register.h b/drivers/staging/sb105x/sb_mp_register.h
new file mode 100644
index 00000000000..5480ae11368
--- /dev/null
+++ b/drivers/staging/sb105x/sb_mp_register.h
@@ -0,0 +1,295 @@
+
+/*
+ * SB105X_UART.h
+ *
+ * Copyright (C) 2008 systembase
+ *
+ * UART registers.
+ *
+ * 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 UART_SB105X_H
+#define UART_SB105X_H
+
+/*
+ * option register
+ */
+
+/* Device Infomation Register */
+#define MP_OPTR_DIR0 0x04 /* port0 ~ port8 */
+#define MP_OPTR_DIR1 0x05 /* port8 ~ port15 */
+#define MP_OPTR_DIR2 0x06 /* port16 ~ port23 */
+#define MP_OPTR_DIR3 0x07 /* port24 ~ port31 */
+
+#define DIR_UART_16C550 0
+#define DIR_UART_16C1050 1
+#define DIR_UART_16C1050A 2
+
+#define DIR_CLK_1843200 0x0 /* input clock 1843200 Hz */
+#define DIR_CLK_3686400 0x1 /* input clock 3686400 Hz */
+#define DIR_CLK_7372800 0x2 /* input clock 7372800 Hz */
+#define DIR_CLK_14745600 0x3 /* input clock 14745600 Hz */
+#define DIR_CLK_29491200 0x4 /* input clock 29491200 Hz */
+#define DIR_CLK_58985400 0x5 /* input clock 58985400 Hz */
+
+/* Interface Information Register */
+#define MP_OPTR_IIR0 0x08 /* port0 ~ port8 */
+#define MP_OPTR_IIR1 0x09 /* port8 ~ port15 */
+#define MP_OPTR_IIR2 0x0A /* port16 ~ port23 */
+#define MP_OPTR_IIR3 0x0B /* port24 ~ port31 */
+
+#define IIR_RS232 0x00 /* RS232 type */
+#define IIR_RS422 0x10 /* RS422 type */
+#define IIR_RS485 0x20 /* RS485 type */
+#define IIR_UNKNOWN 0x30 /* unknown type */
+
+/* Interrrupt Mask Register */
+#define MP_OPTR_IMR0 0x0C /* port0 ~ port8 */
+#define MP_OPTR_IMR1 0x0D /* port8 ~ port15 */
+#define MP_OPTR_IMR2 0x0E /* port16 ~ port23 */
+#define MP_OPTR_IMR3 0x0F /* port24 ~ port31 */
+
+/* Interrupt Poll Register */
+#define MP_OPTR_IPR0 0x10 /* port0 ~ port8 */
+#define MP_OPTR_IPR1 0x11 /* port8 ~ port15 */
+#define MP_OPTR_IPR2 0x12 /* port16 ~ port23 */
+#define MP_OPTR_IPR3 0x13 /* port24 ~ port31 */
+
+/* General Purpose Output Control Register */
+#define MP_OPTR_GPOCR 0x20
+
+/* General Purpose Output Data Register */
+#define MP_OPTR_GPODR 0x21
+
+/* Parallel Additional Function Register */
+#define MP_OPTR_PAFR 0x23
+
+/*
+ * systembase 16c105x UART register
+ */
+
+#define PAGE_0 0
+#define PAGE_1 1
+#define PAGE_2 2
+#define PAGE_3 3
+#define PAGE_4 4
+
+/*
+ * ******************************************************************
+ * * DLAB=0 =============== Page 0 Registers *
+ * ******************************************************************
+ */
+
+#define SB105X_RX 0 /* In: Receive buffer */
+#define SB105X_TX 0 /* Out: Transmit buffer */
+
+#define SB105X_IER 1 /* Out: Interrupt Enable Register */
+
+#define SB105X_IER_CTSI 0x80 /* CTS# Interrupt Enable (Requires EFR[4] = 1) */
+#define SB105X_IER_RTSI 0x40 /* RTS# Interrupt Enable (Requires EFR[4] = 1) */
+#define SB105X_IER_XOI 0x20 /* Xoff Interrupt Enable (Requires EFR[4] = 1) */
+#define SB105X_IER_SME 0x10 /* Sleep Mode Enable (Requires EFR[4] = 1) */
+#define SB105X_IER_MSI 0x08 /* Enable Modem status interrupt */
+#define SB105X_IER_RLSI 0x04 /* Enable receiver line status interrupt */
+#define SB105X_IER_THRI 0x02 /* Enable Transmitter holding register int. */
+#define SB105X_IER_RDI 0x01 /* Enable receiver data interrupt */
+
+#define SB105X_ISR 2 /* In: Interrupt ID Register */
+
+#define SB105X_ISR_NOINT 0x01 /* No interrupts pending */
+#define SB105X_ISR_RLSI 0x06 /* Receiver line status interrupt (Priority = 1)*/
+#define SB105X_ISR_RDAI 0x0c /* Receive Data Available interrupt */
+#define SB105X_ISR_CTII 0x04 /* Character Timeout Indication interrupt */
+#define SB105X_ISR_THRI 0x02 /* Transmitter holding register empty */
+#define SB105X_ISR_MSI 0x00 /* Modem status interrupt */
+#define SB105X_ISR_RXCI 0x10 /* Receive Xoff or Special Character interrupt */
+#define SB105X_ISR_RCSI 0x20 /* RTS#, CTS# status interrupt during Auto RTS/CTS flow control */
+
+#define SB105X_FCR 2 /* Out: FIFO Control Register */
+
+#define SB105X_FCR_FEN 0x01 /* FIFO Enable */
+#define SB105X_FCR_RXFR 0x02 /* RX FIFO Reset */
+#define SB105X_FCR_TXFR 0x04 /* TX FIFO Reset */
+#define SB105X_FCR_DMS 0x08 /* DMA Mode Select */
+
+#define SB105X_FCR_RTR08 0x00 /* Receice Trigger Level set at 8 */
+#define SB105X_FCR_RTR16 0x40 /* Receice Trigger Level set at 16 */
+#define SB105X_FCR_RTR56 0x80 /* Receice Trigger Level set at 56 */
+#define SB105X_FCR_RTR60 0xc0 /* Receice Trigger Level set at 60 */
+#define SB105X_FCR_TTR08 0x00 /* Transmit Trigger Level set at 8 */
+#define SB105X_FCR_TTR16 0x10 /* Transmit Trigger Level set at 16 */
+#define SB105X_FCR_TTR32 0x20 /* Transmit Trigger Level set at 32 */
+#define SB105X_FCR_TTR56 0x30 /* Transmit Trigger Level set at 56 */
+
+#define SB105X_LCR 3 /* Out: Line Control Register */
+/*
+ * * Note: if the word length is 5 bits (SB105X_LCR_WLEN5), then setting
+ * * SB105X_LCR_STOP will select 1.5 stop bits, not 2 stop bits.
+ */
+#define SB105X_LCR_DLAB 0x80 /* Divisor Latch Enable */
+#define SB105X_LCR_SBC 0x40 /* Break Enable*/
+#define SB105X_LCR_SPAR 0x20 /* Set Stick parity */
+#define SB105X_LCR_EPAR 0x10 /* Even parity select */
+#define SB105X_LCR_PAREN 0x08 /* Parity Enable */
+#define SB105X_LCR_STOP 0x04 /* Stop bits: 0->1 bit, 1->2 bits, 1 and SB105X_LCR_WLEN5 -> 1.5 bit */
+#define SB105X_LCR_WLEN5 0x00 /* Wordlength: 5 bits */
+#define SB105X_LCR_WLEN6 0x01 /* Wordlength: 6 bits */
+#define SB105X_LCR_WLEN7 0x02 /* Wordlength: 7 bits */
+#define SB105X_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
+
+#define SB105X_LCR_BF 0xBF
+
+#define SB105X_MCR 4 /* Out: Modem Control Register */
+#define SB105X_MCR_CPS 0x80 /* Clock Prescaler Select */
+#define SB105X_MCR_P2S 0x40 /* Page 2 Select /Xoff Re-Transmit Access Enable */
+#define SB105X_MCR_XOA 0x20 /* Xon Any Enable */
+#define SB105X_MCR_ILB 0x10 /* Internal Loopback Enable */
+#define SB105X_MCR_OUT2 0x08 /* Out2/Interrupt Output Enable*/
+#define SB105X_MCR_OUT1 0x04 /* Out1/Interrupt Output Enable */
+#define SB105X_MCR_RTS 0x02 /* RTS# Output */
+#define SB105X_MCR_DTR 0x01 /* DTR# Output */
+
+#define SB105X_LSR 5 /* In: Line Status Register */
+#define SB105X_LSR_RFEI 0x80 /* Receive FIFO data error Indicator */
+#define SB105X_LSR_TEMI 0x40 /* THR and TSR Empty Indicator */
+#define SB105X_LSR_THRE 0x20 /* THR Empty Indicator */
+#define SB105X_LSR_BII 0x10 /* Break interrupt indicator */
+#define SB105X_LSR_FEI 0x08 /* Frame error indicator */
+#define SB105X_LSR_PEI 0x04 /* Parity error indicator */
+#define SB105X_LSR_OEI 0x02 /* Overrun error indicator */
+#define SB105X_LSR_RDRI 0x01 /* Receive data ready Indicator*/
+
+#define SB105X_MSR 6 /* In: Modem Status Register */
+#define SB105X_MSR_DCD 0x80 /* Data Carrier Detect */
+#define SB105X_MSR_RI 0x40 /* Ring Indicator */
+#define SB105X_MSR_DSR 0x20 /* Data Set Ready */
+#define SB105X_MSR_CTS 0x10 /* Clear to Send */
+#define SB105X_MSR_DDCD 0x08 /* Delta DCD */
+#define SB105X_MSR_DRI 0x04 /* Delta ring indicator */
+#define SB105X_MSR_DDSR 0x02 /* Delta DSR */
+#define SB105X_MSR_DCTS 0x01 /* Delta CTS */
+
+#define SB105XA_MDR 6 /* Out: Multi Drop mode Register */
+#define SB105XA_MDR_NPS 0x08 /* 9th Bit Polarity Select */
+#define SB105XA_MDR_AME 0x02 /* Auto Multi-drop Enable */
+#define SB105XA_MDR_MDE 0x01 /* Multi Drop Enable */
+
+#define SB105X_SPR 7 /* I/O: Scratch Register */
+
+/*
+ * DLAB=1
+ */
+#define SB105X_DLL 0 /* Out: Divisor Latch Low */
+#define SB105X_DLM 1 /* Out: Divisor Latch High */
+
+/*
+ * ******************************************************************
+ * * DLAB(LCR[7]) = 0 , MCR[6] = 1 ============= Page 2 Registers *
+ * ******************************************************************
+ */
+#define SB105X_GICR 1 /* Global Interrupt Control Register */
+#define SB105X_GICR_GIM 0x01 /* Global Interrupt Mask */
+
+#define SB105X_GISR 2 /* Global Interrupt Status Register */
+#define SB105X_GISR_MGICR0 0x80 /* Mirror the content of GICR[0] */
+#define SB105X_GISR_CS3IS 0x08 /* SB105X of CS3# Interrupt Status */
+#define SB105X_GISR_CS2IS 0x04 /* SB105X of CS2# Interrupt Status */
+#define SB105X_GISR_CS1IS 0x02 /* SB105X of CS1# Interrupt Status */
+#define SB105X_GISR_CS0IS 0x01 /* SB105X of CS0# Interrupt Status */
+
+#define SB105X_TFCR 5 /* Transmit FIFO Count Register */
+
+#define SB105X_RFCR 6 /* Receive FIFO Count Register */
+
+#define SB105X_FSR 7 /* Flow Control Status Register */
+#define SB105X_FSR_THFS 0x20 /* Transmit Hardware Flow Control Status */
+#define SB105X_FSR_TSFS 0x10 /* Transmit Software Flow Control Status */
+#define SB105X_FSR_RHFS 0x02 /* Receive Hardware Flow Control Status */
+#define SB105X_FSR_RSFS 0x01 /* Receive Software Flow Control Status */
+
+/*
+ * ******************************************************************
+ * * LCR = 0xBF, PSR[0] = 0 ============= Page 3 Registers *
+ * ******************************************************************
+ */
+
+#define SB105X_PSR 0 /* Page Select Register */
+#define SB105X_PSR_P3KEY 0xA4 /* Page 3 Select Key */
+#define SB105X_PSR_P4KEY 0xA5 /* Page 5 Select Key */
+
+#define SB105X_ATR 1 /* Auto Toggle Control Register */
+#define SB105X_ATR_RPS 0x80 /* RXEN Polarity Select */
+#define SB105X_ATR_RCMS 0x40 /* RXEN Control Mode Select */
+#define SB105X_ATR_TPS 0x20 /* TXEN Polarity Select */
+#define SB105X_ATR_TCMS 0x10 /* TXEN Control Mode Select */
+#define SB105X_ATR_ATDIS 0x00 /* Auto Toggle is disabled */
+#define SB105X_ATR_ART 0x01 /* RTS#/TXEN pin operates as TXEN */
+#define SB105X_ATR_ADT 0x02 /* DTR#/TXEN pin operates as TXEN */
+#define SB105X_ATR_A80 0x03 /* only in 80 pin use */
+
+#define SB105X_EFR 2 /* (Auto) Enhanced Feature Register */
+#define SB105X_EFR_ACTS 0x80 /* Auto-CTS Flow Control Enable */
+#define SB105X_EFR_ARTS 0x40 /* Auto-RTS Flow Control Enable */
+#define SB105X_EFR_SCD 0x20 /* Special Character Detect */
+#define SB105X_EFR_EFBEN 0x10 /* Enhanced Function Bits Enable */
+
+#define SB105X_XON1 4 /* Xon1 Character Register */
+#define SB105X_XON2 5 /* Xon2 Character Register */
+#define SB105X_XOFF1 6 /* Xoff1 Character Register */
+#define SB105X_XOFF2 7 /* Xoff2 Character Register */
+
+/*
+ * ******************************************************************
+ * * LCR = 0xBF, PSR[0] = 1 ============ Page 4 Registers *
+ * ******************************************************************
+ */
+
+#define SB105X_AFR 1 /* Additional Feature Register */
+#define SB105X_AFR_GIPS 0x20 /* Global Interrupt Polarity Select */
+#define SB105X_AFR_GIEN 0x10 /* Global Interrupt Enable */
+#define SB105X_AFR_AFEN 0x01 /* 256-byte FIFO Enable */
+
+#define SB105X_XRCR 2 /* Xoff Re-transmit Count Register */
+#define SB105X_XRCR_NRC1 0x00 /* Transmits Xoff Character whenever the number of received data is 1 during XOFF status */
+#define SB105X_XRCR_NRC4 0x01 /* Transmits Xoff Character whenever the number of received data is 4 during XOFF status */
+#define SB105X_XRCR_NRC8 0x02 /* Transmits Xoff Character whenever the number of received data is 8 during XOFF status */
+#define SB105X_XRCR_NRC16 0x03 /* Transmits Xoff Character whenever the number of received data is 16 during XOFF status */
+
+#define SB105X_TTR 4 /* Transmit FIFO Trigger Level Register */
+#define SB105X_RTR 5 /* Receive FIFO Trigger Level Register */
+#define SB105X_FUR 6 /* Flow Control Upper Threshold Register */
+#define SB105X_FLR 7 /* Flow Control Lower Threshold Register */
+
+
+/* page 0 */
+
+#define SB105X_GET_CHAR(port) inb((port)->iobase + SB105X_RX)
+#define SB105X_GET_IER(port) inb((port)->iobase + SB105X_IER)
+#define SB105X_GET_ISR(port) inb((port)->iobase + SB105X_ISR)
+#define SB105X_GET_LCR(port) inb((port)->iobase + SB105X_LCR)
+#define SB105X_GET_MCR(port) inb((port)->iobase + SB105X_MCR)
+#define SB105X_GET_LSR(port) inb((port)->iobase + SB105X_LSR)
+#define SB105X_GET_MSR(port) inb((port)->iobase + SB105X_MSR)
+#define SB105X_GET_SPR(port) inb((port)->iobase + SB105X_SPR)
+
+#define SB105X_PUT_CHAR(port,v) outb((v),(port)->iobase + SB105X_TX )
+#define SB105X_PUT_IER(port,v) outb((v),(port)->iobase + SB105X_IER )
+#define SB105X_PUT_FCR(port,v) outb((v),(port)->iobase + SB105X_FCR )
+#define SB105X_PUT_LCR(port,v) outb((v),(port)->iobase + SB105X_LCR )
+#define SB105X_PUT_MCR(port,v) outb((v),(port)->iobase + SB105X_MCR )
+#define SB105X_PUT_SPR(port,v) outb((v),(port)->iobase + SB105X_SPR )
+
+
+/* page 1 */
+#define SB105X_GET_REG(port,reg) inb((port)->iobase + (reg))
+#define SB105X_PUT_REG(port,reg,v) outb((v),(port)->iobase + (reg))
+
+/* page 2 */
+
+#define SB105X_PUT_PSR(port,v) outb((v),(port)->iobase + SB105X_PSR )
+
+#endif
diff --git a/drivers/staging/sb105x/sb_pci_mp.c b/drivers/staging/sb105x/sb_pci_mp.c
new file mode 100644
index 00000000000..edb2a85b9d5
--- /dev/null
+++ b/drivers/staging/sb105x/sb_pci_mp.c
@@ -0,0 +1,3196 @@
+#include "sb_pci_mp.h"
+#include <linux/module.h>
+#include <linux/parport.h>
+
+extern struct parport *parport_pc_probe_port(unsigned long base_lo,
+ unsigned long base_hi,
+ int irq, int dma,
+ struct device *dev,
+ int irqflags);
+
+static struct mp_device_t mp_devs[MAX_MP_DEV];
+static int mp_nrpcibrds = sizeof(mp_pciboards)/sizeof(mppcibrd_t);
+static int NR_BOARD=0;
+static int NR_PORTS=0;
+static struct mp_port multi_ports[MAX_MP_PORT];
+static struct irq_info irq_lists[NR_IRQS];
+
+static _INLINE_ unsigned int serial_in(struct mp_port *mtpt, int offset);
+static _INLINE_ void serial_out(struct mp_port *mtpt, int offset, int value);
+static _INLINE_ unsigned int read_option_register(struct mp_port *mtpt, int offset);
+static int sb1054_get_register(struct sb_uart_port * port, int page, int reg);
+static int sb1054_set_register(struct sb_uart_port * port, int page, int reg, int value);
+static void SendATCommand(struct mp_port * mtpt);
+static int set_deep_fifo(struct sb_uart_port * port, int status);
+static int get_deep_fifo(struct sb_uart_port * port);
+static int get_device_type(int arg);
+static int set_auto_rts(struct sb_uart_port *port, int status);
+static void mp_stop(struct tty_struct *tty);
+static void __mp_start(struct tty_struct *tty);
+static void mp_start(struct tty_struct *tty);
+static void mp_tasklet_action(unsigned long data);
+static inline void mp_update_mctrl(struct sb_uart_port *port, unsigned int set, unsigned int clear);
+static int mp_startup(struct sb_uart_state *state, int init_hw);
+static void mp_shutdown(struct sb_uart_state *state);
+static void mp_change_speed(struct sb_uart_state *state, struct MP_TERMIOS *old_termios);
+
+static inline int __mp_put_char(struct sb_uart_port *port, struct circ_buf *circ, unsigned char c);
+static int mp_put_char(struct tty_struct *tty, unsigned char ch);
+
+static void mp_put_chars(struct tty_struct *tty);
+static int mp_write(struct tty_struct *tty, const unsigned char * buf, int count);
+static int mp_write_room(struct tty_struct *tty);
+static int mp_chars_in_buffer(struct tty_struct *tty);
+static void mp_flush_buffer(struct tty_struct *tty);
+static void mp_send_xchar(struct tty_struct *tty, char ch);
+static void mp_throttle(struct tty_struct *tty);
+static void mp_unthrottle(struct tty_struct *tty);
+static int mp_get_info(struct sb_uart_state *state, struct serial_struct *retinfo);
+static int mp_set_info(struct sb_uart_state *state, struct serial_struct *newinfo);
+static int mp_get_lsr_info(struct sb_uart_state *state, unsigned int *value);
+
+static int mp_tiocmget(struct tty_struct *tty);
+static int mp_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear);
+static int mp_break_ctl(struct tty_struct *tty, int break_state);
+static int mp_do_autoconfig(struct sb_uart_state *state);
+static int mp_wait_modem_status(struct sb_uart_state *state, unsigned long arg);
+static int mp_get_count(struct sb_uart_state *state, struct serial_icounter_struct *icnt);
+static int mp_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg);
+static void mp_set_termios(struct tty_struct *tty, struct MP_TERMIOS *old_termios);
+static void mp_close(struct tty_struct *tty, struct file *filp);
+static void mp_wait_until_sent(struct tty_struct *tty, int timeout);
+static void mp_hangup(struct tty_struct *tty);
+static void mp_update_termios(struct sb_uart_state *state);
+static int mp_block_til_ready(struct file *filp, struct sb_uart_state *state);
+static struct sb_uart_state *uart_get(struct uart_driver *drv, int line);
+static int mp_open(struct tty_struct *tty, struct file *filp);
+static const char *mp_type(struct sb_uart_port *port);
+static void mp_change_pm(struct sb_uart_state *state, int pm_state);
+static inline void mp_report_port(struct uart_driver *drv, struct sb_uart_port *port);
+static void mp_configure_port(struct uart_driver *drv, struct sb_uart_state *state, struct sb_uart_port *port);
+static void mp_unconfigure_port(struct uart_driver *drv, struct sb_uart_state *state);
+static int mp_register_driver(struct uart_driver *drv);
+static void mp_unregister_driver(struct uart_driver *drv);
+static int mp_add_one_port(struct uart_driver *drv, struct sb_uart_port *port);
+static int mp_remove_one_port(struct uart_driver *drv, struct sb_uart_port *port);
+static void autoconfig(struct mp_port *mtpt, unsigned int probeflags);
+static void autoconfig_irq(struct mp_port *mtpt);
+static void multi_stop_tx(struct sb_uart_port *port);
+static void multi_start_tx(struct sb_uart_port *port);
+static void multi_stop_rx(struct sb_uart_port *port);
+static void multi_enable_ms(struct sb_uart_port *port);
+static _INLINE_ void receive_chars(struct mp_port *mtpt, int *status );
+static _INLINE_ void transmit_chars(struct mp_port *mtpt);
+static _INLINE_ void check_modem_status(struct mp_port *mtpt);
+static inline void multi_handle_port(struct mp_port *mtpt);
+static irqreturn_t multi_interrupt(int irq, void *dev_id);
+static void serial_do_unlink(struct irq_info *i, struct mp_port *mtpt);
+static int serial_link_irq_chain(struct mp_port *mtpt);
+static void serial_unlink_irq_chain(struct mp_port *mtpt);
+static void multi_timeout(unsigned long data);
+static unsigned int multi_tx_empty(struct sb_uart_port *port);
+static unsigned int multi_get_mctrl(struct sb_uart_port *port);
+static void multi_set_mctrl(struct sb_uart_port *port, unsigned int mctrl);
+static void multi_break_ctl(struct sb_uart_port *port, int break_state);
+static int multi_startup(struct sb_uart_port *port);
+static void multi_shutdown(struct sb_uart_port *port);
+static unsigned int multi_get_divisor(struct sb_uart_port *port, unsigned int baud);
+static void multi_set_termios(struct sb_uart_port *port, struct MP_TERMIOS *termios, struct MP_TERMIOS *old);
+static void multi_pm(struct sb_uart_port *port, unsigned int state, unsigned int oldstate);
+static void multi_release_std_resource(struct mp_port *mtpt);
+static void multi_release_port(struct sb_uart_port *port);
+static int multi_request_port(struct sb_uart_port *port);
+static void multi_config_port(struct sb_uart_port *port, int flags);
+static int multi_verify_port(struct sb_uart_port *port, struct serial_struct *ser);
+static const char * multi_type(struct sb_uart_port *port);
+static void __init multi_init_ports(void);
+static void __init multi_register_ports(struct uart_driver *drv);
+static int init_mp_dev(struct pci_dev *pcidev, mppcibrd_t brd);
+
+static int deep[256];
+static int deep_count;
+static int fcr_arr[256];
+static int fcr_count;
+static int ttr[256];
+static int ttr_count;
+static int rtr[256];
+static int rtr_count;
+
+module_param_array(deep,int,&deep_count,0);
+module_param_array(fcr_arr,int,&fcr_count,0);
+module_param_array(ttr,int,&ttr_count,0);
+module_param_array(rtr,int,&rtr_count,0);
+
+static _INLINE_ unsigned int serial_in(struct mp_port *mtpt, int offset)
+{
+ return inb(mtpt->port.iobase + offset);
+}
+
+static _INLINE_ void serial_out(struct mp_port *mtpt, int offset, int value)
+{
+ outb(value, mtpt->port.iobase + offset);
+}
+
+static _INLINE_ unsigned int read_option_register(struct mp_port *mtpt, int offset)
+{
+ return inb(mtpt->option_base_addr + offset);
+}
+
+static int sb1053a_get_interface(struct mp_port *mtpt, int port_num)
+{
+ unsigned long option_base_addr = mtpt->option_base_addr;
+ unsigned int interface = 0;
+
+ switch (port_num)
+ {
+ case 0:
+ case 1:
+ /* set GPO[1:0] = 00 */
+ outb(0x00, option_base_addr + MP_OPTR_GPODR);
+ break;
+ case 2:
+ case 3:
+ /* set GPO[1:0] = 01 */
+ outb(0x01, option_base_addr + MP_OPTR_GPODR);
+ break;
+ case 4:
+ case 5:
+ /* set GPO[1:0] = 10 */
+ outb(0x02, option_base_addr + MP_OPTR_GPODR);
+ break;
+ default:
+ break;
+ }
+
+ port_num &= 0x1;
+
+ /* get interface */
+ interface = inb(option_base_addr + MP_OPTR_IIR0 + port_num);
+
+ /* set GPO[1:0] = 11 */
+ outb(0x03, option_base_addr + MP_OPTR_GPODR);
+
+ return (interface);
+}
+
+static int sb1054_get_register(struct sb_uart_port * port, int page, int reg)
+{
+ int ret = 0;
+ unsigned int lcr = 0;
+ unsigned int mcr = 0;
+ unsigned int tmp = 0;
+
+ if( page <= 0)
+ {
+ printk(" page 0 can not use this fuction\n");
+ return -1;
+ }
+
+ switch(page)
+ {
+ case 1:
+ lcr = SB105X_GET_LCR(port);
+ tmp = lcr | SB105X_LCR_DLAB;
+ SB105X_PUT_LCR(port, tmp);
+
+ tmp = SB105X_GET_LCR(port);
+
+ ret = SB105X_GET_REG(port,reg);
+ SB105X_PUT_LCR(port,lcr);
+ break;
+ case 2:
+ mcr = SB105X_GET_MCR(port);
+ tmp = mcr | SB105X_MCR_P2S;
+ SB105X_PUT_MCR(port,tmp);
+
+ ret = SB105X_GET_REG(port,reg);
+
+ SB105X_PUT_MCR(port,mcr);
+ break;
+ case 3:
+ lcr = SB105X_GET_LCR(port);
+ tmp = lcr | SB105X_LCR_BF;
+ SB105X_PUT_LCR(port,tmp);
+ SB105X_PUT_REG(port,SB105X_PSR,SB105X_PSR_P3KEY);
+
+ ret = SB105X_GET_REG(port,reg);
+
+ SB105X_PUT_LCR(port,lcr);
+ break;
+ case 4:
+ lcr = SB105X_GET_LCR(port);
+ tmp = lcr | SB105X_LCR_BF;
+ SB105X_PUT_LCR(port,tmp);
+ SB105X_PUT_REG(port,SB105X_PSR,SB105X_PSR_P4KEY);
+
+ ret = SB105X_GET_REG(port,reg);
+
+ SB105X_PUT_LCR(port,lcr);
+ break;
+ default:
+ printk(" error invalid page number \n");
+ return -1;
+ }
+
+ return ret;
+}
+
+static int sb1054_set_register(struct sb_uart_port * port, int page, int reg, int value)
+{
+ int lcr = 0;
+ int mcr = 0;
+ int ret = 0;
+
+ if( page <= 0)
+ {
+ printk(" page 0 can not use this fuction\n");
+ return -1;
+ }
+ switch(page)
+ {
+ case 1:
+ lcr = SB105X_GET_LCR(port);
+ SB105X_PUT_LCR(port, lcr | SB105X_LCR_DLAB);
+
+ SB105X_PUT_REG(port,reg,value);
+
+ SB105X_PUT_LCR(port, lcr);
+ ret = 1;
+ break;
+ case 2:
+ mcr = SB105X_GET_MCR(port);
+ SB105X_PUT_MCR(port, mcr | SB105X_MCR_P2S);
+
+ SB105X_PUT_REG(port,reg,value);
+
+ SB105X_PUT_MCR(port, mcr);
+ ret = 1;
+ break;
+ case 3:
+ lcr = SB105X_GET_LCR(port);
+ SB105X_PUT_LCR(port, lcr | SB105X_LCR_BF);
+ SB105X_PUT_PSR(port, SB105X_PSR_P3KEY);
+
+ SB105X_PUT_REG(port,reg,value);
+
+ SB105X_PUT_LCR(port, lcr);
+ ret = 1;
+ break;
+ case 4:
+ lcr = SB105X_GET_LCR(port);
+ SB105X_PUT_LCR(port, lcr | SB105X_LCR_BF);
+ SB105X_PUT_PSR(port, SB105X_PSR_P4KEY);
+
+ SB105X_PUT_REG(port,reg,value);
+
+ SB105X_PUT_LCR(port, lcr);
+ ret = 1;
+ break;
+ default:
+ printk(" error invalid page number \n");
+ return -1;
+ }
+
+ return ret;
+}
+
+static int set_multidrop_mode(struct sb_uart_port *port, unsigned int mode)
+{
+ int mdr = SB105XA_MDR_NPS;
+
+ if (mode & MDMODE_ENABLE)
+ {
+ mdr |= SB105XA_MDR_MDE;
+ }
+
+ if (1) //(mode & MDMODE_AUTO)
+ {
+ int efr = 0;
+ mdr |= SB105XA_MDR_AME;
+ efr = sb1054_get_register(port, PAGE_3, SB105X_EFR);
+ efr |= SB105X_EFR_SCD;
+ sb1054_set_register(port, PAGE_3, SB105X_EFR, efr);
+ }
+
+ sb1054_set_register(port, PAGE_1, SB105XA_MDR, mdr);
+ port->mdmode &= ~0x6;
+ port->mdmode |= mode;
+ printk("[%d] multidrop init: %x\n", port->line, port->mdmode);
+
+ return 0;
+}
+
+static int get_multidrop_addr(struct sb_uart_port *port)
+{
+ return sb1054_get_register(port, PAGE_3, SB105X_XOFF2);
+}
+
+static int set_multidrop_addr(struct sb_uart_port *port, unsigned int addr)
+{
+ sb1054_set_register(port, PAGE_3, SB105X_XOFF2, addr);
+
+ return 0;
+}
+
+static void SendATCommand(struct mp_port * mtpt)
+{
+ // a t cr lf
+ unsigned char ch[] = {0x61,0x74,0x0d,0x0a,0x0};
+ unsigned char lineControl;
+ unsigned char i=0;
+ unsigned char Divisor = 0xc;
+
+ lineControl = serial_inp(mtpt,UART_LCR);
+ serial_outp(mtpt,UART_LCR,(lineControl | UART_LCR_DLAB));
+ serial_outp(mtpt,UART_DLL,(Divisor & 0xff));
+ serial_outp(mtpt,UART_DLM,(Divisor & 0xff00)>>8); //baudrate is 4800
+
+
+ serial_outp(mtpt,UART_LCR,lineControl);
+ serial_outp(mtpt,UART_LCR,0x03); // N-8-1
+ serial_outp(mtpt,UART_FCR,7);
+ serial_outp(mtpt,UART_MCR,0x3);
+ while(ch[i]){
+ while((serial_inp(mtpt,UART_LSR) & 0x60) !=0x60){
+ ;
+ }
+ serial_outp(mtpt,0,ch[i++]);
+ }
+
+
+}// end of SendATCommand()
+
+static int set_deep_fifo(struct sb_uart_port * port, int status)
+{
+ int afr_status = 0;
+ afr_status = sb1054_get_register(port, PAGE_4, SB105X_AFR);
+
+ if(status == ENABLE)
+ {
+ afr_status |= SB105X_AFR_AFEN;
+ }
+ else
+ {
+ afr_status &= ~SB105X_AFR_AFEN;
+ }
+
+ sb1054_set_register(port,PAGE_4,SB105X_AFR,afr_status);
+ sb1054_set_register(port,PAGE_4,SB105X_TTR,ttr[port->line]);
+ sb1054_set_register(port,PAGE_4,SB105X_RTR,rtr[port->line]);
+ afr_status = sb1054_get_register(port, PAGE_4, SB105X_AFR);
+
+ return afr_status;
+}
+
+static int get_device_type(int arg)
+{
+ int ret;
+ ret = inb(mp_devs[arg].option_reg_addr+MP_OPTR_DIR0);
+ ret = (ret & 0xf0) >> 4;
+ switch (ret)
+ {
+ case DIR_UART_16C550:
+ return PORT_16C55X;
+ case DIR_UART_16C1050:
+ return PORT_16C105X;
+ case DIR_UART_16C1050A:
+ /*
+ if (mtpt->port.line < 2)
+ {
+ return PORT_16C105XA;
+ }
+ else
+ {
+ if (mtpt->device->device_id & 0x50)
+ {
+ return PORT_16C55X;
+ }
+ else
+ {
+ return PORT_16C105X;
+ }
+ }*/
+ return PORT_16C105XA;
+ default:
+ return PORT_UNKNOWN;
+ }
+
+}
+static int get_deep_fifo(struct sb_uart_port * port)
+{
+ int afr_status = 0;
+ afr_status = sb1054_get_register(port, PAGE_4, SB105X_AFR);
+ return afr_status;
+}
+
+static int set_auto_rts(struct sb_uart_port *port, int status)
+{
+ int atr_status = 0;
+
+#if 0
+ int efr_status = 0;
+
+ efr_status = sb1054_get_register(port, PAGE_3, SB105X_EFR);
+ if(status == ENABLE)
+ efr_status |= SB105X_EFR_ARTS;
+ else
+ efr_status &= ~SB105X_EFR_ARTS;
+ sb1054_set_register(port,PAGE_3,SB105X_EFR,efr_status);
+ efr_status = sb1054_get_register(port, PAGE_3, SB105X_EFR);
+#endif
+
+//ATR
+ atr_status = sb1054_get_register(port, PAGE_3, SB105X_ATR);
+ switch(status)
+ {
+ case RS422PTP:
+ atr_status = (SB105X_ATR_TPS) | (SB105X_ATR_A80);
+ break;
+ case RS422MD:
+ atr_status = (SB105X_ATR_TPS) | (SB105X_ATR_TCMS) | (SB105X_ATR_A80);
+ break;
+ case RS485NE:
+ atr_status = (SB105X_ATR_RCMS) | (SB105X_ATR_TPS) | (SB105X_ATR_TCMS) | (SB105X_ATR_A80);
+ break;
+ case RS485ECHO:
+ atr_status = (SB105X_ATR_TPS) | (SB105X_ATR_TCMS) | (SB105X_ATR_A80);
+ break;
+ }
+
+ sb1054_set_register(port,PAGE_3,SB105X_ATR,atr_status);
+ atr_status = sb1054_get_register(port, PAGE_3, SB105X_ATR);
+
+ return atr_status;
+}
+
+static void mp_stop(struct tty_struct *tty)
+{
+ struct sb_uart_state *state = tty->driver_data;
+ struct sb_uart_port *port = state->port;
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+ port->ops->stop_tx(port);
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void __mp_start(struct tty_struct *tty)
+{
+ struct sb_uart_state *state = tty->driver_data;
+ struct sb_uart_port *port = state->port;
+
+ if (!uart_circ_empty(&state->info->xmit) && state->info->xmit.buf &&
+ !tty->stopped && !tty->hw_stopped)
+ port->ops->start_tx(port);
+}
+
+static void mp_start(struct tty_struct *tty)
+{
+ __mp_start(tty);
+}
+
+static void mp_tasklet_action(unsigned long data)
+{
+ struct sb_uart_state *state = (struct sb_uart_state *)data;
+ struct tty_struct *tty;
+
+ printk("tasklet is called!\n");
+ tty = state->info->tty;
+ tty_wakeup(tty);
+}
+
+static inline void mp_update_mctrl(struct sb_uart_port *port, unsigned int set, unsigned int clear)
+{
+ unsigned int old;
+
+ old = port->mctrl;
+ port->mctrl = (old & ~clear) | set;
+ if (old != port->mctrl)
+ port->ops->set_mctrl(port, port->mctrl);
+}
+
+#define uart_set_mctrl(port,set) mp_update_mctrl(port,set,0)
+#define uart_clear_mctrl(port,clear) mp_update_mctrl(port,0,clear)
+
+static int mp_startup(struct sb_uart_state *state, int init_hw)
+{
+ struct sb_uart_info *info = state->info;
+ struct sb_uart_port *port = state->port;
+ unsigned long page;
+ int retval = 0;
+
+ if (info->flags & UIF_INITIALIZED)
+ return 0;
+
+ if (info->tty)
+ set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+ if (port->type == PORT_UNKNOWN)
+ return 0;
+
+ if (!info->xmit.buf) {
+ page = get_zeroed_page(GFP_KERNEL);
+ if (!page)
+ return -ENOMEM;
+
+ info->xmit.buf = (unsigned char *) page;
+
+ uart_circ_clear(&info->xmit);
+ }
+
+ retval = port->ops->startup(port);
+ if (retval == 0) {
+ if (init_hw) {
+ mp_change_speed(state, NULL);
+
+ if (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 (retval && capable(CAP_SYS_ADMIN))
+ retval = 0;
+
+ return retval;
+}
+
+static void mp_shutdown(struct sb_uart_state *state)
+{
+ struct sb_uart_info *info = state->info;
+ struct sb_uart_port *port = state->port;
+
+ if (info->tty)
+ set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+ if (info->flags & UIF_INITIALIZED) {
+ info->flags &= ~UIF_INITIALIZED;
+
+ if (!info->tty || (info->tty->termios.c_cflag & HUPCL))
+ uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+
+ wake_up_interruptible(&info->delta_msr_wait);
+
+ port->ops->shutdown(port);
+
+ synchronize_irq(port->irq);
+ }
+ tasklet_kill(&info->tlet);
+
+ if (info->xmit.buf) {
+ free_page((unsigned long)info->xmit.buf);
+ info->xmit.buf = NULL;
+ }
+}
+
+static void mp_change_speed(struct sb_uart_state *state, struct MP_TERMIOS *old_termios)
+{
+ struct tty_struct *tty = state->info->tty;
+ struct sb_uart_port *port = state->port;
+
+ if (!tty || port->type == PORT_UNKNOWN)
+ return;
+
+ if (tty->termios.c_cflag & CRTSCTS)
+ state->info->flags |= UIF_CTS_FLOW;
+ else
+ state->info->flags &= ~UIF_CTS_FLOW;
+
+ if (tty->termios.c_cflag & CLOCAL)
+ state->info->flags &= ~UIF_CHECK_CD;
+ else
+ state->info->flags |= UIF_CHECK_CD;
+
+ port->ops->set_termios(port, &tty->termios, old_termios);
+}
+
+static inline int __mp_put_char(struct sb_uart_port *port, struct circ_buf *circ, unsigned char c)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ if (!circ->buf)
+ return 0;
+
+ spin_lock_irqsave(&port->lock, flags);
+ if (uart_circ_chars_free(circ) != 0) {
+ circ->buf[circ->head] = c;
+ circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1);
+ ret = 1;
+ }
+ spin_unlock_irqrestore(&port->lock, flags);
+ return ret;
+}
+
+static int mp_put_char(struct tty_struct *tty, unsigned char ch)
+{
+ struct sb_uart_state *state = tty->driver_data;
+
+ return __mp_put_char(state->port, &state->info->xmit, ch);
+}
+
+static void mp_put_chars(struct tty_struct *tty)
+{
+ mp_start(tty);
+}
+
+static int mp_write(struct tty_struct *tty, const unsigned char * buf, int count)
+{
+ struct sb_uart_state *state = tty->driver_data;
+ struct sb_uart_port *port;
+ struct circ_buf *circ;
+ int c, ret = 0;
+
+ if (!state || !state->info) {
+ return -EL3HLT;
+ }
+
+ port = state->port;
+ circ = &state->info->xmit;
+
+ if (!circ->buf)
+ return 0;
+
+ while (1) {
+ c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
+ if (count < c)
+ c = count;
+ if (c <= 0)
+ break;
+ memcpy(circ->buf + circ->head, buf, c);
+
+ circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
+ buf += c;
+ count -= c;
+ ret += c;
+ }
+ mp_start(tty);
+ return ret;
+}
+
+static int mp_write_room(struct tty_struct *tty)
+{
+ struct sb_uart_state *state = tty->driver_data;
+
+ return uart_circ_chars_free(&state->info->xmit);
+}
+
+static int mp_chars_in_buffer(struct tty_struct *tty)
+{
+ struct sb_uart_state *state = tty->driver_data;
+
+ return uart_circ_chars_pending(&state->info->xmit);
+}
+
+static void mp_flush_buffer(struct tty_struct *tty)
+{
+ struct sb_uart_state *state = tty->driver_data;
+ struct sb_uart_port *port;
+ unsigned long flags;
+
+ if (!state || !state->info) {
+ return;
+ }
+
+ port = state->port;
+ spin_lock_irqsave(&port->lock, flags);
+ uart_circ_clear(&state->info->xmit);
+ spin_unlock_irqrestore(&port->lock, flags);
+ wake_up_interruptible(&tty->write_wait);
+ tty_wakeup(tty);
+}
+
+static void mp_send_xchar(struct tty_struct *tty, char ch)
+{
+ struct sb_uart_state *state = tty->driver_data;
+ struct sb_uart_port *port = state->port;
+ unsigned long flags;
+
+ if (port->ops->send_xchar)
+ port->ops->send_xchar(port, ch);
+ else {
+ port->x_char = ch;
+ if (ch) {
+ spin_lock_irqsave(&port->lock, flags);
+ port->ops->start_tx(port);
+ spin_unlock_irqrestore(&port->lock, flags);
+ }
+ }
+}
+
+static void mp_throttle(struct tty_struct *tty)
+{
+ struct sb_uart_state *state = tty->driver_data;
+
+ if (I_IXOFF(tty))
+ mp_send_xchar(tty, STOP_CHAR(tty));
+
+ if (tty->termios.c_cflag & CRTSCTS)
+ uart_clear_mctrl(state->port, TIOCM_RTS);
+}
+
+static void mp_unthrottle(struct tty_struct *tty)
+{
+ struct sb_uart_state *state = tty->driver_data;
+ struct sb_uart_port *port = state->port;
+
+ if (I_IXOFF(tty)) {
+ if (port->x_char)
+ port->x_char = 0;
+ else
+ mp_send_xchar(tty, START_CHAR(tty));
+ }
+
+ if (tty->termios.c_cflag & CRTSCTS)
+ uart_set_mctrl(port, TIOCM_RTS);
+}
+
+static int mp_get_info(struct sb_uart_state *state, struct serial_struct *retinfo)
+{
+ struct sb_uart_port *port = state->port;
+ struct serial_struct tmp;
+
+ memset(&tmp, 0, sizeof(tmp));
+ tmp.type = port->type;
+ tmp.line = port->line;
+ tmp.port = port->iobase;
+ if (HIGH_BITS_OFFSET)
+ tmp.port_high = (long) port->iobase >> HIGH_BITS_OFFSET;
+ tmp.irq = port->irq;
+ tmp.flags = port->flags;
+ tmp.xmit_fifo_size = port->fifosize;
+ tmp.baud_base = port->uartclk / 16;
+ tmp.close_delay = state->close_delay;
+ tmp.closing_wait = state->closing_wait == USF_CLOSING_WAIT_NONE ?
+ ASYNC_CLOSING_WAIT_NONE :
+ state->closing_wait;
+ tmp.custom_divisor = port->custom_divisor;
+ tmp.hub6 = port->hub6;
+ tmp.io_type = port->iotype;
+ tmp.iomem_reg_shift = port->regshift;
+ tmp.iomem_base = (void *)port->mapbase;
+
+ if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
+ return -EFAULT;
+ return 0;
+}
+
+static int mp_set_info(struct sb_uart_state *state, struct serial_struct *newinfo)
+{
+ struct serial_struct new_serial;
+ struct sb_uart_port *port = state->port;
+ unsigned long new_port;
+ unsigned int change_irq, change_port, closing_wait;
+ unsigned int old_custom_divisor;
+ unsigned int old_flags, new_flags;
+ int retval = 0;
+
+ if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
+ return -EFAULT;
+
+ new_port = new_serial.port;
+ if (HIGH_BITS_OFFSET)
+ new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
+
+ new_serial.irq = irq_canonicalize(new_serial.irq);
+
+ closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
+ USF_CLOSING_WAIT_NONE : new_serial.closing_wait;
+ MP_STATE_LOCK(state);
+
+ change_irq = new_serial.irq != port->irq;
+ change_port = new_port != port->iobase ||
+ (unsigned long)new_serial.iomem_base != port->mapbase ||
+ new_serial.hub6 != port->hub6 ||
+ new_serial.io_type != port->iotype ||
+ new_serial.iomem_reg_shift != port->regshift ||
+ new_serial.type != port->type;
+ old_flags = port->flags;
+ new_flags = new_serial.flags;
+ old_custom_divisor = port->custom_divisor;
+
+ if (!capable(CAP_SYS_ADMIN)) {
+ retval = -EPERM;
+ if (change_irq || change_port ||
+ (new_serial.baud_base != port->uartclk / 16) ||
+ (new_serial.close_delay != state->close_delay) ||
+ (closing_wait != state->closing_wait) ||
+ (new_serial.xmit_fifo_size != port->fifosize) ||
+ (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0))
+ goto exit;
+ port->flags = ((port->flags & ~UPF_USR_MASK) |
+ (new_flags & UPF_USR_MASK));
+ port->custom_divisor = new_serial.custom_divisor;
+ goto check_and_exit;
+ }
+
+ if (port->ops->verify_port)
+ retval = port->ops->verify_port(port, &new_serial);
+
+ if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
+ (new_serial.baud_base < 9600))
+ retval = -EINVAL;
+
+ if (retval)
+ goto exit;
+
+ if (change_port || change_irq) {
+ retval = -EBUSY;
+
+ if (uart_users(state) > 1)
+ goto exit;
+
+ mp_shutdown(state);
+ }
+
+ if (change_port) {
+ unsigned long old_iobase, old_mapbase;
+ unsigned int old_type, old_iotype, old_hub6, old_shift;
+
+ old_iobase = port->iobase;
+ old_mapbase = port->mapbase;
+ old_type = port->type;
+ old_hub6 = port->hub6;
+ old_iotype = port->iotype;
+ old_shift = port->regshift;
+
+ if (old_type != PORT_UNKNOWN)
+ port->ops->release_port(port);
+
+ port->iobase = new_port;
+ port->type = new_serial.type;
+ port->hub6 = new_serial.hub6;
+ port->iotype = new_serial.io_type;
+ port->regshift = new_serial.iomem_reg_shift;
+ port->mapbase = (unsigned long)new_serial.iomem_base;
+
+ if (port->type != PORT_UNKNOWN) {
+ retval = port->ops->request_port(port);
+ } else {
+ retval = 0;
+ }
+
+ if (retval && old_type != PORT_UNKNOWN) {
+ port->iobase = old_iobase;
+ port->type = old_type;
+ port->hub6 = old_hub6;
+ port->iotype = old_iotype;
+ port->regshift = old_shift;
+ port->mapbase = old_mapbase;
+ retval = port->ops->request_port(port);
+ if (retval)
+ port->type = PORT_UNKNOWN;
+
+ retval = -EBUSY;
+ }
+ }
+
+ port->irq = new_serial.irq;
+ port->uartclk = new_serial.baud_base * 16;
+ port->flags = (port->flags & ~UPF_CHANGE_MASK) |
+ (new_flags & UPF_CHANGE_MASK);
+ port->custom_divisor = new_serial.custom_divisor;
+ state->close_delay = new_serial.close_delay;
+ state->closing_wait = closing_wait;
+ port->fifosize = new_serial.xmit_fifo_size;
+ if (state->info->tty)
+ state->info->tty->low_latency =
+ (port->flags & UPF_LOW_LATENCY) ? 1 : 0;
+
+check_and_exit:
+ retval = 0;
+ if (port->type == PORT_UNKNOWN)
+ goto exit;
+ if (state->info->flags & UIF_INITIALIZED) {
+ if (((old_flags ^ port->flags) & UPF_SPD_MASK) ||
+ old_custom_divisor != port->custom_divisor) {
+ if (port->flags & UPF_SPD_MASK) {
+ printk(KERN_NOTICE
+ "%s sets custom speed on ttyMP%d. This "
+ "is deprecated.\n", current->comm,
+ port->line);
+ }
+ mp_change_speed(state, NULL);
+ }
+ } else
+ retval = mp_startup(state, 1);
+exit:
+ MP_STATE_UNLOCK(state);
+ return retval;
+}
+
+
+static int mp_get_lsr_info(struct sb_uart_state *state, unsigned int *value)
+{
+ struct sb_uart_port *port = state->port;
+ unsigned int result;
+
+ result = port->ops->tx_empty(port);
+
+ if (port->x_char ||
+ ((uart_circ_chars_pending(&state->info->xmit) > 0) &&
+ !state->info->tty->stopped && !state->info->tty->hw_stopped))
+ result &= ~TIOCSER_TEMT;
+
+ return put_user(result, value);
+}
+
+static int mp_tiocmget(struct tty_struct *tty)
+{
+ struct sb_uart_state *state = tty->driver_data;
+ struct sb_uart_port *port = state->port;
+ int result = -EIO;
+
+ MP_STATE_LOCK(state);
+ if (!(tty->flags & (1 << TTY_IO_ERROR))) {
+ result = port->mctrl;
+ spin_lock_irq(&port->lock);
+ result |= port->ops->get_mctrl(port);
+ spin_unlock_irq(&port->lock);
+ }
+ MP_STATE_UNLOCK(state);
+ return result;
+}
+
+static int mp_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
+{
+ struct sb_uart_state *state = tty->driver_data;
+ struct sb_uart_port *port = state->port;
+ int ret = -EIO;
+
+
+ MP_STATE_LOCK(state);
+ if (!(tty->flags & (1 << TTY_IO_ERROR))) {
+ mp_update_mctrl(port, set, clear);
+ ret = 0;
+ }
+ MP_STATE_UNLOCK(state);
+
+ return ret;
+}
+
+static int mp_break_ctl(struct tty_struct *tty, int break_state)
+{
+ struct sb_uart_state *state = tty->driver_data;
+ struct sb_uart_port *port = state->port;
+
+ MP_STATE_LOCK(state);
+
+ if (port->type != PORT_UNKNOWN)
+ port->ops->break_ctl(port, break_state);
+
+ MP_STATE_UNLOCK(state);
+ return 0;
+}
+
+static int mp_do_autoconfig(struct sb_uart_state *state)
+{
+ struct sb_uart_port *port = state->port;
+ int flags, ret;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (mutex_lock_interruptible(&state->mutex))
+ return -ERESTARTSYS;
+ ret = -EBUSY;
+ if (uart_users(state) == 1) {
+ mp_shutdown(state);
+
+ if (port->type != PORT_UNKNOWN)
+ port->ops->release_port(port);
+
+ flags = UART_CONFIG_TYPE;
+ if (port->flags & UPF_AUTO_IRQ)
+ flags |= UART_CONFIG_IRQ;
+
+ port->ops->config_port(port, flags);
+
+ ret = mp_startup(state, 1);
+ }
+ MP_STATE_UNLOCK(state);
+ return ret;
+}
+
+static int mp_wait_modem_status(struct sb_uart_state *state, unsigned long arg)
+{
+ struct sb_uart_port *port = state->port;
+ DECLARE_WAITQUEUE(wait, current);
+ struct sb_uart_icount cprev, cnow;
+ int ret;
+
+ spin_lock_irq(&port->lock);
+ memcpy(&cprev, &port->icount, sizeof(struct sb_uart_icount));
+
+ port->ops->enable_ms(port);
+ spin_unlock_irq(&port->lock);
+
+ add_wait_queue(&state->info->delta_msr_wait, &wait);
+ for (;;) {
+ spin_lock_irq(&port->lock);
+ memcpy(&cnow, &port->icount, sizeof(struct sb_uart_icount));
+ spin_unlock_irq(&port->lock);
+
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
+ ret = 0;
+ break;
+ }
+
+ schedule();
+
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ break;
+ }
+
+ cprev = cnow;
+ }
+
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&state->info->delta_msr_wait, &wait);
+
+ return ret;
+}
+
+static int mp_get_count(struct sb_uart_state *state, struct serial_icounter_struct *icnt)
+{
+ struct serial_icounter_struct icount;
+ struct sb_uart_icount cnow;
+ struct sb_uart_port *port = state->port;
+
+ spin_lock_irq(&port->lock);
+ memcpy(&cnow, &port->icount, sizeof(struct sb_uart_icount));
+ spin_unlock_irq(&port->lock);
+
+ icount.cts = cnow.cts;
+ icount.dsr = cnow.dsr;
+ icount.rng = cnow.rng;
+ icount.dcd = cnow.dcd;
+ icount.rx = cnow.rx;
+ icount.tx = cnow.tx;
+ icount.frame = cnow.frame;
+ icount.overrun = cnow.overrun;
+ icount.parity = cnow.parity;
+ icount.brk = cnow.brk;
+ icount.buf_overrun = cnow.buf_overrun;
+
+ return copy_to_user(icnt, &icount, sizeof(icount)) ? -EFAULT : 0;
+}
+
+static int mp_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
+{
+ struct sb_uart_state *state = tty->driver_data;
+ struct mp_port *info = (struct mp_port *)state->port;
+ int ret = -ENOIOCTLCMD;
+
+
+ switch (cmd) {
+ case TIOCSMULTIDROP:
+ /* set multi-drop mode enable or disable, and default operation mode is H/W mode */
+ if (info->port.type == PORT_16C105XA)
+ {
+ //arg &= ~0x6;
+ //state->port->mdmode = 0;
+ return set_multidrop_mode((struct sb_uart_port *)info, (unsigned int)arg);
+ }
+ ret = -ENOTSUPP;
+ break;
+ case GETDEEPFIFO:
+ ret = get_deep_fifo(state->port);
+ return ret;
+ case SETDEEPFIFO:
+ ret = set_deep_fifo(state->port,arg);
+ deep[state->port->line] = arg;
+ return ret;
+ case SETTTR:
+ if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){
+ ret = sb1054_set_register(state->port,PAGE_4,SB105X_TTR,arg);
+ ttr[state->port->line] = arg;
+ }
+ return ret;
+ case SETRTR:
+ if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){
+ ret = sb1054_set_register(state->port,PAGE_4,SB105X_RTR,arg);
+ rtr[state->port->line] = arg;
+ }
+ return ret;
+ case GETTTR:
+ if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){
+ ret = sb1054_get_register(state->port,PAGE_4,SB105X_TTR);
+ }
+ return ret;
+ case GETRTR:
+ if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){
+ ret = sb1054_get_register(state->port,PAGE_4,SB105X_RTR);
+ }
+ return ret;
+
+ case SETFCR:
+ if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){
+ ret = sb1054_set_register(state->port,PAGE_1,SB105X_FCR,arg);
+ }
+ else{
+ serial_out(info,2,arg);
+ }
+
+ return ret;
+ case TIOCSMDADDR:
+ /* set multi-drop address */
+ if (info->port.type == PORT_16C105XA)
+ {
+ state->port->mdmode |= MDMODE_ADDR;
+ return set_multidrop_addr((struct sb_uart_port *)info, (unsigned int)arg);
+ }
+ ret = -ENOTSUPP;
+ break;
+
+ case TIOCGMDADDR:
+ /* set multi-drop address */
+ if ((info->port.type == PORT_16C105XA) && (state->port->mdmode & MDMODE_ADDR))
+ {
+ return get_multidrop_addr((struct sb_uart_port *)info);
+ }
+ ret = -ENOTSUPP;
+ break;
+
+ case TIOCSENDADDR:
+ /* send address in multi-drop mode */
+ if ((info->port.type == PORT_16C105XA)
+ && (state->port->mdmode & (MDMODE_ENABLE)))
+ {
+ if (mp_chars_in_buffer(tty) > 0)
+ {
+ tty_wait_until_sent(tty, 0);
+ }
+ //while ((serial_in(info, UART_LSR) & 0x60) != 0x60);
+ //while (sb1054_get_register(state->port, PAGE_2, SB105X_TFCR) != 0);
+ while ((serial_in(info, UART_LSR) & 0x60) != 0x60);
+ serial_out(info, UART_SCR, (int)arg);
+ }
+ break;
+
+ case TIOCGSERIAL:
+ ret = mp_get_info(state, (struct serial_struct *)arg);
+ break;
+
+ case TIOCSSERIAL:
+ ret = mp_set_info(state, (struct serial_struct *)arg);
+ break;
+
+ case TIOCSERCONFIG:
+ ret = mp_do_autoconfig(state);
+ break;
+
+ case TIOCSERGWILD: /* obsolete */
+ case TIOCSERSWILD: /* obsolete */
+ ret = 0;
+ break;
+ /* for Multiport */
+ case TIOCGNUMOFPORT: /* Get number of ports */
+ return NR_PORTS;
+ case TIOCGGETDEVID:
+ return mp_devs[arg].device_id;
+ case TIOCGGETREV:
+ return mp_devs[arg].revision;
+ case TIOCGGETNRPORTS:
+ return mp_devs[arg].nr_ports;
+ case TIOCGGETBDNO:
+ return NR_BOARD;
+ case TIOCGGETINTERFACE:
+ if (mp_devs[arg].revision == 0xc0)
+ {
+ /* for SB16C1053APCI */
+ return (sb1053a_get_interface(info, info->port.line));
+ }
+ else
+ {
+ return (inb(mp_devs[arg].option_reg_addr+MP_OPTR_IIR0+(state->port->line/8)));
+ }
+ case TIOCGGETPORTTYPE:
+ 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 ,
+ info->interface_config_addr);
+ return 0;
+ case TIOCSPTPNOECHO: /* set to multi-drop mode(RS422) or echo mode(RS485) */
+ outb( ( inb(info->interface_config_addr) & ~0x03 ) ,
+ info->interface_config_addr);
+ return 0;
+ }
+
+ if (ret != -ENOIOCTLCMD)
+ goto out;
+
+ if (tty->flags & (1 << TTY_IO_ERROR)) {
+ ret = -EIO;
+ goto out;
+ }
+
+ switch (cmd) {
+ case TIOCMIWAIT:
+ ret = mp_wait_modem_status(state, arg);
+ break;
+
+ case TIOCGICOUNT:
+ ret = mp_get_count(state, (struct serial_icounter_struct *)arg);
+ break;
+ }
+
+ if (ret != -ENOIOCTLCMD)
+ goto out;
+
+ MP_STATE_LOCK(state);
+ switch (cmd) {
+ case TIOCSERGETLSR: /* Get line status register */
+ ret = mp_get_lsr_info(state, (unsigned int *)arg);
+ break;
+
+ default: {
+ struct sb_uart_port *port = state->port;
+ if (port->ops->ioctl)
+ ret = port->ops->ioctl(port, cmd, arg);
+ break;
+ }
+ }
+
+ MP_STATE_UNLOCK(state);
+out:
+ return ret;
+}
+
+static void mp_set_termios(struct tty_struct *tty, struct MP_TERMIOS *old_termios)
+{
+ struct sb_uart_state *state = tty->driver_data;
+ unsigned long flags;
+ unsigned int cflag = tty->termios.c_cflag;
+
+#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+ if ((cflag ^ old_termios->c_cflag) == 0 &&
+ RELEVANT_IFLAG(tty->termios.c_iflag ^ old_termios->c_iflag) == 0)
+ return;
+
+ mp_change_speed(state, old_termios);
+
+ if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
+ uart_clear_mctrl(state->port, TIOCM_RTS | TIOCM_DTR);
+
+ if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
+ unsigned int mask = TIOCM_DTR;
+ if (!(cflag & CRTSCTS) ||
+ !test_bit(TTY_THROTTLED, &tty->flags))
+ mask |= TIOCM_RTS;
+ uart_set_mctrl(state->port, mask);
+ }
+
+ if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
+ spin_lock_irqsave(&state->port->lock, flags);
+ tty->hw_stopped = 0;
+ __mp_start(tty);
+ spin_unlock_irqrestore(&state->port->lock, flags);
+ }
+
+ if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
+ spin_lock_irqsave(&state->port->lock, flags);
+ if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) {
+ tty->hw_stopped = 1;
+ state->port->ops->stop_tx(state->port);
+ }
+ spin_unlock_irqrestore(&state->port->lock, flags);
+ }
+}
+
+static void mp_close(struct tty_struct *tty, struct file *filp)
+{
+ struct sb_uart_state *state = tty->driver_data;
+ struct sb_uart_port *port;
+
+ printk("mp_close!\n");
+ if (!state || !state->port)
+ return;
+
+ port = state->port;
+
+ printk("close1 %d\n", __LINE__);
+ MP_STATE_LOCK(state);
+
+ printk("close2 %d\n", __LINE__);
+ if (tty_hung_up_p(filp))
+ goto done;
+
+ printk("close3 %d\n", __LINE__);
+ if ((tty->count == 1) && (state->count != 1)) {
+ printk("mp_close: bad serial port count; tty->count is 1, "
+ "state->count is %d\n", state->count);
+ state->count = 1;
+ }
+ printk("close4 %d\n", __LINE__);
+ if (--state->count < 0) {
+ printk("rs_close: bad serial port count for ttyMP%d: %d\n",
+ port->line, state->count);
+ state->count = 0;
+ }
+ if (state->count)
+ goto done;
+
+ tty->closing = 1;
+
+ printk("close5 %d\n", __LINE__);
+ if (state->closing_wait != USF_CLOSING_WAIT_NONE)
+ tty_wait_until_sent(tty, state->closing_wait);
+
+ printk("close6 %d\n", __LINE__);
+ if (state->info->flags & UIF_INITIALIZED) {
+ unsigned long flags;
+ spin_lock_irqsave(&port->lock, flags);
+ port->ops->stop_rx(port);
+ spin_unlock_irqrestore(&port->lock, flags);
+ mp_wait_until_sent(tty, port->timeout);
+ }
+ printk("close7 %d\n", __LINE__);
+
+ mp_shutdown(state);
+ printk("close8 %d\n", __LINE__);
+ mp_flush_buffer(tty);
+ tty_ldisc_flush(tty);
+ tty->closing = 0;
+ state->info->tty = NULL;
+ if (state->info->blocked_open)
+ {
+ if (state->close_delay)
+ {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(state->close_delay);
+ }
+ }
+ else
+ {
+ mp_change_pm(state, 3);
+ }
+ printk("close8 %d\n", __LINE__);
+
+ state->info->flags &= ~UIF_NORMAL_ACTIVE;
+ wake_up_interruptible(&state->info->open_wait);
+
+done:
+ printk("close done\n");
+ MP_STATE_UNLOCK(state);
+ module_put(THIS_MODULE);
+}
+
+static void mp_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+ struct sb_uart_state *state = tty->driver_data;
+ struct sb_uart_port *port = state->port;
+ unsigned long char_time, expire;
+
+ if (port->type == PORT_UNKNOWN || port->fifosize == 0)
+ return;
+
+ char_time = (port->timeout - HZ/50) / port->fifosize;
+ char_time = char_time / 5;
+ if (char_time == 0)
+ char_time = 1;
+ if (timeout && timeout < char_time)
+ char_time = timeout;
+
+ if (timeout == 0 || timeout > 2 * port->timeout)
+ timeout = 2 * port->timeout;
+
+ expire = jiffies + timeout;
+
+ while (!port->ops->tx_empty(port)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(char_time);
+ if (signal_pending(current))
+ break;
+ if (time_after(jiffies, expire))
+ break;
+ }
+ set_current_state(TASK_RUNNING); /* might not be needed */
+}
+
+static void mp_hangup(struct tty_struct *tty)
+{
+ struct sb_uart_state *state = tty->driver_data;
+
+ MP_STATE_LOCK(state);
+ if (state->info && state->info->flags & UIF_NORMAL_ACTIVE) {
+ mp_flush_buffer(tty);
+ mp_shutdown(state);
+ state->count = 0;
+ state->info->flags &= ~UIF_NORMAL_ACTIVE;
+ state->info->tty = NULL;
+ wake_up_interruptible(&state->info->open_wait);
+ wake_up_interruptible(&state->info->delta_msr_wait);
+ }
+ MP_STATE_UNLOCK(state);
+}
+
+static void mp_update_termios(struct sb_uart_state *state)
+{
+ struct tty_struct *tty = state->info->tty;
+ struct sb_uart_port *port = state->port;
+
+ if (!(tty->flags & (1 << TTY_IO_ERROR))) {
+ mp_change_speed(state, NULL);
+
+ if (tty->termios.c_cflag & CBAUD)
+ uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ }
+}
+
+static int mp_block_til_ready(struct file *filp, struct sb_uart_state *state)
+{
+ DECLARE_WAITQUEUE(wait, current);
+ struct sb_uart_info *info = state->info;
+ struct sb_uart_port *port = state->port;
+ unsigned int mctrl;
+
+ info->blocked_open++;
+ state->count--;
+
+ add_wait_queue(&info->open_wait, &wait);
+ while (1) {
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ if (tty_hung_up_p(filp) || info->tty == NULL)
+ break;
+
+ if (!(info->flags & UIF_INITIALIZED))
+ break;
+
+ if ((filp->f_flags & O_NONBLOCK) ||
+ (info->tty->termios.c_cflag & CLOCAL) ||
+ (info->tty->flags & (1 << TTY_IO_ERROR))) {
+ break;
+ }
+
+ if (info->tty->termios.c_cflag & CBAUD)
+ uart_set_mctrl(port, TIOCM_DTR);
+
+ spin_lock_irq(&port->lock);
+ port->ops->enable_ms(port);
+ mctrl = port->ops->get_mctrl(port);
+ spin_unlock_irq(&port->lock);
+ if (mctrl & TIOCM_CAR)
+ break;
+
+ MP_STATE_UNLOCK(state);
+ schedule();
+ MP_STATE_LOCK(state);
+
+ if (signal_pending(current))
+ break;
+ }
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&info->open_wait, &wait);
+
+ state->count++;
+ info->blocked_open--;
+
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
+ if (!info->tty || tty_hung_up_p(filp))
+ return -EAGAIN;
+
+ return 0;
+}
+
+static struct sb_uart_state *uart_get(struct uart_driver *drv, int line)
+{
+ struct sb_uart_state *state;
+
+ MP_MUTEX_LOCK(mp_mutex);
+ state = drv->state + line;
+ if (mutex_lock_interruptible(&state->mutex)) {
+ state = ERR_PTR(-ERESTARTSYS);
+ goto out;
+ }
+ state->count++;
+ if (!state->port) {
+ state->count--;
+ MP_STATE_UNLOCK(state);
+ state = ERR_PTR(-ENXIO);
+ goto out;
+ }
+
+ if (!state->info) {
+ state->info = kmalloc(sizeof(struct sb_uart_info), GFP_KERNEL);
+ if (state->info) {
+ memset(state->info, 0, sizeof(struct sb_uart_info));
+ init_waitqueue_head(&state->info->open_wait);
+ init_waitqueue_head(&state->info->delta_msr_wait);
+
+ state->port->info = state->info;
+
+ tasklet_init(&state->info->tlet, mp_tasklet_action,
+ (unsigned long)state);
+ } else {
+ state->count--;
+ MP_STATE_UNLOCK(state);
+ state = ERR_PTR(-ENOMEM);
+ }
+ }
+
+out:
+ MP_MUTEX_UNLOCK(mp_mutex);
+ return state;
+}
+
+static int mp_open(struct tty_struct *tty, struct file *filp)
+{
+ struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state;
+ struct sb_uart_state *state;
+ int retval;
+ int line = tty->index;
+ struct mp_port *mtpt;
+
+ retval = -ENODEV;
+ if (line >= tty->driver->num)
+ goto fail;
+
+ state = uart_get(drv, line);
+
+ mtpt = (struct mp_port *)state->port;
+
+ if (IS_ERR(state)) {
+ retval = PTR_ERR(state);
+ goto fail;
+ }
+
+ tty->driver_data = state;
+ tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0;
+ tty->alt_speed = 0;
+ state->info->tty = tty;
+
+ if (tty_hung_up_p(filp)) {
+ retval = -EAGAIN;
+ state->count--;
+ MP_STATE_UNLOCK(state);
+ goto fail;
+ }
+
+ if (state->count == 1)
+ mp_change_pm(state, 0);
+
+ retval = mp_startup(state, 0);
+
+ if (retval == 0)
+ retval = mp_block_til_ready(filp, state);
+ MP_STATE_UNLOCK(state);
+
+ if (retval == 0 && !(state->info->flags & UIF_NORMAL_ACTIVE)) {
+ state->info->flags |= UIF_NORMAL_ACTIVE;
+
+ mp_update_termios(state);
+ }
+
+ uart_clear_mctrl(state->port, TIOCM_RTS);
+ try_module_get(THIS_MODULE);
+fail:
+ return retval;
+}
+
+
+static const char *mp_type(struct sb_uart_port *port)
+{
+ const char *str = NULL;
+
+ if (port->ops->type)
+ str = port->ops->type(port);
+
+ if (!str)
+ str = "unknown";
+
+ return str;
+}
+
+static void mp_change_pm(struct sb_uart_state *state, int pm_state)
+{
+ struct sb_uart_port *port = state->port;
+ if (port->ops->pm)
+ port->ops->pm(port, pm_state, state->pm_state);
+ state->pm_state = pm_state;
+}
+
+static inline void mp_report_port(struct uart_driver *drv, struct sb_uart_port *port)
+{
+ char address[64];
+
+ switch (port->iotype) {
+ case UPIO_PORT:
+ snprintf(address, sizeof(address),"I/O 0x%x", port->iobase);
+ break;
+ case UPIO_HUB6:
+ snprintf(address, sizeof(address),"I/O 0x%x offset 0x%x", port->iobase, port->hub6);
+ break;
+ case UPIO_MEM:
+ snprintf(address, sizeof(address),"MMIO 0x%lx", port->mapbase);
+ break;
+ default:
+ snprintf(address, sizeof(address),"*unknown*" );
+ strlcpy(address, "*unknown*", sizeof(address));
+ break;
+ }
+
+ printk( "%s%d at %s (irq = %d) is a %s\n",
+ drv->dev_name, port->line, address, port->irq, mp_type(port));
+
+}
+
+static void mp_configure_port(struct uart_driver *drv, struct sb_uart_state *state, struct sb_uart_port *port)
+{
+ unsigned int flags;
+
+
+ if (!port->iobase && !port->mapbase && !port->membase)
+ {
+ DPRINTK("%s error \n",__FUNCTION__);
+ return;
+ }
+ flags = UART_CONFIG_TYPE;
+ if (port->flags & UPF_AUTO_IRQ)
+ flags |= UART_CONFIG_IRQ;
+ if (port->flags & UPF_BOOT_AUTOCONF) {
+ port->type = PORT_UNKNOWN;
+ port->ops->config_port(port, flags);
+ }
+
+ if (port->type != PORT_UNKNOWN) {
+ unsigned long flags;
+
+ mp_report_port(drv, port);
+
+ spin_lock_irqsave(&port->lock, flags);
+ port->ops->set_mctrl(port, 0);
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ mp_change_pm(state, 3);
+ }
+}
+
+static void mp_unconfigure_port(struct uart_driver *drv, struct sb_uart_state *state)
+{
+ struct sb_uart_port *port = state->port;
+ struct sb_uart_info *info = state->info;
+
+ if (info && info->tty)
+ tty_hangup(info->tty);
+
+ MP_STATE_LOCK(state);
+
+ state->info = NULL;
+
+ if (port->type != PORT_UNKNOWN)
+ port->ops->release_port(port);
+
+ port->type = PORT_UNKNOWN;
+
+ if (info) {
+ tasklet_kill(&info->tlet);
+ kfree(info);
+ }
+
+ MP_STATE_UNLOCK(state);
+}
+static struct tty_operations mp_ops = {
+ .open = mp_open,
+ .close = mp_close,
+ .write = mp_write,
+ .put_char = mp_put_char,
+ .flush_chars = mp_put_chars,
+ .write_room = mp_write_room,
+ .chars_in_buffer= mp_chars_in_buffer,
+ .flush_buffer = mp_flush_buffer,
+ .ioctl = mp_ioctl,
+ .throttle = mp_throttle,
+ .unthrottle = mp_unthrottle,
+ .send_xchar = mp_send_xchar,
+ .set_termios = mp_set_termios,
+ .stop = mp_stop,
+ .start = mp_start,
+ .hangup = mp_hangup,
+ .break_ctl = mp_break_ctl,
+ .wait_until_sent= mp_wait_until_sent,
+#ifdef CONFIG_PROC_FS
+ .proc_fops = NULL,
+#endif
+ .tiocmget = mp_tiocmget,
+ .tiocmset = mp_tiocmset,
+};
+
+static int mp_register_driver(struct uart_driver *drv)
+{
+ struct tty_driver *normal = NULL;
+ int i, retval;
+
+ drv->state = kmalloc(sizeof(struct sb_uart_state) * drv->nr, GFP_KERNEL);
+ retval = -ENOMEM;
+ if (!drv->state)
+ {
+ printk("SB PCI Error: Kernel memory allocation error!\n");
+ goto out;
+ }
+ memset(drv->state, 0, sizeof(struct sb_uart_state) * drv->nr);
+
+ normal = alloc_tty_driver(drv->nr);
+ if (!normal)
+ {
+ printk("SB PCI Error: tty allocation error!\n");
+ goto out;
+ }
+
+ drv->tty_driver = normal;
+
+ normal->owner = drv->owner;
+ normal->magic = TTY_DRIVER_MAGIC;
+ normal->driver_name = drv->driver_name;
+ normal->name = drv->dev_name;
+ normal->major = drv->major;
+ normal->minor_start = drv->minor;
+
+ normal->num = MAX_MP_PORT ;
+
+ normal->type = TTY_DRIVER_TYPE_SERIAL;
+ normal->subtype = SERIAL_TYPE_NORMAL;
+ normal->init_termios = tty_std_termios;
+ normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+ normal->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+ normal->driver_state = drv;
+
+ tty_set_operations(normal, &mp_ops);
+
+for (i = 0; i < drv->nr; i++) {
+ struct sb_uart_state *state = drv->state + i;
+
+ state->close_delay = 500;
+ state->closing_wait = 30000;
+
+ mutex_init(&state->mutex);
+ }
+
+ retval = tty_register_driver(normal);
+out:
+ if (retval < 0) {
+ printk("Register tty driver Fail!\n");
+ put_tty_driver(normal);
+ kfree(drv->state);
+ }
+
+ return retval;
+}
+
+void mp_unregister_driver(struct uart_driver *drv)
+{
+ struct tty_driver *normal = NULL;
+
+ normal = drv->tty_driver;
+
+ if (!normal)
+ {
+ return;
+ }
+
+ tty_unregister_driver(normal);
+ put_tty_driver(normal);
+ drv->tty_driver = NULL;
+
+
+ if (drv->state)
+ {
+ kfree(drv->state);
+ }
+
+}
+
+static int mp_add_one_port(struct uart_driver *drv, struct sb_uart_port *port)
+{
+ struct sb_uart_state *state;
+ int ret = 0;
+
+
+ if (port->line >= drv->nr)
+ return -EINVAL;
+
+ state = drv->state + port->line;
+
+ MP_MUTEX_LOCK(mp_mutex);
+ if (state->port) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ state->port = port;
+
+ spin_lock_init(&port->lock);
+ port->cons = drv->cons;
+ port->info = state->info;
+
+ mp_configure_port(drv, state, port);
+
+ tty_register_device(drv->tty_driver, port->line, port->dev);
+
+out:
+ MP_MUTEX_UNLOCK(mp_mutex);
+
+
+ return ret;
+}
+
+static int mp_remove_one_port(struct uart_driver *drv, struct sb_uart_port *port)
+{
+ struct sb_uart_state *state = drv->state + port->line;
+
+ if (state->port != port)
+ printk(KERN_ALERT "Removing wrong port: %p != %p\n",
+ state->port, port);
+
+ MP_MUTEX_LOCK(mp_mutex);
+
+ tty_unregister_device(drv->tty_driver, port->line);
+
+ mp_unconfigure_port(drv, state);
+ state->port = NULL;
+ MP_MUTEX_UNLOCK(mp_mutex);
+
+ return 0;
+}
+
+static void autoconfig(struct mp_port *mtpt, unsigned int probeflags)
+{
+ unsigned char status1, scratch, scratch2, scratch3;
+ unsigned char save_lcr, save_mcr;
+ unsigned long flags;
+
+ unsigned char u_type;
+ unsigned char b_ret = 0;
+
+ if (!mtpt->port.iobase && !mtpt->port.mapbase && !mtpt->port.membase)
+ return;
+
+ DEBUG_AUTOCONF("ttyMP%d: autoconf (0x%04x, 0x%p): ",
+ mtpt->port.line, mtpt->port.iobase, mtpt->port.membase);
+
+ spin_lock_irqsave(&mtpt->port.lock, flags);
+
+ if (!(mtpt->port.flags & UPF_BUGGY_UART)) {
+ scratch = serial_inp(mtpt, UART_IER);
+ serial_outp(mtpt, UART_IER, 0);
+#ifdef __i386__
+ outb(0xff, 0x080);
+#endif
+ scratch2 = serial_inp(mtpt, UART_IER) & 0x0f;
+ serial_outp(mtpt, UART_IER, 0x0F);
+#ifdef __i386__
+ outb(0, 0x080);
+#endif
+ scratch3 = serial_inp(mtpt, UART_IER) & 0x0F;
+ serial_outp(mtpt, UART_IER, scratch);
+ if (scratch2 != 0 || scratch3 != 0x0F) {
+ DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
+ scratch2, scratch3);
+ goto out;
+ }
+ }
+
+ save_mcr = serial_in(mtpt, UART_MCR);
+ save_lcr = serial_in(mtpt, UART_LCR);
+
+ if (!(mtpt->port.flags & UPF_SKIP_TEST)) {
+ serial_outp(mtpt, UART_MCR, UART_MCR_LOOP | 0x0A);
+ status1 = serial_inp(mtpt, UART_MSR) & 0xF0;
+ serial_outp(mtpt, UART_MCR, save_mcr);
+ if (status1 != 0x90) {
+ DEBUG_AUTOCONF("LOOP test failed (%02x) ",
+ status1);
+ goto out;
+ }
+ }
+
+ serial_outp(mtpt, UART_LCR, 0xBF);
+ serial_outp(mtpt, UART_EFR, 0);
+ serial_outp(mtpt, UART_LCR, 0);
+
+ serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO);
+ scratch = serial_in(mtpt, UART_IIR) >> 6;
+
+ DEBUG_AUTOCONF("iir=%d ", scratch);
+ if(mtpt->device->nr_ports >= 8)
+ b_ret = read_option_register(mtpt,(MP_OPTR_DIR0 + ((mtpt->port.line)/8)));
+ else
+ b_ret = read_option_register(mtpt,MP_OPTR_DIR0);
+ u_type = (b_ret & 0xf0) >> 4;
+ if(mtpt->port.type == PORT_UNKNOWN )
+ {
+ switch (u_type)
+ {
+ case DIR_UART_16C550:
+ mtpt->port.type = PORT_16C55X;
+ break;
+ case DIR_UART_16C1050:
+ mtpt->port.type = PORT_16C105X;
+ break;
+ case DIR_UART_16C1050A:
+ if (mtpt->port.line < 2)
+ {
+ mtpt->port.type = PORT_16C105XA;
+ }
+ else
+ {
+ if (mtpt->device->device_id & 0x50)
+ {
+ mtpt->port.type = PORT_16C55X;
+ }
+ else
+ {
+ mtpt->port.type = PORT_16C105X;
+ }
+ }
+ break;
+ default:
+ mtpt->port.type = PORT_UNKNOWN;
+ break;
+ }
+ }
+
+ if(mtpt->port.type == PORT_UNKNOWN )
+ {
+printk("unknow2\n");
+ switch (scratch) {
+ case 0:
+ case 1:
+ mtpt->port.type = PORT_UNKNOWN;
+ break;
+ case 2:
+ case 3:
+ mtpt->port.type = PORT_16C55X;
+ break;
+ }
+ }
+
+ serial_outp(mtpt, UART_LCR, save_lcr);
+
+ mtpt->port.fifosize = uart_config[mtpt->port.type].dfl_xmit_fifo_size;
+ mtpt->capabilities = uart_config[mtpt->port.type].flags;
+
+ if (mtpt->port.type == PORT_UNKNOWN)
+ goto out;
+ serial_outp(mtpt, UART_MCR, save_mcr);
+ serial_outp(mtpt, UART_FCR, (UART_FCR_ENABLE_FIFO |
+ UART_FCR_CLEAR_RCVR |
+ UART_FCR_CLEAR_XMIT));
+ serial_outp(mtpt, UART_FCR, 0);
+ (void)serial_in(mtpt, UART_RX);
+ serial_outp(mtpt, UART_IER, 0);
+
+out:
+ spin_unlock_irqrestore(&mtpt->port.lock, flags);
+ DEBUG_AUTOCONF("type=%s\n", uart_config[mtpt->port.type].name);
+}
+
+static void autoconfig_irq(struct mp_port *mtpt)
+{
+ unsigned char save_mcr, save_ier;
+ unsigned long irqs;
+ int irq;
+
+ /* forget possible initially masked and pending IRQ */
+ probe_irq_off(probe_irq_on());
+ save_mcr = serial_inp(mtpt, UART_MCR);
+ save_ier = serial_inp(mtpt, UART_IER);
+ serial_outp(mtpt, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
+
+ irqs = probe_irq_on();
+ serial_outp(mtpt, UART_MCR, 0);
+ serial_outp(mtpt, UART_MCR,
+ UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
+
+ serial_outp(mtpt, UART_IER, 0x0f); /* enable all intrs */
+ (void)serial_inp(mtpt, UART_LSR);
+ (void)serial_inp(mtpt, UART_RX);
+ (void)serial_inp(mtpt, UART_IIR);
+ (void)serial_inp(mtpt, UART_MSR);
+ serial_outp(mtpt, UART_TX, 0xFF);
+ irq = probe_irq_off(irqs);
+
+ serial_outp(mtpt, UART_MCR, save_mcr);
+ serial_outp(mtpt, UART_IER, save_ier);
+
+ mtpt->port.irq = (irq > 0) ? irq : 0;
+}
+
+static void multi_stop_tx(struct sb_uart_port *port)
+{
+ struct mp_port *mtpt = (struct mp_port *)port;
+
+ if (mtpt->ier & UART_IER_THRI) {
+ mtpt->ier &= ~UART_IER_THRI;
+ serial_out(mtpt, UART_IER, mtpt->ier);
+ }
+
+ tasklet_schedule(&port->info->tlet);
+}
+
+static void multi_start_tx(struct sb_uart_port *port)
+{
+ struct mp_port *mtpt = (struct mp_port *)port;
+
+ if (!(mtpt->ier & UART_IER_THRI)) {
+ mtpt->ier |= UART_IER_THRI;
+ serial_out(mtpt, UART_IER, mtpt->ier);
+ }
+}
+
+static void multi_stop_rx(struct sb_uart_port *port)
+{
+ struct mp_port *mtpt = (struct mp_port *)port;
+
+ mtpt->ier &= ~UART_IER_RLSI;
+ mtpt->port.read_status_mask &= ~UART_LSR_DR;
+ serial_out(mtpt, UART_IER, mtpt->ier);
+}
+
+static void multi_enable_ms(struct sb_uart_port *port)
+{
+ struct mp_port *mtpt = (struct mp_port *)port;
+
+ mtpt->ier |= UART_IER_MSI;
+ serial_out(mtpt, UART_IER, mtpt->ier);
+}
+
+
+static _INLINE_ void receive_chars(struct mp_port *mtpt, int *status )
+{
+ struct tty_struct *tty = mtpt->port.info->tty;
+ unsigned char lsr = *status;
+ int max_count = 256;
+ unsigned char ch;
+ char flag;
+
+ //lsr &= mtpt->port.read_status_mask;
+
+ do {
+ if ((lsr & UART_LSR_PE) && (mtpt->port.mdmode & MDMODE_ENABLE))
+ {
+ ch = serial_inp(mtpt, UART_RX);
+ }
+ else if (lsr & UART_LSR_SPECIAL)
+ {
+ flag = 0;
+ ch = serial_inp(mtpt, UART_RX);
+
+ if (lsr & UART_LSR_BI)
+ {
+
+ mtpt->port.icount.brk++;
+ flag = TTY_BREAK;
+
+ if (sb_uart_handle_break(&mtpt->port))
+ goto ignore_char;
+ }
+ if (lsr & UART_LSR_PE)
+ {
+ mtpt->port.icount.parity++;
+ flag = TTY_PARITY;
+ }
+ if (lsr & UART_LSR_FE)
+ {
+ mtpt->port.icount.frame++;
+ flag = TTY_FRAME;
+ }
+ if (lsr & UART_LSR_OE)
+ {
+ mtpt->port.icount.overrun++;
+ flag = TTY_OVERRUN;
+ }
+ tty_insert_flip_char(tty, ch, flag);
+ }
+ else
+ {
+ ch = serial_inp(mtpt, UART_RX);
+ tty_insert_flip_char(tty, ch, 0);
+ }
+ignore_char:
+ lsr = serial_inp(mtpt, UART_LSR);
+ } while ((lsr & UART_LSR_DR) && (max_count-- > 0));
+
+ tty_flip_buffer_push(tty);
+}
+
+
+
+
+static _INLINE_ void transmit_chars(struct mp_port *mtpt)
+{
+ struct circ_buf *xmit = &mtpt->port.info->xmit;
+ int count;
+
+ if (mtpt->port.x_char) {
+ serial_outp(mtpt, UART_TX, mtpt->port.x_char);
+ mtpt->port.icount.tx++;
+ mtpt->port.x_char = 0;
+ return;
+ }
+ if (uart_circ_empty(xmit) || uart_tx_stopped(&mtpt->port)) {
+ multi_stop_tx(&mtpt->port);
+ return;
+ }
+
+ count = uart_circ_chars_pending(xmit);
+
+ if(count > mtpt->port.fifosize)
+ {
+ count = mtpt->port.fifosize;
+ }
+
+ printk("[%d] mdmode: %x\n", mtpt->port.line, mtpt->port.mdmode);
+ do {
+#if 0
+ /* check multi-drop mode */
+ if ((mtpt->port.mdmode & (MDMODE_ENABLE | MDMODE_ADDR)) == (MDMODE_ENABLE | MDMODE_ADDR))
+ {
+ printk("send address\n");
+ /* send multi-drop address */
+ serial_out(mtpt, UART_SCR, xmit->buf[xmit->tail]);
+ }
+ else
+#endif
+ {
+ serial_out(mtpt, UART_TX, xmit->buf[xmit->tail]);
+ }
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ mtpt->port.icount.tx++;
+ } while (--count > 0);
+}
+
+
+
+static _INLINE_ void check_modem_status(struct mp_port *mtpt)
+{
+ int status;
+
+ status = serial_in(mtpt, UART_MSR);
+
+ if ((status & UART_MSR_ANY_DELTA) == 0)
+ return;
+
+ if (status & UART_MSR_TERI)
+ mtpt->port.icount.rng++;
+ if (status & UART_MSR_DDSR)
+ mtpt->port.icount.dsr++;
+ if (status & UART_MSR_DDCD)
+ sb_uart_handle_dcd_change(&mtpt->port, status & UART_MSR_DCD);
+ if (status & UART_MSR_DCTS)
+ sb_uart_handle_cts_change(&mtpt->port, status & UART_MSR_CTS);
+
+ wake_up_interruptible(&mtpt->port.info->delta_msr_wait);
+}
+
+static inline void multi_handle_port(struct mp_port *mtpt)
+{
+ unsigned int status = serial_inp(mtpt, UART_LSR);
+
+ //printk("lsr: %x\n", status);
+
+ if ((status & UART_LSR_DR) || (status & UART_LSR_SPECIAL))
+ receive_chars(mtpt, &status);
+ check_modem_status(mtpt);
+ if (status & UART_LSR_THRE)
+ {
+ if ((mtpt->port.type == PORT_16C105X)
+ || (mtpt->port.type == PORT_16C105XA))
+ transmit_chars(mtpt);
+ else
+ {
+ if (mtpt->interface >= RS485NE)
+ uart_set_mctrl(&mtpt->port, TIOCM_RTS);
+
+ transmit_chars(mtpt);
+
+
+ if (mtpt->interface >= RS485NE)
+ {
+ while((status=serial_in(mtpt,UART_LSR) &0x60)!=0x60);
+ uart_clear_mctrl(&mtpt->port, TIOCM_RTS);
+ }
+ }
+ }
+}
+
+
+
+static irqreturn_t multi_interrupt(int irq, void *dev_id)
+{
+ struct irq_info *iinfo = dev_id;
+ struct list_head *lhead, *end = NULL;
+ int pass_counter = 0;
+
+
+ spin_lock(&iinfo->lock);
+
+ lhead = iinfo->head;
+ do {
+ struct mp_port *mtpt;
+ unsigned int iir;
+
+ mtpt = list_entry(lhead, struct mp_port, list);
+
+ iir = serial_in(mtpt, UART_IIR);
+ printk("intrrupt! port %d, iir 0x%x\n", mtpt->port.line, iir); //wlee
+ if (!(iir & UART_IIR_NO_INT))
+ {
+ printk("interrupt handle\n");
+ spin_lock(&mtpt->port.lock);
+ multi_handle_port(mtpt);
+ spin_unlock(&mtpt->port.lock);
+
+ end = NULL;
+ } else if (end == NULL)
+ end = lhead;
+
+ lhead = lhead->next;
+ if (lhead == iinfo->head && pass_counter++ > PASS_LIMIT)
+ {
+ printk(KERN_ERR "multi: too much work for "
+ "irq%d\n", irq);
+ printk( "multi: too much work for "
+ "irq%d\n", irq);
+ break;
+ }
+ } while (lhead != end);
+
+ spin_unlock(&iinfo->lock);
+
+
+ return IRQ_HANDLED;
+}
+
+static void serial_do_unlink(struct irq_info *i, struct mp_port *mtpt)
+{
+ spin_lock_irq(&i->lock);
+
+ if (!list_empty(i->head)) {
+ if (i->head == &mtpt->list)
+ i->head = i->head->next;
+ list_del(&mtpt->list);
+ } else {
+ i->head = NULL;
+ }
+
+ spin_unlock_irq(&i->lock);
+}
+
+static int serial_link_irq_chain(struct mp_port *mtpt)
+{
+ struct irq_info *i = irq_lists + mtpt->port.irq;
+ int ret, irq_flags = mtpt->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
+ spin_lock_irq(&i->lock);
+
+ if (i->head) {
+ list_add(&mtpt->list, i->head);
+ spin_unlock_irq(&i->lock);
+
+ ret = 0;
+ } else {
+ INIT_LIST_HEAD(&mtpt->list);
+ i->head = &mtpt->list;
+ spin_unlock_irq(&i->lock);
+
+ ret = request_irq(mtpt->port.irq, multi_interrupt,
+ irq_flags, "serial", i);
+ if (ret < 0)
+ serial_do_unlink(i, mtpt);
+ }
+
+ return ret;
+}
+
+
+
+
+static void serial_unlink_irq_chain(struct mp_port *mtpt)
+{
+ struct irq_info *i = irq_lists + mtpt->port.irq;
+
+ if (list_empty(i->head))
+ {
+ free_irq(mtpt->port.irq, i);
+ }
+ serial_do_unlink(i, mtpt);
+}
+
+static void multi_timeout(unsigned long data)
+{
+ struct mp_port *mtpt = (struct mp_port *)data;
+
+
+ spin_lock(&mtpt->port.lock);
+ multi_handle_port(mtpt);
+ spin_unlock(&mtpt->port.lock);
+
+ mod_timer(&mtpt->timer, jiffies+1 );
+}
+
+static unsigned int multi_tx_empty(struct sb_uart_port *port)
+{
+ struct mp_port *mtpt = (struct mp_port *)port;
+ unsigned long flags;
+ unsigned int ret;
+
+ spin_lock_irqsave(&mtpt->port.lock, flags);
+ ret = serial_in(mtpt, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
+ spin_unlock_irqrestore(&mtpt->port.lock, flags);
+
+ return ret;
+}
+
+
+static unsigned int multi_get_mctrl(struct sb_uart_port *port)
+{
+ struct mp_port *mtpt = (struct mp_port *)port;
+ unsigned char status;
+ unsigned int ret;
+
+ status = serial_in(mtpt, UART_MSR);
+
+ ret = 0;
+ if (status & UART_MSR_DCD)
+ ret |= TIOCM_CAR;
+ if (status & UART_MSR_RI)
+ ret |= TIOCM_RNG;
+ if (status & UART_MSR_DSR)
+ ret |= TIOCM_DSR;
+ if (status & UART_MSR_CTS)
+ ret |= TIOCM_CTS;
+ return ret;
+}
+
+static void multi_set_mctrl(struct sb_uart_port *port, unsigned int mctrl)
+{
+ struct mp_port *mtpt = (struct mp_port *)port;
+ unsigned char mcr = 0;
+
+ mctrl &= 0xff;
+
+ if (mctrl & TIOCM_RTS)
+ mcr |= UART_MCR_RTS;
+ if (mctrl & TIOCM_DTR)
+ mcr |= UART_MCR_DTR;
+ if (mctrl & TIOCM_OUT1)
+ mcr |= UART_MCR_OUT1;
+ if (mctrl & TIOCM_OUT2)
+ mcr |= UART_MCR_OUT2;
+ if (mctrl & TIOCM_LOOP)
+ mcr |= UART_MCR_LOOP;
+
+
+ serial_out(mtpt, UART_MCR, mcr);
+}
+
+
+static void multi_break_ctl(struct sb_uart_port *port, int break_state)
+{
+ struct mp_port *mtpt = (struct mp_port *)port;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mtpt->port.lock, flags);
+ if (break_state == -1)
+ mtpt->lcr |= UART_LCR_SBC;
+ else
+ mtpt->lcr &= ~UART_LCR_SBC;
+ serial_out(mtpt, UART_LCR, mtpt->lcr);
+ spin_unlock_irqrestore(&mtpt->port.lock, flags);
+}
+
+
+
+static int multi_startup(struct sb_uart_port *port)
+{
+ struct mp_port *mtpt = (struct mp_port *)port;
+ unsigned long flags;
+ int retval;
+
+ mtpt->capabilities = uart_config[mtpt->port.type].flags;
+ mtpt->mcr = 0;
+
+ if (mtpt->capabilities & UART_CLEAR_FIFO) {
+ serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO);
+ serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO |
+ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+ serial_outp(mtpt, UART_FCR, 0);
+ }
+
+ (void) serial_inp(mtpt, UART_LSR);
+ (void) serial_inp(mtpt, UART_RX);
+ (void) serial_inp(mtpt, UART_IIR);
+ (void) serial_inp(mtpt, UART_MSR);
+ //test-wlee 9-bit disable
+ serial_outp(mtpt, UART_MSR, 0);
+
+
+ if (!(mtpt->port.flags & UPF_BUGGY_UART) &&
+ (serial_inp(mtpt, UART_LSR) == 0xff)) {
+ printk("ttyS%d: LSR safety check engaged!\n", mtpt->port.line);
+ //return -ENODEV;
+ }
+
+ if ((!is_real_interrupt(mtpt->port.irq)) || (mtpt->poll_type==TYPE_POLL)) {
+ unsigned int timeout = mtpt->port.timeout;
+
+ timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
+
+ mtpt->timer.data = (unsigned long)mtpt;
+ mod_timer(&mtpt->timer, jiffies + timeout);
+ }
+ else
+ {
+ retval = serial_link_irq_chain(mtpt);
+ if (retval)
+ return retval;
+ }
+
+ serial_outp(mtpt, UART_LCR, UART_LCR_WLEN8);
+
+ spin_lock_irqsave(&mtpt->port.lock, flags);
+ if ((is_real_interrupt(mtpt->port.irq))||(mtpt->poll_type==TYPE_INTERRUPT))
+ mtpt->port.mctrl |= TIOCM_OUT2;
+
+ multi_set_mctrl(&mtpt->port, mtpt->port.mctrl);
+ spin_unlock_irqrestore(&mtpt->port.lock, flags);
+
+
+ mtpt->ier = UART_IER_RLSI | UART_IER_RDI;
+ serial_outp(mtpt, UART_IER, mtpt->ier);
+
+ (void) serial_inp(mtpt, UART_LSR);
+ (void) serial_inp(mtpt, UART_RX);
+ (void) serial_inp(mtpt, UART_IIR);
+ (void) serial_inp(mtpt, UART_MSR);
+
+ return 0;
+}
+
+
+
+static void multi_shutdown(struct sb_uart_port *port)
+{
+ struct mp_port *mtpt = (struct mp_port *)port;
+ unsigned long flags;
+
+
+ mtpt->ier = 0;
+ serial_outp(mtpt, UART_IER, 0);
+
+ spin_lock_irqsave(&mtpt->port.lock, flags);
+ mtpt->port.mctrl &= ~TIOCM_OUT2;
+
+ multi_set_mctrl(&mtpt->port, mtpt->port.mctrl);
+ spin_unlock_irqrestore(&mtpt->port.lock, flags);
+
+ serial_out(mtpt, UART_LCR, serial_inp(mtpt, UART_LCR) & ~UART_LCR_SBC);
+ serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO |
+ UART_FCR_CLEAR_RCVR |
+ UART_FCR_CLEAR_XMIT);
+ serial_outp(mtpt, UART_FCR, 0);
+
+
+ (void) serial_in(mtpt, UART_RX);
+
+ if ((!is_real_interrupt(mtpt->port.irq))||(mtpt->poll_type==TYPE_POLL))
+ {
+ del_timer_sync(&mtpt->timer);
+ }
+ else
+ {
+ serial_unlink_irq_chain(mtpt);
+ }
+}
+
+
+
+static unsigned int multi_get_divisor(struct sb_uart_port *port, unsigned int baud)
+{
+ unsigned int quot;
+
+ if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
+ baud == (port->uartclk/4))
+ quot = 0x8001;
+ else if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
+ baud == (port->uartclk/8))
+ quot = 0x8002;
+ else
+ quot = sb_uart_get_divisor(port, baud);
+
+ return quot;
+}
+
+
+
+
+static void multi_set_termios(struct sb_uart_port *port, struct MP_TERMIOS *termios, struct MP_TERMIOS *old)
+{
+ struct mp_port *mtpt = (struct mp_port *)port;
+ unsigned char cval, fcr = 0;
+ unsigned long flags;
+ unsigned int baud, quot;
+
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+ cval = 0x00;
+ break;
+ case CS6:
+ cval = 0x01;
+ break;
+ case CS7:
+ cval = 0x02;
+ break;
+ default:
+ case CS8:
+ cval = 0x03;
+ break;
+ }
+
+ if (termios->c_cflag & CSTOPB)
+ cval |= 0x04;
+ if (termios->c_cflag & PARENB)
+ cval |= UART_LCR_PARITY;
+ if (!(termios->c_cflag & PARODD))
+ cval |= UART_LCR_EPAR;
+
+#ifdef CMSPAR
+ if (termios->c_cflag & CMSPAR)
+ cval |= UART_LCR_SPAR;
+#endif
+
+ baud = sb_uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
+ quot = multi_get_divisor(port, baud);
+
+ if (mtpt->capabilities & UART_USE_FIFO) {
+ //if (baud < 2400)
+ // fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
+ //else
+ // fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
+
+ // fcr = UART_FCR_ENABLE_FIFO | 0x90;
+ fcr = fcr_arr[mtpt->port.line];
+ }
+
+ spin_lock_irqsave(&mtpt->port.lock, flags);
+
+ sb_uart_update_timeout(port, termios->c_cflag, baud);
+
+ mtpt->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+ if (termios->c_iflag & INPCK)
+ mtpt->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+ if (termios->c_iflag & (BRKINT | PARMRK))
+ mtpt->port.read_status_mask |= UART_LSR_BI;
+
+ mtpt->port.ignore_status_mask = 0;
+ if (termios->c_iflag & IGNPAR)
+ mtpt->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
+ if (termios->c_iflag & IGNBRK) {
+ mtpt->port.ignore_status_mask |= UART_LSR_BI;
+ if (termios->c_iflag & IGNPAR)
+ mtpt->port.ignore_status_mask |= UART_LSR_OE;
+ }
+
+ if ((termios->c_cflag & CREAD) == 0)
+ mtpt->port.ignore_status_mask |= UART_LSR_DR;
+
+ mtpt->ier &= ~UART_IER_MSI;
+ if (UART_ENABLE_MS(&mtpt->port, termios->c_cflag))
+ mtpt->ier |= UART_IER_MSI;
+
+ serial_out(mtpt, UART_IER, mtpt->ier);
+
+ if (mtpt->capabilities & UART_STARTECH) {
+ serial_outp(mtpt, UART_LCR, 0xBF);
+ serial_outp(mtpt, UART_EFR,
+ termios->c_cflag & CRTSCTS ? UART_EFR_CTS :0);
+ }
+
+ serial_outp(mtpt, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
+
+ serial_outp(mtpt, UART_DLL, quot & 0xff); /* LS of divisor */
+ serial_outp(mtpt, UART_DLM, quot >> 8); /* MS of divisor */
+
+ serial_outp(mtpt, UART_LCR, cval); /* reset DLAB */
+ mtpt->lcr = cval; /* Save LCR */
+
+ if (fcr & UART_FCR_ENABLE_FIFO) {
+ /* emulated UARTs (Lucent Venus 167x) need two steps */
+ serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO);
+ }
+
+ serial_outp(mtpt, UART_FCR, fcr); /* set fcr */
+
+
+ if ((mtpt->port.type == PORT_16C105X)
+ || (mtpt->port.type == PORT_16C105XA))
+ {
+ if(deep[mtpt->port.line]!=0)
+ set_deep_fifo(port, ENABLE);
+
+ if (mtpt->interface != RS232)
+ set_auto_rts(port,mtpt->interface);
+
+ }
+ else
+ {
+ if (mtpt->interface >= RS485NE)
+ {
+ uart_clear_mctrl(&mtpt->port, TIOCM_RTS);
+ }
+ }
+
+ if(mtpt->device->device_id == PCI_DEVICE_ID_MP4M)
+ {
+ SendATCommand(mtpt);
+ printk("SendATCommand\n");
+ }
+ multi_set_mctrl(&mtpt->port, mtpt->port.mctrl);
+ spin_unlock_irqrestore(&mtpt->port.lock, flags);
+}
+
+static void multi_pm(struct sb_uart_port *port, unsigned int state, unsigned int oldstate)
+{
+ struct mp_port *mtpt = (struct mp_port *)port;
+ if (state) {
+ if (mtpt->capabilities & UART_STARTECH) {
+ serial_outp(mtpt, UART_LCR, 0xBF);
+ serial_outp(mtpt, UART_EFR, UART_EFR_ECB);
+ serial_outp(mtpt, UART_LCR, 0);
+ serial_outp(mtpt, UART_IER, UART_IERX_SLEEP);
+ serial_outp(mtpt, UART_LCR, 0xBF);
+ serial_outp(mtpt, UART_EFR, 0);
+ serial_outp(mtpt, UART_LCR, 0);
+ }
+
+ if (mtpt->pm)
+ mtpt->pm(port, state, oldstate);
+ }
+ else
+ {
+ if (mtpt->capabilities & UART_STARTECH) {
+ serial_outp(mtpt, UART_LCR, 0xBF);
+ serial_outp(mtpt, UART_EFR, UART_EFR_ECB);
+ serial_outp(mtpt, UART_LCR, 0);
+ serial_outp(mtpt, UART_IER, 0);
+ serial_outp(mtpt, UART_LCR, 0xBF);
+ serial_outp(mtpt, UART_EFR, 0);
+ serial_outp(mtpt, UART_LCR, 0);
+ }
+
+ if (mtpt->pm)
+ mtpt->pm(port, state, oldstate);
+ }
+}
+
+static void multi_release_std_resource(struct mp_port *mtpt)
+{
+ unsigned int size = 8 << mtpt->port.regshift;
+
+ switch (mtpt->port.iotype) {
+ case UPIO_MEM:
+ if (!mtpt->port.mapbase)
+ break;
+
+ if (mtpt->port.flags & UPF_IOREMAP) {
+ iounmap(mtpt->port.membase);
+ mtpt->port.membase = NULL;
+ }
+
+ release_mem_region(mtpt->port.mapbase, size);
+ break;
+
+ case UPIO_HUB6:
+ case UPIO_PORT:
+ release_region(mtpt->port.iobase,size);
+ break;
+ }
+}
+
+static void multi_release_port(struct sb_uart_port *port)
+{
+}
+
+static int multi_request_port(struct sb_uart_port *port)
+{
+ return 0;
+}
+
+static void multi_config_port(struct sb_uart_port *port, int flags)
+{
+ struct mp_port *mtpt = (struct mp_port *)port;
+ int probeflags = PROBE_ANY;
+
+ if (flags & UART_CONFIG_TYPE)
+ autoconfig(mtpt, probeflags);
+ if (mtpt->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
+ autoconfig_irq(mtpt);
+
+ if (mtpt->port.type == PORT_UNKNOWN)
+ multi_release_std_resource(mtpt);
+}
+
+static int multi_verify_port(struct sb_uart_port *port, struct serial_struct *ser)
+{
+ if (ser->irq >= NR_IRQS || ser->irq < 0 ||
+ ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
+ ser->type == PORT_STARTECH)
+ return -EINVAL;
+ return 0;
+}
+
+static const char * multi_type(struct sb_uart_port *port)
+{
+ int type = port->type;
+
+ if (type >= ARRAY_SIZE(uart_config))
+ type = 0;
+ return uart_config[type].name;
+}
+
+static struct sb_uart_ops multi_pops = {
+ .tx_empty = multi_tx_empty,
+ .set_mctrl = multi_set_mctrl,
+ .get_mctrl = multi_get_mctrl,
+ .stop_tx = multi_stop_tx,
+ .start_tx = multi_start_tx,
+ .stop_rx = multi_stop_rx,
+ .enable_ms = multi_enable_ms,
+ .break_ctl = multi_break_ctl,
+ .startup = multi_startup,
+ .shutdown = multi_shutdown,
+ .set_termios = multi_set_termios,
+ .pm = multi_pm,
+ .type = multi_type,
+ .release_port = multi_release_port,
+ .request_port = multi_request_port,
+ .config_port = multi_config_port,
+ .verify_port = multi_verify_port,
+};
+
+static struct uart_driver multi_reg = {
+ .owner = THIS_MODULE,
+ .driver_name = "goldel_tulip",
+ .dev_name = "ttyMP",
+ .major = SB_TTY_MP_MAJOR,
+ .minor = 0,
+ .nr = MAX_MP_PORT,
+ .cons = NULL,
+};
+
+static void __init multi_init_ports(void)
+{
+ struct mp_port *mtpt;
+ static int first = 1;
+ int i,j,k;
+ unsigned char osc;
+ unsigned char b_ret = 0;
+ static struct mp_device_t * sbdev;
+
+ if (!first)
+ return;
+ first = 0;
+
+ mtpt = multi_ports;
+
+ for (k=0;k<NR_BOARD;k++)
+ {
+ sbdev = &mp_devs[k];
+
+ for (i = 0; i < sbdev->nr_ports; i++, mtpt++)
+ {
+ mtpt->device = sbdev;
+ mtpt->port.iobase = sbdev->uart_access_addr + 8*i;
+ mtpt->port.irq = sbdev->irq;
+ if ( ((sbdev->device_id == PCI_DEVICE_ID_MP4)&&(sbdev->revision==0x91)))
+ mtpt->interface_config_addr = sbdev->option_reg_addr + 0x08 + i;
+ else if (sbdev->revision == 0xc0)
+ mtpt->interface_config_addr = sbdev->option_reg_addr + 0x08 + (i & 0x1);
+ else
+ mtpt->interface_config_addr = sbdev->option_reg_addr + 0x08 + i/8;
+
+ mtpt->option_base_addr = sbdev->option_reg_addr;
+
+ mtpt->poll_type = sbdev->poll_type;
+
+ mtpt->port.uartclk = BASE_BAUD * 16;
+
+ /* get input clock infomation */
+ osc = inb(sbdev->option_reg_addr + MP_OPTR_DIR0 + i/8) & 0x0F;
+ if (osc==0x0f)
+ osc = 0;
+ for(j=0;j<osc;j++)
+ mtpt->port.uartclk *= 2;
+ mtpt->port.flags |= STD_COM_FLAGS | UPF_SHARE_IRQ ;
+ mtpt->port.iotype = UPIO_PORT;
+ mtpt->port.ops = &multi_pops;
+
+ if (sbdev->revision == 0xc0)
+ {
+ /* for SB16C1053APCI */
+ b_ret = sb1053a_get_interface(mtpt, i);
+ }
+ else
+ {
+ b_ret = read_option_register(mtpt,(MP_OPTR_IIR0 + i/8));
+ printk("IIR_RET = %x\n",b_ret);
+ }
+
+ if(IIR_RS232 == (b_ret & IIR_RS232))
+ {
+ mtpt->interface = RS232;
+ }
+ if(IIR_RS422 == (b_ret & IIR_RS422))
+ {
+ mtpt->interface = RS422PTP;
+ }
+ if(IIR_RS485 == (b_ret & IIR_RS485))
+ {
+ mtpt->interface = RS485NE;
+ }
+ }
+ }
+}
+
+static void __init multi_register_ports(struct uart_driver *drv)
+{
+ int i;
+
+ multi_init_ports();
+
+ for (i = 0; i < NR_PORTS; i++) {
+ struct mp_port *mtpt = &multi_ports[i];
+
+ mtpt->port.line = i;
+ mtpt->port.ops = &multi_pops;
+ init_timer(&mtpt->timer);
+ mtpt->timer.function = multi_timeout;
+ mp_add_one_port(drv, &mtpt->port);
+ }
+}
+
+/**
+ * pci_remap_base - remap BAR value of pci device
+ *
+ * PARAMETERS
+ * pcidev - pci_dev structure address
+ * offset - BAR offset PCI_BASE_ADDRESS_0 ~ PCI_BASE_ADDRESS_4
+ * address - address to be changed BAR value
+ * size - size of address space
+ *
+ * RETURNS
+ * If this function performs successful, it returns 0. Otherwise, It returns -1.
+ */
+static int pci_remap_base(struct pci_dev *pcidev, unsigned int offset,
+ unsigned int address, unsigned int size)
+{
+#if 0
+ struct resource *root;
+ unsigned index = (offset - 0x10) >> 2;
+#endif
+
+ pci_write_config_dword(pcidev, offset, address);
+#if 0
+ root = pcidev->resource[index].parent;
+ release_resource(&pcidev->resource[index]);
+ address &= ~0x1;
+ pcidev->resource[index].start = address;
+ pcidev->resource[index].end = address + size - 1;
+
+ if (request_resource(root, &pcidev->resource[index]) != NULL)
+ {
+ printk(KERN_ERR "pci remap conflict!! 0x%x\n", address);
+ return (-1);
+ }
+#endif
+
+ return (0);
+}
+
+static int init_mp_dev(struct pci_dev *pcidev, mppcibrd_t brd)
+{
+ static struct mp_device_t * sbdev = mp_devs;
+ unsigned long addr = 0;
+ int j;
+ struct resource * ret = NULL;
+
+ sbdev->device_id = brd.device_id;
+ pci_read_config_byte(pcidev, PCI_CLASS_REVISION, &(sbdev->revision));
+ sbdev->name = brd.name;
+ sbdev->uart_access_addr = pcidev->resource[0].start & PCI_BASE_ADDRESS_IO_MASK;
+
+ /* check revision. The SB16C1053APCI's option i/o address is BAR4 */
+ if (sbdev->revision == 0xc0)
+ {
+ /* SB16C1053APCI */
+ sbdev->option_reg_addr = pcidev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK;
+ }
+ else
+ {
+ sbdev->option_reg_addr = pcidev->resource[1].start & PCI_BASE_ADDRESS_IO_MASK;
+ }
+#if 1
+ if (sbdev->revision == 0xc0)
+ {
+ outb(0x00, sbdev->option_reg_addr + MP_OPTR_GPOCR);
+ inb(sbdev->option_reg_addr + MP_OPTR_GPOCR);
+ outb(0x83, sbdev->option_reg_addr + MP_OPTR_GPOCR);
+ }
+#endif
+
+ sbdev->irq = pcidev->irq;
+
+ if ((brd.device_id & 0x0800) || !(brd.device_id &0xff00))
+ {
+ sbdev->poll_type = TYPE_INTERRUPT;
+ }
+ else
+ {
+ sbdev->poll_type = TYPE_POLL;
+ }
+
+ /* codes which is specific to each board*/
+ switch(brd.device_id){
+ case PCI_DEVICE_ID_MP1 :
+ case PCIE_DEVICE_ID_MP1 :
+ case PCIE_DEVICE_ID_MP1E :
+ case PCIE_DEVICE_ID_GT_MP1 :
+ sbdev->nr_ports = 1;
+ break;
+ case PCI_DEVICE_ID_MP2 :
+ case PCIE_DEVICE_ID_MP2 :
+ case PCIE_DEVICE_ID_GT_MP2 :
+ case PCIE_DEVICE_ID_MP2B :
+ case PCIE_DEVICE_ID_MP2E :
+ sbdev->nr_ports = 2;
+
+ /* serial base address remap */
+ if (sbdev->revision == 0xc0)
+ {
+ int prev_port_addr = 0;
+
+ pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &prev_port_addr);
+ pci_remap_base(pcidev, PCI_BASE_ADDRESS_1, prev_port_addr + 8, 8);
+ }
+ break;
+ case PCI_DEVICE_ID_MP4 :
+ case PCI_DEVICE_ID_MP4A :
+ case PCIE_DEVICE_ID_MP4 :
+ case PCI_DEVICE_ID_GT_MP4 :
+ case PCI_DEVICE_ID_GT_MP4A :
+ case PCIE_DEVICE_ID_GT_MP4 :
+ case PCI_DEVICE_ID_MP4M :
+ case PCIE_DEVICE_ID_MP4B :
+ sbdev->nr_ports = 4;
+
+ if(sbdev->revision == 0x91){
+ sbdev->reserved_addr[0] = pcidev->resource[0].start & PCI_BASE_ADDRESS_IO_MASK;
+ outb(0x03 , sbdev->reserved_addr[0] + 0x01);
+ outb(0x03 , sbdev->reserved_addr[0] + 0x02);
+ outb(0x01 , sbdev->reserved_addr[0] + 0x20);
+ outb(0x00 , sbdev->reserved_addr[0] + 0x21);
+ request_region(sbdev->reserved_addr[0], 32, sbdev->name);
+ sbdev->uart_access_addr = pcidev->resource[1].start & PCI_BASE_ADDRESS_IO_MASK;
+ sbdev->option_reg_addr = pcidev->resource[2].start & PCI_BASE_ADDRESS_IO_MASK;
+ }
+
+ /* SB16C1053APCI */
+ if (sbdev->revision == 0xc0)
+ {
+ int prev_port_addr = 0;
+
+ pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &prev_port_addr);
+ pci_remap_base(pcidev, PCI_BASE_ADDRESS_1, prev_port_addr + 8, 8);
+ pci_remap_base(pcidev, PCI_BASE_ADDRESS_2, prev_port_addr + 16, 8);
+ pci_remap_base(pcidev, PCI_BASE_ADDRESS_3, prev_port_addr + 24, 8);
+ }
+ break;
+ case PCI_DEVICE_ID_MP6 :
+ case PCI_DEVICE_ID_MP6A :
+ case PCI_DEVICE_ID_GT_MP6 :
+ case PCI_DEVICE_ID_GT_MP6A :
+ sbdev->nr_ports = 6;
+
+ /* SB16C1053APCI */
+ if (sbdev->revision == 0xc0)
+ {
+ int prev_port_addr = 0;
+
+ pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &prev_port_addr);
+ pci_remap_base(pcidev, PCI_BASE_ADDRESS_1, prev_port_addr + 8, 8);
+ pci_remap_base(pcidev, PCI_BASE_ADDRESS_2, prev_port_addr + 16, 16);
+ pci_remap_base(pcidev, PCI_BASE_ADDRESS_3, prev_port_addr + 32, 16);
+ }
+ break;
+ case PCI_DEVICE_ID_MP8 :
+ case PCIE_DEVICE_ID_MP8 :
+ case PCI_DEVICE_ID_GT_MP8 :
+ case PCIE_DEVICE_ID_GT_MP8 :
+ case PCIE_DEVICE_ID_MP8B :
+ sbdev->nr_ports = 8;
+ break;
+ case PCI_DEVICE_ID_MP32 :
+ case PCIE_DEVICE_ID_MP32 :
+ case PCI_DEVICE_ID_GT_MP32 :
+ case PCIE_DEVICE_ID_GT_MP32 :
+ {
+ int portnum_hex=0;
+ portnum_hex = inb(sbdev->option_reg_addr);
+ sbdev->nr_ports = ((portnum_hex/16)*10) + (portnum_hex % 16);
+ }
+ break;
+ case PCI_DEVICE_ID_MP2S1P :
+ sbdev->nr_ports = 2;
+
+ /* SB16C1053APCI */
+ if (sbdev->revision == 0xc0)
+ {
+ int prev_port_addr = 0;
+
+ pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &prev_port_addr);
+ pci_remap_base(pcidev, PCI_BASE_ADDRESS_1, prev_port_addr + 8, 8);
+ }
+
+ /* add PC compatible parallel port */
+ parport_pc_probe_port(pcidev->resource[2].start, pcidev->resource[3].start, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &pcidev->dev, 0);
+ break;
+ case PCI_DEVICE_ID_MP1P :
+ /* add PC compatible parallel port */
+ parport_pc_probe_port(pcidev->resource[2].start, pcidev->resource[3].start, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &pcidev->dev, 0);
+ break;
+ }
+
+ ret = request_region(sbdev->uart_access_addr, (8*sbdev->nr_ports), sbdev->name);
+
+ if (sbdev->revision == 0xc0)
+ {
+ ret = request_region(sbdev->option_reg_addr, 0x40, sbdev->name);
+ }
+ else
+ {
+ ret = request_region(sbdev->option_reg_addr, 0x20, sbdev->name);
+ }
+
+
+ NR_BOARD++;
+ NR_PORTS += sbdev->nr_ports;
+
+ /* Enable PCI interrupt */
+ addr = sbdev->option_reg_addr + MP_OPTR_IMR0;
+ for(j=0; j < (sbdev->nr_ports/8)+1; j++)
+ {
+ if (sbdev->poll_type == TYPE_INTERRUPT)
+ {
+ outb(0xff,addr +j);
+ }
+ }
+ sbdev++;
+
+ return 0;
+}
+
+static int __init multi_init(void)
+{
+ int ret, i;
+ struct pci_dev *dev = NULL;
+
+ if(fcr_count==0)
+ {
+ for(i=0;i<256;i++)
+ {
+ fcr_arr[i] = 0x01;
+
+ }
+ }
+ if(deep_count==0)
+ {
+ for(i=0;i<256;i++)
+ {
+ deep[i] = 1;
+
+ }
+ }
+ if(rtr_count==0)
+ {
+ for(i=0;i<256;i++)
+ {
+ rtr[i] = 0x10;
+ }
+ }
+ if(ttr_count==0)
+ {
+ for(i=0;i<256;i++)
+ {
+ ttr[i] = 0x38;
+ }
+ }
+
+
+printk("MULTI INIT\n");
+ for( i=0; i< mp_nrpcibrds; i++)
+ {
+
+ while( (dev = pci_get_device(mp_pciboards[i].vendor_id, mp_pciboards[i].device_id, dev) ) )
+
+ {
+printk("FOUND~~~\n");
+// Cent OS bug fix
+// if (mp_pciboards[i].device_id & 0x0800)
+ {
+ int status;
+ pci_disable_device(dev);
+ status = pci_enable_device(dev);
+
+ if (status != 0)
+ {
+ printk("Multiport Board Enable Fail !\n\n");
+ status = -ENXIO;
+ return status;
+ }
+ }
+
+ init_mp_dev(dev, mp_pciboards[i]);
+ }
+ }
+
+ for (i = 0; i < NR_IRQS; i++)
+ spin_lock_init(&irq_lists[i].lock);
+
+ ret = mp_register_driver(&multi_reg);
+
+ if (ret >= 0)
+ multi_register_ports(&multi_reg);
+
+ return ret;
+}
+
+static void __exit multi_exit(void)
+{
+ int i;
+
+ for (i = 0; i < NR_PORTS; i++)
+ mp_remove_one_port(&multi_reg, &multi_ports[i].port);
+
+ mp_unregister_driver(&multi_reg);
+}
+
+module_init(multi_init);
+module_exit(multi_exit);
+
+MODULE_DESCRIPTION("SystemBase Multiport PCI/PCIe CORE");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/sb105x/sb_pci_mp.h b/drivers/staging/sb105x/sb_pci_mp.h
new file mode 100644
index 00000000000..f33efde07b9
--- /dev/null
+++ b/drivers/staging/sb105x/sb_pci_mp.h
@@ -0,0 +1,293 @@
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/serial_reg.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/tty_driver.h>
+#include <linux/pci.h>
+#include <linux/circ_buf.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/segment.h>
+#include <asm/serial.h>
+#include <linux/interrupt.h>
+
+
+#include <linux/parport.h>
+#include <linux/ctype.h>
+#include <linux/poll.h>
+
+
+#define MP_TERMIOS ktermios
+
+#include "sb_mp_register.h"
+#include "sb_ser_core.h"
+
+#define DRIVER_VERSION "1.1"
+#define DRIVER_DATE "2012/01/05"
+#define DRIVER_AUTHOR "SYSTEMBASE<tech@sysbas.com>"
+#define DRIVER_DESC "SystemBase PCI/PCIe Multiport Core"
+
+#define SB_TTY_MP_MAJOR 54
+#define PCI_VENDOR_ID_MULTIPORT 0x14A1
+
+#define PCI_DEVICE_ID_MP1 0x4d01
+#define PCI_DEVICE_ID_MP2 0x4d02
+#define PCI_DEVICE_ID_MP4 0x4d04
+#define PCI_DEVICE_ID_MP4A 0x4d54
+#define PCI_DEVICE_ID_MP6 0x4d06
+#define PCI_DEVICE_ID_MP6A 0x4d56
+#define PCI_DEVICE_ID_MP8 0x4d08
+#define PCI_DEVICE_ID_MP32 0x4d32
+/* Parallel port */
+#define PCI_DEVICE_ID_MP1P 0x4301
+#define PCI_DEVICE_ID_MP2S1P 0x4303
+
+#define PCIE_DEVICE_ID_MP1 0x4501
+#define PCIE_DEVICE_ID_MP2 0x4502
+#define PCIE_DEVICE_ID_MP4 0x4504
+#define PCIE_DEVICE_ID_MP8 0x4508
+#define PCIE_DEVICE_ID_MP32 0x4532
+
+#define PCIE_DEVICE_ID_MP1E 0x4e01
+#define PCIE_DEVICE_ID_MP2E 0x4e02
+#define PCIE_DEVICE_ID_MP2B 0x4b02
+#define PCIE_DEVICE_ID_MP4B 0x4b04
+#define PCIE_DEVICE_ID_MP8B 0x4b08
+
+#define PCI_DEVICE_ID_GT_MP4 0x0004
+#define PCI_DEVICE_ID_GT_MP4A 0x0054
+#define PCI_DEVICE_ID_GT_MP6 0x0006
+#define PCI_DEVICE_ID_GT_MP6A 0x0056
+#define PCI_DEVICE_ID_GT_MP8 0x0008
+#define PCI_DEVICE_ID_GT_MP32 0x0032
+
+#define PCIE_DEVICE_ID_GT_MP1 0x1501
+#define PCIE_DEVICE_ID_GT_MP2 0x1502
+#define PCIE_DEVICE_ID_GT_MP4 0x1504
+#define PCIE_DEVICE_ID_GT_MP8 0x1508
+#define PCIE_DEVICE_ID_GT_MP32 0x1532
+
+#define PCI_DEVICE_ID_MP4M 0x4604 //modem
+
+#define MAX_MP_DEV 8
+#define BD_MAX_PORT 32 /* Max serial port in one board */
+#define MAX_MP_PORT 256 /* Max serial port in one PC */
+
+#define PORT_16C105XA 3
+#define PORT_16C105X 2
+#define PORT_16C55X 1
+
+#define ENABLE 1
+#define DISABLE 0
+
+/* ioctls */
+#define TIOCGNUMOFPORT 0x545F
+#define TIOCSMULTIECHO 0x5440
+#define TIOCSPTPNOECHO 0x5441
+
+#define TIOCGOPTIONREG 0x5461
+#define TIOCGDISABLEIRQ 0x5462
+#define TIOCGENABLEIRQ 0x5463
+#define TIOCGSOFTRESET 0x5464
+#define TIOCGSOFTRESETR 0x5465
+#define TIOCGREGINFO 0x5466
+#define TIOCGGETLSR 0x5467
+#define TIOCGGETDEVID 0x5468
+#define TIOCGGETBDNO 0x5469
+#define TIOCGGETINTERFACE 0x546A
+#define TIOCGGETREV 0x546B
+#define TIOCGGETNRPORTS 0x546C
+#define TIOCGGETPORTTYPE 0x546D
+#define GETDEEPFIFO 0x54AA
+#define SETDEEPFIFO 0x54AB
+#define SETFCR 0x54BA
+#define SETTTR 0x54B1
+#define SETRTR 0x54B2
+#define GETTTR 0x54B3
+#define GETRTR 0x54B4
+
+/* multi-drop mode related ioctl commands */
+#define TIOCSMULTIDROP 0x5470
+#define TIOCSMDADDR 0x5471
+#define TIOCGMDADDR 0x5472
+#define TIOCSENDADDR 0x5473
+
+
+/* serial interface */
+#define RS232 1
+#define RS422PTP 2
+#define RS422MD 3
+#define RS485NE 4
+#define RS485ECHO 5
+
+#define serial_inp(up, offset) serial_in(up, offset)
+#define serial_outp(up, offset, value) serial_out(up, offset, value)
+
+#define PASS_LIMIT 256
+#define is_real_interrupt(irq) ((irq) != 0)
+
+#define PROBE_ANY (~0)
+
+static DEFINE_MUTEX(mp_mutex);
+#define MP_MUTEX_LOCK(x) mutex_lock(&(x))
+#define MP_MUTEX_UNLOCK(x) mutex_unlock(&(x))
+#define MP_STATE_LOCK(x) mutex_lock(&((x)->mutex))
+#define MP_STATE_UNLOCK(x) mutex_unlock(&((x)->mutex))
+
+
+#define UART_LSR_SPECIAL 0x1E
+
+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
+#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0))
+
+
+//#define MP_DEBUG 1
+#undef MP_DEBUG
+
+#ifdef MP_DEBUG
+#define DPRINTK(x...) printk(x)
+#else
+#define DPRINTK(x...) do { } while (0)
+#endif
+
+#ifdef MP_DEBUG
+#define DEBUG_AUTOCONF(fmt...) printk(fmt)
+#else
+#define DEBUG_AUTOCONF(fmt...) do { } while (0)
+#endif
+
+#ifdef MP_DEBUG
+#define DEBUG_INTR(fmt...) printk(fmt)
+#else
+#define DEBUG_INTR(fmt...) do { } while (0)
+#endif
+
+#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
+#define SERIAL_INLINE
+#endif
+#ifdef SERIAL_INLINE
+#define _INLINE_ inline
+#else
+#define _INLINE_
+#endif
+
+#define TYPE_POLL 1
+#define TYPE_INTERRUPT 2
+
+
+struct mp_device_t {
+ unsigned short device_id;
+ unsigned char revision;
+ char *name;
+ unsigned long uart_access_addr;
+ unsigned long option_reg_addr;
+ unsigned long reserved_addr[4];
+ int irq;
+ int nr_ports;
+ int poll_type;
+};
+
+typedef struct mppcibrd {
+ char *name;
+ unsigned short vendor_id;
+ unsigned short device_id;
+} mppcibrd_t;
+
+static mppcibrd_t mp_pciboards[] = {
+
+ { "Multi-1 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP1} ,
+ { "Multi-2 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP2} ,
+ { "Multi-4 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP4} ,
+ { "Multi-4 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP4A} ,
+ { "Multi-6 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP6} ,
+ { "Multi-6 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP6A} ,
+ { "Multi-8 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP8} ,
+ { "Multi-32 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP32} ,
+
+ { "Multi-1P PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP1P} ,
+ { "Multi-2S1P PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP2S1P} ,
+
+ { "Multi-4(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP4} ,
+ { "Multi-4(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP4A} ,
+ { "Multi-6(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP6} ,
+ { "Multi-6(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP6A} ,
+ { "Multi-8(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP8} ,
+ { "Multi-32(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP32} ,
+
+ { "Multi-1 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP1} ,
+ { "Multi-2 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP2} ,
+ { "Multi-4 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP4} ,
+ { "Multi-8 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP8} ,
+ { "Multi-32 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP32} ,
+
+ { "Multi-1 PCIe E", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP1E} ,
+ { "Multi-2 PCIe E", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP2E} ,
+ { "Multi-2 PCIe B", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP2B} ,
+ { "Multi-4 PCIe B", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP4B} ,
+ { "Multi-8 PCIe B", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP8B} ,
+
+ { "Multi-1(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP1} ,
+ { "Multi-2(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP2} ,
+ { "Multi-4(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP4} ,
+ { "Multi-8(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP8} ,
+ { "Multi-32(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP32} ,
+
+ { "Multi-4M PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP4M} ,
+};
+
+struct mp_port {
+ struct sb_uart_port port;
+
+ struct timer_list timer; /* "no irq" timer */
+ struct list_head list; /* ports on this IRQ */
+ unsigned int capabilities; /* port capabilities */
+ unsigned short rev;
+ unsigned char acr;
+ unsigned char ier;
+ unsigned char lcr;
+ unsigned char mcr;
+ unsigned char mcr_mask; /* mask of user bits */
+ unsigned char mcr_force; /* mask of forced bits */
+ unsigned char lsr_break_flag;
+
+ void (*pm)(struct sb_uart_port *port,
+ unsigned int state, unsigned int old);
+ struct mp_device_t *device;
+ unsigned long interface_config_addr;
+ unsigned long option_base_addr;
+ unsigned char interface;
+ unsigned char poll_type;
+};
+
+struct irq_info {
+ spinlock_t lock;
+ struct list_head *head;
+};
+
+struct sb105x_uart_config {
+ char *name;
+ int dfl_xmit_fifo_size;
+ int flags;
+};
+
+static const struct sb105x_uart_config uart_config[] = {
+ { "unknown", 1, 0 },
+ { "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO },
+ { "SB16C1050", 128, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
+ { "SB16C1050A", 128, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
+};
+
+
+
diff --git a/drivers/staging/sb105x/sb_ser_core.h b/drivers/staging/sb105x/sb_ser_core.h
new file mode 100644
index 00000000000..c8fb9917329
--- /dev/null
+++ b/drivers/staging/sb105x/sb_ser_core.h
@@ -0,0 +1,368 @@
+#include <linux/wait.h>
+
+#define UART_CONFIG_TYPE (1 << 0)
+#define UART_CONFIG_IRQ (1 << 1)
+#define UPIO_PORT (0)
+#define UPIO_HUB6 (1)
+#define UPIO_MEM (2)
+#define UPIO_MEM32 (3)
+#define UPIO_AU (4) /* Au1x00 type IO */
+#define UPIO_TSI (5) /* Tsi108/109 type IO */
+#define UPF_FOURPORT (1 << 1)
+#define UPF_SAK (1 << 2)
+#define UPF_SPD_MASK (0x1030)
+#define UPF_SPD_HI (0x0010)
+#define UPF_SPD_VHI (0x0020)
+#define UPF_SPD_CUST (0x0030)
+#define UPF_SPD_SHI (0x1000)
+#define UPF_SPD_WARP (0x1010)
+#define UPF_SKIP_TEST (1 << 6)
+#define UPF_AUTO_IRQ (1 << 7)
+#define UPF_HARDPPS_CD (1 << 11)
+#define UPF_LOW_LATENCY (1 << 13)
+#define UPF_BUGGY_UART (1 << 14)
+#define UPF_MAGIC_MULTIPLIER (1 << 16)
+#define UPF_CONS_FLOW (1 << 23)
+#define UPF_SHARE_IRQ (1 << 24)
+#define UPF_BOOT_AUTOCONF (1 << 28)
+#define UPF_DEAD (1 << 30)
+#define UPF_IOREMAP (1 << 31)
+#define UPF_CHANGE_MASK (0x17fff)
+#define UPF_USR_MASK (UPF_SPD_MASK|UPF_LOW_LATENCY)
+#define USF_CLOSING_WAIT_INF (0)
+#define USF_CLOSING_WAIT_NONE (~0U)
+
+#define UART_XMIT_SIZE PAGE_SIZE
+
+#define UIF_CHECK_CD (1 << 25)
+#define UIF_CTS_FLOW (1 << 26)
+#define UIF_NORMAL_ACTIVE (1 << 29)
+#define UIF_INITIALIZED (1 << 31)
+#define UIF_SUSPENDED (1 << 30)
+
+#define WAKEUP_CHARS 256
+
+#define uart_circ_empty(circ) ((circ)->head == (circ)->tail)
+#define uart_circ_clear(circ) ((circ)->head = (circ)->tail = 0)
+
+#define uart_circ_chars_pending(circ) \
+ (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
+
+#define uart_circ_chars_free(circ) \
+ (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
+
+#define uart_tx_stopped(port) \
+ ((port)->info->tty->stopped || (port)->info->tty->hw_stopped)
+
+#define UART_ENABLE_MS(port,cflag) ((port)->flags & UPF_HARDPPS_CD || \
+ (cflag) & CRTSCTS || \
+ !((cflag) & CLOCAL))
+
+
+struct sb_uart_port;
+struct sb_uart_info;
+struct serial_struct;
+struct device;
+
+struct sb_uart_ops {
+ unsigned int (*tx_empty)(struct sb_uart_port *);
+ void (*set_mctrl)(struct sb_uart_port *, unsigned int mctrl);
+ unsigned int (*get_mctrl)(struct sb_uart_port *);
+ void (*stop_tx)(struct sb_uart_port *);
+ void (*start_tx)(struct sb_uart_port *);
+ void (*send_xchar)(struct sb_uart_port *, char ch);
+ void (*stop_rx)(struct sb_uart_port *);
+ void (*enable_ms)(struct sb_uart_port *);
+ void (*break_ctl)(struct sb_uart_port *, int ctl);
+ int (*startup)(struct sb_uart_port *);
+ void (*shutdown)(struct sb_uart_port *);
+ void (*set_termios)(struct sb_uart_port *, struct MP_TERMIOS *new,
+ struct MP_TERMIOS *old);
+ void (*pm)(struct sb_uart_port *, unsigned int state,
+ unsigned int oldstate);
+ int (*set_wake)(struct sb_uart_port *, unsigned int state);
+
+ const char *(*type)(struct sb_uart_port *);
+
+ void (*release_port)(struct sb_uart_port *);
+
+ int (*request_port)(struct sb_uart_port *);
+ void (*config_port)(struct sb_uart_port *, int);
+ int (*verify_port)(struct sb_uart_port *, struct serial_struct *);
+ int (*ioctl)(struct sb_uart_port *, unsigned int, unsigned long);
+};
+
+
+struct sb_uart_icount {
+ __u32 cts;
+ __u32 dsr;
+ __u32 rng;
+ __u32 dcd;
+ __u32 rx;
+ __u32 tx;
+ __u32 frame;
+ __u32 overrun;
+ __u32 parity;
+ __u32 brk;
+ __u32 buf_overrun;
+};
+typedef unsigned int upf_t;
+
+struct sb_uart_port {
+ spinlock_t lock; /* port lock */
+ unsigned int iobase; /* in/out[bwl] */
+ unsigned char __iomem *membase; /* read/write[bwl] */
+ unsigned int irq; /* irq number */
+ unsigned int uartclk; /* base uart clock */
+ unsigned int fifosize; /* tx fifo size */
+ unsigned char x_char; /* xon/xoff char */
+ unsigned char regshift; /* reg offset shift */
+ unsigned char iotype; /* io access style */
+ unsigned char unused1;
+
+
+ unsigned int read_status_mask; /* driver specific */
+ unsigned int ignore_status_mask; /* driver specific */
+ struct sb_uart_info *info; /* pointer to parent info */
+ struct sb_uart_icount icount; /* statistics */
+
+ struct console *cons; /* struct console, if any */
+#ifdef CONFIG_SERIAL_CORE_CONSOLE
+ unsigned long sysrq; /* sysrq timeout */
+#endif
+
+ upf_t flags;
+
+ unsigned int mctrl; /* current modem ctrl settings */
+ unsigned int timeout; /* character-based timeout */
+ unsigned int type; /* port type */
+ const struct sb_uart_ops *ops;
+ unsigned int custom_divisor;
+ unsigned int line; /* port index */
+ unsigned long mapbase; /* for ioremap */
+ struct device *dev; /* parent device */
+ unsigned char hub6; /* this should be in the 8250 driver */
+ unsigned char unused[3];
+};
+
+#define mdmode unused[2]
+#define MDMODE_ADDR 0x1
+#define MDMODE_ENABLE 0x2
+#define MDMODE_AUTO 0x4
+#define MDMODE_ADDRSEND 0x8
+
+struct sb_uart_state {
+ unsigned int close_delay; /* msec */
+ unsigned int closing_wait; /* msec */
+
+
+ int count;
+ int pm_state;
+ struct sb_uart_info *info;
+ struct sb_uart_port *port;
+
+ struct mutex mutex;
+};
+
+typedef unsigned int uif_t;
+
+struct sb_uart_info {
+ struct tty_struct *tty;
+ struct circ_buf xmit;
+ uif_t flags;
+
+ int blocked_open;
+
+ struct tasklet_struct tlet;
+
+ wait_queue_head_t open_wait;
+ wait_queue_head_t delta_msr_wait;
+};
+
+
+struct module;
+struct tty_driver;
+
+struct uart_driver {
+ struct module *owner;
+ const char *driver_name;
+ const char *dev_name;
+ int major;
+ int minor;
+ int nr;
+ struct console *cons;
+
+ struct sb_uart_state *state;
+ struct tty_driver *tty_driver;
+};
+
+void sb_uart_write_wakeup(struct sb_uart_port *port)
+{
+ struct sb_uart_info *info = port->info;
+ tasklet_schedule(&info->tlet);
+}
+
+void sb_uart_update_timeout(struct sb_uart_port *port, unsigned int cflag,
+ unsigned int baud)
+{
+ unsigned int bits;
+
+ switch (cflag & CSIZE)
+ {
+ case CS5:
+ bits = 7;
+ break;
+
+ case CS6:
+ bits = 8;
+ break;
+
+ case CS7:
+ bits = 9;
+ break;
+
+ default:
+ bits = 10;
+ break;
+ }
+
+ if (cflag & CSTOPB)
+ {
+ bits++;
+ }
+
+ if (cflag & PARENB)
+ {
+ bits++;
+ }
+
+ bits = bits * port->fifosize;
+
+ port->timeout = (HZ * bits) / baud + HZ/50;
+}
+unsigned int sb_uart_get_baud_rate(struct sb_uart_port *port, struct MP_TERMIOS *termios,
+ struct MP_TERMIOS *old, unsigned int min,
+ unsigned int max)
+{
+ unsigned int try, baud, altbaud = 38400;
+ upf_t flags = port->flags & UPF_SPD_MASK;
+
+ if (flags == UPF_SPD_HI)
+ altbaud = 57600;
+ if (flags == UPF_SPD_VHI)
+ altbaud = 115200;
+ if (flags == UPF_SPD_SHI)
+ altbaud = 230400;
+ if (flags == UPF_SPD_WARP)
+ altbaud = 460800;
+
+ for (try = 0; try < 2; try++) {
+
+ switch (termios->c_cflag & (CBAUD | CBAUDEX))
+ {
+ case B921600 : baud = 921600; break;
+ case B460800 : baud = 460800; break;
+ case B230400 : baud = 230400; break;
+ case B115200 : baud = 115200; break;
+ case B57600 : baud = 57600; break;
+ case B38400 : baud = 38400; break;
+ case B19200 : baud = 19200; break;
+ case B9600 : baud = 9600; break;
+ case B4800 : baud = 4800; break;
+ case B2400 : baud = 2400; break;
+ case B1800 : baud = 1800; break;
+ case B1200 : baud = 1200; break;
+ case B600 : baud = 600; break;
+ case B300 : baud = 300; break;
+ case B200 : baud = 200; break;
+ case B150 : baud = 150; break;
+ case B134 : baud = 134; break;
+ case B110 : baud = 110; break;
+ case B75 : baud = 75; break;
+ case B50 : baud = 50; break;
+ default : baud = 9600; break;
+ }
+
+ if (baud == 38400)
+ baud = altbaud;
+
+ if (baud == 0)
+ baud = 9600;
+
+ if (baud >= min && baud <= max)
+ return baud;
+
+ termios->c_cflag &= ~CBAUD;
+ if (old) {
+ termios->c_cflag |= old->c_cflag & CBAUD;
+ old = NULL;
+ continue;
+ }
+
+ termios->c_cflag |= B9600;
+ }
+
+ return 0;
+}
+unsigned int sb_uart_get_divisor(struct sb_uart_port *port, unsigned int baud)
+{
+ unsigned int quot;
+
+ if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
+ quot = port->custom_divisor;
+ else
+ quot = (port->uartclk + (8 * baud)) / (16 * baud);
+
+ return quot;
+}
+
+
+
+static inline int sb_uart_handle_break(struct sb_uart_port *port)
+{
+ struct sb_uart_info *info = port->info;
+
+ if (port->flags & UPF_SAK)
+ do_SAK(info->tty);
+ return 0;
+}
+
+static inline void sb_uart_handle_dcd_change(struct sb_uart_port *port, unsigned int status)
+{
+ struct sb_uart_info *info = port->info;
+
+ port->icount.dcd++;
+
+ if (info->flags & UIF_CHECK_CD) {
+ if (status)
+ wake_up_interruptible(&info->open_wait);
+ else if (info->tty)
+ tty_hangup(info->tty);
+ }
+}
+
+static inline void sb_uart_handle_cts_change(struct sb_uart_port *port, unsigned int status)
+{
+ struct sb_uart_info *info = port->info;
+ struct tty_struct *tty = info->tty;
+
+ port->icount.cts++;
+
+ if (info->flags & UIF_CTS_FLOW) {
+ if (tty->hw_stopped) {
+ if (status) {
+ tty->hw_stopped = 0;
+ port->ops->start_tx(port);
+ sb_uart_write_wakeup(port);
+ }
+ } else {
+ if (!status) {
+ tty->hw_stopped = 1;
+ port->ops->stop_tx(port);
+ }
+ }
+ }
+}
+
+
+
diff --git a/drivers/staging/sbe-2t3e3/cpld.c b/drivers/staging/sbe-2t3e3/cpld.c
index cc2b54d52b1..27365f9bc0b 100644
--- a/drivers/staging/sbe-2t3e3/cpld.c
+++ b/drivers/staging/sbe-2t3e3/cpld.c
@@ -338,7 +338,7 @@ void cpld_set_fractional_mode(struct channel *sc, u32 mode,
SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2);
break;
default:
- printk(KERN_ERR "wrong mode in set_fractional_mode\n");
+ netdev_err(sc->dev, "wrong mode in set_fractional_mode\n");
return;
}
diff --git a/drivers/staging/sbe-2t3e3/main.c b/drivers/staging/sbe-2t3e3/main.c
index f3dbef6b0ee..c8e039860dc 100644
--- a/drivers/staging/sbe-2t3e3/main.c
+++ b/drivers/staging/sbe-2t3e3/main.c
@@ -135,9 +135,10 @@ void t3e3_read_card_serial_number(struct channel *sc)
for (i = 0; i < 3; i++)
sc->ether.card_serial_number[i] = t3e3_eeprom_read_word(sc, 10 + i);
- printk(KERN_INFO "SBE wanPMC-2T3E3 serial number: %04X%04X%04X\n",
- sc->ether.card_serial_number[0], sc->ether.card_serial_number[1],
- sc->ether.card_serial_number[2]);
+ netdev_info(sc->dev, "SBE wanPMC-2T3E3 serial number: %04X%04X%04X\n",
+ sc->ether.card_serial_number[0],
+ sc->ether.card_serial_number[1],
+ sc->ether.card_serial_number[2]);
}
/*
diff --git a/drivers/staging/sbe-2t3e3/module.c b/drivers/staging/sbe-2t3e3/module.c
index 8adb17816ad..ae7af397a99 100644
--- a/drivers/staging/sbe-2t3e3/module.c
+++ b/drivers/staging/sbe-2t3e3/module.c
@@ -10,6 +10,8 @@
* This code is based on a driver written by SBE Inc.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
@@ -50,7 +52,7 @@ static void t3e3_remove_channel(struct channel *channel)
pci_set_drvdata(pdev, NULL);
}
-static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev *pdev, struct card *card)
+static int t3e3_init_channel(struct channel *channel, struct pci_dev *pdev, struct card *card)
{
struct net_device *dev;
unsigned int val;
@@ -66,7 +68,7 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev *
dev = alloc_hdlcdev(channel);
if (!dev) {
- printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n");
+ pr_err("Out of memory\n");
err = -ENOMEM;
goto free_regions;
}
@@ -96,7 +98,8 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev *
err = request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev);
if (err) {
- printk(KERN_WARNING "%s: could not get irq: %d\n", dev->name, dev->irq);
+ netdev_warn(channel->dev, "%s: could not get irq: %d\n",
+ dev->name, dev->irq);
goto unregister_dev;
}
@@ -114,7 +117,7 @@ disable:
return err;
}
-static void __devexit t3e3_remove_card(struct pci_dev *pdev)
+static void t3e3_remove_card(struct pci_dev *pdev)
{
struct channel *channel0 = pci_get_drvdata(pdev);
struct card *card = channel0->card;
@@ -128,7 +131,7 @@ static void __devexit t3e3_remove_card(struct pci_dev *pdev)
kfree(card);
}
-static int __devinit t3e3_init_card(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int t3e3_init_card(struct pci_dev *pdev, const struct pci_device_id *ent)
{
/* pdev points to channel #0 */
struct pci_dev *pdev1 = NULL;
@@ -144,7 +147,7 @@ static int __devinit t3e3_init_card(struct pci_dev *pdev, const struct pci_devic
break; /* found the second channel */
if (!pdev1) {
- printk(KERN_ERR "SBE 2T3E3" ": Can't find the second channel\n");
+ dev_err(&pdev->dev, "Can't find the second channel\n");
return -EFAULT;
}
channels = 2;
@@ -153,7 +156,7 @@ static int __devinit t3e3_init_card(struct pci_dev *pdev, const struct pci_devic
card = kzalloc(sizeof(struct card) + channels * sizeof(struct channel), GFP_KERNEL);
if (!card) {
- printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n");
+ dev_err(&pdev->dev, "Out of memory\n");
return -ENOBUFS;
}
@@ -185,7 +188,7 @@ free_card:
return err;
}
-static struct pci_device_id t3e3_pci_tbl[] __devinitdata = {
+static struct pci_device_id t3e3_pci_tbl[] = {
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_T3E3, 0, 0, 0 },
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
diff --git a/drivers/staging/sbe-2t3e3/netdev.c b/drivers/staging/sbe-2t3e3/netdev.c
index 180c96327b9..1f5088b3c10 100644
--- a/drivers/staging/sbe-2t3e3/netdev.c
+++ b/drivers/staging/sbe-2t3e3/netdev.c
@@ -57,7 +57,7 @@ static int t3e3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return 0;
}
-static struct net_device_stats* t3e3_get_stats(struct net_device *dev)
+static struct net_device_stats *t3e3_get_stats(struct net_device *dev)
{
struct net_device_stats *nstats = &dev->stats;
struct channel *sc = dev_to_priv(dev);
@@ -134,7 +134,8 @@ int setup_device(struct net_device *dev, struct channel *sc)
dev->tx_queue_len = 100;
hdlc->xmit = t3e3_if_start_xmit;
hdlc->attach = t3e3_attach;
- if ((retval = register_hdlc_device(dev))) {
+ retval = register_hdlc_device(dev);
+ if (retval) {
dev_err(&sc->pdev->dev, "error registering HDLC device\n");
return retval;
}
diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c
index a414e52dd08..15c6e3d9437 100644
--- a/drivers/staging/sep/sep_main.c
+++ b/drivers/staging/sep/sep_main.c
@@ -3431,7 +3431,7 @@ static ssize_t sep_create_dcb_dmatables_context(struct sep_device *sep,
if (copy_from_user(dcb_args,
user_dcb_args,
num_dcbs * sizeof(struct build_dcb_struct))) {
- error = -EINVAL;
+ error = -EFAULT;
goto end_function;
}
@@ -3619,7 +3619,7 @@ static ssize_t sep_create_msgarea_context(struct sep_device *sep,
/* Copy input data to write() to allocated message buffer */
if (copy_from_user(*msg_region, msg_user, msg_len)) {
- error = -EINVAL;
+ error = -EFAULT;
goto end_function;
}
@@ -4112,7 +4112,7 @@ static int sep_register_driver_with_fs(struct sep_device *sep)
*Attempt to set up and configure a SEP device that has been
*discovered by the PCI layer. Allocates all required resources.
*/
-static int __devinit sep_probe(struct pci_dev *pdev,
+static int sep_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
int error = 0;
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c
index 099bc69ca00..1b3e995d3a2 100644
--- a/drivers/staging/serqt_usb2/serqt_usb2.c
+++ b/drivers/staging/serqt_usb2/serqt_usb2.c
@@ -272,7 +272,8 @@ static void qt_write_bulk_callback(struct urb *urb)
status = urb->status;
if (status) {
- dev_dbg(&urb->dev->dev, "nonzero write bulk status received:%d\n", status);
+ dev_dbg(&urb->dev->dev,
+ "nonzero write bulk status received:%d\n", status);
return;
}
@@ -290,22 +291,80 @@ static void qt_interrupt_callback(struct urb *urb)
/* FIXME */
}
+static void qt_status_change_check(struct tty_struct *tty,
+ struct urb *urb,
+ struct quatech_port *qt_port,
+ struct usb_serial_port *port)
+{
+ int flag, i;
+ unsigned char *data = urb->transfer_buffer;
+ unsigned int RxCount = urb->actual_length;
+
+ for (i = 0; i < RxCount; ++i) {
+ /* Look ahead code here */
+ if ((i <= (RxCount - 3)) && (data[i] == 0x1b)
+ && (data[i + 1] == 0x1b)) {
+ flag = 0;
+ switch (data[i + 2]) {
+ case 0x00:
+ if (i > (RxCount - 4)) {
+ dev_dbg(&port->dev,
+ "Illegal escape seuences in received data\n");
+ break;
+ }
+
+ ProcessLineStatus(qt_port, data[i + 3]);
+
+ i += 3;
+ flag = 1;
+ break;
+
+ case 0x01:
+ if (i > (RxCount - 4)) {
+ dev_dbg(&port->dev,
+ "Illegal escape seuences in received data\n");
+ break;
+ }
+
+ ProcessModemStatus(qt_port, data[i + 3]);
+
+ i += 3;
+ flag = 1;
+ break;
+
+ case 0xff:
+ dev_dbg(&port->dev, "No status sequence.\n");
+
+ ProcessRxChar(tty, port, data[i]);
+ ProcessRxChar(tty, port, data[i + 1]);
+
+ i += 2;
+ break;
+ }
+ if (flag == 1)
+ continue;
+ }
+
+ if (tty && urb->actual_length)
+ tty_insert_flip_char(tty, data[i], TTY_NORMAL);
+
+ }
+ tty_flip_buffer_push(tty);
+}
+
static void qt_read_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct usb_serial *serial = get_usb_serial(port, __func__);
struct quatech_port *qt_port = qt_get_port_private(port);
- unsigned char *data;
struct tty_struct *tty;
- unsigned int index;
- unsigned int RxCount;
- int i, result;
- int flag, flag_data;
+ int result;
if (urb->status) {
qt_port->ReadBulkStopped = 1;
- dev_dbg(&urb->dev->dev, "%s - nonzero write bulk status received: %d\n",
+ dev_dbg(&urb->dev->dev,
+ "%s - nonzero write bulk status received: %d\n",
__func__, urb->status);
return;
}
@@ -314,14 +373,8 @@ static void qt_read_bulk_callback(struct urb *urb)
if (!tty)
return;
- data = urb->transfer_buffer;
-
- RxCount = urb->actual_length;
-
- /* index = MINOR(port->tty->device) - serial->minor; */
- index = tty->index - serial->minor;
-
- dev_dbg(&port->dev, "%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding);
+ dev_dbg(&port->dev,
+ "%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding);
if (port_paranoia_check(port, __func__) != 0) {
qt_port->ReadBulkStopped = 1;
@@ -333,7 +386,8 @@ static void qt_read_bulk_callback(struct urb *urb)
if (qt_port->closePending == 1) {
/* Were closing , stop reading */
- dev_dbg(&port->dev, "%s - (qt_port->closepending == 1\n", __func__);
+ dev_dbg(&port->dev,
+ "%s - (qt_port->closepending == 1\n", __func__);
qt_port->ReadBulkStopped = 1;
goto exit;
}
@@ -351,62 +405,14 @@ static void qt_read_bulk_callback(struct urb *urb)
if (urb->status) {
qt_port->ReadBulkStopped = 1;
- dev_dbg(&port->dev, "%s - nonzero read bulk status received: %d\n",
+ dev_dbg(&port->dev,
+ "%s - nonzero read bulk status received: %d\n",
__func__, urb->status);
goto exit;
}
- if (RxCount) {
- flag_data = 0;
- for (i = 0; i < RxCount; ++i) {
- /* Look ahead code here */
- if ((i <= (RxCount - 3)) && (data[i] == 0x1b)
- && (data[i + 1] == 0x1b)) {
- flag = 0;
- switch (data[i + 2]) {
- case 0x00:
- /* line status change 4th byte must follow */
- if (i > (RxCount - 4)) {
- dev_dbg(&port->dev, "Illegal escape seuences in received data\n");
- break;
- }
- ProcessLineStatus(qt_port, data[i + 3]);
- i += 3;
- flag = 1;
- break;
-
- case 0x01:
- /* Modem status status change 4th byte must follow */
- dev_dbg(&port->dev, "Modem status status.\n");
- if (i > (RxCount - 4)) {
- dev_dbg(&port->dev, "Illegal escape sequences in received data\n");
- break;
- }
- ProcessModemStatus(qt_port,
- data[i + 3]);
- i += 3;
- flag = 1;
- break;
- case 0xff:
- dev_dbg(&port->dev, "No status sequence.\n");
-
- if (tty) {
- ProcessRxChar(tty, port, data[i]);
- ProcessRxChar(tty, port, data[i + 1]);
- }
- i += 2;
- break;
- }
- if (flag == 1)
- continue;
- }
-
- if (tty && urb->actual_length)
- tty_insert_flip_char(tty, data[i], TTY_NORMAL);
-
- }
- tty_flip_buffer_push(tty);
- }
+ if (urb->actual_length)
+ qt_status_change_check(tty, urb, qt_port, port);
/* Continue trying to always read */
usb_fill_bulk_urb(port->read_urb, serial->dev,
@@ -417,10 +423,11 @@ static void qt_read_bulk_callback(struct urb *urb)
qt_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
- dev_dbg(&port->dev, "%s - failed resubmitting read urb, error %d",
+ dev_dbg(&port->dev,
+ "%s - failed resubmitting read urb, error %d",
__func__, result);
else {
- if (RxCount) {
+ if (urb->actual_length) {
tty_flip_buffer_push(tty);
tty_schedule_flip(tty);
}
@@ -824,6 +831,31 @@ static void qt_release(struct usb_serial *serial)
}
+static void qt_submit_urb_from_open(struct usb_serial *serial,
+ struct usb_serial_port *port)
+{
+ int result;
+ struct usb_serial_port *port0 = serial->port[0];
+
+ /* set up interrupt urb */
+ usb_fill_int_urb(port0->interrupt_in_urb,
+ serial->dev,
+ usb_rcvintpipe(serial->dev,
+ port0->interrupt_in_endpointAddress),
+ port0->interrupt_in_buffer,
+ port0->interrupt_in_urb->transfer_buffer_length,
+ qt_interrupt_callback, serial,
+ port0->interrupt_in_urb->interval);
+
+ result = usb_submit_urb(port0->interrupt_in_urb,
+ GFP_KERNEL);
+ if (result) {
+ dev_err(&port->dev,
+ "%s - Error %d submitting interrupt urb\n",
+ __func__, result);
+ }
+}
+
static int qt_open(struct tty_struct *tty,
struct usb_serial_port *port)
{
@@ -884,38 +916,20 @@ static int qt_open(struct tty_struct *tty,
/* Check to see if we've set up our endpoint info yet */
if (port0->open_ports == 1) {
- if (serial->port[0]->interrupt_in_buffer == NULL) {
- /* set up interrupt urb */
- usb_fill_int_urb(serial->port[0]->interrupt_in_urb,
- serial->dev,
- usb_rcvintpipe(serial->dev,
- serial->port[0]->interrupt_in_endpointAddress),
- serial->port[0]->interrupt_in_buffer,
- serial->port[0]->
- interrupt_in_urb->transfer_buffer_length,
- qt_interrupt_callback, serial,
- serial->port[0]->
- interrupt_in_urb->interval);
-
- result =
- usb_submit_urb(serial->port[0]->interrupt_in_urb,
- GFP_KERNEL);
- if (result) {
- dev_err(&port->dev,
- "%s - Error %d submitting "
- "interrupt urb\n", __func__, result);
- }
-
- }
-
+ if (serial->port[0]->interrupt_in_buffer == NULL)
+ qt_submit_urb_from_open(serial, port);
}
dev_dbg(&port->dev, "port number is %d\n", port->number);
dev_dbg(&port->dev, "serial number is %d\n", port->serial->minor);
- dev_dbg(&port->dev, "Bulkin endpoint is %d\n", port->bulk_in_endpointAddress);
- dev_dbg(&port->dev, "BulkOut endpoint is %d\n", port->bulk_out_endpointAddress);
- dev_dbg(&port->dev, "Interrupt endpoint is %d\n", port->interrupt_in_endpointAddress);
- dev_dbg(&port->dev, "port's number in the device is %d\n", quatech_port->port_num);
+ dev_dbg(&port->dev,
+ "Bulkin endpoint is %d\n", port->bulk_in_endpointAddress);
+ dev_dbg(&port->dev,
+ "BulkOut endpoint is %d\n", port->bulk_out_endpointAddress);
+ dev_dbg(&port->dev, "Interrupt endpoint is %d\n",
+ port->interrupt_in_endpointAddress);
+ dev_dbg(&port->dev, "port's number in the device is %d\n",
+ quatech_port->port_num);
quatech_port->read_urb = port->read_urb;
/* set up our bulk in urb */
@@ -928,7 +942,8 @@ static int qt_open(struct tty_struct *tty,
quatech_port->read_urb->transfer_buffer_length,
qt_read_bulk_callback, quatech_port);
- dev_dbg(&port->dev, "qt_open: bulkin endpoint is %d\n", port->bulk_in_endpointAddress);
+ dev_dbg(&port->dev, "qt_open: bulkin endpoint is %d\n",
+ port->bulk_in_endpointAddress);
quatech_port->read_urb_busy = true;
result = usb_submit_urb(quatech_port->read_urb, GFP_KERNEL);
if (result) {
@@ -1021,15 +1036,18 @@ static void qt_close(struct usb_serial_port *port)
/* Close uart channel */
status = qt_close_channel(serial, index);
if (status < 0)
- dev_dbg(&port->dev, "%s - port %d qt_close_channel failed.\n", __func__, port->number);
+ dev_dbg(&port->dev,
+ "%s - port %d qt_close_channel failed.\n",
+ __func__, port->number);
port0->open_ports--;
- dev_dbg(&port->dev, "qt_num_open_ports in close%d:in port%d\n", port0->open_ports, port->number);
+ dev_dbg(&port->dev, "qt_num_open_ports in close%d:in port%d\n",
+ port0->open_ports, port->number);
if (port0->open_ports == 0) {
if (serial->port[0]->interrupt_in_urb) {
- dev_dbg(&port->dev, "%s", "Shutdown interrupt_in_urb\n");
+ dev_dbg(&port->dev, "Shutdown interrupt_in_urb\n");
usb_kill_urb(serial->port[0]->interrupt_in_urb);
}
@@ -1053,7 +1071,8 @@ static int qt_write(struct tty_struct *tty, struct usb_serial_port *port,
return -ENODEV;
if (count == 0) {
- dev_dbg(&port->dev, "%s - write request of 0 bytes\n", __func__);
+ dev_dbg(&port->dev,
+ "%s - write request of 0 bytes\n", __func__);
return 0;
}
@@ -1080,7 +1099,8 @@ static int qt_write(struct tty_struct *tty, struct usb_serial_port *port,
/* send the data out the bulk port */
result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
if (result)
- dev_dbg(&port->dev, "%s - failed submitting write urb, error %d\n",
+ dev_dbg(&port->dev,
+ "%s - failed submitting write urb, error %d\n",
__func__, result);
else
result = count;
@@ -1163,7 +1183,8 @@ static int qt_ioctl(struct tty_struct *tty,
return 0;
}
- dev_dbg(&port->dev, "%s -No ioctl for that one. port = %d\n", __func__, port->number);
+ dev_dbg(&port->dev, "%s -No ioctl for that one. port = %d\n",
+ __func__, port->number);
return -ENOIOCTLCMD;
}
@@ -1238,7 +1259,8 @@ static void qt_set_termios(struct tty_struct *tty,
/* Now determine flow control */
if (cflag & CRTSCTS) {
- dev_dbg(&port->dev, "%s - Enabling HW flow control port %d\n", __func__, port->number);
+ dev_dbg(&port->dev, "%s - Enabling HW flow control port %d\n",
+ __func__, port->number);
/* Enable RTS/CTS flow control */
status = BoxSetHW_FlowCtrl(port->serial, index, 1);
@@ -1249,7 +1271,9 @@ static void qt_set_termios(struct tty_struct *tty,
}
} else {
/* Disable RTS/CTS flow control */
- dev_dbg(&port->dev, "%s - disabling HW flow control port %d\n", __func__, port->number);
+ dev_dbg(&port->dev,
+ "%s - disabling HW flow control port %d\n",
+ __func__, port->number);
status = BoxSetHW_FlowCtrl(port->serial, index, 0);
if (status < 0) {
@@ -1268,17 +1292,21 @@ static void qt_set_termios(struct tty_struct *tty,
BoxSetSW_FlowCtrl(port->serial, index, stop_char,
start_char);
if (status < 0)
- dev_dbg(&port->dev, "BoxSetSW_FlowCtrl (enabled) failed\n");
+ dev_dbg(&port->dev,
+ "BoxSetSW_FlowCtrl (enabled) failed\n");
} else {
/* disable SW flow control */
status = BoxDisable_SW_FlowCtrl(port->serial, index);
if (status < 0)
- dev_dbg(&port->dev, "BoxSetSW_FlowCtrl (diabling) failed\n");
+ dev_dbg(&port->dev,
+ "BoxSetSW_FlowCtrl (diabling) failed\n");
}
termios->c_cflag &= ~CMSPAR;
- /* FIXME: Error cases should be returning the actual bits changed only */
+ /* FIXME:
+ Error cases should be returning the actual bits changed only
+ */
}
static void qt_break(struct tty_struct *tty, int break_state)
@@ -1436,12 +1464,32 @@ static void qt_throttle(struct tty_struct *tty)
mutex_unlock(&qt_port->lock);
}
+static void qt_submit_urb_from_unthrottle(struct usb_serial_port *port,
+ struct usb_serial *serial)
+{
+ int result;
+
+ /* Start reading from the device */
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ qt_read_bulk_callback, port);
+
+ result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+
+ if (result)
+ dev_err(&port->dev,
+ "%s - failed restarting read urb, error %d\n",
+ __func__, result);
+}
+
static void qt_unthrottle(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = get_usb_serial(port, __func__);
struct quatech_port *qt_port;
- unsigned int result;
if (!serial)
return;
@@ -1457,21 +1505,8 @@ static void qt_unthrottle(struct tty_struct *tty)
dev_dbg(&port->dev, "%s - qt_port->RxHolding = 0\n", __func__);
/* if we have a bulk endpoint, start it up */
- if ((serial->num_bulk_in) && (qt_port->ReadBulkStopped == 1)) {
- /* Start reading from the device */
- usb_fill_bulk_urb(port->read_urb, serial->dev,
- usb_rcvbulkpipe(serial->dev,
- port->bulk_in_endpointAddress),
- port->read_urb->transfer_buffer,
- port->read_urb->
- transfer_buffer_length,
- qt_read_bulk_callback, port);
- result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
- if (result)
- dev_err(&port->dev,
- "%s - failed restarting read urb, error %d\n",
- __func__, result);
- }
+ if ((serial->num_bulk_in) && (qt_port->ReadBulkStopped == 1))
+ qt_submit_urb_from_unthrottle(port, serial);
}
mutex_unlock(&qt_port->lock);
}
diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c
index 3cfd0516adf..58c5f5cf4ce 100644
--- a/drivers/staging/silicom/bp_mod.c
+++ b/drivers/staging/silicom/bp_mod.c
@@ -9,7 +9,6 @@
/* */
/* */
/******************************************************************************/
-#include <linux/version.h>
#include <linux/kernel.h> /* We're doing kernel work */
#include <linux/module.h> /* Specifically, a module */
@@ -4319,16 +4318,6 @@ void remove_bypass_wd_auto(bpctl_dev_t *pbpctl_dev)
del_timer_sync(&pbpctl_dev->bp_timer);
#ifdef BP_SELF_TEST
pbpctl_dev_sl = get_status_port_fn(pbpctl_dev);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31))
- if (pbpctl_dev_sl && (pbpctl_dev_sl->ndev)
- && (pbpctl_dev_sl->ndev->hard_start_xmit)
- && (pbpctl_dev_sl->hard_start_xmit_save)) {
- rtnl_lock();
- pbpctl_dev_sl->ndev->hard_start_xmit =
- pbpctl_dev_sl->hard_start_xmit_save;
- rtnl_unlock();
- }
-#else
if (pbpctl_dev_sl && (pbpctl_dev_sl->ndev)) {
if ((pbpctl_dev_sl->ndev->netdev_ops)
&& (pbpctl_dev_sl->old_ops)) {
@@ -4342,8 +4331,6 @@ void remove_bypass_wd_auto(bpctl_dev_t *pbpctl_dev)
}
}
-
-#endif
#endif
}
@@ -4433,23 +4420,7 @@ int set_bp_self_test(bpctl_dev_t *pbpctl_dev, unsigned int param)
if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
pbpctl_dev->bp_self_test_flag = param == 0 ? 0 : 1;
pbpctl_dev_sl = get_status_port_fn(pbpctl_dev);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31))
- if ((pbpctl_dev_sl->ndev) &&
- (pbpctl_dev_sl->ndev->hard_start_xmit)) {
- rtnl_lock();
- if (pbpctl_dev->bp_self_test_flag == 1) {
- pbpctl_dev_sl->hard_start_xmit_save =
- pbpctl_dev_sl->ndev->hard_start_xmit;
- pbpctl_dev_sl->ndev->hard_start_xmit =
- bp_hard_start_xmit;
- } else if (pbpctl_dev_sl->hard_start_xmit_save) {
- pbpctl_dev_sl->ndev->hard_start_xmit =
- pbpctl_dev_sl->hard_start_xmit_save;
- }
- rtnl_unlock();
- }
-#else
if ((pbpctl_dev_sl->ndev) && (pbpctl_dev_sl->ndev->netdev_ops)) {
rtnl_lock();
if (pbpctl_dev->bp_self_test_flag == 1) {
@@ -4470,7 +4441,6 @@ int set_bp_self_test(bpctl_dev_t *pbpctl_dev, unsigned int param)
}
rtnl_unlock();
}
-#endif
set_bypass_wd_auto(pbpctl_dev, param);
return 0;
@@ -5428,15 +5398,8 @@ static void if_scan_init(void)
/* rcu_read_lock(); */
/* rtnl_lock(); */
/* rcu_read_lock(); */
-#if 1
-#if (LINUX_VERSION_CODE >= 0x020618)
- for_each_netdev(&init_net, dev)
-#elif (LINUX_VERSION_CODE >= 0x20616)
- for_each_netdev(dev)
-#else
- for (dev = dev_base; dev; dev = dev->next)
-#endif
- {
+
+ for_each_netdev(&init_net, dev) {
struct ethtool_drvinfo drvinfo;
char cbuf[32];
@@ -5454,8 +5417,6 @@ static void if_scan_init(void)
dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
} else
continue;
- if (!drvinfo.bus_info)
- continue;
if (!strcmp(drvinfo.bus_info, "N/A"))
continue;
memcpy(&cbuf, drvinfo.bus_info, 32);
@@ -5491,22 +5452,14 @@ static void if_scan_init(void)
}
}
-#endif
/* rtnl_unlock(); */
/* rcu_read_unlock(); */
}
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
-static int device_ioctl(struct inode *inode, /* see include/linux/fs.h */
- struct file *file, /* ditto */
- unsigned int ioctl_num, /* number and param for ioctl */
- unsigned long ioctl_param)
-#else
-static long device_ioctl(struct file *file, /* ditto */
+static long device_ioctl(struct file *file, /* see include/linux/fs.h */
unsigned int ioctl_num, /* number and param for ioctl */
unsigned long ioctl_param)
-#endif
{
struct bpctl_cmd bpctl_cmd;
int dev_idx = 0;
@@ -5517,9 +5470,7 @@ static long device_ioctl(struct file *file, /* ditto */
static bpctl_dev_t *pbpctl_dev;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
/* lock_kernel(); */
-#endif
lock_bpctl();
/* local_irq_save(flags); */
/* if(!spin_trylock_irqsave(&bpvm_lock)){
@@ -5900,9 +5851,7 @@ static long device_ioctl(struct file *file, /* ditto */
ret = -EFAULT;
ret = SUCCESS;
bp_exit:
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
/* unlock_kernel(); */
-#endif
/* spin_unlock_irqrestore(&bpvm_lock, flags); */
unlock_bpctl();
/* unlock_kernel(); */
@@ -5911,12 +5860,7 @@ static long device_ioctl(struct file *file, /* ditto */
struct file_operations Fops = {
.owner = THIS_MODULE,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
- .ioctl = device_ioctl,
-#else
.unlocked_ioctl = device_ioctl,
-#endif
-
.open = device_open,
.release = device_release, /* a.k.a. close */
};
@@ -6952,15 +6896,8 @@ static int __init bypass_init_module(void)
memset(bpctl_dev_arr[idx_dev].bp_tx_data + 7,
0xaa, 5);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
- bpctl_dev_arr[idx_dev].bp_tx_data[12] =
- (ETH_P_BPTEST >> 8) & 0xff;
- bpctl_dev_arr[idx_dev].bp_tx_data[13] =
- ETH_P_BPTEST & 0xff;
-#else
*(__be16 *) (bpctl_dev_arr[idx_dev].bp_tx_data +
12) = htons(ETH_P_BPTEST);
-#endif
} else
printk("bp_ctl: Memory allocation error!\n");
@@ -7009,83 +6946,6 @@ static int __init bypass_init_module(void)
}
}
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
- inter_module_register("is_bypass_sd", THIS_MODULE, &is_bypass_sd);
- inter_module_register("get_bypass_slave_sd", THIS_MODULE,
- &get_bypass_slave_sd);
- inter_module_register("get_bypass_caps_sd", THIS_MODULE,
- &get_bypass_caps_sd);
- inter_module_register("get_wd_set_caps_sd", THIS_MODULE,
- &get_wd_set_caps_sd);
- inter_module_register("set_bypass_sd", THIS_MODULE, &set_bypass_sd);
- inter_module_register("get_bypass_sd", THIS_MODULE, &get_bypass_sd);
- inter_module_register("get_bypass_change_sd", THIS_MODULE,
- &get_bypass_change_sd);
- inter_module_register("set_dis_bypass_sd", THIS_MODULE,
- &set_dis_bypass_sd);
- inter_module_register("get_dis_bypass_sd", THIS_MODULE,
- &get_dis_bypass_sd);
- inter_module_register("set_bypass_pwoff_sd", THIS_MODULE,
- &set_bypass_pwoff_sd);
- inter_module_register("get_bypass_pwoff_sd", THIS_MODULE,
- &get_bypass_pwoff_sd);
- inter_module_register("set_bypass_pwup_sd", THIS_MODULE,
- &set_bypass_pwup_sd);
- inter_module_register("get_bypass_pwup_sd", THIS_MODULE,
- &get_bypass_pwup_sd);
- inter_module_register("get_bypass_wd_sd", THIS_MODULE,
- &get_bypass_wd_sd);
- inter_module_register("set_bypass_wd_sd", THIS_MODULE,
- &set_bypass_wd_sd);
- inter_module_register("get_wd_expire_time_sd", THIS_MODULE,
- &get_wd_expire_time_sd);
- inter_module_register("reset_bypass_wd_timer_sd", THIS_MODULE,
- &reset_bypass_wd_timer_sd);
- inter_module_register("set_std_nic_sd", THIS_MODULE, &set_std_nic_sd);
- inter_module_register("get_std_nic_sd", THIS_MODULE, &get_std_nic_sd);
- inter_module_register("set_tx_sd", THIS_MODULE, &set_tx_sd);
- inter_module_register("get_tx_sd", THIS_MODULE, &get_tx_sd);
- inter_module_register("set_tpl_sd", THIS_MODULE, &set_tpl_sd);
- inter_module_register("get_tpl_sd", THIS_MODULE, &get_tpl_sd);
-
- inter_module_register("set_bp_hw_reset_sd", THIS_MODULE,
- &set_bp_hw_reset_sd);
- inter_module_register("get_bp_hw_reset_sd", THIS_MODULE,
- &get_bp_hw_reset_sd);
-
- inter_module_register("set_tap_sd", THIS_MODULE, &set_tap_sd);
- inter_module_register("get_tap_sd", THIS_MODULE, &get_tap_sd);
- inter_module_register("get_tap_change_sd", THIS_MODULE,
- &get_tap_change_sd);
- inter_module_register("set_dis_tap_sd", THIS_MODULE, &set_dis_tap_sd);
- inter_module_register("get_dis_tap_sd", THIS_MODULE, &get_dis_tap_sd);
- inter_module_register("set_tap_pwup_sd", THIS_MODULE, &set_tap_pwup_sd);
- inter_module_register("get_tap_pwup_sd", THIS_MODULE, &get_tap_pwup_sd);
- inter_module_register("set_bp_disc_sd", THIS_MODULE, &set_bp_disc_sd);
- inter_module_register("get_bp_disc_sd", THIS_MODULE, &get_bp_disc_sd);
- inter_module_register("get_bp_disc_change_sd", THIS_MODULE,
- &get_bp_disc_change_sd);
- inter_module_register("set_bp_dis_disc_sd", THIS_MODULE,
- &set_bp_dis_disc_sd);
- inter_module_register("get_bp_dis_disc_sd", THIS_MODULE,
- &get_bp_dis_disc_sd);
- inter_module_register("set_bp_disc_pwup_sd", THIS_MODULE,
- &set_bp_disc_pwup_sd);
- inter_module_register("get_bp_disc_pwup_sd", THIS_MODULE,
- &get_bp_disc_pwup_sd);
- inter_module_register("set_wd_exp_mode_sd", THIS_MODULE,
- &set_wd_exp_mode_sd);
- inter_module_register("get_wd_exp_mode_sd", THIS_MODULE,
- &get_wd_exp_mode_sd);
- inter_module_register("set_wd_autoreset_sd", THIS_MODULE,
- &set_wd_autoreset_sd);
- inter_module_register("get_wd_autoreset_sd", THIS_MODULE,
- &get_wd_autoreset_sd);
- inter_module_register("get_bypass_info_sd", THIS_MODULE,
- &get_bypass_info_sd);
- inter_module_register("bp_if_scan_sd", THIS_MODULE, &bp_if_scan_sd);
-
-#endif
register_netdevice_notifier(&bp_notifier_block);
#ifdef BP_PROC_SUPPORT
{
@@ -7115,58 +6975,8 @@ static int __init bypass_init_module(void)
static void __exit bypass_cleanup_module(void)
{
int i;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23))
- int ret;
-#endif
unregister_netdevice_notifier(&bp_notifier_block);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
- inter_module_unregister("is_bypass_sd");
- inter_module_unregister("get_bypass_slave_sd");
- inter_module_unregister("get_bypass_caps_sd");
- inter_module_unregister("get_wd_set_caps_sd");
- inter_module_unregister("set_bypass_sd");
- inter_module_unregister("get_bypass_sd");
- inter_module_unregister("get_bypass_change_sd");
- inter_module_unregister("set_dis_bypass_sd");
- inter_module_unregister("get_dis_bypass_sd");
- inter_module_unregister("set_bypass_pwoff_sd");
- inter_module_unregister("get_bypass_pwoff_sd");
- inter_module_unregister("set_bypass_pwup_sd");
- inter_module_unregister("get_bypass_pwup_sd");
- inter_module_unregister("set_bypass_wd_sd");
- inter_module_unregister("get_bypass_wd_sd");
- inter_module_unregister("get_wd_expire_time_sd");
- inter_module_unregister("reset_bypass_wd_timer_sd");
- inter_module_unregister("set_std_nic_sd");
- inter_module_unregister("get_std_nic_sd");
- inter_module_unregister("set_tx_sd");
- inter_module_unregister("get_tx_sd");
- inter_module_unregister("set_tpl_sd");
- inter_module_unregister("get_tpl_sd");
- inter_module_unregister("set_tap_sd");
- inter_module_unregister("get_tap_sd");
- inter_module_unregister("get_tap_change_sd");
- inter_module_unregister("set_dis_tap_sd");
- inter_module_unregister("get_dis_tap_sd");
- inter_module_unregister("set_tap_pwup_sd");
- inter_module_unregister("get_tap_pwup_sd");
- inter_module_unregister("set_bp_disc_sd");
- inter_module_unregister("get_bp_disc_sd");
- inter_module_unregister("get_bp_disc_change_sd");
- inter_module_unregister("set_bp_dis_disc_sd");
- inter_module_unregister("get_bp_dis_disc_sd");
- inter_module_unregister("set_bp_disc_pwup_sd");
- inter_module_unregister("get_bp_disc_pwup_sd");
- inter_module_unregister("set_wd_exp_mode_sd");
- inter_module_unregister("get_wd_exp_mode_sd");
- inter_module_unregister("set_wd_autoreset_sd");
- inter_module_unregister("get_wd_autoreset_sd");
- inter_module_unregister("get_bypass_info_sd");
- inter_module_unregister("bp_if_scan_sd");
-
-#endif
-
for (i = 0; i < device_num; i++) {
/* unsigned long flags; */
#ifdef BP_PROC_SUPPORT
@@ -7198,17 +7008,7 @@ static void __exit bypass_cleanup_module(void)
/*
* Unregister the device
*/
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23))
- ret = unregister_chrdev(major_num, DEVICE_NAME);
-/*
-* If there's an error, report it
-*/
- if (ret < 0)
- printk("Error in module_unregister_chrdev: %d\n", ret);
-#else
unregister_chrdev(major_num, DEVICE_NAME);
-
-#endif
}
module_init(bypass_init_module);
@@ -7597,11 +7397,7 @@ static struct proc_dir_entry *proc_getdir(char *name,
}
if (pde == (struct proc_dir_entry *)0) {
/* create the directory */
-#if (LINUX_VERSION_CODE > 0x20300)
pde = proc_mkdir(name, proc_dir);
-#else
- pde = create_proc_entry(name, S_IFDIR, proc_dir);
-#endif
if (pde == (struct proc_dir_entry *)0) {
return pde;
@@ -7703,13 +7499,8 @@ get_bypass_slave_pfs(char *page, char **start, off_t off, int count,
return len;
}
net_slave_dev = pbp_device_block_slave->ndev;
- if (net_slave_dev) {
- if (net_slave_dev)
- len = sprintf(page, "%s\n", net_slave_dev->name);
- else
- len = sprintf(page, "fail\n");
-
- }
+ if (net_slave_dev)
+ len = sprintf(page, "%s\n", net_slave_dev->name);
*eof = 1;
return len;
diff --git a/drivers/staging/silicom/bp_proc.c b/drivers/staging/silicom/bp_proc.c
index 6ad4b27472e..a01ca97b766 100644
--- a/drivers/staging/silicom/bp_proc.c
+++ b/drivers/staging/silicom/bp_proc.c
@@ -10,21 +10,20 @@
/* */
/******************************************************************************/
-#include <linux/version.h>
-#if defined(CONFIG_SMP) && ! defined(__SMP__)
+#if defined(CONFIG_SMP) && !defined(__SMP__)
#define __SMP__
#endif
#include <linux/proc_fs.h>
#include <linux/netdevice.h>
#include <asm/uaccess.h>
-//#include <linux/smp_lock.h>
+/* #include <linux/smp_lock.h> */
#include "bp_mod.h"
#define BP_PROC_DIR "bypass"
-//#define BYPASS_SUPPORT "bypass"
+/* #define BYPASS_SUPPORT "bypass" */
-#ifdef BYPASS_SUPPORT
+#ifdef BYPASS_SUPPORT
#define GPIO6_SET_ENTRY_SD "gpio6_set"
#define GPIO6_CLEAR_ENTRY_SD "gpio6_clear"
@@ -70,7 +69,7 @@
#define DISC_CHANGE_ENTRY_SD "disc_change"
#define DIS_DISC_ENTRY_SD "dis_disc"
#define DISC_PWUP_ENTRY_SD "disc_pwup"
-#endif //bypass_support
+
static struct proc_dir_entry *bp_procfs_dir;
static struct proc_dir_entry *proc_getdir(char *name,
@@ -86,20 +85,17 @@ static struct proc_dir_entry *proc_getdir(char *name,
if (pde == (struct proc_dir_entry *)0) {
/* create the directory */
pde = create_proc_entry(name, S_IFDIR, proc_dir);
- if (pde == (struct proc_dir_entry *)0) {
- return (pde);
- }
+ if (pde == (struct proc_dir_entry *)0)
+ return pde;
}
- return (pde);
+ return pde;
}
-#ifdef BYPASS_SUPPORT
-
int
bypass_proc_create_entry_sd(struct pfs_unit *pfs_unit_curr,
char *proc_name,
- write_proc_t * write_proc,
- read_proc_t * read_proc,
+ write_proc_t *write_proc,
+ read_proc_t *read_proc,
struct proc_dir_entry *parent_pfs, void *data)
{
strcpy(pfs_unit_curr->proc_name, proc_name);
@@ -107,10 +103,8 @@ bypass_proc_create_entry_sd(struct pfs_unit *pfs_unit_curr,
S_IFREG | S_IRUSR |
S_IWUSR | S_IRGRP |
S_IROTH, parent_pfs);
- if (pfs_unit_curr->proc_entry == 0) {
-
+ if (pfs_unit_curr->proc_entry == 0)
return -1;
- }
pfs_unit_curr->proc_entry->read_proc = read_proc;
pfs_unit_curr->proc_entry->write_proc = write_proc;
@@ -207,9 +201,8 @@ set_bypass_pfs(struct file *file, const char *buffer,
if (count > (sizeof(kbuf) - 1))
return -1;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -239,9 +232,8 @@ set_tap_pfs(struct file *file, const char *buffer,
if (count > (sizeof(kbuf) - 1))
return -1;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -271,9 +263,8 @@ set_disc_pfs(struct file *file, const char *buffer,
if (count > (sizeof(kbuf) - 1))
return -1;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -421,9 +412,8 @@ set_bypass_wd_pfs(struct file *file, const char *buffer,
unsigned int timeout = 0;
char *timeout_ptr = kbuf;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
timeout_ptr = kbuf;
timeout = atoi(&timeout_ptr);
@@ -570,9 +560,8 @@ set_dis_bypass_pfs(struct file *file, const char *buffer,
int bypass_param = 0, length = 0;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -599,9 +588,8 @@ set_dis_tap_pfs(struct file *file, const char *buffer,
int tap_param = 0, length = 0;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -628,9 +616,8 @@ set_dis_disc_pfs(struct file *file, const char *buffer,
int tap_param = 0, length = 0;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -717,9 +704,8 @@ set_bypass_pwup_pfs(struct file *file, const char *buffer,
int bypass_param = 0, length = 0;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -746,9 +732,8 @@ set_bypass_pwoff_pfs(struct file *file, const char *buffer,
int bypass_param = 0, length = 0;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -775,9 +760,8 @@ set_tap_pwup_pfs(struct file *file, const char *buffer,
int tap_param = 0, length = 0;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -804,9 +788,8 @@ set_disc_pwup_pfs(struct file *file, const char *buffer,
int tap_param = 0, length = 0;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -913,9 +896,8 @@ set_std_nic_pfs(struct file *file, const char *buffer,
int bypass_param = 0, length = 0;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -988,9 +970,8 @@ set_wd_exp_mode_pfs(struct file *file, const char *buffer,
if (count > (sizeof(kbuf) - 1))
return -1;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -1036,9 +1017,8 @@ set_wd_autoreset_pfs(struct file *file, const char *buffer,
u32 timeout = 0;
char *timeout_ptr = kbuf;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
timeout_ptr = kbuf;
timeout = atoi(&timeout_ptr);
@@ -1061,9 +1041,8 @@ set_tpl_pfs(struct file *file, const char *buffer,
if (count > (sizeof(kbuf) - 1))
return -1;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -1094,9 +1073,8 @@ set_wait_at_pwup_pfs(struct file *file, const char *buffer,
if (count > (sizeof(kbuf) - 1))
return -1;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -1126,9 +1104,8 @@ set_hw_reset_pfs(struct file *file, const char *buffer,
if (count > (sizeof(kbuf) - 1))
return -1;
- if (copy_from_user(&kbuf, buffer, count)) {
+ if (copy_from_user(&kbuf, buffer, count))
return -1;
- }
kbuf[count] = '\0';
length = strlen(kbuf);
@@ -1147,10 +1124,10 @@ set_hw_reset_pfs(struct file *file, const char *buffer,
#endif /*PMC_FIX_FLAG */
-int bypass_proc_create_dev_sd(bpctl_dev_t * pbp_device_block)
+int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block)
{
struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set);
- static struct proc_dir_entry *procfs_dir = NULL;
+ static struct proc_dir_entry *procfs_dir;
int ret = 0;
sprintf(current_pfs->dir_name, "bypass_%s", dev->name);
@@ -1327,7 +1304,7 @@ int bypass_proc_create_dev_sd(bpctl_dev_t * pbp_device_block)
return ret;
}
-int bypass_proc_remove_dev_sd(bpctl_dev_t * pbp_device_block)
+int bypass_proc_remove_dev_sd(bpctl_dev_t *pbp_device_block)
{
struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set;
diff --git a/drivers/staging/silicom/bypasslib/bplibk.h b/drivers/staging/silicom/bypasslib/bplibk.h
index a1c85eec02f..d8c1d27650b 100644
--- a/drivers/staging/silicom/bypasslib/bplibk.h
+++ b/drivers/staging/silicom/bypasslib/bplibk.h
@@ -28,16 +28,7 @@
((pid==INTEL_PEG4BPII_PID)|| \
(pid==INTEL_PEG4BPFII_PID)))
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10))
-#define pci_get_class pci_find_class
-
-#define pci_get_device pci_find_device
-
-#endif
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
#define EXPORT_SYMBOL_NOVERS EXPORT_SYMBOL
-#endif
#ifdef BP_VENDOR_SUPPORT
char *bp_desc_array[] =
diff --git a/drivers/staging/silicom/bypasslib/bypass.c b/drivers/staging/silicom/bypasslib/bypass.c
index 527829d5813..95a1f1815d9 100644
--- a/drivers/staging/silicom/bypasslib/bypass.c
+++ b/drivers/staging/silicom/bypasslib/bypass.c
@@ -11,7 +11,6 @@
/* */
/******************************************************************************/
-#include <linux/version.h>
#if defined(CONFIG_SMP) && ! defined(__SMP__)
#define __SMP__
#endif
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c
index cd920dad85c..78578ee5955 100644
--- a/drivers/staging/slicoss/slicoss.c
+++ b/drivers/staging/slicoss/slicoss.c
@@ -142,39 +142,12 @@ static DEFINE_PCI_DEVICE_TABLE(slic_pci_tbl) = {
MODULE_DEVICE_TABLE(pci, slic_pci_tbl);
-#ifdef ASSERT
-#undef ASSERT
-#endif
-
-static void slic_assert_fail(void)
-{
- u32 cpuid;
- u32 curr_pid;
- cpuid = smp_processor_id();
- curr_pid = current->pid;
-
- printk(KERN_ERR "%s CPU # %d ---- PID # %d\n",
- __func__, cpuid, curr_pid);
-}
-
-#ifndef ASSERT
-#define ASSERT(a) do { \
- if (!(a)) { \
- printk(KERN_ERR "slicoss ASSERT() Failure: function %s" \
- "line %d\n", __func__, __LINE__); \
- slic_assert_fail(); \
- } \
-} while (0)
-#endif
-
-
#define SLIC_GET_SLIC_HANDLE(_adapter, _pslic_handle) \
{ \
spin_lock_irqsave(&_adapter->handle_lock.lock, \
_adapter->handle_lock.flags); \
_pslic_handle = _adapter->pfree_slic_handles; \
if (_pslic_handle) { \
- ASSERT(_pslic_handle->type == SLIC_HANDLE_FREE); \
_adapter->pfree_slic_handles = _pslic_handle->next; \
} \
spin_unlock_irqrestore(&_adapter->handle_lock.lock, \
@@ -325,11 +298,8 @@ static void slic_timer_ping(ulong dev)
struct adapter *adapter;
struct sliccard *card;
- ASSERT(dev);
adapter = netdev_priv((struct net_device *)dev);
- ASSERT(adapter);
card = adapter->card;
- ASSERT(card);
adapter->pingtimer.expires = jiffies + (PING_TIMER_INTERVAL * HZ);
add_timer(&adapter->pingtimer);
@@ -361,9 +331,6 @@ static void slic_link_config(struct adapter *adapter,
if (adapter->state != ADAPT_UP)
return;
- ASSERT((adapter->devid == SLIC_1GB_DEVICE_ID)
- || (adapter->devid == SLIC_2GB_DEVICE_ID));
-
if (linkspeed > LINK_1000MB)
linkspeed = LINK_AUTOSPEED;
if (linkduplex > LINK_AUTOD)
@@ -593,8 +560,7 @@ static int slic_card_download(struct adapter *adapter)
file = "slicoss/gbdownload.sys";
break;
default:
- ASSERT(0);
- break;
+ return -ENOENT;
}
ret = request_firmware(&fw, file, &adapter->pcidev->dev);
if (ret) {
@@ -604,7 +570,6 @@ static int slic_card_download(struct adapter *adapter)
}
numsects = *(u32 *)(fw->data + index);
index += 4;
- ASSERT(numsects <= 3);
for (i = 0; i < numsects; i++) {
sectsize[i] = *(u32 *)(fw->data + index);
index += 4;
@@ -1060,8 +1025,6 @@ static void slic_upr_start(struct adapter *adapter)
case SLIC_UPR_PING:
slic_reg32_write(&slic_regs->slic_ping, 1, FLUSH);
break;
- default:
- ASSERT(0);
}
}
@@ -1116,9 +1079,6 @@ static void slic_link_upr_complete(struct adapter *adapter, u32 isr)
if (adapter->state != ADAPT_UP)
return;
- ASSERT((adapter->devid == SLIC_1GB_DEVICE_ID)
- || (adapter->devid == SLIC_2GB_DEVICE_ID));
-
linkup = linkstatus & GIG_LINKUP ? LINK_UP : LINK_DOWN;
if (linkstatus & GIG_SPEED_1000)
linkspeed = LINK_1000MB;
@@ -1170,7 +1130,6 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr)
spin_lock_irqsave(&adapter->upr_lock.lock, adapter->upr_lock.flags);
upr = adapter->upr_list;
if (!upr) {
- ASSERT(0);
spin_unlock_irqrestore(&adapter->upr_lock.lock,
adapter->upr_lock.flags);
return;
@@ -1178,7 +1137,6 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr)
adapter->upr_list = upr->next;
upr->next = NULL;
adapter->upr_busy = 0;
- ASSERT(adapter->port == upr->adapter);
switch (upr->upr_request) {
case SLIC_UPR_STATS:
{
@@ -1260,23 +1218,9 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr)
break;
case SLIC_UPR_RCONFIG:
break;
- case SLIC_UPR_RPHY:
- ASSERT(0);
- break;
- case SLIC_UPR_ENLB:
- ASSERT(0);
- break;
- case SLIC_UPR_ENCT:
- ASSERT(0);
- break;
- case SLIC_UPR_PDWN:
- ASSERT(0);
- break;
case SLIC_UPR_PING:
card->pingstatus |= (isr & ISR_PINGDSMASK);
break;
- default:
- ASSERT(0);
}
kfree(upr);
slic_upr_start(adapter);
@@ -1292,7 +1236,6 @@ static void slic_config_get(struct adapter *adapter, u32 config,
status = slic_upr_request(adapter,
SLIC_UPR_RCONFIG,
(u32) config, (u32) config_h, 0, 0);
- ASSERT(status == 0);
}
/*
@@ -1422,7 +1365,6 @@ static int slic_rspqueue_init(struct adapter *adapter)
__iomem struct slic_regs *slic_regs = adapter->slic_regs;
u32 paddrh = 0;
- ASSERT(adapter->state == ADAPT_DOWN);
memset(rspq, 0, sizeof(struct slic_rspqueue));
rspq->num_pages = SLIC_RSPQ_PAGES_GB;
@@ -1439,14 +1381,6 @@ static int slic_rspqueue_init(struct adapter *adapter)
}
/* FIXME:
* do we really need this assertions (4K PAGE_SIZE aligned addr)? */
-#if 0
-#ifndef CONFIG_X86_64
- ASSERT(((u32) rspq->vaddr[i] & 0xFFFFF000) ==
- (u32) rspq->vaddr[i]);
- ASSERT(((u32) rspq->paddr[i] & 0xFFFFF000) ==
- (u32) rspq->paddr[i]);
-#endif
-#endif
memset(rspq->vaddr[i], 0, PAGE_SIZE);
if (paddrh == 0) {
@@ -1475,18 +1409,9 @@ static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter)
return NULL;
buf = rspq->rspbuf;
-#if BITS_PER_LONG == 32
- ASSERT((buf->status & 0xFFFFFFE0) == 0);
-#endif
- ASSERT(buf->hosthandle);
if (++rspq->offset < SLIC_RSPQ_BUFSINPAGE) {
rspq->rspbuf++;
-#if BITS_PER_LONG == 32
- ASSERT(((u32) rspq->rspbuf & 0xFFFFFFE0) ==
- (u32) rspq->rspbuf);
-#endif
} else {
- ASSERT(rspq->offset == SLIC_RSPQ_BUFSINPAGE);
slic_reg64_write(adapter, &adapter->slic_regs->slic_rbar64,
(rspq->paddr[rspq->pageindex] | SLIC_RSPQ_BUFSINPAGE),
&adapter->slic_regs->slic_addr_upper, 0, DONT_FLUSH);
@@ -1494,22 +1419,9 @@ static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter)
rspq->offset = 0;
rspq->rspbuf = (struct slic_rspbuf *)
rspq->vaddr[rspq->pageindex];
-#if BITS_PER_LONG == 32
- ASSERT(((u32) rspq->rspbuf & 0xFFFFF000) ==
- (u32) rspq->rspbuf);
-#endif
}
-#if BITS_PER_LONG == 32
- ASSERT(((u32) buf & 0xFFFFFFE0) == (u32) buf);
-#endif
- return buf;
-}
-
-static void slic_cmdqmem_init(struct adapter *adapter)
-{
- struct slic_cmdqmem *cmdqmem = &adapter->cmdqmem;
- memset(cmdqmem, 0, sizeof(struct slic_cmdqmem));
+ return buf;
}
static void slic_cmdqmem_free(struct adapter *adapter)
@@ -1540,9 +1452,7 @@ static u32 *slic_cmdqmem_addpage(struct adapter *adapter)
&cmdqmem->dma_pages[cmdqmem->pagecnt]);
if (!pageaddr)
return NULL;
-#if BITS_PER_LONG == 32
- ASSERT(((u32) pageaddr & 0xFFFFF000) == (u32) pageaddr);
-#endif
+
cmdqmem->pages[cmdqmem->pagecnt] = pageaddr;
cmdqmem->pagecnt++;
return pageaddr;
@@ -1598,11 +1508,6 @@ static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page)
(adapter->slic_handle_ix < 256)) {
/* Allocate and initialize a SLIC_HANDLE for this command */
SLIC_GET_SLIC_HANDLE(adapter, pslic_handle);
- if (pslic_handle == NULL)
- ASSERT(0);
- ASSERT(pslic_handle ==
- &adapter->slic_handles[pslic_handle->token.
- handle_index]);
pslic_handle->type = SLIC_HANDLE_CMD;
pslic_handle->address = (void *) cmd;
pslic_handle->offset = (ushort) adapter->slic_handle_ix++;
@@ -1641,20 +1546,16 @@ static int slic_cmdq_init(struct adapter *adapter)
int i;
u32 *pageaddr;
- ASSERT(adapter->state == ADAPT_DOWN);
memset(&adapter->cmdq_all, 0, sizeof(struct slic_cmdqueue));
memset(&adapter->cmdq_free, 0, sizeof(struct slic_cmdqueue));
memset(&adapter->cmdq_done, 0, sizeof(struct slic_cmdqueue));
spin_lock_init(&adapter->cmdq_all.lock.lock);
spin_lock_init(&adapter->cmdq_free.lock.lock);
spin_lock_init(&adapter->cmdq_done.lock.lock);
- slic_cmdqmem_init(adapter);
+ memset(&adapter->cmdqmem, 0, sizeof(struct slic_cmdqmem));
adapter->slic_handle_ix = 1;
for (i = 0; i < SLIC_CMDQ_INITPAGES; i++) {
pageaddr = slic_cmdqmem_addpage(adapter);
-#if BITS_PER_LONG == 32
- ASSERT(((u32) pageaddr & 0xFFFFF000) == (u32) pageaddr);
-#endif
if (!pageaddr) {
slic_cmdq_free(adapter);
return -ENOMEM;
@@ -1682,7 +1583,6 @@ static void slic_cmdq_reset(struct adapter *adapter)
while (hcmd) {
if (hcmd->busy) {
skb = hcmd->skb;
- ASSERT(skb);
hcmd->busy = 0;
hcmd->skb = NULL;
dev_kfree_skb_irq(skb);
@@ -1718,7 +1618,6 @@ static void slic_cmdq_getdone(struct adapter *adapter)
struct slic_cmdqueue *done_cmdq = &adapter->cmdq_done;
struct slic_cmdqueue *free_cmdq = &adapter->cmdq_free;
- ASSERT(free_cmdq->head == NULL);
spin_lock_irqsave(&done_cmdq->lock.lock, done_cmdq->lock.flags);
free_cmdq->head = done_cmdq->head;
@@ -1884,7 +1783,6 @@ static int slic_rcvqueue_init(struct adapter *adapter)
int i, count;
struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
- ASSERT(adapter->state == ADAPT_DOWN);
rcvq->tail = NULL;
rcvq->head = NULL;
rcvq->size = SLIC_RCVQ_ENTRIES;
@@ -1913,7 +1811,6 @@ static struct sk_buff *slic_rcvqueue_getnext(struct adapter *adapter)
if (rcvq->count) {
skb = rcvq->head;
rcvbuf = (struct slic_rcvbuf *)skb->head;
- ASSERT(rcvbuf);
if (rcvbuf->status & IRHDDR_SVALID) {
rcvq->head = rcvq->head->next;
@@ -1946,8 +1843,6 @@ static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb)
struct slic_rcvbuf *rcvbuf = (struct slic_rcvbuf *)skb->head;
struct device *dev;
- ASSERT(skb->len == SLIC_RCVBUF_HEADSIZE);
-
paddr = (void *)pci_map_single(adapter->pcidev, skb->head,
SLIC_RCVQ_RCVBUFSIZE, PCI_DMA_FROMDEVICE);
rcvbuf->status = 0;
@@ -2019,7 +1914,6 @@ static int slic_debug_card_show(struct seq_file *seq, void *v)
card->adapters_activated);
seq_printf(seq, " Allocated : %d\n",
card->adapters_allocated);
- ASSERT(card->card_size <= SLIC_NBR_MACS);
for (i = 0; i < card->card_size; i++) {
seq_printf(seq,
" MAC%d : %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
@@ -2460,7 +2354,6 @@ static void slic_link_event_handler(struct adapter *adapter)
(u32) &pshmem->linkstatus, /* no 4GB wrap guaranteed */
0, 0, 0);
#endif
- ASSERT(status == 0);
}
static void slic_init_cleanup(struct adapter *adapter)
@@ -2524,8 +2417,6 @@ static void slic_mcast_set_list(struct net_device *dev)
char *addresses;
struct netdev_hw_addr *ha;
- ASSERT(adapter);
-
netdev_for_each_mc_addr(ha, dev) {
addresses = (char *) &ha->addr;
status = slic_mcast_add_list(adapter, addresses);
@@ -2612,8 +2503,6 @@ static void slic_xmit_fail(struct adapter *adapter,
"xmit_start skb[%p] type[%x] No host commands "
"available\n", skb, skb->pkt_type);
break;
- default:
- ASSERT(0);
}
}
dev_kfree_skb(skb);
@@ -2725,7 +2614,6 @@ static void slic_rcv_handler(struct adapter *adapter)
while ((skb = slic_rcvqueue_getnext(adapter))) {
u32 rx_bytes;
- ASSERT(skb->head);
rcvbuf = (struct slic_rcvbuf *)skb->head;
adapter->card->events++;
if (rcvbuf->status & IRHDDR_ERR) {
@@ -2781,16 +2669,11 @@ static void slic_xmit_complete(struct adapter *adapter)
Get the complete host command buffer
*/
slic_handle_word.handle_token = rspbuf->hosthandle;
- ASSERT(slic_handle_word.handle_index);
- ASSERT(slic_handle_word.handle_index <= SLIC_CMDQ_MAXCMDS);
hcmd =
(struct slic_hostcmd *)
adapter->slic_handles[slic_handle_word.handle_index].
address;
/* hcmd = (struct slic_hostcmd *) rspbuf->hosthandle; */
- ASSERT(hcmd);
- ASSERT(hcmd->pslic_handle ==
- &adapter->slic_handles[slic_handle_word.handle_index]);
if (hcmd->type == SLIC_CMD_DUMB) {
if (hcmd->skb)
dev_kfree_skb_irq(hcmd->skb);
@@ -2884,9 +2767,6 @@ static irqreturn_t slic_interrupt(int irq, void *dev_id)
slic_upr_request_complete(adapter, isr);
}
break;
-
- default:
- break;
}
adapter->isrcopy = 0;
@@ -2911,7 +2791,6 @@ static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
void *offloadcmd = NULL;
card = adapter->card;
- ASSERT(card);
if ((adapter->linkstate != LINK_UP) ||
(adapter->state != ADAPT_UP) || (card->state != CARD_UP)) {
status = XMIT_FAIL_LINK_STATE;
@@ -2929,9 +2808,6 @@ static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
status = XMIT_FAIL_HOSTCMD_FAIL;
goto xmit_fail;
}
- ASSERT(hcmd->pslic_handle);
- ASSERT(hcmd->cmd64.hosthandle ==
- hcmd->pslic_handle->token.handle_token);
hcmd->skb = skb;
hcmd->busy = 1;
hcmd->type = SLIC_CMD_DUMB;
@@ -3024,8 +2900,6 @@ static int slic_if_init(struct adapter *adapter)
struct slic_shmem *pshmem;
int rc;
- ASSERT(card);
-
/* adapter should be down at this point */
if (adapter->state != ADAPT_DOWN) {
dev_err(&dev->dev, "%s: adapter->state != ADAPT_DOWN\n",
@@ -3033,7 +2907,6 @@ static int slic_if_init(struct adapter *adapter)
rc = -EIO;
goto err;
}
- ASSERT(adapter->linkstate == LINK_DOWN);
adapter->devflags_prev = dev->flags;
adapter->macopts = MAC_DIRECTED;
@@ -3133,9 +3006,6 @@ static int slic_entry_open(struct net_device *dev)
struct sliccard *card = adapter->card;
int status;
- ASSERT(adapter);
- ASSERT(card);
-
netif_stop_queue(adapter->netdev);
spin_lock_irqsave(&slic_global.driver_lock.lock,
@@ -3176,7 +3046,7 @@ static void slic_card_cleanup(struct sliccard *card)
kfree(card);
}
-static void __devexit slic_entry_remove(struct pci_dev *pcidev)
+static void slic_entry_remove(struct pci_dev *pcidev)
{
struct net_device *dev = pci_get_drvdata(pcidev);
u32 mmio_start = 0;
@@ -3202,9 +3072,7 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev)
mlist = mlist->next;
kfree(mcaddr);
}
- ASSERT(adapter->card);
card = adapter->card;
- ASSERT(card->adapters_allocated);
card->adapters_allocated--;
adapter->allocated = 0;
if (!card->adapters_allocated) {
@@ -3214,10 +3082,8 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev)
} else {
while (curr_card->next != card)
curr_card = curr_card->next;
- ASSERT(curr_card);
curr_card->next = card->next;
}
- ASSERT(slic_global.num_slic_cards);
slic_global.num_slic_cards--;
slic_card_cleanup(card);
}
@@ -3234,14 +3100,12 @@ static int slic_entry_halt(struct net_device *dev)
spin_lock_irqsave(&slic_global.driver_lock.lock,
slic_global.driver_lock.flags);
- ASSERT(card);
netif_stop_queue(adapter->netdev);
adapter->state = ADAPT_DOWN;
adapter->linkstate = LINK_DOWN;
adapter->upr_list = NULL;
adapter->upr_busy = 0;
adapter->devflags_prev = 0;
- ASSERT(card->adapter[adapter->cardindex] == adapter);
slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
adapter->all_reg_writes++;
adapter->icr_reg_writes++;
@@ -3273,7 +3137,6 @@ static struct net_device_stats *slic_get_stats(struct net_device *dev)
{
struct adapter *adapter = netdev_priv(dev);
- ASSERT(adapter);
dev->stats.collisions = adapter->slic_stats.iface.xmit_collisions;
dev->stats.rx_errors = adapter->slic_stats.iface.rcv_errors;
dev->stats.tx_errors = adapter->slic_stats.iface.xmt_errors;
@@ -3296,7 +3159,6 @@ static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
u32 data[7];
u32 intagg;
- ASSERT(rq);
switch (cmd) {
case SIOCSLICSETINTAGG:
if (copy_from_user(data, rq->ifr_data, 28))
@@ -3342,7 +3204,6 @@ static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
}
#endif
case SIOCETHTOOL:
- ASSERT(adapter);
if (copy_from_user(&ecmd, rq->ifr_data, sizeof(ecmd)))
return -EFAULT;
@@ -3682,7 +3543,6 @@ static void slic_init_adapter(struct net_device *netdev,
/*
Initialize slic_handle array
*/
- ASSERT(SLIC_CMDQ_MAXCMDS <= 0xFFFF);
/*
Start with 1. 0 is an invalid host handle.
*/
@@ -3699,8 +3559,6 @@ static void slic_init_adapter(struct net_device *netdev,
sizeof(struct slic_shmem),
&adapter->
phys_shmem);
- ASSERT(adapter->pshmem);
-
if (adapter->pshmem)
memset(adapter->pshmem, 0, sizeof(struct slic_shmem));
}
@@ -3775,11 +3633,9 @@ static u32 slic_card_locate(struct adapter *adapter)
}
}
- ASSERT(card);
if (!card)
return -ENXIO;
/* Put the adapter in the card's adapter list */
- ASSERT(card->adapter[adapter->port] == NULL);
if (!card->adapter[adapter->port]) {
card->adapter[adapter->port] = adapter;
adapter->card = card;
@@ -3794,7 +3650,6 @@ static u32 slic_card_locate(struct adapter *adapter)
else
break;
}
- ASSERT(i != SLIC_MAX_PORTS);
if (physcard->adapter[i]->slotnumber == adapter->slotnumber)
break;
physcard = physcard->next;
@@ -3802,7 +3657,11 @@ static u32 slic_card_locate(struct adapter *adapter)
if (!physcard) {
/* no structure allocated for this physical card yet */
physcard = kzalloc(sizeof(struct physcard), GFP_ATOMIC);
- ASSERT(physcard);
+ if (!physcard) {
+ if (card_hostid == SLIC_HOSTID_DEFAULT)
+ kfree(card);
+ return -ENOMEM;
+ }
physcard->next = slic_global.phys_card;
slic_global.phys_card = physcard;
@@ -3813,14 +3672,13 @@ static u32 slic_card_locate(struct adapter *adapter)
/* Note - this is ZERO relative */
adapter->physport = physcard->adapters_allocd - 1;
- ASSERT(physcard->adapter[adapter->physport] == NULL);
physcard->adapter[adapter->physport] = adapter;
adapter->physcard = physcard;
return 0;
}
-static int __devinit slic_entry_probe(struct pci_dev *pcidev,
+static int slic_entry_probe(struct pci_dev *pcidev,
const struct pci_device_id *pci_tbl_entry)
{
static int cards_found;
@@ -3962,7 +3820,7 @@ static struct pci_driver slic_driver = {
.name = DRV_NAME,
.id_table = slic_pci_tbl,
.probe = slic_entry_probe,
- .remove = __devexit_p(slic_entry_remove),
+ .remove = slic_entry_remove,
};
static int __init slic_module_init(void)
diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c
index f27182d4dea..0764bbbfd49 100644
--- a/drivers/staging/sm7xxfb/sm7xxfb.c
+++ b/drivers/staging/sm7xxfb/sm7xxfb.c
@@ -768,7 +768,7 @@ static inline void sm7xx_init_hw(void)
outb_p(0x11, 0x3c5);
}
-static int __devinit smtcfb_pci_probe(struct pci_dev *pdev,
+static int smtcfb_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct smtcfb_info *sfb;
@@ -928,7 +928,7 @@ static DEFINE_PCI_DEVICE_TABLE(smtcfb_pci_table) = {
{0,}
};
-static void __devexit smtcfb_pci_remove(struct pci_dev *pdev)
+static void smtcfb_pci_remove(struct pci_dev *pdev)
{
struct smtcfb_info *sfb;
@@ -1027,7 +1027,7 @@ static struct pci_driver smtcfb_driver = {
.name = "smtcfb",
.id_table = smtcfb_pci_table,
.probe = smtcfb_pci_probe,
- .remove = __devexit_p(smtcfb_pci_remove),
+ .remove = smtcfb_pci_remove,
.driver.pm = SM7XX_PM_OPS,
};
diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
index 277491a877e..299f5181019 100644
--- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
+++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
@@ -31,6 +31,7 @@
#include <linux/interrupt.h>
#include <linux/regulator/consumer.h>
#include <linux/module.h>
+#include <linux/input/mt.h>
#include "synaptics_i2c_rmi4.h"
/* TODO: for multiple device support will need a per-device mutex */
@@ -67,7 +68,6 @@
#define PDT_START_SCAN_LOCATION (0x00E9)
#define PDT_END_SCAN_LOCATION (0x000A)
#define PDT_ENTRY_SIZE (0x0006)
-#define RMI4_NUMBER_OF_MAX_FINGERS (8)
#define SYNAPTICS_RMI4_TOUCHPAD_FUNC_NUM (0x11)
#define SYNAPTICS_RMI4_DEVICE_CONTROL_FUNC_NUM (0x01)
@@ -164,6 +164,7 @@ struct synaptics_rmi4_device_info {
* @regulator: pointer to the regulator structure
* @wait: wait queue structure variable
* @touch_stopped: flag to stop the thread function
+ * @fingers_supported: maximum supported fingers
*
* This structure gives the device data information.
*/
@@ -184,6 +185,7 @@ struct synaptics_rmi4_data {
struct regulator *regulator;
wait_queue_head_t wait;
bool touch_stopped;
+ unsigned char fingers_supported;
};
/**
@@ -303,22 +305,21 @@ static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata,
/* number of touch points - fingers down in this case */
int touch_count = 0;
int finger;
- int fingers_supported;
int finger_registers;
int reg;
int finger_shift;
int finger_status;
int retval;
+ int x, y;
+ int wx, wy;
unsigned short data_base_addr;
unsigned short data_offset;
unsigned char data_reg_blk_size;
unsigned char values[2];
unsigned char data[DATA_LEN];
- int x[RMI4_NUMBER_OF_MAX_FINGERS];
- int y[RMI4_NUMBER_OF_MAX_FINGERS];
- int wx[RMI4_NUMBER_OF_MAX_FINGERS];
- int wy[RMI4_NUMBER_OF_MAX_FINGERS];
+ unsigned char fingers_supported = pdata->fingers_supported;
struct i2c_client *client = pdata->i2c_client;
+ struct input_dev *input_dev = pdata->input_dev;
/* get 2D sensor finger data */
/*
@@ -333,7 +334,6 @@ static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata,
* 10 = finger present but data may not be accurate,
* 11 = reserved for product use.
*/
- fingers_supported = rfi->num_of_data_points;
finger_registers = (fingers_supported + 3)/4;
data_base_addr = rfi->fn_desc.data_base_addr;
retval = synaptics_rmi4_i2c_block_read(pdata, data_base_addr, values,
@@ -358,7 +358,11 @@ static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata,
* if finger status indicates a finger is present then
* read the finger data and report it
*/
- if (finger_status == 1 || finger_status == 2) {
+ input_mt_slot(input_dev, finger);
+ input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
+ finger_status != 0);
+
+ if (finger_status) {
/* Read the finger data */
data_offset = data_base_addr +
((finger * data_reg_blk_size) +
@@ -367,50 +371,33 @@ static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata,
data_offset, data,
data_reg_blk_size);
if (retval != data_reg_blk_size) {
- printk(KERN_ERR "%s:read data failed\n",
+ dev_err(&client->dev, "%s:read data failed\n",
__func__);
return 0;
- } else {
- x[touch_count] =
- (data[0] << 4) | (data[2] & MASK_4BIT);
- y[touch_count] =
- (data[1] << 4) |
- ((data[2] >> 4) & MASK_4BIT);
- wy[touch_count] =
- (data[3] >> 4) & MASK_4BIT;
- wx[touch_count] =
- (data[3] & MASK_4BIT);
-
- if (pdata->board->x_flip)
- x[touch_count] =
- pdata->sensor_max_x -
- x[touch_count];
- if (pdata->board->y_flip)
- y[touch_count] =
- pdata->sensor_max_y -
- y[touch_count];
}
+ x = (data[0] << 4) | (data[2] & MASK_4BIT);
+ y = (data[1] << 4) | ((data[2] >> 4) & MASK_4BIT);
+ wy = (data[3] >> 4) & MASK_4BIT;
+ wx = (data[3] & MASK_4BIT);
+
+ if (pdata->board->x_flip)
+ x = pdata->sensor_max_x - x;
+ if (pdata->board->y_flip)
+ y = pdata->sensor_max_y - y;
+
+ input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR,
+ max(wx, wy));
+ input_report_abs(input_dev, ABS_MT_POSITION_X, x);
+ input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
+
/* number of active touch points */
touch_count++;
}
}
- /* report to input subsystem */
- if (touch_count) {
- for (finger = 0; finger < touch_count; finger++) {
- input_report_abs(pdata->input_dev, ABS_MT_TOUCH_MAJOR,
- max(wx[finger] , wy[finger]));
- input_report_abs(pdata->input_dev, ABS_MT_POSITION_X,
- x[finger]);
- input_report_abs(pdata->input_dev, ABS_MT_POSITION_Y,
- y[finger]);
- input_mt_sync(pdata->input_dev);
- }
- } else
- input_mt_sync(pdata->input_dev);
-
/* sync after groups of events */
- input_sync(pdata->input_dev);
+ input_mt_sync_frame(input_dev);
+ input_sync(input_dev);
/* return the number of touch points */
return touch_count;
}
@@ -575,6 +562,7 @@ static int synpatics_rmi4_touchpad_detect(struct synaptics_rmi4_data *pdata,
if ((queries[1] & MASK_3BIT) == 5)
rfi->num_of_data_points = 10;
}
+ pdata->fingers_supported = rfi->num_of_data_points;
/* Need to get interrupt info for handling interrupts */
rfi->index_to_intr_reg = (interruptcount + 7)/8;
if (rfi->index_to_intr_reg != 0)
@@ -891,7 +879,7 @@ static int synaptics_rmi4_i2c_query_device(struct synaptics_rmi4_data *pdata)
* the rmi4 Physical Device Table and enumerate any rmi4 functions that
* have data sources associated with them.
*/
-static int __devinit synaptics_rmi4_probe
+static int synaptics_rmi4_probe
(struct i2c_client *client, const struct i2c_device_id *dev_id)
{
int retval;
@@ -988,6 +976,8 @@ static int __devinit synaptics_rmi4_probe
rmi4_data->sensor_max_y, 0, 0);
input_set_abs_params(rmi4_data->input_dev, ABS_MT_TOUCH_MAJOR, 0,
MAX_TOUCH_MAJOR, 0, 0);
+ input_mt_init_slots(rmi4_data->input_dev,
+ rmi4_data->fingers_supported, 0);
/* Clear interrupts */
synaptics_rmi4_i2c_block_read(rmi4_data,
@@ -1032,7 +1022,7 @@ err_input:
* This function uses to remove the i2c-client
* touchscreen driver and returns integer.
*/
-static int __devexit synaptics_rmi4_remove(struct i2c_client *client)
+static int synaptics_rmi4_remove(struct i2c_client *client)
{
struct synaptics_rmi4_data *rmi4_data = i2c_get_clientdata(client);
const struct synaptics_rmi4_platform_data *pdata = rmi4_data->board;
@@ -1140,33 +1130,11 @@ static struct i2c_driver synaptics_rmi4_driver = {
#endif
},
.probe = synaptics_rmi4_probe,
- .remove = __devexit_p(synaptics_rmi4_remove),
+ .remove = synaptics_rmi4_remove,
.id_table = synaptics_rmi4_id_table,
};
-/**
- * synaptics_rmi4_init() - Initialize the touchscreen driver
- *
- * This function uses to initializes the synaptics
- * touchscreen driver and returns integer.
- */
-static int __init synaptics_rmi4_init(void)
-{
- return i2c_add_driver(&synaptics_rmi4_driver);
-}
-/**
- * synaptics_rmi4_exit() - De-initialize the touchscreen driver
- *
- * This function uses to de-initialize the synaptics
- * touchscreen driver and returns none.
- */
-static void __exit synaptics_rmi4_exit(void)
-{
- i2c_del_driver(&synaptics_rmi4_driver);
-}
-
-module_init(synaptics_rmi4_init);
-module_exit(synaptics_rmi4_exit);
+module_i2c_driver(synaptics_rmi4_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("naveen.gaddipati@stericsson.com, js.ha@stericsson.com");
diff --git a/drivers/staging/telephony/Kconfig b/drivers/staging/telephony/Kconfig
deleted file mode 100644
index b5f78b6ed2b..00000000000
--- a/drivers/staging/telephony/Kconfig
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# Telephony device configuration
-#
-
-menuconfig PHONE
- tristate "Telephony support"
- depends on HAS_IOMEM
- ---help---
- Say Y here if you have a telephony card, which for example allows
- you to use a regular phone for voice-over-IP applications.
-
- Note: this has nothing to do with modems. You do not need to say Y
- here in order to be able to use a modem under Linux.
-
- To compile this driver as a module, choose M here: the
- module will be called phonedev.
-
-if PHONE
-
-config PHONE_IXJ
- tristate "QuickNet Internet LineJack/PhoneJack support"
- depends on ISA || PCI
- ---help---
- Say M if you have a telephony card manufactured by Quicknet
- Technologies, Inc. These include the Internet PhoneJACK and
- Internet LineJACK Telephony Cards. You will get a module called
- ixj.
-
- For the ISA versions of these products, you can configure the
- cards using the isapnp tools (pnpdump/isapnp) or you can use the
- isapnp support. Please read <file:Documentation/telephony/ixj.txt>.
-
- For more information on these cards, see Quicknet's web site at:
- <http://www.quicknet.net/>.
-
- If you do not have any Quicknet telephony cards, you can safely
- say N here.
-
-config PHONE_IXJ_PCMCIA
- tristate "QuickNet Internet LineJack/PhoneJack PCMCIA support"
- depends on PHONE_IXJ && PCMCIA
- help
- Say Y here to configure in PCMCIA service support for the Quicknet
- cards manufactured by Quicknet Technologies, Inc. This changes the
- card initialization code to work with the card manager daemon.
-
-endif # PHONE
diff --git a/drivers/staging/telephony/Makefile b/drivers/staging/telephony/Makefile
deleted file mode 100644
index 1206615d69e..00000000000
--- a/drivers/staging/telephony/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for drivers/telephony
-#
-
-obj-$(CONFIG_PHONE) += phonedev.o
-obj-$(CONFIG_PHONE_IXJ) += ixj.o
-obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o
diff --git a/drivers/staging/telephony/TODO b/drivers/staging/telephony/TODO
deleted file mode 100644
index d47dec3508d..00000000000
--- a/drivers/staging/telephony/TODO
+++ /dev/null
@@ -1,10 +0,0 @@
-TODO
-. Determine if the boards are still in use
- and move this module back to drivers/telephony if necessary
-. Coding style cleanups
-
-Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
-cc Joe Perches <joe@perches.com> if the module should be reactivated.
-
-If no module activity occurs before version 3.6 is released, this
-module should be removed.
diff --git a/drivers/staging/telephony/ixj-ver.h b/drivers/staging/telephony/ixj-ver.h
deleted file mode 100644
index 2031ac6c888..00000000000
--- a/drivers/staging/telephony/ixj-ver.h
+++ /dev/null
@@ -1,4 +0,0 @@
-/* configuration management identifiers */
-#define IXJ_VER_MAJOR 1
-#define IXJ_VER_MINOR 0
-#define IXJ_BLD_VER 1
diff --git a/drivers/staging/telephony/ixj.c b/drivers/staging/telephony/ixj.c
deleted file mode 100644
index 1cfa0b07d72..00000000000
--- a/drivers/staging/telephony/ixj.c
+++ /dev/null
@@ -1,10571 +0,0 @@
-/****************************************************************************
- * ixj.c
- *
- * Device Driver for Quicknet Technologies, Inc.'s Telephony cards
- * including the Internet PhoneJACK, Internet PhoneJACK Lite,
- * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and
- * SmartCABLE
- *
- * (c) Copyright 1999-2001 Quicknet Technologies, 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.
- *
- * Author: Ed Okerson, <eokerson@quicknet.net>
- *
- * Contributors: Greg Herlein, <gherlein@quicknet.net>
- * David W. Erhart, <derhart@quicknet.net>
- * John Sellers, <jsellers@quicknet.net>
- * Mike Preston, <mpreston@quicknet.net>
- *
- * Fixes: David Huggins-Daines, <dhd@cepstral.com>
- * Fabio Ferrari, <fabio.ferrari@digitro.com.br>
- * Artis Kugevics, <artis@mt.lv>
- * Daniele Bellucci, <bellucda@tiscali.it>
- *
- * More information about the hardware related to this driver can be found
- * at our website: http://www.quicknet.net
- *
- * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
- * TECHNOLOGIES, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION
- * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- ***************************************************************************/
-
-/*
- * Revision 4.8 2003/07/09 19:39:00 Daniele Bellucci
- * Audit some copy_*_user and minor cleanup.
- *
- * Revision 4.7 2001/08/13 06:19:33 craigs
- * Added additional changes from Alan Cox and John Anderson for
- * 2.2 to 2.4 cleanup and bounds checking
- *
- * Revision 4.6 2001/08/13 01:05:05 craigs
- * Really fixed PHONE_QUERY_CODEC problem this time
- *
- * Revision 4.5 2001/08/13 00:11:03 craigs
- * Fixed problem in handling of PHONE_QUERY_CODEC, thanks to Shane Anderson
- *
- * Revision 4.4 2001/08/07 07:58:12 craigs
- * Changed back to three digit version numbers
- * Added tagbuild target to allow automatic and easy tagging of versions
- *
- * Revision 4.3 2001/08/07 07:24:47 craigs
- * Added ixj-ver.h to allow easy configuration management of driver
- * Added display of version number in /prox/ixj
- *
- * Revision 4.2 2001/08/06 07:07:19 craigs
- * Reverted IXJCTL_DSP_TYPE and IXJCTL_DSP_VERSION files to original
- * behaviour of returning int rather than short *
- *
- * Revision 4.1 2001/08/05 00:17:37 craigs
- * More changes for correct PCMCIA installation
- * Start of changes for backward Linux compatibility
- *
- * Revision 4.0 2001/08/04 12:33:12 craigs
- * New version using GNU autoconf
- *
- * Revision 3.105 2001/07/20 23:14:32 eokerson
- * More work on CallerID generation when using ring cadences.
- *
- * Revision 3.104 2001/07/06 01:33:55 eokerson
- * Some bugfixes from Robert Vojta <vojta@ipex.cz> and a few mods to the Makefile.
- *
- * Revision 3.103 2001/07/05 19:20:16 eokerson
- * Updated HOWTO
- * Changed mic gain to 30dB on Internet LineJACK mic/speaker port.
- *
- * Revision 3.102 2001/07/03 23:51:21 eokerson
- * Un-mute mic on Internet LineJACK when in speakerphone mode.
- *
- * Revision 3.101 2001/07/02 19:26:56 eokerson
- * Removed initialiazation of ixjdebug and ixj_convert_loaded so they will go in the .bss instead of the .data
- *
- * Revision 3.100 2001/07/02 19:18:27 eokerson
- * Changed driver to make dynamic allocation possible. We now pass IXJ * between functions instead of array indexes.
- * Fixed the way the POTS and PSTN ports interact during a PSTN call to allow local answering.
- * Fixed speaker mode on Internet LineJACK.
- *
- * Revision 3.99 2001/05/09 14:11:16 eokerson
- * Fixed kmalloc error in ixj_build_filter_cadence. Thanks David Chan <cat@waulogy.stanford.edu>.
- *
- * Revision 3.98 2001/05/08 19:55:33 eokerson
- * Fixed POTS hookstate detection while it is connected to PSTN port.
- *
- * Revision 3.97 2001/05/08 00:01:04 eokerson
- * Fixed kernel oops when sending caller ID data.
- *
- * Revision 3.96 2001/05/04 23:09:30 eokerson
- * Now uses one kernel timer for each card, instead of one for the entire driver.
- *
- * Revision 3.95 2001/04/25 22:06:47 eokerson
- * Fixed squawking at beginning of some G.723.1 calls.
- *
- * Revision 3.94 2001/04/03 23:42:00 eokerson
- * Added linear volume ioctls
- * Added raw filter load ioctl
- *
- * Revision 3.93 2001/02/27 01:00:06 eokerson
- * Fixed blocking in CallerID.
- * Reduced size of ixj structure for smaller driver footprint.
- *
- * Revision 3.92 2001/02/20 22:02:59 eokerson
- * Fixed isapnp and pcmcia module compatibility for 2.4.x kernels.
- * Improved PSTN ring detection.
- * Fixed wink generation on POTS ports.
- *
- * Revision 3.91 2001/02/13 00:55:44 eokerson
- * Turn AEC back on after changing frame sizes.
- *
- * Revision 3.90 2001/02/12 16:42:00 eokerson
- * Added ALAW codec, thanks to Fabio Ferrari for the table based converters to make ALAW from ULAW.
- *
- * Revision 3.89 2001/02/12 15:41:16 eokerson
- * Fix from Artis Kugevics - Tone gains were not being set correctly.
- *
- * Revision 3.88 2001/02/05 23:25:42 eokerson
- * Fixed lockup bugs with deregister.
- *
- * Revision 3.87 2001/01/29 21:00:39 eokerson
- * Fix from Fabio Ferrari <fabio.ferrari@digitro.com.br> to properly handle EAGAIN and EINTR during non-blocking write.
- * Updated copyright date.
- *
- * Revision 3.86 2001/01/23 23:53:46 eokerson
- * Fixes to G.729 compatibility.
- *
- * Revision 3.85 2001/01/23 21:30:36 eokerson
- * Added verbage about cards supported.
- * Removed commands that put the card in low power mode at some times that it should not be in low power mode.
- *
- * Revision 3.84 2001/01/22 23:32:10 eokerson
- * Some bugfixes from David Huggins-Daines, <dhd@cepstral.com> and other cleanups.
- *
- * Revision 3.83 2001/01/19 14:51:41 eokerson
- * Fixed ixj_WriteDSPCommand to decrement usage counter when command fails.
- *
- * Revision 3.82 2001/01/19 00:34:49 eokerson
- * Added verbosity to write overlap errors.
- *
- * Revision 3.81 2001/01/18 23:56:54 eokerson
- * Fixed PSTN line test functions.
- *
- * Revision 3.80 2001/01/18 22:29:27 eokerson
- * Updated AEC/AGC values for different cards.
- *
- * Revision 3.79 2001/01/17 02:58:54 eokerson
- * Fixed AEC reset after Caller ID.
- * Fixed Codec lockup after Caller ID on Call Waiting when not using 30ms frames.
- *
- * Revision 3.78 2001/01/16 19:43:09 eokerson
- * Added support for Linux 2.4.x kernels.
- *
- * Revision 3.77 2001/01/09 04:00:52 eokerson
- * Linetest will now test the line, even if it has previously succeeded.
- *
- * Revision 3.76 2001/01/08 19:27:00 eokerson
- * Fixed problem with standard cable on Internet PhoneCARD.
- *
- * Revision 3.75 2000/12/22 16:52:14 eokerson
- * Modified to allow hookstate detection on the POTS port when the PSTN port is selected.
- *
- * Revision 3.74 2000/12/08 22:41:50 eokerson
- * Added capability for G729B.
- *
- * Revision 3.73 2000/12/07 23:35:16 eokerson
- * Added capability to have different ring pattern before CallerID data.
- * Added hookstate checks in CallerID routines to stop FSK.
- *
- * Revision 3.72 2000/12/06 19:31:31 eokerson
- * Modified signal behavior to only send one signal per event.
- *
- * Revision 3.71 2000/12/06 03:23:08 eokerson
- * Fixed CallerID on Call Waiting.
- *
- * Revision 3.70 2000/12/04 21:29:37 eokerson
- * Added checking to Smart Cable gain functions.
- *
- * Revision 3.69 2000/12/04 21:05:20 eokerson
- * Changed ixjdebug levels.
- * Added ioctls to change gains in Internet Phone CARD Smart Cable.
- *
- * Revision 3.68 2000/12/04 00:17:21 craigs
- * Changed mixer voice gain to +6dB rather than 0dB
- *
- * Revision 3.67 2000/11/30 21:25:51 eokerson
- * Fixed write signal errors.
- *
- * Revision 3.66 2000/11/29 22:42:44 eokerson
- * Fixed PSTN ring detect problems.
- *
- * Revision 3.65 2000/11/29 07:31:55 craigs
- * Added new 425Hz filter co-efficients
- * Added card-specific DTMF prescaler initialisation
- *
- * Revision 3.64 2000/11/28 14:03:32 craigs
- * Changed certain mixer initialisations to be 0dB rather than 12dB
- * Added additional information to /proc/ixj
- *
- * Revision 3.63 2000/11/28 11:38:41 craigs
- * Added display of AEC modes in AUTO and AGC mode
- *
- * Revision 3.62 2000/11/28 04:05:44 eokerson
- * Improved PSTN ring detection routine.
- *
- * Revision 3.61 2000/11/27 21:53:12 eokerson
- * Fixed flash detection.
- *
- * Revision 3.60 2000/11/27 15:57:29 eokerson
- * More work on G.729 load routines.
- *
- * Revision 3.59 2000/11/25 21:55:12 eokerson
- * Fixed errors in G.729 load routine.
- *
- * Revision 3.58 2000/11/25 04:08:29 eokerson
- * Added board locks around G.729 and TS85 load routines.
- *
- * Revision 3.57 2000/11/24 05:35:17 craigs
- * Added ability to retrieve mixer values on LineJACK
- * Added complete initialisation of all mixer values at startup
- * Fixed spelling mistake
- *
- * Revision 3.56 2000/11/23 02:52:11 robertj
- * Added cvs change log keyword.
- * Fixed bug in capabilities list when using G.729 module.
- *
- */
-
-#include "ixj-ver.h"
-
-#define PERFMON_STATS
-#define IXJDEBUG 0
-#define MAXRINGS 5
-
-#include <linux/module.h>
-
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/kernel.h> /* printk() */
-#include <linux/fs.h> /* everything... */
-#include <linux/errno.h> /* error codes */
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
-#include <linux/poll.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#include <linux/isapnp.h>
-
-#include "ixj.h"
-
-#define TYPE(inode) (iminor(inode) >> 4)
-#define NUM(inode) (iminor(inode) & 0xf)
-
-static DEFINE_MUTEX(ixj_mutex);
-static int ixjdebug;
-static int hertz = HZ;
-static int samplerate = 100;
-
-module_param(ixjdebug, int, 0);
-
-static DEFINE_PCI_DEVICE_TABLE(ixj_pci_tbl) = {
- { PCI_VENDOR_ID_QUICKNET, PCI_DEVICE_ID_QUICKNET_XJ,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { }
-};
-MODULE_DEVICE_TABLE(pci, ixj_pci_tbl);
-
-/************************************************************************
-*
-* ixjdebug meanings are now bit mapped instead of level based
-* Values can be or'ed together to turn on multiple messages
-*
-* bit 0 (0x0001) = any failure
-* bit 1 (0x0002) = general messages
-* bit 2 (0x0004) = POTS ringing related
-* bit 3 (0x0008) = PSTN events
-* bit 4 (0x0010) = PSTN Cadence state details
-* bit 5 (0x0020) = Tone detection triggers
-* bit 6 (0x0040) = Tone detection cadence details
-* bit 7 (0x0080) = ioctl tracking
-* bit 8 (0x0100) = signal tracking
-* bit 9 (0x0200) = CallerID generation details
-*
-************************************************************************/
-
-#ifdef IXJ_DYN_ALLOC
-
-static IXJ *ixj[IXJMAX];
-#define get_ixj(b) ixj[(b)]
-
-/*
- * Allocate a free IXJ device
- */
-
-static IXJ *ixj_alloc()
-{
- for(cnt=0; cnt<IXJMAX; cnt++)
- {
- if(ixj[cnt] == NULL || !ixj[cnt]->DSPbase)
- {
- j = kmalloc(sizeof(IXJ), GFP_KERNEL);
- if (j == NULL)
- return NULL;
- ixj[cnt] = j;
- return j;
- }
- }
- return NULL;
-}
-
-static void ixj_fsk_free(IXJ *j)
-{
- kfree(j->fskdata);
- j->fskdata = NULL;
-}
-
-static void ixj_fsk_alloc(IXJ *j)
-{
- if(!j->fskdata) {
- j->fskdata = kmalloc(8000, GFP_KERNEL);
- if (!j->fskdata) {
- if(ixjdebug & 0x0200) {
- printk("IXJ phone%d - allocate failed\n", j->board);
- }
- return;
- } else {
- j->fsksize = 8000;
- if(ixjdebug & 0x0200) {
- printk("IXJ phone%d - allocate succeeded\n", j->board);
- }
- }
- }
-}
-
-#else
-
-static IXJ ixj[IXJMAX];
-#define get_ixj(b) (&ixj[(b)])
-
-/*
- * Allocate a free IXJ device
- */
-
-static IXJ *ixj_alloc(void)
-{
- int cnt;
- for(cnt=0; cnt<IXJMAX; cnt++) {
- if(!ixj[cnt].DSPbase)
- return &ixj[cnt];
- }
- return NULL;
-}
-
-static inline void ixj_fsk_free(IXJ *j) {;}
-
-static inline void ixj_fsk_alloc(IXJ *j)
-{
- j->fsksize = 8000;
-}
-
-#endif
-
-#ifdef PERFMON_STATS
-#define ixj_perfmon(x) ((x)++)
-#else
-#define ixj_perfmon(x) do { } while(0)
-#endif
-
-static int ixj_convert_loaded;
-
-static int ixj_WriteDSPCommand(unsigned short, IXJ *j);
-
-/************************************************************************
-*
-* These are function definitions to allow external modules to register
-* enhanced functionality call backs.
-*
-************************************************************************/
-
-static int Stub(IXJ * J, unsigned long arg)
-{
- return 0;
-}
-
-static IXJ_REGFUNC ixj_PreRead = &Stub;
-static IXJ_REGFUNC ixj_PostRead = &Stub;
-static IXJ_REGFUNC ixj_PreWrite = &Stub;
-static IXJ_REGFUNC ixj_PostWrite = &Stub;
-
-static void ixj_read_frame(IXJ *j);
-static void ixj_write_frame(IXJ *j);
-static void ixj_init_timer(IXJ *j);
-static void ixj_add_timer(IXJ * j);
-static void ixj_timeout(unsigned long ptr);
-static int read_filters(IXJ *j);
-static int LineMonitor(IXJ *j);
-static int ixj_fasync(int fd, struct file *, int mode);
-static int ixj_set_port(IXJ *j, int arg);
-static int ixj_set_pots(IXJ *j, int arg);
-static int ixj_hookstate(IXJ *j);
-static int ixj_record_start(IXJ *j);
-static void ixj_record_stop(IXJ *j);
-static void set_rec_volume(IXJ *j, int volume);
-static int get_rec_volume(IXJ *j);
-static int set_rec_codec(IXJ *j, int rate);
-static void ixj_vad(IXJ *j, int arg);
-static int ixj_play_start(IXJ *j);
-static void ixj_play_stop(IXJ *j);
-static int ixj_set_tone_on(unsigned short arg, IXJ *j);
-static int ixj_set_tone_off(unsigned short, IXJ *j);
-static int ixj_play_tone(IXJ *j, char tone);
-static void ixj_aec_start(IXJ *j, int level);
-static int idle(IXJ *j);
-static void ixj_ring_on(IXJ *j);
-static void ixj_ring_off(IXJ *j);
-static void aec_stop(IXJ *j);
-static void ixj_ringback(IXJ *j);
-static void ixj_busytone(IXJ *j);
-static void ixj_dialtone(IXJ *j);
-static void ixj_cpt_stop(IXJ *j);
-static char daa_int_read(IXJ *j);
-static char daa_CR_read(IXJ *j, int cr);
-static int daa_set_mode(IXJ *j, int mode);
-static int ixj_linetest(IXJ *j);
-static int ixj_daa_write(IXJ *j);
-static int ixj_daa_cid_read(IXJ *j);
-static void DAA_Coeff_US(IXJ *j);
-static void DAA_Coeff_UK(IXJ *j);
-static void DAA_Coeff_France(IXJ *j);
-static void DAA_Coeff_Germany(IXJ *j);
-static void DAA_Coeff_Australia(IXJ *j);
-static void DAA_Coeff_Japan(IXJ *j);
-static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf);
-static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr);
-static int ixj_init_tone(IXJ *j, IXJ_TONE * ti);
-static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp);
-static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp);
-/* Serial Control Interface funtions */
-static int SCI_Control(IXJ *j, int control);
-static int SCI_Prepare(IXJ *j);
-static int SCI_WaitHighSCI(IXJ *j);
-static int SCI_WaitLowSCI(IXJ *j);
-static DWORD PCIEE_GetSerialNumber(WORD wAddress);
-static int ixj_PCcontrol_wait(IXJ *j);
-static void ixj_pre_cid(IXJ *j);
-static void ixj_write_cid(IXJ *j);
-static void ixj_write_cid_bit(IXJ *j, int bit);
-static int set_base_frame(IXJ *j, int size);
-static int set_play_codec(IXJ *j, int rate);
-static void set_rec_depth(IXJ *j, int depth);
-static int ixj_mixer(long val, IXJ *j);
-
-/************************************************************************
-CT8020/CT8021 Host Programmers Model
-Host address Function Access
-DSPbase +
-0-1 Aux Software Status Register (reserved) Read Only
-2-3 Software Status Register Read Only
-4-5 Aux Software Control Register (reserved) Read Write
-6-7 Software Control Register Read Write
-8-9 Hardware Status Register Read Only
-A-B Hardware Control Register Read Write
-C-D Host Transmit (Write) Data Buffer Access Port (buffer input)Write Only
-E-F Host Receive (Read) Data Buffer Access Port (buffer input) Read Only
-************************************************************************/
-
-static inline void ixj_read_HSR(IXJ *j)
-{
- j->hsr.bytes.low = inb_p(j->DSPbase + 8);
- j->hsr.bytes.high = inb_p(j->DSPbase + 9);
-}
-
-static inline int IsControlReady(IXJ *j)
-{
- ixj_read_HSR(j);
- return j->hsr.bits.controlrdy ? 1 : 0;
-}
-
-static inline int IsPCControlReady(IXJ *j)
-{
- j->pccr1.byte = inb_p(j->XILINXbase + 3);
- return j->pccr1.bits.crr ? 1 : 0;
-}
-
-static inline int IsStatusReady(IXJ *j)
-{
- ixj_read_HSR(j);
- return j->hsr.bits.statusrdy ? 1 : 0;
-}
-
-static inline int IsRxReady(IXJ *j)
-{
- ixj_read_HSR(j);
- ixj_perfmon(j->rxreadycheck);
- return j->hsr.bits.rxrdy ? 1 : 0;
-}
-
-static inline int IsTxReady(IXJ *j)
-{
- ixj_read_HSR(j);
- ixj_perfmon(j->txreadycheck);
- return j->hsr.bits.txrdy ? 1 : 0;
-}
-
-static inline void set_play_volume(IXJ *j, int volume)
-{
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "IXJ: /dev/phone%d Setting Play Volume to 0x%4.4x\n", j->board, volume);
- ixj_WriteDSPCommand(0xCF02, j);
- ixj_WriteDSPCommand(volume, j);
-}
-
-static int set_play_volume_linear(IXJ *j, int volume)
-{
- int newvolume, dspplaymax;
-
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Play Volume to 0x%4.4x\n", j->board, volume);
- if(volume > 100 || volume < 0) {
- return -1;
- }
-
- /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
- switch (j->cardtype) {
- case QTI_PHONEJACK:
- dspplaymax = 0x380;
- break;
- case QTI_LINEJACK:
- if(j->port == PORT_PSTN) {
- dspplaymax = 0x48;
- } else {
- dspplaymax = 0x100;
- }
- break;
- case QTI_PHONEJACK_LITE:
- dspplaymax = 0x380;
- break;
- case QTI_PHONEJACK_PCI:
- dspplaymax = 0x6C;
- break;
- case QTI_PHONECARD:
- dspplaymax = 0x50;
- break;
- default:
- return -1;
- }
- newvolume = (dspplaymax * volume) / 100;
- set_play_volume(j, newvolume);
- return 0;
-}
-
-static inline void set_play_depth(IXJ *j, int depth)
-{
- if (depth > 60)
- depth = 60;
- if (depth < 0)
- depth = 0;
- ixj_WriteDSPCommand(0x5280 + depth, j);
-}
-
-static inline int get_play_volume(IXJ *j)
-{
- ixj_WriteDSPCommand(0xCF00, j);
- return j->ssr.high << 8 | j->ssr.low;
-}
-
-static int get_play_volume_linear(IXJ *j)
-{
- int volume, newvolume, dspplaymax;
-
- /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
- switch (j->cardtype) {
- case QTI_PHONEJACK:
- dspplaymax = 0x380;
- break;
- case QTI_LINEJACK:
- if(j->port == PORT_PSTN) {
- dspplaymax = 0x48;
- } else {
- dspplaymax = 0x100;
- }
- break;
- case QTI_PHONEJACK_LITE:
- dspplaymax = 0x380;
- break;
- case QTI_PHONEJACK_PCI:
- dspplaymax = 0x6C;
- break;
- case QTI_PHONECARD:
- dspplaymax = 100;
- break;
- default:
- return -1;
- }
- volume = get_play_volume(j);
- newvolume = (volume * 100) / dspplaymax;
- if(newvolume > 100)
- newvolume = 100;
- return newvolume;
-}
-
-static inline BYTE SLIC_GetState(IXJ *j)
-{
- if (j->cardtype == QTI_PHONECARD) {
- j->pccr1.byte = 0;
- j->psccr.bits.dev = 3;
- j->psccr.bits.rw = 1;
- outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00);
- ixj_PCcontrol_wait(j);
- j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF;
- ixj_PCcontrol_wait(j);
- if (j->pslic.bits.powerdown)
- return PLD_SLIC_STATE_OC;
- else if (!j->pslic.bits.ring0 && !j->pslic.bits.ring1)
- return PLD_SLIC_STATE_ACTIVE;
- else
- return PLD_SLIC_STATE_RINGING;
- } else {
- j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
- }
- return j->pld_slicr.bits.state;
-}
-
-static bool SLIC_SetState(BYTE byState, IXJ *j)
-{
- bool fRetVal = false;
-
- if (j->cardtype == QTI_PHONECARD) {
- if (j->flags.pcmciasct) {
- switch (byState) {
- case PLD_SLIC_STATE_TIPOPEN:
- case PLD_SLIC_STATE_OC:
- j->pslic.bits.powerdown = 1;
- j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
- fRetVal = true;
- break;
- case PLD_SLIC_STATE_RINGING:
- if (j->readers || j->writers) {
- j->pslic.bits.powerdown = 0;
- j->pslic.bits.ring0 = 1;
- j->pslic.bits.ring1 = 0;
- fRetVal = true;
- }
- break;
- case PLD_SLIC_STATE_OHT: /* On-hook transmit */
-
- case PLD_SLIC_STATE_STANDBY:
- case PLD_SLIC_STATE_ACTIVE:
- if (j->readers || j->writers) {
- j->pslic.bits.powerdown = 0;
- } else {
- j->pslic.bits.powerdown = 1;
- }
- j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
- fRetVal = true;
- break;
- case PLD_SLIC_STATE_APR: /* Active polarity reversal */
-
- case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */
-
- default:
- fRetVal = false;
- break;
- }
- j->psccr.bits.dev = 3;
- j->psccr.bits.rw = 0;
- outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
- ixj_PCcontrol_wait(j);
- }
- } else {
- /* Set the C1, C2, C3 & B2EN signals. */
- switch (byState) {
- case PLD_SLIC_STATE_OC:
- j->pld_slicw.bits.c1 = 0;
- j->pld_slicw.bits.c2 = 0;
- j->pld_slicw.bits.c3 = 0;
- j->pld_slicw.bits.b2en = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = true;
- break;
- case PLD_SLIC_STATE_RINGING:
- j->pld_slicw.bits.c1 = 1;
- j->pld_slicw.bits.c2 = 0;
- j->pld_slicw.bits.c3 = 0;
- j->pld_slicw.bits.b2en = 1;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = true;
- break;
- case PLD_SLIC_STATE_ACTIVE:
- j->pld_slicw.bits.c1 = 0;
- j->pld_slicw.bits.c2 = 1;
- j->pld_slicw.bits.c3 = 0;
- j->pld_slicw.bits.b2en = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = true;
- break;
- case PLD_SLIC_STATE_OHT: /* On-hook transmit */
-
- j->pld_slicw.bits.c1 = 1;
- j->pld_slicw.bits.c2 = 1;
- j->pld_slicw.bits.c3 = 0;
- j->pld_slicw.bits.b2en = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = true;
- break;
- case PLD_SLIC_STATE_TIPOPEN:
- j->pld_slicw.bits.c1 = 0;
- j->pld_slicw.bits.c2 = 0;
- j->pld_slicw.bits.c3 = 1;
- j->pld_slicw.bits.b2en = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = true;
- break;
- case PLD_SLIC_STATE_STANDBY:
- j->pld_slicw.bits.c1 = 1;
- j->pld_slicw.bits.c2 = 0;
- j->pld_slicw.bits.c3 = 1;
- j->pld_slicw.bits.b2en = 1;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = true;
- break;
- case PLD_SLIC_STATE_APR: /* Active polarity reversal */
-
- j->pld_slicw.bits.c1 = 0;
- j->pld_slicw.bits.c2 = 1;
- j->pld_slicw.bits.c3 = 1;
- j->pld_slicw.bits.b2en = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = true;
- break;
- case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */
-
- j->pld_slicw.bits.c1 = 1;
- j->pld_slicw.bits.c2 = 1;
- j->pld_slicw.bits.c3 = 1;
- j->pld_slicw.bits.b2en = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = true;
- break;
- default:
- fRetVal = false;
- break;
- }
- }
-
- return fRetVal;
-}
-
-static int ixj_wink(IXJ *j)
-{
- BYTE slicnow;
-
- slicnow = SLIC_GetState(j);
-
- j->pots_winkstart = jiffies;
- SLIC_SetState(PLD_SLIC_STATE_OC, j);
-
- msleep(jiffies_to_msecs(j->winktime));
-
- SLIC_SetState(slicnow, j);
- return 0;
-}
-
-static void ixj_init_timer(IXJ *j)
-{
- init_timer(&j->timer);
- j->timer.function = ixj_timeout;
- j->timer.data = (unsigned long)j;
-}
-
-static void ixj_add_timer(IXJ *j)
-{
- j->timer.expires = jiffies + (hertz / samplerate);
- add_timer(&j->timer);
-}
-
-static void ixj_tone_timeout(IXJ *j)
-{
- IXJ_TONE ti;
-
- j->tone_state++;
- if (j->tone_state == 3) {
- j->tone_state = 0;
- if (j->cadence_t) {
- j->tone_cadence_state++;
- if (j->tone_cadence_state >= j->cadence_t->elements_used) {
- switch (j->cadence_t->termination) {
- case PLAY_ONCE:
- ixj_cpt_stop(j);
- break;
- case REPEAT_LAST_ELEMENT:
- j->tone_cadence_state--;
- ixj_play_tone(j, j->cadence_t->ce[j->tone_cadence_state].index);
- break;
- case REPEAT_ALL:
- j->tone_cadence_state = 0;
- if (j->cadence_t->ce[j->tone_cadence_state].freq0) {
- ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
- ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
- ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
- ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
- ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
- ixj_init_tone(j, &ti);
- }
- ixj_set_tone_on(j->cadence_t->ce[0].tone_on_time, j);
- ixj_set_tone_off(j->cadence_t->ce[0].tone_off_time, j);
- ixj_play_tone(j, j->cadence_t->ce[0].index);
- break;
- }
- } else {
- if (j->cadence_t->ce[j->tone_cadence_state].gain0) {
- ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
- ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
- ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
- ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
- ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
- ixj_init_tone(j, &ti);
- }
- ixj_set_tone_on(j->cadence_t->ce[j->tone_cadence_state].tone_on_time, j);
- ixj_set_tone_off(j->cadence_t->ce[j->tone_cadence_state].tone_off_time, j);
- ixj_play_tone(j, j->cadence_t->ce[j->tone_cadence_state].index);
- }
- }
- }
-}
-
-static inline void ixj_kill_fasync(IXJ *j, IXJ_SIGEVENT event, int dir)
-{
- if(j->ixj_signals[event]) {
- if(ixjdebug & 0x0100)
- printk("Sending signal for event %d\n", event);
- /* Send apps notice of change */
- /* see config.h for macro definition */
- kill_fasync(&(j->async_queue), j->ixj_signals[event], dir);
- }
-}
-
-static void ixj_pstn_state(IXJ *j)
-{
- int var;
- union XOPXR0 XR0, daaint;
-
- var = 10;
-
- XR0.reg = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg;
- daaint.reg = 0;
- XR0.bitreg.RMR = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR;
-
- j->pld_scrr.byte = inb_p(j->XILINXbase);
- if (j->pld_scrr.bits.daaflag) {
- daa_int_read(j);
- if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) {
- if(time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) {
- daaint.bitreg.RING = 1;
- if(ixjdebug & 0x0008) {
- printk(KERN_INFO "IXJ DAA Ring Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
- }
- } else {
- daa_set_mode(j, SOP_PU_RESET);
- }
- }
- if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Caller_ID) {
- daaint.bitreg.Caller_ID = 1;
- j->pstn_cid_intr = 1;
- j->pstn_cid_received = jiffies;
- if(ixjdebug & 0x0008) {
- printk(KERN_INFO "IXJ DAA Caller_ID Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
- }
- }
- if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) {
- daaint.bitreg.Cadence = 1;
- if(ixjdebug & 0x0008) {
- printk(KERN_INFO "IXJ DAA Cadence Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
- }
- }
- if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK != XR0.bitreg.VDD_OK) {
- daaint.bitreg.VDD_OK = 1;
- daaint.bitreg.SI_0 = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK;
- }
- }
- daa_CR_read(j, 1);
- if(j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR != XR0.bitreg.RMR && time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) {
- daaint.bitreg.RMR = 1;
- daaint.bitreg.SI_1 = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR;
- if(ixjdebug & 0x0008) {
- printk(KERN_INFO "IXJ DAA RMR /dev/phone%d was %s for %ld\n", j->board, XR0.bitreg.RMR?"on":"off", jiffies - j->pstn_last_rmr);
- }
- j->pstn_prev_rmr = j->pstn_last_rmr;
- j->pstn_last_rmr = jiffies;
- }
- switch(j->daa_mode) {
- case SOP_PU_SLEEP:
- if (daaint.bitreg.RING) {
- if (!j->flags.pstn_ringing) {
- if (j->daa_mode != SOP_PU_RINGING) {
- j->pstn_ring_int = jiffies;
- daa_set_mode(j, SOP_PU_RINGING);
- }
- }
- }
- break;
- case SOP_PU_RINGING:
- if (daaint.bitreg.RMR) {
- if (ixjdebug & 0x0008) {
- printk(KERN_INFO "IXJ Ring Cadence a state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies);
- }
- if (daaint.bitreg.SI_1) { /* Rising edge of RMR */
- j->flags.pstn_rmr = 1;
- j->pstn_ring_start = jiffies;
- j->pstn_ring_stop = 0;
- j->ex.bits.pstn_ring = 0;
- if (j->cadence_f[4].state == 0) {
- j->cadence_f[4].state = 1;
- j->cadence_f[4].on1min = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 - var)) / 10000);
- j->cadence_f[4].on1dot = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100)) / 10000);
- j->cadence_f[4].on1max = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 + var)) / 10000);
- } else if (j->cadence_f[4].state == 2) {
- if((time_after(jiffies, j->cadence_f[4].off1min) &&
- time_before(jiffies, j->cadence_f[4].off1max))) {
- if (j->cadence_f[4].on2) {
- j->cadence_f[4].state = 3;
- j->cadence_f[4].on2min = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 - var)) / 10000));
- j->cadence_f[4].on2dot = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100)) / 10000));
- j->cadence_f[4].on2max = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 + var)) / 10000));
- } else {
- j->cadence_f[4].state = 7;
- }
- } else {
- if (ixjdebug & 0x0008) {
- printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
- j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
- j->cadence_f[4].off1);
- }
- j->cadence_f[4].state = 0;
- }
- } else if (j->cadence_f[4].state == 4) {
- if((time_after(jiffies, j->cadence_f[4].off2min) &&
- time_before(jiffies, j->cadence_f[4].off2max))) {
- if (j->cadence_f[4].on3) {
- j->cadence_f[4].state = 5;
- j->cadence_f[4].on3min = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 - var)) / 10000));
- j->cadence_f[4].on3dot = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100)) / 10000));
- j->cadence_f[4].on3max = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 + var)) / 10000));
- } else {
- j->cadence_f[4].state = 7;
- }
- } else {
- if (ixjdebug & 0x0008) {
- printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
- j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
- j->cadence_f[4].off2);
- }
- j->cadence_f[4].state = 0;
- }
- } else if (j->cadence_f[4].state == 6) {
- if((time_after(jiffies, j->cadence_f[4].off3min) &&
- time_before(jiffies, j->cadence_f[4].off3max))) {
- j->cadence_f[4].state = 7;
- } else {
- if (ixjdebug & 0x0008) {
- printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
- j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
- j->cadence_f[4].off3);
- }
- j->cadence_f[4].state = 0;
- }
- } else {
- j->cadence_f[4].state = 0;
- }
- } else { /* Falling edge of RMR */
- j->pstn_ring_start = 0;
- j->pstn_ring_stop = jiffies;
- if (j->cadence_f[4].state == 1) {
- if(!j->cadence_f[4].on1) {
- j->cadence_f[4].state = 7;
- } else if((time_after(jiffies, j->cadence_f[4].on1min) &&
- time_before(jiffies, j->cadence_f[4].on1max))) {
- if (j->cadence_f[4].off1) {
- j->cadence_f[4].state = 2;
- j->cadence_f[4].off1min = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 - var)) / 10000));
- j->cadence_f[4].off1dot = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100)) / 10000));
- j->cadence_f[4].off1max = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 + var)) / 10000));
- } else {
- j->cadence_f[4].state = 7;
- }
- } else {
- if (ixjdebug & 0x0008) {
- printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
- j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
- j->cadence_f[4].on1);
- }
- j->cadence_f[4].state = 0;
- }
- } else if (j->cadence_f[4].state == 3) {
- if((time_after(jiffies, j->cadence_f[4].on2min) &&
- time_before(jiffies, j->cadence_f[4].on2max))) {
- if (j->cadence_f[4].off2) {
- j->cadence_f[4].state = 4;
- j->cadence_f[4].off2min = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 - var)) / 10000));
- j->cadence_f[4].off2dot = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100)) / 10000));
- j->cadence_f[4].off2max = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 + var)) / 10000));
- } else {
- j->cadence_f[4].state = 7;
- }
- } else {
- if (ixjdebug & 0x0008) {
- printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
- j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
- j->cadence_f[4].on2);
- }
- j->cadence_f[4].state = 0;
- }
- } else if (j->cadence_f[4].state == 5) {
- if((time_after(jiffies, j->cadence_f[4].on3min) &&
- time_before(jiffies, j->cadence_f[4].on3max))) {
- if (j->cadence_f[4].off3) {
- j->cadence_f[4].state = 6;
- j->cadence_f[4].off3min = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 - var)) / 10000));
- j->cadence_f[4].off3dot = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100)) / 10000));
- j->cadence_f[4].off3max = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 + var)) / 10000));
- } else {
- j->cadence_f[4].state = 7;
- }
- } else {
- j->cadence_f[4].state = 0;
- }
- } else {
- if (ixjdebug & 0x0008) {
- printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
- j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
- j->cadence_f[4].on3);
- }
- j->cadence_f[4].state = 0;
- }
- }
- if (ixjdebug & 0x0010) {
- printk(KERN_INFO "IXJ Ring Cadence b state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies);
- }
- if (ixjdebug & 0x0010) {
- switch(j->cadence_f[4].state) {
- case 1:
- printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
- j->cadence_f[4].on1, j->cadence_f[4].on1min, j->cadence_f[4].on1dot, j->cadence_f[4].on1max);
- break;
- case 2:
- printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
- j->cadence_f[4].off1, j->cadence_f[4].off1min, j->cadence_f[4].off1dot, j->cadence_f[4].off1max);
- break;
- case 3:
- printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
- j->cadence_f[4].on2, j->cadence_f[4].on2min, j->cadence_f[4].on2dot, j->cadence_f[4].on2max);
- break;
- case 4:
- printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
- j->cadence_f[4].off2, j->cadence_f[4].off2min, j->cadence_f[4].off2dot, j->cadence_f[4].off2max);
- break;
- case 5:
- printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
- j->cadence_f[4].on3, j->cadence_f[4].on3min, j->cadence_f[4].on3dot, j->cadence_f[4].on3max);
- break;
- case 6:
- printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
- j->cadence_f[4].off3, j->cadence_f[4].off3min, j->cadence_f[4].off3dot, j->cadence_f[4].off3max);
- break;
- }
- }
- }
- if (j->cadence_f[4].state == 7) {
- j->cadence_f[4].state = 0;
- j->pstn_ring_stop = jiffies;
- j->ex.bits.pstn_ring = 1;
- ixj_kill_fasync(j, SIG_PSTN_RING, POLL_IN);
- if(ixjdebug & 0x0008) {
- printk(KERN_INFO "IXJ Ring int set /dev/phone%d at %ld\n", j->board, jiffies);
- }
- }
- if((j->pstn_ring_int != 0 && time_after(jiffies, j->pstn_ring_int + (hertz * 5)) && !j->flags.pstn_rmr) ||
- (j->pstn_ring_stop != 0 && time_after(jiffies, j->pstn_ring_stop + (hertz * 5)))) {
- if(ixjdebug & 0x0008) {
- printk("IXJ DAA no ring in 5 seconds /dev/phone%d at %ld\n", j->board, jiffies);
- printk("IXJ DAA pstn ring int /dev/phone%d at %ld\n", j->board, j->pstn_ring_int);
- printk("IXJ DAA pstn ring stop /dev/phone%d at %ld\n", j->board, j->pstn_ring_stop);
- }
- j->pstn_ring_stop = j->pstn_ring_int = 0;
- daa_set_mode(j, SOP_PU_SLEEP);
- }
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- if (j->pstn_cid_intr && time_after(jiffies, j->pstn_cid_received + hertz)) {
- ixj_daa_cid_read(j);
- j->ex.bits.caller_id = 1;
- ixj_kill_fasync(j, SIG_CALLER_ID, POLL_IN);
- j->pstn_cid_intr = 0;
- }
- if (daaint.bitreg.Cadence) {
- if(ixjdebug & 0x0008) {
- printk("IXJ DAA Cadence interrupt going to sleep /dev/phone%d\n", j->board);
- }
- daa_set_mode(j, SOP_PU_SLEEP);
- j->ex.bits.pstn_ring = 0;
- }
- break;
- case SOP_PU_CONVERSATION:
- if (daaint.bitreg.VDD_OK) {
- if(!daaint.bitreg.SI_0) {
- if (!j->pstn_winkstart) {
- if(ixjdebug & 0x0008) {
- printk("IXJ DAA possible wink /dev/phone%d %ld\n", j->board, jiffies);
- }
- j->pstn_winkstart = jiffies;
- }
- } else {
- if (j->pstn_winkstart) {
- if(ixjdebug & 0x0008) {
- printk("IXJ DAA possible wink end /dev/phone%d %ld\n", j->board, jiffies);
- }
- j->pstn_winkstart = 0;
- }
- }
- }
- if (j->pstn_winkstart && time_after(jiffies, j->pstn_winkstart + ((hertz * j->winktime) / 1000))) {
- if(ixjdebug & 0x0008) {
- printk("IXJ DAA wink detected going to sleep /dev/phone%d %ld\n", j->board, jiffies);
- }
- daa_set_mode(j, SOP_PU_SLEEP);
- j->pstn_winkstart = 0;
- j->ex.bits.pstn_wink = 1;
- ixj_kill_fasync(j, SIG_PSTN_WINK, POLL_IN);
- }
- break;
- }
-}
-
-static void ixj_timeout(unsigned long ptr)
-{
- int board;
- unsigned long jifon;
- IXJ *j = (IXJ *)ptr;
- board = j->board;
-
- if (j->DSPbase && atomic_read(&j->DSPWrite) == 0 && test_and_set_bit(board, (void *)&j->busyflags) == 0) {
- ixj_perfmon(j->timerchecks);
- j->hookstate = ixj_hookstate(j);
- if (j->tone_state) {
- if (!(j->hookstate)) {
- ixj_cpt_stop(j);
- if (j->m_hook) {
- j->m_hook = 0;
- j->ex.bits.hookstate = 1;
- ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
- }
- clear_bit(board, &j->busyflags);
- ixj_add_timer(j);
- return;
- }
- if (j->tone_state == 1)
- jifon = ((hertz * j->tone_on_time) * 25 / 100000);
- else
- jifon = ((hertz * j->tone_on_time) * 25 / 100000) + ((hertz * j->tone_off_time) * 25 / 100000);
- if (time_before(jiffies, j->tone_start_jif + jifon)) {
- if (j->tone_state == 1) {
- ixj_play_tone(j, j->tone_index);
- if (j->dsp.low == 0x20) {
- clear_bit(board, &j->busyflags);
- ixj_add_timer(j);
- return;
- }
- } else {
- ixj_play_tone(j, 0);
- if (j->dsp.low == 0x20) {
- clear_bit(board, &j->busyflags);
- ixj_add_timer(j);
- return;
- }
- }
- } else {
- ixj_tone_timeout(j);
- if (j->flags.dialtone) {
- ixj_dialtone(j);
- }
- if (j->flags.busytone) {
- ixj_busytone(j);
- if (j->dsp.low == 0x20) {
- clear_bit(board, &j->busyflags);
- ixj_add_timer(j);
- return;
- }
- }
- if (j->flags.ringback) {
- ixj_ringback(j);
- if (j->dsp.low == 0x20) {
- clear_bit(board, &j->busyflags);
- ixj_add_timer(j);
- return;
- }
- }
- if (!j->tone_state) {
- ixj_cpt_stop(j);
- }
- }
- }
- if (!(j->tone_state && j->dsp.low == 0x20)) {
- if (IsRxReady(j)) {
- ixj_read_frame(j);
- }
- if (IsTxReady(j)) {
- ixj_write_frame(j);
- }
- }
- if (j->flags.cringing) {
- if (j->hookstate & 1) {
- j->flags.cringing = 0;
- ixj_ring_off(j);
- } else if(j->cadence_f[5].enable && ((!j->cadence_f[5].en_filter) || (j->cadence_f[5].en_filter && j->flags.firstring))) {
- switch(j->cadence_f[5].state) {
- case 0:
- j->cadence_f[5].on1dot = jiffies + (long)((j->cadence_f[5].on1 * (hertz * 100) / 10000));
- if (time_before(jiffies, j->cadence_f[5].on1dot)) {
- if(ixjdebug & 0x0004) {
- printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
- }
- ixj_ring_on(j);
- }
- j->cadence_f[5].state = 1;
- break;
- case 1:
- if (time_after(jiffies, j->cadence_f[5].on1dot)) {
- j->cadence_f[5].off1dot = jiffies + (long)((j->cadence_f[5].off1 * (hertz * 100) / 10000));
- if(ixjdebug & 0x0004) {
- printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
- }
- ixj_ring_off(j);
- j->cadence_f[5].state = 2;
- }
- break;
- case 2:
- if (time_after(jiffies, j->cadence_f[5].off1dot)) {
- if(ixjdebug & 0x0004) {
- printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
- }
- ixj_ring_on(j);
- if (j->cadence_f[5].on2) {
- j->cadence_f[5].on2dot = jiffies + (long)((j->cadence_f[5].on2 * (hertz * 100) / 10000));
- j->cadence_f[5].state = 3;
- } else {
- j->cadence_f[5].state = 7;
- }
- }
- break;
- case 3:
- if (time_after(jiffies, j->cadence_f[5].on2dot)) {
- if(ixjdebug & 0x0004) {
- printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
- }
- ixj_ring_off(j);
- if (j->cadence_f[5].off2) {
- j->cadence_f[5].off2dot = jiffies + (long)((j->cadence_f[5].off2 * (hertz * 100) / 10000));
- j->cadence_f[5].state = 4;
- } else {
- j->cadence_f[5].state = 7;
- }
- }
- break;
- case 4:
- if (time_after(jiffies, j->cadence_f[5].off2dot)) {
- if(ixjdebug & 0x0004) {
- printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
- }
- ixj_ring_on(j);
- if (j->cadence_f[5].on3) {
- j->cadence_f[5].on3dot = jiffies + (long)((j->cadence_f[5].on3 * (hertz * 100) / 10000));
- j->cadence_f[5].state = 5;
- } else {
- j->cadence_f[5].state = 7;
- }
- }
- break;
- case 5:
- if (time_after(jiffies, j->cadence_f[5].on3dot)) {
- if(ixjdebug & 0x0004) {
- printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
- }
- ixj_ring_off(j);
- if (j->cadence_f[5].off3) {
- j->cadence_f[5].off3dot = jiffies + (long)((j->cadence_f[5].off3 * (hertz * 100) / 10000));
- j->cadence_f[5].state = 6;
- } else {
- j->cadence_f[5].state = 7;
- }
- }
- break;
- case 6:
- if (time_after(jiffies, j->cadence_f[5].off3dot)) {
- if(ixjdebug & 0x0004) {
- printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
- }
- j->cadence_f[5].state = 7;
- }
- break;
- case 7:
- if(ixjdebug & 0x0004) {
- printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
- }
- j->flags.cidring = 1;
- j->cadence_f[5].state = 0;
- break;
- }
- if (j->flags.cidring && !j->flags.cidsent) {
- j->flags.cidsent = 1;
- if(j->fskdcnt) {
- SLIC_SetState(PLD_SLIC_STATE_OHT, j);
- ixj_pre_cid(j);
- }
- j->flags.cidring = 0;
- }
- clear_bit(board, &j->busyflags);
- ixj_add_timer(j);
- return;
- } else {
- if (time_after(jiffies, j->ring_cadence_jif + (hertz / 2))) {
- if (j->flags.cidring && !j->flags.cidsent) {
- j->flags.cidsent = 1;
- if(j->fskdcnt) {
- SLIC_SetState(PLD_SLIC_STATE_OHT, j);
- ixj_pre_cid(j);
- }
- j->flags.cidring = 0;
- }
- j->ring_cadence_t--;
- if (j->ring_cadence_t == -1)
- j->ring_cadence_t = 15;
- j->ring_cadence_jif = jiffies;
-
- if (j->ring_cadence & 1 << j->ring_cadence_t) {
- if(j->flags.cidsent && j->cadence_f[5].en_filter)
- j->flags.firstring = 1;
- else
- ixj_ring_on(j);
- } else {
- ixj_ring_off(j);
- if(!j->flags.cidsent)
- j->flags.cidring = 1;
- }
- }
- clear_bit(board, &j->busyflags);
- ixj_add_timer(j);
- return;
- }
- }
- if (!j->flags.ringing) {
- if (j->hookstate) { /* & 1) { */
- if (j->dsp.low != 0x20 &&
- SLIC_GetState(j) != PLD_SLIC_STATE_ACTIVE) {
- SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j);
- }
- LineMonitor(j);
- read_filters(j);
- ixj_WriteDSPCommand(0x511B, j);
- j->proc_load = j->ssr.high << 8 | j->ssr.low;
- if (!j->m_hook && (j->hookstate & 1)) {
- j->m_hook = j->ex.bits.hookstate = 1;
- ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
- }
- } else {
- if (j->ex.bits.dtmf_ready) {
- j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0;
- }
- if (j->m_hook) {
- j->m_hook = 0;
- j->ex.bits.hookstate = 1;
- ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
- }
- }
- }
- if (j->cardtype == QTI_LINEJACK && !j->flags.pstncheck && j->flags.pstn_present) {
- ixj_pstn_state(j);
- }
- if (j->ex.bytes) {
- wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */
- }
- clear_bit(board, &j->busyflags);
- }
- ixj_add_timer(j);
-}
-
-static int ixj_status_wait(IXJ *j)
-{
- unsigned long jif;
-
- jif = jiffies + ((60 * hertz) / 100);
- while (!IsStatusReady(j)) {
- ixj_perfmon(j->statuswait);
- if (time_after(jiffies, jif)) {
- ixj_perfmon(j->statuswaitfail);
- return -1;
- }
- }
- return 0;
-}
-
-static int ixj_PCcontrol_wait(IXJ *j)
-{
- unsigned long jif;
-
- jif = jiffies + ((60 * hertz) / 100);
- while (!IsPCControlReady(j)) {
- ixj_perfmon(j->pcontrolwait);
- if (time_after(jiffies, jif)) {
- ixj_perfmon(j->pcontrolwaitfail);
- return -1;
- }
- }
- return 0;
-}
-
-static int ixj_WriteDSPCommand(unsigned short cmd, IXJ *j)
-{
- BYTES bytes;
- unsigned long jif;
-
- atomic_inc(&j->DSPWrite);
- if(atomic_read(&j->DSPWrite) > 1) {
- printk("IXJ %d DSP write overlap attempting command 0x%4.4x\n", j->board, cmd);
- return -1;
- }
- bytes.high = (cmd & 0xFF00) >> 8;
- bytes.low = cmd & 0x00FF;
- jif = jiffies + ((60 * hertz) / 100);
- while (!IsControlReady(j)) {
- ixj_perfmon(j->iscontrolready);
- if (time_after(jiffies, jif)) {
- ixj_perfmon(j->iscontrolreadyfail);
- atomic_dec(&j->DSPWrite);
- if(atomic_read(&j->DSPWrite) > 0) {
- printk("IXJ %d DSP overlaped command 0x%4.4x during control ready failure.\n", j->board, cmd);
- while(atomic_read(&j->DSPWrite) > 0) {
- atomic_dec(&j->DSPWrite);
- }
- }
- return -1;
- }
- }
- outb(bytes.low, j->DSPbase + 6);
- outb(bytes.high, j->DSPbase + 7);
-
- if (ixj_status_wait(j)) {
- j->ssr.low = 0xFF;
- j->ssr.high = 0xFF;
- atomic_dec(&j->DSPWrite);
- if(atomic_read(&j->DSPWrite) > 0) {
- printk("IXJ %d DSP overlaped command 0x%4.4x during status wait failure.\n", j->board, cmd);
- while(atomic_read(&j->DSPWrite) > 0) {
- atomic_dec(&j->DSPWrite);
- }
- }
- return -1;
- }
-/* Read Software Status Register */
- j->ssr.low = inb_p(j->DSPbase + 2);
- j->ssr.high = inb_p(j->DSPbase + 3);
- atomic_dec(&j->DSPWrite);
- if(atomic_read(&j->DSPWrite) > 0) {
- printk("IXJ %d DSP overlaped command 0x%4.4x\n", j->board, cmd);
- while(atomic_read(&j->DSPWrite) > 0) {
- atomic_dec(&j->DSPWrite);
- }
- }
- return 0;
-}
-
-/***************************************************************************
-*
-* General Purpose IO Register read routine
-*
-***************************************************************************/
-static inline int ixj_gpio_read(IXJ *j)
-{
- if (ixj_WriteDSPCommand(0x5143, j))
- return -1;
-
- j->gpio.bytes.low = j->ssr.low;
- j->gpio.bytes.high = j->ssr.high;
-
- return 0;
-}
-
-static inline void LED_SetState(int state, IXJ *j)
-{
- if (j->cardtype == QTI_LINEJACK) {
- j->pld_scrw.bits.led1 = state & 0x1 ? 1 : 0;
- j->pld_scrw.bits.led2 = state & 0x2 ? 1 : 0;
- j->pld_scrw.bits.led3 = state & 0x4 ? 1 : 0;
- j->pld_scrw.bits.led4 = state & 0x8 ? 1 : 0;
-
- outb(j->pld_scrw.byte, j->XILINXbase);
- }
-}
-
-/*********************************************************************
-* GPIO Pins are configured as follows on the Quicknet Internet
-* PhoneJACK Telephony Cards
-*
-* POTS Select GPIO_6=0 GPIO_7=0
-* Mic/Speaker Select GPIO_6=0 GPIO_7=1
-* Handset Select GPIO_6=1 GPIO_7=0
-*
-* SLIC Active GPIO_1=0 GPIO_2=1 GPIO_5=0
-* SLIC Ringing GPIO_1=1 GPIO_2=1 GPIO_5=0
-* SLIC Open Circuit GPIO_1=0 GPIO_2=0 GPIO_5=0
-*
-* Hook Switch changes reported on GPIO_3
-*********************************************************************/
-static int ixj_set_port(IXJ *j, int arg)
-{
- if (j->cardtype == QTI_PHONEJACK_LITE) {
- if (arg != PORT_POTS)
- return 10;
- else
- return 0;
- }
- switch (arg) {
- case PORT_POTS:
- j->port = PORT_POTS;
- switch (j->cardtype) {
- case QTI_PHONECARD:
- if (j->flags.pcmciasct == 1)
- SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j);
- else
- return 11;
- break;
- case QTI_PHONEJACK_PCI:
- j->pld_slicw.pcib.mic = 0;
- j->pld_slicw.pcib.spk = 0;
- outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
- break;
- case QTI_LINEJACK:
- ixj_set_pots(j, 0); /* Disconnect POTS/PSTN relay */
- if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to
- Software Control Register */
- return 2;
- j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
-
- outb(j->pld_scrw.byte, j->XILINXbase);
- j->pld_clock.byte = 0;
- outb(j->pld_clock.byte, j->XILINXbase + 0x04);
- j->pld_slicw.bits.rly1 = 1;
- j->pld_slicw.bits.spken = 0;
- outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
- ixj_mixer(0x1200, j); /* Turn Off MIC switch on mixer left */
- ixj_mixer(0x1401, j); /* Turn On Mono1 switch on mixer left */
- ixj_mixer(0x1300, j); /* Turn Off MIC switch on mixer right */
- ixj_mixer(0x1501, j); /* Turn On Mono1 switch on mixer right */
- ixj_mixer(0x0E80, j); /*Mic mute */
- ixj_mixer(0x0F00, j); /* Set mono out (SLIC) to 0dB */
- ixj_mixer(0x0080, j); /* Mute Master Left volume */
- ixj_mixer(0x0180, j); /* Mute Master Right volume */
- SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
-/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
- break;
- case QTI_PHONEJACK:
- j->gpio.bytes.high = 0x0B;
- j->gpio.bits.gpio6 = 0;
- j->gpio.bits.gpio7 = 0;
- ixj_WriteDSPCommand(j->gpio.word, j);
- break;
- }
- break;
- case PORT_PSTN:
- if (j->cardtype == QTI_LINEJACK) {
- ixj_WriteDSPCommand(0xC534, j); /* Write CODEC config to Software Control Register */
-
- j->pld_slicw.bits.rly3 = 0;
- j->pld_slicw.bits.rly1 = 1;
- j->pld_slicw.bits.spken = 0;
- outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
- j->port = PORT_PSTN;
- } else {
- return 4;
- }
- break;
- case PORT_SPEAKER:
- j->port = PORT_SPEAKER;
- switch (j->cardtype) {
- case QTI_PHONECARD:
- if (j->flags.pcmciasct) {
- SLIC_SetState(PLD_SLIC_STATE_OC, j);
- }
- break;
- case QTI_PHONEJACK_PCI:
- j->pld_slicw.pcib.mic = 1;
- j->pld_slicw.pcib.spk = 1;
- outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
- break;
- case QTI_LINEJACK:
- ixj_set_pots(j, 0); /* Disconnect POTS/PSTN relay */
- if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to
- Software Control Register */
- return 2;
- j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
-
- outb(j->pld_scrw.byte, j->XILINXbase);
- j->pld_clock.byte = 0;
- outb(j->pld_clock.byte, j->XILINXbase + 0x04);
- j->pld_slicw.bits.rly1 = 1;
- j->pld_slicw.bits.spken = 1;
- outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
- ixj_mixer(0x1201, j); /* Turn On MIC switch on mixer left */
- ixj_mixer(0x1400, j); /* Turn Off Mono1 switch on mixer left */
- ixj_mixer(0x1301, j); /* Turn On MIC switch on mixer right */
- ixj_mixer(0x1500, j); /* Turn Off Mono1 switch on mixer right */
- ixj_mixer(0x0E06, j); /*Mic un-mute 0dB */
- ixj_mixer(0x0F80, j); /* Mute mono out (SLIC) */
- ixj_mixer(0x0000, j); /* Set Master Left volume to 0dB */
- ixj_mixer(0x0100, j); /* Set Master Right volume to 0dB */
- break;
- case QTI_PHONEJACK:
- j->gpio.bytes.high = 0x0B;
- j->gpio.bits.gpio6 = 0;
- j->gpio.bits.gpio7 = 1;
- ixj_WriteDSPCommand(j->gpio.word, j);
- break;
- }
- break;
- case PORT_HANDSET:
- if (j->cardtype != QTI_PHONEJACK) {
- return 5;
- } else {
- j->gpio.bytes.high = 0x0B;
- j->gpio.bits.gpio6 = 1;
- j->gpio.bits.gpio7 = 0;
- ixj_WriteDSPCommand(j->gpio.word, j);
- j->port = PORT_HANDSET;
- }
- break;
- default:
- return 6;
- break;
- }
- return 0;
-}
-
-static int ixj_set_pots(IXJ *j, int arg)
-{
- if (j->cardtype == QTI_LINEJACK) {
- if (arg) {
- if (j->port == PORT_PSTN) {
- j->pld_slicw.bits.rly1 = 0;
- outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
- j->flags.pots_pstn = 1;
- return 1;
- } else {
- j->flags.pots_pstn = 0;
- return 0;
- }
- } else {
- j->pld_slicw.bits.rly1 = 1;
- outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
- j->flags.pots_pstn = 0;
- return 1;
- }
- } else {
- return 0;
- }
-}
-
-static void ixj_ring_on(IXJ *j)
-{
- if (j->dsp.low == 0x20) /* Internet PhoneJACK */
- {
- if (ixjdebug & 0x0004)
- printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", j->board);
-
- j->gpio.bytes.high = 0x0B;
- j->gpio.bytes.low = 0x00;
- j->gpio.bits.gpio1 = 1;
- j->gpio.bits.gpio2 = 1;
- j->gpio.bits.gpio5 = 0;
- ixj_WriteDSPCommand(j->gpio.word, j); /* send the ring signal */
- } else /* Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI */
- {
- if (ixjdebug & 0x0004)
- printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", j->board);
-
- SLIC_SetState(PLD_SLIC_STATE_RINGING, j);
- }
-}
-
-static int ixj_siadc(IXJ *j, int val)
-{
- if(j->cardtype == QTI_PHONECARD){
- if(j->flags.pcmciascp){
- if(val == -1)
- return j->siadc.bits.rxg;
-
- if(val < 0 || val > 0x1F)
- return -1;
-
- j->siadc.bits.hom = 0; /* Handset Out Mute */
- j->siadc.bits.lom = 0; /* Line Out Mute */
- j->siadc.bits.rxg = val; /*(0xC000 - 0x41C8) / 0x4EF; RX PGA Gain */
- j->psccr.bits.addr = 6; /* R/W Smart Cable Register Address */
- j->psccr.bits.rw = 0; /* Read / Write flag */
- j->psccr.bits.dev = 0;
- outb(j->siadc.byte, j->XILINXbase + 0x00);
- outb(j->psccr.byte, j->XILINXbase + 0x01);
- ixj_PCcontrol_wait(j);
- return j->siadc.bits.rxg;
- }
- }
- return -1;
-}
-
-static int ixj_sidac(IXJ *j, int val)
-{
- if(j->cardtype == QTI_PHONECARD){
- if(j->flags.pcmciascp){
- if(val == -1)
- return j->sidac.bits.txg;
-
- if(val < 0 || val > 0x1F)
- return -1;
-
- j->sidac.bits.srm = 1; /* Speaker Right Mute */
- j->sidac.bits.slm = 1; /* Speaker Left Mute */
- j->sidac.bits.txg = val; /* (0xC000 - 0x45E4) / 0x5D3; TX PGA Gain */
- j->psccr.bits.addr = 7; /* R/W Smart Cable Register Address */
- j->psccr.bits.rw = 0; /* Read / Write flag */
- j->psccr.bits.dev = 0;
- outb(j->sidac.byte, j->XILINXbase + 0x00);
- outb(j->psccr.byte, j->XILINXbase + 0x01);
- ixj_PCcontrol_wait(j);
- return j->sidac.bits.txg;
- }
- }
- return -1;
-}
-
-static int ixj_pcmcia_cable_check(IXJ *j)
-{
- j->pccr1.byte = inb_p(j->XILINXbase + 0x03);
- if (!j->flags.pcmciastate) {
- j->pccr2.byte = inb_p(j->XILINXbase + 0x02);
- if (j->pccr1.bits.drf || j->pccr2.bits.rstc) {
- j->flags.pcmciastate = 4;
- return 0;
- }
- if (j->pccr1.bits.ed) {
- j->pccr1.bits.ed = 0;
- j->psccr.bits.dev = 3;
- j->psccr.bits.rw = 1;
- outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00);
- ixj_PCcontrol_wait(j);
- j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF;
- j->pslic.bits.led2 = j->pslic.bits.det ? 1 : 0;
- j->psccr.bits.dev = 3;
- j->psccr.bits.rw = 0;
- outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
- ixj_PCcontrol_wait(j);
- return j->pslic.bits.led2 ? 1 : 0;
- } else if (j->flags.pcmciasct) {
- return j->r_hook;
- } else {
- return 1;
- }
- } else if (j->flags.pcmciastate == 4) {
- if (!j->pccr1.bits.drf) {
- j->flags.pcmciastate = 3;
- }
- return 0;
- } else if (j->flags.pcmciastate == 3) {
- j->pccr2.bits.pwr = 0;
- j->pccr2.bits.rstc = 1;
- outb(j->pccr2.byte, j->XILINXbase + 0x02);
- j->checkwait = jiffies + (hertz * 2);
- j->flags.incheck = 1;
- j->flags.pcmciastate = 2;
- return 0;
- } else if (j->flags.pcmciastate == 2) {
- if (j->flags.incheck) {
- if (time_before(jiffies, j->checkwait)) {
- return 0;
- } else {
- j->flags.incheck = 0;
- }
- }
- j->pccr2.bits.pwr = 0;
- j->pccr2.bits.rstc = 0;
- outb_p(j->pccr2.byte, j->XILINXbase + 0x02);
- j->flags.pcmciastate = 1;
- return 0;
- } else if (j->flags.pcmciastate == 1) {
- j->flags.pcmciastate = 0;
- if (!j->pccr1.bits.drf) {
- j->psccr.bits.dev = 3;
- j->psccr.bits.rw = 1;
- outb_p(j->psccr.byte, j->XILINXbase + 0x01);
- ixj_PCcontrol_wait(j);
- j->flags.pcmciascp = 1; /* Set Cable Present Flag */
-
- j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03; /* Get Cable Type */
-
- if (j->flags.pcmciasct == 3) {
- j->flags.pcmciastate = 4;
- return 0;
- } else if (j->flags.pcmciasct == 0) {
- j->pccr2.bits.pwr = 1;
- j->pccr2.bits.rstc = 0;
- outb_p(j->pccr2.byte, j->XILINXbase + 0x02);
- j->port = PORT_SPEAKER;
- } else {
- j->port = PORT_POTS;
- }
- j->sic1.bits.cpd = 0; /* Chip Power Down */
- j->sic1.bits.mpd = 0; /* MIC Bias Power Down */
- j->sic1.bits.hpd = 0; /* Handset Bias Power Down */
- j->sic1.bits.lpd = 0; /* Line Bias Power Down */
- j->sic1.bits.spd = 1; /* Speaker Drive Power Down */
- j->psccr.bits.addr = 1; /* R/W Smart Cable Register Address */
- j->psccr.bits.rw = 0; /* Read / Write flag */
- j->psccr.bits.dev = 0;
- outb(j->sic1.byte, j->XILINXbase + 0x00);
- outb(j->psccr.byte, j->XILINXbase + 0x01);
- ixj_PCcontrol_wait(j);
-
- j->sic2.bits.al = 0; /* Analog Loopback DAC analog -> ADC analog */
- j->sic2.bits.dl2 = 0; /* Digital Loopback DAC -> ADC one bit */
- j->sic2.bits.dl1 = 0; /* Digital Loopback ADC -> DAC one bit */
- j->sic2.bits.pll = 0; /* 1 = div 10, 0 = div 5 */
- j->sic2.bits.hpd = 0; /* HPF disable */
- j->psccr.bits.addr = 2; /* R/W Smart Cable Register Address */
- j->psccr.bits.rw = 0; /* Read / Write flag */
- j->psccr.bits.dev = 0;
- outb(j->sic2.byte, j->XILINXbase + 0x00);
- outb(j->psccr.byte, j->XILINXbase + 0x01);
- ixj_PCcontrol_wait(j);
-
- j->psccr.bits.addr = 3; /* R/W Smart Cable Register Address */
- j->psccr.bits.rw = 0; /* Read / Write flag */
- j->psccr.bits.dev = 0;
- outb(0x00, j->XILINXbase + 0x00); /* PLL Divide N1 */
- outb(j->psccr.byte, j->XILINXbase + 0x01);
- ixj_PCcontrol_wait(j);
-
- j->psccr.bits.addr = 4; /* R/W Smart Cable Register Address */
- j->psccr.bits.rw = 0; /* Read / Write flag */
- j->psccr.bits.dev = 0;
- outb(0x09, j->XILINXbase + 0x00); /* PLL Multiply M1 */
- outb(j->psccr.byte, j->XILINXbase + 0x01);
- ixj_PCcontrol_wait(j);
-
- j->sirxg.bits.lig = 1; /* Line In Gain */
- j->sirxg.bits.lim = 1; /* Line In Mute */
- j->sirxg.bits.mcg = 0; /* MIC In Gain was 3 */
- j->sirxg.bits.mcm = 0; /* MIC In Mute */
- j->sirxg.bits.him = 0; /* Handset In Mute */
- j->sirxg.bits.iir = 1; /* IIR */
- j->psccr.bits.addr = 5; /* R/W Smart Cable Register Address */
- j->psccr.bits.rw = 0; /* Read / Write flag */
- j->psccr.bits.dev = 0;
- outb(j->sirxg.byte, j->XILINXbase + 0x00);
- outb(j->psccr.byte, j->XILINXbase + 0x01);
- ixj_PCcontrol_wait(j);
-
- ixj_siadc(j, 0x17);
- ixj_sidac(j, 0x1D);
-
- j->siaatt.bits.sot = 0;
- j->psccr.bits.addr = 9; /* R/W Smart Cable Register Address */
- j->psccr.bits.rw = 0; /* Read / Write flag */
- j->psccr.bits.dev = 0;
- outb(j->siaatt.byte, j->XILINXbase + 0x00);
- outb(j->psccr.byte, j->XILINXbase + 0x01);
- ixj_PCcontrol_wait(j);
-
- if (j->flags.pcmciasct == 1 && !j->readers && !j->writers) {
- j->psccr.byte = j->pslic.byte = 0;
- j->pslic.bits.powerdown = 1;
- j->psccr.bits.dev = 3;
- j->psccr.bits.rw = 0;
- outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
- ixj_PCcontrol_wait(j);
- }
- }
- return 0;
- } else {
- j->flags.pcmciascp = 0;
- return 0;
- }
- return 0;
-}
-
-static int ixj_hookstate(IXJ *j)
-{
- int fOffHook = 0;
-
- switch (j->cardtype) {
- case QTI_PHONEJACK:
- ixj_gpio_read(j);
- fOffHook = j->gpio.bits.gpio3read ? 1 : 0;
- break;
- case QTI_LINEJACK:
- case QTI_PHONEJACK_LITE:
- case QTI_PHONEJACK_PCI:
- SLIC_GetState(j);
- if(j->cardtype == QTI_LINEJACK && j->flags.pots_pstn == 1 && (j->readers || j->writers)) {
- fOffHook = j->pld_slicr.bits.potspstn ? 1 : 0;
- if(fOffHook != j->p_hook) {
- if(!j->checkwait) {
- j->checkwait = jiffies;
- }
- if(time_before(jiffies, j->checkwait + 2)) {
- fOffHook ^= 1;
- } else {
- j->checkwait = 0;
- }
- j->p_hook = fOffHook;
- printk("IXJ : /dev/phone%d pots-pstn hookstate check %d at %ld\n", j->board, fOffHook, jiffies);
- }
- } else {
- if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE ||
- j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) {
- if (j->flags.ringing || j->flags.cringing) {
- if (!in_interrupt()) {
- msleep(20);
- }
- SLIC_GetState(j);
- if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) {
- ixj_ring_on(j);
- }
- }
- if (j->cardtype == QTI_PHONEJACK_PCI) {
- j->pld_scrr.byte = inb_p(j->XILINXbase);
- fOffHook = j->pld_scrr.pcib.det ? 1 : 0;
- } else
- fOffHook = j->pld_slicr.bits.det ? 1 : 0;
- }
- }
- break;
- case QTI_PHONECARD:
- fOffHook = ixj_pcmcia_cable_check(j);
- break;
- }
- if (j->r_hook != fOffHook) {
- j->r_hook = fOffHook;
- if (j->port == PORT_SPEAKER || j->port == PORT_HANDSET) { // || (j->port == PORT_PSTN && j->flags.pots_pstn == 0)) {
- j->ex.bits.hookstate = 1;
- ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
- } else if (!fOffHook) {
- j->flash_end = jiffies + ((60 * hertz) / 100);
- }
- }
- if (fOffHook) {
- if(time_before(jiffies, j->flash_end)) {
- j->ex.bits.flash = 1;
- j->flash_end = 0;
- ixj_kill_fasync(j, SIG_FLASH, POLL_IN);
- }
- } else {
- if(time_before(jiffies, j->flash_end)) {
- fOffHook = 1;
- }
- }
-
- if (j->port == PORT_PSTN && j->daa_mode == SOP_PU_CONVERSATION)
- fOffHook |= 2;
-
- if (j->port == PORT_SPEAKER) {
- if(j->cardtype == QTI_PHONECARD) {
- if(j->flags.pcmciascp && j->flags.pcmciasct) {
- fOffHook |= 2;
- }
- } else {
- fOffHook |= 2;
- }
- }
-
- if (j->port == PORT_HANDSET)
- fOffHook |= 2;
-
- return fOffHook;
-}
-
-static void ixj_ring_off(IXJ *j)
-{
- if (j->dsp.low == 0x20) /* Internet PhoneJACK */
- {
- if (ixjdebug & 0x0004)
- printk(KERN_INFO "IXJ Ring Off\n");
- j->gpio.bytes.high = 0x0B;
- j->gpio.bytes.low = 0x00;
- j->gpio.bits.gpio1 = 0;
- j->gpio.bits.gpio2 = 1;
- j->gpio.bits.gpio5 = 0;
- ixj_WriteDSPCommand(j->gpio.word, j);
- } else /* Internet LineJACK */
- {
- if (ixjdebug & 0x0004)
- printk(KERN_INFO "IXJ Ring Off\n");
-
- if(!j->flags.cidplay)
- SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
-
- SLIC_GetState(j);
- }
-}
-
-static void ixj_ring_start(IXJ *j)
-{
- j->flags.cringing = 1;
- if (ixjdebug & 0x0004)
- printk(KERN_INFO "IXJ Cadence Ringing Start /dev/phone%d\n", j->board);
- if (ixj_hookstate(j) & 1) {
- if (j->port == PORT_POTS)
- ixj_ring_off(j);
- j->flags.cringing = 0;
- if (ixjdebug & 0x0004)
- printk(KERN_INFO "IXJ Cadence Ringing Stopped /dev/phone%d off hook\n", j->board);
- } else if(j->cadence_f[5].enable && (!j->cadence_f[5].en_filter)) {
- j->ring_cadence_jif = jiffies;
- j->flags.cidsent = j->flags.cidring = 0;
- j->cadence_f[5].state = 0;
- if(j->cadence_f[5].on1)
- ixj_ring_on(j);
- } else {
- j->ring_cadence_jif = jiffies;
- j->ring_cadence_t = 15;
- if (j->ring_cadence & 1 << j->ring_cadence_t) {
- ixj_ring_on(j);
- } else {
- ixj_ring_off(j);
- }
- j->flags.cidsent = j->flags.cidring = j->flags.firstring = 0;
- }
-}
-
-static int ixj_ring(IXJ *j)
-{
- char cntr;
- unsigned long jif;
-
- j->flags.ringing = 1;
- if (ixj_hookstate(j) & 1) {
- ixj_ring_off(j);
- j->flags.ringing = 0;
- return 1;
- }
- for (cntr = 0; cntr < j->maxrings; cntr++) {
- jif = jiffies + (1 * hertz);
- ixj_ring_on(j);
- while (time_before(jiffies, jif)) {
- if (ixj_hookstate(j) & 1) {
- ixj_ring_off(j);
- j->flags.ringing = 0;
- return 1;
- }
- schedule_timeout_interruptible(1);
- if (signal_pending(current))
- break;
- }
- jif = jiffies + (3 * hertz);
- ixj_ring_off(j);
- while (time_before(jiffies, jif)) {
- if (ixj_hookstate(j) & 1) {
- msleep(10);
- if (ixj_hookstate(j) & 1) {
- j->flags.ringing = 0;
- return 1;
- }
- }
- schedule_timeout_interruptible(1);
- if (signal_pending(current))
- break;
- }
- }
- ixj_ring_off(j);
- j->flags.ringing = 0;
- return 0;
-}
-
-static int ixj_open(struct phone_device *p, struct file *file_p)
-{
- IXJ *j = get_ixj(p->board);
- file_p->private_data = j;
-
- if (!j->DSPbase)
- return -ENODEV;
-
- if (file_p->f_mode & FMODE_READ) {
- if(!j->readers) {
- j->readers++;
- } else {
- return -EBUSY;
- }
- }
-
- if (file_p->f_mode & FMODE_WRITE) {
- if(!j->writers) {
- j->writers++;
- } else {
- if (file_p->f_mode & FMODE_READ){
- j->readers--;
- }
- return -EBUSY;
- }
- }
-
- if (j->cardtype == QTI_PHONECARD) {
- j->pslic.bits.powerdown = 0;
- j->psccr.bits.dev = 3;
- j->psccr.bits.rw = 0;
- outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
- ixj_PCcontrol_wait(j);
- }
-
- j->flags.cidplay = 0;
- j->flags.cidcw_ack = 0;
-
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Opening board %d\n", p->board);
-
- j->framesread = j->frameswritten = 0;
- return 0;
-}
-
-static int ixj_release(struct inode *inode, struct file *file_p)
-{
- IXJ_TONE ti;
- int cnt;
- IXJ *j = file_p->private_data;
- int board = j->p.board;
-
- /*
- * Set up locks to ensure that only one process is talking to the DSP at a time.
- * This is necessary to keep the DSP from locking up.
- */
- while(test_and_set_bit(board, (void *)&j->busyflags) != 0)
- schedule_timeout_interruptible(1);
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Closing board %d\n", NUM(inode));
-
- if (j->cardtype == QTI_PHONECARD)
- ixj_set_port(j, PORT_SPEAKER);
- else
- ixj_set_port(j, PORT_POTS);
-
- aec_stop(j);
- ixj_play_stop(j);
- ixj_record_stop(j);
- set_play_volume(j, 0x100);
- set_rec_volume(j, 0x100);
- ixj_ring_off(j);
-
- /* Restore the tone table to default settings. */
- ti.tone_index = 10;
- ti.gain0 = 1;
- ti.freq0 = hz941;
- ti.gain1 = 0;
- ti.freq1 = hz1209;
- ixj_init_tone(j, &ti);
- ti.tone_index = 11;
- ti.gain0 = 1;
- ti.freq0 = hz941;
- ti.gain1 = 0;
- ti.freq1 = hz1336;
- ixj_init_tone(j, &ti);
- ti.tone_index = 12;
- ti.gain0 = 1;
- ti.freq0 = hz941;
- ti.gain1 = 0;
- ti.freq1 = hz1477;
- ixj_init_tone(j, &ti);
- ti.tone_index = 13;
- ti.gain0 = 1;
- ti.freq0 = hz800;
- ti.gain1 = 0;
- ti.freq1 = 0;
- ixj_init_tone(j, &ti);
- ti.tone_index = 14;
- ti.gain0 = 1;
- ti.freq0 = hz1000;
- ti.gain1 = 0;
- ti.freq1 = 0;
- ixj_init_tone(j, &ti);
- ti.tone_index = 15;
- ti.gain0 = 1;
- ti.freq0 = hz1250;
- ti.gain1 = 0;
- ti.freq1 = 0;
- ixj_init_tone(j, &ti);
- ti.tone_index = 16;
- ti.gain0 = 1;
- ti.freq0 = hz950;
- ti.gain1 = 0;
- ti.freq1 = 0;
- ixj_init_tone(j, &ti);
- ti.tone_index = 17;
- ti.gain0 = 1;
- ti.freq0 = hz1100;
- ti.gain1 = 0;
- ti.freq1 = 0;
- ixj_init_tone(j, &ti);
- ti.tone_index = 18;
- ti.gain0 = 1;
- ti.freq0 = hz1400;
- ti.gain1 = 0;
- ti.freq1 = 0;
- ixj_init_tone(j, &ti);
- ti.tone_index = 19;
- ti.gain0 = 1;
- ti.freq0 = hz1500;
- ti.gain1 = 0;
- ti.freq1 = 0;
- ixj_init_tone(j, &ti);
- ti.tone_index = 20;
- ti.gain0 = 1;
- ti.freq0 = hz1600;
- ti.gain1 = 0;
- ti.freq1 = 0;
- ixj_init_tone(j, &ti);
- ti.tone_index = 21;
- ti.gain0 = 1;
- ti.freq0 = hz1800;
- ti.gain1 = 0;
- ti.freq1 = 0;
- ixj_init_tone(j, &ti);
- ti.tone_index = 22;
- ti.gain0 = 1;
- ti.freq0 = hz2100;
- ti.gain1 = 0;
- ti.freq1 = 0;
- ixj_init_tone(j, &ti);
- ti.tone_index = 23;
- ti.gain0 = 1;
- ti.freq0 = hz1300;
- ti.gain1 = 0;
- ti.freq1 = 0;
- ixj_init_tone(j, &ti);
- ti.tone_index = 24;
- ti.gain0 = 1;
- ti.freq0 = hz2450;
- ti.gain1 = 0;
- ti.freq1 = 0;
- ixj_init_tone(j, &ti);
- ti.tone_index = 25;
- ti.gain0 = 1;
- ti.freq0 = hz350;
- ti.gain1 = 0;
- ti.freq1 = hz440;
- ixj_init_tone(j, &ti);
- ti.tone_index = 26;
- ti.gain0 = 1;
- ti.freq0 = hz440;
- ti.gain1 = 0;
- ti.freq1 = hz480;
- ixj_init_tone(j, &ti);
- ti.tone_index = 27;
- ti.gain0 = 1;
- ti.freq0 = hz480;
- ti.gain1 = 0;
- ti.freq1 = hz620;
- ixj_init_tone(j, &ti);
-
- set_rec_depth(j, 2); /* Set Record Channel Limit to 2 frames */
-
- set_play_depth(j, 2); /* Set Playback Channel Limit to 2 frames */
-
- j->ex.bits.dtmf_ready = 0;
- j->dtmf_state = 0;
- j->dtmf_wp = j->dtmf_rp = 0;
- j->rec_mode = j->play_mode = -1;
- j->flags.ringing = 0;
- j->maxrings = MAXRINGS;
- j->ring_cadence = USA_RING_CADENCE;
- if(j->cadence_f[5].enable) {
- j->cadence_f[5].enable = j->cadence_f[5].en_filter = j->cadence_f[5].state = 0;
- }
- j->drybuffer = 0;
- j->winktime = 320;
- j->flags.dtmf_oob = 0;
- for (cnt = 0; cnt < 4; cnt++)
- j->cadence_f[cnt].enable = 0;
-
- idle(j);
-
- if(j->cardtype == QTI_PHONECARD) {
- SLIC_SetState(PLD_SLIC_STATE_OC, j);
- }
-
- if (file_p->f_mode & FMODE_READ)
- j->readers--;
- if (file_p->f_mode & FMODE_WRITE)
- j->writers--;
-
- if (j->read_buffer && !j->readers) {
- kfree(j->read_buffer);
- j->read_buffer = NULL;
- j->read_buffer_size = 0;
- }
- if (j->write_buffer && !j->writers) {
- kfree(j->write_buffer);
- j->write_buffer = NULL;
- j->write_buffer_size = 0;
- }
- j->rec_codec = j->play_codec = 0;
- j->rec_frame_size = j->play_frame_size = 0;
- j->flags.cidsent = j->flags.cidring = 0;
-
- if(j->cardtype == QTI_LINEJACK && !j->readers && !j->writers) {
- ixj_set_port(j, PORT_PSTN);
- daa_set_mode(j, SOP_PU_SLEEP);
- ixj_set_pots(j, 1);
- }
- ixj_WriteDSPCommand(0x0FE3, j); /* Put the DSP in 1/5 power mode. */
-
- /* Set up the default signals for events */
- for (cnt = 0; cnt < 35; cnt++)
- j->ixj_signals[cnt] = SIGIO;
-
- /* Set the excetion signal enable flags */
- j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring =
- j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 =
- j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1;
-
- file_p->private_data = NULL;
- clear_bit(board, &j->busyflags);
- return 0;
-}
-
-static int read_filters(IXJ *j)
-{
- unsigned short fc, cnt, trg;
- int var;
-
- trg = 0;
- if (ixj_WriteDSPCommand(0x5144, j)) {
- if(ixjdebug & 0x0001) {
- printk(KERN_INFO "Read Frame Counter failed!\n");
- }
- return -1;
- }
- fc = j->ssr.high << 8 | j->ssr.low;
- if (fc == j->frame_count)
- return 1;
-
- j->frame_count = fc;
-
- if (j->dtmf_proc)
- return 1;
-
- var = 10;
-
- for (cnt = 0; cnt < 4; cnt++) {
- if (ixj_WriteDSPCommand(0x5154 + cnt, j)) {
- if(ixjdebug & 0x0001) {
- printk(KERN_INFO "Select Filter %d failed!\n", cnt);
- }
- return -1;
- }
- if (ixj_WriteDSPCommand(0x515C, j)) {
- if(ixjdebug & 0x0001) {
- printk(KERN_INFO "Read Filter History %d failed!\n", cnt);
- }
- return -1;
- }
- j->filter_hist[cnt] = j->ssr.high << 8 | j->ssr.low;
-
- if (j->cadence_f[cnt].enable) {
- if (j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) {
- if (j->cadence_f[cnt].state == 0) {
- j->cadence_f[cnt].state = 1;
- j->cadence_f[cnt].on1min = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 - var)) / 10000));
- j->cadence_f[cnt].on1dot = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100)) / 10000));
- j->cadence_f[cnt].on1max = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 + var)) / 10000));
- } else if (j->cadence_f[cnt].state == 2 &&
- (time_after(jiffies, j->cadence_f[cnt].off1min) &&
- time_before(jiffies, j->cadence_f[cnt].off1max))) {
- if (j->cadence_f[cnt].on2) {
- j->cadence_f[cnt].state = 3;
- j->cadence_f[cnt].on2min = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 - var)) / 10000));
- j->cadence_f[cnt].on2dot = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100)) / 10000));
- j->cadence_f[cnt].on2max = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 + var)) / 10000));
- } else {
- j->cadence_f[cnt].state = 7;
- }
- } else if (j->cadence_f[cnt].state == 4 &&
- (time_after(jiffies, j->cadence_f[cnt].off2min) &&
- time_before(jiffies, j->cadence_f[cnt].off2max))) {
- if (j->cadence_f[cnt].on3) {
- j->cadence_f[cnt].state = 5;
- j->cadence_f[cnt].on3min = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 - var)) / 10000));
- j->cadence_f[cnt].on3dot = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100)) / 10000));
- j->cadence_f[cnt].on3max = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 + var)) / 10000));
- } else {
- j->cadence_f[cnt].state = 7;
- }
- } else {
- j->cadence_f[cnt].state = 0;
- }
- } else if (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)) {
- if (j->cadence_f[cnt].state == 1) {
- if(!j->cadence_f[cnt].on1) {
- j->cadence_f[cnt].state = 7;
- } else if((time_after(jiffies, j->cadence_f[cnt].on1min) &&
- time_before(jiffies, j->cadence_f[cnt].on1max))) {
- if(j->cadence_f[cnt].off1) {
- j->cadence_f[cnt].state = 2;
- j->cadence_f[cnt].off1min = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 - var)) / 10000));
- j->cadence_f[cnt].off1dot = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100)) / 10000));
- j->cadence_f[cnt].off1max = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 + var)) / 10000));
- } else {
- j->cadence_f[cnt].state = 7;
- }
- } else {
- j->cadence_f[cnt].state = 0;
- }
- } else if (j->cadence_f[cnt].state == 3) {
- if((time_after(jiffies, j->cadence_f[cnt].on2min) &&
- time_before(jiffies, j->cadence_f[cnt].on2max))) {
- if(j->cadence_f[cnt].off2) {
- j->cadence_f[cnt].state = 4;
- j->cadence_f[cnt].off2min = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 - var)) / 10000));
- j->cadence_f[cnt].off2dot = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100)) / 10000));
- j->cadence_f[cnt].off2max = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 + var)) / 10000));
- } else {
- j->cadence_f[cnt].state = 7;
- }
- } else {
- j->cadence_f[cnt].state = 0;
- }
- } else if (j->cadence_f[cnt].state == 5) {
- if ((time_after(jiffies, j->cadence_f[cnt].on3min) &&
- time_before(jiffies, j->cadence_f[cnt].on3max))) {
- if(j->cadence_f[cnt].off3) {
- j->cadence_f[cnt].state = 6;
- j->cadence_f[cnt].off3min = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 - var)) / 10000));
- j->cadence_f[cnt].off3dot = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100)) / 10000));
- j->cadence_f[cnt].off3max = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 + var)) / 10000));
- } else {
- j->cadence_f[cnt].state = 7;
- }
- } else {
- j->cadence_f[cnt].state = 0;
- }
- } else {
- j->cadence_f[cnt].state = 0;
- }
- } else {
- switch(j->cadence_f[cnt].state) {
- case 1:
- if(time_after(jiffies, j->cadence_f[cnt].on1dot) &&
- !j->cadence_f[cnt].off1 &&
- !j->cadence_f[cnt].on2 && !j->cadence_f[cnt].off2 &&
- !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
- j->cadence_f[cnt].state = 7;
- }
- break;
- case 3:
- if(time_after(jiffies, j->cadence_f[cnt].on2dot) &&
- !j->cadence_f[cnt].off2 &&
- !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
- j->cadence_f[cnt].state = 7;
- }
- break;
- case 5:
- if(time_after(jiffies, j->cadence_f[cnt].on3dot) &&
- !j->cadence_f[cnt].off3) {
- j->cadence_f[cnt].state = 7;
- }
- break;
- }
- }
-
- if (ixjdebug & 0x0040) {
- printk(KERN_INFO "IXJ Tone Cadence state = %d /dev/phone%d at %ld\n", j->cadence_f[cnt].state, j->board, jiffies);
- switch(j->cadence_f[cnt].state) {
- case 0:
- printk(KERN_INFO "IXJ /dev/phone%d No Tone detected\n", j->board);
- break;
- case 1:
- printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %u %ld - %ld - %ld\n", j->board,
- j->cadence_f[cnt].on1, j->cadence_f[cnt].on1min, j->cadence_f[cnt].on1dot, j->cadence_f[cnt].on1max);
- break;
- case 2:
- printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off1min,
- j->cadence_f[cnt].off1max);
- break;
- case 3:
- printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on2min,
- j->cadence_f[cnt].on2max);
- break;
- case 4:
- printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off2min,
- j->cadence_f[cnt].off2max);
- break;
- case 5:
- printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on3min,
- j->cadence_f[cnt].on3max);
- break;
- case 6:
- printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off3min,
- j->cadence_f[cnt].off3max);
- break;
- }
- }
- }
- if (j->cadence_f[cnt].state == 7) {
- j->cadence_f[cnt].state = 0;
- if (j->cadence_f[cnt].enable == 1)
- j->cadence_f[cnt].enable = 0;
- switch (cnt) {
- case 0:
- if(ixjdebug & 0x0020) {
- printk(KERN_INFO "Filter Cadence 0 triggered %ld\n", jiffies);
- }
- j->ex.bits.fc0 = 1;
- ixj_kill_fasync(j, SIG_FC0, POLL_IN);
- break;
- case 1:
- if(ixjdebug & 0x0020) {
- printk(KERN_INFO "Filter Cadence 1 triggered %ld\n", jiffies);
- }
- j->ex.bits.fc1 = 1;
- ixj_kill_fasync(j, SIG_FC1, POLL_IN);
- break;
- case 2:
- if(ixjdebug & 0x0020) {
- printk(KERN_INFO "Filter Cadence 2 triggered %ld\n", jiffies);
- }
- j->ex.bits.fc2 = 1;
- ixj_kill_fasync(j, SIG_FC2, POLL_IN);
- break;
- case 3:
- if(ixjdebug & 0x0020) {
- printk(KERN_INFO "Filter Cadence 3 triggered %ld\n", jiffies);
- }
- j->ex.bits.fc3 = 1;
- ixj_kill_fasync(j, SIG_FC3, POLL_IN);
- break;
- }
- }
- if (j->filter_en[cnt] && ((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) ||
- (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)))) {
- if((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12))) {
- trg = 1;
- } else if((j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3))) {
- trg = 0;
- }
- switch (cnt) {
- case 0:
- if(ixjdebug & 0x0020) {
- printk(KERN_INFO "Filter 0 triggered %d at %ld\n", trg, jiffies);
- }
- j->ex.bits.f0 = 1;
- ixj_kill_fasync(j, SIG_F0, POLL_IN);
- break;
- case 1:
- if(ixjdebug & 0x0020) {
- printk(KERN_INFO "Filter 1 triggered %d at %ld\n", trg, jiffies);
- }
- j->ex.bits.f1 = 1;
- ixj_kill_fasync(j, SIG_F1, POLL_IN);
- break;
- case 2:
- if(ixjdebug & 0x0020) {
- printk(KERN_INFO "Filter 2 triggered %d at %ld\n", trg, jiffies);
- }
- j->ex.bits.f2 = 1;
- ixj_kill_fasync(j, SIG_F2, POLL_IN);
- break;
- case 3:
- if(ixjdebug & 0x0020) {
- printk(KERN_INFO "Filter 3 triggered %d at %ld\n", trg, jiffies);
- }
- j->ex.bits.f3 = 1;
- ixj_kill_fasync(j, SIG_F3, POLL_IN);
- break;
- }
- }
- }
- return 0;
-}
-
-static int LineMonitor(IXJ *j)
-{
- if (j->dtmf_proc) {
- return -1;
- }
- j->dtmf_proc = 1;
-
- if (ixj_WriteDSPCommand(0x7000, j)) /* Line Monitor */
- return -1;
-
- j->dtmf.bytes.high = j->ssr.high;
- j->dtmf.bytes.low = j->ssr.low;
- if (!j->dtmf_state && j->dtmf.bits.dtmf_valid) {
- j->dtmf_state = 1;
- j->dtmf_current = j->dtmf.bits.digit;
- }
- if (j->dtmf_state && !j->dtmf.bits.dtmf_valid) /* && j->dtmf_wp != j->dtmf_rp) */
- {
- if(!j->cidcw_wait) {
- j->dtmfbuffer[j->dtmf_wp] = j->dtmf_current;
- j->dtmf_wp++;
- if (j->dtmf_wp == 79)
- j->dtmf_wp = 0;
- j->ex.bits.dtmf_ready = 1;
- if(j->ex_sig.bits.dtmf_ready) {
- ixj_kill_fasync(j, SIG_DTMF_READY, POLL_IN);
- }
- }
- else if(j->dtmf_current == 0x00 || j->dtmf_current == 0x0D) {
- if(ixjdebug & 0x0020) {
- printk("IXJ phone%d saw CIDCW Ack DTMF %d from display at %ld\n", j->board, j->dtmf_current, jiffies);
- }
- j->flags.cidcw_ack = 1;
- }
- j->dtmf_state = 0;
- }
- j->dtmf_proc = 0;
-
- return 0;
-}
-
-/************************************************************************
-*
-* Functions to allow alaw <-> ulaw conversions.
-*
-************************************************************************/
-
-static void ulaw2alaw(unsigned char *buff, unsigned long len)
-{
- static unsigned char table_ulaw2alaw[] =
- {
- 0x2A, 0x2B, 0x28, 0x29, 0x2E, 0x2F, 0x2C, 0x2D,
- 0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25,
- 0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D,
- 0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35,
- 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 0x02,
- 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x1A,
- 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 0x12,
- 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6B,
- 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 0x62, 0x63,
- 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 0x7B, 0x79,
- 0x7E, 0x7F, 0x7C, 0x7D, 0x72, 0x73, 0x70, 0x71,
- 0x76, 0x77, 0x74, 0x75, 0x4B, 0x49, 0x4F, 0x4D,
- 0x42, 0x43, 0x40, 0x41, 0x46, 0x47, 0x44, 0x45,
- 0x5A, 0x5B, 0x58, 0x59, 0x5E, 0x5F, 0x5C, 0x5D,
- 0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51,
- 0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0xD5,
- 0xAA, 0xAB, 0xA8, 0xA9, 0xAE, 0xAF, 0xAC, 0xAD,
- 0xA2, 0xA3, 0xA0, 0xA1, 0xA6, 0xA7, 0xA4, 0xA5,
- 0xBA, 0xBB, 0xB8, 0xB9, 0xBE, 0xBF, 0xBC, 0xBD,
- 0xB2, 0xB3, 0xB0, 0xB1, 0xB6, 0xB7, 0xB4, 0xB5,
- 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 0x82,
- 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 0x9A,
- 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 0x92,
- 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 0xEB,
- 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 0xE2, 0xE3,
- 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 0xFB, 0xF9,
- 0xFE, 0xFF, 0xFC, 0xFD, 0xF2, 0xF3, 0xF0, 0xF1,
- 0xF6, 0xF7, 0xF4, 0xF5, 0xCB, 0xC9, 0xCF, 0xCD,
- 0xC2, 0xC3, 0xC0, 0xC1, 0xC6, 0xC7, 0xC4, 0xC5,
- 0xDA, 0xDB, 0xD8, 0xD9, 0xDE, 0xDF, 0xDC, 0xDD,
- 0xD2, 0xD2, 0xD3, 0xD3, 0xD0, 0xD0, 0xD1, 0xD1,
- 0xD6, 0xD6, 0xD7, 0xD7, 0xD4, 0xD4, 0xD5, 0xD5
- };
-
- while (len--)
- {
- *buff = table_ulaw2alaw[*(unsigned char *)buff];
- buff++;
- }
-}
-
-static void alaw2ulaw(unsigned char *buff, unsigned long len)
-{
- static unsigned char table_alaw2ulaw[] =
- {
- 0x29, 0x2A, 0x27, 0x28, 0x2D, 0x2E, 0x2B, 0x2C,
- 0x21, 0x22, 0x1F, 0x20, 0x25, 0x26, 0x23, 0x24,
- 0x39, 0x3A, 0x37, 0x38, 0x3D, 0x3E, 0x3B, 0x3C,
- 0x31, 0x32, 0x2F, 0x30, 0x35, 0x36, 0x33, 0x34,
- 0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D,
- 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05,
- 0x1A, 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D,
- 0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15,
- 0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 0x64, 0x65,
- 0x5D, 0x5D, 0x5C, 0x5C, 0x5F, 0x5F, 0x5E, 0x5E,
- 0x74, 0x76, 0x70, 0x72, 0x7C, 0x7E, 0x78, 0x7A,
- 0x6A, 0x6B, 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D,
- 0x48, 0x49, 0x46, 0x47, 0x4C, 0x4D, 0x4A, 0x4B,
- 0x40, 0x41, 0x3F, 0x3F, 0x44, 0x45, 0x42, 0x43,
- 0x56, 0x57, 0x54, 0x55, 0x5A, 0x5B, 0x58, 0x59,
- 0x4F, 0x4F, 0x4E, 0x4E, 0x52, 0x53, 0x50, 0x51,
- 0xA9, 0xAA, 0xA7, 0xA8, 0xAD, 0xAE, 0xAB, 0xAC,
- 0xA1, 0xA2, 0x9F, 0xA0, 0xA5, 0xA6, 0xA3, 0xA4,
- 0xB9, 0xBA, 0xB7, 0xB8, 0xBD, 0xBE, 0xBB, 0xBC,
- 0xB1, 0xB2, 0xAF, 0xB0, 0xB5, 0xB6, 0xB3, 0xB4,
- 0x8A, 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D,
- 0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85,
- 0x9A, 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D,
- 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95,
- 0xE2, 0xE3, 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5,
- 0xDD, 0xDD, 0xDC, 0xDC, 0xDF, 0xDF, 0xDE, 0xDE,
- 0xF4, 0xF6, 0xF0, 0xF2, 0xFC, 0xFE, 0xF8, 0xFA,
- 0xEA, 0xEB, 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED,
- 0xC8, 0xC9, 0xC6, 0xC7, 0xCC, 0xCD, 0xCA, 0xCB,
- 0xC0, 0xC1, 0xBF, 0xBF, 0xC4, 0xC5, 0xC2, 0xC3,
- 0xD6, 0xD7, 0xD4, 0xD5, 0xDA, 0xDB, 0xD8, 0xD9,
- 0xCF, 0xCF, 0xCE, 0xCE, 0xD2, 0xD3, 0xD0, 0xD1
- };
-
- while (len--)
- {
- *buff = table_alaw2ulaw[*(unsigned char *)buff];
- buff++;
- }
-}
-
-static ssize_t ixj_read(struct file * file_p, char __user *buf, size_t length, loff_t * ppos)
-{
- unsigned long i = *ppos;
- IXJ * j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
-
- DECLARE_WAITQUEUE(wait, current);
-
- if (j->flags.inread)
- return -EALREADY;
-
- j->flags.inread = 1;
-
- add_wait_queue(&j->read_q, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
- mb();
-
- while (!j->read_buffer_ready || (j->dtmf_state && j->flags.dtmf_oob)) {
- ++j->read_wait;
- if (file_p->f_flags & O_NONBLOCK) {
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&j->read_q, &wait);
- j->flags.inread = 0;
- return -EAGAIN;
- }
- if (!ixj_hookstate(j)) {
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&j->read_q, &wait);
- j->flags.inread = 0;
- return 0;
- }
- interruptible_sleep_on(&j->read_q);
- if (signal_pending(current)) {
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&j->read_q, &wait);
- j->flags.inread = 0;
- return -EINTR;
- }
- }
-
- remove_wait_queue(&j->read_q, &wait);
- set_current_state(TASK_RUNNING);
- /* Don't ever copy more than the user asks */
- if(j->rec_codec == ALAW)
- ulaw2alaw(j->read_buffer, min(length, j->read_buffer_size));
- i = copy_to_user(buf, j->read_buffer, min(length, j->read_buffer_size));
- j->read_buffer_ready = 0;
- if (i) {
- j->flags.inread = 0;
- return -EFAULT;
- } else {
- j->flags.inread = 0;
- return min(length, j->read_buffer_size);
- }
-}
-
-static ssize_t ixj_enhanced_read(struct file * file_p, char __user *buf, size_t length,
- loff_t * ppos)
-{
- int pre_retval;
- ssize_t read_retval = 0;
- IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
-
- pre_retval = ixj_PreRead(j, 0L);
- switch (pre_retval) {
- case NORMAL:
- read_retval = ixj_read(file_p, buf, length, ppos);
- ixj_PostRead(j, 0L);
- break;
- case NOPOST:
- read_retval = ixj_read(file_p, buf, length, ppos);
- break;
- case POSTONLY:
- ixj_PostRead(j, 0L);
- break;
- default:
- read_retval = pre_retval;
- }
- return read_retval;
-}
-
-static ssize_t ixj_write(struct file *file_p, const char __user *buf, size_t count, loff_t * ppos)
-{
- unsigned long i = *ppos;
- IXJ *j = file_p->private_data;
-
- DECLARE_WAITQUEUE(wait, current);
-
- if (j->flags.inwrite)
- return -EALREADY;
-
- j->flags.inwrite = 1;
-
- add_wait_queue(&j->write_q, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
- mb();
-
-
- while (!j->write_buffers_empty) {
- ++j->write_wait;
- if (file_p->f_flags & O_NONBLOCK) {
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&j->write_q, &wait);
- j->flags.inwrite = 0;
- return -EAGAIN;
- }
- if (!ixj_hookstate(j)) {
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&j->write_q, &wait);
- j->flags.inwrite = 0;
- return 0;
- }
- interruptible_sleep_on(&j->write_q);
- if (signal_pending(current)) {
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&j->write_q, &wait);
- j->flags.inwrite = 0;
- return -EINTR;
- }
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&j->write_q, &wait);
- if (j->write_buffer_wp + count >= j->write_buffer_end)
- j->write_buffer_wp = j->write_buffer;
- i = copy_from_user(j->write_buffer_wp, buf, min(count, j->write_buffer_size));
- if (i) {
- j->flags.inwrite = 0;
- return -EFAULT;
- }
- if(j->play_codec == ALAW)
- alaw2ulaw(j->write_buffer_wp, min(count, j->write_buffer_size));
- j->flags.inwrite = 0;
- return min(count, j->write_buffer_size);
-}
-
-static ssize_t ixj_enhanced_write(struct file * file_p, const char __user *buf, size_t count, loff_t * ppos)
-{
- int pre_retval;
- ssize_t write_retval = 0;
-
- IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
-
- pre_retval = ixj_PreWrite(j, 0L);
- switch (pre_retval) {
- case NORMAL:
- write_retval = ixj_write(file_p, buf, count, ppos);
- if (write_retval > 0) {
- ixj_PostWrite(j, 0L);
- j->write_buffer_wp += write_retval;
- j->write_buffers_empty--;
- }
- break;
- case NOPOST:
- write_retval = ixj_write(file_p, buf, count, ppos);
- if (write_retval > 0) {
- j->write_buffer_wp += write_retval;
- j->write_buffers_empty--;
- }
- break;
- case POSTONLY:
- ixj_PostWrite(j, 0L);
- break;
- default:
- write_retval = pre_retval;
- }
- return write_retval;
-}
-
-static void ixj_read_frame(IXJ *j)
-{
- int cnt, dly;
-
- if (j->read_buffer) {
- for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
- if (!(cnt % 16) && !IsRxReady(j)) {
- dly = 0;
- while (!IsRxReady(j)) {
- if (dly++ > 5) {
- dly = 0;
- break;
- }
- udelay(10);
- }
- }
- /* Throw away word 0 of the 8021 compressed format to get standard G.729. */
- if (j->rec_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) {
- inb_p(j->DSPbase + 0x0E);
- inb_p(j->DSPbase + 0x0F);
- }
- *(j->read_buffer + cnt) = inb_p(j->DSPbase + 0x0E);
- *(j->read_buffer + cnt + 1) = inb_p(j->DSPbase + 0x0F);
- }
- ++j->framesread;
- if (j->intercom != -1) {
- if (IsTxReady(get_ixj(j->intercom))) {
- for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
- if (!(cnt % 16) && !IsTxReady(j)) {
- dly = 0;
- while (!IsTxReady(j)) {
- if (dly++ > 5) {
- dly = 0;
- break;
- }
- udelay(10);
- }
- }
- outb_p(*(j->read_buffer + cnt), get_ixj(j->intercom)->DSPbase + 0x0C);
- outb_p(*(j->read_buffer + cnt + 1), get_ixj(j->intercom)->DSPbase + 0x0D);
- }
- get_ixj(j->intercom)->frameswritten++;
- }
- } else {
- j->read_buffer_ready = 1;
- wake_up_interruptible(&j->read_q); /* Wake any blocked readers */
-
- wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */
-
- if(j->ixj_signals[SIG_READ_READY])
- ixj_kill_fasync(j, SIG_READ_READY, POLL_OUT);
- }
- }
-}
-
-static short fsk[][6][20] =
-{
- {
- {
- 0, 17846, 29934, 32364, 24351, 8481, -10126, -25465, -32587, -29196,
- -16384, 1715, 19260, 30591, 32051, 23170, 6813, -11743, -26509, -32722
- },
- {
- -28377, -14876, 3425, 20621, 31163, 31650, 21925, 5126, -13328, -27481,
- -32767, -27481, -13328, 5126, 21925, 31650, 31163, 20621, 3425, -14876
- },
- {
- -28377, -32722, -26509, -11743, 6813, 23170, 32051, 30591, 19260, 1715,
- -16384, -29196, -32587, -25465, -10126, 8481, 24351, 32364, 29934, 17846
- },
- {
- 0, -17846, -29934, -32364, -24351, -8481, 10126, 25465, 32587, 29196,
- 16384, -1715, -19260, -30591, -32051, -23170, -6813, 11743, 26509, 32722
- },
- {
- 28377, 14876, -3425, -20621, -31163, -31650, -21925, -5126, 13328, 27481,
- 32767, 27481, 13328, -5126, -21925, -31650, -31163, -20621, -3425, 14876
- },
- {
- 28377, 32722, 26509, 11743, -6813, -23170, -32051, -30591, -19260, -1715,
- 16384, 29196, 32587, 25465, 10126, -8481, -24351, -32364, -29934, -17846
- }
- },
- {
- {
- 0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126,
- 0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126
- },
- {
- -28377, -21925, -13328, -3425, 6813, 16384, 24351, 29934, 32587, 32051,
- 28377, 21925, 13328, 3425, -6813, -16384, -24351, -29934, -32587, -32051
- },
- {
- -28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925,
- 28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925
- },
- {
- 0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126,
- 0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126
- },
- {
- 28377, 21925, 13328, 3425, -6813, -16383, -24351, -29934, -32587, -32051,
- -28377, -21925, -13328, -3425, 6813, 16383, 24351, 29934, 32587, 32051
- },
- {
- 28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925,
- -28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925
- }
- }
-};
-
-
-static void ixj_write_cid_bit(IXJ *j, int bit)
-{
- while (j->fskcnt < 20) {
- if(j->fskdcnt < (j->fsksize - 1))
- j->fskdata[j->fskdcnt++] = fsk[bit][j->fskz][j->fskcnt];
-
- j->fskcnt += 3;
- }
- j->fskcnt %= 20;
-
- if (!bit)
- j->fskz++;
- if (j->fskz >= 6)
- j->fskz = 0;
-
-}
-
-static void ixj_write_cid_byte(IXJ *j, char byte)
-{
- IXJ_CBYTE cb;
-
- cb.cbyte = byte;
- ixj_write_cid_bit(j, 0);
- ixj_write_cid_bit(j, cb.cbits.b0 ? 1 : 0);
- ixj_write_cid_bit(j, cb.cbits.b1 ? 1 : 0);
- ixj_write_cid_bit(j, cb.cbits.b2 ? 1 : 0);
- ixj_write_cid_bit(j, cb.cbits.b3 ? 1 : 0);
- ixj_write_cid_bit(j, cb.cbits.b4 ? 1 : 0);
- ixj_write_cid_bit(j, cb.cbits.b5 ? 1 : 0);
- ixj_write_cid_bit(j, cb.cbits.b6 ? 1 : 0);
- ixj_write_cid_bit(j, cb.cbits.b7 ? 1 : 0);
- ixj_write_cid_bit(j, 1);
-}
-
-static void ixj_write_cid_seize(IXJ *j)
-{
- int cnt;
-
- for (cnt = 0; cnt < 150; cnt++) {
- ixj_write_cid_bit(j, 0);
- ixj_write_cid_bit(j, 1);
- }
- for (cnt = 0; cnt < 180; cnt++) {
- ixj_write_cid_bit(j, 1);
- }
-}
-
-static void ixj_write_cidcw_seize(IXJ *j)
-{
- int cnt;
-
- for (cnt = 0; cnt < 80; cnt++) {
- ixj_write_cid_bit(j, 1);
- }
-}
-
-static int ixj_write_cid_string(IXJ *j, char *s, int checksum)
-{
- int cnt;
-
- for (cnt = 0; cnt < strlen(s); cnt++) {
- ixj_write_cid_byte(j, s[cnt]);
- checksum = (checksum + s[cnt]);
- }
- return checksum;
-}
-
-static void ixj_pad_fsk(IXJ *j, int pad)
-{
- int cnt;
-
- for (cnt = 0; cnt < pad; cnt++) {
- if(j->fskdcnt < (j->fsksize - 1))
- j->fskdata[j->fskdcnt++] = 0x0000;
- }
- for (cnt = 0; cnt < 720; cnt++) {
- if(j->fskdcnt < (j->fsksize - 1))
- j->fskdata[j->fskdcnt++] = 0x0000;
- }
-}
-
-static void ixj_pre_cid(IXJ *j)
-{
- j->cid_play_codec = j->play_codec;
- j->cid_play_frame_size = j->play_frame_size;
- j->cid_play_volume = get_play_volume(j);
- j->cid_play_flag = j->flags.playing;
-
- j->cid_rec_codec = j->rec_codec;
- j->cid_rec_volume = get_rec_volume(j);
- j->cid_rec_flag = j->flags.recording;
-
- j->cid_play_aec_level = j->aec_level;
-
- switch(j->baseframe.low) {
- case 0xA0:
- j->cid_base_frame_size = 20;
- break;
- case 0x50:
- j->cid_base_frame_size = 10;
- break;
- case 0xF0:
- j->cid_base_frame_size = 30;
- break;
- }
-
- ixj_play_stop(j);
- ixj_cpt_stop(j);
-
- j->flags.cidplay = 1;
-
- set_base_frame(j, 30);
- set_play_codec(j, LINEAR16);
- set_play_volume(j, 0x1B);
- ixj_play_start(j);
-}
-
-static void ixj_post_cid(IXJ *j)
-{
- ixj_play_stop(j);
-
- if(j->cidsize > 5000) {
- SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
- }
- j->flags.cidplay = 0;
- if(ixjdebug & 0x0200) {
- printk("IXJ phone%d Finished Playing CallerID data %ld\n", j->board, jiffies);
- }
-
- ixj_fsk_free(j);
-
- j->fskdcnt = 0;
- set_base_frame(j, j->cid_base_frame_size);
- set_play_codec(j, j->cid_play_codec);
- ixj_aec_start(j, j->cid_play_aec_level);
- set_play_volume(j, j->cid_play_volume);
-
- set_rec_codec(j, j->cid_rec_codec);
- set_rec_volume(j, j->cid_rec_volume);
-
- if(j->cid_rec_flag)
- ixj_record_start(j);
-
- if(j->cid_play_flag)
- ixj_play_start(j);
-
- if(j->cid_play_flag) {
- wake_up_interruptible(&j->write_q); /* Wake any blocked writers */
- }
-}
-
-static void ixj_write_cid(IXJ *j)
-{
- char sdmf1[50];
- char sdmf2[50];
- char sdmf3[80];
- char mdmflen, len1, len2, len3;
- int pad;
-
- int checksum = 0;
-
- if (j->dsp.low == 0x20 || j->flags.cidplay)
- return;
-
- j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
- j->cidsize = j->cidcnt = 0;
-
- ixj_fsk_alloc(j);
-
- strcpy(sdmf1, j->cid_send.month);
- strcat(sdmf1, j->cid_send.day);
- strcat(sdmf1, j->cid_send.hour);
- strcat(sdmf1, j->cid_send.min);
- strcpy(sdmf2, j->cid_send.number);
- strcpy(sdmf3, j->cid_send.name);
-
- len1 = strlen(sdmf1);
- len2 = strlen(sdmf2);
- len3 = strlen(sdmf3);
- mdmflen = len1 + len2 + len3 + 6;
-
- while(1){
- ixj_write_cid_seize(j);
-
- ixj_write_cid_byte(j, 0x80);
- checksum = 0x80;
- ixj_write_cid_byte(j, mdmflen);
- checksum = checksum + mdmflen;
-
- ixj_write_cid_byte(j, 0x01);
- checksum = checksum + 0x01;
- ixj_write_cid_byte(j, len1);
- checksum = checksum + len1;
- checksum = ixj_write_cid_string(j, sdmf1, checksum);
- if(ixj_hookstate(j) & 1)
- break;
-
- ixj_write_cid_byte(j, 0x02);
- checksum = checksum + 0x02;
- ixj_write_cid_byte(j, len2);
- checksum = checksum + len2;
- checksum = ixj_write_cid_string(j, sdmf2, checksum);
- if(ixj_hookstate(j) & 1)
- break;
-
- ixj_write_cid_byte(j, 0x07);
- checksum = checksum + 0x07;
- ixj_write_cid_byte(j, len3);
- checksum = checksum + len3;
- checksum = ixj_write_cid_string(j, sdmf3, checksum);
- if(ixj_hookstate(j) & 1)
- break;
-
- checksum %= 256;
- checksum ^= 0xFF;
- checksum += 1;
-
- ixj_write_cid_byte(j, (char) checksum);
-
- pad = j->fskdcnt % 240;
- if (pad) {
- pad = 240 - pad;
- }
- ixj_pad_fsk(j, pad);
- break;
- }
-
- ixj_write_frame(j);
-}
-
-static void ixj_write_cidcw(IXJ *j)
-{
- IXJ_TONE ti;
-
- char sdmf1[50];
- char sdmf2[50];
- char sdmf3[80];
- char mdmflen, len1, len2, len3;
- int pad;
-
- int checksum = 0;
-
- if (j->dsp.low == 0x20 || j->flags.cidplay)
- return;
-
- j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
- j->cidsize = j->cidcnt = 0;
-
- ixj_fsk_alloc(j);
-
- j->flags.cidcw_ack = 0;
-
- ti.tone_index = 23;
- ti.gain0 = 1;
- ti.freq0 = hz440;
- ti.gain1 = 0;
- ti.freq1 = 0;
- ixj_init_tone(j, &ti);
-
- ixj_set_tone_on(1500, j);
- ixj_set_tone_off(32, j);
- if(ixjdebug & 0x0200) {
- printk("IXJ cidcw phone%d first tone start at %ld\n", j->board, jiffies);
- }
- ixj_play_tone(j, 23);
-
- clear_bit(j->board, &j->busyflags);
- while(j->tone_state)
- schedule_timeout_interruptible(1);
- while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0)
- schedule_timeout_interruptible(1);
- if(ixjdebug & 0x0200) {
- printk("IXJ cidcw phone%d first tone end at %ld\n", j->board, jiffies);
- }
-
- ti.tone_index = 24;
- ti.gain0 = 1;
- ti.freq0 = hz2130;
- ti.gain1 = 0;
- ti.freq1 = hz2750;
- ixj_init_tone(j, &ti);
-
- ixj_set_tone_off(10, j);
- ixj_set_tone_on(600, j);
- if(ixjdebug & 0x0200) {
- printk("IXJ cidcw phone%d second tone start at %ld\n", j->board, jiffies);
- }
- ixj_play_tone(j, 24);
-
- clear_bit(j->board, &j->busyflags);
- while(j->tone_state)
- schedule_timeout_interruptible(1);
- while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0)
- schedule_timeout_interruptible(1);
- if(ixjdebug & 0x0200) {
- printk("IXJ cidcw phone%d sent second tone at %ld\n", j->board, jiffies);
- }
-
- j->cidcw_wait = jiffies + ((50 * hertz) / 100);
-
- clear_bit(j->board, &j->busyflags);
- while(!j->flags.cidcw_ack && time_before(jiffies, j->cidcw_wait))
- schedule_timeout_interruptible(1);
- while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0)
- schedule_timeout_interruptible(1);
- j->cidcw_wait = 0;
- if(!j->flags.cidcw_ack) {
- if(ixjdebug & 0x0200) {
- printk("IXJ cidcw phone%d did not receive ACK from display %ld\n", j->board, jiffies);
- }
- ixj_post_cid(j);
- if(j->cid_play_flag) {
- wake_up_interruptible(&j->write_q); /* Wake any blocked readers */
- }
- return;
- } else {
- ixj_pre_cid(j);
- }
- j->flags.cidcw_ack = 0;
- strcpy(sdmf1, j->cid_send.month);
- strcat(sdmf1, j->cid_send.day);
- strcat(sdmf1, j->cid_send.hour);
- strcat(sdmf1, j->cid_send.min);
- strcpy(sdmf2, j->cid_send.number);
- strcpy(sdmf3, j->cid_send.name);
-
- len1 = strlen(sdmf1);
- len2 = strlen(sdmf2);
- len3 = strlen(sdmf3);
- mdmflen = len1 + len2 + len3 + 6;
-
- ixj_write_cidcw_seize(j);
-
- ixj_write_cid_byte(j, 0x80);
- checksum = 0x80;
- ixj_write_cid_byte(j, mdmflen);
- checksum = checksum + mdmflen;
-
- ixj_write_cid_byte(j, 0x01);
- checksum = checksum + 0x01;
- ixj_write_cid_byte(j, len1);
- checksum = checksum + len1;
- checksum = ixj_write_cid_string(j, sdmf1, checksum);
-
- ixj_write_cid_byte(j, 0x02);
- checksum = checksum + 0x02;
- ixj_write_cid_byte(j, len2);
- checksum = checksum + len2;
- checksum = ixj_write_cid_string(j, sdmf2, checksum);
-
- ixj_write_cid_byte(j, 0x07);
- checksum = checksum + 0x07;
- ixj_write_cid_byte(j, len3);
- checksum = checksum + len3;
- checksum = ixj_write_cid_string(j, sdmf3, checksum);
-
- checksum %= 256;
- checksum ^= 0xFF;
- checksum += 1;
-
- ixj_write_cid_byte(j, (char) checksum);
-
- pad = j->fskdcnt % 240;
- if (pad) {
- pad = 240 - pad;
- }
- ixj_pad_fsk(j, pad);
- if(ixjdebug & 0x0200) {
- printk("IXJ cidcw phone%d sent FSK data at %ld\n", j->board, jiffies);
- }
-}
-
-static void ixj_write_vmwi(IXJ *j, int msg)
-{
- char mdmflen;
- int pad;
-
- int checksum = 0;
-
- if (j->dsp.low == 0x20 || j->flags.cidplay)
- return;
-
- j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
- j->cidsize = j->cidcnt = 0;
-
- ixj_fsk_alloc(j);
-
- mdmflen = 3;
-
- if (j->port == PORT_POTS)
- SLIC_SetState(PLD_SLIC_STATE_OHT, j);
-
- ixj_write_cid_seize(j);
-
- ixj_write_cid_byte(j, 0x82);
- checksum = 0x82;
- ixj_write_cid_byte(j, mdmflen);
- checksum = checksum + mdmflen;
-
- ixj_write_cid_byte(j, 0x0B);
- checksum = checksum + 0x0B;
- ixj_write_cid_byte(j, 1);
- checksum = checksum + 1;
-
- if(msg) {
- ixj_write_cid_byte(j, 0xFF);
- checksum = checksum + 0xFF;
- }
- else {
- ixj_write_cid_byte(j, 0x00);
- checksum = checksum + 0x00;
- }
-
- checksum %= 256;
- checksum ^= 0xFF;
- checksum += 1;
-
- ixj_write_cid_byte(j, (char) checksum);
-
- pad = j->fskdcnt % 240;
- if (pad) {
- pad = 240 - pad;
- }
- ixj_pad_fsk(j, pad);
-}
-
-static void ixj_write_frame(IXJ *j)
-{
- int cnt, frame_count, dly;
- IXJ_WORD dat;
-
- frame_count = 0;
- if(j->flags.cidplay) {
- for(cnt = 0; cnt < 480; cnt++) {
- if (!(cnt % 16) && !IsTxReady(j)) {
- dly = 0;
- while (!IsTxReady(j)) {
- if (dly++ > 5) {
- dly = 0;
- break;
- }
- udelay(10);
- }
- }
- dat.word = j->fskdata[j->cidcnt++];
- outb_p(dat.bytes.low, j->DSPbase + 0x0C);
- outb_p(dat.bytes.high, j->DSPbase + 0x0D);
- cnt++;
- }
- if(j->cidcnt >= j->fskdcnt) {
- ixj_post_cid(j);
- }
- /* This may seem rude, but if we just played one frame of FSK data for CallerID
- and there is real audio data in the buffer, we need to throw it away because
- we just used it's time slot */
- if (j->write_buffer_rp > j->write_buffer_wp) {
- j->write_buffer_rp += j->cid_play_frame_size * 2;
- if (j->write_buffer_rp >= j->write_buffer_end) {
- j->write_buffer_rp = j->write_buffer;
- }
- j->write_buffers_empty++;
- wake_up_interruptible(&j->write_q); /* Wake any blocked writers */
-
- wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */
- }
- } else if (j->write_buffer && j->write_buffers_empty < 1) {
- if (j->write_buffer_wp > j->write_buffer_rp) {
- frame_count =
- (j->write_buffer_wp - j->write_buffer_rp) / (j->play_frame_size * 2);
- }
- if (j->write_buffer_rp > j->write_buffer_wp) {
- frame_count =
- (j->write_buffer_wp - j->write_buffer) / (j->play_frame_size * 2) +
- (j->write_buffer_end - j->write_buffer_rp) / (j->play_frame_size * 2);
- }
- if (frame_count >= 1) {
- if (j->ver.low == 0x12 && j->play_mode && j->flags.play_first_frame) {
- BYTES blankword;
-
- switch (j->play_mode) {
- case PLAYBACK_MODE_ULAW:
- case PLAYBACK_MODE_ALAW:
- blankword.low = blankword.high = 0xFF;
- break;
- case PLAYBACK_MODE_8LINEAR:
- case PLAYBACK_MODE_16LINEAR:
- default:
- blankword.low = blankword.high = 0x00;
- break;
- case PLAYBACK_MODE_8LINEAR_WSS:
- blankword.low = blankword.high = 0x80;
- break;
- }
- for (cnt = 0; cnt < 16; cnt++) {
- if (!(cnt % 16) && !IsTxReady(j)) {
- dly = 0;
- while (!IsTxReady(j)) {
- if (dly++ > 5) {
- dly = 0;
- break;
- }
- udelay(10);
- }
- }
- outb_p((blankword.low), j->DSPbase + 0x0C);
- outb_p((blankword.high), j->DSPbase + 0x0D);
- }
- j->flags.play_first_frame = 0;
- } else if (j->play_codec == G723_63 && j->flags.play_first_frame) {
- for (cnt = 0; cnt < 24; cnt++) {
- BYTES blankword;
-
- if(cnt == 12) {
- blankword.low = 0x02;
- blankword.high = 0x00;
- }
- else {
- blankword.low = blankword.high = 0x00;
- }
- if (!(cnt % 16) && !IsTxReady(j)) {
- dly = 0;
- while (!IsTxReady(j)) {
- if (dly++ > 5) {
- dly = 0;
- break;
- }
- udelay(10);
- }
- }
- outb_p((blankword.low), j->DSPbase + 0x0C);
- outb_p((blankword.high), j->DSPbase + 0x0D);
- }
- j->flags.play_first_frame = 0;
- }
- for (cnt = 0; cnt < j->play_frame_size * 2; cnt += 2) {
- if (!(cnt % 16) && !IsTxReady(j)) {
- dly = 0;
- while (!IsTxReady(j)) {
- if (dly++ > 5) {
- dly = 0;
- break;
- }
- udelay(10);
- }
- }
- /* Add word 0 to G.729 frames for the 8021. Right now we don't do VAD/CNG */
- if (j->play_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) {
- if (j->write_buffer_rp[cnt] == 0 &&
- j->write_buffer_rp[cnt + 1] == 0 &&
- j->write_buffer_rp[cnt + 2] == 0 &&
- j->write_buffer_rp[cnt + 3] == 0 &&
- j->write_buffer_rp[cnt + 4] == 0 &&
- j->write_buffer_rp[cnt + 5] == 0 &&
- j->write_buffer_rp[cnt + 6] == 0 &&
- j->write_buffer_rp[cnt + 7] == 0 &&
- j->write_buffer_rp[cnt + 8] == 0 &&
- j->write_buffer_rp[cnt + 9] == 0) {
- /* someone is trying to write silence lets make this a type 0 frame. */
- outb_p(0x00, j->DSPbase + 0x0C);
- outb_p(0x00, j->DSPbase + 0x0D);
- } else {
- /* so all other frames are type 1. */
- outb_p(0x01, j->DSPbase + 0x0C);
- outb_p(0x00, j->DSPbase + 0x0D);
- }
- }
- outb_p(*(j->write_buffer_rp + cnt), j->DSPbase + 0x0C);
- outb_p(*(j->write_buffer_rp + cnt + 1), j->DSPbase + 0x0D);
- *(j->write_buffer_rp + cnt) = 0;
- *(j->write_buffer_rp + cnt + 1) = 0;
- }
- j->write_buffer_rp += j->play_frame_size * 2;
- if (j->write_buffer_rp >= j->write_buffer_end) {
- j->write_buffer_rp = j->write_buffer;
- }
- j->write_buffers_empty++;
- wake_up_interruptible(&j->write_q); /* Wake any blocked writers */
-
- wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */
-
- ++j->frameswritten;
- }
- } else {
- j->drybuffer++;
- }
- if(j->ixj_signals[SIG_WRITE_READY]) {
- ixj_kill_fasync(j, SIG_WRITE_READY, POLL_OUT);
- }
-}
-
-static int idle(IXJ *j)
-{
- if (ixj_WriteDSPCommand(0x0000, j)) /* DSP Idle */
-
- return 0;
-
- if (j->ssr.high || j->ssr.low) {
- return 0;
- } else {
- j->play_mode = -1;
- j->flags.playing = 0;
- j->rec_mode = -1;
- j->flags.recording = 0;
- return 1;
- }
-}
-
-static int set_base_frame(IXJ *j, int size)
-{
- unsigned short cmd;
- int cnt;
-
- idle(j);
- j->cid_play_aec_level = j->aec_level;
- aec_stop(j);
- for (cnt = 0; cnt < 10; cnt++) {
- if (idle(j))
- break;
- }
- if (j->ssr.high || j->ssr.low)
- return -1;
- if (j->dsp.low != 0x20) {
- switch (size) {
- case 30:
- cmd = 0x07F0;
- /* Set Base Frame Size to 240 pg9-10 8021 */
- break;
- case 20:
- cmd = 0x07A0;
- /* Set Base Frame Size to 160 pg9-10 8021 */
- break;
- case 10:
- cmd = 0x0750;
- /* Set Base Frame Size to 80 pg9-10 8021 */
- break;
- default:
- return -1;
- }
- } else {
- if (size == 30)
- return size;
- else
- return -1;
- }
- if (ixj_WriteDSPCommand(cmd, j)) {
- j->baseframe.high = j->baseframe.low = 0xFF;
- return -1;
- } else {
- j->baseframe.high = j->ssr.high;
- j->baseframe.low = j->ssr.low;
- /* If the status returned is 0x0000 (pg9-9 8021) the call failed */
- if(j->baseframe.high == 0x00 && j->baseframe.low == 0x00) {
- return -1;
- }
- }
- ixj_aec_start(j, j->cid_play_aec_level);
- return size;
-}
-
-static int set_rec_codec(IXJ *j, int rate)
-{
- int retval = 0;
-
- j->rec_codec = rate;
-
- switch (rate) {
- case G723_63:
- if (j->ver.low != 0x12 || ixj_convert_loaded) {
- j->rec_frame_size = 12;
- j->rec_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case G723_53:
- if (j->ver.low != 0x12 || ixj_convert_loaded) {
- j->rec_frame_size = 10;
- j->rec_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case TS85:
- if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
- j->rec_frame_size = 16;
- j->rec_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case TS48:
- if (j->ver.low != 0x12 || ixj_convert_loaded) {
- j->rec_frame_size = 9;
- j->rec_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case TS41:
- if (j->ver.low != 0x12 || ixj_convert_loaded) {
- j->rec_frame_size = 8;
- j->rec_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case G728:
- if (j->dsp.low != 0x20) {
- j->rec_frame_size = 48;
- j->rec_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case G729:
- if (j->dsp.low != 0x20) {
- if (!j->flags.g729_loaded) {
- retval = 1;
- break;
- }
- switch (j->baseframe.low) {
- case 0xA0:
- j->rec_frame_size = 10;
- break;
- case 0x50:
- j->rec_frame_size = 5;
- break;
- default:
- j->rec_frame_size = 15;
- break;
- }
- j->rec_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case G729B:
- if (j->dsp.low != 0x20) {
- if (!j->flags.g729_loaded) {
- retval = 1;
- break;
- }
- switch (j->baseframe.low) {
- case 0xA0:
- j->rec_frame_size = 12;
- break;
- case 0x50:
- j->rec_frame_size = 6;
- break;
- default:
- j->rec_frame_size = 18;
- break;
- }
- j->rec_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case ULAW:
- switch (j->baseframe.low) {
- case 0xA0:
- j->rec_frame_size = 80;
- break;
- case 0x50:
- j->rec_frame_size = 40;
- break;
- default:
- j->rec_frame_size = 120;
- break;
- }
- j->rec_mode = 4;
- break;
- case ALAW:
- switch (j->baseframe.low) {
- case 0xA0:
- j->rec_frame_size = 80;
- break;
- case 0x50:
- j->rec_frame_size = 40;
- break;
- default:
- j->rec_frame_size = 120;
- break;
- }
- j->rec_mode = 4;
- break;
- case LINEAR16:
- switch (j->baseframe.low) {
- case 0xA0:
- j->rec_frame_size = 160;
- break;
- case 0x50:
- j->rec_frame_size = 80;
- break;
- default:
- j->rec_frame_size = 240;
- break;
- }
- j->rec_mode = 5;
- break;
- case LINEAR8:
- switch (j->baseframe.low) {
- case 0xA0:
- j->rec_frame_size = 80;
- break;
- case 0x50:
- j->rec_frame_size = 40;
- break;
- default:
- j->rec_frame_size = 120;
- break;
- }
- j->rec_mode = 6;
- break;
- case WSS:
- switch (j->baseframe.low) {
- case 0xA0:
- j->rec_frame_size = 80;
- break;
- case 0x50:
- j->rec_frame_size = 40;
- break;
- default:
- j->rec_frame_size = 120;
- break;
- }
- j->rec_mode = 7;
- break;
- default:
- kfree(j->read_buffer);
- j->rec_frame_size = 0;
- j->rec_mode = -1;
- j->read_buffer = NULL;
- j->read_buffer_size = 0;
- retval = 1;
- break;
- }
- return retval;
-}
-
-static int ixj_record_start(IXJ *j)
-{
- unsigned short cmd = 0x0000;
-
- if (j->read_buffer) {
- ixj_record_stop(j);
- }
- j->flags.recording = 1;
- ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */
-
- if(ixjdebug & 0x0002)
- printk("IXJ %d Starting Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
-
- if (!j->rec_mode) {
- switch (j->rec_codec) {
- case G723_63:
- cmd = 0x5131;
- break;
- case G723_53:
- cmd = 0x5132;
- break;
- case TS85:
- cmd = 0x5130; /* TrueSpeech 8.5 */
-
- break;
- case TS48:
- cmd = 0x5133; /* TrueSpeech 4.8 */
-
- break;
- case TS41:
- cmd = 0x5134; /* TrueSpeech 4.1 */
-
- break;
- case G728:
- cmd = 0x5135;
- break;
- case G729:
- case G729B:
- cmd = 0x5136;
- break;
- default:
- return 1;
- }
- if (ixj_WriteDSPCommand(cmd, j))
- return -1;
- }
- if (!j->read_buffer) {
- if (!j->read_buffer)
- j->read_buffer = kmalloc(j->rec_frame_size * 2, GFP_ATOMIC);
- if (!j->read_buffer) {
- printk("Read buffer allocation for ixj board %d failed!\n", j->board);
- return -ENOMEM;
- }
- }
- j->read_buffer_size = j->rec_frame_size * 2;
-
- if (ixj_WriteDSPCommand(0x5102, j)) /* Set Poll sync mode */
-
- return -1;
-
- switch (j->rec_mode) {
- case 0:
- cmd = 0x1C03; /* Record C1 */
-
- break;
- case 4:
- if (j->ver.low == 0x12) {
- cmd = 0x1E03; /* Record C1 */
-
- } else {
- cmd = 0x1E01; /* Record C1 */
-
- }
- break;
- case 5:
- if (j->ver.low == 0x12) {
- cmd = 0x1E83; /* Record C1 */
-
- } else {
- cmd = 0x1E81; /* Record C1 */
-
- }
- break;
- case 6:
- if (j->ver.low == 0x12) {
- cmd = 0x1F03; /* Record C1 */
-
- } else {
- cmd = 0x1F01; /* Record C1 */
-
- }
- break;
- case 7:
- if (j->ver.low == 0x12) {
- cmd = 0x1F83; /* Record C1 */
- } else {
- cmd = 0x1F81; /* Record C1 */
- }
- break;
- }
- if (ixj_WriteDSPCommand(cmd, j))
- return -1;
-
- if (j->flags.playing) {
- ixj_aec_start(j, j->aec_level);
- }
- return 0;
-}
-
-static void ixj_record_stop(IXJ *j)
-{
- if (ixjdebug & 0x0002)
- printk("IXJ %d Stopping Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
-
- kfree(j->read_buffer);
- j->read_buffer = NULL;
- j->read_buffer_size = 0;
- if (j->rec_mode > -1) {
- ixj_WriteDSPCommand(0x5120, j);
- j->rec_mode = -1;
- }
- j->flags.recording = 0;
-}
-static void ixj_vad(IXJ *j, int arg)
-{
- if (arg)
- ixj_WriteDSPCommand(0x513F, j);
- else
- ixj_WriteDSPCommand(0x513E, j);
-}
-
-static void set_rec_depth(IXJ *j, int depth)
-{
- if (depth > 60)
- depth = 60;
- if (depth < 0)
- depth = 0;
- ixj_WriteDSPCommand(0x5180 + depth, j);
-}
-
-static void set_dtmf_prescale(IXJ *j, int volume)
-{
- ixj_WriteDSPCommand(0xCF07, j);
- ixj_WriteDSPCommand(volume, j);
-}
-
-static int get_dtmf_prescale(IXJ *j)
-{
- ixj_WriteDSPCommand(0xCF05, j);
- return j->ssr.high << 8 | j->ssr.low;
-}
-
-static void set_rec_volume(IXJ *j, int volume)
-{
- if(j->aec_level == AEC_AGC) {
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "IXJ: /dev/phone%d Setting AGC Threshold to 0x%4.4x\n", j->board, volume);
- ixj_WriteDSPCommand(0xCF96, j);
- ixj_WriteDSPCommand(volume, j);
- } else {
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "IXJ: /dev/phone %d Setting Record Volume to 0x%4.4x\n", j->board, volume);
- ixj_WriteDSPCommand(0xCF03, j);
- ixj_WriteDSPCommand(volume, j);
- }
-}
-
-static int set_rec_volume_linear(IXJ *j, int volume)
-{
- int newvolume, dsprecmax;
-
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Record Volume to 0x%4.4x\n", j->board, volume);
- if(volume > 100 || volume < 0) {
- return -1;
- }
-
- /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
- switch (j->cardtype) {
- case QTI_PHONEJACK:
- dsprecmax = 0x440;
- break;
- case QTI_LINEJACK:
- dsprecmax = 0x180;
- ixj_mixer(0x0203, j); /*Voice Left Volume unmute 6db */
- ixj_mixer(0x0303, j); /*Voice Right Volume unmute 6db */
- ixj_mixer(0x0C00, j); /*Mono1 unmute 12db */
- break;
- case QTI_PHONEJACK_LITE:
- dsprecmax = 0x4C0;
- break;
- case QTI_PHONEJACK_PCI:
- dsprecmax = 0x100;
- break;
- case QTI_PHONECARD:
- dsprecmax = 0x400;
- break;
- default:
- return -1;
- }
- newvolume = (dsprecmax * volume) / 100;
- set_rec_volume(j, newvolume);
- return 0;
-}
-
-static int get_rec_volume(IXJ *j)
-{
- if(j->aec_level == AEC_AGC) {
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Getting AGC Threshold\n");
- ixj_WriteDSPCommand(0xCF86, j);
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "AGC Threshold is 0x%2.2x%2.2x\n", j->ssr.high, j->ssr.low);
- return j->ssr.high << 8 | j->ssr.low;
- } else {
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Getting Record Volume\n");
- ixj_WriteDSPCommand(0xCF01, j);
- return j->ssr.high << 8 | j->ssr.low;
- }
-}
-
-static int get_rec_volume_linear(IXJ *j)
-{
- int volume, newvolume, dsprecmax;
-
- switch (j->cardtype) {
- case QTI_PHONEJACK:
- dsprecmax = 0x440;
- break;
- case QTI_LINEJACK:
- dsprecmax = 0x180;
- break;
- case QTI_PHONEJACK_LITE:
- dsprecmax = 0x4C0;
- break;
- case QTI_PHONEJACK_PCI:
- dsprecmax = 0x100;
- break;
- case QTI_PHONECARD:
- dsprecmax = 0x400;
- break;
- default:
- return -1;
- }
- volume = get_rec_volume(j);
- newvolume = (volume * 100) / dsprecmax;
- if(newvolume > 100)
- newvolume = 100;
- return newvolume;
-}
-
-static int get_rec_level(IXJ *j)
-{
- int retval;
-
- ixj_WriteDSPCommand(0xCF88, j);
-
- retval = j->ssr.high << 8 | j->ssr.low;
- retval = (retval * 256) / 240;
- return retval;
-}
-
-static void ixj_aec_start(IXJ *j, int level)
-{
- j->aec_level = level;
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "AGC set = 0x%2.2x\n", j->aec_level);
- if (!level) {
- aec_stop(j);
- } else {
- if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) {
- ixj_WriteDSPCommand(0xE022, j); /* Move AEC filter buffer */
-
- ixj_WriteDSPCommand(0x0300, j);
- }
- ixj_WriteDSPCommand(0xB001, j); /* AEC On */
-
- ixj_WriteDSPCommand(0xE013, j); /* Advanced AEC C1 */
-
- switch (level) {
- case AEC_LOW:
- ixj_WriteDSPCommand(0x0000, j); /* Advanced AEC C2 = off */
-
- ixj_WriteDSPCommand(0xE011, j);
- ixj_WriteDSPCommand(0xFFFF, j);
-
- ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */
- ixj_WriteDSPCommand(0x0000, j); /* to off */
-
- break;
-
- case AEC_MED:
- ixj_WriteDSPCommand(0x0600, j); /* Advanced AEC C2 = on medium */
-
- ixj_WriteDSPCommand(0xE011, j);
- ixj_WriteDSPCommand(0x0080, j);
-
- ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */
- ixj_WriteDSPCommand(0x0000, j); /* to off */
-
- break;
-
- case AEC_HIGH:
- ixj_WriteDSPCommand(0x0C00, j); /* Advanced AEC C2 = on high */
-
- ixj_WriteDSPCommand(0xE011, j);
- ixj_WriteDSPCommand(0x0080, j);
-
- ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */
- ixj_WriteDSPCommand(0x0000, j); /* to off */
-
- break;
-
- case AEC_AGC:
- /* First we have to put the AEC into advance auto mode so that AGC will not conflict with it */
- ixj_WriteDSPCommand(0x0002, j); /* Attenuation scaling factor of 2 */
-
- ixj_WriteDSPCommand(0xE011, j);
- ixj_WriteDSPCommand(0x0100, j); /* Higher Threshold Floor */
-
- ixj_WriteDSPCommand(0xE012, j); /* Set Train and Lock */
-
- if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD)
- ixj_WriteDSPCommand(0x0224, j);
- else
- ixj_WriteDSPCommand(0x1224, j);
-
- ixj_WriteDSPCommand(0xE014, j);
- ixj_WriteDSPCommand(0x0003, j); /* Lock threshold at 3dB */
-
- ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */
-
- /* Now we can set the AGC initial parameters and turn it on */
- ixj_WriteDSPCommand(0xCF90, j); /* Set AGC Minimum gain */
- ixj_WriteDSPCommand(0x0020, j); /* to 0.125 (-18dB) */
-
- ixj_WriteDSPCommand(0xCF91, j); /* Set AGC Maximum gain */
- ixj_WriteDSPCommand(0x1000, j); /* to 16 (24dB) */
-
- ixj_WriteDSPCommand(0xCF92, j); /* Set AGC start gain */
- ixj_WriteDSPCommand(0x0800, j); /* to 8 (+18dB) */
-
- ixj_WriteDSPCommand(0xCF93, j); /* Set AGC hold time */
- ixj_WriteDSPCommand(0x1F40, j); /* to 2 seconds (units are 250us) */
-
- ixj_WriteDSPCommand(0xCF94, j); /* Set AGC Attack Time Constant */
- ixj_WriteDSPCommand(0x0005, j); /* to 8ms */
-
- ixj_WriteDSPCommand(0xCF95, j); /* Set AGC Decay Time Constant */
- ixj_WriteDSPCommand(0x000D, j); /* to 4096ms */
-
- ixj_WriteDSPCommand(0xCF96, j); /* Set AGC Attack Threshold */
- ixj_WriteDSPCommand(0x1200, j); /* to 25% */
-
- ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */
- ixj_WriteDSPCommand(0x0001, j); /* to on */
-
- break;
-
- case AEC_AUTO:
- ixj_WriteDSPCommand(0x0002, j); /* Attenuation scaling factor of 2 */
-
- ixj_WriteDSPCommand(0xE011, j);
- ixj_WriteDSPCommand(0x0100, j); /* Higher Threshold Floor */
-
- ixj_WriteDSPCommand(0xE012, j); /* Set Train and Lock */
-
- if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD)
- ixj_WriteDSPCommand(0x0224, j);
- else
- ixj_WriteDSPCommand(0x1224, j);
-
- ixj_WriteDSPCommand(0xE014, j);
- ixj_WriteDSPCommand(0x0003, j); /* Lock threshold at 3dB */
-
- ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */
-
- break;
- }
- }
-}
-
-static void aec_stop(IXJ *j)
-{
- j->aec_level = AEC_OFF;
- if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) {
- ixj_WriteDSPCommand(0xE022, j); /* Move AEC filter buffer back */
-
- ixj_WriteDSPCommand(0x0700, j);
- }
- if (j->play_mode != -1 && j->rec_mode != -1)
- {
- ixj_WriteDSPCommand(0xB002, j); /* AEC Stop */
- }
-}
-
-static int set_play_codec(IXJ *j, int rate)
-{
- int retval = 0;
-
- j->play_codec = rate;
-
- switch (rate) {
- case G723_63:
- if (j->ver.low != 0x12 || ixj_convert_loaded) {
- j->play_frame_size = 12;
- j->play_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case G723_53:
- if (j->ver.low != 0x12 || ixj_convert_loaded) {
- j->play_frame_size = 10;
- j->play_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case TS85:
- if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
- j->play_frame_size = 16;
- j->play_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case TS48:
- if (j->ver.low != 0x12 || ixj_convert_loaded) {
- j->play_frame_size = 9;
- j->play_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case TS41:
- if (j->ver.low != 0x12 || ixj_convert_loaded) {
- j->play_frame_size = 8;
- j->play_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case G728:
- if (j->dsp.low != 0x20) {
- j->play_frame_size = 48;
- j->play_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case G729:
- if (j->dsp.low != 0x20) {
- if (!j->flags.g729_loaded) {
- retval = 1;
- break;
- }
- switch (j->baseframe.low) {
- case 0xA0:
- j->play_frame_size = 10;
- break;
- case 0x50:
- j->play_frame_size = 5;
- break;
- default:
- j->play_frame_size = 15;
- break;
- }
- j->play_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case G729B:
- if (j->dsp.low != 0x20) {
- if (!j->flags.g729_loaded) {
- retval = 1;
- break;
- }
- switch (j->baseframe.low) {
- case 0xA0:
- j->play_frame_size = 12;
- break;
- case 0x50:
- j->play_frame_size = 6;
- break;
- default:
- j->play_frame_size = 18;
- break;
- }
- j->play_mode = 0;
- } else {
- retval = 1;
- }
- break;
- case ULAW:
- switch (j->baseframe.low) {
- case 0xA0:
- j->play_frame_size = 80;
- break;
- case 0x50:
- j->play_frame_size = 40;
- break;
- default:
- j->play_frame_size = 120;
- break;
- }
- j->play_mode = 2;
- break;
- case ALAW:
- switch (j->baseframe.low) {
- case 0xA0:
- j->play_frame_size = 80;
- break;
- case 0x50:
- j->play_frame_size = 40;
- break;
- default:
- j->play_frame_size = 120;
- break;
- }
- j->play_mode = 2;
- break;
- case LINEAR16:
- switch (j->baseframe.low) {
- case 0xA0:
- j->play_frame_size = 160;
- break;
- case 0x50:
- j->play_frame_size = 80;
- break;
- default:
- j->play_frame_size = 240;
- break;
- }
- j->play_mode = 6;
- break;
- case LINEAR8:
- switch (j->baseframe.low) {
- case 0xA0:
- j->play_frame_size = 80;
- break;
- case 0x50:
- j->play_frame_size = 40;
- break;
- default:
- j->play_frame_size = 120;
- break;
- }
- j->play_mode = 4;
- break;
- case WSS:
- switch (j->baseframe.low) {
- case 0xA0:
- j->play_frame_size = 80;
- break;
- case 0x50:
- j->play_frame_size = 40;
- break;
- default:
- j->play_frame_size = 120;
- break;
- }
- j->play_mode = 5;
- break;
- default:
- kfree(j->write_buffer);
- j->play_frame_size = 0;
- j->play_mode = -1;
- j->write_buffer = NULL;
- j->write_buffer_size = 0;
- retval = 1;
- break;
- }
- return retval;
-}
-
-static int ixj_play_start(IXJ *j)
-{
- unsigned short cmd = 0x0000;
-
- if (j->write_buffer) {
- ixj_play_stop(j);
- }
-
- if(ixjdebug & 0x0002)
- printk("IXJ %d Starting Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
-
- j->flags.playing = 1;
- ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */
-
- j->flags.play_first_frame = 1;
- j->drybuffer = 0;
-
- if (!j->play_mode) {
- switch (j->play_codec) {
- case G723_63:
- cmd = 0x5231;
- break;
- case G723_53:
- cmd = 0x5232;
- break;
- case TS85:
- cmd = 0x5230; /* TrueSpeech 8.5 */
-
- break;
- case TS48:
- cmd = 0x5233; /* TrueSpeech 4.8 */
-
- break;
- case TS41:
- cmd = 0x5234; /* TrueSpeech 4.1 */
-
- break;
- case G728:
- cmd = 0x5235;
- break;
- case G729:
- case G729B:
- cmd = 0x5236;
- break;
- default:
- return 1;
- }
- if (ixj_WriteDSPCommand(cmd, j))
- return -1;
- }
- j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_ATOMIC);
- if (!j->write_buffer) {
- printk("Write buffer allocation for ixj board %d failed!\n", j->board);
- return -ENOMEM;
- }
-/* j->write_buffers_empty = 2; */
- j->write_buffers_empty = 1;
- j->write_buffer_size = j->play_frame_size * 2;
- j->write_buffer_end = j->write_buffer + j->play_frame_size * 2;
- j->write_buffer_rp = j->write_buffer_wp = j->write_buffer;
-
- if (ixj_WriteDSPCommand(0x5202, j)) /* Set Poll sync mode */
-
- return -1;
-
- switch (j->play_mode) {
- case 0:
- cmd = 0x2C03;
- break;
- case 2:
- if (j->ver.low == 0x12) {
- cmd = 0x2C23;
- } else {
- cmd = 0x2C21;
- }
- break;
- case 4:
- if (j->ver.low == 0x12) {
- cmd = 0x2C43;
- } else {
- cmd = 0x2C41;
- }
- break;
- case 5:
- if (j->ver.low == 0x12) {
- cmd = 0x2C53;
- } else {
- cmd = 0x2C51;
- }
- break;
- case 6:
- if (j->ver.low == 0x12) {
- cmd = 0x2C63;
- } else {
- cmd = 0x2C61;
- }
- break;
- }
- if (ixj_WriteDSPCommand(cmd, j))
- return -1;
-
- if (ixj_WriteDSPCommand(0x2000, j)) /* Playback C2 */
- return -1;
-
- if (ixj_WriteDSPCommand(0x2000 + j->play_frame_size, j)) /* Playback C3 */
- return -1;
-
- if (j->flags.recording) {
- ixj_aec_start(j, j->aec_level);
- }
-
- return 0;
-}
-
-static void ixj_play_stop(IXJ *j)
-{
- if (ixjdebug & 0x0002)
- printk("IXJ %d Stopping Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
-
- kfree(j->write_buffer);
- j->write_buffer = NULL;
- j->write_buffer_size = 0;
- if (j->play_mode > -1) {
- ixj_WriteDSPCommand(0x5221, j); /* Stop playback and flush buffers. 8022 reference page 9-40 */
-
- j->play_mode = -1;
- }
- j->flags.playing = 0;
-}
-
-static inline int get_play_level(IXJ *j)
-{
- int retval;
-
- ixj_WriteDSPCommand(0xCF8F, j); /* 8022 Reference page 9-38 */
- return j->ssr.high << 8 | j->ssr.low;
- retval = j->ssr.high << 8 | j->ssr.low;
- retval = (retval * 256) / 240;
- return retval;
-}
-
-static unsigned int ixj_poll(struct file *file_p, poll_table * wait)
-{
- unsigned int mask = 0;
-
- IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
-
- poll_wait(file_p, &(j->poll_q), wait);
- if (j->read_buffer_ready > 0)
- mask |= POLLIN | POLLRDNORM; /* readable */
- if (j->write_buffers_empty > 0)
- mask |= POLLOUT | POLLWRNORM; /* writable */
- if (j->ex.bytes)
- mask |= POLLPRI;
- return mask;
-}
-
-static int ixj_play_tone(IXJ *j, char tone)
-{
- if (!j->tone_state) {
- if(ixjdebug & 0x0002) {
- printk("IXJ %d starting tone %d at %ld\n", j->board, tone, jiffies);
- }
- if (j->dsp.low == 0x20) {
- idle(j);
- }
- j->tone_start_jif = jiffies;
-
- j->tone_state = 1;
- }
-
- j->tone_index = tone;
- if (ixj_WriteDSPCommand(0x6000 + j->tone_index, j))
- return -1;
-
- return 0;
-}
-
-static int ixj_set_tone_on(unsigned short arg, IXJ *j)
-{
- j->tone_on_time = arg;
-
- if (ixj_WriteDSPCommand(0x6E04, j)) /* Set Tone On Period */
-
- return -1;
-
- if (ixj_WriteDSPCommand(arg, j))
- return -1;
-
- return 0;
-}
-
-static int SCI_WaitHighSCI(IXJ *j)
-{
- int cnt;
-
- j->pld_scrr.byte = inb_p(j->XILINXbase);
- if (!j->pld_scrr.bits.sci) {
- for (cnt = 0; cnt < 10; cnt++) {
- udelay(32);
- j->pld_scrr.byte = inb_p(j->XILINXbase);
-
- if ((j->pld_scrr.bits.sci))
- return 1;
- }
- if (ixjdebug & 0x0001)
- printk(KERN_INFO "SCI Wait High failed %x\n", j->pld_scrr.byte);
- return 0;
- } else
- return 1;
-}
-
-static int SCI_WaitLowSCI(IXJ *j)
-{
- int cnt;
-
- j->pld_scrr.byte = inb_p(j->XILINXbase);
- if (j->pld_scrr.bits.sci) {
- for (cnt = 0; cnt < 10; cnt++) {
- udelay(32);
- j->pld_scrr.byte = inb_p(j->XILINXbase);
-
- if (!(j->pld_scrr.bits.sci))
- return 1;
- }
- if (ixjdebug & 0x0001)
- printk(KERN_INFO "SCI Wait Low failed %x\n", j->pld_scrr.byte);
- return 0;
- } else
- return 1;
-}
-
-static int SCI_Control(IXJ *j, int control)
-{
- switch (control) {
- case SCI_End:
- j->pld_scrw.bits.c0 = 0; /* Set PLD Serial control interface */
-
- j->pld_scrw.bits.c1 = 0; /* to no selection */
-
- break;
- case SCI_Enable_DAA:
- j->pld_scrw.bits.c0 = 1; /* Set PLD Serial control interface */
-
- j->pld_scrw.bits.c1 = 0; /* to write to DAA */
-
- break;
- case SCI_Enable_Mixer:
- j->pld_scrw.bits.c0 = 0; /* Set PLD Serial control interface */
-
- j->pld_scrw.bits.c1 = 1; /* to write to mixer */
-
- break;
- case SCI_Enable_EEPROM:
- j->pld_scrw.bits.c0 = 1; /* Set PLD Serial control interface */
-
- j->pld_scrw.bits.c1 = 1; /* to write to EEPROM */
-
- break;
- default:
- return 0;
- break;
- }
- outb_p(j->pld_scrw.byte, j->XILINXbase);
-
- switch (control) {
- case SCI_End:
- return 1;
- break;
- case SCI_Enable_DAA:
- case SCI_Enable_Mixer:
- case SCI_Enable_EEPROM:
- if (!SCI_WaitHighSCI(j))
- return 0;
- break;
- default:
- return 0;
- break;
- }
- return 1;
-}
-
-static int SCI_Prepare(IXJ *j)
-{
- if (!SCI_Control(j, SCI_End))
- return 0;
-
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- return 1;
-}
-
-static int ixj_get_mixer(long val, IXJ *j)
-{
- int reg = (val & 0x1F00) >> 8;
- return j->mix.vol[reg];
-}
-
-static int ixj_mixer(long val, IXJ *j)
-{
- BYTES bytes;
-
- bytes.high = (val & 0x1F00) >> 8;
- bytes.low = val & 0x00FF;
-
- /* save mixer value so we can get back later on */
- j->mix.vol[bytes.high] = bytes.low;
-
- outb_p(bytes.high & 0x1F, j->XILINXbase + 0x03); /* Load Mixer Address */
-
- outb_p(bytes.low, j->XILINXbase + 0x02); /* Load Mixer Data */
-
- SCI_Control(j, SCI_Enable_Mixer);
-
- SCI_Control(j, SCI_End);
-
- return 0;
-}
-
-static int daa_load(BYTES * p_bytes, IXJ *j)
-{
- outb_p(p_bytes->high, j->XILINXbase + 0x03);
- outb_p(p_bytes->low, j->XILINXbase + 0x02);
- if (!SCI_Control(j, SCI_Enable_DAA))
- return 0;
- else
- return 1;
-}
-
-static int ixj_daa_cr4(IXJ *j, char reg)
-{
- BYTES bytes;
-
- switch (j->daa_mode) {
- case SOP_PU_SLEEP:
- bytes.high = 0x14;
- break;
- case SOP_PU_RINGING:
- bytes.high = 0x54;
- break;
- case SOP_PU_CONVERSATION:
- bytes.high = 0x94;
- break;
- case SOP_PU_PULSEDIALING:
- bytes.high = 0xD4;
- break;
- }
-
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = reg;
-
- switch (j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGX) {
- case 0:
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 0;
- break;
- case 1:
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 2;
- break;
- case 2:
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 1;
- break;
- case 3:
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 3;
- break;
- }
-
- bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg;
-
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Prepare(j))
- return 0;
-
- return 1;
-}
-
-static char daa_int_read(IXJ *j)
-{
- BYTES bytes;
-
- if (!SCI_Prepare(j))
- return 0;
-
- bytes.high = 0x38;
- bytes.low = 0x00;
- outb_p(bytes.high, j->XILINXbase + 0x03);
- outb_p(bytes.low, j->XILINXbase + 0x02);
-
- if (!SCI_Control(j, SCI_Enable_DAA))
- return 0;
-
- bytes.high = inb_p(j->XILINXbase + 0x03);
- bytes.low = inb_p(j->XILINXbase + 0x02);
- if (bytes.low != ALISDAA_ID_BYTE) {
- if (ixjdebug & 0x0001)
- printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
- return 0;
- }
- if (!SCI_Control(j, SCI_Enable_DAA))
- return 0;
- if (!SCI_Control(j, SCI_End))
- return 0;
-
- bytes.high = inb_p(j->XILINXbase + 0x03);
- bytes.low = inb_p(j->XILINXbase + 0x02);
-
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg = bytes.high;
-
- return 1;
-}
-
-static char daa_CR_read(IXJ *j, int cr)
-{
- IXJ_WORD wdata;
- BYTES bytes;
-
- if (!SCI_Prepare(j))
- return 0;
-
- switch (j->daa_mode) {
- case SOP_PU_SLEEP:
- bytes.high = 0x30 + cr;
- break;
- case SOP_PU_RINGING:
- bytes.high = 0x70 + cr;
- break;
- case SOP_PU_CONVERSATION:
- bytes.high = 0xB0 + cr;
- break;
- case SOP_PU_PULSEDIALING:
- default:
- bytes.high = 0xF0 + cr;
- break;
- }
-
- bytes.low = 0x00;
-
- outb_p(bytes.high, j->XILINXbase + 0x03);
- outb_p(bytes.low, j->XILINXbase + 0x02);
-
- if (!SCI_Control(j, SCI_Enable_DAA))
- return 0;
-
- bytes.high = inb_p(j->XILINXbase + 0x03);
- bytes.low = inb_p(j->XILINXbase + 0x02);
- if (bytes.low != ALISDAA_ID_BYTE) {
- if (ixjdebug & 0x0001)
- printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
- return 0;
- }
- if (!SCI_Control(j, SCI_Enable_DAA))
- return 0;
- if (!SCI_Control(j, SCI_End))
- return 0;
-
- wdata.word = inw_p(j->XILINXbase + 0x02);
-
- switch(cr){
- case 5:
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = wdata.bytes.high;
- break;
- case 4:
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = wdata.bytes.high;
- break;
- case 3:
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = wdata.bytes.high;
- break;
- case 2:
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = wdata.bytes.high;
- break;
- case 1:
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = wdata.bytes.high;
- break;
- case 0:
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = wdata.bytes.high;
- break;
- default:
- return 0;
- }
- return 1;
-}
-
-static int ixj_daa_cid_reset(IXJ *j)
-{
- int i;
- BYTES bytes;
-
- if (ixjdebug & 0x0002)
- printk("DAA Clearing CID ram\n");
-
- if (!SCI_Prepare(j))
- return 0;
-
- bytes.high = 0x58;
- bytes.low = 0x00;
- outb_p(bytes.high, j->XILINXbase + 0x03);
- outb_p(bytes.low, j->XILINXbase + 0x02);
-
- if (!SCI_Control(j, SCI_Enable_DAA))
- return 0;
-
- if (!SCI_WaitHighSCI(j))
- return 0;
-
- for (i = 0; i < ALISDAA_CALLERID_SIZE - 1; i += 2) {
- bytes.high = bytes.low = 0x00;
- outb_p(bytes.high, j->XILINXbase + 0x03);
-
- if (i < ALISDAA_CALLERID_SIZE - 1)
- outb_p(bytes.low, j->XILINXbase + 0x02);
-
- if (!SCI_Control(j, SCI_Enable_DAA))
- return 0;
-
- if (!SCI_WaitHighSCI(j))
- return 0;
-
- }
-
- if (!SCI_Control(j, SCI_End))
- return 0;
-
- if (ixjdebug & 0x0002)
- printk("DAA CID ram cleared\n");
-
- return 1;
-}
-
-static int ixj_daa_cid_read(IXJ *j)
-{
- int i;
- BYTES bytes;
- char CID[ALISDAA_CALLERID_SIZE];
- bool mContinue;
- char *pIn, *pOut;
-
- if (!SCI_Prepare(j))
- return 0;
-
- bytes.high = 0x78;
- bytes.low = 0x00;
- outb_p(bytes.high, j->XILINXbase + 0x03);
- outb_p(bytes.low, j->XILINXbase + 0x02);
-
- if (!SCI_Control(j, SCI_Enable_DAA))
- return 0;
-
- if (!SCI_WaitHighSCI(j))
- return 0;
-
- bytes.high = inb_p(j->XILINXbase + 0x03);
- bytes.low = inb_p(j->XILINXbase + 0x02);
- if (bytes.low != ALISDAA_ID_BYTE) {
- if (ixjdebug & 0x0001)
- printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
- return 0;
- }
- for (i = 0; i < ALISDAA_CALLERID_SIZE; i += 2) {
- bytes.high = bytes.low = 0x00;
- outb_p(bytes.high, j->XILINXbase + 0x03);
- outb_p(bytes.low, j->XILINXbase + 0x02);
-
- if (!SCI_Control(j, SCI_Enable_DAA))
- return 0;
-
- if (!SCI_WaitHighSCI(j))
- return 0;
-
- CID[i + 0] = inb_p(j->XILINXbase + 0x03);
- CID[i + 1] = inb_p(j->XILINXbase + 0x02);
- }
-
- if (!SCI_Control(j, SCI_End))
- return 0;
-
- pIn = CID;
- pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID;
- mContinue = true;
- while (mContinue) {
- if ((pIn[1] & 0x03) == 0x01) {
- pOut[0] = pIn[0];
- }
- if ((pIn[2] & 0x0c) == 0x04) {
- pOut[1] = ((pIn[2] & 0x03) << 6) | ((pIn[1] & 0xfc) >> 2);
- }
- if ((pIn[3] & 0x30) == 0x10) {
- pOut[2] = ((pIn[3] & 0x0f) << 4) | ((pIn[2] & 0xf0) >> 4);
- }
- if ((pIn[4] & 0xc0) == 0x40) {
- pOut[3] = ((pIn[4] & 0x3f) << 2) | ((pIn[3] & 0xc0) >> 6);
- } else {
- mContinue = false;
- }
- pIn += 5, pOut += 4;
- }
- memset(&j->cid, 0, sizeof(PHONE_CID));
- pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID;
- pOut += 4;
- strncpy(j->cid.month, pOut, 2);
- pOut += 2;
- strncpy(j->cid.day, pOut, 2);
- pOut += 2;
- strncpy(j->cid.hour, pOut, 2);
- pOut += 2;
- strncpy(j->cid.min, pOut, 2);
- pOut += 3;
- j->cid.numlen = *pOut;
- pOut += 1;
- strncpy(j->cid.number, pOut, j->cid.numlen);
- pOut += j->cid.numlen + 1;
- j->cid.namelen = *pOut;
- pOut += 1;
- strncpy(j->cid.name, pOut, j->cid.namelen);
-
- ixj_daa_cid_reset(j);
- return 1;
-}
-
-static char daa_get_version(IXJ *j)
-{
- BYTES bytes;
-
- if (!SCI_Prepare(j))
- return 0;
-
- bytes.high = 0x35;
- bytes.low = 0x00;
- outb_p(bytes.high, j->XILINXbase + 0x03);
- outb_p(bytes.low, j->XILINXbase + 0x02);
-
- if (!SCI_Control(j, SCI_Enable_DAA))
- return 0;
-
- bytes.high = inb_p(j->XILINXbase + 0x03);
- bytes.low = inb_p(j->XILINXbase + 0x02);
- if (bytes.low != ALISDAA_ID_BYTE) {
- if (ixjdebug & 0x0001)
- printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
- return 0;
- }
- if (!SCI_Control(j, SCI_Enable_DAA))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
-
- bytes.high = inb_p(j->XILINXbase + 0x03);
- bytes.low = inb_p(j->XILINXbase + 0x02);
- if (ixjdebug & 0x0002)
- printk("DAA CR5 Byte high = 0x%x low = 0x%x\n", bytes.high, bytes.low);
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = bytes.high;
- return bytes.high;
-}
-
-static int daa_set_mode(IXJ *j, int mode)
-{
- /* NOTE:
- The DAA *MUST* be in the conversation mode if the
- PSTN line is to be seized (PSTN line off-hook).
- Taking the PSTN line off-hook while the DAA is in
- a mode other than conversation mode will cause a
- hardware failure of the ALIS-A part.
-
- NOTE:
- The DAA can only go to SLEEP, RINGING or PULSEDIALING modes
- if the PSTN line is on-hook. Failure to have the PSTN line
- in the on-hook state WILL CAUSE A HARDWARE FAILURE OF THE
- ALIS-A part.
- */
-
- BYTES bytes;
-
- j->flags.pstn_rmr = 0;
-
- if (!SCI_Prepare(j))
- return 0;
-
- switch (mode) {
- case SOP_PU_RESET:
- j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
-
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- j->pld_slicw.bits.rly2 = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- bytes.high = 0x10;
- bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
- daa_load(&bytes, j);
- if (!SCI_Prepare(j))
- return 0;
-
- j->daa_mode = SOP_PU_SLEEP;
- break;
- case SOP_PU_SLEEP:
- if(j->daa_mode == SOP_PU_SLEEP)
- {
- break;
- }
- if (ixjdebug & 0x0008)
- printk(KERN_INFO "phone DAA: SOP_PU_SLEEP at %ld\n", jiffies);
-/* if(j->daa_mode == SOP_PU_CONVERSATION) */
- {
- j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
-
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- j->pld_slicw.bits.rly2 = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- bytes.high = 0x10;
- bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
- daa_load(&bytes, j);
- if (!SCI_Prepare(j))
- return 0;
- }
- j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
-
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- j->pld_slicw.bits.rly2 = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- bytes.high = 0x10;
- bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
- daa_load(&bytes, j);
- if (!SCI_Prepare(j))
- return 0;
-
- j->daa_mode = SOP_PU_SLEEP;
- j->flags.pstn_ringing = 0;
- j->ex.bits.pstn_ring = 0;
- j->pstn_sleeptil = jiffies + (hertz / 4);
- wake_up_interruptible(&j->read_q); /* Wake any blocked readers */
- wake_up_interruptible(&j->write_q); /* Wake any blocked writers */
- wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */
- break;
- case SOP_PU_RINGING:
- if (ixjdebug & 0x0008)
- printk(KERN_INFO "phone DAA: SOP_PU_RINGING at %ld\n", jiffies);
- j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
-
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- j->pld_slicw.bits.rly2 = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- bytes.high = 0x50;
- bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
- daa_load(&bytes, j);
- if (!SCI_Prepare(j))
- return 0;
- j->daa_mode = SOP_PU_RINGING;
- break;
- case SOP_PU_CONVERSATION:
- if (ixjdebug & 0x0008)
- printk(KERN_INFO "phone DAA: SOP_PU_CONVERSATION at %ld\n", jiffies);
- bytes.high = 0x90;
- bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
- daa_load(&bytes, j);
- if (!SCI_Prepare(j))
- return 0;
- j->pld_slicw.bits.rly2 = 1;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- j->pld_scrw.bits.daafsyncen = 1; /* Turn on DAA Frame Sync */
-
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- j->daa_mode = SOP_PU_CONVERSATION;
- j->flags.pstn_ringing = 0;
- j->ex.bits.pstn_ring = 0;
- j->pstn_sleeptil = jiffies;
- j->pstn_ring_start = j->pstn_ring_stop = j->pstn_ring_int = 0;
- break;
- case SOP_PU_PULSEDIALING:
- if (ixjdebug & 0x0008)
- printk(KERN_INFO "phone DAA: SOP_PU_PULSEDIALING at %ld\n", jiffies);
- j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
-
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- j->pld_slicw.bits.rly2 = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- bytes.high = 0xD0;
- bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
- daa_load(&bytes, j);
- if (!SCI_Prepare(j))
- return 0;
- j->daa_mode = SOP_PU_PULSEDIALING;
- break;
- default:
- break;
- }
- return 1;
-}
-
-static int ixj_daa_write(IXJ *j)
-{
- BYTES bytes;
-
- j->flags.pstncheck = 1;
-
- daa_set_mode(j, SOP_PU_SLEEP);
-
- if (!SCI_Prepare(j))
- return 0;
-
- outb_p(j->pld_scrw.byte, j->XILINXbase);
-
- bytes.high = 0x14;
- bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg;
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg;
- bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg;
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg;
- bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Prepare(j))
- return 0;
-
- bytes.high = 0x1F;
- bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg;
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.XOP_xr6_W.reg;
- bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg;
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg;
- bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg;
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg;
- bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg;
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.XOP_xr0_W.reg;
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Prepare(j))
- return 0;
-
- bytes.high = 0x00;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x01;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x02;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x03;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x04;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x05;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x06;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x07;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x08;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x09;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x0A;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x0B;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x0C;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x0D;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x0E;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- if (!SCI_Control(j, SCI_End))
- return 0;
- if (!SCI_WaitLowSCI(j))
- return 0;
-
- bytes.high = 0x0F;
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2];
- bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1];
- if (!daa_load(&bytes, j))
- return 0;
-
- bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0];
- bytes.low = 0x00;
- if (!daa_load(&bytes, j))
- return 0;
-
- udelay(32);
- j->pld_scrr.byte = inb_p(j->XILINXbase);
- if (!SCI_Control(j, SCI_End))
- return 0;
-
- outb_p(j->pld_scrw.byte, j->XILINXbase);
-
- if (ixjdebug & 0x0002)
- printk("DAA Coefficients Loaded\n");
-
- j->flags.pstncheck = 0;
- return 1;
-}
-
-static int ixj_set_tone_off(unsigned short arg, IXJ *j)
-{
- j->tone_off_time = arg;
- if (ixj_WriteDSPCommand(0x6E05, j)) /* Set Tone Off Period */
-
- return -1;
- if (ixj_WriteDSPCommand(arg, j))
- return -1;
- return 0;
-}
-
-static int ixj_get_tone_on(IXJ *j)
-{
- if (ixj_WriteDSPCommand(0x6E06, j)) /* Get Tone On Period */
-
- return -1;
- return 0;
-}
-
-static int ixj_get_tone_off(IXJ *j)
-{
- if (ixj_WriteDSPCommand(0x6E07, j)) /* Get Tone Off Period */
-
- return -1;
- return 0;
-}
-
-static void ixj_busytone(IXJ *j)
-{
- j->flags.ringback = 0;
- j->flags.dialtone = 0;
- j->flags.busytone = 1;
- ixj_set_tone_on(0x07D0, j);
- ixj_set_tone_off(0x07D0, j);
- ixj_play_tone(j, 27);
-}
-
-static void ixj_dialtone(IXJ *j)
-{
- j->flags.ringback = 0;
- j->flags.dialtone = 1;
- j->flags.busytone = 0;
- if (j->dsp.low == 0x20) {
- return;
- } else {
- ixj_set_tone_on(0xFFFF, j);
- ixj_set_tone_off(0x0000, j);
- ixj_play_tone(j, 25);
- }
-}
-
-static void ixj_cpt_stop(IXJ *j)
-{
- if(j->tone_state || j->tone_cadence_state)
- {
- j->flags.dialtone = 0;
- j->flags.busytone = 0;
- j->flags.ringback = 0;
- ixj_set_tone_on(0x0001, j);
- ixj_set_tone_off(0x0000, j);
- ixj_play_tone(j, 0);
- j->tone_state = j->tone_cadence_state = 0;
- if (j->cadence_t) {
- kfree(j->cadence_t->ce);
- kfree(j->cadence_t);
- j->cadence_t = NULL;
- }
- }
- if (j->play_mode == -1 && j->rec_mode == -1)
- idle(j);
- if (j->play_mode != -1 && j->dsp.low == 0x20)
- ixj_play_start(j);
- if (j->rec_mode != -1 && j->dsp.low == 0x20)
- ixj_record_start(j);
-}
-
-static void ixj_ringback(IXJ *j)
-{
- j->flags.busytone = 0;
- j->flags.dialtone = 0;
- j->flags.ringback = 1;
- ixj_set_tone_on(0x0FA0, j);
- ixj_set_tone_off(0x2EE0, j);
- ixj_play_tone(j, 26);
-}
-
-static void ixj_testram(IXJ *j)
-{
- ixj_WriteDSPCommand(0x3001, j); /* Test External SRAM */
-}
-
-static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp)
-{
- ixj_cadence *lcp;
- IXJ_CADENCE_ELEMENT __user *cep;
- IXJ_CADENCE_ELEMENT *lcep;
- IXJ_TONE ti;
- int err;
-
- lcp = kmalloc(sizeof(ixj_cadence), GFP_KERNEL);
- if (lcp == NULL)
- return -ENOMEM;
-
- err = -EFAULT;
- if (copy_from_user(&lcp->elements_used,
- &cp->elements_used, sizeof(int)))
- goto out;
- if (copy_from_user(&lcp->termination,
- &cp->termination, sizeof(IXJ_CADENCE_TERM)))
- goto out;
- if (get_user(cep, &cp->ce))
- goto out;
-
- err = -EINVAL;
- if ((unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE_ELEMENT))
- goto out;
-
- err = -ENOMEM;
- lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL);
- if (!lcep)
- goto out;
-
- err = -EFAULT;
- if (copy_from_user(lcep, cep, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used))
- goto out1;
-
- if (j->cadence_t) {
- kfree(j->cadence_t->ce);
- kfree(j->cadence_t);
- }
- lcp->ce = (void *) lcep;
- j->cadence_t = lcp;
- j->tone_cadence_state = 0;
- ixj_set_tone_on(lcp->ce[0].tone_on_time, j);
- ixj_set_tone_off(lcp->ce[0].tone_off_time, j);
- if (j->cadence_t->ce[j->tone_cadence_state].freq0) {
- ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
- ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
- ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
- ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
- ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
- ixj_init_tone(j, &ti);
- }
- ixj_play_tone(j, lcp->ce[0].index);
- return 1;
-out1:
- kfree(lcep);
-out:
- kfree(lcp);
- return err;
-}
-
-static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp)
-{
- IXJ_FILTER_CADENCE *lcp;
- lcp = memdup_user(cp, sizeof(IXJ_FILTER_CADENCE));
- if (IS_ERR(lcp)) {
- if(ixjdebug & 0x0001) {
- printk(KERN_INFO "Could not allocate memory for cadence or could not copy cadence to kernel\n");
- }
- return PTR_ERR(lcp);
- }
- if (lcp->filter > 5) {
- if(ixjdebug & 0x0001) {
- printk(KERN_INFO "Cadence out of range\n");
- }
- kfree(lcp);
- return -1;
- }
- j->cadence_f[lcp->filter].state = 0;
- j->cadence_f[lcp->filter].enable = lcp->enable;
- j->filter_en[lcp->filter] = j->cadence_f[lcp->filter].en_filter = lcp->en_filter;
- j->cadence_f[lcp->filter].on1 = lcp->on1;
- j->cadence_f[lcp->filter].on1min = 0;
- j->cadence_f[lcp->filter].on1max = 0;
- j->cadence_f[lcp->filter].off1 = lcp->off1;
- j->cadence_f[lcp->filter].off1min = 0;
- j->cadence_f[lcp->filter].off1max = 0;
- j->cadence_f[lcp->filter].on2 = lcp->on2;
- j->cadence_f[lcp->filter].on2min = 0;
- j->cadence_f[lcp->filter].on2max = 0;
- j->cadence_f[lcp->filter].off2 = lcp->off2;
- j->cadence_f[lcp->filter].off2min = 0;
- j->cadence_f[lcp->filter].off2max = 0;
- j->cadence_f[lcp->filter].on3 = lcp->on3;
- j->cadence_f[lcp->filter].on3min = 0;
- j->cadence_f[lcp->filter].on3max = 0;
- j->cadence_f[lcp->filter].off3 = lcp->off3;
- j->cadence_f[lcp->filter].off3min = 0;
- j->cadence_f[lcp->filter].off3max = 0;
- if(ixjdebug & 0x0002) {
- printk(KERN_INFO "Cadence %d loaded\n", lcp->filter);
- }
- kfree(lcp);
- return 0;
-}
-
-static void add_caps(IXJ *j)
-{
- j->caps = 0;
- j->caplist[j->caps].cap = PHONE_VENDOR_QUICKNET;
- strcpy(j->caplist[j->caps].desc, "Quicknet Technologies, Inc. (www.quicknet.net)");
- j->caplist[j->caps].captype = vendor;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
- j->caplist[j->caps].captype = device;
- switch (j->cardtype) {
- case QTI_PHONEJACK:
- strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK");
- break;
- case QTI_LINEJACK:
- strcpy(j->caplist[j->caps].desc, "Quicknet Internet LineJACK");
- break;
- case QTI_PHONEJACK_LITE:
- strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK Lite");
- break;
- case QTI_PHONEJACK_PCI:
- strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK PCI");
- break;
- case QTI_PHONECARD:
- strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneCARD");
- break;
- }
- j->caplist[j->caps].cap = j->cardtype;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
- strcpy(j->caplist[j->caps].desc, "POTS");
- j->caplist[j->caps].captype = port;
- j->caplist[j->caps].cap = pots;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
-
- /* add devices that can do speaker/mic */
- switch (j->cardtype) {
- case QTI_PHONEJACK:
- case QTI_LINEJACK:
- case QTI_PHONEJACK_PCI:
- case QTI_PHONECARD:
- strcpy(j->caplist[j->caps].desc, "SPEAKER");
- j->caplist[j->caps].captype = port;
- j->caplist[j->caps].cap = speaker;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
- default:
- break;
- }
-
- /* add devices that can do handset */
- switch (j->cardtype) {
- case QTI_PHONEJACK:
- strcpy(j->caplist[j->caps].desc, "HANDSET");
- j->caplist[j->caps].captype = port;
- j->caplist[j->caps].cap = handset;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
- break;
- default:
- break;
- }
-
- /* add devices that can do PSTN */
- switch (j->cardtype) {
- case QTI_LINEJACK:
- strcpy(j->caplist[j->caps].desc, "PSTN");
- j->caplist[j->caps].captype = port;
- j->caplist[j->caps].cap = pstn;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
- break;
- default:
- break;
- }
-
- /* add codecs - all cards can do uLaw, linear 8/16, and Windows sound system */
- strcpy(j->caplist[j->caps].desc, "ULAW");
- j->caplist[j->caps].captype = codec;
- j->caplist[j->caps].cap = ULAW;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
-
- strcpy(j->caplist[j->caps].desc, "LINEAR 16 bit");
- j->caplist[j->caps].captype = codec;
- j->caplist[j->caps].cap = LINEAR16;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
-
- strcpy(j->caplist[j->caps].desc, "LINEAR 8 bit");
- j->caplist[j->caps].captype = codec;
- j->caplist[j->caps].cap = LINEAR8;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
-
- strcpy(j->caplist[j->caps].desc, "Windows Sound System");
- j->caplist[j->caps].captype = codec;
- j->caplist[j->caps].cap = WSS;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
-
- /* software ALAW codec, made from ULAW */
- strcpy(j->caplist[j->caps].desc, "ALAW");
- j->caplist[j->caps].captype = codec;
- j->caplist[j->caps].cap = ALAW;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
-
- /* version 12 of the 8020 does the following codecs in a broken way */
- if (j->dsp.low != 0x20 || j->ver.low != 0x12) {
- strcpy(j->caplist[j->caps].desc, "G.723.1 6.3kbps");
- j->caplist[j->caps].captype = codec;
- j->caplist[j->caps].cap = G723_63;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
-
- strcpy(j->caplist[j->caps].desc, "G.723.1 5.3kbps");
- j->caplist[j->caps].captype = codec;
- j->caplist[j->caps].cap = G723_53;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
-
- strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8kbps");
- j->caplist[j->caps].captype = codec;
- j->caplist[j->caps].cap = TS48;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
-
- strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1kbps");
- j->caplist[j->caps].captype = codec;
- j->caplist[j->caps].cap = TS41;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
- }
-
- /* 8020 chips can do TS8.5 native, and 8021/8022 can load it */
- if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
- strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5kbps");
- j->caplist[j->caps].captype = codec;
- j->caplist[j->caps].cap = TS85;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
- }
-
- /* 8021 chips can do G728 */
- if (j->dsp.low == 0x21) {
- strcpy(j->caplist[j->caps].desc, "G.728 16kbps");
- j->caplist[j->caps].captype = codec;
- j->caplist[j->caps].cap = G728;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
- }
-
- /* 8021/8022 chips can do G729 if loaded */
- if (j->dsp.low != 0x20 && j->flags.g729_loaded) {
- strcpy(j->caplist[j->caps].desc, "G.729A 8kbps");
- j->caplist[j->caps].captype = codec;
- j->caplist[j->caps].cap = G729;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
- }
- if (j->dsp.low != 0x20 && j->flags.g729_loaded) {
- strcpy(j->caplist[j->caps].desc, "G.729B 8kbps");
- j->caplist[j->caps].captype = codec;
- j->caplist[j->caps].cap = G729B;
- j->caplist[j->caps].handle = j->caps;
- j->caps++;
- }
-}
-
-static int capabilities_check(IXJ *j, struct phone_capability *pcreq)
-{
- int cnt;
- int retval = 0;
- for (cnt = 0; cnt < j->caps; cnt++) {
- if (pcreq->captype == j->caplist[cnt].captype
- && pcreq->cap == j->caplist[cnt].cap) {
- retval = 1;
- break;
- }
- }
- return retval;
-}
-
-static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg)
-{
- IXJ_TONE ti;
- IXJ_FILTER jf;
- IXJ_FILTER_RAW jfr;
- void __user *argp = (void __user *)arg;
- struct inode *inode = file_p->f_path.dentry->d_inode;
- unsigned int minor = iminor(inode);
- unsigned int raise, mant;
- int board = NUM(inode);
-
- IXJ *j = get_ixj(NUM(inode));
-
- int retval = 0;
-
- /*
- * Set up locks to ensure that only one process is talking to the DSP at a time.
- * This is necessary to keep the DSP from locking up.
- */
- while(test_and_set_bit(board, (void *)&j->busyflags) != 0)
- schedule_timeout_interruptible(1);
- if (ixjdebug & 0x0040)
- printk("phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
- if (minor >= IXJMAX) {
- clear_bit(board, &j->busyflags);
- return -ENODEV;
- }
- /*
- * Check ioctls only root can use.
- */
- if (!capable(CAP_SYS_ADMIN)) {
- switch (cmd) {
- case IXJCTL_TESTRAM:
- case IXJCTL_HZ:
- retval = -EPERM;
- }
- }
- switch (cmd) {
- case IXJCTL_TESTRAM:
- ixj_testram(j);
- retval = (j->ssr.high << 8) + j->ssr.low;
- break;
- case IXJCTL_CARDTYPE:
- retval = j->cardtype;
- break;
- case IXJCTL_SERIAL:
- retval = j->serial;
- break;
- case IXJCTL_VERSION:
- {
- char arg_str[100];
- snprintf(arg_str, sizeof(arg_str),
- "\nDriver version %i.%i.%i", IXJ_VER_MAJOR,
- IXJ_VER_MINOR, IXJ_BLD_VER);
- if (copy_to_user(argp, arg_str, strlen(arg_str)))
- retval = -EFAULT;
- }
- break;
- case PHONE_RING_CADENCE:
- j->ring_cadence = arg;
- break;
- case IXJCTL_CIDCW:
- if(arg) {
- if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) {
- retval = -EFAULT;
- break;
- }
- } else {
- memset(&j->cid_send, 0, sizeof(PHONE_CID));
- }
- ixj_write_cidcw(j);
- break;
- /* Binary compatbility */
- case OLD_PHONE_RING_START:
- arg = 0;
- /* Fall through */
- case PHONE_RING_START:
- if(arg) {
- if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) {
- retval = -EFAULT;
- break;
- }
- ixj_write_cid(j);
- } else {
- memset(&j->cid_send, 0, sizeof(PHONE_CID));
- }
- ixj_ring_start(j);
- break;
- case PHONE_RING_STOP:
- j->flags.cringing = 0;
- if(j->cadence_f[5].enable) {
- j->cadence_f[5].state = 0;
- }
- ixj_ring_off(j);
- break;
- case PHONE_RING:
- retval = ixj_ring(j);
- break;
- case PHONE_EXCEPTION:
- retval = j->ex.bytes;
- if(j->ex.bits.flash) {
- j->flash_end = 0;
- j->ex.bits.flash = 0;
- }
- j->ex.bits.pstn_ring = 0;
- j->ex.bits.caller_id = 0;
- j->ex.bits.pstn_wink = 0;
- j->ex.bits.f0 = 0;
- j->ex.bits.f1 = 0;
- j->ex.bits.f2 = 0;
- j->ex.bits.f3 = 0;
- j->ex.bits.fc0 = 0;
- j->ex.bits.fc1 = 0;
- j->ex.bits.fc2 = 0;
- j->ex.bits.fc3 = 0;
- j->ex.bits.reserved = 0;
- break;
- case PHONE_HOOKSTATE:
- j->ex.bits.hookstate = 0;
- retval = j->hookstate; //j->r_hook;
- break;
- case IXJCTL_SET_LED:
- LED_SetState(arg, j);
- break;
- case PHONE_FRAME:
- retval = set_base_frame(j, arg);
- break;
- case PHONE_REC_CODEC:
- retval = set_rec_codec(j, arg);
- break;
- case PHONE_VAD:
- ixj_vad(j, arg);
- break;
- case PHONE_REC_START:
- ixj_record_start(j);
- break;
- case PHONE_REC_STOP:
- ixj_record_stop(j);
- break;
- case PHONE_REC_DEPTH:
- set_rec_depth(j, arg);
- break;
- case PHONE_REC_VOLUME:
- if(arg == -1) {
- retval = get_rec_volume(j);
- }
- else {
- set_rec_volume(j, arg);
- retval = arg;
- }
- break;
- case PHONE_REC_VOLUME_LINEAR:
- if(arg == -1) {
- retval = get_rec_volume_linear(j);
- }
- else {
- set_rec_volume_linear(j, arg);
- retval = arg;
- }
- break;
- case IXJCTL_DTMF_PRESCALE:
- if(arg == -1) {
- retval = get_dtmf_prescale(j);
- }
- else {
- set_dtmf_prescale(j, arg);
- retval = arg;
- }
- break;
- case PHONE_REC_LEVEL:
- retval = get_rec_level(j);
- break;
- case IXJCTL_SC_RXG:
- retval = ixj_siadc(j, arg);
- break;
- case IXJCTL_SC_TXG:
- retval = ixj_sidac(j, arg);
- break;
- case IXJCTL_AEC_START:
- ixj_aec_start(j, arg);
- break;
- case IXJCTL_AEC_STOP:
- aec_stop(j);
- break;
- case IXJCTL_AEC_GET_LEVEL:
- retval = j->aec_level;
- break;
- case PHONE_PLAY_CODEC:
- retval = set_play_codec(j, arg);
- break;
- case PHONE_PLAY_START:
- retval = ixj_play_start(j);
- break;
- case PHONE_PLAY_STOP:
- ixj_play_stop(j);
- break;
- case PHONE_PLAY_DEPTH:
- set_play_depth(j, arg);
- break;
- case PHONE_PLAY_VOLUME:
- if(arg == -1) {
- retval = get_play_volume(j);
- }
- else {
- set_play_volume(j, arg);
- retval = arg;
- }
- break;
- case PHONE_PLAY_VOLUME_LINEAR:
- if(arg == -1) {
- retval = get_play_volume_linear(j);
- }
- else {
- set_play_volume_linear(j, arg);
- retval = arg;
- }
- break;
- case PHONE_PLAY_LEVEL:
- retval = get_play_level(j);
- break;
- case IXJCTL_DSP_TYPE:
- retval = (j->dsp.high << 8) + j->dsp.low;
- break;
- case IXJCTL_DSP_VERSION:
- retval = (j->ver.high << 8) + j->ver.low;
- break;
- case IXJCTL_HZ:
- hertz = arg;
- break;
- case IXJCTL_RATE:
- if (arg > hertz)
- retval = -1;
- else
- samplerate = arg;
- break;
- case IXJCTL_DRYBUFFER_READ:
- put_user(j->drybuffer, (unsigned long __user *) argp);
- break;
- case IXJCTL_DRYBUFFER_CLEAR:
- j->drybuffer = 0;
- break;
- case IXJCTL_FRAMES_READ:
- put_user(j->framesread, (unsigned long __user *) argp);
- break;
- case IXJCTL_FRAMES_WRITTEN:
- put_user(j->frameswritten, (unsigned long __user *) argp);
- break;
- case IXJCTL_READ_WAIT:
- put_user(j->read_wait, (unsigned long __user *) argp);
- break;
- case IXJCTL_WRITE_WAIT:
- put_user(j->write_wait, (unsigned long __user *) argp);
- break;
- case PHONE_MAXRINGS:
- j->maxrings = arg;
- break;
- case PHONE_SET_TONE_ON_TIME:
- ixj_set_tone_on(arg, j);
- break;
- case PHONE_SET_TONE_OFF_TIME:
- ixj_set_tone_off(arg, j);
- break;
- case PHONE_GET_TONE_ON_TIME:
- if (ixj_get_tone_on(j)) {
- retval = -1;
- } else {
- retval = (j->ssr.high << 8) + j->ssr.low;
- }
- break;
- case PHONE_GET_TONE_OFF_TIME:
- if (ixj_get_tone_off(j)) {
- retval = -1;
- } else {
- retval = (j->ssr.high << 8) + j->ssr.low;
- }
- break;
- case PHONE_PLAY_TONE:
- if (!j->tone_state)
- retval = ixj_play_tone(j, arg);
- else
- retval = -1;
- break;
- case PHONE_GET_TONE_STATE:
- retval = j->tone_state;
- break;
- case PHONE_DTMF_READY:
- retval = j->ex.bits.dtmf_ready;
- break;
- case PHONE_GET_DTMF:
- if (ixj_hookstate(j)) {
- if (j->dtmf_rp != j->dtmf_wp) {
- retval = j->dtmfbuffer[j->dtmf_rp];
- j->dtmf_rp++;
- if (j->dtmf_rp == 79)
- j->dtmf_rp = 0;
- if (j->dtmf_rp == j->dtmf_wp) {
- j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0;
- }
- }
- }
- break;
- case PHONE_GET_DTMF_ASCII:
- if (ixj_hookstate(j)) {
- if (j->dtmf_rp != j->dtmf_wp) {
- switch (j->dtmfbuffer[j->dtmf_rp]) {
- case 10:
- retval = 42; /* '*'; */
-
- break;
- case 11:
- retval = 48; /*'0'; */
-
- break;
- case 12:
- retval = 35; /*'#'; */
-
- break;
- case 28:
- retval = 65; /*'A'; */
-
- break;
- case 29:
- retval = 66; /*'B'; */
-
- break;
- case 30:
- retval = 67; /*'C'; */
-
- break;
- case 31:
- retval = 68; /*'D'; */
-
- break;
- default:
- retval = 48 + j->dtmfbuffer[j->dtmf_rp];
- break;
- }
- j->dtmf_rp++;
- if (j->dtmf_rp == 79)
- j->dtmf_rp = 0;
- if(j->dtmf_rp == j->dtmf_wp)
- {
- j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0;
- }
- }
- }
- break;
- case PHONE_DTMF_OOB:
- j->flags.dtmf_oob = arg;
- break;
- case PHONE_DIALTONE:
- ixj_dialtone(j);
- break;
- case PHONE_BUSY:
- ixj_busytone(j);
- break;
- case PHONE_RINGBACK:
- ixj_ringback(j);
- break;
- case PHONE_WINK:
- if(j->cardtype == QTI_PHONEJACK)
- retval = -1;
- else
- retval = ixj_wink(j);
- break;
- case PHONE_CPT_STOP:
- ixj_cpt_stop(j);
- break;
- case PHONE_QUERY_CODEC:
- {
- struct phone_codec_data pd;
- int val;
- int proto_size[] = {
- -1,
- 12, 10, 16, 9, 8, 48, 5,
- 40, 40, 80, 40, 40, 6
- };
- if(copy_from_user(&pd, argp, sizeof(pd))) {
- retval = -EFAULT;
- break;
- }
- if(pd.type<1 || pd.type>13) {
- retval = -EPROTONOSUPPORT;
- break;
- }
- if(pd.type<G729)
- val=proto_size[pd.type];
- else switch(j->baseframe.low)
- {
- case 0xA0:val=2*proto_size[pd.type];break;
- case 0x50:val=proto_size[pd.type];break;
- default:val=proto_size[pd.type]*3;break;
- }
- pd.buf_min=pd.buf_max=pd.buf_opt=val;
- if(copy_to_user(argp, &pd, sizeof(pd)))
- retval = -EFAULT;
- break;
- }
- case IXJCTL_DSP_IDLE:
- idle(j);
- break;
- case IXJCTL_MIXER:
- if ((arg & 0xff) == 0xff)
- retval = ixj_get_mixer(arg, j);
- else
- ixj_mixer(arg, j);
- break;
- case IXJCTL_DAA_COEFF_SET:
- switch (arg) {
- case DAA_US:
- DAA_Coeff_US(j);
- retval = ixj_daa_write(j);
- break;
- case DAA_UK:
- DAA_Coeff_UK(j);
- retval = ixj_daa_write(j);
- break;
- case DAA_FRANCE:
- DAA_Coeff_France(j);
- retval = ixj_daa_write(j);
- break;
- case DAA_GERMANY:
- DAA_Coeff_Germany(j);
- retval = ixj_daa_write(j);
- break;
- case DAA_AUSTRALIA:
- DAA_Coeff_Australia(j);
- retval = ixj_daa_write(j);
- break;
- case DAA_JAPAN:
- DAA_Coeff_Japan(j);
- retval = ixj_daa_write(j);
- break;
- default:
- retval = 1;
- break;
- }
- break;
- case IXJCTL_DAA_AGAIN:
- ixj_daa_cr4(j, arg | 0x02);
- break;
- case IXJCTL_PSTN_LINETEST:
- retval = ixj_linetest(j);
- break;
- case IXJCTL_VMWI:
- ixj_write_vmwi(j, arg);
- break;
- case IXJCTL_CID:
- if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID)))
- retval = -EFAULT;
- j->ex.bits.caller_id = 0;
- break;
- case IXJCTL_WINK_DURATION:
- j->winktime = arg;
- break;
- case IXJCTL_PORT:
- if (arg)
- retval = ixj_set_port(j, arg);
- else
- retval = j->port;
- break;
- case IXJCTL_POTS_PSTN:
- retval = ixj_set_pots(j, arg);
- break;
- case PHONE_CAPABILITIES:
- add_caps(j);
- retval = j->caps;
- break;
- case PHONE_CAPABILITIES_LIST:
- add_caps(j);
- if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps))
- retval = -EFAULT;
- break;
- case PHONE_CAPABILITIES_CHECK:
- {
- struct phone_capability cap;
- if (copy_from_user(&cap, argp, sizeof(cap)))
- retval = -EFAULT;
- else {
- add_caps(j);
- retval = capabilities_check(j, &cap);
- }
- }
- break;
- case PHONE_PSTN_SET_STATE:
- daa_set_mode(j, arg);
- break;
- case PHONE_PSTN_GET_STATE:
- retval = j->daa_mode;
- j->ex.bits.pstn_ring = 0;
- break;
- case IXJCTL_SET_FILTER:
- if (copy_from_user(&jf, argp, sizeof(jf)))
- retval = -EFAULT;
- else
- retval = ixj_init_filter(j, &jf);
- break;
- case IXJCTL_SET_FILTER_RAW:
- if (copy_from_user(&jfr, argp, sizeof(jfr)))
- retval = -EFAULT;
- else
- retval = ixj_init_filter_raw(j, &jfr);
- break;
- case IXJCTL_GET_FILTER_HIST:
- if(arg<0||arg>3)
- retval = -EINVAL;
- else
- retval = j->filter_hist[arg];
- break;
- case IXJCTL_INIT_TONE:
- if (copy_from_user(&ti, argp, sizeof(ti)))
- retval = -EFAULT;
- else
- retval = ixj_init_tone(j, &ti);
- break;
- case IXJCTL_TONE_CADENCE:
- retval = ixj_build_cadence(j, argp);
- break;
- case IXJCTL_FILTER_CADENCE:
- retval = ixj_build_filter_cadence(j, argp);
- break;
- case IXJCTL_SIGCTL:
- if (copy_from_user(&j->sigdef, argp, sizeof(IXJ_SIGDEF))) {
- retval = -EFAULT;
- break;
- }
- j->ixj_signals[j->sigdef.event] = j->sigdef.signal;
- if(j->sigdef.event < 33) {
- raise = 1;
- for(mant = 0; mant < j->sigdef.event; mant++){
- raise *= 2;
- }
- if(j->sigdef.signal)
- j->ex_sig.bytes |= raise;
- else
- j->ex_sig.bytes &= (raise^0xffff);
- }
- break;
- case IXJCTL_INTERCOM_STOP:
- if(arg < 0 || arg >= IXJMAX)
- return -EINVAL;
- j->intercom = -1;
- ixj_record_stop(j);
- ixj_play_stop(j);
- idle(j);
- get_ixj(arg)->intercom = -1;
- ixj_record_stop(get_ixj(arg));
- ixj_play_stop(get_ixj(arg));
- idle(get_ixj(arg));
- break;
- case IXJCTL_INTERCOM_START:
- if(arg < 0 || arg >= IXJMAX)
- return -EINVAL;
- j->intercom = arg;
- ixj_record_start(j);
- ixj_play_start(j);
- get_ixj(arg)->intercom = board;
- ixj_play_start(get_ixj(arg));
- ixj_record_start(get_ixj(arg));
- break;
- }
- if (ixjdebug & 0x0040)
- printk("phone%d ioctl end, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
- clear_bit(board, &j->busyflags);
- return retval;
-}
-
-static long ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg)
-{
- long ret;
- mutex_lock(&ixj_mutex);
- ret = do_ixj_ioctl(file_p, cmd, arg);
- mutex_unlock(&ixj_mutex);
- return ret;
-}
-
-static int ixj_fasync(int fd, struct file *file_p, int mode)
-{
- IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
-
- return fasync_helper(fd, file_p, mode, &j->async_queue);
-}
-
-static const struct file_operations ixj_fops =
-{
- .owner = THIS_MODULE,
- .read = ixj_enhanced_read,
- .write = ixj_enhanced_write,
- .poll = ixj_poll,
- .unlocked_ioctl = ixj_ioctl,
- .release = ixj_release,
- .fasync = ixj_fasync,
- .llseek = default_llseek,
-};
-
-static int ixj_linetest(IXJ *j)
-{
- j->flags.pstncheck = 1; /* Testing */
- j->flags.pstn_present = 0; /* Assume the line is not there */
-
- daa_int_read(j); /*Clear DAA Interrupt flags */
- /* */
- /* Hold all relays in the normally de-energized position. */
- /* */
-
- j->pld_slicw.bits.rly1 = 0;
- j->pld_slicw.bits.rly2 = 0;
- j->pld_slicw.bits.rly3 = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
-
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
- if (j->pld_slicr.bits.potspstn) {
- j->flags.pots_pstn = 1;
- j->flags.pots_correct = 0;
- LED_SetState(0x4, j);
- } else {
- j->flags.pots_pstn = 0;
- j->pld_slicw.bits.rly1 = 0;
- j->pld_slicw.bits.rly2 = 0;
- j->pld_slicw.bits.rly3 = 1;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
-
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- daa_set_mode(j, SOP_PU_CONVERSATION);
- msleep(1000);
- daa_int_read(j);
- daa_set_mode(j, SOP_PU_RESET);
- if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
- j->flags.pots_correct = 0; /* Should not be line voltage on POTS port. */
- LED_SetState(0x4, j);
- j->pld_slicw.bits.rly3 = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- } else {
- j->flags.pots_correct = 1;
- LED_SetState(0x8, j);
- j->pld_slicw.bits.rly1 = 1;
- j->pld_slicw.bits.rly2 = 0;
- j->pld_slicw.bits.rly3 = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- }
- }
- j->pld_slicw.bits.rly3 = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- daa_set_mode(j, SOP_PU_CONVERSATION);
- msleep(1000);
- daa_int_read(j);
- daa_set_mode(j, SOP_PU_RESET);
- if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
- j->pstn_sleeptil = jiffies + (hertz / 4);
- j->flags.pstn_present = 1;
- } else {
- j->flags.pstn_present = 0;
- }
- if (j->flags.pstn_present) {
- if (j->flags.pots_correct) {
- LED_SetState(0xA, j);
- } else {
- LED_SetState(0x6, j);
- }
- } else {
- if (j->flags.pots_correct) {
- LED_SetState(0x9, j);
- } else {
- LED_SetState(0x5, j);
- }
- }
- j->flags.pstncheck = 0; /* Testing */
- return j->flags.pstn_present;
-}
-
-static int ixj_selfprobe(IXJ *j)
-{
- unsigned short cmd;
- int cnt;
- BYTES bytes;
-
- init_waitqueue_head(&j->poll_q);
- init_waitqueue_head(&j->read_q);
- init_waitqueue_head(&j->write_q);
-
- while(atomic_read(&j->DSPWrite) > 0)
- atomic_dec(&j->DSPWrite);
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Write IDLE to Software Control Register\n");
- ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */
-
- if (ixj_WriteDSPCommand(0x0000, j)) /* Write IDLE to Software Control Register */
- return -1;
-/* The read values of the SSR should be 0x00 for the IDLE command */
- if (j->ssr.low || j->ssr.high)
- return -1;
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Get Device ID Code\n");
- if (ixj_WriteDSPCommand(0x3400, j)) /* Get Device ID Code */
- return -1;
- j->dsp.low = j->ssr.low;
- j->dsp.high = j->ssr.high;
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Get Device Version Code\n");
- if (ixj_WriteDSPCommand(0x3800, j)) /* Get Device Version Code */
- return -1;
- j->ver.low = j->ssr.low;
- j->ver.high = j->ssr.high;
- if (!j->cardtype) {
- if (j->dsp.low == 0x21) {
- bytes.high = bytes.low = inb_p(j->XILINXbase + 0x02);
- outb_p(bytes.low ^ 0xFF, j->XILINXbase + 0x02);
-/* Test for Internet LineJACK or Internet PhoneJACK Lite */
- bytes.low = inb_p(j->XILINXbase + 0x02);
- if (bytes.low == bytes.high) /* Register is read only on */
- /* Internet PhoneJack Lite */
- {
- j->cardtype = QTI_PHONEJACK_LITE;
- if (!request_region(j->XILINXbase, 4, "ixj control")) {
- printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
- return -1;
- }
- j->pld_slicw.pcib.e1 = 1;
- outb_p(j->pld_slicw.byte, j->XILINXbase);
- } else {
- j->cardtype = QTI_LINEJACK;
-
- if (!request_region(j->XILINXbase, 8, "ixj control")) {
- printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
- return -1;
- }
- }
- } else if (j->dsp.low == 0x22) {
- j->cardtype = QTI_PHONEJACK_PCI;
- request_region(j->XILINXbase, 4, "ixj control");
- j->pld_slicw.pcib.e1 = 1;
- outb_p(j->pld_slicw.byte, j->XILINXbase);
- } else
- j->cardtype = QTI_PHONEJACK;
- } else {
- switch (j->cardtype) {
- case QTI_PHONEJACK:
- if (!j->dsp.low != 0x20) {
- j->dsp.high = 0x80;
- j->dsp.low = 0x20;
- ixj_WriteDSPCommand(0x3800, j);
- j->ver.low = j->ssr.low;
- j->ver.high = j->ssr.high;
- }
- break;
- case QTI_LINEJACK:
- if (!request_region(j->XILINXbase, 8, "ixj control")) {
- printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
- return -1;
- }
- break;
- case QTI_PHONEJACK_LITE:
- case QTI_PHONEJACK_PCI:
- if (!request_region(j->XILINXbase, 4, "ixj control")) {
- printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
- return -1;
- }
- j->pld_slicw.pcib.e1 = 1;
- outb_p(j->pld_slicw.byte, j->XILINXbase);
- break;
- case QTI_PHONECARD:
- break;
- }
- }
- if (j->dsp.low == 0x20 || j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) {
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Write CODEC config to Software Control Register\n");
- if (ixj_WriteDSPCommand(0xC462, j)) /* Write CODEC config to Software Control Register */
- return -1;
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Write CODEC timing to Software Control Register\n");
- if (j->cardtype == QTI_PHONEJACK) {
- cmd = 0x9FF2;
- } else {
- cmd = 0x9FF5;
- }
- if (ixj_WriteDSPCommand(cmd, j)) /* Write CODEC timing to Software Control Register */
- return -1;
- } else {
- if (set_base_frame(j, 30) != 30)
- return -1;
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Write CODEC config to Software Control Register\n");
- if (j->cardtype == QTI_PHONECARD) {
- if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to Software Control Register */
- return -1;
- }
- if (j->cardtype == QTI_LINEJACK) {
- if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to Software Control Register */
- return -1;
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Turn on the PLD Clock at 8Khz\n");
- j->pld_clock.byte = 0;
- outb_p(j->pld_clock.byte, j->XILINXbase + 0x04);
- }
- }
-
- if (j->dsp.low == 0x20) {
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Configure GPIO pins\n");
- j->gpio.bytes.high = 0x09;
-/* bytes.low = 0xEF; 0xF7 */
- j->gpio.bits.gpio1 = 1;
- j->gpio.bits.gpio2 = 1;
- j->gpio.bits.gpio3 = 0;
- j->gpio.bits.gpio4 = 1;
- j->gpio.bits.gpio5 = 1;
- j->gpio.bits.gpio6 = 1;
- j->gpio.bits.gpio7 = 1;
- ixj_WriteDSPCommand(j->gpio.word, j); /* Set GPIO pin directions */
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Enable SLIC\n");
- j->gpio.bytes.high = 0x0B;
- j->gpio.bytes.low = 0x00;
- j->gpio.bits.gpio1 = 0;
- j->gpio.bits.gpio2 = 1;
- j->gpio.bits.gpio5 = 0;
- ixj_WriteDSPCommand(j->gpio.word, j); /* send the ring stop signal */
- j->port = PORT_POTS;
- } else {
- if (j->cardtype == QTI_LINEJACK) {
- LED_SetState(0x1, j);
- msleep(100);
- LED_SetState(0x2, j);
- msleep(100);
- LED_SetState(0x4, j);
- msleep(100);
- LED_SetState(0x8, j);
- msleep(100);
- LED_SetState(0x0, j);
- daa_get_version(j);
- if (ixjdebug & 0x0002)
- printk("Loading DAA Coefficients\n");
- DAA_Coeff_US(j);
- if (!ixj_daa_write(j)) {
- printk("DAA write failed on board %d\n", j->board);
- return -1;
- }
- if(!ixj_daa_cid_reset(j)) {
- printk("DAA CID reset failed on board %d\n", j->board);
- return -1;
- }
- j->flags.pots_correct = 0;
- j->flags.pstn_present = 0;
- ixj_linetest(j);
- if (j->flags.pots_correct) {
- j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
-
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- j->pld_slicw.bits.rly1 = 1;
- j->pld_slicw.bits.spken = 1;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
-/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
- j->port = PORT_POTS;
- }
- ixj_set_port(j, PORT_PSTN);
- ixj_set_pots(j, 1);
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Enable Mixer\n");
- ixj_mixer(0x0000, j); /*Master Volume Left unmute 0db */
- ixj_mixer(0x0100, j); /*Master Volume Right unmute 0db */
-
- ixj_mixer(0x0203, j); /*Voice Left Volume unmute 6db */
- ixj_mixer(0x0303, j); /*Voice Right Volume unmute 6db */
-
- ixj_mixer(0x0480, j); /*FM Left mute */
- ixj_mixer(0x0580, j); /*FM Right mute */
-
- ixj_mixer(0x0680, j); /*CD Left mute */
- ixj_mixer(0x0780, j); /*CD Right mute */
-
- ixj_mixer(0x0880, j); /*Line Left mute */
- ixj_mixer(0x0980, j); /*Line Right mute */
-
- ixj_mixer(0x0A80, j); /*Aux left mute */
- ixj_mixer(0x0B80, j); /*Aux right mute */
-
- ixj_mixer(0x0C00, j); /*Mono1 unmute 12db */
- ixj_mixer(0x0D80, j); /*Mono2 mute */
-
- ixj_mixer(0x0E80, j); /*Mic mute */
-
- ixj_mixer(0x0F00, j); /*Mono Out Volume unmute 0db */
-
- ixj_mixer(0x1000, j); /*Voice Left and Right out only */
- ixj_mixer(0x110C, j);
-
-
- ixj_mixer(0x1200, j); /*Mono1 switch on mixer left */
- ixj_mixer(0x1401, j);
-
- ixj_mixer(0x1300, j); /*Mono1 switch on mixer right */
- ixj_mixer(0x1501, j);
-
- ixj_mixer(0x1700, j); /*Clock select */
-
- ixj_mixer(0x1800, j); /*ADC input from mixer */
-
- ixj_mixer(0x1901, j); /*Mic gain 30db */
-
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Setting Default US Ring Cadence Detection\n");
- j->cadence_f[4].state = 0;
- j->cadence_f[4].on1 = 0; /*Cadence Filter 4 is used for PSTN ring cadence */
- j->cadence_f[4].off1 = 0;
- j->cadence_f[4].on2 = 0;
- j->cadence_f[4].off2 = 0;
- j->cadence_f[4].on3 = 0;
- j->cadence_f[4].off3 = 0; /* These should represent standard US ring pulse. */
- j->pstn_last_rmr = jiffies;
-
- } else {
- if (j->cardtype == QTI_PHONECARD) {
- ixj_WriteDSPCommand(0xCF07, j);
- ixj_WriteDSPCommand(0x00B0, j);
- ixj_set_port(j, PORT_SPEAKER);
- } else {
- ixj_set_port(j, PORT_POTS);
- SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
-/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
- }
- }
- }
-
- j->intercom = -1;
- j->framesread = j->frameswritten = 0;
- j->read_wait = j->write_wait = 0;
- j->rxreadycheck = j->txreadycheck = 0;
-
- /* initialise the DTMF prescale to a sensible value */
- if (j->cardtype == QTI_LINEJACK) {
- set_dtmf_prescale(j, 0x10);
- } else {
- set_dtmf_prescale(j, 0x40);
- }
- set_play_volume(j, 0x100);
- set_rec_volume(j, 0x100);
-
- if (ixj_WriteDSPCommand(0x0000, j)) /* Write IDLE to Software Control Register */
- return -1;
-/* The read values of the SSR should be 0x00 for the IDLE command */
- if (j->ssr.low || j->ssr.high)
- return -1;
-
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Enable Line Monitor\n");
-
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "Set Line Monitor to Asynchronous Mode\n");
-
- if (ixj_WriteDSPCommand(0x7E01, j)) /* Asynchronous Line Monitor */
- return -1;
-
- if (ixjdebug & 0x002)
- printk(KERN_INFO "Enable DTMF Detectors\n");
-
- if (ixj_WriteDSPCommand(0x5151, j)) /* Enable DTMF detection */
- return -1;
-
- if (ixj_WriteDSPCommand(0x6E01, j)) /* Set Asynchronous Tone Generation */
- return -1;
-
- set_rec_depth(j, 2); /* Set Record Channel Limit to 2 frames */
-
- set_play_depth(j, 2); /* Set Playback Channel Limit to 2 frames */
-
- j->ex.bits.dtmf_ready = 0;
- j->dtmf_state = 0;
- j->dtmf_wp = j->dtmf_rp = 0;
- j->rec_mode = j->play_mode = -1;
- j->flags.ringing = 0;
- j->maxrings = MAXRINGS;
- j->ring_cadence = USA_RING_CADENCE;
- j->drybuffer = 0;
- j->winktime = 320;
- j->flags.dtmf_oob = 0;
- for (cnt = 0; cnt < 4; cnt++)
- j->cadence_f[cnt].enable = 0;
- /* must be a device on the specified address */
- ixj_WriteDSPCommand(0x0FE3, j); /* Put the DSP in 1/5 power mode. */
-
- /* Set up the default signals for events */
- for (cnt = 0; cnt < 35; cnt++)
- j->ixj_signals[cnt] = SIGIO;
-
- /* Set the exception signal enable flags */
- j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring =
- j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 =
- j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1;
-#ifdef IXJ_DYN_ALLOC
- j->fskdata = NULL;
-#endif
- j->fskdcnt = 0;
- j->cidcw_wait = 0;
-
- /* Register with the Telephony for Linux subsystem */
- j->p.f_op = &ixj_fops;
- j->p.open = ixj_open;
- j->p.board = j->board;
- phone_register_device(&j->p, PHONE_UNIT_ANY);
-
- ixj_init_timer(j);
- ixj_add_timer(j);
- return 0;
-}
-
-/*
- * Exported service for pcmcia card handling
- */
-
-IXJ *ixj_pcmcia_probe(unsigned long dsp, unsigned long xilinx)
-{
- IXJ *j = ixj_alloc();
-
- j->board = 0;
-
- j->DSPbase = dsp;
- j->XILINXbase = xilinx;
- j->cardtype = QTI_PHONECARD;
- ixj_selfprobe(j);
- return j;
-}
-
-EXPORT_SYMBOL(ixj_pcmcia_probe); /* For PCMCIA */
-
-static int ixj_get_status_proc(char *buf)
-{
- int len;
- int cnt;
- IXJ *j;
- len = 0;
- len += sprintf(buf + len, "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, IXJ_VER_MINOR, IXJ_BLD_VER);
- len += sprintf(buf + len, "\nsizeof IXJ struct %Zd bytes", sizeof(IXJ));
- len += sprintf(buf + len, "\nsizeof DAA struct %Zd bytes", sizeof(DAA_REGS));
- len += sprintf(buf + len, "\nUsing old telephony API");
- len += sprintf(buf + len, "\nDebug Level %d\n", ixjdebug);
-
- for (cnt = 0; cnt < IXJMAX; cnt++) {
- j = get_ixj(cnt);
- if(j==NULL)
- continue;
- if (j->DSPbase) {
- len += sprintf(buf + len, "\nCard Num %d", cnt);
- len += sprintf(buf + len, "\nDSP Base Address 0x%4.4x", j->DSPbase);
- if (j->cardtype != QTI_PHONEJACK)
- len += sprintf(buf + len, "\nXILINX Base Address 0x%4.4x", j->XILINXbase);
- len += sprintf(buf + len, "\nDSP Type %2.2x%2.2x", j->dsp.high, j->dsp.low);
- len += sprintf(buf + len, "\nDSP Version %2.2x.%2.2x", j->ver.high, j->ver.low);
- len += sprintf(buf + len, "\nSerial Number %8.8x", j->serial);
- switch (j->cardtype) {
- case (QTI_PHONEJACK):
- len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK");
- break;
- case (QTI_LINEJACK):
- len += sprintf(buf + len, "\nCard Type = Internet LineJACK");
- if (j->flags.g729_loaded)
- len += sprintf(buf + len, " w/G.729 A/B");
- len += sprintf(buf + len, " Country = %d", j->daa_country);
- break;
- case (QTI_PHONEJACK_LITE):
- len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK Lite");
- if (j->flags.g729_loaded)
- len += sprintf(buf + len, " w/G.729 A/B");
- break;
- case (QTI_PHONEJACK_PCI):
- len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK PCI");
- if (j->flags.g729_loaded)
- len += sprintf(buf + len, " w/G.729 A/B");
- break;
- case (QTI_PHONECARD):
- len += sprintf(buf + len, "\nCard Type = Internet PhoneCARD");
- if (j->flags.g729_loaded)
- len += sprintf(buf + len, " w/G.729 A/B");
- len += sprintf(buf + len, "\nSmart Cable %spresent", j->pccr1.bits.drf ? "not " : "");
- if (!j->pccr1.bits.drf)
- len += sprintf(buf + len, "\nSmart Cable type %d", j->flags.pcmciasct);
- len += sprintf(buf + len, "\nSmart Cable state %d", j->flags.pcmciastate);
- break;
- default:
- len += sprintf(buf + len, "\nCard Type = %d", j->cardtype);
- break;
- }
- len += sprintf(buf + len, "\nReaders %d", j->readers);
- len += sprintf(buf + len, "\nWriters %d", j->writers);
- add_caps(j);
- len += sprintf(buf + len, "\nCapabilities %d", j->caps);
- if (j->dsp.low != 0x20)
- len += sprintf(buf + len, "\nDSP Processor load %d", j->proc_load);
- if (j->flags.cidsent)
- len += sprintf(buf + len, "\nCaller ID data sent");
- else
- len += sprintf(buf + len, "\nCaller ID data not sent");
-
- len += sprintf(buf + len, "\nPlay CODEC ");
- switch (j->play_codec) {
- case G723_63:
- len += sprintf(buf + len, "G.723.1 6.3");
- break;
- case G723_53:
- len += sprintf(buf + len, "G.723.1 5.3");
- break;
- case TS85:
- len += sprintf(buf + len, "TrueSpeech 8.5");
- break;
- case TS48:
- len += sprintf(buf + len, "TrueSpeech 4.8");
- break;
- case TS41:
- len += sprintf(buf + len, "TrueSpeech 4.1");
- break;
- case G728:
- len += sprintf(buf + len, "G.728");
- break;
- case G729:
- len += sprintf(buf + len, "G.729");
- break;
- case G729B:
- len += sprintf(buf + len, "G.729B");
- break;
- case ULAW:
- len += sprintf(buf + len, "uLaw");
- break;
- case ALAW:
- len += sprintf(buf + len, "aLaw");
- break;
- case LINEAR16:
- len += sprintf(buf + len, "16 bit Linear");
- break;
- case LINEAR8:
- len += sprintf(buf + len, "8 bit Linear");
- break;
- case WSS:
- len += sprintf(buf + len, "Windows Sound System");
- break;
- default:
- len += sprintf(buf + len, "NO CODEC CHOSEN");
- break;
- }
- len += sprintf(buf + len, "\nRecord CODEC ");
- switch (j->rec_codec) {
- case G723_63:
- len += sprintf(buf + len, "G.723.1 6.3");
- break;
- case G723_53:
- len += sprintf(buf + len, "G.723.1 5.3");
- break;
- case TS85:
- len += sprintf(buf + len, "TrueSpeech 8.5");
- break;
- case TS48:
- len += sprintf(buf + len, "TrueSpeech 4.8");
- break;
- case TS41:
- len += sprintf(buf + len, "TrueSpeech 4.1");
- break;
- case G728:
- len += sprintf(buf + len, "G.728");
- break;
- case G729:
- len += sprintf(buf + len, "G.729");
- break;
- case G729B:
- len += sprintf(buf + len, "G.729B");
- break;
- case ULAW:
- len += sprintf(buf + len, "uLaw");
- break;
- case ALAW:
- len += sprintf(buf + len, "aLaw");
- break;
- case LINEAR16:
- len += sprintf(buf + len, "16 bit Linear");
- break;
- case LINEAR8:
- len += sprintf(buf + len, "8 bit Linear");
- break;
- case WSS:
- len += sprintf(buf + len, "Windows Sound System");
- break;
- default:
- len += sprintf(buf + len, "NO CODEC CHOSEN");
- break;
- }
- len += sprintf(buf + len, "\nAEC ");
- switch (j->aec_level) {
- case AEC_OFF:
- len += sprintf(buf + len, "Off");
- break;
- case AEC_LOW:
- len += sprintf(buf + len, "Low");
- break;
- case AEC_MED:
- len += sprintf(buf + len, "Med");
- break;
- case AEC_HIGH:
- len += sprintf(buf + len, "High");
- break;
- case AEC_AUTO:
- len += sprintf(buf + len, "Auto");
- break;
- case AEC_AGC:
- len += sprintf(buf + len, "AEC/AGC");
- break;
- default:
- len += sprintf(buf + len, "unknown(%i)", j->aec_level);
- break;
- }
-
- len += sprintf(buf + len, "\nRec volume 0x%x", get_rec_volume(j));
- len += sprintf(buf + len, "\nPlay volume 0x%x", get_play_volume(j));
- len += sprintf(buf + len, "\nDTMF prescale 0x%x", get_dtmf_prescale(j));
-
- len += sprintf(buf + len, "\nHook state %d", j->hookstate); /* j->r_hook); */
-
- if (j->cardtype == QTI_LINEJACK) {
- len += sprintf(buf + len, "\nPOTS Correct %d", j->flags.pots_correct);
- len += sprintf(buf + len, "\nPSTN Present %d", j->flags.pstn_present);
- len += sprintf(buf + len, "\nPSTN Check %d", j->flags.pstncheck);
- len += sprintf(buf + len, "\nPOTS to PSTN %d", j->flags.pots_pstn);
- switch (j->daa_mode) {
- case SOP_PU_SLEEP:
- len += sprintf(buf + len, "\nDAA PSTN On Hook");
- break;
- case SOP_PU_RINGING:
- len += sprintf(buf + len, "\nDAA PSTN Ringing");
- len += sprintf(buf + len, "\nRinging state = %d", j->cadence_f[4].state);
- break;
- case SOP_PU_CONVERSATION:
- len += sprintf(buf + len, "\nDAA PSTN Off Hook");
- break;
- case SOP_PU_PULSEDIALING:
- len += sprintf(buf + len, "\nDAA PSTN Pulse Dialing");
- break;
- }
- len += sprintf(buf + len, "\nDAA RMR = %d", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR);
- len += sprintf(buf + len, "\nDAA VDD OK = %d", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK);
- len += sprintf(buf + len, "\nDAA CR0 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg);
- len += sprintf(buf + len, "\nDAA CR1 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg);
- len += sprintf(buf + len, "\nDAA CR2 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg);
- len += sprintf(buf + len, "\nDAA CR3 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg);
- len += sprintf(buf + len, "\nDAA CR4 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg);
- len += sprintf(buf + len, "\nDAA CR5 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg);
- len += sprintf(buf + len, "\nDAA XR0 = 0x%02x", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg);
- len += sprintf(buf + len, "\nDAA ringstop %ld - jiffies %ld", j->pstn_ring_stop, jiffies);
- }
- switch (j->port) {
- case PORT_POTS:
- len += sprintf(buf + len, "\nPort POTS");
- break;
- case PORT_PSTN:
- len += sprintf(buf + len, "\nPort PSTN");
- break;
- case PORT_SPEAKER:
- len += sprintf(buf + len, "\nPort SPEAKER/MIC");
- break;
- case PORT_HANDSET:
- len += sprintf(buf + len, "\nPort HANDSET");
- break;
- }
- if (j->dsp.low == 0x21 || j->dsp.low == 0x22) {
- len += sprintf(buf + len, "\nSLIC state ");
- switch (SLIC_GetState(j)) {
- case PLD_SLIC_STATE_OC:
- len += sprintf(buf + len, "OC");
- break;
- case PLD_SLIC_STATE_RINGING:
- len += sprintf(buf + len, "RINGING");
- break;
- case PLD_SLIC_STATE_ACTIVE:
- len += sprintf(buf + len, "ACTIVE");
- break;
- case PLD_SLIC_STATE_OHT: /* On-hook transmit */
- len += sprintf(buf + len, "OHT");
- break;
- case PLD_SLIC_STATE_TIPOPEN:
- len += sprintf(buf + len, "TIPOPEN");
- break;
- case PLD_SLIC_STATE_STANDBY:
- len += sprintf(buf + len, "STANDBY");
- break;
- case PLD_SLIC_STATE_APR: /* Active polarity reversal */
- len += sprintf(buf + len, "APR");
- break;
- case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */
- len += sprintf(buf + len, "OHTPR");
- break;
- default:
- len += sprintf(buf + len, "%d", SLIC_GetState(j));
- break;
- }
- }
- len += sprintf(buf + len, "\nBase Frame %2.2x.%2.2x", j->baseframe.high, j->baseframe.low);
- len += sprintf(buf + len, "\nCID Base Frame %2d", j->cid_base_frame_size);
-#ifdef PERFMON_STATS
- len += sprintf(buf + len, "\nTimer Checks %ld", j->timerchecks);
- len += sprintf(buf + len, "\nRX Ready Checks %ld", j->rxreadycheck);
- len += sprintf(buf + len, "\nTX Ready Checks %ld", j->txreadycheck);
- len += sprintf(buf + len, "\nFrames Read %ld", j->framesread);
- len += sprintf(buf + len, "\nFrames Written %ld", j->frameswritten);
- len += sprintf(buf + len, "\nDry Buffer %ld", j->drybuffer);
- len += sprintf(buf + len, "\nRead Waits %ld", j->read_wait);
- len += sprintf(buf + len, "\nWrite Waits %ld", j->write_wait);
- len += sprintf(buf + len, "\nStatus Waits %ld", j->statuswait);
- len += sprintf(buf + len, "\nStatus Wait Fails %ld", j->statuswaitfail);
- len += sprintf(buf + len, "\nPControl Waits %ld", j->pcontrolwait);
- len += sprintf(buf + len, "\nPControl Wait Fails %ld", j->pcontrolwaitfail);
- len += sprintf(buf + len, "\nIs Control Ready Checks %ld", j->iscontrolready);
- len += sprintf(buf + len, "\nIs Control Ready Check failures %ld", j->iscontrolreadyfail);
-
-#endif
- len += sprintf(buf + len, "\n");
- }
- }
- return len;
-}
-
-static int ixj_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- int len = ixj_get_status_proc(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
-}
-
-
-static void cleanup(void)
-{
- int cnt;
- IXJ *j;
-
- for (cnt = 0; cnt < IXJMAX; cnt++) {
- j = get_ixj(cnt);
- if(j != NULL && j->DSPbase) {
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "IXJ: Deleting timer for /dev/phone%d\n", cnt);
- del_timer(&j->timer);
- if (j->cardtype == QTI_LINEJACK) {
- j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
-
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- j->pld_slicw.bits.rly1 = 0;
- j->pld_slicw.bits.rly2 = 0;
- j->pld_slicw.bits.rly3 = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- LED_SetState(0x0, j);
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt);
- release_region(j->XILINXbase, 8);
- } else if (j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) {
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt);
- release_region(j->XILINXbase, 4);
- }
- kfree(j->read_buffer);
- kfree(j->write_buffer);
- if (j->dev)
- pnp_device_detach(j->dev);
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "IXJ: Unregistering /dev/phone%d from LTAPI\n", cnt);
- phone_unregister_device(&j->p);
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "IXJ: Releasing DSP address for /dev/phone%d\n", cnt);
- release_region(j->DSPbase, 16);
-#ifdef IXJ_DYN_ALLOC
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "IXJ: Freeing memory for /dev/phone%d\n", cnt);
- kfree(j);
- ixj[cnt] = NULL;
-#endif
- }
- }
- if (ixjdebug & 0x0002)
- printk(KERN_INFO "IXJ: Removing /proc/ixj\n");
- remove_proc_entry ("ixj", NULL);
-}
-
-/* Typedefs */
-typedef struct {
- BYTE length;
- DWORD bits;
-} DATABLOCK;
-
-static void PCIEE_WriteBit(WORD wEEPROMAddress, BYTE lastLCC, BYTE byData)
-{
- lastLCC = lastLCC & 0xfb;
- lastLCC = lastLCC | (byData ? 4 : 0);
- outb(lastLCC, wEEPROMAddress); /*set data out bit as appropriate */
-
- mdelay(1);
- lastLCC = lastLCC | 0x01;
- outb(lastLCC, wEEPROMAddress); /*SK rising edge */
-
- byData = byData << 1;
- lastLCC = lastLCC & 0xfe;
- mdelay(1);
- outb(lastLCC, wEEPROMAddress); /*after delay, SK falling edge */
-
-}
-
-static BYTE PCIEE_ReadBit(WORD wEEPROMAddress, BYTE lastLCC)
-{
- mdelay(1);
- lastLCC = lastLCC | 0x01;
- outb(lastLCC, wEEPROMAddress); /*SK rising edge */
-
- lastLCC = lastLCC & 0xfe;
- mdelay(1);
- outb(lastLCC, wEEPROMAddress); /*after delay, SK falling edge */
-
- return ((inb(wEEPROMAddress) >> 3) & 1);
-}
-
-static bool PCIEE_ReadWord(WORD wAddress, WORD wLoc, WORD * pwResult)
-{
- BYTE lastLCC;
- WORD wEEPROMAddress = wAddress + 3;
- DWORD i;
- BYTE byResult;
- *pwResult = 0;
- lastLCC = inb(wEEPROMAddress);
- lastLCC = lastLCC | 0x02;
- lastLCC = lastLCC & 0xfe;
- outb(lastLCC, wEEPROMAddress); /* CS hi, SK lo */
-
- mdelay(1); /* delay */
-
- PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1);
- PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1);
- PCIEE_WriteBit(wEEPROMAddress, lastLCC, 0);
- for (i = 0; i < 8; i++) {
- PCIEE_WriteBit(wEEPROMAddress, lastLCC, wLoc & 0x80 ? 1 : 0);
- wLoc <<= 1;
- }
-
- for (i = 0; i < 16; i++) {
- byResult = PCIEE_ReadBit(wEEPROMAddress, lastLCC);
- *pwResult = (*pwResult << 1) | byResult;
- }
-
- mdelay(1); /* another delay */
-
- lastLCC = lastLCC & 0xfd;
- outb(lastLCC, wEEPROMAddress); /* negate CS */
-
- return 0;
-}
-
-static DWORD PCIEE_GetSerialNumber(WORD wAddress)
-{
- WORD wLo, wHi;
- if (PCIEE_ReadWord(wAddress, 62, &wLo))
- return 0;
- if (PCIEE_ReadWord(wAddress, 63, &wHi))
- return 0;
- return (((DWORD) wHi << 16) | wLo);
-}
-
-static int dspio[IXJMAX + 1] =
-{
- 0,
-};
-static int xio[IXJMAX + 1] =
-{
- 0,
-};
-
-module_param_array(dspio, int, NULL, 0);
-module_param_array(xio, int, NULL, 0);
-MODULE_DESCRIPTION("Quicknet VoIP Telephony card module - www.quicknet.net");
-MODULE_AUTHOR("Ed Okerson <eokerson@quicknet.net>");
-MODULE_LICENSE("GPL");
-
-static void __exit ixj_exit(void)
-{
- cleanup();
-}
-
-static IXJ *new_ixj(unsigned long port)
-{
- IXJ *res;
- if (!request_region(port, 16, "ixj DSP")) {
- printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n", port);
- return NULL;
- }
- res = ixj_alloc();
- if (!res) {
- release_region(port, 16);
- printk(KERN_INFO "ixj: out of memory\n");
- return NULL;
- }
- res->DSPbase = port;
- return res;
-}
-
-static int __init ixj_probe_isapnp(int *cnt)
-{
- int probe = 0;
- int func = 0x110;
- struct pnp_dev *dev = NULL, *old_dev = NULL;
-
- while (1) {
- do {
- IXJ *j;
- int result;
-
- old_dev = dev;
- dev = pnp_find_dev(NULL, ISAPNP_VENDOR('Q', 'T', 'I'),
- ISAPNP_FUNCTION(func), old_dev);
- if (!dev || !dev->card)
- break;
- result = pnp_device_attach(dev);
- if (result < 0) {
- printk("pnp attach failed %d \n", result);
- break;
- }
- if (pnp_activate_dev(dev) < 0) {
- printk("pnp activate failed (out of resources?)\n");
- pnp_device_detach(dev);
- return -ENOMEM;
- }
-
- if (!pnp_port_valid(dev, 0)) {
- pnp_device_detach(dev);
- return -ENODEV;
- }
-
- j = new_ixj(pnp_port_start(dev, 0));
- if (!j)
- break;
-
- if (func != 0x110)
- j->XILINXbase = pnp_port_start(dev, 1); /* get real port */
-
- switch (func) {
- case (0x110):
- j->cardtype = QTI_PHONEJACK;
- break;
- case (0x310):
- j->cardtype = QTI_LINEJACK;
- break;
- case (0x410):
- j->cardtype = QTI_PHONEJACK_LITE;
- break;
- }
- j->board = *cnt;
- probe = ixj_selfprobe(j);
- if(!probe) {
- j->serial = dev->card->serial;
- j->dev = dev;
- switch (func) {
- case 0x110:
- printk(KERN_INFO "ixj: found Internet PhoneJACK at 0x%x\n", j->DSPbase);
- break;
- case 0x310:
- printk(KERN_INFO "ixj: found Internet LineJACK at 0x%x\n", j->DSPbase);
- break;
- case 0x410:
- printk(KERN_INFO "ixj: found Internet PhoneJACK Lite at 0x%x\n", j->DSPbase);
- break;
- }
- }
- ++*cnt;
- } while (dev);
- if (func == 0x410)
- break;
- if (func == 0x310)
- func = 0x410;
- if (func == 0x110)
- func = 0x310;
- dev = NULL;
- }
- return probe;
-}
-
-static int __init ixj_probe_isa(int *cnt)
-{
- int i, probe;
-
- /* Use passed parameters for older kernels without PnP */
- for (i = 0; i < IXJMAX; i++) {
- if (dspio[i]) {
- IXJ *j = new_ixj(dspio[i]);
-
- if (!j)
- break;
-
- j->XILINXbase = xio[i];
- j->cardtype = 0;
-
- j->board = *cnt;
- probe = ixj_selfprobe(j);
- j->dev = NULL;
- ++*cnt;
- }
- }
- return 0;
-}
-
-static int __init ixj_probe_pci(int *cnt)
-{
- struct pci_dev *pci = NULL;
- int i, probe = 0;
- IXJ *j = NULL;
-
- for (i = 0; i < IXJMAX - *cnt; i++) {
- pci = pci_get_device(PCI_VENDOR_ID_QUICKNET,
- PCI_DEVICE_ID_QUICKNET_XJ, pci);
- if (!pci)
- break;
-
- if (pci_enable_device(pci))
- break;
- j = new_ixj(pci_resource_start(pci, 0));
- if (!j)
- break;
-
- j->serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2);
- j->XILINXbase = j->DSPbase + 0x10;
- j->cardtype = QTI_PHONEJACK_PCI;
- j->board = *cnt;
- probe = ixj_selfprobe(j);
- if (!probe)
- printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase);
- ++*cnt;
- }
- pci_dev_put(pci);
- return probe;
-}
-
-static int __init ixj_init(void)
-{
- int cnt = 0;
- int probe = 0;
-
- cnt = 0;
-
- /* These might be no-ops, see above. */
- if ((probe = ixj_probe_isapnp(&cnt)) < 0) {
- return probe;
- }
- if ((probe = ixj_probe_isa(&cnt)) < 0) {
- return probe;
- }
- if ((probe = ixj_probe_pci(&cnt)) < 0) {
- return probe;
- }
- printk(KERN_INFO "ixj driver initialized.\n");
- create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL);
- return probe;
-}
-
-module_init(ixj_init);
-module_exit(ixj_exit);
-
-static void DAA_Coeff_US(IXJ *j)
-{
- int i;
-
- j->daa_country = DAA_US;
- /*----------------------------------------------- */
- /* CAO */
- for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
- j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
- }
-
-/* Bytes for IM-filter part 1 (04): 0E,32,E2,2F,C2,5A,C0,00 */
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x03;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0x4B;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x5D;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xCD;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0x24;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xC5;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-/* Bytes for IM-filter part 2 (05): 72,85,00,0E,2B,3A,D0,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x71;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x1A;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0A;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xB5;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-/* Bytes for FRX-filter (08): 03,8F,48,F2,8F,48,70,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x05;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xA3;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x72;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x3F;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x3B;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-/* Bytes for FRR-filter (07): 04,8F,38,7F,9B,EA,B0,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x05;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x3E;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xDA;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-/* Bytes for AX-filter (0A): 16,55,DD,CA */
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x41;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-/* Bytes for AR-filter (09): 52,D3,11,42 */
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-/* Bytes for TH-filter part 1 (00): 00,42,48,81,B3,80,00,98 */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xA5;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-/* Bytes for TH-filter part 2 (01): 02,F2,33,A0,68,AB,8A,AD */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xA2;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2B;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xB0;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0xE8;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAB;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xCC;
-/* Bytes for TH-filter part 3 (02): 00,88,DA,54,A4,BA,2D,BB */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xD2;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x24;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xA9;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x3B;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xA6;
-/* ; (10K, 0.68uF) */
- /* */
- /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
- /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-
- /* Levelmetering Ringing (0D):B2,45,0F,8E */
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-
- /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1C; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0xB3; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0xAB; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xAB; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x54; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x2D; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0x62; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x2D; */
- /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x2D; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x62; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBB; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x2A; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7D; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD4; */
-/* */
- /* Levelmetering Ringing (0D):B2,45,0F,8E */
-/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x05; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; */
-/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; */
-
- /* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-/* */
- /* ;CR Registers */
- /* Config. Reg. 0 (filters) (cr0):FE ; CLK gen. by crystal */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-/* Config. Reg. 1 (dialing) (cr1):05 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-/* Config. Reg. 2 (caller ID) (cr2):04 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-/* Config. Reg. 3 (testloops) (cr3):03 ; SEL Bit==0, HP-disabled */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-/* Config. Reg. 4 (analog gain) (cr4):02 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
- /* Config. Reg. 5 (Version) (cr5):02 */
- /* Config. Reg. 6 (Reserved) (cr6):00 */
- /* Config. Reg. 7 (Reserved) (cr7):00 */
- /* */
- /* ;xr Registers */
- /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */
-
- j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */
- /* Ext. Reg. 1 (Interrupt enable) (xr1):3C Cadence, RING, Caller ID, VDD_OK */
-
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x3C;
-/* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-/* Ext. Reg. 3 (DC Char) (xr3):32 ; B-Filter Off == 1 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x3B; /*0x32; */
- /* Ext. Reg. 4 (Cadence) (xr4):00 */
-
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-/* Ext. Reg. 5 (Ring timer) (xr5):22 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-/* Ext. Reg. 6 (Power State) (xr6):00 */
- j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-/* Ext. Reg. 7 (Vdd) (xr7):40 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */
- /* */
- /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */
- /* 12,33,5A,C3 ; 770 Hz */
- /* 13,3C,5B,32 ; 852 Hz */
- /* 1D,1B,5C,CC ; 941 Hz */
-
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */
- /* EC,1D,52,22 ; 1336 Hz */
- /* AA,AC,51,D2 ; 1477 Hz */
- /* 9B,3B,51,25 ; 1633 Hz */
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-}
-
-static void DAA_Coeff_UK(IXJ *j)
-{
- int i;
-
- j->daa_country = DAA_UK;
- /*----------------------------------------------- */
- /* CAO */
- for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
- j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
- }
-
-/* Bytes for IM-filter part 1 (04): 00,C2,BB,A8,CB,81,A0,00 */
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xC2;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xA8;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xCB;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-/* Bytes for IM-filter part 2 (05): 40,00,00,0A,A4,33,E0,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x40;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0A;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xA4;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-/* Bytes for FRX-filter (08): 07,9B,ED,24,B2,A2,A0,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9B;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xED;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x24;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0xB2;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0xA2;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xA0;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-/* Bytes for FRR-filter (07): 0F,92,F2,B2,87,D2,30,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x92;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF2;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0xB2;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x87;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xD2;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x30;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-/* Bytes for AX-filter (0A): 1B,A5,DD,CA */
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x1B;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xA5;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-/* Bytes for AR-filter (09): E2,27,10,D6 */
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x27;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-/* Bytes for TH-filter part 1 (00): 80,2D,38,8B,D0,00,00,98 */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x2D;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x38;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x8B;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xD0;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-/* Bytes for TH-filter part 2 (01): 02,5A,53,F0,0B,5F,84,D4 */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x5A;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x53;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xF0;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x0B;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5F;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x84;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xD4;
-/* Bytes for TH-filter part 3 (02): 00,88,6A,A4,8F,52,F5,32 */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x6A;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0xA4;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x8F;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x52;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xF5;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x32;
-/* ; idle */
- /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-/* Levelmetering Ringing (0D):AA,35,0F,8E ; 25Hz 30V less possible? */
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-/* ;CR Registers */
- /* Config. Reg. 0 (filters) (cr0):FF */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-/* Config. Reg. 1 (dialing) (cr1):05 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-/* Config. Reg. 2 (caller ID) (cr2):04 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-/* Config. Reg. 3 (testloops) (cr3):00 ; */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-/* Config. Reg. 4 (analog gain) (cr4):02 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
- /* Config. Reg. 5 (Version) (cr5):02 */
- /* Config. Reg. 6 (Reserved) (cr6):00 */
- /* Config. Reg. 7 (Reserved) (cr7):00 */
- /* ;xr Registers */
- /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */
-
- j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */
- /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */
-
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */
- /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
-
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-/* Ext. Reg. 3 (DC Char) (xr3):36 ; */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36;
-/* Ext. Reg. 4 (Cadence) (xr4):00 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-/* Ext. Reg. 5 (Ring timer) (xr5):22 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-/* Ext. Reg. 6 (Power State) (xr6):00 */
- j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-/* Ext. Reg. 7 (Vdd) (xr7):46 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46; /* 0x46 ??? Should it be 0x00? */
- /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */
- /* 12,33,5A,C3 ; 770 Hz */
- /* 13,3C,5B,32 ; 852 Hz */
- /* 1D,1B,5C,CC ; 941 Hz */
-
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */
- /* EC,1D,52,22 ; 1336 Hz */
- /* AA,AC,51,D2 ; 1477 Hz */
- /* 9B,3B,51,25 ; 1633 Hz */
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-}
-
-
-static void DAA_Coeff_France(IXJ *j)
-{
- int i;
-
- j->daa_country = DAA_FRANCE;
- /*----------------------------------------------- */
- /* CAO */
- for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
- j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
- }
-
-/* Bytes for IM-filter part 1 (04): 02,A2,43,2C,22,AF,A0,00 */
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x02;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA2;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x43;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2C;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0x22;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xAF;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-/* Bytes for IM-filter part 2 (05): 67,CE,00,0C,22,33,E0,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x67;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xCE;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x2C;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x22;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-/* Bytes for FRX-filter (08): 07,9A,28,F6,23,4A,B0,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9A;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x28;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0xF6;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x23;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x4A;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xB0;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-/* Bytes for FRR-filter (07): 03,8F,F9,2F,9E,FA,20,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x2F;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x9E;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xFA;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-/* Bytes for AX-filter (0A): 16,B5,DD,CA */
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x16;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-/* Bytes for AR-filter (09): 52,C7,10,D6 */
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-/* Bytes for TH-filter part 1 (00): 00,42,48,81,A6,80,00,98 */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xA6;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-/* Bytes for TH-filter part 2 (01): 02,AC,2A,30,78,AC,8A,2C */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAC;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x30;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x78;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAC;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x8A;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x2C;
-/* Bytes for TH-filter part 3 (02): 00,88,DA,A5,22,BA,2C,45 */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0xA5;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x22;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x2C;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x45;
-/* ; idle */
- /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-/* Levelmetering Ringing (0D):32,45,B5,84 ; 50Hz 20V */
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84;
-/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-/* ;CR Registers */
- /* Config. Reg. 0 (filters) (cr0):FF */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-/* Config. Reg. 1 (dialing) (cr1):05 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-/* Config. Reg. 2 (caller ID) (cr2):04 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-/* Config. Reg. 3 (testloops) (cr3):00 ; */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-/* Config. Reg. 4 (analog gain) (cr4):02 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
- /* Config. Reg. 5 (Version) (cr5):02 */
- /* Config. Reg. 6 (Reserved) (cr6):00 */
- /* Config. Reg. 7 (Reserved) (cr7):00 */
- /* ;xr Registers */
- /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */
-
- j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */
- /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */
-
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */
- /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
-
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-/* Ext. Reg. 3 (DC Char) (xr3):36 ; */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36;
-/* Ext. Reg. 4 (Cadence) (xr4):00 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-/* Ext. Reg. 5 (Ring timer) (xr5):22 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-/* Ext. Reg. 6 (Power State) (xr6):00 */
- j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-/* Ext. Reg. 7 (Vdd) (xr7):46 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46; /* 0x46 ??? Should it be 0x00? */
- /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */
- /* 12,33,5A,C3 ; 770 Hz */
- /* 13,3C,5B,32 ; 852 Hz */
- /* 1D,1B,5C,CC ; 941 Hz */
-
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */
- /* EC,1D,52,22 ; 1336 Hz */
- /* AA,AC,51,D2 ; 1477 Hz */
- /* 9B,3B,51,25 ; 1633 Hz */
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-}
-
-
-static void DAA_Coeff_Germany(IXJ *j)
-{
- int i;
-
- j->daa_country = DAA_GERMANY;
- /*----------------------------------------------- */
- /* CAO */
- for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
- j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
- }
-
-/* Bytes for IM-filter part 1 (04): 00,CE,BB,B8,D2,81,B0,00 */
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xCE;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xB8;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xD2;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xB0;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-/* Bytes for IM-filter part 2 (05): 45,8F,00,0C,D2,3A,D0,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x45;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x8F;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0C;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xD2;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x3A;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xD0;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-/* Bytes for FRX-filter (08): 07,AA,E2,34,24,89,20,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xAA;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x24;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x89;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x20;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-/* Bytes for FRR-filter (07): 02,87,FA,37,9A,CA,B0,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x02;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xFA;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x37;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x9A;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCA;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-/* Bytes for AX-filter (0A): 72,D5,DD,CA */
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x72;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xD5;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-/* Bytes for AR-filter (09): 72,42,13,4B */
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x72;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x42;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x13;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0x4B;
-/* Bytes for TH-filter part 1 (00): 80,52,48,81,AD,80,00,98 */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAD;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-/* Bytes for TH-filter part 2 (01): 02,42,5A,20,E8,1A,81,27 */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x42;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x5A;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x20;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0xE8;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x1A;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x27;
-/* Bytes for TH-filter part 3 (02): 00,88,63,26,BD,4B,A3,C2 */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x63;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x26;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xBD;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x4B;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xA3;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xC2;
-/* ; (10K, 0.68uF) */
- /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3B;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x9B;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0xD4;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x1C;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xB3;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-/* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x13;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x42;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0xD4;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x73;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0xCA;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-/* Levelmetering Ringing (0D):B2,45,0F,8E */
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xB2;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-/* ;CR Registers */
- /* Config. Reg. 0 (filters) (cr0):FF ; all Filters enabled, CLK from ext. source */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-/* Config. Reg. 1 (dialing) (cr1):05 ; Manual Ring, Ring metering enabled */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-/* Config. Reg. 2 (caller ID) (cr2):04 ; Analog Gain 0dB, FSC internal */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-/* Config. Reg. 3 (testloops) (cr3):00 ; SEL Bit==0, HP-enabled */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-/* Config. Reg. 4 (analog gain) (cr4):02 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
- /* Config. Reg. 5 (Version) (cr5):02 */
- /* Config. Reg. 6 (Reserved) (cr6):00 */
- /* Config. Reg. 7 (Reserved) (cr7):00 */
- /* ;xr Registers */
- /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */
-
- j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */
- /* Ext. Reg. 1 (Interrupt enable) (xr1):1C ; Ring, CID, VDDOK Interrupts enabled */
-
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */
- /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
-
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-/* Ext. Reg. 3 (DC Char) (xr3):32 ; B-Filter Off==1, U0=3.5V, R=200Ohm */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x32;
-/* Ext. Reg. 4 (Cadence) (xr4):00 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-/* Ext. Reg. 5 (Ring timer) (xr5):22 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-/* Ext. Reg. 6 (Power State) (xr6):00 */
- j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-/* Ext. Reg. 7 (Vdd) (xr7):40 ; VDD=4.25 V */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */
- /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */
- /* 12,33,5A,C3 ; 770 Hz */
- /* 13,3C,5B,32 ; 852 Hz */
- /* 1D,1B,5C,CC ; 941 Hz */
-
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */
- /* EC,1D,52,22 ; 1336 Hz */
- /* AA,AC,51,D2 ; 1477 Hz */
- /* 9B,3B,51,25 ; 1633 Hz */
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-}
-
-
-static void DAA_Coeff_Australia(IXJ *j)
-{
- int i;
-
- j->daa_country = DAA_AUSTRALIA;
- /*----------------------------------------------- */
- /* CAO */
- for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
- j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
- }
-
-/* Bytes for IM-filter part 1 (04): 00,A3,AA,28,B3,82,D0,00 */
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA3;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xAA;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x28;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xB3;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x82;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xD0;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-/* Bytes for IM-filter part 2 (05): 70,96,00,09,32,6B,C0,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x70;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x96;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x09;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x6B;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xC0;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-/* Bytes for FRX-filter (08): 07,96,E2,34,32,9B,30,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x96;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x9B;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-/* Bytes for FRR-filter (07): 0F,9A,E9,2F,22,CC,A0,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x9A;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xE9;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x2F;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x22;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCC;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xA0;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-/* Bytes for AX-filter (0A): CB,45,DD,CA */
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0xCB;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0x45;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-/* Bytes for AR-filter (09): 1B,67,10,D6 */
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x1B;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x67;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-/* Bytes for TH-filter part 1 (00): 80,52,48,81,AF,80,00,98 */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAF;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-/* Bytes for TH-filter part 2 (01): 02,DB,52,B0,38,01,82,AC */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xDB;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x52;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xB0;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x38;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x01;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x82;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xAC;
-/* Bytes for TH-filter part 3 (02): 00,88,4A,3E,2C,3B,24,46 */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x4A;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x3E;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x2C;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x3B;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x24;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x46;
-/* ; idle */
- /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-/* Levelmetering Ringing (0D):32,45,B5,84 ; 50Hz 20V */
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84;
-/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-/* ;CR Registers */
- /* Config. Reg. 0 (filters) (cr0):FF */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-/* Config. Reg. 1 (dialing) (cr1):05 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-/* Config. Reg. 2 (caller ID) (cr2):04 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-/* Config. Reg. 3 (testloops) (cr3):00 ; */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-/* Config. Reg. 4 (analog gain) (cr4):02 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
- /* Config. Reg. 5 (Version) (cr5):02 */
- /* Config. Reg. 6 (Reserved) (cr6):00 */
- /* Config. Reg. 7 (Reserved) (cr7):00 */
- /* ;xr Registers */
- /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */
-
- j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */
- /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */
-
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */
- /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
-
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-/* Ext. Reg. 3 (DC Char) (xr3):2B ; */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x2B;
-/* Ext. Reg. 4 (Cadence) (xr4):00 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-/* Ext. Reg. 5 (Ring timer) (xr5):22 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-/* Ext. Reg. 6 (Power State) (xr6):00 */
- j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-/* Ext. Reg. 7 (Vdd) (xr7):40 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */
-
- /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */
- /* 12,33,5A,C3 ; 770 Hz */
- /* 13,3C,5B,32 ; 852 Hz */
- /* 1D,1B,5C,CC ; 941 Hz */
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-
- /* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */
- /* EC,1D,52,22 ; 1336 Hz */
- /* AA,AC,51,D2 ; 1477 Hz */
- /* 9B,3B,51,25 ; 1633 Hz */
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-}
-
-static void DAA_Coeff_Japan(IXJ *j)
-{
- int i;
-
- j->daa_country = DAA_JAPAN;
- /*----------------------------------------------- */
- /* CAO */
- for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
- j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
- }
-
-/* Bytes for IM-filter part 1 (04): 06,BD,E2,2D,BA,F9,A0,00 */
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x06;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xBD;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xE2;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2D;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xF9;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-/* Bytes for IM-filter part 2 (05): 6F,F7,00,0E,34,33,E0,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x6F;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xF7;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0E;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x34;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-/* Bytes for FRX-filter (08): 02,8F,68,77,9C,58,F0,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x02;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x8F;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x68;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x77;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x9C;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x58;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xF0;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-/* Bytes for FRR-filter (07): 03,8F,38,73,87,EA,20,08 */
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0x38;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x73;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x87;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xEA;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-/* Bytes for AX-filter (0A): 51,C5,DD,CA */
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x51;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xC5;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-/* Bytes for AR-filter (09): 25,A7,10,D6 */
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xA7;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-/* Bytes for TH-filter part 1 (00): 00,42,48,81,AE,80,00,98 */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAE;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-/* Bytes for TH-filter part 2 (01): 02,AB,2A,20,99,5B,89,28 */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAB;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x20;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5B;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x89;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x28;
-/* Bytes for TH-filter part 3 (02): 00,88,DA,25,34,C5,4C,BA */
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x25;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x34;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xC5;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x4C;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xBA;
-/* ; idle */
- /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-/* Levelmetering Ringing (0D):AA,35,0F,8E ; 25Hz 30V ????????? */
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-/* ;CR Registers */
- /* Config. Reg. 0 (filters) (cr0):FF */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-/* Config. Reg. 1 (dialing) (cr1):05 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-/* Config. Reg. 2 (caller ID) (cr2):04 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-/* Config. Reg. 3 (testloops) (cr3):00 ; */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-/* Config. Reg. 4 (analog gain) (cr4):02 */
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
- /* Config. Reg. 5 (Version) (cr5):02 */
- /* Config. Reg. 6 (Reserved) (cr6):00 */
- /* Config. Reg. 7 (Reserved) (cr7):00 */
- /* ;xr Registers */
- /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */
-
- j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */
- /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */
-
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */
- /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
-
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-/* Ext. Reg. 3 (DC Char) (xr3):22 ; */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x22;
-/* Ext. Reg. 4 (Cadence) (xr4):00 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-/* Ext. Reg. 5 (Ring timer) (xr5):22 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-/* Ext. Reg. 6 (Power State) (xr6):00 */
- j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-/* Ext. Reg. 7 (Vdd) (xr7):40 */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */
- /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */
- /* 12,33,5A,C3 ; 770 Hz */
- /* 13,3C,5B,32 ; 852 Hz */
- /* 1D,1B,5C,CC ; 941 Hz */
-
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */
- /* EC,1D,52,22 ; 1336 Hz */
- /* AA,AC,51,D2 ; 1477 Hz */
- /* 9B,3B,51,25 ; 1633 Hz */
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
- j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-}
-
-static s16 tone_table[][19] =
-{
- { /* f20_50[] 11 */
- 32538, /* A1 = 1.985962 */
- -32325, /* A2 = -0.986511 */
- -343, /* B2 = -0.010493 */
- 0, /* B1 = 0 */
- 343, /* B0 = 0.010493 */
- 32619, /* A1 = 1.990906 */
- -32520, /* A2 = -0.992462 */
- 19179, /* B2 = 0.585327 */
- -19178, /* B1 = -1.170593 */
- 19179, /* B0 = 0.585327 */
- 32723, /* A1 = 1.997314 */
- -32686, /* A2 = -0.997528 */
- 9973, /* B2 = 0.304352 */
- -9955, /* B1 = -0.607605 */
- 9973, /* B0 = 0.304352 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f133_200[] 12 */
- 32072, /* A1 = 1.95752 */
- -31896, /* A2 = -0.973419 */
- -435, /* B2 = -0.013294 */
- 0, /* B1 = 0 */
- 435, /* B0 = 0.013294 */
- 32188, /* A1 = 1.9646 */
- -32400, /* A2 = -0.98877 */
- 15139, /* B2 = 0.462036 */
- -14882, /* B1 = -0.908356 */
- 15139, /* B0 = 0.462036 */
- 32473, /* A1 = 1.981995 */
- -32524, /* A2 = -0.992584 */
- 23200, /* B2 = 0.708008 */
- -23113, /* B1 = -1.410706 */
- 23200, /* B0 = 0.708008 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f300 13 */
- 31769, /* A1 = -1.939026 */
- -32584, /* A2 = 0.994385 */
- -475, /* B2 = -0.014522 */
- 0, /* B1 = 0.000000 */
- 475, /* B0 = 0.014522 */
- 31789, /* A1 = -1.940247 */
- -32679, /* A2 = 0.997284 */
- 17280, /* B2 = 0.527344 */
- -16865, /* B1 = -1.029358 */
- 17280, /* B0 = 0.527344 */
- 31841, /* A1 = -1.943481 */
- -32681, /* A2 = 0.997345 */
- 543, /* B2 = 0.016579 */
- -525, /* B1 = -0.032097 */
- 543, /* B0 = 0.016579 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f300_420[] 14 */
- 30750, /* A1 = 1.876892 */
- -31212, /* A2 = -0.952515 */
- -804, /* B2 = -0.024541 */
- 0, /* B1 = 0 */
- 804, /* B0 = 0.024541 */
- 30686, /* A1 = 1.872925 */
- -32145, /* A2 = -0.980988 */
- 14747, /* B2 = 0.450043 */
- -13703, /* B1 = -0.836395 */
- 14747, /* B0 = 0.450043 */
- 31651, /* A1 = 1.931824 */
- -32321, /* A2 = -0.986389 */
- 24425, /* B2 = 0.745422 */
- -23914, /* B1 = -1.459595 */
- 24427, /* B0 = 0.745483 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f330 15 */
- 31613, /* A1 = -1.929565 */
- -32646, /* A2 = 0.996277 */
- -185, /* B2 = -0.005657 */
- 0, /* B1 = 0.000000 */
- 185, /* B0 = 0.005657 */
- 31620, /* A1 = -1.929932 */
- -32713, /* A2 = 0.998352 */
- 19253, /* B2 = 0.587585 */
- -18566, /* B1 = -1.133179 */
- 19253, /* B0 = 0.587585 */
- 31674, /* A1 = -1.933228 */
- -32715, /* A2 = 0.998413 */
- 2575, /* B2 = 0.078590 */
- -2495, /* B1 = -0.152283 */
- 2575, /* B0 = 0.078590 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f300_425[] 16 */
- 30741, /* A1 = 1.876282 */
- -31475, /* A2 = -0.960541 */
- -703, /* B2 = -0.021484 */
- 0, /* B1 = 0 */
- 703, /* B0 = 0.021484 */
- 30688, /* A1 = 1.873047 */
- -32248, /* A2 = -0.984161 */
- 14542, /* B2 = 0.443787 */
- -13523, /* B1 = -0.825439 */
- 14542, /* B0 = 0.443817 */
- 31494, /* A1 = 1.922302 */
- -32366, /* A2 = -0.987762 */
- 21577, /* B2 = 0.658508 */
- -21013, /* B1 = -1.282532 */
- 21577, /* B0 = 0.658508 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f330_440[] 17 */
- 30627, /* A1 = 1.869324 */
- -31338, /* A2 = -0.95636 */
- -843, /* B2 = -0.025749 */
- 0, /* B1 = 0 */
- 843, /* B0 = 0.025749 */
- 30550, /* A1 = 1.864685 */
- -32221, /* A2 = -0.983337 */
- 13594, /* B2 = 0.414886 */
- -12589, /* B1 = -0.768402 */
- 13594, /* B0 = 0.414886 */
- 31488, /* A1 = 1.921936 */
- -32358, /* A2 = -0.987518 */
- 24684, /* B2 = 0.753296 */
- -24029, /* B1 = -1.466614 */
- 24684, /* B0 = 0.753296 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f340 18 */
- 31546, /* A1 = -1.925476 */
- -32646, /* A2 = 0.996277 */
- -445, /* B2 = -0.013588 */
- 0, /* B1 = 0.000000 */
- 445, /* B0 = 0.013588 */
- 31551, /* A1 = -1.925781 */
- -32713, /* A2 = 0.998352 */
- 23884, /* B2 = 0.728882 */
- -22979, /* B1 = -1.402527 */
- 23884, /* B0 = 0.728882 */
- 31606, /* A1 = -1.929138 */
- -32715, /* A2 = 0.998413 */
- 863, /* B2 = 0.026367 */
- -835, /* B1 = -0.050985 */
- 863, /* B0 = 0.026367 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f350_400[] 19 */
- 31006, /* A1 = 1.892517 */
- -32029, /* A2 = -0.977448 */
- -461, /* B2 = -0.014096 */
- 0, /* B1 = 0 */
- 461, /* B0 = 0.014096 */
- 30999, /* A1 = 1.892029 */
- -32487, /* A2 = -0.991455 */
- 11325, /* B2 = 0.345612 */
- -10682, /* B1 = -0.651978 */
- 11325, /* B0 = 0.345612 */
- 31441, /* A1 = 1.919067 */
- -32526, /* A2 = -0.992615 */
- 24324, /* B2 = 0.74231 */
- -23535, /* B1 = -1.436523 */
- 24324, /* B0 = 0.74231 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f350_440[] */
- 30634, /* A1 = 1.869751 */
- -31533, /* A2 = -0.962341 */
- -680, /* B2 = -0.020782 */
- 0, /* B1 = 0 */
- 680, /* B0 = 0.020782 */
- 30571, /* A1 = 1.865906 */
- -32277, /* A2 = -0.985016 */
- 12894, /* B2 = 0.393524 */
- -11945, /* B1 = -0.729065 */
- 12894, /* B0 = 0.393524 */
- 31367, /* A1 = 1.91449 */
- -32379, /* A2 = -0.988129 */
- 23820, /* B2 = 0.726929 */
- -23104, /* B1 = -1.410217 */
- 23820, /* B0 = 0.726929 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f350_450[] */
- 30552, /* A1 = 1.864807 */
- -31434, /* A2 = -0.95929 */
- -690, /* B2 = -0.021066 */
- 0, /* B1 = 0 */
- 690, /* B0 = 0.021066 */
- 30472, /* A1 = 1.859924 */
- -32248, /* A2 = -0.984161 */
- 13385, /* B2 = 0.408478 */
- -12357, /* B1 = -0.754242 */
- 13385, /* B0 = 0.408478 */
- 31358, /* A1 = 1.914001 */
- -32366, /* A2 = -0.987732 */
- 26488, /* B2 = 0.80835 */
- -25692, /* B1 = -1.568176 */
- 26490, /* B0 = 0.808411 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f360 */
- 31397, /* A1 = -1.916321 */
- -32623, /* A2 = 0.995605 */
- -117, /* B2 = -0.003598 */
- 0, /* B1 = 0.000000 */
- 117, /* B0 = 0.003598 */
- 31403, /* A1 = -1.916687 */
- -32700, /* A2 = 0.997925 */
- 3388, /* B2 = 0.103401 */
- -3240, /* B1 = -0.197784 */
- 3388, /* B0 = 0.103401 */
- 31463, /* A1 = -1.920410 */
- -32702, /* A2 = 0.997986 */
- 13346, /* B2 = 0.407288 */
- -12863, /* B1 = -0.785126 */
- 13346, /* B0 = 0.407288 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f380_420[] */
- 30831, /* A1 = 1.881775 */
- -32064, /* A2 = -0.978546 */
- -367, /* B2 = -0.01122 */
- 0, /* B1 = 0 */
- 367, /* B0 = 0.01122 */
- 30813, /* A1 = 1.880737 */
- -32456, /* A2 = -0.990509 */
- 11068, /* B2 = 0.337769 */
- -10338, /* B1 = -0.631042 */
- 11068, /* B0 = 0.337769 */
- 31214, /* A1 = 1.905212 */
- -32491, /* A2 = -0.991577 */
- 16374, /* B2 = 0.499695 */
- -15781, /* B1 = -0.963196 */
- 16374, /* B0 = 0.499695 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f392 */
- 31152, /* A1 = -1.901428 */
- -32613, /* A2 = 0.995300 */
- -314, /* B2 = -0.009605 */
- 0, /* B1 = 0.000000 */
- 314, /* B0 = 0.009605 */
- 31156, /* A1 = -1.901672 */
- -32694, /* A2 = 0.997742 */
- 28847, /* B2 = 0.880371 */
- -2734, /* B1 = -0.166901 */
- 28847, /* B0 = 0.880371 */
- 31225, /* A1 = -1.905823 */
- -32696, /* A2 = 0.997803 */
- 462, /* B2 = 0.014108 */
- -442, /* B1 = -0.027019 */
- 462, /* B0 = 0.014108 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f400_425[] */
- 30836, /* A1 = 1.882141 */
- -32296, /* A2 = -0.985596 */
- -324, /* B2 = -0.009903 */
- 0, /* B1 = 0 */
- 324, /* B0 = 0.009903 */
- 30825, /* A1 = 1.881409 */
- -32570, /* A2 = -0.993958 */
- 16847, /* B2 = 0.51416 */
- -15792, /* B1 = -0.963898 */
- 16847, /* B0 = 0.51416 */
- 31106, /* A1 = 1.89856 */
- -32584, /* A2 = -0.994415 */
- 9579, /* B2 = 0.292328 */
- -9164, /* B1 = -0.559357 */
- 9579, /* B0 = 0.292328 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f400_440[] */
- 30702, /* A1 = 1.873962 */
- -32134, /* A2 = -0.980682 */
- -517, /* B2 = -0.015793 */
- 0, /* B1 = 0 */
- 517, /* B0 = 0.015793 */
- 30676, /* A1 = 1.872375 */
- -32520, /* A2 = -0.992462 */
- 8144, /* B2 = 0.24855 */
- -7596, /* B1 = -0.463684 */
- 8144, /* B0 = 0.24855 */
- 31084, /* A1 = 1.897217 */
- -32547, /* A2 = -0.993256 */
- 22713, /* B2 = 0.693176 */
- -21734, /* B1 = -1.326599 */
- 22713, /* B0 = 0.693176 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f400_450[] */
- 30613, /* A1 = 1.86853 */
- -32031, /* A2 = -0.977509 */
- -618, /* B2 = -0.018866 */
- 0, /* B1 = 0 */
- 618, /* B0 = 0.018866 */
- 30577, /* A1 = 1.866272 */
- -32491, /* A2 = -0.991577 */
- 9612, /* B2 = 0.293335 */
- -8935, /* B1 = -0.54541 */
- 9612, /* B0 = 0.293335 */
- 31071, /* A1 = 1.896484 */
- -32524, /* A2 = -0.992584 */
- 21596, /* B2 = 0.659058 */
- -20667, /* B1 = -1.261414 */
- 21596, /* B0 = 0.659058 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f420 */
- 30914, /* A1 = -1.886841 */
- -32584, /* A2 = 0.994385 */
- -426, /* B2 = -0.013020 */
- 0, /* B1 = 0.000000 */
- 426, /* B0 = 0.013020 */
- 30914, /* A1 = -1.886841 */
- -32679, /* A2 = 0.997314 */
- 17520, /* B2 = 0.534668 */
- -16471, /* B1 = -1.005310 */
- 17520, /* B0 = 0.534668 */
- 31004, /* A1 = -1.892334 */
- -32683, /* A2 = 0.997406 */
- 819, /* B2 = 0.025023 */
- -780, /* B1 = -0.047619 */
- 819, /* B0 = 0.025023 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
-#if 0
- { /* f425 */
- 30881, /* A1 = -1.884827 */
- -32603, /* A2 = 0.994965 */
- -496, /* B2 = -0.015144 */
- 0, /* B1 = 0.000000 */
- 496, /* B0 = 0.015144 */
- 30880, /* A1 = -1.884766 */
- -32692, /* A2 = 0.997711 */
- 24767, /* B2 = 0.755859 */
- -23290, /* B1 = -1.421509 */
- 24767, /* B0 = 0.755859 */
- 30967, /* A1 = -1.890076 */
- -32694, /* A2 = 0.997772 */
- 728, /* B2 = 0.022232 */
- -691, /* B1 = -0.042194 */
- 728, /* B0 = 0.022232 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
-#else
- {
- 30850,
- -32534,
- -504,
- 0,
- 504,
- 30831,
- -32669,
- 24303,
- -22080,
- 24303,
- 30994,
- -32673,
- 1905,
- -1811,
- 1905,
- 5,
- 129,
- 17,
- 0xff5
- },
-#endif
- { /* f425_450[] */
- 30646, /* A1 = 1.870544 */
- -32327, /* A2 = -0.986572 */
- -287, /* B2 = -0.008769 */
- 0, /* B1 = 0 */
- 287, /* B0 = 0.008769 */
- 30627, /* A1 = 1.869324 */
- -32607, /* A2 = -0.995087 */
- 13269, /* B2 = 0.404968 */
- -12376, /* B1 = -0.755432 */
- 13269, /* B0 = 0.404968 */
- 30924, /* A1 = 1.887512 */
- -32619, /* A2 = -0.995453 */
- 19950, /* B2 = 0.608826 */
- -18940, /* B1 = -1.156006 */
- 19950, /* B0 = 0.608826 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f425_475[] */
- 30396, /* A1 = 1.855225 */
- -32014, /* A2 = -0.97699 */
- -395, /* B2 = -0.012055 */
- 0, /* B1 = 0 */
- 395, /* B0 = 0.012055 */
- 30343, /* A1 = 1.85199 */
- -32482, /* A2 = -0.991302 */
- 17823, /* B2 = 0.543945 */
- -16431, /* B1 = -1.002869 */
- 17823, /* B0 = 0.543945 */
- 30872, /* A1 = 1.884338 */
- -32516, /* A2 = -0.99231 */
- 18124, /* B2 = 0.553101 */
- -17246, /* B1 = -1.052673 */
- 18124, /* B0 = 0.553101 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f435 */
- 30796, /* A1 = -1.879639 */
- -32603, /* A2 = 0.994965 */
- -254, /* B2 = -0.007762 */
- 0, /* B1 = 0.000000 */
- 254, /* B0 = 0.007762 */
- 30793, /* A1 = -1.879456 */
- -32692, /* A2 = 0.997711 */
- 18934, /* B2 = 0.577820 */
- -17751, /* B1 = -1.083496 */
- 18934, /* B0 = 0.577820 */
- 30882, /* A1 = -1.884888 */
- -32694, /* A2 = 0.997772 */
- 1858, /* B2 = 0.056713 */
- -1758, /* B1 = -0.107357 */
- 1858, /* B0 = 0.056713 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f440_450[] */
- 30641, /* A1 = 1.870239 */
- -32458, /* A2 = -0.99057 */
- -155, /* B2 = -0.004735 */
- 0, /* B1 = 0 */
- 155, /* B0 = 0.004735 */
- 30631, /* A1 = 1.869568 */
- -32630, /* A2 = -0.995789 */
- 11453, /* B2 = 0.349548 */
- -10666, /* B1 = -0.651001 */
- 11453, /* B0 = 0.349548 */
- 30810, /* A1 = 1.880554 */
- -32634, /* A2 = -0.995941 */
- 12237, /* B2 = 0.373474 */
- -11588, /* B1 = -0.707336 */
- 12237, /* B0 = 0.373474 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f440_480[] */
- 30367, /* A1 = 1.853455 */
- -32147, /* A2 = -0.981079 */
- -495, /* B2 = -0.015113 */
- 0, /* B1 = 0 */
- 495, /* B0 = 0.015113 */
- 30322, /* A1 = 1.850769 */
- -32543, /* A2 = -0.993134 */
- 10031, /* B2 = 0.306152 */
- -9252, /* B1 = -0.564728 */
- 10031, /* B0 = 0.306152 */
- 30770, /* A1 = 1.878052 */
- -32563, /* A2 = -0.993774 */
- 22674, /* B2 = 0.691956 */
- -21465, /* B1 = -1.31012 */
- 22674, /* B0 = 0.691956 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f445 */
- 30709, /* A1 = -1.874329 */
- -32603, /* A2 = 0.994965 */
- -83, /* B2 = -0.002545 */
- 0, /* B1 = 0.000000 */
- 83, /* B0 = 0.002545 */
- 30704, /* A1 = -1.874084 */
- -32692, /* A2 = 0.997711 */
- 10641, /* B2 = 0.324738 */
- -9947, /* B1 = -0.607147 */
- 10641, /* B0 = 0.324738 */
- 30796, /* A1 = -1.879639 */
- -32694, /* A2 = 0.997772 */
- 10079, /* B2 = 0.307587 */
- 9513, /* B1 = 0.580688 */
- 10079, /* B0 = 0.307587 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f450 */
- 30664, /* A1 = -1.871643 */
- -32603, /* A2 = 0.994965 */
- -164, /* B2 = -0.005029 */
- 0, /* B1 = 0.000000 */
- 164, /* B0 = 0.005029 */
- 30661, /* A1 = -1.871399 */
- -32692, /* A2 = 0.997711 */
- 15294, /* B2 = 0.466736 */
- -14275, /* B1 = -0.871307 */
- 15294, /* B0 = 0.466736 */
- 30751, /* A1 = -1.876953 */
- -32694, /* A2 = 0.997772 */
- 3548, /* B2 = 0.108284 */
- -3344, /* B1 = -0.204155 */
- 3548, /* B0 = 0.108284 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f452 */
- 30653, /* A1 = -1.870911 */
- -32615, /* A2 = 0.995361 */
- -209, /* B2 = -0.006382 */
- 0, /* B1 = 0.000000 */
- 209, /* B0 = 0.006382 */
- 30647, /* A1 = -1.870605 */
- -32702, /* A2 = 0.997986 */
- 18971, /* B2 = 0.578979 */
- -17716, /* B1 = -1.081299 */
- 18971, /* B0 = 0.578979 */
- 30738, /* A1 = -1.876099 */
- -32702, /* A2 = 0.998016 */
- 2967, /* B2 = 0.090561 */
- -2793, /* B1 = -0.170502 */
- 2967, /* B0 = 0.090561 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f475 */
- 30437, /* A1 = -1.857727 */
- -32603, /* A2 = 0.994965 */
- -264, /* B2 = -0.008062 */
- 0, /* B1 = 0.000000 */
- 264, /* B0 = 0.008062 */
- 30430, /* A1 = -1.857300 */
- -32692, /* A2 = 0.997711 */
- 21681, /* B2 = 0.661682 */
- -20082, /* B1 = -1.225708 */
- 21681, /* B0 = 0.661682 */
- 30526, /* A1 = -1.863220 */
- -32694, /* A2 = 0.997742 */
- 1559, /* B2 = 0.047600 */
- -1459, /* B1 = -0.089096 */
- 1559, /* B0 = 0.047600 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f480_620[] */
- 28975, /* A1 = 1.768494 */
- -30955, /* A2 = -0.944672 */
- -1026, /* B2 = -0.03133 */
- 0, /* B1 = 0 */
- 1026, /* B0 = 0.03133 */
- 28613, /* A1 = 1.746399 */
- -32089, /* A2 = -0.979309 */
- 14214, /* B2 = 0.433807 */
- -12202, /* B1 = -0.744812 */
- 14214, /* B0 = 0.433807 */
- 30243, /* A1 = 1.845947 */
- -32238, /* A2 = -0.983856 */
- 24825, /* B2 = 0.757629 */
- -23402, /* B1 = -1.428345 */
- 24825, /* B0 = 0.757629 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f494 */
- 30257, /* A1 = -1.846741 */
- -32605, /* A2 = 0.995056 */
- -249, /* B2 = -0.007625 */
- 0, /* B1 = 0.000000 */
- 249, /* B0 = 0.007625 */
- 30247, /* A1 = -1.846191 */
- -32694, /* A2 = 0.997772 */
- 18088, /* B2 = 0.552002 */
- -16652, /* B1 = -1.016418 */
- 18088, /* B0 = 0.552002 */
- 30348, /* A1 = -1.852295 */
- -32696, /* A2 = 0.997803 */
- 2099, /* B2 = 0.064064 */
- -1953, /* B1 = -0.119202 */
- 2099, /* B0 = 0.064064 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f500 */
- 30202, /* A1 = -1.843431 */
- -32624, /* A2 = 0.995622 */
- -413, /* B2 = -0.012622 */
- 0, /* B1 = 0.000000 */
- 413, /* B0 = 0.012622 */
- 30191, /* A1 = -1.842721 */
- -32714, /* A2 = 0.998364 */
- 25954, /* B2 = 0.792057 */
- -23890, /* B1 = -1.458131 */
- 25954, /* B0 = 0.792057 */
- 30296, /* A1 = -1.849172 */
- -32715, /* A2 = 0.998397 */
- 2007, /* B2 = 0.061264 */
- -1860, /* B1 = -0.113568 */
- 2007, /* B0 = 0.061264 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f520 */
- 30001, /* A1 = -1.831116 */
- -32613, /* A2 = 0.995270 */
- -155, /* B2 = -0.004750 */
- 0, /* B1 = 0.000000 */
- 155, /* B0 = 0.004750 */
- 29985, /* A1 = -1.830200 */
- -32710, /* A2 = 0.998260 */
- 6584, /* B2 = 0.200928 */
- -6018, /* B1 = -0.367355 */
- 6584, /* B0 = 0.200928 */
- 30105, /* A1 = -1.837524 */
- -32712, /* A2 = 0.998291 */
- 23812, /* B2 = 0.726685 */
- -21936, /* B1 = -1.338928 */
- 23812, /* B0 = 0.726685 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f523 */
- 29964, /* A1 = -1.828918 */
- -32601, /* A2 = 0.994904 */
- -101, /* B2 = -0.003110 */
- 0, /* B1 = 0.000000 */
- 101, /* B0 = 0.003110 */
- 29949, /* A1 = -1.827942 */
- -32700, /* A2 = 0.997925 */
- 11041, /* B2 = 0.336975 */
- -10075, /* B1 = -0.614960 */
- 11041, /* B0 = 0.336975 */
- 30070, /* A1 = -1.835388 */
- -32702, /* A2 = 0.997986 */
- 16762, /* B2 = 0.511536 */
- -15437, /* B1 = -0.942230 */
- 16762, /* B0 = 0.511536 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f525 */
- 29936, /* A1 = -1.827209 */
- -32584, /* A2 = 0.994415 */
- -91, /* B2 = -0.002806 */
- 0, /* B1 = 0.000000 */
- 91, /* B0 = 0.002806 */
- 29921, /* A1 = -1.826233 */
- -32688, /* A2 = 0.997559 */
- 11449, /* B2 = 0.349396 */
- -10426, /* B1 = -0.636383 */
- 11449, /* B0 = 0.349396 */
- 30045, /* A1 = -1.833862 */
- -32688, /* A2 = 0.997589 */
- 13055, /* B2 = 0.398407 */
- -12028, /* B1 = -0.734161 */
- 13055, /* B0 = 0.398407 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f540_660[] */
- 28499, /* A1 = 1.739441 */
- -31129, /* A2 = -0.949982 */
- -849, /* B2 = -0.025922 */
- 0, /* B1 = 0 */
- 849, /* B0 = 0.025922 */
- 28128, /* A1 = 1.716797 */
- -32130, /* A2 = -0.98056 */
- 14556, /* B2 = 0.444214 */
- -12251, /* B1 = -0.747772 */
- 14556, /* B0 = 0.444244 */
- 29667, /* A1 = 1.81073 */
- -32244, /* A2 = -0.984039 */
- 23038, /* B2 = 0.703064 */
- -21358, /* B1 = -1.303589 */
- 23040, /* B0 = 0.703125 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f587 */
- 29271, /* A1 = -1.786560 */
- -32599, /* A2 = 0.994873 */
- -490, /* B2 = -0.014957 */
- 0, /* B1 = 0.000000 */
- 490, /* B0 = 0.014957 */
- 29246, /* A1 = -1.785095 */
- -32700, /* A2 = 0.997925 */
- 28961, /* B2 = 0.883850 */
- -25796, /* B1 = -1.574463 */
- 28961, /* B0 = 0.883850 */
- 29383, /* A1 = -1.793396 */
- -32700, /* A2 = 0.997955 */
- 1299, /* B2 = 0.039650 */
- -1169, /* B1 = -0.071396 */
- 1299, /* B0 = 0.039650 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f590 */
- 29230, /* A1 = -1.784058 */
- -32584, /* A2 = 0.994415 */
- -418, /* B2 = -0.012757 */
- 0, /* B1 = 0.000000 */
- 418, /* B0 = 0.012757 */
- 29206, /* A1 = -1.782593 */
- -32688, /* A2 = 0.997559 */
- 36556, /* B2 = 1.115601 */
- -32478, /* B1 = -1.982300 */
- 36556, /* B0 = 1.115601 */
- 29345, /* A1 = -1.791077 */
- -32688, /* A2 = 0.997589 */
- 897, /* B2 = 0.027397 */
- -808, /* B1 = -0.049334 */
- 897, /* B0 = 0.027397 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f600 */
- 29116, /* A1 = -1.777100 */
- -32603, /* A2 = 0.994965 */
- -165, /* B2 = -0.005039 */
- 0, /* B1 = 0.000000 */
- 165, /* B0 = 0.005039 */
- 29089, /* A1 = -1.775452 */
- -32708, /* A2 = 0.998199 */
- 6963, /* B2 = 0.212494 */
- -6172, /* B1 = -0.376770 */
- 6963, /* B0 = 0.212494 */
- 29237, /* A1 = -1.784485 */
- -32710, /* A2 = 0.998230 */
- 24197, /* B2 = 0.738464 */
- -21657, /* B1 = -1.321899 */
- 24197, /* B0 = 0.738464 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f660 */
- 28376, /* A1 = -1.731934 */
- -32567, /* A2 = 0.993896 */
- -363, /* B2 = -0.011102 */
- 0, /* B1 = 0.000000 */
- 363, /* B0 = 0.011102 */
- 28337, /* A1 = -1.729614 */
- -32683, /* A2 = 0.997434 */
- 21766, /* B2 = 0.664246 */
- -18761, /* B1 = -1.145081 */
- 21766, /* B0 = 0.664246 */
- 28513, /* A1 = -1.740356 */
- -32686, /* A2 = 0.997498 */
- 2509, /* B2 = 0.076584 */
- -2196, /* B1 = -0.134041 */
- 2509, /* B0 = 0.076584 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f700 */
- 27844, /* A1 = -1.699463 */
- -32563, /* A2 = 0.993744 */
- -366, /* B2 = -0.011187 */
- 0, /* B1 = 0.000000 */
- 366, /* B0 = 0.011187 */
- 27797, /* A1 = -1.696655 */
- -32686, /* A2 = 0.997498 */
- 22748, /* B2 = 0.694214 */
- -19235, /* B1 = -1.174072 */
- 22748, /* B0 = 0.694214 */
- 27995, /* A1 = -1.708740 */
- -32688, /* A2 = 0.997559 */
- 2964, /* B2 = 0.090477 */
- -2546, /* B1 = -0.155449 */
- 2964, /* B0 = 0.090477 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f740 */
- 27297, /* A1 = -1.666077 */
- -32551, /* A2 = 0.993408 */
- -345, /* B2 = -0.010540 */
- 0, /* B1 = 0.000000 */
- 345, /* B0 = 0.010540 */
- 27240, /* A1 = -1.662598 */
- -32683, /* A2 = 0.997406 */
- 22560, /* B2 = 0.688477 */
- -18688, /* B1 = -1.140625 */
- 22560, /* B0 = 0.688477 */
- 27461, /* A1 = -1.676147 */
- -32684, /* A2 = 0.997467 */
- 3541, /* B2 = 0.108086 */
- -2985, /* B1 = -0.182220 */
- 3541, /* B0 = 0.108086 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f750 */
- 27155, /* A1 = -1.657410 */
- -32551, /* A2 = 0.993408 */
- -462, /* B2 = -0.014117 */
- 0, /* B1 = 0.000000 */
- 462, /* B0 = 0.014117 */
- 27097, /* A1 = -1.653870 */
- -32683, /* A2 = 0.997406 */
- 32495, /* B2 = 0.991699 */
- -26776, /* B1 = -1.634338 */
- 32495, /* B0 = 0.991699 */
- 27321, /* A1 = -1.667542 */
- -32684, /* A2 = 0.997467 */
- 1835, /* B2 = 0.056007 */
- -1539, /* B1 = -0.093948 */
- 1835, /* B0 = 0.056007 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f750_1450[] */
- 19298, /* A1 = 1.177917 */
- -24471, /* A2 = -0.746796 */
- -4152, /* B2 = -0.126709 */
- 0, /* B1 = 0 */
- 4152, /* B0 = 0.126709 */
- 12902, /* A1 = 0.787476 */
- -29091, /* A2 = -0.887817 */
- 12491, /* B2 = 0.38121 */
- -1794, /* B1 = -0.109528 */
- 12494, /* B0 = 0.381317 */
- 26291, /* A1 = 1.604736 */
- -30470, /* A2 = -0.929901 */
- 28859, /* B2 = 0.880737 */
- -26084, /* B1 = -1.592102 */
- 28861, /* B0 = 0.880798 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f770 */
- 26867, /* A1 = -1.639832 */
- -32551, /* A2 = 0.993408 */
- -123, /* B2 = -0.003755 */
- 0, /* B1 = 0.000000 */
- 123, /* B0 = 0.003755 */
- 26805, /* A1 = -1.636108 */
- -32683, /* A2 = 0.997406 */
- 17297, /* B2 = 0.527863 */
- -14096, /* B1 = -0.860382 */
- 17297, /* B0 = 0.527863 */
- 27034, /* A1 = -1.650085 */
- -32684, /* A2 = 0.997467 */
- 12958, /* B2 = 0.395477 */
- -10756, /* B1 = -0.656525 */
- 12958, /* B0 = 0.395477 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f800 */
- 26413, /* A1 = -1.612122 */
- -32547, /* A2 = 0.993286 */
- -223, /* B2 = -0.006825 */
- 0, /* B1 = 0.000000 */
- 223, /* B0 = 0.006825 */
- 26342, /* A1 = -1.607849 */
- -32686, /* A2 = 0.997498 */
- 6391, /* B2 = 0.195053 */
- -5120, /* B1 = -0.312531 */
- 6391, /* B0 = 0.195053 */
- 26593, /* A1 = -1.623108 */
- -32688, /* A2 = 0.997559 */
- 23681, /* B2 = 0.722717 */
- -19328, /* B1 = -1.179688 */
- 23681, /* B0 = 0.722717 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f816 */
- 26168, /* A1 = -1.597209 */
- -32528, /* A2 = 0.992706 */
- -235, /* B2 = -0.007182 */
- 0, /* B1 = 0.000000 */
- 235, /* B0 = 0.007182 */
- 26092, /* A1 = -1.592590 */
- -32675, /* A2 = 0.997192 */
- 20823, /* B2 = 0.635498 */
- -16510, /* B1 = -1.007751 */
- 20823, /* B0 = 0.635498 */
- 26363, /* A1 = -1.609070 */
- -32677, /* A2 = 0.997253 */
- 6739, /* B2 = 0.205688 */
- -5459, /* B1 = -0.333206 */
- 6739, /* B0 = 0.205688 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f850 */
- 25641, /* A1 = -1.565063 */
- -32536, /* A2 = 0.992950 */
- -121, /* B2 = -0.003707 */
- 0, /* B1 = 0.000000 */
- 121, /* B0 = 0.003707 */
- 25560, /* A1 = -1.560059 */
- -32684, /* A2 = 0.997437 */
- 18341, /* B2 = 0.559753 */
- -14252, /* B1 = -0.869904 */
- 18341, /* B0 = 0.559753 */
- 25837, /* A1 = -1.577026 */
- -32684, /* A2 = 0.997467 */
- 16679, /* B2 = 0.509003 */
- -13232, /* B1 = -0.807648 */
- 16679, /* B0 = 0.509003 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f857_1645[] */
- 16415, /* A1 = 1.001953 */
- -23669, /* A2 = -0.722321 */
- -4549, /* B2 = -0.138847 */
- 0, /* B1 = 0 */
- 4549, /* B0 = 0.138847 */
- 8456, /* A1 = 0.516174 */
- -28996, /* A2 = -0.884918 */
- 13753, /* B2 = 0.419724 */
- -12, /* B1 = -0.000763 */
- 13757, /* B0 = 0.419846 */
- 24632, /* A1 = 1.503418 */
- -30271, /* A2 = -0.923828 */
- 29070, /* B2 = 0.887146 */
- -25265, /* B1 = -1.542114 */
- 29073, /* B0 = 0.887268 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f900 */
- 24806, /* A1 = -1.514099 */
- -32501, /* A2 = 0.991852 */
- -326, /* B2 = -0.009969 */
- 0, /* B1 = 0.000000 */
- 326, /* B0 = 0.009969 */
- 24709, /* A1 = -1.508118 */
- -32659, /* A2 = 0.996674 */
- 20277, /* B2 = 0.618835 */
- -15182, /* B1 = -0.926636 */
- 20277, /* B0 = 0.618835 */
- 25022, /* A1 = -1.527222 */
- -32661, /* A2 = 0.996735 */
- 4320, /* B2 = 0.131836 */
- -3331, /* B1 = -0.203339 */
- 4320, /* B0 = 0.131836 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f900_1300[] */
- 19776, /* A1 = 1.207092 */
- -27437, /* A2 = -0.837341 */
- -2666, /* B2 = -0.081371 */
- 0, /* B1 = 0 */
- 2666, /* B0 = 0.081371 */
- 16302, /* A1 = 0.995026 */
- -30354, /* A2 = -0.926361 */
- 10389, /* B2 = 0.317062 */
- -3327, /* B1 = -0.203064 */
- 10389, /* B0 = 0.317062 */
- 24299, /* A1 = 1.483154 */
- -30930, /* A2 = -0.943909 */
- 25016, /* B2 = 0.763428 */
- -21171, /* B1 = -1.292236 */
- 25016, /* B0 = 0.763428 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f935_1215[] */
- 20554, /* A1 = 1.254517 */
- -28764, /* A2 = -0.877838 */
- -2048, /* B2 = -0.062515 */
- 0, /* B1 = 0 */
- 2048, /* B0 = 0.062515 */
- 18209, /* A1 = 1.11145 */
- -30951, /* A2 = -0.94458 */
- 9390, /* B2 = 0.286575 */
- -3955, /* B1 = -0.241455 */
- 9390, /* B0 = 0.286575 */
- 23902, /* A1 = 1.458923 */
- -31286, /* A2 = -0.954803 */
- 23252, /* B2 = 0.709595 */
- -19132, /* B1 = -1.167725 */
- 23252, /* B0 = 0.709595 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f941_1477[] */
- 17543, /* A1 = 1.07074 */
- -26220, /* A2 = -0.800201 */
- -3298, /* B2 = -0.100647 */
- 0, /* B1 = 0 */
- 3298, /* B0 = 0.100647 */
- 12423, /* A1 = 0.75827 */
- -30036, /* A2 = -0.916626 */
- 12651, /* B2 = 0.386078 */
- -2444, /* B1 = -0.14917 */
- 12653, /* B0 = 0.386154 */
- 23518, /* A1 = 1.435425 */
- -30745, /* A2 = -0.938293 */
- 27282, /* B2 = 0.832581 */
- -22529, /* B1 = -1.375122 */
- 27286, /* B0 = 0.832703 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f942 */
- 24104, /* A1 = -1.471252 */
- -32507, /* A2 = 0.992065 */
- -351, /* B2 = -0.010722 */
- 0, /* B1 = 0.000000 */
- 351, /* B0 = 0.010722 */
- 23996, /* A1 = -1.464600 */
- -32671, /* A2 = 0.997040 */
- 22848, /* B2 = 0.697266 */
- -16639, /* B1 = -1.015564 */
- 22848, /* B0 = 0.697266 */
- 24332, /* A1 = -1.485168 */
- -32673, /* A2 = 0.997101 */
- 4906, /* B2 = 0.149727 */
- -3672, /* B1 = -0.224174 */
- 4906, /* B0 = 0.149727 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f950 */
- 23967, /* A1 = -1.462830 */
- -32507, /* A2 = 0.992065 */
- -518, /* B2 = -0.015821 */
- 0, /* B1 = 0.000000 */
- 518, /* B0 = 0.015821 */
- 23856, /* A1 = -1.456055 */
- -32671, /* A2 = 0.997040 */
- 26287, /* B2 = 0.802246 */
- -19031, /* B1 = -1.161560 */
- 26287, /* B0 = 0.802246 */
- 24195, /* A1 = -1.476746 */
- -32673, /* A2 = 0.997101 */
- 2890, /* B2 = 0.088196 */
- -2151, /* B1 = -0.131317 */
- 2890, /* B0 = 0.088196 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f950_1400[] */
- 18294, /* A1 = 1.116638 */
- -26962, /* A2 = -0.822845 */
- -2914, /* B2 = -0.088936 */
- 0, /* B1 = 0 */
- 2914, /* B0 = 0.088936 */
- 14119, /* A1 = 0.861786 */
- -30227, /* A2 = -0.922455 */
- 11466, /* B2 = 0.349945 */
- -2833, /* B1 = -0.172943 */
- 11466, /* B0 = 0.349945 */
- 23431, /* A1 = 1.430115 */
- -30828, /* A2 = -0.940796 */
- 25331, /* B2 = 0.773071 */
- -20911, /* B1 = -1.276367 */
- 25331, /* B0 = 0.773071 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f975 */
- 23521, /* A1 = -1.435608 */
- -32489, /* A2 = 0.991516 */
- -193, /* B2 = -0.005915 */
- 0, /* B1 = 0.000000 */
- 193, /* B0 = 0.005915 */
- 23404, /* A1 = -1.428467 */
- -32655, /* A2 = 0.996582 */
- 17740, /* B2 = 0.541412 */
- -12567, /* B1 = -0.767029 */
- 17740, /* B0 = 0.541412 */
- 23753, /* A1 = -1.449829 */
- -32657, /* A2 = 0.996613 */
- 9090, /* B2 = 0.277405 */
- -6662, /* B1 = -0.406647 */
- 9090, /* B0 = 0.277405 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1000 */
- 23071, /* A1 = -1.408203 */
- -32489, /* A2 = 0.991516 */
- -293, /* B2 = -0.008965 */
- 0, /* B1 = 0.000000 */
- 293, /* B0 = 0.008965 */
- 22951, /* A1 = -1.400818 */
- -32655, /* A2 = 0.996582 */
- 5689, /* B2 = 0.173645 */
- -3951, /* B1 = -0.241150 */
- 5689, /* B0 = 0.173645 */
- 23307, /* A1 = -1.422607 */
- -32657, /* A2 = 0.996613 */
- 18692, /* B2 = 0.570435 */
- -13447, /* B1 = -0.820770 */
- 18692, /* B0 = 0.570435 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1020 */
- 22701, /* A1 = -1.385620 */
- -32474, /* A2 = 0.991058 */
- -292, /* B2 = -0.008933 */
- 0, /*163840 , B1 = 10.000000 */
- 292, /* B0 = 0.008933 */
- 22564, /* A1 = -1.377258 */
- -32655, /* A2 = 0.996552 */
- 20756, /* B2 = 0.633423 */
- -14176, /* B1 = -0.865295 */
- 20756, /* B0 = 0.633423 */
- 22960, /* A1 = -1.401428 */
- -32657, /* A2 = 0.996613 */
- 6520, /* B2 = 0.198990 */
- -4619, /* B1 = -0.281937 */
- 6520, /* B0 = 0.198990 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1050 */
- 22142, /* A1 = -1.351501 */
- -32474, /* A2 = 0.991058 */
- -147, /* B2 = -0.004493 */
- 0, /* B1 = 0.000000 */
- 147, /* B0 = 0.004493 */
- 22000, /* A1 = -1.342834 */
- -32655, /* A2 = 0.996552 */
- 15379, /* B2 = 0.469360 */
- -10237, /* B1 = -0.624847 */
- 15379, /* B0 = 0.469360 */
- 22406, /* A1 = -1.367554 */
- -32657, /* A2 = 0.996613 */
- 17491, /* B2 = 0.533783 */
- -12096, /* B1 = -0.738312 */
- 17491, /* B0 = 0.533783 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1100_1750[] */
- 12973, /* A1 = 0.79184 */
- -24916, /* A2 = -0.760376 */
- 6655, /* B2 = 0.203102 */
- 367, /* B1 = 0.0224 */
- 6657, /* B0 = 0.203171 */
- 5915, /* A1 = 0.361053 */
- -29560, /* A2 = -0.90213 */
- -7777, /* B2 = -0.23735 */
- 0, /* B1 = 0 */
- 7777, /* B0 = 0.23735 */
- 20510, /* A1 = 1.251892 */
- -30260, /* A2 = -0.923462 */
- 26662, /* B2 = 0.81366 */
- -20573, /* B1 = -1.255737 */
- 26668, /* B0 = 0.813843 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1140 */
- 20392, /* A1 = -1.244629 */
- -32460, /* A2 = 0.990601 */
- -270, /* B2 = -0.008240 */
- 0, /* B1 = 0.000000 */
- 270, /* B0 = 0.008240 */
- 20218, /* A1 = -1.234009 */
- -32655, /* A2 = 0.996582 */
- 21337, /* B2 = 0.651154 */
- -13044, /* B1 = -0.796143 */
- 21337, /* B0 = 0.651154 */
- 20684, /* A1 = -1.262512 */
- -32657, /* A2 = 0.996643 */
- 8572, /* B2 = 0.261612 */
- -5476, /* B1 = -0.334244 */
- 8572, /* B0 = 0.261612 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1200 */
- 19159, /* A1 = -1.169373 */
- -32456, /* A2 = 0.990509 */
- -335, /* B2 = -0.010252 */
- 0, /* B1 = 0.000000 */
- 335, /* B0 = 0.010252 */
- 18966, /* A1 = -1.157593 */
- -32661, /* A2 = 0.996735 */
- 6802, /* B2 = 0.207588 */
- -3900, /* B1 = -0.238098 */
- 6802, /* B0 = 0.207588 */
- 19467, /* A1 = -1.188232 */
- -32661, /* A2 = 0.996765 */
- 25035, /* B2 = 0.764008 */
- -15049, /* B1 = -0.918579 */
- 25035, /* B0 = 0.764008 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1209 */
- 18976, /* A1 = -1.158264 */
- -32439, /* A2 = 0.989990 */
- -183, /* B2 = -0.005588 */
- 0, /* B1 = 0.000000 */
- 183, /* B0 = 0.005588 */
- 18774, /* A1 = -1.145874 */
- -32650, /* A2 = 0.996429 */
- 15468, /* B2 = 0.472076 */
- -8768, /* B1 = -0.535217 */
- 15468, /* B0 = 0.472076 */
- 19300, /* A1 = -1.177979 */
- -32652, /* A2 = 0.996490 */
- 19840, /* B2 = 0.605499 */
- -11842, /* B1 = -0.722809 */
- 19840, /* B0 = 0.605499 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1330 */
- 16357, /* A1 = -0.998413 */
- -32368, /* A2 = 0.987793 */
- -217, /* B2 = -0.006652 */
- 0, /* B1 = 0.000000 */
- 217, /* B0 = 0.006652 */
- 16107, /* A1 = -0.983126 */
- -32601, /* A2 = 0.994904 */
- 11602, /* B2 = 0.354065 */
- -5555, /* B1 = -0.339111 */
- 11602, /* B0 = 0.354065 */
- 16722, /* A1 = -1.020630 */
- -32603, /* A2 = 0.994965 */
- 15574, /* B2 = 0.475311 */
- -8176, /* B1 = -0.499069 */
- 15574, /* B0 = 0.475311 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1336 */
- 16234, /* A1 = -0.990875 */
- 32404, /* A2 = -0.988922 */
- -193, /* B2 = -0.005908 */
- 0, /* B1 = 0.000000 */
- 193, /* B0 = 0.005908 */
- 15986, /* A1 = -0.975769 */
- -32632, /* A2 = 0.995880 */
- 18051, /* B2 = 0.550903 */
- -8658, /* B1 = -0.528473 */
- 18051, /* B0 = 0.550903 */
- 16591, /* A1 = -1.012695 */
- -32634, /* A2 = 0.995941 */
- 15736, /* B2 = 0.480240 */
- -8125, /* B1 = -0.495926 */
- 15736, /* B0 = 0.480240 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1366 */
- 15564, /* A1 = -0.949982 */
- -32404, /* A2 = 0.988922 */
- -269, /* B2 = -0.008216 */
- 0, /* B1 = 0.000000 */
- 269, /* B0 = 0.008216 */
- 15310, /* A1 = -0.934479 */
- -32632, /* A2 = 0.995880 */
- 10815, /* B2 = 0.330063 */
- -4962, /* B1 = -0.302887 */
- 10815, /* B0 = 0.330063 */
- 15924, /* A1 = -0.971924 */
- -32634, /* A2 = 0.995941 */
- 18880, /* B2 = 0.576172 */
- -9364, /* B1 = -0.571594 */
- 18880, /* B0 = 0.576172 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1380 */
- 15247, /* A1 = -0.930603 */
- -32397, /* A2 = 0.988708 */
- -244, /* B2 = -0.007451 */
- 0, /* B1 = 0.000000 */
- 244, /* B0 = 0.007451 */
- 14989, /* A1 = -0.914886 */
- -32627, /* A2 = 0.995697 */
- 18961, /* B2 = 0.578644 */
- -8498, /* B1 = -0.518707 */
- 18961, /* B0 = 0.578644 */
- 15608, /* A1 = -0.952667 */
- -32628, /* A2 = 0.995758 */
- 11145, /* B2 = 0.340134 */
- -5430, /* B1 = -0.331467 */
- 11145, /* B0 = 0.340134 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1400 */
- 14780, /* A1 = -0.902130 */
- -32393, /* A2 = 0.988586 */
- -396, /* B2 = -0.012086 */
- 0, /* B1 = 0.000000 */
- 396, /* B0 = 0.012086 */
- 14510, /* A1 = -0.885651 */
- -32630, /* A2 = 0.995819 */
- 6326, /* B2 = 0.193069 */
- -2747, /* B1 = -0.167671 */
- 6326, /* B0 = 0.193069 */
- 15154, /* A1 = -0.924957 */
- -32632, /* A2 = 0.995850 */
- 23235, /* B2 = 0.709076 */
- -10983, /* B1 = -0.670380 */
- 23235, /* B0 = 0.709076 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1477 */
- 13005, /* A1 = -0.793793 */
- -32368, /* A2 = 0.987823 */
- -500, /* B2 = -0.015265 */
- 0, /* B1 = 0.000000 */
- 500, /* B0 = 0.015265 */
- 12708, /* A1 = -0.775665 */
- -32615, /* A2 = 0.995331 */
- 11420, /* B2 = 0.348526 */
- -4306, /* B1 = -0.262833 */
- 11420, /* B0 = 0.348526 */
- 13397, /* A1 = -0.817688 */
- -32615, /* A2 = 0.995361 */
- 9454, /* B2 = 0.288528 */
- -3981, /* B1 = -0.243027 */
- 9454, /* B0 = 0.288528 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1600 */
- 10046, /* A1 = -0.613190 */
- -32331, /* A2 = 0.986694 */
- -455, /* B2 = -0.013915 */
- 0, /* B1 = 0.000000 */
- 455, /* B0 = 0.013915 */
- 9694, /* A1 = -0.591705 */
- -32601, /* A2 = 0.994934 */
- 6023, /* B2 = 0.183815 */
- -1708, /* B1 = -0.104279 */
- 6023, /* B0 = 0.183815 */
- 10478, /* A1 = -0.639587 */
- -32603, /* A2 = 0.994965 */
- 22031, /* B2 = 0.672333 */
- -7342, /* B1 = -0.448151 */
- 22031, /* B0 = 0.672333 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1633_1638[] */
- 9181, /* A1 = 0.560394 */
- -32256, /* A2 = -0.984375 */
- -556, /* B2 = -0.016975 */
- 0, /* B1 = 0 */
- 556, /* B0 = 0.016975 */
- 8757, /* A1 = 0.534515 */
- -32574, /* A2 = -0.99408 */
- 8443, /* B2 = 0.25769 */
- -2135, /* B1 = -0.130341 */
- 8443, /* B0 = 0.25769 */
- 9691, /* A1 = 0.591522 */
- -32574, /* A2 = -0.99411 */
- 15446, /* B2 = 0.471375 */
- -4809, /* B1 = -0.293579 */
- 15446, /* B0 = 0.471375 */
- 7, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1800 */
- 5076, /* A1 = -0.309875 */
- -32304, /* A2 = 0.985840 */
- -508, /* B2 = -0.015503 */
- 0, /* B1 = 0.000000 */
- 508, /* B0 = 0.015503 */
- 4646, /* A1 = -0.283600 */
- -32605, /* A2 = 0.995026 */
- 6742, /* B2 = 0.205780 */
- -878, /* B1 = -0.053635 */
- 6742, /* B0 = 0.205780 */
- 5552, /* A1 = -0.338928 */
- -32605, /* A2 = 0.995056 */
- 23667, /* B2 = 0.722260 */
- -4297, /* B1 = -0.262329 */
- 23667, /* B0 = 0.722260 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
- { /* f1860 */
- 3569, /* A1 = -0.217865 */
- -32292, /* A2 = 0.985504 */
- -239, /* B2 = -0.007322 */
- 0, /* B1 = 0.000000 */
- 239, /* B0 = 0.007322 */
- 3117, /* A1 = -0.190277 */
- -32603, /* A2 = 0.994965 */
- 18658, /* B2 = 0.569427 */
- -1557, /* B1 = -0.095032 */
- 18658, /* B0 = 0.569427 */
- 4054, /* A1 = -0.247437 */
- -32603, /* A2 = 0.994965 */
- 18886, /* B2 = 0.576385 */
- -2566, /* B1 = -0.156647 */
- 18886, /* B0 = 0.576385 */
- 5, /* Internal filter scaling */
- 159, /* Minimum in-band energy threshold */
- 21, /* 21/32 in-band to broad-band ratio */
- 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
- },
-};
-static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf)
-{
- unsigned short cmd;
- int cnt, max;
-
- if (jf->filter > 3) {
- return -1;
- }
- if (ixj_WriteDSPCommand(0x5154 + jf->filter, j)) /* Select Filter */
-
- return -1;
- if (!jf->enable) {
- if (ixj_WriteDSPCommand(0x5152, j)) /* Disable Filter */
-
- return -1;
- else
- return 0;
- } else {
- if (ixj_WriteDSPCommand(0x5153, j)) /* Enable Filter */
-
- return -1;
- /* Select the filter (f0 - f3) to use. */
- if (ixj_WriteDSPCommand(0x5154 + jf->filter, j))
- return -1;
- }
- if (jf->freq < 12 && jf->freq > 3) {
- /* Select the frequency for the selected filter. */
- if (ixj_WriteDSPCommand(0x5170 + jf->freq, j))
- return -1;
- } else if (jf->freq > 11) {
- /* We need to load a programmable filter set for undefined */
- /* frequencies. So we will point the filter to a programmable set. */
- /* Since there are only 4 filters and 4 programmable sets, we will */
- /* just point the filter to the same number set and program it for the */
- /* frequency we want. */
- if (ixj_WriteDSPCommand(0x5170 + jf->filter, j))
- return -1;
- if (j->ver.low != 0x12) {
- cmd = 0x515B;
- max = 19;
- } else {
- cmd = 0x515E;
- max = 15;
- }
- if (ixj_WriteDSPCommand(cmd, j))
- return -1;
- for (cnt = 0; cnt < max; cnt++) {
- if (ixj_WriteDSPCommand(tone_table[jf->freq - 12][cnt], j))
- return -1;
- }
- }
- j->filter_en[jf->filter] = jf->enable;
- return 0;
-}
-
-static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr)
-{
- unsigned short cmd;
- int cnt, max;
- if (jfr->filter > 3) {
- return -1;
- }
- if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j)) /* Select Filter */
- return -1;
-
- if (!jfr->enable) {
- if (ixj_WriteDSPCommand(0x5152, j)) /* Disable Filter */
- return -1;
- else
- return 0;
- } else {
- if (ixj_WriteDSPCommand(0x5153, j)) /* Enable Filter */
- return -1;
- /* Select the filter (f0 - f3) to use. */
- if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j))
- return -1;
- }
- /* We need to load a programmable filter set for undefined */
- /* frequencies. So we will point the filter to a programmable set. */
- /* Since there are only 4 filters and 4 programmable sets, we will */
- /* just point the filter to the same number set and program it for the */
- /* frequency we want. */
- if (ixj_WriteDSPCommand(0x5170 + jfr->filter, j))
- return -1;
- if (j->ver.low != 0x12) {
- cmd = 0x515B;
- max = 19;
- } else {
- cmd = 0x515E;
- max = 15;
- }
- if (ixj_WriteDSPCommand(cmd, j))
- return -1;
- for (cnt = 0; cnt < max; cnt++) {
- if (ixj_WriteDSPCommand(jfr->coeff[cnt], j))
- return -1;
- }
- j->filter_en[jfr->filter] = jfr->enable;
- return 0;
-}
-
-static int ixj_init_tone(IXJ *j, IXJ_TONE * ti)
-{
- int freq0, freq1;
- unsigned short data;
- if (ti->freq0) {
- freq0 = ti->freq0;
- } else {
- freq0 = 0x7FFF;
- }
-
- if (ti->freq1) {
- freq1 = ti->freq1;
- } else {
- freq1 = 0x7FFF;
- }
-
- if(ti->tone_index > 12 && ti->tone_index < 28)
- {
- if (ixj_WriteDSPCommand(0x6800 + ti->tone_index, j))
- return -1;
- if (ixj_WriteDSPCommand(0x6000 + (ti->gain1 << 4) + ti->gain0, j))
- return -1;
- data = freq0;
- if (ixj_WriteDSPCommand(data, j))
- return -1;
- data = freq1;
- if (ixj_WriteDSPCommand(data, j))
- return -1;
- }
- return freq0;
-}
-
diff --git a/drivers/staging/telephony/ixj.h b/drivers/staging/telephony/ixj.h
deleted file mode 100644
index 2c841134f61..00000000000
--- a/drivers/staging/telephony/ixj.h
+++ /dev/null
@@ -1,1322 +0,0 @@
-/******************************************************************************
- * ixj.h
- *
- *
- * Device Driver for Quicknet Technologies, Inc.'s Telephony cards
- * including the Internet PhoneJACK, Internet PhoneJACK Lite,
- * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and
- * SmartCABLE
- *
- * (c) Copyright 1999-2001 Quicknet Technologies, 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.
- *
- * Author: Ed Okerson, <eokerson@quicknet.net>
- *
- * Contributors: Greg Herlein, <gherlein@quicknet.net>
- * David W. Erhart, <derhart@quicknet.net>
- * John Sellers, <jsellers@quicknet.net>
- * Mike Preston, <mpreston@quicknet.net>
- *
- * More information about the hardware related to this driver can be found
- * at our website: http://www.quicknet.net
- *
- * Fixes:
- *
- * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
- * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION
- * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- *****************************************************************************/
-#define IXJ_VERSION 3031
-
-#include <linux/types.h>
-
-#include <linux/ixjuser.h>
-#include <linux/phonedev.h>
-
-typedef __u16 WORD;
-typedef __u32 DWORD;
-typedef __u8 BYTE;
-
-#ifndef IXJMAX
-#define IXJMAX 16
-#endif
-
-/******************************************************************************
-*
-* This structure when unioned with the structures below makes simple byte
-* access to the registers easier.
-*
-******************************************************************************/
-typedef struct {
- unsigned char low;
- unsigned char high;
-} BYTES;
-
-typedef union {
- BYTES bytes;
- short word;
-} IXJ_WORD;
-
-typedef struct{
- unsigned int b0:1;
- unsigned int b1:1;
- unsigned int b2:1;
- unsigned int b3:1;
- unsigned int b4:1;
- unsigned int b5:1;
- unsigned int b6:1;
- unsigned int b7:1;
-} IXJ_CBITS;
-
-typedef union{
- IXJ_CBITS cbits;
- char cbyte;
-} IXJ_CBYTE;
-
-/******************************************************************************
-*
-* This structure represents the Hardware Control Register of the CT8020/8021
-* The CT8020 is used in the Internet PhoneJACK, and the 8021 in the
-* Internet LineJACK
-*
-******************************************************************************/
-typedef struct {
- unsigned int rxrdy:1;
- unsigned int txrdy:1;
- unsigned int status:1;
- unsigned int auxstatus:1;
- unsigned int rxdma:1;
- unsigned int txdma:1;
- unsigned int rxburst:1;
- unsigned int txburst:1;
- unsigned int dmadir:1;
- unsigned int cont:1;
- unsigned int irqn:1;
- unsigned int t:5;
-} HCRBIT;
-
-typedef union {
- HCRBIT bits;
- BYTES bytes;
-} HCR;
-
-/******************************************************************************
-*
-* This structure represents the Hardware Status Register of the CT8020/8021
-* The CT8020 is used in the Internet PhoneJACK, and the 8021 in the
-* Internet LineJACK
-*
-******************************************************************************/
-typedef struct {
- unsigned int controlrdy:1;
- unsigned int auxctlrdy:1;
- unsigned int statusrdy:1;
- unsigned int auxstatusrdy:1;
- unsigned int rxrdy:1;
- unsigned int txrdy:1;
- unsigned int restart:1;
- unsigned int irqn:1;
- unsigned int rxdma:1;
- unsigned int txdma:1;
- unsigned int cohostshutdown:1;
- unsigned int t:5;
-} HSRBIT;
-
-typedef union {
- HSRBIT bits;
- BYTES bytes;
-} HSR;
-
-/******************************************************************************
-*
-* This structure represents the General Purpose IO Register of the CT8020/8021
-* The CT8020 is used in the Internet PhoneJACK, and the 8021 in the
-* Internet LineJACK
-*
-******************************************************************************/
-typedef struct {
- unsigned int x:1;
- unsigned int gpio1:1;
- unsigned int gpio2:1;
- unsigned int gpio3:1;
- unsigned int gpio4:1;
- unsigned int gpio5:1;
- unsigned int gpio6:1;
- unsigned int gpio7:1;
- unsigned int xread:1;
- unsigned int gpio1read:1;
- unsigned int gpio2read:1;
- unsigned int gpio3read:1;
- unsigned int gpio4read:1;
- unsigned int gpio5read:1;
- unsigned int gpio6read:1;
- unsigned int gpio7read:1;
-} GPIOBIT;
-
-typedef union {
- GPIOBIT bits;
- BYTES bytes;
- unsigned short word;
-} GPIO;
-
-/******************************************************************************
-*
-* This structure represents the Line Monitor status response
-*
-******************************************************************************/
-typedef struct {
- unsigned int digit:4;
- unsigned int cpf_valid:1;
- unsigned int dtmf_valid:1;
- unsigned int peak:1;
- unsigned int z:1;
- unsigned int f0:1;
- unsigned int f1:1;
- unsigned int f2:1;
- unsigned int f3:1;
- unsigned int frame:4;
-} LMON;
-
-typedef union {
- LMON bits;
- BYTES bytes;
-} DTMF;
-
-typedef struct {
- unsigned int z:7;
- unsigned int dtmf_en:1;
- unsigned int y:4;
- unsigned int F3:1;
- unsigned int F2:1;
- unsigned int F1:1;
- unsigned int F0:1;
-} CP;
-
-typedef union {
- CP bits;
- BYTES bytes;
-} CPTF;
-
-/******************************************************************************
-*
-* This structure represents the Status Control Register on the Internet
-* LineJACK
-*
-******************************************************************************/
-typedef struct {
- unsigned int c0:1;
- unsigned int c1:1;
- unsigned int stereo:1;
- unsigned int daafsyncen:1;
- unsigned int led1:1;
- unsigned int led2:1;
- unsigned int led3:1;
- unsigned int led4:1;
-} PSCRWI; /* Internet LineJACK and Internet PhoneJACK Lite */
-
-typedef struct {
- unsigned int eidp:1;
- unsigned int eisd:1;
- unsigned int x:6;
-} PSCRWP; /* Internet PhoneJACK PCI */
-
-typedef union {
- PSCRWI bits;
- PSCRWP pcib;
- char byte;
-} PLD_SCRW;
-
-typedef struct {
- unsigned int c0:1;
- unsigned int c1:1;
- unsigned int x:1;
- unsigned int d0ee:1;
- unsigned int mixerbusy:1;
- unsigned int sci:1;
- unsigned int dspflag:1;
- unsigned int daaflag:1;
-} PSCRRI;
-
-typedef struct {
- unsigned int eidp:1;
- unsigned int eisd:1;
- unsigned int x:4;
- unsigned int dspflag:1;
- unsigned int det:1;
-} PSCRRP;
-
-typedef union {
- PSCRRI bits;
- PSCRRP pcib;
- char byte;
-} PLD_SCRR;
-
-/******************************************************************************
-*
-* These structures represents the SLIC Control Register on the
-* Internet LineJACK
-*
-******************************************************************************/
-typedef struct {
- unsigned int c1:1;
- unsigned int c2:1;
- unsigned int c3:1;
- unsigned int b2en:1;
- unsigned int spken:1;
- unsigned int rly1:1;
- unsigned int rly2:1;
- unsigned int rly3:1;
-} PSLICWRITE;
-
-typedef struct {
- unsigned int state:3;
- unsigned int b2en:1;
- unsigned int spken:1;
- unsigned int c3:1;
- unsigned int potspstn:1;
- unsigned int det:1;
-} PSLICREAD;
-
-typedef struct {
- unsigned int c1:1;
- unsigned int c2:1;
- unsigned int c3:1;
- unsigned int b2en:1;
- unsigned int e1:1;
- unsigned int mic:1;
- unsigned int spk:1;
- unsigned int x:1;
-} PSLICPCI;
-
-typedef union {
- PSLICPCI pcib;
- PSLICWRITE bits;
- PSLICREAD slic;
- char byte;
-} PLD_SLICW;
-
-typedef union {
- PSLICPCI pcib;
- PSLICREAD bits;
- char byte;
-} PLD_SLICR;
-
-/******************************************************************************
-*
-* These structures represents the Clock Control Register on the
-* Internet LineJACK
-*
-******************************************************************************/
-typedef struct {
- unsigned int clk0:1;
- unsigned int clk1:1;
- unsigned int clk2:1;
- unsigned int x0:1;
- unsigned int slic_e1:1;
- unsigned int x1:1;
- unsigned int x2:1;
- unsigned int x3:1;
-} PCLOCK;
-
-typedef union {
- PCLOCK bits;
- char byte;
-} PLD_CLOCK;
-
-/******************************************************************************
-*
-* These structures deal with the mixer on the Internet LineJACK
-*
-******************************************************************************/
-
-typedef struct {
- unsigned short vol[10];
- unsigned int recsrc;
- unsigned int modcnt;
- unsigned short micpreamp;
-} MIX;
-
-/******************************************************************************
-*
-* These structures deal with the control logic on the Internet PhoneCARD
-*
-******************************************************************************/
-typedef struct {
- unsigned int x0:4; /* unused bits */
-
- unsigned int ed:1; /* Event Detect */
-
- unsigned int drf:1; /* SmartCABLE Removal Flag 1=no cable */
-
- unsigned int dspf:1; /* DSP Flag 1=DSP Ready */
-
- unsigned int crr:1; /* Control Register Ready */
-
-} COMMAND_REG1;
-
-typedef union {
- COMMAND_REG1 bits;
- unsigned char byte;
-} PCMCIA_CR1;
-
-typedef struct {
- unsigned int x0:4; /* unused bits */
-
- unsigned int rstc:1; /* SmartCABLE Reset */
-
- unsigned int pwr:1; /* SmartCABLE Power */
-
- unsigned int x1:2; /* unused bits */
-
-} COMMAND_REG2;
-
-typedef union {
- COMMAND_REG2 bits;
- unsigned char byte;
-} PCMCIA_CR2;
-
-typedef struct {
- unsigned int addr:5; /* R/W SmartCABLE Register Address */
-
- unsigned int rw:1; /* Read / Write flag */
-
- unsigned int dev:2; /* 2 bit SmartCABLE Device Address */
-
-} CONTROL_REG;
-
-typedef union {
- CONTROL_REG bits;
- unsigned char byte;
-} PCMCIA_SCCR;
-
-typedef struct {
- unsigned int hsw:1;
- unsigned int det:1;
- unsigned int led2:1;
- unsigned int led1:1;
- unsigned int ring1:1;
- unsigned int ring0:1;
- unsigned int x:1;
- unsigned int powerdown:1;
-} PCMCIA_SLIC_REG;
-
-typedef union {
- PCMCIA_SLIC_REG bits;
- unsigned char byte;
-} PCMCIA_SLIC;
-
-typedef struct {
- unsigned int cpd:1; /* Chip Power Down */
-
- unsigned int mpd:1; /* MIC Bias Power Down */
-
- unsigned int hpd:1; /* Handset Drive Power Down */
-
- unsigned int lpd:1; /* Line Drive Power Down */
-
- unsigned int spd:1; /* Speaker Drive Power Down */
-
- unsigned int x:2; /* unused bits */
-
- unsigned int sr:1; /* Software Reset */
-
-} Si3CONTROL1;
-
-typedef union {
- Si3CONTROL1 bits;
- unsigned char byte;
-} Si3C1;
-
-typedef struct {
- unsigned int al:1; /* Analog Loopback DAC analog -> ADC analog */
-
- unsigned int dl2:1; /* Digital Loopback DAC -> ADC one bit */
-
- unsigned int dl1:1; /* Digital Loopback ADC -> DAC one bit */
-
- unsigned int pll:1; /* 1 = div 10, 0 = div 5 */
-
- unsigned int hpd:1; /* HPF disable */
-
- unsigned int x:3; /* unused bits */
-
-} Si3CONTROL2;
-
-typedef union {
- Si3CONTROL2 bits;
- unsigned char byte;
-} Si3C2;
-
-typedef struct {
- unsigned int iir:1; /* 1 enables IIR, 0 enables FIR */
-
- unsigned int him:1; /* Handset Input Mute */
-
- unsigned int mcm:1; /* MIC In Mute */
-
- unsigned int mcg:2; /* MIC In Gain */
-
- unsigned int lim:1; /* Line In Mute */
-
- unsigned int lig:2; /* Line In Gain */
-
-} Si3RXGAIN;
-
-typedef union {
- Si3RXGAIN bits;
- unsigned char byte;
-} Si3RXG;
-
-typedef struct {
- unsigned int hom:1; /* Handset Out Mute */
-
- unsigned int lom:1; /* Line Out Mute */
-
- unsigned int rxg:5; /* RX PGA Gain */
-
- unsigned int x:1; /* unused bit */
-
-} Si3ADCVOLUME;
-
-typedef union {
- Si3ADCVOLUME bits;
- unsigned char byte;
-} Si3ADC;
-
-typedef struct {
- unsigned int srm:1; /* Speaker Right Mute */
-
- unsigned int slm:1; /* Speaker Left Mute */
-
- unsigned int txg:5; /* TX PGA Gain */
-
- unsigned int x:1; /* unused bit */
-
-} Si3DACVOLUME;
-
-typedef union {
- Si3DACVOLUME bits;
- unsigned char byte;
-} Si3DAC;
-
-typedef struct {
- unsigned int x:5; /* unused bit */
-
- unsigned int losc:1; /* Line Out Short Circuit */
-
- unsigned int srsc:1; /* Speaker Right Short Circuit */
-
- unsigned int slsc:1; /* Speaker Left Short Circuit */
-
-} Si3STATUSREPORT;
-
-typedef union {
- Si3STATUSREPORT bits;
- unsigned char byte;
-} Si3STAT;
-
-typedef struct {
- unsigned int sot:2; /* Speaker Out Attenuation */
-
- unsigned int lot:2; /* Line Out Attenuation */
-
- unsigned int x:4; /* unused bits */
-
-} Si3ANALOGATTN;
-
-typedef union {
- Si3ANALOGATTN bits;
- unsigned char byte;
-} Si3AATT;
-
-/******************************************************************************
-*
-* These structures deal with the DAA on the Internet LineJACK
-*
-******************************************************************************/
-
-typedef struct _DAA_REGS {
- /*----------------------------------------------- */
- /* SOP Registers */
- /* */
- BYTE bySOP;
-
- union _SOP_REGS {
- struct _SOP {
- union /* SOP - CR0 Register */
- {
- BYTE reg;
- struct _CR0_BITREGS {
- BYTE CLK_EXT:1; /* cr0[0:0] */
-
- BYTE RIP:1; /* cr0[1:1] */
-
- BYTE AR:1; /* cr0[2:2] */
-
- BYTE AX:1; /* cr0[3:3] */
-
- BYTE FRR:1; /* cr0[4:4] */
-
- BYTE FRX:1; /* cr0[5:5] */
-
- BYTE IM:1; /* cr0[6:6] */
-
- BYTE TH:1; /* cr0[7:7] */
-
- } bitreg;
- } cr0;
-
- union /* SOP - CR1 Register */
- {
- BYTE reg;
- struct _CR1_REGS {
- BYTE RM:1; /* cr1[0:0] */
-
- BYTE RMR:1; /* cr1[1:1] */
-
- BYTE No_auto:1; /* cr1[2:2] */
-
- BYTE Pulse:1; /* cr1[3:3] */
-
- BYTE P_Tone1:1; /* cr1[4:4] */
-
- BYTE P_Tone2:1; /* cr1[5:5] */
-
- BYTE E_Tone1:1; /* cr1[6:6] */
-
- BYTE E_Tone2:1; /* cr1[7:7] */
-
- } bitreg;
- } cr1;
-
- union /* SOP - CR2 Register */
- {
- BYTE reg;
- struct _CR2_REGS {
- BYTE Call_II:1; /* CR2[0:0] */
-
- BYTE Call_I:1; /* CR2[1:1] */
-
- BYTE Call_en:1; /* CR2[2:2] */
-
- BYTE Call_pon:1; /* CR2[3:3] */
-
- BYTE IDR:1; /* CR2[4:4] */
-
- BYTE COT_R:3; /* CR2[5:7] */
-
- } bitreg;
- } cr2;
-
- union /* SOP - CR3 Register */
- {
- BYTE reg;
- struct _CR3_REGS {
- BYTE DHP_X:1; /* CR3[0:0] */
-
- BYTE DHP_R:1; /* CR3[1:1] */
-
- BYTE Cal_pctl:1; /* CR3[2:2] */
-
- BYTE SEL:1; /* CR3[3:3] */
-
- BYTE TestLoops:4; /* CR3[4:7] */
-
- } bitreg;
- } cr3;
-
- union /* SOP - CR4 Register */
- {
- BYTE reg;
- struct _CR4_REGS {
- BYTE Fsc_en:1; /* CR4[0:0] */
-
- BYTE Int_en:1; /* CR4[1:1] */
-
- BYTE AGX:2; /* CR4[2:3] */
-
- BYTE AGR_R:2; /* CR4[4:5] */
-
- BYTE AGR_Z:2; /* CR4[6:7] */
-
- } bitreg;
- } cr4;
-
- union /* SOP - CR5 Register */
- {
- BYTE reg;
- struct _CR5_REGS {
- BYTE V_0:1; /* CR5[0:0] */
-
- BYTE V_1:1; /* CR5[1:1] */
-
- BYTE V_2:1; /* CR5[2:2] */
-
- BYTE V_3:1; /* CR5[3:3] */
-
- BYTE V_4:1; /* CR5[4:4] */
-
- BYTE V_5:1; /* CR5[5:5] */
-
- BYTE V_6:1; /* CR5[6:6] */
-
- BYTE V_7:1; /* CR5[7:7] */
-
- } bitreg;
- } cr5;
-
- union /* SOP - CR6 Register */
- {
- BYTE reg;
- struct _CR6_REGS {
- BYTE reserved:8; /* CR6[0:7] */
-
- } bitreg;
- } cr6;
-
- union /* SOP - CR7 Register */
- {
- BYTE reg;
- struct _CR7_REGS {
- BYTE reserved:8; /* CR7[0:7] */
-
- } bitreg;
- } cr7;
- } SOP;
-
- BYTE ByteRegs[sizeof(struct _SOP)];
-
- } SOP_REGS;
-
- /* DAA_REGS.SOP_REGS.SOP.CR5.reg */
- /* DAA_REGS.SOP_REGS.SOP.CR5.bitreg */
- /* DAA_REGS.SOP_REGS.SOP.CR5.bitreg.V_2 */
- /* DAA_REGS.SOP_REGS.ByteRegs[5] */
-
- /*----------------------------------------------- */
- /* XOP Registers */
- /* */
- BYTE byXOP;
-
- union _XOP_REGS {
- struct _XOP {
- union XOPXR0/* XOP - XR0 Register - Read values */
- {
- BYTE reg;
- struct _XR0_BITREGS {
- BYTE SI_0:1; /* XR0[0:0] - Read */
-
- BYTE SI_1:1; /* XR0[1:1] - Read */
-
- BYTE VDD_OK:1; /* XR0[2:2] - Read */
-
- BYTE Caller_ID:1; /* XR0[3:3] - Read */
-
- BYTE RING:1; /* XR0[4:4] - Read */
-
- BYTE Cadence:1; /* XR0[5:5] - Read */
-
- BYTE Wake_up:1; /* XR0[6:6] - Read */
-
- BYTE RMR:1; /* XR0[7:7] - Read */
-
- } bitreg;
- } xr0;
-
- union /* XOP - XR1 Register */
- {
- BYTE reg;
- struct _XR1_BITREGS {
- BYTE M_SI_0:1; /* XR1[0:0] */
-
- BYTE M_SI_1:1; /* XR1[1:1] */
-
- BYTE M_VDD_OK:1; /* XR1[2:2] */
-
- BYTE M_Caller_ID:1; /* XR1[3:3] */
-
- BYTE M_RING:1; /* XR1[4:4] */
-
- BYTE M_Cadence:1; /* XR1[5:5] */
-
- BYTE M_Wake_up:1; /* XR1[6:6] */
-
- BYTE unused:1; /* XR1[7:7] */
-
- } bitreg;
- } xr1;
-
- union /* XOP - XR2 Register */
- {
- BYTE reg;
- struct _XR2_BITREGS {
- BYTE CTO0:1; /* XR2[0:0] */
-
- BYTE CTO1:1; /* XR2[1:1] */
-
- BYTE CTO2:1; /* XR2[2:2] */
-
- BYTE CTO3:1; /* XR2[3:3] */
-
- BYTE CTO4:1; /* XR2[4:4] */
-
- BYTE CTO5:1; /* XR2[5:5] */
-
- BYTE CTO6:1; /* XR2[6:6] */
-
- BYTE CTO7:1; /* XR2[7:7] */
-
- } bitreg;
- } xr2;
-
- union /* XOP - XR3 Register */
- {
- BYTE reg;
- struct _XR3_BITREGS {
- BYTE DCR0:1; /* XR3[0:0] */
-
- BYTE DCR1:1; /* XR3[1:1] */
-
- BYTE DCI:1; /* XR3[2:2] */
-
- BYTE DCU0:1; /* XR3[3:3] */
-
- BYTE DCU1:1; /* XR3[4:4] */
-
- BYTE B_off:1; /* XR3[5:5] */
-
- BYTE AGB0:1; /* XR3[6:6] */
-
- BYTE AGB1:1; /* XR3[7:7] */
-
- } bitreg;
- } xr3;
-
- union /* XOP - XR4 Register */
- {
- BYTE reg;
- struct _XR4_BITREGS {
- BYTE C_0:1; /* XR4[0:0] */
-
- BYTE C_1:1; /* XR4[1:1] */
-
- BYTE C_2:1; /* XR4[2:2] */
-
- BYTE C_3:1; /* XR4[3:3] */
-
- BYTE C_4:1; /* XR4[4:4] */
-
- BYTE C_5:1; /* XR4[5:5] */
-
- BYTE C_6:1; /* XR4[6:6] */
-
- BYTE C_7:1; /* XR4[7:7] */
-
- } bitreg;
- } xr4;
-
- union /* XOP - XR5 Register */
- {
- BYTE reg;
- struct _XR5_BITREGS {
- BYTE T_0:1; /* XR5[0:0] */
-
- BYTE T_1:1; /* XR5[1:1] */
-
- BYTE T_2:1; /* XR5[2:2] */
-
- BYTE T_3:1; /* XR5[3:3] */
-
- BYTE T_4:1; /* XR5[4:4] */
-
- BYTE T_5:1; /* XR5[5:5] */
-
- BYTE T_6:1; /* XR5[6:6] */
-
- BYTE T_7:1; /* XR5[7:7] */
-
- } bitreg;
- } xr5;
-
- union /* XOP - XR6 Register - Read Values */
- {
- BYTE reg;
- struct _XR6_BITREGS {
- BYTE CPS0:1; /* XR6[0:0] */
-
- BYTE CPS1:1; /* XR6[1:1] */
-
- BYTE unused1:2; /* XR6[2:3] */
-
- BYTE CLK_OFF:1; /* XR6[4:4] */
-
- BYTE unused2:3; /* XR6[5:7] */
-
- } bitreg;
- } xr6;
-
- union /* XOP - XR7 Register */
- {
- BYTE reg;
- struct _XR7_BITREGS {
- BYTE unused1:1; /* XR7[0:0] */
-
- BYTE Vdd0:1; /* XR7[1:1] */
-
- BYTE Vdd1:1; /* XR7[2:2] */
-
- BYTE unused2:5; /* XR7[3:7] */
-
- } bitreg;
- } xr7;
- } XOP;
-
- BYTE ByteRegs[sizeof(struct _XOP)];
-
- } XOP_REGS;
-
- /* DAA_REGS.XOP_REGS.XOP.XR7.reg */
- /* DAA_REGS.XOP_REGS.XOP.XR7.bitreg */
- /* DAA_REGS.XOP_REGS.XOP.XR7.bitreg.Vdd0 */
- /* DAA_REGS.XOP_REGS.ByteRegs[7] */
-
- /*----------------------------------------------- */
- /* COP Registers */
- /* */
- BYTE byCOP;
-
- union _COP_REGS {
- struct _COP {
- BYTE THFilterCoeff_1[8]; /* COP - TH Filter Coefficients, CODE=0, Part 1 */
-
- BYTE THFilterCoeff_2[8]; /* COP - TH Filter Coefficients, CODE=1, Part 2 */
-
- BYTE THFilterCoeff_3[8]; /* COP - TH Filter Coefficients, CODE=2, Part 3 */
-
- BYTE RingerImpendance_1[8]; /* COP - Ringer Impendance Coefficients, CODE=3, Part 1 */
-
- BYTE IMFilterCoeff_1[8]; /* COP - IM Filter Coefficients, CODE=4, Part 1 */
-
- BYTE IMFilterCoeff_2[8]; /* COP - IM Filter Coefficients, CODE=5, Part 2 */
-
- BYTE RingerImpendance_2[8]; /* COP - Ringer Impendance Coefficients, CODE=6, Part 2 */
-
- BYTE FRRFilterCoeff[8]; /* COP - FRR Filter Coefficients, CODE=7 */
-
- BYTE FRXFilterCoeff[8]; /* COP - FRX Filter Coefficients, CODE=8 */
-
- BYTE ARFilterCoeff[4]; /* COP - AR Filter Coefficients, CODE=9 */
-
- BYTE AXFilterCoeff[4]; /* COP - AX Filter Coefficients, CODE=10 */
-
- BYTE Tone1Coeff[4]; /* COP - Tone1 Coefficients, CODE=11 */
-
- BYTE Tone2Coeff[4]; /* COP - Tone2 Coefficients, CODE=12 */
-
- BYTE LevelmeteringRinging[4]; /* COP - Levelmetering Ringing, CODE=13 */
-
- BYTE CallerID1stTone[8]; /* COP - Caller ID 1st Tone, CODE=14 */
-
- BYTE CallerID2ndTone[8]; /* COP - Caller ID 2nd Tone, CODE=15 */
-
- } COP;
-
- BYTE ByteRegs[sizeof(struct _COP)];
-
- } COP_REGS;
-
- /* DAA_REGS.COP_REGS.COP.XR7.Tone1Coeff[3] */
- /* DAA_REGS.COP_REGS.COP.XR7.bitreg */
- /* DAA_REGS.COP_REGS.COP.XR7.bitreg.Vdd0 */
- /* DAA_REGS.COP_REGS.ByteRegs[57] */
-
- /*----------------------------------------------- */
- /* CAO Registers */
- /* */
- BYTE byCAO;
-
- union _CAO_REGS {
- struct _CAO {
- BYTE CallerID[512]; /* CAO - Caller ID Bytes */
-
- } CAO;
-
- BYTE ByteRegs[sizeof(struct _CAO)];
- } CAO_REGS;
-
- union /* XOP - XR0 Register - Write values */
- {
- BYTE reg;
- struct _XR0_BITREGSW {
- BYTE SO_0:1; /* XR1[0:0] - Write */
-
- BYTE SO_1:1; /* XR1[1:1] - Write */
-
- BYTE SO_2:1; /* XR1[2:2] - Write */
-
- BYTE unused:5; /* XR1[3:7] - Write */
-
- } bitreg;
- } XOP_xr0_W;
-
- union /* XOP - XR6 Register - Write values */
- {
- BYTE reg;
- struct _XR6_BITREGSW {
- BYTE unused1:4; /* XR6[0:3] */
-
- BYTE CLK_OFF:1; /* XR6[4:4] */
-
- BYTE unused2:3; /* XR6[5:7] */
-
- } bitreg;
- } XOP_xr6_W;
-
-} DAA_REGS;
-
-#define ALISDAA_ID_BYTE 0x81
-#define ALISDAA_CALLERID_SIZE 512
-
-/*------------------------------ */
-/* */
-/* Misc definitions */
-/* */
-
-/* Power Up Operation */
-#define SOP_PU_SLEEP 0
-#define SOP_PU_RINGING 1
-#define SOP_PU_CONVERSATION 2
-#define SOP_PU_PULSEDIALING 3
-#define SOP_PU_RESET 4
-
-#define ALISDAA_CALLERID_SIZE 512
-
-#define PLAYBACK_MODE_COMPRESSED 0 /* Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */
-#define PLAYBACK_MODE_TRUESPEECH_V40 0 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */
-#define PLAYBACK_MODE_TRUESPEECH 8 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps Version 5.1 */
-#define PLAYBACK_MODE_ULAW 2 /* Selects: 64 Kbit/sec MuA-law PCM */
-#define PLAYBACK_MODE_ALAW 10 /* Selects: 64 Kbit/sec A-law PCM */
-#define PLAYBACK_MODE_16LINEAR 6 /* Selects: 128 Kbit/sec 16-bit linear */
-#define PLAYBACK_MODE_8LINEAR 4 /* Selects: 64 Kbit/sec 8-bit signed linear */
-#define PLAYBACK_MODE_8LINEAR_WSS 5 /* Selects: 64 Kbit/sec WSS 8-bit unsigned linear */
-
-#define RECORD_MODE_COMPRESSED 0 /* Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */
-#define RECORD_MODE_TRUESPEECH 0 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */
-#define RECORD_MODE_ULAW 4 /* Selects: 64 Kbit/sec Mu-law PCM */
-#define RECORD_MODE_ALAW 12 /* Selects: 64 Kbit/sec A-law PCM */
-#define RECORD_MODE_16LINEAR 5 /* Selects: 128 Kbit/sec 16-bit linear */
-#define RECORD_MODE_8LINEAR 6 /* Selects: 64 Kbit/sec 8-bit signed linear */
-#define RECORD_MODE_8LINEAR_WSS 7 /* Selects: 64 Kbit/sec WSS 8-bit unsigned linear */
-
-enum SLIC_STATES {
- PLD_SLIC_STATE_OC = 0,
- PLD_SLIC_STATE_RINGING,
- PLD_SLIC_STATE_ACTIVE,
- PLD_SLIC_STATE_OHT,
- PLD_SLIC_STATE_TIPOPEN,
- PLD_SLIC_STATE_STANDBY,
- PLD_SLIC_STATE_APR,
- PLD_SLIC_STATE_OHTPR
-};
-
-enum SCI_CONTROL {
- SCI_End = 0,
- SCI_Enable_DAA,
- SCI_Enable_Mixer,
- SCI_Enable_EEPROM
-};
-
-enum Mode {
- T63, T53, T48, T40
-};
-enum Dir {
- V3_TO_V4, V4_TO_V3, V4_TO_V5, V5_TO_V4
-};
-
-typedef struct Proc_Info_Tag {
- enum Mode convert_mode;
- enum Dir convert_dir;
- int Prev_Frame_Type;
- int Current_Frame_Type;
-} Proc_Info_Type;
-
-enum PREVAL {
- NORMAL = 0,
- NOPOST,
- POSTONLY,
- PREERROR
-};
-
-enum IXJ_EXTENSIONS {
- G729LOADER = 0,
- TS85LOADER,
- PRE_READ,
- POST_READ,
- PRE_WRITE,
- POST_WRITE,
- PRE_IOCTL,
- POST_IOCTL
-};
-
-typedef struct {
- char enable;
- char en_filter;
- unsigned int filter;
- unsigned int state; /* State 0 when cadence has not started. */
-
- unsigned int on1; /* State 1 */
-
- unsigned long on1min; /* State 1 - 10% + jiffies */
- unsigned long on1dot; /* State 1 + jiffies */
-
- unsigned long on1max; /* State 1 + 10% + jiffies */
-
- unsigned int off1; /* State 2 */
-
- unsigned long off1min;
- unsigned long off1dot; /* State 2 + jiffies */
- unsigned long off1max;
- unsigned int on2; /* State 3 */
-
- unsigned long on2min;
- unsigned long on2dot;
- unsigned long on2max;
- unsigned int off2; /* State 4 */
-
- unsigned long off2min;
- unsigned long off2dot; /* State 4 + jiffies */
- unsigned long off2max;
- unsigned int on3; /* State 5 */
-
- unsigned long on3min;
- unsigned long on3dot;
- unsigned long on3max;
- unsigned int off3; /* State 6 */
-
- unsigned long off3min;
- unsigned long off3dot; /* State 6 + jiffies */
- unsigned long off3max;
-} IXJ_CADENCE_F;
-
-typedef struct {
- unsigned int busytone:1;
- unsigned int dialtone:1;
- unsigned int ringback:1;
- unsigned int ringing:1;
- unsigned int playing:1;
- unsigned int recording:1;
- unsigned int cringing:1;
- unsigned int play_first_frame:1;
- unsigned int pstn_present:1;
- unsigned int pstn_ringing:1;
- unsigned int pots_correct:1;
- unsigned int pots_pstn:1;
- unsigned int g729_loaded:1;
- unsigned int ts85_loaded:1;
- unsigned int dtmf_oob:1; /* DTMF Out-Of-Band */
-
- unsigned int pcmciascp:1; /* SmartCABLE Present */
-
- unsigned int pcmciasct:2; /* SmartCABLE Type */
-
- unsigned int pcmciastate:3; /* SmartCABLE Init State */
-
- unsigned int inwrite:1; /* Currently writing */
-
- unsigned int inread:1; /* Currently reading */
-
- unsigned int incheck:1; /* Currently checking the SmartCABLE */
-
- unsigned int cidplay:1; /* Currently playing Caller ID */
-
- unsigned int cidring:1; /* This is the ring for Caller ID */
-
- unsigned int cidsent:1; /* Caller ID has been sent */
-
- unsigned int cidcw_ack:1; /* Caller ID CW ACK (from CPE) */
- unsigned int firstring:1; /* First ring cadence is complete */
- unsigned int pstncheck:1; /* Currently checking the PSTN Line */
- unsigned int pstn_rmr:1;
- unsigned int x:3; /* unused bits */
-
-} IXJ_FLAGS;
-
-/******************************************************************************
-*
-* This structure holds the state of all of the Quicknet cards
-*
-******************************************************************************/
-
-typedef struct {
- int elements_used;
- IXJ_CADENCE_TERM termination;
- IXJ_CADENCE_ELEMENT *ce;
-} ixj_cadence;
-
-typedef struct {
- struct phone_device p;
- struct timer_list timer;
- unsigned int board;
- unsigned int DSPbase;
- unsigned int XILINXbase;
- unsigned int serial;
- atomic_t DSPWrite;
- struct phone_capability caplist[30];
- unsigned int caps;
- struct pnp_dev *dev;
- unsigned int cardtype;
- unsigned int rec_codec;
- unsigned int cid_rec_codec;
- unsigned int cid_rec_volume;
- unsigned char cid_rec_flag;
- signed char rec_mode;
- unsigned int play_codec;
- unsigned int cid_play_codec;
- unsigned int cid_play_volume;
- unsigned char cid_play_flag;
- signed char play_mode;
- IXJ_FLAGS flags;
- unsigned long busyflags;
- unsigned int rec_frame_size;
- unsigned int play_frame_size;
- unsigned int cid_play_frame_size;
- unsigned int cid_base_frame_size;
- unsigned long cidcw_wait;
- int aec_level;
- int cid_play_aec_level;
- int readers, writers;
- wait_queue_head_t poll_q;
- wait_queue_head_t read_q;
- char *read_buffer, *read_buffer_end;
- char *read_convert_buffer;
- size_t read_buffer_size;
- unsigned int read_buffer_ready;
- wait_queue_head_t write_q;
- char *write_buffer, *write_buffer_end;
- char *write_convert_buffer;
- size_t write_buffer_size;
- unsigned int write_buffers_empty;
- unsigned long drybuffer;
- char *write_buffer_rp, *write_buffer_wp;
- char dtmfbuffer[80];
- char dtmf_current;
- int dtmf_wp, dtmf_rp, dtmf_state, dtmf_proc;
- int tone_off_time, tone_on_time;
- struct fasync_struct *async_queue;
- unsigned long tone_start_jif;
- char tone_index;
- char tone_state;
- char maxrings;
- ixj_cadence *cadence_t;
- ixj_cadence *cadence_r;
- int tone_cadence_state;
- IXJ_CADENCE_F cadence_f[6];
- DTMF dtmf;
- CPTF cptf;
- BYTES dsp;
- BYTES ver;
- BYTES scr;
- BYTES ssr;
- BYTES baseframe;
- HSR hsr;
- GPIO gpio;
- PLD_SCRR pld_scrr;
- PLD_SCRW pld_scrw;
- PLD_SLICW pld_slicw;
- PLD_SLICR pld_slicr;
- PLD_CLOCK pld_clock;
- PCMCIA_CR1 pccr1;
- PCMCIA_CR2 pccr2;
- PCMCIA_SCCR psccr;
- PCMCIA_SLIC pslic;
- char pscdd;
- Si3C1 sic1;
- Si3C2 sic2;
- Si3RXG sirxg;
- Si3ADC siadc;
- Si3DAC sidac;
- Si3STAT sistat;
- Si3AATT siaatt;
- MIX mix;
- unsigned short ring_cadence;
- int ring_cadence_t;
- unsigned long ring_cadence_jif;
- unsigned long checkwait;
- int intercom;
- int m_hook;
- int r_hook;
- int p_hook;
- char pstn_envelope;
- char pstn_cid_intr;
- unsigned char fskz;
- unsigned char fskphase;
- unsigned char fskcnt;
- unsigned int cidsize;
- unsigned int cidcnt;
- unsigned long pstn_cid_received;
- PHONE_CID cid;
- PHONE_CID cid_send;
- unsigned long pstn_ring_int;
- unsigned long pstn_ring_start;
- unsigned long pstn_ring_stop;
- unsigned long pstn_winkstart;
- unsigned long pstn_last_rmr;
- unsigned long pstn_prev_rmr;
- unsigned long pots_winkstart;
- unsigned int winktime;
- unsigned long flash_end;
- char port;
- char hookstate;
- union telephony_exception ex;
- union telephony_exception ex_sig;
- int ixj_signals[35];
- IXJ_SIGDEF sigdef;
- char daa_mode;
- char daa_country;
- unsigned long pstn_sleeptil;
- DAA_REGS m_DAAShadowRegs;
- Proc_Info_Type Info_read;
- Proc_Info_Type Info_write;
- unsigned short frame_count;
- unsigned int filter_hist[4];
- unsigned char filter_en[6];
- unsigned short proc_load;
- unsigned long framesread;
- unsigned long frameswritten;
- unsigned long read_wait;
- unsigned long write_wait;
- unsigned long timerchecks;
- unsigned long txreadycheck;
- unsigned long rxreadycheck;
- unsigned long statuswait;
- unsigned long statuswaitfail;
- unsigned long pcontrolwait;
- unsigned long pcontrolwaitfail;
- unsigned long iscontrolready;
- unsigned long iscontrolreadyfail;
- unsigned long pstnstatecheck;
-#ifdef IXJ_DYN_ALLOC
- short *fskdata;
-#else
- short fskdata[8000];
-#endif
- int fsksize;
- int fskdcnt;
-} IXJ;
-
-typedef int (*IXJ_REGFUNC) (IXJ * j, unsigned long arg);
-
-extern IXJ *ixj_pcmcia_probe(unsigned long, unsigned long);
-
diff --git a/drivers/staging/telephony/ixj_pcmcia.c b/drivers/staging/telephony/ixj_pcmcia.c
deleted file mode 100644
index 05032e2cc95..00000000000
--- a/drivers/staging/telephony/ixj_pcmcia.c
+++ /dev/null
@@ -1,187 +0,0 @@
-#include "ixj-ver.h"
-
-#include <linux/module.h>
-
-#include <linux/init.h>
-#include <linux/kernel.h> /* printk() */
-#include <linux/fs.h> /* everything... */
-#include <linux/errno.h> /* error codes */
-#include <linux/slab.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-
-#include "ixj.h"
-
-/*
- * PCMCIA service support for Quicknet cards
- */
-
-
-typedef struct ixj_info_t {
- int ndev;
- struct ixj *port;
-} ixj_info_t;
-
-static void ixj_detach(struct pcmcia_device *p_dev);
-static int ixj_config(struct pcmcia_device * link);
-static void ixj_cs_release(struct pcmcia_device * link);
-
-static int ixj_probe(struct pcmcia_device *p_dev)
-{
- dev_dbg(&p_dev->dev, "ixj_attach()\n");
- /* Create new ixj device */
- p_dev->priv = kzalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
- if (!p_dev->priv) {
- return -ENOMEM;
- }
-
- return ixj_config(p_dev);
-}
-
-static void ixj_detach(struct pcmcia_device *link)
-{
- dev_dbg(&link->dev, "ixj_detach\n");
-
- ixj_cs_release(link);
-
- kfree(link->priv);
-}
-
-static void ixj_get_serial(struct pcmcia_device * link, IXJ * j)
-{
- char *str;
- int i, place;
- dev_dbg(&link->dev, "ixj_get_serial\n");
-
- str = link->prod_id[0];
- if (!str)
- goto failed;
- printk("%s", str);
- str = link->prod_id[1];
- if (!str)
- goto failed;
- printk(" %s", str);
- str = link->prod_id[2];
- if (!str)
- goto failed;
- place = 1;
- for (i = strlen(str) - 1; i >= 0; i--) {
- switch (str[i]) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- j->serial += (str[i] - 48) * place;
- break;
- case 'A':
- case 'B':
- case 'C':
- case 'D':
- case 'E':
- case 'F':
- j->serial += (str[i] - 55) * place;
- break;
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- j->serial += (str[i] - 87) * place;
- break;
- }
- place = place * 0x10;
- }
- str = link->prod_id[3];
- if (!str)
- goto failed;
- printk(" version %s\n", str);
-failed:
- return;
-}
-
-static int ixj_config_check(struct pcmcia_device *p_dev, void *priv_data)
-{
- p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
- p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
- p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
- p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
- p_dev->io_lines = 3;
-
- return pcmcia_request_io(p_dev);
-}
-
-static int ixj_config(struct pcmcia_device * link)
-{
- IXJ *j;
- ixj_info_t *info;
-
- info = link->priv;
- dev_dbg(&link->dev, "ixj_config\n");
-
- link->config_flags = CONF_AUTO_SET_IO;
-
- if (pcmcia_loop_config(link, ixj_config_check, NULL))
- goto failed;
-
- if (pcmcia_enable_device(link))
- goto failed;
-
- /*
- * Register the card with the core.
- */
- j = ixj_pcmcia_probe(link->resource[0]->start,
- link->resource[0]->start + 0x10);
-
- info->ndev = 1;
- ixj_get_serial(link, j);
- return 0;
-
-failed:
- ixj_cs_release(link);
- return -ENODEV;
-}
-
-static void ixj_cs_release(struct pcmcia_device *link)
-{
- ixj_info_t *info = link->priv;
- dev_dbg(&link->dev, "ixj_cs_release\n");
- info->ndev = 0;
- pcmcia_disable_device(link);
-}
-
-static const struct pcmcia_device_id ixj_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x0257, 0x0600),
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, ixj_ids);
-
-static struct pcmcia_driver ixj_driver = {
- .owner = THIS_MODULE,
- .name = "ixj_cs",
- .probe = ixj_probe,
- .remove = ixj_detach,
- .id_table = ixj_ids,
-};
-
-static int __init ixj_pcmcia_init(void)
-{
- return pcmcia_register_driver(&ixj_driver);
-}
-
-static void ixj_pcmcia_exit(void)
-{
- pcmcia_unregister_driver(&ixj_driver);
-}
-
-module_init(ixj_pcmcia_init);
-module_exit(ixj_pcmcia_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/telephony/phonedev.c b/drivers/staging/telephony/phonedev.c
deleted file mode 100644
index 1dd0b6717cc..00000000000
--- a/drivers/staging/telephony/phonedev.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Telephony registration for Linux
- *
- * (c) Copyright 1999 Red Hat Software 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.
- *
- * Author: Alan Cox, <alan@lxorguk.ukuu.org.uk>
- *
- * Fixes: Mar 01 2000 Thomas Sparr, <thomas.l.sparr@telia.com>
- * phone_register_device now works with unit!=PHONE_UNIT_ANY
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/phonedev.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-
-#include <linux/kmod.h>
-#include <linux/sem.h>
-#include <linux/mutex.h>
-
-#define PHONE_NUM_DEVICES 256
-
-/*
- * Active devices
- */
-
-static struct phone_device *phone_device[PHONE_NUM_DEVICES];
-static DEFINE_MUTEX(phone_lock);
-
-/*
- * Open a phone device.
- */
-
-static int phone_open(struct inode *inode, struct file *file)
-{
- unsigned int minor = iminor(inode);
- int err = 0;
- struct phone_device *p;
- const struct file_operations *old_fops, *new_fops = NULL;
-
- if (minor >= PHONE_NUM_DEVICES)
- return -ENODEV;
-
- mutex_lock(&phone_lock);
- p = phone_device[minor];
- if (p)
- new_fops = fops_get(p->f_op);
- if (!new_fops) {
- mutex_unlock(&phone_lock);
- request_module("char-major-%d-%d", PHONE_MAJOR, minor);
- mutex_lock(&phone_lock);
- p = phone_device[minor];
- if (p == NULL || (new_fops = fops_get(p->f_op)) == NULL)
- {
- err=-ENODEV;
- goto end;
- }
- }
- old_fops = file->f_op;
- file->f_op = new_fops;
- if (p->open)
- err = p->open(p, file); /* Tell the device it is open */
- if (err) {
- fops_put(file->f_op);
- file->f_op = fops_get(old_fops);
- }
- fops_put(old_fops);
-end:
- mutex_unlock(&phone_lock);
- return err;
-}
-
-/*
- * Telephony For Linux device drivers request registration here.
- */
-
-int phone_register_device(struct phone_device *p, int unit)
-{
- int base;
- int end;
- int i;
-
- base = 0;
- end = PHONE_NUM_DEVICES - 1;
-
- if (unit != PHONE_UNIT_ANY) {
- base = unit;
- end = unit + 1; /* enter the loop at least one time */
- }
-
- mutex_lock(&phone_lock);
- for (i = base; i < end; i++) {
- if (phone_device[i] == NULL) {
- phone_device[i] = p;
- p->minor = i;
- mutex_unlock(&phone_lock);
- return 0;
- }
- }
- mutex_unlock(&phone_lock);
- return -ENFILE;
-}
-
-/*
- * Unregister an unused Telephony for linux device
- */
-
-void phone_unregister_device(struct phone_device *pfd)
-{
- mutex_lock(&phone_lock);
- if (likely(phone_device[pfd->minor] == pfd))
- phone_device[pfd->minor] = NULL;
- mutex_unlock(&phone_lock);
-}
-
-
-static const struct file_operations phone_fops =
-{
- .owner = THIS_MODULE,
- .open = phone_open,
- .llseek = noop_llseek,
-};
-
-/*
- * Board init functions
- */
-
-
-/*
- * Initialise Telephony for linux
- */
-
-static int __init telephony_init(void)
-{
- printk(KERN_INFO "Linux telephony interface: v1.00\n");
- if (register_chrdev(PHONE_MAJOR, "telephony", &phone_fops)) {
- printk("phonedev: unable to get major %d\n", PHONE_MAJOR);
- return -EIO;
- }
-
- return 0;
-}
-
-static void __exit telephony_exit(void)
-{
- unregister_chrdev(PHONE_MAJOR, "telephony");
-}
-
-module_init(telephony_init);
-module_exit(telephony_exit);
-
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(phone_register_device);
-EXPORT_SYMBOL(phone_unregister_device);
diff --git a/drivers/staging/tidspbridge/dynload/dload_internal.h b/drivers/staging/tidspbridge/dynload/dload_internal.h
index 7b77573fba5..b9d079b9619 100644
--- a/drivers/staging/tidspbridge/dynload/dload_internal.h
+++ b/drivers/staging/tidspbridge/dynload/dload_internal.h
@@ -313,14 +313,14 @@ extern uint32_t dload_reverse_checksum16(void *data, unsigned siz);
/*
* exported by reloc.c
*/
-extern void dload_relocate(struct dload_state *dlthis, tgt_au_t * data,
- struct reloc_record_t *rp, bool * tramps_generated,
+extern void dload_relocate(struct dload_state *dlthis, tgt_au_t *data,
+ struct reloc_record_t *rp, bool *tramps_generated,
bool second_pass);
-extern rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t * data,
+extern rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t *data,
int fieldsz, int offset, unsigned sgn);
-extern int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t * data,
+extern int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t *data,
int fieldsz, int offset, unsigned sgn);
/*
diff --git a/drivers/staging/tidspbridge/dynload/reloc.c b/drivers/staging/tidspbridge/dynload/reloc.c
index 7b28c07ed7c..463abdb6392 100644
--- a/drivers/staging/tidspbridge/dynload/reloc.c
+++ b/drivers/staging/tidspbridge/dynload/reloc.c
@@ -45,7 +45,7 @@ static const char bsssymbol[] = { ".bss" };
* Effect:
* Extracts the specified field and returns it.
************************************************************************* */
-rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t * data, int fieldsz,
+rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t *data, int fieldsz,
int offset, unsigned sgn)
{
register rvalue objval;
@@ -98,7 +98,7 @@ rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t * data, int fieldsz,
************************************************************************* */
static const unsigned char ovf_limit[] = { 1, 2, 2 };
-int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t * data,
+int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t *data,
int fieldsz, int offset, unsigned sgn)
{
register urvalue objval, mask;
@@ -161,7 +161,7 @@ static const u8 c60_scale[SCALE_MASK + 1] = {
* Effect:
* Performs the specified relocation operation
************************************************************************* */
-void dload_relocate(struct dload_state *dlthis, tgt_au_t * data,
+void dload_relocate(struct dload_state *dlthis, tgt_au_t *data,
struct reloc_record_t *rp, bool *tramps_generated,
bool second_pass)
{
diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c
index 701a11ac676..e6f31d817d6 100644
--- a/drivers/staging/tidspbridge/rmgr/drv_interface.c
+++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c
@@ -471,7 +471,7 @@ err1:
return err;
}
-static int __devinit omap34_xx_bridge_probe(struct platform_device *pdev)
+static int omap34_xx_bridge_probe(struct platform_device *pdev)
{
int err;
dev_t dev = 0;
@@ -527,7 +527,7 @@ err1:
return err;
}
-static int __devexit omap34_xx_bridge_remove(struct platform_device *pdev)
+static int omap34_xx_bridge_remove(struct platform_device *pdev)
{
dev_t devno;
int status = 0;
@@ -606,7 +606,7 @@ static struct platform_driver bridge_driver = {
.name = "omap-dsp",
},
.probe = omap34_xx_bridge_probe,
- .remove = __devexit_p(omap34_xx_bridge_remove),
+ .remove = omap34_xx_bridge_remove,
#ifdef CONFIG_PM
.suspend = bridge_suspend,
.resume = bridge_resume,
diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c
index c8d79a7f0e0..ee36415eb26 100644
--- a/drivers/staging/usbip/stub_dev.c
+++ b/drivers/staging/usbip/stub_dev.c
@@ -18,6 +18,7 @@
*/
#include <linux/device.h>
+#include <linux/file.h>
#include <linux/kthread.h>
#include <linux/module.h>
@@ -203,7 +204,7 @@ static void stub_shutdown_connection(struct usbip_device *ud)
* not touch NULL socket.
*/
if (ud->tcp_socket) {
- sock_release(ud->tcp_socket);
+ fput(ud->tcp_socket->file);
ud->tcp_socket = NULL;
}
@@ -432,6 +433,8 @@ static int stub_probe(struct usb_interface *interface,
dev_err(&interface->dev, "stub_add_files for %s\n", udev_busid);
usb_set_intfdata(interface, NULL);
usb_put_intf(interface);
+ usb_put_dev(udev);
+ kthread_stop_put(sdev->ud.eh);
busid_priv->interf_count = 0;
busid_priv->sdev = NULL;
@@ -477,19 +480,17 @@ static void stub_disconnect(struct usb_interface *interface)
/* get stub_device */
if (!sdev) {
dev_err(&interface->dev, "could not get device");
- /* BUG(); */
return;
}
usb_set_intfdata(interface, NULL);
/*
- * NOTE:
- * rx/tx threads are invoked for each usb_device.
+ * NOTE: rx/tx threads are invoked for each usb_device.
*/
stub_remove_files(&interface->dev);
- /*If usb reset called from event handler*/
+ /* If usb reset is called from event handler */
if (busid_priv->sdev->ud.eh == current) {
busid_priv->interf_count--;
return;
@@ -504,13 +505,13 @@ static void stub_disconnect(struct usb_interface *interface)
busid_priv->interf_count = 0;
- /* 1. shutdown the current connection */
+ /* shutdown the current connection */
shutdown_busid(busid_priv);
usb_put_dev(sdev->udev);
usb_put_intf(interface);
- /* 3. free sdev */
+ /* free sdev */
busid_priv->sdev = NULL;
stub_device_free(sdev);
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
index 694cfd7596f..0572a15242b 100644
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -164,7 +164,6 @@ static int tweak_set_configuration_cmd(struct urb *urb)
config, dev_name(&urb->dev->dev));
return 0;
- /* return usb_driver_set_configuration(urb->dev, config); */
}
static int tweak_reset_device_cmd(struct urb *urb)
@@ -480,7 +479,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
return;
}
- /* set priv->urb->transfer_buffer */
+ /* allocate urb transfer buffer, if needed */
if (pdu->u.cmd_submit.transfer_buffer_length > 0) {
priv->urb->transfer_buffer =
kzalloc(pdu->u.cmd_submit.transfer_buffer_length,
@@ -492,7 +491,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
}
}
- /* set priv->urb->setup_packet */
+ /* copy urb setup packet */
priv->urb->setup_packet = kmemdup(&pdu->u.cmd_submit.setup, 8,
GFP_KERNEL);
if (!priv->urb->setup_packet) {
diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c
index 023fda305be..513961fef05 100644
--- a/drivers/staging/usbip/stub_tx.c
+++ b/drivers/staging/usbip/stub_tx.c
@@ -166,7 +166,7 @@ static int stub_send_ret_submit(struct stub_device *sdev)
int ret;
struct urb *urb = priv->urb;
struct usbip_header pdu_header;
- void *iso_buffer = NULL;
+ struct usbip_iso_packet_descriptor *iso_buffer = NULL;
struct kvec *iov = NULL;
int iovnum = 0;
@@ -192,7 +192,6 @@ static int stub_send_ret_submit(struct stub_device *sdev)
setup_ret_submit_pdu(&pdu_header, urb);
usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n",
pdu_header.base.seqnum, urb);
- /*usbip_dump_header(pdu_header);*/
usbip_header_correct_endian(&pdu_header, 1);
iov[iovnum].iov_base = &pdu_header;
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index 57f11f9cd8a..75189feac38 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -413,8 +413,10 @@ struct socket *sockfd_to_socket(unsigned int sockfd)
inode = file->f_dentry->d_inode;
- if (!inode || !S_ISSOCK(inode->i_mode))
+ if (!inode || !S_ISSOCK(inode->i_mode)) {
+ fput(file);
return NULL;
+ }
socket = SOCKET_I(inode);
@@ -439,7 +441,6 @@ static void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb,
* will be discussed when usbip is ported to other operating systems.
*/
if (pack) {
- /* vhci_tx.c */
spdu->transfer_flags =
tweak_transfer_flags(urb->transfer_flags);
spdu->transfer_buffer_length = urb->transfer_buffer_length;
@@ -447,9 +448,7 @@ static void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb,
spdu->number_of_packets = urb->number_of_packets;
spdu->interval = urb->interval;
} else {
- /* stub_rx.c */
urb->transfer_flags = spdu->transfer_flags;
-
urb->transfer_buffer_length = spdu->transfer_buffer_length;
urb->start_frame = spdu->start_frame;
urb->number_of_packets = spdu->number_of_packets;
@@ -463,16 +462,12 @@ static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb,
struct usbip_header_ret_submit *rpdu = &pdu->u.ret_submit;
if (pack) {
- /* stub_tx.c */
-
rpdu->status = urb->status;
rpdu->actual_length = urb->actual_length;
rpdu->start_frame = urb->start_frame;
rpdu->number_of_packets = urb->number_of_packets;
rpdu->error_count = urb->error_count;
} else {
- /* vhci_rx.c */
-
urb->status = rpdu->status;
urb->actual_length = rpdu->actual_length;
urb->start_frame = rpdu->start_frame;
@@ -639,28 +634,26 @@ static void usbip_pack_iso(struct usbip_iso_packet_descriptor *iso,
}
/* must free buffer */
-void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen)
+struct usbip_iso_packet_descriptor*
+usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen)
{
- void *buff;
struct usbip_iso_packet_descriptor *iso;
int np = urb->number_of_packets;
ssize_t size = np * sizeof(*iso);
int i;
- buff = kzalloc(size, GFP_KERNEL);
- if (!buff)
+ iso = kzalloc(size, GFP_KERNEL);
+ if (!iso)
return NULL;
for (i = 0; i < np; i++) {
- iso = buff + (i * sizeof(*iso));
-
- usbip_pack_iso(iso, &urb->iso_frame_desc[i], 1);
- usbip_iso_packet_correct_endian(iso, 1);
+ usbip_pack_iso(&iso[i], &urb->iso_frame_desc[i], 1);
+ usbip_iso_packet_correct_endian(&iso[i], 1);
}
*bufflen = size;
- return buff;
+ return iso;
}
EXPORT_SYMBOL_GPL(usbip_alloc_iso_desc_pdu);
@@ -680,8 +673,6 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb)
/* my Bluetooth dongle gets ISO URBs which are np = 0 */
if (np == 0) {
- /* pr_info("iso np == 0\n"); */
- /* usbip_dump_urb(urb); */
return 0;
}
@@ -703,11 +694,10 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb)
return -EPIPE;
}
+ iso = (struct usbip_iso_packet_descriptor *) buff;
for (i = 0; i < np; i++) {
- iso = buff + (i * sizeof(*iso));
-
- usbip_iso_packet_correct_endian(iso, 0);
- usbip_pack_iso(iso, &urb->iso_frame_desc[i], 0);
+ usbip_iso_packet_correct_endian(&iso[i], 0);
+ usbip_pack_iso(&iso[i], &urb->iso_frame_desc[i], 0);
total_length += urb->iso_frame_desc[i].actual_length;
}
@@ -754,7 +744,7 @@ void usbip_pad_iso(struct usbip_device *ud, struct urb *urb)
/*
* if actual_length is transfer_buffer_length then no padding is
* present.
- */
+ */
if (urb->actual_length == urb->transfer_buffer_length)
return;
@@ -778,14 +768,12 @@ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
int size;
if (ud->side == USBIP_STUB) {
- /* stub_rx.c */
/* the direction of urb must be OUT. */
if (usb_pipein(urb->pipe))
return 0;
size = urb->transfer_buffer_length;
} else {
- /* vhci_rx.c */
/* the direction of urb must be IN. */
if (usb_pipeout(urb->pipe))
return 0;
diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h
index 5d89c0fd6f7..7e6c5436d97 100644
--- a/drivers/staging/usbip/usbip_common.h
+++ b/drivers/staging/usbip/usbip_common.h
@@ -320,7 +320,9 @@ void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd,
int pack);
void usbip_header_correct_endian(struct usbip_header *pdu, int send);
-void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen);
+struct usbip_iso_packet_descriptor*
+usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen);
+
/* some members of urb must be substituted before. */
int usbip_recv_iso(struct usbip_device *ud, struct urb *urb);
void usbip_pad_iso(struct usbip_device *ud, struct urb *urb);
diff --git a/drivers/staging/usbip/userspace/src/usbip_detach.c b/drivers/staging/usbip/userspace/src/usbip_detach.c
index 89bf3c195c2..dac5f065755 100644
--- a/drivers/staging/usbip/userspace/src/usbip_detach.c
+++ b/drivers/staging/usbip/userspace/src/usbip_detach.c
@@ -19,6 +19,7 @@
#include <sysfs/libsysfs.h>
#include <ctype.h>
+#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -46,6 +47,7 @@ static int detach_port(char *port)
{
int ret;
uint8_t portnum;
+ char path[PATH_MAX+1];
for (unsigned int i=0; i < strlen(port); i++)
if (!isdigit(port[i])) {
@@ -57,6 +59,13 @@ static int detach_port(char *port)
portnum = atoi(port);
+ /* remove the port state file */
+
+ snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", portnum);
+
+ remove(path);
+ rmdir(VHCI_STATE_PATH);
+
ret = usbip_vhci_driver_open();
if (ret < 0) {
err("open vhci_driver");
diff --git a/drivers/staging/usbip/vhci.h b/drivers/staging/usbip/vhci.h
index c66b8b3f97b..5dddc4d4b6a 100644
--- a/drivers/staging/usbip/vhci.h
+++ b/drivers/staging/usbip/vhci.h
@@ -99,7 +99,6 @@ extern const struct attribute_group dev_attr_group;
/* vhci_hcd.c */
void rh_port_connect(int rhport, enum usb_device_speed speed);
-void rh_port_disconnect(int rhport);
/* vhci_rx.c */
struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum);
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c
index 620d1beb458..c3aa2195f1a 100644
--- a/drivers/staging/usbip/vhci_hcd.c
+++ b/drivers/staging/usbip/vhci_hcd.c
@@ -18,6 +18,7 @@
*/
#include <linux/init.h>
+#include <linux/file.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
@@ -140,32 +141,23 @@ void rh_port_connect(int rhport, enum usb_device_speed speed)
break;
}
- /* spin_lock(&the_controller->vdev[rhport].ud.lock);
- * the_controller->vdev[rhport].ud.status = VDEV_CONNECT;
- * spin_unlock(&the_controller->vdev[rhport].ud.lock); */
-
spin_unlock_irqrestore(&the_controller->lock, flags);
usb_hcd_poll_rh_status(vhci_to_hcd(the_controller));
}
-void rh_port_disconnect(int rhport)
+static void rh_port_disconnect(int rhport)
{
unsigned long flags;
usbip_dbg_vhci_rh("rh_port_disconnect %d\n", rhport);
spin_lock_irqsave(&the_controller->lock, flags);
- /* stop_activity(dum, driver); */
+
the_controller->port_status[rhport] &= ~USB_PORT_STAT_CONNECTION;
the_controller->port_status[rhport] |=
(1 << USB_PORT_FEAT_C_CONNECTION);
- /* not yet complete the disconnection
- * spin_lock(&vdev->ud.lock);
- * vdev->ud.status = VHC_ST_DISCONNECT;
- * spin_unlock(&vdev->ud.lock); */
-
spin_unlock_irqrestore(&the_controller->lock, flags);
usb_hcd_poll_rh_status(vhci_to_hcd(the_controller));
}
@@ -228,7 +220,6 @@ done:
return changed ? retval : 0;
}
-/* See hub_configure in hub.c */
static inline void hub_descriptor(struct usb_hub_descriptor *desc)
{
memset(desc, 0, sizeof(*desc));
@@ -292,8 +283,6 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
usbip_dbg_vhci_rh(" ClearPortFeature: "
"USB_PORT_FEAT_POWER\n");
dum->port_status[rhport] = 0;
- /* dum->address = 0; */
- /* dum->hdev = 0; */
dum->resuming = 0;
break;
case USB_PORT_FEAT_C_RESET:
@@ -333,11 +322,11 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
retval = -EPIPE;
}
- /* we do no care of resume. */
+ /* we do not care about resume. */
/* whoever resets or resumes must GetPortStatus to
* complete it!!
- * */
+ */
if (dum->resuming && time_after(jiffies, dum->re_timeout)) {
dum->port_status[rhport] |=
(1 << USB_PORT_FEAT_C_SUSPEND);
@@ -345,11 +334,6 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
~(1 << USB_PORT_FEAT_SUSPEND);
dum->resuming = 0;
dum->re_timeout = 0;
- /* if (dum->driver && dum->driver->resume) {
- * spin_unlock (&dum->lock);
- * dum->driver->resume (&dum->gadget);
- * spin_lock (&dum->lock);
- * } */
}
if ((dum->port_status[rhport] & (1 << USB_PORT_FEAT_RESET)) !=
@@ -411,9 +395,6 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
default:
pr_err("default: no such request\n");
- /* dev_dbg (hardware,
- * "hub control req%04x v%04x i%04x l%d\n",
- * typeReq, wValue, wIndex, wLength); */
/* "protocol stall" on error */
retval = -EPIPE;
@@ -456,7 +437,6 @@ static void vhci_tx_urb(struct urb *urb)
if (!vdev) {
pr_err("could not get virtual device");
- /* BUG(); */
return;
}
@@ -813,7 +793,7 @@ static void vhci_shutdown_connection(struct usbip_device *ud)
kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR);
}
- /* kill threads related to this sdev, if v.c. exists */
+ /* kill threads related to this sdev */
if (vdev->ud.tcp_rx) {
kthread_stop_put(vdev->ud.tcp_rx);
vdev->ud.tcp_rx = NULL;
@@ -825,8 +805,8 @@ static void vhci_shutdown_connection(struct usbip_device *ud)
pr_info("stop threads\n");
/* active connection is closed */
- if (vdev->ud.tcp_socket != NULL) {
- sock_release(vdev->ud.tcp_socket);
+ if (vdev->ud.tcp_socket) {
+ fput(vdev->ud.tcp_socket->file);
vdev->ud.tcp_socket = NULL;
}
pr_info("release socket\n");
@@ -872,7 +852,10 @@ static void vhci_device_reset(struct usbip_device *ud)
usb_put_dev(vdev->udev);
vdev->udev = NULL;
- ud->tcp_socket = NULL;
+ if (ud->tcp_socket) {
+ fput(ud->tcp_socket->file);
+ ud->tcp_socket = NULL;
+ }
ud->status = VDEV_ST_NULL;
spin_unlock(&ud->lock);
@@ -928,7 +911,6 @@ static int vhci_start(struct usb_hcd *hcd)
spin_lock_init(&vhci->lock);
hcd->power_budget = 0; /* no limit */
- hcd->state = HC_STATE_RUNNING;
hcd->uses_new_polling = 1;
/* vhci_hcd is now ready to be controlled through sysfs */
@@ -976,8 +958,6 @@ static int vhci_bus_suspend(struct usb_hcd *hcd)
dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__);
spin_lock_irq(&vhci->lock);
- /* vhci->rh_state = DUMMY_RH_SUSPENDED;
- * set_link_state(vhci); */
hcd->state = HC_STATE_SUSPENDED;
spin_unlock_irq(&vhci->lock);
@@ -995,10 +975,6 @@ static int vhci_bus_resume(struct usb_hcd *hcd)
if (!HCD_HW_ACCESSIBLE(hcd)) {
rc = -ESHUTDOWN;
} else {
- /* vhci->rh_state = DUMMY_RH_RUNNING;
- * set_link_state(vhci);
- * if (!list_empty(&vhci->urbp_list))
- * mod_timer(&vhci->timer, jiffies); */
hcd->state = HC_STATE_RUNNING;
}
spin_unlock_irq(&vhci->lock);
@@ -1151,7 +1127,7 @@ static int vhci_hcd_resume(struct platform_device *pdev)
static struct platform_driver vhci_driver = {
.probe = vhci_hcd_probe,
- .remove = __devexit_p(vhci_hcd_remove),
+ .remove = vhci_hcd_remove,
.suspend = vhci_hcd_suspend,
.resume = vhci_hcd_resume,
.driver = {
@@ -1175,7 +1151,6 @@ static struct platform_device the_pdev = {
.name = (char *) driver_name,
.id = -1,
.dev = {
- /* .driver = &vhci_driver, */
.release = the_pdev_release,
},
};
diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c
index f0eaf04fa25..ba5f1c079b6 100644
--- a/drivers/staging/usbip/vhci_rx.c
+++ b/drivers/staging/usbip/vhci_rx.c
@@ -167,7 +167,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
} else {
usbip_dbg_vhci_rx("now giveback urb %p\n", urb);
- /* If unlink is succeed, status is -ECONNRESET */
+ /* If unlink is successful, status is -ECONNRESET */
urb->status = pdu->u.ret_unlink.status;
pr_info("urb->status %d\n", urb->status);
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c
index 7ce9c2f7e44..c66e9c05c76 100644
--- a/drivers/staging/usbip/vhci_sysfs.c
+++ b/drivers/staging/usbip/vhci_sysfs.c
@@ -18,6 +18,7 @@
*/
#include <linux/kthread.h>
+#include <linux/file.h>
#include <linux/net.h>
#include "usbip_common.h"
@@ -189,7 +190,8 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
if (valid_args(rhport, speed) < 0)
return -EINVAL;
- /* check sockfd */
+ /* Extract socket from fd. */
+ /* The correct way to clean this up is to fput(socket->file). */
socket = sockfd_to_socket(sockfd);
if (!socket)
return -EINVAL;
@@ -206,6 +208,8 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
spin_unlock(&vdev->ud.lock);
spin_unlock(&the_controller->lock);
+ fput(socket->file);
+
dev_err(dev, "port %d already used\n", rhport);
return -EINVAL;
}
diff --git a/drivers/staging/usbip/vhci_tx.c b/drivers/staging/usbip/vhci_tx.c
index 9b437e7ef1a..b1f0dcd68f5 100644
--- a/drivers/staging/usbip/vhci_tx.c
+++ b/drivers/staging/usbip/vhci_tx.c
@@ -76,7 +76,7 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev)
int ret;
struct urb *urb = priv->urb;
struct usbip_header pdu_header;
- void *iso_buffer = NULL;
+ struct usbip_iso_packet_descriptor *iso_buffer = NULL;
txsize = 0;
memset(&pdu_header, 0, sizeof(pdu_header));
diff --git a/drivers/staging/vme/devices/vme_pio2.h b/drivers/staging/vme/devices/vme_pio2.h
index 72d9ce0bcb4..d5d94c43c07 100644
--- a/drivers/staging/vme/devices/vme_pio2.h
+++ b/drivers/staging/vme/devices/vme_pio2.h
@@ -243,7 +243,7 @@ struct pio2_card {
int pio2_cntr_reset(struct pio2_card *);
int pio2_gpio_reset(struct pio2_card *);
-int __devinit pio2_gpio_init(struct pio2_card *);
+int pio2_gpio_init(struct pio2_card *);
void pio2_gpio_exit(struct pio2_card *);
#endif /* _VME_PIO2_H_ */
diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c
index dad8281915b..0331178ca3b 100644
--- a/drivers/staging/vme/devices/vme_pio2_core.c
+++ b/drivers/staging/vme/devices/vme_pio2_core.c
@@ -42,8 +42,8 @@ static int variant_num;
static bool loopback;
static int pio2_match(struct vme_dev *);
-static int __devinit pio2_probe(struct vme_dev *);
-static int __devexit pio2_remove(struct vme_dev *);
+static int pio2_probe(struct vme_dev *);
+static int pio2_remove(struct vme_dev *);
static int pio2_get_led(struct pio2_card *card)
{
@@ -156,7 +156,7 @@ static struct vme_driver pio2_driver = {
.name = driver_name,
.match = pio2_match,
.probe = pio2_probe,
- .remove = __devexit_p(pio2_remove),
+ .remove = pio2_remove,
};
@@ -222,7 +222,7 @@ static int pio2_match(struct vme_dev *vdev)
return 1;
}
-static int __devinit pio2_probe(struct vme_dev *vdev)
+static int pio2_probe(struct vme_dev *vdev)
{
struct pio2_card *card;
int retval;
@@ -455,7 +455,7 @@ err_struct:
return retval;
}
-static int __devexit pio2_remove(struct vme_dev *vdev)
+static int pio2_remove(struct vme_dev *vdev)
{
int vec;
int i;
diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c
index ad76a477825..69d880517e0 100644
--- a/drivers/staging/vme/devices/vme_pio2_gpio.c
+++ b/drivers/staging/vme/devices/vme_pio2_gpio.c
@@ -186,7 +186,7 @@ int pio2_gpio_reset(struct pio2_card *card)
return 0;
}
-int __devinit pio2_gpio_init(struct pio2_card *card)
+int pio2_gpio_init(struct pio2_card *card)
{
int retval = 0;
char *label;
diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index c3f94f311ca..4ef852c4c4e 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -15,6 +15,8 @@
* option) any later version.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/device.h>
@@ -135,8 +137,8 @@ static loff_t vme_user_llseek(struct file *, loff_t, int);
static long vme_user_unlocked_ioctl(struct file *, unsigned int, unsigned long);
static int vme_user_match(struct vme_dev *);
-static int __devinit vme_user_probe(struct vme_dev *);
-static int __devexit vme_user_remove(struct vme_dev *);
+static int vme_user_probe(struct vme_dev *);
+static int vme_user_remove(struct vme_dev *);
static const struct file_operations vme_user_fops = {
.open = vme_user_open,
@@ -170,7 +172,7 @@ static int vme_user_open(struct inode *inode, struct file *file)
mutex_lock(&image[minor].mutex);
/* Allow device to be opened if a resource is needed and allocated. */
if (minor < CONTROL_MINOR && image[minor].resource == NULL) {
- printk(KERN_ERR "No resources allocated for device\n");
+ pr_err("No resources allocated for device\n");
err = -EINVAL;
goto err_res;
}
@@ -225,13 +227,13 @@ static ssize_t resource_to_user(int minor, char __user *buf, size_t count,
(unsigned long)copied);
if (retval != 0) {
copied = (copied - retval);
- printk(KERN_INFO "User copy failed\n");
+ pr_info("User copy failed\n");
return -EINVAL;
}
} else {
/* XXX Need to write this */
- printk(KERN_INFO "Currently don't support large transfers\n");
+ pr_info("Currently don't support large transfers\n");
/* Map in pages from userspace */
/* Call vme_master_read to do the transfer */
@@ -265,7 +267,7 @@ static ssize_t resource_from_user(unsigned int minor, const char __user *buf,
image[minor].kern_buf, copied, *ppos);
} else {
/* XXX Need to write this */
- printk(KERN_INFO "Currently don't support large transfers\n");
+ pr_info("Currently don't support large transfers\n");
/* Map in pages from userspace */
/* Call vme_master_write to do the transfer */
@@ -286,7 +288,7 @@ static ssize_t buffer_to_user(unsigned int minor, char __user *buf,
retval = __copy_to_user(buf, image_ptr, (unsigned long)count);
if (retval != 0) {
retval = (count - retval);
- printk(KERN_WARNING "Partial copy to userspace\n");
+ pr_warn("Partial copy to userspace\n");
} else
retval = count;
@@ -305,7 +307,7 @@ static ssize_t buffer_from_user(unsigned int minor, const char __user *buf,
retval = __copy_from_user(image_ptr, buf, (unsigned long)count);
if (retval != 0) {
retval = (count - retval);
- printk(KERN_WARNING "Partial copy to userspace\n");
+ pr_warn("Partial copy to userspace\n");
} else
retval = count;
@@ -476,7 +478,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file,
copied = copy_from_user(&irq_req, argp,
sizeof(struct vme_irq_id));
if (copied != 0) {
- printk(KERN_WARNING "Partial copy from userspace\n");
+ pr_warn("Partial copy from userspace\n");
return -EFAULT;
}
@@ -503,8 +505,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file,
copied = copy_to_user(argp, &master,
sizeof(struct vme_master));
if (copied != 0) {
- printk(KERN_WARNING "Partial copy to "
- "userspace\n");
+ pr_warn("Partial copy to userspace\n");
return -EFAULT;
}
@@ -515,8 +516,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file,
copied = copy_from_user(&master, argp, sizeof(master));
if (copied != 0) {
- printk(KERN_WARNING "Partial copy from "
- "userspace\n");
+ pr_warn("Partial copy from userspace\n");
return -EFAULT;
}
@@ -546,8 +546,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file,
copied = copy_to_user(argp, &slave,
sizeof(struct vme_slave));
if (copied != 0) {
- printk(KERN_WARNING "Partial copy to "
- "userspace\n");
+ pr_warn("Partial copy to userspace\n");
return -EFAULT;
}
@@ -558,8 +557,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file,
copied = copy_from_user(&slave, argp, sizeof(slave));
if (copied != 0) {
- printk(KERN_WARNING "Partial copy from "
- "userspace\n");
+ pr_warn("Partial copy from userspace\n");
return -EFAULT;
}
@@ -599,8 +597,8 @@ static void buf_unalloc(int num)
{
if (image[num].kern_buf) {
#ifdef VME_DEBUG
- printk(KERN_DEBUG "UniverseII:Releasing buffer at %p\n",
- image[num].pci_buf);
+ pr_debug("UniverseII:Releasing buffer at %p\n",
+ image[num].pci_buf);
#endif
vme_free_consistent(image[num].resource, image[num].size_buf,
@@ -612,7 +610,7 @@ static void buf_unalloc(int num)
#ifdef VME_DEBUG
} else {
- printk(KERN_DEBUG "UniverseII: Buffer not allocated\n");
+ pr_debug("UniverseII: Buffer not allocated\n");
#endif
}
}
@@ -621,7 +619,7 @@ static struct vme_driver vme_user_driver = {
.name = driver_name,
.match = vme_user_match,
.probe = vme_user_probe,
- .remove = __devexit_p(vme_user_remove),
+ .remove = vme_user_remove,
};
@@ -629,11 +627,10 @@ static int __init vme_user_init(void)
{
int retval = 0;
- printk(KERN_INFO "VME User Space Access Driver\n");
+ pr_info("VME User Space Access Driver\n");
if (bus_num == 0) {
- printk(KERN_ERR "%s: No cards, skipping registration\n",
- driver_name);
+ pr_err("No cards, skipping registration\n");
retval = -ENODEV;
goto err_nocard;
}
@@ -642,8 +639,8 @@ static int __init vme_user_init(void)
* in future revisions if that ever becomes necessary.
*/
if (bus_num > VME_USER_BUS_MAX) {
- printk(KERN_ERR "%s: Driver only able to handle %d buses\n",
- driver_name, VME_USER_BUS_MAX);
+ pr_err("Driver only able to handle %d buses\n",
+ VME_USER_BUS_MAX);
bus_num = VME_USER_BUS_MAX;
}
@@ -676,15 +673,14 @@ static int vme_user_match(struct vme_dev *vdev)
* as practical. We will therefore reserve the buffers and request the images
* here so that we don't have to do it later.
*/
-static int __devinit vme_user_probe(struct vme_dev *vdev)
+static int vme_user_probe(struct vme_dev *vdev)
{
int i, err;
char name[12];
/* Save pointer to the bridge device */
if (vme_user_bridge != NULL) {
- printk(KERN_ERR "%s: Driver can only be loaded for 1 device\n",
- driver_name);
+ dev_err(&vdev->dev, "Driver can only be loaded for 1 device\n");
err = -EINVAL;
goto err_dev;
}
@@ -707,8 +703,8 @@ static int __devinit vme_user_probe(struct vme_dev *vdev)
err = register_chrdev_region(MKDEV(VME_MAJOR, 0), VME_DEVS,
driver_name);
if (err) {
- printk(KERN_WARNING "%s: Error getting Major Number %d for "
- "driver.\n", driver_name, VME_MAJOR);
+ dev_warn(&vdev->dev, "Error getting Major Number %d for driver.\n",
+ VME_MAJOR);
goto err_region;
}
@@ -718,7 +714,7 @@ static int __devinit vme_user_probe(struct vme_dev *vdev)
vme_user_cdev->owner = THIS_MODULE;
err = cdev_add(vme_user_cdev, MKDEV(VME_MAJOR, 0), VME_DEVS);
if (err) {
- printk(KERN_WARNING "%s: cdev_all failed\n", driver_name);
+ dev_warn(&vdev->dev, "cdev_all failed\n");
goto err_char;
}
@@ -732,16 +728,16 @@ static int __devinit vme_user_probe(struct vme_dev *vdev)
image[i].resource = vme_slave_request(vme_user_bridge,
VME_A24, VME_SCT);
if (image[i].resource == NULL) {
- printk(KERN_WARNING "Unable to allocate slave "
- "resource\n");
+ dev_warn(&vdev->dev,
+ "Unable to allocate slave resource\n");
goto err_slave;
}
image[i].size_buf = PCI_BUF_SIZE;
image[i].kern_buf = vme_alloc_consistent(image[i].resource,
image[i].size_buf, &image[i].pci_buf);
if (image[i].kern_buf == NULL) {
- printk(KERN_WARNING "Unable to allocate memory for "
- "buffer\n");
+ dev_warn(&vdev->dev,
+ "Unable to allocate memory for buffer\n");
image[i].pci_buf = 0;
vme_slave_free(image[i].resource);
err = -ENOMEM;
@@ -758,15 +754,15 @@ static int __devinit vme_user_probe(struct vme_dev *vdev)
image[i].resource = vme_master_request(vme_user_bridge,
VME_A32, VME_SCT, VME_D32);
if (image[i].resource == NULL) {
- printk(KERN_WARNING "Unable to allocate master "
- "resource\n");
+ dev_warn(&vdev->dev,
+ "Unable to allocate master resource\n");
goto err_master;
}
image[i].size_buf = PCI_BUF_SIZE;
image[i].kern_buf = kmalloc(image[i].size_buf, GFP_KERNEL);
if (image[i].kern_buf == NULL) {
- printk(KERN_WARNING "Unable to allocate memory for "
- "master window buffers\n");
+ dev_warn(&vdev->dev,
+ "Unable to allocate memory for master window buffers\n");
err = -ENOMEM;
goto err_master_buf;
}
@@ -775,7 +771,7 @@ static int __devinit vme_user_probe(struct vme_dev *vdev)
/* Create sysfs entries - on udev systems this creates the dev files */
vme_user_sysfs_class = class_create(THIS_MODULE, driver_name);
if (IS_ERR(vme_user_sysfs_class)) {
- printk(KERN_ERR "Error creating vme_user class.\n");
+ dev_err(&vdev->dev, "Error creating vme_user class.\n");
err = PTR_ERR(vme_user_sysfs_class);
goto err_class;
}
@@ -803,8 +799,7 @@ static int __devinit vme_user_probe(struct vme_dev *vdev)
image[i].device = device_create(vme_user_sysfs_class, NULL,
MKDEV(VME_MAJOR, i), NULL, name, num);
if (IS_ERR(image[i].device)) {
- printk(KERN_INFO "%s: Error creating sysfs device\n",
- driver_name);
+ dev_info(&vdev->dev, "Error creating sysfs device\n");
err = PTR_ERR(image[i].device);
goto err_sysfs;
}
@@ -851,7 +846,7 @@ err_dev:
return err;
}
-static int __devexit vme_user_remove(struct vme_dev *dev)
+static int vme_user_remove(struct vme_dev *dev)
{
int i;
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index 9e3b3f2bbe5..453c83d7fe8 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -356,7 +356,7 @@ static char* get_chip_name(int chip_id)
return chip_info_table[i].name;
}
-static void __devexit vt6655_remove(struct pci_dev *pcid)
+static void vt6655_remove(struct pci_dev *pcid)
{
PSDevice pDevice = pci_get_drvdata(pcid);
@@ -902,7 +902,7 @@ static const struct net_device_ops device_netdev_ops = {
.ndo_set_rx_mode = device_set_multi,
};
-static int __devinit
+static int
vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
{
static bool bFirst = true;
@@ -1099,7 +1099,7 @@ static void device_print_info(PSDevice pDevice)
}
-static void __devinit vt6655_init_info(struct pci_dev* pcid, PSDevice* ppDevice,
+static void vt6655_init_info(struct pci_dev* pcid, PSDevice* ppDevice,
PCHIP_INFO pChip_info) {
PSDevice p;
diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c
index 67b1b88b1b8..5f13890cf12 100644
--- a/drivers/staging/vt6655/hostap.c
+++ b/drivers/staging/vt6655/hostap.c
@@ -596,9 +596,9 @@ static int hostap_set_encryption(PSDevice pDevice,
if (param->u.crypt.seq) {
memcpy(&abySeq, param->u.crypt.seq, 8);
- for (ii = 0 ; ii < 8 ; ii++) {
- KeyRSC |= (abySeq[ii] << (ii * 8));
- }
+ for (ii = 0 ; ii < 8 ; ii++)
+ KeyRSC |= (unsigned long)abySeq[ii] << (ii * 8);
+
dwKeyIndex |= 1 << 29;
pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC;
}
diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c
index 4972e57845c..875ee444238 100644
--- a/drivers/staging/vt6655/rxtx.c
+++ b/drivers/staging/vt6655/rxtx.c
@@ -242,7 +242,7 @@ s_vFillTxKey (
}
// Append IV after Mac Header
*pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111
- *pdwIV |= (byKeyIndex << 30);
+ *pdwIV |= (unsigned long)byKeyIndex << 30;
*pdwIV = cpu_to_le32(*pdwIV);
pDevice->dwIVCounter++;
if (pDevice->dwIVCounter > WEP_IV_MASK) {
diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c
index 94bd1fc42c9..6d0b87a1426 100644
--- a/drivers/staging/vt6655/wcmd.c
+++ b/drivers/staging/vt6655/wcmd.c
@@ -412,6 +412,7 @@ vCommandTimer (
if (!is_channel_valid(pMgmt->uScanChannel)) {
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d \n",pMgmt->uScanChannel);
s_bCommandComplete(pDevice);
+ spin_unlock_irq(&pDevice->lock);
return;
}
//printk("chester-pMgmt->uScanChannel=%d,pDevice->byMaxChannel=%d\n",pMgmt->uScanChannel,pDevice->byMaxChannel);
diff --git a/drivers/staging/vt6656/80211mgr.c b/drivers/staging/vt6656/80211mgr.c
index 39f98423dc0..e6ced95e6fa 100644
--- a/drivers/staging/vt6656/80211mgr.c
+++ b/drivers/staging/vt6656/80211mgr.c
@@ -52,11 +52,11 @@
*
*/
+#include "device.h"
#include "tmacro.h"
#include "tether.h"
#include "80211mgr.h"
#include "80211hdr.h"
-#include "device.h"
#include "wpa.h"
/*--------------------- Static Definitions -------------------------*/
diff --git a/drivers/staging/vt6656/Makefile b/drivers/staging/vt6656/Makefile
index 41ed06bb665..c998547884c 100644
--- a/drivers/staging/vt6656/Makefile
+++ b/drivers/staging/vt6656/Makefile
@@ -20,7 +20,6 @@ vt6656_stage-y += main_usb.o \
rc4.o \
tether.o \
tcrc.o \
- ioctl.o \
hostap.o \
wpa.o \
key.o \
diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c
index 2ac066df834..6a139419224 100644
--- a/drivers/staging/vt6656/bssdb.c
+++ b/drivers/staging/vt6656/bssdb.c
@@ -882,7 +882,6 @@ void BSSvSecondCallBack(void *hDeviceContext)
unsigned int uSleepySTACnt = 0;
unsigned int uNonShortSlotSTACnt = 0;
unsigned int uLongPreambleSTACnt = 0;
- viawget_wpa_header *wpahdr;
spin_lock_irq(&pDevice->lock);
@@ -913,7 +912,6 @@ if(pDevice->byReAssocCount > 0) {
if((pDevice->byReAssocCount > 10) && (pDevice->bLinkPass != TRUE)) { //10 sec timeout
printk("Re-association timeout!!!\n");
pDevice->byReAssocCount = 0;
- #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
// if(pDevice->bWPASuppWextEnabled == TRUE)
{
union iwreq_data wrqu;
@@ -922,20 +920,11 @@ if(pDevice->byReAssocCount > 0) {
PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
}
- #endif
}
else if(pDevice->bLinkPass == TRUE)
pDevice->byReAssocCount = 0;
}
-if((pMgmt->eCurrState!=WMAC_STATE_ASSOC) &&
- (pMgmt->eLastState==WMAC_STATE_ASSOC))
-{
- union iwreq_data wrqu;
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.flags = RT_DISCONNECTED_EVENT_FLAG;
- wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
-}
pMgmt->eLastState = pMgmt->eCurrState ;
s_uCalculateLinkQual((void *)pDevice);
@@ -1102,21 +1091,6 @@ if((pMgmt->eCurrState!=WMAC_STATE_ASSOC) &&
DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
/* let wpa supplicant know AP may disconnect */
- if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
- wpahdr = (viawget_wpa_header *)pDevice->skb->data;
- wpahdr->type = VIAWGET_DISASSOC_MSG;
- wpahdr->resp_ie_len = 0;
- wpahdr->req_ie_len = 0;
- skb_put(pDevice->skb, sizeof(viawget_wpa_header));
- pDevice->skb->dev = pDevice->wpadev;
- skb_reset_mac_header(pDevice->skb);
- pDevice->skb->pkt_type = PACKET_HOST;
- pDevice->skb->protocol = htons(ETH_P_802_2);
- memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
- netif_rx(pDevice->skb);
- pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
- }
- #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
{
union iwreq_data wrqu;
memset(&wrqu, 0, sizeof (wrqu));
@@ -1124,7 +1098,6 @@ if((pMgmt->eCurrState!=WMAC_STATE_ASSOC) &&
PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
}
- #endif
}
}
else if (pItemSSID->len != 0) {
@@ -1144,20 +1117,6 @@ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bIsRoaming %d, !\n", pDevice->bIsRoaming );
pDevice->uAutoReConnectTime = 0;
pDevice->uIsroamingTime = 0;
pDevice->bRoaming = FALSE;
-
- wpahdr = (viawget_wpa_header *)pDevice->skb->data;
- wpahdr->type = VIAWGET_CCKM_ROAM_MSG;
- wpahdr->resp_ie_len = 0;
- wpahdr->req_ie_len = 0;
- skb_put(pDevice->skb, sizeof(viawget_wpa_header));
- pDevice->skb->dev = pDevice->wpadev;
- skb_reset_mac_header(pDevice->skb);
- pDevice->skb->pkt_type = PACKET_HOST;
- pDevice->skb->protocol = htons(ETH_P_802_2);
- memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
- netif_rx(pDevice->skb);
- pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
-
}
else if ((pDevice->bRoaming == FALSE)&&(pDevice->bIsRoaming == TRUE)) {
pDevice->uIsroamingTime++;
@@ -1169,11 +1128,9 @@ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bIsRoaming %d, !\n", pDevice->bIsRoaming );
else {
if (pDevice->uAutoReConnectTime < 10) {
pDevice->uAutoReConnectTime++;
- #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
//network manager support need not do Roaming scan???
if(pDevice->bWPASuppWextEnabled ==TRUE)
pDevice->uAutoReConnectTime = 0;
- #endif
}
else {
//mike use old encryption status for wpa reauthen
diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h
index b68b2ec96ea..5007e98d1b0 100644
--- a/drivers/staging/vt6656/desc.h
+++ b/drivers/staging/vt6656/desc.h
@@ -298,7 +298,7 @@ typedef const SCTS_FB *PCSCTS_FB;
// Tx FIFO header
//
typedef struct tagSTxBufHead {
- DWORD adwTxKey[4];
+ u32 adwTxKey[4];
WORD wFIFOCtl;
WORD wTimeStamp;
WORD wFragCtl;
@@ -376,24 +376,24 @@ typedef const STxDataHead_a_FB *PCSTxDataHead_a_FB;
// MICHDR data header
//
typedef struct tagSMICHDRHead {
- DWORD adwHDR0[4];
- DWORD adwHDR1[4];
- DWORD adwHDR2[4];
+ u32 adwHDR0[4];
+ u32 adwHDR1[4];
+ u32 adwHDR2[4];
} __attribute__ ((__packed__))
SMICHDRHead, *PSMICHDRHead;
typedef const SMICHDRHead *PCSMICHDRHead;
typedef struct tagSBEACONCtl {
- DWORD BufReady : 1;
- DWORD TSF : 15;
- DWORD BufLen : 11;
- DWORD Reserved : 5;
+ u32 BufReady:1;
+ u32 TSF:15;
+ u32 BufLen:11;
+ u32 Reserved:5;
} __attribute__ ((__packed__))
SBEACONCtl;
typedef struct tagSSecretKey {
- DWORD dwLowDword;
+ u32 dwLowDword;
BYTE byHighByte;
} __attribute__ ((__packed__))
SSecretKey;
@@ -402,11 +402,11 @@ typedef struct tagSKeyEntry {
BYTE abyAddrHi[2];
WORD wKCTL;
BYTE abyAddrLo[4];
- DWORD dwKey0[4];
- DWORD dwKey1[4];
- DWORD dwKey2[4];
- DWORD dwKey3[4];
- DWORD dwKey4[4];
+ u32 dwKey0[4];
+ u32 dwKey1[4];
+ u32 dwKey2[4];
+ u32 dwKey3[4];
+ u32 dwKey4[4];
} __attribute__ ((__packed__))
SKeyEntry;
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 6370d103910..25bf03af773 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -30,47 +30,28 @@
#define __DEVICE_H__
#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/string.h>
-#include <linux/wait.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/etherdevice.h>
+#include <linux/suspend.h>
#include <linux/if_arp.h>
-#include <linux/sched.h>
-#include <linux/if.h>
-#include <linux/rtnetlink.h>//James
-#include <linux/proc_fs.h>
-#include <linux/inetdevice.h>
-#include <linux/reboot.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+#include <net/cfg80211.h>
+#include <linux/timer.h>
#include <linux/usb.h>
-#include <linux/signal.h>
-#include <linux/firmware.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+
+
#ifdef SIOCETHTOOL
#define DEVICE_ETHTOOL_IOCTL_SUPPORT
#include <linux/ethtool.h>
#else
#undef DEVICE_ETHTOOL_IOCTL_SUPPORT
#endif
-/* Include Wireless Extension definition and check version - Jean II */
-#include <linux/wireless.h>
-#include <net/iw_handler.h> // New driver API
-
-#ifndef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-#define WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-#endif
//please copy below macro to driver_event.c for API
#define RT_INSMOD_EVENT_FLAG 0x0101
@@ -418,7 +399,6 @@ typedef struct __device_info {
struct net_device* dev;
struct net_device_stats stats;
- const struct firmware *firmware;
OPTIONS sOpts;
@@ -734,7 +714,6 @@ typedef struct __device_info {
BYTE byKeyIndex;
BOOL bAES;
- BYTE byCntMeasure;
unsigned int uKeyLength;
BYTE abyKey[WLAN_WEP232_KEYLEN];
@@ -814,16 +793,13 @@ typedef struct __device_info {
//WPA supplicant daemon
struct net_device *wpadev;
BOOL bWPADEVUp;
- struct sk_buff *skb;
//--
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
BOOL bwextstep0;
BOOL bwextstep1;
BOOL bwextstep2;
BOOL bwextstep3;
BOOL bWPASuppWextEnabled;
-#endif
#ifdef HOSTAP
// user space daemon: hostapd, is used for HOSTAP
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c
index 28edf9e7efc..e94f6a1647a 100644
--- a/drivers/staging/vt6656/dpc.c
+++ b/drivers/staging/vt6656/dpc.c
@@ -332,7 +332,7 @@ RXbBulkInProcessData (
PBYTE pbyFrame;
BOOL bDeFragRx = FALSE;
unsigned int cbHeaderOffset;
- unsigned int FrameSize;
+ u32 FrameSize;
WORD wEtherType = 0;
signed int iSANodeIndex = -1;
signed int iDANodeIndex = -1;
@@ -351,7 +351,7 @@ RXbBulkInProcessData (
/* signed long ldBm = 0; */
BOOL bIsWEP = FALSE;
BOOL bExtIV = FALSE;
- DWORD dwWbkStatus;
+ u32 dwWbkStatus;
PRCB pRCBIndicate = pRCB;
PBYTE pbyDAddress;
PWORD pwPLCP_Length;
@@ -366,15 +366,15 @@ RXbBulkInProcessData (
skb = pRCB->skb;
- //[31:16]RcvByteCount ( not include 4-byte Status )
- dwWbkStatus = *( (PDWORD)(skb->data) );
- FrameSize = (unsigned int)(dwWbkStatus >> 16);
- FrameSize += 4;
+ /* [31:16]RcvByteCount ( not include 4-byte Status ) */
+ dwWbkStatus = *((u32 *)(skb->data));
+ FrameSize = dwWbkStatus >> 16;
+ FrameSize += 4;
- if (BytesToIndicate != FrameSize) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 1 \n");
- return FALSE;
- }
+ if (BytesToIndicate != FrameSize) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"------- WRONG Length 1\n");
+ return FALSE;
+ }
if ((BytesToIndicate > 2372) || (BytesToIndicate <= 40)) {
// Frame Size error drop this packet.
@@ -617,7 +617,7 @@ RXbBulkInProcessData (
//Discard beacon packet which channel is 0
if ( (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_BEACON) ||
(WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_PROBERESP) ) {
- return TRUE;
+ return FALSE;
}
}
pRxPacket->byRxChannel = (*pbyRxSts) >> 2;
@@ -818,7 +818,6 @@ RXbBulkInProcessData (
DWORD dwMICKey0 = 0, dwMICKey1 = 0;
DWORD dwLocalMIC_L = 0;
DWORD dwLocalMIC_R = 0;
- viawget_wpa_header *wpahdr;
if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
@@ -864,7 +863,6 @@ RXbBulkInProcessData (
pDevice->dev->name);
}
}
- #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
//send event to wpa_supplicant
//if(pDevice->bWPASuppWextEnabled == TRUE)
{
@@ -889,31 +887,6 @@ RXbBulkInProcessData (
wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
}
- #endif
-
-
- if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
- wpahdr = (viawget_wpa_header *)pDevice->skb->data;
- if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
- (pMgmt->eCurrState == WMAC_STATE_ASSOC) &&
- (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) {
- //s802_11_Status.Flags = NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR;
- wpahdr->type = VIAWGET_PTK_MIC_MSG;
- } else {
- //s802_11_Status.Flags = NDIS_802_11_AUTH_REQUEST_GROUP_ERROR;
- wpahdr->type = VIAWGET_GTK_MIC_MSG;
- }
- wpahdr->resp_ie_len = 0;
- wpahdr->req_ie_len = 0;
- skb_put(pDevice->skb, sizeof(viawget_wpa_header));
- pDevice->skb->dev = pDevice->wpadev;
- skb_reset_mac_header(pDevice->skb);
- pDevice->skb->pkt_type = PACKET_HOST;
- pDevice->skb->protocol = htons(ETH_P_802_2);
- memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
- netif_rx(pDevice->skb);
- pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
- }
return FALSE;
@@ -1217,7 +1190,7 @@ static BOOL s_bHandleRxEncryption (
if (byDecMode == KEY_CTL_WEP) {
// handle WEP
if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
- (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == TRUE)) {
+ (((PSKeyTable)(&pKey->pvKeyTable))->bSoftWEP == TRUE)) {
// Software WEP
// 1. 3253A
// 2. WEP 256
@@ -1238,7 +1211,7 @@ static BOOL s_bHandleRxEncryption (
PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
*pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4));
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16);
if (byDecMode == KEY_CTL_TKIP) {
*pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
} else {
@@ -1324,9 +1297,9 @@ static BOOL s_bHostWepRxEncryption (
if (byDecMode == KEY_CTL_WEP) {
// handle WEP
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byDecMode == KEY_CTL_WEP \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byDecMode == KEY_CTL_WEP\n");
if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
- (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == TRUE) ||
+ (((PSKeyTable)(&pKey->pvKeyTable))->bSoftWEP == TRUE) ||
(bOnFly == FALSE)) {
// Software WEP
// 1. 3253A
@@ -1349,7 +1322,7 @@ static BOOL s_bHostWepRxEncryption (
PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
*pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4));
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16);
if (byDecMode == KEY_CTL_TKIP) {
*pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
@@ -1534,6 +1507,11 @@ RXvFreeRCB(
ASSERT(!pRCB->Ref); // should be 0
ASSERT(pRCB->pDevice); // shouldn't be NULL
+ if (bReAllocSkb == FALSE) {
+ kfree_skb(pRCB->skb);
+ bReAllocSkb = TRUE;
+ }
+
if (bReAllocSkb == TRUE) {
pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
// todo error handling
diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c
index 8c8126a3540..8831ea03c00 100644
--- a/drivers/staging/vt6656/firmware.c
+++ b/drivers/staging/vt6656/firmware.c
@@ -61,28 +61,24 @@ FIRMWAREbDownload(
PSDevice pDevice
)
{
+ struct device *dev = &pDevice->usb->dev;
const struct firmware *fw;
int NdisStatus;
void *pBuffer = NULL;
BOOL result = FALSE;
u16 wLength;
- int ii;
+ int ii, rc;
+
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Download firmware\n");
spin_unlock_irq(&pDevice->lock);
- if (!pDevice->firmware) {
- struct device *dev = &pDevice->usb->dev;
- int rc;
-
- rc = request_firmware(&pDevice->firmware, FIRMWARE_NAME, dev);
- if (rc) {
- dev_err(dev, "firmware file %s request failed (%d)\n",
- FIRMWARE_NAME, rc);
+ rc = request_firmware(&fw, FIRMWARE_NAME, dev);
+ if (rc) {
+ dev_err(dev, "firmware file %s request failed (%d)\n",
+ FIRMWARE_NAME, rc);
goto out;
- }
}
- fw = pDevice->firmware;
pBuffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
if (!pBuffer)
@@ -103,10 +99,12 @@ FIRMWAREbDownload(
DBG_PRT(MSG_LEVEL_DEBUG,
KERN_INFO"Download firmware...%d %zu\n", ii, fw->size);
if (NdisStatus != STATUS_SUCCESS)
- goto out;
+ goto free_fw;
}
result = TRUE;
+free_fw:
+ release_firmware(fw);
out:
kfree(pBuffer);
diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c
index 0a73d4060ee..26a7d0e4b04 100644
--- a/drivers/staging/vt6656/hostap.c
+++ b/drivers/staging/vt6656/hostap.c
@@ -542,9 +542,9 @@ static int hostap_set_encryption(PSDevice pDevice,
if (param->u.crypt.seq) {
memcpy(&abySeq, param->u.crypt.seq, 8);
- for (ii = 0 ; ii < 8 ; ii++) {
- KeyRSC |= (abySeq[ii] << (ii * 8));
- }
+ for (ii = 0 ; ii < 8 ; ii++)
+ KeyRSC |= (unsigned long)abySeq[ii] << (ii * 8);
+
dwKeyIndex |= 1 << 29;
pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC;
}
diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h
index 3734e2c953d..5d8faf9f96e 100644
--- a/drivers/staging/vt6656/int.h
+++ b/drivers/staging/vt6656/int.h
@@ -48,8 +48,8 @@ typedef struct tagSINTData {
BYTE byTSR3;
BYTE byPkt3;
WORD wTime3;
- DWORD dwLoTSF;
- DWORD dwHiTSF;
+ u32 dwLoTSF;
+ u32 dwHiTSF;
BYTE byISR0;
BYTE byISR1;
BYTE byRTSSuccess;
diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c
deleted file mode 100644
index b6af5f69112..00000000000
--- a/drivers/staging/vt6656/ioctl.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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.
- *
- * File: ioctl.c
- *
- * Purpose: private ioctl functions
- *
- * Author: Lyndon Chen
- *
- * Date: Auguest 20, 2003
- *
- * Functions:
- *
- * Revision History:
- *
- */
-
-#include "ioctl.h"
-#include "iocmd.h"
-#include "mac.h"
-#include "card.h"
-#include "hostap.h"
-#include "wpactl.h"
-#include "control.h"
-#include "rndis.h"
-#include "rf.h"
-
-SWPAResult wpa_Result;
-static int msglevel = MSG_LEVEL_INFO;
-
-int private_ioctl(PSDevice pDevice, struct ifreq *rq)
-{
-
- PSCmdRequest pReq = (PSCmdRequest)rq;
- PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
- int result = 0;
- PWLAN_IE_SSID pItemSSID;
- SCmdBSSJoin sJoinCmd;
- SCmdZoneTypeSet sZoneTypeCmd;
- SCmdScan sScanCmd;
- SCmdStartAP sStartAPCmd;
- SCmdSetWEP sWEPCmd;
- SCmdValue sValue;
- SBSSIDList sList;
- SNodeList sNodeList;
- PSBSSIDList pList;
- PSNodeList pNodeList;
- unsigned int cbListCount;
- PKnownBSS pBSS;
- PKnownNodeDB pNode;
- unsigned int ii, jj;
- SCmdLinkStatus sLinkStatus;
- BYTE abySuppRates[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
- BYTE abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- DWORD dwKeyIndex = 0;
- BYTE abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
- signed long ldBm;
-
- pReq->wResult = 0;
-
- switch (pReq->wCmdCode) {
- case WLAN_CMD_BSS_SCAN:
- if (copy_from_user(&sScanCmd, pReq->data, sizeof(SCmdScan))) {
- result = -EFAULT;
- break;
- }
-
- pItemSSID = (PWLAN_IE_SSID)sScanCmd.ssid;
- if (pItemSSID->len > WLAN_SSID_MAXLEN + 1)
- return -EINVAL;
- if (pItemSSID->len != 0) {
- memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- memcpy(abyScanSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN);
- }
- spin_lock_irq(&pDevice->lock);
-
- if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0)
- BSSvClearBSSList(pDevice, FALSE);
- else
- BSSvClearBSSList(pDevice, pDevice->bLinkPass);
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_BSS_SCAN..begin\n");
-
- if (pItemSSID->len != 0)
- bScheduleCommand(pDevice, WLAN_CMD_BSSID_SCAN,
- abyScanSSID);
- else
- bScheduleCommand(pDevice, WLAN_CMD_BSSID_SCAN, NULL);
-
- spin_unlock_irq(&pDevice->lock);
- break;
-
- case WLAN_CMD_ZONETYPE_SET:
- result = -EOPNOTSUPP;
- break;
-
- if (copy_from_user(&sZoneTypeCmd, pReq->data, sizeof(SCmdZoneTypeSet))) {
- result = -EFAULT;
- break;
- }
-
- if (sZoneTypeCmd.bWrite == TRUE) {
- /* write zonetype */
- if (sZoneTypeCmd.ZoneType == ZoneType_USA) {
- /* set to USA */
- printk("set_ZoneType:USA\n");
- } else if (sZoneTypeCmd.ZoneType == ZoneType_Japan) {
- /* set to Japan */
- printk("set_ZoneType:Japan\n");
- } else if (sZoneTypeCmd.ZoneType == ZoneType_Europe) {
- /* set to Europe */
- printk("set_ZoneType:Europe\n");
- }
- } else {
- /* read zonetype */
- BYTE zonetype = 0;
-
- if (zonetype == 0x00) { /* USA */
- sZoneTypeCmd.ZoneType = ZoneType_USA;
- } else if (zonetype == 0x01) { /* Japan */
- sZoneTypeCmd.ZoneType = ZoneType_Japan;
- } else if (zonetype == 0x02) { /* Europe */
- sZoneTypeCmd.ZoneType = ZoneType_Europe;
- } else { /* Unknown ZoneType */
- printk("Error:ZoneType[%x] Unknown ???\n", zonetype);
- result = -EFAULT;
- break;
- }
-
- if (copy_to_user(pReq->data, &sZoneTypeCmd,
- sizeof(SCmdZoneTypeSet))) {
- result = -EFAULT;
- break;
- }
- }
- break;
-
- case WLAN_CMD_BSS_JOIN:
- if (copy_from_user(&sJoinCmd, pReq->data, sizeof(SCmdBSSJoin))) {
- result = -EFAULT;
- break;
- }
-
- pItemSSID = (PWLAN_IE_SSID)sJoinCmd.ssid;
- if (pItemSSID->len > WLAN_SSID_MAXLEN + 1)
- return -EINVAL;
- memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN);
- if (sJoinCmd.wBSSType == ADHOC) {
- pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to adhoc mode\n");
- } else {
- pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to STA mode\n");
- }
- if (sJoinCmd.bPSEnable == TRUE) {
- pDevice->ePSMode = WMAC_POWER_FAST;
- pMgmt->wListenInterval = 2;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving On\n");
- } else {
- pDevice->ePSMode = WMAC_POWER_CAM;
- pMgmt->wListenInterval = 1;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving Off\n");
- }
-
- if (sJoinCmd.bShareKeyAuth == TRUE) {
- pMgmt->bShareKeyAlgorithm = TRUE;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key\n");
- } else {
- pMgmt->bShareKeyAlgorithm = FALSE;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System\n");
- }
-
- pDevice->uChannel = sJoinCmd.uChannel;
- netif_stop_queue(pDevice->dev);
- spin_lock_irq(&pDevice->lock);
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- bScheduleCommand(pDevice, WLAN_CMD_BSSID_SCAN,
- pMgmt->abyDesireSSID);
- bScheduleCommand(pDevice, WLAN_CMD_SSID, NULL);
- spin_unlock_irq(&pDevice->lock);
- break;
-
- case WLAN_CMD_SET_WEP:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WEP Key.\n");
- memset(&sWEPCmd, 0, sizeof(SCmdSetWEP));
- if (copy_from_user(&sWEPCmd, pReq->data, sizeof(SCmdSetWEP))) {
- result = -EFAULT;
- break;
- }
- if (sWEPCmd.bEnableWep != TRUE) {
- int uu;
-
- pDevice->bEncryptionEnable = FALSE;
- pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
- spin_lock_irq(&pDevice->lock);
- for (uu = 0; uu < MAX_KEY_TABLE; uu++)
- MACvDisableKeyEntry(pDevice, uu);
- spin_unlock_irq(&pDevice->lock);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WEP function disable.\n");
- break;
- }
-
- for (ii = 0; ii < WLAN_WEP_NKEYS; ii++) {
- if (sWEPCmd.bWepKeyAvailable[ii]) {
- if (ii == sWEPCmd.byKeyIndex)
- dwKeyIndex = ii | (1 << 31);
- else
- dwKeyIndex = ii;
- spin_lock_irq(&pDevice->lock);
- KeybSetDefaultKey(pDevice, &(pDevice->sKey),
- dwKeyIndex,
- sWEPCmd.auWepKeyLength[ii],
- NULL,
- (PBYTE)&sWEPCmd.abyWepKey[ii][0],
- KEY_CTL_WEP);
- spin_unlock_irq(&pDevice->lock);
- }
- }
- pDevice->byKeyIndex = sWEPCmd.byKeyIndex;
- pDevice->bTransmitKey = TRUE;
- pDevice->bEncryptionEnable = TRUE;
- pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
- break;
-
- case WLAN_CMD_GET_LINK:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_GET_LINK status.\n");
-
- memset(sLinkStatus.abySSID, 0, WLAN_SSID_MAXLEN + 1);
-
- if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)
- sLinkStatus.wBSSType = ADHOC;
- else
- sLinkStatus.wBSSType = INFRA;
-
- if (pMgmt->eCurrState == WMAC_STATE_JOINTED)
- sLinkStatus.byState = ADHOC_JOINTED;
- else
- sLinkStatus.byState = ADHOC_STARTED;
-
- sLinkStatus.uChannel = pMgmt->uCurrChannel;
- if (pDevice->bLinkPass == TRUE) {
- sLinkStatus.bLink = TRUE;
- pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
- memcpy(sLinkStatus.abySSID, pItemSSID->abySSID, pItemSSID->len);
- memcpy(sLinkStatus.abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
- sLinkStatus.uLinkRate = pMgmt->sNodeDBTable[0].wTxDataRate;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Link Success!\n");
- } else {
- sLinkStatus.bLink = FALSE;
- sLinkStatus.uLinkRate = 0;
- }
- if (copy_to_user(pReq->data, &sLinkStatus,
- sizeof(SCmdLinkStatus))) {
- result = -EFAULT;
- break;
- }
- break;
-
- case WLAN_CMD_GET_LISTLEN:
- cbListCount = 0;
- pBSS = &(pMgmt->sBSSList[0]);
- for (ii = 0; ii < MAX_BSS_NUM; ii++) {
- pBSS = &(pMgmt->sBSSList[ii]);
- if (!pBSS->bActive)
- continue;
- cbListCount++;
- }
- sList.uItem = cbListCount;
- if (copy_to_user(pReq->data, &sList, sizeof(SBSSIDList))) {
- result = -EFAULT;
- break;
- }
- pReq->wResult = 0;
- break;
-
- case WLAN_CMD_GET_LIST:
- if (copy_from_user(&sList, pReq->data, sizeof(SBSSIDList))) {
- result = -EFAULT;
- break;
- }
- if (sList.uItem > (ULONG_MAX - sizeof(SBSSIDList)) / sizeof(SBSSIDItem)) {
- result = -EINVAL;
- break;
- }
- pList = kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), GFP_ATOMIC);
- if (pList == NULL) {
- result = -ENOMEM;
- break;
- }
- pList->uItem = sList.uItem;
- pBSS = &(pMgmt->sBSSList[0]);
- for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) {
- pBSS = &(pMgmt->sBSSList[jj]);
- if (pBSS->bActive) {
- pList->sBSSIDList[ii].uChannel = pBSS->uChannel;
- pList->sBSSIDList[ii].wBeaconInterval = pBSS->wBeaconInterval;
- pList->sBSSIDList[ii].wCapInfo = pBSS->wCapInfo;
- RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
- pList->sBSSIDList[ii].uRSSI = (unsigned int)ldBm;
- /* pList->sBSSIDList[ii].uRSSI = pBSS->uRSSI; */
- memcpy(pList->sBSSIDList[ii].abyBSSID, pBSS->abyBSSID, WLAN_BSSID_LEN);
- pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
- memset(pList->sBSSIDList[ii].abySSID, 0, WLAN_SSID_MAXLEN + 1);
- memcpy(pList->sBSSIDList[ii].abySSID, pItemSSID->abySSID, pItemSSID->len);
- if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) {
- pList->sBSSIDList[ii].byNetType = INFRA;
- } else {
- pList->sBSSIDList[ii].byNetType = ADHOC;
- }
- if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) {
- pList->sBSSIDList[ii].bWEPOn = TRUE;
- } else {
- pList->sBSSIDList[ii].bWEPOn = FALSE;
- }
- ii++;
- if (ii >= pList->uItem)
- break;
- }
- }
-
- if (copy_to_user(pReq->data, pList, sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)))) {
- result = -EFAULT;
- break;
- }
- kfree(pList);
- pReq->wResult = 0;
- break;
-
- case WLAN_CMD_GET_MIB:
- if (copy_to_user(pReq->data, &(pDevice->s802_11Counter), sizeof(SDot11MIBCount))) {
- result = -EFAULT;
- break;
- }
- break;
-
- case WLAN_CMD_GET_STAT:
- if (copy_to_user(pReq->data, &(pDevice->scStatistic), sizeof(SStatCounter))) {
- result = -EFAULT;
- break;
- }
- break;
-
- case WLAN_CMD_STOP_MAC:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_STOP_MAC\n");
- /* Todo xxxxxx */
- netif_stop_queue(pDevice->dev);
- spin_lock_irq(&pDevice->lock);
- if (pDevice->bRadioOff == FALSE) {
- CARDbRadioPowerOff(pDevice);
- }
- pDevice->bLinkPass = FALSE;
- ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_SLOW);
- memset(pMgmt->abyCurrBSSID, 0, 6);
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- /* del_timer(&pDevice->sTimerCommand); */
- /* del_timer(&pMgmt->sTimerSecondCallback); */
- pDevice->bCmdRunning = FALSE;
- spin_unlock_irq(&pDevice->lock);
- break;
-
- case WLAN_CMD_START_MAC:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_START_MAC\n");
- /* Todo xxxxxxx */
- if (pDevice->bRadioOff == TRUE)
- CARDbRadioPowerOn(pDevice);
- break;
-
- case WLAN_CMD_SET_HOSTAPD:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD\n");
-
- if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
- result = -EFAULT;
- break;
- }
- if (sValue.dwValue == 1) {
- if (vt6656_hostap_set_hostapd(pDevice, 1, 1) == 0) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HOSTAP\n");
- } else {
- result = -EFAULT;
- break;
- }
- } else {
- vt6656_hostap_set_hostapd(pDevice, 0, 1);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HOSTAP\n");
- }
- break;
-
- case WLAN_CMD_SET_HOSTAPD_STA:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD_STA\n");
- break;
-
- case WLAN_CMD_SET_802_1X:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_802_1X\n");
- if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
- result = -EFAULT;
- break;
- }
-
- if (sValue.dwValue == 1) {
- pDevice->bEnable8021x = TRUE;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable 802.1x\n");
- } else {
- pDevice->bEnable8021x = FALSE;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable 802.1x\n");
- }
- break;
-
- case WLAN_CMD_SET_HOST_WEP:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOST_WEP\n");
- if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
- result = -EFAULT;
- break;
- }
-
- if (sValue.dwValue == 1) {
- pDevice->bEnableHostWEP = TRUE;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HostWEP\n");
- } else {
- pDevice->bEnableHostWEP = FALSE;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HostWEP\n");
- }
- break;
-
- case WLAN_CMD_SET_WPA:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WPA\n");
-
- if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
- result = -EFAULT;
- break;
- }
- if (sValue.dwValue == 1) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "up wpadev\n");
- memcpy(pDevice->wpadev->dev_addr, pDevice->dev->dev_addr,
- ETH_ALEN);
- pDevice->bWPADEVUp = TRUE;
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "close wpadev\n");
- pDevice->bWPADEVUp = FALSE;
- }
- break;
-
- case WLAN_CMD_AP_START:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_AP_START\n");
- if (pDevice->bRadioOff == TRUE) {
- CARDbRadioPowerOn(pDevice);
- add_timer(&pMgmt->sTimerSecondCallback);
- }
- if (copy_from_user(&sStartAPCmd, pReq->data, sizeof(SCmdStartAP))) {
- result = -EFAULT;
- break;
- }
-
- if (sStartAPCmd.wBSSType == AP) {
- pMgmt->eConfigMode = WMAC_CONFIG_AP;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to AP mode\n");
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct BSS type not set to AP mode\n");
- result = -EFAULT;
- break;
- }
-
- if (sStartAPCmd.wBBPType == PHY80211g) {
- pMgmt->byAPBBType = PHY_TYPE_11G;
- } else if (sStartAPCmd.wBBPType == PHY80211a) {
- pMgmt->byAPBBType = PHY_TYPE_11A;
- } else {
- pMgmt->byAPBBType = PHY_TYPE_11B;
- }
-
- pItemSSID = (PWLAN_IE_SSID)sStartAPCmd.ssid;
- if (pItemSSID->len > WLAN_SSID_MAXLEN + 1)
- return -EINVAL;
- memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN);
-
- if ((sStartAPCmd.uChannel > 0) && (sStartAPCmd.uChannel <= 14))
- pDevice->uChannel = sStartAPCmd.uChannel;
-
- if ((sStartAPCmd.uBeaconInt >= 20) && (sStartAPCmd.uBeaconInt <= 1000))
- pMgmt->wIBSSBeaconPeriod = sStartAPCmd.uBeaconInt;
- else
- pMgmt->wIBSSBeaconPeriod = 100;
-
- if (sStartAPCmd.bShareKeyAuth == TRUE) {
- pMgmt->bShareKeyAlgorithm = TRUE;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key\n");
- } else {
- pMgmt->bShareKeyAlgorithm = FALSE;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System\n");
- }
- memcpy(pMgmt->abyIBSSSuppRates, abySuppRates, 6);
-
- if (sStartAPCmd.byBasicRate & BIT3) {
- pMgmt->abyIBSSSuppRates[2] |= BIT7;
- pMgmt->abyIBSSSuppRates[3] |= BIT7;
- pMgmt->abyIBSSSuppRates[4] |= BIT7;
- pMgmt->abyIBSSSuppRates[5] |= BIT7;
- } else if (sStartAPCmd.byBasicRate & BIT2) {
- pMgmt->abyIBSSSuppRates[2] |= BIT7;
- pMgmt->abyIBSSSuppRates[3] |= BIT7;
- pMgmt->abyIBSSSuppRates[4] |= BIT7;
- } else if (sStartAPCmd.byBasicRate & BIT1) {
- pMgmt->abyIBSSSuppRates[2] |= BIT7;
- pMgmt->abyIBSSSuppRates[3] |= BIT7;
- } else if (sStartAPCmd.byBasicRate & BIT1) {
- pMgmt->abyIBSSSuppRates[2] |= BIT7;
- } else {
- /* default 1,2M */
- pMgmt->abyIBSSSuppRates[2] |= BIT7;
- pMgmt->abyIBSSSuppRates[3] |= BIT7;
- }
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Support Rate= %*ph\n",
- 4, pMgmt->abyIBSSSuppRates + 2);
-
- netif_stop_queue(pDevice->dev);
- spin_lock_irq(&pDevice->lock);
- bScheduleCommand(pDevice, WLAN_CMD_RUN_AP, NULL);
- spin_unlock_irq(&pDevice->lock);
- break;
-
- case WLAN_CMD_GET_NODE_CNT:
- cbListCount = 0;
- pNode = &(pMgmt->sNodeDBTable[0]);
- for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
- pNode = &(pMgmt->sNodeDBTable[ii]);
- if (!pNode->bActive)
- continue;
- cbListCount++;
- }
-
- sNodeList.uItem = cbListCount;
- if (copy_to_user(pReq->data, &sNodeList, sizeof(SNodeList))) {
- result = -EFAULT;
- break;
- }
- pReq->wResult = 0;
- break;
-
- case WLAN_CMD_GET_NODE_LIST:
- if (copy_from_user(&sNodeList, pReq->data, sizeof(SNodeList))) {
- result = -EFAULT;
- break;
- }
- if (sNodeList.uItem > (ULONG_MAX - sizeof(SNodeList)) / sizeof(SNodeItem)) {
- result = -ENOMEM;
- break;
- }
- pNodeList = kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), GFP_ATOMIC);
- if (pNodeList == NULL) {
- result = -ENOMEM;
- break;
- }
- pNodeList->uItem = sNodeList.uItem;
- pNode = &(pMgmt->sNodeDBTable[0]);
- for (ii = 0, jj = 0; ii < (MAX_NODE_NUM + 1); ii++) {
- pNode = &(pMgmt->sNodeDBTable[ii]);
- if (pNode->bActive) {
- pNodeList->sNodeList[jj].wAID = pNode->wAID;
- memcpy(pNodeList->sNodeList[jj].abyMACAddr, pNode->abyMACAddr, WLAN_ADDR_LEN);
- pNodeList->sNodeList[jj].wTxDataRate = pNode->wTxDataRate;
- pNodeList->sNodeList[jj].wInActiveCount = (WORD)pNode->uInActiveCount;
- pNodeList->sNodeList[jj].wEnQueueCnt = (WORD)pNode->wEnQueueCnt;
- pNodeList->sNodeList[jj].wFlags = (WORD)pNode->dwFlags;
- pNodeList->sNodeList[jj].bPWBitOn = pNode->bPSEnable;
- pNodeList->sNodeList[jj].byKeyIndex = pNode->byKeyIndex;
- pNodeList->sNodeList[jj].wWepKeyLength = pNode->uWepKeyLength;
- memcpy(&(pNodeList->sNodeList[jj].abyWepKey[0]), &(pNode->abyWepKey[0]), WEP_KEYMAXLEN);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key= %2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
- pNodeList->sNodeList[jj].abyWepKey[0],
- pNodeList->sNodeList[jj].abyWepKey[1],
- pNodeList->sNodeList[jj].abyWepKey[2],
- pNodeList->sNodeList[jj].abyWepKey[3],
- pNodeList->sNodeList[jj].abyWepKey[4]);
- pNodeList->sNodeList[jj].bIsInFallback = pNode->bIsInFallback;
- pNodeList->sNodeList[jj].uTxFailures = pNode->uTxFailures;
- pNodeList->sNodeList[jj].uTxAttempts = pNode->uTxAttempts;
- pNodeList->sNodeList[jj].wFailureRatio = (WORD)pNode->uFailureRatio;
- jj++;
- if (jj >= pNodeList->uItem)
- break;
- }
- }
- if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) {
- kfree(pNodeList);
- result = -EFAULT;
- break;
- }
- kfree(pNodeList);
- pReq->wResult = 0;
- break;
-
- case 0xFF:
- memset(wpa_Result.ifname, 0, sizeof(wpa_Result.ifname));
- wpa_Result.proto = 0;
- wpa_Result.key_mgmt = 0;
- wpa_Result.eap_type = 0;
- wpa_Result.authenticated = FALSE;
- pDevice->fWPA_Authened = FALSE;
- if (copy_from_user(&wpa_Result, pReq->data, sizeof(wpa_Result))) {
- result = -EFAULT;
- break;
- }
- /* for some AP's maybe a good authentication */
- if (wpa_Result.key_mgmt == 0x20)
- pMgmt->Cisco_cckm = 1;
- else
- pMgmt->Cisco_cckm = 0;
-
- if (wpa_Result.authenticated == TRUE) {
- {
- union iwreq_data wrqu;
-
- pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.flags = RT_WPACONNECTED_EVENT_FLAG;
- wrqu.data.length = pItemSSID->len;
- wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pItemSSID->abySSID);
- }
-
- pDevice->fWPA_Authened = TRUE; /* is successful peer to wpa_Result.authenticated? */
- }
-
- pReq->wResult = 0;
- break;
-
- default:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Private command not supported..\n");
- }
-
- return result;
-}
diff --git a/drivers/staging/vt6656/ioctl.h b/drivers/staging/vt6656/ioctl.h
deleted file mode 100644
index caa4ac963d9..00000000000
--- a/drivers/staging/vt6656/ioctl.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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.
- *
- * File: hostap.h
- *
- * Purpose:
- *
- * Author: Lyndon Chen
- *
- * Date: May 21, 2003
- *
- */
-
-#ifndef __IOCTL_H__
-#define __IOCTL_H__
-
-#include "device.h"
-
-/*--------------------- Export Definitions -------------------------*/
-
-
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
-
-int private_ioctl(PSDevice pDevice, struct ifreq *rq);
-
-/*
-void vConfigWEPKey (
- PSDevice pDevice,
- DWORD dwKeyIndex,
- PBYTE pbyKey,
- unsigned long uKeyLength
- );
-*/
-
-#endif /* __IOCTL_H__ */
diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c
index 8f198749ca5..52fce690250 100644
--- a/drivers/staging/vt6656/iwctl.c
+++ b/drivers/staging/vt6656/iwctl.c
@@ -31,26 +31,17 @@
*/
#include "device.h"
-#include "ioctl.h"
-#include "iocmd.h"
+#include "iwctl.h"
#include "mac.h"
#include "card.h"
#include "hostap.h"
#include "power.h"
#include "rf.h"
-
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
#include "iowpa.h"
#include "wpactl.h"
-#endif
-
-#include <net/iw_handler.h>
+#include "control.h"
+#include "rndis.h"
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-#define SUPPORTED_WIRELESS_EXT 18
-#else
-#define SUPPORTED_WIRELESS_EXT 17
-#endif
static const long frequency_list[] = {
2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
@@ -88,9 +79,9 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
* Wireless Handler: get protocol name
*/
int iwctl_giwname(struct net_device *dev, struct iw_request_info *info,
- char *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
- strcpy(wrq, "802.11-a/b/g");
+ strcpy(wrqu->name, "802.11-a/b/g");
return 0;
}
@@ -98,9 +89,10 @@ int iwctl_giwname(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: set scan
*/
int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct iw_point *wrq = &wrqu->data;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
struct iw_scan_req *req = (struct iw_scan_req *)extra;
BYTE abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
@@ -109,7 +101,10 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info,
if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
return -EINVAL;
- PRINT_K(" SIOCSIWSCAN \n");
+ PRINT_K(" SIOCSIWSCAN\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
if (pMgmt->eScanState == WMAC_IS_SCANNING) {
// In scanning..
@@ -137,9 +132,9 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info,
pItemSSID = (PWLAN_IE_SSID)abyScanSSID;
pItemSSID->byElementID = WLAN_EID_SSID;
memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len);
- if (pItemSSID->abySSID[req->essid_len - 1] == '\0') {
+ if (pItemSSID->abySSID[req->essid_len] == '\0') {
if (req->essid_len > 0)
- pItemSSID->len = req->essid_len - 1;
+ pItemSSID->len = req->essid_len;
} else {
pItemSSID->len = req->essid_len;
}
@@ -168,8 +163,9 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler : get scan results
*/
int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
+ struct iw_point *wrq = &wrqu->data;
int ii;
int jj;
int kk;
@@ -184,10 +180,12 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info,
char *current_val = NULL;
struct iw_event iwe;
long ldBm;
- char buf[MAX_WPA_IE_LEN * 2 + 30];
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN\n");
+ if (pMgmt == NULL)
+ return -EFAULT;
+
if (pMgmt->eScanState == WMAC_IS_SCANNING) {
// In scanning..
return -EAGAIN;
@@ -286,12 +284,6 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info,
if ((current_val - current_ev) > IW_EV_LCP_LEN)
current_ev = current_val;
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVCUSTOM;
- sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval);
- iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, buf);
-
if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
@@ -315,12 +307,13 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: set frequence or channel
*/
int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info,
- struct iw_freq *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct iw_freq *wrq = &wrqu->freq;
int rc = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ\n");
// If setting by frequency, convert to a channel
if ((wrq->e == 1) && (wrq->m >= (int)2.412e8) &&
@@ -353,12 +346,17 @@ int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: get frequence or channel
*/
int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info,
- struct iw_freq *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct iw_freq *wrq = &wrqu->freq;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
#ifdef WEXT_USECHANNELS
wrq->m = (int)pMgmt->uCurrChannel;
@@ -379,16 +377,21 @@ int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: set operation mode
*/
int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info,
- __u32 *wmode, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ __u32 *wmode = &wrqu->mode;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
int rc = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Can't set operation mode, hostapd is running \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Can't set operation mode, hostapd is running\n");
return rc;
}
@@ -432,19 +435,72 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info,
rc = -EINVAL;
}
+ if (pDevice->bCommit) {
+ if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+ netif_stop_queue(pDevice->dev);
+ spin_lock_irq(&pDevice->lock);
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_RUN_AP, NULL);
+ spin_unlock_irq(&pDevice->lock);
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Commit the settings\n");
+
+ spin_lock_irq(&pDevice->lock);
+
+ if (pDevice->bLinkPass &&
+ memcmp(pMgmt->abyCurrSSID,
+ pMgmt->abyDesireSSID,
+ WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_DISASSOCIATE, NULL);
+ } else {
+ pDevice->bLinkPass = FALSE;
+ pMgmt->eCurrState = WMAC_STATE_IDLE;
+ memset(pMgmt->abyCurrBSSID, 0, 6);
+ }
+
+ ControlvMaskByte(pDevice,
+ MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY,
+ LEDSTS_STS, LEDSTS_SLOW);
+
+ netif_stop_queue(pDevice->dev);
+
+ pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+
+ if (!pDevice->bWPASuppWextEnabled)
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_BSSID_SCAN,
+ pMgmt->abyDesireSSID);
+
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_SSID,
+ NULL);
+
+ spin_unlock_irq(&pDevice->lock);
+ }
+ pDevice->bCommit = FALSE;
+ }
+
+
return rc;
}
/*
* Wireless Handler: get operation mode
*/
-void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info,
- __u32 *wmode, char *extra)
+int iwctl_giwmode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ __u32 *wmode = &wrqu->mode;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
// If not managed, assume it's ad-hoc
switch (pMgmt->eConfigMode) {
case WMAC_CONFIG_ESS_STA:
@@ -462,14 +518,17 @@ void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info,
default:
*wmode = IW_MODE_ADHOC;
}
+
+ return 0;
}
/*
* Wireless Handler: get capability range
*/
-void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra)
+int iwctl_giwrange(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
+ struct iw_point *wrq = &wrqu->data;
struct iw_range *range = (struct iw_range *)extra;
int i;
int k;
@@ -546,7 +605,7 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info,
range->txpower[0] = 100;
range->num_txpower = 1;
range->txpower_capa = IW_TXPOW_MWATT;
- range->we_version_source = SUPPORTED_WIRELESS_EXT;
+ range->we_version_source = WIRELESS_EXT;
range->we_version_compiled = WIRELESS_EXT;
range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
range->retry_flags = IW_RETRY_LIMIT;
@@ -562,20 +621,26 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info,
range->avg_qual.level = 176; // -80 dBm
range->avg_qual.noise = 0;
}
+
+ return 0;
}
/*
* Wireless Handler : set ap mac address
*/
int iwctl_siwap(struct net_device *dev, struct iw_request_info *info,
- struct sockaddr *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct sockaddr *wrq = &wrqu->ap_addr;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
int rc = 0;
BYTE ZeroBSSID[WLAN_BSSID_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- PRINT_K(" SIOCSIWAP \n");
+ PRINT_K(" SIOCSIWAP\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
if (wrq->sa_family != ARPHRD_ETHER) {
rc = -EINVAL;
@@ -616,12 +681,16 @@ int iwctl_siwap(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: get ap mac address
*/
int iwctl_giwap(struct net_device *dev, struct iw_request_info *info,
- struct sockaddr *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct sockaddr *wrq = &wrqu->ap_addr;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
@@ -639,59 +708,77 @@ int iwctl_giwap(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: get ap list
*/
int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
+ struct iw_point *wrq = &wrqu->data;
+ struct sockaddr *sock;
+ struct iw_quality *qual;
+ PSDevice pDevice = netdev_priv(dev);
+ PSMgmtObject pMgmt = &pDevice->sMgmtObj;
+ PKnownBSS pBSS = &pMgmt->sBSSList[0];
int ii;
int jj;
- int rc = 0;
- struct sockaddr sock[IW_MAX_AP];
- struct iw_quality qual[IW_MAX_AP];
- PSDevice pDevice = netdev_priv(dev);
- PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n");
- // Only super-user can see AP list
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST\n");
+ /* Only super-user can see AP list */
- if (!capable(CAP_NET_ADMIN)) {
- rc = -EPERM;
- return rc;
- }
+ if (pBSS == NULL)
+ return -ENODEV;
- if (wrq->pointer) {
- PKnownBSS pBSS = &(pMgmt->sBSSList[0]);
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
- for (ii = 0, jj= 0; ii < MAX_BSS_NUM; ii++) {
- pBSS = &(pMgmt->sBSSList[ii]);
- if (!pBSS->bActive)
- continue;
- if (jj >= IW_MAX_AP)
- break;
- memcpy(sock[jj].sa_data, pBSS->abyBSSID, 6);
- sock[jj].sa_family = ARPHRD_ETHER;
- qual[jj].level = pBSS->uRSSI;
- qual[jj].qual = qual[jj].noise = 0;
- qual[jj].updated = 2;
- jj++;
- }
+ if (!wrq->pointer)
+ return -EINVAL;
- wrq->flags = 1; // Should be defined
- wrq->length = jj;
- memcpy(extra, sock, sizeof(struct sockaddr) * jj);
- memcpy(extra + sizeof(struct sockaddr) * jj, qual, sizeof(struct iw_quality) * jj);
+ sock = kzalloc(sizeof(struct sockaddr) * IW_MAX_AP, GFP_KERNEL);
+ if (sock == NULL)
+ return -ENOMEM;
+ qual = kzalloc(sizeof(struct iw_quality) * IW_MAX_AP, GFP_KERNEL);
+ if (qual == NULL) {
+ kfree(sock);
+ return -ENOMEM;
}
- return rc;
+
+ for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) {
+ if (!pBSS[ii].bActive)
+ continue;
+ if (jj >= IW_MAX_AP)
+ break;
+ memcpy(sock[jj].sa_data, pBSS[ii].abyBSSID, 6);
+ sock[jj].sa_family = ARPHRD_ETHER;
+ qual[jj].level = pBSS[ii].uRSSI;
+ qual[jj].qual = qual[jj].noise = 0;
+ qual[jj].updated = 2;
+ jj++;
+ }
+
+ wrq->flags = 1; /* Should be defined */
+ wrq->length = jj;
+ memcpy(extra, sock, sizeof(struct sockaddr) * jj);
+ memcpy(extra + sizeof(struct sockaddr) * jj, qual,
+ sizeof(struct iw_quality) * jj);
+
+ kfree(sock);
+ kfree(qual);
+
+ return 0;
}
/*
* Wireless Handler: set essid
*/
int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct iw_point *wrq = &wrqu->essid;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
PWLAN_IE_SSID pItemSSID;
+ if (pMgmt == NULL)
+ return -EFAULT;
+
if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
return -EINVAL;
@@ -704,10 +791,8 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
memset(pMgmt->abyDesireBSSID, 0xFF,6);
PRINT_K("set essid to 'any' \n");
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
// Unknown desired AP, so here need not associate??
return 0;
-#endif
} else {
// Set the SSID
memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
@@ -715,9 +800,9 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
pItemSSID->byElementID = WLAN_EID_SSID;
memcpy(pItemSSID->abySSID, extra, wrq->length);
- if (pItemSSID->abySSID[wrq->length - 1] == '\0') {
+ if (pItemSSID->abySSID[wrq->length] == '\0') {
if (wrq->length>0)
- pItemSSID->len = wrq->length - 1;
+ pItemSSID->len = wrq->length;
} else {
pItemSSID->len = wrq->length;
}
@@ -729,7 +814,6 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
return 0;
}
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
// Wext wil order another command of siwap to link
// with desired AP, so here need not associate??
if (pDevice->bWPASuppWextEnabled == TRUE) {
@@ -778,7 +862,6 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
}
return 0;
}
-#endif
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
}
@@ -792,14 +875,18 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
/*
* Wireless Handler: get essid
*/
-void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra)
+int iwctl_giwessid(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct iw_point *wrq = &wrqu->essid;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
PWLAN_IE_SSID pItemSSID;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
// Note: if wrq->u.data.flags != 0, we should get the relevant
// SSID from the SSID list...
@@ -811,15 +898,18 @@ void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info,
wrq->length = pItemSSID->len;
wrq->flags = 1; // active
+
+ return 0;
}
/*
* Wireless Handler: set data rate
*/
int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->bitrate;
int rc = 0;
u8 brate = 0;
int i;
@@ -893,13 +983,18 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
/*
* Wireless Handler: get data rate
*/
-void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra)
+int iwctl_giwrate(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->bitrate;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
{
BYTE abySupportedRates[13] = {
0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30,
@@ -932,14 +1027,18 @@ void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info,
if (pDevice->bFixRate == TRUE)
wrq->fixed = TRUE;
}
+
+ return 0;
}
/*
* Wireless Handler: set rts threshold
*/
-int iwctl_siwrts(struct net_device *dev, struct iw_param *wrq)
+int iwctl_siwrts(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->rts;
if ((wrq->value < 0 || wrq->value > 2312) && !wrq->disabled)
return -EINVAL;
@@ -956,11 +1055,12 @@ int iwctl_siwrts(struct net_device *dev, struct iw_param *wrq)
* Wireless Handler: get rts
*/
int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->rts;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS\n");
wrq->value = pDevice->wRTSThreshold;
wrq->disabled = (wrq->value >= 2312);
wrq->fixed = 1;
@@ -971,13 +1071,14 @@ int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: set fragment threshold
*/
int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->frag;
int rc = 0;
int fthr = wrq->value;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG\n");
if (wrq->disabled)
fthr = 2312;
@@ -994,11 +1095,12 @@ int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: get fragment threshold
*/
int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->frag;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG\n");
wrq->value = pDevice->wFragmentationThreshold;
wrq->disabled = (wrq->value >= 2312);
wrq->fixed = 1;
@@ -1009,12 +1111,13 @@ int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: set retry threshold
*/
int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->retry;
int rc = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY\n");
if (wrq->disabled) {
rc = -EINVAL;
@@ -1041,10 +1144,11 @@ int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: get retry threshold
*/
int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n");
+ struct iw_param *wrq = &wrqu->retry;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY\n");
wrq->disabled = 0; // Can't be disabled
// Note: by default, display the min retry number
@@ -1067,17 +1171,21 @@ int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: set encode mode
*/
int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
- DWORD dwKeyIndex = (DWORD)(wrq->flags & IW_ENCODE_INDEX);
+ struct iw_point *wrq = &wrqu->encoding;
+ u32 dwKeyIndex = (u32)(wrq->flags & IW_ENCODE_INDEX);
int ii;
int uu;
int rc = 0;
int index = (wrq->flags & IW_ENCODE_INDEX);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
// Check the size of the key
if (wrq->length > WLAN_WEP232_KEYLEN) {
@@ -1155,17 +1263,17 @@ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info,
pMgmt->bShareKeyAlgorithm = FALSE;
}
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
memset(pMgmt->abyDesireBSSID, 0xFF, 6);
-#endif
+
return rc;
}
int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
+ struct iw_point *wrq = &wrqu->encoding;
char abyKey[WLAN_WEP232_KEYLEN];
unsigned index = (unsigned)(wrq->flags & IW_ENCODE_INDEX);
@@ -1173,6 +1281,9 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info,
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
+ if (pMgmt == NULL)
+ return -EFAULT;
+
if (index > WLAN_WEP_NKEYS)
return -EINVAL;
if (index < 1) { // get default key
@@ -1220,13 +1331,17 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: set power mode
*/
int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
+ struct iw_param *wrq = &wrqu->power;
int rc = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
rc = -EINVAL;
@@ -1268,24 +1383,31 @@ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: get power mode
*/
int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
+ struct iw_param *wrq = &wrqu->power;
int mode = pDevice->ePSMode;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
if ((wrq->disabled = (mode == WMAC_POWER_CAM)))
return 0;
if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
- wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
+ wrq->value = (int)((pMgmt->wListenInterval *
+ pMgmt->wCurrBeaconPeriod) / 100);
wrq->flags = IW_POWER_TIMEOUT;
} else {
- wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
+ wrq->value = (int)((pMgmt->wListenInterval *
+ pMgmt->wCurrBeaconPeriod) / 100);
wrq->flags = IW_POWER_PERIOD;
}
+
wrq->flags |= IW_POWER_ALL_R;
return 0;
}
@@ -1294,12 +1416,13 @@ int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: get Sensitivity
*/
int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->sens;
long ldBm;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS\n");
if (pDevice->bLinkPass == TRUE) {
RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
wrq->value = ldBm;
@@ -1311,18 +1434,20 @@ int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info,
return 0;
}
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-
int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
+ struct iw_param *wrq = &wrqu->param;
int ret = 0;
static int wpa_version = 0; // must be static to save the last value, einsn liu
static int pairwise = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
switch (wrq->flags & IW_AUTH_INDEX) {
case IW_AUTH_WPA_VERSION:
wpa_version = wrq->value;
@@ -1406,6 +1531,7 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
}
break;
default:
+ PRINT_K("iwctl_siwauth: not supported %x\n", wrq->flags);
ret = -EOPNOTSUPP;
break;
}
@@ -1413,18 +1539,22 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
}
int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
return -EOPNOTSUPP;
}
int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
+ struct iw_point *wrq = &wrqu->data;
int ret = 0;
+ if (pMgmt == NULL)
+ return -EFAULT;
+
if (wrq->length){
if ((wrq->length < 2) || (extra[1] + 2 != wrq->length)) {
ret = -EINVAL;
@@ -1450,13 +1580,17 @@ out: // not completely ...not necessary in wpa_supplicant 0.5.8
}
int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
+ struct iw_point *wrq = &wrqu->data;
int ret = 0;
int space = wrq->length;
+ if (pMgmt == NULL)
+ return -EFAULT;
+
wrq->length = 0;
if (pMgmt->wWPAIELen > 0) {
wrq->length = pMgmt->wWPAIELen;
@@ -1472,10 +1606,11 @@ int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info,
}
int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
+ struct iw_point *wrq = &wrqu->encoding;
struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
struct viawget_wpa_param *param=NULL;
// original member
@@ -1488,17 +1623,18 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
size_t seq_len = 0;
size_t key_len = 0;
u8 *buf;
- size_t blen;
u8 key_array[64];
int ret = 0;
- PRINT_K("SIOCSIWENCODEEXT...... \n");
+ PRINT_K("SIOCSIWENCODEEXT......\n");
- blen = sizeof(*param);
- buf = kmalloc((int)blen, (int)GFP_KERNEL);
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ buf = kzalloc(sizeof(struct viawget_wpa_param), GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
- memset(buf, 0, blen);
+
param = (struct viawget_wpa_param *)buf;
// recover alg_name
@@ -1588,28 +1724,33 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
}
/*******/
spin_lock_irq(&pDevice->lock);
- ret = wpa_set_keys(pDevice, param, TRUE);
+ ret = wpa_set_keys(pDevice, param);
spin_unlock_irq(&pDevice->lock);
error:
- kfree(param);
+ kfree(buf);
return ret;
}
int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
return -EOPNOTSUPP;
}
int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
PSDevice pDevice = netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
struct iw_mlme *mlme = (struct iw_mlme *)extra;
int ret = 0;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
if (memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)) {
ret = -EINVAL;
return ret;
@@ -1629,81 +1770,62 @@ int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info,
return ret;
}
-#endif
+static int iwctl_config_commit(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SIOCSIWCOMMIT\n");
+
+ return 0;
+}
static const iw_handler iwctl_handler[] = {
- (iw_handler)NULL, // SIOCSIWCOMMIT
- (iw_handler)NULL, // SIOCGIWNAME
- (iw_handler)NULL, // SIOCSIWNWID
- (iw_handler)NULL, // SIOCGIWNWID
- (iw_handler)NULL, // SIOCSIWFREQ
- (iw_handler)NULL, // SIOCGIWFREQ
- (iw_handler)NULL, // SIOCSIWMODE
- (iw_handler)NULL, // SIOCGIWMODE
- (iw_handler)NULL, // SIOCSIWSENS
- (iw_handler)NULL, // SIOCGIWSENS
- (iw_handler)NULL, // SIOCSIWRANGE
- (iw_handler)iwctl_giwrange, // SIOCGIWRANGE
- (iw_handler)NULL, // SIOCSIWPRIV
- (iw_handler)NULL, // SIOCGIWPRIV
- (iw_handler)NULL, // SIOCSIWSTATS
- (iw_handler)NULL, // SIOCGIWSTATS
- (iw_handler)NULL, // SIOCSIWSPY
- (iw_handler)NULL, // SIOCGIWSPY
- (iw_handler)NULL, // -- hole --
- (iw_handler)NULL, // -- hole --
- (iw_handler)NULL, // SIOCSIWAP
- (iw_handler)NULL, // SIOCGIWAP
- (iw_handler)NULL, // -- hole -- 0x16
- (iw_handler)NULL, // SIOCGIWAPLIST
- (iw_handler)iwctl_siwscan, // SIOCSIWSCAN
- (iw_handler)iwctl_giwscan, // SIOCGIWSCAN
- (iw_handler)NULL, // SIOCSIWESSID
- (iw_handler)NULL, // SIOCGIWESSID
- (iw_handler)NULL, // SIOCSIWNICKN
- (iw_handler)NULL, // SIOCGIWNICKN
- (iw_handler)NULL, // -- hole --
- (iw_handler)NULL, // -- hole --
- (iw_handler)NULL, // SIOCSIWRATE 0x20
- (iw_handler)NULL, // SIOCGIWRATE
- (iw_handler)NULL, // SIOCSIWRTS
- (iw_handler)NULL, // SIOCGIWRTS
- (iw_handler)NULL, // SIOCSIWFRAG
- (iw_handler)NULL, // SIOCGIWFRAG
- (iw_handler)NULL, // SIOCSIWTXPOW
- (iw_handler)NULL, // SIOCGIWTXPOW
- (iw_handler)NULL, // SIOCSIWRETRY
- (iw_handler)NULL, // SIOCGIWRETRY
- (iw_handler)NULL, // SIOCSIWENCODE
- (iw_handler)NULL, // SIOCGIWENCODE
- (iw_handler)NULL, // SIOCSIWPOWER
- (iw_handler)NULL, // SIOCGIWPOWER
- (iw_handler)NULL, // -- hole --
- (iw_handler)NULL, // -- hole --
- (iw_handler)NULL, // SIOCSIWGENIE
- (iw_handler)NULL, // SIOCGIWGENIE
- (iw_handler)NULL, // SIOCSIWAUTH
- (iw_handler)NULL, // SIOCGIWAUTH
- (iw_handler)NULL, // SIOCSIWENCODEEXT
- (iw_handler)NULL, // SIOCGIWENCODEEXT
- (iw_handler)NULL, // SIOCSIWPMKSA
- (iw_handler)NULL, // -- hole --
+ IW_HANDLER(SIOCSIWCOMMIT, iwctl_config_commit),
+ IW_HANDLER(SIOCGIWNAME, iwctl_giwname),
+ IW_HANDLER(SIOCSIWFREQ, iwctl_siwfreq),
+ IW_HANDLER(SIOCGIWFREQ, iwctl_giwfreq),
+ IW_HANDLER(SIOCSIWMODE, iwctl_siwmode),
+ IW_HANDLER(SIOCGIWMODE, iwctl_giwmode),
+ IW_HANDLER(SIOCGIWSENS, iwctl_giwsens),
+ IW_HANDLER(SIOCGIWRANGE, iwctl_giwrange),
+ IW_HANDLER(SIOCSIWAP, iwctl_siwap),
+ IW_HANDLER(SIOCGIWAP, iwctl_giwap),
+ IW_HANDLER(SIOCSIWMLME, iwctl_siwmlme),
+ IW_HANDLER(SIOCGIWAPLIST, iwctl_giwaplist),
+ IW_HANDLER(SIOCSIWSCAN, iwctl_siwscan),
+ IW_HANDLER(SIOCGIWSCAN, iwctl_giwscan),
+ IW_HANDLER(SIOCSIWESSID, iwctl_siwessid),
+ IW_HANDLER(SIOCGIWESSID, iwctl_giwessid),
+ IW_HANDLER(SIOCSIWRATE, iwctl_siwrate),
+ IW_HANDLER(SIOCGIWRATE, iwctl_giwrate),
+ IW_HANDLER(SIOCSIWRTS, iwctl_siwrts),
+ IW_HANDLER(SIOCGIWRTS, iwctl_giwrts),
+ IW_HANDLER(SIOCSIWFRAG, iwctl_siwfrag),
+ IW_HANDLER(SIOCGIWFRAG, iwctl_giwfrag),
+ IW_HANDLER(SIOCSIWRETRY, iwctl_siwretry),
+ IW_HANDLER(SIOCGIWRETRY, iwctl_giwretry),
+ IW_HANDLER(SIOCSIWENCODE, iwctl_siwencode),
+ IW_HANDLER(SIOCGIWENCODE, iwctl_giwencode),
+ IW_HANDLER(SIOCSIWPOWER, iwctl_siwpower),
+ 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),
+ IW_HANDLER(SIOCGIWENCODEEXT, iwctl_giwencodeext)
};
static const iw_handler iwctl_private_handler[] = {
NULL, // SIOCIWFIRSTPRIV
};
-struct iw_priv_args iwctl_private_args[] = {
- { IOCTL_CMD_SET, IW_PRIV_TYPE_CHAR | 1024, 0, "set" },
-};
-
const struct iw_handler_def iwctl_handler_def = {
.get_wireless_stats = &iwctl_get_wireless_stats,
- .num_standard = sizeof(iwctl_handler) / sizeof(iw_handler),
+ .num_standard = ARRAY_SIZE(iwctl_handler),
.num_private = 0,
.num_private_args = 0,
- .standard = (iw_handler *)iwctl_handler,
+ .standard = iwctl_handler,
.private = NULL,
.private_args = NULL,
};
diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h
index d056f83a915..b594a10db31 100644
--- a/drivers/staging/vt6656/iwctl.h
+++ b/drivers/staging/vt6656/iwctl.h
@@ -42,106 +42,105 @@
struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev);
int iwctl_siwap(struct net_device *dev, struct iw_request_info *info,
- struct sockaddr *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
-void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra);
+int iwctl_giwrange(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
-void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info,
- __u32 *wmode, char *extra);
+int iwctl_giwmode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info,
- __u32 *wmode, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info,
- struct iw_freq *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info,
- struct iw_freq *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_giwname(struct net_device *dev, struct iw_request_info *info,
- char *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_giwap(struct net_device *dev, struct iw_request_info *info,
- struct sockaddr *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
-void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra);
+int iwctl_giwessid(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
-void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra);
+int iwctl_giwrate(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
-int iwctl_siwrts(struct net_device *dev, struct iw_param *wrq);
+int iwctl_siwrts(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra);
-#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+ union iwreq_data *wrqu, char *extra);
extern const struct iw_handler_def iwctl_handler_def;
-extern const struct iw_priv_args iwctl_private_args;
+extern const struct iw_priv_args iwctl_priv_args;
#endif /* __IWCTL_H__ */
diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c
index a61fcb9591a..8c78b86b5c8 100644
--- a/drivers/staging/vt6656/key.c
+++ b/drivers/staging/vt6656/key.c
@@ -36,9 +36,9 @@
*
*/
+#include "mac.h"
#include "tmacro.h"
#include "key.h"
-#include "mac.h"
#include "rndis.h"
#include "control.h"
@@ -223,7 +223,7 @@ BOOL KeybSetKey(
PSKeyManagement pTable,
PBYTE pbyBSSID,
DWORD dwKeyIndex,
- unsigned long uKeyLength,
+ u32 uKeyLength,
PQWORD pKeyRSC,
PBYTE pbyKey,
BYTE byKeyDecMode
@@ -235,7 +235,8 @@ BOOL KeybSetKey(
PSKeyItem pKey;
unsigned int uKeyIdx;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetKey: %lX\n", dwKeyIndex);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Enter KeybSetKey: %X\n", dwKeyIndex);
j = (MAX_KEY_TABLE-1);
for (i=0;i<(MAX_KEY_TABLE-1);i++) {
@@ -261,7 +262,9 @@ BOOL KeybSetKey(
if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
// Group transmit key
pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Group transmit key(R)[%X]: %d\n",
+ pTable->KeyTable[i].dwGTKeyIndex, i);
}
pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed
pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
@@ -302,9 +305,12 @@ BOOL KeybSetKey(
}
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n ",
+ pKey->dwTSC47_16);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ",
+ pKey->wTSC15_0);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n ",
+ pKey->dwKeyIndex);
return (TRUE);
}
@@ -326,7 +332,9 @@ BOOL KeybSetKey(
if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
// Group transmit key
pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(N)[%lX]: %d\n", pTable->KeyTable[j].dwGTKeyIndex, j);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Group transmit key(N)[%X]: %d\n",
+ pTable->KeyTable[j].dwGTKeyIndex, j);
}
pTable->KeyTable[j].wKeyCtl &= 0xFF0F; // clear group key control filed
pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4);
@@ -367,9 +375,11 @@ BOOL KeybSetKey(
}
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n ",
+ pKey->dwTSC47_16);
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n ",
+ pKey->dwKeyIndex);
return (TRUE);
}
@@ -597,7 +607,8 @@ BOOL KeybGetTransmitKey(PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyType,
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
}
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %X\n",
+ pTable->KeyTable[i].dwGTKeyIndex);
return (TRUE);
}
@@ -664,7 +675,7 @@ BOOL KeybSetDefaultKey(
void *pDeviceHandler,
PSKeyManagement pTable,
DWORD dwKeyIndex,
- unsigned long uKeyLength,
+ u32 uKeyLength,
PQWORD pKeyRSC,
PBYTE pbyKey,
BYTE byKeyDecMode
@@ -696,7 +707,10 @@ BOOL KeybSetDefaultKey(
if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
// Group transmit key
pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, MAX_KEY_TABLE-1);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Group transmit key(R)[%X]: %d\n",
+ pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex,
+ MAX_KEY_TABLE-1);
}
pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00; // clear all key control filed
@@ -747,9 +761,11 @@ BOOL KeybSetDefaultKey(
}
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n",
+ pKey->dwTSC47_16);
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n",
+ pKey->dwKeyIndex);
return (TRUE);
}
@@ -775,7 +791,7 @@ BOOL KeybSetAllGroupKey(
void *pDeviceHandler,
PSKeyManagement pTable,
DWORD dwKeyIndex,
- unsigned long uKeyLength,
+ u32 uKeyLength,
PQWORD pKeyRSC,
PBYTE pbyKey,
BYTE byKeyDecMode
@@ -787,7 +803,8 @@ BOOL KeybSetAllGroupKey(
PSKeyItem pKey;
unsigned int uKeyIdx;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %X\n",
+ dwKeyIndex);
if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key
@@ -804,7 +821,9 @@ BOOL KeybSetAllGroupKey(
if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
// Group transmit key
pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Group transmit key(R)[%X]: %d\n",
+ pTable->KeyTable[i].dwGTKeyIndex, i);
}
pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed
diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h
index f749c7a027d..bd35d39621a 100644
--- a/drivers/staging/vt6656/key.h
+++ b/drivers/staging/vt6656/key.h
@@ -58,7 +58,7 @@
typedef struct tagSKeyItem
{
BOOL bKeyValid;
- unsigned long uKeyLength;
+ u32 uKeyLength;
BYTE abyKey[MAX_KEY_LEN];
QWORD KeyRSC;
DWORD dwTSC47_16;
@@ -107,7 +107,7 @@ BOOL KeybSetKey(
PSKeyManagement pTable,
PBYTE pbyBSSID,
DWORD dwKeyIndex,
- unsigned long uKeyLength,
+ u32 uKeyLength,
PQWORD pKeyRSC,
PBYTE pbyKey,
BYTE byKeyDecMode
@@ -146,7 +146,7 @@ BOOL KeybSetDefaultKey(
void *pDeviceHandler,
PSKeyManagement pTable,
DWORD dwKeyIndex,
- unsigned long uKeyLength,
+ u32 uKeyLength,
PQWORD pKeyRSC,
PBYTE pbyKey,
BYTE byKeyDecMode
@@ -156,7 +156,7 @@ BOOL KeybSetAllGroupKey(
void *pDeviceHandler,
PSKeyManagement pTable,
DWORD dwKeyIndex,
- unsigned long uKeyLength,
+ u32 uKeyLength,
PQWORD pKeyRSC,
PBYTE pbyKey,
BYTE byKeyDecMode
diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c
index af4a29d1477..8fddc7b3930 100644
--- a/drivers/staging/vt6656/mac.c
+++ b/drivers/staging/vt6656/mac.c
@@ -260,7 +260,8 @@ BYTE pbyData[24];
dwData1 <<= 16;
dwData1 |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5));
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData1, wKeyCtl);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %X,"\
+ " KeyCtl:%X\n", wOffset, dwData1, wKeyCtl);
//VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
//VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
@@ -277,7 +278,8 @@ BYTE pbyData[24];
dwData2 <<= 8;
dwData2 |= *(pbyAddr+0);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %lX\n", wOffset, dwData2);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %X\n",
+ wOffset, dwData2);
//VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
//VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index ad422dea702..f33086d6649 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -61,7 +61,6 @@
#include "bssdb.h"
#include "hostap.h"
#include "wpactl.h"
-#include "ioctl.h"
#include "iwctl.h"
#include "dpc.h"
#include "datarate.h"
@@ -244,7 +243,6 @@ static int Config_FileGetParameter(unsigned char *string,
unsigned char *dest,
unsigned char *source);
-static BOOL device_release_WPADEV(PSDevice pDevice);
static void usb_device_reset(PSDevice pDevice);
@@ -634,40 +632,6 @@ static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
return TRUE;
}
-static BOOL device_release_WPADEV(PSDevice pDevice)
-{
- viawget_wpa_header *wpahdr;
- int ii=0;
- // wait_queue_head_t Set_wait;
- //send device close to wpa_supplicant layer
- if (pDevice->bWPADEVUp==TRUE) {
- wpahdr = (viawget_wpa_header *)pDevice->skb->data;
- wpahdr->type = VIAWGET_DEVICECLOSE_MSG;
- wpahdr->resp_ie_len = 0;
- wpahdr->req_ie_len = 0;
- skb_put(pDevice->skb, sizeof(viawget_wpa_header));
- pDevice->skb->dev = pDevice->wpadev;
- skb_reset_mac_header(pDevice->skb);
- pDevice->skb->pkt_type = PACKET_HOST;
- pDevice->skb->protocol = htons(ETH_P_802_2);
- memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
- netif_rx(pDevice->skb);
- pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
-
- //wait release WPADEV
- // init_waitqueue_head(&Set_wait);
- // wait_event_timeout(Set_wait, ((pDevice->wpadev==NULL)&&(pDevice->skb == NULL)),5*HZ); //1s wait
- while(pDevice->bWPADEVUp==TRUE) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout (HZ/20); //wait 50ms
- ii++;
- if(ii>20)
- break;
- }
- }
- return TRUE;
-}
-
#ifdef CONFIG_PM /* Minimal support for suspend and resume */
static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
@@ -711,7 +675,7 @@ static const struct net_device_ops device_netdev_ops = {
.ndo_set_rx_mode = device_set_multi,
};
-static int __devinit
+static int
vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
u8 fake_mac[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
@@ -758,17 +722,6 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
usb_device_reset(pDevice);
- {
- union iwreq_data wrqu;
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.flags = RT_INSMOD_EVENT_FLAG;
- wrqu.data.length = IFNAMSIZ;
- wireless_send_event(pDevice->dev,
- IWEVCUSTOM,
- &wrqu,
- pDevice->dev->name);
- }
-
return 0;
err_netdev:
@@ -991,12 +944,6 @@ BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
static int device_open(struct net_device *dev) {
PSDevice pDevice=(PSDevice) netdev_priv(dev);
- extern SWPAResult wpa_Result;
- memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
- wpa_Result.proto = 0;
- wpa_Result.key_mgmt = 0;
- wpa_Result.eap_type = 0;
- wpa_Result.authenticated = FALSE;
pDevice->fWPA_Authened = FALSE;
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_open...\n");
@@ -1056,13 +1003,11 @@ static int device_open(struct net_device *dev) {
pDevice->bEventAvailable = FALSE;
pDevice->bWPADEVUp = FALSE;
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
pDevice->bwextstep0 = FALSE;
pDevice->bwextstep1 = FALSE;
pDevice->bwextstep2 = FALSE;
pDevice->bwextstep3 = FALSE;
pDevice->bWPASuppWextEnabled = FALSE;
-#endif
pDevice->byReAssocCount = 0;
RXvWorkItem(pDevice);
@@ -1096,15 +1041,8 @@ static int device_open(struct net_device *dev) {
netif_stop_queue(pDevice->dev);
pDevice->flags |= DEVICE_FLAGS_OPENED;
-{
- union iwreq_data wrqu;
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.flags = RT_UPDEV_EVENT_FLAG;
- wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
-}
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
- return 0;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success..\n");
+ return 0;
free_all:
device_free_frag_bufs(pDevice);
@@ -1133,19 +1071,11 @@ static int device_close(struct net_device *dev) {
if (pDevice == NULL)
return -ENODEV;
-{
- union iwreq_data wrqu;
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.flags = RT_DOWNDEV_EVENT_FLAG;
- wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
-}
-
if (pDevice->bLinkPass) {
bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
mdelay(30);
}
-device_release_WPADEV(pDevice);
memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
pMgmt->bShareKeyAlgorithm = FALSE;
@@ -1204,22 +1134,13 @@ device_release_WPADEV(pDevice);
return 0;
}
-static void __devexit vt6656_disconnect(struct usb_interface *intf)
+static void vt6656_disconnect(struct usb_interface *intf)
{
PSDevice device = usb_get_intfdata(intf);
if (!device)
return;
- {
- union iwreq_data req;
- memset(&req, 0, sizeof(req));
- req.data.flags = RT_RMMOD_EVENT_FLAG;
- wireless_send_event(device->dev, IWEVCUSTOM, &req, NULL);
- }
-
- device_release_WPADEV(device);
- release_firmware(device->firmware);
usb_set_intfdata(intf, NULL);
usb_put_dev(interface_to_usbdev(intf));
@@ -1228,9 +1149,9 @@ static void __devexit vt6656_disconnect(struct usb_interface *intf)
if (device->dev) {
unregister_netdev(device->dev);
- wpa_set_wpadev(device, 0);
free_netdev(device->dev);
}
+
}
static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
@@ -1549,470 +1470,35 @@ static void device_set_multi(struct net_device *dev) {
}
-
-static struct net_device_stats *device_get_stats(struct net_device *dev) {
+static struct net_device_stats *device_get_stats(struct net_device *dev)
+{
PSDevice pDevice=(PSDevice) netdev_priv(dev);
return &pDevice->stats;
}
-
-static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
- PSDevice pDevice = (PSDevice)netdev_priv(dev);
- PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
- PSCmdRequest pReq;
- //BOOL bCommit = FALSE;
+static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ PSDevice pDevice = (PSDevice)netdev_priv(dev);
struct iwreq *wrq = (struct iwreq *) rq;
- int rc =0;
-
- if (pMgmt == NULL) {
- rc = -EFAULT;
- return rc;
- }
-
- switch(cmd) {
-
- case SIOCGIWNAME:
- rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
- break;
-
- case SIOCSIWNWID:
- case SIOCGIWNWID: //0x8b03 support
- rc = -EOPNOTSUPP;
- break;
-
- // Set frequency/channel
- case SIOCSIWFREQ:
- rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
- break;
-
- // Get frequency/channel
- case SIOCGIWFREQ:
- rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
- break;
-
- // Set desired network name (ESSID)
- case SIOCSIWESSID:
-
- {
- char essid[IW_ESSID_MAX_SIZE+1];
- if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
- rc = -E2BIG;
- break;
- }
- if (copy_from_user(essid, wrq->u.essid.pointer,
- wrq->u.essid.length)) {
- rc = -EFAULT;
- break;
- }
- rc = iwctl_siwessid(dev, NULL,
- &(wrq->u.essid), essid);
- }
- break;
-
-
- // Get current network name (ESSID)
- case SIOCGIWESSID:
-
- {
- char essid[IW_ESSID_MAX_SIZE+1];
- if (wrq->u.essid.pointer) {
- iwctl_giwessid(dev, NULL,
- &(wrq->u.essid), essid);
- if (copy_to_user(wrq->u.essid.pointer,
- essid,
- wrq->u.essid.length) )
- rc = -EFAULT;
- }
- }
- break;
-
- case SIOCSIWAP:
-
- rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
- break;
-
-
- // Get current Access Point (BSSID)
- case SIOCGIWAP:
- rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
- break;
-
-
- // Set desired station name
- case SIOCSIWNICKN:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
- rc = -EOPNOTSUPP;
- break;
-
- // Get current station name
- case SIOCGIWNICKN:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
- rc = -EOPNOTSUPP;
- break;
-
- // Set the desired bit-rate
- case SIOCSIWRATE:
- rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
- break;
-
- // Get the current bit-rate
- case SIOCGIWRATE:
- iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
- break;
-
- // Set the desired RTS threshold
- case SIOCSIWRTS:
-
- rc = iwctl_siwrts(dev, &(wrq->u.rts));
- break;
-
- // Get the current RTS threshold
- case SIOCGIWRTS:
-
- rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
- break;
-
- // Set the desired fragmentation threshold
- case SIOCSIWFRAG:
-
- rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
- break;
-
- // Get the current fragmentation threshold
- case SIOCGIWFRAG:
-
- rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
- break;
-
- // Set mode of operation
- case SIOCSIWMODE:
- rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
- break;
-
- // Get mode of operation
- case SIOCGIWMODE:
- iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
- break;
-
- // Set WEP keys and mode
- case SIOCSIWENCODE:
- {
- char abyKey[WLAN_WEP232_KEYLEN];
-
- if (wrq->u.encoding.pointer) {
-
-
- if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
- rc = -E2BIG;
- break;
- }
- memset(abyKey, 0, WLAN_WEP232_KEYLEN);
- if (copy_from_user(abyKey,
- wrq->u.encoding.pointer,
- wrq->u.encoding.length)) {
- rc = -EFAULT;
- break;
- }
- } else if (wrq->u.encoding.length != 0) {
- rc = -EINVAL;
- break;
- }
- rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
- }
- break;
-
- // Get the WEP keys and mode
- case SIOCGIWENCODE:
-
- if (!capable(CAP_NET_ADMIN)) {
- rc = -EPERM;
- break;
- }
- {
- char abyKey[WLAN_WEP232_KEYLEN];
-
- rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
- if (rc != 0) break;
- if (wrq->u.encoding.pointer) {
- if (copy_to_user(wrq->u.encoding.pointer,
- abyKey,
- wrq->u.encoding.length))
- rc = -EFAULT;
- }
- }
- break;
-
- // Get the current Tx-Power
- case SIOCGIWTXPOW:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
- rc = -EOPNOTSUPP;
- break;
-
- case SIOCSIWTXPOW:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
- rc = -EOPNOTSUPP;
- break;
-
- case SIOCSIWRETRY:
-
- rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
- break;
-
- case SIOCGIWRETRY:
-
- rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
- break;
-
- // Get range of parameters
- case SIOCGIWRANGE:
-
- {
- struct iw_range range;
-
- iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range);
- if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
- rc = -EFAULT;
- }
-
- break;
-
- case SIOCGIWPOWER:
-
- rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
- break;
-
-
- case SIOCSIWPOWER:
-
- rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
- break;
-
-
- case SIOCGIWSENS:
-
- rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
- break;
-
- case SIOCSIWSENS:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
- rc = -EOPNOTSUPP;
- break;
-
- case SIOCGIWAPLIST:
- {
- char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
-
- if (wrq->u.data.pointer) {
- rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
- if (rc == 0) {
- if (copy_to_user(wrq->u.data.pointer,
- buffer,
- (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality)))
- ))
- rc = -EFAULT;
- }
- }
- }
- break;
-
-
-#ifdef WIRELESS_SPY
- // Set the spy list
- case SIOCSIWSPY:
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
- rc = -EOPNOTSUPP;
- break;
-
- // Get the spy list
- case SIOCGIWSPY:
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
- rc = -EOPNOTSUPP;
- break;
-
-#endif // WIRELESS_SPY
-
- case SIOCGIWPRIV:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
- rc = -EOPNOTSUPP;
-/*
- if(wrq->u.data.pointer) {
- wrq->u.data.length = sizeof(iwctl_private_args) / sizeof( iwctl_private_args[0]);
-
- if(copy_to_user(wrq->u.data.pointer,
- (u_char *) iwctl_private_args,
- sizeof(iwctl_private_args)))
- rc = -EFAULT;
- }
-*/
- break;
-
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
- case SIOCSIWAUTH:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
- rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
- break;
-
- case SIOCGIWAUTH:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
- rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
- break;
-
- case SIOCSIWGENIE:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
- rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
- break;
-
- case SIOCGIWGENIE:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
- rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
- break;
-
- case SIOCSIWENCODEEXT:
- {
- char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
- if(wrq->u.encoding.pointer){
- memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1);
- if(wrq->u.encoding.length > (sizeof(struct iw_encode_ext)+ MAX_KEY_LEN)){
- rc = -E2BIG;
- break;
- }
- if(copy_from_user(extra, wrq->u.encoding.pointer,wrq->u.encoding.length)){
- rc = -EFAULT;
- break;
- }
- }else if(wrq->u.encoding.length != 0){
- rc = -EINVAL;
- break;
- }
- rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
- }
- break;
-
- case SIOCGIWENCODEEXT:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
- rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
- break;
-
- case SIOCSIWMLME:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
- rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
- break;
-
-#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-
- case IOCTL_CMD_TEST:
-
- if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
- rc = -EFAULT;
- break;
- } else {
- rc = 0;
- }
- pReq = (PSCmdRequest)rq;
-
- //20080130-01,<Remark> by Mike Liu
- // if(pDevice->bLinkPass==TRUE)
- pReq->wResult = MAGIC_CODE; //Linking status:0x3142
- //20080130-02,<Remark> by Mike Liu
- // else
- // pReq->wResult = MAGIC_CODE+1; //disconnect status:0x3143
- break;
-
- case IOCTL_CMD_SET:
- if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
- (((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_WPA))
- {
- rc = -EFAULT;
- break;
- } else {
- rc = 0;
- }
+ int rc = 0;
- if (test_and_set_bit( 0, (void*)&(pMgmt->uCmdBusy))) {
- return -EBUSY;
- }
- rc = private_ioctl(pDevice, rq);
- clear_bit( 0, (void*)&(pMgmt->uCmdBusy));
- break;
+ switch (cmd) {
- case IOCTL_CMD_HOSTAPD:
+ case IOCTL_CMD_HOSTAPD:
- if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
- rc = -EFAULT;
- break;
- } else {
- rc = 0;
- }
+ if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+ rc = -EFAULT;
rc = vt6656_hostap_ioctl(pDevice, &wrq->u.data);
- break;
-
- case IOCTL_CMD_WPA:
-
- if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
- rc = -EFAULT;
- break;
- } else {
- rc = 0;
- }
-
- rc = wpa_ioctl(pDevice, &wrq->u.data);
- break;
+ break;
case SIOCETHTOOL:
- return ethtool_ioctl(dev, (void *) rq->ifr_data);
- // All other calls are currently unsupported
-
- default:
- rc = -EOPNOTSUPP;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not supported..%x\n", cmd);
-
-
- }
-
- if (pDevice->bCommit) {
- if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
- netif_stop_queue(pDevice->dev);
- spin_lock_irq(&pDevice->lock);
- bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
- spin_unlock_irq(&pDevice->lock);
- }
- else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
- spin_lock_irq(&pDevice->lock);
-//2007-1121-01<Modify>by EinsnLiu
- if (pDevice->bLinkPass &&
- memcmp(pMgmt->abyCurrSSID,pMgmt->abyDesireSSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
- bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
- } else {
- pDevice->bLinkPass = FALSE;
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- memset(pMgmt->abyCurrBSSID, 0, 6);
- }
- ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
-//End Modify
- netif_stop_queue(pDevice->dev);
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
- pMgmt->eScanType = WMAC_SCAN_ACTIVE;
- if (!pDevice->bWPASuppWextEnabled)
-#endif
- bScheduleCommand((void *) pDevice,
- WLAN_CMD_BSSID_SCAN,
- pMgmt->abyDesireSSID);
- bScheduleCommand((void *) pDevice,
- WLAN_CMD_SSID,
- NULL);
- spin_unlock_irq(&pDevice->lock);
- }
- pDevice->bCommit = FALSE;
- }
+ return ethtool_ioctl(dev, (void *) rq->ifr_data);
+ }
- return rc;
+ return rc;
}
diff --git a/drivers/staging/vt6656/mib.c b/drivers/staging/vt6656/mib.c
index 8a6ee72f440..d4c7b0cc7ec 100644
--- a/drivers/staging/vt6656/mib.c
+++ b/drivers/staging/vt6656/mib.c
@@ -37,7 +37,6 @@
*
*/
-#include "upc.h"
#include "mac.h"
#include "tether.h"
#include "mib.h"
diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h
index 82d69a9cc20..85c28e92366 100644
--- a/drivers/staging/vt6656/mib.h
+++ b/drivers/staging/vt6656/mib.h
@@ -68,7 +68,6 @@ typedef struct tagSDot11Counters {
unsigned long long TKIPLocalMICFailures;
unsigned long long TKIPRemoteMICFailures;
unsigned long long TKIPICVErrors;
- unsigned long long TKIPCounterMeasuresInvoked;
unsigned long long TKIPReplays;
unsigned long long CCMPFormatErrors;
unsigned long long CCMPReplays;
diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c
index 593cdc713b0..74c0598e37b 100644
--- a/drivers/staging/vt6656/rf.c
+++ b/drivers/staging/vt6656/rf.c
@@ -769,6 +769,9 @@ BYTE byPwr = pDevice->byCCKPwr;
return TRUE;
}
+ if (uCH == 0)
+ return -EINVAL;
+
switch (uRATE) {
case RATE_1M:
case RATE_2M:
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 33908387988..83c04e12093 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -355,7 +355,7 @@ s_vFillTxKey (
}
// Append IV after Mac Header
*pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111
- *pdwIV |= (pDevice->byKeyIndex << 30);
+ *pdwIV |= (u32)pDevice->byKeyIndex << 30;
*pdwIV = cpu_to_le32(*pdwIV);
pDevice->dwIVCounter++;
if (pDevice->dwIVCounter > WEP_IV_MASK) {
@@ -375,7 +375,8 @@ s_vFillTxKey (
*(pbyIVHead+3) = (BYTE)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
// Append IV&ExtIV after Mac Header
*pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %x\n",
+ *pdwExtIV);
} else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
pTransmitKey->wTSC15_0++;
@@ -1452,12 +1453,10 @@ s_bPacketToWirelessUsb(
pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
- if ((bNeedEncryption) && (pTransmitKey != NULL)) {
- if (((PSKeyTable) (pTransmitKey->pvKeyTable))->bSoftWEP == TRUE) {
- // WEP 256
- bSoftWEP = TRUE;
- }
- }
+ if (bNeedEncryption && pTransmitKey->pvKeyTable) {
+ if (((PSKeyTable)&pTransmitKey->pvKeyTable)->bSoftWEP == TRUE)
+ bSoftWEP = TRUE; /* WEP 256 */
+ }
pTxBufHead = (PTX_BUFFER) usbPacketBuf;
memset(pTxBufHead, 0, sizeof(TX_BUFFER));
@@ -1751,7 +1750,8 @@ s_bPacketToWirelessUsb(
MIC_vAppend((PBYTE)&(psEthHeader->abyDstAddr[0]), 12);
dwMIC_Priority = 0;
MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %X, %X\n",
+ dwMICKey0, dwMICKey1);
///////////////////////////////////////////////////////////////////
@@ -2633,7 +2633,8 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) {
MIC_vAppend((PBYTE)&(sEthHeader.abyDstAddr[0]), 12);
dwMIC_Priority = 0;
MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY:"\
+ " %X, %X\n", dwMICKey0, dwMICKey1);
uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
@@ -2653,7 +2654,8 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) {
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%x, %x\n",
+ *pdwMIC_L, *pdwMIC_R);
}
@@ -3027,21 +3029,18 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb)
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
}
else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
+ pTransmitKey->dwKeyIndex);
bNeedEncryption = TRUE;
}
}
}
- if (pDevice->byCntMeasure == 2) {
- bNeedDeAuth = TRUE;
- pDevice->s802_11Counter.TKIPCounterMeasuresInvoked++;
- }
-
if (pDevice->bEnableHostWEP) {
if ((uNodeIndex != 0) &&
(pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
+ pTransmitKey->dwKeyIndex);
bNeedEncryption = TRUE;
}
}
@@ -3050,6 +3049,7 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb)
if (pTransmitKey == NULL) {
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
+ pContext->bBoolInUse = FALSE;
dev_kfree_skb_irq(skb);
pStats->tx_dropped++;
return STATUS_FAILURE;
diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h
index f99acf1d8eb..dd2198acc63 100644
--- a/drivers/staging/vt6656/rxtx.h
+++ b/drivers/staging/vt6656/rxtx.h
@@ -61,9 +61,9 @@ typedef struct tagSCTSDataF {
// MICHDR data header
//
typedef struct tagSMICHDR {
- DWORD adwHDR0[4];
- DWORD adwHDR1[4];
- DWORD adwHDR2[4];
+ u32 adwHDR0[4];
+ u32 adwHDR1[4];
+ u32 adwHDR2[4];
} SMICHDR, *PSMICHDR;
@@ -630,7 +630,7 @@ typedef struct tagSTX_BUFFER
BYTE byPKTNO;
WORD wTxByteCount;
- DWORD adwTxKey[4];
+ u32 adwTxKey[4];
WORD wFIFOCtl;
WORD wTimeStamp;
WORD wFragCtl;
diff --git a/drivers/staging/vt6656/tkip.c b/drivers/staging/vt6656/tkip.c
index 003123e550f..282c08d6576 100644
--- a/drivers/staging/vt6656/tkip.c
+++ b/drivers/staging/vt6656/tkip.c
@@ -189,27 +189,25 @@ void TKIPvMixKey(
PBYTE pbyRC4Key
)
{
- unsigned int p1k[5];
-// unsigned int ttak0, ttak1, ttak2, ttak3, ttak4;
- unsigned int tsc0, tsc1, tsc2;
- unsigned int ppk0, ppk1, ppk2, ppk3, ppk4, ppk5;
- unsigned long int pnl,pnh;
-
- int i, j;
-
- pnl = wTSC15_0;
- pnh = dwTSC47_16;
-
- tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
- tsc1 = (unsigned int)(pnh % 65536);
- tsc2 = (unsigned int)(pnl % 65536); /* lsb */
-
- /* Phase 1, step 1 */
- p1k[0] = tsc1;
- p1k[1] = tsc0;
- p1k[2] = (unsigned int)(pbyTA[0] + (pbyTA[1]*256));
- p1k[3] = (unsigned int)(pbyTA[2] + (pbyTA[3]*256));
- p1k[4] = (unsigned int)(pbyTA[4] + (pbyTA[5]*256));
+ u32 p1k[5];
+ u32 tsc0, tsc1, tsc2;
+ u32 ppk0, ppk1, ppk2, ppk3, ppk4, ppk5;
+ u32 pnl, pnh;
+ int i, j;
+
+ pnl = (u32)wTSC15_0;
+ pnh = (u32)(dwTSC47_16 & 0xffffffff);
+
+ tsc0 = (u32)((pnh >> 16) % 65536); /* msb */
+ tsc1 = (u32)(pnh % 65536);
+ tsc2 = (u32)(pnl % 65536); /* lsb */
+
+ /* Phase 1, step 1 */
+ p1k[0] = tsc1;
+ p1k[1] = tsc0;
+ p1k[2] = (u32)(pbyTA[0] + (pbyTA[1]*256));
+ p1k[3] = (u32)(pbyTA[2] + (pbyTA[3]*256));
+ p1k[4] = (u32)(pbyTA[4] + (pbyTA[5]*256));
/* Phase 1, step 2 */
for (i=0; i<8; i++) {
diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h
index 8e9450ef399..dfbf74713a8 100644
--- a/drivers/staging/vt6656/ttype.h
+++ b/drivers/staging/vt6656/ttype.h
@@ -29,6 +29,8 @@
#ifndef __TTYPE_H__
#define __TTYPE_H__
+#include <linux/types.h>
+
/******* Common definitions and typedefs ***********************************/
typedef int BOOL;
@@ -42,17 +44,17 @@ typedef int BOOL;
/****** Simple typedefs ***************************************************/
-typedef unsigned char BYTE; // 8-bit
-typedef unsigned short WORD; // 16-bit
-typedef unsigned long DWORD; // 32-bit
+typedef u8 BYTE;
+typedef u16 WORD;
+typedef u32 DWORD;
// QWORD is for those situation that we want
// an 8-byte-aligned 8 byte long structure
// which is NOT really a floating point number.
typedef union tagUQuadWord {
struct {
- DWORD dwLowDword;
- DWORD dwHighDword;
+ u32 dwLowDword;
+ u32 dwHighDword;
} u;
double DoNotUseThisField;
} UQuadWord;
@@ -60,8 +62,8 @@ typedef UQuadWord QWORD; // 64-bit
/****** Common pointer types ***********************************************/
-typedef unsigned long ULONG_PTR; // 32-bit
-typedef unsigned long DWORD_PTR; // 32-bit
+typedef u32 ULONG_PTR;
+typedef u32 DWORD_PTR;
// boolean pointer
diff --git a/drivers/staging/vt6656/upc.h b/drivers/staging/vt6656/upc.h
deleted file mode 100644
index b33aba4b12c..00000000000
--- a/drivers/staging/vt6656/upc.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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.
- *
- * File: upc.h
- *
- * Purpose: Macros to access device
- *
- * Author: Tevin Chen
- *
- * Date: Mar 17, 1997
- *
- */
-
-#ifndef __UPC_H__
-#define __UPC_H__
-
-#include "device.h"
-#include "ttype.h"
-
-/*--------------------- Export Definitions -------------------------*/
-
-
-//
-// For IO mapped
-//
-
-#ifdef IO_MAP
-
-#define VNSvInPortB(dwIOAddress, pbyData) { \
- *(pbyData) = inb(dwIOAddress); \
-}
-
-
-#define VNSvInPortW(dwIOAddress, pwData) { \
- *(pwData) = inw(dwIOAddress); \
-}
-
-#define VNSvInPortD(dwIOAddress, pdwData) { \
- *(pdwData) = inl(dwIOAddress); \
-}
-
-
-#define VNSvOutPortB(dwIOAddress, byData) { \
- outb(byData, dwIOAddress); \
-}
-
-
-#define VNSvOutPortW(dwIOAddress, wData) { \
- outw(wData, dwIOAddress); \
-}
-
-#define VNSvOutPortD(dwIOAddress, dwData) { \
- outl(dwData, dwIOAddress); \
-}
-
-#else
-
-//
-// For memory mapped IO
-//
-
-
-#define VNSvInPortB(dwIOAddress, pbyData) { \
- volatile BYTE* pbyAddr = ((PBYTE)(dwIOAddress)); \
- *(pbyData) = readb(pbyAddr); \
-}
-
-
-#define VNSvInPortW(dwIOAddress, pwData) { \
- volatile WORD* pwAddr = ((PWORD)(dwIOAddress)); \
- *(pwData) = readw(pwAddr); \
-}
-
-#define VNSvInPortD(dwIOAddress, pdwData) { \
- volatile DWORD* pdwAddr = ((PDWORD)(dwIOAddress)); \
- *(pdwData) = readl(pdwAddr); \
-}
-
-
-#define VNSvOutPortB(dwIOAddress, byData) { \
- volatile BYTE* pbyAddr = ((PBYTE)(dwIOAddress)); \
- writeb((BYTE)byData, pbyAddr); \
-}
-
-
-#define VNSvOutPortW(dwIOAddress, wData) { \
- volatile WORD* pwAddr = ((PWORD)(dwIOAddress)); \
- writew((WORD)wData, pwAddr); \
-}
-
-#define VNSvOutPortD(dwIOAddress, dwData) { \
- volatile DWORD* pdwAddr = ((PDWORD)(dwIOAddress)); \
- writel((DWORD)dwData, pdwAddr); \
-}
-
-#endif
-
-
-//
-// ALWAYS IO-Mapped IO when in 16-bit/32-bit environment
-//
-#define PCBvInPortB(dwIOAddress, pbyData) { \
- *(pbyData) = inb(dwIOAddress); \
-}
-
-#define PCBvInPortW(dwIOAddress, pwData) { \
- *(pwData) = inw(dwIOAddress); \
-}
-
-#define PCBvInPortD(dwIOAddress, pdwData) { \
- *(pdwData) = inl(dwIOAddress); \
-}
-
-#define PCBvOutPortB(dwIOAddress, byData) { \
- outb(byData, dwIOAddress); \
-}
-
-#define PCBvOutPortW(dwIOAddress, wData) { \
- outw(wData, dwIOAddress); \
-}
-
-#define PCBvOutPortD(dwIOAddress, dwData) { \
- outl(dwData, dwIOAddress); \
-}
-
-
-#define PCAvDelayByIO(uDelayUnit) { \
- BYTE byData; \
- unsigned long ii; \
- \
- if (uDelayUnit <= 50) { \
- udelay(uDelayUnit); \
- } \
- else { \
- for (ii = 0; ii < (uDelayUnit); ii++) \
- byData = inb(0x61); \
- } \
-}
-
-
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
-
-#endif /* __UPC_H__ */
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
index 609e8fa10b9..fc68518526e 100644
--- a/drivers/staging/vt6656/usbpipe.c
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -575,7 +575,8 @@ s_nsBulkInUsbIoCompleteRead(
// MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
// }
} else {
- bIndicateReceive = TRUE;
+ if (bytesRead)
+ bIndicateReceive = TRUE;
pDevice->ulBulkInContCRCError = 0;
pDevice->ulBulkInBytesRead += bytesRead;
@@ -660,6 +661,7 @@ PIPEnsSendBulkOut(
if (status != 0)
{
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Tx URB failed %d\n", status);
+ pContext->bBoolInUse = FALSE;
return STATUS_FAILURE;
}
return STATUS_PENDING;
diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c
index 586fbe1627f..22f6b41cfd1 100644
--- a/drivers/staging/vt6656/wcmd.c
+++ b/drivers/staging/vt6656/wcmd.c
@@ -316,17 +316,19 @@ s_MgrMakeProbeRequest(
return pTxPacket;
}
-void vCommandTimerWait(void *hDeviceContext, unsigned int MSecond)
+void vCommandTimerWait(void *hDeviceContext, unsigned long MSecond)
{
- PSDevice pDevice = (PSDevice)hDeviceContext;
+ PSDevice pDevice = (PSDevice)hDeviceContext;
- init_timer(&pDevice->sTimerCommand);
- pDevice->sTimerCommand.data = (unsigned long)pDevice;
- pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
- // RUN_AT :1 msec ~= (HZ/1024)
- pDevice->sTimerCommand.expires = (unsigned int)RUN_AT((MSecond * HZ) >> 10);
- add_timer(&pDevice->sTimerCommand);
- return;
+ 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;
}
void vRunCommand(void *hDeviceContext)
@@ -340,6 +342,7 @@ void vRunCommand(void *hDeviceContext)
BYTE byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
struct sk_buff *skb;
BYTE byData;
+ union iwreq_data wrqu;
if (pDevice->dwDiagRefCount != 0)
@@ -501,16 +504,11 @@ void vRunCommand(void *hDeviceContext)
pMgmt->eScanState = WMAC_NO_SCANNING;
pDevice->bStopDataPkt = FALSE;
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
- if(pMgmt->eScanType == WMAC_SCAN_PASSIVE)
- {
- //send scan event to wpa_Supplicant
- union iwreq_data wrqu;
- PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
- memset(&wrqu, 0, sizeof(wrqu));
- wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
- }
-#endif
+ /*send scan event to wpa_Supplicant*/
+ PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
+ memset(&wrqu, 0, sizeof(wrqu));
+ wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
+
s_bCommandComplete(pDevice);
break;
@@ -523,13 +521,11 @@ void vRunCommand(void *hDeviceContext)
return;
} else {
- #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
pDevice->bwextstep0 = FALSE;
pDevice->bwextstep1 = FALSE;
pDevice->bwextstep2 = FALSE;
pDevice->bwextstep3 = FALSE;
pDevice->bWPASuppWextEnabled = FALSE;
- #endif
pDevice->fWPA_Authened = FALSE;
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n");
@@ -672,7 +668,6 @@ void vRunCommand(void *hDeviceContext)
}
else {
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n");
- #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
// if(pDevice->bWPASuppWextEnabled == TRUE)
{
union iwreq_data wrqu;
@@ -681,7 +676,6 @@ void vRunCommand(void *hDeviceContext)
PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n");
wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
}
- #endif
}
}
s_bCommandComplete(pDevice);
@@ -924,7 +918,6 @@ void vRunCommand(void *hDeviceContext)
// unlock command busy
pMgmt->eCurrState = WMAC_STATE_IDLE;
pMgmt->sNodeDBTable[0].bActive = FALSE;
- #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
// if(pDevice->bWPASuppWextEnabled == TRUE)
{
union iwreq_data wrqu;
@@ -933,15 +926,12 @@ void vRunCommand(void *hDeviceContext)
PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
}
- #endif
}
- #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
pDevice->bwextstep0 = FALSE;
pDevice->bwextstep1 = FALSE;
pDevice->bwextstep2 = FALSE;
pDevice->bwextstep3 = FALSE;
pDevice->bWPASuppWextEnabled = FALSE;
- #endif
//clear current SSID
pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
pItemSSID->len = 0;
diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c
index 7db6a8d3508..95ddc8303bb 100644
--- a/drivers/staging/vt6656/wmgr.c
+++ b/drivers/staging/vt6656/wmgr.c
@@ -925,7 +925,6 @@ s_vMgrRxAssocResponse(
WLAN_FR_ASSOCRESP sFrame;
PWLAN_IE_SSID pItemSSID;
PBYTE pbyIEs;
- viawget_wpa_header *wpahdr;
@@ -973,32 +972,7 @@ s_vMgrRxAssocResponse(
DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID);
pDevice->bLinkPass = TRUE;
ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
- if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
- if(skb_tailroom(pDevice->skb) <(sizeof(viawget_wpa_header)+pMgmt->sAssocInfo.AssocInfo.ResponseIELength+
- pMgmt->sAssocInfo.AssocInfo.RequestIELength)) { //data room not enough
- dev_kfree_skb(pDevice->skb);
- pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
- }
- wpahdr = (viawget_wpa_header *)pDevice->skb->data;
- wpahdr->type = VIAWGET_ASSOC_MSG;
- wpahdr->resp_ie_len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength;
- wpahdr->req_ie_len = pMgmt->sAssocInfo.AssocInfo.RequestIELength;
- memcpy(pDevice->skb->data + sizeof(viawget_wpa_header), pMgmt->sAssocInfo.abyIEs, wpahdr->req_ie_len);
- memcpy(pDevice->skb->data + sizeof(viawget_wpa_header) + wpahdr->req_ie_len,
- pbyIEs,
- wpahdr->resp_ie_len
- );
- skb_put(pDevice->skb, sizeof(viawget_wpa_header) + wpahdr->resp_ie_len + wpahdr->req_ie_len);
- pDevice->skb->dev = pDevice->wpadev;
- skb_reset_mac_header(pDevice->skb);
- pDevice->skb->pkt_type = PACKET_HOST;
- pDevice->skb->protocol = htons(ETH_P_802_2);
- memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
- netif_rx(pDevice->skb);
- pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
- }
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
//if(pDevice->bWPASuppWextEnabled == TRUE)
{
BYTE buf[512];
@@ -1037,7 +1011,6 @@ s_vMgrRxAssocResponse(
wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
}
-#endif //#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
}
else {
@@ -1053,14 +1026,12 @@ s_vMgrRxAssocResponse(
}
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
//need clear flags related to Networkmanager
pDevice->bwextstep0 = FALSE;
pDevice->bwextstep1 = FALSE;
pDevice->bwextstep2 = FALSE;
pDevice->bwextstep3 = FALSE;
pDevice->bWPASuppWextEnabled = FALSE;
-#endif
if(pMgmt->eCurrState == WMAC_STATE_ASSOC)
timer_expire(pDevice->sTimerCommand, 0);
@@ -1587,7 +1558,6 @@ s_vMgrRxDisassociation(
WLAN_FR_DISASSOC sFrame;
unsigned int uNodeIndex = 0;
CMD_STATUS CmdStatus;
- viawget_wpa_header *wpahdr;
if ( pMgmt->eCurrMode == WMAC_MODE_ESS_AP ){
// if is acting an AP..
@@ -1608,20 +1578,6 @@ s_vMgrRxDisassociation(
DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason)));
pDevice->fWPA_Authened = FALSE;
- if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
- wpahdr = (viawget_wpa_header *)pDevice->skb->data;
- wpahdr->type = VIAWGET_DISASSOC_MSG;
- wpahdr->resp_ie_len = 0;
- wpahdr->req_ie_len = 0;
- skb_put(pDevice->skb, sizeof(viawget_wpa_header));
- pDevice->skb->dev = pDevice->wpadev;
- skb_reset_mac_header(pDevice->skb);
- pDevice->skb->pkt_type = PACKET_HOST;
- pDevice->skb->protocol = htons(ETH_P_802_2);
- memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
- netif_rx(pDevice->skb);
- pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
- }
//TODO: do something let upper layer know or
//try to send associate packet again because of inactivity timeout
@@ -1638,7 +1594,6 @@ s_vMgrRxDisassociation(
}
}
- #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
// if(pDevice->bWPASuppWextEnabled == TRUE)
{
union iwreq_data wrqu;
@@ -1647,7 +1602,6 @@ s_vMgrRxDisassociation(
PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
}
- #endif
}
/* else, ignore it */
@@ -1676,7 +1630,6 @@ s_vMgrRxDeauthentication(
{
WLAN_FR_DEAUTHEN sFrame;
unsigned int uNodeIndex = 0;
- viawget_wpa_header *wpahdr;
if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP ){
@@ -1712,22 +1665,6 @@ s_vMgrRxDeauthentication(
}
}
- if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
- wpahdr = (viawget_wpa_header *)pDevice->skb->data;
- wpahdr->type = VIAWGET_DISASSOC_MSG;
- wpahdr->resp_ie_len = 0;
- wpahdr->req_ie_len = 0;
- skb_put(pDevice->skb, sizeof(viawget_wpa_header));
- pDevice->skb->dev = pDevice->wpadev;
- skb_reset_mac_header(pDevice->skb);
- pDevice->skb->pkt_type = PACKET_HOST;
- pDevice->skb->protocol = htons(ETH_P_802_2);
- memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
- netif_rx(pDevice->skb);
- pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
- }
-
- #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
// if(pDevice->bWPASuppWextEnabled == TRUE)
{
union iwreq_data wrqu;
@@ -1736,7 +1673,6 @@ s_vMgrRxDeauthentication(
PRINT_K("wireless_send_event--->SIOCGIWAP(disauthen)\n");
wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
}
- #endif
}
/* else, ignore it. TODO: IBSS authentication service
@@ -2645,10 +2581,8 @@ void vMgrJoinBSSBegin(void *hDeviceContext, PCMD_STATUS pStatus)
*/
}
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
//if(pDevice->bWPASuppWextEnabled == TRUE)
Encyption_Rebuild(pDevice, pCurr);
-#endif
// Infrastructure BSS
s_vMgrSynchBSS(pDevice,
diff --git a/drivers/staging/vt6656/wmgr.h b/drivers/staging/vt6656/wmgr.h
index 13dfb3bf832..52b1b562b14 100644
--- a/drivers/staging/vt6656/wmgr.h
+++ b/drivers/staging/vt6656/wmgr.h
@@ -89,44 +89,44 @@ typedef void (*TimerFunction)(unsigned long);
//+++ NDIS related
-typedef unsigned char NDIS_802_11_MAC_ADDRESS[ETH_ALEN];
+typedef u8 NDIS_802_11_MAC_ADDRESS[ETH_ALEN];
typedef struct _NDIS_802_11_AI_REQFI
{
- unsigned short Capabilities;
- unsigned short ListenInterval;
+ u16 Capabilities;
+ u16 ListenInterval;
NDIS_802_11_MAC_ADDRESS CurrentAPAddress;
} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI;
typedef struct _NDIS_802_11_AI_RESFI
{
- unsigned short Capabilities;
- unsigned short StatusCode;
- unsigned short AssociationId;
+ u16 Capabilities;
+ u16 StatusCode;
+ u16 AssociationId;
} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI;
typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION
{
- unsigned long Length;
- unsigned short AvailableRequestFixedIEs;
- NDIS_802_11_AI_REQFI RequestFixedIEs;
- unsigned long RequestIELength;
- unsigned long OffsetRequestIEs;
- unsigned short AvailableResponseFixedIEs;
- NDIS_802_11_AI_RESFI ResponseFixedIEs;
- unsigned long ResponseIELength;
- unsigned long OffsetResponseIEs;
+ u32 Length;
+ u16 AvailableRequestFixedIEs;
+ NDIS_802_11_AI_REQFI RequestFixedIEs;
+ u32 RequestIELength;
+ u32 OffsetRequestIEs;
+ u16 AvailableResponseFixedIEs;
+ NDIS_802_11_AI_RESFI ResponseFixedIEs;
+ u32 ResponseIELength;
+ u32 OffsetResponseIEs;
} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION;
typedef struct tagSAssocInfo {
- NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo;
- BYTE abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN];
- // store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION
- unsigned long RequestIELength;
- BYTE abyReqIEs[WLAN_BEACON_FR_MAXLEN];
+ NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo;
+ u8 abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN];
+ /* store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION */
+ u32 RequestIELength;
+ u8 abyReqIEs[WLAN_BEACON_FR_MAXLEN];
} SAssocInfo, *PSAssocInfo;
-//---
+
diff --git a/drivers/staging/vt6656/wpa2.c b/drivers/staging/vt6656/wpa2.c
index c0926976627..616e24dcf42 100644
--- a/drivers/staging/vt6656/wpa2.c
+++ b/drivers/staging/vt6656/wpa2.c
@@ -31,8 +31,8 @@
*
*/
-#include "wpa2.h"
#include "device.h"
+#include "wpa2.h"
/*--------------------- Static Definitions -------------------------*/
static int msglevel =MSG_LEVEL_INFO;
diff --git a/drivers/staging/vt6656/wpa2.h b/drivers/staging/vt6656/wpa2.h
index 46c295905b4..c359252a6b0 100644
--- a/drivers/staging/vt6656/wpa2.h
+++ b/drivers/staging/vt6656/wpa2.h
@@ -45,8 +45,8 @@ typedef struct tagsPMKIDInfo {
} PMKIDInfo, *PPMKIDInfo;
typedef struct tagSPMKIDCache {
- unsigned long BSSIDInfoCount;
- PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE];
+ u32 BSSIDInfoCount;
+ PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE];
} SPMKIDCache, *PSPMKIDCache;
diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c
index 3e65aa13201..cc1d48bced2 100644
--- a/drivers/staging/vt6656/wpactl.c
+++ b/drivers/staging/vt6656/wpactl.c
@@ -44,13 +44,6 @@
/*--------------------- Static Definitions -------------------------*/
-#define VIAWGET_WPA_MAX_BUF_SIZE 1024
-
-static const int frequency_list[] = {
- 2412, 2417, 2422, 2427, 2432, 2437, 2442,
- 2447, 2452, 2457, 2462, 2467, 2472, 2484
-};
-
/*--------------------- Static Classes ----------------------------*/
/*--------------------- Static Variables --------------------------*/
@@ -59,118 +52,7 @@ static int msglevel = MSG_LEVEL_INFO;
/*--------------------- Static Functions --------------------------*/
/*--------------------- Export Variables --------------------------*/
-static void wpadev_setup(struct net_device *dev)
-{
- dev->type = ARPHRD_IEEE80211;
- dev->hard_header_len = ETH_HLEN;
- dev->mtu = 2048;
- dev->addr_len = ETH_ALEN;
- dev->tx_queue_len = 1000;
- memset(dev->broadcast, 0xFF, ETH_ALEN);
-
- dev->flags = IFF_BROADCAST | IFF_MULTICAST;
-}
-
-/*
- * Description:
- * register netdev for wpa supplicant daemon
- *
- * Parameters:
- * In:
- * pDevice -
- * enable -
- * Out:
- *
- * Return Value:
- *
- */
-static int wpa_init_wpadev(PSDevice pDevice)
-{
- PSDevice wpadev_priv;
- struct net_device *dev = pDevice->dev;
- int ret = 0;
-
- pDevice->wpadev = alloc_netdev(sizeof(PSDevice), "vntwpa", wpadev_setup);
- if (pDevice->wpadev == NULL)
- return -ENOMEM;
-
- wpadev_priv = netdev_priv(pDevice->wpadev);
- *wpadev_priv = *pDevice;
- memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, ETH_ALEN);
- pDevice->wpadev->base_addr = dev->base_addr;
- pDevice->wpadev->irq = dev->irq;
- pDevice->wpadev->mem_start = dev->mem_start;
- pDevice->wpadev->mem_end = dev->mem_end;
- ret = register_netdev(pDevice->wpadev);
- if (ret) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdev(WPA) failed!\n",
- dev->name);
- free_netdev(pDevice->wpadev);
- return -1;
- }
-
- if (pDevice->skb == NULL) {
- pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
- if (pDevice->skb == NULL)
- return -ENOMEM;
- }
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdev %s for WPA management\n",
- dev->name, pDevice->wpadev->name);
-
- return 0;
-}
-
-/*
- * Description:
- * unregister net_device (wpadev)
- *
- * Parameters:
- * In:
- * pDevice -
- * Out:
- *
- * Return Value:
- *
- */
-static int wpa_release_wpadev(PSDevice pDevice)
-{
- if (pDevice->skb) {
- dev_kfree_skb(pDevice->skb);
- pDevice->skb = NULL;
- }
-
- if (pDevice->wpadev) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
- pDevice->dev->name, pDevice->wpadev->name);
- unregister_netdev(pDevice->wpadev);
- free_netdev(pDevice->wpadev);
- pDevice->wpadev = NULL;
- }
-
- return 0;
-}
-
-/*
- * Description:
- * Set enable/disable dev for wpa supplicant daemon
- *
- * Parameters:
- * In:
- * pDevice -
- * val -
- * Out:
- *
- * Return Value:
- *
- */
-int wpa_set_wpadev(PSDevice pDevice, int val)
-{
- if (val)
- return wpa_init_wpadev(pDevice);
- return wpa_release_wpadev(pDevice);
-}
/*
* Description:
@@ -185,7 +67,7 @@ int wpa_set_wpadev(PSDevice pDevice, int val)
* Return Value:
*
*/
- int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL fcpfkernel)
+int wpa_set_keys(PSDevice pDevice, void *ctx)
{
struct viawget_wpa_param *param = ctx;
PSMgmtObject pMgmt = &pDevice->sMgmtObj;
@@ -217,18 +99,7 @@ int wpa_set_wpadev(PSDevice pDevice, int val)
if (param->u.wpa_key.key && param->u.wpa_key.key_len > sizeof(abyKey))
return -EINVAL;
- spin_unlock_irq(&pDevice->lock);
- if (param->u.wpa_key.key && fcpfkernel) {
- memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len);
- } else {
- if (param->u.wpa_key.key &&
- copy_from_user(&abyKey[0], param->u.wpa_key.key,
- param->u.wpa_key.key_len)) {
- spin_lock_irq(&pDevice->lock);
- return -EINVAL;
- }
- }
- spin_lock_irq(&pDevice->lock);
+ memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len);
dwKeyIndex = (DWORD)(param->u.wpa_key.key_index);
@@ -260,18 +131,7 @@ int wpa_set_wpadev(PSDevice pDevice, int val)
if (param->u.wpa_key.seq && param->u.wpa_key.seq_len > sizeof(abySeq))
return -EINVAL;
- spin_unlock_irq(&pDevice->lock);
- if (param->u.wpa_key.seq && fcpfkernel) {
- memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len);
- } else {
- if (param->u.wpa_key.seq &&
- copy_from_user(&abySeq[0], param->u.wpa_key.seq,
- param->u.wpa_key.seq_len)) {
- spin_lock_irq(&pDevice->lock);
- return -EINVAL;
- }
- }
- spin_lock_irq(&pDevice->lock);
+ memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len);
if (param->u.wpa_key.seq_len > 0) {
for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) {
@@ -399,521 +259,3 @@ int wpa_set_wpadev(PSDevice pDevice, int val)
}
-/*
- * Description:
- * enable wpa auth & mode
- *
- * Parameters:
- * In:
- * pDevice -
- * param -
- * Out:
- *
- * Return Value:
- *
- */
-static int wpa_set_wpa(PSDevice pDevice, struct viawget_wpa_param *param)
-{
- PSMgmtObject pMgmt = &pDevice->sMgmtObj;
- int ret = 0;
-
- pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
- pMgmt->bShareKeyAlgorithm = FALSE;
-
- return ret;
-}
-
- /*
- * Description:
- * set disassociate
- *
- * Parameters:
- * In:
- * pDevice -
- * param -
- * Out:
- *
- * Return Value:
- *
- */
-static int wpa_set_disassociate(PSDevice pDevice, struct viawget_wpa_param *param)
-{
- PSMgmtObject pMgmt = &pDevice->sMgmtObj;
- int ret = 0;
-
- spin_lock_irq(&pDevice->lock);
- if (pDevice->bLinkPass) {
- if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6))
- bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
- }
- spin_unlock_irq(&pDevice->lock);
-
- return ret;
-}
-
-/*
- * Description:
- * enable scan process
- *
- * Parameters:
- * In:
- * pDevice -
- * param -
- * Out:
- *
- * Return Value:
- *
- */
-static int wpa_set_scan(PSDevice pDevice, struct viawget_wpa_param *param)
-{
- int ret = 0;
-
-/**set ap_scan=1&&scan_ssid=1 under hidden ssid mode**/
- PSMgmtObject pMgmt = &pDevice->sMgmtObj;
- PWLAN_IE_SSID pItemSSID;
- printk("wpa_set_scan-->desired [ssid=%s,ssid_len=%d]\n",
- param->u.scan_req.ssid,param->u.scan_req.ssid_len);
-// Set the SSID
- memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
- pItemSSID->byElementID = WLAN_EID_SSID;
- memcpy(pItemSSID->abySSID, param->u.scan_req.ssid, param->u.scan_req.ssid_len);
- pItemSSID->len = param->u.scan_req.ssid_len;
-
- spin_lock_irq(&pDevice->lock);
- BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass);
- bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN,
- pMgmt->abyDesireSSID);
- spin_unlock_irq(&pDevice->lock);
-
- return ret;
-}
-
-/*
- * Description:
- * get bssid
- *
- * Parameters:
- * In:
- * pDevice -
- * param -
- * Out:
- *
- * Return Value:
- *
- */
-static int wpa_get_bssid(PSDevice pDevice, struct viawget_wpa_param *param)
-{
- PSMgmtObject pMgmt = &pDevice->sMgmtObj;
- int ret = 0;
- memcpy(param->u.wpa_associate.bssid, pMgmt->abyCurrBSSID, 6);
-
- return ret;
-}
-
-/*
- * Description:
- * get bssid
- *
- * Parameters:
- * In:
- * pDevice -
- * param -
- * Out:
- *
- * Return Value:
- *
- */
-static int wpa_get_ssid(PSDevice pDevice, struct viawget_wpa_param *param)
-{
- PSMgmtObject pMgmt = &pDevice->sMgmtObj;
- PWLAN_IE_SSID pItemSSID;
- int ret = 0;
-
- pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
-
- memcpy(param->u.wpa_associate.ssid, pItemSSID->abySSID, pItemSSID->len);
- param->u.wpa_associate.ssid_len = pItemSSID->len;
-
- return ret;
-}
-
-/*
- * Description:
- * get scan results
- *
- * Parameters:
- * In:
- * pDevice -
- * param -
- * Out:
- *
- * Return Value:
- *
- */
-static int wpa_get_scan(PSDevice pDevice, struct viawget_wpa_param *param)
-{
- struct viawget_scan_result *scan_buf;
- PSMgmtObject pMgmt = &pDevice->sMgmtObj;
- PWLAN_IE_SSID pItemSSID;
- PKnownBSS pBSS;
- PBYTE pBuf;
- int ret = 0;
- u16 count = 0;
- u16 ii;
- u16 jj;
- long ldBm; //James //add
-
-//******mike:bubble sort by stronger RSSI*****//
- PBYTE ptempBSS;
-
- ptempBSS = kmalloc(sizeof(KnownBSS), GFP_ATOMIC);
-
- if (ptempBSS == NULL) {
- printk("bubble sort kmalloc memory fail@@@\n");
- ret = -ENOMEM;
- return ret;
- }
-
- for (ii = 0; ii < MAX_BSS_NUM; ii++) {
- for (jj = 0; jj < MAX_BSS_NUM - ii - 1; jj++) {
- if ((pMgmt->sBSSList[jj].bActive != TRUE)
- || ((pMgmt->sBSSList[jj].uRSSI > pMgmt->sBSSList[jj + 1].uRSSI)
- && (pMgmt->sBSSList[jj + 1].bActive != FALSE))) {
- memcpy(ptempBSS,&pMgmt->sBSSList[jj], sizeof(KnownBSS));
- memcpy(&pMgmt->sBSSList[jj], &pMgmt->sBSSList[jj + 1],
- sizeof(KnownBSS));
- memcpy(&pMgmt->sBSSList[jj + 1], ptempBSS, sizeof(KnownBSS));
- }
- }
- }
- kfree(ptempBSS);
-
- count = 0;
- pBSS = &(pMgmt->sBSSList[0]);
- for (ii = 0; ii < MAX_BSS_NUM; ii++) {
- pBSS = &(pMgmt->sBSSList[ii]);
- if (!pBSS->bActive)
- continue;
- count++;
- }
-
- pBuf = kcalloc(count, sizeof(struct viawget_scan_result), GFP_ATOMIC);
-
- if (pBuf == NULL) {
- ret = -ENOMEM;
- return ret;
- }
- scan_buf = (struct viawget_scan_result *)pBuf;
- pBSS = &(pMgmt->sBSSList[0]);
- for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) {
- pBSS = &(pMgmt->sBSSList[ii]);
- if (pBSS->bActive) {
- if (jj >= count)
- break;
- memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN);
- pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
- memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len);
- scan_buf->ssid_len = pItemSSID->len;
- scan_buf->freq = frequency_list[pBSS->uChannel-1];
- scan_buf->caps = pBSS->wCapInfo; // DavidWang for sharemode
-
- RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
- if (-ldBm < 50)
- scan_buf->qual = 100;
- else if (-ldBm > 90)
- scan_buf->qual = 0;
- else
- scan_buf->qual=(40-(-ldBm-50))*100/40;
-
- //James
- //scan_buf->caps = pBSS->wCapInfo;
- //scan_buf->qual =
- scan_buf->noise = 0;
- scan_buf->level = ldBm;
-
- //scan_buf->maxrate =
- if (pBSS->wWPALen != 0) {
- scan_buf->wpa_ie_len = pBSS->wWPALen;
- memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen);
- }
- if (pBSS->wRSNLen != 0) {
- scan_buf->rsn_ie_len = pBSS->wRSNLen;
- memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen);
- }
- scan_buf = (struct viawget_scan_result *)((PBYTE)scan_buf + sizeof(struct viawget_scan_result));
- jj ++;
- }
- }
-
- if (jj < count)
- count = jj;
-
- if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count))
- ret = -EFAULT;
-
- param->u.scan_results.scan_count = count;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count);
-
- kfree(pBuf);
- return ret;
-}
-
-/*
- * Description:
- * set associate with AP
- *
- * Parameters:
- * In:
- * pDevice -
- * param -
- * Out:
- *
- * Return Value:
- *
- */
-static int wpa_set_associate(PSDevice pDevice, struct viawget_wpa_param *param)
-{
- PSMgmtObject pMgmt = &pDevice->sMgmtObj;
- PWLAN_IE_SSID pItemSSID;
- BYTE abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- BYTE abyWPAIE[64];
- int ret = 0;
- BOOL bwepEnabled=FALSE;
-
- // set key type & algorithm
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group_suite = %d\n", param->u.wpa_associate.group_suite);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key_mgmt_suite = %d\n", param->u.wpa_associate.key_mgmt_suite);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "auth_alg = %d\n", param->u.wpa_associate.auth_alg);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "mode = %d\n", param->u.wpa_associate.mode);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming dBm = %d\n", param->u.wpa_associate.roam_dbm); // Davidwang
-
- if (param->u.wpa_associate.wpa_ie) {
- if (param->u.wpa_associate.wpa_ie_len > sizeof(abyWPAIE))
- return -EINVAL;
-
- if (copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie,
- param->u.wpa_associate.wpa_ie_len))
- return -EFAULT;
- }
-
- if (param->u.wpa_associate.mode == 1)
- pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
- else
- pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
-
- // set bssid
- if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0)
- memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6);
- // set ssid
- memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
- pItemSSID->byElementID = WLAN_EID_SSID;
- pItemSSID->len = param->u.wpa_associate.ssid_len;
- memcpy(pItemSSID->abySSID, param->u.wpa_associate.ssid, pItemSSID->len);
-
- if (param->u.wpa_associate.wpa_ie_len == 0) {
- if (param->u.wpa_associate.auth_alg & AUTH_ALG_SHARED_KEY)
- pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY;
- else
- pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
- } else if (abyWPAIE[0] == RSN_INFO_ELEM) {
- if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK)
- pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
- else
- pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
- } else {
- if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_WPA_NONE)
- pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
- else if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK)
- pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
- else
- pMgmt->eAuthenMode = WMAC_AUTH_WPA;
- }
-
- switch (param->u.wpa_associate.pairwise_suite) {
- case CIPHER_CCMP:
- pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
- break;
- case CIPHER_TKIP:
- pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
- break;
- case CIPHER_WEP40:
- case CIPHER_WEP104:
- pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
- bwepEnabled = TRUE;
- break;
- case CIPHER_NONE:
- if (param->u.wpa_associate.group_suite == CIPHER_CCMP)
- pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
- else
- pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
- break;
- default:
- pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
- }
-
- pMgmt->Roam_dbm = param->u.wpa_associate.roam_dbm;
- if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) { // @wep-sharekey
- pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
- pMgmt->bShareKeyAlgorithm = TRUE;
- } else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) {
- if(bwepEnabled==TRUE) { //@open-wep
- pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
- } else {
- // @only open
- pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
- }
- }
- // mike save old encryption status
- pDevice->eOldEncryptionStatus = pDevice->eEncryptionStatus;
-
- if (pDevice->eEncryptionStatus != Ndis802_11EncryptionDisabled)
- pDevice->bEncryptionEnable = TRUE;
- else
- pDevice->bEncryptionEnable = FALSE;
-
- if ((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) ||
- ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bwepEnabled==TRUE))) {
- // mike re-comment:open-wep && sharekey-wep needn't do initial key!!
- } else {
- KeyvInitTable(pDevice,&pDevice->sKey);
- }
-
- spin_lock_irq(&pDevice->lock);
- pDevice->bLinkPass = FALSE;
- ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_SLOW);
- memset(pMgmt->abyCurrBSSID, 0, 6);
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- netif_stop_queue(pDevice->dev);
-
-/******* search if ap_scan=2, which is associating request in hidden ssid mode ****/
- {
- PKnownBSS pCurr = NULL;
- pCurr = BSSpSearchBSSList(pDevice,
- pMgmt->abyDesireBSSID,
- pMgmt->abyDesireSSID,
- pDevice->eConfigPHYMode
- );
-
- if (pCurr == NULL){
- printk("wpa_set_associate---->hidden mode site survey before associate.......\n");
- bScheduleCommand((void *)pDevice,
- WLAN_CMD_BSSID_SCAN,
- pMgmt->abyDesireSSID);
- }
- }
-/****************************************************************/
-
- bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
- spin_unlock_irq(&pDevice->lock);
-
- return ret;
-}
-
-/*
- * Description:
- * wpa_ioctl main function supported for wpa supplicant
- *
- * Parameters:
- * In:
- * pDevice -
- * iw_point -
- * Out:
- *
- * Return Value:
- *
- */
-int wpa_ioctl(PSDevice pDevice, struct iw_point *p)
-{
- struct viawget_wpa_param *param;
- int ret = 0;
- int wpa_ioctl = 0;
-
- if (p->length < sizeof(struct viawget_wpa_param) ||
- p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer)
- return -EINVAL;
-
- param = kmalloc((int)p->length, GFP_KERNEL);
- if (param == NULL)
- return -ENOMEM;
-
- if (copy_from_user(param, p->pointer, p->length)) {
- ret = -EFAULT;
- goto out;
- }
-
- switch (param->cmd) {
- case VIAWGET_SET_WPA:
- ret = wpa_set_wpa(pDevice, param);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n");
- break;
-
- case VIAWGET_SET_KEY:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n");
- spin_lock_irq(&pDevice->lock);
- ret = wpa_set_keys(pDevice, param, FALSE);
- spin_unlock_irq(&pDevice->lock);
- break;
-
- case VIAWGET_SET_SCAN:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n");
- ret = wpa_set_scan(pDevice, param);
- break;
-
- case VIAWGET_GET_SCAN:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n");
- ret = wpa_get_scan(pDevice, param);
- wpa_ioctl = 1;
- break;
-
- case VIAWGET_GET_SSID:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n");
- ret = wpa_get_ssid(pDevice, param);
- wpa_ioctl = 1;
- break;
-
- case VIAWGET_GET_BSSID:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n");
- ret = wpa_get_bssid(pDevice, param);
- wpa_ioctl = 1;
- break;
-
- case VIAWGET_SET_ASSOCIATE:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n");
- ret = wpa_set_associate(pDevice, param);
- break;
-
- case VIAWGET_SET_DISASSOCIATE:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n");
- ret = wpa_set_disassociate(pDevice, param);
- break;
-
- case VIAWGET_SET_DROP_UNENCRYPT:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n");
- break;
-
- case VIAWGET_SET_DEAUTHENTICATE:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n");
- break;
-
- default:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n",
- param->cmd);
- kfree(param);
- return -EOPNOTSUPP;
- }
-
- if ((ret == 0) && wpa_ioctl) {
- if (copy_to_user(p->pointer, param, p->length)) {
- ret = -EFAULT;
- goto out;
- }
- }
-
-out:
- kfree(param);
- return ret;
-}
diff --git a/drivers/staging/vt6656/wpactl.h b/drivers/staging/vt6656/wpactl.h
index 00c8451ab50..b4ec6b0e1c6 100644
--- a/drivers/staging/vt6656/wpactl.h
+++ b/drivers/staging/vt6656/wpactl.h
@@ -30,9 +30,7 @@
#define __WPACTL_H__
#include "device.h"
-#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
#include "iowpa.h"
-#endif
/*--------------------- Export Definitions -------------------------*/
@@ -40,17 +38,11 @@
//WPA related
typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg;
-typedef enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP,
- CIPHER_WEP104 } wpa_cipher;
-typedef enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
- KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE, KEY_MGMT_CCKM } wpa_key_mgmt;//20080717-02,<Modify> by James Li
#define AUTH_ALG_OPEN_SYSTEM 0x01
#define AUTH_ALG_SHARED_KEY 0x02
#define AUTH_ALG_LEAP 0x04
-#define GENERIC_INFO_ELEM 0xdd
-#define RSN_INFO_ELEM 0x30
typedef unsigned long long NDIS_802_11_KEY_RSC;
@@ -60,8 +52,6 @@ typedef unsigned long long NDIS_802_11_KEY_RSC;
/*--------------------- Export Functions --------------------------*/
-int wpa_set_wpadev(PSDevice pDevice, int val);
-int wpa_ioctl(PSDevice pDevice, struct iw_point *p);
-int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL fcpfkernel);
+int wpa_set_keys(PSDevice pDevice, void *ctx);
#endif /* __WPACL_H__ */
diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c
index 1b8b8ace39e..faa93f0ee10 100644
--- a/drivers/staging/winbond/mds.c
+++ b/drivers/staging/winbond/mds.c
@@ -315,7 +315,7 @@ static void Mds_HeaderCopy(struct wbsoft_priv *adapter, struct wb35_descriptor *
pT00->T00_tx_packet_id = pDes->Descriptor_ID; /* Set packet ID */
pT00->T00_header_length = 24; /* Set header length */
- pT01->T01_retry_abort_ebable = 1; /* 921013 931130.5.h */
+ pT01->T01_retry_abort_enable = 1; /* 921013 931130.5.h */
/* Key ID setup */
pT01->T01_wep_id = 0;
@@ -476,11 +476,8 @@ Mds_Tx(struct wbsoft_priv *adapter)
/* 931130.5.b */
FragmentCount = PacketSize/FragmentThreshold + 1;
stmp = PacketSize + FragmentCount*32 + 8; /* 931130.5.c 8:MIC */
- if ((XmitBufSize + stmp) >= MAX_USB_TX_BUFFER) {
- printk("[Mds_Tx] Excess max tx buffer.\n");
+ if ((XmitBufSize + stmp) >= MAX_USB_TX_BUFFER)
break; /* buffer is not enough */
- }
-
/*
* Start transmitting
diff --git a/drivers/staging/winbond/wb35rx_f.h b/drivers/staging/winbond/wb35rx_f.h
index 1fdf65ea604..559bdca12e1 100644
--- a/drivers/staging/winbond/wb35rx_f.h
+++ b/drivers/staging/winbond/wb35rx_f.h
@@ -4,12 +4,12 @@
#include <net/mac80211.h>
#include "wbhal.h"
-//====================================
-// Interface function declare
-//====================================
-unsigned char Wb35Rx_initial( struct hw_data * pHwData );
-void Wb35Rx_destroy( struct hw_data * pHwData );
-void Wb35Rx_stop( struct hw_data * pHwData );
+/*
+ * Interface function declaration
+ */
+unsigned char Wb35Rx_initial(struct hw_data *pHwData);
+void Wb35Rx_destroy(struct hw_data *pHwData);
+void Wb35Rx_stop(struct hw_data *pHwData);
void Wb35Rx_start(struct ieee80211_hw *hw);
#endif
diff --git a/drivers/staging/winbond/wb35rx_s.h b/drivers/staging/winbond/wb35rx_s.h
index 4b03274a7d2..545bc950072 100644
--- a/drivers/staging/winbond/wb35rx_s.h
+++ b/drivers/staging/winbond/wb35rx_s.h
@@ -1,44 +1,44 @@
-//============================================================================
-// wb35rx.h --
-//============================================================================
+#ifndef __WINBOND_35RX_S_H
+#define __WINBOND_35RX_S_H
-// Definition for this module used
-#define MAX_USB_RX_BUFFER 4096 // This parameter must be 4096 931130.4.f
+/* Definition for this module used */
+#define MAX_USB_RX_BUFFER 4096 /* This parameter must be 4096 931130.4.f */
+#define MAX_USB_RX_BUFFER_NUMBER ETHERNET_RX_DESCRIPTORS /* Maximum 254, 255 is RESERVED ID */
+#define RX_INTERFACE 0 /* Interface 1 */
+#define RX_PIPE 2 /* Pipe 3 */
+#define MAX_PACKET_SIZE 1600 /* 1568 = 8 + 1532 + 4 + 24(IV EIV MIC ICV CRC) for check DMA data 931130.4.g */
+#define RX_END_TAG 0x0badbeef
-#define MAX_USB_RX_BUFFER_NUMBER ETHERNET_RX_DESCRIPTORS // Maximum 254, 255 is RESERVED ID
-#define RX_INTERFACE 0 // Interface 1
-#define RX_PIPE 2 // Pipe 3
-#define MAX_PACKET_SIZE 1600 //1568 // 8 + 1532 + 4 + 24(IV EIV MIC ICV CRC) for check DMA data 931130.4.g
-#define RX_END_TAG 0x0badbeef
-
-//====================================
-// Internal variable for module
-//====================================
+/*
+ * Internal variable for module
+ */
struct wb35_rx {
- u32 ByteReceived;// For calculating throughput of BulkIn
- atomic_t RxFireCounter;// Does Wb35Rx module fire?
+ u32 ByteReceived; /* For calculating throughput of BulkIn */
+ atomic_t RxFireCounter;/* Does Wb35Rx module fire? */
- u8 RxBuffer[ MAX_USB_RX_BUFFER_NUMBER ][ ((MAX_USB_RX_BUFFER+3) & ~0x03 ) ];
- u16 RxBufferSize[ ((MAX_USB_RX_BUFFER_NUMBER+1) & ~0x01) ];
- u8 RxOwner[ ((MAX_USB_RX_BUFFER_NUMBER+3) & ~0x03 ) ];//Ownership of buffer 0: SW 1:HW
+ u8 RxBuffer[MAX_USB_RX_BUFFER_NUMBER][((MAX_USB_RX_BUFFER+3) & ~0x03)];
+ u16 RxBufferSize[((MAX_USB_RX_BUFFER_NUMBER+1) & ~0x01)];
+ u8 RxOwner[((MAX_USB_RX_BUFFER_NUMBER+3) & ~0x03)]; /* Ownership of buffer 0:SW 1:HW */
- u32 RxProcessIndex;//The next index to process
- u32 RxBufferId;
- u32 EP3vm_state;
+ u32 RxProcessIndex; /* The next index to process */
+ u32 RxBufferId;
+ u32 EP3vm_state;
- u32 rx_halt; // For VM stopping
+ u32 rx_halt; /* For VM stopping */
- u16 MoreDataSize;
- u16 PacketSize;
+ u16 MoreDataSize;
+ u16 PacketSize;
- u32 CurrentRxBufferId; // For complete routine usage
- u32 Rx3UrbCancel;
+ u32 CurrentRxBufferId; /* For complete routine usage */
+ u32 Rx3UrbCancel;
- u32 LastR1; // For RSSI reporting
- struct urb * RxUrb;
- u32 Ep3ErrorCount2; // 20060625.1 Usbd for Rx DMA error count
+ u32 LastR1; /* For RSSI reporting */
+ struct urb *RxUrb;
+ u32 Ep3ErrorCount2; /* 20060625.1 Usbd for Rx DMA error count */
int EP3VM_status;
- u8 * pDRx;
+ u8 *pDRx;
};
+
+#endif /* __WINBOND_35RX_S_H */
diff --git a/drivers/staging/winbond/wbhal.h b/drivers/staging/winbond/wbhal.h
index 39e84a0d972..289ee549146 100644
--- a/drivers/staging/winbond/wbhal.h
+++ b/drivers/staging/winbond/wbhal.h
@@ -226,11 +226,11 @@ struct T01_descriptor {
u32 T01_add_challenge_text:1;
u32 T01_inhibit_crc:1;
u32 T01_loop_back_wep_mode:1;
- u32 T01_retry_abort_ebable:1;
+ u32 T01_retry_abort_enable:1;
};
#else
struct {
- u32 T01_retry_abort_ebable:1;
+ u32 T01_retry_abort_enable:1;
u32 T01_loop_back_wep_mode:1;
u32 T01_inhibit_crc:1;
u32 T01_add_challenge_text:1;
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c
index 48aa1361903..3fa1ae4d3d7 100644
--- a/drivers/staging/winbond/wbusb.c
+++ b/drivers/staging/winbond/wbusb.c
@@ -79,18 +79,15 @@ static int wbsoft_add_interface(struct ieee80211_hw *dev,
static void wbsoft_remove_interface(struct ieee80211_hw *dev,
struct ieee80211_vif *vif)
{
- printk("wbsoft_remove interface called\n");
}
static void wbsoft_stop(struct ieee80211_hw *hw)
{
- printk(KERN_INFO "%s called\n", __func__);
}
static int wbsoft_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats)
{
- printk(KERN_INFO "%s called\n", __func__);
return 0;
}
@@ -179,12 +176,9 @@ static void hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info
if (pHwData->SurpriseRemove)
return;
- printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo);
-
RFSynthesizer_SwitchingChannel(pHwData, channel); /* Switch channel */
pHwData->Channel = channel.ChanNo;
pHwData->band = channel.band;
- pr_debug("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band);
reg->M28_MacControl &= ~0xff; /* Clean channel information field */
reg->M28_MacControl |= channel.ChanNo;
Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl,
@@ -264,8 +258,6 @@ static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
struct wbsoft_priv *priv = dev->priv;
struct chan_info ch;
- printk("wbsoft_config called\n");
-
/* Should use channel_num, or something, as that is already pre-translated */
ch.band = 1;
ch.ChanNo = 1;
@@ -282,7 +274,6 @@ static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
static u64 wbsoft_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif)
{
- printk("wbsoft_get_tsf called\n");
return 0;
}
@@ -716,7 +707,6 @@ static int wb35_hw_init(struct ieee80211_hw *hw)
}
priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData);
- pr_debug("Driver init, antenna no = %d\n", priv->sLocalPara.bAntennaNo);
hal_get_hw_radio_off(pHwData);
/* Waiting for HAL setting OK */
@@ -782,9 +772,6 @@ static int wb35_probe(struct usb_interface *intf,
interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc;
- if (endpoint[2].wMaxPacketSize == 512)
- printk("[w35und] Working on USB 2.0\n");
-
err = wb35_hw_init(dev);
if (err)
goto error_free_hw;
@@ -836,7 +823,6 @@ static void wb35_hw_halt(struct wbsoft_priv *adapter)
{
/* Turn off Rx and Tx hardware ability */
hal_stop(&adapter->sHwData);
- pr_debug("[w35und] Hal_stop O.K.\n");
/* Waiting Irp completed */
msleep(100);
diff --git a/drivers/staging/wlags49_h2/ap_h2.c b/drivers/staging/wlags49_h2/ap_h2.c
index eb8244c4d6f..e524153e925 100644
--- a/drivers/staging/wlags49_h2/ap_h2.c
+++ b/drivers/staging/wlags49_h2/ap_h2.c
@@ -25,10 +25,10 @@
*/
-#include "hcfcfg.h" /* to get hcf_16 etc defined as well as */
+#include "hcfcfg.h" /* to get hcf_16 etc defined as well as */
/* possible settings which inluence mdd.h or dhf.h */
-#include "mdd.h" /* to get COMP_ID_STA etc defined */
-#include "dhf.h" /* used to be "fhfmem.h", to get memblock,plugrecord, */
+#include "mdd.h" /* to get COMP_ID_STA etc defined */
+#include "dhf.h" /* used to be "fhfmem.h", to get memblock,plugrecord, */
static const hcf_8 fw_image_1_data[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -3301,7 +3301,7 @@ static const CFG_RANGE20_STRCT fw_image_infocompat[] = {
COMP_ROLE_SUPL,
COMP_ID_APF,
{
- { 2, 2, 4 } /* variant, bottom, top */
+ { 2, 2, 4 } /* variant, bottom, top */
}
},
{ 3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)),
@@ -3309,9 +3309,9 @@ static const CFG_RANGE20_STRCT fw_image_infocompat[] = {
COMP_ROLE_ACT,
COMP_ID_MFI,
{
- { 4, 6, 7 }, /* variant, bottom, top */
- { 5, 6, 7 }, /* variant, bottom, top */
- { 6, 6, 7 } /* variant, bottom, top */
+ { 4, 6, 7 }, /* variant, bottom, top */
+ { 5, 6, 7 }, /* variant, bottom, top */
+ { 6, 6, 7 } /* variant, bottom, top */
}
},
{ 3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)),
@@ -3319,7 +3319,7 @@ static const CFG_RANGE20_STRCT fw_image_infocompat[] = {
COMP_ROLE_ACT,
COMP_ID_CFI,
{
- { 2, 1, 2 } /* variant, bottom, top */
+ { 2, 1, 2 } /* variant, bottom, top */
}
},
{ 0000, 0000, 0000, 0000, { { 0000, 0000, 0000 } } } /* endsentinel */
diff --git a/drivers/staging/wlags49_h2/man/wlags49.4 b/drivers/staging/wlags49_h2/man/wlags49.4
index a3458853074..37df9987918 100644
--- a/drivers/staging/wlags49_h2/man/wlags49.4
+++ b/drivers/staging/wlags49_h2/man/wlags49.4
@@ -108,7 +108,7 @@ with the I/O base address and MAC address used by the card.
\- Card power management
\- Support for Hermes-II & Hermes-II.5 based PCMCIA, Mini PCI, and CardBus cards
\- Wired Equivalent Privacy (WEP)
- \- WPA-PSK support (EXPERIMENTAL)
+ \- WPA-PSK support
\- Driver utility interface (UIL)
\- Wireless Extensions
\- Software AP mode
diff --git a/drivers/staging/wlags49_h2/wl_if.h b/drivers/staging/wlags49_h2/wl_if.h
index 6d66dabf032..425d3733b36 100644
--- a/drivers/staging/wlags49_h2/wl_if.h
+++ b/drivers/staging/wlags49_h2/wl_if.h
@@ -71,45 +71,39 @@
#define MAX_LTV_BUF_SIZE (512 - (sizeof(hcf_16) * 2))
#define HCF_TALLIES_SIZE (sizeof(CFG_HERMES_TALLIES_STRCT) + \
- (sizeof(hcf_16) * 2))
+ (sizeof(hcf_16) * 2))
#define HCF_MAX_MULTICAST 16
#define HCF_MAX_NAME_LEN 32
-#define MAX_LINE_SIZE 256
+#define MAX_LINE_SIZE 256
#define HCF_NUM_IO_PORTS 0x80
#define TX_TIMEOUT ((800 * HZ) / 1000)
-//#define HCF_MIN_COMM_QUALITY 0
-//#define HCF_MAX_COMM_QUALITY 92
-//#define HCF_MIN_SIGNAL_LEVEL 47
-//#define HCF_MAX_SIGNAL_LEVEL 138
-//#define HCF_MIN_NOISE_LEVEL 47
-//#define HCF_MAX_NOISE_LEVEL 138
-//#define HCF_0DBM_OFFSET 149
-
-// PE1DNN
-// Better data from the real world. Not scientific but empirical data gathered
-// from a Thomson Speedtouch 110 which is identified as:
-// PCMCIA Info: "Agere Systems" "Wireless PC Card Model 0110"
-// Manufacture ID: 0156,0003
-// Lowest measurment for noise floor seen is value 54
-// Highest signal strength in close proximity to the AP seen is value 118
-// Very good must be around 100 (otherwise its never "full scale"
-// All other constants are derrived from these. This makes the signal gauge
-// work for me...
+/* PE1DNN
+ * Better data from the real world. Not scientific but empirical data gathered
+ * from a Thomson Speedtouch 110 which is identified as:
+ * PCMCIA Info: "Agere Systems" "Wireless PC Card Model 0110"
+ * Manufacture ID: 0156,0003
+ * Lowest measurment for noise floor seen is value 54
+ * Highest signal strength in close proximity to the AP seen is value 118
+ * Very good must be around 100 (otherwise its never "full scale"
+ * All other constants are derrived from these. This makes the signal gauge
+ * work for me...
+ */
#define HCF_MIN_SIGNAL_LEVEL 54
#define HCF_MAX_SIGNAL_LEVEL 100
#define HCF_MIN_NOISE_LEVEL HCF_MIN_SIGNAL_LEVEL
#define HCF_MAX_NOISE_LEVEL HCF_MAX_SIGNAL_LEVEL
#define HCF_0DBM_OFFSET (HCF_MAX_SIGNAL_LEVEL + 1)
#define HCF_MIN_COMM_QUALITY 0
-#define HCF_MAX_COMM_QUALITY (HCF_MAX_SIGNAL_LEVEL - HCF_MIN_NOISE_LEVEL + 1)
+#define HCF_MAX_COMM_QUALITY (HCF_MAX_SIGNAL_LEVEL - \
+ HCF_MIN_NOISE_LEVEL + 1)
/* For encryption (WEP) */
-#define MIN_KEY_SIZE 5 // 40 bits RC4 - WEP
-#define MAX_KEY_SIZE 13 // 104 bits
+#define MIN_KEY_SIZE 5 /* 40 bits RC4 - WEP */
+#define MAX_KEY_SIZE 13 /* 104 bits */
#define MAX_KEYS 4
#define RADIO_CHANNELS 14
@@ -121,12 +115,12 @@
#define MAX_RTS_BYTES 2347
#define MAX_RATES 8
-#define MEGABIT 1024*1024
+#define MEGABIT (1024 * 1024)
#define HCF_FAILURE 0xFF
#define UIL_FAILURE 0xFF
-#define CFG_UIL_CONNECT 0xA123 // Define differently?
-#define CFG_UIL_CONNECT_ACK_CODE 0x5653435A // VSCZ
+#define CFG_UIL_CONNECT 0xA123 /* Define differently? */
+#define CFG_UIL_CONNECT_ACK_CODE 0x5653435A /* VSCZ */
#define WVLAN2_UIL_CONNECTED (0x01L << 0)
#define WVLAN2_UIL_BUSY (0x01L << 1)
@@ -154,15 +148,15 @@ UIL_FUN_GET_INFO
UIL_FUN_PUT_INFO
*/
-#define SIOCSIWNETNAME SIOCDEVPRIVATE+1
-#define SIOCGIWNETNAME SIOCDEVPRIVATE+2
-#define SIOCSIWSTANAME SIOCDEVPRIVATE+3
-#define SIOCGIWSTANAME SIOCDEVPRIVATE+4
-#define SIOCSIWPORTTYPE SIOCDEVPRIVATE+5
-#define SIOCGIWPORTTYPE SIOCDEVPRIVATE+6
+#define SIOCSIWNETNAME (SIOCDEVPRIVATE + 1)
+#define SIOCGIWNETNAME (SIOCDEVPRIVATE + 2)
+#define SIOCSIWSTANAME (SIOCDEVPRIVATE + 3)
+#define SIOCGIWSTANAME (SIOCDEVPRIVATE + 4)
+#define SIOCSIWPORTTYPE (SIOCDEVPRIVATE + 5)
+#define SIOCGIWPORTTYPE (SIOCDEVPRIVATE + 6)
/* IOCTL code for the RTS interface */
-#define WL_IOCTL_RTS SIOCDEVPRIVATE+7
+#define WL_IOCTL_RTS (SIOCDEVPRIVATE + 7)
/* IOCTL subcodes for WL_IOCTL_RTS */
#define WL_IOCTL_RTS_READ 1
@@ -174,61 +168,54 @@ UIL_FUN_PUT_INFO
/*******************************************************************************
* STRUCTURE DEFINITIONS
******************************************************************************/
-typedef struct
-{
- __u16 length;
- __u8 name[HCF_MAX_NAME_LEN];
+typedef struct {
+ __u16 length;
+ __u8 name[HCF_MAX_NAME_LEN];
}
wvName_t;
-typedef struct
-{
- hcf_16 len;
- hcf_16 typ;
- union
- {
- hcf_8 u8[MAX_LTV_BUF_SIZE / sizeof(hcf_8)];
- hcf_16 u16[MAX_LTV_BUF_SIZE / sizeof(hcf_16)];
- hcf_32 u32[MAX_LTV_BUF_SIZE / sizeof(hcf_32)];
- } u;
+typedef struct {
+ hcf_16 len;
+ hcf_16 typ;
+ union {
+ hcf_8 u8[MAX_LTV_BUF_SIZE / sizeof(hcf_8)];
+ hcf_16 u16[MAX_LTV_BUF_SIZE / sizeof(hcf_16)];
+ hcf_32 u32[MAX_LTV_BUF_SIZE / sizeof(hcf_32)];
+ } u;
}
ltv_t;
-struct uilreq
-{
- union
- {
- char ifrn_name[IFNAMSIZ];
- } ifr_ifrn;
+struct uilreq {
+ union {
+ char ifrn_name[IFNAMSIZ];
+ } ifr_ifrn;
- IFBP hcfCtx;
- __u8 command;
- __u8 result;
+ IFBP hcfCtx;
+ __u8 command;
+ __u8 result;
- /* The data field in this structure is typically an LTV of some type. The
- len field is the size of the buffer in bytes, as opposed to words (like
- the L-field in the LTV */
- __u16 len;
- void *data;
+ /* The data field in this structure is typically an LTV of some type.
+ The len field is the size of the buffer in bytes, as opposed to words
+ (like the L-field in the LTV */
+ __u16 len;
+ void *data;
};
-struct rtsreq
-{
- union
- {
- char ifrn_name[IFNAMSIZ];
- }
- ifr_ifrn;
+struct rtsreq {
+ union {
+ char ifrn_name[IFNAMSIZ];
+ }
+ ifr_ifrn;
- __u16 typ;
- __u16 reg;
- __u16 len;
- __u16 *data;
+ __u16 typ;
+ __u16 reg;
+ __u16 len;
+ __u16 *data;
};
-#endif // __WAVELAN2_IF_H__
+#endif /* __WAVELAN2_IF_H__ */
diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c
index a09c3ac793a..6226e5eebf3 100644
--- a/drivers/staging/wlags49_h2/wl_pci.c
+++ b/drivers/staging/wlags49_h2/wl_pci.c
@@ -111,7 +111,7 @@ extern dbg_info_t *DbgInfo;
#endif // DBG
/* define the PCI device Table Cardname and id tables */
-static struct pci_device_id wl_pci_tbl[] __devinitdata = {
+static struct pci_device_id wl_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_0), },
{ PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_1), },
{ PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_2), },
@@ -124,9 +124,9 @@ MODULE_DEVICE_TABLE(pci, wl_pci_tbl);
/*******************************************************************************
* function prototypes
******************************************************************************/
-int __devinit wl_pci_probe( struct pci_dev *pdev,
+int wl_pci_probe( struct pci_dev *pdev,
const struct pci_device_id *ent );
-void __devexit wl_pci_remove(struct pci_dev *pdev);
+void wl_pci_remove(struct pci_dev *pdev);
int wl_pci_setup( struct pci_dev *pdev );
void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev );
@@ -160,14 +160,13 @@ void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp );
/*******************************************************************************
* PCI module function registration
******************************************************************************/
-static struct pci_driver wl_driver =
-{
- name: MODULE_NAME,
- id_table: wl_pci_tbl,
- probe: wl_pci_probe,
- remove: __devexit_p(wl_pci_remove),
- suspend: NULL,
- resume: NULL,
+static struct pci_driver wl_driver = {
+ .name = MODULE_NAME,
+ .id_table = wl_pci_tbl,
+ .probe = wl_pci_probe,
+ .remove = wl_pci_remove,
+ .suspend = NULL,
+ .resume = NULL
};
/*******************************************************************************
@@ -399,7 +398,7 @@ int wl_adapter_is_open( struct net_device *dev )
* errno value otherwise
*
******************************************************************************/
-int __devinit wl_pci_probe( struct pci_dev *pdev,
+int wl_pci_probe( struct pci_dev *pdev,
const struct pci_device_id *ent )
{
int result;
@@ -436,7 +435,7 @@ int __devinit wl_pci_probe( struct pci_dev *pdev,
* N/A
*
******************************************************************************/
-void __devexit wl_pci_remove(struct pci_dev *pdev)
+void wl_pci_remove(struct pci_dev *pdev)
{
struct net_device *dev = NULL;
/*------------------------------------------------------------------------*/
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
index f180c3d8b01..c1a8cb62515 100644
--- a/drivers/staging/wlan-ng/hfa384x_usb.c
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -171,11 +171,11 @@ static void hfa384x_ctlxout_callback(struct urb *urb);
static void hfa384x_usbin_callback(struct urb *urb);
static void
-hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t * usbin);
+hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb);
-static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t * usbin);
+static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
static void
hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout);
@@ -285,7 +285,7 @@ static inline const char *ctlxstr(CTLX_STATE s)
return ctlx_str[s];
};
-static inline hfa384x_usbctlx_t *get_active_ctlx(hfa384x_t * hw)
+static inline hfa384x_usbctlx_t *get_active_ctlx(hfa384x_t *hw)
{
return list_entry(hw->ctlxq.active.next, hfa384x_usbctlx_t, list);
}
diff --git a/drivers/staging/xgifb/TODO b/drivers/staging/xgifb/TODO
index 13d9bc25797..392b29d8f13 100644
--- a/drivers/staging/xgifb/TODO
+++ b/drivers/staging/xgifb/TODO
@@ -1,4 +1,4 @@
-This drivers still need a lot of work. I can list all cleanups to do but it's
+This drivers still needs a lot of work. I can list all cleanups to do but it's
going to be long. So, I'm writing "cleanups" and not the list.
Arnaud
diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c
index f775c545384..e0f745de7e7 100644
--- a/drivers/staging/xgifb/XGI_main_26.c
+++ b/drivers/staging/xgifb/XGI_main_26.c
@@ -73,9 +73,9 @@ static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
ModeIdIndex, XGI_Pr);
- ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ ClockIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
- Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
+ Clock = XGI_VCLKData[ClockIndex].CLOCK * 1000;
return Clock;
}
@@ -101,35 +101,35 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
return 0;
RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
ModeIdIndex, XGI_Pr);
- index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
- sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
+ sr_data = XGI_CRT1Table[index].CR[5];
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
+ cr_data = XGI_CRT1Table[index].CR[0];
/* Horizontal total */
HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
A = HT + 5;
- HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
+ HDE = (XGI330_RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
E = HDE + 1;
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
+ cr_data = XGI_CRT1Table[index].CR[3];
/* Horizontal retrace (=sync) start */
HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
F = HRS - E - 3;
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
+ cr_data = XGI_CRT1Table[index].CR[1];
/* Horizontal blank start */
HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
- sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
+ sr_data = XGI_CRT1Table[index].CR[6];
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
+ cr_data = XGI_CRT1Table[index].CR[2];
- cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
+ cr_data2 = XGI_CRT1Table[index].CR[4];
/* Horizontal blank end */
HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
@@ -150,11 +150,11 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
*right_margin = F * 8;
*hsync_len = C * 8;
- sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
+ sr_data = XGI_CRT1Table[index].CR[14];
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
+ cr_data = XGI_CRT1Table[index].CR[8];
- cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
+ cr_data2 = XGI_CRT1Table[index].CR[9];
/* Vertical total */
VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
@@ -162,10 +162,10 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
| ((unsigned short) (sr_data & 0x01) << 10);
A = VT + 2;
- VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
+ VDE = XGI330_RefIndex[RefreshRateTableIndex].YRes - 1;
E = VDE + 1;
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
+ cr_data = XGI_CRT1Table[index].CR[10];
/* Vertical retrace (=sync) start */
VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
@@ -173,23 +173,23 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
| ((unsigned short) (sr_data & 0x08) << 7);
F = VRS + 1 - E;
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
+ cr_data = XGI_CRT1Table[index].CR[12];
- cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
+ cr_data3 = (XGI_CRT1Table[index].CR[14] & 0x80) << 5;
/* Vertical blank start */
VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
| ((unsigned short) (cr_data3 & 0x20) << 4)
| ((unsigned short) (sr_data & 0x04) << 8);
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
+ cr_data = XGI_CRT1Table[index].CR[13];
/* Vertical blank end */
VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
temp = VBE - ((E - 1) & 511);
B = (temp > 0) ? temp : (temp + 512);
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
+ cr_data = XGI_CRT1Table[index].CR[11];
/* Vertical retrace (=sync) end */
VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
@@ -202,25 +202,25 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
*lower_margin = F;
*vsync_len = C;
- if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
+ if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
*sync &= ~FB_SYNC_VERT_HIGH_ACT;
else
*sync |= FB_SYNC_VERT_HIGH_ACT;
- if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
+ if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
*sync &= ~FB_SYNC_HOR_HIGH_ACT;
else
*sync |= FB_SYNC_HOR_HIGH_ACT;
*vmode = FB_VMODE_NONINTERLACED;
- if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
+ if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
*vmode = FB_VMODE_INTERLACED;
else {
j = 0;
- while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
- if (XGI_Pr->EModeIDTable[j].Ext_ModeID ==
- XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
- if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag &
+ while (XGI330_EModeIDTable[j].Ext_ModeID != 0xff) {
+ if (XGI330_EModeIDTable[j].Ext_ModeID ==
+ XGI330_RefIndex[RefreshRateTableIndex].ModeID) {
+ if (XGI330_EModeIDTable[j].Ext_ModeFlag &
DoubleScanMode) {
*vmode = FB_VMODE_DOUBLE;
}
@@ -1695,7 +1695,7 @@ static int __init XGIfb_setup(char *options)
return 0;
}
-static int __devinit xgifb_probe(struct pci_dev *pdev,
+static int xgifb_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
u8 reg, reg1;
@@ -2103,7 +2103,7 @@ error:
/* PCI DEVICE HANDLING */
/*****************************************************/
-static void __devexit xgifb_remove(struct pci_dev *pdev)
+static void xgifb_remove(struct pci_dev *pdev)
{
struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
struct fb_info *fb_info = xgifb_info->fb_info;
@@ -2127,7 +2127,7 @@ static struct pci_driver xgifb_driver = {
.name = "xgifb",
.id_table = xgifb_pci_table,
.probe = xgifb_probe,
- .remove = __devexit_p(xgifb_remove)
+ .remove = xgifb_remove
};
diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h
index 77137e4452a..148f6373c9a 100644
--- a/drivers/staging/xgifb/vb_def.h
+++ b/drivers/staging/xgifb/vb_def.h
@@ -254,9 +254,16 @@
#define XGI330_SR1F 0
#define XGI330_SR23 0xf6
#define XGI330_SR24 0x0d
-#define XGI330_SR25 0
#define XGI330_SR31 0xc0
#define XGI330_SR32 0x11
#define XGI330_SR33 0
+extern const struct XGI_ExtStruct XGI330_EModeIDTable[];
+extern const struct XGI_Ext2Struct XGI330_RefIndex[];
+extern const struct XGI_CRT1TableStruct XGI_CRT1Table[];
+extern const struct XGI_ECLKDataStruct XGI340_ECLKData[];
+extern const struct SiS_VCLKData XGI_VCLKData[];
+extern const unsigned char XGI340_CR6B[][4];
+extern const unsigned char XGI340_AGPReg[];
+
#endif
diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c
index 7739dbd9f02..2b791c10eb1 100644
--- a/drivers/staging/xgifb/vb_init.c
+++ b/drivers/staging/xgifb/vb_init.c
@@ -94,8 +94,8 @@ static void XGINew_DDR1x_MRS_340(unsigned long P3c4,
0x18,
pVBInfo->SR15[2][pVBInfo->ram_type]); /* SR18 */
xgifb_reg_set(P3c4, 0x19, 0x01);
- xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[0]);
- xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[1]);
+ xgifb_reg_set(P3c4, 0x16, 0x03);
+ xgifb_reg_set(P3c4, 0x16, 0x83);
mdelay(1);
xgifb_reg_set(P3c4, 0x1B, 0x03);
udelay(500);
@@ -103,8 +103,8 @@ static void XGINew_DDR1x_MRS_340(unsigned long P3c4,
0x18,
pVBInfo->SR15[2][pVBInfo->ram_type]); /* SR18 */
xgifb_reg_set(P3c4, 0x19, 0x00);
- xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[2]);
- xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[3]);
+ xgifb_reg_set(P3c4, 0x16, 0x03);
+ xgifb_reg_set(P3c4, 0x16, 0x83);
xgifb_reg_set(P3c4, 0x1B, 0x00);
}
@@ -124,13 +124,13 @@ static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension,
xgifb_reg_set(pVBInfo->P3c4,
0x2E,
- pVBInfo->ECLKData[pVBInfo->ram_type].SR2E);
+ XGI340_ECLKData[pVBInfo->ram_type].SR2E);
xgifb_reg_set(pVBInfo->P3c4,
0x2F,
- pVBInfo->ECLKData[pVBInfo->ram_type].SR2F);
+ XGI340_ECLKData[pVBInfo->ram_type].SR2F);
xgifb_reg_set(pVBInfo->P3c4,
0x30,
- pVBInfo->ECLKData[pVBInfo->ram_type].SR30);
+ XGI340_ECLKData[pVBInfo->ram_type].SR30);
/* When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */
/* Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz,
@@ -138,10 +138,10 @@ static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension,
if (HwDeviceExtension->jChipType == XG42) {
if ((pVBInfo->MCLKData[pVBInfo->ram_type].SR28 == 0x1C) &&
(pVBInfo->MCLKData[pVBInfo->ram_type].SR29 == 0x01) &&
- (((pVBInfo->ECLKData[pVBInfo->ram_type].SR2E == 0x1C) &&
- (pVBInfo->ECLKData[pVBInfo->ram_type].SR2F == 0x01)) ||
- ((pVBInfo->ECLKData[pVBInfo->ram_type].SR2E == 0x22) &&
- (pVBInfo->ECLKData[pVBInfo->ram_type].SR2F == 0x01))))
+ (((XGI340_ECLKData[pVBInfo->ram_type].SR2E == 0x1C) &&
+ (XGI340_ECLKData[pVBInfo->ram_type].SR2F == 0x01)) ||
+ ((XGI340_ECLKData[pVBInfo->ram_type].SR2E == 0x22) &&
+ (XGI340_ECLKData[pVBInfo->ram_type].SR2F == 0x01))))
xgifb_reg_set(pVBInfo->P3c4,
0x32,
((unsigned char) xgifb_reg_get(
@@ -429,7 +429,7 @@ static void XGINew_SetDRAMDefaultRegister340(
temp2 = 0;
for (i = 0; i < 4; i++) {
/* CR6B DQS fine tune delay */
- temp = pVBInfo->CR6B[pVBInfo->ram_type][i];
+ temp = XGI340_CR6B[pVBInfo->ram_type][i];
for (j = 0; j < 4; j++) {
temp1 = ((temp >> (2 * j)) & 0x03) << 2;
temp2 |= temp1;
@@ -444,7 +444,7 @@ static void XGINew_SetDRAMDefaultRegister340(
temp2 = 0;
for (i = 0; i < 4; i++) {
/* CR6E DQM fine tune delay */
- temp = pVBInfo->CR6E[pVBInfo->ram_type][i];
+ temp = 0;
for (j = 0; j < 4; j++) {
temp1 = ((temp >> (2 * j)) & 0x03) << 2;
temp2 |= temp1;
@@ -463,7 +463,7 @@ static void XGINew_SetDRAMDefaultRegister340(
temp2 = 0;
for (i = 0; i < 8; i++) {
/* CR6F DQ fine tune delay */
- temp = pVBInfo->CR6F[pVBInfo->ram_type][8 * k + i];
+ temp = 0;
for (j = 0; j < 4; j++) {
temp1 = (temp >> (2 * j)) & 0x03;
temp2 |= temp1;
@@ -486,7 +486,7 @@ static void XGINew_SetDRAMDefaultRegister340(
temp2 = 0x80;
/* CR89 terminator type select */
- temp = pVBInfo->CR89[pVBInfo->ram_type][0];
+ temp = 0;
for (j = 0; j < 4; j++) {
temp1 = (temp >> (2 * j)) & 0x03;
temp2 |= temp1;
@@ -496,7 +496,7 @@ static void XGINew_SetDRAMDefaultRegister340(
temp2 += 0x10;
}
- temp = pVBInfo->CR89[pVBInfo->ram_type][1];
+ temp = 0;
temp1 = temp & 0x03;
temp2 |= temp1;
xgifb_reg_set(P3d4, 0x89, temp2);
@@ -1378,17 +1378,17 @@ unsigned char XGIInitNew(struct pci_dev *pdev)
for (i = 0x47; i <= 0x4C; i++)
xgifb_reg_set(pVBInfo->P3d4,
i,
- pVBInfo->AGPReg[i - 0x47]);
+ XGI340_AGPReg[i - 0x47]);
for (i = 0x70; i <= 0x71; i++)
xgifb_reg_set(pVBInfo->P3d4,
i,
- pVBInfo->AGPReg[6 + i - 0x70]);
+ XGI340_AGPReg[6 + i - 0x70]);
for (i = 0x74; i <= 0x77; i++)
xgifb_reg_set(pVBInfo->P3d4,
i,
- pVBInfo->AGPReg[8 + i - 0x74]);
+ XGI340_AGPReg[8 + i - 0x74]);
pci_read_config_dword(pdev, 0x50, &Temp);
Temp >>= 20;
@@ -1401,7 +1401,7 @@ unsigned char XGIInitNew(struct pci_dev *pdev)
/* Set PCI */
xgifb_reg_set(pVBInfo->P3c4, 0x23, XGI330_SR23);
xgifb_reg_set(pVBInfo->P3c4, 0x24, XGI330_SR24);
- xgifb_reg_set(pVBInfo->P3c4, 0x25, XGI330_SR25);
+ xgifb_reg_set(pVBInfo->P3c4, 0x25, 0);
if (HwDeviceExtension->jChipType < XG20) {
/* Set VB */
@@ -1482,11 +1482,8 @@ unsigned char XGIInitNew(struct pci_dev *pdev)
XGINew_SetDRAMSize_340(xgifb_info, HwDeviceExtension, pVBInfo);
- xgifb_reg_set(pVBInfo->P3c4,
- 0x22,
- (unsigned char) ((pVBInfo->SR22) & 0xFE));
-
- xgifb_reg_set(pVBInfo->P3c4, 0x21, pVBInfo->SR21);
+ xgifb_reg_set(pVBInfo->P3c4, 0x22, 0xfa);
+ xgifb_reg_set(pVBInfo->P3c4, 0x21, 0xa3);
XGINew_ChkSenseStatus(HwDeviceExtension, pVBInfo);
XGINew_SetModeScratch(HwDeviceExtension, pVBInfo);
diff --git a/drivers/staging/xgifb/vb_init.h b/drivers/staging/xgifb/vb_init.h
index a27b4fe0bb7..d5489832254 100644
--- a/drivers/staging/xgifb/vb_init.h
+++ b/drivers/staging/xgifb/vb_init.h
@@ -1,6 +1,5 @@
#ifndef _VBINIT_
#define _VBINIT_
extern unsigned char XGIInitNew(struct pci_dev *pdev);
-extern struct XGI21_LVDSCapStruct XGI21_LCDCapList[13];
#endif
diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c
index e95a1655a6c..d723a257199 100644
--- a/drivers/staging/xgifb/vb_setmode.c
+++ b/drivers/staging/xgifb/vb_setmode.c
@@ -23,18 +23,7 @@ static const unsigned short XGINew_VGA_DAC[] = {
void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
{
- pVBInfo->StandTable = &XGI330_StandTable;
- pVBInfo->EModeIDTable = XGI330_EModeIDTable;
- pVBInfo->RefIndex = XGI330_RefIndex;
- pVBInfo->XGINEWUB_CRT1Table = XGI_CRT1Table;
-
pVBInfo->MCLKData = XGI340New_MCLKData;
- pVBInfo->ECLKData = XGI340_ECLKData;
- pVBInfo->VCLKData = XGI_VCLKData;
- pVBInfo->VBVCLKData = XGI_VBVCLKData;
- pVBInfo->ScreenOffset = XGI330_ScreenOffset;
- pVBInfo->StResInfo = XGI330_StResInfo;
- pVBInfo->ModeResInfo = XGI330_ModeResInfo;
pVBInfo->LCDResInfo = 0;
pVBInfo->LCDTypeInfo = 0;
@@ -44,19 +33,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
pVBInfo->SR15 = XGI340_SR13;
pVBInfo->CR40 = XGI340_cr41;
- pVBInfo->CR6B = XGI340_CR6B;
- pVBInfo->CR6E = XGI340_CR6E;
- pVBInfo->CR6F = XGI340_CR6F;
- pVBInfo->CR89 = XGI340_CR89;
- pVBInfo->AGPReg = XGI340_AGPReg;
- pVBInfo->SR16 = XGI340_SR16;
-
- pVBInfo->SR21 = 0xa3;
- pVBInfo->SR22 = 0xfb;
-
- pVBInfo->TimingH = XGI_TimingH;
- pVBInfo->TimingV = XGI_TimingV;
- pVBInfo->UpdateCRT1 = XGI_UpdateCRT1Table;
/* 310 customization related */
if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV))
@@ -90,10 +66,10 @@ static void XGI_SetSeqRegs(unsigned short ModeNo,
unsigned char tempah, SRdata;
unsigned short i, modeflag;
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
- tempah = pVBInfo->StandTable->SR[0];
+ tempah = XGI330_StandTable.SR[0];
i = XGI_SetCRT2ToLCDA;
if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
@@ -108,7 +84,7 @@ static void XGI_SetSeqRegs(unsigned short ModeNo,
for (i = 02; i <= 04; i++) {
/* Get SR2,3,4 from file */
- SRdata = pVBInfo->StandTable->SR[i - 1];
+ SRdata = XGI330_StandTable.SR[i - 1];
xgifb_reg_set(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */
}
}
@@ -125,7 +101,7 @@ static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension,
for (i = 0; i <= 0x18; i++) {
/* Get CRTC from file */
- CRTCdata = pVBInfo->StandTable->CRTC[i];
+ CRTCdata = XGI330_StandTable.CRTC[i];
xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */
}
}
@@ -137,10 +113,10 @@ static void XGI_SetATTRegs(unsigned short ModeNo,
unsigned char ARdata;
unsigned short i, modeflag;
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
for (i = 0; i <= 0x13; i++) {
- ARdata = pVBInfo->StandTable->ATTR[i];
+ ARdata = XGI330_StandTable.ATTR[i];
if ((modeflag & Charx8Dot) && i == 0x13) { /* ifndef Dot9 */
if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
@@ -171,7 +147,7 @@ static void XGI_SetGRCRegs(struct vb_device_info *pVBInfo)
for (i = 0; i <= 0x08; i++) {
/* Get GR from file */
- GRdata = pVBInfo->StandTable->GRC[i];
+ GRdata = XGI330_StandTable.GRC[i];
xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */
}
@@ -194,12 +170,12 @@ static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo)
{
xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x20);
- xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[0].SR2B);
- xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[0].SR2C);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[0].SR2B);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[0].SR2C);
xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x10);
- xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B);
- xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[1].SR2B);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[1].SR2C);
xgifb_reg_and(pVBInfo->P3c4, 0x31, ~0x30);
return 0;
@@ -212,9 +188,9 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
{
unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ tempbx = XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
tempax = 0;
if (pVBInfo->IF_DEF_LVDS == 0) {
@@ -279,9 +255,9 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
}
}
- for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID ==
+ for (; XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID ==
tempbx; (*i)--) {
- infoflag = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].
+ infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)].
Ext_InfoFlag;
if (infoflag & tempax)
return 1;
@@ -291,9 +267,9 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
}
for ((*i) = 0;; (*i)++) {
- infoflag = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].
+ infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)].
Ext_InfoFlag;
- if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID
+ if (XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID
!= tempbx) {
return 0;
}
@@ -310,7 +286,7 @@ static void XGI_SetSync(unsigned short RefreshRateTableIndex,
unsigned short sync, temp;
/* di+0x00 */
- sync = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
+ sync = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
sync &= 0xC0;
temp = 0x2F;
temp |= sync;
@@ -328,22 +304,22 @@ static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo,
data &= 0x7F;
xgifb_reg_set(pVBInfo->P3d4, 0x11, data);
- data = pVBInfo->TimingH[0].data[0];
+ data = pVBInfo->TimingH.data[0];
xgifb_reg_set(pVBInfo->P3d4, 0, data);
for (i = 0x01; i <= 0x04; i++) {
- data = pVBInfo->TimingH[0].data[i];
+ data = pVBInfo->TimingH.data[i];
xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 1), data);
}
for (i = 0x05; i <= 0x06; i++) {
- data = pVBInfo->TimingH[0].data[i];
+ data = pVBInfo->TimingH.data[i];
xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i + 6), data);
}
j = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0e);
j &= 0x1F;
- data = pVBInfo->TimingH[0].data[7];
+ data = pVBInfo->TimingH.data[7];
data &= 0xE0;
data |= j;
xgifb_reg_set(pVBInfo->P3c4, 0x0e, data);
@@ -385,32 +361,32 @@ static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex,
unsigned short i, j;
for (i = 0x00; i <= 0x01; i++) {
- data = pVBInfo->TimingV[0].data[i];
+ data = pVBInfo->TimingV.data[i];
xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 6), data);
}
for (i = 0x02; i <= 0x03; i++) {
- data = pVBInfo->TimingV[0].data[i];
+ data = pVBInfo->TimingV.data[i];
xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data);
}
for (i = 0x04; i <= 0x05; i++) {
- data = pVBInfo->TimingV[0].data[i];
+ data = pVBInfo->TimingV.data[i];
xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x11), data);
}
j = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0a);
j &= 0xC0;
- data = pVBInfo->TimingV[0].data[6];
+ data = pVBInfo->TimingV.data[6];
data &= 0x3F;
data |= j;
xgifb_reg_set(pVBInfo->P3c4, 0x0a, data);
- data = pVBInfo->TimingV[0].data[6];
+ data = pVBInfo->TimingV.data[6];
data &= 0x80;
data = data >> 2;
- i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ i = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
i &= DoubleScanMode;
if (i)
data |= 0x80;
@@ -430,7 +406,7 @@ static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short i;
/* Get index */
- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
index = index & IndexMask;
data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
@@ -438,12 +414,12 @@ static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
for (i = 0; i < 8; i++)
- pVBInfo->TimingH[0].data[i]
- = pVBInfo->XGINEWUB_CRT1Table[index].CR[i];
+ pVBInfo->TimingH.data[i]
+ = XGI_CRT1Table[index].CR[i];
for (i = 0; i < 7; i++)
- pVBInfo->TimingV[0].data[i]
- = pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8];
+ pVBInfo->TimingV.data[i]
+ = XGI_CRT1Table[index].CR[i + 8];
XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
@@ -466,23 +442,23 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned char index, Tempax, Tempbx, Tempcx, Tempdx;
unsigned short Temp1, Temp2, Temp3;
- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
/* Tempax: CR4 HRS */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
+ Tempax = XGI_CRT1Table[index].CR[3];
Tempcx = Tempax; /* Tempcx: HRS */
/* SR2E[7:0]->HRS */
xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
- Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */
+ Tempdx = XGI_CRT1Table[index].CR[5]; /* SRB */
Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */
Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */
Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */
Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
+ Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */
Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
- Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
+ Tempbx = XGI_CRT1Table[index].CR[6]; /* SRC */
Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */
Tempbx <<= 3; /* Tempbx[5]: HRE[5] */
Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */
@@ -504,12 +480,12 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
/* CR10 VRS */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10];
+ Tempax = XGI_CRT1Table[index].CR[10];
Tempbx = Tempax; /* Tempbx: VRS */
Tempax &= 0x01; /* Tempax[0]: VRS[0] */
xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */
/* CR7[2][7] VRE */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9];
+ Tempax = XGI_CRT1Table[index].CR[9];
Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */
Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */
Tempdx <<= 5; /* Tempdx[7]: VRS[8] */
@@ -523,17 +499,17 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
/* Tempax: SRA */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
+ Tempax = XGI_CRT1Table[index].CR[14];
Tempax &= 0x08; /* Tempax[3]: VRS[3] */
Temp2 = Tempax;
Temp2 <<= 7; /* Temp2[10]: VRS[10] */
Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */
/* Tempax: CR11 VRE */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11];
+ Tempax = XGI_CRT1Table[index].CR[11];
Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
/* Tempbx: SRA */
- Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
+ Tempbx = XGI_CRT1Table[index].CR[14];
Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */
Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
@@ -563,23 +539,23 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo,
{
unsigned short index, Tempax, Tempbx, Tempcx;
- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
/* Tempax: CR4 HRS */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
+ Tempax = XGI_CRT1Table[index].CR[3];
Tempbx = Tempax; /* Tempbx: HRS[7:0] */
/* SR2E[7:0]->HRS */
xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
/* SR0B */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5];
+ Tempax = XGI_CRT1Table[index].CR[5];
Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
+ Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */
Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
Tempcx = Tempax; /* Tempcx: HRE[4:0] */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
+ Tempax = XGI_CRT1Table[index].CR[6]; /* SRC */
Tempax &= 0x04; /* Tempax[2]: HRE[5] */
Tempax <<= 3; /* Tempax[5]: HRE[5] */
Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */
@@ -588,12 +564,12 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo,
Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */
/* Tempax: CR4 HRS */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
+ Tempax = XGI_CRT1Table[index].CR[3];
Tempax &= 0x3F; /* Tempax: HRS[5:0] */
if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */
Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */
+ Tempax = XGI_CRT1Table[index].CR[5]; /* SR0B */
Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
@@ -602,13 +578,13 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo,
xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
/* CR10 VRS */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10];
+ Tempax = XGI_CRT1Table[index].CR[10];
/* SR34[7:0]->VRS[7:0] */
xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax);
Tempcx = Tempax; /* Tempcx <= VRS[7:0] */
/* CR7[7][2] VRS[9][8] */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9];
+ Tempax = XGI_CRT1Table[index].CR[9];
Tempbx = Tempax; /* Tempbx <= CR07[7:0] */
Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */
Tempax >>= 2; /* Tempax[0]: VRS[8] */
@@ -617,15 +593,15 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo,
Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */
Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */
/* Tempax: SR0A */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
+ Tempax = XGI_CRT1Table[index].CR[14];
Tempax &= 0x08; /* SR0A[3] VRS[10] */
Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */
/* Tempax: CR11 VRE */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11];
+ Tempax = XGI_CRT1Table[index].CR[11];
Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
/* Tempbx: SR0A */
- Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
+ Tempbx = XGI_CRT1Table[index].CR[14];
Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */
Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
@@ -698,7 +674,7 @@ static void xgifb_set_lcd(int chip_id,
xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */
xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */
- Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ Data = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
if (Data & 0x4000)
/* Hsync polarity */
xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20);
@@ -721,10 +697,10 @@ static void XGI_UpdateXG21CRTC(unsigned short ModeNo,
xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */
if (ModeNo == 0x2E &&
- (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC ==
+ (XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC ==
RES640x480x60))
index = 12;
- else if (ModeNo == 0x2E && (pVBInfo->RefIndex[RefreshRateTableIndex].
+ else if (ModeNo == 0x2E && (XGI330_RefIndex[RefreshRateTableIndex].
Ext_CRT1CRTC == RES640x480x72))
index = 13;
else if (ModeNo == 0x2F)
@@ -736,13 +712,13 @@ static void XGI_UpdateXG21CRTC(unsigned short ModeNo,
if (index != -1) {
xgifb_reg_set(pVBInfo->P3d4, 0x02,
- pVBInfo->UpdateCRT1[index].CR02);
+ XGI_UpdateCRT1Table[index].CR02);
xgifb_reg_set(pVBInfo->P3d4, 0x03,
- pVBInfo->UpdateCRT1[index].CR03);
+ XGI_UpdateCRT1Table[index].CR03);
xgifb_reg_set(pVBInfo->P3d4, 0x15,
- pVBInfo->UpdateCRT1[index].CR15);
+ XGI_UpdateCRT1Table[index].CR15);
xgifb_reg_set(pVBInfo->P3d4, 0x16,
- pVBInfo->UpdateCRT1[index].CR16);
+ XGI_UpdateCRT1Table[index].CR16);
}
}
@@ -755,11 +731,11 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension,
unsigned char data;
- resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- tempax = pVBInfo->ModeResInfo[resindex].HTotal;
- tempbx = pVBInfo->ModeResInfo[resindex].VTotal;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ tempax = XGI330_ModeResInfo[resindex].HTotal;
+ tempbx = XGI330_ModeResInfo[resindex].VTotal;
if (modeflag & HalfDCLK)
tempax = tempax >> 1;
@@ -767,7 +743,7 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension,
if (modeflag & HalfDCLK)
tempax = tempax << 1;
- temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
if (temp & InterlaceMode)
tempbx = tempbx >> 1;
@@ -819,11 +795,11 @@ static void XGI_SetCRT1Offset(unsigned short ModeNo,
unsigned short temp, ah, al, temp2, i, DisplayUnit;
/* GetOffset */
- temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+ temp = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
temp = temp >> 8;
- temp = pVBInfo->ScreenOffset[temp];
+ temp = XGI330_ScreenOffset[temp];
- temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
temp2 &= InterlaceMode;
if (temp2)
@@ -874,7 +850,7 @@ static void XGI_SetCRT1Offset(unsigned short ModeNo,
xgifb_reg_set(pVBInfo->P3d4, 0x13, temp);
/* SetDisplayUnit */
- temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
temp2 &= InterlaceMode;
if (temp2)
DisplayUnit >>= 1;
@@ -904,9 +880,9 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
unsigned short modeflag, resinfo;
/* si+Ext_ResInfo */
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- CRT2Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ CRT2Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
if (pVBInfo->IF_DEF_LVDS == 0) {
CRT2Index = CRT2Index >> 6; /* for LCD */
@@ -947,7 +923,7 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
VCLKIndex = TVCLKBASE_315_25 + TVVCLK;
} else { /* for CRT2 */
/* di+Ext_CRTVCLK */
- VCLKIndex = pVBInfo->RefIndex[RefreshRateTableIndex].
+ VCLKIndex = XGI330_RefIndex[RefreshRateTableIndex].
Ext_CRTVCLK;
VCLKIndex &= IndexMask;
}
@@ -971,13 +947,11 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo,
unsigned short vclkindex;
if (pVBInfo->IF_DEF_LVDS == 1) {
- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
- xgifb_reg_set(pVBInfo->P3c4, 0x2B,
- pVBInfo->VCLKData[index].SR2B);
- xgifb_reg_set(pVBInfo->P3c4, 0x2C,
- pVBInfo->VCLKData[index].SR2C);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[index].SR2B);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[index].SR2C);
xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
} else if ((pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
| VB_SIS302LV | VB_XGI301C)) && (pVBInfo->VBInfo
@@ -987,24 +961,22 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo,
pVBInfo);
data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
- data = pVBInfo->VBVCLKData[vclkindex].Part4_A;
+ data = XGI_VBVCLKData[vclkindex].Part4_A;
xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
- data = pVBInfo->VBVCLKData[vclkindex].Part4_B;
+ data = XGI_VBVCLKData[vclkindex].Part4_B;
xgifb_reg_set(pVBInfo->P3c4, 0x2C, data);
xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
} else {
- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
- xgifb_reg_set(pVBInfo->P3c4, 0x2B,
- pVBInfo->VCLKData[index].SR2B);
- xgifb_reg_set(pVBInfo->P3c4, 0x2C,
- pVBInfo->VCLKData[index].SR2C);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[index].SR2B);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[index].SR2C);
xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
}
if (HwDeviceExtension->jChipType >= XG20) {
- if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag &
+ if (XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag &
HalfDCLK) {
data = xgifb_reg_get(pVBInfo->P3c4, 0x2B);
xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
@@ -1064,9 +1036,9 @@ static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension,
unsigned char index;
- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
index &= IndexMask;
- VCLK = pVBInfo->VCLKData[index].CLOCK;
+ VCLK = XGI_VCLKData[index].CLOCK;
data = xgifb_reg_get(pVBInfo->P3c4, 0x32);
data &= 0xf3;
@@ -1102,8 +1074,8 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
unsigned short data, data2, data3, infoflag = 0, modeflag, resindex,
xres;
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01)
xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
@@ -1120,8 +1092,8 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
data2 |= 0x20;
xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2);
- resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
+ resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
data = 0x0000;
if (infoflag & InterlaceMode) {
@@ -1282,13 +1254,13 @@ static void XGI_GetLVDSResInfo(unsigned short ModeNo,
unsigned short resindex, xres, yres, modeflag;
/* si+Ext_ResInfo */
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
/* si+Ext_ResInfo */
- resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
- xres = pVBInfo->ModeResInfo[resindex].HTotal;
- yres = pVBInfo->ModeResInfo[resindex].VTotal;
+ xres = XGI330_ModeResInfo[resindex].HTotal;
+ yres = XGI330_ModeResInfo[resindex].VTotal;
if (modeflag & HalfDCLK)
xres = xres << 1;
@@ -1305,64 +1277,21 @@ static void XGI_GetLVDSResInfo(unsigned short ModeNo,
pVBInfo->VDE = yres;
}
-static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo,
+static void const *XGI_GetLcdPtr(struct XGI330_LCDDataTablStruct const *table,
+ unsigned short ModeNo,
unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo)
{
- unsigned short i, tempdx, tempbx, tempal, modeflag, table;
-
- struct XGI330_LCDDataTablStruct *tempdi = NULL;
-
- tempbx = BX;
-
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-
- tempal = tempal & 0x0f;
-
- if (tempbx <= 1) { /* ExpLink */
- tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-
- if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
- tempal = pVBInfo->RefIndex[RefreshRateTableIndex].
- Ext_CRT2CRTC2;
- }
+ unsigned short i, tempdx, tempbx, modeflag;
- if (tempbx & 0x01)
- tempal = (tempal >> 4);
-
- tempal = (tempal & 0x0f);
- }
-
- switch (tempbx) {
- case 0:
- case 1:
- tempdi = xgifb_epllcd_crt1;
- break;
- case 2:
- tempdi = XGI_EPLLCDDataPtr;
- break;
- case 3:
- tempdi = XGI_EPLLCDDesDataPtr;
- break;
- case 4:
- tempdi = XGI_LCDDataTable;
- break;
- case 5:
- tempdi = XGI_LCDDesDataTable;
- break;
- default:
- break;
- }
+ tempbx = 0;
- if (tempdi == NULL) /* OEMUtil */
- return NULL;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- table = tempbx;
i = 0;
- while (tempdi[i].PANELID != 0xff) {
+ while (table[i].PANELID != 0xff) {
tempdx = pVBInfo->LCDResInfo;
if (tempbx & 0x0080) { /* OEMUtil */
tempbx &= (~0x0080);
@@ -1372,341 +1301,21 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo,
if (pVBInfo->LCDInfo & EnableScalingLCD)
tempdx &= (~PanelResInfo);
- if (tempdi[i].PANELID == tempdx) {
- tempbx = tempdi[i].MASK;
+ if (table[i].PANELID == tempdx) {
+ tempbx = table[i].MASK;
tempdx = pVBInfo->LCDInfo;
if (modeflag & HalfDCLK)
tempdx |= SetLCDLowResolution;
tempbx &= tempdx;
- if (tempbx == tempdi[i].CAP)
+ if (tempbx == table[i].CAP)
break;
}
i++;
}
- if (table == 0) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_LVDSCRT11024x768_1_H[tempal];
- break;
- case 1:
- return &XGI_LVDSCRT11024x768_2_H[tempal];
- break;
- case 2:
- return &XGI_LVDSCRT11280x1024_1_H[tempal];
- break;
- case 3:
- return &XGI_LVDSCRT11280x1024_2_H[tempal];
- break;
- case 4:
- return &XGI_LVDSCRT11400x1050_1_H[tempal];
- break;
- case 5:
- return &XGI_LVDSCRT11400x1050_2_H[tempal];
- break;
- case 6:
- return &XGI_LVDSCRT11600x1200_1_H[tempal];
- break;
- case 7:
- return &XGI_LVDSCRT11024x768_1_Hx75[tempal];
- break;
- case 8:
- return &XGI_LVDSCRT11024x768_2_Hx75[tempal];
- break;
- case 9:
- return &XGI_LVDSCRT11280x1024_1_Hx75[tempal];
- break;
- case 10:
- return &XGI_LVDSCRT11280x1024_2_Hx75[tempal];
- break;
- default:
- break;
- }
- } else if (table == 1) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_LVDSCRT11024x768_1_V[tempal];
- break;
- case 1:
- return &XGI_LVDSCRT11024x768_2_V[tempal];
- break;
- case 2:
- return &XGI_LVDSCRT11280x1024_1_V[tempal];
- break;
- case 3:
- return &XGI_LVDSCRT11280x1024_2_V[tempal];
- break;
- case 4:
- return &XGI_LVDSCRT11400x1050_1_V[tempal];
- break;
- case 5:
- return &XGI_LVDSCRT11400x1050_2_V[tempal];
- break;
- case 6:
- return &XGI_LVDSCRT11600x1200_1_V[tempal];
- break;
- case 7:
- return &XGI_LVDSCRT11024x768_1_Vx75[tempal];
- break;
- case 8:
- return &XGI_LVDSCRT11024x768_2_Vx75[tempal];
- break;
- case 9:
- return &XGI_LVDSCRT11280x1024_1_Vx75[tempal];
- break;
- case 10:
- return &XGI_LVDSCRT11280x1024_2_Vx75[tempal];
- break;
- default:
- break;
- }
- } else if (table == 2) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_LVDS1024x768Data_1[tempal];
- break;
- case 1:
- return &XGI_LVDS1024x768Data_2[tempal];
- break;
- case 2:
- return &XGI_LVDS1280x1024Data_1[tempal];
- break;
- case 3:
- return &XGI_LVDS1280x1024Data_2[tempal];
- break;
- case 4:
- return &XGI_LVDS1400x1050Data_1[tempal];
- break;
- case 5:
- return &XGI_LVDS1400x1050Data_2[tempal];
- break;
- case 6:
- return &XGI_LVDS1600x1200Data_1[tempal];
- break;
- case 7:
- return &XGI_LVDSNoScalingData[tempal];
- break;
- case 8:
- return &XGI_LVDS1024x768Data_1x75[tempal];
- break;
- case 9:
- return &XGI_LVDS1024x768Data_2x75[tempal];
- break;
- case 10:
- return &XGI_LVDS1280x1024Data_1x75[tempal];
- break;
- case 11:
- return &XGI_LVDS1280x1024Data_2x75[tempal];
- break;
- case 12:
- return &XGI_LVDSNoScalingDatax75[tempal];
- break;
- default:
- break;
- }
- } else if (table == 3) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_LVDS1024x768Des_1[tempal];
- break;
- case 1:
- return &XGI_LVDS1024x768Des_3[tempal];
- break;
- case 2:
- return &XGI_LVDS1024x768Des_2[tempal];
- break;
- case 3:
- return &XGI_LVDS1280x1024Des_1[tempal];
- break;
- case 4:
- return &XGI_LVDS1280x1024Des_2[tempal];
- break;
- case 5:
- return &XGI_LVDS1400x1050Des_1[tempal];
- break;
- case 6:
- return &XGI_LVDS1400x1050Des_2[tempal];
- break;
- case 7:
- return &XGI_LVDS1600x1200Des_1[tempal];
- break;
- case 8:
- return &XGI_LVDSNoScalingDesData[tempal];
- break;
- case 9:
- return &XGI_LVDS1024x768Des_1x75[tempal];
- break;
- case 10:
- return &XGI_LVDS1024x768Des_3x75[tempal];
- break;
- case 11:
- return &XGI_LVDS1024x768Des_2x75[tempal];
- break;
- case 12:
- return &XGI_LVDS1280x1024Des_1x75[tempal];
- break;
- case 13:
- return &XGI_LVDS1280x1024Des_2x75[tempal];
- break;
- case 14:
- return &XGI_LVDSNoScalingDesDatax75[tempal];
- break;
- default:
- break;
- }
- } else if (table == 4) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_ExtLCD1024x768Data[tempal];
- break;
- case 1:
- return &XGI_StLCD1024x768Data[tempal];
- break;
- case 2:
- return &XGI_CetLCD1024x768Data[tempal];
- break;
- case 3:
- return &XGI_ExtLCD1280x1024Data[tempal];
- break;
- case 4:
- return &XGI_StLCD1280x1024Data[tempal];
- break;
- case 5:
- return &XGI_CetLCD1280x1024Data[tempal];
- break;
- case 6:
- case 7:
- return &xgifb_lcd_1400x1050[tempal];
- break;
- case 8:
- return &XGI_CetLCD1400x1050Data[tempal];
- break;
- case 9:
- return &XGI_ExtLCD1600x1200Data[tempal];
- break;
- case 10:
- return &XGI_StLCD1600x1200Data[tempal];
- break;
- case 11:
- return &XGI_NoScalingData[tempal];
- break;
- case 12:
- return &XGI_ExtLCD1024x768x75Data[tempal];
- break;
- case 13:
- return &XGI_ExtLCD1024x768x75Data[tempal];
- break;
- case 14:
- return &XGI_CetLCD1024x768x75Data[tempal];
- break;
- case 15:
- case 16:
- return &xgifb_lcd_1280x1024x75[tempal];
- break;
- case 17:
- return &XGI_CetLCD1280x1024x75Data[tempal];
- break;
- case 18:
- return &XGI_NoScalingDatax75[tempal];
- break;
- default:
- break;
- }
- } else if (table == 5) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_ExtLCDDes1024x768Data[tempal];
- break;
- case 1:
- return &XGI_StLCDDes1024x768Data[tempal];
- break;
- case 2:
- return &XGI_CetLCDDes1024x768Data[tempal];
- break;
- case 3:
- if ((pVBInfo->VBType & VB_SIS301LV) ||
- (pVBInfo->VBType & VB_SIS302LV))
- return &XGI_ExtLCDDLDes1280x1024Data[tempal];
- else
- return &XGI_ExtLCDDes1280x1024Data[tempal];
- break;
- case 4:
- if ((pVBInfo->VBType & VB_SIS301LV) ||
- (pVBInfo->VBType & VB_SIS302LV))
- return &XGI_StLCDDLDes1280x1024Data[tempal];
- else
- return &XGI_StLCDDes1280x1024Data[tempal];
- break;
- case 5:
- if ((pVBInfo->VBType & VB_SIS301LV) ||
- (pVBInfo->VBType & VB_SIS302LV))
- return &XGI_CetLCDDLDes1280x1024Data[tempal];
- else
- return &XGI_CetLCDDes1280x1024Data[tempal];
- break;
- case 6:
- case 7:
- if ((pVBInfo->VBType & VB_SIS301LV) ||
- (pVBInfo->VBType & VB_SIS302LV))
- return &xgifb_lcddldes_1400x1050[tempal];
- else
- return &xgifb_lcddes_1400x1050[tempal];
- break;
- case 8:
- return &XGI_CetLCDDes1400x1050Data[tempal];
- break;
- case 9:
- return &XGI_CetLCDDes1400x1050Data2[tempal];
- break;
- case 10:
- if ((pVBInfo->VBType & VB_SIS301LV) ||
- (pVBInfo->VBType & VB_SIS302LV))
- return &XGI_ExtLCDDLDes1600x1200Data[tempal];
- else
- return &XGI_ExtLCDDes1600x1200Data[tempal];
- break;
- case 11:
- if ((pVBInfo->VBType & VB_SIS301LV) ||
- (pVBInfo->VBType & VB_SIS302LV))
- return &XGI_StLCDDLDes1600x1200Data[tempal];
- else
- return &XGI_StLCDDes1600x1200Data[tempal];
- break;
- case 12:
- return &XGI_NoScalingDesData[tempal];
- break;
- case 13:
- case 14:
- return &xgifb_lcddes_1024x768x75[tempal];
- break;
- case 15:
- return &XGI_CetLCDDes1024x768x75Data[tempal];
- break;
- case 16:
- case 17:
- if ((pVBInfo->VBType & VB_SIS301LV) ||
- (pVBInfo->VBType & VB_SIS302LV))
- return &xgifb_lcddldes_1280x1024x75[tempal];
- else
- return &xgifb_lcddes_1280x1024x75[tempal];
- break;
- case 18:
- if ((pVBInfo->VBType & VB_SIS301LV) ||
- (pVBInfo->VBType & VB_SIS302LV))
- return &XGI_CetLCDDLDes1280x1024x75Data[tempal];
- else
- return &XGI_CetLCDDes1280x1024x75Data[tempal];
- break;
- case 19:
- return &XGI_NoScalingDesDatax75[tempal];
- break;
- default:
- break;
- }
- }
- return NULL;
+ return table[i].DATAPTR;
}
static struct SiS_TVData const *XGI_GetTVPtr(unsigned short ModeNo,
@@ -1716,8 +1325,8 @@ static struct SiS_TVData const *XGI_GetTVPtr(unsigned short ModeNo,
{
unsigned short i, tempdx, tempal, modeflag;
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
tempal = tempal & 0x3f;
tempdx = pVBInfo->TVInfo;
@@ -1743,40 +1352,35 @@ static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo)
{
- unsigned short tempbx;
- struct SiS_LVDSData *LCDPtr = NULL;
+ struct SiS_LVDSData const *LCDPtr;
- tempbx = 2;
+ if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
+ return;
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
- LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
- RefreshRateTableIndex, pVBInfo);
- pVBInfo->VGAHT = LCDPtr->VGAHT;
- pVBInfo->VGAVT = LCDPtr->VGAVT;
- pVBInfo->HT = LCDPtr->LCDHT;
- pVBInfo->VT = LCDPtr->LCDVT;
- }
+ LCDPtr = XGI_GetLcdPtr(XGI_EPLLCDDataPtr, ModeNo, ModeIdIndex,
+ RefreshRateTableIndex, pVBInfo);
+ pVBInfo->VGAHT = LCDPtr->VGAHT;
+ pVBInfo->VGAVT = LCDPtr->VGAVT;
+ pVBInfo->HT = LCDPtr->LCDHT;
+ pVBInfo->VT = LCDPtr->LCDVT;
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
- if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding
- | EnableScalingLCD))) {
- if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
- (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
- pVBInfo->HDE = 1024;
- pVBInfo->VDE = 768;
- } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
- (pVBInfo->LCDResInfo ==
- Panel_1280x1024x75)) {
- pVBInfo->HDE = 1280;
- pVBInfo->VDE = 1024;
- } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
- pVBInfo->HDE = 1400;
- pVBInfo->VDE = 1050;
- } else {
- pVBInfo->HDE = 1600;
- pVBInfo->VDE = 1200;
- }
- }
+ if (pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD))
+ return;
+
+ if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
+ (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
+ pVBInfo->HDE = 1024;
+ pVBInfo->VDE = 768;
+ } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
+ (pVBInfo->LCDResInfo == Panel_1280x1024x75)) {
+ pVBInfo->HDE = 1280;
+ pVBInfo->VDE = 1024;
+ } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
+ pVBInfo->HDE = 1400;
+ pVBInfo->VDE = 1050;
+ } else {
+ pVBInfo->HDE = 1600;
+ pVBInfo->VDE = 1200;
}
}
@@ -1786,32 +1390,29 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
struct vb_device_info *pVBInfo)
{
unsigned char index;
- unsigned short tempbx, i;
- struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL;
- struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL;
+ unsigned short i;
+ struct XGI_LVDSCRT1HDataStruct const *LCDPtr = NULL;
+ struct XGI_LVDSCRT1VDataStruct const *LCDPtr1 = NULL;
- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
index = index & IndexMask;
- tempbx = 0;
-
if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
- LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
+ LCDPtr = XGI_GetLcdPtr(xgifb_epllcd_crt1_h, ModeNo, ModeIdIndex,
RefreshRateTableIndex, pVBInfo);
for (i = 0; i < 8; i++)
- pVBInfo->TimingH[0].data[i] = LCDPtr[0].Reg[i];
+ pVBInfo->TimingH.data[i] = LCDPtr[0].Reg[i];
}
XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
- tempbx = 1;
-
if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
- LCDPtr1 = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
- RefreshRateTableIndex, pVBInfo);
+ LCDPtr1 = XGI_GetLcdPtr(xgifb_epllcd_crt1_v, ModeNo,
+ ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo);
for (i = 0; i < 7; i++)
- pVBInfo->TimingV[0].data[i] = LCDPtr1[0].Reg[i];
+ pVBInfo->TimingV.data[i] = LCDPtr1[0].Reg[i];
}
XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
@@ -1895,17 +1496,18 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
{
unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
unsigned long temp, temp1, temp2, temp3, push3;
- struct XGI_LCDDesStruct *LCDPtr = NULL;
- struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
+ struct XGI_LCDDesStruct const *LCDPtr = NULL;
+ struct XGI330_LCDDataDesStruct2 const *LCDPtr1 = NULL;
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- tempbx = 3;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
if (pVBInfo->LCDInfo & EnableScalingLCD)
- LCDPtr1 = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
- RefreshRateTableIndex, pVBInfo);
+ LCDPtr1 = XGI_GetLcdPtr(XGI_EPLLCDDesDataPtr, ModeNo,
+ ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo);
else
- LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
- RefreshRateTableIndex, pVBInfo);
+ LCDPtr = XGI_GetLcdPtr(XGI_EPLLCDDesDataPtr, ModeNo,
+ ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo);
XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
push1 = tempbx;
@@ -2179,7 +1781,7 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
unsigned char tempal;
/* si+Ext_ResInfo */
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
if ((pVBInfo->SetFlag & ProgrammingCRT2) &&
(!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */
@@ -2241,7 +1843,7 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
if ((pVBInfo->LCDInfo & EnableScalingLCD) && (modeflag & Charx8Dot))
tempal = tempal ^ tempal; /* ; set to VCLK25MHz always */
- tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
return tempal;
}
@@ -2425,7 +2027,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
{
unsigned short tempax, push, tempbx, temp, modeflag;
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
pVBInfo->SetFlag = 0;
pVBInfo->ModeType = modeflag & ModeTypeMask;
tempbx = 0;
@@ -2501,7 +2103,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
} else {
temp = 0x017C;
}
- } else { /* 3nd party chip */
+ } else { /* 3rd party chip */
temp = SetCRT2ToLCD;
}
@@ -2611,8 +2213,8 @@ static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
resinfo = 0;
if (pVBInfo->VBInfo & SetCRT2ToTV) {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
if (pVBInfo->VBInfo & SetCRT2ToTV) {
temp = xgifb_reg_get(pVBInfo->P3d4, 0x35);
@@ -2697,9 +2299,9 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo,
pVBInfo->LCDTypeInfo = 0;
pVBInfo->LCDInfo = 0;
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
/* si+Ext_ResInfo // */
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
tempbx = temp & 0x0F;
@@ -2778,9 +2380,9 @@ unsigned char XGI_SearchModeID(unsigned short ModeNo,
unsigned short *ModeIdIndex, struct vb_device_info *pVBInfo)
{
for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
- if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
+ if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
break;
- if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
+ if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
return 0;
}
@@ -3020,11 +2622,11 @@ static void XGI_GetCRT2ResInfo(unsigned short ModeNo,
{
unsigned short xres, yres, modeflag, resindex;
- resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
- yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
+ resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
+ yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
/* si+St_ModeFlag */
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
if (modeflag & HalfDCLK)
xres *= 2;
@@ -3099,19 +2701,19 @@ static void XGI_GetRAMDAC2DATA(unsigned short ModeNo,
pVBInfo->RVBHCMAX = 1;
pVBInfo->RVBHCFACT = 1;
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
CRT1Index &= IndexMask;
- temp1 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0];
- temp2 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
+ temp1 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[0];
+ temp2 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[5];
tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
- tempbx = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8];
+ tempbx = (unsigned short) XGI_CRT1Table[CRT1Index].CR[8];
tempcx = (unsigned short)
- pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8;
+ XGI_CRT1Table[CRT1Index].CR[14] << 8;
tempcx &= 0x0100;
tempcx = tempcx << 2;
tempbx |= tempcx;
- temp1 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
+ temp1 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[9];
if (temp1 & 0x01)
tempbx |= 0x0100;
@@ -3136,13 +2738,13 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo)
{
- unsigned short tempax = 0, tempbx, modeflag, resinfo;
+ unsigned short tempax = 0, tempbx = 0, modeflag, resinfo;
- struct SiS_LCDData *LCDPtr = NULL;
+ struct SiS_LCDData const *LCDPtr = NULL;
/* si+Ext_ResInfo */
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
pVBInfo->NewFlickerMode = 0;
pVBInfo->RVBHRS = 50;
@@ -3152,10 +2754,8 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
return;
}
- tempbx = 4;
-
if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
- LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
+ LCDPtr = XGI_GetLcdPtr(XGI_LCDDataTable, ModeNo, ModeIdIndex,
RefreshRateTableIndex, pVBInfo);
pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
@@ -3345,7 +2945,7 @@ static unsigned short XGI_GetColorDepth(unsigned short ModeNo,
short index;
unsigned short modeflag;
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
index = (modeflag & ModeTypeMask) - ModeEGA;
if (index < 0)
@@ -3363,12 +2963,12 @@ static unsigned short XGI_GetOffset(unsigned short ModeNo,
unsigned short temp, colordepth, modeinfo, index, infoflag,
ColorDepth[] = { 0x01, 0x02, 0x04 };
- modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
- infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ modeinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+ infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
index = (modeinfo >> 8) & 0xFF;
- temp = pVBInfo->ScreenOffset[index];
+ temp = XGI330_ScreenOffset[index];
if (infoflag & InterlaceMode)
temp = temp << 1;
@@ -3424,9 +3024,9 @@ static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
{
unsigned short tempcx = 0, CRT1Index = 0, resinfo = 0;
- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
CRT1Index &= IndexMask;
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
HwDeviceExtension, pVBInfo);
@@ -3447,10 +3047,10 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0,
pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0;
- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
CRT1Index &= IndexMask;
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
/* bainy change table name */
if (modeflag & HalfDCLK) {
@@ -3469,14 +3069,13 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
tempcx += tempbx;
if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
- tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
- tempbx |= ((pVBInfo->
- XGINEWUB_CRT1Table[CRT1Index].CR[14] &
+ tempbx = XGI_CRT1Table[CRT1Index].CR[4];
+ tempbx |= ((XGI_CRT1Table[CRT1Index].CR[14] &
0xC0) << 2);
tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
- tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
+ tempcx = XGI_CRT1Table[CRT1Index].CR[5];
tempcx &= 0x1F;
- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[15];
+ temp = XGI_CRT1Table[CRT1Index].CR[15];
temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
}
@@ -3505,14 +3104,13 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
tempcx += tempbx;
if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
- tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3];
- tempbx |= ((pVBInfo->
- XGINEWUB_CRT1Table[CRT1Index].CR[5] &
+ tempbx = XGI_CRT1Table[CRT1Index].CR[3];
+ tempbx |= ((XGI_CRT1Table[CRT1Index].CR[5] &
0xC0) << 2);
tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
- tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
+ tempcx = XGI_CRT1Table[CRT1Index].CR[4];
tempcx &= 0x1F;
- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[6];
+ temp = XGI_CRT1Table[CRT1Index].CR[6];
temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
tempbx += 16;
@@ -3554,8 +3152,8 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1;
if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
- tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10];
- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
+ tempbx = XGI_CRT1Table[CRT1Index].CR[10];
+ temp = XGI_CRT1Table[CRT1Index].CR[9];
if (temp & 0x04)
tempbx |= 0x0100;
@@ -3563,12 +3161,12 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
if (temp & 0x080)
tempbx |= 0x0200;
- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14];
+ temp = XGI_CRT1Table[CRT1Index].CR[14];
if (temp & 0x08)
tempbx |= 0x0400;
- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[11];
+ temp = XGI_CRT1Table[CRT1Index].CR[11];
tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
}
@@ -3609,9 +3207,9 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
modeflag, CRT1Index;
/* si+Ext_ResInfo */
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
CRT1Index &= IndexMask;
if (!(pVBInfo->VBInfo & SetInSlaveMode))
@@ -3909,9 +3507,9 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned long longtemp, tempeax, tempebx, temp2, tempecx;
/* si+Ext_ResInfo */
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- crt2crtc = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ crt2crtc = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
tempax = 0;
@@ -4345,12 +3943,12 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short push1, push2, pushbx, tempax, tempbx, tempcx, temp,
tempah, tempbh, tempch, resinfo, modeflag, CRT1Index;
- struct XGI_LCDDesStruct *LCDBDesPtr = NULL;
+ struct XGI_LCDDesStruct const *LCDBDesPtr = NULL;
/* si+Ext_ResInfo */
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
CRT1Index &= IndexMask;
if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
@@ -4390,10 +3988,15 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
xgifb_reg_and_or(pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
xgifb_reg_and_or(pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
- /* Customized LCDB Des no add */
- tempbx = 5;
- LCDBDesPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
- RefreshRateTableIndex, pVBInfo);
+ /* Customized LCDB Does not add */
+ if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV))
+ LCDBDesPtr = XGI_GetLcdPtr(xgifb_lcddldes, ModeNo, ModeIdIndex,
+ RefreshRateTableIndex, pVBInfo);
+ else
+ LCDBDesPtr = XGI_GetLcdPtr(XGI_LCDDesDataTable, ModeNo,
+ ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo);
+
tempah = pVBInfo->LCDResInfo;
tempah &= PanelResInfo;
@@ -4545,12 +4148,11 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
/* Output : di -> Tap4 Reg. Setting Pointer */
/* Description : */
/* --------------------------------------------------------------------- */
-static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx,
- struct vb_device_info *pVBInfo)
+static struct XGI301C_Tap4TimingStruct const
+*XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo)
{
unsigned short tempax, tempbx, i;
-
- struct XGI301C_Tap4TimingStruct *Tap4TimingPtr;
+ struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr;
if (tempcx == 0) {
tempax = pVBInfo->VGAHDE;
@@ -4591,8 +4193,7 @@ static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx,
static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
{
unsigned short i, j;
-
- struct XGI301C_Tap4TimingStruct *Tap4TimingPtr;
+ struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr;
if (!(pVBInfo->VBType & VB_XGI301C))
return;
@@ -4628,7 +4229,7 @@ static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short modeflag;
/* si+Ext_ResInfo */
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00);
if (pVBInfo->TVInfo & TVSetPAL) {
@@ -4687,7 +4288,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned long tempebx, tempeax, templong;
/* si+Ext_ResInfo */
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
temp = pVBInfo->RVBHCFACT;
xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp);
@@ -4890,11 +4491,11 @@ static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info,
{
unsigned short xres, yres, colordepth, modeflag, resindex;
- resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
- yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
+ resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
+ yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
/* si+St_ModeFlag */
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
if (!(modeflag & Charx8Dot)) {
xres /= 9;
@@ -4952,11 +4553,11 @@ static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info,
else
XGI_SetXG21FPBits(pVBInfo);
- resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
- yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
+ resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
+ yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
/* si+St_ModeFlag */
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
if (!(modeflag & Charx8Dot))
xres = xres * 8 / 9;
@@ -5619,8 +5220,8 @@ static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex,
struct vb_device_info *pVBInfo)
{
unsigned short tempbx, index;
-
- unsigned char tempcl, tempch, tempal, *filterPtr;
+ unsigned char const *filterPtr;
+ unsigned char tempcl, tempch, tempal;
XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
@@ -5653,7 +5254,7 @@ static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex,
return;
}
- tempal = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
+ tempal = XGI330_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
if (tempcl == 0)
index = tempal * 4;
else
@@ -5915,7 +5516,7 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
unsigned short RefreshRateTableIndex, i, modeflag, index, temp;
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
index = xgifb_reg_get(pVBInfo->P3d4, 0x33);
index = index >> pVBInfo->SelectCRT2Rate;
@@ -5948,31 +5549,30 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
}
}
- RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex;
- ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID;
+ RefreshRateTableIndex = XGI330_EModeIDTable[ModeIdIndex].REFindex;
+ ModeNo = XGI330_RefIndex[RefreshRateTableIndex].ModeID;
if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */
- if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 800) &&
- (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 600)) {
+ if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 800) &&
+ (XGI330_RefIndex[RefreshRateTableIndex].YRes == 600)) {
index++;
}
/* do the similar adjustment like XGISearchCRT1Rate() */
- if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1024) &&
- (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 768)) {
+ if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1024) &&
+ (XGI330_RefIndex[RefreshRateTableIndex].YRes == 768)) {
index++;
}
- if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1280) &&
- (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 1024)) {
+ if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
+ (XGI330_RefIndex[RefreshRateTableIndex].YRes == 1024)) {
index++;
}
}
i = 0;
do {
- if (pVBInfo->RefIndex[RefreshRateTableIndex + i].
+ if (XGI330_RefIndex[RefreshRateTableIndex + i].
ModeID != ModeNo)
break;
- temp = pVBInfo->RefIndex[RefreshRateTableIndex + i].
- Ext_InfoFlag;
+ temp = XGI330_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
temp &= ModeTypeMask;
if (temp < pVBInfo->ModeType)
break;
@@ -5982,7 +5582,7 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
} while (index != 0xFFFF);
if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
if (pVBInfo->VBInfo & SetInSlaveMode) {
- temp = pVBInfo->RefIndex[RefreshRateTableIndex + i - 1].
+ temp = XGI330_RefIndex[RefreshRateTableIndex + i - 1].
Ext_InfoFlag;
if (temp & InterlaceMode)
i++;
@@ -6272,7 +5872,7 @@ static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info,
unsigned short RefreshRateTableIndex, temp;
XGI_SetSeqRegs(ModeNo, ModeIdIndex, pVBInfo);
- outb(pVBInfo->StandTable->MISC, pVBInfo->P3c2);
+ outb(XGI330_StandTable.MISC, pVBInfo->P3c2);
XGI_SetCRTCRegs(HwDeviceExtension, pVBInfo);
XGI_SetATTRegs(ModeNo, ModeIdIndex, pVBInfo);
XGI_SetGRCRegs(pVBInfo);
@@ -6458,7 +6058,7 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
pVBInfo))
return 0;
- pVBInfo->ModeType = pVBInfo->EModeIDTable[ModeIdIndex].
+ pVBInfo->ModeType = XGI330_EModeIDTable[ModeIdIndex].
Ext_ModeFlag & ModeTypeMask;
pVBInfo->SetFlag = 0;
diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h
index 70158c2c68a..acf6e7fbbae 100644
--- a/drivers/staging/xgifb/vb_struct.h
+++ b/drivers/staging/xgifb/vb_struct.h
@@ -56,7 +56,7 @@ struct XGI330_LCDDataTablStruct {
unsigned char PANELID;
unsigned short MASK;
unsigned short CAP;
- unsigned short DATAPTR;
+ void const *DATAPTR;
};
struct XGI330_TVDataTablStruct {
@@ -158,40 +158,18 @@ struct vb_device_info {
void __iomem *FBAddr;
unsigned long BaseAddr;
- unsigned char (*CR6B)[4];
- unsigned char (*CR6E)[4];
- unsigned char (*CR6F)[32];
- unsigned char (*CR89)[2];
+ unsigned char const (*SR15)[8];
+ unsigned char const (*CR40)[8];
- unsigned char (*SR15)[8];
- unsigned char (*CR40)[8];
+ struct SiS_MCLKData const *MCLKData;
- unsigned char *AGPReg;
- unsigned char *SR16;
- unsigned char SR21;
- unsigned char SR22;
- unsigned char SR25;
- struct SiS_MCLKData *MCLKData;
- struct XGI_ECLKDataStruct *ECLKData;
-
- unsigned char *ScreenOffset;
unsigned char *pXGINew_DRAMTypeDefinition;
unsigned char XGINew_CR97;
- struct XGI330_LCDCapStruct *LCDCapList;
-
- struct XGI_TimingHStruct *TimingH;
- struct XGI_TimingVStruct *TimingV;
+ struct XGI330_LCDCapStruct const *LCDCapList;
- struct SiS_StandTable_S *StandTable;
- struct XGI_ExtStruct *EModeIDTable;
- struct XGI_Ext2Struct *RefIndex;
- struct XGI_CRT1TableStruct *XGINEWUB_CRT1Table;
- struct SiS_VCLKData *VCLKData;
- struct SiS_VBVCLKData *VBVCLKData;
- struct SiS_StResInfo_S *StResInfo;
- struct SiS_ModeResInfo_S *ModeResInfo;
- struct XGI_XG21CRT1Struct *UpdateCRT1;
+ struct XGI_TimingHStruct TimingH;
+ struct XGI_TimingVStruct TimingV;
int ram_type;
int ram_channel;
diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h
index 180aae042ce..39f528b14f0 100644
--- a/drivers/staging/xgifb/vb_table.h
+++ b/drivers/staging/xgifb/vb_table.h
@@ -1,6 +1,6 @@
#ifndef _VB_TABLE_
#define _VB_TABLE_
-static struct SiS_MCLKData XGI340New_MCLKData[] = {
+static const struct SiS_MCLKData XGI340New_MCLKData[] = {
{0x16, 0x01, 0x01, 166},
{0x19, 0x02, 0x01, 124},
{0x7C, 0x08, 0x01, 200},
@@ -11,7 +11,7 @@ static struct SiS_MCLKData XGI340New_MCLKData[] = {
{0x5c, 0x23, 0x01, 166}
};
-static struct SiS_MCLKData XGI27New_MCLKData[] = {
+static const struct SiS_MCLKData XGI27New_MCLKData[] = {
{0x5c, 0x23, 0x01, 166},
{0x19, 0x02, 0x01, 124},
{0x7C, 0x08, 0x80, 200},
@@ -22,7 +22,7 @@ static struct SiS_MCLKData XGI27New_MCLKData[] = {
{0x5c, 0x23, 0x01, 166}
};
-static struct XGI_ECLKDataStruct XGI340_ECLKData[] = {
+const struct XGI_ECLKDataStruct XGI340_ECLKData[] = {
{0x5c, 0x23, 0x01, 166},
{0x55, 0x84, 0x01, 123},
{0x7C, 0x08, 0x01, 200},
@@ -33,21 +33,21 @@ static struct XGI_ECLKDataStruct XGI340_ECLKData[] = {
{0x5c, 0x23, 0x01, 166}
};
-static unsigned char XG27_SR13[4][8] = {
+static const unsigned char XG27_SR13[4][8] = {
{0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */
{0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */
{0x32, 0x32, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR18 */
{0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00} /* SR1B */
};
-static unsigned char XGI340_SR13[4][8] = {
+static const unsigned char XGI340_SR13[4][8] = {
{0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */
{0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */
{0x31, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR18 */
{0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00} /* SR1B */
};
-static unsigned char XGI340_cr41[24][8] = {
+static const unsigned char XGI340_cr41[24][8] = {
{0x20, 0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0 CR41 */
{0xc4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1 CR8A */
{0xc4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 2 CR8B */
@@ -74,7 +74,7 @@ static unsigned char XGI340_cr41[24][8] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 23 CRC5 */
};
-static unsigned char XGI27_cr41[24][8] = {
+static const unsigned char XGI27_cr41[24][8] = {
{0x20, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0 CR41 */
{0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1 CR8A */
{0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 2 CR8B */
@@ -103,7 +103,7 @@ static unsigned char XGI27_cr41[24][8] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 23 CRC5 */
};
-static unsigned char XGI340_CR6B[8][4] = {
+const unsigned char XGI340_CR6B[8][4] = {
{0xaa, 0xaa, 0xaa, 0xaa},
{0xaa, 0xaa, 0xaa, 0xaa},
{0xaa, 0xaa, 0xaa, 0xaa},
@@ -114,21 +114,13 @@ static unsigned char XGI340_CR6B[8][4] = {
{0x00, 0x00, 0x00, 0x00}
};
-static unsigned char XGI340_CR6E[8][4];
-
-static unsigned char XGI340_CR6F[8][32];
-
-static unsigned char XGI340_CR89[8][2];
-
/* CR47,CR48,CR49,CR4A,CR4B,CR4C,CR70,CR71,CR74,CR75,CR76,CR77 */
-static unsigned char XGI340_AGPReg[12] = {
+const unsigned char XGI340_AGPReg[12] = {
0x28, 0x23, 0x00, 0x20, 0x00, 0x20,
0x00, 0x05, 0xd0, 0x10, 0x10, 0x00
};
-static unsigned char XGI340_SR16[4] = {0x03, 0x83, 0x03, 0x83};
-
-static struct XGI_ExtStruct XGI330_EModeIDTable[] = {
+const struct XGI_ExtStruct XGI330_EModeIDTable[] = {
{0x2e, 0x0a1b, 0x0306, 0x06, 0x05, 0x06},
{0x2f, 0x0a1b, 0x0305, 0x05, 0x05, 0x05},
{0x30, 0x2a1b, 0x0407, 0x07, 0x07, 0x0e},
@@ -200,7 +192,7 @@ static struct XGI_ExtStruct XGI330_EModeIDTable[] = {
{0xff, 0x0000, 0x0000, 0x00, 0x00, 0x00}
};
-static struct SiS_StandTable_S XGI330_StandTable = {
+static const struct SiS_StandTable_S XGI330_StandTable = {
/* ExtVGATable */
0x00, 0x00, 0x00, 0x0000,
{0x01, 0x0f, 0x00, 0x0e},
@@ -216,11 +208,7 @@ static struct SiS_StandTable_S XGI330_StandTable = {
0xff}
};
-static struct XGI_TimingHStruct XGI_TimingH[1];
-
-static struct XGI_TimingVStruct XGI_TimingV[1];
-
-static struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] = {
+static const struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] = {
{0x01, 0x27, 0x91, 0x8f, 0xc0}, /* 00 */
{0x03, 0x4f, 0x83, 0x8f, 0xc0}, /* 01 */
{0x05, 0x27, 0x91, 0x8f, 0xc0}, /* 02 */
@@ -240,7 +228,7 @@ static struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] = {
{0x59, 0x27, 0x91, 0x8f, 0xc0} /* 16 */
};
-static struct XGI_CRT1TableStruct XGI_CRT1Table[] = {
+const struct XGI_CRT1TableStruct XGI_CRT1Table[] = {
{ {0x2d, 0x28, 0x90, 0x2c, 0x90, 0x00, 0x04, 0x00,
0xbf, 0x1f, 0x9c, 0x8e, 0x96, 0xb9, 0x30} }, /* 0x0 */
{ {0x2d, 0x28, 0x90, 0x2c, 0x90, 0x00, 0x04, 0x00,
@@ -404,7 +392,7 @@ static struct XGI_CRT1TableStruct XGI_CRT1Table[] = {
};
/*add for new UNIVGABIOS*/
-static struct SiS_LCDData XGI_StLCD1024x768Data[] = {
+static const struct SiS_LCDData XGI_StLCD1024x768Data[] = {
{62, 25, 800, 546, 1344, 806},
{32, 15, 930, 546, 1344, 806},
{62, 25, 800, 546, 1344, 806}, /*chiawenfordot9->dot8*/
@@ -414,7 +402,7 @@ static struct SiS_LCDData XGI_StLCD1024x768Data[] = {
{1, 1, 1344, 806, 1344, 806}
};
-static struct SiS_LCDData XGI_ExtLCD1024x768Data[] = {
+static const struct SiS_LCDData XGI_ExtLCD1024x768Data[] = {
{42, 25, 1536, 419, 1344, 806},
{48, 25, 1536, 369, 1344, 806},
{42, 25, 1536, 419, 1344, 806},
@@ -430,7 +418,7 @@ static struct SiS_LCDData XGI_ExtLCD1024x768Data[] = {
{1, 1, 1344, 806, 1344, 806}
};
-static struct SiS_LCDData XGI_CetLCD1024x768Data[] = {
+static const struct SiS_LCDData XGI_CetLCD1024x768Data[] = {
{1, 1, 1344, 806, 1344, 806}, /* ; 00 (320x200,320x400,
640x200,640x400) */
{1, 1, 1344, 806, 1344, 806}, /* 01 (320x350,640x350) */
@@ -441,7 +429,7 @@ static struct SiS_LCDData XGI_CetLCD1024x768Data[] = {
{1, 1, 1344, 806, 1344, 806} /* 06 (1024x768x60Hz) */
};
-static struct SiS_LCDData XGI_StLCD1280x1024Data[] = {
+static const struct SiS_LCDData XGI_StLCD1280x1024Data[] = {
{22, 5, 800, 510, 1650, 1088},
{22, 5, 800, 510, 1650, 1088},
{176, 45, 900, 510, 1650, 1088},
@@ -452,7 +440,7 @@ static struct SiS_LCDData XGI_StLCD1280x1024Data[] = {
{1, 1, 1688, 1066, 1688, 1066}
};
-static struct SiS_LCDData XGI_ExtLCD1280x1024Data[] = {
+static const struct SiS_LCDData XGI_ExtLCD1280x1024Data[] = {
{211, 60, 1024, 501, 1688, 1066},
{211, 60, 1024, 508, 1688, 1066},
{211, 60, 1024, 501, 1688, 1066},
@@ -463,7 +451,7 @@ static struct SiS_LCDData XGI_ExtLCD1280x1024Data[] = {
{1, 1, 1688, 1066, 1688, 1066}
};
-static struct SiS_LCDData XGI_CetLCD1280x1024Data[] = {
+static const struct SiS_LCDData XGI_CetLCD1280x1024Data[] = {
{1, 1, 1688, 1066, 1688, 1066}, /* 00 (320x200,320x400,
640x200,640x400) */
{1, 1, 1688, 1066, 1688, 1066}, /* 01 (320x350,640x350) */
@@ -476,7 +464,7 @@ static struct SiS_LCDData XGI_CetLCD1280x1024Data[] = {
{1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */
};
-static struct SiS_LCDData xgifb_lcd_1400x1050[] = {
+static const struct SiS_LCDData xgifb_lcd_1400x1050[] = {
{211, 100, 2100, 408, 1688, 1066}, /* 00 (320x200,320x400,
640x200,640x400) */
{211, 64, 1536, 358, 1688, 1066}, /* 01 (320x350,640x350) */
@@ -490,7 +478,7 @@ static struct SiS_LCDData xgifb_lcd_1400x1050[] = {
{1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */
};
-static struct SiS_LCDData XGI_ExtLCD1600x1200Data[] = {
+static const struct SiS_LCDData XGI_ExtLCD1600x1200Data[] = {
{4, 1, 1620, 420, 2160, 1250}, /* 00 (320x200,320x400,
640x200,640x400)*/
{27, 7, 1920, 375, 2160, 1250}, /* 01 (320x350,640x350) */
@@ -504,7 +492,7 @@ static struct SiS_LCDData XGI_ExtLCD1600x1200Data[] = {
{1, 1, 2160, 1250, 2160, 1250} /* 09 (1600x1200x60Hz) ;302lv */
};
-static struct SiS_LCDData XGI_StLCD1600x1200Data[] = {
+static const struct SiS_LCDData XGI_StLCD1600x1200Data[] = {
{27, 4, 800, 500, 2160, 1250}, /* 00 (320x200,320x400,
640x200,640x400) */
{27, 4, 800, 500, 2160, 1250}, /* 01 (320x350,640x350) */
@@ -520,7 +508,7 @@ static struct SiS_LCDData XGI_StLCD1600x1200Data[] = {
#define XGI_CetLCD1400x1050Data XGI_CetLCD1280x1024Data
-static struct SiS_LCDData XGI_NoScalingData[] = {
+static const struct SiS_LCDData XGI_NoScalingData[] = {
{1, 1, 800, 449, 800, 449},
{1, 1, 800, 449, 800, 449},
{1, 1, 900, 449, 900, 449},
@@ -531,7 +519,7 @@ static struct SiS_LCDData XGI_NoScalingData[] = {
{1, 1, 1688, 1066, 1688, 1066}
};
-static struct SiS_LCDData XGI_ExtLCD1024x768x75Data[] = {
+static const struct SiS_LCDData XGI_ExtLCD1024x768x75Data[] = {
{42, 25, 1536, 419, 1344, 806}, /* ; 00 (320x200,320x400,
640x200,640x400) */
{48, 25, 1536, 369, 1344, 806}, /* ; 01 (320x350,640x350) */
@@ -542,7 +530,7 @@ static struct SiS_LCDData XGI_ExtLCD1024x768x75Data[] = {
{1, 1, 1312, 800, 1312, 800} /* ; 06 (1024x768x75Hz) */
};
-static struct SiS_LCDData XGI_CetLCD1024x768x75Data[] = {
+static const struct SiS_LCDData XGI_CetLCD1024x768x75Data[] = {
{1, 1, 1312, 800, 1312, 800}, /* ; 00 (320x200,320x400,
640x200,640x400) */
{1, 1, 1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */
@@ -553,7 +541,7 @@ static struct SiS_LCDData XGI_CetLCD1024x768x75Data[] = {
{1, 1, 1312, 800, 1312, 800} /* ; 06 (1024x768x75Hz) */
};
-static struct SiS_LCDData xgifb_lcd_1280x1024x75[] = {
+static const struct SiS_LCDData xgifb_lcd_1280x1024x75[] = {
{211, 60, 1024, 501, 1688, 1066}, /* ; 00 (320x200,320x400,
640x200,640x400) */
{211, 60, 1024, 508, 1688, 1066}, /* ; 01 (320x350,640x350) */
@@ -567,7 +555,7 @@ static struct SiS_LCDData xgifb_lcd_1280x1024x75[] = {
#define XGI_CetLCD1280x1024x75Data XGI_CetLCD1280x1024Data
-static struct SiS_LCDData XGI_NoScalingDatax75[] = {
+static const struct SiS_LCDData XGI_NoScalingDatax75[] = {
{1, 1, 800, 449, 800, 449}, /* ; 00 (320x200, 320x400,
640x200, 640x400) */
{1, 1, 800, 449, 800, 449}, /* ; 01 (320x350, 640x350) */
@@ -582,7 +570,7 @@ static struct SiS_LCDData XGI_NoScalingDatax75[] = {
{1, 1, 1688, 806, 1688, 806} /* ; 0A (1280x768x75Hz) */
};
-static struct XGI_LCDDesStruct XGI_ExtLCDDes1024x768Data[] = {
+static const struct XGI_LCDDesStruct XGI_ExtLCDDes1024x768Data[] = {
{9, 1057, 0, 771}, /* ; 00 (320x200,320x400,640x200,640x400) */
{9, 1057, 0, 771}, /* ; 01 (320x350,640x350) */
{9, 1057, 0, 771}, /* ; 02 (360x400,720x400) */
@@ -592,7 +580,7 @@ static struct XGI_LCDDesStruct XGI_ExtLCDDes1024x768Data[] = {
{9, 1057, 805, 770} /* ; 06 (1024x768x60Hz) */
};
-static struct XGI_LCDDesStruct XGI_StLCDDes1024x768Data[] = {
+static const struct XGI_LCDDesStruct XGI_StLCDDes1024x768Data[] = {
{9, 1057, 737, 703}, /* ; 00 (320x200,320x400,640x200,640x400) */
{9, 1057, 686, 651}, /* ; 01 (320x350,640x350) */
{9, 1057, 737, 703}, /* ; 02 (360x400,720x400) */
@@ -602,7 +590,7 @@ static struct XGI_LCDDesStruct XGI_StLCDDes1024x768Data[] = {
{9, 1057, 805, 770} /* ; 06 (1024x768x60Hz) */
};
-static struct XGI_LCDDesStruct XGI_CetLCDDes1024x768Data[] = {
+static const struct XGI_LCDDesStruct XGI_CetLCDDes1024x768Data[] = {
{1152, 856, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */
{1152, 856, 597, 562}, /* ; 01 (320x350,640x350) */
{1152, 856, 622, 587}, /* ; 02 (360x400,720x400) */
@@ -612,7 +600,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDes1024x768Data[] = {
{0, 1048, 805, 770} /* ; 06 (1024x768x60Hz) */
};
-static struct XGI_LCDDesStruct XGI_ExtLCDDLDes1280x1024Data[] = {
+static const struct XGI_LCDDesStruct XGI_ExtLCDDLDes1280x1024Data[] = {
{18, 1346, 981, 940}, /* 00 (320x200,320x400,640x200,640x400) */
{18, 1346, 926, 865}, /* 01 (320x350,640x350) */
{18, 1346, 981, 940}, /* 02 (360x400,720x400) */
@@ -623,7 +611,7 @@ static struct XGI_LCDDesStruct XGI_ExtLCDDLDes1280x1024Data[] = {
{18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */
};
-static struct XGI_LCDDesStruct XGI_StLCDDLDes1280x1024Data[] = {
+static const struct XGI_LCDDesStruct XGI_StLCDDLDes1280x1024Data[] = {
{18, 1346, 970, 907}, /* 00 (320x200,320x400,640x200,640x400) */
{18, 1346, 917, 854}, /* 01 (320x350,640x350) */
{18, 1346, 970, 907}, /* 02 (360x400,720x400) */
@@ -634,7 +622,7 @@ static struct XGI_LCDDesStruct XGI_StLCDDLDes1280x1024Data[] = {
{18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */
};
-static struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024Data[] = {
+static const struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024Data[] = {
{1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */
{1368, 1008, 729, 688}, /* 01 (320x350,640x350) */
{1368, 1008, 752, 711}, /* 02 (360x400,720x400) */
@@ -645,7 +633,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024Data[] = {
{18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */
};
-static struct XGI_LCDDesStruct XGI_ExtLCDDes1280x1024Data[] = {
+static const struct XGI_LCDDesStruct XGI_ExtLCDDes1280x1024Data[] = {
{9, 1337, 981, 940}, /* ; 00 (320x200,320x400,640x200,640x400) */
{9, 1337, 926, 884}, /* ; 01 (320x350,640x350) alan, 2003/09/30 */
{9, 1337, 981, 940}, /* ; 02 (360x400,720x400) */
@@ -656,7 +644,7 @@ static struct XGI_LCDDesStruct XGI_ExtLCDDes1280x1024Data[] = {
{9, 1337, 1065, 1024} /* ; 07 (1280x1024x60Hz) */
};
-static struct XGI_LCDDesStruct XGI_StLCDDes1280x1024Data[] = {
+static const struct XGI_LCDDesStruct XGI_StLCDDes1280x1024Data[] = {
{9, 1337, 970, 907}, /* ; 00 (320x200,320x400,640x200,640x400) */
{9, 1337, 917, 854}, /* ; 01 (320x350,640x350) */
{9, 1337, 970, 907}, /* ; 02 (360x400,720x400) */
@@ -667,7 +655,7 @@ static struct XGI_LCDDesStruct XGI_StLCDDes1280x1024Data[] = {
{9, 1337, 1065, 1024} /* ; 07 (1280x1024x60Hz) */
};
-static struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024Data[] = {
+static const struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024Data[] = {
{1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */
{1368, 1008, 729, 688}, /* 01 (320x350,640x350) */
{1368, 1008, 752, 711}, /* 02 (360x400,720x400) */
@@ -678,7 +666,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024Data[] = {
{9, 1337, 1065, 1024} /* 07 (1280x1024x60Hz) */
};
-static struct XGI_LCDDesStruct xgifb_lcddldes_1400x1050[] = {
+static const struct XGI_LCDDesStruct xgifb_lcddldes_1400x1050[] = {
{18, 1464, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */
{18, 1464, 0, 1051}, /* 01 (320x350,640x350) */
{18, 1464, 0, 1051}, /* 02 (360x400,720x400) */
@@ -690,7 +678,7 @@ static struct XGI_LCDDesStruct xgifb_lcddldes_1400x1050[] = {
{18, 1464, 0, 1051} /* 08 (1400x1050x60Hz) */
};
-static struct XGI_LCDDesStruct xgifb_lcddes_1400x1050[] = {
+static const struct XGI_LCDDesStruct xgifb_lcddes_1400x1050[] = {
{9, 1455, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */
{9, 1455, 0, 1051}, /* 01 (320x350,640x350) */
{9, 1455, 0, 1051}, /* 02 (360x400,720x400) */
@@ -702,7 +690,7 @@ static struct XGI_LCDDesStruct xgifb_lcddes_1400x1050[] = {
{9, 1455, 0, 1051} /* 08 (1400x1050x60Hz) */
};
-static struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data[] = {
+static const struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data[] = {
{1308, 1068, 781, 766}, /* 00 (320x200,320x400,640x200,640x400) */
{1308, 1068, 781, 766}, /* 01 (320x350,640x350) */
{1308, 1068, 781, 766}, /* 02 (360x400,720x400) */
@@ -714,7 +702,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data[] = {
{18, 1464, 0, 1051} /* 08 (1400x1050x60Hz) */
};
-static struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data2[] = {
+static const struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data2[] = {
{0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */
{0, 1448, 0, 1051}, /* 01 (320x350,640x350) */
{0, 1448, 0, 1051}, /* 02 (360x400,720x400) */
@@ -722,7 +710,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data2[] = {
{0, 1448, 0, 1051} /* 04 (640x480x60Hz) */
};
-static struct XGI_LCDDesStruct XGI_ExtLCDDLDes1600x1200Data[] = {
+static const struct XGI_LCDDesStruct XGI_ExtLCDDLDes1600x1200Data[] = {
{18, 1682, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */
{18, 1682, 0, 1201}, /* 01 (320x350,640x350) */
{18, 1682, 0, 1201}, /* 02 (360x400,720x400) */
@@ -735,7 +723,7 @@ static struct XGI_LCDDesStruct XGI_ExtLCDDLDes1600x1200Data[] = {
{18, 1682, 0, 1201} /* 09 (1600x1200x60Hz) */
};
-static struct XGI_LCDDesStruct XGI_StLCDDLDes1600x1200Data[] = {
+static const struct XGI_LCDDesStruct XGI_StLCDDLDes1600x1200Data[] = {
{18, 1682, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */
{18, 1682, 1083, 1034}, /* 01 (320x350,640x350) */
{18, 1682, 1150, 1101}, /* 02 (360x400,720x400) */
@@ -748,7 +736,7 @@ static struct XGI_LCDDesStruct XGI_StLCDDLDes1600x1200Data[] = {
{18, 1682, 0, 1201} /* 09 (1600x1200x60Hz) */
};
-static struct XGI_LCDDesStruct XGI_ExtLCDDes1600x1200Data[] = {
+static const struct XGI_LCDDesStruct XGI_ExtLCDDes1600x1200Data[] = {
{9, 1673, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */
{9, 1673, 0, 1201}, /* 01 (320x350,640x350) */
{9, 1673, 0, 1201}, /* 02 (360x400,720x400) */
@@ -761,7 +749,7 @@ static struct XGI_LCDDesStruct XGI_ExtLCDDes1600x1200Data[] = {
{9, 1673, 0, 1201} /* 09 (1600x1200x60Hz) */
};
-static struct XGI_LCDDesStruct XGI_StLCDDes1600x1200Data[] = {
+static const struct XGI_LCDDesStruct XGI_StLCDDes1600x1200Data[] = {
{9, 1673, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */
{9, 1673, 1083, 1034}, /* 01 (320x350,640x350) */
{9, 1673, 1150, 1101}, /* 02 (360x400,720x400) */
@@ -774,7 +762,7 @@ static struct XGI_LCDDesStruct XGI_StLCDDes1600x1200Data[] = {
{9, 1673, 0, 1201} /* 09 (1600x1200x60Hz) */
};
-static struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] = {
+static const struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] = {
{9, 657, 448, 405, 96, 2}, /* 00 (320x200,320x400,
640x200,640x400) */
{9, 657, 448, 355, 96, 2}, /* 01 (320x350,640x350) */
@@ -790,7 +778,7 @@ static struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] = {
};
/* ;;1024x768x75Hz */
-static struct XGI_LCDDesStruct xgifb_lcddes_1024x768x75[] = {
+static const struct XGI_LCDDesStruct xgifb_lcddes_1024x768x75[] = {
{9, 1049, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */
{9, 1049, 0, 769}, /* ; 01 (320x350,640x350) */
{9, 1049, 0, 769}, /* ; 02 (360x400,720x400) */
@@ -801,7 +789,7 @@ static struct XGI_LCDDesStruct xgifb_lcddes_1024x768x75[] = {
};
/* ;;1024x768x75Hz */
-static struct XGI_LCDDesStruct XGI_CetLCDDes1024x768x75Data[] = {
+static const struct XGI_LCDDesStruct XGI_CetLCDDes1024x768x75Data[] = {
{1152, 856, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */
{1152, 856, 597, 562}, /* ; 01 (320x350,640x350) */
{1192, 896, 622, 587}, /* ; 02 (360x400,720x400) */
@@ -812,7 +800,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDes1024x768x75Data[] = {
};
/* ;;1280x1024x75Hz */
-static struct XGI_LCDDesStruct xgifb_lcddldes_1280x1024x75[] = {
+static const struct XGI_LCDDesStruct xgifb_lcddldes_1280x1024x75[] = {
{18, 1314, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
{18, 1314, 0, 1025}, /* ; 01 (320x350,640x350) */
{18, 1314, 0, 1025}, /* ; 02 (360x400,720x400) */
@@ -824,7 +812,7 @@ static struct XGI_LCDDesStruct xgifb_lcddldes_1280x1024x75[] = {
};
/* 1280x1024x75Hz */
-static struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = {
+static const struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = {
{1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */
{1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */
{1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */
@@ -836,7 +824,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = {
};
/* ;;1280x1024x75Hz */
-static struct XGI_LCDDesStruct xgifb_lcddes_1280x1024x75[] = {
+static const struct XGI_LCDDesStruct xgifb_lcddes_1280x1024x75[] = {
{9, 1305, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
{9, 1305, 0, 1025}, /* ; 01 (320x350,640x350) */
{9, 1305, 0, 1025}, /* ; 02 (360x400,720x400) */
@@ -848,7 +836,7 @@ static struct XGI_LCDDesStruct xgifb_lcddes_1280x1024x75[] = {
};
/* 1280x1024x75Hz */
-static struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024x75Data[] = {
+static const struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024x75Data[] = {
{1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */
{1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */
{1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */
@@ -860,7 +848,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024x75Data[] = {
};
/* Scaling LCD 75Hz */
-static struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] = {
+static const struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] = {
{9, 657, 448, 405, 96, 2}, /* ; 00 (320x200,320x400,
640x200,640x400) */
{9, 657, 448, 355, 96, 2}, /* ; 01 (320x350,640x350) */
@@ -1174,7 +1162,7 @@ static const unsigned char XGI330_Ren750pGroup3[] = {
0x18, 0x1D, 0x23, 0x28, 0x4C, 0xAA, 0x01
};
-static struct SiS_LVDSData XGI_LVDS1024x768Data_1[] = {
+static const struct SiS_LVDSData XGI_LVDS1024x768Data_1[] = {
{ 960, 438, 1344, 806}, /* 00 (320x200,320x400,640x200,640x400) */
{ 960, 388, 1344, 806}, /* 01 (320x350,640x350) */
{1040, 438, 1344, 806}, /* 02 (360x400,720x400) */
@@ -1185,7 +1173,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Data_1[] = {
};
-static struct SiS_LVDSData XGI_LVDS1024x768Data_2[] = {
+static const struct SiS_LVDSData XGI_LVDS1024x768Data_2[] = {
{1344, 806, 1344, 806},
{1344, 806, 1344, 806},
{1344, 806, 1344, 806},
@@ -1197,7 +1185,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Data_2[] = {
{800, 525, 1280, 813}
};
-static struct SiS_LVDSData XGI_LVDS1280x1024Data_1[] = {
+static const struct SiS_LVDSData XGI_LVDS1280x1024Data_1[] = {
{1048, 442, 1688, 1066},
{1048, 392, 1688, 1066},
{1048, 442, 1688, 1066},
@@ -1210,7 +1198,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Data_1[] = {
#define XGI_LVDS1280x1024Data_2 XGI_LVDS1024x768Data_2
-static struct SiS_LVDSData XGI_LVDS1400x1050Data_1[] = {
+static const struct SiS_LVDSData XGI_LVDS1400x1050Data_1[] = {
{928, 416, 1688, 1066},
{928, 366, 1688, 1066},
{928, 416, 1688, 1066},
@@ -1222,7 +1210,7 @@ static struct SiS_LVDSData XGI_LVDS1400x1050Data_1[] = {
{1688, 1066, 1688, 1066}
};
-static struct SiS_LVDSData XGI_LVDS1400x1050Data_2[] = {
+static const struct SiS_LVDSData XGI_LVDS1400x1050Data_2[] = {
{1688, 1066, 1688, 1066},
{1688, 1066, 1688, 1066},
{1688, 1066, 1688, 1066},
@@ -1235,7 +1223,7 @@ static struct SiS_LVDSData XGI_LVDS1400x1050Data_2[] = {
};
/* ;;[ycchen] 12/05/02 LCDHTxLCDVT=2048x1320 */
-static struct SiS_LVDSData XGI_LVDS1600x1200Data_1[] = {
+static const struct SiS_LVDSData XGI_LVDS1600x1200Data_1[] = {
{1088, 520, 2048, 1320}, /* 00 (320x200,320x400,640x200,640x400) */
{1088, 470, 2048, 1320}, /* 01 (320x350,640x350) */
{1088, 520, 2048, 1320}, /* 02 (360x400,720x400) */
@@ -1248,7 +1236,7 @@ static struct SiS_LVDSData XGI_LVDS1600x1200Data_1[] = {
{2048, 1320, 2048, 1320} /* 09 (1600x1200) */
};
-static struct SiS_LVDSData XGI_LVDSNoScalingData[] = {
+static const struct SiS_LVDSData XGI_LVDSNoScalingData[] = {
{ 800, 449, 800, 449}, /* 00 (320x200,320x400,640x200,640x400) */
{ 800, 449, 800, 449}, /* 01 (320x350,640x350) */
{ 800, 449, 800, 449}, /* 02 (360x400,720x400) */
@@ -1262,7 +1250,7 @@ static struct SiS_LVDSData XGI_LVDSNoScalingData[] = {
{1688, 806, 1688, 806} /* 0A (1280x768x60Hz) */
};
-static struct SiS_LVDSData XGI_LVDS1024x768Data_1x75[] = {
+static const struct SiS_LVDSData XGI_LVDS1024x768Data_1x75[] = {
{ 960, 438, 1312, 800}, /* 00 (320x200,320x400,640x200,640x400) */
{ 960, 388, 1312, 800}, /* 01 (320x350,640x350) */
{1040, 438, 1312, 800}, /* 02 (360x400,720x400) */
@@ -1273,7 +1261,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Data_1x75[] = {
};
-static struct SiS_LVDSData XGI_LVDS1024x768Data_2x75[] = {
+static const struct SiS_LVDSData XGI_LVDS1024x768Data_2x75[] = {
{1312, 800, 1312, 800}, /* ; 00 (320x200,320x400,640x200,640x400) */
{1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */
{1312, 800, 1312, 800}, /* ; 02 (360x400,720x400) */
@@ -1283,7 +1271,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Data_2x75[] = {
{1312, 800, 1312, 800}, /* ; 06 (512x384,1024x768) */
};
-static struct SiS_LVDSData XGI_LVDS1280x1024Data_1x75[] = {
+static const struct SiS_LVDSData XGI_LVDS1280x1024Data_1x75[] = {
{1048, 442, 1688, 1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{1048, 392, 1688, 1066 }, /* ; 01 (320x350,640x350) */
{1128, 442, 1688, 1066 }, /* ; 02 (360x400,720x400) */
@@ -1294,7 +1282,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Data_1x75[] = {
{1688, 1066, 1688, 1066 }, /* ; 06; 07 (640x512,1280x1024) */
};
-static struct SiS_LVDSData XGI_LVDS1280x1024Data_2x75[] = {
+static const struct SiS_LVDSData XGI_LVDS1280x1024Data_2x75[] = {
{1688, 1066, 1688, 1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{1688, 1066, 1688, 1066 }, /* ; 01 (320x350,640x350) */
{1688, 1066, 1688, 1066 }, /* ; 02 (360x400,720x400) */
@@ -1305,7 +1293,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Data_2x75[] = {
{1688, 1066, 1688, 1066 }, /* ; 06; 07 (640x512,1280x1024) */
};
-static struct SiS_LVDSData XGI_LVDSNoScalingDatax75[] = {
+static const struct SiS_LVDSData XGI_LVDSNoScalingDatax75[] = {
{ 800, 449, 800, 449}, /* ; 00 (320x200,320x400,640x200,640x400) */
{ 800, 449, 800, 449}, /* ; 01 (320x350,640x350) */
{ 900, 449, 900, 449}, /* ; 02 (360x400,720x400) */
@@ -1320,7 +1308,7 @@ static struct SiS_LVDSData XGI_LVDSNoScalingDatax75[] = {
{1688, 806, 1688, 806}, /* ; 0A (1280x768x75Hz) */
};
-static struct SiS_LVDSData XGI_LVDS1024x768Des_1[] = {
+static const struct SiS_LVDSData XGI_LVDS1024x768Des_1[] = {
{0, 1048, 0, 771}, /* 00 (320x200,320x400,640x200,640x400) */
{0, 1048, 0, 771}, /* 01 (320x350,640x350) */
{0, 1048, 0, 771}, /* 02 (360x400,720x400) */
@@ -1330,7 +1318,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Des_1[] = {
{0, 1048, 805, 770} /* 06 (1024x768x60Hz) */
} ;
-static struct SiS_LVDSData XGI_LVDS1024x768Des_2[] = {
+static const struct SiS_LVDSData XGI_LVDS1024x768Des_2[] = {
{1142, 856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */
{1142, 856, 597, 562}, /* 01 (320x350,640x350) */
{1142, 856, 622, 587}, /* 02 (360x400,720x400) */
@@ -1340,7 +1328,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Des_2[] = {
{ 0, 1048, 805, 771} /* 06 (1024x768x60Hz) */
};
-static struct SiS_LVDSData XGI_LVDS1024x768Des_3[] = {
+static const struct SiS_LVDSData XGI_LVDS1024x768Des_3[] = {
{320, 24, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */
{320, 24, 597, 562}, /* 01 (320x350,640x350) */
{320, 24, 622, 587}, /* 02 (360x400,720x400) */
@@ -1348,7 +1336,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Des_3[] = {
{320, 24, 722, 687} /* 04 (640x480x60Hz) */
};
-static struct SiS_LVDSData XGI_LVDS1280x1024Des_1[] = {
+static const struct SiS_LVDSData XGI_LVDS1280x1024Des_1[] = {
{0, 1328, 0, 1025}, /* 00 (320x200,320x400,640x200,640x400) */
{0, 1328, 0, 1025}, /* 01 (320x350,640x350) */
{0, 1328, 0, 1025}, /* 02 (360x400,720x400) */
@@ -1360,7 +1348,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Des_1[] = {
};
/* The Display setting for DE Mode Panel */
-static struct SiS_LVDSData XGI_LVDS1280x1024Des_2[] = {
+static const struct SiS_LVDSData XGI_LVDS1280x1024Des_2[] = {
{1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */
{1368, 1008, 729, 688}, /* 01 (320x350,640x350) */
{1408, 1048, 752, 711}, /* 02 (360x400,720x400) */
@@ -1371,7 +1359,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Des_2[] = {
{0000, 1328, 0, 1025} /* 07 (1280x1024x60Hz) */
};
-static struct SiS_LVDSData XGI_LVDS1400x1050Des_1[] = {
+static const struct SiS_LVDSData XGI_LVDS1400x1050Des_1[] = {
{0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */
{0, 1448, 0, 1051}, /* 01 (320x350,640x350) */
{0, 1448, 0, 1051}, /* 02 (360x400,720x400) */
@@ -1383,7 +1371,7 @@ static struct SiS_LVDSData XGI_LVDS1400x1050Des_1[] = {
{0, 1448, 0, 1051} /* 08 (1400x1050x60Hz) */
};
-static struct SiS_LVDSData XGI_LVDS1400x1050Des_2[] = {
+static const struct SiS_LVDSData XGI_LVDS1400x1050Des_2[] = {
{1308, 1068, 781, 766}, /* 00 (320x200,320x400,640x200,640x400) */
{1308, 1068, 781, 766}, /* 01 (320x350,640x350) */
{1308, 1068, 781, 766}, /* 02 (360x400,720x400) */
@@ -1395,7 +1383,7 @@ static struct SiS_LVDSData XGI_LVDS1400x1050Des_2[] = {
{ 0, 1448, 0, 1051} /* 08 (1400x1050x60Hz) */
};
-static struct SiS_LVDSData XGI_LVDS1600x1200Des_1[] = {
+static const struct SiS_LVDSData XGI_LVDS1600x1200Des_1[] = {
{0, 1664, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */
{0, 1664, 0, 1201}, /* 01 (320x350,640x350) */
{0, 1664, 0, 1201}, /* 02 (360x400,720x400) */
@@ -1408,7 +1396,7 @@ static struct SiS_LVDSData XGI_LVDS1600x1200Des_1[] = {
{0, 1664, 0, 1201} /* 09 (1600x1200x60Hz) */
};
-static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] = {
+static const struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] = {
{0, 648, 448, 405, 96, 2}, /* 00 (320x200,320x400,
640x200,640x400) */
{0, 648, 448, 355, 96, 2}, /* 01 (320x350,640x350) */
@@ -1424,7 +1412,7 @@ static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] = {
};
/* ; 1024x768 Full-screen */
-static struct SiS_LVDSData XGI_LVDS1024x768Des_1x75[] = {
+static const struct SiS_LVDSData XGI_LVDS1024x768Des_1x75[] = {
{0, 1040, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */
{0, 1040, 0, 769}, /* ; 01 (320x350,640x350) */
{0, 1040, 0, 769}, /* ; 02 (360x400,720x400) */
@@ -1435,7 +1423,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Des_1x75[] = {
};
/* ; 1024x768 center-screen (Enh. Mode) */
-static struct SiS_LVDSData XGI_LVDS1024x768Des_2x75[] = {
+static const struct SiS_LVDSData XGI_LVDS1024x768Des_2x75[] = {
{1142, 856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */
{1142, 856, 597, 562}, /* 01 (320x350,640x350) */
{1142, 856, 622, 587}, /* 02 (360x400,720x400) */
@@ -1446,7 +1434,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Des_2x75[] = {
};
/* ; 1024x768 center-screen (St.Mode) */
-static struct SiS_LVDSData XGI_LVDS1024x768Des_3x75[] = {
+static const struct SiS_LVDSData XGI_LVDS1024x768Des_3x75[] = {
{320, 24, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */
{320, 24, 597, 562}, /* ; 01 (320x350,640x350) */
{320, 24, 622, 587}, /* ; 02 (360x400,720x400) */
@@ -1454,7 +1442,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Des_3x75[] = {
{320, 24, 722, 687} /* ; 04 (640x480x60Hz) */
};
-static struct SiS_LVDSData XGI_LVDS1280x1024Des_1x75[] = {
+static const struct SiS_LVDSData XGI_LVDS1280x1024Des_1x75[] = {
{0, 1296, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
{0, 1296, 0, 1025}, /* ; 01 (320x350,640x350) */
{0, 1296, 0, 1025}, /* ; 02 (360x400,720x400) */
@@ -1467,7 +1455,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Des_1x75[] = {
/* The Display setting for DE Mode Panel */
/* Set DE as default */
-static struct SiS_LVDSData XGI_LVDS1280x1024Des_2x75[] = {
+static const struct SiS_LVDSData XGI_LVDS1280x1024Des_2x75[] = {
{1368, 976, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */
{1368, 976, 729, 688}, /* ; 01 (320x350,640x350) */
{1408, 976, 752, 711}, /* ; 02 (360x400,720x400) */
@@ -1479,7 +1467,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Des_2x75[] = {
};
/* Scaling LCD 75Hz */
-static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = {
+static const struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = {
{0, 648, 448, 405, 96, 2}, /* ; 00 (320x200,320x400,
640x200,640x400) */
{0, 648, 448, 355, 96, 2}, /* ; 01 (320x350,640x350) */
@@ -1495,7 +1483,7 @@ static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = {
};
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_H[] = {
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_H[] = {
{ {0x4B, 0x27, 0x8F, 0x32, 0x1B, 0x00, 0x45, 0x00} }, /* 00 (320x) */
{ {0x4B, 0x27, 0x8F, 0x2B, 0x03, 0x00, 0x44, 0x00} }, /* 01 (360x) */
{ {0x55, 0x31, 0x99, 0x46, 0x1D, 0x00, 0x55, 0x00} }, /* 02 (400x) */
@@ -1507,7 +1495,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_H[] = {
};
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_H[] = {
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_H[] = {
{ {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00 } }, /* 00 (320x) */
{ {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00 } }, /* 01 (360x) */
{ {0x60, 0x31, 0x84, 0x3A, 0x88, 0x00, 0x01, 0x00 } }, /* 02 (400x) */
@@ -1520,7 +1508,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_H[] = {
};
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_H[] = {
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_H[] = {
{ {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} }, /* 00 (320x) */
{ {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} }, /* 01 (360x) */
{ {0x63, 0x31, 0x87, 0x3D, 0x8E, 0x00, 0x01, 0x00} }, /* 02 (400x) */
@@ -1532,7 +1520,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_H[] = {
};
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_H[] = {
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_H[] = {
{ {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} }, /* 00 (320x) */
{ {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} }, /* 01 (360x) */
{ {0x7E, 0x40, 0x84, 0x49, 0x91, 0x00, 0x01, 0x00} }, /* 02 (400x) */
@@ -1545,7 +1533,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_H[] = {
};
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] = {
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] = {
{ {0x47, 0x27, 0x8B, 0x2C, 0x1A, 0x00, 0x05, 0x00} }, /* 00 (320x) */
{ {0x47, 0x27, 0x8B, 0x30, 0x1E, 0x00, 0x05, 0x00} }, /* 01 (360x) */
{ {0x51, 0x31, 0x95, 0x36, 0x04, 0x00, 0x01, 0x00} }, /* 02 (400x) */
@@ -1559,7 +1547,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] = {
};
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] = {
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] = {
{ {0x76, 0x3F, 0x83, 0x45, 0x8C, 0x00, 0x41, 0x00} }, /* 00 (320x) */
{ {0x76, 0x3F, 0x83, 0x45, 0x8C, 0x00, 0x41, 0x00} }, /* 01 (360x) */
{ {0x76, 0x31, 0x9A, 0x48, 0x9F, 0x00, 0x41, 0x00} }, /* 02 (400x) */
@@ -1574,7 +1562,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] = {
/* ;302lv channelA [ycchen] 12/05/02 LCDHT=2048 */
/* ; CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] = {
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] = {
{ {0x5B, 0x27, 0x9F, 0x32, 0x0A, 0x00, 0x01, 0x00} }, /* 00 (320x) */
{ {0x5B, 0x27, 0x9F, 0x32, 0x0A, 0x00, 0x01, 0x00} }, /* 01 (360x) */
{ {0x65, 0x31, 0x89, 0x3C, 0x94, 0x00, 0x01, 0x00} }, /* 02 (400x) */
@@ -1589,7 +1577,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] = {
};
/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] = {
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] = {
{ {0x97, 0x1F, 0x60, 0x87, 0x5D, 0x83, 0x10} }, /* 00 (x350) */
{ {0xB4, 0x1F, 0x92, 0x89, 0x8F, 0xB5, 0x30} }, /* 01 (x400) */
{ {0x04, 0x3E, 0xE2, 0x89, 0xDF, 0x05, 0x00} }, /* 02 (x480) */
@@ -1598,7 +1586,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] = {
};
/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] = {
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] = {
{ {0x24, 0xBB, 0x31, 0x87, 0x5D, 0x25, 0x30} }, /* 00 (x350) */
{ {0x24, 0xBB, 0x4A, 0x80, 0x8F, 0x25, 0x30} }, /* 01 (x400) */
{ {0x24, 0xBB, 0x72, 0x88, 0xDF, 0x25, 0x30} }, /* 02 (x480) */
@@ -1607,7 +1595,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] = {
};
/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] = {
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] = {
{ {0x86, 0x1F, 0x5E, 0x82, 0x5D, 0x87, 0x00} }, /* 00 (x350) */
{ {0xB8, 0x1F, 0x90, 0x84, 0x8F, 0xB9, 0x30} }, /* 01 (x400) */
{ {0x08, 0x3E, 0xE0, 0x84, 0xDF, 0x09, 0x00} }, /* 02 (x480) */
@@ -1617,7 +1605,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] = {
};
/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] = {
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] = {
{ {0x28, 0xD2, 0xAF, 0x83, 0xAE, 0xD8, 0xA1} }, /* 00 (x350) */
{ {0x28, 0xD2, 0xC8, 0x8C, 0xC7, 0xF2, 0x81} }, /* 01 (x400) */
{ {0x28, 0xD2, 0xF0, 0x84, 0xEF, 0x1A, 0xB1} }, /* 02 (x480) */
@@ -1627,7 +1615,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] = {
};
/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] = {
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] = {
{ {0x6C, 0x1F, 0x60, 0x84, 0x5D, 0x6D, 0x10} }, /* 00 (x350) */
{ {0x9E, 0x1F, 0x93, 0x86, 0x8F, 0x9F, 0x30} }, /* 01 (x400) */
{ {0xEE, 0x1F, 0xE2, 0x86, 0xDF, 0xEF, 0x10} }, /* 02 (x480) */
@@ -1638,7 +1626,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] = {
};
/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] = {
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] = {
{ {0x28, 0x92, 0xB6, 0x83, 0xB5, 0xCF, 0x81} }, /* 00 (x350) */
{ {0x28, 0x92, 0xD5, 0x82, 0xD4, 0xEE, 0x81} }, /* 01 (x400) */
{ {0x28, 0x92, 0xFD, 0x8A, 0xFC, 0x16, 0xB1} }, /* 02 (x480) */
@@ -1649,7 +1637,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] = {
};
/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] = {
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] = {
{ {0xd4, 0x1F, 0x81, 0x84, 0x5D, 0xd5, 0x10} }, /* 00 (x350) */
{ {0x06, 0x3e, 0xb3, 0x86, 0x8F, 0x07, 0x20} }, /* 01 (x400) */
{ {0x56, 0xba, 0x03, 0x86, 0xDF, 0x57, 0x00} }, /* 02 (x480) */
@@ -1661,7 +1649,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] = {
};
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] = {
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] = {
{ {0x4B, 0x27, 0x8F, 0x32, 0x1B, 0x00, 0x45, 0x00} },/* ; 00 (320x) */
{ {0x4B, 0x27, 0x8F, 0x2B, 0x03, 0x00, 0x44, 0x00} },/* ; 01 (360x) */
{ {0x55, 0x31, 0x99, 0x46, 0x1D, 0x00, 0x55, 0x00} },/* ; 02 (400x) */
@@ -1673,7 +1661,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] = {
};
/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] = {
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] = {
{ {0x97, 0x1F, 0x60, 0x87, 0x5D, 0x83, 0x10} },/* ; 00 (x350) */
{ {0xB4, 0x1F, 0x92, 0x89, 0x8F, 0xB5, 0x30} },/* ; 01 (x400) */
{ {0xFE, 0x1F, 0xE0, 0x84, 0xDF, 0xFF, 0x10} },/* ; 02 (x480) */
@@ -1682,7 +1670,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] = {
};
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] = {
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] = {
{ {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} },/* ; 00 (320x) */
{ {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} },/* ; 01 (360x) */
{ {0x63, 0x31, 0x87, 0x3D, 0x8E, 0x00, 0x01, 0x00} },/* ; 02 (400x) */
@@ -1694,7 +1682,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] = {
};
/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] = {
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] = {
{ {0x24, 0xBB, 0x31, 0x87, 0x5D, 0x25, 0x30} },/* ; 00 (x350) */
{ {0x24, 0xBB, 0x4A, 0x80, 0x8F, 0x25, 0x30} },/* ; 01 (x400) */
{ {0x24, 0xBB, 0x72, 0x88, 0xDF, 0x25, 0x30} },/* ; 02 (x480) */
@@ -1703,7 +1691,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] = {
};
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] = {
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] = {
{ {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00} },/* ; 00 (320x) */
{ {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00} },/* ; 01 (360x) */
{ {0x60, 0x31, 0x84, 0x3A, 0x88, 0x00, 0x01, 0x00} },/* ; 02 (400x) */
@@ -1716,7 +1704,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] = {
};
/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] = {
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] = {
{ {0x86, 0xD1, 0xBC, 0x80, 0xBB, 0xE5, 0x00} },/* ; 00 (x350) */
{ {0xB8, 0x1F, 0x90, 0x84, 0x8F, 0xB9, 0x30} },/* ; 01 (x400) */
{ {0x08, 0x3E, 0xE0, 0x84, 0xDF, 0x09, 0x00} },/* ; 02 (x480) */
@@ -1725,7 +1713,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] = {
{ {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* ; 05 (x1024) */
};
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] = {
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] = {
{ {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} },/* ; 00 (320x) */
{ {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} },/* ; 01 (360x) */
{ {0x7E, 0x40, 0x84, 0x49, 0x91, 0x00, 0x01, 0x00} },/* ; 02 (400x) */
@@ -1738,7 +1726,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] = {
};
/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] = {
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] = {
{ {0x28, 0xD2, 0xAF, 0x83, 0xAE, 0xD8, 0xA1} },/* ; 00 (x350) */
{ {0x28, 0xD2, 0xC8, 0x8C, 0xC7, 0xF2, 0x81} },/* ; 01 (x400) */
{ {0x28, 0xD2, 0xF0, 0x84, 0xEF, 0x1A, 0xB1} },/* ; 02 (x480) */
@@ -1748,115 +1736,141 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] = {
};
/*add for new UNIVGABIOS*/
-static struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] = {
- {Panel_1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCD1024x768Data */
- {Panel_1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCD1024x768Data */
- {Panel_1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCD1024x768Data */
- {Panel_1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCD1280x1024Data */
- {Panel_1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCD1280x1024Data */
- {Panel_1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCD1280x1024Data */
- {Panel_1400x1050, 0x0019, 0x0001, 6}, /* XGI_ExtLCD1400x1050Data */
- {Panel_1400x1050, 0x0019, 0x0000, 7}, /* XGI_StLCD1400x1050Data */
- {Panel_1400x1050, 0x0018, 0x0010, 8}, /* XGI_CetLCD1400x1050Data */
- {Panel_1600x1200, 0x0019, 0x0001, 9}, /* XGI_ExtLCD1600x1200Data */
- {Panel_1600x1200, 0x0019, 0x0000, 10}, /* XGI_StLCD1600x1200Data */
- {PanelRef60Hz, 0x0008, 0x0008, 11}, /* XGI_NoScalingData */
- {Panel_1024x768x75, 0x0019, 0x0001, 12}, /* XGI_ExtLCD1024x768x75Data */
- {Panel_1024x768x75, 0x0019, 0x0000, 13}, /* XGI_StLCD1024x768x75Data */
- {Panel_1024x768x75, 0x0018, 0x0010, 14}, /* XGI_CetLCD1024x768x75Data */
- /* XGI_ExtLCD1280x1024x75Data */
- {Panel_1280x1024x75, 0x0019, 0x0001, 15},
- /* XGI_StLCD1280x1024x75Data */
- {Panel_1280x1024x75, 0x0019, 0x0000, 16},
- /* XGI_CetLCD1280x1024x75Data */
- {Panel_1280x1024x75, 0x0018, 0x0010, 17},
- {PanelRef75Hz, 0x0008, 0x0008, 18}, /* XGI_NoScalingDatax75 */
- {0xFF, 0x0000, 0x0000, 0} /* End of table */
-};
-
-static struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] = {
- {Panel_1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCDDes1024x768Data */
- {Panel_1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCDDes1024x768Data */
- {Panel_1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCDDes1024x768Data */
- {Panel_1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCDDes1280x1024Data */
- {Panel_1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCDDes1280x1024Data */
- {Panel_1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCDDes1280x1024Data */
- {Panel_1400x1050, 0x0019, 0x0001, 6}, /* XGI_ExtLCDDes1400x1050Data */
- {Panel_1400x1050, 0x0019, 0x0000, 7}, /* XGI_StLCDDes1400x1050Data */
- {Panel_1400x1050, 0x0418, 0x0010, 8}, /* XGI_CetLCDDes1400x1050Data */
- {Panel_1400x1050, 0x0418, 0x0410, 9}, /* XGI_CetLCDDes1400x1050Data2 */
- {Panel_1600x1200, 0x0019, 0x0001, 10}, /* XGI_ExtLCDDes1600x1200Data */
- {Panel_1600x1200, 0x0019, 0x0000, 11}, /* XGI_StLCDDes1600x1200Data */
- {PanelRef60Hz, 0x0008, 0x0008, 12}, /* XGI_NoScalingDesData */
- /* XGI_ExtLCDDes1024x768x75Data */
- {Panel_1024x768x75, 0x0019, 0x0001, 13},
- /* XGI_StLCDDes1024x768x75Data */
- {Panel_1024x768x75, 0x0019, 0x0000, 14},
- /* XGI_CetLCDDes1024x768x75Data */
- {Panel_1024x768x75, 0x0018, 0x0010, 15},
- /* XGI_ExtLCDDes1280x1024x75Data */
- {Panel_1280x1024x75, 0x0019, 0x0001, 16},
- /* XGI_StLCDDes1280x1024x75Data */
- {Panel_1280x1024x75, 0x0019, 0x0000, 17},
- /* XGI_CetLCDDes1280x1024x75Data */
- {Panel_1280x1024x75, 0x0018, 0x0010, 18},
- {PanelRef75Hz, 0x0008, 0x0008, 19}, /* XGI_NoScalingDesDatax75 */
- {0xFF, 0x0000, 0x0000, 0}
-};
-
-static struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1[] = {
- {Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDSCRT11024x768_1 */
- {Panel_1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDSCRT11024x768_2 */
- {Panel_1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDSCRT11280x1024_1 */
- {Panel_1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDSCRT11280x1024_2 */
- {Panel_1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDSCRT11400x1050_1 */
- {Panel_1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDSCRT11400x1050_2 */
- {Panel_1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDSCRT11600x1200_1 */
- {Panel_1024x768x75, 0x0018, 0x0000, 7}, /* XGI_LVDSCRT11024x768_1x75 */
- {Panel_1024x768x75, 0x0018, 0x0010, 8}, /* XGI_LVDSCRT11024x768_2x75 */
- {Panel_1280x1024x75, 0x0018, 0x0000, 9}, /*XGI_LVDSCRT11280x1024_1x75*/
- {Panel_1280x1024x75, 0x0018, 0x0010, 10},/*XGI_LVDSCRT11280x1024_2x75*/
- {0xFF, 0x0000, 0x0000, 0}
-};
-
-static struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] = {
- {Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDS1024x768Data_1 */
- {Panel_1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDS1024x768Data_2 */
- {Panel_1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDS1280x1024Data_1 */
- {Panel_1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDS1280x1024Data_2 */
- {Panel_1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDS1400x1050Data_1 */
- {Panel_1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDS1400x1050Data_2 */
- {Panel_1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDS1600x1200Data_1 */
- {PanelRef60Hz, 0x0008, 0x0008, 7}, /* XGI_LVDSNoScalingData */
- {Panel_1024x768x75, 0x0018, 0x0000, 8}, /* XGI_LVDS1024x768Data_1x75 */
- {Panel_1024x768x75, 0x0018, 0x0010, 9}, /* XGI_LVDS1024x768Data_2x75 */
- /* XGI_LVDS1280x1024Data_1x75 */
- {Panel_1280x1024x75, 0x0018, 0x0000, 10},
- /* XGI_LVDS1280x1024Data_2x75 */
- {Panel_1280x1024x75, 0x0018, 0x0010, 11},
- {PanelRef75Hz, 0x0008, 0x0008, 12}, /* XGI_LVDSNoScalingDatax75 */
- {0xFF, 0x0000, 0x0000, 0}
-};
-
-static struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] = {
- {Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDS1024x768Des_1 */
- {Panel_1024x768, 0x0618, 0x0410, 1}, /* XGI_LVDS1024x768Des_3 */
- {Panel_1024x768, 0x0018, 0x0010, 2}, /* XGI_LVDS1024x768Des_2 */
- {Panel_1280x1024, 0x0018, 0x0000, 3}, /* XGI_LVDS1280x1024Des_1 */
- {Panel_1280x1024, 0x0018, 0x0010, 4}, /* XGI_LVDS1280x1024Des_2 */
- {Panel_1400x1050, 0x0018, 0x0000, 5}, /* XGI_LVDS1400x1050Des_1 */
- {Panel_1400x1050, 0x0018, 0x0010, 6}, /* XGI_LVDS1400x1050Des_2 */
- {Panel_1600x1200, 0x0018, 0x0000, 7}, /* XGI_LVDS1600x1200Des_1 */
- {PanelRef60Hz, 0x0008, 0x0008, 8}, /* XGI_LVDSNoScalingDesData */
- {Panel_1024x768x75, 0x0018, 0x0000, 9}, /* XGI_LVDS1024x768Des_1x75 */
- {Panel_1024x768x75, 0x0618, 0x0410, 10}, /* XGI_LVDS1024x768Des_3x75 */
- {Panel_1024x768x75, 0x0018, 0x0010, 11}, /* XGI_LVDS1024x768Des_2x75 */
- /* XGI_LVDS1280x1024Des_1x75 */
- {Panel_1280x1024x75, 0x0018, 0x0000, 12},
- /* XGI_LVDS1280x1024Des_2x75 */
- {Panel_1280x1024x75, 0x0018, 0x0010, 13},
- {PanelRef75Hz, 0x0008, 0x0008, 14}, /* XGI_LVDSNoScalingDesDatax75 */
- {0xFF, 0x0000, 0x0000, 0}
+static const struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] = {
+ {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCD1024x768Data },
+ {Panel_1024x768, 0x0019, 0x0000, XGI_StLCD1024x768Data },
+ {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCD1024x768Data },
+ {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCD1280x1024Data },
+ {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCD1280x1024Data },
+ {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCD1280x1024Data },
+ {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcd_1400x1050 },
+ {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcd_1400x1050 },
+ {Panel_1400x1050, 0x0018, 0x0010, XGI_CetLCD1400x1050Data },
+ {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCD1600x1200Data },
+ {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCD1600x1200Data },
+ {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingData },
+ {Panel_1024x768x75, 0x0019, 0x0001, XGI_ExtLCD1024x768x75Data },
+ {Panel_1024x768x75, 0x0019, 0x0000, XGI_ExtLCD1024x768x75Data },
+ {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCD1024x768x75Data },
+ {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcd_1280x1024x75 },
+ {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcd_1280x1024x75 },
+ {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCD1280x1024x75Data },
+ {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDatax75 },
+ {0xFF, 0x0000, 0x0000, NULL } /* End of table */
+};
+
+static const struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] = {
+ {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCDDes1024x768Data },
+ {Panel_1024x768, 0x0019, 0x0000, XGI_StLCDDes1024x768Data },
+ {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCDDes1024x768Data },
+ {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCDDes1280x1024Data },
+ {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCDDes1280x1024Data },
+ {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCDDes1280x1024Data },
+ {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcddes_1400x1050 },
+ {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcddes_1400x1050 },
+ {Panel_1400x1050, 0x0418, 0x0010, XGI_CetLCDDes1400x1050Data },
+ {Panel_1400x1050, 0x0418, 0x0410, XGI_CetLCDDes1400x1050Data2 },
+ {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCDDes1600x1200Data },
+ {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCDDes1600x1200Data },
+ {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingDesData },
+ {Panel_1024x768x75, 0x0019, 0x0001, xgifb_lcddes_1024x768x75 },
+ {Panel_1024x768x75, 0x0019, 0x0000, xgifb_lcddes_1024x768x75 },
+ {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCDDes1024x768x75Data },
+ {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcddes_1280x1024x75 },
+ {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcddes_1280x1024x75 },
+ {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCDDes1280x1024x75Data },
+ {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDesDatax75 },
+ {0xFF, 0x0000, 0x0000, NULL }
+};
+
+static const struct XGI330_LCDDataTablStruct xgifb_lcddldes[] = {
+ {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCDDes1024x768Data },
+ {Panel_1024x768, 0x0019, 0x0000, XGI_StLCDDes1024x768Data },
+ {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCDDes1024x768Data },
+ {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCDDLDes1280x1024Data },
+ {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCDDLDes1280x1024Data },
+ {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCDDLDes1280x1024Data },
+ {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcddldes_1400x1050 },
+ {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcddldes_1400x1050 },
+ {Panel_1400x1050, 0x0418, 0x0010, XGI_CetLCDDes1400x1050Data },
+ {Panel_1400x1050, 0x0418, 0x0410, XGI_CetLCDDes1400x1050Data2 },
+ {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCDDLDes1600x1200Data },
+ {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCDDLDes1600x1200Data },
+ {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingDesData },
+ {Panel_1024x768x75, 0x0019, 0x0001, xgifb_lcddes_1024x768x75 },
+ {Panel_1024x768x75, 0x0019, 0x0000, xgifb_lcddes_1024x768x75 },
+ {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCDDes1024x768x75Data },
+ {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcddldes_1280x1024x75 },
+ {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcddldes_1280x1024x75 },
+ {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCDDLDes1280x1024x75Data },
+ {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDesDatax75 },
+ {0xFF, 0x0000, 0x0000, NULL }
+};
+
+static const struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_h[] = {
+ {Panel_1024x768, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_H },
+ {Panel_1024x768, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_H },
+ {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_H },
+ {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_H },
+ {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDSCRT11400x1050_1_H },
+ {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDSCRT11400x1050_2_H },
+ {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDSCRT11600x1200_1_H },
+ {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_Hx75 },
+ {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_Hx75 },
+ {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_Hx75 },
+ {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_Hx75 },
+ {0xFF, 0x0000, 0x0000, NULL }
+};
+
+static const struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_v[] = {
+ {Panel_1024x768, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_V },
+ {Panel_1024x768, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_V },
+ {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_V },
+ {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_V },
+ {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDSCRT11400x1050_1_V },
+ {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDSCRT11400x1050_2_V },
+ {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDSCRT11600x1200_1_V },
+ {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_Vx75 },
+ {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_Vx75 },
+ {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_Vx75 },
+ {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_Vx75 },
+ {0xFF, 0x0000, 0x0000, NULL }
+};
+
+static const struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] = {
+ {Panel_1024x768, 0x0018, 0x0000, XGI_LVDS1024x768Data_1 },
+ {Panel_1024x768, 0x0018, 0x0010, XGI_LVDS1024x768Data_2 },
+ {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDS1280x1024Data_1 },
+ {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDS1280x1024Data_2 },
+ {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDS1400x1050Data_1 },
+ {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDS1400x1050Data_2 },
+ {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDS1600x1200Data_1 },
+ {PanelRef60Hz, 0x0008, 0x0008, XGI_LVDSNoScalingData },
+ {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDS1024x768Data_1x75 },
+ {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDS1024x768Data_2x75 },
+ {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDS1280x1024Data_1x75 },
+ {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDS1280x1024Data_2x75 },
+ {PanelRef75Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDatax75 },
+ {0xFF, 0x0000, 0x0000, NULL }
+};
+
+static const struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] = {
+ {Panel_1024x768, 0x0018, 0x0000, XGI_LVDS1024x768Des_1 },
+ {Panel_1024x768, 0x0618, 0x0410, XGI_LVDS1024x768Des_3 },
+ {Panel_1024x768, 0x0018, 0x0010, XGI_LVDS1024x768Des_2 },
+ {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDS1280x1024Des_1 },
+ {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDS1280x1024Des_2 },
+ {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDS1400x1050Des_1 },
+ {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDS1400x1050Des_2 },
+ {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDS1600x1200Des_1 },
+ {PanelRef60Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDesData },
+ {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDS1024x768Des_1x75 },
+ {Panel_1024x768x75, 0x0618, 0x0410, XGI_LVDS1024x768Des_3x75 },
+ {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDS1024x768Des_2x75 },
+ {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDS1280x1024Des_1x75 },
+ {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDS1280x1024Des_2x75 },
+ {PanelRef75Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDesDatax75 },
+ {0xFF, 0x0000, 0x0000, NULL }
};
static const struct XGI330_TVDataTablStruct XGI_TVDataTable[] = {
@@ -1877,7 +1891,7 @@ static const struct XGI330_TVDataTablStruct XGI_TVDataTable[] = {
};
/* Dual link only */
-static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = {
+static const struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = {
/* LCDCap1024x768 */
{Panel_1024x768, DefaultLCDCap, 0, 0x88, 0x06, VCLK65_315,
0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
@@ -1912,7 +1926,7 @@ static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = {
0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
};
-static struct XGI330_LCDCapStruct XGI_LCDCapList[] = {
+static const struct XGI330_LCDCapStruct XGI_LCDCapList[] = {
/* LCDCap1024x768 */
{Panel_1024x768, DefaultLCDCap, 0, 0x88, 0x06, VCLK65_315,
0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
@@ -1947,7 +1961,7 @@ static struct XGI330_LCDCapStruct XGI_LCDCapList[] = {
0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
};
-static struct XGI_Ext2Struct XGI330_RefIndex[] = {
+const struct XGI_Ext2Struct XGI330_RefIndex[] = {
{Mode32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175,
0x00, 0x10, 0x59, 320, 200},/* 00 */
{Mode32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175,
@@ -2101,21 +2115,13 @@ static struct XGI_Ext2Struct XGI330_RefIndex[] = {
0x30, 0x47, 0x37, 1024, 768},/* 48 1024x768x160Hz */
};
-static unsigned char XGI330_ScreenOffset[] = {
+static const unsigned char XGI330_ScreenOffset[] = {
0x14, 0x19, 0x20, 0x28, 0x32, 0x40,
0x50, 0x64, 0x78, 0x80, 0x2d, 0x35,
0x57, 0x48
};
-static struct SiS_StResInfo_S XGI330_StResInfo[] = {
- {640, 400},
- {640, 350},
- {720, 400},
- {720, 350},
- {640, 480}
-};
-
-static struct SiS_ModeResInfo_S XGI330_ModeResInfo[] = {
+static const struct SiS_ModeResInfo_S XGI330_ModeResInfo[] = {
{ 320, 200, 8, 8},
{ 320, 240, 8, 8},
{ 320, 400, 8, 8},
@@ -2141,7 +2147,7 @@ static struct SiS_ModeResInfo_S XGI330_ModeResInfo[] = {
{1152, 864, 8, 16}
};
-static struct SiS_VCLKData XGI_VCLKData[] = {
+const struct SiS_VCLKData XGI_VCLKData[] = {
/* SR2B,SR2C,SR2D */
{0x1B, 0xE1, 25}, /* 00 (25.175MHz) */
{0x4E, 0xE4, 28}, /* 01 (28.322MHz) */
@@ -2234,7 +2240,7 @@ static struct SiS_VCLKData XGI_VCLKData[] = {
{0xFF, 0x00, 0} /* End mark */
};
-static struct SiS_VBVCLKData XGI_VBVCLKData[] = {
+static const struct SiS_VBVCLKData XGI_VBVCLKData[] = {
{0x1B, 0xE1, 25}, /* 00 (25.175MHz) */
{0x4E, 0xE4, 28}, /* 01 (28.322MHz) */
{0x57, 0xE4, 31}, /* 02 (31.500MHz) */
@@ -2329,7 +2335,7 @@ static struct SiS_VBVCLKData XGI_VBVCLKData[] = {
#define XGI301TVDelay 0x22
#define XGI301LCDDelay 0x12
-static unsigned char TVAntiFlickList[] = {/* NTSCAntiFlicker */
+static const unsigned char TVAntiFlickList[] = {/* NTSCAntiFlicker */
0x04, /* ; 0 Adaptive */
0x00, /* ; 1 new anti-flicker ? */
@@ -2341,7 +2347,7 @@ static unsigned char TVAntiFlickList[] = {/* NTSCAntiFlicker */
};
-static unsigned char TVEdgeList[] = {
+static const unsigned char TVEdgeList[] = {
0x00, /* ; 0 NTSC No Edge enhance */
0x04, /* ; 1 NTSC Adaptive Edge enhance */
0x00, /* ; 0 PAL No Edge enhance */
@@ -2350,7 +2356,7 @@ static unsigned char TVEdgeList[] = {
0x00 /* ; 1 HiTV */
};
-static unsigned long TVPhaseList[] = {
+static const unsigned long TVPhaseList[] = {
0x08BAED21, /* ; 0 NTSC phase */
0x00E3052A, /* ; 1 PAL phase */
0x9B2EE421, /* ; 2 PAL-M phase */
@@ -2367,7 +2373,7 @@ static unsigned long TVPhaseList[] = {
0xE00A831E /* ; D PAL-M 1024x768 */
};
-static unsigned char NTSCYFilter1[] = {
+static const unsigned char NTSCYFilter1[] = {
0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */
0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */
0xEB, 0x04, 0x25, 0x18, /* 2 : 640x text mode */
@@ -2377,7 +2383,7 @@ static unsigned char NTSCYFilter1[] = {
0xEB, 0x15, 0x25, 0xF6 /* 6 : 800x gra. mode */
};
-static unsigned char PALYFilter1[] = {
+static const unsigned char PALYFilter1[] = {
0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */
0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */
0xF1, 0xF7, 0x1F, 0x32, /* 2 : 640x text mode */
@@ -2387,7 +2393,7 @@ static unsigned char PALYFilter1[] = {
0xFC, 0xFB, 0x14, 0x2A /* 6 : 800x gra. mode */
};
-static unsigned char xgifb_palmn_yfilter1[] = {
+static const unsigned char xgifb_palmn_yfilter1[] = {
0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */
0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */
0xEB, 0x04, 0x10, 0x18, /* 2 : 640x text mode */
@@ -2398,7 +2404,7 @@ static unsigned char xgifb_palmn_yfilter1[] = {
0xFF, 0xFF, 0xFF, 0xFF /* End of Table */
};
-static unsigned char xgifb_yfilter2[] = {
+static const unsigned char xgifb_yfilter2[] = {
0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 0 : 320x text mode */
0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 1 : 360x text mode */
0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 2 : 640x text mode */
@@ -2409,13 +2415,13 @@ static unsigned char xgifb_yfilter2[] = {
0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28 /* 7 : 1024xgra. mode */
};
-static unsigned char XGI_NTSC1024AdjTime[] = {
+static const unsigned char XGI_NTSC1024AdjTime[] = {
0xa7, 0x07, 0xf2, 0x6e, 0x17, 0x8b, 0x73, 0x53,
0x13, 0x40, 0x34, 0xF4, 0x63, 0xBB, 0xCC, 0x7A,
0x58, 0xe4, 0x73, 0xd0, 0x13
};
-static struct XGI301C_Tap4TimingStruct xgifb_tap4_timing[] = {
+static const struct XGI301C_Tap4TimingStruct xgifb_tap4_timing[] = {
{0, {
0x00, 0x20, 0x00, 0x00, 0x7F, 0x20, 0x02, 0x7F, /* ; C0-C7 */
0x7D, 0x20, 0x04, 0x7F, 0x7D, 0x1F, 0x06, 0x7E, /* ; C8-CF */
@@ -2429,7 +2435,7 @@ static struct XGI301C_Tap4TimingStruct xgifb_tap4_timing[] = {
}
};
-static struct XGI301C_Tap4TimingStruct PALTap4Timing[] = {
+static const struct XGI301C_Tap4TimingStruct PALTap4Timing[] = {
{600, {
0x05, 0x19, 0x05, 0x7D, 0x03, 0x19, 0x06, 0x7E, /* ; C0-C7 */
0x02, 0x19, 0x08, 0x7D, 0x01, 0x18, 0x0A, 0x7D, /* ; C8-CF */
@@ -2465,7 +2471,7 @@ static struct XGI301C_Tap4TimingStruct PALTap4Timing[] = {
}
};
-static struct XGI301C_Tap4TimingStruct xgifb_ntsc_525_tap4_timing[] = {
+static const struct XGI301C_Tap4TimingStruct xgifb_ntsc_525_tap4_timing[] = {
{480, {
0x04, 0x1A, 0x04, 0x7E, 0x03, 0x1A, 0x06, 0x7D, /* ; C0-C7 */
0x01, 0x1A, 0x08, 0x7D, 0x00, 0x19, 0x0A, 0x7D, /* ; C8-CF */
@@ -2501,7 +2507,7 @@ static struct XGI301C_Tap4TimingStruct xgifb_ntsc_525_tap4_timing[] = {
}
};
-static struct XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[] = {
+static const struct XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[] = {
{0xFFFF, {
0x05, 0x19, 0x05, 0x7D, 0x03, 0x19, 0x06, 0x7E, /* ; C0-C7 */
0x02, 0x19, 0x08, 0x7D, 0x01, 0x18, 0x0A, 0x7D, /* ; C8-CF */
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index 6edefde2372..fb4a7c94aed 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -183,62 +183,25 @@ static inline int is_partial_io(struct bio_vec *bvec)
return bvec->bv_len != PAGE_SIZE;
}
-static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
- u32 index, int offset, struct bio *bio)
+static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
{
- int ret;
- size_t clen;
- struct page *page;
- unsigned char *user_mem, *cmem, *uncmem = NULL;
-
- page = bvec->bv_page;
-
- if (zram_test_flag(zram, index, ZRAM_ZERO)) {
- handle_zero_page(bvec);
- return 0;
- }
+ int ret = LZO_E_OK;
+ size_t clen = PAGE_SIZE;
+ unsigned char *cmem;
+ unsigned long handle = zram->table[index].handle;
- /* Requested page is not present in compressed area */
- if (unlikely(!zram->table[index].handle)) {
- pr_debug("Read before write: sector=%lu, size=%u",
- (ulong)(bio->bi_sector), bio->bi_size);
- handle_zero_page(bvec);
+ if (!handle || zram_test_flag(zram, index, ZRAM_ZERO)) {
+ memset(mem, 0, PAGE_SIZE);
return 0;
}
- if (is_partial_io(bvec)) {
- /* Use a temporary buffer to decompress the page */
- uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (!uncmem) {
- pr_info("Error allocating temp memory!\n");
- return -ENOMEM;
- }
- }
-
- user_mem = kmap_atomic(page);
- if (!is_partial_io(bvec))
- uncmem = user_mem;
- clen = PAGE_SIZE;
-
- cmem = zs_map_object(zram->mem_pool, zram->table[index].handle,
- ZS_MM_RO);
-
- if (zram->table[index].size == PAGE_SIZE) {
- memcpy(uncmem, cmem, PAGE_SIZE);
- ret = LZO_E_OK;
- } else {
+ cmem = zs_map_object(zram->mem_pool, handle, ZS_MM_RO);
+ if (zram->table[index].size == PAGE_SIZE)
+ memcpy(mem, cmem, PAGE_SIZE);
+ else
ret = lzo1x_decompress_safe(cmem, zram->table[index].size,
- uncmem, &clen);
- }
-
- if (is_partial_io(bvec)) {
- memcpy(user_mem + bvec->bv_offset, uncmem + offset,
- bvec->bv_len);
- kfree(uncmem);
- }
-
- zs_unmap_object(zram->mem_pool, zram->table[index].handle);
- kunmap_atomic(user_mem);
+ mem, &clen);
+ zs_unmap_object(zram->mem_pool, handle);
/* Should NEVER happen. Return bio error if it does. */
if (unlikely(ret != LZO_E_OK)) {
@@ -247,36 +210,56 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
return ret;
}
- flush_dcache_page(page);
-
return 0;
}
-static int zram_read_before_write(struct zram *zram, char *mem, u32 index)
+static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
+ u32 index, int offset, struct bio *bio)
{
int ret;
- size_t clen = PAGE_SIZE;
- unsigned char *cmem;
- unsigned long handle = zram->table[index].handle;
+ struct page *page;
+ unsigned char *user_mem, *uncmem = NULL;
- if (zram_test_flag(zram, index, ZRAM_ZERO) || !handle) {
- memset(mem, 0, PAGE_SIZE);
+ page = bvec->bv_page;
+
+ if (unlikely(!zram->table[index].handle) ||
+ zram_test_flag(zram, index, ZRAM_ZERO)) {
+ handle_zero_page(bvec);
return 0;
}
- cmem = zs_map_object(zram->mem_pool, handle, ZS_MM_RO);
- ret = lzo1x_decompress_safe(cmem, zram->table[index].size,
- mem, &clen);
- zs_unmap_object(zram->mem_pool, handle);
+ user_mem = kmap_atomic(page);
+ if (is_partial_io(bvec))
+ /* Use a temporary buffer to decompress the page */
+ uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ else
+ uncmem = user_mem;
+ if (!uncmem) {
+ pr_info("Unable to allocate temp memory\n");
+ ret = -ENOMEM;
+ goto out_cleanup;
+ }
+
+ ret = zram_decompress_page(zram, uncmem, index);
/* Should NEVER happen. Return bio error if it does. */
if (unlikely(ret != LZO_E_OK)) {
pr_err("Decompression failed! err=%d, page=%u\n", ret, index);
zram_stat64_inc(zram, &zram->stats.failed_reads);
- return ret;
+ goto out_cleanup;
}
- return 0;
+ if (is_partial_io(bvec))
+ memcpy(user_mem + bvec->bv_offset, uncmem + offset,
+ bvec->bv_len);
+
+ flush_dcache_page(page);
+ ret = 0;
+out_cleanup:
+ kunmap_atomic(user_mem);
+ if (is_partial_io(bvec))
+ kfree(uncmem);
+ return ret;
}
static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
@@ -302,7 +285,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
ret = -ENOMEM;
goto out;
}
- ret = zram_read_before_write(zram, uncmem, index);
+ ret = zram_decompress_page(zram, uncmem, index);
if (ret) {
kfree(uncmem);
goto out;
diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h
index 572c0b1551d..df2eec407db 100644
--- a/drivers/staging/zram/zram_drv.h
+++ b/drivers/staging/zram/zram_drv.h
@@ -39,8 +39,8 @@ static const size_t max_zpage_size = PAGE_SIZE / 4 * 3;
/*
* NOTE: max_zpage_size must be less than or equal to:
- * ZS_MAX_ALLOC_SIZE - sizeof(struct zobj_header)
- * otherwise, xv_malloc() would always return failure.
+ * ZS_MAX_ALLOC_SIZE. Otherwise, zs_malloc() would
+ * always return failure.
*/
/*-- End of configurable params */
diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c
index edb0ed4125d..de1eacf65db 100644
--- a/drivers/staging/zram/zram_sysfs.c
+++ b/drivers/staging/zram/zram_sysfs.c
@@ -15,6 +15,7 @@
#include <linux/device.h>
#include <linux/genhd.h>
#include <linux/mm.h>
+#include <linux/kernel.h>
#include "zram_drv.h"
@@ -54,13 +55,12 @@ static ssize_t disksize_show(struct device *dev,
static ssize_t disksize_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t len)
{
- int ret;
u64 disksize;
struct zram *zram = dev_to_zram(dev);
- ret = kstrtoull(buf, 10, &disksize);
- if (ret)
- return ret;
+ disksize = memparse(buf, NULL);
+ if (!disksize)
+ return -EINVAL;
down_write(&zram->init_lock);
if (zram->init_done) {
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 9097155e9eb..dcecbfb1724 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1819,8 +1819,10 @@ void target_execute_cmd(struct se_cmd *cmd)
/*
* If the received CDB has aleady been aborted stop processing it here.
*/
- if (transport_check_aborted_status(cmd, 1))
+ if (transport_check_aborted_status(cmd, 1)) {
+ complete(&cmd->t_transport_stop_comp);
return;
+ }
/*
* Determine if IOCTL context caller in requesting the stopping of this
@@ -3067,7 +3069,7 @@ void transport_send_task_abort(struct se_cmd *cmd)
unsigned long flags;
spin_lock_irqsave(&cmd->t_state_lock, flags);
- if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) {
+ if (cmd->se_cmd_flags & (SCF_SENT_CHECK_CONDITION | SCF_SENT_DELAYED_TAS)) {
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
return;
}
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 42d0a2581a8..9d7d00cdfec 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1771,6 +1771,7 @@ fail_free_irq:
fail_unregister:
tty_unregister_driver(serial_driver);
fail_put_tty_driver:
+ tty_port_destroy(&state->tport);
put_tty_driver(serial_driver);
return error;
}
@@ -1785,6 +1786,7 @@ static int __exit amiga_serial_remove(struct platform_device *pdev)
printk("SERIAL: failed to unregister serial driver (%d)\n",
error);
put_tty_driver(serial_driver);
+ tty_port_destroy(&state->tport);
free_irq(IRQ_AMIGA_TBE, state);
free_irq(IRQ_AMIGA_RBF, state);
diff --git a/drivers/tty/bfin_jtag_comm.c b/drivers/tty/bfin_jtag_comm.c
index 02b7d3a0969..1cfcdbf1d0c 100644
--- a/drivers/tty/bfin_jtag_comm.c
+++ b/drivers/tty/bfin_jtag_comm.c
@@ -240,8 +240,6 @@ static int __init bfin_jc_init(void)
{
int ret;
- tty_port_init(&port);
-
bfin_jc_kthread = kthread_create(bfin_jc_emudat_manager, NULL, DRV_NAME);
if (IS_ERR(bfin_jc_kthread))
return PTR_ERR(bfin_jc_kthread);
@@ -257,6 +255,8 @@ static int __init bfin_jc_init(void)
if (!bfin_jc_driver)
goto err_driver;
+ tty_port_init(&port);
+
bfin_jc_driver->driver_name = DRV_NAME;
bfin_jc_driver->name = DEV_NAME;
bfin_jc_driver->type = TTY_DRIVER_TYPE_SERIAL;
@@ -274,6 +274,7 @@ static int __init bfin_jc_init(void)
return 0;
err:
+ tty_port_destroy(&port);
put_tty_driver(bfin_jc_driver);
err_driver:
kfree(bfin_jc_write_buf.buf);
@@ -289,6 +290,7 @@ static void __exit bfin_jc_exit(void)
kfree(bfin_jc_write_buf.buf);
tty_unregister_driver(bfin_jc_driver);
put_tty_driver(bfin_jc_driver);
+ tty_port_destroy(&port);
}
module_exit(bfin_jc_exit);
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c
index 0a6a0bc1b59..b09c8d1f9a6 100644
--- a/drivers/tty/cyclades.c
+++ b/drivers/tty/cyclades.c
@@ -3099,7 +3099,7 @@ static const struct tty_port_operations cyz_port_ops = {
* ---------------------------------------------------------------------
*/
-static int __devinit cy_init_card(struct cyclades_card *cinfo)
+static int cy_init_card(struct cyclades_card *cinfo)
{
struct cyclades_port *info;
unsigned int channel, port;
@@ -3196,7 +3196,7 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
/* initialize chips on Cyclom-Y card -- return number of valid
chips (which is number of ports/4) */
-static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr,
+static unsigned short cyy_init_card(void __iomem *true_base_addr,
int index)
{
unsigned int chip_number;
@@ -3405,7 +3405,7 @@ static int __init cy_detect_isa(void)
} /* cy_detect_isa */
#ifdef CONFIG_PCI
-static inline int __devinit cyc_isfwstr(const char *str, unsigned int size)
+static inline int cyc_isfwstr(const char *str, unsigned int size)
{
unsigned int a;
@@ -3420,7 +3420,7 @@ static inline int __devinit cyc_isfwstr(const char *str, unsigned int size)
return 0;
}
-static inline void __devinit cyz_fpga_copy(void __iomem *fpga, const u8 *data,
+static inline void cyz_fpga_copy(void __iomem *fpga, const u8 *data,
unsigned int size)
{
for (; size > 0; size--) {
@@ -3429,7 +3429,7 @@ static inline void __devinit cyz_fpga_copy(void __iomem *fpga, const u8 *data,
}
}
-static void __devinit plx_init(struct pci_dev *pdev, int irq,
+static void plx_init(struct pci_dev *pdev, int irq,
struct RUNTIME_9060 __iomem *addr)
{
/* Reset PLX */
@@ -3449,7 +3449,7 @@ static void __devinit plx_init(struct pci_dev *pdev, int irq,
pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq);
}
-static int __devinit __cyz_load_fw(const struct firmware *fw,
+static int __cyz_load_fw(const struct firmware *fw,
const char *name, const u32 mailbox, void __iomem *base,
void __iomem *fpga)
{
@@ -3526,7 +3526,7 @@ static int __devinit __cyz_load_fw(const struct firmware *fw,
return 0;
}
-static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
+static int cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
struct RUNTIME_9060 __iomem *ctl_addr, int irq)
{
const struct firmware *fw;
@@ -3692,7 +3692,7 @@ err:
return retval;
}
-static int __devinit cy_pci_probe(struct pci_dev *pdev,
+static int cy_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct cyclades_card *card;
@@ -3931,10 +3931,10 @@ err:
return retval;
}
-static void __devexit cy_pci_remove(struct pci_dev *pdev)
+static void cy_pci_remove(struct pci_dev *pdev)
{
struct cyclades_card *cinfo = pci_get_drvdata(pdev);
- unsigned int i;
+ unsigned int i, channel;
/* non-Z with old PLX */
if (!cy_is_Z(cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) ==
@@ -3960,9 +3960,11 @@ static void __devexit cy_pci_remove(struct pci_dev *pdev)
pci_release_regions(pdev);
cinfo->base_addr = NULL;
- for (i = cinfo->first_line; i < cinfo->first_line +
- cinfo->nports; i++)
+ for (channel = 0, i = cinfo->first_line; i < cinfo->first_line +
+ cinfo->nports; i++, channel++) {
tty_unregister_device(cy_serial_driver, i);
+ tty_port_destroy(&cinfo->ports[channel].port);
+ }
cinfo->nports = 0;
kfree(cinfo->ports);
}
@@ -3971,7 +3973,7 @@ static struct pci_driver cy_pci_driver = {
.name = "cyclades",
.id_table = cy_pci_dev_id,
.probe = cy_pci_probe,
- .remove = __devexit_p(cy_pci_remove)
+ .remove = cy_pci_remove
};
#endif
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c
index 4ab936b7aac..c117d775a22 100644
--- a/drivers/tty/ehv_bytechan.c
+++ b/drivers/tty/ehv_bytechan.c
@@ -699,7 +699,7 @@ static const struct tty_port_operations ehv_bc_tty_port_ops = {
.shutdown = ehv_bc_tty_port_shutdown,
};
-static int __devinit ehv_bc_tty_probe(struct platform_device *pdev)
+static int ehv_bc_tty_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct ehv_bc_data *bc;
@@ -757,6 +757,7 @@ static int __devinit ehv_bc_tty_probe(struct platform_device *pdev)
return 0;
error:
+ tty_port_destroy(&bc->port);
irq_dispose_mapping(bc->tx_irq);
irq_dispose_mapping(bc->rx_irq);
@@ -770,6 +771,7 @@ static int ehv_bc_tty_remove(struct platform_device *pdev)
tty_unregister_device(ehv_bc_driver, bc - bcs);
+ tty_port_destroy(&bc->port);
irq_dispose_mapping(bc->tx_irq);
irq_dispose_mapping(bc->rx_irq);
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index a5dec1ca1b8..13ee53bd0bf 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -424,7 +424,6 @@ static void hvc_hangup(struct tty_struct *tty)
{
struct hvc_struct *hp = tty->driver_data;
unsigned long flags;
- int temp_open_count;
if (!hp)
return;
@@ -444,7 +443,6 @@ static void hvc_hangup(struct tty_struct *tty)
return;
}
- temp_open_count = hp->port.count;
hp->port.count = 0;
spin_unlock_irqrestore(&hp->port.lock, flags);
tty_port_tty_set(&hp->port, NULL);
@@ -453,11 +451,6 @@ static void hvc_hangup(struct tty_struct *tty)
if (hp->ops->notifier_hangup)
hp->ops->notifier_hangup(hp, hp->data);
-
- while(temp_open_count) {
- --temp_open_count;
- tty_port_put(&hp->port);
- }
}
/*
diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
index 0d2ea0c224c..be1a9a1e749 100644
--- a/drivers/tty/hvc/hvc_opal.c
+++ b/drivers/tty/hvc/hvc_opal.c
@@ -41,7 +41,7 @@
static const char hvc_opal_name[] = "hvc_opal";
-static struct of_device_id hvc_opal_match[] __devinitdata = {
+static struct of_device_id hvc_opal_match[] = {
{ .name = "serial", .compatible = "ibm,opal-console-raw" },
{ .name = "serial", .compatible = "ibm,opal-console-hvsi" },
{ },
@@ -161,7 +161,7 @@ static const struct hv_ops hvc_opal_hvsi_ops = {
.tiocmset = hvc_opal_hvsi_tiocmset,
};
-static int __devinit hvc_opal_probe(struct platform_device *dev)
+static int hvc_opal_probe(struct platform_device *dev)
{
const struct hv_ops *ops;
struct hvc_struct *hp;
@@ -222,7 +222,7 @@ static int __devinit hvc_opal_probe(struct platform_device *dev)
return 0;
}
-static int __devexit hvc_opal_remove(struct platform_device *dev)
+static int hvc_opal_remove(struct platform_device *dev)
{
struct hvc_struct *hp = dev_get_drvdata(&dev->dev);
int rc, termno;
@@ -239,7 +239,7 @@ static int __devexit hvc_opal_remove(struct platform_device *dev)
static struct platform_driver hvc_opal_driver = {
.probe = hvc_opal_probe,
- .remove = __devexit_p(hvc_opal_remove),
+ .remove = hvc_opal_remove,
.driver = {
.name = hvc_opal_name,
.owner = THIS_MODULE,
diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c
index 070c0ee6864..ed6f5f1f5a5 100644
--- a/drivers/tty/hvc/hvc_vio.c
+++ b/drivers/tty/hvc/hvc_vio.c
@@ -53,7 +53,7 @@
static const char hvc_driver_name[] = "hvc_console";
-static struct vio_device_id hvc_driver_table[] __devinitdata = {
+static struct vio_device_id hvc_driver_table[] = {
{"serial", "hvterm1"},
#ifndef HVC_OLD_HVSI
{"serial", "hvterm-protocol"},
@@ -293,7 +293,7 @@ static int udbg_hvc_getc(void)
}
}
-static int __devinit hvc_vio_probe(struct vio_dev *vdev,
+static int hvc_vio_probe(struct vio_dev *vdev,
const struct vio_device_id *id)
{
const struct hv_ops *ops;
@@ -362,7 +362,7 @@ static int __devinit hvc_vio_probe(struct vio_dev *vdev,
return 0;
}
-static int __devexit hvc_vio_remove(struct vio_dev *vdev)
+static int hvc_vio_remove(struct vio_dev *vdev)
{
struct hvc_struct *hp = dev_get_drvdata(&vdev->dev);
int rc, termno;
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
index f4abfe238f9..19843ec3f80 100644
--- a/drivers/tty/hvc/hvc_xen.c
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -422,7 +422,7 @@ static int xencons_connect_backend(struct xenbus_device *dev,
return ret;
}
-static int __devinit xencons_probe(struct xenbus_device *dev,
+static int xencons_probe(struct xenbus_device *dev,
const struct xenbus_device_id *id)
{
int ret, devid;
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
index cab5c7adf8e..87763573395 100644
--- a/drivers/tty/hvc/hvcs.c
+++ b/drivers/tty/hvc/hvcs.c
@@ -330,12 +330,12 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp);
static void hvcs_close(struct tty_struct *tty, struct file *filp);
static void hvcs_hangup(struct tty_struct * tty);
-static int __devinit hvcs_probe(struct vio_dev *dev,
+static int hvcs_probe(struct vio_dev *dev,
const struct vio_device_id *id);
-static int __devexit hvcs_remove(struct vio_dev *dev);
+static int hvcs_remove(struct vio_dev *dev);
static int __init hvcs_module_init(void);
static void __exit hvcs_module_exit(void);
-static int __devinit hvcs_initialize(void);
+static int hvcs_initialize(void);
#define HVCS_SCHED_READ 0x00000001
#define HVCS_QUICK_READ 0x00000002
@@ -676,7 +676,7 @@ static int khvcsd(void *unused)
return 0;
}
-static struct vio_device_id hvcs_driver_table[] __devinitdata= {
+static struct vio_device_id hvcs_driver_table[] = {
{"serial-server", "hvterm2"},
{ "", "" }
};
@@ -756,7 +756,7 @@ static int hvcs_get_index(void)
return -1;
}
-static int __devinit hvcs_probe(
+static int hvcs_probe(
struct vio_dev *dev,
const struct vio_device_id *id)
{
@@ -835,7 +835,7 @@ static int __devinit hvcs_probe(
return 0;
}
-static int __devexit hvcs_remove(struct vio_dev *dev)
+static int hvcs_remove(struct vio_dev *dev)
{
struct hvcs_struct *hvcsd = dev_get_drvdata(&dev->dev);
unsigned long flags;
@@ -874,7 +874,7 @@ static int __devexit hvcs_remove(struct vio_dev *dev)
static struct vio_driver hvcs_vio_driver = {
.id_table = hvcs_driver_table,
.probe = hvcs_probe,
- .remove = __devexit_p(hvcs_remove),
+ .remove = hvcs_remove,
.name = hvcs_driver_name,
};
@@ -1478,7 +1478,7 @@ static void hvcs_free_index_list(void)
hvcs_index_count = 0;
}
-static int __devinit hvcs_initialize(void)
+static int hvcs_initialize(void)
{
int rc, num_ttys_to_alloc;
@@ -1496,8 +1496,10 @@ static int __devinit hvcs_initialize(void)
num_ttys_to_alloc = hvcs_parm_num_devs;
hvcs_tty_driver = alloc_tty_driver(num_ttys_to_alloc);
- if (!hvcs_tty_driver)
+ if (!hvcs_tty_driver) {
+ mutex_unlock(&hvcs_init_mutex);
return -ENOMEM;
+ }
if (hvcs_alloc_index_list(num_ttys_to_alloc)) {
rc = -ENOMEM;
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c
index 5b95b4f28cf..68357a6e4de 100644
--- a/drivers/tty/hvc/hvsi.c
+++ b/drivers/tty/hvc/hvsi.c
@@ -1218,6 +1218,7 @@ static int __init hvsi_console_init(void)
if (hp->virq == 0) {
printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n",
__func__, irq[0]);
+ tty_port_destroy(&hp->port);
continue;
}
diff --git a/drivers/tty/ipwireless/network.c b/drivers/tty/ipwireless/network.c
index 57102e66165..c0dfb642383 100644
--- a/drivers/tty/ipwireless/network.c
+++ b/drivers/tty/ipwireless/network.c
@@ -352,6 +352,8 @@ static struct sk_buff *ipw_packet_received_skb(unsigned char *data,
}
skb = dev_alloc_skb(length + 4);
+ if (skb == NULL)
+ return NULL;
skb_reserve(skb, 2);
memcpy(skb_put(skb, length), data, length);
@@ -397,7 +399,8 @@ void ipwireless_network_packet_received(struct ipw_network *network,
/* Send the data to the ppp_generic module. */
skb = ipw_packet_received_skb(data, length);
- ppp_input(network->ppp_channel, skb);
+ if (skb)
+ ppp_input(network->ppp_channel, skb);
} else
spin_unlock_irqrestore(&network->lock,
flags);
diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c
index 160f0ad9589..2cde13ddf9f 100644
--- a/drivers/tty/ipwireless/tty.c
+++ b/drivers/tty/ipwireless/tty.c
@@ -566,6 +566,7 @@ void ipwireless_tty_free(struct ipw_tty *tty)
ipwireless_disassociate_network_ttys(network,
ttyj->channel_idx);
tty_unregister_device(ipw_tty_driver, j);
+ tty_port_destroy(&ttyj->port);
ttys[j] = NULL;
mutex_unlock(&ttyj->ipw_tty_mutex);
kfree(ttyj);
diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c
index d7492e18360..3205b2e9090 100644
--- a/drivers/tty/isicom.c
+++ b/drivers/tty/isicom.c
@@ -148,7 +148,7 @@
#endif
static int isicom_probe(struct pci_dev *, const struct pci_device_id *);
-static void __devexit isicom_remove(struct pci_dev *);
+static void isicom_remove(struct pci_dev *);
static struct pci_device_id isicom_pci_tbl[] = {
{ PCI_DEVICE(VENDOR_ID, 0x2028) },
@@ -168,7 +168,7 @@ static struct pci_driver isicom_driver = {
.name = "isicom",
.id_table = isicom_pci_tbl,
.probe = isicom_probe,
- .remove = __devexit_p(isicom_remove)
+ .remove = isicom_remove
};
static int prev_card = 3; /* start servicing isi_card[0] */
@@ -603,7 +603,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
if (tty_port_cts_enabled(&port->port)) {
if (tty->hw_stopped) {
if (header & ISI_CTS) {
- port->port.tty->hw_stopped = 0;
+ tty->hw_stopped = 0;
/* start tx ing */
port->status |= (ISI_TXOK
| ISI_CTS);
@@ -1307,7 +1307,7 @@ static const struct tty_port_operations isicom_port_ops = {
.shutdown = isicom_shutdown,
};
-static int __devinit reset_card(struct pci_dev *pdev,
+static int reset_card(struct pci_dev *pdev,
const unsigned int card, unsigned int *signature)
{
struct isi_board *board = pci_get_drvdata(pdev);
@@ -1368,7 +1368,7 @@ end:
return retval;
}
-static int __devinit load_firmware(struct pci_dev *pdev,
+static int load_firmware(struct pci_dev *pdev,
const unsigned int index, const unsigned int signature)
{
struct isi_board *board = pci_get_drvdata(pdev);
@@ -1548,7 +1548,7 @@ end:
*/
static unsigned int card_count;
-static int __devinit isicom_probe(struct pci_dev *pdev,
+static int isicom_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
unsigned int uninitialized_var(signature), index;
@@ -1610,10 +1610,15 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
if (retval < 0)
goto errunri;
- for (index = 0; index < board->port_count; index++)
- tty_port_register_device(&board->ports[index].port,
- isicom_normal, board->index * 16 + index,
- &pdev->dev);
+ for (index = 0; index < board->port_count; index++) {
+ struct tty_port *tport = &board->ports[index].port;
+ tty_port_init(tport);
+ tport->ops = &isicom_port_ops;
+ tport->close_delay = 50 * HZ/100;
+ tport->closing_wait = 3000 * HZ/100;
+ tty_port_register_device(tport, isicom_normal,
+ board->index * 16 + index, &pdev->dev);
+ }
return 0;
@@ -1630,13 +1635,15 @@ err:
return retval;
}
-static void __devexit isicom_remove(struct pci_dev *pdev)
+static void isicom_remove(struct pci_dev *pdev)
{
struct isi_board *board = pci_get_drvdata(pdev);
unsigned int i;
- for (i = 0; i < board->port_count; i++)
+ for (i = 0; i < board->port_count; i++) {
tty_unregister_device(isicom_normal, board->index * 16 + i);
+ tty_port_destroy(&board->ports[i].port);
+ }
free_irq(board->irq, board);
pci_release_region(pdev, 3);
@@ -1655,13 +1662,9 @@ static int __init isicom_init(void)
isi_card[idx].ports = port;
spin_lock_init(&isi_card[idx].card_lock);
for (channel = 0; channel < 16; channel++, port++) {
- tty_port_init(&port->port);
- port->port.ops = &isicom_port_ops;
port->magic = ISICOM_MAGIC;
port->card = &isi_card[idx];
port->channel = channel;
- port->port.close_delay = 50 * HZ/100;
- port->port.closing_wait = 3000 * HZ/100;
port->status = 0;
/* . . . */
}
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c
index 56e616b9109..f9d28503bde 100644
--- a/drivers/tty/moxa.c
+++ b/drivers/tty/moxa.c
@@ -895,6 +895,8 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
return 0;
err_free:
+ for (i = 0; i < MAX_PORTS_PER_BOARD; i++)
+ tty_port_destroy(&brd->ports[i].port);
kfree(brd->ports);
err:
return ret;
@@ -919,6 +921,8 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
tty_kref_put(tty);
}
}
+ for (a = 0; a < MAX_PORTS_PER_BOARD; a++)
+ tty_port_destroy(&brd->ports[a].port);
while (1) {
opened = 0;
for (a = 0; a < brd->numPorts; a++)
@@ -941,7 +945,7 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
}
#ifdef CONFIG_PCI
-static int __devinit moxa_pci_probe(struct pci_dev *pdev,
+static int moxa_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct moxa_board_conf *board;
@@ -1016,7 +1020,7 @@ err:
return retval;
}
-static void __devexit moxa_pci_remove(struct pci_dev *pdev)
+static void moxa_pci_remove(struct pci_dev *pdev)
{
struct moxa_board_conf *brd = pci_get_drvdata(pdev);
@@ -1029,7 +1033,7 @@ static struct pci_driver moxa_pci_driver = {
.name = "moxa",
.id_table = moxa_pcibrds,
.probe = moxa_pci_probe,
- .remove = __devexit_p(moxa_pci_remove)
+ .remove = moxa_pci_remove
};
#endif /* CONFIG_PCI */
@@ -1370,7 +1374,7 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
p->DCDState = dcd;
spin_unlock_irqrestore(&p->port.lock, flags);
tty = tty_port_tty_get(&p->port);
- if (tty && C_CLOCAL(tty) && !dcd)
+ if (tty && !C_CLOCAL(tty) && !dcd)
tty_hangup(tty);
tty_kref_put(tty);
}
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
index cfda47dabd2..40113868bec 100644
--- a/drivers/tty/mxser.c
+++ b/drivers/tty/mxser.c
@@ -487,7 +487,7 @@ static void mxser_disable_must_rx_software_flow_control(unsigned long baseio)
}
#ifdef CONFIG_PCI
-static int __devinit CheckIsMoxaMust(unsigned long io)
+static int CheckIsMoxaMust(unsigned long io)
{
u8 oldmcr, hwid;
int i;
@@ -2369,7 +2369,7 @@ static void mxser_release_ISA_res(struct mxser_board *brd)
mxser_release_vector(brd);
}
-static int __devinit mxser_initbrd(struct mxser_board *brd,
+static int mxser_initbrd(struct mxser_board *brd,
struct pci_dev *pdev)
{
struct mxser_port *info;
@@ -2411,14 +2411,27 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser",
brd);
- if (retval)
+ if (retval) {
+ for (i = 0; i < brd->info->nports; i++)
+ tty_port_destroy(&brd->ports[i].port);
printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may "
"conflict with another device.\n",
brd->info->name, brd->irq);
+ }
return retval;
}
+static void mxser_board_remove(struct mxser_board *brd)
+{
+ unsigned int i;
+
+ for (i = 0; i < brd->info->nports; i++) {
+ tty_unregister_device(mxvar_sdriver, brd->idx + i);
+ tty_port_destroy(&brd->ports[i].port);
+ }
+}
+
static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd)
{
int id, i, bits, ret;
@@ -2534,7 +2547,7 @@ err_irqconflict:
return -EIO;
}
-static int __devinit mxser_probe(struct pci_dev *pdev,
+static int mxser_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
#ifdef CONFIG_PCI
@@ -2645,14 +2658,12 @@ err:
#endif
}
-static void __devexit mxser_remove(struct pci_dev *pdev)
+static void mxser_remove(struct pci_dev *pdev)
{
#ifdef CONFIG_PCI
struct mxser_board *brd = pci_get_drvdata(pdev);
- unsigned int i;
- for (i = 0; i < brd->info->nports; i++)
- tty_unregister_device(mxvar_sdriver, brd->idx + i);
+ mxser_board_remove(brd);
free_irq(pdev->irq, brd);
pci_release_region(pdev, 2);
@@ -2666,7 +2677,7 @@ static struct pci_driver mxser_driver = {
.name = "mxser",
.id_table = mxser_pcibrds,
.probe = mxser_probe,
- .remove = __devexit_p(mxser_remove)
+ .remove = mxser_remove
};
static int __init mxser_module_init(void)
@@ -2748,15 +2759,13 @@ err_put:
static void __exit mxser_module_exit(void)
{
- unsigned int i, j;
+ unsigned int i;
pci_unregister_driver(&mxser_driver);
for (i = 0; i < MXSER_BOARDS; i++) /* ISA remains */
if (mxser_boards[i].info != NULL)
- for (j = 0; j < mxser_boards[i].info->nports; j++)
- tty_unregister_device(mxvar_sdriver,
- mxser_boards[i].idx + j);
+ mxser_board_remove(&mxser_boards[i]);
tty_unregister_driver(mxvar_sdriver);
put_tty_driver(mxvar_sdriver);
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 1e8e8ce5595..dcc0430a49c 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -134,7 +134,6 @@ struct gsm_dlci {
#define DLCI_OPENING 1 /* Sending SABM not seen UA */
#define DLCI_OPEN 2 /* SABM/UA complete */
#define DLCI_CLOSING 3 /* Sending DISC not seen UA/DM */
- struct kref ref; /* freed from port or mux close */
struct mutex mutex;
/* Link layer */
@@ -1635,7 +1634,6 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr)
if (dlci == NULL)
return NULL;
spin_lock_init(&dlci->lock);
- kref_init(&dlci->ref);
mutex_init(&dlci->mutex);
dlci->fifo = &dlci->_fifo;
if (kfifo_alloc(&dlci->_fifo, 4096, GFP_KERNEL) < 0) {
@@ -1669,9 +1667,9 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr)
*
* Can sleep.
*/
-static void gsm_dlci_free(struct kref *ref)
+static void gsm_dlci_free(struct tty_port *port)
{
- struct gsm_dlci *dlci = container_of(ref, struct gsm_dlci, ref);
+ struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port);
del_timer_sync(&dlci->t1);
dlci->gsm->dlci[dlci->addr] = NULL;
@@ -1683,12 +1681,12 @@ static void gsm_dlci_free(struct kref *ref)
static inline void dlci_get(struct gsm_dlci *dlci)
{
- kref_get(&dlci->ref);
+ tty_port_get(&dlci->port);
}
static inline void dlci_put(struct gsm_dlci *dlci)
{
- kref_put(&dlci->ref, gsm_dlci_free);
+ tty_port_put(&dlci->port);
}
/**
@@ -2874,6 +2872,7 @@ static void gsm_dtr_rts(struct tty_port *port, int onoff)
static const struct tty_port_operations gsm_port_ops = {
.carrier_raised = gsm_carrier_raised,
.dtr_rts = gsm_dtr_rts,
+ .destruct = gsm_dlci_free,
};
static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty)
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 8c0b7b42319..19083efa231 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -73,10 +73,42 @@
#define ECHO_OP_SET_CANON_COL 0x81
#define ECHO_OP_ERASE_TAB 0x82
+struct n_tty_data {
+ unsigned int column;
+ unsigned long overrun_time;
+ int num_overrun;
+
+ unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1;
+ unsigned char echo_overrun:1;
+
+ DECLARE_BITMAP(process_char_map, 256);
+ DECLARE_BITMAP(read_flags, N_TTY_BUF_SIZE);
+
+ char *read_buf;
+ int read_head;
+ int read_tail;
+ int read_cnt;
+
+ unsigned char *echo_buf;
+ unsigned int echo_pos;
+ unsigned int echo_cnt;
+
+ int canon_data;
+ unsigned long canon_head;
+ unsigned int canon_column;
+
+ struct mutex atomic_read_lock;
+ struct mutex output_lock;
+ struct mutex echo_lock;
+ spinlock_t read_lock;
+};
+
static inline int tty_put_user(struct tty_struct *tty, unsigned char x,
unsigned char __user *ptr)
{
- tty_audit_add_data(tty, &x, 1);
+ struct n_tty_data *ldata = tty->disc_data;
+
+ tty_audit_add_data(tty, &x, 1, ldata->icanon);
return put_user(x, ptr);
}
@@ -92,17 +124,18 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x,
static void n_tty_set_room(struct tty_struct *tty)
{
+ struct n_tty_data *ldata = tty->disc_data;
int left;
int old_left;
- /* tty->read_cnt is not read locked ? */
+ /* ldata->read_cnt is not read locked ? */
if (I_PARMRK(tty)) {
/* Multiply read_cnt by 3, since each byte might take up to
* three times as many spaces when PARMRK is set (depending on
* its flags, e.g. parity error). */
- left = N_TTY_BUF_SIZE - tty->read_cnt * 3 - 1;
+ left = N_TTY_BUF_SIZE - ldata->read_cnt * 3 - 1;
} else
- left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
+ left = N_TTY_BUF_SIZE - ldata->read_cnt - 1;
/*
* If we are doing input canonicalization, and there are no
@@ -111,44 +144,47 @@ static void n_tty_set_room(struct tty_struct *tty)
* characters will be beeped.
*/
if (left <= 0)
- left = tty->icanon && !tty->canon_data;
+ left = ldata->icanon && !ldata->canon_data;
old_left = tty->receive_room;
tty->receive_room = left;
/* Did this open up the receive buffer? We may need to flip */
- if (left && !old_left)
- schedule_work(&tty->buf.work);
+ if (left && !old_left) {
+ WARN_RATELIMIT(tty->port->itty == NULL,
+ "scheduling with invalid itty\n");
+ schedule_work(&tty->port->buf.work);
+ }
}
-static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
+static void put_tty_queue_nolock(unsigned char c, struct n_tty_data *ldata)
{
- if (tty->read_cnt < N_TTY_BUF_SIZE) {
- tty->read_buf[tty->read_head] = c;
- tty->read_head = (tty->read_head + 1) & (N_TTY_BUF_SIZE-1);
- tty->read_cnt++;
+ if (ldata->read_cnt < N_TTY_BUF_SIZE) {
+ ldata->read_buf[ldata->read_head] = c;
+ ldata->read_head = (ldata->read_head + 1) & (N_TTY_BUF_SIZE-1);
+ ldata->read_cnt++;
}
}
/**
* put_tty_queue - add character to tty
* @c: character
- * @tty: tty device
+ * @ldata: n_tty data
*
* Add a character to the tty read_buf queue. This is done under the
* read_lock to serialize character addition and also to protect us
* against parallel reads or flushes
*/
-static void put_tty_queue(unsigned char c, struct tty_struct *tty)
+static void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
{
unsigned long flags;
/*
* The problem of stomping on the buffers ends here.
* Why didn't anyone see this one coming? --AJK
*/
- spin_lock_irqsave(&tty->read_lock, flags);
- put_tty_queue_nolock(c, tty);
- spin_unlock_irqrestore(&tty->read_lock, flags);
+ spin_lock_irqsave(&ldata->read_lock, flags);
+ put_tty_queue_nolock(c, ldata);
+ spin_unlock_irqrestore(&ldata->read_lock, flags);
}
/**
@@ -179,18 +215,19 @@ static void check_unthrottle(struct tty_struct *tty)
static void reset_buffer_flags(struct tty_struct *tty)
{
+ struct n_tty_data *ldata = tty->disc_data;
unsigned long flags;
- spin_lock_irqsave(&tty->read_lock, flags);
- tty->read_head = tty->read_tail = tty->read_cnt = 0;
- spin_unlock_irqrestore(&tty->read_lock, flags);
+ spin_lock_irqsave(&ldata->read_lock, flags);
+ ldata->read_head = ldata->read_tail = ldata->read_cnt = 0;
+ spin_unlock_irqrestore(&ldata->read_lock, flags);
- mutex_lock(&tty->echo_lock);
- tty->echo_pos = tty->echo_cnt = tty->echo_overrun = 0;
- mutex_unlock(&tty->echo_lock);
+ mutex_lock(&ldata->echo_lock);
+ ldata->echo_pos = ldata->echo_cnt = ldata->echo_overrun = 0;
+ mutex_unlock(&ldata->echo_lock);
- tty->canon_head = tty->canon_data = tty->erasing = 0;
- memset(&tty->read_flags, 0, sizeof tty->read_flags);
+ ldata->canon_head = ldata->canon_data = ldata->erasing = 0;
+ bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
n_tty_set_room(tty);
}
@@ -235,18 +272,19 @@ static void n_tty_flush_buffer(struct tty_struct *tty)
static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty)
{
+ struct n_tty_data *ldata = tty->disc_data;
unsigned long flags;
ssize_t n = 0;
- spin_lock_irqsave(&tty->read_lock, flags);
- if (!tty->icanon) {
- n = tty->read_cnt;
- } else if (tty->canon_data) {
- n = (tty->canon_head > tty->read_tail) ?
- tty->canon_head - tty->read_tail :
- tty->canon_head + (N_TTY_BUF_SIZE - tty->read_tail);
+ spin_lock_irqsave(&ldata->read_lock, flags);
+ if (!ldata->icanon) {
+ n = ldata->read_cnt;
+ } else if (ldata->canon_data) {
+ n = (ldata->canon_head > ldata->read_tail) ?
+ ldata->canon_head - ldata->read_tail :
+ ldata->canon_head + (N_TTY_BUF_SIZE - ldata->read_tail);
}
- spin_unlock_irqrestore(&tty->read_lock, flags);
+ spin_unlock_irqrestore(&ldata->read_lock, flags);
return n;
}
@@ -301,6 +339,7 @@ static inline int is_continuation(unsigned char c, struct tty_struct *tty)
static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
{
+ struct n_tty_data *ldata = tty->disc_data;
int spaces;
if (!space)
@@ -309,48 +348,48 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
switch (c) {
case '\n':
if (O_ONLRET(tty))
- tty->column = 0;
+ ldata->column = 0;
if (O_ONLCR(tty)) {
if (space < 2)
return -1;
- tty->canon_column = tty->column = 0;
+ ldata->canon_column = ldata->column = 0;
tty->ops->write(tty, "\r\n", 2);
return 2;
}
- tty->canon_column = tty->column;
+ ldata->canon_column = ldata->column;
break;
case '\r':
- if (O_ONOCR(tty) && tty->column == 0)
+ if (O_ONOCR(tty) && ldata->column == 0)
return 0;
if (O_OCRNL(tty)) {
c = '\n';
if (O_ONLRET(tty))
- tty->canon_column = tty->column = 0;
+ ldata->canon_column = ldata->column = 0;
break;
}
- tty->canon_column = tty->column = 0;
+ ldata->canon_column = ldata->column = 0;
break;
case '\t':
- spaces = 8 - (tty->column & 7);
+ spaces = 8 - (ldata->column & 7);
if (O_TABDLY(tty) == XTABS) {
if (space < spaces)
return -1;
- tty->column += spaces;
+ ldata->column += spaces;
tty->ops->write(tty, " ", spaces);
return spaces;
}
- tty->column += spaces;
+ ldata->column += spaces;
break;
case '\b':
- if (tty->column > 0)
- tty->column--;
+ if (ldata->column > 0)
+ ldata->column--;
break;
default:
if (!iscntrl(c)) {
if (O_OLCUC(tty))
c = toupper(c);
if (!is_continuation(c, tty))
- tty->column++;
+ ldata->column++;
}
break;
}
@@ -375,14 +414,15 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
static int process_output(unsigned char c, struct tty_struct *tty)
{
+ struct n_tty_data *ldata = tty->disc_data;
int space, retval;
- mutex_lock(&tty->output_lock);
+ mutex_lock(&ldata->output_lock);
space = tty_write_room(tty);
retval = do_output_char(c, tty, space);
- mutex_unlock(&tty->output_lock);
+ mutex_unlock(&ldata->output_lock);
if (retval < 0)
return -1;
else
@@ -411,15 +451,16 @@ static int process_output(unsigned char c, struct tty_struct *tty)
static ssize_t process_output_block(struct tty_struct *tty,
const unsigned char *buf, unsigned int nr)
{
+ struct n_tty_data *ldata = tty->disc_data;
int space;
int i;
const unsigned char *cp;
- mutex_lock(&tty->output_lock);
+ mutex_lock(&ldata->output_lock);
space = tty_write_room(tty);
if (!space) {
- mutex_unlock(&tty->output_lock);
+ mutex_unlock(&ldata->output_lock);
return 0;
}
if (nr > space)
@@ -431,30 +472,30 @@ static ssize_t process_output_block(struct tty_struct *tty,
switch (c) {
case '\n':
if (O_ONLRET(tty))
- tty->column = 0;
+ ldata->column = 0;
if (O_ONLCR(tty))
goto break_out;
- tty->canon_column = tty->column;
+ ldata->canon_column = ldata->column;
break;
case '\r':
- if (O_ONOCR(tty) && tty->column == 0)
+ if (O_ONOCR(tty) && ldata->column == 0)
goto break_out;
if (O_OCRNL(tty))
goto break_out;
- tty->canon_column = tty->column = 0;
+ ldata->canon_column = ldata->column = 0;
break;
case '\t':
goto break_out;
case '\b':
- if (tty->column > 0)
- tty->column--;
+ if (ldata->column > 0)
+ ldata->column--;
break;
default:
if (!iscntrl(c)) {
if (O_OLCUC(tty))
goto break_out;
if (!is_continuation(c, tty))
- tty->column++;
+ ldata->column++;
}
break;
}
@@ -462,7 +503,7 @@ static ssize_t process_output_block(struct tty_struct *tty,
break_out:
i = tty->ops->write(tty, buf, i);
- mutex_unlock(&tty->output_lock);
+ mutex_unlock(&ldata->output_lock);
return i;
}
@@ -494,21 +535,22 @@ break_out:
static void process_echoes(struct tty_struct *tty)
{
+ struct n_tty_data *ldata = tty->disc_data;
int space, nr;
unsigned char c;
unsigned char *cp, *buf_end;
- if (!tty->echo_cnt)
+ if (!ldata->echo_cnt)
return;
- mutex_lock(&tty->output_lock);
- mutex_lock(&tty->echo_lock);
+ mutex_lock(&ldata->output_lock);
+ mutex_lock(&ldata->echo_lock);
space = tty_write_room(tty);
- buf_end = tty->echo_buf + N_TTY_BUF_SIZE;
- cp = tty->echo_buf + tty->echo_pos;
- nr = tty->echo_cnt;
+ buf_end = ldata->echo_buf + N_TTY_BUF_SIZE;
+ cp = ldata->echo_buf + ldata->echo_pos;
+ nr = ldata->echo_cnt;
while (nr > 0) {
c = *cp;
if (c == ECHO_OP_START) {
@@ -545,7 +587,7 @@ static void process_echoes(struct tty_struct *tty)
* Otherwise, tab spacing is normal.
*/
if (!(num_chars & 0x80))
- num_chars += tty->canon_column;
+ num_chars += ldata->canon_column;
num_bs = 8 - (num_chars & 7);
if (num_bs > space) {
@@ -555,22 +597,22 @@ static void process_echoes(struct tty_struct *tty)
space -= num_bs;
while (num_bs--) {
tty_put_char(tty, '\b');
- if (tty->column > 0)
- tty->column--;
+ if (ldata->column > 0)
+ ldata->column--;
}
cp += 3;
nr -= 3;
break;
case ECHO_OP_SET_CANON_COL:
- tty->canon_column = tty->column;
+ ldata->canon_column = ldata->column;
cp += 2;
nr -= 2;
break;
case ECHO_OP_MOVE_BACK_COL:
- if (tty->column > 0)
- tty->column--;
+ if (ldata->column > 0)
+ ldata->column--;
cp += 2;
nr -= 2;
break;
@@ -582,7 +624,7 @@ static void process_echoes(struct tty_struct *tty)
break;
}
tty_put_char(tty, ECHO_OP_START);
- tty->column++;
+ ldata->column++;
space--;
cp += 2;
nr -= 2;
@@ -604,7 +646,7 @@ static void process_echoes(struct tty_struct *tty)
}
tty_put_char(tty, '^');
tty_put_char(tty, op ^ 0100);
- tty->column += 2;
+ ldata->column += 2;
space -= 2;
cp += 2;
nr -= 2;
@@ -635,20 +677,20 @@ static void process_echoes(struct tty_struct *tty)
}
if (nr == 0) {
- tty->echo_pos = 0;
- tty->echo_cnt = 0;
- tty->echo_overrun = 0;
+ ldata->echo_pos = 0;
+ ldata->echo_cnt = 0;
+ ldata->echo_overrun = 0;
} else {
- int num_processed = tty->echo_cnt - nr;
- tty->echo_pos += num_processed;
- tty->echo_pos &= N_TTY_BUF_SIZE - 1;
- tty->echo_cnt = nr;
+ int num_processed = ldata->echo_cnt - nr;
+ ldata->echo_pos += num_processed;
+ ldata->echo_pos &= N_TTY_BUF_SIZE - 1;
+ ldata->echo_cnt = nr;
if (num_processed > 0)
- tty->echo_overrun = 0;
+ ldata->echo_overrun = 0;
}
- mutex_unlock(&tty->echo_lock);
- mutex_unlock(&tty->output_lock);
+ mutex_unlock(&ldata->echo_lock);
+ mutex_unlock(&ldata->output_lock);
if (tty->ops->flush_chars)
tty->ops->flush_chars(tty);
@@ -657,72 +699,70 @@ static void process_echoes(struct tty_struct *tty)
/**
* add_echo_byte - add a byte to the echo buffer
* @c: unicode byte to echo
- * @tty: terminal device
+ * @ldata: n_tty data
*
* Add a character or operation byte to the echo buffer.
*
* Should be called under the echo lock to protect the echo buffer.
*/
-static void add_echo_byte(unsigned char c, struct tty_struct *tty)
+static void add_echo_byte(unsigned char c, struct n_tty_data *ldata)
{
int new_byte_pos;
- if (tty->echo_cnt == N_TTY_BUF_SIZE) {
+ if (ldata->echo_cnt == N_TTY_BUF_SIZE) {
/* Circular buffer is already at capacity */
- new_byte_pos = tty->echo_pos;
+ new_byte_pos = ldata->echo_pos;
/*
* Since the buffer start position needs to be advanced,
* be sure to step by a whole operation byte group.
*/
- if (tty->echo_buf[tty->echo_pos] == ECHO_OP_START) {
- if (tty->echo_buf[(tty->echo_pos + 1) &
+ if (ldata->echo_buf[ldata->echo_pos] == ECHO_OP_START) {
+ if (ldata->echo_buf[(ldata->echo_pos + 1) &
(N_TTY_BUF_SIZE - 1)] ==
ECHO_OP_ERASE_TAB) {
- tty->echo_pos += 3;
- tty->echo_cnt -= 2;
+ ldata->echo_pos += 3;
+ ldata->echo_cnt -= 2;
} else {
- tty->echo_pos += 2;
- tty->echo_cnt -= 1;
+ ldata->echo_pos += 2;
+ ldata->echo_cnt -= 1;
}
} else {
- tty->echo_pos++;
+ ldata->echo_pos++;
}
- tty->echo_pos &= N_TTY_BUF_SIZE - 1;
+ ldata->echo_pos &= N_TTY_BUF_SIZE - 1;
- tty->echo_overrun = 1;
+ ldata->echo_overrun = 1;
} else {
- new_byte_pos = tty->echo_pos + tty->echo_cnt;
+ new_byte_pos = ldata->echo_pos + ldata->echo_cnt;
new_byte_pos &= N_TTY_BUF_SIZE - 1;
- tty->echo_cnt++;
+ ldata->echo_cnt++;
}
- tty->echo_buf[new_byte_pos] = c;
+ ldata->echo_buf[new_byte_pos] = c;
}
/**
* echo_move_back_col - add operation to move back a column
- * @tty: terminal device
+ * @ldata: n_tty data
*
* Add an operation to the echo buffer to move back one column.
*
* Locking: echo_lock to protect the echo buffer
*/
-static void echo_move_back_col(struct tty_struct *tty)
+static void echo_move_back_col(struct n_tty_data *ldata)
{
- mutex_lock(&tty->echo_lock);
-
- add_echo_byte(ECHO_OP_START, tty);
- add_echo_byte(ECHO_OP_MOVE_BACK_COL, tty);
-
- mutex_unlock(&tty->echo_lock);
+ mutex_lock(&ldata->echo_lock);
+ add_echo_byte(ECHO_OP_START, ldata);
+ add_echo_byte(ECHO_OP_MOVE_BACK_COL, ldata);
+ mutex_unlock(&ldata->echo_lock);
}
/**
* echo_set_canon_col - add operation to set the canon column
- * @tty: terminal device
+ * @ldata: n_tty data
*
* Add an operation to the echo buffer to set the canon column
* to the current column.
@@ -730,21 +770,19 @@ static void echo_move_back_col(struct tty_struct *tty)
* Locking: echo_lock to protect the echo buffer
*/
-static void echo_set_canon_col(struct tty_struct *tty)
+static void echo_set_canon_col(struct n_tty_data *ldata)
{
- mutex_lock(&tty->echo_lock);
-
- add_echo_byte(ECHO_OP_START, tty);
- add_echo_byte(ECHO_OP_SET_CANON_COL, tty);
-
- mutex_unlock(&tty->echo_lock);
+ mutex_lock(&ldata->echo_lock);
+ add_echo_byte(ECHO_OP_START, ldata);
+ add_echo_byte(ECHO_OP_SET_CANON_COL, ldata);
+ mutex_unlock(&ldata->echo_lock);
}
/**
* echo_erase_tab - add operation to erase a tab
* @num_chars: number of character columns already used
* @after_tab: true if num_chars starts after a previous tab
- * @tty: terminal device
+ * @ldata: n_tty data
*
* Add an operation to the echo buffer to erase a tab.
*
@@ -758,12 +796,12 @@ static void echo_set_canon_col(struct tty_struct *tty)
*/
static void echo_erase_tab(unsigned int num_chars, int after_tab,
- struct tty_struct *tty)
+ struct n_tty_data *ldata)
{
- mutex_lock(&tty->echo_lock);
+ mutex_lock(&ldata->echo_lock);
- add_echo_byte(ECHO_OP_START, tty);
- add_echo_byte(ECHO_OP_ERASE_TAB, tty);
+ add_echo_byte(ECHO_OP_START, ldata);
+ add_echo_byte(ECHO_OP_ERASE_TAB, ldata);
/* We only need to know this modulo 8 (tab spacing) */
num_chars &= 7;
@@ -772,9 +810,9 @@ static void echo_erase_tab(unsigned int num_chars, int after_tab,
if (after_tab)
num_chars |= 0x80;
- add_echo_byte(num_chars, tty);
+ add_echo_byte(num_chars, ldata);
- mutex_unlock(&tty->echo_lock);
+ mutex_unlock(&ldata->echo_lock);
}
/**
@@ -790,18 +828,16 @@ static void echo_erase_tab(unsigned int num_chars, int after_tab,
* Locking: echo_lock to protect the echo buffer
*/
-static void echo_char_raw(unsigned char c, struct tty_struct *tty)
+static void echo_char_raw(unsigned char c, struct n_tty_data *ldata)
{
- mutex_lock(&tty->echo_lock);
-
+ mutex_lock(&ldata->echo_lock);
if (c == ECHO_OP_START) {
- add_echo_byte(ECHO_OP_START, tty);
- add_echo_byte(ECHO_OP_START, tty);
+ add_echo_byte(ECHO_OP_START, ldata);
+ add_echo_byte(ECHO_OP_START, ldata);
} else {
- add_echo_byte(c, tty);
+ add_echo_byte(c, ldata);
}
-
- mutex_unlock(&tty->echo_lock);
+ mutex_unlock(&ldata->echo_lock);
}
/**
@@ -820,30 +856,32 @@ static void echo_char_raw(unsigned char c, struct tty_struct *tty)
static void echo_char(unsigned char c, struct tty_struct *tty)
{
- mutex_lock(&tty->echo_lock);
+ struct n_tty_data *ldata = tty->disc_data;
+
+ mutex_lock(&ldata->echo_lock);
if (c == ECHO_OP_START) {
- add_echo_byte(ECHO_OP_START, tty);
- add_echo_byte(ECHO_OP_START, tty);
+ add_echo_byte(ECHO_OP_START, ldata);
+ add_echo_byte(ECHO_OP_START, ldata);
} else {
if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t')
- add_echo_byte(ECHO_OP_START, tty);
- add_echo_byte(c, tty);
+ add_echo_byte(ECHO_OP_START, ldata);
+ add_echo_byte(c, ldata);
}
- mutex_unlock(&tty->echo_lock);
+ mutex_unlock(&ldata->echo_lock);
}
/**
* finish_erasing - complete erase
- * @tty: tty doing the erase
+ * @ldata: n_tty data
*/
-static inline void finish_erasing(struct tty_struct *tty)
+static inline void finish_erasing(struct n_tty_data *ldata)
{
- if (tty->erasing) {
- echo_char_raw('/', tty);
- tty->erasing = 0;
+ if (ldata->erasing) {
+ echo_char_raw('/', ldata);
+ ldata->erasing = 0;
}
}
@@ -861,12 +899,13 @@ static inline void finish_erasing(struct tty_struct *tty)
static void eraser(unsigned char c, struct tty_struct *tty)
{
+ struct n_tty_data *ldata = tty->disc_data;
enum { ERASE, WERASE, KILL } kill_type;
int head, seen_alnums, cnt;
unsigned long flags;
/* FIXME: locking needed ? */
- if (tty->read_head == tty->canon_head) {
+ if (ldata->read_head == ldata->canon_head) {
/* process_output('\a', tty); */ /* what do you think? */
return;
}
@@ -876,24 +915,24 @@ static void eraser(unsigned char c, struct tty_struct *tty)
kill_type = WERASE;
else {
if (!L_ECHO(tty)) {
- spin_lock_irqsave(&tty->read_lock, flags);
- tty->read_cnt -= ((tty->read_head - tty->canon_head) &
+ spin_lock_irqsave(&ldata->read_lock, flags);
+ ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) &
(N_TTY_BUF_SIZE - 1));
- tty->read_head = tty->canon_head;
- spin_unlock_irqrestore(&tty->read_lock, flags);
+ ldata->read_head = ldata->canon_head;
+ spin_unlock_irqrestore(&ldata->read_lock, flags);
return;
}
if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) {
- spin_lock_irqsave(&tty->read_lock, flags);
- tty->read_cnt -= ((tty->read_head - tty->canon_head) &
+ spin_lock_irqsave(&ldata->read_lock, flags);
+ ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) &
(N_TTY_BUF_SIZE - 1));
- tty->read_head = tty->canon_head;
- spin_unlock_irqrestore(&tty->read_lock, flags);
- finish_erasing(tty);
+ ldata->read_head = ldata->canon_head;
+ spin_unlock_irqrestore(&ldata->read_lock, flags);
+ finish_erasing(ldata);
echo_char(KILL_CHAR(tty), tty);
/* Add a newline if ECHOK is on and ECHOKE is off. */
if (L_ECHOK(tty))
- echo_char_raw('\n', tty);
+ echo_char_raw('\n', ldata);
return;
}
kill_type = KILL;
@@ -901,14 +940,14 @@ static void eraser(unsigned char c, struct tty_struct *tty)
seen_alnums = 0;
/* FIXME: Locking ?? */
- while (tty->read_head != tty->canon_head) {
- head = tty->read_head;
+ while (ldata->read_head != ldata->canon_head) {
+ head = ldata->read_head;
/* erase a single possibly multibyte character */
do {
head = (head - 1) & (N_TTY_BUF_SIZE-1);
- c = tty->read_buf[head];
- } while (is_continuation(c, tty) && head != tty->canon_head);
+ c = ldata->read_buf[head];
+ } while (is_continuation(c, tty) && head != ldata->canon_head);
/* do not partially erase */
if (is_continuation(c, tty))
@@ -921,30 +960,31 @@ static void eraser(unsigned char c, struct tty_struct *tty)
else if (seen_alnums)
break;
}
- cnt = (tty->read_head - head) & (N_TTY_BUF_SIZE-1);
- spin_lock_irqsave(&tty->read_lock, flags);
- tty->read_head = head;
- tty->read_cnt -= cnt;
- spin_unlock_irqrestore(&tty->read_lock, flags);
+ cnt = (ldata->read_head - head) & (N_TTY_BUF_SIZE-1);
+ spin_lock_irqsave(&ldata->read_lock, flags);
+ ldata->read_head = head;
+ ldata->read_cnt -= cnt;
+ spin_unlock_irqrestore(&ldata->read_lock, flags);
if (L_ECHO(tty)) {
if (L_ECHOPRT(tty)) {
- if (!tty->erasing) {
- echo_char_raw('\\', tty);
- tty->erasing = 1;
+ if (!ldata->erasing) {
+ echo_char_raw('\\', ldata);
+ ldata->erasing = 1;
}
/* if cnt > 1, output a multi-byte character */
echo_char(c, tty);
while (--cnt > 0) {
head = (head+1) & (N_TTY_BUF_SIZE-1);
- echo_char_raw(tty->read_buf[head], tty);
- echo_move_back_col(tty);
+ echo_char_raw(ldata->read_buf[head],
+ ldata);
+ echo_move_back_col(ldata);
}
} else if (kill_type == ERASE && !L_ECHOE(tty)) {
echo_char(ERASE_CHAR(tty), tty);
} else if (c == '\t') {
unsigned int num_chars = 0;
int after_tab = 0;
- unsigned long tail = tty->read_head;
+ unsigned long tail = ldata->read_head;
/*
* Count the columns used for characters
@@ -953,9 +993,9 @@ static void eraser(unsigned char c, struct tty_struct *tty)
* This info is used to go back the correct
* number of columns.
*/
- while (tail != tty->canon_head) {
+ while (tail != ldata->canon_head) {
tail = (tail-1) & (N_TTY_BUF_SIZE-1);
- c = tty->read_buf[tail];
+ c = ldata->read_buf[tail];
if (c == '\t') {
after_tab = 1;
break;
@@ -966,25 +1006,25 @@ static void eraser(unsigned char c, struct tty_struct *tty)
num_chars++;
}
}
- echo_erase_tab(num_chars, after_tab, tty);
+ echo_erase_tab(num_chars, after_tab, ldata);
} else {
if (iscntrl(c) && L_ECHOCTL(tty)) {
- echo_char_raw('\b', tty);
- echo_char_raw(' ', tty);
- echo_char_raw('\b', tty);
+ echo_char_raw('\b', ldata);
+ echo_char_raw(' ', ldata);
+ echo_char_raw('\b', ldata);
}
if (!iscntrl(c) || L_ECHOCTL(tty)) {
- echo_char_raw('\b', tty);
- echo_char_raw(' ', tty);
- echo_char_raw('\b', tty);
+ echo_char_raw('\b', ldata);
+ echo_char_raw(' ', ldata);
+ echo_char_raw('\b', ldata);
}
}
}
if (kill_type == ERASE)
break;
}
- if (tty->read_head == tty->canon_head && L_ECHO(tty))
- finish_erasing(tty);
+ if (ldata->read_head == ldata->canon_head && L_ECHO(tty))
+ finish_erasing(ldata);
}
/**
@@ -1023,6 +1063,8 @@ static inline void isig(int sig, struct tty_struct *tty, int flush)
static inline void n_tty_receive_break(struct tty_struct *tty)
{
+ struct n_tty_data *ldata = tty->disc_data;
+
if (I_IGNBRK(tty))
return;
if (I_BRKINT(tty)) {
@@ -1030,10 +1072,10 @@ static inline void n_tty_receive_break(struct tty_struct *tty)
return;
}
if (I_PARMRK(tty)) {
- put_tty_queue('\377', tty);
- put_tty_queue('\0', tty);
+ put_tty_queue('\377', ldata);
+ put_tty_queue('\0', ldata);
}
- put_tty_queue('\0', tty);
+ put_tty_queue('\0', ldata);
wake_up_interruptible(&tty->read_wait);
}
@@ -1052,16 +1094,17 @@ static inline void n_tty_receive_break(struct tty_struct *tty)
static inline void n_tty_receive_overrun(struct tty_struct *tty)
{
+ struct n_tty_data *ldata = tty->disc_data;
char buf[64];
- tty->num_overrun++;
- if (time_before(tty->overrun_time, jiffies - HZ) ||
- time_after(tty->overrun_time, jiffies)) {
+ ldata->num_overrun++;
+ if (time_after(jiffies, ldata->overrun_time + HZ) ||
+ time_after(ldata->overrun_time, jiffies)) {
printk(KERN_WARNING "%s: %d input overrun(s)\n",
tty_name(tty, buf),
- tty->num_overrun);
- tty->overrun_time = jiffies;
- tty->num_overrun = 0;
+ ldata->num_overrun);
+ ldata->overrun_time = jiffies;
+ ldata->num_overrun = 0;
}
}
@@ -1076,16 +1119,18 @@ static inline void n_tty_receive_overrun(struct tty_struct *tty)
static inline void n_tty_receive_parity_error(struct tty_struct *tty,
unsigned char c)
{
+ struct n_tty_data *ldata = tty->disc_data;
+
if (I_IGNPAR(tty))
return;
if (I_PARMRK(tty)) {
- put_tty_queue('\377', tty);
- put_tty_queue('\0', tty);
- put_tty_queue(c, tty);
+ put_tty_queue('\377', ldata);
+ put_tty_queue('\0', ldata);
+ put_tty_queue(c, ldata);
} else if (I_INPCK(tty))
- put_tty_queue('\0', tty);
+ put_tty_queue('\0', ldata);
else
- put_tty_queue(c, tty);
+ put_tty_queue(c, ldata);
wake_up_interruptible(&tty->read_wait);
}
@@ -1101,11 +1146,12 @@ static inline void n_tty_receive_parity_error(struct tty_struct *tty,
static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
{
+ struct n_tty_data *ldata = tty->disc_data;
unsigned long flags;
int parmrk;
- if (tty->raw) {
- put_tty_queue(c, tty);
+ if (ldata->raw) {
+ put_tty_queue(c, ldata);
return;
}
@@ -1115,7 +1161,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
c = tolower(c);
if (L_EXTPROC(tty)) {
- put_tty_queue(c, tty);
+ put_tty_queue(c, ldata);
return;
}
@@ -1143,26 +1189,26 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
* handle specially, do shortcut processing to speed things
* up.
*/
- if (!test_bit(c, tty->process_char_map) || tty->lnext) {
- tty->lnext = 0;
+ if (!test_bit(c, ldata->process_char_map) || ldata->lnext) {
+ ldata->lnext = 0;
parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
- if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) {
+ if (ldata->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) {
/* beep if no space */
if (L_ECHO(tty))
process_output('\a', tty);
return;
}
if (L_ECHO(tty)) {
- finish_erasing(tty);
+ finish_erasing(ldata);
/* Record the column of first canon char. */
- if (tty->canon_head == tty->read_head)
- echo_set_canon_col(tty);
+ if (ldata->canon_head == ldata->read_head)
+ echo_set_canon_col(ldata);
echo_char(c, tty);
process_echoes(tty);
}
if (parmrk)
- put_tty_queue(c, tty);
- put_tty_queue(c, tty);
+ put_tty_queue(c, ldata);
+ put_tty_queue(c, ldata);
return;
}
@@ -1218,7 +1264,7 @@ send_signal:
} else if (c == '\n' && I_INLCR(tty))
c = '\r';
- if (tty->icanon) {
+ if (ldata->icanon) {
if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) ||
(c == WERASE_CHAR(tty) && L_IEXTEN(tty))) {
eraser(c, tty);
@@ -1226,12 +1272,12 @@ send_signal:
return;
}
if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) {
- tty->lnext = 1;
+ ldata->lnext = 1;
if (L_ECHO(tty)) {
- finish_erasing(tty);
+ finish_erasing(ldata);
if (L_ECHOCTL(tty)) {
- echo_char_raw('^', tty);
- echo_char_raw('\b', tty);
+ echo_char_raw('^', ldata);
+ echo_char_raw('\b', ldata);
process_echoes(tty);
}
}
@@ -1239,34 +1285,34 @@ send_signal:
}
if (c == REPRINT_CHAR(tty) && L_ECHO(tty) &&
L_IEXTEN(tty)) {
- unsigned long tail = tty->canon_head;
+ unsigned long tail = ldata->canon_head;
- finish_erasing(tty);
+ finish_erasing(ldata);
echo_char(c, tty);
- echo_char_raw('\n', tty);
- while (tail != tty->read_head) {
- echo_char(tty->read_buf[tail], tty);
+ echo_char_raw('\n', ldata);
+ while (tail != ldata->read_head) {
+ echo_char(ldata->read_buf[tail], tty);
tail = (tail+1) & (N_TTY_BUF_SIZE-1);
}
process_echoes(tty);
return;
}
if (c == '\n') {
- if (tty->read_cnt >= N_TTY_BUF_SIZE) {
+ if (ldata->read_cnt >= N_TTY_BUF_SIZE) {
if (L_ECHO(tty))
process_output('\a', tty);
return;
}
if (L_ECHO(tty) || L_ECHONL(tty)) {
- echo_char_raw('\n', tty);
+ echo_char_raw('\n', ldata);
process_echoes(tty);
}
goto handle_newline;
}
if (c == EOF_CHAR(tty)) {
- if (tty->read_cnt >= N_TTY_BUF_SIZE)
+ if (ldata->read_cnt >= N_TTY_BUF_SIZE)
return;
- if (tty->canon_head != tty->read_head)
+ if (ldata->canon_head != ldata->read_head)
set_bit(TTY_PUSH, &tty->flags);
c = __DISABLED_CHAR;
goto handle_newline;
@@ -1275,7 +1321,7 @@ send_signal:
(c == EOL2_CHAR(tty) && L_IEXTEN(tty))) {
parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty))
? 1 : 0;
- if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk)) {
+ if (ldata->read_cnt >= (N_TTY_BUF_SIZE - parmrk)) {
if (L_ECHO(tty))
process_output('\a', tty);
return;
@@ -1285,8 +1331,8 @@ send_signal:
*/
if (L_ECHO(tty)) {
/* Record the column of first canon char. */
- if (tty->canon_head == tty->read_head)
- echo_set_canon_col(tty);
+ if (ldata->canon_head == ldata->read_head)
+ echo_set_canon_col(ldata);
echo_char(c, tty);
process_echoes(tty);
}
@@ -1295,15 +1341,15 @@ send_signal:
* EOL_CHAR and EOL2_CHAR?
*/
if (parmrk)
- put_tty_queue(c, tty);
+ put_tty_queue(c, ldata);
handle_newline:
- spin_lock_irqsave(&tty->read_lock, flags);
- set_bit(tty->read_head, tty->read_flags);
- put_tty_queue_nolock(c, tty);
- tty->canon_head = tty->read_head;
- tty->canon_data++;
- spin_unlock_irqrestore(&tty->read_lock, flags);
+ spin_lock_irqsave(&ldata->read_lock, flags);
+ set_bit(ldata->read_head, ldata->read_flags);
+ put_tty_queue_nolock(c, ldata);
+ ldata->canon_head = ldata->read_head;
+ ldata->canon_data++;
+ spin_unlock_irqrestore(&ldata->read_lock, flags);
kill_fasync(&tty->fasync, SIGIO, POLL_IN);
if (waitqueue_active(&tty->read_wait))
wake_up_interruptible(&tty->read_wait);
@@ -1312,29 +1358,29 @@ handle_newline:
}
parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
- if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) {
+ if (ldata->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) {
/* beep if no space */
if (L_ECHO(tty))
process_output('\a', tty);
return;
}
if (L_ECHO(tty)) {
- finish_erasing(tty);
+ finish_erasing(ldata);
if (c == '\n')
- echo_char_raw('\n', tty);
+ echo_char_raw('\n', ldata);
else {
/* Record the column of first canon char. */
- if (tty->canon_head == tty->read_head)
- echo_set_canon_col(tty);
+ if (ldata->canon_head == ldata->read_head)
+ echo_set_canon_col(ldata);
echo_char(c, tty);
}
process_echoes(tty);
}
if (parmrk)
- put_tty_queue(c, tty);
+ put_tty_queue(c, ldata);
- put_tty_queue(c, tty);
+ put_tty_queue(c, ldata);
}
@@ -1369,33 +1415,31 @@ static void n_tty_write_wakeup(struct tty_struct *tty)
static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
char *fp, int count)
{
+ struct n_tty_data *ldata = tty->disc_data;
const unsigned char *p;
char *f, flags = TTY_NORMAL;
int i;
char buf[64];
unsigned long cpuflags;
- if (!tty->read_buf)
- return;
-
- if (tty->real_raw) {
- spin_lock_irqsave(&tty->read_lock, cpuflags);
- i = min(N_TTY_BUF_SIZE - tty->read_cnt,
- N_TTY_BUF_SIZE - tty->read_head);
+ if (ldata->real_raw) {
+ spin_lock_irqsave(&ldata->read_lock, cpuflags);
+ i = min(N_TTY_BUF_SIZE - ldata->read_cnt,
+ N_TTY_BUF_SIZE - ldata->read_head);
i = min(count, i);
- memcpy(tty->read_buf + tty->read_head, cp, i);
- tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
- tty->read_cnt += i;
+ memcpy(ldata->read_buf + ldata->read_head, cp, i);
+ ldata->read_head = (ldata->read_head + i) & (N_TTY_BUF_SIZE-1);
+ ldata->read_cnt += i;
cp += i;
count -= i;
- i = min(N_TTY_BUF_SIZE - tty->read_cnt,
- N_TTY_BUF_SIZE - tty->read_head);
+ i = min(N_TTY_BUF_SIZE - ldata->read_cnt,
+ N_TTY_BUF_SIZE - ldata->read_head);
i = min(count, i);
- memcpy(tty->read_buf + tty->read_head, cp, i);
- tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
- tty->read_cnt += i;
- spin_unlock_irqrestore(&tty->read_lock, cpuflags);
+ memcpy(ldata->read_buf + ldata->read_head, cp, i);
+ ldata->read_head = (ldata->read_head + i) & (N_TTY_BUF_SIZE-1);
+ ldata->read_cnt += i;
+ spin_unlock_irqrestore(&ldata->read_lock, cpuflags);
} else {
for (i = count, p = cp, f = fp; i; i--, p++) {
if (f)
@@ -1426,7 +1470,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
n_tty_set_room(tty);
- if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) ||
+ if ((!ldata->icanon && (ldata->read_cnt >= tty->minimum_to_wake)) ||
L_EXTPROC(tty)) {
kill_fasync(&tty->fasync, SIGIO, POLL_IN);
if (waitqueue_active(&tty->read_wait))
@@ -1470,25 +1514,25 @@ 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;
- BUG_ON(!tty);
if (old)
canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON;
if (canon_change) {
- memset(&tty->read_flags, 0, sizeof tty->read_flags);
- tty->canon_head = tty->read_tail;
- tty->canon_data = 0;
- tty->erasing = 0;
+ bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
+ ldata->canon_head = ldata->read_tail;
+ ldata->canon_data = 0;
+ ldata->erasing = 0;
}
- if (canon_change && !L_ICANON(tty) && tty->read_cnt)
+ if (canon_change && !L_ICANON(tty) && ldata->read_cnt)
wake_up_interruptible(&tty->read_wait);
- tty->icanon = (L_ICANON(tty) != 0);
+ ldata->icanon = (L_ICANON(tty) != 0);
if (test_bit(TTY_HW_COOK_IN, &tty->flags)) {
- tty->raw = 1;
- tty->real_raw = 1;
+ ldata->raw = 1;
+ ldata->real_raw = 1;
n_tty_set_room(tty);
return;
}
@@ -1496,51 +1540,51 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) ||
I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) ||
I_PARMRK(tty)) {
- memset(tty->process_char_map, 0, 256/8);
+ bitmap_zero(ldata->process_char_map, 256);
if (I_IGNCR(tty) || I_ICRNL(tty))
- set_bit('\r', tty->process_char_map);
+ set_bit('\r', ldata->process_char_map);
if (I_INLCR(tty))
- set_bit('\n', tty->process_char_map);
+ set_bit('\n', ldata->process_char_map);
if (L_ICANON(tty)) {
- set_bit(ERASE_CHAR(tty), tty->process_char_map);
- set_bit(KILL_CHAR(tty), tty->process_char_map);
- set_bit(EOF_CHAR(tty), tty->process_char_map);
- set_bit('\n', tty->process_char_map);
- set_bit(EOL_CHAR(tty), tty->process_char_map);
+ set_bit(ERASE_CHAR(tty), ldata->process_char_map);
+ set_bit(KILL_CHAR(tty), ldata->process_char_map);
+ set_bit(EOF_CHAR(tty), ldata->process_char_map);
+ set_bit('\n', ldata->process_char_map);
+ set_bit(EOL_CHAR(tty), ldata->process_char_map);
if (L_IEXTEN(tty)) {
set_bit(WERASE_CHAR(tty),
- tty->process_char_map);
+ ldata->process_char_map);
set_bit(LNEXT_CHAR(tty),
- tty->process_char_map);
+ ldata->process_char_map);
set_bit(EOL2_CHAR(tty),
- tty->process_char_map);
+ ldata->process_char_map);
if (L_ECHO(tty))
set_bit(REPRINT_CHAR(tty),
- tty->process_char_map);
+ ldata->process_char_map);
}
}
if (I_IXON(tty)) {
- set_bit(START_CHAR(tty), tty->process_char_map);
- set_bit(STOP_CHAR(tty), tty->process_char_map);
+ set_bit(START_CHAR(tty), ldata->process_char_map);
+ set_bit(STOP_CHAR(tty), ldata->process_char_map);
}
if (L_ISIG(tty)) {
- set_bit(INTR_CHAR(tty), tty->process_char_map);
- set_bit(QUIT_CHAR(tty), tty->process_char_map);
- set_bit(SUSP_CHAR(tty), tty->process_char_map);
+ set_bit(INTR_CHAR(tty), ldata->process_char_map);
+ set_bit(QUIT_CHAR(tty), ldata->process_char_map);
+ set_bit(SUSP_CHAR(tty), ldata->process_char_map);
}
- clear_bit(__DISABLED_CHAR, tty->process_char_map);
- tty->raw = 0;
- tty->real_raw = 0;
+ clear_bit(__DISABLED_CHAR, ldata->process_char_map);
+ ldata->raw = 0;
+ ldata->real_raw = 0;
} else {
- tty->raw = 1;
+ ldata->raw = 1;
if ((I_IGNBRK(tty) || (!I_BRKINT(tty) && !I_PARMRK(tty))) &&
(I_IGNPAR(tty) || !I_INPCK(tty)) &&
(tty->driver->flags & TTY_DRIVER_REAL_RAW))
- tty->real_raw = 1;
+ ldata->real_raw = 1;
else
- tty->real_raw = 0;
+ ldata->real_raw = 0;
}
n_tty_set_room(tty);
/* The termios change make the tty ready for I/O */
@@ -1560,15 +1604,13 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
static void n_tty_close(struct tty_struct *tty)
{
+ struct n_tty_data *ldata = tty->disc_data;
+
n_tty_flush_buffer(tty);
- if (tty->read_buf) {
- kfree(tty->read_buf);
- tty->read_buf = NULL;
- }
- if (tty->echo_buf) {
- kfree(tty->echo_buf);
- tty->echo_buf = NULL;
- }
+ kfree(ldata->read_buf);
+ kfree(ldata->echo_buf);
+ kfree(ldata);
+ tty->disc_data = NULL;
}
/**
@@ -1583,37 +1625,50 @@ static void n_tty_close(struct tty_struct *tty)
static int n_tty_open(struct tty_struct *tty)
{
- if (!tty)
- return -EINVAL;
+ struct n_tty_data *ldata;
+
+ ldata = kzalloc(sizeof(*ldata), GFP_KERNEL);
+ if (!ldata)
+ goto err;
+
+ ldata->overrun_time = jiffies;
+ mutex_init(&ldata->atomic_read_lock);
+ mutex_init(&ldata->output_lock);
+ mutex_init(&ldata->echo_lock);
+ spin_lock_init(&ldata->read_lock);
/* These are ugly. Currently a malloc failure here can panic */
- if (!tty->read_buf) {
- tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
- if (!tty->read_buf)
- return -ENOMEM;
- }
- if (!tty->echo_buf) {
- tty->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
+ ldata->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
+ ldata->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
+ if (!ldata->read_buf || !ldata->echo_buf)
+ goto err_free_bufs;
- if (!tty->echo_buf)
- return -ENOMEM;
- }
+ tty->disc_data = ldata;
reset_buffer_flags(tty);
tty_unthrottle(tty);
- tty->column = 0;
+ ldata->column = 0;
n_tty_set_termios(tty, NULL);
tty->minimum_to_wake = 1;
tty->closing = 0;
+
return 0;
+err_free_bufs:
+ kfree(ldata->read_buf);
+ kfree(ldata->echo_buf);
+ kfree(ldata);
+err:
+ return -ENOMEM;
}
static inline int input_available_p(struct tty_struct *tty, int amt)
{
+ struct n_tty_data *ldata = tty->disc_data;
+
tty_flush_to_ldisc(tty);
- if (tty->icanon && !L_EXTPROC(tty)) {
- if (tty->canon_data)
+ if (ldata->icanon && !L_EXTPROC(tty)) {
+ if (ldata->canon_data)
return 1;
- } else if (tty->read_cnt >= (amt ? amt : 1))
+ } else if (ldata->read_cnt >= (amt ? amt : 1))
return 1;
return 0;
@@ -1632,7 +1687,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt)
* buffer, and once to drain the space from the (physical) beginning of
* the buffer to head pointer.
*
- * Called under the tty->atomic_read_lock sem
+ * Called under the ldata->atomic_read_lock sem
*
*/
@@ -1641,29 +1696,31 @@ static int copy_from_read_buf(struct tty_struct *tty,
size_t *nr)
{
+ struct n_tty_data *ldata = tty->disc_data;
int retval;
size_t n;
unsigned long flags;
bool is_eof;
retval = 0;
- spin_lock_irqsave(&tty->read_lock, flags);
- n = min(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail);
+ spin_lock_irqsave(&ldata->read_lock, flags);
+ n = min(ldata->read_cnt, N_TTY_BUF_SIZE - ldata->read_tail);
n = min(*nr, n);
- spin_unlock_irqrestore(&tty->read_lock, flags);
+ spin_unlock_irqrestore(&ldata->read_lock, flags);
if (n) {
- retval = copy_to_user(*b, &tty->read_buf[tty->read_tail], n);
+ retval = copy_to_user(*b, &ldata->read_buf[ldata->read_tail], n);
n -= retval;
is_eof = n == 1 &&
- tty->read_buf[tty->read_tail] == EOF_CHAR(tty);
- tty_audit_add_data(tty, &tty->read_buf[tty->read_tail], n);
- spin_lock_irqsave(&tty->read_lock, flags);
- tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1);
- tty->read_cnt -= n;
+ ldata->read_buf[ldata->read_tail] == EOF_CHAR(tty);
+ tty_audit_add_data(tty, &ldata->read_buf[ldata->read_tail], n,
+ ldata->icanon);
+ spin_lock_irqsave(&ldata->read_lock, flags);
+ ldata->read_tail = (ldata->read_tail + n) & (N_TTY_BUF_SIZE-1);
+ ldata->read_cnt -= n;
/* Turn single EOF into zero-length read */
- if (L_EXTPROC(tty) && tty->icanon && is_eof && !tty->read_cnt)
+ if (L_EXTPROC(tty) && ldata->icanon && is_eof && !ldata->read_cnt)
n = 0;
- spin_unlock_irqrestore(&tty->read_lock, flags);
+ spin_unlock_irqrestore(&ldata->read_lock, flags);
*b += n;
*nr -= n;
}
@@ -1730,6 +1787,7 @@ static int job_control(struct tty_struct *tty, struct file *file)
static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
unsigned char __user *buf, size_t nr)
{
+ struct n_tty_data *ldata = tty->disc_data;
unsigned char __user *b = buf;
DECLARE_WAITQUEUE(wait, current);
int c;
@@ -1741,17 +1799,13 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
int packet;
do_it_again:
-
- if (WARN_ON(!tty->read_buf))
- return -EAGAIN;
-
c = job_control(tty, file);
if (c < 0)
return c;
minimum = time = 0;
timeout = MAX_SCHEDULE_TIMEOUT;
- if (!tty->icanon) {
+ if (!ldata->icanon) {
time = (HZ / 10) * TIME_CHAR(tty);
minimum = MIN_CHAR(tty);
if (minimum) {
@@ -1774,10 +1828,10 @@ do_it_again:
* Internal serialization of reads.
*/
if (file->f_flags & O_NONBLOCK) {
- if (!mutex_trylock(&tty->atomic_read_lock))
+ if (!mutex_trylock(&ldata->atomic_read_lock))
return -EAGAIN;
} else {
- if (mutex_lock_interruptible(&tty->atomic_read_lock))
+ if (mutex_lock_interruptible(&ldata->atomic_read_lock))
return -ERESTARTSYS;
}
packet = tty->packet;
@@ -1830,7 +1884,6 @@ do_it_again:
/* FIXME: does n_tty_set_room need locking ? */
n_tty_set_room(tty);
timeout = schedule_timeout(timeout);
- BUG_ON(!tty->read_buf);
continue;
}
__set_current_state(TASK_RUNNING);
@@ -1845,45 +1898,45 @@ do_it_again:
nr--;
}
- if (tty->icanon && !L_EXTPROC(tty)) {
+ if (ldata->icanon && !L_EXTPROC(tty)) {
/* N.B. avoid overrun if nr == 0 */
- spin_lock_irqsave(&tty->read_lock, flags);
- while (nr && tty->read_cnt) {
+ spin_lock_irqsave(&ldata->read_lock, flags);
+ while (nr && ldata->read_cnt) {
int eol;
- eol = test_and_clear_bit(tty->read_tail,
- tty->read_flags);
- c = tty->read_buf[tty->read_tail];
- tty->read_tail = ((tty->read_tail+1) &
+ eol = test_and_clear_bit(ldata->read_tail,
+ ldata->read_flags);
+ c = ldata->read_buf[ldata->read_tail];
+ ldata->read_tail = ((ldata->read_tail+1) &
(N_TTY_BUF_SIZE-1));
- tty->read_cnt--;
+ ldata->read_cnt--;
if (eol) {
/* this test should be redundant:
* we shouldn't be reading data if
* canon_data is 0
*/
- if (--tty->canon_data < 0)
- tty->canon_data = 0;
+ if (--ldata->canon_data < 0)
+ ldata->canon_data = 0;
}
- spin_unlock_irqrestore(&tty->read_lock, flags);
+ spin_unlock_irqrestore(&ldata->read_lock, flags);
if (!eol || (c != __DISABLED_CHAR)) {
if (tty_put_user(tty, c, b++)) {
retval = -EFAULT;
b--;
- spin_lock_irqsave(&tty->read_lock, flags);
+ spin_lock_irqsave(&ldata->read_lock, flags);
break;
}
nr--;
}
if (eol) {
tty_audit_push(tty);
- spin_lock_irqsave(&tty->read_lock, flags);
+ spin_lock_irqsave(&ldata->read_lock, flags);
break;
}
- spin_lock_irqsave(&tty->read_lock, flags);
+ spin_lock_irqsave(&ldata->read_lock, flags);
}
- spin_unlock_irqrestore(&tty->read_lock, flags);
+ spin_unlock_irqrestore(&ldata->read_lock, flags);
if (retval)
break;
} else {
@@ -1915,7 +1968,7 @@ do_it_again:
if (time)
timeout = time;
}
- mutex_unlock(&tty->atomic_read_lock);
+ mutex_unlock(&ldata->atomic_read_lock);
remove_wait_queue(&tty->read_wait, &wait);
if (!waitqueue_active(&tty->read_wait))
@@ -2076,19 +2129,19 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
return mask;
}
-static unsigned long inq_canon(struct tty_struct *tty)
+static unsigned long inq_canon(struct n_tty_data *ldata)
{
int nr, head, tail;
- if (!tty->canon_data)
+ if (!ldata->canon_data)
return 0;
- head = tty->canon_head;
- tail = tty->read_tail;
+ head = ldata->canon_head;
+ tail = ldata->read_tail;
nr = (head - tail) & (N_TTY_BUF_SIZE-1);
/* Skip EOF-chars.. */
while (head != tail) {
- if (test_bit(tail, tty->read_flags) &&
- tty->read_buf[tail] == __DISABLED_CHAR)
+ if (test_bit(tail, ldata->read_flags) &&
+ ldata->read_buf[tail] == __DISABLED_CHAR)
nr--;
tail = (tail+1) & (N_TTY_BUF_SIZE-1);
}
@@ -2098,6 +2151,7 @@ static unsigned long inq_canon(struct tty_struct *tty)
static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ struct n_tty_data *ldata = tty->disc_data;
int retval;
switch (cmd) {
@@ -2105,9 +2159,9 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
case TIOCINQ:
/* FIXME: Locking */
- retval = tty->read_cnt;
+ retval = ldata->read_cnt;
if (L_ICANON(tty))
- retval = inq_canon(tty);
+ retval = inq_canon(ldata);
return put_user(retval, (unsigned int __user *) arg);
default:
return n_tty_ioctl_helper(tty, file, cmd, arg);
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c
index b917c942495..a0c69ab0439 100644
--- a/drivers/tty/nozomi.c
+++ b/drivers/tty/nozomi.c
@@ -400,7 +400,7 @@ struct buffer {
} __attribute__ ((packed));
/* Global variables */
-static const struct pci_device_id nozomi_pci_tbl[] __devinitconst = {
+static const struct pci_device_id nozomi_pci_tbl[] = {
{PCI_DEVICE(0x1931, 0x000c)}, /* Nozomi HSDPA */
{},
};
@@ -1360,7 +1360,7 @@ static void remove_sysfs_files(struct nozomi *dc)
}
/* Allocate memory for one device */
-static int __devinit nozomi_card_init(struct pci_dev *pdev,
+static int nozomi_card_init(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
resource_size_t start;
@@ -1479,6 +1479,7 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
if (IS_ERR(tty_dev)) {
ret = PTR_ERR(tty_dev);
dev_err(&pdev->dev, "Could not allocate tty?\n");
+ tty_port_destroy(&port->port);
goto err_free_tty;
}
}
@@ -1486,8 +1487,10 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
return 0;
err_free_tty:
- for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i)
- tty_unregister_device(ntty_driver, i);
+ for (i = 0; i < MAX_PORT; ++i) {
+ tty_unregister_device(ntty_driver, dc->index_start + i);
+ tty_port_destroy(&dc->port[i].port);
+ }
err_free_kfifo:
for (i = 0; i < MAX_PORT; i++)
kfifo_free(&dc->port[i].fifo_ul);
@@ -1504,7 +1507,7 @@ err:
return ret;
}
-static void __devexit tty_exit(struct nozomi *dc)
+static void tty_exit(struct nozomi *dc)
{
unsigned int i;
@@ -1520,12 +1523,14 @@ static void __devexit tty_exit(struct nozomi *dc)
complete off a hangup method ? */
while (dc->open_ttys)
msleep(1);
- for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i)
- tty_unregister_device(ntty_driver, i);
+ for (i = 0; i < MAX_PORT; ++i) {
+ tty_unregister_device(ntty_driver, dc->index_start + i);
+ tty_port_destroy(&dc->port[i].port);
+ }
}
/* Deallocate memory for one device */
-static void __devexit nozomi_card_exit(struct pci_dev *pdev)
+static void nozomi_card_exit(struct pci_dev *pdev)
{
int i;
struct ctrl_ul ctrl;
@@ -1903,7 +1908,7 @@ static struct pci_driver nozomi_driver = {
.name = NOZOMI_NAME,
.id_table = nozomi_pci_tbl,
.probe = nozomi_card_init,
- .remove = __devexit_p(nozomi_card_exit),
+ .remove = nozomi_card_exit,
};
static __init int nozomi_init(void)
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index a82b39939a9..be6a373601b 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -4,9 +4,6 @@
* Added support for a Unix98-style ptmx device.
* -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
*
- * When reading this code see also fs/devpts. In particular note that the
- * driver_data field is used by the devpts side as a binding to the devpts
- * inode.
*/
#include <linux/module.h>
@@ -59,7 +56,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
#ifdef CONFIG_UNIX98_PTYS
if (tty->driver == ptm_driver) {
mutex_lock(&devpts_mutex);
- devpts_pty_kill(tty->link);
+ devpts_pty_kill(tty->link->driver_data);
mutex_unlock(&devpts_mutex);
}
#endif
@@ -96,7 +93,7 @@ static void pty_unthrottle(struct tty_struct *tty)
static int pty_space(struct tty_struct *to)
{
- int n = 8192 - to->buf.memory_used;
+ int n = 8192 - to->port->buf.memory_used;
if (n < 0)
return 0;
return n;
@@ -174,6 +171,41 @@ static int pty_set_lock(struct tty_struct *tty, int __user *arg)
return 0;
}
+static int pty_get_lock(struct tty_struct *tty, int __user *arg)
+{
+ int locked = test_bit(TTY_PTY_LOCK, &tty->flags);
+ return put_user(locked, arg);
+}
+
+/* Set the packet mode on a pty */
+static int pty_set_pktmode(struct tty_struct *tty, int __user *arg)
+{
+ unsigned long flags;
+ int pktmode;
+
+ if (get_user(pktmode, arg))
+ return -EFAULT;
+
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
+ if (pktmode) {
+ if (!tty->packet) {
+ tty->packet = 1;
+ tty->link->ctrl_status = 0;
+ }
+ } else
+ tty->packet = 0;
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+
+ return 0;
+}
+
+/* Get the packet mode of a pty */
+static int pty_get_pktmode(struct tty_struct *tty, int __user *arg)
+{
+ int pktmode = tty->packet;
+ return put_user(pktmode, arg);
+}
+
/* Send a signal to the slave */
static int pty_signal(struct tty_struct *tty, int sig)
{
@@ -245,7 +277,7 @@ static void pty_set_termios(struct tty_struct *tty,
* peform a terminal resize correctly
*/
-int pty_resize(struct tty_struct *tty, struct winsize *ws)
+static int pty_resize(struct tty_struct *tty, struct winsize *ws)
{
struct pid *pgrp, *rpgrp;
unsigned long flags;
@@ -348,6 +380,7 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty,
tty_port_init(ports[1]);
o_tty->port = ports[0];
tty->port = ports[1];
+ o_tty->port->itty = o_tty;
tty_driver_kref_get(driver);
tty->count++;
@@ -366,9 +399,16 @@ err:
return retval;
}
+/* this is called once with whichever end is closed last */
+static void pty_unix98_shutdown(struct tty_struct *tty)
+{
+ devpts_kill_index(tty->driver_data, tty->index);
+}
+
static void pty_cleanup(struct tty_struct *tty)
{
- kfree(tty->port);
+ tty->port->itty = NULL;
+ tty_port_put(tty->port);
}
/* Traditional BSD devices */
@@ -393,6 +433,12 @@ static int pty_bsd_ioctl(struct tty_struct *tty,
switch (cmd) {
case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
return pty_set_lock(tty, (int __user *) arg);
+ case TIOCGPTLCK: /* Get PT Lock status */
+ return pty_get_lock(tty, (int __user *)arg);
+ case TIOCPKT: /* Set PT packet mode */
+ return pty_set_pktmode(tty, (int __user *)arg);
+ case TIOCGPKT: /* Get PT packet mode */
+ return pty_get_pktmode(tty, (int __user *)arg);
case TIOCSIG: /* Send signal to other side of pty */
return pty_signal(tty, (int) arg);
}
@@ -507,6 +553,12 @@ static int pty_unix98_ioctl(struct tty_struct *tty,
switch (cmd) {
case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
return pty_set_lock(tty, (int __user *)arg);
+ case TIOCGPTLCK: /* Get PT Lock status */
+ return pty_get_lock(tty, (int __user *)arg);
+ case TIOCPKT: /* Set PT packet mode */
+ return pty_set_pktmode(tty, (int __user *)arg);
+ case TIOCGPKT: /* Get PT packet mode */
+ return pty_get_pktmode(tty, (int __user *)arg);
case TIOCGPTN: /* Get PT Number */
return put_user(tty->index, (unsigned int __user *)arg);
case TIOCSIG: /* Send signal to other side of pty */
@@ -547,7 +599,7 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
struct tty_struct *tty;
mutex_lock(&devpts_mutex);
- tty = devpts_get_tty(pts_inode, idx);
+ tty = devpts_get_priv(pts_inode);
mutex_unlock(&devpts_mutex);
/* Master must be open before slave */
if (!tty)
@@ -581,6 +633,7 @@ static const struct tty_operations ptm_unix98_ops = {
.set_termios = pty_set_termios,
.ioctl = pty_unix98_ioctl,
.resize = pty_resize,
+ .shutdown = pty_unix98_shutdown,
.cleanup = pty_cleanup
};
@@ -596,6 +649,7 @@ static const struct tty_operations pty_unix98_ops = {
.chars_in_buffer = pty_chars_in_buffer,
.unthrottle = pty_unthrottle,
.set_termios = pty_set_termios,
+ .shutdown = pty_unix98_shutdown,
.cleanup = pty_cleanup,
};
@@ -614,6 +668,7 @@ static const struct tty_operations pty_unix98_ops = {
static int ptmx_open(struct inode *inode, struct file *filp)
{
struct tty_struct *tty;
+ struct inode *slave_inode;
int retval;
int index;
@@ -650,15 +705,21 @@ static int ptmx_open(struct inode *inode, struct file *filp)
tty_add_file(tty, filp);
- retval = devpts_pty_new(inode, tty->link);
- if (retval)
+ slave_inode = devpts_pty_new(inode,
+ MKDEV(UNIX98_PTY_SLAVE_MAJOR, index), index,
+ tty->link);
+ if (IS_ERR(slave_inode)) {
+ retval = PTR_ERR(slave_inode);
goto err_release;
+ }
retval = ptm_driver->ops->open(tty, filp);
if (retval)
goto err_release;
tty_unlock(tty);
+ tty->driver_data = inode;
+ tty->link->driver_data = slave_inode;
return 0;
err_release:
tty_unlock(tty);
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c
index 9700d34b20a..e42009a0052 100644
--- a/drivers/tty/rocket.c
+++ b/drivers/tty/rocket.c
@@ -673,6 +673,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) {
printk(KERN_ERR "RocketPort sInitChan(%d, %d, %d) failed!\n",
board, aiop, chan);
+ tty_port_destroy(&info->port);
kfree(info);
return;
}
@@ -1757,7 +1758,7 @@ static void rp_flush_buffer(struct tty_struct *tty)
#ifdef CONFIG_PCI
-static struct pci_device_id __devinitdata __used rocket_pci_ids[] = {
+static struct pci_device_id __used rocket_pci_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) },
{ }
};
@@ -2357,6 +2358,7 @@ static void rp_cleanup_module(void)
for (i = 0; i < MAX_RP_PORTS; i++)
if (rp_table[i]) {
tty_unregister_device(rocket_driver, i);
+ tty_port_destroy(&rp_table[i]->port);
kfree(rp_table[i]);
}
diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
index 66c38a3f74c..f99a84526f8 100644
--- a/drivers/tty/serial/68328serial.c
+++ b/drivers/tty/serial/68328serial.c
@@ -1225,6 +1225,8 @@ rs68328_init(void)
if (tty_register_driver(serial_driver)) {
put_tty_driver(serial_driver);
+ for (i = 0; i < NR_PORTS; i++)
+ tty_port_destroy(&m68k_soft[i].tport);
printk(KERN_ERR "Couldn't register serial driver\n");
return -ENOMEM;
}
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index 3ba4234592b..d085e3a8ec0 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -280,7 +280,17 @@ static const struct serial8250_config uart_config[] = {
.fifo_size = 64,
.tx_loadsz = 64,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
- .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR,
+ .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR |
+ UART_CAP_SLEEP,
+ },
+ [PORT_XR17V35X] = {
+ .name = "XR17V35X",
+ .fifo_size = 256,
+ .tx_loadsz = 256,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11 |
+ UART_FCR_T_TRIG_11,
+ .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR |
+ UART_CAP_SLEEP,
},
[PORT_LPC3220] = {
.name = "LPC3220",
@@ -455,6 +465,7 @@ static void io_serial_out(struct uart_port *p, int offset, int value)
}
static int serial8250_default_handle_irq(struct uart_port *port);
+static int exar_handle_irq(struct uart_port *port);
static void set_io_from_upio(struct uart_port *p)
{
@@ -574,6 +585,19 @@ EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos);
*/
static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
{
+ /*
+ * Exar UARTs have a SLEEP register that enables or disables
+ * each UART to enter sleep mode separately. On the XR17V35x the
+ * register is accessible to each UART at the UART_EXAR_SLEEP
+ * offset but the UART channel may only write to the corresponding
+ * bit.
+ */
+ if ((p->port.type == PORT_XR17V35X) ||
+ (p->port.type == PORT_XR17D15X)) {
+ serial_out(p, UART_EXAR_SLEEP, 0xff);
+ return;
+ }
+
if (p->capabilities & UART_CAP_SLEEP) {
if (p->capabilities & UART_CAP_EFR) {
serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B);
@@ -882,6 +906,27 @@ static void autoconfig_16550a(struct uart_8250_port *up)
up->capabilities |= UART_CAP_FIFO;
/*
+ * XR17V35x UARTs have an extra divisor register, DLD
+ * that gets enabled with when DLAB is set which will
+ * cause the device to incorrectly match and assign
+ * port type to PORT_16650. The EFR for this UART is
+ * found at offset 0x09. Instead check the Deice ID (DVID)
+ * register for a 2, 4 or 8 port UART.
+ */
+ if (up->port.flags & UPF_EXAR_EFR) {
+ status1 = serial_in(up, UART_EXAR_DVID);
+ if (status1 == 0x82 || status1 == 0x84 || status1 == 0x88) {
+ DEBUG_AUTOCONF("Exar XR17V35x ");
+ up->port.type = PORT_XR17V35X;
+ up->capabilities |= UART_CAP_AFE | UART_CAP_EFR |
+ UART_CAP_SLEEP;
+
+ return;
+ }
+
+ }
+
+ /*
* Check for presence of the EFR when DLAB is set.
* Only ST16C650V1 UARTs pass this test.
*/
@@ -1013,8 +1058,12 @@ static void autoconfig_16550a(struct uart_8250_port *up)
* Exar uarts have EFR in a weird location
*/
if (up->port.flags & UPF_EXAR_EFR) {
+ DEBUG_AUTOCONF("Exar XR17D15x ");
up->port.type = PORT_XR17D15X;
- up->capabilities |= UART_CAP_AFE | UART_CAP_EFR;
+ up->capabilities |= UART_CAP_AFE | UART_CAP_EFR |
+ UART_CAP_SLEEP;
+
+ return;
}
/*
@@ -1516,6 +1565,31 @@ static int serial8250_default_handle_irq(struct uart_port *port)
}
/*
+ * These Exar UARTs have an extra interrupt indicator that could
+ * fire for a few unimplemented interrupts. One of which is a
+ * wakeup event when coming out of sleep. Put this here just
+ * to be on the safe side that these interrupts don't go unhandled.
+ */
+static int exar_handle_irq(struct uart_port *port)
+{
+ unsigned char int0, int1, int2, int3;
+ unsigned int iir = serial_port_in(port, UART_IIR);
+ int ret;
+
+ ret = serial8250_handle_irq(port, iir);
+
+ if ((port->type == PORT_XR17V35X) ||
+ (port->type == PORT_XR17D15X)) {
+ int0 = serial_port_in(port, 0x80);
+ int1 = serial_port_in(port, 0x81);
+ int2 = serial_port_in(port, 0x82);
+ int3 = serial_port_in(port, 0x83);
+ }
+
+ return ret;
+}
+
+/*
* This is the serial driver's interrupt routine.
*
* Arjan thinks the old way was overly complex, so it got simplified.
@@ -2349,16 +2423,14 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
serial_port_out(port, UART_EFR, efr);
}
-#ifdef CONFIG_ARCH_OMAP1
/* Workaround to enable 115200 baud on OMAP1510 internal ports */
- if (cpu_is_omap1510() && is_omap_port(up)) {
+ if (is_omap1510_8250(up)) {
if (baud == 115200) {
quot = 1;
serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1);
} else
serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0);
}
-#endif
/*
* For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2,
@@ -2439,10 +2511,9 @@ static unsigned int serial8250_port_size(struct uart_8250_port *pt)
{
if (pt->port.iotype == UPIO_AU)
return 0x1000;
-#ifdef CONFIG_ARCH_OMAP1
- if (is_omap_port(pt))
+ if (is_omap1_8250(pt))
return 0x16 << pt->port.regshift;
-#endif
+
return 8 << pt->port.regshift;
}
@@ -2617,6 +2688,11 @@ static void serial8250_config_port(struct uart_port *port, int flags)
serial8250_release_rsa_resource(up);
if (port->type == PORT_UNKNOWN)
serial8250_release_std_resource(up);
+
+ /* Fixme: probably not the best place for this */
+ if ((port->type == PORT_XR17V35X) ||
+ (port->type == PORT_XR17D15X))
+ port->handle_irq = exar_handle_irq;
}
static int
@@ -2992,7 +3068,7 @@ void serial8250_resume_port(int line)
* list is terminated with a zero flags entry, which means we expect
* all entries to have at least UPF_BOOT_AUTOCONF set.
*/
-static int __devinit serial8250_probe(struct platform_device *dev)
+static int serial8250_probe(struct platform_device *dev)
{
struct plat_serial8250_port *p = dev->dev.platform_data;
struct uart_8250_port uart;
@@ -3038,7 +3114,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
/*
* Remove serial ports registered against a platform device.
*/
-static int __devexit serial8250_remove(struct platform_device *dev)
+static int serial8250_remove(struct platform_device *dev)
{
int i;
@@ -3081,7 +3157,7 @@ static int serial8250_resume(struct platform_device *dev)
static struct platform_driver serial8250_isa_driver = {
.probe = serial8250_probe,
- .remove = __devexit_p(serial8250_remove),
+ .remove = serial8250_remove,
.suspend = serial8250_suspend,
.resume = serial8250_resume,
.driver = {
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index 5a76f9c8d36..3b4ea84898c 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -106,3 +106,39 @@ static inline int serial8250_pnp_init(void) { return 0; }
static inline void serial8250_pnp_exit(void) { }
#endif
+#ifdef CONFIG_ARCH_OMAP1
+static inline int is_omap1_8250(struct uart_8250_port *pt)
+{
+ int res;
+
+ switch (pt->port.mapbase) {
+ case OMAP1_UART1_BASE:
+ case OMAP1_UART2_BASE:
+ case OMAP1_UART3_BASE:
+ res = 1;
+ break;
+ default:
+ res = 0;
+ break;
+ }
+
+ return res;
+}
+
+static inline int is_omap1510_8250(struct uart_8250_port *pt)
+{
+ if (!cpu_is_omap1510())
+ return 0;
+
+ return is_omap1_8250(pt);
+}
+#else
+static inline int is_omap1_8250(struct uart_8250_port *pt)
+{
+ return 0;
+}
+static inline int is_omap1510_8250(struct uart_8250_port *pt)
+{
+ return 0;
+}
+#endif
diff --git a/drivers/tty/serial/8250/8250_acorn.c b/drivers/tty/serial/8250/8250_acorn.c
index 857498312a9..549aa07c0d2 100644
--- a/drivers/tty/serial/8250/8250_acorn.c
+++ b/drivers/tty/serial/8250/8250_acorn.c
@@ -38,7 +38,7 @@ struct serial_card_info {
void __iomem *vaddr;
};
-static int __devinit
+static int
serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
{
struct serial_card_info *info;
@@ -80,7 +80,7 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
return 0;
}
-static void __devexit serial_card_remove(struct expansion_card *ec)
+static void serial_card_remove(struct expansion_card *ec)
{
struct serial_card_info *info = ecard_get_drvdata(ec);
int i;
@@ -116,7 +116,7 @@ static const struct ecard_id serial_cids[] = {
static struct ecard_driver serial_card_driver = {
.probe = serial_card_probe,
- .remove = __devexit_p(serial_card_remove),
+ .remove = serial_card_remove,
.id_table = serial_cids,
.drv = {
.name = "8250_acorn",
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index c3b2ec0c8c0..1d0dba2d562 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -87,7 +87,7 @@ static int dw8250_handle_irq(struct uart_port *p)
return 0;
}
-static int __devinit dw8250_probe(struct platform_device *pdev)
+static int dw8250_probe(struct platform_device *pdev)
{
struct uart_8250_port uart = {};
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -152,7 +152,7 @@ static int __devinit dw8250_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit dw8250_remove(struct platform_device *pdev)
+static int dw8250_remove(struct platform_device *pdev)
{
struct dw8250_data *data = platform_get_drvdata(pdev);
@@ -161,6 +161,29 @@ static int __devexit dw8250_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM
+static int dw8250_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct dw8250_data *data = platform_get_drvdata(pdev);
+
+ serial8250_suspend_port(data->line);
+
+ return 0;
+}
+
+static int dw8250_resume(struct platform_device *pdev)
+{
+ struct dw8250_data *data = platform_get_drvdata(pdev);
+
+ serial8250_resume_port(data->line);
+
+ return 0;
+}
+#else
+#define dw8250_suspend NULL
+#define dw8250_resume NULL
+#endif /* CONFIG_PM */
+
static const struct of_device_id dw8250_match[] = {
{ .compatible = "snps,dw-apb-uart" },
{ /* Sentinel */ }
@@ -174,7 +197,9 @@ static struct platform_driver dw8250_platform_driver = {
.of_match_table = dw8250_match,
},
.probe = dw8250_probe,
- .remove = __devexit_p(dw8250_remove),
+ .remove = dw8250_remove,
+ .suspend = dw8250_suspend,
+ .resume = dw8250_resume,
};
module_platform_driver(dw8250_platform_driver);
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c
index eaafb98debe..f53a7db4350 100644
--- a/drivers/tty/serial/8250/8250_early.c
+++ b/drivers/tty/serial/8250/8250_early.c
@@ -48,7 +48,7 @@ struct early_serial8250_device {
static struct early_serial8250_device early_device;
-static unsigned int __init serial_in(struct uart_port *port, int offset)
+unsigned int __weak __init serial8250_early_in(struct uart_port *port, int offset)
{
switch (port->iotype) {
case UPIO_MEM:
@@ -62,7 +62,7 @@ static unsigned int __init serial_in(struct uart_port *port, int offset)
}
}
-static void __init serial_out(struct uart_port *port, int offset, int value)
+void __weak __init serial8250_early_out(struct uart_port *port, int offset, int value)
{
switch (port->iotype) {
case UPIO_MEM:
@@ -84,7 +84,7 @@ static void __init wait_for_xmitr(struct uart_port *port)
unsigned int status;
for (;;) {
- status = serial_in(port, UART_LSR);
+ status = serial8250_early_in(port, UART_LSR);
if ((status & BOTH_EMPTY) == BOTH_EMPTY)
return;
cpu_relax();
@@ -94,7 +94,7 @@ static void __init wait_for_xmitr(struct uart_port *port)
static void __init serial_putc(struct uart_port *port, int c)
{
wait_for_xmitr(port);
- serial_out(port, UART_TX, c);
+ serial8250_early_out(port, UART_TX, c);
}
static void __init early_serial8250_write(struct console *console,
@@ -104,14 +104,14 @@ static void __init early_serial8250_write(struct console *console,
unsigned int ier;
/* Save the IER and disable interrupts */
- ier = serial_in(port, UART_IER);
- serial_out(port, UART_IER, 0);
+ ier = serial8250_early_in(port, UART_IER);
+ serial8250_early_out(port, UART_IER, 0);
uart_console_write(port, s, count, serial_putc);
/* Wait for transmitter to become empty and restore the IER */
wait_for_xmitr(port);
- serial_out(port, UART_IER, ier);
+ serial8250_early_out(port, UART_IER, ier);
}
static unsigned int __init probe_baud(struct uart_port *port)
@@ -119,11 +119,11 @@ static unsigned int __init probe_baud(struct uart_port *port)
unsigned char lcr, dll, dlm;
unsigned int quot;
- lcr = serial_in(port, UART_LCR);
- serial_out(port, UART_LCR, lcr | UART_LCR_DLAB);
- dll = serial_in(port, UART_DLL);
- dlm = serial_in(port, UART_DLM);
- serial_out(port, UART_LCR, lcr);
+ lcr = serial8250_early_in(port, UART_LCR);
+ serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB);
+ dll = serial8250_early_in(port, UART_DLL);
+ dlm = serial8250_early_in(port, UART_DLM);
+ serial8250_early_out(port, UART_LCR, lcr);
quot = (dlm << 8) | dll;
return (port->uartclk / 16) / quot;
@@ -135,17 +135,17 @@ static void __init init_port(struct early_serial8250_device *device)
unsigned int divisor;
unsigned char c;
- serial_out(port, UART_LCR, 0x3); /* 8n1 */
- serial_out(port, UART_IER, 0); /* no interrupt */
- serial_out(port, UART_FCR, 0); /* no fifo */
- serial_out(port, UART_MCR, 0x3); /* DTR + RTS */
-
- divisor = port->uartclk / (16 * device->baud);
- c = serial_in(port, UART_LCR);
- serial_out(port, UART_LCR, c | UART_LCR_DLAB);
- serial_out(port, UART_DLL, divisor & 0xff);
- serial_out(port, UART_DLM, (divisor >> 8) & 0xff);
- serial_out(port, UART_LCR, c & ~UART_LCR_DLAB);
+ serial8250_early_out(port, UART_LCR, 0x3); /* 8n1 */
+ serial8250_early_out(port, UART_IER, 0); /* no interrupt */
+ serial8250_early_out(port, UART_FCR, 0); /* no fifo */
+ serial8250_early_out(port, UART_MCR, 0x3); /* DTR + RTS */
+
+ divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * device->baud);
+ c = serial8250_early_in(port, UART_LCR);
+ serial8250_early_out(port, UART_LCR, c | UART_LCR_DLAB);
+ serial8250_early_out(port, UART_DLL, divisor & 0xff);
+ serial8250_early_out(port, UART_DLM, (divisor >> 8) & 0xff);
+ serial8250_early_out(port, UART_LCR, c & ~UART_LCR_DLAB);
}
static int __init parse_options(struct early_serial8250_device *device,
diff --git a/drivers/tty/serial/8250/8250_em.c b/drivers/tty/serial/8250/8250_em.c
index 3a0363e7f3a..916cc19fbbd 100644
--- a/drivers/tty/serial/8250/8250_em.c
+++ b/drivers/tty/serial/8250/8250_em.c
@@ -89,7 +89,7 @@ static void serial8250_em_serial_dl_write(struct uart_8250_port *up, int value)
serial_out(up, UART_DLM_EM, value >> 8 & 0xff);
}
-static int __devinit serial8250_em_probe(struct platform_device *pdev)
+static int serial8250_em_probe(struct platform_device *pdev)
{
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -152,7 +152,7 @@ static int __devinit serial8250_em_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit serial8250_em_remove(struct platform_device *pdev)
+static int serial8250_em_remove(struct platform_device *pdev)
{
struct serial8250_em_priv *priv = platform_get_drvdata(pdev);
@@ -163,7 +163,7 @@ static int __devexit serial8250_em_remove(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id serial8250_em_dt_ids[] __devinitconst = {
+static const struct of_device_id serial8250_em_dt_ids[] = {
{ .compatible = "renesas,em-uart", },
{},
};
@@ -176,7 +176,7 @@ static struct platform_driver serial8250_em_platform_driver = {
.owner = THIS_MODULE,
},
.probe = serial8250_em_probe,
- .remove = __devexit_p(serial8250_em_remove),
+ .remove = serial8250_em_remove,
};
module_platform_driver(serial8250_em_platform_driver);
diff --git a/drivers/tty/serial/8250/8250_hp300.c b/drivers/tty/serial/8250/8250_hp300.c
index f3d0edf4664..5bdaf271d39 100644
--- a/drivers/tty/serial/8250/8250_hp300.c
+++ b/drivers/tty/serial/8250/8250_hp300.c
@@ -36,9 +36,9 @@ static struct hp300_port *hp300_ports;
#ifdef CONFIG_HPDCA
-static int __devinit hpdca_init_one(struct dio_dev *d,
+static int hpdca_init_one(struct dio_dev *d,
const struct dio_device_id *ent);
-static void __devexit hpdca_remove_one(struct dio_dev *d);
+static void hpdca_remove_one(struct dio_dev *d);
static struct dio_device_id hpdca_dio_tbl[] = {
{ DIO_ID_DCA0 },
@@ -52,7 +52,7 @@ static struct dio_driver hpdca_driver = {
.name = "hpdca",
.id_table = hpdca_dio_tbl,
.probe = hpdca_init_one,
- .remove = __devexit_p(hpdca_remove_one),
+ .remove = hpdca_remove_one,
};
#endif
@@ -159,7 +159,7 @@ int __init hp300_setup_serial_console(void)
#endif /* CONFIG_SERIAL_8250_CONSOLE */
#ifdef CONFIG_HPDCA
-static int __devinit hpdca_init_one(struct dio_dev *d,
+static int hpdca_init_one(struct dio_dev *d,
const struct dio_device_id *ent)
{
struct uart_8250_port uart;
@@ -288,7 +288,7 @@ static int __init hp300_8250_init(void)
}
#ifdef CONFIG_HPDCA
-static void __devexit hpdca_remove_one(struct dio_dev *d)
+static void hpdca_remove_one(struct dio_dev *d)
{
int line;
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 17b7d26abf4..26b9dc012ed 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -288,7 +288,7 @@ static int pci_plx9050_init(struct pci_dev *dev)
return 0;
}
-static void __devexit pci_plx9050_exit(struct pci_dev *dev)
+static void pci_plx9050_exit(struct pci_dev *dev)
{
u8 __iomem *p;
@@ -313,7 +313,7 @@ static void __devexit pci_plx9050_exit(struct pci_dev *dev)
#define NI8420_INT_ENABLE_REG 0x38
#define NI8420_INT_ENABLE_BIT 0x2000
-static void __devexit pci_ni8420_exit(struct pci_dev *dev)
+static void pci_ni8420_exit(struct pci_dev *dev)
{
void __iomem *p;
unsigned long base, len;
@@ -345,7 +345,7 @@ static void __devexit pci_ni8420_exit(struct pci_dev *dev)
#define MITE_LCIMR2_CLR_CPU_IE (1 << 30)
-static void __devexit pci_ni8430_exit(struct pci_dev *dev)
+static void pci_ni8430_exit(struct pci_dev *dev)
{
void __iomem *p;
unsigned long base, len;
@@ -422,7 +422,7 @@ static int sbs_init(struct pci_dev *dev)
* Disables the global interrupt of PMC-OctalPro
*/
-static void __devexit sbs_exit(struct pci_dev *dev)
+static void sbs_exit(struct pci_dev *dev)
{
u8 __iomem *p;
@@ -991,7 +991,7 @@ static int pci_ite887x_init(struct pci_dev *dev)
return ret;
}
-static void __devexit pci_ite887x_exit(struct pci_dev *dev)
+static void pci_ite887x_exit(struct pci_dev *dev)
{
u32 ioport;
/* the ioport is bit 0-15 in POSIO0R */
@@ -1068,7 +1068,7 @@ ce4100_serial_setup(struct serial_private *priv,
{
int ret;
- ret = setup_port(priv, port, 0, 0, board->reg_shift);
+ ret = setup_port(priv, port, idx, 0, board->reg_shift);
port->port.iotype = UPIO_MEM32;
port->port.type = PORT_XSCALE;
port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
@@ -1165,6 +1165,94 @@ pci_xr17c154_setup(struct serial_private *priv,
}
static int
+pci_xr17v35x_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ u8 __iomem *p;
+
+ p = pci_ioremap_bar(priv->dev, 0);
+ if (p == NULL)
+ return -ENOMEM;
+
+ port->port.flags |= UPF_EXAR_EFR;
+
+ /*
+ * Setup Multipurpose Input/Output pins.
+ */
+ if (idx == 0) {
+ writeb(0x00, p + 0x8f); /*MPIOINT[7:0]*/
+ writeb(0x00, p + 0x90); /*MPIOLVL[7:0]*/
+ writeb(0x00, p + 0x91); /*MPIO3T[7:0]*/
+ writeb(0x00, p + 0x92); /*MPIOINV[7:0]*/
+ writeb(0x00, p + 0x93); /*MPIOSEL[7:0]*/
+ writeb(0x00, p + 0x94); /*MPIOOD[7:0]*/
+ writeb(0x00, p + 0x95); /*MPIOINT[15:8]*/
+ writeb(0x00, p + 0x96); /*MPIOLVL[15:8]*/
+ writeb(0x00, p + 0x97); /*MPIO3T[15:8]*/
+ writeb(0x00, p + 0x98); /*MPIOINV[15:8]*/
+ writeb(0x00, p + 0x99); /*MPIOSEL[15:8]*/
+ writeb(0x00, p + 0x9a); /*MPIOOD[15:8]*/
+ }
+ writeb(0x00, p + UART_EXAR_8XMODE);
+ writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
+ writeb(128, p + UART_EXAR_TXTRG);
+ writeb(128, p + UART_EXAR_RXTRG);
+ iounmap(p);
+
+ return pci_default_setup(priv, board, port, idx);
+}
+
+#define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004
+#define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002
+#define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a
+#define PCI_DEVICE_ID_COMMTECH_2328PCI335 0x000b
+
+static int
+pci_fastcom335_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ u8 __iomem *p;
+
+ p = pci_ioremap_bar(priv->dev, 0);
+ if (p == NULL)
+ return -ENOMEM;
+
+ port->port.flags |= UPF_EXAR_EFR;
+
+ /*
+ * Setup Multipurpose Input/Output pins.
+ */
+ if (idx == 0) {
+ switch (priv->dev->device) {
+ case PCI_DEVICE_ID_COMMTECH_4222PCI335:
+ case PCI_DEVICE_ID_COMMTECH_4224PCI335:
+ writeb(0x78, p + 0x90); /* MPIOLVL[7:0] */
+ writeb(0x00, p + 0x92); /* MPIOINV[7:0] */
+ writeb(0x00, p + 0x93); /* MPIOSEL[7:0] */
+ break;
+ case PCI_DEVICE_ID_COMMTECH_2324PCI335:
+ case PCI_DEVICE_ID_COMMTECH_2328PCI335:
+ writeb(0x00, p + 0x90); /* MPIOLVL[7:0] */
+ writeb(0xc0, p + 0x92); /* MPIOINV[7:0] */
+ writeb(0xc0, p + 0x93); /* MPIOSEL[7:0] */
+ break;
+ }
+ writeb(0x00, p + 0x8f); /* MPIOINT[7:0] */
+ writeb(0x00, p + 0x91); /* MPIO3T[7:0] */
+ writeb(0x00, p + 0x94); /* MPIOOD[7:0] */
+ }
+ writeb(0x00, p + UART_EXAR_8XMODE);
+ writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
+ writeb(32, p + UART_EXAR_TXTRG);
+ writeb(32, p + UART_EXAR_RXTRG);
+ iounmap(p);
+
+ return pci_default_setup(priv, board, port, idx);
+}
+
+static int
pci_wch_ch353_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_8250_port *port, int idx)
@@ -1213,6 +1301,10 @@ pci_wch_ch353_setup(struct serial_private *priv,
#define PCI_VENDOR_ID_AGESTAR 0x5372
#define PCI_DEVICE_ID_AGESTAR_9375 0x6872
#define PCI_VENDOR_ID_ASIX 0x9710
+#define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0019
+#define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020
+#define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021
+
/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
@@ -1314,7 +1406,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_ite887x_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_ite887x_exit),
+ .exit = pci_ite887x_exit,
},
/*
* National Instruments
@@ -1326,7 +1418,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_ni8420_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_ni8420_exit),
+ .exit = pci_ni8420_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
@@ -1335,7 +1427,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_ni8420_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_ni8420_exit),
+ .exit = pci_ni8420_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
@@ -1344,7 +1436,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_ni8420_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_ni8420_exit),
+ .exit = pci_ni8420_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
@@ -1353,7 +1445,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_ni8420_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_ni8420_exit),
+ .exit = pci_ni8420_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
@@ -1362,7 +1454,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_ni8420_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_ni8420_exit),
+ .exit = pci_ni8420_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
@@ -1371,7 +1463,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_ni8420_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_ni8420_exit),
+ .exit = pci_ni8420_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
@@ -1380,7 +1472,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_ni8420_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_ni8420_exit),
+ .exit = pci_ni8420_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
@@ -1389,7 +1481,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_ni8420_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_ni8420_exit),
+ .exit = pci_ni8420_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
@@ -1398,7 +1490,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_ni8420_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_ni8420_exit),
+ .exit = pci_ni8420_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
@@ -1407,7 +1499,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_ni8420_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_ni8420_exit),
+ .exit = pci_ni8420_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
@@ -1416,7 +1508,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_ni8420_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_ni8420_exit),
+ .exit = pci_ni8420_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
@@ -1425,7 +1517,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_ni8420_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_ni8420_exit),
+ .exit = pci_ni8420_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
@@ -1434,7 +1526,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8430_setup,
- .exit = __devexit_p(pci_ni8430_exit),
+ .exit = pci_ni8430_exit,
},
/*
* Panacom
@@ -1446,7 +1538,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_plx9050_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_plx9050_exit),
+ .exit = pci_plx9050_exit,
},
{
.vendor = PCI_VENDOR_ID_PANACOM,
@@ -1455,7 +1547,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.init = pci_plx9050_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_plx9050_exit),
+ .exit = pci_plx9050_exit,
},
/*
* PLX
@@ -1474,7 +1566,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_SUBDEVICE_ID_EXSYS_4055,
.init = pci_plx9050_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_plx9050_exit),
+ .exit = pci_plx9050_exit,
},
{
.vendor = PCI_VENDOR_ID_PLX,
@@ -1483,7 +1575,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_SUBDEVICE_ID_KEYSPAN_SX2,
.init = pci_plx9050_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_plx9050_exit),
+ .exit = pci_plx9050_exit,
},
{
.vendor = PCI_VENDOR_ID_PLX,
@@ -1492,7 +1584,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_SUBDEVICE_ID_UNKNOWN_0x1584,
.init = pci_plx9050_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_plx9050_exit),
+ .exit = pci_plx9050_exit,
},
{
.vendor = PCI_VENDOR_ID_PLX,
@@ -1501,7 +1593,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_DEVICE_ID_PLX_ROMULUS,
.init = pci_plx9050_init,
.setup = pci_default_setup,
- .exit = __devexit_p(pci_plx9050_exit),
+ .exit = pci_plx9050_exit,
},
/*
* SBS Technologies, Inc., PMC-OCTALPRO 232
@@ -1513,7 +1605,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_SUBDEVICE_ID_OCTPRO232,
.init = sbs_init,
.setup = sbs_setup,
- .exit = __devexit_p(sbs_exit),
+ .exit = sbs_exit,
},
/*
* SBS Technologies, Inc., PMC-OCTALPRO 422
@@ -1525,7 +1617,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_SUBDEVICE_ID_OCTPRO422,
.init = sbs_init,
.setup = sbs_setup,
- .exit = __devexit_p(sbs_exit),
+ .exit = sbs_exit,
},
/*
* SBS Technologies, Inc., P-Octal 232
@@ -1537,7 +1629,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_SUBDEVICE_ID_POCTAL232,
.init = sbs_init,
.setup = sbs_setup,
- .exit = __devexit_p(sbs_exit),
+ .exit = sbs_exit,
},
/*
* SBS Technologies, Inc., P-Octal 422
@@ -1549,7 +1641,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_SUBDEVICE_ID_POCTAL422,
.init = sbs_init,
.setup = sbs_setup,
- .exit = __devexit_p(sbs_exit),
+ .exit = sbs_exit,
},
/*
* SIIG cards - these may be called via parport_serial
@@ -1622,6 +1714,27 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.setup = pci_xr17c154_setup,
},
+ {
+ .vendor = PCI_VENDOR_ID_EXAR,
+ .device = PCI_DEVICE_ID_EXAR_XR17V352,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_xr17v35x_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_EXAR,
+ .device = PCI_DEVICE_ID_EXAR_XR17V354,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_xr17v35x_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_EXAR,
+ .device = PCI_DEVICE_ID_EXAR_XR17V358,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_xr17v35x_setup,
+ },
/*
* Xircom cards
*/
@@ -1788,6 +1901,59 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.setup = pci_asix_setup,
},
/*
+ * Commtech, Inc. Fastcom adapters
+ *
+ */
+ {
+ .vendor = PCI_VENDOR_ID_COMMTECH,
+ .device = PCI_DEVICE_ID_COMMTECH_4222PCI335,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_fastcom335_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_COMMTECH,
+ .device = PCI_DEVICE_ID_COMMTECH_4224PCI335,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_fastcom335_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_COMMTECH,
+ .device = PCI_DEVICE_ID_COMMTECH_2324PCI335,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_fastcom335_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_COMMTECH,
+ .device = PCI_DEVICE_ID_COMMTECH_2328PCI335,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_fastcom335_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_COMMTECH,
+ .device = PCI_DEVICE_ID_COMMTECH_4222PCIE,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_xr17v35x_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_COMMTECH,
+ .device = PCI_DEVICE_ID_COMMTECH_4224PCIE,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_xr17v35x_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_COMMTECH,
+ .device = PCI_DEVICE_ID_COMMTECH_4228PCIE,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_xr17v35x_setup,
+ },
+ /*
* Default "match everything" terminator entry
*/
{
@@ -1863,6 +2029,10 @@ enum pci_board_num_t {
pbn_b0_4_1152000,
+ pbn_b0_2_1152000_200,
+ pbn_b0_4_1152000_200,
+ pbn_b0_8_1152000_200,
+
pbn_b0_2_1843200,
pbn_b0_4_1843200,
@@ -1962,6 +2132,9 @@ enum pci_board_num_t {
pbn_exar_XR17C152,
pbn_exar_XR17C154,
pbn_exar_XR17C158,
+ pbn_exar_XR17V352,
+ pbn_exar_XR17V354,
+ pbn_exar_XR17V358,
pbn_exar_ibm_saturn,
pbn_pasemi_1682M,
pbn_ni8430_2,
@@ -1987,7 +2160,7 @@ enum pci_board_num_t {
* see first lines of serial_in() and serial_out() in 8250.c
*/
-static struct pciserial_board pci_boards[] __devinitdata = {
+static struct pciserial_board pci_boards[] = {
[pbn_default] = {
.flags = FL_BASE0,
.num_ports = 1,
@@ -2057,6 +2230,27 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.uart_offset = 8,
},
+ [pbn_b0_2_1152000_200] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 1152000,
+ .uart_offset = 0x200,
+ },
+
+ [pbn_b0_4_1152000_200] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 1152000,
+ .uart_offset = 0x200,
+ },
+
+ [pbn_b0_8_1152000_200] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 1152000,
+ .uart_offset = 0x200,
+ },
+
[pbn_b0_2_1843200] = {
.flags = FL_BASE0,
.num_ports = 2,
@@ -2580,6 +2774,30 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.base_baud = 921600,
.uart_offset = 0x200,
},
+ [pbn_exar_XR17V352] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 7812500,
+ .uart_offset = 0x400,
+ .reg_shift = 0,
+ .first_offset = 0,
+ },
+ [pbn_exar_XR17V354] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 7812500,
+ .uart_offset = 0x400,
+ .reg_shift = 0,
+ .first_offset = 0,
+ },
+ [pbn_exar_XR17V358] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 7812500,
+ .uart_offset = 0x400,
+ .reg_shift = 0,
+ .first_offset = 0,
+ },
[pbn_exar_ibm_saturn] = {
.flags = FL_BASE0,
.num_ports = 1,
@@ -2658,8 +2876,8 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.first_offset = 0x1000,
},
[pbn_ce4100_1_115200] = {
- .flags = FL_BASE0,
- .num_ports = 1,
+ .flags = FL_BASE_BARS,
+ .num_ports = 2,
.base_baud = 921600,
.reg_shift = 2,
},
@@ -2691,7 +2909,7 @@ static const struct pci_device_id blacklist[] = {
* guess what the configuration might be, based on the pitiful PCI
* serial specs. Returns 0 on success, 1 on failure.
*/
-static int __devinit
+static int
serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
{
const struct pci_device_id *bldev;
@@ -2917,7 +3135,7 @@ EXPORT_SYMBOL_GPL(pciserial_resume_ports);
* Probe one serial board. Unfortunately, there is no rhyme nor reason
* to the arrangement of serial ports on a PCI card.
*/
-static int __devinit
+static int
pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
{
struct pci_serial_quirk *quirk;
@@ -2988,7 +3206,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
return rc;
}
-static void __devexit pciserial_remove_one(struct pci_dev *dev)
+static void pciserial_remove_one(struct pci_dev *dev)
{
struct serial_private *priv = pci_get_drvdata(dev);
@@ -3826,6 +4044,21 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_exar_XR17C158 },
+ /*
+ * Exar Corp. XR17V35[248] Dual/Quad/Octal PCIe UARTs
+ */
+ { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V352,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0,
+ 0, pbn_exar_XR17V352 },
+ { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V354,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0,
+ 0, pbn_exar_XR17V354 },
+ { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V358,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0,
+ 0, pbn_exar_XR17V358 },
/*
* Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke)
@@ -4257,6 +4490,38 @@ static struct pci_device_id serial_pci_tbl[] = {
0, 0, pbn_b0_bt_2_115200 },
/*
+ * Commtech, Inc. Fastcom adapters
+ */
+ { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCI335,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0,
+ 0, pbn_b0_2_1152000_200 },
+ { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCI335,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0,
+ 0, pbn_b0_4_1152000_200 },
+ { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2324PCI335,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0,
+ 0, pbn_b0_4_1152000_200 },
+ { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2328PCI335,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0,
+ 0, pbn_b0_8_1152000_200 },
+ { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCIE,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0,
+ 0, pbn_exar_XR17V352 },
+ { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCIE,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0,
+ 0, pbn_exar_XR17V354 },
+ { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4228PCIE,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0,
+ 0, pbn_exar_XR17V358 },
+
+ /*
* These entries match devices with class COMMUNICATION_SERIAL,
* COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
*/
@@ -4323,7 +4588,7 @@ static const struct pci_error_handlers serial8250_err_handler = {
static struct pci_driver serial_pci_driver = {
.name = "serial",
.probe = pciserial_init_one,
- .remove = __devexit_p(pciserial_remove_one),
+ .remove = pciserial_remove_one,
#ifdef CONFIG_PM
.suspend = pciserial_suspend_one,
.resume = pciserial_resume_one,
@@ -4332,18 +4597,7 @@ static struct pci_driver serial_pci_driver = {
.err_handler = &serial8250_err_handler,
};
-static int __init serial8250_pci_init(void)
-{
- return pci_register_driver(&serial_pci_driver);
-}
-
-static void __exit serial8250_pci_exit(void)
-{
- pci_unregister_driver(&serial_pci_driver);
-}
-
-module_init(serial8250_pci_init);
-module_exit(serial8250_pci_exit);
+module_pci_driver(serial_pci_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module");
diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c
index f8ee25001dd..35d9ab95c5c 100644
--- a/drivers/tty/serial/8250/8250_pnp.c
+++ b/drivers/tty/serial/8250/8250_pnp.c
@@ -370,14 +370,14 @@ static const struct pnp_device_id pnp_dev_table[] = {
MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
-static char *modem_names[] __devinitdata = {
+static char *modem_names[] = {
"MODEM", "Modem", "modem", "FAX", "Fax", "fax",
"56K", "56k", "K56", "33.6", "28.8", "14.4",
"33,600", "28,800", "14,400", "33.600", "28.800", "14.400",
"33600", "28800", "14400", "V.90", "V.34", "V.32", NULL
};
-static int __devinit check_name(char *name)
+static int check_name(char *name)
{
char **tmp;
@@ -388,7 +388,7 @@ static int __devinit check_name(char *name)
return 0;
}
-static int __devinit check_resources(struct pnp_dev *dev)
+static int check_resources(struct pnp_dev *dev)
{
resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
int i;
@@ -412,7 +412,7 @@ static int __devinit check_resources(struct pnp_dev *dev)
* PnP modems, alternatively we must hardcode all modems in pnp_devices[]
* table.
*/
-static int __devinit serial_pnp_guess_board(struct pnp_dev *dev)
+static int serial_pnp_guess_board(struct pnp_dev *dev)
{
if (!(check_name(pnp_dev_name(dev)) ||
(dev->card && check_name(dev->card->name))))
@@ -424,7 +424,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev)
return -ENODEV;
}
-static int __devinit
+static int
serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
struct uart_8250_port uart;
@@ -476,7 +476,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
return 0;
}
-static void __devexit serial_pnp_remove(struct pnp_dev *dev)
+static void serial_pnp_remove(struct pnp_dev *dev)
{
long line = (long)pnp_get_drvdata(dev);
if (line)
@@ -511,7 +511,7 @@ static int serial_pnp_resume(struct pnp_dev *dev)
static struct pnp_driver serial_pnp_driver = {
.name = "serial",
.probe = serial_pnp_probe,
- .remove = __devexit_p(serial_pnp_remove),
+ .remove = serial_pnp_remove,
.suspend = serial_pnp_suspend,
.resume = serial_pnp_resume,
.id_table = pnp_dev_table,
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 2a53be5f010..59c23d03810 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -93,7 +93,7 @@ config SERIAL_SB1250_DUART_CONSOLE
config SERIAL_ATMEL
bool "AT91 / AT32 on-chip serial port support"
- depends on (ARM && ARCH_AT91) || AVR32
+ depends on ARCH_AT91 || AVR32
select SERIAL_CORE
help
This enables the driver for the on-chip UARTs of the Atmel
@@ -198,7 +198,7 @@ config SERIAL_CLPS711X_CONSOLE
config SERIAL_SAMSUNG
tristate "Samsung SoC serial support"
- depends on ARM && PLAT_SAMSUNG
+ depends on PLAT_SAMSUNG
select SERIAL_CORE
help
Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
@@ -208,14 +208,14 @@ config SERIAL_SAMSUNG
config SERIAL_SAMSUNG_UARTS_4
bool
- depends on ARM && PLAT_SAMSUNG
+ depends on PLAT_SAMSUNG
default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442)
help
Internal node for the common case of 4 Samsung compatible UARTs
config SERIAL_SAMSUNG_UARTS
int
- depends on ARM && PLAT_SAMSUNG
+ depends on PLAT_SAMSUNG
default 6 if ARCH_S5P6450
default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416
default 3
@@ -249,7 +249,7 @@ config SERIAL_SAMSUNG_CONSOLE
config SERIAL_SIRFSOC
tristate "SiRF SoC Platform Serial port support"
- depends on ARM && ARCH_PRIMA2
+ depends on ARCH_PRIMA2
select SERIAL_CORE
help
Support for the on-chip UART on the CSR SiRFprimaII series,
@@ -347,7 +347,7 @@ config SERIAL_ZS_CONSOLE
config SERIAL_21285
tristate "DC21285 serial port support"
- depends on ARM && FOOTBRIDGE
+ depends on FOOTBRIDGE
select SERIAL_CORE
help
If you have a machine based on a 21285 (Footbridge) StrongARM(R)/
@@ -371,7 +371,7 @@ config SERIAL_21285_CONSOLE
config SERIAL_MPSC
bool "Marvell MPSC serial port support"
- depends on PPC32 && MV64X60
+ depends on MV64X60
select SERIAL_CORE
help
Say Y here if you want to use the Marvell MPSC serial controller.
@@ -408,7 +408,7 @@ config SERIAL_PXA_CONSOLE
config SERIAL_SA1100
bool "SA1100 serial port support"
- depends on ARM && ARCH_SA1100
+ depends on ARCH_SA1100
select SERIAL_CORE
help
If you have a machine based on a SA1100/SA1110 StrongARM(R) CPU you
@@ -716,7 +716,7 @@ config SERIAL_SH_SCI_DMA
config SERIAL_PNX8XXX
bool "Enable PNX8XXX SoCs' UART Support"
- depends on MIPS && (SOC_PNX8550 || SOC_PNX833X)
+ depends on SOC_PNX8550 || SOC_PNX833X
select SERIAL_CORE
help
If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330
@@ -1013,7 +1013,7 @@ config SERIAL_SGI_IOC3
config SERIAL_MSM
bool "MSM on-chip serial port support"
- depends on ARM && ARCH_MSM
+ depends on ARCH_MSM
select SERIAL_CORE
config SERIAL_MSM_CONSOLE
@@ -1035,7 +1035,7 @@ config SERIAL_MSM_HS
config SERIAL_VT8500
bool "VIA VT8500 on-chip serial port support"
- depends on ARM && ARCH_VT8500
+ depends on ARCH_VT8500
select SERIAL_CORE
config SERIAL_VT8500_CONSOLE
@@ -1045,7 +1045,7 @@ config SERIAL_VT8500_CONSOLE
config SERIAL_NETX
tristate "NetX serial port support"
- depends on ARM && ARCH_NETX
+ depends on ARCH_NETX
select SERIAL_CORE
help
If you have a machine based on a Hilscher NetX SoC you
@@ -1376,6 +1376,7 @@ config SERIAL_MXS_AUART_CONSOLE
config SERIAL_XILINX_PS_UART
tristate "Xilinx PS UART support"
+ depends on OF
select SERIAL_CORE
help
This driver supports the Xilinx PS UART port.
@@ -1423,4 +1424,27 @@ config SERIAL_EFM32_UART_CONSOLE
depends on SERIAL_EFM32_UART=y
select SERIAL_CORE_CONSOLE
+config SERIAL_ARC
+ tristate "ARC UART driver support"
+ select SERIAL_CORE
+ help
+ Driver for on-chip UART for ARC(Synopsys) for the legacy
+ FPGA Boards (ML50x/ARCAngel4)
+
+config SERIAL_ARC_CONSOLE
+ bool "Console on ARC UART"
+ depends on SERIAL_ARC=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Enable system Console on ARC UART
+
+config SERIAL_ARC_NR_PORTS
+ int "Number of ARC UART ports"
+ depends on SERIAL_ARC
+ range 1 3
+ default "1"
+ help
+ Set this to the number of serial ports you want the driver
+ to support.
+
endmenu
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 4f694dafa71..df1b998c436 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -82,3 +82,4 @@ obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o
obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o
obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o
obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o
+obj-$(CONFIG_SERIAL_ARC) += arc_uart.o
diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c
index 530181e49f6..872f14ae43d 100644
--- a/drivers/tty/serial/altera_jtaguart.c
+++ b/drivers/tty/serial/altera_jtaguart.c
@@ -406,7 +406,7 @@ static struct uart_driver altera_jtaguart_driver = {
.cons = ALTERA_JTAGUART_CONSOLE,
};
-static int __devinit altera_jtaguart_probe(struct platform_device *pdev)
+static int altera_jtaguart_probe(struct platform_device *pdev)
{
struct altera_jtaguart_platform_uart *platp = pdev->dev.platform_data;
struct uart_port *port;
@@ -453,7 +453,7 @@ static int __devinit altera_jtaguart_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit altera_jtaguart_remove(struct platform_device *pdev)
+static int altera_jtaguart_remove(struct platform_device *pdev)
{
struct uart_port *port;
int i = pdev->id;
@@ -477,7 +477,7 @@ MODULE_DEVICE_TABLE(of, altera_jtaguart_match);
static struct platform_driver altera_jtaguart_platform_driver = {
.probe = altera_jtaguart_probe,
- .remove = __devexit_p(altera_jtaguart_remove),
+ .remove = altera_jtaguart_remove,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c
index 15d80b9fb30..684a0808e1c 100644
--- a/drivers/tty/serial/altera_uart.c
+++ b/drivers/tty/serial/altera_uart.c
@@ -532,7 +532,7 @@ static int altera_uart_get_of_uartclk(struct platform_device *pdev,
}
#endif /* CONFIG_OF */
-static int __devinit altera_uart_probe(struct platform_device *pdev)
+static int altera_uart_probe(struct platform_device *pdev)
{
struct altera_uart_platform_uart *platp = pdev->dev.platform_data;
struct uart_port *port;
@@ -598,7 +598,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit altera_uart_remove(struct platform_device *pdev)
+static int altera_uart_remove(struct platform_device *pdev)
{
struct uart_port *port = platform_get_drvdata(pdev);
@@ -621,7 +621,7 @@ MODULE_DEVICE_TABLE(of, altera_uart_match);
static struct platform_driver altera_uart_platform_driver = {
.probe = altera_uart_probe,
- .remove = __devexit_p(altera_uart_remove),
+ .remove = altera_uart_remove,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index d7e1edec50b..7fca4022a8b 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -56,8 +56,7 @@
#include <linux/of_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/sizes.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
#define UART_NR 14
@@ -1973,7 +1972,8 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
goto out;
}
- uap = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
+ uap = devm_kzalloc(&dev->dev, sizeof(struct uart_amba_port),
+ GFP_KERNEL);
if (uap == NULL) {
ret = -ENOMEM;
goto out;
@@ -1981,16 +1981,17 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
i = pl011_probe_dt_alias(i, &dev->dev);
- base = ioremap(dev->res.start, resource_size(&dev->res));
+ base = devm_ioremap(&dev->dev, dev->res.start,
+ resource_size(&dev->res));
if (!base) {
ret = -ENOMEM;
- goto free;
+ goto out;
}
uap->pinctrl = devm_pinctrl_get(&dev->dev);
if (IS_ERR(uap->pinctrl)) {
ret = PTR_ERR(uap->pinctrl);
- goto unmap;
+ goto out;
}
uap->pins_default = pinctrl_lookup_state(uap->pinctrl,
PINCTRL_STATE_DEFAULT);
@@ -2002,10 +2003,10 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
if (IS_ERR(uap->pins_sleep))
dev_dbg(&dev->dev, "could not get sleep pinstate\n");
- uap->clk = clk_get(&dev->dev, NULL);
+ uap->clk = devm_clk_get(&dev->dev, NULL);
if (IS_ERR(uap->clk)) {
ret = PTR_ERR(uap->clk);
- goto unmap;
+ goto out;
}
uap->vendor = vendor;
@@ -2038,11 +2039,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
amba_set_drvdata(dev, NULL);
amba_ports[i] = NULL;
pl011_dma_remove(uap);
- clk_put(uap->clk);
- unmap:
- iounmap(base);
- free:
- kfree(uap);
}
out:
return ret;
@@ -2062,9 +2058,6 @@ static int pl011_remove(struct amba_device *dev)
amba_ports[i] = NULL;
pl011_dma_remove(uap);
- iounmap(uap->port.membase);
- clk_put(uap->clk);
- kfree(uap);
return 0;
}
diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c
index 7162f70d926..59ae2b53e76 100644
--- a/drivers/tty/serial/apbuart.c
+++ b/drivers/tty/serial/apbuart.c
@@ -554,7 +554,7 @@ static struct uart_driver grlib_apbuart_driver = {
/* OF Platform Driver */
/* ======================================================================== */
-static int __devinit apbuart_probe(struct platform_device *op)
+static int apbuart_probe(struct platform_device *op)
{
int i;
struct uart_port *port = NULL;
diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c
index e4f60e2b87f..505c490c0b4 100644
--- a/drivers/tty/serial/ar933x_uart.c
+++ b/drivers/tty/serial/ar933x_uart.c
@@ -25,11 +25,19 @@
#include <linux/io.h>
#include <linux/irq.h>
+#include <asm/div64.h>
+
#include <asm/mach-ath79/ar933x_uart.h>
#include <asm/mach-ath79/ar933x_uart_platform.h>
#define DRIVER_NAME "ar933x-uart"
+#define AR933X_UART_MAX_SCALE 0xff
+#define AR933X_UART_MAX_STEP 0xffff
+
+#define AR933X_UART_MIN_BAUD 300
+#define AR933X_UART_MAX_BAUD 3000000
+
#define AR933X_DUMMY_STATUS_RD 0x01
static struct uart_driver ar933x_uart_driver;
@@ -37,6 +45,8 @@ static struct uart_driver ar933x_uart_driver;
struct ar933x_uart_port {
struct uart_port port;
unsigned int ier; /* shadow Interrupt Enable Register */
+ unsigned int min_baud;
+ unsigned int max_baud;
};
static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
@@ -162,6 +172,57 @@ static void ar933x_uart_enable_ms(struct uart_port *port)
{
}
+/*
+ * baudrate = (clk / (scale + 1)) * (step * (1 / 2^17))
+ */
+static unsigned long ar933x_uart_get_baud(unsigned int clk,
+ unsigned int scale,
+ unsigned int step)
+{
+ u64 t;
+ u32 div;
+
+ div = (2 << 16) * (scale + 1);
+ t = clk;
+ t *= step;
+ t += (div / 2);
+ do_div(t, div);
+
+ return t;
+}
+
+static void ar933x_uart_get_scale_step(unsigned int clk,
+ unsigned int baud,
+ unsigned int *scale,
+ unsigned int *step)
+{
+ unsigned int tscale;
+ long min_diff;
+
+ *scale = 0;
+ *step = 0;
+
+ min_diff = baud;
+ for (tscale = 0; tscale < AR933X_UART_MAX_SCALE; tscale++) {
+ u64 tstep;
+ int diff;
+
+ tstep = baud * (tscale + 1);
+ tstep *= (2 << 16);
+ do_div(tstep, clk);
+
+ if (tstep > AR933X_UART_MAX_STEP)
+ break;
+
+ diff = abs(ar933x_uart_get_baud(clk, tscale, tstep) - baud);
+ if (diff < min_diff) {
+ min_diff = diff;
+ *scale = tscale;
+ *step = tstep;
+ }
+ }
+}
+
static void ar933x_uart_set_termios(struct uart_port *port,
struct ktermios *new,
struct ktermios *old)
@@ -169,7 +230,7 @@ static void ar933x_uart_set_termios(struct uart_port *port,
struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
unsigned int cs;
unsigned long flags;
- unsigned int baud, scale;
+ unsigned int baud, scale, step;
/* Only CS8 is supported */
new->c_cflag &= ~CSIZE;
@@ -191,8 +252,8 @@ static void ar933x_uart_set_termios(struct uart_port *port,
/* Mark/space parity is not supported */
new->c_cflag &= ~CMSPAR;
- baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
- scale = (port->uartclk / (16 * baud)) - 1;
+ baud = uart_get_baud_rate(port, new, old, up->min_baud, up->max_baud);
+ ar933x_uart_get_scale_step(port->uartclk, baud, &scale, &step);
/*
* Ok, we're now changing the port state. Do it with
@@ -200,6 +261,10 @@ static void ar933x_uart_set_termios(struct uart_port *port,
*/
spin_lock_irqsave(&up->port.lock, flags);
+ /* disable the UART */
+ ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG,
+ AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S);
+
/* Update the per-port timeout. */
uart_update_timeout(port, new->c_cflag, baud);
@@ -210,7 +275,7 @@ static void ar933x_uart_set_termios(struct uart_port *port,
up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD;
ar933x_uart_write(up, AR933X_UART_CLOCK_REG,
- scale << AR933X_UART_CLOCK_SCALE_S | 8192);
+ scale << AR933X_UART_CLOCK_SCALE_S | step);
/* setup configuration register */
ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs);
@@ -219,6 +284,11 @@ static void ar933x_uart_set_termios(struct uart_port *port,
ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
AR933X_UART_CS_HOST_INT_EN);
+ /* reenable the UART */
+ ar933x_uart_rmw(up, AR933X_UART_CS_REG,
+ AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S,
+ AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S);
+
spin_unlock_irqrestore(&up->port.lock, flags);
if (tty_termios_baud_rate(new))
@@ -401,6 +471,8 @@ static void ar933x_uart_config_port(struct uart_port *port, int flags)
static int ar933x_uart_verify_port(struct uart_port *port,
struct serial_struct *ser)
{
+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
+
if (ser->type != PORT_UNKNOWN &&
ser->type != PORT_AR933X)
return -EINVAL;
@@ -408,7 +480,8 @@ static int ar933x_uart_verify_port(struct uart_port *port,
if (ser->irq < 0 || ser->irq >= NR_IRQS)
return -EINVAL;
- if (ser->baud_base < 28800)
+ if (ser->baud_base < up->min_baud ||
+ ser->baud_base > up->max_baud)
return -EINVAL;
return 0;
@@ -554,13 +627,14 @@ static struct uart_driver ar933x_uart_driver = {
.cons = AR933X_SERIAL_CONSOLE,
};
-static int __devinit ar933x_uart_probe(struct platform_device *pdev)
+static int ar933x_uart_probe(struct platform_device *pdev)
{
struct ar933x_uart_platform_data *pdata;
struct ar933x_uart_port *up;
struct uart_port *port;
struct resource *mem_res;
struct resource *irq_res;
+ unsigned int baud;
int id;
int ret;
@@ -611,6 +685,12 @@ static int __devinit ar933x_uart_probe(struct platform_device *pdev)
port->fifosize = AR933X_UART_FIFO_SIZE;
port->ops = &ar933x_uart_ops;
+ baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1);
+ up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD);
+
+ baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP);
+ up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD);
+
ar933x_uart_add_console_port(up);
ret = uart_add_one_port(&ar933x_uart_driver, &up->port);
@@ -627,7 +707,7 @@ err_free_up:
return ret;
}
-static int __devexit ar933x_uart_remove(struct platform_device *pdev)
+static int ar933x_uart_remove(struct platform_device *pdev)
{
struct ar933x_uart_port *up;
@@ -645,7 +725,7 @@ static int __devexit ar933x_uart_remove(struct platform_device *pdev)
static struct platform_driver ar933x_uart_platform_driver = {
.probe = ar933x_uart_probe,
- .remove = __devexit_p(ar933x_uart_remove),
+ .remove = ar933x_uart_remove,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c
new file mode 100644
index 00000000000..3e0b3fac6a0
--- /dev/null
+++ b/drivers/tty/serial/arc_uart.c
@@ -0,0 +1,746 @@
+/*
+ * ARC On-Chip(fpga) UART Driver
+ *
+ * Copyright (C) 2010-2012 Synopsys, Inc. (www.synopsys.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.
+ *
+ * vineetg: July 10th 2012
+ * -Decoupled the driver from arch/arc
+ * +Using platform_get_resource() for irq/membase (thx to bfin_uart.c)
+ * +Using early_platform_xxx() for early console (thx to mach-shmobile/xxx)
+ *
+ * Vineetg: Aug 21st 2010
+ * -Is uart_tx_stopped() not done in tty write path as it has already been
+ * taken care of, in serial core
+ *
+ * Vineetg: Aug 18th 2010
+ * -New Serial Core based ARC UART driver
+ * -Derived largely from blackfin driver albiet with some major tweaks
+ *
+ * TODO:
+ * -check if sysreq works
+ */
+
+#if defined(CONFIG_SERIAL_ARC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/platform_device.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+/*************************************
+ * ARC UART Hardware Specs
+ ************************************/
+#define ARC_UART_TX_FIFO_SIZE 1
+
+/*
+ * UART Register set (this is not a Standards Compliant IP)
+ * Also each reg is Word aligned, but only 8 bits wide
+ */
+#define R_ID0 0
+#define R_ID1 4
+#define R_ID2 8
+#define R_ID3 12
+#define R_DATA 16
+#define R_STS 20
+#define R_BAUDL 24
+#define R_BAUDH 28
+
+/* Bits for UART Status Reg (R/W) */
+#define RXIENB 0x04 /* Receive Interrupt Enable */
+#define TXIENB 0x40 /* Transmit Interrupt Enable */
+
+#define RXEMPTY 0x20 /* Receive FIFO Empty: No char receivede */
+#define TXEMPTY 0x80 /* Transmit FIFO Empty, thus char can be written into */
+
+#define RXFULL 0x08 /* Receive FIFO full */
+#define RXFULL1 0x10 /* Receive FIFO has space for 1 char (tot space=4) */
+
+#define RXFERR 0x01 /* Frame Error: Stop Bit not detected */
+#define RXOERR 0x02 /* OverFlow Err: Char recv but RXFULL still set */
+
+/* Uart bit fiddling helpers: lowest level */
+#define RBASE(uart, reg) (uart->port.membase + reg)
+#define UART_REG_SET(u, r, v) writeb((v), RBASE(u, r))
+#define UART_REG_GET(u, r) readb(RBASE(u, r))
+
+#define UART_REG_OR(u, r, v) UART_REG_SET(u, r, UART_REG_GET(u, r) | (v))
+#define UART_REG_CLR(u, r, v) UART_REG_SET(u, r, UART_REG_GET(u, r) & ~(v))
+
+/* Uart bit fiddling helpers: API level */
+#define UART_SET_DATA(uart, val) UART_REG_SET(uart, R_DATA, val)
+#define UART_GET_DATA(uart) UART_REG_GET(uart, R_DATA)
+
+#define UART_SET_BAUDH(uart, val) UART_REG_SET(uart, R_BAUDH, val)
+#define UART_SET_BAUDL(uart, val) UART_REG_SET(uart, R_BAUDL, val)
+
+#define UART_CLR_STATUS(uart, val) UART_REG_CLR(uart, R_STS, val)
+#define UART_GET_STATUS(uart) UART_REG_GET(uart, R_STS)
+
+#define UART_ALL_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, RXIENB|TXIENB)
+#define UART_RX_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, RXIENB)
+#define UART_TX_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, TXIENB)
+
+#define UART_ALL_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, RXIENB|TXIENB)
+#define UART_RX_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, RXIENB)
+#define UART_TX_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, TXIENB)
+
+#define ARC_SERIAL_DEV_NAME "ttyARC"
+
+struct arc_uart_port {
+ struct uart_port port;
+ unsigned long baud;
+ int is_emulated; /* H/w vs. Instruction Set Simulator */
+};
+
+#define to_arc_port(uport) container_of(uport, struct arc_uart_port, port)
+
+static struct arc_uart_port arc_uart_ports[CONFIG_SERIAL_ARC_NR_PORTS];
+
+#ifdef CONFIG_SERIAL_ARC_CONSOLE
+static struct console arc_console;
+#endif
+
+#define DRIVER_NAME "arc-uart"
+
+static struct uart_driver arc_uart_driver = {
+ .owner = THIS_MODULE,
+ .driver_name = DRIVER_NAME,
+ .dev_name = ARC_SERIAL_DEV_NAME,
+ .major = 0,
+ .minor = 0,
+ .nr = CONFIG_SERIAL_ARC_NR_PORTS,
+#ifdef CONFIG_SERIAL_ARC_CONSOLE
+ .cons = &arc_console,
+#endif
+};
+
+static void arc_serial_stop_rx(struct uart_port *port)
+{
+ struct arc_uart_port *uart = to_arc_port(port);
+
+ UART_RX_IRQ_DISABLE(uart);
+}
+
+static void arc_serial_stop_tx(struct uart_port *port)
+{
+ struct arc_uart_port *uart = to_arc_port(port);
+
+ while (!(UART_GET_STATUS(uart) & TXEMPTY))
+ cpu_relax();
+
+ UART_TX_IRQ_DISABLE(uart);
+}
+
+/*
+ * Return TIOCSER_TEMT when transmitter is not busy.
+ */
+static unsigned int arc_serial_tx_empty(struct uart_port *port)
+{
+ struct arc_uart_port *uart = to_arc_port(port);
+ unsigned int stat;
+
+ stat = UART_GET_STATUS(uart);
+ if (stat & TXEMPTY)
+ return TIOCSER_TEMT;
+
+ return 0;
+}
+
+/*
+ * Driver internal routine, used by both tty(serial core) as well as tx-isr
+ * -Called under spinlock in either cases
+ * -also tty->stopped / tty->hw_stopped has already been checked
+ * = by uart_start( ) before calling us
+ * = tx_ist checks that too before calling
+ */
+static void arc_serial_tx_chars(struct arc_uart_port *uart)
+{
+ struct circ_buf *xmit = &uart->port.state->xmit;
+ int sent = 0;
+ unsigned char ch;
+
+ if (unlikely(uart->port.x_char)) {
+ UART_SET_DATA(uart, uart->port.x_char);
+ uart->port.icount.tx++;
+ uart->port.x_char = 0;
+ sent = 1;
+ } else if (xmit->tail != xmit->head) { /* TODO: uart_circ_empty */
+ ch = xmit->buf[xmit->tail];
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ uart->port.icount.tx++;
+ while (!(UART_GET_STATUS(uart) & TXEMPTY))
+ cpu_relax();
+ UART_SET_DATA(uart, ch);
+ sent = 1;
+ }
+
+ /*
+ * If num chars in xmit buffer are too few, ask tty layer for more.
+ * By Hard ISR to schedule processing in software interrupt part
+ */
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&uart->port);
+
+ if (sent)
+ UART_TX_IRQ_ENABLE(uart);
+}
+
+/*
+ * port is locked and interrupts are disabled
+ * uart_start( ) calls us under the port spinlock irqsave
+ */
+static void arc_serial_start_tx(struct uart_port *port)
+{
+ struct arc_uart_port *uart = to_arc_port(port);
+
+ arc_serial_tx_chars(uart);
+}
+
+static void arc_serial_rx_chars(struct arc_uart_port *uart)
+{
+ struct tty_struct *tty = tty_port_tty_get(&uart->port.state->port);
+ unsigned int status, ch, flg = 0;
+
+ if (!tty)
+ return;
+
+ /*
+ * UART has 4 deep RX-FIFO. Driver's recongnition of this fact
+ * is very subtle. Here's how ...
+ * Upon getting a RX-Intr, such that RX-EMPTY=0, meaning data available,
+ * driver reads the DATA Reg and keeps doing that in a loop, until
+ * RX-EMPTY=1. Multiple chars being avail, with a single Interrupt,
+ * before RX-EMPTY=0, implies some sort of buffering going on in the
+ * controller, which is indeed the Rx-FIFO.
+ */
+ while (!((status = UART_GET_STATUS(uart)) & RXEMPTY)) {
+
+ ch = UART_GET_DATA(uart);
+ uart->port.icount.rx++;
+
+ if (unlikely(status & (RXOERR | RXFERR))) {
+ if (status & RXOERR) {
+ uart->port.icount.overrun++;
+ flg = TTY_OVERRUN;
+ UART_CLR_STATUS(uart, RXOERR);
+ }
+
+ if (status & RXFERR) {
+ uart->port.icount.frame++;
+ flg = TTY_FRAME;
+ UART_CLR_STATUS(uart, RXFERR);
+ }
+ } else
+ flg = TTY_NORMAL;
+
+ if (unlikely(uart_handle_sysrq_char(&uart->port, ch)))
+ goto done;
+
+ uart_insert_char(&uart->port, status, RXOERR, ch, flg);
+
+done:
+ tty_flip_buffer_push(tty);
+ }
+
+ tty_kref_put(tty);
+}
+
+/*
+ * A note on the Interrupt handling state machine of this driver
+ *
+ * kernel printk writes funnel thru the console driver framework and in order
+ * to keep things simple as well as efficient, it writes to UART in polled
+ * mode, in one shot, and exits.
+ *
+ * OTOH, Userland output (via tty layer), uses interrupt based writes as there
+ * can be undeterministic delay between char writes.
+ *
+ * Thus Rx-interrupts are always enabled, while tx-interrupts are by default
+ * disabled.
+ *
+ * When tty has some data to send out, serial core calls driver's start_tx
+ * which
+ * -checks-if-tty-buffer-has-char-to-send
+ * -writes-data-to-uart
+ * -enable-tx-intr
+ *
+ * Once data bits are pushed out, controller raises the Tx-room-avail-Interrupt.
+ * The first thing Tx ISR does is disable further Tx interrupts (as this could
+ * be the last char to send, before settling down into the quiet polled mode).
+ * It then calls the exact routine used by tty layer write to send out any
+ * more char in tty buffer. In case of sending, it re-enables Tx-intr. In case
+ * of no data, it remains disabled.
+ * This is how the transmit state machine is dynamically switched on/off
+ */
+
+static irqreturn_t arc_serial_isr(int irq, void *dev_id)
+{
+ struct arc_uart_port *uart = dev_id;
+ unsigned int status;
+
+ status = UART_GET_STATUS(uart);
+
+ /*
+ * Single IRQ for both Rx (data available) Tx (room available) Interrupt
+ * notifications from the UART Controller.
+ * To demultiplex between the two, we check the relevant bits
+ */
+ if ((status & RXIENB) && !(status & RXEMPTY)) {
+
+ /* already in ISR, no need of xx_irqsave */
+ spin_lock(&uart->port.lock);
+ arc_serial_rx_chars(uart);
+ spin_unlock(&uart->port.lock);
+ }
+
+ if ((status & TXIENB) && (status & TXEMPTY)) {
+
+ /* Unconditionally disable further Tx-Interrupts.
+ * will be enabled by tx_chars() if needed.
+ */
+ UART_TX_IRQ_DISABLE(uart);
+
+ spin_lock(&uart->port.lock);
+
+ if (!uart_tx_stopped(&uart->port))
+ arc_serial_tx_chars(uart);
+
+ spin_unlock(&uart->port.lock);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static unsigned int arc_serial_get_mctrl(struct uart_port *port)
+{
+ /*
+ * Pretend we have a Modem status reg and following bits are
+ * always set, to satify the serial core state machine
+ * (DSR) Data Set Ready
+ * (CTS) Clear To Send
+ * (CAR) Carrier Detect
+ */
+ return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+}
+
+static void arc_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ /* MCR not present */
+}
+
+/* Enable Modem Status Interrupts */
+
+static void arc_serial_enable_ms(struct uart_port *port)
+{
+ /* MSR not present */
+}
+
+static void arc_serial_break_ctl(struct uart_port *port, int break_state)
+{
+ /* ARC UART doesn't support sending Break signal */
+}
+
+static int arc_serial_startup(struct uart_port *port)
+{
+ struct arc_uart_port *uart = to_arc_port(port);
+
+ /* Before we hook up the ISR, Disable all UART Interrupts */
+ UART_ALL_IRQ_DISABLE(uart);
+
+ if (request_irq(uart->port.irq, arc_serial_isr, 0, "arc uart rx-tx",
+ uart)) {
+ dev_warn(uart->port.dev, "Unable to attach ARC UART intr\n");
+ return -EBUSY;
+ }
+
+ UART_RX_IRQ_ENABLE(uart); /* Only Rx IRQ enabled to begin with */
+
+ return 0;
+}
+
+/* This is not really needed */
+static void arc_serial_shutdown(struct uart_port *port)
+{
+ struct arc_uart_port *uart = to_arc_port(port);
+ free_irq(uart->port.irq, uart);
+}
+
+static void
+arc_serial_set_termios(struct uart_port *port, struct ktermios *new,
+ struct ktermios *old)
+{
+ struct arc_uart_port *uart = to_arc_port(port);
+ unsigned int baud, uartl, uarth, hw_val;
+ unsigned long flags;
+
+ /*
+ * Use the generic handler so that any specially encoded baud rates
+ * such as SPD_xx flags or "%B0" can be handled
+ * Max Baud I suppose will not be more than current 115K * 4
+ * Formula for ARC UART is: hw-val = ((CLK/(BAUD*4)) -1)
+ * spread over two 8-bit registers
+ */
+ baud = uart_get_baud_rate(port, new, old, 0, 460800);
+
+ hw_val = port->uartclk / (uart->baud * 4) - 1;
+ uartl = hw_val & 0xFF;
+ uarth = (hw_val >> 8) & 0xFF;
+
+ /*
+ * UART ISS(Instruction Set simulator) emulation has a subtle bug:
+ * A existing value of Baudh = 0 is used as a indication to startup
+ * it's internal state machine.
+ * Thus if baudh is set to 0, 2 times, it chokes.
+ * This happens with BAUD=115200 and the formaula above
+ * Until that is fixed, when running on ISS, we will set baudh to !0
+ */
+ if (uart->is_emulated)
+ uarth = 1;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ UART_ALL_IRQ_DISABLE(uart);
+
+ UART_SET_BAUDL(uart, uartl);
+ UART_SET_BAUDH(uart, uarth);
+
+ UART_RX_IRQ_ENABLE(uart);
+
+ /*
+ * UART doesn't support Parity/Hardware Flow Control;
+ * Only supports 8N1 character size
+ */
+ new->c_cflag &= ~(CMSPAR|CRTSCTS|CSIZE);
+ new->c_cflag |= CS8;
+
+ if (old)
+ tty_termios_copy_hw(new, old);
+
+ /* Don't rewrite B0 */
+ if (tty_termios_baud_rate(new))
+ tty_termios_encode_baud_rate(new, baud, baud);
+
+ uart_update_timeout(port, new->c_cflag, baud);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *arc_serial_type(struct uart_port *port)
+{
+ struct arc_uart_port *uart = to_arc_port(port);
+
+ return uart->port.type == PORT_ARC ? DRIVER_NAME : NULL;
+}
+
+static void arc_serial_release_port(struct uart_port *port)
+{
+}
+
+static int arc_serial_request_port(struct uart_port *port)
+{
+ return 0;
+}
+
+/*
+ * Verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int
+arc_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+ if (port->type != PORT_UNKNOWN && ser->type != PORT_ARC)
+ return -EINVAL;
+
+ return 0;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void arc_serial_config_port(struct uart_port *port, int flags)
+{
+ struct arc_uart_port *uart = to_arc_port(port);
+
+ if (flags & UART_CONFIG_TYPE)
+ uart->port.type = PORT_ARC;
+}
+
+#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_ARC_CONSOLE)
+
+static void arc_serial_poll_putchar(struct uart_port *port, unsigned char chr)
+{
+ struct arc_uart_port *uart = to_arc_port(port);
+
+ while (!(UART_GET_STATUS(uart) & TXEMPTY))
+ cpu_relax();
+
+ UART_SET_DATA(uart, chr);
+}
+#endif
+
+#ifdef CONFIG_CONSOLE_POLL
+static int arc_serial_poll_getchar(struct uart_port *port)
+{
+ struct arc_uart_port *uart = to_arc_port(port);
+ unsigned char chr;
+
+ while (!(UART_GET_STATUS(uart) & RXEMPTY))
+ cpu_relax();
+
+ chr = UART_GET_DATA(uart);
+ return chr;
+}
+#endif
+
+static struct uart_ops arc_serial_pops = {
+ .tx_empty = arc_serial_tx_empty,
+ .set_mctrl = arc_serial_set_mctrl,
+ .get_mctrl = arc_serial_get_mctrl,
+ .stop_tx = arc_serial_stop_tx,
+ .start_tx = arc_serial_start_tx,
+ .stop_rx = arc_serial_stop_rx,
+ .enable_ms = arc_serial_enable_ms,
+ .break_ctl = arc_serial_break_ctl,
+ .startup = arc_serial_startup,
+ .shutdown = arc_serial_shutdown,
+ .set_termios = arc_serial_set_termios,
+ .type = arc_serial_type,
+ .release_port = arc_serial_release_port,
+ .request_port = arc_serial_request_port,
+ .config_port = arc_serial_config_port,
+ .verify_port = arc_serial_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+ .poll_put_char = arc_serial_poll_putchar,
+ .poll_get_char = arc_serial_poll_getchar,
+#endif
+};
+
+static int
+arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart)
+{
+ struct resource *res, *res2;
+ unsigned long *plat_data;
+
+ if (pdev->id < 0 || pdev->id >= CONFIG_SERIAL_ARC_NR_PORTS) {
+ dev_err(&pdev->dev, "Wrong uart platform device id.\n");
+ return -ENOENT;
+ }
+
+ plat_data = ((unsigned long *)(pdev->dev.platform_data));
+ uart->baud = plat_data[0];
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res2)
+ return -ENODEV;
+
+ uart->port.mapbase = res->start;
+ uart->port.membase = ioremap_nocache(res->start, resource_size(res));
+ if (!uart->port.membase)
+ /* No point of dev_err since UART itself is hosed here */
+ return -ENXIO;
+
+ uart->port.irq = res2->start;
+ uart->port.dev = &pdev->dev;
+ uart->port.iotype = UPIO_MEM;
+ uart->port.flags = UPF_BOOT_AUTOCONF;
+ uart->port.line = pdev->id;
+ uart->port.ops = &arc_serial_pops;
+
+ uart->port.uartclk = plat_data[1];
+ uart->port.fifosize = ARC_UART_TX_FIFO_SIZE;
+
+ /*
+ * uart_insert_char( ) uses it in decideding whether to ignore a
+ * char or not. Explicitly setting it here, removes the subtelty
+ */
+ uart->port.ignore_status_mask = 0;
+
+ /* Real Hardware vs. emulated to work around a bug */
+ uart->is_emulated = !!plat_data[2];
+
+ return 0;
+}
+
+#ifdef CONFIG_SERIAL_ARC_CONSOLE
+
+static int arc_serial_console_setup(struct console *co, char *options)
+{
+ struct uart_port *port;
+ int baud = 115200;
+ int bits = 8;
+ int parity = 'n';
+ int flow = 'n';
+
+ if (co->index < 0 || co->index >= CONFIG_SERIAL_ARC_NR_PORTS)
+ return -ENODEV;
+
+ /*
+ * The uart port backing the console (e.g. ttyARC1) might not have been
+ * init yet. If so, defer the console setup to after the port.
+ */
+ port = &arc_uart_ports[co->index].port;
+ if (!port->membase)
+ return -ENODEV;
+
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+ /*
+ * Serial core will call port->ops->set_termios( )
+ * which will set the baud reg
+ */
+ return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static void arc_serial_console_putchar(struct uart_port *port, int ch)
+{
+ arc_serial_poll_putchar(port, (unsigned char)ch);
+}
+
+/*
+ * Interrupts are disabled on entering
+ */
+static void arc_serial_console_write(struct console *co, const char *s,
+ unsigned int count)
+{
+ struct uart_port *port = &arc_uart_ports[co->index].port;
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+ uart_console_write(port, s, count, arc_serial_console_putchar);
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static struct console arc_console = {
+ .name = ARC_SERIAL_DEV_NAME,
+ .write = arc_serial_console_write,
+ .device = uart_console_device,
+ .setup = arc_serial_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+ .data = &arc_uart_driver
+};
+
+static __init void early_serial_write(struct console *con, const char *s,
+ unsigned int n)
+{
+ struct uart_port *port = &arc_uart_ports[con->index].port;
+ unsigned int i;
+
+ for (i = 0; i < n; i++, s++) {
+ if (*s == '\n')
+ arc_serial_poll_putchar(port, '\r');
+ arc_serial_poll_putchar(port, *s);
+ }
+}
+
+static struct __initdata console arc_early_serial_console = {
+ .name = "early_ARCuart",
+ .write = early_serial_write,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
+ .index = -1
+};
+
+static int arc_serial_probe_earlyprintk(struct platform_device *pdev)
+{
+ arc_early_serial_console.index = pdev->id;
+
+ arc_uart_init_one(pdev, &arc_uart_ports[pdev->id]);
+
+ arc_serial_console_setup(&arc_early_serial_console, NULL);
+
+ register_console(&arc_early_serial_console);
+ return 0;
+}
+#else
+static int arc_serial_probe_earlyprintk(struct platform_device *pdev)
+{
+ return -ENODEV;
+}
+#endif /* CONFIG_SERIAL_ARC_CONSOLE */
+
+static int arc_serial_probe(struct platform_device *pdev)
+{
+ struct arc_uart_port *uart;
+ int rc;
+
+ if (is_early_platform_device(pdev))
+ return arc_serial_probe_earlyprintk(pdev);
+
+ uart = &arc_uart_ports[pdev->id];
+ rc = arc_uart_init_one(pdev, uart);
+ if (rc)
+ return rc;
+
+ return uart_add_one_port(&arc_uart_driver, &uart->port);
+}
+
+static int arc_serial_remove(struct platform_device *pdev)
+{
+ /* This will never be called */
+ return 0;
+}
+
+static struct platform_driver arc_platform_driver = {
+ .probe = arc_serial_probe,
+ .remove = arc_serial_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+#ifdef CONFIG_SERIAL_ARC_CONSOLE
+/*
+ * Register an early platform driver of "earlyprintk" class.
+ * ARCH platform code installs the driver and probes the early devices
+ * The installation could rely on user specifying earlyprintk=xyx in cmd line
+ * or it could be done independently, for all "earlyprintk" class drivers.
+ * [see arch/arc/plat-arcfpga/platform.c]
+ */
+early_platform_init("earlyprintk", &arc_platform_driver);
+
+#endif /* CONFIG_SERIAL_ARC_CONSOLE */
+
+static int __init arc_serial_init(void)
+{
+ int ret;
+
+ ret = uart_register_driver(&arc_uart_driver);
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&arc_platform_driver);
+ if (ret)
+ uart_unregister_driver(&arc_uart_driver);
+
+ return ret;
+}
+
+static void __exit arc_serial_exit(void)
+{
+ platform_driver_unregister(&arc_platform_driver);
+ uart_unregister_driver(&arc_uart_driver);
+}
+
+module_init(arc_serial_init);
+module_exit(arc_serial_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("plat-arcfpga/uart");
+MODULE_AUTHOR("Vineet Gupta");
+MODULE_DESCRIPTION("ARC(Synopsys) On-Chip(fpga) serial driver");
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 3d7e1ee2fa5..b95886c1198 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -39,6 +39,7 @@
#include <linux/atmel_pdc.h>
#include <linux/atmel_serial.h>
#include <linux/uaccess.h>
+#include <linux/pinctrl/consumer.h>
#include <asm/io.h>
#include <asm/ioctls.h>
@@ -1423,7 +1424,7 @@ static struct uart_ops atmel_pops = {
#endif
};
-static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port,
+static void atmel_of_init_port(struct atmel_uart_port *atmel_port,
struct device_node *np)
{
u32 rs485_delay[2];
@@ -1458,7 +1459,7 @@ static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port,
/*
* Configure the port from the platform device resource info.
*/
-static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
+static void atmel_init_port(struct atmel_uart_port *atmel_port,
struct platform_device *pdev)
{
struct uart_port *port = &atmel_port->uart;
@@ -1766,13 +1767,14 @@ static int atmel_serial_resume(struct platform_device *pdev)
#define atmel_serial_resume NULL
#endif
-static int __devinit atmel_serial_probe(struct platform_device *pdev)
+static int atmel_serial_probe(struct platform_device *pdev)
{
struct atmel_uart_port *port;
struct device_node *np = pdev->dev.of_node;
struct atmel_uart_data *pdata = pdev->dev.platform_data;
void *data;
int ret = -ENODEV;
+ struct pinctrl *pinctrl;
BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
@@ -1805,6 +1807,12 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
atmel_init_port(port, pdev);
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl)) {
+ ret = PTR_ERR(pinctrl);
+ goto err;
+ }
+
if (!atmel_use_dma_rx(&port->uart)) {
ret = -ENOMEM;
data = kmalloc(sizeof(struct atmel_uart_char)
@@ -1851,7 +1859,7 @@ err:
return ret;
}
-static int __devexit atmel_serial_remove(struct platform_device *pdev)
+static int atmel_serial_remove(struct platform_device *pdev)
{
struct uart_port *port = platform_get_drvdata(pdev);
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
@@ -1876,7 +1884,7 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev)
static struct platform_driver atmel_serial_driver = {
.probe = atmel_serial_probe,
- .remove = __devexit_p(atmel_serial_remove),
+ .remove = atmel_serial_remove,
.suspend = atmel_serial_suspend,
.resume = atmel_serial_resume,
.driver = {
diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c
index c0b68b9cad9..c76a226080f 100644
--- a/drivers/tty/serial/bcm63xx_uart.c
+++ b/drivers/tty/serial/bcm63xx_uart.c
@@ -801,7 +801,7 @@ static struct uart_driver bcm_uart_driver = {
/*
* platform driver probe/remove callback
*/
-static int __devinit bcm_uart_probe(struct platform_device *pdev)
+static int bcm_uart_probe(struct platform_device *pdev)
{
struct resource *res_mem, *res_irq;
struct uart_port *port;
@@ -848,7 +848,7 @@ static int __devinit bcm_uart_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit bcm_uart_remove(struct platform_device *pdev)
+static int bcm_uart_remove(struct platform_device *pdev)
{
struct uart_port *port;
@@ -865,7 +865,7 @@ static int __devexit bcm_uart_remove(struct platform_device *pdev)
*/
static struct platform_driver bcm_uart_platform_driver = {
.probe = bcm_uart_probe,
- .remove = __devexit_p(bcm_uart_remove),
+ .remove = bcm_uart_remove,
.driver = {
.owner = THIS_MODULE,
.name = "bcm63xx_uart",
diff --git a/drivers/tty/serial/bfin_sport_uart.c b/drivers/tty/serial/bfin_sport_uart.c
index 7fbc3a08f10..f5d117379b6 100644
--- a/drivers/tty/serial/bfin_sport_uart.c
+++ b/drivers/tty/serial/bfin_sport_uart.c
@@ -740,7 +740,7 @@ static struct dev_pm_ops bfin_sport_uart_dev_pm_ops = {
};
#endif
-static int __devinit sport_uart_probe(struct platform_device *pdev)
+static int sport_uart_probe(struct platform_device *pdev)
{
struct resource *res;
struct sport_uart_port *sport;
@@ -850,7 +850,7 @@ out_error_free_mem:
return ret;
}
-static int __devexit sport_uart_remove(struct platform_device *pdev)
+static int sport_uart_remove(struct platform_device *pdev)
{
struct sport_uart_port *sport = platform_get_drvdata(pdev);
@@ -871,7 +871,7 @@ static int __devexit sport_uart_remove(struct platform_device *pdev)
static struct platform_driver sport_uart_driver = {
.probe = sport_uart_probe,
- .remove = __devexit_p(sport_uart_remove),
+ .remove = sport_uart_remove,
.driver = {
.name = DRV_NAME,
#ifdef CONFIG_PM
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c
index 9242d56ba26..e6a008f4939 100644
--- a/drivers/tty/serial/bfin_uart.c
+++ b/drivers/tty/serial/bfin_uart.c
@@ -477,9 +477,9 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
{
int x_pos, pos;
+ unsigned long flags;
- dma_disable_irq_nosync(uart->rx_dma_channel);
- spin_lock_bh(&uart->rx_lock);
+ spin_lock_irqsave(&uart->rx_lock, flags);
/* 2D DMA RX buffer ring is used. Because curr_y_count and
* curr_x_count can't be read as an atomic operation,
@@ -510,8 +510,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
uart->rx_dma_buf.tail = uart->rx_dma_buf.head;
}
- spin_unlock_bh(&uart->rx_lock);
- dma_enable_irq(uart->rx_dma_channel);
+ spin_unlock_irqrestore(&uart->rx_lock, flags);
mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES);
}
@@ -800,6 +799,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned long flags;
unsigned int baud, quot;
unsigned int ier, lcr = 0;
+ unsigned long timeout;
switch (termios->c_cflag & CSIZE) {
case CS8:
@@ -869,6 +869,14 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15);
+ /* Wait till the transfer buffer is empty */
+ timeout = jiffies + msecs_to_jiffies(10);
+ while (UART_GET_GCTL(uart) & UCEN && !(UART_GET_LSR(uart) & TEMT))
+ if (time_after(jiffies, timeout)) {
+ dev_warn(port->dev, "timeout waiting for TX buffer empty\n");
+ break;
+ }
+
/* Disable UART */
ier = UART_GET_IER(uart);
UART_PUT_GCTL(uart, UART_GET_GCTL(uart) & ~UCEN);
@@ -1390,7 +1398,7 @@ out_error_free_mem:
return ret;
}
-static int __devexit bfin_serial_remove(struct platform_device *pdev)
+static int bfin_serial_remove(struct platform_device *pdev)
{
struct bfin_serial_port *uart = platform_get_drvdata(pdev);
@@ -1410,7 +1418,7 @@ static int __devexit bfin_serial_remove(struct platform_device *pdev)
static struct platform_driver bfin_serial_driver = {
.probe = bfin_serial_probe,
- .remove = __devexit_p(bfin_serial_remove),
+ .remove = bfin_serial_remove,
.suspend = bfin_serial_suspend,
.resume = bfin_serial_resume,
.driver = {
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c
index d0f719fafc8..3fd2526d121 100644
--- a/drivers/tty/serial/clps711x.c
+++ b/drivers/tty/serial/clps711x.c
@@ -10,15 +10,6 @@
* 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
*/
#if defined(CONFIG_SERIAL_CLPS711X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -26,172 +17,169 @@
#endif
#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/sysrq.h>
-#include <linux/spinlock.h>
#include <linux/device.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
+#include <linux/console.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#define UART_NR 2
-
-#define SERIAL_CLPS711X_MAJOR 204
-#define SERIAL_CLPS711X_MINOR 40
-#define SERIAL_CLPS711X_NR UART_NR
-
-/*
- * We use the relevant SYSCON register as a base address for these ports.
- */
-#define UBRLCR(port) ((port)->iobase + UBRLCR1 - SYSCON1)
-#define UARTDR(port) ((port)->iobase + UARTDR1 - SYSCON1)
-#define SYSFLG(port) ((port)->iobase + SYSFLG1 - SYSCON1)
-#define SYSCON(port) ((port)->iobase + SYSCON1 - SYSCON1)
-
-#define TX_IRQ(port) ((port)->irq)
-#define RX_IRQ(port) ((port)->irq + 1)
-#define UART_ANY_ERR (UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR)
-
-#define tx_enabled(port) ((port)->unused[0])
+#define UART_CLPS711X_NAME "uart-clps711x"
+#define UART_CLPS711X_NR 2
+#define UART_CLPS711X_MAJOR 204
+#define UART_CLPS711X_MINOR 40
+
+#define UBRLCR(port) ((port)->line ? UBRLCR2 : UBRLCR1)
+#define UARTDR(port) ((port)->line ? UARTDR2 : UARTDR1)
+#define SYSFLG(port) ((port)->line ? SYSFLG2 : SYSFLG1)
+#define SYSCON(port) ((port)->line ? SYSCON2 : SYSCON1)
+#define TX_IRQ(port) ((port)->line ? IRQ_UTXINT2 : IRQ_UTXINT1)
+#define RX_IRQ(port) ((port)->line ? IRQ_URXINT2 : IRQ_URXINT1)
+
+struct clps711x_port {
+ struct uart_driver uart;
+ struct clk *uart_clk;
+ struct uart_port port[UART_CLPS711X_NR];
+ int tx_enabled[UART_CLPS711X_NR];
+#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
+ struct console console;
+#endif
+};
-static void clps711xuart_stop_tx(struct uart_port *port)
+static void uart_clps711x_stop_tx(struct uart_port *port)
{
- if (tx_enabled(port)) {
+ struct clps711x_port *s = dev_get_drvdata(port->dev);
+
+ if (s->tx_enabled[port->line]) {
disable_irq(TX_IRQ(port));
- tx_enabled(port) = 0;
+ s->tx_enabled[port->line] = 0;
}
}
-static void clps711xuart_start_tx(struct uart_port *port)
+static void uart_clps711x_start_tx(struct uart_port *port)
{
- if (!tx_enabled(port)) {
+ struct clps711x_port *s = dev_get_drvdata(port->dev);
+
+ if (!s->tx_enabled[port->line]) {
enable_irq(TX_IRQ(port));
- tx_enabled(port) = 1;
+ s->tx_enabled[port->line] = 1;
}
}
-static void clps711xuart_stop_rx(struct uart_port *port)
+static void uart_clps711x_stop_rx(struct uart_port *port)
{
disable_irq(RX_IRQ(port));
}
-static void clps711xuart_enable_ms(struct uart_port *port)
+static void uart_clps711x_enable_ms(struct uart_port *port)
{
+ /* Do nothing */
}
-static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id)
+static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
- struct tty_struct *tty = port->state->port.tty;
+ struct tty_struct *tty = tty_port_tty_get(&port->state->port);
unsigned int status, ch, flg;
- status = clps_readl(SYSFLG(port));
- while (!(status & SYSFLG_URXFE)) {
- ch = clps_readl(UARTDR(port));
+ if (!tty)
+ return IRQ_HANDLED;
- port->icount.rx++;
+ for (;;) {
+ status = clps_readl(SYSFLG(port));
+ if (status & SYSFLG_URXFE)
+ break;
+
+ ch = clps_readw(UARTDR(port));
+ status = ch & (UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR);
+ ch &= 0xff;
+ port->icount.rx++;
flg = TTY_NORMAL;
- /*
- * Note that the error handling code is
- * out of the main execution path
- */
- if (unlikely(ch & UART_ANY_ERR)) {
- if (ch & UARTDR_PARERR)
+ if (unlikely(status)) {
+ if (status & UARTDR_PARERR)
port->icount.parity++;
- else if (ch & UARTDR_FRMERR)
+ else if (status & UARTDR_FRMERR)
port->icount.frame++;
- if (ch & UARTDR_OVERR)
+ else if (status & UARTDR_OVERR)
port->icount.overrun++;
- ch &= port->read_status_mask;
+ status &= port->read_status_mask;
- if (ch & UARTDR_PARERR)
+ if (status & UARTDR_PARERR)
flg = TTY_PARITY;
- else if (ch & UARTDR_FRMERR)
+ else if (status & UARTDR_FRMERR)
flg = TTY_FRAME;
-
-#ifdef SUPPORT_SYSRQ
- port->sysrq = 0;
-#endif
+ else if (status & UARTDR_OVERR)
+ flg = TTY_OVERRUN;
}
if (uart_handle_sysrq_char(port, ch))
- goto ignore_char;
+ continue;
- /*
- * CHECK: does overrun affect the current character?
- * ASSUMPTION: it does not.
- */
- uart_insert_char(port, ch, UARTDR_OVERR, ch, flg);
+ if (status & port->ignore_status_mask)
+ continue;
- ignore_char:
- status = clps_readl(SYSFLG(port));
+ uart_insert_char(port, status, UARTDR_OVERR, ch, flg);
}
+
tty_flip_buffer_push(tty);
+
+ tty_kref_put(tty);
+
return IRQ_HANDLED;
}
-static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)
+static irqreturn_t uart_clps711x_int_tx(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
+ struct clps711x_port *s = dev_get_drvdata(port->dev);
struct circ_buf *xmit = &port->state->xmit;
- int count;
if (port->x_char) {
- clps_writel(port->x_char, UARTDR(port));
+ clps_writew(port->x_char, UARTDR(port));
port->icount.tx++;
port->x_char = 0;
return IRQ_HANDLED;
}
- if (uart_circ_empty(xmit) || uart_tx_stopped(port))
- goto disable_tx_irq;
+ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+ disable_irq_nosync(TX_IRQ(port));
+ s->tx_enabled[port->line] = 0;
+ return IRQ_HANDLED;
+ }
- count = port->fifosize >> 1;
- do {
- clps_writel(xmit->buf[xmit->tail], UARTDR(port));
+ while (!uart_circ_empty(xmit)) {
+ clps_writew(xmit->buf[xmit->tail], UARTDR(port));
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
port->icount.tx++;
- if (uart_circ_empty(xmit))
+ if (clps_readl(SYSFLG(port) & SYSFLG_UTXFF))
break;
- } while (--count > 0);
+ }
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
- if (uart_circ_empty(xmit)) {
- disable_tx_irq:
- disable_irq_nosync(TX_IRQ(port));
- tx_enabled(port) = 0;
- }
-
return IRQ_HANDLED;
}
-static unsigned int clps711xuart_tx_empty(struct uart_port *port)
+static unsigned int uart_clps711x_tx_empty(struct uart_port *port)
{
- unsigned int status = clps_readl(SYSFLG(port));
- return status & SYSFLG_UBUSY ? 0 : TIOCSER_TEMT;
+ return (clps_readl(SYSFLG(port) & SYSFLG_UBUSY)) ? 0 : TIOCSER_TEMT;
}
-static unsigned int clps711xuart_get_mctrl(struct uart_port *port)
+static unsigned int uart_clps711x_get_mctrl(struct uart_port *port)
{
- unsigned int port_addr;
- unsigned int result = 0;
- unsigned int status;
+ unsigned int status, result = 0;
- port_addr = SYSFLG(port);
- if (port_addr == SYSFLG1) {
+ if (port->line == 0) {
status = clps_readl(SYSFLG1);
if (status & SYSFLG1_DCD)
result |= TIOCM_CAR;
@@ -199,104 +187,86 @@ static unsigned int clps711xuart_get_mctrl(struct uart_port *port)
result |= TIOCM_DSR;
if (status & SYSFLG1_CTS)
result |= TIOCM_CTS;
- }
+ } else
+ result = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR;
return result;
}
-static void
-clps711xuart_set_mctrl_null(struct uart_port *port, unsigned int mctrl)
+static void uart_clps711x_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
+ /* Do nothing */
}
-static void clps711xuart_break_ctl(struct uart_port *port, int break_state)
+static void uart_clps711x_break_ctl(struct uart_port *port, int break_state)
{
unsigned long flags;
unsigned int ubrlcr;
spin_lock_irqsave(&port->lock, flags);
+
ubrlcr = clps_readl(UBRLCR(port));
- if (break_state == -1)
+ if (break_state)
ubrlcr |= UBRLCR_BREAK;
else
ubrlcr &= ~UBRLCR_BREAK;
clps_writel(ubrlcr, UBRLCR(port));
+
spin_unlock_irqrestore(&port->lock, flags);
}
-static int clps711xuart_startup(struct uart_port *port)
+static int uart_clps711x_startup(struct uart_port *port)
{
- unsigned int syscon;
- int retval;
-
- tx_enabled(port) = 1;
-
- /*
- * Allocate the IRQs
- */
- retval = request_irq(TX_IRQ(port), clps711xuart_int_tx, 0,
- "clps711xuart_tx", port);
- if (retval)
- return retval;
-
- retval = request_irq(RX_IRQ(port), clps711xuart_int_rx, 0,
- "clps711xuart_rx", port);
- if (retval) {
- free_irq(TX_IRQ(port), port);
- return retval;
+ struct clps711x_port *s = dev_get_drvdata(port->dev);
+ int ret;
+
+ s->tx_enabled[port->line] = 1;
+ /* Allocate the IRQs */
+ ret = devm_request_irq(port->dev, TX_IRQ(port), uart_clps711x_int_tx,
+ 0, UART_CLPS711X_NAME " TX", port);
+ if (ret)
+ return ret;
+
+ ret = devm_request_irq(port->dev, RX_IRQ(port), uart_clps711x_int_rx,
+ 0, UART_CLPS711X_NAME " RX", port);
+ if (ret) {
+ devm_free_irq(port->dev, TX_IRQ(port), port);
+ return ret;
}
- /*
- * enable the port
- */
- syscon = clps_readl(SYSCON(port));
- syscon |= SYSCON_UARTEN;
- clps_writel(syscon, SYSCON(port));
+ /* Disable break */
+ clps_writel(clps_readl(UBRLCR(port)) & ~UBRLCR_BREAK, UBRLCR(port));
+
+ /* Enable the port */
+ clps_writel(clps_readl(SYSCON(port)) | SYSCON_UARTEN, SYSCON(port));
return 0;
}
-static void clps711xuart_shutdown(struct uart_port *port)
+static void uart_clps711x_shutdown(struct uart_port *port)
{
- unsigned int ubrlcr, syscon;
+ /* Free the interrupts */
+ devm_free_irq(port->dev, TX_IRQ(port), port);
+ devm_free_irq(port->dev, RX_IRQ(port), port);
- /*
- * Free the interrupt
- */
- free_irq(TX_IRQ(port), port); /* TX interrupt */
- free_irq(RX_IRQ(port), port); /* RX interrupt */
-
- /*
- * disable the port
- */
- syscon = clps_readl(SYSCON(port));
- syscon &= ~SYSCON_UARTEN;
- clps_writel(syscon, SYSCON(port));
-
- /*
- * disable break condition and fifos
- */
- ubrlcr = clps_readl(UBRLCR(port));
- ubrlcr &= ~(UBRLCR_FIFOEN | UBRLCR_BREAK);
- clps_writel(ubrlcr, UBRLCR(port));
+ /* Disable the port */
+ clps_writel(clps_readl(SYSCON(port)) & ~SYSCON_UARTEN, SYSCON(port));
}
-static void
-clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios,
- struct ktermios *old)
+static void uart_clps711x_set_termios(struct uart_port *port,
+ struct ktermios *termios,
+ struct ktermios *old)
{
unsigned int ubrlcr, baud, quot;
unsigned long flags;
- /*
- * We don't implement CREAD.
- */
- termios->c_cflag |= CREAD;
+ /* Mask termios capabilities we don't support */
+ termios->c_cflag &= ~CMSPAR;
+ termios->c_iflag &= ~(BRKINT | IGNBRK);
- /*
- * Ask the core to calculate the divisor for us.
- */
- baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
+ /* Ask the core to calculate the divisor for us */
+ baud = uart_get_baud_rate(port, termios, old, port->uartclk / 4096,
+ port->uartclk / 16);
quot = uart_get_divisor(port, baud);
switch (termios->c_cflag & CSIZE) {
@@ -309,160 +279,117 @@ clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios,
case CS7:
ubrlcr = UBRLCR_WRDLEN7;
break;
- default: // CS8
+ case CS8:
+ default:
ubrlcr = UBRLCR_WRDLEN8;
break;
}
+
if (termios->c_cflag & CSTOPB)
ubrlcr |= UBRLCR_XSTOP;
+
if (termios->c_cflag & PARENB) {
ubrlcr |= UBRLCR_PRTEN;
if (!(termios->c_cflag & PARODD))
ubrlcr |= UBRLCR_EVENPRT;
}
- if (port->fifosize > 1)
- ubrlcr |= UBRLCR_FIFOEN;
- spin_lock_irqsave(&port->lock, flags);
+ /* Enable FIFO */
+ ubrlcr |= UBRLCR_FIFOEN;
- /*
- * Update the per-port timeout.
- */
- uart_update_timeout(port, termios->c_cflag, baud);
+ spin_lock_irqsave(&port->lock, flags);
+ /* Set read status mask */
port->read_status_mask = UARTDR_OVERR;
if (termios->c_iflag & INPCK)
port->read_status_mask |= UARTDR_PARERR | UARTDR_FRMERR;
- /*
- * Characters to ignore
- */
+ /* Set status ignore mask */
port->ignore_status_mask = 0;
- if (termios->c_iflag & IGNPAR)
- port->ignore_status_mask |= UARTDR_FRMERR | UARTDR_PARERR;
- if (termios->c_iflag & IGNBRK) {
- /*
- * If we're ignoring parity and break indicators,
- * ignore overruns to (for real raw support).
- */
- if (termios->c_iflag & IGNPAR)
- port->ignore_status_mask |= UARTDR_OVERR;
- }
+ if (!(termios->c_cflag & CREAD))
+ port->ignore_status_mask |= UARTDR_OVERR | UARTDR_PARERR |
+ UARTDR_FRMERR;
- quot -= 1;
+ uart_update_timeout(port, termios->c_cflag, baud);
- clps_writel(ubrlcr | quot, UBRLCR(port));
+ clps_writel(ubrlcr | (quot - 1), UBRLCR(port));
spin_unlock_irqrestore(&port->lock, flags);
}
-static const char *clps711xuart_type(struct uart_port *port)
+static const char *uart_clps711x_type(struct uart_port *port)
{
- return port->type == PORT_CLPS711X ? "CLPS711x" : NULL;
+ return (port->type == PORT_CLPS711X) ? "CLPS711X" : NULL;
}
-/*
- * Configure/autoconfigure the port.
- */
-static void clps711xuart_config_port(struct uart_port *port, int flags)
+static void uart_clps711x_config_port(struct uart_port *port, int flags)
{
if (flags & UART_CONFIG_TYPE)
port->type = PORT_CLPS711X;
}
-static void clps711xuart_release_port(struct uart_port *port)
+static void uart_clps711x_release_port(struct uart_port *port)
{
+ /* Do nothing */
}
-static int clps711xuart_request_port(struct uart_port *port)
+static int uart_clps711x_request_port(struct uart_port *port)
{
+ /* Do nothing */
return 0;
}
-static struct uart_ops clps711x_pops = {
- .tx_empty = clps711xuart_tx_empty,
- .set_mctrl = clps711xuart_set_mctrl_null,
- .get_mctrl = clps711xuart_get_mctrl,
- .stop_tx = clps711xuart_stop_tx,
- .start_tx = clps711xuart_start_tx,
- .stop_rx = clps711xuart_stop_rx,
- .enable_ms = clps711xuart_enable_ms,
- .break_ctl = clps711xuart_break_ctl,
- .startup = clps711xuart_startup,
- .shutdown = clps711xuart_shutdown,
- .set_termios = clps711xuart_set_termios,
- .type = clps711xuart_type,
- .config_port = clps711xuart_config_port,
- .release_port = clps711xuart_release_port,
- .request_port = clps711xuart_request_port,
-};
-
-static struct uart_port clps711x_ports[UART_NR] = {
- {
- .iobase = SYSCON1,
- .irq = IRQ_UTXINT1, /* IRQ_URXINT1, IRQ_UMSINT */
- .uartclk = 3686400,
- .fifosize = 16,
- .ops = &clps711x_pops,
- .line = 0,
- .flags = UPF_BOOT_AUTOCONF,
- },
- {
- .iobase = SYSCON2,
- .irq = IRQ_UTXINT2, /* IRQ_URXINT2 */
- .uartclk = 3686400,
- .fifosize = 16,
- .ops = &clps711x_pops,
- .line = 1,
- .flags = UPF_BOOT_AUTOCONF,
- }
+static const struct uart_ops uart_clps711x_ops = {
+ .tx_empty = uart_clps711x_tx_empty,
+ .set_mctrl = uart_clps711x_set_mctrl,
+ .get_mctrl = uart_clps711x_get_mctrl,
+ .stop_tx = uart_clps711x_stop_tx,
+ .start_tx = uart_clps711x_start_tx,
+ .stop_rx = uart_clps711x_stop_rx,
+ .enable_ms = uart_clps711x_enable_ms,
+ .break_ctl = uart_clps711x_break_ctl,
+ .startup = uart_clps711x_startup,
+ .shutdown = uart_clps711x_shutdown,
+ .set_termios = uart_clps711x_set_termios,
+ .type = uart_clps711x_type,
+ .config_port = uart_clps711x_config_port,
+ .release_port = uart_clps711x_release_port,
+ .request_port = uart_clps711x_request_port,
};
#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
-static void clps711xuart_console_putchar(struct uart_port *port, int ch)
+static void uart_clps711x_console_putchar(struct uart_port *port, int ch)
{
while (clps_readl(SYSFLG(port)) & SYSFLG_UTXFF)
barrier();
- clps_writel(ch, UARTDR(port));
+
+ clps_writew(ch, UARTDR(port));
}
-/*
- * Print a string to the serial port trying not to disturb
- * any possible real use of the port...
- *
- * The console_lock must be held when we get here.
- *
- * Note that this is called with interrupts already disabled
- */
-static void
-clps711xuart_console_write(struct console *co, const char *s,
- unsigned int count)
+static void uart_clps711x_console_write(struct console *co, const char *c,
+ unsigned n)
{
- struct uart_port *port = clps711x_ports + co->index;
- unsigned int status, syscon;
+ struct clps711x_port *s = (struct clps711x_port *)co->data;
+ struct uart_port *port = &s->port[co->index];
+ u32 syscon;
- /*
- * Ensure that the port is enabled.
- */
+ /* Ensure that the port is enabled */
syscon = clps_readl(SYSCON(port));
clps_writel(syscon | SYSCON_UARTEN, SYSCON(port));
- uart_console_write(port, s, count, clps711xuart_console_putchar);
+ uart_console_write(port, c, n, uart_clps711x_console_putchar);
- /*
- * Finally, wait for transmitter to become empty
- * and restore the uart state.
- */
- do {
- status = clps_readl(SYSFLG(port));
- } while (status & SYSFLG_UBUSY);
+ /* Wait for transmitter to become empty */
+ while (clps_readl(SYSFLG(port)) & SYSFLG_UBUSY)
+ barrier();
+ /* Restore the uart state */
clps_writel(syscon, SYSCON(port));
}
-static void __init
-clps711xuart_console_get_options(struct uart_port *port, int *baud,
- int *parity, int *bits)
+static void uart_clps711x_console_get_options(struct uart_port *port,
+ int *baud, int *parity,
+ int *bits)
{
if (clps_readl(SYSCON(port)) & SYSCON_UARTEN) {
unsigned int ubrlcr, quot;
@@ -487,92 +414,124 @@ clps711xuart_console_get_options(struct uart_port *port, int *baud,
}
}
-static int __init clps711xuart_console_setup(struct console *co, char *options)
+static int uart_clps711x_console_setup(struct console *co, char *options)
{
- struct uart_port *port;
- int baud = 38400;
- int bits = 8;
- int parity = 'n';
- int flow = 'n';
-
- /*
- * Check whether an invalid uart number has been specified, and
- * if so, search for the first available port that does have
- * console support.
- */
- port = uart_get_console(clps711x_ports, UART_NR, co);
+ int baud = 38400, bits = 8, parity = 'n', flow = 'n';
+ struct clps711x_port *s = (struct clps711x_port *)co->data;
+ struct uart_port *port = &s->port[(co->index > 0) ? co->index : 0];
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
else
- clps711xuart_console_get_options(port, &baud, &parity, &bits);
+ uart_clps711x_console_get_options(port, &baud, &parity, &bits);
return uart_set_options(port, co, baud, parity, bits, flow);
}
+#endif
-static struct uart_driver clps711x_reg;
-static struct console clps711x_console = {
- .name = "ttyCL",
- .write = clps711xuart_console_write,
- .device = uart_console_device,
- .setup = clps711xuart_console_setup,
- .flags = CON_PRINTBUFFER,
- .index = -1,
- .data = &clps711x_reg,
-};
-
-static int __init clps711xuart_console_init(void)
+static int uart_clps711x_probe(struct platform_device *pdev)
{
- register_console(&clps711x_console);
- return 0;
-}
-console_initcall(clps711xuart_console_init);
+ struct clps711x_port *s;
+ int ret, i;
+
+ s = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_port), GFP_KERNEL);
+ if (!s) {
+ dev_err(&pdev->dev, "Error allocating port structure\n");
+ return -ENOMEM;
+ }
+ platform_set_drvdata(pdev, s);
-#define CLPS711X_CONSOLE &clps711x_console
-#else
-#define CLPS711X_CONSOLE NULL
+ s->uart_clk = devm_clk_get(&pdev->dev, "uart");
+ if (IS_ERR(s->uart_clk)) {
+ dev_err(&pdev->dev, "Can't get UART clocks\n");
+ ret = PTR_ERR(s->uart_clk);
+ goto err_out;
+ }
+
+ s->uart.owner = THIS_MODULE;
+ s->uart.dev_name = "ttyCL";
+ s->uart.major = UART_CLPS711X_MAJOR;
+ s->uart.minor = UART_CLPS711X_MINOR;
+ s->uart.nr = UART_CLPS711X_NR;
+#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
+ s->uart.cons = &s->console;
+ s->uart.cons->device = uart_console_device;
+ s->uart.cons->write = uart_clps711x_console_write;
+ s->uart.cons->setup = uart_clps711x_console_setup;
+ s->uart.cons->flags = CON_PRINTBUFFER;
+ s->uart.cons->index = -1;
+ s->uart.cons->data = s;
+ strcpy(s->uart.cons->name, "ttyCL");
#endif
+ 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);
+ goto err_out;
+ }
-static struct uart_driver clps711x_reg = {
- .driver_name = "ttyCL",
- .dev_name = "ttyCL",
- .major = SERIAL_CLPS711X_MAJOR,
- .minor = SERIAL_CLPS711X_MINOR,
- .nr = UART_NR,
+ for (i = 0; i < UART_CLPS711X_NR; i++) {
+ s->port[i].line = i;
+ s->port[i].dev = &pdev->dev;
+ s->port[i].irq = TX_IRQ(&s->port[i]);
+ s->port[i].iobase = SYSCON(&s->port[i]);
+ s->port[i].type = PORT_CLPS711X;
+ s->port[i].fifosize = 16;
+ s->port[i].flags = UPF_SKIP_TEST | UPF_FIXED_TYPE;
+ s->port[i].uartclk = clk_get_rate(s->uart_clk);
+ s->port[i].ops = &uart_clps711x_ops;
+ WARN_ON(uart_add_one_port(&s->uart, &s->port[i]));
+ }
- .cons = CLPS711X_CONSOLE,
-};
+ return 0;
-static int __init clps711xuart_init(void)
-{
- int ret, i;
+err_out:
+ platform_set_drvdata(pdev, NULL);
- printk(KERN_INFO "Serial: CLPS711x driver\n");
+ return ret;
+}
- ret = uart_register_driver(&clps711x_reg);
- if (ret)
- return ret;
+static int uart_clps711x_remove(struct platform_device *pdev)
+{
+ struct clps711x_port *s = platform_get_drvdata(pdev);
+ int i;
- for (i = 0; i < UART_NR; i++)
- uart_add_one_port(&clps711x_reg, &clps711x_ports[i]);
+ 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);
+ platform_set_drvdata(pdev, NULL);
return 0;
}
-static void __exit clps711xuart_exit(void)
-{
- int i;
+static struct platform_driver clps711x_uart_driver = {
+ .driver = {
+ .name = UART_CLPS711X_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = uart_clps711x_probe,
+ .remove = uart_clps711x_remove,
+};
+module_platform_driver(clps711x_uart_driver);
- for (i = 0; i < UART_NR; i++)
- uart_remove_one_port(&clps711x_reg, &clps711x_ports[i]);
+static struct platform_device clps711x_uart_device = {
+ .name = UART_CLPS711X_NAME,
+};
- uart_unregister_driver(&clps711x_reg);
+static int __init uart_clps711x_init(void)
+{
+ return platform_device_register(&clps711x_uart_device);
}
+module_init(uart_clps711x_init);
-module_init(clps711xuart_init);
-module_exit(clps711xuart_exit);
+static void __exit uart_clps711x_exit(void)
+{
+ platform_device_unregister(&clps711x_uart_device);
+}
+module_exit(uart_clps711x_exit);
MODULE_AUTHOR("Deep Blue Solutions Ltd");
-MODULE_DESCRIPTION("CLPS-711x generic serial driver");
+MODULE_DESCRIPTION("CLPS711X serial driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS_CHARDEV(SERIAL_CLPS711X_MAJOR, SERIAL_CLPS711X_MINOR);
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
index d0dd9194cec..ad0caf17680 100644
--- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
@@ -1373,7 +1373,7 @@ static struct uart_driver cpm_reg = {
static int probe_index;
-static int __devinit cpm_uart_probe(struct platform_device *ofdev)
+static int cpm_uart_probe(struct platform_device *ofdev)
{
int index = probe_index++;
struct uart_cpm_port *pinfo = &cpm_uart_ports[index];
@@ -1396,7 +1396,7 @@ static int __devinit cpm_uart_probe(struct platform_device *ofdev)
return uart_add_one_port(&cpm_reg, &pinfo->port);
}
-static int __devexit cpm_uart_remove(struct platform_device *ofdev)
+static int cpm_uart_remove(struct platform_device *ofdev)
{
struct uart_cpm_port *pinfo = dev_get_drvdata(&ofdev->dev);
return uart_remove_one_port(&cpm_reg, &pinfo->port);
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c
index 615e4647049..a8cbb267052 100644
--- a/drivers/tty/serial/efm32-uart.c
+++ b/drivers/tty/serial/efm32-uart.c
@@ -690,7 +690,7 @@ static int efm32_uart_probe_dt(struct platform_device *pdev,
}
-static int __devinit efm32_uart_probe(struct platform_device *pdev)
+static int efm32_uart_probe(struct platform_device *pdev)
{
struct efm32_uart_port *efm_port;
struct resource *res;
@@ -764,7 +764,7 @@ err_get_base:
return ret;
}
-static int __devexit efm32_uart_remove(struct platform_device *pdev)
+static int efm32_uart_remove(struct platform_device *pdev)
{
struct efm32_uart_port *efm_port = platform_get_drvdata(pdev);
@@ -791,7 +791,7 @@ MODULE_DEVICE_TABLE(of, efm32_uart_dt_ids);
static struct platform_driver efm32_uart_driver = {
.probe = efm32_uart_probe,
- .remove = __devexit_p(efm32_uart_remove),
+ .remove = efm32_uart_remove,
.driver = {
.name = DRIVER_NAME,
diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c
index defc4e3393a..6197a69adb4 100644
--- a/drivers/tty/serial/icom.c
+++ b/drivers/tty/serial/icom.c
@@ -175,7 +175,7 @@ static void free_port_memory(struct icom_port *icom_port)
}
}
-static int __devinit get_port_memory(struct icom_port *icom_port)
+static int get_port_memory(struct icom_port *icom_port)
{
int index;
unsigned long stgAddr;
@@ -1314,7 +1314,7 @@ static struct uart_driver icom_uart_driver = {
.cons = ICOM_CONSOLE,
};
-static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
+static int icom_init_ports(struct icom_adapter *icom_adapter)
{
u32 subsystem_id = icom_adapter->subsystem_id;
int i;
@@ -1381,7 +1381,7 @@ static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *i
0x8024 + 2 - 2 * (icom_port->port - 2);
}
}
-static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
+static int icom_load_ports(struct icom_adapter *icom_adapter)
{
struct icom_port *icom_port;
int port_num;
@@ -1407,7 +1407,7 @@ static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
return 0;
}
-static int __devinit icom_alloc_adapter(struct icom_adapter
+static int icom_alloc_adapter(struct icom_adapter
**icom_adapter_ref)
{
int adapter_count = 0;
@@ -1487,7 +1487,7 @@ static void icom_kref_release(struct kref *kref)
icom_remove_adapter(icom_adapter);
}
-static int __devinit icom_probe(struct pci_dev *dev,
+static int icom_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
int index;
@@ -1596,7 +1596,7 @@ probe_exit0:
return retval;
}
-static void __devexit icom_remove(struct pci_dev *dev)
+static void icom_remove(struct pci_dev *dev)
{
struct icom_adapter *icom_adapter;
struct list_head *tmp;
@@ -1617,7 +1617,7 @@ static struct pci_driver icom_pci_driver = {
.name = ICOM_DRIVER_NAME,
.id_table = icom_pci_table,
.probe = icom_probe,
- .remove = __devexit_p(icom_remove),
+ .remove = icom_remove,
};
static int __init icom_init(void)
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c
index 5b9bc19ed13..675d94ab0af 100644
--- a/drivers/tty/serial/ifx6x60.c
+++ b/drivers/tty/serial/ifx6x60.c
@@ -60,20 +60,27 @@
#include <linux/pm_runtime.h>
#include <linux/spi/ifx_modem.h>
#include <linux/delay.h>
+#include <linux/reboot.h>
#include "ifx6x60.h"
#define IFX_SPI_MORE_MASK 0x10
-#define IFX_SPI_MORE_BIT 12 /* bit position in u16 */
-#define IFX_SPI_CTS_BIT 13 /* bit position in u16 */
+#define IFX_SPI_MORE_BIT 4 /* bit position in u8 */
+#define IFX_SPI_CTS_BIT 6 /* bit position in u8 */
#define IFX_SPI_MODE SPI_MODE_1
#define IFX_SPI_TTY_ID 0
#define IFX_SPI_TIMEOUT_SEC 2
#define IFX_SPI_HEADER_0 (-1)
#define IFX_SPI_HEADER_F (-2)
+#define PO_POST_DELAY 200
+#define IFX_MDM_RST_PMU 4
+
/* forward reference */
static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev);
+static int ifx_modem_reboot_callback(struct notifier_block *nfb,
+ unsigned long event, void *data);
+static int ifx_modem_power_off(struct ifx_spi_device *ifx_dev);
/* local variables */
static int spi_bpw = 16; /* 8, 16 or 32 bit word length */
@@ -81,6 +88,29 @@ static struct tty_driver *tty_drv;
static struct ifx_spi_device *saved_ifx_dev;
static struct lock_class_key ifx_spi_key;
+static struct notifier_block ifx_modem_reboot_notifier_block = {
+ .notifier_call = ifx_modem_reboot_callback,
+};
+
+static int ifx_modem_power_off(struct ifx_spi_device *ifx_dev)
+{
+ gpio_set_value(IFX_MDM_RST_PMU, 1);
+ msleep(PO_POST_DELAY);
+
+ return 0;
+}
+
+static int ifx_modem_reboot_callback(struct notifier_block *nfb,
+ unsigned long event, void *data)
+{
+ if (saved_ifx_dev)
+ ifx_modem_power_off(saved_ifx_dev);
+ else
+ pr_warn("no ifx modem active;\n");
+
+ return NOTIFY_OK;
+}
+
/* GPIO/GPE settings */
/**
@@ -152,26 +182,67 @@ ifx_spi_power_state_clear(struct ifx_spi_device *ifx_dev, unsigned char val)
}
/**
- * swap_buf
+ * swap_buf_8
* @buf: our buffer
* @len : number of bytes (not words) in the buffer
* @end: end of buffer
*
* Swap the contents of a buffer into big endian format
*/
-static inline void swap_buf(u16 *buf, int len, void *end)
+static inline void swap_buf_8(unsigned char *buf, int len, void *end)
+{
+ /* don't swap buffer if SPI word width is 8 bits */
+ return;
+}
+
+/**
+ * swap_buf_16
+ * @buf: our buffer
+ * @len : number of bytes (not words) in the buffer
+ * @end: end of buffer
+ *
+ * Swap the contents of a buffer into big endian format
+ */
+static inline void swap_buf_16(unsigned char *buf, int len, void *end)
{
int n;
+ u16 *buf_16 = (u16 *)buf;
len = ((len + 1) >> 1);
- if ((void *)&buf[len] > end) {
- pr_err("swap_buf: swap exceeds boundary (%p > %p)!",
- &buf[len], end);
+ if ((void *)&buf_16[len] > end) {
+ pr_err("swap_buf_16: swap exceeds boundary (%p > %p)!",
+ &buf_16[len], end);
+ return;
+ }
+ for (n = 0; n < len; n++) {
+ *buf_16 = cpu_to_be16(*buf_16);
+ buf_16++;
+ }
+}
+
+/**
+ * swap_buf_32
+ * @buf: our buffer
+ * @len : number of bytes (not words) in the buffer
+ * @end: end of buffer
+ *
+ * Swap the contents of a buffer into big endian format
+ */
+static inline void swap_buf_32(unsigned char *buf, int len, void *end)
+{
+ int n;
+
+ u32 *buf_32 = (u32 *)buf;
+ len = (len + 3) >> 2;
+
+ if ((void *)&buf_32[len] > end) {
+ pr_err("swap_buf_32: swap exceeds boundary (%p > %p)!\n",
+ &buf_32[len], end);
return;
}
for (n = 0; n < len; n++) {
- *buf = cpu_to_be16(*buf);
- buf++;
+ *buf_32 = cpu_to_be32(*buf_32);
+ buf_32++;
}
}
@@ -190,9 +261,7 @@ static void mrdy_assert(struct ifx_spi_device *ifx_dev)
if (!val) {
if (!test_and_set_bit(IFX_SPI_STATE_TIMER_PENDING,
&ifx_dev->flags)) {
- ifx_dev->spi_timer.expires =
- jiffies + IFX_SPI_TIMEOUT_SEC*HZ;
- add_timer(&ifx_dev->spi_timer);
+ mod_timer(&ifx_dev->spi_timer,jiffies + IFX_SPI_TIMEOUT_SEC*HZ);
}
}
@@ -449,7 +518,7 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev)
tx_count-IFX_SPI_HEADER_OVERHEAD,
ifx_dev->spi_more);
/* swap actual data in the buffer */
- swap_buf((u16 *)(ifx_dev->tx_buffer), tx_count,
+ ifx_dev->swap_buf((ifx_dev->tx_buffer), tx_count,
&ifx_dev->tx_buffer[IFX_SPI_TRANSFER_SIZE]);
return tx_count;
}
@@ -469,9 +538,17 @@ static int ifx_spi_write(struct tty_struct *tty, const unsigned char *buf,
{
struct ifx_spi_device *ifx_dev = tty->driver_data;
unsigned char *tmp_buf = (unsigned char *)buf;
- int tx_count = kfifo_in_locked(&ifx_dev->tx_fifo, tmp_buf, count,
- &ifx_dev->fifo_lock);
- mrdy_assert(ifx_dev);
+ unsigned long flags;
+ bool is_fifo_empty;
+ int tx_count;
+
+ spin_lock_irqsave(&ifx_dev->fifo_lock, flags);
+ is_fifo_empty = kfifo_is_empty(&ifx_dev->tx_fifo);
+ tx_count = kfifo_in(&ifx_dev->tx_fifo, tmp_buf, count);
+ spin_unlock_irqrestore(&ifx_dev->fifo_lock, flags);
+ if (is_fifo_empty)
+ mrdy_assert(ifx_dev);
+
return tx_count;
}
@@ -530,12 +607,19 @@ static int ifx_port_activate(struct tty_port *port, struct tty_struct *tty)
/* clear any old data; can't do this in 'close' */
kfifo_reset(&ifx_dev->tx_fifo);
+ /* clear any flag which may be set in port shutdown procedure */
+ clear_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags);
+ clear_bit(IFX_SPI_STATE_IO_READY, &ifx_dev->flags);
+
/* put port data into this tty */
tty->driver_data = ifx_dev;
/* allows flip string push from int context */
tty->low_latency = 1;
+ /* set flag to allows data transfer */
+ set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags);
+
return 0;
}
@@ -551,6 +635,7 @@ static void ifx_port_shutdown(struct tty_port *port)
struct ifx_spi_device *ifx_dev =
container_of(port, struct ifx_spi_device, tty_port);
+ clear_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags);
mrdy_set_low(ifx_dev);
clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
tasklet_kill(&ifx_dev->io_work_tasklet);
@@ -617,7 +702,7 @@ static void ifx_spi_complete(void *ctx)
if (!ifx_dev->spi_msg.status) {
/* check header validity, get comm flags */
- swap_buf((u16 *)ifx_dev->rx_buffer, IFX_SPI_HEADER_OVERHEAD,
+ ifx_dev->swap_buf(ifx_dev->rx_buffer, IFX_SPI_HEADER_OVERHEAD,
&ifx_dev->rx_buffer[IFX_SPI_HEADER_OVERHEAD]);
decode_result = ifx_spi_decode_spi_header(ifx_dev->rx_buffer,
&length, &more, &cts);
@@ -636,7 +721,8 @@ static void ifx_spi_complete(void *ctx)
actual_length = min((unsigned int)length,
ifx_dev->spi_msg.actual_length);
- swap_buf((u16 *)(ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD),
+ ifx_dev->swap_buf(
+ (ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD),
actual_length,
&ifx_dev->rx_buffer[IFX_SPI_TRANSFER_SIZE]);
ifx_spi_insert_flip_string(
@@ -705,7 +791,8 @@ static void ifx_spi_io(unsigned long data)
int retval;
struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *) data;
- if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags)) {
+ if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags) &&
+ test_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags)) {
if (ifx_dev->gpio.unack_srdy_int_nb > 0)
ifx_dev->gpio.unack_srdy_int_nb--;
@@ -773,6 +860,7 @@ static void ifx_spi_free_port(struct ifx_spi_device *ifx_dev)
{
if (ifx_dev->tty_dev)
tty_unregister_device(tty_drv, ifx_dev->minor);
+ tty_port_destroy(&ifx_dev->tty_port);
kfifo_free(&ifx_dev->tx_fifo);
}
@@ -806,10 +894,12 @@ static int ifx_spi_create_port(struct ifx_spi_device *ifx_dev)
dev_dbg(&ifx_dev->spi_dev->dev,
"%s: registering tty device failed", __func__);
ret = PTR_ERR(ifx_dev->tty_dev);
- goto error_ret;
+ goto error_port;
}
return 0;
+error_port:
+ tty_port_destroy(pport);
error_ret:
ifx_spi_free_port(ifx_dev);
return ret;
@@ -826,7 +916,7 @@ error_ret:
static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev)
{
if (test_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags)) {
- del_timer_sync(&ifx_dev->spi_timer);
+ del_timer(&ifx_dev->spi_timer);
clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
}
@@ -1001,6 +1091,14 @@ static int ifx_spi_spi_probe(struct spi_device *spi)
return -ENODEV;
}
+ /* init swap_buf function according to word width configuration */
+ if (spi->bits_per_word == 32)
+ ifx_dev->swap_buf = swap_buf_32;
+ else if (spi->bits_per_word == 16)
+ ifx_dev->swap_buf = swap_buf_16;
+ else
+ ifx_dev->swap_buf = swap_buf_8;
+
/* ensure SPI protocol flags are initialized to enable transfer */
ifx_dev->spi_more = 0;
ifx_dev->spi_slave_cts = 0;
@@ -1219,6 +1317,9 @@ static int ifx_spi_spi_remove(struct spi_device *spi)
static void ifx_spi_spi_shutdown(struct spi_device *spi)
{
+ struct ifx_spi_device *ifx_dev = spi_get_drvdata(spi);
+
+ ifx_modem_power_off(ifx_dev);
}
/*
@@ -1338,7 +1439,7 @@ static struct spi_driver ifx_spi_driver = {
.owner = THIS_MODULE},
.probe = ifx_spi_spi_probe,
.shutdown = ifx_spi_spi_shutdown,
- .remove = __devexit_p(ifx_spi_spi_remove),
+ .remove = ifx_spi_spi_remove,
.suspend = ifx_spi_spi_suspend,
.resume = ifx_spi_spi_resume,
.id_table = ifx_id_table
@@ -1354,7 +1455,9 @@ static void __exit ifx_spi_exit(void)
{
/* unregister */
tty_unregister_driver(tty_drv);
+ put_tty_driver(tty_drv);
spi_unregister_driver((void *)&ifx_spi_driver);
+ unregister_reboot_notifier(&ifx_modem_reboot_notifier_block);
}
/**
@@ -1389,16 +1492,31 @@ static int __init ifx_spi_init(void)
if (result) {
pr_err("%s: tty_register_driver failed(%d)",
DRVNAME, result);
- put_tty_driver(tty_drv);
- return result;
+ goto err_free_tty;
}
result = spi_register_driver((void *)&ifx_spi_driver);
if (result) {
pr_err("%s: spi_register_driver failed(%d)",
DRVNAME, result);
- tty_unregister_driver(tty_drv);
+ goto err_unreg_tty;
}
+
+ result = register_reboot_notifier(&ifx_modem_reboot_notifier_block);
+ if (result) {
+ pr_err("%s: register ifx modem reboot notifier failed(%d)",
+ DRVNAME, result);
+ goto err_unreg_spi;
+ }
+
+ return 0;
+err_unreg_spi:
+ spi_unregister_driver((void *)&ifx_spi_driver);
+err_unreg_tty:
+ tty_unregister_driver(tty_drv);
+err_free_tty:
+ put_tty_driver(tty_drv);
+
return result;
}
diff --git a/drivers/tty/serial/ifx6x60.h b/drivers/tty/serial/ifx6x60.h
index e8464baf9e7..4fbddc29783 100644
--- a/drivers/tty/serial/ifx6x60.h
+++ b/drivers/tty/serial/ifx6x60.h
@@ -41,6 +41,7 @@
#define IFX_SPI_STATE_IO_IN_PROGRESS 1
#define IFX_SPI_STATE_IO_READY 2
#define IFX_SPI_STATE_TIMER_PENDING 3
+#define IFX_SPI_STATE_IO_AVAILABLE 4
/* flow control bitfields */
#define IFX_SPI_DCD 0
@@ -124,6 +125,7 @@ struct ifx_spi_device {
#define MR_INPROGRESS 1
#define MR_COMPLETE 2
wait_queue_head_t mdm_reset_wait;
+ void (*swap_buf)(unsigned char *buf, int len, void *end);
};
#endif /* _IFX6X60_H */
diff --git a/drivers/tty/serial/ioc3_serial.c b/drivers/tty/serial/ioc3_serial.c
index 5ac52898a0b..d8f1d1d5447 100644
--- a/drivers/tty/serial/ioc3_serial.c
+++ b/drivers/tty/serial/ioc3_serial.c
@@ -2010,7 +2010,7 @@ static int ioc3uart_remove(struct ioc3_submodule *is,
* @idd: ioc3 driver data for this card
*/
-static int __devinit
+static int
ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
{
struct pci_dev *pdev = idd->pdev;
diff --git a/drivers/tty/serial/jsm/jsm.h b/drivers/tty/serial/jsm/jsm.h
index 529bec6edaf..844d5e4eb1a 100644
--- a/drivers/tty/serial/jsm/jsm.h
+++ b/drivers/tty/serial/jsm/jsm.h
@@ -57,9 +57,11 @@ enum {
DBG_CARR = 0x10000,
};
-#define jsm_printk(nlevel, klevel, pdev, fmt, args...) \
- if ((DBG_##nlevel & jsm_debug)) \
- dev_printk(KERN_##klevel, pdev->dev, fmt, ## args)
+#define jsm_dbg(nlevel, pdev, fmt, ...) \
+do { \
+ if (DBG_##nlevel & jsm_debug) \
+ dev_dbg(pdev->dev, fmt, ##__VA_ARGS__); \
+} while (0)
#define MAXLINES 256
#define MAXPORTS 8
diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c
index 5ab3c3b595e..a47d882d674 100644
--- a/drivers/tty/serial/jsm/jsm_driver.c
+++ b/drivers/tty/serial/jsm/jsm_driver.c
@@ -64,7 +64,7 @@ int jsm_debug;
module_param(jsm_debug, int, 0);
MODULE_PARM_DESC(jsm_debug, "Driver debugging level");
-static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int rc = 0;
struct jsm_board *brd;
@@ -107,8 +107,7 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device
brd->irq = pdev->irq;
- jsm_printk(INIT, INFO, &brd->pci_dev,
- "jsm_found_board - NEO adapter\n");
+ jsm_dbg(INIT, &brd->pci_dev, "jsm_found_board - NEO adapter\n");
/* get the PCI Base Address Registers */
brd->membase = pci_resource_start(pdev, 0);
@@ -179,7 +178,7 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device
return rc;
}
-static void __devexit jsm_remove_one(struct pci_dev *pdev)
+static void jsm_remove_one(struct pci_dev *pdev)
{
struct jsm_board *brd = pci_get_drvdata(pdev);
int i = 0;
@@ -218,7 +217,7 @@ static struct pci_driver jsm_driver = {
.name = "jsm",
.id_table = jsm_pci_tbl,
.probe = jsm_probe_one,
- .remove = __devexit_p(jsm_remove_one),
+ .remove = jsm_remove_one,
.err_handler = &jsm_err_handler,
};
diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c
index 81dfafa11b0..dfaf4882641 100644
--- a/drivers/tty/serial/jsm/jsm_neo.c
+++ b/drivers/tty/serial/jsm/jsm_neo.c
@@ -52,7 +52,7 @@ static void neo_set_cts_flow_control(struct jsm_channel *ch)
ier = readb(&ch->ch_neo_uart->ier);
efr = readb(&ch->ch_neo_uart->efr);
- jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting CTSFLOW\n");
+ jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Setting CTSFLOW\n");
/* Turn on auto CTS flow control */
ier |= (UART_17158_IER_CTSDSR);
@@ -83,7 +83,7 @@ static void neo_set_rts_flow_control(struct jsm_channel *ch)
ier = readb(&ch->ch_neo_uart->ier);
efr = readb(&ch->ch_neo_uart->efr);
- jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting RTSFLOW\n");
+ jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Setting RTSFLOW\n");
/* Turn on auto RTS flow control */
ier |= (UART_17158_IER_RTSDTR);
@@ -123,7 +123,7 @@ static void neo_set_ixon_flow_control(struct jsm_channel *ch)
ier = readb(&ch->ch_neo_uart->ier);
efr = readb(&ch->ch_neo_uart->efr);
- jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting IXON FLOW\n");
+ jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Setting IXON FLOW\n");
/* Turn off auto CTS flow control */
ier &= ~(UART_17158_IER_CTSDSR);
@@ -160,7 +160,7 @@ static void neo_set_ixoff_flow_control(struct jsm_channel *ch)
ier = readb(&ch->ch_neo_uart->ier);
efr = readb(&ch->ch_neo_uart->efr);
- jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting IXOFF FLOW\n");
+ jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Setting IXOFF FLOW\n");
/* Turn off auto RTS flow control */
ier &= ~(UART_17158_IER_RTSDTR);
@@ -198,7 +198,7 @@ static void neo_set_no_input_flow_control(struct jsm_channel *ch)
ier = readb(&ch->ch_neo_uart->ier);
efr = readb(&ch->ch_neo_uart->efr);
- jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Unsetting Input FLOW\n");
+ jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Unsetting Input FLOW\n");
/* Turn off auto RTS flow control */
ier &= ~(UART_17158_IER_RTSDTR);
@@ -237,7 +237,7 @@ static void neo_set_no_output_flow_control(struct jsm_channel *ch)
ier = readb(&ch->ch_neo_uart->ier);
efr = readb(&ch->ch_neo_uart->efr);
- jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Unsetting Output FLOW\n");
+ jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Unsetting Output FLOW\n");
/* Turn off auto CTS flow control */
ier &= ~(UART_17158_IER_CTSDSR);
@@ -276,7 +276,7 @@ static inline void neo_set_new_start_stop_chars(struct jsm_channel *ch)
if (ch->ch_c_cflag & CRTSCTS)
return;
- jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "start\n");
+ jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "start\n");
/* Tell UART what start/stop chars it should be looking for */
writeb(ch->ch_startc, &ch->ch_neo_uart->xonchar1);
@@ -455,7 +455,7 @@ static void neo_copy_data_from_uart_to_queue(struct jsm_channel *ch)
* I hope thats okay with everyone? Yes? Good.
*/
while (qleft < 1) {
- jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
+ jsm_dbg(READ, &ch->ch_bd->pci_dev,
"Queue full, dropping DATA:%x LSR:%x\n",
ch->ch_rqueue[tail], ch->ch_equeue[tail]);
@@ -467,8 +467,8 @@ static void neo_copy_data_from_uart_to_queue(struct jsm_channel *ch)
memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, 1);
ch->ch_equeue[head] = (u8) linestatus;
- jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
- "DATA/LSR pair: %x %x\n", ch->ch_rqueue[head], ch->ch_equeue[head]);
+ jsm_dbg(READ, &ch->ch_bd->pci_dev, "DATA/LSR pair: %x %x\n",
+ ch->ch_rqueue[head], ch->ch_equeue[head]);
/* Ditch any remaining linestatus value. */
linestatus = 0;
@@ -521,8 +521,8 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch)
ch->ch_cached_lsr &= ~(UART_LSR_THRE);
writeb(circ->buf[circ->tail], &ch->ch_neo_uart->txrx);
- jsm_printk(WRITE, INFO, &ch->ch_bd->pci_dev,
- "Tx data: %x\n", circ->buf[circ->tail]);
+ jsm_dbg(WRITE, &ch->ch_bd->pci_dev,
+ "Tx data: %x\n", circ->buf[circ->tail]);
circ->tail = (circ->tail + 1) & (UART_XMIT_SIZE - 1);
ch->ch_txcount++;
}
@@ -575,8 +575,9 @@ static void neo_parse_modem(struct jsm_channel *ch, u8 signals)
{
u8 msignals = signals;
- jsm_printk(MSIGS, INFO, &ch->ch_bd->pci_dev,
- "neo_parse_modem: port: %d msignals: %x\n", ch->ch_portnum, msignals);
+ jsm_dbg(MSIGS, &ch->ch_bd->pci_dev,
+ "neo_parse_modem: port: %d msignals: %x\n",
+ ch->ch_portnum, msignals);
/* Scrub off lower bits. They signify delta's, which I don't care about */
/* Keep DDCD and DDSR though */
@@ -606,8 +607,8 @@ static void neo_parse_modem(struct jsm_channel *ch, u8 signals)
else
ch->ch_mistat &= ~UART_MSR_CTS;
- jsm_printk(MSIGS, INFO, &ch->ch_bd->pci_dev,
- "Port: %d DTR: %d RTS: %d CTS: %d DSR: %d " "RI: %d CD: %d\n",
+ jsm_dbg(MSIGS, &ch->ch_bd->pci_dev,
+ "Port: %d DTR: %d RTS: %d CTS: %d DSR: %d " "RI: %d CD: %d\n",
ch->ch_portnum,
!!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_DTR),
!!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_RTS),
@@ -649,8 +650,8 @@ static void neo_flush_uart_write(struct jsm_channel *ch)
/* Check to see if the UART feels it completely flushed the FIFO. */
tmp = readb(&ch->ch_neo_uart->isr_fcr);
if (tmp & 4) {
- jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev,
- "Still flushing TX UART... i: %d\n", i);
+ jsm_dbg(IOCTL, &ch->ch_bd->pci_dev,
+ "Still flushing TX UART... i: %d\n", i);
udelay(10);
}
else
@@ -681,8 +682,8 @@ static void neo_flush_uart_read(struct jsm_channel *ch)
/* Check to see if the UART feels it completely flushed the FIFO. */
tmp = readb(&ch->ch_neo_uart->isr_fcr);
if (tmp & 2) {
- jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev,
- "Still flushing RX UART... i: %d\n", i);
+ jsm_dbg(IOCTL, &ch->ch_bd->pci_dev,
+ "Still flushing RX UART... i: %d\n", i);
udelay(10);
}
else
@@ -705,8 +706,9 @@ static void neo_clear_break(struct jsm_channel *ch, int force)
writeb((temp & ~UART_LCR_SBC), &ch->ch_neo_uart->lcr);
ch->ch_flags &= ~(CH_BREAK_SENDING);
- jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev,
- "clear break Finishing UART_LCR_SBC! finished: %lx\n", jiffies);
+ jsm_dbg(IOCTL, &ch->ch_bd->pci_dev,
+ "clear break Finishing UART_LCR_SBC! finished: %lx\n",
+ jiffies);
/* flush write operation */
neo_pci_posting_flush(ch->ch_bd);
@@ -748,8 +750,8 @@ static inline void neo_parse_isr(struct jsm_board *brd, u32 port)
*/
isr &= ~(UART_17158_IIR_FIFO_ENABLED);
- jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev,
- "%s:%d isr: %x\n", __FILE__, __LINE__, isr);
+ jsm_dbg(INTR, &ch->ch_bd->pci_dev, "%s:%d isr: %x\n",
+ __FILE__, __LINE__, isr);
if (isr & (UART_17158_IIR_RDI_TIMEOUT | UART_IIR_RDI)) {
/* Read data from uart -> queue */
@@ -772,8 +774,9 @@ static inline void neo_parse_isr(struct jsm_board *brd, u32 port)
if (isr & UART_17158_IIR_XONXOFF) {
cause = readb(&ch->ch_neo_uart->xoffchar1);
- jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev,
- "Port %d. Got ISR_XONXOFF: cause:%x\n", port, cause);
+ jsm_dbg(INTR, &ch->ch_bd->pci_dev,
+ "Port %d. Got ISR_XONXOFF: cause:%x\n",
+ port, cause);
/*
* Since the UART detected either an XON or
@@ -786,17 +789,19 @@ static inline void neo_parse_isr(struct jsm_board *brd, u32 port)
if (brd->channels[port]->ch_flags & CH_STOP) {
ch->ch_flags &= ~(CH_STOP);
}
- jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev,
- "Port %d. XON detected in incoming data\n", port);
+ jsm_dbg(INTR, &ch->ch_bd->pci_dev,
+ "Port %d. XON detected in incoming data\n",
+ port);
}
else if (cause == UART_17158_XOFF_DETECT) {
if (!(brd->channels[port]->ch_flags & CH_STOP)) {
ch->ch_flags |= CH_STOP;
- jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev,
- "Setting CH_STOP\n");
+ jsm_dbg(INTR, &ch->ch_bd->pci_dev,
+ "Setting CH_STOP\n");
}
- jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev,
- "Port: %d. XOFF detected in incoming data\n", port);
+ jsm_dbg(INTR, &ch->ch_bd->pci_dev,
+ "Port: %d. XOFF detected in incoming data\n",
+ port);
}
spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
}
@@ -825,8 +830,8 @@ static inline void neo_parse_isr(struct jsm_board *brd, u32 port)
}
/* Parse any modem signal changes */
- jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev,
- "MOD_STAT: sending to parse_modem_sigs\n");
+ jsm_dbg(INTR, &ch->ch_bd->pci_dev,
+ "MOD_STAT: sending to parse_modem_sigs\n");
neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr));
}
}
@@ -849,8 +854,8 @@ static inline void neo_parse_lsr(struct jsm_board *brd, u32 port)
linestatus = readb(&ch->ch_neo_uart->lsr);
- jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev,
- "%s:%d port: %d linestatus: %x\n", __FILE__, __LINE__, port, linestatus);
+ jsm_dbg(INTR, &ch->ch_bd->pci_dev, "%s:%d port: %d linestatus: %x\n",
+ __FILE__, __LINE__, port, linestatus);
ch->ch_cached_lsr |= linestatus;
@@ -869,7 +874,7 @@ static inline void neo_parse_lsr(struct jsm_board *brd, u32 port)
*to do the special RX+LSR read for this FIFO load.
*/
if (linestatus & UART_17158_RX_FIFO_DATA_ERROR)
- jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev,
+ jsm_dbg(INTR, &ch->ch_bd->pci_dev,
"%s:%d Port: %d Got an RX error, need to parse LSR\n",
__FILE__, __LINE__, port);
@@ -880,20 +885,21 @@ static inline void neo_parse_lsr(struct jsm_board *brd, u32 port)
if (linestatus & UART_LSR_PE) {
ch->ch_err_parity++;
- jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev,
- "%s:%d Port: %d. PAR ERR!\n", __FILE__, __LINE__, port);
+ jsm_dbg(INTR, &ch->ch_bd->pci_dev, "%s:%d Port: %d. PAR ERR!\n",
+ __FILE__, __LINE__, port);
}
if (linestatus & UART_LSR_FE) {
ch->ch_err_frame++;
- jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev,
- "%s:%d Port: %d. FRM ERR!\n", __FILE__, __LINE__, port);
+ jsm_dbg(INTR, &ch->ch_bd->pci_dev, "%s:%d Port: %d. FRM ERR!\n",
+ __FILE__, __LINE__, port);
}
if (linestatus & UART_LSR_BI) {
ch->ch_err_break++;
- jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev,
- "%s:%d Port: %d. BRK INTR!\n", __FILE__, __LINE__, port);
+ jsm_dbg(INTR, &ch->ch_bd->pci_dev,
+ "%s:%d Port: %d. BRK INTR!\n",
+ __FILE__, __LINE__, port);
}
if (linestatus & UART_LSR_OE) {
@@ -904,8 +910,9 @@ static inline void neo_parse_lsr(struct jsm_board *brd, u32 port)
* Probably we should eventually have an orun stat in our driver...
*/
ch->ch_err_overrun++;
- jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev,
- "%s:%d Port: %d. Rx Overrun!\n", __FILE__, __LINE__, port);
+ jsm_dbg(INTR, &ch->ch_bd->pci_dev,
+ "%s:%d Port: %d. Rx Overrun!\n",
+ __FILE__, __LINE__, port);
}
if (linestatus & UART_LSR_THRE) {
@@ -1128,11 +1135,11 @@ static irqreturn_t neo_intr(int irq, void *voidbrd)
*/
uart_poll = readl(brd->re_map_membase + UART_17158_POLL_ADDR_OFFSET);
- jsm_printk(INTR, INFO, &brd->pci_dev,
- "%s:%d uart_poll: %x\n", __FILE__, __LINE__, uart_poll);
+ jsm_dbg(INTR, &brd->pci_dev, "%s:%d uart_poll: %x\n",
+ __FILE__, __LINE__, uart_poll);
if (!uart_poll) {
- jsm_printk(INTR, INFO, &brd->pci_dev,
+ jsm_dbg(INTR, &brd->pci_dev,
"Kernel interrupted to me, but no pending interrupts...\n");
spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags);
return IRQ_NONE;
@@ -1158,15 +1165,15 @@ static irqreturn_t neo_intr(int irq, void *voidbrd)
continue;
}
- jsm_printk(INTR, INFO, &brd->pci_dev,
- "%s:%d port: %x type: %x\n", __FILE__, __LINE__, port, type);
+ jsm_dbg(INTR, &brd->pci_dev, "%s:%d port: %x type: %x\n",
+ __FILE__, __LINE__, port, type);
/* Remove this port + type from uart_poll */
uart_poll &= ~(jsm_offset_table[port]);
if (!type) {
/* If no type, just ignore it, and move onto next port */
- jsm_printk(INTR, ERR, &brd->pci_dev,
+ jsm_dbg(INTR, &brd->pci_dev,
"Interrupt with no type! port: %d\n", port);
continue;
}
@@ -1231,15 +1238,16 @@ static irqreturn_t neo_intr(int irq, void *voidbrd)
* these once and awhile.
* Its harmless, just ignore it and move on.
*/
- jsm_printk(INTR, ERR, &brd->pci_dev,
- "%s:%d Unknown Interrupt type: %x\n", __FILE__, __LINE__, type);
+ jsm_dbg(INTR, &brd->pci_dev,
+ "%s:%d Unknown Interrupt type: %x\n",
+ __FILE__, __LINE__, type);
continue;
}
}
spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags);
- jsm_printk(INTR, INFO, &brd->pci_dev, "finish.\n");
+ jsm_dbg(INTR, &brd->pci_dev, "finish\n");
return IRQ_HANDLED;
}
diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c
index 71397961773..4c00c5550b1 100644
--- a/drivers/tty/serial/jsm/jsm_tty.c
+++ b/drivers/tty/serial/jsm/jsm_tty.c
@@ -43,7 +43,7 @@ static inline int jsm_get_mstat(struct jsm_channel *ch)
unsigned char mstat;
unsigned result;
- jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "start\n");
+ jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "start\n");
mstat = (ch->ch_mostat | ch->ch_mistat);
@@ -62,7 +62,7 @@ static inline int jsm_get_mstat(struct jsm_channel *ch)
if (mstat & UART_MSR_DCD)
result |= TIOCM_CD;
- jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n");
+ jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "finish\n");
return result;
}
@@ -79,14 +79,14 @@ static unsigned int jsm_tty_get_mctrl(struct uart_port *port)
int result;
struct jsm_channel *channel = (struct jsm_channel *)port;
- jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n");
+ jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n");
result = jsm_get_mstat(channel);
if (result < 0)
return -ENXIO;
- jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n");
+ jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "finish\n");
return result;
}
@@ -100,7 +100,7 @@ static void jsm_tty_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
struct jsm_channel *channel = (struct jsm_channel *)port;
- jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n");
+ jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n");
if (mctrl & TIOCM_RTS)
channel->ch_mostat |= UART_MCR_RTS;
@@ -114,7 +114,7 @@ static void jsm_tty_set_mctrl(struct uart_port *port, unsigned int mctrl)
channel->ch_bd->bd_ops->assert_modem_signals(channel);
- jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n");
+ jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "finish\n");
udelay(10);
}
@@ -135,23 +135,23 @@ static void jsm_tty_start_tx(struct uart_port *port)
{
struct jsm_channel *channel = (struct jsm_channel *)port;
- jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n");
+ jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n");
channel->ch_flags &= ~(CH_STOP);
jsm_tty_write(port);
- jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n");
+ jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "finish\n");
}
static void jsm_tty_stop_tx(struct uart_port *port)
{
struct jsm_channel *channel = (struct jsm_channel *)port;
- jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n");
+ jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n");
channel->ch_flags |= (CH_STOP);
- jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n");
+ jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "finish\n");
}
static void jsm_tty_send_xchar(struct uart_port *port, char ch)
@@ -216,16 +216,16 @@ static int jsm_tty_open(struct uart_port *port)
if (!channel->ch_rqueue) {
channel->ch_rqueue = kzalloc(RQUEUESIZE, GFP_KERNEL);
if (!channel->ch_rqueue) {
- jsm_printk(INIT, ERR, &channel->ch_bd->pci_dev,
- "unable to allocate read queue buf");
+ jsm_dbg(INIT, &channel->ch_bd->pci_dev,
+ "unable to allocate read queue buf\n");
return -ENOMEM;
}
}
if (!channel->ch_equeue) {
channel->ch_equeue = kzalloc(EQUEUESIZE, GFP_KERNEL);
if (!channel->ch_equeue) {
- jsm_printk(INIT, ERR, &channel->ch_bd->pci_dev,
- "unable to allocate error queue buf");
+ jsm_dbg(INIT, &channel->ch_bd->pci_dev,
+ "unable to allocate error queue buf\n");
return -ENOMEM;
}
}
@@ -234,7 +234,7 @@ static int jsm_tty_open(struct uart_port *port)
/*
* Initialize if neither terminal is open.
*/
- jsm_printk(OPEN, INFO, &channel->ch_bd->pci_dev,
+ jsm_dbg(OPEN, &channel->ch_bd->pci_dev,
"jsm_open: initializing channel in open...\n");
/*
@@ -270,7 +270,7 @@ static int jsm_tty_open(struct uart_port *port)
channel->ch_open_count++;
- jsm_printk(OPEN, INFO, &channel->ch_bd->pci_dev, "finish\n");
+ jsm_dbg(OPEN, &channel->ch_bd->pci_dev, "finish\n");
return 0;
}
@@ -280,7 +280,7 @@ static void jsm_tty_close(struct uart_port *port)
struct ktermios *ts;
struct jsm_channel *channel = (struct jsm_channel *)port;
- jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n");
+ jsm_dbg(CLOSE, &channel->ch_bd->pci_dev, "start\n");
bd = channel->ch_bd;
ts = &port->state->port.tty->termios;
@@ -293,7 +293,7 @@ static void jsm_tty_close(struct uart_port *port)
* If we have HUPCL set, lower DTR and RTS
*/
if (channel->ch_c_cflag & HUPCL) {
- jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev,
+ jsm_dbg(CLOSE, &channel->ch_bd->pci_dev,
"Close. HUPCL set, dropping DTR/RTS\n");
/* Drop RTS/DTR */
@@ -304,7 +304,7 @@ static void jsm_tty_close(struct uart_port *port)
/* Turn off UART interrupts for this port */
channel->ch_bd->bd_ops->uart_off(channel);
- jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "finish\n");
+ jsm_dbg(CLOSE, &channel->ch_bd->pci_dev, "finish\n");
}
static void jsm_tty_set_termios(struct uart_port *port,
@@ -371,7 +371,7 @@ static struct uart_ops jsm_ops = {
* Init the tty subsystem. Called once per board after board has been
* downloaded and init'ed.
*/
-int __devinit jsm_tty_init(struct jsm_board *brd)
+int jsm_tty_init(struct jsm_board *brd)
{
int i;
void __iomem *vaddr;
@@ -380,7 +380,7 @@ int __devinit jsm_tty_init(struct jsm_board *brd)
if (!brd)
return -ENXIO;
- jsm_printk(INIT, INFO, &brd->pci_dev, "start\n");
+ jsm_dbg(INIT, &brd->pci_dev, "start\n");
/*
* Initialize board structure elements.
@@ -401,9 +401,9 @@ int __devinit jsm_tty_init(struct jsm_board *brd)
*/
brd->channels[i] = kzalloc(sizeof(struct jsm_channel), GFP_KERNEL);
if (!brd->channels[i]) {
- jsm_printk(CORE, ERR, &brd->pci_dev,
+ jsm_dbg(CORE, &brd->pci_dev,
"%s:%d Unable to allocate memory for channel struct\n",
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
}
}
}
@@ -431,7 +431,7 @@ int __devinit jsm_tty_init(struct jsm_board *brd)
init_waitqueue_head(&ch->ch_flags_wait);
}
- jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n");
+ jsm_dbg(INIT, &brd->pci_dev, "finish\n");
return 0;
}
@@ -444,7 +444,7 @@ int jsm_uart_port_init(struct jsm_board *brd)
if (!brd)
return -ENXIO;
- jsm_printk(INIT, INFO, &brd->pci_dev, "start\n");
+ jsm_dbg(INIT, &brd->pci_dev, "start\n");
/*
* Initialize board structure elements.
@@ -481,7 +481,7 @@ int jsm_uart_port_init(struct jsm_board *brd)
printk(KERN_INFO "jsm: Port %d added\n", i);
}
- jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n");
+ jsm_dbg(INIT, &brd->pci_dev, "finish\n");
return 0;
}
@@ -493,7 +493,7 @@ int jsm_remove_uart_port(struct jsm_board *brd)
if (!brd)
return -ENXIO;
- jsm_printk(INIT, INFO, &brd->pci_dev, "start\n");
+ jsm_dbg(INIT, &brd->pci_dev, "start\n");
/*
* Initialize board structure elements.
@@ -513,7 +513,7 @@ int jsm_remove_uart_port(struct jsm_board *brd)
uart_remove_one_port(&jsm_uart_driver, &brd->channels[i]->uart_port);
}
- jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n");
+ jsm_dbg(INIT, &brd->pci_dev, "finish\n");
return 0;
}
@@ -531,7 +531,7 @@ void jsm_input(struct jsm_channel *ch)
int s = 0;
int i = 0;
- jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start\n");
+ jsm_dbg(READ, &ch->ch_bd->pci_dev, "start\n");
if (!ch)
return;
@@ -560,7 +560,7 @@ void jsm_input(struct jsm_channel *ch)
return;
}
- jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start\n");
+ jsm_dbg(READ, &ch->ch_bd->pci_dev, "start\n");
/*
*If the device is not open, or CREAD is off, flush
@@ -569,8 +569,9 @@ void jsm_input(struct jsm_channel *ch)
if (!tp ||
!(tp->termios.c_cflag & CREAD) ) {
- jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
- "input. dropping %d bytes on port %d...\n", data_len, ch->ch_portnum);
+ jsm_dbg(READ, &ch->ch_bd->pci_dev,
+ "input. dropping %d bytes on port %d...\n",
+ data_len, ch->ch_portnum);
ch->ch_r_head = tail;
/* Force queue flow control to be released, if needed */
@@ -585,17 +586,17 @@ void jsm_input(struct jsm_channel *ch)
*/
if (ch->ch_flags & CH_STOPI) {
spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
- jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
+ jsm_dbg(READ, &ch->ch_bd->pci_dev,
"Port %d throttled, not reading any data. head: %x tail: %x\n",
ch->ch_portnum, head, tail);
return;
}
- jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start 2\n");
+ jsm_dbg(READ, &ch->ch_bd->pci_dev, "start 2\n");
if (data_len <= 0) {
spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
- jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n");
+ jsm_dbg(READ, &ch->ch_bd->pci_dev, "jsm_input 1\n");
return;
}
@@ -653,7 +654,7 @@ void jsm_input(struct jsm_channel *ch)
/* Tell the tty layer its okay to "eat" the data now */
tty_flip_buffer_push(tp);
- jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n");
+ jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "finish\n");
}
static void jsm_carrier(struct jsm_channel *ch)
@@ -663,7 +664,7 @@ static void jsm_carrier(struct jsm_channel *ch)
int virt_carrier = 0;
int phys_carrier = 0;
- jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev, "start\n");
+ jsm_dbg(CARR, &ch->ch_bd->pci_dev, "start\n");
if (!ch)
return;
@@ -673,16 +674,16 @@ static void jsm_carrier(struct jsm_channel *ch)
return;
if (ch->ch_mistat & UART_MSR_DCD) {
- jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev,
- "mistat: %x D_CD: %x\n", ch->ch_mistat, ch->ch_mistat & UART_MSR_DCD);
+ jsm_dbg(CARR, &ch->ch_bd->pci_dev, "mistat: %x D_CD: %x\n",
+ ch->ch_mistat, ch->ch_mistat & UART_MSR_DCD);
phys_carrier = 1;
}
if (ch->ch_c_cflag & CLOCAL)
virt_carrier = 1;
- jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev,
- "DCD: physical: %d virt: %d\n", phys_carrier, virt_carrier);
+ jsm_dbg(CARR, &ch->ch_bd->pci_dev, "DCD: physical: %d virt: %d\n",
+ phys_carrier, virt_carrier);
/*
* Test for a VIRTUAL carrier transition to HIGH.
@@ -694,8 +695,7 @@ static void jsm_carrier(struct jsm_channel *ch)
* for carrier in the open routine.
*/
- jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev,
- "carrier: virt DCD rose\n");
+ jsm_dbg(CARR, &ch->ch_bd->pci_dev, "carrier: virt DCD rose\n");
if (waitqueue_active(&(ch->ch_flags_wait)))
wake_up_interruptible(&ch->ch_flags_wait);
@@ -711,7 +711,7 @@ static void jsm_carrier(struct jsm_channel *ch)
* for carrier in the open routine.
*/
- jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev,
+ jsm_dbg(CARR, &ch->ch_bd->pci_dev,
"carrier: physical DCD rose\n");
if (waitqueue_active(&(ch->ch_flags_wait)))
@@ -790,8 +790,8 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
if(!(ch->ch_flags & CH_RECEIVER_OFF)) {
bd_ops->disable_receiver(ch);
ch->ch_flags |= (CH_RECEIVER_OFF);
- jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
- "Internal queue hit hilevel mark (%d)! Turning off interrupts.\n",
+ jsm_dbg(READ, &ch->ch_bd->pci_dev,
+ "Internal queue hit hilevel mark (%d)! Turning off interrupts\n",
qleft);
}
}
@@ -800,8 +800,9 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
if (ch->ch_stops_sent <= MAX_STOPS_SENT) {
bd_ops->send_stop_character(ch);
ch->ch_stops_sent++;
- jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
- "Sending stop char! Times sent: %x\n", ch->ch_stops_sent);
+ jsm_dbg(READ, &ch->ch_bd->pci_dev,
+ "Sending stop char! Times sent: %x\n",
+ ch->ch_stops_sent);
}
}
}
@@ -827,8 +828,8 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
if (ch->ch_flags & CH_RECEIVER_OFF) {
bd_ops->enable_receiver(ch);
ch->ch_flags &= ~(CH_RECEIVER_OFF);
- jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
- "Internal queue hit lowlevel mark (%d)! Turning on interrupts.\n",
+ jsm_dbg(READ, &ch->ch_bd->pci_dev,
+ "Internal queue hit lowlevel mark (%d)! Turning on interrupts\n",
qleft);
}
}
@@ -836,7 +837,8 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) {
ch->ch_stops_sent = 0;
bd_ops->send_start_character(ch);
- jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Sending start char!\n");
+ jsm_dbg(READ, &ch->ch_bd->pci_dev,
+ "Sending start char!\n");
}
}
}
diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c
index d185247ba1a..6ac2b797a76 100644
--- a/drivers/tty/serial/kgdb_nmi.c
+++ b/drivers/tty/serial/kgdb_nmi.c
@@ -266,6 +266,7 @@ static int kgdb_nmi_tty_install(struct tty_driver *drv, struct tty_struct *tty)
}
return 0;
err:
+ tty_port_destroy(&priv->port);
kfree(priv);
return ret;
}
@@ -275,6 +276,7 @@ static void kgdb_nmi_tty_cleanup(struct tty_struct *tty)
struct kgdb_nmi_tty_priv *priv = tty->driver_data;
tty->driver_data = NULL;
+ tty_port_destroy(&priv->port);
kfree(priv);
}
diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c
index ba3af3bf6d4..0e86bff3fe2 100644
--- a/drivers/tty/serial/lpc32xx_hs.c
+++ b/drivers/tty/serial/lpc32xx_hs.c
@@ -686,7 +686,7 @@ static struct uart_ops serial_lpc32xx_pops = {
/*
* Register a set of serial devices attached to a platform device
*/
-static int __devinit serial_hs_lpc32xx_probe(struct platform_device *pdev)
+static int serial_hs_lpc32xx_probe(struct platform_device *pdev)
{
struct lpc32xx_hsuart_port *p = &lpc32xx_hs_ports[uarts_registered];
int ret = 0;
@@ -740,7 +740,7 @@ static int __devinit serial_hs_lpc32xx_probe(struct platform_device *pdev)
/*
* Remove serial ports registered against a platform device.
*/
-static int __devexit serial_hs_lpc32xx_remove(struct platform_device *pdev)
+static int serial_hs_lpc32xx_remove(struct platform_device *pdev)
{
struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev);
@@ -783,7 +783,7 @@ MODULE_DEVICE_TABLE(of, serial_hs_lpc32xx_dt_ids);
static struct platform_driver serial_hs_lpc32xx_driver = {
.probe = serial_hs_lpc32xx_probe,
- .remove = __devexit_p(serial_hs_lpc32xx_remove),
+ .remove = serial_hs_lpc32xx_remove,
.suspend = serial_hs_lpc32xx_suspend,
.resume = serial_hs_lpc32xx_resume,
.driver = {
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c
index 0f24486be53..7ce3197087b 100644
--- a/drivers/tty/serial/max3100.c
+++ b/drivers/tty/serial/max3100.c
@@ -742,7 +742,7 @@ static struct uart_driver max3100_uart_driver = {
};
static int uart_driver_registered;
-static int __devinit max3100_probe(struct spi_device *spi)
+static int max3100_probe(struct spi_device *spi)
{
int i, retval;
struct plat_max3100 *pdata;
@@ -818,7 +818,7 @@ static int __devinit max3100_probe(struct spi_device *spi)
return 0;
}
-static int __devexit max3100_remove(struct spi_device *spi)
+static int max3100_remove(struct spi_device *spi)
{
struct max3100_port *s = dev_get_drvdata(&spi->dev);
int i;
@@ -907,7 +907,7 @@ static struct spi_driver max3100_driver = {
},
.probe = max3100_probe,
- .remove = __devexit_p(max3100_remove),
+ .remove = max3100_remove,
.suspend = max3100_suspend,
.resume = max3100_resume,
};
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index 2bc28a59d38..a801f6872ca 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -378,7 +378,7 @@ static void max310x_wait_pll(struct max310x_port *s)
}
}
-static int __devinit max310x_update_best_err(unsigned long f, long *besterr)
+static int max310x_update_best_err(unsigned long f, long *besterr)
{
/* Use baudrate 115200 for calculate error */
long err = f % (115200 * 16);
@@ -391,7 +391,7 @@ static int __devinit max310x_update_best_err(unsigned long f, long *besterr)
return 1;
}
-static int __devinit max310x_set_ref_clk(struct max310x_port *s)
+static int max310x_set_ref_clk(struct max310x_port *s)
{
unsigned int div, clksrc, pllcfg = 0;
long besterr = -1;
@@ -995,7 +995,7 @@ static struct max310x_pdata generic_plat_data = {
.frequency = 26000000,
};
-static int __devinit max310x_probe(struct spi_device *spi)
+static int max310x_probe(struct spi_device *spi)
{
struct max310x_port *s;
struct device *dev = &spi->dev;
@@ -1178,6 +1178,7 @@ static int __devinit max310x_probe(struct spi_device *spi)
s->gpio.set = max310x_gpio_set;
s->gpio.base = pdata->gpio_base;
s->gpio.ngpio = s->nr_gpio;
+ s->gpio.can_sleep = 1;
if (gpiochip_add(&s->gpio)) {
/* Indicate that we should not call gpiochip_remove */
s->gpio.base = 0;
@@ -1202,7 +1203,7 @@ err_out:
return ret;
}
-static int __devexit max310x_remove(struct spi_device *spi)
+static int max310x_remove(struct spi_device *spi)
{
struct device *dev = &spi->dev;
struct max310x_port *s = dev_get_drvdata(dev);
@@ -1239,6 +1240,7 @@ static int __devexit max310x_remove(struct spi_device *spi)
static const struct spi_device_id max310x_id_table[] = {
{ "max3107", MAX310X_TYPE_MAX3107 },
{ "max3108", MAX310X_TYPE_MAX3108 },
+ { }
};
MODULE_DEVICE_TABLE(spi, max310x_id_table);
@@ -1248,7 +1250,7 @@ static struct spi_driver max310x_driver = {
.owner = THIS_MODULE,
},
.probe = max310x_probe,
- .remove = __devexit_p(max310x_remove),
+ .remove = max310x_remove,
.suspend = max310x_suspend,
.resume = max310x_resume,
.id_table = max310x_id_table,
diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c
index 9afca093d6e..fcd56ab6053 100644
--- a/drivers/tty/serial/mcf.c
+++ b/drivers/tty/serial/mcf.c
@@ -571,7 +571,7 @@ static struct uart_driver mcf_driver = {
/****************************************************************************/
-static int __devinit mcf_probe(struct platform_device *pdev)
+static int mcf_probe(struct platform_device *pdev)
{
struct mcf_platform_uart *platp = pdev->dev.platform_data;
struct uart_port *port;
@@ -599,7 +599,7 @@ static int __devinit mcf_probe(struct platform_device *pdev)
/****************************************************************************/
-static int __devexit mcf_remove(struct platform_device *pdev)
+static int mcf_remove(struct platform_device *pdev)
{
struct uart_port *port;
int i;
@@ -617,7 +617,7 @@ static int __devexit mcf_remove(struct platform_device *pdev)
static struct platform_driver mcf_platform_driver = {
.probe = mcf_probe,
- .remove = __devexit_p(mcf_remove),
+ .remove = mcf_remove,
.driver = {
.name = "mcfuart",
.owner = THIS_MODULE,
diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c
index c4b50af46c4..2c01344dc33 100644
--- a/drivers/tty/serial/mfd.c
+++ b/drivers/tty/serial/mfd.c
@@ -36,6 +36,7 @@
#include <linux/serial_mfd.h>
#include <linux/dma-mapping.h>
#include <linux/pci.h>
+#include <linux/nmi.h>
#include <linux/io.h>
#include <linux/debugfs.h>
#include <linux/pm_runtime.h>
@@ -1113,6 +1114,8 @@ serial_hsu_console_write(struct console *co, const char *s, unsigned int count)
unsigned int ier;
int locked = 1;
+ touch_nmi_watchdog();
+
local_irq_save(flags);
if (up->port.sysrq)
locked = 0;
@@ -1456,7 +1459,7 @@ static void serial_hsu_remove(struct pci_dev *pdev)
}
/* First 3 are UART ports, and the 4th is the DMA */
-static const struct pci_device_id pci_ids[] __devinitconst = {
+static const struct pci_device_id pci_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081B) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081C) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081D) },
@@ -1468,7 +1471,7 @@ static struct pci_driver hsu_pci_driver = {
.name = "HSU serial",
.id_table = pci_ids,
.probe = serial_hsu_probe,
- .remove = __devexit_p(serial_hsu_remove),
+ .remove = serial_hsu_remove,
.suspend = serial_hsu_suspend,
.resume = serial_hsu_resume,
.driver = {
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c
index 8cf577008ad..7c23c4f4c58 100644
--- a/drivers/tty/serial/mpc52xx_uart.c
+++ b/drivers/tty/serial/mpc52xx_uart.c
@@ -1308,7 +1308,7 @@ static struct of_device_id mpc52xx_uart_of_match[] = {
{},
};
-static int __devinit mpc52xx_uart_of_probe(struct platform_device *op)
+static int mpc52xx_uart_of_probe(struct platform_device *op)
{
int idx = -1;
unsigned int uartclk;
diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c
index df2a2240a3a..58734d7e746 100644
--- a/drivers/tty/serial/mrst_max3110.c
+++ b/drivers/tty/serial/mrst_max3110.c
@@ -773,7 +773,7 @@ static int serial_m3110_resume(struct spi_device *spi)
#define serial_m3110_resume NULL
#endif
-static int __devinit serial_m3110_probe(struct spi_device *spi)
+static int serial_m3110_probe(struct spi_device *spi)
{
struct uart_max3110 *max;
void *buffer;
@@ -855,7 +855,7 @@ err_get_page:
return ret;
}
-static int __devexit serial_m3110_remove(struct spi_device *dev)
+static int serial_m3110_remove(struct spi_device *dev)
{
struct uart_max3110 *max = spi_get_drvdata(dev);
@@ -879,7 +879,7 @@ static struct spi_driver uart_max3110_driver = {
.owner = THIS_MODULE,
},
.probe = serial_m3110_probe,
- .remove = __devexit_p(serial_m3110_remove),
+ .remove = serial_m3110_remove,
.suspend = serial_m3110_suspend,
.resume = serial_m3110_resume,
};
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index 033e0bc9eba..95fd39be293 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -917,7 +917,7 @@ static int __init msm_serial_probe(struct platform_device *pdev)
return uart_add_one_port(&msm_uart_driver, port);
}
-static int __devexit msm_serial_remove(struct platform_device *pdev)
+static int msm_serial_remove(struct platform_device *pdev)
{
struct msm_port *msm_port = platform_get_drvdata(pdev);
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index fca13dc73e2..1fa92284ade 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -401,7 +401,7 @@ static int msm_hs_request_port(struct uart_port *port)
return 0;
}
-static int __devexit msm_hs_remove(struct platform_device *pdev)
+static int msm_hs_remove(struct platform_device *pdev)
{
struct msm_hs_port *msm_uport;
@@ -1521,7 +1521,7 @@ err_msm_hs_init_clk:
}
/* Initialize tx and rx data structures */
-static int __devinit uartdm_init_port(struct uart_port *uport)
+static int uartdm_init_port(struct uart_port *uport)
{
int ret = 0;
struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
@@ -1614,7 +1614,7 @@ err_tx_command_ptr_ptr:
return ret;
}
-static int __devinit msm_hs_probe(struct platform_device *pdev)
+static int msm_hs_probe(struct platform_device *pdev)
{
int ret;
struct uart_port *uport;
@@ -1838,7 +1838,7 @@ static const struct dev_pm_ops msm_hs_dev_pm_ops = {
static struct platform_driver msm_serial_hs_platform_driver = {
.probe = msm_hs_probe,
- .remove = __devexit_p(msm_hs_remove),
+ .remove = msm_hs_remove,
.driver = {
.name = "msm_serial_hs",
.owner = THIS_MODULE,
diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c
index 7ea8a263fd9..e2775b6df5a 100644
--- a/drivers/tty/serial/mux.c
+++ b/drivers/tty/serial/mux.c
@@ -520,7 +520,7 @@ static int __init mux_probe(struct parisc_device *dev)
return 0;
}
-static int __devexit mux_remove(struct parisc_device *dev)
+static int mux_remove(struct parisc_device *dev)
{
int i, j;
int port_count = (long)dev_get_drvdata(&dev->dev);
@@ -571,14 +571,14 @@ static struct parisc_driver builtin_serial_mux_driver = {
.name = "builtin_serial_mux",
.id_table = builtin_mux_tbl,
.probe = mux_probe,
- .remove = __devexit_p(mux_remove),
+ .remove = mux_remove,
};
static struct parisc_driver serial_mux_driver = {
.name = "serial_mux",
.id_table = mux_tbl,
.probe = mux_probe,
- .remove = __devexit_p(mux_remove),
+ .remove = mux_remove,
};
/**
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index 6db3baa39a9..6db23b035ef 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -34,6 +34,8 @@
#include <linux/io.h>
#include <linux/pinctrl/consumer.h>
#include <linux/of_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/fsl/mxs-dma.h>
#include <asm/cacheflush.h>
@@ -71,6 +73,15 @@
#define AUART_CTRL0_SFTRST (1 << 31)
#define AUART_CTRL0_CLKGATE (1 << 30)
+#define AUART_CTRL0_RXTO_ENABLE (1 << 27)
+#define AUART_CTRL0_RXTIMEOUT(v) (((v) & 0x7ff) << 16)
+#define AUART_CTRL0_XFER_COUNT(v) ((v) & 0xffff)
+
+#define AUART_CTRL1_XFER_COUNT(v) ((v) & 0xffff)
+
+#define AUART_CTRL2_DMAONERR (1 << 26)
+#define AUART_CTRL2_TXDMAE (1 << 25)
+#define AUART_CTRL2_RXDMAE (1 << 24)
#define AUART_CTRL2_CTSEN (1 << 15)
#define AUART_CTRL2_RTSEN (1 << 14)
@@ -111,29 +122,170 @@
#define AUART_STAT_BERR (1 << 18)
#define AUART_STAT_PERR (1 << 17)
#define AUART_STAT_FERR (1 << 16)
+#define AUART_STAT_RXCOUNT_MASK 0xffff
static struct uart_driver auart_driver;
+enum mxs_auart_type {
+ IMX23_AUART,
+ IMX28_AUART,
+};
+
struct mxs_auart_port {
struct uart_port port;
- unsigned int flags;
+#define MXS_AUART_DMA_CONFIG 0x1
+#define MXS_AUART_DMA_ENABLED 0x2
+#define MXS_AUART_DMA_TX_SYNC 2 /* bit 2 */
+#define MXS_AUART_DMA_RX_READY 3 /* bit 3 */
+ unsigned long flags;
unsigned int ctrl;
+ enum mxs_auart_type devtype;
unsigned int irq;
struct clk *clk;
struct device *dev;
+
+ /* for DMA */
+ struct mxs_dma_data dma_data;
+ int dma_channel_rx, dma_channel_tx;
+ int dma_irq_rx, dma_irq_tx;
+ int dma_channel;
+
+ struct scatterlist tx_sgl;
+ struct dma_chan *tx_dma_chan;
+ void *tx_dma_buf;
+
+ struct scatterlist rx_sgl;
+ struct dma_chan *rx_dma_chan;
+ void *rx_dma_buf;
+};
+
+static struct platform_device_id mxs_auart_devtype[] = {
+ { .name = "mxs-auart-imx23", .driver_data = IMX23_AUART },
+ { .name = "mxs-auart-imx28", .driver_data = IMX28_AUART },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, mxs_auart_devtype);
+
+static struct of_device_id mxs_auart_dt_ids[] = {
+ {
+ .compatible = "fsl,imx28-auart",
+ .data = &mxs_auart_devtype[IMX28_AUART]
+ }, {
+ .compatible = "fsl,imx23-auart",
+ .data = &mxs_auart_devtype[IMX23_AUART]
+ }, { /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids);
+
+static inline int is_imx28_auart(struct mxs_auart_port *s)
+{
+ return s->devtype == IMX28_AUART;
+}
+
+static inline bool auart_dma_enabled(struct mxs_auart_port *s)
+{
+ return s->flags & MXS_AUART_DMA_ENABLED;
+}
static void mxs_auart_stop_tx(struct uart_port *u);
#define to_auart_port(u) container_of(u, struct mxs_auart_port, port)
-static inline void mxs_auart_tx_chars(struct mxs_auart_port *s)
+static void mxs_auart_tx_chars(struct mxs_auart_port *s);
+
+static void dma_tx_callback(void *param)
{
+ struct mxs_auart_port *s = param;
struct circ_buf *xmit = &s->port.state->xmit;
+ dma_unmap_sg(s->dev, &s->tx_sgl, 1, DMA_TO_DEVICE);
+
+ /* clear the bit used to serialize the DMA tx. */
+ clear_bit(MXS_AUART_DMA_TX_SYNC, &s->flags);
+ smp_mb__after_clear_bit();
+
+ /* wake up the possible processes. */
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&s->port);
+
+ mxs_auart_tx_chars(s);
+}
+
+static int mxs_auart_dma_tx(struct mxs_auart_port *s, int size)
+{
+ struct dma_async_tx_descriptor *desc;
+ struct scatterlist *sgl = &s->tx_sgl;
+ struct dma_chan *channel = s->tx_dma_chan;
+ u32 pio;
+
+ /* [1] : send PIO. Note, the first pio word is CTRL1. */
+ pio = AUART_CTRL1_XFER_COUNT(size);
+ desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)&pio,
+ 1, DMA_TRANS_NONE, 0);
+ if (!desc) {
+ dev_err(s->dev, "step 1 error\n");
+ return -EINVAL;
+ }
+
+ /* [2] : set DMA buffer. */
+ sg_init_one(sgl, s->tx_dma_buf, size);
+ dma_map_sg(s->dev, sgl, 1, DMA_TO_DEVICE);
+ desc = dmaengine_prep_slave_sg(channel, sgl,
+ 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+ dev_err(s->dev, "step 2 error\n");
+ return -EINVAL;
+ }
+
+ /* [3] : submit the DMA */
+ desc->callback = dma_tx_callback;
+ desc->callback_param = s;
+ dmaengine_submit(desc);
+ dma_async_issue_pending(channel);
+ return 0;
+}
+
+static void mxs_auart_tx_chars(struct mxs_auart_port *s)
+{
+ struct circ_buf *xmit = &s->port.state->xmit;
+
+ if (auart_dma_enabled(s)) {
+ int i = 0;
+ int size;
+ void *buffer = s->tx_dma_buf;
+
+ if (test_and_set_bit(MXS_AUART_DMA_TX_SYNC, &s->flags))
+ return;
+
+ while (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) {
+ size = min_t(u32, UART_XMIT_SIZE - i,
+ CIRC_CNT_TO_END(xmit->head,
+ xmit->tail,
+ UART_XMIT_SIZE));
+ memcpy(buffer + i, xmit->buf + xmit->tail, size);
+ xmit->tail = (xmit->tail + size) & (UART_XMIT_SIZE - 1);
+
+ i += size;
+ if (i >= UART_XMIT_SIZE)
+ break;
+ }
+
+ if (uart_tx_stopped(&s->port))
+ mxs_auart_stop_tx(&s->port);
+
+ if (i) {
+ mxs_auart_dma_tx(s, i);
+ } else {
+ clear_bit(MXS_AUART_DMA_TX_SYNC, &s->flags);
+ smp_mb__after_clear_bit();
+ }
+ return;
+ }
+
+
while (!(readl(s->port.membase + AUART_STAT) &
AUART_STAT_TXFF)) {
if (s->port.x_char) {
@@ -287,10 +439,159 @@ static u32 mxs_auart_get_mctrl(struct uart_port *u)
return mctrl;
}
+static bool mxs_auart_dma_filter(struct dma_chan *chan, void *param)
+{
+ struct mxs_auart_port *s = param;
+
+ if (!mxs_dma_is_apbx(chan))
+ return false;
+
+ if (s->dma_channel == chan->chan_id) {
+ chan->private = &s->dma_data;
+ return true;
+ }
+ return false;
+}
+
+static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s);
+static void dma_rx_callback(void *arg)
+{
+ struct mxs_auart_port *s = (struct mxs_auart_port *) arg;
+ struct tty_struct *tty = s->port.state->port.tty;
+ int count;
+ u32 stat;
+
+ dma_unmap_sg(s->dev, &s->rx_sgl, 1, DMA_FROM_DEVICE);
+
+ stat = readl(s->port.membase + AUART_STAT);
+ stat &= ~(AUART_STAT_OERR | AUART_STAT_BERR |
+ AUART_STAT_PERR | AUART_STAT_FERR);
+
+ count = stat & AUART_STAT_RXCOUNT_MASK;
+ tty_insert_flip_string(tty, s->rx_dma_buf, count);
+
+ writel(stat, s->port.membase + AUART_STAT);
+ tty_flip_buffer_push(tty);
+
+ /* start the next DMA for RX. */
+ mxs_auart_dma_prep_rx(s);
+}
+
+static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s)
+{
+ struct dma_async_tx_descriptor *desc;
+ struct scatterlist *sgl = &s->rx_sgl;
+ struct dma_chan *channel = s->rx_dma_chan;
+ u32 pio[1];
+
+ /* [1] : send PIO */
+ pio[0] = AUART_CTRL0_RXTO_ENABLE
+ | AUART_CTRL0_RXTIMEOUT(0x80)
+ | AUART_CTRL0_XFER_COUNT(UART_XMIT_SIZE);
+ desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio,
+ 1, DMA_TRANS_NONE, 0);
+ if (!desc) {
+ dev_err(s->dev, "step 1 error\n");
+ return -EINVAL;
+ }
+
+ /* [2] : send DMA request */
+ sg_init_one(sgl, s->rx_dma_buf, UART_XMIT_SIZE);
+ dma_map_sg(s->dev, sgl, 1, DMA_FROM_DEVICE);
+ desc = dmaengine_prep_slave_sg(channel, sgl, 1, DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+ dev_err(s->dev, "step 2 error\n");
+ return -1;
+ }
+
+ /* [3] : submit the DMA, but do not issue it. */
+ desc->callback = dma_rx_callback;
+ desc->callback_param = s;
+ dmaengine_submit(desc);
+ dma_async_issue_pending(channel);
+ return 0;
+}
+
+static void mxs_auart_dma_exit_channel(struct mxs_auart_port *s)
+{
+ if (s->tx_dma_chan) {
+ dma_release_channel(s->tx_dma_chan);
+ s->tx_dma_chan = NULL;
+ }
+ if (s->rx_dma_chan) {
+ dma_release_channel(s->rx_dma_chan);
+ s->rx_dma_chan = NULL;
+ }
+
+ kfree(s->tx_dma_buf);
+ kfree(s->rx_dma_buf);
+ s->tx_dma_buf = NULL;
+ s->rx_dma_buf = NULL;
+}
+
+static void mxs_auart_dma_exit(struct mxs_auart_port *s)
+{
+
+ writel(AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE | AUART_CTRL2_DMAONERR,
+ s->port.membase + AUART_CTRL2_CLR);
+
+ mxs_auart_dma_exit_channel(s);
+ s->flags &= ~MXS_AUART_DMA_ENABLED;
+ clear_bit(MXS_AUART_DMA_TX_SYNC, &s->flags);
+ clear_bit(MXS_AUART_DMA_RX_READY, &s->flags);
+}
+
+static int mxs_auart_dma_init(struct mxs_auart_port *s)
+{
+ dma_cap_mask_t mask;
+
+ if (auart_dma_enabled(s))
+ return 0;
+
+ /* We do not get the right DMA channels. */
+ if (s->dma_channel_rx == -1 || s->dma_channel_rx == -1)
+ return -EINVAL;
+
+ /* init for RX */
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ s->dma_channel = s->dma_channel_rx;
+ s->dma_data.chan_irq = s->dma_irq_rx;
+ s->rx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s);
+ if (!s->rx_dma_chan)
+ goto err_out;
+ s->rx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA);
+ if (!s->rx_dma_buf)
+ goto err_out;
+
+ /* init for TX */
+ s->dma_channel = s->dma_channel_tx;
+ s->dma_data.chan_irq = s->dma_irq_tx;
+ s->tx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s);
+ if (!s->tx_dma_chan)
+ goto err_out;
+ s->tx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA);
+ if (!s->tx_dma_buf)
+ goto err_out;
+
+ /* set the flags */
+ s->flags |= MXS_AUART_DMA_ENABLED;
+ dev_dbg(s->dev, "enabled the DMA support.");
+
+ return 0;
+
+err_out:
+ mxs_auart_dma_exit_channel(s);
+ return -EINVAL;
+
+}
+
static void mxs_auart_settermios(struct uart_port *u,
struct ktermios *termios,
struct ktermios *old)
{
+ struct mxs_auart_port *s = to_auart_port(u);
u32 bm, ctrl, ctrl2, div;
unsigned int cflag, baud;
@@ -362,10 +663,23 @@ static void mxs_auart_settermios(struct uart_port *u,
ctrl |= AUART_LINECTRL_STP2;
/* figure out the hardware flow control settings */
- if (cflag & CRTSCTS)
+ if (cflag & CRTSCTS) {
+ /*
+ * The DMA has a bug(see errata:2836) in mx23.
+ * So we can not implement the DMA for auart in mx23,
+ * we can only implement the DMA support for auart
+ * in mx28.
+ */
+ if (is_imx28_auart(s) && (s->flags & MXS_AUART_DMA_CONFIG)) {
+ if (!mxs_auart_dma_init(s))
+ /* enable DMA tranfer */
+ ctrl2 |= AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE
+ | AUART_CTRL2_DMAONERR;
+ }
ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN;
- else
+ } else {
ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN);
+ }
/* set baud rate */
baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk);
@@ -377,6 +691,19 @@ static void mxs_auart_settermios(struct uart_port *u,
writel(ctrl2, u->membase + AUART_CTRL2);
uart_update_timeout(u, termios->c_cflag, baud);
+
+ /* prepare for the DMA RX. */
+ if (auart_dma_enabled(s) &&
+ !test_and_set_bit(MXS_AUART_DMA_RX_READY, &s->flags)) {
+ if (!mxs_auart_dma_prep_rx(s)) {
+ /* Disable the normal RX interrupt. */
+ writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN,
+ u->membase + AUART_INTR_CLR);
+ } else {
+ mxs_auart_dma_exit(s);
+ dev_err(s->dev, "We can not start up the DMA.\n");
+ }
+ }
}
static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
@@ -395,7 +722,8 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
}
if (istat & (AUART_INTR_RTIS | AUART_INTR_RXIS)) {
- mxs_auart_rx_chars(s);
+ if (!auart_dma_enabled(s))
+ mxs_auart_rx_chars(s);
istat &= ~(AUART_INTR_RTIS | AUART_INTR_RXIS);
}
@@ -455,6 +783,9 @@ static void mxs_auart_shutdown(struct uart_port *u)
{
struct mxs_auart_port *s = to_auart_port(u);
+ if (auart_dma_enabled(s))
+ mxs_auart_dma_exit(s);
+
writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR);
writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
@@ -688,6 +1019,7 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,
struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
+ u32 dma_channel[2];
int ret;
if (!np)
@@ -701,11 +1033,27 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,
}
s->port.line = ret;
+ s->dma_irq_rx = platform_get_irq(pdev, 1);
+ s->dma_irq_tx = platform_get_irq(pdev, 2);
+
+ ret = of_property_read_u32_array(np, "fsl,auart-dma-channel",
+ dma_channel, 2);
+ if (ret == 0) {
+ s->dma_channel_rx = dma_channel[0];
+ s->dma_channel_tx = dma_channel[1];
+
+ s->flags |= MXS_AUART_DMA_CONFIG;
+ } else {
+ s->dma_channel_rx = -1;
+ s->dma_channel_tx = -1;
+ }
return 0;
}
-static int __devinit mxs_auart_probe(struct platform_device *pdev)
+static int mxs_auart_probe(struct platform_device *pdev)
{
+ const struct of_device_id *of_id =
+ of_match_device(mxs_auart_dt_ids, &pdev->dev);
struct mxs_auart_port *s;
u32 version;
int ret = 0;
@@ -730,6 +1078,11 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev)
goto out_free;
}
+ if (of_id) {
+ pdev->id_entry = of_id->data;
+ s->devtype = pdev->id_entry->driver_data;
+ }
+
s->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(s->clk)) {
ret = PTR_ERR(s->clk);
@@ -751,7 +1104,6 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev)
s->port.type = PORT_IMX;
s->port.dev = s->dev = get_device(&pdev->dev);
- s->flags = 0;
s->ctrl = 0;
s->irq = platform_get_irq(pdev, 0);
@@ -789,7 +1141,7 @@ out:
return ret;
}
-static int __devexit mxs_auart_remove(struct platform_device *pdev)
+static int mxs_auart_remove(struct platform_device *pdev)
{
struct mxs_auart_port *s = platform_get_drvdata(pdev);
@@ -805,15 +1157,9 @@ static int __devexit mxs_auart_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id mxs_auart_dt_ids[] = {
- { .compatible = "fsl,imx23-auart", },
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids);
-
static struct platform_driver mxs_auart_driver = {
.probe = mxs_auart_probe,
- .remove = __devexit_p(mxs_auart_remove),
+ .remove = mxs_auart_remove,
.driver = {
.name = "mxs-auart",
.owner = THIS_MODULE,
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index df443b908ca..e7cae1c2d7d 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -21,8 +21,10 @@
#include <linux/of_serial.h>
#include <linux/of_platform.h>
#include <linux/nwpserial.h>
+#include <linux/clk.h>
struct of_serial_info {
+ struct clk *clk;
int type;
int line;
};
@@ -50,8 +52,9 @@ EXPORT_SYMBOL_GPL(tegra_serial_handle_break);
/*
* Fill a struct uart_port for a given device node
*/
-static int __devinit of_platform_serial_setup(struct platform_device *ofdev,
- int type, struct uart_port *port)
+static int of_platform_serial_setup(struct platform_device *ofdev,
+ int type, struct uart_port *port,
+ struct of_serial_info *info)
{
struct resource resource;
struct device_node *np = ofdev->dev.of_node;
@@ -60,8 +63,17 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev,
memset(port, 0, sizeof *port);
if (of_property_read_u32(np, "clock-frequency", &clk)) {
- dev_warn(&ofdev->dev, "no clock-frequency property set\n");
- return -ENODEV;
+
+ /* Get clk rate through clk driver if present */
+ info->clk = clk_get(&ofdev->dev, NULL);
+ if (IS_ERR(info->clk)) {
+ dev_warn(&ofdev->dev,
+ "clk or clock-frequency not defined\n");
+ return PTR_ERR(info->clk);
+ }
+
+ clk_prepare_enable(info->clk);
+ clk = clk_get_rate(info->clk);
}
/* If current-speed was set, then try not to change it. */
if (of_property_read_u32(np, "current-speed", &spd) == 0)
@@ -70,7 +82,7 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev,
ret = of_address_to_resource(np, 0, &resource);
if (ret) {
dev_warn(&ofdev->dev, "invalid address\n");
- return ret;
+ goto out;
}
spin_lock_init(&port->lock);
@@ -97,7 +109,8 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev,
default:
dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n",
prop);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
}
@@ -115,13 +128,17 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev,
port->handle_break = tegra_serial_handle_break;
return 0;
+out:
+ if (info->clk)
+ clk_disable_unprepare(info->clk);
+ return ret;
}
/*
* Try to register a serial port
*/
static struct of_device_id of_platform_serial_table[];
-static int __devinit of_platform_serial_probe(struct platform_device *ofdev)
+static int of_platform_serial_probe(struct platform_device *ofdev)
{
const struct of_device_id *match;
struct of_serial_info *info;
@@ -141,7 +158,7 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev)
return -ENOMEM;
port_type = (unsigned long)match->data;
- ret = of_platform_serial_setup(ofdev, port_type, &port);
+ ret = of_platform_serial_setup(ofdev, port_type, &port, info);
if (ret)
goto out;
@@ -204,6 +221,9 @@ static int of_platform_serial_remove(struct platform_device *ofdev)
/* need to add code for these */
break;
}
+
+ if (info->clk)
+ clk_disable_unprepare(info->clk);
kfree(info);
return 0;
}
@@ -211,7 +231,7 @@ static int of_platform_serial_remove(struct platform_device *ofdev)
/*
* A few common types, add more as needed.
*/
-static struct of_device_id __devinitdata of_platform_serial_table[] = {
+static struct of_device_id of_platform_serial_table[] = {
{ .compatible = "ns8250", .data = (void *)PORT_8250, },
{ .compatible = "ns16450", .data = (void *)PORT_16450, },
{ .compatible = "ns16550a", .data = (void *)PORT_16550A, },
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 6d3d26a607b..b538e2e4ae5 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -96,7 +96,7 @@ struct uart_omap_port {
unsigned char msr_saved_flags;
char name[20];
unsigned long port_activity;
- u32 context_loss_cnt;
+ int context_loss_cnt;
u32 errata;
u8 wakeups_enabled;
unsigned int irq_pending:1;
@@ -702,11 +702,7 @@ serial_omap_configure_xonxoff
serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG);
- /* Enable special char function UARTi.EFR_REG[5] and
- * load the new software flow control mode IXON or IXOFF
- * and restore the UARTi.EFR_REG[4] ENHANCED_EN value.
- */
- serial_out(up, UART_EFR, up->efr | UART_EFR_SCD);
+
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
serial_out(up, UART_MCR, up->mcr & ~UART_MCR_TCRTLR);
@@ -1081,7 +1077,7 @@ out:
#ifdef CONFIG_SERIAL_OMAP_CONSOLE
-static struct uart_omap_port *serial_omap_console_ports[4];
+static struct uart_omap_port *serial_omap_console_ports[OMAP_MAX_HSUART_PORTS];
static struct uart_driver serial_omap_reg;
@@ -1242,7 +1238,7 @@ static int serial_omap_resume(struct device *dev)
}
#endif
-static void __devinit omap_serial_fill_features_erratas(struct uart_omap_port *up)
+static void omap_serial_fill_features_erratas(struct uart_omap_port *up)
{
u32 mvr, scheme;
u16 revision, major, minor;
@@ -1295,7 +1291,7 @@ static void __devinit omap_serial_fill_features_erratas(struct uart_omap_port *u
}
}
-static __devinit struct omap_uart_port_info *of_get_uart_port_info(struct device *dev)
+static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev)
{
struct omap_uart_port_info *omap_up_info;
@@ -1308,7 +1304,7 @@ static __devinit struct omap_uart_port_info *of_get_uart_port_info(struct device
return omap_up_info;
}
-static int __devinit serial_omap_probe(struct platform_device *pdev)
+static int serial_omap_probe(struct platform_device *pdev)
{
struct uart_omap_port *up;
struct resource *mem, *irq;
@@ -1445,7 +1441,7 @@ err_port_line:
return ret;
}
-static int __devexit serial_omap_remove(struct platform_device *dev)
+static int serial_omap_remove(struct platform_device *dev)
{
struct uart_omap_port *up = platform_get_drvdata(dev);
@@ -1556,11 +1552,15 @@ static int serial_omap_runtime_resume(struct device *dev)
{
struct uart_omap_port *up = dev_get_drvdata(dev);
- u32 loss_cnt = serial_omap_get_context_loss_count(up);
+ int loss_cnt = serial_omap_get_context_loss_count(up);
- if (up->context_loss_cnt != loss_cnt)
+ if (loss_cnt < 0) {
+ dev_err(dev, "serial_omap_get_context_loss_count failed : %d\n",
+ loss_cnt);
serial_omap_restore_context(up);
-
+ } else if (up->context_loss_cnt != loss_cnt) {
+ serial_omap_restore_context(up);
+ }
up->latency = up->calc_latency;
schedule_work(&up->qos_work);
@@ -1586,7 +1586,7 @@ MODULE_DEVICE_TABLE(of, omap_serial_of_match);
static struct platform_driver serial_omap_driver = {
.probe = serial_omap_probe,
- .remove = __devexit_p(serial_omap_remove),
+ .remove = serial_omap_remove,
.driver = {
.name = DRIVER_NAME,
.pm = &serial_omap_dev_pm_ops,
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
index 4cd6c238152..8318925fbf6 100644
--- a/drivers/tty/serial/pch_uart.c
+++ b/drivers/tty/serial/pch_uart.c
@@ -1839,7 +1839,7 @@ static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = {
{0,},
};
-static int __devinit pch_uart_pci_probe(struct pci_dev *pdev,
+static int pch_uart_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
int ret;
@@ -1869,7 +1869,7 @@ static struct pci_driver pch_uart_pci_driver = {
.name = "pch_uart",
.id_table = pch_uart_pci_id,
.probe = pch_uart_pci_probe,
- .remove = __devexit_p(pch_uart_pci_remove),
+ .remove = pch_uart_pci_remove,
.suspend = pch_uart_pci_suspend,
.resume = pch_uart_pci_resume,
};
diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c
index 9033fc6e0e4..2764828251f 100644
--- a/drivers/tty/serial/pxa.c
+++ b/drivers/tty/serial/pxa.c
@@ -705,6 +705,57 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count)
clk_disable_unprepare(up->clk);
}
+#ifdef CONFIG_CONSOLE_POLL
+/*
+ * Console polling routines for writing and reading from the uart while
+ * in an interrupt or debug context.
+ */
+
+static int serial_pxa_get_poll_char(struct uart_port *port)
+{
+ struct uart_pxa_port *up = (struct uart_pxa_port *)port;
+ unsigned char lsr = serial_in(up, UART_LSR);
+
+ while (!(lsr & UART_LSR_DR))
+ lsr = serial_in(up, UART_LSR);
+
+ return serial_in(up, UART_RX);
+}
+
+
+static void serial_pxa_put_poll_char(struct uart_port *port,
+ unsigned char c)
+{
+ unsigned int ier;
+ struct uart_pxa_port *up = (struct uart_pxa_port *)port;
+
+ /*
+ * First save the IER then disable the interrupts
+ */
+ ier = serial_in(up, UART_IER);
+ serial_out(up, UART_IER, UART_IER_UUE);
+
+ wait_for_xmitr(up);
+ /*
+ * Send the character out.
+ * If a LF, also do CR...
+ */
+ serial_out(up, UART_TX, c);
+ if (c == 10) {
+ wait_for_xmitr(up);
+ serial_out(up, UART_TX, 13);
+ }
+
+ /*
+ * Finally, wait for transmitter to become empty
+ * and restore the IER
+ */
+ wait_for_xmitr(up);
+ serial_out(up, UART_IER, ier);
+}
+
+#endif /* CONFIG_CONSOLE_POLL */
+
static int __init
serial_pxa_console_setup(struct console *co, char *options)
{
@@ -759,6 +810,10 @@ struct uart_ops serial_pxa_pops = {
.request_port = serial_pxa_request_port,
.config_port = serial_pxa_config_port,
.verify_port = serial_pxa_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+ .poll_get_char = serial_pxa_get_poll_char,
+ .poll_put_char = serial_pxa_put_poll_char,
+#endif
};
static struct uart_driver serial_pxa_reg = {
diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c
index 2ca5959ec3f..da56c8a0fdc 100644
--- a/drivers/tty/serial/sa1100.c
+++ b/drivers/tty/serial/sa1100.c
@@ -637,7 +637,7 @@ static void __init sa1100_init_ports(void)
PPSR |= PPC_TXD1 | PPC_TXD3;
}
-void __devinit sa1100_register_uart_fns(struct sa1100_port_fns *fns)
+void sa1100_register_uart_fns(struct sa1100_port_fns *fns)
{
if (fns->get_mctrl)
sa1100_pops.get_mctrl = fns->get_mctrl;
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index 7f04717176a..fb0e0f0bed0 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -223,8 +223,11 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id)
struct uart_port *port = &ourport->port;
struct tty_struct *tty = port->state->port.tty;
unsigned int ufcon, ch, flag, ufstat, uerstat;
+ unsigned long flags;
int max_count = 64;
+ spin_lock_irqsave(&port->lock, flags);
+
while (max_count-- > 0) {
ufcon = rd_regl(port, S3C2410_UFCON);
ufstat = rd_regl(port, S3C2410_UFSTAT);
@@ -299,6 +302,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id)
tty_flip_buffer_push(tty);
out:
+ spin_unlock_irqrestore(&port->lock, flags);
return IRQ_HANDLED;
}
@@ -307,8 +311,11 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
struct s3c24xx_uart_port *ourport = id;
struct uart_port *port = &ourport->port;
struct circ_buf *xmit = &port->state->xmit;
+ unsigned long flags;
int count = 256;
+ spin_lock_irqsave(&port->lock, flags);
+
if (port->x_char) {
wr_regb(port, S3C2410_UTXH, port->x_char);
port->icount.tx++;
@@ -336,13 +343,17 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
port->icount.tx++;
}
- if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) {
+ spin_unlock(&port->lock);
uart_write_wakeup(port);
+ spin_lock(&port->lock);
+ }
if (uart_circ_empty(xmit))
s3c24xx_serial_stop_tx(port);
out:
+ spin_unlock_irqrestore(&port->lock, flags);
return IRQ_HANDLED;
}
@@ -352,10 +363,8 @@ static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
struct s3c24xx_uart_port *ourport = id;
struct uart_port *port = &ourport->port;
unsigned int pend = rd_regl(port, S3C64XX_UINTP);
- unsigned long flags;
irqreturn_t ret = IRQ_HANDLED;
- spin_lock_irqsave(&port->lock, flags);
if (pend & S3C64XX_UINTM_RXD_MSK) {
ret = s3c24xx_serial_rx_chars(irq, id);
wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK);
@@ -364,7 +373,6 @@ static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
ret = s3c24xx_serial_tx_chars(irq, id);
wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK);
}
- spin_unlock_irqrestore(&port->lock, flags);
return ret;
}
@@ -530,16 +538,16 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
switch (level) {
case 3:
if (!IS_ERR(ourport->baudclk))
- clk_disable(ourport->baudclk);
+ clk_disable_unprepare(ourport->baudclk);
- clk_disable(ourport->clk);
+ clk_disable_unprepare(ourport->clk);
break;
case 0:
- clk_enable(ourport->clk);
+ clk_prepare_enable(ourport->clk);
if (!IS_ERR(ourport->baudclk))
- clk_enable(ourport->baudclk);
+ clk_prepare_enable(ourport->baudclk);
break;
default:
@@ -713,11 +721,11 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
s3c24xx_serial_setsource(port, clk_sel);
if (!IS_ERR(ourport->baudclk)) {
- clk_disable(ourport->baudclk);
+ clk_disable_unprepare(ourport->baudclk);
ourport->baudclk = ERR_PTR(-EINVAL);
}
- clk_enable(clk);
+ clk_prepare_enable(clk);
ourport->baudclk = clk;
ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0;
@@ -1256,7 +1264,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit s3c24xx_serial_remove(struct platform_device *dev)
+static int s3c24xx_serial_remove(struct platform_device *dev)
{
struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
@@ -1287,9 +1295,9 @@ static int s3c24xx_serial_resume(struct device *dev)
struct s3c24xx_uart_port *ourport = to_ourport(port);
if (port) {
- clk_enable(ourport->clk);
+ clk_prepare_enable(ourport->clk);
s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
- clk_disable(ourport->clk);
+ clk_disable_unprepare(ourport->clk);
uart_resume_port(&s3c24xx_uart_drv, port);
}
@@ -1701,6 +1709,16 @@ MODULE_DEVICE_TABLE(platform, s3c24xx_serial_driver_ids);
#ifdef CONFIG_OF
static const struct of_device_id s3c24xx_uart_dt_match[] = {
+ { .compatible = "samsung,s3c2410-uart",
+ .data = (void *)S3C2410_SERIAL_DRV_DATA },
+ { .compatible = "samsung,s3c2412-uart",
+ .data = (void *)S3C2412_SERIAL_DRV_DATA },
+ { .compatible = "samsung,s3c2440-uart",
+ .data = (void *)S3C2440_SERIAL_DRV_DATA },
+ { .compatible = "samsung,s3c6400-uart",
+ .data = (void *)S3C6400_SERIAL_DRV_DATA },
+ { .compatible = "samsung,s5pv210-uart",
+ .data = (void *)S5PV210_SERIAL_DRV_DATA },
{ .compatible = "samsung,exynos4210-uart",
.data = (void *)EXYNOS4210_SERIAL_DRV_DATA },
{},
@@ -1712,7 +1730,7 @@ MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
static struct platform_driver samsung_serial_driver = {
.probe = s3c24xx_serial_probe,
- .remove = __devexit_p(s3c24xx_serial_remove),
+ .remove = s3c24xx_serial_remove,
.id_table = s3c24xx_serial_driver_ids,
.driver = {
.name = "samsung-uart",
diff --git a/drivers/tty/serial/sc26xx.c b/drivers/tty/serial/sc26xx.c
index 9d664242b31..aced1dd923d 100644
--- a/drivers/tty/serial/sc26xx.c
+++ b/drivers/tty/serial/sc26xx.c
@@ -621,7 +621,7 @@ static u8 sc26xx_flags2mask(unsigned int flags, unsigned int bitpos)
return bit ? (1 << (bit - 1)) : 0;
}
-static void __devinit sc26xx_init_masks(struct uart_sc26xx_port *up,
+static void sc26xx_init_masks(struct uart_sc26xx_port *up,
int line, unsigned int data)
{
up->dtr_mask[line] = sc26xx_flags2mask(data, 0);
@@ -632,7 +632,7 @@ static void __devinit sc26xx_init_masks(struct uart_sc26xx_port *up,
up->ri_mask[line] = sc26xx_flags2mask(data, 20);
}
-static int __devinit sc26xx_probe(struct platform_device *dev)
+static int sc26xx_probe(struct platform_device *dev)
{
struct resource *res;
struct uart_sc26xx_port *up;
@@ -733,7 +733,7 @@ static int __exit sc26xx_driver_remove(struct platform_device *dev)
static struct platform_driver sc26xx_driver = {
.probe = sc26xx_probe,
- .remove = __devexit_p(sc26xx_driver_remove),
+ .remove = sc26xx_driver_remove,
.driver = {
.name = "SC26xx",
.owner = THIS_MODULE,
diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c
index e821068cd95..418b495e323 100644
--- a/drivers/tty/serial/sccnxp.c
+++ b/drivers/tty/serial/sccnxp.c
@@ -740,7 +740,7 @@ static int sccnxp_console_setup(struct console *co, char *options)
}
#endif
-static int __devinit sccnxp_probe(struct platform_device *pdev)
+static int sccnxp_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int chiptype = pdev->id_entry->driver_data;
@@ -943,7 +943,7 @@ err_out:
return ret;
}
-static int __devexit sccnxp_remove(struct platform_device *pdev)
+static int sccnxp_remove(struct platform_device *pdev)
{
int i;
struct sccnxp_port *s = platform_get_drvdata(pdev);
@@ -981,7 +981,7 @@ static struct platform_driver sccnxp_uart_driver = {
.owner = THIS_MODULE,
},
.probe = sccnxp_probe,
- .remove = __devexit_p(sccnxp_remove),
+ .remove = sccnxp_remove,
.id_table = sccnxp_id_table,
};
module_platform_driver(sccnxp_uart_driver);
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 0fcfd98a956..fb5aa42fde7 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -634,10 +634,10 @@ static void uart_unthrottle(struct tty_struct *tty)
uart_set_mctrl(port, TIOCM_RTS);
}
-static void uart_get_info(struct tty_port *port,
- struct uart_state *state,
+static void do_uart_get_info(struct tty_port *port,
struct serial_struct *retinfo)
{
+ struct uart_state *state = container_of(port, struct uart_state, port);
struct uart_port *uport = state->uart_port;
memset(retinfo, 0, sizeof(*retinfo));
@@ -662,17 +662,21 @@ static void uart_get_info(struct tty_port *port,
retinfo->iomem_base = (void *)(unsigned long)uport->mapbase;
}
-static int uart_get_info_user(struct uart_state *state,
- struct serial_struct __user *retinfo)
+static void uart_get_info(struct tty_port *port,
+ struct serial_struct *retinfo)
{
- struct tty_port *port = &state->port;
- struct serial_struct tmp;
-
/* Ensure the state we copy is consistent and no hardware changes
occur as we go */
mutex_lock(&port->mutex);
- uart_get_info(port, state, &tmp);
+ do_uart_get_info(port, retinfo);
mutex_unlock(&port->mutex);
+}
+
+static int uart_get_info_user(struct tty_port *port,
+ struct serial_struct __user *retinfo)
+{
+ struct serial_struct tmp;
+ uart_get_info(port, &tmp);
if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
return -EFAULT;
@@ -1131,7 +1135,7 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd,
*/
switch (cmd) {
case TIOCGSERIAL:
- ret = uart_get_info_user(state, uarg);
+ ret = uart_get_info_user(port, uarg);
break;
case TIOCSSERIAL:
@@ -2293,6 +2297,8 @@ int uart_register_driver(struct uart_driver *drv)
if (retval >= 0)
return retval;
+ for (i = 0; i < drv->nr; i++)
+ tty_port_destroy(&drv->state[i].port);
put_tty_driver(normal);
out_kfree:
kfree(drv->state);
@@ -2312,8 +2318,12 @@ out:
void uart_unregister_driver(struct uart_driver *drv)
{
struct tty_driver *p = drv->tty_driver;
+ unsigned int i;
+
tty_unregister_driver(p);
put_tty_driver(p);
+ for (i = 0; i < drv->nr; i++)
+ tty_port_destroy(&drv->state[i].port);
kfree(drv->state);
drv->state = NULL;
drv->tty_driver = NULL;
@@ -2329,21 +2339,166 @@ struct tty_driver *uart_console_device(struct console *co, int *index)
static ssize_t uart_get_attr_uartclk(struct device *dev,
struct device_attribute *attr, char *buf)
{
- int ret;
+ struct serial_struct tmp;
struct tty_port *port = dev_get_drvdata(dev);
- struct uart_state *state = container_of(port, struct uart_state, port);
- mutex_lock(&state->port.mutex);
- ret = snprintf(buf, PAGE_SIZE, "%d\n", state->uart_port->uartclk);
- mutex_unlock(&state->port.mutex);
+ uart_get_info(port, &tmp);
+ return snprintf(buf, PAGE_SIZE, "%d\n", tmp.baud_base * 16);
+}
- return ret;
+static ssize_t uart_get_attr_type(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct serial_struct tmp;
+ struct tty_port *port = dev_get_drvdata(dev);
+
+ uart_get_info(port, &tmp);
+ return snprintf(buf, PAGE_SIZE, "%d\n", tmp.type);
+}
+static ssize_t uart_get_attr_line(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct serial_struct tmp;
+ struct tty_port *port = dev_get_drvdata(dev);
+
+ uart_get_info(port, &tmp);
+ return snprintf(buf, PAGE_SIZE, "%d\n", tmp.line);
+}
+
+static ssize_t uart_get_attr_port(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct serial_struct tmp;
+ struct tty_port *port = dev_get_drvdata(dev);
+ unsigned long ioaddr;
+
+ uart_get_info(port, &tmp);
+ ioaddr = tmp.port;
+ if (HIGH_BITS_OFFSET)
+ ioaddr |= (unsigned long)tmp.port_high << HIGH_BITS_OFFSET;
+ return snprintf(buf, PAGE_SIZE, "0x%lX\n", ioaddr);
}
+static ssize_t uart_get_attr_irq(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct serial_struct tmp;
+ struct tty_port *port = dev_get_drvdata(dev);
+
+ uart_get_info(port, &tmp);
+ return snprintf(buf, PAGE_SIZE, "%d\n", tmp.irq);
+}
+
+static ssize_t uart_get_attr_flags(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct serial_struct tmp;
+ struct tty_port *port = dev_get_drvdata(dev);
+
+ uart_get_info(port, &tmp);
+ return snprintf(buf, PAGE_SIZE, "0x%X\n", tmp.flags);
+}
+
+static ssize_t uart_get_attr_xmit_fifo_size(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct serial_struct tmp;
+ struct tty_port *port = dev_get_drvdata(dev);
+
+ uart_get_info(port, &tmp);
+ return snprintf(buf, PAGE_SIZE, "%d\n", tmp.xmit_fifo_size);
+}
+
+
+static ssize_t uart_get_attr_close_delay(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct serial_struct tmp;
+ struct tty_port *port = dev_get_drvdata(dev);
+
+ uart_get_info(port, &tmp);
+ return snprintf(buf, PAGE_SIZE, "%d\n", tmp.close_delay);
+}
+
+
+static ssize_t uart_get_attr_closing_wait(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct serial_struct tmp;
+ struct tty_port *port = dev_get_drvdata(dev);
+
+ uart_get_info(port, &tmp);
+ return snprintf(buf, PAGE_SIZE, "%d\n", tmp.closing_wait);
+}
+
+static ssize_t uart_get_attr_custom_divisor(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct serial_struct tmp;
+ struct tty_port *port = dev_get_drvdata(dev);
+
+ uart_get_info(port, &tmp);
+ return snprintf(buf, PAGE_SIZE, "%d\n", tmp.custom_divisor);
+}
+
+static ssize_t uart_get_attr_io_type(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct serial_struct tmp;
+ struct tty_port *port = dev_get_drvdata(dev);
+
+ uart_get_info(port, &tmp);
+ return snprintf(buf, PAGE_SIZE, "%d\n", tmp.io_type);
+}
+
+static ssize_t uart_get_attr_iomem_base(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct serial_struct tmp;
+ struct tty_port *port = dev_get_drvdata(dev);
+
+ uart_get_info(port, &tmp);
+ return snprintf(buf, PAGE_SIZE, "0x%lX\n", (unsigned long)tmp.iomem_base);
+}
+
+static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct serial_struct tmp;
+ struct tty_port *port = dev_get_drvdata(dev);
+
+ uart_get_info(port, &tmp);
+ return snprintf(buf, PAGE_SIZE, "%d\n", tmp.iomem_reg_shift);
+}
+
+static DEVICE_ATTR(type, S_IRUSR | S_IRGRP, uart_get_attr_type, NULL);
+static DEVICE_ATTR(line, S_IRUSR | S_IRGRP, uart_get_attr_line, NULL);
+static DEVICE_ATTR(port, S_IRUSR | S_IRGRP, uart_get_attr_port, NULL);
+static DEVICE_ATTR(irq, S_IRUSR | S_IRGRP, uart_get_attr_irq, NULL);
+static DEVICE_ATTR(flags, S_IRUSR | S_IRGRP, uart_get_attr_flags, NULL);
+static DEVICE_ATTR(xmit_fifo_size, S_IRUSR | S_IRGRP, uart_get_attr_xmit_fifo_size, NULL);
static DEVICE_ATTR(uartclk, S_IRUSR | S_IRGRP, uart_get_attr_uartclk, NULL);
+static DEVICE_ATTR(close_delay, S_IRUSR | S_IRGRP, uart_get_attr_close_delay, NULL);
+static DEVICE_ATTR(closing_wait, S_IRUSR | S_IRGRP, uart_get_attr_closing_wait, NULL);
+static DEVICE_ATTR(custom_divisor, S_IRUSR | S_IRGRP, uart_get_attr_custom_divisor, NULL);
+static DEVICE_ATTR(io_type, S_IRUSR | S_IRGRP, uart_get_attr_io_type, NULL);
+static DEVICE_ATTR(iomem_base, S_IRUSR | S_IRGRP, uart_get_attr_iomem_base, NULL);
+static DEVICE_ATTR(iomem_reg_shift, S_IRUSR | S_IRGRP, uart_get_attr_iomem_reg_shift, NULL);
static struct attribute *tty_dev_attrs[] = {
+ &dev_attr_type.attr,
+ &dev_attr_line.attr,
+ &dev_attr_port.attr,
+ &dev_attr_irq.attr,
+ &dev_attr_flags.attr,
+ &dev_attr_xmit_fifo_size.attr,
&dev_attr_uartclk.attr,
+ &dev_attr_close_delay.attr,
+ &dev_attr_closing_wait.attr,
+ &dev_attr_custom_divisor.attr,
+ &dev_attr_io_type.attr,
+ &dev_attr_iomem_base.attr,
+ &dev_attr_iomem_reg_shift.attr,
NULL,
};
@@ -2356,6 +2511,7 @@ static const struct attribute_group *tty_dev_attr_groups[] = {
NULL
};
+
/**
* uart_add_one_port - attach a driver-defined port structure
* @drv: pointer to the uart low level driver structure for this port
diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c
index 6ae2a58d62f..b52b21aeb25 100644
--- a/drivers/tty/serial/serial_txx9.c
+++ b/drivers/tty/serial/serial_txx9.c
@@ -1030,7 +1030,7 @@ static DEFINE_MUTEX(serial_txx9_mutex);
*
* On success the port is ready to use and the line number is returned.
*/
-static int __devinit serial_txx9_register_port(struct uart_port *port)
+static int serial_txx9_register_port(struct uart_port *port)
{
int i;
struct uart_txx9_port *uart;
@@ -1078,7 +1078,7 @@ static int __devinit serial_txx9_register_port(struct uart_port *port)
* Remove one serial port. This may not be called from interrupt
* context. We hand the port back to the our control.
*/
-static void __devexit serial_txx9_unregister_port(int line)
+static void serial_txx9_unregister_port(int line)
{
struct uart_txx9_port *uart = &serial_txx9_ports[line];
@@ -1096,7 +1096,7 @@ static void __devexit serial_txx9_unregister_port(int line)
/*
* Register a set of serial devices attached to a platform device.
*/
-static int __devinit serial_txx9_probe(struct platform_device *dev)
+static int serial_txx9_probe(struct platform_device *dev)
{
struct uart_port *p = dev->dev.platform_data;
struct uart_port port;
@@ -1126,7 +1126,7 @@ static int __devinit serial_txx9_probe(struct platform_device *dev)
/*
* Remove serial ports registered against a platform device.
*/
-static int __devexit serial_txx9_remove(struct platform_device *dev)
+static int serial_txx9_remove(struct platform_device *dev)
{
int i;
@@ -1171,7 +1171,7 @@ static int serial_txx9_resume(struct platform_device *dev)
static struct platform_driver serial_txx9_plat_driver = {
.probe = serial_txx9_probe,
- .remove = __devexit_p(serial_txx9_remove),
+ .remove = serial_txx9_remove,
#ifdef CONFIG_PM
.suspend = serial_txx9_suspend,
.resume = serial_txx9_resume,
@@ -1187,7 +1187,7 @@ static struct platform_driver serial_txx9_plat_driver = {
* Probe one serial board. Unfortunately, there is no rhyme nor reason
* to the arrangement of serial ports on a PCI card.
*/
-static int __devinit
+static int
pciserial_txx9_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
{
struct uart_port port;
@@ -1217,7 +1217,7 @@ pciserial_txx9_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
return 0;
}
-static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev)
+static void pciserial_txx9_remove_one(struct pci_dev *dev)
{
struct uart_txx9_port *up = pci_get_drvdata(dev);
@@ -1261,7 +1261,7 @@ static const struct pci_device_id serial_txx9_pci_tbl[] = {
static struct pci_driver serial_txx9_pci_driver = {
.name = "serial_txx9",
.probe = pciserial_txx9_init_one,
- .remove = __devexit_p(pciserial_txx9_remove_one),
+ .remove = pciserial_txx9_remove_one,
#ifdef CONFIG_PM
.suspend = pciserial_txx9_suspend_one,
.resume = pciserial_txx9_resume_one,
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 6ee59001d61..61477567423 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -99,12 +99,6 @@ struct sci_port {
#endif
struct notifier_block freq_transition;
-
-#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
- unsigned short saved_smr;
- unsigned short saved_fcr;
- unsigned char saved_brr;
-#endif
};
/* Function prototypes */
@@ -202,9 +196,9 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
[SCxSR] = { 0x14, 16 },
[SCxRDR] = { 0x60, 8 },
[SCFCR] = { 0x18, 16 },
- [SCFDR] = { 0x1c, 16 },
- [SCTFDR] = sci_reg_invalid,
- [SCRFDR] = sci_reg_invalid,
+ [SCFDR] = sci_reg_invalid,
+ [SCTFDR] = { 0x38, 16 },
+ [SCRFDR] = { 0x3c, 16 },
[SCSPTR] = sci_reg_invalid,
[SCLSR] = sci_reg_invalid,
},
@@ -491,7 +485,7 @@ static int sci_txfill(struct uart_port *port)
reg = sci_getreg(port, SCTFDR);
if (reg->size)
- return serial_port_in(port, SCTFDR) & 0xff;
+ return serial_port_in(port, SCTFDR) & ((port->fifosize << 1) - 1);
reg = sci_getreg(port, SCFDR);
if (reg->size)
@@ -511,7 +505,7 @@ static int sci_rxfill(struct uart_port *port)
reg = sci_getreg(port, SCRFDR);
if (reg->size)
- return serial_port_in(port, SCRFDR) & 0xff;
+ return serial_port_in(port, SCRFDR) & ((port->fifosize << 1) - 1);
reg = sci_getreg(port, SCFDR);
if (reg->size)
@@ -1132,7 +1126,7 @@ static const char *sci_gpio_str(unsigned int index)
return sci_gpio_names[index];
}
-static void __devinit sci_init_gpios(struct sci_port *port)
+static void sci_init_gpios(struct sci_port *port)
{
struct uart_port *up = &port->port;
int i;
@@ -1749,22 +1743,21 @@ static inline void sci_free_dma(struct uart_port *port)
static int sci_startup(struct uart_port *port)
{
struct sci_port *s = to_sci_port(port);
+ unsigned long flags;
int ret;
dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
- pm_runtime_put_noidle(port->dev);
-
- sci_port_enable(s);
-
ret = sci_request_irq(s);
if (unlikely(ret < 0))
return ret;
sci_request_dma(port);
+ spin_lock_irqsave(&port->lock, flags);
sci_start_tx(port);
sci_start_rx(port);
+ spin_unlock_irqrestore(&port->lock, flags);
return 0;
}
@@ -1772,18 +1765,17 @@ static int sci_startup(struct uart_port *port)
static void sci_shutdown(struct uart_port *port)
{
struct sci_port *s = to_sci_port(port);
+ unsigned long flags;
dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
+ spin_lock_irqsave(&port->lock, flags);
sci_stop_rx(port);
sci_stop_tx(port);
+ spin_unlock_irqrestore(&port->lock, flags);
sci_free_dma(port);
sci_free_irq(s);
-
- sci_port_disable(s);
-
- pm_runtime_get_noresume(port->dev);
}
static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps,
@@ -1829,7 +1821,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
{
struct sci_port *s = to_sci_port(port);
struct plat_sci_reg *reg;
- unsigned int baud, smr_val, max_baud;
+ unsigned int baud, smr_val, max_baud, cks;
int t = -1;
/*
@@ -1863,21 +1855,18 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
uart_update_timeout(port, termios->c_cflag, baud);
- serial_port_out(port, SCSMR, smr_val);
-
- dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t,
- s->cfg->scscr);
+ for (cks = 0; t >= 256 && cks <= 3; cks++)
+ t >>= 2;
- if (t > 0) {
- if (t >= 256) {
- serial_port_out(port, SCSMR, (serial_port_in(port, SCSMR) & ~3) | 1);
- t >>= 2;
- } else
- serial_port_out(port, SCSMR, serial_port_in(port, SCSMR) & ~3);
+ dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n",
+ __func__, smr_val, cks, t, s->cfg->scscr);
+ if (t >= 0) {
+ serial_port_out(port, SCSMR, (smr_val & ~3) | cks);
serial_port_out(port, SCBRR, t);
udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
- }
+ } else
+ serial_port_out(port, SCSMR, smr_val);
sci_init_pins(port, termios->c_cflag);
@@ -1932,6 +1921,21 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
sci_port_disable(s);
}
+static void sci_pm(struct uart_port *port, unsigned int state,
+ unsigned int oldstate)
+{
+ struct sci_port *sci_port = to_sci_port(port);
+
+ switch (state) {
+ case 3:
+ sci_port_disable(sci_port);
+ break;
+ default:
+ sci_port_enable(sci_port);
+ break;
+ }
+}
+
static const char *sci_type(struct uart_port *port)
{
switch (port->type) {
@@ -2053,6 +2057,7 @@ static struct uart_ops sci_uart_ops = {
.startup = sci_startup,
.shutdown = sci_shutdown,
.set_termios = sci_set_termios,
+ .pm = sci_pm,
.type = sci_type,
.release_port = sci_release_port,
.request_port = sci_request_port,
@@ -2064,7 +2069,7 @@ static struct uart_ops sci_uart_ops = {
#endif
};
-static int __devinit sci_init_single(struct platform_device *dev,
+static int sci_init_single(struct platform_device *dev,
struct sci_port *sci_port,
unsigned int index,
struct plat_sci_port *p)
@@ -2121,8 +2126,6 @@ static int __devinit sci_init_single(struct platform_device *dev,
sci_init_gpios(sci_port);
- pm_runtime_irq_safe(&dev->dev);
- pm_runtime_get_noresume(&dev->dev);
pm_runtime_enable(&dev->dev);
}
@@ -2206,9 +2209,21 @@ static void serial_console_write(struct console *co, const char *s,
{
struct sci_port *sci_port = &sci_ports[co->index];
struct uart_port *port = &sci_port->port;
- unsigned short bits;
+ unsigned short bits, ctrl;
+ unsigned long flags;
+ int locked = 1;
+
+ local_irq_save(flags);
+ if (port->sysrq)
+ locked = 0;
+ else if (oops_in_progress)
+ locked = spin_trylock(&port->lock);
+ else
+ spin_lock(&port->lock);
- sci_port_enable(sci_port);
+ /* first save the SCSCR then disable the interrupts */
+ ctrl = serial_port_in(port, SCSCR);
+ serial_port_out(port, SCSCR, sci_port->cfg->scscr);
uart_console_write(port, s, count, serial_console_putchar);
@@ -2217,10 +2232,15 @@ static void serial_console_write(struct console *co, const char *s,
while ((serial_port_in(port, SCxSR) & bits) != bits)
cpu_relax();
- sci_port_disable(sci_port);
+ /* restore the SCSCR */
+ serial_port_out(port, SCSCR, ctrl);
+
+ if (locked)
+ spin_unlock(&port->lock);
+ local_irq_restore(flags);
}
-static int __devinit serial_console_setup(struct console *co, char *options)
+static int serial_console_setup(struct console *co, char *options)
{
struct sci_port *sci_port;
struct uart_port *port;
@@ -2249,13 +2269,9 @@ static int __devinit serial_console_setup(struct console *co, char *options)
if (unlikely(ret != 0))
return ret;
- sci_port_enable(sci_port);
-
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
- sci_port_disable(sci_port);
-
return uart_set_options(port, co, baud, parity, bits, flow);
}
@@ -2278,7 +2294,7 @@ static struct console early_serial_console = {
static char early_serial_buf[32];
-static int __devinit sci_probe_earlyprintk(struct platform_device *pdev)
+static int sci_probe_earlyprintk(struct platform_device *pdev)
{
struct plat_sci_port *cfg = pdev->dev.platform_data;
@@ -2298,57 +2314,15 @@ static int __devinit sci_probe_earlyprintk(struct platform_device *pdev)
return 0;
}
-#define uart_console(port) ((port)->cons->index == (port)->line)
-
-static int sci_runtime_suspend(struct device *dev)
-{
- struct sci_port *sci_port = dev_get_drvdata(dev);
- struct uart_port *port = &sci_port->port;
-
- if (uart_console(port)) {
- struct plat_sci_reg *reg;
-
- sci_port->saved_smr = serial_port_in(port, SCSMR);
- sci_port->saved_brr = serial_port_in(port, SCBRR);
-
- reg = sci_getreg(port, SCFCR);
- if (reg->size)
- sci_port->saved_fcr = serial_port_in(port, SCFCR);
- else
- sci_port->saved_fcr = 0;
- }
- return 0;
-}
-
-static int sci_runtime_resume(struct device *dev)
-{
- struct sci_port *sci_port = dev_get_drvdata(dev);
- struct uart_port *port = &sci_port->port;
-
- if (uart_console(port)) {
- sci_reset(port);
- serial_port_out(port, SCSMR, sci_port->saved_smr);
- serial_port_out(port, SCBRR, sci_port->saved_brr);
-
- if (sci_port->saved_fcr)
- serial_port_out(port, SCFCR, sci_port->saved_fcr);
-
- serial_port_out(port, SCSCR, sci_port->cfg->scscr);
- }
- return 0;
-}
-
#define SCI_CONSOLE (&serial_console)
#else
-static inline int __devinit sci_probe_earlyprintk(struct platform_device *pdev)
+static inline int sci_probe_earlyprintk(struct platform_device *pdev)
{
return -EINVAL;
}
#define SCI_CONSOLE NULL
-#define sci_runtime_suspend NULL
-#define sci_runtime_resume NULL
#endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */
@@ -2379,7 +2353,7 @@ static int sci_remove(struct platform_device *dev)
return 0;
}
-static int __devinit sci_probe_single(struct platform_device *dev,
+static int sci_probe_single(struct platform_device *dev,
unsigned int index,
struct plat_sci_port *p,
struct sci_port *sciport)
@@ -2409,7 +2383,7 @@ static int __devinit sci_probe_single(struct platform_device *dev,
return 0;
}
-static int __devinit sci_probe(struct platform_device *dev)
+static int sci_probe(struct platform_device *dev)
{
struct plat_sci_port *p = dev->dev.platform_data;
struct sci_port *sp = &sci_ports[dev->id];
@@ -2466,8 +2440,6 @@ static int sci_resume(struct device *dev)
}
static const struct dev_pm_ops sci_dev_pm_ops = {
- .runtime_suspend = sci_runtime_suspend,
- .runtime_resume = sci_runtime_resume,
.suspend = sci_suspend,
.resume = sci_resume,
};
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c
index a9e2bd1ab53..5da5cb96276 100644
--- a/drivers/tty/serial/sirfsoc_uart.c
+++ b/drivers/tty/serial/sirfsoc_uart.c
@@ -727,7 +727,7 @@ static int sirfsoc_uart_resume(struct platform_device *pdev)
return 0;
}
-static struct of_device_id sirfsoc_uart_ids[] __devinitdata = {
+static struct of_device_id sirfsoc_uart_ids[] = {
{ .compatible = "sirf,prima2-uart", },
{}
};
@@ -735,7 +735,7 @@ MODULE_DEVICE_TABLE(of, sirfsoc_serial_of_match);
static struct platform_driver sirfsoc_uart_driver = {
.probe = sirfsoc_uart_probe,
- .remove = __devexit_p(sirfsoc_uart_remove),
+ .remove = sirfsoc_uart_remove,
.suspend = sirfsoc_uart_suspend,
.resume = sirfsoc_uart_resume,
.driver = {
diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c
index 505961cfd93..b9bf9c53f7f 100644
--- a/drivers/tty/serial/sunhv.c
+++ b/drivers/tty/serial/sunhv.c
@@ -519,7 +519,7 @@ static struct console sunhv_console = {
.data = &sunhv_reg,
};
-static int __devinit hv_probe(struct platform_device *op)
+static int hv_probe(struct platform_device *op)
{
struct uart_port *port;
unsigned long minor;
@@ -598,7 +598,7 @@ out_free_port:
return err;
}
-static int __devexit hv_remove(struct platform_device *dev)
+static int hv_remove(struct platform_device *dev)
{
struct uart_port *port = dev_get_drvdata(&dev->dev);
@@ -636,7 +636,7 @@ static struct platform_driver hv_driver = {
.of_match_table = hv_match,
},
.probe = hv_probe,
- .remove = __devexit_p(hv_remove),
+ .remove = hv_remove,
};
static int __init sunhv_init(void)
diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c
index f0d93eb7e6e..bd8b3b63410 100644
--- a/drivers/tty/serial/sunsab.c
+++ b/drivers/tty/serial/sunsab.c
@@ -954,7 +954,7 @@ static inline struct console *SUNSAB_CONSOLE(void)
#define sunsab_console_init() do { } while (0)
#endif
-static int __devinit sunsab_init_one(struct uart_sunsab_port *up,
+static int sunsab_init_one(struct uart_sunsab_port *up,
struct platform_device *op,
unsigned long offset,
int line)
@@ -1007,7 +1007,7 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up,
return 0;
}
-static int __devinit sab_probe(struct platform_device *op)
+static int sab_probe(struct platform_device *op)
{
static int inst;
struct uart_sunsab_port *up;
@@ -1063,7 +1063,7 @@ out:
return err;
}
-static int __devexit sab_remove(struct platform_device *op)
+static int sab_remove(struct platform_device *op)
{
struct uart_sunsab_port *up = dev_get_drvdata(&op->dev);
@@ -1100,7 +1100,7 @@ static struct platform_driver sab_driver = {
.of_match_table = sab_match,
},
.probe = sab_probe,
- .remove = __devexit_p(sab_remove),
+ .remove = sab_remove,
};
static int __init sunsab_init(void)
diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c
index b97913dcdbf..220da3f9724 100644
--- a/drivers/tty/serial/sunsu.c
+++ b/drivers/tty/serial/sunsu.c
@@ -1185,7 +1185,7 @@ static struct uart_driver sunsu_reg = {
.major = TTY_MAJOR,
};
-static int __devinit sunsu_kbd_ms_init(struct uart_sunsu_port *up)
+static int sunsu_kbd_ms_init(struct uart_sunsu_port *up)
{
int quot, baud;
#ifdef CONFIG_SERIO
@@ -1391,7 +1391,7 @@ static inline struct console *SUNSU_CONSOLE(void)
#define sunsu_serial_console_init() do { } while (0)
#endif
-static enum su_type __devinit su_get_type(struct device_node *dp)
+static enum su_type su_get_type(struct device_node *dp)
{
struct device_node *ap = of_find_node_by_path("/aliases");
@@ -1412,7 +1412,7 @@ static enum su_type __devinit su_get_type(struct device_node *dp)
return SU_PORT_PORT;
}
-static int __devinit su_probe(struct platform_device *op)
+static int su_probe(struct platform_device *op)
{
static int inst;
struct device_node *dp = op->dev.of_node;
@@ -1503,7 +1503,7 @@ out_unmap:
return err;
}
-static int __devexit su_remove(struct platform_device *op)
+static int su_remove(struct platform_device *op)
{
struct uart_sunsu_port *up = dev_get_drvdata(&op->dev);
bool kbdms = false;
@@ -1556,7 +1556,7 @@ static struct platform_driver su_driver = {
.of_match_table = su_match,
},
.probe = su_probe,
- .remove = __devexit_p(su_remove),
+ .remove = su_remove,
};
static int __init sunsu_init(void)
diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c
index babd9470982..aef4fab957c 100644
--- a/drivers/tty/serial/sunzilog.c
+++ b/drivers/tty/serial/sunzilog.c
@@ -1282,7 +1282,7 @@ static inline struct console *SUNZILOG_CONSOLE(void)
#define SUNZILOG_CONSOLE() (NULL)
#endif
-static void __devinit sunzilog_init_kbdms(struct uart_sunzilog_port *up)
+static void sunzilog_init_kbdms(struct uart_sunzilog_port *up)
{
int baud, brg;
@@ -1302,7 +1302,7 @@ static void __devinit sunzilog_init_kbdms(struct uart_sunzilog_port *up)
}
#ifdef CONFIG_SERIO
-static void __devinit sunzilog_register_serio(struct uart_sunzilog_port *up)
+static void sunzilog_register_serio(struct uart_sunzilog_port *up)
{
struct serio *serio = &up->serio;
@@ -1331,7 +1331,7 @@ static void __devinit sunzilog_register_serio(struct uart_sunzilog_port *up)
}
#endif
-static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up)
+static void sunzilog_init_hw(struct uart_sunzilog_port *up)
{
struct zilog_channel __iomem *channel;
unsigned long flags;
@@ -1400,7 +1400,7 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up)
static int zilog_irq;
-static int __devinit zs_probe(struct platform_device *op)
+static int zs_probe(struct platform_device *op)
{
static int kbm_inst, uart_inst;
int inst;
@@ -1507,7 +1507,7 @@ static int __devinit zs_probe(struct platform_device *op)
return 0;
}
-static void __devexit zs_remove_one(struct uart_sunzilog_port *up)
+static void zs_remove_one(struct uart_sunzilog_port *up)
{
if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) {
#ifdef CONFIG_SERIO
@@ -1517,7 +1517,7 @@ static void __devexit zs_remove_one(struct uart_sunzilog_port *up)
uart_remove_one_port(&sunzilog_reg, &up->port);
}
-static int __devexit zs_remove(struct platform_device *op)
+static int zs_remove(struct platform_device *op)
{
struct uart_sunzilog_port *up = dev_get_drvdata(&op->dev);
struct zilog_layout __iomem *regs;
@@ -1548,7 +1548,7 @@ static struct platform_driver zs_driver = {
.of_match_table = zs_match,
},
.probe = zs_probe,
- .remove = __devexit_p(zs_remove),
+ .remove = zs_remove,
};
static int __init sunzilog_init(void)
diff --git a/drivers/tty/serial/timbuart.c b/drivers/tty/serial/timbuart.c
index 70f97491d8f..5be0d68fece 100644
--- a/drivers/tty/serial/timbuart.c
+++ b/drivers/tty/serial/timbuart.c
@@ -426,7 +426,7 @@ static struct uart_driver timbuart_driver = {
.nr = 1
};
-static int __devinit timbuart_probe(struct platform_device *dev)
+static int timbuart_probe(struct platform_device *dev)
{
int err, irq;
struct timbuart_port *uart;
@@ -492,7 +492,7 @@ err_mem:
return err;
}
-static int __devexit timbuart_remove(struct platform_device *dev)
+static int timbuart_remove(struct platform_device *dev)
{
struct timbuart_port *uart = platform_get_drvdata(dev);
@@ -510,7 +510,7 @@ static struct platform_driver timbuart_platform_driver = {
.owner = THIS_MODULE,
},
.probe = timbuart_probe,
- .remove = __devexit_p(timbuart_remove),
+ .remove = timbuart_remove,
};
module_platform_driver(timbuart_platform_driver);
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c
index 6579ffdd8e9..89eee43c4e2 100644
--- a/drivers/tty/serial/uartlite.c
+++ b/drivers/tty/serial/uartlite.c
@@ -408,7 +408,7 @@ static void ulite_console_write(struct console *co, const char *s,
spin_unlock_irqrestore(&port->lock, flags);
}
-static int __devinit ulite_console_setup(struct console *co, char *options)
+static int ulite_console_setup(struct console *co, char *options)
{
struct uart_port *port;
int baud = 9600;
@@ -486,7 +486,7 @@ static struct uart_driver ulite_uart_driver = {
*
* Returns: 0 on success, <0 otherwise
*/
-static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq)
+static int ulite_assign(struct device *dev, int id, u32 base, int irq)
{
struct uart_port *port;
int rc;
@@ -542,7 +542,7 @@ static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq)
*
* @dev: pointer to device structure
*/
-static int __devexit ulite_release(struct device *dev)
+static int ulite_release(struct device *dev)
{
struct uart_port *port = dev_get_drvdata(dev);
int rc = 0;
@@ -562,7 +562,7 @@ static int __devexit ulite_release(struct device *dev)
#if defined(CONFIG_OF)
/* Match table for of_platform binding */
-static struct of_device_id ulite_of_match[] __devinitdata = {
+static struct of_device_id ulite_of_match[] = {
{ .compatible = "xlnx,opb-uartlite-1.00.b", },
{ .compatible = "xlnx,xps-uartlite-1.00.a", },
{}
@@ -570,7 +570,7 @@ static struct of_device_id ulite_of_match[] __devinitdata = {
MODULE_DEVICE_TABLE(of, ulite_of_match);
#endif /* CONFIG_OF */
-static int __devinit ulite_probe(struct platform_device *pdev)
+static int ulite_probe(struct platform_device *pdev)
{
struct resource *res, *res2;
int id = pdev->id;
@@ -593,7 +593,7 @@ static int __devinit ulite_probe(struct platform_device *pdev)
return ulite_assign(&pdev->dev, id, res->start, res2->start);
}
-static int __devexit ulite_remove(struct platform_device *pdev)
+static int ulite_remove(struct platform_device *pdev)
{
return ulite_release(&pdev->dev);
}
@@ -603,7 +603,7 @@ MODULE_ALIAS("platform:uartlite");
static struct platform_driver ulite_platform_driver = {
.probe = ulite_probe,
- .remove = __devexit_p(ulite_remove),
+ .remove = ulite_remove,
.driver = {
.owner = THIS_MODULE,
.name = "uartlite",
diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c
index cf0d9485ec0..62ee0166bc6 100644
--- a/drivers/tty/serial/vr41xx_siu.c
+++ b/drivers/tty/serial/vr41xx_siu.c
@@ -823,7 +823,7 @@ static struct console siu_console = {
.data = &siu_uart_driver,
};
-static int __devinit siu_console_init(void)
+static int siu_console_init(void)
{
struct uart_port *port;
int i;
@@ -867,7 +867,7 @@ static struct uart_driver siu_uart_driver = {
.cons = SERIAL_VR41XX_CONSOLE,
};
-static int __devinit siu_probe(struct platform_device *dev)
+static int siu_probe(struct platform_device *dev)
{
struct uart_port *port;
int num, i, retval;
@@ -901,7 +901,7 @@ static int __devinit siu_probe(struct platform_device *dev)
return 0;
}
-static int __devexit siu_remove(struct platform_device *dev)
+static int siu_remove(struct platform_device *dev)
{
struct uart_port *port;
int i;
@@ -952,7 +952,7 @@ static int siu_resume(struct platform_device *dev)
static struct platform_driver siu_device_driver = {
.probe = siu_probe,
- .remove = __devexit_p(siu_remove),
+ .remove = siu_remove,
.suspend = siu_suspend,
.resume = siu_resume,
.driver = {
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c
index 205d4cf4a06..8fd181436a6 100644
--- a/drivers/tty/serial/vt8500_serial.c
+++ b/drivers/tty/serial/vt8500_serial.c
@@ -554,7 +554,7 @@ static struct uart_driver vt8500_uart_driver = {
.cons = VT8500_CONSOLE,
};
-static int __devinit vt8500_serial_probe(struct platform_device *pdev)
+static int vt8500_serial_probe(struct platform_device *pdev)
{
struct vt8500_port *vt8500_port;
struct resource *mmres, *irqres;
@@ -567,10 +567,6 @@ static int __devinit vt8500_serial_probe(struct platform_device *pdev)
if (!mmres || !irqres)
return -ENODEV;
- vt8500_port = kzalloc(sizeof(struct vt8500_port), GFP_KERNEL);
- if (!vt8500_port)
- return -ENOMEM;
-
if (np)
port = of_alias_get_id(np, "serial");
if (port > VT8500_MAX_PORTS)
@@ -593,6 +589,10 @@ static int __devinit vt8500_serial_probe(struct platform_device *pdev)
return -EBUSY;
}
+ vt8500_port = kzalloc(sizeof(struct vt8500_port), GFP_KERNEL);
+ if (!vt8500_port)
+ return -ENOMEM;
+
vt8500_port->uart.type = PORT_VT8500;
vt8500_port->uart.iotype = UPIO_MEM;
vt8500_port->uart.mapbase = mmres->start;
@@ -634,7 +634,7 @@ err:
return ret;
}
-static int __devexit vt8500_serial_remove(struct platform_device *pdev)
+static int vt8500_serial_remove(struct platform_device *pdev)
{
struct vt8500_port *vt8500_port = platform_get_drvdata(pdev);
@@ -652,7 +652,7 @@ static const struct of_device_id wmt_dt_ids[] = {
static struct platform_driver vt8500_platform_driver = {
.probe = vt8500_serial_probe,
- .remove = __devexit_p(vt8500_serial_remove),
+ .remove = vt8500_serial_remove,
.driver = {
.name = "vt8500_serial",
.owner = THIS_MODULE,
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index b627363352e..9ab910370c5 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -939,22 +939,18 @@ static struct uart_driver xuartps_uart_driver = {
*
* Returns 0 on success, negative error otherwise
**/
-static int __devinit xuartps_probe(struct platform_device *pdev)
+static int xuartps_probe(struct platform_device *pdev)
{
int rc;
struct uart_port *port;
struct resource *res, *res2;
int clk = 0;
-#ifdef CONFIG_OF
const unsigned int *prop;
prop = of_get_property(pdev->dev.of_node, "clock", NULL);
if (prop)
clk = be32_to_cpup(prop);
-#else
- clk = *((unsigned int *)(pdev->dev.platform_data));
-#endif
if (!clk) {
dev_err(&pdev->dev, "no clock specified\n");
return -ENODEV;
@@ -1001,7 +997,7 @@ static int __devinit xuartps_probe(struct platform_device *pdev)
*
* Returns 0 on success, negative error otherwise
**/
-static int __devexit xuartps_remove(struct platform_device *pdev)
+static int xuartps_remove(struct platform_device *pdev)
{
struct uart_port *port = dev_get_drvdata(&pdev->dev);
int rc = 0;
@@ -1044,16 +1040,11 @@ static int xuartps_resume(struct platform_device *pdev)
}
/* Match table for of_platform binding */
-
-#ifdef CONFIG_OF
-static struct of_device_id xuartps_of_match[] __devinitdata = {
+static struct of_device_id xuartps_of_match[] = {
{ .compatible = "xlnx,xuartps", },
{}
};
MODULE_DEVICE_TABLE(of, xuartps_of_match);
-#else
-#define xuartps_of_match NULL
-#endif
static struct platform_driver xuartps_platform_driver = {
.probe = xuartps_probe, /* Probe method */
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c
index 70e3a525bc8..9e071f6985f 100644
--- a/drivers/tty/synclink.c
+++ b/drivers/tty/synclink.c
@@ -898,7 +898,7 @@ static struct pci_driver synclink_pci_driver = {
.name = "synclink",
.id_table = synclink_pci_tbl,
.probe = synclink_init_one,
- .remove = __devexit_p(synclink_remove_one),
+ .remove = synclink_remove_one,
};
static struct tty_driver *serial_driver;
@@ -4425,6 +4425,7 @@ static void synclink_cleanup(void)
mgsl_release_resources(info);
tmp = info;
info = info->next_device;
+ tty_port_destroy(&tmp->port);
kfree(tmp);
}
@@ -8064,7 +8065,7 @@ static void hdlcdev_exit(struct mgsl_struct *info)
#endif /* CONFIG_HDLC */
-static int __devinit synclink_init_one (struct pci_dev *dev,
+static int synclink_init_one (struct pci_dev *dev,
const struct pci_device_id *ent)
{
struct mgsl_struct *info;
@@ -8116,7 +8117,7 @@ static int __devinit synclink_init_one (struct pci_dev *dev,
return 0;
}
-static void __devexit synclink_remove_one (struct pci_dev *dev)
+static void synclink_remove_one (struct pci_dev *dev)
{
}
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c
index b38e954eedd..aba1e59f4a8 100644
--- a/drivers/tty/synclink_gt.c
+++ b/drivers/tty/synclink_gt.c
@@ -110,7 +110,7 @@ static struct pci_driver pci_driver = {
.name = "synclink_gt",
.id_table = pci_table,
.probe = init_one,
- .remove = __devexit_p(remove_one),
+ .remove = remove_one,
};
static bool pci_registered;
@@ -3645,8 +3645,10 @@ static void device_init(int adapter_num, struct pci_dev *pdev)
for (i=0; i < port_count; ++i) {
port_array[i] = alloc_dev(adapter_num, i, pdev);
if (port_array[i] == NULL) {
- for (--i; i >= 0; --i)
+ for (--i; i >= 0; --i) {
+ tty_port_destroy(&port_array[i]->port);
kfree(port_array[i]);
+ }
return;
}
}
@@ -3696,7 +3698,7 @@ static void device_init(int adapter_num, struct pci_dev *pdev)
}
}
-static int __devinit init_one(struct pci_dev *dev,
+static int init_one(struct pci_dev *dev,
const struct pci_device_id *ent)
{
if (pci_enable_device(dev)) {
@@ -3708,7 +3710,7 @@ static int __devinit init_one(struct pci_dev *dev,
return 0;
}
-static void __devexit remove_one(struct pci_dev *dev)
+static void remove_one(struct pci_dev *dev)
{
}
@@ -3773,6 +3775,7 @@ static void slgt_cleanup(void)
release_resources(info);
tmp = info;
info = info->next_device;
+ tty_port_destroy(&tmp->port);
kfree(tmp);
}
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c
index f17d9f3d84a..fd43fb6f7ce 100644
--- a/drivers/tty/synclinkmp.c
+++ b/drivers/tty/synclinkmp.c
@@ -492,7 +492,7 @@ static struct pci_driver synclinkmp_pci_driver = {
.name = "synclinkmp",
.id_table = synclinkmp_pci_tbl,
.probe = synclinkmp_init_one,
- .remove = __devexit_p(synclinkmp_remove_one),
+ .remove = synclinkmp_remove_one,
};
@@ -3843,8 +3843,10 @@ static void device_init(int adapter_num, struct pci_dev *pdev)
for ( port = 0; port < SCA_MAX_PORTS; ++port ) {
port_array[port] = alloc_dev(adapter_num,port,pdev);
if( port_array[port] == NULL ) {
- for ( --port; port >= 0; --port )
+ for (--port; port >= 0; --port) {
+ tty_port_destroy(&port_array[port]->port);
kfree(port_array[port]);
+ }
return;
}
}
@@ -3953,6 +3955,7 @@ static void synclinkmp_cleanup(void)
}
tmp = info;
info = info->next_device;
+ tty_port_destroy(&tmp->port);
kfree(tmp);
}
@@ -5592,7 +5595,7 @@ static void write_control_reg(SLMP_INFO * info)
}
-static int __devinit synclinkmp_init_one (struct pci_dev *dev,
+static int synclinkmp_init_one (struct pci_dev *dev,
const struct pci_device_id *ent)
{
if (pci_enable_device(dev)) {
@@ -5603,6 +5606,6 @@ static int __devinit synclinkmp_init_one (struct pci_dev *dev,
return 0;
}
-static void __devexit synclinkmp_remove_one (struct pci_dev *dev)
+static void synclinkmp_remove_one (struct pci_dev *dev)
{
}
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 16ee6cee07d..b3c4a250ff8 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -346,7 +346,8 @@ static struct sysrq_key_op sysrq_term_op = {
static void moom_callback(struct work_struct *ignored)
{
- out_of_memory(node_zonelist(0, GFP_KERNEL), GFP_KERNEL, 0, NULL, true);
+ out_of_memory(node_zonelist(first_online_node, GFP_KERNEL), GFP_KERNEL,
+ 0, NULL, true);
}
static DECLARE_WORK(moom_work, moom_callback);
diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c
index b0b39b823cc..6953dc82850 100644
--- a/drivers/tty/tty_audit.c
+++ b/drivers/tty/tty_audit.c
@@ -23,7 +23,7 @@ struct tty_audit_buf {
};
static struct tty_audit_buf *tty_audit_buf_alloc(int major, int minor,
- int icanon)
+ unsigned icanon)
{
struct tty_audit_buf *buf;
@@ -239,7 +239,8 @@ int tty_audit_push_task(struct task_struct *tsk, kuid_t loginuid, u32 sessionid)
* if TTY auditing is disabled or out of memory. Otherwise, return a new
* reference to the buffer.
*/
-static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty)
+static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty,
+ unsigned icanon)
{
struct tty_audit_buf *buf, *buf2;
@@ -257,7 +258,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty)
buf2 = tty_audit_buf_alloc(tty->driver->major,
tty->driver->minor_start + tty->index,
- tty->icanon);
+ icanon);
if (buf2 == NULL) {
audit_log_lost("out of memory in TTY auditing");
return NULL;
@@ -287,7 +288,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty)
* Audit @data of @size from @tty, if necessary.
*/
void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
- size_t size)
+ size_t size, unsigned icanon)
{
struct tty_audit_buf *buf;
int major, minor;
@@ -299,7 +300,7 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
&& tty->driver->subtype == PTY_TYPE_MASTER)
return;
- buf = tty_audit_buf_get(tty);
+ buf = tty_audit_buf_get(tty, icanon);
if (!buf)
return;
@@ -307,11 +308,11 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
major = tty->driver->major;
minor = tty->driver->minor_start + tty->index;
if (buf->major != major || buf->minor != minor
- || buf->icanon != tty->icanon) {
+ || buf->icanon != icanon) {
tty_audit_buf_push_current(buf);
buf->major = major;
buf->minor = minor;
- buf->icanon = tty->icanon;
+ buf->icanon = icanon;
}
do {
size_t run;
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index 91e326ffe7d..45d916198f7 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -27,19 +27,21 @@
* Locking: none
*/
-void tty_buffer_free_all(struct tty_struct *tty)
+void tty_buffer_free_all(struct tty_port *port)
{
+ struct tty_bufhead *buf = &port->buf;
struct tty_buffer *thead;
- while ((thead = tty->buf.head) != NULL) {
- tty->buf.head = thead->next;
+
+ while ((thead = buf->head) != NULL) {
+ buf->head = thead->next;
kfree(thead);
}
- while ((thead = tty->buf.free) != NULL) {
- tty->buf.free = thead->next;
+ while ((thead = buf->free) != NULL) {
+ buf->free = thead->next;
kfree(thead);
}
- tty->buf.tail = NULL;
- tty->buf.memory_used = 0;
+ buf->tail = NULL;
+ buf->memory_used = 0;
}
/**
@@ -54,11 +56,11 @@ void tty_buffer_free_all(struct tty_struct *tty)
* Locking: Caller must hold tty->buf.lock
*/
-static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size)
+static struct tty_buffer *tty_buffer_alloc(struct tty_port *port, size_t size)
{
struct tty_buffer *p;
- if (tty->buf.memory_used + size > 65536)
+ if (port->buf.memory_used + size > 65536)
return NULL;
p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC);
if (p == NULL)
@@ -70,7 +72,7 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size)
p->read = 0;
p->char_buf_ptr = (char *)(p->data);
p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size;
- tty->buf.memory_used += size;
+ port->buf.memory_used += size;
return p;
}
@@ -85,17 +87,19 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size)
* Locking: Caller must hold tty->buf.lock
*/
-static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
+static void tty_buffer_free(struct tty_port *port, struct tty_buffer *b)
{
+ struct tty_bufhead *buf = &port->buf;
+
/* Dumb strategy for now - should keep some stats */
- tty->buf.memory_used -= b->size;
- WARN_ON(tty->buf.memory_used < 0);
+ buf->memory_used -= b->size;
+ WARN_ON(buf->memory_used < 0);
if (b->size >= 512)
kfree(b);
else {
- b->next = tty->buf.free;
- tty->buf.free = b;
+ b->next = buf->free;
+ buf->free = b;
}
}
@@ -110,15 +114,16 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
* Locking: Caller must hold tty->buf.lock
*/
-static void __tty_buffer_flush(struct tty_struct *tty)
+static void __tty_buffer_flush(struct tty_port *port)
{
+ struct tty_bufhead *buf = &port->buf;
struct tty_buffer *thead;
- while ((thead = tty->buf.head) != NULL) {
- tty->buf.head = thead->next;
- tty_buffer_free(tty, thead);
+ while ((thead = buf->head) != NULL) {
+ buf->head = thead->next;
+ tty_buffer_free(port, thead);
}
- tty->buf.tail = NULL;
+ buf->tail = NULL;
}
/**
@@ -134,21 +139,24 @@ static void __tty_buffer_flush(struct tty_struct *tty)
void tty_buffer_flush(struct tty_struct *tty)
{
+ struct tty_port *port = tty->port;
+ struct tty_bufhead *buf = &port->buf;
unsigned long flags;
- spin_lock_irqsave(&tty->buf.lock, flags);
+
+ spin_lock_irqsave(&buf->lock, flags);
/* If the data is being pushed to the tty layer then we can't
process it here. Instead set a flag and the flush_to_ldisc
path will process the flush request before it exits */
- if (test_bit(TTY_FLUSHING, &tty->flags)) {
- set_bit(TTY_FLUSHPENDING, &tty->flags);
- spin_unlock_irqrestore(&tty->buf.lock, flags);
+ if (test_bit(TTYP_FLUSHING, &port->iflags)) {
+ set_bit(TTYP_FLUSHPENDING, &port->iflags);
+ spin_unlock_irqrestore(&buf->lock, flags);
wait_event(tty->read_wait,
- test_bit(TTY_FLUSHPENDING, &tty->flags) == 0);
+ test_bit(TTYP_FLUSHPENDING, &port->iflags) == 0);
return;
} else
- __tty_buffer_flush(tty);
- spin_unlock_irqrestore(&tty->buf.lock, flags);
+ __tty_buffer_flush(port);
+ spin_unlock_irqrestore(&buf->lock, flags);
}
/**
@@ -163,9 +171,9 @@ void tty_buffer_flush(struct tty_struct *tty)
* Locking: Caller must hold tty->buf.lock
*/
-static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
+static struct tty_buffer *tty_buffer_find(struct tty_port *port, size_t size)
{
- struct tty_buffer **tbh = &tty->buf.free;
+ struct tty_buffer **tbh = &port->buf.free;
while ((*tbh) != NULL) {
struct tty_buffer *t = *tbh;
if (t->size >= size) {
@@ -174,14 +182,14 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
t->used = 0;
t->commit = 0;
t->read = 0;
- tty->buf.memory_used += t->size;
+ port->buf.memory_used += t->size;
return t;
}
tbh = &((*tbh)->next);
}
/* Round the buffer size out */
size = (size + 0xFF) & ~0xFF;
- return tty_buffer_alloc(tty, size);
+ return tty_buffer_alloc(port, size);
/* Should possibly check if this fails for the largest buffer we
have queued and recycle that ? */
}
@@ -192,29 +200,31 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
*
* Make at least size bytes of linear space available for the tty
* buffer. If we fail return the size we managed to find.
- * Locking: Caller must hold tty->buf.lock
+ * Locking: Caller must hold port->buf.lock
*/
-static int __tty_buffer_request_room(struct tty_struct *tty, size_t size)
+static int __tty_buffer_request_room(struct tty_port *port, size_t size)
{
+ struct tty_bufhead *buf = &port->buf;
struct tty_buffer *b, *n;
int left;
/* OPTIMISATION: We could keep a per tty "zero" sized buffer to
remove this conditional if its worth it. This would be invisible
to the callers */
- if ((b = tty->buf.tail) != NULL)
+ b = buf->tail;
+ if (b != NULL)
left = b->size - b->used;
else
left = 0;
if (left < size) {
/* This is the slow path - looking for new buffers to use */
- if ((n = tty_buffer_find(tty, size)) != NULL) {
+ if ((n = tty_buffer_find(port, size)) != NULL) {
if (b != NULL) {
b->next = n;
b->commit = b->used;
} else
- tty->buf.head = n;
- tty->buf.tail = n;
+ buf->head = n;
+ buf->tail = n;
} else
size = left;
}
@@ -231,16 +241,17 @@ static int __tty_buffer_request_room(struct tty_struct *tty, size_t size)
* Make at least size bytes of linear space available for the tty
* buffer. If we fail return the size we managed to find.
*
- * Locking: Takes tty->buf.lock
+ * Locking: Takes port->buf.lock
*/
int tty_buffer_request_room(struct tty_struct *tty, size_t size)
{
+ struct tty_port *port = tty->port;
unsigned long flags;
int length;
- spin_lock_irqsave(&tty->buf.lock, flags);
- length = __tty_buffer_request_room(tty, size);
- spin_unlock_irqrestore(&tty->buf.lock, flags);
+ spin_lock_irqsave(&port->buf.lock, flags);
+ length = __tty_buffer_request_room(port, size);
+ spin_unlock_irqrestore(&port->buf.lock, flags);
return length;
}
EXPORT_SYMBOL_GPL(tty_buffer_request_room);
@@ -255,12 +266,13 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room);
* Queue a series of bytes to the tty buffering. All the characters
* passed are marked with the supplied flag. Returns the number added.
*
- * Locking: Called functions may take tty->buf.lock
+ * Locking: Called functions may take port->buf.lock
*/
int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
const unsigned char *chars, char flag, size_t size)
{
+ struct tty_bufhead *buf = &tty->port->buf;
int copied = 0;
do {
int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
@@ -268,18 +280,18 @@ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
unsigned long flags;
struct tty_buffer *tb;
- spin_lock_irqsave(&tty->buf.lock, flags);
- space = __tty_buffer_request_room(tty, goal);
- tb = tty->buf.tail;
+ spin_lock_irqsave(&buf->lock, flags);
+ space = __tty_buffer_request_room(tty->port, goal);
+ tb = buf->tail;
/* If there is no space then tb may be NULL */
if (unlikely(space == 0)) {
- spin_unlock_irqrestore(&tty->buf.lock, flags);
+ spin_unlock_irqrestore(&buf->lock, flags);
break;
}
memcpy(tb->char_buf_ptr + tb->used, chars, space);
memset(tb->flag_buf_ptr + tb->used, flag, space);
tb->used += space;
- spin_unlock_irqrestore(&tty->buf.lock, flags);
+ spin_unlock_irqrestore(&buf->lock, flags);
copied += space;
chars += space;
/* There is a small chance that we need to split the data over
@@ -300,12 +312,13 @@ EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag);
* the flags array indicates the status of the character. Returns the
* number added.
*
- * Locking: Called functions may take tty->buf.lock
+ * Locking: Called functions may take port->buf.lock
*/
int tty_insert_flip_string_flags(struct tty_struct *tty,
const unsigned char *chars, const char *flags, size_t size)
{
+ struct tty_bufhead *buf = &tty->port->buf;
int copied = 0;
do {
int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
@@ -313,18 +326,18 @@ int tty_insert_flip_string_flags(struct tty_struct *tty,
unsigned long __flags;
struct tty_buffer *tb;
- spin_lock_irqsave(&tty->buf.lock, __flags);
- space = __tty_buffer_request_room(tty, goal);
- tb = tty->buf.tail;
+ spin_lock_irqsave(&buf->lock, __flags);
+ space = __tty_buffer_request_room(tty->port, goal);
+ tb = buf->tail;
/* If there is no space then tb may be NULL */
if (unlikely(space == 0)) {
- spin_unlock_irqrestore(&tty->buf.lock, __flags);
+ spin_unlock_irqrestore(&buf->lock, __flags);
break;
}
memcpy(tb->char_buf_ptr + tb->used, chars, space);
memcpy(tb->flag_buf_ptr + tb->used, flags, space);
tb->used += space;
- spin_unlock_irqrestore(&tty->buf.lock, __flags);
+ spin_unlock_irqrestore(&buf->lock, __flags);
copied += space;
chars += space;
flags += space;
@@ -342,18 +355,23 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags);
* Takes any pending buffers and transfers their ownership to the
* ldisc side of the queue. It then schedules those characters for
* processing by the line discipline.
+ * Note that this function can only be used when the low_latency flag
+ * is unset. Otherwise the workqueue won't be flushed.
*
- * Locking: Takes tty->buf.lock
+ * Locking: Takes port->buf.lock
*/
void tty_schedule_flip(struct tty_struct *tty)
{
+ struct tty_bufhead *buf = &tty->port->buf;
unsigned long flags;
- spin_lock_irqsave(&tty->buf.lock, flags);
- if (tty->buf.tail != NULL)
- tty->buf.tail->commit = tty->buf.tail->used;
- spin_unlock_irqrestore(&tty->buf.lock, flags);
- schedule_work(&tty->buf.work);
+ WARN_ON(tty->low_latency);
+
+ spin_lock_irqsave(&buf->lock, flags);
+ if (buf->tail != NULL)
+ buf->tail->commit = buf->tail->used;
+ spin_unlock_irqrestore(&buf->lock, flags);
+ schedule_work(&buf->work);
}
EXPORT_SYMBOL(tty_schedule_flip);
@@ -369,26 +387,27 @@ EXPORT_SYMBOL(tty_schedule_flip);
* that need their own block copy routines into the buffer. There is no
* guarantee the buffer is a DMA target!
*
- * Locking: May call functions taking tty->buf.lock
+ * Locking: May call functions taking port->buf.lock
*/
int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars,
- size_t size)
+ size_t size)
{
+ struct tty_bufhead *buf = &tty->port->buf;
int space;
unsigned long flags;
struct tty_buffer *tb;
- spin_lock_irqsave(&tty->buf.lock, flags);
- space = __tty_buffer_request_room(tty, size);
+ spin_lock_irqsave(&buf->lock, flags);
+ space = __tty_buffer_request_room(tty->port, size);
- tb = tty->buf.tail;
+ tb = buf->tail;
if (likely(space)) {
*chars = tb->char_buf_ptr + tb->used;
memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
tb->used += space;
}
- spin_unlock_irqrestore(&tty->buf.lock, flags);
+ spin_unlock_irqrestore(&buf->lock, flags);
return space;
}
EXPORT_SYMBOL_GPL(tty_prepare_flip_string);
@@ -406,26 +425,27 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string);
* that need their own block copy routines into the buffer. There is no
* guarantee the buffer is a DMA target!
*
- * Locking: May call functions taking tty->buf.lock
+ * Locking: May call functions taking port->buf.lock
*/
int tty_prepare_flip_string_flags(struct tty_struct *tty,
unsigned char **chars, char **flags, size_t size)
{
+ struct tty_bufhead *buf = &tty->port->buf;
int space;
unsigned long __flags;
struct tty_buffer *tb;
- spin_lock_irqsave(&tty->buf.lock, __flags);
- space = __tty_buffer_request_room(tty, size);
+ spin_lock_irqsave(&buf->lock, __flags);
+ space = __tty_buffer_request_room(tty->port, size);
- tb = tty->buf.tail;
+ tb = buf->tail;
if (likely(space)) {
*chars = tb->char_buf_ptr + tb->used;
*flags = tb->flag_buf_ptr + tb->used;
tb->used += space;
}
- spin_unlock_irqrestore(&tty->buf.lock, __flags);
+ spin_unlock_irqrestore(&buf->lock, __flags);
return space;
}
EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
@@ -446,20 +466,25 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
static void flush_to_ldisc(struct work_struct *work)
{
- struct tty_struct *tty =
- container_of(work, struct tty_struct, buf.work);
+ struct tty_port *port = container_of(work, struct tty_port, buf.work);
+ struct tty_bufhead *buf = &port->buf;
+ struct tty_struct *tty;
unsigned long flags;
struct tty_ldisc *disc;
+ tty = port->itty;
+ if (WARN_RATELIMIT(tty == NULL, "tty is NULL\n"))
+ return;
+
disc = tty_ldisc_ref(tty);
if (disc == NULL) /* !TTY_LDISC */
return;
- spin_lock_irqsave(&tty->buf.lock, flags);
+ spin_lock_irqsave(&buf->lock, flags);
- if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) {
+ if (!test_and_set_bit(TTYP_FLUSHING, &port->iflags)) {
struct tty_buffer *head;
- while ((head = tty->buf.head) != NULL) {
+ while ((head = buf->head) != NULL) {
int count;
char *char_buf;
unsigned char *flag_buf;
@@ -468,14 +493,14 @@ static void flush_to_ldisc(struct work_struct *work)
if (!count) {
if (head->next == NULL)
break;
- tty->buf.head = head->next;
- tty_buffer_free(tty, head);
+ buf->head = head->next;
+ tty_buffer_free(port, head);
continue;
}
/* Ldisc or user is trying to flush the buffers
we are feeding to the ldisc, stop feeding the
line discipline as we want to empty the queue */
- if (test_bit(TTY_FLUSHPENDING, &tty->flags))
+ if (test_bit(TTYP_FLUSHPENDING, &port->iflags))
break;
if (!tty->receive_room)
break;
@@ -484,22 +509,22 @@ static void flush_to_ldisc(struct work_struct *work)
char_buf = head->char_buf_ptr + head->read;
flag_buf = head->flag_buf_ptr + head->read;
head->read += count;
- spin_unlock_irqrestore(&tty->buf.lock, flags);
+ spin_unlock_irqrestore(&buf->lock, flags);
disc->ops->receive_buf(tty, char_buf,
flag_buf, count);
- spin_lock_irqsave(&tty->buf.lock, flags);
+ spin_lock_irqsave(&buf->lock, flags);
}
- clear_bit(TTY_FLUSHING, &tty->flags);
+ clear_bit(TTYP_FLUSHING, &port->iflags);
}
/* We may have a deferred request to flush the input buffer,
if so pull the chain under the lock and empty the queue */
- if (test_bit(TTY_FLUSHPENDING, &tty->flags)) {
- __tty_buffer_flush(tty);
- clear_bit(TTY_FLUSHPENDING, &tty->flags);
+ if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) {
+ __tty_buffer_flush(port);
+ clear_bit(TTYP_FLUSHPENDING, &port->iflags);
wake_up(&tty->read_wait);
}
- spin_unlock_irqrestore(&tty->buf.lock, flags);
+ spin_unlock_irqrestore(&buf->lock, flags);
tty_ldisc_deref(disc);
}
@@ -514,7 +539,8 @@ static void flush_to_ldisc(struct work_struct *work)
*/
void tty_flush_to_ldisc(struct tty_struct *tty)
{
- flush_work(&tty->buf.work);
+ if (!tty->low_latency)
+ flush_work(&tty->port->buf.work);
}
/**
@@ -532,16 +558,18 @@ void tty_flush_to_ldisc(struct tty_struct *tty)
void tty_flip_buffer_push(struct tty_struct *tty)
{
+ struct tty_bufhead *buf = &tty->port->buf;
unsigned long flags;
- spin_lock_irqsave(&tty->buf.lock, flags);
- if (tty->buf.tail != NULL)
- tty->buf.tail->commit = tty->buf.tail->used;
- spin_unlock_irqrestore(&tty->buf.lock, flags);
+
+ spin_lock_irqsave(&buf->lock, flags);
+ if (buf->tail != NULL)
+ buf->tail->commit = buf->tail->used;
+ spin_unlock_irqrestore(&buf->lock, flags);
if (tty->low_latency)
- flush_to_ldisc(&tty->buf.work);
+ flush_to_ldisc(&buf->work);
else
- schedule_work(&tty->buf.work);
+ schedule_work(&buf->work);
}
EXPORT_SYMBOL(tty_flip_buffer_push);
@@ -555,13 +583,15 @@ EXPORT_SYMBOL(tty_flip_buffer_push);
* Locking: none
*/
-void tty_buffer_init(struct tty_struct *tty)
+void tty_buffer_init(struct tty_port *port)
{
- spin_lock_init(&tty->buf.lock);
- tty->buf.head = NULL;
- tty->buf.tail = NULL;
- tty->buf.free = NULL;
- tty->buf.memory_used = 0;
- INIT_WORK(&tty->buf.work, flush_to_ldisc);
+ struct tty_bufhead *buf = &port->buf;
+
+ spin_lock_init(&buf->lock);
+ buf->head = NULL;
+ buf->tail = NULL;
+ buf->free = NULL;
+ buf->memory_used = 0;
+ INIT_WORK(&buf->work, flush_to_ldisc);
}
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 2ea176b2280..da9fde85075 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -186,7 +186,6 @@ void free_tty_struct(struct tty_struct *tty)
if (tty->dev)
put_device(tty->dev);
kfree(tty->write_buf);
- tty_buffer_free_all(tty);
tty->magic = 0xDEADDEAD;
kfree(tty);
}
@@ -237,7 +236,7 @@ void tty_free_file(struct file *file)
}
/* Delete file from its tty */
-void tty_del_file(struct file *file)
+static void tty_del_file(struct file *file)
{
struct tty_file_private *priv = file->private_data;
@@ -555,7 +554,7 @@ EXPORT_SYMBOL_GPL(tty_wakeup);
* tasklist_lock to walk task list for hangup event
* ->siglock to protect ->signal/->sighand
*/
-void __tty_hangup(struct tty_struct *tty)
+static void __tty_hangup(struct tty_struct *tty)
{
struct file *cons_filp = NULL;
struct file *filp, *f = NULL;
@@ -1417,6 +1416,8 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
"%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n",
__func__, tty->driver->name);
+ tty->port->itty = tty;
+
/*
* Structures all installed ... call the ldisc open routines.
* If we fail here just call release_tty to clean up. No need
@@ -1552,6 +1553,7 @@ static void release_tty(struct tty_struct *tty, int idx)
tty->ops->shutdown(tty);
tty_free_termios(tty);
tty_driver_remove_tty(tty->driver, tty);
+ tty->port->itty = NULL;
if (tty->link)
tty_kref_put(tty->link);
@@ -1625,7 +1627,6 @@ int tty_release(struct inode *inode, struct file *filp)
struct tty_struct *tty = file_tty(filp);
struct tty_struct *o_tty;
int pty_master, tty_closing, o_tty_closing, do_sleep;
- int devpts;
int idx;
char buf[64];
@@ -1640,7 +1641,6 @@ int tty_release(struct inode *inode, struct file *filp)
idx = tty->index;
pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
tty->driver->subtype == PTY_TYPE_MASTER);
- devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0;
/* Review: parallel close */
o_tty = tty->link;
@@ -1799,9 +1799,6 @@ int tty_release(struct inode *inode, struct file *filp)
release_tty(tty, idx);
mutex_unlock(&tty_mutex);
- /* Make this pty number available for reallocation */
- if (devpts)
- devpts_kill_index(inode, idx);
return 0;
}
@@ -2690,6 +2687,11 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case TIOCNXCL:
clear_bit(TTY_EXCLUSIVE, &tty->flags);
return 0;
+ case TIOCGEXCL:
+ {
+ int excl = test_bit(TTY_EXCLUSIVE, &tty->flags);
+ return put_user(excl, (int __user *)p);
+ }
case TIOCNOTTY:
if (current->signal->tty != tty)
return -ENOTTY;
@@ -2937,19 +2939,13 @@ void initialize_tty_struct(struct tty_struct *tty,
tty_ldisc_init(tty);
tty->session = NULL;
tty->pgrp = NULL;
- tty->overrun_time = jiffies;
- tty_buffer_init(tty);
mutex_init(&tty->legacy_mutex);
mutex_init(&tty->termios_mutex);
mutex_init(&tty->ldisc_mutex);
init_waitqueue_head(&tty->write_wait);
init_waitqueue_head(&tty->read_wait);
INIT_WORK(&tty->hangup_work, do_tty_hangup);
- mutex_init(&tty->atomic_read_lock);
mutex_init(&tty->atomic_write_lock);
- mutex_init(&tty->output_lock);
- mutex_init(&tty->echo_lock);
- spin_lock_init(&tty->read_lock);
spin_lock_init(&tty->ctrl_lock);
INIT_LIST_HEAD(&tty->tty_files);
INIT_WORK(&tty->SAK_work, do_SAK_work);
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c
index 12b1fa0f4f8..8481b29d5b3 100644
--- a/drivers/tty/tty_ioctl.c
+++ b/drivers/tty/tty_ioctl.c
@@ -1118,7 +1118,6 @@ EXPORT_SYMBOL_GPL(tty_perform_flush);
int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
- unsigned long flags;
int retval;
switch (cmd) {
@@ -1153,26 +1152,6 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
return 0;
case TCFLSH:
return tty_perform_flush(tty, arg);
- case TIOCPKT:
- {
- int pktmode;
-
- if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
- tty->driver->subtype != PTY_TYPE_MASTER)
- return -ENOTTY;
- if (get_user(pktmode, (int __user *) arg))
- return -EFAULT;
- spin_lock_irqsave(&tty->ctrl_lock, flags);
- if (pktmode) {
- if (!tty->packet) {
- tty->packet = 1;
- tty->link->ctrl_status = 0;
- }
- } else
- tty->packet = 0;
- spin_unlock_irqrestore(&tty->ctrl_lock, flags);
- return 0;
- }
default:
/* Try the mode commands */
return tty_mode_ioctl(tty, file, cmd, arg);
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 0f2a2c5e704..c5782294e53 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -26,7 +26,7 @@
* callers who will do ldisc lookups and cannot sleep.
*/
-static DEFINE_SPINLOCK(tty_ldisc_lock);
+static DEFINE_RAW_SPINLOCK(tty_ldisc_lock);
static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
/* Line disc dispatch table */
static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
@@ -49,21 +49,21 @@ static void put_ldisc(struct tty_ldisc *ld)
* If this is the last user, free the ldisc, and
* release the ldisc ops.
*
- * We really want an "atomic_dec_and_lock_irqsave()",
+ * We really want an "atomic_dec_and_raw_lock_irqsave()",
* but we don't have it, so this does it by hand.
*/
- local_irq_save(flags);
- if (atomic_dec_and_lock(&ld->users, &tty_ldisc_lock)) {
+ raw_spin_lock_irqsave(&tty_ldisc_lock, flags);
+ if (atomic_dec_and_test(&ld->users)) {
struct tty_ldisc_ops *ldo = ld->ops;
ldo->refcount--;
module_put(ldo->owner);
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags);
kfree(ld);
return;
}
- local_irq_restore(flags);
+ raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags);
wake_up(&ld->wq_idle);
}
@@ -88,11 +88,11 @@ int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
if (disc < N_TTY || disc >= NR_LDISCS)
return -EINVAL;
- spin_lock_irqsave(&tty_ldisc_lock, flags);
+ raw_spin_lock_irqsave(&tty_ldisc_lock, flags);
tty_ldiscs[disc] = new_ldisc;
new_ldisc->num = disc;
new_ldisc->refcount = 0;
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags);
return ret;
}
@@ -118,12 +118,12 @@ int tty_unregister_ldisc(int disc)
if (disc < N_TTY || disc >= NR_LDISCS)
return -EINVAL;
- spin_lock_irqsave(&tty_ldisc_lock, flags);
+ raw_spin_lock_irqsave(&tty_ldisc_lock, flags);
if (tty_ldiscs[disc]->refcount)
ret = -EBUSY;
else
tty_ldiscs[disc] = NULL;
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags);
return ret;
}
@@ -134,7 +134,7 @@ static struct tty_ldisc_ops *get_ldops(int disc)
unsigned long flags;
struct tty_ldisc_ops *ldops, *ret;
- spin_lock_irqsave(&tty_ldisc_lock, flags);
+ raw_spin_lock_irqsave(&tty_ldisc_lock, flags);
ret = ERR_PTR(-EINVAL);
ldops = tty_ldiscs[disc];
if (ldops) {
@@ -144,7 +144,7 @@ static struct tty_ldisc_ops *get_ldops(int disc)
ret = ldops;
}
}
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags);
return ret;
}
@@ -152,10 +152,10 @@ static void put_ldops(struct tty_ldisc_ops *ldops)
{
unsigned long flags;
- spin_lock_irqsave(&tty_ldisc_lock, flags);
+ raw_spin_lock_irqsave(&tty_ldisc_lock, flags);
ldops->refcount--;
module_put(ldops->owner);
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags);
}
/**
@@ -287,11 +287,11 @@ static struct tty_ldisc *tty_ldisc_try(struct tty_struct *tty)
unsigned long flags;
struct tty_ldisc *ld;
- spin_lock_irqsave(&tty_ldisc_lock, flags);
+ raw_spin_lock_irqsave(&tty_ldisc_lock, flags);
ld = NULL;
if (test_bit(TTY_LDISC, &tty->flags))
ld = get_ldisc(tty->ldisc);
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags);
return ld;
}
@@ -512,7 +512,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
static int tty_ldisc_halt(struct tty_struct *tty)
{
clear_bit(TTY_LDISC, &tty->flags);
- return cancel_work_sync(&tty->buf.work);
+ return cancel_work_sync(&tty->port->buf.work);
}
/**
@@ -525,7 +525,7 @@ static void tty_ldisc_flush_works(struct tty_struct *tty)
{
flush_work(&tty->hangup_work);
flush_work(&tty->SAK_work);
- flush_work(&tty->buf.work);
+ flush_work(&tty->port->buf.work);
}
/**
@@ -704,9 +704,9 @@ enable:
/* Restart the work queue in case no characters kick it off. Safe if
already running */
if (work)
- schedule_work(&tty->buf.work);
+ schedule_work(&tty->port->buf.work);
if (o_work)
- schedule_work(&o_tty->buf.work);
+ schedule_work(&o_tty->port->buf.work);
mutex_unlock(&tty->ldisc_mutex);
tty_unlock(tty);
return retval;
@@ -817,7 +817,7 @@ void tty_ldisc_hangup(struct tty_struct *tty)
*/
clear_bit(TTY_LDISC, &tty->flags);
tty_unlock(tty);
- cancel_work_sync(&tty->buf.work);
+ cancel_work_sync(&tty->port->buf.work);
mutex_unlock(&tty->ldisc_mutex);
retry:
tty_lock(tty);
@@ -897,6 +897,11 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
static void tty_ldisc_kill(struct tty_struct *tty)
{
+ /* There cannot be users from userspace now. But there still might be
+ * drivers holding a reference via tty_ldisc_ref. Do not steal them the
+ * ldisc until they are done. */
+ tty_ldisc_wait_idle(tty, MAX_SCHEDULE_TIMEOUT);
+
mutex_lock(&tty->ldisc_mutex);
/*
* Now kill off the ldisc
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c
index 67feac9e6eb..2e41abebbcb 100644
--- a/drivers/tty/tty_mutex.c
+++ b/drivers/tty/tty_mutex.c
@@ -19,7 +19,7 @@ static void __lockfunc tty_lock_nested(struct tty_struct *tty,
unsigned int subclass)
{
if (tty->magic != TTY_MAGIC) {
- printk(KERN_ERR "L Bad %p\n", tty);
+ pr_err("L Bad %p\n", tty);
WARN_ON(1);
return;
}
@@ -36,7 +36,7 @@ EXPORT_SYMBOL(tty_lock);
void __lockfunc tty_unlock(struct tty_struct *tty)
{
if (tty->magic != TTY_MAGIC) {
- printk(KERN_ERR "U Bad %p\n", tty);
+ pr_err("U Bad %p\n", tty);
WARN_ON(1);
return;
}
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index d7bdd8d0c23..b7ff59d3db8 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -21,6 +21,7 @@
void tty_port_init(struct tty_port *port)
{
memset(port, 0, sizeof(*port));
+ tty_buffer_init(port);
init_waitqueue_head(&port->open_wait);
init_waitqueue_head(&port->close_wait);
init_waitqueue_head(&port->delta_msr_wait);
@@ -121,12 +122,27 @@ void tty_port_free_xmit_buf(struct tty_port *port)
}
EXPORT_SYMBOL(tty_port_free_xmit_buf);
+/**
+ * tty_port_destroy -- destroy inited port
+ * @port: tty port to be doestroyed
+ *
+ * When a port was initialized using tty_port_init, one has to destroy the
+ * port by this function. Either indirectly by using tty_port refcounting
+ * (tty_port_put) or directly if refcounting is not used.
+ */
+void tty_port_destroy(struct tty_port *port)
+{
+ tty_buffer_free_all(port);
+}
+EXPORT_SYMBOL(tty_port_destroy);
+
static void tty_port_destructor(struct kref *kref)
{
struct tty_port *port = container_of(kref, struct tty_port, kref);
if (port->xmit_buf)
free_page((unsigned long)port->xmit_buf);
- if (port->ops->destruct)
+ tty_port_destroy(port);
+ if (port->ops && port->ops->destruct)
port->ops->destruct(port);
else
kfree(port);
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c
index 2aaa0c22840..248381b3072 100644
--- a/drivers/tty/vt/consolemap.c
+++ b/drivers/tty/vt/consolemap.c
@@ -410,10 +410,8 @@ static void con_release_unimap(struct uni_pagedir *p)
kfree(p->inverse_translations[i]);
p->inverse_translations[i] = NULL;
}
- if (p->inverse_trans_unicode) {
- kfree(p->inverse_trans_unicode);
- p->inverse_trans_unicode = NULL;
- }
+ kfree(p->inverse_trans_unicode);
+ p->inverse_trans_unicode = NULL;
}
/* Caller must hold the console lock */
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c
index 8e9b4be97a2..60b7b692605 100644
--- a/drivers/tty/vt/selection.c
+++ b/drivers/tty/vt/selection.c
@@ -341,15 +341,11 @@ int paste_selection(struct tty_struct *tty)
struct tty_ldisc *ld;
DECLARE_WAITQUEUE(wait, current);
-
console_lock();
poke_blanked_console();
console_unlock();
- /* FIXME: wtf is this supposed to achieve ? */
- ld = tty_ldisc_ref(tty);
- if (!ld)
- ld = tty_ldisc_ref_wait(tty);
+ ld = tty_ldisc_ref_wait(tty);
/* FIXME: this is completely unsafe */
add_wait_queue(&vc->paste_wait, &wait);
@@ -361,8 +357,7 @@ int paste_selection(struct tty_struct *tty)
}
count = sel_buffer_lth - pasted;
count = min(count, tty->receive_room);
- tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
- NULL, count);
+ ld->ops->receive_buf(tty, sel_buffer + pasted, NULL, count);
pasted += count;
}
remove_wait_queue(&vc->paste_wait, &wait);
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index f87d7e8964b..8fd89687d06 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -539,25 +539,25 @@ static void insert_char(struct vc_data *vc, unsigned int nr)
{
unsigned short *p = (unsigned short *) vc->vc_pos;
- scr_memmovew(p + nr, p, vc->vc_cols - vc->vc_x);
+ scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x) * 2);
scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
vc->vc_need_wrap = 0;
if (DO_UPDATE(vc))
do_update_region(vc, (unsigned long) p,
- (vc->vc_cols - vc->vc_x) / 2 + 1);
+ vc->vc_cols - vc->vc_x);
}
static void delete_char(struct vc_data *vc, unsigned int nr)
{
unsigned short *p = (unsigned short *) vc->vc_pos;
- scr_memcpyw(p, p + nr, vc->vc_cols - vc->vc_x - nr);
+ scr_memcpyw(p, p + nr, (vc->vc_cols - vc->vc_x - nr) * 2);
scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char,
nr * 2);
vc->vc_need_wrap = 0;
if (DO_UPDATE(vc))
do_update_region(vc, (unsigned long) p,
- (vc->vc_cols - vc->vc_x) / 2);
+ vc->vc_cols - vc->vc_x);
}
static int softcursor_original;
@@ -779,6 +779,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
con_set_default_unimap(vc);
vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
if (!vc->vc_screenbuf) {
+ tty_port_destroy(&vc->port);
kfree(vc);
vc_cons[currcons].d = NULL;
return -ENOMEM;
@@ -999,8 +1000,10 @@ void vc_deallocate(unsigned int currcons)
put_pid(vc->vt_pid);
module_put(vc->vc_sw->owner);
kfree(vc->vc_screenbuf);
- if (currcons >= MIN_NR_CONSOLES)
+ if (currcons >= MIN_NR_CONSOLES) {
+ tty_port_destroy(&vc->port);
kfree(vc);
+ }
vc_cons[currcons].d = NULL;
}
}
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index b841f56d2e6..98ff1735eaf 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -25,6 +25,7 @@
#include <linux/console.h>
#include <linux/consolemap.h>
#include <linux/signal.h>
+#include <linux/suspend.h>
#include <linux/timex.h>
#include <asm/io.h>
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index 6f3ea9bbc81..82e2b89d448 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -44,6 +44,22 @@ config UIO_PDRV_GENIRQ
If you don't know what to do here, say N.
+config UIO_DMEM_GENIRQ
+ tristate "Userspace platform driver with generic irq and dynamic memory"
+ help
+ Platform driver for Userspace I/O devices, including generic
+ interrupt handling code. Shared interrupts are not supported.
+
+ Memory regions can be specified with the same platform device
+ resources as the UIO_PDRV drivers, but dynamic regions can also
+ be specified.
+ The number and size of these regions is static,
+ but the memory allocation is not performed until
+ the associated device file is opened. The
+ memory is freed once the uio device is closed.
+
+ If you don't know what to do here, say N.
+
config UIO_AEC
tristate "AEC video timestamp device"
depends on PCI
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index d4dd9a5552f..b354c539507 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_UIO) += uio.o
obj-$(CONFIG_UIO_CIF) += uio_cif.o
obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o
obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o
+obj-$(CONFIG_UIO_DMEM_GENIRQ) += uio_dmem_genirq.o
obj-$(CONFIG_UIO_AEC) += uio_aec.o
obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o
obj-$(CONFIG_UIO_PCI_GENERIC) += uio_pci_generic.o
diff --git a/drivers/uio/uio_aec.c b/drivers/uio/uio_aec.c
index 72b22d44e8b..1548982db58 100644
--- a/drivers/uio/uio_aec.c
+++ b/drivers/uio/uio_aec.c
@@ -78,7 +78,7 @@ static void print_board_data(struct pci_dev *pdev, struct uio_info *i)
ioread8(i->priv + 0x07));
}
-static int __devinit probe(struct pci_dev *pdev, const struct pci_device_id *id)
+static int probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct uio_info *info;
int ret;
diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c
index a84a451159e..7dd6fc60539 100644
--- a/drivers/uio/uio_cif.c
+++ b/drivers/uio/uio_cif.c
@@ -40,7 +40,7 @@ static irqreturn_t hilscher_handler(int irq, struct uio_info *dev_info)
return IRQ_HANDLED;
}
-static int __devinit hilscher_pci_probe(struct pci_dev *dev,
+static int hilscher_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct uio_info *info;
@@ -112,7 +112,7 @@ static void hilscher_pci_remove(struct pci_dev *dev)
kfree (info);
}
-static struct pci_device_id hilscher_pci_ids[] __devinitdata = {
+static struct pci_device_id hilscher_pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_PLX,
.device = PCI_DEVICE_ID_PLX_9030,
diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c
new file mode 100644
index 00000000000..252434c9ea9
--- /dev/null
+++ b/drivers/uio/uio_dmem_genirq.c
@@ -0,0 +1,359 @@
+/*
+ * drivers/uio/uio_dmem_genirq.c
+ *
+ * Userspace I/O platform driver with generic IRQ handling code.
+ *
+ * Copyright (C) 2012 Damian Hobson-Garcia
+ *
+ * Based on uio_pdrv_genirq.c by 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/platform_device.h>
+#include <linux/uio_driver.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_data/uio_dmem_genirq.h>
+#include <linux/stringify.h>
+#include <linux/pm_runtime.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+
+#define DRIVER_NAME "uio_dmem_genirq"
+#define DMEM_MAP_ERROR (~0)
+
+struct uio_dmem_genirq_platdata {
+ struct uio_info *uioinfo;
+ spinlock_t lock;
+ unsigned long flags;
+ struct platform_device *pdev;
+ unsigned int dmem_region_start;
+ unsigned int num_dmem_regions;
+ void *dmem_region_vaddr[MAX_UIO_MAPS];
+ struct mutex alloc_lock;
+ unsigned int refcnt;
+};
+
+static int uio_dmem_genirq_open(struct uio_info *info, struct inode *inode)
+{
+ struct uio_dmem_genirq_platdata *priv = info->priv;
+ struct uio_mem *uiomem;
+ int ret = 0;
+ int dmem_region = priv->dmem_region_start;
+
+ uiomem = &priv->uioinfo->mem[priv->dmem_region_start];
+
+ mutex_lock(&priv->alloc_lock);
+ while (!priv->refcnt && uiomem < &priv->uioinfo->mem[MAX_UIO_MAPS]) {
+ void *addr;
+ if (!uiomem->size)
+ break;
+
+ addr = dma_alloc_coherent(&priv->pdev->dev, uiomem->size,
+ (dma_addr_t *)&uiomem->addr, GFP_KERNEL);
+ if (!addr) {
+ uiomem->addr = DMEM_MAP_ERROR;
+ }
+ priv->dmem_region_vaddr[dmem_region++] = addr;
+ ++uiomem;
+ }
+ priv->refcnt++;
+
+ mutex_unlock(&priv->alloc_lock);
+ /* Wait until the Runtime PM code has woken up the device */
+ pm_runtime_get_sync(&priv->pdev->dev);
+ return ret;
+}
+
+static int uio_dmem_genirq_release(struct uio_info *info, struct inode *inode)
+{
+ struct uio_dmem_genirq_platdata *priv = info->priv;
+ struct uio_mem *uiomem;
+ int dmem_region = priv->dmem_region_start;
+
+ /* Tell the Runtime PM code that the device has become idle */
+ pm_runtime_put_sync(&priv->pdev->dev);
+
+ uiomem = &priv->uioinfo->mem[priv->dmem_region_start];
+
+ mutex_lock(&priv->alloc_lock);
+
+ priv->refcnt--;
+ while (!priv->refcnt && uiomem < &priv->uioinfo->mem[MAX_UIO_MAPS]) {
+ if (!uiomem->size)
+ break;
+ if (priv->dmem_region_vaddr[dmem_region]) {
+ dma_free_coherent(&priv->pdev->dev, uiomem->size,
+ priv->dmem_region_vaddr[dmem_region],
+ uiomem->addr);
+ }
+ uiomem->addr = DMEM_MAP_ERROR;
+ ++dmem_region;
+ ++uiomem;
+ }
+
+ mutex_unlock(&priv->alloc_lock);
+ return 0;
+}
+
+static irqreturn_t uio_dmem_genirq_handler(int irq, struct uio_info *dev_info)
+{
+ struct uio_dmem_genirq_platdata *priv = dev_info->priv;
+
+ /* Just disable the interrupt in the interrupt controller, and
+ * remember the state so we can allow user space to enable it later.
+ */
+
+ if (!test_and_set_bit(0, &priv->flags))
+ disable_irq_nosync(irq);
+
+ return IRQ_HANDLED;
+}
+
+static int uio_dmem_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on)
+{
+ struct uio_dmem_genirq_platdata *priv = dev_info->priv;
+ unsigned long flags;
+
+ /* Allow user space to enable and disable the interrupt
+ * in the interrupt controller, but keep track of the
+ * state to prevent per-irq depth damage.
+ *
+ * Serialize this operation to support multiple tasks.
+ */
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (irq_on) {
+ if (test_and_clear_bit(0, &priv->flags))
+ enable_irq(dev_info->irq);
+ } else {
+ if (!test_and_set_bit(0, &priv->flags))
+ disable_irq(dev_info->irq);
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+static int uio_dmem_genirq_probe(struct platform_device *pdev)
+{
+ struct uio_dmem_genirq_pdata *pdata = pdev->dev.platform_data;
+ struct uio_info *uioinfo = &pdata->uioinfo;
+ struct uio_dmem_genirq_platdata *priv;
+ struct uio_mem *uiomem;
+ int ret = -EINVAL;
+ int i;
+
+ if (pdev->dev.of_node) {
+ int irq;
+
+ /* alloc uioinfo for one device */
+ uioinfo = kzalloc(sizeof(*uioinfo), GFP_KERNEL);
+ if (!uioinfo) {
+ ret = -ENOMEM;
+ dev_err(&pdev->dev, "unable to kmalloc\n");
+ goto bad2;
+ }
+ uioinfo->name = pdev->dev.of_node->name;
+ uioinfo->version = "devicetree";
+
+ /* Multiple IRQs are not supported */
+ irq = platform_get_irq(pdev, 0);
+ if (irq == -ENXIO)
+ uioinfo->irq = UIO_IRQ_NONE;
+ else
+ uioinfo->irq = irq;
+ }
+
+ if (!uioinfo || !uioinfo->name || !uioinfo->version) {
+ dev_err(&pdev->dev, "missing platform_data\n");
+ goto bad0;
+ }
+
+ if (uioinfo->handler || uioinfo->irqcontrol ||
+ uioinfo->irq_flags & IRQF_SHARED) {
+ dev_err(&pdev->dev, "interrupt configuration error\n");
+ goto bad0;
+ }
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ ret = -ENOMEM;
+ dev_err(&pdev->dev, "unable to kmalloc\n");
+ goto bad0;
+ }
+
+ dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+
+ priv->uioinfo = uioinfo;
+ spin_lock_init(&priv->lock);
+ priv->flags = 0; /* interrupt is enabled to begin with */
+ priv->pdev = pdev;
+ mutex_init(&priv->alloc_lock);
+
+ if (!uioinfo->irq) {
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to get IRQ\n");
+ goto bad0;
+ }
+ uioinfo->irq = ret;
+ }
+ uiomem = &uioinfo->mem[0];
+
+ for (i = 0; i < pdev->num_resources; ++i) {
+ struct resource *r = &pdev->resource[i];
+
+ if (r->flags != IORESOURCE_MEM)
+ continue;
+
+ if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
+ dev_warn(&pdev->dev, "device has more than "
+ __stringify(MAX_UIO_MAPS)
+ " I/O memory resources.\n");
+ break;
+ }
+
+ uiomem->memtype = UIO_MEM_PHYS;
+ uiomem->addr = r->start;
+ uiomem->size = resource_size(r);
+ ++uiomem;
+ }
+
+ priv->dmem_region_start = i;
+ priv->num_dmem_regions = pdata->num_dynamic_regions;
+
+ for (i = 0; i < pdata->num_dynamic_regions; ++i) {
+ if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
+ dev_warn(&pdev->dev, "device has more than "
+ __stringify(MAX_UIO_MAPS)
+ " dynamic and fixed memory regions.\n");
+ break;
+ }
+ uiomem->memtype = UIO_MEM_PHYS;
+ uiomem->addr = DMEM_MAP_ERROR;
+ uiomem->size = pdata->dynamic_region_sizes[i];
+ ++uiomem;
+ }
+
+ while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
+ uiomem->size = 0;
+ ++uiomem;
+ }
+
+ /* This driver requires no hardware specific kernel code to handle
+ * interrupts. Instead, the interrupt handler simply disables the
+ * interrupt in the interrupt controller. User space is responsible
+ * for performing hardware specific acknowledge and re-enabling of
+ * the interrupt in the interrupt controller.
+ *
+ * Interrupt sharing is not supported.
+ */
+
+ uioinfo->handler = uio_dmem_genirq_handler;
+ uioinfo->irqcontrol = uio_dmem_genirq_irqcontrol;
+ uioinfo->open = uio_dmem_genirq_open;
+ uioinfo->release = uio_dmem_genirq_release;
+ uioinfo->priv = priv;
+
+ /* Enable Runtime PM for this device:
+ * The device starts in suspended state to allow the hardware to be
+ * turned off by default. The Runtime PM bus code should power on the
+ * hardware and enable clocks at open().
+ */
+ pm_runtime_enable(&pdev->dev);
+
+ ret = uio_register_device(&pdev->dev, priv->uioinfo);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to register uio device\n");
+ goto bad1;
+ }
+
+ platform_set_drvdata(pdev, priv);
+ return 0;
+ bad1:
+ kfree(priv);
+ pm_runtime_disable(&pdev->dev);
+ bad0:
+ /* kfree uioinfo for OF */
+ if (pdev->dev.of_node)
+ kfree(uioinfo);
+ bad2:
+ return ret;
+}
+
+static int uio_dmem_genirq_remove(struct platform_device *pdev)
+{
+ struct uio_dmem_genirq_platdata *priv = platform_get_drvdata(pdev);
+
+ uio_unregister_device(priv->uioinfo);
+ pm_runtime_disable(&pdev->dev);
+
+ priv->uioinfo->handler = NULL;
+ priv->uioinfo->irqcontrol = NULL;
+
+ /* kfree uioinfo for OF */
+ if (pdev->dev.of_node)
+ kfree(priv->uioinfo);
+
+ kfree(priv);
+ return 0;
+}
+
+static int uio_dmem_genirq_runtime_nop(struct device *dev)
+{
+ /* Runtime PM callback shared between ->runtime_suspend()
+ * and ->runtime_resume(). Simply returns success.
+ *
+ * In this driver pm_runtime_get_sync() and pm_runtime_put_sync()
+ * are used at open() and release() time. This allows the
+ * Runtime PM code to turn off power to the device while the
+ * device is unused, ie before open() and after release().
+ *
+ * This Runtime PM callback does not need to save or restore
+ * any registers since user space is responsbile for hardware
+ * register reinitialization after open().
+ */
+ return 0;
+}
+
+static const struct dev_pm_ops uio_dmem_genirq_dev_pm_ops = {
+ .runtime_suspend = uio_dmem_genirq_runtime_nop,
+ .runtime_resume = uio_dmem_genirq_runtime_nop,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id uio_of_genirq_match[] = {
+ { /* empty for now */ },
+};
+MODULE_DEVICE_TABLE(of, uio_of_genirq_match);
+#else
+# define uio_of_genirq_match NULL
+#endif
+
+static struct platform_driver uio_dmem_genirq = {
+ .probe = uio_dmem_genirq_probe,
+ .remove = uio_dmem_genirq_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .pm = &uio_dmem_genirq_dev_pm_ops,
+ .of_match_table = uio_of_genirq_match,
+ },
+};
+
+module_platform_driver(uio_dmem_genirq);
+
+MODULE_AUTHOR("Damian Hobson-Garcia");
+MODULE_DESCRIPTION("Userspace I/O platform driver with dynamic memory.");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/uio/uio_netx.c b/drivers/uio/uio_netx.c
index a879fd5741f..6a4ba5e83e3 100644
--- a/drivers/uio/uio_netx.c
+++ b/drivers/uio/uio_netx.c
@@ -48,7 +48,7 @@ static irqreturn_t netx_handler(int irq, struct uio_info *dev_info)
return IRQ_HANDLED;
}
-static int __devinit netx_pci_probe(struct pci_dev *dev,
+static int netx_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct uio_info *info;
diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c
index 0bd08ef2b39..14aa10c1f6d 100644
--- a/drivers/uio/uio_pci_generic.c
+++ b/drivers/uio/uio_pci_generic.c
@@ -53,7 +53,7 @@ static irqreturn_t irqhandler(int irq, struct uio_info *info)
return IRQ_HANDLED;
}
-static int __devinit probe(struct pci_dev *pdev,
+static int probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct uio_pci_generic_dev *gdev;
diff --git a/drivers/uio/uio_pdrv.c b/drivers/uio/uio_pdrv.c
index 72d3646c736..39be9e06170 100644
--- a/drivers/uio/uio_pdrv.c
+++ b/drivers/uio/uio_pdrv.c
@@ -60,6 +60,7 @@ static int uio_pdrv_probe(struct platform_device *pdev)
uiomem->memtype = UIO_MEM_PHYS;
uiomem->addr = r->start;
uiomem->size = resource_size(r);
+ uiomem->name = r->name;
++uiomem;
}
diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
index 42202cd8315..c122bca669b 100644
--- a/drivers/uio/uio_pdrv_genirq.c
+++ b/drivers/uio/uio_pdrv_genirq.c
@@ -102,7 +102,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
int ret = -EINVAL;
int i;
- if (!uioinfo) {
+ if (pdev->dev.of_node) {
int irq;
/* alloc uioinfo for one device */
@@ -172,6 +172,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
uiomem->memtype = UIO_MEM_PHYS;
uiomem->addr = r->start;
uiomem->size = resource_size(r);
+ uiomem->name = r->name;
++uiomem;
}
diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c
index 33a7a273b45..cce0f78341c 100644
--- a/drivers/uio/uio_pruss.c
+++ b/drivers/uio/uio_pruss.c
@@ -112,7 +112,7 @@ static void pruss_cleanup(struct platform_device *dev,
kfree(gdev);
}
-static int __devinit pruss_probe(struct platform_device *dev)
+static int pruss_probe(struct platform_device *dev)
{
struct uio_info *p;
struct uio_pruss_dev *gdev;
@@ -209,7 +209,7 @@ out_free:
return ret;
}
-static int __devexit pruss_remove(struct platform_device *dev)
+static int pruss_remove(struct platform_device *dev)
{
struct uio_pruss_dev *gdev = platform_get_drvdata(dev);
@@ -220,7 +220,7 @@ static int __devexit pruss_remove(struct platform_device *dev)
static struct platform_driver pruss_driver = {
.probe = pruss_probe,
- .remove = __devexit_p(pruss_remove),
+ .remove = pruss_remove,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/uio/uio_sercos3.c b/drivers/uio/uio_sercos3.c
index a187fa14c5c..81a10a56312 100644
--- a/drivers/uio/uio_sercos3.c
+++ b/drivers/uio/uio_sercos3.c
@@ -116,7 +116,7 @@ static int sercos3_setup_iomem(struct pci_dev *dev, struct uio_info *info,
return 0;
}
-static int __devinit sercos3_pci_probe(struct pci_dev *dev,
+static int sercos3_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct uio_info *info;
@@ -197,7 +197,7 @@ static void sercos3_pci_remove(struct pci_dev *dev)
kfree(info);
}
-static struct pci_device_id sercos3_pci_ids[] __devinitdata = {
+static struct pci_device_id sercos3_pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_PLX,
.device = PCI_DEVICE_ID_PLX_9030,
diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c
index 6f3b6e26739..fe815ecd557 100644
--- a/drivers/usb/c67x00/c67x00-drv.c
+++ b/drivers/usb/c67x00/c67x00-drv.c
@@ -116,7 +116,7 @@ static irqreturn_t c67x00_irq(int irq, void *__dev)
/* ------------------------------------------------------------------------- */
-static int __devinit c67x00_drv_probe(struct platform_device *pdev)
+static int c67x00_drv_probe(struct platform_device *pdev)
{
struct c67x00_device *c67x00;
struct c67x00_platform_data *pdata;
@@ -191,7 +191,7 @@ static int __devinit c67x00_drv_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit c67x00_drv_remove(struct platform_device *pdev)
+static int c67x00_drv_remove(struct platform_device *pdev)
{
struct c67x00_device *c67x00 = platform_get_drvdata(pdev);
struct resource *res;
@@ -219,7 +219,7 @@ static int __devexit c67x00_drv_remove(struct platform_device *pdev)
static struct platform_driver c67x00_driver = {
.probe = c67x00_drv_probe,
- .remove = __devexit_p(c67x00_drv_remove),
+ .remove = c67x00_drv_remove,
.driver = {
.owner = THIS_MODULE,
.name = "c67x00",
diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig
index 1ea932a1368..608a2aeb400 100644
--- a/drivers/usb/chipidea/Kconfig
+++ b/drivers/usb/chipidea/Kconfig
@@ -20,6 +20,7 @@ config USB_CHIPIDEA_UDC
config USB_CHIPIDEA_HOST
bool "ChipIdea host controller"
depends on USB=y || USB=USB_CHIPIDEA
+ depends on USB_EHCI_HCD
select USB_EHCI_ROOT_HUB_TT
help
Say Y here to enable host controller functionality of the
diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c
index 0f5ca4bea17..8c291220be7 100644
--- a/drivers/usb/chipidea/ci13xxx_imx.c
+++ b/drivers/usb/chipidea/ci13xxx_imx.c
@@ -85,7 +85,7 @@ EXPORT_SYMBOL_GPL(usbmisc_get_init_data);
/* End of common functions shared by usbmisc drivers*/
-static struct ci13xxx_platform_data ci13xxx_imx_platdata __devinitdata = {
+static struct ci13xxx_platform_data ci13xxx_imx_platdata = {
.name = "ci13xxx_imx",
.flags = CI13XXX_REQUIRE_TRANSCEIVER |
CI13XXX_PULLUP_ON_VBUS |
@@ -93,7 +93,7 @@ static struct ci13xxx_platform_data ci13xxx_imx_platdata __devinitdata = {
.capoffset = DEF_CAPOFFSET,
};
-static int __devinit ci13xxx_imx_probe(struct platform_device *pdev)
+static int ci13xxx_imx_probe(struct platform_device *pdev)
{
struct ci13xxx_imx_data *data;
struct platform_device *plat_ci, *phy_pdev;
@@ -220,7 +220,7 @@ put_np:
return ret;
}
-static int __devexit ci13xxx_imx_remove(struct platform_device *pdev)
+static int ci13xxx_imx_remove(struct platform_device *pdev)
{
struct ci13xxx_imx_data *data = platform_get_drvdata(pdev);
@@ -252,7 +252,7 @@ MODULE_DEVICE_TABLE(of, ci13xxx_imx_dt_ids);
static struct platform_driver ci13xxx_imx_driver = {
.probe = ci13xxx_imx_probe,
- .remove = __devexit_p(ci13xxx_imx_remove),
+ .remove = ci13xxx_imx_remove,
.driver = {
.name = "imx_usb",
.owner = THIS_MODULE,
diff --git a/drivers/usb/chipidea/ci13xxx_msm.c b/drivers/usb/chipidea/ci13xxx_msm.c
index b01feb3be92..7d16681fd3d 100644
--- a/drivers/usb/chipidea/ci13xxx_msm.c
+++ b/drivers/usb/chipidea/ci13xxx_msm.c
@@ -55,7 +55,7 @@ static struct ci13xxx_platform_data ci13xxx_msm_platdata = {
.notify_event = ci13xxx_msm_notify_event,
};
-static int __devinit ci13xxx_msm_probe(struct platform_device *pdev)
+static int ci13xxx_msm_probe(struct platform_device *pdev)
{
struct platform_device *plat_ci;
@@ -77,7 +77,7 @@ static int __devinit ci13xxx_msm_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit ci13xxx_msm_remove(struct platform_device *pdev)
+static int ci13xxx_msm_remove(struct platform_device *pdev)
{
struct platform_device *plat_ci = platform_get_drvdata(pdev);
@@ -89,7 +89,7 @@ static int __devexit ci13xxx_msm_remove(struct platform_device *pdev)
static struct platform_driver ci13xxx_msm_driver = {
.probe = ci13xxx_msm_probe,
- .remove = __devexit_p(ci13xxx_msm_remove),
+ .remove = ci13xxx_msm_remove,
.driver = { .name = "msm_hsusb", },
};
diff --git a/drivers/usb/chipidea/ci13xxx_pci.c b/drivers/usb/chipidea/ci13xxx_pci.c
index 918e14971f2..9b227e39299 100644
--- a/drivers/usb/chipidea/ci13xxx_pci.c
+++ b/drivers/usb/chipidea/ci13xxx_pci.c
@@ -48,7 +48,7 @@ struct ci13xxx_platform_data penwell_pci_platdata = {
* Allocates basic PCI resources for this USB device controller, and then
* invokes the udc_probe() method to start the UDC associated with it
*/
-static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev,
+static int ci13xxx_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct ci13xxx_platform_data *platdata = (void *)id->driver_data;
@@ -107,7 +107,7 @@ static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev,
* first invoking the udc_remove() and then releases
* all PCI resources allocated for this USB device controller
*/
-static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev)
+static void ci13xxx_pci_remove(struct pci_dev *pdev)
{
struct platform_device *plat_ci = pci_get_drvdata(pdev);
@@ -147,7 +147,7 @@ static struct pci_driver ci13xxx_pci_driver = {
.name = UDC_DRIVER_NAME,
.id_table = ci13xxx_pci_id_table,
.probe = ci13xxx_pci_probe,
- .remove = __devexit_p(ci13xxx_pci_remove),
+ .remove = ci13xxx_pci_remove,
};
module_pci_driver(ci13xxx_pci_driver);
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index f69d029b460..aebf695a934 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -385,12 +385,13 @@ EXPORT_SYMBOL_GPL(ci13xxx_add_device);
void ci13xxx_remove_device(struct platform_device *pdev)
{
+ int id = pdev->id;
platform_device_unregister(pdev);
- ida_simple_remove(&ci_ida, pdev->id);
+ ida_simple_remove(&ci_ida, id);
}
EXPORT_SYMBOL_GPL(ci13xxx_remove_device);
-static int __devinit ci_hdrc_probe(struct platform_device *pdev)
+static int ci_hdrc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ci13xxx *ci;
@@ -508,7 +509,7 @@ rm_wq:
return ret;
}
-static int __devexit ci_hdrc_remove(struct platform_device *pdev)
+static int ci_hdrc_remove(struct platform_device *pdev)
{
struct ci13xxx *ci = platform_get_drvdata(pdev);
@@ -523,7 +524,7 @@ static int __devexit ci_hdrc_remove(struct platform_device *pdev)
static struct platform_driver ci_hdrc_driver = {
.probe = ci_hdrc_probe,
- .remove = __devexit_p(ci_hdrc_remove),
+ .remove = ci_hdrc_remove,
.driver = {
.name = "ci_hdrc",
},
diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c
index c6f50a25756..3bc244d2636 100644
--- a/drivers/usb/chipidea/debug.c
+++ b/drivers/usb/chipidea/debug.c
@@ -160,9 +160,6 @@ static ssize_t show_device(struct device *dev, struct device_attribute *attr,
gadget->speed);
n += scnprintf(buf + n, PAGE_SIZE - n, "max_speed = %d\n",
gadget->max_speed);
- /* TODO: Scheduled for removal in 3.8. */
- n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n",
- gadget_is_dualspeed(gadget));
n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n",
gadget->is_otg);
n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n",
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index ebff9f4f56e..caecad9213f 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -20,77 +20,18 @@
*/
#include <linux/kernel.h>
+#include <linux/io.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/usb/chipidea.h>
-#define CHIPIDEA_EHCI
-#include "../host/ehci-hcd.c"
+#include "../host/ehci.h"
#include "ci.h"
#include "bits.h"
#include "host.h"
-static int ci_ehci_setup(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int ret;
-
- hcd->has_tt = 1;
-
- ret = ehci_setup(hcd);
- if (ret)
- return ret;
-
- ehci_port_power(ehci, 0);
-
- return ret;
-}
-
-static const struct hc_driver ci_ehci_hc_driver = {
- .description = "ehci_hcd",
- .product_desc = "ChipIdea HDRC EHCI",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
-
- /*
- * basic lifecycle operations
- */
- .reset = ci_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,
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
+static struct hc_driver __read_mostly ci_ehci_hc_driver;
static irqreturn_t host_irq(struct ci13xxx *ci)
{
@@ -157,5 +98,7 @@ int ci_hdrc_host_init(struct ci13xxx *ci)
rdrv->name = "host";
ci->roles[CI_ROLE_HOST] = rdrv;
+ ehci_init_driver(&ci_ehci_hc_driver, NULL);
+
return 0;
}
diff --git a/drivers/usb/chipidea/usbmisc_imx6q.c b/drivers/usb/chipidea/usbmisc_imx6q.c
index 416e3fc58fd..845efe29e6b 100644
--- a/drivers/usb/chipidea/usbmisc_imx6q.c
+++ b/drivers/usb/chipidea/usbmisc_imx6q.c
@@ -82,7 +82,7 @@ static const struct of_device_id usbmisc_imx6q_dt_ids[] = {
{ /* sentinel */ }
};
-static int __devinit usbmisc_imx6q_probe(struct platform_device *pdev)
+static int usbmisc_imx6q_probe(struct platform_device *pdev)
{
struct resource *res;
struct imx6q_usbmisc *data;
@@ -127,7 +127,7 @@ static int __devinit usbmisc_imx6q_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit usbmisc_imx6q_remove(struct platform_device *pdev)
+static int usbmisc_imx6q_remove(struct platform_device *pdev)
{
usbmisc_unset_ops(&imx6q_usbmisc_ops);
clk_disable_unprepare(usbmisc->clk);
@@ -136,7 +136,7 @@ static int __devexit usbmisc_imx6q_remove(struct platform_device *pdev)
static struct platform_driver usbmisc_imx6q_driver = {
.probe = usbmisc_imx6q_probe,
- .remove = __devexit_p(usbmisc_imx6q_remove),
+ .remove = usbmisc_imx6q_remove,
.driver = {
.name = "usbmisc_imx6q",
.owner = THIS_MODULE,
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 6e49ec6f3ad..8d809a811e1 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -787,6 +787,10 @@ static int get_serial_info(struct acm *acm, struct serial_struct __user *info)
tmp.flags = ASYNC_LOW_LATENCY;
tmp.xmit_fifo_size = acm->writesize;
tmp.baud_base = le32_to_cpu(acm->line.dwDTERate);
+ tmp.close_delay = acm->port.close_delay / 10;
+ tmp.closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
+ ASYNC_CLOSING_WAIT_NONE :
+ acm->port.closing_wait / 10;
if (copy_to_user(info, &tmp, sizeof(tmp)))
return -EFAULT;
@@ -794,6 +798,37 @@ static int get_serial_info(struct acm *acm, struct serial_struct __user *info)
return 0;
}
+static int set_serial_info(struct acm *acm,
+ struct serial_struct __user *newinfo)
+{
+ struct serial_struct new_serial;
+ unsigned int closing_wait, close_delay;
+ int retval = 0;
+
+ if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
+ return -EFAULT;
+
+ close_delay = new_serial.close_delay * 10;
+ closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
+ ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10;
+
+ mutex_lock(&acm->port.mutex);
+
+ if (!capable(CAP_SYS_ADMIN)) {
+ if ((close_delay != acm->port.close_delay) ||
+ (closing_wait != acm->port.closing_wait))
+ retval = -EPERM;
+ else
+ retval = -EOPNOTSUPP;
+ } else {
+ acm->port.close_delay = close_delay;
+ acm->port.closing_wait = closing_wait;
+ }
+
+ mutex_unlock(&acm->port.mutex);
+ return retval;
+}
+
static int acm_tty_ioctl(struct tty_struct *tty,
unsigned int cmd, unsigned long arg)
{
@@ -804,6 +839,9 @@ static int acm_tty_ioctl(struct tty_struct *tty,
case TIOCGSERIAL: /* gets serial port data */
rv = get_serial_info(acm, (struct serial_struct __user *) arg);
break;
+ case TIOCSSERIAL:
+ rv = set_serial_info(acm, (struct serial_struct __user *) arg);
+ break;
}
return rv;
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index f460de31ace..cbacea933b1 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -591,16 +591,14 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
/* Now look at all of this device's children. */
usb_hub_for_each_child(usbdev, chix, childdev) {
- if (childdev) {
- usb_lock_device(childdev);
- ret = usb_device_dump(buffer, nbytes, skip_bytes,
- file_offset, childdev, bus,
- level + 1, chix - 1, ++cnt);
- usb_unlock_device(childdev);
- if (ret == -EFAULT)
- return total_written;
- total_written += ret;
- }
+ usb_lock_device(childdev);
+ ret = usb_device_dump(buffer, nbytes, skip_bytes,
+ file_offset, childdev, bus,
+ level + 1, chix - 1, ++cnt);
+ usb_unlock_device(childdev);
+ if (ret == -EFAULT)
+ return total_written;
+ total_written += ret;
}
return total_written;
}
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 6056db7af41..88dde95b679 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -32,8 +32,6 @@
#include "usb.h"
-#ifdef CONFIG_HOTPLUG
-
/*
* Adds a new dynamic USBdevice ID to this driver,
* and cause the driver to probe for all devices again.
@@ -194,20 +192,6 @@ static void usb_free_dynids(struct usb_driver *usb_drv)
}
spin_unlock(&usb_drv->dynids.lock);
}
-#else
-static inline int usb_create_newid_files(struct usb_driver *usb_drv)
-{
- return 0;
-}
-
-static void usb_remove_newid_files(struct usb_driver *usb_drv)
-{
-}
-
-static inline void usb_free_dynids(struct usb_driver *usb_drv)
-{
-}
-#endif
static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf,
struct usb_driver *drv)
@@ -790,7 +774,6 @@ static int usb_device_match(struct device *dev, struct device_driver *drv)
return 0;
}
-#ifdef CONFIG_HOTPLUG
static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct usb_device *usb_dev;
@@ -832,14 +815,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
return 0;
}
-#else
-
-static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- return -ENODEV;
-}
-#endif /* CONFIG_HOTPLUG */
-
/**
* usb_register_device_driver - register a USB device (not interface) driver
* @new_udriver: USB operations for the device driver
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index 69ecd3c9231..eff2010eb63 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -47,6 +47,9 @@ int usb_choose_configuration(struct usb_device *udev)
int insufficient_power = 0;
struct usb_host_config *c, *best;
+ if (usb_device_is_owned(udev))
+ return 0;
+
best = NULL;
c = udev->config;
num_configs = udev->descriptor.bNumConfigurations;
@@ -160,9 +163,7 @@ static int generic_probe(struct usb_device *udev)
/* Choose and set the configuration. This registers the interfaces
* with the driver core and lets interface drivers bind to them.
*/
- if (usb_device_is_owned(udev))
- ; /* Don't configure if the device is owned */
- else if (udev->authorized == 0)
+ if (udev->authorized == 0)
dev_err(&udev->dev, "Device is not authorized for usage\n");
else {
c = usb_choose_configuration(udev);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 1e741bca026..4225d5e7213 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2039,8 +2039,9 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
status = hcd->driver->bus_resume(hcd);
clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
if (status == 0) {
- /* TRSMRCY = 10 msec */
- msleep(10);
+ struct usb_device *udev;
+ int port1;
+
spin_lock_irq(&hcd_root_hub_lock);
if (!HCD_DEAD(hcd)) {
usb_set_device_state(rhdev, rhdev->actconfig
@@ -2050,6 +2051,20 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
hcd->state = HC_STATE_RUNNING;
}
spin_unlock_irq(&hcd_root_hub_lock);
+
+ /*
+ * Check whether any of the enabled ports on the root hub are
+ * unsuspended. If they are then a TRSMRCY delay is needed
+ * (this is what the USB-2 spec calls a "global resume").
+ * Otherwise we can skip the delay.
+ */
+ usb_hub_for_each_child(rhdev, port1, udev) {
+ if (udev->state != USB_STATE_NOTATTACHED &&
+ !udev->port_is_suspended) {
+ usleep_range(10000, 11000); /* TRSMRCY */
+ break;
+ }
+ }
} else {
hcd->state = old_state;
dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
@@ -2151,8 +2166,15 @@ 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)
@@ -2160,6 +2182,7 @@ 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);
@@ -2347,6 +2370,14 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd,
int retval;
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,
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 1af04bdeaf0..a815fd2cc5e 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -39,6 +39,9 @@
#endif
#endif
+#define USB_VENDOR_GENESYS_LOGIC 0x05e3
+#define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01
+
struct usb_port {
struct usb_device *child;
struct device dev;
@@ -86,6 +89,8 @@ struct usb_hub {
unsigned quiescing:1;
unsigned disconnected:1;
+ unsigned quirk_check_port_auto_suspend:1;
+
unsigned has_indicators:1;
u8 indicator[USB_MAXCHILDREN];
struct delayed_work leds;
@@ -736,7 +741,6 @@ static void hub_tt_work(struct work_struct *work)
struct usb_hub *hub =
container_of(work, struct usb_hub, tt.clear_work);
unsigned long flags;
- int limit = 100;
spin_lock_irqsave (&hub->tt.lock, flags);
while (!list_empty(&hub->tt.clear_list)) {
@@ -746,9 +750,6 @@ static void hub_tt_work(struct work_struct *work)
const struct hc_driver *drv;
int status;
- if (!hub->quiescing && --limit < 0)
- break;
-
next = hub->tt.clear_list.next;
clear = list_entry (next, struct usb_tt_clear, clear_list);
list_del (&clear->clear_list);
@@ -1612,6 +1613,41 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
desc = intf->cur_altsetting;
hdev = interface_to_usbdev(intf);
+ /*
+ * Set default autosuspend delay as 0 to speedup bus suspend,
+ * based on the below considerations:
+ *
+ * - Unlike other drivers, the hub driver does not rely on the
+ * autosuspend delay to provide enough time to handle a wakeup
+ * event, and the submitted status URB is just to check future
+ * change on hub downstream ports, so it is safe to do it.
+ *
+ * - The patch might cause one or more auto supend/resume for
+ * below very rare devices when they are plugged into hub
+ * first time:
+ *
+ * devices having trouble initializing, and disconnect
+ * themselves from the bus and then reconnect a second
+ * or so later
+ *
+ * devices just for downloading firmware, and disconnects
+ * themselves after completing it
+ *
+ * For these quite rare devices, their drivers may change the
+ * autosuspend delay of their parent hub in the probe() to one
+ * appropriate value to avoid the subtle problem if someone
+ * does care it.
+ *
+ * - The patch may cause one or more auto suspend/resume on
+ * hub during running 'lsusb', but it is probably too
+ * infrequent to worry about.
+ *
+ * - Change autosuspend delay of hub can avoid unnecessary auto
+ * suspend timer for hub, also may decrease power consumption
+ * of USB bus.
+ */
+ pm_runtime_set_autosuspend_delay(&hdev->dev, 0);
+
/* Hubs have proper suspend/resume support. */
usb_enable_autosuspend(hdev);
@@ -1670,6 +1706,9 @@ descriptor_error:
if (hdev->speed == USB_SPEED_HIGH)
highspeed_hubs++;
+ if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND)
+ hub->quirk_check_port_auto_suspend = 1;
+
if (hub_configure(hub, endpoint) >= 0)
return 0;
@@ -2012,7 +2051,7 @@ static void show_string(struct usb_device *udev, char *id, char *string)
{
if (!string)
return;
- dev_printk(KERN_INFO, &udev->dev, "%s: %s\n", id, string);
+ dev_info(&udev->dev, "%s: %s\n", id, string);
}
static void announce_device(struct usb_device *udev)
@@ -2879,6 +2918,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
(PMSG_IS_AUTO(msg) ? "auto-" : ""),
udev->do_remote_wakeup);
usb_set_device_state(udev, USB_STATE_SUSPENDED);
+ udev->port_is_suspended = 1;
msleep(10);
}
usb_mark_last_busy(hub->hdev);
@@ -3043,6 +3083,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
SuspendCleared:
if (status == 0) {
+ udev->port_is_suspended = 0;
if (hub_is_superspeed(hub->hdev)) {
if (portchange & USB_PORT_STAT_C_LINK_STATE)
clear_port_feature(hub->hdev, port1,
@@ -3126,6 +3167,21 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
#endif
+static int check_ports_changed(struct usb_hub *hub)
+{
+ int port1;
+
+ for (port1 = 1; port1 <= hub->hdev->maxchild; ++port1) {
+ u16 portstatus, portchange;
+ int status;
+
+ status = hub_port_status(hub, port1, &portstatus, &portchange);
+ if (!status && portchange)
+ return 1;
+ }
+ return 0;
+}
+
static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
{
struct usb_hub *hub = usb_get_intfdata (intf);
@@ -3144,6 +3200,16 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
return -EBUSY;
}
}
+
+ if (hdev->do_remote_wakeup && hub->quirk_check_port_auto_suspend) {
+ /* check if there are changes pending on hub ports */
+ if (check_ports_changed(hub)) {
+ if (PMSG_IS_AUTO(msg))
+ return -EBUSY;
+ pm_wakeup_event(&hdev->dev, 2000);
+ }
+ }
+
if (hub_is_superspeed(hdev) && hdev->do_remote_wakeup) {
/* Enable hub to send remote wakeup for all ports. */
for (port1 = 1; port1 <= hdev->maxchild; port1++) {
@@ -3972,6 +4038,9 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
if (retval)
goto fail;
+ if (hcd->phy && !hdev->parent)
+ usb_phy_notify_connect(hcd->phy, udev->speed);
+
/*
* Some superspeed devices have finished the link training process
* and attached to a superspeed hub port, but the device descriptor
@@ -4166,8 +4235,12 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
}
/* Disconnect any existing devices under this port */
- if (udev)
+ if (udev) {
+ if (hcd->phy && !hdev->parent &&
+ !(portstatus & USB_PORT_STAT_CONNECTION))
+ usb_phy_notify_disconnect(hcd->phy, udev->speed);
usb_disconnect(&hub->ports[port1 - 1]->child);
+ }
clear_bit(port1, hub->change_bits);
/* We can forget about a "removed" device when there's a physical
@@ -4190,13 +4263,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
}
}
- if (hcd->phy && !hdev->parent) {
- if (portstatus & USB_PORT_STAT_CONNECTION)
- usb_phy_notify_connect(hcd->phy, port1);
- else
- usb_phy_notify_disconnect(hcd->phy, port1);
- }
-
/* Return now if debouncing failed or nothing is connected or
* the device was "removed".
*/
@@ -4648,6 +4714,11 @@ 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,
+ .idVendor = USB_VENDOR_GENESYS_LOGIC,
+ .bInterfaceClass = USB_CLASS_HUB,
+ .driver_info = HUB_QUIRK_CHECK_PORT_AUTOSUSPEND},
{ .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,
.bDeviceClass = USB_CLASS_HUB},
{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 1ed5afd91e6..131f73649b6 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1540,7 +1540,6 @@ static void usb_release_interface(struct device *dev)
kfree(intf);
}
-#ifdef CONFIG_HOTPLUG
static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct usb_device *usb_dev;
@@ -1575,14 +1574,6 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
return 0;
}
-#else
-
-static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- return -ENODEV;
-}
-#endif /* CONFIG_HOTPLUG */
-
struct device_type usb_if_device_type = {
.name = "usb_interface",
.release = usb_release_interface,
@@ -1795,7 +1786,8 @@ free_interfaces:
if (dev->actconfig && usb_disable_lpm(dev)) {
dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__);
mutex_unlock(hcd->bandwidth_mutex);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto free_interfaces;
}
ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
if (ret < 0) {
@@ -1806,29 +1798,8 @@ free_interfaces:
goto free_interfaces;
}
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
- NULL, 0, USB_CTRL_SET_TIMEOUT);
- if (ret < 0) {
- /* All the old state is gone, so what else can we do?
- * The device is probably useless now anyway.
- */
- cp = NULL;
- }
-
- dev->actconfig = cp;
- if (!cp) {
- usb_set_device_state(dev, USB_STATE_ADDRESS);
- usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
- /* Leave LPM disabled while the device is unconfigured. */
- mutex_unlock(hcd->bandwidth_mutex);
- usb_autosuspend_device(dev);
- goto free_interfaces;
- }
- mutex_unlock(hcd->bandwidth_mutex);
- usb_set_device_state(dev, USB_STATE_CONFIGURED);
-
- /* Initialize the new interface structures and the
+ /*
+ * Initialize the new interface structures and the
* hc/hcd/usbcore interface/endpoint state.
*/
for (i = 0; i < nintf; ++i) {
@@ -1872,6 +1843,35 @@ free_interfaces:
}
kfree(new_interfaces);
+ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
+ NULL, 0, USB_CTRL_SET_TIMEOUT);
+ if (ret < 0 && cp) {
+ /*
+ * All the old state is gone, so what else can we do?
+ * The device is probably useless now anyway.
+ */
+ usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
+ for (i = 0; i < nintf; ++i) {
+ usb_disable_interface(dev, cp->interface[i], true);
+ put_device(&cp->interface[i]->dev);
+ cp->interface[i] = NULL;
+ }
+ cp = NULL;
+ }
+
+ dev->actconfig = cp;
+ mutex_unlock(hcd->bandwidth_mutex);
+
+ if (!cp) {
+ usb_set_device_state(dev, USB_STATE_ADDRESS);
+
+ /* Leave LPM disabled while the device is unconfigured. */
+ usb_autosuspend_device(dev);
+ return ret;
+ }
+ usb_set_device_state(dev, USB_STATE_CONFIGURED);
+
if (cp->string == NULL &&
!(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
cp->string = usb_cache_string(dev, cp->desc.iConfiguration);
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 9d912bfdcff..e0d9d948218 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -214,9 +214,25 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);
* urb->interval is modified to reflect the actual transfer period used
* (normally some power of two units). And for isochronous urbs,
* urb->start_frame is modified to reflect when the URB's transfers were
- * scheduled to start. Not all isochronous transfer scheduling policies
- * will work, but most host controller drivers should easily handle ISO
- * queues going from now until 10-200 msec into the future.
+ * scheduled to start.
+ *
+ * Not all isochronous transfer scheduling policies will work, but most
+ * host controller drivers should easily handle ISO queues going from now
+ * until 10-200 msec into the future. Drivers should try to keep at
+ * least one or two msec of data in the queue; many controllers require
+ * that new transfers start at least 1 msec in the future when they are
+ * added. If the driver is unable to keep up and the queue empties out,
+ * the behavior for new submissions is governed by the URB_ISO_ASAP flag.
+ * If the flag is set, or if the queue is idle, then the URB is always
+ * assigned to the first available (and not yet expired) slot in the
+ * endpoint's schedule. If the flag is not set and the queue is active
+ * then the URB is always assigned to the next slot in the schedule
+ * following the end of the endpoint's previous URB, even if that slot is
+ * in the past. When a packet is assigned in this way to a slot that has
+ * already expired, the packet is not transmitted and the corresponding
+ * usb_iso_packet_descriptor's status field will return -EXDEV. If this
+ * would happen to all the packets in the URB, submission fails with a
+ * -EXDEV error code.
*
* For control endpoints, the synchronous usb_control_msg() call is
* often used (in non-interrupt context) instead of this call.
@@ -305,8 +321,13 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
struct usb_host_endpoint *ep;
int is_out;
- if (!urb || urb->hcpriv || !urb->complete)
+ if (!urb || !urb->complete)
return -EINVAL;
+ if (urb->hcpriv) {
+ WARN_ONCE(1, "URB %p submitted while active\n", urb);
+ return -EBUSY;
+ }
+
dev = urb->dev;
if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED))
return -ENODEV;
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index cd8fb44a3e1..f81b9257273 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -233,7 +233,6 @@ static void usb_release_dev(struct device *dev)
kfree(udev);
}
-#ifdef CONFIG_HOTPLUG
static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct usb_device *usb_dev;
@@ -249,14 +248,6 @@ static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
return 0;
}
-#else
-
-static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- return -ENODEV;
-}
-#endif /* CONFIG_HOTPLUG */
-
#ifdef CONFIG_PM
/* USB device Power-Management thunks.
@@ -370,14 +361,14 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
struct usb_bus *bus, unsigned port1)
{
struct usb_device *dev;
- struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self);
+ struct usb_hcd *usb_hcd = bus_to_hcd(bus);
unsigned root_hub = 0;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return NULL;
- if (!usb_get_hcd(bus_to_hcd(bus))) {
+ if (!usb_get_hcd(usb_hcd)) {
kfree(dev);
return NULL;
}
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index d441fe4c180..4502648b817 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -27,19 +27,7 @@ endif
##
obj-$(CONFIG_USB_DWC3) += dwc3-omap.o
-
-##
-# REVISIT Samsung Exynos platform needs the clk API which isn't
-# defined on all architectures. If we allow dwc3-exynos.c compile
-# always we will fail the linking phase on those architectures
-# which don't provide clk api implementation and that's unnaceptable.
-#
-# When Samsung's platform start supporting pm_runtime, this check
-# for HAVE_CLK should be removed.
-##
-ifneq ($(CONFIG_HAVE_CLK),)
- obj-$(CONFIG_USB_DWC3) += dwc3-exynos.o
-endif
+obj-$(CONFIG_USB_DWC3) += dwc3-exynos.o
ifneq ($(CONFIG_PCI),)
obj-$(CONFIG_USB_DWC3) += dwc3-pci.o
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c14ebc975ba..3a4004a620a 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -66,45 +66,6 @@ MODULE_PARM_DESC(maximum_speed, "Maximum supported speed.");
/* -------------------------------------------------------------------------- */
-#define DWC3_DEVS_POSSIBLE 32
-
-static DECLARE_BITMAP(dwc3_devs, DWC3_DEVS_POSSIBLE);
-
-int dwc3_get_device_id(void)
-{
- int id;
-
-again:
- id = find_first_zero_bit(dwc3_devs, DWC3_DEVS_POSSIBLE);
- if (id < DWC3_DEVS_POSSIBLE) {
- int old;
-
- old = test_and_set_bit(id, dwc3_devs);
- if (old)
- goto again;
- } else {
- pr_err("dwc3: no space for new device\n");
- id = -ENOMEM;
- }
-
- return id;
-}
-EXPORT_SYMBOL_GPL(dwc3_get_device_id);
-
-void dwc3_put_device_id(int id)
-{
- int ret;
-
- if (id < 0)
- return;
-
- ret = test_bit(id, dwc3_devs);
- WARN(!ret, "dwc3: ID %d not in use\n", id);
- smp_mb__before_clear_bit();
- clear_bit(id, dwc3_devs);
-}
-EXPORT_SYMBOL_GPL(dwc3_put_device_id);
-
void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
{
u32 reg;
@@ -169,7 +130,6 @@ static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
struct dwc3_event_buffer *evt)
{
dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
- kfree(evt);
}
/**
@@ -180,12 +140,11 @@ static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
* Returns a pointer to the allocated event buffer structure on success
* otherwise ERR_PTR(errno).
*/
-static struct dwc3_event_buffer *__devinit
-dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length)
+static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length)
{
struct dwc3_event_buffer *evt;
- evt = kzalloc(sizeof(*evt), GFP_KERNEL);
+ evt = devm_kzalloc(dwc->dev, sizeof(*evt), GFP_KERNEL);
if (!evt)
return ERR_PTR(-ENOMEM);
@@ -193,10 +152,8 @@ dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length)
evt->length = length;
evt->buf = dma_alloc_coherent(dwc->dev, length,
&evt->dma, GFP_KERNEL);
- if (!evt->buf) {
- kfree(evt);
+ if (!evt->buf)
return ERR_PTR(-ENOMEM);
- }
return evt;
}
@@ -215,8 +172,6 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
if (evt)
dwc3_free_one_event_buffer(dwc, evt);
}
-
- kfree(dwc->ev_buffs);
}
/**
@@ -227,7 +182,7 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
* Returns 0 on success otherwise negative errno. In the error case, dwc
* may contain some buffers allocated but not all which were requested.
*/
-static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
+static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
{
int num;
int i;
@@ -235,7 +190,8 @@ static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
num = DWC3_NUM_INT(dwc->hwparams.hwparams1);
dwc->num_event_buffers = num;
- dwc->ev_buffs = kzalloc(sizeof(*dwc->ev_buffs) * num, GFP_KERNEL);
+ dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * num,
+ GFP_KERNEL);
if (!dwc->ev_buffs) {
dev_err(dwc->dev, "can't allocate event buffers array\n");
return -ENOMEM;
@@ -303,7 +259,7 @@ static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
}
}
-static void __devinit dwc3_cache_hwparams(struct dwc3 *dwc)
+static void dwc3_cache_hwparams(struct dwc3 *dwc)
{
struct dwc3_hwparams *parms = &dwc->hwparams;
@@ -324,7 +280,7 @@ static void __devinit dwc3_cache_hwparams(struct dwc3 *dwc)
*
* Returns 0 on success otherwise negative errno.
*/
-static int __devinit dwc3_core_init(struct dwc3 *dwc)
+static int dwc3_core_init(struct dwc3 *dwc)
{
unsigned long timeout;
u32 reg;
@@ -358,8 +314,6 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc)
dwc3_core_soft_reset(dwc);
- dwc3_cache_hwparams(dwc);
-
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
reg &= ~DWC3_GCTL_DISSCRAMBLE;
@@ -383,24 +337,14 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc)
dwc3_writel(dwc->regs, DWC3_GCTL, reg);
- ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
- if (ret) {
- dev_err(dwc->dev, "failed to allocate event buffers\n");
- ret = -ENOMEM;
- goto err1;
- }
-
ret = dwc3_event_buffers_setup(dwc);
if (ret) {
dev_err(dwc->dev, "failed to setup event buffers\n");
- goto err1;
+ goto err0;
}
return 0;
-err1:
- dwc3_free_event_buffers(dwc);
-
err0:
return ret;
}
@@ -408,16 +352,14 @@ err0:
static void dwc3_core_exit(struct dwc3 *dwc)
{
dwc3_event_buffers_cleanup(dwc);
- dwc3_free_event_buffers(dwc);
usb_phy_shutdown(dwc->usb2_phy);
usb_phy_shutdown(dwc->usb3_phy);
-
}
#define DWC3_ALIGN_MASK (16 - 1)
-static int __devinit dwc3_probe(struct platform_device *pdev)
+static int dwc3_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct resource *res;
@@ -515,10 +457,19 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
pm_runtime_get_sync(dev);
pm_runtime_forbid(dev);
+ dwc3_cache_hwparams(dwc);
+
+ ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
+ if (ret) {
+ dev_err(dwc->dev, "failed to allocate event buffers\n");
+ ret = -ENOMEM;
+ goto err0;
+ }
+
ret = dwc3_core_init(dwc);
if (ret) {
dev_err(dev, "failed to initialize core\n");
- return ret;
+ goto err0;
}
mode = DWC3_MODE(dwc->hwparams.hwparams0);
@@ -590,10 +541,13 @@ err2:
err1:
dwc3_core_exit(dwc);
+err0:
+ dwc3_free_event_buffers(dwc);
+
return ret;
}
-static int __devexit dwc3_remove(struct platform_device *pdev)
+static int dwc3_remove(struct platform_device *pdev)
{
struct dwc3 *dwc = platform_get_drvdata(pdev);
struct resource *res;
@@ -628,7 +582,7 @@ static int __devexit dwc3_remove(struct platform_device *pdev)
static struct platform_driver dwc3_driver = {
.probe = dwc3_probe,
- .remove = __devexit_p(dwc3_remove),
+ .remove = dwc3_remove,
.driver = {
.name = "dwc3",
},
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 243affc9343..49995634426 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -868,7 +868,4 @@ void dwc3_host_exit(struct dwc3 *dwc);
int dwc3_gadget_init(struct dwc3 *dwc);
void dwc3_gadget_exit(struct dwc3 *dwc);
-extern int dwc3_get_device_id(void);
-extern void dwc3_put_device_id(int id);
-
#endif /* __DRIVERS_USB_DWC3_CORE_H */
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c
index d4a30f11872..92604b4f971 100644
--- a/drivers/usb/dwc3/debugfs.c
+++ b/drivers/usb/dwc3/debugfs.c
@@ -652,7 +652,7 @@ static const struct file_operations dwc3_link_state_fops = {
.release = single_release,
};
-int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
+int dwc3_debugfs_init(struct dwc3 *dwc)
{
struct dentry *root;
struct dentry *file;
@@ -703,7 +703,7 @@ err0:
return ret;
}
-void __devexit dwc3_debugfs_exit(struct dwc3 *dwc)
+void dwc3_debugfs_exit(struct dwc3 *dwc)
{
debugfs_remove_recursive(dwc->root);
dwc->root = NULL;
diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
index ca6597853f9..aae5328ac77 100644
--- a/drivers/usb/dwc3/dwc3-exynos.c
+++ b/drivers/usb/dwc3/dwc3-exynos.c
@@ -21,6 +21,7 @@
#include <linux/clk.h>
#include <linux/usb/otg.h>
#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/of.h>
#include "core.h"
@@ -33,7 +34,7 @@ struct dwc3_exynos {
struct clk *clk;
};
-static int __devinit dwc3_exynos_register_phys(struct dwc3_exynos *exynos)
+static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos)
{
struct nop_usb_xceiv_platform_data pdata;
struct platform_device *pdev;
@@ -87,14 +88,14 @@ err1:
return ret;
}
-static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
+static u64 dwc3_exynos_dma_mask = DMA_BIT_MASK(32);
+
+static int dwc3_exynos_probe(struct platform_device *pdev)
{
- struct dwc3_exynos_data *pdata = pdev->dev.platform_data;
struct platform_device *dwc3;
struct dwc3_exynos *exynos;
struct clk *clk;
- int devid;
int ret = -ENOMEM;
exynos = kzalloc(sizeof(*exynos), GFP_KERNEL);
@@ -103,11 +104,15 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
goto err0;
}
- platform_set_drvdata(pdev, exynos);
+ /*
+ * 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 = &dwc3_exynos_dma_mask;
- devid = dwc3_get_device_id();
- if (devid < 0)
- goto err1;
+ platform_set_drvdata(pdev, exynos);
ret = dwc3_exynos_register_phys(exynos);
if (ret) {
@@ -115,10 +120,10 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
goto err1;
}
- dwc3 = platform_device_alloc("dwc3", devid);
+ dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
if (!dwc3) {
dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");
- goto err2;
+ goto err1;
}
clk = clk_get(&pdev->dev, "usbdrd30");
@@ -139,14 +144,6 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
clk_enable(exynos->clk);
- /* PHY initialization */
- if (!pdata) {
- dev_dbg(&pdev->dev, "missing platform data\n");
- } else {
- if (pdata->phy_init)
- pdata->phy_init(pdev, pdata->phy_type);
- }
-
ret = platform_device_add_resources(dwc3, pdev->resource,
pdev->num_resources);
if (ret) {
@@ -163,35 +160,24 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
return 0;
err4:
- if (pdata && pdata->phy_exit)
- pdata->phy_exit(pdev, pdata->phy_type);
-
clk_disable(clk);
clk_put(clk);
err3:
platform_device_put(dwc3);
-err2:
- dwc3_put_device_id(devid);
err1:
kfree(exynos);
err0:
return ret;
}
-static int __devexit dwc3_exynos_remove(struct platform_device *pdev)
+static int dwc3_exynos_remove(struct platform_device *pdev)
{
struct dwc3_exynos *exynos = platform_get_drvdata(pdev);
- struct dwc3_exynos_data *pdata = pdev->dev.platform_data;
platform_device_unregister(exynos->dwc3);
platform_device_unregister(exynos->usb2_phy);
platform_device_unregister(exynos->usb3_phy);
- dwc3_put_device_id(exynos->dwc3->id);
-
- if (pdata && pdata->phy_exit)
- pdata->phy_exit(pdev, pdata->phy_type);
-
clk_disable(exynos->clk);
clk_put(exynos->clk);
@@ -200,11 +186,20 @@ static int __devexit dwc3_exynos_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_OF
+static const struct of_device_id exynos_dwc3_match[] = {
+ { .compatible = "samsung,exynos-dwc3" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, exynos_dwc3_match);
+#endif
+
static struct platform_driver dwc3_exynos_driver = {
.probe = dwc3_exynos_probe,
- .remove = __devexit_p(dwc3_exynos_remove),
+ .remove = dwc3_exynos_remove,
.driver = {
.name = "exynos-dwc3",
+ .of_match_table = of_match_ptr(exynos_dwc3_match),
},
};
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index ee57a10d90d..f31867fd257 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -157,7 +157,7 @@ static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value)
writel(value, base + offset);
}
-static int __devinit dwc3_omap_register_phys(struct dwc3_omap *omap)
+static int dwc3_omap_register_phys(struct dwc3_omap *omap)
{
struct nop_usb_xceiv_platform_data pdata;
struct platform_device *pdev;
@@ -262,7 +262,7 @@ static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
return IRQ_HANDLED;
}
-static int __devinit dwc3_omap_probe(struct platform_device *pdev)
+static int dwc3_omap_probe(struct platform_device *pdev)
{
struct dwc3_omap_data *pdata = pdev->dev.platform_data;
struct device_node *node = pdev->dev.of_node;
@@ -272,7 +272,6 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
struct resource *res;
struct device *dev = &pdev->dev;
- int devid;
int size;
int ret = -ENOMEM;
int irq;
@@ -315,14 +314,10 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
return ret;
}
- devid = dwc3_get_device_id();
- if (devid < 0)
- return -ENODEV;
-
- dwc3 = platform_device_alloc("dwc3", devid);
+ dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
if (!dwc3) {
dev_err(dev, "couldn't allocate dwc3 device\n");
- goto err1;
+ return -ENOMEM;
}
context = devm_kzalloc(dev, resource_size(res), GFP_KERNEL);
@@ -423,23 +418,16 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
err2:
platform_device_put(dwc3);
-
-err1:
- dwc3_put_device_id(devid);
-
return ret;
}
-static int __devexit dwc3_omap_remove(struct platform_device *pdev)
+static int dwc3_omap_remove(struct platform_device *pdev)
{
struct dwc3_omap *omap = platform_get_drvdata(pdev);
platform_device_unregister(omap->dwc3);
platform_device_unregister(omap->usb2_phy);
platform_device_unregister(omap->usb3_phy);
-
- dwc3_put_device_id(omap->dwc3->id);
-
return 0;
}
@@ -453,7 +441,7 @@ MODULE_DEVICE_TABLE(of, of_dwc3_matach);
static struct platform_driver dwc3_omap_driver = {
.probe = dwc3_omap_probe,
- .remove = __devexit_p(dwc3_omap_remove),
+ .remove = dwc3_omap_remove,
.driver = {
.name = "omap-dwc3",
.of_match_table = of_dwc3_matach,
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 94f550e37f9..7d70f44567d 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -58,7 +58,7 @@ struct dwc3_pci {
struct platform_device *usb3_phy;
};
-static int __devinit dwc3_pci_register_phys(struct dwc3_pci *glue)
+static int dwc3_pci_register_phys(struct dwc3_pci *glue)
{
struct nop_usb_xceiv_platform_data pdata;
struct platform_device *pdev;
@@ -112,14 +112,13 @@ err1:
return ret;
}
-static int __devinit dwc3_pci_probe(struct pci_dev *pci,
+static int dwc3_pci_probe(struct pci_dev *pci,
const struct pci_device_id *id)
{
struct resource res[2];
struct platform_device *dwc3;
struct dwc3_pci *glue;
int ret = -ENOMEM;
- int devid;
struct device *dev = &pci->dev;
glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL);
@@ -145,13 +144,7 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
return ret;
}
- devid = dwc3_get_device_id();
- if (devid < 0) {
- ret = -ENOMEM;
- goto err1;
- }
-
- dwc3 = platform_device_alloc("dwc3", devid);
+ dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
if (!dwc3) {
dev_err(dev, "couldn't allocate dwc3 device\n");
ret = -ENOMEM;
@@ -172,7 +165,7 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res));
if (ret) {
dev_err(dev, "couldn't add resources to dwc3 device\n");
- goto err2;
+ goto err1;
}
pci_set_drvdata(pci, glue);
@@ -195,23 +188,18 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
err3:
pci_set_drvdata(pci, NULL);
platform_device_put(dwc3);
-
-err2:
- dwc3_put_device_id(devid);
-
err1:
pci_disable_device(pci);
return ret;
}
-static void __devexit dwc3_pci_remove(struct pci_dev *pci)
+static void dwc3_pci_remove(struct pci_dev *pci)
{
struct dwc3_pci *glue = pci_get_drvdata(pci);
platform_device_unregister(glue->usb2_phy);
platform_device_unregister(glue->usb3_phy);
- dwc3_put_device_id(glue->dwc3->id);
platform_device_unregister(glue->dwc3);
pci_set_drvdata(pci, NULL);
pci_disable_device(pci);
@@ -230,7 +218,7 @@ static struct pci_driver dwc3_pci_driver = {
.name = "dwc3-pci",
.id_table = dwc3_pci_id_table,
.probe = dwc3_pci_probe,
- .remove = __devexit_p(dwc3_pci_remove),
+ .remove = dwc3_pci_remove,
};
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 7b7deddf6a5..2e43b332aae 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1579,7 +1579,7 @@ static const struct usb_gadget_ops dwc3_gadget_ops = {
/* -------------------------------------------------------------------------- */
-static int __devinit dwc3_gadget_init_endpoints(struct dwc3 *dwc)
+static int dwc3_gadget_init_endpoints(struct dwc3 *dwc)
{
struct dwc3_ep *dep;
u8 epnum;
@@ -2374,7 +2374,7 @@ static irqreturn_t dwc3_interrupt(int irq, void *_dwc)
*
* Returns 0 on success otherwise negative errno.
*/
-int __devinit dwc3_gadget_init(struct dwc3 *dwc)
+int dwc3_gadget_init(struct dwc3 *dwc)
{
u32 reg;
int ret;
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c
index e426ad626d7..5e29ddeb4d3 100644
--- a/drivers/usb/early/ehci-dbgp.c
+++ b/drivers/usb/early/ehci-dbgp.c
@@ -20,6 +20,7 @@
#include <linux/usb/ehci_def.h>
#include <linux/delay.h>
#include <linux/serial_core.h>
+#include <linux/kconfig.h>
#include <linux/kgdb.h>
#include <linux/kthread.h>
#include <asm/io.h>
@@ -614,12 +615,6 @@ err:
return -ENODEV;
}
-int dbgp_external_startup(struct usb_hcd *hcd)
-{
- return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
-}
-EXPORT_SYMBOL_GPL(dbgp_external_startup);
-
static int ehci_reset_port(int port)
{
u32 portsc;
@@ -979,6 +974,7 @@ struct console early_dbgp_console = {
.index = -1,
};
+#if IS_ENABLED(CONFIG_USB)
int dbgp_reset_prep(struct usb_hcd *hcd)
{
int ret = xen_dbgp_reset_prep(hcd);
@@ -1007,6 +1003,13 @@ int dbgp_reset_prep(struct usb_hcd *hcd)
}
EXPORT_SYMBOL_GPL(dbgp_reset_prep);
+int dbgp_external_startup(struct usb_hcd *hcd)
+{
+ return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
+}
+EXPORT_SYMBOL_GPL(dbgp_external_startup);
+#endif /* USB */
+
#ifdef CONFIG_KGDB
static char kgdbdbgp_buf[DBGP_MAX_PACKET];
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index e0ff51b8952..14625fd2cec 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -721,31 +721,6 @@ config USB_FUNCTIONFS_GENERIC
Include a configuration with the Function Filesystem alone with
no Ethernet interface.
-config USB_FILE_STORAGE
- tristate "File-backed Storage Gadget (DEPRECATED)"
- depends on BLOCK
- help
- The File-backed 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.
-
- Say "y" to link the driver statically, or "m" to build a
- dynamically linked module called "g_file_storage".
-
- NOTE: This driver is deprecated. Its replacement is the
- Mass Storage Gadget.
-
-config USB_FILE_STORAGE_TEST
- bool "File-backed Storage Gadget testing version"
- depends on USB_FILE_STORAGE
- default n
- help
- Say "y" to generate the larger testing version of the
- File-backed Storage Gadget, useful for probing the
- behavior of USB Mass Storage hosts. Not needed for
- normal operation.
-
config USB_MASS_STORAGE
tristate "Mass Storage Gadget"
depends on BLOCK
@@ -756,8 +731,8 @@ config USB_MASS_STORAGE
device (in much the same way as the "loop" device driver),
specified as a module parameter or sysfs option.
- This driver is an updated replacement for the deprecated
- File-backed Storage Gadget (g_file_storage).
+ This driver is a replacement for now removed File-backed
+ Storage Gadget (g_file_storage).
Say "y" to link the driver statically, or "m" to build
a dynamically linked module called "g_mass_storage".
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 307be5fa824..8b4acfd92aa 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -44,7 +44,6 @@ g_ether-y := ether.o
g_serial-y := serial.o
g_midi-y := gmidi.o
gadgetfs-y := inode.o
-g_file_storage-y := file_storage.o
g_mass_storage-y := mass_storage.o
g_printer-y := printer.o
g_cdc-y := cdc2.o
@@ -62,7 +61,6 @@ obj-$(CONFIG_USB_AUDIO) += g_audio.o
obj-$(CONFIG_USB_ETH) += g_ether.o
obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o
obj-$(CONFIG_USB_FUNCTIONFS) += g_ffs.o
-obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o
obj-$(CONFIG_USB_MASS_STORAGE) += g_mass_storage.o
obj-$(CONFIG_USB_G_SERIAL) += g_serial.o
obj-$(CONFIG_USB_G_PRINTER) += g_printer.o
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 89d90b5fb78..e6135faabc3 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -1673,7 +1673,7 @@ static void at91udc_shutdown(struct platform_device *dev)
spin_unlock_irqrestore(&udc->lock, flags);
}
-static void __devinit at91udc_of_init(struct at91_udc *udc,
+static void at91udc_of_init(struct at91_udc *udc,
struct device_node *np)
{
struct at91_udc_data *board = &udc->board;
@@ -1693,7 +1693,7 @@ static void __devinit at91udc_of_init(struct at91_udc *udc,
board->pullup_active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
}
-static int __devinit at91udc_probe(struct platform_device *pdev)
+static int at91udc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct at91_udc *udc;
diff --git a/drivers/usb/gadget/bcm63xx_udc.c b/drivers/usb/gadget/bcm63xx_udc.c
index 9ca792224cd..47a49931361 100644
--- a/drivers/usb/gadget/bcm63xx_udc.c
+++ b/drivers/usb/gadget/bcm63xx_udc.c
@@ -2323,7 +2323,7 @@ static void bcm63xx_udc_gadget_release(struct device *dev)
* Note that platform data is required, because pd.port_no varies from chip
* to chip and is used to switch the correct USB port to device mode.
*/
-static int __devinit bcm63xx_udc_probe(struct platform_device *pdev)
+static int bcm63xx_udc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct bcm63xx_usbd_platform_data *pd = dev->platform_data;
@@ -2433,7 +2433,7 @@ out_uninit:
* bcm63xx_udc_remove - Remove the device from the system.
* @pdev: Platform device struct from the bcm63xx BSP code.
*/
-static int __devexit bcm63xx_udc_remove(struct platform_device *pdev)
+static int bcm63xx_udc_remove(struct platform_device *pdev)
{
struct bcm63xx_udc *udc = platform_get_drvdata(pdev);
@@ -2450,7 +2450,7 @@ static int __devexit bcm63xx_udc_remove(struct platform_device *pdev)
static struct platform_driver bcm63xx_udc_driver = {
.probe = bcm63xx_udc_probe,
- .remove = __devexit_p(bcm63xx_udc_remove),
+ .remove = bcm63xx_udc_remove,
.driver = {
.name = DRV_MODULE_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 957f973dd96..2a6bfe759c2 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -107,7 +107,7 @@ int config_ep_by_speed(struct usb_gadget *g,
}
/* else: fall through */
default:
- speed_desc = f->descriptors;
+ speed_desc = f->fs_descriptors;
}
/* find descriptors */
for_each_ep_desc(speed_desc, d_spd) {
@@ -200,7 +200,7 @@ int usb_add_function(struct usb_configuration *config,
* as full speed ... it's the function drivers that will need
* to avoid bulk and ISO transfers.
*/
- if (!config->fullspeed && function->descriptors)
+ if (!config->fullspeed && function->fs_descriptors)
config->fullspeed = true;
if (!config->highspeed && function->hs_descriptors)
config->highspeed = true;
@@ -363,7 +363,7 @@ static int config_buf(struct usb_configuration *config,
descriptors = f->hs_descriptors;
break;
default:
- descriptors = f->descriptors;
+ descriptors = f->fs_descriptors;
}
if (!descriptors)
@@ -620,7 +620,7 @@ static int set_config(struct usb_composite_dev *cdev,
descriptors = f->hs_descriptors;
break;
default:
- descriptors = f->descriptors;
+ descriptors = f->fs_descriptors;
}
for (; *descriptors; ++descriptors) {
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index e3a98929d34..34e12fc52c2 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -19,7 +19,7 @@
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
-
+#include <linux/usb/composite.h>
/**
* usb_descriptor_fillbuf - fill buffer with descriptors
@@ -158,3 +158,40 @@ usb_copy_descriptors(struct usb_descriptor_header **src)
return ret;
}
EXPORT_SYMBOL_GPL(usb_copy_descriptors);
+
+int usb_assign_descriptors(struct usb_function *f,
+ struct usb_descriptor_header **fs,
+ struct usb_descriptor_header **hs,
+ struct usb_descriptor_header **ss)
+{
+ struct usb_gadget *g = f->config->cdev->gadget;
+
+ if (fs) {
+ f->fs_descriptors = usb_copy_descriptors(fs);
+ if (!f->fs_descriptors)
+ goto err;
+ }
+ if (hs && gadget_is_dualspeed(g)) {
+ f->hs_descriptors = usb_copy_descriptors(hs);
+ if (!f->hs_descriptors)
+ goto err;
+ }
+ if (ss && gadget_is_superspeed(g)) {
+ f->ss_descriptors = usb_copy_descriptors(ss);
+ if (!f->ss_descriptors)
+ goto err;
+ }
+ return 0;
+err:
+ usb_free_all_descriptors(f);
+ return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(usb_assign_descriptors);
+
+void usb_free_all_descriptors(struct usb_function *f)
+{
+ usb_free_descriptors(f->fs_descriptors);
+ usb_free_descriptors(f->hs_descriptors);
+ usb_free_descriptors(f->ss_descriptors);
+}
+EXPORT_SYMBOL_GPL(usb_free_all_descriptors);
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 0f7541be28f..95d584dbed1 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -63,16 +63,20 @@ MODULE_LICENSE("GPL");
struct dummy_hcd_module_parameters {
bool is_super_speed;
bool is_high_speed;
+ unsigned int num;
};
static struct dummy_hcd_module_parameters mod_data = {
.is_super_speed = false,
.is_high_speed = true,
+ .num = 1,
};
module_param_named(is_super_speed, mod_data.is_super_speed, bool, S_IRUGO);
MODULE_PARM_DESC(is_super_speed, "true to simulate SuperSpeed connection");
module_param_named(is_high_speed, mod_data.is_high_speed, bool, S_IRUGO);
MODULE_PARM_DESC(is_high_speed, "true to simulate HighSpeed connection");
+module_param_named(num, mod_data.num, uint, S_IRUGO);
+MODULE_PARM_DESC(num, "number of emulated controllers");
/*-------------------------------------------------------------------------*/
/* gadget side driver data structres */
@@ -238,8 +242,6 @@ static inline struct dummy *gadget_dev_to_dummy(struct device *dev)
return container_of(dev, struct dummy, gadget.dev);
}
-static struct dummy the_controller;
-
/*-------------------------------------------------------------------------*/
/* SLAVE/GADGET SIDE UTILITY ROUTINES */
@@ -973,9 +975,10 @@ static void init_dummy_udc_hw(struct dummy *dum)
static int dummy_udc_probe(struct platform_device *pdev)
{
- struct dummy *dum = &the_controller;
+ struct dummy *dum;
int rc;
+ dum = *((void **)dev_get_platdata(&pdev->dev));
dum->gadget.name = gadget_name;
dum->gadget.ops = &dummy_ops;
dum->gadget.max_speed = USB_SPEED_SUPER;
@@ -2398,10 +2401,13 @@ static int dummy_h_get_frame(struct usb_hcd *hcd)
static int dummy_setup(struct usb_hcd *hcd)
{
+ struct dummy *dum;
+
+ dum = *((void **)dev_get_platdata(hcd->self.controller));
hcd->self.sg_tablesize = ~0;
if (usb_hcd_is_primary_hcd(hcd)) {
- the_controller.hs_hcd = hcd_to_dummy_hcd(hcd);
- the_controller.hs_hcd->dum = &the_controller;
+ dum->hs_hcd = hcd_to_dummy_hcd(hcd);
+ dum->hs_hcd->dum = dum;
/*
* Mark the first roothub as being USB 2.0.
* The USB 3.0 roothub will be registered later by
@@ -2410,8 +2416,8 @@ static int dummy_setup(struct usb_hcd *hcd)
hcd->speed = HCD_USB2;
hcd->self.root_hub->speed = USB_SPEED_HIGH;
} else {
- the_controller.ss_hcd = hcd_to_dummy_hcd(hcd);
- the_controller.ss_hcd->dum = &the_controller;
+ dum->ss_hcd = hcd_to_dummy_hcd(hcd);
+ dum->ss_hcd->dum = dum;
hcd->speed = HCD_USB3;
hcd->self.root_hub->speed = USB_SPEED_SUPER;
}
@@ -2524,11 +2530,13 @@ static struct hc_driver dummy_hcd = {
static int dummy_hcd_probe(struct platform_device *pdev)
{
+ struct dummy *dum;
struct usb_hcd *hs_hcd;
struct usb_hcd *ss_hcd;
int retval;
dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
+ dum = *((void **)dev_get_platdata(&pdev->dev));
if (!mod_data.is_super_speed)
dummy_hcd.flags = HCD_USB2;
@@ -2561,7 +2569,7 @@ dealloc_usb2_hcd:
usb_remove_hcd(hs_hcd);
put_usb2_hcd:
usb_put_hcd(hs_hcd);
- the_controller.hs_hcd = the_controller.ss_hcd = NULL;
+ dum->hs_hcd = dum->ss_hcd = NULL;
return retval;
}
@@ -2579,8 +2587,8 @@ static int dummy_hcd_remove(struct platform_device *pdev)
usb_remove_hcd(dummy_hcd_to_hcd(dum->hs_hcd));
usb_put_hcd(dummy_hcd_to_hcd(dum->hs_hcd));
- the_controller.hs_hcd = NULL;
- the_controller.ss_hcd = NULL;
+ dum->hs_hcd = NULL;
+ dum->ss_hcd = NULL;
return 0;
}
@@ -2627,13 +2635,15 @@ static struct platform_driver dummy_hcd_driver = {
};
/*-------------------------------------------------------------------------*/
-
-static struct platform_device *the_udc_pdev;
-static struct platform_device *the_hcd_pdev;
+#define MAX_NUM_UDC 2
+static struct platform_device *the_udc_pdev[MAX_NUM_UDC];
+static struct platform_device *the_hcd_pdev[MAX_NUM_UDC];
static int __init init(void)
{
int retval = -ENOMEM;
+ int i;
+ struct dummy *dum[MAX_NUM_UDC];
if (usb_disabled())
return -ENODEV;
@@ -2641,65 +2651,129 @@ static int __init init(void)
if (!mod_data.is_high_speed && mod_data.is_super_speed)
return -EINVAL;
- the_hcd_pdev = platform_device_alloc(driver_name, -1);
- if (!the_hcd_pdev)
- return retval;
- the_udc_pdev = platform_device_alloc(gadget_name, -1);
- if (!the_udc_pdev)
- goto err_alloc_udc;
+ if (mod_data.num < 1 || mod_data.num > MAX_NUM_UDC) {
+ pr_err("Number of emulated UDC must be in range of 1…%d\n",
+ MAX_NUM_UDC);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < mod_data.num; i++) {
+ the_hcd_pdev[i] = platform_device_alloc(driver_name, i);
+ if (!the_hcd_pdev[i]) {
+ i--;
+ while (i >= 0)
+ platform_device_put(the_hcd_pdev[i--]);
+ return retval;
+ }
+ }
+ for (i = 0; i < mod_data.num; i++) {
+ the_udc_pdev[i] = platform_device_alloc(gadget_name, i);
+ if (!the_udc_pdev[i]) {
+ i--;
+ while (i >= 0)
+ platform_device_put(the_udc_pdev[i--]);
+ goto err_alloc_udc;
+ }
+ }
+ for (i = 0; i < mod_data.num; i++) {
+ dum[i] = kzalloc(sizeof(struct dummy), GFP_KERNEL);
+ if (!dum[i])
+ goto err_add_pdata;
+ retval = platform_device_add_data(the_hcd_pdev[i], &dum[i],
+ sizeof(void *));
+ if (retval)
+ goto err_add_pdata;
+ retval = platform_device_add_data(the_udc_pdev[i], &dum[i],
+ sizeof(void *));
+ if (retval)
+ goto err_add_pdata;
+ }
retval = platform_driver_register(&dummy_hcd_driver);
if (retval < 0)
- goto err_register_hcd_driver;
+ goto err_add_pdata;
retval = platform_driver_register(&dummy_udc_driver);
if (retval < 0)
goto err_register_udc_driver;
- retval = platform_device_add(the_hcd_pdev);
- if (retval < 0)
- goto err_add_hcd;
- if (!the_controller.hs_hcd ||
- (!the_controller.ss_hcd && mod_data.is_super_speed)) {
- /*
- * The hcd was added successfully but its probe function failed
- * for some reason.
- */
- retval = -EINVAL;
- goto err_add_udc;
+ for (i = 0; i < mod_data.num; i++) {
+ retval = platform_device_add(the_hcd_pdev[i]);
+ if (retval < 0) {
+ i--;
+ while (i >= 0)
+ platform_device_del(the_hcd_pdev[i--]);
+ goto err_add_hcd;
+ }
}
- retval = platform_device_add(the_udc_pdev);
- if (retval < 0)
- goto err_add_udc;
- if (!platform_get_drvdata(the_udc_pdev)) {
- /*
- * The udc was added successfully but its probe function failed
- * for some reason.
- */
- retval = -EINVAL;
- goto err_probe_udc;
+ for (i = 0; i < mod_data.num; i++) {
+ if (!dum[i]->hs_hcd ||
+ (!dum[i]->ss_hcd && mod_data.is_super_speed)) {
+ /*
+ * The hcd was added successfully but its probe
+ * function failed for some reason.
+ */
+ retval = -EINVAL;
+ goto err_add_udc;
+ }
+ }
+
+ for (i = 0; i < mod_data.num; i++) {
+ retval = platform_device_add(the_udc_pdev[i]);
+ if (retval < 0) {
+ i--;
+ while (i >= 0)
+ platform_device_del(the_udc_pdev[i]);
+ goto err_add_udc;
+ }
+ }
+
+ for (i = 0; i < mod_data.num; i++) {
+ if (!platform_get_drvdata(the_udc_pdev[i])) {
+ /*
+ * The udc was added successfully but its probe
+ * function failed for some reason.
+ */
+ retval = -EINVAL;
+ goto err_probe_udc;
+ }
}
return retval;
err_probe_udc:
- platform_device_del(the_udc_pdev);
+ for (i = 0; i < mod_data.num; i++)
+ platform_device_del(the_udc_pdev[i]);
err_add_udc:
- platform_device_del(the_hcd_pdev);
+ for (i = 0; i < mod_data.num; i++)
+ platform_device_del(the_hcd_pdev[i]);
err_add_hcd:
platform_driver_unregister(&dummy_udc_driver);
err_register_udc_driver:
platform_driver_unregister(&dummy_hcd_driver);
-err_register_hcd_driver:
- platform_device_put(the_udc_pdev);
+err_add_pdata:
+ for (i = 0; i < mod_data.num; i++)
+ kfree(dum[i]);
+ for (i = 0; i < mod_data.num; i++)
+ platform_device_put(the_udc_pdev[i]);
err_alloc_udc:
- platform_device_put(the_hcd_pdev);
+ for (i = 0; i < mod_data.num; i++)
+ platform_device_put(the_hcd_pdev[i]);
return retval;
}
module_init(init);
static void __exit cleanup(void)
{
- platform_device_unregister(the_udc_pdev);
- platform_device_unregister(the_hcd_pdev);
+ int i;
+
+ for (i = 0; i < mod_data.num; i++) {
+ struct dummy *dum;
+
+ dum = *((void **)dev_get_platdata(&the_udc_pdev[i]->dev));
+
+ platform_device_unregister(the_udc_pdev[i]);
+ platform_device_unregister(the_hcd_pdev[i]);
+ kfree(dum);
+ }
platform_driver_unregister(&dummy_udc_driver);
platform_driver_unregister(&dummy_hcd_driver);
}
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index d672250a61f..549174466c2 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -87,7 +87,7 @@ static inline struct f_acm *port_to_acm(struct gserial *p)
/* notification endpoint uses smallish and infrequent fixed-size messages */
-#define GS_LOG2_NOTIFY_INTERVAL 5 /* 1 << 5 == 32 msec */
+#define GS_NOTIFY_INTERVAL_MS 32
#define GS_NOTIFY_MAXPACKET 10 /* notification + 2 bytes */
/* interface and class descriptors: */
@@ -167,7 +167,7 @@ static struct usb_endpoint_descriptor acm_fs_notify_desc = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET),
- .bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL,
+ .bInterval = GS_NOTIFY_INTERVAL_MS,
};
static struct usb_endpoint_descriptor acm_fs_in_desc = {
@@ -199,14 +199,13 @@ static struct usb_descriptor_header *acm_fs_function[] = {
};
/* high speed support: */
-
static struct usb_endpoint_descriptor acm_hs_notify_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET),
- .bInterval = GS_LOG2_NOTIFY_INTERVAL+4,
+ .bInterval = USB_MS_TO_HS_INTERVAL(GS_NOTIFY_INTERVAL_MS),
};
static struct usb_endpoint_descriptor acm_hs_in_desc = {
@@ -659,37 +658,22 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
acm->notify_req->complete = acm_cdc_notify_complete;
acm->notify_req->context = acm;
- /* copy descriptors */
- f->descriptors = usb_copy_descriptors(acm_fs_function);
- if (!f->descriptors)
- goto fail;
-
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
*/
- if (gadget_is_dualspeed(c->cdev->gadget)) {
- acm_hs_in_desc.bEndpointAddress =
- acm_fs_in_desc.bEndpointAddress;
- acm_hs_out_desc.bEndpointAddress =
- acm_fs_out_desc.bEndpointAddress;
- acm_hs_notify_desc.bEndpointAddress =
- acm_fs_notify_desc.bEndpointAddress;
-
- /* copy descriptors */
- f->hs_descriptors = usb_copy_descriptors(acm_hs_function);
- }
- if (gadget_is_superspeed(c->cdev->gadget)) {
- acm_ss_in_desc.bEndpointAddress =
- acm_fs_in_desc.bEndpointAddress;
- acm_ss_out_desc.bEndpointAddress =
- acm_fs_out_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->ss_descriptors = usb_copy_descriptors(acm_ss_function);
- if (!f->ss_descriptors)
- goto fail;
- }
+ acm_hs_in_desc.bEndpointAddress = acm_fs_in_desc.bEndpointAddress;
+ acm_hs_out_desc.bEndpointAddress = acm_fs_out_desc.bEndpointAddress;
+ acm_hs_notify_desc.bEndpointAddress =
+ acm_fs_notify_desc.bEndpointAddress;
+
+ acm_ss_in_desc.bEndpointAddress = acm_fs_in_desc.bEndpointAddress;
+ acm_ss_out_desc.bEndpointAddress = acm_fs_out_desc.bEndpointAddress;
+
+ status = usb_assign_descriptors(f, acm_fs_function, acm_hs_function,
+ acm_ss_function);
+ if (status)
+ goto fail;
DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n",
acm->port_num,
@@ -721,11 +705,8 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_acm *acm = func_to_acm(f);
- if (gadget_is_dualspeed(c->cdev->gadget))
- usb_free_descriptors(f->hs_descriptors);
- if (gadget_is_superspeed(c->cdev->gadget))
- usb_free_descriptors(f->ss_descriptors);
- usb_free_descriptors(f->descriptors);
+ acm_string_defs[0].id = 0;
+ usb_free_all_descriptors(f);
gs_free_req(acm->notify, acm->notify_req);
kfree(acm);
}
@@ -762,27 +743,15 @@ int acm_bind_config(struct usb_configuration *c, u8 port_num)
*/
/* maybe allocate device-global string IDs, and patch descriptors */
- if (acm_string_defs[ACM_CTRL_IDX].id == 0) {
- status = usb_string_id(c->cdev);
+ if (acm_string_defs[0].id == 0) {
+ status = usb_string_ids_tab(c->cdev, acm_string_defs);
if (status < 0)
return status;
- acm_string_defs[ACM_CTRL_IDX].id = status;
-
- acm_control_interface_desc.iInterface = status;
-
- status = usb_string_id(c->cdev);
- if (status < 0)
- return status;
- acm_string_defs[ACM_DATA_IDX].id = status;
-
- acm_data_interface_desc.iInterface = status;
-
- status = usb_string_id(c->cdev);
- if (status < 0)
- return status;
- acm_string_defs[ACM_IAD_IDX].id = status;
-
- acm_iad_descriptor.iFunction = status;
+ acm_control_interface_desc.iInterface =
+ acm_string_defs[ACM_CTRL_IDX].id;
+ acm_data_interface_desc.iInterface =
+ acm_string_defs[ACM_DATA_IDX].id;
+ acm_iad_descriptor.iFunction = acm_string_defs[ACM_IAD_IDX].id;
}
/* allocate and initialize one new instance */
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
index 95bc94f8e57..83420a310fb 100644
--- a/drivers/usb/gadget/f_ecm.c
+++ b/drivers/usb/gadget/f_ecm.c
@@ -91,7 +91,7 @@ static inline unsigned ecm_bitrate(struct usb_gadget *g)
* encapsulated commands (vendor-specific, using control-OUT).
*/
-#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
+#define ECM_STATUS_INTERVAL_MS 32
#define ECM_STATUS_BYTECOUNT 16 /* 8 byte header + data */
@@ -192,7 +192,7 @@ static struct usb_endpoint_descriptor fs_ecm_notify_desc = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
- .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
+ .bInterval = ECM_STATUS_INTERVAL_MS,
};
static struct usb_endpoint_descriptor fs_ecm_in_desc = {
@@ -239,7 +239,7 @@ static struct usb_endpoint_descriptor hs_ecm_notify_desc = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
- .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
+ .bInterval = USB_MS_TO_HS_INTERVAL(ECM_STATUS_INTERVAL_MS),
};
static struct usb_endpoint_descriptor hs_ecm_in_desc = {
@@ -288,7 +288,7 @@ static struct usb_endpoint_descriptor ss_ecm_notify_desc = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
- .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
+ .bInterval = USB_MS_TO_HS_INTERVAL(ECM_STATUS_INTERVAL_MS),
};
static struct usb_ss_ep_comp_descriptor ss_ecm_intr_comp_desc = {
@@ -330,6 +330,7 @@ static struct usb_ss_ep_comp_descriptor ss_ecm_bulk_comp_desc = {
static struct usb_descriptor_header *ecm_ss_function[] = {
/* CDC ECM control descriptors */
+ (struct usb_descriptor_header *) &ecm_iad_descriptor,
(struct usb_descriptor_header *) &ecm_control_intf,
(struct usb_descriptor_header *) &ecm_header_desc,
(struct usb_descriptor_header *) &ecm_union_desc,
@@ -353,7 +354,7 @@ static struct usb_descriptor_header *ecm_ss_function[] = {
static struct usb_string ecm_string_defs[] = {
[0].s = "CDC Ethernet Control Model (ECM)",
- [1].s = NULL /* DYNAMIC */,
+ [1].s = "",
[2].s = "CDC Ethernet Data",
[3].s = "CDC ECM",
{ } /* end of list */
@@ -742,42 +743,24 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
ecm->notify_req->context = ecm;
ecm->notify_req->complete = ecm_notify_complete;
- /* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(ecm_fs_function);
- if (!f->descriptors)
- goto fail;
-
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
*/
- if (gadget_is_dualspeed(c->cdev->gadget)) {
- hs_ecm_in_desc.bEndpointAddress =
- fs_ecm_in_desc.bEndpointAddress;
- hs_ecm_out_desc.bEndpointAddress =
- fs_ecm_out_desc.bEndpointAddress;
- hs_ecm_notify_desc.bEndpointAddress =
- fs_ecm_notify_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->hs_descriptors = usb_copy_descriptors(ecm_hs_function);
- if (!f->hs_descriptors)
- goto fail;
- }
-
- if (gadget_is_superspeed(c->cdev->gadget)) {
- ss_ecm_in_desc.bEndpointAddress =
- fs_ecm_in_desc.bEndpointAddress;
- ss_ecm_out_desc.bEndpointAddress =
- fs_ecm_out_desc.bEndpointAddress;
- ss_ecm_notify_desc.bEndpointAddress =
- fs_ecm_notify_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->ss_descriptors = usb_copy_descriptors(ecm_ss_function);
- if (!f->ss_descriptors)
- goto fail;
- }
+ hs_ecm_in_desc.bEndpointAddress = fs_ecm_in_desc.bEndpointAddress;
+ hs_ecm_out_desc.bEndpointAddress = fs_ecm_out_desc.bEndpointAddress;
+ hs_ecm_notify_desc.bEndpointAddress =
+ fs_ecm_notify_desc.bEndpointAddress;
+
+ ss_ecm_in_desc.bEndpointAddress = fs_ecm_in_desc.bEndpointAddress;
+ ss_ecm_out_desc.bEndpointAddress = fs_ecm_out_desc.bEndpointAddress;
+ ss_ecm_notify_desc.bEndpointAddress =
+ fs_ecm_notify_desc.bEndpointAddress;
+
+ status = usb_assign_descriptors(f, ecm_fs_function, ecm_hs_function,
+ ecm_ss_function);
+ if (status)
+ goto fail;
/* NOTE: all that is done without knowing or caring about
* the network link ... which is unavailable to this code
@@ -795,11 +778,6 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
fail:
- if (f->descriptors)
- usb_free_descriptors(f->descriptors);
- if (f->hs_descriptors)
- usb_free_descriptors(f->hs_descriptors);
-
if (ecm->notify_req) {
kfree(ecm->notify_req->buf);
usb_ep_free_request(ecm->notify, ecm->notify_req);
@@ -808,9 +786,9 @@ fail:
/* we might as well release our claims on endpoints */
if (ecm->notify)
ecm->notify->driver_data = NULL;
- if (ecm->port.out_ep->desc)
+ if (ecm->port.out_ep)
ecm->port.out_ep->driver_data = NULL;
- if (ecm->port.in_ep->desc)
+ if (ecm->port.in_ep)
ecm->port.in_ep->driver_data = NULL;
ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
@@ -825,16 +803,11 @@ ecm_unbind(struct usb_configuration *c, struct usb_function *f)
DBG(c->cdev, "ecm unbind\n");
- if (gadget_is_superspeed(c->cdev->gadget))
- usb_free_descriptors(f->ss_descriptors);
- if (gadget_is_dualspeed(c->cdev->gadget))
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
+ ecm_string_defs[0].id = 0;
+ usb_free_all_descriptors(f);
kfree(ecm->notify_req->buf);
usb_ep_free_request(ecm->notify, ecm->notify_req);
-
- ecm_string_defs[1].s = NULL;
kfree(ecm);
}
@@ -859,36 +832,15 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
if (!can_support_ecm(c->cdev->gadget) || !ethaddr)
return -EINVAL;
- /* maybe allocate device-global string IDs */
if (ecm_string_defs[0].id == 0) {
-
- /* control interface label */
- status = usb_string_id(c->cdev);
- if (status < 0)
- return status;
- ecm_string_defs[0].id = status;
- ecm_control_intf.iInterface = status;
-
- /* data interface label */
- status = usb_string_id(c->cdev);
- if (status < 0)
+ status = usb_string_ids_tab(c->cdev, ecm_string_defs);
+ if (status)
return status;
- ecm_string_defs[2].id = status;
- ecm_data_intf.iInterface = status;
- /* MAC address */
- status = usb_string_id(c->cdev);
- if (status < 0)
- return status;
- ecm_string_defs[1].id = status;
- ecm_desc.iMACAddress = status;
-
- /* IAD label */
- status = usb_string_id(c->cdev);
- if (status < 0)
- return status;
- ecm_string_defs[3].id = status;
- ecm_iad_descriptor.iFunction = status;
+ ecm_control_intf.iInterface = ecm_string_defs[0].id;
+ ecm_data_intf.iInterface = ecm_string_defs[2].id;
+ ecm_desc.iMACAddress = ecm_string_defs[1].id;
+ ecm_iad_descriptor.iFunction = ecm_string_defs[3].id;
}
/* allocate and initialize one new instance */
@@ -913,9 +865,7 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
ecm->port.func.disable = ecm_disable;
status = usb_add_function(c, &ecm->port.func);
- if (status) {
- ecm_string_defs[1].s = NULL;
+ if (status)
kfree(ecm);
- }
return status;
}
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
index 1a7b2dd7d40..cf0ebee8556 100644
--- a/drivers/usb/gadget/f_eem.c
+++ b/drivers/usb/gadget/f_eem.c
@@ -274,38 +274,20 @@ eem_bind(struct usb_configuration *c, struct usb_function *f)
status = -ENOMEM;
- /* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(eem_fs_function);
- if (!f->descriptors)
- goto fail;
-
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
*/
- if (gadget_is_dualspeed(c->cdev->gadget)) {
- eem_hs_in_desc.bEndpointAddress =
- eem_fs_in_desc.bEndpointAddress;
- eem_hs_out_desc.bEndpointAddress =
- eem_fs_out_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->hs_descriptors = usb_copy_descriptors(eem_hs_function);
- if (!f->hs_descriptors)
- goto fail;
- }
+ eem_hs_in_desc.bEndpointAddress = eem_fs_in_desc.bEndpointAddress;
+ eem_hs_out_desc.bEndpointAddress = eem_fs_out_desc.bEndpointAddress;
- if (gadget_is_superspeed(c->cdev->gadget)) {
- eem_ss_in_desc.bEndpointAddress =
- eem_fs_in_desc.bEndpointAddress;
- eem_ss_out_desc.bEndpointAddress =
- eem_fs_out_desc.bEndpointAddress;
+ eem_ss_in_desc.bEndpointAddress = eem_fs_in_desc.bEndpointAddress;
+ eem_ss_out_desc.bEndpointAddress = eem_fs_out_desc.bEndpointAddress;
- /* copy descriptors, and track endpoint copies */
- f->ss_descriptors = usb_copy_descriptors(eem_ss_function);
- if (!f->ss_descriptors)
- goto fail;
- }
+ status = usb_assign_descriptors(f, eem_fs_function, eem_hs_function,
+ eem_ss_function);
+ if (status)
+ goto fail;
DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n",
gadget_is_superspeed(c->cdev->gadget) ? "super" :
@@ -314,15 +296,10 @@ eem_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
fail:
- if (f->descriptors)
- usb_free_descriptors(f->descriptors);
- if (f->hs_descriptors)
- usb_free_descriptors(f->hs_descriptors);
-
- /* we might as well release our claims on endpoints */
- if (eem->port.out_ep->desc)
+ usb_free_all_descriptors(f);
+ if (eem->port.out_ep)
eem->port.out_ep->driver_data = NULL;
- if (eem->port.in_ep->desc)
+ if (eem->port.in_ep)
eem->port.in_ep->driver_data = NULL;
ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
@@ -337,11 +314,7 @@ eem_unbind(struct usb_configuration *c, struct usb_function *f)
DBG(c->cdev, "eem unbind\n");
- if (gadget_is_superspeed(c->cdev->gadget))
- usb_free_descriptors(f->ss_descriptors);
- if (gadget_is_dualspeed(c->cdev->gadget))
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
+ usb_free_all_descriptors(f);
kfree(eem);
}
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 64c4ec10d1f..4a6961c517f 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -2097,7 +2097,7 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
if (isHS)
func->function.hs_descriptors[(long)valuep] = desc;
else
- func->function.descriptors[(long)valuep] = desc;
+ func->function.fs_descriptors[(long)valuep] = desc;
if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT)
return 0;
@@ -2249,7 +2249,7 @@ static int ffs_func_bind(struct usb_configuration *c,
* numbers without worrying that it may be described later on.
*/
if (likely(full)) {
- func->function.descriptors = data->fs_descs;
+ func->function.fs_descriptors = data->fs_descs;
ret = ffs_do_descs(ffs->fs_descs_count,
data->raw_descs,
sizeof data->raw_descs,
diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c
index 511e527178e..6e69a8e8d22 100644
--- a/drivers/usb/gadget/f_hid.c
+++ b/drivers/usb/gadget/f_hid.c
@@ -573,7 +573,6 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f)
goto fail;
hidg_interface_desc.bInterfaceNumber = status;
-
/* allocate instance-specific endpoints */
status = -ENODEV;
ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc);
@@ -609,20 +608,15 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f)
hidg_desc.desc[0].wDescriptorLength =
cpu_to_le16(hidg->report_desc_length);
- /* copy descriptors */
- f->descriptors = usb_copy_descriptors(hidg_fs_descriptors);
- if (!f->descriptors)
- goto fail;
+ hidg_hs_in_ep_desc.bEndpointAddress =
+ hidg_fs_in_ep_desc.bEndpointAddress;
+ hidg_hs_out_ep_desc.bEndpointAddress =
+ hidg_fs_out_ep_desc.bEndpointAddress;
- if (gadget_is_dualspeed(c->cdev->gadget)) {
- hidg_hs_in_ep_desc.bEndpointAddress =
- hidg_fs_in_ep_desc.bEndpointAddress;
- hidg_hs_out_ep_desc.bEndpointAddress =
- hidg_fs_out_ep_desc.bEndpointAddress;
- f->hs_descriptors = usb_copy_descriptors(hidg_hs_descriptors);
- if (!f->hs_descriptors)
- goto fail;
- }
+ status = usb_assign_descriptors(f, hidg_fs_descriptors,
+ hidg_hs_descriptors, NULL);
+ if (status)
+ goto fail;
mutex_init(&hidg->lock);
spin_lock_init(&hidg->spinlock);
@@ -649,9 +643,7 @@ fail:
usb_ep_free_request(hidg->in_ep, hidg->req);
}
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
-
+ usb_free_all_descriptors(f);
return status;
}
@@ -668,9 +660,7 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
kfree(hidg->req->buf);
usb_ep_free_request(hidg->in_ep, hidg->req);
- /* free descriptors copies */
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
+ usb_free_all_descriptors(f);
kfree(hidg->report_desc);
kfree(hidg);
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 7275706caeb..bb39cb2bb3a 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -177,6 +177,7 @@ loopback_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_composite_dev *cdev = c->cdev;
struct f_loopback *loop = func_to_loop(f);
int id;
+ int ret;
/* allocate interface ID(s) */
id = usb_interface_id(c, f);
@@ -201,22 +202,19 @@ autoconf_fail:
loop->out_ep->driver_data = cdev; /* claim */
/* support high speed hardware */
- if (gadget_is_dualspeed(c->cdev->gadget)) {
- hs_loop_source_desc.bEndpointAddress =
- fs_loop_source_desc.bEndpointAddress;
- hs_loop_sink_desc.bEndpointAddress =
- fs_loop_sink_desc.bEndpointAddress;
- f->hs_descriptors = hs_loopback_descs;
- }
+ hs_loop_source_desc.bEndpointAddress =
+ fs_loop_source_desc.bEndpointAddress;
+ hs_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress;
/* support super speed hardware */
- if (gadget_is_superspeed(c->cdev->gadget)) {
- ss_loop_source_desc.bEndpointAddress =
- fs_loop_source_desc.bEndpointAddress;
- ss_loop_sink_desc.bEndpointAddress =
- fs_loop_sink_desc.bEndpointAddress;
- f->ss_descriptors = ss_loopback_descs;
- }
+ ss_loop_source_desc.bEndpointAddress =
+ fs_loop_source_desc.bEndpointAddress;
+ ss_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress;
+
+ ret = usb_assign_descriptors(f, fs_loopback_descs, hs_loopback_descs,
+ ss_loopback_descs);
+ if (ret)
+ return ret;
DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
(gadget_is_superspeed(c->cdev->gadget) ? "super" :
@@ -228,6 +226,7 @@ autoconf_fail:
static void
loopback_unbind(struct usb_configuration *c, struct usb_function *f)
{
+ usb_free_all_descriptors(f);
kfree(func_to_loop(f));
}
@@ -379,7 +378,6 @@ static int __init loopback_bind_config(struct usb_configuration *c)
return -ENOMEM;
loop->function.name = "loopback";
- loop->function.descriptors = fs_loopback_descs;
loop->function.bind = loopback_bind;
loop->function.unbind = loopback_unbind;
loop->function.set_alt = loopback_set_alt;
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 3a7668bde3e..5d027b3e1ef 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -228,10 +228,6 @@
static const char fsg_string_interface[] = "Mass Storage";
-#define FSG_NO_DEVICE_STRINGS 1
-#define FSG_NO_OTG 1
-#define FSG_NO_INTR_EP 1
-
#include "storage_common.c"
@@ -2904,9 +2900,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
}
fsg_common_put(common);
- usb_free_descriptors(fsg->function.descriptors);
- usb_free_descriptors(fsg->function.hs_descriptors);
- usb_free_descriptors(fsg->function.ss_descriptors);
+ usb_free_all_descriptors(&fsg->function);
kfree(fsg);
}
@@ -2916,6 +2910,8 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_gadget *gadget = c->cdev->gadget;
int i;
struct usb_ep *ep;
+ unsigned max_burst;
+ int ret;
fsg->gadget = gadget;
@@ -2939,45 +2935,27 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
ep->driver_data = fsg->common; /* claim the endpoint */
fsg->bulk_out = ep;
- /* Copy descriptors */
- f->descriptors = usb_copy_descriptors(fsg_fs_function);
- if (unlikely(!f->descriptors))
- return -ENOMEM;
-
- if (gadget_is_dualspeed(gadget)) {
- /* Assume endpoint addresses are the same for both speeds */
- fsg_hs_bulk_in_desc.bEndpointAddress =
- fsg_fs_bulk_in_desc.bEndpointAddress;
- fsg_hs_bulk_out_desc.bEndpointAddress =
- fsg_fs_bulk_out_desc.bEndpointAddress;
- f->hs_descriptors = usb_copy_descriptors(fsg_hs_function);
- if (unlikely(!f->hs_descriptors)) {
- usb_free_descriptors(f->descriptors);
- return -ENOMEM;
- }
- }
-
- if (gadget_is_superspeed(gadget)) {
- unsigned max_burst;
+ /* Assume endpoint addresses are the same for both speeds */
+ fsg_hs_bulk_in_desc.bEndpointAddress =
+ fsg_fs_bulk_in_desc.bEndpointAddress;
+ fsg_hs_bulk_out_desc.bEndpointAddress =
+ fsg_fs_bulk_out_desc.bEndpointAddress;
- /* Calculate bMaxBurst, we know packet size is 1024 */
- max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15);
+ /* Calculate bMaxBurst, we know packet size is 1024 */
+ max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15);
- fsg_ss_bulk_in_desc.bEndpointAddress =
- fsg_fs_bulk_in_desc.bEndpointAddress;
- fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
+ fsg_ss_bulk_in_desc.bEndpointAddress =
+ fsg_fs_bulk_in_desc.bEndpointAddress;
+ fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
- fsg_ss_bulk_out_desc.bEndpointAddress =
- fsg_fs_bulk_out_desc.bEndpointAddress;
- fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
+ fsg_ss_bulk_out_desc.bEndpointAddress =
+ fsg_fs_bulk_out_desc.bEndpointAddress;
+ fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
- f->ss_descriptors = usb_copy_descriptors(fsg_ss_function);
- if (unlikely(!f->ss_descriptors)) {
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
- return -ENOMEM;
- }
- }
+ ret = usb_assign_descriptors(f, fsg_fs_function, fsg_hs_function,
+ fsg_ss_function);
+ if (ret)
+ goto autoconf_fail;
return 0;
@@ -2986,7 +2964,6 @@ autoconf_fail:
return -ENOTSUPP;
}
-
/****************************** ADD FUNCTION ******************************/
static struct usb_gadget_strings *fsg_strings_array[] = {
diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/f_midi.c
index 8ed1259fe80..263e721c269 100644
--- a/drivers/usb/gadget/f_midi.c
+++ b/drivers/usb/gadget/f_midi.c
@@ -414,7 +414,7 @@ static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f)
kfree(midi->id);
midi->id = NULL;
- usb_free_descriptors(f->descriptors);
+ usb_free_all_descriptors(f);
kfree(midi);
}
@@ -881,19 +881,25 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)
* both speeds
*/
/* copy descriptors, and track endpoint copies */
+ f->fs_descriptors = usb_copy_descriptors(midi_function);
+ if (!f->fs_descriptors)
+ goto fail_f_midi;
+
if (gadget_is_dualspeed(c->cdev->gadget)) {
- c->highspeed = true;
bulk_in_desc.wMaxPacketSize = cpu_to_le16(512);
bulk_out_desc.wMaxPacketSize = cpu_to_le16(512);
f->hs_descriptors = usb_copy_descriptors(midi_function);
- } else {
- f->descriptors = usb_copy_descriptors(midi_function);
+ if (!f->hs_descriptors)
+ goto fail_f_midi;
}
kfree(midi_function);
return 0;
+fail_f_midi:
+ kfree(midi_function);
+ usb_free_descriptors(f->hs_descriptors);
fail:
/* we might as well release our claims on endpoints */
if (midi->out_ep)
diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
index b651b529c67..6c8362f937b 100644
--- a/drivers/usb/gadget/f_ncm.c
+++ b/drivers/usb/gadget/f_ncm.c
@@ -102,7 +102,7 @@ static inline unsigned ncm_bitrate(struct usb_gadget *g)
USB_CDC_NCM_NTB32_SUPPORTED)
static struct usb_cdc_ncm_ntb_parameters ntb_parameters = {
- .wLength = sizeof ntb_parameters,
+ .wLength = cpu_to_le16(sizeof(ntb_parameters)),
.bmNtbFormatsSupported = cpu_to_le16(FORMATS_SUPPORTED),
.dwNtbInMaxSize = cpu_to_le32(NTB_DEFAULT_IN_SIZE),
.wNdpInDivisor = cpu_to_le16(4),
@@ -121,7 +121,7 @@ static struct usb_cdc_ncm_ntb_parameters ntb_parameters = {
* waste less bandwidth.
*/
-#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
+#define NCM_STATUS_INTERVAL_MS 32
#define NCM_STATUS_BYTECOUNT 16 /* 8 byte header + data */
static struct usb_interface_assoc_descriptor ncm_iad_desc __initdata = {
@@ -230,7 +230,7 @@ static struct usb_endpoint_descriptor fs_ncm_notify_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(NCM_STATUS_BYTECOUNT),
- .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
+ .bInterval = NCM_STATUS_INTERVAL_MS,
};
static struct usb_endpoint_descriptor fs_ncm_in_desc __initdata = {
@@ -275,7 +275,7 @@ static struct usb_endpoint_descriptor hs_ncm_notify_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(NCM_STATUS_BYTECOUNT),
- .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
+ .bInterval = USB_MS_TO_HS_INTERVAL(NCM_STATUS_INTERVAL_MS),
};
static struct usb_endpoint_descriptor hs_ncm_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
@@ -321,7 +321,7 @@ static struct usb_descriptor_header *ncm_hs_function[] __initdata = {
static struct usb_string ncm_string_defs[] = {
[STRING_CTRL_IDX].s = "CDC Network Control Model (NCM)",
- [STRING_MAC_IDX].s = NULL /* DYNAMIC */,
+ [STRING_MAC_IDX].s = "",
[STRING_DATA_IDX].s = "CDC Network Data",
[STRING_IAD_IDX].s = "CDC NCM",
{ } /* end of list */
@@ -869,15 +869,19 @@ static struct sk_buff *ncm_wrap_ntb(struct gether *port,
struct sk_buff *skb2;
int ncb_len = 0;
__le16 *tmp;
- int div = ntb_parameters.wNdpInDivisor;
- int rem = ntb_parameters.wNdpInPayloadRemainder;
+ int div;
+ int rem;
int pad;
- int ndp_align = ntb_parameters.wNdpInAlignment;
+ int ndp_align;
int ndp_pad;
unsigned max_size = ncm->port.fixed_in_len;
struct ndp_parser_opts *opts = ncm->parser_opts;
unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0;
+ div = le16_to_cpu(ntb_parameters.wNdpInDivisor);
+ rem = le16_to_cpu(ntb_parameters.wNdpInPayloadRemainder);
+ ndp_align = le16_to_cpu(ntb_parameters.wNdpInAlignment);
+
ncb_len += opts->nth_size;
ndp_pad = ALIGN(ncb_len, ndp_align) - ncb_len;
ncb_len += ndp_pad;
@@ -1208,30 +1212,18 @@ ncm_bind(struct usb_configuration *c, struct usb_function *f)
ncm->notify_req->context = ncm;
ncm->notify_req->complete = ncm_notify_complete;
- /* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(ncm_fs_function);
- if (!f->descriptors)
- goto fail;
-
/*
* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
*/
- if (gadget_is_dualspeed(c->cdev->gadget)) {
- hs_ncm_in_desc.bEndpointAddress =
- fs_ncm_in_desc.bEndpointAddress;
- hs_ncm_out_desc.bEndpointAddress =
- fs_ncm_out_desc.bEndpointAddress;
- hs_ncm_notify_desc.bEndpointAddress =
- fs_ncm_notify_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->hs_descriptors = usb_copy_descriptors(ncm_hs_function);
- if (!f->hs_descriptors)
- goto fail;
- }
+ hs_ncm_in_desc.bEndpointAddress = fs_ncm_in_desc.bEndpointAddress;
+ hs_ncm_out_desc.bEndpointAddress = fs_ncm_out_desc.bEndpointAddress;
+ hs_ncm_notify_desc.bEndpointAddress =
+ fs_ncm_notify_desc.bEndpointAddress;
+ status = usb_assign_descriptors(f, ncm_fs_function, ncm_hs_function,
+ NULL);
/*
* NOTE: all that is done without knowing or caring about
* the network link ... which is unavailable to this code
@@ -1248,9 +1240,7 @@ ncm_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
fail:
- if (f->descriptors)
- usb_free_descriptors(f->descriptors);
-
+ usb_free_all_descriptors(f);
if (ncm->notify_req) {
kfree(ncm->notify_req->buf);
usb_ep_free_request(ncm->notify, ncm->notify_req);
@@ -1259,9 +1249,9 @@ fail:
/* we might as well release our claims on endpoints */
if (ncm->notify)
ncm->notify->driver_data = NULL;
- if (ncm->port.out_ep->desc)
+ if (ncm->port.out_ep)
ncm->port.out_ep->driver_data = NULL;
- if (ncm->port.in_ep->desc)
+ if (ncm->port.in_ep)
ncm->port.in_ep->driver_data = NULL;
ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
@@ -1276,14 +1266,12 @@ ncm_unbind(struct usb_configuration *c, struct usb_function *f)
DBG(c->cdev, "ncm unbind\n");
- if (gadget_is_dualspeed(c->cdev->gadget))
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
+ ncm_string_defs[0].id = 0;
+ usb_free_all_descriptors(f);
kfree(ncm->notify_req->buf);
usb_ep_free_request(ncm->notify, ncm->notify_req);
- ncm_string_defs[1].s = NULL;
kfree(ncm);
}
@@ -1307,37 +1295,19 @@ int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
if (!can_support_ecm(c->cdev->gadget) || !ethaddr)
return -EINVAL;
- /* maybe allocate device-global string IDs */
if (ncm_string_defs[0].id == 0) {
-
- /* control interface label */
- status = usb_string_id(c->cdev);
+ status = usb_string_ids_tab(c->cdev, ncm_string_defs);
if (status < 0)
return status;
- ncm_string_defs[STRING_CTRL_IDX].id = status;
- ncm_control_intf.iInterface = status;
+ ncm_control_intf.iInterface =
+ ncm_string_defs[STRING_CTRL_IDX].id;
- /* data interface label */
- status = usb_string_id(c->cdev);
- if (status < 0)
- return status;
- ncm_string_defs[STRING_DATA_IDX].id = status;
+ status = ncm_string_defs[STRING_DATA_IDX].id;
ncm_data_nop_intf.iInterface = status;
ncm_data_intf.iInterface = status;
- /* MAC address */
- status = usb_string_id(c->cdev);
- if (status < 0)
- return status;
- ncm_string_defs[STRING_MAC_IDX].id = status;
- ecm_desc.iMACAddress = status;
-
- /* IAD */
- status = usb_string_id(c->cdev);
- if (status < 0)
- return status;
- ncm_string_defs[STRING_IAD_IDX].id = status;
- ncm_iad_desc.iFunction = status;
+ ecm_desc.iMACAddress = ncm_string_defs[STRING_MAC_IDX].id;
+ ncm_iad_desc.iFunction = ncm_string_defs[STRING_IAD_IDX].id;
}
/* allocate and initialize one new instance */
@@ -1347,7 +1317,7 @@ int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
/* export host's Ethernet address in CDC format */
snprintf(ncm->ethaddr, sizeof ncm->ethaddr, "%pm", ethaddr);
- ncm_string_defs[1].s = ncm->ethaddr;
+ ncm_string_defs[STRING_MAC_IDX].s = ncm->ethaddr;
spin_lock_init(&ncm->lock);
ncm_reset_values(ncm);
@@ -1367,9 +1337,7 @@ int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
ncm->port.unwrap = ncm_unwrap_ntb;
status = usb_add_function(c, &ncm->port.func);
- if (status) {
- ncm_string_defs[1].s = NULL;
+ if (status)
kfree(ncm);
- }
return status;
}
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c
index 5f400f66aa9..d8dd8782768 100644
--- a/drivers/usb/gadget/f_obex.c
+++ b/drivers/usb/gadget/f_obex.c
@@ -331,23 +331,19 @@ obex_bind(struct usb_configuration *c, struct usb_function *f)
obex->port.out = ep;
ep->driver_data = cdev; /* claim */
- /* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(fs_function);
-
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
*/
- if (gadget_is_dualspeed(c->cdev->gadget)) {
- obex_hs_ep_in_desc.bEndpointAddress =
- obex_fs_ep_in_desc.bEndpointAddress;
- obex_hs_ep_out_desc.bEndpointAddress =
- obex_fs_ep_out_desc.bEndpointAddress;
+ obex_hs_ep_in_desc.bEndpointAddress =
+ obex_fs_ep_in_desc.bEndpointAddress;
+ obex_hs_ep_out_desc.bEndpointAddress =
+ obex_fs_ep_out_desc.bEndpointAddress;
- /* copy descriptors, and track endpoint copies */
- f->hs_descriptors = usb_copy_descriptors(hs_function);
- }
+ status = usb_assign_descriptors(f, fs_function, hs_function, NULL);
+ if (status)
+ goto fail;
/* Avoid letting this gadget enumerate until the userspace
* OBEX server is active.
@@ -368,6 +364,7 @@ obex_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
fail:
+ usb_free_all_descriptors(f);
/* we might as well release our claims on endpoints */
if (obex->port.out)
obex->port.out->driver_data = NULL;
@@ -382,9 +379,8 @@ fail:
static void
obex_unbind(struct usb_configuration *c, struct usb_function *f)
{
- if (gadget_is_dualspeed(c->cdev->gadget))
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
+ obex_string_defs[OBEX_CTRL_IDX].id = 0;
+ usb_free_all_descriptors(f);
kfree(func_to_obex(f));
}
@@ -423,22 +419,16 @@ int __init obex_bind_config(struct usb_configuration *c, u8 port_num)
if (!can_support_obex(c))
return -EINVAL;
- /* maybe allocate device-global string IDs, and patch descriptors */
if (obex_string_defs[OBEX_CTRL_IDX].id == 0) {
- status = usb_string_id(c->cdev);
- if (status < 0)
- return status;
- obex_string_defs[OBEX_CTRL_IDX].id = status;
-
- obex_control_intf.iInterface = status;
-
- status = usb_string_id(c->cdev);
+ status = usb_string_ids_tab(c->cdev, obex_string_defs);
if (status < 0)
return status;
- obex_string_defs[OBEX_DATA_IDX].id = status;
+ obex_control_intf.iInterface =
+ obex_string_defs[OBEX_CTRL_IDX].id;
- obex_data_nop_intf.iInterface =
- obex_data_intf.iInterface = status;
+ status = obex_string_defs[OBEX_DATA_IDX].id;
+ obex_data_nop_intf.iInterface = status;
+ obex_data_intf.iInterface = status;
}
/* allocate and initialize one new instance */
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
index 8ee9268fe25..b21ab558b6c 100644
--- a/drivers/usb/gadget/f_phonet.c
+++ b/drivers/usb/gadget/f_phonet.c
@@ -515,14 +515,14 @@ int pn_bind(struct usb_configuration *c, struct usb_function *f)
fp->in_ep = ep;
ep->driver_data = fp; /* Claim */
- pn_hs_sink_desc.bEndpointAddress =
- pn_fs_sink_desc.bEndpointAddress;
- pn_hs_source_desc.bEndpointAddress =
- pn_fs_source_desc.bEndpointAddress;
+ pn_hs_sink_desc.bEndpointAddress = pn_fs_sink_desc.bEndpointAddress;
+ pn_hs_source_desc.bEndpointAddress = pn_fs_source_desc.bEndpointAddress;
/* Do not try to bind Phonet twice... */
- fp->function.descriptors = fs_pn_function;
- fp->function.hs_descriptors = hs_pn_function;
+ status = usb_assign_descriptors(f, fs_pn_function, hs_pn_function,
+ NULL);
+ if (status)
+ goto err;
/* Incoming USB requests */
status = -ENOMEM;
@@ -531,7 +531,7 @@ int pn_bind(struct usb_configuration *c, struct usb_function *f)
req = usb_ep_alloc_request(fp->out_ep, GFP_KERNEL);
if (!req)
- goto err;
+ goto err_req;
req->complete = pn_rx_complete;
fp->out_reqv[i] = req;
@@ -540,14 +540,18 @@ int pn_bind(struct usb_configuration *c, struct usb_function *f)
/* Outgoing USB requests */
fp->in_req = usb_ep_alloc_request(fp->in_ep, GFP_KERNEL);
if (!fp->in_req)
- goto err;
+ goto err_req;
INFO(cdev, "USB CDC Phonet function\n");
INFO(cdev, "using %s, OUT %s, IN %s\n", cdev->gadget->name,
fp->out_ep->name, fp->in_ep->name);
return 0;
+err_req:
+ for (i = 0; i < phonet_rxq_size && fp->out_reqv[i]; i++)
+ usb_ep_free_request(fp->out_ep, fp->out_reqv[i]);
err:
+ usb_free_all_descriptors(f);
if (fp->out_ep)
fp->out_ep->driver_data = NULL;
if (fp->in_ep)
@@ -569,6 +573,7 @@ pn_unbind(struct usb_configuration *c, struct usb_function *f)
if (fp->out_reqv[i])
usb_ep_free_request(fp->out_ep, fp->out_reqv[i]);
+ usb_free_all_descriptors(f);
kfree(fp);
}
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index b1681e45aca..71beeb83355 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -101,7 +101,7 @@ static unsigned int bitrate(struct usb_gadget *g)
/*
*/
-#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
+#define RNDIS_STATUS_INTERVAL_MS 32
#define STATUS_BYTECOUNT 8 /* 8 bytes data */
@@ -190,7 +190,7 @@ static struct usb_endpoint_descriptor fs_notify_desc = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
- .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
+ .bInterval = RNDIS_STATUS_INTERVAL_MS,
};
static struct usb_endpoint_descriptor fs_in_desc = {
@@ -236,7 +236,7 @@ static struct usb_endpoint_descriptor hs_notify_desc = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
- .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
+ .bInterval = USB_MS_TO_HS_INTERVAL(RNDIS_STATUS_INTERVAL_MS)
};
static struct usb_endpoint_descriptor hs_in_desc = {
@@ -284,7 +284,7 @@ static struct usb_endpoint_descriptor ss_notify_desc = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
- .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
+ .bInterval = USB_MS_TO_HS_INTERVAL(RNDIS_STATUS_INTERVAL_MS)
};
static struct usb_ss_ep_comp_descriptor ss_intr_comp_desc = {
@@ -722,42 +722,22 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
rndis->notify_req->context = rndis;
rndis->notify_req->complete = rndis_response_complete;
- /* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(eth_fs_function);
- if (!f->descriptors)
- goto fail;
-
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
*/
- if (gadget_is_dualspeed(c->cdev->gadget)) {
- hs_in_desc.bEndpointAddress =
- fs_in_desc.bEndpointAddress;
- hs_out_desc.bEndpointAddress =
- fs_out_desc.bEndpointAddress;
- hs_notify_desc.bEndpointAddress =
- fs_notify_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->hs_descriptors = usb_copy_descriptors(eth_hs_function);
- if (!f->hs_descriptors)
- goto fail;
- }
+ hs_in_desc.bEndpointAddress = fs_in_desc.bEndpointAddress;
+ hs_out_desc.bEndpointAddress = fs_out_desc.bEndpointAddress;
+ hs_notify_desc.bEndpointAddress = fs_notify_desc.bEndpointAddress;
- if (gadget_is_superspeed(c->cdev->gadget)) {
- ss_in_desc.bEndpointAddress =
- fs_in_desc.bEndpointAddress;
- ss_out_desc.bEndpointAddress =
- fs_out_desc.bEndpointAddress;
- ss_notify_desc.bEndpointAddress =
- fs_notify_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->ss_descriptors = usb_copy_descriptors(eth_ss_function);
- if (!f->ss_descriptors)
- goto fail;
- }
+ ss_in_desc.bEndpointAddress = fs_in_desc.bEndpointAddress;
+ ss_out_desc.bEndpointAddress = fs_out_desc.bEndpointAddress;
+ ss_notify_desc.bEndpointAddress = fs_notify_desc.bEndpointAddress;
+
+ status = usb_assign_descriptors(f, eth_fs_function, eth_hs_function,
+ eth_ss_function);
+ if (status)
+ goto fail;
rndis->port.open = rndis_open;
rndis->port.close = rndis_close;
@@ -788,12 +768,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
fail:
- if (gadget_is_superspeed(c->cdev->gadget) && f->ss_descriptors)
- usb_free_descriptors(f->ss_descriptors);
- if (gadget_is_dualspeed(c->cdev->gadget) && f->hs_descriptors)
- usb_free_descriptors(f->hs_descriptors);
- if (f->descriptors)
- usb_free_descriptors(f->descriptors);
+ usb_free_all_descriptors(f);
if (rndis->notify_req) {
kfree(rndis->notify_req->buf);
@@ -803,9 +778,9 @@ fail:
/* we might as well release our claims on endpoints */
if (rndis->notify)
rndis->notify->driver_data = NULL;
- if (rndis->port.out_ep->desc)
+ if (rndis->port.out_ep)
rndis->port.out_ep->driver_data = NULL;
- if (rndis->port.in_ep->desc)
+ if (rndis->port.in_ep)
rndis->port.in_ep->driver_data = NULL;
ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
@@ -820,13 +795,9 @@ rndis_unbind(struct usb_configuration *c, struct usb_function *f)
rndis_deregister(rndis->config);
rndis_exit();
- rndis_string_defs[0].id = 0;
- if (gadget_is_superspeed(c->cdev->gadget))
- usb_free_descriptors(f->ss_descriptors);
- if (gadget_is_dualspeed(c->cdev->gadget))
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
+ rndis_string_defs[0].id = 0;
+ usb_free_all_descriptors(f);
kfree(rndis->notify_req->buf);
usb_ep_free_request(rndis->notify, rndis->notify_req);
@@ -851,34 +822,19 @@ rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
if (!can_support_rndis(c) || !ethaddr)
return -EINVAL;
- /* maybe allocate device-global string IDs */
if (rndis_string_defs[0].id == 0) {
-
/* ... and setup RNDIS itself */
status = rndis_init();
if (status < 0)
return status;
- /* control interface label */
- status = usb_string_id(c->cdev);
- if (status < 0)
+ status = usb_string_ids_tab(c->cdev, rndis_string_defs);
+ if (status)
return status;
- rndis_string_defs[0].id = status;
- rndis_control_intf.iInterface = status;
- /* data interface label */
- status = usb_string_id(c->cdev);
- if (status < 0)
- return status;
- rndis_string_defs[1].id = status;
- rndis_data_intf.iInterface = status;
-
- /* IAD iFunction label */
- status = usb_string_id(c->cdev);
- if (status < 0)
- return status;
- rndis_string_defs[2].id = status;
- rndis_iad_descriptor.iFunction = status;
+ rndis_control_intf.iInterface = rndis_string_defs[0].id;
+ rndis_data_intf.iInterface = rndis_string_defs[1].id;
+ rndis_iad_descriptor.iFunction = rndis_string_defs[2].id;
}
/* allocate and initialize one new instance */
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index 07197d63d9b..98fa7795df5 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -213,34 +213,20 @@ gser_bind(struct usb_configuration *c, struct usb_function *f)
gser->port.out = ep;
ep->driver_data = cdev; /* claim */
- /* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(gser_fs_function);
-
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
*/
- if (gadget_is_dualspeed(c->cdev->gadget)) {
- gser_hs_in_desc.bEndpointAddress =
- gser_fs_in_desc.bEndpointAddress;
- gser_hs_out_desc.bEndpointAddress =
- gser_fs_out_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->hs_descriptors = usb_copy_descriptors(gser_hs_function);
- }
- if (gadget_is_superspeed(c->cdev->gadget)) {
- gser_ss_in_desc.bEndpointAddress =
- gser_fs_in_desc.bEndpointAddress;
- gser_ss_out_desc.bEndpointAddress =
- gser_fs_out_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->ss_descriptors = usb_copy_descriptors(gser_ss_function);
- if (!f->ss_descriptors)
- goto fail;
- }
+ gser_hs_in_desc.bEndpointAddress = gser_fs_in_desc.bEndpointAddress;
+ gser_hs_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress;
+ gser_ss_in_desc.bEndpointAddress = gser_fs_in_desc.bEndpointAddress;
+ gser_ss_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress;
+
+ status = usb_assign_descriptors(f, gser_fs_function, gser_hs_function,
+ gser_ss_function);
+ if (status)
+ goto fail;
DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n",
gser->port_num,
gadget_is_superspeed(c->cdev->gadget) ? "super" :
@@ -263,11 +249,7 @@ fail:
static void
gser_unbind(struct usb_configuration *c, struct usb_function *f)
{
- if (gadget_is_dualspeed(c->cdev->gadget))
- usb_free_descriptors(f->hs_descriptors);
- if (gadget_is_superspeed(c->cdev->gadget))
- usb_free_descriptors(f->ss_descriptors);
- usb_free_descriptors(f->descriptors);
+ usb_free_all_descriptors(f);
kfree(func_to_gser(f));
}
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index 3c126fde6e7..102d49beb9d 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -319,6 +319,7 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_composite_dev *cdev = c->cdev;
struct f_sourcesink *ss = func_to_ss(f);
int id;
+ int ret;
/* allocate interface ID(s) */
id = usb_interface_id(c, f);
@@ -387,64 +388,57 @@ no_iso:
isoc_maxpacket = 1024;
/* support high speed hardware */
- if (gadget_is_dualspeed(c->cdev->gadget)) {
- hs_source_desc.bEndpointAddress =
- fs_source_desc.bEndpointAddress;
- hs_sink_desc.bEndpointAddress =
- fs_sink_desc.bEndpointAddress;
+ hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
+ hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress;
- /*
- * Fill in the HS isoc descriptors from the module parameters.
- * We assume that the user knows what they are doing and won't
- * give parameters that their UDC doesn't support.
- */
- hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
- hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11;
- hs_iso_source_desc.bInterval = isoc_interval;
- hs_iso_source_desc.bEndpointAddress =
- fs_iso_source_desc.bEndpointAddress;
-
- hs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
- hs_iso_sink_desc.wMaxPacketSize |= isoc_mult << 11;
- hs_iso_sink_desc.bInterval = isoc_interval;
- hs_iso_sink_desc.bEndpointAddress =
- fs_iso_sink_desc.bEndpointAddress;
-
- f->hs_descriptors = hs_source_sink_descs;
- }
+ /*
+ * Fill in the HS isoc descriptors from the module parameters.
+ * We assume that the user knows what they are doing and won't
+ * give parameters that their UDC doesn't support.
+ */
+ hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
+ hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11;
+ hs_iso_source_desc.bInterval = isoc_interval;
+ hs_iso_source_desc.bEndpointAddress =
+ fs_iso_source_desc.bEndpointAddress;
+
+ hs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
+ hs_iso_sink_desc.wMaxPacketSize |= isoc_mult << 11;
+ hs_iso_sink_desc.bInterval = isoc_interval;
+ hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
/* support super speed hardware */
- if (gadget_is_superspeed(c->cdev->gadget)) {
- ss_source_desc.bEndpointAddress =
- fs_source_desc.bEndpointAddress;
- ss_sink_desc.bEndpointAddress =
- fs_sink_desc.bEndpointAddress;
+ ss_source_desc.bEndpointAddress =
+ fs_source_desc.bEndpointAddress;
+ ss_sink_desc.bEndpointAddress =
+ fs_sink_desc.bEndpointAddress;
- /*
- * Fill in the SS isoc descriptors from the module parameters.
- * We assume that the user knows what they are doing and won't
- * give parameters that their UDC doesn't support.
- */
- ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
- ss_iso_source_desc.bInterval = isoc_interval;
- ss_iso_source_comp_desc.bmAttributes = isoc_mult;
- ss_iso_source_comp_desc.bMaxBurst = isoc_maxburst;
- ss_iso_source_comp_desc.wBytesPerInterval =
- isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
- ss_iso_source_desc.bEndpointAddress =
- fs_iso_source_desc.bEndpointAddress;
-
- ss_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
- ss_iso_sink_desc.bInterval = isoc_interval;
- ss_iso_sink_comp_desc.bmAttributes = isoc_mult;
- ss_iso_sink_comp_desc.bMaxBurst = isoc_maxburst;
- ss_iso_sink_comp_desc.wBytesPerInterval =
- isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
- ss_iso_sink_desc.bEndpointAddress =
- fs_iso_sink_desc.bEndpointAddress;
-
- f->ss_descriptors = ss_source_sink_descs;
- }
+ /*
+ * Fill in the SS isoc descriptors from the module parameters.
+ * We assume that the user knows what they are doing and won't
+ * give parameters that their UDC doesn't support.
+ */
+ ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
+ ss_iso_source_desc.bInterval = isoc_interval;
+ ss_iso_source_comp_desc.bmAttributes = isoc_mult;
+ ss_iso_source_comp_desc.bMaxBurst = isoc_maxburst;
+ ss_iso_source_comp_desc.wBytesPerInterval =
+ isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
+ ss_iso_source_desc.bEndpointAddress =
+ fs_iso_source_desc.bEndpointAddress;
+
+ ss_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
+ ss_iso_sink_desc.bInterval = isoc_interval;
+ ss_iso_sink_comp_desc.bmAttributes = isoc_mult;
+ ss_iso_sink_comp_desc.bMaxBurst = isoc_maxburst;
+ ss_iso_sink_comp_desc.wBytesPerInterval =
+ isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
+ ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
+
+ ret = usb_assign_descriptors(f, fs_source_sink_descs,
+ hs_source_sink_descs, ss_source_sink_descs);
+ if (ret)
+ return ret;
DBG(cdev, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s\n",
(gadget_is_superspeed(c->cdev->gadget) ? "super" :
@@ -458,6 +452,7 @@ no_iso:
static void
sourcesink_unbind(struct usb_configuration *c, struct usb_function *f)
{
+ usb_free_all_descriptors(f);
kfree(func_to_ss(f));
}
@@ -773,7 +768,6 @@ static int __init sourcesink_bind_config(struct usb_configuration *c)
return -ENOMEM;
ss->function.name = "source/sink";
- ss->function.descriptors = fs_source_sink_descs;
ss->function.bind = sourcesink_bind;
ss->function.unbind = sourcesink_unbind;
ss->function.set_alt = sourcesink_set_alt;
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
index 4060c0bd978..f172bd152fb 100644
--- a/drivers/usb/gadget/f_subset.c
+++ b/drivers/usb/gadget/f_subset.c
@@ -236,7 +236,7 @@ static struct usb_descriptor_header *ss_eth_function[] = {
static struct usb_string geth_string_defs[] = {
[0].s = "CDC Ethernet Subset/SAFE",
- [1].s = NULL /* DYNAMIC */,
+ [1].s = "",
{ } /* end of list */
};
@@ -319,38 +319,22 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
geth->port.out_ep = ep;
ep->driver_data = cdev; /* claim */
- /* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(fs_eth_function);
- if (!f->descriptors)
- goto fail;
-
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
*/
- if (gadget_is_dualspeed(c->cdev->gadget)) {
- hs_subset_in_desc.bEndpointAddress =
- fs_subset_in_desc.bEndpointAddress;
- hs_subset_out_desc.bEndpointAddress =
- fs_subset_out_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->hs_descriptors = usb_copy_descriptors(hs_eth_function);
- if (!f->hs_descriptors)
- goto fail;
- }
+ hs_subset_in_desc.bEndpointAddress = fs_subset_in_desc.bEndpointAddress;
+ hs_subset_out_desc.bEndpointAddress =
+ fs_subset_out_desc.bEndpointAddress;
- if (gadget_is_superspeed(c->cdev->gadget)) {
- ss_subset_in_desc.bEndpointAddress =
- fs_subset_in_desc.bEndpointAddress;
- ss_subset_out_desc.bEndpointAddress =
- fs_subset_out_desc.bEndpointAddress;
+ ss_subset_in_desc.bEndpointAddress = fs_subset_in_desc.bEndpointAddress;
+ ss_subset_out_desc.bEndpointAddress =
+ fs_subset_out_desc.bEndpointAddress;
- /* copy descriptors, and track endpoint copies */
- f->ss_descriptors = usb_copy_descriptors(ss_eth_function);
- if (!f->ss_descriptors)
- goto fail;
- }
+ status = usb_assign_descriptors(f, fs_eth_function, hs_eth_function,
+ ss_eth_function);
+ if (status)
+ goto fail;
/* NOTE: all that is done without knowing or caring about
* the network link ... which is unavailable to this code
@@ -364,15 +348,11 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
fail:
- if (f->descriptors)
- usb_free_descriptors(f->descriptors);
- if (f->hs_descriptors)
- usb_free_descriptors(f->hs_descriptors);
-
+ usb_free_all_descriptors(f);
/* we might as well release our claims on endpoints */
- if (geth->port.out_ep->desc)
+ if (geth->port.out_ep)
geth->port.out_ep->driver_data = NULL;
- if (geth->port.in_ep->desc)
+ if (geth->port.in_ep)
geth->port.in_ep->driver_data = NULL;
ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
@@ -383,12 +363,8 @@ fail:
static void
geth_unbind(struct usb_configuration *c, struct usb_function *f)
{
- if (gadget_is_superspeed(c->cdev->gadget))
- usb_free_descriptors(f->ss_descriptors);
- if (gadget_is_dualspeed(c->cdev->gadget))
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
- geth_string_defs[1].s = NULL;
+ geth_string_defs[0].id = 0;
+ usb_free_all_descriptors(f);
kfree(func_to_geth(f));
}
@@ -414,20 +390,11 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
/* maybe allocate device-global string IDs */
if (geth_string_defs[0].id == 0) {
-
- /* interface label */
- status = usb_string_id(c->cdev);
+ status = usb_string_ids_tab(c->cdev, geth_string_defs);
if (status < 0)
return status;
- geth_string_defs[0].id = status;
- subset_data_intf.iInterface = status;
-
- /* MAC address */
- status = usb_string_id(c->cdev);
- if (status < 0)
- return status;
- geth_string_defs[1].id = status;
- ether_desc.iMACAddress = status;
+ subset_data_intf.iInterface = geth_string_defs[0].id;
+ ether_desc.iMACAddress = geth_string_defs[1].id;
}
/* allocate and initialize one new instance */
@@ -449,9 +416,7 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
geth->port.func.disable = geth_disable;
status = usb_add_function(c, &geth->port.func);
- if (status) {
- geth_string_defs[1].s = NULL;
+ if (status)
kfree(geth);
- }
return status;
}
diff --git a/drivers/usb/gadget/f_uac1.c b/drivers/usb/gadget/f_uac1.c
index 1a5dcd5565e..f570e667a64 100644
--- a/drivers/usb/gadget/f_uac1.c
+++ b/drivers/usb/gadget/f_uac1.c
@@ -630,7 +630,7 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_composite_dev *cdev = c->cdev;
struct f_audio *audio = func_to_audio(f);
int status;
- struct usb_ep *ep;
+ struct usb_ep *ep = NULL;
f_audio_build_desc(audio);
@@ -659,22 +659,14 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f)
status = -ENOMEM;
/* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(f_audio_desc);
-
- /*
- * support all relevant hardware speeds... we expect that when
- * hardware is dual speed, all bulk-capable endpoints work at
- * both speeds
- */
- if (gadget_is_dualspeed(c->cdev->gadget)) {
- c->highspeed = true;
- f->hs_descriptors = usb_copy_descriptors(f_audio_desc);
- }
-
+ status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, NULL);
+ if (status)
+ goto fail;
return 0;
fail:
-
+ if (ep)
+ ep->driver_data = NULL;
return status;
}
@@ -683,8 +675,7 @@ f_audio_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_audio *audio = func_to_audio(f);
- usb_free_descriptors(f->descriptors);
- usb_free_descriptors(f->hs_descriptors);
+ usb_free_all_descriptors(f);
kfree(audio);
}
diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c
index d3c6cffccb7..d7da258fa3f 100644
--- a/drivers/usb/gadget/f_uac2.c
+++ b/drivers/usb/gadget/f_uac2.c
@@ -50,13 +50,6 @@ static int c_ssize = 2;
module_param(c_ssize, uint, S_IRUGO);
MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)");
-#define DMA_ADDR_INVALID (~(dma_addr_t)0)
-
-#define ALT_SET(x, a) do {(x) &= ~0xff; (x) |= (a); } while (0)
-#define ALT_GET(x) ((x) & 0xff)
-#define INTF_SET(x, i) do {(x) &= 0xff; (x) |= ((i) << 8); } while (0)
-#define INTF_GET(x) ((x >> 8) & 0xff)
-
/* Keep everyone on toes */
#define USB_XFERS 2
@@ -144,8 +137,9 @@ static struct snd_pcm_hardware uac2_pcm_hardware = {
};
struct audio_dev {
- /* Currently active {Interface[15:8] | AltSettings[7:0]} */
- __u16 ac_alt, as_out_alt, as_in_alt;
+ u8 ac_intf, ac_alt;
+ u8 as_out_intf, as_out_alt;
+ u8 as_in_intf, as_in_alt;
struct usb_ep *in_ep, *out_ep;
struct usb_function func;
@@ -408,7 +402,7 @@ static struct snd_pcm_ops uac2_pcm_ops = {
.prepare = uac2_pcm_null,
};
-static int __devinit snd_uac2_probe(struct platform_device *pdev)
+static int snd_uac2_probe(struct platform_device *pdev)
{
struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev);
struct snd_card *card;
@@ -526,32 +520,22 @@ enum {
STR_AS_IN_ALT1,
};
-static const char ifassoc[] = "Source/Sink";
-static const char ifctrl[] = "Topology Control";
static char clksrc_in[8];
static char clksrc_out[8];
-static const char usb_it[] = "USBH Out";
-static const char io_it[] = "USBD Out";
-static const char usb_ot[] = "USBH In";
-static const char io_ot[] = "USBD In";
-static const char out_alt0[] = "Playback Inactive";
-static const char out_alt1[] = "Playback Active";
-static const char in_alt0[] = "Capture Inactive";
-static const char in_alt1[] = "Capture Active";
static struct usb_string strings_fn[] = {
- [STR_ASSOC].s = ifassoc,
- [STR_IF_CTRL].s = ifctrl,
+ [STR_ASSOC].s = "Source/Sink",
+ [STR_IF_CTRL].s = "Topology Control",
[STR_CLKSRC_IN].s = clksrc_in,
[STR_CLKSRC_OUT].s = clksrc_out,
- [STR_USB_IT].s = usb_it,
- [STR_IO_IT].s = io_it,
- [STR_USB_OT].s = usb_ot,
- [STR_IO_OT].s = io_ot,
- [STR_AS_OUT_ALT0].s = out_alt0,
- [STR_AS_OUT_ALT1].s = out_alt1,
- [STR_AS_IN_ALT0].s = in_alt0,
- [STR_AS_IN_ALT1].s = in_alt1,
+ [STR_USB_IT].s = "USBH Out",
+ [STR_IO_IT].s = "USBD Out",
+ [STR_USB_OT].s = "USBH In",
+ [STR_IO_OT].s = "USBD In",
+ [STR_AS_OUT_ALT0].s = "Playback Inactive",
+ [STR_AS_OUT_ALT1].s = "Playback Active",
+ [STR_AS_IN_ALT0].s = "Capture Inactive",
+ [STR_AS_IN_ALT1].s = "Capture Active",
{ },
};
@@ -952,8 +936,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
return ret;
}
std_ac_if_desc.bInterfaceNumber = ret;
- ALT_SET(agdev->ac_alt, 0);
- INTF_SET(agdev->ac_alt, ret);
+ agdev->ac_intf = ret;
+ agdev->ac_alt = 0;
ret = usb_interface_id(cfg, fn);
if (ret < 0) {
@@ -963,8 +947,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
}
std_as_out_if0_desc.bInterfaceNumber = ret;
std_as_out_if1_desc.bInterfaceNumber = ret;
- ALT_SET(agdev->as_out_alt, 0);
- INTF_SET(agdev->as_out_alt, ret);
+ agdev->as_out_intf = ret;
+ agdev->as_out_alt = 0;
ret = usb_interface_id(cfg, fn);
if (ret < 0) {
@@ -974,19 +958,23 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
}
std_as_in_if0_desc.bInterfaceNumber = ret;
std_as_in_if1_desc.bInterfaceNumber = ret;
- ALT_SET(agdev->as_in_alt, 0);
- INTF_SET(agdev->as_in_alt, ret);
+ agdev->as_in_intf = ret;
+ agdev->as_in_alt = 0;
agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc);
- if (!agdev->out_ep)
+ if (!agdev->out_ep) {
dev_err(&uac2->pdev.dev,
"%s:%d Error!\n", __func__, __LINE__);
+ goto err;
+ }
agdev->out_ep->driver_data = agdev;
agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc);
- if (!agdev->in_ep)
+ if (!agdev->in_ep) {
dev_err(&uac2->pdev.dev,
"%s:%d Error!\n", __func__, __LINE__);
+ goto err;
+ }
agdev->in_ep->driver_data = agdev;
hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
@@ -994,9 +982,9 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;
hs_epin_desc.wMaxPacketSize = fs_epin_desc.wMaxPacketSize;
- fn->descriptors = usb_copy_descriptors(fs_audio_desc);
- if (gadget_is_dualspeed(gadget))
- fn->hs_descriptors = usb_copy_descriptors(hs_audio_desc);
+ ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL);
+ if (ret)
+ goto err;
prm = &agdev->uac2.c_prm;
prm->max_psize = hs_epout_desc.wMaxPacketSize;
@@ -1005,6 +993,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
prm->max_psize = 0;
dev_err(&uac2->pdev.dev,
"%s:%d Error!\n", __func__, __LINE__);
+ goto err;
}
prm = &agdev->uac2.p_prm;
@@ -1014,17 +1003,28 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
prm->max_psize = 0;
dev_err(&uac2->pdev.dev,
"%s:%d Error!\n", __func__, __LINE__);
+ goto err;
}
- return alsa_uac2_init(agdev);
+ ret = alsa_uac2_init(agdev);
+ if (ret)
+ goto err;
+ return 0;
+err:
+ kfree(agdev->uac2.p_prm.rbuf);
+ kfree(agdev->uac2.c_prm.rbuf);
+ usb_free_all_descriptors(fn);
+ if (agdev->in_ep)
+ agdev->in_ep->driver_data = NULL;
+ if (agdev->out_ep)
+ agdev->out_ep->driver_data = NULL;
+ return -EINVAL;
}
static void
afunc_unbind(struct usb_configuration *cfg, struct usb_function *fn)
{
struct audio_dev *agdev = func_to_agdev(fn);
- struct usb_composite_dev *cdev = cfg->cdev;
- struct usb_gadget *gadget = cdev->gadget;
struct uac2_rtd_params *prm;
alsa_uac2_exit(agdev);
@@ -1034,10 +1034,7 @@ afunc_unbind(struct usb_configuration *cfg, struct usb_function *fn)
prm = &agdev->uac2.c_prm;
kfree(prm->rbuf);
-
- if (gadget_is_dualspeed(gadget))
- usb_free_descriptors(fn->hs_descriptors);
- usb_free_descriptors(fn->descriptors);
+ usb_free_all_descriptors(fn);
if (agdev->in_ep)
agdev->in_ep->driver_data = NULL;
@@ -1064,7 +1061,7 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt)
return -EINVAL;
}
- if (intf == INTF_GET(agdev->ac_alt)) {
+ if (intf == agdev->ac_intf) {
/* Control I/f has only 1 AltSetting - 0 */
if (alt) {
dev_err(&uac2->pdev.dev,
@@ -1074,16 +1071,16 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt)
return 0;
}
- if (intf == INTF_GET(agdev->as_out_alt)) {
+ if (intf == agdev->as_out_intf) {
ep = agdev->out_ep;
prm = &uac2->c_prm;
config_ep_by_speed(gadget, fn, ep);
- ALT_SET(agdev->as_out_alt, alt);
- } else if (intf == INTF_GET(agdev->as_in_alt)) {
+ agdev->as_out_alt = alt;
+ } else if (intf == agdev->as_in_intf) {
ep = agdev->in_ep;
prm = &uac2->p_prm;
config_ep_by_speed(gadget, fn, ep);
- ALT_SET(agdev->as_in_alt, alt);
+ agdev->as_in_alt = alt;
} else {
dev_err(&uac2->pdev.dev,
"%s:%d Error!\n", __func__, __LINE__);
@@ -1117,7 +1114,6 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt)
prm->ureq[i].pp = prm;
req->zero = 0;
- req->dma = DMA_ADDR_INVALID;
req->context = &prm->ureq[i];
req->length = prm->max_psize;
req->complete = agdev_iso_complete;
@@ -1136,12 +1132,12 @@ afunc_get_alt(struct usb_function *fn, unsigned intf)
struct audio_dev *agdev = func_to_agdev(fn);
struct snd_uac2_chip *uac2 = &agdev->uac2;
- if (intf == INTF_GET(agdev->ac_alt))
- return ALT_GET(agdev->ac_alt);
- else if (intf == INTF_GET(agdev->as_out_alt))
- return ALT_GET(agdev->as_out_alt);
- else if (intf == INTF_GET(agdev->as_in_alt))
- return ALT_GET(agdev->as_in_alt);
+ if (intf == agdev->ac_intf)
+ return agdev->ac_alt;
+ else if (intf == agdev->as_out_intf)
+ return agdev->as_out_alt;
+ else if (intf == agdev->as_in_intf)
+ return agdev->as_in_alt;
else
dev_err(&uac2->pdev.dev,
"%s:%d Invalid Interface %d!\n",
@@ -1157,10 +1153,10 @@ afunc_disable(struct usb_function *fn)
struct snd_uac2_chip *uac2 = &agdev->uac2;
free_ep(&uac2->p_prm, agdev->in_ep);
- ALT_SET(agdev->as_in_alt, 0);
+ agdev->as_in_alt = 0;
free_ep(&uac2->c_prm, agdev->out_ep);
- ALT_SET(agdev->as_out_alt, 0);
+ agdev->as_out_alt = 0;
}
static int
@@ -1267,7 +1263,7 @@ setup_rq_inf(struct usb_function *fn, const struct usb_ctrlrequest *cr)
u16 w_index = le16_to_cpu(cr->wIndex);
u8 intf = w_index & 0xff;
- if (intf != INTF_GET(agdev->ac_alt)) {
+ if (intf != agdev->ac_intf) {
dev_err(&uac2->pdev.dev,
"%s:%d Error!\n", __func__, __LINE__);
return -EOPNOTSUPP;
@@ -1316,7 +1312,7 @@ afunc_setup(struct usb_function *fn, const struct usb_ctrlrequest *cr)
static int audio_bind_config(struct usb_configuration *cfg)
{
- int id, res;
+ int res;
agdev_g = kzalloc(sizeof *agdev_g, GFP_KERNEL);
if (agdev_g == NULL) {
@@ -1324,89 +1320,21 @@ static int audio_bind_config(struct usb_configuration *cfg)
return -ENOMEM;
}
- id = usb_string_id(cfg->cdev);
- if (id < 0)
- return id;
-
- strings_fn[STR_ASSOC].id = id;
- iad_desc.iFunction = id,
-
- id = usb_string_id(cfg->cdev);
- if (id < 0)
- return id;
-
- strings_fn[STR_IF_CTRL].id = id;
- std_ac_if_desc.iInterface = id,
-
- id = usb_string_id(cfg->cdev);
- if (id < 0)
- return id;
-
- strings_fn[STR_CLKSRC_IN].id = id;
- in_clk_src_desc.iClockSource = id,
-
- id = usb_string_id(cfg->cdev);
- if (id < 0)
- return id;
-
- strings_fn[STR_CLKSRC_OUT].id = id;
- out_clk_src_desc.iClockSource = id,
-
- id = usb_string_id(cfg->cdev);
- if (id < 0)
- return id;
-
- strings_fn[STR_USB_IT].id = id;
- usb_out_it_desc.iTerminal = id,
-
- id = usb_string_id(cfg->cdev);
- if (id < 0)
- return id;
-
- strings_fn[STR_IO_IT].id = id;
- io_in_it_desc.iTerminal = id;
-
- id = usb_string_id(cfg->cdev);
- if (id < 0)
- return id;
-
- strings_fn[STR_USB_OT].id = id;
- usb_in_ot_desc.iTerminal = id;
-
- id = usb_string_id(cfg->cdev);
- if (id < 0)
- return id;
-
- strings_fn[STR_IO_OT].id = id;
- io_out_ot_desc.iTerminal = id;
-
- id = usb_string_id(cfg->cdev);
- if (id < 0)
- return id;
-
- strings_fn[STR_AS_OUT_ALT0].id = id;
- std_as_out_if0_desc.iInterface = id;
-
- id = usb_string_id(cfg->cdev);
- if (id < 0)
- return id;
-
- strings_fn[STR_AS_OUT_ALT1].id = id;
- std_as_out_if1_desc.iInterface = id;
-
- id = usb_string_id(cfg->cdev);
- if (id < 0)
- return id;
-
- strings_fn[STR_AS_IN_ALT0].id = id;
- std_as_in_if0_desc.iInterface = id;
-
- id = usb_string_id(cfg->cdev);
- if (id < 0)
- return id;
-
- strings_fn[STR_AS_IN_ALT1].id = id;
- std_as_in_if1_desc.iInterface = id;
+ res = usb_string_ids_tab(cfg->cdev, strings_fn);
+ if (res)
+ return res;
+ iad_desc.iFunction = strings_fn[STR_ASSOC].id;
+ std_ac_if_desc.iInterface = strings_fn[STR_IF_CTRL].id;
+ in_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_IN].id;
+ out_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_OUT].id;
+ usb_out_it_desc.iTerminal = strings_fn[STR_USB_IT].id;
+ io_in_it_desc.iTerminal = strings_fn[STR_IO_IT].id;
+ usb_in_ot_desc.iTerminal = strings_fn[STR_USB_OT].id;
+ io_out_ot_desc.iTerminal = strings_fn[STR_IO_OT].id;
+ std_as_out_if0_desc.iInterface = strings_fn[STR_AS_OUT_ALT0].id;
+ std_as_out_if1_desc.iInterface = strings_fn[STR_AS_OUT_ALT1].id;
+ std_as_in_if0_desc.iInterface = strings_fn[STR_AS_IN_ALT0].id;
+ std_as_in_if1_desc.iInterface = strings_fn[STR_AS_IN_ALT1].id;
agdev_g->func.name = "uac2_func";
agdev_g->func.strings = fn_strings;
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c
index 2a8bf0655c6..5b629876941 100644
--- a/drivers/usb/gadget/f_uvc.c
+++ b/drivers/usb/gadget/f_uvc.c
@@ -417,7 +417,6 @@ uvc_register_video(struct uvc_device *uvc)
return -ENOMEM;
video->parent = &cdev->gadget->dev;
- video->minor = -1;
video->fops = &uvc_v4l2_fops;
video->release = video_device_release;
strncpy(video->name, cdev->gadget->name, sizeof(video->name));
@@ -577,27 +576,15 @@ uvc_function_unbind(struct usb_configuration *c, struct usb_function *f)
INFO(cdev, "uvc_function_unbind\n");
- if (uvc->vdev) {
- if (uvc->vdev->minor == -1)
- video_device_release(uvc->vdev);
- else
- video_unregister_device(uvc->vdev);
- uvc->vdev = NULL;
- }
+ video_unregister_device(uvc->vdev);
+ uvc->control_ep->driver_data = NULL;
+ uvc->video.ep->driver_data = NULL;
- if (uvc->control_ep)
- uvc->control_ep->driver_data = NULL;
- if (uvc->video.ep)
- uvc->video.ep->driver_data = NULL;
-
- if (uvc->control_req) {
- usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
- kfree(uvc->control_buf);
- }
+ uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id = 0;
+ usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
+ kfree(uvc->control_buf);
- kfree(f->descriptors);
- kfree(f->hs_descriptors);
- kfree(f->ss_descriptors);
+ usb_free_all_descriptors(f);
kfree(uvc);
}
@@ -663,49 +650,40 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
/* sanity check the streaming endpoint module parameters */
if (streaming_maxpacket > 1024)
streaming_maxpacket = 1024;
+ /*
+ * Fill in the HS descriptors from the module parameters for the Video
+ * Streaming endpoint.
+ * NOTE: We assume that the user knows what they are doing and won't
+ * give parameters that their UDC doesn't support.
+ */
+ uvc_hs_streaming_ep.wMaxPacketSize = streaming_maxpacket;
+ uvc_hs_streaming_ep.wMaxPacketSize |= streaming_mult << 11;
+ uvc_hs_streaming_ep.bInterval = streaming_interval;
+ uvc_hs_streaming_ep.bEndpointAddress =
+ uvc_fs_streaming_ep.bEndpointAddress;
- /* Copy descriptors for FS. */
- f->descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL);
-
- /* support high speed hardware */
- if (gadget_is_dualspeed(cdev->gadget)) {
- /*
- * Fill in the HS descriptors from the module parameters for the
- * Video Streaming endpoint.
- * NOTE: We assume that the user knows what they are doing and
- * won't give parameters that their UDC doesn't support.
- */
- uvc_hs_streaming_ep.wMaxPacketSize = streaming_maxpacket;
- uvc_hs_streaming_ep.wMaxPacketSize |= streaming_mult << 11;
- uvc_hs_streaming_ep.bInterval = streaming_interval;
- uvc_hs_streaming_ep.bEndpointAddress =
- uvc_fs_streaming_ep.bEndpointAddress;
-
- /* Copy descriptors. */
- f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH);
- }
+ /*
+ * Fill in the SS descriptors from the module parameters for the Video
+ * Streaming endpoint.
+ * NOTE: We assume that the user knows what they are doing and won't
+ * give parameters that their UDC doesn't support.
+ */
+ uvc_ss_streaming_ep.wMaxPacketSize = streaming_maxpacket;
+ uvc_ss_streaming_ep.bInterval = streaming_interval;
+ uvc_ss_streaming_comp.bmAttributes = streaming_mult;
+ uvc_ss_streaming_comp.bMaxBurst = streaming_maxburst;
+ uvc_ss_streaming_comp.wBytesPerInterval =
+ streaming_maxpacket * (streaming_mult + 1) *
+ (streaming_maxburst + 1);
+ uvc_ss_streaming_ep.bEndpointAddress =
+ uvc_fs_streaming_ep.bEndpointAddress;
- /* support super speed hardware */
- if (gadget_is_superspeed(c->cdev->gadget)) {
- /*
- * Fill in the SS descriptors from the module parameters for the
- * Video Streaming endpoint.
- * NOTE: We assume that the user knows what they are doing and
- * won't give parameters that their UDC doesn't support.
- */
- uvc_ss_streaming_ep.wMaxPacketSize = streaming_maxpacket;
- uvc_ss_streaming_ep.bInterval = streaming_interval;
- uvc_ss_streaming_comp.bmAttributes = streaming_mult;
- uvc_ss_streaming_comp.bMaxBurst = streaming_maxburst;
- uvc_ss_streaming_comp.wBytesPerInterval =
- streaming_maxpacket * (streaming_mult + 1) *
- (streaming_maxburst + 1);
- uvc_ss_streaming_ep.bEndpointAddress =
- uvc_fs_streaming_ep.bEndpointAddress;
-
- /* Copy descriptors. */
+ /* Copy descriptors */
+ f->fs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL);
+ if (gadget_is_dualspeed(cdev->gadget))
+ f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH);
+ if (gadget_is_superspeed(c->cdev->gadget))
f->ss_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_SUPER);
- }
/* Preallocate control endpoint request. */
uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL);
@@ -740,7 +718,20 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
error:
- uvc_function_unbind(c, f);
+ if (uvc->vdev)
+ video_device_release(uvc->vdev);
+
+ if (uvc->control_ep)
+ uvc->control_ep->driver_data = NULL;
+ if (uvc->video.ep)
+ uvc->video.ep->driver_data = NULL;
+
+ if (uvc->control_req) {
+ usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
+ kfree(uvc->control_buf);
+ }
+
+ usb_free_all_descriptors(f);
return ret;
}
@@ -808,25 +799,16 @@ uvc_bind_config(struct usb_configuration *c,
uvc->desc.hs_streaming = hs_streaming;
uvc->desc.ss_streaming = ss_streaming;
- /* maybe allocate device-global string IDs, and patch descriptors */
+ /* Allocate string descriptor numbers. */
if (uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id == 0) {
- /* Allocate string descriptor numbers. */
- ret = usb_string_id(c->cdev);
- if (ret < 0)
- goto error;
- uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id = ret;
- uvc_iad.iFunction = ret;
-
- ret = usb_string_id(c->cdev);
- if (ret < 0)
- goto error;
- uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id = ret;
- uvc_control_intf.iInterface = ret;
-
- ret = usb_string_id(c->cdev);
- if (ret < 0)
+ ret = usb_string_ids_tab(c->cdev, uvc_en_us_strings);
+ if (ret)
goto error;
- uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id = ret;
+ uvc_iad.iFunction =
+ uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id;
+ uvc_control_intf.iInterface =
+ uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id;
+ ret = uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id;
uvc_streaming_intf_alt0.iInterface = ret;
uvc_streaming_intf_alt1.iInterface = ret;
}
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
deleted file mode 100644
index 3f7d640b675..00000000000
--- a/drivers/usb/gadget/file_storage.c
+++ /dev/null
@@ -1,3656 +0,0 @@
-/*
- * file_storage.c -- File-backed USB Storage Gadget, for USB development
- *
- * Copyright (C) 2003-2008 Alan Stern
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. 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.
- * 3. The names of the above-listed copyright holders may not be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/*
- * The File-backed Storage Gadget acts as a USB Mass Storage device,
- * appearing to the host as a disk drive or as a CD-ROM drive. In addition
- * to providing an example of a genuinely useful gadget driver for a USB
- * device, it also illustrates a technique of double-buffering for increased
- * throughput. Last but not least, it gives an easy way to probe the
- * behavior of the Mass Storage drivers in a USB host.
- *
- * Backing storage is provided by a regular file or a block device, specified
- * by the "file" module parameter. Access can be limited to read-only by
- * setting the optional "ro" module parameter. (For CD-ROM emulation,
- * access is always read-only.) The gadget will indicate that it has
- * removable media if the optional "removable" module parameter is set.
- *
- * The gadget supports the Control-Bulk (CB), Control-Bulk-Interrupt (CBI),
- * and Bulk-Only (also known as Bulk-Bulk-Bulk or BBB) transports, selected
- * by the optional "transport" module parameter. It also supports the
- * following protocols: RBC (0x01), ATAPI or SFF-8020i (0x02), QIC-157 (0c03),
- * UFI (0x04), SFF-8070i (0x05), and transparent SCSI (0x06), selected by
- * the optional "protocol" module parameter. In addition, the default
- * Vendor ID, Product ID, release number and serial number can be overridden.
- *
- * There is support for multiple logical units (LUNs), each of which has
- * its own backing file. The number of LUNs can be set using the optional
- * "luns" module parameter (anywhere from 1 to 8), and the corresponding
- * files are specified using comma-separated lists for "file" and "ro".
- * The default number of LUNs is taken from the number of "file" elements;
- * it is 1 if "file" is not given. If "removable" is not set then a backing
- * file must be specified for each LUN. If it is set, then an unspecified
- * or empty backing filename means the LUN's medium is not loaded. Ideally
- * each LUN would be settable independently as a disk drive or a CD-ROM
- * drive, but currently all LUNs have to be the same type. The CD-ROM
- * emulation includes a single data track and no audio tracks; hence there
- * need be only one backing file per LUN.
- *
- * Requirements are modest; only a bulk-in and a bulk-out endpoint are
- * needed (an interrupt-out endpoint is also needed for CBI). The memory
- * requirement amounts to two 16K buffers, size configurable by a parameter.
- * Support is included for both full-speed and high-speed operation.
- *
- * Note that the driver is slightly non-portable in that it assumes a
- * single memory/DMA buffer will be useable for bulk-in, bulk-out, and
- * interrupt-in endpoints. With most device controllers this isn't an
- * issue, but there may be some with hardware restrictions that prevent
- * a buffer from being used by more than one endpoint.
- *
- * Module options:
- *
- * file=filename[,filename...]
- * Required if "removable" is not set, names of
- * the files or block devices used for
- * backing storage
- * serial=HHHH... Required serial number (string of hex chars)
- * ro=b[,b...] Default false, booleans for read-only access
- * removable Default false, boolean for removable media
- * luns=N Default N = number of filenames, number of
- * LUNs to support
- * nofua=b[,b...] Default false, booleans for ignore FUA flag
- * in SCSI WRITE(10,12) commands
- * stall Default determined according to the type of
- * USB device controller (usually true),
- * boolean to permit the driver to halt
- * bulk endpoints
- * cdrom Default false, boolean for whether to emulate
- * a CD-ROM drive
- * transport=XXX Default BBB, transport name (CB, CBI, or BBB)
- * protocol=YYY Default SCSI, protocol name (RBC, 8020 or
- * ATAPI, QIC, UFI, 8070, or SCSI;
- * also 1 - 6)
- * vendor=0xVVVV Default 0x0525 (NetChip), USB Vendor ID
- * product=0xPPPP Default 0xa4a5 (FSG), USB Product ID
- * release=0xRRRR Override the USB release number (bcdDevice)
- * buflen=N Default N=16384, buffer size used (will be
- * rounded down to a multiple of
- * PAGE_CACHE_SIZE)
- *
- * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "serial", "ro",
- * "removable", "luns", "nofua", "stall", and "cdrom" options are available;
- * default values are used for everything else.
- *
- * The pathnames of the backing files and the ro settings are available in
- * the attribute files "file", "nofua", and "ro" in the lun<n> subdirectory of
- * the gadget's sysfs directory. If the "removable" option is set, writing to
- * these files will simulate ejecting/loading the medium (writing an empty
- * line means eject) and adjusting a write-enable tab. Changes to the ro
- * setting are not allowed when the medium is loaded or if CD-ROM emulation
- * is being used.
- *
- * This gadget driver is heavily based on "Gadget Zero" by David Brownell.
- * The driver's SCSI command interface was based on the "Information
- * technology - Small Computer System Interface - 2" document from
- * X3T9.2 Project 375D, Revision 10L, 7-SEP-93, available at
- * <http://www.t10.org/ftp/t10/drafts/s2/s2-r10l.pdf>. The single exception
- * is opcode 0x23 (READ FORMAT CAPACITIES), which was based on the
- * "Universal Serial Bus Mass Storage Class UFI Command Specification"
- * document, Revision 1.0, December 14, 1998, available at
- * <http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf>.
- */
-
-
-/*
- * Driver Design
- *
- * The FSG driver is fairly straightforward. There is a main kernel
- * thread that handles most of the work. Interrupt routines field
- * callbacks from the controller driver: bulk- and interrupt-request
- * completion notifications, endpoint-0 events, and disconnect events.
- * Completion events are passed to the main thread by wakeup calls. Many
- * ep0 requests are handled at interrupt time, but SetInterface,
- * SetConfiguration, and device reset requests are forwarded to the
- * thread in the form of "exceptions" using SIGUSR1 signals (since they
- * should interrupt any ongoing file I/O operations).
- *
- * The thread's main routine implements the standard command/data/status
- * parts of a SCSI interaction. It and its subroutines are full of tests
- * for pending signals/exceptions -- all this polling is necessary since
- * the kernel has no setjmp/longjmp equivalents. (Maybe this is an
- * indication that the driver really wants to be running in userspace.)
- * An important point is that so long as the thread is alive it keeps an
- * open reference to the backing file. This will prevent unmounting
- * the backing file's underlying filesystem and could cause problems
- * during system shutdown, for example. To prevent such problems, the
- * thread catches INT, TERM, and KILL signals and converts them into
- * an EXIT exception.
- *
- * In normal operation the main thread is started during the gadget's
- * fsg_bind() callback and stopped during fsg_unbind(). But it can also
- * exit when it receives a signal, and there's no point leaving the
- * gadget running when the thread is dead. So just before the thread
- * exits, it deregisters the gadget driver. This makes things a little
- * tricky: The driver is deregistered at two places, and the exiting
- * thread can indirectly call fsg_unbind() which in turn can tell the
- * thread to exit. The first problem is resolved through the use of the
- * REGISTERED atomic bitflag; the driver will only be deregistered once.
- * The second problem is resolved by having fsg_unbind() check
- * fsg->state; it won't try to stop the thread if the state is already
- * FSG_STATE_TERMINATED.
- *
- * To provide maximum throughput, the driver uses a circular pipeline of
- * buffer heads (struct fsg_buffhd). In principle the pipeline can be
- * arbitrarily long; in practice the benefits don't justify having more
- * than 2 stages (i.e., double buffering). But it helps to think of the
- * pipeline as being a long one. Each buffer head contains a bulk-in and
- * a bulk-out request pointer (since the buffer can be used for both
- * output and input -- directions always are given from the host's
- * point of view) as well as a pointer to the buffer and various state
- * variables.
- *
- * Use of the pipeline follows a simple protocol. There is a variable
- * (fsg->next_buffhd_to_fill) that points to the next buffer head to use.
- * At any time that buffer head may still be in use from an earlier
- * request, so each buffer head has a state variable indicating whether
- * it is EMPTY, FULL, or BUSY. Typical use involves waiting for the
- * buffer head to be EMPTY, filling the buffer either by file I/O or by
- * USB I/O (during which the buffer head is BUSY), and marking the buffer
- * head FULL when the I/O is complete. Then the buffer will be emptied
- * (again possibly by USB I/O, during which it is marked BUSY) and
- * finally marked EMPTY again (possibly by a completion routine).
- *
- * A module parameter tells the driver to avoid stalling the bulk
- * endpoints wherever the transport specification allows. This is
- * necessary for some UDCs like the SuperH, which cannot reliably clear a
- * halt on a bulk endpoint. However, under certain circumstances the
- * Bulk-only specification requires a stall. In such cases the driver
- * will halt the endpoint and set a flag indicating that it should clear
- * the halt in software during the next device reset. Hopefully this
- * will permit everything to work correctly. Furthermore, although the
- * specification allows the bulk-out endpoint to halt when the host sends
- * too much data, implementing this would cause an unavoidable race.
- * The driver will always use the "no-stall" approach for OUT transfers.
- *
- * One subtle point concerns sending status-stage responses for ep0
- * requests. Some of these requests, such as device reset, can involve
- * interrupting an ongoing file I/O operation, which might take an
- * arbitrarily long time. During that delay the host might give up on
- * the original ep0 request and issue a new one. When that happens the
- * driver should not notify the host about completion of the original
- * request, as the host will no longer be waiting for it. So the driver
- * assigns to each ep0 request a unique tag, and it keeps track of the
- * tag value of the request associated with a long-running exception
- * (device-reset, interface-change, or configuration-change). When the
- * exception handler is finished, the status-stage response is submitted
- * only if the current ep0 request tag is equal to the exception request
- * tag. Thus only the most recently received ep0 request will get a
- * status-stage response.
- *
- * Warning: This driver source file is too long. It ought to be split up
- * into a header file plus about 3 separate .c files, to handle the details
- * of the Gadget, USB Mass Storage, and SCSI protocols.
- */
-
-
-/* #define VERBOSE_DEBUG */
-/* #define DUMP_MSGS */
-
-
-#include <linux/blkdev.h>
-#include <linux/completion.h>
-#include <linux/dcache.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/fcntl.h>
-#include <linux/file.h>
-#include <linux/fs.h>
-#include <linux/kref.h>
-#include <linux/kthread.h>
-#include <linux/limits.h>
-#include <linux/module.h>
-#include <linux/rwsem.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/freezer.h>
-#include <linux/utsname.h>
-
-#include <linux/usb/composite.h>
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-
-#include "gadget_chips.h"
-
-#define DRIVER_DESC "File-backed Storage Gadget"
-#define DRIVER_NAME "g_file_storage"
-#define DRIVER_VERSION "1 September 2010"
-
-static char fsg_string_manufacturer[64];
-static const char fsg_string_product[] = DRIVER_DESC;
-static const char fsg_string_config[] = "Self-powered";
-static const char fsg_string_interface[] = "Mass Storage";
-
-
-#include "storage_common.c"
-
-
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR("Alan Stern");
-MODULE_LICENSE("Dual BSD/GPL");
-
-/*
- * This driver assumes self-powered hardware and has no way for users to
- * trigger remote wakeup. It uses autoconfiguration to select endpoints
- * and endpoint addresses.
- */
-
-
-/*-------------------------------------------------------------------------*/
-
-
-/* Encapsulate the module parameter settings */
-
-static struct {
- char *file[FSG_MAX_LUNS];
- char *serial;
- bool ro[FSG_MAX_LUNS];
- bool nofua[FSG_MAX_LUNS];
- unsigned int num_filenames;
- unsigned int num_ros;
- unsigned int num_nofuas;
- unsigned int nluns;
-
- bool removable;
- bool can_stall;
- bool cdrom;
-
- char *transport_parm;
- char *protocol_parm;
- unsigned short vendor;
- unsigned short product;
- unsigned short release;
- unsigned int buflen;
-
- int transport_type;
- char *transport_name;
- int protocol_type;
- char *protocol_name;
-
-} mod_data = { // Default values
- .transport_parm = "BBB",
- .protocol_parm = "SCSI",
- .removable = 0,
- .can_stall = 1,
- .cdrom = 0,
- .vendor = FSG_VENDOR_ID,
- .product = FSG_PRODUCT_ID,
- .release = 0xffff, // Use controller chip type
- .buflen = 16384,
- };
-
-
-module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames,
- S_IRUGO);
-MODULE_PARM_DESC(file, "names of backing files or devices");
-
-module_param_named(serial, mod_data.serial, charp, S_IRUGO);
-MODULE_PARM_DESC(serial, "USB serial number");
-
-module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO);
-MODULE_PARM_DESC(ro, "true to force read-only");
-
-module_param_array_named(nofua, mod_data.nofua, bool, &mod_data.num_nofuas,
- S_IRUGO);
-MODULE_PARM_DESC(nofua, "true to ignore SCSI WRITE(10,12) FUA bit");
-
-module_param_named(luns, mod_data.nluns, uint, S_IRUGO);
-MODULE_PARM_DESC(luns, "number of LUNs");
-
-module_param_named(removable, mod_data.removable, bool, S_IRUGO);
-MODULE_PARM_DESC(removable, "true to simulate removable media");
-
-module_param_named(stall, mod_data.can_stall, bool, S_IRUGO);
-MODULE_PARM_DESC(stall, "false to prevent bulk stalls");
-
-module_param_named(cdrom, mod_data.cdrom, bool, S_IRUGO);
-MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk");
-
-/* In the non-TEST version, only the module parameters listed above
- * are available. */
-#ifdef CONFIG_USB_FILE_STORAGE_TEST
-
-module_param_named(transport, mod_data.transport_parm, charp, S_IRUGO);
-MODULE_PARM_DESC(transport, "type of transport (BBB, CBI, or CB)");
-
-module_param_named(protocol, mod_data.protocol_parm, charp, S_IRUGO);
-MODULE_PARM_DESC(protocol, "type of protocol (RBC, 8020, QIC, UFI, "
- "8070, or SCSI)");
-
-module_param_named(vendor, mod_data.vendor, ushort, S_IRUGO);
-MODULE_PARM_DESC(vendor, "USB Vendor ID");
-
-module_param_named(product, mod_data.product, ushort, S_IRUGO);
-MODULE_PARM_DESC(product, "USB Product ID");
-
-module_param_named(release, mod_data.release, ushort, S_IRUGO);
-MODULE_PARM_DESC(release, "USB release number");
-
-module_param_named(buflen, mod_data.buflen, uint, S_IRUGO);
-MODULE_PARM_DESC(buflen, "I/O buffer size");
-
-#endif /* CONFIG_USB_FILE_STORAGE_TEST */
-
-
-/*
- * These definitions will permit the compiler to avoid generating code for
- * parts of the driver that aren't used in the non-TEST version. Even gcc
- * can recognize when a test of a constant expression yields a dead code
- * path.
- */
-
-#ifdef CONFIG_USB_FILE_STORAGE_TEST
-
-#define transport_is_bbb() (mod_data.transport_type == USB_PR_BULK)
-#define transport_is_cbi() (mod_data.transport_type == USB_PR_CBI)
-#define protocol_is_scsi() (mod_data.protocol_type == USB_SC_SCSI)
-
-#else
-
-#define transport_is_bbb() 1
-#define transport_is_cbi() 0
-#define protocol_is_scsi() 1
-
-#endif /* CONFIG_USB_FILE_STORAGE_TEST */
-
-
-/*-------------------------------------------------------------------------*/
-
-
-struct fsg_dev {
- /* lock protects: state, all the req_busy's, and cbbuf_cmnd */
- spinlock_t lock;
- struct usb_gadget *gadget;
-
- /* filesem protects: backing files in use */
- struct rw_semaphore filesem;
-
- /* reference counting: wait until all LUNs are released */
- struct kref ref;
-
- struct usb_ep *ep0; // Handy copy of gadget->ep0
- struct usb_request *ep0req; // For control responses
- unsigned int ep0_req_tag;
- const char *ep0req_name;
-
- struct usb_request *intreq; // For interrupt responses
- int intreq_busy;
- struct fsg_buffhd *intr_buffhd;
-
- unsigned int bulk_out_maxpacket;
- enum fsg_state state; // For exception handling
- unsigned int exception_req_tag;
-
- u8 config, new_config;
-
- unsigned int running : 1;
- unsigned int bulk_in_enabled : 1;
- unsigned int bulk_out_enabled : 1;
- unsigned int intr_in_enabled : 1;
- unsigned int phase_error : 1;
- unsigned int short_packet_received : 1;
- unsigned int bad_lun_okay : 1;
-
- unsigned long atomic_bitflags;
-#define REGISTERED 0
-#define IGNORE_BULK_OUT 1
-#define SUSPENDED 2
-
- struct usb_ep *bulk_in;
- struct usb_ep *bulk_out;
- struct usb_ep *intr_in;
-
- struct fsg_buffhd *next_buffhd_to_fill;
- struct fsg_buffhd *next_buffhd_to_drain;
-
- int thread_wakeup_needed;
- struct completion thread_notifier;
- struct task_struct *thread_task;
-
- int cmnd_size;
- u8 cmnd[MAX_COMMAND_SIZE];
- enum data_direction data_dir;
- u32 data_size;
- u32 data_size_from_cmnd;
- u32 tag;
- unsigned int lun;
- u32 residue;
- u32 usb_amount_left;
-
- /* The CB protocol offers no way for a host to know when a command
- * has completed. As a result the next command may arrive early,
- * and we will still have to handle it. For that reason we need
- * a buffer to store new commands when using CB (or CBI, which
- * does not oblige a host to wait for command completion either). */
- int cbbuf_cmnd_size;
- u8 cbbuf_cmnd[MAX_COMMAND_SIZE];
-
- unsigned int nluns;
- struct fsg_lun *luns;
- struct fsg_lun *curlun;
- /* Must be the last entry */
- struct fsg_buffhd buffhds[];
-};
-
-typedef void (*fsg_routine_t)(struct fsg_dev *);
-
-static int exception_in_progress(struct fsg_dev *fsg)
-{
- return (fsg->state > FSG_STATE_IDLE);
-}
-
-/* Make bulk-out requests be divisible by the maxpacket size */
-static void set_bulk_out_req_length(struct fsg_dev *fsg,
- struct fsg_buffhd *bh, unsigned int length)
-{
- unsigned int rem;
-
- bh->bulk_out_intended_length = length;
- rem = length % fsg->bulk_out_maxpacket;
- if (rem > 0)
- length += fsg->bulk_out_maxpacket - rem;
- bh->outreq->length = length;
-}
-
-static struct fsg_dev *the_fsg;
-static struct usb_gadget_driver fsg_driver;
-
-
-/*-------------------------------------------------------------------------*/
-
-static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
-{
- const char *name;
-
- if (ep == fsg->bulk_in)
- name = "bulk-in";
- else if (ep == fsg->bulk_out)
- name = "bulk-out";
- else
- name = ep->name;
- DBG(fsg, "%s set halt\n", name);
- return usb_ep_set_halt(ep);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * DESCRIPTORS ... most are static, but strings and (full) configuration
- * descriptors are built on demand. Also the (static) config and interface
- * descriptors are adjusted during fsg_bind().
- */
-
-/* There is only one configuration. */
-#define CONFIG_VALUE 1
-
-static struct usb_device_descriptor
-device_desc = {
- .bLength = sizeof device_desc,
- .bDescriptorType = USB_DT_DEVICE,
-
- .bcdUSB = cpu_to_le16(0x0200),
- .bDeviceClass = USB_CLASS_PER_INTERFACE,
-
- /* The next three values can be overridden by module parameters */
- .idVendor = cpu_to_le16(FSG_VENDOR_ID),
- .idProduct = cpu_to_le16(FSG_PRODUCT_ID),
- .bcdDevice = cpu_to_le16(0xffff),
-
- .iManufacturer = FSG_STRING_MANUFACTURER,
- .iProduct = FSG_STRING_PRODUCT,
- .iSerialNumber = FSG_STRING_SERIAL,
- .bNumConfigurations = 1,
-};
-
-static struct usb_config_descriptor
-config_desc = {
- .bLength = sizeof config_desc,
- .bDescriptorType = USB_DT_CONFIG,
-
- /* wTotalLength computed by usb_gadget_config_buf() */
- .bNumInterfaces = 1,
- .bConfigurationValue = CONFIG_VALUE,
- .iConfiguration = FSG_STRING_CONFIG,
- .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
- .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2,
-};
-
-
-static struct usb_qualifier_descriptor
-dev_qualifier = {
- .bLength = sizeof dev_qualifier,
- .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
-
- .bcdUSB = cpu_to_le16(0x0200),
- .bDeviceClass = USB_CLASS_PER_INTERFACE,
-
- .bNumConfigurations = 1,
-};
-
-static int populate_bos(struct fsg_dev *fsg, u8 *buf)
-{
- memcpy(buf, &fsg_bos_desc, USB_DT_BOS_SIZE);
- buf += USB_DT_BOS_SIZE;
-
- memcpy(buf, &fsg_ext_cap_desc, USB_DT_USB_EXT_CAP_SIZE);
- buf += USB_DT_USB_EXT_CAP_SIZE;
-
- memcpy(buf, &fsg_ss_cap_desc, USB_DT_USB_SS_CAP_SIZE);
-
- return USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE
- + USB_DT_USB_EXT_CAP_SIZE;
-}
-
-/*
- * Config descriptors must agree with the code that sets configurations
- * and with code managing interfaces and their altsettings. They must
- * also handle different speeds and other-speed requests.
- */
-static int populate_config_buf(struct usb_gadget *gadget,
- u8 *buf, u8 type, unsigned index)
-{
- enum usb_device_speed speed = gadget->speed;
- int len;
- const struct usb_descriptor_header **function;
-
- if (index > 0)
- return -EINVAL;
-
- if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG)
- speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed;
- function = gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH
- ? (const struct usb_descriptor_header **)fsg_hs_function
- : (const struct usb_descriptor_header **)fsg_fs_function;
-
- /* for now, don't advertise srp-only devices */
- if (!gadget_is_otg(gadget))
- function++;
-
- len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function);
- ((struct usb_config_descriptor *) buf)->bDescriptorType = type;
- return len;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* These routines may be called in process context or in_irq */
-
-/* Caller must hold fsg->lock */
-static void wakeup_thread(struct fsg_dev *fsg)
-{
- /* Tell the main thread that something has happened */
- fsg->thread_wakeup_needed = 1;
- if (fsg->thread_task)
- wake_up_process(fsg->thread_task);
-}
-
-
-static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state)
-{
- unsigned long flags;
-
- /* Do nothing if a higher-priority exception is already in progress.
- * If a lower-or-equal priority exception is in progress, preempt it
- * and notify the main thread by sending it a signal. */
- spin_lock_irqsave(&fsg->lock, flags);
- if (fsg->state <= new_state) {
- fsg->exception_req_tag = fsg->ep0_req_tag;
- fsg->state = new_state;
- if (fsg->thread_task)
- send_sig_info(SIGUSR1, SEND_SIG_FORCED,
- fsg->thread_task);
- }
- spin_unlock_irqrestore(&fsg->lock, flags);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* The disconnect callback and ep0 routines. These always run in_irq,
- * except that ep0_queue() is called in the main thread to acknowledge
- * completion of various requests: set config, set interface, and
- * Bulk-only device reset. */
-
-static void fsg_disconnect(struct usb_gadget *gadget)
-{
- struct fsg_dev *fsg = get_gadget_data(gadget);
-
- DBG(fsg, "disconnect or port reset\n");
- raise_exception(fsg, FSG_STATE_DISCONNECT);
-}
-
-
-static int ep0_queue(struct fsg_dev *fsg)
-{
- int rc;
-
- rc = usb_ep_queue(fsg->ep0, fsg->ep0req, GFP_ATOMIC);
- if (rc != 0 && rc != -ESHUTDOWN) {
-
- /* We can't do much more than wait for a reset */
- WARNING(fsg, "error in submission: %s --> %d\n",
- fsg->ep0->name, rc);
- }
- return rc;
-}
-
-static void ep0_complete(struct usb_ep *ep, struct usb_request *req)
-{
- struct fsg_dev *fsg = ep->driver_data;
-
- if (req->actual > 0)
- dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual);
- if (req->status || req->actual != req->length)
- DBG(fsg, "%s --> %d, %u/%u\n", __func__,
- req->status, req->actual, req->length);
- if (req->status == -ECONNRESET) // Request was cancelled
- usb_ep_fifo_flush(ep);
-
- if (req->status == 0 && req->context)
- ((fsg_routine_t) (req->context))(fsg);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Bulk and interrupt endpoint completion handlers.
- * These always run in_irq. */
-
-static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
-{
- struct fsg_dev *fsg = ep->driver_data;
- struct fsg_buffhd *bh = req->context;
-
- if (req->status || req->actual != req->length)
- DBG(fsg, "%s --> %d, %u/%u\n", __func__,
- req->status, req->actual, req->length);
- if (req->status == -ECONNRESET) // Request was cancelled
- usb_ep_fifo_flush(ep);
-
- /* Hold the lock while we update the request and buffer states */
- smp_wmb();
- spin_lock(&fsg->lock);
- bh->inreq_busy = 0;
- bh->state = BUF_STATE_EMPTY;
- wakeup_thread(fsg);
- spin_unlock(&fsg->lock);
-}
-
-static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
-{
- struct fsg_dev *fsg = ep->driver_data;
- struct fsg_buffhd *bh = req->context;
-
- dump_msg(fsg, "bulk-out", req->buf, req->actual);
- if (req->status || req->actual != bh->bulk_out_intended_length)
- DBG(fsg, "%s --> %d, %u/%u\n", __func__,
- req->status, req->actual,
- bh->bulk_out_intended_length);
- if (req->status == -ECONNRESET) // Request was cancelled
- usb_ep_fifo_flush(ep);
-
- /* Hold the lock while we update the request and buffer states */
- smp_wmb();
- spin_lock(&fsg->lock);
- bh->outreq_busy = 0;
- bh->state = BUF_STATE_FULL;
- wakeup_thread(fsg);
- spin_unlock(&fsg->lock);
-}
-
-
-#ifdef CONFIG_USB_FILE_STORAGE_TEST
-static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
-{
- struct fsg_dev *fsg = ep->driver_data;
- struct fsg_buffhd *bh = req->context;
-
- if (req->status || req->actual != req->length)
- DBG(fsg, "%s --> %d, %u/%u\n", __func__,
- req->status, req->actual, req->length);
- if (req->status == -ECONNRESET) // Request was cancelled
- usb_ep_fifo_flush(ep);
-
- /* Hold the lock while we update the request and buffer states */
- smp_wmb();
- spin_lock(&fsg->lock);
- fsg->intreq_busy = 0;
- bh->state = BUF_STATE_EMPTY;
- wakeup_thread(fsg);
- spin_unlock(&fsg->lock);
-}
-
-#else
-static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
-{}
-#endif /* CONFIG_USB_FILE_STORAGE_TEST */
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Ep0 class-specific handlers. These always run in_irq. */
-
-#ifdef CONFIG_USB_FILE_STORAGE_TEST
-static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-{
- struct usb_request *req = fsg->ep0req;
- static u8 cbi_reset_cmnd[6] = {
- SEND_DIAGNOSTIC, 4, 0xff, 0xff, 0xff, 0xff};
-
- /* Error in command transfer? */
- if (req->status || req->length != req->actual ||
- req->actual < 6 || req->actual > MAX_COMMAND_SIZE) {
-
- /* Not all controllers allow a protocol stall after
- * receiving control-out data, but we'll try anyway. */
- fsg_set_halt(fsg, fsg->ep0);
- return; // Wait for reset
- }
-
- /* Is it the special reset command? */
- if (req->actual >= sizeof cbi_reset_cmnd &&
- memcmp(req->buf, cbi_reset_cmnd,
- sizeof cbi_reset_cmnd) == 0) {
-
- /* Raise an exception to stop the current operation
- * and reinitialize our state. */
- DBG(fsg, "cbi reset request\n");
- raise_exception(fsg, FSG_STATE_RESET);
- return;
- }
-
- VDBG(fsg, "CB[I] accept device-specific command\n");
- spin_lock(&fsg->lock);
-
- /* Save the command for later */
- if (fsg->cbbuf_cmnd_size)
- WARNING(fsg, "CB[I] overwriting previous command\n");
- fsg->cbbuf_cmnd_size = req->actual;
- memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size);
-
- wakeup_thread(fsg);
- spin_unlock(&fsg->lock);
-}
-
-#else
-static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-{}
-#endif /* CONFIG_USB_FILE_STORAGE_TEST */
-
-
-static int class_setup_req(struct fsg_dev *fsg,
- const struct usb_ctrlrequest *ctrl)
-{
- struct usb_request *req = fsg->ep0req;
- int value = -EOPNOTSUPP;
- u16 w_index = le16_to_cpu(ctrl->wIndex);
- u16 w_value = le16_to_cpu(ctrl->wValue);
- u16 w_length = le16_to_cpu(ctrl->wLength);
-
- if (!fsg->config)
- return value;
-
- /* Handle Bulk-only class-specific requests */
- if (transport_is_bbb()) {
- switch (ctrl->bRequest) {
-
- case US_BULK_RESET_REQUEST:
- if (ctrl->bRequestType != (USB_DIR_OUT |
- USB_TYPE_CLASS | USB_RECIP_INTERFACE))
- break;
- if (w_index != 0 || w_value != 0 || w_length != 0) {
- value = -EDOM;
- break;
- }
-
- /* Raise an exception to stop the current operation
- * and reinitialize our state. */
- DBG(fsg, "bulk reset request\n");
- raise_exception(fsg, FSG_STATE_RESET);
- value = DELAYED_STATUS;
- break;
-
- case US_BULK_GET_MAX_LUN:
- if (ctrl->bRequestType != (USB_DIR_IN |
- USB_TYPE_CLASS | USB_RECIP_INTERFACE))
- break;
- if (w_index != 0 || w_value != 0 || w_length != 1) {
- value = -EDOM;
- break;
- }
- VDBG(fsg, "get max LUN\n");
- *(u8 *) req->buf = fsg->nluns - 1;
- value = 1;
- break;
- }
- }
-
- /* Handle CBI class-specific requests */
- else {
- switch (ctrl->bRequest) {
-
- case USB_CBI_ADSC_REQUEST:
- if (ctrl->bRequestType != (USB_DIR_OUT |
- USB_TYPE_CLASS | USB_RECIP_INTERFACE))
- break;
- if (w_index != 0 || w_value != 0) {
- value = -EDOM;
- break;
- }
- if (w_length > MAX_COMMAND_SIZE) {
- value = -EOVERFLOW;
- break;
- }
- value = w_length;
- fsg->ep0req->context = received_cbi_adsc;
- break;
- }
- }
-
- if (value == -EOPNOTSUPP)
- VDBG(fsg,
- "unknown class-specific control req "
- "%02x.%02x v%04x i%04x l%u\n",
- ctrl->bRequestType, ctrl->bRequest,
- le16_to_cpu(ctrl->wValue), w_index, w_length);
- return value;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Ep0 standard request handlers. These always run in_irq. */
-
-static int standard_setup_req(struct fsg_dev *fsg,
- const struct usb_ctrlrequest *ctrl)
-{
- struct usb_request *req = fsg->ep0req;
- int value = -EOPNOTSUPP;
- u16 w_index = le16_to_cpu(ctrl->wIndex);
- u16 w_value = le16_to_cpu(ctrl->wValue);
-
- /* Usually this just stores reply data in the pre-allocated ep0 buffer,
- * but config change events will also reconfigure hardware. */
- switch (ctrl->bRequest) {
-
- case USB_REQ_GET_DESCRIPTOR:
- if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
- USB_RECIP_DEVICE))
- break;
- switch (w_value >> 8) {
-
- case USB_DT_DEVICE:
- VDBG(fsg, "get device descriptor\n");
- device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket;
- value = sizeof device_desc;
- memcpy(req->buf, &device_desc, value);
- break;
- case USB_DT_DEVICE_QUALIFIER:
- VDBG(fsg, "get device qualifier\n");
- if (!gadget_is_dualspeed(fsg->gadget) ||
- fsg->gadget->speed == USB_SPEED_SUPER)
- break;
- /*
- * Assume ep0 uses the same maxpacket value for both
- * speeds
- */
- dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
- value = sizeof dev_qualifier;
- memcpy(req->buf, &dev_qualifier, value);
- break;
-
- case USB_DT_OTHER_SPEED_CONFIG:
- VDBG(fsg, "get other-speed config descriptor\n");
- if (!gadget_is_dualspeed(fsg->gadget) ||
- fsg->gadget->speed == USB_SPEED_SUPER)
- break;
- goto get_config;
- case USB_DT_CONFIG:
- VDBG(fsg, "get configuration descriptor\n");
-get_config:
- value = populate_config_buf(fsg->gadget,
- req->buf,
- w_value >> 8,
- w_value & 0xff);
- break;
-
- case USB_DT_STRING:
- VDBG(fsg, "get string descriptor\n");
-
- /* wIndex == language code */
- value = usb_gadget_get_string(&fsg_stringtab,
- w_value & 0xff, req->buf);
- break;
-
- case USB_DT_BOS:
- VDBG(fsg, "get bos descriptor\n");
-
- if (gadget_is_superspeed(fsg->gadget))
- value = populate_bos(fsg, req->buf);
- break;
- }
-
- break;
-
- /* One config, two speeds */
- case USB_REQ_SET_CONFIGURATION:
- if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD |
- USB_RECIP_DEVICE))
- break;
- VDBG(fsg, "set configuration\n");
- if (w_value == CONFIG_VALUE || w_value == 0) {
- fsg->new_config = w_value;
-
- /* Raise an exception to wipe out previous transaction
- * state (queued bufs, etc) and set the new config. */
- raise_exception(fsg, FSG_STATE_CONFIG_CHANGE);
- value = DELAYED_STATUS;
- }
- break;
- case USB_REQ_GET_CONFIGURATION:
- if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
- USB_RECIP_DEVICE))
- break;
- VDBG(fsg, "get configuration\n");
- *(u8 *) req->buf = fsg->config;
- value = 1;
- break;
-
- case USB_REQ_SET_INTERFACE:
- if (ctrl->bRequestType != (USB_DIR_OUT| USB_TYPE_STANDARD |
- USB_RECIP_INTERFACE))
- break;
- if (fsg->config && w_index == 0) {
-
- /* Raise an exception to wipe out previous transaction
- * state (queued bufs, etc) and install the new
- * interface altsetting. */
- raise_exception(fsg, FSG_STATE_INTERFACE_CHANGE);
- value = DELAYED_STATUS;
- }
- break;
- case USB_REQ_GET_INTERFACE:
- if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
- USB_RECIP_INTERFACE))
- break;
- if (!fsg->config)
- break;
- if (w_index != 0) {
- value = -EDOM;
- break;
- }
- VDBG(fsg, "get interface\n");
- *(u8 *) req->buf = 0;
- value = 1;
- break;
-
- default:
- VDBG(fsg,
- "unknown control req %02x.%02x v%04x i%04x l%u\n",
- ctrl->bRequestType, ctrl->bRequest,
- w_value, w_index, le16_to_cpu(ctrl->wLength));
- }
-
- return value;
-}
-
-
-static int fsg_setup(struct usb_gadget *gadget,
- const struct usb_ctrlrequest *ctrl)
-{
- struct fsg_dev *fsg = get_gadget_data(gadget);
- int rc;
- int w_length = le16_to_cpu(ctrl->wLength);
-
- ++fsg->ep0_req_tag; // Record arrival of a new request
- fsg->ep0req->context = NULL;
- fsg->ep0req->length = 0;
- dump_msg(fsg, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl));
-
- if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
- rc = class_setup_req(fsg, ctrl);
- else
- rc = standard_setup_req(fsg, ctrl);
-
- /* Respond with data/status or defer until later? */
- if (rc >= 0 && rc != DELAYED_STATUS) {
- rc = min(rc, w_length);
- fsg->ep0req->length = rc;
- fsg->ep0req->zero = rc < w_length;
- fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ?
- "ep0-in" : "ep0-out");
- rc = ep0_queue(fsg);
- }
-
- /* Device either stalls (rc < 0) or reports success */
- return rc;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* All the following routines run in process context */
-
-
-/* Use this for bulk or interrupt transfers, not ep0 */
-static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
- struct usb_request *req, int *pbusy,
- enum fsg_buffer_state *state)
-{
- int rc;
-
- if (ep == fsg->bulk_in)
- dump_msg(fsg, "bulk-in", req->buf, req->length);
- else if (ep == fsg->intr_in)
- dump_msg(fsg, "intr-in", req->buf, req->length);
-
- spin_lock_irq(&fsg->lock);
- *pbusy = 1;
- *state = BUF_STATE_BUSY;
- spin_unlock_irq(&fsg->lock);
- rc = usb_ep_queue(ep, req, GFP_KERNEL);
- if (rc != 0) {
- *pbusy = 0;
- *state = BUF_STATE_EMPTY;
-
- /* We can't do much more than wait for a reset */
-
- /* Note: currently the net2280 driver fails zero-length
- * submissions if DMA is enabled. */
- if (rc != -ESHUTDOWN && !(rc == -EOPNOTSUPP &&
- req->length == 0))
- WARNING(fsg, "error in submission: %s --> %d\n",
- ep->name, rc);
- }
-}
-
-
-static int sleep_thread(struct fsg_dev *fsg)
-{
- int rc = 0;
-
- /* Wait until a signal arrives or we are woken up */
- for (;;) {
- try_to_freeze();
- set_current_state(TASK_INTERRUPTIBLE);
- if (signal_pending(current)) {
- rc = -EINTR;
- break;
- }
- if (fsg->thread_wakeup_needed)
- break;
- schedule();
- }
- __set_current_state(TASK_RUNNING);
- fsg->thread_wakeup_needed = 0;
- return rc;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static int do_read(struct fsg_dev *fsg)
-{
- struct fsg_lun *curlun = fsg->curlun;
- u32 lba;
- struct fsg_buffhd *bh;
- int rc;
- u32 amount_left;
- loff_t file_offset, file_offset_tmp;
- unsigned int amount;
- ssize_t nread;
-
- /* Get the starting Logical Block Address and check that it's
- * not too big */
- if (fsg->cmnd[0] == READ_6)
- lba = get_unaligned_be24(&fsg->cmnd[1]);
- else {
- lba = get_unaligned_be32(&fsg->cmnd[2]);
-
- /* We allow DPO (Disable Page Out = don't save data in the
- * cache) and FUA (Force Unit Access = don't read from the
- * cache), but we don't implement them. */
- if ((fsg->cmnd[1] & ~0x18) != 0) {
- curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return -EINVAL;
- }
- }
- if (lba >= curlun->num_sectors) {
- curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- return -EINVAL;
- }
- file_offset = ((loff_t) lba) << curlun->blkbits;
-
- /* Carry out the file reads */
- amount_left = fsg->data_size_from_cmnd;
- if (unlikely(amount_left == 0))
- return -EIO; // No default reply
-
- for (;;) {
-
- /* Figure out how much we need to read:
- * Try to read the remaining amount.
- * But don't read more than the buffer size.
- * And don't try to read past the end of the file.
- */
- amount = min((unsigned int) amount_left, mod_data.buflen);
- amount = min((loff_t) amount,
- curlun->file_length - file_offset);
-
- /* Wait for the next buffer to become available */
- bh = fsg->next_buffhd_to_fill;
- while (bh->state != BUF_STATE_EMPTY) {
- rc = sleep_thread(fsg);
- if (rc)
- return rc;
- }
-
- /* If we were asked to read past the end of file,
- * end with an empty buffer. */
- if (amount == 0) {
- curlun->sense_data =
- SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- curlun->sense_data_info = file_offset >> curlun->blkbits;
- curlun->info_valid = 1;
- bh->inreq->length = 0;
- bh->state = BUF_STATE_FULL;
- break;
- }
-
- /* Perform the read */
- file_offset_tmp = file_offset;
- nread = vfs_read(curlun->filp,
- (char __user *) bh->buf,
- amount, &file_offset_tmp);
- VLDBG(curlun, "file read %u @ %llu -> %d\n", amount,
- (unsigned long long) file_offset,
- (int) nread);
- if (signal_pending(current))
- return -EINTR;
-
- if (nread < 0) {
- LDBG(curlun, "error in file read: %d\n",
- (int) nread);
- nread = 0;
- } else if (nread < amount) {
- LDBG(curlun, "partial file read: %d/%u\n",
- (int) nread, amount);
- nread = round_down(nread, curlun->blksize);
- }
- file_offset += nread;
- amount_left -= nread;
- fsg->residue -= nread;
-
- /* Except at the end of the transfer, nread will be
- * equal to the buffer size, which is divisible by the
- * bulk-in maxpacket size.
- */
- bh->inreq->length = nread;
- bh->state = BUF_STATE_FULL;
-
- /* If an error occurred, report it and its position */
- if (nread < amount) {
- curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
- curlun->sense_data_info = file_offset >> curlun->blkbits;
- curlun->info_valid = 1;
- break;
- }
-
- if (amount_left == 0)
- break; // No more left to read
-
- /* Send this buffer and go read some more */
- bh->inreq->zero = 0;
- start_transfer(fsg, fsg->bulk_in, bh->inreq,
- &bh->inreq_busy, &bh->state);
- fsg->next_buffhd_to_fill = bh->next;
- }
-
- return -EIO; // No default reply
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static int do_write(struct fsg_dev *fsg)
-{
- struct fsg_lun *curlun = fsg->curlun;
- u32 lba;
- struct fsg_buffhd *bh;
- int get_some_more;
- u32 amount_left_to_req, amount_left_to_write;
- loff_t usb_offset, file_offset, file_offset_tmp;
- unsigned int amount;
- ssize_t nwritten;
- int rc;
-
- if (curlun->ro) {
- curlun->sense_data = SS_WRITE_PROTECTED;
- return -EINVAL;
- }
- spin_lock(&curlun->filp->f_lock);
- curlun->filp->f_flags &= ~O_SYNC; // Default is not to wait
- spin_unlock(&curlun->filp->f_lock);
-
- /* Get the starting Logical Block Address and check that it's
- * not too big */
- if (fsg->cmnd[0] == WRITE_6)
- lba = get_unaligned_be24(&fsg->cmnd[1]);
- else {
- lba = get_unaligned_be32(&fsg->cmnd[2]);
-
- /* We allow DPO (Disable Page Out = don't save data in the
- * cache) and FUA (Force Unit Access = write directly to the
- * medium). We don't implement DPO; we implement FUA by
- * performing synchronous output. */
- if ((fsg->cmnd[1] & ~0x18) != 0) {
- curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return -EINVAL;
- }
- /* FUA */
- if (!curlun->nofua && (fsg->cmnd[1] & 0x08)) {
- spin_lock(&curlun->filp->f_lock);
- curlun->filp->f_flags |= O_DSYNC;
- spin_unlock(&curlun->filp->f_lock);
- }
- }
- if (lba >= curlun->num_sectors) {
- curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- return -EINVAL;
- }
-
- /* Carry out the file writes */
- get_some_more = 1;
- file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits;
- amount_left_to_req = amount_left_to_write = fsg->data_size_from_cmnd;
-
- while (amount_left_to_write > 0) {
-
- /* Queue a request for more data from the host */
- bh = fsg->next_buffhd_to_fill;
- if (bh->state == BUF_STATE_EMPTY && get_some_more) {
-
- /* Figure out how much we want to get:
- * Try to get the remaining amount,
- * but not more than the buffer size.
- */
- amount = min(amount_left_to_req, mod_data.buflen);
-
- /* Beyond the end of the backing file? */
- if (usb_offset >= curlun->file_length) {
- get_some_more = 0;
- curlun->sense_data =
- SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- curlun->sense_data_info = usb_offset >> curlun->blkbits;
- curlun->info_valid = 1;
- continue;
- }
-
- /* Get the next buffer */
- usb_offset += amount;
- fsg->usb_amount_left -= amount;
- amount_left_to_req -= amount;
- if (amount_left_to_req == 0)
- get_some_more = 0;
-
- /* Except at the end of the transfer, amount will be
- * equal to the buffer size, which is divisible by
- * the bulk-out maxpacket size.
- */
- set_bulk_out_req_length(fsg, bh, amount);
- start_transfer(fsg, fsg->bulk_out, bh->outreq,
- &bh->outreq_busy, &bh->state);
- fsg->next_buffhd_to_fill = bh->next;
- continue;
- }
-
- /* Write the received data to the backing file */
- bh = fsg->next_buffhd_to_drain;
- if (bh->state == BUF_STATE_EMPTY && !get_some_more)
- break; // We stopped early
- if (bh->state == BUF_STATE_FULL) {
- smp_rmb();
- fsg->next_buffhd_to_drain = bh->next;
- bh->state = BUF_STATE_EMPTY;
-
- /* Did something go wrong with the transfer? */
- if (bh->outreq->status != 0) {
- curlun->sense_data = SS_COMMUNICATION_FAILURE;
- curlun->sense_data_info = file_offset >> curlun->blkbits;
- curlun->info_valid = 1;
- break;
- }
-
- amount = bh->outreq->actual;
- if (curlun->file_length - file_offset < amount) {
- LERROR(curlun,
- "write %u @ %llu beyond end %llu\n",
- amount, (unsigned long long) file_offset,
- (unsigned long long) curlun->file_length);
- amount = curlun->file_length - file_offset;
- }
-
- /* Don't accept excess data. The spec doesn't say
- * what to do in this case. We'll ignore the error.
- */
- amount = min(amount, bh->bulk_out_intended_length);
-
- /* Don't write a partial block */
- amount = round_down(amount, curlun->blksize);
- if (amount == 0)
- goto empty_write;
-
- /* Perform the write */
- file_offset_tmp = file_offset;
- nwritten = vfs_write(curlun->filp,
- (char __user *) bh->buf,
- amount, &file_offset_tmp);
- VLDBG(curlun, "file write %u @ %llu -> %d\n", amount,
- (unsigned long long) file_offset,
- (int) nwritten);
- if (signal_pending(current))
- return -EINTR; // Interrupted!
-
- if (nwritten < 0) {
- LDBG(curlun, "error in file write: %d\n",
- (int) nwritten);
- nwritten = 0;
- } else if (nwritten < amount) {
- LDBG(curlun, "partial file write: %d/%u\n",
- (int) nwritten, amount);
- nwritten = round_down(nwritten, curlun->blksize);
- }
- file_offset += nwritten;
- amount_left_to_write -= nwritten;
- fsg->residue -= nwritten;
-
- /* If an error occurred, report it and its position */
- if (nwritten < amount) {
- curlun->sense_data = SS_WRITE_ERROR;
- curlun->sense_data_info = file_offset >> curlun->blkbits;
- curlun->info_valid = 1;
- break;
- }
-
- empty_write:
- /* Did the host decide to stop early? */
- if (bh->outreq->actual < bh->bulk_out_intended_length) {
- fsg->short_packet_received = 1;
- break;
- }
- continue;
- }
-
- /* Wait for something to happen */
- rc = sleep_thread(fsg);
- if (rc)
- return rc;
- }
-
- return -EIO; // No default reply
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static int do_synchronize_cache(struct fsg_dev *fsg)
-{
- struct fsg_lun *curlun = fsg->curlun;
- int rc;
-
- /* We ignore the requested LBA and write out all file's
- * dirty data buffers. */
- rc = fsg_lun_fsync_sub(curlun);
- if (rc)
- curlun->sense_data = SS_WRITE_ERROR;
- return 0;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static void invalidate_sub(struct fsg_lun *curlun)
-{
- struct file *filp = curlun->filp;
- struct inode *inode = filp->f_path.dentry->d_inode;
- unsigned long rc;
-
- rc = invalidate_mapping_pages(inode->i_mapping, 0, -1);
- VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc);
-}
-
-static int do_verify(struct fsg_dev *fsg)
-{
- struct fsg_lun *curlun = fsg->curlun;
- u32 lba;
- u32 verification_length;
- struct fsg_buffhd *bh = fsg->next_buffhd_to_fill;
- loff_t file_offset, file_offset_tmp;
- u32 amount_left;
- unsigned int amount;
- ssize_t nread;
-
- /* Get the starting Logical Block Address and check that it's
- * not too big */
- lba = get_unaligned_be32(&fsg->cmnd[2]);
- if (lba >= curlun->num_sectors) {
- curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- return -EINVAL;
- }
-
- /* We allow DPO (Disable Page Out = don't save data in the
- * cache) but we don't implement it. */
- if ((fsg->cmnd[1] & ~0x10) != 0) {
- curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return -EINVAL;
- }
-
- verification_length = get_unaligned_be16(&fsg->cmnd[7]);
- if (unlikely(verification_length == 0))
- return -EIO; // No default reply
-
- /* Prepare to carry out the file verify */
- amount_left = verification_length << curlun->blkbits;
- file_offset = ((loff_t) lba) << curlun->blkbits;
-
- /* Write out all the dirty buffers before invalidating them */
- fsg_lun_fsync_sub(curlun);
- if (signal_pending(current))
- return -EINTR;
-
- invalidate_sub(curlun);
- if (signal_pending(current))
- return -EINTR;
-
- /* Just try to read the requested blocks */
- while (amount_left > 0) {
-
- /* Figure out how much we need to read:
- * Try to read the remaining amount, but not more than
- * the buffer size.
- * And don't try to read past the end of the file.
- */
- amount = min((unsigned int) amount_left, mod_data.buflen);
- amount = min((loff_t) amount,
- curlun->file_length - file_offset);
- if (amount == 0) {
- curlun->sense_data =
- SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- curlun->sense_data_info = file_offset >> curlun->blkbits;
- curlun->info_valid = 1;
- break;
- }
-
- /* Perform the read */
- file_offset_tmp = file_offset;
- nread = vfs_read(curlun->filp,
- (char __user *) bh->buf,
- amount, &file_offset_tmp);
- VLDBG(curlun, "file read %u @ %llu -> %d\n", amount,
- (unsigned long long) file_offset,
- (int) nread);
- if (signal_pending(current))
- return -EINTR;
-
- if (nread < 0) {
- LDBG(curlun, "error in file verify: %d\n",
- (int) nread);
- nread = 0;
- } else if (nread < amount) {
- LDBG(curlun, "partial file verify: %d/%u\n",
- (int) nread, amount);
- nread = round_down(nread, curlun->blksize);
- }
- if (nread == 0) {
- curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
- curlun->sense_data_info = file_offset >> curlun->blkbits;
- curlun->info_valid = 1;
- break;
- }
- file_offset += nread;
- amount_left -= nread;
- }
- return 0;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-{
- u8 *buf = (u8 *) bh->buf;
-
- static char vendor_id[] = "Linux ";
- static char product_disk_id[] = "File-Stor Gadget";
- static char product_cdrom_id[] = "File-CD Gadget ";
-
- if (!fsg->curlun) { // Unsupported LUNs are okay
- fsg->bad_lun_okay = 1;
- memset(buf, 0, 36);
- buf[0] = 0x7f; // Unsupported, no device-type
- buf[4] = 31; // Additional length
- return 36;
- }
-
- memset(buf, 0, 8);
- buf[0] = (mod_data.cdrom ? TYPE_ROM : TYPE_DISK);
- if (mod_data.removable)
- buf[1] = 0x80;
- buf[2] = 2; // ANSI SCSI level 2
- buf[3] = 2; // SCSI-2 INQUIRY data format
- buf[4] = 31; // Additional length
- // No special options
- sprintf(buf + 8, "%-8s%-16s%04x", vendor_id,
- (mod_data.cdrom ? product_cdrom_id :
- product_disk_id),
- mod_data.release);
- return 36;
-}
-
-
-static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-{
- struct fsg_lun *curlun = fsg->curlun;
- u8 *buf = (u8 *) bh->buf;
- u32 sd, sdinfo;
- int valid;
-
- /*
- * From the SCSI-2 spec., section 7.9 (Unit attention condition):
- *
- * If a REQUEST SENSE command is received from an initiator
- * with a pending unit attention condition (before the target
- * generates the contingent allegiance condition), then the
- * target shall either:
- * a) report any pending sense data and preserve the unit
- * attention condition on the logical unit, or,
- * b) report the unit attention condition, may discard any
- * pending sense data, and clear the unit attention
- * condition on the logical unit for that initiator.
- *
- * FSG normally uses option a); enable this code to use option b).
- */
-#if 0
- if (curlun && curlun->unit_attention_data != SS_NO_SENSE) {
- curlun->sense_data = curlun->unit_attention_data;
- curlun->unit_attention_data = SS_NO_SENSE;
- }
-#endif
-
- if (!curlun) { // Unsupported LUNs are okay
- fsg->bad_lun_okay = 1;
- sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
- sdinfo = 0;
- valid = 0;
- } else {
- sd = curlun->sense_data;
- sdinfo = curlun->sense_data_info;
- valid = curlun->info_valid << 7;
- curlun->sense_data = SS_NO_SENSE;
- curlun->sense_data_info = 0;
- curlun->info_valid = 0;
- }
-
- memset(buf, 0, 18);
- buf[0] = valid | 0x70; // Valid, current error
- buf[2] = SK(sd);
- put_unaligned_be32(sdinfo, &buf[3]); /* Sense information */
- buf[7] = 18 - 8; // Additional sense length
- buf[12] = ASC(sd);
- buf[13] = ASCQ(sd);
- return 18;
-}
-
-
-static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-{
- struct fsg_lun *curlun = fsg->curlun;
- u32 lba = get_unaligned_be32(&fsg->cmnd[2]);
- int pmi = fsg->cmnd[8];
- u8 *buf = (u8 *) bh->buf;
-
- /* Check the PMI and LBA fields */
- if (pmi > 1 || (pmi == 0 && lba != 0)) {
- curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return -EINVAL;
- }
-
- put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
- /* Max logical block */
- put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */
- return 8;
-}
-
-
-static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-{
- struct fsg_lun *curlun = fsg->curlun;
- int msf = fsg->cmnd[1] & 0x02;
- u32 lba = get_unaligned_be32(&fsg->cmnd[2]);
- u8 *buf = (u8 *) bh->buf;
-
- if ((fsg->cmnd[1] & ~0x02) != 0) { /* Mask away MSF */
- curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return -EINVAL;
- }
- if (lba >= curlun->num_sectors) {
- curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- return -EINVAL;
- }
-
- memset(buf, 0, 8);
- buf[0] = 0x01; /* 2048 bytes of user data, rest is EC */
- store_cdrom_address(&buf[4], msf, lba);
- return 8;
-}
-
-
-static int do_read_toc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-{
- struct fsg_lun *curlun = fsg->curlun;
- int msf = fsg->cmnd[1] & 0x02;
- int start_track = fsg->cmnd[6];
- u8 *buf = (u8 *) bh->buf;
-
- if ((fsg->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */
- start_track > 1) {
- curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return -EINVAL;
- }
-
- memset(buf, 0, 20);
- buf[1] = (20-2); /* TOC data length */
- buf[2] = 1; /* First track number */
- buf[3] = 1; /* Last track number */
- buf[5] = 0x16; /* Data track, copying allowed */
- buf[6] = 0x01; /* Only track is number 1 */
- store_cdrom_address(&buf[8], msf, 0);
-
- buf[13] = 0x16; /* Lead-out track is data */
- buf[14] = 0xAA; /* Lead-out track number */
- store_cdrom_address(&buf[16], msf, curlun->num_sectors);
- return 20;
-}
-
-
-static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-{
- struct fsg_lun *curlun = fsg->curlun;
- int mscmnd = fsg->cmnd[0];
- u8 *buf = (u8 *) bh->buf;
- u8 *buf0 = buf;
- int pc, page_code;
- int changeable_values, all_pages;
- int valid_page = 0;
- int len, limit;
-
- if ((fsg->cmnd[1] & ~0x08) != 0) { // Mask away DBD
- curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return -EINVAL;
- }
- pc = fsg->cmnd[2] >> 6;
- page_code = fsg->cmnd[2] & 0x3f;
- if (pc == 3) {
- curlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED;
- return -EINVAL;
- }
- changeable_values = (pc == 1);
- all_pages = (page_code == 0x3f);
-
- /* Write the mode parameter header. Fixed values are: default
- * medium type, no cache control (DPOFUA), and no block descriptors.
- * The only variable value is the WriteProtect bit. We will fill in
- * the mode data length later. */
- memset(buf, 0, 8);
- if (mscmnd == MODE_SENSE) {
- buf[2] = (curlun->ro ? 0x80 : 0x00); // WP, DPOFUA
- buf += 4;
- limit = 255;
- } else { // MODE_SENSE_10
- buf[3] = (curlun->ro ? 0x80 : 0x00); // WP, DPOFUA
- buf += 8;
- limit = 65535; // Should really be mod_data.buflen
- }
-
- /* No block descriptors */
-
- /* The mode pages, in numerical order. The only page we support
- * is the Caching page. */
- if (page_code == 0x08 || all_pages) {
- valid_page = 1;
- buf[0] = 0x08; // Page code
- buf[1] = 10; // Page length
- memset(buf+2, 0, 10); // None of the fields are changeable
-
- if (!changeable_values) {
- buf[2] = 0x04; // Write cache enable,
- // Read cache not disabled
- // No cache retention priorities
- put_unaligned_be16(0xffff, &buf[4]);
- /* Don't disable prefetch */
- /* Minimum prefetch = 0 */
- put_unaligned_be16(0xffff, &buf[8]);
- /* Maximum prefetch */
- put_unaligned_be16(0xffff, &buf[10]);
- /* Maximum prefetch ceiling */
- }
- buf += 12;
- }
-
- /* Check that a valid page was requested and the mode data length
- * isn't too long. */
- len = buf - buf0;
- if (!valid_page || len > limit) {
- curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return -EINVAL;
- }
-
- /* Store the mode data length */
- if (mscmnd == MODE_SENSE)
- buf0[0] = len - 1;
- else
- put_unaligned_be16(len - 2, buf0);
- return len;
-}
-
-
-static int do_start_stop(struct fsg_dev *fsg)
-{
- struct fsg_lun *curlun = fsg->curlun;
- int loej, start;
-
- if (!mod_data.removable) {
- curlun->sense_data = SS_INVALID_COMMAND;
- return -EINVAL;
- }
-
- // int immed = fsg->cmnd[1] & 0x01;
- loej = fsg->cmnd[4] & 0x02;
- start = fsg->cmnd[4] & 0x01;
-
-#ifdef CONFIG_USB_FILE_STORAGE_TEST
- if ((fsg->cmnd[1] & ~0x01) != 0 || // Mask away Immed
- (fsg->cmnd[4] & ~0x03) != 0) { // Mask LoEj, Start
- curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return -EINVAL;
- }
-
- if (!start) {
-
- /* Are we allowed to unload the media? */
- if (curlun->prevent_medium_removal) {
- LDBG(curlun, "unload attempt prevented\n");
- curlun->sense_data = SS_MEDIUM_REMOVAL_PREVENTED;
- return -EINVAL;
- }
- if (loej) { // Simulate an unload/eject
- up_read(&fsg->filesem);
- down_write(&fsg->filesem);
- fsg_lun_close(curlun);
- up_write(&fsg->filesem);
- down_read(&fsg->filesem);
- }
- } else {
-
- /* Our emulation doesn't support mounting; the medium is
- * available for use as soon as it is loaded. */
- if (!fsg_lun_is_open(curlun)) {
- curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
- return -EINVAL;
- }
- }
-#endif
- return 0;
-}
-
-
-static int do_prevent_allow(struct fsg_dev *fsg)
-{
- struct fsg_lun *curlun = fsg->curlun;
- int prevent;
-
- if (!mod_data.removable) {
- curlun->sense_data = SS_INVALID_COMMAND;
- return -EINVAL;
- }
-
- prevent = fsg->cmnd[4] & 0x01;
- if ((fsg->cmnd[4] & ~0x01) != 0) { // Mask away Prevent
- curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return -EINVAL;
- }
-
- if (curlun->prevent_medium_removal && !prevent)
- fsg_lun_fsync_sub(curlun);
- curlun->prevent_medium_removal = prevent;
- return 0;
-}
-
-
-static int do_read_format_capacities(struct fsg_dev *fsg,
- struct fsg_buffhd *bh)
-{
- struct fsg_lun *curlun = fsg->curlun;
- u8 *buf = (u8 *) bh->buf;
-
- buf[0] = buf[1] = buf[2] = 0;
- buf[3] = 8; // Only the Current/Maximum Capacity Descriptor
- buf += 4;
-
- put_unaligned_be32(curlun->num_sectors, &buf[0]);
- /* Number of blocks */
- put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */
- buf[4] = 0x02; /* Current capacity */
- return 12;
-}
-
-
-static int do_mode_select(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-{
- struct fsg_lun *curlun = fsg->curlun;
-
- /* We don't support MODE SELECT */
- curlun->sense_data = SS_INVALID_COMMAND;
- return -EINVAL;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static int halt_bulk_in_endpoint(struct fsg_dev *fsg)
-{
- int rc;
-
- rc = fsg_set_halt(fsg, fsg->bulk_in);
- if (rc == -EAGAIN)
- VDBG(fsg, "delayed bulk-in endpoint halt\n");
- while (rc != 0) {
- if (rc != -EAGAIN) {
- WARNING(fsg, "usb_ep_set_halt -> %d\n", rc);
- rc = 0;
- break;
- }
-
- /* Wait for a short time and then try again */
- if (msleep_interruptible(100) != 0)
- return -EINTR;
- rc = usb_ep_set_halt(fsg->bulk_in);
- }
- return rc;
-}
-
-static int wedge_bulk_in_endpoint(struct fsg_dev *fsg)
-{
- int rc;
-
- DBG(fsg, "bulk-in set wedge\n");
- rc = usb_ep_set_wedge(fsg->bulk_in);
- if (rc == -EAGAIN)
- VDBG(fsg, "delayed bulk-in endpoint wedge\n");
- while (rc != 0) {
- if (rc != -EAGAIN) {
- WARNING(fsg, "usb_ep_set_wedge -> %d\n", rc);
- rc = 0;
- break;
- }
-
- /* Wait for a short time and then try again */
- if (msleep_interruptible(100) != 0)
- return -EINTR;
- rc = usb_ep_set_wedge(fsg->bulk_in);
- }
- return rc;
-}
-
-static int throw_away_data(struct fsg_dev *fsg)
-{
- struct fsg_buffhd *bh;
- u32 amount;
- int rc;
-
- while ((bh = fsg->next_buffhd_to_drain)->state != BUF_STATE_EMPTY ||
- fsg->usb_amount_left > 0) {
-
- /* Throw away the data in a filled buffer */
- if (bh->state == BUF_STATE_FULL) {
- smp_rmb();
- bh->state = BUF_STATE_EMPTY;
- fsg->next_buffhd_to_drain = bh->next;
-
- /* A short packet or an error ends everything */
- if (bh->outreq->actual < bh->bulk_out_intended_length ||
- bh->outreq->status != 0) {
- raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT);
- return -EINTR;
- }
- continue;
- }
-
- /* Try to submit another request if we need one */
- bh = fsg->next_buffhd_to_fill;
- if (bh->state == BUF_STATE_EMPTY && fsg->usb_amount_left > 0) {
- amount = min(fsg->usb_amount_left,
- (u32) mod_data.buflen);
-
- /* Except at the end of the transfer, amount will be
- * equal to the buffer size, which is divisible by
- * the bulk-out maxpacket size.
- */
- set_bulk_out_req_length(fsg, bh, amount);
- start_transfer(fsg, fsg->bulk_out, bh->outreq,
- &bh->outreq_busy, &bh->state);
- fsg->next_buffhd_to_fill = bh->next;
- fsg->usb_amount_left -= amount;
- continue;
- }
-
- /* Otherwise wait for something to happen */
- rc = sleep_thread(fsg);
- if (rc)
- return rc;
- }
- return 0;
-}
-
-
-static int finish_reply(struct fsg_dev *fsg)
-{
- struct fsg_buffhd *bh = fsg->next_buffhd_to_fill;
- int rc = 0;
-
- switch (fsg->data_dir) {
- case DATA_DIR_NONE:
- break; // Nothing to send
-
- /* If we don't know whether the host wants to read or write,
- * this must be CB or CBI with an unknown command. We mustn't
- * try to send or receive any data. So stall both bulk pipes
- * if we can and wait for a reset. */
- case DATA_DIR_UNKNOWN:
- if (mod_data.can_stall) {
- fsg_set_halt(fsg, fsg->bulk_out);
- rc = halt_bulk_in_endpoint(fsg);
- }
- break;
-
- /* All but the last buffer of data must have already been sent */
- case DATA_DIR_TO_HOST:
- if (fsg->data_size == 0)
- ; // Nothing to send
-
- /* If there's no residue, simply send the last buffer */
- else if (fsg->residue == 0) {
- bh->inreq->zero = 0;
- start_transfer(fsg, fsg->bulk_in, bh->inreq,
- &bh->inreq_busy, &bh->state);
- fsg->next_buffhd_to_fill = bh->next;
- }
-
- /* There is a residue. For CB and CBI, simply mark the end
- * of the data with a short packet. However, if we are
- * allowed to stall, there was no data at all (residue ==
- * data_size), and the command failed (invalid LUN or
- * sense data is set), then halt the bulk-in endpoint
- * instead. */
- else if (!transport_is_bbb()) {
- if (mod_data.can_stall &&
- fsg->residue == fsg->data_size &&
- (!fsg->curlun || fsg->curlun->sense_data != SS_NO_SENSE)) {
- bh->state = BUF_STATE_EMPTY;
- rc = halt_bulk_in_endpoint(fsg);
- } else {
- bh->inreq->zero = 1;
- start_transfer(fsg, fsg->bulk_in, bh->inreq,
- &bh->inreq_busy, &bh->state);
- fsg->next_buffhd_to_fill = bh->next;
- }
- }
-
- /*
- * For Bulk-only, mark the end of the data with a short
- * packet. If we are allowed to stall, halt the bulk-in
- * endpoint. (Note: This violates the Bulk-Only Transport
- * specification, which requires us to pad the data if we
- * don't halt the endpoint. Presumably nobody will mind.)
- */
- else {
- bh->inreq->zero = 1;
- start_transfer(fsg, fsg->bulk_in, bh->inreq,
- &bh->inreq_busy, &bh->state);
- fsg->next_buffhd_to_fill = bh->next;
- if (mod_data.can_stall)
- rc = halt_bulk_in_endpoint(fsg);
- }
- break;
-
- /* We have processed all we want from the data the host has sent.
- * There may still be outstanding bulk-out requests. */
- case DATA_DIR_FROM_HOST:
- if (fsg->residue == 0)
- ; // Nothing to receive
-
- /* Did the host stop sending unexpectedly early? */
- else if (fsg->short_packet_received) {
- raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT);
- rc = -EINTR;
- }
-
- /* We haven't processed all the incoming data. Even though
- * we may be allowed to stall, doing so would cause a race.
- * The controller may already have ACK'ed all the remaining
- * bulk-out packets, in which case the host wouldn't see a
- * STALL. Not realizing the endpoint was halted, it wouldn't
- * clear the halt -- leading to problems later on. */
-#if 0
- else if (mod_data.can_stall) {
- fsg_set_halt(fsg, fsg->bulk_out);
- raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT);
- rc = -EINTR;
- }
-#endif
-
- /* We can't stall. Read in the excess data and throw it
- * all away. */
- else
- rc = throw_away_data(fsg);
- break;
- }
- return rc;
-}
-
-
-static int send_status(struct fsg_dev *fsg)
-{
- struct fsg_lun *curlun = fsg->curlun;
- struct fsg_buffhd *bh;
- int rc;
- u8 status = US_BULK_STAT_OK;
- u32 sd, sdinfo = 0;
-
- /* Wait for the next buffer to become available */
- bh = fsg->next_buffhd_to_fill;
- while (bh->state != BUF_STATE_EMPTY) {
- rc = sleep_thread(fsg);
- if (rc)
- return rc;
- }
-
- if (curlun) {
- sd = curlun->sense_data;
- sdinfo = curlun->sense_data_info;
- } else if (fsg->bad_lun_okay)
- sd = SS_NO_SENSE;
- else
- sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
-
- if (fsg->phase_error) {
- DBG(fsg, "sending phase-error status\n");
- status = US_BULK_STAT_PHASE;
- sd = SS_INVALID_COMMAND;
- } else if (sd != SS_NO_SENSE) {
- DBG(fsg, "sending command-failure status\n");
- status = US_BULK_STAT_FAIL;
- VDBG(fsg, " sense data: SK x%02x, ASC x%02x, ASCQ x%02x;"
- " info x%x\n",
- SK(sd), ASC(sd), ASCQ(sd), sdinfo);
- }
-
- if (transport_is_bbb()) {
- struct bulk_cs_wrap *csw = bh->buf;
-
- /* Store and send the Bulk-only CSW */
- csw->Signature = cpu_to_le32(US_BULK_CS_SIGN);
- csw->Tag = fsg->tag;
- csw->Residue = cpu_to_le32(fsg->residue);
- csw->Status = status;
-
- bh->inreq->length = US_BULK_CS_WRAP_LEN;
- bh->inreq->zero = 0;
- start_transfer(fsg, fsg->bulk_in, bh->inreq,
- &bh->inreq_busy, &bh->state);
-
- } else if (mod_data.transport_type == USB_PR_CB) {
-
- /* Control-Bulk transport has no status phase! */
- return 0;
-
- } else { // USB_PR_CBI
- struct interrupt_data *buf = bh->buf;
-
- /* Store and send the Interrupt data. UFI sends the ASC
- * and ASCQ bytes. Everything else sends a Type (which
- * is always 0) and the status Value. */
- if (mod_data.protocol_type == USB_SC_UFI) {
- buf->bType = ASC(sd);
- buf->bValue = ASCQ(sd);
- } else {
- buf->bType = 0;
- buf->bValue = status;
- }
- fsg->intreq->length = CBI_INTERRUPT_DATA_LEN;
-
- fsg->intr_buffhd = bh; // Point to the right buffhd
- fsg->intreq->buf = bh->inreq->buf;
- fsg->intreq->context = bh;
- start_transfer(fsg, fsg->intr_in, fsg->intreq,
- &fsg->intreq_busy, &bh->state);
- }
-
- fsg->next_buffhd_to_fill = bh->next;
- return 0;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Check whether the command is properly formed and whether its data size
- * and direction agree with the values we already have. */
-static int check_command(struct fsg_dev *fsg, int cmnd_size,
- enum data_direction data_dir, unsigned int mask,
- int needs_medium, const char *name)
-{
- int i;
- int lun = fsg->cmnd[1] >> 5;
- static const char dirletter[4] = {'u', 'o', 'i', 'n'};
- char hdlen[20];
- struct fsg_lun *curlun;
-
- /* Adjust the expected cmnd_size for protocol encapsulation padding.
- * Transparent SCSI doesn't pad. */
- if (protocol_is_scsi())
- ;
-
- /* There's some disagreement as to whether RBC pads commands or not.
- * We'll play it safe and accept either form. */
- else if (mod_data.protocol_type == USB_SC_RBC) {
- if (fsg->cmnd_size == 12)
- cmnd_size = 12;
-
- /* All the other protocols pad to 12 bytes */
- } else
- cmnd_size = 12;
-
- hdlen[0] = 0;
- if (fsg->data_dir != DATA_DIR_UNKNOWN)
- sprintf(hdlen, ", H%c=%u", dirletter[(int) fsg->data_dir],
- fsg->data_size);
- VDBG(fsg, "SCSI command: %s; Dc=%d, D%c=%u; Hc=%d%s\n",
- name, cmnd_size, dirletter[(int) data_dir],
- fsg->data_size_from_cmnd, fsg->cmnd_size, hdlen);
-
- /* We can't reply at all until we know the correct data direction
- * and size. */
- if (fsg->data_size_from_cmnd == 0)
- data_dir = DATA_DIR_NONE;
- if (fsg->data_dir == DATA_DIR_UNKNOWN) { // CB or CBI
- fsg->data_dir = data_dir;
- fsg->data_size = fsg->data_size_from_cmnd;
-
- } else { // Bulk-only
- if (fsg->data_size < fsg->data_size_from_cmnd) {
-
- /* Host data size < Device data size is a phase error.
- * Carry out the command, but only transfer as much
- * as we are allowed. */
- fsg->data_size_from_cmnd = fsg->data_size;
- fsg->phase_error = 1;
- }
- }
- fsg->residue = fsg->usb_amount_left = fsg->data_size;
-
- /* Conflicting data directions is a phase error */
- if (fsg->data_dir != data_dir && fsg->data_size_from_cmnd > 0) {
- fsg->phase_error = 1;
- return -EINVAL;
- }
-
- /* Verify the length of the command itself */
- if (cmnd_size != fsg->cmnd_size) {
-
- /* Special case workaround: There are plenty of buggy SCSI
- * implementations. Many have issues with cbw->Length
- * field passing a wrong command size. For those cases we
- * always try to work around the problem by using the length
- * sent by the host side provided it is at least as large
- * as the correct command length.
- * Examples of such cases would be MS-Windows, which issues
- * REQUEST SENSE with cbw->Length == 12 where it should
- * be 6, and xbox360 issuing INQUIRY, TEST UNIT READY and
- * REQUEST SENSE with cbw->Length == 10 where it should
- * be 6 as well.
- */
- if (cmnd_size <= fsg->cmnd_size) {
- DBG(fsg, "%s is buggy! Expected length %d "
- "but we got %d\n", name,
- cmnd_size, fsg->cmnd_size);
- cmnd_size = fsg->cmnd_size;
- } else {
- fsg->phase_error = 1;
- return -EINVAL;
- }
- }
-
- /* Check that the LUN values are consistent */
- if (transport_is_bbb()) {
- if (fsg->lun != lun)
- DBG(fsg, "using LUN %d from CBW, "
- "not LUN %d from CDB\n",
- fsg->lun, lun);
- }
-
- /* Check the LUN */
- curlun = fsg->curlun;
- if (curlun) {
- if (fsg->cmnd[0] != REQUEST_SENSE) {
- curlun->sense_data = SS_NO_SENSE;
- curlun->sense_data_info = 0;
- curlun->info_valid = 0;
- }
- } else {
- fsg->bad_lun_okay = 0;
-
- /* INQUIRY and REQUEST SENSE commands are explicitly allowed
- * to use unsupported LUNs; all others may not. */
- if (fsg->cmnd[0] != INQUIRY &&
- fsg->cmnd[0] != REQUEST_SENSE) {
- DBG(fsg, "unsupported LUN %d\n", fsg->lun);
- return -EINVAL;
- }
- }
-
- /* If a unit attention condition exists, only INQUIRY and
- * REQUEST SENSE commands are allowed; anything else must fail. */
- if (curlun && curlun->unit_attention_data != SS_NO_SENSE &&
- fsg->cmnd[0] != INQUIRY &&
- fsg->cmnd[0] != REQUEST_SENSE) {
- curlun->sense_data = curlun->unit_attention_data;
- curlun->unit_attention_data = SS_NO_SENSE;
- return -EINVAL;
- }
-
- /* Check that only command bytes listed in the mask are non-zero */
- fsg->cmnd[1] &= 0x1f; // Mask away the LUN
- for (i = 1; i < cmnd_size; ++i) {
- if (fsg->cmnd[i] && !(mask & (1 << i))) {
- if (curlun)
- curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return -EINVAL;
- }
- }
-
- /* If the medium isn't mounted and the command needs to access
- * it, return an error. */
- if (curlun && !fsg_lun_is_open(curlun) && needs_medium) {
- curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* wrapper of check_command for data size in blocks handling */
-static int check_command_size_in_blocks(struct fsg_dev *fsg, int cmnd_size,
- enum data_direction data_dir, unsigned int mask,
- int needs_medium, const char *name)
-{
- if (fsg->curlun)
- fsg->data_size_from_cmnd <<= fsg->curlun->blkbits;
- return check_command(fsg, cmnd_size, data_dir,
- mask, needs_medium, name);
-}
-
-static int do_scsi_command(struct fsg_dev *fsg)
-{
- struct fsg_buffhd *bh;
- int rc;
- int reply = -EINVAL;
- int i;
- static char unknown[16];
-
- dump_cdb(fsg);
-
- /* Wait for the next buffer to become available for data or status */
- bh = fsg->next_buffhd_to_drain = fsg->next_buffhd_to_fill;
- while (bh->state != BUF_STATE_EMPTY) {
- rc = sleep_thread(fsg);
- if (rc)
- return rc;
- }
- fsg->phase_error = 0;
- fsg->short_packet_received = 0;
-
- down_read(&fsg->filesem); // We're using the backing file
- switch (fsg->cmnd[0]) {
-
- case INQUIRY:
- fsg->data_size_from_cmnd = fsg->cmnd[4];
- if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
- (1<<4), 0,
- "INQUIRY")) == 0)
- reply = do_inquiry(fsg, bh);
- break;
-
- case MODE_SELECT:
- fsg->data_size_from_cmnd = fsg->cmnd[4];
- if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST,
- (1<<1) | (1<<4), 0,
- "MODE SELECT(6)")) == 0)
- reply = do_mode_select(fsg, bh);
- break;
-
- case MODE_SELECT_10:
- fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
- if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST,
- (1<<1) | (3<<7), 0,
- "MODE SELECT(10)")) == 0)
- reply = do_mode_select(fsg, bh);
- break;
-
- case MODE_SENSE:
- fsg->data_size_from_cmnd = fsg->cmnd[4];
- if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
- (1<<1) | (1<<2) | (1<<4), 0,
- "MODE SENSE(6)")) == 0)
- reply = do_mode_sense(fsg, bh);
- break;
-
- case MODE_SENSE_10:
- fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
- if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
- (1<<1) | (1<<2) | (3<<7), 0,
- "MODE SENSE(10)")) == 0)
- reply = do_mode_sense(fsg, bh);
- break;
-
- case ALLOW_MEDIUM_REMOVAL:
- fsg->data_size_from_cmnd = 0;
- if ((reply = check_command(fsg, 6, DATA_DIR_NONE,
- (1<<4), 0,
- "PREVENT-ALLOW MEDIUM REMOVAL")) == 0)
- reply = do_prevent_allow(fsg);
- break;
-
- case READ_6:
- i = fsg->cmnd[4];
- fsg->data_size_from_cmnd = (i == 0) ? 256 : i;
- if ((reply = check_command_size_in_blocks(fsg, 6,
- DATA_DIR_TO_HOST,
- (7<<1) | (1<<4), 1,
- "READ(6)")) == 0)
- reply = do_read(fsg);
- break;
-
- case READ_10:
- fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
- if ((reply = check_command_size_in_blocks(fsg, 10,
- DATA_DIR_TO_HOST,
- (1<<1) | (0xf<<2) | (3<<7), 1,
- "READ(10)")) == 0)
- reply = do_read(fsg);
- break;
-
- case READ_12:
- fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]);
- if ((reply = check_command_size_in_blocks(fsg, 12,
- DATA_DIR_TO_HOST,
- (1<<1) | (0xf<<2) | (0xf<<6), 1,
- "READ(12)")) == 0)
- reply = do_read(fsg);
- break;
-
- case READ_CAPACITY:
- fsg->data_size_from_cmnd = 8;
- if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
- (0xf<<2) | (1<<8), 1,
- "READ CAPACITY")) == 0)
- reply = do_read_capacity(fsg, bh);
- break;
-
- case READ_HEADER:
- if (!mod_data.cdrom)
- goto unknown_cmnd;
- fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
- if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
- (3<<7) | (0x1f<<1), 1,
- "READ HEADER")) == 0)
- reply = do_read_header(fsg, bh);
- break;
-
- case READ_TOC:
- if (!mod_data.cdrom)
- goto unknown_cmnd;
- fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
- if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
- (7<<6) | (1<<1), 1,
- "READ TOC")) == 0)
- reply = do_read_toc(fsg, bh);
- break;
-
- case READ_FORMAT_CAPACITIES:
- fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
- if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
- (3<<7), 1,
- "READ FORMAT CAPACITIES")) == 0)
- reply = do_read_format_capacities(fsg, bh);
- break;
-
- case REQUEST_SENSE:
- fsg->data_size_from_cmnd = fsg->cmnd[4];
- if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
- (1<<4), 0,
- "REQUEST SENSE")) == 0)
- reply = do_request_sense(fsg, bh);
- break;
-
- case START_STOP:
- fsg->data_size_from_cmnd = 0;
- if ((reply = check_command(fsg, 6, DATA_DIR_NONE,
- (1<<1) | (1<<4), 0,
- "START-STOP UNIT")) == 0)
- reply = do_start_stop(fsg);
- break;
-
- case SYNCHRONIZE_CACHE:
- fsg->data_size_from_cmnd = 0;
- if ((reply = check_command(fsg, 10, DATA_DIR_NONE,
- (0xf<<2) | (3<<7), 1,
- "SYNCHRONIZE CACHE")) == 0)
- reply = do_synchronize_cache(fsg);
- break;
-
- case TEST_UNIT_READY:
- fsg->data_size_from_cmnd = 0;
- reply = check_command(fsg, 6, DATA_DIR_NONE,
- 0, 1,
- "TEST UNIT READY");
- break;
-
- /* Although optional, this command is used by MS-Windows. We
- * support a minimal version: BytChk must be 0. */
- case VERIFY:
- fsg->data_size_from_cmnd = 0;
- if ((reply = check_command(fsg, 10, DATA_DIR_NONE,
- (1<<1) | (0xf<<2) | (3<<7), 1,
- "VERIFY")) == 0)
- reply = do_verify(fsg);
- break;
-
- case WRITE_6:
- i = fsg->cmnd[4];
- fsg->data_size_from_cmnd = (i == 0) ? 256 : i;
- if ((reply = check_command_size_in_blocks(fsg, 6,
- DATA_DIR_FROM_HOST,
- (7<<1) | (1<<4), 1,
- "WRITE(6)")) == 0)
- reply = do_write(fsg);
- break;
-
- case WRITE_10:
- fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
- if ((reply = check_command_size_in_blocks(fsg, 10,
- DATA_DIR_FROM_HOST,
- (1<<1) | (0xf<<2) | (3<<7), 1,
- "WRITE(10)")) == 0)
- reply = do_write(fsg);
- break;
-
- case WRITE_12:
- fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]);
- if ((reply = check_command_size_in_blocks(fsg, 12,
- DATA_DIR_FROM_HOST,
- (1<<1) | (0xf<<2) | (0xf<<6), 1,
- "WRITE(12)")) == 0)
- reply = do_write(fsg);
- break;
-
- /* Some mandatory commands that we recognize but don't implement.
- * They don't mean much in this setting. It's left as an exercise
- * for anyone interested to implement RESERVE and RELEASE in terms
- * of Posix locks. */
- case FORMAT_UNIT:
- case RELEASE:
- case RESERVE:
- case SEND_DIAGNOSTIC:
- // Fall through
-
- default:
- unknown_cmnd:
- fsg->data_size_from_cmnd = 0;
- sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]);
- if ((reply = check_command(fsg, fsg->cmnd_size,
- DATA_DIR_UNKNOWN, ~0, 0, unknown)) == 0) {
- fsg->curlun->sense_data = SS_INVALID_COMMAND;
- reply = -EINVAL;
- }
- break;
- }
- up_read(&fsg->filesem);
-
- if (reply == -EINTR || signal_pending(current))
- return -EINTR;
-
- /* Set up the single reply buffer for finish_reply() */
- if (reply == -EINVAL)
- reply = 0; // Error reply length
- if (reply >= 0 && fsg->data_dir == DATA_DIR_TO_HOST) {
- reply = min((u32) reply, fsg->data_size_from_cmnd);
- bh->inreq->length = reply;
- bh->state = BUF_STATE_FULL;
- fsg->residue -= reply;
- } // Otherwise it's already set
-
- return 0;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-{
- struct usb_request *req = bh->outreq;
- struct bulk_cb_wrap *cbw = req->buf;
-
- /* Was this a real packet? Should it be ignored? */
- if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags))
- return -EINVAL;
-
- /* Is the CBW valid? */
- if (req->actual != US_BULK_CB_WRAP_LEN ||
- cbw->Signature != cpu_to_le32(
- US_BULK_CB_SIGN)) {
- DBG(fsg, "invalid CBW: len %u sig 0x%x\n",
- req->actual,
- le32_to_cpu(cbw->Signature));
-
- /* The Bulk-only spec says we MUST stall the IN endpoint
- * (6.6.1), so it's unavoidable. It also says we must
- * retain this state until the next reset, but there's
- * no way to tell the controller driver it should ignore
- * Clear-Feature(HALT) requests.
- *
- * We aren't required to halt the OUT endpoint; instead
- * we can simply accept and discard any data received
- * until the next reset. */
- wedge_bulk_in_endpoint(fsg);
- set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
- return -EINVAL;
- }
-
- /* Is the CBW meaningful? */
- if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~US_BULK_FLAG_IN ||
- cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) {
- DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, "
- "cmdlen %u\n",
- cbw->Lun, cbw->Flags, cbw->Length);
-
- /* We can do anything we want here, so let's stall the
- * bulk pipes if we are allowed to. */
- if (mod_data.can_stall) {
- fsg_set_halt(fsg, fsg->bulk_out);
- halt_bulk_in_endpoint(fsg);
- }
- return -EINVAL;
- }
-
- /* Save the command for later */
- fsg->cmnd_size = cbw->Length;
- memcpy(fsg->cmnd, cbw->CDB, fsg->cmnd_size);
- if (cbw->Flags & US_BULK_FLAG_IN)
- fsg->data_dir = DATA_DIR_TO_HOST;
- else
- fsg->data_dir = DATA_DIR_FROM_HOST;
- fsg->data_size = le32_to_cpu(cbw->DataTransferLength);
- if (fsg->data_size == 0)
- fsg->data_dir = DATA_DIR_NONE;
- fsg->lun = cbw->Lun;
- fsg->tag = cbw->Tag;
- return 0;
-}
-
-
-static int get_next_command(struct fsg_dev *fsg)
-{
- struct fsg_buffhd *bh;
- int rc = 0;
-
- if (transport_is_bbb()) {
-
- /* Wait for the next buffer to become available */
- bh = fsg->next_buffhd_to_fill;
- while (bh->state != BUF_STATE_EMPTY) {
- rc = sleep_thread(fsg);
- if (rc)
- return rc;
- }
-
- /* Queue a request to read a Bulk-only CBW */
- set_bulk_out_req_length(fsg, bh, US_BULK_CB_WRAP_LEN);
- start_transfer(fsg, fsg->bulk_out, bh->outreq,
- &bh->outreq_busy, &bh->state);
-
- /* We will drain the buffer in software, which means we
- * can reuse it for the next filling. No need to advance
- * next_buffhd_to_fill. */
-
- /* Wait for the CBW to arrive */
- while (bh->state != BUF_STATE_FULL) {
- rc = sleep_thread(fsg);
- if (rc)
- return rc;
- }
- smp_rmb();
- rc = received_cbw(fsg, bh);
- bh->state = BUF_STATE_EMPTY;
-
- } else { // USB_PR_CB or USB_PR_CBI
-
- /* Wait for the next command to arrive */
- while (fsg->cbbuf_cmnd_size == 0) {
- rc = sleep_thread(fsg);
- if (rc)
- return rc;
- }
-
- /* Is the previous status interrupt request still busy?
- * The host is allowed to skip reading the status,
- * so we must cancel it. */
- if (fsg->intreq_busy)
- usb_ep_dequeue(fsg->intr_in, fsg->intreq);
-
- /* Copy the command and mark the buffer empty */
- fsg->data_dir = DATA_DIR_UNKNOWN;
- spin_lock_irq(&fsg->lock);
- fsg->cmnd_size = fsg->cbbuf_cmnd_size;
- memcpy(fsg->cmnd, fsg->cbbuf_cmnd, fsg->cmnd_size);
- fsg->cbbuf_cmnd_size = 0;
- spin_unlock_irq(&fsg->lock);
-
- /* Use LUN from the command */
- fsg->lun = fsg->cmnd[1] >> 5;
- }
-
- /* Update current lun */
- if (fsg->lun >= 0 && fsg->lun < fsg->nluns)
- fsg->curlun = &fsg->luns[fsg->lun];
- else
- fsg->curlun = NULL;
-
- return rc;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static int enable_endpoint(struct fsg_dev *fsg, struct usb_ep *ep,
- const struct usb_endpoint_descriptor *d)
-{
- int rc;
-
- ep->driver_data = fsg;
- ep->desc = d;
- rc = usb_ep_enable(ep);
- if (rc)
- ERROR(fsg, "can't enable %s, result %d\n", ep->name, rc);
- return rc;
-}
-
-static int alloc_request(struct fsg_dev *fsg, struct usb_ep *ep,
- struct usb_request **preq)
-{
- *preq = usb_ep_alloc_request(ep, GFP_ATOMIC);
- if (*preq)
- return 0;
- ERROR(fsg, "can't allocate request for %s\n", ep->name);
- return -ENOMEM;
-}
-
-/*
- * Reset interface setting and re-init endpoint state (toggle etc).
- * Call with altsetting < 0 to disable the interface. The only other
- * available altsetting is 0, which enables the interface.
- */
-static int do_set_interface(struct fsg_dev *fsg, int altsetting)
-{
- int rc = 0;
- int i;
- const struct usb_endpoint_descriptor *d;
-
- if (fsg->running)
- DBG(fsg, "reset interface\n");
-
-reset:
- /* Deallocate the requests */
- for (i = 0; i < fsg_num_buffers; ++i) {
- struct fsg_buffhd *bh = &fsg->buffhds[i];
-
- if (bh->inreq) {
- usb_ep_free_request(fsg->bulk_in, bh->inreq);
- bh->inreq = NULL;
- }
- if (bh->outreq) {
- usb_ep_free_request(fsg->bulk_out, bh->outreq);
- bh->outreq = NULL;
- }
- }
- if (fsg->intreq) {
- usb_ep_free_request(fsg->intr_in, fsg->intreq);
- fsg->intreq = NULL;
- }
-
- /* Disable the endpoints */
- if (fsg->bulk_in_enabled) {
- usb_ep_disable(fsg->bulk_in);
- fsg->bulk_in_enabled = 0;
- }
- if (fsg->bulk_out_enabled) {
- usb_ep_disable(fsg->bulk_out);
- fsg->bulk_out_enabled = 0;
- }
- if (fsg->intr_in_enabled) {
- usb_ep_disable(fsg->intr_in);
- fsg->intr_in_enabled = 0;
- }
-
- fsg->running = 0;
- if (altsetting < 0 || rc != 0)
- return rc;
-
- DBG(fsg, "set interface %d\n", altsetting);
-
- /* Enable the endpoints */
- d = fsg_ep_desc(fsg->gadget,
- &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc,
- &fsg_ss_bulk_in_desc);
- if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0)
- goto reset;
- fsg->bulk_in_enabled = 1;
-
- d = fsg_ep_desc(fsg->gadget,
- &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc,
- &fsg_ss_bulk_out_desc);
- if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0)
- goto reset;
- fsg->bulk_out_enabled = 1;
- fsg->bulk_out_maxpacket = usb_endpoint_maxp(d);
- clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
-
- if (transport_is_cbi()) {
- d = fsg_ep_desc(fsg->gadget,
- &fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc,
- &fsg_ss_intr_in_desc);
- if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0)
- goto reset;
- fsg->intr_in_enabled = 1;
- }
-
- /* Allocate the requests */
- for (i = 0; i < fsg_num_buffers; ++i) {
- struct fsg_buffhd *bh = &fsg->buffhds[i];
-
- if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0)
- goto reset;
- if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0)
- goto reset;
- bh->inreq->buf = bh->outreq->buf = bh->buf;
- bh->inreq->context = bh->outreq->context = bh;
- bh->inreq->complete = bulk_in_complete;
- bh->outreq->complete = bulk_out_complete;
- }
- if (transport_is_cbi()) {
- if ((rc = alloc_request(fsg, fsg->intr_in, &fsg->intreq)) != 0)
- goto reset;
- fsg->intreq->complete = intr_in_complete;
- }
-
- fsg->running = 1;
- for (i = 0; i < fsg->nluns; ++i)
- fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED;
- return rc;
-}
-
-
-/*
- * Change our operational configuration. This code must agree with the code
- * that returns config descriptors, and with interface altsetting code.
- *
- * It's also responsible for power management interactions. Some
- * configurations might not work with our current power sources.
- * For now we just assume the gadget is always self-powered.
- */
-static int do_set_config(struct fsg_dev *fsg, u8 new_config)
-{
- int rc = 0;
-
- /* Disable the single interface */
- if (fsg->config != 0) {
- DBG(fsg, "reset config\n");
- fsg->config = 0;
- rc = do_set_interface(fsg, -1);
- }
-
- /* Enable the interface */
- if (new_config != 0) {
- fsg->config = new_config;
- if ((rc = do_set_interface(fsg, 0)) != 0)
- fsg->config = 0; // Reset on errors
- else
- INFO(fsg, "%s config #%d\n",
- usb_speed_string(fsg->gadget->speed),
- fsg->config);
- }
- return rc;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static void handle_exception(struct fsg_dev *fsg)
-{
- siginfo_t info;
- int sig;
- int i;
- int num_active;
- struct fsg_buffhd *bh;
- enum fsg_state old_state;
- u8 new_config;
- struct fsg_lun *curlun;
- unsigned int exception_req_tag;
- int rc;
-
- /* Clear the existing signals. Anything but SIGUSR1 is converted
- * into a high-priority EXIT exception. */
- for (;;) {
- sig = dequeue_signal_lock(current, &current->blocked, &info);
- if (!sig)
- break;
- if (sig != SIGUSR1) {
- if (fsg->state < FSG_STATE_EXIT)
- DBG(fsg, "Main thread exiting on signal\n");
- raise_exception(fsg, FSG_STATE_EXIT);
- }
- }
-
- /* Cancel all the pending transfers */
- if (fsg->intreq_busy)
- usb_ep_dequeue(fsg->intr_in, fsg->intreq);
- for (i = 0; i < fsg_num_buffers; ++i) {
- bh = &fsg->buffhds[i];
- if (bh->inreq_busy)
- usb_ep_dequeue(fsg->bulk_in, bh->inreq);
- if (bh->outreq_busy)
- usb_ep_dequeue(fsg->bulk_out, bh->outreq);
- }
-
- /* Wait until everything is idle */
- for (;;) {
- num_active = fsg->intreq_busy;
- for (i = 0; i < fsg_num_buffers; ++i) {
- bh = &fsg->buffhds[i];
- num_active += bh->inreq_busy + bh->outreq_busy;
- }
- if (num_active == 0)
- break;
- if (sleep_thread(fsg))
- return;
- }
-
- /* Clear out the controller's fifos */
- if (fsg->bulk_in_enabled)
- usb_ep_fifo_flush(fsg->bulk_in);
- if (fsg->bulk_out_enabled)
- usb_ep_fifo_flush(fsg->bulk_out);
- if (fsg->intr_in_enabled)
- usb_ep_fifo_flush(fsg->intr_in);
-
- /* Reset the I/O buffer states and pointers, the SCSI
- * state, and the exception. Then invoke the handler. */
- spin_lock_irq(&fsg->lock);
-
- for (i = 0; i < fsg_num_buffers; ++i) {
- bh = &fsg->buffhds[i];
- bh->state = BUF_STATE_EMPTY;
- }
- fsg->next_buffhd_to_fill = fsg->next_buffhd_to_drain =
- &fsg->buffhds[0];
-
- exception_req_tag = fsg->exception_req_tag;
- new_config = fsg->new_config;
- old_state = fsg->state;
-
- if (old_state == FSG_STATE_ABORT_BULK_OUT)
- fsg->state = FSG_STATE_STATUS_PHASE;
- else {
- for (i = 0; i < fsg->nluns; ++i) {
- curlun = &fsg->luns[i];
- curlun->prevent_medium_removal = 0;
- curlun->sense_data = curlun->unit_attention_data =
- SS_NO_SENSE;
- curlun->sense_data_info = 0;
- curlun->info_valid = 0;
- }
- fsg->state = FSG_STATE_IDLE;
- }
- spin_unlock_irq(&fsg->lock);
-
- /* Carry out any extra actions required for the exception */
- switch (old_state) {
- default:
- break;
-
- case FSG_STATE_ABORT_BULK_OUT:
- send_status(fsg);
- spin_lock_irq(&fsg->lock);
- if (fsg->state == FSG_STATE_STATUS_PHASE)
- fsg->state = FSG_STATE_IDLE;
- spin_unlock_irq(&fsg->lock);
- break;
-
- case FSG_STATE_RESET:
- /* In case we were forced against our will to halt a
- * bulk endpoint, clear the halt now. (The SuperH UDC
- * requires this.) */
- if (test_and_clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags))
- usb_ep_clear_halt(fsg->bulk_in);
-
- if (transport_is_bbb()) {
- if (fsg->ep0_req_tag == exception_req_tag)
- ep0_queue(fsg); // Complete the status stage
-
- } else if (transport_is_cbi())
- send_status(fsg); // Status by interrupt pipe
-
- /* Technically this should go here, but it would only be
- * a waste of time. Ditto for the INTERFACE_CHANGE and
- * CONFIG_CHANGE cases. */
- // for (i = 0; i < fsg->nluns; ++i)
- // fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED;
- break;
-
- case FSG_STATE_INTERFACE_CHANGE:
- rc = do_set_interface(fsg, 0);
- if (fsg->ep0_req_tag != exception_req_tag)
- break;
- if (rc != 0) // STALL on errors
- fsg_set_halt(fsg, fsg->ep0);
- else // Complete the status stage
- ep0_queue(fsg);
- break;
-
- case FSG_STATE_CONFIG_CHANGE:
- rc = do_set_config(fsg, new_config);
- if (fsg->ep0_req_tag != exception_req_tag)
- break;
- if (rc != 0) // STALL on errors
- fsg_set_halt(fsg, fsg->ep0);
- else // Complete the status stage
- ep0_queue(fsg);
- break;
-
- case FSG_STATE_DISCONNECT:
- for (i = 0; i < fsg->nluns; ++i)
- fsg_lun_fsync_sub(fsg->luns + i);
- do_set_config(fsg, 0); // Unconfigured state
- break;
-
- case FSG_STATE_EXIT:
- case FSG_STATE_TERMINATED:
- do_set_config(fsg, 0); // Free resources
- spin_lock_irq(&fsg->lock);
- fsg->state = FSG_STATE_TERMINATED; // Stop the thread
- spin_unlock_irq(&fsg->lock);
- break;
- }
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static int fsg_main_thread(void *fsg_)
-{
- struct fsg_dev *fsg = fsg_;
-
- /* Allow the thread to be killed by a signal, but set the signal mask
- * to block everything but INT, TERM, KILL, and USR1. */
- allow_signal(SIGINT);
- allow_signal(SIGTERM);
- allow_signal(SIGKILL);
- allow_signal(SIGUSR1);
-
- /* Allow the thread to be frozen */
- set_freezable();
-
- /* Arrange for userspace references to be interpreted as kernel
- * pointers. That way we can pass a kernel pointer to a routine
- * that expects a __user pointer and it will work okay. */
- set_fs(get_ds());
-
- /* The main loop */
- while (fsg->state != FSG_STATE_TERMINATED) {
- if (exception_in_progress(fsg) || signal_pending(current)) {
- handle_exception(fsg);
- continue;
- }
-
- if (!fsg->running) {
- sleep_thread(fsg);
- continue;
- }
-
- if (get_next_command(fsg))
- continue;
-
- spin_lock_irq(&fsg->lock);
- if (!exception_in_progress(fsg))
- fsg->state = FSG_STATE_DATA_PHASE;
- spin_unlock_irq(&fsg->lock);
-
- if (do_scsi_command(fsg) || finish_reply(fsg))
- continue;
-
- spin_lock_irq(&fsg->lock);
- if (!exception_in_progress(fsg))
- fsg->state = FSG_STATE_STATUS_PHASE;
- spin_unlock_irq(&fsg->lock);
-
- if (send_status(fsg))
- continue;
-
- spin_lock_irq(&fsg->lock);
- if (!exception_in_progress(fsg))
- fsg->state = FSG_STATE_IDLE;
- spin_unlock_irq(&fsg->lock);
- }
-
- spin_lock_irq(&fsg->lock);
- fsg->thread_task = NULL;
- spin_unlock_irq(&fsg->lock);
-
- /* If we are exiting because of a signal, unregister the
- * gadget driver. */
- if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags))
- usb_gadget_unregister_driver(&fsg_driver);
-
- /* Let the unbind and cleanup routines know the thread has exited */
- complete_and_exit(&fsg->thread_notifier, 0);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-
-/* The write permissions and store_xxx pointers are set in fsg_bind() */
-static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL);
-static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, NULL);
-static DEVICE_ATTR(file, 0444, fsg_show_file, NULL);
-
-
-/*-------------------------------------------------------------------------*/
-
-static void fsg_release(struct kref *ref)
-{
- struct fsg_dev *fsg = container_of(ref, struct fsg_dev, ref);
-
- kfree(fsg->luns);
- kfree(fsg);
-}
-
-static void lun_release(struct device *dev)
-{
- struct rw_semaphore *filesem = dev_get_drvdata(dev);
- struct fsg_dev *fsg =
- container_of(filesem, struct fsg_dev, filesem);
-
- kref_put(&fsg->ref, fsg_release);
-}
-
-static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
-{
- struct fsg_dev *fsg = get_gadget_data(gadget);
- int i;
- struct fsg_lun *curlun;
- struct usb_request *req = fsg->ep0req;
-
- DBG(fsg, "unbind\n");
- clear_bit(REGISTERED, &fsg->atomic_bitflags);
-
- /* If the thread isn't already dead, tell it to exit now */
- if (fsg->state != FSG_STATE_TERMINATED) {
- raise_exception(fsg, FSG_STATE_EXIT);
- wait_for_completion(&fsg->thread_notifier);
-
- /* The cleanup routine waits for this completion also */
- complete(&fsg->thread_notifier);
- }
-
- /* Unregister the sysfs attribute files and the LUNs */
- for (i = 0; i < fsg->nluns; ++i) {
- curlun = &fsg->luns[i];
- if (curlun->registered) {
- device_remove_file(&curlun->dev, &dev_attr_nofua);
- device_remove_file(&curlun->dev, &dev_attr_ro);
- device_remove_file(&curlun->dev, &dev_attr_file);
- fsg_lun_close(curlun);
- device_unregister(&curlun->dev);
- curlun->registered = 0;
- }
- }
-
- /* Free the data buffers */
- for (i = 0; i < fsg_num_buffers; ++i)
- kfree(fsg->buffhds[i].buf);
-
- /* Free the request and buffer for endpoint 0 */
- if (req) {
- kfree(req->buf);
- usb_ep_free_request(fsg->ep0, req);
- }
-
- set_gadget_data(gadget, NULL);
-}
-
-
-static int __init check_parameters(struct fsg_dev *fsg)
-{
- int prot;
-
- /* Store the default values */
- mod_data.transport_type = USB_PR_BULK;
- mod_data.transport_name = "Bulk-only";
- mod_data.protocol_type = USB_SC_SCSI;
- mod_data.protocol_name = "Transparent SCSI";
-
- /* Some peripheral controllers are known not to be able to
- * halt bulk endpoints correctly. If one of them is present,
- * disable stalls.
- */
- if (gadget_is_at91(fsg->gadget))
- mod_data.can_stall = 0;
-
- if (mod_data.release == 0xffff)
- mod_data.release = get_default_bcdDevice();
-
- prot = simple_strtol(mod_data.protocol_parm, NULL, 0);
-
-#ifdef CONFIG_USB_FILE_STORAGE_TEST
- if (strnicmp(mod_data.transport_parm, "BBB", 10) == 0) {
- ; // Use default setting
- } else if (strnicmp(mod_data.transport_parm, "CB", 10) == 0) {
- mod_data.transport_type = USB_PR_CB;
- mod_data.transport_name = "Control-Bulk";
- } else if (strnicmp(mod_data.transport_parm, "CBI", 10) == 0) {
- mod_data.transport_type = USB_PR_CBI;
- mod_data.transport_name = "Control-Bulk-Interrupt";
- } else {
- ERROR(fsg, "invalid transport: %s\n", mod_data.transport_parm);
- return -EINVAL;
- }
-
- if (strnicmp(mod_data.protocol_parm, "SCSI", 10) == 0 ||
- prot == USB_SC_SCSI) {
- ; // Use default setting
- } else if (strnicmp(mod_data.protocol_parm, "RBC", 10) == 0 ||
- prot == USB_SC_RBC) {
- mod_data.protocol_type = USB_SC_RBC;
- mod_data.protocol_name = "RBC";
- } else if (strnicmp(mod_data.protocol_parm, "8020", 4) == 0 ||
- strnicmp(mod_data.protocol_parm, "ATAPI", 10) == 0 ||
- prot == USB_SC_8020) {
- mod_data.protocol_type = USB_SC_8020;
- mod_data.protocol_name = "8020i (ATAPI)";
- } else if (strnicmp(mod_data.protocol_parm, "QIC", 3) == 0 ||
- prot == USB_SC_QIC) {
- mod_data.protocol_type = USB_SC_QIC;
- mod_data.protocol_name = "QIC-157";
- } else if (strnicmp(mod_data.protocol_parm, "UFI", 10) == 0 ||
- prot == USB_SC_UFI) {
- mod_data.protocol_type = USB_SC_UFI;
- mod_data.protocol_name = "UFI";
- } else if (strnicmp(mod_data.protocol_parm, "8070", 4) == 0 ||
- prot == USB_SC_8070) {
- mod_data.protocol_type = USB_SC_8070;
- mod_data.protocol_name = "8070i";
- } else {
- ERROR(fsg, "invalid protocol: %s\n", mod_data.protocol_parm);
- return -EINVAL;
- }
-
- mod_data.buflen &= PAGE_CACHE_MASK;
- if (mod_data.buflen <= 0) {
- ERROR(fsg, "invalid buflen\n");
- return -ETOOSMALL;
- }
-
-#endif /* CONFIG_USB_FILE_STORAGE_TEST */
-
- /* Serial string handling.
- * On a real device, the serial string would be loaded
- * from permanent storage. */
- if (mod_data.serial) {
- const char *ch;
- unsigned len = 0;
-
- /* Sanity check :
- * The CB[I] specification limits the serial string to
- * 12 uppercase hexadecimal characters.
- * BBB need at least 12 uppercase hexadecimal characters,
- * with a maximum of 126. */
- for (ch = mod_data.serial; *ch; ++ch) {
- ++len;
- if ((*ch < '0' || *ch > '9') &&
- (*ch < 'A' || *ch > 'F')) { /* not uppercase hex */
- WARNING(fsg,
- "Invalid serial string character: %c\n",
- *ch);
- goto no_serial;
- }
- }
- if (len > 126 ||
- (mod_data.transport_type == USB_PR_BULK && len < 12) ||
- (mod_data.transport_type != USB_PR_BULK && len > 12)) {
- WARNING(fsg, "Invalid serial string length!\n");
- goto no_serial;
- }
- fsg_strings[FSG_STRING_SERIAL - 1].s = mod_data.serial;
- } else {
- WARNING(fsg, "No serial-number string provided!\n");
- no_serial:
- device_desc.iSerialNumber = 0;
- }
-
- return 0;
-}
-
-
-static int __init fsg_bind(struct usb_gadget *gadget,
- struct usb_gadget_driver *driver)
-{
- struct fsg_dev *fsg = the_fsg;
- int rc;
- int i;
- struct fsg_lun *curlun;
- struct usb_ep *ep;
- struct usb_request *req;
- char *pathbuf, *p;
-
- fsg->gadget = gadget;
- set_gadget_data(gadget, fsg);
- fsg->ep0 = gadget->ep0;
- fsg->ep0->driver_data = fsg;
-
- if ((rc = check_parameters(fsg)) != 0)
- goto out;
-
- if (mod_data.removable) { // Enable the store_xxx attributes
- dev_attr_file.attr.mode = 0644;
- dev_attr_file.store = fsg_store_file;
- if (!mod_data.cdrom) {
- dev_attr_ro.attr.mode = 0644;
- dev_attr_ro.store = fsg_store_ro;
- }
- }
-
- /* Only for removable media? */
- dev_attr_nofua.attr.mode = 0644;
- dev_attr_nofua.store = fsg_store_nofua;
-
- /* Find out how many LUNs there should be */
- i = mod_data.nluns;
- if (i == 0)
- i = max(mod_data.num_filenames, 1u);
- if (i > FSG_MAX_LUNS) {
- ERROR(fsg, "invalid number of LUNs: %d\n", i);
- rc = -EINVAL;
- goto out;
- }
-
- /* Create the LUNs, open their backing files, and register the
- * LUN devices in sysfs. */
- fsg->luns = kzalloc(i * sizeof(struct fsg_lun), GFP_KERNEL);
- if (!fsg->luns) {
- rc = -ENOMEM;
- goto out;
- }
- fsg->nluns = i;
-
- for (i = 0; i < fsg->nluns; ++i) {
- curlun = &fsg->luns[i];
- curlun->cdrom = !!mod_data.cdrom;
- curlun->ro = mod_data.cdrom || mod_data.ro[i];
- curlun->initially_ro = curlun->ro;
- curlun->removable = mod_data.removable;
- curlun->nofua = mod_data.nofua[i];
- curlun->dev.release = lun_release;
- curlun->dev.parent = &gadget->dev;
- curlun->dev.driver = &fsg_driver.driver;
- dev_set_drvdata(&curlun->dev, &fsg->filesem);
- dev_set_name(&curlun->dev,"%s-lun%d",
- dev_name(&gadget->dev), i);
-
- kref_get(&fsg->ref);
- rc = device_register(&curlun->dev);
- if (rc) {
- INFO(fsg, "failed to register LUN%d: %d\n", i, rc);
- put_device(&curlun->dev);
- goto out;
- }
- curlun->registered = 1;
-
- rc = device_create_file(&curlun->dev, &dev_attr_ro);
- if (rc)
- goto out;
- rc = device_create_file(&curlun->dev, &dev_attr_nofua);
- if (rc)
- goto out;
- rc = device_create_file(&curlun->dev, &dev_attr_file);
- if (rc)
- goto out;
-
- if (mod_data.file[i] && *mod_data.file[i]) {
- rc = fsg_lun_open(curlun, mod_data.file[i]);
- if (rc)
- goto out;
- } else if (!mod_data.removable) {
- ERROR(fsg, "no file given for LUN%d\n", i);
- rc = -EINVAL;
- goto out;
- }
- }
-
- /* Find all the endpoints we will use */
- usb_ep_autoconfig_reset(gadget);
- ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
- if (!ep)
- goto autoconf_fail;
- ep->driver_data = fsg; // claim the endpoint
- fsg->bulk_in = ep;
-
- ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc);
- if (!ep)
- goto autoconf_fail;
- ep->driver_data = fsg; // claim the endpoint
- fsg->bulk_out = ep;
-
- if (transport_is_cbi()) {
- ep = usb_ep_autoconfig(gadget, &fsg_fs_intr_in_desc);
- if (!ep)
- goto autoconf_fail;
- ep->driver_data = fsg; // claim the endpoint
- fsg->intr_in = ep;
- }
-
- /* Fix up the descriptors */
- device_desc.idVendor = cpu_to_le16(mod_data.vendor);
- device_desc.idProduct = cpu_to_le16(mod_data.product);
- device_desc.bcdDevice = cpu_to_le16(mod_data.release);
-
- i = (transport_is_cbi() ? 3 : 2); // Number of endpoints
- fsg_intf_desc.bNumEndpoints = i;
- fsg_intf_desc.bInterfaceSubClass = mod_data.protocol_type;
- fsg_intf_desc.bInterfaceProtocol = mod_data.transport_type;
- fsg_fs_function[i + FSG_FS_FUNCTION_PRE_EP_ENTRIES] = NULL;
-
- if (gadget_is_dualspeed(gadget)) {
- fsg_hs_function[i + FSG_HS_FUNCTION_PRE_EP_ENTRIES] = NULL;
-
- /* Assume endpoint addresses are the same for both speeds */
- fsg_hs_bulk_in_desc.bEndpointAddress =
- fsg_fs_bulk_in_desc.bEndpointAddress;
- fsg_hs_bulk_out_desc.bEndpointAddress =
- fsg_fs_bulk_out_desc.bEndpointAddress;
- fsg_hs_intr_in_desc.bEndpointAddress =
- fsg_fs_intr_in_desc.bEndpointAddress;
- }
-
- if (gadget_is_superspeed(gadget)) {
- unsigned max_burst;
-
- fsg_ss_function[i + FSG_SS_FUNCTION_PRE_EP_ENTRIES] = NULL;
-
- /* Calculate bMaxBurst, we know packet size is 1024 */
- max_burst = min_t(unsigned, mod_data.buflen / 1024, 15);
-
- /* Assume endpoint addresses are the same for both speeds */
- fsg_ss_bulk_in_desc.bEndpointAddress =
- fsg_fs_bulk_in_desc.bEndpointAddress;
- fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
-
- fsg_ss_bulk_out_desc.bEndpointAddress =
- fsg_fs_bulk_out_desc.bEndpointAddress;
- fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
- }
-
- if (gadget_is_otg(gadget))
- fsg_otg_desc.bmAttributes |= USB_OTG_HNP;
-
- rc = -ENOMEM;
-
- /* Allocate the request and buffer for endpoint 0 */
- fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL);
- if (!req)
- goto out;
- req->buf = kmalloc(EP0_BUFSIZE, GFP_KERNEL);
- if (!req->buf)
- goto out;
- req->complete = ep0_complete;
-
- /* Allocate the data buffers */
- for (i = 0; i < fsg_num_buffers; ++i) {
- struct fsg_buffhd *bh = &fsg->buffhds[i];
-
- /* Allocate for the bulk-in endpoint. We assume that
- * the buffer will also work with the bulk-out (and
- * interrupt-in) endpoint. */
- bh->buf = kmalloc(mod_data.buflen, GFP_KERNEL);
- if (!bh->buf)
- goto out;
- bh->next = bh + 1;
- }
- fsg->buffhds[fsg_num_buffers - 1].next = &fsg->buffhds[0];
-
- /* This should reflect the actual gadget power source */
- usb_gadget_set_selfpowered(gadget);
-
- snprintf(fsg_string_manufacturer, sizeof fsg_string_manufacturer,
- "%s %s with %s",
- init_utsname()->sysname, init_utsname()->release,
- gadget->name);
-
- fsg->thread_task = kthread_create(fsg_main_thread, fsg,
- "file-storage-gadget");
- if (IS_ERR(fsg->thread_task)) {
- rc = PTR_ERR(fsg->thread_task);
- goto out;
- }
-
- INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
- INFO(fsg, "NOTE: This driver is deprecated. "
- "Consider using g_mass_storage instead.\n");
- INFO(fsg, "Number of LUNs=%d\n", fsg->nluns);
-
- pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
- for (i = 0; i < fsg->nluns; ++i) {
- curlun = &fsg->luns[i];
- if (fsg_lun_is_open(curlun)) {
- p = NULL;
- if (pathbuf) {
- p = d_path(&curlun->filp->f_path,
- pathbuf, PATH_MAX);
- if (IS_ERR(p))
- p = NULL;
- }
- LINFO(curlun, "ro=%d, nofua=%d, file: %s\n",
- curlun->ro, curlun->nofua, (p ? p : "(error)"));
- }
- }
- kfree(pathbuf);
-
- DBG(fsg, "transport=%s (x%02x)\n",
- mod_data.transport_name, mod_data.transport_type);
- DBG(fsg, "protocol=%s (x%02x)\n",
- mod_data.protocol_name, mod_data.protocol_type);
- DBG(fsg, "VendorID=x%04x, ProductID=x%04x, Release=x%04x\n",
- mod_data.vendor, mod_data.product, mod_data.release);
- DBG(fsg, "removable=%d, stall=%d, cdrom=%d, buflen=%u\n",
- mod_data.removable, mod_data.can_stall,
- mod_data.cdrom, mod_data.buflen);
- DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task));
-
- set_bit(REGISTERED, &fsg->atomic_bitflags);
-
- /* Tell the thread to start working */
- wake_up_process(fsg->thread_task);
- return 0;
-
-autoconf_fail:
- ERROR(fsg, "unable to autoconfigure all endpoints\n");
- rc = -ENOTSUPP;
-
-out:
- fsg->state = FSG_STATE_TERMINATED; // The thread is dead
- fsg_unbind(gadget);
- complete(&fsg->thread_notifier);
- return rc;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static void fsg_suspend(struct usb_gadget *gadget)
-{
- struct fsg_dev *fsg = get_gadget_data(gadget);
-
- DBG(fsg, "suspend\n");
- set_bit(SUSPENDED, &fsg->atomic_bitflags);
-}
-
-static void fsg_resume(struct usb_gadget *gadget)
-{
- struct fsg_dev *fsg = get_gadget_data(gadget);
-
- DBG(fsg, "resume\n");
- clear_bit(SUSPENDED, &fsg->atomic_bitflags);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static __refdata struct usb_gadget_driver fsg_driver = {
- .max_speed = USB_SPEED_SUPER,
- .function = (char *) fsg_string_product,
- .bind = fsg_bind,
- .unbind = fsg_unbind,
- .disconnect = fsg_disconnect,
- .setup = fsg_setup,
- .suspend = fsg_suspend,
- .resume = fsg_resume,
-
- .driver = {
- .name = DRIVER_NAME,
- .owner = THIS_MODULE,
- // .release = ...
- // .suspend = ...
- // .resume = ...
- },
-};
-
-
-static int __init fsg_alloc(void)
-{
- struct fsg_dev *fsg;
-
- fsg = kzalloc(sizeof *fsg +
- fsg_num_buffers * sizeof *(fsg->buffhds), GFP_KERNEL);
-
- if (!fsg)
- return -ENOMEM;
- spin_lock_init(&fsg->lock);
- init_rwsem(&fsg->filesem);
- kref_init(&fsg->ref);
- init_completion(&fsg->thread_notifier);
-
- the_fsg = fsg;
- return 0;
-}
-
-
-static int __init fsg_init(void)
-{
- int rc;
- struct fsg_dev *fsg;
-
- rc = fsg_num_buffers_validate();
- if (rc != 0)
- return rc;
-
- if ((rc = fsg_alloc()) != 0)
- return rc;
- fsg = the_fsg;
- rc = usb_gadget_probe_driver(&fsg_driver);
- if (rc != 0)
- kref_put(&fsg->ref, fsg_release);
- return rc;
-}
-module_init(fsg_init);
-
-
-static void __exit fsg_cleanup(void)
-{
- struct fsg_dev *fsg = the_fsg;
-
- /* Unregister the driver iff the thread hasn't already done so */
- if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags))
- usb_gadget_unregister_driver(&fsg_driver);
-
- /* Wait for the thread to finish up */
- wait_for_completion(&fsg->thread_notifier);
-
- kref_put(&fsg->ref, fsg_release);
-}
-module_exit(fsg_cleanup);
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c
index b09452d6f33..ec50f18c889 100644
--- a/drivers/usb/gadget/fsl_qe_udc.c
+++ b/drivers/usb/gadget/fsl_qe_udc.c
@@ -2347,7 +2347,7 @@ static int fsl_qe_stop(struct usb_gadget *gadget,
}
/* udc structure's alloc and setup, include ep-param alloc */
-static struct qe_udc __devinit *qe_udc_config(struct platform_device *ofdev)
+static struct qe_udc *qe_udc_config(struct platform_device *ofdev)
{
struct qe_udc *udc;
struct device_node *np = ofdev->dev.of_node;
@@ -2402,7 +2402,7 @@ cleanup:
}
/* USB Controller register init */
-static int __devinit qe_udc_reg_init(struct qe_udc *udc)
+static int qe_udc_reg_init(struct qe_udc *udc)
{
struct usb_ctlr __iomem *qe_usbregs;
qe_usbregs = udc->usb_regs;
@@ -2420,7 +2420,7 @@ static int __devinit qe_udc_reg_init(struct qe_udc *udc)
return 0;
}
-static int __devinit qe_ep_config(struct qe_udc *udc, unsigned char pipe_num)
+static int qe_ep_config(struct qe_udc *udc, unsigned char pipe_num)
{
struct qe_ep *ep = &udc->eps[pipe_num];
@@ -2473,7 +2473,7 @@ static void qe_udc_release(struct device *dev)
/* Driver probe functions */
static const struct of_device_id qe_udc_match[];
-static int __devinit qe_udc_probe(struct platform_device *ofdev)
+static int qe_udc_probe(struct platform_device *ofdev)
{
struct qe_udc *udc;
const struct of_device_id *match;
@@ -2651,7 +2651,7 @@ static int qe_udc_resume(struct platform_device *dev)
}
#endif
-static int __devexit qe_udc_remove(struct platform_device *ofdev)
+static int qe_udc_remove(struct platform_device *ofdev)
{
struct qe_udc *udc = dev_get_drvdata(&ofdev->dev);
struct qe_ep *ep;
@@ -2710,7 +2710,7 @@ static int __devexit qe_udc_remove(struct platform_device *ofdev)
}
/*-------------------------------------------------------------------------*/
-static const struct of_device_id qe_udc_match[] __devinitconst = {
+static const struct of_device_id qe_udc_match[] = {
{
.compatible = "fsl,mpc8323-qe-usb",
.data = (void *)PORT_QE,
@@ -2735,7 +2735,7 @@ static struct platform_driver udc_driver = {
.of_match_table = qe_udc_match,
},
.probe = qe_udc_probe,
- .remove = __devexit_p(qe_udc_remove),
+ .remove = qe_udc_remove,
#ifdef CONFIG_PM
.suspend = qe_udc_suspend,
.resume = qe_udc_resume,
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 6ae70cba0c4..c19f7f13790 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -2126,7 +2126,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
tmp_reg = fsl_readl(&dr_regs->usbintr);
t = scnprintf(next, size,
- "USB Intrrupt Enable Reg:\n"
+ "USB Interrupt Enable Reg:\n"
"Sleep Enable: %d SOF Received Enable: %d "
"Reset Enable: %d\n"
"System Error Enable: %d "
diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c
index 74130f6c12c..c36260ea8bf 100644
--- a/drivers/usb/gadget/hid.c
+++ b/drivers/usb/gadget/hid.c
@@ -203,7 +203,7 @@ static int __init hidg_plat_driver_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit hidg_plat_driver_remove(struct platform_device *pdev)
+static int hidg_plat_driver_remove(struct platform_device *pdev)
{
struct hidg_func_node *e, *n;
@@ -229,7 +229,7 @@ static __refdata struct usb_composite_driver hidg_driver = {
};
static struct platform_driver hidg_plat_driver = {
- .remove = __devexit_p(hidg_plat_driver_remove),
+ .remove = hidg_plat_driver_remove,
.driver = {
.owner = THIS_MODULE,
.name = "hidg",
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 76494cabf4e..8ac840f25ba 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -76,7 +76,6 @@ MODULE_LICENSE ("GPL");
/*----------------------------------------------------------------------*/
#define GADGETFS_MAGIC 0xaee71ee7
-#define DMA_ADDR_INVALID (~(dma_addr_t)0)
/* /dev/gadget/$CHIP represents ep0 and the whole device */
enum ep0_state {
@@ -918,7 +917,6 @@ static void clean_req (struct usb_ep *ep, struct usb_request *req)
if (req->buf != dev->rbuf) {
kfree(req->buf);
req->buf = dev->rbuf;
- req->dma = DMA_ADDR_INVALID;
}
req->complete = epio_complete;
dev->setup_out_ready = 0;
@@ -1408,7 +1406,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
dev->setup_abort = 1;
req->buf = dev->rbuf;
- req->dma = DMA_ADDR_INVALID;
req->context = NULL;
value = -EOPNOTSUPP;
switch (ctrl->bRequest) {
diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c
index 21a9861dabf..dd1c9b1fe52 100644
--- a/drivers/usb/gadget/lpc32xx_udc.c
+++ b/drivers/usb/gadget/lpc32xx_udc.c
@@ -2399,7 +2399,7 @@ static void udc_handle_ep0_setup(struct lpc32xx_udc *udc)
if (i < 0) {
/* setup processing failed, force stall */
- dev_err(udc->dev,
+ dev_dbg(udc->dev,
"req %02x.%02x protocol STALL; stat %d\n",
reqtype, req, i);
udc->ep0state = WAIT_FOR_SETUP;
@@ -3352,7 +3352,7 @@ phy_fail:
return retval;
}
-static int __devexit lpc32xx_udc_remove(struct platform_device *pdev)
+static int lpc32xx_udc_remove(struct platform_device *pdev)
{
struct lpc32xx_udc *udc = platform_get_drvdata(pdev);
@@ -3447,7 +3447,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_udc_of_match);
#endif
static struct platform_driver lpc32xx_udc_driver = {
- .remove = __devexit_p(lpc32xx_udc_remove),
+ .remove = lpc32xx_udc_remove,
.shutdown = lpc32xx_udc_shutdown,
.suspend = lpc32xx_udc_suspend,
.resume = lpc32xx_udc_resume,
diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c
index 8cfd5b028db..b5cea273c95 100644
--- a/drivers/usb/gadget/mv_u3d_core.c
+++ b/drivers/usb/gadget/mv_u3d_core.c
@@ -1763,7 +1763,7 @@ static void mv_u3d_gadget_release(struct device *dev)
dev_dbg(dev, "%s\n", __func__);
}
-static __devexit int mv_u3d_remove(struct platform_device *dev)
+static int mv_u3d_remove(struct platform_device *dev)
{
struct mv_u3d *u3d = platform_get_drvdata(dev);
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c
index ea45224f78c..379aac7b82f 100644
--- a/drivers/usb/gadget/mv_udc_core.c
+++ b/drivers/usb/gadget/mv_udc_core.c
@@ -2128,7 +2128,7 @@ static void gadget_release(struct device *_dev)
complete(udc->done);
}
-static int __devexit mv_udc_remove(struct platform_device *dev)
+static int mv_udc_remove(struct platform_device *dev)
{
struct mv_udc *udc = the_controller;
int clk_i;
@@ -2188,7 +2188,7 @@ static int __devexit mv_udc_remove(struct platform_device *dev)
return 0;
}
-static int __devinit mv_udc_probe(struct platform_device *dev)
+static int mv_udc_probe(struct platform_device *dev)
{
struct mv_usb_platform_data *pdata = dev->dev.platform_data;
struct mv_udc *udc;
diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c
index c009263a47e..d226058e3b8 100644
--- a/drivers/usb/gadget/net2272.c
+++ b/drivers/usb/gadget/net2272.c
@@ -2193,7 +2193,7 @@ net2272_gadget_release(struct device *_dev)
/*---------------------------------------------------------------------------*/
-static void __devexit
+static void
net2272_remove(struct net2272 *dev)
{
usb_del_gadget_udc(&dev->gadget);
@@ -2215,8 +2215,7 @@ net2272_remove(struct net2272 *dev)
dev_info(dev->dev, "unbind\n");
}
-static struct net2272 * __devinit
-net2272_probe_init(struct device *dev, unsigned int irq)
+static struct net2272 *net2272_probe_init(struct device *dev, unsigned int irq)
{
struct net2272 *ret;
@@ -2246,7 +2245,7 @@ net2272_probe_init(struct device *dev, unsigned int irq)
return ret;
}
-static int __devinit
+static int
net2272_probe_fin(struct net2272 *dev, unsigned int irqflags)
{
int ret;
@@ -2306,7 +2305,7 @@ err_add_udc:
* don't respond over USB until a gadget driver binds to us
*/
-static int __devinit
+static int
net2272_rdk1_probe(struct pci_dev *pdev, struct net2272 *dev)
{
unsigned long resource, len, tmp;
@@ -2389,7 +2388,7 @@ net2272_rdk1_probe(struct pci_dev *pdev, struct net2272 *dev)
return ret;
}
-static int __devinit
+static int
net2272_rdk2_probe(struct pci_dev *pdev, struct net2272 *dev)
{
unsigned long resource, len;
@@ -2447,7 +2446,7 @@ net2272_rdk2_probe(struct pci_dev *pdev, struct net2272 *dev)
return ret;
}
-static int __devinit
+static int
net2272_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct net2272 *dev;
@@ -2489,7 +2488,7 @@ net2272_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return ret;
}
-static void __devexit
+static void
net2272_rdk1_remove(struct pci_dev *pdev, struct net2272 *dev)
{
int i;
@@ -2511,7 +2510,7 @@ net2272_rdk1_remove(struct pci_dev *pdev, struct net2272 *dev)
}
}
-static void __devexit
+static void
net2272_rdk2_remove(struct pci_dev *pdev, struct net2272 *dev)
{
int i;
@@ -2530,7 +2529,7 @@ net2272_rdk2_remove(struct pci_dev *pdev, struct net2272 *dev)
pci_resource_len(pdev, i));
}
-static void __devexit
+static void
net2272_pci_remove(struct pci_dev *pdev)
{
struct net2272 *dev = pci_get_drvdata(pdev);
@@ -2549,7 +2548,7 @@ net2272_pci_remove(struct pci_dev *pdev)
}
/* Table of matching PCI IDs */
-static struct pci_device_id __devinitdata pci_ids[] = {
+static struct pci_device_id pci_ids[] = {
{ /* RDK 1 card */
.class = ((PCI_CLASS_BRIDGE_OTHER << 8) | 0xfe),
.class_mask = 0,
@@ -2575,7 +2574,7 @@ static struct pci_driver net2272_pci_driver = {
.id_table = pci_ids,
.probe = net2272_pci_probe,
- .remove = __devexit_p(net2272_pci_remove),
+ .remove = net2272_pci_remove,
};
static int net2272_pci_register(void)
@@ -2595,7 +2594,7 @@ static inline void net2272_pci_unregister(void) { }
/*---------------------------------------------------------------------------*/
-static int __devinit
+static int
net2272_plat_probe(struct platform_device *pdev)
{
struct net2272 *dev;
@@ -2661,7 +2660,7 @@ net2272_plat_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit
+static int
net2272_plat_remove(struct platform_device *pdev)
{
struct net2272 *dev = platform_get_drvdata(pdev);
@@ -2678,7 +2677,7 @@ net2272_plat_remove(struct platform_device *pdev)
static struct platform_driver net2272_plat_driver = {
.probe = net2272_plat_probe,
- .remove = __devexit_p(net2272_plat_remove),
+ .remove = net2272_plat_remove,
.driver = {
.name = driver_name,
.owner = THIS_MODULE,
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index ac335af154b..708c0b55dcc 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -9,7 +9,7 @@
* CODE STATUS HIGHLIGHTS
*
* This driver should work well with most "gadget" drivers, including
- * the File Storage, Serial, and Ethernet/RNDIS gadget drivers
+ * the Mass Storage, Serial, and Ethernet/RNDIS gadget drivers
* as well as Gadget Zero and Gadgetfs.
*
* DMA is enabled by default. Drivers using transfer queues might use
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 2a4749c3eb3..9412bf53b86 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -2506,7 +2506,7 @@ static inline void remove_proc_file(void) {}
* UDC_SYSCON_1.CFG_LOCK is set can now work. We won't use that
* capability yet though.
*/
-static unsigned __devinit
+static unsigned
omap_ep_setup(char *name, u8 addr, u8 type,
unsigned buf, unsigned maxp, int dbuf)
{
@@ -2624,7 +2624,7 @@ static void omap_udc_release(struct device *dev)
udc = NULL;
}
-static int __devinit
+static int
omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv)
{
unsigned tmp, buf;
@@ -2761,7 +2761,7 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv)
return 0;
}
-static int __devinit omap_udc_probe(struct platform_device *pdev)
+static int omap_udc_probe(struct platform_device *pdev)
{
int status = -ENODEV;
int hmc;
@@ -2974,7 +2974,7 @@ cleanup0:
return status;
}
-static int __devexit omap_udc_remove(struct platform_device *pdev)
+static int omap_udc_remove(struct platform_device *pdev)
{
DECLARE_COMPLETION_ONSTACK(done);
@@ -3060,7 +3060,7 @@ static int omap_udc_resume(struct platform_device *dev)
static struct platform_driver udc_driver = {
.probe = omap_udc_probe,
- .remove = __devexit_p(omap_udc_remove),
+ .remove = omap_udc_remove,
.suspend = omap_udc_suspend,
.resume = omap_udc_resume,
.driver = {
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index e156e3f2672..35bcc83d1e0 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -983,8 +983,10 @@ static int __init printer_func_bind(struct usb_configuration *c,
{
struct printer_dev *dev = container_of(f, struct printer_dev, function);
struct usb_composite_dev *cdev = c->cdev;
- struct usb_ep *in_ep, *out_ep;
+ struct usb_ep *in_ep;
+ struct usb_ep *out_ep = NULL;
int id;
+ int ret;
id = usb_interface_id(c, f);
if (id < 0)
@@ -1010,6 +1012,11 @@ autoconf_fail:
hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress;
+ ret = usb_assign_descriptors(f, fs_printer_function,
+ hs_printer_function, NULL);
+ if (ret)
+ return ret;
+
dev->in_ep = in_ep;
dev->out_ep = out_ep;
return 0;
@@ -1018,6 +1025,7 @@ autoconf_fail:
static void printer_func_unbind(struct usb_configuration *c,
struct usb_function *f)
{
+ usb_free_all_descriptors(f);
}
static int printer_func_set_alt(struct usb_function *f,
@@ -1110,8 +1118,6 @@ static int __init printer_bind_config(struct usb_configuration *c)
dev = &usb_printer_gadget;
dev->function.name = shortname;
- dev->function.descriptors = fs_printer_function;
- dev->function.hs_descriptors = hs_printer_function;
dev->function.bind = printer_func_bind;
dev->function.setup = printer_func_setup;
dev->function.unbind = printer_func_unbind;
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h
index a1d268c6f2c..79d81a4b234 100644
--- a/drivers/usb/gadget/pxa27x_udc.h
+++ b/drivers/usb/gadget/pxa27x_udc.h
@@ -418,7 +418,7 @@ struct udc_stats {
* @irq: udc irq
* @clk: udc clock
* @usb_gadget: udc gadget structure
- * @driver: bound gadget (zero, g_ether, g_file_storage, ...)
+ * @driver: bound gadget (zero, g_ether, g_mass_storage, ...)
* @dev: device
* @mach: machine info, used to activate specific GPIO
* @transceiver: external transceiver to handle vbus sense and D+ pullup
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 6f696ee8b81..141971d9051 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -3072,7 +3072,7 @@ static struct usb_gadget_ops s3c_hsotg_gadget_ops = {
* creation) to give to the gadget driver. Setup the endpoint name, any
* direction information and other state that may be required.
*/
-static void __devinit s3c_hsotg_initep(struct s3c_hsotg *hsotg,
+static void s3c_hsotg_initep(struct s3c_hsotg *hsotg,
struct s3c_hsotg_ep *hs_ep,
int epnum)
{
@@ -3414,7 +3414,7 @@ static const struct file_operations ep_fops = {
* with the same name as the device itself, in case we end up
* with multiple blocks in future systems.
*/
-static void __devinit s3c_hsotg_create_debug(struct s3c_hsotg *hsotg)
+static void s3c_hsotg_create_debug(struct s3c_hsotg *hsotg)
{
struct dentry *root;
unsigned epidx;
@@ -3460,7 +3460,7 @@ static void __devinit s3c_hsotg_create_debug(struct s3c_hsotg *hsotg)
*
* Cleanup (remove) the debugfs files for use on module exit.
*/
-static void __devexit s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg)
+static void s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg)
{
unsigned epidx;
@@ -3490,7 +3490,7 @@ static void s3c_hsotg_release(struct device *dev)
* @pdev: The platform information for the driver
*/
-static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
+static int s3c_hsotg_probe(struct platform_device *pdev)
{
struct s3c_hsotg_plat *plat = pdev->dev.platform_data;
struct device *dev = &pdev->dev;
@@ -3675,7 +3675,7 @@ err_clk:
* s3c_hsotg_remove - remove function for hsotg driver
* @pdev: The platform information for the driver
*/
-static int __devexit s3c_hsotg_remove(struct platform_device *pdev)
+static int s3c_hsotg_remove(struct platform_device *pdev)
{
struct s3c_hsotg *hsotg = platform_get_drvdata(pdev);
@@ -3708,7 +3708,7 @@ static struct platform_driver s3c_hsotg_driver = {
.owner = THIS_MODULE,
},
.probe = s3c_hsotg_probe,
- .remove = __devexit_p(s3c_hsotg_remove),
+ .remove = s3c_hsotg_remove,
.suspend = s3c_hsotg_suspend,
.resume = s3c_hsotg_resume,
};
diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c
index d8e785d4ad5..52379b11f08 100644
--- a/drivers/usb/gadget/s3c-hsudc.c
+++ b/drivers/usb/gadget/s3c-hsudc.c
@@ -1261,7 +1261,7 @@ static struct usb_gadget_ops s3c_hsudc_gadget_ops = {
.vbus_draw = s3c_hsudc_vbus_draw,
};
-static int __devinit s3c_hsudc_probe(struct platform_device *pdev)
+static int s3c_hsudc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct resource *res;
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index 8d9bcd8207c..0e3ae43454a 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -11,30 +11,10 @@
* (at your option) any later version.
*/
-
/*
* This file requires the following identifiers used in USB strings to
* be defined (each of type pointer to char):
- * - fsg_string_manufacturer -- name of the manufacturer
- * - fsg_string_product -- name of the product
- * - fsg_string_config -- name of the configuration
* - fsg_string_interface -- name of the interface
- * The first four are only needed when FSG_DESCRIPTORS_DEVICE_STRINGS
- * macro is defined prior to including this file.
- */
-
-/*
- * When FSG_NO_INTR_EP is defined fsg_fs_intr_in_desc and
- * fsg_hs_intr_in_desc objects as well as
- * FSG_FS_FUNCTION_PRE_EP_ENTRIES and FSG_HS_FUNCTION_PRE_EP_ENTRIES
- * macros are not defined.
- *
- * When FSG_NO_DEVICE_STRINGS is defined FSG_STRING_MANUFACTURER,
- * FSG_STRING_PRODUCT, FSG_STRING_SERIAL and FSG_STRING_CONFIG are not
- * defined (as well as corresponding entries in string tables are
- * missing) and FSG_STRING_INTERFACE has value of zero.
- *
- * When FSG_NO_OTG is defined fsg_otg_desc won't be defined.
*/
/*
@@ -78,34 +58,6 @@
#define LWARN(lun, fmt, args...) dev_warn(&(lun)->dev, fmt, ## args)
#define LINFO(lun, fmt, args...) dev_info(&(lun)->dev, fmt, ## args)
-/*
- * Keep those macros in sync with those in
- * include/linux/usb/composite.h or else GCC will complain. If they
- * are identical (the same names of arguments, white spaces in the
- * same places) GCC will allow redefinition otherwise (even if some
- * white space is removed or added) warning will be issued.
- *
- * Those macros are needed here because File Storage Gadget does not
- * include the composite.h header. For composite gadgets those macros
- * are redundant since composite.h is included any way.
- *
- * One could check whether those macros are already defined (which
- * would indicate composite.h had been included) or not (which would
- * indicate we were in FSG) but this is not done because a warning is
- * desired if definitions here differ from the ones in composite.h.
- *
- * We want the definitions to match and be the same in File Storage
- * Gadget as well as Mass Storage Function (and so composite gadgets
- * using MSF). If someone changes them in composite.h it will produce
- * a warning in this file when building MSF.
- */
-#define DBG(d, fmt, args...) dev_dbg(&(d)->gadget->dev , fmt , ## args)
-#define VDBG(d, fmt, args...) dev_vdbg(&(d)->gadget->dev , fmt , ## args)
-#define ERROR(d, fmt, args...) dev_err(&(d)->gadget->dev , fmt , ## args)
-#define WARNING(d, fmt, args...) dev_warn(&(d)->gadget->dev , fmt , ## args)
-#define INFO(d, fmt, args...) dev_info(&(d)->gadget->dev , fmt , ## args)
-
-
#ifdef DUMP_MSGS
@@ -203,9 +155,12 @@ struct fsg_lun {
struct device dev;
};
-#define fsg_lun_is_open(curlun) ((curlun)->filp != NULL)
+static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
+{
+ return curlun->filp != NULL;
+}
-static struct fsg_lun *fsg_lun_from_dev(struct device *dev)
+static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev)
{
return container_of(dev, struct fsg_lun, dev);
}
@@ -308,26 +263,10 @@ static inline u32 get_unaligned_be24(u8 *buf)
enum {
-#ifndef FSG_NO_DEVICE_STRINGS
- FSG_STRING_MANUFACTURER = 1,
- FSG_STRING_PRODUCT,
- FSG_STRING_SERIAL,
- FSG_STRING_CONFIG,
-#endif
FSG_STRING_INTERFACE
};
-#ifndef FSG_NO_OTG
-static struct usb_otg_descriptor
-fsg_otg_desc = {
- .bLength = sizeof fsg_otg_desc,
- .bDescriptorType = USB_DT_OTG,
-
- .bmAttributes = USB_OTG_SRP,
-};
-#endif
-
/* There is only one interface. */
static struct usb_interface_descriptor
@@ -367,37 +306,10 @@ fsg_fs_bulk_out_desc = {
/* wMaxPacketSize set by autoconfiguration */
};
-#ifndef FSG_NO_INTR_EP
-
-static struct usb_endpoint_descriptor
-fsg_fs_intr_in_desc = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
-
- .bEndpointAddress = USB_DIR_IN,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = cpu_to_le16(2),
- .bInterval = 32, /* frames -> 32 ms */
-};
-
-#ifndef FSG_NO_OTG
-# define FSG_FS_FUNCTION_PRE_EP_ENTRIES 2
-#else
-# define FSG_FS_FUNCTION_PRE_EP_ENTRIES 1
-#endif
-
-#endif
-
static struct usb_descriptor_header *fsg_fs_function[] = {
-#ifndef FSG_NO_OTG
- (struct usb_descriptor_header *) &fsg_otg_desc,
-#endif
(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,
-#ifndef FSG_NO_INTR_EP
- (struct usb_descriptor_header *) &fsg_fs_intr_in_desc,
-#endif
NULL,
};
@@ -431,37 +343,11 @@ fsg_hs_bulk_out_desc = {
.bInterval = 1, /* NAK every 1 uframe */
};
-#ifndef FSG_NO_INTR_EP
-
-static struct usb_endpoint_descriptor
-fsg_hs_intr_in_desc = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
-
- /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
- .bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = cpu_to_le16(2),
- .bInterval = 9, /* 2**(9-1) = 256 uframes -> 32 ms */
-};
-
-#ifndef FSG_NO_OTG
-# define FSG_HS_FUNCTION_PRE_EP_ENTRIES 2
-#else
-# define FSG_HS_FUNCTION_PRE_EP_ENTRIES 1
-#endif
-
-#endif
static struct usb_descriptor_header *fsg_hs_function[] = {
-#ifndef FSG_NO_OTG
- (struct usb_descriptor_header *) &fsg_otg_desc,
-#endif
(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,
-#ifndef FSG_NO_INTR_EP
- (struct usb_descriptor_header *) &fsg_hs_intr_in_desc,
-#endif
NULL,
};
@@ -499,34 +385,6 @@ static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
/*.bMaxBurst = DYNAMIC, */
};
-#ifndef FSG_NO_INTR_EP
-
-static struct usb_endpoint_descriptor
-fsg_ss_intr_in_desc = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
-
- /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
- .bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = cpu_to_le16(2),
- .bInterval = 9, /* 2**(9-1) = 256 uframes -> 32 ms */
-};
-
-static struct usb_ss_ep_comp_descriptor fsg_ss_intr_in_comp_desc = {
- .bLength = sizeof(fsg_ss_bulk_in_comp_desc),
- .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
-
- .wBytesPerInterval = cpu_to_le16(2),
-};
-
-#ifndef FSG_NO_OTG
-# define FSG_SS_FUNCTION_PRE_EP_ENTRIES 2
-#else
-# define FSG_SS_FUNCTION_PRE_EP_ENTRIES 1
-#endif
-
-#endif
-
static __maybe_unused struct usb_ext_cap_descriptor fsg_ext_cap_desc = {
.bLength = USB_DT_USB_EXT_CAP_SIZE,
.bDescriptorType = USB_DT_DEVICE_CAPABILITY,
@@ -563,18 +421,11 @@ static __maybe_unused struct usb_bos_descriptor fsg_bos_desc = {
};
static struct usb_descriptor_header *fsg_ss_function[] = {
-#ifndef FSG_NO_OTG
- (struct usb_descriptor_header *) &fsg_otg_desc,
-#endif
(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,
(struct usb_descriptor_header *) &fsg_ss_bulk_out_desc,
(struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc,
-#ifndef FSG_NO_INTR_EP
- (struct usb_descriptor_header *) &fsg_ss_intr_in_desc,
- (struct usb_descriptor_header *) &fsg_ss_intr_in_comp_desc,
-#endif
NULL,
};
@@ -594,12 +445,6 @@ fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
static struct usb_string fsg_strings[] = {
-#ifndef FSG_NO_DEVICE_STRINGS
- {FSG_STRING_MANUFACTURER, fsg_string_manufacturer},
- {FSG_STRING_PRODUCT, fsg_string_product},
- {FSG_STRING_SERIAL, ""},
- {FSG_STRING_CONFIG, fsg_string_config},
-#endif
{FSG_STRING_INTERFACE, fsg_string_interface},
{}
};
diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c
index 97e68b38cfd..4f7f76f00c7 100644
--- a/drivers/usb/gadget/tcm_usb_gadget.c
+++ b/drivers/usb/gadget/tcm_usb_gadget.c
@@ -1384,7 +1384,7 @@ static struct se_node_acl *usbg_alloc_fabric_acl(struct se_portal_group *se_tpg)
nacl = kzalloc(sizeof(struct usbg_nacl), GFP_KERNEL);
if (!nacl) {
- printk(KERN_ERR "Unable to alocate struct usbg_nacl\n");
+ printk(KERN_ERR "Unable to allocate struct usbg_nacl\n");
return NULL;
}
@@ -2139,6 +2139,7 @@ static struct usb_descriptor_header *uasp_fs_function_desc[] = {
(struct usb_descriptor_header *) &uasp_status_pipe_desc,
(struct usb_descriptor_header *) &uasp_fs_cmd_desc,
(struct usb_descriptor_header *) &uasp_cmd_pipe_desc,
+ NULL,
};
static struct usb_descriptor_header *uasp_hs_function_desc[] = {
@@ -2239,6 +2240,7 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_gadget *gadget = c->cdev->gadget;
struct usb_ep *ep;
int iface;
+ int ret;
iface = usb_interface_id(c, f);
if (iface < 0)
@@ -2289,6 +2291,11 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f)
uasp_ss_status_desc.bEndpointAddress;
uasp_fs_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress;
+ ret = usb_assign_descriptors(f, uasp_fs_function_desc,
+ uasp_hs_function_desc, uasp_ss_function_desc);
+ if (ret)
+ goto ep_fail;
+
return 0;
ep_fail:
pr_err("Can't claim all required eps\n");
@@ -2304,6 +2311,7 @@ static void usbg_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_uas *fu = to_f_uas(f);
+ usb_free_all_descriptors(f);
kfree(fu);
}
@@ -2384,9 +2392,6 @@ static int usbg_cfg_bind(struct usb_configuration *c)
if (!fu)
return -ENOMEM;
fu->function.name = "Target Function";
- fu->function.descriptors = uasp_fs_function_desc;
- fu->function.hs_descriptors = uasp_hs_function_desc;
- fu->function.ss_descriptors = uasp_ss_function_desc;
fu->function.bind = usbg_bind;
fu->function.unbind = usbg_unbind;
fu->function.set_alt = usbg_set_alt;
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index f1739526820..d0f95482f40 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -1145,8 +1145,10 @@ int gserial_setup(struct usb_gadget *g, unsigned count)
return status;
fail:
- while (count--)
+ while (count--) {
+ tty_port_destroy(&ports[count].port->port);
kfree(ports[count].port);
+ }
put_tty_driver(gs_tty_driver);
gs_tty_driver = NULL;
return status;
@@ -1200,6 +1202,7 @@ void gserial_cleanup(void)
WARN_ON(port->port_usb != NULL);
+ tty_port_destroy(&port->port);
kfree(port);
}
n_ports = 0;
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index f3cd9690b10..4d90a800063 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -439,16 +439,6 @@ static DEVICE_ATTR(name, S_IRUSR, usb_udc_##param##_show, NULL)
static USB_UDC_SPEED_ATTR(current_speed, speed);
static USB_UDC_SPEED_ATTR(maximum_speed, max_speed);
-/* TODO: Scheduled for removal in 3.8. */
-static ssize_t usb_udc_is_dualspeed_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_udc *udc = container_of(dev, struct usb_udc, dev);
- return snprintf(buf, PAGE_SIZE, "%d\n",
- gadget_is_dualspeed(udc->gadget));
-}
-static DEVICE_ATTR(is_dualspeed, S_IRUSR, usb_udc_is_dualspeed_show, NULL);
-
#define USB_UDC_ATTR(name) \
ssize_t usb_udc_##name##_show(struct device *dev, \
struct device_attribute *attr, char *buf) \
@@ -472,7 +462,6 @@ static struct attribute *usb_udc_attrs[] = {
&dev_attr_current_speed.attr,
&dev_attr_maximum_speed.attr,
- &dev_attr_is_dualspeed.attr,
&dev_attr_is_otg.attr,
&dev_attr_is_a_peripheral.attr,
&dev_attr_b_hnp_enable.attr,
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 3f1431d37e1..d6bb128ce21 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -95,6 +95,11 @@ config USB_EHCI_TT_NEWSCHED
If unsure, say Y.
+config USB_EHCI_PCI
+ tristate
+ depends on USB_EHCI_HCD && PCI
+ default y
+
config USB_EHCI_HCD_PMC_MSP
tristate "EHCI support for on-chip PMC MSP71xx USB controller"
depends on USB_EHCI_HCD && MSP_HAS_USB
@@ -215,9 +220,13 @@ config USB_W90X900_EHCI
Enables support for the W90X900 USB controller
config USB_CNS3XXX_EHCI
- bool "Cavium CNS3XXX EHCI Module"
+ bool "Cavium CNS3XXX EHCI Module (DEPRECATED)"
depends on USB_EHCI_HCD && ARCH_CNS3XXX
+ select USB_EHCI_HCD_PLATFORM
---help---
+ This option is deprecated now and the driver was removed, use
+ USB_EHCI_HCD_PLATFORM instead.
+
Enable support for the CNS3XXX SOC's on-chip EHCI controller.
It is needed for high-speed (480Mbit/sec) USB 2.0 device
support.
@@ -333,16 +342,6 @@ config USB_OHCI_ATH79
Enables support for the built-in OHCI controller present on the
Atheros AR71XX/AR7240 SoCs.
-config USB_OHCI_HCD_PPC_SOC
- bool "OHCI support for on-chip PPC USB controller"
- depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
- default y
- select USB_OHCI_BIG_ENDIAN_DESC
- select USB_OHCI_BIG_ENDIAN_MMIO
- ---help---
- Enables support for the USB controller on the MPC52xx or
- STB03xxx processor chip. If unsure, say Y.
-
config USB_OHCI_HCD_PPC_OF_BE
bool "OHCI support for OF platform bus (big endian)"
depends on USB_OHCI_HCD && PPC_OF
@@ -393,9 +392,13 @@ config USB_OHCI_HCD_SSB
If unsure, say N.
config USB_OHCI_SH
- bool "OHCI support for SuperH USB controller"
+ bool "OHCI support for SuperH USB controller (DEPRECATED)"
depends on USB_OHCI_HCD && SUPERH
+ select USB_OHCI_HCD_PLATFORM
---help---
+ This option is deprecated now and the driver was removed, use
+ USB_OHCI_HCD_PLATFORM instead.
+
Enables support for the on-chip OHCI controller on the SuperH.
If you use the PCI OHCI controller, this option is not necessary.
@@ -406,9 +409,13 @@ config USB_OHCI_EXYNOS
Enable support for the Samsung Exynos SOC's on-chip OHCI controller.
config USB_CNS3XXX_OHCI
- bool "Cavium CNS3XXX OHCI Module"
+ bool "Cavium CNS3XXX OHCI Module (DEPRECATED)"
depends on USB_OHCI_HCD && ARCH_CNS3XXX
+ select USB_OHCI_HCD_PLATFORM
---help---
+ This option is deprecated now and the driver was removed, use
+ USB_OHCI_HCD_PLATFORM instead.
+
Enable support for the CNS3XXX SOC's on-chip OHCI controller.
It is needed for low-speed USB 1.0 device support.
@@ -423,7 +430,7 @@ config USB_OHCI_HCD_PLATFORM
If unsure, say N.
config USB_EHCI_HCD_PLATFORM
- bool "Generic EHCI driver for a platform device"
+ tristate "Generic EHCI driver for a platform device"
depends on USB_EHCI_HCD
default n
---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 9e0a89ced15..1eb4c3006e9 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -24,6 +24,9 @@ obj-$(CONFIG_USB_WHCI_HCD) += whci/
obj-$(CONFIG_PCI) += pci-quirks.o
obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
+obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
+obj-$(CONFIG_USB_EHCI_HCD_PLATFORM) += ehci-platform.o
+
obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o
@@ -40,6 +43,5 @@ obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o
obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o
obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o
obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o
-obj-$(CONFIG_MIPS_ALCHEMY) += alchemy-common.o
obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o
obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o
diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
index 443da21d73c..df13d425e9c 100644
--- a/drivers/usb/host/bcma-hcd.c
+++ b/drivers/usb/host/bcma-hcd.c
@@ -54,7 +54,7 @@ static int bcma_wait_bits(struct bcma_device *dev, u16 reg, u32 bitmask,
return -ETIMEDOUT;
}
-static void __devinit bcma_hcd_4716wa(struct bcma_device *dev)
+static void bcma_hcd_4716wa(struct bcma_device *dev)
{
#ifdef CONFIG_BCMA_DRIVER_MIPS
/* Work around for 4716 failures. */
@@ -88,7 +88,7 @@ static void __devinit bcma_hcd_4716wa(struct bcma_device *dev)
}
/* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
-static void __devinit bcma_hcd_init_chip(struct bcma_device *dev)
+static void bcma_hcd_init_chip(struct bcma_device *dev)
{
u32 tmp;
@@ -165,8 +165,7 @@ static const struct usb_ehci_pdata ehci_pdata = {
static const struct usb_ohci_pdata ohci_pdata = {
};
-static struct platform_device * __devinit
-bcma_hcd_create_pdev(struct bcma_device *dev, bool ohci, u32 addr)
+static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev, bool ohci, u32 addr)
{
struct platform_device *hci_dev;
struct resource hci_res[2];
@@ -212,7 +211,7 @@ err_alloc:
return ERR_PTR(ret);
}
-static int __devinit bcma_hcd_probe(struct bcma_device *dev)
+static int bcma_hcd_probe(struct bcma_device *dev)
{
int err;
u16 chipid_top;
@@ -266,7 +265,7 @@ err_free_usb_dev:
return err;
}
-static void __devexit bcma_hcd_remove(struct bcma_device *dev)
+static void bcma_hcd_remove(struct bcma_device *dev)
{
struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
struct platform_device *ohci_dev = usb_dev->ohci_dev;
@@ -306,7 +305,7 @@ static int bcma_hcd_resume(struct bcma_device *dev)
#define bcma_hcd_resume NULL
#endif /* CONFIG_PM */
-static const struct bcma_device_id bcma_hcd_table[] __devinitconst = {
+static const struct bcma_device_id bcma_hcd_table[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
BCMA_CORETABLE_END
};
@@ -316,7 +315,7 @@ static struct bcma_driver bcma_hcd_driver = {
.name = KBUILD_MODNAME,
.id_table = bcma_hcd_table,
.probe = bcma_hcd_probe,
- .remove = __devexit_p(bcma_hcd_remove),
+ .remove = bcma_hcd_remove,
.shutdown = bcma_hcd_shutdown,
.suspend = bcma_hcd_suspend,
.resume = bcma_hcd_resume,
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 411bb74152e..27639487f7a 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -53,18 +53,11 @@ static void atmel_stop_ehci(struct platform_device *pdev)
static int ehci_atmel_setup(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval;
/* registers start at offset 0x0 */
ehci->caps = hcd->regs;
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 0);
-
- return retval;
+ return ehci_setup(hcd);
}
static const struct hc_driver ehci_atmel_hc_driver = {
@@ -104,7 +97,7 @@ static const struct hc_driver ehci_atmel_hc_driver = {
static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32);
-static int __devinit ehci_atmel_drv_probe(struct platform_device *pdev)
+static int ehci_atmel_drv_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
const struct hc_driver *driver = &ehci_atmel_hc_driver;
@@ -189,7 +182,7 @@ fail_create_hcd:
return retval;
}
-static int __devexit ehci_atmel_drv_remove(struct platform_device *pdev)
+static int ehci_atmel_drv_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
@@ -214,7 +207,7 @@ MODULE_DEVICE_TABLE(of, atmel_ehci_dt_ids);
static struct platform_driver ehci_atmel_driver = {
.probe = ehci_atmel_drv_probe,
- .remove = __devexit_p(ehci_atmel_drv_remove),
+ .remove = ehci_atmel_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
.driver = {
.name = "atmel-ehci",
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c
deleted file mode 100644
index 65c945eb414..00000000000
--- a/drivers/usb/host/ehci-au1xxx.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * EHCI HCD (Host Controller Driver) for USB.
- *
- * Bus Glue for AMD Alchemy Au1xxx
- *
- * Based on "ohci-au1xxx.c" by Matt Porter <mporter@kernel.crashing.org>
- *
- * Modified for AMD Alchemy Au1200 EHC
- * by K.Boge <karsten.boge@amd.com>
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/platform_device.h>
-#include <asm/mach-au1x00/au1000.h>
-
-
-extern int usb_disabled(void);
-
-static int au1xxx_ehci_setup(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int ret;
-
- ehci->caps = hcd->regs;
- ret = ehci_setup(hcd);
-
- ehci->need_io_watchdog = 0;
- return ret;
-}
-
-static const struct hc_driver ehci_au1xxx_hc_driver = {
- .description = hcd_name,
- .product_desc = "Au1xxx EHCI",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
-
- /*
- * basic lifecycle operations
- *
- * FIXME -- ehci_init() doesn't do enough here.
- * See ehci-ppc-soc for a complete implementation.
- */
- .reset = au1xxx_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,
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
-static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- struct resource *res;
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- if (pdev->resource[1].flags != IORESOURCE_IRQ) {
- pr_debug("resource[1] is not IORESOURCE_IRQ");
- return -ENOMEM;
- }
- hcd = usb_create_hcd(&ehci_au1xxx_hc_driver, &pdev->dev, "Au1xxx");
- if (!hcd)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (!hcd->regs) {
- pr_debug("devm_request_and_ioremap failed");
- ret = -ENOMEM;
- goto err1;
- }
-
- if (alchemy_usb_control(ALCHEMY_USB_EHCI0, 1)) {
- printk(KERN_INFO "%s: controller init failed!\n", pdev->name);
- ret = -ENODEV;
- goto err1;
- }
-
- ret = usb_add_hcd(hcd, pdev->resource[1].start,
- IRQF_SHARED);
- if (ret == 0) {
- platform_set_drvdata(pdev, hcd);
- return ret;
- }
-
- alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
-err1:
- usb_put_hcd(hcd);
- return ret;
-}
-
-static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
- usb_put_hcd(hcd);
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
-{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
- bool do_wakeup = device_may_wakeup(dev);
- int rc;
-
- rc = ehci_suspend(hcd, do_wakeup);
- alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
-
- return rc;
-}
-
-static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
-{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
-
- alchemy_usb_control(ALCHEMY_USB_EHCI0, 1);
- ehci_resume(hcd, false);
-
- return 0;
-}
-
-static const struct dev_pm_ops au1xxx_ehci_pmops = {
- .suspend = ehci_hcd_au1xxx_drv_suspend,
- .resume = ehci_hcd_au1xxx_drv_resume,
-};
-
-#define AU1XXX_EHCI_PMOPS &au1xxx_ehci_pmops
-
-#else
-#define AU1XXX_EHCI_PMOPS NULL
-#endif
-
-static struct platform_driver ehci_hcd_au1xxx_driver = {
- .probe = ehci_hcd_au1xxx_drv_probe,
- .remove = ehci_hcd_au1xxx_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "au1xxx-ehci",
- .owner = THIS_MODULE,
- .pm = AU1XXX_EHCI_PMOPS,
- }
-};
-
-MODULE_ALIAS("platform:au1xxx-ehci");
diff --git a/drivers/usb/host/ehci-cns3xxx.c b/drivers/usb/host/ehci-cns3xxx.c
deleted file mode 100644
index d91708d2e72..00000000000
--- a/drivers/usb/host/ehci-cns3xxx.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2008 Cavium Networks
- *
- * This file 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/platform_device.h>
-#include <linux/atomic.h>
-#include <mach/cns3xxx.h>
-#include <mach/pm.h>
-
-static int cns3xxx_ehci_init(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval;
-
- /*
- * EHCI and OHCI share the same clock and power,
- * resetting twice would cause the 1st controller been reset.
- * Therefore only do power up at the first up device, and
- * power down at the last down device.
- *
- * Set USB AHB INCR length to 16
- */
- if (atomic_inc_return(&usb_pwr_ref) == 1) {
- cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
- cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
- cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
- __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
- MISC_CHIP_CONFIG_REG);
- }
-
- ehci->caps = hcd->regs;
-
- hcd->has_tt = 0;
-
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 0);
-
- return retval;
-}
-
-static const struct hc_driver cns3xxx_ehci_hc_driver = {
- .description = hcd_name,
- .product_desc = "CNS3XXX EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
- .reset = cns3xxx_ehci_init,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
- .get_frame_number = ehci_get_frame,
- .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 cns3xxx_ehci_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct usb_hcd *hcd;
- const struct hc_driver *driver = &cns3xxx_ehci_hc_driver;
- struct resource *res;
- int irq;
- int retval;
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(dev, "Found HC with no IRQ.\n");
- return -ENODEV;
- }
- irq = res->start;
-
- hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
- if (!hcd)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(dev, "Found HC with no register addr.\n");
- retval = -ENODEV;
- goto err1;
- }
-
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (hcd->regs == NULL) {
- dev_dbg(dev, "error mapping memory\n");
- retval = -EFAULT;
- goto err1;
- }
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval == 0)
- return retval;
-
-err1:
- usb_put_hcd(hcd);
-
- return retval;
-}
-
-static int cns3xxx_ehci_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
-
- /*
- * EHCI and OHCI share the same clock and power,
- * resetting twice would cause the 1st controller been reset.
- * Therefore only do power up at the first up device, and
- * power down at the last down device.
- */
- if (atomic_dec_return(&usb_pwr_ref) == 0)
- cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
-
- usb_put_hcd(hcd);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-MODULE_ALIAS("platform:cns3xxx-ehci");
-
-static struct platform_driver cns3xxx_ehci_driver = {
- .probe = cns3xxx_ehci_probe,
- .remove = cns3xxx_ehci_remove,
- .driver = {
- .name = "cns3xxx-ehci",
- },
-};
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 1599806e3d4..70b496dc18a 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -18,21 +18,6 @@
/* this file is part of ehci-hcd.c */
-#define ehci_dbg(ehci, fmt, args...) \
- dev_dbg (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
-#define ehci_err(ehci, fmt, args...) \
- dev_err (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
-#define ehci_info(ehci, fmt, args...) \
- dev_info (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
-#define ehci_warn(ehci, fmt, args...) \
- dev_warn (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
-
-#ifdef VERBOSE_DEBUG
-# define ehci_vdbg ehci_dbg
-#else
- static inline void ehci_vdbg(struct ehci_hcd *ehci, ...) {}
-#endif
-
#ifdef DEBUG
/* check the values in the HCSPARAMS register
@@ -352,11 +337,6 @@ static int debug_async_open(struct inode *, struct file *);
static int debug_periodic_open(struct inode *, struct file *);
static int debug_registers_open(struct inode *, struct file *);
static int debug_async_open(struct inode *, struct file *);
-static ssize_t debug_lpm_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-static ssize_t debug_lpm_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos);
-static int debug_lpm_close(struct inode *inode, struct file *file);
static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
static int debug_close(struct inode *, struct file *);
@@ -382,14 +362,6 @@ static const struct file_operations debug_registers_fops = {
.release = debug_close,
.llseek = default_llseek,
};
-static const struct file_operations debug_lpm_fops = {
- .owner = THIS_MODULE,
- .open = simple_open,
- .read = debug_lpm_read,
- .write = debug_lpm_write,
- .release = debug_lpm_close,
- .llseek = noop_llseek,
-};
static struct dentry *ehci_debug_root;
@@ -971,86 +943,6 @@ static int debug_registers_open(struct inode *inode, struct file *file)
return file->private_data ? 0 : -ENOMEM;
}
-static int debug_lpm_close(struct inode *inode, struct file *file)
-{
- return 0;
-}
-
-static ssize_t debug_lpm_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- /* TODO: show lpm stats */
- return 0;
-}
-
-static ssize_t debug_lpm_write(struct file *file, const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct usb_hcd *hcd;
- struct ehci_hcd *ehci;
- char buf[50];
- size_t len;
- u32 temp;
- unsigned long port;
- u32 __iomem *portsc ;
- u32 params;
-
- hcd = bus_to_hcd(file->private_data);
- ehci = hcd_to_ehci(hcd);
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
- buf[len] = '\0';
- if (len > 0 && buf[len - 1] == '\n')
- buf[len - 1] = '\0';
-
- if (strncmp(buf, "enable", 5) == 0) {
- if (strict_strtoul(buf + 7, 10, &port))
- return -EINVAL;
- params = ehci_readl(ehci, &ehci->caps->hcs_params);
- if (port > HCS_N_PORTS(params)) {
- ehci_dbg(ehci, "ERR: LPM on bad port %lu\n", port);
- return -ENODEV;
- }
- portsc = &ehci->regs->port_status[port-1];
- temp = ehci_readl(ehci, portsc);
- if (!(temp & PORT_DEV_ADDR)) {
- ehci_dbg(ehci, "LPM: no device attached\n");
- return -ENODEV;
- }
- temp |= PORT_LPM;
- ehci_writel(ehci, temp, portsc);
- printk(KERN_INFO "force enable LPM for port %lu\n", port);
- } else if (strncmp(buf, "hird=", 5) == 0) {
- unsigned long hird;
- if (strict_strtoul(buf + 5, 16, &hird))
- return -EINVAL;
- printk(KERN_INFO "setting hird %s %lu\n", buf + 6, hird);
- ehci->command = (ehci->command & ~CMD_HIRD) | (hird << 24);
- ehci_writel(ehci, ehci->command, &ehci->regs->command);
- } else if (strncmp(buf, "disable", 7) == 0) {
- if (strict_strtoul(buf + 8, 10, &port))
- return -EINVAL;
- params = ehci_readl(ehci, &ehci->caps->hcs_params);
- if (port > HCS_N_PORTS(params)) {
- ehci_dbg(ehci, "ERR: LPM off bad port %lu\n", port);
- return -ENODEV;
- }
- portsc = &ehci->regs->port_status[port-1];
- temp = ehci_readl(ehci, portsc);
- if (!(temp & PORT_DEV_ADDR)) {
- ehci_dbg(ehci, "ERR: no device attached\n");
- return -ENODEV;
- }
- temp &= ~PORT_LPM;
- ehci_writel(ehci, temp, portsc);
- printk(KERN_INFO "disabled LPM for port %lu\n", port);
- } else
- return -EOPNOTSUPP;
- return count;
-}
-
static inline void create_debug_files (struct ehci_hcd *ehci)
{
struct usb_bus *bus = &ehci_to_hcd(ehci)->self;
@@ -1071,10 +963,6 @@ static inline void create_debug_files (struct ehci_hcd *ehci)
&debug_registers_fops))
goto file_error;
- if (!debugfs_create_file("lpm", S_IRUGO|S_IWUSR, ehci->debug_dir, bus,
- &debug_lpm_fops))
- goto file_error;
-
return;
file_error:
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 0d2f35ca93f..fd9b5424b86 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -349,7 +349,6 @@ static int ehci_fsl_reinit(struct ehci_hcd *ehci)
{
if (ehci_fsl_usb_setup(ehci))
return -EINVAL;
- ehci_port_power(ehci, 0);
return 0;
}
diff --git a/drivers/usb/host/ehci-grlib.c b/drivers/usb/host/ehci-grlib.c
index 3180cb3624d..1fc89292f5d 100644
--- a/drivers/usb/host/ehci-grlib.c
+++ b/drivers/usb/host/ehci-grlib.c
@@ -34,22 +34,6 @@
#define GRUSBHC_HCIVERSION 0x0100 /* Known value of cap. reg. HCIVERSION */
-/* called during probe() after chip reset completes */
-static int ehci_grlib_setup(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval;
-
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 1);
-
- return retval;
-}
-
-
static const struct hc_driver ehci_grlib_hc_driver = {
.description = hcd_name,
.product_desc = "GRLIB GRUSBHC EHCI",
@@ -64,7 +48,7 @@ static const struct hc_driver ehci_grlib_hc_driver = {
/*
* basic lifecycle operations
*/
- .reset = ehci_grlib_setup,
+ .reset = ehci_setup,
.start = ehci_run,
.stop = ehci_stop,
.shutdown = ehci_shutdown,
@@ -98,7 +82,7 @@ static const struct hc_driver ehci_grlib_hc_driver = {
};
-static int __devinit ehci_hcd_grlib_probe(struct platform_device *op)
+static int ehci_hcd_grlib_probe(struct platform_device *op)
{
struct device_node *dn = op->dev.of_node;
struct usb_hcd *hcd;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 6bf6c42481e..c97503bb0b0 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -39,7 +39,6 @@
#include <linux/dma-mapping.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
-#include <linux/uaccess.h>
#include <asm/byteorder.h>
#include <asm/io.h>
@@ -108,19 +107,39 @@ static bool ignore_oc = 0;
module_param (ignore_oc, bool, S_IRUGO);
MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications");
-/* for link power management(LPM) feature */
-static unsigned int hird;
-module_param(hird, int, S_IRUGO);
-MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
-
#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
/*-------------------------------------------------------------------------*/
#include "ehci.h"
-#include "ehci-dbg.c"
#include "pci-quirks.h"
+/*
+ * The MosChip MCS9990 controller updates its microframe counter
+ * a little before the frame counter, and occasionally we will read
+ * the invalid intermediate value. Avoid problems by checking the
+ * microframe number (the low-order 3 bits); if they are 0 then
+ * re-read the register to get the correct value.
+ */
+static unsigned ehci_moschip_read_frame_index(struct ehci_hcd *ehci)
+{
+ unsigned uf;
+
+ uf = ehci_readl(ehci, &ehci->regs->frame_index);
+ if (unlikely((uf & 7) == 0))
+ uf = ehci_readl(ehci, &ehci->regs->frame_index);
+ return uf;
+}
+
+static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
+{
+ if (ehci->frame_index_bug)
+ return ehci_moschip_read_frame_index(ehci);
+ return ehci_readl(ehci, &ehci->regs->frame_index);
+}
+
+#include "ehci-dbg.c"
+
/*-------------------------------------------------------------------------*/
/*
@@ -293,7 +312,6 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
#include "ehci-timer.c"
#include "ehci-hub.c"
-#include "ehci-lpm.c"
#include "ehci-mem.c"
#include "ehci-q.c"
#include "ehci-sched.c"
@@ -353,24 +371,6 @@ static void ehci_shutdown(struct usb_hcd *hcd)
hrtimer_cancel(&ehci->hrtimer);
}
-static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
-{
- unsigned port;
-
- if (!HCS_PPC (ehci->hcs_params))
- return;
-
- ehci_dbg (ehci, "...power%s ports...\n", is_on ? "up" : "down");
- for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; )
- (void) ehci_hub_control(ehci_to_hcd(ehci),
- is_on ? SetPortFeature : ClearPortFeature,
- USB_PORT_FEAT_POWER,
- port--, NULL, 0);
- /* Flush those writes */
- ehci_readl(ehci, &ehci->regs->command);
- msleep(20);
-}
-
/*-------------------------------------------------------------------------*/
/*
@@ -503,7 +503,7 @@ static int ehci_init(struct usb_hcd *hcd)
/* controllers may cache some of the periodic schedule ... */
if (HCC_ISOC_CACHE(hcc_params)) // full frame cache
- ehci->i_thresh = 2 + 8;
+ ehci->i_thresh = 0;
else // N microframes cached
ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params);
@@ -555,17 +555,6 @@ static int ehci_init(struct usb_hcd *hcd)
temp &= ~(3 << 2);
temp |= (EHCI_TUNE_FLS << 2);
}
- if (HCC_LPM(hcc_params)) {
- /* support link power management EHCI 1.1 addendum */
- ehci_dbg(ehci, "support lpm\n");
- ehci->has_lpm = 1;
- if (hird > 0xf) {
- ehci_dbg(ehci, "hird %d invalid, use default 0",
- hird);
- hird = 0;
- }
- temp |= hird << 24;
- }
ehci->command = temp;
/* Accept arbitrarily long scatter-gather lists */
@@ -660,7 +649,7 @@ static int ehci_run (struct usb_hcd *hcd)
return 0;
}
-static int ehci_setup(struct usb_hcd *hcd)
+int ehci_setup(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
int retval;
@@ -691,6 +680,7 @@ static int ehci_setup(struct usb_hcd *hcd)
return 0;
}
+EXPORT_SYMBOL_GPL(ehci_setup);
/*-------------------------------------------------------------------------*/
@@ -1096,7 +1086,7 @@ static int ehci_get_frame (struct usb_hcd *hcd)
/* These routines handle the generic parts of controller suspend/resume */
-static int __maybe_unused ehci_suspend(struct usb_hcd *hcd, bool do_wakeup)
+int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
@@ -1119,9 +1109,10 @@ static int __maybe_unused ehci_suspend(struct usb_hcd *hcd, bool do_wakeup)
return 0;
}
+EXPORT_SYMBOL_GPL(ehci_suspend);
/* Returns 0 if power was preserved, 1 if power was lost */
-static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated)
+int ehci_resume(struct usb_hcd *hcd, bool hibernated)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
@@ -1177,33 +1168,83 @@ static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated)
ehci->rh_state = EHCI_RH_SUSPENDED;
spin_unlock_irq(&ehci->lock);
- /* here we "know" root ports should always stay powered */
- ehci_port_power(ehci, 1);
-
return 1;
}
+EXPORT_SYMBOL_GPL(ehci_resume);
#endif
/*-------------------------------------------------------------------------*/
/*
- * The EHCI in ChipIdea HDRC cannot be a separate module or device,
- * because its registers (and irq) are shared between host/gadget/otg
- * functions and in order to facilitate role switching we cannot
- * give the ehci driver exclusive access to those.
+ * Generic structure: This gets copied for platform drivers so that
+ * individual entries can be overridden as needed.
*/
-#ifndef CHIPIDEA_EHCI
+
+static const struct hc_driver ehci_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "EHCI Host Controller",
+ .hcd_priv_size = sizeof(struct ehci_hcd),
+
+ /*
+ * generic hardware linkage
+ */
+ .irq = ehci_irq,
+ .flags = HCD_MEMORY | HCD_USB2,
+
+ /*
+ * 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,
+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+
+ /*
+ * scheduling support
+ */
+ .get_frame_number = ehci_get_frame,
+
+ /*
+ * root hub support
+ */
+ .hub_status_data = ehci_hub_status_data,
+ .hub_control = ehci_hub_control,
+ .bus_suspend = ehci_bus_suspend,
+ .bus_resume = ehci_bus_resume,
+ .relinquish_port = ehci_relinquish_port,
+ .port_handed_over = ehci_port_handed_over,
+};
+
+void ehci_init_driver(struct hc_driver *drv,
+ const struct ehci_driver_overrides *over)
+{
+ /* Copy the generic table to drv and then apply the overrides */
+ *drv = ehci_hc_driver;
+
+ if (over) {
+ drv->hcd_priv_size += over->extra_priv_size;
+ if (over->reset)
+ drv->reset = over->reset;
+ }
+}
+EXPORT_SYMBOL_GPL(ehci_init_driver);
+
+/*-------------------------------------------------------------------------*/
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR (DRIVER_AUTHOR);
MODULE_LICENSE ("GPL");
-#ifdef CONFIG_PCI
-#include "ehci-pci.c"
-#define PCI_DRIVER ehci_pci_driver
-#endif
-
#ifdef CONFIG_USB_EHCI_FSL
#include "ehci-fsl.c"
#define PLATFORM_DRIVER ehci_fsl_driver
@@ -1219,11 +1260,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_hcd_sh_driver
#endif
-#ifdef CONFIG_MIPS_ALCHEMY
-#include "ehci-au1xxx.c"
-#define PLATFORM_DRIVER ehci_hcd_au1xxx_driver
-#endif
-
#ifdef CONFIG_USB_EHCI_HCD_OMAP
#include "ehci-omap.c"
#define PLATFORM_DRIVER ehci_hcd_omap_driver
@@ -1249,11 +1285,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_orion_driver
#endif
-#ifdef CONFIG_ARCH_IXP4XX
-#include "ehci-ixp4xx.c"
-#define PLATFORM_DRIVER ixp4xx_ehci_driver
-#endif
-
#ifdef CONFIG_USB_W90X900_EHCI
#include "ehci-w90x900.c"
#define PLATFORM_DRIVER ehci_hcd_w90x900_driver
@@ -1269,11 +1300,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_octeon_driver
#endif
-#ifdef CONFIG_USB_CNS3XXX_EHCI
-#include "ehci-cns3xxx.c"
-#define PLATFORM_DRIVER cns3xxx_ehci_driver
-#endif
-
#ifdef CONFIG_ARCH_VT8500
#include "ehci-vt8500.c"
#define PLATFORM_DRIVER vt8500_ehci_driver
@@ -1314,34 +1340,23 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_grlib_driver
#endif
-#ifdef CONFIG_CPU_XLR
-#include "ehci-xls.c"
-#define PLATFORM_DRIVER ehci_xls_driver
-#endif
-
#ifdef CONFIG_USB_EHCI_MV
#include "ehci-mv.c"
#define PLATFORM_DRIVER ehci_mv_driver
#endif
-#ifdef CONFIG_MACH_LOONGSON1
-#include "ehci-ls1x.c"
-#define PLATFORM_DRIVER ehci_ls1x_driver
-#endif
-
#ifdef CONFIG_MIPS_SEAD3
#include "ehci-sead3.c"
#define PLATFORM_DRIVER ehci_hcd_sead3_driver
#endif
-#ifdef CONFIG_USB_EHCI_HCD_PLATFORM
-#include "ehci-platform.c"
-#define PLATFORM_DRIVER ehci_platform_driver
-#endif
-
-#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
- !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
- !defined(XILINX_OF_PLATFORM_DRIVER)
+#if !IS_ENABLED(CONFIG_USB_EHCI_PCI) && \
+ !IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) && \
+ !defined(CONFIG_USB_CHIPIDEA_HOST) && \
+ !defined(PLATFORM_DRIVER) && \
+ !defined(PS3_SYSTEM_BUS_DRIVER) && \
+ !defined(OF_PLATFORM_DRIVER) && \
+ !defined(XILINX_OF_PLATFORM_DRIVER)
#error "missing bus glue for ehci-hcd"
#endif
@@ -1378,12 +1393,6 @@ static int __init ehci_hcd_init(void)
goto clean0;
#endif
-#ifdef PCI_DRIVER
- retval = pci_register_driver(&PCI_DRIVER);
- if (retval < 0)
- goto clean1;
-#endif
-
#ifdef PS3_SYSTEM_BUS_DRIVER
retval = ps3_ehci_driver_register(&PS3_SYSTEM_BUS_DRIVER);
if (retval < 0)
@@ -1415,10 +1424,6 @@ clean3:
ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
clean2:
#endif
-#ifdef PCI_DRIVER
- pci_unregister_driver(&PCI_DRIVER);
-clean1:
-#endif
#ifdef PLATFORM_DRIVER
platform_driver_unregister(&PLATFORM_DRIVER);
clean0:
@@ -1444,9 +1449,6 @@ static void __exit ehci_hcd_cleanup(void)
#ifdef PLATFORM_DRIVER
platform_driver_unregister(&PLATFORM_DRIVER);
#endif
-#ifdef PCI_DRIVER
- pci_unregister_driver(&PCI_DRIVER);
-#endif
#ifdef PS3_SYSTEM_BUS_DRIVER
ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
#endif
@@ -1456,5 +1458,3 @@ static void __exit ehci_hcd_cleanup(void)
clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
}
module_exit(ehci_hcd_cleanup);
-
-#endif /* CHIPIDEA_EHCI */
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 914ce9370e7..4ccb97c0678 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -56,6 +56,19 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci)
if (!ehci->owned_ports)
return;
+ /* Make sure the ports are powered */
+ port = HCS_N_PORTS(ehci->hcs_params);
+ while (port--) {
+ if (test_bit(port, &ehci->owned_ports)) {
+ reg = &ehci->regs->port_status[port];
+ status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
+ if (!(status & PORT_POWER)) {
+ status |= PORT_POWER;
+ ehci_writel(ehci, status, reg);
+ }
+ }
+ }
+
/* Give the connections some time to appear */
msleep(20);
@@ -384,11 +397,24 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
ehci_writel(ehci, ehci->command, &ehci->regs->command);
ehci->rh_state = EHCI_RH_RUNNING;
- /* Some controller/firmware combinations need a delay during which
- * they set up the port statuses. See Bugzilla #8190. */
- spin_unlock_irq(&ehci->lock);
- msleep(8);
- spin_lock_irq(&ehci->lock);
+ /*
+ * According to Bugzilla #8190, the port status for some controllers
+ * will be wrong without a delay. At their wrong status, the port
+ * is enabled, but not suspended neither resumed.
+ */
+ i = HCS_N_PORTS(ehci->hcs_params);
+ while (i--) {
+ temp = ehci_readl(ehci, &ehci->regs->port_status[i]);
+ if ((temp & PORT_PE) &&
+ !(temp & (PORT_SUSPEND | PORT_RESUME))) {
+ ehci_dbg(ehci, "Port status(0x%x) is wrong\n", temp);
+ spin_unlock_irq(&ehci->lock);
+ msleep(8);
+ spin_lock_irq(&ehci->lock);
+ break;
+ }
+ }
+
if (ehci->shutdown)
goto shutdown;
@@ -764,11 +790,6 @@ static int ehci_hub_control (
status_reg);
break;
case USB_PORT_FEAT_C_CONNECTION:
- if (ehci->has_lpm) {
- /* clear PORTSC bits on disconnect */
- temp &= ~PORT_LPM;
- temp &= ~PORT_DEV_ADDR;
- }
ehci_writel(ehci, temp | PORT_CSC, status_reg);
break;
case USB_PORT_FEAT_C_OVER_CURRENT:
@@ -1088,8 +1109,7 @@ error_exit:
return retval;
}
-static void __maybe_unused ehci_relinquish_port(struct usb_hcd *hcd,
- int portnum)
+static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
@@ -1098,8 +1118,7 @@ static void __maybe_unused ehci_relinquish_port(struct usb_hcd *hcd,
set_owner(ehci, --portnum, PORT_OWNER);
}
-static int __maybe_unused ehci_port_handed_over(struct usb_hcd *hcd,
- int portnum)
+static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
u32 __iomem *reg;
diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c
deleted file mode 100644
index f224c0a48be..00000000000
--- a/drivers/usb/host/ehci-ixp4xx.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * IXP4XX EHCI Host Controller Driver
- *
- * Author: Vladimir Barinov <vbarinov@embeddedalley.com>
- *
- * Based on "ehci-fsl.c" by Randy Vinson <rvinson@mvista.com>
- *
- * 2007 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#include <linux/platform_device.h>
-
-static int ixp4xx_ehci_init(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval = 0;
-
- ehci->big_endian_desc = 1;
- ehci->big_endian_mmio = 1;
-
- ehci->caps = hcd->regs + 0x100;
-
- hcd->has_tt = 1;
-
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 0);
-
- return retval;
-}
-
-static const struct hc_driver ixp4xx_ehci_hc_driver = {
- .description = hcd_name,
- .product_desc = "IXP4XX EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
- .reset = ixp4xx_ehci_init,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
- .get_frame_number = ehci_get_frame,
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
-#if defined(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 ixp4xx_ehci_probe(struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- const struct hc_driver *driver = &ixp4xx_ehci_hc_driver;
- struct resource *res;
- int irq;
- int retval;
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(&pdev->dev,
- "Found HC with no IRQ. Check %s setup!\n",
- dev_name(&pdev->dev));
- return -ENODEV;
- }
- irq = res->start;
-
- hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
- if (!hcd) {
- retval = -ENOMEM;
- goto fail_create_hcd;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev,
- "Found HC with no register addr. Check %s setup!\n",
- dev_name(&pdev->dev));
- retval = -ENODEV;
- goto fail_request_resource;
- }
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (hcd->regs == NULL) {
- dev_dbg(&pdev->dev, "error mapping memory\n");
- retval = -EFAULT;
- goto fail_request_resource;
- }
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval)
- goto fail_request_resource;
-
- return retval;
-
-fail_request_resource:
- usb_put_hcd(hcd);
-fail_create_hcd:
- dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
- return retval;
-}
-
-static int ixp4xx_ehci_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- usb_put_hcd(hcd);
-
- return 0;
-}
-
-MODULE_ALIAS("platform:ixp4xx-ehci");
-
-static struct platform_driver ixp4xx_ehci_driver = {
- .probe = ixp4xx_ehci_probe,
- .remove = ixp4xx_ehci_remove,
- .driver = {
- .name = "ixp4xx-ehci",
- },
-};
diff --git a/drivers/usb/host/ehci-lpm.c b/drivers/usb/host/ehci-lpm.c
deleted file mode 100644
index 2111627a19d..00000000000
--- a/drivers/usb/host/ehci-lpm.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* ehci-lpm.c EHCI HCD LPM support code
- * Copyright (c) 2008 - 2010, Intel Corporation.
- * Author: Jacob Pan <jacob.jun.pan@intel.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.
- *
- * 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.
-*/
-
-/* this file is part of ehci-hcd.c */
-static int __maybe_unused ehci_lpm_set_da(struct ehci_hcd *ehci,
- int dev_addr, int port_num)
-{
- u32 __iomem portsc;
-
- ehci_dbg(ehci, "set dev address %d for port %d\n", dev_addr, port_num);
- if (port_num > HCS_N_PORTS(ehci->hcs_params)) {
- ehci_dbg(ehci, "invalid port number %d\n", port_num);
- return -ENODEV;
- }
- portsc = ehci_readl(ehci, &ehci->regs->port_status[port_num-1]);
- portsc &= ~PORT_DEV_ADDR;
- portsc |= dev_addr<<25;
- ehci_writel(ehci, portsc, &ehci->regs->port_status[port_num-1]);
- return 0;
-}
-
-/*
- * this function is used to check if the device support LPM
- * if yes, mark the PORTSC register with PORT_LPM bit
- */
-static int __maybe_unused ehci_lpm_check(struct ehci_hcd *ehci, int port)
-{
- u32 __iomem *portsc ;
- u32 val32;
- int retval;
-
- portsc = &ehci->regs->port_status[port-1];
- val32 = ehci_readl(ehci, portsc);
- if (!(val32 & PORT_DEV_ADDR)) {
- ehci_dbg(ehci, "LPM: no device attached\n");
- return -ENODEV;
- }
- val32 |= PORT_LPM;
- ehci_writel(ehci, val32, portsc);
- msleep(5);
- val32 |= PORT_SUSPEND;
- ehci_dbg(ehci, "Sending LPM 0x%08x to port %d\n", val32, port);
- ehci_writel(ehci, val32, portsc);
- /* wait for ACK */
- msleep(10);
- retval = handshake(ehci, &ehci->regs->port_status[port-1], PORT_SSTS,
- PORTSC_SUSPEND_STS_ACK, 125);
- dbg_port(ehci, "LPM", port, val32);
- if (retval != -ETIMEDOUT) {
- ehci_dbg(ehci, "LPM: device ACK for LPM\n");
- val32 |= PORT_LPM;
- /*
- * now device should be in L1 sleep, let's wake up the device
- * so that we can complete enumeration.
- */
- ehci_writel(ehci, val32, portsc);
- msleep(10);
- val32 |= PORT_RESUME;
- ehci_writel(ehci, val32, portsc);
- } else {
- ehci_dbg(ehci, "LPM: device does not ACK, disable LPM %d\n",
- retval);
- val32 &= ~PORT_LPM;
- retval = -ETIMEDOUT;
- ehci_writel(ehci, val32, portsc);
- }
-
- return retval;
-}
diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c
deleted file mode 100644
index ca759652626..00000000000
--- a/drivers/usb/host/ehci-ls1x.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Bus Glue for Loongson LS1X built-in EHCI controller.
- *
- * Copyright (c) 2012 Zhang, Keguang <keguang.zhang@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/platform_device.h>
-
-static int ehci_ls1x_reset(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int ret;
-
- ehci->caps = hcd->regs;
-
- ret = ehci_setup(hcd);
- if (ret)
- return ret;
-
- ehci_port_power(ehci, 0);
-
- return 0;
-}
-
-static const struct hc_driver ehci_ls1x_hc_driver = {
- .description = hcd_name,
- .product_desc = "LOONGSON1 EHCI",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
-
- /*
- * basic lifecycle operations
- */
- .reset = ehci_ls1x_reset,
- .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,
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
-static int ehci_hcd_ls1x_probe(struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- struct resource *res;
- int irq;
- int ret;
-
- pr_debug("initializing loongson1 ehci USB Controller\n");
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(&pdev->dev,
- "Found HC with no IRQ. Check %s setup!\n",
- dev_name(&pdev->dev));
- return -ENODEV;
- }
- irq = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev,
- "Found HC with no register addr. Check %s setup!\n",
- dev_name(&pdev->dev));
- return -ENODEV;
- }
-
- hcd = usb_create_hcd(&ehci_ls1x_hc_driver, &pdev->dev,
- dev_name(&pdev->dev));
- if (!hcd)
- return -ENOMEM;
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (hcd->regs == NULL) {
- dev_dbg(&pdev->dev, "error mapping memory\n");
- ret = -EFAULT;
- goto err_put_hcd;
- }
-
- ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (ret)
- goto err_put_hcd;
-
- return ret;
-
-err_put_hcd:
- usb_put_hcd(hcd);
- return ret;
-}
-
-static int ehci_hcd_ls1x_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- usb_put_hcd(hcd);
-
- return 0;
-}
-
-static struct platform_driver ehci_ls1x_driver = {
- .probe = ehci_hcd_ls1x_probe,
- .remove = ehci_hcd_ls1x_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "ls1x-ehci",
- .owner = THIS_MODULE,
- },
-};
-
-MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ls1x-ehci");
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index 4af4dc5b618..88a49c87e74 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -53,7 +53,6 @@ static int ehci_msm_reset(struct usb_hcd *hcd)
/* Disable streaming mode and select host mode */
writel(0x13, USB_USBMODE);
- ehci_port_power(ehci, 1);
return 0;
}
@@ -174,7 +173,7 @@ put_hcd:
return ret;
}
-static int __devexit ehci_msm_remove(struct platform_device *pdev)
+static int ehci_msm_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
@@ -221,7 +220,7 @@ static const struct dev_pm_ops ehci_msm_dev_pm_ops = {
static struct platform_driver ehci_msm_driver = {
.probe = ehci_msm_probe,
- .remove = __devexit_p(ehci_msm_remove),
+ .remove = ehci_msm_remove,
.driver = {
.name = "msm_hsusb_host",
.pm = &ehci_msm_dev_pm_ops,
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index 4a08fc0b27c..8804f74689d 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -39,17 +39,9 @@ struct ehci_mxc_priv {
/* called during probe() after chip reset completes */
static int ehci_mxc_setup(struct usb_hcd *hcd)
{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval;
-
hcd->has_tt = 1;
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 0);
- return 0;
+ return ehci_setup(hcd);
}
static const struct hc_driver ehci_mxc_hc_driver = {
diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c
index ba26957abf4..a89750fff4f 100644
--- a/drivers/usb/host/ehci-octeon.c
+++ b/drivers/usb/host/ehci-octeon.c
@@ -159,9 +159,6 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, hcd);
- /* root ports should always stay powered */
- ehci_port_power(ehci, 1);
-
return 0;
err3:
ehci_octeon_stop();
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index d7fe287d067..44e7d0f638e 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -146,9 +146,6 @@ static int omap_ehci_init(struct usb_hcd *hcd)
gpio_set_value_cansleep(pdata->reset_gpio_port[1], 1);
}
- /* root ports should always stay powered */
- ehci_port_power(ehci, 1);
-
return rc;
}
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index 9c2717d6673..f74794c9315 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -101,20 +101,6 @@ static void orion_usb_phy_v1_setup(struct usb_hcd *hcd)
wrl(USB_MODE, 0x13);
}
-static int ehci_orion_setup(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval;
-
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 0);
-
- return retval;
-}
-
static const struct hc_driver ehci_orion_hc_driver = {
.description = hcd_name,
.product_desc = "Marvell Orion EHCI",
@@ -129,7 +115,7 @@ static const struct hc_driver ehci_orion_hc_driver = {
/*
* basic lifecycle operations
*/
- .reset = ehci_orion_setup,
+ .reset = ehci_setup,
.start = ehci_run,
.stop = ehci_stop,
.shutdown = ehci_shutdown,
@@ -160,7 +146,7 @@ static const struct hc_driver ehci_orion_hc_driver = {
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
-static void __devinit
+static void
ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
const struct mbus_dram_target_info *dram)
{
@@ -181,7 +167,7 @@ ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
}
}
-static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
+static int ehci_orion_drv_probe(struct platform_device *pdev)
{
struct orion_ehci_data *pd = pdev->dev.platform_data;
const struct mbus_dram_target_info *dram;
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 2cb7d370c4e..dabb2049482 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -18,9 +18,18 @@
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef CONFIG_PCI
-#error "This file is PCI bus glue. CONFIG_PCI must be defined."
-#endif
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ehci.h"
+#include "pci-quirks.h"
+
+#define DRIVER_DESC "EHCI PCI platform driver"
+
+static const char hcd_name[] = "ehci-pci";
/* defined here to avoid adding to pci_ids.h for single instance use */
#define PCI_DEVICE_ID_INTEL_CE4100_USB 0x2e70
@@ -103,7 +112,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
}
break;
case PCI_VENDOR_ID_INTEL:
- ehci->fs_i_thresh = 1;
if (pdev->device == PCI_DEVICE_ID_INTEL_CE4100_USB)
hcd->has_tt = 1;
break;
@@ -203,11 +211,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
break;
case PCI_VENDOR_ID_INTEL:
ehci->need_io_watchdog = 0;
- if (pdev->device == 0x0806 || pdev->device == 0x0811
- || pdev->device == 0x0829) {
- ehci_info(ehci, "disable lpm for langwell/penwell\n");
- ehci->has_lpm = 0;
- }
break;
case PCI_VENDOR_ID_NVIDIA:
switch (pdev->device) {
@@ -217,8 +220,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
* devices with PPCD enabled.
*/
case 0x0d9d:
- ehci_info(ehci, "disable lpm/ppcd for nvidia mcp89");
- ehci->has_lpm = 0;
+ ehci_info(ehci, "disable ppcd for nvidia mcp89\n");
ehci->has_ppcd = 0;
ehci->command &= ~CMD_PPCEE;
break;
@@ -304,7 +306,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
ehci_warn(ehci, "selective suspend/wakeup unavailable\n");
#endif
- ehci_port_power(ehci, 1);
retval = ehci_pci_reinit(ehci, pdev);
done:
return retval;
@@ -323,18 +324,14 @@ done:
* Also they depend on separate root hub suspend/resume.
*/
-static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
-{
- return ehci_suspend(hcd, do_wakeup);
-}
-
static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev)
{
return pdev->class == PCI_CLASS_SERIAL_USB_EHCI &&
pdev->vendor == PCI_VENDOR_ID_INTEL &&
(pdev->device == 0x1E26 ||
pdev->device == 0x8C2D ||
- pdev->device == 0x8C26);
+ pdev->device == 0x8C26 ||
+ pdev->device == 0x9C26);
}
static void ehci_enable_xhci_companion(void)
@@ -378,76 +375,17 @@ static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
(void) ehci_pci_reinit(ehci, pdev);
return 0;
}
-#endif
-static int ehci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int rc = 0;
-
- if (!udev->parent) /* udev is root hub itself, impossible */
- rc = -1;
- /* we only support lpm device connected to root hub yet */
- if (ehci->has_lpm && !udev->parent->parent) {
- rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum);
- if (!rc)
- rc = ehci_lpm_check(ehci, udev->portnum);
- }
- return rc;
-}
+#else
-static const struct hc_driver ehci_pci_hc_driver = {
- .description = hcd_name,
- .product_desc = "EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
+#define ehci_suspend NULL
+#define ehci_pci_resume NULL
+#endif /* CONFIG_PM */
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
+static struct hc_driver __read_mostly ehci_pci_hc_driver;
- /*
- * basic lifecycle operations
- */
+static const struct ehci_driver_overrides pci_overrides __initdata = {
.reset = ehci_pci_setup,
- .start = ehci_run,
-#ifdef CONFIG_PM
- .pci_suspend = ehci_pci_suspend,
- .pci_resume = ehci_pci_resume,
-#endif
- .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,
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- /*
- * call back when device connected and addressed
- */
- .update_device = ehci_update_device,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
/*-------------------------------------------------------------------------*/
@@ -480,3 +418,31 @@ static struct pci_driver ehci_pci_driver = {
},
#endif
};
+
+static int __init ehci_pci_init(void)
+{
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+ ehci_init_driver(&ehci_pci_hc_driver, &pci_overrides);
+
+ /* Entries for the PCI suspend/resume callbacks are special */
+ ehci_pci_hc_driver.pci_suspend = ehci_suspend;
+ ehci_pci_hc_driver.pci_resume = ehci_pci_resume;
+
+ return pci_register_driver(&ehci_pci_driver);
+}
+module_init(ehci_pci_init);
+
+static void __exit ehci_pci_cleanup(void)
+{
+ pci_unregister_driver(&ehci_pci_driver);
+}
+module_exit(ehci_pci_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("David Brownell");
+MODULE_AUTHOR("Alan Stern");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 764e0100b6f..58fa0c90c7c 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -18,9 +18,21 @@
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
+#include <linux/kernel.h>
+#include <linux/hrtimer.h>
+#include <linux/io.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
#include <linux/usb/ehci_pdriver.h>
+#include "ehci.h"
+
+#define DRIVER_DESC "EHCI generic platform driver"
+
+static const char hcd_name[] = "ehci-platform";
+
static int ehci_platform_reset(struct usb_hcd *hcd)
{
struct platform_device *pdev = to_platform_device(hcd->self.controller);
@@ -38,47 +50,18 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
if (retval)
return retval;
- if (pdata->port_power_on)
- ehci_port_power(ehci, 1);
- if (pdata->port_power_off)
- ehci_port_power(ehci, 0);
-
+ if (pdata->no_io_watchdog)
+ ehci->need_io_watchdog = 0;
return 0;
}
-static const struct hc_driver ehci_platform_hc_driver = {
- .description = hcd_name,
- .product_desc = "Generic Platform EHCI Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
-
- .reset = ehci_platform_reset,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
-
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
+static struct hc_driver __read_mostly ehci_platform_hc_driver;
- .get_frame_number = ehci_get_frame,
-
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
-#if defined(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 const struct ehci_driver_overrides platform_overrides __initdata = {
+ .reset = ehci_platform_reset,
};
-static int __devinit ehci_platform_probe(struct platform_device *dev)
+static int ehci_platform_probe(struct platform_device *dev)
{
struct usb_hcd *hcd;
struct resource *res_mem;
@@ -96,12 +79,12 @@ static int __devinit ehci_platform_probe(struct platform_device *dev)
irq = platform_get_irq(dev, 0);
if (irq < 0) {
- pr_err("no irq provided");
+ dev_err(&dev->dev, "no irq provided");
return irq;
}
res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!res_mem) {
- pr_err("no memory recourse provided");
+ dev_err(&dev->dev, "no memory resource provided");
return -ENXIO;
}
@@ -121,29 +104,19 @@ static int __devinit ehci_platform_probe(struct platform_device *dev)
hcd->rsrc_start = res_mem->start;
hcd->rsrc_len = resource_size(res_mem);
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- pr_err("controller already in use");
- err = -EBUSY;
- goto err_put_hcd;
- }
-
- hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
+ hcd->regs = devm_request_and_ioremap(&dev->dev, res_mem);
if (!hcd->regs) {
err = -ENOMEM;
- goto err_release_region;
+ goto err_put_hcd;
}
err = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (err)
- goto err_iounmap;
+ goto err_put_hcd;
platform_set_drvdata(dev, hcd);
return err;
-err_iounmap:
- iounmap(hcd->regs);
-err_release_region:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err_put_hcd:
usb_put_hcd(hcd);
err_power:
@@ -153,14 +126,12 @@ err_power:
return err;
}
-static int __devexit ehci_platform_remove(struct platform_device *dev)
+static int ehci_platform_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
struct usb_ehci_pdata *pdata = dev->dev.platform_data;
usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
platform_set_drvdata(dev, NULL);
@@ -225,7 +196,7 @@ static const struct dev_pm_ops ehci_platform_pm_ops = {
static struct platform_driver ehci_platform_driver = {
.id_table = ehci_platform_table,
.probe = ehci_platform_probe,
- .remove = __devexit_p(ehci_platform_remove),
+ .remove = ehci_platform_remove,
.shutdown = usb_hcd_platform_shutdown,
.driver = {
.owner = THIS_MODULE,
@@ -233,3 +204,26 @@ static struct platform_driver ehci_platform_driver = {
.pm = &ehci_platform_pm_ops,
}
};
+
+static int __init ehci_platform_init(void)
+{
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+ ehci_init_driver(&ehci_platform_hc_driver, &platform_overrides);
+ return platform_driver_register(&ehci_platform_driver);
+}
+module_init(ehci_platform_init);
+
+static void __exit ehci_platform_cleanup(void)
+{
+ platform_driver_unregister(&ehci_platform_driver);
+}
+module_exit(ehci_platform_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Hauke Mehrtens");
+MODULE_AUTHOR("Alan Stern");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c
index 087aee2a904..363890ee41d 100644
--- a/drivers/usb/host/ehci-pmcmsp.c
+++ b/drivers/usb/host/ehci-pmcmsp.c
@@ -90,7 +90,6 @@ static int ehci_msp_setup(struct usb_hcd *hcd)
return retval;
usb_hcd_tdi_set_mode(ehci);
- ehci_port_power(ehci, 0);
return retval;
}
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c
index fa937d05a02..45aceefd0c2 100644
--- a/drivers/usb/host/ehci-ppc-of.c
+++ b/drivers/usb/host/ehci-ppc-of.c
@@ -71,7 +71,7 @@ static const struct hc_driver ehci_ppc_of_hc_driver = {
* Fix: Enable Break Memory Transfer (BMT) in INSNREG3
*/
#define PPC440EPX_EHCI0_INSREG_BMT (0x1 << 0)
-static int __devinit
+static int
ppc44x_enable_bmt(struct device_node *dn)
{
__iomem u32 *insreg_virt;
@@ -87,7 +87,7 @@ ppc44x_enable_bmt(struct device_node *dn)
}
-static int __devinit ehci_hcd_ppc_of_probe(struct platform_device *op)
+static int ehci_hcd_ppc_of_probe(struct platform_device *op)
{
struct device_node *dn = op->dev.of_node;
struct usb_hcd *hcd;
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
index 45a356e9f13..df5925a4f0d 100644
--- a/drivers/usb/host/ehci-ps3.c
+++ b/drivers/usb/host/ehci-ps3.c
@@ -93,7 +93,7 @@ static const struct hc_driver ps3_ehci_hc_driver = {
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
-static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev)
+static int ps3_ehci_probe(struct ps3_system_bus_device *dev)
{
int result;
struct usb_hcd *hcd;
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 4b66374bdc8..3d989028c83 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -264,15 +264,9 @@ ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status)
__releases(ehci->lock)
__acquires(ehci->lock)
{
- if (likely (urb->hcpriv != NULL)) {
- struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv;
-
- /* S-mask in a QH means it's an interrupt urb */
- if ((qh->hw->hw_info2 & cpu_to_hc32(ehci, QH_SMASK)) != 0) {
-
- /* ... update hc-wide periodic stats (for usbfs) */
- ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;
- }
+ if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
+ /* ... update hc-wide periodic stats */
+ ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;
}
if (unlikely(urb->unlinked)) {
diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
index 85b74be202e..319dcfaa873 100644
--- a/drivers/usb/host/ehci-s5p.c
+++ b/drivers/usb/host/ehci-s5p.c
@@ -85,7 +85,7 @@ static void s5p_setup_vbus_gpio(struct platform_device *pdev)
static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32);
-static int __devinit s5p_ehci_probe(struct platform_device *pdev)
+static int s5p_ehci_probe(struct platform_device *pdev)
{
struct s5p_ehci_platdata *pdata;
struct s5p_ehci_hcd *s5p_ehci;
@@ -136,7 +136,7 @@ static int __devinit s5p_ehci_probe(struct platform_device *pdev)
goto fail_clk;
}
- err = clk_enable(s5p_ehci->clk);
+ err = clk_prepare_enable(s5p_ehci->clk);
if (err)
goto fail_clk;
@@ -183,13 +183,13 @@ static int __devinit s5p_ehci_probe(struct platform_device *pdev)
return 0;
fail_io:
- clk_disable(s5p_ehci->clk);
+ clk_disable_unprepare(s5p_ehci->clk);
fail_clk:
usb_put_hcd(hcd);
return err;
}
-static int __devexit s5p_ehci_remove(struct platform_device *pdev)
+static int s5p_ehci_remove(struct platform_device *pdev)
{
struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev);
@@ -200,7 +200,7 @@ static int __devexit s5p_ehci_remove(struct platform_device *pdev)
if (pdata && pdata->phy_exit)
pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
- clk_disable(s5p_ehci->clk);
+ clk_disable_unprepare(s5p_ehci->clk);
usb_put_hcd(hcd);
@@ -231,7 +231,7 @@ static int s5p_ehci_suspend(struct device *dev)
if (pdata && pdata->phy_exit)
pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
- clk_disable(s5p_ehci->clk);
+ clk_disable_unprepare(s5p_ehci->clk);
return rc;
}
@@ -243,7 +243,7 @@ static int s5p_ehci_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
- clk_enable(s5p_ehci->clk);
+ clk_prepare_enable(s5p_ehci->clk);
if (pdata && pdata->phy_init)
pdata->phy_init(pdev, S5P_USB_PHY_HOST);
@@ -274,7 +274,7 @@ MODULE_DEVICE_TABLE(of, exynos_ehci_match);
static struct platform_driver s5p_ehci_driver = {
.probe = s5p_ehci_probe,
- .remove = __devexit_p(s5p_ehci_remove),
+ .remove = s5p_ehci_remove,
.shutdown = s5p_ehci_shutdown,
.driver = {
.name = "s5p-ehci",
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 7cf3da7babf..69ebee73c0c 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -36,29 +36,6 @@
static int ehci_get_frame (struct usb_hcd *hcd);
-#ifdef CONFIG_PCI
-
-static unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
-{
- unsigned uf;
-
- /*
- * The MosChip MCS9990 controller updates its microframe counter
- * a little before the frame counter, and occasionally we will read
- * the invalid intermediate value. Avoid problems by checking the
- * microframe number (the low-order 3 bits); if they are 0 then
- * re-read the register to get the correct value.
- */
- uf = ehci_readl(ehci, &ehci->regs->frame_index);
- if (unlikely(ehci->frame_index_bug && ((uf & 7) == 0)))
- uf = ehci_readl(ehci, &ehci->regs->frame_index);
- return uf;
-}
-
-#endif
-
-/*-------------------------------------------------------------------------*/
-
/*
* periodic_next_shadow - return "next" pointer on shadow list
* @periodic: host pointer to qh/itd/sitd
@@ -1361,7 +1338,7 @@ sitd_slot_ok (
* given EHCI_TUNE_FLS and the slop). Or, write a smarter scheduler!
*/
-#define SCHEDULE_SLOP 80 /* microframes */
+#define SCHEDULING_DELAY 40 /* microframes */
static int
iso_stream_schedule (
@@ -1370,7 +1347,7 @@ iso_stream_schedule (
struct ehci_iso_stream *stream
)
{
- u32 now, next, start, period, span;
+ u32 now, base, next, start, period, span;
int status;
unsigned mod = ehci->periodic_size << 3;
struct ehci_iso_sched *sched = urb->hcpriv;
@@ -1382,62 +1359,72 @@ iso_stream_schedule (
span <<= 3;
}
- if (span > mod - SCHEDULE_SLOP) {
- ehci_dbg (ehci, "iso request %p too long\n", urb);
- status = -EFBIG;
- goto fail;
- }
-
now = ehci_read_frame_index(ehci) & (mod - 1);
/* Typical case: reuse current schedule, stream is still active.
* Hopefully there are no gaps from the host falling behind
- * (irq delays etc), but if there are we'll take the next
- * slot in the schedule, implicitly assuming URB_ISO_ASAP.
+ * (irq delays etc). If there are, the behavior depends on
+ * whether URB_ISO_ASAP is set.
*/
if (likely (!list_empty (&stream->td_list))) {
- u32 excess;
- /* For high speed devices, allow scheduling within the
- * isochronous scheduling threshold. For full speed devices
- * and Intel PCI-based controllers, don't (work around for
- * Intel ICH9 bug).
- */
- if (!stream->highspeed && ehci->fs_i_thresh)
- next = now + ehci->i_thresh;
+ /* Take the isochronous scheduling threshold into account */
+ if (ehci->i_thresh)
+ next = now + ehci->i_thresh; /* uframe cache */
else
- next = now;
+ next = (now + 2 + 7) & ~0x07; /* full frame cache */
- /* Fell behind (by up to twice the slop amount)?
- * We decide based on the time of the last currently-scheduled
- * slot, not the time of the next available slot.
+ /*
+ * Use ehci->last_iso_frame as the base. There can't be any
+ * TDs scheduled for earlier than that.
*/
- excess = (stream->next_uframe - period - next) & (mod - 1);
- if (excess >= mod - 2 * SCHEDULE_SLOP)
- start = next + excess - mod + period *
- DIV_ROUND_UP(mod - excess, period);
- else
- start = next + excess + period;
- if (start - now >= mod) {
- ehci_dbg(ehci, "request %p would overflow (%d+%d >= %d)\n",
- urb, start - now - period, period,
- mod);
- status = -EFBIG;
+ 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)) {
+
+ /* USB_ISO_ASAP: Round up to the first available slot */
+ if (urb->transfer_flags & URB_ISO_ASAP)
+ start += (next - start + period - 1) & -period;
+
+ /*
+ * Not ASAP: Use the next slot in the stream. If
+ * the entire URB falls before the threshold, fail.
+ */
+ else if (start + span - period < next) {
+ ehci_dbg(ehci, "iso urb late %p (%u+%u < %u)\n",
+ urb, start + base,
+ span - period, next + base);
+ status = -EXDEV;
+ goto fail;
+ }
+ }
+
+ start += base;
}
/* 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 slop should handle reasonably slow cpus. it
+ * 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.
*/
else {
int done = 0;
- start = SCHEDULE_SLOP + (now & ~0x07);
- /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
+ base = now & ~0x07;
+ start = base + SCHEDULING_DELAY;
/* find a uframe slot with enough bandwidth.
* Early uframes are more precious because full-speed
@@ -1464,19 +1451,16 @@ iso_stream_schedule (
/* no room in the schedule */
if (!done) {
- ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n",
- urb, now, now + mod);
+ ehci_dbg(ehci, "iso sched full %p", urb);
status = -ENOSPC;
goto fail;
}
}
/* Tried to schedule too far into the future? */
- if (unlikely(start - now + span - period
- >= mod - 2 * SCHEDULE_SLOP)) {
- ehci_dbg(ehci, "request %p would overflow (%d+%d >= %d)\n",
- urb, start - now, span - period,
- mod - 2 * SCHEDULE_SLOP);
+ if (unlikely(start - base + span - period >= mod)) {
+ ehci_dbg(ehci, "request %p would overflow (%u+%u >= %u)\n",
+ urb, start - base, span - period, mod);
status = -EFBIG;
goto fail;
}
@@ -1490,7 +1474,7 @@ iso_stream_schedule (
/* Make sure scan_isoc() sees these */
if (ehci->isoc_count == 0)
- ehci->next_frame = now >> 3;
+ ehci->last_iso_frame = now >> 3;
return 0;
fail:
@@ -1646,7 +1630,7 @@ static void itd_link_urb(
/* don't need that schedule data any more */
iso_sched_free (stream, iso_sched);
- urb->hcpriv = NULL;
+ urb->hcpriv = stream;
++ehci->isoc_count;
enable_periodic(ehci);
@@ -1708,7 +1692,7 @@ static bool itd_complete(struct ehci_hcd *ehci, struct ehci_itd *itd)
urb->actual_length += desc->actual_length;
} else {
/* URB was too late */
- desc->status = -EXDEV;
+ urb->error_count++;
}
}
@@ -2045,7 +2029,7 @@ static void sitd_link_urb(
/* don't need that schedule data any more */
iso_sched_free (stream, sched);
- urb->hcpriv = NULL;
+ urb->hcpriv = stream;
++ehci->isoc_count;
enable_periodic(ehci);
@@ -2081,7 +2065,7 @@ static bool sitd_complete(struct ehci_hcd *ehci, struct ehci_sitd *sitd)
t = hc32_to_cpup(ehci, &sitd->hw_results);
/* report transfer status */
- if (t & SITD_ERRS) {
+ if (unlikely(t & SITD_ERRS)) {
urb->error_count++;
if (t & SITD_STS_DBE)
desc->status = usb_pipein (urb->pipe)
@@ -2091,6 +2075,9 @@ static bool sitd_complete(struct ehci_hcd *ehci, struct ehci_sitd *sitd)
desc->status = -EOVERFLOW;
else /* XACT, MMF, etc */
desc->status = -EPROTO;
+ } else if (unlikely(t & SITD_STS_ACTIVE)) {
+ /* URB was too late */
+ urb->error_count++;
} else {
desc->status = 0;
desc->actual_length = desc->length - SITD_LENGTH(t);
@@ -2220,16 +2207,16 @@ static void scan_isoc(struct ehci_hcd *ehci)
now_frame = (uf >> 3) & fmask;
live = true;
} else {
- now_frame = (ehci->next_frame - 1) & fmask;
+ now_frame = (ehci->last_iso_frame - 1) & fmask;
live = false;
}
ehci->now_frame = now_frame;
- frame = ehci->next_frame;
for (;;) {
union ehci_shadow q, *q_p;
__hc32 type, *hw_p;
+ frame = ehci->last_iso_frame;
restart:
/* scan each element in frame's queue for completions */
q_p = &ehci->pshadow [frame];
@@ -2334,7 +2321,6 @@ restart:
/* Stop when we have reached the current frame */
if (frame == now_frame)
break;
- frame = (frame + 1) & fmask;
+ ehci->last_iso_frame = (frame + 1) & fmask;
}
- ehci->next_frame = now_frame;
}
diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c
index 6081e1ed3ac..0c90a24fa98 100644
--- a/drivers/usb/host/ehci-sh.c
+++ b/drivers/usb/host/ehci-sh.c
@@ -21,17 +21,10 @@ struct ehci_sh_priv {
static int ehci_sh_reset(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int ret;
ehci->caps = hcd->regs;
- ret = ehci_setup(hcd);
- if (unlikely(ret))
- return ret;
-
- ehci_port_power(ehci, 0);
-
- return ret;
+ return ehci_setup(hcd);
}
static const struct hc_driver ehci_sh_hc_driver = {
diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c
index c718a065e15..466c1bb5b96 100644
--- a/drivers/usb/host/ehci-spear.c
+++ b/drivers/usb/host/ehci-spear.c
@@ -37,18 +37,11 @@ static void spear_stop_ehci(struct spear_ehci *ehci)
static int ehci_spear_setup(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval = 0;
/* registers start at offset 0x0 */
ehci->caps = hcd->regs;
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 0);
-
- return retval;
+ return ehci_setup(hcd);
}
static const struct hc_driver ehci_spear_hc_driver = {
@@ -116,8 +109,6 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
struct clk *usbh_clk;
const struct hc_driver *driver = &ehci_spear_hc_driver;
int irq, retval;
- char clk_name[20] = "usbh_clk";
- static int instance = -1;
if (usb_disabled())
return -ENODEV;
@@ -125,7 +116,7 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
retval = irq;
- goto fail_irq_get;
+ goto fail;
}
/*
@@ -136,47 +127,38 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
if (!pdev->dev.dma_mask)
pdev->dev.dma_mask = &spear_ehci_dma_mask;
- /*
- * Increment the device instance, when probing via device-tree
- */
- if (pdev->id < 0)
- instance++;
- else
- instance = pdev->id;
- sprintf(clk_name, "usbh.%01d_clk", instance);
-
- usbh_clk = clk_get(NULL, clk_name);
+ usbh_clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(usbh_clk)) {
dev_err(&pdev->dev, "Error getting interface clock\n");
retval = PTR_ERR(usbh_clk);
- goto fail_get_usbh_clk;
+ goto fail;
}
hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
if (!hcd) {
retval = -ENOMEM;
- goto fail_create_hcd;
+ goto fail;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
retval = -ENODEV;
- goto fail_request_resource;
+ goto err_put_hcd;
}
hcd->rsrc_start = res->start;
hcd->rsrc_len = resource_size(res);
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
+ if (!devm_request_mem_region(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len,
driver->description)) {
retval = -EBUSY;
- goto fail_request_resource;
+ goto err_put_hcd;
}
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len);
if (hcd->regs == NULL) {
dev_dbg(&pdev->dev, "error mapping memory\n");
retval = -ENOMEM;
- goto fail_ioremap;
+ goto err_put_hcd;
}
ehci = (struct spear_ehci *)hcd_to_ehci(hcd);
@@ -185,21 +167,15 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
spear_start_ehci(ehci);
retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (retval)
- goto fail_add_hcd;
+ goto err_stop_ehci;
return retval;
-fail_add_hcd:
+err_stop_ehci:
spear_stop_ehci(ehci);
- iounmap(hcd->regs);
-fail_ioremap:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-fail_request_resource:
+err_put_hcd:
usb_put_hcd(hcd);
-fail_create_hcd:
- clk_put(usbh_clk);
-fail_get_usbh_clk:
-fail_irq_get:
+fail:
dev_err(&pdev->dev, "init fail, %d\n", retval);
return retval ;
@@ -218,17 +194,12 @@ static int spear_ehci_hcd_drv_remove(struct platform_device *pdev)
if (ehci_p->clk)
spear_stop_ehci(ehci_p);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
- if (ehci_p->clk)
- clk_put(ehci_p->clk);
-
return 0;
}
-static struct of_device_id spear_ehci_id_table[] __devinitdata = {
+static struct of_device_id spear_ehci_id_table[] = {
{ .compatible = "st,spear600-ehci", },
{ },
};
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 6223d175784..acf17556bd8 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -28,7 +28,10 @@
#include <linux/pm_runtime.h>
#include <linux/usb/tegra_usb_phy.h>
-#include <mach/iomap.h>
+
+#define TEGRA_USB_BASE 0xC5000000
+#define TEGRA_USB2_BASE 0xC5004000
+#define TEGRA_USB3_BASE 0xC5008000
#define TEGRA_USB_DMA_ALIGN 32
@@ -277,7 +280,6 @@ static void tegra_ehci_shutdown(struct usb_hcd *hcd)
static int tegra_ehci_setup(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval;
/* EHCI registers start at offset 0x100 */
ehci->caps = hcd->regs + 0x100;
@@ -285,12 +287,7 @@ static int tegra_ehci_setup(struct usb_hcd *hcd)
/* switch to host mode */
hcd->has_tt = 1;
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 1);
- return retval;
+ return ehci_setup(hcd);
}
struct dma_aligned_buffer {
@@ -778,9 +775,6 @@ static int tegra_ehci_remove(struct platform_device *pdev)
struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev);
struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci);
- if (tegra == NULL || hcd == NULL)
- return -EINVAL;
-
pm_runtime_get_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
@@ -811,7 +805,7 @@ static void tegra_ehci_hcd_shutdown(struct platform_device *pdev)
hcd->driver->shutdown(hcd);
}
-static struct of_device_id tegra_ehci_of_match[] __devinitdata = {
+static struct of_device_id tegra_ehci_of_match[] = {
{ .compatible = "nvidia,tegra20-ehci", },
{ },
};
diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c
index d3c9a3e397b..11695d5b9d8 100644
--- a/drivers/usb/host/ehci-vt8500.c
+++ b/drivers/usb/host/ehci-vt8500.c
@@ -19,22 +19,6 @@
#include <linux/of.h>
#include <linux/platform_device.h>
-static int ehci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int rc = 0;
-
- if (!udev->parent) /* udev is root hub itself, impossible */
- rc = -1;
- /* we only support lpm device connected to root hub yet */
- if (ehci->has_lpm && !udev->parent->parent) {
- rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum);
- if (!rc)
- rc = ehci_lpm_check(ehci, udev->portnum);
- }
- return rc;
-}
-
static const struct hc_driver vt8500_ehci_hc_driver = {
.description = hcd_name,
.product_desc = "VT8500 EHCI",
@@ -77,11 +61,6 @@ static const struct hc_driver vt8500_ehci_hc_driver = {
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
- /*
- * call back when device connected and addressed
- */
- .update_device = ehci_update_device,
-
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c
index ec598082c14..59e0e24c753 100644
--- a/drivers/usb/host/ehci-w90x900.c
+++ b/drivers/usb/host/ehci-w90x900.c
@@ -13,12 +13,12 @@
#include <linux/platform_device.h>
-/*ebable phy0 and phy1 for w90p910*/
+/* enable phy0 and phy1 for w90p910 */
#define ENPHY (0x01<<8)
#define PHY0_CTR (0xA4)
#define PHY1_CTR (0xA8)
-static int __devinit usb_w90x900_probe(const struct hc_driver *driver,
+static int usb_w90x900_probe(const struct hc_driver *driver,
struct platform_device *pdev)
{
struct usb_hcd *hcd;
@@ -147,7 +147,7 @@ static const struct hc_driver ehci_w90x900_hc_driver = {
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
-static int __devinit ehci_w90x900_probe(struct platform_device *pdev)
+static int ehci_w90x900_probe(struct platform_device *pdev)
{
if (usb_disabled())
return -ENODEV;
@@ -155,7 +155,7 @@ static int __devinit ehci_w90x900_probe(struct platform_device *pdev)
return usb_w90x900_probe(&ehci_w90x900_hc_driver, pdev);
}
-static int __devexit ehci_w90x900_remove(struct platform_device *pdev)
+static int ehci_w90x900_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
@@ -166,7 +166,7 @@ static int __devexit ehci_w90x900_remove(struct platform_device *pdev)
static struct platform_driver ehci_hcd_w90x900_driver = {
.probe = ehci_w90x900_probe,
- .remove = __devexit_p(ehci_w90x900_remove),
+ .remove = ehci_w90x900_remove,
.driver = {
.name = "w90x900-ehci",
.owner = THIS_MODULE,
diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c
index 6a3f921a5d7..4f285e8e404 100644
--- a/drivers/usb/host/ehci-xilinx-of.c
+++ b/drivers/usb/host/ehci-xilinx-of.c
@@ -125,7 +125,7 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = {
* as HS only or HS/FS only, it checks the configuration in the device tree
* entry, and sets an appropriate value for hcd->has_tt.
*/
-static int __devinit ehci_hcd_xilinx_of_probe(struct platform_device *op)
+static int ehci_hcd_xilinx_of_probe(struct platform_device *op)
{
struct device_node *dn = op->dev.of_node;
struct usb_hcd *hcd;
diff --git a/drivers/usb/host/ehci-xls.c b/drivers/usb/host/ehci-xls.c
deleted file mode 100644
index 8dc6a22d90b..00000000000
--- a/drivers/usb/host/ehci-xls.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * EHCI HCD for Netlogic XLS processors.
- *
- * (C) Copyright 2011 Netlogic Microsystems Inc.
- *
- * Based on various ehci-*.c drivers
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- */
-
-#include <linux/platform_device.h>
-
-static int ehci_xls_setup(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-
- ehci->caps = hcd->regs;
-
- return ehci_setup(hcd);
-}
-
-int ehci_xls_probe_internal(const struct hc_driver *driver,
- struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- struct resource *res;
- int retval, irq;
-
- /* Get our IRQ from an earlier registered Platform Resource */
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n",
- dev_name(&pdev->dev));
- return -ENODEV;
- }
-
- /* Get our Memory Handle */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "Error: MMIO Handle %s setup!\n",
- dev_name(&pdev->dev));
- return -ENODEV;
- }
- hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
- if (!hcd) {
- retval = -ENOMEM;
- goto err1;
- }
-
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
- driver->description)) {
- dev_dbg(&pdev->dev, "controller already in use\n");
- retval = -EBUSY;
- goto err2;
- }
- hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
-
- if (hcd->regs == NULL) {
- dev_dbg(&pdev->dev, "error mapping memory\n");
- retval = -EFAULT;
- goto err3;
- }
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval != 0)
- goto err4;
- return retval;
-
-err4:
- iounmap(hcd->regs);
-err3:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err2:
- usb_put_hcd(hcd);
-err1:
- dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev),
- retval);
- return retval;
-}
-
-static struct hc_driver ehci_xls_hc_driver = {
- .description = hcd_name,
- .product_desc = "XLS EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
- .irq = ehci_irq,
- .flags = HCD_USB2 | HCD_MEMORY,
- .reset = ehci_xls_setup,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
-
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
-
- .get_frame_number = ehci_get_frame,
-
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
-static int ehci_xls_probe(struct platform_device *pdev)
-{
- if (usb_disabled())
- return -ENODEV;
-
- return ehci_xls_probe_internal(&ehci_xls_hc_driver, pdev);
-}
-
-static int ehci_xls_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
- return 0;
-}
-
-MODULE_ALIAS("ehci-xls");
-
-static struct platform_driver ehci_xls_driver = {
- .probe = ehci_xls_probe,
- .remove = ehci_xls_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "ehci-xls",
- },
-};
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index da07d98f7d1..9dadc7118d6 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -143,7 +143,7 @@ struct ehci_hcd { /* one per controller */
struct ehci_qh *intr_unlink_last;
unsigned intr_unlink_cycle;
unsigned now_frame; /* frame from HC hardware */
- unsigned next_frame; /* scan periodic, start here */
+ unsigned last_iso_frame; /* last frame scanned for iso */
unsigned intr_count; /* intr activity count */
unsigned isoc_count; /* isoc activity count */
unsigned periodic_count; /* periodic activity count */
@@ -193,7 +193,6 @@ struct ehci_hcd { /* one per controller */
unsigned has_amcc_usb23:1;
unsigned need_io_watchdog:1;
unsigned amd_pll_fix:1;
- unsigned fs_i_thresh:1; /* Intel iso scheduling */
unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/
unsigned has_synopsys_hc_bug:1; /* Synopsys HC */
unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */
@@ -207,7 +206,6 @@ struct ehci_hcd { /* one per controller */
#define OHCI_HCCTRL_LEN 0x4
__hc32 *ohci_hcctrl_reg;
unsigned has_hostpc:1;
- unsigned has_lpm:1; /* support link power management */
unsigned has_ppcd:1; /* support per-port change bits */
u8 sbrn; /* packed release number */
@@ -762,26 +760,41 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x)
/*-------------------------------------------------------------------------*/
-#ifdef CONFIG_PCI
-
-/* For working around the MosChip frame-index-register bug */
-static unsigned ehci_read_frame_index(struct ehci_hcd *ehci);
-
+#define ehci_dbg(ehci, fmt, args...) \
+ dev_dbg(ehci_to_hcd(ehci)->self.controller , fmt , ## args)
+#define ehci_err(ehci, fmt, args...) \
+ dev_err(ehci_to_hcd(ehci)->self.controller , fmt , ## args)
+#define ehci_info(ehci, fmt, args...) \
+ dev_info(ehci_to_hcd(ehci)->self.controller , fmt , ## args)
+#define ehci_warn(ehci, fmt, args...) \
+ dev_warn(ehci_to_hcd(ehci)->self.controller , fmt , ## args)
+
+#ifdef VERBOSE_DEBUG
+# define ehci_vdbg ehci_dbg
#else
-
-static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
-{
- return ehci_readl(ehci, &ehci->regs->frame_index);
-}
-
+ static inline void ehci_vdbg(struct ehci_hcd *ehci, ...) {}
#endif
-/*-------------------------------------------------------------------------*/
-
#ifndef DEBUG
#define STUB_DEBUG_FILES
#endif /* DEBUG */
/*-------------------------------------------------------------------------*/
+/* Declarations of things exported for use by ehci platform drivers */
+
+struct ehci_driver_overrides {
+ size_t extra_priv_size;
+ int (*reset)(struct usb_hcd *hcd);
+};
+
+extern void ehci_init_driver(struct hc_driver *drv,
+ const struct ehci_driver_overrides *over);
+extern int ehci_setup(struct usb_hcd *hcd);
+
+#ifdef CONFIG_PM
+extern int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup);
+extern int ehci_resume(struct usb_hcd *hcd, bool hibernated);
+#endif /* CONFIG_PM */
+
#endif /* __LINUX_EHCI_HCD_H */
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c
index 7da1a26bed2..0b46542591f 100644
--- a/drivers/usb/host/fhci-hcd.c
+++ b/drivers/usb/host/fhci-hcd.c
@@ -561,7 +561,7 @@ static const struct hc_driver fhci_driver = {
.hub_control = fhci_hub_control,
};
-static int __devinit of_fhci_probe(struct platform_device *ofdev)
+static int of_fhci_probe(struct platform_device *ofdev)
{
struct device *dev = &ofdev->dev;
struct device_node *node = dev->of_node;
@@ -780,7 +780,7 @@ err_regs:
return ret;
}
-static int __devexit fhci_remove(struct device *dev)
+static int fhci_remove(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct fhci_hcd *fhci = hcd_to_fhci(hcd);
@@ -803,7 +803,7 @@ static int __devexit fhci_remove(struct device *dev)
return 0;
}
-static int __devexit of_fhci_remove(struct platform_device *ofdev)
+static int of_fhci_remove(struct platform_device *ofdev)
{
return fhci_remove(&ofdev->dev);
}
@@ -821,7 +821,7 @@ static struct platform_driver of_fhci_driver = {
.of_match_table = of_fhci_match,
},
.probe = of_fhci_probe,
- .remove = __devexit_p(of_fhci_remove),
+ .remove = of_fhci_remove,
};
module_platform_driver(of_fhci_driver);
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
index 1e771292383..5105127c1d4 100644
--- a/drivers/usb/host/fsl-mph-dr-of.c
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -24,7 +24,7 @@ struct fsl_usb2_dev_data {
enum fsl_usb2_operating_modes op_mode; /* operating mode */
};
-struct fsl_usb2_dev_data dr_mode_data[] __devinitdata = {
+struct fsl_usb2_dev_data dr_mode_data[] = {
{
.dr_mode = "host",
.drivers = { "fsl-ehci", NULL, NULL, },
@@ -42,7 +42,7 @@ struct fsl_usb2_dev_data dr_mode_data[] __devinitdata = {
},
};
-struct fsl_usb2_dev_data * __devinit get_dr_mode_data(struct device_node *np)
+struct fsl_usb2_dev_data *get_dr_mode_data(struct device_node *np)
{
const unsigned char *prop;
int i;
@@ -59,7 +59,7 @@ struct fsl_usb2_dev_data * __devinit get_dr_mode_data(struct device_node *np)
return &dr_mode_data[0]; /* mode not specified, use host */
}
-static enum fsl_usb2_phy_modes __devinit determine_usb_phy(const char *phy_type)
+static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
{
if (!phy_type)
return FSL_USB2_PHY_NONE;
@@ -75,7 +75,7 @@ static enum fsl_usb2_phy_modes __devinit determine_usb_phy(const char *phy_type)
return FSL_USB2_PHY_NONE;
}
-struct platform_device * __devinit fsl_usb2_device_register(
+struct platform_device *fsl_usb2_device_register(
struct platform_device *ofdev,
struct fsl_usb2_platform_data *pdata,
const char *name, int id)
@@ -154,7 +154,7 @@ static int usb_get_ver_info(struct device_node *np)
return ver;
}
-static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
+static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
{
struct device_node *np = ofdev->dev.of_node;
struct platform_device *usb_dev;
@@ -224,13 +224,13 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
return 0;
}
-static int __devexit __unregister_subdev(struct device *dev, void *d)
+static int __unregister_subdev(struct device *dev, void *d)
{
platform_device_unregister(to_platform_device(dev));
return 0;
}
-static int __devexit fsl_usb2_mph_dr_of_remove(struct platform_device *ofdev)
+static int fsl_usb2_mph_dr_of_remove(struct platform_device *ofdev)
{
device_for_each_child(&ofdev->dev, NULL, __unregister_subdev);
return 0;
@@ -336,7 +336,7 @@ static struct platform_driver fsl_usb2_mph_dr_driver = {
.of_match_table = fsl_usb2_mph_dr_of_match,
},
.probe = fsl_usb2_mph_dr_of_probe,
- .remove = __devexit_p(fsl_usb2_mph_dr_of_remove),
+ .remove = fsl_usb2_mph_dr_of_remove,
};
module_platform_driver(fsl_usb2_mph_dr_driver);
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c
index f19e2690c23..bd6a7447ccc 100644
--- a/drivers/usb/host/imx21-hcd.c
+++ b/drivers/usb/host/imx21-hcd.c
@@ -1680,7 +1680,7 @@ static int imx21_hc_reset(struct usb_hcd *hcd)
return 0;
}
-static int __devinit imx21_hc_start(struct usb_hcd *hcd)
+static int imx21_hc_start(struct usb_hcd *hcd)
{
struct imx21 *imx21 = hcd_to_imx21(hcd);
unsigned long flags;
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 9e65e3091c8..b64e661618b 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1557,7 +1557,7 @@ static int isp116x_remove(struct platform_device *pdev)
return 0;
}
-static int __devinit isp116x_probe(struct platform_device *pdev)
+static int isp116x_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct isp116x *isp116x;
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
index 256326322cf..974480c516f 100644
--- a/drivers/usb/host/isp1362-hcd.c
+++ b/drivers/usb/host/isp1362-hcd.c
@@ -2645,7 +2645,7 @@ static struct hc_driver isp1362_hc_driver = {
/*-------------------------------------------------------------------------*/
-static int __devexit isp1362_remove(struct platform_device *pdev)
+static int isp1362_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
@@ -2680,7 +2680,7 @@ static int __devexit isp1362_remove(struct platform_device *pdev)
return 0;
}
-static int __devinit isp1362_probe(struct platform_device *pdev)
+static int isp1362_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct isp1362_hcd *isp1362_hcd;
@@ -2856,7 +2856,7 @@ static int isp1362_resume(struct platform_device *pdev)
static struct platform_driver isp1362_driver = {
.probe = isp1362_probe,
- .remove = __devexit_p(isp1362_remove),
+ .remove = isp1362_remove,
.suspend = isp1362_suspend,
.resume = isp1362_resume,
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index fff114fd546..bbb791bd761 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -43,7 +43,6 @@ static int of_isp1760_probe(struct platform_device *dev)
struct device_node *dp = dev->dev.of_node;
struct resource *res;
struct resource memory;
- struct of_irq oirq;
int virq;
resource_size_t res_len;
int ret;
@@ -69,14 +68,12 @@ static int of_isp1760_probe(struct platform_device *dev)
goto free_data;
}
- if (of_irq_map_one(dp, 0, &oirq)) {
+ virq = irq_of_parse_and_map(dp, 0);
+ if (!virq) {
ret = -ENODEV;
goto release_reg;
}
- virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
- oirq.size);
-
if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
devflags |= ISP1760_FLAG_ISP1761;
@@ -175,7 +172,7 @@ static struct platform_driver isp1760_of_driver = {
#endif
#ifdef CONFIG_PCI
-static int __devinit isp1761_pci_probe(struct pci_dev *dev,
+static int isp1761_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
u8 latency, limit;
@@ -349,7 +346,7 @@ static struct pci_driver isp1761_pci_driver = {
};
#endif
-static int __devinit isp1760_plat_probe(struct platform_device *pdev)
+static int isp1760_plat_probe(struct platform_device *pdev)
{
int ret = 0;
struct usb_hcd *hcd;
@@ -416,7 +413,7 @@ out:
return ret;
}
-static int __devexit isp1760_plat_remove(struct platform_device *pdev)
+static int isp1760_plat_remove(struct platform_device *pdev)
{
struct resource *mem_res;
resource_size_t mem_size;
@@ -435,7 +432,7 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev)
static struct platform_driver isp1760_plat_driver = {
.probe = isp1760_plat_probe,
- .remove = __devexit_p(isp1760_plat_remove),
+ .remove = isp1760_plat_remove,
.driver = {
.name = "isp1760",
},
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 0bf72f943b0..221850a8c25 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -94,7 +94,7 @@ static void at91_stop_hc(struct platform_device *pdev)
/*-------------------------------------------------------------------------*/
-static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
+static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
@@ -108,7 +108,7 @@ static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_dev
* then invokes the start() method for the HCD associated with it
* through the hotplug entry's driver_data.
*/
-static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver,
+static int usb_hcd_at91_probe(const struct hc_driver *driver,
struct platform_device *pdev)
{
int retval;
@@ -203,7 +203,7 @@ static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver,
* context, "rmmod" or something similar.
*
*/
-static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd,
+static void usb_hcd_at91_remove(struct usb_hcd *hcd,
struct platform_device *pdev)
{
usb_remove_hcd(hcd);
@@ -222,7 +222,7 @@ static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd,
/*-------------------------------------------------------------------------*/
-static int __devinit
+static int
ohci_at91_reset (struct usb_hcd *hcd)
{
struct at91_usbh_data *board = hcd->self.controller->platform_data;
@@ -236,7 +236,7 @@ ohci_at91_reset (struct usb_hcd *hcd)
return 0;
}
-static int __devinit
+static int
ohci_at91_start (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
@@ -506,7 +506,7 @@ MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids);
static u64 at91_ohci_dma_mask = DMA_BIT_MASK(32);
-static int __devinit ohci_at91_of_init(struct platform_device *pdev)
+static int ohci_at91_of_init(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
int i, gpio;
@@ -548,7 +548,7 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev)
return 0;
}
#else
-static int __devinit ohci_at91_of_init(struct platform_device *pdev)
+static int ohci_at91_of_init(struct platform_device *pdev)
{
return 0;
}
@@ -556,7 +556,7 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev)
/*-------------------------------------------------------------------------*/
-static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev)
+static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
{
struct at91_usbh_data *pdata;
int i;
@@ -641,7 +641,7 @@ static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev)
return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
}
-static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev)
+static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
{
struct at91_usbh_data *pdata = pdev->dev.platform_data;
int i;
@@ -705,7 +705,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
if (!clocked)
at91_start_clock();
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
#else
@@ -717,7 +717,7 @@ MODULE_ALIAS("platform:at91_ohci");
static struct platform_driver ohci_hcd_at91_driver = {
.probe = ohci_hcd_at91_drv_probe,
- .remove = __devexit_p(ohci_hcd_at91_drv_remove),
+ .remove = ohci_hcd_at91_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
.suspend = ohci_hcd_at91_drv_suspend,
.resume = ohci_hcd_at91_drv_resume,
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
deleted file mode 100644
index c611699b4aa..00000000000
--- a/drivers/usb/host/ohci-au1xxx.c
+++ /dev/null
@@ -1,234 +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 AMD Alchemy Au1xxx
- *
- * 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 AMD Alchemy Au1xxx
- * by Matt Porter <mporter@kernel.crashing.org>
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/platform_device.h>
-#include <linux/signal.h>
-
-#include <asm/mach-au1x00/au1000.h>
-
-
-extern int usb_disabled(void);
-
-static int __devinit ohci_au1xxx_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int ret;
-
- ohci_dbg(ohci, "ohci_au1xxx_start, ohci:%p", ohci);
-
- 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_au1xxx_hc_driver = {
- .description = hcd_name,
- .product_desc = "Au1xxx OHCI",
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .start = ohci_au1xxx_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_au1xxx_drv_probe(struct platform_device *pdev)
-{
- int ret, unit;
- struct usb_hcd *hcd;
-
- if (usb_disabled())
- return -ENODEV;
-
- if (pdev->resource[1].flags != IORESOURCE_IRQ) {
- pr_debug("resource[1] is not IORESOURCE_IRQ\n");
- return -ENOMEM;
- }
-
- hcd = usb_create_hcd(&ohci_au1xxx_hc_driver, &pdev->dev, "au1xxx");
- if (!hcd)
- return -ENOMEM;
-
- hcd->rsrc_start = pdev->resource[0].start;
- hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- pr_debug("request_mem_region failed\n");
- ret = -EBUSY;
- goto err1;
- }
-
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- pr_debug("ioremap failed\n");
- ret = -ENOMEM;
- goto err2;
- }
-
- unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ?
- ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
- if (alchemy_usb_control(unit, 1)) {
- printk(KERN_INFO "%s: controller init failed!\n", pdev->name);
- ret = -ENODEV;
- goto err3;
- }
-
- ohci_hcd_init(hcd_to_ohci(hcd));
-
- ret = usb_add_hcd(hcd, pdev->resource[1].start,
- IRQF_SHARED);
- if (ret == 0) {
- platform_set_drvdata(pdev, hcd);
- return ret;
- }
-
- alchemy_usb_control(unit, 0);
-err3:
- iounmap(hcd->regs);
-err2:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err1:
- usb_put_hcd(hcd);
- return ret;
-}
-
-static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
- int unit;
-
- unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ?
- ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
- usb_remove_hcd(hcd);
- alchemy_usb_control(unit, 0);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int ohci_hcd_au1xxx_drv_suspend(struct device *dev)
-{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- unsigned long flags;
- int rc;
-
- rc = 0;
-
- /* Root hub was already suspended. Disable irq emission and
- * mark HW unaccessible, bail out if RH has been resumed. Use
- * the spinlock to properly synchronize with possible pending
- * RH suspend or resume activity.
- */
- spin_lock_irqsave(&ohci->lock, flags);
- if (ohci->rh_state != OHCI_RH_SUSPENDED) {
- rc = -EINVAL;
- goto bail;
- }
- ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
- (void)ohci_readl(ohci, &ohci->regs->intrdisable);
-
- clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
- alchemy_usb_control(ALCHEMY_USB_OHCI0, 0);
-bail:
- spin_unlock_irqrestore(&ohci->lock, flags);
-
- return rc;
-}
-
-static int ohci_hcd_au1xxx_drv_resume(struct device *dev)
-{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
-
- alchemy_usb_control(ALCHEMY_USB_OHCI0, 1);
-
- set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
- ohci_finish_controller_resume(hcd);
-
- return 0;
-}
-
-static const struct dev_pm_ops au1xxx_ohci_pmops = {
- .suspend = ohci_hcd_au1xxx_drv_suspend,
- .resume = ohci_hcd_au1xxx_drv_resume,
-};
-
-#define AU1XXX_OHCI_PMOPS &au1xxx_ohci_pmops
-
-#else
-#define AU1XXX_OHCI_PMOPS NULL
-#endif
-
-static struct platform_driver ohci_hcd_au1xxx_driver = {
- .probe = ohci_hcd_au1xxx_drv_probe,
- .remove = ohci_hcd_au1xxx_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "au1xxx-ohci",
- .owner = THIS_MODULE,
- .pm = AU1XXX_OHCI_PMOPS,
- },
-};
-
-MODULE_ALIAS("platform:au1xxx-ohci");
diff --git a/drivers/usb/host/ohci-cns3xxx.c b/drivers/usb/host/ohci-cns3xxx.c
deleted file mode 100644
index 2c9f233047b..00000000000
--- a/drivers/usb/host/ohci-cns3xxx.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright 2008 Cavium Networks
- *
- * This file 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/platform_device.h>
-#include <linux/atomic.h>
-#include <mach/cns3xxx.h>
-#include <mach/pm.h>
-
-static int __devinit
-cns3xxx_ohci_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int ret;
-
- /*
- * EHCI and OHCI share the same clock and power,
- * resetting twice would cause the 1st controller been reset.
- * Therefore only do power up at the first up device, and
- * power down at the last down device.
- *
- * Set USB AHB INCR length to 16
- */
- if (atomic_inc_return(&usb_pwr_ref) == 1) {
- cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
- cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
- cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
- __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
- MISC_CHIP_CONFIG_REG);
- }
-
- ret = ohci_init(ohci);
- if (ret < 0)
- return ret;
-
- ohci->num_ports = 1;
-
- 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 cns3xxx_ohci_hc_driver = {
- .description = hcd_name,
- .product_desc = "CNS3XXX OHCI Host controller",
- .hcd_priv_size = sizeof(struct ohci_hcd),
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
- .start = cns3xxx_ohci_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 cns3xxx_ohci_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct usb_hcd *hcd;
- const struct hc_driver *driver = &cns3xxx_ohci_hc_driver;
- struct resource *res;
- int irq;
- int retval;
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(dev, "Found HC with no IRQ.\n");
- return -ENODEV;
- }
- irq = res->start;
-
- hcd = usb_create_hcd(driver, dev, dev_name(dev));
- if (!hcd)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(dev, "Found HC with no register addr.\n");
- retval = -ENODEV;
- goto err1;
- }
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
- driver->description)) {
- dev_dbg(dev, "controller already in use\n");
- retval = -EBUSY;
- goto err1;
- }
-
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- dev_dbg(dev, "error mapping memory\n");
- retval = -EFAULT;
- goto err2;
- }
-
- ohci_hcd_init(hcd_to_ohci(hcd));
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval == 0)
- return retval;
-
- iounmap(hcd->regs);
-err2:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err1:
- usb_put_hcd(hcd);
- return retval;
-}
-
-static int cns3xxx_ohci_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-
- /*
- * EHCI and OHCI share the same clock and power,
- * resetting twice would cause the 1st controller been reset.
- * Therefore only do power up at the first up device, and
- * power down at the last down device.
- */
- if (atomic_dec_return(&usb_pwr_ref) == 0)
- cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
-
- usb_put_hcd(hcd);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-MODULE_ALIAS("platform:cns3xxx-ohci");
-
-static struct platform_driver ohci_hcd_cns3xxx_driver = {
- .probe = cns3xxx_ohci_probe,
- .remove = cns3xxx_ohci_remove,
- .driver = {
- .name = "cns3xxx-ohci",
- },
-};
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
index dbfbd1dfd2e..8704e9fa5a8 100644
--- a/drivers/usb/host/ohci-ep93xx.c
+++ b/drivers/usb/host/ohci-ep93xx.c
@@ -107,7 +107,7 @@ static void usb_hcd_ep93xx_remove(struct usb_hcd *hcd,
usb_put_hcd(hcd);
}
-static int __devinit ohci_ep93xx_start(struct usb_hcd *hcd)
+static int ohci_ep93xx_start(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int ret;
@@ -194,7 +194,7 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev)
ep93xx_start_hc(&pdev->dev);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
#endif
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index 20a50081f92..aa3b8844bb9 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -23,6 +23,11 @@ struct exynos_ohci_hcd {
struct clk *clk;
};
+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);
@@ -30,10 +35,6 @@ static int ohci_exynos_start(struct usb_hcd *hcd)
ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci);
- 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",
@@ -53,6 +54,7 @@ static const struct hc_driver exynos_ohci_hc_driver = {
.irq = ohci_irq,
.flags = HCD_MEMORY|HCD_USB11,
+ .reset = ohci_exynos_reset,
.start = ohci_exynos_start,
.stop = ohci_stop,
.shutdown = ohci_shutdown,
@@ -74,7 +76,7 @@ static const struct hc_driver exynos_ohci_hc_driver = {
static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32);
-static int __devinit exynos_ohci_probe(struct platform_device *pdev)
+static int exynos_ohci_probe(struct platform_device *pdev)
{
struct exynos4_ohci_platdata *pdata;
struct exynos_ohci_hcd *exynos_ohci;
@@ -115,7 +117,7 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev)
}
exynos_ohci->hcd = hcd;
- exynos_ohci->clk = clk_get(&pdev->dev, "usbhost");
+ exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");
if (IS_ERR(exynos_ohci->clk)) {
dev_err(&pdev->dev, "Failed to get usbhost clock\n");
@@ -123,9 +125,9 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev)
goto fail_clk;
}
- err = clk_enable(exynos_ohci->clk);
+ err = clk_prepare_enable(exynos_ohci->clk);
if (err)
- goto fail_clken;
+ goto fail_clk;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
@@ -167,15 +169,13 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev)
return 0;
fail_io:
- clk_disable(exynos_ohci->clk);
-fail_clken:
- clk_put(exynos_ohci->clk);
+ clk_disable_unprepare(exynos_ohci->clk);
fail_clk:
usb_put_hcd(hcd);
return err;
}
-static int __devexit exynos_ohci_remove(struct platform_device *pdev)
+static int exynos_ohci_remove(struct platform_device *pdev)
{
struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
@@ -186,8 +186,7 @@ static int __devexit exynos_ohci_remove(struct platform_device *pdev)
if (pdata && pdata->phy_exit)
pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
- clk_disable(exynos_ohci->clk);
- clk_put(exynos_ohci->clk);
+ clk_disable_unprepare(exynos_ohci->clk);
usb_put_hcd(hcd);
@@ -232,7 +231,7 @@ static int exynos_ohci_suspend(struct device *dev)
if (pdata && pdata->phy_exit)
pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
- clk_disable(exynos_ohci->clk);
+ clk_disable_unprepare(exynos_ohci->clk);
fail:
spin_unlock_irqrestore(&ohci->lock, flags);
@@ -247,15 +246,12 @@ static int exynos_ohci_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
- clk_enable(exynos_ohci->clk);
+ clk_prepare_enable(exynos_ohci->clk);
if (pdata && pdata->phy_init)
pdata->phy_init(pdev, S5P_USB_PHY_HOST);
- /* Mark hardware accessible again as we are out of D3 state by now */
- set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
@@ -279,7 +275,7 @@ MODULE_DEVICE_TABLE(of, exynos_ohci_match);
static struct platform_driver exynos_ohci_driver = {
.probe = exynos_ohci_probe,
- .remove = __devexit_p(exynos_ohci_remove),
+ .remove = exynos_ohci_remove,
.shutdown = exynos_ohci_shutdown,
.driver = {
.name = "exynos-ohci",
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 4a1d64d9233..180a2b01db5 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -231,13 +231,41 @@ static int ohci_urb_enqueue (
frame &= ~(ed->interval - 1);
frame |= ed->branch;
urb->start_frame = frame;
+ }
+ } else if (ed->type == PIPE_ISOCHRONOUS) {
+ u16 next = ohci_frame_no(ohci) + 2;
+ u16 frame = ed->last_iso + ed->interval;
+
+ /* Behind the scheduling threshold? */
+ if (unlikely(tick_before(frame, next))) {
- /* yes, only URB_ISO_ASAP is supported, and
- * urb->start_frame is never used as input.
+ /* USB_ISO_ASAP: Round up to the first available slot */
+ if (urb->transfer_flags & URB_ISO_ASAP)
+ frame += (next - frame + ed->interval - 1) &
+ -ed->interval;
+
+ /*
+ * Not ASAP: Use the next slot in the stream. If
+ * the entire URB falls before the threshold, fail.
*/
+ else if (tick_before(frame + ed->interval *
+ (urb->number_of_packets - 1), next)) {
+ retval = -EXDEV;
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
+ goto fail;
+ }
+
+ /*
+ * Some OHCI hardware doesn't handle late TDs
+ * correctly. After retiring them it proceeds to
+ * the next ED instead of the next TD. Therefore
+ * we have to omit the late TDs entirely.
+ */
+ urb_priv->td_cnt = DIV_ROUND_UP(next - frame,
+ ed->interval);
}
- } else if (ed->type == PIPE_ISOCHRONOUS)
- urb->start_frame = ed->last_iso + ed->interval;
+ urb->start_frame = frame;
+ }
/* fill the TDs and link them to the ed; and
* enable that part of the schedule, if needed
@@ -983,6 +1011,79 @@ static int ohci_restart (struct ohci_hcd *ohci)
#endif
+#ifdef CONFIG_PM
+
+static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+ unsigned long flags;
+
+ /* Disable irq emission and mark HW unaccessible. Use
+ * the spinlock to properly synchronize with possible pending
+ * RH suspend or resume activity.
+ */
+ spin_lock_irqsave (&ohci->lock, flags);
+ ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
+ (void)ohci_readl(ohci, &ohci->regs->intrdisable);
+
+ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+ spin_unlock_irqrestore (&ohci->lock, flags);
+
+ return 0;
+}
+
+
+static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ int port;
+ bool need_reinit = false;
+
+ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+ /* Make sure resume from hibernation re-enumerates everything */
+ if (hibernated)
+ ohci_usb_reset(ohci);
+
+ /* See if the controller is already running or has been reset */
+ ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
+ if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
+ need_reinit = true;
+ } else {
+ switch (ohci->hc_control & OHCI_CTRL_HCFS) {
+ case OHCI_USB_OPER:
+ case OHCI_USB_RESET:
+ need_reinit = true;
+ }
+ }
+
+ /* If needed, reinitialize and suspend the root hub */
+ if (need_reinit) {
+ spin_lock_irq(&ohci->lock);
+ ohci_rh_resume(ohci);
+ ohci_rh_suspend(ohci, 0);
+ spin_unlock_irq(&ohci->lock);
+ }
+
+ /* Normally just turn on port power and enable interrupts */
+ else {
+ ohci_dbg(ohci, "powerup ports\n");
+ for (port = 0; port < ohci->num_ports; port++)
+ ohci_writel(ohci, RH_PS_PPS,
+ &ohci->regs->roothub.portstatus[port]);
+
+ ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable);
+ ohci_readl(ohci, &ohci->regs->intrenable);
+ msleep(20);
+ }
+
+ usb_hcd_resume_root_hub(hcd);
+
+ return 0;
+}
+
+#endif
+
/*-------------------------------------------------------------------------*/
MODULE_AUTHOR (DRIVER_AUTHOR);
@@ -1029,21 +1130,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_hcd_ep93xx_driver
#endif
-#ifdef CONFIG_MIPS_ALCHEMY
-#include "ohci-au1xxx.c"
-#define PLATFORM_DRIVER ohci_hcd_au1xxx_driver
-#endif
-
-#ifdef CONFIG_PNX8550
-#include "ohci-pnx8550.c"
-#define PLATFORM_DRIVER ohci_hcd_pnx8550_driver
-#endif
-
-#ifdef CONFIG_USB_OHCI_HCD_PPC_SOC
-#include "ohci-ppc-soc.c"
-#define PLATFORM_DRIVER ohci_hcd_ppc_soc_driver
-#endif
-
#ifdef CONFIG_ARCH_AT91
#include "ohci-at91.c"
#define PLATFORM_DRIVER ohci_hcd_at91_driver
@@ -1059,11 +1145,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_hcd_da8xx_driver
#endif
-#ifdef CONFIG_USB_OHCI_SH
-#include "ohci-sh.c"
-#define PLATFORM_DRIVER ohci_hcd_sh_driver
-#endif
-
#ifdef CONFIG_USB_OHCI_HCD_PPC_OF
#include "ohci-ppc-of.c"
@@ -1105,16 +1186,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_hcd_tilegx_driver
#endif
-#ifdef CONFIG_USB_CNS3XXX_OHCI
-#include "ohci-cns3xxx.c"
-#define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver
-#endif
-
-#ifdef CONFIG_CPU_XLR
-#include "ohci-xls.c"
-#define PLATFORM_DRIVER ohci_xls_driver
-#endif
-
#ifdef CONFIG_USB_OHCI_HCD_PLATFORM
#include "ohci-platform.c"
#define PLATFORM_DRIVER ohci_platform_driver
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 2f3619eefef..db09dae7b55 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -316,48 +316,6 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
return rc;
}
-/* Carry out the final steps of resuming the controller device */
-static void __maybe_unused ohci_finish_controller_resume(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int port;
- bool need_reinit = false;
-
- /* See if the controller is already running or has been reset */
- ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
- if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
- need_reinit = true;
- } else {
- switch (ohci->hc_control & OHCI_CTRL_HCFS) {
- case OHCI_USB_OPER:
- case OHCI_USB_RESET:
- need_reinit = true;
- }
- }
-
- /* If needed, reinitialize and suspend the root hub */
- if (need_reinit) {
- spin_lock_irq(&ohci->lock);
- ohci_rh_resume(ohci);
- ohci_rh_suspend(ohci, 0);
- spin_unlock_irq(&ohci->lock);
- }
-
- /* Normally just turn on port power and enable interrupts */
- else {
- ohci_dbg(ohci, "powerup ports\n");
- for (port = 0; port < ohci->num_ports; port++)
- ohci_writel(ohci, RH_PS_PPS,
- &ohci->regs->roothub.portstatus[port]);
-
- ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable);
- ohci_readl(ohci, &ohci->regs->intrenable);
- msleep(20);
- }
-
- usb_hcd_resume_root_hub(hcd);
-}
-
/* Carry out polling-, autostop-, and autoresume-related state changes */
static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
int any_connected, int rhsc_status)
diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c
index 931d588c3fb..8062bb9dea1 100644
--- a/drivers/usb/host/ohci-jz4740.c
+++ b/drivers/usb/host/ohci-jz4740.c
@@ -145,7 +145,7 @@ static const struct hc_driver ohci_jz4740_hc_driver = {
};
-static __devinit int jz4740_ohci_probe(struct platform_device *pdev)
+static int jz4740_ohci_probe(struct platform_device *pdev)
{
int ret;
struct usb_hcd *hcd;
@@ -239,7 +239,7 @@ err_free:
return ret;
}
-static __devexit int jz4740_ohci_remove(struct platform_device *pdev)
+static int jz4740_ohci_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct jz4740_ohci_hcd *jz4740_ohci = hcd_to_jz4740_hcd(hcd);
@@ -266,7 +266,7 @@ static __devexit int jz4740_ohci_remove(struct platform_device *pdev)
static struct platform_driver ohci_hcd_jz4740_driver = {
.probe = jz4740_ohci_probe,
- .remove = __devexit_p(jz4740_ohci_remove),
+ .remove = jz4740_ohci_remove,
.driver = {
.name = "jz4740-ohci",
.owner = THIS_MODULE,
diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c
index e068f034cb9..2344040c16d 100644
--- a/drivers/usb/host/ohci-nxp.c
+++ b/drivers/usb/host/ohci-nxp.c
@@ -147,7 +147,7 @@ static void nxp_stop_hc(void)
__raw_writel(tmp, USB_OTG_STAT_CONTROL);
}
-static int __devinit ohci_nxp_start(struct usb_hcd *hcd)
+static int ohci_nxp_start(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int ret;
@@ -205,7 +205,7 @@ static const struct hc_driver ohci_nxp_hc_driver = {
.start_port_reset = ohci_start_port_reset,
};
-static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev)
+static int usb_hcd_nxp_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd = 0;
struct ohci_hcd *ohci;
diff --git a/drivers/usb/host/ohci-octeon.c b/drivers/usb/host/ohci-octeon.c
index d469bf9b9e5..d44430d009f 100644
--- a/drivers/usb/host/ohci-octeon.c
+++ b/drivers/usb/host/ohci-octeon.c
@@ -42,7 +42,7 @@ static void ohci_octeon_hw_stop(void)
octeon2_usb_clocks_stop();
}
-static int __devinit ohci_octeon_start(struct usb_hcd *hcd)
+static int ohci_octeon_start(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int ret;
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 4531d03503c..733c77c3635 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -530,7 +530,7 @@ static int ohci_omap_resume(struct platform_device *dev)
ohci->next_statechange = jiffies;
omap_ohci_clock_power(1);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index 1b8133b6e45..4382af3a45f 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -125,7 +125,7 @@ static const struct hc_driver ohci_omap3_hc_driver = {
* then invokes the start() method for the HCD associated with it
* through the hotplug entry's driver_data.
*/
-static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev)
+static int ohci_hcd_omap3_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct usb_hcd *hcd = NULL;
@@ -209,7 +209,7 @@ err_io:
* the HCD's stop() method. It is always called from a thread
* context, normally "rmmod", "apmd", or something similar.
*/
-static int __devexit ohci_hcd_omap3_remove(struct platform_device *pdev)
+static int ohci_hcd_omap3_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct usb_hcd *hcd = dev_get_drvdata(dev);
@@ -232,7 +232,7 @@ static void ohci_hcd_omap3_shutdown(struct platform_device *pdev)
static struct platform_driver ohci_hcd_omap3_driver = {
.probe = ohci_hcd_omap3_probe,
- .remove = __devexit_p(ohci_hcd_omap3_remove),
+ .remove = ohci_hcd_omap3_remove,
.shutdown = ohci_hcd_omap3_shutdown,
.driver = {
.name = "ohci-omap3",
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 1843bb68ac7..951514ef446 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -270,7 +270,7 @@ static int ohci_pci_reset (struct usb_hcd *hcd)
}
-static int __devinit ohci_pci_start (struct usb_hcd *hcd)
+static int ohci_pci_start (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int ret;
@@ -296,49 +296,6 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd)
return ret;
}
-#ifdef CONFIG_PM
-
-static int ohci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
-{
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- unsigned long flags;
- int rc = 0;
-
- /* Root hub was already suspended. Disable irq emission and
- * mark HW unaccessible, bail out if RH has been resumed. Use
- * the spinlock to properly synchronize with possible pending
- * RH suspend or resume activity.
- */
- spin_lock_irqsave (&ohci->lock, flags);
- if (ohci->rh_state != OHCI_RH_SUSPENDED) {
- rc = -EINVAL;
- goto bail;
- }
- ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
- (void)ohci_readl(ohci, &ohci->regs->intrdisable);
-
- clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
- bail:
- spin_unlock_irqrestore (&ohci->lock, flags);
-
- return rc;
-}
-
-
-static int ohci_pci_resume(struct usb_hcd *hcd, bool hibernated)
-{
- set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
- /* Make sure resume from hibernation re-enumerates everything */
- if (hibernated)
- ohci_usb_reset(hcd_to_ohci(hcd));
-
- ohci_finish_controller_resume(hcd);
- return 0;
-}
-
-#endif /* CONFIG_PM */
-
/*-------------------------------------------------------------------------*/
@@ -362,8 +319,8 @@ static const struct hc_driver ohci_pci_hc_driver = {
.shutdown = ohci_shutdown,
#ifdef CONFIG_PM
- .pci_suspend = ohci_pci_suspend,
- .pci_resume = ohci_pci_resume,
+ .pci_suspend = ohci_suspend,
+ .pci_resume = ohci_resume,
#endif
/*
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index e24ec9f7916..084503b03fc 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -31,6 +31,10 @@ static int ohci_platform_reset(struct usb_hcd *hcd)
ohci->flags |= OHCI_QUIRK_FRAME_NO;
ohci_hcd_init(ohci);
+
+ if (pdata->num_ports)
+ ohci->num_ports = pdata->num_ports;
+
err = ohci_init(ohci);
return err;
@@ -79,7 +83,7 @@ static const struct hc_driver ohci_platform_hc_driver = {
.start_port_reset = ohci_start_port_reset,
};
-static int __devinit ohci_platform_probe(struct platform_device *dev)
+static int ohci_platform_probe(struct platform_device *dev)
{
struct usb_hcd *hcd;
struct resource *res_mem;
@@ -97,13 +101,13 @@ static int __devinit ohci_platform_probe(struct platform_device *dev)
irq = platform_get_irq(dev, 0);
if (irq < 0) {
- pr_err("no irq provided");
+ dev_err(&dev->dev, "no irq provided");
return irq;
}
res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!res_mem) {
- pr_err("no memory recourse provided");
+ dev_err(&dev->dev, "no memory resource provided");
return -ENXIO;
}
@@ -123,29 +127,19 @@ static int __devinit ohci_platform_probe(struct platform_device *dev)
hcd->rsrc_start = res_mem->start;
hcd->rsrc_len = resource_size(res_mem);
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- pr_err("controller already in use");
- err = -EBUSY;
- goto err_put_hcd;
- }
-
- hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
+ hcd->regs = devm_request_and_ioremap(&dev->dev, res_mem);
if (!hcd->regs) {
err = -ENOMEM;
- goto err_release_region;
+ goto err_put_hcd;
}
err = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (err)
- goto err_iounmap;
+ goto err_put_hcd;
platform_set_drvdata(dev, hcd);
return err;
-err_iounmap:
- iounmap(hcd->regs);
-err_release_region:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err_put_hcd:
usb_put_hcd(hcd);
err_power:
@@ -155,14 +149,12 @@ err_power:
return err;
}
-static int __devexit ohci_platform_remove(struct platform_device *dev)
+static int ohci_platform_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
struct usb_ohci_pdata *pdata = dev->dev.platform_data;
usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
platform_set_drvdata(dev, NULL);
@@ -199,7 +191,7 @@ static int ohci_platform_resume(struct device *dev)
return err;
}
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
@@ -222,7 +214,7 @@ static const struct dev_pm_ops ohci_platform_pm_ops = {
static struct platform_driver ohci_platform_driver = {
.id_table = ohci_platform_table,
.probe = ohci_platform_probe,
- .remove = __devexit_p(ohci_platform_remove),
+ .remove = ohci_platform_remove,
.shutdown = usb_hcd_platform_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c
deleted file mode 100644
index 148d27d6a67..00000000000
--- a/drivers/usb/host/ohci-pnx8550.c
+++ /dev/null
@@ -1,243 +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
- * (C) Copyright 2005 Embedded Alley Solutions, Inc.
- *
- * Bus Glue for PNX8550
- *
- * 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 PNX8550 from ohci-sa1111.c and sa-omap.c
- * by Vitaly Wool <vitalywool@gmail.com>
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <asm/mach-pnx8550/usb.h>
-#include <asm/mach-pnx8550/int.h>
-#include <asm/mach-pnx8550/pci.h>
-
-#ifndef CONFIG_PNX8550
-#error "This file is PNX8550 bus glue. CONFIG_PNX8550 must be defined."
-#endif
-
-extern int usb_disabled(void);
-
-/*-------------------------------------------------------------------------*/
-
-static void pnx8550_start_hc(struct platform_device *dev)
-{
- /*
- * Set register CLK48CTL to enable and 48MHz
- */
- outl(0x00000003, PCI_BASE | 0x0004770c);
-
- /*
- * Set register CLK12CTL to enable and 48MHz
- */
- outl(0x00000003, PCI_BASE | 0x00047710);
-
- udelay(100);
-}
-
-static void pnx8550_stop_hc(struct platform_device *dev)
-{
- udelay(10);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* configure so an HC device and id are always provided */
-/* always called with process context; sleeping is OK */
-
-
-/**
- * usb_hcd_pnx8550_probe - initialize pnx8550-based HCDs
- * Context: !in_interrupt()
- *
- * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- *
- */
-int usb_hcd_pnx8550_probe (const struct hc_driver *driver,
- struct platform_device *dev)
-{
- int retval;
- struct usb_hcd *hcd;
-
- if (dev->resource[0].flags != IORESOURCE_MEM ||
- dev->resource[1].flags != IORESOURCE_IRQ) {
- dev_err (&dev->dev,"invalid resource type\n");
- return -ENOMEM;
- }
-
- hcd = usb_create_hcd (driver, &dev->dev, "pnx8550");
- if (!hcd)
- return -ENOMEM;
- hcd->rsrc_start = dev->resource[0].start;
- hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- dev_err(&dev->dev, "request_mem_region [0x%08llx, 0x%08llx] "
- "failed\n", hcd->rsrc_start, hcd->rsrc_len);
- retval = -EBUSY;
- goto err1;
- }
-
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- dev_err(&dev->dev, "ioremap [[0x%08llx, 0x%08llx] failed\n",
- hcd->rsrc_start, hcd->rsrc_len);
- retval = -ENOMEM;
- goto err2;
- }
-
- pnx8550_start_hc(dev);
-
- ohci_hcd_init(hcd_to_ohci(hcd));
-
- retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
- if (retval == 0)
- return retval;
-
- pnx8550_stop_hc(dev);
- iounmap(hcd->regs);
- err2:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- err1:
- usb_put_hcd(hcd);
- return retval;
-}
-
-
-/* may be called without controller electrically present */
-/* may be called with controller, bus, and devices active */
-
-/**
- * usb_hcd_pnx8550_remove - shutdown processing for pnx8550-based HCDs
- * @dev: USB Host Controller being removed
- * Context: !in_interrupt()
- *
- * Reverses the effect of usb_hcd_pnx8550_probe(), first invoking
- * the HCD's stop() method. It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
- *
- */
-void usb_hcd_pnx8550_remove (struct usb_hcd *hcd, struct platform_device *dev)
-{
- usb_remove_hcd(hcd);
- pnx8550_stop_hc(dev);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int __devinit
-ohci_pnx8550_start (struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- int ret;
-
- ohci_dbg (ohci, "ohci_pnx8550_start, ohci:%p", ohci);
-
- 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_pnx8550_hc_driver = {
- .description = hcd_name,
- .product_desc = "PNX8550 OHCI",
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .start = ohci_pnx8550_start,
- .stop = ohci_stop,
-
- /*
- * 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_pnx8550_drv_probe(struct platform_device *pdev)
-{
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- ret = usb_hcd_pnx8550_probe(&ohci_pnx8550_hc_driver, pdev);
- return ret;
-}
-
-static int ohci_hcd_pnx8550_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_hcd_pnx8550_remove(hcd, pdev);
- return 0;
-}
-
-MODULE_ALIAS("platform:pnx8550-ohci");
-
-static struct platform_driver ohci_hcd_pnx8550_driver = {
- .driver = {
- .name = "pnx8550-ohci",
- .owner = THIS_MODULE,
- },
- .probe = ohci_hcd_pnx8550_drv_probe,
- .remove = ohci_hcd_pnx8550_drv_remove,
-};
-
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c
index e27d5ae2b9e..64c2ed9ff95 100644
--- a/drivers/usb/host/ohci-ppc-of.c
+++ b/drivers/usb/host/ohci-ppc-of.c
@@ -19,7 +19,7 @@
#include <asm/prom.h>
-static int __devinit
+static int
ohci_ppc_of_start(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
@@ -81,7 +81,7 @@ static const struct hc_driver ohci_ppc_of_hc_driver = {
};
-static int __devinit ohci_hcd_ppc_of_probe(struct platform_device *op)
+static int ohci_hcd_ppc_of_probe(struct platform_device *op)
{
struct device_node *dn = op->dev.of_node;
struct usb_hcd *hcd;
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
deleted file mode 100644
index 185c39ed81b..00000000000
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ /dev/null
@@ -1,216 +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
- * (C) Copyright 2003-2005 MontaVista Software Inc.
- *
- * Bus Glue for PPC On-Chip OHCI driver
- * Tested on Freescale MPC5200 and IBM STB04xxx
- *
- * Modified by Dale Farnsworth <dale@farnsworth.org> from ohci-sa1111.c
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/platform_device.h>
-#include <linux/signal.h>
-
-/* configure so an HC device and id are always provided */
-/* always called with process context; sleeping is OK */
-
-/**
- * usb_hcd_ppc_soc_probe - initialize On-Chip HCDs
- * Context: !in_interrupt()
- *
- * Allocates basic resources for this USB host controller.
- *
- * Store this function in the HCD's struct pci_driver as probe().
- */
-static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
- struct platform_device *pdev)
-{
- int retval;
- struct usb_hcd *hcd;
- struct ohci_hcd *ohci;
- struct resource *res;
- int irq;
-
- pr_debug("initializing PPC-SOC USB Controller\n");
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- pr_debug("%s: no irq\n", __FILE__);
- return -ENODEV;
- }
- irq = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- pr_debug("%s: no reg addr\n", __FILE__);
- return -ENODEV;
- }
-
- hcd = usb_create_hcd(driver, &pdev->dev, "PPC-SOC USB");
- if (!hcd)
- return -ENOMEM;
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- pr_debug("%s: request_mem_region failed\n", __FILE__);
- retval = -EBUSY;
- goto err1;
- }
-
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- pr_debug("%s: ioremap failed\n", __FILE__);
- retval = -ENOMEM;
- goto err2;
- }
-
- ohci = hcd_to_ohci(hcd);
- ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC;
-
-#ifdef CONFIG_PPC_MPC52xx
- /* MPC52xx doesn't need frame_no shift */
- ohci->flags |= OHCI_QUIRK_FRAME_NO;
-#endif
- ohci_hcd_init(ohci);
-
- retval = usb_add_hcd(hcd, irq, 0);
- if (retval == 0)
- return retval;
-
- pr_debug("Removing PPC-SOC USB Controller\n");
-
- iounmap(hcd->regs);
- err2:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- err1:
- usb_put_hcd(hcd);
- return retval;
-}
-
-
-/* may be called without controller electrically present */
-/* may be called with controller, bus, and devices active */
-
-/**
- * usb_hcd_ppc_soc_remove - shutdown processing for On-Chip HCDs
- * @pdev: USB Host Controller being removed
- * Context: !in_interrupt()
- *
- * Reverses the effect of usb_hcd_ppc_soc_probe().
- * It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
- *
- */
-static void usb_hcd_ppc_soc_remove(struct usb_hcd *hcd,
- struct platform_device *pdev)
-{
- usb_remove_hcd(hcd);
-
- pr_debug("stopping PPC-SOC USB Controller\n");
-
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
-}
-
-static int __devinit
-ohci_ppc_soc_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 const struct hc_driver ohci_ppc_soc_hc_driver = {
- .description = hcd_name,
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .start = ohci_ppc_soc_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_ppc_soc_drv_probe(struct platform_device *pdev)
-{
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- ret = usb_hcd_ppc_soc_probe(&ohci_ppc_soc_hc_driver, pdev);
- return ret;
-}
-
-static int ohci_hcd_ppc_soc_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_hcd_ppc_soc_remove(hcd, pdev);
- return 0;
-}
-
-static struct platform_driver ohci_hcd_ppc_soc_driver = {
- .probe = ohci_hcd_ppc_soc_drv_probe,
- .remove = ohci_hcd_ppc_soc_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
-#ifdef CONFIG_PM
- /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/
- /*.resume = ohci_hcd_ppc_soc_drv_resume,*/
-#endif
- .driver = {
- .name = "ppc-soc-ohci",
- .owner = THIS_MODULE,
- },
-};
-
-MODULE_ALIAS("platform:ppc-soc-ohci");
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index 2ee1d8d713d..7d35cd9e286 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -30,7 +30,7 @@ static int ps3_ohci_hc_reset(struct usb_hcd *hcd)
return ohci_init(ohci);
}
-static int __devinit ps3_ohci_hc_start(struct usb_hcd *hcd)
+static int ps3_ohci_hc_start(struct usb_hcd *hcd)
{
int result;
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
@@ -76,7 +76,7 @@ static const struct hc_driver ps3_ohci_hc_driver = {
#endif
};
-static int __devinit ps3_ohci_probe(struct ps3_system_bus_device *dev)
+static int ps3_ohci_probe(struct ps3_system_bus_device *dev)
{
int result;
struct usb_hcd *hcd;
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 2bf11440b01..efe71f3ca47 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -284,7 +284,7 @@ MODULE_DEVICE_TABLE(of, pxa_ohci_dt_ids);
static u64 pxa_ohci_dma_mask = DMA_BIT_MASK(32);
-static int __devinit ohci_pxa_of_init(struct platform_device *pdev)
+static int ohci_pxa_of_init(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct pxaohci_platform_data *pdata;
@@ -330,7 +330,7 @@ static int __devinit ohci_pxa_of_init(struct platform_device *pdev)
return 0;
}
#else
-static int __devinit ohci_pxa_of_init(struct platform_device *pdev)
+static int ohci_pxa_of_init(struct platform_device *pdev)
{
return 0;
}
@@ -471,7 +471,7 @@ void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)
/*-------------------------------------------------------------------------*/
-static int __devinit
+static int
ohci_pxa27x_start (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
@@ -591,7 +591,7 @@ static int ohci_hcd_pxa27x_drv_resume(struct device *dev)
/* Select Power Management Mode */
pxa27x_ohci_select_pmm(ohci, inf->port_mode);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index c5a1ea9145f..7482cfbe8c5 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -596,7 +596,6 @@ static void td_submit_urb (
urb_priv->ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_C);
}
- urb_priv->td_cnt = 0;
list_add (&urb_priv->pending, &ohci->pending);
if (data_len)
@@ -672,7 +671,8 @@ static void td_submit_urb (
* we could often reduce the number of TDs here.
*/
case PIPE_ISOCHRONOUS:
- for (cnt = 0; cnt < urb->number_of_packets; cnt++) {
+ for (cnt = urb_priv->td_cnt; cnt < urb->number_of_packets;
+ cnt++) {
int frame = urb->start_frame;
// FIXME scheduling should handle frame counter
@@ -1128,6 +1128,25 @@ dl_done_list (struct ohci_hcd *ohci)
while (td) {
struct td *td_next = td->next_dl_td;
+ struct ed *ed = td->ed;
+
+ /*
+ * Some OHCI controllers (NVIDIA for sure, maybe others)
+ * occasionally forget to add TDs to the done queue. Since
+ * TDs for a given endpoint are always processed in order,
+ * if we find a TD on the donelist then all of its
+ * predecessors must be finished as well.
+ */
+ for (;;) {
+ struct td *td2;
+
+ td2 = list_first_entry(&ed->td_list, struct td,
+ td_list);
+ if (td2 == td)
+ break;
+ takeback_td(ohci, td2);
+ }
+
takeback_td(ohci, td);
td = td_next;
}
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index 0d2309ca471..ad0f5526960 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -323,8 +323,6 @@ usb_hcd_s3c2410_remove(struct usb_hcd *hcd, struct platform_device *dev)
{
usb_remove_hcd(hcd);
s3c2410_stop_hc(dev);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
}
@@ -353,35 +351,29 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
hcd->rsrc_start = dev->resource[0].start;
hcd->rsrc_len = resource_size(&dev->resource[0]);
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- dev_err(&dev->dev, "request_mem_region failed\n");
- retval = -EBUSY;
+ hcd->regs = devm_request_and_ioremap(&dev->dev, &dev->resource[0]);
+ if (!hcd->regs) {
+ dev_err(&dev->dev, "devm_request_and_ioremap failed\n");
+ retval = -ENOMEM;
goto err_put;
}
- clk = clk_get(&dev->dev, "usb-host");
+ clk = devm_clk_get(&dev->dev, "usb-host");
if (IS_ERR(clk)) {
dev_err(&dev->dev, "cannot get usb-host clock\n");
retval = PTR_ERR(clk);
- goto err_mem;
+ goto err_put;
}
- usb_clk = clk_get(&dev->dev, "usb-bus-host");
+ usb_clk = devm_clk_get(&dev->dev, "usb-bus-host");
if (IS_ERR(usb_clk)) {
dev_err(&dev->dev, "cannot get usb-bus-host clock\n");
retval = PTR_ERR(usb_clk);
- goto err_clk;
+ goto err_put;
}
s3c2410_start_hc(dev, hcd);
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- dev_err(&dev->dev, "ioremap failed\n");
- retval = -ENOMEM;
- goto err_ioremap;
- }
-
ohci_hcd_init(hcd_to_ohci(hcd));
retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
@@ -392,14 +384,6 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
err_ioremap:
s3c2410_stop_hc(dev);
- iounmap(hcd->regs);
- clk_put(usb_clk);
-
- err_clk:
- clk_put(clk);
-
- err_mem:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err_put:
usb_put_hcd(hcd);
@@ -474,12 +458,12 @@ static const struct hc_driver ohci_s3c2410_hc_driver = {
/* device driver */
-static int __devinit ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
+static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
{
return usb_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev);
}
-static int __devexit ohci_hcd_s3c2410_drv_remove(struct platform_device *pdev)
+static int ohci_hcd_s3c2410_drv_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
@@ -524,8 +508,7 @@ static int ohci_hcd_s3c2410_drv_resume(struct device *dev)
s3c2410_start_hc(pdev, hcd);
- set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
@@ -541,7 +524,7 @@ static const struct dev_pm_ops ohci_hcd_s3c2410_pm_ops = {
static struct platform_driver ohci_hcd_s3c2410_driver = {
.probe = ohci_hcd_s3c2410_drv_probe,
- .remove = __devexit_p(ohci_hcd_s3c2410_drv_remove),
+ .remove = ohci_hcd_s3c2410_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
index b6cc9252092..17b2a7dad77 100644
--- a/drivers/usb/host/ohci-sa1111.c
+++ b/drivers/usb/host/ohci-sa1111.c
@@ -63,7 +63,7 @@ static int ohci_sa1111_reset(struct usb_hcd *hcd)
return ohci_init(ohci);
}
-static int __devinit ohci_sa1111_start(struct usb_hcd *hcd)
+static int ohci_sa1111_start(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int ret;
diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c
deleted file mode 100644
index 76a20c27836..00000000000
--- a/drivers/usb/host/ohci-sh.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * OHCI HCD (Host Controller Driver) for USB.
- *
- * Copyright (C) 2008 Renesas Solutions Corp.
- *
- * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@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.
- *
- * 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/platform_device.h>
-
-static int ohci_sh_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-
- ohci_hcd_init(ohci);
- ohci_init(ohci);
- ohci_run(ohci);
- return 0;
-}
-
-static const struct hc_driver ohci_sh_hc_driver = {
- .description = hcd_name,
- .product_desc = "SuperH OHCI",
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .start = ohci_sh_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_sh_probe(struct platform_device *pdev)
-{
- struct resource *res = NULL;
- struct usb_hcd *hcd = NULL;
- int irq = -1;
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "platform_get_resource error.\n");
- return -ENODEV;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "platform_get_irq error.\n");
- return -ENODEV;
- }
-
- /* initialize hcd */
- hcd = usb_create_hcd(&ohci_sh_hc_driver, &pdev->dev, (char *)hcd_name);
- if (!hcd) {
- dev_err(&pdev->dev, "Failed to create hcd\n");
- return -ENOMEM;
- }
-
- hcd->regs = (void __iomem *)res->start;
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
- ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (ret != 0) {
- dev_err(&pdev->dev, "Failed to add hcd\n");
- usb_put_hcd(hcd);
- return ret;
- }
-
- return ret;
-}
-
-static int ohci_hcd_sh_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- usb_put_hcd(hcd);
-
- return 0;
-}
-
-static struct platform_driver ohci_hcd_sh_driver = {
- .probe = ohci_hcd_sh_probe,
- .remove = ohci_hcd_sh_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "sh_ohci",
- .owner = THIS_MODULE,
- },
-};
-
-MODULE_ALIAS("platform:sh_ohci");
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c
index 5596ac2ba1c..3b5b908fd47 100644
--- a/drivers/usb/host/ohci-sm501.c
+++ b/drivers/usb/host/ohci-sm501.c
@@ -238,7 +238,7 @@ static int ohci_sm501_resume(struct platform_device *pdev)
ohci->next_statechange = jiffies;
sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
#else
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index fc7305ee3c9..9020bf0e2ec 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -33,7 +33,7 @@ static void spear_stop_ohci(struct spear_ohci *ohci)
clk_disable_unprepare(ohci->clk);
}
-static int __devinit ohci_spear_start(struct usb_hcd *hcd)
+static int ohci_spear_start(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int ret;
@@ -101,13 +101,11 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
struct spear_ohci *ohci_p;
struct resource *res;
int retval, irq;
- char clk_name[20] = "usbh_clk";
- static int instance = -1;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
retval = irq;
- goto fail_irq_get;
+ goto fail;
}
/*
@@ -118,47 +116,39 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
if (!pdev->dev.dma_mask)
pdev->dev.dma_mask = &spear_ohci_dma_mask;
- /*
- * Increment the device instance, when probing via device-tree
- */
- if (pdev->id < 0)
- instance++;
- else
- instance = pdev->id;
- sprintf(clk_name, "usbh.%01d_clk", instance);
-
- usbh_clk = clk_get(NULL, clk_name);
+ usbh_clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(usbh_clk)) {
dev_err(&pdev->dev, "Error getting interface clock\n");
retval = PTR_ERR(usbh_clk);
- goto fail_get_usbh_clk;
+ goto fail;
}
hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
if (!hcd) {
retval = -ENOMEM;
- goto fail_create_hcd;
+ goto fail;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
retval = -ENODEV;
- goto fail_request_resource;
+ goto err_put_hcd;
}
hcd->rsrc_start = pdev->resource[0].start;
hcd->rsrc_len = resource_size(res);
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ if (!devm_request_mem_region(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len,
+ hcd_name)) {
dev_dbg(&pdev->dev, "request_mem_region failed\n");
retval = -EBUSY;
- goto fail_request_resource;
+ goto err_put_hcd;
}
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len);
if (!hcd->regs) {
dev_dbg(&pdev->dev, "ioremap failed\n");
retval = -ENOMEM;
- goto fail_ioremap;
+ goto err_put_hcd;
}
ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
@@ -171,15 +161,9 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
return retval;
spear_stop_ohci(ohci_p);
- iounmap(hcd->regs);
-fail_ioremap:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-fail_request_resource:
+err_put_hcd:
usb_put_hcd(hcd);
-fail_create_hcd:
- clk_put(usbh_clk);
-fail_get_usbh_clk:
-fail_irq_get:
+fail:
dev_err(&pdev->dev, "init fail, %d\n", retval);
return retval;
@@ -194,12 +178,8 @@ static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
if (ohci_p->clk)
spear_stop_ohci(ohci_p);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
- if (ohci_p->clk)
- clk_put(ohci_p->clk);
platform_set_drvdata(pdev, NULL);
return 0;
}
@@ -231,12 +211,12 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
ohci->next_statechange = jiffies;
spear_start_ohci(ohci_p);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
#endif
-static struct of_device_id spear_ohci_id_table[] __devinitdata = {
+static struct of_device_id spear_ohci_id_table[] = {
{ .compatible = "st,spear600-ohci", },
{ },
};
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c
index 60c2b0722f2..d370245a4ee 100644
--- a/drivers/usb/host/ohci-tmio.c
+++ b/drivers/usb/host/ohci-tmio.c
@@ -184,7 +184,7 @@ static const struct hc_driver ohci_tmio_hc_driver = {
/*-------------------------------------------------------------------------*/
static struct platform_driver ohci_hcd_tmio_driver;
-static int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev)
+static int ohci_hcd_tmio_drv_probe(struct platform_device *dev)
{
const struct mfd_cell *cell = mfd_get_cell(dev);
struct resource *regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
@@ -271,7 +271,7 @@ err_usb_create_hcd:
return ret;
}
-static int __devexit ohci_hcd_tmio_drv_remove(struct platform_device *dev)
+static int ohci_hcd_tmio_drv_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
struct tmio_hcd *tmio = hcd_to_tmio(hcd);
@@ -352,7 +352,7 @@ static int ohci_hcd_tmio_drv_resume(struct platform_device *dev)
spin_unlock_irqrestore(&tmio->lock, flags);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
@@ -363,7 +363,7 @@ static int ohci_hcd_tmio_drv_resume(struct platform_device *dev)
static struct platform_driver ohci_hcd_tmio_driver = {
.probe = ohci_hcd_tmio_drv_probe,
- .remove = __devexit_p(ohci_hcd_tmio_drv_remove),
+ .remove = ohci_hcd_tmio_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
.suspend = ohci_hcd_tmio_drv_suspend,
.resume = ohci_hcd_tmio_drv_resume,
diff --git a/drivers/usb/host/ohci-xls.c b/drivers/usb/host/ohci-xls.c
deleted file mode 100644
index 84201cd1a47..00000000000
--- a/drivers/usb/host/ohci-xls.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * OHCI HCD for Netlogic XLS processors.
- *
- * (C) Copyright 2011 Netlogic Microsystems Inc.
- *
- * Based on ohci-au1xxx.c, and other Linux OHCI drivers.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- */
-
-#include <linux/platform_device.h>
-#include <linux/signal.h>
-
-static int ohci_xls_probe_internal(const struct hc_driver *driver,
- struct platform_device *dev)
-{
- struct resource *res;
- struct usb_hcd *hcd;
- int retval, irq;
-
- /* Get our IRQ from an earlier registered Platform Resource */
- irq = platform_get_irq(dev, 0);
- if (irq < 0) {
- dev_err(&dev->dev, "Found HC with no IRQ\n");
- return -ENODEV;
- }
-
- /* Get our Memory Handle */
- res = platform_get_resource(dev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&dev->dev, "MMIO Handle incorrect!\n");
- return -ENODEV;
- }
-
- hcd = usb_create_hcd(driver, &dev->dev, "XLS");
- if (!hcd) {
- retval = -ENOMEM;
- goto err1;
- }
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
- driver->description)) {
- dev_dbg(&dev->dev, "Controller already in use\n");
- retval = -EBUSY;
- goto err2;
- }
-
- hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
- if (hcd->regs == NULL) {
- dev_dbg(&dev->dev, "error mapping memory\n");
- retval = -EFAULT;
- goto err3;
- }
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval != 0)
- goto err4;
- return retval;
-
-err4:
- iounmap(hcd->regs);
-err3:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err2:
- usb_put_hcd(hcd);
-err1:
- dev_err(&dev->dev, "init fail, %d\n", retval);
- return retval;
-}
-
-static int ohci_xls_reset(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-
- ohci_hcd_init(ohci);
- return ohci_init(ohci);
-}
-
-static int __devinit ohci_xls_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci;
- int ret;
-
- ohci = hcd_to_ohci(hcd);
- 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 struct hc_driver ohci_xls_hc_driver = {
- .description = hcd_name,
- .product_desc = "XLS OHCI Host Controller",
- .hcd_priv_size = sizeof(struct ohci_hcd),
- .irq = ohci_irq,
- .flags = HCD_MEMORY | HCD_USB11,
- .reset = ohci_xls_reset,
- .start = ohci_xls_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_xls_probe(struct platform_device *dev)
-{
- int ret;
-
- pr_debug("In ohci_xls_probe");
- if (usb_disabled())
- return -ENODEV;
- ret = ohci_xls_probe_internal(&ohci_xls_hc_driver, dev);
- return ret;
-}
-
-static int ohci_xls_remove(struct platform_device *dev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(dev);
-
- usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
- return 0;
-}
-
-static struct platform_driver ohci_xls_driver = {
- .probe = ohci_xls_probe,
- .remove = ohci_xls_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "ohci-xls-0",
- .owner = THIS_MODULE,
- },
-};
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 39f9e4a9a2d..a3b6d7104ae 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -443,7 +443,7 @@ static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
#define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO)
#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
-static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
+static void quirk_usb_handoff_uhci(struct pci_dev *pdev)
{
unsigned long base = 0;
int i;
@@ -461,12 +461,12 @@ static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
uhci_check_and_reset_hc(pdev, base);
}
-static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
+static int mmio_resource_enabled(struct pci_dev *pdev, int idx)
{
return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
}
-static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
+static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
{
void __iomem *base;
u32 control;
@@ -533,7 +533,7 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
iounmap(base);
}
-static const struct dmi_system_id __devinitconst ehci_dmi_nohandoff_table[] = {
+static const struct dmi_system_id ehci_dmi_nohandoff_table[] = {
{
/* Pegatron Lucid (ExoPC) */
.matches = {
@@ -558,7 +558,7 @@ static const struct dmi_system_id __devinitconst ehci_dmi_nohandoff_table[] = {
{ }
};
-static void __devinit ehci_bios_handoff(struct pci_dev *pdev,
+static void ehci_bios_handoff(struct pci_dev *pdev,
void __iomem *op_reg_base,
u32 cap, u8 offset)
{
@@ -626,7 +626,7 @@ static void __devinit ehci_bios_handoff(struct pci_dev *pdev,
writel(0, op_reg_base + EHCI_CONFIGFLAG);
}
-static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
+static void quirk_usb_disable_ehci(struct pci_dev *pdev)
{
void __iomem *base, *op_reg_base;
u32 hcc_params, cap, val;
@@ -723,6 +723,7 @@ static int handshake(void __iomem *ptr, u32 mask, u32 done,
}
#define PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI 0x8C31
+#define PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI 0x9C31
bool usb_is_intel_ppt_switchable_xhci(struct pci_dev *pdev)
{
@@ -736,7 +737,8 @@ bool usb_is_intel_lpt_switchable_xhci(struct pci_dev *pdev)
{
return pdev->class == PCI_CLASS_SERIAL_USB_XHCI &&
pdev->vendor == PCI_VENDOR_ID_INTEL &&
- pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI;
+ (pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI ||
+ pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI);
}
bool usb_is_intel_switchable_xhci(struct pci_dev *pdev)
@@ -841,7 +843,7 @@ EXPORT_SYMBOL_GPL(usb_disable_xhci_ports);
* and then waits 5 seconds for the BIOS to hand over control.
* If we timeout, assume the BIOS is broken and take control anyway.
*/
-static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)
+static void quirk_usb_handoff_xhci(struct pci_dev *pdev)
{
void __iomem *base;
int ext_cap_offset;
@@ -941,7 +943,7 @@ hc_init:
iounmap(base);
}
-static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
+static void quirk_usb_early_handoff(struct pci_dev *pdev)
{
/* Skip Netlogic mips SoC's internal PCI USB controller.
* This device does not need/support EHCI/OHCI handoff
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index fcc09e5ec0a..a6fd8f5371d 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2036,10 +2036,8 @@ static void collect_usb_address_map(struct usb_device *udev, unsigned long *map)
udev->parent->descriptor.bDeviceClass == USB_CLASS_HUB)
map[udev->devnum/32] |= (1 << (udev->devnum % 32));
- usb_hub_for_each_child(udev, chix, childdev) {
- if (childdev)
- collect_usb_address_map(childdev, map);
- }
+ usb_hub_for_each_child(udev, chix, childdev)
+ collect_usb_address_map(childdev, map);
}
/* this function must be called with interrupt disabled */
@@ -2393,7 +2391,7 @@ static const struct dev_pm_ops r8a66597_dev_pm_ops = {
#define R8A66597_DEV_PM_OPS NULL
#endif
-static int __devexit r8a66597_remove(struct platform_device *pdev)
+static int r8a66597_remove(struct platform_device *pdev)
{
struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev);
struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597);
@@ -2407,7 +2405,7 @@ static int __devexit r8a66597_remove(struct platform_device *pdev)
return 0;
}
-static int __devinit r8a66597_probe(struct platform_device *pdev)
+static int r8a66597_probe(struct platform_device *pdev)
{
char clk_name[8];
struct resource *res = NULL, *ires;
@@ -2534,7 +2532,7 @@ clean_up:
static struct platform_driver r8a66597_driver = {
.probe = r8a66597_probe,
- .remove = __devexit_p(r8a66597_remove),
+ .remove = r8a66597_remove,
.driver = {
.name = (char *) hcd_name,
.owner = THIS_MODULE,
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index 619b05f42d4..d62f0404baa 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -1595,7 +1595,7 @@ static struct hc_driver sl811h_hc_driver = {
/*-------------------------------------------------------------------------*/
-static int __devexit
+static int
sl811h_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
@@ -1618,7 +1618,7 @@ sl811h_remove(struct platform_device *dev)
return 0;
}
-static int __devinit
+static int
sl811h_probe(struct platform_device *dev)
{
struct usb_hcd *hcd;
@@ -1808,7 +1808,7 @@ sl811h_resume(struct platform_device *dev)
/* this driver is exported so sl811_cs can depend on it */
struct platform_driver sl811h_driver = {
.probe = sl811h_probe,
- .remove = __devexit_p(sl811h_remove),
+ .remove = sl811h_remove,
.suspend = sl811h_suspend,
.resume = sl811h_resume,
diff --git a/drivers/usb/host/ssb-hcd.c b/drivers/usb/host/ssb-hcd.c
index c2a29faba07..74af2c6287d 100644
--- a/drivers/usb/host/ssb-hcd.c
+++ b/drivers/usb/host/ssb-hcd.c
@@ -39,7 +39,7 @@ struct ssb_hcd_device {
u32 enable_flags;
};
-static void __devinit ssb_hcd_5354wa(struct ssb_device *dev)
+static void ssb_hcd_5354wa(struct ssb_device *dev)
{
#ifdef CONFIG_SSB_DRIVER_MIPS
/* Work around for 5354 failures */
@@ -53,7 +53,7 @@ static void __devinit ssb_hcd_5354wa(struct ssb_device *dev)
#endif
}
-static void __devinit ssb_hcd_usb20wa(struct ssb_device *dev)
+static void ssb_hcd_usb20wa(struct ssb_device *dev)
{
if (dev->id.coreid == SSB_DEV_USB20_HOST) {
/*
@@ -80,7 +80,7 @@ static void __devinit ssb_hcd_usb20wa(struct ssb_device *dev)
}
/* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
-static u32 __devinit ssb_hcd_init_chip(struct ssb_device *dev)
+static u32 ssb_hcd_init_chip(struct ssb_device *dev)
{
u32 flags = 0;
@@ -101,8 +101,7 @@ static const struct usb_ehci_pdata ehci_pdata = {
static const struct usb_ohci_pdata ohci_pdata = {
};
-static struct platform_device * __devinit
-ssb_hcd_create_pdev(struct ssb_device *dev, bool ohci, u32 addr, u32 len)
+static struct platform_device *ssb_hcd_create_pdev(struct ssb_device *dev, bool ohci, u32 addr, u32 len)
{
struct platform_device *hci_dev;
struct resource hci_res[2];
@@ -148,7 +147,7 @@ err_alloc:
return ERR_PTR(ret);
}
-static int __devinit ssb_hcd_probe(struct ssb_device *dev,
+static int ssb_hcd_probe(struct ssb_device *dev,
const struct ssb_device_id *id)
{
int err, tmp;
@@ -207,7 +206,7 @@ err_free_usb_dev:
return err;
}
-static void __devexit ssb_hcd_remove(struct ssb_device *dev)
+static void ssb_hcd_remove(struct ssb_device *dev)
{
struct ssb_hcd_device *usb_dev = ssb_get_drvdata(dev);
struct platform_device *ohci_dev = usb_dev->ohci_dev;
@@ -221,7 +220,7 @@ static void __devexit ssb_hcd_remove(struct ssb_device *dev)
ssb_device_disable(dev, 0);
}
-static void __devexit ssb_hcd_shutdown(struct ssb_device *dev)
+static void ssb_hcd_shutdown(struct ssb_device *dev)
{
ssb_device_disable(dev, 0);
}
@@ -249,7 +248,7 @@ static int ssb_hcd_resume(struct ssb_device *dev)
#define ssb_hcd_resume NULL
#endif /* CONFIG_PM */
-static const struct ssb_device_id ssb_hcd_table[] __devinitconst = {
+static const struct ssb_device_id ssb_hcd_table[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
@@ -261,7 +260,7 @@ static struct ssb_driver ssb_hcd_driver = {
.name = KBUILD_MODNAME,
.id_table = ssb_hcd_table,
.probe = ssb_hcd_probe,
- .remove = __devexit_p(ssb_hcd_remove),
+ .remove = ssb_hcd_remove,
.shutdown = ssb_hcd_shutdown,
.suspend = ssb_hcd_suspend,
.resume = ssb_hcd_resume,
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index dbbd1ba2522..5efdffe3236 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -2990,7 +2990,7 @@ static struct hc_driver u132_hc_driver = {
* synchronously - but instead should immediately stop activity to the
* device and asynchronously call usb_remove_hcd()
*/
-static int __devexit u132_remove(struct platform_device *pdev)
+static int u132_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
if (hcd) {
@@ -3084,7 +3084,7 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev)
mutex_unlock(&u132->sw_lock);
}
-static int __devinit u132_probe(struct platform_device *pdev)
+static int u132_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
int retval;
@@ -3212,7 +3212,7 @@ static int u132_resume(struct platform_device *pdev)
*/
static struct platform_driver u132_platform_driver = {
.probe = u132_probe,
- .remove = __devexit_p(u132_remove),
+ .remove = u132_remove,
.suspend = u132_suspend,
.resume = u132_resume,
.driver = {
diff --git a/drivers/usb/host/uhci-grlib.c b/drivers/usb/host/uhci-grlib.c
index f7a62138e3e..511bfc46dd7 100644
--- a/drivers/usb/host/uhci-grlib.c
+++ b/drivers/usb/host/uhci-grlib.c
@@ -85,7 +85,7 @@ static const struct hc_driver uhci_grlib_hc_driver = {
};
-static int __devinit uhci_hcd_grlib_probe(struct platform_device *op)
+static int uhci_hcd_grlib_probe(struct platform_device *op)
{
struct device_node *dn = op->dev.of_node;
struct usb_hcd *hcd;
diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c
index 68ebf20e151..8c4dace4b14 100644
--- a/drivers/usb/host/uhci-platform.c
+++ b/drivers/usb/host/uhci-platform.c
@@ -62,7 +62,7 @@ static const struct hc_driver uhci_platform_hc_driver = {
static u64 platform_uhci_dma_mask = DMA_BIT_MASK(32);
-static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev)
+static int uhci_hcd_platform_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct uhci_hcd *uhci;
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index d2c6f5ac462..15921fd5504 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -1256,7 +1256,8 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
struct uhci_qh *qh)
{
struct uhci_td *td = NULL; /* Since urb->number_of_packets > 0 */
- int i, frame;
+ int i;
+ unsigned frame, next;
unsigned long destination, status;
struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
@@ -1265,37 +1266,29 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
urb->number_of_packets >= UHCI_NUMFRAMES)
return -EFBIG;
+ uhci_get_current_frame_number(uhci);
+
/* Check the period and figure out the starting frame number */
if (!qh->bandwidth_reserved) {
qh->period = urb->interval;
- if (urb->transfer_flags & URB_ISO_ASAP) {
- qh->phase = -1; /* Find the best phase */
- i = uhci_check_bandwidth(uhci, qh);
- if (i)
- return i;
-
- /* Allow a little time to allocate the TDs */
- uhci_get_current_frame_number(uhci);
- frame = uhci->frame_number + 10;
-
- /* Move forward to the first frame having the
- * correct phase */
- urb->start_frame = frame + ((qh->phase - frame) &
- (qh->period - 1));
- } else {
- i = urb->start_frame - uhci->last_iso_frame;
- if (i <= 0 || i >= UHCI_NUMFRAMES)
- return -EINVAL;
- qh->phase = urb->start_frame & (qh->period - 1);
- i = uhci_check_bandwidth(uhci, qh);
- if (i)
- return i;
- }
+ qh->phase = -1; /* Find the best phase */
+ i = uhci_check_bandwidth(uhci, qh);
+ if (i)
+ return i;
+
+ /* Allow a little time to allocate the TDs */
+ next = uhci->frame_number + 10;
+ frame = qh->phase;
+
+ /* Round up to the first available slot */
+ frame += (next - frame + qh->period - 1) & -qh->period;
} else if (qh->period != urb->interval) {
return -EINVAL; /* Can't change the period */
} else {
+ next = uhci->frame_number + 2;
+
/* Find the next unused frame */
if (list_empty(&qh->queue)) {
frame = qh->iso_frame;
@@ -1308,25 +1301,31 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
lurb->number_of_packets *
lurb->interval;
}
- if (urb->transfer_flags & URB_ISO_ASAP) {
- /* Skip some frames if necessary to insure
- * the start frame is in the future.
+
+ /* Fell behind? */
+ if (uhci_frame_before_eq(frame, next)) {
+
+ /* USB_ISO_ASAP: Round up to the first available slot */
+ if (urb->transfer_flags & URB_ISO_ASAP)
+ frame += (next - frame + qh->period - 1) &
+ -qh->period;
+
+ /*
+ * Not ASAP: Use the next slot in the stream. If
+ * the entire URB falls before the threshold, fail.
*/
- uhci_get_current_frame_number(uhci);
- if (uhci_frame_before_eq(frame, uhci->frame_number)) {
- frame = uhci->frame_number + 1;
- frame += ((qh->phase - frame) &
- (qh->period - 1));
- }
- } /* Otherwise pick up where the last URB leaves off */
- urb->start_frame = frame;
+ else if (!uhci_frame_before_eq(next,
+ frame + (urb->number_of_packets - 1) *
+ qh->period))
+ return -EXDEV;
+ }
}
/* Make sure we won't have to go too far into the future */
if (uhci_frame_before_eq(uhci->last_iso_frame + UHCI_NUMFRAMES,
- urb->start_frame + urb->number_of_packets *
- urb->interval))
+ frame + urb->number_of_packets * urb->interval))
return -EFBIG;
+ urb->start_frame = frame;
status = TD_CTRL_ACTIVE | TD_CTRL_IOS;
destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 487bc083dea..fb51c7085ad 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -205,7 +205,12 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,
next = xhci_segment_alloc(xhci, cycle_state, flags);
if (!next) {
- xhci_free_segments_for_ring(xhci, *first);
+ prev = *first;
+ while (prev) {
+ next = prev->next;
+ xhci_segment_free(xhci, prev);
+ prev = next;
+ }
return -ENOMEM;
}
xhci_link_segments(xhci, prev, next, type);
@@ -258,7 +263,7 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
return ring;
fail:
- xhci_ring_free(xhci, ring);
+ kfree(ring);
return NULL;
}
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 8345d7c2306..af259e0ec17 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -29,6 +29,7 @@
/* Device for a quirk */
#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000
+#define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400 0x1400
#define PCI_VENDOR_ID_ETRON 0x1b6f
#define PCI_DEVICE_ID_ASROCK_P67 0x7023
@@ -58,8 +59,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
/* Look for vendor-specific quirks */
if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
- pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) {
- if (pdev->revision == 0x0) {
+ (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK ||
+ pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1400)) {
+ if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK &&
+ pdev->revision == 0x0) {
xhci->quirks |= XHCI_RESET_EP_QUIRK;
xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
" endpoint cmd after reset endpoint\n");
@@ -218,15 +221,8 @@ static void xhci_pci_remove(struct pci_dev *dev)
static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- int retval = 0;
- if (hcd->state != HC_STATE_SUSPENDED ||
- xhci->shared_hcd->state != HC_STATE_SUSPENDED)
- return -EINVAL;
-
- retval = xhci_suspend(xhci);
-
- return retval;
+ return xhci_suspend(xhci);
}
static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 4e1a8946b8d..cbb44b7b9d6 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -318,7 +318,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
* seconds), then it should assume that the there are
* larger problems with the xHC and assert HCRST.
*/
- ret = handshake(xhci, &xhci->op_regs->cmd_ring,
+ ret = xhci_handshake(xhci, &xhci->op_regs->cmd_ring,
CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
if (ret < 0) {
xhci_err(xhci, "Stopped the command ring failed, "
@@ -3071,11 +3071,11 @@ static u32 xhci_td_remainder(unsigned int remainder)
}
/*
- * For xHCI 1.0 host controllers, TD size is the number of packets remaining in
- * the TD (*not* including this TRB).
+ * For xHCI 1.0 host controllers, TD size is the number of max packet sized
+ * packets remaining in the TD (*not* including this TRB).
*
* Total TD packet count = total_packet_count =
- * roundup(TD size in bytes / wMaxPacketSize)
+ * DIV_ROUND_UP(TD size in bytes / wMaxPacketSize)
*
* Packets transferred up to and including this TRB = packets_transferred =
* rounddown(total bytes transferred including this TRB / wMaxPacketSize)
@@ -3083,15 +3083,16 @@ static u32 xhci_td_remainder(unsigned int remainder)
* TD size = total_packet_count - packets_transferred
*
* It must fit in bits 21:17, so it can't be bigger than 31.
+ * The last TRB in a TD must have the TD size set to zero.
*/
-
static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
- unsigned int total_packet_count, struct urb *urb)
+ unsigned int total_packet_count, struct urb *urb,
+ unsigned int num_trbs_left)
{
int packets_transferred;
/* One TRB with a zero-length data packet. */
- if (running_total == 0 && trb_buff_len == 0)
+ if (num_trbs_left == 0 || (running_total == 0 && trb_buff_len == 0))
return 0;
/* All the TRB queueing functions don't count the current TRB in
@@ -3100,7 +3101,9 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
packets_transferred = (running_total + trb_buff_len) /
usb_endpoint_maxp(&urb->ep->desc);
- return xhci_td_remainder(total_packet_count - packets_transferred);
+ if ((total_packet_count - packets_transferred) > 31)
+ return 31 << 17;
+ return (total_packet_count - packets_transferred) << 17;
}
static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
@@ -3127,7 +3130,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
num_trbs = count_sg_trbs_needed(xhci, urb);
num_sgs = urb->num_mapped_sgs;
- total_packet_count = roundup(urb->transfer_buffer_length,
+ total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
usb_endpoint_maxp(&urb->ep->desc));
trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
@@ -3210,7 +3213,8 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
running_total);
} else {
remainder = xhci_v1_0_td_remainder(running_total,
- trb_buff_len, total_packet_count, urb);
+ trb_buff_len, total_packet_count, urb,
+ num_trbs - 1);
}
length_field = TRB_LEN(trb_buff_len) |
remainder |
@@ -3318,7 +3322,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
start_cycle = ep_ring->cycle_state;
running_total = 0;
- total_packet_count = roundup(urb->transfer_buffer_length,
+ total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
usb_endpoint_maxp(&urb->ep->desc));
/* How much data is in the first TRB? */
addr = (u64) urb->transfer_dma;
@@ -3364,7 +3368,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
running_total);
} else {
remainder = xhci_v1_0_td_remainder(running_total,
- trb_buff_len, total_packet_count, urb);
+ trb_buff_len, total_packet_count, urb,
+ num_trbs - 1);
}
length_field = TRB_LEN(trb_buff_len) |
remainder |
@@ -3627,7 +3632,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
addr = start_addr + urb->iso_frame_desc[i].offset;
td_len = urb->iso_frame_desc[i].length;
td_remain_len = td_len;
- total_packet_count = roundup(td_len,
+ total_packet_count = DIV_ROUND_UP(td_len,
usb_endpoint_maxp(&urb->ep->desc));
/* A zero-length transfer still involves at least one packet. */
if (total_packet_count == 0)
@@ -3706,7 +3711,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
} else {
remainder = xhci_v1_0_td_remainder(
running_total, trb_buff_len,
- total_packet_count, urb);
+ total_packet_count, urb,
+ (trbs_per_td - j - 1));
}
length_field = TRB_LEN(trb_buff_len) |
remainder |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index c9e419f29b7..5c72c431bab 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB");
/* TODO: copied from ehci-hcd.c - can this be refactored? */
/*
- * handshake - spin reading hc until handshake completes or fails
+ * xhci_handshake - spin reading hc until handshake completes or fails
* @ptr: address of hc register to be read
* @mask: bits to look at in result of read
* @done: value of those bits when handshake succeeds
@@ -52,7 +52,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB");
* handshake done). There are two failure modes: "usec" have passed (major
* hardware flakeout), or the register reads as all-ones (hardware removed).
*/
-int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
+int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr,
u32 mask, u32 done, int usec)
{
u32 result;
@@ -103,7 +103,7 @@ int xhci_halt(struct xhci_hcd *xhci)
xhci_dbg(xhci, "// Halt the HC\n");
xhci_quiesce(xhci);
- ret = handshake(xhci, &xhci->op_regs->status,
+ ret = xhci_handshake(xhci, &xhci->op_regs->status,
STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
if (!ret) {
xhci->xhc_state |= XHCI_STATE_HALTED;
@@ -132,7 +132,7 @@ static int xhci_start(struct xhci_hcd *xhci)
* Wait for the HCHalted Status bit to be 0 to indicate the host is
* running.
*/
- ret = handshake(xhci, &xhci->op_regs->status,
+ ret = xhci_handshake(xhci, &xhci->op_regs->status,
STS_HALT, 0, XHCI_MAX_HALT_USEC);
if (ret == -ETIMEDOUT)
xhci_err(xhci, "Host took too long to start, "
@@ -167,7 +167,7 @@ int xhci_reset(struct xhci_hcd *xhci)
command |= CMD_RESET;
xhci_writel(xhci, command, &xhci->op_regs->command);
- ret = handshake(xhci, &xhci->op_regs->command,
+ ret = xhci_handshake(xhci, &xhci->op_regs->command,
CMD_RESET, 0, 10 * 1000 * 1000);
if (ret)
return ret;
@@ -177,7 +177,7 @@ int xhci_reset(struct xhci_hcd *xhci)
* xHCI cannot write to any doorbells or operational registers other
* than status until the "Controller Not Ready" flag is cleared.
*/
- ret = handshake(xhci, &xhci->op_regs->status,
+ ret = xhci_handshake(xhci, &xhci->op_regs->status,
STS_CNR, 0, 10 * 1000 * 1000);
for (i = 0; i < 2; ++i) {
@@ -480,7 +480,7 @@ static bool compliance_mode_recovery_timer_quirk_check(void)
if (strstr(dmi_product_name, "Z420") ||
strstr(dmi_product_name, "Z620") ||
strstr(dmi_product_name, "Z820") ||
- strstr(dmi_product_name, "Z1"))
+ strstr(dmi_product_name, "Z1 Workstation"))
return true;
return false;
@@ -880,6 +880,10 @@ int xhci_suspend(struct xhci_hcd *xhci)
struct usb_hcd *hcd = xhci_to_hcd(xhci);
u32 command;
+ if (hcd->state != HC_STATE_SUSPENDED ||
+ xhci->shared_hcd->state != HC_STATE_SUSPENDED)
+ return -EINVAL;
+
spin_lock_irq(&xhci->lock);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
@@ -890,7 +894,7 @@ int xhci_suspend(struct xhci_hcd *xhci)
command = xhci_readl(xhci, &xhci->op_regs->command);
command &= ~CMD_RUN;
xhci_writel(xhci, command, &xhci->op_regs->command);
- if (handshake(xhci, &xhci->op_regs->status,
+ if (xhci_handshake(xhci, &xhci->op_regs->status,
STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) {
xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n");
spin_unlock_irq(&xhci->lock);
@@ -905,7 +909,8 @@ int xhci_suspend(struct xhci_hcd *xhci)
command = xhci_readl(xhci, &xhci->op_regs->command);
command |= CMD_CSS;
xhci_writel(xhci, command, &xhci->op_regs->command);
- if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10 * 1000)) {
+ if (xhci_handshake(xhci, &xhci->op_regs->status,
+ STS_SAVE, 0, 10 * 1000)) {
xhci_warn(xhci, "WARN: xHC save state timeout\n");
spin_unlock_irq(&xhci->lock);
return -ETIMEDOUT;
@@ -967,7 +972,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
command = xhci_readl(xhci, &xhci->op_regs->command);
command |= CMD_CRS;
xhci_writel(xhci, command, &xhci->op_regs->command);
- if (handshake(xhci, &xhci->op_regs->status,
+ if (xhci_handshake(xhci, &xhci->op_regs->status,
STS_RESTORE, 0, 10 * 1000)) {
xhci_warn(xhci, "WARN: xHC restore state timeout\n");
spin_unlock_irq(&xhci->lock);
@@ -1035,7 +1040,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
command = xhci_readl(xhci, &xhci->op_regs->command);
command |= CMD_RUN;
xhci_writel(xhci, command, &xhci->op_regs->command);
- handshake(xhci, &xhci->op_regs->status, STS_HALT,
+ xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT,
0, 250 * 1000);
/* step 5: walk topology and initialize portsc,
@@ -2254,7 +2259,7 @@ static bool xhci_is_async_ep(unsigned int ep_type)
static bool xhci_is_sync_in_ep(unsigned int ep_type)
{
- return (ep_type == ISOC_IN_EP || ep_type != INT_IN_EP);
+ return (ep_type == ISOC_IN_EP || ep_type == INT_IN_EP);
}
static unsigned int xhci_get_ss_bw_consumed(struct xhci_bw_info *ep_bw)
@@ -3874,7 +3879,8 @@ static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd,
spin_lock_irqsave(&xhci->lock, flags);
/* Check L1 Status */
- ret = handshake(xhci, pm_addr, PORT_L1S_MASK, PORT_L1S_SUCCESS, 125);
+ ret = xhci_handshake(xhci, pm_addr,
+ PORT_L1S_MASK, PORT_L1S_SUCCESS, 125);
if (ret != -ETIMEDOUT) {
/* enter L1 successfully */
temp = xhci_readl(xhci, addr);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 53df4e70ca0..f791bd0aee6 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1720,7 +1720,7 @@ static inline void xhci_unregister_plat(void)
/* xHCI host controller glue */
typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *);
-int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
+int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr,
u32 mask, u32 done, int usec);
void xhci_quiesce(struct xhci_hcd *xhci);
int xhci_halt(struct xhci_hcd *xhci);
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index a8f05239350..fecde69bfa7 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -246,6 +246,7 @@ config USB_YUREX
config USB_EZUSB_FX2
tristate "Functions for loading firmware on EZUSB chips"
+ depends on USB
help
Say Y here if you need EZUSB device support.
(Cypress FX/FX2/FX2LP microcontrollers)
diff --git a/drivers/usb/misc/ezusb.c b/drivers/usb/misc/ezusb.c
index 6589268a651..e712afed947 100644
--- a/drivers/usb/misc/ezusb.c
+++ b/drivers/usb/misc/ezusb.c
@@ -15,6 +15,7 @@
#include <linux/usb.h>
#include <linux/firmware.h>
#include <linux/ihex.h>
+#include <linux/usb/ezusb.h>
struct ezusb_fx_type {
/* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */
@@ -22,21 +23,16 @@ struct ezusb_fx_type {
unsigned short max_internal_adress;
};
-struct ezusb_fx_type ezusb_fx1 = {
+static struct ezusb_fx_type ezusb_fx1 = {
.cpucs_reg = 0x7F92,
.max_internal_adress = 0x1B3F,
};
-struct ezusb_fx_type ezusb_fx2 = {
- .cpucs_reg = 0xE600,
- .max_internal_adress = 0x3FFF,
-};
-
/* Commands for writing to memory */
#define WRITE_INT_RAM 0xA0
#define WRITE_EXT_RAM 0xA3
-int ezusb_writememory(struct usb_device *dev, int address,
+static int ezusb_writememory(struct usb_device *dev, int address,
unsigned char *data, int length, __u8 request)
{
int result;
@@ -58,10 +54,9 @@ int ezusb_writememory(struct usb_device *dev, int address,
kfree(transfer_buffer);
return result;
}
-EXPORT_SYMBOL_GPL(ezusb_writememory);
-int ezusb_set_reset(struct usb_device *dev, unsigned short cpucs_reg,
- unsigned char reset_bit)
+static int ezusb_set_reset(struct usb_device *dev, unsigned short cpucs_reg,
+ unsigned char reset_bit)
{
int response = ezusb_writememory(dev, cpucs_reg, &reset_bit, 1, WRITE_INT_RAM);
if (response < 0)
@@ -76,12 +71,6 @@ int ezusb_fx1_set_reset(struct usb_device *dev, unsigned char reset_bit)
}
EXPORT_SYMBOL_GPL(ezusb_fx1_set_reset);
-int ezusb_fx2_set_reset(struct usb_device *dev, unsigned char reset_bit)
-{
- return ezusb_set_reset(dev, ezusb_fx2.cpucs_reg, reset_bit);
-}
-EXPORT_SYMBOL_GPL(ezusb_fx2_set_reset);
-
static int ezusb_ihex_firmware_download(struct usb_device *dev,
struct ezusb_fx_type fx,
const char *firmware_path)
@@ -151,11 +140,28 @@ int ezusb_fx1_ihex_firmware_download(struct usb_device *dev,
}
EXPORT_SYMBOL_GPL(ezusb_fx1_ihex_firmware_download);
+#if 0
+/*
+ * Once someone one needs these fx2 functions, uncomment them
+ * and add them to ezusb.h and all should be good.
+ */
+static struct ezusb_fx_type ezusb_fx2 = {
+ .cpucs_reg = 0xE600,
+ .max_internal_adress = 0x3FFF,
+};
+
+int ezusb_fx2_set_reset(struct usb_device *dev, unsigned char reset_bit)
+{
+ return ezusb_set_reset(dev, ezusb_fx2.cpucs_reg, reset_bit);
+}
+EXPORT_SYMBOL_GPL(ezusb_fx2_set_reset);
+
int ezusb_fx2_ihex_firmware_download(struct usb_device *dev,
const char *firmware_path)
{
return ezusb_ihex_firmware_download(dev, ezusb_fx2, firmware_path);
}
EXPORT_SYMBOL_GPL(ezusb_fx2_ihex_firmware_download);
+#endif
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 055b84adeda..7667b12f2ff 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -423,6 +423,9 @@ alloc_sglist(int nents, int max, int vary)
unsigned i;
unsigned size = max;
+ if (max == 0)
+ return NULL;
+
sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL);
if (!sg)
return NULL;
@@ -2386,6 +2389,7 @@ static struct usbtest_info gz_info = {
.name = "Linux gadget zero",
.autoconf = 1,
.ctrl_out = 1,
+ .iso = 1,
.alt = 0,
};
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c
index c964d6af178..3d1c71b50f7 100644
--- a/drivers/usb/musb/am35x.c
+++ b/drivers/usb/musb/am35x.c
@@ -455,7 +455,7 @@ static const struct musb_platform_ops am35x_ops = {
static u64 am35x_dmamask = DMA_BIT_MASK(32);
-static int __devinit am35x_probe(struct platform_device *pdev)
+static int am35x_probe(struct platform_device *pdev)
{
struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
struct platform_device *musb;
@@ -465,7 +465,6 @@ static int __devinit am35x_probe(struct platform_device *pdev)
struct clk *clk;
int ret = -ENOMEM;
- int musbid;
glue = kzalloc(sizeof(*glue), GFP_KERNEL);
if (!glue) {
@@ -473,18 +472,10 @@ static int __devinit am35x_probe(struct platform_device *pdev)
goto err0;
}
- /* get the musb id */
- musbid = musb_get_id(&pdev->dev, GFP_KERNEL);
- if (musbid < 0) {
- dev_err(&pdev->dev, "failed to allocate musb id\n");
- ret = -ENOMEM;
- goto err1;
- }
-
- musb = platform_device_alloc("musb-hdrc", musbid);
+ musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
if (!musb) {
dev_err(&pdev->dev, "failed to allocate musb device\n");
- goto err2;
+ goto err1;
}
phy_clk = clk_get(&pdev->dev, "fck");
@@ -513,7 +504,6 @@ static int __devinit am35x_probe(struct platform_device *pdev)
goto err6;
}
- musb->id = musbid;
musb->dev.parent = &pdev->dev;
musb->dev.dma_mask = &am35x_dmamask;
musb->dev.coherent_dma_mask = am35x_dmamask;
@@ -563,9 +553,6 @@ err4:
err3:
platform_device_put(musb);
-err2:
- musb_put_id(&pdev->dev, musbid);
-
err1:
kfree(glue);
@@ -573,13 +560,11 @@ err0:
return ret;
}
-static int __devexit am35x_remove(struct platform_device *pdev)
+static int am35x_remove(struct platform_device *pdev)
{
struct am35x_glue *glue = platform_get_drvdata(pdev);
- musb_put_id(&pdev->dev, glue->musb->id);
- platform_device_del(glue->musb);
- platform_device_put(glue->musb);
+ platform_device_unregister(glue->musb);
clk_disable(glue->clk);
clk_disable(glue->phy_clk);
clk_put(glue->clk);
@@ -644,7 +629,7 @@ static struct dev_pm_ops am35x_pm_ops = {
static struct platform_driver am35x_driver = {
.probe = am35x_probe,
- .remove = __devexit_p(am35x_remove),
+ .remove = am35x_remove,
.driver = {
.name = "musb-am35x",
.pm = DEV_PM_OPS,
@@ -654,15 +639,4 @@ static struct platform_driver am35x_driver = {
MODULE_DESCRIPTION("AM35x MUSB Glue Layer");
MODULE_AUTHOR("Ajay Kumar Gupta <ajay.gupta@ti.com>");
MODULE_LICENSE("GPL v2");
-
-static int __init am35x_init(void)
-{
- return platform_driver_register(&am35x_driver);
-}
-module_init(am35x_init);
-
-static void __exit am35x_exit(void)
-{
- platform_driver_unregister(&am35x_driver);
-}
-module_exit(am35x_exit);
+module_platform_driver(am35x_driver);
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
index e8cff9bb9d2..14dab9f9b3d 100644
--- a/drivers/usb/musb/blackfin.c
+++ b/drivers/usb/musb/blackfin.c
@@ -448,14 +448,13 @@ static const struct musb_platform_ops bfin_ops = {
static u64 bfin_dmamask = DMA_BIT_MASK(32);
-static int __devinit bfin_probe(struct platform_device *pdev)
+static int bfin_probe(struct platform_device *pdev)
{
struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
struct platform_device *musb;
struct bfin_glue *glue;
int ret = -ENOMEM;
- int musbid;
glue = kzalloc(sizeof(*glue), GFP_KERNEL);
if (!glue) {
@@ -463,21 +462,12 @@ static int __devinit bfin_probe(struct platform_device *pdev)
goto err0;
}
- /* get the musb id */
- musbid = musb_get_id(&pdev->dev, GFP_KERNEL);
- if (musbid < 0) {
- dev_err(&pdev->dev, "failed to allocate musb id\n");
- ret = -ENOMEM;
- goto err1;
- }
-
- musb = platform_device_alloc("musb-hdrc", musbid);
+ musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
if (!musb) {
dev_err(&pdev->dev, "failed to allocate musb device\n");
- goto err2;
+ goto err1;
}
- musb->id = musbid;
musb->dev.parent = &pdev->dev;
musb->dev.dma_mask = &bfin_dmamask;
musb->dev.coherent_dma_mask = bfin_dmamask;
@@ -513,9 +503,6 @@ static int __devinit bfin_probe(struct platform_device *pdev)
err3:
platform_device_put(musb);
-err2:
- musb_put_id(&pdev->dev, musbid);
-
err1:
kfree(glue);
@@ -523,13 +510,11 @@ err0:
return ret;
}
-static int __devexit bfin_remove(struct platform_device *pdev)
+static int bfin_remove(struct platform_device *pdev)
{
struct bfin_glue *glue = platform_get_drvdata(pdev);
- musb_put_id(&pdev->dev, glue->musb->id);
- platform_device_del(glue->musb);
- platform_device_put(glue->musb);
+ platform_device_unregister(glue->musb);
kfree(glue);
return 0;
@@ -585,15 +570,4 @@ static struct platform_driver bfin_driver = {
MODULE_DESCRIPTION("Blackfin MUSB Glue Layer");
MODULE_AUTHOR("Bryan Wy <cooloney@kernel.org>");
MODULE_LICENSE("GPL v2");
-
-static int __init bfin_init(void)
-{
- return platform_driver_register(&bfin_driver);
-}
-module_init(bfin_init);
-
-static void __exit bfin_exit(void)
-{
- platform_driver_unregister(&bfin_driver);
-}
-module_exit(bfin_exit);
+module_platform_driver(bfin_driver);
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
index e19da82b478..0968dd7a859 100644
--- a/drivers/usb/musb/cppi_dma.c
+++ b/drivers/usb/musb/cppi_dma.c
@@ -1314,10 +1314,10 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
+EXPORT_SYMBOL_GPL(cppi_interrupt);
/* Instantiate a software object representing a DMA controller. */
-struct dma_controller *__devinit
-dma_controller_create(struct musb *musb, void __iomem *mregs)
+struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *mregs)
{
struct cppi *controller;
struct device *dev = musb->controller;
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
index 8bc44b76eec..97996af2646 100644
--- a/drivers/usb/musb/da8xx.c
+++ b/drivers/usb/musb/da8xx.c
@@ -471,7 +471,7 @@ static const struct musb_platform_ops da8xx_ops = {
static u64 da8xx_dmamask = DMA_BIT_MASK(32);
-static int __devinit da8xx_probe(struct platform_device *pdev)
+static int da8xx_probe(struct platform_device *pdev)
{
struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
struct platform_device *musb;
@@ -480,7 +480,6 @@ static int __devinit da8xx_probe(struct platform_device *pdev)
struct clk *clk;
int ret = -ENOMEM;
- int musbid;
glue = kzalloc(sizeof(*glue), GFP_KERNEL);
if (!glue) {
@@ -488,18 +487,10 @@ static int __devinit da8xx_probe(struct platform_device *pdev)
goto err0;
}
- /* get the musb id */
- musbid = musb_get_id(&pdev->dev, GFP_KERNEL);
- if (musbid < 0) {
- dev_err(&pdev->dev, "failed to allocate musb id\n");
- ret = -ENOMEM;
- goto err1;
- }
-
- musb = platform_device_alloc("musb-hdrc", musbid);
+ musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
if (!musb) {
dev_err(&pdev->dev, "failed to allocate musb device\n");
- goto err2;
+ goto err1;
}
clk = clk_get(&pdev->dev, "usb20");
@@ -515,7 +506,6 @@ static int __devinit da8xx_probe(struct platform_device *pdev)
goto err4;
}
- musb->id = musbid;
musb->dev.parent = &pdev->dev;
musb->dev.dma_mask = &da8xx_dmamask;
musb->dev.coherent_dma_mask = da8xx_dmamask;
@@ -558,9 +548,6 @@ err4:
err3:
platform_device_put(musb);
-err2:
- musb_put_id(&pdev->dev, musbid);
-
err1:
kfree(glue);
@@ -568,13 +555,11 @@ err0:
return ret;
}
-static int __devexit da8xx_remove(struct platform_device *pdev)
+static int da8xx_remove(struct platform_device *pdev)
{
struct da8xx_glue *glue = platform_get_drvdata(pdev);
- musb_put_id(&pdev->dev, glue->musb->id);
- platform_device_del(glue->musb);
- platform_device_put(glue->musb);
+ platform_device_unregister(glue->musb);
clk_disable(glue->clk);
clk_put(glue->clk);
kfree(glue);
@@ -584,7 +569,7 @@ static int __devexit da8xx_remove(struct platform_device *pdev)
static struct platform_driver da8xx_driver = {
.probe = da8xx_probe,
- .remove = __devexit_p(da8xx_remove),
+ .remove = da8xx_remove,
.driver = {
.name = "musb-da8xx",
},
@@ -593,15 +578,4 @@ static struct platform_driver da8xx_driver = {
MODULE_DESCRIPTION("DA8xx/OMAP-L1x MUSB Glue Layer");
MODULE_AUTHOR("Sergei Shtylyov <sshtylyov@ru.mvista.com>");
MODULE_LICENSE("GPL v2");
-
-static int __init da8xx_init(void)
-{
- return platform_driver_register(&da8xx_driver);
-}
-module_init(da8xx_init);
-
-static void __exit da8xx_exit(void)
-{
- platform_driver_unregister(&da8xx_driver);
-}
-module_exit(da8xx_exit);
+module_platform_driver(da8xx_driver);
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 606bfd00cde..b1c01cad28b 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -504,7 +504,7 @@ static const struct musb_platform_ops davinci_ops = {
static u64 davinci_dmamask = DMA_BIT_MASK(32);
-static int __devinit davinci_probe(struct platform_device *pdev)
+static int davinci_probe(struct platform_device *pdev)
{
struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
struct platform_device *musb;
@@ -512,7 +512,6 @@ static int __devinit davinci_probe(struct platform_device *pdev)
struct clk *clk;
int ret = -ENOMEM;
- int musbid;
glue = kzalloc(sizeof(*glue), GFP_KERNEL);
if (!glue) {
@@ -520,18 +519,10 @@ static int __devinit davinci_probe(struct platform_device *pdev)
goto err0;
}
- /* get the musb id */
- musbid = musb_get_id(&pdev->dev, GFP_KERNEL);
- if (musbid < 0) {
- dev_err(&pdev->dev, "failed to allocate musb id\n");
- ret = -ENOMEM;
- goto err1;
- }
-
- musb = platform_device_alloc("musb-hdrc", musbid);
+ musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
if (!musb) {
dev_err(&pdev->dev, "failed to allocate musb device\n");
- goto err2;
+ goto err1;
}
clk = clk_get(&pdev->dev, "usb");
@@ -547,7 +538,6 @@ static int __devinit davinci_probe(struct platform_device *pdev)
goto err4;
}
- musb->id = musbid;
musb->dev.parent = &pdev->dev;
musb->dev.dma_mask = &davinci_dmamask;
musb->dev.coherent_dma_mask = davinci_dmamask;
@@ -590,9 +580,6 @@ err4:
err3:
platform_device_put(musb);
-err2:
- musb_put_id(&pdev->dev, musbid);
-
err1:
kfree(glue);
@@ -600,13 +587,11 @@ err0:
return ret;
}
-static int __devexit davinci_remove(struct platform_device *pdev)
+static int davinci_remove(struct platform_device *pdev)
{
struct davinci_glue *glue = platform_get_drvdata(pdev);
- musb_put_id(&pdev->dev, glue->musb->id);
- platform_device_del(glue->musb);
- platform_device_put(glue->musb);
+ platform_device_unregister(glue->musb);
clk_disable(glue->clk);
clk_put(glue->clk);
kfree(glue);
@@ -616,7 +601,7 @@ static int __devexit davinci_remove(struct platform_device *pdev)
static struct platform_driver davinci_driver = {
.probe = davinci_probe,
- .remove = __devexit_p(davinci_remove),
+ .remove = davinci_remove,
.driver = {
.name = "musb-davinci",
},
@@ -625,15 +610,4 @@ static struct platform_driver davinci_driver = {
MODULE_DESCRIPTION("DaVinci MUSB Glue Layer");
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
MODULE_LICENSE("GPL v2");
-
-static int __init davinci_init(void)
-{
- return platform_driver_register(&davinci_driver);
-}
-module_init(davinci_init);
-
-static void __exit davinci_exit(void)
-{
- platform_driver_unregister(&davinci_driver);
-}
-module_exit(davinci_exit);
+module_platform_driver(davinci_driver);
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index bb56a0e8b23..57cc9c6eaa9 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -116,7 +116,6 @@
#define MUSB_DRIVER_NAME "musb-hdrc"
const char musb_driver_name[] = MUSB_DRIVER_NAME;
-static DEFINE_IDA(musb_ida);
MODULE_DESCRIPTION(DRIVER_INFO);
MODULE_AUTHOR(DRIVER_AUTHOR);
@@ -133,35 +132,6 @@ static inline struct musb *dev_to_musb(struct device *dev)
/*-------------------------------------------------------------------------*/
-int musb_get_id(struct device *dev, gfp_t gfp_mask)
-{
- int ret;
- int id;
-
- ret = ida_pre_get(&musb_ida, gfp_mask);
- if (!ret) {
- dev_err(dev, "failed to reserve resource for id\n");
- return -ENOMEM;
- }
-
- ret = ida_get_new(&musb_ida, &id);
- if (ret < 0) {
- dev_err(dev, "failed to allocate a new id\n");
- return ret;
- }
-
- return id;
-}
-EXPORT_SYMBOL_GPL(musb_get_id);
-
-void musb_put_id(struct device *dev, int id)
-{
-
- dev_dbg(dev, "removing id %d\n", id);
- ida_remove(&musb_ida, id);
-}
-EXPORT_SYMBOL_GPL(musb_put_id);
-
#ifndef CONFIG_BLACKFIN
static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
{
@@ -467,12 +437,12 @@ void musb_hnp_stop(struct musb *musb)
*/
static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
- u8 devctl, u8 power)
+ u8 devctl)
{
struct usb_otg *otg = musb->xceiv->otg;
irqreturn_t handled = IRQ_NONE;
- dev_dbg(musb->controller, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl,
+ dev_dbg(musb->controller, "<== DevCtl=%02x, int_usb=0x%x\n", devctl,
int_usb);
/* in host mode, the peripheral may issue remote wakeup.
@@ -485,6 +455,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
if (devctl & MUSB_DEVCTL_HM) {
void __iomem *mbase = musb->mregs;
+ u8 power;
switch (musb->xceiv->state) {
case OTG_STATE_A_SUSPEND:
@@ -492,6 +463,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
* will stop RESUME signaling
*/
+ power = musb_readb(musb->mregs, MUSB_POWER);
if (power & MUSB_POWER_SUSPENDM) {
/* spurious */
musb->int_usb &= ~MUSB_INTR_SUSPEND;
@@ -655,8 +627,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
}
if (int_usb & MUSB_INTR_SUSPEND) {
- dev_dbg(musb->controller, "SUSPEND (%s) devctl %02x power %02x\n",
- otg_state_string(musb->xceiv->state), devctl, power);
+ dev_dbg(musb->controller, "SUSPEND (%s) devctl %02x\n",
+ otg_state_string(musb->xceiv->state), devctl);
handled = IRQ_HANDLED;
switch (musb->xceiv->state) {
@@ -722,8 +694,10 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
if (is_peripheral_active(musb)) {
/* REVISIT HNP; just force disconnect */
}
- musb_writew(musb->mregs, MUSB_INTRTXE, musb->epmask);
- musb_writew(musb->mregs, MUSB_INTRRXE, musb->epmask & 0xfffe);
+ musb->intrtxe = musb->epmask;
+ musb_writew(musb->mregs, MUSB_INTRTXE, musb->intrtxe);
+ musb->intrrxe = musb->epmask & 0xfffe;
+ musb_writew(musb->mregs, MUSB_INTRRXE, musb->intrrxe);
musb_writeb(musb->mregs, MUSB_INTRUSBE, 0xf7);
musb->port1_status &= ~(USB_PORT_STAT_LOW_SPEED
|USB_PORT_STAT_HIGH_SPEED
@@ -944,8 +918,10 @@ void musb_start(struct musb *musb)
dev_dbg(musb->controller, "<== devctl %02x\n", devctl);
/* Set INT enable registers, enable interrupts */
- musb_writew(regs, MUSB_INTRTXE, musb->epmask);
- musb_writew(regs, MUSB_INTRRXE, musb->epmask & 0xfffe);
+ musb->intrtxe = musb->epmask;
+ musb_writew(regs, MUSB_INTRTXE, musb->intrtxe);
+ musb->intrrxe = musb->epmask & 0xfffe;
+ musb_writew(regs, MUSB_INTRRXE, musb->intrrxe);
musb_writeb(regs, MUSB_INTRUSBE, 0xf7);
musb_writeb(regs, MUSB_TESTMODE, 0);
@@ -983,7 +959,9 @@ static void musb_generic_disable(struct musb *musb)
/* disable interrupts */
musb_writeb(mbase, MUSB_INTRUSBE, 0);
+ musb->intrtxe = 0;
musb_writew(mbase, MUSB_INTRTXE, 0);
+ musb->intrrxe = 0;
musb_writew(mbase, MUSB_INTRRXE, 0);
/* off */
@@ -1062,12 +1040,12 @@ static void musb_shutdown(struct platform_device *pdev)
|| defined(CONFIG_USB_MUSB_AM35X_MODULE) \
|| defined(CONFIG_USB_MUSB_DSPS) \
|| defined(CONFIG_USB_MUSB_DSPS_MODULE)
-static ushort __devinitdata fifo_mode = 4;
+static ushort fifo_mode = 4;
#elif defined(CONFIG_USB_MUSB_UX500) \
|| defined(CONFIG_USB_MUSB_UX500_MODULE)
-static ushort __devinitdata fifo_mode = 5;
+static ushort fifo_mode = 5;
#else
-static ushort __devinitdata fifo_mode = 2;
+static ushort fifo_mode = 2;
#endif
/* "modprobe ... fifo_mode=1" etc */
@@ -1080,7 +1058,7 @@ MODULE_PARM_DESC(fifo_mode, "initial endpoint configuration");
*/
/* mode 0 - fits in 2KB */
-static struct musb_fifo_cfg __devinitdata mode_0_cfg[] = {
+static struct musb_fifo_cfg mode_0_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, },
@@ -1089,7 +1067,7 @@ static struct musb_fifo_cfg __devinitdata mode_0_cfg[] = {
};
/* mode 1 - fits in 4KB */
-static struct musb_fifo_cfg __devinitdata mode_1_cfg[] = {
+static struct musb_fifo_cfg mode_1_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, },
{ .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, .mode = BUF_DOUBLE, },
@@ -1098,7 +1076,7 @@ static struct musb_fifo_cfg __devinitdata mode_1_cfg[] = {
};
/* mode 2 - fits in 4KB */
-static struct musb_fifo_cfg __devinitdata mode_2_cfg[] = {
+static struct musb_fifo_cfg mode_2_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
@@ -1108,7 +1086,7 @@ static struct musb_fifo_cfg __devinitdata mode_2_cfg[] = {
};
/* mode 3 - fits in 4KB */
-static struct musb_fifo_cfg __devinitdata mode_3_cfg[] = {
+static struct musb_fifo_cfg mode_3_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
@@ -1118,7 +1096,7 @@ static struct musb_fifo_cfg __devinitdata mode_3_cfg[] = {
};
/* mode 4 - fits in 16KB */
-static struct musb_fifo_cfg __devinitdata mode_4_cfg[] = {
+static struct musb_fifo_cfg mode_4_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
@@ -1149,7 +1127,7 @@ static struct musb_fifo_cfg __devinitdata mode_4_cfg[] = {
};
/* mode 5 - fits in 8KB */
-static struct musb_fifo_cfg __devinitdata mode_5_cfg[] = {
+static struct musb_fifo_cfg mode_5_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
@@ -1185,7 +1163,7 @@ static struct musb_fifo_cfg __devinitdata mode_5_cfg[] = {
*
* returns negative errno or offset for next fifo.
*/
-static int __devinit
+static int
fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep,
const struct musb_fifo_cfg *cfg, u16 offset)
{
@@ -1256,11 +1234,11 @@ fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep,
return offset + (maxpacket << ((c_size & MUSB_FIFOSZ_DPB) ? 1 : 0));
}
-static struct musb_fifo_cfg __devinitdata ep0_cfg = {
+static struct musb_fifo_cfg ep0_cfg = {
.style = FIFO_RXTX, .maxpacket = 64,
};
-static int __devinit ep_config_from_table(struct musb *musb)
+static int ep_config_from_table(struct musb *musb)
{
const struct musb_fifo_cfg *cfg;
unsigned i, n;
@@ -1351,7 +1329,7 @@ done:
* ep_config_from_hw - when MUSB_C_DYNFIFO_DEF is false
* @param musb the controller
*/
-static int __devinit ep_config_from_hw(struct musb *musb)
+static int ep_config_from_hw(struct musb *musb)
{
u8 epnum = 0;
struct musb_hw_ep *hw_ep;
@@ -1398,7 +1376,7 @@ enum { MUSB_CONTROLLER_MHDRC, MUSB_CONTROLLER_HDRC, };
/* Initialize MUSB (M)HDRC part of the USB hardware subsystem;
* configure endpoints, or take their config from silicon
*/
-static int __devinit musb_core_init(u16 musb_type, struct musb *musb)
+static int musb_core_init(u16 musb_type, struct musb *musb)
{
u8 reg;
char *type;
@@ -1523,33 +1501,6 @@ static int __devinit musb_core_init(u16 musb_type, struct musb *musb)
/*-------------------------------------------------------------------------*/
-#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) || \
- defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500)
-
-static irqreturn_t generic_interrupt(int irq, void *__hci)
-{
- unsigned long flags;
- irqreturn_t retval = IRQ_NONE;
- struct musb *musb = __hci;
-
- spin_lock_irqsave(&musb->lock, flags);
-
- musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
- musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
- musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
-
- if (musb->int_usb || musb->int_tx || musb->int_rx)
- retval = musb_interrupt(musb);
-
- spin_unlock_irqrestore(&musb->lock, flags);
-
- return retval;
-}
-
-#else
-#define generic_interrupt NULL
-#endif
-
/*
* handle all the irqs defined by the HDRC core. for now we expect: other
* irq sources (phy, dma, etc) will be handled first, musb->int_* values
@@ -1560,12 +1511,11 @@ static irqreturn_t generic_interrupt(int irq, void *__hci)
irqreturn_t musb_interrupt(struct musb *musb)
{
irqreturn_t retval = IRQ_NONE;
- u8 devctl, power;
+ u8 devctl;
int ep_num;
u32 reg;
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
- power = musb_readb(musb->mregs, MUSB_POWER);
dev_dbg(musb->controller, "** IRQ %s usb%04x tx%04x rx%04x\n",
(devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral",
@@ -1576,7 +1526,7 @@ irqreturn_t musb_interrupt(struct musb *musb)
*/
if (musb->int_usb)
retval |= musb_stage0_irq(musb, musb->int_usb,
- devctl, power);
+ devctl);
/* "stage 1" is handling endpoint irqs */
@@ -1628,7 +1578,7 @@ irqreturn_t musb_interrupt(struct musb *musb)
EXPORT_SYMBOL_GPL(musb_interrupt);
#ifndef CONFIG_MUSB_PIO_ONLY
-static bool __devinitdata use_dma = 1;
+static bool use_dma = 1;
/* "modprobe ... use_dma=0" etc */
module_param(use_dma, bool, 0);
@@ -1809,8 +1759,7 @@ static void musb_irq_work(struct work_struct *data)
* Init support
*/
-static struct musb *__devinit
-allocate_instance(struct device *dev,
+static struct musb *allocate_instance(struct device *dev,
struct musb_hdrc_config *config, void __iomem *mbase)
{
struct musb *musb;
@@ -1885,7 +1834,7 @@ static void musb_free(struct musb *musb)
* @ctrl: virtual address of controller registers,
* not yet corrected for platform-specific offsets
*/
-static int __devinit
+static int
musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
{
int status;
@@ -1919,7 +1868,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
musb->ops = plat->platform_ops;
/* The musb_platform_init() call:
- * - adjusts musb->mregs and musb->isr if needed,
+ * - adjusts musb->mregs
+ * - sets the musb->isr
* - may initialize an integrated tranceiver
* - initializes musb->xceiv, usually by otg_get_phy()
* - stops powering VBUS
@@ -1929,7 +1879,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
* external/discrete ones in various flavors (twl4030 family,
* isp1504, non-OTG, etc) mostly hooking up through ULPI.
*/
- musb->isr = generic_interrupt;
status = musb_platform_init(musb);
if (status < 0)
goto fail1;
@@ -2060,7 +2009,7 @@ fail0:
/* all implementations (PCI bridge to FPGA, VLYNQ, etc) should just
* bridge to a platform device; this driver then suffices.
*/
-static int __devinit musb_probe(struct platform_device *pdev)
+static int musb_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int irq = platform_get_irq_byname(pdev, "mc");
@@ -2085,7 +2034,7 @@ static int __devinit musb_probe(struct platform_device *pdev)
return status;
}
-static int __devexit musb_remove(struct platform_device *pdev)
+static int musb_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct musb *musb = dev_to_musb(dev);
@@ -2120,8 +2069,6 @@ static void musb_save_context(struct musb *musb)
musb->context.testmode = musb_readb(musb_base, MUSB_TESTMODE);
musb->context.busctl = musb_read_ulpi_buscontrol(musb->mregs);
musb->context.power = musb_readb(musb_base, MUSB_POWER);
- musb->context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE);
- musb->context.intrrxe = musb_readw(musb_base, MUSB_INTRRXE);
musb->context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE);
musb->context.index = musb_readb(musb_base, MUSB_INDEX);
musb->context.devctl = musb_readb(musb_base, MUSB_DEVCTL);
@@ -2194,8 +2141,8 @@ static void musb_restore_context(struct musb *musb)
musb_writeb(musb_base, MUSB_TESTMODE, musb->context.testmode);
musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl);
musb_writeb(musb_base, MUSB_POWER, musb->context.power);
- musb_writew(musb_base, MUSB_INTRTXE, musb->context.intrtxe);
- musb_writew(musb_base, MUSB_INTRRXE, musb->context.intrrxe);
+ musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe);
+ musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe);
musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe);
musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl);
@@ -2340,7 +2287,7 @@ static struct platform_driver musb_driver = {
.pm = MUSB_DEV_PM_OPS,
},
.probe = musb_probe,
- .remove = __devexit_p(musb_remove),
+ .remove = musb_remove,
.shutdown = musb_shutdown,
};
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index c158aacd6de..7fb4819a6f1 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -288,7 +288,6 @@ struct musb_csr_regs {
struct musb_context_registers {
u8 power;
- u16 intrtxe, intrrxe;
u8 intrusbe;
u16 frame;
u8 index, testmode;
@@ -313,6 +312,8 @@ struct musb {
struct work_struct irq_work;
u16 hwvers;
+ u16 intrrxe;
+ u16 intrtxe;
/* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
#define MUSB_PORT_STAT_RESUME (1 << 31)
@@ -521,8 +522,6 @@ extern const char musb_driver_name[];
extern void musb_start(struct musb *musb);
extern void musb_stop(struct musb *musb);
-extern int musb_get_id(struct device *dev, gfp_t gfp_mask);
-extern void musb_put_id(struct device *dev, int id);
extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src);
extern void musb_read_fifo(struct musb_hw_ep *ep, u16 len, u8 *dst);
diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c
index 1d6e8af94c0..4c216790e86 100644
--- a/drivers/usb/musb/musb_debugfs.c
+++ b/drivers/usb/musb/musb_debugfs.c
@@ -233,7 +233,7 @@ static const struct file_operations musb_test_mode_fops = {
.release = single_release,
};
-int __devinit musb_init_debugfs(struct musb *musb)
+int musb_init_debugfs(struct musb *musb)
{
struct dentry *root;
struct dentry *file;
diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h
index 24d39210d4a..1b6b827b769 100644
--- a/drivers/usb/musb/musb_dma.h
+++ b/drivers/usb/musb/musb_dma.h
@@ -178,8 +178,7 @@ struct dma_controller {
extern void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit);
-extern struct dma_controller *__devinit
-dma_controller_create(struct musb *, void __iomem *);
+extern struct dma_controller *dma_controller_create(struct musb *, void __iomem *);
extern void dma_controller_destroy(struct dma_controller *);
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index ff5f112053d..9a975aa0dee 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -124,8 +124,44 @@ struct dsps_glue {
const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
struct timer_list timer[2]; /* otg_workaround timer */
unsigned long last_timer[2]; /* last timer data for each instance */
+ u32 __iomem *usb_ctrl[2];
};
+#define DSPS_AM33XX_CONTROL_MODULE_PHYS_0 0x44e10620
+#define DSPS_AM33XX_CONTROL_MODULE_PHYS_1 0x44e10628
+
+static const resource_size_t dsps_control_module_phys[] = {
+ DSPS_AM33XX_CONTROL_MODULE_PHYS_0,
+ DSPS_AM33XX_CONTROL_MODULE_PHYS_1,
+};
+
+/**
+ * musb_dsps_phy_control - phy on/off
+ * @glue: struct dsps_glue *
+ * @id: musb instance
+ * @on: flag for phy to be switched on or off
+ *
+ * This is to enable the PHY using usb_ctrl register in system control
+ * module space.
+ *
+ * XXX: This function will be removed once we have a seperate driver for
+ * control module
+ */
+static void musb_dsps_phy_control(struct dsps_glue *glue, u8 id, u8 on)
+{
+ u32 usbphycfg;
+
+ usbphycfg = readl(glue->usb_ctrl[id]);
+
+ if (on) {
+ usbphycfg &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN);
+ usbphycfg |= USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN;
+ } else {
+ usbphycfg |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN;
+ }
+
+ writel(usbphycfg, glue->usb_ctrl[id]);
+}
/**
* dsps_musb_enable - enable interrupts
*/
@@ -296,7 +332,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
* Also, DRVVBUS pulses for SRP (but not at 5V) ...
*/
if (usbintr & MUSB_INTR_BABBLE)
- pr_info("CAUTION: musb: Babble Interrupt Occured\n");
+ pr_info("CAUTION: musb: Babble Interrupt Occurred\n");
if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) {
int drvvbus = dsps_readl(reg_base, wrp->status);
@@ -365,11 +401,9 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
static int dsps_musb_init(struct musb *musb)
{
struct device *dev = musb->controller;
- struct musb_hdrc_platform_data *plat = dev->platform_data;
struct platform_device *pdev = to_platform_device(dev);
struct dsps_glue *glue = dev_get_drvdata(dev->parent);
const struct dsps_musb_wrapper *wrp = glue->wrp;
- struct omap_musb_board_data *data = plat->board_data;
void __iomem *reg_base = musb->ctrl_base;
u32 rev, val;
int status;
@@ -377,7 +411,8 @@ static int dsps_musb_init(struct musb *musb)
/* mentor core register starts at offset of 0x400 from musb base */
musb->mregs += wrp->musb_core_offset;
- /* Get the NOP PHY */
+ /* NOP driver needs change if supporting dual instance */
+ usb_nop_xceiv_register();
musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
if (IS_ERR_OR_NULL(musb->xceiv))
return -ENODEV;
@@ -395,8 +430,7 @@ static int dsps_musb_init(struct musb *musb)
dsps_writel(reg_base, wrp->control, (1 << wrp->reset));
/* Start the on-chip PHY and its PLL. */
- if (data->set_phy_power)
- data->set_phy_power(1);
+ musb_dsps_phy_control(glue, pdev->id, 1);
musb->isr = dsps_interrupt;
@@ -418,16 +452,13 @@ err0:
static int dsps_musb_exit(struct musb *musb)
{
struct device *dev = musb->controller;
- struct musb_hdrc_platform_data *plat = dev->platform_data;
- struct omap_musb_board_data *data = plat->board_data;
struct platform_device *pdev = to_platform_device(dev);
struct dsps_glue *glue = dev_get_drvdata(dev->parent);
del_timer_sync(&glue->timer[pdev->id]);
/* Shutdown the on-chip PHY and its PLL. */
- if (data->set_phy_power)
- data->set_phy_power(0);
+ musb_dsps_phy_control(glue, pdev->id, 0);
/* NOP driver needs change if supporting dual instance */
usb_put_phy(musb->xceiv);
@@ -448,7 +479,7 @@ static struct musb_platform_ops dsps_ops = {
static u64 musb_dmamask = DMA_BIT_MASK(32);
-static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
+static int dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
{
struct device *dev = glue->dev;
struct platform_device *pdev = to_platform_device(dev);
@@ -459,24 +490,33 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
struct resource *res;
struct resource resources[2];
char res_name[11];
- int ret, musbid;
+ int ret;
- /* get memory resource */
- snprintf(res_name, sizeof(res_name), "musb%d", id);
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
+ resources[0].start = dsps_control_module_phys[id];
+ resources[0].end = resources[0].start + SZ_4 - 1;
+ resources[0].flags = IORESOURCE_MEM;
+
+ glue->usb_ctrl[id] = devm_request_and_ioremap(&pdev->dev, resources);
+ if (glue->usb_ctrl[id] == NULL) {
+ dev_err(dev, "Failed to obtain usb_ctrl%d memory\n", id);
+ ret = -ENODEV;
+ goto err0;
+ }
+
+ /* first resource is for usbss, so start index from 1 */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, id + 1);
if (!res) {
- dev_err(dev, "%s get mem resource failed\n", res_name);
+ dev_err(dev, "failed to get memory for instance %d\n", id);
ret = -ENODEV;
goto err0;
}
res->parent = NULL;
resources[0] = *res;
- /* get irq resource */
- snprintf(res_name, sizeof(res_name), "musb%d-irq", id);
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name);
+ /* first resource is for usbss, so start index from 1 */
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, id + 1);
if (!res) {
- dev_err(dev, "%s get irq resource failed\n", res_name);
+ dev_err(dev, "failed to get irq for instance %d\n", id);
ret = -ENODEV;
goto err0;
}
@@ -484,22 +524,14 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
resources[1] = *res;
resources[1].name = "mc";
- /* get the musb id */
- musbid = musb_get_id(dev, GFP_KERNEL);
- if (musbid < 0) {
- dev_err(dev, "failed to allocate musb id\n");
- ret = -ENOMEM;
- goto err0;
- }
/* allocate the child platform device */
- musb = platform_device_alloc("musb-hdrc", musbid);
+ musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
if (!musb) {
dev_err(dev, "failed to allocate musb device\n");
ret = -ENOMEM;
- goto err1;
+ goto err0;
}
- musb->id = musbid;
musb->dev.parent = dev;
musb->dev.dma_mask = &musb_dmamask;
musb->dev.coherent_dma_mask = musb_dmamask;
@@ -556,20 +588,11 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
err2:
platform_device_put(musb);
-err1:
- musb_put_id(dev, musbid);
err0:
return ret;
}
-static void dsps_delete_musb_pdev(struct dsps_glue *glue, u8 id)
-{
- musb_put_id(glue->dev, glue->musb[id]->id);
- platform_device_del(glue->musb[id]);
- platform_device_put(glue->musb[id]);
-}
-
-static int __devinit dsps_probe(struct platform_device *pdev)
+static int dsps_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
const struct of_device_id *match;
@@ -628,7 +651,7 @@ static int __devinit dsps_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to create child pdev\n");
/* release resources of previously created instances */
for (i--; i >= 0 ; i--)
- dsps_delete_musb_pdev(glue, i);
+ platform_device_unregister(glue->musb[i]);
goto err3;
}
}
@@ -645,7 +668,7 @@ err1:
err0:
return ret;
}
-static int __devexit dsps_remove(struct platform_device *pdev)
+static int dsps_remove(struct platform_device *pdev)
{
struct dsps_glue *glue = platform_get_drvdata(pdev);
const struct dsps_musb_wrapper *wrp = glue->wrp;
@@ -653,7 +676,7 @@ static int __devexit dsps_remove(struct platform_device *pdev)
/* delete the child platform device */
for (i = 0; i < wrp->instances ; i++)
- dsps_delete_musb_pdev(glue, i);
+ platform_device_unregister(glue->musb[i]);
/* disable usbss clocks */
pm_runtime_put(&pdev->dev);
@@ -666,24 +689,26 @@ static int __devexit dsps_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int dsps_suspend(struct device *dev)
{
- struct musb_hdrc_platform_data *plat = dev->platform_data;
- struct omap_musb_board_data *data = plat->board_data;
+ struct platform_device *pdev = to_platform_device(dev->parent);
+ struct dsps_glue *glue = platform_get_drvdata(pdev);
+ const struct dsps_musb_wrapper *wrp = glue->wrp;
+ int i;
- /* Shutdown the on-chip PHY and its PLL. */
- if (data->set_phy_power)
- data->set_phy_power(0);
+ for (i = 0; i < wrp->instances; i++)
+ musb_dsps_phy_control(glue, i, 0);
return 0;
}
static int dsps_resume(struct device *dev)
{
- struct musb_hdrc_platform_data *plat = dev->platform_data;
- struct omap_musb_board_data *data = plat->board_data;
+ struct platform_device *pdev = to_platform_device(dev->parent);
+ struct dsps_glue *glue = platform_get_drvdata(pdev);
+ const struct dsps_musb_wrapper *wrp = glue->wrp;
+ int i;
- /* Start the on-chip PHY and its PLL. */
- if (data->set_phy_power)
- data->set_phy_power(1);
+ for (i = 0; i < wrp->instances; i++)
+ musb_dsps_phy_control(glue, i, 1);
return 0;
}
@@ -691,7 +716,7 @@ static int dsps_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume);
-static const struct dsps_musb_wrapper ti81xx_driver_data __devinitconst = {
+static const struct dsps_musb_wrapper ti81xx_driver_data = {
.revision = 0x00,
.control = 0x14,
.status = 0x18,
@@ -719,10 +744,10 @@ static const struct dsps_musb_wrapper ti81xx_driver_data __devinitconst = {
.rxep_bitmap = (0xfffe << 16),
.musb_core_offset = 0x400,
.poll_seconds = 2,
- .instances = 2,
+ .instances = 1,
};
-static const struct platform_device_id musb_dsps_id_table[] __devinitconst = {
+static const struct platform_device_id musb_dsps_id_table[] = {
{
.name = "musb-ti81xx",
.driver_data = (kernel_ulong_t) &ti81xx_driver_data,
@@ -732,7 +757,7 @@ static const struct platform_device_id musb_dsps_id_table[] __devinitconst = {
MODULE_DEVICE_TABLE(platform, musb_dsps_id_table);
#ifdef CONFIG_OF
-static const struct of_device_id musb_dsps_of_match[] __devinitconst = {
+static const struct of_device_id musb_dsps_of_match[] = {
{ .compatible = "ti,musb-am33xx",
.data = (void *) &ti81xx_driver_data, },
{ },
@@ -742,7 +767,7 @@ MODULE_DEVICE_TABLE(of, musb_dsps_of_match);
static struct platform_driver dsps_usbss_driver = {
.probe = dsps_probe,
- .remove = __devexit_p(dsps_remove),
+ .remove = dsps_remove,
.driver = {
.name = "musb-dsps",
.pm = &dsps_pm_ops,
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index d0b87e7b4ab..876787438c2 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -707,11 +707,12 @@ static void rxstate(struct musb *musb, struct musb_request *req)
fifo_count = musb_readw(epio, MUSB_RXCOUNT);
/*
- * use mode 1 only if we expect data of at least ep packet_sz
- * and have not yet received a short packet
+ * Enable Mode 1 on RX transfers only when short_not_ok flag
+ * is set. Currently short_not_ok flag is set only from
+ * file_storage and f_mass_storage drivers
*/
- if ((request->length - request->actual >= musb_ep->packet_sz) &&
- (fifo_count >= musb_ep->packet_sz))
+
+ if (request->short_not_ok && fifo_count == musb_ep->packet_sz)
use_mode_1 = 1;
else
use_mode_1 = 0;
@@ -727,6 +728,27 @@ static void rxstate(struct musb *musb, struct musb_request *req)
c = musb->dma_controller;
channel = musb_ep->dma;
+ /* We use DMA Req mode 0 in rx_csr, and DMA controller operates in
+ * mode 0 only. So we do not get endpoint interrupts due to DMA
+ * completion. We only get interrupts from DMA controller.
+ *
+ * We could operate in DMA mode 1 if we knew the size of the tranfer
+ * in advance. For mass storage class, request->length = what the host
+ * sends, so that'd work. But for pretty much everything else,
+ * request->length is routinely more than what the host sends. For
+ * most these gadgets, end of is signified either by a short packet,
+ * or filling the last byte of the buffer. (Sending extra data in
+ * that last pckate should trigger an overflow fault.) But in mode 1,
+ * we don't get DMA completion interrupt for short packets.
+ *
+ * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1),
+ * to get endpoint interrupt on every DMA req, but that didn't seem
+ * to work reliably.
+ *
+ * REVISIT an updated g_file_storage can set req->short_not_ok, which
+ * then becomes usable as a runtime "use mode 1" hint...
+ */
+
/* Experimental: Mode1 works with mass storage use cases */
if (use_mode_1) {
csr |= MUSB_RXCSR_AUTOCLEAR;
@@ -1068,7 +1090,6 @@ static int musb_gadget_enable(struct usb_ep *ep,
*/
musb_ep_select(mbase, epnum);
if (usb_endpoint_dir_in(desc)) {
- u16 int_txe = musb_readw(mbase, MUSB_INTRTXE);
if (hw_ep->is_shared_fifo)
musb_ep->is_in = 1;
@@ -1080,8 +1101,8 @@ static int musb_gadget_enable(struct usb_ep *ep,
goto fail;
}
- int_txe |= (1 << epnum);
- musb_writew(mbase, MUSB_INTRTXE, int_txe);
+ musb->intrtxe |= (1 << epnum);
+ musb_writew(mbase, MUSB_INTRTXE, musb->intrtxe);
/* REVISIT if can_bulk_split(), use by updating "tmp";
* likewise high bandwidth periodic tx
@@ -1108,7 +1129,6 @@ static int musb_gadget_enable(struct usb_ep *ep,
musb_writew(regs, MUSB_TXCSR, csr);
} else {
- u16 int_rxe = musb_readw(mbase, MUSB_INTRRXE);
if (hw_ep->is_shared_fifo)
musb_ep->is_in = 0;
@@ -1120,8 +1140,8 @@ static int musb_gadget_enable(struct usb_ep *ep,
goto fail;
}
- int_rxe |= (1 << epnum);
- musb_writew(mbase, MUSB_INTRRXE, int_rxe);
+ musb->intrrxe |= (1 << epnum);
+ musb_writew(mbase, MUSB_INTRRXE, musb->intrrxe);
/* REVISIT if can_bulk_combine() use by updating "tmp"
* likewise high bandwidth periodic rx
@@ -1209,14 +1229,12 @@ static int musb_gadget_disable(struct usb_ep *ep)
/* zero the endpoint sizes */
if (musb_ep->is_in) {
- u16 int_txe = musb_readw(musb->mregs, MUSB_INTRTXE);
- int_txe &= ~(1 << epnum);
- musb_writew(musb->mregs, MUSB_INTRTXE, int_txe);
+ musb->intrtxe &= ~(1 << epnum);
+ musb_writew(musb->mregs, MUSB_INTRTXE, musb->intrtxe);
musb_writew(epio, MUSB_TXMAXP, 0);
} else {
- u16 int_rxe = musb_readw(musb->mregs, MUSB_INTRRXE);
- int_rxe &= ~(1 << epnum);
- musb_writew(musb->mregs, MUSB_INTRRXE, int_rxe);
+ musb->intrrxe &= ~(1 << epnum);
+ musb_writew(musb->mregs, MUSB_INTRRXE, musb->intrrxe);
musb_writew(epio, MUSB_RXMAXP, 0);
}
@@ -1532,7 +1550,7 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep)
void __iomem *epio = musb->endpoints[epnum].regs;
void __iomem *mbase;
unsigned long flags;
- u16 csr, int_txe;
+ u16 csr;
mbase = musb->mregs;
@@ -1540,8 +1558,7 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep)
musb_ep_select(mbase, (u8) epnum);
/* disable interrupts */
- int_txe = musb_readw(mbase, MUSB_INTRTXE);
- musb_writew(mbase, MUSB_INTRTXE, int_txe & ~(1 << epnum));
+ musb_writew(mbase, MUSB_INTRTXE, musb->intrtxe & ~(1 << epnum));
if (musb_ep->is_in) {
csr = musb_readw(epio, MUSB_TXCSR);
@@ -1565,7 +1582,7 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep)
}
/* re-enable interrupt */
- musb_writew(mbase, MUSB_INTRTXE, int_txe);
+ musb_writew(mbase, MUSB_INTRTXE, musb->intrtxe);
spin_unlock_irqrestore(&musb->lock, flags);
}
@@ -1770,7 +1787,7 @@ static void musb_gadget_release(struct device *dev)
}
-static void __devinit
+static void
init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in)
{
struct musb_hw_ep *hw_ep = musb->endpoints + epnum;
@@ -1807,7 +1824,7 @@ init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in)
* Initialize the endpoints exposed to peripheral drivers, with backlinks
* to the rest of the driver state.
*/
-static inline void __devinit musb_g_init_endpoints(struct musb *musb)
+static inline void musb_g_init_endpoints(struct musb *musb)
{
u8 epnum;
struct musb_hw_ep *hw_ep;
@@ -1840,7 +1857,7 @@ static inline void __devinit musb_g_init_endpoints(struct musb *musb)
/* called once during driver setup to initialize and link into
* the driver model; memory is zeroed.
*/
-int __devinit musb_gadget_setup(struct musb *musb)
+int musb_gadget_setup(struct musb *musb)
{
int status;
@@ -2154,10 +2171,9 @@ __acquires(musb->lock)
u8 devctl = musb_readb(mbase, MUSB_DEVCTL);
u8 power;
- dev_dbg(musb->controller, "<== %s addr=%x driver '%s'\n",
+ dev_dbg(musb->controller, "<== %s driver '%s'\n",
(devctl & MUSB_DEVCTL_BDEVICE)
? "B-Device" : "A-Device",
- musb_readb(mbase, MUSB_FADDR),
musb->gadget_driver
? musb->gadget_driver->driver.name
: NULL
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c
index e40d7647caf..c9c1ac4e075 100644
--- a/drivers/usb/musb/musb_gadget_ep0.c
+++ b/drivers/usb/musb/musb_gadget_ep0.c
@@ -673,10 +673,8 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb)
csr = musb_readw(regs, MUSB_CSR0);
len = musb_readb(regs, MUSB_COUNT0);
- dev_dbg(musb->controller, "csr %04x, count %d, myaddr %d, ep0stage %s\n",
- csr, len,
- musb_readb(mbase, MUSB_FADDR),
- decode_ep0stage(musb->ep0_state));
+ dev_dbg(musb->controller, "csr %04x, count %d, ep0stage %s\n",
+ csr, len, decode_ep0stage(musb->ep0_state));
if (csr & MUSB_CSR0_P_DATAEND) {
/*
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 3df6a76b851..e9f0fd9ddd2 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -740,7 +740,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
csr = musb_readw(epio, MUSB_TXCSR);
/* disable interrupt in case we flush */
- int_txe = musb_readw(mbase, MUSB_INTRTXE);
+ int_txe = musb->intrtxe;
musb_writew(mbase, MUSB_INTRTXE, int_txe & ~(1 << epnum));
/* general endpoint setup */
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 0fc6ca6bc60..3d1fd52a15a 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -380,8 +380,7 @@ void dma_controller_destroy(struct dma_controller *c)
kfree(controller);
}
-struct dma_controller *__devinit
-dma_controller_create(struct musb *musb, void __iomem *base)
+struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *base)
{
struct musb_dma_controller *controller;
struct device *dev = musb->controller;
diff --git a/drivers/usb/musb/musbhsdma.h b/drivers/usb/musb/musbhsdma.h
index 320fd4afb93..f7b13fd2525 100644
--- a/drivers/usb/musb/musbhsdma.h
+++ b/drivers/usb/musb/musbhsdma.h
@@ -31,10 +31,6 @@
*
*/
-#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430)
-#include "omap2430.h"
-#endif
-
#ifndef CONFIG_BLACKFIN
#define MUSB_HSDMA_BASE 0x200
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index a538fe17a96..da00af46079 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -333,6 +333,26 @@ static void omap_musb_mailbox_work(struct work_struct *mailbox_work)
omap_musb_set_mailbox(glue);
}
+static irqreturn_t omap2430_musb_interrupt(int irq, void *__hci)
+{
+ unsigned long flags;
+ irqreturn_t retval = IRQ_NONE;
+ struct musb *musb = __hci;
+
+ spin_lock_irqsave(&musb->lock, flags);
+
+ musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
+ musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
+ musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
+
+ if (musb->int_usb || musb->int_tx || musb->int_rx)
+ retval = musb_interrupt(musb);
+
+ spin_unlock_irqrestore(&musb->lock, flags);
+
+ return retval;
+}
+
static int omap2430_musb_init(struct musb *musb)
{
u32 l;
@@ -352,6 +372,8 @@ static int omap2430_musb_init(struct musb *musb)
return -ENODEV;
}
+ musb->isr = omap2430_musb_interrupt;
+
status = pm_runtime_get_sync(dev);
if (status < 0) {
dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
@@ -468,7 +490,7 @@ static const struct musb_platform_ops omap2430_ops = {
static u64 omap2430_dmamask = DMA_BIT_MASK(32);
-static int __devinit omap2430_probe(struct platform_device *pdev)
+static int omap2430_probe(struct platform_device *pdev)
{
struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
struct omap_musb_board_data *data;
@@ -478,7 +500,6 @@ static int __devinit omap2430_probe(struct platform_device *pdev)
struct musb_hdrc_config *config;
struct resource *res;
int ret = -ENOMEM;
- int musbid;
glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
if (!glue) {
@@ -486,21 +507,12 @@ static int __devinit omap2430_probe(struct platform_device *pdev)
goto err0;
}
- /* get the musb id */
- musbid = musb_get_id(&pdev->dev, GFP_KERNEL);
- if (musbid < 0) {
- dev_err(&pdev->dev, "failed to allocate musb id\n");
- ret = -ENOMEM;
- goto err0;
- }
-
- musb = platform_device_alloc("musb-hdrc", musbid);
+ musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
if (!musb) {
dev_err(&pdev->dev, "failed to allocate musb device\n");
- goto err1;
+ goto err0;
}
- musb->id = musbid;
musb->dev.parent = &pdev->dev;
musb->dev.dma_mask = &omap2430_dmamask;
musb->dev.coherent_dma_mask = omap2430_dmamask;
@@ -521,7 +533,7 @@ static int __devinit omap2430_probe(struct platform_device *pdev)
dev_err(&pdev->dev,
"failed to allocate musb platfrom data\n");
ret = -ENOMEM;
- goto err1;
+ goto err2;
}
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
@@ -529,14 +541,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev)
dev_err(&pdev->dev,
"failed to allocate musb board data\n");
ret = -ENOMEM;
- goto err1;
+ goto err2;
}
config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
if (!data) {
dev_err(&pdev->dev,
"failed to allocate musb hdrc config\n");
- goto err1;
+ goto err2;
}
of_property_read_u32(np, "mode", (u32 *)&pdata->mode);
@@ -589,19 +601,15 @@ static int __devinit omap2430_probe(struct platform_device *pdev)
err2:
platform_device_put(musb);
-err1:
- musb_put_id(&pdev->dev, musbid);
-
err0:
return ret;
}
-static int __devexit omap2430_remove(struct platform_device *pdev)
+static int omap2430_remove(struct platform_device *pdev)
{
struct omap2430_glue *glue = platform_get_drvdata(pdev);
cancel_work_sync(&glue->omap_musb_mailbox_work);
- musb_put_id(&pdev->dev, glue->musb->id);
platform_device_unregister(glue->musb);
return 0;
@@ -666,7 +674,7 @@ MODULE_DEVICE_TABLE(of, omap2430_id_table);
static struct platform_driver omap2430_driver = {
.probe = omap2430_probe,
- .remove = __devexit_p(omap2430_remove),
+ .remove = omap2430_remove,
.driver = {
.name = "musb-omap2430",
.pm = DEV_PM_OPS,
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
index dc4d75ea13a..8bde6fc5eb7 100644
--- a/drivers/usb/musb/tusb6010.c
+++ b/drivers/usb/musb/tusb6010.c
@@ -1153,14 +1153,13 @@ static const struct musb_platform_ops tusb_ops = {
static u64 tusb_dmamask = DMA_BIT_MASK(32);
-static int __devinit tusb_probe(struct platform_device *pdev)
+static int tusb_probe(struct platform_device *pdev)
{
struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
struct platform_device *musb;
struct tusb6010_glue *glue;
int ret = -ENOMEM;
- int musbid;
glue = kzalloc(sizeof(*glue), GFP_KERNEL);
if (!glue) {
@@ -1168,21 +1167,12 @@ static int __devinit tusb_probe(struct platform_device *pdev)
goto err0;
}
- /* get the musb id */
- musbid = musb_get_id(&pdev->dev, GFP_KERNEL);
- if (musbid < 0) {
- dev_err(&pdev->dev, "failed to allocate musb id\n");
- ret = -ENOMEM;
- goto err1;
- }
-
- musb = platform_device_alloc("musb-hdrc", musbid);
+ musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
if (!musb) {
dev_err(&pdev->dev, "failed to allocate musb device\n");
- goto err2;
+ goto err1;
}
- musb->id = musbid;
musb->dev.parent = &pdev->dev;
musb->dev.dma_mask = &tusb_dmamask;
musb->dev.coherent_dma_mask = tusb_dmamask;
@@ -1218,9 +1208,6 @@ static int __devinit tusb_probe(struct platform_device *pdev)
err3:
platform_device_put(musb);
-err2:
- musb_put_id(&pdev->dev, musbid);
-
err1:
kfree(glue);
@@ -1228,13 +1215,11 @@ err0:
return ret;
}
-static int __devexit tusb_remove(struct platform_device *pdev)
+static int tusb_remove(struct platform_device *pdev)
{
struct tusb6010_glue *glue = platform_get_drvdata(pdev);
- musb_put_id(&pdev->dev, glue->musb->id);
- platform_device_del(glue->musb);
- platform_device_put(glue->musb);
+ platform_device_unregister(glue->musb);
kfree(glue);
return 0;
@@ -1242,7 +1227,7 @@ static int __devexit tusb_remove(struct platform_device *pdev)
static struct platform_driver tusb_driver = {
.probe = tusb_probe,
- .remove = __devexit_p(tusb_remove),
+ .remove = tusb_remove,
.driver = {
.name = "musb-tusb",
},
@@ -1251,15 +1236,4 @@ static struct platform_driver tusb_driver = {
MODULE_DESCRIPTION("TUSB6010 MUSB Glue Layer");
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
MODULE_LICENSE("GPL v2");
-
-static int __init tusb_init(void)
-{
- return platform_driver_register(&tusb_driver);
-}
-module_init(tusb_init);
-
-static void __exit tusb_exit(void)
-{
- platform_driver_unregister(&tusb_driver);
-}
-module_exit(tusb_exit);
+module_platform_driver(tusb_driver);
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 7a62b95dac2..2c46d42e661 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -661,8 +661,7 @@ void dma_controller_destroy(struct dma_controller *c)
kfree(tusb_dma);
}
-struct dma_controller *__devinit
-dma_controller_create(struct musb *musb, void __iomem *base)
+struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *base)
{
void __iomem *tbase = musb->ctrl_base;
struct tusb_omap_dma *tusb_dma;
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c
index d62a91fedc2..a27ca1a9c99 100644
--- a/drivers/usb/musb/ux500.c
+++ b/drivers/usb/musb/ux500.c
@@ -36,6 +36,26 @@ struct ux500_glue {
};
#define glue_to_musb(g) platform_get_drvdata(g->musb)
+static irqreturn_t ux500_musb_interrupt(int irq, void *__hci)
+{
+ unsigned long flags;
+ irqreturn_t retval = IRQ_NONE;
+ struct musb *musb = __hci;
+
+ spin_lock_irqsave(&musb->lock, flags);
+
+ musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
+ musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
+ musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
+
+ if (musb->int_usb || musb->int_tx || musb->int_rx)
+ retval = musb_interrupt(musb);
+
+ spin_unlock_irqrestore(&musb->lock, flags);
+
+ return retval;
+}
+
static int ux500_musb_init(struct musb *musb)
{
musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
@@ -44,6 +64,8 @@ static int ux500_musb_init(struct musb *musb)
return -ENODEV;
}
+ musb->isr = ux500_musb_interrupt;
+
return 0;
}
@@ -59,13 +81,12 @@ static const struct musb_platform_ops ux500_ops = {
.exit = ux500_musb_exit,
};
-static int __devinit ux500_probe(struct platform_device *pdev)
+static int ux500_probe(struct platform_device *pdev)
{
struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
struct platform_device *musb;
struct ux500_glue *glue;
struct clk *clk;
-
int ret = -ENOMEM;
glue = kzalloc(sizeof(*glue), GFP_KERNEL);
@@ -74,18 +95,10 @@ static int __devinit ux500_probe(struct platform_device *pdev)
goto err0;
}
- /* get the musb id */
- musbid = musb_get_id(&pdev->dev, GFP_KERNEL);
- if (musbid < 0) {
- dev_err(&pdev->dev, "failed to allocate musb id\n");
- ret = -ENOMEM;
- goto err1;
- }
-
- musb = platform_device_alloc("musb-hdrc", musbid);
+ musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
if (!musb) {
dev_err(&pdev->dev, "failed to allocate musb device\n");
- goto err2;
+ goto err1;
}
clk = clk_get(&pdev->dev, "usb");
@@ -101,7 +114,6 @@ static int __devinit ux500_probe(struct platform_device *pdev)
goto err4;
}
- musb->id = musbid;
musb->dev.parent = &pdev->dev;
musb->dev.dma_mask = pdev->dev.dma_mask;
musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask;
@@ -144,9 +156,6 @@ err4:
err3:
platform_device_put(musb);
-err2:
- musb_put_id(&pdev->dev, musbid);
-
err1:
kfree(glue);
@@ -154,13 +163,11 @@ err0:
return ret;
}
-static int __devexit ux500_remove(struct platform_device *pdev)
+static int ux500_remove(struct platform_device *pdev)
{
struct ux500_glue *glue = platform_get_drvdata(pdev);
- musb_put_id(&pdev->dev, glue->musb->id);
- platform_device_del(glue->musb);
- platform_device_put(glue->musb);
+ platform_device_unregister(glue->musb);
clk_disable(glue->clk);
clk_put(glue->clk);
kfree(glue);
@@ -209,7 +216,7 @@ static const struct dev_pm_ops ux500_pm_ops = {
static struct platform_driver ux500_driver = {
.probe = ux500_probe,
- .remove = __devexit_p(ux500_remove),
+ .remove = ux500_remove,
.driver = {
.name = "musb-ux500",
.pm = DEV_PM_OPS,
@@ -219,15 +226,4 @@ static struct platform_driver ux500_driver = {
MODULE_DESCRIPTION("UX500 MUSB Glue Layer");
MODULE_AUTHOR("Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>");
MODULE_LICENSE("GPL v2");
-
-static int __init ux500_init(void)
-{
- return platform_driver_register(&ux500_driver);
-}
-module_init(ux500_init);
-
-static void __exit ux500_exit(void)
-{
- platform_driver_unregister(&ux500_driver);
-}
-module_exit(ux500_exit);
+module_platform_driver(ux500_driver);
diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c
index f1059e725ea..039e567dd3b 100644
--- a/drivers/usb/musb/ux500_dma.c
+++ b/drivers/usb/musb/ux500_dma.c
@@ -364,8 +364,7 @@ void dma_controller_destroy(struct dma_controller *c)
kfree(controller);
}
-struct dma_controller *__devinit
-dma_controller_create(struct musb *musb, void __iomem *base)
+struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *base)
{
struct ux500_dma_controller *controller;
struct platform_device *pdev = to_platform_device(musb->controller);
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index d8c8a42bff3..6223062d5d1 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -58,7 +58,7 @@ config USB_ULPI_VIEWPORT
config TWL4030_USB
tristate "TWL4030 USB Transceiver Driver"
- depends on TWL4030_CORE && REGULATOR_TWL4030
+ depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
select USB_OTG_UTILS
help
Enable this to support the USB OTG transceiver on TWL4030
@@ -68,7 +68,7 @@ config TWL4030_USB
config TWL6030_USB
tristate "TWL6030 USB Transceiver Driver"
- depends on TWL4030_CORE && OMAP_USB2
+ depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS
select USB_OTG_UTILS
help
Enable this to support the USB OTG transceiver on TWL6030
diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c
index ae8ad561f08..2d86f26a018 100644
--- a/drivers/usb/otg/ab8500-usb.c
+++ b/drivers/usb/otg/ab8500-usb.c
@@ -468,7 +468,7 @@ static int ab8500_usb_v2_res_setup(struct platform_device *pdev,
return 0;
}
-static int __devinit ab8500_usb_probe(struct platform_device *pdev)
+static int ab8500_usb_probe(struct platform_device *pdev)
{
struct ab8500_usb *ab;
struct usb_otg *otg;
@@ -546,7 +546,7 @@ fail0:
return err;
}
-static int __devexit ab8500_usb_remove(struct platform_device *pdev)
+static int ab8500_usb_remove(struct platform_device *pdev)
{
struct ab8500_usb *ab = platform_get_drvdata(pdev);
@@ -571,7 +571,7 @@ static int __devexit ab8500_usb_remove(struct platform_device *pdev)
static struct platform_driver ab8500_usb_driver = {
.probe = ab8500_usb_probe,
- .remove = __devexit_p(ab8500_usb_remove),
+ .remove = ab8500_usb_remove,
.driver = {
.name = "ab8500-usb",
.owner = THIS_MODULE,
diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c
index c19d1d7173a..d16adb41eb2 100644
--- a/drivers/usb/otg/fsl_otg.c
+++ b/drivers/usb/otg/fsl_otg.c
@@ -1110,7 +1110,7 @@ static const struct file_operations otg_fops = {
.release = fsl_otg_release,
};
-static int __devinit fsl_otg_probe(struct platform_device *pdev)
+static int fsl_otg_probe(struct platform_device *pdev)
{
int ret;
@@ -1144,7 +1144,7 @@ static int __devinit fsl_otg_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit fsl_otg_remove(struct platform_device *pdev)
+static int fsl_otg_remove(struct platform_device *pdev)
{
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
@@ -1169,7 +1169,7 @@ static int __devexit fsl_otg_remove(struct platform_device *pdev)
struct platform_driver fsl_otg_driver = {
.probe = fsl_otg_probe,
- .remove = __devexit_p(fsl_otg_remove),
+ .remove = fsl_otg_remove,
.driver = {
.name = driver_name,
.owner = THIS_MODULE,
diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c
index ceee2119bff..af9cb11626b 100644
--- a/drivers/usb/otg/isp1301_omap.c
+++ b/drivers/usb/otg/isp1301_omap.c
@@ -1493,7 +1493,7 @@ isp1301_start_hnp(struct usb_otg *otg)
/*-------------------------------------------------------------------------*/
-static int __devinit
+static int
isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
{
int status;
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 9f5fc906041..3b9f0d95113 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1606,7 +1606,7 @@ free_motg:
return ret;
}
-static int __devexit msm_otg_remove(struct platform_device *pdev)
+static int msm_otg_remove(struct platform_device *pdev)
{
struct msm_otg *motg = platform_get_drvdata(pdev);
struct usb_phy *phy = &motg->phy;
@@ -1746,7 +1746,7 @@ static const struct dev_pm_ops msm_otg_dev_pm_ops = {
#endif
static struct platform_driver msm_otg_driver = {
- .remove = __devexit_p(msm_otg_remove),
+ .remove = msm_otg_remove,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/usb/otg/mv_otg.c b/drivers/usb/otg/mv_otg.c
index 3f124e8f579..1dd57504186 100644
--- a/drivers/usb/otg/mv_otg.c
+++ b/drivers/usb/otg/mv_otg.c
@@ -958,16 +958,4 @@ static struct platform_driver mv_otg_driver = {
.resume = mv_otg_resume,
#endif
};
-
-static int __init mv_otg_init(void)
-{
- return platform_driver_register(&mv_otg_driver);
-}
-
-static void __exit mv_otg_exit(void)
-{
- platform_driver_unregister(&mv_otg_driver);
-}
-
-module_init(mv_otg_init);
-module_exit(mv_otg_exit);
+module_platform_driver(mv_otg_driver);
diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c
index 88db976647c..76302720055 100644
--- a/drivers/usb/otg/mxs-phy.c
+++ b/drivers/usb/otg/mxs-phy.c
@@ -20,7 +20,6 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
-#include <linux/workqueue.h>
#define DRIVER_NAME "mxs_phy"
@@ -35,16 +34,9 @@
#define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14)
#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1)
-/*
- * Amount of delay in miliseconds to safely enable ENHOSTDISCONDETECT bit
- * so that connection and reset processing can be completed for the root hub.
- */
-#define MXY_PHY_ENHOSTDISCONDETECT_DELAY 250
-
struct mxs_phy {
struct usb_phy phy;
struct clk *clk;
- struct delayed_work enhostdiscondetect_work;
};
#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
@@ -70,7 +62,6 @@ static int mxs_phy_init(struct usb_phy *phy)
clk_prepare_enable(mxs_phy->clk);
mxs_phy_hw_init(mxs_phy);
- INIT_DELAYED_WORK(&mxs_phy->enhostdiscondetect_work, NULL);
return 0;
}
@@ -85,46 +76,28 @@ static void mxs_phy_shutdown(struct usb_phy *phy)
clk_disable_unprepare(mxs_phy->clk);
}
-static void mxs_phy_enhostdiscondetect_delay(struct work_struct *ws)
+static int mxs_phy_on_connect(struct usb_phy *phy,
+ enum usb_device_speed speed)
{
- struct mxs_phy *mxs_phy = container_of(ws, struct mxs_phy,
- enhostdiscondetect_work.work);
-
- /* Enable HOSTDISCONDETECT after delay. */
- dev_dbg(mxs_phy->phy.dev, "Setting ENHOSTDISCONDETECT\n");
- writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
- mxs_phy->phy.io_priv + HW_USBPHY_CTRL_SET);
-}
-
-static int mxs_phy_on_connect(struct usb_phy *phy, int port)
-{
- struct mxs_phy *mxs_phy = to_mxs_phy(phy);
-
- dev_dbg(phy->dev, "Connect on port %d\n", port);
-
- mxs_phy_hw_init(mxs_phy);
+ dev_dbg(phy->dev, "%s speed device has connected\n",
+ (speed == USB_SPEED_HIGH) ? "high" : "non-high");
- /*
- * Delay enabling ENHOSTDISCONDETECT so that connection and
- * reset processing can be completed for the root hub.
- */
- dev_dbg(phy->dev, "Delaying setting ENHOSTDISCONDETECT\n");
- PREPARE_DELAYED_WORK(&mxs_phy->enhostdiscondetect_work,
- mxs_phy_enhostdiscondetect_delay);
- schedule_delayed_work(&mxs_phy->enhostdiscondetect_work,
- msecs_to_jiffies(MXY_PHY_ENHOSTDISCONDETECT_DELAY));
+ if (speed == USB_SPEED_HIGH)
+ writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ phy->io_priv + HW_USBPHY_CTRL_SET);
return 0;
}
-static int mxs_phy_on_disconnect(struct usb_phy *phy, int port)
+static int mxs_phy_on_disconnect(struct usb_phy *phy,
+ enum usb_device_speed speed)
{
- dev_dbg(phy->dev, "Disconnect on port %d\n", port);
+ dev_dbg(phy->dev, "%s speed device has disconnected\n",
+ (speed == USB_SPEED_HIGH) ? "high" : "non-high");
- /* No need to delay before clearing ENHOSTDISCONDETECT. */
- dev_dbg(phy->dev, "Clearing ENHOSTDISCONDETECT\n");
- writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
- phy->io_priv + HW_USBPHY_CTRL_CLR);
+ if (speed == USB_SPEED_HIGH)
+ writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ phy->io_priv + HW_USBPHY_CTRL_CLR);
return 0;
}
@@ -176,7 +149,7 @@ static int mxs_phy_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit mxs_phy_remove(struct platform_device *pdev)
+static int mxs_phy_remove(struct platform_device *pdev)
{
platform_set_drvdata(pdev, NULL);
@@ -191,7 +164,7 @@ MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
static struct platform_driver mxs_phy_driver = {
.probe = mxs_phy_probe,
- .remove = __devexit_p(mxs_phy_remove),
+ .remove = mxs_phy_remove,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c
index e52e35e7ada..a3ce24b94a7 100644
--- a/drivers/usb/otg/nop-usb-xceiv.c
+++ b/drivers/usb/otg/nop-usb-xceiv.c
@@ -93,7 +93,7 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host)
return 0;
}
-static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
+static int nop_usb_xceiv_probe(struct platform_device *pdev)
{
struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data;
struct nop_usb_xceiv *nop;
@@ -141,7 +141,7 @@ exit:
return err;
}
-static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev)
+static int nop_usb_xceiv_remove(struct platform_device *pdev)
{
struct nop_usb_xceiv *nop = platform_get_drvdata(pdev);
@@ -156,7 +156,7 @@ static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev)
static struct platform_driver nop_usb_xceiv_driver = {
.probe = nop_usb_xceiv_probe,
- .remove = __devexit_p(nop_usb_xceiv_remove),
+ .remove = nop_usb_xceiv_remove,
.driver = {
.name = "nop_usb_xceiv",
.owner = THIS_MODULE,
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c
index f0d2e7530cf..0a701938ab5 100644
--- a/drivers/usb/otg/twl4030-usb.c
+++ b/drivers/usb/otg/twl4030-usb.c
@@ -123,10 +123,10 @@
#define PHY_CLK_CTRL_STS 0xFF
#define PHY_DPLL_CLK (1 << 0)
-/* In module TWL4030_MODULE_PM_MASTER */
+/* In module TWL_MODULE_PM_MASTER */
#define STS_HW_CONDITIONS 0x0F
-/* In module TWL4030_MODULE_PM_RECEIVER */
+/* In module TWL_MODULE_PM_RECEIVER */
#define VUSB_DEDICATED1 0x7D
#define VUSB_DEDICATED2 0x7E
#define VUSB1V5_DEV_GRP 0x71
@@ -195,14 +195,14 @@ static int twl4030_i2c_write_u8_verify(struct twl4030_usb *twl,
}
#define twl4030_usb_write_verify(twl, address, data) \
- twl4030_i2c_write_u8_verify(twl, TWL4030_MODULE_USB, (data), (address))
+ 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(TWL4030_MODULE_USB, data, address);
+ 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);
@@ -227,7 +227,7 @@ static inline int twl4030_readb(struct twl4030_usb *twl, u8 module, u8 address)
static inline int twl4030_usb_read(struct twl4030_usb *twl, u8 address)
{
- return twl4030_readb(twl, TWL4030_MODULE_USB, address);
+ return twl4030_readb(twl, TWL_MODULE_USB, address);
}
/*-------------------------------------------------------------------------*/
@@ -264,8 +264,7 @@ static enum omap_musb_vbus_id_status
* signal is active, the OTG module is activated, and
* its interrupt may be raised (may wake the system).
*/
- status = twl4030_readb(twl, TWL4030_MODULE_PM_MASTER,
- STS_HW_CONDITIONS);
+ 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))) {
@@ -372,8 +371,7 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on)
* 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(TWL4030_MODULE_PM_RECEIVER, 0,
- VUSB_DEDICATED2);
+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);
regulator_enable(twl->usb1v5);
__twl4030_phy_power(twl, 1);
twl4030_usb_write(twl, PHY_CLK_CTRL,
@@ -419,50 +417,48 @@ static void twl4030_phy_resume(struct twl4030_usb *twl)
static int twl4030_usb_ldo_init(struct twl4030_usb *twl)
{
/* Enable writing to power configuration registers */
- twl_i2c_write_u8(TWL4030_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_CFG1,
+ TWL4030_PM_MASTER_PROTECT_KEY);
- twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
- TWL4030_PM_MASTER_KEY_CFG2,
- 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(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/
+ /*twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/
/* input to VUSB3V1 LDO is from VBAT, not VBUS */
- twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1);
+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1);
/* Initialize 3.1V regulator */
- twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP);
+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP);
twl->usb3v1 = regulator_get(twl->dev, "usb3v1");
if (IS_ERR(twl->usb3v1))
return -ENODEV;
- twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE);
+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE);
/* Initialize 1.5V regulator */
- twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP);
+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP);
twl->usb1v5 = regulator_get(twl->dev, "usb1v5");
if (IS_ERR(twl->usb1v5))
goto fail1;
- twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE);
+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE);
/* Initialize 1.8V regulator */
- twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP);
+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP);
twl->usb1v8 = regulator_get(twl->dev, "usb1v8");
if (IS_ERR(twl->usb1v8))
goto fail2;
- twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE);
+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE);
/* disable access to power configuration registers */
- twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0,
- TWL4030_PM_MASTER_PROTECT_KEY);
+ twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
+ TWL4030_PM_MASTER_PROTECT_KEY);
return 0;
@@ -579,7 +575,7 @@ static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host)
return 0;
}
-static int __devinit twl4030_usb_probe(struct platform_device *pdev)
+static int twl4030_usb_probe(struct platform_device *pdev)
{
struct twl4030_usb_data *pdata = pdev->dev.platform_data;
struct twl4030_usb *twl;
diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c
index fcadef7864f..8cd6cf49bdb 100644
--- a/drivers/usb/otg/twl6030-usb.c
+++ b/drivers/usb/otg/twl6030-usb.c
@@ -310,7 +310,7 @@ static int twl6030_set_vbus(struct phy_companion *comparator, bool enabled)
return 0;
}
-static int __devinit twl6030_usb_probe(struct platform_device *pdev)
+static int twl6030_usb_probe(struct platform_device *pdev)
{
u32 ret;
struct twl6030_usb *twl;
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 63c339b3e67..7eb73c561bd 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -32,3 +32,15 @@ config MV_U3D_PHY
help
Enable this to support Marvell USB 3.0 phy controller for Marvell
SoC.
+
+config USB_RCAR_PHY
+ tristate "Renesas R-Car USB phy support"
+ depends on USB || USB_GADGET
+ select USB_OTG_UTILS
+ help
+ Say Y here to add support for the Renesas R-Car USB phy driver.
+ This chip is typically used as USB phy for USB host, gadget.
+ This driver supports: R8A7779
+
+ To compile this driver as a module, choose M here: the
+ module will be called rcar-phy.
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index b069f29f122..1a579a860a0 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_OMAP_USB2) += omap-usb2.o
obj-$(CONFIG_USB_ISP1301) += isp1301.o
obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o
obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o
+obj-$(CONFIG_USB_RCAR_PHY) += rcar-phy.o
diff --git a/drivers/usb/phy/mv_u3d_phy.c b/drivers/usb/phy/mv_u3d_phy.c
index 9f1c5d3c60e..eaddbe3d430 100644
--- a/drivers/usb/phy/mv_u3d_phy.c
+++ b/drivers/usb/phy/mv_u3d_phy.c
@@ -262,7 +262,7 @@ calstart:
return 0;
}
-static int __devinit mv_u3d_phy_probe(struct platform_device *pdev)
+static int mv_u3d_phy_probe(struct platform_device *pdev)
{
struct mv_u3d_phy *mv_u3d_phy;
struct mv_usb_platform_data *pdata;
@@ -331,7 +331,7 @@ static int __exit mv_u3d_phy_remove(struct platform_device *pdev)
static struct platform_driver mv_u3d_phy_driver = {
.probe = mv_u3d_phy_probe,
- .remove = __devexit_p(mv_u3d_phy_remove),
+ .remove = mv_u3d_phy_remove,
.driver = {
.name = "mv-u3d-phy",
.owner = THIS_MODULE,
diff --git a/drivers/usb/phy/omap-usb2.c b/drivers/usb/phy/omap-usb2.c
index 15ab3d6f2e8..26ae8f49225 100644
--- a/drivers/usb/phy/omap-usb2.c
+++ b/drivers/usb/phy/omap-usb2.c
@@ -141,7 +141,7 @@ static int omap_usb2_suspend(struct usb_phy *x, int suspend)
return 0;
}
-static int __devinit omap_usb2_probe(struct platform_device *pdev)
+static int omap_usb2_probe(struct platform_device *pdev)
{
struct omap_usb *phy;
struct usb_otg *otg;
@@ -199,7 +199,7 @@ static int __devinit omap_usb2_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit omap_usb2_remove(struct platform_device *pdev)
+static int omap_usb2_remove(struct platform_device *pdev)
{
struct omap_usb *phy = platform_get_drvdata(pdev);
@@ -254,7 +254,7 @@ MODULE_DEVICE_TABLE(of, omap_usb2_id_table);
static struct platform_driver omap_usb2_driver = {
.probe = omap_usb2_probe,
- .remove = __devexit_p(omap_usb2_remove),
+ .remove = omap_usb2_remove,
.driver = {
.name = "omap-usb2",
.owner = THIS_MODULE,
diff --git a/drivers/usb/phy/rcar-phy.c b/drivers/usb/phy/rcar-phy.c
new file mode 100644
index 00000000000..a35681b0c50
--- /dev/null
+++ b/drivers/usb/phy/rcar-phy.c
@@ -0,0 +1,220 @@
+/*
+ * Renesas R-Car USB phy driver
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.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/io.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+
+/* USBH common register */
+#define USBPCTRL0 0x0800
+#define USBPCTRL1 0x0804
+#define USBST 0x0808
+#define USBEH0 0x080C
+#define USBOH0 0x081C
+#define USBCTL0 0x0858
+#define EIIBC1 0x0094
+#define EIIBC2 0x009C
+
+/* USBPCTRL1 */
+#define PHY_RST (1 << 2)
+#define PLL_ENB (1 << 1)
+#define PHY_ENB (1 << 0)
+
+/* USBST */
+#define ST_ACT (1 << 31)
+#define ST_PLL (1 << 30)
+
+struct rcar_usb_phy_priv {
+ struct usb_phy phy;
+ spinlock_t lock;
+
+ void __iomem *reg0;
+ void __iomem *reg1;
+ int counter;
+};
+
+#define usb_phy_to_priv(p) container_of(p, struct rcar_usb_phy_priv, phy)
+
+
+/*
+ * USB initial/install operation.
+ *
+ * This function setup USB phy.
+ * The used value and setting order came from
+ * [USB :: Initial setting] on datasheet.
+ */
+static int rcar_usb_phy_init(struct usb_phy *phy)
+{
+ struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy);
+ struct device *dev = phy->dev;
+ void __iomem *reg0 = priv->reg0;
+ void __iomem *reg1 = priv->reg1;
+ int i;
+ u32 val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->counter++ == 0) {
+
+ /*
+ * USB phy start-up
+ */
+
+ /* (1) USB-PHY standby release */
+ iowrite32(PHY_ENB, (reg0 + USBPCTRL1));
+
+ /* (2) start USB-PHY internal PLL */
+ iowrite32(PHY_ENB | PLL_ENB, (reg0 + USBPCTRL1));
+
+ /* (3) USB module status check */
+ for (i = 0; i < 1024; i++) {
+ udelay(10);
+ val = ioread32(reg0 + USBST);
+ if (val == (ST_ACT | ST_PLL))
+ break;
+ }
+
+ if (val != (ST_ACT | ST_PLL)) {
+ dev_err(dev, "USB phy not ready\n");
+ goto phy_init_end;
+ }
+
+ /* (4) USB-PHY reset clear */
+ iowrite32(PHY_ENB | PLL_ENB | PHY_RST, (reg0 + USBPCTRL1));
+
+ /* set platform specific port settings */
+ iowrite32(0x00000000, (reg0 + USBPCTRL0));
+
+ /*
+ * EHCI IP internal buffer setting
+ * EHCI IP internal buffer enable
+ *
+ * These are recommended value of a datasheet
+ * see [USB :: EHCI internal buffer setting]
+ */
+ iowrite32(0x00ff0040, (reg0 + EIIBC1));
+ iowrite32(0x00ff0040, (reg1 + EIIBC1));
+
+ iowrite32(0x00000001, (reg0 + EIIBC2));
+ iowrite32(0x00000001, (reg1 + EIIBC2));
+
+ /*
+ * Bus alignment settings
+ */
+
+ /* (1) EHCI bus alignment (little endian) */
+ iowrite32(0x00000000, (reg0 + USBEH0));
+
+ /* (1) OHCI bus alignment (little endian) */
+ iowrite32(0x00000000, (reg0 + USBOH0));
+ }
+
+phy_init_end:
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+static void rcar_usb_phy_shutdown(struct usb_phy *phy)
+{
+ struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy);
+ void __iomem *reg0 = priv->reg0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (priv->counter-- == 1) { /* last user */
+ iowrite32(0x00000000, (reg0 + USBPCTRL0));
+ iowrite32(0x00000000, (reg0 + USBPCTRL1));
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int rcar_usb_phy_probe(struct platform_device *pdev)
+{
+ struct rcar_usb_phy_priv *priv;
+ struct resource *res0, *res1;
+ struct device *dev = &pdev->dev;
+ void __iomem *reg0, *reg1;
+ int ret;
+
+ res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res0 || !res1) {
+ dev_err(dev, "Not enough platform resources\n");
+ return -EINVAL;
+ }
+
+ /*
+ * CAUTION
+ *
+ * Because this phy address is also mapped under OHCI/EHCI address area,
+ * this driver can't use devm_request_and_ioremap(dev, res) here
+ */
+ reg0 = devm_ioremap_nocache(dev, res0->start, resource_size(res0));
+ reg1 = devm_ioremap_nocache(dev, res1->start, resource_size(res1));
+ if (!reg0 || !reg1) {
+ dev_err(dev, "ioremap error\n");
+ return -ENOMEM;
+ }
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ dev_err(dev, "priv data allocation error\n");
+ return -ENOMEM;
+ }
+
+ priv->reg0 = reg0;
+ priv->reg1 = reg1;
+ priv->counter = 0;
+ priv->phy.dev = dev;
+ priv->phy.label = dev_name(dev);
+ priv->phy.init = rcar_usb_phy_init;
+ priv->phy.shutdown = rcar_usb_phy_shutdown;
+ spin_lock_init(&priv->lock);
+
+ ret = usb_add_phy(&priv->phy, USB_PHY_TYPE_USB2);
+ if (ret < 0) {
+ dev_err(dev, "usb phy addition error\n");
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, priv);
+
+ return ret;
+}
+
+static int rcar_usb_phy_remove(struct platform_device *pdev)
+{
+ struct rcar_usb_phy_priv *priv = platform_get_drvdata(pdev);
+
+ usb_remove_phy(&priv->phy);
+
+ return 0;
+}
+
+static struct platform_driver rcar_usb_phy_driver = {
+ .driver = {
+ .name = "rcar_usb_phy",
+ },
+ .probe = rcar_usb_phy_probe,
+ .remove = rcar_usb_phy_remove,
+};
+
+module_platform_driver(rcar_usb_phy_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Renesas R-Car USB phy");
+MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/drivers/usb/phy/tegra_usb_phy.c b/drivers/usb/phy/tegra_usb_phy.c
index 987116f9efc..9d13c81754e 100644
--- a/drivers/usb/phy/tegra_usb_phy.c
+++ b/drivers/usb/phy/tegra_usb_phy.c
@@ -29,7 +29,9 @@
#include <linux/usb/ulpi.h>
#include <asm/mach-types.h>
#include <linux/usb/tegra_usb_phy.h>
-#include <mach/iomap.h>
+
+#define TEGRA_USB_BASE 0xC5000000
+#define TEGRA_USB_SIZE SZ_16K
#define ULPI_VIEWPORT 0x170
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c
index 072edc1cc55..38bce046f4d 100644
--- a/drivers/usb/renesas_usbhs/common.c
+++ b/drivers/usb/renesas_usbhs/common.c
@@ -132,6 +132,11 @@ void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable)
usbhs_bset(priv, SYSCFG, mask, enable ? val : 0);
}
+void usbhs_sys_function_pullup(struct usbhs_priv *priv, int enable)
+{
+ usbhs_bset(priv, SYSCFG, DPRPU, enable ? DPRPU : 0);
+}
+
void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode)
{
usbhs_write(priv, TESTMODE, mode);
@@ -551,7 +556,7 @@ probe_end_pipe_exit:
return ret;
}
-static int __devexit usbhs_remove(struct platform_device *pdev)
+static int usbhs_remove(struct platform_device *pdev)
{
struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
struct renesas_usbhs_platform_info *info = pdev->dev.platform_data;
@@ -631,7 +636,7 @@ static struct platform_driver renesas_usbhs_driver = {
.pm = &usbhsc_pm_ops,
},
.probe = usbhs_probe,
- .remove = __devexit_p(usbhs_remove),
+ .remove = usbhs_remove,
};
module_platform_driver(renesas_usbhs_driver);
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h
index dddf40a59de..c69dd2fba36 100644
--- a/drivers/usb/renesas_usbhs/common.h
+++ b/drivers/usb/renesas_usbhs/common.h
@@ -285,6 +285,7 @@ void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data);
*/
void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable);
void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable);
+void usbhs_sys_function_pullup(struct usbhs_priv *priv, int enable);
void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode);
/*
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index c021b202c0f..9538f0feafe 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -163,7 +163,7 @@ static int usbhsf_pkt_handler(struct usbhs_pipe *pipe, int type)
func = pkt->handler->dma_done;
break;
default:
- dev_err(dev, "unknown pkt hander\n");
+ dev_err(dev, "unknown pkt handler\n");
goto __usbhs_pkt_handler_end;
}
@@ -192,8 +192,8 @@ void usbhs_pkt_start(struct usbhs_pipe *pipe)
/*
* irq enable/disable function
*/
-#define usbhsf_irq_empty_ctrl(p, e) usbhsf_irq_callback_ctrl(p, bempsts, e)
-#define usbhsf_irq_ready_ctrl(p, e) usbhsf_irq_callback_ctrl(p, brdysts, e)
+#define usbhsf_irq_empty_ctrl(p, e) usbhsf_irq_callback_ctrl(p, irq_bempsts, e)
+#define usbhsf_irq_ready_ctrl(p, e) usbhsf_irq_callback_ctrl(p, irq_brdysts, e)
#define usbhsf_irq_callback_ctrl(pipe, status, enable) \
({ \
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); \
@@ -202,9 +202,9 @@ void usbhs_pkt_start(struct usbhs_pipe *pipe)
if (!mod) \
return; \
if (enable) \
- mod->irq_##status |= status; \
+ mod->status |= status; \
else \
- mod->irq_##status &= ~status; \
+ mod->status &= ~status; \
usbhs_irq_callback_update(priv, mod); \
})
@@ -488,6 +488,8 @@ static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done)
usbhs_pipe_data_sequence(pipe, pkt->sequence);
pkt->sequence = -1; /* -1 sequence will be ignored */
+ usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length);
+
ret = usbhsf_fifo_select(pipe, fifo, 1);
if (ret < 0)
return 0;
@@ -594,6 +596,7 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done)
usbhs_pipe_data_sequence(pipe, pkt->sequence);
pkt->sequence = -1; /* -1 sequence will be ignored */
+ usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length);
usbhs_pipe_enable(pipe);
usbhsf_rx_irq_ctrl(pipe, 1);
@@ -795,6 +798,7 @@ static void xfer_work(struct work_struct *work)
dev_dbg(dev, " %s %d (%d/ %d)\n",
fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);
+ usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans);
usbhs_pipe_enable(pipe);
usbhsf_dma_start(pipe, fifo);
dma_async_issue_pending(chan);
diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c
index 61933a90e5b..6a030b931a3 100644
--- a/drivers/usb/renesas_usbhs/mod.c
+++ b/drivers/usb/renesas_usbhs/mod.c
@@ -151,7 +151,7 @@ int usbhs_mod_probe(struct usbhs_priv *priv)
goto mod_init_host_err;
/* irq settings */
- ret = request_irq(priv->irq, usbhs_interrupt,
+ ret = devm_request_irq(dev, priv->irq, usbhs_interrupt,
priv->irqflags, dev_name(dev), priv);
if (ret) {
dev_err(dev, "irq request err\n");
@@ -172,7 +172,6 @@ void usbhs_mod_remove(struct usbhs_priv *priv)
{
usbhs_mod_host_remove(priv);
usbhs_mod_gadget_remove(priv);
- free_irq(priv->irq, priv);
}
/*
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 28478ce26c3..dd41f61893e 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -883,6 +883,16 @@ static int usbhsg_get_frame(struct usb_gadget *gadget)
return usbhs_frame_get_num(priv);
}
+static int usbhsg_pullup(struct usb_gadget *gadget, int is_on)
+{
+ struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
+ struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
+
+ usbhs_sys_function_pullup(priv, is_on);
+
+ return 0;
+}
+
static int usbhsg_set_selfpowered(struct usb_gadget *gadget, int is_self)
{
struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
@@ -900,6 +910,7 @@ static struct usb_gadget_ops usbhsg_gadget_ops = {
.set_selfpowered = usbhsg_set_selfpowered,
.udc_start = usbhsg_gadget_start,
.udc_stop = usbhsg_gadget_stop,
+ .pullup = usbhsg_pullup,
};
static int usbhsg_start(struct usbhs_priv *priv)
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c
index 069cd765400..3d3cd6ca268 100644
--- a/drivers/usb/renesas_usbhs/mod_host.c
+++ b/drivers/usb/renesas_usbhs/mod_host.c
@@ -85,6 +85,7 @@ struct usbhsh_ep {
struct usbhsh_device *udev; /* attached udev */
struct usb_host_endpoint *ep;
struct list_head ep_list; /* list to usbhsh_device */
+ unsigned int counter; /* pipe attach counter */
};
#define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */
@@ -271,8 +272,12 @@ static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv,
/******************** spin lock ********************/
usbhs_lock(priv, flags);
- if (unlikely(usbhsh_uep_to_pipe(uep))) {
- dev_err(dev, "uep already has pipe\n");
+ /*
+ * if uep has been attached to pipe,
+ * reuse it
+ */
+ if (usbhsh_uep_to_pipe(uep)) {
+ ret = 0;
goto usbhsh_pipe_attach_done;
}
@@ -320,6 +325,9 @@ static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv,
}
usbhsh_pipe_attach_done:
+ if (0 == ret)
+ uep->counter++;
+
usbhs_unlock(priv, flags);
/******************** spin unlock ******************/
@@ -346,7 +354,7 @@ static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv,
if (unlikely(!pipe)) {
dev_err(dev, "uep doens't have pipe\n");
- } else {
+ } else if (1 == uep->counter--) { /* last user */
struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep);
struct usbhsh_device *udev = usbhsh_uep_to_udev(uep);
@@ -391,6 +399,7 @@ static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv,
/*
* init endpoint
*/
+ uep->counter = 0;
INIT_LIST_HEAD(&uep->ep_list);
list_add_tail(&uep->ep_list, &udev->ep_list_head);
@@ -686,9 +695,9 @@ static int usbhsh_queue_push(struct usb_hcd *hcd,
}
if (usb_pipein(urb->pipe))
- pipe->handler = &usbhs_fifo_pio_pop_handler;
+ pipe->handler = &usbhs_fifo_dma_pop_handler;
else
- pipe->handler = &usbhs_fifo_pio_push_handler;
+ pipe->handler = &usbhs_fifo_dma_push_handler;
buf = (void *)(urb->transfer_buffer + urb->actual_length);
len = urb->transfer_buffer_length - urb->actual_length;
@@ -921,6 +930,19 @@ static int usbhsh_dcp_queue_push(struct usb_hcd *hcd,
*/
static int usbhsh_dma_map_ctrl(struct usbhs_pkt *pkt, int map)
{
+ if (map) {
+ struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt);
+ struct urb *urb = ureq->urb;
+
+ /* it can not use scatter/gather */
+ if (urb->num_sgs)
+ return -EINVAL;
+
+ pkt->dma = urb->transfer_dma;
+ if (!pkt->dma)
+ return -EINVAL;
+ }
+
return 0;
}
@@ -946,7 +968,6 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
struct usb_host_endpoint *ep = urb->ep;
struct usbhsh_device *new_udev = NULL;
int is_dir_in = usb_pipein(urb->pipe);
- int i;
int ret;
dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out");
@@ -992,13 +1013,7 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
* attach pipe to endpoint
* see [image of mod_host]
*/
- for (i = 0; i < 1024; i++) {
- ret = usbhsh_pipe_attach(hpriv, urb);
- if (ret < 0)
- msleep(100);
- else
- break;
- }
+ ret = usbhsh_pipe_attach(hpriv, urb);
if (ret < 0) {
dev_err(dev, "pipe attach failed\n");
goto usbhsh_urb_enqueue_error_free_endpoint;
@@ -1072,8 +1087,6 @@ static void usbhsh_endpoint_disable(struct usb_hcd *hcd,
static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf)
{
struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd);
- struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv);
- struct device *dev = usbhs_priv_to_dev(priv);
int roothub_id = 1; /* only 1 root hub */
/*
@@ -1085,8 +1098,6 @@ static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf)
else
*buf = 0;
- dev_dbg(dev, "%s (%02x)\n", __func__, *buf);
-
return !!(*buf);
}
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c
index 122526cfd32..7926e1c700f 100644
--- a/drivers/usb/renesas_usbhs/pipe.c
+++ b/drivers/usb/renesas_usbhs/pipe.c
@@ -93,6 +93,82 @@ static void usbhsp_pipe_cfg_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
}
/*
+ * PIPEnTRN/PIPEnTRE functions
+ */
+static void usbhsp_pipe_trn_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
+{
+ struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
+ struct device *dev = usbhs_priv_to_dev(priv);
+ int num = usbhs_pipe_number(pipe);
+ u16 reg;
+
+ /*
+ * It is impossible to calculate address,
+ * since PIPEnTRN addresses were mapped randomly.
+ */
+#define CASE_PIPExTRN(a) \
+ case 0x ## a: \
+ reg = PIPE ## a ## TRN; \
+ break;
+
+ switch (num) {
+ CASE_PIPExTRN(1);
+ CASE_PIPExTRN(2);
+ CASE_PIPExTRN(3);
+ CASE_PIPExTRN(4);
+ CASE_PIPExTRN(5);
+ CASE_PIPExTRN(B);
+ CASE_PIPExTRN(C);
+ CASE_PIPExTRN(D);
+ CASE_PIPExTRN(E);
+ CASE_PIPExTRN(F);
+ CASE_PIPExTRN(9);
+ CASE_PIPExTRN(A);
+ default:
+ dev_err(dev, "unknown pipe (%d)\n", num);
+ return;
+ }
+ __usbhsp_pipe_xxx_set(pipe, 0, reg, mask, val);
+}
+
+static void usbhsp_pipe_tre_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
+{
+ struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
+ struct device *dev = usbhs_priv_to_dev(priv);
+ int num = usbhs_pipe_number(pipe);
+ u16 reg;
+
+ /*
+ * It is impossible to calculate address,
+ * since PIPEnTRE addresses were mapped randomly.
+ */
+#define CASE_PIPExTRE(a) \
+ case 0x ## a: \
+ reg = PIPE ## a ## TRE; \
+ break;
+
+ switch (num) {
+ CASE_PIPExTRE(1);
+ CASE_PIPExTRE(2);
+ CASE_PIPExTRE(3);
+ CASE_PIPExTRE(4);
+ CASE_PIPExTRE(5);
+ CASE_PIPExTRE(B);
+ CASE_PIPExTRE(C);
+ CASE_PIPExTRE(D);
+ CASE_PIPExTRE(E);
+ CASE_PIPExTRE(F);
+ CASE_PIPExTRE(9);
+ CASE_PIPExTRE(A);
+ default:
+ dev_err(dev, "unknown pipe (%d)\n", num);
+ return;
+ }
+
+ __usbhsp_pipe_xxx_set(pipe, 0, reg, mask, val);
+}
+
+/*
* PIPEBUF
*/
static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
@@ -264,6 +340,31 @@ int usbhs_pipe_is_stall(struct usbhs_pipe *pipe)
return (int)(pid == PID_STALL10 || pid == PID_STALL11);
}
+void usbhs_pipe_set_trans_count_if_bulk(struct usbhs_pipe *pipe, int len)
+{
+ if (!usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
+ return;
+
+ /*
+ * clear and disable transfer counter for IN/OUT pipe
+ */
+ usbhsp_pipe_tre_set(pipe, TRCLR | TRENB, TRCLR);
+
+ /*
+ * Only IN direction bulk pipe can use transfer count.
+ * Without using this function,
+ * received data will break if it was large data size.
+ * see PIPEnTRN/PIPEnTRE for detail
+ */
+ if (usbhs_pipe_is_dir_in(pipe)) {
+ int maxp = usbhs_pipe_get_maxpacket(pipe);
+
+ usbhsp_pipe_trn_set(pipe, 0xffff, DIV_ROUND_UP(len, maxp));
+ usbhsp_pipe_tre_set(pipe, TRENB, TRENB); /* enable */
+ }
+}
+
+
/*
* pipe setup
*/
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h
index 3d80c7b1fd1..b476fde955b 100644
--- a/drivers/usb/renesas_usbhs/pipe.h
+++ b/drivers/usb/renesas_usbhs/pipe.h
@@ -88,6 +88,7 @@ void usbhs_pipe_enable(struct usbhs_pipe *pipe);
void usbhs_pipe_disable(struct usbhs_pipe *pipe);
void usbhs_pipe_stall(struct usbhs_pipe *pipe);
int usbhs_pipe_is_stall(struct usbhs_pipe *pipe);
+void usbhs_pipe_set_trans_count_if_bulk(struct usbhs_pipe *pipe, int len);
void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo);
void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel,
u16 epnum, u16 maxp);
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
index 54e1bb6372e..6d110a3bc7e 100644
--- a/drivers/usb/serial/aircable.c
+++ b/drivers/usb/serial/aircable.c
@@ -68,10 +68,6 @@
#define THROTTLED 0x01
#define ACTUALLY_THROTTLED 0x02
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v2.0"
#define DRIVER_AUTHOR "Naranjo, Manuel Francisco <naranjo.manuel@gmail.com>, Johan Hovold <jhovold@gmail.com>"
#define DRIVER_DESC "AIRcable USB Driver"
@@ -192,5 +188,4 @@ module_usb_serial_driver(serial_drivers, id_table);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index bd50a8a41a0..a88882c0e23 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -37,11 +37,6 @@
#include <linux/mutex.h>
#include <linux/spinlock.h>
-/*
- * Version information
- */
-
-#define DRIVER_VERSION "v0.7"
#define DRIVER_AUTHOR "Bart Hartgers <bart.hartgers+ark3116@gmail.com>"
#define DRIVER_DESC "USB ARK3116 serial/IrDA driver"
#define DRIVER_DEV_DESC "ARK3116 RS232/IrDA"
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index ea29556f0d7..b72a4c16670 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -37,10 +37,6 @@
#include <linux/usb/serial.h>
#include "belkin_sa.h"
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.3"
#define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>"
#define DRIVER_DESC "USB Belkin Serial converter driver"
@@ -509,5 +505,4 @@ module_usb_serial_driver(serial_drivers, id_table);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index c15f2e7cefc..37decb13d7e 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -121,7 +121,6 @@ static int usb_serial_device_remove(struct device *dev)
return retval;
}
-#ifdef CONFIG_HOTPLUG
static ssize_t store_new_id(struct device_driver *driver,
const char *buf, size_t count)
{
@@ -159,15 +158,6 @@ static void free_dynids(struct usb_serial_driver *drv)
spin_unlock(&drv->dynids.lock);
}
-#else
-static struct driver_attribute drv_attrs[] = {
- __ATTR_NULL,
-};
-static inline void free_dynids(struct usb_serial_driver *drv)
-{
-}
-#endif
-
struct bus_type usb_serial_bus_type = {
.name = "usb-serial",
.match = usb_serial_device_match,
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index eb033fc92a1..f14736f647f 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -24,10 +24,6 @@
#include <linux/uaccess.h>
#include <linux/usb/serial.h>
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v0.09"
#define DRIVER_DESC "Silicon Labs CP210x RS232 serial adaptor driver"
/*
@@ -35,8 +31,7 @@
*/
static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *);
static void cp210x_close(struct usb_serial_port *);
-static void cp210x_get_termios(struct tty_struct *,
- struct usb_serial_port *port);
+static void cp210x_get_termios(struct tty_struct *, struct usb_serial_port *);
static void cp210x_get_termios_port(struct usb_serial_port *port,
unsigned int *cflagp, unsigned int *baudp);
static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *,
@@ -118,6 +113,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */
{ USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */
{ USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */
+ { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */
{ USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */
{ USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
@@ -169,7 +165,7 @@ struct cp210x_serial_private {
static struct usb_serial_driver cp210x_device = {
.driver = {
.owner = THIS_MODULE,
- .name = "cp210x",
+ .name = "cp210x",
},
.id_table = id_table,
.num_ports = 1,
@@ -179,7 +175,7 @@ static struct usb_serial_driver cp210x_device = {
.close = cp210x_close,
.break_ctl = cp210x_break_ctl,
.set_termios = cp210x_set_termios,
- .tiocmget = cp210x_tiocmget,
+ .tiocmget = cp210x_tiocmget,
.tiocmset = cp210x_tiocmset,
.attach = cp210x_startup,
.release = cp210x_release,
@@ -281,7 +277,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
int result, i, length;
/* Number of integers required to contain the array */
- length = (((size - 1) | 3) + 1)/4;
+ length = (((size - 1) | 3) + 1) / 4;
buf = kcalloc(length, sizeof(__le32), GFP_KERNEL);
if (!buf) {
@@ -328,12 +324,11 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
int result, i, length;
/* Number of integers required to contain the array */
- length = (((size - 1) | 3) + 1)/4;
+ length = (((size - 1) | 3) + 1) / 4;
buf = kmalloc(length * sizeof(__le32), GFP_KERNEL);
if (!buf) {
- dev_err(&port->dev, "%s - out of memory.\n",
- __func__);
+ dev_err(&port->dev, "%s - out of memory.\n", __func__);
return -ENOMEM;
}
@@ -384,7 +379,8 @@ static inline int cp210x_set_config_single(struct usb_serial_port *port,
* cp210x_quantise_baudrate
* Quantises the baud rate as per AN205 Table 1
*/
-static unsigned int cp210x_quantise_baudrate(unsigned int baud) {
+static unsigned int cp210x_quantise_baudrate(unsigned int baud)
+{
if (baud <= 300)
baud = 300;
else if (baud <= 600) baud = 600;
@@ -467,9 +463,7 @@ static void cp210x_get_termios(struct tty_struct *tty,
cp210x_get_termios_port(tty->driver_data,
&tty->termios.c_cflag, &baud);
tty_encode_baud_rate(tty, baud, baud);
- }
-
- else {
+ } else {
unsigned int cflag;
cflag = 0;
cp210x_get_termios_port(port, &cflag, &baud);
@@ -693,8 +687,8 @@ static void cp210x_set_termios(struct tty_struct *tty,
break;*/
default:
dev_dbg(dev, "cp210x driver does not support the number of bits requested, using 8 bit mode\n");
- bits |= BITS_DATA_8;
- break;
+ bits |= BITS_DATA_8;
+ break;
}
if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2))
dev_dbg(dev, "Number of data bits requested not supported by device\n");
@@ -767,7 +761,7 @@ static void cp210x_set_termios(struct tty_struct *tty,
}
-static int cp210x_tiocmset (struct tty_struct *tty,
+static int cp210x_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear)
{
struct usb_serial_port *port = tty->driver_data;
@@ -809,7 +803,7 @@ static void cp210x_dtr_rts(struct usb_serial_port *p, int on)
cp210x_tiocmset_port(p, 0, TIOCM_DTR|TIOCM_RTS);
}
-static int cp210x_tiocmget (struct tty_struct *tty)
+static int cp210x_tiocmget(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
unsigned int control;
@@ -829,7 +823,7 @@ static int cp210x_tiocmget (struct tty_struct *tty)
return result;
}
-static void cp210x_break_ctl (struct tty_struct *tty, int break_state)
+static void cp210x_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
unsigned int state;
@@ -874,5 +868,4 @@ static void cp210x_release(struct usb_serial *serial)
module_usb_serial_driver(serial_drivers, id_table);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 4ee77dcbe69..69a4fa1cee2 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -43,10 +43,6 @@
#define CYBERJACK_LOCAL_BUF_SIZE 32
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.01"
#define DRIVER_AUTHOR "Matthias Bruestle"
#define DRIVER_DESC "REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver"
@@ -441,5 +437,4 @@ module_usb_serial_driver(serial_drivers, id_table);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index f0da1279c11..fd8c35fd452 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -50,10 +50,6 @@ static bool stats;
static int interval;
static bool unstable_bauds;
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.10"
#define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>"
#define DRIVER_DESC "Cypress USB to Serial Driver"
@@ -1303,7 +1299,6 @@ module_usb_serial_driver(serial_drivers, id_table_combined);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
module_param(stats, bool, S_IRUGO | S_IWUSR);
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index b50fa1c6d88..45d4af62967 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -32,10 +32,6 @@
/* Defines */
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.80.1.2"
#define DRIVER_AUTHOR "Peter Berger <pberger@brimson.com>, Al Borchers <borchers@steinerpoint.com>"
#define DRIVER_DESC "Digi AccelePort USB-2/USB-4 Serial Converter driver"
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 43ede4a1e12..0f658618db1 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -28,10 +28,6 @@
#include <linux/usb.h>
#include <linux/usb/serial.h>
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.3"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Gary Brubaker <xavyer@ix.netcom.com>"
#define DRIVER_DESC "USB Empeg Mark I/II Driver"
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index be845873e23..0a373b3ae96 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -73,7 +73,6 @@ struct ftdi_private {
char prev_status; /* Used for TIOCMIWAIT */
bool dev_gone; /* Used to abort TIOCMIWAIT */
char transmit_empty; /* If transmitter is empty or not */
- struct usb_serial_port *port;
__u16 interface; /* FT2232C, FT2232H or FT4232H port interface
(0 for FT232/245) */
@@ -192,6 +191,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_THROTTLE_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GATEWAY_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) },
+ { USB_DEVICE(NEWPORT_VID, NEWPORT_AGILIS_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_SPROG_II) },
@@ -923,6 +923,9 @@ static int ftdi_get_icount(struct tty_struct *tty,
static int ftdi_ioctl(struct tty_struct *tty,
unsigned int cmd, unsigned long arg);
static void ftdi_break_ctl(struct tty_struct *tty, int break_state);
+static int ftdi_chars_in_buffer(struct tty_struct *tty);
+static int ftdi_get_modem_status(struct tty_struct *tty,
+ unsigned char status[2]);
static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base);
static unsigned short int ftdi_232am_baud_to_divisor(int baud);
@@ -957,6 +960,7 @@ static struct usb_serial_driver ftdi_sio_device = {
.ioctl = ftdi_ioctl,
.set_termios = ftdi_set_termios,
.break_ctl = ftdi_break_ctl,
+ .chars_in_buffer = ftdi_chars_in_buffer,
};
static struct usb_serial_driver * const serial_drivers[] = {
@@ -1090,6 +1094,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set,
__func__,
(set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged",
(set & TIOCM_RTS) ? "HIGH" : (clear & TIOCM_RTS) ? "LOW" : "unchanged");
+ rv = usb_translate_errors(rv);
} else {
dev_dbg(dev, "%s - DTR %s, RTS %s\n", __func__,
(set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged",
@@ -1682,7 +1687,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
kref_init(&priv->kref);
mutex_init(&priv->cfg_lock);
- memset(&priv->icount, 0x00, sizeof(priv->icount));
init_waitqueue_head(&priv->delta_msr_wait);
priv->flags = ASYNC_LOW_LATENCY;
@@ -1691,7 +1695,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
if (quirk && quirk->port_probe)
quirk->port_probe(priv);
- priv->port = port;
usb_set_serial_port_data(port, priv);
ftdi_determine_type(port);
@@ -1781,7 +1784,7 @@ static int ftdi_8u2232c_probe(struct usb_serial *serial)
struct usb_device *udev = serial->dev;
if ((udev->manufacturer && !strcmp(udev->manufacturer, "CALAO Systems")) ||
- (udev->product && !strcmp(udev->product, "BeagleBone/XDS100")))
+ (udev->product && !strcmp(udev->product, "BeagleBone/XDS100V2")))
return ftdi_jtag_probe(serial);
return 0;
@@ -2089,6 +2092,29 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state)
}
+static int ftdi_chars_in_buffer(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ int chars;
+ unsigned char buf[2];
+ int ret;
+
+ chars = usb_serial_generic_chars_in_buffer(tty);
+ if (chars)
+ goto out;
+
+ /* Check if hardware buffer is empty. */
+ ret = ftdi_get_modem_status(tty, buf);
+ if (ret == 2) {
+ if (!(buf[1] & FTDI_RS_TEMT))
+ chars = 1;
+ }
+out:
+ dev_dbg(&port->dev, "%s - %d\n", __func__, chars);
+
+ return chars;
+}
+
/* old_termios contains the original termios settings and tty->termios contains
* the new setting to be used
* WARNING: set_termios calls this with old_termios in kernel space
@@ -2272,7 +2298,14 @@ no_c_cflag_changes:
}
}
-static int ftdi_tiocmget(struct tty_struct *tty)
+/*
+ * Get modem-control status.
+ *
+ * Returns the number of status bytes retrieved (device dependant), or
+ * negative error code.
+ */
+static int ftdi_get_modem_status(struct tty_struct *tty,
+ unsigned char status[2])
{
struct usb_serial_port *port = tty->driver_data;
struct ftdi_private *priv = usb_get_serial_port_data(port);
@@ -2312,16 +2345,43 @@ static int ftdi_tiocmget(struct tty_struct *tty)
FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
0, priv->interface,
buf, len, WDR_TIMEOUT);
- if (ret < 0)
+ if (ret < 0) {
+ dev_err(&port->dev, "failed to get modem status: %d\n", ret);
+ ret = usb_translate_errors(ret);
goto out;
+ }
- ret = (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) |
- (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) |
- (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) |
- (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) |
- priv->last_dtr_rts;
+ status[0] = buf[0];
+ if (ret > 1)
+ status[1] = buf[1];
+ else
+ status[1] = 0;
+
+ dev_dbg(&port->dev, "%s - 0x%02x%02x\n", __func__, status[0],
+ status[1]);
out:
kfree(buf);
+
+ return ret;
+}
+
+static int ftdi_tiocmget(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ unsigned char buf[2];
+ int ret;
+
+ ret = ftdi_get_modem_status(tty, buf);
+ if (ret < 0)
+ return ret;
+
+ ret = (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) |
+ (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) |
+ (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) |
+ (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) |
+ priv->last_dtr_rts;
+
return ret;
}
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index 57c12ef6625..049b6e715fa 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -752,6 +752,12 @@
#define TTI_VID 0x103E /* Vendor Id */
#define TTI_QL355P_PID 0x03E8 /* TTi QL355P power supply */
+/*
+ * Newport Cooperation (www.newport.com)
+ */
+#define NEWPORT_VID 0x104D
+#define NEWPORT_AGILIS_PID 0x3000
+
/* Interbiometrics USB I/O Board */
/* Developed for Interbiometrics by Rudolf Gugler */
#define INTERBIOMETRICS_VID 0x1209
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 296612153ea..2ea70a63199 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -262,6 +262,7 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars);
return chars;
}
+EXPORT_SYMBOL_GPL(usb_serial_generic_chars_in_buffer);
static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port,
int index, gfp_t mem_flags)
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c
index 0bbaf21a9d1..2cba60d90c7 100644
--- a/drivers/usb/serial/hp4x.c
+++ b/drivers/usb/serial/hp4x.c
@@ -20,10 +20,6 @@
#include <linux/usb.h>
#include <linux/usb/serial.h>
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.00"
#define DRIVER_DESC "HP4x (48/49) Generic Serial driver"
#define HP_VENDOR_ID 0x03f0
@@ -52,5 +48,4 @@ static struct usb_serial_driver * const serial_drivers[] = {
module_usb_serial_driver(serial_drivers, id_table);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 5acc0d13864..7b770c7f8b1 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -51,10 +51,6 @@
#include "io_ionsp.h" /* info for the iosp messages */
#include "io_16654.h" /* 16654 UART defines */
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v2.7"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com> and David Iacovelli"
#define DRIVER_DESC "Edgeport USB Serial Driver"
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 60023c2d2a3..58184f3de68 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -40,10 +40,6 @@
#include "io_usbvend.h"
#include "io_ti.h"
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v0.7mode043006"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com> and David Iacovelli"
#define DRIVER_DESC "Edgeport USB Serial Driver"
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 1068bf22e27..76c9a847da5 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -25,11 +25,6 @@
#define KP_RETRIES 100
-/*
- * Version Information
- */
-
-#define DRIVER_VERSION "v1.0"
#define DRIVER_AUTHOR "Ganesh Varadarajan <ganesh@veritas.com>"
#define DRIVER_DESC "USB PocketPC PDA driver"
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 4264821a3b3..155eab14b30 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -49,10 +49,6 @@
#include <linux/uaccess.h>
#include "usb-wwan.h"
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v0.4"
#define DRIVER_AUTHOR "Roelf Diedericks"
#define DRIVER_DESC "IPWireless tty driver"
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index cd5533e81de..1e1fbed65ef 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -32,10 +32,6 @@
#include "iuu_phoenix.h"
#include <linux/random.h>
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v0.12"
#define DRIVER_DESC "Infinity USB Unlimited Phoenix driver"
static const struct usb_device_id id_table[] = {
@@ -1164,7 +1160,7 @@ static ssize_t store_vcc_mode(struct device *dev,
struct iuu_private *priv = usb_get_serial_port_data(port);
unsigned long v;
- if (strict_strtoul(buf, 10, &v)) {
+ if (kstrtoul(buf, 10, &v)) {
dev_err(dev, "%s - vcc_mode: %s is not a unsigned long\n",
__func__, buf);
goto fail_store_vcc_mode;
@@ -1232,8 +1228,6 @@ MODULE_AUTHOR("Alain Degreffe eczema@ecze.com");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
-
module_param(xmas, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(xmas, "Xmas colors enabled or not");
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 7179b0c5f81..97bc49f68ef 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -44,10 +44,6 @@
#include <linux/usb/ezusb.h>
#include "keyspan.h"
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.1.5"
#define DRIVER_AUTHOR "Hugh Blemings <hugh@misc.nu"
#define DRIVER_DESC "Keyspan USB to Serial Converter Driver"
@@ -2430,7 +2426,7 @@ static void keyspan_release(struct usb_serial *serial)
static int keyspan_port_probe(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
- struct keyspan_port_private *s_priv;
+ struct keyspan_serial_private *s_priv;
struct keyspan_port_private *p_priv;
const struct keyspan_device_details *d_details;
struct callbacks *cback;
@@ -2445,7 +2441,6 @@ static int keyspan_port_probe(struct usb_serial_port *port)
if (!p_priv)
return -ENOMEM;
- s_priv = usb_get_serial_data(port->serial);
p_priv->device_details = d_details;
/* Setup values for the various callback routines */
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index bb87e29c4ac..41b01092af0 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -42,10 +42,6 @@
#undef XIRCOM
#endif
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.1"
#define DRIVER_AUTHOR "Brian Warner <warner@lothar.com>"
#define DRIVER_DESC "USB Keyspan PDA Converter driver"
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index 1f4517864cd..fc9e14a1e9b 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -49,10 +49,6 @@
#include <linux/usb/serial.h>
#include "kl5kusb105.h"
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v0.4"
#define DRIVER_AUTHOR "Utz-Uwe Haus <haus@uuhaus.de>, Johan Hovold <jhovold@gmail.com>"
#define DRIVER_DESC "KLSI KL5KUSB105 chipset USB->Serial Converter driver"
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index c9ca7a5b12e..b747ba615d0 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -38,8 +38,6 @@
#include <linux/ioctl.h>
#include "kobil_sct.h"
-/* Version Information */
-#define DRIVER_VERSION "21/05/2004"
#define DRIVER_AUTHOR "KOBIL Systems GmbH - http://www.kobil.com"
#define DRIVER_DESC "KOBIL USB Smart Card Terminal Driver (experimental)"
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 8a208100410..b6911757c85 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -38,10 +38,6 @@
#include <linux/ioctl.h>
#include "mct_u232.h"
-/*
- * Version Information
- */
-#define DRIVER_VERSION "z2.1" /* Linux in-kernel version */
#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
#define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c
index 6f29c74eb76..3d258448c29 100644
--- a/drivers/usb/serial/metro-usb.c
+++ b/drivers/usb/serial/metro-usb.c
@@ -20,8 +20,6 @@
#include <linux/uaccess.h>
#include <linux/usb/serial.h>
-/* Version Information */
-#define DRIVER_VERSION "v1.2.0.0"
#define DRIVER_DESC "Metrologic Instruments Inc. - USB-POS driver"
/* Product information. */
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 75267421aad..f57a6b1fe78 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -36,10 +36,6 @@
#include <linux/uaccess.h>
#include <linux/parport.h>
-/*
- * Version Information
- */
-#define DRIVER_VERSION "2.1"
#define DRIVER_AUTHOR "Aspire Communications pvt Ltd."
#define DRIVER_DESC "Moschip USB Serial Driver"
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 1cf3375ec1a..66d9e088d9d 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -35,10 +35,6 @@
#include <linux/usb/serial.h>
#include <linux/uaccess.h>
-/*
- * Version Information
- */
-#define DRIVER_VERSION "1.3.2"
#define DRIVER_DESC "Moschip 7840/7820 USB Serial Driver"
/*
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 9ab73d29577..7818af931a4 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -23,10 +23,6 @@
#include <linux/usb.h>
#include <linux/usb/serial.h>
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.1"
#define DRIVER_AUTHOR "Alessandro Zummo"
#define DRIVER_DESC "USB ZyXEL omni.net LCD PLUS Driver"
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 6aba731d486..c6bfb83efb1 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -1,6 +1,7 @@
/*
* Opticon USB barcode to serial driver
*
+ * Copyright (C) 2011 - 2012 Johan Hovold <jhovold@gmail.com>
* Copyright (C) 2011 Martin Jansen <martin.jansen@opticon.com>
* Copyright (C) 2008 - 2009 Greg Kroah-Hartman <gregkh@suse.de>
* Copyright (C) 2008 - 2009 Novell Inc.
@@ -40,114 +41,70 @@ MODULE_DEVICE_TABLE(usb, id_table);
/* This structure holds all of the individual device information */
struct opticon_private {
- struct usb_device *udev;
- struct usb_serial *serial;
- struct usb_serial_port *port;
- unsigned char *bulk_in_buffer;
- struct urb *bulk_read_urb;
- int buffer_size;
- u8 bulk_address;
spinlock_t lock; /* protects the following flags */
- bool throttled;
- bool actually_throttled;
bool rts;
bool cts;
int outstanding_urbs;
};
-
-static void opticon_read_bulk_callback(struct urb *urb)
+static void opticon_process_data_packet(struct usb_serial_port *port,
+ const unsigned char *buf, size_t len)
{
- struct opticon_private *priv = urb->context;
- unsigned char *data = urb->transfer_buffer;
- struct usb_serial_port *port = priv->port;
- int status = urb->status;
struct tty_struct *tty;
- int result;
- int data_length;
+
+ tty = tty_port_tty_get(&port->port);
+ if (!tty)
+ return;
+
+ tty_insert_flip_string(tty, buf, len);
+ tty_flip_buffer_push(tty);
+ tty_kref_put(tty);
+}
+
+static void opticon_process_status_packet(struct usb_serial_port *port,
+ const unsigned char *buf, size_t len)
+{
+ struct opticon_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
- switch (status) {
- case 0:
- /* success */
- break;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dev_dbg(&priv->udev->dev, "%s - urb shutting down with status: %d\n",
- __func__, status);
+ spin_lock_irqsave(&priv->lock, flags);
+ if (buf[0] == 0x00)
+ priv->cts = false;
+ else
+ priv->cts = true;
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void opticon_process_read_urb(struct urb *urb)
+{
+ struct usb_serial_port *port = urb->context;
+ const unsigned char *hdr = urb->transfer_buffer;
+ const unsigned char *data = hdr + 2;
+ size_t data_len = urb->actual_length - 2;
+
+ if (urb->actual_length <= 2) {
+ dev_dbg(&port->dev, "malformed packet received: %d bytes\n",
+ urb->actual_length);
return;
- default:
- dev_dbg(&priv->udev->dev, "%s - nonzero urb status received: %d\n",
- __func__, status);
- goto exit;
}
-
- usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
-
- if (urb->actual_length > 2) {
- data_length = urb->actual_length - 2;
-
- /*
- * Data from the device comes with a 2 byte header:
- *
- * <0x00><0x00>data...
- * This is real data to be sent to the tty layer
- * <0x00><0x01)level
- * This is a CTS level change, the third byte is the CTS
- * value (0 for low, 1 for high).
- */
- if ((data[0] == 0x00) && (data[1] == 0x00)) {
- /* real data, send it to the tty layer */
- tty = tty_port_tty_get(&port->port);
- if (tty) {
- tty_insert_flip_string(tty, data + 2,
- data_length);
- tty_flip_buffer_push(tty);
- tty_kref_put(tty);
- }
- } else {
- if ((data[0] == 0x00) && (data[1] == 0x01)) {
- spin_lock_irqsave(&priv->lock, flags);
- /* CTS status information package */
- if (data[2] == 0x00)
- priv->cts = false;
- else
- priv->cts = true;
- spin_unlock_irqrestore(&priv->lock, flags);
- } else {
- dev_dbg(&priv->udev->dev,
- "Unknown data packet received from the device:"
- " %2x %2x\n",
- data[0], data[1]);
- }
- }
+ /*
+ * Data from the device comes with a 2 byte header:
+ *
+ * <0x00><0x00>data...
+ * This is real data to be sent to the tty layer
+ * <0x00><0x01>level
+ * This is a CTS level change, the third byte is the CTS
+ * value (0 for low, 1 for high).
+ */
+ if ((hdr[0] == 0x00) && (hdr[1] == 0x00)) {
+ opticon_process_data_packet(port, data, data_len);
+ } else if ((hdr[0] == 0x00) && (hdr[1] == 0x01)) {
+ opticon_process_status_packet(port, data, data_len);
} else {
- dev_dbg(&priv->udev->dev,
- "Improper amount of data received from the device, "
- "%d bytes", urb->actual_length);
+ dev_dbg(&port->dev, "unknown packet received: %02x %02x\n",
+ hdr[0], hdr[1]);
}
-
-exit:
- spin_lock(&priv->lock);
-
- /* Continue trying to always read if we should */
- if (!priv->throttled) {
- usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev,
- usb_rcvbulkpipe(priv->udev,
- priv->bulk_address),
- priv->bulk_in_buffer, priv->buffer_size,
- opticon_read_bulk_callback, priv);
- result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC);
- if (result)
- dev_err(&port->dev,
- "%s - failed resubmitting read urb, error %d\n",
- __func__, result);
- } else
- priv->actually_throttled = true;
- spin_unlock(&priv->lock);
}
static int send_control_msg(struct usb_serial_port *port, u8 requesttype,
@@ -175,52 +132,35 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype,
static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port)
{
- struct opticon_private *priv = usb_get_serial_data(port->serial);
+ struct opticon_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
- int result = 0;
+ int res;
spin_lock_irqsave(&priv->lock, flags);
- priv->throttled = false;
- priv->actually_throttled = false;
- priv->port = port;
priv->rts = false;
spin_unlock_irqrestore(&priv->lock, flags);
/* Clear RTS line */
send_control_msg(port, CONTROL_RTS, 0);
- /* Setup the read URB and start reading from the device */
- usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev,
- usb_rcvbulkpipe(priv->udev,
- priv->bulk_address),
- priv->bulk_in_buffer, priv->buffer_size,
- opticon_read_bulk_callback, priv);
-
/* clear the halt status of the enpoint */
- usb_clear_halt(priv->udev, priv->bulk_read_urb->pipe);
+ usb_clear_halt(port->serial->dev, port->read_urb->pipe);
+
+ res = usb_serial_generic_open(tty, port);
+ if (!res)
+ return res;
- result = usb_submit_urb(priv->bulk_read_urb, GFP_KERNEL);
- if (result)
- dev_err(&port->dev,
- "%s - failed resubmitting read urb, error %d\n",
- __func__, result);
/* Request CTS line state, sometimes during opening the current
* CTS state can be missed. */
send_control_msg(port, RESEND_CTS_STATE, 1);
- return result;
-}
-
-static void opticon_close(struct usb_serial_port *port)
-{
- struct opticon_private *priv = usb_get_serial_data(port->serial);
- /* shutdown our urbs */
- usb_kill_urb(priv->bulk_read_urb);
+ return res;
}
static void opticon_write_control_callback(struct urb *urb)
{
- struct opticon_private *priv = urb->context;
+ struct usb_serial_port *port = urb->context;
+ struct opticon_private *priv = usb_get_serial_port_data(port);
int status = urb->status;
unsigned long flags;
@@ -231,20 +171,21 @@ static void opticon_write_control_callback(struct urb *urb)
kfree(urb->setup_packet);
if (status)
- dev_dbg(&priv->udev->dev, "%s - nonzero write bulk status received: %d\n",
+ dev_dbg(&port->dev,
+ "%s - non-zero urb status received: %d\n",
__func__, status);
spin_lock_irqsave(&priv->lock, flags);
--priv->outstanding_urbs;
spin_unlock_irqrestore(&priv->lock, flags);
- usb_serial_port_softint(priv->port);
+ usb_serial_port_softint(port);
}
static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count)
{
- struct opticon_private *priv = usb_get_serial_data(port->serial);
+ struct opticon_private *priv = usb_get_serial_port_data(port);
struct usb_serial *serial = port->serial;
struct urb *urb;
unsigned char *buffer;
@@ -298,7 +239,7 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port,
usb_fill_control_urb(urb, serial->dev,
usb_sndctrlpipe(serial->dev, 0),
(unsigned char *)dr, buffer, count,
- opticon_write_control_callback, priv);
+ opticon_write_control_callback, port);
/* send it down the pipe */
status = usb_submit_urb(urb, GFP_ATOMIC);
@@ -331,7 +272,7 @@ error_no_buffer:
static int opticon_write_room(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
- struct opticon_private *priv = usb_get_serial_data(port->serial);
+ struct opticon_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
/*
@@ -350,44 +291,10 @@ static int opticon_write_room(struct tty_struct *tty)
return 2048;
}
-static void opticon_throttle(struct tty_struct *tty)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct opticon_private *priv = usb_get_serial_data(port->serial);
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->throttled = true;
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-
-static void opticon_unthrottle(struct tty_struct *tty)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct opticon_private *priv = usb_get_serial_data(port->serial);
- unsigned long flags;
- int result, was_throttled;
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->throttled = false;
- was_throttled = priv->actually_throttled;
- priv->actually_throttled = false;
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (was_throttled) {
- result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC);
- if (result)
- dev_err(&port->dev,
- "%s - failed submitting read urb, error %d\n",
- __func__, result);
- }
-}
-
static int opticon_tiocmget(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
- struct opticon_private *priv = usb_get_serial_data(port->serial);
+ struct opticon_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
int result = 0;
@@ -407,7 +314,7 @@ static int opticon_tiocmset(struct tty_struct *tty,
{
struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
- struct opticon_private *priv = usb_get_serial_data(port->serial);
+ struct opticon_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
bool rts;
bool changed = false;
@@ -438,7 +345,7 @@ static int opticon_tiocmset(struct tty_struct *tty,
return ret;
}
-static int get_serial_info(struct opticon_private *priv,
+static int get_serial_info(struct usb_serial_port *port,
struct serial_struct __user *serial)
{
struct serial_struct tmp;
@@ -450,7 +357,7 @@ static int get_serial_info(struct opticon_private *priv,
/* fake emulate a 16550 uart to make userspace code happy */
tmp.type = PORT_16550A;
- tmp.line = priv->serial->minor;
+ tmp.line = port->serial->minor;
tmp.port = 0;
tmp.irq = 0;
tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
@@ -468,13 +375,12 @@ static int opticon_ioctl(struct tty_struct *tty,
unsigned int cmd, unsigned long arg)
{
struct usb_serial_port *port = tty->driver_data;
- struct opticon_private *priv = usb_get_serial_data(port->serial);
dev_dbg(&port->dev, "%s - port %d, cmd = 0x%x\n", __func__, port->number, cmd);
switch (cmd) {
case TIOCGSERIAL:
- return get_serial_info(priv,
+ return get_serial_info(port,
(struct serial_struct __user *)arg);
}
@@ -483,106 +389,36 @@ static int opticon_ioctl(struct tty_struct *tty,
static int opticon_startup(struct usb_serial *serial)
{
- struct opticon_private *priv;
- struct usb_host_interface *intf;
- int i;
- int retval = -ENOMEM;
- bool bulk_in_found = false;
-
- /* create our private serial structure */
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (priv == NULL) {
- dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__);
- return -ENOMEM;
- }
- spin_lock_init(&priv->lock);
- priv->serial = serial;
- priv->port = serial->port[0];
- priv->udev = serial->dev;
- priv->outstanding_urbs = 0; /* Init the outstanding urbs */
-
- /* find our bulk endpoint */
- intf = serial->interface->altsetting;
- for (i = 0; i < intf->desc.bNumEndpoints; ++i) {
- struct usb_endpoint_descriptor *endpoint;
-
- endpoint = &intf->endpoint[i].desc;
- if (!usb_endpoint_is_bulk_in(endpoint))
- continue;
-
- priv->bulk_read_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!priv->bulk_read_urb) {
- dev_err(&priv->udev->dev, "out of memory\n");
- goto error;
- }
-
- priv->buffer_size = usb_endpoint_maxp(endpoint) * 2;
- priv->bulk_in_buffer = kmalloc(priv->buffer_size, GFP_KERNEL);
- if (!priv->bulk_in_buffer) {
- dev_err(&priv->udev->dev, "out of memory\n");
- goto error;
- }
-
- priv->bulk_address = endpoint->bEndpointAddress;
-
- bulk_in_found = true;
- break;
- }
-
- if (!bulk_in_found) {
- dev_err(&priv->udev->dev,
- "Error - the proper endpoints were not found!\n");
- goto error;
+ if (!serial->num_bulk_in) {
+ dev_err(&serial->dev->dev, "no bulk in endpoint\n");
+ return -ENODEV;
}
- usb_set_serial_data(serial, priv);
return 0;
-
-error:
- usb_free_urb(priv->bulk_read_urb);
- kfree(priv->bulk_in_buffer);
- kfree(priv);
- return retval;
}
-static void opticon_disconnect(struct usb_serial *serial)
+static int opticon_port_probe(struct usb_serial_port *port)
{
- struct opticon_private *priv = usb_get_serial_data(serial);
-
- usb_kill_urb(priv->bulk_read_urb);
- usb_free_urb(priv->bulk_read_urb);
-}
+ struct opticon_private *priv;
-static void opticon_release(struct usb_serial *serial)
-{
- struct opticon_private *priv = usb_get_serial_data(serial);
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
- kfree(priv->bulk_in_buffer);
- kfree(priv);
-}
+ spin_lock_init(&priv->lock);
-static int opticon_suspend(struct usb_serial *serial, pm_message_t message)
-{
- struct opticon_private *priv = usb_get_serial_data(serial);
+ usb_set_serial_port_data(port, priv);
- usb_kill_urb(priv->bulk_read_urb);
return 0;
}
-static int opticon_resume(struct usb_serial *serial)
+static int opticon_port_remove(struct usb_serial_port *port)
{
- struct opticon_private *priv = usb_get_serial_data(serial);
- struct usb_serial_port *port = serial->port[0];
- int result;
-
- mutex_lock(&port->port.mutex);
- /* This is protected by the port mutex against close/open */
- if (test_bit(ASYNCB_INITIALIZED, &port->port.flags))
- result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO);
- else
- result = 0;
- mutex_unlock(&port->port.mutex);
- return result;
+ struct opticon_private *priv = usb_get_serial_port_data(port);
+
+ kfree(priv);
+
+ return 0;
}
static struct usb_serial_driver opticon_device = {
@@ -592,20 +428,19 @@ static struct usb_serial_driver opticon_device = {
},
.id_table = id_table,
.num_ports = 1,
+ .bulk_in_size = 256,
.attach = opticon_startup,
+ .port_probe = opticon_port_probe,
+ .port_remove = opticon_port_remove,
.open = opticon_open,
- .close = opticon_close,
.write = opticon_write,
.write_room = opticon_write_room,
- .disconnect = opticon_disconnect,
- .release = opticon_release,
- .throttle = opticon_throttle,
- .unthrottle = opticon_unthrottle,
+ .throttle = usb_serial_generic_throttle,
+ .unthrottle = usb_serial_generic_unthrottle,
.ioctl = opticon_ioctl,
.tiocmget = opticon_tiocmget,
.tiocmset = opticon_tiocmset,
- .suspend = opticon_suspend,
- .resume = opticon_resume,
+ .process_read_urb = opticon_process_read_urb,
};
static struct usb_serial_driver * const serial_drivers[] = {
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 5dee7d61241..e6f87b76c71 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -28,7 +28,6 @@
device features.
*/
-#define DRIVER_VERSION "v0.7.2"
#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
#define DRIVER_DESC "USB Driver for GSM modems"
@@ -81,6 +80,7 @@ static void option_instat_callback(struct urb *urb);
#define OPTION_PRODUCT_GTM380_MODEM 0x7201
#define HUAWEI_VENDOR_ID 0x12D1
+#define HUAWEI_PRODUCT_E173 0x140C
#define HUAWEI_PRODUCT_K4505 0x1464
#define HUAWEI_PRODUCT_K3765 0x1465
#define HUAWEI_PRODUCT_K4605 0x14C6
@@ -158,6 +158,7 @@ static void option_instat_callback(struct urb *urb);
#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001
#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000
#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001
+#define NOVATELWIRELESS_PRODUCT_E362 0x9010
#define NOVATELWIRELESS_PRODUCT_G1 0xA001
#define NOVATELWIRELESS_PRODUCT_G1_M 0xA002
#define NOVATELWIRELESS_PRODUCT_G2 0xA010
@@ -193,6 +194,9 @@ static void option_instat_callback(struct urb *urb);
#define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181
#define DELL_PRODUCT_5730_MINICARD_VZW 0x8182
+#define DELL_PRODUCT_5800_MINICARD_VZW 0x8195 /* Novatel E362 */
+#define DELL_PRODUCT_5800_V2_MINICARD_VZW 0x8196 /* Novatel E362 */
+
#define KYOCERA_VENDOR_ID 0x0c88
#define KYOCERA_PRODUCT_KPC650 0x17da
#define KYOCERA_PRODUCT_KPC680 0x180a
@@ -283,6 +287,7 @@ static void option_instat_callback(struct urb *urb);
/* ALCATEL PRODUCTS */
#define ALCATEL_VENDOR_ID 0x1bbb
#define ALCATEL_PRODUCT_X060S_X200 0x0000
+#define ALCATEL_PRODUCT_X220_X500D 0x0017
#define PIRELLI_VENDOR_ID 0x1266
#define PIRELLI_PRODUCT_C100_1 0x1002
@@ -548,6 +553,8 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) },
{ USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) },
{ USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff),
+ .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
@@ -706,6 +713,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) },
/* Novatel Ovation MC551 a.k.a. Verizon USB551L */
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
@@ -728,28 +736,30 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
+ { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
{ USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) },
{ USB_DEVICE(YISO_VENDOR_ID, YISO_PRODUCT_U893) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1004) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1005) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1006) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1007) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1008) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1009) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100A) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100B) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100C) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100D) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100E) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100F) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1010) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1011) },
- { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1004, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1005, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1006, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1007, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1008, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1009, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100A, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100B, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100C, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100D, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100E, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100F, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1010, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1011, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012, 0xff) },
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) },
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
@@ -876,6 +886,10 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf5_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0135, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0136, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0137, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0139, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0144, 0xff, 0xff, 0xff) },
@@ -896,20 +910,34 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0189, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0191, 0xff, 0xff, 0xff), /* ZTE EuFi890 */
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0196, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0197, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0199, 0xff, 0xff, 0xff), /* ZTE MF820S */
.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0200, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0201, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0254, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0257, 0xff, 0xff, 0xff), /* ZTE MF821 */
.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0265, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0284, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0317, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0330, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0395, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1018, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1021, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf2_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) },
@@ -1089,6 +1117,10 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1301, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1302, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1303, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1333, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf2_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff),
@@ -1157,6 +1189,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
.driver_info = (kernel_ulong_t)&alcatel_x200_blacklist
},
+ { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) },
{ USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
{ USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
@@ -1165,22 +1198,22 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) },
{ USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) },
/* Pirelli */
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)},
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2)},
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004)},
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005)},
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006)},
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007)},
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008)},
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009)},
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A)},
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B) },
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C) },
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D) },
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E) },
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) },
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)},
- { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)},
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012, 0xff) },
/* Cinterion */
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
@@ -1341,20 +1374,10 @@ static int option_probe(struct usb_serial *serial,
&serial->interface->cur_altsetting->desc;
struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
- /*
- * D-Link DWM 652 still exposes CD-Rom emulation interface in modem
- * mode.
- */
- if (dev_desc->idVendor == DLINK_VENDOR_ID &&
- dev_desc->idProduct == DLINK_PRODUCT_DWM_652 &&
- iface_desc->bInterfaceClass == 0x08)
+ /* Never bind to the CD-Rom emulation interface */
+ if (iface_desc->bInterfaceClass == 0x08)
return -ENODEV;
- /* Bandrich modem and AT command interface is 0xff */
- if ((dev_desc->idVendor == BANDRICH_VENDOR_ID ||
- dev_desc->idVendor == PIRELLI_VENDOR_ID) &&
- iface_desc->bInterfaceClass != 0xff)
- return -ENODEV;
/*
* Don't bind reserved interfaces (like network ones) which often have
* the same class/subclass/protocol as the serial interfaces. Look at
@@ -1369,9 +1392,9 @@ static int option_probe(struct usb_serial *serial,
* Don't bind network interface on Samsung GT-B3730, it is handled by
* a separate module.
*/
- if (dev_desc->idVendor == SAMSUNG_VENDOR_ID &&
- dev_desc->idProduct == SAMSUNG_PRODUCT_GT_B3730 &&
- iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
+ if (dev_desc->idVendor == cpu_to_le16(SAMSUNG_VENDOR_ID) &&
+ dev_desc->idProduct == cpu_to_le16(SAMSUNG_PRODUCT_GT_B3730) &&
+ iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
return -ENODEV;
/* Store device id so we can use it during attach. */
@@ -1509,5 +1532,4 @@ static int option_send_setup(struct usb_serial_port *port)
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index cee9a52ca89..d217fd6ee43 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -57,7 +57,6 @@
#define OTI6858_DESCRIPTION \
"Ours Technology Inc. OTi-6858 USB to serial adapter driver"
#define OTI6858_AUTHOR "Tomasz Michal Lukaszewski <FIXME@FIXME>"
-#define OTI6858_VERSION "0.2"
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) },
@@ -899,5 +898,4 @@ module_usb_serial_driver(serial_drivers, id_table);
MODULE_DESCRIPTION(OTI6858_DESCRIPTION);
MODULE_AUTHOR(OTI6858_AUTHOR);
-MODULE_VERSION(OTI6858_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c
index ffcfc962ab1..d152be97d04 100644
--- a/drivers/usb/serial/quatech2.c
+++ b/drivers/usb/serial/quatech2.c
@@ -65,8 +65,6 @@
#define QT2_WRITE_BUFFER_SIZE 512 /* size of write buffer */
#define QT2_WRITE_CONTROL_SIZE 5 /* control bytes used for a write */
-/* Version Information */
-#define DRIVER_VERSION "v0.1"
#define DRIVER_DESC "Quatech 2nd gen USB to Serial Driver"
#define USB_VENDOR_ID_QUATECH 0x061d
diff --git a/drivers/usb/serial/siemens_mpi.c b/drivers/usb/serial/siemens_mpi.c
index e4a1787cdba..a76b1ae54a2 100644
--- a/drivers/usb/serial/siemens_mpi.c
+++ b/drivers/usb/serial/siemens_mpi.c
@@ -16,8 +16,6 @@
#include <linux/usb.h>
#include <linux/usb/serial.h>
-/* Version Information */
-#define DRIVER_VERSION "Version 0.1 09/26/2005"
#define DRIVER_AUTHOR "Thomas Hergenhahn@web.de http://libnodave.sf.net"
#define DRIVER_DESC "Driver for Siemens USB/MPI adapter"
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 270860f6bb2..af06f2f5f38 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -18,7 +18,7 @@
*/
/* Uncomment to log function calls */
/* #define DEBUG */
-#define DRIVER_VERSION "v.1.7.16"
+
#define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer"
#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
@@ -1078,7 +1078,6 @@ module_usb_serial_driver(serial_drivers, id_table);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
module_param(nmea, bool, S_IRUGO | S_IWUSR);
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index 769c137f897..a42536af125 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -28,9 +28,6 @@
#include <linux/usb.h>
#include <linux/usb/serial.h>
-
-/* Version Information */
-#define DRIVER_VERSION "v0.10"
#define DRIVER_DESC "SPCP8x5 USB to serial adaptor driver"
#define SPCP8x5_007_VID 0x04FC
@@ -651,5 +648,4 @@ static struct usb_serial_driver * const serial_drivers[] = {
module_usb_serial_driver(serial_drivers, id_table);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c
index 868d1e6852e..4543ea35022 100644
--- a/drivers/usb/serial/ssu100.c
+++ b/drivers/usb/serial/ssu100.c
@@ -46,8 +46,6 @@
#define FULLPWRBIT 0x00000080
#define NEXT_BOARD_POWER_BIT 0x00000004
-/* Version Information */
-#define DRIVER_VERSION "v0.1"
#define DRIVER_DESC "Quatech SSU-100 USB to Serial Driver"
#define USB_VENDOR_ID_QUATECH 0x061d /* Quatech VID */
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 73b8e056916..64bda135ba7 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -597,6 +597,7 @@ static void port_release(struct device *dev)
kfifo_free(&port->write_fifo);
kfree(port->interrupt_in_buffer);
kfree(port->interrupt_out_buffer);
+ tty_port_destroy(&port->port);
kfree(port);
}
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index 61a73ad1a18..01c94aada56 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -19,7 +19,6 @@
- controlling the baud rate doesn't make sense
*/
-#define DRIVER_VERSION "v0.7.2"
#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
#define DRIVER_DESC "USB Driver for GSM modems"
@@ -455,9 +454,6 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
struct usb_serial *serial = port->serial;
struct urb *urb;
- if (endpoint == -1)
- return NULL; /* endpoint not needed */
-
urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */
if (urb == NULL) {
dev_dbg(&serial->interface->dev,
@@ -489,6 +485,9 @@ int usb_wwan_port_probe(struct usb_serial_port *port)
init_usb_anchor(&portdata->delayed);
for (i = 0; i < N_IN_URB; i++) {
+ if (!port->bulk_in_size)
+ break;
+
buffer = (u8 *)__get_free_page(GFP_KERNEL);
if (!buffer)
goto bail_out_error;
@@ -502,8 +501,8 @@ int usb_wwan_port_probe(struct usb_serial_port *port)
}
for (i = 0; i < N_OUT_URB; i++) {
- if (port->bulk_out_endpointAddress == -1)
- continue;
+ if (!port->bulk_out_size)
+ break;
buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
if (!buffer)
@@ -710,5 +709,4 @@ EXPORT_SYMBOL(usb_wwan_resume);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/vivopay-serial.c b/drivers/usb/serial/vivopay-serial.c
index 0c0aa876c20..6299526ff8c 100644
--- a/drivers/usb/serial/vivopay-serial.c
+++ b/drivers/usb/serial/vivopay-serial.c
@@ -10,8 +10,6 @@
#include <linux/usb.h>
#include <linux/usb/serial.h>
-
-#define DRIVER_VERSION "v1.0"
#define DRIVER_DESC "ViVOpay USB Serial Driver"
#define VIVOPAY_VENDOR_ID 0x1d5f
@@ -42,5 +40,4 @@ module_usb_serial_driver(serial_drivers, id_table);
MODULE_AUTHOR("Forest Bond <forest.bond@outpostembedded.com>");
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index 0ae7bb64b5e..eab04a6b5fb 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -203,7 +203,7 @@ config USB_STORAGE_ENE_UB6250
config USB_UAS
tristate "USB Attached SCSI"
- depends on USB && SCSI
+ depends on USB && SCSI && BROKEN
help
The USB Attached SCSI protocol is supported by some USB
storage devices. It permits higher performance by supporting
diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c
index d36446dd7ae..ea5f2586fbd 100644
--- a/drivers/usb/storage/realtek_cr.c
+++ b/drivers/usb/storage/realtek_cr.c
@@ -455,7 +455,7 @@ static int rts51x_check_status(struct us_data *us, u8 lun)
u8 buf[16];
retval = rts51x_read_status(us, lun, buf, 16, &(chip->status_len));
- if (retval < 0)
+ if (retval != STATUS_SUCCESS)
return -EIO;
US_DEBUGP("chip->status_len = %d\n", chip->status_len);
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index a3d54366afc..92f35abee92 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -186,6 +186,12 @@ static int slave_configure(struct scsi_device *sdev)
/* Some devices don't handle VPD pages correctly */
sdev->skip_vpd_pages = 1;
+ /* Do not attempt to use REPORT SUPPORTED OPERATION CODES */
+ sdev->no_report_opcodes = 1;
+
+ /* Do not attempt to use WRITE SAME */
+ sdev->no_write_same = 1;
+
/* Some disks return the total number of blocks in response
* to READ CAPACITY rather than the highest block number.
* If this device makes that mistake, tell the sd driver. */
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 12aa72630ae..31b3e1a61bb 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -925,7 +925,6 @@ int usb_stor_probe1(struct us_data **pus,
host->max_cmd_len = 16;
host->sg_tablesize = usb_stor_sg_tablesize(intf);
*pus = us = host_to_us(host);
- memset(us, 0, sizeof(struct us_data));
mutex_init(&(us->dev_mutex));
us_set_lock_class(&us->dev_mutex, intf);
init_completion(&us->cmnd_ready);
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index 0616f235bd6..ce310170829 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -105,20 +105,15 @@ static int skel_open(struct inode *inode, struct file *file)
goto exit;
}
- /* increment our usage count for the device */
- kref_get(&dev->kref);
-
- /* lock the device to allow correctly handling errors
- * in resumption */
- mutex_lock(&dev->io_mutex);
-
retval = usb_autopm_get_interface(interface);
if (retval)
- goto out_err;
+ goto exit;
+
+ /* increment our usage count for the device */
+ kref_get(&dev->kref);
/* save our object in the file's private structure */
file->private_data = dev;
- mutex_unlock(&dev->io_mutex);
exit:
return retval;
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index 231009af65a..1d365316960 100644
--- a/drivers/usb/wusbcore/devconnect.c
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -847,19 +847,6 @@ static void wusb_dev_bos_rm(struct wusb_dev *wusb_dev)
wusb_dev->wusb_cap_descr = NULL;
};
-static struct usb_wireless_cap_descriptor wusb_cap_descr_default = {
- .bLength = sizeof(wusb_cap_descr_default),
- .bDescriptorType = USB_DT_DEVICE_CAPABILITY,
- .bDevCapabilityType = USB_CAP_TYPE_WIRELESS_USB,
-
- .bmAttributes = USB_WIRELESS_BEACON_NONE,
- .wPHYRates = cpu_to_le16(USB_WIRELESS_PHY_53),
- .bmTFITXPowerInfo = 0,
- .bmFFITXPowerInfo = 0,
- .bmBandGroup = cpu_to_le16(0x0001), /* WUSB1.0[7.4.1] bottom */
- .bReserved = 0
-};
-
/*
* USB stack's device addition Notifier Callback
*
diff --git a/drivers/uwb/Kconfig b/drivers/uwb/Kconfig
index d100f54ed65..2431eedbe6a 100644
--- a/drivers/uwb/Kconfig
+++ b/drivers/uwb/Kconfig
@@ -3,8 +3,7 @@
#
menuconfig UWB
- tristate "Ultra Wideband devices (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ tristate "Ultra Wideband devices"
depends on PCI
default n
help
diff --git a/drivers/uwb/reset.c b/drivers/uwb/reset.c
index 703228559e8..8b47c9cdd64 100644
--- a/drivers/uwb/reset.c
+++ b/drivers/uwb/reset.c
@@ -97,6 +97,7 @@ int uwb_rc_cmd_async(struct uwb_rc *rc, const char *cmd_name,
neh = uwb_rc_neh_add(rc, cmd, expected_type, expected_event, cb, arg);
if (IS_ERR(neh)) {
result = PTR_ERR(neh);
+ uwb_dev_unlock(&rc->uwb_dev);
goto out;
}
diff --git a/drivers/uwb/umc-bus.c b/drivers/uwb/umc-bus.c
index 82a84d53120..5c5b3fc9088 100644
--- a/drivers/uwb/umc-bus.c
+++ b/drivers/uwb/umc-bus.c
@@ -63,7 +63,7 @@ int umc_controller_reset(struct umc_dev *umc)
struct device *parent = umc->dev.parent;
int ret = 0;
- if (device_trylock(parent))
+ if (!device_trylock(parent))
return -EAGAIN;
ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper);
if (ret >= 0)
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 99ac2cb08b4..dedaf81d8f3 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -1076,7 +1076,7 @@ static int translate_desc(struct vhost_dev *dev, u64 addr, u32 len,
}
_iov = iov + ret;
size = reg->memory_size - addr + reg->guest_phys_addr;
- _iov->iov_len = min((u64)len, size);
+ _iov->iov_len = min((u64)len - s, size);
_iov->iov_base = (void __user *)(unsigned long)
(reg->userspace_addr + addr - reg->guest_phys_addr);
s += size;
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c
index df5db99af23..a1e41d4faa7 100644
--- a/drivers/video/backlight/adp5520_bl.c
+++ b/drivers/video/backlight/adp5520_bl.c
@@ -282,7 +282,7 @@ static const struct attribute_group adp5520_bl_attr_group = {
.attrs = adp5520_bl_attributes,
};
-static int __devinit adp5520_bl_probe(struct platform_device *pdev)
+static int adp5520_bl_probe(struct platform_device *pdev)
{
struct backlight_properties props;
struct backlight_device *bl;
@@ -333,7 +333,7 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit adp5520_bl_remove(struct platform_device *pdev)
+static int adp5520_bl_remove(struct platform_device *pdev)
{
struct backlight_device *bl = platform_get_drvdata(pdev);
struct adp5520_bl *data = bl_get_data(bl);
@@ -375,7 +375,7 @@ static struct platform_driver adp5520_bl_driver = {
.owner = THIS_MODULE,
},
.probe = adp5520_bl_probe,
- .remove = __devexit_p(adp5520_bl_remove),
+ .remove = adp5520_bl_remove,
.suspend = adp5520_bl_suspend,
.resume = adp5520_bl_resume,
};
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index 77d1fdba597..6bb72c0cb80 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -213,7 +213,7 @@ static int adp8860_led_setup(struct adp8860_led *led)
return ret;
}
-static int __devinit adp8860_led_probe(struct i2c_client *client)
+static int adp8860_led_probe(struct i2c_client *client)
{
struct adp8860_backlight_platform_data *pdata =
client->dev.platform_data;
@@ -295,7 +295,7 @@ static int __devinit adp8860_led_probe(struct i2c_client *client)
return ret;
}
-static int __devexit adp8860_led_remove(struct i2c_client *client)
+static int adp8860_led_remove(struct i2c_client *client)
{
struct adp8860_backlight_platform_data *pdata =
client->dev.platform_data;
@@ -310,12 +310,12 @@ static int __devexit adp8860_led_remove(struct i2c_client *client)
return 0;
}
#else
-static int __devinit adp8860_led_probe(struct i2c_client *client)
+static int adp8860_led_probe(struct i2c_client *client)
{
return 0;
}
-static int __devexit adp8860_led_remove(struct i2c_client *client)
+static int adp8860_led_remove(struct i2c_client *client)
{
return 0;
}
@@ -650,7 +650,7 @@ static const struct attribute_group adp8860_bl_attr_group = {
.attrs = adp8860_bl_attributes,
};
-static int __devinit adp8860_probe(struct i2c_client *client,
+static int adp8860_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct backlight_device *bl;
@@ -755,7 +755,7 @@ out1:
return ret;
}
-static int __devexit adp8860_remove(struct i2c_client *client)
+static int adp8860_remove(struct i2c_client *client)
{
struct adp8860_bl *data = i2c_get_clientdata(client);
@@ -805,7 +805,7 @@ static struct i2c_driver adp8860_driver = {
.name = KBUILD_MODNAME,
},
.probe = adp8860_probe,
- .remove = __devexit_p(adp8860_remove),
+ .remove = adp8860_remove,
.suspend = adp8860_i2c_suspend,
.resume = adp8860_i2c_resume,
.id_table = adp8860_id,
diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c
index edf7f91c8e6..63c882b8177 100644
--- a/drivers/video/backlight/adp8870_bl.c
+++ b/drivers/video/backlight/adp8870_bl.c
@@ -235,7 +235,7 @@ static int adp8870_led_setup(struct adp8870_led *led)
return ret;
}
-static int __devinit adp8870_led_probe(struct i2c_client *client)
+static int adp8870_led_probe(struct i2c_client *client)
{
struct adp8870_backlight_platform_data *pdata =
client->dev.platform_data;
@@ -320,7 +320,7 @@ static int __devinit adp8870_led_probe(struct i2c_client *client)
return ret;
}
-static int __devexit adp8870_led_remove(struct i2c_client *client)
+static int adp8870_led_remove(struct i2c_client *client)
{
struct adp8870_backlight_platform_data *pdata =
client->dev.platform_data;
@@ -335,12 +335,12 @@ static int __devexit adp8870_led_remove(struct i2c_client *client)
return 0;
}
#else
-static int __devinit adp8870_led_probe(struct i2c_client *client)
+static int adp8870_led_probe(struct i2c_client *client)
{
return 0;
}
-static int __devexit adp8870_led_remove(struct i2c_client *client)
+static int adp8870_led_remove(struct i2c_client *client)
{
return 0;
}
@@ -839,7 +839,7 @@ static const struct attribute_group adp8870_bl_attr_group = {
.attrs = adp8870_bl_attributes,
};
-static int __devinit adp8870_probe(struct i2c_client *client,
+static int adp8870_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct backlight_properties props;
@@ -929,7 +929,7 @@ out1:
return ret;
}
-static int __devexit adp8870_remove(struct i2c_client *client)
+static int adp8870_remove(struct i2c_client *client)
{
struct adp8870_bl *data = i2c_get_clientdata(client);
@@ -977,7 +977,7 @@ static struct i2c_driver adp8870_driver = {
.name = KBUILD_MODNAME,
},
.probe = adp8870_probe,
- .remove = __devexit_p(adp8870_remove),
+ .remove = adp8870_remove,
.suspend = adp8870_i2c_suspend,
.resume = adp8870_i2c_resume,
.id_table = adp8870_id,
diff --git a/drivers/video/backlight/ams369fg06.c b/drivers/video/backlight/ams369fg06.c
index 3729238e709..f57e1905236 100644
--- a/drivers/video/backlight/ams369fg06.c
+++ b/drivers/video/backlight/ams369fg06.c
@@ -474,7 +474,7 @@ static const struct backlight_ops ams369fg06_backlight_ops = {
.update_status = ams369fg06_set_brightness,
};
-static int __devinit ams369fg06_probe(struct spi_device *spi)
+static int ams369fg06_probe(struct spi_device *spi)
{
int ret = 0;
struct ams369fg06 *lcd = NULL;
@@ -548,7 +548,7 @@ out_lcd_unregister:
return ret;
}
-static int __devexit ams369fg06_remove(struct spi_device *spi)
+static int ams369fg06_remove(struct spi_device *spi)
{
struct ams369fg06 *lcd = dev_get_drvdata(&spi->dev);
@@ -617,7 +617,7 @@ static struct spi_driver ams369fg06_driver = {
.owner = THIS_MODULE,
},
.probe = ams369fg06_probe,
- .remove = __devexit_p(ams369fg06_remove),
+ .remove = ams369fg06_remove,
.shutdown = ams369fg06_shutdown,
.suspend = ams369fg06_suspend,
.resume = ams369fg06_resume,
diff --git a/drivers/video/backlight/apple_bl.c b/drivers/video/backlight/apple_bl.c
index 9dc73ac3709..f088d4c0738 100644
--- a/drivers/video/backlight/apple_bl.c
+++ b/drivers/video/backlight/apple_bl.c
@@ -137,7 +137,7 @@ static const struct hw_data nvidia_chipset_data = {
.set_brightness = nvidia_chipset_set_brightness,
};
-static int __devinit apple_bl_add(struct acpi_device *dev)
+static int apple_bl_add(struct acpi_device *dev)
{
struct backlight_properties props;
struct pci_dev *host;
@@ -196,7 +196,7 @@ static int __devinit apple_bl_add(struct acpi_device *dev)
return 0;
}
-static int __devexit apple_bl_remove(struct acpi_device *dev, int type)
+static int apple_bl_remove(struct acpi_device *dev, int type)
{
backlight_device_unregister(apple_backlight_device);
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
index c781768ba89..eaaebf21993 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -529,7 +529,7 @@ static int setup_gpio_backlight(struct corgi_lcd *lcd,
return 0;
}
-static int __devinit corgi_lcd_probe(struct spi_device *spi)
+static int corgi_lcd_probe(struct spi_device *spi)
{
struct backlight_properties props;
struct corgi_lcd_platform_data *pdata = spi->dev.platform_data;
@@ -590,7 +590,7 @@ err_unregister_lcd:
return ret;
}
-static int __devexit corgi_lcd_remove(struct spi_device *spi)
+static int corgi_lcd_remove(struct spi_device *spi)
{
struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev);
@@ -611,7 +611,7 @@ static struct spi_driver corgi_lcd_driver = {
.owner = THIS_MODULE,
},
.probe = corgi_lcd_probe,
- .remove = __devexit_p(corgi_lcd_remove),
+ .remove = corgi_lcd_remove,
.suspend = corgi_lcd_suspend,
.resume = corgi_lcd_resume,
};
diff --git a/drivers/video/backlight/ep93xx_bl.c b/drivers/video/backlight/ep93xx_bl.c
index 08214e1f095..ef3e21e8f82 100644
--- a/drivers/video/backlight/ep93xx_bl.c
+++ b/drivers/video/backlight/ep93xx_bl.c
@@ -141,7 +141,7 @@ static struct platform_driver ep93xxbl_driver = {
.owner = THIS_MODULE,
},
.probe = ep93xxbl_probe,
- .remove = __devexit_p(ep93xxbl_remove),
+ .remove = ep93xxbl_remove,
.suspend = ep93xxbl_suspend,
.resume = ep93xxbl_resume,
};
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index 38aa0027214..c9996634244 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -103,7 +103,7 @@ static const struct backlight_ops hp680bl_ops = {
.update_status = hp680bl_set_intensity,
};
-static int __devinit hp680bl_probe(struct platform_device *pdev)
+static int hp680bl_probe(struct platform_device *pdev)
{
struct backlight_properties props;
struct backlight_device *bd;
diff --git a/drivers/video/backlight/ili9320.c b/drivers/video/backlight/ili9320.c
index 9327cd1b314..66cc313185a 100644
--- a/drivers/video/backlight/ili9320.c
+++ b/drivers/video/backlight/ili9320.c
@@ -171,7 +171,7 @@ static struct lcd_ops ili9320_ops = {
.set_power = ili9320_set_power,
};
-static void __devinit ili9320_setup_spi(struct ili9320 *ili,
+static void ili9320_setup_spi(struct ili9320 *ili,
struct spi_device *dev)
{
struct ili9320_spi *spi = &ili->access.spi;
@@ -197,7 +197,7 @@ static void __devinit ili9320_setup_spi(struct ili9320 *ili,
spi_message_add_tail(&spi->xfer[1], &spi->message);
}
-int __devinit ili9320_probe_spi(struct spi_device *spi,
+int ili9320_probe_spi(struct spi_device *spi,
struct ili9320_client *client)
{
struct ili9320_platdata *cfg = spi->dev.platform_data;
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c
index 2d90c0648aa..f5aa0a5961d 100644
--- a/drivers/video/backlight/l4f00242t03.c
+++ b/drivers/video/backlight/l4f00242t03.c
@@ -150,7 +150,7 @@ static struct lcd_ops l4f_ops = {
.get_power = l4f00242t03_lcd_power_get,
};
-static int __devinit l4f00242t03_probe(struct spi_device *spi)
+static int l4f00242t03_probe(struct spi_device *spi)
{
struct l4f00242t03_priv *priv;
struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
@@ -230,7 +230,7 @@ err1:
return ret;
}
-static int __devexit l4f00242t03_remove(struct spi_device *spi)
+static int l4f00242t03_remove(struct spi_device *spi)
{
struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
@@ -260,7 +260,7 @@ static struct spi_driver l4f00242t03_driver = {
.owner = THIS_MODULE,
},
.probe = l4f00242t03_probe,
- .remove = __devexit_p(l4f00242t03_remove),
+ .remove = l4f00242t03_remove,
.shutdown = l4f00242t03_shutdown,
};
diff --git a/drivers/video/backlight/ld9040.c b/drivers/video/backlight/ld9040.c
index 58f517fb7d4..1cb35241851 100644
--- a/drivers/video/backlight/ld9040.c
+++ b/drivers/video/backlight/ld9040.c
@@ -788,7 +788,7 @@ out_free_regulator:
return ret;
}
-static int __devexit ld9040_remove(struct spi_device *spi)
+static int ld9040_remove(struct spi_device *spi)
{
struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
@@ -847,7 +847,7 @@ static struct spi_driver ld9040_driver = {
.owner = THIS_MODULE,
},
.probe = ld9040_probe,
- .remove = __devexit_p(ld9040_remove),
+ .remove = ld9040_remove,
.shutdown = ld9040_shutdown,
.suspend = ld9040_suspend,
.resume = ld9040_resume,
diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c
index 18dca0c29c6..5d18d4d7f47 100644
--- a/drivers/video/backlight/lm3533_bl.c
+++ b/drivers/video/backlight/lm3533_bl.c
@@ -257,7 +257,7 @@ static struct attribute_group lm3533_bl_attribute_group = {
.attrs = lm3533_bl_attributes
};
-static int __devinit lm3533_bl_setup(struct lm3533_bl *bl,
+static int lm3533_bl_setup(struct lm3533_bl *bl,
struct lm3533_bl_platform_data *pdata)
{
int ret;
@@ -269,7 +269,7 @@ static int __devinit lm3533_bl_setup(struct lm3533_bl *bl,
return lm3533_ctrlbank_set_pwm(&bl->cb, pdata->pwm);
}
-static int __devinit lm3533_bl_probe(struct platform_device *pdev)
+static int lm3533_bl_probe(struct platform_device *pdev)
{
struct lm3533 *lm3533;
struct lm3533_bl_platform_data *pdata;
@@ -351,7 +351,7 @@ err_unregister:
return ret;
}
-static int __devexit lm3533_bl_remove(struct platform_device *pdev)
+static int lm3533_bl_remove(struct platform_device *pdev)
{
struct lm3533_bl *bl = platform_get_drvdata(pdev);
struct backlight_device *bd = bl->bd;
@@ -406,7 +406,7 @@ static struct platform_driver lm3533_bl_driver = {
.owner = THIS_MODULE,
},
.probe = lm3533_bl_probe,
- .remove = __devexit_p(lm3533_bl_remove),
+ .remove = lm3533_bl_remove,
.shutdown = lm3533_bl_shutdown,
.suspend = lm3533_bl_suspend,
.resume = lm3533_bl_resume,
diff --git a/drivers/video/backlight/lm3630_bl.c b/drivers/video/backlight/lm3630_bl.c
index dc191441796..0207bc0a440 100644
--- a/drivers/video/backlight/lm3630_bl.c
+++ b/drivers/video/backlight/lm3630_bl.c
@@ -55,7 +55,7 @@ struct lm3630_chip_data {
};
/* initialize chip */
-static int __devinit lm3630_chip_init(struct lm3630_chip_data *pchip)
+static int lm3630_chip_init(struct lm3630_chip_data *pchip)
{
int ret;
unsigned int reg_val;
@@ -349,7 +349,7 @@ static const struct regmap_config lm3630_regmap = {
.max_register = REG_MAX,
};
-static int __devinit lm3630_probe(struct i2c_client *client,
+static int lm3630_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct lm3630_platform_data *pdata = client->dev.platform_data;
@@ -429,7 +429,7 @@ err_chip_init:
return ret;
}
-static int __devexit lm3630_remove(struct i2c_client *client)
+static int lm3630_remove(struct i2c_client *client)
{
int ret;
struct lm3630_chip_data *pchip = i2c_get_clientdata(client);
@@ -463,7 +463,7 @@ static struct i2c_driver lm3630_i2c_driver = {
.name = LM3630_NAME,
},
.probe = lm3630_probe,
- .remove = __devexit_p(lm3630_remove),
+ .remove = lm3630_remove,
.id_table = lm3630_id,
};
diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c
index 585949b5705..b0e1e8ba4d9 100644
--- a/drivers/video/backlight/lm3639_bl.c
+++ b/drivers/video/backlight/lm3639_bl.c
@@ -48,7 +48,7 @@ struct lm3639_chip_data {
};
/* initialize chip */
-static int __devinit lm3639_chip_init(struct lm3639_chip_data *pchip)
+static int lm3639_chip_init(struct lm3639_chip_data *pchip)
{
int ret;
unsigned int reg_val;
@@ -299,7 +299,7 @@ static const struct regmap_config lm3639_regmap = {
.max_register = REG_MAX,
};
-static int __devinit lm3639_probe(struct i2c_client *client,
+static int lm3639_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret;
@@ -397,7 +397,7 @@ err_out:
return ret;
}
-static int __devexit lm3639_remove(struct i2c_client *client)
+static int lm3639_remove(struct i2c_client *client)
{
struct lm3639_chip_data *pchip = i2c_get_clientdata(client);
@@ -425,7 +425,7 @@ static struct i2c_driver lm3639_i2c_driver = {
.name = LM3639_NAME,
},
.probe = lm3639_probe,
- .remove = __devexit_p(lm3639_remove),
+ .remove = lm3639_remove,
.id_table = lm3639_id,
};
diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c
index ea43f225419..b29c7071c9d 100644
--- a/drivers/video/backlight/lms283gf05.c
+++ b/drivers/video/backlight/lms283gf05.c
@@ -150,7 +150,7 @@ static struct lcd_ops lms_ops = {
.get_power = NULL,
};
-static int __devinit lms283gf05_probe(struct spi_device *spi)
+static int lms283gf05_probe(struct spi_device *spi)
{
struct lms283gf05_state *st;
struct lms283gf05_pdata *pdata = spi->dev.platform_data;
@@ -193,7 +193,7 @@ static int __devinit lms283gf05_probe(struct spi_device *spi)
return 0;
}
-static int __devexit lms283gf05_remove(struct spi_device *spi)
+static int lms283gf05_remove(struct spi_device *spi)
{
struct lms283gf05_state *st = dev_get_drvdata(&spi->dev);
@@ -208,7 +208,7 @@ static struct spi_driver lms283gf05_driver = {
.owner = THIS_MODULE,
},
.probe = lms283gf05_probe,
- .remove = __devexit_p(lms283gf05_remove),
+ .remove = lms283gf05_remove,
};
module_spi_driver(lms283gf05_driver);
diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c
index aa6d4f71131..fd985e0681e 100644
--- a/drivers/video/backlight/lp855x_bl.c
+++ b/drivers/video/backlight/lp855x_bl.c
@@ -297,7 +297,7 @@ err_dev:
return ret;
}
-static int __devexit lp855x_remove(struct i2c_client *cl)
+static int lp855x_remove(struct i2c_client *cl)
{
struct lp855x *lp = i2c_get_clientdata(cl);
@@ -324,7 +324,7 @@ static struct i2c_driver lp855x_driver = {
.name = "lp855x",
},
.probe = lp855x_probe,
- .remove = __devexit_p(lp855x_remove),
+ .remove = lp855x_remove,
.id_table = lp855x_ids,
};
diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c
index 4066a5bbd82..226d813edf0 100644
--- a/drivers/video/backlight/ltv350qv.c
+++ b/drivers/video/backlight/ltv350qv.c
@@ -226,7 +226,7 @@ static struct lcd_ops ltv_ops = {
.set_power = ltv350qv_set_power,
};
-static int __devinit ltv350qv_probe(struct spi_device *spi)
+static int ltv350qv_probe(struct spi_device *spi)
{
struct ltv350qv *lcd;
struct lcd_device *ld;
@@ -261,7 +261,7 @@ out_unregister:
return ret;
}
-static int __devexit ltv350qv_remove(struct spi_device *spi)
+static int ltv350qv_remove(struct spi_device *spi)
{
struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
@@ -305,7 +305,7 @@ static struct spi_driver ltv350qv_driver = {
},
.probe = ltv350qv_probe,
- .remove = __devexit_p(ltv350qv_remove),
+ .remove = ltv350qv_remove,
.shutdown = ltv350qv_shutdown,
.suspend = ltv350qv_suspend,
.resume = ltv350qv_resume,
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
index f72ba54f364..c6bec7aab87 100644
--- a/drivers/video/backlight/max8925_bl.c
+++ b/drivers/video/backlight/max8925_bl.c
@@ -101,7 +101,7 @@ static const struct backlight_ops max8925_backlight_ops = {
.get_brightness = max8925_backlight_get_brightness,
};
-static int __devinit max8925_backlight_probe(struct platform_device *pdev)
+static int max8925_backlight_probe(struct platform_device *pdev)
{
struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct max8925_backlight_pdata *pdata = pdev->dev.platform_data;
@@ -171,7 +171,7 @@ out:
return ret;
}
-static int __devexit max8925_backlight_remove(struct platform_device *pdev)
+static int max8925_backlight_remove(struct platform_device *pdev)
{
struct backlight_device *bl = platform_get_drvdata(pdev);
@@ -185,7 +185,7 @@ static struct platform_driver max8925_backlight_driver = {
.owner = THIS_MODULE,
},
.probe = max8925_backlight_probe,
- .remove = __devexit_p(max8925_backlight_remove),
+ .remove = max8925_backlight_remove,
};
module_platform_driver(max8925_backlight_driver);
diff --git a/drivers/video/backlight/pcf50633-backlight.c b/drivers/video/backlight/pcf50633-backlight.c
index c092159f438..0087396007e 100644
--- a/drivers/video/backlight/pcf50633-backlight.c
+++ b/drivers/video/backlight/pcf50633-backlight.c
@@ -99,7 +99,7 @@ static const struct backlight_ops pcf50633_bl_ops = {
.options = BL_CORE_SUSPENDRESUME,
};
-static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
+static int pcf50633_bl_probe(struct platform_device *pdev)
{
struct pcf50633_bl *pcf_bl;
struct device *parent = pdev->dev.parent;
@@ -145,7 +145,7 @@ static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit pcf50633_bl_remove(struct platform_device *pdev)
+static int pcf50633_bl_remove(struct platform_device *pdev)
{
struct pcf50633_bl *pcf_bl = platform_get_drvdata(pdev);
@@ -158,7 +158,7 @@ static int __devexit pcf50633_bl_remove(struct platform_device *pdev)
static struct platform_driver pcf50633_bl_driver = {
.probe = pcf50633_bl_probe,
- .remove = __devexit_p(pcf50633_bl_remove),
+ .remove = pcf50633_bl_remove,
.driver = {
.name = "pcf50633-backlight",
},
diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c
index ca4f5d70fe1..894bfc5ce42 100644
--- a/drivers/video/backlight/platform_lcd.c
+++ b/drivers/video/backlight/platform_lcd.c
@@ -73,7 +73,7 @@ static struct lcd_ops platform_lcd_ops = {
.check_fb = platform_lcd_match,
};
-static int __devinit platform_lcd_probe(struct platform_device *pdev)
+static int platform_lcd_probe(struct platform_device *pdev)
{
struct plat_lcd_data *pdata;
struct platform_lcd *plcd;
@@ -112,7 +112,7 @@ static int __devinit platform_lcd_probe(struct platform_device *pdev)
return err;
}
-static int __devexit platform_lcd_remove(struct platform_device *pdev)
+static int platform_lcd_remove(struct platform_device *pdev)
{
struct platform_lcd *plcd = platform_get_drvdata(pdev);
@@ -164,7 +164,7 @@ static struct platform_driver platform_lcd_driver = {
.of_match_table = of_match_ptr(platform_lcd_of_match),
},
.probe = platform_lcd_probe,
- .remove = __devexit_p(platform_lcd_remove),
+ .remove = platform_lcd_remove,
};
module_platform_driver(platform_lcd_driver);
diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c
index 6437ae474cf..484e10dd1a8 100644
--- a/drivers/video/backlight/s6e63m0.c
+++ b/drivers/video/backlight/s6e63m0.c
@@ -733,7 +733,7 @@ static ssize_t s6e63m0_sysfs_show_gamma_table(struct device *dev,
static DEVICE_ATTR(gamma_table, 0444,
s6e63m0_sysfs_show_gamma_table, NULL);
-static int __devinit s6e63m0_probe(struct spi_device *spi)
+static int s6e63m0_probe(struct spi_device *spi)
{
int ret = 0;
struct s6e63m0 *lcd = NULL;
@@ -825,7 +825,7 @@ out_lcd_unregister:
return ret;
}
-static int __devexit s6e63m0_remove(struct spi_device *spi)
+static int s6e63m0_remove(struct spi_device *spi)
{
struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev);
@@ -897,7 +897,7 @@ static struct spi_driver s6e63m0_driver = {
.owner = THIS_MODULE,
},
.probe = s6e63m0_probe,
- .remove = __devexit_p(s6e63m0_remove),
+ .remove = s6e63m0_remove,
.shutdown = s6e63m0_shutdown,
.suspend = s6e63m0_suspend,
.resume = s6e63m0_resume,
diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c
index 02444d042cd..146ffb9404d 100644
--- a/drivers/video/backlight/tdo24m.c
+++ b/drivers/video/backlight/tdo24m.c
@@ -328,7 +328,7 @@ static struct lcd_ops tdo24m_ops = {
.set_mode = tdo24m_set_mode,
};
-static int __devinit tdo24m_probe(struct spi_device *spi)
+static int tdo24m_probe(struct spi_device *spi)
{
struct tdo24m *lcd;
struct spi_message *m;
@@ -401,7 +401,7 @@ out_unregister:
return err;
}
-static int __devexit tdo24m_remove(struct spi_device *spi)
+static int tdo24m_remove(struct spi_device *spi)
{
struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
@@ -444,7 +444,7 @@ static struct spi_driver tdo24m_driver = {
.owner = THIS_MODULE,
},
.probe = tdo24m_probe,
- .remove = __devexit_p(tdo24m_remove),
+ .remove = tdo24m_remove,
.shutdown = tdo24m_shutdown,
.suspend = tdo24m_suspend,
.resume = tdo24m_resume,
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
index 49342e1d20b..a0521abdcd8 100644
--- a/drivers/video/backlight/tosa_bl.c
+++ b/drivers/video/backlight/tosa_bl.c
@@ -78,7 +78,7 @@ static const struct backlight_ops bl_ops = {
.update_status = tosa_bl_update_status,
};
-static int __devinit tosa_bl_probe(struct i2c_client *client,
+static int tosa_bl_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct backlight_properties props;
@@ -126,7 +126,7 @@ err_reg:
return ret;
}
-static int __devexit tosa_bl_remove(struct i2c_client *client)
+static int tosa_bl_remove(struct i2c_client *client)
{
struct tosa_bl_data *data = i2c_get_clientdata(client);
@@ -170,7 +170,7 @@ static struct i2c_driver tosa_bl_driver = {
.owner = THIS_MODULE,
},
.probe = tosa_bl_probe,
- .remove = __devexit_p(tosa_bl_remove),
+ .remove = tosa_bl_remove,
.suspend = tosa_bl_suspend,
.resume = tosa_bl_resume,
.id_table = tosa_bl_id,
diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c
index 33047a66cc2..86fff88c2e4 100644
--- a/drivers/video/backlight/tosa_lcd.c
+++ b/drivers/video/backlight/tosa_lcd.c
@@ -169,7 +169,7 @@ static struct lcd_ops tosa_lcd_ops = {
.set_mode = tosa_lcd_set_mode,
};
-static int __devinit tosa_lcd_probe(struct spi_device *spi)
+static int tosa_lcd_probe(struct spi_device *spi)
{
int ret;
struct tosa_lcd_data *data;
@@ -226,7 +226,7 @@ err_gpio_tg:
return ret;
}
-static int __devexit tosa_lcd_remove(struct spi_device *spi)
+static int tosa_lcd_remove(struct spi_device *spi)
{
struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev);
@@ -275,7 +275,7 @@ static struct spi_driver tosa_lcd_driver = {
.owner = THIS_MODULE,
},
.probe = tosa_lcd_probe,
- .remove = __devexit_p(tosa_lcd_remove),
+ .remove = tosa_lcd_remove,
.suspend = tosa_lcd_suspend,
.resume = tosa_lcd_resume,
};
diff --git a/drivers/video/backlight/vgg2432a4.c b/drivers/video/backlight/vgg2432a4.c
index b617fae9aa2..712b0acfd33 100644
--- a/drivers/video/backlight/vgg2432a4.c
+++ b/drivers/video/backlight/vgg2432a4.c
@@ -227,7 +227,7 @@ static struct ili9320_client vgg2432a4_client = {
/* Device probe */
-static int __devinit vgg2432a4_probe(struct spi_device *spi)
+static int vgg2432a4_probe(struct spi_device *spi)
{
int ret;
@@ -240,7 +240,7 @@ static int __devinit vgg2432a4_probe(struct spi_device *spi)
return 0;
}
-static int __devexit vgg2432a4_remove(struct spi_device *spi)
+static int vgg2432a4_remove(struct spi_device *spi)
{
return ili9320_remove(dev_get_drvdata(&spi->dev));
}
@@ -256,7 +256,7 @@ static struct spi_driver vgg2432a4_driver = {
.owner = THIS_MODULE,
},
.probe = vgg2432a4_probe,
- .remove = __devexit_p(vgg2432a4_remove),
+ .remove = vgg2432a4_remove,
.shutdown = vgg2432a4_shutdown,
.suspend = vgg2432a4_suspend,
.resume = vgg2432a4_resume,
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index d64ac384288..bee92846cfa 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -365,11 +365,20 @@ struct platform_device *dsi_get_dsidev_from_id(int module)
struct omap_dss_output *out;
enum omap_dss_output_id id;
- id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+ switch (module) {
+ case 0:
+ id = OMAP_DSS_OUTPUT_DSI1;
+ break;
+ case 1:
+ id = OMAP_DSS_OUTPUT_DSI2;
+ break;
+ default:
+ return NULL;
+ }
out = omap_dss_get_output(id);
- return out->pdev;
+ return out ? out->pdev : NULL;
}
static inline void dsi_write_reg(struct platform_device *dsidev,
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 2ab1c3e9655..5f6eea801b0 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -697,11 +697,15 @@ static int dss_get_clocks(void)
dss.dss_clk = clk;
- clk = clk_get(NULL, dss.feat->clk_name);
- if (IS_ERR(clk)) {
- DSSERR("Failed to get %s\n", dss.feat->clk_name);
- r = PTR_ERR(clk);
- goto err;
+ if (dss.feat->clk_name) {
+ clk = clk_get(NULL, dss.feat->clk_name);
+ if (IS_ERR(clk)) {
+ DSSERR("Failed to get %s\n", dss.feat->clk_name);
+ r = PTR_ERR(clk);
+ goto err;
+ }
+ } else {
+ clk = NULL;
}
dss.dpll4_m4_ck = clk;
@@ -805,10 +809,10 @@ static int __init dss_init_features(struct device *dev)
if (cpu_is_omap24xx())
src = &omap24xx_dss_feats;
- else if (cpu_is_omap34xx())
- src = &omap34xx_dss_feats;
else if (cpu_is_omap3630())
src = &omap3630_dss_feats;
+ else if (cpu_is_omap34xx())
+ src = &omap34xx_dss_feats;
else if (cpu_is_omap44xx())
src = &omap44xx_dss_feats;
else if (soc_is_omap54xx())
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index a48a7dd75b3..8c9b8b3b7f7 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -644,8 +644,10 @@ static void hdmi_dump_regs(struct seq_file *s)
{
mutex_lock(&hdmi.lock);
- if (hdmi_runtime_get())
+ if (hdmi_runtime_get()) {
+ mutex_unlock(&hdmi.lock);
return;
+ }
hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s);
hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s);
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 606b89f1235..d630b26a005 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -787,7 +787,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
case OMAPFB_WAITFORVSYNC:
DBG("ioctl WAITFORVSYNC\n");
- if (!display && !display->output && !display->output->manager) {
+ if (!display || !display->output || !display->output->manager) {
r = -EINVAL;
break;
}
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 0908e604433..2a70558b36e 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -27,13 +27,15 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/balloon_compaction.h>
/*
* Balloon device works in 4K page units. So each page is pointed to by
* multiple balloon pages. All memory counters in this driver are in balloon
* page units.
*/
-#define VIRTIO_BALLOON_PAGES_PER_PAGE (PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT)
+#define VIRTIO_BALLOON_PAGES_PER_PAGE (unsigned)(PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT)
+#define VIRTIO_BALLOON_ARRAY_PFNS_MAX 256
struct virtio_balloon
{
@@ -52,15 +54,19 @@ struct virtio_balloon
/* Number of balloon pages we've told the Host we're not using. */
unsigned int num_pages;
/*
- * The pages we've told the Host we're not using.
+ * The pages we've told the Host we're not using are enqueued
+ * at vb_dev_info->pages list.
* Each page on this list adds VIRTIO_BALLOON_PAGES_PER_PAGE
* to num_pages above.
*/
- struct list_head pages;
+ struct balloon_dev_info *vb_dev_info;
+
+ /* Synchronize access/update to this struct virtio_balloon elements */
+ struct mutex balloon_lock;
/* The array of pfns we tell the Host about. */
unsigned int num_pfns;
- u32 pfns[256];
+ u32 pfns[VIRTIO_BALLOON_ARRAY_PFNS_MAX];
/* Memory statistics */
int need_stats_update;
@@ -122,18 +128,21 @@ static void set_page_pfns(u32 pfns[], struct page *page)
static void fill_balloon(struct virtio_balloon *vb, size_t num)
{
+ struct balloon_dev_info *vb_dev_info = vb->vb_dev_info;
+
/* We can only do one array worth at a time. */
num = min(num, ARRAY_SIZE(vb->pfns));
+ mutex_lock(&vb->balloon_lock);
for (vb->num_pfns = 0; vb->num_pfns < num;
vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
- struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY |
- __GFP_NOMEMALLOC | __GFP_NOWARN);
+ struct page *page = balloon_page_enqueue(vb_dev_info);
+
if (!page) {
if (printk_ratelimit())
dev_printk(KERN_INFO, &vb->vdev->dev,
- "Out of puff! Can't get %zu pages\n",
- num);
+ "Out of puff! Can't get %u pages\n",
+ VIRTIO_BALLOON_PAGES_PER_PAGE);
/* Sleep for at least 1/5 of a second before retry. */
msleep(200);
break;
@@ -141,14 +150,12 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num)
set_page_pfns(vb->pfns + vb->num_pfns, page);
vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE;
totalram_pages--;
- list_add(&page->lru, &vb->pages);
}
- /* Didn't get any? Oh well. */
- if (vb->num_pfns == 0)
- return;
-
- tell_host(vb, vb->inflate_vq);
+ /* Did we get any? */
+ if (vb->num_pfns != 0)
+ tell_host(vb, vb->inflate_vq);
+ mutex_unlock(&vb->balloon_lock);
}
static void release_pages_by_pfn(const u32 pfns[], unsigned int num)
@@ -157,7 +164,7 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num)
/* Find pfns pointing at start of each page, get pages and free them. */
for (i = 0; i < num; i += VIRTIO_BALLOON_PAGES_PER_PAGE) {
- __free_page(balloon_pfn_to_page(pfns[i]));
+ balloon_page_free(balloon_pfn_to_page(pfns[i]));
totalram_pages++;
}
}
@@ -165,14 +172,17 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num)
static void leak_balloon(struct virtio_balloon *vb, size_t num)
{
struct page *page;
+ struct balloon_dev_info *vb_dev_info = vb->vb_dev_info;
/* We can only do one array worth at a time. */
num = min(num, ARRAY_SIZE(vb->pfns));
+ mutex_lock(&vb->balloon_lock);
for (vb->num_pfns = 0; vb->num_pfns < num;
vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
- page = list_first_entry(&vb->pages, struct page, lru);
- list_del(&page->lru);
+ page = balloon_page_dequeue(vb_dev_info);
+ if (!page)
+ break;
set_page_pfns(vb->pfns + vb->num_pfns, page);
vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE;
}
@@ -183,6 +193,7 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num)
* is true, we *have* to do it in this order
*/
tell_host(vb, vb->deflate_vq);
+ mutex_unlock(&vb->balloon_lock);
release_pages_by_pfn(vb->pfns, vb->num_pfns);
}
@@ -339,9 +350,84 @@ static int init_vqs(struct virtio_balloon *vb)
return 0;
}
+static const struct address_space_operations virtio_balloon_aops;
+#ifdef CONFIG_BALLOON_COMPACTION
+/*
+ * virtballoon_migratepage - perform the balloon page migration on behalf of
+ * a compation thread. (called under page lock)
+ * @mapping: the page->mapping which will be assigned to the new migrated page.
+ * @newpage: page that will replace the isolated page after migration finishes.
+ * @page : the isolated (old) page that is about to be migrated to newpage.
+ * @mode : compaction mode -- not used for balloon page migration.
+ *
+ * After a ballooned page gets isolated by compaction procedures, this is the
+ * function that performs the page migration on behalf of a compaction thread
+ * The page migration for virtio balloon is done in a simple swap fashion which
+ * follows these two macro steps:
+ * 1) insert newpage into vb->pages list and update the host about it;
+ * 2) update the host about the old page removed from vb->pages list;
+ *
+ * This function preforms the balloon page migration task.
+ * Called through balloon_mapping->a_ops->migratepage
+ */
+int virtballoon_migratepage(struct address_space *mapping,
+ struct page *newpage, struct page *page, enum migrate_mode mode)
+{
+ struct balloon_dev_info *vb_dev_info = balloon_page_device(page);
+ struct virtio_balloon *vb;
+ unsigned long flags;
+
+ BUG_ON(!vb_dev_info);
+
+ vb = vb_dev_info->balloon_device;
+
+ /*
+ * In order to avoid lock contention while migrating pages concurrently
+ * to leak_balloon() or fill_balloon() we just give up the balloon_lock
+ * this turn, as it is easier to retry the page migration later.
+ * This also prevents fill_balloon() getting stuck into a mutex
+ * recursion in the case it ends up triggering memory compaction
+ * while it is attempting to inflate the ballon.
+ */
+ if (!mutex_trylock(&vb->balloon_lock))
+ return -EAGAIN;
+
+ /* balloon's page migration 1st step -- inflate "newpage" */
+ spin_lock_irqsave(&vb_dev_info->pages_lock, flags);
+ balloon_page_insert(newpage, mapping, &vb_dev_info->pages);
+ vb_dev_info->isolated_pages--;
+ spin_unlock_irqrestore(&vb_dev_info->pages_lock, flags);
+ vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE;
+ set_page_pfns(vb->pfns, newpage);
+ tell_host(vb, vb->inflate_vq);
+
+ /*
+ * balloon's page migration 2nd step -- deflate "page"
+ *
+ * It's safe to delete page->lru here because this page is at
+ * an isolated migration list, and this step is expected to happen here
+ */
+ balloon_page_delete(page);
+ vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE;
+ set_page_pfns(vb->pfns, page);
+ tell_host(vb, vb->deflate_vq);
+
+ mutex_unlock(&vb->balloon_lock);
+
+ return MIGRATEPAGE_BALLOON_SUCCESS;
+}
+
+/* define the balloon_mapping->a_ops callback to allow balloon page migration */
+static const struct address_space_operations virtio_balloon_aops = {
+ .migratepage = virtballoon_migratepage,
+};
+#endif /* CONFIG_BALLOON_COMPACTION */
+
static int virtballoon_probe(struct virtio_device *vdev)
{
struct virtio_balloon *vb;
+ struct address_space *vb_mapping;
+ struct balloon_dev_info *vb_devinfo;
int err;
vdev->priv = vb = kmalloc(sizeof(*vb), GFP_KERNEL);
@@ -350,16 +436,37 @@ static int virtballoon_probe(struct virtio_device *vdev)
goto out;
}
- INIT_LIST_HEAD(&vb->pages);
vb->num_pages = 0;
+ mutex_init(&vb->balloon_lock);
init_waitqueue_head(&vb->config_change);
init_waitqueue_head(&vb->acked);
vb->vdev = vdev;
vb->need_stats_update = 0;
+ vb_devinfo = balloon_devinfo_alloc(vb);
+ if (IS_ERR(vb_devinfo)) {
+ err = PTR_ERR(vb_devinfo);
+ goto out_free_vb;
+ }
+
+ vb_mapping = balloon_mapping_alloc(vb_devinfo,
+ (balloon_compaction_check()) ?
+ &virtio_balloon_aops : NULL);
+ if (IS_ERR(vb_mapping)) {
+ /*
+ * IS_ERR(vb_mapping) && PTR_ERR(vb_mapping) == -EOPNOTSUPP
+ * This means !CONFIG_BALLOON_COMPACTION, otherwise we get off.
+ */
+ err = PTR_ERR(vb_mapping);
+ if (err != -EOPNOTSUPP)
+ goto out_free_vb_devinfo;
+ }
+
+ vb->vb_dev_info = vb_devinfo;
+
err = init_vqs(vb);
if (err)
- goto out_free_vb;
+ goto out_free_vb_mapping;
vb->thread = kthread_run(balloon, vb, "vballoon");
if (IS_ERR(vb->thread)) {
@@ -371,6 +478,10 @@ static int virtballoon_probe(struct virtio_device *vdev)
out_del_vqs:
vdev->config->del_vqs(vdev);
+out_free_vb_mapping:
+ balloon_mapping_free(vb_mapping);
+out_free_vb_devinfo:
+ balloon_devinfo_free(vb_devinfo);
out_free_vb:
kfree(vb);
out:
@@ -396,6 +507,8 @@ static void __devexit virtballoon_remove(struct virtio_device *vdev)
kthread_stop(vb->thread);
remove_common(vb);
+ balloon_mapping_free(vb->vb_dev_info->mapping);
+ balloon_devinfo_free(vb->vb_dev_info);
kfree(vb);
}
diff --git a/drivers/vme/boards/vme_vmivme7805.c b/drivers/vme/boards/vme_vmivme7805.c
index 8e05bb4e135..dd22b5072e2 100644
--- a/drivers/vme/boards/vme_vmivme7805.c
+++ b/drivers/vme/boards/vme_vmivme7805.c
@@ -19,10 +19,8 @@
#include "vme_vmivme7805.h"
-static int __init vmic_init(void);
static int vmic_probe(struct pci_dev *, const struct pci_device_id *);
static void vmic_remove(struct pci_dev *);
-static void __exit vmic_exit(void);
/** Base address to access FPGA register */
static void *vmic_base;
@@ -41,11 +39,6 @@ static struct pci_driver vmic_driver = {
.remove = vmic_remove,
};
-static int __init vmic_init(void)
-{
- return pci_register_driver(&vmic_driver);
-}
-
static int vmic_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
int retval;
@@ -109,15 +102,9 @@ static void vmic_remove(struct pci_dev *pdev)
}
-static void __exit vmic_exit(void)
-{
- pci_unregister_driver(&vmic_driver);
-}
+module_pci_driver(vmic_driver);
MODULE_DESCRIPTION("VMIVME-7805 board support driver");
MODULE_AUTHOR("Arthur Benilov <arthur.benilov@iba-group.com>");
MODULE_LICENSE("GPL");
-module_init(vmic_init);
-module_exit(vmic_exit);
-
diff --git a/drivers/vme/bridges/vme_ca91cx42.c b/drivers/vme/bridges/vme_ca91cx42.c
index 1425d22cf95..64bfea31442 100644
--- a/drivers/vme/bridges/vme_ca91cx42.c
+++ b/drivers/vme/bridges/vme_ca91cx42.c
@@ -34,10 +34,8 @@
#include "../vme_bridge.h"
#include "vme_ca91cx42.h"
-static int __init ca91cx42_init(void);
static int ca91cx42_probe(struct pci_dev *, const struct pci_device_id *);
static void ca91cx42_remove(struct pci_dev *);
-static void __exit ca91cx42_exit(void);
/* Module parameters */
static int geoid;
@@ -1523,11 +1521,6 @@ static void ca91cx42_free_consistent(struct device *parent, size_t size,
pci_free_consistent(pdev, size, vaddr, dma);
}
-static int __init ca91cx42_init(void)
-{
- return pci_register_driver(&ca91cx42_driver);
-}
-
/*
* Configure CR/CSR space
*
@@ -1944,16 +1937,10 @@ static void ca91cx42_remove(struct pci_dev *pdev)
kfree(ca91cx42_bridge);
}
-static void __exit ca91cx42_exit(void)
-{
- pci_unregister_driver(&ca91cx42_driver);
-}
+module_pci_driver(ca91cx42_driver);
MODULE_PARM_DESC(geoid, "Override geographical addressing");
module_param(geoid, int, 0);
MODULE_DESCRIPTION("VME driver for the Tundra Universe II VME bridge");
MODULE_LICENSE("GPL");
-
-module_init(ca91cx42_init);
-module_exit(ca91cx42_exit);
diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c
index 5fbd08ffb9c..9c1aa4dc39c 100644
--- a/drivers/vme/bridges/vme_tsi148.c
+++ b/drivers/vme/bridges/vme_tsi148.c
@@ -35,10 +35,8 @@
#include "../vme_bridge.h"
#include "vme_tsi148.h"
-static int __init tsi148_init(void);
static int tsi148_probe(struct pci_dev *, const struct pci_device_id *);
static void tsi148_remove(struct pci_dev *);
-static void __exit tsi148_exit(void);
/* Module parameter */
@@ -2244,11 +2242,6 @@ static void tsi148_free_consistent(struct device *parent, size_t size,
pci_free_consistent(pdev, size, vaddr, dma);
}
-static int __init tsi148_init(void)
-{
- return pci_register_driver(&tsi148_driver);
-}
-
/*
* Configure CR/CSR space
*
@@ -2754,10 +2747,7 @@ static void tsi148_remove(struct pci_dev *pdev)
kfree(tsi148_bridge);
}
-static void __exit tsi148_exit(void)
-{
- pci_unregister_driver(&tsi148_driver);
-}
+module_pci_driver(tsi148_driver);
MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes");
module_param(err_chk, bool, 0);
@@ -2767,6 +2757,3 @@ module_param(geoid, int, 0);
MODULE_DESCRIPTION("VME driver for the Tundra Tempe VME bridge");
MODULE_LICENSE("GPL");
-
-module_init(tsi148_init);
-module_exit(tsi148_exit);
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig
index 7e984034a11..c433a746e3f 100644
--- a/drivers/w1/masters/Kconfig
+++ b/drivers/w1/masters/Kconfig
@@ -26,7 +26,7 @@ config W1_MASTER_DS2490
config W1_MASTER_DS2482
tristate "Maxim DS2482 I2C to 1-Wire bridge"
- depends on I2C && EXPERIMENTAL
+ depends on I2C
help
If you say yes here you get support for the Maxim DS2482
I2C to 1-Wire bridge.
diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c
index e5f74416d4b..6429b9e9fb8 100644
--- a/drivers/w1/masters/ds2482.c
+++ b/drivers/w1/masters/ds2482.c
@@ -505,19 +505,8 @@ static int ds2482_remove(struct i2c_client *client)
return 0;
}
-static int __init sensors_ds2482_init(void)
-{
- return i2c_add_driver(&ds2482_driver);
-}
-
-static void __exit sensors_ds2482_exit(void)
-{
- i2c_del_driver(&ds2482_driver);
-}
+module_i2c_driver(ds2482_driver);
MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
MODULE_DESCRIPTION("DS2482 driver");
MODULE_LICENSE("GPL");
-
-module_init(sensors_ds2482_init);
-module_exit(sensors_ds2482_exit);
diff --git a/drivers/w1/masters/matrox_w1.c b/drivers/w1/masters/matrox_w1.c
index f667c26b219..d8667b0212d 100644
--- a/drivers/w1/masters/matrox_w1.c
+++ b/drivers/w1/masters/matrox_w1.c
@@ -48,14 +48,14 @@ static struct pci_device_id matrox_w1_tbl[] = {
};
MODULE_DEVICE_TABLE(pci, matrox_w1_tbl);
-static int __devinit matrox_w1_probe(struct pci_dev *, const struct pci_device_id *);
-static void __devexit matrox_w1_remove(struct pci_dev *);
+static int matrox_w1_probe(struct pci_dev *, const struct pci_device_id *);
+static void matrox_w1_remove(struct pci_dev *);
static struct pci_driver matrox_w1_pci_driver = {
.name = "matrox_w1",
.id_table = matrox_w1_tbl,
.probe = matrox_w1_probe,
- .remove = __devexit_p(matrox_w1_remove),
+ .remove = matrox_w1_remove,
};
/*
@@ -152,7 +152,7 @@ static void matrox_w1_hw_init(struct matrox_device *dev)
matrox_w1_write_reg(dev, MATROX_GET_CONTROL, 0x00);
}
-static int __devinit matrox_w1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int matrox_w1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct matrox_device *dev;
int err;
@@ -220,7 +220,7 @@ err_out_free_device:
return err;
}
-static void __devexit matrox_w1_remove(struct pci_dev *pdev)
+static void matrox_w1_remove(struct pci_dev *pdev)
{
struct matrox_device *dev = pci_get_drvdata(pdev);
diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c
index 1cc61a700fa..d338b56ea2f 100644
--- a/drivers/w1/masters/mxc_w1.c
+++ b/drivers/w1/masters/mxc_w1.c
@@ -103,7 +103,7 @@ static u8 mxc_w1_ds2_touch_bit(void *data, u8 bit)
return ((__raw_readb(ctrl_addr)) >> 3) & 0x1;
}
-static int __devinit mxc_w1_probe(struct platform_device *pdev)
+static int mxc_w1_probe(struct platform_device *pdev)
{
struct mxc_w1_device *mdev;
struct resource *res;
@@ -117,9 +117,9 @@ static int __devinit mxc_w1_probe(struct platform_device *pdev)
if (!mdev)
return -ENOMEM;
- mdev->clk = clk_get(&pdev->dev, "owire");
- if (!mdev->clk) {
- err = -ENODEV;
+ mdev->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(mdev->clk)) {
+ err = PTR_ERR(mdev->clk);
goto failed_clk;
}
@@ -134,7 +134,7 @@ static int __devinit mxc_w1_probe(struct platform_device *pdev)
mdev->regs = ioremap(res->start, resource_size(res));
if (!mdev->regs) {
- printk(KERN_ERR "Cannot map frame buffer registers\n");
+ dev_err(&pdev->dev, "Cannot map mxc_w1 registers\n");
goto failed_ioremap;
}
@@ -167,7 +167,7 @@ failed_clk:
/*
* disassociate the w1 device from the driver
*/
-static int __devexit mxc_w1_remove(struct platform_device *pdev)
+static int mxc_w1_remove(struct platform_device *pdev)
{
struct mxc_w1_device *mdev = platform_get_drvdata(pdev);
struct resource *res;
@@ -191,21 +191,9 @@ static struct platform_driver mxc_w1_driver = {
.name = "mxc_w1",
},
.probe = mxc_w1_probe,
- .remove = mxc_w1_remove,
+ .remove = __devexit_p(mxc_w1_remove),
};
-
-static int __init mxc_w1_init(void)
-{
- return platform_driver_register(&mxc_w1_driver);
-}
-
-static void mxc_w1_exit(void)
-{
- platform_driver_unregister(&mxc_w1_driver);
-}
-
-module_init(mxc_w1_init);
-module_exit(mxc_w1_exit);
+module_platform_driver(mxc_w1_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Freescale Semiconductors Inc");
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c
index ca8e60bb2f9..184dbce4abd 100644
--- a/drivers/w1/masters/omap_hdq.c
+++ b/drivers/w1/masters/omap_hdq.c
@@ -69,12 +69,12 @@ struct hdq_data {
int init_trans;
};
-static int __devinit omap_hdq_probe(struct platform_device *pdev);
-static int __devexit omap_hdq_remove(struct platform_device *pdev);
+static int omap_hdq_probe(struct platform_device *pdev);
+static int omap_hdq_remove(struct platform_device *pdev);
static struct platform_driver omap_hdq_driver = {
.probe = omap_hdq_probe,
- .remove = __devexit_p(omap_hdq_remove),
+ .remove = omap_hdq_remove,
.driver = {
.name = "omap_hdq",
},
@@ -537,7 +537,7 @@ static void omap_w1_write_byte(void *_hdq, u8 byte)
}
}
-static int __devinit omap_hdq_probe(struct platform_device *pdev)
+static int omap_hdq_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct hdq_data *hdq_data;
@@ -613,7 +613,7 @@ err_w1:
return ret;
}
-static int __devexit omap_hdq_remove(struct platform_device *pdev)
+static int omap_hdq_remove(struct platform_device *pdev)
{
struct hdq_data *hdq_data = platform_get_drvdata(pdev);
diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c
index 6012c4ea320..85b363a5bd0 100644
--- a/drivers/w1/masters/w1-gpio.c
+++ b/drivers/w1/masters/w1-gpio.c
@@ -16,6 +16,9 @@
#include <linux/gpio.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/err.h>
+#include <linux/of.h>
#include "../w1.h"
#include "../w1_int.h"
@@ -44,7 +47,6 @@ static u8 w1_gpio_read_bit(void *data)
return gpio_get_value(pdata->pin) ? 1 : 0;
}
-#ifdef CONFIG_OF
static struct of_device_id w1_gpio_dt_ids[] = {
{ .compatible = "w1-gpio" },
{}
@@ -55,11 +57,6 @@ 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;
- const struct of_device_id *of_id =
- of_match_device(w1_gpio_dt_ids, &pdev->dev);
-
- if (!of_id)
- return 0;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@@ -74,41 +71,53 @@ static int w1_gpio_probe_dt(struct platform_device *pdev)
return 0;
}
-#else
-static int w1_gpio_probe_dt(struct platform_device *pdev)
-{
- return 0;
-}
-#endif
static int __init w1_gpio_probe(struct platform_device *pdev)
{
struct w1_bus_master *master;
struct w1_gpio_platform_data *pdata;
+ struct pinctrl *pinctrl;
int err;
- err = w1_gpio_probe_dt(pdev);
- if (err < 0)
- return err;
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl))
+ dev_warn(&pdev->dev, "unable to select pin group\n");
+
+ if (of_have_populated_dt()) {
+ err = w1_gpio_probe_dt(pdev);
+ if (err < 0) {
+ dev_err(&pdev->dev, "Failed to parse DT\n");
+ return err;
+ }
+ }
pdata = pdev->dev.platform_data;
- if (!pdata)
+ if (!pdata) {
+ dev_err(&pdev->dev, "No configuration data\n");
return -ENXIO;
+ }
master = kzalloc(sizeof(struct w1_bus_master), GFP_KERNEL);
- if (!master)
+ if (!master) {
+ dev_err(&pdev->dev, "Out of memory\n");
return -ENOMEM;
+ }
err = gpio_request(pdata->pin, "w1");
- if (err)
+ if (err) {
+ dev_err(&pdev->dev, "gpio_request (pin) failed\n");
goto free_master;
+ }
if (gpio_is_valid(pdata->ext_pullup_enable_pin)) {
err = gpio_request_one(pdata->ext_pullup_enable_pin,
GPIOF_INIT_LOW, "w1 pullup");
- if (err < 0)
+ if (err < 0) {
+ dev_err(&pdev->dev, "gpio_request_one "
+ "(ext_pullup_enable_pin) failed\n");
goto free_gpio;
+ }
}
master->data = pdata;
@@ -123,8 +132,10 @@ static int __init w1_gpio_probe(struct platform_device *pdev)
}
err = w1_add_master_device(master);
- if (err)
+ if (err) {
+ dev_err(&pdev->dev, "w1_add_master device failed\n");
goto free_gpio_ext_pu;
+ }
if (pdata->enable_external_pullup)
pdata->enable_external_pullup(1);
@@ -198,23 +209,13 @@ static struct platform_driver w1_gpio_driver = {
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(w1_gpio_dt_ids),
},
+ .probe = w1_gpio_probe,
.remove = __exit_p(w1_gpio_remove),
.suspend = w1_gpio_suspend,
.resume = w1_gpio_resume,
};
-static int __init w1_gpio_init(void)
-{
- return platform_driver_probe(&w1_gpio_driver, w1_gpio_probe);
-}
-
-static void __exit w1_gpio_exit(void)
-{
- platform_driver_unregister(&w1_gpio_driver);
-}
-
-module_init(w1_gpio_init);
-module_exit(w1_gpio_exit);
+module_platform_driver(w1_gpio_driver);
MODULE_DESCRIPTION("GPIO w1 bus master driver");
MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>");
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 1a574370d2c..7994d933f04 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -551,7 +551,6 @@ void w1_destroy_master_attributes(struct w1_master *master)
sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group);
}
-#ifdef CONFIG_HOTPLUG
static int w1_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct w1_master *md = NULL;
@@ -587,12 +586,6 @@ static int w1_uevent(struct device *dev, struct kobj_uevent_env *env)
end:
return err;
}
-#else
-static int w1_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- return 0;
-}
-#endif
static int __w1_attach_slave_device(struct w1_slave *sl)
{
diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c
index 4397881c83f..24a517777fa 100644
--- a/drivers/watchdog/acquirewdt.c
+++ b/drivers/watchdog/acquirewdt.c
@@ -240,7 +240,7 @@ static struct miscdevice acq_miscdev = {
* Init & exit routines
*/
-static int __devinit acq_probe(struct platform_device *dev)
+static int acq_probe(struct platform_device *dev)
{
int ret;
@@ -275,7 +275,7 @@ out:
return ret;
}
-static int __devexit acq_remove(struct platform_device *dev)
+static int acq_remove(struct platform_device *dev)
{
misc_deregister(&acq_miscdev);
release_region(wdt_start, 1);
@@ -293,7 +293,7 @@ static void acq_shutdown(struct platform_device *dev)
static struct platform_driver acquirewdt_driver = {
.probe = acq_probe,
- .remove = __devexit_p(acq_remove),
+ .remove = acq_remove,
.shutdown = acq_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c
index 64ae9e9fed9..cc6702fc526 100644
--- a/drivers/watchdog/advantechwdt.c
+++ b/drivers/watchdog/advantechwdt.c
@@ -238,7 +238,7 @@ static struct miscdevice advwdt_miscdev = {
* Init & exit routines
*/
-static int __devinit advwdt_probe(struct platform_device *dev)
+static int advwdt_probe(struct platform_device *dev)
{
int ret;
@@ -282,7 +282,7 @@ unreg_stop:
goto out;
}
-static int __devexit advwdt_remove(struct platform_device *dev)
+static int advwdt_remove(struct platform_device *dev)
{
misc_deregister(&advwdt_miscdev);
release_region(wdt_start, 1);
@@ -300,7 +300,7 @@ static void advwdt_shutdown(struct platform_device *dev)
static struct platform_driver advwdt_driver = {
.probe = advwdt_probe,
- .remove = __devexit_p(advwdt_remove),
+ .remove = advwdt_remove,
.shutdown = advwdt_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c
index dc30dbd21cf..3003e2a9580 100644
--- a/drivers/watchdog/ar7_wdt.c
+++ b/drivers/watchdog/ar7_wdt.c
@@ -274,7 +274,7 @@ static struct miscdevice ar7_wdt_miscdev = {
.fops = &ar7_wdt_fops,
};
-static int __devinit ar7_wdt_probe(struct platform_device *pdev)
+static int ar7_wdt_probe(struct platform_device *pdev)
{
int rc;
@@ -314,7 +314,7 @@ out:
return rc;
}
-static int __devexit ar7_wdt_remove(struct platform_device *pdev)
+static int ar7_wdt_remove(struct platform_device *pdev)
{
misc_deregister(&ar7_wdt_miscdev);
clk_put(vbus_clk);
@@ -330,7 +330,7 @@ static void ar7_wdt_shutdown(struct platform_device *pdev)
static struct platform_driver ar7_wdt_driver = {
.probe = ar7_wdt_probe,
- .remove = __devexit_p(ar7_wdt_remove),
+ .remove = ar7_wdt_remove,
.shutdown = ar7_wdt_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index 7ef99a169e3..89831ed24a4 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -199,7 +199,7 @@ static struct miscdevice at91wdt_miscdev = {
.fops = &at91wdt_fops,
};
-static int __devinit at91wdt_probe(struct platform_device *pdev)
+static int at91wdt_probe(struct platform_device *pdev)
{
int res;
@@ -216,7 +216,7 @@ static int __devinit at91wdt_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit at91wdt_remove(struct platform_device *pdev)
+static int at91wdt_remove(struct platform_device *pdev)
{
int res;
@@ -254,7 +254,7 @@ static int at91wdt_resume(struct platform_device *pdev)
static struct platform_driver at91wdt_driver = {
.probe = at91wdt_probe,
- .remove = __devexit_p(at91wdt_remove),
+ .remove = at91wdt_remove,
.shutdown = at91wdt_shutdown,
.suspend = at91wdt_suspend,
.resume = at91wdt_resume,
diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c
index 1f9371f49c4..7c8ede7816b 100644
--- a/drivers/watchdog/ath79_wdt.c
+++ b/drivers/watchdog/ath79_wdt.c
@@ -224,7 +224,7 @@ static struct miscdevice ath79_wdt_miscdev = {
.fops = &ath79_wdt_fops,
};
-static int __devinit ath79_wdt_probe(struct platform_device *pdev)
+static int ath79_wdt_probe(struct platform_device *pdev)
{
u32 ctrl;
int err;
@@ -270,7 +270,7 @@ err_clk_put:
return err;
}
-static int __devexit ath79_wdt_remove(struct platform_device *pdev)
+static int ath79_wdt_remove(struct platform_device *pdev)
{
misc_deregister(&ath79_wdt_miscdev);
clk_disable(wdt_clk);
@@ -284,7 +284,7 @@ static void ath97_wdt_shutdown(struct platform_device *pdev)
}
static struct platform_driver ath79_wdt_driver = {
- .remove = __devexit_p(ath79_wdt_remove),
+ .remove = ath79_wdt_remove,
.shutdown = ath97_wdt_shutdown,
.driver = {
.name = DRIVER_NAME,
diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c
index 551880bfd62..b2b80d4ac81 100644
--- a/drivers/watchdog/bcm63xx_wdt.c
+++ b/drivers/watchdog/bcm63xx_wdt.c
@@ -236,7 +236,7 @@ static struct miscdevice bcm63xx_wdt_miscdev = {
};
-static int __devinit bcm63xx_wdt_probe(struct platform_device *pdev)
+static int bcm63xx_wdt_probe(struct platform_device *pdev)
{
int ret;
struct resource *r;
@@ -286,7 +286,7 @@ unmap:
return ret;
}
-static int __devexit bcm63xx_wdt_remove(struct platform_device *pdev)
+static int bcm63xx_wdt_remove(struct platform_device *pdev)
{
if (!nowayout)
bcm63xx_wdt_pause();
@@ -304,7 +304,7 @@ static void bcm63xx_wdt_shutdown(struct platform_device *pdev)
static struct platform_driver bcm63xx_wdt_driver = {
.probe = bcm63xx_wdt_probe,
- .remove = __devexit_p(bcm63xx_wdt_remove),
+ .remove = bcm63xx_wdt_remove,
.shutdown = bcm63xx_wdt_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
index 38bc383e067..5d36d6fb496 100644
--- a/drivers/watchdog/bfin_wdt.c
+++ b/drivers/watchdog/bfin_wdt.c
@@ -356,7 +356,7 @@ static const struct watchdog_info bfin_wdt_info = {
* Registers the misc device. Actual device
* initialization is handled by bfin_wdt_open().
*/
-static int __devinit bfin_wdt_probe(struct platform_device *pdev)
+static int bfin_wdt_probe(struct platform_device *pdev)
{
int ret;
@@ -379,7 +379,7 @@ static int __devinit bfin_wdt_probe(struct platform_device *pdev)
* Unregisters the misc device. Actual device
* deinitialization is handled by bfin_wdt_close().
*/
-static int __devexit bfin_wdt_remove(struct platform_device *pdev)
+static int bfin_wdt_remove(struct platform_device *pdev)
{
misc_deregister(&bfin_wdt_miscdev);
return 0;
@@ -401,7 +401,7 @@ static struct platform_device *bfin_wdt_device;
static struct platform_driver bfin_wdt_driver = {
.probe = bfin_wdt_probe,
- .remove = __devexit_p(bfin_wdt_remove),
+ .remove = bfin_wdt_remove,
.shutdown = bfin_wdt_shutdown,
.suspend = bfin_wdt_suspend,
.resume = bfin_wdt_resume,
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c
index 7e888393de1..cd87758abac 100644
--- a/drivers/watchdog/cpu5wdt.c
+++ b/drivers/watchdog/cpu5wdt.c
@@ -215,7 +215,7 @@ static struct miscdevice cpu5wdt_misc = {
/* init/exit function */
-static int __devinit cpu5wdt_init(void)
+static int cpu5wdt_init(void)
{
unsigned int val;
int err;
@@ -256,12 +256,12 @@ no_port:
return err;
}
-static int __devinit cpu5wdt_init_module(void)
+static int cpu5wdt_init_module(void)
{
return cpu5wdt_init();
}
-static void __devexit cpu5wdt_exit(void)
+static void cpu5wdt_exit(void)
{
if (cpu5wdt_device.queue) {
cpu5wdt_device.queue = 0;
@@ -274,7 +274,7 @@ static void __devexit cpu5wdt_exit(void)
}
-static void __devexit cpu5wdt_exit_module(void)
+static void cpu5wdt_exit_module(void)
{
cpu5wdt_exit();
}
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c
index 95b1b954de1..11d55ce5ca8 100644
--- a/drivers/watchdog/cpwd.c
+++ b/drivers/watchdog/cpwd.c
@@ -528,7 +528,7 @@ static const struct file_operations cpwd_fops = {
.llseek = no_llseek,
};
-static int __devinit cpwd_probe(struct platform_device *op)
+static int cpwd_probe(struct platform_device *op)
{
struct device_node *options;
const char *str_prop;
@@ -640,7 +640,7 @@ out_free:
goto out;
}
-static int __devexit cpwd_remove(struct platform_device *op)
+static int cpwd_remove(struct platform_device *op)
{
struct cpwd *p = dev_get_drvdata(&op->dev);
int i;
@@ -684,7 +684,7 @@ static struct platform_driver cpwd_driver = {
.of_match_table = cpwd_match,
},
.probe = cpwd_probe,
- .remove = __devexit_p(cpwd_remove),
+ .remove = cpwd_remove,
};
module_platform_driver(cpwd_driver);
diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c
index f7abbaeebca..8be70d8f268 100644
--- a/drivers/watchdog/da9052_wdt.c
+++ b/drivers/watchdog/da9052_wdt.c
@@ -179,7 +179,7 @@ static const struct watchdog_ops da9052_wdt_ops = {
};
-static int __devinit da9052_wdt_probe(struct platform_device *pdev)
+static int da9052_wdt_probe(struct platform_device *pdev)
{
struct da9052 *da9052 = dev_get_drvdata(pdev->dev.parent);
struct da9052_wdt_data *driver_data;
@@ -224,7 +224,7 @@ err:
return ret;
}
-static int __devexit da9052_wdt_remove(struct platform_device *pdev)
+static int da9052_wdt_remove(struct platform_device *pdev)
{
struct da9052_wdt_data *driver_data = dev_get_drvdata(&pdev->dev);
@@ -236,7 +236,7 @@ static int __devexit da9052_wdt_remove(struct platform_device *pdev)
static struct platform_driver da9052_wdt_driver = {
.probe = da9052_wdt_probe,
- .remove = __devexit_p(da9052_wdt_remove),
+ .remove = da9052_wdt_remove,
.driver = {
.name = "da9052-watchdog",
},
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index c8c5c8032bc..8791879e518 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -199,7 +199,7 @@ static struct miscdevice davinci_wdt_miscdev = {
.fops = &davinci_wdt_fops,
};
-static int __devinit davinci_wdt_probe(struct platform_device *pdev)
+static int davinci_wdt_probe(struct platform_device *pdev)
{
int ret = 0, size;
struct device *dev = &pdev->dev;
@@ -248,7 +248,7 @@ static int __devinit davinci_wdt_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit davinci_wdt_remove(struct platform_device *pdev)
+static int davinci_wdt_remove(struct platform_device *pdev)
{
misc_deregister(&davinci_wdt_miscdev);
if (wdt_mem) {
@@ -268,7 +268,7 @@ static struct platform_driver platform_wdt_driver = {
.owner = THIS_MODULE,
},
.probe = davinci_wdt_probe,
- .remove = __devexit_p(davinci_wdt_remove),
+ .remove = davinci_wdt_remove,
};
module_platform_driver(platform_wdt_driver);
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index 06de1211a44..a0eba3c40e2 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -293,7 +293,7 @@ static struct miscdevice dw_wdt_miscdev = {
.minor = WATCHDOG_MINOR,
};
-static int __devinit dw_wdt_drv_probe(struct platform_device *pdev)
+static int dw_wdt_drv_probe(struct platform_device *pdev)
{
int ret;
struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -333,7 +333,7 @@ out_put_clk:
return ret;
}
-static int __devexit dw_wdt_drv_remove(struct platform_device *pdev)
+static int dw_wdt_drv_remove(struct platform_device *pdev)
{
misc_deregister(&dw_wdt_miscdev);
@@ -345,7 +345,7 @@ static int __devexit dw_wdt_drv_remove(struct platform_device *pdev)
static struct platform_driver dw_wdt_driver = {
.probe = dw_wdt_drv_probe,
- .remove = __devexit_p(dw_wdt_drv_remove),
+ .remove = dw_wdt_drv_remove,
.driver = {
.name = "dw_wdt",
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index 77050037597..e0574844c31 100644
--- a/drivers/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
@@ -112,7 +112,7 @@ static struct watchdog_device ep93xx_wdt_wdd = {
.ops = &ep93xx_wdt_ops,
};
-static int __devinit ep93xx_wdt_probe(struct platform_device *pdev)
+static int ep93xx_wdt_probe(struct platform_device *pdev)
{
struct resource *res;
unsigned long val;
@@ -156,7 +156,7 @@ static int __devinit ep93xx_wdt_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit ep93xx_wdt_remove(struct platform_device *pdev)
+static int ep93xx_wdt_remove(struct platform_device *pdev)
{
watchdog_unregister_device(&ep93xx_wdt_wdd);
return 0;
@@ -168,7 +168,7 @@ static struct platform_driver ep93xx_wdt_driver = {
.name = "ep93xx-wdt",
},
.probe = ep93xx_wdt_probe,
- .remove = __devexit_p(ep93xx_wdt_remove),
+ .remove = ep93xx_wdt_remove,
};
module_platform_driver(ep93xx_wdt_driver);
diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c
index 17f4cae770c..b9c5b58e59d 100644
--- a/drivers/watchdog/gef_wdt.c
+++ b/drivers/watchdog/gef_wdt.c
@@ -262,7 +262,7 @@ static struct miscdevice gef_wdt_miscdev = {
};
-static int __devinit gef_wdt_probe(struct platform_device *dev)
+static int gef_wdt_probe(struct platform_device *dev)
{
int timeout = 10;
u32 freq;
@@ -285,7 +285,7 @@ static int __devinit gef_wdt_probe(struct platform_device *dev)
return misc_register(&gef_wdt_miscdev);
}
-static int __devexit gef_wdt_remove(struct platform_device *dev)
+static int gef_wdt_remove(struct platform_device *dev)
{
misc_deregister(&gef_wdt_miscdev);
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c
index dc563b680ab..fcd599d4e22 100644
--- a/drivers/watchdog/geodewdt.c
+++ b/drivers/watchdog/geodewdt.c
@@ -215,7 +215,7 @@ static struct miscdevice geodewdt_miscdev = {
.fops = &geodewdt_fops,
};
-static int __devinit geodewdt_probe(struct platform_device *dev)
+static int geodewdt_probe(struct platform_device *dev)
{
int ret;
@@ -243,7 +243,7 @@ static int __devinit geodewdt_probe(struct platform_device *dev)
return ret;
}
-static int __devexit geodewdt_remove(struct platform_device *dev)
+static int geodewdt_remove(struct platform_device *dev)
{
misc_deregister(&geodewdt_miscdev);
return 0;
@@ -256,7 +256,7 @@ static void geodewdt_shutdown(struct platform_device *dev)
static struct platform_driver geodewdt_driver = {
.probe = geodewdt_probe,
- .remove = __devexit_p(geodewdt_remove),
+ .remove = geodewdt_remove,
.shutdown = geodewdt_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index ae60406ea8a..8717255ec7b 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -212,7 +212,7 @@ asm(".text \n\t"
* 0 : SUCCESS
* <0 : FAILURE
*/
-static int __devinit cru_detect(unsigned long map_entry,
+static int cru_detect(unsigned long map_entry,
unsigned long map_offset)
{
void *bios32_map;
@@ -268,7 +268,7 @@ static int __devinit cru_detect(unsigned long map_entry,
/*
* bios_checksum
*/
-static int __devinit bios_checksum(const char __iomem *ptr, int len)
+static int bios_checksum(const char __iomem *ptr, int len)
{
char sum = 0;
int i;
@@ -293,7 +293,7 @@ static int __devinit bios_checksum(const char __iomem *ptr, int len)
* 0 : SUCCESS
* <0 : FAILURE
*/
-static int __devinit bios32_present(const char __iomem *p)
+static int bios32_present(const char __iomem *p)
{
struct bios32_service_dir *bios_32_ptr;
int length;
@@ -323,7 +323,7 @@ static int __devinit bios32_present(const char __iomem *p)
return -ENODEV;
}
-static int __devinit detect_cru_service(void)
+static int detect_cru_service(void)
{
char __iomem *p, *q;
int rc = -1;
@@ -395,7 +395,7 @@ asm(".text \n\t"
* This function checks whether or not a SMBIOS/DMI record is
* the 64bit CRU info or not
*/
-static void __devinit dmi_find_cru(const struct dmi_header *dm, void *dummy)
+static void dmi_find_cru(const struct dmi_header *dm, void *dummy)
{
struct smbios_cru64_info *smbios_cru64_ptr;
unsigned long cru_physical_address;
@@ -414,7 +414,7 @@ static void __devinit dmi_find_cru(const struct dmi_header *dm, void *dummy)
}
}
-static int __devinit detect_cru_service(void)
+static int detect_cru_service(void)
{
cru_rom_addr = NULL;
@@ -647,7 +647,7 @@ static struct miscdevice hpwdt_miscdev = {
#ifdef CONFIG_HPWDT_NMI_DECODING
#ifdef CONFIG_X86_LOCAL_APIC
-static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev)
+static void hpwdt_check_nmi_decoding(struct pci_dev *dev)
{
/*
* If nmi_watchdog is turned off then we can turn on
@@ -656,7 +656,7 @@ static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev)
hpwdt_nmi_decoding = 1;
}
#else
-static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev)
+static void hpwdt_check_nmi_decoding(struct pci_dev *dev)
{
dev_warn(&dev->dev, "NMI decoding is disabled. "
"Your kernel does not support a NMI Watchdog.\n");
@@ -671,7 +671,7 @@ static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev)
* This check is independent of architecture and needs to be made for
* any ProLiant system.
*/
-static void __devinit dmi_find_icru(const struct dmi_header *dm, void *dummy)
+static void dmi_find_icru(const struct dmi_header *dm, void *dummy)
{
struct smbios_proliant_info *smbios_proliant_ptr;
@@ -682,7 +682,7 @@ static void __devinit dmi_find_icru(const struct dmi_header *dm, void *dummy)
}
}
-static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev)
+static int hpwdt_init_nmi_decoding(struct pci_dev *dev)
{
int retval;
@@ -762,11 +762,11 @@ static void hpwdt_exit_nmi_decoding(void)
iounmap(cru_rom_addr);
}
#else /* !CONFIG_HPWDT_NMI_DECODING */
-static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev)
+static void hpwdt_check_nmi_decoding(struct pci_dev *dev)
{
}
-static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev)
+static int hpwdt_init_nmi_decoding(struct pci_dev *dev)
{
return 0;
}
@@ -776,7 +776,7 @@ static void hpwdt_exit_nmi_decoding(void)
}
#endif /* CONFIG_HPWDT_NMI_DECODING */
-static int __devinit hpwdt_init_one(struct pci_dev *dev,
+static int hpwdt_init_one(struct pci_dev *dev,
const struct pci_device_id *ent)
{
int retval;
@@ -848,7 +848,7 @@ error_pci_iomap:
return retval;
}
-static void __devexit hpwdt_exit(struct pci_dev *dev)
+static void hpwdt_exit(struct pci_dev *dev)
{
if (!nowayout)
hpwdt_stop();
@@ -863,7 +863,7 @@ static struct pci_driver hpwdt_driver = {
.name = "hpwdt",
.id_table = hpwdt_devices,
.probe = hpwdt_init_one,
- .remove = __devexit_p(hpwdt_exit),
+ .remove = hpwdt_exit,
};
MODULE_AUTHOR("Tom Mingarelli");
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index 276877d5b6a..2b2ea13d03e 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -344,7 +344,7 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl);
* Init & exit routines
*/
-static unsigned char __devinit esb_getdevice(struct pci_dev *pdev)
+static unsigned char esb_getdevice(struct pci_dev *pdev)
{
if (pci_enable_device(pdev)) {
pr_err("failed to enable device\n");
@@ -375,7 +375,7 @@ err_devput:
return 0;
}
-static void __devinit esb_initdevice(void)
+static void esb_initdevice(void)
{
u8 val1;
u16 val2;
@@ -416,7 +416,7 @@ static void __devinit esb_initdevice(void)
esb_timer_set_heartbeat(heartbeat);
}
-static int __devinit esb_probe(struct pci_dev *pdev,
+static int esb_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
int ret;
@@ -465,7 +465,7 @@ err_unmap:
return ret;
}
-static void __devexit esb_remove(struct pci_dev *pdev)
+static void esb_remove(struct pci_dev *pdev)
{
/* Stop the timer before we leave */
if (!nowayout)
@@ -488,7 +488,7 @@ static struct pci_driver esb_driver = {
.name = ESB_MODULE_NAME,
.id_table = esb_pci_tbl,
.probe = esb_probe,
- .remove = __devexit_p(esb_remove),
+ .remove = esb_remove,
.shutdown = esb_shutdown,
};
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 545d387de41..6130321da38 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -364,7 +364,7 @@ static struct watchdog_device iTCO_wdt_watchdog_dev = {
* Init & exit routines
*/
-static void __devexit iTCO_wdt_cleanup(void)
+static void iTCO_wdt_cleanup(void)
{
/* Stop the timer before we leave */
if (!nowayout)
@@ -390,7 +390,7 @@ static void __devexit iTCO_wdt_cleanup(void)
iTCO_wdt_private.gcs = NULL;
}
-static int __devinit iTCO_wdt_probe(struct platform_device *dev)
+static int iTCO_wdt_probe(struct platform_device *dev)
{
int ret = -ENODEV;
unsigned long val32;
@@ -533,7 +533,7 @@ out:
return ret;
}
-static int __devexit iTCO_wdt_remove(struct platform_device *dev)
+static int iTCO_wdt_remove(struct platform_device *dev)
{
if (iTCO_wdt_private.tco_res || iTCO_wdt_private.smi_res)
iTCO_wdt_cleanup();
@@ -548,7 +548,7 @@ static void iTCO_wdt_shutdown(struct platform_device *dev)
static struct platform_driver iTCO_wdt_driver = {
.probe = iTCO_wdt_probe,
- .remove = __devexit_p(iTCO_wdt_remove),
+ .remove = iTCO_wdt_remove,
.shutdown = iTCO_wdt_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c
index 184c0bfc87a..eb6b5cc98ec 100644
--- a/drivers/watchdog/ib700wdt.c
+++ b/drivers/watchdog/ib700wdt.c
@@ -277,7 +277,7 @@ static struct miscdevice ibwdt_miscdev = {
* Init & exit routines
*/
-static int __devinit ibwdt_probe(struct platform_device *dev)
+static int ibwdt_probe(struct platform_device *dev)
{
int res;
@@ -319,7 +319,7 @@ out_nostopreg:
return res;
}
-static int __devexit ibwdt_remove(struct platform_device *dev)
+static int ibwdt_remove(struct platform_device *dev)
{
misc_deregister(&ibwdt_miscdev);
release_region(WDT_START, 1);
@@ -337,7 +337,7 @@ static void ibwdt_shutdown(struct platform_device *dev)
static struct platform_driver ibwdt_driver = {
.probe = ibwdt_probe,
- .remove = __devexit_p(ibwdt_remove),
+ .remove = ibwdt_remove,
.shutdown = ibwdt_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c
index 8f541b94005..e24ef6a6e06 100644
--- a/drivers/watchdog/ie6xx_wdt.c
+++ b/drivers/watchdog/ie6xx_wdt.c
@@ -225,7 +225,7 @@ static const struct file_operations ie6xx_wdt_dbg_operations = {
.release = single_release,
};
-static void __devinit ie6xx_wdt_debugfs_init(void)
+static void ie6xx_wdt_debugfs_init(void)
{
/* /sys/kernel/debug/ie6xx_wdt */
ie6xx_wdt_data.debugfs = debugfs_create_file("ie6xx_wdt",
@@ -238,7 +238,7 @@ static void ie6xx_wdt_debugfs_exit(void)
}
#else
-static void __devinit ie6xx_wdt_debugfs_init(void)
+static void ie6xx_wdt_debugfs_init(void)
{
}
@@ -247,7 +247,7 @@ static void ie6xx_wdt_debugfs_exit(void)
}
#endif
-static int __devinit ie6xx_wdt_probe(struct platform_device *pdev)
+static int ie6xx_wdt_probe(struct platform_device *pdev)
{
struct resource *res;
u8 wdtlr;
@@ -295,7 +295,7 @@ misc_register_error:
return ret;
}
-static int __devexit ie6xx_wdt_remove(struct platform_device *pdev)
+static int ie6xx_wdt_remove(struct platform_device *pdev)
{
struct resource *res;
@@ -311,7 +311,7 @@ static int __devexit ie6xx_wdt_remove(struct platform_device *pdev)
static struct platform_driver ie6xx_wdt_driver = {
.probe = ie6xx_wdt_probe,
- .remove = __devexit_p(ie6xx_wdt_remove),
+ .remove = ie6xx_wdt_remove,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c
index 978615ef899..a61408fa0c9 100644
--- a/drivers/watchdog/jz4740_wdt.c
+++ b/drivers/watchdog/jz4740_wdt.c
@@ -144,7 +144,7 @@ static const struct watchdog_ops jz4740_wdt_ops = {
.set_timeout = jz4740_wdt_set_timeout,
};
-static int __devinit jz4740_wdt_probe(struct platform_device *pdev)
+static int jz4740_wdt_probe(struct platform_device *pdev)
{
struct jz4740_wdt_drvdata *drvdata;
struct watchdog_device *jz4740_wdt;
@@ -197,7 +197,7 @@ err_out:
return ret;
}
-static int __devexit jz4740_wdt_remove(struct platform_device *pdev)
+static int jz4740_wdt_remove(struct platform_device *pdev)
{
struct jz4740_wdt_drvdata *drvdata = platform_get_drvdata(pdev);
@@ -210,7 +210,7 @@ static int __devexit jz4740_wdt_remove(struct platform_device *pdev)
static struct platform_driver jz4740_wdt_driver = {
.probe = jz4740_wdt_probe,
- .remove = __devexit_p(jz4740_wdt_remove),
+ .remove = jz4740_wdt_remove,
.driver = {
.name = "jz4740-wdt",
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index c1a4d3bf581..dce9ecffd44 100644
--- a/drivers/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -235,7 +235,7 @@ static struct miscdevice ks8695wdt_miscdev = {
.fops = &ks8695wdt_fops,
};
-static int __devinit ks8695wdt_probe(struct platform_device *pdev)
+static int ks8695wdt_probe(struct platform_device *pdev)
{
int res;
@@ -252,7 +252,7 @@ static int __devinit ks8695wdt_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit ks8695wdt_remove(struct platform_device *pdev)
+static int ks8695wdt_remove(struct platform_device *pdev)
{
int res;
@@ -290,7 +290,7 @@ static int ks8695wdt_resume(struct platform_device *pdev)
static struct platform_driver ks8695wdt_driver = {
.probe = ks8695wdt_probe,
- .remove = __devexit_p(ks8695wdt_remove),
+ .remove = ks8695wdt_remove,
.shutdown = ks8695wdt_shutdown,
.suspend = ks8695wdt_suspend,
.resume = ks8695wdt_resume,
diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c
index 2e74c3a8ee5..79fe01b4233 100644
--- a/drivers/watchdog/lantiq_wdt.c
+++ b/drivers/watchdog/lantiq_wdt.c
@@ -186,7 +186,7 @@ static struct miscdevice ltq_wdt_miscdev = {
.fops = &ltq_wdt_fops,
};
-static int __devinit
+static int
ltq_wdt_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -220,7 +220,7 @@ ltq_wdt_probe(struct platform_device *pdev)
return misc_register(&ltq_wdt_miscdev);
}
-static int __devexit
+static int
ltq_wdt_remove(struct platform_device *pdev)
{
misc_deregister(&ltq_wdt_miscdev);
@@ -236,7 +236,7 @@ MODULE_DEVICE_TABLE(of, ltq_wdt_match);
static struct platform_driver ltq_wdt_driver = {
.probe = ltq_wdt_probe,
- .remove = __devexit_p(ltq_wdt_remove),
+ .remove = ltq_wdt_remove,
.driver = {
.name = "wdt",
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c
index 8f4a74e9161..773c661723c 100644
--- a/drivers/watchdog/max63xx_wdt.c
+++ b/drivers/watchdog/max63xx_wdt.c
@@ -174,7 +174,7 @@ static struct watchdog_device max63xx_wdt_dev = {
.ops = &max63xx_wdt_ops,
};
-static int __devinit max63xx_wdt_probe(struct platform_device *pdev)
+static int max63xx_wdt_probe(struct platform_device *pdev)
{
struct resource *wdt_mem;
struct max63xx_timeout *table;
@@ -209,7 +209,7 @@ static int __devinit max63xx_wdt_probe(struct platform_device *pdev)
return watchdog_register_device(&max63xx_wdt_dev);
}
-static int __devexit max63xx_wdt_remove(struct platform_device *pdev)
+static int max63xx_wdt_remove(struct platform_device *pdev)
{
watchdog_unregister_device(&max63xx_wdt_dev);
return 0;
@@ -228,7 +228,7 @@ MODULE_DEVICE_TABLE(platform, max63xx_id_table);
static struct platform_driver max63xx_wdt_driver = {
.probe = max63xx_wdt_probe,
- .remove = __devexit_p(max63xx_wdt_remove),
+ .remove = max63xx_wdt_remove,
.id_table = max63xx_id_table,
.driver = {
.name = "max63xx_wdt",
diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c
index 37e4b52dbce..97d62ee5034 100644
--- a/drivers/watchdog/mixcomwd.c
+++ b/drivers/watchdog/mixcomwd.c
@@ -73,7 +73,7 @@
static struct {
int ioport;
int id;
-} mixcomwd_io_info[] __devinitdata = {
+} mixcomwd_io_info[] = {
/* The Mixcom cards */
{0x0d90, MIXCOM_ID},
{0x0e90, MIXCOM_ID},
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index e6a038ae8dc..da2752063bb 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -188,7 +188,7 @@ static struct miscdevice mpc8xxx_wdt_miscdev = {
};
static const struct of_device_id mpc8xxx_wdt_match[];
-static int __devinit mpc8xxx_wdt_probe(struct platform_device *ofdev)
+static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
{
int ret;
const struct of_device_id *match;
@@ -245,7 +245,7 @@ err_unmap:
return ret;
}
-static int __devexit mpc8xxx_wdt_remove(struct platform_device *ofdev)
+static int mpc8xxx_wdt_remove(struct platform_device *ofdev)
{
mpc8xxx_wdt_pr_warn("watchdog removed");
del_timer_sync(&wdt_timer);
@@ -281,7 +281,7 @@ MODULE_DEVICE_TABLE(of, mpc8xxx_wdt_match);
static struct platform_driver mpc8xxx_wdt_driver = {
.probe = mpc8xxx_wdt_probe,
- .remove = __devexit_p(mpc8xxx_wdt_remove),
+ .remove = mpc8xxx_wdt_remove,
.driver = {
.name = "mpc8xxx_wdt",
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 7c741dc987b..a84eb551ea2 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -327,7 +327,7 @@ static struct miscdevice mpcore_wdt_miscdev = {
.fops = &mpcore_wdt_fops,
};
-static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
+static int mpcore_wdt_probe(struct platform_device *pdev)
{
struct mpcore_wdt *wdt;
struct resource *res;
@@ -378,7 +378,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
+static int mpcore_wdt_remove(struct platform_device *pdev)
{
platform_set_drvdata(pdev, NULL);
@@ -415,7 +415,7 @@ MODULE_ALIAS("platform:mpcore_wdt");
static struct platform_driver mpcore_wdt_driver = {
.probe = mpcore_wdt_probe,
- .remove = __devexit_p(mpcore_wdt_remove),
+ .remove = mpcore_wdt_remove,
.suspend = mpcore_wdt_suspend,
.resume = mpcore_wdt_resume,
.shutdown = mpcore_wdt_shutdown,
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c
index c29e31d99fe..14dab6ff87a 100644
--- a/drivers/watchdog/mtx-1_wdt.c
+++ b/drivers/watchdog/mtx-1_wdt.c
@@ -204,7 +204,7 @@ static struct miscdevice mtx1_wdt_misc = {
};
-static int __devinit mtx1_wdt_probe(struct platform_device *pdev)
+static int mtx1_wdt_probe(struct platform_device *pdev)
{
int ret;
@@ -233,7 +233,7 @@ static int __devinit mtx1_wdt_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit mtx1_wdt_remove(struct platform_device *pdev)
+static int mtx1_wdt_remove(struct platform_device *pdev)
{
/* FIXME: do we need to lock this test ? */
if (mtx1_wdt_device.queue) {
@@ -248,7 +248,7 @@ static int __devexit mtx1_wdt_remove(struct platform_device *pdev)
static struct platform_driver mtx1_wdt_driver = {
.probe = mtx1_wdt_probe,
- .remove = __devexit_p(mtx1_wdt_remove),
+ .remove = mtx1_wdt_remove,
.driver.name = "mtx1-wdt",
.driver.owner = THIS_MODULE,
};
diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c
index c53d025e70d..c7fb878ca49 100644
--- a/drivers/watchdog/mv64x60_wdt.c
+++ b/drivers/watchdog/mv64x60_wdt.c
@@ -253,7 +253,7 @@ static struct miscdevice mv64x60_wdt_miscdev = {
.fops = &mv64x60_wdt_fops,
};
-static int __devinit mv64x60_wdt_probe(struct platform_device *dev)
+static int mv64x60_wdt_probe(struct platform_device *dev)
{
struct mv64x60_wdt_pdata *pdata = dev->dev.platform_data;
struct resource *r;
@@ -287,7 +287,7 @@ static int __devinit mv64x60_wdt_probe(struct platform_device *dev)
return misc_register(&mv64x60_wdt_miscdev);
}
-static int __devexit mv64x60_wdt_remove(struct platform_device *dev)
+static int mv64x60_wdt_remove(struct platform_device *dev)
{
misc_deregister(&mv64x60_wdt_miscdev);
@@ -300,7 +300,7 @@ static int __devexit mv64x60_wdt_remove(struct platform_device *dev)
static struct platform_driver mv64x60_wdt_driver = {
.probe = mv64x60_wdt_probe,
- .remove = __devexit_p(mv64x60_wdt_remove),
+ .remove = mv64x60_wdt_remove,
.driver = {
.owner = THIS_MODULE,
.name = MV64x60_WDT_NAME,
diff --git a/drivers/watchdog/nuc900_wdt.c b/drivers/watchdog/nuc900_wdt.c
index ea4c7448b75..04c45a10299 100644
--- a/drivers/watchdog/nuc900_wdt.c
+++ b/drivers/watchdog/nuc900_wdt.c
@@ -242,7 +242,7 @@ static struct miscdevice nuc900wdt_miscdev = {
.fops = &nuc900wdt_fops,
};
-static int __devinit nuc900wdt_probe(struct platform_device *pdev)
+static int nuc900wdt_probe(struct platform_device *pdev)
{
int ret = 0;
@@ -309,7 +309,7 @@ err_get:
return ret;
}
-static int __devexit nuc900wdt_remove(struct platform_device *pdev)
+static int nuc900wdt_remove(struct platform_device *pdev)
{
misc_deregister(&nuc900wdt_miscdev);
@@ -328,7 +328,7 @@ static int __devexit nuc900wdt_remove(struct platform_device *pdev)
static struct platform_driver nuc900wdt_driver = {
.probe = nuc900wdt_probe,
- .remove = __devexit_p(nuc900wdt_remove),
+ .remove = nuc900wdt_remove,
.driver = {
.name = "nuc900-wdt",
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/nv_tco.c b/drivers/watchdog/nv_tco.c
index 6bbb9efc612..59cf19eeea0 100644
--- a/drivers/watchdog/nv_tco.c
+++ b/drivers/watchdog/nv_tco.c
@@ -302,7 +302,7 @@ MODULE_DEVICE_TABLE(pci, tco_pci_tbl);
* Init & exit routines
*/
-static unsigned char __devinit nv_tco_getdevice(void)
+static unsigned char nv_tco_getdevice(void)
{
struct pci_dev *dev = NULL;
u32 val;
@@ -376,7 +376,7 @@ out:
return 0;
}
-static int __devinit nv_tco_init(struct platform_device *dev)
+static int nv_tco_init(struct platform_device *dev)
{
int ret;
@@ -423,7 +423,7 @@ unreg_region:
return ret;
}
-static void __devexit nv_tco_cleanup(void)
+static void nv_tco_cleanup(void)
{
u32 val;
@@ -445,7 +445,7 @@ static void __devexit nv_tco_cleanup(void)
release_region(tcobase, 0x10);
}
-static int __devexit nv_tco_remove(struct platform_device *dev)
+static int nv_tco_remove(struct platform_device *dev)
{
if (tcobase)
nv_tco_cleanup();
@@ -468,7 +468,7 @@ static void nv_tco_shutdown(struct platform_device *dev)
static struct platform_driver nv_tco_driver = {
.probe = nv_tco_init,
- .remove = __devexit_p(nv_tco_remove),
+ .remove = nv_tco_remove,
.shutdown = nv_tco_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c
index 294fb4e0052..2761ddb0850 100644
--- a/drivers/watchdog/of_xilinx_wdt.c
+++ b/drivers/watchdog/of_xilinx_wdt.c
@@ -289,7 +289,7 @@ static struct miscdevice xwdt_miscdev = {
.fops = &xwdt_fops,
};
-static int __devinit xwdt_probe(struct platform_device *pdev)
+static int xwdt_probe(struct platform_device *pdev)
{
int rc;
u32 *tmptr;
@@ -383,7 +383,7 @@ err_out:
return rc;
}
-static int __devexit xwdt_remove(struct platform_device *dev)
+static int xwdt_remove(struct platform_device *dev)
{
misc_deregister(&xwdt_miscdev);
iounmap(xdev.base);
@@ -393,7 +393,7 @@ static int __devexit xwdt_remove(struct platform_device *dev)
}
/* Match table for of_platform binding */
-static struct of_device_id __devinitdata xwdt_of_match[] = {
+static struct of_device_id xwdt_of_match[] = {
{ .compatible = "xlnx,xps-timebase-wdt-1.01.a", },
{},
};
@@ -401,7 +401,7 @@ MODULE_DEVICE_TABLE(of, xwdt_of_match);
static struct platform_driver xwdt_driver = {
.probe = xwdt_probe,
- .remove = __devexit_p(xwdt_remove),
+ .remove = xwdt_remove,
.driver = {
.owner = THIS_MODULE,
.name = WATCHDOG_NAME,
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index f5db18dbc0f..d8da5162f0d 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -264,7 +264,7 @@ static const struct file_operations omap_wdt_fops = {
.llseek = no_llseek,
};
-static int __devinit omap_wdt_probe(struct platform_device *pdev)
+static int omap_wdt_probe(struct platform_device *pdev)
{
struct resource *res, *mem;
struct omap_wdt_dev *wdev;
@@ -359,7 +359,7 @@ static void omap_wdt_shutdown(struct platform_device *pdev)
}
}
-static int __devexit omap_wdt_remove(struct platform_device *pdev)
+static int omap_wdt_remove(struct platform_device *pdev)
{
struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -426,7 +426,7 @@ MODULE_DEVICE_TABLE(of, omap_wdt_of_match);
static struct platform_driver omap_wdt_driver = {
.probe = omap_wdt_probe,
- .remove = __devexit_p(omap_wdt_remove),
+ .remove = omap_wdt_remove,
.shutdown = omap_wdt_shutdown,
.suspend = omap_wdt_suspend,
.resume = omap_wdt_resume,
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index c20f96b579d..0478b001b1e 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -142,7 +142,7 @@ static struct watchdog_device orion_wdt = {
.ops = &orion_wdt_ops,
};
-static int __devinit orion_wdt_probe(struct platform_device *pdev)
+static int orion_wdt_probe(struct platform_device *pdev)
{
struct resource *res;
int ret;
@@ -181,7 +181,7 @@ static int __devinit orion_wdt_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit orion_wdt_remove(struct platform_device *pdev)
+static int orion_wdt_remove(struct platform_device *pdev)
{
watchdog_unregister_device(&orion_wdt);
clk_disable_unprepare(clk);
@@ -193,7 +193,7 @@ static void orion_wdt_shutdown(struct platform_device *pdev)
orion_wdt_stop(&orion_wdt);
}
-static const struct of_device_id orion_wdt_of_match_table[] __devinitdata = {
+static const struct of_device_id orion_wdt_of_match_table[] = {
{ .compatible = "marvell,orion-wdt", },
{},
};
@@ -201,7 +201,7 @@ MODULE_DEVICE_TABLE(of, orion_wdt_of_match_table);
static struct platform_driver orion_wdt_driver = {
.probe = orion_wdt_probe,
- .remove = __devexit_p(orion_wdt_remove),
+ .remove = orion_wdt_remove,
.shutdown = orion_wdt_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c
index 75694cf24f8..33e49a7f889 100644
--- a/drivers/watchdog/pcwd.c
+++ b/drivers/watchdog/pcwd.c
@@ -801,7 +801,7 @@ static inline int get_revision(void)
* The initial rate is once per second at board start up, then twice
* per second for normal operation.
*/
-static int __devinit pcwd_isa_match(struct device *dev, unsigned int id)
+static int pcwd_isa_match(struct device *dev, unsigned int id)
{
int base_addr = pcwd_ioports[id];
int port0, last_port0; /* Reg 0, in case it's REV A */
@@ -846,7 +846,7 @@ static int __devinit pcwd_isa_match(struct device *dev, unsigned int id)
return retval;
}
-static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id)
+static int pcwd_isa_probe(struct device *dev, unsigned int id)
{
int ret;
@@ -949,7 +949,7 @@ error_request_region:
return ret;
}
-static int __devexit pcwd_isa_remove(struct device *dev, unsigned int id)
+static int pcwd_isa_remove(struct device *dev, unsigned int id)
{
if (debug >= DEBUG)
pr_debug("pcwd_isa_remove id=%d\n", id);
@@ -984,7 +984,7 @@ static void pcwd_isa_shutdown(struct device *dev, unsigned int id)
static struct isa_driver pcwd_isa_driver = {
.match = pcwd_isa_match,
.probe = pcwd_isa_probe,
- .remove = __devexit_p(pcwd_isa_remove),
+ .remove = pcwd_isa_remove,
.shutdown = pcwd_isa_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c
index ee6900da867..7890f84edf7 100644
--- a/drivers/watchdog/pcwd_pci.c
+++ b/drivers/watchdog/pcwd_pci.c
@@ -682,7 +682,7 @@ static struct notifier_block pcipcwd_notifier = {
* Init & exit routines
*/
-static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
+static int pcipcwd_card_init(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
int ret = -EIO;
@@ -785,7 +785,7 @@ err_out_disable_device:
return ret;
}
-static void __devexit pcipcwd_card_exit(struct pci_dev *pdev)
+static void pcipcwd_card_exit(struct pci_dev *pdev)
{
/* Stop the timer before we leave */
if (!nowayout)
@@ -812,7 +812,7 @@ static struct pci_driver pcipcwd_driver = {
.name = WATCHDOG_NAME,
.id_table = pcipcwd_pci_tbl,
.probe = pcipcwd_card_init,
- .remove = __devexit_p(pcipcwd_card_exit),
+ .remove = pcipcwd_card_exit,
};
module_pci_driver(pcipcwd_driver);
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 87722e12605..dcba5dab6c2 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -146,7 +146,7 @@ static struct watchdog_device pnx4008_wdd = {
.max_timeout = MAX_HEARTBEAT,
};
-static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
+static int pnx4008_wdt_probe(struct platform_device *pdev)
{
struct resource *r;
int ret = 0;
@@ -192,7 +192,7 @@ out:
return ret;
}
-static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
+static int pnx4008_wdt_remove(struct platform_device *pdev)
{
watchdog_unregister_device(&pnx4008_wdd);
@@ -217,7 +217,7 @@ static struct platform_driver platform_wdt_driver = {
.of_match_table = of_match_ptr(pnx4008_wdt_match),
},
.probe = pnx4008_wdt_probe,
- .remove = __devexit_p(pnx4008_wdt_remove),
+ .remove = pnx4008_wdt_remove,
};
module_platform_driver(platform_wdt_driver);
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c
index 547353a50eb..f78bc008cbb 100644
--- a/drivers/watchdog/rc32434_wdt.c
+++ b/drivers/watchdog/rc32434_wdt.c
@@ -260,7 +260,7 @@ static struct miscdevice rc32434_wdt_miscdev = {
.fops = &rc32434_wdt_fops,
};
-static int __devinit rc32434_wdt_probe(struct platform_device *pdev)
+static int rc32434_wdt_probe(struct platform_device *pdev)
{
int ret;
struct resource *r;
@@ -306,7 +306,7 @@ unmap:
return ret;
}
-static int __devexit rc32434_wdt_remove(struct platform_device *pdev)
+static int rc32434_wdt_remove(struct platform_device *pdev)
{
misc_deregister(&rc32434_wdt_miscdev);
iounmap(wdt_reg);
@@ -320,7 +320,7 @@ static void rc32434_wdt_shutdown(struct platform_device *pdev)
static struct platform_driver rc32434_wdt_driver = {
.probe = rc32434_wdt_probe,
- .remove = __devexit_p(rc32434_wdt_remove),
+ .remove = rc32434_wdt_remove,
.shutdown = rc32434_wdt_shutdown,
.driver = {
.name = "rc32434_wdt",
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
index 042ccc56ae2..b0f116c2fd5 100644
--- a/drivers/watchdog/rdc321x_wdt.c
+++ b/drivers/watchdog/rdc321x_wdt.c
@@ -225,7 +225,7 @@ static struct miscdevice rdc321x_wdt_misc = {
.fops = &rdc321x_wdt_fops,
};
-static int __devinit rdc321x_wdt_probe(struct platform_device *pdev)
+static int rdc321x_wdt_probe(struct platform_device *pdev)
{
int err;
struct resource *r;
@@ -272,7 +272,7 @@ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit rdc321x_wdt_remove(struct platform_device *pdev)
+static int rdc321x_wdt_remove(struct platform_device *pdev)
{
if (rdc321x_wdt_device.queue) {
rdc321x_wdt_device.queue = 0;
@@ -286,7 +286,7 @@ static int __devexit rdc321x_wdt_remove(struct platform_device *pdev)
static struct platform_driver rdc321x_wdt_driver = {
.probe = rdc321x_wdt_probe,
- .remove = __devexit_p(rdc321x_wdt_remove),
+ .remove = rdc321x_wdt_remove,
.driver = {
.owner = THIS_MODULE,
.name = "rdc321x-wdt",
diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c
index 49e1b1c2135..0040451aec1 100644
--- a/drivers/watchdog/riowd.c
+++ b/drivers/watchdog/riowd.c
@@ -174,7 +174,7 @@ static struct miscdevice riowd_miscdev = {
.fops = &riowd_fops
};
-static int __devinit riowd_probe(struct platform_device *op)
+static int riowd_probe(struct platform_device *op)
{
struct riowd *p;
int err = -EINVAL;
@@ -220,7 +220,7 @@ out:
return err;
}
-static int __devexit riowd_remove(struct platform_device *op)
+static int riowd_remove(struct platform_device *op)
{
struct riowd *p = dev_get_drvdata(&op->dev);
@@ -246,7 +246,7 @@ static struct platform_driver riowd_driver = {
.of_match_table = riowd_match,
},
.probe = riowd_probe,
- .remove = __devexit_p(riowd_remove),
+ .remove = riowd_remove,
};
module_platform_driver(riowd_driver);
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 9245b4d23bf..b0dab10fc6a 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -303,7 +303,7 @@ static inline void s3c2410wdt_cpufreq_deregister(void)
}
#endif
-static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
+static int s3c2410wdt_probe(struct platform_device *pdev)
{
struct device *dev;
unsigned int wtcon;
@@ -437,7 +437,7 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit s3c2410wdt_remove(struct platform_device *dev)
+static int s3c2410wdt_remove(struct platform_device *dev)
{
watchdog_unregister_device(&s3c2410_wdd);
@@ -508,7 +508,7 @@ MODULE_DEVICE_TABLE(of, s3c2410_wdt_match);
static struct platform_driver s3c2410wdt_driver = {
.probe = s3c2410wdt_probe,
- .remove = __devexit_p(s3c2410wdt_remove),
+ .remove = s3c2410wdt_remove,
.shutdown = s3c2410wdt_shutdown,
.suspend = s3c2410wdt_suspend,
.resume = s3c2410wdt_resume,
diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c
index 9681ada0f25..af7b136b187 100644
--- a/drivers/watchdog/sch311x_wdt.c
+++ b/drivers/watchdog/sch311x_wdt.c
@@ -356,7 +356,7 @@ static struct miscdevice sch311x_wdt_miscdev = {
* Init & exit routines
*/
-static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
+static int sch311x_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int err;
@@ -429,7 +429,7 @@ exit:
return err;
}
-static int __devexit sch311x_wdt_remove(struct platform_device *pdev)
+static int sch311x_wdt_remove(struct platform_device *pdev)
{
/* Stop the timer before we leave */
if (!nowayout)
@@ -451,7 +451,7 @@ static void sch311x_wdt_shutdown(struct platform_device *dev)
static struct platform_driver sch311x_wdt_driver = {
.probe = sch311x_wdt_probe,
- .remove = __devexit_p(sch311x_wdt_remove),
+ .remove = sch311x_wdt_remove,
.shutdown = sch311x_wdt_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
index e5b59bebcdb..6a89e4045fb 100644
--- a/drivers/watchdog/shwdt.c
+++ b/drivers/watchdog/shwdt.c
@@ -217,7 +217,7 @@ static struct watchdog_device sh_wdt_dev = {
.ops = &sh_wdt_ops,
};
-static int __devinit sh_wdt_probe(struct platform_device *pdev)
+static int sh_wdt_probe(struct platform_device *pdev)
{
struct sh_wdt *wdt;
struct resource *res;
@@ -298,7 +298,7 @@ err:
return rc;
}
-static int __devexit sh_wdt_remove(struct platform_device *pdev)
+static int sh_wdt_remove(struct platform_device *pdev)
{
struct sh_wdt *wdt = platform_get_drvdata(pdev);
@@ -324,7 +324,7 @@ static struct platform_driver sh_wdt_driver = {
},
.probe = sh_wdt_probe,
- .remove = __devexit_p(sh_wdt_remove),
+ .remove = sh_wdt_remove,
.shutdown = sh_wdt_shutdown,
};
diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
index ae5e82cb83f..b3876812ff0 100644
--- a/drivers/watchdog/sp5100_tco.c
+++ b/drivers/watchdog/sp5100_tco.c
@@ -271,7 +271,7 @@ MODULE_DEVICE_TABLE(pci, sp5100_tco_pci_tbl);
* Init & exit routines
*/
-static unsigned char __devinit sp5100_tco_setupdevice(void)
+static unsigned char sp5100_tco_setupdevice(void)
{
struct pci_dev *dev = NULL;
u32 val;
@@ -361,7 +361,7 @@ exit:
return 0;
}
-static int __devinit sp5100_tco_init(struct platform_device *dev)
+static int sp5100_tco_init(struct platform_device *dev)
{
int ret;
u32 val;
@@ -412,7 +412,7 @@ exit:
return ret;
}
-static void __devexit sp5100_tco_cleanup(void)
+static void sp5100_tco_cleanup(void)
{
/* Stop the timer before we leave */
if (!nowayout)
@@ -425,7 +425,7 @@ static void __devexit sp5100_tco_cleanup(void)
release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
}
-static int __devexit sp5100_tco_remove(struct platform_device *dev)
+static int sp5100_tco_remove(struct platform_device *dev)
{
if (tcobase)
sp5100_tco_cleanup();
@@ -439,7 +439,7 @@ static void sp5100_tco_shutdown(struct platform_device *dev)
static struct platform_driver sp5100_tco_driver = {
.probe = sp5100_tco_init,
- .remove = __devexit_p(sp5100_tco_remove),
+ .remove = sp5100_tco_remove,
.shutdown = sp5100_tco_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index e4841c36798..4552847fc7f 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -210,7 +210,7 @@ static const struct watchdog_ops wdt_ops = {
.get_timeleft = wdt_timeleft,
};
-static int __devinit
+static int
sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
{
struct sp805_wdt *wdt;
@@ -272,7 +272,7 @@ err:
return ret;
}
-static int __devexit sp805_wdt_remove(struct amba_device *adev)
+static int sp805_wdt_remove(struct amba_device *adev)
{
struct sp805_wdt *wdt = amba_get_drvdata(adev);
@@ -326,7 +326,7 @@ static struct amba_driver sp805_wdt_driver = {
},
.id_table = sp805_wdt_ids,
.probe = sp805_wdt_probe,
- .remove = __devexit_p(sp805_wdt_remove),
+ .remove = sp805_wdt_remove,
};
module_amba_driver(sp805_wdt_driver);
diff --git a/drivers/watchdog/stmp3xxx_wdt.c b/drivers/watchdog/stmp3xxx_wdt.c
index 21d96b92bfd..1f4f69728fe 100644
--- a/drivers/watchdog/stmp3xxx_wdt.c
+++ b/drivers/watchdog/stmp3xxx_wdt.c
@@ -204,7 +204,7 @@ static struct miscdevice stmp3xxx_wdt_miscdev = {
.fops = &stmp3xxx_wdt_fops,
};
-static int __devinit stmp3xxx_wdt_probe(struct platform_device *pdev)
+static int stmp3xxx_wdt_probe(struct platform_device *pdev)
{
int ret = 0;
@@ -229,7 +229,7 @@ static int __devinit stmp3xxx_wdt_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit stmp3xxx_wdt_remove(struct platform_device *pdev)
+static int stmp3xxx_wdt_remove(struct platform_device *pdev)
{
misc_deregister(&stmp3xxx_wdt_miscdev);
return 0;
@@ -269,7 +269,7 @@ static struct platform_driver platform_wdt_driver = {
.name = "stmp3xxx_wdt",
},
.probe = stmp3xxx_wdt_probe,
- .remove = __devexit_p(stmp3xxx_wdt_remove),
+ .remove = stmp3xxx_wdt_remove,
.suspend = stmp3xxx_wdt_suspend,
.resume = stmp3xxx_wdt_resume,
};
diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c
index 8df050d800e..b8a92459f10 100644
--- a/drivers/watchdog/ts72xx_wdt.c
+++ b/drivers/watchdog/ts72xx_wdt.c
@@ -390,7 +390,7 @@ static struct miscdevice ts72xx_wdt_miscdev = {
.fops = &ts72xx_wdt_fops,
};
-static __devinit int ts72xx_wdt_probe(struct platform_device *pdev)
+static int ts72xx_wdt_probe(struct platform_device *pdev)
{
struct ts72xx_wdt *wdt;
struct resource *r1, *r2;
@@ -476,7 +476,7 @@ fail:
return error;
}
-static __devexit int ts72xx_wdt_remove(struct platform_device *pdev)
+static int ts72xx_wdt_remove(struct platform_device *pdev)
{
struct ts72xx_wdt *wdt = platform_get_drvdata(pdev);
struct resource *res;
@@ -499,7 +499,7 @@ static __devexit int ts72xx_wdt_remove(struct platform_device *pdev)
static struct platform_driver ts72xx_wdt_driver = {
.probe = ts72xx_wdt_probe,
- .remove = __devexit_p(ts72xx_wdt_remove),
+ .remove = ts72xx_wdt_remove,
.driver = {
.name = "ts72xx-wdt",
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c
index 249f11305d2..9f54b1da718 100644
--- a/drivers/watchdog/twl4030_wdt.c
+++ b/drivers/watchdog/twl4030_wdt.c
@@ -170,7 +170,7 @@ static const struct file_operations twl4030_wdt_fops = {
.write = twl4030_wdt_write_fop,
};
-static int __devinit twl4030_wdt_probe(struct platform_device *pdev)
+static int twl4030_wdt_probe(struct platform_device *pdev)
{
int ret = 0;
struct twl4030_wdt *wdt;
@@ -204,7 +204,7 @@ static int __devinit twl4030_wdt_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit twl4030_wdt_remove(struct platform_device *pdev)
+static int twl4030_wdt_remove(struct platform_device *pdev)
{
struct twl4030_wdt *wdt = platform_get_drvdata(pdev);
@@ -247,7 +247,7 @@ static int twl4030_wdt_resume(struct platform_device *pdev)
static struct platform_driver twl4030_wdt_driver = {
.probe = twl4030_wdt_probe,
- .remove = __devexit_p(twl4030_wdt_remove),
+ .remove = twl4030_wdt_remove,
.suspend = twl4030_wdt_suspend,
.resume = twl4030_wdt_resume,
.driver = {
diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c
index aa50da3ccfe..1a68f760cf8 100644
--- a/drivers/watchdog/via_wdt.c
+++ b/drivers/watchdog/via_wdt.c
@@ -155,7 +155,7 @@ static struct watchdog_device wdt_dev = {
.max_timeout = WDT_TIMEOUT_MAX,
};
-static int __devinit wdt_probe(struct pci_dev *pdev,
+static int wdt_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
unsigned char conf;
@@ -229,7 +229,7 @@ err_out_disable_device:
return ret;
}
-static void __devexit wdt_remove(struct pci_dev *pdev)
+static void wdt_remove(struct pci_dev *pdev)
{
watchdog_unregister_device(&wdt_dev);
del_timer(&timer);
@@ -250,7 +250,7 @@ static struct pci_driver wdt_driver = {
.name = "via_wdt",
.id_table = wdt_pci_table,
.probe = wdt_probe,
- .remove = __devexit_p(wdt_remove),
+ .remove = wdt_remove,
};
module_pci_driver(wdt_driver);
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index e32654efdbb..36a54c0e32d 100644
--- a/drivers/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
@@ -605,7 +605,7 @@ static struct notifier_block wdtpci_notifier = {
};
-static int __devinit wdtpci_init_one(struct pci_dev *dev,
+static int wdtpci_init_one(struct pci_dev *dev,
const struct pci_device_id *ent)
{
int ret = -EIO;
@@ -705,7 +705,7 @@ out_pci:
}
-static void __devexit wdtpci_remove_one(struct pci_dev *pdev)
+static void wdtpci_remove_one(struct pci_dev *pdev)
{
/* here we assume only one device will ever have
* been picked up and registered by probe function */
@@ -736,7 +736,7 @@ static struct pci_driver wdtpci_driver = {
.name = "wdt_pci",
.id_table = wdtpci_pci_tbl,
.probe = wdtpci_init_one,
- .remove = __devexit_p(wdtpci_remove_one),
+ .remove = wdtpci_remove_one,
};
module_pci_driver(wdtpci_driver);
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index 87d66d236c3..9dcb6d08227 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -181,7 +181,7 @@ static const struct watchdog_ops wm831x_wdt_ops = {
.set_timeout = wm831x_wdt_set_timeout,
};
-static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
+static int wm831x_wdt_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *chip_pdata;
@@ -292,7 +292,7 @@ err:
return ret;
}
-static int __devexit wm831x_wdt_remove(struct platform_device *pdev)
+static int wm831x_wdt_remove(struct platform_device *pdev)
{
struct wm831x_wdt_drvdata *driver_data = dev_get_drvdata(&pdev->dev);
@@ -306,7 +306,7 @@ static int __devexit wm831x_wdt_remove(struct platform_device *pdev)
static struct platform_driver wm831x_wdt_driver = {
.probe = wm831x_wdt_probe,
- .remove = __devexit_p(wm831x_wdt_remove),
+ .remove = wm831x_wdt_remove,
.driver = {
.name = "wm831x-watchdog",
},
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c
index 3c76693447f..34d272ada23 100644
--- a/drivers/watchdog/wm8350_wdt.c
+++ b/drivers/watchdog/wm8350_wdt.c
@@ -140,7 +140,7 @@ static struct watchdog_device wm8350_wdt = {
.max_timeout = 4,
};
-static int __devinit wm8350_wdt_probe(struct platform_device *pdev)
+static int wm8350_wdt_probe(struct platform_device *pdev)
{
struct wm8350 *wm8350 = platform_get_drvdata(pdev);
@@ -158,7 +158,7 @@ static int __devinit wm8350_wdt_probe(struct platform_device *pdev)
return watchdog_register_device(&wm8350_wdt);
}
-static int __devexit wm8350_wdt_remove(struct platform_device *pdev)
+static int wm8350_wdt_remove(struct platform_device *pdev)
{
watchdog_unregister_device(&wm8350_wdt);
return 0;
@@ -166,7 +166,7 @@ static int __devexit wm8350_wdt_remove(struct platform_device *pdev)
static struct platform_driver wm8350_wdt_driver = {
.probe = wm8350_wdt_probe,
- .remove = __devexit_p(wm8350_wdt_remove),
+ .remove = wm8350_wdt_remove,
.driver = {
.name = "wm8350-wdt",
},
diff --git a/drivers/watchdog/xen_wdt.c b/drivers/watchdog/xen_wdt.c
index e4a25b51165..92ad33d0cb7 100644
--- a/drivers/watchdog/xen_wdt.c
+++ b/drivers/watchdog/xen_wdt.c
@@ -244,7 +244,7 @@ static struct miscdevice xen_wdt_miscdev = {
.fops = &xen_wdt_fops,
};
-static int __devinit xen_wdt_probe(struct platform_device *dev)
+static int xen_wdt_probe(struct platform_device *dev)
{
struct sched_watchdog wd = { .id = ~0 };
int ret = HYPERVISOR_sched_op(SCHEDOP_watchdog, &wd);
@@ -280,7 +280,7 @@ static int __devinit xen_wdt_probe(struct platform_device *dev)
return ret;
}
-static int __devexit xen_wdt_remove(struct platform_device *dev)
+static int xen_wdt_remove(struct platform_device *dev)
{
/* Stop the timer before we leave */
if (!nowayout)
@@ -315,7 +315,7 @@ static int xen_wdt_resume(struct platform_device *dev)
static struct platform_driver xen_wdt_driver = {
.probe = xen_wdt_probe,
- .remove = __devexit_p(xen_wdt_remove),
+ .remove = xen_wdt_remove,
.shutdown = xen_wdt_shutdown,
.suspend = xen_wdt_suspend,
.resume = xen_wdt_resume,
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index 8adb9cc267f..71f5c459b08 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -361,13 +361,13 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
down_write(&mm->mmap_sem);
vma = find_vma(mm, m.addr);
- ret = -EINVAL;
if (!vma ||
vma->vm_ops != &privcmd_vm_ops ||
(m.addr != vma->vm_start) ||
((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) ||
!privcmd_enforce_singleshot_mapping(vma)) {
up_write(&mm->mmap_sem);
+ ret = -EINVAL;
goto out;
}
@@ -383,12 +383,16 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
up_write(&mm->mmap_sem);
- if (state.global_error && (version == 1)) {
- /* Write back errors in second pass. */
- state.user_mfn = (xen_pfn_t *)m.arr;
- state.err = err_array;
- ret = traverse_pages(m.num, sizeof(xen_pfn_t),
- &pagelist, mmap_return_errors_v1, &state);
+ if (version == 1) {
+ if (state.global_error) {
+ /* Write back errors in second pass. */
+ state.user_mfn = (xen_pfn_t *)m.arr;
+ state.err = err_array;
+ ret = traverse_pages(m.num, sizeof(xen_pfn_t),
+ &pagelist, mmap_return_errors_v1, &state);
+ } else
+ ret = 0;
+
} else if (version == 2) {
ret = __copy_to_user(m.err, err_array, m.num * sizeof(int));
if (ret)
diff --git a/drivers/xen/xen-selfballoon.c b/drivers/xen/xen-selfballoon.c
index 7d041cb6da2..2552d3e0a70 100644
--- a/drivers/xen/xen-selfballoon.c
+++ b/drivers/xen/xen-selfballoon.c
@@ -222,7 +222,7 @@ static void selfballoon_process(struct work_struct *work)
if (xen_selfballooning_enabled) {
cur_pages = totalram_pages;
tgt_pages = cur_pages; /* default is no change */
- goal_pages = percpu_counter_read_positive(&vm_committed_as) +
+ goal_pages = vm_memory_committed() +
totalreserve_pages +
MB2PAGES(selfballoon_reserved_mb);
#ifdef CONFIG_FRONTSWAP
diff --git a/firmware/Makefile b/firmware/Makefile
index eeb14030d8a..cbb09ce9730 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -97,7 +97,6 @@ fw-shipped-$(CONFIG_TEHUTI) += tehuti/bdx.bin
fw-shipped-$(CONFIG_TIGON3) += tigon/tg3.bin tigon/tg3_tso.bin \
tigon/tg3_tso5.bin
fw-shipped-$(CONFIG_TYPHOON) += 3com/typhoon.bin
-fw-shipped-$(CONFIG_USB_DABUSB) += dabusb/firmware.fw dabusb/bitstream.bin
fw-shipped-$(CONFIG_USB_EMI26) += emi26/loader.fw emi26/firmware.fw \
emi26/bitstream.fw
fw-shipped-$(CONFIG_USB_EMI62) += emi62/loader.fw emi62/bitstream.fw \
diff --git a/firmware/dabusb/bitstream.bin.ihex b/firmware/dabusb/bitstream.bin.ihex
deleted file mode 100644
index 5021a4b1e63..00000000000
--- a/firmware/dabusb/bitstream.bin.ihex
+++ /dev/null
@@ -1,761 +0,0 @@
-:1000000000090FF00FF00FF00FF000000161000D7C
-:1000100064616275736274722E6E63640062000BB9
-:10002000733130786C76713130300063000B3139C8
-:1000300039392F30392F32340064000931303A34E5
-:10004000323A3436006500002EC0FF20175F9F5BF8
-:10005000FEFBBBB7BBBBFBBFAFEFFBDFB7FBFB7F61
-:10006000BFB7EFF2FFFBFEFFFFEFFFFEFFBFFFFF9B
-:10007000FFFFAFFFFAFFFFFFC9FFFFFFDFFFFFFF3B
-:10008000FFFFFFFFFFFFFFFFFFFFFFFBFFA3FFFBE4
-:10009000FEFFBFEFE3FEFFBFE3FEFFBF6FFBF6FF18
-:1000A000BFFF47FFFF9FEEF9FECF9FEFFBCF9BEE19
-:1000B000F8FEEF8FEEFBFE0BFFFFFFFFFFFFFFFFE2
-:1000C000FFFFBFFFFFFBFFFFBFFFFFFC17FFFFFFAF
-:1000D000FFFFFF7FFFFFFF7FFFFFFBFFFF7FFFFFB4
-:1000E000FC3FFFFFFFFFFFFFFFFFFFFBFFFFFFFFE7
-:1000F000FFFFFFFFFFFE5FFFFFFDFFFFDBFFFDFFD9
-:1001000077FFFDFFFFDFFEFDFFFFF2FFFFFFFFFFB9
-:10011000FFFDFFFFFFFDFFFFFFFFFFFFFFFFFFE111
-:100120007FFFFFFFFFFFFFFFFFFFFFFFFF3FFFFF1F
-:10013000FFFFFFFFE3FFFFFFFFFFFFFFFFFFFFBF2B
-:10014000FFFEFFFFFFFFFFFFFF67FFFFFFFFFFFF58
-:100150007FFFFFFF7FFFFFFFFFFFDFFFFFFF2FFF9F
-:10016000F3FDFF7FDEF7FDFF7FF77DFF7FDFF7BD4C
-:10017000FF7FFF1FFFEFFBFEFFBFEFFBFEFFEFFB6D
-:10018000FEFFBFEFFBFEFFFF3FFE7F9FE7F9FE7F15
-:100190009FE7FA7F9FE7F9FE7F9FE7FFFC7FBFBFE6
-:1001A000EFFBFEFFBFEFFBB7BFEFFBFEFFBFEFFBB9
-:1001B000FFE0FDF9FE7F9FE7F9FE7F9DF9FE7D9D43
-:1001C000E7F9FE7F9FEDEDFFFDFF7FDFF7FDFF7F8E
-:1001D000DFFDFF7FDFF7FDFF7FDFFF9BFFEFFBFE14
-:1001E000FBBFEFBBFEFFAFBBBEFFBFEFFBFEFFFFE2
-:1001F000B7BFDBF6BDBF6BDBF6F9BF5BD6F9BF6FF0
-:10020000DBF6FDBFFF0EFFFFFFFF5FFFF7FFFF7F86
-:10021000F7BDFFFFFFFFFFFFFFDF9FFFFFFFFEFFB9
-:10022000FFEFFEFEFFFF77FFFBFBFFFFFFFFF83F47
-:10023000FFFDFFFFFFFDFFFFFFFFFFFFFFFFFFFFD2
-:10024000FFFFFFF47FFFFEFDBEFFDFFEFFFFEF7F3E
-:10025000FFCFFFCFFFFFFFDFE6FFFF7FDFF7DD7F91
-:100260007FDFF7FF7FDFD7FDFF7FDFF7FFCDFFF2F7
-:10027000FFFF4F7FF4FFFFFFE7EFFFFFFFFFFFFFF1
-:10028000FFFFBBFFEFFFFEFFFFFFEFFFFFEFFFFBF7
-:10029000FFFFFFFFFFFFFF65EFFFFF7FFFFDEFFFAA
-:1002A000FFFFFEFFFFFFFFFFFFFFFFFECFDFFEFFB1
-:1002B000FFFBFFFFFFFFF3FFFFFFFFFFFFFFFFFF5E
-:1002C000FEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
-:1002D000FFFFFFFFFFFEBFFFFFFFE37FFFFFFFFF0B
-:1002E000FFFFEFEBFFFEBFFFEBFFFC7FFFFFFFEE2B
-:1002F000FFFFFFFFFFFFDDFFD6FFFDBFFFFBFFFEA0
-:10030000FDFFFFFDEFFFFFFFFFFFFFDEFFFFFFFF32
-:10031000FFFFBFFFFDFF7FBFFF5FDFFFFFBF77FF77
-:10032000FFFF7FD7FFFFFFFFFFC3FFFFFFFFDFEFF1
-:10033000FFFFFEFBFFFFDFBFFFFFFFFFEDFFB7FF8C
-:10034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
-:10035000FFFFFFAF7FFFFFFFFFFFFFFFFFFFFFFF7D
-:10036000FFFFFFFFFFFFFFFFDFBFDFF3FDFBFF5BD3
-:10037000FDFFBFEFF7FFFF7DFFFFFFFFF83BFFBF74
-:100380006FFFFEFFBFFFEB7DFFEFFBFEFFFFFFFFF9
-:10039000FFF27FFCFF3FDFEDFEFFFFFFFFEF5FF7A8
-:1003A000B5FFEFFFFFFFE03F9F9EFFFFEFFFDFFF87
-:1003B000BF5FBFCFF3FFFFFFFFFFFF69AF33FDFF5D
-:1003C000FBFFFFFFFFFCFF7FD9FFDFFFFFFFFFF514
-:1003D000A3DF6EDEFFFFBDFFFFFEFFFFFFFEE7FDB9
-:1003E000FFFFFFF9EFC6FEB7ADE5F9FFFFFFCFFF57
-:1003F000FFFFCDFB7FFFFFFFF9F60FDFECCF7FFFA5
-:10040000FB7FFFFFFFFDFFFEF9FD7FFF7FFFF95B35
-:10041000FF73DCFD7BDFFFFFFF7BFFFFF753D6FFA2
-:10042000FFFFFFD89FFEFFEF7FEEFFFFFFFBEDED2D
-:10043000FDFFFEFFFFFB7FFFE27FFF6FD857F7FF57
-:10044000FFFFDFFFE8FFFFFDFFFFFC7FFFE4FFFB97
-:10045000EFFBFEDFB7EDFFFEDF7FFFFE7FB7FFFFA5
-:10046000FFFF89FFFFCFF3FE7FFFEFFFFE7E7FFBE5
-:10047000FFFFFFFFFFFFFFF1FFEB7AD5BF6FDBBE92
-:10048000FDB7D8F6E5BF6FFBFEF5BD7E06FFDFF7D3
-:10049000FBF6FF3FFFDBFFFF6FFBF7FFFFFFFBFEFE
-:1004A000F7AFFFB7EDEFF7FEFFFFDFFFFEFFEFFF58
-:1004B000FFFFFFBFF7FC1FEEFBFEBDFF7F5FD7FD19
-:1004C000FB43FFFFFDFF5FFFF7FFF93FFFCFF3FDAA
-:1004D000F77EEFA7F9FE8FA7E9F37E9FFBF8FFFFFA
-:1004E0003FFD7F5FDFFDFFFF5FFFFD5FFFFF7FFDE4
-:1004F0007FFD9FFFE0FFFAF8BE6F9FE6F8BE3F9AD0
-:10050000F9BE6F9FE2F9FE6F9FF9FFF5FD7FCFDF28
-:10051000FDFD7FFFF5FFFFFFF7F5FD0FDBFFD3FFCD
-:10052000EBFAFFFFBFFFFAFFFFCBFBFEFFFFEBFA8B
-:10053000FEFFFFB7FFFFFFFFBFFFDFF5FFFFD7FFA6
-:10054000FFFFDFD7F5FF7FFE4FFFFDFF7F7FFFAD92
-:10055000EBFBFFADFFFFFFFFAFEBFBFFFC0DFFFF72
-:10056000DFD2FDFFFFFDF6FFFF7FFFFF1FFFFFFF55
-:10057000FFFB3F7DEB32FEBF2FEBFAAEBDE0FA7E14
-:10058000BFADEBFAFEBFF57FFFDEFEE3FBFFFFFF33
-:10059000DFEF4FDFFF7FDFFFF7FFFFF87FFFFFEFAA
-:1005A000FBFFFFFFEFFFFFDFEDFBDFFFBFFFFFFF05
-:1005B00081FFFFFFFF3FFFFFFFFFFEDDFEEFFDFFBF
-:1005C000FFFBFEF7FF93FDFB7EFFFE87E9FF7FB396
-:1005D0009FFEFEFFAFFDFE7E3FFE67FFFFF7FFFFC2
-:1005E000FCF7DFFDFF7FFFFF7F6DFFFFFEFFFF2FAB
-:1005F000FFBFFFFFEEFFBEFFFFFEFFEFFFFFFEFFAF
-:10060000EFFFFFFA5FFFFFFBFFFFEFFFFBFEFDFFCA
-:10061000FEFFFBFFFFFF7FFFFEBFDFFFFBFFFFF7DC
-:10062000FCFDFFFFFFFFFF7FFFFFFFFFFFF27FFFEC
-:10063000FFFFFF7FFFFFFFFFF3FFFFFFEFFBFFFF6A
-:10064000FFDFE2FFFFFBFFFFFFFFFFFFFBE7FFFD19
-:10065000FFFFFFBFFFFFFFEDEFFDFFFFDFD7F5FD62
-:100660007F5DFDFF7FDF97F4FD7B5FFFC9FFFBFE32
-:10067000FFBFFF5FFFFFF7FFEFFDFFEFFFFFFFFF94
-:10068000FFF7FFD7FD7D7FFFFFFFFFEFDFF7FDFFE8
-:10069000BBFFFF7FFFFEE3FFF9FE7FBFEFFBFEFF27
-:1006A000BFF9FEFF9FEFF9FEFFBFF3DAFF37CDF38F
-:1006B0007CDF37CDF37F37CDF37CDF37CCF37F5A48
-:1006C000BDF6FDBF6FDBF6FDBF6FDEFDBF6FDBF676
-:1006D000FDBF6FFEF16FEB7ADEB7ADEB7ADEB7AF41
-:1006E0007ADEB7ADEB7ADEB7FF7EFFFECDB36CDB13
-:1006F00036CDB36CDECDB36CDB36CDB36CDFC9BFAA
-:10070000F7BDEF7A9EA7A9EA7AB7BDEA7BDEA7BD5F
-:10071000CA728D91FFEFFBFEFFBFEFFBFEF7EFFB11
-:10072000FEFFBFEFFBFEFFFE87FFF6FDBF6FDBF6B0
-:10073000FDBF6FF6FDBF6FDBF6FDBF6FFE4FFFBF66
-:10074000EFBBEEFBBEEFBBEFBEEFBBEEFBBEEFBB06
-:10075000EFFC5FFFFFFF3FCFF3FCFF3FCFFCFF3F0E
-:10076000CFF3FCFF3FCFFD9FFEBFAFEBFAFEBFAF65
-:10077000EBFEBFAFEBFAFEBFAFEBFFE16FFDFF7F1C
-:10078000DFF7FDFF7FDFFDFF7FDFF7FDFF7FDFFF8F
-:100790007ABFFBFEDFB7EDFB7EDFB7FB7EDFB7ED99
-:1007A000FB7EDFB7FFC9FFFFBFEFFBFEFFBFEFFB25
-:1007B000FFBFEFFBFEFFBFEEFBFEBBFFFEFFBFEF89
-:1007C000FBFEFFBFEFFEFFBFEFFBFEFF3FCFFFE7EC
-:1007D000FEFFF5FD775DD735DD77D7F5CD7B5DD7AE
-:1007E000F5DD77FE27FFFF8BE2F8BE2F8BE2F9AF36
-:1007F0008BE2F8BE2F8BE2F9FE1FFF5FD7F5FD7F7E
-:100800005FD7F5FF5FD7F5FD7F5FD7F5FFFA3FFEB6
-:10081000BFAFEBFAFEBFAFEBECBFAFEBFAFEBFAF83
-:10082000EBFFFE7FFD7FFFFFFFFFFFFFFFFFFFFFEF
-:10083000FFFFFFFFFFFFFFE6FFFADFF7FDFF7FDFB0
-:10084000F7FCFFDFF7FDFF7FDFF7FDFFF5FFFFFFA1
-:10085000FFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFAC
-:10086000FF02FFFEBFABEBFABEBF23EBDE1FAFEA1A
-:10087000FAFEAFAFEBFD97FFF3FC7B1FCFF1FC7FE0
-:100880001FF1FC771FCDF1FCFF1FFE87FFAFEFFAD2
-:10089000FEFFAFEFFAFDBF2BFB7EBFBFEBFBFBFB09
-:1008A000DFFFFBF7FFFF7FF7F7FFFDDFFEFCDFFF5A
-:1008B000DFFFFDFFDABFFFBBEFFBF9FFBEEFFBFB86
-:1008C000BFEFFBFEFFBFEFFBFFF77FFDD7FFFF7F13
-:1008D000FFFFFFFEF7FFFEFFF7FFFF7FFFFFECFFCD
-:1008E000FFFEDFBFFFFBFEFFBB68AE1FAEFBFBFFE3
-:1008F000FFBFFFD5FF7FFFFFF7FEFEFFBFEF9FFDAE
-:100900007FFFCBFFFFDFFFFFBBF7BFFFFFFFFFDF77
-:10091000FFBFFBFFFFFFDE3FFFFFFFFFFFA7FFFF64
-:10092000FFFFEFFF7FFBFDFB7FFFFFFFFFCFF37CB0
-:10093000FF7F8D7FFFFFFFFFFBFFF7FBFEFDFFFF4C
-:10094000FFFFF7FDFF7FFD1FFDFFFFFFFFBFDFFF85
-:10095000FFFE5CFF6DFF7FABE7F1FFFD9FFFFFAD8B
-:10096000EB7A3F1FFFFFFEBFAFF3DEF5FF8FFBDF2C
-:10097000E67FFFDFF3FDFF7EFFFFFFFFFFFDF7F3E5
-:100980007FDFF7EFFFF63F9FDFFFFFEEFFFFEFFB9D
-:10099000FFFFF9FBFE4FBFEFBBFF69AFAFFCFF3FAF
-:1009A000DDFFFCBF8FFFFDF3BFED9EFCBF6FF5D3F6
-:1009B000DFFFDBD6F5EFFDFEFFB9FF1FD2A9AFFFCA
-:1009C000DBF7BFEF46FFFFADEB7ADFEFF7FF7FF717
-:1009D0009FEDFF7FFFADEB7FF56FFFFDFBD6F4F7DB
-:1009E000FBF97E7FFF5FC2FEBFFDFB33DFF95BFFDC
-:1009F000FFDD677DCFEFDBECFF77DDF7FDFFFFDE8F
-:100A0000A7BFD49FFFFFBFEFFEFFDFEFBBFFFFEFEE
-:100A1000EBFAFFEFBDFBFFE27FFFDFDFF7FDBFBBC0
-:100A200073F7FD7FDFDEF7BFEADBF6FFD6FFFF6679
-:100A3000FFBEFFBF6BD9F6DFFFFB7E7FB77EFFFEF9
-:100A4000FFCDFFFE7FFFFCFD3FFBFBF7FFFFFBF64B
-:100A50007DFE7FFFFCFFB9FFF9FAFEBFAF5BD6ED6D
-:100A6000AD7BF6F9BFEFF8FAFEBFFEE6FFFFF7FD3C
-:100A7000FF7FBFEFF3FFFF6FF7FEFFFFF7FDFEF70E
-:100A8000EFFFFBEFFB7EDEFEFFBFFFFEFFFFFBFF86
-:100A9000FFEFFB6FFC1FFEE7FFFFFFEFFFD3B4BBD1
-:100AA000FFFFFDBF6FE3FEFFBFFCBFF7CFF7FDFF0A
-:100AB0002FDFABEAFFDFE7EA9AAFEFFBFEFFF53F80
-:100AC000FD7EFFD7F5FBFFFDF7FF7FFEF7FDFFD7AC
-:100AD000FFD77FEE7FFA79FE2F8BE6F9FE3F9EF976
-:100AE000BE2F0BE7F9FE2F9FFDFFFE7D7F5FD7FF37
-:100AF000FF7FFFFDFF7F5F97FFFD7F5FFFE3FFFF4E
-:100B0000FAFEBFAFFBFBFFFFCFEBFEBFAFFFFAFE6E
-:100B1000BFFF87FFFFF5FFFFFFFFFDFF7FFFFFFF29
-:100B2000FBFFFFF5FFFFFE0FFFFDEBFFFFF7FFEF02
-:100B30007BDFFEFFFFDFF7FDEB7FDFFF5FFFFFFFE8
-:100B4000FFFDBFFF7EFABFC7DBF7BD3FFBFFF6FF30
-:100B5000FAAFFFEBFAFE3F2FEAFA3EADC9BAF6ADA7
-:100B6000AFEBFAF6BFFE7FFFFFFDFFF17F3FCFF156
-:100B7000EFFF7FFFBCDFDFF7DDFFE07FFFFFFEFF62
-:100B8000FAECBB7F5FFFFBECFFEFB7FFF7FFFFB5B2
-:100B9000FFFF7FFFFFFFEEDF5FDFDEFFAEE777FFE8
-:100BA000FFDFF7FFE3FFFABBFEFFAFFDFBFEBFABCE
-:100BB000F9FEFFBF7FBFFEBDFED7FF9FFDFFBEEF6B
-:100BC000FFEEFDBB5BEFFF7FEFFFEFFF7FFF4FFF10
-:100BD000EFFBBCFCFFFFFFFEFEFDFAFEFBFFFDF39B
-:100BE000FBFFF85FFFFFD7F5FDDFEFFFF3DC5FCE24
-:100BF000F5BDFFFFD7FFFFF93FFFDFF7FFFEFFFD6A
-:100C0000FFFBFFF7B97DFEDFFFFFFFFFF97FFFFE70
-:100C1000FFFF7FFFFEFFFFF7F6FFBFF1F8FFFFFFCB
-:100C2000FFE0FFFFFFFFF9FFFFFFFFFFEFEFFFFF19
-:100C30009BFB7FFFFFFFC1FFDFFF3F5FD7BFEFBB26
-:100C4000DEEEFF7FDFFFFEF57FDFFF99FFFFFAFF9C
-:100C5000BFFDEB7AFFB7FEFEFFFFEFFFFFFDBFFF1B
-:100C600097FFFDF7FF7FF7FFFFFD5FFEF3F9DFDF83
-:100C7000FFFFFCFFFF83FFFFFEFF9EECFBEEFF9FED
-:100C8000BFEFFFFEED7BFFFFFFF15AFFFFFDFF7C93
-:100C9000693BDFFF7F1FDFFFFDBAFFFFFBFF5BBD8F
-:100CA000FFFFFFFFD7B6EDE9FFD6BD6F5FFBFFEF9C
-:100CB000FF5FFEF66FFFFFFFFFF7EB7ADFFF9F7F1F
-:100CC0007FFFB7FFFFFEDFFF6CFFFBFFBB6FEBFE9D
-:100CD000CCF7A5FA5CF575BBB7DFFE6F5FC5BFFD4E
-:100CE0007BFEFF95E729CF4FF591EE6BDFEFFD54CB
-:100CF000F5BDB1FFEFEEFBBEBFAFFEDEBD6FDAF2BA
-:100D0000FFAFBEFFFFFD7EA7FFF7FFBFEF7BF6FD46
-:100D1000BD4AF28585BF5BFEB5FDFAFF4FFFFEDFE2
-:100D2000FFEDFFBFFFBF7FFEFFB76DFFF7BFBFEF58
-:100D3000FD1FFFFE7DFF67FFFFFF3F7FFEBFFFE759
-:100D4000DFE7FFEF6BFC1FFFBFEFFBFEDEBFAFFA7D
-:100D5000FFB6EFF9FEFF8FEFDBEFAB6FFBFEFFFFA0
-:100D6000EFFDFF7FFFFFDEFFFFEFFFFFFF3FFF6CA9
-:100D7000FFBFFBFFFEFFFBFEDFFFFFEFFFFFBFFF3D
-:100D8000FFFEFBFFD57FFFFFEFFBFFFFBFEF43B58C
-:100D9000FD6FCFD6BE3F7FDBFEC3FFFDFFAFEBFB9A
-:100DA000FCFF3EEFE8FABDCDAAFEFE7DCFFFB7FF08
-:100DB000F7FFFFFFFDFF75CD52D7FDFBF7DDFBEF22
-:100DC000EBFFFF4FFFBF9FE7F9FC7F8BC3F9AF8FAE
-:100DD000E7E9BE7F9FE6F9FC5FFFFFF7FDFF7A5F63
-:100DE000D7EDFFFFD7FFDD7FE7FFFCFFFC3FFFFFF5
-:100DF000FFFBFFFEBFAFFFFDFFEFFFEBFFFFFFFFBE
-:100E0000FFF77FFF7FDFFFFDFD7FFEF7FD7FDFFF49
-:100E1000FDFFFFDFFBFFEEFFFBFFF7FDFF7ADFF5D6
-:100E2000FDFADFF7FCFF7FDFBFEDFFC9FFDFFFBF8C
-:100E30002FFBFFBCADFFF7FFFFEFD3FF7DBF6FFFC1
-:100E4000FAFFFEBFAEEAFABEADA5EBCEBFA7EB5AE6
-:100E5000DEBDAF6BFD57FFFFF47F1F7FFDFF7F36C9
-:100E6000F0DF79FFFFFFF7FDBFFF87FFFBF3FCFF1C
-:100E7000FFFFFF7EFFBFDFFFFFFFFFFFFDBFF89F0C
-:100E8000FFFFFFFFBFFFFFFDF7FCBDFFFEFFFFFF02
-:100E9000FFFFFBF9BFFFFFEBE2FEFFBFEFA9BA2F99
-:100EA000EBF9FE77DFF7FFFFF97FFFFF7FEFD7FF5B
-:100EB000FDFFFBF5FFBF6FDFFFFFFDFFFFF0FFFF53
-:100EC000FF3FCFFFBAEE9BBFEED7FECDEFFFDFBFF8
-:100ED000FFFFC5FFFFFD7F4FFDF6D9FF4FD6FDBFDA
-:100EE0006EFFFFF47FFF7F8BFFFFFFFFF7FFF9FE31
-:100EF00037FFD9FBF5AFFDFFFFFBFFFF07FFFFFF4C
-:100F0000FBF7FFFDFF7CFA7E4FFCDF1DC7FFFFFFF5
-:100F1000FFAEFFFFFFFFFDFBFFFFFEFEFCFF7F7F3D
-:100F2000BFEFFEFFFFFF5FFDFFFFFFFD6F5AD77BA7
-:100F3000BE5FFE39FFF7FFF7FDFEAA1FFFFFFFFFB1
-:100F4000FEFEABAFFDFEBFFFF7FF7FFE8FE3FBEEC4
-:100F50007FFFFFFFFFEBFBFFFDBFEFDFFFFFFFFFAB
-:100F6000FFFFFFFBE43FFFDFFFFFFFFFF3EFBBFBF4
-:100F7000BFEFBBFFD7BFFFFFFF29AFF7FFFFFBFFAF
-:100F8000FBE6FF0FFB3FDF0FFFAFFFFFFFF5C3DF08
-:100F90005FFFFFFFFE6BCABEBCFF9FF2BFFFFEFA02
-:100FA000FFFFEF16FFFFFFFFFFFCDF97FD79FF3725
-:100FB000E77FFFFFB5FFFFF62FFFFDFBFEFFFFFD05
-:100FC0005F575FFFDB52DFFFFDBFFFFFFCDBFF7BF7
-:100FD000B5FD7FFF719C6EFFF635A59BFFFFFDFF02
-:100FE000FFDB9E7FFEEFFBFFFFBDEFFFDEB7F94BA0
-:100FF000FFF5EFFFFFFFE87EFFEADFF7FFFD695B2C
-:10100000FC9FEF78D6FFEBEFFFFFFFE8FFFFEDFF60
-:10101000FFFFFFE3F9F6BFFFFFFEDFFF7FFFFFFFEC
-:10102000D1FFFFE7FFFFFFFFE7F9FFBF7FD9FFFD1C
-:10103000FE7FFFFEFFF9FFFBD6DFBFEF5BD6FFBFF2
-:10104000FBF6FFBFEFF8F6DDBEFE16FFBFEFFFFEBB
-:10105000FFBFEFFFFFFF6FFBFFFFFF6FF3FFF7EF38
-:10106000FBFFBFFFEFFEFFBFFFFFFFBEBFFFEFFFB6
-:101070007FEFFFFD17FB7BFFFFFD7FDBF6F47FFAC1
-:10108000FEF5BFEBE3F7FFFFE9BFFFAFF7FDF37E30
-:101090008FA3EAFFCBF3EEFFBFEFF7F9FFFE7FFF71
-:1010A000FFFFFFF5FBF6FFF52FFEFBD7BFFFBEDF0F
-:1010B0009FFFF0FFFFF9FE7F8FA3F8FE6F9FF9F609
-:1010C0002F9FE7F9FE2F9FE1FFFFFF7FDFF7F5FD81
-:1010D0007F7FF5FF9F5FFBFEFF7FFFFFCBFFFFFBE7
-:1010E000FEFFBFAFFBFEFFDFFEFEBFF7FFFFFFFF10
-:1010F000FFC7FFFFFDFF7FDDF7FDFFFFD7FFFD7F90
-:10110000FFFBFDFFFFFEEF7FFDEFFBFEFBFDFF7F23
-:10111000DFFDFF7ADFF7FDFFFFFFFF1FFFFFD3F7C4
-:10112000FFFF6FDBFFFFEFCBF4FFFFFFFFFFFFFED3
-:1011300029FFE8DA769FAF6ADAFE35EBDAD6BFAB85
-:10114000EB7ADEBFD77FFFFEFFBFEFFDDF77BFFD8E
-:1011500037EFFFEFFF3FFFFFFFFE7FFFFFFFF77E51
-:10116000DFFFFFFFFAB77FFFFFFEFFFFFFFF89FFF3
-:10117000FFFFFFFFFFFFFFFFFF9FFBFFFFFFE7FFFB
-:10118000FFFFFFAAFFABFBFAEFBFFFDFFA7BB9FE61
-:10119000FEFFFDFFF7FE3FFFB7FFF7EEFF7FEFFF1C
-:1011A000FF7FFF1FFBFFBFFBFEFFBDFFFF2FFFBF4A
-:1011B000FF7FDFFAFFFFFCEEF5F3BEFB0FEFF3BEA0
-:1011C000EFFC5FFF5AFFF7DFFFFFFED5FC5FFBF28E
-:1011D000FFFF2FBBF3FFFFBFFFEFFFEFFFFFFFFF9F
-:1011E000BFFFFFFD7BFFDFB9FFFBFFD87FFFFFFFE6
-:1011F000FBFFFC7F1FBFE0DFF7EFFFFD7FFEDFFFA0
-:10120000E0FFFFFDEFFBFFFEF7DFFFEB5FFFF7FF08
-:10121000FFFFFFBFFFFDFFFDFFFFFFF7FDFF3BDC13
-:10122000FD6D7B5F57F5FD7F5FFFB1FFEBFFFFFFBC
-:10123000FBFBFEFFBFFBBEFFBFEFFBFEFFAFFEF7FA
-:10124000DFDFFFFFFF7FCFF3F8FFD7FBFF5FBFF7C5
-:10125000FBFF7FFE23FFFFFE7FF3FFFBFEFFFFF39D
-:10126000FFFFF5F9FF3FFFFFF09AFFBE7FFFFCF99C
-:10127000FFFDAFEBFEBFFFCFF3FE7FFFFF5BBDFFC8
-:10128000BCEBFFD7D4AFAFFDFFCFF7FDFF7FDFF79C
-:10129000FDFEFF6FFFFBFFFFFFFD7F5EFDBFDBF687
-:1012A000FDBF6FFBEEFDFF7AFFFAFBFF3FFBB75F71
-:1012B000D6F71F71DC771DC731DC77DFF9BFF55B2F
-:1012C000F4D79DAEFFBFFDBFDBF6FDBF6FDBF6FEC3
-:1012D0003D81FFEBFEFEFEFFEB7ADF7D777DF5794A
-:1012E000DF57DDF57D7EE6FFD63FBF7FFFD4F53FBC
-:1012F000BFFBBEEFB3EEFB9EEFBBFE8BFFFEDFB787
-:10130000EDFFF7FDFEFFEFBBEEFFBEEFBBEEEBFC2C
-:101310001FFFFFFDFFE7FFF7FDFFEFFEFFBFEFFB46
-:10132000FEFFBFEBFA1FFFB7EF5BFEFFAFEBDDE7A2
-:10133000DE779DE779DE779DBFE66FFFFEFFBFEFAB
-:10134000FBFEFDBF6FF6FDBF6FDBF6FDBFFF7EFF4F
-:10135000FFFBFEFEFFEFFBFDEF7EF7BDEF7BDEF751
-:10136000BDEFFFD5FFBFFFEFFEFFFC3F0FE7FE7FA6
-:101370009FE7F9FE7F9FE7FEF3FFFEDFADDF67EE3D
-:10138000FBBFEFFEFFBFEFFBFEFFBFEFFF23FFFF43
-:10139000FFFF7FFFF3BCDBFEFBFFFBBEF7FBFF7F26
-:1013A000DFFFCFFBFF9FE3F9BE3F8FE779FF9DE7AC
-:1013B000F9FE7F9FE7F9FE5FFFCFF7FFFFFFDFF743
-:1013C000FE7FE7F9FE7FFFFFFBFEFFFFBFFFBFBF12
-:1013D000FFFEFFBFEFFFFDFFFFFFFFFFFFF7FDFF7A
-:1013E000FF3FFFBFFFF7FFFF7FDFFFFFFFFFFFFFB5
-:1013F000FFFFFFFFFFE8EFFF5FF7BFF9FEDFB7FD7D
-:10140000FFDFF7FDFF7FDFF7FDFFDDFFF2FFBFFF2F
-:10141000FFBFFFFF2FF2FFBF2F7BD2F7BF2FFFBB16
-:10142000FFEE8FAFEBFAFE3FA769CE8FA4EAFAEE8C
-:10143000B7AEEBFDC7FFF7F7FFFFFFFFFF7F3EF300
-:1014400074FF3F4FFFE7FF3FFEA7FFFFDFF7B7FF48
-:10145000F7FFBAEF37EBFBFEBFFBFEF3FFF9DFFF51
-:10146000BFFFFFFFBFFFFFFFFDDFFFFDFFFFFBFE35
-:10147000FDFFFBBFFE3FEDFFDFBE3DA7FBFA3FE6F2
-:10148000E1FEFE3FEFE3DFF57FFEFF7EFFFFFFFFA4
-:10149000EF6FF6FF7DEFD7DEFF7DEFFFF2FFFFFF7F
-:1014A000FFFFFF7BDEFBE6EEEF376EF37EEB37EF01
-:1014B000FFC1FFFEFFF7EFFFFFFFBF3FD2DFBF2FF0
-:1014C0007BE2FFFE3BBDDBFFFEFFFFFFFFFFEFFE0A
-:1014D000FFFBFFFFBFFFFBDFFFBFFFB7FFFFBFEF5C
-:1014E000FFFFFFFFFFFF0FFF7FFF1FEFF1FDFFF685
-:1014F000AFFFFFFFFFFFEFFFFFFFFE9FFFFFFF7745
-:10150000EFF7FBFFFE5FFFFFBFCFFBF7DDF7F5FF58
-:101510005FD5F5FD7F5FD7F5FFFB0FFFFFA9EA7AE7
-:10152000FFAF8FFEDFAFEFFBFEFFBFEFFBDFE55F3F
-:10153000FFFFFFFFFFBD57FFFF6F77BFF7FBFF7F89
-:10154000BFF7FFFCBFFF9FFFFFEFFFFEFFFFFF1F87
-:10155000CFFFFCFFFFFFFFFB65AFF37CFF3FDFFF2B
-:10156000FDE9FE7FE7FFFE7FFFFFFFFFFDE3DFFBFF
-:10157000DBF6FDEF5BFBFFDFFCFF3FDFF3FDFF7FF3
-:10158000DFEF66FFDFADEB7ADEF7F7E7D9FD9F67A8
-:10159000D9F67D9FE7DFF547FD655BD6F4FEFFEFEB
-:1015A000FF6DF6DDB76DDB76DCB77DFA9BF66D9DE2
-:1015B0006759DFF7DDFFEBFEBFAFEBFAFEBFAFE32E
-:1015C000D19FFFBDBFEFFEF7BFBFF7D77FDDF79D10
-:1015D000DF7FDFF7FFE07FFDC1DFF7FDC77F7FFB28
-:1015E000FFBBECFB3EFFBFECFBFFD87FBF6CFFBE39
-:1015F000FFBFEDFFEFFEFBBFEFFBFEFFBFEEFFC542
-:10160000FFAF6FFFFCFD3FE7FFFEFFEFFBFEFFBFFD
-:10161000EFFBFEBF89FEFABAFEBFAFFBF6F5D97D40
-:101620009765D9745D9765D3FED6FFBFF7FDFF7F41
-:10163000BFCFFBFEFFEFFBFEFFBFEFFBFFF68FFB15
-:10164000FFEFFB7EDBFEFFBEEFEEFBBEEFBBEEFB74
-:10165000BEFFFFDFFF43FFFFFBEF5FB7FE7FE7F952
-:10166000FE7F9FE7F9FE7FF9BFFEAF77FDFF2FAF4B
-:10167000A7FEFFEFFBFEFFBFEFFBFEFFF17FEFDFFB
-:10168000FF97F5EFFFDFFFFFBFFFBFFFFFFEFFFF8D
-:10169000FFE0FFFFF9FE2F8BE3F8BE779FF9DA77C3
-:1016A0009DE779DE779FDDFFFDFD7F5FD7FDFF7F43
-:1016B000E7FE7F97E7FBFEFFBFEFFFABFFEFFAFE12
-:1016C000BFAFFFFAFFFFDFFFFBFFF7FDFF7FDFFF8D
-:1016D00067FFF7F5FFFFFFDFFDFFFFFFFFFFFFFFE6
-:1016E000FFFFFFFFFFEFFFBDEBFFFFF7ADEBFFDFFE
-:1016F000FDFF3FDFF7FDFF7FDFFF5FFFF7FFFFFD30
-:10170000BFFFCBF4FF7FD3F7FD3F7FD3F7FFFC3F55
-:10171000FFEAFABEAFABEBBAF4956B52D4AD2F4AE9
-:10172000D2F6BFD27FF73FFFFFF37FFFFFF7FFBA8D
-:10173000DFFBFDFFBFFFFBFFF87FEAFFFEFEDFFFE1
-:10174000F7FF7FBBFFFFBFDFFBFFFFBFFFB17FFFE7
-:10175000FBEFFFFFFFFFFFBFCFFEFFFFEFFFF7FF36
-:10176000FFFFF1FF69BEFABFAFE2FFFEFDAFF3FE80
-:10177000FFBFEFFBFCFFFF07FD95DBDF7FDFAFFF68
-:10178000F7AF36FEBF65EBF6FE9F6FFE07FFCFFF9C
-:10179000F8FEFFCFFFF6FAE7FBFEFFBBEDF9FFFF18
-:1017A000FF5FFFFFFF75FFEF7EFDE0E85ED3E5F929
-:1017B0003E5FD7F7FFFA2FFBFFFFFFFFFEFFFF7F24
-:1017C0007FD7F57D5F57D5F5EFFFF37FFC7FFFC730
-:1017D000F1FFFF1FCFB0FF3FCFF3FCFF3FCEFFE491
-:1017E000FFDF7FFEF7BBFFFFDFEFEEFFBFEFFBFE8C
-:1017F000BFBFEFFFD1FFFFFFFDFBFFFDFFFB9FE939
-:10180000FE7F9FE7F9FE7FBFFFB3FFFFF7FFFFAF4C
-:10181000F7FFB63FEBFAFEBFAFEBFAFEBFFEA7FF46
-:10182000FFFFFFFFF7FFFFFFFE9FF7F9FF7F9FE737
-:10183000FFFFFEAF6FFFFFFF9FFFDFFF7D5FDDFF5D
-:10184000FBBFE7BBFFFBDF6D5F7EFFFFFFFFFFFF1F
-:10185000EBF7FFE7EFF7FFFF7FFFF7FFFC8FFFEFEF
-:10186000FDFEFFBEF4F27DD7CFFF3FFFFFFFFFFF7E
-:10187000FFCF6BFFBF3FFBF2FC7FEBFF9FFAFFFF49
-:101880003FFFF3FFFFFD70F7FFFFBFFFFBD7FEF544
-:1018900077FF15DD77FDFF7FDFF7FBCDBFFFFDFF96
-:1018A000FFDF37CDF9ECFEEFBBF4FB3F4FB3FFFD9D
-:1018B000CBFFE97E549FE54BB7FFDD7DC771DD7738
-:1018C0005DD775CD7FD6FFD3F6F93F6D95AF7FFE1F
-:1018D000FFEFFBFEFFBFEFFBFEF6C7FFAD7BCAFFCE
-:1018E000BFBFEFFDE3DFB7EDFB7EDF37EDE3FBDFEF
-:1018F000FF525C15FDCF7FDFFEEFEFFBFEFFBFEC7D
-:101900007BFEFFFE3E7FDAF7FDFF7FFFFFFBEFBBB5
-:101910006FFBFEFFBFEFFBFFF77DFFD8FFFDBF7F33
-:10192000FBFFFF9FFBFE7F9FE7F9FE7F9FEA7FF6AD
-:10193000BFBD6A5AF6E5BF775F6DDD775DD775DDB0
-:1019400077FFA5BFCFFBFFFFBFCFFBFDFFBFF3FEC0
-:10195000FFBFEFFBFEFFFDABFFBFBFFFFBFF7FEF56
-:10196000FFBEFBEEFBBEEFBBEEFBBFFFB5FFD0BC87
-:10197000FD2F4BF7FFFF9FF9FE7F9FE7F9FE7F9F4B
-:10198000FA8FFDABFADABFAFB3FDFFBFFBFEFFBFBF
-:10199000EFFBFEF7BFFF9FFF77F7BDFD77DFFF7E11
-:1019A000DFEDBBFEFFBEEFFBFEFFFA3FFFBE6F8F1A
-:1019B000E6F9FE7F9FC7FE7F9FE7F9FE7F9FE7FB6B
-:1019C0007FFF7FCFFFFDFFFFDFFBAFBFEFFFFEFF1E
-:1019D0009FEFFBFFFCFFFBFEFFFFFFFFFEFFFFF79C
-:1019E000FFFFFFFFFFFFFFFFFFF5FFFFFF3FDFF7F9
-:1019F000FFFF7FEFFEFFBFFFFBFFFFBFEFFFB37FE8
-:101A0000FF7B5EF7FDFF7B7FF7FF7FDFF7FDFF7F4B
-:101A1000DFF7FF17FFFFFF7FFFFFDDF6FCBFCBF215
-:101A2000BCBF2FCBF2FCBFFE8FFFFA7EBFA7EBDA65
-:101A3000FCBFAF7AFEBFAFEAFAFEBFAFF4DFFEFF36
-:101A4000F33C7F3EFFCFF8BF8FE3F8FE3F8FE7E820
-:101A5000FFFC9FFFFFCFEBB3E7FB7BF3FEFFCFDB8A
-:101A6000FBFBBF6F6FDFEC7FFFFFF7FDFDFFFFFFAD
-:101A7000FFB2BFFFDEFDBDEFFBF6DFEAE7DBFEBB3B
-:101A8000FFEBFBBF9F8FE8FE3F8FA3F8FE3F8FFF6A
-:101A9000F87EFDFD7FFFFBCDFFFDFF5FEFFDFFFF4C
-:101AA000DFF7FDFFBE90FFFFEEFF3FBFF3BBFEB7CA
-:101AB000ABFAFEAFADEAFADEABFF63FFFEF2FFB3B7
-:101AC000FFDFEE7DFF03F1F43F1FC3F1EC7FFE6FFC
-:101AD000FFFBFBFF9FFFBFFF7B5FFDFFDFF7FDFD10
-:101AE0007F7FDFFECFFBFFFFAFFBFF1FEFA5FDBF3B
-:101AF000DFFB7DFFBFDFFBFFFD3BFFFFFFFFFFFDC8
-:101B0000AFF3FFFB7FBFD7FBBF7FBBF7FFF87FFFC4
-:101B1000FA5FD7FFDF7FEFFFFF7FDBF7FDFF7FDFA0
-:101B2000B7FBECFFFFF7BFEFFDFCFBFFEFF0FE3F65
-:101B30008FE3F8FE3F8FEF8DFFFFEF7FBFFFFBFFCF
-:101B4000DBBFFFFFFFFFFFFFFFFFFFEFD8FF2E7F91
-:101B5000BEEFFE6EFFBFF9FFFFF3FFFFFFFFFFFFCA
-:101B6000FC66BE47F37FDFFE879FFFFFFFFFE7FFB7
-:101B7000FFFFFFFFFFD66F7CFB4FD2FFFD2BFEFF69
-:101B8000FFFD5FD7D5F57DFFFFFFBF9BFFFFDFB7F1
-:101B9000FFFFDFFF3FCFFE7FBFEFFBFCFF3FFFD923
-:101BA000BFFE97EC8FB7FE9B7DFDB7DD771DC7713C
-:101BB000DD775DD7F36FFD3F73DDAFFD7AFFFFAFDC
-:101BC000FEFDBFEFFBFEFFBFEF667FFFFFBFBFFF66
-:101BD000FBFFF7DFFDFB7DDFB7CDF37C5F3F913F80
-:101BE000FF3DEF7BFFFCFFCAEFFEFFBDEFFB1EE7F3
-:101BF000BBEC7FB3FFFD9FFFFFFEFFFF7FBFFBFE40
-:101C0000FFBFEFFBEEFBBFDF67FFFFBFEFDBFFBCFC
-:101C1000FE7FFBFF9FEFF9FE7F9FE7F9FE87FFEE58
-:101C2000FBBEE5BFEFF9D765F7DDE77DDF775DD771
-:101C30007FF89BFEFFBFEFFBFFFFBFEFFBFF7FCFF8
-:101C4000F3FCFFBFEFFFDB3FEFFBFEFFDFFFFEFB21
-:101C5000BBEFBFEFBBEEFBBEEFBBFFFC7FFD3B5B13
-:101C6000D6E5FD4FC3FBFFBFEFFBFEFFBFEFFBFF62
-:101C7000B4FFFABC8FB2E9D22ECFFBFFBFEFFBFE61
-:101C8000FFBFEFFBFFECFFFDFD7FDFF7E4DF5FFF52
-:101C9000FFFBFFFFFFFFFFFFFFFFC3FFEFE6F8FEC5
-:101CA0003F8B83F9FE7FE7F9FE7F9FE7F9FE7F1701
-:101CB000FDFFFFFF7F5FF72CFFFFFFFE7FFFE7F9D0
-:101CC000FE7F9FFE2FFFFFEFFFFEBFEFADFFFF7F09
-:101CD000FFFFFFFFFFFFFFFFFEDFFFDFFFFDFD7FD9
-:101CE000DFF7FFFFFFFFFFFFFFFFFFFFFFFA3FFEF2
-:101CF000F7FDEF7AFFB1BDFF7FF7FDFF7FDFF7FD57
-:101D0000FF7FF327FFDFFFDDFFFC9BFFCBFCBF2F37
-:101D1000CBF2FCBF2FC9FFDEFFDFAFEBDAFEBBAFBC
-:101D2000EBF8F7AFE8FAFEBFAFEBF2FFFDFFFFEF16
-:101D3000BDD7BFFFFFDE8FB8DE378DA378DA3F8FC8
-:101D4000FFA1FFFFFBFBFFFFFFFFA7BDFB76FDBF72
-:101D5000EFDBFEBBBFFE277FFFFEFEFDF5FFEFF5CD
-:101D6000DF1FE7FDFF7FDFF7FDFFFFCDFDAEFFFAD1
-:101D70003E3FABFDF87E8FE3F8FE3E8FE3F8FFFEBB
-:101D80001FEFDFBFFEDEDFD9FFDFBCFFFF7FFFEF0E
-:101D9000FD7FDFF7F93FFEFFFF6FFEDEBFF7EDEAE5
-:101DA000FD8F83F8EA3F8FEFFFF47FFFEFEF7BF3C8
-:101DB000F15FFFFFF13B7FDFF7FDFFFFFFFFE0FF7C
-:101DC000FFFFF7FF6FFF7FFFFFF7DEF7BFEFFBF7C8
-:101DD000FDFFFFF5FAFFFFFBE7FFF3F87FF3DFFFFF
-:101DE000FFFFFFFFFFFF1FEFBBFFFFFFFFFFFFFD39
-:101DF000FF7FFF9FFFFFFFFFFFFFFFCFFF37FFFFCB
-:101E00007FDF775DE7FCFFBFF7F5FBFFFFD7F5FB53
-:101E1000FFFF45FD7FEAFDBEBFDFF7FFFFDBFBFEF7
-:101E2000FFBFEFFFFFFFFB5F7FFFFEFFFFFFFFFF37
-:101E3000FFFEFFEFFDFF7FDFFFEFFBF80FF3FFF982
-:101E40002EFBFEFCF3EFFFFFBFFFFBE7FFFE7EFF75
-:101E5000C06BCFFF34DFF1FDFFEFFFFFFFDFF7FDCA
-:101E6000CF7F9CFDFD6CF7FFF6FDEB2B9FFFFCFE8B
-:101E70007EFFFFFFFFD7F3F7FFFBE1BFFFEB7ADE4B
-:101E8000D7FBFFF9FEFFFFF3DE7FFDE77FFFFDBB22
-:101E9000FFFF7ECCF6AF5F7FFEF47DF7FDBB6EDB10
-:101EA000B7FFF7DF66FFFFF73DCFDEBDFFFFDEDBED
-:101EB0008DF77EDFB7EF7FFFF687FFFFEFFEDEBF18
-:101EC000FFFFFFBBEFFDFF7BDEF73FFFBFFBDBFF4D
-:101ED000F2B6FDBD7FE7FFFFFF6FF7FFFFFFFE7765
-:101EE000FFBFF8AFFFDFBFFFBF7FFBFFFFFFDBFEE2
-:101EF000FFBFFFFAFFFDFFF67FFF9FFFFF3FEFF8F9
-:101F0000EE7E9FBAFEBF8FEFFEFEF9FFFA7FFE7EE8
-:101F1000BFAFFB96FD9FEF5E65BEEF5BB6FFBEE316
-:101F2000FFB5BFFFFDFF7FFFEFDFFEFFBFFBFEFF43
-:101F3000BFCFFFFFFFFD9BFFFEFBFEDFFF7FFFF735
-:101F4000FEFFDFFBFBFEFFFFFFFFFFB7FEFAFFAB6D
-:101F5000EFFFFDB57B7FFBF7FDFFFFDDFFEF8FFFA1
-:101F60002FFFFB7CFF3FDF73EBFE3FFFEFFBFEFF2E
-:101F7000EFFDFFBFFD0FFFFFFFF5F9FF7FD7FDFF6F
-:101F8000DFFFF7FBFF7FBFFFFFF09FFFFE7F8BE3CD
-:101F9000F9DE279BE6BE7F9BC3F8DE7F9DE7FE7FD1
-:101FA000FFFF5FD7FFFFFF4FFBFFFF7FFFAFFF9FED
-:101FB0007FFBFFE8FFFFFEBFAFFFFFFEBFEFF7FFB6
-:101FC000BFFFFFFFFFFFF7FFFCFFFFFD7FFFFFFFEE
-:101FD000FD3FCFFFFFFFFFF7FFFD7FFFFF93FFFFF9
-:101FE0007ADFF7FFFF7B7FB7EFFFFFFDBFFDFBFF52
-:101FF000F7FFD7FFFFFFFC9F6FCBFFF4BBDFD6FDE2
-:10200000BF2FD3F7FFDFFFCFFFFABEBDAF6ADABE47
-:10201000BBAB3ABE2DAEEBDAF63FADF5DDFFCFF14F
-:10202000FFF97FFF73FEFFCFC3F4F72FF3FFFCFF31
-:102030007C1FFF3F4FFF7EFFEFBDF6FEFF2BEFDC67
-:10204000FBFDFFFBFFEA7BFFFFFFFFFFFBF7DFFF6F
-:10205000E37DFFB7FFBFFFFFDFFFF8FFBFFFBFEB71
-:10206000E7FAFE3DBFE9FCBFFFFAFBFEFFFFFFD929
-:10207000FFFFFFF67FFFF67DFFDFCFFDBFFBEF7EAB
-:10208000FF7FFFFFD3FFFDFBFFFBFFFFFFEFFFBF66
-:10209000FEFFF7EFFFFFFFFBFF87FFFDFFFFFFFFE7
-:1020A0007BFEFFFE3BF7F7FF3FFFFFFFFFFF0FFF4A
-:1020B000FFFFFFFBFFFFFFF7FFFFADFFFEF7FFFF97
-:1020C0005FFFFFDFFFFDFFF5FFDFFFBDFFE9FFC79C
-:1020D000F3FFFFF7FFF3FFF83BFFFF7BDFBFFBEFF3
-:1020E000FBFFFBF7F7BBFFFFFFFFFBFFFE7FF37F6D
-:1020F0005EB7BFFD7FFFF97FFBFFEBFD7F7FFFEF4B
-:10210000FBE03FFEBFBFDFFF7EFFF7FFFFFEBFFF2D
-:10211000DB78FFFFFFEEA1BFF5DEFBF7FFFBFFFF64
-:10212000FFFFFBFFFFD7FFFFFFFFEFF0FFFFFFF316
-:10213000F7FFEFFFE7CFFFFBFFEFFFFF9F9FEFFCF6
-:1021400016BFFEF3E4FFFFC6FFE7FFFFFDFFBFFF83
-:10215000FF3FFFBFD6AF7FFE6B7E7FFFAFFFFFBFAE
-:10216000FF5FFFFEFFFFFEFFFFBDDBFFFE5FF2FF35
-:10217000FF5FFFFFFFFFFFFFEF7FFFFFFFFFDEBF00
-:10218000FFFFEFFB77FEBD7F5FFFFFFFDF6FEDFF20
-:10219000FDFF7FFD6FFFFF77DACFFD5FFFBFFFFF22
-:1021A000DF7FFFFBFFFFFFFF667FFFFEBFE7BFFA9A
-:1021B000FFFEFFFFFFDFFF59EFFFEFFB7F89FFFF10
-:1021C000E9FF6FFFF5FFFFFFFFFF7FF2F7FFFFEF74
-:1021D000F87FFBFFFDFFFFD9FFEFBBFFFFFFBFEF66
-:1021E000DEFFFF9F7FDFFFF7FFFFFFFFDFFFFFAF98
-:1021F000FFFFF73FEB9FFE7F9E7F9FFE87FFEDDB9C
-:1022000056FFBFAF0BD2FFEFDB6E7DBD6FF8FE3F19
-:10221000FA5BFFFDBFEFFFBF6FDBE6FFFF3FFFDFB6
-:10222000FEFFFFFFFFDA3FFFFBFEFEFFFFDFF7BD14
-:10223000FFFDFFFEFFFBFFFFFFFFF15FFD9FDFFDE7
-:10224000FFFD7FFFFFFFFF76FAFFFF7FE3F8FFAEA2
-:10225000FFFB7E9D73FFFA7FDFFFFF7FFFFBCDFF5C
-:102260007FEFFBFFFDFFF77F7FEFFFEDFFFFFFB588
-:10227000FFBFFFBFFDEFDBF7FF93FFEFE2F9BE7F8C
-:102280008BE7F9FE6BE7F9FE7F9FE7F9FE7F47FFDB
-:10229000FFFDFF9FFFD7FFFFFFFFF5FF9FFFF7FE4B
-:1022A000FFBFFE6FFFFFFBFFFFFFAFFFFFFF7FFBE7
-:1022B000FFFEFFFFFFFFFFFDDFFFFFF7FFFFFFDF79
-:1022C000FFFFFF5FFFFFFFFF5FFBFEFFF837FFFF32
-:1022D000EFFF7FFEBFFFFFFEBFFFFF7FFFBFFDFFE2
-:1022E0007FFA7FFFFF6FFFFF7DFFCFFFFFFF4FFFF5
-:1022F000F2FFFFFFFFFFFABFFFAEEBFAFEBBADEB55
-:10230000FAF7AF6BFAF6BF25E9F27F45FFFFFDF75D
-:10231000F7BFFFDFFFFFBFFBFFDFF3FFF73FCFFF9D
-:10232000A1FFFFBFE7FFFF7FFF3DFFFFFFF7FF2F8D
-:10233000FFFBF57FFE57FFFFFFFFFFFFFFFFFFF7EC
-:102340003FFFFEFFFFFFFDFEF7EEAFFEEEE7FAFFF9
-:10235000FE9DF95EFEFFEBFFFFDFA7FFFFFFFCDB4B
-:10236000FFFFFF7EFBFFFFEFFBFDFFDBFFFFFFEF4C
-:10237000FFFFFFFDBFFEBFFF6F7FFFF7FFFFF9FF0E
-:10238000F7FFBFDEF7FFFFFFFA7FFDBF5FFFFFBF75
-:10239000FFEDFFF7BFFFFFEFFFDFFFFFFFE6FFFBF4
-:1023A0007FFFFFFFFFFFF7FFFFFFFFFFFFFFEBFFD9
-:1023B000FDFFF5FFF67FDFBDCFFFFFFFFFDFFFFF74
-:1023C000FFF9FFFFFFFFFFE3FFEEBFFF7DEFFEFF23
-:1023D000FFFFBFFFFFFFFFFEFFFFFFFFE7FFB5AE01
-:1023E000FFFFB6FEBFFFFFBFFFFFFFFFFFFFFFFFC7
-:1023F000FF27FFEFFE7FDFFF7EFFFFFFFFFFFFFFF7
-:10240000FFFFFDFFF7F99FFF5FFFFFFFFFFFFF7F6C
-:10241000FFFFFEFFFFFFFFFFFFFFFF0FFFE7BFFE16
-:10242000FFBFFFFFFFFFFCBFFFFFFEFFFFFFFFC47B
-:102430006BFF291FFBAFFFFFFFFFFFEF1BFEFFFC42
-:102440006FFFFFFD6AF7D7F5BFFFFEFFFFFFFFFF3E
-:10245000FEBFFFFFFAFFFFF7FBDDBFFFE7FFFFFF58
-:10246000FFFFFFFFFFFD7FFFFFF5FFFFF7FDB3EF6E
-:10247000FD7E5DFFFDFFFFFFFD7FD2F5FB7ECBB74D
-:10248000FFFFFFC6FFFDEE63FFFFFFFFFFF6FD65E9
-:102490005BDFFFD5FFFFFFF6E7BFF7A9FFFFEDFF0B
-:1024A000FFFFFFFFEBFFFFFFAFFFFFFFF81BFFE3A7
-:1024B000D0BFFFE1FFFFFFFFFFD7FFFFFF5FFFFF81
-:1024C000FFFFAFFFDB76BFFF7FFFBFEFFEFFBFEF7A
-:1024D000FBFEFFFFFFBFF27FFF9FFEBDFE7FFFFF02
-:1024E000FFFFFFFFFFFFFFFFFFF73FEC7FF695BB0E
-:1024F000EFF8FEFCBF2FDAFCBF2FCBF2FCBFEFFFE3
-:10250000A9BFCFFBFFFFFFFEDDB76DF6D9B66D9B10
-:1025100076D9BFFBFDA3FFBFEFFFEFFFFFFF7FDF1C
-:10252000FDEF7BDEF7FDEF7FFFFF05FFFAFE7FEF9C
-:10253000E3FFFFFD7FFFFFFFFF5FFFFFFD7FFBAFBF
-:10254000FF63C8FFBFEFFFFFFA7FFFFFFFFE9FF7AC
-:10255000FFFABFFE9FFB7FFFFFEFD7FFFFF5FFFFF7
-:10256000FFFFFD7FFFFFBFFFF9BFFFBE279FE7F91A
-:10257000FE7F8BE7FE7F9FE2F9FE7F9FE7F17FFF03
-:10258000FFFFFBFEFFFFFFD7FFFFFFFFF5FFFFFF92
-:10259000D7FFFAFFFEFFFFFFFDFFFFFFAFF7FFFFD3
-:1025A000FFEBFFFFFFAFFFC4FFF7FFFFEFFFFFFFF2
-:1025B000FF5FFFFFFFFFD7FFFFFFFFFFEBFFFB7A90
-:1025C000DFF7FDFFFFFEBFFFFF7FFFAFFFFFFFF75E
-:1025D000EFE3FFDDD2FFDFFFFFF2FCBFCBF6FDBF75
-:1025E0002FCBFF7FDFDEAFFFDAEEBFAFE9FAF4BD3E
-:1025F000AF5AAEBBAB6BDADEBFADD75EFFFFBFFC41
-:10260000FFDFFDFFFFFFFFDFF7FFFFFFFFFDFFFA2B
-:102610001FFFFEFBEFBFFDFFFDBD77FFFFFFFF9D2F
-:10262000EFFFFFFFEF7DFFFBFEEFFFFFFFFFFFF779
-:10263000FFFFFFFFFFFFFFEEBFE4FBFFFE3FFEFFDC
-:10264000FFFFFFAFEAFEBFAFEBFAFEFFFFFF55F65D
-:10265000FFFEF7FF7FFFEBF75FC5FD7F5FD7F5FF5D
-:102660006FFBFF8AFFFFFFFFEBFFFFFFFFFBBFBF1B
-:10267000EFFBFFFFFFFFFBFF77DFFBFFFD7FEFFFC0
-:10268000FFFFBF7FFFDFBFFFFBFFFFFFFEEFDFFFAF
-:10269000FEFF9FEF7DFFF7FF7FFFFFDFF7FDFFEFFF
-:1026A000DFFFDFFFFFFFFFFFFFFFFFFFFDFFFFFB80
-:1026B000FDFFBFDFD1FFF83BFFFFFFFFFFFFFFFF85
-:1026C0007EDBFDFF77DBB77DBFFBFFF87FED7B5E39
-:1026D000FFFEFFFF4FD7FD7FDFD7F5FF7FFFFFFF37
-:1026E000F23FFEFFBFFFFFFFFFBFEFFEFF3BEEFF2E
-:1026F000FCEFFFFFFF85FFFDFEFFF5FFFFFEFFDFA5
-:10270000FBFF5FBFFFFDFFFFFFFFA8FFFF9F9EFFD7
-:10271000FFFF7FF3FFFFCFFFF7FDFF7FFFFFFC16FB
-:10272000BFCFA3E5EF7FFFF3E4FFCF93FCFF3FCFE5
-:10273000FFFFFFD60F7DBF6EFBF4FCAF6DDB77B7FD
-:102740006DDBF6FDBFFFFFFFBF9BFADEB7B7EDF90C
-:102750007EB7ACEBD6B3ADEB7ADFFFFFFFD8BFFFA0
-:10276000B7ED9F6FDDF768DB37B36CDB36CDB37F3A
-:10277000FF7FF56FFDEF793DF793E47A9EADEA7A3E
-:102780009EF7BDEFFFFFFF767FFBC6FFBBEFDAFED4
-:10279000FDBFFBFEFFBFEFFBFFFFFBFFA5FFFDAB98
-:1027A0006F78DE178F79DFFDFF7FDFF7FDFFFFFB1F
-:1027B000FFFBFFEFFBEFFBFEFFBBDAF3EF3BCEF3DC
-:1027C000BCEF3FCFDFFFB7FFFFFFCF73FFBFEFFFD0
-:1027D000F3FF3FCFF3FCFF3DCF9FFE07FFAFEBFEC4
-:1027E000FDBFEFEBFAFFAFEBFAFEBFAFFBFE3FFB27
-:1027F0009BFF7FDFFFF3FEFFDEF7BF7BDEF7BDEF62
-:102800007BFEFFFFDF3FFEFFB7FFEFF7FFBFEDFEF1
-:10281000DFB7EDFB7EDFFFFFFFFD5FEFEBFAFEF5BD
-:10282000BF6FFFFFFFFFFFFFFFFFFFFEF8FFA8FFE7
-:10283000FFBFEFFB6AFBB7EFFBFFBFEFFBFEFFBF86
-:10284000EFFBFFE0FFFFFD7F5CD77DDFF35CF5CDA5
-:10285000735ED7B5FD7FEFFFDBFFFFE2F8BE2F8F82
-:10286000E7F8BE6BE2F8BE2F8BE2F9FE7FE7FFD7F9
-:10287000F5FD7FFFF7F5FD7FD7F5FD7F5FD7F5FF0E
-:10288000FFFF8FFFAFEBFAFFFFBFEBFAFF2FEBFA73
-:10289000FEBFAFEBFFFFFE5FFF5FFFFFFDFFFFD758
-:1028A000FFFFFFFFFFFFFFFFFFFFFFFFBFFEB7FDC3
-:1028B000FF7EDFF7ADFF7FF7FDFF7FDFF7FDFF7FD7
-:1028C000F67FFFFFFFDBF6FCAFFFFFFFFFF7FFFF29
-:1028D000FFFFFFFFFFECBFFFAFEBFAF6AB8FEBFAAA
-:1028E000F7A5EBFABEBFAFEBFAFF6DFFFF7FDF335B
-:1028F000DDFF7FFEF7FC7FFBFFFFFFFFFFFFFFA970
-:10290000FFFDFFFFFEFFFFDFFFFFEFEFFDFF7FFF9C
-:10291000FFFFFFFEA7FFFFFF77DFF7FD9F7FFE773B
-:10292000EFFFFFFFFFFFFFFFFFAFBFAFFFF9BEBF2E
-:102930008FFBFEFEEFFBFEFFBFEFFBFFFFFDDF6F38
-:10294000EFFF7FFFBFBFDFFFFCFFDFF7FDEF7FDFA4
-:10295000FFFFFF3FF6FFCFFFDBFBF7FFEB7AFFFF49
-:10296000FFBFEFFBFFFFFFFE6DFDFF5FFBFFFFF70C
-:10297000FF5FF5FFFFFFFFFFFFFFFFFFF8FFFBFF1C
-:10298000FFFDFFFFFFFFE7F6BFFFFFFFFFFBFFFFBE
-:10299000FFC9FFFFFFBDFFBFAFEFEF3FD1FC7FFBE4
-:1029A000C7FFFFFFFFFFE3FFFFFFFFFDFFFF77FF15
-:1029B000DFB7FDF7FDF7FFFFFFFFFF57FFF7A5FDAF
-:1029C0003FDFBFBFFE7FFFFFFFDFFAFDFFFFFFFE20
-:1029D00087FFE9FFFEEFBFEFFEFEFFEFFFFFFFFF08
-:1029E000FFFFFFFFFA9FFF3FFFFDFD57DFFDF3FFF6
-:1029F000DFFDFF5FDFF5FDFFFFF98FFFFFFFEE7FDC
-:102A0000FFFFBF5EFEECFB3F7F9FEFF9FFFFCD6B4B
-:102A1000FFFFFFC5F3FCFA38FFAF3FEE7F9FFFD902
-:102A2000FFFFFD7AF7FFF3FFAF6FDBF2B9E9FBFFC2
-:102A3000FFFFFEFFFFEFFFFBC5BFFFEFFF5EB7AD80
-:102A4000CD797CFFFFFFFFFFFFFFFFFFFD93FFEF4F
-:102A5000EAFEBFEF5BD2CDF56D77DFF7FDFF7FDFDD
-:102A6000FFFF66FFD5657D5F759D657FD6FB4FFFD8
-:102A7000FFFFFFFFFFFFF6C7FFBFEFFAFEFFBFEB51
-:102A8000FFDFFF7EFFFFEFFD7ED7FF78DFFF5FDF19
-:102A9000F5BF7FDFC5FF3FF67EFF0FEFF23EBFFFC2
-:102AA000FB3FFFFB7FFFB3FEFBF6FDFFDAF7FDFF09
-:102AB0007FDFF7BFFFFA7FFFFFFFFF9FFFF3DCF928
-:102AC000BFCEE7F9FE7F9FE7FFFFE27FFEFFBFEF8C
-:102AD000EBFAFF9F671EFF8FE7F8FE7F8FEFFFBDCA
-:102AE000BFFFFBFFFFDFF7FFFCFFBFFFFFFFFFFFA5
-:102AF000FFFFFFFDB3FFFFEFFFFFBFEDFFFBEEFEAC
-:102B0000FFFFEFFFFEFFFFFFFFB5FFB7FDFD6EFF0D
-:102B1000FFFEFD2FD8FEBF8FEBF9FE3FFFFACFFF80
-:102B2000E7D9FABFDF77FCFB3FABFEFFBFEFFBFE51
-:102B3000FFFFEE1FFFDFF7FFFFFF5F9735BF5EFE72
-:102B4000BFEFFFF7FDFFFFFABFFFBE6F9FE7F8BEC5
-:102B50002F8B66947D9DE7F9FE7F9FE7F17FFFFF56
-:102B6000FFF7F5FD7F5FFBFD9EFFFBFEFFFFEFFF25
-:102B7000FFA0FFFFFFBFEFEBFAFEBFB7F7F7FFFFC6
-:102B8000FDFFFFFFFFFFDDFFFDFFFFFFD7FFFFFFA3
-:102B90007FF5FFFFEFFFFFFFBFFFFFABFEFBFEFF79
-:102BA000F7AFFFFFDEF7EB5FDFF7FDFF7FDFFFFF34
-:102BB000B3FFC9FEFFFFFFFFD6FFFFCBFFFFDFFF25
-:102BC000FFFFFFFFFC8FFFBABEBFAFEB78FEB7ADD4
-:102BD0003AFEB7AFEB7AFEBFAFFF9FFFFFDFFCFF10
-:102BE000FFFEC3FEFFFF33FCFFBFDFF3FFFFBB9F12
-:102BF000FFFFFFEBDFFFFFAFF76FF9BFEFFDFFFF59
-:102C0000FFFFFFE37FFFFFFFFBFFFFBFFDFBF7FFC2
-:102C1000DFF7FFFEEF5FBDFFFAFFF8FFBFAFFBFE80
-:102C2000FE3FEFE8FFDFF3FDFFFFFFFFFFEDFFFBE0
-:102C3000FDFFAFFFFFFEFEBFDBFFFFFFBFFFDFFFBC
-:102C4000FDFFCBFFFFFFFFFFBF6FFF7FB7B3FFFFAE
-:102C5000DFFFFBEFFFFFFF07FFFBFFFFFFEDFFF5D0
-:102C60007CFF7FFEFFFFEFCFFFFBFFFF2FFFFFFF8C
-:102C7000FFF3FFFBFFFEFFFFFFFFFFFFBFFFFFFFB5
-:102C8000FD1BFFFFFFFFFFFFFFFFFE7CFFFFFFFFBE
-:102C9000EFFFFFFFFFFBBF7FFDFFFFFFFFFFFFFF1A
-:102CA000DBFFFFFFFFFFFFFDFFFFF07FFFFFFFFFE9
-:102CB000FFFFFFFFFFFBFFDFFFFFFFFFFFFDBFFE8B
-:102CC0007FFFFFFFFFFFFFFFFFEFFEFFBFFFFFFFE5
-:102CD000FFFFEFFAB5FFFFFFF7F7FFFFFFFFDFFB97
-:102CE000FCFFFFFEFF7FDFBFFFCBBFF9FE7F9FE74B
-:102CF000F9FE7F97E1FE799FE7FDFE7FDFFE37FF5C
-:102D0000FBDEDEBDEFF3FEFBAFEBFEFFFFCFFFFE12
-:102D1000FFBFFF8FFFEFFBFEFFBFE7F95E7FEFFB1B
-:102D2000DAFFBFEFFBFEFFFD1FFFFFFFFFFFFFDF2F
-:102D3000FFFF7FFFFFF7FB7FFFFFFFFFFC3FFFBFB2
-:102D4000EFFBFEFFBFEF7B7FBFEFFBFEFFB5EFFBAF
-:102D5000BFFA7FFCFF3FCFF3FCFF3FCFBCFF3FEF4D
-:102D6000F3FCFE3FCFFFEEEFFBFEFFBFEFFB6AD7AA
-:102D7000B7FBF8FFB7EFBAFEFFBF7FE9FFF97E5F51
-:102D800097E5F9FE7FBFF97E5F9FE5FBFE5FB7FF2A
-:102D9000A3FFF7FDFF7FDFF7FDFF5EF77DFF77DF26
-:102DA000F7FDFF7FFFD7FFFFFFFFFFFFFDDFFB7F8B
-:102DB000FFFFEFFFFEFBFFFFBFFE8FFFDFF7FDFD15
-:102DC0007FDFF7FD3EDFF5BDFF7FDFF7FDF7FF9FFC
-:102DD000FFFFFFFFFFFFFFFFFFFDFFBEFFFFFFFF46
-:102DE000FFFFFFFD3FFFDFF7FDFF7FDFF7FDFFCFB9
-:102DF00077FCFF5FDFF7FDFFF47FFFFFFFFFFFFFC3
-:102E0000FFFFFFFFFFFFFFFFFFFDFFFFFFEEFFFFE5
-:102E1000FFFFFFFFFFFFFFFFEDFBFFFFBFFFFFFF18
-:102E2000FFFFE9FFFFFFFFFFFFFBFFFFFFD3FFFFF8
-:102E3000BF3FFBFFFFFFFBF3FFFFFFFFFFFFFFFFB6
-:102E4000FFFFFFFFFFFEFFF7FFFFFFFF17FFFFFF83
-:102E5000DFFFFDFFFFFFFFFFDFDFFFFDFFFFDFF70E
-:102E6000FF4FFFFFFFFFFFFFFFFFFFFEFFFFFFFD25
-:102E7000FFFFFFFFFEFF9FFFFFFFFFFFFFFFFFFFC3
-:102E8000FDFFFFFFFFFF7FFFFFFF7A3FFFFFFFFF19
-:102E9000FFFFFF7FFFFFFFFFFFFFFFFFFFFFFFF2CF
-:102EA0007FFFFBFEFFBFEFF8FEFFBFFBFEFF8FECD7
-:102EB000FBFEFFBFF8F7FEFFBFEFFBFEFDBFCFEC51
-:102EC000FF3FEFDBF8FFBFCFFFF9FFFFBFFFFBFFC7
-:102ED000FFFFEFFBDFFFFFFFFFFFBFFFFFFFBBFFBA
-:102EE000EFFBFEEFBFEEEBFBFEFFEFFEEEBFFEEBF8
-:102EF000FFEFFF17FF7EEBBBFEBFBEFBEF5BF7BD37
-:0A2F0000FBCFBFBFBBFB7ECCEFFF91
-:00000001FF
-
- * Copyright (C) 1999 BayCom GmbH
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that redistributions of source
- * code retain the above copyright notice and this comment without
- * modification.
diff --git a/firmware/dabusb/firmware.HEX b/firmware/dabusb/firmware.HEX
deleted file mode 100644
index 7c258df2b0a..00000000000
--- a/firmware/dabusb/firmware.HEX
+++ /dev/null
@@ -1,649 +0,0 @@
-:02000000215786
-:0300030002016691
-:03000B0002016689
-:0300130002016681
-:03001B0002016679
-:0300230002016671
-:03002B0002016669
-:0300330002030FB6
-:03003B0002016659
-:03004300020100B7
-:03004B0002016649
-:0300530002016641
-:03005B000204BDDF
-:0300630002016730
-:03010000020C5A94
-:030104000201ED08
-:030108000202519F
-:03010C0002027C70
-:030110000202E404
-:0101140032B8
-:0101180032B4
-:03011C000205FDDC
-:03012000020000DA
-:03012400020000D6
-:0301280002043C92
-:03012C0002046A60
-:03013000020000CA
-:03013400020000C6
-:03013800020000C2
-:03013C00020000BE
-:03014000020000BA
-:03014400020000B6
-:03014800020000B2
-:03014C00020000AE
-:03015000020000AA
-:03015400020000A6
-:0A01570075817FE5826003020161FB
-:0501610012076F21648C
-:010166003266
-:0E016700C0D0C086C082C083C0E0907F97E009
-:0E0175004480F0907F69F0F0F0F0F0F0F0F0D0
-:0E018300F0F0F0F0F0F0F0F0F0F0F0F0F0F04E
-:0E019100F0F0F0F0F0F0F0F0F0F0907F97E07A
-:03019F00557FF099
-:0E01A200907F9AE030E423907F68F0F0F0F058
-:0E01B000F0F0F0F0F0F0F0F0F0F0F0F0F0F021
-:0E01BE00F0F0F0F0F0F0F0F0F0F0F0F0F0F013
-:0E01CC00E5D8C2E3F5D8D0E0D083D082D0864B
-:0301DA00D0D03250
-:0801DD0075860090FFC37C054C
-:0701E500A3E582458370F9D8
-:0101EC0022F0
-:0E01ED00C0E0C0F0C082C083C002C003C0D01A
-:0E01FB0075D000C086758600E591C2E4F591CE
-:0D020900908800E0F541907FAB7402F0900A
-:090216007FAB7402F0E5326021B7
-:04021F007A007B00E6
-:0B022300C3EA9418EB64809480501232
-:0E022E00907F69F0F0F0F0F0F0F0F00ABA0006
-:02023C00010BB4
-:02023E0080E35B
-:02024000D08666
-:0E024200D0D0D003D002D083D082D0F0D0E054
-:01025000327B
-:0E025100C0E0C0F0C082C083C0D075D000C035
-:0E025F0086758600E591C2E4F591907FAB7440
-:04026D0004F0D08643
-:0B027100D0D0D083D082D0F0D0E0329B
-:0E027C00C0E0C0F0C082C083C002C003C00456
-:0E028A00C005C006C007C000C001C0D075D0BE
-:0D02980000C086758600E591C2E4F59190E6
-:0C02A5007FAB7408F0756E00756F0212DC
-:0602B1001144757039755F
-:0602B700710C75720212C9
-:0C02BD001175907FD6E4F075D820D08633
-:0E02C900D0D0D001D000D007D006D005D00490
-:0D02D700D003D002D083D082D0F0D0E0322E
-:0E02E400C0E0C0F0C082C083C0D075D000C0A2
-:0E02F20086758600E591C2E4F591907FAB74AD
-:0403000010F0D086A3
-:0B030400D0D0D083D082D0F0D0E03207
-:0E030F00C0E0C0F0C082C083C002C003C004C2
-:0E031D00C005C006C007C000C001C0D075D02A
-:0C032B0000C086758600756E00756F02BC
-:0703370012114475704075BE
-:06033E00710C7572021241
-:0E0344001175907FD67402F0907FD67406F08B
-:0503520075D810D086F3
-:0E035700D0D0D001D000D007D006D005D00401
-:0D036500D003D002D083D082D0F0D0E0329F
-:0D037200907FA57480F0907FA6749AF01221
-:0C037F00101B907FA6E542F012101B90AE
-:0D038B007FA6E543F012101B907FA5744083
-:01039800F074
-:010399002241
-:0D039A00907FA57480F0907FA6749AF012F9
-:0C03A700101B907FA6E544F012101B9084
-:0C03B3007FA6E545F012101B907FA6E528
-:0B03BF0046F012101B907FA57440F068
-:0103CA002210
-:0A03CB0075440275450075460012E6
-:0903D500039A75420375430012FE
-:0203DE000372A8
-:0103E00022FA
-:0C03E100908800E536F09088007410252C
-:0903ED0036F01201DD75420175C4
-:0903F600431812037275440275EC
-:0903FF00450075460012039A75D1
-:08040800420375434412037224
-:0104100022C9
-:0E041100C0E0C0F0C082C083C0D075D000C073
-:0E041F0086758600E591C2E4F591907FAA747F
-:04042D0002F0D08683
-:0B043100D0D0D083D082D0F0D0E032D9
-:0E043C00C0E0C0F0C082C083C0D075D000C048
-:0E044A0086758600E591C2E4F591907FA97455
-:0704580004F0753001D086AD
-:0B045F00D0D0D083D082D0F0D0E032AB
-:0E046A00C0E0C0F0C082C083C0D075D000C01A
-:0E04780086758600E591C2E4F591907FAA7426
-:0704860004F0753101D0867E
-:0B048D00D0D0D083D082D0F0D0E0327D
-:0E049800C0E0C0F0C082C083C0D075D000C0EC
-:0C04A60086758600E591C2E5F591D086D0
-:0B04B200D0D0D083D082D0F0D0E03258
-:0E04BD00C0E0C0F0C082C083C0D075D000C0C7
-:0C04CB0086758600E591C2E7F591D086A9
-:0B04D700D0D0D083D082D0F0D0E03233
-:0C04E200907FEAE0FA8A20907F96E4F018
-:0104EE0022EB
-:0704EF00907FEAE0FA8A2188
-:0104F60022E3
-:0E04F700901713E0FA901715E0FB74802AFAB4
-:0E05050074802BFBEA0303543FFCEAC423542A
-:0E0513001FFA2CFAEB0303543FFCEBC42354F5
-:0B0521001FFB2CFB90170AE0FC60029F
-:02052C007A0053
-:07052E0090170CE0FC6002D5
-:020535007B0049
-:0B053700EA2BFCC313F53A7544028B5D
-:07054200458A4612039A7579
-:090549006E08756F001211447573
-:040552007047757108
-:080556000C757202121175858B
-:05055E003A731211A028
-:010563002275
-:0E056400907F96E0FA907F9674806502F0908A
-:0E0572007FEBE0FA907FEAE0FB907FEFE0FC89
-:0E0580003395E0FD8C057C00907FEEE0FE33AD
-:0E058E0095E0FFEC2EFCED3FFD907FE9E0FED6
-:05059C00BE0102800316
-:0305A1000205F957
-:0605A400BC0121BD001E98
-:0E05AA00EAC40354F8FCEB25E0FD2C2400FC11
-:0E05B800E43417FD907EC0E0FE8C828D83F04F
-:0205C600803182
-:0E05C800EAC40354F8FAEB25E0FB2AFA2400FB
-:0E05D600FBE43417FC907EC0E0FD8B828C832A
-:0E05E400F074012A2400FAE43417FB907EC163
-:0705F200E0FC8A828B83F01C
-:0305F90075380151
-:0105FC0022DC
-:0E05FD00C0E0C0F0C082C083C002C003C004D2
-:0E060B00C005C006C007C000C001C0D075D039
-:0D06190000C086758600E591C2E4F5919061
-:0D0626007FAA7401F0120564753700D086BC
-:0E063300D0D0D001D000D007D006D005D00422
-:0D064100D003D002D083D082D0F0D0E032C0
-:0E064E00907FEBE0FA907FEAE0FB907FEEE019
-:0E065C00FC3395E0FD907F96E0FE907F967453
-:0E066A00806506F0907F007401F0EAC403542E
-:0E067800F8FEEB25E0FB2EFE2400FBE4341719
-:0E068600FF8B828F83E0FB74012E2400FEE4C4
-:0E0694003417FF8E828F83E0FE907FE9E0FF37
-:0306A200BF810A0B
-:0A06A500907F00EBF0907F01EEF073
-:0806AF00907FE9E0FBBB821A19
-:0306B700BA010C79
-:0C06BA00907F00E4F0907F01E4F0800BE2
-:0B06C600907F00E4F0907F0174B5F01D
-:0806D100907FE9E0FBBB831BF5
-:0306D900BA010D56
-:0D06DC00907F007401F0907F01E4F0800B2E
-:0B06E900907F00E4F0907F017412F09D
-:0806F400907FE9E0FBBB841CD0
-:0306FC00BA010D33
-:0D06FF00907F007401F0907F01E4F0800C0A
-:0C070C00907F007480F0907F017401F079
-:05071800907FB5ECF03C
-:01071D0022B9
-:0C071E0075360D908800741DF0756B801E
-:0A072A00756C3C1210E2756B8075CF
-:090734006C0F1210E2756B807568
-:09073D006C061210E2756B807568
-:070746006C011210E27A00C1
-:03074D00BAFF00F0
-:02075000500A4D
-:0A075200C0021201DDD0020A80F19E
-:0A075C00756B80756C3C1210E2759D
-:080766006B80756C0F1210E2AC
-:01076E002268
-:0E076F00907FA1E4F0907FAF7401F0907F9234
-:0E077D007402F0758E3175892175880075C87B
-:0E078B0000758D4075984075C04075870075EB
-:0907990020007521007522007595
-:0507A200230075470073
-:0707A700C3E5479420501147
-:0D07AE00E5472400F582E43417F583E4F0FC
-:0407BB00054780E886
-:0907BF00E4F540F53FE4F53CF5DA
-:0707C8003BE4F53EF53D7531
-:0B07CF003200753700753900907F93F1
-:0E07DA00743CF0907F9C74FFF0907F967480CA
-:0E07E800F0907F947470F0907F9D748FF0906D
-:0E07F6007F97E4F0907F9574C2F0907F987426
-:0E08040028F0907F9E7428F0907FF0E4F09032
-:0E0812007FF1E4F0907FF2E4F0907FF3E4F0E9
-:0E082000907FF4E4F0907FF5E4F0907FF6E432
-:0E082E00F0907FF7E4F0907FF8E4F0907FF90F
-:0E083C007438F0907FFA74A0F0907FFB74A0E7
-:0E084A00F0907FFC74A0F0907FFD74A0F09001
-:0E0858007FFE74A0F0907FFF74A0F0907FE010
-:0E0866007403F0907FE17401F0907FDD7480E8
-:0B087400F012124312071E7A007B00F6
-:09087F00C3EA941EEB940050172B
-:0C088800908800E0F54790880BE0F547F1
-:09089400907F68F00ABA00010B24
-:02089D0080E0F9
-:0C089F001203E1907FD6E4F07A007B00A9
-:0D08AB008A048B05C3EA94E0EB942E501AEA
-:0E08B800C002C003C004C0051201DDD005D08F
-:0A08C60004D003D0020ABA00010BAF
-:0208D00080D9CD
-:0D08D200907FD67402F0907FD67406F090EF
-:0E08DF007FDE7405F0907FDF7405F0907FAC33
-:0E08ED00E4F0907FAD7405F075A88075F810EA
-:0D08FB00907FAE740BF0907FE27488F09057
-:0C0908007FAB7408F075E81175320175C2
-:0C0914003100753000C004C0051204F76B
-:0A092000D005D004753400753501D0
-:0D092A00907FAE7403F08C02BA00028003CF
-:03093700020A3F72
-:0C093A00853334907F9D748FF0907F9780
-:0E0946007408F0907F9D7488F0907F9AE0FA1C
-:0C09540074055AF533907F9D748FF0906D
-:0D0960007F977402F0907F9D7482F0E53364
-:0D096D0025E0FA907F9AE05405FB4AF5332F
-:02097A00600C0F
-:0C097C00907F96E0FA907F9674804AF01D
-:0B098800756E00756F00C004C0051202
-:0E0993001144D005D004901713E0FA74802AA6
-:0609A100FAE533B404295D
-:0309A700BAA000F3
-:0209AA005024D7
-:0D09AC00901713E004FB0B901713EBF09075
-:0E09B9001713E0FB901715F0C002C004C00534
-:0909C7001204F7D005D004D0029F
-:0509D000E533B402262E
-:0609D500C374049A5020D7
-:0D09DB00901713E0FA1A1A901713EAF09023
-:0D09E8001713E0FA901715F0C004C00512B7
-:0609F50004F7D005D00458
-:0509FB00E533B4081D06
-:040A0000E534701950
-:0A0A040074012535540FF5358535D2
-:0C0A0E0075757600C004C0051213FED000
-:030A1A0005D00400
-:050A1D00E533B4011DEA
-:040A2200E53470192E
-:0A0A2600E53524FF540FF535853542
-:0C0A300075757600C004C0051213FED0DE
-:030A3C0005D004DE
-:0E0A3F00C004C0051201DDD005D004907F96E2
-:0E0A4D00E0FA907F96747F5AF0907F977408BD
-:0A0A5B00F0C3EC9400ED9402400893
-:080A6500907F96E0FA20E608FC
-:080A6D00C3E49C74089D5013C2
-:0E0A7500907F96E0FA907F9674406502F07CC8
-:050A8300007D0080056C
-:050A88000CBC00010D93
-:050A8D00E538B4010E84
-:0D0A9200C004C0051204F7D005D00475386B
-:010A9F000056
-:070AA000E531700302092A91
-:0A0AA700907FC9E0FA7003020C2DE5
-:0E0AB100907F96E0FA907F9674806502F09038
-:090ABF007DC0E0FABA2C028003AC
-:030AC800020B36E8
-:050ACB007532007B0004
-:030AD000BB640004
-:020AD300501CB5
-:0E0AD500C002C003C004C0051201DDD005D070
-:0D0AE30004D003D00290880FE0F5470B808F
-:010AF000DF26
-:0D0AF100C002C004C00512071E1203E1126E
-:0C0AFE0004F7D005D004D002756E00751E
-:0D0B0A006F01C002C004C005121144D005E7
-:090B1700D004D00275704D757117
-:0B0B20000C757202C002C004C0051278
-:0B0B2B001175D005D004D002020C2D83
-:030B3600BA2A3B9D
-:0D0B3900907F987420F0C002C004C0051227
-:0E0B460001DDD005D004D002907F987428F015
-:020B54007B0024
-:030B5600BB0A00D7
-:050B59004003020C2D19
-:0E0B5E00C002C003C004C0051201DDD005D0E6
-:080B6C0004D003D0020B80E26B
-:030B7400BA2B1A7F
-:080B7700907FC9E0FBBB4012B6
-:0E0B7F00C002C004C005121205D005D004D07B
-:040B8D0002020C2D27
-:030B9100BA101F78
-:0E0B9400907F96E0FB907F9674806503F0C022
-:0E0BA20002C004C00512103DD005D004D002E0
-:030BB000020C2D07
-:030BB300BA111262
-:0E0BB600C002C004C00512106AD005D004D0E1
-:040BC40002020C2DF0
-:030BC800BA12124C
-:0E0BCB00C002C004C00512108FD005D004D0A7
-:040BD90002020C2DDB
-:030BDD00BA130B3D
-:0B0BE000907DC1E0FB908800F0804297
-:030BEB00BA141128
-:0E0BEE00C002C004C0051211DDD005D004D035
-:030BFC0002802E46
-:030BFF00BA151D07
-:0C0C0200907DC1E0F575907DC2E0F576B4
-:0E0C0E00C002C004C0051213FED005D004D0F1
-:030C1C0002800E45
-:030C1F00BA160BF7
-:0B0C2200C004C0051213A3D005D004CD
-:0B0C2D00907FC9E4F075310002092A35
-:010C38002299
-:070C3900535550454E4400E5
-:070C4000524553554D4500DC
-:060C470020566F6C200036
-:0D0C4D004441425553422076312E30300094
-:0E0C5A00C0E0C0F0C082C083C002C003C0046E
-:0E0C6800C005C006C007C000C001C0D075D0D6
-:0D0C760000C086758600E591C2E4F59190FE
-:0E0C83007FAB7401F0907FE8E0FA907FE9E02B
-:060C9100FBBB0002800322
-:030C9700020D3813
-:030C9A00BA801409
-:0E0C9D00907F007401F0907F01E4F0907FB52D
-:060CAB007402F0020ECD00
-:050CB100BA820280037D
-:030CB600020D1D0F
-:080CB900907FECE0FCBC01009F
-:020CC1004021D0
-:060CC300C374079C401BF6
-:0E0CC900EC24FF25E0FD24C6F582E4347FF51F
-:0D0CD70083E0FD530501907F00EDF0802BC0
-:030CE400BC8100D0
-:020CE7004021AA
-:060CE900C374879C401B50
-:0E0CEF00EC247F25E0FC24B6F582E4347FF58A
-:0D0CFD0083E0FC530401907F00ECF08005C3
-:050D0A00907F00E4F001
-:0E0D0F00907F01E4F0907FB57402F0020ECDEB
-:050D1D00BA8102800311
-:030D2200020EC5F9
-:0E0D2500907F00E4F0907F01E4F0907FB574C1
-:050D330002F0020ECDEC
-:030D3800BB012DCF
-:060D3B00BA0003020ECD18
-:030D4100BA0211E2
-:0D0D4400755900C002C003120EF0D003D09C
-:040D510002020ECDBF
-:050D5500BA2102800339
-:030D5A00020ECDB9
-:0B0D5D00753701907FC5E4F0020ECD59
-:030D6800BB031FAB
-:060D6B00BA0003020ECDE8
-:050D7100BA020280033C
-:030D7600020ECD9D
-:0D0D7900755901C002C003120EF0D003D066
-:040D860002020ECD8A
-:030D8A00BB065451
-:050D8D00BA80028003A2
-:030D9200020EC589
-:080D9500907FEBE0FCBC0115AE
-:0C0D9D007CFB7D0F8D067F00907FD4EE64
-:090DA900F0907FD5ECF0020ECDB4
-:0A0DB200907FEBE0FCBC020280031E
-:030DBC00020EC55F
-:0A0DBF00907FEAE0FCBC0002800314
-:030DC900020EC552
-:0C0DCC007C3B7D0F8D067F00907FD4EEF5
-:090DD800F0907FD5ECF0020ECD85
-:060DE100BB0703020EC572
-:030DE700BB081036
-:0D0DEA00AC48907F00ECF0907FB57401F0F4
-:030DF700020ECD1C
-:030DFA00BB093101
-:050DFD00BA00028003B2
-:030E0200020EC518
-:0E0E0500907FEAE0FCC374019C5003020EC50E
-:080E1300907FEAE0FCBC000A3C
-:0A0E1B00901721E4F0901722E4F094
-:090E2500907FEAE0F548020ECDD1
-:030E2E00BB0A27D5
-:050E3100BA81028003FC
-:030E3600020EC5E4
-:0E0E3900907FECE0FA2420FAE43417FC8A8261
-:0E0E47008C83E0FA907F00F0907FB57401F08C
-:030E5500020ECDBD
-:050E5800BB0B0280034A
-:030E5D00020EA9D9
-:0D0E6000901720E4F0907FECE0FABA011A40
-:080E6D00907FEDE0FABA0012DB
-:0E0E7500907FEAE0FA901721F0C0031204E229
-:040E8300D0038046D2
-:080E8700907FECE0FABA023E94
-:080E8F00907FEDE0FABA003695
-:0D0E9700C0031204EFD003907FEAE0FA9050
-:050EA4001722F080247C
-:050EA900BB12028017DE
-:050EAE00BB8102800D74
-:050EB300BB8302800872
-:050EB800BB8202800373
-:030EBD00BB8405EE
-:050EC00012064E80083F
-:080EC500907FB47403F0800675
-:060ECD00907FB47402F0F6
-:020ED300D086C7
-:0E0ED500D0D0D001D000D007D006D005D00478
-:0D0EE300D003D002D083D082D0F0D0E03216
-:0B0EF000907FECE0F55AC39401401D18
-:070EFB00C37407955A40166D
-:0D0F0200E55A24FF25E0FA24C6F582E43408
-:090F0F007FF583AA59EAF0802263
-:070F1800C3E55A9481401B60
-:070F1F00C37487955A4014CA
-:0D0F2600E55A24FF25E0FA24B6F582E434F4
-:070F33007FF583AA59EAF0E3
-:010F3A002294
-:0E0F3B000902BA000301004000090400000092
-:0E0F49000101000009240100013D0001010C1E
-:0E0F570024020110070002030000000D240612
-:0E0F650003010215000300030000092403022B
-:0E0F7300010100010009240304020300030031
-:0E0F8100092403050306000100090401000015
-:0E0F8F00010200000904010101010200000737
-:0E0F9D002401020101000B24020102021001D6
-:0E0FAB0080BB00090588050001010000072534
-:0E0FB900010000000009040200020000000018
-:0E0FC7000705820240000007050202400000FC
-:0E0FD50009040201030000000007058202402B
-:0E0FE30000000705020240000009058905A074
-:0A0FF1000101000000FFFFFFFF00F8
-:0E0FFB00120100010000004047059999000115
-:0E10090000000001000000000000000902BA13
-:0410170000030100D1
-:02101B007A0059
-:03101D00BA050011
-:02102000501767
-:08102200907FA5E0FB30E00522
-:05102A00900001800DA3
-:0A102F00C0021201DDD0020A80E4C5
-:0310390090000123
-:01103C002291
-:0E103D00907DC1E0F9A3E0FAA3E0FB7C007D0A
-:04104B007EEB6012C6
-:0E104F0089828A83E0A3A982AA838C828D8382
-:04105D00F00CDBEECA
-:08106100907DC3E0907FB9F01F
-:011069002264
-:0E106A00907DC1E0F9A3E0FAA3E0FB7CC47D19
-:041078007DEB60E5C7
-:0E107C008C828D83E00C89828A83F0A3A98286
-:04108A00AA83DBEE6C
-:01108E00223F
-:0E108F00907FA57480F00586907DC1E00586F7
-:0E109D00A3F012101B907FA60586A3A3E0F916
-:0510AB006016A305869C
-:0D10B000907FA60586E0A30586F0C0011222
-:0610BD00101BD001D9ED6B
-:0610C300907FA57440F0CF
-:0110C9002204
-:0810CA009088027401F07A0025
-:0310D200BAFF0062
-:0210D500500ABF
-:0A10D700C0021201DDD0020A80F110
-:0110E10022EC
-:0510E200E56BB4C0083D
-:0810E700908803E56CF080061F
-:0610EF00908802E56CF0A0
-:0410F5007A007B0002
-:0B10F900C3EA9432EB6480948050073F
-:051104000ABA00010B16
-:0211090080EE76
-:01110B0022C1
-:0A110C00908803E56DF005397A00C4
-:03111600BA2800F4
-:02111900500381
-:03111B000A80F84F
-:05111E00E539B41008E2
-:0811230090880274C0F0800EF8
-:05112B00E539B42009C4
-:091130009088027480F07539000A
-:021139007A003A
-:03113B00BA2800CF
-:02113E0050035C
-:031140000A80F82A
-:011143002289
-:04114400E56F6002F1
-:0211480080071E
-:07114A007A007539008005F1
-:051151007A4075391021
-:09115600E56E2AFAE56E2539F573
-:0A115F003990880274802AF07A00AB
-:08116900C3EA648094A850035E
-:031171000A80F5FC
-:011174002258
-:06117500AA70AB71AC7220
-:0C117B008A828B838CF01214EEFD601849
-:0D1187008D6DC002C003C00412110CD00415
-:09119400D003D0020ABA00010BDD
-:02119D0080DCF4
-:01119F00222D
-:0D11A000E573C4540FFA53020FC374099A8B
-:0211AD005006EA
-:0611AF0074372AFB8004E6
-:0411B50074302AFB6D
-:0C11B9008B6DC00312110CD003AA7353FD
-:0811C500020FC374099A5006E1
-:0611CD0074372AFB8004C8
-:0411D30074302AFB4F
-:0511D7008B6D12110CEC
-:0111DC0022F0
-:0711DD00907DC3E0FA600FF2
-:0C11E400907DC1E0F56E907DC2E0F56FDB
-:0311F00012114495
-:0C11F300907DFFE4F07570C475717D758F
-:0511FF007201121175E0
-:0112040022C7
-:021205007A0469
-:03120700BA4000EA
-:02120A0050365C
-:0E120C00EA24C0F582E4347DF583E0FB7C002B
-:03121A00BC08000D
-:02121D0050205F
-:06121F008B05ED30E70B2A
-:0B122500907F967442F074C3F08008C4
-:08123000907F96E4F07481F058
-:07123800EB25E0FB0C80DB5D
-:03123F000A80C55D
-:011242002289
-:041243007A007BEFC3
-:03124700BA1000DA
-:02124A00502032
-:0E124C0074112BFB2400FCE43418FD8C828D01
-:0E125A0083E4F0EA2400F582E43419F583E41D
-:04126800F00A80DB2D
-:01126C00225F
-:0E126D0074F82400F58274033484F583E4F0F1
-:0E127B0074F92400F58274033484F583E4F0E2
-:0E12890074FA2400F58274033484F583E4F0D3
-:0E12970074FB2400F58274033484F583E4F0C4
-:0E12A50074FF2400F58274033484F583E4F0B2
-:0112B3002218
-:0E12B4001203CB12126D7AC07B877C0174018D
-:0E12C2002AFDE43BFE8C078A828B838CF0743D
-:0E12D000011214BF2DFAE43EFB8F048D828EB6
-:0E12DE00838FF074061214BF74012AFDE43BE6
-:0E12EC00FE8C078A828B838CF0E41214BF7490
-:0E12FA00012DFAE43EFB8F048D828E838FF06F
-:0E130800740B1214BF74012AFDE43BFE8C0727
-:0E1316008A828B838CF074081214BF74012D30
-:0E132400FAE43EFB8F048D828E838FF07401FD
-:0E1332001214BF2AFDE43BFE8C078A828B83D7
-:0E1340008CF0E41214BF74012DFAE43EFB8F12
-:0E134E00048D828E838FF074031214BF7D0015
-:03135C00BD0600CB
-:02135F0050122A
-:0B1361008A828B838CF00ABA00010B1B
-:07136C00E41214BF0D80E93B
-:0D1373008A828B838CF0E5741214BF74F92C
-:0E1380002400F58274033484F583740FF07436
-:0E138E00FE2400F58274033484F5837401F0AC
-:06139C001203E11204F748
-:0113A2002228
-:0D13A300907DC1E0FA2400FBE43419FC90B9
-:0E13B0007DC2E0FD8B828C83F075F011EAA403
-:0313BE00FA7B00B7
-:0313C100BB10005E
-:0213C4005024B3
-:0E13C600EA2400FCE43418FDEB2CFCE43DFDB1
-:0E13D40074042B24C0F582E4347DF583E0FE22
-:0813E2008C828D83F00B80D793
-:0E13EA00EA2400FAE43418FB74102AF582E4B9
-:0513F8003BF583E4F069
-:0113FD0022CD
-:0413FE00E57660022E
-:02140200801652
-:0C140400740F5575FA8A752400F582E417
-:0A1410003419F583E0F5741212B4EC
-:0A141A001210CA756E00756F001203
-:0614240011447570B9755A
-:06142A007114757202123C
-:0B1430001175E576B402047401800120
-:01143B00E4CC
-:03143C00FA700F34
-:0C143F0074012575F573C0021211A0D0D5
-:03144B0002800A12
-:0A144E00857573C0021211A0D002D0
-:0C145800756E00756F01C002121144D0C7
-:0414640002EA701A0E
-:0D14680075F011E575A4FA2400FAE43418BB
-:09147500FB8A708B717572011283
-:04147E00117580362E
-:021482007A00EE
-:03148400BA10009B
-:02148700502FE4
-:0D148900EA2400F582E43419F583E0FBE568
-:0414960075B5031B0A
-:0E149A0075F011EAA4FB2400FBE43418FC8B6F
-:0914A800708C71757201C0021212
-:0414B1001175D002DF
-:0314B5000A80CCDE
-:0114B8002211
-:0614B90050726F67200075
-:0E14BF00C8C0E0C8C0E0E5F0600B14600F1478
-:0714CD00601114601280158C
-:0714D400D0E0A882F6800EB3
-:0514DB00D0E0F08009E3
-:0414E000D0E08005D3
-:0514E400D0E0A882F237
-:0414E900C8D0E0C8BF
-:0114ED0022DC
-:0E14EE00C8C0E0E5F0600D14600F14600F142C
-:0614FC00601074FF800F78
-:05150200A882E6800A4A
-:03150700E080077A
-:04150A00E4938003E3
-:03150E00A882E2CE
-:04151100F8D0E0C866
-:0115150022B3
-:00000001FF
-
- * Copyright (C) 1999 BayCom GmbH
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that redistributions of source
- * code retain the above copyright notice and this comment without
- * modification.
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 1a1e5e3b1ea..ab3a456f665 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -70,19 +70,6 @@ static void bdev_inode_switch_bdi(struct inode *inode,
spin_unlock(&dst->wb.list_lock);
}
-sector_t blkdev_max_block(struct block_device *bdev)
-{
- sector_t retval = ~((sector_t)0);
- loff_t sz = i_size_read(bdev->bd_inode);
-
- if (sz) {
- unsigned int size = block_size(bdev);
- unsigned int sizebits = blksize_bits(size);
- retval = (sz >> sizebits);
- }
- return retval;
-}
-
/* Kill _all_ buffers and pagecache , dirty or not.. */
void kill_bdev(struct block_device *bdev)
{
@@ -116,8 +103,6 @@ EXPORT_SYMBOL(invalidate_bdev);
int set_blocksize(struct block_device *bdev, int size)
{
- struct address_space *mapping;
-
/* Size must be a power of two, and between 512 and PAGE_SIZE */
if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size))
return -EINVAL;
@@ -126,19 +111,6 @@ int set_blocksize(struct block_device *bdev, int size)
if (size < bdev_logical_block_size(bdev))
return -EINVAL;
- /* Prevent starting I/O or mapping the device */
- percpu_down_write(&bdev->bd_block_size_semaphore);
-
- /* Check that the block device is not memory mapped */
- mapping = bdev->bd_inode->i_mapping;
- mutex_lock(&mapping->i_mmap_mutex);
- if (mapping_mapped(mapping)) {
- mutex_unlock(&mapping->i_mmap_mutex);
- percpu_up_write(&bdev->bd_block_size_semaphore);
- return -EBUSY;
- }
- mutex_unlock(&mapping->i_mmap_mutex);
-
/* Don't change the size if it is same as current */
if (bdev->bd_block_size != size) {
sync_blockdev(bdev);
@@ -146,9 +118,6 @@ int set_blocksize(struct block_device *bdev, int size)
bdev->bd_inode->i_blkbits = blksize_bits(size);
kill_bdev(bdev);
}
-
- percpu_up_write(&bdev->bd_block_size_semaphore);
-
return 0;
}
@@ -181,52 +150,12 @@ static int
blkdev_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh, int create)
{
- if (iblock >= blkdev_max_block(I_BDEV(inode))) {
- if (create)
- return -EIO;
-
- /*
- * for reads, we're just trying to fill a partial page.
- * return a hole, they will have to call get_block again
- * before they can fill it, and they will get -EIO at that
- * time
- */
- return 0;
- }
bh->b_bdev = I_BDEV(inode);
bh->b_blocknr = iblock;
set_buffer_mapped(bh);
return 0;
}
-static int
-blkdev_get_blocks(struct inode *inode, sector_t iblock,
- struct buffer_head *bh, int create)
-{
- sector_t end_block = blkdev_max_block(I_BDEV(inode));
- unsigned long max_blocks = bh->b_size >> inode->i_blkbits;
-
- if ((iblock + max_blocks) > end_block) {
- max_blocks = end_block - iblock;
- if ((long)max_blocks <= 0) {
- if (create)
- return -EIO; /* write fully beyond EOF */
- /*
- * It is a read which is fully beyond EOF. We return
- * a !buffer_mapped buffer
- */
- max_blocks = 0;
- }
- }
-
- bh->b_bdev = I_BDEV(inode);
- bh->b_blocknr = iblock;
- bh->b_size = max_blocks << inode->i_blkbits;
- if (max_blocks)
- set_buffer_mapped(bh);
- return 0;
-}
-
static ssize_t
blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
loff_t offset, unsigned long nr_segs)
@@ -235,7 +164,7 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
struct inode *inode = file->f_mapping->host;
return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset,
- nr_segs, blkdev_get_blocks, NULL, NULL, 0);
+ nr_segs, blkdev_get_block, NULL, NULL, 0);
}
int __sync_blockdev(struct block_device *bdev, int wait)
@@ -459,12 +388,6 @@ static struct inode *bdev_alloc_inode(struct super_block *sb)
struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL);
if (!ei)
return NULL;
-
- if (unlikely(percpu_init_rwsem(&ei->bdev.bd_block_size_semaphore))) {
- kmem_cache_free(bdev_cachep, ei);
- return NULL;
- }
-
return &ei->vfs_inode;
}
@@ -473,8 +396,6 @@ static void bdev_i_callback(struct rcu_head *head)
struct inode *inode = container_of(head, struct inode, i_rcu);
struct bdev_inode *bdi = BDEV_I(inode);
- percpu_free_rwsem(&bdi->bdev.bd_block_size_semaphore);
-
kmem_cache_free(bdev_cachep, bdi);
}
@@ -1593,22 +1514,6 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
return blkdev_ioctl(bdev, mode, cmd, arg);
}
-ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos)
-{
- ssize_t ret;
- struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host);
-
- percpu_down_read(&bdev->bd_block_size_semaphore);
-
- ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
-
- percpu_up_read(&bdev->bd_block_size_semaphore);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(blkdev_aio_read);
-
/*
* Write data to the block device. Only intended for the block device itself
* and the raw driver which basically is a fake block device.
@@ -1620,16 +1525,12 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
struct file *file = iocb->ki_filp;
- struct block_device *bdev = I_BDEV(file->f_mapping->host);
struct blk_plug plug;
ssize_t ret;
BUG_ON(iocb->ki_pos != pos);
blk_start_plug(&plug);
-
- percpu_down_read(&bdev->bd_block_size_semaphore);
-
ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
if (ret > 0 || ret == -EIOCBQUEUED) {
ssize_t err;
@@ -1638,62 +1539,27 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
if (err < 0 && ret > 0)
ret = err;
}
-
- percpu_up_read(&bdev->bd_block_size_semaphore);
-
blk_finish_plug(&plug);
-
return ret;
}
EXPORT_SYMBOL_GPL(blkdev_aio_write);
-static int blkdev_mmap(struct file *file, struct vm_area_struct *vma)
-{
- int ret;
- struct block_device *bdev = I_BDEV(file->f_mapping->host);
-
- percpu_down_read(&bdev->bd_block_size_semaphore);
-
- ret = generic_file_mmap(file, vma);
-
- percpu_up_read(&bdev->bd_block_size_semaphore);
-
- return ret;
-}
-
-static ssize_t blkdev_splice_read(struct file *file, loff_t *ppos,
- struct pipe_inode_info *pipe, size_t len,
- unsigned int flags)
-{
- ssize_t ret;
- struct block_device *bdev = I_BDEV(file->f_mapping->host);
-
- percpu_down_read(&bdev->bd_block_size_semaphore);
-
- ret = generic_file_splice_read(file, ppos, pipe, len, flags);
-
- percpu_up_read(&bdev->bd_block_size_semaphore);
-
- return ret;
-}
-
-static ssize_t blkdev_splice_write(struct pipe_inode_info *pipe,
- struct file *file, loff_t *ppos, size_t len,
- unsigned int flags)
+static ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
{
- ssize_t ret;
- struct block_device *bdev = I_BDEV(file->f_mapping->host);
-
- percpu_down_read(&bdev->bd_block_size_semaphore);
-
- ret = generic_file_splice_write(pipe, file, ppos, len, flags);
+ struct file *file = iocb->ki_filp;
+ struct inode *bd_inode = file->f_mapping->host;
+ loff_t size = i_size_read(bd_inode);
- percpu_up_read(&bdev->bd_block_size_semaphore);
+ if (pos >= size)
+ return 0;
- return ret;
+ size -= pos;
+ if (size < INT_MAX)
+ nr_segs = iov_shorten((struct iovec *)iov, nr_segs, size);
+ return generic_file_aio_read(iocb, iov, nr_segs, pos);
}
-
/*
* Try to release a page associated with block device when the system
* is under memory pressure.
@@ -1724,16 +1590,16 @@ const struct file_operations def_blk_fops = {
.llseek = block_llseek,
.read = do_sync_read,
.write = do_sync_write,
- .aio_read = blkdev_aio_read,
+ .aio_read = blkdev_aio_read,
.aio_write = blkdev_aio_write,
- .mmap = blkdev_mmap,
+ .mmap = generic_file_mmap,
.fsync = blkdev_fsync,
.unlocked_ioctl = block_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_blkdev_ioctl,
#endif
- .splice_read = blkdev_splice_read,
- .splice_write = blkdev_splice_write,
+ .splice_read = generic_file_splice_read,
+ .splice_write = generic_file_splice_write,
};
int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 7cda51995c1..22a0439e5a8 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3416,8 +3416,8 @@ void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
num_dirty = root->fs_info->dirty_metadata_bytes;
if (num_dirty > thresh) {
- balance_dirty_pages_ratelimited_nr(
- root->fs_info->btree_inode->i_mapping, 1);
+ balance_dirty_pages_ratelimited(
+ root->fs_info->btree_inode->i_mapping);
}
return;
}
@@ -3437,8 +3437,8 @@ void __btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
num_dirty = root->fs_info->dirty_metadata_bytes;
if (num_dirty > thresh) {
- balance_dirty_pages_ratelimited_nr(
- root->fs_info->btree_inode->i_mapping, 1);
+ balance_dirty_pages_ratelimited(
+ root->fs_info->btree_inode->i_mapping);
}
return;
}
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 9ab1bed8811..a8ee75cb96e 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1346,8 +1346,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
cond_resched();
- balance_dirty_pages_ratelimited_nr(inode->i_mapping,
- dirty_pages);
+ balance_dirty_pages_ratelimited(inode->i_mapping);
if (dirty_pages < (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
btrfs_btree_balance_dirty(root, 1);
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 8fcf9a59c28..5b3429ab8ec 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1225,7 +1225,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
}
defrag_count += ret;
- balance_dirty_pages_ratelimited_nr(inode->i_mapping, ret);
+ balance_dirty_pages_ratelimited(inode->i_mapping);
mutex_unlock(&inode->i_mutex);
if (newer_than) {
diff --git a/fs/buffer.c b/fs/buffer.c
index b5f044283ed..6e9ed48064f 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -555,7 +555,7 @@ void emergency_thaw_all(void)
*/
int sync_mapping_buffers(struct address_space *mapping)
{
- struct address_space *buffer_mapping = mapping->assoc_mapping;
+ struct address_space *buffer_mapping = mapping->private_data;
if (buffer_mapping == NULL || list_empty(&mapping->private_list))
return 0;
@@ -588,10 +588,10 @@ void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode)
struct address_space *buffer_mapping = bh->b_page->mapping;
mark_buffer_dirty(bh);
- if (!mapping->assoc_mapping) {
- mapping->assoc_mapping = buffer_mapping;
+ if (!mapping->private_data) {
+ mapping->private_data = buffer_mapping;
} else {
- BUG_ON(mapping->assoc_mapping != buffer_mapping);
+ BUG_ON(mapping->private_data != buffer_mapping);
}
if (!bh->b_assoc_map) {
spin_lock(&buffer_mapping->private_lock);
@@ -788,7 +788,7 @@ void invalidate_inode_buffers(struct inode *inode)
if (inode_has_buffers(inode)) {
struct address_space *mapping = &inode->i_data;
struct list_head *list = &mapping->private_list;
- struct address_space *buffer_mapping = mapping->assoc_mapping;
+ struct address_space *buffer_mapping = mapping->private_data;
spin_lock(&buffer_mapping->private_lock);
while (!list_empty(list))
@@ -811,7 +811,7 @@ int remove_inode_buffers(struct inode *inode)
if (inode_has_buffers(inode)) {
struct address_space *mapping = &inode->i_data;
struct list_head *list = &mapping->private_list;
- struct address_space *buffer_mapping = mapping->assoc_mapping;
+ struct address_space *buffer_mapping = mapping->private_data;
spin_lock(&buffer_mapping->private_lock);
while (!list_empty(list)) {
@@ -911,6 +911,18 @@ link_dev_buffers(struct page *page, struct buffer_head *head)
attach_page_buffers(page, head);
}
+static sector_t blkdev_max_block(struct block_device *bdev, unsigned int size)
+{
+ sector_t retval = ~((sector_t)0);
+ loff_t sz = i_size_read(bdev->bd_inode);
+
+ if (sz) {
+ unsigned int sizebits = blksize_bits(size);
+ retval = (sz >> sizebits);
+ }
+ return retval;
+}
+
/*
* Initialise the state of a blockdev page's buffers.
*/
@@ -921,7 +933,7 @@ init_page_buffers(struct page *page, struct block_device *bdev,
struct buffer_head *head = page_buffers(page);
struct buffer_head *bh = head;
int uptodate = PageUptodate(page);
- sector_t end_block = blkdev_max_block(I_BDEV(bdev->bd_inode));
+ sector_t end_block = blkdev_max_block(I_BDEV(bdev->bd_inode), size);
do {
if (!buffer_mapped(bh)) {
@@ -1553,6 +1565,28 @@ void unmap_underlying_metadata(struct block_device *bdev, sector_t block)
EXPORT_SYMBOL(unmap_underlying_metadata);
/*
+ * Size is a power-of-two in the range 512..PAGE_SIZE,
+ * and the case we care about most is PAGE_SIZE.
+ *
+ * So this *could* possibly be written with those
+ * constraints in mind (relevant mostly if some
+ * architecture has a slow bit-scan instruction)
+ */
+static inline int block_size_bits(unsigned int blocksize)
+{
+ return ilog2(blocksize);
+}
+
+static struct buffer_head *create_page_buffers(struct page *page, struct inode *inode, unsigned int b_state)
+{
+ BUG_ON(!PageLocked(page));
+
+ if (!page_has_buffers(page))
+ create_empty_buffers(page, 1 << ACCESS_ONCE(inode->i_blkbits), b_state);
+ return page_buffers(page);
+}
+
+/*
* NOTE! All mapped/uptodate combinations are valid:
*
* Mapped Uptodate Meaning
@@ -1589,19 +1623,13 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
sector_t block;
sector_t last_block;
struct buffer_head *bh, *head;
- const unsigned blocksize = 1 << inode->i_blkbits;
+ unsigned int blocksize, bbits;
int nr_underway = 0;
int write_op = (wbc->sync_mode == WB_SYNC_ALL ?
WRITE_SYNC : WRITE);
- BUG_ON(!PageLocked(page));
-
- last_block = (i_size_read(inode) - 1) >> inode->i_blkbits;
-
- if (!page_has_buffers(page)) {
- create_empty_buffers(page, blocksize,
+ head = create_page_buffers(page, inode,
(1 << BH_Dirty)|(1 << BH_Uptodate));
- }
/*
* Be very careful. We have no exclusion from __set_page_dirty_buffers
@@ -1613,9 +1641,12 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
* handle that here by just cleaning them.
*/
- block = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
- head = page_buffers(page);
bh = head;
+ blocksize = bh->b_size;
+ bbits = block_size_bits(blocksize);
+
+ block = (sector_t)page->index << (PAGE_CACHE_SHIFT - bbits);
+ last_block = (i_size_read(inode) - 1) >> bbits;
/*
* Get all the dirty buffers mapped to disk addresses and
@@ -1806,12 +1837,10 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len,
BUG_ON(to > PAGE_CACHE_SIZE);
BUG_ON(from > to);
- blocksize = 1 << inode->i_blkbits;
- if (!page_has_buffers(page))
- create_empty_buffers(page, blocksize, 0);
- head = page_buffers(page);
+ head = create_page_buffers(page, inode, 0);
+ blocksize = head->b_size;
+ bbits = block_size_bits(blocksize);
- bbits = inode->i_blkbits;
block = (sector_t)page->index << (PAGE_CACHE_SHIFT - bbits);
for(bh = head, block_start = 0; bh != head || !block_start;
@@ -1881,11 +1910,11 @@ static int __block_commit_write(struct inode *inode, struct page *page,
unsigned blocksize;
struct buffer_head *bh, *head;
- blocksize = 1 << inode->i_blkbits;
+ bh = head = page_buffers(page);
+ blocksize = bh->b_size;
- for(bh = head = page_buffers(page), block_start = 0;
- bh != head || !block_start;
- block_start=block_end, bh = bh->b_this_page) {
+ block_start = 0;
+ do {
block_end = block_start + blocksize;
if (block_end <= from || block_start >= to) {
if (!buffer_uptodate(bh))
@@ -1895,7 +1924,10 @@ static int __block_commit_write(struct inode *inode, struct page *page,
mark_buffer_dirty(bh);
}
clear_buffer_new(bh);
- }
+
+ block_start = block_end;
+ bh = bh->b_this_page;
+ } while (bh != head);
/*
* If this is a partial write which happened to make all buffers
@@ -2020,7 +2052,6 @@ EXPORT_SYMBOL(generic_write_end);
int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc,
unsigned long from)
{
- struct inode *inode = page->mapping->host;
unsigned block_start, block_end, blocksize;
unsigned to;
struct buffer_head *bh, *head;
@@ -2029,13 +2060,13 @@ int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc,
if (!page_has_buffers(page))
return 0;
- blocksize = 1 << inode->i_blkbits;
+ head = page_buffers(page);
+ blocksize = head->b_size;
to = min_t(unsigned, PAGE_CACHE_SIZE - from, desc->count);
to = from + to;
if (from < blocksize && to > PAGE_CACHE_SIZE - blocksize)
return 0;
- head = page_buffers(page);
bh = head;
block_start = 0;
do {
@@ -2068,18 +2099,16 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
struct inode *inode = page->mapping->host;
sector_t iblock, lblock;
struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
- unsigned int blocksize;
+ unsigned int blocksize, bbits;
int nr, i;
int fully_mapped = 1;
- BUG_ON(!PageLocked(page));
- blocksize = 1 << inode->i_blkbits;
- if (!page_has_buffers(page))
- create_empty_buffers(page, blocksize, 0);
- head = page_buffers(page);
+ head = create_page_buffers(page, inode, 0);
+ blocksize = head->b_size;
+ bbits = block_size_bits(blocksize);
- iblock = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
- lblock = (i_size_read(inode)+blocksize-1) >> inode->i_blkbits;
+ iblock = (sector_t)page->index << (PAGE_CACHE_SHIFT - bbits);
+ lblock = (i_size_read(inode)+blocksize-1) >> bbits;
bh = head;
nr = 0;
i = 0;
@@ -2864,6 +2893,55 @@ static void end_bio_bh_io_sync(struct bio *bio, int err)
bio_put(bio);
}
+/*
+ * This allows us to do IO even on the odd last sectors
+ * of a device, even if the bh block size is some multiple
+ * of the physical sector size.
+ *
+ * We'll just truncate the bio to the size of the device,
+ * and clear the end of the buffer head manually.
+ *
+ * Truly out-of-range accesses will turn into actual IO
+ * errors, this only handles the "we need to be able to
+ * do IO at the final sector" case.
+ */
+static void guard_bh_eod(int rw, struct bio *bio, struct buffer_head *bh)
+{
+ sector_t maxsector;
+ unsigned bytes;
+
+ maxsector = i_size_read(bio->bi_bdev->bd_inode) >> 9;
+ if (!maxsector)
+ return;
+
+ /*
+ * If the *whole* IO is past the end of the device,
+ * let it through, and the IO layer will turn it into
+ * an EIO.
+ */
+ if (unlikely(bio->bi_sector >= maxsector))
+ return;
+
+ maxsector -= bio->bi_sector;
+ bytes = bio->bi_size;
+ if (likely((bytes >> 9) <= maxsector))
+ return;
+
+ /* Uhhuh. We've got a bh that straddles the device size! */
+ bytes = maxsector << 9;
+
+ /* Truncate the bio.. */
+ bio->bi_size = bytes;
+ bio->bi_io_vec[0].bv_len = bytes;
+
+ /* ..and clear the end of the buffer for reads */
+ if ((rw & RW_MASK) == READ) {
+ void *kaddr = kmap_atomic(bh->b_page);
+ memset(kaddr + bh_offset(bh) + bytes, 0, bh->b_size - bytes);
+ kunmap_atomic(kaddr);
+ }
+}
+
int submit_bh(int rw, struct buffer_head * bh)
{
struct bio *bio;
@@ -2900,6 +2978,9 @@ int submit_bh(int rw, struct buffer_head * bh)
bio->bi_end_io = end_bio_bh_io_sync;
bio->bi_private = bh;
+ /* Take care of bh's that straddle the end of the device */
+ guard_bh_eod(rw, bio, bh);
+
bio_get(bio);
submit_bio(rw, bio);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index edb25b4bbb9..70b6f4c3a0c 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1794,7 +1794,6 @@ static int cifs_writepages(struct address_space *mapping,
struct TCP_Server_Info *server;
struct page *page;
int rc = 0;
- loff_t isize = i_size_read(mapping->host);
/*
* If wsize is smaller than the page cache size, default to writing
@@ -1899,7 +1898,7 @@ retry:
*/
set_page_writeback(page);
- if (page_offset(page) >= isize) {
+ if (page_offset(page) >= i_size_read(mapping->host)) {
done = true;
unlock_page(page);
end_page_writeback(page);
@@ -1932,7 +1931,8 @@ retry:
wdata->offset = page_offset(wdata->pages[0]);
wdata->pagesz = PAGE_CACHE_SIZE;
wdata->tailsz =
- min(isize - page_offset(wdata->pages[nr_pages - 1]),
+ min(i_size_read(mapping->host) -
+ page_offset(wdata->pages[nr_pages - 1]),
(loff_t)PAGE_CACHE_SIZE);
wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) +
wdata->tailsz;
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index f9b5d3d6cf3..1c576e87136 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -86,14 +86,17 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
dentry = d_lookup(parent, name);
if (dentry) {
+ int err;
inode = dentry->d_inode;
/* update inode in place if i_ino didn't change */
if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) {
cifs_fattr_to_inode(inode, fattr);
return dentry;
}
- d_drop(dentry);
+ err = d_invalidate(dentry);
dput(dentry);
+ if (err)
+ return NULL;
}
dentry = d_alloc(parent, name);
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index 56cc4be8780..34cea279833 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -766,7 +766,6 @@ smb_set_file_info(struct inode *inode, const char *full_path,
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = NULL;
struct cifs_tcon *tcon;
- FILE_BASIC_INFO info_buf;
/* if the file is already open for write, just use that fileid */
open_file = find_writable_file(cinode, true);
@@ -817,7 +816,7 @@ smb_set_file_info(struct inode *inode, const char *full_path,
netpid = current->tgid;
set_via_filehandle:
- rc = CIFSSMBSetFileInfo(xid, tcon, &info_buf, netfid, netpid);
+ rc = CIFSSMBSetFileInfo(xid, tcon, buf, netfid, netpid);
if (!rc)
cinode->cifsAttrs = le32_to_cpu(buf->Attributes);
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 4c6285fff59..e2f57a00702 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -844,6 +844,9 @@ COMPATIBLE_IOCTL(TIOCGDEV)
COMPATIBLE_IOCTL(TIOCCBRK)
COMPATIBLE_IOCTL(TIOCGSID)
COMPATIBLE_IOCTL(TIOCGICOUNT)
+COMPATIBLE_IOCTL(TIOCGPKT)
+COMPATIBLE_IOCTL(TIOCGPTLCK)
+COMPATIBLE_IOCTL(TIOCGEXCL)
/* Little t */
COMPATIBLE_IOCTL(TIOCGETD)
COMPATIBLE_IOCTL(TIOCSETD)
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index b607d92cdf2..153bb1e42e6 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -59,7 +59,6 @@ static struct inode *debugfs_get_inode(struct super_block *sb, umode_t mode, dev
case S_IFDIR:
inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
- inode->i_private = NULL;
/* directory inodes start off with i_nlink == 2
* (for "." entry) */
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 14afbabe654..472e6befc54 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -545,37 +545,38 @@ void devpts_kill_index(struct inode *ptmx_inode, int idx)
mutex_unlock(&allocated_ptys_lock);
}
-int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty)
+/**
+ * devpts_pty_new -- create a new inode in /dev/pts/
+ * @ptmx_inode: inode of the master
+ * @device: major+minor of the node to be created
+ * @index: used as a name of the node
+ * @priv: what's given back by devpts_get_priv
+ *
+ * The created inode is returned. Remove it from /dev/pts/ by devpts_pty_kill.
+ */
+struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index,
+ void *priv)
{
- /* tty layer puts index from devpts_new_index() in here */
- int number = tty->index;
- struct tty_driver *driver = tty->driver;
- dev_t device = MKDEV(driver->major, driver->minor_start+number);
struct dentry *dentry;
struct super_block *sb = pts_sb_from_inode(ptmx_inode);
- struct inode *inode = new_inode(sb);
+ struct inode *inode;
struct dentry *root = sb->s_root;
struct pts_fs_info *fsi = DEVPTS_SB(sb);
struct pts_mount_opts *opts = &fsi->mount_opts;
- int ret = 0;
char s[12];
- /* We're supposed to be given the slave end of a pty */
- BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY);
- BUG_ON(driver->subtype != PTY_TYPE_SLAVE);
-
+ inode = new_inode(sb);
if (!inode)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
- inode->i_ino = number + 3;
+ inode->i_ino = index + 3;
inode->i_uid = opts->setuid ? opts->uid : current_fsuid();
inode->i_gid = opts->setgid ? opts->gid : current_fsgid();
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
init_special_inode(inode, S_IFCHR|opts->mode, device);
- inode->i_private = tty;
- tty->driver_data = inode;
+ inode->i_private = priv;
- sprintf(s, "%d", number);
+ sprintf(s, "%d", index);
mutex_lock(&root->d_inode->i_mutex);
@@ -585,18 +586,24 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty)
fsnotify_create(root->d_inode, dentry);
} else {
iput(inode);
- ret = -ENOMEM;
+ inode = ERR_PTR(-ENOMEM);
}
mutex_unlock(&root->d_inode->i_mutex);
- return ret;
+ return inode;
}
-struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number)
+/**
+ * devpts_get_priv -- get private data for a slave
+ * @pts_inode: inode of the slave
+ *
+ * Returns whatever was passed as priv in devpts_pty_new for a given inode.
+ */
+void *devpts_get_priv(struct inode *pts_inode)
{
struct dentry *dentry;
- struct tty_struct *tty;
+ void *priv = NULL;
BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
@@ -605,18 +612,22 @@ struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number)
if (!dentry)
return NULL;
- tty = NULL;
if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
- tty = (struct tty_struct *)pts_inode->i_private;
+ priv = pts_inode->i_private;
dput(dentry);
- return tty;
+ return priv;
}
-void devpts_pty_kill(struct tty_struct *tty)
+/**
+ * devpts_pty_kill -- remove inode form /dev/pts/
+ * @inode: inode of the slave to be removed
+ *
+ * This is an inverse operation of devpts_pty_new.
+ */
+void devpts_pty_kill(struct inode *inode)
{
- struct inode *inode = tty->driver_data;
struct super_block *sb = pts_sb_from_inode(inode);
struct dentry *root = sb->s_root;
struct dentry *dentry;
diff --git a/fs/direct-io.c b/fs/direct-io.c
index f86c720dba0..cf5b44b10c6 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -540,6 +540,7 @@ static int get_more_blocks(struct dio *dio, struct dio_submit *sdio,
sector_t fs_endblk; /* Into file, in filesystem-sized blocks */
unsigned long fs_count; /* Number of filesystem-sized blocks */
int create;
+ unsigned int i_blkbits = sdio->blkbits + sdio->blkfactor;
/*
* If there was a memory error and we've overwritten all the
@@ -554,7 +555,7 @@ static int get_more_blocks(struct dio *dio, struct dio_submit *sdio,
fs_count = fs_endblk - fs_startblk + 1;
map_bh->b_state = 0;
- map_bh->b_size = fs_count << dio->inode->i_blkbits;
+ map_bh->b_size = fs_count << i_blkbits;
/*
* For writes inside i_size on a DIO_SKIP_HOLES filesystem we
@@ -1053,7 +1054,8 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
int seg;
size_t size;
unsigned long addr;
- unsigned blkbits = inode->i_blkbits;
+ unsigned i_blkbits = ACCESS_ONCE(inode->i_blkbits);
+ unsigned blkbits = i_blkbits;
unsigned blocksize_mask = (1 << blkbits) - 1;
ssize_t retval = -EINVAL;
loff_t end = offset;
@@ -1149,7 +1151,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
dio->inode = inode;
dio->rw = rw;
sdio.blkbits = blkbits;
- sdio.blkfactor = inode->i_blkbits - blkbits;
+ sdio.blkfactor = i_blkbits - blkbits;
sdio.block_in_file = offset >> blkbits;
sdio.get_block = get_block;
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 7320a66e958..22548f56197 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -2101,8 +2101,9 @@ int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range)
end = start + (range->len >> sb->s_blocksize_bits) - 1;
minlen = range->minlen >> sb->s_blocksize_bits;
- if (unlikely(minlen > EXT3_BLOCKS_PER_GROUP(sb)) ||
- unlikely(start >= max_blks))
+ if (minlen > EXT3_BLOCKS_PER_GROUP(sb) ||
+ start >= max_blks ||
+ range->len < sb->s_blocksize)
return -EINVAL;
if (end >= max_blks)
end = max_blks - 1;
diff --git a/fs/file.c b/fs/file.c
index 708d997a774..eff23162485 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -685,7 +685,6 @@ void do_close_on_exec(struct files_struct *files)
struct fdtable *fdt;
/* exec unshares first */
- BUG_ON(atomic_read(&files->count) != 1);
spin_lock(&files->file_lock);
for (i = 0; ; i++) {
unsigned long set;
@@ -995,16 +994,18 @@ int iterate_fd(struct files_struct *files, unsigned n,
const void *p)
{
struct fdtable *fdt;
- struct file *file;
int res = 0;
if (!files)
return 0;
spin_lock(&files->file_lock);
- fdt = files_fdtable(files);
- while (!res && n < fdt->max_fds) {
- file = rcu_dereference_check_fdtable(files, fdt->fd[n++]);
- if (file)
- res = f(p, file, n);
+ for (fdt = files_fdtable(files); n < fdt->max_fds; n++) {
+ struct file *file;
+ file = rcu_dereference_check_fdtable(files, fdt->fd[n]);
+ if (!file)
+ continue;
+ res = f(p, file, n);
+ if (res)
+ break;
}
spin_unlock(&files->file_lock);
return res;
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 51ea267d444..3e3422f7f0a 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -228,6 +228,8 @@ static void requeue_io(struct inode *inode, struct bdi_writeback *wb)
static void inode_sync_complete(struct inode *inode)
{
inode->i_state &= ~I_SYNC;
+ /* If inode is clean an unused, put it into LRU now... */
+ inode_add_lru(inode);
/* Waiters must see I_SYNC cleared before being woken up */
smp_mb();
wake_up_bit(&inode->i_state, __I_SYNC);
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index e6c2fd53cab..0f22d09f358 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -768,7 +768,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
mapping->host = s->s_bdev->bd_inode;
mapping->flags = 0;
mapping_set_gfp_mask(mapping, GFP_NOFS);
- mapping->assoc_mapping = NULL;
+ mapping->private_data = NULL;
mapping->backing_dev_info = s->s_bdi;
mapping->writeback_index = 0;
}
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index c5bc355d824..4a55f35a6ce 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -151,8 +151,8 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
- unsigned long start_addr;
struct hstate *h = hstate_file(file);
+ struct vm_unmapped_area_info info;
if (len & ~huge_page_mask(h))
return -EINVAL;
@@ -173,39 +173,13 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
return addr;
}
- if (len > mm->cached_hole_size)
- start_addr = mm->free_area_cache;
- else {
- start_addr = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = 0;
- }
-
-full_search:
- addr = ALIGN(start_addr, huge_page_size(h));
-
- for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
- /* At this point: (!vma || addr < vma->vm_end). */
- if (TASK_SIZE - len < addr) {
- /*
- * Start a new search - just in case we missed
- * some holes.
- */
- if (start_addr != TASK_UNMAPPED_BASE) {
- start_addr = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = 0;
- goto full_search;
- }
- return -ENOMEM;
- }
-
- if (!vma || addr + len <= vma->vm_start) {
- mm->free_area_cache = addr + len;
- return addr;
- }
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
- addr = ALIGN(vma->vm_end, huge_page_size(h));
- }
+ info.flags = 0;
+ info.length = len;
+ info.low_limit = TASK_UNMAPPED_BASE;
+ info.high_limit = TASK_SIZE;
+ info.align_mask = PAGE_MASK & ~huge_page_mask(h);
+ info.align_offset = 0;
+ return vm_unmapped_area(&info);
}
#endif
@@ -608,11 +582,11 @@ static int hugetlbfs_migrate_page(struct address_space *mapping,
int rc;
rc = migrate_huge_page_move_mapping(mapping, newpage, page);
- if (rc)
+ if (rc != MIGRATEPAGE_SUCCESS)
return rc;
migrate_page_copy(newpage, page);
- return 0;
+ return MIGRATEPAGE_SUCCESS;
}
static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -923,7 +897,7 @@ static struct file_system_type hugetlbfs_fs_type = {
.kill_sb = kill_litter_super,
};
-static struct vfsmount *hugetlbfs_vfsmount;
+static struct vfsmount *hugetlbfs_vfsmount[HUGE_MAX_HSTATE];
static int can_do_hugetlb_shm(void)
{
@@ -932,9 +906,22 @@ static int can_do_hugetlb_shm(void)
return capable(CAP_IPC_LOCK) || in_group_p(shm_group);
}
+static int get_hstate_idx(int page_size_log)
+{
+ struct hstate *h;
+
+ if (!page_size_log)
+ return default_hstate_idx;
+ h = size_to_hstate(1 << page_size_log);
+ if (!h)
+ return -1;
+ return h - hstates;
+}
+
struct file *hugetlb_file_setup(const char *name, unsigned long addr,
size_t size, vm_flags_t acctflag,
- struct user_struct **user, int creat_flags)
+ struct user_struct **user,
+ int creat_flags, int page_size_log)
{
int error = -ENOMEM;
struct file *file;
@@ -944,9 +931,14 @@ struct file *hugetlb_file_setup(const char *name, unsigned long addr,
struct qstr quick_string;
struct hstate *hstate;
unsigned long num_pages;
+ int hstate_idx;
+
+ hstate_idx = get_hstate_idx(page_size_log);
+ if (hstate_idx < 0)
+ return ERR_PTR(-ENODEV);
*user = NULL;
- if (!hugetlbfs_vfsmount)
+ if (!hugetlbfs_vfsmount[hstate_idx])
return ERR_PTR(-ENOENT);
if (creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm()) {
@@ -963,7 +955,7 @@ struct file *hugetlb_file_setup(const char *name, unsigned long addr,
}
}
- root = hugetlbfs_vfsmount->mnt_root;
+ root = hugetlbfs_vfsmount[hstate_idx]->mnt_root;
quick_string.name = name;
quick_string.len = strlen(quick_string.name);
quick_string.hash = 0;
@@ -971,7 +963,7 @@ struct file *hugetlb_file_setup(const char *name, unsigned long addr,
if (!path.dentry)
goto out_shm_unlock;
- path.mnt = mntget(hugetlbfs_vfsmount);
+ path.mnt = mntget(hugetlbfs_vfsmount[hstate_idx]);
error = -ENOSPC;
inode = hugetlbfs_get_inode(root->d_sb, NULL, S_IFREG | S_IRWXUGO, 0);
if (!inode)
@@ -1011,8 +1003,9 @@ out_shm_unlock:
static int __init init_hugetlbfs_fs(void)
{
+ struct hstate *h;
int error;
- struct vfsmount *vfsmount;
+ int i;
error = bdi_init(&hugetlbfs_backing_dev_info);
if (error)
@@ -1029,14 +1022,26 @@ static int __init init_hugetlbfs_fs(void)
if (error)
goto out;
- vfsmount = kern_mount(&hugetlbfs_fs_type);
+ i = 0;
+ for_each_hstate(h) {
+ char buf[50];
+ unsigned ps_kb = 1U << (h->order + PAGE_SHIFT - 10);
- if (!IS_ERR(vfsmount)) {
- hugetlbfs_vfsmount = vfsmount;
- return 0;
- }
+ snprintf(buf, sizeof(buf), "pagesize=%uK", ps_kb);
+ hugetlbfs_vfsmount[i] = kern_mount_data(&hugetlbfs_fs_type,
+ buf);
- error = PTR_ERR(vfsmount);
+ if (IS_ERR(hugetlbfs_vfsmount[i])) {
+ pr_err("hugetlb: Cannot mount internal hugetlbfs for "
+ "page size %uK", ps_kb);
+ error = PTR_ERR(hugetlbfs_vfsmount[i]);
+ hugetlbfs_vfsmount[i] = NULL;
+ }
+ i++;
+ }
+ /* Non default hstates are optional */
+ if (!IS_ERR_OR_NULL(hugetlbfs_vfsmount[default_hstate_idx]))
+ return 0;
out:
kmem_cache_destroy(hugetlbfs_inode_cachep);
@@ -1047,13 +1052,19 @@ static int __init init_hugetlbfs_fs(void)
static void __exit exit_hugetlbfs_fs(void)
{
+ struct hstate *h;
+ int i;
+
+
/*
* Make sure all delayed rcu free inodes are flushed before we
* destroy cache.
*/
rcu_barrier();
kmem_cache_destroy(hugetlbfs_inode_cachep);
- kern_unmount(hugetlbfs_vfsmount);
+ i = 0;
+ for_each_hstate(h)
+ kern_unmount(hugetlbfs_vfsmount[i++]);
unregister_filesystem(&hugetlbfs_fs_type);
bdi_destroy(&hugetlbfs_backing_dev_info);
}
diff --git a/fs/inode.c b/fs/inode.c
index b03c7195724..14084b72b25 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -165,7 +165,7 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
mapping->host = inode;
mapping->flags = 0;
mapping_set_gfp_mask(mapping, GFP_HIGHUSER_MOVABLE);
- mapping->assoc_mapping = NULL;
+ mapping->private_data = NULL;
mapping->backing_dev_info = &default_backing_dev_info;
mapping->writeback_index = 0;
@@ -408,6 +408,19 @@ static void inode_lru_list_add(struct inode *inode)
spin_unlock(&inode->i_sb->s_inode_lru_lock);
}
+/*
+ * Add inode to LRU if needed (inode is unused and clean).
+ *
+ * Needs inode->i_lock held.
+ */
+void inode_add_lru(struct inode *inode)
+{
+ if (!(inode->i_state & (I_DIRTY | I_SYNC | I_FREEING | I_WILL_FREE)) &&
+ !atomic_read(&inode->i_count) && inode->i_sb->s_flags & MS_ACTIVE)
+ inode_lru_list_add(inode);
+}
+
+
static void inode_lru_list_del(struct inode *inode)
{
spin_lock(&inode->i_sb->s_inode_lru_lock);
@@ -1390,8 +1403,7 @@ static void iput_final(struct inode *inode)
if (!drop && (sb->s_flags & MS_ACTIVE)) {
inode->i_state |= I_REFERENCED;
- if (!(inode->i_state & (I_DIRTY|I_SYNC)))
- inode_lru_list_add(inode);
+ inode_add_lru(inode);
spin_unlock(&inode->i_lock);
return;
}
diff --git a/fs/internal.h b/fs/internal.h
index 916b7cbf3e3..2f6af7f645e 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -110,6 +110,7 @@ extern int open_check_o_direct(struct file *f);
* inode.c
*/
extern spinlock_t inode_sb_list_lock;
+extern void inode_add_lru(struct inode *inode);
/*
* fs-writeback.c
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 78b7f84241d..7f5120bf0ec 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -1961,7 +1961,9 @@ retry:
spin_unlock(&journal->j_list_lock);
jbd_unlock_bh_state(bh);
spin_unlock(&journal->j_state_lock);
+ unlock_buffer(bh);
log_wait_commit(journal, tid);
+ lock_buffer(bh);
goto retry;
}
/*
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 60ef3fb707f..1506673c087 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -138,33 +138,39 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
struct page *pg;
struct inode *inode = mapping->host;
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+ struct jffs2_raw_inode ri;
+ uint32_t alloc_len = 0;
pgoff_t index = pos >> PAGE_CACHE_SHIFT;
uint32_t pageofs = index << PAGE_CACHE_SHIFT;
int ret = 0;
+ jffs2_dbg(1, "%s()\n", __func__);
+
+ if (pageofs > inode->i_size) {
+ ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
+ ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
+ if (ret)
+ return ret;
+ }
+
+ mutex_lock(&f->sem);
pg = grab_cache_page_write_begin(mapping, index, flags);
- if (!pg)
+ if (!pg) {
+ if (alloc_len)
+ jffs2_complete_reservation(c);
+ mutex_unlock(&f->sem);
return -ENOMEM;
+ }
*pagep = pg;
- jffs2_dbg(1, "%s()\n", __func__);
-
- if (pageofs > inode->i_size) {
+ if (alloc_len) {
/* Make new hole frag from old EOF to new page */
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
- struct jffs2_raw_inode ri;
struct jffs2_full_dnode *fn;
- uint32_t alloc_len;
jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
(unsigned int)inode->i_size, pageofs);
- ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
- ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
- if (ret)
- goto out_page;
-
- mutex_lock(&f->sem);
memset(&ri, 0, sizeof(ri));
ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -191,7 +197,6 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
if (IS_ERR(fn)) {
ret = PTR_ERR(fn);
jffs2_complete_reservation(c);
- mutex_unlock(&f->sem);
goto out_page;
}
ret = jffs2_add_full_dnode_to_inode(c, f, fn);
@@ -206,12 +211,10 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
jffs2_mark_node_obsolete(c, fn->raw);
jffs2_free_full_dnode(fn);
jffs2_complete_reservation(c);
- mutex_unlock(&f->sem);
goto out_page;
}
jffs2_complete_reservation(c);
inode->i_size = pageofs;
- mutex_unlock(&f->sem);
}
/*
@@ -220,18 +223,18 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
* case of a short-copy.
*/
if (!PageUptodate(pg)) {
- mutex_lock(&f->sem);
ret = jffs2_do_readpage_nolock(inode, pg);
- mutex_unlock(&f->sem);
if (ret)
goto out_page;
}
+ mutex_unlock(&f->sem);
jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
return ret;
out_page:
unlock_page(pg);
page_cache_release(pg);
+ mutex_unlock(&f->sem);
return ret;
}
diff --git a/fs/namei.c b/fs/namei.c
index 937f9d50c84..5f4cdf3ad91 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2131,6 +2131,11 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
if (!len)
return ERR_PTR(-EACCES);
+ if (unlikely(name[0] == '.')) {
+ if (len < 2 || (len == 2 && name[1] == '.'))
+ return ERR_PTR(-EACCES);
+ }
+
while (len--) {
c = *(const unsigned char *)name++;
if (c == '/' || c == '\0')
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index ce8cb926526..b9e66b7e0c1 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -450,7 +450,8 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
nfs_refresh_inode(dentry->d_inode, entry->fattr);
goto out;
} else {
- d_drop(dentry);
+ if (d_invalidate(dentry) != 0)
+ goto out;
dput(dentry);
}
}
@@ -1100,6 +1101,8 @@ out_set_verifier:
out_zap_parent:
nfs_zap_caches(dir);
out_bad:
+ nfs_free_fattr(fattr);
+ nfs_free_fhandle(fhandle);
nfs_mark_for_revalidate(dir);
if (inode && S_ISDIR(inode->i_mode)) {
/* Purge readdir caches. */
@@ -1112,8 +1115,6 @@ out_zap_parent:
shrink_dcache_parent(dentry);
}
d_drop(dentry);
- nfs_free_fattr(fattr);
- nfs_free_fhandle(fhandle);
dput(parent);
dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n",
__func__, dentry->d_parent->d_name.name,
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 3e7b2a0dc0c..07f76db04ec 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -431,7 +431,7 @@ void nilfs_mapping_init(struct address_space *mapping, struct inode *inode,
mapping->host = inode;
mapping->flags = 0;
mapping_set_gfp_mask(mapping, GFP_NOFS);
- mapping->assoc_mapping = NULL;
+ mapping->private_data = NULL;
mapping->backing_dev_info = bdi;
mapping->a_ops = &empty_aops;
}
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 721d692fa8d..6fcaeb8c902 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -258,7 +258,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
if (ret)
goto out_close_fd;
- fd_install(fd, f);
+ if (fd != FAN_NOFD)
+ fd_install(fd, f);
return fanotify_event_metadata.event_len;
out_close_fd:
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 5a4ee77cec5..dda08980494 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2513,18 +2513,15 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
ret = sd.num_spliced;
if (ret > 0) {
- unsigned long nr_pages;
int err;
- nr_pages = (ret + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-
err = generic_write_sync(out, *ppos, ret);
if (err)
ret = err;
else
*ppos += ret;
- balance_dirty_pages_ratelimited_nr(mapping, nr_pages);
+ balance_dirty_pages_ratelimited(mapping);
}
return ret;
diff --git a/fs/proc/array.c b/fs/proc/array.c
index c1c207c36ca..d3696708fc1 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -438,7 +438,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
min_flt += sig->min_flt;
maj_flt += sig->maj_flt;
- thread_group_times(task, &utime, &stime);
+ thread_group_cputime_adjusted(task, &utime, &stime);
gtime += sig->gtime;
}
@@ -454,7 +454,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
if (!whole) {
min_flt = task->min_flt;
maj_flt = task->maj_flt;
- task_times(task, &utime, &stime);
+ task_cputime_adjusted(task, &utime, &stime);
gtime = task->gtime;
}
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 144a96732dd..aa63d25157b 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -873,12 +873,119 @@ static const struct file_operations proc_environ_operations = {
.release = mem_release,
};
+static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
+ char buffer[PROC_NUMBUF];
+ int oom_adj = OOM_ADJUST_MIN;
+ size_t len;
+ unsigned long flags;
+
+ if (!task)
+ return -ESRCH;
+ if (lock_task_sighand(task, &flags)) {
+ if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MAX)
+ oom_adj = OOM_ADJUST_MAX;
+ else
+ oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) /
+ OOM_SCORE_ADJ_MAX;
+ unlock_task_sighand(task, &flags);
+ }
+ put_task_struct(task);
+ len = snprintf(buffer, sizeof(buffer), "%d\n", oom_adj);
+ return simple_read_from_buffer(buf, count, ppos, buffer, len);
+}
+
+static ssize_t oom_adj_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct task_struct *task;
+ char buffer[PROC_NUMBUF];
+ int oom_adj;
+ unsigned long flags;
+ int err;
+
+ memset(buffer, 0, sizeof(buffer));
+ if (count > sizeof(buffer) - 1)
+ count = sizeof(buffer) - 1;
+ if (copy_from_user(buffer, buf, count)) {
+ err = -EFAULT;
+ goto out;
+ }
+
+ err = kstrtoint(strstrip(buffer), 0, &oom_adj);
+ if (err)
+ goto out;
+ if ((oom_adj < OOM_ADJUST_MIN || oom_adj > OOM_ADJUST_MAX) &&
+ oom_adj != OOM_DISABLE) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ task = get_proc_task(file->f_path.dentry->d_inode);
+ if (!task) {
+ err = -ESRCH;
+ goto out;
+ }
+
+ task_lock(task);
+ if (!task->mm) {
+ err = -EINVAL;
+ goto err_task_lock;
+ }
+
+ if (!lock_task_sighand(task, &flags)) {
+ err = -ESRCH;
+ goto err_task_lock;
+ }
+
+ /*
+ * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum
+ * value is always attainable.
+ */
+ if (oom_adj == OOM_ADJUST_MAX)
+ oom_adj = OOM_SCORE_ADJ_MAX;
+ else
+ oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
+
+ if (oom_adj < task->signal->oom_score_adj &&
+ !capable(CAP_SYS_RESOURCE)) {
+ err = -EACCES;
+ goto err_sighand;
+ }
+
+ /*
+ * /proc/pid/oom_adj is provided for legacy purposes, ask users to use
+ * /proc/pid/oom_score_adj instead.
+ */
+ printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n",
+ current->comm, task_pid_nr(current), task_pid_nr(task),
+ task_pid_nr(task));
+
+ task->signal->oom_score_adj = oom_adj;
+ trace_oom_score_adj_update(task);
+err_sighand:
+ unlock_task_sighand(task, &flags);
+err_task_lock:
+ task_unlock(task);
+ put_task_struct(task);
+out:
+ return err < 0 ? err : count;
+}
+
+static const struct file_operations proc_oom_adj_operations = {
+ .read = oom_adj_read,
+ .write = oom_adj_write,
+ .llseek = generic_file_llseek,
+};
+
static ssize_t oom_score_adj_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
char buffer[PROC_NUMBUF];
- int oom_score_adj = OOM_SCORE_ADJ_MIN;
+ short oom_score_adj = OOM_SCORE_ADJ_MIN;
unsigned long flags;
size_t len;
@@ -889,7 +996,7 @@ static ssize_t oom_score_adj_read(struct file *file, char __user *buf,
unlock_task_sighand(task, &flags);
}
put_task_struct(task);
- len = snprintf(buffer, sizeof(buffer), "%d\n", oom_score_adj);
+ len = snprintf(buffer, sizeof(buffer), "%hd\n", oom_score_adj);
return simple_read_from_buffer(buf, count, ppos, buffer, len);
}
@@ -936,15 +1043,15 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf,
goto err_task_lock;
}
- if (oom_score_adj < task->signal->oom_score_adj_min &&
+ if ((short)oom_score_adj < task->signal->oom_score_adj_min &&
!capable(CAP_SYS_RESOURCE)) {
err = -EACCES;
goto err_sighand;
}
- task->signal->oom_score_adj = oom_score_adj;
+ task->signal->oom_score_adj = (short)oom_score_adj;
if (has_capability_noaudit(current, CAP_SYS_RESOURCE))
- task->signal->oom_score_adj_min = oom_score_adj;
+ task->signal->oom_score_adj_min = (short)oom_score_adj;
trace_oom_score_adj_update(task);
err_sighand:
@@ -1770,8 +1877,9 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
if (!vma)
goto out_no_vma;
- result = proc_map_files_instantiate(dir, dentry, task,
- (void *)(unsigned long)vma->vm_file->f_mode);
+ if (vma->vm_file)
+ result = proc_map_files_instantiate(dir, dentry, task,
+ (void *)(unsigned long)vma->vm_file->f_mode);
out_no_vma:
up_read(&mm->mmap_sem);
@@ -2598,6 +2706,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("cgroup", S_IRUGO, proc_cgroup_operations),
#endif
INF("oom_score", S_IRUGO, proc_oom_score),
+ REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
#ifdef CONFIG_AUDITSYSCALL
REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
@@ -2964,6 +3073,7 @@ static const struct pid_entry tid_base_stuff[] = {
REG("cgroup", S_IRUGO, proc_cgroup_operations),
#endif
INF("oom_score", S_IRUGO, proc_oom_score),
+ REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
#ifdef CONFIG_AUDITSYSCALL
REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index a40da07e93d..947fbe06c3b 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -161,6 +161,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c)
while (s < e) {
unsigned long flags;
+ u64 id;
if (c > psinfo->bufsize)
c = psinfo->bufsize;
@@ -172,7 +173,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c)
spin_lock_irqsave(&psinfo->buf_lock, flags);
}
memcpy(psinfo->buf, s, c);
- psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo);
+ psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, c, psinfo);
spin_unlock_irqrestore(&psinfo->buf_lock, flags);
s += c;
c = e - s;
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index f27f01a98aa..d83736fbc26 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1782,8 +1782,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
BUG_ON(!th->t_trans_id);
- dquot_initialize(inode);
+ reiserfs_write_unlock(inode->i_sb);
err = dquot_alloc_inode(inode);
+ reiserfs_write_lock(inode->i_sb);
if (err)
goto out_end_trans;
if (!dir->i_nlink) {
@@ -1979,8 +1980,10 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
out_end_trans:
journal_end(th, th->t_super, th->t_blocks_allocated);
+ reiserfs_write_unlock(inode->i_sb);
/* Drop can be outside and it needs more credits so it's better to have it outside */
dquot_drop(inode);
+ reiserfs_write_lock(inode->i_sb);
inode->i_flags |= S_NOQUOTA;
make_bad_inode(inode);
@@ -3103,10 +3106,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
/* must be turned off for recursive notify_change calls */
ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
- depth = reiserfs_write_lock_once(inode->i_sb);
if (is_quota_modification(inode, attr))
dquot_initialize(inode);
-
+ depth = reiserfs_write_lock_once(inode->i_sb);
if (attr->ia_valid & ATTR_SIZE) {
/* version 2 items will be caught by the s_maxbytes check
** done for us in vmtruncate
@@ -3170,7 +3172,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
error = journal_begin(&th, inode->i_sb, jbegin_count);
if (error)
goto out;
+ reiserfs_write_unlock_once(inode->i_sb, depth);
error = dquot_transfer(inode, attr);
+ depth = reiserfs_write_lock_once(inode->i_sb);
if (error) {
journal_end(&th, inode->i_sb, jbegin_count);
goto out;
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index f8afa4b162b..2f40a4c70a4 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -1968,7 +1968,9 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree
key2type(&(key->on_disk_key)));
#endif
+ reiserfs_write_unlock(inode->i_sb);
retval = dquot_alloc_space_nodirty(inode, pasted_size);
+ reiserfs_write_lock(inode->i_sb);
if (retval) {
pathrelse(search_path);
return retval;
@@ -2061,9 +2063,11 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th,
"reiserquota insert_item(): allocating %u id=%u type=%c",
quota_bytes, inode->i_uid, head2type(ih));
#endif
+ reiserfs_write_unlock(inode->i_sb);
/* We can't dirty inode here. It would be immediately written but
* appropriate stat item isn't inserted yet... */
retval = dquot_alloc_space_nodirty(inode, quota_bytes);
+ reiserfs_write_lock(inode->i_sb);
if (retval) {
pathrelse(path);
return retval;
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 1078ae17999..418bdc3a57d 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -298,7 +298,9 @@ static int finish_unfinished(struct super_block *s)
retval = remove_save_link_only(s, &save_link_key, 0);
continue;
}
+ reiserfs_write_unlock(s);
dquot_initialize(inode);
+ reiserfs_write_lock(s);
if (truncate && S_ISDIR(inode->i_mode)) {
/* We got a truncate request for a dir which is impossible.
@@ -1335,7 +1337,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
kfree(qf_names[i]);
#endif
err = -EINVAL;
- goto out_err;
+ goto out_unlock;
}
#ifdef CONFIG_QUOTA
handle_quota_files(s, qf_names, &qfmt);
@@ -1379,7 +1381,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
if (blocks) {
err = reiserfs_resize(s, blocks);
if (err != 0)
- goto out_err;
+ goto out_unlock;
}
if (*mount_flags & MS_RDONLY) {
@@ -1389,9 +1391,15 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
/* it is read-only already */
goto out_ok;
+ /*
+ * Drop write lock. Quota will retake it when needed and lock
+ * ordering requires calling dquot_suspend() without it.
+ */
+ reiserfs_write_unlock(s);
err = dquot_suspend(s, -1);
if (err < 0)
goto out_err;
+ reiserfs_write_lock(s);
/* try to remount file system with read-only permissions */
if (sb_umount_state(rs) == REISERFS_VALID_FS
@@ -1401,7 +1409,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
err = journal_begin(&th, s, 10);
if (err)
- goto out_err;
+ goto out_unlock;
/* Mounting a rw partition read-only. */
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
@@ -1416,7 +1424,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
if (reiserfs_is_journal_aborted(journal)) {
err = journal->j_errno;
- goto out_err;
+ goto out_unlock;
}
handle_data_mode(s, mount_options);
@@ -1425,7 +1433,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */
err = journal_begin(&th, s, 10);
if (err)
- goto out_err;
+ goto out_unlock;
/* Mount a partition which is read-only, read-write */
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
@@ -1442,10 +1450,16 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
SB_JOURNAL(s)->j_must_wait = 1;
err = journal_end(&th, s, 10);
if (err)
- goto out_err;
+ goto out_unlock;
if (!(*mount_flags & MS_RDONLY)) {
+ /*
+ * Drop write lock. Quota will retake it when needed and lock
+ * ordering requires calling dquot_resume() without it.
+ */
+ reiserfs_write_unlock(s);
dquot_resume(s, -1);
+ reiserfs_write_lock(s);
finish_unfinished(s);
reiserfs_xattr_init(s, *mount_flags);
}
@@ -1455,9 +1469,10 @@ out_ok:
reiserfs_write_unlock(s);
return 0;
+out_unlock:
+ reiserfs_write_unlock(s);
out_err:
kfree(new_opts);
- reiserfs_write_unlock(s);
return err;
}
@@ -2095,13 +2110,15 @@ static int reiserfs_write_dquot(struct dquot *dquot)
REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
if (ret)
goto out;
+ reiserfs_write_unlock(dquot->dq_sb);
ret = dquot_commit(dquot);
+ reiserfs_write_lock(dquot->dq_sb);
err =
journal_end(&th, dquot->dq_sb,
REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
if (!ret && err)
ret = err;
- out:
+out:
reiserfs_write_unlock(dquot->dq_sb);
return ret;
}
@@ -2117,13 +2134,15 @@ static int reiserfs_acquire_dquot(struct dquot *dquot)
REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
if (ret)
goto out;
+ reiserfs_write_unlock(dquot->dq_sb);
ret = dquot_acquire(dquot);
+ reiserfs_write_lock(dquot->dq_sb);
err =
journal_end(&th, dquot->dq_sb,
REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
if (!ret && err)
ret = err;
- out:
+out:
reiserfs_write_unlock(dquot->dq_sb);
return ret;
}
@@ -2137,19 +2156,21 @@ static int reiserfs_release_dquot(struct dquot *dquot)
ret =
journal_begin(&th, dquot->dq_sb,
REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
+ reiserfs_write_unlock(dquot->dq_sb);
if (ret) {
/* Release dquot anyway to avoid endless cycle in dqput() */
dquot_release(dquot);
goto out;
}
ret = dquot_release(dquot);
+ reiserfs_write_lock(dquot->dq_sb);
err =
journal_end(&th, dquot->dq_sb,
REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
if (!ret && err)
ret = err;
- out:
reiserfs_write_unlock(dquot->dq_sb);
+out:
return ret;
}
@@ -2174,11 +2195,13 @@ static int reiserfs_write_info(struct super_block *sb, int type)
ret = journal_begin(&th, sb, 2);
if (ret)
goto out;
+ reiserfs_write_unlock(sb);
ret = dquot_commit_info(sb, type);
+ reiserfs_write_lock(sb);
err = journal_end(&th, sb, 2);
if (!ret && err)
ret = err;
- out:
+out:
reiserfs_write_unlock(sb);
return ret;
}
@@ -2203,8 +2226,11 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
struct reiserfs_transaction_handle th;
int opt = type == USRQUOTA ? REISERFS_USRQUOTA : REISERFS_GRPQUOTA;
- if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt)))
- return -EINVAL;
+ reiserfs_write_lock(sb);
+ if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt))) {
+ err = -EINVAL;
+ goto out;
+ }
/* Quotafile not on the same filesystem? */
if (path->dentry->d_sb != sb) {
@@ -2246,8 +2272,10 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
if (err)
goto out;
}
- err = dquot_quota_on(sb, type, format_id, path);
+ reiserfs_write_unlock(sb);
+ return dquot_quota_on(sb, type, format_id, path);
out:
+ reiserfs_write_unlock(sb);
return err;
}
@@ -2320,7 +2348,9 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
tocopy = sb->s_blocksize - offset < towrite ?
sb->s_blocksize - offset : towrite;
tmp_bh.b_state = 0;
+ reiserfs_write_lock(sb);
err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE);
+ reiserfs_write_unlock(sb);
if (err)
goto out;
if (offset || tocopy != sb->s_blocksize)
@@ -2336,10 +2366,12 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
flush_dcache_page(bh->b_page);
set_buffer_uptodate(bh);
unlock_buffer(bh);
+ reiserfs_write_lock(sb);
reiserfs_prepare_for_journal(sb, bh, 1);
journal_mark_dirty(current->journal_info, sb, bh);
if (!journal_quota)
reiserfs_add_ordered_list(inode, bh);
+ reiserfs_write_unlock(sb);
brelse(bh);
offset = 0;
towrite -= tocopy;
diff --git a/fs/splice.c b/fs/splice.c
index 13e5b4776e7..8890604e3fc 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1024,17 +1024,14 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
ret = sd.num_spliced;
if (ret > 0) {
- unsigned long nr_pages;
int err;
- nr_pages = (ret + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-
err = generic_write_sync(out, *ppos, ret);
if (err)
ret = err;
else
*ppos += ret;
- balance_dirty_pages_ratelimited_nr(mapping, nr_pages);
+ balance_dirty_pages_ratelimited(mapping);
}
sb_end_write(inode->i_sb);
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 00012e31829..602f56db044 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -485,8 +485,8 @@ const struct file_operations sysfs_file_operations = {
.poll = sysfs_poll,
};
-int sysfs_attr_ns(struct kobject *kobj, const struct attribute *attr,
- const void **pns)
+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;
diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c
index 28ec13af28d..2dcf3d473fe 100644
--- a/fs/ubifs/find.c
+++ b/fs/ubifs/find.c
@@ -681,8 +681,16 @@ int ubifs_find_free_leb_for_idx(struct ubifs_info *c)
if (!lprops) {
lprops = ubifs_fast_find_freeable(c);
if (!lprops) {
- ubifs_assert(c->freeable_cnt == 0);
- if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
+ /*
+ * The first condition means the following: go scan the
+ * LPT if there are uncategorized lprops, which means
+ * there may be freeable LEBs there (UBIFS does not
+ * store the information about freeable LEBs in the
+ * master node).
+ */
+ if (c->in_a_category_cnt != c->main_lebs ||
+ c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
+ ubifs_assert(c->freeable_cnt == 0);
lprops = scan_for_leb_for_idx(c);
if (IS_ERR(lprops)) {
err = PTR_ERR(lprops);
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c
index e5a2a35a46d..46190a7c42a 100644
--- a/fs/ubifs/lprops.c
+++ b/fs/ubifs/lprops.c
@@ -300,8 +300,11 @@ void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops,
default:
ubifs_assert(0);
}
+
lprops->flags &= ~LPROPS_CAT_MASK;
lprops->flags |= cat;
+ c->in_a_category_cnt += 1;
+ ubifs_assert(c->in_a_category_cnt <= c->main_lebs);
}
/**
@@ -334,6 +337,9 @@ static void ubifs_remove_from_cat(struct ubifs_info *c,
default:
ubifs_assert(0);
}
+
+ c->in_a_category_cnt -= 1;
+ ubifs_assert(c->in_a_category_cnt >= 0);
}
/**
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 5486346d0a3..d133c276fe0 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1183,6 +1183,8 @@ struct ubifs_debug_info;
* @freeable_list: list of freeable non-index LEBs (free + dirty == @leb_size)
* @frdi_idx_list: list of freeable index LEBs (free + dirty == @leb_size)
* @freeable_cnt: number of freeable LEBs in @freeable_list
+ * @in_a_category_cnt: count of lprops which are in a certain category, which
+ * basically meants that they were loaded from the flash
*
* @ltab_lnum: LEB number of LPT's own lprops table
* @ltab_offs: offset of LPT's own lprops table
@@ -1412,6 +1414,7 @@ struct ubifs_info {
struct list_head freeable_list;
struct list_head frdi_idx_list;
int freeable_cnt;
+ int in_a_category_cnt;
int ltab_lnum;
int ltab_offs;
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index e562dd43f41..e57e2daa357 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -481,11 +481,17 @@ static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh)
*
* The fix is two passes across the ioend list - one to start writeback on the
* buffer_heads, and then submit them for I/O on the second pass.
+ *
+ * If @fail is non-zero, it means that we have a situation where some part of
+ * the submission process has failed after we have marked paged for writeback
+ * and unlocked them. In this situation, we need to fail the ioend chain rather
+ * than submit it to IO. This typically only happens on a filesystem shutdown.
*/
STATIC void
xfs_submit_ioend(
struct writeback_control *wbc,
- xfs_ioend_t *ioend)
+ xfs_ioend_t *ioend,
+ int fail)
{
xfs_ioend_t *head = ioend;
xfs_ioend_t *next;
@@ -506,6 +512,18 @@ xfs_submit_ioend(
next = ioend->io_list;
bio = NULL;
+ /*
+ * If we are failing the IO now, just mark the ioend with an
+ * error and finish it. This will run IO completion immediately
+ * as there is only one reference to the ioend at this point in
+ * time.
+ */
+ if (fail) {
+ ioend->io_error = -fail;
+ xfs_finish_ioend(ioend);
+ continue;
+ }
+
for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) {
if (!bio) {
@@ -1060,7 +1078,18 @@ xfs_vm_writepage(
xfs_start_page_writeback(page, 1, count);
- if (ioend && imap_valid) {
+ /* if there is no IO to be submitted for this page, we are done */
+ if (!ioend)
+ return 0;
+
+ ASSERT(iohead);
+
+ /*
+ * Any errors from this point onwards need tobe reported through the IO
+ * completion path as we have marked the initial page as under writeback
+ * and unlocked it.
+ */
+ if (imap_valid) {
xfs_off_t end_index;
end_index = imap.br_startoff + imap.br_blockcount;
@@ -1079,20 +1108,15 @@ xfs_vm_writepage(
wbc, end_index);
}
- if (iohead) {
- /*
- * Reserve log space if we might write beyond the on-disk
- * inode size.
- */
- if (ioend->io_type != XFS_IO_UNWRITTEN &&
- xfs_ioend_is_append(ioend)) {
- err = xfs_setfilesize_trans_alloc(ioend);
- if (err)
- goto error;
- }
- xfs_submit_ioend(wbc, iohead);
- }
+ /*
+ * Reserve log space if we might write beyond the on-disk inode size.
+ */
+ err = 0;
+ if (ioend->io_type != XFS_IO_UNWRITTEN && xfs_ioend_is_append(ioend))
+ err = xfs_setfilesize_trans_alloc(ioend);
+
+ xfs_submit_ioend(wbc, iohead, err);
return 0;
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index d330111ca73..70eec182977 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -1291,6 +1291,7 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
leaf2 = blk2->bp->b_addr;
ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
+ ASSERT(leaf2->hdr.count == 0);
args = state->args;
trace_xfs_attr_leaf_rebalance(args);
@@ -1361,6 +1362,7 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
* I assert that since all callers pass in an empty
* second buffer, this code should never execute.
*/
+ ASSERT(0);
/*
* Figure the total bytes to be added to the destination leaf.
@@ -1422,10 +1424,24 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
args->index2 = 0;
args->blkno2 = blk2->blkno;
} else {
+ /*
+ * On a double leaf split, the original attr location
+ * is already stored in blkno2/index2, so don't
+ * overwrite it overwise we corrupt the tree.
+ */
blk2->index = blk1->index
- be16_to_cpu(leaf1->hdr.count);
- args->index = args->index2 = blk2->index;
- args->blkno = args->blkno2 = blk2->blkno;
+ args->index = blk2->index;
+ args->blkno = blk2->blkno;
+ if (!state->extravalid) {
+ /*
+ * set the new attr location to match the old
+ * one and let the higher level split code
+ * decide where in the leaf to place it.
+ */
+ args->index2 = blk2->index;
+ args->blkno2 = blk2->blkno;
+ }
}
} else {
ASSERT(state->inleaf == 1);
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 933b7930b86..4b0b8dd1b7b 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1197,9 +1197,14 @@ xfs_buf_bio_end_io(
{
xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private;
- xfs_buf_ioerror(bp, -error);
+ /*
+ * don't overwrite existing errors - otherwise we can lose errors on
+ * buffers that require multiple bios to complete.
+ */
+ if (!bp->b_error)
+ xfs_buf_ioerror(bp, -error);
- if (!error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ))
+ if (!bp->b_error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ))
invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp));
_xfs_buf_ioend(bp, 1);
@@ -1279,6 +1284,11 @@ next_chunk:
if (size)
goto next_chunk;
} else {
+ /*
+ * This is guaranteed not to be the last io reference count
+ * because the caller (xfs_buf_iorequest) holds a count itself.
+ */
+ atomic_dec(&bp->b_io_remaining);
xfs_buf_ioerror(bp, EIO);
bio_put(bio);
}
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
index 03f14856bd0..0943457e0fa 100644
--- a/include/acpi/acconfig.h
+++ b/include/acpi/acconfig.h
@@ -241,6 +241,7 @@
*****************************************************************************/
#define ACPI_DEBUGGER_MAX_ARGS 8 /* Must be max method args + 1 */
+#define ACPI_DB_LINE_BUFFER_SIZE 512
#define ACPI_DEBUGGER_COMMAND_PROMPT '-'
#define ACPI_DEBUGGER_EXECUTE_PROMPT '%'
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h
index 19503449814..6c3890e0214 100644
--- a/include/acpi/acexcep.h
+++ b/include/acpi/acexcep.h
@@ -122,7 +122,7 @@
#define AE_CODE_TBL_MAX 0x0005
/*
- * AML exceptions. These are caused by problems with
+ * AML exceptions. These are caused by problems with
* the actual AML byte stream
*/
#define AE_AML_BAD_OPCODE (acpi_status) (0x0001 | AE_CODE_AML)
diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h
index 745dd24e3cb..7665df66328 100644
--- a/include/acpi/acnames.h
+++ b/include/acpi/acnames.h
@@ -50,6 +50,7 @@
#define METHOD_NAME__HID "_HID"
#define METHOD_NAME__CID "_CID"
#define METHOD_NAME__UID "_UID"
+#define METHOD_NAME__SUB "_SUB"
#define METHOD_NAME__ADR "_ADR"
#define METHOD_NAME__INI "_INI"
#define METHOD_NAME__STA "_STA"
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 0daa0fbd865..7ced5dc20dd 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -144,12 +144,11 @@ struct acpi_device_flags {
u32 bus_address:1;
u32 removable:1;
u32 ejectable:1;
- u32 lockable:1;
u32 suprise_removal_ok:1;
u32 power_manageable:1;
u32 performance_manageable:1;
u32 eject_pending:1;
- u32 reserved:23;
+ u32 reserved:24;
};
/* File System */
@@ -180,6 +179,7 @@ struct acpi_device_pnp {
acpi_device_name device_name; /* Driver-determined */
acpi_device_class device_class; /* " */
union acpi_object *str_obj; /* unicode string for _STR method */
+ unsigned long sun; /* _SUN */
};
#define acpi_device_bid(d) ((d)->pnp.bus_id)
@@ -201,6 +201,7 @@ struct acpi_device_power_flags {
struct acpi_device_power_state {
struct {
u8 valid:1;
+ u8 os_accessible:1;
u8 explicit_set:1; /* _PSx present? */
u8 reserved:6;
} flags;
@@ -339,6 +340,7 @@ acpi_status acpi_bus_get_status_handle(acpi_handle handle,
unsigned long long *sta);
int acpi_bus_get_status(struct acpi_device *device);
int acpi_bus_set_power(acpi_handle handle, int state);
+int acpi_device_set_power(struct acpi_device *device, int state);
int acpi_bus_update_power(acpi_handle handle, int *state_p);
bool acpi_bus_power_manageable(acpi_handle handle);
bool acpi_bus_can_wakeup(acpi_handle handle);
@@ -410,36 +412,100 @@ acpi_handle acpi_get_child(acpi_handle, u64);
int acpi_is_root_bridge(acpi_handle);
acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
-#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle))
+#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev))
int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state);
int acpi_disable_wakeup_device_power(struct acpi_device *dev);
#ifdef CONFIG_PM
+acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
+ acpi_notify_handler handler, void *context);
+acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
+ acpi_notify_handler handler);
+int acpi_device_power_state(struct device *dev, struct acpi_device *adev,
+ u32 target_state, int d_max_in, int *d_min_p);
int acpi_pm_device_sleep_state(struct device *, int *, int);
#else
-static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
+static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
+ acpi_notify_handler handler,
+ void *context)
+{
+ return AE_SUPPORT;
+}
+static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
+ acpi_notify_handler handler)
+{
+ return AE_SUPPORT;
+}
+static inline int __acpi_device_power_state(int m, int *p)
{
if (p)
*p = ACPI_STATE_D0;
return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3) ? m : ACPI_STATE_D0;
}
+static inline int acpi_device_power_state(struct device *dev,
+ struct acpi_device *adev,
+ u32 target_state, int d_max_in,
+ int *d_min_p)
+{
+ return __acpi_device_power_state(d_max_in, d_min_p);
+}
+static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
+{
+ return __acpi_device_power_state(m, p);
+}
#endif
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_PM_RUNTIME
+int __acpi_device_run_wake(struct acpi_device *, bool);
int acpi_pm_device_run_wake(struct device *, bool);
-int acpi_pm_device_sleep_wake(struct device *, bool);
#else
+static inline int __acpi_device_run_wake(struct acpi_device *adev, bool en)
+{
+ return -ENODEV;
+}
static inline int acpi_pm_device_run_wake(struct device *dev, bool enable)
{
return -ENODEV;
}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+int __acpi_device_sleep_wake(struct acpi_device *, u32, bool);
+int acpi_pm_device_sleep_wake(struct device *, bool);
+#else
+static inline int __acpi_device_sleep_wake(struct acpi_device *adev,
+ u32 target_state, bool enable)
+{
+ return -ENODEV;
+}
static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
{
return -ENODEV;
}
#endif
+#ifdef CONFIG_ACPI_SLEEP
+u32 acpi_target_system_state(void);
+#else
+static inline u32 acpi_target_system_state(void) { return ACPI_STATE_S0; }
+#endif
+
+static inline bool acpi_device_power_manageable(struct acpi_device *adev)
+{
+ return adev->flags.power_manageable;
+}
+
+static inline bool acpi_device_can_wakeup(struct acpi_device *adev)
+{
+ return adev->wakeup.flags.valid;
+}
+
+static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
+{
+ return adev->power.states[ACPI_STATE_D3_COLD].flags.os_accessible;
+}
+
#else /* CONFIG_ACPI */
static inline int register_acpi_bus_type(void *bus) { return 0; }
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index 1222ba93d80..43152742b46 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -1,7 +1,6 @@
-
/******************************************************************************
*
- * Name: acpiosxf.h - All interfaces to the OS Services Layer (OSL). These
+ * Name: acpiosxf.h - All interfaces to the OS Services Layer (OSL). These
* interfaces must be implemented by OSL to interface the
* ACPI components to the host operating system.
*
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 8b891dbead6..3d88395d4d6 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -1,4 +1,3 @@
-
/******************************************************************************
*
* Name: acpixf.h - External interfaces to the ACPI subsystem
@@ -47,7 +46,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20120913
+#define ACPI_CA_VERSION 0x20121018
#include <acpi/acconfig.h>
#include <acpi/actypes.h>
@@ -178,8 +177,7 @@ acpi_status acpi_unload_table_id(acpi_owner_id id);
acpi_status
acpi_get_table_header(acpi_string signature,
- u32 instance,
- struct acpi_table_header *out_table_header);
+ u32 instance, struct acpi_table_header *out_table_header);
acpi_status
acpi_get_table_with_size(acpi_string signature,
@@ -190,8 +188,7 @@ acpi_get_table(acpi_string signature,
u32 instance, struct acpi_table_header **out_table);
acpi_status
-acpi_get_table_by_index(u32 table_index,
- struct acpi_table_header **out_table);
+acpi_get_table_by_index(u32 table_index, struct acpi_table_header **out_table);
acpi_status
acpi_install_table_handler(acpi_tbl_handler handler, void *context);
@@ -274,7 +271,7 @@ acpi_install_initialization_handler(acpi_init_handler handler, u32 function);
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
acpi_install_global_event_handler
- (ACPI_GBL_EVENT_HANDLER handler, void *context))
+ (acpi_gbl_event_handler handler, void *context))
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
acpi_install_fixed_event_handler(u32
@@ -300,10 +297,9 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
u32 gpe_number,
acpi_gpe_handler
address))
-acpi_status
-acpi_install_notify_handler(acpi_handle device,
- u32 handler_type,
- acpi_notify_handler handler, void *context);
+acpi_status acpi_install_notify_handler(acpi_handle device, u32 handler_type,
+ acpi_notify_handler handler,
+ void *context);
acpi_status
acpi_remove_notify_handler(acpi_handle device,
diff --git a/include/acpi/actbl3.h b/include/acpi/actbl3.h
index 8c61b5fe42a..6585141e4b9 100644
--- a/include/acpi/actbl3.h
+++ b/include/acpi/actbl3.h
@@ -277,10 +277,10 @@ struct acpi_table_gtdt {
******************************************************************************/
#define ACPI_MPST_CHANNEL_INFO \
- u16 reserved1; \
u8 channel_id; \
- u8 reserved2; \
- u16 power_node_count;
+ u8 reserved1[3]; \
+ u16 power_node_count; \
+ u16 reserved2;
/* Main table */
@@ -304,9 +304,8 @@ struct acpi_mpst_power_node {
u32 length;
u64 range_address;
u64 range_length;
- u8 num_power_states;
- u8 num_physical_components;
- u16 reserved2;
+ u32 num_power_states;
+ u32 num_physical_components;
};
/* Values for Flags field above */
@@ -332,10 +331,11 @@ struct acpi_mpst_component {
struct acpi_mpst_data_hdr {
u16 characteristics_count;
+ u16 reserved;
};
struct acpi_mpst_power_data {
- u8 revision;
+ u8 structure_id;
u8 flags;
u16 reserved1;
u32 average_power;
@@ -356,10 +356,10 @@ struct acpi_mpst_shared {
u32 signature;
u16 pcc_command;
u16 pcc_status;
- u16 command_register;
- u16 status_register;
- u16 power_state_id;
- u16 power_node_id;
+ u32 command_register;
+ u32 status_register;
+ u32 power_state_id;
+ u32 power_node_id;
u64 energy_consumed;
u64 average_power;
};
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index a85bae96826..4f43f1fba13 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -453,10 +453,14 @@ typedef u64 acpi_integer;
#define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i)
#define ACPI_PTR_TO_PHYSADDR(i) ACPI_TO_INTEGER(i)
+/* Optimizations for 4-character (32-bit) acpi_name manipulation */
+
#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
#define ACPI_COMPARE_NAME(a,b) (*ACPI_CAST_PTR (u32, (a)) == *ACPI_CAST_PTR (u32, (b)))
+#define ACPI_MOVE_NAME(dest,src) (*ACPI_CAST_PTR (u32, (dest)) = *ACPI_CAST_PTR (u32, (src)))
#else
#define ACPI_COMPARE_NAME(a,b) (!ACPI_STRNCMP (ACPI_CAST_PTR (char, (a)), ACPI_CAST_PTR (char, (b)), ACPI_NAME_SIZE))
+#define ACPI_MOVE_NAME(dest,src) (ACPI_STRNCPY (ACPI_CAST_PTR (char, (dest)), ACPI_CAST_PTR (char, (src)), ACPI_NAME_SIZE))
#endif
/*******************************************************************************
@@ -796,11 +800,11 @@ typedef u8 acpi_adr_space_type;
/* Sleep function dispatch */
-typedef acpi_status(*ACPI_SLEEP_FUNCTION) (u8 sleep_state);
+typedef acpi_status(*acpi_sleep_function) (u8 sleep_state);
struct acpi_sleep_functions {
- ACPI_SLEEP_FUNCTION legacy_function;
- ACPI_SLEEP_FUNCTION extended_function;
+ acpi_sleep_function legacy_function;
+ acpi_sleep_function extended_function;
};
/*
@@ -922,7 +926,8 @@ struct acpi_system_info {
/*
* Types specific to the OS service interfaces
*/
-typedef u32(ACPI_SYSTEM_XFACE * acpi_osd_handler) (void *context);
+typedef u32
+ (ACPI_SYSTEM_XFACE * acpi_osd_handler) (void *context);
typedef void
(ACPI_SYSTEM_XFACE * acpi_osd_exec_callback) (void *context);
@@ -931,14 +936,15 @@ typedef void
* Various handlers and callback procedures
*/
typedef
-void (*ACPI_GBL_EVENT_HANDLER) (u32 event_type,
+void (*acpi_gbl_event_handler) (u32 event_type,
acpi_handle device,
u32 event_number, void *context);
#define ACPI_EVENT_TYPE_GPE 0
#define ACPI_EVENT_TYPE_FIXED 1
-typedef u32(*acpi_event_handler) (void *context);
+typedef
+u32(*acpi_event_handler) (void *context);
typedef
u32 (*acpi_gpe_handler) (acpi_handle gpe_device, u32 gpe_number, void *context);
@@ -1018,17 +1024,17 @@ u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported);
#define ACPI_UUID_LENGTH 16
-/* Structures used for device/processor HID, UID, CID */
+/* Structures used for device/processor HID, UID, CID, and SUB */
-struct acpica_device_id {
+struct acpi_pnp_device_id {
u32 length; /* Length of string + null */
char *string;
};
-struct acpica_device_id_list {
+struct acpi_pnp_device_id_list {
u32 count; /* Number of IDs in Ids array */
u32 list_size; /* Size of list, including ID strings */
- struct acpica_device_id ids[1]; /* ID array */
+ struct acpi_pnp_device_id ids[1]; /* ID array */
};
/*
@@ -1046,9 +1052,10 @@ struct acpi_device_info {
u8 lowest_dstates[5]; /* _sx_w values: 0xFF indicates not valid */
u32 current_status; /* _STA value */
u64 address; /* _ADR value */
- struct acpica_device_id hardware_id; /* _HID value */
- struct acpica_device_id unique_id; /* _UID value */
- struct acpica_device_id_list compatible_id_list; /* _CID list <must be last> */
+ struct acpi_pnp_device_id hardware_id; /* _HID value */
+ struct acpi_pnp_device_id unique_id; /* _UID value */
+ struct acpi_pnp_device_id subsystem_id; /* _SUB value */
+ struct acpi_pnp_device_id_list compatible_id_list; /* _CID list <must be last> */
};
/* Values for Flags field above (acpi_get_object_info) */
@@ -1061,11 +1068,12 @@ struct acpi_device_info {
#define ACPI_VALID_ADR 0x02
#define ACPI_VALID_HID 0x04
#define ACPI_VALID_UID 0x08
-#define ACPI_VALID_CID 0x10
-#define ACPI_VALID_SXDS 0x20
-#define ACPI_VALID_SXWS 0x40
+#define ACPI_VALID_SUB 0x10
+#define ACPI_VALID_CID 0x20
+#define ACPI_VALID_SXDS 0x40
+#define ACPI_VALID_SXWS 0x80
-/* Flags for _STA method */
+/* Flags for _STA return value (current_status above) */
#define ACPI_STA_DEVICE_PRESENT 0x01
#define ACPI_STA_DEVICE_ENABLED 0x02
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index a9432fc6b8b..20ca7663975 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -5,6 +5,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/of.h>
+#include <linux/pinctrl/pinctrl.h>
#ifdef CONFIG_GPIOLIB
@@ -56,6 +57,8 @@ struct device_node;
* enabling module power and clock; may sleep
* @free: optional hook for chip-specific deactivation, such as
* disabling module power and clock; may sleep
+ * @get_direction: returns direction for signal "offset", 0=out, 1=in,
+ * (same as GPIOF_DIR_XXX), or negative error
* @direction_input: configures signal "offset" as input, or returns error
* @get: returns value for signal "offset"; for output signals this
* returns either the value actually sensed, or zero
@@ -100,7 +103,8 @@ struct gpio_chip {
unsigned offset);
void (*free)(struct gpio_chip *chip,
unsigned offset);
-
+ int (*get_direction)(struct gpio_chip *chip,
+ unsigned offset);
int (*direction_input)(struct gpio_chip *chip,
unsigned offset);
int (*get)(struct gpio_chip *chip,
@@ -134,6 +138,15 @@ struct gpio_chip {
int (*of_xlate)(struct gpio_chip *gc,
const struct of_phandle_args *gpiospec, u32 *flags);
#endif
+#ifdef CONFIG_PINCTRL
+ /*
+ * If CONFIG_PINCTRL is enabled, then gpio controllers can optionally
+ * describe the actual pin range which they serve in an SoC. This
+ * information would be used by pinctrl subsystem to configure
+ * corresponding pins for gpio usage.
+ */
+ struct list_head pin_ranges;
+#endif
};
extern const char *gpiochip_is_requested(struct gpio_chip *chip,
@@ -257,4 +270,41 @@ static inline void gpio_unexport(unsigned gpio)
}
#endif /* CONFIG_GPIO_SYSFS */
+#ifdef CONFIG_PINCTRL
+
+/**
+ * struct gpio_pin_range - pin range controlled by a gpio chip
+ * @head: list for maintaining set of pin ranges, used internally
+ * @pctldev: pinctrl device which handles corresponding pins
+ * @range: actual range of pins controlled by a gpio controller
+ */
+
+struct gpio_pin_range {
+ struct list_head node;
+ struct pinctrl_dev *pctldev;
+ struct pinctrl_gpio_range range;
+};
+
+int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
+ unsigned int gpio_offset, unsigned int pin_offset,
+ unsigned int npins);
+void gpiochip_remove_pin_ranges(struct gpio_chip *chip);
+
+#else
+
+static inline int
+gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
+ unsigned int gpio_offset, unsigned int pin_offset,
+ unsigned int npins)
+{
+ return 0;
+}
+
+static inline void
+gpiochip_remove_pin_ranges(struct gpio_chip *chip)
+{
+}
+
+#endif /* CONFIG_PINCTRL */
+
#endif /* _ASM_GENERIC_GPIO_H */
diff --git a/include/asm-generic/trace_clock.h b/include/asm-generic/trace_clock.h
new file mode 100644
index 00000000000..6726f1bafb5
--- /dev/null
+++ b/include/asm-generic/trace_clock.h
@@ -0,0 +1,16 @@
+#ifndef _ASM_GENERIC_TRACE_CLOCK_H
+#define _ASM_GENERIC_TRACE_CLOCK_H
+/*
+ * Arch-specific trace clocks.
+ */
+
+/*
+ * Additional trace clocks added to the trace_clocks
+ * array in kernel/trace/trace.c
+ * None if the architecture has not defined it.
+ */
+#ifndef ARCH_TRACE_CLOCKS
+# define ARCH_TRACE_CLOCKS
+#endif
+
+#endif /* _ASM_GENERIC_TRACE_CLOCK_H */
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h
index af1cbaf535e..c5c35e62942 100644
--- a/include/drm/drm_pciids.h
+++ b/include/drm/drm_pciids.h
@@ -210,6 +210,7 @@
{0x1002, 0x6798, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6799, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
{0x1002, 0x679A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x679B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
{0x1002, 0x679E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
{0x1002, 0x679F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 90be9898110..c33fa3ce9b7 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -25,7 +25,9 @@
#ifndef _LINUX_ACPI_H
#define _LINUX_ACPI_H
+#include <linux/errno.h>
#include <linux/ioport.h> /* for struct resource */
+#include <linux/device.h>
#ifdef CONFIG_ACPI
@@ -250,6 +252,26 @@ extern int pnpacpi_disabled;
#define PXM_INVAL (-1)
+bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res);
+bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res);
+bool acpi_dev_resource_address_space(struct acpi_resource *ares,
+ struct resource *res);
+bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
+ struct resource *res);
+unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable);
+bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
+ struct resource *res);
+
+struct resource_list_entry {
+ struct list_head node;
+ struct resource res;
+};
+
+void acpi_dev_free_resource_list(struct list_head *list);
+int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
+ int (*preproc)(struct acpi_resource *, void *),
+ void *preproc_data);
+
int acpi_check_resource_conflict(const struct resource *res);
int acpi_check_region(resource_size_t start, resource_size_t n,
@@ -257,10 +279,14 @@ int acpi_check_region(resource_size_t start, resource_size_t n,
int acpi_resources_are_enforced(void);
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_HIBERNATION
void __init acpi_no_s4_hw_signature(void);
+#endif
+
+#ifdef CONFIG_PM_SLEEP
void __init acpi_old_suspend_ordering(void);
void __init acpi_nvs_nosave(void);
+void __init acpi_nvs_nosave_s3(void);
#endif /* CONFIG_PM_SLEEP */
struct acpi_osc_context {
@@ -364,6 +390,17 @@ extern int acpi_nvs_register(__u64 start, __u64 size);
extern int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *),
void *data);
+const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
+ const struct device *dev);
+
+static inline bool acpi_driver_match_device(struct device *dev,
+ const struct device_driver *drv)
+{
+ return !!acpi_match_device(drv->acpi_match_table, dev);
+}
+
+#define ACPI_PTR(_ptr) (_ptr)
+
#else /* !CONFIG_ACPI */
#define acpi_disabled 1
@@ -418,6 +455,22 @@ static inline int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *),
return 0;
}
+struct acpi_device_id;
+
+static inline const struct acpi_device_id *acpi_match_device(
+ const struct acpi_device_id *ids, const struct device *dev)
+{
+ return NULL;
+}
+
+static inline bool acpi_driver_match_device(struct device *dev,
+ const struct device_driver *drv)
+{
+ return false;
+}
+
+#define ACPI_PTR(_ptr) (NULL)
+
#endif /* !CONFIG_ACPI */
#ifdef CONFIG_ACPI
@@ -430,4 +483,84 @@ acpi_status acpi_os_prepare_sleep(u8 sleep_state,
#define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0)
#endif
+#if defined(CONFIG_ACPI) && defined(CONFIG_PM_RUNTIME)
+int acpi_dev_runtime_suspend(struct device *dev);
+int acpi_dev_runtime_resume(struct device *dev);
+int acpi_subsys_runtime_suspend(struct device *dev);
+int acpi_subsys_runtime_resume(struct device *dev);
+#else
+static inline int acpi_dev_runtime_suspend(struct device *dev) { return 0; }
+static inline int acpi_dev_runtime_resume(struct device *dev) { return 0; }
+static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; }
+static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; }
+#endif
+
+#ifdef CONFIG_ACPI_SLEEP
+int acpi_dev_suspend_late(struct device *dev);
+int acpi_dev_resume_early(struct device *dev);
+int acpi_subsys_prepare(struct device *dev);
+int acpi_subsys_suspend_late(struct device *dev);
+int acpi_subsys_resume_early(struct device *dev);
+#else
+static inline int acpi_dev_suspend_late(struct device *dev) { return 0; }
+static inline int acpi_dev_resume_early(struct device *dev) { return 0; }
+static inline int acpi_subsys_prepare(struct device *dev) { return 0; }
+static inline int acpi_subsys_suspend_late(struct device *dev) { return 0; }
+static inline int acpi_subsys_resume_early(struct device *dev) { return 0; }
+#endif
+
+#if defined(CONFIG_ACPI) && defined(CONFIG_PM)
+int acpi_dev_pm_attach(struct device *dev, bool power_on);
+void acpi_dev_pm_detach(struct device *dev, bool power_off);
+#else
+static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
+{
+ return -ENODEV;
+}
+static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
+#endif
+
+#ifdef CONFIG_ACPI
+__printf(3, 4)
+void acpi_handle_printk(const char *level, acpi_handle handle,
+ const char *fmt, ...);
+#else /* !CONFIG_ACPI */
+static inline __printf(3, 4) void
+acpi_handle_printk(const char *level, void *handle, const char *fmt, ...) {}
+#endif /* !CONFIG_ACPI */
+
+/*
+ * acpi_handle_<level>: Print message with ACPI prefix and object path
+ *
+ * These interfaces acquire the global namespace mutex to obtain an object
+ * path. In interrupt context, it shows the object path as <n/a>.
+ */
+#define acpi_handle_emerg(handle, fmt, ...) \
+ acpi_handle_printk(KERN_EMERG, handle, fmt, ##__VA_ARGS__)
+#define acpi_handle_alert(handle, fmt, ...) \
+ acpi_handle_printk(KERN_ALERT, handle, fmt, ##__VA_ARGS__)
+#define acpi_handle_crit(handle, fmt, ...) \
+ acpi_handle_printk(KERN_CRIT, handle, fmt, ##__VA_ARGS__)
+#define acpi_handle_err(handle, fmt, ...) \
+ acpi_handle_printk(KERN_ERR, handle, fmt, ##__VA_ARGS__)
+#define acpi_handle_warn(handle, fmt, ...) \
+ acpi_handle_printk(KERN_WARNING, handle, fmt, ##__VA_ARGS__)
+#define acpi_handle_notice(handle, fmt, ...) \
+ acpi_handle_printk(KERN_NOTICE, handle, fmt, ##__VA_ARGS__)
+#define acpi_handle_info(handle, fmt, ...) \
+ acpi_handle_printk(KERN_INFO, handle, fmt, ##__VA_ARGS__)
+
+/* REVISIT: Support CONFIG_DYNAMIC_DEBUG when necessary */
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
+#define acpi_handle_debug(handle, fmt, ...) \
+ acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__)
+#else
+#define acpi_handle_debug(handle, fmt, ...) \
+({ \
+ if (0) \
+ acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__); \
+ 0; \
+})
+#endif
+
#endif /*_LINUX_ACPI_H*/
diff --git a/include/linux/acpi_gpio.h b/include/linux/acpi_gpio.h
new file mode 100644
index 00000000000..91615a389b6
--- /dev/null
+++ b/include/linux/acpi_gpio.h
@@ -0,0 +1,19 @@
+#ifndef _LINUX_ACPI_GPIO_H_
+#define _LINUX_ACPI_GPIO_H_
+
+#include <linux/errno.h>
+
+#ifdef CONFIG_GPIO_ACPI
+
+int acpi_get_gpio(char *path, int pin);
+
+#else /* CONFIG_GPIO_ACPI */
+
+static inline int acpi_get_gpio(char *path, int pin)
+{
+ return -ENODEV;
+}
+
+#endif /* CONFIG_GPIO_ACPI */
+
+#endif /* _LINUX_ACPI_GPIO_H_ */
diff --git a/include/linux/balloon_compaction.h b/include/linux/balloon_compaction.h
new file mode 100644
index 00000000000..f7f1d7169b1
--- /dev/null
+++ b/include/linux/balloon_compaction.h
@@ -0,0 +1,272 @@
+/*
+ * include/linux/balloon_compaction.h
+ *
+ * Common interface definitions for making balloon pages movable by compaction.
+ *
+ * Despite being perfectly possible to perform ballooned pages migration, they
+ * make a special corner case to compaction scans because balloon pages are not
+ * enlisted at any LRU list like the other pages we do compact / migrate.
+ *
+ * As the page isolation scanning step a compaction thread does is a lockless
+ * procedure (from a page standpoint), it might bring some racy situations while
+ * performing balloon page compaction. In order to sort out these racy scenarios
+ * and safely perform balloon's page compaction and migration we must, always,
+ * ensure following these three simple rules:
+ *
+ * i. when updating a balloon's page ->mapping element, strictly do it under
+ * the following lock order, independently of the far superior
+ * locking scheme (lru_lock, balloon_lock):
+ * +-page_lock(page);
+ * +--spin_lock_irq(&b_dev_info->pages_lock);
+ * ... page->mapping updates here ...
+ *
+ * ii. before isolating or dequeueing a balloon page from the balloon device
+ * pages list, the page reference counter must be raised by one and the
+ * extra refcount must be dropped when the page is enqueued back into
+ * the balloon device page list, thus a balloon page keeps its reference
+ * counter raised only while it is under our special handling;
+ *
+ * iii. after the lockless scan step have selected a potential balloon page for
+ * isolation, re-test the page->mapping flags and the page ref counter
+ * under the proper page lock, to ensure isolating a valid balloon page
+ * (not yet isolated, nor under release procedure)
+ *
+ * The functions provided by this interface are placed to help on coping with
+ * the aforementioned balloon page corner case, as well as to ensure the simple
+ * set of exposed rules are satisfied while we are dealing with balloon pages
+ * compaction / migration.
+ *
+ * Copyright (C) 2012, Red Hat, Inc. Rafael Aquini <aquini@redhat.com>
+ */
+#ifndef _LINUX_BALLOON_COMPACTION_H
+#define _LINUX_BALLOON_COMPACTION_H
+#include <linux/pagemap.h>
+#include <linux/page-flags.h>
+#include <linux/migrate.h>
+#include <linux/gfp.h>
+#include <linux/err.h>
+
+/*
+ * Balloon device information descriptor.
+ * This struct is used to allow the common balloon compaction interface
+ * procedures to find the proper balloon device holding memory pages they'll
+ * have to cope for page compaction / migration, as well as it serves the
+ * balloon driver as a page book-keeper for its registered balloon devices.
+ */
+struct balloon_dev_info {
+ void *balloon_device; /* balloon device descriptor */
+ struct address_space *mapping; /* balloon special page->mapping */
+ unsigned long isolated_pages; /* # of isolated pages for migration */
+ spinlock_t pages_lock; /* Protection to pages list */
+ struct list_head pages; /* Pages enqueued & handled to Host */
+};
+
+extern struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info);
+extern struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info);
+extern struct balloon_dev_info *balloon_devinfo_alloc(
+ void *balloon_dev_descriptor);
+
+static inline void balloon_devinfo_free(struct balloon_dev_info *b_dev_info)
+{
+ kfree(b_dev_info);
+}
+
+/*
+ * balloon_page_free - release a balloon page back to the page free lists
+ * @page: ballooned page to be set free
+ *
+ * This function must be used to properly set free an isolated/dequeued balloon
+ * page at the end of a sucessful page migration, or at the balloon driver's
+ * page release procedure.
+ */
+static inline void balloon_page_free(struct page *page)
+{
+ /*
+ * Balloon pages always get an extra refcount before being isolated
+ * and before being dequeued to help on sorting out fortuite colisions
+ * between a thread attempting to isolate and another thread attempting
+ * to release the very same balloon page.
+ *
+ * Before we handle the page back to Buddy, lets drop its extra refcnt.
+ */
+ put_page(page);
+ __free_page(page);
+}
+
+#ifdef CONFIG_BALLOON_COMPACTION
+extern bool balloon_page_isolate(struct page *page);
+extern void balloon_page_putback(struct page *page);
+extern int balloon_page_migrate(struct page *newpage,
+ struct page *page, enum migrate_mode mode);
+extern struct address_space
+*balloon_mapping_alloc(struct balloon_dev_info *b_dev_info,
+ const struct address_space_operations *a_ops);
+
+static inline void balloon_mapping_free(struct address_space *balloon_mapping)
+{
+ kfree(balloon_mapping);
+}
+
+/*
+ * page_flags_cleared - helper to perform balloon @page ->flags tests.
+ *
+ * As balloon pages are obtained from buddy and we do not play with page->flags
+ * at driver level (exception made when we get the page lock for compaction),
+ * we can safely identify a ballooned page by checking if the
+ * PAGE_FLAGS_CHECK_AT_PREP page->flags are all cleared. This approach also
+ * helps us skip ballooned pages that are locked for compaction or release, thus
+ * mitigating their racy check at balloon_page_movable()
+ */
+static inline bool page_flags_cleared(struct page *page)
+{
+ return !(page->flags & PAGE_FLAGS_CHECK_AT_PREP);
+}
+
+/*
+ * __is_movable_balloon_page - helper to perform @page mapping->flags tests
+ */
+static inline bool __is_movable_balloon_page(struct page *page)
+{
+ struct address_space *mapping = page->mapping;
+ return mapping_balloon(mapping);
+}
+
+/*
+ * balloon_page_movable - test page->mapping->flags to identify balloon pages
+ * that can be moved by compaction/migration.
+ *
+ * This function is used at core compaction's page isolation scheme, therefore
+ * most pages exposed to it are not enlisted as balloon pages and so, to avoid
+ * undesired side effects like racing against __free_pages(), we cannot afford
+ * holding the page locked while testing page->mapping->flags here.
+ *
+ * As we might return false positives in the case of a balloon page being just
+ * released under us, the page->mapping->flags need to be re-tested later,
+ * under the proper page lock, at the functions that will be coping with the
+ * balloon page case.
+ */
+static inline bool balloon_page_movable(struct page *page)
+{
+ /*
+ * Before dereferencing and testing mapping->flags, let's make sure
+ * this is not a page that uses ->mapping in a different way
+ */
+ if (page_flags_cleared(page) && !page_mapped(page) &&
+ page_count(page) == 1)
+ return __is_movable_balloon_page(page);
+
+ return false;
+}
+
+/*
+ * balloon_page_insert - insert a page into the balloon's page list and make
+ * the page->mapping assignment accordingly.
+ * @page : page to be assigned as a 'balloon page'
+ * @mapping : allocated special 'balloon_mapping'
+ * @head : balloon's device page list head
+ *
+ * Caller must ensure the page is locked and the spin_lock protecting balloon
+ * pages list is held before inserting a page into the balloon device.
+ */
+static inline void balloon_page_insert(struct page *page,
+ struct address_space *mapping,
+ struct list_head *head)
+{
+ page->mapping = mapping;
+ list_add(&page->lru, head);
+}
+
+/*
+ * balloon_page_delete - delete a page from balloon's page list and clear
+ * the page->mapping assignement accordingly.
+ * @page : page to be released from balloon's page list
+ *
+ * Caller must ensure the page is locked and the spin_lock protecting balloon
+ * pages list is held before deleting a page from the balloon device.
+ */
+static inline void balloon_page_delete(struct page *page)
+{
+ page->mapping = NULL;
+ list_del(&page->lru);
+}
+
+/*
+ * balloon_page_device - get the b_dev_info descriptor for the balloon device
+ * that enqueues the given page.
+ */
+static inline struct balloon_dev_info *balloon_page_device(struct page *page)
+{
+ struct address_space *mapping = page->mapping;
+ if (likely(mapping))
+ return mapping->private_data;
+
+ return NULL;
+}
+
+static inline gfp_t balloon_mapping_gfp_mask(void)
+{
+ return GFP_HIGHUSER_MOVABLE;
+}
+
+static inline bool balloon_compaction_check(void)
+{
+ return true;
+}
+
+#else /* !CONFIG_BALLOON_COMPACTION */
+
+static inline void *balloon_mapping_alloc(void *balloon_device,
+ const struct address_space_operations *a_ops)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline void balloon_mapping_free(struct address_space *balloon_mapping)
+{
+ return;
+}
+
+static inline void balloon_page_insert(struct page *page,
+ struct address_space *mapping,
+ struct list_head *head)
+{
+ list_add(&page->lru, head);
+}
+
+static inline void balloon_page_delete(struct page *page)
+{
+ list_del(&page->lru);
+}
+
+static inline bool balloon_page_movable(struct page *page)
+{
+ return false;
+}
+
+static inline bool balloon_page_isolate(struct page *page)
+{
+ return false;
+}
+
+static inline void balloon_page_putback(struct page *page)
+{
+ return;
+}
+
+static inline int balloon_page_migrate(struct page *newpage,
+ struct page *page, enum migrate_mode mode)
+{
+ return 0;
+}
+
+static inline gfp_t balloon_mapping_gfp_mask(void)
+{
+ return GFP_HIGHUSER;
+}
+
+static inline bool balloon_compaction_check(void)
+{
+ return false;
+}
+#endif /* CONFIG_BALLOON_COMPACTION */
+#endif /* _LINUX_BALLOON_COMPACTION_H */
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 6d6795d46a7..7b74452c531 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -51,8 +51,8 @@ extern unsigned long free_all_bootmem(void);
extern void free_bootmem_node(pg_data_t *pgdat,
unsigned long addr,
unsigned long size);
-extern void free_bootmem(unsigned long addr, unsigned long size);
-extern void free_bootmem_late(unsigned long addr, unsigned long size);
+extern void free_bootmem(unsigned long physaddr, unsigned long size);
+extern void free_bootmem_late(unsigned long physaddr, unsigned long size);
/*
* Flags for reserve_bootmem (also if CONFIG_HAVE_ARCH_BOOTMEM_NODE,
diff --git a/include/linux/bug.h b/include/linux/bug.h
index aaac4bba6f5..b1cf40de847 100644
--- a/include/linux/bug.h
+++ b/include/linux/bug.h
@@ -15,6 +15,7 @@ struct pt_regs;
#define BUILD_BUG_ON_NOT_POWER_OF_2(n)
#define BUILD_BUG_ON_ZERO(e) (0)
#define BUILD_BUG_ON_NULL(e) ((void*)0)
+#define BUILD_BUG_ON_INVALID(e) (0)
#define BUILD_BUG_ON(condition)
#define BUILD_BUG() (0)
#else /* __CHECKER__ */
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index c1273158292..4989b8a7bed 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -53,9 +53,18 @@ struct clk_hw;
* @disable: Disable the clock atomically. Called with enable_lock held.
* This function must not sleep.
*
- * @recalc_rate Recalculate the rate of this clock, by quering hardware. The
+ * @is_enabled: Queries the hardware to determine if the clock is enabled.
+ * This function must not sleep. Optional, if this op is not
+ * set then the enable count will be used.
+ *
+ * @disable_unused: Disable the clock atomically. Only called from
+ * clk_disable_unused for gate clocks with special needs.
+ * Called with enable_lock held. This function must not
+ * sleep.
+ *
+ * @recalc_rate Recalculate the rate of this clock, by querying hardware. The
* parent rate is an input parameter. It is up to the caller to
- * insure that the prepare_mutex is held across this call.
+ * ensure that the prepare_mutex is held across this call.
* Returns the calculated rate. Optional, but recommended - if
* this op is not set then clock rate will be initialized to 0.
*
@@ -89,7 +98,7 @@ struct clk_hw;
* implementations to split any work between atomic (enable) and sleepable
* (prepare) contexts. If enabling a clock requires code that might sleep,
* this must be done in clk_prepare. Clock enable code that will never be
- * called in a sleepable context may be implement in clk_enable.
+ * called in a sleepable context may be implemented in clk_enable.
*
* Typically, drivers will call clk_prepare when a clock may be needed later
* (eg. when a device is opened), and clk_enable when the clock is actually
@@ -102,6 +111,7 @@ struct clk_ops {
int (*enable)(struct clk_hw *hw);
void (*disable)(struct clk_hw *hw);
int (*is_enabled)(struct clk_hw *hw);
+ void (*disable_unused)(struct clk_hw *hw);
unsigned long (*recalc_rate)(struct clk_hw *hw,
unsigned long parent_rate);
long (*round_rate)(struct clk_hw *hw, unsigned long,
@@ -327,19 +337,21 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
* error code; drivers must test for an error code after calling clk_register.
*/
struct clk *clk_register(struct device *dev, struct clk_hw *hw);
+struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw);
void clk_unregister(struct clk *clk);
+void devm_clk_unregister(struct device *dev, struct clk *clk);
/* helper functions */
const char *__clk_get_name(struct clk *clk);
struct clk_hw *__clk_get_hw(struct clk *clk);
u8 __clk_get_num_parents(struct clk *clk);
struct clk *__clk_get_parent(struct clk *clk);
-inline int __clk_get_enable_count(struct clk *clk);
-inline int __clk_get_prepare_count(struct clk *clk);
+unsigned int __clk_get_enable_count(struct clk *clk);
+unsigned int __clk_get_prepare_count(struct clk *clk);
unsigned long __clk_get_rate(struct clk *clk);
unsigned long __clk_get_flags(struct clk *clk);
-int __clk_is_enabled(struct clk *clk);
+bool __clk_is_enabled(struct clk *clk);
struct clk *__clk_lookup(const char *name);
/*
diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h
new file mode 100644
index 00000000000..e24339ccb7f
--- /dev/null
+++ b/include/linux/context_tracking.h
@@ -0,0 +1,18 @@
+#ifndef _LINUX_CONTEXT_TRACKING_H
+#define _LINUX_CONTEXT_TRACKING_H
+
+#ifdef CONFIG_CONTEXT_TRACKING
+#include <linux/sched.h>
+
+extern void user_enter(void);
+extern void user_exit(void);
+extern void context_tracking_task_switch(struct task_struct *prev,
+ struct task_struct *next);
+#else
+static inline void user_enter(void) { }
+static inline void user_exit(void) { }
+static inline void context_tracking_task_switch(struct task_struct *prev,
+ struct task_struct *next) { }
+#endif /* !CONFIG_CONTEXT_TRACKING */
+
+#endif
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index b60f6ba01d0..a55b88eaf96 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -11,6 +11,7 @@
#ifndef _LINUX_CPUFREQ_H
#define _LINUX_CPUFREQ_H
+#include <asm/cputime.h>
#include <linux/mutex.h>
#include <linux/notifier.h>
#include <linux/threads.h>
@@ -22,6 +23,8 @@
#include <asm/div64.h>
#define CPUFREQ_NAME_LEN 16
+/* Print length for names. Extra 1 space for accomodating '\n' in prints */
+#define CPUFREQ_NAME_PLEN (CPUFREQ_NAME_LEN + 1)
/*********************************************************************
@@ -404,6 +407,4 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
unsigned int cpu);
void cpufreq_frequency_table_put_attr(unsigned int cpu);
-
-
#endif /* _LINUX_CPUFREQ_H */
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 279b1eaa8b7..3711b34dc4f 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -82,13 +82,6 @@ cpuidle_set_statedata(struct cpuidle_state_usage *st_usage, void *data)
st_usage->driver_data = data;
}
-struct cpuidle_state_kobj {
- struct cpuidle_state *state;
- struct cpuidle_state_usage *state_usage;
- struct completion kobj_unregister;
- struct kobject kobj;
-};
-
struct cpuidle_device {
unsigned int registered:1;
unsigned int enabled:1;
@@ -98,7 +91,7 @@ struct cpuidle_device {
int state_count;
struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX];
struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX];
-
+ struct cpuidle_driver_kobj *kobj_driver;
struct list_head device_list;
struct kobject kobj;
struct completion kobj_unregister;
@@ -131,6 +124,7 @@ static inline int cpuidle_get_last_residency(struct cpuidle_device *dev)
struct cpuidle_driver {
const char *name;
struct module *owner;
+ int refcnt;
unsigned int power_specified:1;
/* set to 1 to use the core cpuidle time keeping (for all states). */
@@ -163,6 +157,10 @@ extern int cpuidle_wrap_enter(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index));
extern int cpuidle_play_dead(void);
+extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev);
+extern int cpuidle_register_cpu_driver(struct cpuidle_driver *drv, int cpu);
+extern void cpuidle_unregister_cpu_driver(struct cpuidle_driver *drv, int cpu);
+
#else
static inline void disable_cpuidle(void) { }
static inline int cpuidle_idle_call(void) { return -ENODEV; }
@@ -189,7 +187,6 @@ static inline int cpuidle_wrap_enter(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index))
{ return -ENODEV; }
static inline int cpuidle_play_dead(void) {return -ENODEV; }
-
#endif
#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 281c72a3b9d..e83ef39b3be 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -25,12 +25,12 @@ struct devfreq;
* struct devfreq_dev_status - Data given from devfreq user device to
* governors. Represents the performance
* statistics.
- * @total_time The total time represented by this instance of
+ * @total_time: The total time represented by this instance of
* devfreq_dev_status
- * @busy_time The time that the device was working among the
+ * @busy_time: The time that the device was working among the
* total_time.
- * @current_frequency The operating frequency.
- * @private_data An entry not specified by the devfreq framework.
+ * @current_frequency: The operating frequency.
+ * @private_data: An entry not specified by the devfreq framework.
* A device and a specific governor may have their
* own protocol with private_data. However, because
* this is governor-specific, a governor using this
@@ -54,23 +54,27 @@ struct devfreq_dev_status {
/**
* struct devfreq_dev_profile - Devfreq's user device profile
- * @initial_freq The operating frequency when devfreq_add_device() is
+ * @initial_freq: The operating frequency when devfreq_add_device() is
* called.
- * @polling_ms The polling interval in ms. 0 disables polling.
- * @target The device should set its operating frequency at
+ * @polling_ms: The polling interval in ms. 0 disables polling.
+ * @target: The device should set its operating frequency at
* freq or lowest-upper-than-freq value. If freq is
* higher than any operable frequency, set maximum.
* Before returning, target function should set
* freq at the current frequency.
* The "flags" parameter's possible values are
* explained above with "DEVFREQ_FLAG_*" macros.
- * @get_dev_status The device should provide the current performance
+ * @get_dev_status: The device should provide the current performance
* status to devfreq, which is used by governors.
- * @exit An optional callback that is called when devfreq
+ * @get_cur_freq: The device should provide the current frequency
+ * at which it is operating.
+ * @exit: An optional callback that is called when devfreq
* is removing the devfreq object due to error or
* from devfreq_remove_device() call. If the user
* has registered devfreq->nb at a notifier-head,
* this is the time to unregister it.
+ * @freq_table: Optional list of frequencies to support statistics.
+ * @max_state: The size of freq_table.
*/
struct devfreq_dev_profile {
unsigned long initial_freq;
@@ -79,63 +83,63 @@ struct devfreq_dev_profile {
int (*target)(struct device *dev, unsigned long *freq, u32 flags);
int (*get_dev_status)(struct device *dev,
struct devfreq_dev_status *stat);
+ int (*get_cur_freq)(struct device *dev, unsigned long *freq);
void (*exit)(struct device *dev);
+
+ unsigned int *freq_table;
+ unsigned int max_state;
};
/**
* struct devfreq_governor - Devfreq policy governor
- * @name Governor's name
- * @get_target_freq Returns desired operating frequency for the device.
+ * @node: list node - contains registered devfreq governors
+ * @name: Governor's name
+ * @get_target_freq: Returns desired operating frequency for the device.
* Basically, get_target_freq will run
* devfreq_dev_profile.get_dev_status() to get the
* status of the device (load = busy_time / total_time).
* If no_central_polling is set, this callback is called
* only with update_devfreq() notified by OPP.
- * @init Called when the devfreq is being attached to a device
- * @exit Called when the devfreq is being removed from a
- * device. Governor should stop any internal routines
- * before return because related data may be
- * freed after exit().
- * @no_central_polling Do not use devfreq's central polling mechanism.
- * When this is set, devfreq will not call
- * get_target_freq with devfreq_monitor(). However,
- * devfreq will call get_target_freq with
- * devfreq_update() notified by OPP framework.
+ * @event_handler: Callback for devfreq core framework to notify events
+ * to governors. Events include per device governor
+ * init and exit, opp changes out of devfreq, suspend
+ * and resume of per device devfreq during device idle.
*
* Note that the callbacks are called with devfreq->lock locked by devfreq.
*/
struct devfreq_governor {
+ struct list_head node;
+
const char name[DEVFREQ_NAME_LEN];
int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
- int (*init)(struct devfreq *this);
- void (*exit)(struct devfreq *this);
- const bool no_central_polling;
+ int (*event_handler)(struct devfreq *devfreq,
+ unsigned int event, void *data);
};
/**
* struct devfreq - Device devfreq structure
- * @node list node - contains the devices with devfreq that have been
+ * @node: list node - contains the devices with devfreq that have been
* registered.
- * @lock a mutex to protect accessing devfreq.
- * @dev device registered by devfreq class. dev.parent is the device
+ * @lock: a mutex to protect accessing devfreq.
+ * @dev: device registered by devfreq class. dev.parent is the device
* using devfreq.
- * @profile device-specific devfreq profile
- * @governor method how to choose frequency based on the usage.
- * @nb notifier block used to notify devfreq object that it should
+ * @profile: device-specific devfreq profile
+ * @governor: method how to choose frequency based on the usage.
+ * @governor_name: devfreq governor name for use with this devfreq
+ * @nb: notifier block used to notify devfreq object that it should
* reevaluate operable frequencies. Devfreq users may use
* devfreq.nb to the corresponding register notifier call chain.
- * @polling_jiffies interval in jiffies.
- * @previous_freq previously configured frequency value.
- * @next_polling the number of remaining jiffies to poll with
- * "devfreq_monitor" executions to reevaluate
- * frequency/voltage of the device. Set by
- * profile's polling_ms interval.
- * @data Private data of the governor. The devfreq framework does not
+ * @work: delayed work for load monitoring.
+ * @previous_freq: previously configured frequency value.
+ * @data: Private data of the governor. The devfreq framework does not
* touch this.
- * @being_removed a flag to mark that this object is being removed in
- * order to prevent trying to remove the object multiple times.
- * @min_freq Limit minimum frequency requested by user (0: none)
- * @max_freq Limit maximum frequency requested by user (0: none)
+ * @min_freq: Limit minimum frequency requested by user (0: none)
+ * @max_freq: Limit maximum frequency requested by user (0: none)
+ * @stop_polling: devfreq polling status of a device.
+ * @total_trans: Number of devfreq transitions
+ * @trans_table: Statistics of devfreq transitions
+ * @time_in_state: Statistics of devfreq states
+ * @last_stat_updated: The last time stat updated
*
* This structure stores the devfreq information for a give device.
*
@@ -152,26 +156,33 @@ struct devfreq {
struct device dev;
struct devfreq_dev_profile *profile;
const struct devfreq_governor *governor;
+ char governor_name[DEVFREQ_NAME_LEN];
struct notifier_block nb;
+ struct delayed_work work;
- unsigned long polling_jiffies;
unsigned long previous_freq;
- unsigned int next_polling;
void *data; /* private data for governors */
- bool being_removed;
-
unsigned long min_freq;
unsigned long max_freq;
+ bool stop_polling;
+
+ /* information for device freqeuncy transition */
+ unsigned int total_trans;
+ unsigned int *trans_table;
+ unsigned long *time_in_state;
+ unsigned long last_stat_updated;
};
#if defined(CONFIG_PM_DEVFREQ)
extern struct devfreq *devfreq_add_device(struct device *dev,
struct devfreq_dev_profile *profile,
- const struct devfreq_governor *governor,
+ const char *governor_name,
void *data);
extern int devfreq_remove_device(struct devfreq *devfreq);
+extern int devfreq_suspend_device(struct devfreq *devfreq);
+extern int devfreq_resume_device(struct devfreq *devfreq);
/* Helper functions for devfreq user device driver with OPP. */
extern struct opp *devfreq_recommended_opp(struct device *dev,
@@ -181,23 +192,13 @@ extern int devfreq_register_opp_notifier(struct device *dev,
extern int devfreq_unregister_opp_notifier(struct device *dev,
struct devfreq *devfreq);
-#ifdef CONFIG_DEVFREQ_GOV_POWERSAVE
-extern const struct devfreq_governor devfreq_powersave;
-#endif
-#ifdef CONFIG_DEVFREQ_GOV_PERFORMANCE
-extern const struct devfreq_governor devfreq_performance;
-#endif
-#ifdef CONFIG_DEVFREQ_GOV_USERSPACE
-extern const struct devfreq_governor devfreq_userspace;
-#endif
-#ifdef CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND
-extern const struct devfreq_governor devfreq_simple_ondemand;
+#if IS_ENABLED(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND)
/**
* struct devfreq_simple_ondemand_data - void *data fed to struct devfreq
* and devfreq_add_device
- * @ upthreshold If the load is over this value, the frequency jumps.
+ * @upthreshold: If the load is over this value, the frequency jumps.
* Specify 0 to use the default. Valid value = 0 to 100.
- * @ downdifferential If the load is under upthreshold - downdifferential,
+ * @downdifferential: If the load is under upthreshold - downdifferential,
* the governor may consider slowing the frequency down.
* Specify 0 to use the default. Valid value = 0 to 100.
* downdifferential < upthreshold must hold.
@@ -214,7 +215,7 @@ struct devfreq_simple_ondemand_data {
#else /* !CONFIG_PM_DEVFREQ */
static struct devfreq *devfreq_add_device(struct device *dev,
struct devfreq_dev_profile *profile,
- struct devfreq_governor *governor,
+ const char *governor_name,
void *data)
{
return NULL;
@@ -225,6 +226,16 @@ static int devfreq_remove_device(struct devfreq *devfreq)
return 0;
}
+static int devfreq_suspend_device(struct devfreq *devfreq)
+{
+ return 0;
+}
+
+static int devfreq_resume_device(struct devfreq *devfreq)
+{
+ return 0;
+}
+
static struct opp *devfreq_recommended_opp(struct device *dev,
unsigned long *freq, u32 flags)
{
@@ -243,11 +254,6 @@ static int devfreq_unregister_opp_notifier(struct device *dev,
return -EINVAL;
}
-#define devfreq_powersave NULL
-#define devfreq_performance NULL
-#define devfreq_userspace NULL
-#define devfreq_simple_ondemand NULL
-
#endif /* CONFIG_PM_DEVFREQ */
#endif /* __LINUX_DEVFREQ_H__ */
diff --git a/include/linux/device.h b/include/linux/device.h
index 86ef6ab553b..05292e48834 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -190,6 +190,7 @@ extern struct klist *bus_get_device_klist(struct bus_type *bus);
* @mod_name: Used for built-in modules.
* @suppress_bind_attrs: Disables bind/unbind via sysfs.
* @of_match_table: The open firmware table.
+ * @acpi_match_table: The ACPI match table.
* @probe: Called to query the existence of a specific device,
* whether this driver can work with it, and bind the driver
* to a specific device.
@@ -223,6 +224,7 @@ struct device_driver {
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
const struct of_device_id *of_match_table;
+ const struct acpi_device_id *acpi_match_table;
int (*probe) (struct device *dev);
int (*remove) (struct device *dev);
@@ -576,6 +578,12 @@ struct device_dma_parameters {
unsigned long segment_boundary_mask;
};
+struct acpi_dev_node {
+#ifdef CONFIG_ACPI
+ void *handle;
+#endif
+};
+
/**
* struct device - The basic device structure
* @parent: The device's "parent" device, the device to which it is attached.
@@ -616,6 +624,7 @@ struct device_dma_parameters {
* @dma_mem: Internal for coherent mem override.
* @archdata: For arch-specific additions.
* @of_node: Associated device tree node.
+ * @acpi_node: Associated ACPI device node.
* @devt: For creating the sysfs "dev".
* @id: device instance
* @devres_lock: Spinlock to protect the resource of the device.
@@ -680,6 +689,7 @@ struct device {
struct dev_archdata archdata;
struct device_node *of_node; /* associated device tree node */
+ struct acpi_dev_node acpi_node; /* associated ACPI device node */
dev_t devt; /* dev_t, creates the sysfs "dev" */
u32 id; /* device instance */
@@ -700,6 +710,14 @@ static inline struct device *kobj_to_dev(struct kobject *kobj)
return container_of(kobj, struct device, kobj);
}
+#ifdef CONFIG_ACPI
+#define ACPI_HANDLE(dev) ((dev)->acpi_node.handle)
+#define ACPI_HANDLE_SET(dev, _handle_) (dev)->acpi_node.handle = (_handle_)
+#else
+#define ACPI_HANDLE(dev) (NULL)
+#define ACPI_HANDLE_SET(dev, _handle_) do { } while (0)
+#endif
+
/* Get the wakeup routines, which depend on struct device */
#include <linux/pm_wakeup.h>
diff --git a/include/linux/devpts_fs.h b/include/linux/devpts_fs.h
index 5ce0e5fd712..251a2090a55 100644
--- a/include/linux/devpts_fs.h
+++ b/include/linux/devpts_fs.h
@@ -20,28 +20,28 @@
int devpts_new_index(struct inode *ptmx_inode);
void devpts_kill_index(struct inode *ptmx_inode, int idx);
/* mknod in devpts */
-int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty);
-/* get tty structure */
-struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number);
+struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index,
+ void *priv);
+/* get private structure */
+void *devpts_get_priv(struct inode *pts_inode);
/* unlink */
-void devpts_pty_kill(struct tty_struct *tty);
+void devpts_pty_kill(struct inode *inode);
#else
/* Dummy stubs in the no-pty case */
static inline int devpts_new_index(struct inode *ptmx_inode) { return -EINVAL; }
static inline void devpts_kill_index(struct inode *ptmx_inode, int idx) { }
-static inline int devpts_pty_new(struct inode *ptmx_inode,
- struct tty_struct *tty)
+static inline struct inode *devpts_pty_new(struct inode *ptmx_inode,
+ dev_t device, int index, void *priv)
{
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
-static inline struct tty_struct *devpts_get_tty(struct inode *pts_inode,
- int number)
+static inline void *devpts_get_priv(struct inode *pts_inode)
{
return NULL;
}
-static inline void devpts_pty_kill(struct tty_struct *tty) { }
+static inline void devpts_pty_kill(struct inode *inode) { }
#endif
diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h
index 2f303e4b7ed..01b5c84be82 100644
--- a/include/linux/dma-contiguous.h
+++ b/include/linux/dma-contiguous.h
@@ -68,7 +68,7 @@ struct device;
extern struct cma *dma_contiguous_default_area;
void dma_contiguous_reserve(phys_addr_t addr_limit);
-int dma_declare_contiguous(struct device *dev, unsigned long size,
+int dma_declare_contiguous(struct device *dev, phys_addr_t size,
phys_addr_t base, phys_addr_t limit);
struct page *dma_alloc_from_contiguous(struct device *dev, int count,
@@ -83,7 +83,7 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages,
static inline void dma_contiguous_reserve(phys_addr_t limit) { }
static inline
-int dma_declare_contiguous(struct device *dev, unsigned long size,
+int dma_declare_contiguous(struct device *dev, phys_addr_t size,
phys_addr_t base, phys_addr_t limit)
{
return -ENOSYS;
diff --git a/include/linux/edac.h b/include/linux/edac.h
index bab9f8473dc..1b8c02b36f7 100644
--- a/include/linux/edac.h
+++ b/include/linux/edac.h
@@ -533,6 +533,7 @@ struct csrow_info {
u32 ue_count; /* Uncorrectable Errors for this csrow */
u32 ce_count; /* Correctable Errors for this csrow */
+ u32 nr_pages; /* combined pages count of all channels */
struct mem_ctl_info *mci; /* the parent */
@@ -667,6 +668,8 @@ struct mem_ctl_info {
u32 fake_inject_ue;
u16 fake_inject_count;
#endif
+ __u8 csbased : 1, /* csrow-based memory controller */
+ __resv : 7;
};
#endif
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index d09af4b67cf..b90091af579 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -177,6 +177,7 @@ static inline int freeze_kernel_threads(void) { return -ENOSYS; }
static inline void thaw_processes(void) {}
static inline void thaw_kernel_threads(void) {}
+static inline bool try_to_freeze_nowarn(void) { return false; }
static inline bool try_to_freeze(void) { return false; }
static inline void freezer_do_not_count(void) {}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b33cfc97b9c..408fb1e77a0 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -418,7 +418,7 @@ struct address_space {
struct backing_dev_info *backing_dev_info; /* device readahead, etc */
spinlock_t private_lock; /* for use by the address_space */
struct list_head private_list; /* ditto */
- struct address_space *assoc_mapping; /* ditto */
+ void *private_data; /* ditto */
} __attribute__((aligned(sizeof(long))));
/*
* On most architectures that alignment is already the case; but
@@ -462,8 +462,6 @@ struct block_device {
int bd_fsfreeze_count;
/* Mutex for freeze */
struct mutex bd_fsfreeze_mutex;
- /* A semaphore that prevents I/O while block size is being changed */
- struct percpu_rw_semaphore bd_block_size_semaphore;
};
/*
@@ -2049,7 +2047,6 @@ extern void unregister_blkdev(unsigned int, const char *);
extern struct block_device *bdget(dev_t);
extern struct block_device *bdgrab(struct block_device *bdev);
extern void bd_set_size(struct block_device *, loff_t size);
-extern sector_t blkdev_max_block(struct block_device *bdev);
extern void bd_forget(struct inode *inode);
extern void bdput(struct block_device *);
extern void invalidate_bdev(struct block_device *);
@@ -2379,8 +2376,6 @@ extern int generic_segment_checks(const struct iovec *iov,
unsigned long *nr_segs, size_t *count, int access_flags);
/* fs/block_dev.c */
-extern ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos);
extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos);
extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end,
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 642928cf57b..a3d489531d8 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -86,6 +86,12 @@ struct trace_iterator {
cpumask_var_t started;
};
+enum trace_iter_flags {
+ TRACE_FILE_LAT_FMT = 1,
+ TRACE_FILE_ANNOTATE = 2,
+ TRACE_FILE_TIME_IN_NS = 4,
+};
+
struct trace_event;
@@ -127,13 +133,13 @@ trace_current_buffer_lock_reserve(struct ring_buffer **current_buffer,
void trace_current_buffer_unlock_commit(struct ring_buffer *buffer,
struct ring_buffer_event *event,
unsigned long flags, int pc);
-void trace_nowake_buffer_unlock_commit(struct ring_buffer *buffer,
- struct ring_buffer_event *event,
- unsigned long flags, int pc);
-void trace_nowake_buffer_unlock_commit_regs(struct ring_buffer *buffer,
- struct ring_buffer_event *event,
- unsigned long flags, int pc,
- struct pt_regs *regs);
+void trace_buffer_unlock_commit(struct ring_buffer *buffer,
+ struct ring_buffer_event *event,
+ unsigned long flags, int pc);
+void trace_buffer_unlock_commit_regs(struct ring_buffer *buffer,
+ struct ring_buffer_event *event,
+ unsigned long flags, int pc,
+ struct pt_regs *regs);
void trace_current_buffer_discard_commit(struct ring_buffer *buffer,
struct ring_buffer_event *event);
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 02c1c9710be..31e8041274f 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -31,6 +31,7 @@ struct vm_area_struct;
#define ___GFP_THISNODE 0x40000u
#define ___GFP_RECLAIMABLE 0x80000u
#define ___GFP_NOTRACK 0x200000u
+#define ___GFP_NO_KSWAPD 0x400000u
#define ___GFP_OTHER_NODE 0x800000u
#define ___GFP_WRITE 0x1000000u
@@ -85,6 +86,7 @@ struct vm_area_struct;
#define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) /* Page is reclaimable */
#define __GFP_NOTRACK ((__force gfp_t)___GFP_NOTRACK) /* Don't track with kmemcheck */
+#define __GFP_NO_KSWAPD ((__force gfp_t)___GFP_NO_KSWAPD)
#define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */
#define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) /* Allocator intends to dirty page */
@@ -114,7 +116,8 @@ struct vm_area_struct;
__GFP_MOVABLE)
#define GFP_IOFS (__GFP_IO | __GFP_FS)
#define GFP_TRANSHUGE (GFP_HIGHUSER_MOVABLE | __GFP_COMP | \
- __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN)
+ __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN | \
+ __GFP_NO_KSWAPD)
#ifdef CONFIG_NUMA
#define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY)
@@ -263,7 +266,7 @@ static inline enum zone_type gfp_zone(gfp_t flags)
static inline int gfp_zonelist(gfp_t flags)
{
- if (NUMA_BUILD && unlikely(flags & __GFP_THISNODE))
+ if (IS_ENABLED(CONFIG_NUMA) && unlikely(flags & __GFP_THISNODE))
return 1;
return 0;
diff --git a/include/linux/gpio.h b/include/linux/gpio.h
index 2e31e8b3a19..bfe66562153 100644
--- a/include/linux/gpio.h
+++ b/include/linux/gpio.h
@@ -72,9 +72,9 @@ static inline int irq_to_gpio(unsigned int irq)
return -EINVAL;
}
-#endif
+#endif /* ! CONFIG_ARCH_HAVE_CUSTOM_GPIO_H */
-#else
+#else /* ! CONFIG_GENERIC_GPIO */
#include <linux/kernel.h>
#include <linux/types.h>
@@ -231,6 +231,21 @@ static inline int irq_to_gpio(unsigned irq)
return -EINVAL;
}
-#endif
+static inline int
+gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
+ unsigned int gpio_offset, unsigned int pin_offset,
+ unsigned int npins)
+{
+ WARN_ON(1);
+ return -EINVAL;
+}
+
+static inline void
+gpiochip_remove_pin_ranges(struct gpio_chip *chip)
+{
+ WARN_ON(1);
+}
+
+#endif /* ! CONFIG_GENERIC_GPIO */
#endif /* __LINUX_GPIO_H */
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index cab3da3d094..624ef3f45c8 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -4,6 +4,7 @@
#include <linux/preempt.h>
#include <linux/lockdep.h>
#include <linux/ftrace_irq.h>
+#include <linux/vtime.h>
#include <asm/hardirq.h>
/*
@@ -129,16 +130,6 @@ extern void synchronize_irq(unsigned int irq);
# define synchronize_irq(irq) barrier()
#endif
-struct task_struct;
-
-#if !defined(CONFIG_VIRT_CPU_ACCOUNTING) && !defined(CONFIG_IRQ_TIME_ACCOUNTING)
-static inline void vtime_account(struct task_struct *tsk)
-{
-}
-#else
-extern void vtime_account(struct task_struct *tsk);
-#endif
-
#if defined(CONFIG_TINY_RCU) || defined(CONFIG_TINY_PREEMPT_RCU)
static inline void rcu_nmi_enter(void)
@@ -162,7 +153,7 @@ extern void rcu_nmi_exit(void);
*/
#define __irq_enter() \
do { \
- vtime_account(current); \
+ vtime_account_irq_enter(current); \
add_preempt_count(HARDIRQ_OFFSET); \
trace_hardirq_enter(); \
} while (0)
@@ -178,7 +169,7 @@ extern void irq_enter(void);
#define __irq_exit() \
do { \
trace_hardirq_exit(); \
- vtime_account(current); \
+ vtime_account_irq_exit(current); \
sub_preempt_count(HARDIRQ_OFFSET); \
} while (0)
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index b31cb7da034..1af47755245 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -8,6 +8,10 @@ extern int do_huge_pmd_anonymous_page(struct mm_struct *mm,
extern int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,
pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long addr,
struct vm_area_struct *vma);
+extern void huge_pmd_set_accessed(struct mm_struct *mm,
+ struct vm_area_struct *vma,
+ unsigned long address, pmd_t *pmd,
+ pmd_t orig_pmd, int dirty);
extern int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long address, pmd_t *pmd,
pmd_t orig_pmd);
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 225164842ab..3e7fa1acf09 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -183,7 +183,8 @@ extern const struct file_operations hugetlbfs_file_operations;
extern const struct vm_operations_struct hugetlb_vm_ops;
struct file *hugetlb_file_setup(const char *name, unsigned long addr,
size_t size, vm_flags_t acct,
- struct user_struct **user, int creat_flags);
+ struct user_struct **user, int creat_flags,
+ int page_size_log);
static inline int is_file_hugepages(struct file *file)
{
@@ -195,12 +196,14 @@ static inline int is_file_hugepages(struct file *file)
return 0;
}
+
#else /* !CONFIG_HUGETLBFS */
#define is_file_hugepages(file) 0
static inline struct file *
hugetlb_file_setup(const char *name, unsigned long addr, size_t size,
- vm_flags_t acctflag, struct user_struct **user, int creat_flags)
+ vm_flags_t acctflag, struct user_struct **user, int creat_flags,
+ int page_size_log)
{
return ERR_PTR(-ENOSYS);
}
diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h
index 6ae9c631a1b..0464c85e63f 100644
--- a/include/linux/hw_breakpoint.h
+++ b/include/linux/hw_breakpoint.h
@@ -1,35 +1,8 @@
#ifndef _LINUX_HW_BREAKPOINT_H
#define _LINUX_HW_BREAKPOINT_H
-enum {
- HW_BREAKPOINT_LEN_1 = 1,
- HW_BREAKPOINT_LEN_2 = 2,
- HW_BREAKPOINT_LEN_4 = 4,
- HW_BREAKPOINT_LEN_8 = 8,
-};
-
-enum {
- HW_BREAKPOINT_EMPTY = 0,
- HW_BREAKPOINT_R = 1,
- HW_BREAKPOINT_W = 2,
- HW_BREAKPOINT_RW = HW_BREAKPOINT_R | HW_BREAKPOINT_W,
- HW_BREAKPOINT_X = 4,
- HW_BREAKPOINT_INVALID = HW_BREAKPOINT_RW | HW_BREAKPOINT_X,
-};
-
-enum bp_type_idx {
- TYPE_INST = 0,
-#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS
- TYPE_DATA = 0,
-#else
- TYPE_DATA = 1,
-#endif
- TYPE_MAX
-};
-
-#ifdef __KERNEL__
-
#include <linux/perf_event.h>
+#include <uapi/linux/hw_breakpoint.h>
#ifdef CONFIG_HAVE_HW_BREAKPOINT
@@ -151,6 +124,4 @@ static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
}
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_HW_BREAKPOINT_H */
diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
index df804ba73e0..92a0dc75bc7 100644
--- a/include/linux/i2c-omap.h
+++ b/include/linux/i2c-omap.h
@@ -34,6 +34,7 @@ struct omap_i2c_bus_platform_data {
u32 clkrate;
u32 rev;
u32 flags;
+ void (*set_mpu_wkup_lat)(struct device *dev, long set);
};
#endif
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 800de224336..d0c4db7b487 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -259,6 +259,7 @@ static inline void i2c_set_clientdata(struct i2c_client *dev, void *data)
* @platform_data: stored in i2c_client.dev.platform_data
* @archdata: copied into i2c_client.dev.archdata
* @of_node: pointer to OpenFirmware device node
+ * @acpi_node: ACPI device node
* @irq: stored in i2c_client.irq
*
* I2C doesn't actually support hardware probing, although controllers and
@@ -279,6 +280,7 @@ struct i2c_board_info {
void *platform_data;
struct dev_archdata *archdata;
struct device_node *of_node;
+ struct acpi_dev_node acpi_node;
int irq;
};
@@ -501,4 +503,11 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap)
i2c_del_driver)
#endif /* I2C */
+
+#if IS_ENABLED(CONFIG_ACPI_I2C)
+extern void acpi_i2c_register_devices(struct i2c_adapter *adap);
+#else
+static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) {}
+#endif
+
#endif /* _LINUX_I2C_H */
diff --git a/include/linux/i2c/pcf857x.h b/include/linux/i2c/pcf857x.h
index 781e6bd06c3..0767a2a6b2f 100644
--- a/include/linux/i2c/pcf857x.h
+++ b/include/linux/i2c/pcf857x.h
@@ -10,7 +10,6 @@
* @setup: optional callback issued once the GPIOs are valid
* @teardown: optional callback issued before the GPIOs are invalidated
* @context: optional parameter passed to setup() and teardown()
- * @irq: optional interrupt number
*
* In addition to the I2C_BOARD_INFO() state appropriate to each chip,
* the i2c_board_info used with the pcf875x driver must provide its
@@ -40,8 +39,6 @@ struct pcf857x_platform_data {
int gpio, unsigned ngpio,
void *context);
void *context;
-
- int irq;
};
#endif /* __LINUX_PCF857X_H */
diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h
index c629b3a1d9a..f3eea18fdf4 100644
--- a/include/linux/iio/buffer.h
+++ b/include/linux/iio/buffer.h
@@ -66,7 +66,8 @@ struct iio_buffer_access_funcs {
* @stufftoread: [INTERN] flag to indicate new data.
* @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.
+ */
struct iio_buffer {
int length;
int bytes_per_datum;
@@ -81,9 +82,22 @@ struct iio_buffer {
const struct attribute_group *attrs;
struct list_head demux_list;
unsigned char *demux_bounce;
+ struct list_head buffer_list;
};
/**
+ * iio_update_buffers() - add or remove buffer from active list
+ * @indio_dev: device to add buffer to
+ * @insert_buffer: buffer to insert
+ * @remove_buffer: buffer_to_remove
+ *
+ * Note this will tear down the all buffering and build it up again
+ */
+int iio_update_buffers(struct iio_dev *indio_dev,
+ struct iio_buffer *insert_buffer,
+ struct iio_buffer *remove_buffer);
+
+/**
* iio_buffer_init() - Initialize the buffer structure
* @buffer: buffer to be initialized
**/
@@ -115,11 +129,11 @@ int iio_scan_mask_set(struct iio_dev *indio_dev,
struct iio_buffer *buffer, int bit);
/**
- * iio_push_to_buffer() - push to a registered buffer.
- * @buffer: IIO buffer structure for device
- * @data: the data to push to the buffer
+ * iio_push_to_buffers() - push to a registered buffer.
+ * @indio_dev: iio_dev structure for device.
+ * @data: Full scan.
*/
-int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data);
+int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data);
int iio_update_demux(struct iio_dev *indio_dev);
@@ -181,7 +195,7 @@ bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev,
#else /* CONFIG_IIO_BUFFER */
static inline int iio_buffer_register(struct iio_dev *indio_dev,
- struct iio_chan_spec *channels,
+ const struct iio_chan_spec *channels,
int num_channels)
{
return 0;
diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
index e875bcf0478..16c35ac045b 100644
--- a/include/linux/iio/consumer.h
+++ b/include/linux/iio/consumer.h
@@ -9,6 +9,8 @@
*/
#ifndef _IIO_INKERN_CONSUMER_H_
#define _IIO_INKERN_CONSUMER_H_
+
+#include <linux/types.h>
#include <linux/iio/types.h>
struct iio_dev;
@@ -18,10 +20,12 @@ struct iio_chan_spec;
* struct iio_channel - everything needed for a consumer to use a channel
* @indio_dev: Device on which the channel exists.
* @channel: Full description of the channel.
+ * @data: Data about the channel used by consumer.
*/
struct iio_channel {
struct iio_dev *indio_dev;
const struct iio_chan_spec *channel;
+ void *data;
};
/**
@@ -59,6 +63,52 @@ struct iio_channel *iio_channel_get_all(const char *name);
*/
void iio_channel_release_all(struct iio_channel *chan);
+struct iio_cb_buffer;
+/**
+ * iio_channel_get_all_cb() - register callback for triggered capture
+ * @name: Name of client device.
+ * @cb: Callback function.
+ * @private: Private data passed to callback.
+ *
+ * NB right now we have no ability to mux data from multiple devices.
+ * So if the channels requested come from different devices this will
+ * fail.
+ */
+struct iio_cb_buffer *iio_channel_get_all_cb(const char *name,
+ int (*cb)(u8 *data,
+ void *private),
+ void *private);
+/**
+ * iio_channel_release_all_cb() - release and unregister the callback.
+ * @cb_buffer: The callback buffer that was allocated.
+ */
+void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buffer);
+
+/**
+ * iio_channel_start_all_cb() - start the flow of data through callback.
+ * @cb_buff: The callback buffer we are starting.
+ */
+int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff);
+
+/**
+ * iio_channel_stop_all_cb() - stop the flow of data through the callback.
+ * @cb_buff: The callback buffer we are stopping.
+ */
+void iio_channel_stop_all_cb(struct iio_cb_buffer *cb_buff);
+
+/**
+ * iio_channel_cb_get_channels() - get access to the underlying channels.
+ * @cb_buff: The callback buffer from whom we want the channel
+ * information.
+ *
+ * This function allows one to obtain information about the channels.
+ * Whilst this may allow direct reading if all buffers are disabled, the
+ * primary aim is to allow drivers that are consuming a channel to query
+ * things like scaling of the channel.
+ */
+struct iio_channel
+*iio_channel_cb_get_channels(const struct iio_cb_buffer *cb_buffer);
+
/**
* iio_read_channel_raw() - read from a given channel
* @chan: The channel being queried.
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 7806c24e5bc..da8c776ba0b 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -410,6 +410,7 @@ struct iio_buffer_setup_ops {
* and owner
* @event_interface: [INTERN] event chrdevs associated with interrupt lines
* @buffer: [DRIVER] any buffer present
+ * @buffer_list: [INTERN] list of all buffers currently attached
* @scan_bytes: [INTERN] num bytes captured to be fed to buffer demux
* @mlock: [INTERN] lock used to prevent simultaneous device state
* changes
@@ -448,6 +449,7 @@ struct iio_dev {
struct iio_event_interface *event_interface;
struct iio_buffer *buffer;
+ struct list_head buffer_list;
int scan_bytes;
struct mutex mlock;
@@ -618,6 +620,9 @@ static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev)
};
#endif
+int iio_str_to_fixpoint(const char *str, int fract_mult, int *integer,
+ int *fract);
+
/**
* IIO_DEGREE_TO_RAD() - Convert degree to rad
* @deg: A value in degree
diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h
new file mode 100644
index 00000000000..ff781dca2e9
--- /dev/null
+++ b/include/linux/iio/imu/adis.h
@@ -0,0 +1,280 @@
+/*
+ * Common library for ADIS16XXX devices
+ *
+ * Copyright 2012 Analog Devices Inc.
+ * Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __IIO_ADIS_H__
+#define __IIO_ADIS_H__
+
+#include <linux/spi/spi.h>
+#include <linux/interrupt.h>
+#include <linux/iio/types.h>
+
+#define ADIS_WRITE_REG(reg) ((0x80 | (reg)))
+#define ADIS_READ_REG(reg) ((reg) & 0x7f)
+
+#define ADIS_PAGE_SIZE 0x80
+#define ADIS_REG_PAGE_ID 0x00
+
+struct adis;
+
+/**
+ * struct adis_data - ADIS chip variant specific data
+ * @read_delay: SPI delay for read operations in us
+ * @write_delay: SPI delay for write operations in us
+ * @glob_cmd_reg: Register address of the GLOB_CMD register
+ * @msc_ctrl_reg: Register address of the MSC_CTRL register
+ * @diag_stat_reg: Register address of the DIAG_STAT register
+ * @status_error_msgs: Array of error messgaes
+ * @status_error_mask:
+ */
+struct adis_data {
+ unsigned int read_delay;
+ unsigned int write_delay;
+
+ unsigned int glob_cmd_reg;
+ unsigned int msc_ctrl_reg;
+ unsigned int diag_stat_reg;
+
+ unsigned int self_test_mask;
+ unsigned int startup_delay;
+
+ const char * const *status_error_msgs;
+ unsigned int status_error_mask;
+
+ int (*enable_irq)(struct adis *adis, bool enable);
+
+ bool has_paging;
+};
+
+struct adis {
+ struct spi_device *spi;
+ struct iio_trigger *trig;
+
+ const struct adis_data *data;
+
+ struct mutex txrx_lock;
+ struct spi_message msg;
+ struct spi_transfer *xfer;
+ unsigned int current_page;
+ void *buffer;
+
+ uint8_t tx[10] ____cacheline_aligned;
+ uint8_t rx[4];
+};
+
+int adis_init(struct adis *adis, struct iio_dev *indio_dev,
+ struct spi_device *spi, const struct adis_data *data);
+int adis_reset(struct adis *adis);
+
+int adis_write_reg(struct adis *adis, unsigned int reg,
+ unsigned int val, unsigned int size);
+int adis_read_reg(struct adis *adis, unsigned int reg,
+ unsigned int *val, unsigned int size);
+
+/**
+ * adis_write_reg_8() - Write single byte to a register
+ * @adis: The adis device
+ * @reg: The address of the register to be written
+ * @value: The value to write
+ */
+static inline int adis_write_reg_8(struct adis *adis, unsigned int reg,
+ uint8_t val)
+{
+ return adis_write_reg(adis, reg, val, 1);
+}
+
+/**
+ * adis_write_reg_16() - Write 2 bytes to a pair of registers
+ * @adis: The adis device
+ * @reg: The address of the lower of the two registers
+ * @value: Value to be written
+ */
+static inline int adis_write_reg_16(struct adis *adis, unsigned int reg,
+ uint16_t val)
+{
+ return adis_write_reg(adis, reg, val, 2);
+}
+
+/**
+ * adis_write_reg_32() - write 4 bytes to four registers
+ * @adis: The adis device
+ * @reg: The address of the lower of the four register
+ * @value: Value to be written
+ */
+static inline int adis_write_reg_32(struct adis *adis, unsigned int reg,
+ uint32_t val)
+{
+ return adis_write_reg(adis, reg, val, 4);
+}
+
+/**
+ * adis_read_reg_16() - read 2 bytes from a 16-bit register
+ * @adis: The adis device
+ * @reg: The address of the lower of the two registers
+ * @val: The value read back from the device
+ */
+static inline int adis_read_reg_16(struct adis *adis, unsigned int reg,
+ uint16_t *val)
+{
+ unsigned int tmp;
+ int ret;
+
+ ret = adis_read_reg(adis, reg, &tmp, 2);
+ *val = tmp;
+
+ return ret;
+}
+
+/**
+ * adis_read_reg_32() - read 4 bytes from a 32-bit register
+ * @adis: The adis device
+ * @reg: The address of the lower of the two registers
+ * @val: The value read back from the device
+ */
+static inline int adis_read_reg_32(struct adis *adis, unsigned int reg,
+ uint32_t *val)
+{
+ unsigned int tmp;
+ int ret;
+
+ ret = adis_read_reg(adis, reg, &tmp, 4);
+ *val = tmp;
+
+ return ret;
+}
+
+int adis_enable_irq(struct adis *adis, bool enable);
+int adis_check_status(struct adis *adis);
+
+int adis_initial_startup(struct adis *adis);
+
+int adis_single_conversion(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, unsigned int error_mask,
+ int *val);
+
+#define ADIS_VOLTAGE_CHAN(addr, si, chan, name, bits) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = (chan), \
+ .extend_name = name, \
+ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+ IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
+ .address = (addr), \
+ .scan_index = (si), \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = (bits), \
+ .storagebits = 16, \
+ .endianness = IIO_BE, \
+ }, \
+}
+
+#define ADIS_SUPPLY_CHAN(addr, si, bits) \
+ ADIS_VOLTAGE_CHAN(addr, si, 0, "supply", bits)
+
+#define ADIS_AUX_ADC_CHAN(addr, si, bits) \
+ ADIS_VOLTAGE_CHAN(addr, si, 1, NULL, bits)
+
+#define ADIS_TEMP_CHAN(addr, si, bits) { \
+ .type = IIO_TEMP, \
+ .indexed = 1, \
+ .channel = 0, \
+ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+ IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \
+ IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \
+ .address = (addr), \
+ .scan_index = (si), \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = (bits), \
+ .storagebits = 16, \
+ .endianness = IIO_BE, \
+ }, \
+}
+
+#define ADIS_MOD_CHAN(_type, mod, addr, si, info, bits) { \
+ .type = (_type), \
+ .modified = 1, \
+ .channel2 = IIO_MOD_ ## mod, \
+ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+ IIO_CHAN_INFO_SCALE_SHARED_BIT | \
+ info, \
+ .address = (addr), \
+ .scan_index = (si), \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = (bits), \
+ .storagebits = 16, \
+ .endianness = IIO_BE, \
+ }, \
+}
+
+#define ADIS_ACCEL_CHAN(mod, addr, si, info, bits) \
+ ADIS_MOD_CHAN(IIO_ACCEL, mod, addr, si, info, bits)
+
+#define ADIS_GYRO_CHAN(mod, addr, si, info, bits) \
+ ADIS_MOD_CHAN(IIO_ANGL_VEL, mod, addr, si, info, bits)
+
+#define ADIS_INCLI_CHAN(mod, addr, si, info, bits) \
+ ADIS_MOD_CHAN(IIO_INCLI, mod, addr, si, info, bits)
+
+#define ADIS_ROT_CHAN(mod, addr, si, info, bits) \
+ ADIS_MOD_CHAN(IIO_ROT, mod, addr, si, info, bits)
+
+#ifdef CONFIG_IIO_ADIS_LIB_BUFFER
+
+int adis_setup_buffer_and_trigger(struct adis *adis,
+ struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *));
+void adis_cleanup_buffer_and_trigger(struct adis *adis,
+ struct iio_dev *indio_dev);
+
+int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev);
+void adis_remove_trigger(struct adis *adis);
+
+int adis_update_scan_mode(struct iio_dev *indio_dev,
+ const unsigned long *scan_mask);
+
+#else /* CONFIG_IIO_BUFFER */
+
+static inline int adis_setup_buffer_and_trigger(struct adis *adis,
+ struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *))
+{
+ return 0;
+}
+
+static inline void adis_cleanup_buffer_and_trigger(struct adis *adis,
+ struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis_probe_trigger(struct adis *adis,
+ struct iio_dev *indio_dev)
+{
+ return 0;
+}
+
+static inline void adis_remove_trigger(struct adis *adis)
+{
+}
+
+#define adis_update_scan_mode NULL
+
+#endif /* CONFIG_IIO_BUFFER */
+
+#ifdef CONFIG_DEBUG_FS
+
+int adis_debugfs_reg_access(struct iio_dev *indio_dev,
+ unsigned int reg, unsigned int writeval, unsigned int *readval);
+
+#else
+
+#define adis_debugfs_reg_access NULL
+
+#endif
+
+#endif
diff --git a/include/linux/iio/machine.h b/include/linux/iio/machine.h
index 809a3f08d5a..1601a2a63a7 100644
--- a/include/linux/iio/machine.h
+++ b/include/linux/iio/machine.h
@@ -19,11 +19,13 @@
* @consumer_dev_name: Name to uniquely identify the consumer device.
* @consumer_channel: Unique name used to identify the channel on the
* consumer side.
+ * @consumer_data: Data about the channel for use by the consumer driver.
*/
struct iio_map {
const char *adc_channel_label;
const char *consumer_dev_name;
const char *consumer_channel;
+ void *consumer_data;
};
#endif
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index 5c647ecfd5b..88bf0f0d27b 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -28,6 +28,7 @@ enum iio_chan_type {
IIO_CAPACITANCE,
IIO_ALTVOLTAGE,
IIO_CCT,
+ IIO_PRESSURE,
};
enum iio_modifier {
@@ -58,5 +59,6 @@ enum iio_modifier {
#define IIO_VAL_INT_PLUS_NANO 3
#define IIO_VAL_INT_PLUS_MICRO_DB 4
#define IIO_VAL_FRACTIONAL 10
+#define IIO_VAL_FRACTIONAL_LOG2 11
#endif /* _IIO_TYPES_H_ */
diff --git a/include/linux/init.h b/include/linux/init.h
index e59041e21df..f63692d6902 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -93,13 +93,13 @@
#define __exit __section(.exit.text) __exitused __cold notrace
-/* Used for HOTPLUG */
-#define __devinit __section(.devinit.text) __cold notrace
-#define __devinitdata __section(.devinit.data)
-#define __devinitconst __constsection(.devinit.rodata)
-#define __devexit __section(.devexit.text) __exitused __cold notrace
-#define __devexitdata __section(.devexit.data)
-#define __devexitconst __constsection(.devexit.rodata)
+/* Used for HOTPLUG, but that is always enabled now, so just make them noops */
+#define __devinit
+#define __devinitdata
+#define __devinitconst
+#define __devexit
+#define __devexitdata
+#define __devexitconst
/* Used for HOTPLUG_CPU */
#define __cpuinit __section(.cpuinit.text) __cold notrace
@@ -126,10 +126,6 @@
#define __INITRODATA .section ".init.rodata","a",%progbits
#define __FINITDATA .previous
-#define __DEVINIT .section ".devinit.text", "ax"
-#define __DEVINITDATA .section ".devinit.data", "aw"
-#define __DEVINITRODATA .section ".devinit.rodata", "a"
-
#define __CPUINIT .section ".cpuinit.text", "ax"
#define __CPUINITDATA .section ".cpuinit.data", "aw"
#define __CPUINITRODATA .section ".cpuinit.rodata", "a"
diff --git a/drivers/staging/ipack/ipack.h b/include/linux/ipack.h
index d8e3bb6feac..fea12cbb2ae 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/include/linux/ipack.h
@@ -1,8 +1,8 @@
/*
* Industry-pack bus.
*
- * (C) 2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
- * (C) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
+ * Copyright (C) 2011-2012 CERN (www.cern.ch)
+ * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.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
@@ -13,8 +13,6 @@
#include <linux/device.h>
#include <linux/interrupt.h>
-#include "ipack_ids.h"
-
#define IPACK_IDPROM_OFFSET_I 0x01
#define IPACK_IDPROM_OFFSET_P 0x03
#define IPACK_IDPROM_OFFSET_A 0x05
@@ -28,31 +26,63 @@
#define IPACK_IDPROM_OFFSET_NUM_BYTES 0x15
#define IPACK_IDPROM_OFFSET_CRC 0x17
+/*
+ * IndustryPack Fromat, Vendor and Device IDs.
+ */
+
+/* ID section format versions */
+#define IPACK_ID_VERSION_INVALID 0x00
+#define IPACK_ID_VERSION_1 0x01
+#define IPACK_ID_VERSION_2 0x02
+
+/* Vendors and devices. Sort key: vendor first, device next. */
+#define IPACK1_VENDOR_ID_RESERVED1 0x00
+#define IPACK1_VENDOR_ID_RESERVED2 0xFF
+#define IPACK1_VENDOR_ID_UNREGISTRED01 0x01
+#define IPACK1_VENDOR_ID_UNREGISTRED02 0x02
+#define IPACK1_VENDOR_ID_UNREGISTRED03 0x03
+#define IPACK1_VENDOR_ID_UNREGISTRED04 0x04
+#define IPACK1_VENDOR_ID_UNREGISTRED05 0x05
+#define IPACK1_VENDOR_ID_UNREGISTRED06 0x06
+#define IPACK1_VENDOR_ID_UNREGISTRED07 0x07
+#define IPACK1_VENDOR_ID_UNREGISTRED08 0x08
+#define IPACK1_VENDOR_ID_UNREGISTRED09 0x09
+#define IPACK1_VENDOR_ID_UNREGISTRED10 0x0A
+#define IPACK1_VENDOR_ID_UNREGISTRED11 0x0B
+#define IPACK1_VENDOR_ID_UNREGISTRED12 0x0C
+#define IPACK1_VENDOR_ID_UNREGISTRED13 0x0D
+#define IPACK1_VENDOR_ID_UNREGISTRED14 0x0E
+#define IPACK1_VENDOR_ID_UNREGISTRED15 0x0F
+
+#define IPACK1_VENDOR_ID_SBS 0xF0
+#define IPACK1_DEVICE_ID_SBS_OCTAL_232 0x22
+#define IPACK1_DEVICE_ID_SBS_OCTAL_422 0x2A
+#define IPACK1_DEVICE_ID_SBS_OCTAL_485 0x48
+
struct ipack_bus_ops;
struct ipack_driver;
enum ipack_space {
IPACK_IO_SPACE = 0,
- IPACK_ID_SPACE = 1,
- IPACK_MEM_SPACE = 2,
+ IPACK_ID_SPACE,
IPACK_INT_SPACE,
+ IPACK_MEM8_SPACE,
+ IPACK_MEM16_SPACE,
+ /* Dummy for counting the number of entries. Must remain the last
+ * entry */
+ IPACK_SPACE_COUNT,
};
/**
- * struct ipack_addr_space - Virtual address space mapped for a specified type.
- *
- * @address: virtual address
- * @size: size of the mapped space
*/
-struct ipack_addr_space {
- void __iomem *address;
- unsigned int size;
+struct ipack_region {
+ phys_addr_t start;
+ size_t size;
};
/**
* struct ipack_device
*
- * @bus_nr: IP bus number where the device is plugged
* @slot: Slot where the device is plugged in the carrier board
* @bus: ipack_bus_device where the device is plugged to.
* @id_space: Virtual address to ID space.
@@ -65,14 +95,11 @@ struct ipack_addr_space {
* by the carrier board throught bus->ops.
*/
struct ipack_device {
- unsigned int bus_nr;
unsigned int slot;
struct ipack_bus_device *bus;
- struct ipack_addr_space id_space;
- struct ipack_addr_space io_space;
- struct ipack_addr_space int_space;
- struct ipack_addr_space mem_space;
struct device dev;
+ void (*release) (struct ipack_device *dev);
+ struct ipack_region region[IPACK_SPACE_COUNT];
u8 *id;
size_t id_avail;
u32 id_vendor;
@@ -84,10 +111,11 @@ struct ipack_device {
};
/**
- * struct ipack_driver_ops -- callbacks to mezzanine driver for installing/removing one device
+ * struct ipack_driver_ops -- Callbacks to IPack device driver
*
- * @probe: Probe function
- * @remove: tell the driver that the carrier board wants to remove one device
+ * @probe: Probe function
+ * @remove: Prepare imminent removal of the device. Services provided by the
+ * device should be revoked.
*/
struct ipack_driver_ops {
@@ -96,10 +124,10 @@ struct ipack_driver_ops {
};
/**
- * struct ipack_driver -- Specific data to each ipack board driver
+ * struct ipack_driver -- Specific data to each ipack device driver
*
- * @driver: Device driver kernel representation
- * @ops: Mezzanine driver operations specific for the ipack bus.
+ * @driver: Device driver kernel representation
+ * @ops: Callbacks provided by the IPack device driver
*/
struct ipack_driver {
struct device_driver driver;
@@ -125,8 +153,6 @@ struct ipack_driver {
* @reset_timeout: Resets the state returned by get_timeout.
*/
struct ipack_bus_ops {
- int (*map_space) (struct ipack_device *dev, unsigned int memory_size, int space);
- int (*unmap_space) (struct ipack_device *dev, int space);
int (*request_irq) (struct ipack_device *dev,
irqreturn_t (*handler)(void *), void *arg);
int (*free_irq) (struct ipack_device *dev);
@@ -171,7 +197,7 @@ struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots,
int ipack_bus_unregister(struct ipack_bus_device *bus);
/**
- * ipack_driver_register -- Register a new driver
+ * ipack_driver_register -- Register a new ipack device driver
*
* Called by a ipack driver to register itself as a driver
* that can manage ipack devices.
@@ -181,15 +207,18 @@ int ipack_driver_register(struct ipack_driver *edrv, struct module *owner,
void ipack_driver_unregister(struct ipack_driver *edrv);
/**
- * ipack_device_register -- register a new mezzanine device
+ * ipack_device_register -- register an IPack device with the kernel
+ * @dev: the new device to register.
*
- * @bus: ipack bus device it is plugged to.
- * @slot: slot position in the bus device.
+ * Register a new IPack device ("module" in IndustryPack jargon). The call
+ * is done by the carrier driver. The carrier should populate the fields
+ * bus and slot as well as the region array of @dev prior to calling this
+ * function. The rest of the fields will be allocated and populated
+ * during registration.
*
- * Register a new ipack device (mezzanine device). The call is done by
- * the carrier device driver.
+ * Return zero on success or error code on failure.
*/
-struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, int slot);
+int ipack_device_register(struct ipack_device *dev);
void ipack_device_unregister(struct ipack_device *dev);
/**
@@ -200,8 +229,7 @@ void ipack_device_unregister(struct ipack_device *dev);
* in a generic manner.
*/
#define DEFINE_IPACK_DEVICE_TABLE(_table) \
- const struct ipack_device_id _table[] __devinitconst
-
+ const struct ipack_device_id _table[]
/**
* IPACK_DEVICE - macro used to describe a specific IndustryPack device
* @_format: the format version (currently either 1 or 2, 8 bit value)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 216b0ba109d..526f10a637c 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -392,6 +392,15 @@ static inline void irq_move_masked_irq(struct irq_data *data) { }
extern int no_irq_affinity;
+#ifdef CONFIG_HARDIRQS_SW_RESEND
+int irq_set_parent(int irq, int parent_irq);
+#else
+static inline int irq_set_parent(int irq, int parent_irq)
+{
+ return 0;
+}
+#endif
+
/*
* Built-in IRQ handlers for various IRQ types,
* callable via desc->handle_irq()
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index 0ba014c5505..623325e2ff9 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -11,6 +11,8 @@
struct irq_affinity_notify;
struct proc_dir_entry;
struct module;
+struct irq_desc;
+
/**
* struct irq_desc - interrupt descriptor
* @irq_data: per irq and chip data passed down to chip functions
@@ -65,6 +67,7 @@ struct irq_desc {
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dir;
#endif
+ int parent_irq;
struct module *owner;
const char *name;
} ____cacheline_internodealigned_in_smp;
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index 6b87413da9d..82ed068b1eb 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -70,11 +70,12 @@ extern int register_refined_jiffies(long clock_tick_rate);
/*
* The 64-bit value is not atomic - you MUST NOT read it
- * without sampling the sequence number in xtime_lock.
+ * without sampling the sequence number in jiffies_lock.
* get_jiffies_64() will do this for you as appropriate.
*/
extern u64 __jiffy_data jiffies_64;
extern unsigned long volatile __jiffy_data jiffies;
+extern seqlock_t jiffies_lock;
#if (BITS_PER_LONG < 64)
u64 get_jiffies_64(void);
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index a123b13b70f..d97ed589744 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -527,9 +527,6 @@ __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap);
extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode);
#else
-static inline __printf(1, 2)
-int trace_printk(const char *fmt, ...);
-
static inline void tracing_start(void) { }
static inline void tracing_stop(void) { }
static inline void ftrace_off_permanent(void) { }
@@ -539,8 +536,8 @@ static inline void tracing_on(void) { }
static inline void tracing_off(void) { }
static inline int tracing_is_on(void) { return 0; }
-static inline int
-trace_printk(const char *fmt, ...)
+static inline __printf(1, 2)
+int trace_printk(const char *fmt, ...)
{
return 0;
}
@@ -687,18 +684,11 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
/* Trap pasters of __FUNCTION__ at compile-time */
#define __FUNCTION__ (__func__)
-/* This helps us to avoid #ifdef CONFIG_NUMA */
-#ifdef CONFIG_NUMA
-#define NUMA_BUILD 1
-#else
-#define NUMA_BUILD 0
-#endif
-
-/* This helps us avoid #ifdef CONFIG_COMPACTION */
-#ifdef CONFIG_COMPACTION
-#define COMPACTION_BUILD 1
+/* This helps us to avoid #ifdef CONFIG_SYMBOL_PREFIX */
+#ifdef CONFIG_SYMBOL_PREFIX
+#define SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX
#else
-#define COMPACTION_BUILD 0
+#define SYMBOL_PREFIX ""
#endif
/* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index 36d12f0884c..66b70780e91 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -7,6 +7,7 @@
#include <linux/cpumask.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
+#include <linux/vtime.h>
#include <asm/irq.h>
#include <asm/cputime.h>
@@ -126,16 +127,16 @@ extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t)
extern void account_steal_time(cputime_t);
extern void account_idle_time(cputime_t);
-extern void account_process_tick(struct task_struct *, int user);
-extern void account_steal_ticks(unsigned long ticks);
-extern void account_idle_ticks(unsigned long ticks);
-
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
-extern void vtime_task_switch(struct task_struct *prev);
-extern void vtime_account_system(struct task_struct *tsk);
-extern void vtime_account_idle(struct task_struct *tsk);
+static inline void account_process_tick(struct task_struct *tsk, int user)
+{
+ vtime_account_user(tsk);
+}
#else
-static inline void vtime_task_switch(struct task_struct *prev) { }
+extern void account_process_tick(struct task_struct *, int user);
#endif
+extern void account_steal_ticks(unsigned long ticks);
+extern void account_idle_ticks(unsigned long ticks);
+
#endif /* _LINUX_KERNEL_STAT_H */
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 1e57449395b..939b11268c8 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -203,7 +203,6 @@ extern struct kobject *power_kobj;
/* The global /sys/firmware/ kobject for people to chain off of */
extern struct kobject *firmware_kobj;
-#if defined(CONFIG_HOTPLUG)
int kobject_uevent(struct kobject *kobj, enum kobject_action action);
int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
char *envp[]);
@@ -213,22 +212,5 @@ int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...);
int kobject_action_type(const char *buf, size_t count,
enum kobject_action *type);
-#else
-static inline int kobject_uevent(struct kobject *kobj,
- enum kobject_action action)
-{ return 0; }
-static inline int kobject_uevent_env(struct kobject *kobj,
- enum kobject_action action,
- char *envp[])
-{ return 0; }
-
-static inline __printf(2, 3)
-int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
-{ return -ENOMEM; }
-
-static inline int kobject_action_type(const char *buf, size_t count,
- enum kobject_action *type)
-{ return -EINVAL; }
-#endif
#endif /* _KOBJECT_H_ */
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index ecc554374e4..d5cddd8dcc5 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -726,7 +726,11 @@ static inline int kvm_deassign_device(struct kvm *kvm,
static inline void kvm_guest_enter(void)
{
BUG_ON(preemptible());
- vtime_account(current);
+ /*
+ * This is running in ioctl context so we can avoid
+ * the call to vtime_account() with its unnecessary idle check.
+ */
+ vtime_account_system_irqsafe(current);
current->flags |= PF_VCPU;
/* KVM does not hold any references to rcu protected data when it
* switches CPU into a guest mode. In fact switching to a guest mode
@@ -740,7 +744,11 @@ static inline void kvm_guest_enter(void)
static inline void kvm_guest_exit(void)
{
- vtime_account(current);
+ /*
+ * This is running in ioctl context so we can avoid
+ * the call to vtime_account() with its unnecessary idle check.
+ */
+ vtime_account_system_irqsafe(current);
current->flags &= ~PF_VCPU;
}
diff --git a/include/linux/memory.h b/include/linux/memory.h
index ff9a9f8e0ed..a09216d0dcc 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -53,6 +53,7 @@ int arch_get_memory_phys_device(unsigned long start_pfn);
struct memory_notify {
unsigned long start_pfn;
unsigned long nr_pages;
+ int status_change_nid_normal;
int status_change_nid;
};
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 95573ec4ee6..4a45c4e5002 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -26,6 +26,13 @@ enum {
MEMORY_HOTPLUG_MAX_BOOTMEM_TYPE = NODE_INFO,
};
+/* Types for control the zone type of onlined memory */
+enum {
+ ONLINE_KEEP,
+ ONLINE_KERNEL,
+ ONLINE_MOVABLE,
+};
+
/*
* pgdat resizing functions
*/
@@ -46,6 +53,10 @@ void pgdat_resize_init(struct pglist_data *pgdat)
}
/*
* Zone resizing functions
+ *
+ * Note: any attempt to resize a zone should has pgdat_resize_lock()
+ * zone_span_writelock() both held. This ensure the size of a zone
+ * can't be changed while pgdat_resize_lock() held.
*/
static inline unsigned zone_span_seqbegin(struct zone *zone)
{
@@ -71,7 +82,7 @@ extern int zone_grow_free_lists(struct zone *zone, unsigned long new_nr_pages);
extern int zone_grow_waitqueues(struct zone *zone, unsigned long nr_pages);
extern int add_one_highpage(struct page *page, int pfn, int bad_ppro);
/* VM interface that may be used by firmware interface */
-extern int online_pages(unsigned long, unsigned long);
+extern int online_pages(unsigned long, unsigned long, int);
extern void __offline_isolated_pages(unsigned long, unsigned long);
typedef void (*online_page_callback_t)(struct page *page);
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index e5ccb9ddd90..dbd212723b7 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -82,16 +82,6 @@ static inline void mpol_cond_put(struct mempolicy *pol)
__mpol_put(pol);
}
-extern struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol,
- struct mempolicy *frompol);
-static inline struct mempolicy *mpol_cond_copy(struct mempolicy *tompol,
- struct mempolicy *frompol)
-{
- if (!frompol)
- return frompol;
- return __mpol_cond_copy(tompol, frompol);
-}
-
extern struct mempolicy *__mpol_dup(struct mempolicy *pol);
static inline struct mempolicy *mpol_dup(struct mempolicy *pol)
{
@@ -215,12 +205,6 @@ static inline void mpol_cond_put(struct mempolicy *pol)
{
}
-static inline struct mempolicy *mpol_cond_copy(struct mempolicy *to,
- struct mempolicy *from)
-{
- return from;
-}
-
static inline void mpol_get(struct mempolicy *pol)
{
}
diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
index a0ca0dca124..478672ed0c3 100644
--- a/include/linux/mfd/88pm80x.h
+++ b/include/linux/mfd/88pm80x.h
@@ -364,6 +364,6 @@ static inline int pm80x_dev_resume(struct device *dev)
#endif
extern int pm80x_init(struct i2c_client *client,
- const struct i2c_device_id *id) __devinit;
+ const struct i2c_device_id *id);
extern int pm80x_deinit(struct i2c_client *client);
#endif /* __LINUX_MFD_88PM80X_H */
diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h
index 1491044efa1..1cb5698b4d7 100644
--- a/include/linux/mfd/abx500/ab8500.h
+++ b/include/linux/mfd/abx500/ab8500.h
@@ -291,9 +291,9 @@ struct ab8500_platform_data {
struct ab8500_codec_platform_data *codec;
};
-extern int __devinit ab8500_init(struct ab8500 *ab8500,
+extern int ab8500_init(struct ab8500 *ab8500,
enum ab8500_version version);
-extern int __devexit ab8500_exit(struct ab8500 *ab8500);
+extern int ab8500_exit(struct ab8500 *ab8500);
extern int ab8500_suspend(struct ab8500 *ab8500);
diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h
index b82f6ee66a0..6ee4247df11 100644
--- a/include/linux/mfd/db8500-prcmu.h
+++ b/include/linux/mfd/db8500-prcmu.h
@@ -515,7 +515,6 @@ enum romcode_read prcmu_get_rc_p2a(void);
enum ap_pwrst prcmu_get_xp70_current_state(void);
bool prcmu_has_arm_maxopp(void);
struct prcmu_fw_version *prcmu_get_fw_version(void);
-int prcmu_request_ape_opp_100_voltage(bool enable);
int prcmu_release_usb_wakeup_state(void);
void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep,
struct prcmu_auto_pm_config *idle);
@@ -564,6 +563,7 @@ int db8500_prcmu_set_arm_opp(u8 opp);
int db8500_prcmu_get_arm_opp(void);
int db8500_prcmu_set_ape_opp(u8 opp);
int db8500_prcmu_get_ape_opp(void);
+int db8500_prcmu_request_ape_opp_100_voltage(bool enable);
int db8500_prcmu_set_ddr_opp(u8 opp);
int db8500_prcmu_get_ddr_opp(void);
@@ -610,7 +610,7 @@ static inline int db8500_prcmu_get_ape_opp(void)
return APE_100_OPP;
}
-static inline int prcmu_request_ape_opp_100_voltage(bool enable)
+static inline int db8500_prcmu_request_ape_opp_100_voltage(bool enable)
{
return 0;
}
diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h
index c410d99bd66..c202d6c4d87 100644
--- a/include/linux/mfd/dbx500-prcmu.h
+++ b/include/linux/mfd/dbx500-prcmu.h
@@ -336,6 +336,11 @@ static inline int prcmu_get_ape_opp(void)
return db8500_prcmu_get_ape_opp();
}
+static inline int prcmu_request_ape_opp_100_voltage(bool enable)
+{
+ return db8500_prcmu_request_ape_opp_100_voltage(enable);
+}
+
static inline void prcmu_system_reset(u16 reset_code)
{
return db8500_prcmu_system_reset(reset_code);
@@ -507,6 +512,11 @@ static inline int prcmu_get_ape_opp(void)
return APE_100_OPP;
}
+static inline int prcmu_request_ape_opp_100_voltage(bool enable)
+{
+ return 0;
+}
+
static inline int prcmu_set_arm_opp(u8 opp)
{
return 0;
diff --git a/include/linux/mfd/pm8xxx/irq.h b/include/linux/mfd/pm8xxx/irq.h
index 4b21769f448..f83d6b43ecb 100644
--- a/include/linux/mfd/pm8xxx/irq.h
+++ b/include/linux/mfd/pm8xxx/irq.h
@@ -37,21 +37,21 @@ struct pm_irq_chip;
#ifdef CONFIG_MFD_PM8XXX_IRQ
int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq);
-struct pm_irq_chip * __devinit pm8xxx_irq_init(struct device *dev,
+struct pm_irq_chip *pm8xxx_irq_init(struct device *dev,
const struct pm8xxx_irq_platform_data *pdata);
-int __devexit pm8xxx_irq_exit(struct pm_irq_chip *chip);
+int pm8xxx_irq_exit(struct pm_irq_chip *chip);
#else
static inline int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq)
{
return -ENXIO;
}
-static inline struct pm_irq_chip * __devinit pm8xxx_irq_init(
+static inline struct pm_irq_chip *pm8xxx_irq_init(
const struct device *dev,
const struct pm8xxx_irq_platform_data *pdata)
{
return ERR_PTR(-ENXIO);
}
-static inline int __devexit pm8xxx_irq_exit(struct pm_irq_chip *chip)
+static inline int pm8xxx_irq_exit(struct pm_irq_chip *chip)
{
return -ENXIO;
}
diff --git a/drivers/staging/rts_pstor/debug.h b/include/linux/mfd/rtsx_common.h
index ab305be96fb..a8d393e3066 100644
--- a/drivers/staging/rts_pstor/debug.h
+++ b/include/linux/mfd/rtsx_common.h
@@ -1,5 +1,4 @@
-/* Driver for Realtek PCI-Express card reader
- * Header file
+/* Driver for Realtek driver-based card reader
*
* Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
*
@@ -17,27 +16,33 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Author:
- * wwang (wei_wang@realsil.com.cn)
+ * Wei WANG <wei_wang@realsil.com.cn>
* No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
*/
-#ifndef __REALTEK_RTSX_DEBUG_H
-#define __REALTEK_RTSX_DEBUG_H
+#ifndef __RTSX_COMMON_H
+#define __RTSX_COMMON_H
-#include <linux/kernel.h>
+#define DRV_NAME_RTSX_PCI "rtsx_pci"
+#define DRV_NAME_RTSX_PCI_SDMMC "rtsx_pci_sdmmc"
+#define DRV_NAME_RTSX_PCI_MS "rtsx_pci_ms"
-#define RTSX_STOR "rts_pstor: "
+#define RTSX_REG_PAIR(addr, val) (((u32)(addr) << 16) | (u8)(val))
-#ifdef CONFIG_RTS_PSTOR_DEBUG
-#define RTSX_DEBUGP(x...) printk(KERN_DEBUG RTSX_STOR x)
-#define RTSX_DEBUGPN(x...) printk(KERN_DEBUG x)
-#define RTSX_DEBUGPX(x...) printk(x)
-#define RTSX_DEBUG(x) x
-#else
-#define RTSX_DEBUGP(x...)
-#define RTSX_DEBUGPN(x...)
-#define RTSX_DEBUGPX(x...)
-#define RTSX_DEBUG(x)
-#endif
+#define RTSX_SSC_DEPTH_4M 0x01
+#define RTSX_SSC_DEPTH_2M 0x02
+#define RTSX_SSC_DEPTH_1M 0x03
+#define RTSX_SSC_DEPTH_500K 0x04
+#define RTSX_SSC_DEPTH_250K 0x05
+
+#define RTSX_SD_CARD 0
+#define RTSX_MS_CARD 1
+
+struct platform_device;
-#endif /* __REALTEK_RTSX_DEBUG_H */
+struct rtsx_slot {
+ struct platform_device *p_dev;
+ void (*card_event)(struct platform_device *p_dev);
+};
+
+#endif
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
new file mode 100644
index 00000000000..060b721fcbf
--- /dev/null
+++ b/include/linux/mfd/rtsx_pci.h
@@ -0,0 +1,794 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Wei WANG <wei_wang@realsil.com.cn>
+ * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#ifndef __RTSX_PCI_H
+#define __RTSX_PCI_H
+
+#include <linux/sched.h>
+#include <linux/pci.h>
+
+#include "rtsx_common.h"
+
+#define MAX_RW_REG_CNT 1024
+
+/* PCI Operation Register Address */
+#define RTSX_HCBAR 0x00
+#define RTSX_HCBCTLR 0x04
+#define RTSX_HDBAR 0x08
+#define RTSX_HDBCTLR 0x0C
+#define RTSX_HAIMR 0x10
+#define RTSX_BIPR 0x14
+#define RTSX_BIER 0x18
+
+/* Host command buffer control register */
+#define STOP_CMD (0x01 << 28)
+
+/* Host data buffer control register */
+#define SDMA_MODE 0x00
+#define ADMA_MODE (0x02 << 26)
+#define STOP_DMA (0x01 << 28)
+#define TRIG_DMA (0x01 << 31)
+
+/* Host access internal memory register */
+#define HAIMR_TRANS_START (0x01 << 31)
+#define HAIMR_READ 0x00
+#define HAIMR_WRITE (0x01 << 30)
+#define HAIMR_READ_START (HAIMR_TRANS_START | HAIMR_READ)
+#define HAIMR_WRITE_START (HAIMR_TRANS_START | HAIMR_WRITE)
+#define HAIMR_TRANS_END (HAIMR_TRANS_START)
+
+/* Bus interrupt pending register */
+#define CMD_DONE_INT (1 << 31)
+#define DATA_DONE_INT (1 << 30)
+#define TRANS_OK_INT (1 << 29)
+#define TRANS_FAIL_INT (1 << 28)
+#define XD_INT (1 << 27)
+#define MS_INT (1 << 26)
+#define SD_INT (1 << 25)
+#define GPIO0_INT (1 << 24)
+#define OC_INT (1 << 23)
+#define SD_WRITE_PROTECT (1 << 19)
+#define XD_EXIST (1 << 18)
+#define MS_EXIST (1 << 17)
+#define SD_EXIST (1 << 16)
+#define DELINK_INT GPIO0_INT
+#define MS_OC_INT (1 << 23)
+#define SD_OC_INT (1 << 22)
+
+#define CARD_INT (XD_INT | MS_INT | SD_INT)
+#define NEED_COMPLETE_INT (DATA_DONE_INT | TRANS_OK_INT | TRANS_FAIL_INT)
+#define RTSX_INT (CMD_DONE_INT | NEED_COMPLETE_INT | \
+ CARD_INT | GPIO0_INT | OC_INT)
+
+#define CARD_EXIST (XD_EXIST | MS_EXIST | SD_EXIST)
+
+/* Bus interrupt enable register */
+#define CMD_DONE_INT_EN (1 << 31)
+#define DATA_DONE_INT_EN (1 << 30)
+#define TRANS_OK_INT_EN (1 << 29)
+#define TRANS_FAIL_INT_EN (1 << 28)
+#define XD_INT_EN (1 << 27)
+#define MS_INT_EN (1 << 26)
+#define SD_INT_EN (1 << 25)
+#define GPIO0_INT_EN (1 << 24)
+#define OC_INT_EN (1 << 23)
+#define DELINK_INT_EN GPIO0_INT_EN
+#define MS_OC_INT_EN (1 << 23)
+#define SD_OC_INT_EN (1 << 22)
+
+#define READ_REG_CMD 0
+#define WRITE_REG_CMD 1
+#define CHECK_REG_CMD 2
+
+/*
+ * macros for easy use
+ */
+#define rtsx_pci_writel(pcr, reg, value) \
+ iowrite32(value, (pcr)->remap_addr + reg)
+#define rtsx_pci_readl(pcr, reg) \
+ ioread32((pcr)->remap_addr + reg)
+#define rtsx_pci_writew(pcr, reg, value) \
+ iowrite16(value, (pcr)->remap_addr + reg)
+#define rtsx_pci_readw(pcr, reg) \
+ ioread16((pcr)->remap_addr + reg)
+#define rtsx_pci_writeb(pcr, reg, value) \
+ iowrite8(value, (pcr)->remap_addr + reg)
+#define rtsx_pci_readb(pcr, reg) \
+ ioread8((pcr)->remap_addr + reg)
+
+#define rtsx_pci_read_config_byte(pcr, where, val) \
+ pci_read_config_byte((pcr)->pci, where, val)
+
+#define rtsx_pci_write_config_byte(pcr, where, val) \
+ pci_write_config_byte((pcr)->pci, where, val)
+
+#define rtsx_pci_read_config_dword(pcr, where, val) \
+ pci_read_config_dword((pcr)->pci, where, val)
+
+#define rtsx_pci_write_config_dword(pcr, where, val) \
+ pci_write_config_dword((pcr)->pci, where, val)
+
+#define STATE_TRANS_NONE 0
+#define STATE_TRANS_CMD 1
+#define STATE_TRANS_BUF 2
+#define STATE_TRANS_SG 3
+
+#define TRANS_NOT_READY 0
+#define TRANS_RESULT_OK 1
+#define TRANS_RESULT_FAIL 2
+#define TRANS_NO_DEVICE 3
+
+#define RTSX_RESV_BUF_LEN 4096
+#define HOST_CMDS_BUF_LEN 1024
+#define HOST_SG_TBL_BUF_LEN (RTSX_RESV_BUF_LEN - HOST_CMDS_BUF_LEN)
+#define HOST_SG_TBL_ITEMS (HOST_SG_TBL_BUF_LEN / 8)
+#define MAX_SG_ITEM_LEN 0x80000
+
+#define HOST_TO_DEVICE 0
+#define DEVICE_TO_HOST 1
+
+#define MAX_PHASE 31
+#define RX_TUNING_CNT 3
+
+/* SG descriptor */
+#define SG_INT 0x04
+#define SG_END 0x02
+#define SG_VALID 0x01
+
+#define SG_NO_OP 0x00
+#define SG_TRANS_DATA (0x02 << 4)
+#define SG_LINK_DESC (0x03 << 4)
+
+/* SD bank voltage */
+#define SD_IO_3V3 0
+#define SD_IO_1V8 1
+
+
+/* Card Clock Enable Register */
+#define SD_CLK_EN 0x04
+#define MS_CLK_EN 0x08
+
+/* Card Select Register */
+#define SD_MOD_SEL 2
+#define MS_MOD_SEL 3
+
+/* Card Output Enable Register */
+#define SD_OUTPUT_EN 0x04
+#define MS_OUTPUT_EN 0x08
+
+/* CARD_SHARE_MODE */
+#define CARD_SHARE_MASK 0x0F
+#define CARD_SHARE_MULTI_LUN 0x00
+#define CARD_SHARE_NORMAL 0x00
+#define CARD_SHARE_48_SD 0x04
+#define CARD_SHARE_48_MS 0x08
+/* CARD_SHARE_MODE for barossa */
+#define CARD_SHARE_BAROSSA_SD 0x01
+#define CARD_SHARE_BAROSSA_MS 0x02
+
+/* SD30_DRIVE_SEL */
+#define DRIVER_TYPE_A 0x05
+#define DRIVER_TYPE_B 0x03
+#define DRIVER_TYPE_C 0x02
+#define DRIVER_TYPE_D 0x01
+
+/* FPDCTL */
+#define SSC_POWER_DOWN 0x01
+#define SD_OC_POWER_DOWN 0x02
+#define ALL_POWER_DOWN 0x07
+#define OC_POWER_DOWN 0x06
+
+/* CLK_CTL */
+#define CHANGE_CLK 0x01
+
+/* LDO_CTL */
+#define BPP_LDO_POWB 0x03
+#define BPP_LDO_ON 0x00
+#define BPP_LDO_SUSPEND 0x02
+#define BPP_LDO_OFF 0x03
+
+/* CD_PAD_CTL */
+#define CD_DISABLE_MASK 0x07
+#define MS_CD_DISABLE 0x04
+#define SD_CD_DISABLE 0x02
+#define XD_CD_DISABLE 0x01
+#define CD_DISABLE 0x07
+#define CD_ENABLE 0x00
+#define MS_CD_EN_ONLY 0x03
+#define SD_CD_EN_ONLY 0x05
+#define XD_CD_EN_ONLY 0x06
+#define FORCE_CD_LOW_MASK 0x38
+#define FORCE_CD_XD_LOW 0x08
+#define FORCE_CD_SD_LOW 0x10
+#define FORCE_CD_MS_LOW 0x20
+#define CD_AUTO_DISABLE 0x40
+
+/* SD_STAT1 */
+#define SD_CRC7_ERR 0x80
+#define SD_CRC16_ERR 0x40
+#define SD_CRC_WRITE_ERR 0x20
+#define SD_CRC_WRITE_ERR_MASK 0x1C
+#define GET_CRC_TIME_OUT 0x02
+#define SD_TUNING_COMPARE_ERR 0x01
+
+/* SD_STAT2 */
+#define SD_RSP_80CLK_TIMEOUT 0x01
+
+/* SD_BUS_STAT */
+#define SD_CLK_TOGGLE_EN 0x80
+#define SD_CLK_FORCE_STOP 0x40
+#define SD_DAT3_STATUS 0x10
+#define SD_DAT2_STATUS 0x08
+#define SD_DAT1_STATUS 0x04
+#define SD_DAT0_STATUS 0x02
+#define SD_CMD_STATUS 0x01
+
+/* SD_PAD_CTL */
+#define SD_IO_USING_1V8 0x80
+#define SD_IO_USING_3V3 0x7F
+#define TYPE_A_DRIVING 0x00
+#define TYPE_B_DRIVING 0x01
+#define TYPE_C_DRIVING 0x02
+#define TYPE_D_DRIVING 0x03
+
+/* SD_SAMPLE_POINT_CTL */
+#define DDR_FIX_RX_DAT 0x00
+#define DDR_VAR_RX_DAT 0x80
+#define DDR_FIX_RX_DAT_EDGE 0x00
+#define DDR_FIX_RX_DAT_14_DELAY 0x40
+#define DDR_FIX_RX_CMD 0x00
+#define DDR_VAR_RX_CMD 0x20
+#define DDR_FIX_RX_CMD_POS_EDGE 0x00
+#define DDR_FIX_RX_CMD_14_DELAY 0x10
+#define SD20_RX_POS_EDGE 0x00
+#define SD20_RX_14_DELAY 0x08
+#define SD20_RX_SEL_MASK 0x08
+
+/* SD_PUSH_POINT_CTL */
+#define DDR_FIX_TX_CMD_DAT 0x00
+#define DDR_VAR_TX_CMD_DAT 0x80
+#define DDR_FIX_TX_DAT_14_TSU 0x00
+#define DDR_FIX_TX_DAT_12_TSU 0x40
+#define DDR_FIX_TX_CMD_NEG_EDGE 0x00
+#define DDR_FIX_TX_CMD_14_AHEAD 0x20
+#define SD20_TX_NEG_EDGE 0x00
+#define SD20_TX_14_AHEAD 0x10
+#define SD20_TX_SEL_MASK 0x10
+#define DDR_VAR_SDCLK_POL_SWAP 0x01
+
+/* SD_TRANSFER */
+#define SD_TRANSFER_START 0x80
+#define SD_TRANSFER_END 0x40
+#define SD_STAT_IDLE 0x20
+#define SD_TRANSFER_ERR 0x10
+/* SD Transfer Mode definition */
+#define SD_TM_NORMAL_WRITE 0x00
+#define SD_TM_AUTO_WRITE_3 0x01
+#define SD_TM_AUTO_WRITE_4 0x02
+#define SD_TM_AUTO_READ_3 0x05
+#define SD_TM_AUTO_READ_4 0x06
+#define SD_TM_CMD_RSP 0x08
+#define SD_TM_AUTO_WRITE_1 0x09
+#define SD_TM_AUTO_WRITE_2 0x0A
+#define SD_TM_NORMAL_READ 0x0C
+#define SD_TM_AUTO_READ_1 0x0D
+#define SD_TM_AUTO_READ_2 0x0E
+#define SD_TM_AUTO_TUNING 0x0F
+
+/* SD_VPTX_CTL / SD_VPRX_CTL */
+#define PHASE_CHANGE 0x80
+#define PHASE_NOT_RESET 0x40
+
+/* SD_DCMPS_TX_CTL / SD_DCMPS_RX_CTL */
+#define DCMPS_CHANGE 0x80
+#define DCMPS_CHANGE_DONE 0x40
+#define DCMPS_ERROR 0x20
+#define DCMPS_CURRENT_PHASE 0x1F
+
+/* SD Configure 1 Register */
+#define SD_CLK_DIVIDE_0 0x00
+#define SD_CLK_DIVIDE_256 0xC0
+#define SD_CLK_DIVIDE_128 0x80
+#define SD_BUS_WIDTH_1BIT 0x00
+#define SD_BUS_WIDTH_4BIT 0x01
+#define SD_BUS_WIDTH_8BIT 0x02
+#define SD_ASYNC_FIFO_NOT_RST 0x10
+#define SD_20_MODE 0x00
+#define SD_DDR_MODE 0x04
+#define SD_30_MODE 0x08
+
+#define SD_CLK_DIVIDE_MASK 0xC0
+
+/* SD_CMD_STATE */
+#define SD_CMD_IDLE 0x80
+
+/* SD_DATA_STATE */
+#define SD_DATA_IDLE 0x80
+
+/* DCM_DRP_CTL */
+#define DCM_RESET 0x08
+#define DCM_LOCKED 0x04
+#define DCM_208M 0x00
+#define DCM_TX 0x01
+#define DCM_RX 0x02
+
+/* DCM_DRP_TRIG */
+#define DRP_START 0x80
+#define DRP_DONE 0x40
+
+/* DCM_DRP_CFG */
+#define DRP_WRITE 0x80
+#define DRP_READ 0x00
+#define DCM_WRITE_ADDRESS_50 0x50
+#define DCM_WRITE_ADDRESS_51 0x51
+#define DCM_READ_ADDRESS_00 0x00
+#define DCM_READ_ADDRESS_51 0x51
+
+/* IRQSTAT0 */
+#define DMA_DONE_INT 0x80
+#define SUSPEND_INT 0x40
+#define LINK_RDY_INT 0x20
+#define LINK_DOWN_INT 0x10
+
+/* DMACTL */
+#define DMA_RST 0x80
+#define DMA_BUSY 0x04
+#define DMA_DIR_TO_CARD 0x00
+#define DMA_DIR_FROM_CARD 0x02
+#define DMA_EN 0x01
+#define DMA_128 (0 << 4)
+#define DMA_256 (1 << 4)
+#define DMA_512 (2 << 4)
+#define DMA_1024 (3 << 4)
+#define DMA_PACK_SIZE_MASK 0x30
+
+/* SSC_CTL1 */
+#define SSC_RSTB 0x80
+#define SSC_8X_EN 0x40
+#define SSC_FIX_FRAC 0x20
+#define SSC_SEL_1M 0x00
+#define SSC_SEL_2M 0x08
+#define SSC_SEL_4M 0x10
+#define SSC_SEL_8M 0x18
+
+/* SSC_CTL2 */
+#define SSC_DEPTH_MASK 0x07
+#define SSC_DEPTH_DISALBE 0x00
+#define SSC_DEPTH_4M 0x01
+#define SSC_DEPTH_2M 0x02
+#define SSC_DEPTH_1M 0x03
+#define SSC_DEPTH_500K 0x04
+#define SSC_DEPTH_250K 0x05
+
+/* System Clock Control Register */
+#define CLK_LOW_FREQ 0x01
+
+/* System Clock Divider Register */
+#define CLK_DIV_1 0x01
+#define CLK_DIV_2 0x02
+#define CLK_DIV_4 0x03
+#define CLK_DIV_8 0x04
+
+/* MS_CFG */
+#define SAMPLE_TIME_RISING 0x00
+#define SAMPLE_TIME_FALLING 0x80
+#define PUSH_TIME_DEFAULT 0x00
+#define PUSH_TIME_ODD 0x40
+#define NO_EXTEND_TOGGLE 0x00
+#define EXTEND_TOGGLE_CHK 0x20
+#define MS_BUS_WIDTH_1 0x00
+#define MS_BUS_WIDTH_4 0x10
+#define MS_BUS_WIDTH_8 0x18
+#define MS_2K_SECTOR_MODE 0x04
+#define MS_512_SECTOR_MODE 0x00
+#define MS_TOGGLE_TIMEOUT_EN 0x00
+#define MS_TOGGLE_TIMEOUT_DISEN 0x01
+#define MS_NO_CHECK_INT 0x02
+
+/* MS_TRANS_CFG */
+#define WAIT_INT 0x80
+#define NO_WAIT_INT 0x00
+#define NO_AUTO_READ_INT_REG 0x00
+#define AUTO_READ_INT_REG 0x40
+#define MS_CRC16_ERR 0x20
+#define MS_RDY_TIMEOUT 0x10
+#define MS_INT_CMDNK 0x08
+#define MS_INT_BREQ 0x04
+#define MS_INT_ERR 0x02
+#define MS_INT_CED 0x01
+
+/* MS_TRANSFER */
+#define MS_TRANSFER_START 0x80
+#define MS_TRANSFER_END 0x40
+#define MS_TRANSFER_ERR 0x20
+#define MS_BS_STATE 0x10
+#define MS_TM_READ_BYTES 0x00
+#define MS_TM_NORMAL_READ 0x01
+#define MS_TM_WRITE_BYTES 0x04
+#define MS_TM_NORMAL_WRITE 0x05
+#define MS_TM_AUTO_READ 0x08
+#define MS_TM_AUTO_WRITE 0x0C
+
+/* SD Configure 2 Register */
+#define SD_CALCULATE_CRC7 0x00
+#define SD_NO_CALCULATE_CRC7 0x80
+#define SD_CHECK_CRC16 0x00
+#define SD_NO_CHECK_CRC16 0x40
+#define SD_NO_CHECK_WAIT_CRC_TO 0x20
+#define SD_WAIT_BUSY_END 0x08
+#define SD_NO_WAIT_BUSY_END 0x00
+#define SD_CHECK_CRC7 0x00
+#define SD_NO_CHECK_CRC7 0x04
+#define SD_RSP_LEN_0 0x00
+#define SD_RSP_LEN_6 0x01
+#define SD_RSP_LEN_17 0x02
+/* SD/MMC Response Type Definition */
+#define SD_RSP_TYPE_R0 0x04
+#define SD_RSP_TYPE_R1 0x01
+#define SD_RSP_TYPE_R1b 0x09
+#define SD_RSP_TYPE_R2 0x02
+#define SD_RSP_TYPE_R3 0x05
+#define SD_RSP_TYPE_R4 0x05
+#define SD_RSP_TYPE_R5 0x01
+#define SD_RSP_TYPE_R6 0x01
+#define SD_RSP_TYPE_R7 0x01
+
+/* SD_CONFIURE3 */
+#define SD_RSP_80CLK_TIMEOUT_EN 0x01
+
+/* Card Transfer Reset Register */
+#define SPI_STOP 0x01
+#define XD_STOP 0x02
+#define SD_STOP 0x04
+#define MS_STOP 0x08
+#define SPI_CLR_ERR 0x10
+#define XD_CLR_ERR 0x20
+#define SD_CLR_ERR 0x40
+#define MS_CLR_ERR 0x80
+
+/* Card Data Source Register */
+#define PINGPONG_BUFFER 0x01
+#define RING_BUFFER 0x00
+
+/* Card Power Control Register */
+#define PMOS_STRG_MASK 0x10
+#define PMOS_STRG_800mA 0x10
+#define PMOS_STRG_400mA 0x00
+#define SD_POWER_OFF 0x03
+#define SD_PARTIAL_POWER_ON 0x01
+#define SD_POWER_ON 0x00
+#define SD_POWER_MASK 0x03
+#define MS_POWER_OFF 0x0C
+#define MS_PARTIAL_POWER_ON 0x04
+#define MS_POWER_ON 0x00
+#define MS_POWER_MASK 0x0C
+#define BPP_POWER_OFF 0x0F
+#define BPP_POWER_5_PERCENT_ON 0x0E
+#define BPP_POWER_10_PERCENT_ON 0x0C
+#define BPP_POWER_15_PERCENT_ON 0x08
+#define BPP_POWER_ON 0x00
+#define BPP_POWER_MASK 0x0F
+
+/* PWR_GATE_CTRL */
+#define PWR_GATE_EN 0x01
+#define LDO3318_PWR_MASK 0x06
+#define LDO_ON 0x00
+#define LDO_SUSPEND 0x04
+#define LDO_OFF 0x06
+
+/* CARD_CLK_SOURCE */
+#define CRC_FIX_CLK (0x00 << 0)
+#define CRC_VAR_CLK0 (0x01 << 0)
+#define CRC_VAR_CLK1 (0x02 << 0)
+#define SD30_FIX_CLK (0x00 << 2)
+#define SD30_VAR_CLK0 (0x01 << 2)
+#define SD30_VAR_CLK1 (0x02 << 2)
+#define SAMPLE_FIX_CLK (0x00 << 4)
+#define SAMPLE_VAR_CLK0 (0x01 << 4)
+#define SAMPLE_VAR_CLK1 (0x02 << 4)
+
+#define MS_CFG 0xFD40
+#define MS_TPC 0xFD41
+#define MS_TRANS_CFG 0xFD42
+#define MS_TRANSFER 0xFD43
+#define MS_INT_REG 0xFD44
+#define MS_BYTE_CNT 0xFD45
+#define MS_SECTOR_CNT_L 0xFD46
+#define MS_SECTOR_CNT_H 0xFD47
+#define MS_DBUS_H 0xFD48
+
+#define SD_CFG1 0xFDA0
+#define SD_CFG2 0xFDA1
+#define SD_CFG3 0xFDA2
+#define SD_STAT1 0xFDA3
+#define SD_STAT2 0xFDA4
+#define SD_BUS_STAT 0xFDA5
+#define SD_PAD_CTL 0xFDA6
+#define SD_SAMPLE_POINT_CTL 0xFDA7
+#define SD_PUSH_POINT_CTL 0xFDA8
+#define SD_CMD0 0xFDA9
+#define SD_CMD1 0xFDAA
+#define SD_CMD2 0xFDAB
+#define SD_CMD3 0xFDAC
+#define SD_CMD4 0xFDAD
+#define SD_CMD5 0xFDAE
+#define SD_BYTE_CNT_L 0xFDAF
+#define SD_BYTE_CNT_H 0xFDB0
+#define SD_BLOCK_CNT_L 0xFDB1
+#define SD_BLOCK_CNT_H 0xFDB2
+#define SD_TRANSFER 0xFDB3
+#define SD_CMD_STATE 0xFDB5
+#define SD_DATA_STATE 0xFDB6
+
+#define SRCTL 0xFC13
+
+#define DCM_DRP_CTL 0xFC23
+#define DCM_DRP_TRIG 0xFC24
+#define DCM_DRP_CFG 0xFC25
+#define DCM_DRP_WR_DATA_L 0xFC26
+#define DCM_DRP_WR_DATA_H 0xFC27
+#define DCM_DRP_RD_DATA_L 0xFC28
+#define DCM_DRP_RD_DATA_H 0xFC29
+#define SD_VPCLK0_CTL 0xFC2A
+#define SD_VPCLK1_CTL 0xFC2B
+#define SD_DCMPS0_CTL 0xFC2C
+#define SD_DCMPS1_CTL 0xFC2D
+#define SD_VPTX_CTL SD_VPCLK0_CTL
+#define SD_VPRX_CTL SD_VPCLK1_CTL
+#define SD_DCMPS_TX_CTL SD_DCMPS0_CTL
+#define SD_DCMPS_RX_CTL SD_DCMPS1_CTL
+#define CARD_CLK_SOURCE 0xFC2E
+
+#define CARD_PWR_CTL 0xFD50
+#define CARD_CLK_SWITCH 0xFD51
+#define CARD_SHARE_MODE 0xFD52
+#define CARD_DRIVE_SEL 0xFD53
+#define CARD_STOP 0xFD54
+#define CARD_OE 0xFD55
+#define CARD_AUTO_BLINK 0xFD56
+#define CARD_GPIO_DIR 0xFD57
+#define CARD_GPIO 0xFD58
+#define CARD_DATA_SOURCE 0xFD5B
+#define CARD_SELECT 0xFD5C
+#define SD30_DRIVE_SEL 0xFD5E
+#define CARD_CLK_EN 0xFD69
+#define SDIO_CTRL 0xFD6B
+#define CD_PAD_CTL 0xFD73
+
+#define FPDCTL 0xFC00
+#define PDINFO 0xFC01
+
+#define CLK_CTL 0xFC02
+#define CLK_DIV 0xFC03
+#define CLK_SEL 0xFC04
+
+#define SSC_DIV_N_0 0xFC0F
+#define SSC_DIV_N_1 0xFC10
+#define SSC_CTL1 0xFC11
+#define SSC_CTL2 0xFC12
+
+#define RCCTL 0xFC14
+
+#define FPGA_PULL_CTL 0xFC1D
+#define OLT_LED_CTL 0xFC1E
+#define GPIO_CTL 0xFC1F
+
+#define LDO_CTL 0xFC1E
+#define SYS_VER 0xFC32
+
+#define CARD_PULL_CTL1 0xFD60
+#define CARD_PULL_CTL2 0xFD61
+#define CARD_PULL_CTL3 0xFD62
+#define CARD_PULL_CTL4 0xFD63
+#define CARD_PULL_CTL5 0xFD64
+#define CARD_PULL_CTL6 0xFD65
+
+/* PCI Express Related Registers */
+#define IRQEN0 0xFE20
+#define IRQSTAT0 0xFE21
+#define IRQEN1 0xFE22
+#define IRQSTAT1 0xFE23
+#define TLPRIEN 0xFE24
+#define TLPRISTAT 0xFE25
+#define TLPTIEN 0xFE26
+#define TLPTISTAT 0xFE27
+#define DMATC0 0xFE28
+#define DMATC1 0xFE29
+#define DMATC2 0xFE2A
+#define DMATC3 0xFE2B
+#define DMACTL 0xFE2C
+#define BCTL 0xFE2D
+#define RBBC0 0xFE2E
+#define RBBC1 0xFE2F
+#define RBDAT 0xFE30
+#define RBCTL 0xFE34
+#define CFGADDR0 0xFE35
+#define CFGADDR1 0xFE36
+#define CFGDATA0 0xFE37
+#define CFGDATA1 0xFE38
+#define CFGDATA2 0xFE39
+#define CFGDATA3 0xFE3A
+#define CFGRWCTL 0xFE3B
+#define PHYRWCTL 0xFE3C
+#define PHYDATA0 0xFE3D
+#define PHYDATA1 0xFE3E
+#define PHYADDR 0xFE3F
+#define MSGRXDATA0 0xFE40
+#define MSGRXDATA1 0xFE41
+#define MSGRXDATA2 0xFE42
+#define MSGRXDATA3 0xFE43
+#define MSGTXDATA0 0xFE44
+#define MSGTXDATA1 0xFE45
+#define MSGTXDATA2 0xFE46
+#define MSGTXDATA3 0xFE47
+#define MSGTXCTL 0xFE48
+#define PETXCFG 0xFE49
+
+#define CDRESUMECTL 0xFE52
+#define WAKE_SEL_CTL 0xFE54
+#define PME_FORCE_CTL 0xFE56
+#define ASPM_FORCE_CTL 0xFE57
+#define PM_CLK_FORCE_CTL 0xFE58
+#define PERST_GLITCH_WIDTH 0xFE5C
+#define CHANGE_LINK_STATE 0xFE5B
+#define RESET_LOAD_REG 0xFE5E
+#define EFUSE_CONTENT 0xFE5F
+#define HOST_SLEEP_STATE 0xFE60
+#define SDIO_CFG 0xFE70
+
+#define NFTS_TX_CTRL 0xFE72
+
+#define PWR_GATE_CTRL 0xFE75
+#define PWD_SUSPEND_EN 0xFE76
+#define LDO_PWR_SEL 0xFE78
+
+#define DUMMY_REG_RESET_0 0xFE90
+
+/* Memory mapping */
+#define SRAM_BASE 0xE600
+#define RBUF_BASE 0xF400
+#define PPBUF_BASE1 0xF800
+#define PPBUF_BASE2 0xFA00
+#define IMAGE_FLAG_ADDR0 0xCE80
+#define IMAGE_FLAG_ADDR1 0xCE81
+
+#define rtsx_pci_init_cmd(pcr) ((pcr)->ci = 0)
+
+struct rtsx_pcr;
+
+struct pcr_handle {
+ struct rtsx_pcr *pcr;
+};
+
+struct pcr_ops {
+ int (*extra_init_hw)(struct rtsx_pcr *pcr);
+ int (*optimize_phy)(struct rtsx_pcr *pcr);
+ int (*turn_on_led)(struct rtsx_pcr *pcr);
+ int (*turn_off_led)(struct rtsx_pcr *pcr);
+ int (*enable_auto_blink)(struct rtsx_pcr *pcr);
+ int (*disable_auto_blink)(struct rtsx_pcr *pcr);
+ int (*card_power_on)(struct rtsx_pcr *pcr, int card);
+ int (*card_power_off)(struct rtsx_pcr *pcr, int card);
+ unsigned int (*cd_deglitch)(struct rtsx_pcr *pcr);
+};
+
+enum PDEV_STAT {PDEV_STAT_IDLE, PDEV_STAT_RUN};
+
+struct rtsx_pcr {
+ struct pci_dev *pci;
+ unsigned int id;
+
+ /* pci resources */
+ unsigned long addr;
+ void __iomem *remap_addr;
+ int irq;
+
+ /* host reserved buffer */
+ void *rtsx_resv_buf;
+ dma_addr_t rtsx_resv_buf_addr;
+
+ void *host_cmds_ptr;
+ dma_addr_t host_cmds_addr;
+ int ci;
+
+ void *host_sg_tbl_ptr;
+ dma_addr_t host_sg_tbl_addr;
+ int sgi;
+
+ u32 bier;
+ char trans_result;
+
+ unsigned int card_inserted;
+ unsigned int card_removed;
+
+ struct delayed_work carddet_work;
+ struct delayed_work idle_work;
+
+ spinlock_t lock;
+ struct mutex pcr_mutex;
+ struct completion *done;
+ struct completion *finish_me;
+
+ unsigned int cur_clock;
+ bool ms_pmos;
+ bool remove_pci;
+ bool msi_en;
+
+#define EXTRA_CAPS_SD_SDR50 (1 << 0)
+#define EXTRA_CAPS_SD_SDR104 (1 << 1)
+#define EXTRA_CAPS_SD_DDR50 (1 << 2)
+#define EXTRA_CAPS_MMC_HSDDR (1 << 3)
+#define EXTRA_CAPS_MMC_HS200 (1 << 4)
+#define EXTRA_CAPS_MMC_8BIT (1 << 5)
+ u32 extra_caps;
+
+#define IC_VER_A 0
+#define IC_VER_B 1
+#define IC_VER_C 2
+#define IC_VER_D 3
+ u8 ic_version;
+
+ const u32 *sd_pull_ctl_enable_tbl;
+ const u32 *sd_pull_ctl_disable_tbl;
+ const u32 *ms_pull_ctl_enable_tbl;
+ const u32 *ms_pull_ctl_disable_tbl;
+
+ const struct pcr_ops *ops;
+ enum PDEV_STAT state;
+
+ int num_slots;
+ struct rtsx_slot *slots;
+};
+
+#define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid))
+#define PCI_VID(pcr) ((pcr)->pci->vendor)
+#define PCI_PID(pcr) ((pcr)->pci->device)
+
+void rtsx_pci_start_run(struct rtsx_pcr *pcr);
+int rtsx_pci_write_register(struct rtsx_pcr *pcr, u16 addr, u8 mask, u8 data);
+int rtsx_pci_read_register(struct rtsx_pcr *pcr, u16 addr, u8 *data);
+int rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val);
+int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val);
+void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr);
+void rtsx_pci_add_cmd(struct rtsx_pcr *pcr,
+ u8 cmd_type, u16 reg_addr, u8 mask, u8 data);
+void rtsx_pci_send_cmd_no_wait(struct rtsx_pcr *pcr);
+int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout);
+int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
+ int num_sg, bool read, int timeout);
+int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len);
+int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len);
+int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card);
+int rtsx_pci_card_pull_ctl_disable(struct rtsx_pcr *pcr, int card);
+int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
+ u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk);
+int rtsx_pci_card_power_on(struct rtsx_pcr *pcr, int card);
+int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card);
+unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr);
+void rtsx_pci_complete_unfinished_transfer(struct rtsx_pcr *pcr);
+
+static inline u8 *rtsx_pci_get_cmd_data(struct rtsx_pcr *pcr)
+{
+ return (u8 *)(pcr->host_cmds_ptr);
+}
+
+#endif
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index ce7e6671968..0b5865c61ef 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -7,9 +7,27 @@
typedef struct page *new_page_t(struct page *, unsigned long private, int **);
+/*
+ * Return values from addresss_space_operations.migratepage():
+ * - negative errno on page migration failure;
+ * - zero on page migration success;
+ *
+ * The balloon page migration introduces this special case where a 'distinct'
+ * return code is used to flag a successful page migration to unmap_and_move().
+ * This approach is necessary because page migration can race against balloon
+ * deflation procedure, and for such case we could introduce a nasty page leak
+ * if a successfully migrated balloon page gets released concurrently with
+ * migration's unmap_and_move() wrap-up steps.
+ */
+#define MIGRATEPAGE_SUCCESS 0
+#define MIGRATEPAGE_BALLOON_SUCCESS 1 /* special ret code for balloon page
+ * sucessful migration case.
+ */
+
#ifdef CONFIG_MIGRATION
extern void putback_lru_pages(struct list_head *l);
+extern void putback_movable_pages(struct list_head *l);
extern int migrate_page(struct address_space *,
struct page *, struct page *, enum migrate_mode);
extern int migrate_pages(struct list_head *l, new_page_t x,
@@ -33,6 +51,7 @@ extern int migrate_huge_page_move_mapping(struct address_space *mapping,
#else
static inline void putback_lru_pages(struct list_head *l) {}
+static inline void putback_movable_pages(struct list_head *l) {}
static inline int migrate_pages(struct list_head *l, new_page_t x,
unsigned long private, bool offlining,
enum migrate_mode mode) { return -ENOSYS; }
diff --git a/include/linux/mm.h b/include/linux/mm.h
index fa068040273..4af4f0b1be4 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1456,6 +1456,37 @@ extern unsigned long vm_mmap(struct file *, unsigned long,
unsigned long, unsigned long,
unsigned long, unsigned long);
+struct vm_unmapped_area_info {
+#define VM_UNMAPPED_AREA_TOPDOWN 1
+ unsigned long flags;
+ unsigned long length;
+ unsigned long low_limit;
+ unsigned long high_limit;
+ unsigned long align_mask;
+ unsigned long align_offset;
+};
+
+extern unsigned long unmapped_area(struct vm_unmapped_area_info *info);
+extern unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info);
+
+/*
+ * Search for an unmapped address range.
+ *
+ * We are looking for a range that:
+ * - does not intersect with any VMA;
+ * - is contained within the [low_limit, high_limit) interval;
+ * - is at least the desired size.
+ * - satisfies (begin_addr & align_mask) == (align_offset & align_mask)
+ */
+static inline unsigned long
+vm_unmapped_area(struct vm_unmapped_area_info *info)
+{
+ if (!(info->flags & VM_UNMAPPED_AREA_TOPDOWN))
+ return unmapped_area(info);
+ else
+ return unmapped_area_topdown(info);
+}
+
/* truncate.c */
extern void truncate_inode_pages(struct address_space *, loff_t);
extern void truncate_inode_pages_range(struct address_space *,
@@ -1684,9 +1715,5 @@ static inline unsigned int debug_guardpage_minorder(void) { return 0; }
static inline bool page_is_guard(struct page *page) { return false; }
#endif /* CONFIG_DEBUG_PAGEALLOC */
-extern void reset_zone_present_pages(void);
-extern void fixup_zone_present_pages(int nid, unsigned long start_pfn,
- unsigned long end_pfn);
-
#endif /* __KERNEL__ */
#endif /* _LINUX_MM_H */
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 31f8a3af7d9..7ade2731b5d 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -224,7 +224,8 @@ struct vm_region {
* library, the executable area etc).
*/
struct vm_area_struct {
- struct mm_struct * vm_mm; /* The address space we belong to. */
+ /* The first cache line has the info for VMA tree walking. */
+
unsigned long vm_start; /* Our start address within vm_mm. */
unsigned long vm_end; /* The first byte after our end address
within vm_mm. */
@@ -232,11 +233,22 @@ struct vm_area_struct {
/* linked list of VM areas per task, sorted by address */
struct vm_area_struct *vm_next, *vm_prev;
+ struct rb_node vm_rb;
+
+ /*
+ * Largest free memory gap in bytes to the left of this VMA.
+ * Either between this VMA and vma->vm_prev, or between one of the
+ * VMAs below us in the VMA rbtree and its ->vm_prev. This helps
+ * get_unmapped_area find a free area of the right size.
+ */
+ unsigned long rb_subtree_gap;
+
+ /* Second cache line starts here. */
+
+ struct mm_struct *vm_mm; /* The address space we belong to. */
pgprot_t vm_page_prot; /* Access permissions of this VMA. */
unsigned long vm_flags; /* Flags, see mm.h. */
- struct rb_node vm_rb;
-
/*
* For areas with an address space and backing store,
* linkage into the address_space->i_mmap interval tree, or
@@ -322,6 +334,7 @@ struct mm_struct {
unsigned long task_size; /* size of task vm space */
unsigned long cached_hole_size; /* if non-zero, the largest hole below free_area_cache */
unsigned long free_area_cache; /* first hole of size cached_hole_size or larger */
+ unsigned long highest_vm_end; /* highest vma end address */
pgd_t * pgd;
atomic_t mm_users; /* How many users with user space? */
atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */
diff --git a/include/linux/mman.h b/include/linux/mman.h
index d09dde1e57f..9aa863da287 100644
--- a/include/linux/mman.h
+++ b/include/linux/mman.h
@@ -11,6 +11,8 @@ extern int sysctl_overcommit_memory;
extern int sysctl_overcommit_ratio;
extern struct percpu_counter vm_committed_as;
+unsigned long vm_memory_committed(void);
+
static inline void vm_acct_memory(long pages)
{
percpu_counter_add(&vm_committed_as, pages);
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 943550dfe9e..5c69315d60c 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -85,6 +85,7 @@ struct mmc_ext_csd {
bool boot_ro_lockable;
u8 raw_exception_status; /* 53 */
u8 raw_partition_support; /* 160 */
+ u8 raw_rpmb_size_mult; /* 168 */
u8 raw_erased_mem_count; /* 181 */
u8 raw_ext_csd_structure; /* 194 */
u8 raw_card_type; /* 196 */
@@ -206,6 +207,7 @@ struct mmc_part {
#define MMC_BLK_DATA_AREA_MAIN (1<<0)
#define MMC_BLK_DATA_AREA_BOOT (1<<1)
#define MMC_BLK_DATA_AREA_GP (1<<2)
+#define MMC_BLK_DATA_AREA_RPMB (1<<3)
};
/*
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 9b9cdafc773..5bf7c2274fc 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -170,6 +170,8 @@ extern int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from,
extern unsigned int mmc_calc_max_discard(struct mmc_card *card);
extern int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen);
+extern int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount,
+ bool is_rel_write);
extern int mmc_hw_reset(struct mmc_host *host);
extern int mmc_hw_reset_check(struct mmc_host *host);
extern int mmc_can_reset(struct mmc_card *card);
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index 96531664a06..34be4f47293 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -229,8 +229,9 @@ struct dw_mci_board {
u32 quirks; /* Workaround / Quirk flags */
unsigned int bus_hz; /* Clock speed at the cclk_in pad */
- unsigned int caps; /* Capabilities */
- unsigned int caps2; /* More capabilities */
+ u32 caps; /* Capabilities */
+ u32 caps2; /* More capabilities */
+ u32 pm_caps; /* PM capabilities */
/*
* Override fifo depth. If 0, autodetect it from the FIFOTH register,
* but note that this may not be reliable after a bootloader has used
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 7abb0e1f7bd..61a10c17aab 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -53,12 +53,12 @@ struct mmc_ios {
#define MMC_TIMING_LEGACY 0
#define MMC_TIMING_MMC_HS 1
#define MMC_TIMING_SD_HS 2
-#define MMC_TIMING_UHS_SDR12 MMC_TIMING_LEGACY
-#define MMC_TIMING_UHS_SDR25 MMC_TIMING_SD_HS
-#define MMC_TIMING_UHS_SDR50 3
-#define MMC_TIMING_UHS_SDR104 4
-#define MMC_TIMING_UHS_DDR50 5
-#define MMC_TIMING_MMC_HS200 6
+#define MMC_TIMING_UHS_SDR12 3
+#define MMC_TIMING_UHS_SDR25 4
+#define MMC_TIMING_UHS_SDR50 5
+#define MMC_TIMING_UHS_SDR104 6
+#define MMC_TIMING_UHS_DDR50 7
+#define MMC_TIMING_MMC_HS200 8
#define MMC_SDR_MODE 0
#define MMC_1_2V_DDR_MODE 1
@@ -136,6 +136,7 @@ struct mmc_host_ops {
void (*enable_preset_value)(struct mmc_host *host, bool enable);
int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv);
void (*hw_reset)(struct mmc_host *host);
+ void (*card_event)(struct mmc_host *host);
};
struct mmc_card;
@@ -211,7 +212,7 @@ struct mmc_host {
#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */
#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */
- unsigned long caps; /* Host capabilities */
+ u32 caps; /* Host capabilities */
#define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */
#define MMC_CAP_MMC_HIGHSPEED (1 << 1) /* Can do MMC high-speed timing */
@@ -241,7 +242,7 @@ struct mmc_host {
#define MMC_CAP_CMD23 (1 << 30) /* CMD23 supported. */
#define MMC_CAP_HW_RESET (1 << 31) /* Hardware reset */
- unsigned int caps2; /* More host capabilities */
+ u32 caps2; /* More host capabilities */
#define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */
#define MMC_CAP2_CACHE_CTRL (1 << 1) /* Allow cache control */
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 01e4b394029..94d532e41c6 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -286,6 +286,7 @@ struct _mmc_csd {
#define EXT_CSD_BKOPS_START 164 /* W */
#define EXT_CSD_SANITIZE_START 165 /* W */
#define EXT_CSD_WR_REL_PARAM 166 /* RO */
+#define EXT_CSD_RPMB_MULT 168 /* RO */
#define EXT_CSD_BOOT_WP 173 /* R/W */
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
#define EXT_CSD_PART_CONFIG 179 /* R/W */
@@ -339,6 +340,7 @@ struct _mmc_csd {
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
+#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3)
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
#define EXT_CSD_PART_SUPPORT_PART_EN (0x1)
diff --git a/include/linux/mmc/mxs-mmc.h b/include/linux/mmc/mxs-mmc.h
deleted file mode 100644
index 7c2ad3a7f2f..00000000000
--- a/include/linux/mmc/mxs-mmc.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2011 Freescale Semiconductor, Inc. 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 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __LINUX_MMC_MXS_MMC_H__
-#define __LINUX_MMC_MXS_MMC_H__
-
-struct mxs_mmc_platform_data {
- int wp_gpio; /* write protect pin */
- unsigned int flags;
-#define SLOTF_4_BIT_CAPABLE (1 << 0)
-#define SLOTF_8_BIT_CAPABLE (1 << 1)
-};
-
-#endif /* __LINUX_MMC_MXS_MMC_H__ */
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 1edcb4dad8c..4bbc3301fbb 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -92,6 +92,8 @@ struct sdhci_host {
#define SDHCI_QUIRK2_HOST_OFF_CARD_ON (1<<0)
#define SDHCI_QUIRK2_HOST_NO_CMD23 (1<<1)
+/* The system physically doesn't support 1.8v, even if the host does */
+#define SDHCI_QUIRK2_NO_1_8_V (1<<2)
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
@@ -158,8 +160,8 @@ struct sdhci_host {
struct timer_list timer; /* Timer for timeouts */
- unsigned int caps; /* Alternative CAPABILITY_0 */
- unsigned int caps1; /* Alternative CAPABILITY_1 */
+ u32 caps; /* Alternative CAPABILITY_0 */
+ u32 caps1; /* Alternative CAPABILITY_1 */
unsigned int ocr_avail_sdio; /* OCR bit masks */
unsigned int ocr_avail_sd;
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 50aaca81f63..0c0b1d608a6 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -63,10 +63,8 @@ enum {
#ifdef CONFIG_CMA
# define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA)
-# define cma_wmark_pages(zone) zone->min_cma_pages
#else
# define is_migrate_cma(migratetype) false
-# define cma_wmark_pages(zone) 0
#endif
#define for_each_migratetype_order(order, type) \
@@ -383,13 +381,6 @@ struct zone {
/* see spanned/present_pages for more description */
seqlock_t span_seqlock;
#endif
-#ifdef CONFIG_CMA
- /*
- * CMA needs to increase watermark levels during the allocation
- * process to make sure that the system is not starved.
- */
- unsigned long min_cma_pages;
-#endif
struct free_area free_area[MAX_ORDER];
#ifndef CONFIG_SPARSEMEM
@@ -752,7 +743,7 @@ extern int init_currently_empty_zone(struct zone *zone, unsigned long start_pfn,
unsigned long size,
enum memmap_context context);
-extern void lruvec_init(struct lruvec *lruvec, struct zone *zone);
+extern void lruvec_init(struct lruvec *lruvec);
static inline struct zone *lruvec_zone(struct lruvec *lruvec)
{
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f8eda0276f0..a848ffc327f 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1488,6 +1488,9 @@ struct napi_gro_cb {
/* Used in ipv6_gro_receive() */
int proto;
+
+ /* used in skb_gro_receive() slow path */
+ struct sk_buff *last;
};
#define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb)
diff --git a/include/linux/node.h b/include/linux/node.h
index 624e53cecc0..2115ad5d6f1 100644
--- a/include/linux/node.h
+++ b/include/linux/node.h
@@ -27,10 +27,9 @@ struct node {
};
struct memory_block;
-extern struct node node_devices[];
+extern struct node *node_devices[];
typedef void (*node_registration_func_t)(struct node *);
-extern int register_node(struct node *, int, struct node *);
extern void unregister_node(struct node *node);
#ifdef CONFIG_NUMA
extern int register_one_node(int nid);
diff --git a/include/linux/of.h b/include/linux/of.h
index b4e50d56fc7..60053bd7e79 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -46,7 +46,7 @@ struct device_node {
const char *name;
const char *type;
phandle phandle;
- char *full_name;
+ const char *full_name;
struct property *properties;
struct property *deadprops; /* removed properties */
@@ -60,7 +60,7 @@ struct device_node {
unsigned long _flags;
void *data;
#if defined(CONFIG_SPARC)
- char *path_component_name;
+ const char *path_component_name;
unsigned int unique_id;
struct of_irq_controller *irq_trans;
#endif
@@ -88,14 +88,14 @@ static inline void of_node_put(struct device_node *node) { }
#ifdef CONFIG_OF
/* Pointer for first entry in chain of all nodes. */
-extern struct device_node *allnodes;
+extern struct device_node *of_allnodes;
extern struct device_node *of_chosen;
extern struct device_node *of_aliases;
extern rwlock_t devtree_lock;
static inline bool of_have_populated_dt(void)
{
- return allnodes != NULL;
+ return of_allnodes != NULL;
}
static inline bool of_node_is_root(const struct device_node *node)
@@ -179,11 +179,22 @@ extern struct device_node *of_find_compatible_node(struct device_node *from,
#define for_each_compatible_node(dn, type, compatible) \
for (dn = of_find_compatible_node(NULL, type, compatible); dn; \
dn = of_find_compatible_node(dn, type, compatible))
-extern struct device_node *of_find_matching_node(struct device_node *from,
- const struct of_device_id *matches);
+extern struct device_node *of_find_matching_node_and_match(
+ struct device_node *from,
+ const struct of_device_id *matches,
+ const struct of_device_id **match);
+static inline struct device_node *of_find_matching_node(
+ struct device_node *from,
+ const struct of_device_id *matches)
+{
+ return of_find_matching_node_and_match(from, matches, NULL);
+}
#define for_each_matching_node(dn, matches) \
for (dn = of_find_matching_node(NULL, matches); dn; \
dn = of_find_matching_node(dn, matches))
+#define for_each_matching_node_and_match(dn, matches, match) \
+ for (dn = of_find_matching_node_and_match(NULL, matches, match); \
+ dn; dn = of_find_matching_node_and_match(dn, matches, match))
extern struct device_node *of_find_node_by_path(const char *path);
extern struct device_node *of_find_node_by_phandle(phandle handle);
extern struct device_node *of_get_parent(const struct device_node *node);
@@ -223,6 +234,10 @@ extern struct device_node *of_find_node_with_property(
extern struct property *of_find_property(const struct device_node *np,
const char *name,
int *lenp);
+extern int of_property_read_u8_array(const struct device_node *np,
+ const char *propname, u8 *out_values, size_t sz);
+extern int of_property_read_u16_array(const struct device_node *np,
+ const char *propname, u16 *out_values, size_t sz);
extern int of_property_read_u32_array(const struct device_node *np,
const char *propname,
u32 *out_values,
@@ -255,7 +270,7 @@ extern int of_n_size_cells(struct device_node *np);
extern const struct of_device_id *of_match_node(
const struct of_device_id *matches, const struct device_node *node);
extern int of_modalias_node(struct device_node *node, char *modalias, int len);
-extern struct device_node *of_parse_phandle(struct device_node *np,
+extern struct device_node *of_parse_phandle(const struct device_node *np,
const char *phandle_name,
int index);
extern int of_parse_phandle_with_args(struct device_node *np,
@@ -364,6 +379,18 @@ static inline struct device_node *of_find_compatible_node(
return NULL;
}
+static inline int of_property_read_u8_array(const struct device_node *np,
+ const char *propname, u8 *out_values, size_t sz)
+{
+ return -ENOSYS;
+}
+
+static inline int of_property_read_u16_array(const struct device_node *np,
+ const char *propname, u16 *out_values, size_t sz)
+{
+ return -ENOSYS;
+}
+
static inline int of_property_read_u32_array(const struct device_node *np,
const char *propname,
u32 *out_values, size_t sz)
@@ -411,7 +438,7 @@ static inline int of_property_match_string(struct device_node *np,
return -ENOSYS;
}
-static inline struct device_node *of_parse_phandle(struct device_node *np,
+static inline struct device_node *of_parse_phandle(const struct device_node *np,
const char *phandle_name,
int index)
{
@@ -470,6 +497,20 @@ static inline bool of_property_read_bool(const struct device_node *np,
return prop ? true : false;
}
+static inline int of_property_read_u8(const struct device_node *np,
+ const char *propname,
+ u8 *out_value)
+{
+ return of_property_read_u8_array(np, propname, out_value, 1);
+}
+
+static inline int of_property_read_u16(const struct device_node *np,
+ const char *propname,
+ u16 *out_value)
+{
+ return of_property_read_u16_array(np, propname, out_value, 1);
+}
+
static inline int of_property_read_u32(const struct device_node *np,
const char *propname,
u32 *out_value)
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index e20e3af68fb..0506eb53519 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -42,10 +42,12 @@ static inline struct device_node *of_find_matching_node_by_address(
{
return NULL;
}
+#ifndef of_iomap
static inline void __iomem *of_iomap(struct device_node *device, int index)
{
return NULL;
}
+#endif
static inline const __be32 *of_get_address(struct device_node *dev, int index,
u64 *size, unsigned int *flags)
{
diff --git a/include/linux/oom.h b/include/linux/oom.h
index fb9826847b8..da60007075b 100644
--- a/include/linux/oom.h
+++ b/include/linux/oom.h
@@ -29,8 +29,23 @@ enum oom_scan_t {
OOM_SCAN_SELECT, /* always select this thread first */
};
-extern void compare_swap_oom_score_adj(int old_val, int new_val);
-extern int test_set_oom_score_adj(int new_val);
+/* Thread is the potential origin of an oom condition; kill first on oom */
+#define OOM_FLAG_ORIGIN ((__force oom_flags_t)0x1)
+
+static inline void set_current_oom_origin(void)
+{
+ current->signal->oom_flags |= OOM_FLAG_ORIGIN;
+}
+
+static inline void clear_current_oom_origin(void)
+{
+ current->signal->oom_flags &= ~OOM_FLAG_ORIGIN;
+}
+
+static inline bool oom_task_origin(const struct task_struct *p)
+{
+ return !!(p->signal->oom_flags & OOM_FLAG_ORIGIN);
+}
extern unsigned long oom_badness(struct task_struct *p,
struct mem_cgroup *memcg, const nodemask_t *nodemask,
@@ -49,8 +64,6 @@ extern void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask,
extern enum oom_scan_t oom_scan_process_thread(struct task_struct *task,
unsigned long totalpages, const nodemask_t *nodemask,
bool force_kill);
-extern void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
- int order);
extern void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
int order, nodemask_t *mask, bool force_kill);
diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
index 76a9539cfd3..a92061e08d4 100644
--- a/include/linux/page-isolation.h
+++ b/include/linux/page-isolation.h
@@ -2,7 +2,8 @@
#define __LINUX_PAGEISOLATION_H
-bool has_unmovable_pages(struct zone *zone, struct page *page, int count);
+bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
+ bool skip_hwpoisoned_pages);
void set_pageblock_migratetype(struct page *page, int migratetype);
int move_freepages_block(struct zone *zone, struct page *page,
int migratetype);
@@ -21,7 +22,7 @@ int move_freepages(struct zone *zone,
*/
int
start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
- unsigned migratetype);
+ unsigned migratetype, bool skip_hwpoisoned_pages);
/*
* Changes MIGRATE_ISOLATE to MIGRATE_MOVABLE.
@@ -34,12 +35,13 @@ undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
/*
* Test all pages in [start_pfn, end_pfn) are isolated or not.
*/
-int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn);
+int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn,
+ bool skip_hwpoisoned_pages);
/*
* Internal functions. Changes pageblock's migrate type.
*/
-int set_migratetype_isolate(struct page *page);
+int set_migratetype_isolate(struct page *page, bool skip_hwpoisoned_pages);
void unset_migratetype_isolate(struct page *page, unsigned migratetype);
struct page *alloc_migrate_target(struct page *page, unsigned long private,
int **resultp);
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index e42c762f0dc..6da609d14c1 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -24,6 +24,7 @@ enum mapping_flags {
AS_ENOSPC = __GFP_BITS_SHIFT + 1, /* ENOSPC on async write */
AS_MM_ALL_LOCKS = __GFP_BITS_SHIFT + 2, /* under mm_take_all_locks() */
AS_UNEVICTABLE = __GFP_BITS_SHIFT + 3, /* e.g., ramdisk, SHM_LOCK */
+ AS_BALLOON_MAP = __GFP_BITS_SHIFT + 4, /* balloon page special map */
};
static inline void mapping_set_error(struct address_space *mapping, int error)
@@ -53,6 +54,21 @@ static inline int mapping_unevictable(struct address_space *mapping)
return !!mapping;
}
+static inline void mapping_set_balloon(struct address_space *mapping)
+{
+ set_bit(AS_BALLOON_MAP, &mapping->flags);
+}
+
+static inline void mapping_clear_balloon(struct address_space *mapping)
+{
+ clear_bit(AS_BALLOON_MAP, &mapping->flags);
+}
+
+static inline int mapping_balloon(struct address_space *mapping)
+{
+ return mapping && test_bit(AS_BALLOON_MAP, &mapping->flags);
+}
+
static inline gfp_t mapping_gfp_mask(struct address_space * mapping)
{
return (__force gfp_t)mapping->flags & __GFP_BITS_MASK;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index ee2179546c6..d03d2463efa 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -588,7 +588,7 @@ struct pci_driver {
* in a generic manner.
*/
#define DEFINE_PCI_DEVICE_TABLE(_table) \
- const struct pci_device_id _table[] __devinitconst
+ const struct pci_device_id _table[]
/**
* PCI_DEVICE - macro used to describe a specific pci device
@@ -686,7 +686,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
void pci_bus_release_busn_res(struct pci_bus *b);
-struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus,
+struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
struct pci_ops *ops, void *sysdata,
struct list_head *resources);
struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,
@@ -941,10 +941,8 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev);
/* Functions for PCI Hotplug drivers to use */
int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap);
-#ifdef CONFIG_HOTPLUG
unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge);
unsigned int pci_rescan_bus(struct pci_bus *bus);
-#endif
/* Vital product data routines */
ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf);
@@ -1580,7 +1578,7 @@ extern int pci_pci_problems;
extern unsigned long pci_cardbus_io_size;
extern unsigned long pci_cardbus_mem_size;
-extern u8 __devinitdata pci_dfl_cache_line_size;
+extern u8 pci_dfl_cache_line_size;
extern u8 pci_cache_line_size;
extern unsigned long pci_hotplug_io_size;
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 9d36b829533..0f8447376dd 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1985,6 +1985,9 @@
#define PCI_DEVICE_ID_EXAR_XR17C152 0x0152
#define PCI_DEVICE_ID_EXAR_XR17C154 0x0154
#define PCI_DEVICE_ID_EXAR_XR17C158 0x0158
+#define PCI_DEVICE_ID_EXAR_XR17V352 0x0352
+#define PCI_DEVICE_ID_EXAR_XR17V354 0x0354
+#define PCI_DEVICE_ID_EXAR_XR17V358 0x0358
#define PCI_VENDOR_ID_MICROGATE 0x13c0
#define PCI_DEVICE_ID_MICROGATE_USC 0x0010
@@ -2323,6 +2326,8 @@
#define PCI_VENDOR_ID_TOPSPIN 0x1867
+#define PCI_VENDOR_ID_COMMTECH 0x18f7
+
#define PCI_VENDOR_ID_SILAN 0x1904
#define PCI_VENDOR_ID_RENESAS 0x1912
diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h
index 250a4acddb2..bd1e86071e5 100644
--- a/include/linux/percpu-rwsem.h
+++ b/include/linux/percpu-rwsem.h
@@ -13,7 +13,7 @@ struct percpu_rw_semaphore {
};
#define light_mb() barrier()
-#define heavy_mb() synchronize_sched()
+#define heavy_mb() synchronize_sched_expedited()
static inline void percpu_down_read(struct percpu_rw_semaphore *p)
{
@@ -51,7 +51,7 @@ static inline void percpu_down_write(struct percpu_rw_semaphore *p)
{
mutex_lock(&p->mtx);
p->locked = true;
- synchronize_sched(); /* make sure that all readers exit the rcu_read_lock_sched region */
+ synchronize_sched_expedited(); /* make sure that all readers exit the rcu_read_lock_sched region */
while (__percpu_count(p->counters))
msleep(1);
heavy_mb(); /* C, between read of p->counter and write to data, paired with B */
diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h
index 4f0abb9f1c0..47a1bdd8887 100644
--- a/include/linux/pinctrl/pinconf-generic.h
+++ b/include/linux/pinctrl/pinconf-generic.h
@@ -46,11 +46,11 @@
* @PIN_CONFIG_DRIVE_OPEN_SOURCE: the pin will be driven with open source
* (open emitter). Sending this config will enabale open drain mode, the
* argument is ignored.
+ * @PIN_CONFIG_INPUT_SCHMITT_DISABLE: disable schmitt-trigger mode on the pin.
* @PIN_CONFIG_INPUT_SCHMITT: this will configure an input pin to run in
* schmitt-trigger mode. If the schmitt-trigger has adjustable hysteresis,
* the threshold value is given on a custom format as argument when
- * setting pins to this mode. The argument zero turns the schmitt trigger
- * off.
+ * setting pins to this mode.
* @PIN_CONFIG_INPUT_DEBOUNCE: this will configure the pin to debounce mode,
* which means it will wait for signals to settle when reading inputs. The
* argument gives the debounce time on a custom format. Setting the
@@ -74,6 +74,7 @@ enum pin_config_param {
PIN_CONFIG_DRIVE_PUSH_PULL,
PIN_CONFIG_DRIVE_OPEN_DRAIN,
PIN_CONFIG_DRIVE_OPEN_SOURCE,
+ PIN_CONFIG_INPUT_SCHMITT_DISABLE,
PIN_CONFIG_INPUT_SCHMITT,
PIN_CONFIG_INPUT_DEBOUNCE,
PIN_CONFIG_POWER_SOURCE,
diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h
index 7d087f03e91..04d6700d99a 100644
--- a/include/linux/pinctrl/pinctrl.h
+++ b/include/linux/pinctrl/pinctrl.h
@@ -134,6 +134,25 @@ extern void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev,
extern void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *ranges,
unsigned nranges);
+extern void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range);
+
+extern struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname,
+ struct pinctrl_gpio_range *range);
+extern struct pinctrl_gpio_range *
+pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,
+ unsigned int pin);
+
+#ifdef CONFIG_OF
+extern struct pinctrl_dev *of_pinctrl_get(struct device_node *np);
+#else
+static inline
+struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
+{
+ return NULL;
+}
+#endif /* CONFIG_OF */
+
extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev);
extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev);
#else
diff --git a/include/linux/platform_data/ad5449.h b/include/linux/platform_data/ad5449.h
new file mode 100644
index 00000000000..bd712bd4b94
--- /dev/null
+++ b/include/linux/platform_data/ad5449.h
@@ -0,0 +1,40 @@
+/*
+ * AD5415, AD5426, AD5429, AD5432, AD5439, AD5443, AD5449 Digital to Analog
+ * Converter driver.
+ *
+ * Copyright 2012 Analog Devices Inc.
+ * Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#ifndef __LINUX_PLATFORM_DATA_AD5449_H__
+#define __LINUX_PLATFORM_DATA_AD5449_H__
+
+/**
+ * enum ad5449_sdo_mode - AD5449 SDO pin configuration
+ * @AD5449_SDO_DRIVE_FULL: Drive the SDO pin with full strength.
+ * @AD5449_SDO_DRIVE_WEAK: Drive the SDO pin with not full strength.
+ * @AD5449_SDO_OPEN_DRAIN: Operate the SDO pin in open-drain mode.
+ * @AD5449_SDO_DISABLED: Disable the SDO pin, in this mode it is not possible to
+ * read back from the device.
+ */
+enum ad5449_sdo_mode {
+ AD5449_SDO_DRIVE_FULL = 0x0,
+ AD5449_SDO_DRIVE_WEAK = 0x1,
+ AD5449_SDO_OPEN_DRAIN = 0x2,
+ AD5449_SDO_DISABLED = 0x3,
+};
+
+/**
+ * struct ad5449_platform_data - Platform data for the ad5449 DAC driver
+ * @sdo_mode: SDO pin mode
+ * @hardware_clear_to_midscale: Whether asserting the hardware CLR pin sets the
+ * outputs to midscale (true) or to zero scale(false).
+ */
+struct ad5449_platform_data {
+ enum ad5449_sdo_mode sdo_mode;
+ bool hardware_clear_to_midscale;
+};
+
+#endif
diff --git a/include/linux/platform_data/ad7298.h b/include/linux/platform_data/ad7298.h
new file mode 100644
index 00000000000..fbf8adf1363
--- /dev/null
+++ b/include/linux/platform_data/ad7298.h
@@ -0,0 +1,20 @@
+/*
+ * AD7298 SPI ADC driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#ifndef __LINUX_PLATFORM_DATA_AD7298_H__
+#define __LINUX_PLATFORM_DATA_AD7298_H__
+
+/**
+ * struct ad7298_platform_data - Platform data for the ad7298 ADC driver
+ * @ext_ref: Whether to use an external reference voltage.
+ **/
+struct ad7298_platform_data {
+ bool ext_ref;
+};
+
+#endif /* IIO_ADC_AD7298_H_ */
diff --git a/include/linux/platform_data/ad7793.h b/include/linux/platform_data/ad7793.h
new file mode 100644
index 00000000000..7ea6751aae6
--- /dev/null
+++ b/include/linux/platform_data/ad7793.h
@@ -0,0 +1,112 @@
+/*
+ * AD7792/AD7793 SPI ADC driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+#ifndef __LINUX_PLATFORM_DATA_AD7793_H__
+#define __LINUX_PLATFORM_DATA_AD7793_H__
+
+/**
+ * enum ad7793_clock_source - AD7793 clock source selection
+ * @AD7793_CLK_SRC_INT: Internal 64 kHz clock, not available at the CLK pin.
+ * @AD7793_CLK_SRC_INT_CO: Internal 64 kHz clock, available at the CLK pin.
+ * @AD7793_CLK_SRC_EXT: Use external clock.
+ * @AD7793_CLK_SRC_EXT_DIV2: Use external clock divided by 2.
+ */
+enum ad7793_clock_source {
+ AD7793_CLK_SRC_INT,
+ AD7793_CLK_SRC_INT_CO,
+ AD7793_CLK_SRC_EXT,
+ AD7793_CLK_SRC_EXT_DIV2,
+};
+
+/**
+ * enum ad7793_bias_voltage - AD7793 bias voltage selection
+ * @AD7793_BIAS_VOLTAGE_DISABLED: Bias voltage generator disabled
+ * @AD7793_BIAS_VOLTAGE_AIN1: Bias voltage connected to AIN1(-).
+ * @AD7793_BIAS_VOLTAGE_AIN2: Bias voltage connected to AIN2(-).
+ * @AD7793_BIAS_VOLTAGE_AIN3: Bias voltage connected to AIN3(-).
+ * Only valid for AD7795/AD7796.
+ */
+enum ad7793_bias_voltage {
+ AD7793_BIAS_VOLTAGE_DISABLED,
+ AD7793_BIAS_VOLTAGE_AIN1,
+ AD7793_BIAS_VOLTAGE_AIN2,
+ AD7793_BIAS_VOLTAGE_AIN3,
+};
+
+/**
+ * enum ad7793_refsel - AD7793 reference voltage selection
+ * @AD7793_REFSEL_REFIN1: External reference applied between REFIN1(+)
+ * and REFIN1(-).
+ * @AD7793_REFSEL_REFIN2: External reference applied between REFIN2(+) and
+ * and REFIN1(-). Only valid for AD7795/AD7796.
+ * @AD7793_REFSEL_INTERNAL: Internal 1.17 V reference.
+ */
+enum ad7793_refsel {
+ AD7793_REFSEL_REFIN1 = 0,
+ AD7793_REFSEL_REFIN2 = 1,
+ AD7793_REFSEL_INTERNAL = 2,
+};
+
+/**
+ * enum ad7793_current_source_direction - AD7793 excitation current direction
+ * @AD7793_IEXEC1_IOUT1_IEXEC2_IOUT2: Current source IEXC1 connected to pin
+ * IOUT1, current source IEXC2 connected to pin IOUT2.
+ * @AD7793_IEXEC1_IOUT2_IEXEC2_IOUT1: Current source IEXC2 connected to pin
+ * IOUT1, current source IEXC1 connected to pin IOUT2.
+ * @AD7793_IEXEC1_IEXEC2_IOUT1: Both current sources connected to pin IOUT1.
+ * Only valid when the current sources are set to 10 uA or 210 uA.
+ * @AD7793_IEXEC1_IEXEC2_IOUT2: Both current sources connected to Pin IOUT2.
+ * Only valid when the current ources are set to 10 uA or 210 uA.
+ */
+enum ad7793_current_source_direction {
+ AD7793_IEXEC1_IOUT1_IEXEC2_IOUT2 = 0,
+ AD7793_IEXEC1_IOUT2_IEXEC2_IOUT1 = 1,
+ AD7793_IEXEC1_IEXEC2_IOUT1 = 2,
+ AD7793_IEXEC1_IEXEC2_IOUT2 = 3,
+};
+
+/**
+ * enum ad7793_excitation_current - AD7793 excitation current selection
+ * @AD7793_IX_DISABLED: Excitation current Disabled.
+ * @AD7793_IX_10uA: Enable 10 micro-ampere excitation current.
+ * @AD7793_IX_210uA: Enable 210 micro-ampere excitation current.
+ * @AD7793_IX_1mA: Enable 1 milli-Ampere excitation current.
+ */
+enum ad7793_excitation_current {
+ AD7793_IX_DISABLED = 0,
+ AD7793_IX_10uA = 1,
+ AD7793_IX_210uA = 2,
+ AD7793_IX_1mA = 3,
+};
+
+/**
+ * struct ad7793_platform_data - AD7793 platform data
+ * @clock_src: Clock source selection
+ * @burnout_current: If set to true the 100nA burnout current is enabled.
+ * @boost_enable: Enable boost for the bias voltage generator.
+ * @buffered: If set to true configure the device for buffered input mode.
+ * @unipolar: If set to true sample in unipolar mode, if set to false sample in
+ * bipolar mode.
+ * @refsel: Reference voltage selection
+ * @bias_voltage: Bias voltage selection
+ * @exitation_current: Excitation current selection
+ * @current_source_direction: Excitation current direction selection
+ */
+struct ad7793_platform_data {
+ enum ad7793_clock_source clock_src;
+ bool burnout_current;
+ bool boost_enable;
+ bool buffered;
+ bool unipolar;
+
+ enum ad7793_refsel refsel;
+ enum ad7793_bias_voltage bias_voltage;
+ enum ad7793_excitation_current exitation_current;
+ enum ad7793_current_source_direction current_source_direction;
+};
+
+#endif /* IIO_ADC_AD7793_H_ */
diff --git a/include/linux/platform_data/ad7887.h b/include/linux/platform_data/ad7887.h
new file mode 100644
index 00000000000..1e06eac3174
--- /dev/null
+++ b/include/linux/platform_data/ad7887.h
@@ -0,0 +1,26 @@
+/*
+ * AD7887 SPI ADC driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+#ifndef IIO_ADC_AD7887_H_
+#define IIO_ADC_AD7887_H_
+
+/**
+ * struct ad7887_platform_data - AD7887 ADC driver platform data
+ * @en_dual: Whether to use dual channel mode. If set to true AIN1 becomes the
+ * second input channel, and Vref is internally connected to Vdd. If set to
+ * false the device is used in single channel mode and AIN1/Vref is used as
+ * VREF input.
+ * @use_onchip_ref: Whether to use the onchip reference. If set to true the
+ * internal 2.5V reference is used. If set to false a external reference is
+ * used.
+ */
+struct ad7887_platform_data {
+ bool en_dual;
+ bool use_onchip_ref;
+};
+
+#endif /* IIO_ADC_AD7887_H_ */
diff --git a/include/linux/platform_data/ads7828.h b/include/linux/platform_data/ads7828.h
new file mode 100644
index 00000000000..3245f45f9d7
--- /dev/null
+++ b/include/linux/platform_data/ads7828.h
@@ -0,0 +1,29 @@
+/*
+ * TI ADS7828 A/D Converter platform data definition
+ *
+ * Copyright (c) 2012 Savoir-faire Linux Inc.
+ * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+ *
+ * For further information, see the Documentation/hwmon/ads7828 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.
+ */
+
+#ifndef _PDATA_ADS7828_H
+#define _PDATA_ADS7828_H
+
+/**
+ * struct ads7828_platform_data - optional ADS7828 connectivity info
+ * @diff_input: Differential input mode.
+ * @ext_vref: Use an external voltage reference.
+ * @vref_mv: Voltage reference value, if external.
+ */
+struct ads7828_platform_data {
+ bool diff_input;
+ bool ext_vref;
+ unsigned int vref_mv;
+};
+
+#endif /* _PDATA_ADS7828_H */
diff --git a/include/linux/platform_data/clk-integrator.h b/include/linux/platform_data/clk-integrator.h
index 83fe9c283bb..280edac9d0a 100644
--- a/include/linux/platform_data/clk-integrator.h
+++ b/include/linux/platform_data/clk-integrator.h
@@ -1 +1,3 @@
void integrator_clk_init(bool is_cp);
+void integrator_impd1_clk_init(void __iomem *base, unsigned int id);
+void integrator_impd1_clk_exit(unsigned int id);
diff --git a/include/linux/platform_data/gpio-ts5500.h b/include/linux/platform_data/gpio-ts5500.h
new file mode 100644
index 00000000000..b10d11c9bb4
--- /dev/null
+++ b/include/linux/platform_data/gpio-ts5500.h
@@ -0,0 +1,27 @@
+/*
+ * GPIO (DIO) header for Technologic Systems TS-5500
+ *
+ * Copyright (c) 2012 Savoir-faire Linux Inc.
+ * Vivien Didelot <vivien.didelot@savoirfairelinux.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 _PDATA_GPIO_TS5500_H
+#define _PDATA_GPIO_TS5500_H
+
+/**
+ * struct ts5500_dio_platform_data - TS-5500 pin block configuration
+ * @base: The GPIO base number to use.
+ * @strap: The only pin connected to an interrupt in a block is input-only.
+ * If you need a bidirectional line which can trigger an IRQ, you
+ * may strap it with an in/out pin. This flag indicates this case.
+ */
+struct ts5500_dio_platform_data {
+ int base;
+ bool strap;
+};
+
+#endif /* _PDATA_GPIO_TS5500_H */
diff --git a/include/linux/platform_data/omap_drm.h b/include/linux/platform_data/omap_drm.h
index 3da73bdc203..f4e4a237ebd 100644
--- a/include/linux/platform_data/omap_drm.h
+++ b/include/linux/platform_data/omap_drm.h
@@ -46,6 +46,7 @@ struct omap_kms_platform_data {
};
struct omap_drm_platform_data {
+ uint32_t omaprev;
struct omap_kms_platform_data *kms_pdata;
};
diff --git a/include/linux/platform_data/omap_ocp2scp.h b/include/linux/platform_data/omap_ocp2scp.h
new file mode 100644
index 00000000000..5c6c3939355
--- /dev/null
+++ b/include/linux/platform_data/omap_ocp2scp.h
@@ -0,0 +1,31 @@
+/*
+ * omap_ocp2scp.h -- ocp2scp header file
+ *
+ * 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.
+ *
+ */
+
+#ifndef __DRIVERS_OMAP_OCP2SCP_H
+#define __DRIVERS_OMAP_OCP2SCP_H
+
+struct omap_ocp2scp_dev {
+ const char *drv_name;
+ struct resource *res;
+};
+
+struct omap_ocp2scp_platform_data {
+ int dev_cnt;
+ struct omap_ocp2scp_dev **devices;
+};
+#endif /* __DRIVERS_OMAP_OCP2SCP_H */
diff --git a/include/linux/platform_data/pinctrl-coh901.h b/include/linux/platform_data/pinctrl-coh901.h
index 30dea251b83..dfbc65d1048 100644
--- a/include/linux/platform_data/pinctrl-coh901.h
+++ b/include/linux/platform_data/pinctrl-coh901.h
@@ -13,14 +13,10 @@
* struct u300_gpio_platform - U300 GPIO platform data
* @ports: number of GPIO block ports
* @gpio_base: first GPIO number for this block (use a free range)
- * @gpio_irq_base: first GPIO IRQ number for this block (use a free range)
- * @pinctrl_device: pin control device to spawn as child
*/
struct u300_gpio_platform {
u8 ports;
int gpio_base;
- int gpio_irq_base;
- struct platform_device *pinctrl_device;
};
#endif /* __MACH_U300_GPIO_U300_H */
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/include/linux/platform_data/pinctrl-nomadik.h
index 3b8ec60af35..f73b2f0c55b 100644
--- a/arch/arm/plat-nomadik/include/plat/pincfg.h
+++ b/include/linux/platform_data/pinctrl-nomadik.h
@@ -1,16 +1,17 @@
/*
- * Copyright (C) ST-Ericsson SA 2010
+ * Structures and registers for GPIO access in the Nomadik SoC
*
- * License terms: GNU General Public License, version 2
- * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * Copyright (C) 2008 STMicroelectronics
+ * Author: Prafulla WADASKAR <prafulla.wadaskar@st.com>
+ * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
*
- * Based on arch/arm/mach-pxa/include/mach/mfp.h:
- * Copyright (C) 2007 Marvell International Ltd.
- * eric miao <eric.miao@marvell.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 __PLAT_PINCFG_H
-#define __PLAT_PINCFG_H
+#ifndef __PLAT_NOMADIK_GPIO
+#define __PLAT_NOMADIK_GPIO
/*
* pin configurations are represented by 32-bit integers:
@@ -166,8 +167,100 @@ typedef unsigned long pin_cfg_t;
(PIN_CFG_DEFAULT |\
(PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val))
+/*
+ * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
+ * the "gpio" namespace for generic and cross-machine functions
+ */
+
+#define GPIO_BLOCK_SHIFT 5
+#define NMK_GPIO_PER_CHIP (1 << GPIO_BLOCK_SHIFT)
+
+/* Register in the logic block */
+#define NMK_GPIO_DAT 0x00
+#define NMK_GPIO_DATS 0x04
+#define NMK_GPIO_DATC 0x08
+#define NMK_GPIO_PDIS 0x0c
+#define NMK_GPIO_DIR 0x10
+#define NMK_GPIO_DIRS 0x14
+#define NMK_GPIO_DIRC 0x18
+#define NMK_GPIO_SLPC 0x1c
+#define NMK_GPIO_AFSLA 0x20
+#define NMK_GPIO_AFSLB 0x24
+#define NMK_GPIO_LOWEMI 0x28
+
+#define NMK_GPIO_RIMSC 0x40
+#define NMK_GPIO_FIMSC 0x44
+#define NMK_GPIO_IS 0x48
+#define NMK_GPIO_IC 0x4c
+#define NMK_GPIO_RWIMSC 0x50
+#define NMK_GPIO_FWIMSC 0x54
+#define NMK_GPIO_WKS 0x58
+/* These appear in DB8540 and later ASICs */
+#define NMK_GPIO_EDGELEVEL 0x5C
+#define NMK_GPIO_LEVEL 0x60
+
+/* Alternate functions: function C is set in hw by setting both A and B */
+#define NMK_GPIO_ALT_GPIO 0
+#define NMK_GPIO_ALT_A 1
+#define NMK_GPIO_ALT_B 2
+#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
+
+#define NMK_GPIO_ALT_CX_SHIFT 2
+#define NMK_GPIO_ALT_C1 ((1<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+#define NMK_GPIO_ALT_C2 ((2<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+#define NMK_GPIO_ALT_C3 ((3<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+#define NMK_GPIO_ALT_C4 ((4<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+
+/* Pull up/down values */
+enum nmk_gpio_pull {
+ NMK_GPIO_PULL_NONE,
+ NMK_GPIO_PULL_UP,
+ NMK_GPIO_PULL_DOWN,
+};
+
+/* Sleep mode */
+enum nmk_gpio_slpm {
+ NMK_GPIO_SLPM_INPUT,
+ NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
+ NMK_GPIO_SLPM_NOCHANGE,
+ NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
+};
+
+/* Older deprecated pin config API that should go away soon */
extern int nmk_config_pin(pin_cfg_t cfg, bool sleep);
extern int nmk_config_pins(pin_cfg_t *cfgs, int num);
extern int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num);
-
+extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode);
+extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull);
+#ifdef CONFIG_PINCTRL_NOMADIK
+extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
+#else
+static inline int nmk_gpio_set_mode(int gpio, int gpio_mode)
+{
+ return -ENODEV;
+}
#endif
+extern int nmk_gpio_get_mode(int gpio);
+
+extern void nmk_gpio_wakeups_suspend(void);
+extern void nmk_gpio_wakeups_resume(void);
+
+extern void nmk_gpio_clocks_enable(void);
+extern void nmk_gpio_clocks_disable(void);
+
+extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up);
+
+/*
+ * Platform data to register a block: only the initial gpio/irq number.
+ */
+struct nmk_gpio_platform_data {
+ char *name;
+ int first_gpio;
+ int first_irq;
+ int num_gpio;
+ u32 (*get_secondary_status)(unsigned int bank);
+ void (*set_ioforce)(bool enable);
+ bool supports_sleepmode;
+};
+
+#endif /* __PLAT_NOMADIK_GPIO */
diff --git a/include/linux/platform_data/pxa_sdhci.h b/include/linux/platform_data/pxa_sdhci.h
index 59acd987ed3..27d3156d093 100644
--- a/include/linux/platform_data/pxa_sdhci.h
+++ b/include/linux/platform_data/pxa_sdhci.h
@@ -38,6 +38,7 @@
* @max_speed: the maximum speed supported
* @host_caps: Standard MMC host capabilities bit field.
* @quirks: quirks of platfrom
+ * @quirks2: quirks2 of platfrom
* @pm_caps: pm_caps of platfrom
*/
struct sdhci_pxa_platdata {
@@ -48,9 +49,10 @@ struct sdhci_pxa_platdata {
unsigned int ext_cd_gpio;
bool ext_cd_gpio_invert;
unsigned int max_speed;
- unsigned int host_caps;
- unsigned int host_caps2;
+ u32 host_caps;
+ u32 host_caps2;
unsigned int quirks;
+ unsigned int quirks2;
unsigned int pm_caps;
};
diff --git a/include/linux/platform_data/uio_dmem_genirq.h b/include/linux/platform_data/uio_dmem_genirq.h
new file mode 100644
index 00000000000..973c1bb3216
--- /dev/null
+++ b/include/linux/platform_data/uio_dmem_genirq.h
@@ -0,0 +1,26 @@
+/*
+ * include/linux/platform_data/uio_dmem_genirq.h
+ *
+ * Copyright (C) 2012 Damian Hobson-Garcia
+ *
+ * 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 _UIO_DMEM_GENIRQ_H
+#define _UIO_DMEM_GENIRQ_H
+
+#include <linux/uio_driver.h>
+
+struct uio_dmem_genirq_pdata {
+ struct uio_info uioinfo;
+ unsigned int *dynamic_region_sizes;
+ unsigned int num_dynamic_regions;
+};
+#endif /* _UIO_DMEM_GENIRQ_H */
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 5711e9525a2..a9ded9a3c17 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -55,6 +55,7 @@ extern int platform_add_devices(struct platform_device **, int);
struct platform_device_info {
struct device *parent;
+ struct acpi_dev_node acpi_node;
const char *name;
int id;
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 007e687c4f6..03d7bb14531 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -546,10 +546,9 @@ struct dev_pm_info {
unsigned long active_jiffies;
unsigned long suspended_jiffies;
unsigned long accounting_timestamp;
- struct dev_pm_qos_request *pq_req;
#endif
struct pm_subsys_data *subsys_data; /* Owned by the subsystem. */
- struct pm_qos_constraints *constraints;
+ struct dev_pm_qos *qos;
};
extern void update_pm_runtime_accounting(struct device *dev);
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
index 9924ea1f22e..5a95013905c 100644
--- a/include/linux/pm_qos.h
+++ b/include/linux/pm_qos.h
@@ -20,6 +20,13 @@ enum {
PM_QOS_NUM_CLASSES,
};
+enum pm_qos_flags_status {
+ PM_QOS_FLAGS_UNDEFINED = -1,
+ PM_QOS_FLAGS_NONE,
+ PM_QOS_FLAGS_SOME,
+ PM_QOS_FLAGS_ALL,
+};
+
#define PM_QOS_DEFAULT_VALUE -1
#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
@@ -27,14 +34,31 @@ enum {
#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0
#define PM_QOS_DEV_LAT_DEFAULT_VALUE 0
+#define PM_QOS_FLAG_NO_POWER_OFF (1 << 0)
+#define PM_QOS_FLAG_REMOTE_WAKEUP (1 << 1)
+
struct pm_qos_request {
struct plist_node node;
int pm_qos_class;
struct delayed_work work; /* for pm_qos_update_request_timeout */
};
+struct pm_qos_flags_request {
+ struct list_head node;
+ s32 flags; /* Do not change to 64 bit */
+};
+
+enum dev_pm_qos_req_type {
+ DEV_PM_QOS_LATENCY = 1,
+ DEV_PM_QOS_FLAGS,
+};
+
struct dev_pm_qos_request {
- struct plist_node node;
+ enum dev_pm_qos_req_type type;
+ union {
+ struct plist_node pnode;
+ struct pm_qos_flags_request flr;
+ } data;
struct device *dev;
};
@@ -45,8 +69,8 @@ enum pm_qos_type {
};
/*
- * Note: The lockless read path depends on the CPU accessing
- * target_value atomically. Atomic access is only guaranteed on all CPU
+ * Note: The lockless read path depends on the CPU accessing target_value
+ * or effective_flags atomically. Atomic access is only guaranteed on all CPU
* types linux supports for 32 bit quantites
*/
struct pm_qos_constraints {
@@ -57,6 +81,18 @@ struct pm_qos_constraints {
struct blocking_notifier_head *notifiers;
};
+struct pm_qos_flags {
+ struct list_head list;
+ s32 effective_flags; /* Do not change to 64 bit */
+};
+
+struct dev_pm_qos {
+ struct pm_qos_constraints latency;
+ struct pm_qos_flags flags;
+ struct dev_pm_qos_request *latency_req;
+ struct dev_pm_qos_request *flags_req;
+};
+
/* Action requested to pm_qos_update_target */
enum pm_qos_req_action {
PM_QOS_ADD_REQ, /* Add a new request */
@@ -71,6 +107,9 @@ static inline int dev_pm_qos_request_active(struct dev_pm_qos_request *req)
int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node,
enum pm_qos_req_action action, int value);
+bool pm_qos_update_flags(struct pm_qos_flags *pqf,
+ struct pm_qos_flags_request *req,
+ enum pm_qos_req_action action, s32 val);
void pm_qos_add_request(struct pm_qos_request *req, int pm_qos_class,
s32 value);
void pm_qos_update_request(struct pm_qos_request *req,
@@ -86,10 +125,12 @@ int pm_qos_request_active(struct pm_qos_request *req);
s32 pm_qos_read_value(struct pm_qos_constraints *c);
#ifdef CONFIG_PM
+enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, s32 mask);
+enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev, s32 mask);
s32 __dev_pm_qos_read_value(struct device *dev);
s32 dev_pm_qos_read_value(struct device *dev);
int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
- s32 value);
+ enum dev_pm_qos_req_type type, s32 value);
int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value);
int dev_pm_qos_remove_request(struct dev_pm_qos_request *req);
int dev_pm_qos_add_notifier(struct device *dev,
@@ -103,12 +144,19 @@ void dev_pm_qos_constraints_destroy(struct device *dev);
int dev_pm_qos_add_ancestor_request(struct device *dev,
struct dev_pm_qos_request *req, s32 value);
#else
+static inline enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev,
+ s32 mask)
+ { return PM_QOS_FLAGS_UNDEFINED; }
+static inline enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev,
+ s32 mask)
+ { return PM_QOS_FLAGS_UNDEFINED; }
static inline s32 __dev_pm_qos_read_value(struct device *dev)
{ return 0; }
static inline s32 dev_pm_qos_read_value(struct device *dev)
{ return 0; }
static inline int dev_pm_qos_add_request(struct device *dev,
struct dev_pm_qos_request *req,
+ enum dev_pm_qos_req_type type,
s32 value)
{ return 0; }
static inline int dev_pm_qos_update_request(struct dev_pm_qos_request *req,
@@ -144,10 +192,31 @@ static inline int dev_pm_qos_add_ancestor_request(struct device *dev,
#ifdef CONFIG_PM_RUNTIME
int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value);
void dev_pm_qos_hide_latency_limit(struct device *dev);
+int dev_pm_qos_expose_flags(struct device *dev, s32 value);
+void dev_pm_qos_hide_flags(struct device *dev);
+int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set);
+
+static inline s32 dev_pm_qos_requested_latency(struct device *dev)
+{
+ return dev->power.qos->latency_req->data.pnode.prio;
+}
+
+static inline s32 dev_pm_qos_requested_flags(struct device *dev)
+{
+ return dev->power.qos->flags_req->data.flr.flags;
+}
#else
static inline int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value)
{ return 0; }
static inline void dev_pm_qos_hide_latency_limit(struct device *dev) {}
+static inline int dev_pm_qos_expose_flags(struct device *dev, s32 value)
+ { return 0; }
+static inline void dev_pm_qos_hide_flags(struct device *dev) {}
+static inline int dev_pm_qos_update_flags(struct device *dev, s32 m, bool set)
+ { return 0; }
+
+static inline s32 dev_pm_qos_requested_latency(struct device *dev) { return 0; }
+static inline s32 dev_pm_qos_requested_flags(struct device *dev) { return 0; }
#endif
#endif
diff --git a/include/linux/rculist.h b/include/linux/rculist.h
index e0f0fab2041..c92dd28eaa6 100644
--- a/include/linux/rculist.h
+++ b/include/linux/rculist.h
@@ -286,23 +286,6 @@ static inline void list_splice_init_rcu(struct list_head *list,
&pos->member != (head); \
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_continue_rcu
- * @pos: the &struct list_head to use as a loop cursor.
- * @head: the head for your list.
- *
- * Iterate over an rcu-protected list, continuing after current point.
- *
- * This list-traversal primitive may safely run concurrently with
- * the _rcu list-mutation primitives such as list_add_rcu()
- * as long as the traversal is guarded by rcu_read_lock().
- */
-#define list_for_each_continue_rcu(pos, head) \
- for ((pos) = rcu_dereference_raw(list_next_rcu(pos)); \
- (pos) != (head); \
- (pos) = rcu_dereference_raw(list_next_rcu(pos)))
-
/**
* list_for_each_entry_continue_rcu - continue iteration over list of given type
* @pos: the type * to use as a loop cursor.
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 7c968e4f929..275aa3f1062 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -90,6 +90,25 @@ extern void do_trace_rcu_torture_read(char *rcutorturename,
* that started after call_rcu() was invoked. RCU read-side critical
* sections are delimited by rcu_read_lock() and rcu_read_unlock(),
* and may be nested.
+ *
+ * Note that all CPUs must agree that the grace period extended beyond
+ * all pre-existing RCU read-side critical section. On systems with more
+ * than one CPU, this means that when "func()" is invoked, each CPU is
+ * guaranteed to have executed a full memory barrier since the end of its
+ * last RCU read-side critical section whose beginning preceded the call
+ * to call_rcu(). It also means that each CPU executing an RCU read-side
+ * critical section that continues beyond the start of "func()" must have
+ * executed a memory barrier after the call_rcu() but 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 call_rcu() and CPU B invoked the
+ * resulting RCU callback function "func()", then both CPU A and CPU B are
+ * guaranteed to execute a full memory barrier during the time interval
+ * between the call to call_rcu() and the invocation of "func()" -- even
+ * if CPU A and CPU B are the same CPU (but again only if the system has
+ * more than one CPU).
*/
extern void call_rcu(struct rcu_head *head,
void (*func)(struct rcu_head *head));
@@ -118,6 +137,9 @@ extern void call_rcu(struct rcu_head *head,
* OR
* - rcu_read_lock_bh() and rcu_read_unlock_bh(), if in process context.
* These may be nested.
+ *
+ * See the description of call_rcu() for more detailed information on
+ * memory ordering guarantees.
*/
extern void call_rcu_bh(struct rcu_head *head,
void (*func)(struct rcu_head *head));
@@ -137,6 +159,9 @@ extern void call_rcu_bh(struct rcu_head *head,
* OR
* anything that disables preemption.
* These may be nested.
+ *
+ * See the description of call_rcu() for more detailed information on
+ * memory ordering guarantees.
*/
extern void call_rcu_sched(struct rcu_head *head,
void (*func)(struct rcu_head *rcu));
@@ -197,13 +222,13 @@ extern void rcu_user_enter(void);
extern void rcu_user_exit(void);
extern void rcu_user_enter_after_irq(void);
extern void rcu_user_exit_after_irq(void);
-extern void rcu_user_hooks_switch(struct task_struct *prev,
- struct task_struct *next);
#else
static inline void rcu_user_enter(void) { }
static inline void rcu_user_exit(void) { }
static inline void rcu_user_enter_after_irq(void) { }
static inline void rcu_user_exit_after_irq(void) { }
+static inline void rcu_user_hooks_switch(struct task_struct *prev,
+ struct task_struct *next) { }
#endif /* CONFIG_RCU_USER_QS */
extern void exit_rcu(void);
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index 6c8835f74f7..519777e3fa0 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -159,13 +159,14 @@ int ring_buffer_record_is_on(struct ring_buffer *buffer);
void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu);
void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu);
-unsigned long ring_buffer_oldest_event_ts(struct ring_buffer *buffer, int cpu);
+u64 ring_buffer_oldest_event_ts(struct ring_buffer *buffer, int cpu);
unsigned long ring_buffer_bytes_cpu(struct ring_buffer *buffer, int cpu);
unsigned long ring_buffer_entries(struct ring_buffer *buffer);
unsigned long ring_buffer_overruns(struct ring_buffer *buffer);
unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu);
unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu);
unsigned long ring_buffer_commit_overrun_cpu(struct ring_buffer *buffer, int cpu);
+unsigned long ring_buffer_dropped_events_cpu(struct ring_buffer *buffer, int cpu);
u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu);
void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer,
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 4187da51100..a3e78427866 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -275,9 +275,11 @@ struct rio_id_table {
* struct rio_net - RIO network info
* @node: Node in global list of RIO networks
* @devices: List of devices in this network
+ * @switches: List of switches in this netowrk
* @mports: List of master ports accessing this network
* @hport: Default port for accessing this network
* @id: RIO network ID
+ * @destid_table: destID allocation table
*/
struct rio_net {
struct list_head node; /* node in list of networks */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 0dd42a02df2..b96ff1e43ad 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -109,6 +109,8 @@ extern void update_cpu_load_nohz(void);
extern unsigned long get_parent_ip(unsigned long addr);
+extern void dump_cpu_task(int cpu);
+
struct seq_file;
struct cfs_rq;
struct task_group;
@@ -434,13 +436,28 @@ struct cpu_itimer {
};
/**
+ * struct cputime - snaphsot of system and user cputime
+ * @utime: time spent in user mode
+ * @stime: time spent in system mode
+ *
+ * Gathers a generic snapshot of user and system time.
+ */
+struct cputime {
+ cputime_t utime;
+ cputime_t stime;
+};
+
+/**
* struct task_cputime - collected CPU time counts
* @utime: time spent in user mode, in &cputime_t units
* @stime: time spent in kernel mode, in &cputime_t units
* @sum_exec_runtime: total time spent on the CPU, in nanoseconds
*
- * This structure groups together three kinds of CPU time that are
- * tracked for threads and thread groups. Most things considering
+ * This is an extension of struct cputime that includes the total runtime
+ * spent by the task from the scheduler point of view.
+ *
+ * As a result, this structure groups together three kinds of CPU time
+ * that are tracked for threads and thread groups. Most things considering
* CPU time want to group these counts together and treat all three
* of them in parallel.
*/
@@ -581,7 +598,7 @@ struct signal_struct {
cputime_t gtime;
cputime_t cgtime;
#ifndef CONFIG_VIRT_CPU_ACCOUNTING
- cputime_t prev_utime, prev_stime;
+ struct cputime prev_cputime;
#endif
unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt;
@@ -631,9 +648,10 @@ struct signal_struct {
struct rw_semaphore group_rwsem;
#endif
- int oom_score_adj; /* OOM kill score adjustment */
- int oom_score_adj_min; /* OOM kill score adjustment minimum value.
- * Only settable by CAP_SYS_RESOURCE. */
+ oom_flags_t oom_flags;
+ short oom_score_adj; /* OOM kill score adjustment */
+ short oom_score_adj_min; /* OOM kill score adjustment min value.
+ * Only settable by CAP_SYS_RESOURCE. */
struct mutex cred_guard_mutex; /* guard against foreign influences on
* credential calculations
@@ -1061,6 +1079,7 @@ struct sched_class {
#ifdef CONFIG_SMP
int (*select_task_rq)(struct task_struct *p, int sd_flag, int flags);
+ void (*migrate_task_rq)(struct task_struct *p, int next_cpu);
void (*pre_schedule) (struct rq *this_rq, struct task_struct *task);
void (*post_schedule) (struct rq *this_rq);
@@ -1095,6 +1114,18 @@ struct load_weight {
unsigned long weight, inv_weight;
};
+struct sched_avg {
+ /*
+ * These sums represent an infinite geometric series and so are bound
+ * above by 1024/(1-y). Thus we only need a u32 to store them for for all
+ * choices of y < 1-2^(-32)*1024.
+ */
+ u32 runnable_avg_sum, runnable_avg_period;
+ u64 last_runnable_update;
+ s64 decay_count;
+ unsigned long load_avg_contrib;
+};
+
#ifdef CONFIG_SCHEDSTATS
struct sched_statistics {
u64 wait_start;
@@ -1155,6 +1186,15 @@ struct sched_entity {
/* rq "owned" by this entity/group: */
struct cfs_rq *my_q;
#endif
+/*
+ * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be
+ * removed when useful for applications beyond shares distribution (e.g.
+ * load-balance).
+ */
+#if defined(CONFIG_SMP) && defined(CONFIG_FAIR_GROUP_SCHED)
+ /* Per-entity load-tracking */
+ struct sched_avg avg;
+#endif
};
struct sched_rt_entity {
@@ -1318,7 +1358,7 @@ struct task_struct {
cputime_t utime, stime, utimescaled, stimescaled;
cputime_t gtime;
#ifndef CONFIG_VIRT_CPU_ACCOUNTING
- cputime_t prev_utime, prev_stime;
+ struct cputime prev_cputime;
#endif
unsigned long nvcsw, nivcsw; /* context switch counts */
struct timespec start_time; /* monotonic time */
@@ -1729,8 +1769,8 @@ static inline void put_task_struct(struct task_struct *t)
__put_task_struct(t);
}
-extern void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st);
-extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st);
+extern void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st);
+extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st);
/*
* Per process flags
@@ -1844,14 +1884,6 @@ static inline void rcu_copy_process(struct task_struct *p)
#endif
-static inline void rcu_switch(struct task_struct *prev,
- struct task_struct *next)
-{
-#ifdef CONFIG_RCU_USER_QS
- rcu_user_hooks_switch(prev, next);
-#endif
-}
-
static inline void tsk_restore_flags(struct task_struct *task,
unsigned long orig_flags, unsigned long flags)
{
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index c174c90fb3f..c490d20b3fb 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -105,6 +105,8 @@ extern int early_serial_setup(struct uart_port *port);
extern int serial8250_find_port(struct uart_port *p);
extern int serial8250_find_port_for_earlycon(void);
+extern unsigned int serial8250_early_in(struct uart_port *port, int offset);
+extern void serial8250_early_out(struct uart_port *port, int offset, int value);
extern int setup_early_serial8250_console(char *cmdline);
extern void serial8250_do_set_termios(struct uart_port *port,
struct ktermios *termios, struct ktermios *old);
diff --git a/include/linux/shm.h b/include/linux/shm.h
index bcf8a6a3ec0..429c1995d75 100644
--- a/include/linux/shm.h
+++ b/include/linux/shm.h
@@ -29,6 +29,21 @@ struct shmid_kernel /* private to the kernel */
#define SHM_HUGETLB 04000 /* segment will use huge TLB pages */
#define SHM_NORESERVE 010000 /* don't check for reservations */
+/* Bits [26:31] are reserved */
+
+/*
+ * When SHM_HUGETLB is set bits [26:31] encode the log2 of the huge page size.
+ * This gives us 6 bits, which is enough until someone invents 128 bit address
+ * spaces.
+ *
+ * Assume these are all power of twos.
+ * When 0 use the default page size.
+ */
+#define SHM_HUGE_SHIFT 26
+#define SHM_HUGE_MASK 0x3f
+#define SHM_HUGE_2MB (21 << SHM_HUGE_SHIFT)
+#define SHM_HUGE_1GB (30 << SHM_HUGE_SHIFT)
+
#ifdef CONFIG_SYSVIPC
long do_shmat(int shmid, char __user *shmaddr, int shmflg, unsigned long *addr,
unsigned long shmlba);
diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h
index c64de9dd763..2f694f3846a 100644
--- a/include/linux/spi/ads7846.h
+++ b/include/linux/spi/ads7846.h
@@ -46,8 +46,9 @@ struct ads7846_platform_data {
u16 debounce_rep; /* additional consecutive good readings
* required after the first two */
int gpio_pendown; /* the GPIO used to decide the pendown
- * state if get_pendown_state == NULL
- */
+ * state if get_pendown_state == NULL */
+ int gpio_pendown_debounce; /* platform specific debounce time for
+ * the gpio_pendown */
int (*get_pendown_state)(void);
int (*filter_init) (const struct ads7846_platform_data *pdata,
void **filter_data);
diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index 55a5c52cbb2..6eb691b0835 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -16,8 +16,10 @@
* 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
@@ -40,6 +42,8 @@ struct rcu_batch {
struct rcu_head *head, **tail;
};
+#define RCU_BATCH_INIT(name) { NULL, &(name.head) }
+
struct srcu_struct {
unsigned completed;
struct srcu_struct_array __percpu *per_cpu_ref;
@@ -70,12 +74,42 @@ int __init_srcu_struct(struct srcu_struct *sp, const char *name,
__init_srcu_struct((sp), #sp, &__srcu_key); \
})
+#define __SRCU_DEP_MAP_INIT(srcu_name) .dep_map = { .name = #srcu_name },
#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
int init_srcu_struct(struct srcu_struct *sp);
+#define __SRCU_DEP_MAP_INIT(srcu_name)
#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+void process_srcu(struct work_struct *work);
+
+#define __SRCU_STRUCT_INIT(name) \
+ { \
+ .completed = -300, \
+ .per_cpu_ref = &name##_srcu_array, \
+ .queue_lock = __SPIN_LOCK_UNLOCKED(name.queue_lock), \
+ .running = false, \
+ .batch_queue = RCU_BATCH_INIT(name.batch_queue), \
+ .batch_check0 = RCU_BATCH_INIT(name.batch_check0), \
+ .batch_check1 = RCU_BATCH_INIT(name.batch_check1), \
+ .batch_done = RCU_BATCH_INIT(name.batch_done), \
+ .work = __DELAYED_WORK_INITIALIZER(name.work, process_srcu, 0),\
+ __SRCU_DEP_MAP_INIT(name) \
+ }
+
+/*
+ * define and init a srcu struct at build time.
+ * dont't call init_srcu_struct() nor cleanup_srcu_struct() on it.
+ */
+#define DEFINE_SRCU(name) \
+ static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\
+ struct srcu_struct name = __SRCU_STRUCT_INIT(name);
+
+#define DEFINE_STATIC_SRCU(name) \
+ static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\
+ static struct srcu_struct name = __SRCU_STRUCT_INIT(name);
+
/**
* call_srcu() - Queue a callback for invocation after an SRCU grace period
* @sp: srcu_struct in queue the callback
diff --git a/include/linux/tick.h b/include/linux/tick.h
index f37fceb69b7..1a6567b4849 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -142,4 +142,10 @@ static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; }
static inline u64 get_cpu_iowait_time_us(int cpu, u64 *unused) { return -1; }
# endif /* !NO_HZ */
+# ifdef CONFIG_CPU_IDLE_GOV_MENU
+extern void menu_hrtimer_cancel(void);
+# else
+static inline void menu_hrtimer_cancel(void) {}
+# endif /* CONFIG_CPU_IDLE_GOV_MENU */
+
#endif
diff --git a/include/linux/trace_clock.h b/include/linux/trace_clock.h
index 4eb490237d4..d563f37e1a1 100644
--- a/include/linux/trace_clock.h
+++ b/include/linux/trace_clock.h
@@ -12,6 +12,8 @@
#include <linux/compiler.h>
#include <linux/types.h>
+#include <asm/trace_clock.h>
+
extern u64 notrace trace_clock_local(void);
extern u64 notrace trace_clock(void);
extern u64 notrace trace_clock_global(void);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index f0b4eb47297..8db1b569c37 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -188,7 +188,9 @@ struct tty_port_operations {
};
struct tty_port {
+ struct tty_bufhead buf; /* Locked internally */
struct tty_struct *tty; /* Back pointer */
+ struct tty_struct *itty; /* internal back ptr */
const struct tty_port_operations *ops; /* Port operations */
spinlock_t lock; /* Lock protecting tty field */
int blocked_open; /* Waiting to open */
@@ -197,6 +199,9 @@ struct tty_port {
wait_queue_head_t close_wait; /* Close waiters */
wait_queue_head_t delta_msr_wait; /* Modem status change */
unsigned long flags; /* TTY flags ASY_*/
+ unsigned long iflags; /* TTYP_ internal flags */
+#define TTYP_FLUSHING 1 /* Flushing to ldisc in progress */
+#define TTYP_FLUSHPENDING 2 /* Queued buffer flush pending */
unsigned char console:1; /* port is a console */
struct mutex mutex; /* Locking */
struct mutex buf_mutex; /* Buffer alloc lock */
@@ -235,6 +240,7 @@ struct tty_struct {
struct mutex ldisc_mutex;
struct tty_ldisc *ldisc;
+ struct mutex atomic_write_lock;
struct mutex legacy_mutex;
struct mutex termios_mutex;
spinlock_t ctrl_lock;
@@ -254,7 +260,6 @@ struct tty_struct {
struct tty_struct *link;
struct fasync_struct *fasync;
- struct tty_bufhead buf; /* Locked internally */
int alt_speed; /* For magic substitution of 38400 bps */
wait_queue_head_t write_wait;
wait_queue_head_t read_wait;
@@ -265,37 +270,10 @@ struct tty_struct {
#define N_TTY_BUF_SIZE 4096
- /*
- * The following is data for the N_TTY line discipline. For
- * historical reasons, this is included in the tty structure.
- * Mostly locked by the BKL.
- */
- unsigned int column;
- unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1;
unsigned char closing:1;
- unsigned char echo_overrun:1;
unsigned short minimum_to_wake;
- unsigned long overrun_time;
- int num_overrun;
- unsigned long process_char_map[256/(8*sizeof(unsigned long))];
- char *read_buf;
- int read_head;
- int read_tail;
- int read_cnt;
- unsigned long read_flags[N_TTY_BUF_SIZE/(8*sizeof(unsigned long))];
- unsigned char *echo_buf;
- unsigned int echo_pos;
- unsigned int echo_cnt;
- int canon_data;
- unsigned long canon_head;
- unsigned int canon_column;
- struct mutex atomic_read_lock;
- struct mutex atomic_write_lock;
- struct mutex output_lock;
- struct mutex echo_lock;
unsigned char *write_buf;
int write_cnt;
- spinlock_t read_lock;
/* If the tty has a pending do_SAK, queue it here - akpm */
struct work_struct SAK_work;
struct tty_port *port;
@@ -335,8 +313,6 @@ struct tty_file_private {
#define TTY_PTY_LOCK 16 /* pty private */
#define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */
#define TTY_HUPPED 18 /* Post driver->hangup() */
-#define TTY_FLUSHING 19 /* Flushing to ldisc in progress */
-#define TTY_FLUSHPENDING 20 /* Queued buffer flush pending */
#define TTY_HUPPING 21 /* ->hangup() in progress */
#define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
@@ -412,9 +388,9 @@ extern void disassociate_ctty(int priv);
extern void no_tty(void);
extern void tty_flip_buffer_push(struct tty_struct *tty);
extern void tty_flush_to_ldisc(struct tty_struct *tty);
-extern void tty_buffer_free_all(struct tty_struct *tty);
+extern void tty_buffer_free_all(struct tty_port *port);
extern void tty_buffer_flush(struct tty_struct *tty);
-extern void tty_buffer_init(struct tty_struct *tty);
+extern void tty_buffer_init(struct tty_port *port);
extern speed_t tty_get_baud_rate(struct tty_struct *tty);
extern speed_t tty_termios_baud_rate(struct ktermios *termios);
extern speed_t tty_termios_input_baud_rate(struct ktermios *termios);
@@ -479,6 +455,7 @@ extern struct device *tty_port_register_device_attr(struct tty_port *port,
const struct attribute_group **attr_grp);
extern int tty_port_alloc_xmit_buf(struct tty_port *port);
extern void tty_port_free_xmit_buf(struct tty_port *port);
+extern void tty_port_destroy(struct tty_port *port);
extern void tty_port_put(struct tty_port *port);
static inline struct tty_port *tty_port_get(struct tty_port *port)
@@ -535,7 +512,7 @@ extern void n_tty_inherit_ops(struct tty_ldisc_ops *ops);
/* tty_audit.c */
#ifdef CONFIG_AUDIT
extern void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
- size_t size);
+ size_t size, unsigned icanon);
extern void tty_audit_exit(void);
extern void tty_audit_fork(struct signal_struct *sig);
extern void tty_audit_tiocsti(struct tty_struct *tty, char ch);
@@ -544,7 +521,7 @@ extern int tty_audit_push_task(struct task_struct *tsk,
kuid_t loginuid, u32 sessionid);
#else
static inline void tty_audit_add_data(struct tty_struct *tty,
- unsigned char *data, size_t size)
+ unsigned char *data, size_t size, unsigned icanon)
{
}
static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch)
diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h
index 9239d033a0a..2002344ed36 100644
--- a/include/linux/tty_flip.h
+++ b/include/linux/tty_flip.h
@@ -11,7 +11,7 @@ void tty_schedule_flip(struct tty_struct *tty);
static inline int tty_insert_flip_char(struct tty_struct *tty,
unsigned char ch, char flag)
{
- struct tty_buffer *tb = tty->buf.tail;
+ struct tty_buffer *tb = tty->port->buf.tail;
if (tb && tb->used < tb->size) {
tb->flag_buf_ptr[tb->used] = flag;
tb->char_buf_ptr[tb->used++] = ch;
diff --git a/include/linux/types.h b/include/linux/types.h
index 1cc0e4b9a04..4d118ba1134 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -156,6 +156,7 @@ typedef u32 dma_addr_t;
#endif
typedef unsigned __bitwise__ gfp_t;
typedef unsigned __bitwise__ fmode_t;
+typedef unsigned __bitwise__ oom_flags_t;
#ifdef CONFIG_PHYS_ADDR_T_64BIT
typedef u64 phys_addr_t;
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
index 24594571c5a..4f628a6fc5b 100644
--- a/include/linux/uprobes.h
+++ b/include/linux/uprobes.h
@@ -97,12 +97,12 @@ extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_con
extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
extern int uprobe_mmap(struct vm_area_struct *vma);
extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end);
+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 unsigned long __weak uprobe_get_swbp_addr(struct pt_regs *regs);
-extern void __weak arch_uprobe_enable_step(struct arch_uprobe *arch);
-extern void __weak arch_uprobe_disable_step(struct arch_uprobe *arch);
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);
@@ -129,6 +129,12 @@ static inline void
uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end)
{
}
+static inline void uprobe_start_dup_mmap(void)
+{
+}
+static inline void uprobe_end_dup_mmap(void)
+{
+}
static inline void
uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm)
{
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 10278d18709..689b14b26c8 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -482,6 +482,7 @@ struct usb3_lpm_parameters {
* @connect_time: time device was first connected
* @do_remote_wakeup: remote wakeup should be enabled
* @reset_resume: needs reset instead of resume
+ * @port_is_suspended: the upstream port is suspended (L2 or U3)
* @wusb_dev: if this is a Wireless USB device, link to the WUSB
* specific data for the device.
* @slot_id: Slot ID assigned by xHCI
@@ -560,6 +561,7 @@ struct usb_device {
unsigned do_remote_wakeup:1;
unsigned reset_resume:1;
+ unsigned port_is_suspended:1;
#endif
struct wusb_dev *wusb_dev;
int slot_id;
@@ -588,8 +590,9 @@ extern struct usb_device *usb_hub_find_child(struct usb_device *hdev,
*/
#define usb_hub_for_each_child(hdev, port1, child) \
for (port1 = 1, child = usb_hub_find_child(hdev, port1); \
- port1 <= hdev->maxchild; \
- child = usb_hub_find_child(hdev, ++port1))
+ port1 <= hdev->maxchild; \
+ child = usb_hub_find_child(hdev, ++port1)) \
+ if (!child) continue; else
/* USB device locking */
#define usb_lock_device(udev) device_lock(&(udev)->dev)
@@ -805,6 +808,22 @@ static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size)
.bcdDevice_hi = (hi)
/**
+ * USB_DEVICE_INTERFACE_CLASS - describe a usb device with a specific interface class
+ * @vend: the 16 bit USB Vendor ID
+ * @prod: the 16 bit USB Product ID
+ * @cl: bInterfaceClass value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific interface class of devices.
+ */
+#define USB_DEVICE_INTERFACE_CLASS(vend, prod, cl) \
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
+ USB_DEVICE_ID_MATCH_INT_CLASS, \
+ .idVendor = (vend), \
+ .idProduct = (prod), \
+ .bInterfaceClass = (cl)
+
+/**
* USB_DEVICE_INTERFACE_PROTOCOL - describe a usb device with a specific interface protocol
* @vend: the 16 bit USB Vendor ID
* @prod: the 16 bit USB Product ID
@@ -1129,8 +1148,8 @@ extern int usb_disabled(void);
* Note: URB_DIR_IN/OUT is automatically set in usb_submit_urb().
*/
#define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */
-#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame
- * ignored */
+#define URB_ISO_ASAP 0x0002 /* iso-only; use the first unexpired
+ * slot in the schedule */
#define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */
#define URB_NO_FSBR 0x0020 /* UHCI-specific */
#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUT with short packet */
@@ -1309,15 +1328,20 @@ typedef void (*usb_complete_t)(struct urb *);
* the transfer interval in the endpoint descriptor is logarithmic.
* Device drivers must convert that value to linear units themselves.)
*
- * Isochronous URBs normally use the URB_ISO_ASAP transfer flag, telling
- * the host controller to schedule the transfer as soon as bandwidth
- * utilization allows, and then set start_frame to reflect the actual frame
- * selected during submission. Otherwise drivers must specify the start_frame
- * and handle the case where the transfer can't begin then. However, drivers
- * won't know how bandwidth is currently allocated, and while they can
- * find the current frame using usb_get_current_frame_number () they can't
- * know the range for that frame number. (Ranges for frame counter values
- * are HC-specific, and can go from 256 to 65536 frames from "now".)
+ * If an isochronous endpoint queue isn't already running, the host
+ * controller will schedule a new URB to start as soon as bandwidth
+ * utilization allows. If the queue is running then a new URB will be
+ * scheduled to start in the first transfer slot following the end of the
+ * preceding URB, if that slot has not already expired. If the slot has
+ * expired (which can happen when IRQ delivery is delayed for a long time),
+ * the scheduling behavior depends on the URB_ISO_ASAP flag. If the flag
+ * is clear then the URB will be scheduled to start in the expired slot,
+ * implying that some of its packets will not be transferred; if the flag
+ * is set then the URB will be scheduled in the first unexpired slot,
+ * breaking the queue's synchronization. Upon URB completion, the
+ * start_frame field will be set to the (micro)frame number in which the
+ * transfer was scheduled. Ranges for frame counter values are HC-specific
+ * and can go from as low as 256 to as high as 65536 frames.
*
* Isochronous URBs have a different data transfer model, in part because
* the quality of service is only "best effort". Callers provide specially
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index f8dda062180..b09c37e04a9 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -38,6 +38,7 @@
#include <linux/version.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
+#include <linux/log2.h>
/*
* USB function drivers should return USB_GADGET_DELAYED_STATUS if they
@@ -51,6 +52,7 @@
/* big enough to hold our biggest descriptor */
#define USB_COMP_EP0_BUFSIZ 1024
+#define USB_MS_TO_HS_INTERVAL(x) (ilog2((x * 1000 / 125)) + 1)
struct usb_configuration;
/**
@@ -117,7 +119,7 @@ struct usb_configuration;
struct usb_function {
const char *name;
struct usb_gadget_strings **strings;
- struct usb_descriptor_header **descriptors;
+ struct usb_descriptor_header **fs_descriptors;
struct usb_descriptor_header **hs_descriptors;
struct usb_descriptor_header **ss_descriptors;
diff --git a/include/linux/usb/ehci_pdriver.h b/include/linux/usb/ehci_pdriver.h
index c9d09f8b7ff..99238b096f7 100644
--- a/include/linux/usb/ehci_pdriver.h
+++ b/include/linux/usb/ehci_pdriver.h
@@ -29,6 +29,8 @@
* initialization.
* @port_power_off: set to 1 if the controller needs to be powered down
* after initialization.
+ * @no_io_watchdog: set to 1 if the controller does not need the I/O
+ * watchdog to run.
*
* These are general configuration options for the EHCI controller. All of
* these options are activating more or less workarounds for some hardware.
@@ -39,8 +41,7 @@ struct usb_ehci_pdata {
unsigned has_synopsys_hc_bug:1;
unsigned big_endian_desc:1;
unsigned big_endian_mmio:1;
- unsigned port_power_on:1;
- unsigned port_power_off:1;
+ unsigned no_io_watchdog:1;
/* Turn on all power and clocks */
int (*power_on)(struct platform_device *pdev);
diff --git a/include/linux/usb/ezusb.h b/include/linux/usb/ezusb.h
index fc618d8d1e9..639ee45779f 100644
--- a/include/linux/usb/ezusb.h
+++ b/include/linux/usb/ezusb.h
@@ -1,16 +1,8 @@
#ifndef __EZUSB_H
#define __EZUSB_H
-
-extern int ezusb_writememory(struct usb_device *dev, int address,
- unsigned char *data, int length, __u8 bRequest);
-
extern int ezusb_fx1_set_reset(struct usb_device *dev, unsigned char reset_bit);
-extern int ezusb_fx2_set_reset(struct usb_device *dev, unsigned char reset_bit);
-
extern int ezusb_fx1_ihex_firmware_download(struct usb_device *dev,
const char *firmware_path);
-extern int ezusb_fx2_ihex_firmware_download(struct usb_device *dev,
- const char *firmware_path);
#endif /* __EZUSB_H */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 5b6e5088824..0af6569b8cc 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -939,6 +939,13 @@ static inline void usb_free_descriptors(struct usb_descriptor_header **v)
kfree(v);
}
+struct usb_function;
+int usb_assign_descriptors(struct usb_function *f,
+ struct usb_descriptor_header **fs,
+ struct usb_descriptor_header **hs,
+ struct usb_descriptor_header **ss);
+void usb_free_all_descriptors(struct usb_function *f);
+
/*-------------------------------------------------------------------------*/
/* utility to simplify map/unmap of usb_requests to/from DMA */
diff --git a/include/linux/usb/ohci_pdriver.h b/include/linux/usb/ohci_pdriver.h
index 74e7755168b..012f2b7eb2b 100644
--- a/include/linux/usb/ohci_pdriver.h
+++ b/include/linux/usb/ohci_pdriver.h
@@ -25,6 +25,7 @@
* @big_endian_desc: BE descriptors
* @big_endian_mmio: BE registers
* @no_big_frame_no: no big endian frame_no shift
+ * @num_ports: number of ports
*
* These are general configuration options for the OHCI controller. All of
* these options are activating more or less workarounds for some hardware.
@@ -33,6 +34,7 @@ struct usb_ohci_pdata {
unsigned big_endian_desc:1;
unsigned big_endian_mmio:1;
unsigned no_big_frame_no:1;
+ unsigned int num_ports;
/* Turn on all power and clocks */
int (*power_on)(struct platform_device *pdev);
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h
index 06b5bae35b2..a29ae1eb934 100644
--- a/include/linux/usb/phy.h
+++ b/include/linux/usb/phy.h
@@ -10,6 +10,7 @@
#define __LINUX_USB_PHY_H
#include <linux/notifier.h>
+#include <linux/usb.h>
enum usb_phy_events {
USB_EVENT_NONE, /* no events or cable disconnected */
@@ -99,8 +100,10 @@ struct usb_phy {
int suspend);
/* notify phy connect status change */
- int (*notify_connect)(struct usb_phy *x, int port);
- int (*notify_disconnect)(struct usb_phy *x, int port);
+ int (*notify_connect)(struct usb_phy *x,
+ enum usb_device_speed speed);
+ int (*notify_disconnect)(struct usb_phy *x,
+ enum usb_device_speed speed);
};
@@ -189,19 +192,19 @@ usb_phy_set_suspend(struct usb_phy *x, int suspend)
}
static inline int
-usb_phy_notify_connect(struct usb_phy *x, int port)
+usb_phy_notify_connect(struct usb_phy *x, enum usb_device_speed speed)
{
if (x->notify_connect)
- return x->notify_connect(x, port);
+ return x->notify_connect(x, speed);
else
return 0;
}
static inline int
-usb_phy_notify_disconnect(struct usb_phy *x, int port)
+usb_phy_notify_disconnect(struct usb_phy *x, enum usb_device_speed speed)
{
if (x->notify_disconnect)
- return x->notify_disconnect(x, port);
+ return x->notify_disconnect(x, speed);
else
return 0;
}
diff --git a/include/linux/vtime.h b/include/linux/vtime.h
new file mode 100644
index 00000000000..ae30ab58431
--- /dev/null
+++ b/include/linux/vtime.h
@@ -0,0 +1,48 @@
+#ifndef _LINUX_KERNEL_VTIME_H
+#define _LINUX_KERNEL_VTIME_H
+
+struct task_struct;
+
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+extern void vtime_task_switch(struct task_struct *prev);
+extern void vtime_account_system(struct task_struct *tsk);
+extern void vtime_account_system_irqsafe(struct task_struct *tsk);
+extern void vtime_account_idle(struct task_struct *tsk);
+extern void vtime_account_user(struct task_struct *tsk);
+extern void vtime_account(struct task_struct *tsk);
+#else
+static inline void vtime_task_switch(struct task_struct *prev) { }
+static inline void vtime_account_system(struct task_struct *tsk) { }
+static inline void vtime_account_system_irqsafe(struct task_struct *tsk) { }
+static inline void vtime_account(struct task_struct *tsk) { }
+#endif
+
+#ifdef CONFIG_IRQ_TIME_ACCOUNTING
+extern void irqtime_account_irq(struct task_struct *tsk);
+#else
+static inline void irqtime_account_irq(struct task_struct *tsk) { }
+#endif
+
+static inline void vtime_account_irq_enter(struct task_struct *tsk)
+{
+ /*
+ * Hardirq can interrupt idle task anytime. So we need vtime_account()
+ * that performs the idle check in CONFIG_VIRT_CPU_ACCOUNTING.
+ * Softirq can also interrupt idle task directly if it calls
+ * local_bh_enable(). Such case probably don't exist but we never know.
+ * Ksoftirqd is not concerned because idle time is flushed on context
+ * switch. Softirqs in the end of hardirqs are also not a problem because
+ * the idle time is flushed on hardirq time already.
+ */
+ vtime_account(tsk);
+ irqtime_account_irq(tsk);
+}
+
+static inline void vtime_account_irq_exit(struct task_struct *tsk)
+{
+ /* On hard|softirq exit we always account to hard|softirq cputime */
+ vtime_account_system(tsk);
+ irqtime_account_irq(tsk);
+}
+
+#endif /* _LINUX_KERNEL_VTIME_H */
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 50c3e8fa06a..b82a83aba31 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -161,14 +161,7 @@ void __bdi_update_bandwidth(struct backing_dev_info *bdi,
unsigned long start_time);
void page_writeback_init(void);
-void balance_dirty_pages_ratelimited_nr(struct address_space *mapping,
- unsigned long nr_pages_dirtied);
-
-static inline void
-balance_dirty_pages_ratelimited(struct address_space *mapping)
-{
- balance_dirty_pages_ratelimited_nr(mapping, 1);
-}
+void balance_dirty_pages_ratelimited(struct address_space *mapping);
typedef int (*writepage_t)(struct page *page, struct writeback_control *wbc,
void *data);
diff --git a/include/media/adv7604.h b/include/media/adv7604.h
index 171b957db74..dc004bc926c 100644
--- a/include/media/adv7604.h
+++ b/include/media/adv7604.h
@@ -40,14 +40,6 @@ enum adv7604_op_ch_sel {
ADV7604_OP_CH_SEL_RBG = 5,
};
-/* Primary mode (IO register 0x01, [3:0]) */
-enum adv7604_prim_mode {
- ADV7604_PRIM_MODE_COMP = 1,
- ADV7604_PRIM_MODE_RGB = 2,
- ADV7604_PRIM_MODE_HDMI_COMP = 5,
- ADV7604_PRIM_MODE_HDMI_GR = 6,
-};
-
/* Input Color Space (IO register 0x02, [7:4]) */
enum adv7604_inp_color_space {
ADV7604_INP_COLOR_SPACE_LIM_RGB = 0,
@@ -103,9 +95,6 @@ struct adv7604_platform_data {
/* Bus rotation and reordering */
enum adv7604_op_ch_sel op_ch_sel;
- /* Primary mode */
- enum adv7604_prim_mode prim_mode;
-
/* Select output format */
enum adv7604_op_format_sel op_format_sel;
@@ -142,6 +131,16 @@ struct adv7604_platform_data {
u8 i2c_vdp;
};
+/*
+ * Mode of operation.
+ * This is used as the input argument of the s_routing video op.
+ */
+enum adv7604_mode {
+ ADV7604_MODE_COMP,
+ ADV7604_MODE_GR,
+ ADV7604_MODE_HDMI,
+};
+
#define V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE (V4L2_CID_DV_CLASS_BASE + 0x1000)
#define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL (V4L2_CID_DV_CLASS_BASE + 0x1001)
#define V4L2_CID_ADV_RX_FREE_RUN_COLOR (V4L2_CID_DV_CLASS_BASE + 0x1002)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 6feeccd83dd..4af45e33105 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -525,6 +525,7 @@ static inline __u32 cookie_v6_init_sequence(struct sock *sk,
extern void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss,
int nonagle);
extern bool tcp_may_send_now(struct sock *sk);
+extern int __tcp_retransmit_skb(struct sock *, struct sk_buff *);
extern int tcp_retransmit_skb(struct sock *, struct sk_buff *);
extern void tcp_retransmit_timer(struct sock *sk);
extern void tcp_xmit_retransmit_queue(struct sock *);
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 6f0ba01afe7..63445ede48b 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1351,7 +1351,7 @@ struct xfrm6_tunnel {
};
extern void xfrm_init(void);
-extern void xfrm4_init(int rt_hash_size);
+extern void xfrm4_init(void);
extern int xfrm_state_init(struct net *net);
extern void xfrm_state_fini(struct net *net);
extern void xfrm4_state_init(void);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 88fae8d2015..55367b04dc9 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -135,6 +135,8 @@ struct scsi_device {
* because we did a bus reset. */
unsigned use_10_for_rw:1; /* first try 10-byte read / write */
unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */
+ unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */
+ unsigned no_write_same:1; /* no WRITE SAME command */
unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */
unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */
unsigned skip_vpd_pages:1; /* do not read VPD pages */
@@ -362,6 +364,8 @@ extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout,
int retries, struct scsi_sense_hdr *sshdr);
extern int scsi_get_vpd_page(struct scsi_device *, u8 page, unsigned char *buf,
int buf_len);
+extern int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer,
+ unsigned int len, unsigned char opcode);
extern int scsi_device_set_state(struct scsi_device *sdev,
enum scsi_device_state state);
extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type,
diff --git a/include/trace/events/gfpflags.h b/include/trace/events/gfpflags.h
index 9391706e925..d6fd8e5b14b 100644
--- a/include/trace/events/gfpflags.h
+++ b/include/trace/events/gfpflags.h
@@ -36,6 +36,7 @@
{(unsigned long)__GFP_RECLAIMABLE, "GFP_RECLAIMABLE"}, \
{(unsigned long)__GFP_MOVABLE, "GFP_MOVABLE"}, \
{(unsigned long)__GFP_NOTRACK, "GFP_NOTRACK"}, \
+ {(unsigned long)__GFP_NO_KSWAPD, "GFP_NO_KSWAPD"}, \
{(unsigned long)__GFP_OTHER_NODE, "GFP_OTHER_NODE"} \
) : "GFP_NOWAIT"
diff --git a/include/trace/events/oom.h b/include/trace/events/oom.h
index dd4ba3b9200..1e974983757 100644
--- a/include/trace/events/oom.h
+++ b/include/trace/events/oom.h
@@ -14,7 +14,7 @@ TRACE_EVENT(oom_score_adj_update,
TP_STRUCT__entry(
__field( pid_t, pid)
__array( char, comm, TASK_COMM_LEN )
- __field( int, oom_score_adj)
+ __field( short, oom_score_adj)
),
TP_fast_assign(
@@ -23,7 +23,7 @@ TRACE_EVENT(oom_score_adj_update,
__entry->oom_score_adj = task->signal->oom_score_adj;
),
- TP_printk("pid=%d comm=%s oom_score_adj=%d",
+ TP_printk("pid=%d comm=%s oom_score_adj=%hd",
__entry->pid, __entry->comm, __entry->oom_score_adj)
);
diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h
index 5bde94d8585..d4f559b1ec3 100644
--- a/include/trace/events/rcu.h
+++ b/include/trace/events/rcu.h
@@ -549,6 +549,7 @@ TRACE_EVENT(rcu_torture_read,
* "EarlyExit": rcu_barrier_callback() piggybacked, thus early exit.
* "Inc1": rcu_barrier_callback() piggyback check counter incremented.
* "Offline": rcu_barrier_callback() found offline CPU
+ * "OnlineNoCB": rcu_barrier_callback() found online no-CBs CPU.
* "OnlineQ": rcu_barrier_callback() found online CPU with callbacks.
* "OnlineNQ": rcu_barrier_callback() found online CPU, no callbacks.
* "IRQ": An rcu_barrier_callback() callback posted on remote CPU.
diff --git a/include/trace/events/task.h b/include/trace/events/task.h
index b53add02e92..102a646e199 100644
--- a/include/trace/events/task.h
+++ b/include/trace/events/task.h
@@ -15,7 +15,7 @@ TRACE_EVENT(task_newtask,
__field( pid_t, pid)
__array( char, comm, TASK_COMM_LEN)
__field( unsigned long, clone_flags)
- __field( int, oom_score_adj)
+ __field( short, oom_score_adj)
),
TP_fast_assign(
@@ -25,7 +25,7 @@ TRACE_EVENT(task_newtask,
__entry->oom_score_adj = task->signal->oom_score_adj;
),
- TP_printk("pid=%d comm=%s clone_flags=%lx oom_score_adj=%d",
+ TP_printk("pid=%d comm=%s clone_flags=%lx oom_score_adj=%hd",
__entry->pid, __entry->comm,
__entry->clone_flags, __entry->oom_score_adj)
);
@@ -40,7 +40,7 @@ TRACE_EVENT(task_rename,
__field( pid_t, pid)
__array( char, oldcomm, TASK_COMM_LEN)
__array( char, newcomm, TASK_COMM_LEN)
- __field( int, oom_score_adj)
+ __field( short, oom_score_adj)
),
TP_fast_assign(
@@ -50,7 +50,7 @@ TRACE_EVENT(task_rename,
__entry->oom_score_adj = task->signal->oom_score_adj;
),
- TP_printk("pid=%d oldcomm=%s newcomm=%s oom_score_adj=%d",
+ TP_printk("pid=%d oldcomm=%s newcomm=%s oom_score_adj=%hd",
__entry->pid, __entry->oldcomm,
__entry->newcomm, __entry->oom_score_adj)
);
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index a763888a36f..40dc5e8fe34 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -545,8 +545,7 @@ ftrace_raw_event_##call(void *__data, proto) \
{ assign; } \
\
if (!filter_current_check_discard(buffer, event_call, entry, event)) \
- trace_nowake_buffer_unlock_commit(buffer, \
- event, irq_flags, pc); \
+ trace_buffer_unlock_commit(buffer, event, irq_flags, pc); \
}
/*
* The ftrace_test_probe is compiled out, it is only here as a build time check
@@ -620,79 +619,6 @@ __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
-/*
- * Define the insertion callback to perf events
- *
- * The job is very similar to ftrace_raw_event_<call> except that we don't
- * insert in the ring buffer but in a perf counter.
- *
- * static void ftrace_perf_<call>(proto)
- * {
- * struct ftrace_data_offsets_<call> __maybe_unused __data_offsets;
- * struct ftrace_event_call *event_call = &event_<call>;
- * extern void perf_tp_event(int, u64, u64, void *, int);
- * struct ftrace_raw_##call *entry;
- * struct perf_trace_buf *trace_buf;
- * u64 __addr = 0, __count = 1;
- * unsigned long irq_flags;
- * struct trace_entry *ent;
- * int __entry_size;
- * int __data_size;
- * int __cpu
- * int pc;
- *
- * pc = preempt_count();
- *
- * __data_size = ftrace_get_offsets_<call>(&__data_offsets, args);
- *
- * // Below we want to get the aligned size by taking into account
- * // the u32 field that will later store the buffer size
- * __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32),
- * sizeof(u64));
- * __entry_size -= sizeof(u32);
- *
- * // Protect the non nmi buffer
- * // This also protects the rcu read side
- * local_irq_save(irq_flags);
- * __cpu = smp_processor_id();
- *
- * if (in_nmi())
- * trace_buf = rcu_dereference_sched(perf_trace_buf_nmi);
- * else
- * trace_buf = rcu_dereference_sched(perf_trace_buf);
- *
- * if (!trace_buf)
- * goto end;
- *
- * trace_buf = per_cpu_ptr(trace_buf, __cpu);
- *
- * // Avoid recursion from perf that could mess up the buffer
- * if (trace_buf->recursion++)
- * goto end_recursion;
- *
- * raw_data = trace_buf->buf;
- *
- * // Make recursion update visible before entering perf_tp_event
- * // so that we protect from perf recursions.
- *
- * barrier();
- *
- * //zero dead bytes from alignment to avoid stack leak to userspace:
- * *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL;
- * entry = (struct ftrace_raw_<call> *)raw_data;
- * ent = &entry->ent;
- * tracing_generic_entry_update(ent, irq_flags, pc);
- * ent->type = event_call->id;
- *
- * <tstruct> <- do some jobs with dynamic arrays
- *
- * <assign> <- affect our values
- *
- * perf_tp_event(event_call->id, __addr, __count, entry,
- * __entry_size); <- submit them to perf counter
- *
- * }
- */
#ifdef CONFIG_PERF_EVENTS
diff --git a/include/trace/syscall.h b/include/trace/syscall.h
index 31966a4fb8c..84bc4197e73 100644
--- a/include/trace/syscall.h
+++ b/include/trace/syscall.h
@@ -31,27 +31,4 @@ struct syscall_metadata {
struct ftrace_event_call *exit_event;
};
-#ifdef CONFIG_FTRACE_SYSCALLS
-extern unsigned long arch_syscall_addr(int nr);
-extern int init_syscall_trace(struct ftrace_event_call *call);
-
-extern int reg_event_syscall_enter(struct ftrace_event_call *call);
-extern void unreg_event_syscall_enter(struct ftrace_event_call *call);
-extern int reg_event_syscall_exit(struct ftrace_event_call *call);
-extern void unreg_event_syscall_exit(struct ftrace_event_call *call);
-extern int
-ftrace_format_syscall(struct ftrace_event_call *call, struct trace_seq *s);
-enum print_line_t print_syscall_enter(struct trace_iterator *iter, int flags,
- struct trace_event *event);
-enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags,
- struct trace_event *event);
-#endif
-
-#ifdef CONFIG_PERF_EVENTS
-int perf_sysenter_enable(struct ftrace_event_call *call);
-void perf_sysenter_disable(struct ftrace_event_call *call);
-int perf_sysexit_enable(struct ftrace_event_call *call);
-void perf_sysexit_disable(struct ftrace_event_call *call);
-#endif
-
#endif /* _TRACE_SYSCALL_H */
diff --git a/include/uapi/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h
index 199975fac39..143dacbb7d9 100644
--- a/include/uapi/asm-generic/ioctls.h
+++ b/include/uapi/asm-generic/ioctls.h
@@ -74,6 +74,9 @@
#define TCSETXW 0x5435
#define TIOCSIG _IOW('T', 0x36, int) /* pty: generate signal */
#define TIOCVHANGUP 0x5437
+#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
+#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
+#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
#define FIONCLEX 0x5450
#define FIOCLEX 0x5451
diff --git a/include/uapi/asm-generic/mman-common.h b/include/uapi/asm-generic/mman-common.h
index d030d2c2647..4164529a94f 100644
--- a/include/uapi/asm-generic/mman-common.h
+++ b/include/uapi/asm-generic/mman-common.h
@@ -55,4 +55,15 @@
/* compatibility flags */
#define MAP_FILE 0
+/*
+ * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size.
+ * This gives us 6 bits, which is enough until someone invents 128 bit address
+ * spaces.
+ *
+ * Assume these are all power of twos.
+ * When 0 use the default page size.
+ */
+#define MAP_HUGE_SHIFT 26
+#define MAP_HUGE_MASK 0x3f
+
#endif /* __ASM_GENERIC_MMAN_COMMON_H */
diff --git a/include/uapi/asm-generic/mman.h b/include/uapi/asm-generic/mman.h
index 32c8bd6a196..e9fe6fd2a07 100644
--- a/include/uapi/asm-generic/mman.h
+++ b/include/uapi/asm-generic/mman.h
@@ -13,6 +13,8 @@
#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */
#define MAP_HUGETLB 0x40000 /* create a huge page mapping */
+/* Bits [26:31] are reserved, see mman-common.h for MAP_HUGETLB usage */
+
#define MCL_CURRENT 1 /* lock all current mappings */
#define MCL_FUTURE 2 /* lock all future mappings */
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index e194387ef78..19e765fbfef 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -415,3 +415,4 @@ header-y += wireless.h
header-y += x25.h
header-y += xattr.h
header-y += xfrm.h
+header-y += hw_breakpoint.h
diff --git a/include/uapi/linux/hw_breakpoint.h b/include/uapi/linux/hw_breakpoint.h
new file mode 100644
index 00000000000..b04000a2296
--- /dev/null
+++ b/include/uapi/linux/hw_breakpoint.h
@@ -0,0 +1,30 @@
+#ifndef _UAPI_LINUX_HW_BREAKPOINT_H
+#define _UAPI_LINUX_HW_BREAKPOINT_H
+
+enum {
+ HW_BREAKPOINT_LEN_1 = 1,
+ HW_BREAKPOINT_LEN_2 = 2,
+ HW_BREAKPOINT_LEN_4 = 4,
+ HW_BREAKPOINT_LEN_8 = 8,
+};
+
+enum {
+ HW_BREAKPOINT_EMPTY = 0,
+ HW_BREAKPOINT_R = 1,
+ HW_BREAKPOINT_W = 2,
+ HW_BREAKPOINT_RW = HW_BREAKPOINT_R | HW_BREAKPOINT_W,
+ HW_BREAKPOINT_X = 4,
+ HW_BREAKPOINT_INVALID = HW_BREAKPOINT_RW | HW_BREAKPOINT_X,
+};
+
+enum bp_type_idx {
+ TYPE_INST = 0,
+#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS
+ TYPE_DATA = 0,
+#else
+ TYPE_DATA = 1,
+#endif
+ TYPE_MAX
+};
+
+#endif /* _UAPI_LINUX_HW_BREAKPOINT_H */
diff --git a/include/uapi/linux/oom.h b/include/uapi/linux/oom.h
index a49c4afc706..b29272d621c 100644
--- a/include/uapi/linux/oom.h
+++ b/include/uapi/linux/oom.h
@@ -8,4 +8,13 @@
#define OOM_SCORE_ADJ_MIN (-1000)
#define OOM_SCORE_ADJ_MAX 1000
+/*
+ * /proc/<pid>/oom_adj set to -17 protects from the oom killer for legacy
+ * purposes.
+ */
+#define OOM_DISABLE (-17)
+/* inclusive */
+#define OOM_ADJUST_MIN (-16)
+#define OOM_ADJUST_MAX 15
+
#endif /* _UAPI__INCLUDE_LINUX_OOM_H */
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index 7e1ab20adc0..78f99d97475 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -49,7 +49,8 @@
#define PORT_XR17D15X 21 /* Exar XR17D15x UART */
#define PORT_LPC3220 22 /* NXP LPC32xx SoC "Standard" UART */
#define PORT_8250_CIR 23 /* CIR infrared port, has its own driver */
-#define PORT_MAX_8250 23 /* max port ID */
+#define PORT_XR17V35X 24 /* Exar XR17V35x UARTs */
+#define PORT_MAX_8250 24 /* max port ID */
/*
* ARM specific type numbers. These are not currently guaranteed
@@ -215,5 +216,7 @@
/* Energy Micro efm32 SoC */
#define PORT_EFMUART 100
+/* ARC (Synopsys) on-chip UART */
+#define PORT_ARC 101
#endif /* _UAPILINUX_SERIAL_CORE_H */
diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h
index 5ed325e88a8..e6322605b13 100644
--- a/include/uapi/linux/serial_reg.h
+++ b/include/uapi/linux/serial_reg.h
@@ -367,5 +367,23 @@
#define UART_OMAP_MDR1_CIR_MODE 0x06 /* CIR mode */
#define UART_OMAP_MDR1_DISABLE 0x07 /* Disable (default state) */
+/*
+ * These are definitions for the Exar XR17V35X and XR17(C|D)15X
+ */
+#define UART_EXAR_8XMODE 0x88 /* 8X sampling rate select */
+#define UART_EXAR_SLEEP 0x8b /* Sleep mode */
+#define UART_EXAR_DVID 0x8d /* Device identification */
+
+#define UART_EXAR_FCTR 0x08 /* Feature Control Register */
+#define UART_FCTR_EXAR_IRDA 0x08 /* IrDa data encode select */
+#define UART_FCTR_EXAR_485 0x10 /* Auto 485 half duplex dir ctl */
+#define UART_FCTR_EXAR_TRGA 0x00 /* FIFO trigger table A */
+#define UART_FCTR_EXAR_TRGB 0x60 /* FIFO trigger table B */
+#define UART_FCTR_EXAR_TRGC 0x80 /* FIFO trigger table C */
+#define UART_FCTR_EXAR_TRGD 0xc0 /* FIFO trigger table D programmable */
+
+#define UART_EXAR_TXTRG 0x0a /* Tx FIFO trigger level write-only */
+#define UART_EXAR_RXTRG 0x0b /* Rx FIFO trigger level write-only */
+
#endif /* _LINUX_SERIAL_REG_H */
diff --git a/init/Kconfig b/init/Kconfig
index 6fdd6e33932..2054e048bb9 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -486,35 +486,35 @@ config PREEMPT_RCU
This option enables preemptible-RCU code that is common between
the TREE_PREEMPT_RCU and TINY_PREEMPT_RCU implementations.
+config CONTEXT_TRACKING
+ bool
+
config RCU_USER_QS
bool "Consider userspace as in RCU extended quiescent state"
- depends on HAVE_RCU_USER_QS && SMP
+ depends on HAVE_CONTEXT_TRACKING && SMP
+ select CONTEXT_TRACKING
help
This option sets hooks on kernel / userspace boundaries and
puts RCU in extended quiescent state when the CPU runs in
userspace. It means that when a CPU runs in userspace, it is
excluded from the global RCU state machine and thus doesn't
- to keep the timer tick on for RCU.
+ try to keep the timer tick on for RCU.
Unless you want to hack and help the development of the full
- tickless feature, you shouldn't enable this option. It adds
- unnecessary overhead.
+ dynticks mode, you shouldn't enable this option. It also
+ adds unnecessary overhead.
If unsure say N
-config RCU_USER_QS_FORCE
- bool "Force userspace extended QS by default"
- depends on RCU_USER_QS
+config CONTEXT_TRACKING_FORCE
+ bool "Force context tracking"
+ depends on CONTEXT_TRACKING
help
- Set the hooks in user/kernel boundaries by default in order to
- test this feature that treats userspace as an extended quiescent
- state until we have a real user like a full adaptive nohz option.
-
- Unless you want to hack and help the development of the full
- tickless feature, you shouldn't enable this option. It adds
- unnecessary overhead.
-
- If unsure say N
+ Probe on user/kernel boundaries by default in order to
+ test the features that rely on it such as userspace RCU extended
+ quiescent states.
+ This test is there for debugging until we have a real user like the
+ full dynticks mode.
config RCU_FANOUT
int "Tree-based hierarchical RCU fanout value"
@@ -582,14 +582,13 @@ config RCU_FAST_NO_HZ
depends on NO_HZ && SMP
default n
help
- This option causes RCU to attempt to accelerate grace periods
- in order to allow CPUs to enter dynticks-idle state more
- quickly. On the other hand, this option increases the overhead
- of the dynticks-idle checking, particularly on systems with
- large numbers of CPUs.
+ This option causes RCU to attempt to accelerate grace periods in
+ order to allow CPUs to enter dynticks-idle state more quickly.
+ On the other hand, this option increases the overhead of the
+ dynticks-idle checking, thus degrading scheduling latency.
- Say Y if energy efficiency is critically important, particularly
- if you have relatively few CPUs.
+ Say Y if energy efficiency is critically important, and you don't
+ care about real-time response.
Say N if you are unsure.
@@ -655,6 +654,28 @@ config RCU_BOOST_DELAY
Accept the default if unsure.
+config RCU_NOCB_CPU
+ bool "Offload RCU callback processing from boot-selected CPUs"
+ depends on TREE_RCU || TREE_PREEMPT_RCU
+ default n
+ help
+ Use this option to reduce OS jitter for aggressive HPC or
+ real-time workloads. It can also be used to offload RCU
+ callback invocation to energy-efficient CPUs in battery-powered
+ asymmetric multiprocessors.
+
+ This option offloads callback invocation from the set of
+ CPUs specified at boot time by the rcu_nocbs parameter.
+ For each such CPU, a kthread ("rcuoN") will be created to
+ invoke callbacks, where the "N" is the CPU being offloaded.
+ Nothing prevents this kthread from running on the specified
+ CPUs, but (1) the kthreads may be preempted between each
+ callback, and (2) affinity or cgroups can be used to force
+ the kthreads to run on whatever set of CPUs is desired.
+
+ Say Y here if you want reduced OS jitter on selected CPUs.
+ Say N here if you are unsure.
+
endmenu # "RCU Subsystem"
config IKCONFIG
diff --git a/ipc/shm.c b/ipc/shm.c
index dff40c9f73c..4fa6d8fee73 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -495,7 +495,8 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
if (shmflg & SHM_NORESERVE)
acctflag = VM_NORESERVE;
file = hugetlb_file_setup(name, 0, size, acctflag,
- &shp->mlock_user, HUGETLB_SHMFS_INODE);
+ &shp->mlock_user, HUGETLB_SHMFS_INODE,
+ (shmflg >> SHM_HUGE_SHIFT) & SHM_HUGE_MASK);
} else {
/*
* Do not allow no accounting for OVERCOMMIT_NEVER, even
diff --git a/kernel/Makefile b/kernel/Makefile
index 86e3285ae7e..ac0d533eb7d 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -110,6 +110,7 @@ obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
obj-$(CONFIG_PADATA) += padata.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
+obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
$(obj)/configs.o: $(obj)/config_data.h
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 2f186ed80c4..fc7376bf86e 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1159,7 +1159,7 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
cred = current_cred();
spin_lock_irq(&tsk->sighand->siglock);
- if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name)
+ if (tsk->signal && tsk->signal->tty)
tty = tsk->signal->tty->name;
else
tty = "(none)";
diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c
new file mode 100644
index 00000000000..e0e07fd5550
--- /dev/null
+++ b/kernel/context_tracking.c
@@ -0,0 +1,83 @@
+#include <linux/context_tracking.h>
+#include <linux/rcupdate.h>
+#include <linux/sched.h>
+#include <linux/percpu.h>
+#include <linux/hardirq.h>
+
+struct context_tracking {
+ /*
+ * When active is false, hooks are not set to
+ * minimize overhead: TIF flags are cleared
+ * and calls to user_enter/exit are ignored. This
+ * may be further optimized using static keys.
+ */
+ bool active;
+ enum {
+ IN_KERNEL = 0,
+ IN_USER,
+ } state;
+};
+
+static DEFINE_PER_CPU(struct context_tracking, context_tracking) = {
+#ifdef CONFIG_CONTEXT_TRACKING_FORCE
+ .active = true,
+#endif
+};
+
+void user_enter(void)
+{
+ unsigned long flags;
+
+ /*
+ * Some contexts may involve an exception occuring in an irq,
+ * leading to that nesting:
+ * rcu_irq_enter() rcu_user_exit() rcu_user_exit() rcu_irq_exit()
+ * This would mess up the dyntick_nesting count though. And rcu_irq_*()
+ * helpers are enough to protect RCU uses inside the exception. So
+ * just return immediately if we detect we are in an IRQ.
+ */
+ if (in_interrupt())
+ return;
+
+ WARN_ON_ONCE(!current->mm);
+
+ local_irq_save(flags);
+ if (__this_cpu_read(context_tracking.active) &&
+ __this_cpu_read(context_tracking.state) != IN_USER) {
+ __this_cpu_write(context_tracking.state, IN_USER);
+ rcu_user_enter();
+ }
+ local_irq_restore(flags);
+}
+
+void user_exit(void)
+{
+ unsigned long flags;
+
+ /*
+ * Some contexts may involve an exception occuring in an irq,
+ * leading to that nesting:
+ * rcu_irq_enter() rcu_user_exit() rcu_user_exit() rcu_irq_exit()
+ * This would mess up the dyntick_nesting count though. And rcu_irq_*()
+ * helpers are enough to protect RCU uses inside the exception. So
+ * just return immediately if we detect we are in an IRQ.
+ */
+ if (in_interrupt())
+ return;
+
+ local_irq_save(flags);
+ if (__this_cpu_read(context_tracking.state) == IN_USER) {
+ __this_cpu_write(context_tracking.state, IN_KERNEL);
+ rcu_user_exit();
+ }
+ local_irq_restore(flags);
+}
+
+void context_tracking_task_switch(struct task_struct *prev,
+ struct task_struct *next)
+{
+ if (__this_cpu_read(context_tracking.active)) {
+ clear_tsk_thread_flag(prev, TIF_NOHZ);
+ set_tsk_thread_flag(next, TIF_NOHZ);
+ }
+}
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 42bd331ee0a..3046a503242 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -348,11 +348,13 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
struct task_struct *idle;
- if (cpu_online(cpu) || !cpu_present(cpu))
- return -EINVAL;
-
cpu_hotplug_begin();
+ if (cpu_online(cpu) || !cpu_present(cpu)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
idle = idle_thread_get(cpu);
if (IS_ERR(idle)) {
ret = PTR_ERR(idle);
@@ -601,6 +603,11 @@ cpu_hotplug_pm_callback(struct notifier_block *nb,
static int __init cpu_hotplug_pm_sync_init(void)
{
+ /*
+ * cpu_hotplug_pm_callback has higher priority than x86
+ * bsp_pm_callback which depends on cpu_hotplug_pm_callback
+ * to disable cpu hotplug to avoid cpu hotplug race.
+ */
pm_notifier(cpu_hotplug_pm_callback, 0);
return 0;
}
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c
index 9a7b487c6fe..fe8a916507e 100644
--- a/kernel/events/hw_breakpoint.c
+++ b/kernel/events/hw_breakpoint.c
@@ -111,14 +111,16 @@ static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type)
* Count the number of breakpoints of the same type and same task.
* The given event must be not on the list.
*/
-static int task_bp_pinned(struct perf_event *bp, enum bp_type_idx type)
+static int task_bp_pinned(int cpu, struct perf_event *bp, enum bp_type_idx type)
{
struct task_struct *tsk = bp->hw.bp_target;
struct perf_event *iter;
int count = 0;
list_for_each_entry(iter, &bp_task_head, hw.bp_list) {
- if (iter->hw.bp_target == tsk && find_slot_idx(iter) == type)
+ if (iter->hw.bp_target == tsk &&
+ find_slot_idx(iter) == type &&
+ cpu == iter->cpu)
count += hw_breakpoint_weight(iter);
}
@@ -141,7 +143,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp,
if (!tsk)
slots->pinned += max_task_bp_pinned(cpu, type);
else
- slots->pinned += task_bp_pinned(bp, type);
+ slots->pinned += task_bp_pinned(cpu, bp, type);
slots->flexible = per_cpu(nr_bp_flexible[type], cpu);
return;
@@ -154,7 +156,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp,
if (!tsk)
nr += max_task_bp_pinned(cpu, type);
else
- nr += task_bp_pinned(bp, type);
+ nr += task_bp_pinned(cpu, bp, type);
if (nr > slots->pinned)
slots->pinned = nr;
@@ -188,7 +190,7 @@ static void toggle_bp_task_slot(struct perf_event *bp, int cpu, bool enable,
int old_idx = 0;
int idx = 0;
- old_count = task_bp_pinned(bp, type);
+ old_count = task_bp_pinned(cpu, bp, type);
old_idx = old_count - 1;
idx = old_idx + weight;
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 5cc4e7e42e6..dea7acfbb07 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -33,6 +33,7 @@
#include <linux/ptrace.h> /* user_enable_single_step */
#include <linux/kdebug.h> /* notifier mechanism */
#include "../../mm/internal.h" /* munlock_vma_page */
+#include <linux/percpu-rwsem.h>
#include <linux/uprobes.h>
@@ -71,6 +72,8 @@ static struct mutex uprobes_mutex[UPROBES_HASH_SZ];
static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ];
#define uprobes_mmap_hash(v) (&uprobes_mmap_mutex[((unsigned long)(v)) % UPROBES_HASH_SZ])
+static struct percpu_rw_semaphore dup_mmap_sem;
+
/*
* uprobe_events allows us to skip the uprobe_mmap if there are no uprobe
* events active at this time. Probably a fine grained per inode count is
@@ -766,10 +769,13 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
struct map_info *info;
int err = 0;
+ percpu_down_write(&dup_mmap_sem);
info = build_map_info(uprobe->inode->i_mapping,
uprobe->offset, is_register);
- if (IS_ERR(info))
- return PTR_ERR(info);
+ if (IS_ERR(info)) {
+ err = PTR_ERR(info);
+ goto out;
+ }
while (info) {
struct mm_struct *mm = info->mm;
@@ -799,7 +805,8 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
mmput(mm);
info = free_map_info(info);
}
-
+ out:
+ percpu_up_write(&dup_mmap_sem);
return err;
}
@@ -1131,6 +1138,16 @@ void uprobe_clear_state(struct mm_struct *mm)
kfree(area);
}
+void uprobe_start_dup_mmap(void)
+{
+ percpu_down_read(&dup_mmap_sem);
+}
+
+void uprobe_end_dup_mmap(void)
+{
+ percpu_up_read(&dup_mmap_sem);
+}
+
void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm)
{
newmm->uprobes_state.xol_area = NULL;
@@ -1199,6 +1216,11 @@ static unsigned long xol_get_insn_slot(struct uprobe *uprobe, unsigned long slot
vaddr = kmap_atomic(area->page);
memcpy(vaddr + offset, uprobe->arch.insn, MAX_UINSN_BYTES);
kunmap_atomic(vaddr);
+ /*
+ * We probably need flush_icache_user_range() but it needs vma.
+ * This should work on supported architectures too.
+ */
+ flush_dcache_page(area->page);
return current->utask->xol_vaddr;
}
@@ -1430,16 +1452,6 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp)
return uprobe;
}
-void __weak arch_uprobe_enable_step(struct arch_uprobe *arch)
-{
- user_enable_single_step(current);
-}
-
-void __weak arch_uprobe_disable_step(struct arch_uprobe *arch)
-{
- user_disable_single_step(current);
-}
-
/*
* Run handler and ask thread to singlestep.
* Ensure all non-fatal signals cannot interrupt thread while it singlesteps.
@@ -1493,7 +1505,6 @@ static void handle_swbp(struct pt_regs *regs)
goto out;
if (!pre_ssout(uprobe, regs, bp_vaddr)) {
- arch_uprobe_enable_step(&uprobe->arch);
utask->active_uprobe = uprobe;
utask->state = UTASK_SSTEP;
return;
@@ -1525,7 +1536,6 @@ static void handle_singlestep(struct uprobe_task *utask, struct pt_regs *regs)
else
WARN_ON_ONCE(1);
- arch_uprobe_disable_step(&uprobe->arch);
put_uprobe(uprobe);
utask->active_uprobe = NULL;
utask->state = UTASK_RUNNING;
@@ -1604,6 +1614,9 @@ static int __init init_uprobes(void)
mutex_init(&uprobes_mmap_mutex[i]);
}
+ if (percpu_init_rwsem(&dup_mmap_sem))
+ return -ENOMEM;
+
return register_die_notifier(&uprobe_exception_nb);
}
module_init(init_uprobes);
diff --git a/kernel/exit.c b/kernel/exit.c
index 346616c0092..618f7ee5600 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1186,11 +1186,11 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
* as other threads in the parent group can be right
* here reaping other children at the same time.
*
- * We use thread_group_times() to get times for the thread
+ * We use thread_group_cputime_adjusted() to get times for the thread
* group, which consolidates times for all threads in the
* group including the group leader.
*/
- thread_group_times(p, &tgutime, &tgstime);
+ thread_group_cputime_adjusted(p, &tgutime, &tgstime);
spin_lock_irq(&p->real_parent->sighand->siglock);
psig = p->real_parent->signal;
sig = p->signal;
diff --git a/kernel/fork.c b/kernel/fork.c
index 8b20ab7d3aa..850dde1e0c8 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -352,6 +352,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
unsigned long charge;
struct mempolicy *pol;
+ uprobe_start_dup_mmap();
down_write(&oldmm->mmap_sem);
flush_cache_dup_mm(oldmm);
uprobe_dup_mmap(oldmm, mm);
@@ -469,6 +470,7 @@ out:
up_write(&mm->mmap_sem);
flush_tlb_mm(oldmm);
up_write(&oldmm->mmap_sem);
+ uprobe_end_dup_mmap();
return retval;
fail_nomem_anon_vma_fork:
mpol_put(pol);
@@ -1222,7 +1224,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->utime = p->stime = p->gtime = 0;
p->utimescaled = p->stimescaled = 0;
#ifndef CONFIG_VIRT_CPU_ACCOUNTING
- p->prev_utime = p->prev_stime = 0;
+ p->prev_cputime.utime = p->prev_cputime.stime = 0;
#endif
#if defined(SPLIT_RSS_COUNTING)
memset(&p->rss_stat, 0, sizeof(p->rss_stat));
diff --git a/kernel/futex.c b/kernel/futex.c
index 3717e7b306e..19eb089ca00 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -716,7 +716,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb,
struct futex_pi_state **ps,
struct task_struct *task, int set_waiters)
{
- int lock_taken, ret, ownerdied = 0;
+ int lock_taken, ret, force_take = 0;
u32 uval, newval, curval, vpid = task_pid_vnr(task);
retry:
@@ -755,17 +755,15 @@ retry:
newval = curval | FUTEX_WAITERS;
/*
- * There are two cases, where a futex might have no owner (the
- * owner TID is 0): OWNER_DIED. We take over the futex in this
- * case. We also do an unconditional take over, when the owner
- * of the futex died.
- *
- * This is safe as we are protected by the hash bucket lock !
+ * Should we force take the futex? See below.
*/
- if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) {
- /* Keep the OWNER_DIED bit */
+ if (unlikely(force_take)) {
+ /*
+ * Keep the OWNER_DIED and the WAITERS bit and set the
+ * new TID value.
+ */
newval = (curval & ~FUTEX_TID_MASK) | vpid;
- ownerdied = 0;
+ force_take = 0;
lock_taken = 1;
}
@@ -775,7 +773,7 @@ retry:
goto retry;
/*
- * We took the lock due to owner died take over.
+ * We took the lock due to forced take over.
*/
if (unlikely(lock_taken))
return 1;
@@ -790,20 +788,25 @@ retry:
switch (ret) {
case -ESRCH:
/*
- * No owner found for this futex. Check if the
- * OWNER_DIED bit is set to figure out whether
- * this is a robust futex or not.
+ * We failed to find an owner for this
+ * futex. So we have no pi_state to block
+ * on. This can happen in two cases:
+ *
+ * 1) The owner died
+ * 2) A stale FUTEX_WAITERS bit
+ *
+ * Re-read the futex value.
*/
if (get_futex_value_locked(&curval, uaddr))
return -EFAULT;
/*
- * We simply start over in case of a robust
- * futex. The code above will take the futex
- * and return happy.
+ * If the owner died or we have a stale
+ * WAITERS bit the owner TID in the user space
+ * futex is 0.
*/
- if (curval & FUTEX_OWNER_DIED) {
- ownerdied = 1;
+ if (!(curval & FUTEX_TID_MASK)) {
+ force_take = 1;
goto retry;
}
default:
@@ -840,6 +843,9 @@ static void wake_futex(struct futex_q *q)
{
struct task_struct *p = q->task;
+ if (WARN(q->pi_state || q->rt_waiter, "refusing to wake PI futex\n"))
+ return;
+
/*
* We set q->lock_ptr = NULL _before_ we wake up the task. If
* a non-futex wake up happens on another CPU then the task
@@ -1075,6 +1081,10 @@ retry_private:
plist_for_each_entry_safe(this, next, head, list) {
if (match_futex (&this->key, &key1)) {
+ if (this->pi_state || this->rt_waiter) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
wake_futex(this);
if (++ret >= nr_wake)
break;
@@ -1087,6 +1097,10 @@ retry_private:
op_ret = 0;
plist_for_each_entry_safe(this, next, head, list) {
if (match_futex (&this->key, &key2)) {
+ if (this->pi_state || this->rt_waiter) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
wake_futex(this);
if (++op_ret >= nr_wake2)
break;
@@ -1095,6 +1109,7 @@ retry_private:
ret += op_ret;
}
+out_unlock:
double_unlock_hb(hb1, hb2);
out_put_keys:
put_futex_key(&key2);
@@ -1384,9 +1399,13 @@ retry_private:
/*
* FUTEX_WAIT_REQEUE_PI and FUTEX_CMP_REQUEUE_PI should always
* be paired with each other and no other futex ops.
+ *
+ * We should never be requeueing a futex_q with a pi_state,
+ * which is awaiting a futex_unlock_pi().
*/
if ((requeue_pi && !this->rt_waiter) ||
- (!requeue_pi && this->rt_waiter)) {
+ (!requeue_pi && this->rt_waiter) ||
+ this->pi_state) {
ret = -EINVAL;
break;
}
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 57d86d07221..3aca9f29d30 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -272,6 +272,7 @@ void handle_nested_irq(unsigned int irq)
raw_spin_lock_irq(&desc->lock);
+ desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
kstat_incr_irqs_this_cpu(irq, desc);
action = desc->action;
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 4e69e24d3d7..96f3a1d9c37 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -177,8 +177,8 @@ struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
irq_base = irq_alloc_descs(first_irq, first_irq, size,
of_node_to_nid(of_node));
if (irq_base < 0) {
- WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
- first_irq);
+ pr_info("Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
+ first_irq);
irq_base = first_irq;
}
} else
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 4c69326aa77..35c70c9e24d 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -616,6 +616,22 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
return ret;
}
+#ifdef CONFIG_HARDIRQS_SW_RESEND
+int irq_set_parent(int irq, int parent_irq)
+{
+ unsigned long flags;
+ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
+
+ if (!desc)
+ return -EINVAL;
+
+ desc->parent_irq = parent_irq;
+
+ irq_put_desc_unlock(desc, flags);
+ return 0;
+}
+#endif
+
/*
* Default primary interrupt handler for threaded interrupts. Is
* assigned as primary handler when request_threaded_irq is called
@@ -716,6 +732,7 @@ static void
irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action)
{
cpumask_var_t mask;
+ bool valid = true;
if (!test_and_clear_bit(IRQTF_AFFINITY, &action->thread_flags))
return;
@@ -730,10 +747,18 @@ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action)
}
raw_spin_lock_irq(&desc->lock);
- cpumask_copy(mask, desc->irq_data.affinity);
+ /*
+ * This code is triggered unconditionally. Check the affinity
+ * mask pointer. For CPU_MASK_OFFSTACK=n this is optimized out.
+ */
+ if (desc->irq_data.affinity)
+ cpumask_copy(mask, desc->irq_data.affinity);
+ else
+ valid = false;
raw_spin_unlock_irq(&desc->lock);
- set_cpus_allowed_ptr(current, mask);
+ if (valid)
+ set_cpus_allowed_ptr(current, mask);
free_cpumask_var(mask);
}
#else
@@ -833,6 +858,8 @@ static int irq_thread(void *data)
init_task_work(&on_exit_work, irq_thread_dtor);
task_work_add(current, &on_exit_work, false);
+ irq_thread_check_affinity(desc, action);
+
while (!irq_wait_for_interrupt(action)) {
irqreturn_t action_ret;
@@ -936,6 +963,16 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
*/
get_task_struct(t);
new->thread = t;
+ /*
+ * Tell the thread to set its affinity. This is
+ * important for shared interrupt handlers as we do
+ * not invoke setup_affinity() for the secondary
+ * handlers as everything is already set up. Even for
+ * interrupts marked with IRQF_NO_BALANCE this is
+ * correct as we want the thread to move to the cpu(s)
+ * on which the requesting code placed the interrupt.
+ */
+ set_bit(IRQTF_AFFINITY, &new->thread_flags);
}
if (!alloc_cpumask_var(&mask, GFP_KERNEL)) {
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c
index 6454db7b6a4..9065107f083 100644
--- a/kernel/irq/resend.c
+++ b/kernel/irq/resend.c
@@ -74,6 +74,14 @@ void check_irq_resend(struct irq_desc *desc, unsigned int irq)
if (!desc->irq_data.chip->irq_retrigger ||
!desc->irq_data.chip->irq_retrigger(&desc->irq_data)) {
#ifdef CONFIG_HARDIRQS_SW_RESEND
+ /*
+ * If the interrupt has a parent irq and runs
+ * in the thread context of the parent irq,
+ * retrigger the parent.
+ */
+ if (desc->parent_irq &&
+ irq_settings_is_nested_thread(desc))
+ irq = desc->parent_irq;
/* Set it pending and activate the softirq: */
set_bit(irq, irqs_resend);
tasklet_schedule(&resend_tasklet);
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index 4e316e1acf5..6ada93c23a9 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -26,7 +26,6 @@ static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
static struct kobj_attribute _name##_attr = \
__ATTR(_name, 0644, _name##_show, _name##_store)
-#if defined(CONFIG_HOTPLUG)
/* current uevent sequence number */
static ssize_t uevent_seqnum_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
@@ -54,7 +53,7 @@ static ssize_t uevent_helper_store(struct kobject *kobj,
return count;
}
KERNEL_ATTR_RW(uevent_helper);
-#endif
+
#ifdef CONFIG_PROFILING
static ssize_t profiling_show(struct kobject *kobj,
@@ -141,6 +140,23 @@ static ssize_t fscaps_show(struct kobject *kobj,
}
KERNEL_ATTR_RO(fscaps);
+int rcu_expedited;
+static ssize_t rcu_expedited_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", rcu_expedited);
+}
+static ssize_t rcu_expedited_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ if (kstrtoint(buf, 0, &rcu_expedited))
+ return -EINVAL;
+
+ return count;
+}
+KERNEL_ATTR_RW(rcu_expedited);
+
/*
* Make /sys/kernel/notes give the raw contents of our kernel .notes section.
*/
@@ -169,10 +185,8 @@ EXPORT_SYMBOL_GPL(kernel_kobj);
static struct attribute * kernel_attrs[] = {
&fscaps_attr.attr,
-#if defined(CONFIG_HOTPLUG)
&uevent_seqnum_attr.attr,
&uevent_helper_attr.attr,
-#endif
#ifdef CONFIG_PROFILING
&profiling_attr.attr,
#endif
@@ -182,6 +196,7 @@ static struct attribute * kernel_attrs[] = {
&kexec_crash_size_attr.attr,
&vmcoreinfo_attr.attr,
#endif
+ &rcu_expedited_attr.attr,
NULL
};
diff --git a/kernel/lockdep_proc.c b/kernel/lockdep_proc.c
index 91c32a0b612..b2c71c5873e 100644
--- a/kernel/lockdep_proc.c
+++ b/kernel/lockdep_proc.c
@@ -39,7 +39,7 @@ static void l_stop(struct seq_file *m, void *v)
static void print_name(struct seq_file *m, struct lock_class *class)
{
- char str[128];
+ char str[KSYM_NAME_LEN];
const char *name = class->name;
if (!name) {
diff --git a/kernel/modsign_pubkey.c b/kernel/modsign_pubkey.c
index 4646eb2c382..767e559dfb1 100644
--- a/kernel/modsign_pubkey.c
+++ b/kernel/modsign_pubkey.c
@@ -21,10 +21,10 @@ struct key *modsign_keyring;
extern __initdata const u8 modsign_certificate_list[];
extern __initdata const u8 modsign_certificate_list_end[];
asm(".section .init.data,\"aw\"\n"
- "modsign_certificate_list:\n"
+ SYMBOL_PREFIX "modsign_certificate_list:\n"
".incbin \"signing_key.x509\"\n"
".incbin \"extra_certificates\"\n"
- "modsign_certificate_list_end:"
+ SYMBOL_PREFIX "modsign_certificate_list_end:"
);
/*
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
index ea1b1df5dbb..f2970bddc5e 100644
--- a/kernel/module_signing.c
+++ b/kernel/module_signing.c
@@ -27,13 +27,13 @@
* - Information block
*/
struct module_signature {
- enum pkey_algo algo : 8; /* Public-key crypto algorithm */
- enum pkey_hash_algo hash : 8; /* Digest algorithm */
- enum pkey_id_type id_type : 8; /* Key identifier type */
- u8 signer_len; /* Length of signer's name */
- u8 key_id_len; /* Length of key identifier */
- u8 __pad[3];
- __be32 sig_len; /* Length of signature data */
+ u8 algo; /* Public-key crypto algorithm [enum pkey_algo] */
+ u8 hash; /* Digest algorithm [enum pkey_hash_algo] */
+ u8 id_type; /* Key identifier type [enum pkey_id_type] */
+ u8 signer_len; /* Length of signer's name */
+ u8 key_id_len; /* Length of key identifier */
+ u8 __pad[3];
+ __be32 sig_len; /* Length of signature data */
};
/*
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 125cb67daa2..d73840271dc 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -217,30 +217,6 @@ static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p,
return 0;
}
-void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times)
-{
- struct signal_struct *sig = tsk->signal;
- struct task_struct *t;
-
- times->utime = sig->utime;
- times->stime = sig->stime;
- times->sum_exec_runtime = sig->sum_sched_runtime;
-
- rcu_read_lock();
- /* make sure we can trust tsk->thread_group list */
- if (!likely(pid_alive(tsk)))
- goto out;
-
- t = tsk;
- do {
- times->utime += t->utime;
- times->stime += t->stime;
- times->sum_exec_runtime += task_sched_runtime(t);
- } while_each_thread(tsk, t);
-out:
- rcu_read_unlock();
-}
-
static void update_gt_cputime(struct task_cputime *a, struct task_cputime *b)
{
if (b->utime > a->utime)
diff --git a/kernel/power/main.c b/kernel/power/main.c
index f458238109c..1c16f9167de 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -59,7 +59,7 @@ static ssize_t pm_async_store(struct kobject *kobj, struct kobj_attribute *attr,
{
unsigned long val;
- if (strict_strtoul(buf, 10, &val))
+ if (kstrtoul(buf, 10, &val))
return -EINVAL;
if (val > 1)
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index 846bd42c7ed..9322ff7eaad 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -213,6 +213,69 @@ int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node,
}
/**
+ * pm_qos_flags_remove_req - Remove device PM QoS flags request.
+ * @pqf: Device PM QoS flags set to remove the request from.
+ * @req: Request to remove from the set.
+ */
+static void pm_qos_flags_remove_req(struct pm_qos_flags *pqf,
+ struct pm_qos_flags_request *req)
+{
+ s32 val = 0;
+
+ list_del(&req->node);
+ list_for_each_entry(req, &pqf->list, node)
+ val |= req->flags;
+
+ pqf->effective_flags = val;
+}
+
+/**
+ * pm_qos_update_flags - Update a set of PM QoS flags.
+ * @pqf: Set of flags to update.
+ * @req: Request to add to the set, to modify, or to remove from the set.
+ * @action: Action to take on the set.
+ * @val: Value of the request to add or modify.
+ *
+ * Update the given set of PM QoS flags and call notifiers if the aggregate
+ * value has changed. Returns 1 if the aggregate constraint value has changed,
+ * 0 otherwise.
+ */
+bool pm_qos_update_flags(struct pm_qos_flags *pqf,
+ struct pm_qos_flags_request *req,
+ enum pm_qos_req_action action, s32 val)
+{
+ unsigned long irqflags;
+ s32 prev_value, curr_value;
+
+ spin_lock_irqsave(&pm_qos_lock, irqflags);
+
+ prev_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags;
+
+ switch (action) {
+ case PM_QOS_REMOVE_REQ:
+ pm_qos_flags_remove_req(pqf, req);
+ break;
+ case PM_QOS_UPDATE_REQ:
+ pm_qos_flags_remove_req(pqf, req);
+ case PM_QOS_ADD_REQ:
+ req->flags = val;
+ INIT_LIST_HEAD(&req->node);
+ list_add_tail(&req->node, &pqf->list);
+ pqf->effective_flags |= val;
+ break;
+ default:
+ /* no action */
+ ;
+ }
+
+ curr_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags;
+
+ spin_unlock_irqrestore(&pm_qos_lock, irqflags);
+
+ return prev_value != curr_value;
+}
+
+/**
* pm_qos_request - returns current system wide qos expectation
* @pm_qos_class: identification of which qos value is requested
*
@@ -500,7 +563,7 @@ static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
} else {
ascii_value[count] = '\0';
}
- ret = strict_strtoul(ascii_value, 16, &ulval);
+ ret = kstrtoul(ascii_value, 16, &ulval);
if (ret) {
pr_debug("%s, 0x%lx, 0x%x\n", ascii_value, ulval, ret);
return -EINVAL;
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index 3c9d764eb0d..7c33ed20041 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -126,7 +126,7 @@ static int swsusp_extents_insert(unsigned long swap_offset)
/* Figure out where to put the new node */
while (*new) {
- ext = container_of(*new, struct swsusp_extent, node);
+ ext = rb_entry(*new, struct swsusp_extent, node);
parent = *new;
if (swap_offset < ext->start) {
/* Try to merge */
diff --git a/kernel/printk.c b/kernel/printk.c
index 2d607f4d179..22e070f3470 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -87,6 +87,12 @@ static DEFINE_SEMAPHORE(console_sem);
struct console *console_drivers;
EXPORT_SYMBOL_GPL(console_drivers);
+#ifdef CONFIG_LOCKDEP
+static struct lockdep_map console_lock_dep_map = {
+ .name = "console_lock"
+};
+#endif
+
/*
* This is used for debugging the mess that is the VT code by
* keeping track if we have the console semaphore held. It's
@@ -1908,12 +1914,14 @@ static int __cpuinit console_cpu_notify(struct notifier_block *self,
*/
void console_lock(void)
{
- BUG_ON(in_interrupt());
+ might_sleep();
+
down(&console_sem);
if (console_suspended)
return;
console_locked = 1;
console_may_schedule = 1;
+ mutex_acquire(&console_lock_dep_map, 0, 0, _RET_IP_);
}
EXPORT_SYMBOL(console_lock);
@@ -1935,6 +1943,7 @@ int console_trylock(void)
}
console_locked = 1;
console_may_schedule = 0;
+ mutex_acquire(&console_lock_dep_map, 0, 1, _RET_IP_);
return 1;
}
EXPORT_SYMBOL(console_trylock);
@@ -2095,6 +2104,7 @@ skip:
local_irq_restore(flags);
}
console_locked = 0;
+ mutex_release(&console_lock_dep_map, 1, _RET_IP_);
/* Release the exclusive_console once it is used */
if (unlikely(exclusive_console))
diff --git a/kernel/rcu.h b/kernel/rcu.h
index 8ba99cdc651..20dfba576c2 100644
--- a/kernel/rcu.h
+++ b/kernel/rcu.h
@@ -109,4 +109,6 @@ static inline bool __rcu_reclaim(char *rn, struct rcu_head *head)
}
}
+extern int rcu_expedited;
+
#endif /* __LINUX_RCU_H */
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 29ca1c6da59..a2cf76177b4 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -46,12 +46,15 @@
#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
/*
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c
index e4c6a598d6f..e7dce58f9c2 100644
--- a/kernel/rcutiny.c
+++ b/kernel/rcutiny.c
@@ -195,7 +195,7 @@ EXPORT_SYMBOL(rcu_is_cpu_idle);
*/
int rcu_is_cpu_rrupt_from_idle(void)
{
- return rcu_dynticks_nesting <= 0;
+ return rcu_dynticks_nesting <= 1;
}
/*
diff --git a/kernel/rcutiny_plugin.h b/kernel/rcutiny_plugin.h
index 3d019028220..f85016a2309 100644
--- a/kernel/rcutiny_plugin.h
+++ b/kernel/rcutiny_plugin.h
@@ -706,7 +706,10 @@ void synchronize_rcu(void)
return;
/* Once we get past the fastpath checks, same code as rcu_barrier(). */
- rcu_barrier();
+ if (rcu_expedited)
+ synchronize_rcu_expedited();
+ else
+ rcu_barrier();
}
EXPORT_SYMBOL_GPL(synchronize_rcu);
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index aaa7b9f3532..31dea01c85f 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -339,7 +339,6 @@ rcu_stutter_wait(char *title)
struct rcu_torture_ops {
void (*init)(void);
- void (*cleanup)(void);
int (*readlock)(void);
void (*read_delay)(struct rcu_random_state *rrsp);
void (*readunlock)(int idx);
@@ -431,7 +430,6 @@ static void rcu_torture_deferred_free(struct rcu_torture *p)
static struct rcu_torture_ops rcu_ops = {
.init = NULL,
- .cleanup = NULL,
.readlock = rcu_torture_read_lock,
.read_delay = rcu_read_delay,
.readunlock = rcu_torture_read_unlock,
@@ -475,7 +473,6 @@ static void rcu_sync_torture_init(void)
static struct rcu_torture_ops rcu_sync_ops = {
.init = rcu_sync_torture_init,
- .cleanup = NULL,
.readlock = rcu_torture_read_lock,
.read_delay = rcu_read_delay,
.readunlock = rcu_torture_read_unlock,
@@ -493,7 +490,6 @@ static struct rcu_torture_ops rcu_sync_ops = {
static struct rcu_torture_ops rcu_expedited_ops = {
.init = rcu_sync_torture_init,
- .cleanup = NULL,
.readlock = rcu_torture_read_lock,
.read_delay = rcu_read_delay, /* just reuse rcu's version. */
.readunlock = rcu_torture_read_unlock,
@@ -536,7 +532,6 @@ static void rcu_bh_torture_deferred_free(struct rcu_torture *p)
static struct rcu_torture_ops rcu_bh_ops = {
.init = NULL,
- .cleanup = NULL,
.readlock = rcu_bh_torture_read_lock,
.read_delay = rcu_read_delay, /* just reuse rcu's version. */
.readunlock = rcu_bh_torture_read_unlock,
@@ -553,7 +548,6 @@ static struct rcu_torture_ops rcu_bh_ops = {
static struct rcu_torture_ops rcu_bh_sync_ops = {
.init = rcu_sync_torture_init,
- .cleanup = NULL,
.readlock = rcu_bh_torture_read_lock,
.read_delay = rcu_read_delay, /* just reuse rcu's version. */
.readunlock = rcu_bh_torture_read_unlock,
@@ -570,7 +564,6 @@ static struct rcu_torture_ops rcu_bh_sync_ops = {
static struct rcu_torture_ops rcu_bh_expedited_ops = {
.init = rcu_sync_torture_init,
- .cleanup = NULL,
.readlock = rcu_bh_torture_read_lock,
.read_delay = rcu_read_delay, /* just reuse rcu's version. */
.readunlock = rcu_bh_torture_read_unlock,
@@ -589,19 +582,7 @@ static struct rcu_torture_ops rcu_bh_expedited_ops = {
* Definitions for srcu torture testing.
*/
-static struct srcu_struct srcu_ctl;
-
-static void srcu_torture_init(void)
-{
- init_srcu_struct(&srcu_ctl);
- rcu_sync_torture_init();
-}
-
-static void srcu_torture_cleanup(void)
-{
- synchronize_srcu(&srcu_ctl);
- cleanup_srcu_struct(&srcu_ctl);
-}
+DEFINE_STATIC_SRCU(srcu_ctl);
static int srcu_torture_read_lock(void) __acquires(&srcu_ctl)
{
@@ -672,8 +653,7 @@ static int srcu_torture_stats(char *page)
}
static struct rcu_torture_ops srcu_ops = {
- .init = srcu_torture_init,
- .cleanup = srcu_torture_cleanup,
+ .init = rcu_sync_torture_init,
.readlock = srcu_torture_read_lock,
.read_delay = srcu_read_delay,
.readunlock = srcu_torture_read_unlock,
@@ -687,8 +667,7 @@ static struct rcu_torture_ops srcu_ops = {
};
static struct rcu_torture_ops srcu_sync_ops = {
- .init = srcu_torture_init,
- .cleanup = srcu_torture_cleanup,
+ .init = rcu_sync_torture_init,
.readlock = srcu_torture_read_lock,
.read_delay = srcu_read_delay,
.readunlock = srcu_torture_read_unlock,
@@ -712,8 +691,7 @@ static void srcu_torture_read_unlock_raw(int idx) __releases(&srcu_ctl)
}
static struct rcu_torture_ops srcu_raw_ops = {
- .init = srcu_torture_init,
- .cleanup = srcu_torture_cleanup,
+ .init = rcu_sync_torture_init,
.readlock = srcu_torture_read_lock_raw,
.read_delay = srcu_read_delay,
.readunlock = srcu_torture_read_unlock_raw,
@@ -727,8 +705,7 @@ static struct rcu_torture_ops srcu_raw_ops = {
};
static struct rcu_torture_ops srcu_raw_sync_ops = {
- .init = srcu_torture_init,
- .cleanup = srcu_torture_cleanup,
+ .init = rcu_sync_torture_init,
.readlock = srcu_torture_read_lock_raw,
.read_delay = srcu_read_delay,
.readunlock = srcu_torture_read_unlock_raw,
@@ -747,8 +724,7 @@ static void srcu_torture_synchronize_expedited(void)
}
static struct rcu_torture_ops srcu_expedited_ops = {
- .init = srcu_torture_init,
- .cleanup = srcu_torture_cleanup,
+ .init = rcu_sync_torture_init,
.readlock = srcu_torture_read_lock,
.read_delay = srcu_read_delay,
.readunlock = srcu_torture_read_unlock,
@@ -783,7 +759,6 @@ static void rcu_sched_torture_deferred_free(struct rcu_torture *p)
static struct rcu_torture_ops sched_ops = {
.init = rcu_sync_torture_init,
- .cleanup = NULL,
.readlock = sched_torture_read_lock,
.read_delay = rcu_read_delay, /* just reuse rcu's version. */
.readunlock = sched_torture_read_unlock,
@@ -799,7 +774,6 @@ static struct rcu_torture_ops sched_ops = {
static struct rcu_torture_ops sched_sync_ops = {
.init = rcu_sync_torture_init,
- .cleanup = NULL,
.readlock = sched_torture_read_lock,
.read_delay = rcu_read_delay, /* just reuse rcu's version. */
.readunlock = sched_torture_read_unlock,
@@ -814,7 +788,6 @@ static struct rcu_torture_ops sched_sync_ops = {
static struct rcu_torture_ops sched_expedited_ops = {
.init = rcu_sync_torture_init,
- .cleanup = NULL,
.readlock = sched_torture_read_lock,
.read_delay = rcu_read_delay, /* just reuse rcu's version. */
.readunlock = sched_torture_read_unlock,
@@ -1396,12 +1369,16 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, char *tag)
"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);
}
@@ -1502,6 +1479,7 @@ rcu_torture_onoff(void *arg)
unsigned long delta;
int maxcpu = -1;
DEFINE_RCU_RANDOM(rand);
+ int ret;
unsigned long starttime;
VERBOSE_PRINTK_STRING("rcu_torture_onoff task started");
@@ -1522,7 +1500,13 @@ rcu_torture_onoff(void *arg)
torture_type, cpu);
starttime = jiffies;
n_offline_attempts++;
- if (cpu_down(cpu) == 0) {
+ 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",
@@ -1936,8 +1920,6 @@ rcu_torture_cleanup(void)
rcu_torture_stats_print(); /* -After- the stats thread is stopped! */
- if (cur_ops->cleanup)
- cur_ops->cleanup();
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 ||
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 74df86bd920..e441b77b614 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -68,9 +68,9 @@ static struct lock_class_key rcu_fqs_class[RCU_NUM_LVLS];
.level = { &sname##_state.node[0] }, \
.call = cr, \
.fqs_state = RCU_GP_IDLE, \
- .gpnum = -300, \
- .completed = -300, \
- .onofflock = __RAW_SPIN_LOCK_UNLOCKED(&sname##_state.onofflock), \
+ .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), \
@@ -207,18 +207,15 @@ 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),
-#if defined(CONFIG_RCU_USER_QS) && !defined(CONFIG_RCU_USER_QS_FORCE)
- .ignore_user_qs = true,
-#endif
};
-static int blimit = 10; /* Maximum callbacks per rcu_do_batch. */
-static int qhimark = 10000; /* If this many pending, ignore blimit. */
-static int qlowmark = 100; /* Once only this many pending, use blimit. */
+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, int, 0444);
-module_param(qhimark, int, 0444);
-module_param(qlowmark, int, 0444);
+module_param(blimit, long, 0444);
+module_param(qhimark, long, 0444);
+module_param(qlowmark, long, 0444);
int rcu_cpu_stall_suppress __read_mostly; /* 1 = suppress stall warnings. */
int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT;
@@ -303,7 +300,8 @@ EXPORT_SYMBOL_GPL(rcu_sched_force_quiescent_state);
static int
cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp)
{
- return &rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL];
+ return &rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL] &&
+ rdp->nxttail[RCU_DONE_TAIL] != NULL;
}
/*
@@ -312,8 +310,11 @@ cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp)
static int
cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp)
{
- return *rdp->nxttail[RCU_DONE_TAIL +
- ACCESS_ONCE(rsp->completed) != rdp->completed] &&
+ struct rcu_head **ntp;
+
+ ntp = rdp->nxttail[RCU_DONE_TAIL +
+ (ACCESS_ONCE(rsp->completed) != rdp->completed)];
+ return rdp->nxttail[RCU_DONE_TAIL] && ntp && *ntp &&
!rcu_gp_in_progress(rsp);
}
@@ -416,29 +417,7 @@ EXPORT_SYMBOL_GPL(rcu_idle_enter);
*/
void rcu_user_enter(void)
{
- unsigned long flags;
- struct rcu_dynticks *rdtp;
-
- /*
- * Some contexts may involve an exception occuring in an irq,
- * leading to that nesting:
- * rcu_irq_enter() rcu_user_exit() rcu_user_exit() rcu_irq_exit()
- * This would mess up the dyntick_nesting count though. And rcu_irq_*()
- * helpers are enough to protect RCU uses inside the exception. So
- * just return immediately if we detect we are in an IRQ.
- */
- if (in_interrupt())
- return;
-
- WARN_ON_ONCE(!current->mm);
-
- local_irq_save(flags);
- rdtp = &__get_cpu_var(rcu_dynticks);
- if (!rdtp->ignore_user_qs && !rdtp->in_user) {
- rdtp->in_user = true;
- rcu_eqs_enter(true);
- }
- local_irq_restore(flags);
+ rcu_eqs_enter(1);
}
/**
@@ -575,27 +554,7 @@ EXPORT_SYMBOL_GPL(rcu_idle_exit);
*/
void rcu_user_exit(void)
{
- unsigned long flags;
- struct rcu_dynticks *rdtp;
-
- /*
- * Some contexts may involve an exception occuring in an irq,
- * leading to that nesting:
- * rcu_irq_enter() rcu_user_exit() rcu_user_exit() rcu_irq_exit()
- * This would mess up the dyntick_nesting count though. And rcu_irq_*()
- * helpers are enough to protect RCU uses inside the exception. So
- * just return immediately if we detect we are in an IRQ.
- */
- if (in_interrupt())
- return;
-
- local_irq_save(flags);
- rdtp = &__get_cpu_var(rcu_dynticks);
- if (rdtp->in_user) {
- rdtp->in_user = false;
- rcu_eqs_exit(true);
- }
- local_irq_restore(flags);
+ rcu_eqs_exit(1);
}
/**
@@ -718,21 +677,6 @@ int rcu_is_cpu_idle(void)
}
EXPORT_SYMBOL(rcu_is_cpu_idle);
-#ifdef CONFIG_RCU_USER_QS
-void rcu_user_hooks_switch(struct task_struct *prev,
- struct task_struct *next)
-{
- struct rcu_dynticks *rdtp;
-
- /* Interrupts are disabled in context switch */
- rdtp = &__get_cpu_var(rcu_dynticks);
- if (!rdtp->ignore_user_qs) {
- clear_tsk_thread_flag(prev, TIF_NOHZ);
- set_tsk_thread_flag(next, TIF_NOHZ);
- }
-}
-#endif /* #ifdef CONFIG_RCU_USER_QS */
-
#if defined(CONFIG_PROVE_RCU) && defined(CONFIG_HOTPLUG_CPU)
/*
@@ -873,6 +817,29 @@ static void record_gp_stall_check_time(struct rcu_state *rsp)
rsp->jiffies_stall = jiffies + 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;
@@ -880,6 +847,7 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
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. */
@@ -924,12 +892,15 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
raw_spin_unlock_irqrestore(&rnp->lock, flags);
print_cpu_stall_info_end();
- printk(KERN_CONT "(detected by %d, t=%ld jiffies)\n",
- smp_processor_id(), (long)(jiffies - rsp->gp_start));
+ 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)
printk(KERN_ERR "INFO: Stall ended before state dump start\n");
else if (!trigger_all_cpu_backtrace())
- dump_stack();
+ rcu_dump_cpu_stacks(rsp);
/* Complain about tasks blocking the grace period. */
@@ -940,8 +911,10 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
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...
@@ -952,7 +925,10 @@ static void print_cpu_stall(struct rcu_state *rsp)
print_cpu_stall_info_begin();
print_cpu_stall_info(rsp, smp_processor_id());
print_cpu_stall_info_end();
- printk(KERN_CONT " (t=%lu jiffies)\n", jiffies - rsp->gp_start);
+ 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();
@@ -1091,6 +1067,7 @@ static void init_callback_list(struct rcu_data *rdp)
rdp->nxtlist = NULL;
for (i = 0; i < RCU_NEXT_SIZE; i++)
rdp->nxttail[i] = &rdp->nxtlist;
+ init_nocb_callback_list(rdp);
}
/*
@@ -1404,15 +1381,37 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
!cpu_needs_another_gp(rsp, rdp)) {
/*
* Either we have not yet spawned the grace-period
- * task or this CPU does not need another 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.
*/
raw_spin_unlock_irqrestore(&rnp->lock, flags);
return;
}
+ /*
+ * Because 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. So promote all callbacks to be
+ * handled after the end of the next grace period. If the
+ * CPU is not yet aware of the end of the previous grace period,
+ * we need to allow for the callback advancement that will
+ * occur when it does become aware. Deadlock prevents us from
+ * making it aware at this point: We cannot acquire a leaf
+ * rcu_node ->lock while holding the root rcu_node ->lock.
+ */
+ rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
+ if (rdp->completed == rsp->completed)
+ rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
+
rsp->gp_flags = RCU_GP_FLAG_INIT;
- raw_spin_unlock_irqrestore(&rnp->lock, flags);
+ raw_spin_unlock(&rnp->lock); /* Interrupts remain disabled. */
+
+ /* Ensure that CPU is aware of completion of last grace period. */
+ rcu_process_gp_end(rsp, rdp);
+ local_irq_restore(flags);
+
+ /* Wake up rcu_gp_kthread() to start the grace period. */
wake_up(&rsp->gp_wq);
}
@@ -1573,16 +1572,20 @@ rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp)
/*
* Send the specified CPU's RCU callbacks to the orphanage. The
* specified CPU must be offline, and the caller must hold the
- * ->onofflock.
+ * ->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 (is_nocb_cpu(rdp->cpu))
+ return;
+
/*
* Orphan the callbacks. First adjust the counts. This is safe
- * because ->onofflock excludes _rcu_barrier()'s adoption of
- * the callbacks, thus no memory barrier is required.
+ * 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;
@@ -1623,13 +1626,17 @@ rcu_send_cbs_to_orphanage(int cpu, struct rcu_state *rsp,
/*
* Adopt the RCU callbacks from the specified rcu_state structure's
- * orphanage. The caller must hold the ->onofflock.
+ * 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;
@@ -1702,7 +1709,7 @@ static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp)
/* Exclude any attempts to start a new grace period. */
mutex_lock(&rsp->onoff_mutex);
- raw_spin_lock_irqsave(&rsp->onofflock, flags);
+ 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);
@@ -1729,10 +1736,10 @@ static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp)
/*
* 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 ->onofflock
+ * because invoking rcu_report_unblock_qs_rnp() with ->orphan_lock
* held leads to deadlock.
*/
- raw_spin_unlock(&rsp->onofflock); /* irqs remain disabled. */
+ 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);
@@ -1769,7 +1776,8 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
{
unsigned long flags;
struct rcu_head *next, *list, **tail;
- int bl, count, count_lazy, i;
+ long bl, count, count_lazy;
+ int i;
/* If no callbacks are ready, just return.*/
if (!cpu_has_callbacks_ready_to_invoke(rdp)) {
@@ -2107,9 +2115,15 @@ static void __call_rcu_core(struct rcu_state *rsp, struct rcu_data *rdp,
}
}
+/*
+ * 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, bool lazy)
+ struct rcu_state *rsp, int cpu, bool lazy)
{
unsigned long flags;
struct rcu_data *rdp;
@@ -2129,9 +2143,14 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
rdp = this_cpu_ptr(rsp->rda);
/* Add the callback to our list. */
- if (unlikely(rdp->nxttail[RCU_NEXT_TAIL] == NULL)) {
+ 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. */
- WARN_ON_ONCE(1);
local_irq_restore(flags);
return;
}
@@ -2160,7 +2179,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
*/
void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
{
- __call_rcu(head, func, &rcu_sched_state, 0);
+ __call_rcu(head, func, &rcu_sched_state, -1, 0);
}
EXPORT_SYMBOL_GPL(call_rcu_sched);
@@ -2169,7 +2188,7 @@ EXPORT_SYMBOL_GPL(call_rcu_sched);
*/
void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
{
- __call_rcu(head, func, &rcu_bh_state, 0);
+ __call_rcu(head, func, &rcu_bh_state, -1, 0);
}
EXPORT_SYMBOL_GPL(call_rcu_bh);
@@ -2205,10 +2224,28 @@ static inline int rcu_blocking_is_gp(void)
* rcu_read_lock_sched().
*
* This means that all preempt_disable code sequences, including NMI and
- * 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.
+ * 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
@@ -2224,7 +2261,10 @@ void synchronize_sched(void)
"Illegal synchronize_sched() in RCU-sched read-side critical section");
if (rcu_blocking_is_gp())
return;
- wait_rcu_gp(call_rcu_sched);
+ if (rcu_expedited)
+ synchronize_sched_expedited();
+ else
+ wait_rcu_gp(call_rcu_sched);
}
EXPORT_SYMBOL_GPL(synchronize_sched);
@@ -2236,6 +2276,9 @@ EXPORT_SYMBOL_GPL(synchronize_sched);
* 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)
{
@@ -2245,13 +2288,13 @@ void synchronize_rcu_bh(void)
"Illegal synchronize_rcu_bh() in RCU-bh read-side critical section");
if (rcu_blocking_is_gp())
return;
- wait_rcu_gp(call_rcu_bh);
+ if (rcu_expedited)
+ synchronize_rcu_bh_expedited();
+ else
+ wait_rcu_gp(call_rcu_bh);
}
EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
-static atomic_t sync_sched_expedited_started = ATOMIC_INIT(0);
-static atomic_t sync_sched_expedited_done = ATOMIC_INIT(0);
-
static int synchronize_sched_expedited_cpu_stop(void *data)
{
/*
@@ -2308,10 +2351,32 @@ static int synchronize_sched_expedited_cpu_stop(void *data)
*/
void synchronize_sched_expedited(void)
{
- int firstsnap, s, snap, trycount = 0;
+ 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;
+ }
- /* Note that atomic_inc_return() implies full memory barrier. */
- firstsnap = snap = atomic_inc_return(&sync_sched_expedited_started);
+ /*
+ * 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()));
@@ -2323,48 +2388,65 @@ void synchronize_sched_expedited(void)
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 {
- synchronize_sched();
+ wait_rcu_gp(call_rcu_sched);
+ atomic_long_inc(&rsp->expedited_normal);
return;
}
- /* Check to see if someone else did our work for us. */
- s = atomic_read(&sync_sched_expedited_done);
- if (UINT_CMP_GE((unsigned)s, (unsigned)firstsnap)) {
- smp_mb(); /* ensure test happens before caller kfree */
+ /* 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 subtract
- * 1 to get the same token that the last incrementer got.
- * 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.
+ * 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_read(&sync_sched_expedited_started);
+ 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 beat us to the punch.
+ * than we did already did their update.
*/
do {
- s = atomic_read(&sync_sched_expedited_done);
- if (UINT_CMP_GE((unsigned)s, (unsigned)snap)) {
- smp_mb(); /* ensure test happens before caller kfree */
+ 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_cmpxchg(&sync_sched_expedited_done, s, snap) != s);
+ } while (atomic_long_cmpxchg(&rsp->expedited_done, s, snap) != s);
+ atomic_long_inc(&rsp->expedited_done_exit);
put_online_cpus();
}
@@ -2558,9 +2640,17 @@ static void _rcu_barrier(struct rcu_state *rsp)
* When that callback is invoked, we will know that all of the
* corresponding CPU's preceding callbacks have been invoked.
*/
- for_each_online_cpu(cpu) {
+ for_each_possible_cpu(cpu) {
+ if (!cpu_online(cpu) && !is_nocb_cpu(cpu))
+ continue;
rdp = per_cpu_ptr(rsp->rda, cpu);
- if (ACCESS_ONCE(rdp->qlen)) {
+ if (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);
@@ -2634,6 +2724,7 @@ rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp)
#endif
rdp->cpu = cpu;
rdp->rsp = rsp;
+ rcu_boot_init_nocb_percpu_data(rdp);
raw_spin_unlock_irqrestore(&rnp->lock, flags);
}
@@ -2715,6 +2806,7 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu);
struct rcu_node *rnp = rdp->mynode;
struct rcu_state *rsp;
+ int ret = NOTIFY_OK;
trace_rcu_utilization("Start CPU hotplug");
switch (action) {
@@ -2728,7 +2820,10 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
rcu_boost_kthread_setaffinity(rnp, -1);
break;
case CPU_DOWN_PREPARE:
- rcu_boost_kthread_setaffinity(rnp, cpu);
+ if (nocb_cpu_expendable(cpu))
+ rcu_boost_kthread_setaffinity(rnp, cpu);
+ else
+ ret = NOTIFY_BAD;
break;
case CPU_DYING:
case CPU_DYING_FROZEN:
@@ -2752,7 +2847,7 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
break;
}
trace_rcu_utilization("End CPU hotplug");
- return NOTIFY_OK;
+ return ret;
}
/*
@@ -2772,6 +2867,7 @@ static int __init rcu_spawn_gp_kthread(void)
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;
}
@@ -2967,6 +3063,7 @@ void __init rcu_init(void)
rcu_init_one(&rcu_sched_state, &rcu_sched_data);
rcu_init_one(&rcu_bh_state, &rcu_bh_data);
__rcu_init_preempt();
+ rcu_init_nocb();
open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
/*
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
index a240f032848..4b69291b093 100644
--- a/kernel/rcutree.h
+++ b/kernel/rcutree.h
@@ -287,6 +287,7 @@ struct rcu_data {
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;
@@ -317,6 +318,18 @@ struct rcu_data {
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 */
+
int cpu;
struct rcu_state *rsp;
};
@@ -369,6 +382,12 @@ struct rcu_state {
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));
+#ifdef CONFIG_RCU_NOCB_CPU
+ void (*call_remote)(struct rcu_head *head,
+ void (*func)(struct rcu_head *head));
+ /* call_rcu() flavor, but for */
+ /* placing on remote CPU. */
+#endif /* #ifdef CONFIG_RCU_NOCB_CPU */
/* The following fields are guarded by the root rcu_node's lock. */
@@ -383,9 +402,8 @@ struct rcu_state {
/* End of fields guarded by root rcu_node's lock. */
- raw_spinlock_t onofflock ____cacheline_internodealigned_in_smp;
- /* exclude on/offline and */
- /* starting new GP. */
+ 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. */
@@ -394,7 +412,7 @@ struct rcu_state {
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 onofflock. */
+ /* End of fields guarded by orphan_lock. */
struct mutex onoff_mutex; /* Coordinate hotplug & GPs. */
@@ -405,6 +423,18 @@ struct rcu_state {
/* _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 */
@@ -428,6 +458,8 @@ struct rcu_state {
#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)
@@ -504,5 +536,32 @@ 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 bool is_nocb_cpu(int cpu);
+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 bool nocb_cpu_expendable(int cpu);
+static void rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp);
+static void rcu_spawn_nocb_kthreads(struct rcu_state *rsp);
+static void init_nocb_callback_list(struct rcu_data *rdp);
+static void __init rcu_init_nocb(void);
#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
index f9211548818..f6e5ec2932b 100644
--- a/kernel/rcutree_plugin.h
+++ b/kernel/rcutree_plugin.h
@@ -25,6 +25,7 @@
*/
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <linux/oom.h>
#include <linux/smpboot.h>
@@ -36,6 +37,14 @@
#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 rcu_nocb_poll; /* Offload kthread are to poll. */
+module_param(rcu_nocb_poll, bool, 0444);
+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
@@ -76,6 +85,18 @@ static void __init rcu_bootup_announce_oddness(void)
printk(KERN_INFO "\tExperimental boot-time adjustment of leaf fanout to %d.\n", rcu_fanout_leaf);
if (nr_cpu_ids != NR_CPUS)
printk(KERN_INFO "\tRCU restricting CPUs from NR_CPUS=%d to nr_cpu_ids=%d.\n", NR_CPUS, nr_cpu_ids);
+#ifdef CONFIG_RCU_NOCB_CPU
+ if (have_rcu_nocb_mask) {
+ if (cpumask_test_cpu(0, rcu_nocb_mask)) {
+ cpumask_clear_cpu(0, rcu_nocb_mask);
+ pr_info("\tCPU 0: illegal no-CBs CPU (cleared).\n");
+ }
+ cpulist_scnprintf(nocb_buf, sizeof(nocb_buf), rcu_nocb_mask);
+ pr_info("\tExperimental no-CBs CPUs: %s.\n", nocb_buf);
+ if (rcu_nocb_poll)
+ pr_info("\tExperimental polled no-CBs CPUs.\n");
+ }
+#endif /* #ifdef CONFIG_RCU_NOCB_CPU */
}
#ifdef CONFIG_TREE_PREEMPT_RCU
@@ -642,7 +663,7 @@ static void rcu_preempt_do_callbacks(void)
*/
void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
{
- __call_rcu(head, func, &rcu_preempt_state, 0);
+ __call_rcu(head, func, &rcu_preempt_state, -1, 0);
}
EXPORT_SYMBOL_GPL(call_rcu);
@@ -656,7 +677,7 @@ EXPORT_SYMBOL_GPL(call_rcu);
void kfree_call_rcu(struct rcu_head *head,
void (*func)(struct rcu_head *rcu))
{
- __call_rcu(head, func, &rcu_preempt_state, 1);
+ __call_rcu(head, func, &rcu_preempt_state, -1, 1);
}
EXPORT_SYMBOL_GPL(kfree_call_rcu);
@@ -670,6 +691,9 @@ EXPORT_SYMBOL_GPL(kfree_call_rcu);
* 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)
{
@@ -679,7 +703,10 @@ void synchronize_rcu(void)
"Illegal synchronize_rcu() in RCU read-side critical section");
if (!rcu_scheduler_active)
return;
- wait_rcu_gp(call_rcu);
+ if (rcu_expedited)
+ synchronize_rcu_expedited();
+ else
+ wait_rcu_gp(call_rcu);
}
EXPORT_SYMBOL_GPL(synchronize_rcu);
@@ -757,7 +784,8 @@ static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp,
* 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 rsp->onofflock.
+ * 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)
@@ -831,7 +859,7 @@ void synchronize_rcu_expedited(void)
udelay(trycount * num_online_cpus());
} else {
put_online_cpus();
- synchronize_rcu();
+ wait_rcu_gp(call_rcu);
return;
}
}
@@ -875,6 +903,11 @@ 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)
{
@@ -1013,7 +1046,7 @@ static void rcu_preempt_check_callbacks(int cpu)
void kfree_call_rcu(struct rcu_head *head,
void (*func)(struct rcu_head *rcu))
{
- __call_rcu(head, func, &rcu_sched_state, 1);
+ __call_rcu(head, func, &rcu_sched_state, -1, 1);
}
EXPORT_SYMBOL_GPL(kfree_call_rcu);
@@ -2092,3 +2125,373 @@ 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);
+
+/* Is the specified CPU a no-CPUs CPU? */
+static bool 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 (!is_nocb_cpu(rdp->cpu))
+ return 0;
+ __call_rcu_nocb_enqueue(rdp, rhp, &rhp->next, 1, lazy);
+ 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 (!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;
+}
+
+/*
+ * There must be at least one non-no-CBs CPU in operation at any given
+ * time, because no-CBs CPUs are not capable of initiating grace periods
+ * independently. This function therefore complains if the specified
+ * CPU is the last non-no-CBs CPU, allowing the CPU-hotplug system to
+ * avoid offlining the last such CPU. (Recursion is a wonderful thing,
+ * but you have to have a base case!)
+ */
+static bool nocb_cpu_expendable(int cpu)
+{
+ cpumask_var_t non_nocb_cpus;
+ int ret;
+
+ /*
+ * If there are no no-CB CPUs or if this CPU is not a no-CB CPU,
+ * then offlining this CPU is harmless. Let it happen.
+ */
+ if (!have_rcu_nocb_mask || is_nocb_cpu(cpu))
+ return 1;
+
+ /* If no memory, play it safe and keep the CPU around. */
+ if (!alloc_cpumask_var(&non_nocb_cpus, GFP_NOIO))
+ return 0;
+ cpumask_andnot(non_nocb_cpus, cpu_online_mask, rcu_nocb_mask);
+ cpumask_clear_cpu(cpu, non_nocb_cpus);
+ ret = !cpumask_empty(non_nocb_cpus);
+ free_cpumask_var(non_nocb_cpus);
+ return ret;
+}
+
+/*
+ * Helper structure for remote registry of RCU callbacks.
+ * This is needed for when a no-CBs CPU needs to start a grace period.
+ * If it just invokes call_rcu(), the resulting callback will be queued,
+ * which can result in deadlock.
+ */
+struct rcu_head_remote {
+ struct rcu_head *rhp;
+ call_rcu_func_t *crf;
+ void (*func)(struct rcu_head *rhp);
+};
+
+/*
+ * Register a callback as specified by the rcu_head_remote struct.
+ * This function is intended to be invoked via smp_call_function_single().
+ */
+static void call_rcu_local(void *arg)
+{
+ struct rcu_head_remote *rhrp =
+ container_of(arg, struct rcu_head_remote, rhp);
+
+ rhrp->crf(rhrp->rhp, rhrp->func);
+}
+
+/*
+ * Set up an rcu_head_remote structure and the invoke call_rcu_local()
+ * on CPU 0 (which is guaranteed to be a non-no-CBs CPU) via
+ * smp_call_function_single().
+ */
+static void invoke_crf_remote(struct rcu_head *rhp,
+ void (*func)(struct rcu_head *rhp),
+ call_rcu_func_t crf)
+{
+ struct rcu_head_remote rhr;
+
+ rhr.rhp = rhp;
+ rhr.crf = crf;
+ rhr.func = func;
+ smp_call_function_single(0, call_rcu_local, &rhr, 1);
+}
+
+/*
+ * Helper functions to be passed to wait_rcu_gp(), each of which
+ * invokes invoke_crf_remote() to register a callback appropriately.
+ */
+static void __maybe_unused
+call_rcu_preempt_remote(struct rcu_head *rhp,
+ void (*func)(struct rcu_head *rhp))
+{
+ invoke_crf_remote(rhp, func, call_rcu);
+}
+static void call_rcu_bh_remote(struct rcu_head *rhp,
+ void (*func)(struct rcu_head *rhp))
+{
+ invoke_crf_remote(rhp, func, call_rcu_bh);
+}
+static void call_rcu_sched_remote(struct rcu_head *rhp,
+ void (*func)(struct rcu_head *rhp))
+{
+ invoke_crf_remote(rhp, func, call_rcu_sched);
+}
+
+/*
+ * 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(rdp->nocb_wq, rdp->nocb_head);
+ list = ACCESS_ONCE(rdp->nocb_head);
+ if (!list) {
+ schedule_timeout_interruptible(1);
+ 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;
+ wait_rcu_gp(rdp->rsp->call_remote);
+
+ /* 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%d", cpu);
+ BUG_ON(IS_ERR(t));
+ ACCESS_ONCE(rdp->nocb_kthread) = t;
+ }
+}
+
+/* Prevent __call_rcu() from enqueuing callbacks on no-CBs CPUs */
+static void init_nocb_callback_list(struct rcu_data *rdp)
+{
+ if (rcu_nocb_mask == NULL ||
+ !cpumask_test_cpu(rdp->cpu, rcu_nocb_mask))
+ return;
+ rdp->nxttail[RCU_NEXT_TAIL] = NULL;
+}
+
+/* Initialize the ->call_remote fields in the rcu_state structures. */
+static void __init rcu_init_nocb(void)
+{
+#ifdef CONFIG_PREEMPT_RCU
+ rcu_preempt_state.call_remote = call_rcu_preempt_remote;
+#endif /* #ifdef CONFIG_PREEMPT_RCU */
+ rcu_bh_state.call_remote = call_rcu_bh_remote;
+ rcu_sched_state.call_remote = call_rcu_sched_remote;
+}
+
+#else /* #ifdef CONFIG_RCU_NOCB_CPU */
+
+static bool is_nocb_cpu(int cpu)
+{
+ return false;
+}
+
+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 bool nocb_cpu_expendable(int cpu)
+{
+ return 1;
+}
+
+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 void init_nocb_callback_list(struct rcu_data *rdp)
+{
+}
+
+static void __init rcu_init_nocb(void)
+{
+}
+
+#endif /* #else #ifdef CONFIG_RCU_NOCB_CPU */
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c
index 693513bc50e..0d095dcaa67 100644
--- a/kernel/rcutree_trace.c
+++ b/kernel/rcutree_trace.c
@@ -46,29 +46,58 @@
#define RCU_TREE_NONCORE
#include "rcutree.h"
-static int show_rcubarrier(struct seq_file *m, void *unused)
+#define ulong2long(a) (*(long *)(&(a)))
+
+static int r_open(struct inode *inode, struct file *file,
+ const struct seq_operations *op)
{
- struct rcu_state *rsp;
+ 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;
+}
- for_each_rcu_flavor(rsp)
- seq_printf(m, "%s: bcc: %d nbd: %lu\n",
- rsp->name,
- atomic_read(&rsp->barrier_cpu_count),
- rsp->n_barrier_done);
+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, NULL);
+ 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 = seq_lseek,
- .release = single_release,
+ .llseek = no_llseek,
+ .release = seq_release,
};
#ifdef CONFIG_RCU_BOOST
@@ -84,12 +113,14 @@ static char convert_kthread_status(unsigned int kthread_status)
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=%lu g=%lu pq=%d qp=%d",
+ seq_printf(m, "%3d%cc=%ld g=%ld pq=%d qp=%d",
rdp->cpu,
cpu_is_offline(rdp->cpu) ? '!' : ' ',
- rdp->completed, rdp->gpnum,
+ 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),
@@ -97,8 +128,11 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
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",
- rdp->qlen_lazy, rdp->qlen,
+ qll, ql,
".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] !=
rdp->nxttail[RCU_NEXT_TAIL]],
".R"[rdp->nxttail[RCU_WAIT_TAIL] !=
@@ -114,101 +148,67 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
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 co=%lu ca=%lu\n",
- rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted);
+ 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 *unused)
+static int show_rcudata(struct seq_file *m, void *v)
{
- int cpu;
- struct rcu_state *rsp;
-
- for_each_rcu_flavor(rsp) {
- seq_printf(m, "%s:\n", rsp->name);
- for_each_possible_cpu(cpu)
- print_one_rcu_data(m, per_cpu_ptr(rsp->rda, cpu));
- }
+ 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 single_open(file, show_rcudata, NULL);
+ return r_open(inode, file, &rcudate_op);
}
static const struct file_operations rcudata_fops = {
.owner = THIS_MODULE,
.open = rcudata_open,
.read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .llseek = no_llseek,
+ .release = seq_release,
};
-static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp)
-{
- if (!rdp->beenonline)
- return;
- seq_printf(m, "%d,%s,%lu,%lu,%d,%d",
- rdp->cpu,
- cpu_is_offline(rdp->cpu) ? "\"N\"" : "\"Y\"",
- rdp->completed, rdp->gpnum,
- rdp->passed_quiesce, rdp->qs_pending);
- seq_printf(m, ",%d,%llx,%d,%lu",
- atomic_read(&rdp->dynticks->dynticks),
- rdp->dynticks->dynticks_nesting,
- rdp->dynticks->dynticks_nmi_nesting,
- rdp->dynticks_fqs);
- seq_printf(m, ",%lu", rdp->offline_fqs);
- seq_printf(m, ",%ld,%ld,\"%c%c%c%c\"", rdp->qlen_lazy, rdp->qlen,
- ".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, ",%d,\"%c\"",
- per_cpu(rcu_cpu_has_work, rdp->cpu),
- convert_kthread_status(per_cpu(rcu_cpu_kthread_status,
- rdp->cpu)));
-#endif /* #ifdef CONFIG_RCU_BOOST */
- seq_printf(m, ",%ld", rdp->blimit);
- seq_printf(m, ",%lu,%lu,%lu\n",
- rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted);
-}
-
-static int show_rcudata_csv(struct seq_file *m, void *unused)
+static int show_rcuexp(struct seq_file *m, void *v)
{
- int cpu;
- struct rcu_state *rsp;
-
- seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pq\",");
- seq_puts(m, "\"dt\",\"dt nesting\",\"dt NMI nesting\",\"df\",");
- seq_puts(m, "\"of\",\"qll\",\"ql\",\"qs\"");
-#ifdef CONFIG_RCU_BOOST
- seq_puts(m, "\"kt\",\"ktl\"");
-#endif /* #ifdef CONFIG_RCU_BOOST */
- seq_puts(m, ",\"b\",\"ci\",\"co\",\"ca\"\n");
- for_each_rcu_flavor(rsp) {
- seq_printf(m, "\"%s:\"\n", rsp->name);
- for_each_possible_cpu(cpu)
- print_one_rcu_data_csv(m, per_cpu_ptr(rsp->rda, cpu));
- }
+ 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 rcudata_csv_open(struct inode *inode, struct file *file)
+static int rcuexp_open(struct inode *inode, struct file *file)
{
- return single_open(file, show_rcudata_csv, NULL);
+ return single_open(file, show_rcuexp, inode->i_private);
}
-static const struct file_operations rcudata_csv_fops = {
+static const struct file_operations rcuexp_fops = {
.owner = THIS_MODULE,
- .open = rcudata_csv_open,
+ .open = rcuexp_open,
.read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .llseek = no_llseek,
+ .release = seq_release,
};
#ifdef CONFIG_RCU_BOOST
@@ -254,27 +254,11 @@ static const struct file_operations rcu_node_boost_fops = {
.owner = THIS_MODULE,
.open = rcu_node_boost_open,
.read = seq_read,
- .llseek = seq_lseek,
+ .llseek = no_llseek,
.release = single_release,
};
-/*
- * Create the rcuboost debugfs entry. Standard error return.
- */
-static int rcu_boost_trace_create_file(struct dentry *rcudir)
-{
- return !debugfs_create_file("rcuboost", 0444, rcudir, NULL,
- &rcu_node_boost_fops);
-}
-
-#else /* #ifdef CONFIG_RCU_BOOST */
-
-static int rcu_boost_trace_create_file(struct dentry *rcudir)
-{
- return 0; /* There cannot be an error if we didn't create it! */
-}
-
-#endif /* #else #ifdef CONFIG_RCU_BOOST */
+#endif /* #ifdef CONFIG_RCU_BOOST */
static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
{
@@ -283,8 +267,9 @@ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
struct rcu_node *rnp;
gpnum = rsp->gpnum;
- seq_printf(m, "%s: c=%lu g=%lu s=%d jfq=%ld j=%x ",
- rsp->name, rsp->completed, gpnum, rsp->fqs_state,
+ 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",
@@ -306,26 +291,24 @@ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
seq_puts(m, "\n");
}
-static int show_rcuhier(struct seq_file *m, void *unused)
+static int show_rcuhier(struct seq_file *m, void *v)
{
- struct rcu_state *rsp;
-
- for_each_rcu_flavor(rsp)
- print_one_rcu_state(m, rsp);
+ 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, NULL);
+ 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 = seq_lseek,
- .release = single_release,
+ .llseek = no_llseek,
+ .release = seq_release,
};
static void show_one_rcugp(struct seq_file *m, struct rcu_state *rsp)
@@ -338,42 +321,42 @@ static void show_one_rcugp(struct seq_file *m, struct rcu_state *rsp)
struct rcu_node *rnp = &rsp->node[0];
raw_spin_lock_irqsave(&rnp->lock, flags);
- completed = rsp->completed;
- gpnum = rsp->gpnum;
- if (rsp->completed == rsp->gpnum)
+ 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, "%s: completed=%ld gpnum=%lu age=%ld max=%ld\n",
- rsp->name, completed, gpnum, gpage, gpmax);
+ 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 *unused)
+static int show_rcugp(struct seq_file *m, void *v)
{
- struct rcu_state *rsp;
-
- for_each_rcu_flavor(rsp)
- show_one_rcugp(m, rsp);
+ 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, NULL);
+ 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 = seq_lseek,
- .release = single_release,
+ .llseek = no_llseek,
+ .release = seq_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) ? '!' : ' ',
@@ -389,34 +372,30 @@ static void print_one_rcu_pending(struct seq_file *m, struct rcu_data *rdp)
rdp->n_rp_need_nothing);
}
-static int show_rcu_pending(struct seq_file *m, void *unused)
+static int show_rcu_pending(struct seq_file *m, void *v)
{
- int cpu;
- struct rcu_data *rdp;
- struct rcu_state *rsp;
-
- for_each_rcu_flavor(rsp) {
- seq_printf(m, "%s:\n", rsp->name);
- for_each_possible_cpu(cpu) {
- rdp = per_cpu_ptr(rsp->rda, cpu);
- if (rdp->beenonline)
- print_one_rcu_pending(m, rdp);
- }
- }
+ 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 single_open(file, show_rcu_pending, NULL);
+ 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 = seq_lseek,
- .release = single_release,
+ .llseek = no_llseek,
+ .release = seq_release,
};
static int show_rcutorture(struct seq_file *m, void *unused)
@@ -446,43 +425,58 @@ 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;
- retval = debugfs_create_file("rcubarrier", 0444, rcudir,
- NULL, &rcubarrier_fops);
- if (!retval)
- goto free_out;
-
- retval = debugfs_create_file("rcudata", 0444, rcudir,
- NULL, &rcudata_fops);
- if (!retval)
- goto free_out;
-
- retval = debugfs_create_file("rcudata.csv", 0444, rcudir,
- NULL, &rcudata_csv_fops);
- if (!retval)
- goto free_out;
-
- if (rcu_boost_trace_create_file(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;
- retval = debugfs_create_file("rcugp", 0444, rcudir, NULL, &rcugp_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("rcuhier", 0444, rcudir,
- NULL, &rcuhier_fops);
- if (!retval)
- goto free_out;
+ retval = debugfs_create_file("rcugp", 0444,
+ rspdir, rsp, &rcugp_fops);
+ if (!retval)
+ goto free_out;
- retval = debugfs_create_file("rcu_pending", 0444, rcudir,
- NULL, &rcu_pending_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);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 2d8927fda71..f5066a61f97 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -72,6 +72,7 @@
#include <linux/slab.h>
#include <linux/init_task.h>
#include <linux/binfmts.h>
+#include <linux/context_tracking.h>
#include <asm/switch_to.h>
#include <asm/tlb.h>
@@ -952,6 +953,8 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
trace_sched_migrate_task(p, new_cpu);
if (task_cpu(p) != new_cpu) {
+ if (p->sched_class->migrate_task_rq)
+ p->sched_class->migrate_task_rq(p, new_cpu);
p->se.nr_migrations++;
perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, 1, NULL, 0);
}
@@ -1524,6 +1527,15 @@ static void __sched_fork(struct task_struct *p)
p->se.vruntime = 0;
INIT_LIST_HEAD(&p->se.group_node);
+/*
+ * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be
+ * removed when useful for applications beyond shares distribution (e.g.
+ * load-balance).
+ */
+#if defined(CONFIG_SMP) && defined(CONFIG_FAIR_GROUP_SCHED)
+ p->se.avg.runnable_avg_period = 0;
+ p->se.avg.runnable_avg_sum = 0;
+#endif
#ifdef CONFIG_SCHEDSTATS
memset(&p->se.statistics, 0, sizeof(p->se.statistics));
#endif
@@ -1886,8 +1898,8 @@ context_switch(struct rq *rq, struct task_struct *prev,
spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
#endif
+ context_tracking_task_switch(prev, next);
/* Here we just switch the register state and the stack. */
- rcu_switch(prev, next);
switch_to(prev, next, prev);
barrier();
@@ -2911,7 +2923,7 @@ asmlinkage void __sched schedule(void)
}
EXPORT_SYMBOL(schedule);
-#ifdef CONFIG_RCU_USER_QS
+#ifdef CONFIG_CONTEXT_TRACKING
asmlinkage void __sched schedule_user(void)
{
/*
@@ -2920,9 +2932,9 @@ asmlinkage void __sched schedule_user(void)
* we haven't yet exited the RCU idle mode. Do it here manually until
* we find a better solution.
*/
- rcu_user_exit();
+ user_exit();
schedule();
- rcu_user_enter();
+ user_enter();
}
#endif
@@ -3027,7 +3039,7 @@ asmlinkage void __sched preempt_schedule_irq(void)
/* Catch callers which need to be fixed */
BUG_ON(ti->preempt_count || !irqs_disabled());
- rcu_user_exit();
+ user_exit();
do {
add_preempt_count(PREEMPT_ACTIVE);
local_irq_enable();
@@ -4474,6 +4486,7 @@ static const char stat_nam[] = TASK_STATE_TO_CHAR_STR;
void sched_show_task(struct task_struct *p)
{
unsigned long free = 0;
+ int ppid;
unsigned state;
state = p->state ? __ffs(p->state) + 1 : 0;
@@ -4493,8 +4506,11 @@ void sched_show_task(struct task_struct *p)
#ifdef CONFIG_DEBUG_STACK_USAGE
free = stack_not_used(p);
#endif
+ rcu_read_lock();
+ ppid = task_pid_nr(rcu_dereference(p->real_parent));
+ rcu_read_unlock();
printk(KERN_CONT "%5lu %5d %6d 0x%08lx\n", free,
- task_pid_nr(p), task_pid_nr(rcu_dereference(p->real_parent)),
+ task_pid_nr(p), ppid,
(unsigned long)task_thread_info(p)->flags);
show_stack(p, NULL);
@@ -8076,3 +8092,9 @@ struct cgroup_subsys cpuacct_subsys = {
.base_cftypes = files,
};
#endif /* CONFIG_CGROUP_CPUACCT */
+
+void dump_cpu_task(int cpu)
+{
+ pr_info("Task dump for CPU %d:\n", cpu);
+ sched_show_task(cpu_curr(cpu));
+}
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index 81b763ba58a..293b202fcf7 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -43,7 +43,7 @@ DEFINE_PER_CPU(seqcount_t, irq_time_seq);
* Called before incrementing preempt_count on {soft,}irq_enter
* and before decrementing preempt_count on {soft,}irq_exit.
*/
-void vtime_account(struct task_struct *curr)
+void irqtime_account_irq(struct task_struct *curr)
{
unsigned long flags;
s64 delta;
@@ -73,7 +73,7 @@ void vtime_account(struct task_struct *curr)
irq_time_write_end();
local_irq_restore(flags);
}
-EXPORT_SYMBOL_GPL(vtime_account);
+EXPORT_SYMBOL_GPL(irqtime_account_irq);
static int irqtime_account_hi_update(void)
{
@@ -288,6 +288,34 @@ static __always_inline bool steal_account_process_tick(void)
return false;
}
+/*
+ * Accumulate raw cputime values of dead tasks (sig->[us]time) and live
+ * tasks (sum on group iteration) belonging to @tsk's group.
+ */
+void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times)
+{
+ struct signal_struct *sig = tsk->signal;
+ struct task_struct *t;
+
+ times->utime = sig->utime;
+ times->stime = sig->stime;
+ times->sum_exec_runtime = sig->sum_sched_runtime;
+
+ rcu_read_lock();
+ /* make sure we can trust tsk->thread_group list */
+ if (!likely(pid_alive(tsk)))
+ goto out;
+
+ t = tsk;
+ do {
+ times->utime += t->utime;
+ times->stime += t->stime;
+ times->sum_exec_runtime += task_sched_runtime(t);
+ } while_each_thread(tsk, t);
+out:
+ rcu_read_unlock();
+}
+
#ifndef CONFIG_VIRT_CPU_ACCOUNTING
#ifdef CONFIG_IRQ_TIME_ACCOUNTING
@@ -417,13 +445,13 @@ void account_idle_ticks(unsigned long ticks)
* Use precise platform statistics if available:
*/
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
-void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
+void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st)
{
*ut = p->utime;
*st = p->stime;
}
-void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
+void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st)
{
struct task_cputime cputime;
@@ -433,6 +461,29 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
*st = cputime.stime;
}
+void vtime_account_system_irqsafe(struct task_struct *tsk)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ vtime_account_system(tsk);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(vtime_account_system_irqsafe);
+
+#ifndef __ARCH_HAS_VTIME_TASK_SWITCH
+void vtime_task_switch(struct task_struct *prev)
+{
+ if (is_idle_task(prev))
+ vtime_account_idle(prev);
+ else
+ vtime_account_system(prev);
+
+ vtime_account_user(prev);
+ arch_vtime_task_switch(prev);
+}
+#endif
+
/*
* Archs that account the whole time spent in the idle task
* (outside irq) as idle time can rely on this and just implement
@@ -444,16 +495,10 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
#ifndef __ARCH_HAS_VTIME_ACCOUNT
void vtime_account(struct task_struct *tsk)
{
- unsigned long flags;
-
- local_irq_save(flags);
-
if (in_interrupt() || !is_idle_task(tsk))
vtime_account_system(tsk);
else
vtime_account_idle(tsk);
-
- local_irq_restore(flags);
}
EXPORT_SYMBOL_GPL(vtime_account);
#endif /* __ARCH_HAS_VTIME_ACCOUNT */
@@ -478,14 +523,30 @@ static cputime_t scale_utime(cputime_t utime, cputime_t rtime, cputime_t total)
return (__force cputime_t) temp;
}
-void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
+/*
+ * Adjust tick based cputime random precision against scheduler
+ * runtime accounting.
+ */
+static void cputime_adjust(struct task_cputime *curr,
+ struct cputime *prev,
+ cputime_t *ut, cputime_t *st)
{
- cputime_t rtime, utime = p->utime, total = utime + p->stime;
+ cputime_t rtime, utime, total;
+
+ utime = curr->utime;
+ total = utime + curr->stime;
/*
- * Use CFS's precise accounting:
+ * Tick based cputime accounting depend on random scheduling
+ * timeslices of a task to be interrupted or not by the timer.
+ * Depending on these circumstances, the number of these interrupts
+ * may be over or under-optimistic, matching the real user and system
+ * cputime with a variable precision.
+ *
+ * Fix this by scaling these tick based values against the total
+ * runtime accounted by the CFS scheduler.
*/
- rtime = nsecs_to_cputime(p->se.sum_exec_runtime);
+ rtime = nsecs_to_cputime(curr->sum_exec_runtime);
if (total)
utime = scale_utime(utime, rtime, total);
@@ -493,38 +554,36 @@ void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
utime = rtime;
/*
- * Compare with previous values, to keep monotonicity:
+ * If the tick based count grows faster than the scheduler one,
+ * the result of the scaling may go backward.
+ * Let's enforce monotonicity.
*/
- p->prev_utime = max(p->prev_utime, utime);
- p->prev_stime = max(p->prev_stime, rtime - p->prev_utime);
+ prev->utime = max(prev->utime, utime);
+ prev->stime = max(prev->stime, rtime - prev->utime);
- *ut = p->prev_utime;
- *st = p->prev_stime;
+ *ut = prev->utime;
+ *st = prev->stime;
+}
+
+void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st)
+{
+ struct task_cputime cputime = {
+ .utime = p->utime,
+ .stime = p->stime,
+ .sum_exec_runtime = p->se.sum_exec_runtime,
+ };
+
+ cputime_adjust(&cputime, &p->prev_cputime, ut, st);
}
/*
* Must be called with siglock held.
*/
-void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
+void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st)
{
- struct signal_struct *sig = p->signal;
struct task_cputime cputime;
- cputime_t rtime, utime, total;
thread_group_cputime(p, &cputime);
-
- total = cputime.utime + cputime.stime;
- rtime = nsecs_to_cputime(cputime.sum_exec_runtime);
-
- if (total)
- utime = scale_utime(cputime.utime, rtime, total);
- else
- utime = rtime;
-
- sig->prev_utime = max(sig->prev_utime, utime);
- sig->prev_stime = max(sig->prev_stime, rtime - sig->prev_utime);
-
- *ut = sig->prev_utime;
- *st = sig->prev_stime;
+ cputime_adjust(&cputime, &p->signal->prev_cputime, ut, st);
}
#endif
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 6f79596e0ea..2cd3c1b4e58 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -61,14 +61,20 @@ static unsigned long nsec_low(unsigned long long nsec)
static void print_cfs_group_stats(struct seq_file *m, int cpu, struct task_group *tg)
{
struct sched_entity *se = tg->se[cpu];
- if (!se)
- return;
#define P(F) \
SEQ_printf(m, " .%-30s: %lld\n", #F, (long long)F)
#define PN(F) \
SEQ_printf(m, " .%-30s: %lld.%06ld\n", #F, SPLIT_NS((long long)F))
+ if (!se) {
+ struct sched_avg *avg = &cpu_rq(cpu)->avg;
+ P(avg->runnable_avg_sum);
+ P(avg->runnable_avg_period);
+ return;
+ }
+
+
PN(se->exec_start);
PN(se->vruntime);
PN(se->sum_exec_runtime);
@@ -85,6 +91,12 @@ static void print_cfs_group_stats(struct seq_file *m, int cpu, struct task_group
P(se->statistics.wait_count);
#endif
P(se->load.weight);
+#ifdef CONFIG_SMP
+ P(se->avg.runnable_avg_sum);
+ P(se->avg.runnable_avg_period);
+ P(se->avg.load_avg_contrib);
+ P(se->avg.decay_count);
+#endif
#undef PN
#undef P
}
@@ -206,14 +218,18 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
SEQ_printf(m, " .%-30s: %ld\n", "load", cfs_rq->load.weight);
#ifdef CONFIG_FAIR_GROUP_SCHED
#ifdef CONFIG_SMP
- SEQ_printf(m, " .%-30s: %Ld.%06ld\n", "load_avg",
- SPLIT_NS(cfs_rq->load_avg));
- SEQ_printf(m, " .%-30s: %Ld.%06ld\n", "load_period",
- SPLIT_NS(cfs_rq->load_period));
- SEQ_printf(m, " .%-30s: %ld\n", "load_contrib",
- cfs_rq->load_contribution);
- SEQ_printf(m, " .%-30s: %d\n", "load_tg",
- atomic_read(&cfs_rq->tg->load_weight));
+ SEQ_printf(m, " .%-30s: %lld\n", "runnable_load_avg",
+ cfs_rq->runnable_load_avg);
+ SEQ_printf(m, " .%-30s: %lld\n", "blocked_load_avg",
+ cfs_rq->blocked_load_avg);
+ SEQ_printf(m, " .%-30s: %ld\n", "tg_load_avg",
+ atomic64_read(&cfs_rq->tg->load_avg));
+ SEQ_printf(m, " .%-30s: %lld\n", "tg_load_contrib",
+ cfs_rq->tg_load_contrib);
+ SEQ_printf(m, " .%-30s: %d\n", "tg_runnable_contrib",
+ cfs_rq->tg_runnable_contrib);
+ SEQ_printf(m, " .%-30s: %d\n", "tg->runnable_avg",
+ atomic_read(&cfs_rq->tg->runnable_avg));
#endif
print_cfs_group_stats(m, cpu, cfs_rq->tg);
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 6b800a14b99..59e072b2db9 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -259,6 +259,9 @@ static inline struct cfs_rq *group_cfs_rq(struct sched_entity *grp)
return grp->my_q;
}
+static void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq,
+ int force_update);
+
static inline void list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
{
if (!cfs_rq->on_list) {
@@ -278,6 +281,8 @@ static inline void list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
}
cfs_rq->on_list = 1;
+ /* We should have no load, but we need to update last_decay. */
+ update_cfs_rq_blocked_load(cfs_rq, 0);
}
}
@@ -653,9 +658,6 @@ static u64 sched_vslice(struct cfs_rq *cfs_rq, struct sched_entity *se)
return calc_delta_fair(sched_slice(cfs_rq, se), se);
}
-static void update_cfs_load(struct cfs_rq *cfs_rq, int global_update);
-static void update_cfs_shares(struct cfs_rq *cfs_rq);
-
/*
* Update the current task's runtime statistics. Skip current tasks that
* are not in our scheduling class.
@@ -675,10 +677,6 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr,
curr->vruntime += delta_exec_weighted;
update_min_vruntime(cfs_rq);
-
-#if defined CONFIG_SMP && defined CONFIG_FAIR_GROUP_SCHED
- cfs_rq->load_unacc_exec_time += delta_exec;
-#endif
}
static void update_curr(struct cfs_rq *cfs_rq)
@@ -801,72 +799,7 @@ account_entity_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se)
}
#ifdef CONFIG_FAIR_GROUP_SCHED
-/* we need this in update_cfs_load and load-balance functions below */
-static inline int throttled_hierarchy(struct cfs_rq *cfs_rq);
# ifdef CONFIG_SMP
-static void update_cfs_rq_load_contribution(struct cfs_rq *cfs_rq,
- int global_update)
-{
- struct task_group *tg = cfs_rq->tg;
- long load_avg;
-
- load_avg = div64_u64(cfs_rq->load_avg, cfs_rq->load_period+1);
- load_avg -= cfs_rq->load_contribution;
-
- if (global_update || abs(load_avg) > cfs_rq->load_contribution / 8) {
- atomic_add(load_avg, &tg->load_weight);
- cfs_rq->load_contribution += load_avg;
- }
-}
-
-static void update_cfs_load(struct cfs_rq *cfs_rq, int global_update)
-{
- u64 period = sysctl_sched_shares_window;
- u64 now, delta;
- unsigned long load = cfs_rq->load.weight;
-
- if (cfs_rq->tg == &root_task_group || throttled_hierarchy(cfs_rq))
- return;
-
- now = rq_of(cfs_rq)->clock_task;
- delta = now - cfs_rq->load_stamp;
-
- /* truncate load history at 4 idle periods */
- if (cfs_rq->load_stamp > cfs_rq->load_last &&
- now - cfs_rq->load_last > 4 * period) {
- cfs_rq->load_period = 0;
- cfs_rq->load_avg = 0;
- delta = period - 1;
- }
-
- cfs_rq->load_stamp = now;
- cfs_rq->load_unacc_exec_time = 0;
- cfs_rq->load_period += delta;
- if (load) {
- cfs_rq->load_last = now;
- cfs_rq->load_avg += delta * load;
- }
-
- /* consider updating load contribution on each fold or truncate */
- if (global_update || cfs_rq->load_period > period
- || !cfs_rq->load_period)
- update_cfs_rq_load_contribution(cfs_rq, global_update);
-
- while (cfs_rq->load_period > period) {
- /*
- * Inline assembly required to prevent the compiler
- * optimising this loop into a divmod call.
- * See __iter_div_u64_rem() for another example of this.
- */
- asm("" : "+rm" (cfs_rq->load_period));
- cfs_rq->load_period /= 2;
- cfs_rq->load_avg /= 2;
- }
-
- if (!cfs_rq->curr && !cfs_rq->nr_running && !cfs_rq->load_avg)
- list_del_leaf_cfs_rq(cfs_rq);
-}
-
static inline long calc_tg_weight(struct task_group *tg, struct cfs_rq *cfs_rq)
{
long tg_weight;
@@ -876,8 +809,8 @@ static inline long calc_tg_weight(struct task_group *tg, struct cfs_rq *cfs_rq)
* to gain a more accurate current total weight. See
* update_cfs_rq_load_contribution().
*/
- tg_weight = atomic_read(&tg->load_weight);
- tg_weight -= cfs_rq->load_contribution;
+ tg_weight = atomic64_read(&tg->load_avg);
+ tg_weight -= cfs_rq->tg_load_contrib;
tg_weight += cfs_rq->load.weight;
return tg_weight;
@@ -901,27 +834,11 @@ static long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg)
return shares;
}
-
-static void update_entity_shares_tick(struct cfs_rq *cfs_rq)
-{
- if (cfs_rq->load_unacc_exec_time > sysctl_sched_shares_window) {
- update_cfs_load(cfs_rq, 0);
- update_cfs_shares(cfs_rq);
- }
-}
# else /* CONFIG_SMP */
-static void update_cfs_load(struct cfs_rq *cfs_rq, int global_update)
-{
-}
-
static inline long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg)
{
return tg->shares;
}
-
-static inline void update_entity_shares_tick(struct cfs_rq *cfs_rq)
-{
-}
# endif /* CONFIG_SMP */
static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
unsigned long weight)
@@ -939,6 +856,8 @@ static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
account_entity_enqueue(cfs_rq, se);
}
+static inline int throttled_hierarchy(struct cfs_rq *cfs_rq);
+
static void update_cfs_shares(struct cfs_rq *cfs_rq)
{
struct task_group *tg;
@@ -958,18 +877,478 @@ static void update_cfs_shares(struct cfs_rq *cfs_rq)
reweight_entity(cfs_rq_of(se), se, shares);
}
#else /* CONFIG_FAIR_GROUP_SCHED */
-static void update_cfs_load(struct cfs_rq *cfs_rq, int global_update)
+static inline void update_cfs_shares(struct cfs_rq *cfs_rq)
{
}
+#endif /* CONFIG_FAIR_GROUP_SCHED */
-static inline void update_cfs_shares(struct cfs_rq *cfs_rq)
+/* Only depends on SMP, FAIR_GROUP_SCHED may be removed when useful in lb */
+#if defined(CONFIG_SMP) && defined(CONFIG_FAIR_GROUP_SCHED)
+/*
+ * We choose a half-life close to 1 scheduling period.
+ * Note: The tables below are dependent on this value.
+ */
+#define LOAD_AVG_PERIOD 32
+#define LOAD_AVG_MAX 47742 /* maximum possible load avg */
+#define LOAD_AVG_MAX_N 345 /* number of full periods to produce LOAD_MAX_AVG */
+
+/* Precomputed fixed inverse multiplies for multiplication by y^n */
+static const u32 runnable_avg_yN_inv[] = {
+ 0xffffffff, 0xfa83b2da, 0xf5257d14, 0xefe4b99a, 0xeac0c6e6, 0xe5b906e6,
+ 0xe0ccdeeb, 0xdbfbb796, 0xd744fcc9, 0xd2a81d91, 0xce248c14, 0xc9b9bd85,
+ 0xc5672a10, 0xc12c4cc9, 0xbd08a39e, 0xb8fbaf46, 0xb504f333, 0xb123f581,
+ 0xad583ee9, 0xa9a15ab4, 0xa5fed6a9, 0xa2704302, 0x9ef5325f, 0x9b8d39b9,
+ 0x9837f050, 0x94f4efa8, 0x91c3d373, 0x8ea4398a, 0x8b95c1e3, 0x88980e80,
+ 0x85aac367, 0x82cd8698,
+};
+
+/*
+ * Precomputed \Sum y^k { 1<=k<=n }. These are floor(true_value) to prevent
+ * over-estimates when re-combining.
+ */
+static const u32 runnable_avg_yN_sum[] = {
+ 0, 1002, 1982, 2941, 3880, 4798, 5697, 6576, 7437, 8279, 9103,
+ 9909,10698,11470,12226,12966,13690,14398,15091,15769,16433,17082,
+ 17718,18340,18949,19545,20128,20698,21256,21802,22336,22859,23371,
+};
+
+/*
+ * Approximate:
+ * val * y^n, where y^32 ~= 0.5 (~1 scheduling period)
+ */
+static __always_inline u64 decay_load(u64 val, u64 n)
{
+ unsigned int local_n;
+
+ if (!n)
+ return val;
+ else if (unlikely(n > LOAD_AVG_PERIOD * 63))
+ return 0;
+
+ /* after bounds checking we can collapse to 32-bit */
+ local_n = n;
+
+ /*
+ * As y^PERIOD = 1/2, we can combine
+ * y^n = 1/2^(n/PERIOD) * k^(n%PERIOD)
+ * With a look-up table which covers k^n (n<PERIOD)
+ *
+ * To achieve constant time decay_load.
+ */
+ if (unlikely(local_n >= LOAD_AVG_PERIOD)) {
+ val >>= local_n / LOAD_AVG_PERIOD;
+ local_n %= LOAD_AVG_PERIOD;
+ }
+
+ val *= runnable_avg_yN_inv[local_n];
+ /* We don't use SRR here since we always want to round down. */
+ return val >> 32;
}
-static inline void update_entity_shares_tick(struct cfs_rq *cfs_rq)
+/*
+ * For updates fully spanning n periods, the contribution to runnable
+ * average will be: \Sum 1024*y^n
+ *
+ * We can compute this reasonably efficiently by combining:
+ * y^PERIOD = 1/2 with precomputed \Sum 1024*y^n {for n <PERIOD}
+ */
+static u32 __compute_runnable_contrib(u64 n)
{
+ u32 contrib = 0;
+
+ if (likely(n <= LOAD_AVG_PERIOD))
+ return runnable_avg_yN_sum[n];
+ else if (unlikely(n >= LOAD_AVG_MAX_N))
+ return LOAD_AVG_MAX;
+
+ /* Compute \Sum k^n combining precomputed values for k^i, \Sum k^j */
+ do {
+ contrib /= 2; /* y^LOAD_AVG_PERIOD = 1/2 */
+ contrib += runnable_avg_yN_sum[LOAD_AVG_PERIOD];
+
+ n -= LOAD_AVG_PERIOD;
+ } while (n > LOAD_AVG_PERIOD);
+
+ contrib = decay_load(contrib, n);
+ return contrib + runnable_avg_yN_sum[n];
}
-#endif /* CONFIG_FAIR_GROUP_SCHED */
+
+/*
+ * We can represent the historical contribution to runnable average as the
+ * coefficients of a geometric series. To do this we sub-divide our runnable
+ * history into segments of approximately 1ms (1024us); label the segment that
+ * occurred N-ms ago p_N, with p_0 corresponding to the current period, e.g.
+ *
+ * [<- 1024us ->|<- 1024us ->|<- 1024us ->| ...
+ * p0 p1 p2
+ * (now) (~1ms ago) (~2ms ago)
+ *
+ * Let u_i denote the fraction of p_i that the entity was runnable.
+ *
+ * We then designate the fractions u_i as our co-efficients, yielding the
+ * following representation of historical load:
+ * u_0 + u_1*y + u_2*y^2 + u_3*y^3 + ...
+ *
+ * We choose y based on the with of a reasonably scheduling period, fixing:
+ * y^32 = 0.5
+ *
+ * This means that the contribution to load ~32ms ago (u_32) will be weighted
+ * approximately half as much as the contribution to load within the last ms
+ * (u_0).
+ *
+ * When a period "rolls over" and we have new u_0`, multiplying the previous
+ * sum again by y is sufficient to update:
+ * load_avg = u_0` + y*(u_0 + u_1*y + u_2*y^2 + ... )
+ * = u_0 + u_1*y + u_2*y^2 + ... [re-labeling u_i --> u_{i+1}]
+ */
+static __always_inline int __update_entity_runnable_avg(u64 now,
+ struct sched_avg *sa,
+ int runnable)
+{
+ u64 delta, periods;
+ u32 runnable_contrib;
+ int delta_w, decayed = 0;
+
+ delta = now - sa->last_runnable_update;
+ /*
+ * This should only happen when time goes backwards, which it
+ * unfortunately does during sched clock init when we swap over to TSC.
+ */
+ if ((s64)delta < 0) {
+ sa->last_runnable_update = now;
+ return 0;
+ }
+
+ /*
+ * Use 1024ns as the unit of measurement since it's a reasonable
+ * approximation of 1us and fast to compute.
+ */
+ delta >>= 10;
+ if (!delta)
+ return 0;
+ sa->last_runnable_update = now;
+
+ /* delta_w is the amount already accumulated against our next period */
+ delta_w = sa->runnable_avg_period % 1024;
+ if (delta + delta_w >= 1024) {
+ /* period roll-over */
+ decayed = 1;
+
+ /*
+ * Now that we know we're crossing a period boundary, figure
+ * out how much from delta we need to complete the current
+ * period and accrue it.
+ */
+ delta_w = 1024 - delta_w;
+ if (runnable)
+ sa->runnable_avg_sum += delta_w;
+ sa->runnable_avg_period += delta_w;
+
+ delta -= delta_w;
+
+ /* Figure out how many additional periods this update spans */
+ periods = delta / 1024;
+ delta %= 1024;
+
+ sa->runnable_avg_sum = decay_load(sa->runnable_avg_sum,
+ periods + 1);
+ sa->runnable_avg_period = decay_load(sa->runnable_avg_period,
+ periods + 1);
+
+ /* Efficiently calculate \sum (1..n_period) 1024*y^i */
+ runnable_contrib = __compute_runnable_contrib(periods);
+ if (runnable)
+ sa->runnable_avg_sum += runnable_contrib;
+ sa->runnable_avg_period += runnable_contrib;
+ }
+
+ /* Remainder of delta accrued against u_0` */
+ if (runnable)
+ sa->runnable_avg_sum += delta;
+ sa->runnable_avg_period += delta;
+
+ return decayed;
+}
+
+/* Synchronize an entity's decay with its parenting cfs_rq.*/
+static inline u64 __synchronize_entity_decay(struct sched_entity *se)
+{
+ struct cfs_rq *cfs_rq = cfs_rq_of(se);
+ u64 decays = atomic64_read(&cfs_rq->decay_counter);
+
+ decays -= se->avg.decay_count;
+ if (!decays)
+ return 0;
+
+ se->avg.load_avg_contrib = decay_load(se->avg.load_avg_contrib, decays);
+ se->avg.decay_count = 0;
+
+ return decays;
+}
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+static inline void __update_cfs_rq_tg_load_contrib(struct cfs_rq *cfs_rq,
+ int force_update)
+{
+ struct task_group *tg = cfs_rq->tg;
+ s64 tg_contrib;
+
+ tg_contrib = cfs_rq->runnable_load_avg + cfs_rq->blocked_load_avg;
+ tg_contrib -= cfs_rq->tg_load_contrib;
+
+ if (force_update || abs64(tg_contrib) > cfs_rq->tg_load_contrib / 8) {
+ atomic64_add(tg_contrib, &tg->load_avg);
+ cfs_rq->tg_load_contrib += tg_contrib;
+ }
+}
+
+/*
+ * Aggregate cfs_rq runnable averages into an equivalent task_group
+ * representation for computing load contributions.
+ */
+static inline void __update_tg_runnable_avg(struct sched_avg *sa,
+ struct cfs_rq *cfs_rq)
+{
+ struct task_group *tg = cfs_rq->tg;
+ long contrib;
+
+ /* The fraction of a cpu used by this cfs_rq */
+ contrib = div_u64(sa->runnable_avg_sum << NICE_0_SHIFT,
+ sa->runnable_avg_period + 1);
+ contrib -= cfs_rq->tg_runnable_contrib;
+
+ if (abs(contrib) > cfs_rq->tg_runnable_contrib / 64) {
+ atomic_add(contrib, &tg->runnable_avg);
+ cfs_rq->tg_runnable_contrib += contrib;
+ }
+}
+
+static inline void __update_group_entity_contrib(struct sched_entity *se)
+{
+ struct cfs_rq *cfs_rq = group_cfs_rq(se);
+ struct task_group *tg = cfs_rq->tg;
+ int runnable_avg;
+
+ u64 contrib;
+
+ contrib = cfs_rq->tg_load_contrib * tg->shares;
+ se->avg.load_avg_contrib = div64_u64(contrib,
+ atomic64_read(&tg->load_avg) + 1);
+
+ /*
+ * For group entities we need to compute a correction term in the case
+ * that they are consuming <1 cpu so that we would contribute the same
+ * load as a task of equal weight.
+ *
+ * Explicitly co-ordinating this measurement would be expensive, but
+ * fortunately the sum of each cpus contribution forms a usable
+ * lower-bound on the true value.
+ *
+ * Consider the aggregate of 2 contributions. Either they are disjoint
+ * (and the sum represents true value) or they are disjoint and we are
+ * understating by the aggregate of their overlap.
+ *
+ * Extending this to N cpus, for a given overlap, the maximum amount we
+ * understand is then n_i(n_i+1)/2 * w_i where n_i is the number of
+ * cpus that overlap for this interval and w_i is the interval width.
+ *
+ * On a small machine; the first term is well-bounded which bounds the
+ * total error since w_i is a subset of the period. Whereas on a
+ * larger machine, while this first term can be larger, if w_i is the
+ * of consequential size guaranteed to see n_i*w_i quickly converge to
+ * our upper bound of 1-cpu.
+ */
+ runnable_avg = atomic_read(&tg->runnable_avg);
+ if (runnable_avg < NICE_0_LOAD) {
+ se->avg.load_avg_contrib *= runnable_avg;
+ se->avg.load_avg_contrib >>= NICE_0_SHIFT;
+ }
+}
+#else
+static inline void __update_cfs_rq_tg_load_contrib(struct cfs_rq *cfs_rq,
+ int force_update) {}
+static inline void __update_tg_runnable_avg(struct sched_avg *sa,
+ struct cfs_rq *cfs_rq) {}
+static inline void __update_group_entity_contrib(struct sched_entity *se) {}
+#endif
+
+static inline void __update_task_entity_contrib(struct sched_entity *se)
+{
+ u32 contrib;
+
+ /* avoid overflowing a 32-bit type w/ SCHED_LOAD_SCALE */
+ contrib = se->avg.runnable_avg_sum * scale_load_down(se->load.weight);
+ contrib /= (se->avg.runnable_avg_period + 1);
+ se->avg.load_avg_contrib = scale_load(contrib);
+}
+
+/* Compute the current contribution to load_avg by se, return any delta */
+static long __update_entity_load_avg_contrib(struct sched_entity *se)
+{
+ long old_contrib = se->avg.load_avg_contrib;
+
+ if (entity_is_task(se)) {
+ __update_task_entity_contrib(se);
+ } else {
+ __update_tg_runnable_avg(&se->avg, group_cfs_rq(se));
+ __update_group_entity_contrib(se);
+ }
+
+ return se->avg.load_avg_contrib - old_contrib;
+}
+
+static inline void subtract_blocked_load_contrib(struct cfs_rq *cfs_rq,
+ long load_contrib)
+{
+ if (likely(load_contrib < cfs_rq->blocked_load_avg))
+ cfs_rq->blocked_load_avg -= load_contrib;
+ else
+ cfs_rq->blocked_load_avg = 0;
+}
+
+static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq);
+
+/* Update a sched_entity's runnable average */
+static inline void update_entity_load_avg(struct sched_entity *se,
+ int update_cfs_rq)
+{
+ struct cfs_rq *cfs_rq = cfs_rq_of(se);
+ long contrib_delta;
+ u64 now;
+
+ /*
+ * For a group entity we need to use their owned cfs_rq_clock_task() in
+ * case they are the parent of a throttled hierarchy.
+ */
+ if (entity_is_task(se))
+ now = cfs_rq_clock_task(cfs_rq);
+ else
+ now = cfs_rq_clock_task(group_cfs_rq(se));
+
+ if (!__update_entity_runnable_avg(now, &se->avg, se->on_rq))
+ return;
+
+ contrib_delta = __update_entity_load_avg_contrib(se);
+
+ if (!update_cfs_rq)
+ return;
+
+ if (se->on_rq)
+ cfs_rq->runnable_load_avg += contrib_delta;
+ else
+ subtract_blocked_load_contrib(cfs_rq, -contrib_delta);
+}
+
+/*
+ * Decay the load contributed by all blocked children and account this so that
+ * their contribution may appropriately discounted when they wake up.
+ */
+static void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq, int force_update)
+{
+ u64 now = cfs_rq_clock_task(cfs_rq) >> 20;
+ u64 decays;
+
+ decays = now - cfs_rq->last_decay;
+ if (!decays && !force_update)
+ return;
+
+ if (atomic64_read(&cfs_rq->removed_load)) {
+ u64 removed_load = atomic64_xchg(&cfs_rq->removed_load, 0);
+ subtract_blocked_load_contrib(cfs_rq, removed_load);
+ }
+
+ if (decays) {
+ cfs_rq->blocked_load_avg = decay_load(cfs_rq->blocked_load_avg,
+ decays);
+ atomic64_add(decays, &cfs_rq->decay_counter);
+ cfs_rq->last_decay = now;
+ }
+
+ __update_cfs_rq_tg_load_contrib(cfs_rq, force_update);
+ update_cfs_shares(cfs_rq);
+}
+
+static inline void update_rq_runnable_avg(struct rq *rq, int runnable)
+{
+ __update_entity_runnable_avg(rq->clock_task, &rq->avg, runnable);
+ __update_tg_runnable_avg(&rq->avg, &rq->cfs);
+}
+
+/* Add the load generated by se into cfs_rq's child load-average */
+static inline void enqueue_entity_load_avg(struct cfs_rq *cfs_rq,
+ struct sched_entity *se,
+ int wakeup)
+{
+ /*
+ * We track migrations using entity decay_count <= 0, on a wake-up
+ * migration we use a negative decay count to track the remote decays
+ * accumulated while sleeping.
+ */
+ if (unlikely(se->avg.decay_count <= 0)) {
+ se->avg.last_runnable_update = rq_of(cfs_rq)->clock_task;
+ if (se->avg.decay_count) {
+ /*
+ * In a wake-up migration we have to approximate the
+ * time sleeping. This is because we can't synchronize
+ * clock_task between the two cpus, and it is not
+ * guaranteed to be read-safe. Instead, we can
+ * approximate this using our carried decays, which are
+ * explicitly atomically readable.
+ */
+ se->avg.last_runnable_update -= (-se->avg.decay_count)
+ << 20;
+ update_entity_load_avg(se, 0);
+ /* Indicate that we're now synchronized and on-rq */
+ se->avg.decay_count = 0;
+ }
+ wakeup = 0;
+ } else {
+ __synchronize_entity_decay(se);
+ }
+
+ /* migrated tasks did not contribute to our blocked load */
+ if (wakeup) {
+ subtract_blocked_load_contrib(cfs_rq, se->avg.load_avg_contrib);
+ update_entity_load_avg(se, 0);
+ }
+
+ cfs_rq->runnable_load_avg += se->avg.load_avg_contrib;
+ /* we force update consideration on load-balancer moves */
+ update_cfs_rq_blocked_load(cfs_rq, !wakeup);
+}
+
+/*
+ * Remove se's load from this cfs_rq child load-average, if the entity is
+ * transitioning to a blocked state we track its projected decay using
+ * blocked_load_avg.
+ */
+static inline void dequeue_entity_load_avg(struct cfs_rq *cfs_rq,
+ struct sched_entity *se,
+ int sleep)
+{
+ update_entity_load_avg(se, 1);
+ /* we force update consideration on load-balancer moves */
+ update_cfs_rq_blocked_load(cfs_rq, !sleep);
+
+ cfs_rq->runnable_load_avg -= se->avg.load_avg_contrib;
+ if (sleep) {
+ cfs_rq->blocked_load_avg += se->avg.load_avg_contrib;
+ se->avg.decay_count = atomic64_read(&cfs_rq->decay_counter);
+ } /* migrations, e.g. sleep=0 leave decay_count == 0 */
+}
+#else
+static inline void update_entity_load_avg(struct sched_entity *se,
+ int update_cfs_rq) {}
+static inline void update_rq_runnable_avg(struct rq *rq, int runnable) {}
+static inline void enqueue_entity_load_avg(struct cfs_rq *cfs_rq,
+ struct sched_entity *se,
+ int wakeup) {}
+static inline void dequeue_entity_load_avg(struct cfs_rq *cfs_rq,
+ struct sched_entity *se,
+ int sleep) {}
+static inline void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq,
+ int force_update) {}
+#endif
static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
@@ -1096,9 +1475,8 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
* Update run-time statistics of the 'current'.
*/
update_curr(cfs_rq);
- update_cfs_load(cfs_rq, 0);
account_entity_enqueue(cfs_rq, se);
- update_cfs_shares(cfs_rq);
+ enqueue_entity_load_avg(cfs_rq, se, flags & ENQUEUE_WAKEUP);
if (flags & ENQUEUE_WAKEUP) {
place_entity(cfs_rq, se, 0);
@@ -1190,9 +1568,8 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
if (se != cfs_rq->curr)
__dequeue_entity(cfs_rq, se);
- se->on_rq = 0;
- update_cfs_load(cfs_rq, 0);
account_entity_dequeue(cfs_rq, se);
+ dequeue_entity_load_avg(cfs_rq, se, flags & DEQUEUE_SLEEP);
/*
* Normalize the entity after updating the min_vruntime because the
@@ -1206,7 +1583,7 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
return_cfs_rq_runtime(cfs_rq);
update_min_vruntime(cfs_rq);
- update_cfs_shares(cfs_rq);
+ se->on_rq = 0;
}
/*
@@ -1340,6 +1717,8 @@ static void put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev)
update_stats_wait_start(cfs_rq, prev);
/* Put 'current' back into the tree. */
__enqueue_entity(cfs_rq, prev);
+ /* in !on_rq case, update occurred at dequeue */
+ update_entity_load_avg(prev, 1);
}
cfs_rq->curr = NULL;
}
@@ -1353,9 +1732,10 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued)
update_curr(cfs_rq);
/*
- * Update share accounting for long-running entities.
+ * Ensure that runnable average is periodically updated.
*/
- update_entity_shares_tick(cfs_rq);
+ update_entity_load_avg(curr, 1);
+ update_cfs_rq_blocked_load(cfs_rq, 1);
#ifdef CONFIG_SCHED_HRTICK
/*
@@ -1448,6 +1828,15 @@ static inline struct cfs_bandwidth *tg_cfs_bandwidth(struct task_group *tg)
return &tg->cfs_bandwidth;
}
+/* rq->task_clock normalized against any time this cfs_rq has spent throttled */
+static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq)
+{
+ if (unlikely(cfs_rq->throttle_count))
+ return cfs_rq->throttled_clock_task;
+
+ return rq_of(cfs_rq)->clock_task - cfs_rq->throttled_clock_task_time;
+}
+
/* returns 0 on failure to allocate runtime */
static int assign_cfs_rq_runtime(struct cfs_rq *cfs_rq)
{
@@ -1592,14 +1981,9 @@ static int tg_unthrottle_up(struct task_group *tg, void *data)
cfs_rq->throttle_count--;
#ifdef CONFIG_SMP
if (!cfs_rq->throttle_count) {
- u64 delta = rq->clock_task - cfs_rq->load_stamp;
-
- /* leaving throttled state, advance shares averaging windows */
- cfs_rq->load_stamp += delta;
- cfs_rq->load_last += delta;
-
- /* update entity weight now that we are on_rq again */
- update_cfs_shares(cfs_rq);
+ /* adjust cfs_rq_clock_task() */
+ cfs_rq->throttled_clock_task_time += rq->clock_task -
+ cfs_rq->throttled_clock_task;
}
#endif
@@ -1611,9 +1995,9 @@ static int tg_throttle_down(struct task_group *tg, void *data)
struct rq *rq = data;
struct cfs_rq *cfs_rq = tg->cfs_rq[cpu_of(rq)];
- /* group is entering throttled state, record last load */
+ /* group is entering throttled state, stop time */
if (!cfs_rq->throttle_count)
- update_cfs_load(cfs_rq, 0);
+ cfs_rq->throttled_clock_task = rq->clock_task;
cfs_rq->throttle_count++;
return 0;
@@ -1628,7 +2012,7 @@ static void throttle_cfs_rq(struct cfs_rq *cfs_rq)
se = cfs_rq->tg->se[cpu_of(rq_of(cfs_rq))];
- /* account load preceding throttle */
+ /* freeze hierarchy runnable averages while throttled */
rcu_read_lock();
walk_tg_tree_from(cfs_rq->tg, tg_throttle_down, tg_nop, (void *)rq);
rcu_read_unlock();
@@ -1652,7 +2036,7 @@ static void throttle_cfs_rq(struct cfs_rq *cfs_rq)
rq->nr_running -= task_delta;
cfs_rq->throttled = 1;
- cfs_rq->throttled_timestamp = rq->clock;
+ cfs_rq->throttled_clock = rq->clock;
raw_spin_lock(&cfs_b->lock);
list_add_tail_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq);
raw_spin_unlock(&cfs_b->lock);
@@ -1670,10 +2054,9 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq)
cfs_rq->throttled = 0;
raw_spin_lock(&cfs_b->lock);
- cfs_b->throttled_time += rq->clock - cfs_rq->throttled_timestamp;
+ cfs_b->throttled_time += rq->clock - cfs_rq->throttled_clock;
list_del_rcu(&cfs_rq->throttled_list);
raw_spin_unlock(&cfs_b->lock);
- cfs_rq->throttled_timestamp = 0;
update_rq_clock(rq);
/* update hierarchical throttle state */
@@ -2073,8 +2456,13 @@ static void unthrottle_offline_cfs_rqs(struct rq *rq)
}
#else /* CONFIG_CFS_BANDWIDTH */
-static __always_inline
-void account_cfs_rq_runtime(struct cfs_rq *cfs_rq, unsigned long delta_exec) {}
+static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq)
+{
+ return rq_of(cfs_rq)->clock_task;
+}
+
+static void account_cfs_rq_runtime(struct cfs_rq *cfs_rq,
+ unsigned long delta_exec) {}
static void check_cfs_rq_runtime(struct cfs_rq *cfs_rq) {}
static void check_enqueue_throttle(struct cfs_rq *cfs_rq) {}
static __always_inline void return_cfs_rq_runtime(struct cfs_rq *cfs_rq) {}
@@ -2207,12 +2595,14 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
if (cfs_rq_throttled(cfs_rq))
break;
- update_cfs_load(cfs_rq, 0);
- update_cfs_shares(cfs_rq);
+ update_entity_load_avg(se, 1);
+ update_cfs_rq_blocked_load(cfs_rq, 0);
}
- if (!se)
+ if (!se) {
+ update_rq_runnable_avg(rq, rq->nr_running);
inc_nr_running(rq);
+ }
hrtick_update(rq);
}
@@ -2266,12 +2656,14 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags)
if (cfs_rq_throttled(cfs_rq))
break;
- update_cfs_load(cfs_rq, 0);
- update_cfs_shares(cfs_rq);
+ update_entity_load_avg(se, 1);
+ update_cfs_rq_blocked_load(cfs_rq, 0);
}
- if (!se)
+ if (!se) {
dec_nr_running(rq);
+ update_rq_runnable_avg(rq, 1);
+ }
hrtick_update(rq);
}
@@ -2781,6 +3173,37 @@ unlock:
return new_cpu;
}
+
+/*
+ * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be
+ * removed when useful for applications beyond shares distribution (e.g.
+ * load-balance).
+ */
+#ifdef CONFIG_FAIR_GROUP_SCHED
+/*
+ * Called immediately before a task is migrated to a new cpu; task_cpu(p) and
+ * cfs_rq_of(p) references at time of call are still valid and identify the
+ * previous cpu. However, the caller only guarantees p->pi_lock is held; no
+ * other assumptions, including the state of rq->lock, should be made.
+ */
+static void
+migrate_task_rq_fair(struct task_struct *p, int next_cpu)
+{
+ struct sched_entity *se = &p->se;
+ struct cfs_rq *cfs_rq = cfs_rq_of(se);
+
+ /*
+ * Load tracking: accumulate removed load so that it can be processed
+ * when we next update owning cfs_rq under rq->lock. Tasks contribute
+ * to blocked load iff they have a positive decay-count. It can never
+ * be negative here since on-rq tasks have decay-count == 0.
+ */
+ if (se->avg.decay_count) {
+ se->avg.decay_count = -__synchronize_entity_decay(se);
+ atomic64_add(se->avg.load_avg_contrib, &cfs_rq->removed_load);
+ }
+}
+#endif
#endif /* CONFIG_SMP */
static unsigned long
@@ -2907,7 +3330,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
* Batch and idle tasks do not preempt non-idle tasks (their preemption
* is driven by the tick):
*/
- if (unlikely(p->policy != SCHED_NORMAL))
+ if (unlikely(p->policy != SCHED_NORMAL) || !sched_feat(WAKEUP_PREEMPTION))
return;
find_matching_se(&se, &pse);
@@ -3033,8 +3456,122 @@ static bool yield_to_task_fair(struct rq *rq, struct task_struct *p, bool preemp
#ifdef CONFIG_SMP
/**************************************************
- * Fair scheduling class load-balancing methods:
- */
+ * Fair scheduling class load-balancing methods.
+ *
+ * BASICS
+ *
+ * The purpose of load-balancing is to achieve the same basic fairness the
+ * per-cpu scheduler provides, namely provide a proportional amount of compute
+ * time to each task. This is expressed in the following equation:
+ *
+ * W_i,n/P_i == W_j,n/P_j for all i,j (1)
+ *
+ * Where W_i,n is the n-th weight average for cpu i. The instantaneous weight
+ * W_i,0 is defined as:
+ *
+ * W_i,0 = \Sum_j w_i,j (2)
+ *
+ * Where w_i,j is the weight of the j-th runnable task on cpu i. This weight
+ * is derived from the nice value as per prio_to_weight[].
+ *
+ * The weight average is an exponential decay average of the instantaneous
+ * weight:
+ *
+ * W'_i,n = (2^n - 1) / 2^n * W_i,n + 1 / 2^n * W_i,0 (3)
+ *
+ * P_i is the cpu power (or compute capacity) of cpu i, typically it is the
+ * fraction of 'recent' time available for SCHED_OTHER task execution. But it
+ * can also include other factors [XXX].
+ *
+ * To achieve this balance we define a measure of imbalance which follows
+ * directly from (1):
+ *
+ * imb_i,j = max{ avg(W/P), W_i/P_i } - min{ avg(W/P), W_j/P_j } (4)
+ *
+ * We them move tasks around to minimize the imbalance. In the continuous
+ * function space it is obvious this converges, in the discrete case we get
+ * a few fun cases generally called infeasible weight scenarios.
+ *
+ * [XXX expand on:
+ * - infeasible weights;
+ * - local vs global optima in the discrete case. ]
+ *
+ *
+ * SCHED DOMAINS
+ *
+ * In order to solve the imbalance equation (4), and avoid the obvious O(n^2)
+ * for all i,j solution, we create a tree of cpus that follows the hardware
+ * topology where each level pairs two lower groups (or better). This results
+ * in O(log n) layers. Furthermore we reduce the number of cpus going up the
+ * tree to only the first of the previous level and we decrease the frequency
+ * of load-balance at each level inv. proportional to the number of cpus in
+ * the groups.
+ *
+ * This yields:
+ *
+ * log_2 n 1 n
+ * \Sum { --- * --- * 2^i } = O(n) (5)
+ * i = 0 2^i 2^i
+ * `- size of each group
+ * | | `- number of cpus doing load-balance
+ * | `- freq
+ * `- sum over all levels
+ *
+ * Coupled with a limit on how many tasks we can migrate every balance pass,
+ * this makes (5) the runtime complexity of the balancer.
+ *
+ * An important property here is that each CPU is still (indirectly) connected
+ * to every other cpu in at most O(log n) steps:
+ *
+ * The adjacency matrix of the resulting graph is given by:
+ *
+ * log_2 n
+ * A_i,j = \Union (i % 2^k == 0) && i / 2^(k+1) == j / 2^(k+1) (6)
+ * k = 0
+ *
+ * And you'll find that:
+ *
+ * A^(log_2 n)_i,j != 0 for all i,j (7)
+ *
+ * Showing there's indeed a path between every cpu in at most O(log n) steps.
+ * The task movement gives a factor of O(m), giving a convergence complexity
+ * of:
+ *
+ * O(nm log n), n := nr_cpus, m := nr_tasks (8)
+ *
+ *
+ * WORK CONSERVING
+ *
+ * In order to avoid CPUs going idle while there's still work to do, new idle
+ * balancing is more aggressive and has the newly idle cpu iterate up the domain
+ * tree itself instead of relying on other CPUs to bring it work.
+ *
+ * This adds some complexity to both (5) and (8) but it reduces the total idle
+ * time.
+ *
+ * [XXX more?]
+ *
+ *
+ * CGROUPS
+ *
+ * Cgroups make a horror show out of (2), instead of a simple sum we get:
+ *
+ * s_k,i
+ * W_i,0 = \Sum_j \Prod_k w_k * ----- (9)
+ * S_k
+ *
+ * Where
+ *
+ * s_k,i = \Sum_j w_i,j,k and S_k = \Sum_i s_k,i (10)
+ *
+ * w_i,j,k is the weight of the j-th runnable task in the k-th cgroup on cpu i.
+ *
+ * The big problem is S_k, its a global sum needed to compute a local (W_i)
+ * property.
+ *
+ * [XXX write more on how we solve this.. _after_ merging pjt's patches that
+ * rewrite all of this once again.]
+ */
static unsigned long __read_mostly max_load_balance_interval = HZ/10;
@@ -3300,52 +3837,58 @@ next:
/*
* update tg->load_weight by folding this cpu's load_avg
*/
-static int update_shares_cpu(struct task_group *tg, int cpu)
+static void __update_blocked_averages_cpu(struct task_group *tg, int cpu)
{
- struct cfs_rq *cfs_rq;
- unsigned long flags;
- struct rq *rq;
-
- if (!tg->se[cpu])
- return 0;
-
- rq = cpu_rq(cpu);
- cfs_rq = tg->cfs_rq[cpu];
-
- raw_spin_lock_irqsave(&rq->lock, flags);
+ struct sched_entity *se = tg->se[cpu];
+ struct cfs_rq *cfs_rq = tg->cfs_rq[cpu];
- update_rq_clock(rq);
- update_cfs_load(cfs_rq, 1);
+ /* throttled entities do not contribute to load */
+ if (throttled_hierarchy(cfs_rq))
+ return;
- /*
- * We need to update shares after updating tg->load_weight in
- * order to adjust the weight of groups with long running tasks.
- */
- update_cfs_shares(cfs_rq);
+ update_cfs_rq_blocked_load(cfs_rq, 1);
- raw_spin_unlock_irqrestore(&rq->lock, flags);
-
- return 0;
+ if (se) {
+ update_entity_load_avg(se, 1);
+ /*
+ * We pivot on our runnable average having decayed to zero for
+ * list removal. This generally implies that all our children
+ * have also been removed (modulo rounding error or bandwidth
+ * control); however, such cases are rare and we can fix these
+ * at enqueue.
+ *
+ * TODO: fix up out-of-order children on enqueue.
+ */
+ if (!se->avg.runnable_avg_sum && !cfs_rq->nr_running)
+ list_del_leaf_cfs_rq(cfs_rq);
+ } else {
+ struct rq *rq = rq_of(cfs_rq);
+ update_rq_runnable_avg(rq, rq->nr_running);
+ }
}
-static void update_shares(int cpu)
+static void update_blocked_averages(int cpu)
{
- struct cfs_rq *cfs_rq;
struct rq *rq = cpu_rq(cpu);
+ struct cfs_rq *cfs_rq;
+ unsigned long flags;
- rcu_read_lock();
+ raw_spin_lock_irqsave(&rq->lock, flags);
+ update_rq_clock(rq);
/*
* Iterates the task_group tree in a bottom up fashion, see
* list_add_leaf_cfs_rq() for details.
*/
for_each_leaf_cfs_rq(rq, cfs_rq) {
- /* throttled entities do not contribute to load */
- if (throttled_hierarchy(cfs_rq))
- continue;
-
- update_shares_cpu(cfs_rq->tg, cpu);
+ /*
+ * Note: We may want to consider periodically releasing
+ * rq->lock about these updates so that creating many task
+ * groups does not result in continually extending hold time.
+ */
+ __update_blocked_averages_cpu(cfs_rq->tg, rq->cpu);
}
- rcu_read_unlock();
+
+ raw_spin_unlock_irqrestore(&rq->lock, flags);
}
/*
@@ -3397,7 +3940,7 @@ static unsigned long task_h_load(struct task_struct *p)
return load;
}
#else
-static inline void update_shares(int cpu)
+static inline void update_blocked_averages(int cpu)
{
}
@@ -4457,12 +5000,14 @@ void idle_balance(int this_cpu, struct rq *this_rq)
if (this_rq->avg_idle < sysctl_sched_migration_cost)
return;
+ update_rq_runnable_avg(this_rq, 1);
+
/*
* Drop the rq->lock, but keep IRQ/preempt disabled.
*/
raw_spin_unlock(&this_rq->lock);
- update_shares(this_cpu);
+ update_blocked_averages(this_cpu);
rcu_read_lock();
for_each_domain(this_cpu, sd) {
unsigned long interval;
@@ -4717,7 +5262,7 @@ static void rebalance_domains(int cpu, enum cpu_idle_type idle)
int update_next_balance = 0;
int need_serialize;
- update_shares(cpu);
+ update_blocked_averages(cpu);
rcu_read_lock();
for_each_domain(cpu, sd) {
@@ -4954,6 +5499,8 @@ static void task_tick_fair(struct rq *rq, struct task_struct *curr, int queued)
cfs_rq = cfs_rq_of(se);
entity_tick(cfs_rq, se, queued);
}
+
+ update_rq_runnable_avg(rq, 1);
}
/*
@@ -5046,6 +5593,20 @@ static void switched_from_fair(struct rq *rq, struct task_struct *p)
place_entity(cfs_rq, se, 0);
se->vruntime -= cfs_rq->min_vruntime;
}
+
+#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP)
+ /*
+ * Remove our load from contribution when we leave sched_fair
+ * and ensure we don't carry in an old decay_count if we
+ * switch back.
+ */
+ if (p->se.avg.decay_count) {
+ struct cfs_rq *cfs_rq = cfs_rq_of(&p->se);
+ __synchronize_entity_decay(&p->se);
+ subtract_blocked_load_contrib(cfs_rq,
+ p->se.avg.load_avg_contrib);
+ }
+#endif
}
/*
@@ -5092,11 +5653,16 @@ void init_cfs_rq(struct cfs_rq *cfs_rq)
#ifndef CONFIG_64BIT
cfs_rq->min_vruntime_copy = cfs_rq->min_vruntime;
#endif
+#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP)
+ atomic64_set(&cfs_rq->decay_counter, 1);
+ atomic64_set(&cfs_rq->removed_load, 0);
+#endif
}
#ifdef CONFIG_FAIR_GROUP_SCHED
static void task_move_group_fair(struct task_struct *p, int on_rq)
{
+ struct cfs_rq *cfs_rq;
/*
* If the task was not on the rq at the time of this cgroup movement
* it must have been asleep, sleeping tasks keep their ->vruntime
@@ -5128,8 +5694,19 @@ static void task_move_group_fair(struct task_struct *p, int on_rq)
if (!on_rq)
p->se.vruntime -= cfs_rq_of(&p->se)->min_vruntime;
set_task_rq(p, task_cpu(p));
- if (!on_rq)
- p->se.vruntime += cfs_rq_of(&p->se)->min_vruntime;
+ if (!on_rq) {
+ cfs_rq = cfs_rq_of(&p->se);
+ p->se.vruntime += cfs_rq->min_vruntime;
+#ifdef CONFIG_SMP
+ /*
+ * migrate_task_rq_fair() will have removed our previous
+ * contribution, but we must synchronize for ongoing future
+ * decay.
+ */
+ p->se.avg.decay_count = atomic64_read(&cfs_rq->decay_counter);
+ cfs_rq->blocked_load_avg += p->se.avg.load_avg_contrib;
+#endif
+ }
}
void free_fair_sched_group(struct task_group *tg)
@@ -5214,10 +5791,6 @@ void init_tg_cfs_entry(struct task_group *tg, struct cfs_rq *cfs_rq,
cfs_rq->tg = tg;
cfs_rq->rq = rq;
-#ifdef CONFIG_SMP
- /* allow initial update_cfs_load() to truncate */
- cfs_rq->load_stamp = 1;
-#endif
init_cfs_rq_runtime(cfs_rq);
tg->cfs_rq[cpu] = cfs_rq;
@@ -5264,8 +5837,11 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares)
se = tg->se[i];
/* Propagate contribution to hierarchy */
raw_spin_lock_irqsave(&rq->lock, flags);
- for_each_sched_entity(se)
+ for_each_sched_entity(se) {
update_cfs_shares(group_cfs_rq(se));
+ /* update contribution to parent */
+ update_entity_load_avg(se, 1);
+ }
raw_spin_unlock_irqrestore(&rq->lock, flags);
}
@@ -5319,7 +5895,9 @@ const struct sched_class fair_sched_class = {
#ifdef CONFIG_SMP
.select_task_rq = select_task_rq_fair,
-
+#ifdef CONFIG_FAIR_GROUP_SCHED
+ .migrate_task_rq = migrate_task_rq_fair,
+#endif
.rq_online = rq_online_fair,
.rq_offline = rq_offline_fair,
diff --git a/kernel/sched/features.h b/kernel/sched/features.h
index eebefcad702..e68e69ab917 100644
--- a/kernel/sched/features.h
+++ b/kernel/sched/features.h
@@ -32,6 +32,11 @@ SCHED_FEAT(LAST_BUDDY, true)
SCHED_FEAT(CACHE_HOT_BUDDY, true)
/*
+ * Allow wakeup-time preemption of the current task:
+ */
+SCHED_FEAT(WAKEUP_PREEMPTION, true)
+
+/*
* Use arch dependent cpu power functions
*/
SCHED_FEAT(ARCH_POWER, true)
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 7a7db09cfab..5eca173b563 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -112,6 +112,8 @@ struct task_group {
unsigned long shares;
atomic_t load_weight;
+ atomic64_t load_avg;
+ atomic_t runnable_avg;
#endif
#ifdef CONFIG_RT_GROUP_SCHED
@@ -222,22 +224,29 @@ struct cfs_rq {
unsigned int nr_spread_over;
#endif
+#ifdef CONFIG_SMP
+/*
+ * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be
+ * removed when useful for applications beyond shares distribution (e.g.
+ * load-balance).
+ */
#ifdef CONFIG_FAIR_GROUP_SCHED
- struct rq *rq; /* cpu runqueue to which this cfs_rq is attached */
-
/*
- * leaf cfs_rqs are those that hold tasks (lowest schedulable entity in
- * a hierarchy). Non-leaf lrqs hold other higher schedulable entities
- * (like users, containers etc.)
- *
- * leaf_cfs_rq_list ties together list of leaf cfs_rq's in a cpu. This
- * list is used during load balance.
+ * CFS Load tracking
+ * Under CFS, load is tracked on a per-entity basis and aggregated up.
+ * This allows for the description of both thread and group usage (in
+ * the FAIR_GROUP_SCHED case).
*/
- int on_list;
- struct list_head leaf_cfs_rq_list;
- struct task_group *tg; /* group that "owns" this runqueue */
+ u64 runnable_load_avg, blocked_load_avg;
+ atomic64_t decay_counter, removed_load;
+ u64 last_decay;
+#endif /* CONFIG_FAIR_GROUP_SCHED */
+/* These always depend on CONFIG_FAIR_GROUP_SCHED */
+#ifdef CONFIG_FAIR_GROUP_SCHED
+ u32 tg_runnable_contrib;
+ u64 tg_load_contrib;
+#endif /* CONFIG_FAIR_GROUP_SCHED */
-#ifdef CONFIG_SMP
/*
* h_load = weight * f(tg)
*
@@ -245,26 +254,30 @@ struct cfs_rq {
* this group.
*/
unsigned long h_load;
+#endif /* CONFIG_SMP */
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+ struct rq *rq; /* cpu runqueue to which this cfs_rq is attached */
/*
- * Maintaining per-cpu shares distribution for group scheduling
+ * leaf cfs_rqs are those that hold tasks (lowest schedulable entity in
+ * a hierarchy). Non-leaf lrqs hold other higher schedulable entities
+ * (like users, containers etc.)
*
- * load_stamp is the last time we updated the load average
- * load_last is the last time we updated the load average and saw load
- * load_unacc_exec_time is currently unaccounted execution time
+ * leaf_cfs_rq_list ties together list of leaf cfs_rq's in a cpu. This
+ * list is used during load balance.
*/
- u64 load_avg;
- u64 load_period;
- u64 load_stamp, load_last, load_unacc_exec_time;
+ int on_list;
+ struct list_head leaf_cfs_rq_list;
+ struct task_group *tg; /* group that "owns" this runqueue */
- unsigned long load_contribution;
-#endif /* CONFIG_SMP */
#ifdef CONFIG_CFS_BANDWIDTH
int runtime_enabled;
u64 runtime_expires;
s64 runtime_remaining;
- u64 throttled_timestamp;
+ u64 throttled_clock, throttled_clock_task;
+ u64 throttled_clock_task_time;
int throttled, throttle_count;
struct list_head throttled_list;
#endif /* CONFIG_CFS_BANDWIDTH */
@@ -467,6 +480,8 @@ struct rq {
#ifdef CONFIG_SMP
struct llist_head wake_list;
#endif
+
+ struct sched_avg avg;
};
static inline int cpu_of(struct rq *rq)
@@ -1212,4 +1227,3 @@ static inline u64 irq_time_read(int cpu)
}
#endif /* CONFIG_64BIT */
#endif /* CONFIG_IRQ_TIME_ACCOUNTING */
-
diff --git a/kernel/softirq.c b/kernel/softirq.c
index cc96bdc0c2c..ed567babe78 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -221,7 +221,7 @@ asmlinkage void __do_softirq(void)
current->flags &= ~PF_MEMALLOC;
pending = local_softirq_pending();
- vtime_account(current);
+ vtime_account_irq_enter(current);
__local_bh_disable((unsigned long)__builtin_return_address(0),
SOFTIRQ_OFFSET);
@@ -272,7 +272,7 @@ restart:
lockdep_softirq_exit();
- vtime_account(current);
+ vtime_account_irq_exit(current);
__local_bh_enable(SOFTIRQ_OFFSET);
tsk_restore_flags(current, old_flags, PF_MEMALLOC);
}
@@ -341,7 +341,7 @@ static inline void invoke_softirq(void)
*/
void irq_exit(void)
{
- vtime_account(current);
+ vtime_account_irq_exit(current);
trace_hardirq_exit();
sub_preempt_count(IRQ_EXIT_OFFSET);
if (!in_interrupt() && local_softirq_pending())
diff --git a/kernel/srcu.c b/kernel/srcu.c
index 97c465ebd84..2b859828cdc 100644
--- a/kernel/srcu.c
+++ b/kernel/srcu.c
@@ -16,8 +16,10 @@
* 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
@@ -34,6 +36,10 @@
#include <linux/delay.h>
#include <linux/srcu.h>
+#include <trace/events/rcu.h>
+
+#include "rcu.h"
+
/*
* Initialize an rcu_batch structure to empty.
*/
@@ -92,9 +98,6 @@ static inline void rcu_batch_move(struct rcu_batch *to, struct rcu_batch *from)
}
}
-/* single-thread state-machine */
-static void process_srcu(struct work_struct *work);
-
static int init_srcu_struct_fields(struct srcu_struct *sp)
{
sp->completed = 0;
@@ -464,7 +467,9 @@ static void __synchronize_srcu(struct srcu_struct *sp, int trycount)
*/
void synchronize_srcu(struct srcu_struct *sp)
{
- __synchronize_srcu(sp, SYNCHRONIZE_SRCU_TRYCOUNT);
+ __synchronize_srcu(sp, rcu_expedited
+ ? SYNCHRONIZE_SRCU_EXP_TRYCOUNT
+ : SYNCHRONIZE_SRCU_TRYCOUNT);
}
EXPORT_SYMBOL_GPL(synchronize_srcu);
@@ -637,7 +642,7 @@ static void srcu_reschedule(struct srcu_struct *sp)
/*
* This is the work-queue function that handles SRCU grace periods.
*/
-static void process_srcu(struct work_struct *work)
+void process_srcu(struct work_struct *work)
{
struct srcu_struct *sp;
@@ -648,3 +653,4 @@ static void process_srcu(struct work_struct *work)
srcu_invoke_callbacks(sp);
srcu_reschedule(sp);
}
+EXPORT_SYMBOL_GPL(process_srcu);
diff --git a/kernel/sys.c b/kernel/sys.c
index e6e0ece5f6a..265b3769042 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1046,7 +1046,7 @@ void do_sys_times(struct tms *tms)
cputime_t tgutime, tgstime, cutime, cstime;
spin_lock_irq(&current->sighand->siglock);
- thread_group_times(current, &tgutime, &tgstime);
+ thread_group_cputime_adjusted(current, &tgutime, &tgstime);
cutime = current->signal->cutime;
cstime = current->signal->cstime;
spin_unlock_irq(&current->sighand->siglock);
@@ -1704,7 +1704,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
utime = stime = 0;
if (who == RUSAGE_THREAD) {
- task_times(current, &utime, &stime);
+ task_cputime_adjusted(current, &utime, &stime);
accumulate_thread_rusage(p, r);
maxrss = p->signal->maxrss;
goto out;
@@ -1730,7 +1730,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
break;
case RUSAGE_SELF:
- thread_group_times(p, &tgutime, &tgstime);
+ thread_group_cputime_adjusted(p, &tgutime, &tgstime);
utime += tgutime;
stime += tgstime;
r->ru_nvcsw += p->signal->nvcsw;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 26f65eaa01f..33f71f37267 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -565,7 +565,7 @@ static struct ctl_table kern_table[] = {
.extra2 = &one,
},
#endif
-#ifdef CONFIG_HOTPLUG
+
{
.procname = "hotplug",
.data = &uevent_helper,
@@ -573,7 +573,7 @@ static struct ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = proc_dostring,
},
-#endif
+
#ifdef CONFIG_CHR_DEV_SG
{
.procname = "sg-big-buff",
diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
index 6629bf7b528..7a925ba456f 100644
--- a/kernel/time/jiffies.c
+++ b/kernel/time/jiffies.c
@@ -58,7 +58,7 @@ static cycle_t jiffies_read(struct clocksource *cs)
return (cycle_t) jiffies;
}
-struct clocksource clocksource_jiffies = {
+static struct clocksource clocksource_jiffies = {
.name = "jiffies",
.rating = 1, /* lowest valid rating*/
.read = jiffies_read,
@@ -67,6 +67,8 @@ struct clocksource clocksource_jiffies = {
.shift = JIFFIES_SHIFT,
};
+__cacheline_aligned_in_smp DEFINE_SEQLOCK(jiffies_lock);
+
#if (BITS_PER_LONG < 64)
u64 get_jiffies_64(void)
{
@@ -74,9 +76,9 @@ u64 get_jiffies_64(void)
u64 ret;
do {
- seq = read_seqbegin(&xtime_lock);
+ seq = read_seqbegin(&jiffies_lock);
ret = jiffies_64;
- } while (read_seqretry(&xtime_lock, seq));
+ } while (read_seqretry(&jiffies_lock, seq));
return ret;
}
EXPORT_SYMBOL(get_jiffies_64);
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index da6c9ecad4e..b1600a6973f 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -63,13 +63,13 @@ int tick_is_oneshot_available(void)
static void tick_periodic(int cpu)
{
if (tick_do_timer_cpu == cpu) {
- write_seqlock(&xtime_lock);
+ write_seqlock(&jiffies_lock);
/* Keep track of the next tick event */
tick_next_period = ktime_add(tick_next_period, tick_period);
do_timer(1);
- write_sequnlock(&xtime_lock);
+ write_sequnlock(&jiffies_lock);
}
update_process_times(user_mode(get_irq_regs()));
@@ -130,9 +130,9 @@ void tick_setup_periodic(struct clock_event_device *dev, int broadcast)
ktime_t next;
do {
- seq = read_seqbegin(&xtime_lock);
+ seq = read_seqbegin(&jiffies_lock);
next = tick_next_period;
- } while (read_seqretry(&xtime_lock, seq));
+ } while (read_seqretry(&jiffies_lock, seq));
clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT);
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index 4e265b901fe..cf3e59ed6dc 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -141,4 +141,3 @@ static inline int tick_device_is_functional(struct clock_event_device *dev)
#endif
extern void do_timer(unsigned long ticks);
-extern seqlock_t xtime_lock;
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index a4026088526..d58e552d9fd 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -31,7 +31,7 @@
static DEFINE_PER_CPU(struct tick_sched, tick_cpu_sched);
/*
- * The time, when the last jiffy update happened. Protected by xtime_lock.
+ * The time, when the last jiffy update happened. Protected by jiffies_lock.
*/
static ktime_t last_jiffies_update;
@@ -49,14 +49,14 @@ static void tick_do_update_jiffies64(ktime_t now)
ktime_t delta;
/*
- * Do a quick check without holding xtime_lock:
+ * Do a quick check without holding jiffies_lock:
*/
delta = ktime_sub(now, last_jiffies_update);
if (delta.tv64 < tick_period.tv64)
return;
- /* Reevalute with xtime_lock held */
- write_seqlock(&xtime_lock);
+ /* Reevalute with jiffies_lock held */
+ write_seqlock(&jiffies_lock);
delta = ktime_sub(now, last_jiffies_update);
if (delta.tv64 >= tick_period.tv64) {
@@ -79,7 +79,7 @@ static void tick_do_update_jiffies64(ktime_t now)
/* Keep the tick_next_period variable up to date */
tick_next_period = ktime_add(last_jiffies_update, tick_period);
}
- write_sequnlock(&xtime_lock);
+ write_sequnlock(&jiffies_lock);
}
/*
@@ -89,15 +89,58 @@ static ktime_t tick_init_jiffy_update(void)
{
ktime_t period;
- write_seqlock(&xtime_lock);
+ write_seqlock(&jiffies_lock);
/* Did we start the jiffies update yet ? */
if (last_jiffies_update.tv64 == 0)
last_jiffies_update = tick_next_period;
period = last_jiffies_update;
- write_sequnlock(&xtime_lock);
+ write_sequnlock(&jiffies_lock);
return period;
}
+
+static void tick_sched_do_timer(ktime_t now)
+{
+ int cpu = smp_processor_id();
+
+#ifdef CONFIG_NO_HZ
+ /*
+ * Check if the do_timer duty was dropped. We don't care about
+ * concurrency: This happens only when the cpu in charge went
+ * into a long sleep. If two cpus happen to assign themself to
+ * this duty, then the jiffies update is still serialized by
+ * jiffies_lock.
+ */
+ if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE))
+ tick_do_timer_cpu = cpu;
+#endif
+
+ /* Check, if the jiffies need an update */
+ if (tick_do_timer_cpu == cpu)
+ tick_do_update_jiffies64(now);
+}
+
+static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs)
+{
+#ifdef CONFIG_NO_HZ
+ /*
+ * When we are idle and the tick is stopped, we have to touch
+ * the watchdog as we might not schedule for a really long
+ * time. This happens on complete idle SMP systems while
+ * waiting on the login prompt. We also increment the "start of
+ * idle" jiffy stamp so the idle accounting adjustment we do
+ * when we go busy again does not account too much ticks.
+ */
+ if (ts->tick_stopped) {
+ touch_softlockup_watchdog();
+ if (is_idle_task(current))
+ ts->idle_jiffies++;
+ }
+#endif
+ update_process_times(user_mode(regs));
+ profile_tick(CPU_PROFILING);
+}
+
/*
* NOHZ - aka dynamic tick functionality
*/
@@ -282,11 +325,11 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
/* Read jiffies and the time when jiffies were updated last */
do {
- seq = read_seqbegin(&xtime_lock);
+ seq = read_seqbegin(&jiffies_lock);
last_update = last_jiffies_update;
last_jiffies = jiffies;
time_delta = timekeeping_max_deferment();
- } while (read_seqretry(&xtime_lock, seq));
+ } while (read_seqretry(&jiffies_lock, seq));
if (rcu_needs_cpu(cpu, &rcu_delta_jiffies) || printk_needs_cpu(cpu) ||
arch_needs_cpu(cpu)) {
@@ -526,6 +569,8 @@ void tick_nohz_irq_exit(void)
if (!ts->inidle)
return;
+ /* Cancel the timer because CPU already waken up from the C-states*/
+ menu_hrtimer_cancel();
__tick_nohz_idle_enter(ts);
}
@@ -621,6 +666,8 @@ void tick_nohz_idle_exit(void)
ts->inidle = 0;
+ /* Cancel the timer because CPU already waken up from the C-states*/
+ menu_hrtimer_cancel();
if (ts->idle_active || ts->tick_stopped)
now = ktime_get();
@@ -648,40 +695,12 @@ static void tick_nohz_handler(struct clock_event_device *dev)
{
struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
struct pt_regs *regs = get_irq_regs();
- int cpu = smp_processor_id();
ktime_t now = ktime_get();
dev->next_event.tv64 = KTIME_MAX;
- /*
- * Check if the do_timer duty was dropped. We don't care about
- * concurrency: This happens only when the cpu in charge went
- * into a long sleep. If two cpus happen to assign themself to
- * this duty, then the jiffies update is still serialized by
- * xtime_lock.
- */
- if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE))
- tick_do_timer_cpu = cpu;
-
- /* Check, if the jiffies need an update */
- if (tick_do_timer_cpu == cpu)
- tick_do_update_jiffies64(now);
-
- /*
- * When we are idle and the tick is stopped, we have to touch
- * the watchdog as we might not schedule for a really long
- * time. This happens on complete idle SMP systems while
- * waiting on the login prompt. We also increment the "start
- * of idle" jiffy stamp so the idle accounting adjustment we
- * do when we go busy again does not account too much ticks.
- */
- if (ts->tick_stopped) {
- touch_softlockup_watchdog();
- ts->idle_jiffies++;
- }
-
- update_process_times(user_mode(regs));
- profile_tick(CPU_PROFILING);
+ tick_sched_do_timer(now);
+ tick_sched_handle(ts, regs);
while (tick_nohz_reprogram(ts, now)) {
now = ktime_get();
@@ -794,7 +813,7 @@ void tick_check_idle(int cpu)
#ifdef CONFIG_HIGH_RES_TIMERS
/*
* We rearm the timer until we get disabled by the idle code.
- * Called with interrupts disabled and timer->base->cpu_base->lock held.
+ * Called with interrupts disabled.
*/
static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
{
@@ -802,45 +821,15 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
container_of(timer, struct tick_sched, sched_timer);
struct pt_regs *regs = get_irq_regs();
ktime_t now = ktime_get();
- int cpu = smp_processor_id();
-#ifdef CONFIG_NO_HZ
- /*
- * Check if the do_timer duty was dropped. We don't care about
- * concurrency: This happens only when the cpu in charge went
- * into a long sleep. If two cpus happen to assign themself to
- * this duty, then the jiffies update is still serialized by
- * xtime_lock.
- */
- if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE))
- tick_do_timer_cpu = cpu;
-#endif
-
- /* Check, if the jiffies need an update */
- if (tick_do_timer_cpu == cpu)
- tick_do_update_jiffies64(now);
+ tick_sched_do_timer(now);
/*
* Do not call, when we are not in irq context and have
* no valid regs pointer
*/
- if (regs) {
- /*
- * When we are idle and the tick is stopped, we have to touch
- * the watchdog as we might not schedule for a really long
- * time. This happens on complete idle SMP systems while
- * waiting on the login prompt. We also increment the "start of
- * idle" jiffy stamp so the idle accounting adjustment we do
- * when we go busy again does not account too much ticks.
- */
- if (ts->tick_stopped) {
- touch_softlockup_watchdog();
- if (is_idle_task(current))
- ts->idle_jiffies++;
- }
- update_process_times(user_mode(regs));
- profile_tick(CPU_PROFILING);
- }
+ if (regs)
+ tick_sched_handle(ts, regs);
hrtimer_forward(timer, now, tick_period);
@@ -874,7 +863,7 @@ void tick_setup_sched_timer(void)
/* Get the next period (per cpu) */
hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update());
- /* Offset the tick to avert xtime_lock contention. */
+ /* Offset the tick to avert jiffies_lock contention. */
if (sched_skew_tick) {
u64 offset = ktime_to_ns(tick_period) >> 1;
do_div(offset, num_possible_cpus());
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index e424970bb56..4c7de02eacd 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -25,12 +25,6 @@
static struct timekeeper timekeeper;
-/*
- * This read-write spinlock protects us from races in SMP while
- * playing with xtime.
- */
-__cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
-
/* flag for if timekeeping is suspended */
int __read_mostly timekeeping_suspended;
@@ -1299,9 +1293,7 @@ struct timespec get_monotonic_coarse(void)
}
/*
- * The 64-bit jiffies value is not atomic - you MUST NOT read it
- * without sampling the sequence number in xtime_lock.
- * jiffies is defined in the linker script...
+ * Must hold jiffies_lock
*/
void do_timer(unsigned long ticks)
{
@@ -1389,7 +1381,7 @@ EXPORT_SYMBOL_GPL(ktime_get_monotonic_offset);
*/
void xtime_update(unsigned long ticks)
{
- write_seqlock(&xtime_lock);
+ write_seqlock(&jiffies_lock);
do_timer(ticks);
- write_sequnlock(&xtime_lock);
+ write_sequnlock(&jiffies_lock);
}
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 4cea4f41c1d..5d89335a485 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -119,6 +119,7 @@ config TRACING
select BINARY_PRINTF
select EVENT_TRACING
select TRACE_CLOCK
+ select IRQ_WORK
config GENERIC_TRACER
bool
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 9dcf15d3838..7693aaf324c 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -2437,7 +2437,7 @@ static void reset_iter_read(struct ftrace_iterator *iter)
{
iter->pos = 0;
iter->func_pos = 0;
- iter->flags &= ~(FTRACE_ITER_PRINTALL & FTRACE_ITER_HASH);
+ iter->flags &= ~(FTRACE_ITER_PRINTALL | FTRACE_ITER_HASH);
}
static void *t_start(struct seq_file *m, loff_t *pos)
@@ -2868,7 +2868,7 @@ static int __init ftrace_mod_cmd_init(void)
{
return register_ftrace_command(&ftrace_mod_cmd);
}
-device_initcall(ftrace_mod_cmd_init);
+core_initcall(ftrace_mod_cmd_init);
static void function_trace_probe_call(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *op, struct pt_regs *pt_regs)
@@ -4055,7 +4055,7 @@ static int __init ftrace_nodyn_init(void)
ftrace_enabled = 1;
return 0;
}
-device_initcall(ftrace_nodyn_init);
+core_initcall(ftrace_nodyn_init);
static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; }
static inline void ftrace_startup_enable(int command) { }
@@ -4381,7 +4381,7 @@ ftrace_pid_write(struct file *filp, const char __user *ubuf,
if (strlen(tmp) == 0)
return 1;
- ret = strict_strtol(tmp, 10, &val);
+ ret = kstrtol(tmp, 10, &val);
if (ret < 0)
return ret;
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index b979426d16c..ce8514feedc 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -460,9 +460,10 @@ struct ring_buffer_per_cpu {
unsigned long lost_events;
unsigned long last_overrun;
local_t entries_bytes;
- local_t commit_overrun;
- local_t overrun;
local_t entries;
+ local_t overrun;
+ local_t commit_overrun;
+ local_t dropped_events;
local_t committing;
local_t commits;
unsigned long read;
@@ -1396,6 +1397,8 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer)
struct list_head *head_page_with_bit;
head_page = &rb_set_head_page(cpu_buffer)->list;
+ if (!head_page)
+ break;
prev_page = head_page->prev;
first_page = pages->next;
@@ -1820,7 +1823,7 @@ rb_add_time_stamp(struct ring_buffer_event *event, u64 delta)
}
/**
- * ring_buffer_update_event - update event type and data
+ * rb_update_event - update event type and data
* @event: the even to update
* @type: the type of event
* @length: the size of the event field in the ring buffer
@@ -2155,8 +2158,10 @@ rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer,
* If we are not in overwrite mode,
* this is easy, just stop here.
*/
- if (!(buffer->flags & RB_FL_OVERWRITE))
+ if (!(buffer->flags & RB_FL_OVERWRITE)) {
+ local_inc(&cpu_buffer->dropped_events);
goto out_reset;
+ }
ret = rb_handle_head_page(cpu_buffer,
tail_page,
@@ -2720,8 +2725,8 @@ EXPORT_SYMBOL_GPL(ring_buffer_discard_commit);
* and not the length of the event which would hold the header.
*/
int ring_buffer_write(struct ring_buffer *buffer,
- unsigned long length,
- void *data)
+ unsigned long length,
+ void *data)
{
struct ring_buffer_per_cpu *cpu_buffer;
struct ring_buffer_event *event;
@@ -2929,12 +2934,12 @@ rb_num_of_entries(struct ring_buffer_per_cpu *cpu_buffer)
* @buffer: The ring buffer
* @cpu: The per CPU buffer to read from.
*/
-unsigned long ring_buffer_oldest_event_ts(struct ring_buffer *buffer, int cpu)
+u64 ring_buffer_oldest_event_ts(struct ring_buffer *buffer, int cpu)
{
unsigned long flags;
struct ring_buffer_per_cpu *cpu_buffer;
struct buffer_page *bpage;
- unsigned long ret;
+ u64 ret = 0;
if (!cpumask_test_cpu(cpu, buffer->cpumask))
return 0;
@@ -2949,7 +2954,8 @@ unsigned long ring_buffer_oldest_event_ts(struct ring_buffer *buffer, int cpu)
bpage = cpu_buffer->reader_page;
else
bpage = rb_set_head_page(cpu_buffer);
- ret = bpage->page->time_stamp;
+ if (bpage)
+ ret = bpage->page->time_stamp;
raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
return ret;
@@ -2995,7 +3001,8 @@ unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu)
EXPORT_SYMBOL_GPL(ring_buffer_entries_cpu);
/**
- * ring_buffer_overrun_cpu - get the number of overruns in a cpu_buffer
+ * ring_buffer_overrun_cpu - get the number of overruns caused by the ring
+ * buffer wrapping around (only if RB_FL_OVERWRITE is on).
* @buffer: The ring buffer
* @cpu: The per CPU buffer to get the number of overruns from
*/
@@ -3015,7 +3022,9 @@ unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu)
EXPORT_SYMBOL_GPL(ring_buffer_overrun_cpu);
/**
- * ring_buffer_commit_overrun_cpu - get the number of overruns caused by commits
+ * ring_buffer_commit_overrun_cpu - get the number of overruns caused by
+ * commits failing due to the buffer wrapping around while there are uncommitted
+ * events, such as during an interrupt storm.
* @buffer: The ring buffer
* @cpu: The per CPU buffer to get the number of overruns from
*/
@@ -3036,6 +3045,28 @@ ring_buffer_commit_overrun_cpu(struct ring_buffer *buffer, int cpu)
EXPORT_SYMBOL_GPL(ring_buffer_commit_overrun_cpu);
/**
+ * ring_buffer_dropped_events_cpu - get the number of dropped events caused by
+ * the ring buffer filling up (only if RB_FL_OVERWRITE is off).
+ * @buffer: The ring buffer
+ * @cpu: The per CPU buffer to get the number of overruns from
+ */
+unsigned long
+ring_buffer_dropped_events_cpu(struct ring_buffer *buffer, int cpu)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ unsigned long ret;
+
+ if (!cpumask_test_cpu(cpu, buffer->cpumask))
+ return 0;
+
+ cpu_buffer = buffer->buffers[cpu];
+ ret = local_read(&cpu_buffer->dropped_events);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(ring_buffer_dropped_events_cpu);
+
+/**
* ring_buffer_entries - get the number of entries in a buffer
* @buffer: The ring buffer
*
@@ -3260,6 +3291,8 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
* Splice the empty reader page into the list around the head.
*/
reader = rb_set_head_page(cpu_buffer);
+ if (!reader)
+ goto out;
cpu_buffer->reader_page->list.next = rb_list_head(reader->list.next);
cpu_buffer->reader_page->list.prev = reader->list.prev;
@@ -3778,12 +3811,17 @@ void
ring_buffer_read_finish(struct ring_buffer_iter *iter)
{
struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
+ unsigned long flags;
/*
* Ring buffer is disabled from recording, here's a good place
- * to check the integrity of the ring buffer.
+ * to check the integrity of the ring buffer.
+ * Must prevent readers from trying to read, as the check
+ * clears the HEAD page and readers require it.
*/
+ raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
rb_check_pages(cpu_buffer);
+ raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
atomic_dec(&cpu_buffer->record_disabled);
atomic_dec(&cpu_buffer->buffer->resize_disabled);
@@ -3864,9 +3902,10 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
local_set(&cpu_buffer->reader_page->page->commit, 0);
cpu_buffer->reader_page->read = 0;
- local_set(&cpu_buffer->commit_overrun, 0);
local_set(&cpu_buffer->entries_bytes, 0);
local_set(&cpu_buffer->overrun, 0);
+ local_set(&cpu_buffer->commit_overrun, 0);
+ local_set(&cpu_buffer->dropped_events, 0);
local_set(&cpu_buffer->entries, 0);
local_set(&cpu_buffer->committing, 0);
local_set(&cpu_buffer->commits, 0);
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 31e4f55773f..b69cc380322 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -19,6 +19,7 @@
#include <linux/seq_file.h>
#include <linux/notifier.h>
#include <linux/irqflags.h>
+#include <linux/irq_work.h>
#include <linux/debugfs.h>
#include <linux/pagemap.h>
#include <linux/hardirq.h>
@@ -78,6 +79,21 @@ static int dummy_set_flag(u32 old_flags, u32 bit, int set)
}
/*
+ * To prevent the comm cache from being overwritten when no
+ * tracing is active, only save the comm when a trace event
+ * occurred.
+ */
+static DEFINE_PER_CPU(bool, trace_cmdline_save);
+
+/*
+ * When a reader is waiting for data, then this variable is
+ * set to true.
+ */
+static bool trace_wakeup_needed;
+
+static struct irq_work trace_work_wakeup;
+
+/*
* Kill all tracing for good (never come back).
* It is initialized to 1 but will turn to zero if the initialization
* of the tracer is successful. But that is the only place that sets
@@ -139,6 +155,18 @@ static int __init set_ftrace_dump_on_oops(char *str)
}
__setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops);
+
+static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata;
+static char *trace_boot_options __initdata;
+
+static int __init set_trace_boot_options(char *str)
+{
+ strncpy(trace_boot_options_buf, str, MAX_TRACER_SIZE);
+ trace_boot_options = trace_boot_options_buf;
+ return 0;
+}
+__setup("trace_options=", set_trace_boot_options);
+
unsigned long long ns2usecs(cycle_t nsec)
{
nsec += 500;
@@ -198,20 +226,9 @@ static struct trace_array max_tr;
static DEFINE_PER_CPU(struct trace_array_cpu, max_tr_data);
-/* tracer_enabled is used to toggle activation of a tracer */
-static int tracer_enabled = 1;
-
-/**
- * tracing_is_enabled - return tracer_enabled status
- *
- * This function is used by other tracers to know the status
- * of the tracer_enabled flag. Tracers may use this function
- * to know if it should enable their features when starting
- * up. See irqsoff tracer for an example (start_irqsoff_tracer).
- */
int tracing_is_enabled(void)
{
- return tracer_enabled;
+ return tracing_is_on();
}
/*
@@ -333,12 +350,18 @@ unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK |
static int trace_stop_count;
static DEFINE_RAW_SPINLOCK(tracing_start_lock);
-static void wakeup_work_handler(struct work_struct *work)
+/**
+ * trace_wake_up - wake up tasks waiting for trace input
+ *
+ * Schedules a delayed work to wake up any task that is blocked on the
+ * trace_wait queue. These is used with trace_poll for tasks polling the
+ * trace.
+ */
+static void trace_wake_up(struct irq_work *work)
{
- wake_up(&trace_wait);
-}
+ wake_up_all(&trace_wait);
-static DECLARE_DELAYED_WORK(wakeup_work, wakeup_work_handler);
+}
/**
* tracing_on - enable tracing buffers
@@ -393,22 +416,6 @@ int tracing_is_on(void)
}
EXPORT_SYMBOL_GPL(tracing_is_on);
-/**
- * trace_wake_up - wake up tasks waiting for trace input
- *
- * Schedules a delayed work to wake up any task that is blocked on the
- * trace_wait queue. These is used with trace_poll for tasks polling the
- * trace.
- */
-void trace_wake_up(void)
-{
- const unsigned long delay = msecs_to_jiffies(2);
-
- if (trace_flags & TRACE_ITER_BLOCK)
- return;
- schedule_delayed_work(&wakeup_work, delay);
-}
-
static int __init set_buf_size(char *str)
{
unsigned long buf_size;
@@ -431,7 +438,7 @@ static int __init set_tracing_thresh(char *str)
if (!str)
return 0;
- ret = strict_strtoul(str, 0, &threshold);
+ ret = kstrtoul(str, 0, &threshold);
if (ret < 0)
return 0;
tracing_thresh = threshold * 1000;
@@ -477,10 +484,12 @@ static const char *trace_options[] = {
static struct {
u64 (*func)(void);
const char *name;
+ int in_ns; /* is this clock in nanoseconds? */
} trace_clocks[] = {
- { trace_clock_local, "local" },
- { trace_clock_global, "global" },
- { trace_clock_counter, "counter" },
+ { trace_clock_local, "local", 1 },
+ { trace_clock_global, "global", 1 },
+ { trace_clock_counter, "counter", 0 },
+ ARCH_TRACE_CLOCKS
};
int trace_clock_id;
@@ -757,6 +766,40 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
}
#endif /* CONFIG_TRACER_MAX_TRACE */
+static void default_wait_pipe(struct trace_iterator *iter)
+{
+ DEFINE_WAIT(wait);
+
+ prepare_to_wait(&trace_wait, &wait, TASK_INTERRUPTIBLE);
+
+ /*
+ * The events can happen in critical sections where
+ * checking a work queue can cause deadlocks.
+ * After adding a task to the queue, this flag is set
+ * only to notify events to try to wake up the queue
+ * using irq_work.
+ *
+ * We don't clear it even if the buffer is no longer
+ * empty. The flag only causes the next event to run
+ * irq_work to do the work queue wake up. The worse
+ * that can happen if we race with !trace_empty() is that
+ * an event will cause an irq_work to try to wake up
+ * an empty queue.
+ *
+ * There's no reason to protect this flag either, as
+ * the work queue and irq_work logic will do the necessary
+ * synchronization for the wake ups. The only thing
+ * that is necessary is that the wake up happens after
+ * a task has been queued. It's OK for spurious wake ups.
+ */
+ trace_wakeup_needed = true;
+
+ if (trace_empty(iter))
+ schedule();
+
+ finish_wait(&trace_wait, &wait);
+}
+
/**
* register_tracer - register a tracer with the ftrace system.
* @type - the plugin for the tracer
@@ -875,32 +918,6 @@ int register_tracer(struct tracer *type)
return ret;
}
-void unregister_tracer(struct tracer *type)
-{
- struct tracer **t;
-
- mutex_lock(&trace_types_lock);
- for (t = &trace_types; *t; t = &(*t)->next) {
- if (*t == type)
- goto found;
- }
- pr_info("Tracer %s not registered\n", type->name);
- goto out;
-
- found:
- *t = (*t)->next;
-
- if (type == current_trace && tracer_enabled) {
- tracer_enabled = 0;
- tracing_stop();
- if (current_trace->stop)
- current_trace->stop(&global_trace);
- current_trace = &nop_trace;
- }
-out:
- mutex_unlock(&trace_types_lock);
-}
-
void tracing_reset(struct trace_array *tr, int cpu)
{
struct ring_buffer *buffer = tr->buffer;
@@ -1131,10 +1148,14 @@ void trace_find_cmdline(int pid, char comm[])
void tracing_record_cmdline(struct task_struct *tsk)
{
- if (atomic_read(&trace_record_cmdline_disabled) || !tracer_enabled ||
- !tracing_is_on())
+ if (atomic_read(&trace_record_cmdline_disabled) || !tracing_is_on())
return;
+ if (!__this_cpu_read(trace_cmdline_save))
+ return;
+
+ __this_cpu_write(trace_cmdline_save, false);
+
trace_save_cmdline(tsk);
}
@@ -1178,27 +1199,36 @@ trace_buffer_lock_reserve(struct ring_buffer *buffer,
return event;
}
+void
+__buffer_unlock_commit(struct ring_buffer *buffer, struct ring_buffer_event *event)
+{
+ __this_cpu_write(trace_cmdline_save, true);
+ if (trace_wakeup_needed) {
+ trace_wakeup_needed = false;
+ /* irq_work_queue() supplies it's own memory barriers */
+ irq_work_queue(&trace_work_wakeup);
+ }
+ ring_buffer_unlock_commit(buffer, event);
+}
+
static inline void
__trace_buffer_unlock_commit(struct ring_buffer *buffer,
struct ring_buffer_event *event,
- unsigned long flags, int pc,
- int wake)
+ unsigned long flags, int pc)
{
- ring_buffer_unlock_commit(buffer, event);
+ __buffer_unlock_commit(buffer, event);
ftrace_trace_stack(buffer, flags, 6, pc);
ftrace_trace_userstack(buffer, flags, pc);
-
- if (wake)
- trace_wake_up();
}
void trace_buffer_unlock_commit(struct ring_buffer *buffer,
struct ring_buffer_event *event,
unsigned long flags, int pc)
{
- __trace_buffer_unlock_commit(buffer, event, flags, pc, 1);
+ __trace_buffer_unlock_commit(buffer, event, flags, pc);
}
+EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit);
struct ring_buffer_event *
trace_current_buffer_lock_reserve(struct ring_buffer **current_rb,
@@ -1215,29 +1245,21 @@ void trace_current_buffer_unlock_commit(struct ring_buffer *buffer,
struct ring_buffer_event *event,
unsigned long flags, int pc)
{
- __trace_buffer_unlock_commit(buffer, event, flags, pc, 1);
+ __trace_buffer_unlock_commit(buffer, event, flags, pc);
}
EXPORT_SYMBOL_GPL(trace_current_buffer_unlock_commit);
-void trace_nowake_buffer_unlock_commit(struct ring_buffer *buffer,
- struct ring_buffer_event *event,
- unsigned long flags, int pc)
+void trace_buffer_unlock_commit_regs(struct ring_buffer *buffer,
+ struct ring_buffer_event *event,
+ unsigned long flags, int pc,
+ struct pt_regs *regs)
{
- __trace_buffer_unlock_commit(buffer, event, flags, pc, 0);
-}
-EXPORT_SYMBOL_GPL(trace_nowake_buffer_unlock_commit);
-
-void trace_nowake_buffer_unlock_commit_regs(struct ring_buffer *buffer,
- struct ring_buffer_event *event,
- unsigned long flags, int pc,
- struct pt_regs *regs)
-{
- ring_buffer_unlock_commit(buffer, event);
+ __buffer_unlock_commit(buffer, event);
ftrace_trace_stack_regs(buffer, flags, 0, pc, regs);
ftrace_trace_userstack(buffer, flags, pc);
}
-EXPORT_SYMBOL_GPL(trace_nowake_buffer_unlock_commit_regs);
+EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit_regs);
void trace_current_buffer_discard_commit(struct ring_buffer *buffer,
struct ring_buffer_event *event)
@@ -1269,7 +1291,7 @@ trace_function(struct trace_array *tr,
entry->parent_ip = parent_ip;
if (!filter_check_discard(call, entry, buffer, event))
- ring_buffer_unlock_commit(buffer, event);
+ __buffer_unlock_commit(buffer, event);
}
void
@@ -1362,7 +1384,7 @@ static void __ftrace_trace_stack(struct ring_buffer *buffer,
entry->size = trace.nr_entries;
if (!filter_check_discard(call, entry, buffer, event))
- ring_buffer_unlock_commit(buffer, event);
+ __buffer_unlock_commit(buffer, event);
out:
/* Again, don't let gcc optimize things here */
@@ -1458,7 +1480,7 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
save_stack_trace_user(&trace);
if (!filter_check_discard(call, entry, buffer, event))
- ring_buffer_unlock_commit(buffer, event);
+ __buffer_unlock_commit(buffer, event);
out_drop_count:
__this_cpu_dec(user_stack_count);
@@ -1559,10 +1581,10 @@ static int alloc_percpu_trace_buffer(void)
return -ENOMEM;
}
+static int buffers_allocated;
+
void trace_printk_init_buffers(void)
{
- static int buffers_allocated;
-
if (buffers_allocated)
return;
@@ -1571,7 +1593,38 @@ void trace_printk_init_buffers(void)
pr_info("ftrace: Allocated trace_printk buffers\n");
+ /* Expand the buffers to set size */
+ tracing_update_buffers();
+
buffers_allocated = 1;
+
+ /*
+ * trace_printk_init_buffers() can be called by modules.
+ * If that happens, then we need to start cmdline recording
+ * directly here. If the global_trace.buffer is already
+ * allocated here, then this was called by module code.
+ */
+ if (global_trace.buffer)
+ tracing_start_cmdline_record();
+}
+
+void trace_printk_start_comm(void)
+{
+ /* Start tracing comms if trace printk is set */
+ if (!buffers_allocated)
+ return;
+ tracing_start_cmdline_record();
+}
+
+static void trace_printk_start_stop_comm(int enabled)
+{
+ if (!buffers_allocated)
+ return;
+
+ if (enabled)
+ tracing_start_cmdline_record();
+ else
+ tracing_stop_cmdline_record();
}
/**
@@ -1622,7 +1675,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
memcpy(entry->buf, tbuffer, sizeof(u32) * len);
if (!filter_check_discard(call, entry, buffer, event)) {
- ring_buffer_unlock_commit(buffer, event);
+ __buffer_unlock_commit(buffer, event);
ftrace_trace_stack(buffer, flags, 6, pc);
}
@@ -1693,7 +1746,7 @@ int trace_array_vprintk(struct trace_array *tr,
memcpy(&entry->buf, tbuffer, len);
entry->buf[len] = '\0';
if (!filter_check_discard(call, entry, buffer, event)) {
- ring_buffer_unlock_commit(buffer, event);
+ __buffer_unlock_commit(buffer, event);
ftrace_trace_stack(buffer, flags, 6, pc);
}
out:
@@ -2426,6 +2479,10 @@ __tracing_open(struct inode *inode, struct file *file)
if (ring_buffer_overruns(iter->tr->buffer))
iter->iter_flags |= TRACE_FILE_ANNOTATE;
+ /* Output in nanoseconds only if we are using a clock in nanoseconds. */
+ if (trace_clocks[trace_clock_id].in_ns)
+ iter->iter_flags |= TRACE_FILE_TIME_IN_NS;
+
/* stop the trace while dumping */
tracing_stop();
@@ -2794,26 +2851,19 @@ static void set_tracer_flags(unsigned int mask, int enabled)
if (mask == TRACE_ITER_OVERWRITE)
ring_buffer_change_overwrite(global_trace.buffer, enabled);
+
+ if (mask == TRACE_ITER_PRINTK)
+ trace_printk_start_stop_comm(enabled);
}
-static ssize_t
-tracing_trace_options_write(struct file *filp, const char __user *ubuf,
- size_t cnt, loff_t *ppos)
+static int trace_set_options(char *option)
{
- char buf[64];
char *cmp;
int neg = 0;
- int ret;
+ int ret = 0;
int i;
- if (cnt >= sizeof(buf))
- return -EINVAL;
-
- if (copy_from_user(&buf, ubuf, cnt))
- return -EFAULT;
-
- buf[cnt] = 0;
- cmp = strstrip(buf);
+ cmp = strstrip(option);
if (strncmp(cmp, "no", 2) == 0) {
neg = 1;
@@ -2832,10 +2882,25 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,
mutex_lock(&trace_types_lock);
ret = set_tracer_option(current_trace, cmp, neg);
mutex_unlock(&trace_types_lock);
- if (ret)
- return ret;
}
+ return ret;
+}
+
+static ssize_t
+tracing_trace_options_write(struct file *filp, const char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ char buf[64];
+
+ if (cnt >= sizeof(buf))
+ return -EINVAL;
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ return -EFAULT;
+
+ trace_set_options(buf);
+
*ppos += cnt;
return cnt;
@@ -2940,56 +3005,6 @@ static const struct file_operations tracing_saved_cmdlines_fops = {
};
static ssize_t
-tracing_ctrl_read(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- char buf[64];
- int r;
-
- r = sprintf(buf, "%u\n", tracer_enabled);
- return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
-}
-
-static ssize_t
-tracing_ctrl_write(struct file *filp, const char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- struct trace_array *tr = filp->private_data;
- unsigned long val;
- int ret;
-
- ret = kstrtoul_from_user(ubuf, cnt, 10, &val);
- if (ret)
- return ret;
-
- val = !!val;
-
- mutex_lock(&trace_types_lock);
- if (tracer_enabled ^ val) {
-
- /* Only need to warn if this is used to change the state */
- WARN_ONCE(1, "tracing_enabled is deprecated. Use tracing_on");
-
- if (val) {
- tracer_enabled = 1;
- if (current_trace->start)
- current_trace->start(tr);
- tracing_start();
- } else {
- tracer_enabled = 0;
- tracing_stop();
- if (current_trace->stop)
- current_trace->stop(tr);
- }
- }
- mutex_unlock(&trace_types_lock);
-
- *ppos += cnt;
-
- return cnt;
-}
-
-static ssize_t
tracing_set_trace_read(struct file *filp, char __user *ubuf,
size_t cnt, loff_t *ppos)
{
@@ -3030,6 +3045,10 @@ static int __tracing_resize_ring_buffer(unsigned long size, int cpu)
*/
ring_buffer_expanded = 1;
+ /* May be called before buffers are initialized */
+ if (!global_trace.buffer)
+ return 0;
+
ret = ring_buffer_resize(global_trace.buffer, size, cpu);
if (ret < 0)
return ret;
@@ -3325,6 +3344,10 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp)
if (trace_flags & TRACE_ITER_LATENCY_FMT)
iter->iter_flags |= TRACE_FILE_LAT_FMT;
+ /* Output in nanoseconds only if we are using a clock in nanoseconds. */
+ if (trace_clocks[trace_clock_id].in_ns)
+ iter->iter_flags |= TRACE_FILE_TIME_IN_NS;
+
iter->cpu_file = cpu_file;
iter->tr = &global_trace;
mutex_init(&iter->mutex);
@@ -3385,19 +3408,6 @@ tracing_poll_pipe(struct file *filp, poll_table *poll_table)
}
}
-
-void default_wait_pipe(struct trace_iterator *iter)
-{
- DEFINE_WAIT(wait);
-
- prepare_to_wait(&trace_wait, &wait, TASK_INTERRUPTIBLE);
-
- if (trace_empty(iter))
- schedule();
-
- finish_wait(&trace_wait, &wait);
-}
-
/*
* This is a make-shift waitqueue.
* A tracer might use this callback on some rare cases:
@@ -3438,7 +3448,7 @@ static int tracing_wait_pipe(struct file *filp)
return -EINTR;
/*
- * We block until we read something and tracing is disabled.
+ * We block until we read something and tracing is enabled.
* We still block if tracing is disabled, but we have never
* read anything. This allows a user to cat this file, and
* then enable tracing. But after we have read something,
@@ -3446,7 +3456,7 @@ static int tracing_wait_pipe(struct file *filp)
*
* iter->pos will be 0 if we haven't read anything.
*/
- if (!tracer_enabled && iter->pos)
+ if (tracing_is_enabled() && iter->pos)
break;
}
@@ -3955,7 +3965,7 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
} else
entry->buf[cnt] = '\0';
- ring_buffer_unlock_commit(buffer, event);
+ __buffer_unlock_commit(buffer, event);
written = cnt;
@@ -4016,6 +4026,14 @@ static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf,
if (max_tr.buffer)
ring_buffer_set_clock(max_tr.buffer, trace_clocks[i].func);
+ /*
+ * New clock may not be consistent with the previous clock.
+ * Reset the buffer so that it doesn't have incomparable timestamps.
+ */
+ tracing_reset_online_cpus(&global_trace);
+ if (max_tr.buffer)
+ tracing_reset_online_cpus(&max_tr);
+
mutex_unlock(&trace_types_lock);
*fpos += cnt;
@@ -4037,13 +4055,6 @@ static const struct file_operations tracing_max_lat_fops = {
.llseek = generic_file_llseek,
};
-static const struct file_operations tracing_ctrl_fops = {
- .open = tracing_open_generic,
- .read = tracing_ctrl_read,
- .write = tracing_ctrl_write,
- .llseek = generic_file_llseek,
-};
-
static const struct file_operations set_tracer_fops = {
.open = tracing_open_generic,
.read = tracing_set_trace_read,
@@ -4377,13 +4388,27 @@ tracing_stats_read(struct file *filp, char __user *ubuf,
cnt = ring_buffer_bytes_cpu(tr->buffer, cpu);
trace_seq_printf(s, "bytes: %ld\n", cnt);
- t = ns2usecs(ring_buffer_oldest_event_ts(tr->buffer, cpu));
- usec_rem = do_div(t, USEC_PER_SEC);
- trace_seq_printf(s, "oldest event ts: %5llu.%06lu\n", t, usec_rem);
+ if (trace_clocks[trace_clock_id].in_ns) {
+ /* local or global for trace_clock */
+ t = ns2usecs(ring_buffer_oldest_event_ts(tr->buffer, cpu));
+ usec_rem = do_div(t, USEC_PER_SEC);
+ trace_seq_printf(s, "oldest event ts: %5llu.%06lu\n",
+ t, usec_rem);
+
+ t = ns2usecs(ring_buffer_time_stamp(tr->buffer, cpu));
+ usec_rem = do_div(t, USEC_PER_SEC);
+ trace_seq_printf(s, "now ts: %5llu.%06lu\n", t, usec_rem);
+ } else {
+ /* counter or tsc mode for trace_clock */
+ trace_seq_printf(s, "oldest event ts: %llu\n",
+ ring_buffer_oldest_event_ts(tr->buffer, cpu));
+
+ trace_seq_printf(s, "now ts: %llu\n",
+ ring_buffer_time_stamp(tr->buffer, cpu));
+ }
- t = ns2usecs(ring_buffer_time_stamp(tr->buffer, cpu));
- usec_rem = do_div(t, USEC_PER_SEC);
- trace_seq_printf(s, "now ts: %5llu.%06lu\n", t, usec_rem);
+ cnt = ring_buffer_dropped_events_cpu(tr->buffer, cpu);
+ trace_seq_printf(s, "dropped events: %ld\n", cnt);
count = simple_read_from_buffer(ubuf, count, ppos, s->buffer, s->len);
@@ -4815,9 +4840,6 @@ static __init int tracer_init_debugfs(void)
d_tracer = tracing_init_dentry();
- trace_create_file("tracing_enabled", 0644, d_tracer,
- &global_trace, &tracing_ctrl_fops);
-
trace_create_file("trace_options", 0644, d_tracer,
NULL, &tracing_iter_fops);
@@ -5089,6 +5111,7 @@ __init static int tracer_alloc_buffers(void)
/* Only allocate trace_printk buffers if a trace_printk exists */
if (__stop___trace_bprintk_fmt != __start___trace_bprintk_fmt)
+ /* Must be called before global_trace.buffer is allocated */
trace_printk_init_buffers();
/* To save memory, keep the ring buffer size to its minimum */
@@ -5136,6 +5159,7 @@ __init static int tracer_alloc_buffers(void)
#endif
trace_init_cmdlines();
+ init_irq_work(&trace_work_wakeup, trace_wake_up);
register_tracer(&nop_trace);
current_trace = &nop_trace;
@@ -5147,6 +5171,13 @@ __init static int tracer_alloc_buffers(void)
register_die_notifier(&trace_die_notifier);
+ while (trace_boot_options) {
+ char *option;
+
+ option = strsep(&trace_boot_options, ",");
+ trace_set_options(option);
+ }
+
return 0;
out_free_cpumask:
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index c15f528c1af..c75d7988902 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -285,8 +285,8 @@ struct tracer {
int (*set_flag)(u32 old_flags, u32 bit, int set);
struct tracer *next;
struct tracer_flags *flags;
- int print_max;
- int use_max_tr;
+ bool print_max;
+ bool use_max_tr;
};
@@ -327,7 +327,6 @@ trace_buffer_iter(struct trace_iterator *iter, int cpu)
int tracer_init(struct tracer *t, struct trace_array *tr);
int tracing_is_enabled(void);
-void trace_wake_up(void);
void tracing_reset(struct trace_array *tr, int cpu);
void tracing_reset_online_cpus(struct trace_array *tr);
void tracing_reset_current(int cpu);
@@ -349,9 +348,6 @@ trace_buffer_lock_reserve(struct ring_buffer *buffer,
unsigned long len,
unsigned long flags,
int pc);
-void trace_buffer_unlock_commit(struct ring_buffer *buffer,
- struct ring_buffer_event *event,
- unsigned long flags, int pc);
struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
struct trace_array_cpu *data);
@@ -359,6 +355,9 @@ struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
int *ent_cpu, u64 *ent_ts);
+void __buffer_unlock_commit(struct ring_buffer *buffer,
+ struct ring_buffer_event *event);
+
int trace_empty(struct trace_iterator *iter);
void *trace_find_next_entry_inc(struct trace_iterator *iter);
@@ -367,7 +366,6 @@ void trace_init_global_iter(struct trace_iterator *iter);
void tracing_iter_reset(struct trace_iterator *iter, int cpu);
-void default_wait_pipe(struct trace_iterator *iter);
void poll_wait_pipe(struct trace_iterator *iter);
void ftrace(struct trace_array *tr,
@@ -407,12 +405,7 @@ void tracing_sched_switch_assign_trace(struct trace_array *tr);
void tracing_stop_sched_switch_record(void);
void tracing_start_sched_switch_record(void);
int register_tracer(struct tracer *type);
-void unregister_tracer(struct tracer *type);
int is_tracing_stopped(void);
-enum trace_file_type {
- TRACE_FILE_LAT_FMT = 1,
- TRACE_FILE_ANNOTATE = 2,
-};
extern cpumask_var_t __read_mostly tracing_buffer_mask;
@@ -841,6 +834,7 @@ extern const char *__start___trace_bprintk_fmt[];
extern const char *__stop___trace_bprintk_fmt[];
void trace_printk_init_buffers(void);
+void trace_printk_start_comm(void);
#undef FTRACE_ENTRY
#define FTRACE_ENTRY(call, struct_name, id, tstruct, print, filter) \
diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c
index 8d3538b4ea5..95e96842ed2 100644
--- a/kernel/trace/trace_branch.c
+++ b/kernel/trace/trace_branch.c
@@ -77,7 +77,7 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
entry->correct = val == expect;
if (!filter_check_discard(call, entry, buffer, event))
- ring_buffer_unlock_commit(buffer, event);
+ __buffer_unlock_commit(buffer, event);
out:
atomic_dec(&tr->data[cpu]->disabled);
@@ -199,7 +199,7 @@ __init static int init_branch_tracer(void)
}
return register_tracer(&branch_trace);
}
-device_initcall(init_branch_tracer);
+core_initcall(init_branch_tracer);
#else
static inline
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index d608d09d08c..880073d0b94 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -491,19 +491,6 @@ static void t_stop(struct seq_file *m, void *p)
mutex_unlock(&event_mutex);
}
-static int
-ftrace_event_seq_open(struct inode *inode, struct file *file)
-{
- const struct seq_operations *seq_ops;
-
- if ((file->f_mode & FMODE_WRITE) &&
- (file->f_flags & O_TRUNC))
- ftrace_clear_events();
-
- seq_ops = inode->i_private;
- return seq_open(file, seq_ops);
-}
-
static ssize_t
event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
loff_t *ppos)
@@ -980,6 +967,9 @@ show_header(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
return r;
}
+static int ftrace_event_avail_open(struct inode *inode, struct file *file);
+static int ftrace_event_set_open(struct inode *inode, struct file *file);
+
static const struct seq_operations show_event_seq_ops = {
.start = t_start,
.next = t_next,
@@ -995,14 +985,14 @@ static const struct seq_operations show_set_event_seq_ops = {
};
static const struct file_operations ftrace_avail_fops = {
- .open = ftrace_event_seq_open,
+ .open = ftrace_event_avail_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static const struct file_operations ftrace_set_event_fops = {
- .open = ftrace_event_seq_open,
+ .open = ftrace_event_set_open,
.read = seq_read,
.write = ftrace_event_write,
.llseek = seq_lseek,
@@ -1078,6 +1068,26 @@ static struct dentry *event_trace_events_dir(void)
return d_events;
}
+static int
+ftrace_event_avail_open(struct inode *inode, struct file *file)
+{
+ const struct seq_operations *seq_ops = &show_event_seq_ops;
+
+ return seq_open(file, seq_ops);
+}
+
+static int
+ftrace_event_set_open(struct inode *inode, struct file *file)
+{
+ const struct seq_operations *seq_ops = &show_set_event_seq_ops;
+
+ if ((file->f_mode & FMODE_WRITE) &&
+ (file->f_flags & O_TRUNC))
+ ftrace_clear_events();
+
+ return seq_open(file, seq_ops);
+}
+
static struct dentry *
event_subsystem_dir(const char *name, struct dentry *d_events)
{
@@ -1489,6 +1499,9 @@ static __init int event_trace_enable(void)
if (ret)
pr_warn("Failed to enable trace event: %s\n", token);
}
+
+ trace_printk_start_comm();
+
return 0;
}
@@ -1505,15 +1518,13 @@ static __init int event_trace_init(void)
return 0;
entry = debugfs_create_file("available_events", 0444, d_tracer,
- (void *)&show_event_seq_ops,
- &ftrace_avail_fops);
+ NULL, &ftrace_avail_fops);
if (!entry)
pr_warning("Could not create debugfs "
"'available_events' entry\n");
entry = debugfs_create_file("set_event", 0644, d_tracer,
- (void *)&show_set_event_seq_ops,
- &ftrace_set_event_fops);
+ NULL, &ftrace_set_event_fops);
if (!entry)
pr_warning("Could not create debugfs "
"'set_event' entry\n");
@@ -1749,7 +1760,7 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip,
entry->ip = ip;
entry->parent_ip = parent_ip;
- trace_nowake_buffer_unlock_commit(buffer, event, flags, pc);
+ trace_buffer_unlock_commit(buffer, event, flags, pc);
out:
atomic_dec(&per_cpu(ftrace_test_event_disable, cpu));
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index c154797a7ff..e5b0ca8b8d4 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -1000,9 +1000,9 @@ static int init_pred(struct filter_parse_state *ps,
}
} else {
if (field->is_signed)
- ret = strict_strtoll(pred->regex.pattern, 0, &val);
+ ret = kstrtoll(pred->regex.pattern, 0, &val);
else
- ret = strict_strtoull(pred->regex.pattern, 0, &val);
+ ret = kstrtoull(pred->regex.pattern, 0, &val);
if (ret) {
parse_error(ps, FILT_ERR_ILLEGAL_INTVAL, 0);
return -EINVAL;
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 507a7a9630b..bb227e380cb 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -366,7 +366,7 @@ ftrace_trace_onoff_callback(struct ftrace_hash *hash,
* We use the callback data field (which is a pointer)
* as our counter.
*/
- ret = strict_strtoul(number, 0, (unsigned long *)&count);
+ ret = kstrtoul(number, 0, (unsigned long *)&count);
if (ret)
return ret;
@@ -411,5 +411,4 @@ static __init int init_function_trace(void)
init_func_cmd_traceon();
return register_tracer(&function_trace);
}
-device_initcall(init_function_trace);
-
+core_initcall(init_function_trace);
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index 99b4378393d..4edb4b74eb7 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -223,7 +223,7 @@ int __trace_graph_entry(struct trace_array *tr,
entry = ring_buffer_event_data(event);
entry->graph_ent = *trace;
if (!filter_current_check_discard(buffer, call, entry, event))
- ring_buffer_unlock_commit(buffer, event);
+ __buffer_unlock_commit(buffer, event);
return 1;
}
@@ -327,7 +327,7 @@ void __trace_graph_return(struct trace_array *tr,
entry = ring_buffer_event_data(event);
entry->ret = *trace;
if (!filter_current_check_discard(buffer, call, entry, event))
- ring_buffer_unlock_commit(buffer, event);
+ __buffer_unlock_commit(buffer, event);
}
void trace_graph_return(struct ftrace_graph_ret *trace)
@@ -1474,4 +1474,4 @@ static __init int init_graph_trace(void)
return register_tracer(&graph_trace);
}
-device_initcall(init_graph_trace);
+core_initcall(init_graph_trace);
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index d98ee8283b2..5ffce7b0f33 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -604,7 +604,7 @@ static struct tracer irqsoff_tracer __read_mostly =
.reset = irqsoff_tracer_reset,
.start = irqsoff_tracer_start,
.stop = irqsoff_tracer_stop,
- .print_max = 1,
+ .print_max = true,
.print_header = irqsoff_print_header,
.print_line = irqsoff_print_line,
.flags = &tracer_flags,
@@ -614,7 +614,7 @@ static struct tracer irqsoff_tracer __read_mostly =
#endif
.open = irqsoff_trace_open,
.close = irqsoff_trace_close,
- .use_max_tr = 1,
+ .use_max_tr = true,
};
# define register_irqsoff(trace) register_tracer(&trace)
#else
@@ -637,7 +637,7 @@ static struct tracer preemptoff_tracer __read_mostly =
.reset = irqsoff_tracer_reset,
.start = irqsoff_tracer_start,
.stop = irqsoff_tracer_stop,
- .print_max = 1,
+ .print_max = true,
.print_header = irqsoff_print_header,
.print_line = irqsoff_print_line,
.flags = &tracer_flags,
@@ -647,7 +647,7 @@ static struct tracer preemptoff_tracer __read_mostly =
#endif
.open = irqsoff_trace_open,
.close = irqsoff_trace_close,
- .use_max_tr = 1,
+ .use_max_tr = true,
};
# define register_preemptoff(trace) register_tracer(&trace)
#else
@@ -672,7 +672,7 @@ static struct tracer preemptirqsoff_tracer __read_mostly =
.reset = irqsoff_tracer_reset,
.start = irqsoff_tracer_start,
.stop = irqsoff_tracer_stop,
- .print_max = 1,
+ .print_max = true,
.print_header = irqsoff_print_header,
.print_line = irqsoff_print_line,
.flags = &tracer_flags,
@@ -682,7 +682,7 @@ static struct tracer preemptirqsoff_tracer __read_mostly =
#endif
.open = irqsoff_trace_open,
.close = irqsoff_trace_close,
- .use_max_tr = 1,
+ .use_max_tr = true,
};
# define register_preemptirqsoff(trace) register_tracer(&trace)
@@ -698,4 +698,4 @@ __init static int init_irqsoff_tracer(void)
return 0;
}
-device_initcall(init_irqsoff_tracer);
+core_initcall(init_irqsoff_tracer);
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 1a2117043bb..1865d5f7653 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -444,7 +444,7 @@ static int create_trace_probe(int argc, char **argv)
return -EINVAL;
}
/* an address specified */
- ret = strict_strtoul(&argv[1][0], 0, (unsigned long *)&addr);
+ ret = kstrtoul(&argv[1][0], 0, (unsigned long *)&addr);
if (ret) {
pr_info("Failed to parse address.\n");
return ret;
@@ -751,8 +751,8 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
if (!filter_current_check_discard(buffer, call, entry, event))
- trace_nowake_buffer_unlock_commit_regs(buffer, event,
- irq_flags, pc, regs);
+ trace_buffer_unlock_commit_regs(buffer, event,
+ irq_flags, pc, regs);
}
/* Kretprobe handler */
@@ -784,8 +784,8 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
if (!filter_current_check_discard(buffer, call, entry, event))
- trace_nowake_buffer_unlock_commit_regs(buffer, event,
- irq_flags, pc, regs);
+ trace_buffer_unlock_commit_regs(buffer, event,
+ irq_flags, pc, regs);
}
/* Event entry printers */
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index 123b189c732..194d79602dc 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -610,24 +610,54 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
return trace_print_lat_fmt(s, entry);
}
-static unsigned long preempt_mark_thresh = 100;
+static unsigned long preempt_mark_thresh_us = 100;
static int
-lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
- unsigned long rel_usecs)
+lat_print_timestamp(struct trace_iterator *iter, u64 next_ts)
{
- return trace_seq_printf(s, " %4lldus%c: ", abs_usecs,
- rel_usecs > preempt_mark_thresh ? '!' :
- rel_usecs > 1 ? '+' : ' ');
+ unsigned long verbose = trace_flags & TRACE_ITER_VERBOSE;
+ unsigned long in_ns = iter->iter_flags & TRACE_FILE_TIME_IN_NS;
+ unsigned long long abs_ts = iter->ts - iter->tr->time_start;
+ unsigned long long rel_ts = next_ts - iter->ts;
+ struct trace_seq *s = &iter->seq;
+
+ if (in_ns) {
+ abs_ts = ns2usecs(abs_ts);
+ rel_ts = ns2usecs(rel_ts);
+ }
+
+ if (verbose && in_ns) {
+ unsigned long abs_usec = do_div(abs_ts, USEC_PER_MSEC);
+ unsigned long abs_msec = (unsigned long)abs_ts;
+ unsigned long rel_usec = do_div(rel_ts, USEC_PER_MSEC);
+ unsigned long rel_msec = (unsigned long)rel_ts;
+
+ return trace_seq_printf(
+ s, "[%08llx] %ld.%03ldms (+%ld.%03ldms): ",
+ ns2usecs(iter->ts),
+ abs_msec, abs_usec,
+ rel_msec, rel_usec);
+ } else if (verbose && !in_ns) {
+ return trace_seq_printf(
+ s, "[%016llx] %lld (+%lld): ",
+ iter->ts, abs_ts, rel_ts);
+ } else if (!verbose && in_ns) {
+ return trace_seq_printf(
+ s, " %4lldus%c: ",
+ abs_ts,
+ rel_ts > preempt_mark_thresh_us ? '!' :
+ rel_ts > 1 ? '+' : ' ');
+ } else { /* !verbose && !in_ns */
+ return trace_seq_printf(s, " %4lld: ", abs_ts);
+ }
}
int trace_print_context(struct trace_iterator *iter)
{
struct trace_seq *s = &iter->seq;
struct trace_entry *entry = iter->ent;
- unsigned long long t = ns2usecs(iter->ts);
- unsigned long usec_rem = do_div(t, USEC_PER_SEC);
- unsigned long secs = (unsigned long)t;
+ unsigned long long t;
+ unsigned long secs, usec_rem;
char comm[TASK_COMM_LEN];
int ret;
@@ -644,8 +674,13 @@ int trace_print_context(struct trace_iterator *iter)
return 0;
}
- return trace_seq_printf(s, " %5lu.%06lu: ",
- secs, usec_rem);
+ if (iter->iter_flags & TRACE_FILE_TIME_IN_NS) {
+ t = ns2usecs(iter->ts);
+ usec_rem = do_div(t, USEC_PER_SEC);
+ secs = (unsigned long)t;
+ return trace_seq_printf(s, " %5lu.%06lu: ", secs, usec_rem);
+ } else
+ return trace_seq_printf(s, " %12llu: ", iter->ts);
}
int trace_print_lat_context(struct trace_iterator *iter)
@@ -659,36 +694,29 @@ int trace_print_lat_context(struct trace_iterator *iter)
*next_entry = trace_find_next_entry(iter, NULL,
&next_ts);
unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
- unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);
- unsigned long rel_usecs;
/* Restore the original ent_size */
iter->ent_size = ent_size;
if (!next_entry)
next_ts = iter->ts;
- rel_usecs = ns2usecs(next_ts - iter->ts);
if (verbose) {
char comm[TASK_COMM_LEN];
trace_find_cmdline(entry->pid, comm);
- ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08llx]"
- " %ld.%03ldms (+%ld.%03ldms): ", comm,
- entry->pid, iter->cpu, entry->flags,
- entry->preempt_count, iter->idx,
- ns2usecs(iter->ts),
- abs_usecs / USEC_PER_MSEC,
- abs_usecs % USEC_PER_MSEC,
- rel_usecs / USEC_PER_MSEC,
- rel_usecs % USEC_PER_MSEC);
+ ret = trace_seq_printf(
+ s, "%16s %5d %3d %d %08x %08lx ",
+ comm, entry->pid, iter->cpu, entry->flags,
+ entry->preempt_count, iter->idx);
} else {
ret = lat_print_generic(s, entry, iter->cpu);
- if (ret)
- ret = lat_print_timestamp(s, abs_usecs, rel_usecs);
}
+ if (ret)
+ ret = lat_print_timestamp(iter, next_ts);
+
return ret;
}
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index daa9980153a..412e959709b 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -441,7 +441,7 @@ static const struct fetch_type *find_fetch_type(const char *type)
goto fail;
type++;
- if (strict_strtoul(type, 0, &bs))
+ if (kstrtoul(type, 0, &bs))
goto fail;
switch (bs) {
@@ -501,8 +501,8 @@ int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset)
tmp = strchr(symbol, '+');
if (tmp) {
- /* skip sign because strict_strtol doesn't accept '+' */
- ret = strict_strtoul(tmp + 1, 0, offset);
+ /* skip sign because kstrtoul doesn't accept '+' */
+ ret = kstrtoul(tmp + 1, 0, offset);
if (ret)
return ret;
@@ -533,7 +533,7 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
else
ret = -EINVAL;
} else if (isdigit(arg[5])) {
- ret = strict_strtoul(arg + 5, 10, &param);
+ ret = kstrtoul(arg + 5, 10, &param);
if (ret || param > PARAM_MAX_STACK)
ret = -EINVAL;
else {
@@ -579,7 +579,7 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t,
case '@': /* memory or symbol */
if (isdigit(arg[1])) {
- ret = strict_strtoul(arg + 1, 0, &param);
+ ret = kstrtoul(arg + 1, 0, &param);
if (ret)
break;
@@ -597,14 +597,14 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t,
break;
case '+': /* deref memory */
- arg++; /* Skip '+', because strict_strtol() rejects it. */
+ arg++; /* Skip '+', because kstrtol() rejects it. */
case '-':
tmp = strchr(arg, '(');
if (!tmp)
break;
*tmp = '\0';
- ret = strict_strtol(arg, 0, &offset);
+ ret = kstrtol(arg, 0, &offset);
if (ret)
break;
diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c
index 7e62c0a1845..3374c792ccd 100644
--- a/kernel/trace/trace_sched_switch.c
+++ b/kernel/trace/trace_sched_switch.c
@@ -102,9 +102,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
entry->next_cpu = task_cpu(wakee);
if (!filter_check_discard(call, entry, buffer, event))
- ring_buffer_unlock_commit(buffer, event);
- ftrace_trace_stack(tr->buffer, flags, 6, pc);
- ftrace_trace_userstack(tr->buffer, flags, pc);
+ trace_buffer_unlock_commit(buffer, event, flags, pc);
}
static void
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c
index 02170c00c41..bc64fc13755 100644
--- a/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/trace/trace_sched_wakeup.c
@@ -589,7 +589,7 @@ static struct tracer wakeup_tracer __read_mostly =
.reset = wakeup_tracer_reset,
.start = wakeup_tracer_start,
.stop = wakeup_tracer_stop,
- .print_max = 1,
+ .print_max = true,
.print_header = wakeup_print_header,
.print_line = wakeup_print_line,
.flags = &tracer_flags,
@@ -599,7 +599,7 @@ static struct tracer wakeup_tracer __read_mostly =
#endif
.open = wakeup_trace_open,
.close = wakeup_trace_close,
- .use_max_tr = 1,
+ .use_max_tr = true,
};
static struct tracer wakeup_rt_tracer __read_mostly =
@@ -610,7 +610,7 @@ static struct tracer wakeup_rt_tracer __read_mostly =
.start = wakeup_tracer_start,
.stop = wakeup_tracer_stop,
.wait_pipe = poll_wait_pipe,
- .print_max = 1,
+ .print_max = true,
.print_header = wakeup_print_header,
.print_line = wakeup_print_line,
.flags = &tracer_flags,
@@ -620,7 +620,7 @@ static struct tracer wakeup_rt_tracer __read_mostly =
#endif
.open = wakeup_trace_open,
.close = wakeup_trace_close,
- .use_max_tr = 1,
+ .use_max_tr = true,
};
__init static int init_wakeup_tracer(void)
@@ -637,4 +637,4 @@ __init static int init_wakeup_tracer(void)
return 0;
}
-device_initcall(init_wakeup_tracer);
+core_initcall(init_wakeup_tracer);
diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c
index 2c00a691a54..47623169a81 100644
--- a/kernel/trace/trace_selftest.c
+++ b/kernel/trace/trace_selftest.c
@@ -320,7 +320,6 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
int (*func)(void))
{
int save_ftrace_enabled = ftrace_enabled;
- int save_tracer_enabled = tracer_enabled;
unsigned long count;
char *func_name;
int ret;
@@ -331,7 +330,6 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
/* enable tracing, and record the filter function */
ftrace_enabled = 1;
- tracer_enabled = 1;
/* passed in by parameter to fool gcc from optimizing */
func();
@@ -395,7 +393,6 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
out:
ftrace_enabled = save_ftrace_enabled;
- tracer_enabled = save_tracer_enabled;
/* Enable tracing on all functions again */
ftrace_set_global_filter(NULL, 0, 1);
@@ -452,7 +449,6 @@ static int
trace_selftest_function_recursion(void)
{
int save_ftrace_enabled = ftrace_enabled;
- int save_tracer_enabled = tracer_enabled;
char *func_name;
int len;
int ret;
@@ -465,7 +461,6 @@ trace_selftest_function_recursion(void)
/* enable tracing, and record the filter function */
ftrace_enabled = 1;
- tracer_enabled = 1;
/* Handle PPC64 '.' name */
func_name = "*" __stringify(DYN_FTRACE_TEST_NAME);
@@ -534,7 +529,6 @@ trace_selftest_function_recursion(void)
ret = 0;
out:
ftrace_enabled = save_ftrace_enabled;
- tracer_enabled = save_tracer_enabled;
return ret;
}
@@ -569,7 +563,6 @@ static int
trace_selftest_function_regs(void)
{
int save_ftrace_enabled = ftrace_enabled;
- int save_tracer_enabled = tracer_enabled;
char *func_name;
int len;
int ret;
@@ -586,7 +579,6 @@ trace_selftest_function_regs(void)
/* enable tracing, and record the filter function */
ftrace_enabled = 1;
- tracer_enabled = 1;
/* Handle PPC64 '.' name */
func_name = "*" __stringify(DYN_FTRACE_TEST_NAME);
@@ -648,7 +640,6 @@ trace_selftest_function_regs(void)
ret = 0;
out:
ftrace_enabled = save_ftrace_enabled;
- tracer_enabled = save_tracer_enabled;
return ret;
}
@@ -662,7 +653,6 @@ int
trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
{
int save_ftrace_enabled = ftrace_enabled;
- int save_tracer_enabled = tracer_enabled;
unsigned long count;
int ret;
@@ -671,7 +661,6 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
/* start the tracing */
ftrace_enabled = 1;
- tracer_enabled = 1;
ret = tracer_init(trace, tr);
if (ret) {
@@ -708,7 +697,6 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
ret = trace_selftest_function_regs();
out:
ftrace_enabled = save_ftrace_enabled;
- tracer_enabled = save_tracer_enabled;
/* kill ftrace totally if we failed */
if (ret)
@@ -1106,6 +1094,7 @@ trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr)
tracing_stop();
/* check both trace buffers */
ret = trace_test_buffer(tr, NULL);
+ printk("ret = %d\n", ret);
if (!ret)
ret = trace_test_buffer(&max_tr, &count);
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index 2485a7d09b1..7609dd6714c 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -21,9 +21,6 @@ static int syscall_enter_register(struct ftrace_event_call *event,
static int syscall_exit_register(struct ftrace_event_call *event,
enum trace_reg type, void *data);
-static int syscall_enter_define_fields(struct ftrace_event_call *call);
-static int syscall_exit_define_fields(struct ftrace_event_call *call);
-
static struct list_head *
syscall_get_enter_fields(struct ftrace_event_call *call)
{
@@ -32,30 +29,6 @@ syscall_get_enter_fields(struct ftrace_event_call *call)
return &entry->enter_fields;
}
-struct trace_event_functions enter_syscall_print_funcs = {
- .trace = print_syscall_enter,
-};
-
-struct trace_event_functions exit_syscall_print_funcs = {
- .trace = print_syscall_exit,
-};
-
-struct ftrace_event_class event_class_syscall_enter = {
- .system = "syscalls",
- .reg = syscall_enter_register,
- .define_fields = syscall_enter_define_fields,
- .get_fields = syscall_get_enter_fields,
- .raw_init = init_syscall_trace,
-};
-
-struct ftrace_event_class event_class_syscall_exit = {
- .system = "syscalls",
- .reg = syscall_exit_register,
- .define_fields = syscall_exit_define_fields,
- .fields = LIST_HEAD_INIT(event_class_syscall_exit.fields),
- .raw_init = init_syscall_trace,
-};
-
extern struct syscall_metadata *__start_syscalls_metadata[];
extern struct syscall_metadata *__stop_syscalls_metadata[];
@@ -432,7 +405,7 @@ void unreg_event_syscall_exit(struct ftrace_event_call *call)
mutex_unlock(&syscall_trace_lock);
}
-int init_syscall_trace(struct ftrace_event_call *call)
+static int init_syscall_trace(struct ftrace_event_call *call)
{
int id;
int num;
@@ -457,6 +430,30 @@ int init_syscall_trace(struct ftrace_event_call *call)
return id;
}
+struct trace_event_functions enter_syscall_print_funcs = {
+ .trace = print_syscall_enter,
+};
+
+struct trace_event_functions exit_syscall_print_funcs = {
+ .trace = print_syscall_exit,
+};
+
+struct ftrace_event_class event_class_syscall_enter = {
+ .system = "syscalls",
+ .reg = syscall_enter_register,
+ .define_fields = syscall_enter_define_fields,
+ .get_fields = syscall_get_enter_fields,
+ .raw_init = init_syscall_trace,
+};
+
+struct ftrace_event_class event_class_syscall_exit = {
+ .system = "syscalls",
+ .reg = syscall_exit_register,
+ .define_fields = syscall_exit_define_fields,
+ .fields = LIST_HEAD_INIT(event_class_syscall_exit.fields),
+ .raw_init = init_syscall_trace,
+};
+
unsigned long __init __weak arch_syscall_addr(int nr)
{
return (unsigned long)sys_call_table[nr];
@@ -537,7 +534,7 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head, NULL);
}
-int perf_sysenter_enable(struct ftrace_event_call *call)
+static int perf_sysenter_enable(struct ftrace_event_call *call)
{
int ret = 0;
int num;
@@ -558,7 +555,7 @@ int perf_sysenter_enable(struct ftrace_event_call *call)
return ret;
}
-void perf_sysenter_disable(struct ftrace_event_call *call)
+static void perf_sysenter_disable(struct ftrace_event_call *call)
{
int num;
@@ -615,7 +612,7 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head, NULL);
}
-int perf_sysexit_enable(struct ftrace_event_call *call)
+static int perf_sysexit_enable(struct ftrace_event_call *call)
{
int ret = 0;
int num;
@@ -636,7 +633,7 @@ int perf_sysexit_enable(struct ftrace_event_call *call)
return ret;
}
-void perf_sysexit_disable(struct ftrace_event_call *call)
+static void perf_sysexit_disable(struct ftrace_event_call *call)
{
int num;
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 03003cd7dd9..9614db8b0f8 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -189,7 +189,7 @@ static int create_trace_uprobe(int argc, char **argv)
if (argv[0][0] == '-')
is_delete = true;
else if (argv[0][0] != 'p') {
- pr_info("Probe definition must be started with 'p', 'r' or" " '-'.\n");
+ pr_info("Probe definition must be started with 'p' or '-'.\n");
return -EINVAL;
}
@@ -252,7 +252,7 @@ static int create_trace_uprobe(int argc, char **argv)
if (ret)
goto fail_address_parse;
- ret = strict_strtoul(arg, 0, &offset);
+ ret = kstrtoul(arg, 0, &offset);
if (ret)
goto fail_address_parse;
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 9d4c8d5a1f5..c8c21be11ab 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -116,7 +116,7 @@ static unsigned long get_timestamp(int this_cpu)
return cpu_clock(this_cpu) >> 30LL; /* 2^30 ~= 10^9 */
}
-static unsigned long get_sample_period(void)
+static u64 get_sample_period(void)
{
/*
* convert watchdog_thresh from seconds to ns
@@ -125,7 +125,7 @@ static unsigned long get_sample_period(void)
* and hard thresholds) to increment before the
* hardlockup detector generates a warning
*/
- return get_softlockup_thresh() * (NSEC_PER_SEC / 5);
+ return get_softlockup_thresh() * ((u64)NSEC_PER_SEC / 5);
}
/* Commands for resetting the watchdog */
@@ -368,6 +368,9 @@ static void watchdog_disable(unsigned int cpu)
{
struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer);
+ if (!watchdog_enabled)
+ return;
+
watchdog_set_prio(SCHED_NORMAL, 0);
hrtimer_cancel(hrtimer);
/* disable the perf event */
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 042d221d33c..1dae900df79 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1361,8 +1361,19 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq,
WARN_ON_ONCE(timer->function != delayed_work_timer_fn ||
timer->data != (unsigned long)dwork);
- BUG_ON(timer_pending(timer));
- BUG_ON(!list_empty(&work->entry));
+ WARN_ON_ONCE(timer_pending(timer));
+ WARN_ON_ONCE(!list_empty(&work->entry));
+
+ /*
+ * If @delay is 0, queue @dwork->work immediately. This is for
+ * both optimization and correctness. The earliest @timer can
+ * expire is on the closest next tick and delayed_work users depend
+ * on that there's no such delay when @delay is 0.
+ */
+ if (!delay) {
+ __queue_work(cpu, wq, &dwork->work);
+ return;
+ }
timer_stats_timer_set_start_info(&dwork->timer);
@@ -1417,9 +1428,6 @@ bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
bool ret = false;
unsigned long flags;
- if (!delay)
- return queue_work_on(cpu, wq, &dwork->work);
-
/* read the comment in __queue_work() */
local_irq_save(flags);
@@ -2407,8 +2415,10 @@ static int rescuer_thread(void *__wq)
repeat:
set_current_state(TASK_INTERRUPTIBLE);
- if (kthread_should_stop())
+ if (kthread_should_stop()) {
+ __set_current_state(TASK_RUNNING);
return 0;
+ }
/*
* See whether any cpu is asking for help. Unbounded
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 28e9d6c9894..41faf0b8df1 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -972,7 +972,7 @@ config RCU_CPU_STALL_TIMEOUT
int "RCU CPU stall timeout in seconds"
depends on TREE_RCU || TREE_PREEMPT_RCU
range 3 300
- default 60
+ default 21
help
If a given RCU grace period extends more than the specified
number of seconds, a CPU stall warning is printed. If the
diff --git a/lib/Makefile b/lib/Makefile
index 821a1622911..e3723c7527d 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -12,7 +12,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
idr.o int_sqrt.o extable.o \
sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \
proportions.o flex_proportions.o prio_heap.o ratelimit.o show_mem.o \
- is_single_threaded.o plist.o decompress.o
+ is_single_threaded.o plist.o decompress.o kobject_uevent.o
lib-$(CONFIG_MMU) += ioremap.o
lib-$(CONFIG_SMP) += cpumask.o
@@ -31,7 +31,6 @@ CFLAGS_kobject.o += -DDEBUG
CFLAGS_kobject_uevent.o += -DDEBUG
endif
-lib-$(CONFIG_HOTPLUG) += kobject_uevent.o
obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
obj-$(CONFIG_GENERIC_PCI_IOMAP) += pci_iomap.o
obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o
@@ -163,7 +162,7 @@ $(obj)/crc32table.h: $(obj)/gen_crc32table
#
obj-$(CONFIG_OID_REGISTRY) += oid_registry.o
-$(obj)/oid_registry.c: $(obj)/oid_registry_data.c
+$(obj)/oid_registry.o: $(obj)/oid_registry_data.c
$(obj)/oid_registry_data.c: $(srctree)/include/linux/oid_registry.h \
$(src)/build_OID_registry
diff --git a/lib/asn1_decoder.c b/lib/asn1_decoder.c
index de2c8b5a715..5293d243302 100644
--- a/lib/asn1_decoder.c
+++ b/lib/asn1_decoder.c
@@ -91,7 +91,7 @@ next_tag:
/* Extract the length */
len = data[dp++];
- if (len < 0x7f) {
+ if (len <= 0x7f) {
dp += len;
goto next_tag;
}
diff --git a/lib/cpumask.c b/lib/cpumask.c
index 402a54ac35c..d327b87c99b 100644
--- a/lib/cpumask.c
+++ b/lib/cpumask.c
@@ -161,6 +161,6 @@ EXPORT_SYMBOL(free_cpumask_var);
*/
void __init free_bootmem_cpumask_var(cpumask_var_t mask)
{
- free_bootmem((unsigned long)mask, cpumask_size());
+ free_bootmem(__pa(mask), cpumask_size());
}
#endif
diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h
index 678ce4f1e12..095ab157a52 100644
--- a/lib/mpi/longlong.h
+++ b/lib/mpi/longlong.h
@@ -641,7 +641,14 @@ do { \
************** MIPS *****************
***************************************/
#if defined(__mips__) && W_TYPE_SIZE == 32
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4
+#define umul_ppmm(w1, w0, u, v) \
+do { \
+ UDItype __ll = (UDItype)(u) * (v); \
+ w1 = __ll >> 32; \
+ w0 = __ll; \
+} while (0)
+#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("multu %2,%3" \
: "=l" ((USItype)(w0)), \
@@ -666,7 +673,15 @@ do { \
************** MIPS/64 **************
***************************************/
#if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4
+#define umul_ppmm(w1, w0, u, v) \
+do { \
+ typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \
+ __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \
+ w1 = __ll >> 64; \
+ w0 = __ll; \
+} while (0)
+#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("dmultu %2,%3" \
: "=l" ((UDItype)(w0)), \
diff --git a/mm/Kconfig b/mm/Kconfig
index a3f8dddaaab..e6651c5de14 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -188,6 +188,21 @@ config SPLIT_PTLOCK_CPUS
default "4"
#
+# support for memory balloon compaction
+config BALLOON_COMPACTION
+ bool "Allow for balloon memory compaction/migration"
+ def_bool y
+ depends on COMPACTION && VIRTIO_BALLOON
+ help
+ Memory fragmentation introduced by ballooning might reduce
+ significantly the number of 2MB contiguous memory blocks that can be
+ used within a guest, thus imposing performance penalties associated
+ with the reduced number of transparent huge pages that could be used
+ by the guest workload. Allowing the compaction & migration for memory
+ pages enlisted as being part of memory balloon devices avoids the
+ scenario aforementioned and helps improving memory defragmentation.
+
+#
# support for memory compaction
config COMPACTION
bool "Allow for memory compaction"
diff --git a/mm/Makefile b/mm/Makefile
index 6b025f80af3..3a4628751f8 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -16,7 +16,8 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \
readahead.o swap.o truncate.o vmscan.o shmem.o \
util.o mmzone.o vmstat.o backing-dev.o \
mm_init.o mmu_context.o percpu.o slab_common.o \
- compaction.o interval_tree.o $(mmu-y)
+ compaction.o balloon_compaction.o \
+ interval_tree.o $(mmu-y)
obj-y += init-mm.o
diff --git a/mm/balloon_compaction.c b/mm/balloon_compaction.c
new file mode 100644
index 00000000000..07dbc8ec46c
--- /dev/null
+++ b/mm/balloon_compaction.c
@@ -0,0 +1,302 @@
+/*
+ * mm/balloon_compaction.c
+ *
+ * Common interface for making balloon pages movable by compaction.
+ *
+ * Copyright (C) 2012, Red Hat, Inc. Rafael Aquini <aquini@redhat.com>
+ */
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/balloon_compaction.h>
+
+/*
+ * balloon_devinfo_alloc - allocates a balloon device information descriptor.
+ * @balloon_dev_descriptor: pointer to reference the balloon device which
+ * this struct balloon_dev_info will be servicing.
+ *
+ * Driver must call it to properly allocate and initialize an instance of
+ * struct balloon_dev_info which will be used to reference a balloon device
+ * as well as to keep track of the balloon device page list.
+ */
+struct balloon_dev_info *balloon_devinfo_alloc(void *balloon_dev_descriptor)
+{
+ struct balloon_dev_info *b_dev_info;
+ b_dev_info = kmalloc(sizeof(*b_dev_info), GFP_KERNEL);
+ if (!b_dev_info)
+ return ERR_PTR(-ENOMEM);
+
+ b_dev_info->balloon_device = balloon_dev_descriptor;
+ b_dev_info->mapping = NULL;
+ b_dev_info->isolated_pages = 0;
+ spin_lock_init(&b_dev_info->pages_lock);
+ INIT_LIST_HEAD(&b_dev_info->pages);
+
+ return b_dev_info;
+}
+EXPORT_SYMBOL_GPL(balloon_devinfo_alloc);
+
+/*
+ * balloon_page_enqueue - allocates a new page and inserts it into the balloon
+ * page list.
+ * @b_dev_info: balloon device decriptor where we will insert a new page to
+ *
+ * Driver must call it to properly allocate a new enlisted balloon page
+ * before definetively removing it from the guest system.
+ * This function returns the page address for the recently enqueued page or
+ * NULL in the case we fail to allocate a new page this turn.
+ */
+struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info)
+{
+ unsigned long flags;
+ struct page *page = alloc_page(balloon_mapping_gfp_mask() |
+ __GFP_NOMEMALLOC | __GFP_NORETRY);
+ if (!page)
+ return NULL;
+
+ /*
+ * Block others from accessing the 'page' when we get around to
+ * establishing additional references. We should be the only one
+ * holding a reference to the 'page' at this point.
+ */
+ BUG_ON(!trylock_page(page));
+ spin_lock_irqsave(&b_dev_info->pages_lock, flags);
+ balloon_page_insert(page, b_dev_info->mapping, &b_dev_info->pages);
+ spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
+ unlock_page(page);
+ return page;
+}
+EXPORT_SYMBOL_GPL(balloon_page_enqueue);
+
+/*
+ * balloon_page_dequeue - removes a page from balloon's page list and returns
+ * the its address to allow the driver release the page.
+ * @b_dev_info: balloon device decriptor where we will grab a page from.
+ *
+ * Driver must call it to properly de-allocate a previous enlisted balloon page
+ * before definetively releasing it back to the guest system.
+ * This function returns the page address for the recently dequeued page or
+ * NULL in the case we find balloon's page list temporarily empty due to
+ * compaction isolated pages.
+ */
+struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info)
+{
+ struct page *page, *tmp;
+ unsigned long flags;
+ bool dequeued_page;
+
+ dequeued_page = false;
+ list_for_each_entry_safe(page, tmp, &b_dev_info->pages, lru) {
+ /*
+ * Block others from accessing the 'page' while we get around
+ * establishing additional references and preparing the 'page'
+ * to be released by the balloon driver.
+ */
+ if (trylock_page(page)) {
+ spin_lock_irqsave(&b_dev_info->pages_lock, flags);
+ /*
+ * Raise the page refcount here to prevent any wrong
+ * attempt to isolate this page, in case of coliding
+ * with balloon_page_isolate() just after we release
+ * the page lock.
+ *
+ * balloon_page_free() will take care of dropping
+ * this extra refcount later.
+ */
+ get_page(page);
+ balloon_page_delete(page);
+ spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
+ unlock_page(page);
+ dequeued_page = true;
+ break;
+ }
+ }
+
+ if (!dequeued_page) {
+ /*
+ * If we are unable to dequeue a balloon page because the page
+ * list is empty and there is no isolated pages, then something
+ * went out of track and some balloon pages are lost.
+ * BUG() here, otherwise the balloon driver may get stuck into
+ * an infinite loop while attempting to release all its pages.
+ */
+ spin_lock_irqsave(&b_dev_info->pages_lock, flags);
+ if (unlikely(list_empty(&b_dev_info->pages) &&
+ !b_dev_info->isolated_pages))
+ BUG();
+ spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
+ page = NULL;
+ }
+ return page;
+}
+EXPORT_SYMBOL_GPL(balloon_page_dequeue);
+
+#ifdef CONFIG_BALLOON_COMPACTION
+/*
+ * balloon_mapping_alloc - allocates a special ->mapping for ballooned pages.
+ * @b_dev_info: holds the balloon device information descriptor.
+ * @a_ops: balloon_mapping address_space_operations descriptor.
+ *
+ * Driver must call it to properly allocate and initialize an instance of
+ * struct address_space which will be used as the special page->mapping for
+ * balloon device enlisted page instances.
+ */
+struct address_space *balloon_mapping_alloc(struct balloon_dev_info *b_dev_info,
+ const struct address_space_operations *a_ops)
+{
+ struct address_space *mapping;
+
+ mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
+ if (!mapping)
+ return ERR_PTR(-ENOMEM);
+
+ /*
+ * Give a clean 'zeroed' status to all elements of this special
+ * balloon page->mapping struct address_space instance.
+ */
+ address_space_init_once(mapping);
+
+ /*
+ * Set mapping->flags appropriately, to allow balloon pages
+ * ->mapping identification.
+ */
+ mapping_set_balloon(mapping);
+ mapping_set_gfp_mask(mapping, balloon_mapping_gfp_mask());
+
+ /* balloon's page->mapping->a_ops callback descriptor */
+ mapping->a_ops = a_ops;
+
+ /*
+ * Establish a pointer reference back to the balloon device descriptor
+ * this particular page->mapping will be servicing.
+ * This is used by compaction / migration procedures to identify and
+ * access the balloon device pageset while isolating / migrating pages.
+ *
+ * As some balloon drivers can register multiple balloon devices
+ * for a single guest, this also helps compaction / migration to
+ * properly deal with multiple balloon pagesets, when required.
+ */
+ mapping->private_data = b_dev_info;
+ b_dev_info->mapping = mapping;
+
+ return mapping;
+}
+EXPORT_SYMBOL_GPL(balloon_mapping_alloc);
+
+static inline void __isolate_balloon_page(struct page *page)
+{
+ struct balloon_dev_info *b_dev_info = page->mapping->private_data;
+ unsigned long flags;
+ spin_lock_irqsave(&b_dev_info->pages_lock, flags);
+ list_del(&page->lru);
+ b_dev_info->isolated_pages++;
+ spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
+}
+
+static inline void __putback_balloon_page(struct page *page)
+{
+ struct balloon_dev_info *b_dev_info = page->mapping->private_data;
+ unsigned long flags;
+ spin_lock_irqsave(&b_dev_info->pages_lock, flags);
+ list_add(&page->lru, &b_dev_info->pages);
+ b_dev_info->isolated_pages--;
+ spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
+}
+
+static inline int __migrate_balloon_page(struct address_space *mapping,
+ struct page *newpage, struct page *page, enum migrate_mode mode)
+{
+ return page->mapping->a_ops->migratepage(mapping, newpage, page, mode);
+}
+
+/* __isolate_lru_page() counterpart for a ballooned page */
+bool balloon_page_isolate(struct page *page)
+{
+ /*
+ * Avoid burning cycles with pages that are yet under __free_pages(),
+ * or just got freed under us.
+ *
+ * In case we 'win' a race for a balloon page being freed under us and
+ * raise its refcount preventing __free_pages() from doing its job
+ * the put_page() at the end of this block will take care of
+ * release this page, thus avoiding a nasty leakage.
+ */
+ if (likely(get_page_unless_zero(page))) {
+ /*
+ * As balloon pages are not isolated from LRU lists, concurrent
+ * compaction threads can race against page migration functions
+ * as well as race against the balloon driver releasing a page.
+ *
+ * In order to avoid having an already isolated balloon page
+ * being (wrongly) re-isolated while it is under migration,
+ * or to avoid attempting to isolate pages being released by
+ * the balloon driver, lets be sure we have the page lock
+ * before proceeding with the balloon page isolation steps.
+ */
+ if (likely(trylock_page(page))) {
+ /*
+ * A ballooned page, by default, has just one refcount.
+ * Prevent concurrent compaction threads from isolating
+ * an already isolated balloon page by refcount check.
+ */
+ if (__is_movable_balloon_page(page) &&
+ page_count(page) == 2) {
+ __isolate_balloon_page(page);
+ unlock_page(page);
+ return true;
+ }
+ unlock_page(page);
+ }
+ put_page(page);
+ }
+ return false;
+}
+
+/* putback_lru_page() counterpart for a ballooned page */
+void balloon_page_putback(struct page *page)
+{
+ /*
+ * 'lock_page()' stabilizes the page and prevents races against
+ * concurrent isolation threads attempting to re-isolate it.
+ */
+ lock_page(page);
+
+ if (__is_movable_balloon_page(page)) {
+ __putback_balloon_page(page);
+ /* drop the extra ref count taken for page isolation */
+ put_page(page);
+ } else {
+ WARN_ON(1);
+ dump_page(page);
+ }
+ unlock_page(page);
+}
+
+/* move_to_new_page() counterpart for a ballooned page */
+int balloon_page_migrate(struct page *newpage,
+ struct page *page, enum migrate_mode mode)
+{
+ struct address_space *mapping;
+ int rc = -EAGAIN;
+
+ /*
+ * Block others from accessing the 'newpage' when we get around to
+ * establishing additional references. We should be the only one
+ * holding a reference to the 'newpage' at this point.
+ */
+ BUG_ON(!trylock_page(newpage));
+
+ if (WARN_ON(!__is_movable_balloon_page(page))) {
+ dump_page(page);
+ unlock_page(newpage);
+ return rc;
+ }
+
+ mapping = page->mapping;
+ if (mapping)
+ rc = __migrate_balloon_page(mapping, newpage, page, mode);
+
+ unlock_page(newpage);
+ return rc;
+}
+#endif /* CONFIG_BALLOON_COMPACTION */
diff --git a/mm/bootmem.c b/mm/bootmem.c
index 434be4ae7a0..ecc45958ac0 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -147,21 +147,21 @@ unsigned long __init init_bootmem(unsigned long start, unsigned long pages)
/*
* free_bootmem_late - free bootmem pages directly to page allocator
- * @addr: starting address of the range
+ * @addr: starting physical address of the range
* @size: size of the range in bytes
*
* This is only useful when the bootmem allocator has already been torn
* down, but we are still initializing the system. Pages are given directly
* to the page allocator, no bootmem metadata is updated because it is gone.
*/
-void __init free_bootmem_late(unsigned long addr, unsigned long size)
+void __init free_bootmem_late(unsigned long physaddr, unsigned long size)
{
unsigned long cursor, end;
- kmemleak_free_part(__va(addr), size);
+ kmemleak_free_part(__va(physaddr), size);
- cursor = PFN_UP(addr);
- end = PFN_DOWN(addr + size);
+ cursor = PFN_UP(physaddr);
+ end = PFN_DOWN(physaddr + size);
for (; cursor < end; cursor++) {
__free_pages_bootmem(pfn_to_page(cursor), 0);
@@ -198,8 +198,6 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
int order = ilog2(BITS_PER_LONG);
__free_pages_bootmem(pfn_to_page(start), order);
- fixup_zone_present_pages(page_to_nid(pfn_to_page(start)),
- start, start + BITS_PER_LONG);
count += BITS_PER_LONG;
start += BITS_PER_LONG;
} else {
@@ -210,9 +208,6 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
if (vec & 1) {
page = pfn_to_page(start + off);
__free_pages_bootmem(page, 0);
- fixup_zone_present_pages(
- page_to_nid(page),
- start + off, start + off + 1);
count++;
}
vec >>= 1;
@@ -226,11 +221,8 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
pages = bdata->node_low_pfn - bdata->node_min_pfn;
pages = bootmem_bootmap_pages(pages);
count += pages;
- while (pages--) {
- fixup_zone_present_pages(page_to_nid(page),
- page_to_pfn(page), page_to_pfn(page) + 1);
+ while (pages--)
__free_pages_bootmem(page++, 0);
- }
bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count);
@@ -385,21 +377,21 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
/**
* free_bootmem - mark a page range as usable
- * @addr: starting address of the range
+ * @addr: starting physical address of the range
* @size: size of the range in bytes
*
* Partial pages will be considered reserved and left as they are.
*
* The range must be contiguous but may span node boundaries.
*/
-void __init free_bootmem(unsigned long addr, unsigned long size)
+void __init free_bootmem(unsigned long physaddr, unsigned long size)
{
unsigned long start, end;
- kmemleak_free_part(__va(addr), size);
+ kmemleak_free_part(__va(physaddr), size);
- start = PFN_UP(addr);
- end = PFN_DOWN(addr + size);
+ start = PFN_UP(physaddr);
+ end = PFN_DOWN(physaddr + size);
mark_bootmem(start, end, 0, 0);
}
diff --git a/mm/compaction.c b/mm/compaction.c
index 9eef55838fc..d24dd2d7bad 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -14,6 +14,7 @@
#include <linux/backing-dev.h>
#include <linux/sysctl.h>
#include <linux/sysfs.h>
+#include <linux/balloon_compaction.h>
#include "internal.h"
#if defined CONFIG_COMPACTION || defined CONFIG_CMA
@@ -565,9 +566,24 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
goto next_pageblock;
}
- /* Check may be lockless but that's ok as we recheck later */
- if (!PageLRU(page))
+ /*
+ * Check may be lockless but that's ok as we recheck later.
+ * It's possible to migrate LRU pages and balloon pages
+ * Skip any other type of page
+ */
+ if (!PageLRU(page)) {
+ if (unlikely(balloon_page_movable(page))) {
+ if (locked && balloon_page_isolate(page)) {
+ /* Successfully isolated */
+ cc->finished_update_migrate = true;
+ list_add(&page->lru, migratelist);
+ cc->nr_migratepages++;
+ nr_isolated++;
+ goto check_compact_cluster;
+ }
+ }
continue;
+ }
/*
* PageLRU is set. lru_lock normally excludes isolation
@@ -621,6 +637,7 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
cc->nr_migratepages++;
nr_isolated++;
+check_compact_cluster:
/* Avoid isolating too much */
if (cc->nr_migratepages == COMPACT_CLUSTER_MAX) {
++low_pfn;
@@ -713,7 +730,15 @@ static void isolate_freepages(struct zone *zone,
/* Found a block suitable for isolating free pages from */
isolated = 0;
- end_pfn = min(pfn + pageblock_nr_pages, zone_end_pfn);
+
+ /*
+ * As pfn may not start aligned, pfn+pageblock_nr_page
+ * may cross a MAX_ORDER_NR_PAGES boundary and miss
+ * a pfn_valid check. Ensure isolate_freepages_block()
+ * only scans within a pageblock
+ */
+ end_pfn = ALIGN(pfn + 1, pageblock_nr_pages);
+ end_pfn = min(end_pfn, zone_end_pfn);
isolated = isolate_freepages_block(cc, pfn, end_pfn,
freelist, false);
nr_freepages += isolated;
@@ -978,7 +1003,7 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
switch (isolate_migratepages(zone, cc)) {
case ISOLATE_ABORT:
ret = COMPACT_PARTIAL;
- putback_lru_pages(&cc->migratepages);
+ putback_movable_pages(&cc->migratepages);
cc->nr_migratepages = 0;
goto out;
case ISOLATE_NONE:
@@ -1001,9 +1026,9 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
trace_mm_compaction_migratepages(nr_migrate - nr_remaining,
nr_remaining);
- /* Release LRU pages not migrated */
+ /* Release isolated pages not migrated */
if (err) {
- putback_lru_pages(&cc->migratepages);
+ putback_movable_pages(&cc->migratepages);
cc->nr_migratepages = 0;
if (err == -ENOMEM) {
ret = COMPACT_PARTIAL;
diff --git a/mm/dmapool.c b/mm/dmapool.c
index c5ab33bca0a..c69781e97cf 100644
--- a/mm/dmapool.c
+++ b/mm/dmapool.c
@@ -50,7 +50,6 @@ struct dma_pool { /* the pool */
size_t allocation;
size_t boundary;
char name[32];
- wait_queue_head_t waitq;
struct list_head pools;
};
@@ -62,8 +61,6 @@ struct dma_page { /* cacheable header for 'allocation' bytes */
unsigned int offset;
};
-#define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000)
-
static DEFINE_MUTEX(pools_lock);
static ssize_t
@@ -172,7 +169,6 @@ struct dma_pool *dma_pool_create(const char *name, struct device *dev,
retval->size = size;
retval->boundary = boundary;
retval->allocation = allocation;
- init_waitqueue_head(&retval->waitq);
if (dev) {
int ret;
@@ -227,7 +223,6 @@ static struct dma_page *pool_alloc_page(struct dma_pool *pool, gfp_t mem_flags)
memset(page->vaddr, POOL_POISON_FREED, pool->allocation);
#endif
pool_initialise_page(pool, page);
- list_add(&page->page_list, &pool->page_list);
page->in_use = 0;
page->offset = 0;
} else {
@@ -315,30 +310,21 @@ void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags,
might_sleep_if(mem_flags & __GFP_WAIT);
spin_lock_irqsave(&pool->lock, flags);
- restart:
list_for_each_entry(page, &pool->page_list, page_list) {
if (page->offset < pool->allocation)
goto ready;
}
- page = pool_alloc_page(pool, GFP_ATOMIC);
- if (!page) {
- if (mem_flags & __GFP_WAIT) {
- DECLARE_WAITQUEUE(wait, current);
- __set_current_state(TASK_UNINTERRUPTIBLE);
- __add_wait_queue(&pool->waitq, &wait);
- spin_unlock_irqrestore(&pool->lock, flags);
+ /* pool_alloc_page() might sleep, so temporarily drop &pool->lock */
+ spin_unlock_irqrestore(&pool->lock, flags);
- schedule_timeout(POOL_TIMEOUT_JIFFIES);
+ page = pool_alloc_page(pool, mem_flags);
+ if (!page)
+ return NULL;
- spin_lock_irqsave(&pool->lock, flags);
- __remove_wait_queue(&pool->waitq, &wait);
- goto restart;
- }
- retval = NULL;
- goto done;
- }
+ spin_lock_irqsave(&pool->lock, flags);
+ list_add(&page->page_list, &pool->page_list);
ready:
page->in_use++;
offset = page->offset;
@@ -346,9 +332,32 @@ void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags,
retval = offset + page->vaddr;
*handle = offset + page->dma;
#ifdef DMAPOOL_DEBUG
+ {
+ int i;
+ u8 *data = retval;
+ /* page->offset is stored in first 4 bytes */
+ for (i = sizeof(page->offset); i < pool->size; i++) {
+ if (data[i] == POOL_POISON_FREED)
+ continue;
+ if (pool->dev)
+ dev_err(pool->dev,
+ "dma_pool_alloc %s, %p (corruped)\n",
+ pool->name, retval);
+ else
+ pr_err("dma_pool_alloc %s, %p (corruped)\n",
+ pool->name, retval);
+
+ /*
+ * Dump the first 4 bytes even if they are not
+ * POOL_POISON_FREED
+ */
+ print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1,
+ data, pool->size, 1);
+ break;
+ }
+ }
memset(retval, POOL_POISON_ALLOCATED, pool->size);
#endif
- done:
spin_unlock_irqrestore(&pool->lock, flags);
return retval;
}
@@ -435,8 +444,6 @@ void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma)
page->in_use--;
*(int *)vaddr = page->offset;
page->offset = offset;
- if (waitqueue_active(&pool->waitq))
- wake_up_locked(&pool->waitq);
/*
* Resist a temptation to do
* if (!is_page_busy(page)) pool_free_page(pool, page);
diff --git a/mm/highmem.c b/mm/highmem.c
index d517cd16a6e..d999077431d 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -98,8 +98,8 @@ struct page *kmap_to_page(void *vaddr)
{
unsigned long addr = (unsigned long)vaddr;
- if (addr >= PKMAP_ADDR(0) && addr <= PKMAP_ADDR(LAST_PKMAP)) {
- int i = (addr - PKMAP_ADDR(0)) >> PAGE_SHIFT;
+ if (addr >= PKMAP_ADDR(0) && addr < PKMAP_ADDR(LAST_PKMAP)) {
+ int i = PKMAP_NR(addr);
return pte_page(pkmap_page_table[i]);
}
@@ -137,8 +137,7 @@ static void flush_all_zero_pkmaps(void)
* So no dangers, even with speculative execution.
*/
page = pte_page(pkmap_page_table[i]);
- pte_clear(&init_mm, (unsigned long)page_address(page),
- &pkmap_page_table[i]);
+ pte_clear(&init_mm, PKMAP_ADDR(i), &pkmap_page_table[i]);
set_page_address(page, NULL);
need_flush = 1;
@@ -324,11 +323,7 @@ struct page_address_map {
struct list_head list;
};
-/*
- * page_address_map freelist, allocated from page_address_maps.
- */
-static struct list_head page_address_pool; /* freelist */
-static spinlock_t pool_lock; /* protects page_address_pool */
+static struct page_address_map page_address_maps[LAST_PKMAP];
/*
* Hash table bucket
@@ -393,14 +388,7 @@ void set_page_address(struct page *page, void *virtual)
pas = page_slot(page);
if (virtual) { /* Add */
- BUG_ON(list_empty(&page_address_pool));
-
- spin_lock_irqsave(&pool_lock, flags);
- pam = list_entry(page_address_pool.next,
- struct page_address_map, list);
- list_del(&pam->list);
- spin_unlock_irqrestore(&pool_lock, flags);
-
+ pam = &page_address_maps[PKMAP_NR((unsigned long)virtual)];
pam->page = page;
pam->virtual = virtual;
@@ -413,9 +401,6 @@ void set_page_address(struct page *page, void *virtual)
if (pam->page == page) {
list_del(&pam->list);
spin_unlock_irqrestore(&pas->lock, flags);
- spin_lock_irqsave(&pool_lock, flags);
- list_add_tail(&pam->list, &page_address_pool);
- spin_unlock_irqrestore(&pool_lock, flags);
goto done;
}
}
@@ -425,20 +410,14 @@ done:
return;
}
-static struct page_address_map page_address_maps[LAST_PKMAP];
-
void __init page_address_init(void)
{
int i;
- INIT_LIST_HEAD(&page_address_pool);
- for (i = 0; i < ARRAY_SIZE(page_address_maps); i++)
- list_add(&page_address_maps[i].list, &page_address_pool);
for (i = 0; i < ARRAY_SIZE(page_address_htable); i++) {
INIT_LIST_HEAD(&page_address_htable[i].lh);
spin_lock_init(&page_address_htable[i].lock);
}
- spin_lock_init(&pool_lock);
}
#endif /* defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL) */
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 40f17c34b41..5f902e20e8c 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -606,6 +606,15 @@ static inline pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma)
return pmd;
}
+static inline pmd_t mk_huge_pmd(struct page *page, struct vm_area_struct *vma)
+{
+ pmd_t entry;
+ entry = mk_pmd(page, vma->vm_page_prot);
+ entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
+ entry = pmd_mkhuge(entry);
+ return entry;
+}
+
static int __do_huge_pmd_anonymous_page(struct mm_struct *mm,
struct vm_area_struct *vma,
unsigned long haddr, pmd_t *pmd,
@@ -629,9 +638,7 @@ static int __do_huge_pmd_anonymous_page(struct mm_struct *mm,
pte_free(mm, pgtable);
} else {
pmd_t entry;
- entry = mk_pmd(page, vma->vm_page_prot);
- entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
- entry = pmd_mkhuge(entry);
+ entry = mk_huge_pmd(page, vma);
/*
* The spinlocking to take the lru_lock inside
* page_add_new_anon_rmap() acts as a full memory
@@ -777,6 +784,28 @@ out:
return ret;
}
+void huge_pmd_set_accessed(struct mm_struct *mm,
+ struct vm_area_struct *vma,
+ unsigned long address,
+ pmd_t *pmd, pmd_t orig_pmd,
+ int dirty)
+{
+ pmd_t entry;
+ unsigned long haddr;
+
+ spin_lock(&mm->page_table_lock);
+ if (unlikely(!pmd_same(*pmd, orig_pmd)))
+ goto unlock;
+
+ entry = pmd_mkyoung(orig_pmd);
+ haddr = address & HPAGE_PMD_MASK;
+ if (pmdp_set_access_flags(vma, haddr, pmd, entry, dirty))
+ update_mmu_cache_pmd(vma, address, pmd);
+
+unlock:
+ spin_unlock(&mm->page_table_lock);
+}
+
static int do_huge_pmd_wp_page_fallback(struct mm_struct *mm,
struct vm_area_struct *vma,
unsigned long address,
@@ -951,9 +980,7 @@ int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
} else {
pmd_t entry;
VM_BUG_ON(!PageHead(page));
- entry = mk_pmd(new_page, vma->vm_page_prot);
- entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
- entry = pmd_mkhuge(entry);
+ entry = mk_huge_pmd(new_page, vma);
pmdp_clear_flush(vma, haddr, pmd);
page_add_new_anon_rmap(new_page, vma, haddr);
set_pmd_at(mm, haddr, pmd, entry);
@@ -1146,22 +1173,14 @@ pmd_t *page_check_address_pmd(struct page *page,
unsigned long address,
enum page_check_address_pmd_flag flag)
{
- pgd_t *pgd;
- pud_t *pud;
pmd_t *pmd, *ret = NULL;
if (address & ~HPAGE_PMD_MASK)
goto out;
- pgd = pgd_offset(mm, address);
- if (!pgd_present(*pgd))
- goto out;
-
- pud = pud_offset(pgd, address);
- if (!pud_present(*pud))
+ pmd = mm_find_pmd(mm, address);
+ if (!pmd)
goto out;
-
- pmd = pmd_offset(pud, address);
if (pmd_none(*pmd))
goto out;
if (pmd_page(*pmd) != page)
@@ -1701,64 +1720,49 @@ static void release_pte_pages(pte_t *pte, pte_t *_pte)
}
}
-static void release_all_pte_pages(pte_t *pte)
-{
- release_pte_pages(pte, pte + HPAGE_PMD_NR);
-}
-
static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
unsigned long address,
pte_t *pte)
{
struct page *page;
pte_t *_pte;
- int referenced = 0, isolated = 0, none = 0;
+ int referenced = 0, none = 0;
for (_pte = pte; _pte < pte+HPAGE_PMD_NR;
_pte++, address += PAGE_SIZE) {
pte_t pteval = *_pte;
if (pte_none(pteval)) {
if (++none <= khugepaged_max_ptes_none)
continue;
- else {
- release_pte_pages(pte, _pte);
+ else
goto out;
- }
}
- if (!pte_present(pteval) || !pte_write(pteval)) {
- release_pte_pages(pte, _pte);
+ if (!pte_present(pteval) || !pte_write(pteval))
goto out;
- }
page = vm_normal_page(vma, address, pteval);
- if (unlikely(!page)) {
- release_pte_pages(pte, _pte);
+ if (unlikely(!page))
goto out;
- }
+
VM_BUG_ON(PageCompound(page));
BUG_ON(!PageAnon(page));
VM_BUG_ON(!PageSwapBacked(page));
/* cannot use mapcount: can't collapse if there's a gup pin */
- if (page_count(page) != 1) {
- release_pte_pages(pte, _pte);
+ if (page_count(page) != 1)
goto out;
- }
/*
* We can do it before isolate_lru_page because the
* page can't be freed from under us. NOTE: PG_lock
* is needed to serialize against split_huge_page
* when invoked from the VM.
*/
- if (!trylock_page(page)) {
- release_pte_pages(pte, _pte);
+ if (!trylock_page(page))
goto out;
- }
/*
* Isolate the page to avoid collapsing an hugepage
* currently in use by the VM.
*/
if (isolate_lru_page(page)) {
unlock_page(page);
- release_pte_pages(pte, _pte);
goto out;
}
/* 0 stands for page_is_file_cache(page) == false */
@@ -1771,12 +1775,11 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
mmu_notifier_test_young(vma->vm_mm, address))
referenced = 1;
}
- if (unlikely(!referenced))
- release_all_pte_pages(pte);
- else
- isolated = 1;
+ if (likely(referenced))
+ return 1;
out:
- return isolated;
+ release_pte_pages(pte, _pte);
+ return 0;
}
static void __collapse_huge_page_copy(pte_t *pte, struct page *page,
@@ -1918,14 +1921,26 @@ static struct page
}
#endif
+static bool hugepage_vma_check(struct vm_area_struct *vma)
+{
+ if ((!(vma->vm_flags & VM_HUGEPAGE) && !khugepaged_always()) ||
+ (vma->vm_flags & VM_NOHUGEPAGE))
+ return false;
+
+ if (!vma->anon_vma || vma->vm_ops)
+ return false;
+ if (is_vma_temporary_stack(vma))
+ return false;
+ VM_BUG_ON(vma->vm_flags & VM_NO_THP);
+ return true;
+}
+
static void collapse_huge_page(struct mm_struct *mm,
unsigned long address,
struct page **hpage,
struct vm_area_struct *vma,
int node)
{
- pgd_t *pgd;
- pud_t *pud;
pmd_t *pmd, _pmd;
pte_t *pte;
pgtable_t pgtable;
@@ -1960,28 +1975,12 @@ static void collapse_huge_page(struct mm_struct *mm,
hend = vma->vm_end & HPAGE_PMD_MASK;
if (address < hstart || address + HPAGE_PMD_SIZE > hend)
goto out;
-
- if ((!(vma->vm_flags & VM_HUGEPAGE) && !khugepaged_always()) ||
- (vma->vm_flags & VM_NOHUGEPAGE))
- goto out;
-
- if (!vma->anon_vma || vma->vm_ops)
- goto out;
- if (is_vma_temporary_stack(vma))
+ if (!hugepage_vma_check(vma))
goto out;
- VM_BUG_ON(vma->vm_flags & VM_NO_THP);
-
- pgd = pgd_offset(mm, address);
- if (!pgd_present(*pgd))
+ pmd = mm_find_pmd(mm, address);
+ if (!pmd)
goto out;
-
- pud = pud_offset(pgd, address);
- if (!pud_present(*pud))
- goto out;
-
- pmd = pmd_offset(pud, address);
- /* pmd can't go away or become huge under us */
- if (!pmd_present(*pmd) || pmd_trans_huge(*pmd))
+ if (pmd_trans_huge(*pmd))
goto out;
anon_vma_lock(vma->anon_vma);
@@ -2028,9 +2027,7 @@ static void collapse_huge_page(struct mm_struct *mm,
__SetPageUptodate(new_page);
pgtable = pmd_pgtable(_pmd);
- _pmd = mk_pmd(new_page, vma->vm_page_prot);
- _pmd = maybe_pmd_mkwrite(pmd_mkdirty(_pmd), vma);
- _pmd = pmd_mkhuge(_pmd);
+ _pmd = mk_huge_pmd(new_page, vma);
/*
* spin_lock() below is not the equivalent of smp_wmb(), so
@@ -2064,8 +2061,6 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
unsigned long address,
struct page **hpage)
{
- pgd_t *pgd;
- pud_t *pud;
pmd_t *pmd;
pte_t *pte, *_pte;
int ret = 0, referenced = 0, none = 0;
@@ -2076,16 +2071,10 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
VM_BUG_ON(address & ~HPAGE_PMD_MASK);
- pgd = pgd_offset(mm, address);
- if (!pgd_present(*pgd))
- goto out;
-
- pud = pud_offset(pgd, address);
- if (!pud_present(*pud))
+ pmd = mm_find_pmd(mm, address);
+ if (!pmd)
goto out;
-
- pmd = pmd_offset(pud, address);
- if (!pmd_present(*pmd) || pmd_trans_huge(*pmd))
+ if (pmd_trans_huge(*pmd))
goto out;
pte = pte_offset_map_lock(mm, pmd, address, &ptl);
@@ -2193,20 +2182,11 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages,
progress++;
break;
}
-
- if ((!(vma->vm_flags & VM_HUGEPAGE) &&
- !khugepaged_always()) ||
- (vma->vm_flags & VM_NOHUGEPAGE)) {
- skip:
+ if (!hugepage_vma_check(vma)) {
+skip:
progress++;
continue;
}
- if (!vma->anon_vma || vma->vm_ops)
- goto skip;
- if (is_vma_temporary_stack(vma))
- goto skip;
- VM_BUG_ON(vma->vm_flags & VM_NO_THP);
-
hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK;
hend = vma->vm_end & HPAGE_PMD_MASK;
if (hstart >= hend)
@@ -2379,22 +2359,12 @@ void __split_huge_page_pmd(struct mm_struct *mm, pmd_t *pmd)
static void split_huge_page_address(struct mm_struct *mm,
unsigned long address)
{
- pgd_t *pgd;
- pud_t *pud;
pmd_t *pmd;
VM_BUG_ON(!(address & ~HPAGE_PMD_MASK));
- pgd = pgd_offset(mm, address);
- if (!pgd_present(*pgd))
- return;
-
- pud = pud_offset(pgd, address);
- if (!pud_present(*pud))
- return;
-
- pmd = pmd_offset(pud, address);
- if (!pmd_present(*pmd))
+ pmd = mm_find_pmd(mm, address);
+ if (!pmd)
return;
/*
* Caller holds the mmap_sem write mode, so a huge pmd cannot
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 59a0059b39e..1ef2cd4ae3c 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1800,7 +1800,7 @@ static void hugetlb_unregister_all_nodes(void)
* remove hstate attributes from any nodes that have them.
*/
for (nid = 0; nid < nr_node_ids; nid++)
- hugetlb_unregister_node(&node_devices[nid]);
+ hugetlb_unregister_node(node_devices[nid]);
}
/*
@@ -1845,7 +1845,7 @@ static void hugetlb_register_all_nodes(void)
int nid;
for_each_node_state(nid, N_HIGH_MEMORY) {
- struct node *node = &node_devices[nid];
+ struct node *node = node_devices[nid];
if (node->dev.id == nid)
hugetlb_register_node(node);
}
diff --git a/mm/internal.h b/mm/internal.h
index a4fa284f6bc..52d1fa95719 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -92,6 +92,11 @@ extern int isolate_lru_page(struct page *page);
extern void putback_lru_page(struct page *page);
/*
+ * in mm/rmap.c:
+ */
+extern pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address);
+
+/*
* in mm/page_alloc.c
*/
extern void __free_pages_bootmem(struct page *page, unsigned int order);
diff --git a/mm/ksm.c b/mm/ksm.c
index ae539f0b8aa..382d930a0bf 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -778,8 +778,6 @@ static int replace_page(struct vm_area_struct *vma, struct page *page,
struct page *kpage, pte_t orig_pte)
{
struct mm_struct *mm = vma->vm_mm;
- pgd_t *pgd;
- pud_t *pud;
pmd_t *pmd;
pte_t *ptep;
spinlock_t *ptl;
@@ -792,18 +790,10 @@ static int replace_page(struct vm_area_struct *vma, struct page *page,
if (addr == -EFAULT)
goto out;
- pgd = pgd_offset(mm, addr);
- if (!pgd_present(*pgd))
+ pmd = mm_find_pmd(mm, addr);
+ if (!pmd)
goto out;
-
- pud = pud_offset(pgd, addr);
- if (!pud_present(*pud))
- goto out;
-
- pmd = pmd_offset(pud, addr);
BUG_ON(pmd_trans_huge(*pmd));
- if (!pmd_present(*pmd))
- goto out;
mmun_start = addr;
mmun_end = addr + PAGE_SIZE;
@@ -1929,12 +1919,9 @@ static ssize_t run_store(struct kobject *kobj, struct kobj_attribute *attr,
if (ksm_run != flags) {
ksm_run = flags;
if (flags & KSM_RUN_UNMERGE) {
- int oom_score_adj;
-
- oom_score_adj = test_set_oom_score_adj(OOM_SCORE_ADJ_MAX);
+ set_current_oom_origin();
err = unmerge_and_remove_all_rmap_items();
- compare_swap_oom_score_adj(OOM_SCORE_ADJ_MAX,
- oom_score_adj);
+ clear_current_oom_origin();
if (err) {
ksm_run = KSM_RUN_STOP;
count = err;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 7acf43bf04a..cf6d0df4849 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1055,12 +1055,24 @@ struct lruvec *mem_cgroup_zone_lruvec(struct zone *zone,
struct mem_cgroup *memcg)
{
struct mem_cgroup_per_zone *mz;
+ struct lruvec *lruvec;
- if (mem_cgroup_disabled())
- return &zone->lruvec;
+ if (mem_cgroup_disabled()) {
+ lruvec = &zone->lruvec;
+ goto out;
+ }
mz = mem_cgroup_zoneinfo(memcg, zone_to_nid(zone), zone_idx(zone));
- return &mz->lruvec;
+ lruvec = &mz->lruvec;
+out:
+ /*
+ * Since a node can be onlined after the mem_cgroup was created,
+ * we have to be prepared to initialize lruvec->zone here;
+ * and if offlined then reonlined, we need to reinitialize it.
+ */
+ if (unlikely(lruvec->zone != zone))
+ lruvec->zone = zone;
+ return lruvec;
}
/*
@@ -1087,9 +1099,12 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone)
struct mem_cgroup_per_zone *mz;
struct mem_cgroup *memcg;
struct page_cgroup *pc;
+ struct lruvec *lruvec;
- if (mem_cgroup_disabled())
- return &zone->lruvec;
+ if (mem_cgroup_disabled()) {
+ lruvec = &zone->lruvec;
+ goto out;
+ }
pc = lookup_page_cgroup(page);
memcg = pc->mem_cgroup;
@@ -1107,7 +1122,16 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone)
pc->mem_cgroup = memcg = root_mem_cgroup;
mz = page_cgroup_zoneinfo(memcg, page);
- return &mz->lruvec;
+ lruvec = &mz->lruvec;
+out:
+ /*
+ * Since a node can be onlined after the mem_cgroup was created,
+ * we have to be prepared to initialize lruvec->zone here;
+ * and if offlined then reonlined, we need to reinitialize it.
+ */
+ if (unlikely(lruvec->zone != zone))
+ lruvec->zone = zone;
+ return lruvec;
}
/**
@@ -1452,21 +1476,30 @@ static int mem_cgroup_count_children(struct mem_cgroup *memcg)
static u64 mem_cgroup_get_limit(struct mem_cgroup *memcg)
{
u64 limit;
- u64 memsw;
limit = res_counter_read_u64(&memcg->res, RES_LIMIT);
- limit += total_swap_pages << PAGE_SHIFT;
- memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT);
/*
- * If memsw is finite and limits the amount of swap space available
- * to this memcg, return that limit.
+ * Do not consider swap space if we cannot swap due to swappiness
*/
- return min(limit, memsw);
+ if (mem_cgroup_swappiness(memcg)) {
+ u64 memsw;
+
+ limit += total_swap_pages << PAGE_SHIFT;
+ memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT);
+
+ /*
+ * If memsw is finite and limits the amount of swap space
+ * available to this memcg, return that limit.
+ */
+ limit = min(limit, memsw);
+ }
+
+ return limit;
}
-void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
- int order)
+static void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
+ int order)
{
struct mem_cgroup *iter;
unsigned long chosen_points = 0;
@@ -3688,17 +3721,17 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
static bool mem_cgroup_force_empty_list(struct mem_cgroup *memcg,
int node, int zid, enum lru_list lru)
{
- struct mem_cgroup_per_zone *mz;
+ struct lruvec *lruvec;
unsigned long flags, loop;
struct list_head *list;
struct page *busy;
struct zone *zone;
zone = &NODE_DATA(node)->node_zones[zid];
- mz = mem_cgroup_zoneinfo(memcg, node, zid);
- list = &mz->lruvec.lists[lru];
+ lruvec = mem_cgroup_zone_lruvec(zone, memcg);
+ list = &lruvec->lists[lru];
- loop = mz->lru_size[lru];
+ loop = mem_cgroup_get_lru_size(lruvec, lru);
/* give some margin against EBUSY etc...*/
loop += 256;
busy = NULL;
@@ -4736,7 +4769,7 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node)
for (zone = 0; zone < MAX_NR_ZONES; zone++) {
mz = &pn->zoneinfo[zone];
- lruvec_init(&mz->lruvec, &NODE_DATA(node)->node_zones[zone]);
+ lruvec_init(&mz->lruvec);
mz->usage_in_excess = 0;
mz->on_tree = false;
mz->memcg = memcg;
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 6c5899b9034..108c52fa60f 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -781,16 +781,16 @@ static struct page_state {
{ compound, compound, "huge", me_huge_page },
#endif
- { sc|dirty, sc|dirty, "swapcache", me_swapcache_dirty },
- { sc|dirty, sc, "swapcache", me_swapcache_clean },
+ { sc|dirty, sc|dirty, "dirty swapcache", me_swapcache_dirty },
+ { sc|dirty, sc, "clean swapcache", me_swapcache_clean },
- { unevict|dirty, unevict|dirty, "unevictable LRU", me_pagecache_dirty},
- { unevict, unevict, "unevictable LRU", me_pagecache_clean},
+ { unevict|dirty, unevict|dirty, "dirty unevictable LRU", me_pagecache_dirty },
+ { unevict, unevict, "clean unevictable LRU", me_pagecache_clean },
- { mlock|dirty, mlock|dirty, "mlocked LRU", me_pagecache_dirty },
- { mlock, mlock, "mlocked LRU", me_pagecache_clean },
+ { mlock|dirty, mlock|dirty, "dirty mlocked LRU", me_pagecache_dirty },
+ { mlock, mlock, "clean mlocked LRU", me_pagecache_clean },
- { lru|dirty, lru|dirty, "LRU", me_pagecache_dirty },
+ { lru|dirty, lru|dirty, "dirty LRU", me_pagecache_dirty },
{ lru|dirty, lru, "clean LRU", me_pagecache_clean },
/*
@@ -812,14 +812,14 @@ static struct page_state {
#undef slab
#undef reserved
+/*
+ * "Dirty/Clean" indication is not 100% accurate due to the possibility of
+ * setting PG_dirty outside page lock. See also comment above set_page_dirty().
+ */
static void action_result(unsigned long pfn, char *msg, int result)
{
- struct page *page = pfn_to_page(pfn);
-
- printk(KERN_ERR "MCE %#lx: %s%s page recovery: %s\n",
- pfn,
- PageDirty(page) ? "dirty " : "",
- msg, action_name[result]);
+ pr_err("MCE %#lx: %s page recovery: %s\n",
+ pfn, msg, action_name[result]);
}
static int page_action(struct page_state *ps, struct page *p,
@@ -1385,7 +1385,7 @@ static int get_any_page(struct page *p, unsigned long pfn, int flags)
* Isolate the page, so that it doesn't get reallocated if it
* was free.
*/
- set_migratetype_isolate(p);
+ set_migratetype_isolate(p, true);
/*
* When the target page is a free hugepage, just remove it
* from free hugepage list.
@@ -1476,9 +1476,17 @@ int soft_offline_page(struct page *page, int flags)
{
int ret;
unsigned long pfn = page_to_pfn(page);
+ struct page *hpage = compound_trans_head(page);
if (PageHuge(page))
return soft_offline_huge_page(page, flags);
+ if (PageTransHuge(hpage)) {
+ if (PageAnon(hpage) && unlikely(split_huge_page(hpage))) {
+ pr_info("soft offline: %#lx: failed to split THP\n",
+ pfn);
+ return -EBUSY;
+ }
+ }
ret = get_any_page(page, pfn, flags);
if (ret < 0)
diff --git a/mm/memory.c b/mm/memory.c
index fb135ba4aba..76537738563 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2527,9 +2527,8 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
int ret = 0;
int page_mkwrite = 0;
struct page *dirty_page = NULL;
- unsigned long mmun_start; /* For mmu_notifiers */
- unsigned long mmun_end; /* For mmu_notifiers */
- bool mmun_called = false; /* For mmu_notifiers */
+ unsigned long mmun_start = 0; /* For mmu_notifiers */
+ unsigned long mmun_end = 0; /* For mmu_notifiers */
old_page = vm_normal_page(vma, address, orig_pte);
if (!old_page) {
@@ -2708,8 +2707,7 @@ gotten:
goto oom_free_new;
mmun_start = address & PAGE_MASK;
- mmun_end = (address & PAGE_MASK) + PAGE_SIZE;
- mmun_called = true;
+ mmun_end = mmun_start + PAGE_SIZE;
mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
/*
@@ -2778,7 +2776,7 @@ gotten:
page_cache_release(new_page);
unlock:
pte_unmap_unlock(page_table, ptl);
- if (mmun_called)
+ if (mmun_end > mmun_start)
mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
if (old_page) {
/*
@@ -3539,8 +3537,9 @@ retry:
barrier();
if (pmd_trans_huge(orig_pmd)) {
- if (flags & FAULT_FLAG_WRITE &&
- !pmd_write(orig_pmd) &&
+ unsigned int dirty = flags & FAULT_FLAG_WRITE;
+
+ if (dirty && !pmd_write(orig_pmd) &&
!pmd_trans_splitting(orig_pmd)) {
ret = do_huge_pmd_wp_page(mm, vma, address, pmd,
orig_pmd);
@@ -3552,6 +3551,9 @@ retry:
if (unlikely(ret & VM_FAULT_OOM))
goto retry;
return ret;
+ } else {
+ huge_pmd_set_accessed(mm, vma, address, pmd,
+ orig_pmd, dirty);
}
return 0;
}
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 56b758ae57d..de9cb14ae75 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -106,7 +106,6 @@ static void get_page_bootmem(unsigned long info, struct page *page,
void __ref put_page_bootmem(struct page *page)
{
unsigned long type;
- struct zone *zone;
type = (unsigned long) page->lru.next;
BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE ||
@@ -117,12 +116,6 @@ void __ref put_page_bootmem(struct page *page)
set_page_private(page, 0);
INIT_LIST_HEAD(&page->lru);
__free_pages_bootmem(page, 0);
-
- zone = page_zone(page);
- zone_span_writelock(zone);
- zone->present_pages++;
- zone_span_writeunlock(zone);
- totalram_pages++;
}
}
@@ -212,7 +205,7 @@ static void grow_zone_span(struct zone *zone, unsigned long start_pfn,
zone_span_writelock(zone);
old_zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
- if (start_pfn < zone->zone_start_pfn)
+ if (!zone->spanned_pages || start_pfn < zone->zone_start_pfn)
zone->zone_start_pfn = start_pfn;
zone->spanned_pages = max(old_zone_end_pfn, end_pfn) -
@@ -221,13 +214,134 @@ static void grow_zone_span(struct zone *zone, unsigned long start_pfn,
zone_span_writeunlock(zone);
}
+static void resize_zone(struct zone *zone, unsigned long start_pfn,
+ unsigned long end_pfn)
+{
+ zone_span_writelock(zone);
+
+ if (end_pfn - start_pfn) {
+ zone->zone_start_pfn = start_pfn;
+ zone->spanned_pages = end_pfn - start_pfn;
+ } else {
+ /*
+ * make it consist as free_area_init_core(),
+ * if spanned_pages = 0, then keep start_pfn = 0
+ */
+ zone->zone_start_pfn = 0;
+ zone->spanned_pages = 0;
+ }
+
+ zone_span_writeunlock(zone);
+}
+
+static void fix_zone_id(struct zone *zone, unsigned long start_pfn,
+ unsigned long end_pfn)
+{
+ enum zone_type zid = zone_idx(zone);
+ int nid = zone->zone_pgdat->node_id;
+ unsigned long pfn;
+
+ for (pfn = start_pfn; pfn < end_pfn; pfn++)
+ set_page_links(pfn_to_page(pfn), zid, nid, pfn);
+}
+
+static int __meminit move_pfn_range_left(struct zone *z1, struct zone *z2,
+ unsigned long start_pfn, unsigned long end_pfn)
+{
+ int ret;
+ unsigned long flags;
+ unsigned long z1_start_pfn;
+
+ if (!z1->wait_table) {
+ ret = init_currently_empty_zone(z1, start_pfn,
+ end_pfn - start_pfn, MEMMAP_HOTPLUG);
+ if (ret)
+ return ret;
+ }
+
+ pgdat_resize_lock(z1->zone_pgdat, &flags);
+
+ /* can't move pfns which are higher than @z2 */
+ if (end_pfn > z2->zone_start_pfn + z2->spanned_pages)
+ goto out_fail;
+ /* the move out part mast at the left most of @z2 */
+ if (start_pfn > z2->zone_start_pfn)
+ goto out_fail;
+ /* must included/overlap */
+ if (end_pfn <= z2->zone_start_pfn)
+ goto out_fail;
+
+ /* use start_pfn for z1's start_pfn if z1 is empty */
+ if (z1->spanned_pages)
+ z1_start_pfn = z1->zone_start_pfn;
+ else
+ z1_start_pfn = start_pfn;
+
+ resize_zone(z1, z1_start_pfn, end_pfn);
+ resize_zone(z2, end_pfn, z2->zone_start_pfn + z2->spanned_pages);
+
+ pgdat_resize_unlock(z1->zone_pgdat, &flags);
+
+ fix_zone_id(z1, start_pfn, end_pfn);
+
+ return 0;
+out_fail:
+ pgdat_resize_unlock(z1->zone_pgdat, &flags);
+ return -1;
+}
+
+static int __meminit move_pfn_range_right(struct zone *z1, struct zone *z2,
+ unsigned long start_pfn, unsigned long end_pfn)
+{
+ int ret;
+ unsigned long flags;
+ unsigned long z2_end_pfn;
+
+ if (!z2->wait_table) {
+ ret = init_currently_empty_zone(z2, start_pfn,
+ end_pfn - start_pfn, MEMMAP_HOTPLUG);
+ if (ret)
+ return ret;
+ }
+
+ pgdat_resize_lock(z1->zone_pgdat, &flags);
+
+ /* can't move pfns which are lower than @z1 */
+ if (z1->zone_start_pfn > start_pfn)
+ goto out_fail;
+ /* the move out part mast at the right most of @z1 */
+ if (z1->zone_start_pfn + z1->spanned_pages > end_pfn)
+ goto out_fail;
+ /* must included/overlap */
+ if (start_pfn >= z1->zone_start_pfn + z1->spanned_pages)
+ goto out_fail;
+
+ /* use end_pfn for z2's end_pfn if z2 is empty */
+ if (z2->spanned_pages)
+ z2_end_pfn = z2->zone_start_pfn + z2->spanned_pages;
+ else
+ z2_end_pfn = end_pfn;
+
+ resize_zone(z1, z1->zone_start_pfn, start_pfn);
+ resize_zone(z2, start_pfn, z2_end_pfn);
+
+ pgdat_resize_unlock(z1->zone_pgdat, &flags);
+
+ fix_zone_id(z2, start_pfn, end_pfn);
+
+ return 0;
+out_fail:
+ pgdat_resize_unlock(z1->zone_pgdat, &flags);
+ return -1;
+}
+
static void grow_pgdat_span(struct pglist_data *pgdat, unsigned long start_pfn,
unsigned long end_pfn)
{
unsigned long old_pgdat_end_pfn =
pgdat->node_start_pfn + pgdat->node_spanned_pages;
- if (start_pfn < pgdat->node_start_pfn)
+ if (!pgdat->node_spanned_pages || start_pfn < pgdat->node_start_pfn)
pgdat->node_start_pfn = start_pfn;
pgdat->node_spanned_pages = max(old_pgdat_end_pfn, end_pfn) -
@@ -467,8 +581,61 @@ static int online_pages_range(unsigned long start_pfn, unsigned long nr_pages,
return 0;
}
+/* ensure every online node has NORMAL memory */
+static bool can_online_high_movable(struct zone *zone)
+{
+ return node_state(zone_to_nid(zone), N_NORMAL_MEMORY);
+}
+
+/* check which state of node_states will be changed when online memory */
+static void node_states_check_changes_online(unsigned long nr_pages,
+ struct zone *zone, struct memory_notify *arg)
+{
+ int nid = zone_to_nid(zone);
+ enum zone_type zone_last = ZONE_NORMAL;
+
+ /*
+ * If we have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes
+ * which have 0...ZONE_NORMAL, set zone_last to ZONE_NORMAL.
+ *
+ * If we don't have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes
+ * which have 0...ZONE_MOVABLE, set zone_last to ZONE_MOVABLE.
+ */
+ if (N_HIGH_MEMORY == N_NORMAL_MEMORY)
+ zone_last = ZONE_MOVABLE;
+
+ /*
+ * if the memory to be online is in a zone of 0...zone_last, and
+ * the zones of 0...zone_last don't have memory before online, we will
+ * need to set the node to node_states[N_NORMAL_MEMORY] after
+ * the memory is online.
+ */
+ if (zone_idx(zone) <= zone_last && !node_state(nid, N_NORMAL_MEMORY))
+ arg->status_change_nid_normal = nid;
+ else
+ arg->status_change_nid_normal = -1;
+
+ /*
+ * if the node don't have memory befor online, we will need to
+ * set the node to node_states[N_HIGH_MEMORY] after the memory
+ * is online.
+ */
+ if (!node_state(nid, N_HIGH_MEMORY))
+ arg->status_change_nid = nid;
+ else
+ arg->status_change_nid = -1;
+}
-int __ref online_pages(unsigned long pfn, unsigned long nr_pages)
+static void node_states_set_node(int node, struct memory_notify *arg)
+{
+ if (arg->status_change_nid_normal >= 0)
+ node_set_state(node, N_NORMAL_MEMORY);
+
+ node_set_state(node, N_HIGH_MEMORY);
+}
+
+
+int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_type)
{
unsigned long onlined_pages = 0;
struct zone *zone;
@@ -478,13 +645,40 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages)
struct memory_notify arg;
lock_memory_hotplug();
+ /*
+ * This doesn't need a lock to do pfn_to_page().
+ * The section can't be removed here because of the
+ * memory_block->state_mutex.
+ */
+ zone = page_zone(pfn_to_page(pfn));
+
+ if ((zone_idx(zone) > ZONE_NORMAL || online_type == ONLINE_MOVABLE) &&
+ !can_online_high_movable(zone)) {
+ unlock_memory_hotplug();
+ return -1;
+ }
+
+ if (online_type == ONLINE_KERNEL && zone_idx(zone) == ZONE_MOVABLE) {
+ if (move_pfn_range_left(zone - 1, zone, pfn, pfn + nr_pages)) {
+ unlock_memory_hotplug();
+ return -1;
+ }
+ }
+ if (online_type == ONLINE_MOVABLE && zone_idx(zone) == ZONE_MOVABLE - 1) {
+ if (move_pfn_range_right(zone, zone + 1, pfn, pfn + nr_pages)) {
+ unlock_memory_hotplug();
+ return -1;
+ }
+ }
+
+ /* Previous code may changed the zone of the pfn range */
+ zone = page_zone(pfn_to_page(pfn));
+
arg.start_pfn = pfn;
arg.nr_pages = nr_pages;
- arg.status_change_nid = -1;
+ node_states_check_changes_online(nr_pages, zone, &arg);
nid = page_to_nid(pfn_to_page(pfn));
- if (node_present_pages(nid) == 0)
- arg.status_change_nid = nid;
ret = memory_notify(MEM_GOING_ONLINE, &arg);
ret = notifier_to_errno(ret);
@@ -494,23 +688,21 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages)
return ret;
}
/*
- * This doesn't need a lock to do pfn_to_page().
- * The section can't be removed here because of the
- * memory_block->state_mutex.
- */
- zone = page_zone(pfn_to_page(pfn));
- /*
* If this zone is not populated, then it is not in zonelist.
* This means the page allocator ignores this zone.
* So, zonelist must be updated after online.
*/
mutex_lock(&zonelists_mutex);
- if (!populated_zone(zone))
+ if (!populated_zone(zone)) {
need_zonelists_rebuild = 1;
+ build_all_zonelists(NULL, zone);
+ }
ret = walk_system_ram_range(pfn, nr_pages, &onlined_pages,
online_pages_range);
if (ret) {
+ if (need_zonelists_rebuild)
+ zone_pcp_reset(zone);
mutex_unlock(&zonelists_mutex);
printk(KERN_DEBUG "online_pages [mem %#010llx-%#010llx] failed\n",
(unsigned long long) pfn << PAGE_SHIFT,
@@ -524,9 +716,9 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages)
zone->present_pages += onlined_pages;
zone->zone_pgdat->node_present_pages += onlined_pages;
if (onlined_pages) {
- node_set_state(zone_to_nid(zone), N_HIGH_MEMORY);
+ node_states_set_node(zone_to_nid(zone), &arg);
if (need_zonelists_rebuild)
- build_all_zonelists(NULL, zone);
+ build_all_zonelists(NULL, NULL);
else
zone_pcp_update(zone);
}
@@ -854,7 +1046,7 @@ check_pages_isolated_cb(unsigned long start_pfn, unsigned long nr_pages,
{
int ret;
long offlined = *(long *)data;
- ret = test_pages_isolated(start_pfn, start_pfn + nr_pages);
+ ret = test_pages_isolated(start_pfn, start_pfn + nr_pages, true);
offlined = nr_pages;
if (!ret)
*(long *)data += offlined;
@@ -874,6 +1066,91 @@ check_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
return offlined;
}
+/* ensure the node has NORMAL memory if it is still online */
+static bool can_offline_normal(struct zone *zone, unsigned long nr_pages)
+{
+ struct pglist_data *pgdat = zone->zone_pgdat;
+ unsigned long present_pages = 0;
+ enum zone_type zt;
+
+ for (zt = 0; zt <= ZONE_NORMAL; zt++)
+ present_pages += pgdat->node_zones[zt].present_pages;
+
+ if (present_pages > nr_pages)
+ return true;
+
+ present_pages = 0;
+ for (; zt <= ZONE_MOVABLE; zt++)
+ present_pages += pgdat->node_zones[zt].present_pages;
+
+ /*
+ * we can't offline the last normal memory until all
+ * higher memory is offlined.
+ */
+ return present_pages == 0;
+}
+
+/* check which state of node_states will be changed when offline memory */
+static void node_states_check_changes_offline(unsigned long nr_pages,
+ struct zone *zone, struct memory_notify *arg)
+{
+ struct pglist_data *pgdat = zone->zone_pgdat;
+ unsigned long present_pages = 0;
+ enum zone_type zt, zone_last = ZONE_NORMAL;
+
+ /*
+ * If we have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes
+ * which have 0...ZONE_NORMAL, set zone_last to ZONE_NORMAL.
+ *
+ * If we don't have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes
+ * which have 0...ZONE_MOVABLE, set zone_last to ZONE_MOVABLE.
+ */
+ if (N_HIGH_MEMORY == N_NORMAL_MEMORY)
+ zone_last = ZONE_MOVABLE;
+
+ /*
+ * check whether node_states[N_NORMAL_MEMORY] will be changed.
+ * If the memory to be offline is in a zone of 0...zone_last,
+ * and it is the last present memory, 0...zone_last will
+ * become empty after offline , thus we can determind we will
+ * need to clear the node from node_states[N_NORMAL_MEMORY].
+ */
+ for (zt = 0; zt <= zone_last; zt++)
+ present_pages += pgdat->node_zones[zt].present_pages;
+ if (zone_idx(zone) <= zone_last && nr_pages >= present_pages)
+ arg->status_change_nid_normal = zone_to_nid(zone);
+ else
+ arg->status_change_nid_normal = -1;
+
+ /*
+ * node_states[N_HIGH_MEMORY] contains nodes which have 0...ZONE_MOVABLE
+ */
+ zone_last = ZONE_MOVABLE;
+
+ /*
+ * check whether node_states[N_HIGH_MEMORY] will be changed
+ * If we try to offline the last present @nr_pages from the node,
+ * we can determind we will need to clear the node from
+ * node_states[N_HIGH_MEMORY].
+ */
+ for (; zt <= zone_last; zt++)
+ present_pages += pgdat->node_zones[zt].present_pages;
+ if (nr_pages >= present_pages)
+ arg->status_change_nid = zone_to_nid(zone);
+ else
+ arg->status_change_nid = -1;
+}
+
+static void node_states_clear_node(int node, struct memory_notify *arg)
+{
+ if (arg->status_change_nid_normal >= 0)
+ node_clear_state(node, N_NORMAL_MEMORY);
+
+ if ((N_HIGH_MEMORY != N_NORMAL_MEMORY) &&
+ (arg->status_change_nid >= 0))
+ node_clear_state(node, N_HIGH_MEMORY);
+}
+
static int __ref __offline_pages(unsigned long start_pfn,
unsigned long end_pfn, unsigned long timeout)
{
@@ -900,16 +1177,19 @@ static int __ref __offline_pages(unsigned long start_pfn,
node = zone_to_nid(zone);
nr_pages = end_pfn - start_pfn;
+ ret = -EINVAL;
+ if (zone_idx(zone) <= ZONE_NORMAL && !can_offline_normal(zone, nr_pages))
+ goto out;
+
/* set above range as isolated */
- ret = start_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE);
+ ret = start_isolate_page_range(start_pfn, end_pfn,
+ MIGRATE_MOVABLE, true);
if (ret)
goto out;
arg.start_pfn = start_pfn;
arg.nr_pages = nr_pages;
- arg.status_change_nid = -1;
- if (nr_pages >= node_present_pages(node))
- arg.status_change_nid = node;
+ node_states_check_changes_offline(nr_pages, zone, &arg);
ret = memory_notify(MEM_GOING_OFFLINE, &arg);
ret = notifier_to_errno(ret);
@@ -982,10 +1262,9 @@ repeat:
} else
zone_pcp_update(zone);
- if (!node_present_pages(node)) {
- node_clear_state(node, N_HIGH_MEMORY);
+ node_states_clear_node(node, &arg);
+ if (arg.status_change_nid >= 0)
kswapd_stop(node);
- }
vm_total_pages = nr_free_pagecache_pages();
writeback_set_ratelimit();
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index d04a8a54c29..05b28361a39 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1907,7 +1907,6 @@ alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma,
unsigned long addr, int node)
{
struct mempolicy *pol;
- struct zonelist *zl;
struct page *page;
unsigned int cpuset_mems_cookie;
@@ -1926,23 +1925,11 @@ retry_cpuset:
return page;
}
- zl = policy_zonelist(gfp, pol, node);
- if (unlikely(mpol_needs_cond_ref(pol))) {
- /*
- * slow path: ref counted shared policy
- */
- struct page *page = __alloc_pages_nodemask(gfp, order,
- zl, policy_nodemask(gfp, pol));
- __mpol_put(pol);
- if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page))
- goto retry_cpuset;
- return page;
- }
- /*
- * fast path: default or task policy
- */
- page = __alloc_pages_nodemask(gfp, order, zl,
+ page = __alloc_pages_nodemask(gfp, order,
+ policy_zonelist(gfp, pol, node),
policy_nodemask(gfp, pol));
+ if (unlikely(mpol_needs_cond_ref(pol)))
+ __mpol_put(pol);
if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page))
goto retry_cpuset;
return page;
@@ -2037,28 +2024,6 @@ struct mempolicy *__mpol_dup(struct mempolicy *old)
return new;
}
-/*
- * If *frompol needs [has] an extra ref, copy *frompol to *tompol ,
- * eliminate the * MPOL_F_* flags that require conditional ref and
- * [NOTE!!!] drop the extra ref. Not safe to reference *frompol directly
- * after return. Use the returned value.
- *
- * Allows use of a mempolicy for, e.g., multiple allocations with a single
- * policy lookup, even if the policy needs/has extra ref on lookup.
- * shmem_readahead needs this.
- */
-struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol,
- struct mempolicy *frompol)
-{
- if (!mpol_needs_cond_ref(frompol))
- return frompol;
-
- *tompol = *frompol;
- tompol->flags &= ~MPOL_F_SHARED; /* copy doesn't need unref */
- __mpol_put(frompol);
- return tompol;
-}
-
/* Slow path of a mempolicy comparison */
bool __mpol_equal(struct mempolicy *a, struct mempolicy *b)
{
diff --git a/mm/migrate.c b/mm/migrate.c
index 77ed2d77370..3f675ca0827 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -35,6 +35,7 @@
#include <linux/hugetlb.h>
#include <linux/hugetlb_cgroup.h>
#include <linux/gfp.h>
+#include <linux/balloon_compaction.h>
#include <asm/tlbflush.h>
@@ -79,7 +80,30 @@ void putback_lru_pages(struct list_head *l)
list_del(&page->lru);
dec_zone_page_state(page, NR_ISOLATED_ANON +
page_is_file_cache(page));
- putback_lru_page(page);
+ putback_lru_page(page);
+ }
+}
+
+/*
+ * Put previously isolated pages back onto the appropriate lists
+ * from where they were once taken off for compaction/migration.
+ *
+ * This function shall be used instead of putback_lru_pages(),
+ * whenever the isolated pageset has been built by isolate_migratepages_range()
+ */
+void putback_movable_pages(struct list_head *l)
+{
+ struct page *page;
+ struct page *page2;
+
+ list_for_each_entry_safe(page, page2, l, lru) {
+ list_del(&page->lru);
+ dec_zone_page_state(page, NR_ISOLATED_ANON +
+ page_is_file_cache(page));
+ if (unlikely(balloon_page_movable(page)))
+ balloon_page_putback(page);
+ else
+ putback_lru_page(page);
}
}
@@ -91,8 +115,6 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,
{
struct mm_struct *mm = vma->vm_mm;
swp_entry_t entry;
- pgd_t *pgd;
- pud_t *pud;
pmd_t *pmd;
pte_t *ptep, pte;
spinlock_t *ptl;
@@ -103,19 +125,11 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,
goto out;
ptl = &mm->page_table_lock;
} else {
- pgd = pgd_offset(mm, addr);
- if (!pgd_present(*pgd))
- goto out;
-
- pud = pud_offset(pgd, addr);
- if (!pud_present(*pud))
+ pmd = mm_find_pmd(mm, addr);
+ if (!pmd)
goto out;
-
- pmd = pmd_offset(pud, addr);
if (pmd_trans_huge(*pmd))
goto out;
- if (!pmd_present(*pmd))
- goto out;
ptep = pte_offset_map(pmd, addr);
@@ -286,7 +300,7 @@ static int migrate_page_move_mapping(struct address_space *mapping,
/* Anonymous page without mapping */
if (page_count(page) != 1)
return -EAGAIN;
- return 0;
+ return MIGRATEPAGE_SUCCESS;
}
spin_lock_irq(&mapping->tree_lock);
@@ -356,7 +370,7 @@ static int migrate_page_move_mapping(struct address_space *mapping,
}
spin_unlock_irq(&mapping->tree_lock);
- return 0;
+ return MIGRATEPAGE_SUCCESS;
}
/*
@@ -372,7 +386,7 @@ int migrate_huge_page_move_mapping(struct address_space *mapping,
if (!mapping) {
if (page_count(page) != 1)
return -EAGAIN;
- return 0;
+ return MIGRATEPAGE_SUCCESS;
}
spin_lock_irq(&mapping->tree_lock);
@@ -399,7 +413,7 @@ int migrate_huge_page_move_mapping(struct address_space *mapping,
page_unfreeze_refs(page, expected_count - 1);
spin_unlock_irq(&mapping->tree_lock);
- return 0;
+ return MIGRATEPAGE_SUCCESS;
}
/*
@@ -486,11 +500,11 @@ int migrate_page(struct address_space *mapping,
rc = migrate_page_move_mapping(mapping, newpage, page, NULL, mode);
- if (rc)
+ if (rc != MIGRATEPAGE_SUCCESS)
return rc;
migrate_page_copy(newpage, page);
- return 0;
+ return MIGRATEPAGE_SUCCESS;
}
EXPORT_SYMBOL(migrate_page);
@@ -513,7 +527,7 @@ int buffer_migrate_page(struct address_space *mapping,
rc = migrate_page_move_mapping(mapping, newpage, page, head, mode);
- if (rc)
+ if (rc != MIGRATEPAGE_SUCCESS)
return rc;
/*
@@ -549,7 +563,7 @@ int buffer_migrate_page(struct address_space *mapping,
} while (bh != head);
- return 0;
+ return MIGRATEPAGE_SUCCESS;
}
EXPORT_SYMBOL(buffer_migrate_page);
#endif
@@ -628,7 +642,7 @@ static int fallback_migrate_page(struct address_space *mapping,
*
* Return value:
* < 0 - error code
- * == 0 - success
+ * MIGRATEPAGE_SUCCESS - success
*/
static int move_to_new_page(struct page *newpage, struct page *page,
int remap_swapcache, enum migrate_mode mode)
@@ -665,7 +679,7 @@ static int move_to_new_page(struct page *newpage, struct page *page,
else
rc = fallback_migrate_page(mapping, newpage, page, mode);
- if (rc) {
+ if (rc != MIGRATEPAGE_SUCCESS) {
newpage->mapping = NULL;
} else {
if (remap_swapcache)
@@ -778,6 +792,18 @@ static int __unmap_and_move(struct page *page, struct page *newpage,
}
}
+ if (unlikely(balloon_page_movable(page))) {
+ /*
+ * A ballooned page does not need any special attention from
+ * physical to virtual reverse mapping procedures.
+ * Skip any attempt to unmap PTEs or to remap swap cache,
+ * in order to avoid burning cycles at rmap level, and perform
+ * the page migration right away (proteced by page lock).
+ */
+ rc = balloon_page_migrate(newpage, page, mode);
+ goto uncharge;
+ }
+
/*
* Corner case handling:
* 1. When a new swap-cache page is read into, it is added to the LRU
@@ -814,7 +840,9 @@ skip_unmap:
put_anon_vma(anon_vma);
uncharge:
- mem_cgroup_end_migration(mem, page, newpage, rc == 0);
+ mem_cgroup_end_migration(mem, page, newpage,
+ (rc == MIGRATEPAGE_SUCCESS ||
+ rc == MIGRATEPAGE_BALLOON_SUCCESS));
unlock:
unlock_page(page);
out:
@@ -846,6 +874,18 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
goto out;
rc = __unmap_and_move(page, newpage, force, offlining, mode);
+
+ if (unlikely(rc == MIGRATEPAGE_BALLOON_SUCCESS)) {
+ /*
+ * A ballooned page has been migrated already.
+ * Now, it's the time to wrap-up counters,
+ * handle the page back to Buddy and return.
+ */
+ dec_zone_page_state(page, NR_ISOLATED_ANON +
+ page_is_file_cache(page));
+ balloon_page_free(page);
+ return MIGRATEPAGE_SUCCESS;
+ }
out:
if (rc != -EAGAIN) {
/*
@@ -987,7 +1027,7 @@ int migrate_pages(struct list_head *from,
case -EAGAIN:
retry++;
break;
- case 0:
+ case MIGRATEPAGE_SUCCESS:
break;
default:
/* Permanent failure */
@@ -996,15 +1036,12 @@ int migrate_pages(struct list_head *from,
}
}
}
- rc = 0;
+ rc = nr_failed + retry;
out:
if (!swapwrite)
current->flags &= ~PF_SWAPWRITE;
- if (rc)
- return rc;
-
- return nr_failed + retry;
+ return rc;
}
int migrate_huge_page(struct page *hpage, new_page_t get_new_page,
@@ -1024,7 +1061,7 @@ int migrate_huge_page(struct page *hpage, new_page_t get_new_page,
/* try again */
cond_resched();
break;
- case 0:
+ case MIGRATEPAGE_SUCCESS:
goto out;
default:
rc = -EIO;
diff --git a/mm/mmap.c b/mm/mmap.c
index 2d942353d68..f940062c8d4 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -31,6 +31,7 @@
#include <linux/audit.h>
#include <linux/khugepaged.h>
#include <linux/uprobes.h>
+#include <linux/rbtree_augmented.h>
#include <asm/uaccess.h>
#include <asm/cacheflush.h>
@@ -89,6 +90,20 @@ int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
struct percpu_counter vm_committed_as ____cacheline_aligned_in_smp;
/*
+ * The global memory commitment made in the system can be a metric
+ * that can be used to drive ballooning decisions when Linux is hosted
+ * as a guest. On Hyper-V, the host implements a policy engine for dynamically
+ * balancing memory across competing virtual machines that are hosted.
+ * Several metrics drive this policy engine including the guest reported
+ * memory commitment.
+ */
+unsigned long vm_memory_committed(void)
+{
+ return percpu_counter_read_positive(&vm_committed_as);
+}
+EXPORT_SYMBOL_GPL(vm_memory_committed);
+
+/*
* Check that a process has enough memory to allocate a new virtual
* mapping. 0 means there is enough memory for the allocation to
* succeed and -ENOMEM implies there is not.
@@ -297,59 +312,162 @@ out:
return retval;
}
+static long vma_compute_subtree_gap(struct vm_area_struct *vma)
+{
+ unsigned long max, subtree_gap;
+ max = vma->vm_start;
+ if (vma->vm_prev)
+ max -= vma->vm_prev->vm_end;
+ if (vma->vm_rb.rb_left) {
+ subtree_gap = rb_entry(vma->vm_rb.rb_left,
+ struct vm_area_struct, vm_rb)->rb_subtree_gap;
+ if (subtree_gap > max)
+ max = subtree_gap;
+ }
+ if (vma->vm_rb.rb_right) {
+ subtree_gap = rb_entry(vma->vm_rb.rb_right,
+ struct vm_area_struct, vm_rb)->rb_subtree_gap;
+ if (subtree_gap > max)
+ max = subtree_gap;
+ }
+ return max;
+}
+
#ifdef CONFIG_DEBUG_VM_RB
static int browse_rb(struct rb_root *root)
{
- int i = 0, j;
+ int i = 0, j, bug = 0;
struct rb_node *nd, *pn = NULL;
unsigned long prev = 0, pend = 0;
for (nd = rb_first(root); nd; nd = rb_next(nd)) {
struct vm_area_struct *vma;
vma = rb_entry(nd, struct vm_area_struct, vm_rb);
- if (vma->vm_start < prev)
- printk("vm_start %lx prev %lx\n", vma->vm_start, prev), i = -1;
- if (vma->vm_start < pend)
+ if (vma->vm_start < prev) {
+ printk("vm_start %lx prev %lx\n", vma->vm_start, prev);
+ bug = 1;
+ }
+ if (vma->vm_start < pend) {
printk("vm_start %lx pend %lx\n", vma->vm_start, pend);
- if (vma->vm_start > vma->vm_end)
- printk("vm_end %lx < vm_start %lx\n", vma->vm_end, vma->vm_start);
+ bug = 1;
+ }
+ if (vma->vm_start > vma->vm_end) {
+ printk("vm_end %lx < vm_start %lx\n",
+ vma->vm_end, vma->vm_start);
+ bug = 1;
+ }
+ if (vma->rb_subtree_gap != vma_compute_subtree_gap(vma)) {
+ printk("free gap %lx, correct %lx\n",
+ vma->rb_subtree_gap,
+ vma_compute_subtree_gap(vma));
+ bug = 1;
+ }
i++;
pn = nd;
prev = vma->vm_start;
pend = vma->vm_end;
}
j = 0;
- for (nd = pn; nd; nd = rb_prev(nd)) {
+ for (nd = pn; nd; nd = rb_prev(nd))
j++;
+ if (i != j) {
+ printk("backwards %d, forwards %d\n", j, i);
+ bug = 1;
+ }
+ return bug ? -1 : i;
+}
+
+static void validate_mm_rb(struct rb_root *root, struct vm_area_struct *ignore)
+{
+ struct rb_node *nd;
+
+ for (nd = rb_first(root); nd; nd = rb_next(nd)) {
+ struct vm_area_struct *vma;
+ vma = rb_entry(nd, struct vm_area_struct, vm_rb);
+ BUG_ON(vma != ignore &&
+ vma->rb_subtree_gap != vma_compute_subtree_gap(vma));
}
- if (i != j)
- printk("backwards %d, forwards %d\n", j, i), i = 0;
- return i;
}
void validate_mm(struct mm_struct *mm)
{
int bug = 0;
int i = 0;
+ unsigned long highest_address = 0;
struct vm_area_struct *vma = mm->mmap;
while (vma) {
struct anon_vma_chain *avc;
+ vma_lock_anon_vma(vma);
list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
anon_vma_interval_tree_verify(avc);
+ vma_unlock_anon_vma(vma);
+ highest_address = vma->vm_end;
vma = vma->vm_next;
i++;
}
- if (i != mm->map_count)
- printk("map_count %d vm_next %d\n", mm->map_count, i), bug = 1;
+ if (i != mm->map_count) {
+ printk("map_count %d vm_next %d\n", mm->map_count, i);
+ bug = 1;
+ }
+ if (highest_address != mm->highest_vm_end) {
+ printk("mm->highest_vm_end %lx, found %lx\n",
+ mm->highest_vm_end, highest_address);
+ bug = 1;
+ }
i = browse_rb(&mm->mm_rb);
- if (i != mm->map_count)
- printk("map_count %d rb %d\n", mm->map_count, i), bug = 1;
+ if (i != mm->map_count) {
+ printk("map_count %d rb %d\n", mm->map_count, i);
+ bug = 1;
+ }
BUG_ON(bug);
}
#else
+#define validate_mm_rb(root, ignore) do { } while (0)
#define validate_mm(mm) do { } while (0)
#endif
+RB_DECLARE_CALLBACKS(static, vma_gap_callbacks, struct vm_area_struct, vm_rb,
+ unsigned long, rb_subtree_gap, vma_compute_subtree_gap)
+
+/*
+ * Update augmented rbtree rb_subtree_gap values after vma->vm_start or
+ * vma->vm_prev->vm_end values changed, without modifying the vma's position
+ * in the rbtree.
+ */
+static void vma_gap_update(struct vm_area_struct *vma)
+{
+ /*
+ * As it turns out, RB_DECLARE_CALLBACKS() already created a callback
+ * function that does exacltly what we want.
+ */
+ vma_gap_callbacks_propagate(&vma->vm_rb, NULL);
+}
+
+static inline void vma_rb_insert(struct vm_area_struct *vma,
+ struct rb_root *root)
+{
+ /* All rb_subtree_gap values must be consistent prior to insertion */
+ validate_mm_rb(root, NULL);
+
+ rb_insert_augmented(&vma->vm_rb, root, &vma_gap_callbacks);
+}
+
+static void vma_rb_erase(struct vm_area_struct *vma, struct rb_root *root)
+{
+ /*
+ * All rb_subtree_gap values must be consistent prior to erase,
+ * with the possible exception of the vma being erased.
+ */
+ validate_mm_rb(root, vma);
+
+ /*
+ * Note rb_erase_augmented is a fairly large inline function,
+ * so make sure we instantiate it only once with our desired
+ * augmented rbtree callbacks.
+ */
+ rb_erase_augmented(&vma->vm_rb, root, &vma_gap_callbacks);
+}
+
/*
* vma has some anon_vma assigned, and is already inserted on that
* anon_vma's interval trees.
@@ -419,8 +537,25 @@ static int find_vma_links(struct mm_struct *mm, unsigned long addr,
void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma,
struct rb_node **rb_link, struct rb_node *rb_parent)
{
+ /* Update tracking information for the gap following the new vma. */
+ if (vma->vm_next)
+ vma_gap_update(vma->vm_next);
+ else
+ mm->highest_vm_end = vma->vm_end;
+
+ /*
+ * vma->vm_prev wasn't known when we followed the rbtree to find the
+ * correct insertion point for that vma. As a result, we could not
+ * update the vma vm_rb parents rb_subtree_gap values on the way down.
+ * So, we first insert the vma with a zero rb_subtree_gap value
+ * (to be consistent with what we did on the way down), and then
+ * immediately update the gap to the correct value. Finally we
+ * rebalance the rbtree after all augmented values have been set.
+ */
rb_link_node(&vma->vm_rb, rb_parent, rb_link);
- rb_insert_color(&vma->vm_rb, &mm->mm_rb);
+ vma->rb_subtree_gap = 0;
+ vma_gap_update(vma);
+ vma_rb_insert(vma, &mm->mm_rb);
}
static void __vma_link_file(struct vm_area_struct *vma)
@@ -496,12 +631,12 @@ static inline void
__vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma,
struct vm_area_struct *prev)
{
- struct vm_area_struct *next = vma->vm_next;
+ struct vm_area_struct *next;
- prev->vm_next = next;
+ vma_rb_erase(vma, &mm->mm_rb);
+ prev->vm_next = next = vma->vm_next;
if (next)
next->vm_prev = prev;
- rb_erase(&vma->vm_rb, &mm->mm_rb);
if (mm->mmap_cache == vma)
mm->mmap_cache = prev;
}
@@ -523,6 +658,7 @@ int vma_adjust(struct vm_area_struct *vma, unsigned long start,
struct rb_root *root = NULL;
struct anon_vma *anon_vma = NULL;
struct file *file = vma->vm_file;
+ bool start_changed = false, end_changed = false;
long adjust_next = 0;
int remove_next = 0;
@@ -613,8 +749,14 @@ again: remove_next = 1 + (end > next->vm_end);
vma_interval_tree_remove(next, root);
}
- vma->vm_start = start;
- vma->vm_end = end;
+ if (start != vma->vm_start) {
+ vma->vm_start = start;
+ start_changed = true;
+ }
+ if (end != vma->vm_end) {
+ vma->vm_end = end;
+ end_changed = true;
+ }
vma->vm_pgoff = pgoff;
if (adjust_next) {
next->vm_start += adjust_next << PAGE_SHIFT;
@@ -643,6 +785,15 @@ again: remove_next = 1 + (end > next->vm_end);
* (it may either follow vma or precede it).
*/
__insert_vm_struct(mm, insert);
+ } else {
+ if (start_changed)
+ vma_gap_update(vma);
+ if (end_changed) {
+ if (!next)
+ mm->highest_vm_end = end;
+ else if (!adjust_next)
+ vma_gap_update(next);
+ }
}
if (anon_vma) {
@@ -676,10 +827,13 @@ again: remove_next = 1 + (end > next->vm_end);
* we must remove another next too. It would clutter
* up the code too much to do both in one go.
*/
- if (remove_next == 2) {
- next = vma->vm_next;
+ next = vma->vm_next;
+ if (remove_next == 2)
goto again;
- }
+ else if (next)
+ vma_gap_update(next);
+ else
+ mm->highest_vm_end = end;
}
if (insert && file)
uprobe_mmap(insert);
@@ -1151,8 +1305,9 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
* memory so no accounting is necessary
*/
file = hugetlb_file_setup(HUGETLB_ANON_FILE, addr, len,
- VM_NORESERVE, &user,
- HUGETLB_ANONHUGE_INODE);
+ VM_NORESERVE,
+ &user, HUGETLB_ANONHUGE_INODE,
+ (flags >> MAP_HUGE_SHIFT) & MAP_HUGE_MASK);
if (IS_ERR(file))
return PTR_ERR(file);
}
@@ -1398,6 +1553,206 @@ unacct_error:
return error;
}
+unsigned long unmapped_area(struct vm_unmapped_area_info *info)
+{
+ /*
+ * We implement the search by looking for an rbtree node that
+ * immediately follows a suitable gap. That is,
+ * - gap_start = vma->vm_prev->vm_end <= info->high_limit - length;
+ * - gap_end = vma->vm_start >= info->low_limit + length;
+ * - gap_end - gap_start >= length
+ */
+
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ unsigned long length, low_limit, high_limit, gap_start, gap_end;
+
+ /* Adjust search length to account for worst case alignment overhead */
+ length = info->length + info->align_mask;
+ if (length < info->length)
+ return -ENOMEM;
+
+ /* Adjust search limits by the desired length */
+ if (info->high_limit < length)
+ return -ENOMEM;
+ high_limit = info->high_limit - length;
+
+ if (info->low_limit > high_limit)
+ return -ENOMEM;
+ low_limit = info->low_limit + length;
+
+ /* Check if rbtree root looks promising */
+ if (RB_EMPTY_ROOT(&mm->mm_rb))
+ goto check_highest;
+ vma = rb_entry(mm->mm_rb.rb_node, struct vm_area_struct, vm_rb);
+ if (vma->rb_subtree_gap < length)
+ goto check_highest;
+
+ while (true) {
+ /* Visit left subtree if it looks promising */
+ gap_end = vma->vm_start;
+ if (gap_end >= low_limit && vma->vm_rb.rb_left) {
+ struct vm_area_struct *left =
+ rb_entry(vma->vm_rb.rb_left,
+ struct vm_area_struct, vm_rb);
+ if (left->rb_subtree_gap >= length) {
+ vma = left;
+ continue;
+ }
+ }
+
+ gap_start = vma->vm_prev ? vma->vm_prev->vm_end : 0;
+check_current:
+ /* Check if current node has a suitable gap */
+ if (gap_start > high_limit)
+ return -ENOMEM;
+ if (gap_end >= low_limit && gap_end - gap_start >= length)
+ goto found;
+
+ /* Visit right subtree if it looks promising */
+ if (vma->vm_rb.rb_right) {
+ struct vm_area_struct *right =
+ rb_entry(vma->vm_rb.rb_right,
+ struct vm_area_struct, vm_rb);
+ if (right->rb_subtree_gap >= length) {
+ vma = right;
+ continue;
+ }
+ }
+
+ /* Go back up the rbtree to find next candidate node */
+ while (true) {
+ struct rb_node *prev = &vma->vm_rb;
+ if (!rb_parent(prev))
+ goto check_highest;
+ vma = rb_entry(rb_parent(prev),
+ struct vm_area_struct, vm_rb);
+ if (prev == vma->vm_rb.rb_left) {
+ gap_start = vma->vm_prev->vm_end;
+ gap_end = vma->vm_start;
+ goto check_current;
+ }
+ }
+ }
+
+check_highest:
+ /* Check highest gap, which does not precede any rbtree node */
+ gap_start = mm->highest_vm_end;
+ gap_end = ULONG_MAX; /* Only for VM_BUG_ON below */
+ if (gap_start > high_limit)
+ return -ENOMEM;
+
+found:
+ /* We found a suitable gap. Clip it with the original low_limit. */
+ if (gap_start < info->low_limit)
+ gap_start = info->low_limit;
+
+ /* Adjust gap address to the desired alignment */
+ gap_start += (info->align_offset - gap_start) & info->align_mask;
+
+ VM_BUG_ON(gap_start + info->length > info->high_limit);
+ VM_BUG_ON(gap_start + info->length > gap_end);
+ return gap_start;
+}
+
+unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info)
+{
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ unsigned long length, low_limit, high_limit, gap_start, gap_end;
+
+ /* Adjust search length to account for worst case alignment overhead */
+ length = info->length + info->align_mask;
+ if (length < info->length)
+ return -ENOMEM;
+
+ /*
+ * Adjust search limits by the desired length.
+ * See implementation comment at top of unmapped_area().
+ */
+ gap_end = info->high_limit;
+ if (gap_end < length)
+ return -ENOMEM;
+ high_limit = gap_end - length;
+
+ if (info->low_limit > high_limit)
+ return -ENOMEM;
+ low_limit = info->low_limit + length;
+
+ /* Check highest gap, which does not precede any rbtree node */
+ gap_start = mm->highest_vm_end;
+ if (gap_start <= high_limit)
+ goto found_highest;
+
+ /* Check if rbtree root looks promising */
+ if (RB_EMPTY_ROOT(&mm->mm_rb))
+ return -ENOMEM;
+ vma = rb_entry(mm->mm_rb.rb_node, struct vm_area_struct, vm_rb);
+ if (vma->rb_subtree_gap < length)
+ return -ENOMEM;
+
+ while (true) {
+ /* Visit right subtree if it looks promising */
+ gap_start = vma->vm_prev ? vma->vm_prev->vm_end : 0;
+ if (gap_start <= high_limit && vma->vm_rb.rb_right) {
+ struct vm_area_struct *right =
+ rb_entry(vma->vm_rb.rb_right,
+ struct vm_area_struct, vm_rb);
+ if (right->rb_subtree_gap >= length) {
+ vma = right;
+ continue;
+ }
+ }
+
+check_current:
+ /* Check if current node has a suitable gap */
+ gap_end = vma->vm_start;
+ if (gap_end < low_limit)
+ return -ENOMEM;
+ if (gap_start <= high_limit && gap_end - gap_start >= length)
+ goto found;
+
+ /* Visit left subtree if it looks promising */
+ if (vma->vm_rb.rb_left) {
+ struct vm_area_struct *left =
+ rb_entry(vma->vm_rb.rb_left,
+ struct vm_area_struct, vm_rb);
+ if (left->rb_subtree_gap >= length) {
+ vma = left;
+ continue;
+ }
+ }
+
+ /* Go back up the rbtree to find next candidate node */
+ while (true) {
+ struct rb_node *prev = &vma->vm_rb;
+ if (!rb_parent(prev))
+ return -ENOMEM;
+ vma = rb_entry(rb_parent(prev),
+ struct vm_area_struct, vm_rb);
+ if (prev == vma->vm_rb.rb_right) {
+ gap_start = vma->vm_prev ?
+ vma->vm_prev->vm_end : 0;
+ goto check_current;
+ }
+ }
+ }
+
+found:
+ /* We found a suitable gap. Clip it with the original high_limit. */
+ if (gap_end > info->high_limit)
+ gap_end = info->high_limit;
+
+found_highest:
+ /* Compute highest gap address at the desired alignment */
+ gap_end -= info->length;
+ gap_end -= (gap_end - info->align_offset) & info->align_mask;
+
+ VM_BUG_ON(gap_end < info->low_limit);
+ VM_BUG_ON(gap_end < gap_start);
+ return gap_end;
+}
+
/* Get an address range which is currently unmapped.
* For shmat() with addr=0.
*
@@ -1416,7 +1771,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
- unsigned long start_addr;
+ struct vm_unmapped_area_info info;
if (len > TASK_SIZE)
return -ENOMEM;
@@ -1431,40 +1786,13 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
(!vma || addr + len <= vma->vm_start))
return addr;
}
- if (len > mm->cached_hole_size) {
- start_addr = addr = mm->free_area_cache;
- } else {
- start_addr = addr = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = 0;
- }
-full_search:
- for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
- /* At this point: (!vma || addr < vma->vm_end). */
- if (TASK_SIZE - len < addr) {
- /*
- * Start a new search - just in case we missed
- * some holes.
- */
- if (start_addr != TASK_UNMAPPED_BASE) {
- addr = TASK_UNMAPPED_BASE;
- start_addr = addr;
- mm->cached_hole_size = 0;
- goto full_search;
- }
- return -ENOMEM;
- }
- if (!vma || addr + len <= vma->vm_start) {
- /*
- * Remember the place where we stopped the search:
- */
- mm->free_area_cache = addr + len;
- return addr;
- }
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
- addr = vma->vm_end;
- }
+ info.flags = 0;
+ info.length = len;
+ info.low_limit = TASK_UNMAPPED_BASE;
+ info.high_limit = TASK_SIZE;
+ info.align_mask = 0;
+ return vm_unmapped_area(&info);
}
#endif
@@ -1489,7 +1817,8 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
{
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
- unsigned long addr = addr0, start_addr;
+ unsigned long addr = addr0;
+ struct vm_unmapped_area_info info;
/* requested length too big for entire address space */
if (len > TASK_SIZE)
@@ -1507,53 +1836,12 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
return addr;
}
- /* check if free_area_cache is useful for us */
- if (len <= mm->cached_hole_size) {
- mm->cached_hole_size = 0;
- mm->free_area_cache = mm->mmap_base;
- }
-
-try_again:
- /* either no address requested or can't fit in requested address hole */
- start_addr = addr = mm->free_area_cache;
-
- if (addr < len)
- goto fail;
-
- addr -= len;
- do {
- /*
- * Lookup failure means no vma is above this address,
- * else if new region fits below vma->vm_start,
- * return with success:
- */
- vma = find_vma(mm, addr);
- if (!vma || addr+len <= vma->vm_start)
- /* remember the address as a hint for next time */
- return (mm->free_area_cache = addr);
-
- /* remember the largest hole we saw so far */
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
-
- /* try just below the current vma->vm_start */
- addr = vma->vm_start-len;
- } while (len < vma->vm_start);
-
-fail:
- /*
- * if hint left us with no space for the requested
- * mapping then try again:
- *
- * Note: this is different with the case of bottomup
- * which does the fully line-search, but we use find_vma
- * here that causes some holes skipped.
- */
- if (start_addr != mm->mmap_base) {
- mm->free_area_cache = mm->mmap_base;
- mm->cached_hole_size = 0;
- goto try_again;
- }
+ info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+ info.length = len;
+ info.low_limit = PAGE_SIZE;
+ info.high_limit = mm->mmap_base;
+ info.align_mask = 0;
+ addr = vm_unmapped_area(&info);
/*
* A failed mmap() very likely causes application failure,
@@ -1561,14 +1849,13 @@ fail:
* can happen with large stack limits and large mmap()
* allocations.
*/
- mm->cached_hole_size = ~0UL;
- mm->free_area_cache = TASK_UNMAPPED_BASE;
- addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
- /*
- * Restore the topdown base:
- */
- mm->free_area_cache = mm->mmap_base;
- mm->cached_hole_size = ~0UL;
+ if (addr & ~PAGE_MASK) {
+ VM_BUG_ON(addr != -ENOMEM);
+ info.flags = 0;
+ info.low_limit = TASK_UNMAPPED_BASE;
+ info.high_limit = TASK_SIZE;
+ addr = vm_unmapped_area(&info);
+ }
return addr;
}
@@ -1781,6 +2068,10 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
anon_vma_interval_tree_pre_update_vma(vma);
vma->vm_end = address;
anon_vma_interval_tree_post_update_vma(vma);
+ if (vma->vm_next)
+ vma_gap_update(vma->vm_next);
+ else
+ vma->vm_mm->highest_vm_end = address;
perf_event_mmap(vma);
}
}
@@ -1835,6 +2126,7 @@ int expand_downwards(struct vm_area_struct *vma,
vma->vm_start = address;
vma->vm_pgoff -= grow;
anon_vma_interval_tree_post_update_vma(vma);
+ vma_gap_update(vma);
perf_event_mmap(vma);
}
}
@@ -1957,14 +2249,17 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
insertion_point = (prev ? &prev->vm_next : &mm->mmap);
vma->vm_prev = NULL;
do {
- rb_erase(&vma->vm_rb, &mm->mm_rb);
+ vma_rb_erase(vma, &mm->mm_rb);
mm->map_count--;
tail_vma = vma;
vma = vma->vm_next;
} while (vma && vma->vm_start < end);
*insertion_point = vma;
- if (vma)
+ if (vma) {
vma->vm_prev = prev;
+ vma_gap_update(vma);
+ } else
+ mm->highest_vm_end = prev ? prev->vm_end : 0;
tail_vma->vm_next = NULL;
if (mm->unmap_area == arch_unmap_area)
addr = prev ? prev->vm_end : mm->mmap_base;
diff --git a/mm/mmzone.c b/mm/mmzone.c
index 3cef80f6ac7..4596d81b89b 100644
--- a/mm/mmzone.c
+++ b/mm/mmzone.c
@@ -87,7 +87,7 @@ int memmap_valid_within(unsigned long pfn,
}
#endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */
-void lruvec_init(struct lruvec *lruvec, struct zone *zone)
+void lruvec_init(struct lruvec *lruvec)
{
enum lru_list lru;
@@ -95,8 +95,4 @@ void lruvec_init(struct lruvec *lruvec, struct zone *zone)
for_each_lru(lru)
INIT_LIST_HEAD(&lruvec->lists[lru]);
-
-#ifdef CONFIG_MEMCG
- lruvec->zone = zone;
-#endif
}
diff --git a/mm/nobootmem.c b/mm/nobootmem.c
index 714d5d65047..bd82f6b3141 100644
--- a/mm/nobootmem.c
+++ b/mm/nobootmem.c
@@ -116,8 +116,6 @@ static unsigned long __init __free_memory_core(phys_addr_t start,
return 0;
__free_pages_memory(start_pfn, end_pfn);
- fixup_zone_present_pages(pfn_to_nid(start >> PAGE_SHIFT),
- start_pfn, end_pfn);
return end_pfn - start_pfn;
}
@@ -128,7 +126,6 @@ unsigned long __init free_low_memory_core_early(int nodeid)
phys_addr_t start, end, size;
u64 i;
- reset_zone_present_pages();
for_each_free_mem_range(i, MAX_NUMNODES, &start, &end, NULL)
count += __free_memory_core(start, end);
diff --git a/mm/nommu.c b/mm/nommu.c
index 45131b41bcd..79c3cac87af 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -66,6 +66,21 @@ int heap_stack_gap = 0;
atomic_long_t mmap_pages_allocated;
+/*
+ * The global memory commitment made in the system can be a metric
+ * that can be used to drive ballooning decisions when Linux is hosted
+ * as a guest. On Hyper-V, the host implements a policy engine for dynamically
+ * balancing memory across competing virtual machines that are hosted.
+ * Several metrics drive this policy engine including the guest reported
+ * memory commitment.
+ */
+unsigned long vm_memory_committed(void)
+{
+ return percpu_counter_read_positive(&vm_committed_as);
+}
+
+EXPORT_SYMBOL_GPL(vm_memory_committed);
+
EXPORT_SYMBOL(mem_map);
EXPORT_SYMBOL(num_physpages);
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 79e0f3e2483..18f1ae2b45d 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -44,48 +44,6 @@ int sysctl_oom_kill_allocating_task;
int sysctl_oom_dump_tasks = 1;
static DEFINE_SPINLOCK(zone_scan_lock);
-/*
- * compare_swap_oom_score_adj() - compare and swap current's oom_score_adj
- * @old_val: old oom_score_adj for compare
- * @new_val: new oom_score_adj for swap
- *
- * Sets the oom_score_adj value for current to @new_val iff its present value is
- * @old_val. Usually used to reinstate a previous value to prevent racing with
- * userspacing tuning the value in the interim.
- */
-void compare_swap_oom_score_adj(int old_val, int new_val)
-{
- struct sighand_struct *sighand = current->sighand;
-
- spin_lock_irq(&sighand->siglock);
- if (current->signal->oom_score_adj == old_val)
- current->signal->oom_score_adj = new_val;
- trace_oom_score_adj_update(current);
- spin_unlock_irq(&sighand->siglock);
-}
-
-/**
- * test_set_oom_score_adj() - set current's oom_score_adj and return old value
- * @new_val: new oom_score_adj value
- *
- * Sets the oom_score_adj value for current to @new_val with proper
- * synchronization and returns the old value. Usually used to temporarily
- * set a value, save the old value in the caller, and then reinstate it later.
- */
-int test_set_oom_score_adj(int new_val)
-{
- struct sighand_struct *sighand = current->sighand;
- int old_val;
-
- spin_lock_irq(&sighand->siglock);
- old_val = current->signal->oom_score_adj;
- current->signal->oom_score_adj = new_val;
- trace_oom_score_adj_update(current);
- spin_unlock_irq(&sighand->siglock);
-
- return old_val;
-}
-
#ifdef CONFIG_NUMA
/**
* has_intersects_mems_allowed() - check task eligiblity for kill
@@ -193,7 +151,7 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg,
if (!p)
return 0;
- adj = p->signal->oom_score_adj;
+ adj = (long)p->signal->oom_score_adj;
if (adj == OOM_SCORE_ADJ_MIN) {
task_unlock(p);
return 0;
@@ -310,26 +268,20 @@ enum oom_scan_t oom_scan_process_thread(struct task_struct *task,
if (!task->mm)
return OOM_SCAN_CONTINUE;
- if (task->flags & PF_EXITING) {
+ /*
+ * If task is allocating a lot of memory and has been marked to be
+ * killed first if it triggers an oom, then select it.
+ */
+ if (oom_task_origin(task))
+ return OOM_SCAN_SELECT;
+
+ if (task->flags & PF_EXITING && !force_kill) {
/*
- * If task is current and is in the process of releasing memory,
- * allow the "kill" to set TIF_MEMDIE, which will allow it to
- * access memory reserves. Otherwise, it may stall forever.
- *
- * The iteration isn't broken here, however, in case other
- * threads are found to have already been oom killed.
+ * If this task is not being ptraced on exit, then wait for it
+ * to finish before killing some other task unnecessarily.
*/
- if (task == current)
- return OOM_SCAN_SELECT;
- else if (!force_kill) {
- /*
- * If this task is not being ptraced on exit, then wait
- * for it to finish before killing some other task
- * unnecessarily.
- */
- if (!(task->group_leader->ptrace & PT_TRACE_EXIT))
- return OOM_SCAN_ABORT;
- }
+ if (!(task->group_leader->ptrace & PT_TRACE_EXIT))
+ return OOM_SCAN_ABORT;
}
return OOM_SCAN_OK;
}
@@ -412,7 +364,7 @@ static void dump_tasks(const struct mem_cgroup *memcg, const nodemask_t *nodemas
continue;
}
- pr_info("[%5d] %5d %5d %8lu %8lu %7lu %8lu %5d %s\n",
+ pr_info("[%5d] %5d %5d %8lu %8lu %7lu %8lu %5hd %s\n",
task->pid, from_kuid(&init_user_ns, task_uid(task)),
task->tgid, task->mm->total_vm, get_mm_rss(task->mm),
task->mm->nr_ptes,
@@ -428,7 +380,7 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order,
{
task_lock(current);
pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, "
- "oom_score_adj=%d\n",
+ "oom_score_adj=%hd\n",
current->comm, gfp_mask, order,
current->signal->oom_score_adj);
cpuset_print_task_mems_allowed(current);
@@ -706,11 +658,11 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
return;
/*
- * If current has a pending SIGKILL, then automatically select it. The
- * goal is to allow it to allocate so that it may quickly exit and free
- * its memory.
+ * If current has a pending SIGKILL or is exiting, then automatically
+ * select it. The goal is to allow it to allocate so that it may
+ * quickly exit and free its memory.
*/
- if (fatal_signal_pending(current)) {
+ if (fatal_signal_pending(current) || current->flags & PF_EXITING) {
set_thread_flag(TIF_MEMDIE);
return;
}
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 830893b2b3c..6f427122449 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -1069,7 +1069,7 @@ static void bdi_update_bandwidth(struct backing_dev_info *bdi,
}
/*
- * After a task dirtied this many pages, balance_dirty_pages_ratelimited_nr()
+ * After a task dirtied this many pages, balance_dirty_pages_ratelimited()
* will look to see if it needs to start dirty throttling.
*
* If dirty_poll_interval is too low, big NUMA machines will call the expensive
@@ -1436,9 +1436,8 @@ static DEFINE_PER_CPU(int, bdp_ratelimits);
DEFINE_PER_CPU(int, dirty_throttle_leaks) = 0;
/**
- * balance_dirty_pages_ratelimited_nr - balance dirty memory state
+ * balance_dirty_pages_ratelimited - balance dirty memory state
* @mapping: address_space which was dirtied
- * @nr_pages_dirtied: number of pages which the caller has just dirtied
*
* Processes which are dirtying memory should call in here once for each page
* which was newly dirtied. The function will periodically check the system's
@@ -1449,8 +1448,7 @@ DEFINE_PER_CPU(int, dirty_throttle_leaks) = 0;
* limit we decrease the ratelimiting by a lot, to prevent individual processes
* from overshooting the limit by (ratelimit_pages) each.
*/
-void balance_dirty_pages_ratelimited_nr(struct address_space *mapping,
- unsigned long nr_pages_dirtied)
+void balance_dirty_pages_ratelimited(struct address_space *mapping)
{
struct backing_dev_info *bdi = mapping->backing_dev_info;
int ratelimit;
@@ -1484,6 +1482,7 @@ void balance_dirty_pages_ratelimited_nr(struct address_space *mapping,
*/
p = &__get_cpu_var(dirty_throttle_leaks);
if (*p > 0 && current->nr_dirtied < ratelimit) {
+ unsigned long nr_pages_dirtied;
nr_pages_dirtied = min(*p, ratelimit - current->nr_dirtied);
*p -= nr_pages_dirtied;
current->nr_dirtied += nr_pages_dirtied;
@@ -1493,7 +1492,7 @@ void balance_dirty_pages_ratelimited_nr(struct address_space *mapping,
if (unlikely(current->nr_dirtied >= ratelimit))
balance_dirty_pages(mapping, current->nr_dirtied);
}
-EXPORT_SYMBOL(balance_dirty_pages_ratelimited_nr);
+EXPORT_SYMBOL(balance_dirty_pages_ratelimited);
void throttle_vm_writeout(gfp_t gfp_mask)
{
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5b74de6702e..5a8d339d282 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -667,11 +667,13 @@ static void free_pcppages_bulk(struct zone *zone, int count,
/* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */
__free_one_page(page, zone, 0, mt);
trace_mm_page_pcpu_drain(page, 0, mt);
- if (is_migrate_cma(mt))
- __mod_zone_page_state(zone, NR_FREE_CMA_PAGES, 1);
+ if (likely(get_pageblock_migratetype(page) != MIGRATE_ISOLATE)) {
+ __mod_zone_page_state(zone, NR_FREE_PAGES, 1);
+ if (is_migrate_cma(mt))
+ __mod_zone_page_state(zone, NR_FREE_CMA_PAGES, 1);
+ }
} while (--to_free && --batch_free && !list_empty(list));
}
- __mod_zone_page_state(zone, NR_FREE_PAGES, count);
spin_unlock(&zone->lock);
}
@@ -1392,21 +1394,22 @@ int capture_free_page(struct page *page, int alloc_order, int migratetype)
zone = page_zone(page);
order = page_order(page);
+ mt = get_pageblock_migratetype(page);
- /* Obey watermarks as if the page was being allocated */
- watermark = low_wmark_pages(zone) + (1 << order);
- if (!zone_watermark_ok(zone, 0, watermark, 0, 0))
- return 0;
+ if (mt != MIGRATE_ISOLATE) {
+ /* Obey watermarks as if the page was being allocated */
+ watermark = low_wmark_pages(zone) + (1 << order);
+ if (!zone_watermark_ok(zone, 0, watermark, 0, 0))
+ return 0;
+
+ __mod_zone_freepage_state(zone, -(1UL << alloc_order), mt);
+ }
/* Remove page from free list */
list_del(&page->lru);
zone->free_area[order].nr_free--;
rmv_page_order(page);
- mt = get_pageblock_migratetype(page);
- if (unlikely(mt != MIGRATE_ISOLATE))
- __mod_zone_freepage_state(zone, -(1UL << order), mt);
-
if (alloc_order != order)
expand(zone, page, alloc_order, order,
&zone->free_area[order], migratetype);
@@ -1422,7 +1425,7 @@ int capture_free_page(struct page *page, int alloc_order, int migratetype)
}
}
- return 1UL << order;
+ return 1UL << alloc_order;
}
/*
@@ -1871,7 +1874,7 @@ zonelist_scan:
*/
for_each_zone_zonelist_nodemask(zone, z, zonelist,
high_zoneidx, nodemask) {
- if (NUMA_BUILD && zlc_active &&
+ if (IS_ENABLED(CONFIG_NUMA) && zlc_active &&
!zlc_zone_worth_trying(zonelist, z, allowednodes))
continue;
if ((alloc_flags & ALLOC_CPUSET) &&
@@ -1917,7 +1920,8 @@ zonelist_scan:
classzone_idx, alloc_flags))
goto try_this_zone;
- if (NUMA_BUILD && !did_zlc_setup && nr_online_nodes > 1) {
+ if (IS_ENABLED(CONFIG_NUMA) &&
+ !did_zlc_setup && nr_online_nodes > 1) {
/*
* we do zlc_setup if there are multiple nodes
* and before considering the first zone allowed
@@ -1936,7 +1940,7 @@ zonelist_scan:
* As we may have just activated ZLC, check if the first
* eligible zone has failed zone_reclaim recently.
*/
- if (NUMA_BUILD && zlc_active &&
+ if (IS_ENABLED(CONFIG_NUMA) && zlc_active &&
!zlc_zone_worth_trying(zonelist, z, allowednodes))
continue;
@@ -1962,11 +1966,11 @@ try_this_zone:
if (page)
break;
this_zone_full:
- if (NUMA_BUILD)
+ if (IS_ENABLED(CONFIG_NUMA))
zlc_mark_zone_full(zonelist, z);
}
- if (unlikely(NUMA_BUILD && page == NULL && zlc_active)) {
+ if (unlikely(IS_ENABLED(CONFIG_NUMA) && page == NULL && zlc_active)) {
/* Disable zlc cache for second zonelist scan */
zlc_active = 0;
goto zonelist_scan;
@@ -2266,7 +2270,7 @@ __alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order,
return NULL;
/* After successful reclaim, reconsider all zones for allocation */
- if (NUMA_BUILD)
+ if (IS_ENABLED(CONFIG_NUMA))
zlc_clear_zones_full(zonelist);
retry:
@@ -2412,12 +2416,14 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
* allowed per node queues are empty and that nodes are
* over allocated.
*/
- if (NUMA_BUILD && (gfp_mask & GFP_THISNODE) == GFP_THISNODE)
+ if (IS_ENABLED(CONFIG_NUMA) &&
+ (gfp_mask & GFP_THISNODE) == GFP_THISNODE)
goto nopage;
restart:
- wake_all_kswapd(order, zonelist, high_zoneidx,
- zone_idx(preferred_zone));
+ if (!(gfp_mask & __GFP_NO_KSWAPD))
+ wake_all_kswapd(order, zonelist, high_zoneidx,
+ zone_idx(preferred_zone));
/*
* OK, we're below the kswapd watermark and have kicked background
@@ -2494,7 +2500,7 @@ rebalance:
* system then fail the allocation instead of entering direct reclaim.
*/
if ((deferred_compaction || contended_compaction) &&
- (gfp_mask & (__GFP_MOVABLE|__GFP_REPEAT)) == __GFP_MOVABLE)
+ (gfp_mask & __GFP_NO_KSWAPD))
goto nopage;
/* Try direct reclaim and then allocating */
@@ -2818,7 +2824,7 @@ unsigned int nr_free_pagecache_pages(void)
static inline void show_node(struct zone *zone)
{
- if (NUMA_BUILD)
+ if (IS_ENABLED(CONFIG_NUMA))
printk("Node %d ", zone_to_nid(zone));
}
@@ -2876,6 +2882,31 @@ out:
#define K(x) ((x) << (PAGE_SHIFT-10))
+static void show_migration_types(unsigned char type)
+{
+ static const char types[MIGRATE_TYPES] = {
+ [MIGRATE_UNMOVABLE] = 'U',
+ [MIGRATE_RECLAIMABLE] = 'E',
+ [MIGRATE_MOVABLE] = 'M',
+ [MIGRATE_RESERVE] = 'R',
+#ifdef CONFIG_CMA
+ [MIGRATE_CMA] = 'C',
+#endif
+ [MIGRATE_ISOLATE] = 'I',
+ };
+ char tmp[MIGRATE_TYPES + 1];
+ char *p = tmp;
+ int i;
+
+ for (i = 0; i < MIGRATE_TYPES; i++) {
+ if (type & (1 << i))
+ *p++ = types[i];
+ }
+
+ *p = '\0';
+ printk("(%s) ", tmp);
+}
+
/*
* Show free area list (used inside shift_scroll-lock stuff)
* We also calculate the percentage fragmentation. We do this by counting the
@@ -3004,6 +3035,7 @@ void show_free_areas(unsigned int filter)
for_each_populated_zone(zone) {
unsigned long nr[MAX_ORDER], flags, order, total = 0;
+ unsigned char types[MAX_ORDER];
if (skip_free_areas_node(filter, zone_to_nid(zone)))
continue;
@@ -3012,12 +3044,24 @@ void show_free_areas(unsigned int filter)
spin_lock_irqsave(&zone->lock, flags);
for (order = 0; order < MAX_ORDER; order++) {
- nr[order] = zone->free_area[order].nr_free;
+ struct free_area *area = &zone->free_area[order];
+ int type;
+
+ nr[order] = area->nr_free;
total += nr[order] << order;
+
+ types[order] = 0;
+ for (type = 0; type < MIGRATE_TYPES; type++) {
+ if (!list_empty(&area->free_list[type]))
+ types[order] |= 1 << type;
+ }
}
spin_unlock_irqrestore(&zone->lock, flags);
- for (order = 0; order < MAX_ORDER; order++)
+ for (order = 0; order < MAX_ORDER; order++) {
printk("%lu*%lukB ", nr[order], K(1UL) << order);
+ if (nr[order])
+ show_migration_types(types[order]);
+ }
printk("= %lukB\n", K(total));
}
@@ -4505,7 +4549,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat,
zone->zone_pgdat = pgdat;
zone_pcp_init(zone);
- lruvec_init(&zone->lruvec, zone);
+ lruvec_init(&zone->lruvec);
if (!size)
continue;
@@ -5174,10 +5218,6 @@ static void __setup_per_zone_wmarks(void)
zone->watermark[WMARK_LOW] = min_wmark_pages(zone) + (tmp >> 2);
zone->watermark[WMARK_HIGH] = min_wmark_pages(zone) + (tmp >> 1);
- zone->watermark[WMARK_MIN] += cma_wmark_pages(zone);
- zone->watermark[WMARK_LOW] += cma_wmark_pages(zone);
- zone->watermark[WMARK_HIGH] += cma_wmark_pages(zone);
-
setup_zone_migrate_reserve(zone);
spin_unlock_irqrestore(&zone->lock, flags);
}
@@ -5575,7 +5615,8 @@ void set_pageblock_flags_group(struct page *page, unsigned long flags,
* MIGRATE_MOVABLE block might include unmovable pages. It means you can't
* expect this function should be exact.
*/
-bool has_unmovable_pages(struct zone *zone, struct page *page, int count)
+bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
+ bool skip_hwpoisoned_pages)
{
unsigned long pfn, iter, found;
int mt;
@@ -5610,6 +5651,13 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count)
continue;
}
+ /*
+ * The HWPoisoned page may be not in buddy system, and
+ * page_count() is not 0.
+ */
+ if (skip_hwpoisoned_pages && PageHWPoison(page))
+ continue;
+
if (!PageLRU(page))
found++;
/*
@@ -5652,7 +5700,7 @@ bool is_pageblock_removable_nolock(struct page *page)
zone->zone_start_pfn + zone->spanned_pages <= pfn)
return false;
- return !has_unmovable_pages(zone, page, 0);
+ return !has_unmovable_pages(zone, page, 0, true);
}
#ifdef CONFIG_CMA
@@ -5710,58 +5758,10 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
0, false, MIGRATE_SYNC);
}
- putback_lru_pages(&cc->migratepages);
+ putback_movable_pages(&cc->migratepages);
return ret > 0 ? 0 : ret;
}
-/*
- * Update zone's cma pages counter used for watermark level calculation.
- */
-static inline void __update_cma_watermarks(struct zone *zone, int count)
-{
- unsigned long flags;
- spin_lock_irqsave(&zone->lock, flags);
- zone->min_cma_pages += count;
- spin_unlock_irqrestore(&zone->lock, flags);
- setup_per_zone_wmarks();
-}
-
-/*
- * Trigger memory pressure bump to reclaim some pages in order to be able to
- * allocate 'count' pages in single page units. Does similar work as
- *__alloc_pages_slowpath() function.
- */
-static int __reclaim_pages(struct zone *zone, gfp_t gfp_mask, int count)
-{
- enum zone_type high_zoneidx = gfp_zone(gfp_mask);
- struct zonelist *zonelist = node_zonelist(0, gfp_mask);
- int did_some_progress = 0;
- int order = 1;
-
- /*
- * Increase level of watermarks to force kswapd do his job
- * to stabilise at new watermark level.
- */
- __update_cma_watermarks(zone, count);
-
- /* Obey watermarks as if the page was being allocated */
- while (!zone_watermark_ok(zone, 0, low_wmark_pages(zone), 0, 0)) {
- wake_all_kswapd(order, zonelist, high_zoneidx, zone_idx(zone));
-
- did_some_progress = __perform_reclaim(gfp_mask, order, zonelist,
- NULL);
- if (!did_some_progress) {
- /* Exhausted what can be done so it's blamo time */
- out_of_memory(zonelist, gfp_mask, order, NULL, false);
- }
- }
-
- /* Restore original watermark levels. */
- __update_cma_watermarks(zone, -count);
-
- return count;
-}
-
/**
* alloc_contig_range() -- tries to allocate given range of pages
* @start: start PFN to allocate
@@ -5785,7 +5785,6 @@ static int __reclaim_pages(struct zone *zone, gfp_t gfp_mask, int count)
int alloc_contig_range(unsigned long start, unsigned long end,
unsigned migratetype)
{
- struct zone *zone = page_zone(pfn_to_page(start));
unsigned long outer_start, outer_end;
int ret = 0, order;
@@ -5823,7 +5822,8 @@ int alloc_contig_range(unsigned long start, unsigned long end,
*/
ret = start_isolate_page_range(pfn_max_align_down(start),
- pfn_max_align_up(end), migratetype);
+ pfn_max_align_up(end), migratetype,
+ false);
if (ret)
return ret;
@@ -5862,18 +5862,13 @@ int alloc_contig_range(unsigned long start, unsigned long end,
}
/* Make sure the range is really isolated. */
- if (test_pages_isolated(outer_start, end)) {
+ if (test_pages_isolated(outer_start, end, false)) {
pr_warn("alloc_contig_range test_pages_isolated(%lx, %lx) failed\n",
outer_start, end);
ret = -EBUSY;
goto done;
}
- /*
- * Reclaim enough pages to make sure that contiguous allocation
- * will not starve the system.
- */
- __reclaim_pages(zone, GFP_HIGHUSER_MOVABLE, end-start);
/* Grab isolated pages from freelists. */
outer_end = isolate_freepages_range(&cc, outer_start, end);
@@ -5931,7 +5926,6 @@ void __meminit zone_pcp_update(struct zone *zone)
}
#endif
-#ifdef CONFIG_MEMORY_HOTREMOVE
void zone_pcp_reset(struct zone *zone)
{
unsigned long flags;
@@ -5951,6 +5945,7 @@ void zone_pcp_reset(struct zone *zone)
local_irq_restore(flags);
}
+#ifdef CONFIG_MEMORY_HOTREMOVE
/*
* All pages in the range must be isolated before calling this.
*/
@@ -5977,6 +5972,16 @@ __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn)
continue;
}
page = pfn_to_page(pfn);
+ /*
+ * The HWPoisoned page may be not in buddy system, and
+ * page_count() is not 0.
+ */
+ if (unlikely(!PageBuddy(page) && PageHWPoison(page))) {
+ pfn++;
+ SetPageReserved(page);
+ continue;
+ }
+
BUG_ON(page_count(page));
BUG_ON(!PageBuddy(page));
order = page_order(page);
@@ -5987,8 +5992,6 @@ __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn)
list_del(&page->lru);
rmv_page_order(page);
zone->free_area[order].nr_free--;
- __mod_zone_page_state(zone, NR_FREE_PAGES,
- - (1UL << order));
for (i = 0; i < (1 << order); i++)
SetPageReserved((page+i));
pfn += (1 << order);
@@ -6098,37 +6101,3 @@ void dump_page(struct page *page)
dump_page_flags(page->flags);
mem_cgroup_print_bad_page(page);
}
-
-/* reset zone->present_pages */
-void reset_zone_present_pages(void)
-{
- struct zone *z;
- int i, nid;
-
- for_each_node_state(nid, N_HIGH_MEMORY) {
- for (i = 0; i < MAX_NR_ZONES; i++) {
- z = NODE_DATA(nid)->node_zones + i;
- z->present_pages = 0;
- }
- }
-}
-
-/* calculate zone's present pages in buddy system */
-void fixup_zone_present_pages(int nid, unsigned long start_pfn,
- unsigned long end_pfn)
-{
- struct zone *z;
- unsigned long zone_start_pfn, zone_end_pfn;
- int i;
-
- for (i = 0; i < MAX_NR_ZONES; i++) {
- z = NODE_DATA(nid)->node_zones + i;
- zone_start_pfn = z->zone_start_pfn;
- zone_end_pfn = zone_start_pfn + z->spanned_pages;
-
- /* if the two regions intersect */
- if (!(zone_start_pfn >= end_pfn || zone_end_pfn <= start_pfn))
- z->present_pages += min(end_pfn, zone_end_pfn) -
- max(start_pfn, zone_start_pfn);
- }
-}
diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c
index 5ddad0c6daa..44db00e253e 100644
--- a/mm/page_cgroup.c
+++ b/mm/page_cgroup.c
@@ -251,6 +251,9 @@ static int __meminit page_cgroup_callback(struct notifier_block *self,
mn->nr_pages, mn->status_change_nid);
break;
case MEM_CANCEL_ONLINE:
+ offline_page_cgroup(mn->start_pfn,
+ mn->nr_pages, mn->status_change_nid);
+ break;
case MEM_GOING_OFFLINE:
break;
case MEM_ONLINE:
diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index f2f5b4818e9..9d2264ea460 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -30,7 +30,7 @@ static void restore_pageblock_isolate(struct page *page, int migratetype)
zone->nr_pageblock_isolate--;
}
-int set_migratetype_isolate(struct page *page)
+int set_migratetype_isolate(struct page *page, bool skip_hwpoisoned_pages)
{
struct zone *zone;
unsigned long flags, pfn;
@@ -66,7 +66,8 @@ int set_migratetype_isolate(struct page *page)
* FIXME: Now, memory hotplug doesn't call shrink_slab() by itself.
* We just check MOVABLE pages.
*/
- if (!has_unmovable_pages(zone, page, arg.pages_found))
+ if (!has_unmovable_pages(zone, page, arg.pages_found,
+ skip_hwpoisoned_pages))
ret = 0;
/*
@@ -134,7 +135,7 @@ __first_valid_page(unsigned long pfn, unsigned long nr_pages)
* Returns 0 on success and -EBUSY if any part of range cannot be isolated.
*/
int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
- unsigned migratetype)
+ unsigned migratetype, bool skip_hwpoisoned_pages)
{
unsigned long pfn;
unsigned long undo_pfn;
@@ -147,7 +148,8 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
pfn < end_pfn;
pfn += pageblock_nr_pages) {
page = __first_valid_page(pfn, pageblock_nr_pages);
- if (page && set_migratetype_isolate(page)) {
+ if (page &&
+ set_migratetype_isolate(page, skip_hwpoisoned_pages)) {
undo_pfn = pfn;
goto undo;
}
@@ -190,7 +192,8 @@ int undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
* Returns 1 if all pages in the range are isolated.
*/
static int
-__test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn)
+__test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn,
+ bool skip_hwpoisoned_pages)
{
struct page *page;
@@ -220,6 +223,14 @@ __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn)
else if (page_count(page) == 0 &&
get_freepage_migratetype(page) == MIGRATE_ISOLATE)
pfn += 1;
+ else if (skip_hwpoisoned_pages && PageHWPoison(page)) {
+ /*
+ * The HWPoisoned page may be not in buddy
+ * system, and page_count() is not 0.
+ */
+ pfn++;
+ continue;
+ }
else
break;
}
@@ -228,7 +239,8 @@ __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn)
return 1;
}
-int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
+int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn,
+ bool skip_hwpoisoned_pages)
{
unsigned long pfn, flags;
struct page *page;
@@ -251,7 +263,8 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
/* Check all pages are free or Marked as ISOLATED */
zone = page_zone(page);
spin_lock_irqsave(&zone->lock, flags);
- ret = __test_page_isolated_in_pageblock(start_pfn, end_pfn);
+ ret = __test_page_isolated_in_pageblock(start_pfn, end_pfn,
+ skip_hwpoisoned_pages);
spin_unlock_irqrestore(&zone->lock, flags);
return ret ? 0 : -EBUSY;
}
diff --git a/mm/rmap.c b/mm/rmap.c
index 2ee1ef0f317..cf7e99a87c3 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -562,6 +562,27 @@ unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
return address;
}
+pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd = NULL;
+
+ pgd = pgd_offset(mm, address);
+ if (!pgd_present(*pgd))
+ goto out;
+
+ pud = pud_offset(pgd, address);
+ if (!pud_present(*pud))
+ goto out;
+
+ pmd = pmd_offset(pud, address);
+ if (!pmd_present(*pmd))
+ pmd = NULL;
+out:
+ return pmd;
+}
+
/*
* Check that @page is mapped at @address into @mm.
*
@@ -574,8 +595,6 @@ unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
pte_t *__page_check_address(struct page *page, struct mm_struct *mm,
unsigned long address, spinlock_t **ptlp, int sync)
{
- pgd_t *pgd;
- pud_t *pud;
pmd_t *pmd;
pte_t *pte;
spinlock_t *ptl;
@@ -586,17 +605,10 @@ pte_t *__page_check_address(struct page *page, struct mm_struct *mm,
goto check;
}
- pgd = pgd_offset(mm, address);
- if (!pgd_present(*pgd))
- return NULL;
-
- pud = pud_offset(pgd, address);
- if (!pud_present(*pud))
+ pmd = mm_find_pmd(mm, address);
+ if (!pmd)
return NULL;
- pmd = pmd_offset(pud, address);
- if (!pmd_present(*pmd))
- return NULL;
if (pmd_trans_huge(*pmd))
return NULL;
@@ -1139,9 +1151,11 @@ void page_remove_rmap(struct page *page)
* containing the swap entry, but page not yet written to swap.
*
* And we can skip it on file pages, so long as the filesystem
- * participates in dirty tracking; but need to catch shm and tmpfs
- * and ramfs pages which have been modified since creation by read
- * fault.
+ * participates in dirty tracking (note that this is not only an
+ * optimization but also solves problems caused by dirty flag in
+ * storage key getting set by a write from inside kernel); but need to
+ * catch shm and tmpfs and ramfs pages which have been modified since
+ * creation by read fault.
*
* Note that mapping must be decided above, before decrementing
* mapcount (which luckily provides a barrier): once page is unmapped,
@@ -1345,8 +1359,6 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount,
struct vm_area_struct *vma, struct page *check_page)
{
struct mm_struct *mm = vma->vm_mm;
- pgd_t *pgd;
- pud_t *pud;
pmd_t *pmd;
pte_t *pte;
pte_t pteval;
@@ -1366,16 +1378,8 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount,
if (end > vma->vm_end)
end = vma->vm_end;
- pgd = pgd_offset(mm, address);
- if (!pgd_present(*pgd))
- return ret;
-
- pud = pud_offset(pgd, address);
- if (!pud_present(*pud))
- return ret;
-
- pmd = pmd_offset(pud, address);
- if (!pmd_present(*pmd))
+ pmd = mm_find_pmd(mm, address);
+ if (!pmd)
return ret;
mmun_start = address;
diff --git a/mm/shmem.c b/mm/shmem.c
index 67afba5117f..50c5b8f3a35 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -643,7 +643,7 @@ static void shmem_evict_inode(struct inode *inode)
kfree(info->symlink);
simple_xattrs_free(&info->xattrs);
- BUG_ON(inode->i_blocks);
+ WARN_ON(inode->i_blocks);
shmem_free_inode(inode->i_sb);
clear_inode(inode);
}
@@ -910,25 +910,29 @@ static struct mempolicy *shmem_get_sbmpol(struct shmem_sb_info *sbinfo)
static struct page *shmem_swapin(swp_entry_t swap, gfp_t gfp,
struct shmem_inode_info *info, pgoff_t index)
{
- struct mempolicy mpol, *spol;
struct vm_area_struct pvma;
-
- spol = mpol_cond_copy(&mpol,
- mpol_shared_policy_lookup(&info->policy, index));
+ struct page *page;
/* Create a pseudo vma that just contains the policy */
pvma.vm_start = 0;
/* Bias interleave by inode number to distribute better across nodes */
pvma.vm_pgoff = index + info->vfs_inode.i_ino;
pvma.vm_ops = NULL;
- pvma.vm_policy = spol;
- return swapin_readahead(swap, gfp, &pvma, 0);
+ pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, index);
+
+ page = swapin_readahead(swap, gfp, &pvma, 0);
+
+ /* Drop reference taken by mpol_shared_policy_lookup() */
+ mpol_cond_put(pvma.vm_policy);
+
+ return page;
}
static struct page *shmem_alloc_page(gfp_t gfp,
struct shmem_inode_info *info, pgoff_t index)
{
struct vm_area_struct pvma;
+ struct page *page;
/* Create a pseudo vma that just contains the policy */
pvma.vm_start = 0;
@@ -937,10 +941,12 @@ static struct page *shmem_alloc_page(gfp_t gfp,
pvma.vm_ops = NULL;
pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, index);
- /*
- * alloc_page_vma() will drop the shared policy reference
- */
- return alloc_page_vma(gfp, &pvma, 0);
+ page = alloc_page_vma(gfp, &pvma, 0);
+
+ /* Drop reference taken by mpol_shared_policy_lookup() */
+ mpol_cond_put(pvma.vm_policy);
+
+ return page;
}
#else /* !CONFIG_NUMA */
#ifdef CONFIG_TMPFS
@@ -1145,8 +1151,20 @@ repeat:
if (!error) {
error = shmem_add_to_page_cache(page, mapping, index,
gfp, swp_to_radix_entry(swap));
- /* We already confirmed swap, and make no allocation */
- VM_BUG_ON(error);
+ /*
+ * We already confirmed swap under page lock, and make
+ * no memory allocation here, so usually no possibility
+ * of error; but free_swap_and_cache() only trylocks a
+ * page, so it is just possible that the entry has been
+ * truncated or holepunched since swap was confirmed.
+ * shmem_undo_range() will have done some of the
+ * unaccounting, now delete_from_swap_cache() will do
+ * the rest (including mem_cgroup_uncharge_swapcache).
+ * Reset swap.val? No, leave it so "failed" goes back to
+ * "repeat": reading a hole and writing should succeed.
+ */
+ if (error)
+ delete_from_swap_cache(page);
}
if (error)
goto failed;
diff --git a/mm/slub.c b/mm/slub.c
index a0d698467f7..487f0bdd53c 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3573,7 +3573,7 @@ static void slab_mem_offline_callback(void *arg)
struct memory_notify *marg = arg;
int offline_node;
- offline_node = marg->status_change_nid;
+ offline_node = marg->status_change_nid_normal;
/*
* If the node still has available memory. we need kmem_cache_node
@@ -3606,7 +3606,7 @@ static int slab_mem_going_online_callback(void *arg)
struct kmem_cache_node *n;
struct kmem_cache *s;
struct memory_notify *marg = arg;
- int nid = marg->status_change_nid;
+ int nid = marg->status_change_nid_normal;
int ret = 0;
/*
diff --git a/mm/sparse.c b/mm/sparse.c
index fac95f2888f..6b5fb762e2c 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -617,7 +617,7 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
{
return; /* XXX: Not implemented yet */
}
-static void free_map_bootmem(struct page *page, unsigned long nr_pages)
+static void free_map_bootmem(struct page *memmap, unsigned long nr_pages)
{
}
#else
@@ -638,7 +638,6 @@ static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
got_map_page:
ret = (struct page *)pfn_to_kaddr(page_to_pfn(page));
got_map_ptr:
- memset(ret, 0, memmap_size);
return ret;
}
@@ -658,10 +657,11 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
get_order(sizeof(struct page) * nr_pages));
}
-static void free_map_bootmem(struct page *page, unsigned long nr_pages)
+static void free_map_bootmem(struct page *memmap, unsigned long nr_pages)
{
unsigned long maps_section_nr, removing_section_nr, i;
unsigned long magic;
+ struct page *page = virt_to_page(memmap);
for (i = 0; i < nr_pages; i++, page++) {
magic = (unsigned long) page->lru.next;
@@ -710,13 +710,10 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap)
*/
if (memmap) {
- struct page *memmap_page;
- memmap_page = virt_to_page(memmap);
-
nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page))
>> PAGE_SHIFT;
- free_map_bootmem(memmap_page, nr_pages);
+ free_map_bootmem(memmap, nr_pages);
}
}
@@ -760,6 +757,8 @@ int __meminit sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
goto out;
}
+ memset(memmap, 0, sizeof(struct page) * nr_pages);
+
ms->section_mem_map |= SECTION_MARKED_PRESENT;
ret = sparse_init_one_section(ms, section_nr, memmap, usemap);
@@ -773,6 +772,27 @@ out:
return ret;
}
+#ifdef CONFIG_MEMORY_FAILURE
+static void clear_hwpoisoned_pages(struct page *memmap, int nr_pages)
+{
+ int i;
+
+ if (!memmap)
+ return;
+
+ for (i = 0; i < PAGES_PER_SECTION; i++) {
+ if (PageHWPoison(&memmap[i])) {
+ atomic_long_sub(1, &mce_bad_pages);
+ ClearPageHWPoison(&memmap[i]);
+ }
+ }
+}
+#else
+static inline void clear_hwpoisoned_pages(struct page *memmap, int nr_pages)
+{
+}
+#endif
+
void sparse_remove_one_section(struct zone *zone, struct mem_section *ms)
{
struct page *memmap = NULL;
@@ -786,6 +806,7 @@ void sparse_remove_one_section(struct zone *zone, struct mem_section *ms)
ms->pageblock_flags = NULL;
}
+ clear_hwpoisoned_pages(memmap, PAGES_PER_SECTION);
free_section_usemap(memmap, usemap);
}
#endif
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 71cd288b200..e97a0e5aea9 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1443,13 +1443,12 @@ static int setup_swap_extents(struct swap_info_struct *sis, sector_t *span)
return generic_swapfile_activate(sis, swap_file, span);
}
-static void enable_swap_info(struct swap_info_struct *p, int prio,
+static void _enable_swap_info(struct swap_info_struct *p, int prio,
unsigned char *swap_map,
unsigned long *frontswap_map)
{
int i, prev;
- spin_lock(&swap_lock);
if (prio >= 0)
p->prio = prio;
else
@@ -1472,10 +1471,25 @@ static void enable_swap_info(struct swap_info_struct *p, int prio,
swap_list.head = swap_list.next = p->type;
else
swap_info[prev]->next = p->type;
+}
+
+static void enable_swap_info(struct swap_info_struct *p, int prio,
+ unsigned char *swap_map,
+ unsigned long *frontswap_map)
+{
+ spin_lock(&swap_lock);
+ _enable_swap_info(p, prio, swap_map, frontswap_map);
frontswap_init(p->type);
spin_unlock(&swap_lock);
}
+static void reinsert_swap_info(struct swap_info_struct *p)
+{
+ spin_lock(&swap_lock);
+ _enable_swap_info(p, p->prio, p->swap_map, frontswap_map_get(p));
+ spin_unlock(&swap_lock);
+}
+
SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
{
struct swap_info_struct *p = NULL;
@@ -1484,7 +1498,6 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
struct address_space *mapping;
struct inode *inode;
struct filename *pathname;
- int oom_score_adj;
int i, type, prev;
int err;
@@ -1494,9 +1507,8 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
BUG_ON(!current->mm);
pathname = getname(specialfile);
- err = PTR_ERR(pathname);
if (IS_ERR(pathname))
- goto out;
+ return PTR_ERR(pathname);
victim = file_open_name(pathname, O_RDWR|O_LARGEFILE, 0);
err = PTR_ERR(victim);
@@ -1544,19 +1556,13 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
p->flags &= ~SWP_WRITEOK;
spin_unlock(&swap_lock);
- oom_score_adj = test_set_oom_score_adj(OOM_SCORE_ADJ_MAX);
+ set_current_oom_origin();
err = try_to_unuse(type, false, 0); /* force all pages to be unused */
- compare_swap_oom_score_adj(OOM_SCORE_ADJ_MAX, oom_score_adj);
+ clear_current_oom_origin();
if (err) {
- /*
- * reading p->prio and p->swap_map outside the lock is
- * safe here because only sys_swapon and sys_swapoff
- * change them, and there can be no other sys_swapon or
- * sys_swapoff for this swap_info_struct at this point.
- */
/* re-insert swap space back into swap_list */
- enable_swap_info(p, p->prio, p->swap_map, frontswap_map_get(p));
+ reinsert_swap_info(p);
goto out_dput;
}
@@ -1608,6 +1614,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
out_dput:
filp_close(victim, NULL);
out:
+ putname(pathname);
return err;
}
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 78e08300db2..5123a169ab7 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2550,7 +2550,7 @@ static void s_stop(struct seq_file *m, void *p)
static void show_numa_info(struct seq_file *m, struct vm_struct *v)
{
- if (NUMA_BUILD) {
+ if (IS_ENABLED(CONFIG_NUMA)) {
unsigned int nr, *counters = m->private;
if (!counters)
@@ -2615,7 +2615,7 @@ static int vmalloc_open(struct inode *inode, struct file *file)
unsigned int *ptr = NULL;
int ret;
- if (NUMA_BUILD) {
+ if (IS_ENABLED(CONFIG_NUMA)) {
ptr = kmalloc(nr_node_ids * sizeof(unsigned int), GFP_KERNEL);
if (ptr == NULL)
return -ENOMEM;
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 8b055e9379b..157bb116dec 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1679,13 +1679,24 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc,
if (global_reclaim(sc)) {
free = zone_page_state(zone, NR_FREE_PAGES);
- /* If we have very few page cache pages,
- force-scan anon pages. */
if (unlikely(file + free <= high_wmark_pages(zone))) {
+ /*
+ * If we have very few page cache pages, force-scan
+ * anon pages.
+ */
fraction[0] = 1;
fraction[1] = 0;
denominator = 1;
goto out;
+ } else if (!inactive_file_is_low_global(zone)) {
+ /*
+ * There is enough inactive page cache, do not
+ * reclaim anything from the working set right now.
+ */
+ fraction[0] = 0;
+ fraction[1] = 1;
+ denominator = 1;
+ goto out;
}
}
@@ -1752,7 +1763,7 @@ out:
/* Use reclaim/compaction for costly allocs or under memory pressure */
static bool in_reclaim_compaction(struct scan_control *sc)
{
- if (COMPACTION_BUILD && sc->order &&
+ if (IS_ENABLED(CONFIG_COMPACTION) && sc->order &&
(sc->order > PAGE_ALLOC_COSTLY_ORDER ||
sc->priority < DEF_PRIORITY - 2))
return true;
@@ -1760,28 +1771,6 @@ static bool in_reclaim_compaction(struct scan_control *sc)
return false;
}
-#ifdef CONFIG_COMPACTION
-/*
- * If compaction is deferred for sc->order then scale the number of pages
- * reclaimed based on the number of consecutive allocation failures
- */
-static unsigned long scale_for_compaction(unsigned long pages_for_compaction,
- struct lruvec *lruvec, struct scan_control *sc)
-{
- struct zone *zone = lruvec_zone(lruvec);
-
- if (zone->compact_order_failed <= sc->order)
- pages_for_compaction <<= zone->compact_defer_shift;
- return pages_for_compaction;
-}
-#else
-static unsigned long scale_for_compaction(unsigned long pages_for_compaction,
- struct lruvec *lruvec, struct scan_control *sc)
-{
- return pages_for_compaction;
-}
-#endif
-
/*
* Reclaim/compaction is used for high-order allocation requests. It reclaims
* order-0 pages before compacting the zone. should_continue_reclaim() returns
@@ -1829,9 +1818,6 @@ static inline bool should_continue_reclaim(struct lruvec *lruvec,
* inactive lists are large enough, continue reclaiming
*/
pages_for_compaction = (2UL << sc->order);
-
- pages_for_compaction = scale_for_compaction(pages_for_compaction,
- lruvec, sc);
inactive_lru_pages = get_lru_size(lruvec, LRU_INACTIVE_FILE);
if (nr_swap_pages > 0)
inactive_lru_pages += get_lru_size(lruvec, LRU_INACTIVE_ANON);
@@ -2030,7 +2016,7 @@ static bool shrink_zones(struct zonelist *zonelist, struct scan_control *sc)
if (zone->all_unreclaimable &&
sc->priority != DEF_PRIORITY)
continue; /* Let kswapd poll it */
- if (COMPACTION_BUILD) {
+ if (IS_ENABLED(CONFIG_COMPACTION)) {
/*
* If we already have plenty of memory free for
* compaction in this zone, don't free any more.
@@ -2232,9 +2218,12 @@ static bool pfmemalloc_watermark_ok(pg_data_t *pgdat)
* Throttle direct reclaimers if backing storage is backed by the network
* and the PFMEMALLOC reserve for the preferred node is getting dangerously
* depleted. kswapd will continue to make progress and wake the processes
- * when the low watermark is reached
+ * when the low watermark is reached.
+ *
+ * Returns true if a fatal signal was delivered during throttling. If this
+ * happens, the page allocator should not consider triggering the OOM killer.
*/
-static void throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
+static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
nodemask_t *nodemask)
{
struct zone *zone;
@@ -2249,13 +2238,20 @@ static void throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
* processes to block on log_wait_commit().
*/
if (current->flags & PF_KTHREAD)
- return;
+ goto out;
+
+ /*
+ * If a fatal signal is pending, this process should not throttle.
+ * It should return quickly so it can exit and free its memory
+ */
+ if (fatal_signal_pending(current))
+ goto out;
/* Check if the pfmemalloc reserves are ok */
first_zones_zonelist(zonelist, high_zoneidx, NULL, &zone);
pgdat = zone->zone_pgdat;
if (pfmemalloc_watermark_ok(pgdat))
- return;
+ goto out;
/* Account for the throttling */
count_vm_event(PGSCAN_DIRECT_THROTTLE);
@@ -2271,12 +2267,20 @@ static void throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
if (!(gfp_mask & __GFP_FS)) {
wait_event_interruptible_timeout(pgdat->pfmemalloc_wait,
pfmemalloc_watermark_ok(pgdat), HZ);
- return;
+
+ goto check_pending;
}
/* Throttle until kswapd wakes the process */
wait_event_killable(zone->zone_pgdat->pfmemalloc_wait,
pfmemalloc_watermark_ok(pgdat));
+
+check_pending:
+ if (fatal_signal_pending(current))
+ return true;
+
+out:
+ return false;
}
unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
@@ -2298,13 +2302,12 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
.gfp_mask = sc.gfp_mask,
};
- throttle_direct_reclaim(gfp_mask, zonelist, nodemask);
-
/*
- * Do not enter reclaim if fatal signal is pending. 1 is returned so
- * that the page allocator does not consider triggering OOM
+ * Do not enter reclaim if fatal signal was delivered while throttled.
+ * 1 is returned so that the page allocator does not OOM kill at this
+ * point.
*/
- if (fatal_signal_pending(current))
+ if (throttle_direct_reclaim(gfp_mask, zonelist, nodemask))
return 1;
trace_mm_vmscan_direct_reclaim_begin(order,
@@ -2422,6 +2425,20 @@ static void age_active_anon(struct zone *zone, struct scan_control *sc)
} while (memcg);
}
+static bool zone_balanced(struct zone *zone, int order,
+ unsigned long balance_gap, int classzone_idx)
+{
+ if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone) +
+ balance_gap, classzone_idx, 0))
+ return false;
+
+ if (IS_ENABLED(CONFIG_COMPACTION) && order &&
+ !compaction_suitable(zone, order))
+ return false;
+
+ return true;
+}
+
/*
* pgdat_balanced is used when checking if a node is balanced for high-order
* allocations. Only zones that meet watermarks and are in a zone allowed
@@ -2500,8 +2517,7 @@ static bool prepare_kswapd_sleep(pg_data_t *pgdat, int order, long remaining,
continue;
}
- if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone),
- i, 0))
+ if (!zone_balanced(zone, order, 0, i))
all_zones_ok = false;
else
balanced += zone->present_pages;
@@ -2610,8 +2626,7 @@ loop_again:
break;
}
- if (!zone_watermark_ok_safe(zone, order,
- high_wmark_pages(zone), 0, 0)) {
+ if (!zone_balanced(zone, order, 0, 0)) {
end_zone = i;
break;
} else {
@@ -2681,15 +2696,14 @@ loop_again:
* Do not reclaim more than needed for compaction.
*/
testorder = order;
- if (COMPACTION_BUILD && order &&
+ if (IS_ENABLED(CONFIG_COMPACTION) && order &&
compaction_suitable(zone, order) !=
COMPACT_SKIPPED)
testorder = 0;
if ((buffer_heads_over_limit && is_highmem_idx(i)) ||
- !zone_watermark_ok_safe(zone, testorder,
- high_wmark_pages(zone) + balance_gap,
- end_zone, 0)) {
+ !zone_balanced(zone, testorder,
+ balance_gap, end_zone)) {
shrink_zone(zone, &sc);
reclaim_state->reclaimed_slab = 0;
@@ -2716,8 +2730,7 @@ loop_again:
continue;
}
- if (!zone_watermark_ok_safe(zone, testorder,
- high_wmark_pages(zone), end_zone, 0)) {
+ if (!zone_balanced(zone, testorder, 0, end_zone)) {
all_zones_ok = 0;
/*
* We are still under min water mark. This
@@ -2822,29 +2835,10 @@ out:
if (!populated_zone(zone))
continue;
- if (zone->all_unreclaimable &&
- sc.priority != DEF_PRIORITY)
- continue;
-
- /* Would compaction fail due to lack of free memory? */
- if (COMPACTION_BUILD &&
- compaction_suitable(zone, order) == COMPACT_SKIPPED)
- goto loop_again;
-
- /* Confirm the zone is balanced for order-0 */
- if (!zone_watermark_ok(zone, 0,
- high_wmark_pages(zone), 0, 0)) {
- order = sc.order = 0;
- goto loop_again;
- }
-
/* Check if the memory needs to be defragmented. */
if (zone_watermark_ok(zone, order,
low_wmark_pages(zone), *classzone_idx, 0))
zones_need_compaction = 0;
-
- /* If balanced, clear the congested flag */
- zone_clear_flag(zone, ZONE_CONGESTED);
}
if (zones_need_compaction)
@@ -2969,7 +2963,7 @@ static int kswapd(void *p)
classzone_idx = new_classzone_idx = pgdat->nr_zones - 1;
balanced_classzone_idx = classzone_idx;
for ( ; ; ) {
- int ret;
+ bool ret;
/*
* If the last balance_pgdat was unsuccessful it's unlikely a
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index b9a28d2dd3e..ce0684a1fc8 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -325,6 +325,12 @@ void batadv_interface_rx(struct net_device *soft_iface,
soft_iface->last_rx = jiffies;
+ /* Let the bridge loop avoidance check the packet. If will
+ * not handle it, we can safely push it up.
+ */
+ if (batadv_bla_rx(bat_priv, skb, vid, is_bcast))
+ goto out;
+
if (orig_node)
batadv_tt_add_temporary_global_entry(bat_priv, orig_node,
ethhdr->h_source);
@@ -332,12 +338,6 @@ void batadv_interface_rx(struct net_device *soft_iface,
if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest))
goto dropped;
- /* Let the bridge loop avoidance check the packet. If will
- * not handle it, we can safely push it up.
- */
- if (batadv_bla_rx(bat_priv, skb, vid, is_bcast))
- goto out;
-
netif_rx(skb);
goto out;
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 112edd371b2..baae7158580 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -769,6 +769,12 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
*/
tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP;
+ /* the change can carry possible "attribute" flags like the
+ * TT_CLIENT_WIFI, therefore they have to be copied in the
+ * client entry
+ */
+ tt_global_entry->common.flags |= flags;
+
/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
* one originator left in the list and we previously received a
* delete + roaming change for this originator.
@@ -1496,7 +1502,7 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
memcpy(tt_change->addr, tt_common_entry->addr,
ETH_ALEN);
- tt_change->flags = BATADV_NO_FLAGS;
+ tt_change->flags = tt_common_entry->flags;
tt_count++;
tt_change++;
@@ -2450,6 +2456,13 @@ bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
{
bool ret = false;
+ /* if the originator is a backbone node (meaning it belongs to the same
+ * LAN of this node) the temporary client must not be added because to
+ * reach such destination the node must use the LAN instead of the mesh
+ */
+ if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
+ goto out;
+
if (!batadv_tt_global_add(bat_priv, orig_node, addr,
BATADV_TT_CLIENT_TEMP,
atomic_read(&orig_node->last_ttvn)))
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8a0ce706aeb..a0a2f97b9c6 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1754,11 +1754,11 @@ int hci_register_dev(struct hci_dev *hdev)
if (hdev->dev_type != HCI_AMP)
set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
- schedule_work(&hdev->power_on);
-
hci_notify(hdev, HCI_DEV_REG);
hci_dev_hold(hdev);
+ schedule_work(&hdev->power_on);
+
return id;
err_wqueue:
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index aa2ea0a8142..91de4239da6 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -326,7 +326,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
struct hci_dev *d;
size_t rp_len;
u16 count;
- int i, err;
+ int err;
BT_DBG("sock %p", sk);
@@ -347,9 +347,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
return -ENOMEM;
}
- rp->num_controllers = cpu_to_le16(count);
-
- i = 0;
+ count = 0;
list_for_each_entry(d, &hci_dev_list, list) {
if (test_bit(HCI_SETUP, &d->dev_flags))
continue;
@@ -357,10 +355,13 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
if (!mgmt_valid_hdev(d))
continue;
- rp->index[i++] = cpu_to_le16(d->id);
+ rp->index[count++] = cpu_to_le16(d->id);
BT_DBG("Added hci%u", d->id);
}
+ rp->num_controllers = cpu_to_le16(count);
+ rp_len = sizeof(*rp) + (2 * count);
+
read_unlock(&hci_dev_list_lock);
err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp,
@@ -1366,6 +1367,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
continue;
list_del(&match->list);
+ kfree(match);
found++;
}
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 2ac8d50861e..a5923378bdf 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -267,7 +267,7 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags);
mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type,
- hcon->dst_type, reason);
+ hcon->dst_type, HCI_ERROR_AUTH_FAILURE);
cancel_delayed_work_sync(&conn->security_timer);
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 6f747582718..969b7cdff59 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -1084,6 +1084,9 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
op->sk = sk;
op->ifindex = ifindex;
+ /* ifindex for timeout events w/o previous frame reception */
+ op->rx_ifindex = ifindex;
+
/* initialize uninitialized (kzalloc) structure */
hrtimer_init(&op->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
op->timer.function = bcm_rx_timeout_handler;
diff --git a/net/core/dev.c b/net/core/dev.c
index bda6d004f9f..e5942bf45a6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2818,8 +2818,10 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
if (unlikely(tcpu != next_cpu) &&
(tcpu == RPS_NO_CPU || !cpu_online(tcpu) ||
((int)(per_cpu(softnet_data, tcpu).input_queue_head -
- rflow->last_qtail)) >= 0))
+ rflow->last_qtail)) >= 0)) {
+ tcpu = next_cpu;
rflow = set_rps_cpu(dev, skb, rflow, next_cpu);
+ }
if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) {
*rflowp = rflow;
@@ -3449,6 +3451,8 @@ static int napi_gro_complete(struct sk_buff *skb)
struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK];
int err = -ENOENT;
+ BUILD_BUG_ON(sizeof(struct napi_gro_cb) > sizeof(skb->cb));
+
if (NAPI_GRO_CB(skb)->count == 1) {
skb_shinfo(skb)->gso_size = 0;
goto out;
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index 87cc17db2d5..b079c7bbc15 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -319,7 +319,8 @@ int dev_addr_del(struct net_device *dev, const unsigned char *addr,
*/
ha = list_first_entry(&dev->dev_addrs.list,
struct netdev_hw_addr, list);
- if (ha->addr == dev->dev_addr && ha->refcount == 1)
+ if (!memcmp(ha->addr, addr, dev->addr_len) &&
+ ha->type == addr_type && ha->refcount == 1)
return -ENOENT;
err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len,
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index bcf02f608cb..017a8bacfb2 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -429,6 +429,17 @@ static struct attribute_group netstat_group = {
.name = "statistics",
.attrs = netstat_attrs,
};
+
+#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211)
+static struct attribute *wireless_attrs[] = {
+ NULL
+};
+
+static struct attribute_group wireless_group = {
+ .name = "wireless",
+ .attrs = wireless_attrs,
+};
+#endif
#endif /* CONFIG_SYSFS */
#ifdef CONFIG_RPS
@@ -1409,6 +1420,15 @@ int netdev_register_kobject(struct net_device *net)
groups++;
*groups++ = &netstat_group;
+
+#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211)
+ if (net->ieee80211_ptr)
+ *groups++ = &wireless_group;
+#if IS_ENABLED(CONFIG_WIRELESS_EXT)
+ else if (net->wireless_handlers)
+ *groups++ = &wireless_group;
+#endif
+#endif
#endif /* CONFIG_SYSFS */
error = device_add(dev);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 4007c1437fd..3f0636cd76c 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3004,7 +3004,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
skb_shinfo(nskb)->gso_size = pinfo->gso_size;
pinfo->gso_size = 0;
skb_header_release(p);
- nskb->prev = p;
+ NAPI_GRO_CB(nskb)->last = p;
nskb->data_len += p->len;
nskb->truesize += p->truesize;
@@ -3030,8 +3030,8 @@ merge:
__skb_pull(skb, offset);
- p->prev->next = skb;
- p->prev = skb;
+ NAPI_GRO_CB(p)->last->next = skb;
+ NAPI_GRO_CB(p)->last = skb;
skb_header_release(skb);
done:
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index f2eccd53174..17ff9fd7cdd 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -257,7 +257,8 @@ static inline bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt,
struct inet_peer *peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, 1);
rc = inet_peer_xrlim_allow(peer,
net->ipv4.sysctl_icmp_ratelimit);
- inet_putpeer(peer);
+ if (peer)
+ inet_putpeer(peer);
}
out:
return rc;
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 0c34bfabc11..e23e16dc501 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -44,6 +44,10 @@ struct inet_diag_entry {
u16 dport;
u16 family;
u16 userlocks;
+#if IS_ENABLED(CONFIG_IPV6)
+ struct in6_addr saddr_storage; /* for IPv4-mapped-IPv6 addresses */
+ struct in6_addr daddr_storage; /* for IPv4-mapped-IPv6 addresses */
+#endif
};
static DEFINE_MUTEX(inet_diag_table_mutex);
@@ -428,25 +432,31 @@ static int inet_diag_bc_run(const struct nlattr *_bc,
break;
}
- if (cond->prefix_len == 0)
- break;
-
if (op->code == INET_DIAG_BC_S_COND)
addr = entry->saddr;
else
addr = entry->daddr;
+ if (cond->family != AF_UNSPEC &&
+ cond->family != entry->family) {
+ if (entry->family == AF_INET6 &&
+ cond->family == AF_INET) {
+ if (addr[0] == 0 && addr[1] == 0 &&
+ addr[2] == htonl(0xffff) &&
+ bitstring_match(addr + 3,
+ cond->addr,
+ cond->prefix_len))
+ break;
+ }
+ yes = 0;
+ break;
+ }
+
+ if (cond->prefix_len == 0)
+ break;
if (bitstring_match(addr, cond->addr,
cond->prefix_len))
break;
- if (entry->family == AF_INET6 &&
- cond->family == AF_INET) {
- if (addr[0] == 0 && addr[1] == 0 &&
- addr[2] == htonl(0xffff) &&
- bitstring_match(addr + 3, cond->addr,
- cond->prefix_len))
- break;
- }
yes = 0;
break;
}
@@ -509,6 +519,55 @@ static int valid_cc(const void *bc, int len, int cc)
return 0;
}
+/* Validate an inet_diag_hostcond. */
+static bool valid_hostcond(const struct inet_diag_bc_op *op, int len,
+ int *min_len)
+{
+ int addr_len;
+ struct inet_diag_hostcond *cond;
+
+ /* Check hostcond space. */
+ *min_len += sizeof(struct inet_diag_hostcond);
+ if (len < *min_len)
+ return false;
+ cond = (struct inet_diag_hostcond *)(op + 1);
+
+ /* Check address family and address length. */
+ switch (cond->family) {
+ case AF_UNSPEC:
+ addr_len = 0;
+ break;
+ case AF_INET:
+ addr_len = sizeof(struct in_addr);
+ break;
+ case AF_INET6:
+ addr_len = sizeof(struct in6_addr);
+ break;
+ default:
+ return false;
+ }
+ *min_len += addr_len;
+ if (len < *min_len)
+ return false;
+
+ /* Check prefix length (in bits) vs address length (in bytes). */
+ if (cond->prefix_len > 8 * addr_len)
+ return false;
+
+ return true;
+}
+
+/* Validate a port comparison operator. */
+static inline bool valid_port_comparison(const struct inet_diag_bc_op *op,
+ int len, int *min_len)
+{
+ /* Port comparisons put the port in a follow-on inet_diag_bc_op. */
+ *min_len += sizeof(struct inet_diag_bc_op);
+ if (len < *min_len)
+ return false;
+ return true;
+}
+
static int inet_diag_bc_audit(const void *bytecode, int bytecode_len)
{
const void *bc = bytecode;
@@ -516,29 +575,39 @@ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len)
while (len > 0) {
const struct inet_diag_bc_op *op = bc;
+ int min_len = sizeof(struct inet_diag_bc_op);
//printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len);
switch (op->code) {
- case INET_DIAG_BC_AUTO:
case INET_DIAG_BC_S_COND:
case INET_DIAG_BC_D_COND:
+ if (!valid_hostcond(bc, len, &min_len))
+ return -EINVAL;
+ break;
case INET_DIAG_BC_S_GE:
case INET_DIAG_BC_S_LE:
case INET_DIAG_BC_D_GE:
case INET_DIAG_BC_D_LE:
- case INET_DIAG_BC_JMP:
- if (op->no < 4 || op->no > len + 4 || op->no & 3)
- return -EINVAL;
- if (op->no < len &&
- !valid_cc(bytecode, bytecode_len, len - op->no))
+ if (!valid_port_comparison(bc, len, &min_len))
return -EINVAL;
break;
+ case INET_DIAG_BC_AUTO:
+ case INET_DIAG_BC_JMP:
case INET_DIAG_BC_NOP:
break;
default:
return -EINVAL;
}
- if (op->yes < 4 || op->yes > len + 4 || op->yes & 3)
+
+ if (op->code != INET_DIAG_BC_NOP) {
+ if (op->no < min_len || op->no > len + 4 || op->no & 3)
+ return -EINVAL;
+ if (op->no < len &&
+ !valid_cc(bytecode, bytecode_len, len - op->no))
+ return -EINVAL;
+ }
+
+ if (op->yes < min_len || op->yes > len + 4 || op->yes & 3)
return -EINVAL;
bc += op->yes;
len -= op->yes;
@@ -596,6 +665,36 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw,
cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
}
+/* Get the IPv4, IPv6, or IPv4-mapped-IPv6 local and remote addresses
+ * from a request_sock. For IPv4-mapped-IPv6 we must map IPv4 to IPv6.
+ */
+static inline void inet_diag_req_addrs(const struct sock *sk,
+ const struct request_sock *req,
+ struct inet_diag_entry *entry)
+{
+ struct inet_request_sock *ireq = inet_rsk(req);
+
+#if IS_ENABLED(CONFIG_IPV6)
+ if (sk->sk_family == AF_INET6) {
+ if (req->rsk_ops->family == AF_INET6) {
+ entry->saddr = inet6_rsk(req)->loc_addr.s6_addr32;
+ entry->daddr = inet6_rsk(req)->rmt_addr.s6_addr32;
+ } else if (req->rsk_ops->family == AF_INET) {
+ ipv6_addr_set_v4mapped(ireq->loc_addr,
+ &entry->saddr_storage);
+ ipv6_addr_set_v4mapped(ireq->rmt_addr,
+ &entry->daddr_storage);
+ entry->saddr = entry->saddr_storage.s6_addr32;
+ entry->daddr = entry->daddr_storage.s6_addr32;
+ }
+ } else
+#endif
+ {
+ entry->saddr = &ireq->loc_addr;
+ entry->daddr = &ireq->rmt_addr;
+ }
+}
+
static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
struct request_sock *req,
struct user_namespace *user_ns,
@@ -637,8 +736,10 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
r->idiag_inode = 0;
#if IS_ENABLED(CONFIG_IPV6)
if (r->idiag_family == AF_INET6) {
- *(struct in6_addr *)r->id.idiag_src = inet6_rsk(req)->loc_addr;
- *(struct in6_addr *)r->id.idiag_dst = inet6_rsk(req)->rmt_addr;
+ struct inet_diag_entry entry;
+ inet_diag_req_addrs(sk, req, &entry);
+ memcpy(r->id.idiag_src, entry.saddr, sizeof(struct in6_addr));
+ memcpy(r->id.idiag_dst, entry.daddr, sizeof(struct in6_addr));
}
#endif
@@ -691,18 +792,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
continue;
if (bc) {
- entry.saddr =
-#if IS_ENABLED(CONFIG_IPV6)
- (entry.family == AF_INET6) ?
- inet6_rsk(req)->loc_addr.s6_addr32 :
-#endif
- &ireq->loc_addr;
- entry.daddr =
-#if IS_ENABLED(CONFIG_IPV6)
- (entry.family == AF_INET6) ?
- inet6_rsk(req)->rmt_addr.s6_addr32 :
-#endif
- &ireq->rmt_addr;
+ inet_diag_req_addrs(sk, req, &entry);
entry.dport = ntohs(ireq->rmt_port);
if (!inet_diag_bc_run(bc, &entry))
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 448e6854682..8d5cc75dac8 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -707,28 +707,27 @@ EXPORT_SYMBOL(ip_defrag);
struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user)
{
- const struct iphdr *iph;
+ struct iphdr iph;
u32 len;
if (skb->protocol != htons(ETH_P_IP))
return skb;
- if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+ if (!skb_copy_bits(skb, 0, &iph, sizeof(iph)))
return skb;
- iph = ip_hdr(skb);
- if (iph->ihl < 5 || iph->version != 4)
+ if (iph.ihl < 5 || iph.version != 4)
return skb;
- if (!pskb_may_pull(skb, iph->ihl*4))
- return skb;
- iph = ip_hdr(skb);
- len = ntohs(iph->tot_len);
- if (skb->len < len || len < (iph->ihl * 4))
+
+ len = ntohs(iph.tot_len);
+ if (skb->len < len || len < (iph.ihl * 4))
return skb;
- if (ip_is_fragment(ip_hdr(skb))) {
+ if (ip_is_fragment(&iph)) {
skb = skb_share_check(skb, GFP_ATOMIC);
if (skb) {
+ if (!pskb_may_pull(skb, iph.ihl*4))
+ return skb;
if (pskb_trim_rcsum(skb, len))
return skb;
memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 5eea4a81104..14bbfcf717a 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -457,19 +457,28 @@ static int do_ip_setsockopt(struct sock *sk, int level,
struct inet_sock *inet = inet_sk(sk);
int val = 0, err;
- if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) |
- (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) |
- (1<<IP_RETOPTS) | (1<<IP_TOS) |
- (1<<IP_TTL) | (1<<IP_HDRINCL) |
- (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
- (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
- (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) |
- (1<<IP_MINTTL) | (1<<IP_NODEFRAG))) ||
- optname == IP_UNICAST_IF ||
- optname == IP_MULTICAST_TTL ||
- optname == IP_MULTICAST_ALL ||
- optname == IP_MULTICAST_LOOP ||
- optname == IP_RECVORIGDSTADDR) {
+ switch (optname) {
+ case IP_PKTINFO:
+ case IP_RECVTTL:
+ case IP_RECVOPTS:
+ case IP_RECVTOS:
+ case IP_RETOPTS:
+ case IP_TOS:
+ case IP_TTL:
+ case IP_HDRINCL:
+ case IP_MTU_DISCOVER:
+ case IP_RECVERR:
+ case IP_ROUTER_ALERT:
+ case IP_FREEBIND:
+ case IP_PASSSEC:
+ case IP_TRANSPARENT:
+ case IP_MINTTL:
+ case IP_NODEFRAG:
+ case IP_UNICAST_IF:
+ case IP_MULTICAST_TTL:
+ case IP_MULTICAST_ALL:
+ case IP_MULTICAST_LOOP:
+ case IP_RECVORIGDSTADDR:
if (optlen >= sizeof(int)) {
if (get_user(val, (int __user *) optval))
return -EFAULT;
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 1831092f999..858fddf6482 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -338,12 +338,17 @@ static int vti_rcv(struct sk_buff *skb)
if (tunnel != NULL) {
struct pcpu_tstats *tstats;
+ if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
+ return -1;
+
tstats = this_cpu_ptr(tunnel->dev->tstats);
u64_stats_update_begin(&tstats->syncp);
tstats->rx_packets++;
tstats->rx_bytes += skb->len;
u64_stats_update_end(&tstats->syncp);
+ skb->mark = 0;
+ secpath_reset(skb);
skb->dev = tunnel->dev;
return 1;
}
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 6168c4dc58b..3eab2b2ffd3 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1318,6 +1318,10 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
if (get_user(v, (u32 __user *)optval))
return -EFAULT;
+ /* "pimreg%u" should not exceed 16 bytes (IFNAMSIZ) */
+ if (v != RT_TABLE_DEFAULT && v >= 1000000000)
+ return -EINVAL;
+
rtnl_lock();
ret = 0;
if (sk == rtnl_dereference(mrt->mroute_sk)) {
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index a8c651216fa..df251424d81 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1785,6 +1785,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
if (dev_out->flags & IFF_LOOPBACK)
flags |= RTCF_LOCAL;
+ do_cache = true;
if (type == RTN_BROADCAST) {
flags |= RTCF_BROADCAST | RTCF_LOCAL;
fi = NULL;
@@ -1793,6 +1794,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr,
fl4->flowi4_proto))
flags &= ~RTCF_LOCAL;
+ else
+ do_cache = false;
/* If multicast route do not exist use
* default one, but do not gateway in this case.
* Yes, it is hack.
@@ -1802,8 +1805,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
}
fnhe = NULL;
- do_cache = fi != NULL;
- if (fi) {
+ do_cache &= fi != NULL;
+ if (do_cache) {
struct rtable __rcu **prth;
struct fib_nh *nh = &FIB_RES_NH(*res);
@@ -2597,7 +2600,7 @@ int __init ip_rt_init(void)
pr_err("Unable to create route proc files\n");
#ifdef CONFIG_XFRM
xfrm_init();
- xfrm4_init(ip_rt_max_size);
+ xfrm4_init();
#endif
rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL, NULL);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 197c0008503..e457c7ab2e2 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -830,8 +830,8 @@ static int tcp_send_mss(struct sock *sk, int *size_goal, int flags)
return mss_now;
}
-static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset,
- size_t psize, int flags)
+static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset,
+ size_t size, int flags)
{
struct tcp_sock *tp = tcp_sk(sk);
int mss_now, size_goal;
@@ -858,12 +858,9 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse
if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
goto out_err;
- while (psize > 0) {
+ while (size > 0) {
struct sk_buff *skb = tcp_write_queue_tail(sk);
- struct page *page = pages[poffset / PAGE_SIZE];
int copy, i;
- int offset = poffset % PAGE_SIZE;
- int size = min_t(size_t, psize, PAGE_SIZE - offset);
bool can_coalesce;
if (!tcp_send_head(sk) || (copy = size_goal - skb->len) <= 0) {
@@ -912,8 +909,8 @@ new_segment:
TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH;
copied += copy;
- poffset += copy;
- if (!(psize -= copy))
+ offset += copy;
+ if (!(size -= copy))
goto out;
if (skb->len < size_goal || (flags & MSG_OOB))
@@ -960,7 +957,7 @@ int tcp_sendpage(struct sock *sk, struct page *page, int offset,
flags);
lock_sock(sk);
- res = do_tcp_sendpages(sk, &page, offset, size, flags);
+ res = do_tcp_sendpages(sk, page, offset, size, flags);
release_sock(sk);
return res;
}
@@ -1212,7 +1209,7 @@ new_segment:
wait_for_sndbuf:
set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
wait_for_memory:
- if (copied && likely(!tp->repair))
+ if (copied)
tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH);
if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
@@ -1223,7 +1220,7 @@ wait_for_memory:
}
out:
- if (copied && likely(!tp->repair))
+ if (copied)
tcp_push(sk, flags, mss_now, tp->nonagle);
release_sock(sk);
return copied + copied_syn;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 2c2b13a999e..181fc8234a5 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5313,11 +5313,6 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb,
goto discard;
}
- /* ts_recent update must be made after we are sure that the packet
- * is in window.
- */
- tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
-
/* step 3: check security and precedence [ignored] */
/* step 4: Check for a SYN
@@ -5552,6 +5547,11 @@ step5:
if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0)
goto discard;
+ /* ts_recent update must be made after we are sure that the packet
+ * is in window.
+ */
+ tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
+
tcp_rcv_rtt_measure_ts(sk, skb);
/* Process urgent data. */
@@ -5645,7 +5645,11 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
tcp_fastopen_cache_set(sk, mss, cookie, syn_drop);
if (data) { /* Retransmit unacked data in SYN */
- tcp_retransmit_skb(sk, data);
+ tcp_for_write_queue_from(data, sk) {
+ if (data == tcp_send_head(sk) ||
+ __tcp_retransmit_skb(sk, data))
+ break;
+ }
tcp_rearm_rto(sk);
return true;
}
@@ -6130,6 +6134,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
} else
goto discard;
+ /* ts_recent update must be made after we are sure that the packet
+ * is in window.
+ */
+ tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
+
/* step 6: check the URG bit */
tcp_urg(sk, skb, th);
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index 53bc5847bfa..f696d7c2e9f 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -1,7 +1,6 @@
#include <linux/rcupdate.h>
#include <linux/spinlock.h>
#include <linux/jiffies.h>
-#include <linux/bootmem.h>
#include <linux/module.h>
#include <linux/cache.h>
#include <linux/slab.h>
@@ -9,6 +8,7 @@
#include <linux/tcp.h>
#include <linux/hash.h>
#include <linux/tcp_metrics.h>
+#include <linux/vmalloc.h>
#include <net/inet_connection_sock.h>
#include <net/net_namespace.h>
@@ -1034,7 +1034,10 @@ static int __net_init tcp_net_metrics_init(struct net *net)
net->ipv4.tcp_metrics_hash_log = order_base_2(slots);
size = sizeof(struct tcpm_hash_bucket) << net->ipv4.tcp_metrics_hash_log;
- net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL);
+ net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
+ if (!net->ipv4.tcp_metrics_hash)
+ net->ipv4.tcp_metrics_hash = vzalloc(size);
+
if (!net->ipv4.tcp_metrics_hash)
return -ENOMEM;
@@ -1055,7 +1058,10 @@ static void __net_exit tcp_net_metrics_exit(struct net *net)
tm = next;
}
}
- kfree(net->ipv4.tcp_metrics_hash);
+ if (is_vmalloc_addr(net->ipv4.tcp_metrics_hash))
+ vfree(net->ipv4.tcp_metrics_hash);
+ else
+ kfree(net->ipv4.tcp_metrics_hash);
}
static __net_initdata struct pernet_operations tcp_net_metrics_ops = {
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index cfe6ffe1c17..948ac275b9b 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1986,6 +1986,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
BUG_ON(!tso_segs);
+ if (unlikely(tp->repair) && tp->repair_queue == TCP_SEND_QUEUE)
+ goto repair; /* Skip network transmission */
+
cwnd_quota = tcp_cwnd_test(tp, skb);
if (!cwnd_quota)
break;
@@ -2026,6 +2029,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp)))
break;
+repair:
/* Advance the send_head. This one is sent out.
* This call will increment packets_out.
*/
@@ -2305,12 +2309,11 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to,
* state updates are done by the caller. Returns non-zero if an
* error occurred which prevented the send.
*/
-int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
+int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
{
struct tcp_sock *tp = tcp_sk(sk);
struct inet_connection_sock *icsk = inet_csk(sk);
unsigned int cur_mss;
- int err;
/* Inconslusive MTU probe */
if (icsk->icsk_mtup.probe_size) {
@@ -2383,11 +2386,17 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) {
struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER,
GFP_ATOMIC);
- err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
- -ENOBUFS;
+ return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
+ -ENOBUFS;
} else {
- err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
+ return tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
}
+}
+
+int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
+{
+ struct tcp_sock *tp = tcp_sk(sk);
+ int err = __tcp_retransmit_skb(sk, skb);
if (err == 0) {
/* Update global TCP statistics. */
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 05c5ab8d983..3be0ac2c192 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -279,19 +279,8 @@ static void __exit xfrm4_policy_fini(void)
xfrm_policy_unregister_afinfo(&xfrm4_policy_afinfo);
}
-void __init xfrm4_init(int rt_max_size)
+void __init xfrm4_init(void)
{
- /*
- * Select a default value for the gc_thresh based on the main route
- * table hash size. It seems to me the worst case scenario is when
- * we have ipsec operating in transport mode, in which we create a
- * dst_entry per socket. The xfrm gc algorithm starts trying to remove
- * entries at gc_thresh, and prevents new allocations as 2*gc_thresh
- * so lets set an initial xfrm gc_thresh value at the rt_max_size/2.
- * That will let us store an ipsec connection per route table entry,
- * and start cleaning when were 1/2 full
- */
- xfrm4_dst_ops.gc_thresh = rt_max_size/2;
dst_entries_init(&xfrm4_dst_ops);
xfrm4_state_init();
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index c4f934176ca..30647857a37 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -252,6 +252,7 @@ struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu)
return NULL;
dst->ops->update_pmtu(dst, sk, NULL, mtu);
- return inet6_csk_route_socket(sk, &fl6);
+ dst = inet6_csk_route_socket(sk, &fl6);
+ return IS_ERR(dst) ? NULL : dst;
}
EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu);
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index ba6d13d1f1e..e02faed6d17 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -827,6 +827,7 @@ pref_skip_coa:
if (val < 0 || val > 255)
goto e_inval;
np->min_hopcount = val;
+ retv = 0;
break;
case IPV6_DONTFRAG:
np->dontfrag = valbool;
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 496ce2cebcd..a68c88cdec6 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -183,6 +183,7 @@ static void __exit __ircomm_tty_cleanup(struct ircomm_tty_cb *self)
ircomm_tty_shutdown(self);
self->magic = 0;
+ tty_port_destroy(&self->port);
kfree(self);
}
diff --git a/net/irda/irttp.c b/net/irda/irttp.c
index 1002e3396f7..ae43c62f904 100644
--- a/net/irda/irttp.c
+++ b/net/irda/irttp.c
@@ -441,6 +441,7 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
lsap = irlmp_open_lsap(stsap_sel, &ttp_notify, 0);
if (lsap == NULL) {
IRDA_DEBUG(0, "%s: unable to allocate LSAP!!\n", __func__);
+ __irttp_close_tsap(self);
return NULL;
}
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 05f3a313db8..7371f676cf4 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2594,6 +2594,9 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
else
local->probe_req_reg--;
+ if (!local->open_count)
+ break;
+
ieee80211_queue_work(&local->hw, &local->reconfig_filter);
break;
default:
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index bf87c70ac6c..c21e33d1abd 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -1151,10 +1151,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
mutex_lock(&sdata->u.ibss.mtx);
- sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
- memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
- sdata->u.ibss.ssid_len = 0;
-
active_ibss = ieee80211_sta_active_ibss(sdata);
if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
@@ -1175,6 +1171,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
}
}
+ ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
+ memset(ifibss->bssid, 0, ETH_ALEN);
+ ifibss->ssid_len = 0;
+
sta_info_flush(sdata->local, sdata);
spin_lock_bh(&ifibss->incomplete_lock);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8c804550465..156e5835e37 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1314,6 +1314,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
struct net_device *dev);
netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
struct net_device *dev);
+void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
+ struct sk_buff_head *skbs);
/* HT */
void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index c80c4490351..f57f597972f 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -871,8 +871,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
local->hw.wiphy->cipher_suites,
sizeof(u32) * local->hw.wiphy->n_cipher_suites,
GFP_KERNEL);
- if (!suites)
- return -ENOMEM;
+ if (!suites) {
+ result = -ENOMEM;
+ goto fail_wiphy_register;
+ }
for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) {
u32 suite = local->hw.wiphy->cipher_suites[r];
if (suite == WLAN_CIPHER_SUITE_WEP40 ||
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 83608ac1678..2c84185dfdb 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -458,8 +458,6 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata)
list_move_tail(&roc->list, &tmp_list);
roc->abort = true;
}
-
- ieee80211_start_next_roc(local);
mutex_unlock(&local->mtx);
list_for_each_entry_safe(roc, tmp, &tmp_list, list) {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index c4cdbde24fd..43e60b5a754 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -917,7 +917,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
struct cfg80211_sched_scan_request *req)
{
struct ieee80211_local *local = sdata->local;
- struct ieee80211_sched_scan_ies sched_scan_ies;
+ struct ieee80211_sched_scan_ies sched_scan_ies = {};
int ret, i;
mutex_lock(&local->mtx);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 0a4e4c04db8..d2eb64e1235 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -117,8 +117,8 @@ static void free_sta_work(struct work_struct *wk)
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
- __skb_queue_purge(&sta->ps_tx_buf[ac]);
- __skb_queue_purge(&sta->tx_filtered[ac]);
+ ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]);
+ ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]);
}
#ifdef CONFIG_MAC80211_MESH
@@ -141,7 +141,7 @@ static void free_sta_work(struct work_struct *wk)
tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
if (!tid_tx)
continue;
- __skb_queue_purge(&tid_tx->pending);
+ ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending);
kfree(tid_tx);
}
@@ -961,6 +961,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
struct ieee80211_local *local = sdata->local;
struct sk_buff_head pending;
int filtered = 0, buffered = 0, ac;
+ unsigned long flags;
clear_sta_flag(sta, WLAN_STA_SP);
@@ -976,12 +977,16 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
int count = skb_queue_len(&pending), tmp;
+ spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags);
skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending);
+ spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags);
tmp = skb_queue_len(&pending);
filtered += tmp - count;
count = tmp;
+ spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags);
skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending);
+ spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags);
tmp = skb_queue_len(&pending);
buffered += tmp - count;
}
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 3af0cc4130f..101eb88a2b7 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -668,3 +668,12 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb)
dev_kfree_skb_any(skb);
}
EXPORT_SYMBOL(ieee80211_free_txskb);
+
+void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
+ struct sk_buff_head *skbs)
+{
+ struct sk_buff *skb;
+
+ while ((skb = __skb_dequeue(skbs)))
+ ieee80211_free_txskb(hw, skb);
+}
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c9bf83f3665..b858ebe41fd 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1358,7 +1358,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
if (tx->skb)
ieee80211_free_txskb(&tx->local->hw, tx->skb);
else
- __skb_queue_purge(&tx->skbs);
+ ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs);
return -1;
} else if (unlikely(res == TX_QUEUED)) {
I802_DEBUG_INC(tx->local->tx_handlers_queued);
@@ -2120,10 +2120,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
*/
void ieee80211_clear_tx_pending(struct ieee80211_local *local)
{
+ struct sk_buff *skb;
int i;
- for (i = 0; i < local->hw.queues; i++)
- skb_queue_purge(&local->pending[i]);
+ for (i = 0; i < local->hw.queues; i++) {
+ while ((skb = skb_dequeue(&local->pending[i])) != NULL)
+ ieee80211_free_txskb(&local->hw, skb);
+ }
}
/*
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 239391807ca..0151ae33c4c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1491,6 +1491,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
list_for_each_entry(sdata, &local->interfaces, list) {
if (sdata->vif.type != NL80211_IFTYPE_STATION)
continue;
+ if (!sdata->u.mgd.associated)
+ continue;
ieee80211_send_nullfunc(local, sdata, 0);
}
diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
index ec3dba5dcd6..5c0b78528e5 100644
--- a/net/netfilter/ipset/ip_set_hash_ip.c
+++ b/net/netfilter/ipset/ip_set_hash_ip.c
@@ -173,6 +173,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
return adtfn(set, &nip, timeout, flags);
}
+ ip_to = ip;
if (tb[IPSET_ATTR_IP_TO]) {
ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
if (ret)
@@ -185,8 +186,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
if (!cidr || cidr > 32)
return -IPSET_ERR_INVALID_CIDR;
ip_set_mask_from_to(ip, ip_to, cidr);
- } else
- ip_to = ip;
+ }
hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1);
diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
index 0171f7502fa..6283351f4ee 100644
--- a/net/netfilter/ipset/ip_set_hash_ipport.c
+++ b/net/netfilter/ipset/ip_set_hash_ipport.c
@@ -162,7 +162,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipport4_elem data = { };
- u32 ip, ip_to = 0, p = 0, port, port_to;
+ u32 ip, ip_to, p = 0, port, port_to;
u32 timeout = h->timeout;
bool with_ports = false;
int ret;
@@ -210,7 +210,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
return ip_set_eexist(ret, flags) ? 0 : ret;
}
- ip = ntohl(data.ip);
+ ip_to = ip = ntohl(data.ip);
if (tb[IPSET_ATTR_IP_TO]) {
ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
if (ret)
@@ -223,8 +223,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
if (!cidr || cidr > 32)
return -IPSET_ERR_INVALID_CIDR;
ip_set_mask_from_to(ip, ip_to, cidr);
- } else
- ip_to = ip;
+ }
port_to = port = ntohs(data.port);
if (with_ports && tb[IPSET_ATTR_PORT_TO]) {
diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
index 6344ef551ec..6a21271c8d5 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportip.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
@@ -166,7 +166,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportip4_elem data = { };
- u32 ip, ip_to = 0, p = 0, port, port_to;
+ u32 ip, ip_to, p = 0, port, port_to;
u32 timeout = h->timeout;
bool with_ports = false;
int ret;
@@ -218,7 +218,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
return ip_set_eexist(ret, flags) ? 0 : ret;
}
- ip = ntohl(data.ip);
+ ip_to = ip = ntohl(data.ip);
if (tb[IPSET_ATTR_IP_TO]) {
ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
if (ret)
@@ -231,8 +231,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
if (!cidr || cidr > 32)
return -IPSET_ERR_INVALID_CIDR;
ip_set_mask_from_to(ip, ip_to, cidr);
- } else
- ip_to = ip;
+ }
port_to = port = ntohs(data.port);
if (with_ports && tb[IPSET_ATTR_PORT_TO]) {
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
index cb71f9a774e..2d5cd4ee30e 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
@@ -215,8 +215,8 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportnet4_elem data = { .cidr = HOST_MASK - 1 };
- u32 ip, ip_to = 0, p = 0, port, port_to;
- u32 ip2_from = 0, ip2_to, ip2_last, ip2;
+ u32 ip, ip_to, p = 0, port, port_to;
+ u32 ip2_from, ip2_to, ip2_last, ip2;
u32 timeout = h->timeout;
bool with_ports = false;
u8 cidr;
@@ -286,6 +286,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
return ip_set_eexist(ret, flags) ? 0 : ret;
}
+ ip_to = ip;
if (tb[IPSET_ATTR_IP_TO]) {
ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
if (ret)
@@ -306,6 +307,8 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
if (port > port_to)
swap(port, port_to);
}
+
+ ip2_to = ip2_from;
if (tb[IPSET_ATTR_IP2_TO]) {
ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to);
if (ret)
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
index b9a63381e34..45a101439bc 100644
--- a/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -793,7 +793,7 @@ static struct ip_set_type hash_netiface_type __read_mostly = {
[IPSET_ATTR_IP] = { .type = NLA_NESTED },
[IPSET_ATTR_IP_TO] = { .type = NLA_NESTED },
[IPSET_ATTR_IFACE] = { .type = NLA_NUL_STRING,
- .len = IPSET_MAXNAMELEN - 1 },
+ .len = IFNAMSIZ - 1 },
[IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
[IPSET_ATTR_CIDR] = { .type = NLA_U8 },
[IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
index 8847b4d8be0..701c88a20fe 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -41,7 +41,8 @@ MODULE_DESCRIPTION("cttimeout: Extended Netfilter Connection Tracking timeout tu
static LIST_HEAD(cttimeout_list);
static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = {
- [CTA_TIMEOUT_NAME] = { .type = NLA_NUL_STRING },
+ [CTA_TIMEOUT_NAME] = { .type = NLA_NUL_STRING,
+ .len = CTNL_TIMEOUT_NAME_MAX - 1},
[CTA_TIMEOUT_L3PROTO] = { .type = NLA_U16 },
[CTA_TIMEOUT_L4PROTO] = { .type = NLA_U8 },
[CTA_TIMEOUT_DATA] = { .type = NLA_NESTED },
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index cc10d073c33..9e8f4b2801f 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -1210,7 +1210,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
local->remote_miu = LLCP_DEFAULT_MIU;
local->remote_lto = LLCP_DEFAULT_LTO;
- list_add(&llcp_devices, &local->list);
+ list_add(&local->list, &llcp_devices);
return 0;
}
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 98c70630ad0..733cbf49ed1 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -702,15 +702,11 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
/* We only match on the lower 8 bits of the opcode. */
if (ntohs(arp->ar_op) <= 0xff)
key->ip.proto = ntohs(arp->ar_op);
-
- if (key->ip.proto == ARPOP_REQUEST
- || key->ip.proto == ARPOP_REPLY) {
- memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src));
- memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst));
- memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN);
- memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN);
- key_len = SW_FLOW_KEY_OFFSET(ipv4.arp);
- }
+ memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src));
+ memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst));
+ memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN);
+ memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN);
+ key_len = SW_FLOW_KEY_OFFSET(ipv4.arp);
}
} else if (key->eth.type == htons(ETH_P_IPV6)) {
int nh_len; /* IPv6 Header + Extensions */
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c
index 3c1e58ba714..a9033481fa5 100644
--- a/net/openvswitch/vport-netdev.c
+++ b/net/openvswitch/vport-netdev.c
@@ -158,7 +158,7 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb)
if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) {
net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n",
- ovs_dp_name(vport->dp),
+ netdev_vport->dev->name,
packet_length(skb), mtu);
goto error;
}
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 7c2df9c33df..69ce21e3716 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -183,7 +183,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
msg = sctp_datamsg_new(GFP_KERNEL);
if (!msg)
- return NULL;
+ return ERR_PTR(-ENOMEM);
/* Note: Calculate this outside of the loop, so that all fragments
* have the same expiration.
@@ -280,11 +280,14 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0);
- if (!chunk)
+ if (!chunk) {
+ err = -ENOMEM;
goto errout;
+ }
+
err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov);
if (err < 0)
- goto errout;
+ goto errout_chunk_free;
offset += len;
@@ -315,8 +318,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0);
- if (!chunk)
+ if (!chunk) {
+ err = -ENOMEM;
goto errout;
+ }
err = sctp_user_addto_chunk(chunk, offset, over,msgh->msg_iov);
@@ -324,7 +329,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
__skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr
- (__u8 *)chunk->skb->data);
if (err < 0)
- goto errout;
+ goto errout_chunk_free;
sctp_datamsg_assign(msg, chunk);
list_add_tail(&chunk->frag_list, &msg->chunks);
@@ -332,6 +337,9 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
return msg;
+errout_chunk_free:
+ sctp_chunk_free(chunk);
+
errout:
list_for_each_safe(pos, temp, &msg->chunks) {
list_del_init(pos);
@@ -339,7 +347,7 @@ errout:
sctp_chunk_free(chunk);
}
sctp_datamsg_put(msg);
- return NULL;
+ return ERR_PTR(err);
}
/* Check whether this message has expired. */
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index c3bea269faf..9966e7b1645 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -102,7 +102,7 @@ static const struct file_operations sctp_snmp_seq_fops = {
.open = sctp_snmp_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = single_release,
+ .release = single_release_net,
};
/* Set up the proc fs entry for 'snmp' object. */
@@ -251,7 +251,7 @@ static const struct file_operations sctp_eps_seq_fops = {
.open = sctp_eps_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = seq_release_net,
};
/* Set up the proc fs entry for 'eps' object. */
@@ -372,7 +372,7 @@ static const struct file_operations sctp_assocs_seq_fops = {
.open = sctp_assocs_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = seq_release_net,
};
/* Set up the proc fs entry for 'assocs' object. */
@@ -517,7 +517,7 @@ static const struct file_operations sctp_remaddr_seq_fops = {
.open = sctp_remaddr_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = seq_release_net,
};
int __net_init sctp_remaddr_proc_init(struct net *net)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index a60d1f8b41c..406d957d08f 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1915,8 +1915,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
/* Break the message into multiple chunks of maximum size. */
datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len);
- if (!datamsg) {
- err = -ENOMEM;
+ if (IS_ERR(datamsg)) {
+ err = PTR_ERR(datamsg);
goto out_free;
}
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 953c21e4af9..206cf5238fd 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -331,7 +331,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
* 1/8, rto_alpha would be expressed as 3.
*/
tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta)
- + ((abs(tp->srtt - rtt)) >> net->sctp.rto_beta);
+ + (((__u32)abs64((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta);
tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha)
+ (rtt >> net->sctp.rto_alpha);
} else {
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index bcc7d7ee5a5..b75756b05af 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -141,9 +141,8 @@ static const struct ieee80211_regdomain world_regdom = {
.reg_rules = {
/* IEEE 802.11b/g, channels 1..11 */
REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
- /* IEEE 802.11b/g, channels 12..13. No HT40
- * channel fits here. */
- REG_RULE(2467-10, 2472+10, 20, 6, 20,
+ /* IEEE 802.11b/g, channels 12..13. */
+ REG_RULE(2467-10, 2472+10, 40, 6, 20,
NL80211_RRF_PASSIVE_SCAN |
NL80211_RRF_NO_IBSS),
/* IEEE 802.11 channel 14 - Only JP enables
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0be6f110cce..bdf42fdf64c 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -266,6 +266,9 @@ $(obj)/%.dtb.S: $(obj)/%.dtb
quiet_cmd_dtc = DTC $@
cmd_dtc = $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) -d $(depfile) $<
+$(obj)/%.dtb: $(src)/%.dts FORCE
+ $(call if_changed_dep,dtc)
+
# Bzip2
# ---------------------------------------------------------------------------
diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile
index 6d1c6bb9f22..2a48022c41e 100644
--- a/scripts/dtc/Makefile
+++ b/scripts/dtc/Makefile
@@ -27,3 +27,5 @@ HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC)
# dependencies on generated files need to be listed explicitly
$(obj)/dtc-lexer.lex.o: $(obj)/dtc-parser.tab.h
+# generated files need to be cleaned explicitly
+clean-files := dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h
diff --git a/scripts/headers_install.pl b/scripts/headers_install.pl
index 239d22d4207..6c353ae8a45 100644
--- a/scripts/headers_install.pl
+++ b/scripts/headers_install.pl
@@ -42,6 +42,9 @@ foreach my $filename (@files) {
$line =~ s/(^|\s)(inline)\b/$1__$2__/g;
$line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g;
$line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g;
+ $line =~ s/#ifndef _UAPI/#ifndef /;
+ $line =~ s/#define _UAPI/#define /;
+ $line =~ s!#endif /[*] _UAPI!#endif /* !;
printf {$out} "%s", $line;
}
close $out;
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index bd2e0989555..cdd48600e02 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -12,7 +12,7 @@ extern "C" {
#include <assert.h>
#include <stdio.h>
-#include <sys/queue.h>
+#include "list.h"
#ifndef __cplusplus
#include <stdbool.h>
#endif
@@ -175,12 +175,11 @@ struct menu {
#define MENU_ROOT 0x0002
struct jump_key {
- CIRCLEQ_ENTRY(jump_key) entries;
+ struct list_head entries;
size_t offset;
struct menu *target;
int index;
};
-CIRCLEQ_HEAD(jk_head, jump_key);
#define JUMP_NB 9
diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h
new file mode 100644
index 00000000000..0ae730be5f4
--- /dev/null
+++ b/scripts/kconfig/list.h
@@ -0,0 +1,91 @@
+#ifndef LIST_H
+#define LIST_H
+
+/*
+ * Copied from include/linux/...
+ */
+
+#undef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+ return head->next == head;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head *_new,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = _new;
+ _new->next = next;
+ _new->prev = prev;
+ prev->next = _new;
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *_new, struct list_head *head)
+{
+ __list_add(_new, head->prev, head);
+}
+
+#endif
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 1d1c08537f1..ef1a7381f95 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -21,9 +21,9 @@ P(menu_get_root_menu,struct menu *,(struct menu *menu));
P(menu_get_parent_menu,struct menu *,(struct menu *menu));
P(menu_has_help,bool,(struct menu *menu));
P(menu_get_help,const char *,(struct menu *menu));
-P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct jk_head
+P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head
*head));
-P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct jk_head
+P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct list_head
*head));
P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 48f67448af7..53975cf8760 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -312,7 +312,7 @@ static void set_config_filename(const char *config_filename)
struct search_data {
- struct jk_head *head;
+ struct list_head *head;
struct menu **targets;
int *keys;
};
@@ -323,7 +323,7 @@ static void update_text(char *buf, size_t start, size_t end, void *_data)
struct jump_key *pos;
int k = 0;
- CIRCLEQ_FOREACH(pos, data->head, entries) {
+ list_for_each_entry(pos, data->head, entries) {
if (pos->offset >= start && pos->offset < end) {
char header[4];
@@ -375,7 +375,7 @@ again:
sym_arr = sym_re_search(dialog_input);
do {
- struct jk_head head = CIRCLEQ_HEAD_INITIALIZER(head);
+ LIST_HEAD(head);
struct menu *targets[JUMP_NB];
int keys[JUMP_NB + 1], i;
struct search_data data = {
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index a3cade659f8..e98a05c8e50 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -508,7 +508,7 @@ const char *menu_get_help(struct menu *menu)
}
static void get_prompt_str(struct gstr *r, struct property *prop,
- struct jk_head *head)
+ struct list_head *head)
{
int i, j;
struct menu *submenu[8], *menu, *location = NULL;
@@ -544,12 +544,13 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
} else
jump->target = location;
- if (CIRCLEQ_EMPTY(head))
+ if (list_empty(head))
jump->index = 0;
else
- jump->index = CIRCLEQ_LAST(head)->index + 1;
+ jump->index = list_entry(head->prev, struct jump_key,
+ entries)->index + 1;
- CIRCLEQ_INSERT_TAIL(head, jump, entries);
+ list_add_tail(&jump->entries, head);
}
if (i > 0) {
@@ -573,7 +574,8 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
/*
* head is optional and may be NULL
*/
-void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head)
+void get_symbol_str(struct gstr *r, struct symbol *sym,
+ struct list_head *head)
{
bool hit;
struct property *prop;
@@ -612,7 +614,7 @@ void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head)
str_append(r, "\n\n");
}
-struct gstr get_relations_str(struct symbol **sym_arr, struct jk_head *head)
+struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head)
{
struct symbol *sym;
struct gstr res = str_new();
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 0d93856a03f..ff36c508a10 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -858,25 +858,23 @@ static void check_section(const char *modname, struct elf_info *elf,
#define ALL_INIT_DATA_SECTIONS \
".init.setup$", ".init.rodata$", \
- ".devinit.rodata$", ".cpuinit.rodata$", ".meminit.rodata$", \
- ".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$"
+ ".cpuinit.rodata$", ".meminit.rodata$", \
+ ".init.data$", ".cpuinit.data$", ".meminit.data$"
#define ALL_EXIT_DATA_SECTIONS \
- ".exit.data$", ".devexit.data$", ".cpuexit.data$", ".memexit.data$"
+ ".exit.data$", ".cpuexit.data$", ".memexit.data$"
#define ALL_INIT_TEXT_SECTIONS \
- ".init.text$", ".devinit.text$", ".cpuinit.text$", ".meminit.text$"
+ ".init.text$", ".cpuinit.text$", ".meminit.text$"
#define ALL_EXIT_TEXT_SECTIONS \
- ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$"
+ ".exit.text$", ".cpuexit.text$", ".memexit.text$"
#define ALL_PCI_INIT_SECTIONS \
".pci_fixup_early$", ".pci_fixup_header$", ".pci_fixup_final$", \
".pci_fixup_enable$", ".pci_fixup_resume$", \
".pci_fixup_resume_early$", ".pci_fixup_suspend$"
-#define ALL_XXXINIT_SECTIONS DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, \
- MEM_INIT_SECTIONS
-#define ALL_XXXEXIT_SECTIONS DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, \
- MEM_EXIT_SECTIONS
+#define ALL_XXXINIT_SECTIONS CPU_INIT_SECTIONS, MEM_INIT_SECTIONS
+#define ALL_XXXEXIT_SECTIONS CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS
#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
@@ -885,12 +883,10 @@ static void check_section(const char *modname, struct elf_info *elf,
#define TEXT_SECTIONS ".text$"
#define INIT_SECTIONS ".init.*"
-#define DEV_INIT_SECTIONS ".devinit.*"
#define CPU_INIT_SECTIONS ".cpuinit.*"
#define MEM_INIT_SECTIONS ".meminit.*"
#define EXIT_SECTIONS ".exit.*"
-#define DEV_EXIT_SECTIONS ".devexit.*"
#define CPU_EXIT_SECTIONS ".cpuexit.*"
#define MEM_EXIT_SECTIONS ".memexit.*"
@@ -979,7 +975,7 @@ const struct sectioncheck sectioncheck[] = {
.mismatch = DATA_TO_ANY_EXIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
},
-/* Do not reference init code/data from devinit/cpuinit/meminit code/data */
+/* Do not reference init code/data from cpuinit/meminit code/data */
{
.fromsec = { ALL_XXXINIT_SECTIONS, NULL },
.tosec = { INIT_SECTIONS, NULL },
@@ -1000,7 +996,7 @@ const struct sectioncheck sectioncheck[] = {
.mismatch = XXXINIT_TO_SOME_INIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
},
-/* Do not reference exit code/data from devexit/cpuexit/memexit code/data */
+/* Do not reference exit code/data from cpuexit/memexit code/data */
{
.fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
.tosec = { EXIT_SECTIONS, NULL },
@@ -1089,7 +1085,7 @@ static const struct sectioncheck *section_mismatch(
* Pattern 2:
* Many drivers utilise a *driver container with references to
* add, remove, probe functions etc.
- * These functions may often be marked __devinit and we do not want to
+ * These functions may often be marked __cpuinit and we do not want to
* warn here.
* the pattern is identified by:
* tosec = init or exit section
diff --git a/scripts/sign-file b/scripts/sign-file
index 87ca59d36e7..974a20b661b 100755
--- a/scripts/sign-file
+++ b/scripts/sign-file
@@ -156,12 +156,12 @@ sub asn1_extract($$@)
if ($l == 0x1) {
$len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1));
- } elsif ($l = 0x2) {
+ } elsif ($l == 0x2) {
$len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2));
- } elsif ($l = 0x3) {
+ } elsif ($l == 0x3) {
$len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16;
$len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2));
- } elsif ($l = 0x4) {
+ } elsif ($l == 0x4) {
$len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4));
} else {
die $x509, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n";
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 842c254396d..b08d20c66c2 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -164,8 +164,8 @@ static void dev_exception_clean(struct dev_cgroup *dev_cgroup)
struct dev_exception_item *ex, *tmp;
list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) {
- list_del(&ex->list);
- kfree(ex);
+ list_del_rcu(&ex->list);
+ kfree_rcu(ex, rcu);
}
}
@@ -298,7 +298,7 @@ static int may_access(struct dev_cgroup *dev_cgroup,
struct dev_exception_item *ex;
bool match = false;
- list_for_each_entry(ex, &dev_cgroup->exceptions, list) {
+ list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) {
if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK))
continue;
if ((refex->type & DEV_CHAR) && !(ex->type & DEV_CHAR))
@@ -352,6 +352,8 @@ static int parent_has_perm(struct dev_cgroup *childcg,
*/
static inline int may_allow_all(struct dev_cgroup *parent)
{
+ if (!parent)
+ return 1;
return parent->behavior == DEVCG_DEFAULT_ALLOW;
}
@@ -376,11 +378,14 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
int count, rc;
struct dev_exception_item ex;
struct cgroup *p = devcgroup->css.cgroup;
- struct dev_cgroup *parent = cgroup_to_devcgroup(p->parent);
+ struct dev_cgroup *parent = NULL;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+ if (p->parent)
+ parent = cgroup_to_devcgroup(p->parent);
+
memset(&ex, 0, sizeof(ex));
b = buffer;
@@ -391,11 +396,14 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
if (!may_allow_all(parent))
return -EPERM;
dev_exception_clean(devcgroup);
+ devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
+ if (!parent)
+ break;
+
rc = dev_exceptions_copy(&devcgroup->exceptions,
&parent->exceptions);
if (rc)
return rc;
- devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
break;
case DEVCG_DENY:
dev_exception_clean(devcgroup);
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index 28f911cdd7c..c5454c0477c 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -174,7 +174,8 @@ static void sel_netnode_insert(struct sel_netnode *node)
if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) {
struct sel_netnode *tail;
tail = list_entry(
- rcu_dereference(sel_netnode_hash[idx].list.prev),
+ rcu_dereference_protected(sel_netnode_hash[idx].list.prev,
+ lockdep_is_held(&sel_netnode_lock)),
struct sel_netnode, list);
list_del_rcu(&tail->list);
kfree_rcu(tail, rcu);
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 50169bcfd90..7266020c16c 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -2581,9 +2581,14 @@ static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea)
struct es1968 *chip = tea->private_data;
unsigned long io = chip->io_port + GPIO_DATA;
u16 val = inw(io);
-
- return (val & STR_DATA) ? TEA575X_DATA : 0 |
- (val & STR_MOST) ? TEA575X_MOST : 0;
+ u8 ret;
+
+ ret = 0;
+ if (val & STR_DATA)
+ ret |= TEA575X_DATA;
+ if (val & STR_MOST)
+ ret |= TEA575X_MOST;
+ return ret;
}
static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output)
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index cc2e91d1553..c5806f89be1 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -767,9 +767,14 @@ static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea)
struct fm801 *chip = tea->private_data;
unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip);
-
- return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 |
- (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0;
+ u8 ret;
+
+ ret = 0;
+ if (reg & FM801_GPIO_GP(gpio.data))
+ ret |= TEA575X_DATA;
+ if (reg & FM801_GPIO_GP(gpio.most))
+ ret |= TEA575X_MOST;
+ return ret;
}
static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output)
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 70d4848b5cd..d010de12335 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -95,6 +95,7 @@ int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset)
EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
#ifdef CONFIG_PM
+#define codec_in_pm(codec) ((codec)->in_pm)
static void hda_power_work(struct work_struct *work);
static void hda_keep_power_on(struct hda_codec *codec);
#define hda_codec_is_power_on(codec) ((codec)->power_on)
@@ -104,6 +105,7 @@ static inline void hda_call_pm_notify(struct hda_bus *bus, bool power_up)
bus->ops.pm_notify(bus, power_up);
}
#else
+#define codec_in_pm(codec) 0
static inline void hda_keep_power_on(struct hda_codec *codec) {}
#define hda_codec_is_power_on(codec) 1
#define hda_call_pm_notify(bus, state) {}
@@ -228,7 +230,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
}
mutex_unlock(&bus->cmd_mutex);
snd_hda_power_down(codec);
- if (res && *res == -1 && bus->rirb_error) {
+ if (!codec_in_pm(codec) && res && *res == -1 && bus->rirb_error) {
if (bus->response_reset) {
snd_printd("hda_codec: resetting BUS due to "
"fatal communication error\n");
@@ -238,7 +240,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
goto again;
}
/* clear reset-flag when the communication gets recovered */
- if (!err)
+ if (!err || codec_in_pm(codec))
bus->response_reset = 0;
return err;
}
@@ -3616,6 +3618,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq)
{
unsigned int state;
+ codec->in_pm = 1;
+
if (codec->patch_ops.suspend)
codec->patch_ops.suspend(codec);
hda_cleanup_all_streams(codec);
@@ -3630,6 +3634,7 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq)
codec->power_transition = 0;
codec->power_jiffies = jiffies;
spin_unlock(&codec->power_lock);
+ codec->in_pm = 0;
return state;
}
@@ -3638,6 +3643,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq)
*/
static void hda_call_codec_resume(struct hda_codec *codec)
{
+ codec->in_pm = 1;
+
/* set as if powered on for avoiding re-entering the resume
* in the resume / power-save sequence
*/
@@ -3656,6 +3663,8 @@ static void hda_call_codec_resume(struct hda_codec *codec)
snd_hda_codec_resume_cache(codec);
}
snd_hda_jack_report_sync(codec);
+
+ codec->in_pm = 0;
snd_hda_power_down(codec); /* flag down before returning */
}
#endif /* CONFIG_PM */
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 507fe8a917b..4f4e545c0f4 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -869,6 +869,7 @@ struct hda_codec {
unsigned int power_on :1; /* current (global) power-state */
unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */
unsigned int pm_down_notified:1; /* PM notified to controller */
+ unsigned int in_pm:1; /* suspend/resume being performed */
int power_transition; /* power-state in transition */
int power_count; /* current (global) power refcount */
struct delayed_work power_work; /* delayed task for powerdown */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index cd2dbaf1be7..f9d870e554d 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -556,6 +556,12 @@ enum {
#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */
#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */
#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */
+#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */
+
+/* quirks for Intel PCH */
+#define AZX_DCAPS_INTEL_PCH \
+ (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_BUFSIZE | \
+ AZX_DCAPS_COUNT_LPIB_DELAY | AZX_DCAPS_PM_RUNTIME)
/* quirks for ATI SB / AMD Hudson */
#define AZX_DCAPS_PRESET_ATI_SB \
@@ -2433,6 +2439,9 @@ static void azx_power_notify(struct hda_bus *bus, bool power_up)
{
struct azx *chip = bus->private_data;
+ if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
+ return;
+
if (power_up)
pm_runtime_get_sync(&chip->pci->dev);
else
@@ -2548,7 +2557,8 @@ static int azx_runtime_suspend(struct device *dev)
struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip = card->private_data;
- if (!power_save_controller)
+ if (!power_save_controller ||
+ !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
return -EAGAIN;
azx_stop_chip(chip);
@@ -3429,39 +3439,30 @@ static void __devexit azx_remove(struct pci_dev *pci)
static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
/* CPT */
{ PCI_DEVICE(0x8086, 0x1c20),
- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
/* PBG */
{ PCI_DEVICE(0x8086, 0x1d20),
- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE},
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
/* Panther Point */
{ PCI_DEVICE(0x8086, 0x1e20),
- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
/* Lynx Point */
{ PCI_DEVICE(0x8086, 0x8c20),
- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
/* Lynx Point-LP */
{ PCI_DEVICE(0x8086, 0x9c20),
- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
/* Lynx Point-LP */
{ PCI_DEVICE(0x8086, 0x9c21),
- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
/* Haswell */
{ PCI_DEVICE(0x8086, 0x0c0c),
- .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+ .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH },
{ PCI_DEVICE(0x8086, 0x0d0c),
- .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+ .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH },
/* 5 Series/3400 */
{ PCI_DEVICE(0x8086, 0x3b56),
- .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+ .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH },
/* SCH */
{ PCI_DEVICE(0x8086, 0x811b),
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index d5f3a26d608..3bcb6717235 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -466,6 +466,7 @@ static int parse_output(struct hda_codec *codec)
memcpy(cfg->speaker_pins, cfg->line_out_pins,
sizeof(cfg->speaker_pins));
cfg->line_outs = 0;
+ memset(cfg->line_out_pins, 0, sizeof(cfg->line_out_pins));
}
return 0;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index c0ce3b1f04b..ad68d223f8a 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5407,6 +5407,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO),
+ SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF),
@@ -7064,6 +7065,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
{ .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
{ .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 },
{ .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
+ { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 },
{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
.patch = patch_alc861 },
{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index c03b65af305..054967d8bac 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -268,7 +268,7 @@ EXPORT_SYMBOL_GPL(arizona_out_ev);
static unsigned int arizona_sysclk_48k_rates[] = {
6144000,
12288000,
- 22579200,
+ 24576000,
49152000,
73728000,
98304000,
@@ -278,7 +278,7 @@ static unsigned int arizona_sysclk_48k_rates[] = {
static unsigned int arizona_sysclk_44k1_rates[] = {
5644800,
11289600,
- 24576000,
+ 22579200,
45158400,
67737600,
90316800,
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index f994af34f55..e3f0a7f3131 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -485,7 +485,7 @@ static int cs4271_probe(struct snd_soc_codec *codec)
gpio_nreset = cs4271plat->gpio_nreset;
if (gpio_nreset >= 0)
- if (gpio_request(gpio_nreset, "CS4271 Reset"))
+ if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset"))
gpio_nreset = -EINVAL;
if (gpio_nreset >= 0) {
/* Reset codec */
@@ -535,15 +535,10 @@ static int cs4271_probe(struct snd_soc_codec *codec)
static int cs4271_remove(struct snd_soc_codec *codec)
{
struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
- int gpio_nreset;
- gpio_nreset = cs4271->gpio_nreset;
-
- if (gpio_is_valid(gpio_nreset)) {
+ if (gpio_is_valid(cs4271->gpio_nreset))
/* Set codec to the reset state */
- gpio_set_value(gpio_nreset, 0);
- gpio_free(gpio_nreset);
- }
+ gpio_set_value(cs4271->gpio_nreset, 0);
return 0;
};
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index 4d8db3685e9..97a81051e88 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -773,7 +773,6 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
{
struct snd_soc_codec *codec = codec_dai->codec;
struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
u8 iface = 0;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -822,7 +821,7 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
case SND_SOC_DAIFMT_NB_IF:
break;
default:
- ret = -EINVAL;
+ return -EINVAL;
}
cs42l52->config.format = iface;
snd_soc_write(codec, CS42L52_IFACE_CTL1, cs42l52->config.format);
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 1722b586bdb..7394e73fa43 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -42,6 +42,556 @@ static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0);
+static const struct reg_default wm5102_sysclk_reva_patch[] = {
+ { 0x3000, 0x2225 },
+ { 0x3001, 0x3a03 },
+ { 0x3002, 0x0225 },
+ { 0x3003, 0x0801 },
+ { 0x3004, 0x6249 },
+ { 0x3005, 0x0c04 },
+ { 0x3006, 0x0225 },
+ { 0x3007, 0x5901 },
+ { 0x3008, 0xe249 },
+ { 0x3009, 0x030d },
+ { 0x300a, 0x0249 },
+ { 0x300b, 0x2c01 },
+ { 0x300c, 0xe249 },
+ { 0x300d, 0x4342 },
+ { 0x300e, 0xe249 },
+ { 0x300f, 0x73c0 },
+ { 0x3010, 0x4249 },
+ { 0x3011, 0x0c00 },
+ { 0x3012, 0x0225 },
+ { 0x3013, 0x1f01 },
+ { 0x3014, 0x0225 },
+ { 0x3015, 0x1e01 },
+ { 0x3016, 0x0225 },
+ { 0x3017, 0xfa00 },
+ { 0x3018, 0x0000 },
+ { 0x3019, 0xf000 },
+ { 0x301a, 0x0000 },
+ { 0x301b, 0xf000 },
+ { 0x301c, 0x0000 },
+ { 0x301d, 0xf000 },
+ { 0x301e, 0x0000 },
+ { 0x301f, 0xf000 },
+ { 0x3020, 0x0000 },
+ { 0x3021, 0xf000 },
+ { 0x3022, 0x0000 },
+ { 0x3023, 0xf000 },
+ { 0x3024, 0x0000 },
+ { 0x3025, 0xf000 },
+ { 0x3026, 0x0000 },
+ { 0x3027, 0xf000 },
+ { 0x3028, 0x0000 },
+ { 0x3029, 0xf000 },
+ { 0x302a, 0x0000 },
+ { 0x302b, 0xf000 },
+ { 0x302c, 0x0000 },
+ { 0x302d, 0xf000 },
+ { 0x302e, 0x0000 },
+ { 0x302f, 0xf000 },
+ { 0x3030, 0x0225 },
+ { 0x3031, 0x1a01 },
+ { 0x3032, 0x0225 },
+ { 0x3033, 0x1e00 },
+ { 0x3034, 0x0225 },
+ { 0x3035, 0x1f00 },
+ { 0x3036, 0x6225 },
+ { 0x3037, 0xf800 },
+ { 0x3038, 0x0000 },
+ { 0x3039, 0xf000 },
+ { 0x303a, 0x0000 },
+ { 0x303b, 0xf000 },
+ { 0x303c, 0x0000 },
+ { 0x303d, 0xf000 },
+ { 0x303e, 0x0000 },
+ { 0x303f, 0xf000 },
+ { 0x3040, 0x2226 },
+ { 0x3041, 0x3a03 },
+ { 0x3042, 0x0226 },
+ { 0x3043, 0x0801 },
+ { 0x3044, 0x6249 },
+ { 0x3045, 0x0c06 },
+ { 0x3046, 0x0226 },
+ { 0x3047, 0x5901 },
+ { 0x3048, 0xe249 },
+ { 0x3049, 0x030d },
+ { 0x304a, 0x0249 },
+ { 0x304b, 0x2c01 },
+ { 0x304c, 0xe249 },
+ { 0x304d, 0x4342 },
+ { 0x304e, 0xe249 },
+ { 0x304f, 0x73c0 },
+ { 0x3050, 0x4249 },
+ { 0x3051, 0x0c00 },
+ { 0x3052, 0x0226 },
+ { 0x3053, 0x1f01 },
+ { 0x3054, 0x0226 },
+ { 0x3055, 0x1e01 },
+ { 0x3056, 0x0226 },
+ { 0x3057, 0xfa00 },
+ { 0x3058, 0x0000 },
+ { 0x3059, 0xf000 },
+ { 0x305a, 0x0000 },
+ { 0x305b, 0xf000 },
+ { 0x305c, 0x0000 },
+ { 0x305d, 0xf000 },
+ { 0x305e, 0x0000 },
+ { 0x305f, 0xf000 },
+ { 0x3060, 0x0000 },
+ { 0x3061, 0xf000 },
+ { 0x3062, 0x0000 },
+ { 0x3063, 0xf000 },
+ { 0x3064, 0x0000 },
+ { 0x3065, 0xf000 },
+ { 0x3066, 0x0000 },
+ { 0x3067, 0xf000 },
+ { 0x3068, 0x0000 },
+ { 0x3069, 0xf000 },
+ { 0x306a, 0x0000 },
+ { 0x306b, 0xf000 },
+ { 0x306c, 0x0000 },
+ { 0x306d, 0xf000 },
+ { 0x306e, 0x0000 },
+ { 0x306f, 0xf000 },
+ { 0x3070, 0x0226 },
+ { 0x3071, 0x1a01 },
+ { 0x3072, 0x0226 },
+ { 0x3073, 0x1e00 },
+ { 0x3074, 0x0226 },
+ { 0x3075, 0x1f00 },
+ { 0x3076, 0x6226 },
+ { 0x3077, 0xf800 },
+ { 0x3078, 0x0000 },
+ { 0x3079, 0xf000 },
+ { 0x307a, 0x0000 },
+ { 0x307b, 0xf000 },
+ { 0x307c, 0x0000 },
+ { 0x307d, 0xf000 },
+ { 0x307e, 0x0000 },
+ { 0x307f, 0xf000 },
+ { 0x3080, 0x2227 },
+ { 0x3081, 0x3a03 },
+ { 0x3082, 0x0227 },
+ { 0x3083, 0x0801 },
+ { 0x3084, 0x6255 },
+ { 0x3085, 0x0c04 },
+ { 0x3086, 0x0227 },
+ { 0x3087, 0x5901 },
+ { 0x3088, 0xe255 },
+ { 0x3089, 0x030d },
+ { 0x308a, 0x0255 },
+ { 0x308b, 0x2c01 },
+ { 0x308c, 0xe255 },
+ { 0x308d, 0x4342 },
+ { 0x308e, 0xe255 },
+ { 0x308f, 0x73c0 },
+ { 0x3090, 0x4255 },
+ { 0x3091, 0x0c00 },
+ { 0x3092, 0x0227 },
+ { 0x3093, 0x1f01 },
+ { 0x3094, 0x0227 },
+ { 0x3095, 0x1e01 },
+ { 0x3096, 0x0227 },
+ { 0x3097, 0xfa00 },
+ { 0x3098, 0x0000 },
+ { 0x3099, 0xf000 },
+ { 0x309a, 0x0000 },
+ { 0x309b, 0xf000 },
+ { 0x309c, 0x0000 },
+ { 0x309d, 0xf000 },
+ { 0x309e, 0x0000 },
+ { 0x309f, 0xf000 },
+ { 0x30a0, 0x0000 },
+ { 0x30a1, 0xf000 },
+ { 0x30a2, 0x0000 },
+ { 0x30a3, 0xf000 },
+ { 0x30a4, 0x0000 },
+ { 0x30a5, 0xf000 },
+ { 0x30a6, 0x0000 },
+ { 0x30a7, 0xf000 },
+ { 0x30a8, 0x0000 },
+ { 0x30a9, 0xf000 },
+ { 0x30aa, 0x0000 },
+ { 0x30ab, 0xf000 },
+ { 0x30ac, 0x0000 },
+ { 0x30ad, 0xf000 },
+ { 0x30ae, 0x0000 },
+ { 0x30af, 0xf000 },
+ { 0x30b0, 0x0227 },
+ { 0x30b1, 0x1a01 },
+ { 0x30b2, 0x0227 },
+ { 0x30b3, 0x1e00 },
+ { 0x30b4, 0x0227 },
+ { 0x30b5, 0x1f00 },
+ { 0x30b6, 0x6227 },
+ { 0x30b7, 0xf800 },
+ { 0x30b8, 0x0000 },
+ { 0x30b9, 0xf000 },
+ { 0x30ba, 0x0000 },
+ { 0x30bb, 0xf000 },
+ { 0x30bc, 0x0000 },
+ { 0x30bd, 0xf000 },
+ { 0x30be, 0x0000 },
+ { 0x30bf, 0xf000 },
+ { 0x30c0, 0x2228 },
+ { 0x30c1, 0x3a03 },
+ { 0x30c2, 0x0228 },
+ { 0x30c3, 0x0801 },
+ { 0x30c4, 0x6255 },
+ { 0x30c5, 0x0c06 },
+ { 0x30c6, 0x0228 },
+ { 0x30c7, 0x5901 },
+ { 0x30c8, 0xe255 },
+ { 0x30c9, 0x030d },
+ { 0x30ca, 0x0255 },
+ { 0x30cb, 0x2c01 },
+ { 0x30cc, 0xe255 },
+ { 0x30cd, 0x4342 },
+ { 0x30ce, 0xe255 },
+ { 0x30cf, 0x73c0 },
+ { 0x30d0, 0x4255 },
+ { 0x30d1, 0x0c00 },
+ { 0x30d2, 0x0228 },
+ { 0x30d3, 0x1f01 },
+ { 0x30d4, 0x0228 },
+ { 0x30d5, 0x1e01 },
+ { 0x30d6, 0x0228 },
+ { 0x30d7, 0xfa00 },
+ { 0x30d8, 0x0000 },
+ { 0x30d9, 0xf000 },
+ { 0x30da, 0x0000 },
+ { 0x30db, 0xf000 },
+ { 0x30dc, 0x0000 },
+ { 0x30dd, 0xf000 },
+ { 0x30de, 0x0000 },
+ { 0x30df, 0xf000 },
+ { 0x30e0, 0x0000 },
+ { 0x30e1, 0xf000 },
+ { 0x30e2, 0x0000 },
+ { 0x30e3, 0xf000 },
+ { 0x30e4, 0x0000 },
+ { 0x30e5, 0xf000 },
+ { 0x30e6, 0x0000 },
+ { 0x30e7, 0xf000 },
+ { 0x30e8, 0x0000 },
+ { 0x30e9, 0xf000 },
+ { 0x30ea, 0x0000 },
+ { 0x30eb, 0xf000 },
+ { 0x30ec, 0x0000 },
+ { 0x30ed, 0xf000 },
+ { 0x30ee, 0x0000 },
+ { 0x30ef, 0xf000 },
+ { 0x30f0, 0x0228 },
+ { 0x30f1, 0x1a01 },
+ { 0x30f2, 0x0228 },
+ { 0x30f3, 0x1e00 },
+ { 0x30f4, 0x0228 },
+ { 0x30f5, 0x1f00 },
+ { 0x30f6, 0x6228 },
+ { 0x30f7, 0xf800 },
+ { 0x30f8, 0x0000 },
+ { 0x30f9, 0xf000 },
+ { 0x30fa, 0x0000 },
+ { 0x30fb, 0xf000 },
+ { 0x30fc, 0x0000 },
+ { 0x30fd, 0xf000 },
+ { 0x30fe, 0x0000 },
+ { 0x30ff, 0xf000 },
+ { 0x3100, 0x222b },
+ { 0x3101, 0x3a03 },
+ { 0x3102, 0x222b },
+ { 0x3103, 0x5803 },
+ { 0x3104, 0xe26f },
+ { 0x3105, 0x030d },
+ { 0x3106, 0x626f },
+ { 0x3107, 0x2c01 },
+ { 0x3108, 0xe26f },
+ { 0x3109, 0x4342 },
+ { 0x310a, 0xe26f },
+ { 0x310b, 0x73c0 },
+ { 0x310c, 0x026f },
+ { 0x310d, 0x0c00 },
+ { 0x310e, 0x022b },
+ { 0x310f, 0x1f01 },
+ { 0x3110, 0x022b },
+ { 0x3111, 0x1e01 },
+ { 0x3112, 0x022b },
+ { 0x3113, 0xfa00 },
+ { 0x3114, 0x0000 },
+ { 0x3115, 0xf000 },
+ { 0x3116, 0x0000 },
+ { 0x3117, 0xf000 },
+ { 0x3118, 0x0000 },
+ { 0x3119, 0xf000 },
+ { 0x311a, 0x0000 },
+ { 0x311b, 0xf000 },
+ { 0x311c, 0x0000 },
+ { 0x311d, 0xf000 },
+ { 0x311e, 0x0000 },
+ { 0x311f, 0xf000 },
+ { 0x3120, 0x022b },
+ { 0x3121, 0x0a01 },
+ { 0x3122, 0x022b },
+ { 0x3123, 0x1e00 },
+ { 0x3124, 0x022b },
+ { 0x3125, 0x1f00 },
+ { 0x3126, 0x622b },
+ { 0x3127, 0xf800 },
+ { 0x3128, 0x0000 },
+ { 0x3129, 0xf000 },
+ { 0x312a, 0x0000 },
+ { 0x312b, 0xf000 },
+ { 0x312c, 0x0000 },
+ { 0x312d, 0xf000 },
+ { 0x312e, 0x0000 },
+ { 0x312f, 0xf000 },
+ { 0x3130, 0x0000 },
+ { 0x3131, 0xf000 },
+ { 0x3132, 0x0000 },
+ { 0x3133, 0xf000 },
+ { 0x3134, 0x0000 },
+ { 0x3135, 0xf000 },
+ { 0x3136, 0x0000 },
+ { 0x3137, 0xf000 },
+ { 0x3138, 0x0000 },
+ { 0x3139, 0xf000 },
+ { 0x313a, 0x0000 },
+ { 0x313b, 0xf000 },
+ { 0x313c, 0x0000 },
+ { 0x313d, 0xf000 },
+ { 0x313e, 0x0000 },
+ { 0x313f, 0xf000 },
+ { 0x3140, 0x0000 },
+ { 0x3141, 0xf000 },
+ { 0x3142, 0x0000 },
+ { 0x3143, 0xf000 },
+ { 0x3144, 0x0000 },
+ { 0x3145, 0xf000 },
+ { 0x3146, 0x0000 },
+ { 0x3147, 0xf000 },
+ { 0x3148, 0x0000 },
+ { 0x3149, 0xf000 },
+ { 0x314a, 0x0000 },
+ { 0x314b, 0xf000 },
+ { 0x314c, 0x0000 },
+ { 0x314d, 0xf000 },
+ { 0x314e, 0x0000 },
+ { 0x314f, 0xf000 },
+ { 0x3150, 0x0000 },
+ { 0x3151, 0xf000 },
+ { 0x3152, 0x0000 },
+ { 0x3153, 0xf000 },
+ { 0x3154, 0x0000 },
+ { 0x3155, 0xf000 },
+ { 0x3156, 0x0000 },
+ { 0x3157, 0xf000 },
+ { 0x3158, 0x0000 },
+ { 0x3159, 0xf000 },
+ { 0x315a, 0x0000 },
+ { 0x315b, 0xf000 },
+ { 0x315c, 0x0000 },
+ { 0x315d, 0xf000 },
+ { 0x315e, 0x0000 },
+ { 0x315f, 0xf000 },
+ { 0x3160, 0x0000 },
+ { 0x3161, 0xf000 },
+ { 0x3162, 0x0000 },
+ { 0x3163, 0xf000 },
+ { 0x3164, 0x0000 },
+ { 0x3165, 0xf000 },
+ { 0x3166, 0x0000 },
+ { 0x3167, 0xf000 },
+ { 0x3168, 0x0000 },
+ { 0x3169, 0xf000 },
+ { 0x316a, 0x0000 },
+ { 0x316b, 0xf000 },
+ { 0x316c, 0x0000 },
+ { 0x316d, 0xf000 },
+ { 0x316e, 0x0000 },
+ { 0x316f, 0xf000 },
+ { 0x3170, 0x0000 },
+ { 0x3171, 0xf000 },
+ { 0x3172, 0x0000 },
+ { 0x3173, 0xf000 },
+ { 0x3174, 0x0000 },
+ { 0x3175, 0xf000 },
+ { 0x3176, 0x0000 },
+ { 0x3177, 0xf000 },
+ { 0x3178, 0x0000 },
+ { 0x3179, 0xf000 },
+ { 0x317a, 0x0000 },
+ { 0x317b, 0xf000 },
+ { 0x317c, 0x0000 },
+ { 0x317d, 0xf000 },
+ { 0x317e, 0x0000 },
+ { 0x317f, 0xf000 },
+ { 0x3180, 0x2001 },
+ { 0x3181, 0xf101 },
+ { 0x3182, 0x0000 },
+ { 0x3183, 0xf000 },
+ { 0x3184, 0x0000 },
+ { 0x3185, 0xf000 },
+ { 0x3186, 0x0000 },
+ { 0x3187, 0xf000 },
+ { 0x3188, 0x0000 },
+ { 0x3189, 0xf000 },
+ { 0x318a, 0x0000 },
+ { 0x318b, 0xf000 },
+ { 0x318c, 0x0000 },
+ { 0x318d, 0xf000 },
+ { 0x318e, 0x0000 },
+ { 0x318f, 0xf000 },
+ { 0x3190, 0x0000 },
+ { 0x3191, 0xf000 },
+ { 0x3192, 0x0000 },
+ { 0x3193, 0xf000 },
+ { 0x3194, 0x0000 },
+ { 0x3195, 0xf000 },
+ { 0x3196, 0x0000 },
+ { 0x3197, 0xf000 },
+ { 0x3198, 0x0000 },
+ { 0x3199, 0xf000 },
+ { 0x319a, 0x0000 },
+ { 0x319b, 0xf000 },
+ { 0x319c, 0x0000 },
+ { 0x319d, 0xf000 },
+ { 0x319e, 0x0000 },
+ { 0x319f, 0xf000 },
+ { 0x31a0, 0x0000 },
+ { 0x31a1, 0xf000 },
+ { 0x31a2, 0x0000 },
+ { 0x31a3, 0xf000 },
+ { 0x31a4, 0x0000 },
+ { 0x31a5, 0xf000 },
+ { 0x31a6, 0x0000 },
+ { 0x31a7, 0xf000 },
+ { 0x31a8, 0x0000 },
+ { 0x31a9, 0xf000 },
+ { 0x31aa, 0x0000 },
+ { 0x31ab, 0xf000 },
+ { 0x31ac, 0x0000 },
+ { 0x31ad, 0xf000 },
+ { 0x31ae, 0x0000 },
+ { 0x31af, 0xf000 },
+ { 0x31b0, 0x0000 },
+ { 0x31b1, 0xf000 },
+ { 0x31b2, 0x0000 },
+ { 0x31b3, 0xf000 },
+ { 0x31b4, 0x0000 },
+ { 0x31b5, 0xf000 },
+ { 0x31b6, 0x0000 },
+ { 0x31b7, 0xf000 },
+ { 0x31b8, 0x0000 },
+ { 0x31b9, 0xf000 },
+ { 0x31ba, 0x0000 },
+ { 0x31bb, 0xf000 },
+ { 0x31bc, 0x0000 },
+ { 0x31bd, 0xf000 },
+ { 0x31be, 0x0000 },
+ { 0x31bf, 0xf000 },
+ { 0x31c0, 0x0000 },
+ { 0x31c1, 0xf000 },
+ { 0x31c2, 0x0000 },
+ { 0x31c3, 0xf000 },
+ { 0x31c4, 0x0000 },
+ { 0x31c5, 0xf000 },
+ { 0x31c6, 0x0000 },
+ { 0x31c7, 0xf000 },
+ { 0x31c8, 0x0000 },
+ { 0x31c9, 0xf000 },
+ { 0x31ca, 0x0000 },
+ { 0x31cb, 0xf000 },
+ { 0x31cc, 0x0000 },
+ { 0x31cd, 0xf000 },
+ { 0x31ce, 0x0000 },
+ { 0x31cf, 0xf000 },
+ { 0x31d0, 0x0000 },
+ { 0x31d1, 0xf000 },
+ { 0x31d2, 0x0000 },
+ { 0x31d3, 0xf000 },
+ { 0x31d4, 0x0000 },
+ { 0x31d5, 0xf000 },
+ { 0x31d6, 0x0000 },
+ { 0x31d7, 0xf000 },
+ { 0x31d8, 0x0000 },
+ { 0x31d9, 0xf000 },
+ { 0x31da, 0x0000 },
+ { 0x31db, 0xf000 },
+ { 0x31dc, 0x0000 },
+ { 0x31dd, 0xf000 },
+ { 0x31de, 0x0000 },
+ { 0x31df, 0xf000 },
+ { 0x31e0, 0x0000 },
+ { 0x31e1, 0xf000 },
+ { 0x31e2, 0x0000 },
+ { 0x31e3, 0xf000 },
+ { 0x31e4, 0x0000 },
+ { 0x31e5, 0xf000 },
+ { 0x31e6, 0x0000 },
+ { 0x31e7, 0xf000 },
+ { 0x31e8, 0x0000 },
+ { 0x31e9, 0xf000 },
+ { 0x31ea, 0x0000 },
+ { 0x31eb, 0xf000 },
+ { 0x31ec, 0x0000 },
+ { 0x31ed, 0xf000 },
+ { 0x31ee, 0x0000 },
+ { 0x31ef, 0xf000 },
+ { 0x31f0, 0x0000 },
+ { 0x31f1, 0xf000 },
+ { 0x31f2, 0x0000 },
+ { 0x31f3, 0xf000 },
+ { 0x31f4, 0x0000 },
+ { 0x31f5, 0xf000 },
+ { 0x31f6, 0x0000 },
+ { 0x31f7, 0xf000 },
+ { 0x31f8, 0x0000 },
+ { 0x31f9, 0xf000 },
+ { 0x31fa, 0x0000 },
+ { 0x31fb, 0xf000 },
+ { 0x31fc, 0x0000 },
+ { 0x31fd, 0xf000 },
+ { 0x31fe, 0x0000 },
+ { 0x31ff, 0xf000 },
+ { 0x024d, 0xff50 },
+ { 0x0252, 0xff50 },
+ { 0x0259, 0x0112 },
+ { 0x025e, 0x0112 },
+};
+
+static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct arizona *arizona = dev_get_drvdata(codec->dev);
+ struct regmap *regmap = codec->control_data;
+ const struct reg_default *patch = NULL;
+ int i, patch_size;
+
+ switch (arizona->rev) {
+ case 0:
+ patch = wm5102_sysclk_reva_patch;
+ patch_size = ARRAY_SIZE(wm5102_sysclk_reva_patch);
+ break;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ if (patch)
+ for (i = 0; i < patch_size; i++)
+ regmap_write(regmap, patch[i].reg,
+ patch[i].def);
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static const struct snd_kcontrol_new wm5102_snd_controls[] = {
SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL,
ARIZONA_IN1_OSR_SHIFT, 1, 0),
@@ -297,7 +847,7 @@ static const struct snd_kcontrol_new wm5102_aec_loopback_mux =
static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
- 0, NULL, 0),
+ 0, wm5102_sysclk_ev, SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 5421fd9fbcb..4c0a8e49613 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -782,7 +782,7 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream,
wm8978->mclk_idx = -1;
f_sel = wm8978->f_mclk;
} else {
- if (!wm8978->f_pllout) {
+ if (!wm8978->f_opclk) {
/* We only enter here, if OPCLK is not used */
int ret = wm8978_configure_pll(codec);
if (ret < 0)
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
index b9f16598324..2ba08148655 100644
--- a/sound/soc/kirkwood/kirkwood-dma.c
+++ b/sound/soc/kirkwood/kirkwood-dma.c
@@ -71,7 +71,6 @@ static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id)
printk(KERN_WARNING "%s: got err interrupt 0x%lx\n",
__func__, cause);
writel(cause, priv->io + KIRKWOOD_ERR_CAUSE);
- return IRQ_HANDLED;
}
/* we've enabled only bytes interrupts ... */
@@ -178,7 +177,7 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream)
}
dram = mv_mbus_dram_info();
- addr = virt_to_phys(substream->dma_buffer.area);
+ addr = substream->dma_buffer.addr;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
prdata->play_stream = substream;
kirkwood_dma_conf_mbus_windows(priv->io,
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index 542538d10ab..1d5db484d2d 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -95,7 +95,7 @@ static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate)
do {
cpu_relax();
value = readl(io + KIRKWOOD_DCO_SPCR_STATUS);
- value &= KIRKWOOD_DCO_SPCR_STATUS;
+ value &= KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK;
} while (value == 0);
}
@@ -180,67 +180,72 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
- unsigned long value;
-
- /*
- * specs says KIRKWOOD_PLAYCTL must be read 2 times before
- * changing it. So read 1 time here and 1 later.
- */
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
+ uint32_t ctl, value;
+
+ ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
+ if (ctl & KIRKWOOD_PLAYCTL_PAUSE) {
+ unsigned timeout = 5000;
+ /*
+ * The Armada510 spec says that if we enter pause mode, the
+ * busy bit must be read back as clear _twice_. Make sure
+ * we respect that otherwise we get DMA underruns.
+ */
+ do {
+ value = ctl;
+ ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
+ if (!((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY))
+ break;
+ udelay(1);
+ } while (timeout--);
+
+ if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY)
+ dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n",
+ ctl);
+ }
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- /* stop audio, enable interrupts */
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
- value |= KIRKWOOD_PLAYCTL_PAUSE;
- writel(value, priv->io + KIRKWOOD_PLAYCTL);
-
value = readl(priv->io + KIRKWOOD_INT_MASK);
value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES;
writel(value, priv->io + KIRKWOOD_INT_MASK);
/* configure audio & enable i2s playback */
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
- value &= ~KIRKWOOD_PLAYCTL_BURST_MASK;
- value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE
+ ctl &= ~KIRKWOOD_PLAYCTL_BURST_MASK;
+ ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE
| KIRKWOOD_PLAYCTL_SPDIF_EN);
if (priv->burst == 32)
- value |= KIRKWOOD_PLAYCTL_BURST_32;
+ ctl |= KIRKWOOD_PLAYCTL_BURST_32;
else
- value |= KIRKWOOD_PLAYCTL_BURST_128;
- value |= KIRKWOOD_PLAYCTL_I2S_EN;
- writel(value, priv->io + KIRKWOOD_PLAYCTL);
+ ctl |= KIRKWOOD_PLAYCTL_BURST_128;
+ ctl |= KIRKWOOD_PLAYCTL_I2S_EN;
+ writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
break;
case SNDRV_PCM_TRIGGER_STOP:
/* stop audio, disable interrupts */
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
- value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
- writel(value, priv->io + KIRKWOOD_PLAYCTL);
+ ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
+ writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
value = readl(priv->io + KIRKWOOD_INT_MASK);
value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES;
writel(value, priv->io + KIRKWOOD_INT_MASK);
/* disable all playbacks */
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
- value &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN);
- writel(value, priv->io + KIRKWOOD_PLAYCTL);
+ ctl &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN);
+ writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
case SNDRV_PCM_TRIGGER_SUSPEND:
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
- value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
- writel(value, priv->io + KIRKWOOD_PLAYCTL);
+ ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
+ writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
break;
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
- value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE);
- writel(value, priv->io + KIRKWOOD_PLAYCTL);
+ ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE);
+ writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
break;
default:
@@ -260,11 +265,6 @@ static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- /* stop audio, enable interrupts */
- value = readl(priv->io + KIRKWOOD_RECCTL);
- value |= KIRKWOOD_RECCTL_PAUSE;
- writel(value, priv->io + KIRKWOOD_RECCTL);
-
value = readl(priv->io + KIRKWOOD_INT_MASK);
value |= KIRKWOOD_INT_CAUSE_REC_BYTES;
writel(value, priv->io + KIRKWOOD_INT_MASK);
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index aa037b292f3..c294fbb523f 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -523,16 +523,24 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
/*
- * write a data to saif data register to trigger
- * the transfer
+ * write data to saif data register to trigger
+ * the transfer.
+ * For 24-bit format the 32-bit FIFO register stores
+ * only one channel, so we need to write twice.
+ * This is also safe for the other non 24-bit formats.
*/
__raw_writel(0, saif->base + SAIF_DATA);
+ __raw_writel(0, saif->base + SAIF_DATA);
} else {
/*
- * read a data from saif data register to trigger
- * the receive
+ * read data from saif data register to trigger
+ * the receive.
+ * For 24-bit format the 32-bit FIFO register stores
+ * only one channel, so we need to read twice.
+ * This is also safe for the other non 24-bit formats.
*/
__raw_readl(saif->base + SAIF_DATA);
+ __raw_readl(saif->base + SAIF_DATA);
}
master_saif->ongoing = 1;
@@ -812,3 +820,4 @@ module_platform_driver(mxs_saif_driver);
MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("MXS ASoC SAIF driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mxs-saif");
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index e7b83179aca..3c7c3a59ed3 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -207,6 +207,8 @@ config SND_SOC_BELLS
select SND_SOC_WM5102
select SND_SOC_WM5110
select SND_SOC_WM9081
+ select SND_SOC_WM0010
+ select SND_SOC_WM1250_EV1
config SND_SOC_LOWLAND
tristate "Audio support for Wolfson Lowland"
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c
index b0d46d63d55..a2ca1567b9e 100644
--- a/sound/soc/samsung/bells.c
+++ b/sound/soc/samsung/bells.c
@@ -212,7 +212,7 @@ static struct snd_soc_dai_link bells_dai_wm5102[] = {
{
.name = "Sub",
.stream_name = "Sub",
- .cpu_dai_name = "wm5110-aif3",
+ .cpu_dai_name = "wm5102-aif3",
.codec_dai_name = "wm9081-hifi",
.codec_name = "wm9081.1-006c",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d1198627fc4..10d21be383f 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2786,8 +2786,9 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
val = (ucontrol->value.integer.value[0] + min) & mask;
val = val << shift;
- if (snd_soc_update_bits_locked(codec, reg, val_mask, val))
- return err;
+ err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
+ if (err < 0)
+ return err;
if (snd_soc_volsw_is_stereo(mc)) {
val_mask = mask << rshift;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index d0a4be38dc0..6e35bcae02d 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3745,7 +3745,7 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card)
{
struct snd_soc_codec *codec;
- list_for_each_entry(codec, &card->codec_dev_list, list) {
+ list_for_each_entry(codec, &card->codec_dev_list, card_list) {
soc_dapm_shutdown_codec(&codec->dapm);
if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
snd_soc_dapm_set_bias_level(&codec->dapm,
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 282f0fc9fed..dbf7999d18b 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -559,9 +559,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
return;
card = chip->card;
- mutex_lock(&register_mutex);
down_write(&chip->shutdown_rwsem);
chip->shutdown = 1;
+ up_write(&chip->shutdown_rwsem);
+
+ mutex_lock(&register_mutex);
chip->num_interfaces--;
if (chip->num_interfaces <= 0) {
snd_card_disconnect(card);
@@ -582,11 +584,9 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
snd_usb_mixer_disconnect(p);
}
usb_chip[chip->index] = NULL;
- up_write(&chip->shutdown_rwsem);
mutex_unlock(&register_mutex);
snd_card_free_when_closed(card);
} else {
- up_write(&chip->shutdown_rwsem);
mutex_unlock(&register_mutex);
}
}
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index c83f6143c0e..eeefbce3873 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -148,6 +148,7 @@ struct snd_usb_midi_out_endpoint {
struct snd_usb_midi_out_endpoint* ep;
struct snd_rawmidi_substream *substream;
int active;
+ bool autopm_reference;
uint8_t cable; /* cable number << 4 */
uint8_t state;
#define STATE_UNKNOWN 0
@@ -1076,7 +1077,8 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
return -ENXIO;
}
err = usb_autopm_get_interface(umidi->iface);
- if (err < 0)
+ port->autopm_reference = err >= 0;
+ if (err < 0 && err != -EACCES)
return -EIO;
substream->runtime->private_data = port;
port->state = STATE_UNKNOWN;
@@ -1087,9 +1089,11 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream)
{
struct snd_usb_midi* umidi = substream->rmidi->private_data;
+ struct usbmidi_out_port *port = substream->runtime->private_data;
substream_open(substream, 0);
- usb_autopm_put_interface(umidi->iface);
+ if (port->autopm_reference)
+ usb_autopm_put_interface(umidi->iface);
return 0;
}
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 5c12a3fe8c3..ef6fa24fc47 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -459,7 +459,7 @@ static int configure_endpoint(struct snd_usb_substream *subs)
return ret;
if (subs->sync_endpoint)
- ret = snd_usb_endpoint_set_params(subs->data_endpoint,
+ ret = snd_usb_endpoint_set_params(subs->sync_endpoint,
subs->pcm_format,
subs->channels,
subs->period_bytes,
diff --git a/tools/Makefile b/tools/Makefile
index 3ae43947a17..1f9a529fe54 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -31,44 +31,44 @@ help:
@echo ' clean: a summary clean target to clean _all_ folders'
cpupower: FORCE
- $(QUIET_SUBDIR0)power/$@/ $(QUIET_SUBDIR1)
+ $(call descend,power/$@)
firewire lguest perf usb virtio vm: FORCE
- $(QUIET_SUBDIR0)$@/ $(QUIET_SUBDIR1)
+ $(call descend,$@)
selftests: FORCE
- $(QUIET_SUBDIR0)testing/$@/ $(QUIET_SUBDIR1)
+ $(call descend,testing/$@)
turbostat x86_energy_perf_policy: FORCE
- $(QUIET_SUBDIR0)power/x86/$@/ $(QUIET_SUBDIR1)
+ $(call descend,power/x86/$@)
cpupower_install:
- $(QUIET_SUBDIR0)power/$(@:_install=)/ $(QUIET_SUBDIR1) install
+ $(call descend,power/$(@:_install=),install)
firewire_install lguest_install perf_install usb_install virtio_install vm_install:
- $(QUIET_SUBDIR0)$(@:_install=)/ $(QUIET_SUBDIR1) install
+ $(call descend,$(@:_install=),install)
selftests_install:
- $(QUIET_SUBDIR0)testing/$(@:_clean=)/ $(QUIET_SUBDIR1) install
+ $(call descend,testing/$(@:_clean=),install)
turbostat_install x86_energy_perf_policy_install:
- $(QUIET_SUBDIR0)power/x86/$(@:_install=)/ $(QUIET_SUBDIR1) install
+ $(call descend,power/x86/$(@:_install=),install)
install: cpupower_install firewire_install lguest_install perf_install \
selftests_install turbostat_install usb_install virtio_install \
vm_install x86_energy_perf_policy_install
cpupower_clean:
- $(QUIET_SUBDIR0)power/cpupower/ $(QUIET_SUBDIR1) clean
+ $(call descend,power/cpupower,clean)
firewire_clean lguest_clean perf_clean usb_clean virtio_clean vm_clean:
- $(QUIET_SUBDIR0)$(@:_clean=)/ $(QUIET_SUBDIR1) clean
+ $(call descend,$(@:_clean=),clean)
selftests_clean:
- $(QUIET_SUBDIR0)testing/$(@:_clean=)/ $(QUIET_SUBDIR1) clean
+ $(call descend,testing/$(@:_clean=),clean)
turbostat_clean x86_energy_perf_policy_clean:
- $(QUIET_SUBDIR0)power/x86/$(@:_clean=)/ $(QUIET_SUBDIR1) clean
+ $(call descend,power/x86/$(@:_clean=),clean)
clean: cpupower_clean firewire_clean lguest_clean perf_clean selftests_clean \
turbostat_clean usb_clean virtio_clean vm_clean \
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 5959affd882..d25a46925e6 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -43,6 +43,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
+#include <net/if.h>
/*
* KVP protocol: The user mode component first registers with the
@@ -88,6 +89,7 @@ static char *os_major = "";
static char *os_minor = "";
static char *processor_arch;
static char *os_build;
+static char *os_version;
static char *lic_version = "Unknown version";
static struct utsname uts_buf;
@@ -297,7 +299,7 @@ static int kvp_file_init(void)
return 0;
}
-static int kvp_key_delete(int pool, __u8 *key, int key_size)
+static int kvp_key_delete(int pool, const char *key, int key_size)
{
int i;
int j, k;
@@ -340,7 +342,7 @@ static int kvp_key_delete(int pool, __u8 *key, int key_size)
return 1;
}
-static int kvp_key_add_or_modify(int pool, __u8 *key, int key_size, __u8 *value,
+static int kvp_key_add_or_modify(int pool, const char *key, int key_size, const char *value,
int value_size)
{
int i;
@@ -394,7 +396,7 @@ static int kvp_key_add_or_modify(int pool, __u8 *key, int key_size, __u8 *value,
return 0;
}
-static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value,
+static int kvp_get_value(int pool, const char *key, int key_size, char *value,
int value_size)
{
int i;
@@ -426,8 +428,8 @@ static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value,
return 1;
}
-static int kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size,
- __u8 *value, int value_size)
+static int kvp_pool_enumerate(int pool, int index, char *key, int key_size,
+ char *value, int value_size)
{
struct kvp_record *record;
@@ -453,7 +455,9 @@ void kvp_get_os_info(void)
char *p, buf[512];
uname(&uts_buf);
- os_build = uts_buf.release;
+ os_version = uts_buf.release;
+ os_build = strdup(uts_buf.release);
+
os_name = uts_buf.sysname;
processor_arch = uts_buf.machine;
@@ -462,7 +466,7 @@ void kvp_get_os_info(void)
* string to be of the form: x.y.z
* Strip additional information we may have.
*/
- p = strchr(os_build, '-');
+ p = strchr(os_version, '-');
if (p)
*p = '\0';
@@ -879,7 +883,7 @@ static int kvp_process_ip_address(void *addrp,
addr_length = INET6_ADDRSTRLEN;
}
- if ((length - *offset) < addr_length + 1)
+ if ((length - *offset) < addr_length + 2)
return HV_E_FAIL;
if (str == NULL) {
strcpy(buffer, "inet_ntop failed\n");
@@ -887,11 +891,13 @@ static int kvp_process_ip_address(void *addrp,
}
if (*offset == 0)
strcpy(buffer, tmp);
- else
+ else {
+ strcat(buffer, ";");
strcat(buffer, tmp);
- strcat(buffer, ";");
+ }
*offset += strlen(str) + 1;
+
return 0;
}
@@ -953,7 +959,9 @@ kvp_get_ip_info(int family, char *if_name, int op,
* supported address families; if not we gather info on
* the specified address family.
*/
- if ((family != 0) && (curp->ifa_addr->sa_family != family)) {
+ if ((((family != 0) &&
+ (curp->ifa_addr->sa_family != family))) ||
+ (curp->ifa_flags & IFF_LOOPBACK)) {
curp = curp->ifa_next;
continue;
}
@@ -1478,13 +1486,19 @@ int main(void)
len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0,
addr_p, &addr_l);
- if (len < 0 || addr.nl_pid) {
+ if (len < 0) {
syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s",
addr.nl_pid, errno, strerror(errno));
close(fd);
return -1;
}
+ if (addr.nl_pid) {
+ syslog(LOG_WARNING, "Received packet from untrusted pid:%u",
+ addr.nl_pid);
+ continue;
+ }
+
incoming_msg = (struct nlmsghdr *)kvp_recv_buffer;
incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg);
hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data;
@@ -1649,7 +1663,7 @@ int main(void)
strcpy(key_name, "OSMinorVersion");
break;
case OSVersion:
- strcpy(key_value, os_build);
+ strcpy(key_value, os_version);
strcpy(key_name, "OSVersion");
break;
case ProcessorArchitecture:
diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 04d959fa022..a20e3203343 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -253,7 +253,7 @@ all_deps := $(all_objs:%.o=.%.d)
# let .d file also depends on the source and header files
define check_deps
@set -e; $(RM) $@; \
- $(CC) -M $(CFLAGS) $< > $@.$$$$; \
+ $(CC) -MM $(CFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
$(RM) $@.$$$$
endef
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index f2989c525e4..5a824e355d0 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -174,7 +174,7 @@ static int cmdline_init(struct pevent *pevent)
return 0;
}
-static char *find_cmdline(struct pevent *pevent, int pid)
+static const char *find_cmdline(struct pevent *pevent, int pid)
{
const struct cmdline *comm;
struct cmdline key;
@@ -2637,7 +2637,7 @@ process_func_handler(struct event_format *event, struct pevent_function_handler
struct print_arg *farg;
enum event_type type;
char *token;
- char *test;
+ const char *test;
int i;
arg->type = PRINT_FUNC;
@@ -3889,7 +3889,7 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
struct event_format *event, struct print_arg *arg)
{
unsigned char *buf;
- char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x";
+ const char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x";
if (arg->type == PRINT_FUNC) {
process_defined_func(s, data, size, event, arg);
@@ -3931,7 +3931,8 @@ static int is_printable_array(char *p, unsigned int len)
return 1;
}
-static void print_event_fields(struct trace_seq *s, void *data, int size,
+static void print_event_fields(struct trace_seq *s, void *data,
+ int size __maybe_unused,
struct event_format *event)
{
struct format_field *field;
@@ -4408,7 +4409,7 @@ void pevent_event_info(struct trace_seq *s, struct event_format *event,
void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
struct pevent_record *record)
{
- static char *spaces = " "; /* 20 spaces */
+ static const char *spaces = " "; /* 20 spaces */
struct event_format *event;
unsigned long secs;
unsigned long usecs;
@@ -5070,8 +5071,8 @@ static const char * const pevent_error_str[] = {
};
#undef _PE
-int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum,
- char *buf, size_t buflen)
+int pevent_strerror(struct pevent *pevent __maybe_unused,
+ enum pevent_errno errnum, char *buf, size_t buflen)
{
int idx;
const char *msg;
@@ -5100,6 +5101,7 @@ int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum,
case PEVENT_ERRNO__READ_FORMAT_FAILED:
case PEVENT_ERRNO__READ_PRINT_FAILED:
case PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED:
+ case PEVENT_ERRNO__INVALID_ARG_TYPE:
snprintf(buf, buflen, "%s", msg);
break;
@@ -5362,7 +5364,7 @@ int pevent_register_print_function(struct pevent *pevent,
if (type == PEVENT_FUNC_ARG_VOID)
break;
- if (type < 0 || type >= PEVENT_FUNC_ARG_MAX_TYPES) {
+ if (type >= PEVENT_FUNC_ARG_MAX_TYPES) {
do_warning("Invalid argument type %d", type);
ret = PEVENT_ERRNO__INVALID_ARG_TYPE;
goto out_free;
@@ -5560,7 +5562,7 @@ void pevent_free(struct pevent *pevent)
}
if (pevent->func_map) {
- for (i = 0; i < pevent->func_count; i++) {
+ for (i = 0; i < (int)pevent->func_count; i++) {
free(pevent->func_map[i].func);
free(pevent->func_map[i].mod);
}
@@ -5582,7 +5584,7 @@ void pevent_free(struct pevent *pevent)
}
if (pevent->printk_map) {
- for (i = 0; i < pevent->printk_count; i++)
+ for (i = 0; i < (int)pevent->printk_count; i++)
free(pevent->printk_map[i].printk);
free(pevent->printk_map);
}
diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile
index 9f2e44f2b17..ef6d22e879e 100644
--- a/tools/perf/Documentation/Makefile
+++ b/tools/perf/Documentation/Makefile
@@ -1,3 +1,5 @@
+include ../config/utilities.mak
+
OUTPUT := ./
ifeq ("$(origin O)", "command line")
ifneq ($(O),)
@@ -64,6 +66,7 @@ MAKEINFO=makeinfo
INSTALL_INFO=install-info
DOCBOOK2X_TEXI=docbook2x-texi
DBLATEX=dblatex
+XMLTO=xmlto
ifndef PERL_PATH
PERL_PATH = /usr/bin/perl
endif
@@ -71,6 +74,16 @@ endif
-include ../config.mak.autogen
-include ../config.mak
+_tmp_tool_path := $(call get-executable,$(ASCIIDOC))
+ifeq ($(_tmp_tool_path),)
+ missing_tools = $(ASCIIDOC)
+endif
+
+_tmp_tool_path := $(call get-executable,$(XMLTO))
+ifeq ($(_tmp_tool_path),)
+ missing_tools += $(XMLTO)
+endif
+
#
# For asciidoc ...
# -7.1.2, no extra settings are needed.
@@ -170,7 +183,12 @@ pdf: $(OUTPUT)user-manual.pdf
install: install-man
-install-man: man
+check-man-tools:
+ifdef missing_tools
+ $(error "You need to install $(missing_tools) for man pages")
+endif
+
+do-install-man: man
$(INSTALL) -d -m 755 $(DESTDIR)$(man1dir)
# $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir)
# $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir)
@@ -178,6 +196,15 @@ install-man: man
# $(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)
+else
+ $(MAKE) do-install-man
+endif
+
install-info: info
$(INSTALL) -d -m 755 $(DESTDIR)$(infodir)
$(INSTALL) -m 644 $(OUTPUT)perf.info $(OUTPUT)perfman.info $(DESTDIR)$(infodir)
@@ -246,7 +273,7 @@ $(MAN_HTML): $(OUTPUT)%.html : %.txt
$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml
$(QUIET_XMLTO)$(RM) $@ && \
- xmlto -o $(OUTPUT) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
+ $(XMLTO) -o $(OUTPUT) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
$(OUTPUT)%.xml : %.txt
$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
diff --git a/tools/perf/Documentation/android.txt b/tools/perf/Documentation/android.txt
new file mode 100644
index 00000000000..8484c3a04a6
--- /dev/null
+++ b/tools/perf/Documentation/android.txt
@@ -0,0 +1,78 @@
+How to compile perf for Android
+=========================================
+
+I. Set the Android NDK environment
+------------------------------------------------
+
+(a). Use the Android NDK
+------------------------------------------------
+1. You need to download and install the Android Native Development Kit (NDK).
+Set the NDK variable to point to the path where you installed the NDK:
+ export NDK=/path/to/android-ndk
+
+2. Set cross-compiling environment variables for NDK toolchain and sysroot.
+For arm:
+ export NDK_TOOLCHAIN=${NDK}/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-
+ export NDK_SYSROOT=${NDK}/platforms/android-9/arch-arm
+For x86:
+ export NDK_TOOLCHAIN=${NDK}/toolchains/x86-4.6/prebuilt/linux-x86/bin/i686-linux-android-
+ export NDK_SYSROOT=${NDK}/platforms/android-9/arch-x86
+
+This method is not working for Android NDK versions up to Revision 8b.
+perf uses some bionic enhancements that are not included in these NDK versions.
+You can use method (b) described below instead.
+
+(b). Use the Android source tree
+-----------------------------------------------
+1. Download the master branch of the Android source tree.
+Set the environment for the target you want using:
+ source build/envsetup.sh
+ lunch
+
+2. Build your own NDK sysroot to contain latest bionic changes and set the
+NDK sysroot environment variable.
+ cd ${ANDROID_BUILD_TOP}/ndk
+For arm:
+ ./build/tools/build-ndk-sysroot.sh --abi=arm
+ export NDK_SYSROOT=${ANDROID_BUILD_TOP}/ndk/build/platforms/android-3/arch-arm
+For x86:
+ ./build/tools/build-ndk-sysroot.sh --abi=x86
+ export NDK_SYSROOT=${ANDROID_BUILD_TOP}/ndk/build/platforms/android-3/arch-x86
+
+3. Set the NDK toolchain environment variable.
+For arm:
+ export NDK_TOOLCHAIN=${ANDROID_TOOLCHAIN}/arm-linux-androideabi-
+For x86:
+ export NDK_TOOLCHAIN=${ANDROID_TOOLCHAIN}/i686-linux-android-
+
+II. Compile perf for Android
+------------------------------------------------
+You need to run make with the NDK toolchain and sysroot defined above:
+For arm:
+ make ARCH=arm CROSS_COMPILE=${NDK_TOOLCHAIN} CFLAGS="--sysroot=${NDK_SYSROOT}"
+For x86:
+ make ARCH=x86 CROSS_COMPILE=${NDK_TOOLCHAIN} CFLAGS="--sysroot=${NDK_SYSROOT}"
+
+III. Install perf
+-----------------------------------------------
+You need to connect to your Android device/emulator using adb.
+Install perf using:
+ adb push perf /data/perf
+
+If you also want to use perf-archive you need busybox tools for Android.
+For installing perf-archive, you first need to replace #!/bin/bash with #!/system/bin/sh:
+ sed 's/#!\/bin\/bash/#!\/system\/bin\/sh/g' perf-archive >> /tmp/perf-archive
+ chmod +x /tmp/perf-archive
+ adb push /tmp/perf-archive /data/perf-archive
+
+IV. Environment settings for running perf
+------------------------------------------------
+Some perf features need environment variables to run properly.
+You need to set these before running perf on the target:
+ adb shell
+ # PERF_PAGER=cat
+
+IV. Run perf
+------------------------------------------------
+Run perf on your device/emulator to which you previously connected using adb:
+ # ./data/perf
diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt
index ab7f667de1b..194f37d635d 100644
--- a/tools/perf/Documentation/perf-diff.txt
+++ b/tools/perf/Documentation/perf-diff.txt
@@ -72,6 +72,66 @@ OPTIONS
--symfs=<directory>::
Look for files with symbols relative to this directory.
+-b::
+--baseline-only::
+ Show only items with match in baseline.
+
+-c::
+--compute::
+ Differential computation selection - delta,ratio,wdiff (default is delta).
+ If '+' is specified as a first character, the output is sorted based
+ on the computation results.
+ See COMPARISON METHODS section for more info.
+
+-p::
+--period::
+ Show period values for both compared hist entries.
+
+-F::
+--formula::
+ Show formula for given computation.
+
+COMPARISON METHODS
+------------------
+delta
+~~~~~
+If specified the 'Delta' column is displayed with value 'd' computed as:
+
+ d = A->period_percent - B->period_percent
+
+with:
+ - A/B being matching hist entry from first/second file specified
+ (or perf.data/perf.data.old) respectively.
+
+ - period_percent being the % of the hist entry period value within
+ single data file
+
+ratio
+~~~~~
+If specified the 'Ratio' column is displayed with value 'r' computed as:
+
+ r = A->period / B->period
+
+with:
+ - A/B being matching hist entry from first/second file specified
+ (or perf.data/perf.data.old) respectively.
+
+ - period being the hist entry period value
+
+wdiff
+~~~~~
+If specified the 'Weighted diff' column is displayed with value 'd' computed as:
+
+ d = B->period * WEIGHT-A - A->period * WEIGHT-B
+
+ - A/B being matching hist entry from first/second file specified
+ (or perf.data/perf.data.old) respectively.
+
+ - period being the hist entry period value
+
+ - WEIGHT-A/WEIGHT-B being user suplied weights in the the '-c' option
+ behind ':' separator like '-c wdiff:1,2'.
+
SEE ALSO
--------
linkperf:perf-record[1]
diff --git a/tools/perf/Documentation/perf-inject.txt b/tools/perf/Documentation/perf-inject.txt
index 025630d43cd..a00a34276c5 100644
--- a/tools/perf/Documentation/perf-inject.txt
+++ b/tools/perf/Documentation/perf-inject.txt
@@ -29,6 +29,17 @@ OPTIONS
-v::
--verbose::
Be more verbose.
+-i::
+--input=::
+ Input file name. (default: stdin)
+-o::
+--output=::
+ Output file name. (default: stdout)
+-s::
+--sched-stat::
+ Merge sched_stat and sched_switch for getting events where and how long
+ tasks slept. sched_switch contains a callchain where a task slept and
+ sched_stat contains a timeslice how long a task slept.
SEE ALSO
--------
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 2fa173b5197..cf0c3107e06 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -108,6 +108,11 @@ with it. --append may be used here. Examples:
3>results perf stat --log-fd 3 -- $cmd
3>>results perf stat --log-fd 3 --append -- $cmd
+--pre::
+--post::
+ Pre and post measurement hooks, e.g.:
+
+perf stat --repeat 10 --null --sync --pre 'make -s O=defconfig-build/clean' -- make -s -j64 O=defconfig-build/ bzImage
EXAMPLES
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 3a2ae37310a..68718ccdd17 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -48,6 +48,12 @@ comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-
In per-thread mode with inheritance mode on (default), Events are captured only when
the thread executes on the designated CPUs. Default is to monitor all CPUs.
+--duration:
+ Show only events that had a duration greater than N.M ms.
+
+--sched:
+ Accrue thread runtime and provide a summary at the end of the session.
+
SEE ALSO
--------
linkperf:perf-record[1], linkperf:perf-script[1]
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 00deed4d615..891bc77bdb2 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -155,23 +155,58 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
-include config/feature-tests.mak
-ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -fstack-protector-all),y)
+ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
CFLAGS := $(CFLAGS) -fstack-protector-all
endif
-ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -Wstack-protector),y)
+ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
CFLAGS := $(CFLAGS) -Wstack-protector
endif
-ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -Wvolatile-register-var),y)
+ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y)
CFLAGS := $(CFLAGS) -Wvolatile-register-var
endif
### --- END CONFIGURATION SECTION ---
-BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+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
+
+BASIC_CFLAGS = \
+ -Iutil/include \
+ -Iarch/$(ARCH)/include \
+ $(if $(objtree),-I$(objtree)/arch/$(ARCH)/include/generated/uapi) \
+ -I$(srctree)/arch/$(ARCH)/include/uapi \
+ -I$(srctree)/arch/$(ARCH)/include \
+ $(if $(objtree),-I$(objtree)/include/generated/uapi) \
+ -I$(srctree)/include/uapi \
+ -I$(srctree)/include \
+ -I$(OUTPUT)util \
+ -Iutil \
+ -I. \
+ -I$(TRACE_EVENT_DIR) \
+ -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+
BASIC_LDFLAGS =
+ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
+ BIONIC := 1
+ EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
+ EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
+ BASIC_CFLAGS += -I.
+endif
+
# Guard against environment variables
BUILTIN_OBJS =
LIB_H =
@@ -303,6 +338,7 @@ 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
@@ -319,6 +355,7 @@ 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
@@ -362,7 +399,6 @@ 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/parse-events-test.o
LIB_OBJS += $(OUTPUT)util/path.o
LIB_OBJS += $(OUTPUT)util/rbtree.o
LIB_OBJS += $(OUTPUT)util/bitmap.o
@@ -377,15 +413,16 @@ 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/dso-test-data.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
@@ -413,10 +450,29 @@ LIB_OBJS += $(OUTPUT)util/intlist.o
LIB_OBJS += $(OUTPUT)util/vdso.o
LIB_OBJS += $(OUTPUT)util/stat.o
+LIB_OBJS += $(OUTPUT)ui/setup.o
LIB_OBJS += $(OUTPUT)ui/helpline.o
+LIB_OBJS += $(OUTPUT)ui/progress.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/util.o
+
BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
# Benchmark modules
@@ -446,8 +502,8 @@ 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-test.o
BUILTIN_OBJS += $(OUTPUT)builtin-inject.o
+BUILTIN_OBJS += $(OUTPUT)tests/builtin-test.o
PERFLIBS = $(LIB_FILE) $(LIBTRACEEVENT)
@@ -468,18 +524,33 @@ ifdef NO_LIBELF
NO_LIBUNWIND := 1
else
FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
-ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y)
+ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS)
- ifneq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC)),y)
- msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
- else
+ 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);
+
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
- FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS)
- ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),y)
+ # 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=$(ALL_CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(ALL_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
@@ -495,7 +566,7 @@ ifdef LIBUNWIND_DIR
endif
FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
-ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND)),y)
+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
@@ -524,7 +595,8 @@ LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
else # NO_LIBELF
BASIC_CFLAGS += -DLIBELF_SUPPORT
-ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON)),y)
+FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
+ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
BASIC_CFLAGS += -DLIBELF_MMAP
endif
@@ -532,7 +604,8 @@ 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);
else
- BASIC_CFLAGS += -DDWARF_SUPPORT
+ BASIC_CFLAGS := -DDWARF_SUPPORT $(LIBDW_CFLAGS) $(BASIC_CFLAGS)
+ BASIC_LDFLAGS := $(LIBDW_LDFLAGS) $(BASIC_LDFLAGS)
EXTLIBS += -lelf -ldw
LIB_OBJS += $(OUTPUT)util/probe-finder.o
LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
@@ -550,7 +623,7 @@ endif
ifndef NO_LIBAUDIT
FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit
- ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT)),y)
+ ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
else
BASIC_CFLAGS += -DLIBAUDIT_SUPPORT
@@ -561,23 +634,23 @@ endif
ifndef NO_NEWT
FLAGS_NEWT=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lnewt
- ifneq ($(call try-cc,$(SOURCE_NEWT),$(FLAGS_NEWT)),y)
+ ifneq ($(call try-cc,$(SOURCE_NEWT),$(FLAGS_NEWT),libnewt),y)
msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev);
else
# Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
BASIC_CFLAGS += -I/usr/include/slang
BASIC_CFLAGS += -DNEWT_SUPPORT
EXTLIBS += -lnewt -lslang
- LIB_OBJS += $(OUTPUT)ui/setup.o
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/progress.o
+ LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
LIB_OBJS += $(OUTPUT)ui/util.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
@@ -590,10 +663,10 @@ endif
ifndef NO_GTK2
FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
- ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2)),y)
+ ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y)
msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
else
- ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2)),y)
+ ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR
endif
BASIC_CFLAGS += -DGTK2_SUPPORT
@@ -603,9 +676,9 @@ ifndef NO_GTK2
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
# Make sure that it'd be included only once.
ifeq ($(findstring -DNEWT_SUPPORT,$(BASIC_CFLAGS)),)
- LIB_OBJS += $(OUTPUT)ui/setup.o
LIB_OBJS += $(OUTPUT)ui/util.o
endif
endif
@@ -620,7 +693,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)),y)
+ ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
BASIC_CFLAGS += -DNO_LIBPERL
else
ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS)
@@ -674,11 +747,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)),y)
+ ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED),python),y)
$(call disable-python,Python.h (for Python 2.x))
else
- ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED)),y)
+ ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED),python version),y)
$(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)
@@ -712,22 +785,22 @@ else
BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
else
FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
- has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD))
+ 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))
+ has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty)
ifeq ($(has_bfd_iberty),y)
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))
+ has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz)
ifeq ($(has_bfd_iberty_z),y)
EXTLIBS += -lbfd -liberty -lz
else
FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty
- has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE))
+ has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
ifeq ($(has_cplus_demangle),y)
EXTLIBS += -liberty
BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
@@ -749,13 +822,19 @@ ifeq ($(NO_PERF_REGS),0)
endif
ifndef NO_STRLCPY
- ifeq ($(call try-cc,$(SOURCE_STRLCPY),),y)
+ ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
BASIC_CFLAGS += -DHAVE_STRLCPY
endif
endif
+ifndef NO_ON_EXIT
+ ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
+ BASIC_CFLAGS += -DHAVE_ON_EXIT
+ endif
+endif
+
ifndef NO_BACKTRACE
- ifeq ($(call try-cc,$(SOURCE_BACKTRACE),),y)
+ ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
BASIC_CFLAGS += -DBACKTRACE_SUPPORT
endif
endif
@@ -864,10 +943,14 @@ $(OUTPUT)%.s: %.S
$(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
'-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \
- '-DBINDIR="$(bindir_relative_SQ)"' \
'-DPREFIX="$(prefix_SQ)"' \
$<
+$(OUTPUT)tests/attr.o: tests/attr.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
+ '-DBINDIR="$(bindir_SQ)"' \
+ $<
+
$(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
@@ -883,6 +966,9 @@ $(OUTPUT)ui/browsers/hists.o: ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS
$(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
+$(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
+
$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
@@ -954,20 +1040,15 @@ help:
@echo 'Perf maintainer targets:'
@echo ' clean - clean all binary objects and build output'
-doc:
- $(MAKE) -C Documentation all
-
-man:
- $(MAKE) -C Documentation man
-html:
- $(MAKE) -C Documentation html
+DOC_TARGETS := doc man html info pdf
-info:
- $(MAKE) -C Documentation info
+INSTALL_DOC_TARGETS := $(patsubst %,install-%,$(DOC_TARGETS)) try-install-man
+INSTALL_DOC_TARGETS += quick-install-doc quick-install-man quick-install-html
-pdf:
- $(MAKE) -C Documentation pdf
+# 'make doc' should call 'make -C Documentation all'
+$(DOC_TARGETS):
+ $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:doc=all)
TAGS:
$(RM) TAGS
@@ -1018,7 +1099,7 @@ perfexec_instdir = $(prefix)/$(perfexecdir)
endif
perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
-install: all
+install: all try-install-man
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
@@ -1034,33 +1115,17 @@ install: all
$(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'
$(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-python_ext:
$(PYTHON_WORD) util/setup.py --quiet install --root='/$(DESTDIR_SQ)'
-install-doc:
- $(MAKE) -C Documentation install
-
-install-man:
- $(MAKE) -C Documentation install-man
-
-install-html:
- $(MAKE) -C Documentation install-html
-
-install-info:
- $(MAKE) -C Documentation install-info
-
-install-pdf:
- $(MAKE) -C Documentation install-pdf
-
-quick-install-doc:
- $(MAKE) -C Documentation quick-install
-
-quick-install-man:
- $(MAKE) -C Documentation quick-install-man
-
-quick-install-html:
- $(MAKE) -C Documentation quick-install-html
+# 'make install-doc' should call 'make -C Documentation install'
+$(INSTALL_DOC_TARGETS):
+ $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:-doc=)
### Cleaning rules
@@ -1068,7 +1133,7 @@ clean: $(LIBTRACEEVENT)-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*
- $(MAKE) -C Documentation/ clean
+ $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
$(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS
$(RM) $(OUTPUT)util/*-bison*
$(RM) $(OUTPUT)util/*-flex*
diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
new file mode 100644
index 00000000000..3e975cb6232
--- /dev/null
+++ b/tools/perf/arch/common.c
@@ -0,0 +1,211 @@
+#include <stdio.h>
+#include <sys/utsname.h>
+#include "common.h"
+#include "../util/debug.h"
+
+const char *const arm_triplets[] = {
+ "arm-eabi-",
+ "arm-linux-androideabi-",
+ "arm-unknown-linux-",
+ "arm-unknown-linux-gnu-",
+ "arm-unknown-linux-gnueabi-",
+ NULL
+};
+
+const char *const powerpc_triplets[] = {
+ "powerpc-unknown-linux-gnu-",
+ "powerpc64-unknown-linux-gnu-",
+ NULL
+};
+
+const char *const s390_triplets[] = {
+ "s390-ibm-linux-",
+ NULL
+};
+
+const char *const sh_triplets[] = {
+ "sh-unknown-linux-gnu-",
+ "sh64-unknown-linux-gnu-",
+ NULL
+};
+
+const char *const sparc_triplets[] = {
+ "sparc-unknown-linux-gnu-",
+ "sparc64-unknown-linux-gnu-",
+ NULL
+};
+
+const char *const x86_triplets[] = {
+ "x86_64-pc-linux-gnu-",
+ "x86_64-unknown-linux-gnu-",
+ "i686-pc-linux-gnu-",
+ "i586-pc-linux-gnu-",
+ "i486-pc-linux-gnu-",
+ "i386-pc-linux-gnu-",
+ "i686-linux-android-",
+ "i686-android-linux-",
+ NULL
+};
+
+const char *const mips_triplets[] = {
+ "mips-unknown-linux-gnu-",
+ "mipsel-linux-android-",
+ NULL
+};
+
+static bool lookup_path(char *name)
+{
+ bool found = false;
+ char *path, *tmp;
+ char buf[PATH_MAX];
+ char *env = getenv("PATH");
+
+ if (!env)
+ return false;
+
+ env = strdup(env);
+ if (!env)
+ return false;
+
+ path = strtok_r(env, ":", &tmp);
+ while (path) {
+ scnprintf(buf, sizeof(buf), "%s/%s", path, name);
+ if (access(buf, F_OK) == 0) {
+ found = true;
+ break;
+ }
+ path = strtok_r(NULL, ":", &tmp);
+ }
+ free(env);
+ return found;
+}
+
+static int lookup_triplets(const char *const *triplets, const char *name)
+{
+ int i;
+ char buf[PATH_MAX];
+
+ for (i = 0; triplets[i] != NULL; i++) {
+ scnprintf(buf, sizeof(buf), "%s%s", triplets[i], name);
+ if (lookup_path(buf))
+ return i;
+ }
+ return -1;
+}
+
+/*
+ * Return architecture name in a normalized form.
+ * The conversion logic comes from the Makefile.
+ */
+static const char *normalize_arch(char *arch)
+{
+ if (!strcmp(arch, "x86_64"))
+ return "x86";
+ if (arch[0] == 'i' && arch[2] == '8' && arch[3] == '6')
+ return "x86";
+ if (!strcmp(arch, "sun4u") || !strncmp(arch, "sparc", 5))
+ return "sparc";
+ if (!strncmp(arch, "arm", 3) || !strcmp(arch, "sa110"))
+ return "arm";
+ if (!strncmp(arch, "s390", 4))
+ return "s390";
+ if (!strncmp(arch, "parisc", 6))
+ return "parisc";
+ if (!strncmp(arch, "powerpc", 7) || !strncmp(arch, "ppc", 3))
+ return "powerpc";
+ if (!strncmp(arch, "mips", 4))
+ return "mips";
+ if (!strncmp(arch, "sh", 2) && isdigit(arch[2]))
+ return "sh";
+
+ return arch;
+}
+
+static int perf_session_env__lookup_binutils_path(struct perf_session_env *env,
+ const char *name,
+ const char **path)
+{
+ int idx;
+ const char *arch, *cross_env;
+ struct utsname uts;
+ const char *const *path_list;
+ char *buf = NULL;
+
+ arch = normalize_arch(env->arch);
+
+ if (uname(&uts) < 0)
+ goto out;
+
+ /*
+ * We don't need to try to find objdump path for native system.
+ * Just use default binutils path (e.g.: "objdump").
+ */
+ if (!strcmp(normalize_arch(uts.machine), arch))
+ goto out;
+
+ cross_env = getenv("CROSS_COMPILE");
+ if (cross_env) {
+ if (asprintf(&buf, "%s%s", cross_env, name) < 0)
+ goto out_error;
+ if (buf[0] == '/') {
+ if (access(buf, F_OK) == 0)
+ goto out;
+ goto out_error;
+ }
+ if (lookup_path(buf))
+ goto out;
+ free(buf);
+ }
+
+ if (!strcmp(arch, "arm"))
+ path_list = arm_triplets;
+ else if (!strcmp(arch, "powerpc"))
+ path_list = powerpc_triplets;
+ else if (!strcmp(arch, "sh"))
+ path_list = sh_triplets;
+ else if (!strcmp(arch, "s390"))
+ path_list = s390_triplets;
+ else if (!strcmp(arch, "sparc"))
+ path_list = sparc_triplets;
+ else if (!strcmp(arch, "x86"))
+ path_list = x86_triplets;
+ else if (!strcmp(arch, "mips"))
+ path_list = mips_triplets;
+ else {
+ ui__error("binutils for %s not supported.\n", arch);
+ goto out_error;
+ }
+
+ idx = lookup_triplets(path_list, name);
+ if (idx < 0) {
+ ui__error("Please install %s for %s.\n"
+ "You can add it to PATH, set CROSS_COMPILE or "
+ "override the default using --%s.\n",
+ name, arch, name);
+ goto out_error;
+ }
+
+ if (asprintf(&buf, "%s%s", path_list[idx], name) < 0)
+ goto out_error;
+
+out:
+ *path = buf;
+ return 0;
+out_error:
+ free(buf);
+ *path = NULL;
+ return -1;
+}
+
+int perf_session_env__lookup_objdump(struct perf_session_env *env)
+{
+ /*
+ * For live mode, env->arch will be NULL and we can use
+ * the native objdump tool.
+ */
+ if (env->arch == NULL)
+ return 0;
+
+ return perf_session_env__lookup_binutils_path(env, "objdump",
+ &objdump_path);
+}
diff --git a/tools/perf/arch/common.h b/tools/perf/arch/common.h
new file mode 100644
index 00000000000..ede246eda9b
--- /dev/null
+++ b/tools/perf/arch/common.h
@@ -0,0 +1,10 @@
+#ifndef ARCH_PERF_COMMON_H
+#define ARCH_PERF_COMMON_H
+
+#include "../util/session.h"
+
+extern const char *objdump_path;
+
+int perf_session_env__lookup_objdump(struct perf_session_env *env);
+
+#endif /* ARCH_PERF_COMMON_H */
diff --git a/tools/perf/arch/x86/include/perf_regs.h b/tools/perf/arch/x86/include/perf_regs.h
index 46fc9f15c6b..7fcdcdbee91 100644
--- a/tools/perf/arch/x86/include/perf_regs.h
+++ b/tools/perf/arch/x86/include/perf_regs.h
@@ -3,7 +3,7 @@
#include <stdlib.h>
#include "../../util/types.h"
-#include "../../../../../arch/x86/include/asm/perf_regs.h"
+#include <asm/perf_regs.h>
#ifndef ARCH_X86_64
#define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 9ea38540b87..dc870cf31b7 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -28,12 +28,12 @@
#include "util/hist.h"
#include "util/session.h"
#include "util/tool.h"
+#include "arch/common.h"
#include <linux/bitmap.h>
struct perf_annotate {
struct perf_tool tool;
- char const *input_name;
bool force, use_tui, use_stdio;
bool full_paths;
bool print_line;
@@ -139,7 +139,7 @@ find_next:
}
if (use_browser > 0) {
- key = hist_entry__tui_annotate(he, evidx, NULL, NULL, 0);
+ key = hist_entry__tui_annotate(he, evidx, NULL);
switch (key) {
case K_RIGHT:
next = rb_next(nd);
@@ -174,7 +174,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
struct perf_evsel *pos;
u64 total_nr_samples;
- session = perf_session__new(ann->input_name, O_RDONLY,
+ session = perf_session__new(input_name, O_RDONLY,
ann->force, false, &ann->tool);
if (session == NULL)
return -ENOMEM;
@@ -186,6 +186,12 @@ static int __cmd_annotate(struct perf_annotate *ann)
goto out_delete;
}
+ if (!objdump_path) {
+ ret = perf_session_env__lookup_objdump(&session->header.env);
+ if (ret)
+ goto out_delete;
+ }
+
ret = perf_session__process_events(session, &ann->tool);
if (ret)
goto out_delete;
@@ -246,13 +252,14 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
.sample = process_sample_event,
.mmap = perf_event__process_mmap,
.comm = perf_event__process_comm,
- .fork = perf_event__process_task,
+ .exit = perf_event__process_exit,
+ .fork = perf_event__process_fork,
.ordered_samples = true,
.ordering_requires_timestamps = true,
},
};
const struct option options[] = {
- OPT_STRING('i', "input", &annotate.input_name, "file",
+ OPT_STRING('i', "input", &input_name, "file",
"input file name"),
OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
"only consider symbols in these dsos"),
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index d37e077f4b1..fae8b250b2c 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -13,6 +13,7 @@
#include "util/header.h"
#include "util/parse-options.h"
#include "util/strlist.h"
+#include "util/build-id.h"
#include "util/symbol.h"
static int build_id_cache__add_file(const char *filename, const char *debugdir)
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
index a0e94fffa03..a82d99fec83 100644
--- a/tools/perf/builtin-buildid-list.c
+++ b/tools/perf/builtin-buildid-list.c
@@ -44,8 +44,7 @@ static int filename__fprintf_build_id(const char *name, FILE *fp)
return fprintf(fp, "%s\n", sbuild_id);
}
-static int perf_session__list_build_ids(const char *input_name,
- bool force, bool with_hits)
+static int perf_session__list_build_ids(bool force, bool with_hits)
{
struct perf_session *session;
@@ -81,7 +80,6 @@ int cmd_buildid_list(int argc, const char **argv,
bool show_kernel = false;
bool with_hits = false;
bool force = false;
- const char *input_name = NULL;
const struct option options[] = {
OPT_BOOLEAN('H', "with-hits", &with_hits, "Show only DSOs with hits"),
OPT_STRING('i', "input", &input_name, "file", "input file name"),
@@ -101,5 +99,5 @@ int cmd_buildid_list(int argc, const char **argv,
if (show_kernel)
return sysfs__fprintf_build_id(stdout);
- return perf_session__list_build_ids(input_name, force, with_hits);
+ return perf_session__list_build_ids(force, with_hits);
}
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index a0b531c14b9..93b852f8a5d 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -24,6 +24,228 @@ static char const *input_old = "perf.data.old",
static char diff__default_sort_order[] = "dso,symbol";
static bool force;
static bool show_displacement;
+static bool show_period;
+static bool show_formula;
+static bool show_baseline_only;
+static bool sort_compute;
+
+static s64 compute_wdiff_w1;
+static s64 compute_wdiff_w2;
+
+enum {
+ COMPUTE_DELTA,
+ COMPUTE_RATIO,
+ COMPUTE_WEIGHTED_DIFF,
+ COMPUTE_MAX,
+};
+
+const char *compute_names[COMPUTE_MAX] = {
+ [COMPUTE_DELTA] = "delta",
+ [COMPUTE_RATIO] = "ratio",
+ [COMPUTE_WEIGHTED_DIFF] = "wdiff",
+};
+
+static int compute;
+
+static int setup_compute_opt_wdiff(char *opt)
+{
+ char *w1_str = opt;
+ char *w2_str;
+
+ int ret = -EINVAL;
+
+ if (!opt)
+ goto out;
+
+ w2_str = strchr(opt, ',');
+ if (!w2_str)
+ goto out;
+
+ *w2_str++ = 0x0;
+ if (!*w2_str)
+ goto out;
+
+ compute_wdiff_w1 = strtol(w1_str, NULL, 10);
+ compute_wdiff_w2 = strtol(w2_str, NULL, 10);
+
+ if (!compute_wdiff_w1 || !compute_wdiff_w2)
+ goto out;
+
+ pr_debug("compute wdiff w1(%" PRId64 ") w2(%" PRId64 ")\n",
+ compute_wdiff_w1, compute_wdiff_w2);
+
+ ret = 0;
+
+ out:
+ if (ret)
+ pr_err("Failed: wrong weight data, use 'wdiff:w1,w2'\n");
+
+ return ret;
+}
+
+static int setup_compute_opt(char *opt)
+{
+ if (compute == COMPUTE_WEIGHTED_DIFF)
+ return setup_compute_opt_wdiff(opt);
+
+ if (opt) {
+ pr_err("Failed: extra option specified '%s'", opt);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int setup_compute(const struct option *opt, const char *str,
+ int unset __maybe_unused)
+{
+ int *cp = (int *) opt->value;
+ char *cstr = (char *) str;
+ char buf[50];
+ unsigned i;
+ char *option;
+
+ if (!str) {
+ *cp = COMPUTE_DELTA;
+ return 0;
+ }
+
+ if (*str == '+') {
+ sort_compute = true;
+ cstr = (char *) ++str;
+ if (!*str)
+ return 0;
+ }
+
+ option = strchr(str, ':');
+ if (option) {
+ unsigned len = option++ - str;
+
+ /*
+ * The str data are not writeable, so we need
+ * to use another buffer.
+ */
+
+ /* No option value is longer. */
+ if (len >= sizeof(buf))
+ return -EINVAL;
+
+ strncpy(buf, str, len);
+ buf[len] = 0x0;
+ cstr = buf;
+ }
+
+ for (i = 0; i < COMPUTE_MAX; i++)
+ if (!strcmp(cstr, compute_names[i])) {
+ *cp = i;
+ return setup_compute_opt(option);
+ }
+
+ pr_err("Failed: '%s' is not computation method "
+ "(use 'delta','ratio' or 'wdiff')\n", str);
+ return -EINVAL;
+}
+
+static double get_period_percent(struct hist_entry *he, u64 period)
+{
+ u64 total = he->hists->stats.total_period;
+ return (period * 100.0) / total;
+}
+
+double perf_diff__compute_delta(struct hist_entry *he)
+{
+ struct hist_entry *pair = hist_entry__next_pair(he);
+ double new_percent = get_period_percent(he, he->stat.period);
+ double old_percent = pair ? get_period_percent(pair, pair->stat.period) : 0.0;
+
+ he->diff.period_ratio_delta = new_percent - old_percent;
+ he->diff.computed = true;
+ return he->diff.period_ratio_delta;
+}
+
+double perf_diff__compute_ratio(struct hist_entry *he)
+{
+ struct hist_entry *pair = hist_entry__next_pair(he);
+ double new_period = he->stat.period;
+ double old_period = pair ? pair->stat.period : 0;
+
+ he->diff.computed = true;
+ he->diff.period_ratio = pair ? (new_period / old_period) : 0;
+ return he->diff.period_ratio;
+}
+
+s64 perf_diff__compute_wdiff(struct hist_entry *he)
+{
+ struct hist_entry *pair = hist_entry__next_pair(he);
+ u64 new_period = he->stat.period;
+ u64 old_period = pair ? pair->stat.period : 0;
+
+ he->diff.computed = true;
+
+ if (!pair)
+ he->diff.wdiff = 0;
+ else
+ he->diff.wdiff = new_period * compute_wdiff_w2 -
+ old_period * compute_wdiff_w1;
+
+ return he->diff.wdiff;
+}
+
+static int formula_delta(struct hist_entry *he, char *buf, size_t size)
+{
+ struct hist_entry *pair = hist_entry__next_pair(he);
+
+ if (!pair)
+ return -1;
+
+ return scnprintf(buf, size,
+ "(%" PRIu64 " * 100 / %" PRIu64 ") - "
+ "(%" PRIu64 " * 100 / %" PRIu64 ")",
+ he->stat.period, he->hists->stats.total_period,
+ pair->stat.period, pair->hists->stats.total_period);
+}
+
+static int formula_ratio(struct hist_entry *he, char *buf, size_t size)
+{
+ struct hist_entry *pair = hist_entry__next_pair(he);
+ double new_period = he->stat.period;
+ double old_period = pair ? pair->stat.period : 0;
+
+ if (!pair)
+ return -1;
+
+ return scnprintf(buf, size, "%.0F / %.0F", new_period, old_period);
+}
+
+static int formula_wdiff(struct hist_entry *he, char *buf, size_t size)
+{
+ struct hist_entry *pair = hist_entry__next_pair(he);
+ u64 new_period = he->stat.period;
+ u64 old_period = pair ? pair->stat.period : 0;
+
+ if (!pair)
+ return -1;
+
+ return scnprintf(buf, size,
+ "(%" PRIu64 " * " "%" PRId64 ") - (%" PRIu64 " * " "%" PRId64 ")",
+ new_period, compute_wdiff_w2, old_period, compute_wdiff_w1);
+}
+
+int perf_diff__formula(char *buf, size_t size, struct hist_entry *he)
+{
+ switch (compute) {
+ case COMPUTE_DELTA:
+ return formula_delta(he, buf, size);
+ case COMPUTE_RATIO:
+ return formula_ratio(he, buf, size);
+ case COMPUTE_WEIGHTED_DIFF:
+ return formula_wdiff(he, buf, size);
+ default:
+ BUG_ON(1);
+ }
+
+ return -1;
+}
static int hists__add_entry(struct hists *self,
struct addr_location *al, u64 period)
@@ -47,7 +269,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
return -1;
}
- if (al.filtered || al.sym == NULL)
+ if (al.filtered)
return 0;
if (hists__add_entry(&evsel->hists, &al, sample->period)) {
@@ -63,8 +285,8 @@ static struct perf_tool tool = {
.sample = diff__process_sample_event,
.mmap = perf_event__process_mmap,
.comm = perf_event__process_comm,
- .exit = perf_event__process_task,
- .fork = perf_event__process_task,
+ .exit = perf_event__process_exit,
+ .fork = perf_event__process_fork,
.lost = perf_event__process_lost,
.ordered_samples = true,
.ordering_requires_timestamps = true,
@@ -112,36 +334,6 @@ static void hists__name_resort(struct hists *self, bool sort)
self->entries = tmp;
}
-static struct hist_entry *hists__find_entry(struct hists *self,
- struct hist_entry *he)
-{
- struct rb_node *n = self->entries.rb_node;
-
- while (n) {
- struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node);
- int64_t cmp = hist_entry__cmp(he, iter);
-
- if (cmp < 0)
- n = n->rb_left;
- else if (cmp > 0)
- n = n->rb_right;
- else
- return iter;
- }
-
- return NULL;
-}
-
-static void hists__match(struct hists *older, struct hists *newer)
-{
- struct rb_node *nd;
-
- for (nd = rb_first(&newer->entries); nd; nd = rb_next(nd)) {
- struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node);
- pos->pair = hists__find_entry(older, pos);
- }
-}
-
static struct perf_evsel *evsel_match(struct perf_evsel *evsel,
struct perf_evlist *evlist)
{
@@ -172,6 +364,144 @@ static void perf_evlist__resort_hists(struct perf_evlist *evlist, bool name)
}
}
+static void hists__baseline_only(struct hists *hists)
+{
+ struct rb_node *next = rb_first(&hists->entries);
+
+ while (next != NULL) {
+ struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node);
+
+ next = rb_next(&he->rb_node);
+ if (!hist_entry__next_pair(he)) {
+ rb_erase(&he->rb_node, &hists->entries);
+ hist_entry__free(he);
+ }
+ }
+}
+
+static void hists__precompute(struct hists *hists)
+{
+ struct rb_node *next = rb_first(&hists->entries);
+
+ while (next != NULL) {
+ struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node);
+
+ next = rb_next(&he->rb_node);
+
+ switch (compute) {
+ case COMPUTE_DELTA:
+ perf_diff__compute_delta(he);
+ break;
+ case COMPUTE_RATIO:
+ perf_diff__compute_ratio(he);
+ break;
+ case COMPUTE_WEIGHTED_DIFF:
+ perf_diff__compute_wdiff(he);
+ break;
+ default:
+ BUG_ON(1);
+ }
+ }
+}
+
+static int64_t cmp_doubles(double l, double r)
+{
+ if (l > r)
+ return -1;
+ else if (l < r)
+ return 1;
+ else
+ return 0;
+}
+
+static int64_t
+hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
+ int c)
+{
+ switch (c) {
+ case COMPUTE_DELTA:
+ {
+ double l = left->diff.period_ratio_delta;
+ double r = right->diff.period_ratio_delta;
+
+ return cmp_doubles(l, r);
+ }
+ case COMPUTE_RATIO:
+ {
+ double l = left->diff.period_ratio;
+ double r = right->diff.period_ratio;
+
+ return cmp_doubles(l, r);
+ }
+ case COMPUTE_WEIGHTED_DIFF:
+ {
+ s64 l = left->diff.wdiff;
+ s64 r = right->diff.wdiff;
+
+ return r - l;
+ }
+ default:
+ BUG_ON(1);
+ }
+
+ return 0;
+}
+
+static void insert_hist_entry_by_compute(struct rb_root *root,
+ struct hist_entry *he,
+ int c)
+{
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+ struct hist_entry *iter;
+
+ while (*p != NULL) {
+ parent = *p;
+ iter = rb_entry(parent, struct hist_entry, rb_node);
+ if (hist_entry__cmp_compute(he, iter, c) < 0)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+
+ rb_link_node(&he->rb_node, parent, p);
+ rb_insert_color(&he->rb_node, root);
+}
+
+static void hists__compute_resort(struct hists *hists)
+{
+ struct rb_root tmp = RB_ROOT;
+ struct rb_node *next = rb_first(&hists->entries);
+
+ while (next != NULL) {
+ struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node);
+
+ next = rb_next(&he->rb_node);
+
+ rb_erase(&he->rb_node, &hists->entries);
+ insert_hist_entry_by_compute(&tmp, he, compute);
+ }
+
+ hists->entries = tmp;
+}
+
+static void hists__process(struct hists *old, struct hists *new)
+{
+ hists__match(new, old);
+
+ if (show_baseline_only)
+ hists__baseline_only(new);
+ else
+ hists__link(new, old);
+
+ if (sort_compute) {
+ hists__precompute(new);
+ hists__compute_resort(new);
+ }
+
+ hists__fprintf(new, true, 0, 0, stdout);
+}
+
static int __cmd_diff(void)
{
int ret, i;
@@ -213,8 +543,7 @@ static int __cmd_diff(void)
first = false;
- hists__match(&evsel_old->hists, &evsel->hists);
- hists__fprintf(&evsel->hists, true, 0, 0, stdout);
+ hists__process(&evsel_old->hists, &evsel->hists);
}
out_delete:
@@ -235,6 +564,16 @@ static const struct option options[] = {
"be more verbose (show symbol address, etc)"),
OPT_BOOLEAN('M', "displacement", &show_displacement,
"Show position displacement relative to baseline"),
+ OPT_BOOLEAN('b', "baseline-only", &show_baseline_only,
+ "Show only items with match in baseline"),
+ OPT_CALLBACK('c', "compute", &compute,
+ "delta,ratio,wdiff:w1,w2 (default delta)",
+ "Entries differential computation selection",
+ setup_compute),
+ OPT_BOOLEAN('p', "period", &show_period,
+ "Show period values."),
+ OPT_BOOLEAN('F', "formula", &show_formula,
+ "Show formula."),
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
"dump raw trace in ASCII"),
OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
@@ -263,12 +602,36 @@ static void ui_init(void)
/* No overhead column. */
perf_hpp__column_enable(PERF_HPP__OVERHEAD, false);
- /* Display baseline/delta/displacement columns. */
+ /*
+ * Display baseline/delta/ratio/displacement/
+ * formula/periods columns.
+ */
perf_hpp__column_enable(PERF_HPP__BASELINE, true);
- perf_hpp__column_enable(PERF_HPP__DELTA, true);
+
+ switch (compute) {
+ case COMPUTE_DELTA:
+ perf_hpp__column_enable(PERF_HPP__DELTA, true);
+ break;
+ case COMPUTE_RATIO:
+ perf_hpp__column_enable(PERF_HPP__RATIO, true);
+ break;
+ case COMPUTE_WEIGHTED_DIFF:
+ perf_hpp__column_enable(PERF_HPP__WEIGHTED_DIFF, true);
+ break;
+ default:
+ BUG_ON(1);
+ };
if (show_displacement)
perf_hpp__column_enable(PERF_HPP__DISPL, true);
+
+ if (show_formula)
+ perf_hpp__column_enable(PERF_HPP__FORMULA, true);
+
+ if (show_period) {
+ perf_hpp__column_enable(PERF_HPP__PERIOD, true);
+ perf_hpp__column_enable(PERF_HPP__PERIOD_BASELINE, true);
+ }
}
int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c
index 997afb82691..c20f1dcfb7e 100644
--- a/tools/perf/builtin-evlist.c
+++ b/tools/perf/builtin-evlist.c
@@ -48,12 +48,12 @@ static int __if_print(bool *first, const char *field, u64 value)
#define if_print(field) __if_print(&first, #field, pos->attr.field)
-static int __cmd_evlist(const char *input_name, struct perf_attr_details *details)
+static int __cmd_evlist(const char *file_name, struct perf_attr_details *details)
{
struct perf_session *session;
struct perf_evsel *pos;
- session = perf_session__new(input_name, O_RDONLY, 0, false, NULL);
+ session = perf_session__new(file_name, O_RDONLY, 0, false, NULL);
if (session == NULL)
return -ENOMEM;
@@ -111,7 +111,6 @@ static int __cmd_evlist(const char *input_name, struct perf_attr_details *detail
int cmd_evlist(int argc, const char **argv, const char *prefix __maybe_unused)
{
struct perf_attr_details details = { .verbose = false, };
- const char *input_name = NULL;
const struct option options[] = {
OPT_STRING('i', "input", &input_name, "file", "Input file name"),
OPT_BOOLEAN('F', "freq", &details.freq, "Show the sample frequency"),
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 4688bea95c1..84ad6abe425 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -8,33 +8,53 @@
#include "builtin.h"
#include "perf.h"
+#include "util/color.h"
+#include "util/evlist.h"
+#include "util/evsel.h"
#include "util/session.h"
#include "util/tool.h"
#include "util/debug.h"
+#include "util/build-id.h"
#include "util/parse-options.h"
+#include <linux/list.h>
+
struct perf_inject {
struct perf_tool tool;
bool build_ids;
+ bool sched_stat;
+ const char *input_name;
+ int pipe_output,
+ output;
+ u64 bytes_written;
+ struct list_head samples;
+};
+
+struct event_entry {
+ struct list_head node;
+ u32 tid;
+ union perf_event event[0];
};
-static int perf_event__repipe_synth(struct perf_tool *tool __maybe_unused,
+static int perf_event__repipe_synth(struct perf_tool *tool,
union perf_event *event,
struct machine *machine __maybe_unused)
{
+ struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
uint32_t size;
void *buf = event;
size = event->header.size;
while (size) {
- int ret = write(STDOUT_FILENO, buf, size);
+ int ret = write(inject->output, buf, size);
if (ret < 0)
return -errno;
size -= ret;
buf += ret;
+ inject->bytes_written += ret;
}
return 0;
@@ -80,12 +100,25 @@ static int perf_event__repipe(struct perf_tool *tool,
return perf_event__repipe_synth(tool, event, machine);
}
+typedef int (*inject_handler)(struct perf_tool *tool,
+ union perf_event *event,
+ struct perf_sample *sample,
+ struct perf_evsel *evsel,
+ struct machine *machine);
+
static int perf_event__repipe_sample(struct perf_tool *tool,
union perf_event *event,
- struct perf_sample *sample __maybe_unused,
- struct perf_evsel *evsel __maybe_unused,
- struct machine *machine)
+ struct perf_sample *sample,
+ struct perf_evsel *evsel,
+ struct machine *machine)
{
+ if (evsel->handler.func) {
+ inject_handler f = evsel->handler.func;
+ return f(tool, event, sample, evsel, machine);
+ }
+
+ build_id__mark_dso_hit(tool, event, sample, evsel, machine);
+
return perf_event__repipe_synth(tool, event, machine);
}
@@ -102,14 +135,14 @@ static int perf_event__repipe_mmap(struct perf_tool *tool,
return err;
}
-static int perf_event__repipe_task(struct perf_tool *tool,
+static int perf_event__repipe_fork(struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample,
struct machine *machine)
{
int err;
- err = perf_event__process_task(tool, event, sample, machine);
+ err = perf_event__process_fork(tool, event, sample, machine);
perf_event__repipe(tool, event, sample, machine);
return err;
@@ -210,6 +243,80 @@ repipe:
return 0;
}
+static int perf_inject__sched_process_exit(struct perf_tool *tool,
+ union perf_event *event __maybe_unused,
+ struct perf_sample *sample,
+ struct perf_evsel *evsel __maybe_unused,
+ struct machine *machine __maybe_unused)
+{
+ struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
+ struct event_entry *ent;
+
+ list_for_each_entry(ent, &inject->samples, node) {
+ if (sample->tid == ent->tid) {
+ list_del_init(&ent->node);
+ free(ent);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int perf_inject__sched_switch(struct perf_tool *tool,
+ union perf_event *event,
+ struct perf_sample *sample,
+ struct perf_evsel *evsel,
+ struct machine *machine)
+{
+ struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
+ struct event_entry *ent;
+
+ perf_inject__sched_process_exit(tool, event, sample, evsel, machine);
+
+ ent = malloc(event->header.size + sizeof(struct event_entry));
+ if (ent == NULL) {
+ color_fprintf(stderr, PERF_COLOR_RED,
+ "Not enough memory to process sched switch event!");
+ return -1;
+ }
+
+ ent->tid = sample->tid;
+ memcpy(&ent->event, event, event->header.size);
+ list_add(&ent->node, &inject->samples);
+ return 0;
+}
+
+static int perf_inject__sched_stat(struct perf_tool *tool,
+ union perf_event *event __maybe_unused,
+ struct perf_sample *sample,
+ struct perf_evsel *evsel,
+ struct machine *machine)
+{
+ struct event_entry *ent;
+ union perf_event *event_sw;
+ struct perf_sample sample_sw;
+ struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
+ u32 pid = perf_evsel__intval(evsel, sample, "pid");
+
+ list_for_each_entry(ent, &inject->samples, node) {
+ if (pid == ent->tid)
+ goto found;
+ }
+
+ return 0;
+found:
+ event_sw = &ent->event[0];
+ perf_evsel__parse_sample(evsel, event_sw, &sample_sw);
+
+ sample_sw.period = sample->period;
+ sample_sw.time = sample->time;
+ perf_event__synthesize_sample(event_sw, evsel->attr.sample_type,
+ &sample_sw, false);
+ build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine);
+ return perf_event__repipe(tool, event_sw, &sample_sw, machine);
+}
+
extern volatile int session_done;
static void sig_handler(int sig __maybe_unused)
@@ -217,6 +324,21 @@ static void sig_handler(int sig __maybe_unused)
session_done = 1;
}
+static int perf_evsel__check_stype(struct perf_evsel *evsel,
+ u64 sample_type, const char *sample_msg)
+{
+ struct perf_event_attr *attr = &evsel->attr;
+ const char *name = perf_evsel__name(evsel);
+
+ if (!(attr->sample_type & sample_type)) {
+ pr_err("Samples for %s event do not have %s attribute set.",
+ name, sample_msg);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int __cmd_inject(struct perf_inject *inject)
{
struct perf_session *session;
@@ -224,19 +346,48 @@ static int __cmd_inject(struct perf_inject *inject)
signal(SIGINT, sig_handler);
- if (inject->build_ids) {
- inject->tool.sample = perf_event__inject_buildid;
+ if (inject->build_ids || inject->sched_stat) {
inject->tool.mmap = perf_event__repipe_mmap;
- inject->tool.fork = perf_event__repipe_task;
+ inject->tool.fork = perf_event__repipe_fork;
inject->tool.tracing_data = perf_event__repipe_tracing_data;
}
- session = perf_session__new("-", O_RDONLY, false, true, &inject->tool);
+ session = perf_session__new(inject->input_name, O_RDONLY, false, true, &inject->tool);
if (session == NULL)
return -ENOMEM;
+ if (inject->build_ids) {
+ inject->tool.sample = perf_event__inject_buildid;
+ } else if (inject->sched_stat) {
+ struct perf_evsel *evsel;
+
+ inject->tool.ordered_samples = true;
+
+ list_for_each_entry(evsel, &session->evlist->entries, node) {
+ const char *name = perf_evsel__name(evsel);
+
+ if (!strcmp(name, "sched:sched_switch")) {
+ if (perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID"))
+ return -EINVAL;
+
+ evsel->handler.func = perf_inject__sched_switch;
+ } else if (!strcmp(name, "sched:sched_process_exit"))
+ evsel->handler.func = perf_inject__sched_process_exit;
+ else if (!strncmp(name, "sched:sched_stat_", 17))
+ evsel->handler.func = perf_inject__sched_stat;
+ }
+ }
+
+ if (!inject->pipe_output)
+ lseek(inject->output, session->header.data_offset, SEEK_SET);
+
ret = perf_session__process_events(session, &inject->tool);
+ if (!inject->pipe_output) {
+ session->header.data_size = inject->bytes_written;
+ perf_session__write_header(session, session->evlist, inject->output, true);
+ }
+
perf_session__delete(session);
return ret;
@@ -260,10 +411,20 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
.tracing_data = perf_event__repipe_tracing_data_synth,
.build_id = perf_event__repipe_op2_synth,
},
+ .input_name = "-",
+ .samples = LIST_HEAD_INIT(inject.samples),
};
+ const char *output_name = "-";
const struct option options[] = {
OPT_BOOLEAN('b', "build-ids", &inject.build_ids,
"Inject build-ids into the output stream"),
+ OPT_STRING('i', "input", &inject.input_name, "file",
+ "input file name"),
+ OPT_STRING('o', "output", &output_name, "file",
+ "output file name"),
+ OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat,
+ "Merge sched-stat and sched-switch for getting events "
+ "where and how long tasks slept"),
OPT_INCR('v', "verbose", &verbose,
"be more verbose (show build ids, etc)"),
OPT_END()
@@ -281,6 +442,18 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
if (argc)
usage_with_options(inject_usage, options);
+ if (!strcmp(output_name, "-")) {
+ inject.pipe_output = 1;
+ inject.output = STDOUT_FILENO;
+ } else {
+ inject.output = open(output_name, O_CREAT | O_WRONLY | O_TRUNC,
+ S_IRUSR | S_IWUSR);
+ if (inject.output < 0) {
+ perror("failed to create output file");
+ return -1;
+ }
+ }
+
if (symbol__init() < 0)
return -1;
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 14bf82f6365..0b4b796167b 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -477,7 +477,7 @@ static void sort_result(void)
__sort_result(&root_caller_stat, &root_caller_sorted, &caller_sort);
}
-static int __cmd_kmem(const char *input_name)
+static int __cmd_kmem(void)
{
int err = -EINVAL;
struct perf_session *session;
@@ -743,7 +743,6 @@ static int __cmd_record(int argc, const char **argv)
int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
{
const char * const default_sort_order = "frag,hit,bytes";
- const char *input_name = NULL;
const struct option kmem_options[] = {
OPT_STRING('i', "input", &input_name, "file", "input file name"),
OPT_CALLBACK_NOOPT(0, "caller", NULL, NULL,
@@ -779,7 +778,7 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
if (list_empty(&alloc_sort))
setup_sorting(&alloc_sort, default_sort_order);
- return __cmd_kmem(input_name);
+ return __cmd_kmem();
} else
usage_with_options(kmem_usage, kmem_options);
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 260abc535b5..ca3f80ebc10 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -22,9 +22,10 @@
#include <pthread.h>
#include <math.h>
-#include "../../arch/x86/include/asm/svm.h"
-#include "../../arch/x86/include/asm/vmx.h"
-#include "../../arch/x86/include/asm/kvm.h"
+#if defined(__i386__) || defined(__x86_64__)
+#include <asm/svm.h>
+#include <asm/vmx.h>
+#include <asm/kvm.h>
struct event_key {
#define INVALID_KEY (~0ULL)
@@ -58,7 +59,7 @@ struct kvm_event_key {
};
-struct perf_kvm;
+struct perf_kvm_stat;
struct kvm_events_ops {
bool (*is_begin_event)(struct perf_evsel *evsel,
@@ -66,7 +67,7 @@ struct kvm_events_ops {
struct event_key *key);
bool (*is_end_event)(struct perf_evsel *evsel,
struct perf_sample *sample, struct event_key *key);
- void (*decode_key)(struct perf_kvm *kvm, struct event_key *key,
+ void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key,
char decode[20]);
const char *name;
};
@@ -79,7 +80,7 @@ struct exit_reasons_table {
#define EVENTS_BITS 12
#define EVENTS_CACHE_SIZE (1UL << EVENTS_BITS)
-struct perf_kvm {
+struct perf_kvm_stat {
struct perf_tool tool;
struct perf_session *session;
@@ -146,7 +147,7 @@ static struct exit_reasons_table svm_exit_reasons[] = {
SVM_EXIT_REASONS
};
-static const char *get_exit_reason(struct perf_kvm *kvm, u64 exit_code)
+static const char *get_exit_reason(struct perf_kvm_stat *kvm, u64 exit_code)
{
int i = kvm->exit_reasons_size;
struct exit_reasons_table *tbl = kvm->exit_reasons;
@@ -162,7 +163,7 @@ static const char *get_exit_reason(struct perf_kvm *kvm, u64 exit_code)
return "UNKNOWN";
}
-static void exit_event_decode_key(struct perf_kvm *kvm,
+static void exit_event_decode_key(struct perf_kvm_stat *kvm,
struct event_key *key,
char decode[20])
{
@@ -228,7 +229,7 @@ static bool mmio_event_end(struct perf_evsel *evsel, struct perf_sample *sample,
return false;
}
-static void mmio_event_decode_key(struct perf_kvm *kvm __maybe_unused,
+static void mmio_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
struct event_key *key,
char decode[20])
{
@@ -271,7 +272,7 @@ static bool ioport_event_end(struct perf_evsel *evsel,
return kvm_entry_event(evsel);
}
-static void ioport_event_decode_key(struct perf_kvm *kvm __maybe_unused,
+static void ioport_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
struct event_key *key,
char decode[20])
{
@@ -286,7 +287,7 @@ static struct kvm_events_ops ioport_events = {
.name = "IO Port Access"
};
-static bool register_kvm_events_ops(struct perf_kvm *kvm)
+static bool register_kvm_events_ops(struct perf_kvm_stat *kvm)
{
bool ret = true;
@@ -311,11 +312,11 @@ struct vcpu_event_record {
};
-static void init_kvm_event_record(struct perf_kvm *kvm)
+static void init_kvm_event_record(struct perf_kvm_stat *kvm)
{
- int i;
+ unsigned int i;
- for (i = 0; i < (int)EVENTS_CACHE_SIZE; i++)
+ for (i = 0; i < EVENTS_CACHE_SIZE; i++)
INIT_LIST_HEAD(&kvm->kvm_events_cache[i]);
}
@@ -360,7 +361,7 @@ static struct kvm_event *kvm_alloc_init_event(struct event_key *key)
return event;
}
-static struct kvm_event *find_create_kvm_event(struct perf_kvm *kvm,
+static struct kvm_event *find_create_kvm_event(struct perf_kvm_stat *kvm,
struct event_key *key)
{
struct kvm_event *event;
@@ -369,9 +370,10 @@ static struct kvm_event *find_create_kvm_event(struct perf_kvm *kvm,
BUG_ON(key->key == INVALID_KEY);
head = &kvm->kvm_events_cache[kvm_events_hash_fn(key->key)];
- list_for_each_entry(event, head, hash_entry)
+ list_for_each_entry(event, head, hash_entry) {
if (event->key.key == key->key && event->key.info == key->info)
return event;
+ }
event = kvm_alloc_init_event(key);
if (!event)
@@ -381,7 +383,7 @@ static struct kvm_event *find_create_kvm_event(struct perf_kvm *kvm,
return event;
}
-static bool handle_begin_event(struct perf_kvm *kvm,
+static bool handle_begin_event(struct perf_kvm_stat *kvm,
struct vcpu_event_record *vcpu_record,
struct event_key *key, u64 timestamp)
{
@@ -416,7 +418,10 @@ static double kvm_event_rel_stddev(int vcpu_id, struct kvm_event *event)
static bool update_kvm_event(struct kvm_event *event, int vcpu_id,
u64 time_diff)
{
- kvm_update_event_stats(&event->total, time_diff);
+ if (vcpu_id == -1) {
+ kvm_update_event_stats(&event->total, time_diff);
+ return true;
+ }
if (!kvm_event_expand(event, vcpu_id))
return false;
@@ -425,13 +430,19 @@ static bool update_kvm_event(struct kvm_event *event, int vcpu_id,
return true;
}
-static bool handle_end_event(struct perf_kvm *kvm,
+static bool handle_end_event(struct perf_kvm_stat *kvm,
struct vcpu_event_record *vcpu_record,
struct event_key *key,
u64 timestamp)
{
struct kvm_event *event;
u64 time_begin, time_diff;
+ int vcpu;
+
+ if (kvm->trace_vcpu == -1)
+ vcpu = -1;
+ else
+ vcpu = vcpu_record->vcpu_id;
event = vcpu_record->last_event;
time_begin = vcpu_record->start_time;
@@ -461,7 +472,7 @@ static bool handle_end_event(struct perf_kvm *kvm,
BUG_ON(timestamp < time_begin);
time_diff = timestamp - time_begin;
- return update_kvm_event(event, vcpu_record->vcpu_id, time_diff);
+ return update_kvm_event(event, vcpu, time_diff);
}
static
@@ -486,7 +497,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
return thread->priv;
}
-static bool handle_kvm_event(struct perf_kvm *kvm,
+static bool handle_kvm_event(struct perf_kvm_stat *kvm,
struct thread *thread,
struct perf_evsel *evsel,
struct perf_sample *sample)
@@ -498,6 +509,11 @@ static bool handle_kvm_event(struct perf_kvm *kvm,
if (!vcpu_record)
return true;
+ /* only process events for vcpus user cares about */
+ if ((kvm->trace_vcpu != -1) &&
+ (kvm->trace_vcpu != vcpu_record->vcpu_id))
+ return true;
+
if (kvm->events_ops->is_begin_event(evsel, sample, &key))
return handle_begin_event(kvm, vcpu_record, &key, sample->time);
@@ -541,7 +557,7 @@ static struct kvm_event_key keys[] = {
{ NULL, NULL }
};
-static bool select_key(struct perf_kvm *kvm)
+static bool select_key(struct perf_kvm_stat *kvm)
{
int i;
@@ -577,7 +593,8 @@ static void insert_to_result(struct rb_root *result, struct kvm_event *event,
rb_insert_color(&event->rb, result);
}
-static void update_total_count(struct perf_kvm *kvm, struct kvm_event *event)
+static void
+update_total_count(struct perf_kvm_stat *kvm, struct kvm_event *event)
{
int vcpu = kvm->trace_vcpu;
@@ -590,19 +607,21 @@ static bool event_is_valid(struct kvm_event *event, int vcpu)
return !!get_event_count(event, vcpu);
}
-static void sort_result(struct perf_kvm *kvm)
+static void sort_result(struct perf_kvm_stat *kvm)
{
unsigned int i;
int vcpu = kvm->trace_vcpu;
struct kvm_event *event;
- for (i = 0; i < EVENTS_CACHE_SIZE; i++)
- list_for_each_entry(event, &kvm->kvm_events_cache[i], hash_entry)
+ for (i = 0; i < EVENTS_CACHE_SIZE; i++) {
+ list_for_each_entry(event, &kvm->kvm_events_cache[i], hash_entry) {
if (event_is_valid(event, vcpu)) {
update_total_count(kvm, event);
insert_to_result(&kvm->result, event,
kvm->compare, vcpu);
}
+ }
+ }
}
/* returns left most element of result, and erase it */
@@ -627,7 +646,7 @@ static void print_vcpu_info(int vcpu)
pr_info("VCPU %d:\n\n", vcpu);
}
-static void print_result(struct perf_kvm *kvm)
+static void print_result(struct perf_kvm_stat *kvm)
{
char decode[20];
struct kvm_event *event;
@@ -659,8 +678,8 @@ static void print_result(struct perf_kvm *kvm)
pr_info("\n");
}
- pr_info("\nTotal Samples:%lld, Total events handled time:%.2fus.\n\n",
- (unsigned long long)kvm->total_count, kvm->total_time / 1e3);
+ pr_info("\nTotal Samples:%" PRIu64 ", Total events handled time:%.2fus.\n\n",
+ kvm->total_count, kvm->total_time / 1e3);
}
static int process_sample_event(struct perf_tool *tool,
@@ -670,7 +689,8 @@ static int process_sample_event(struct perf_tool *tool,
struct machine *machine)
{
struct thread *thread = machine__findnew_thread(machine, sample->tid);
- struct perf_kvm *kvm = container_of(tool, struct perf_kvm, tool);
+ struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat,
+ tool);
if (thread == NULL) {
pr_debug("problem processing %d event, skipping it.\n",
@@ -701,7 +721,7 @@ static int get_cpu_isa(struct perf_session *session)
return isa;
}
-static int read_events(struct perf_kvm *kvm)
+static int read_events(struct perf_kvm_stat *kvm)
{
int ret;
@@ -750,7 +770,7 @@ static bool verify_vcpu(int vcpu)
return true;
}
-static int kvm_events_report_vcpu(struct perf_kvm *kvm)
+static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm)
{
int ret = -EINVAL;
int vcpu = kvm->trace_vcpu;
@@ -798,7 +818,8 @@ static const char * const record_args[] = {
_p; \
})
-static int kvm_events_record(struct perf_kvm *kvm, int argc, const char **argv)
+static int
+kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
{
unsigned int rec_argc, i, j;
const char **rec_argv;
@@ -821,7 +842,8 @@ static int kvm_events_record(struct perf_kvm *kvm, int argc, const char **argv)
return cmd_record(i, rec_argv, NULL);
}
-static int kvm_events_report(struct perf_kvm *kvm, int argc, const char **argv)
+static int
+kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
{
const struct option kvm_events_report_options[] = {
OPT_STRING(0, "event", &kvm->report_event, "report event",
@@ -864,24 +886,37 @@ static void print_kvm_stat_usage(void)
printf("\nOtherwise, it is the alias of 'perf stat':\n");
}
-static int kvm_cmd_stat(struct perf_kvm *kvm, int argc, const char **argv)
+static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
{
+ struct perf_kvm_stat kvm = {
+ .file_name = file_name,
+
+ .trace_vcpu = -1,
+ .report_event = "vmexit",
+ .sort_key = "sample",
+
+ .exit_reasons = svm_exit_reasons,
+ .exit_reasons_size = ARRAY_SIZE(svm_exit_reasons),
+ .exit_reasons_isa = "SVM",
+ };
+
if (argc == 1) {
print_kvm_stat_usage();
goto perf_stat;
}
if (!strncmp(argv[1], "rec", 3))
- return kvm_events_record(kvm, argc - 1, argv + 1);
+ return kvm_events_record(&kvm, argc - 1, argv + 1);
if (!strncmp(argv[1], "rep", 3))
- return kvm_events_report(kvm, argc - 1 , argv + 1);
+ return kvm_events_report(&kvm, argc - 1 , argv + 1);
perf_stat:
return cmd_stat(argc, argv, NULL);
}
+#endif
-static int __cmd_record(struct perf_kvm *kvm, int argc, const char **argv)
+static int __cmd_record(const char *file_name, int argc, const char **argv)
{
int rec_argc, i = 0, j;
const char **rec_argv;
@@ -890,7 +925,7 @@ static int __cmd_record(struct perf_kvm *kvm, int argc, const char **argv)
rec_argv = calloc(rec_argc + 1, sizeof(char *));
rec_argv[i++] = strdup("record");
rec_argv[i++] = strdup("-o");
- rec_argv[i++] = strdup(kvm->file_name);
+ rec_argv[i++] = strdup(file_name);
for (j = 1; j < argc; j++, i++)
rec_argv[i] = argv[j];
@@ -899,7 +934,7 @@ static int __cmd_record(struct perf_kvm *kvm, int argc, const char **argv)
return cmd_record(i, rec_argv, NULL);
}
-static int __cmd_report(struct perf_kvm *kvm, int argc, const char **argv)
+static int __cmd_report(const char *file_name, int argc, const char **argv)
{
int rec_argc, i = 0, j;
const char **rec_argv;
@@ -908,7 +943,7 @@ static int __cmd_report(struct perf_kvm *kvm, int argc, const char **argv)
rec_argv = calloc(rec_argc + 1, sizeof(char *));
rec_argv[i++] = strdup("report");
rec_argv[i++] = strdup("-i");
- rec_argv[i++] = strdup(kvm->file_name);
+ rec_argv[i++] = strdup(file_name);
for (j = 1; j < argc; j++, i++)
rec_argv[i] = argv[j];
@@ -917,7 +952,8 @@ static int __cmd_report(struct perf_kvm *kvm, int argc, const char **argv)
return cmd_report(i, rec_argv, NULL);
}
-static int __cmd_buildid_list(struct perf_kvm *kvm, int argc, const char **argv)
+static int
+__cmd_buildid_list(const char *file_name, int argc, const char **argv)
{
int rec_argc, i = 0, j;
const char **rec_argv;
@@ -926,7 +962,7 @@ static int __cmd_buildid_list(struct perf_kvm *kvm, int argc, const char **argv)
rec_argv = calloc(rec_argc + 1, sizeof(char *));
rec_argv[i++] = strdup("buildid-list");
rec_argv[i++] = strdup("-i");
- rec_argv[i++] = strdup(kvm->file_name);
+ rec_argv[i++] = strdup(file_name);
for (j = 1; j < argc; j++, i++)
rec_argv[i] = argv[j];
@@ -937,20 +973,12 @@ static int __cmd_buildid_list(struct perf_kvm *kvm, int argc, const char **argv)
int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
{
- struct perf_kvm kvm = {
- .trace_vcpu = -1,
- .report_event = "vmexit",
- .sort_key = "sample",
-
- .exit_reasons = svm_exit_reasons,
- .exit_reasons_size = ARRAY_SIZE(svm_exit_reasons),
- .exit_reasons_isa = "SVM",
- };
+ const char *file_name;
const struct option kvm_options[] = {
- OPT_STRING('i', "input", &kvm.file_name, "file",
+ OPT_STRING('i', "input", &file_name, "file",
"Input file name"),
- OPT_STRING('o', "output", &kvm.file_name, "file",
+ OPT_STRING('o', "output", &file_name, "file",
"Output file name"),
OPT_BOOLEAN(0, "guest", &perf_guest,
"Collect guest os data"),
@@ -985,32 +1013,34 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
if (!perf_host)
perf_guest = 1;
- if (!kvm.file_name) {
+ if (!file_name) {
if (perf_host && !perf_guest)
- kvm.file_name = strdup("perf.data.host");
+ file_name = strdup("perf.data.host");
else if (!perf_host && perf_guest)
- kvm.file_name = strdup("perf.data.guest");
+ file_name = strdup("perf.data.guest");
else
- kvm.file_name = strdup("perf.data.kvm");
+ file_name = strdup("perf.data.kvm");
- if (!kvm.file_name) {
+ if (!file_name) {
pr_err("Failed to allocate memory for filename\n");
return -ENOMEM;
}
}
if (!strncmp(argv[0], "rec", 3))
- return __cmd_record(&kvm, argc, argv);
+ return __cmd_record(file_name, argc, argv);
else if (!strncmp(argv[0], "rep", 3))
- return __cmd_report(&kvm, argc, argv);
+ return __cmd_report(file_name, argc, argv);
else if (!strncmp(argv[0], "diff", 4))
return cmd_diff(argc, argv, NULL);
else if (!strncmp(argv[0], "top", 3))
return cmd_top(argc, argv, NULL);
else if (!strncmp(argv[0], "buildid-list", 12))
- return __cmd_buildid_list(&kvm, argc, argv);
+ return __cmd_buildid_list(file_name, argc, argv);
+#if defined(__i386__) || defined(__x86_64__)
else if (!strncmp(argv[0], "stat", 4))
- return kvm_cmd_stat(&kvm, argc, argv);
+ return kvm_cmd_stat(file_name, argc, argv);
+#endif
else
usage_with_options(kvm_usage, kvm_options);
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 6f5f328157a..42583006974 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -335,8 +335,6 @@ alloc_failed:
return NULL;
}
-static const char *input_name;
-
struct trace_lock_handler {
int (*acquire_event)(struct perf_evsel *evsel,
struct perf_sample *sample);
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index e9231659754..f3151d3c70c 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -31,6 +31,38 @@
#include <sched.h>
#include <sys/mman.h>
+#ifndef HAVE_ON_EXIT
+#ifndef ATEXIT_MAX
+#define ATEXIT_MAX 32
+#endif
+static int __on_exit_count = 0;
+typedef void (*on_exit_func_t) (int, void *);
+static on_exit_func_t __on_exit_funcs[ATEXIT_MAX];
+static void *__on_exit_args[ATEXIT_MAX];
+static int __exitcode = 0;
+static void __handle_on_exit_funcs(void);
+static int on_exit(on_exit_func_t function, void *arg);
+#define exit(x) (exit)(__exitcode = (x))
+
+static int on_exit(on_exit_func_t function, void *arg)
+{
+ if (__on_exit_count == ATEXIT_MAX)
+ return -ENOMEM;
+ else if (__on_exit_count == 0)
+ atexit(__handle_on_exit_funcs);
+ __on_exit_funcs[__on_exit_count] = function;
+ __on_exit_args[__on_exit_count++] = arg;
+ return 0;
+}
+
+static void __handle_on_exit_funcs(void)
+{
+ int i;
+ for (i = 0; i < __on_exit_count; i++)
+ __on_exit_funcs[i] (__exitcode, __on_exit_args[i]);
+}
+#endif
+
enum write_mode_t {
WRITE_FORCE,
WRITE_APPEND
@@ -198,11 +230,15 @@ static int perf_record__open(struct perf_record *rec)
struct perf_record_opts *opts = &rec->opts;
int rc = 0;
- perf_evlist__config_attrs(evlist, opts);
-
+ /*
+ * Set the evsel leader links before we configure attributes,
+ * since some might depend on this info.
+ */
if (opts->group)
perf_evlist__set_leader(evlist);
+ perf_evlist__config_attrs(evlist, opts);
+
list_for_each_entry(pos, &evlist->entries, node) {
struct perf_event_attr *attr = &pos->attr;
/*
@@ -285,6 +321,11 @@ try_again:
perf_evsel__name(pos));
rc = -err;
goto out;
+ } else if ((err == EOPNOTSUPP) && (attr->precise_ip)) {
+ ui__error("\'precise\' request may not be supported. "
+ "Try removing 'p' modifier\n");
+ rc = -err;
+ goto out;
}
printf("\n");
@@ -326,7 +367,8 @@ 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)) {
+ } 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 {
@@ -460,6 +502,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
struct perf_evlist *evsel_list = rec->evlist;
const char *output_name = rec->output_name;
struct perf_session *session;
+ bool disabled = false;
rec->progname = argv[0];
@@ -659,7 +702,13 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
}
}
- perf_evlist__enable(evsel_list);
+ /*
+ * When perf is starting the traced process, all the events
+ * (apart from group members) have enable_on_exec=1 set,
+ * so don't spoil it by prematurely enabling them.
+ */
+ if (!perf_target__none(&opts->target))
+ perf_evlist__enable(evsel_list);
/*
* Let the child rip
@@ -682,8 +731,15 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
waking++;
}
- if (done)
+ /*
+ * When perf is starting the traced process, at the end events
+ * die with the process and we wait for that. Thus no need to
+ * disable events in this case.
+ */
+ if (done && !disabled && !perf_target__none(&opts->target)) {
perf_evlist__disable(evsel_list);
+ disabled = true;
+ }
}
if (quiet || signr == SIGUSR1)
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index a61725d89d3..fc251005dd3 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -33,13 +33,13 @@
#include "util/thread.h"
#include "util/sort.h"
#include "util/hist.h"
+#include "arch/common.h"
#include <linux/bitmap.h>
struct perf_report {
struct perf_tool tool;
struct perf_session *session;
- char const *input_name;
bool force, use_tui, use_gtk, use_stdio;
bool hide_unresolved;
bool dont_use_callchains;
@@ -428,10 +428,11 @@ static int __cmd_report(struct perf_report *rep)
if (use_browser > 0) {
if (use_browser == 1) {
perf_evlist__tui_browse_hists(session->evlist, help,
- NULL, NULL, 0);
+ NULL,
+ &session->header.env);
} else if (use_browser == 2) {
perf_evlist__gtk_browse_hists(session->evlist, help,
- NULL, NULL, 0);
+ NULL);
}
} else
perf_evlist__tty_browse_hists(session->evlist, rep, help);
@@ -556,8 +557,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
.sample = process_sample_event,
.mmap = perf_event__process_mmap,
.comm = perf_event__process_comm,
- .exit = perf_event__process_task,
- .fork = perf_event__process_task,
+ .exit = perf_event__process_exit,
+ .fork = perf_event__process_fork,
.lost = perf_event__process_lost,
.read = process_read_event,
.attr = perf_event__process_attr,
@@ -570,7 +571,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
.pretty_printing_style = "normal",
};
const struct option options[] = {
- OPT_STRING('i', "input", &report.input_name, "file",
+ OPT_STRING('i', "input", &input_name, "file",
"input file name"),
OPT_INCR('v', "verbose", &verbose,
"be more verbose (show symbol address, etc)"),
@@ -656,13 +657,13 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
if (report.inverted_callchain)
callchain_param.order = ORDER_CALLER;
- if (!report.input_name || !strlen(report.input_name)) {
+ if (!input_name || !strlen(input_name)) {
if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
- report.input_name = "-";
+ input_name = "-";
else
- report.input_name = "perf.data";
+ input_name = "perf.data";
}
- session = perf_session__new(report.input_name, O_RDONLY,
+ session = perf_session__new(input_name, O_RDONLY,
report.force, false, &report.tool);
if (session == NULL)
return -ENOMEM;
@@ -687,7 +688,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
}
- if (strcmp(report.input_name, "-") != 0)
+ if (strcmp(input_name, "-") != 0)
setup_browser(true);
else {
use_browser = 0;
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 3488ead3b60..cc28b85dabd 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -120,7 +120,6 @@ struct trace_sched_handler {
struct perf_sched {
struct perf_tool tool;
- const char *input_name;
const char *sort_order;
unsigned long nr_tasks;
struct task_desc *pid_to_task[MAX_PID];
@@ -1460,7 +1459,7 @@ static int perf_sched__read_events(struct perf_sched *sched, bool destroy,
};
struct perf_session *session;
- session = perf_session__new(sched->input_name, O_RDONLY, 0, false, &sched->tool);
+ session = perf_session__new(input_name, O_RDONLY, 0, false, &sched->tool);
if (session == NULL) {
pr_debug("No Memory for session\n");
return -1;
@@ -1672,7 +1671,8 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
.sample = perf_sched__process_tracepoint_sample,
.comm = perf_event__process_comm,
.lost = perf_event__process_lost,
- .fork = perf_event__process_task,
+ .exit = perf_event__process_exit,
+ .fork = perf_event__process_fork,
.ordered_samples = true,
},
.cmp_pid = LIST_HEAD_INIT(sched.cmp_pid),
@@ -1707,7 +1707,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
OPT_END()
};
const struct option sched_options[] = {
- OPT_STRING('i', "input", &sched.input_name, "file",
+ OPT_STRING('i', "input", &input_name, "file",
"input file name"),
OPT_INCR('v', "verbose", &verbose,
"be more verbose (show symbol address, etc)"),
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index fb9625083a2..b363e7b292b 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -520,8 +520,8 @@ static struct perf_tool perf_script = {
.sample = process_sample_event,
.mmap = perf_event__process_mmap,
.comm = perf_event__process_comm,
- .exit = perf_event__process_task,
- .fork = perf_event__process_task,
+ .exit = perf_event__process_exit,
+ .fork = perf_event__process_fork,
.attr = perf_event__process_attr,
.event_type = perf_event__process_event_type,
.tracing_data = perf_event__process_tracing_data,
@@ -1030,6 +1030,68 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
}
/*
+ * Some scripts specify the required events in their "xxx-record" file,
+ * this function will check if the events in perf.data match those
+ * mentioned in the "xxx-record".
+ *
+ * Fixme: All existing "xxx-record" are all in good formats "-e event ",
+ * which is covered well now. And new parsing code should be added to
+ * cover the future complexing formats like event groups etc.
+ */
+static int check_ev_match(char *dir_name, char *scriptname,
+ struct perf_session *session)
+{
+ char filename[MAXPATHLEN], evname[128];
+ char line[BUFSIZ], *p;
+ struct perf_evsel *pos;
+ int match, len;
+ FILE *fp;
+
+ sprintf(filename, "%s/bin/%s-record", dir_name, scriptname);
+
+ fp = fopen(filename, "r");
+ if (!fp)
+ return -1;
+
+ while (fgets(line, sizeof(line), fp)) {
+ p = ltrim(line);
+ if (*p == '#')
+ continue;
+
+ while (strlen(p)) {
+ p = strstr(p, "-e");
+ if (!p)
+ break;
+
+ p += 2;
+ p = ltrim(p);
+ len = strcspn(p, " \t");
+ if (!len)
+ break;
+
+ snprintf(evname, len + 1, "%s", p);
+
+ match = 0;
+ list_for_each_entry(pos,
+ &session->evlist->entries, node) {
+ if (!strcmp(perf_evsel__name(pos), evname)) {
+ match = 1;
+ break;
+ }
+ }
+
+ if (!match) {
+ fclose(fp);
+ return -1;
+ }
+ }
+ }
+
+ fclose(fp);
+ return 0;
+}
+
+/*
* Return -1 if none is found, otherwise the actual scripts number.
*
* Currently the only user of this function is the script browser, which
@@ -1039,17 +1101,23 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
int find_scripts(char **scripts_array, char **scripts_path_array)
{
struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
- char scripts_path[MAXPATHLEN];
+ char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
DIR *scripts_dir, *lang_dir;
- char lang_path[MAXPATHLEN];
+ struct perf_session *session;
char *temp;
int i = 0;
+ session = perf_session__new(input_name, O_RDONLY, 0, false, NULL);
+ if (!session)
+ return -1;
+
snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
scripts_dir = opendir(scripts_path);
- if (!scripts_dir)
+ if (!scripts_dir) {
+ perf_session__delete(session);
return -1;
+ }
for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
@@ -1077,10 +1145,18 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
snprintf(scripts_array[i],
(temp - script_dirent.d_name) + 1,
"%s", script_dirent.d_name);
+
+ if (check_ev_match(lang_path,
+ scripts_array[i], session))
+ continue;
+
i++;
}
+ closedir(lang_dir);
}
+ closedir(scripts_dir);
+ perf_session__delete(session);
return i;
}
@@ -1175,7 +1251,6 @@ static int have_cmd(int argc, const char **argv)
int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
{
bool show_full_info = false;
- const char *input_name = NULL;
char *rec_script_path = NULL;
char *rep_script_path = NULL;
struct perf_session *session;
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 93b9011fa3e..c247faca712 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -57,6 +57,7 @@
#include "util/thread.h"
#include "util/thread_map.h"
+#include <stdlib.h>
#include <sys/prctl.h>
#include <locale.h>
@@ -83,6 +84,9 @@ static const char *csv_sep = NULL;
static bool csv_output = false;
static bool group = false;
static FILE *output = NULL;
+static const char *pre_cmd = NULL;
+static const char *post_cmd = NULL;
+static bool sync_run = false;
static volatile int done = 0;
@@ -125,8 +129,7 @@ static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
static struct stats walltime_nsecs_stats;
-static int create_perf_stat_counter(struct perf_evsel *evsel,
- struct perf_evsel *first)
+static int create_perf_stat_counter(struct perf_evsel *evsel)
{
struct perf_event_attr *attr = &evsel->attr;
bool exclude_guest_missing = false;
@@ -149,7 +152,8 @@ retry:
return 0;
}
- if (!perf_target__has_task(&target) && (!group || evsel == first)) {
+ if (!perf_target__has_task(&target) &&
+ !perf_evsel__is_group_member(evsel)) {
attr->disabled = 1;
attr->enable_on_exec = 1;
}
@@ -265,10 +269,10 @@ static int read_counter(struct perf_evsel *counter)
return 0;
}
-static int run_perf_stat(int argc __maybe_unused, const char **argv)
+static int __run_perf_stat(int argc __maybe_unused, const char **argv)
{
unsigned long long t0, t1;
- struct perf_evsel *counter, *first;
+ struct perf_evsel *counter;
int status = 0;
int child_ready_pipe[2], go_pipe[2];
const bool forks = (argc > 0);
@@ -328,10 +332,8 @@ static int run_perf_stat(int argc __maybe_unused, const char **argv)
if (group)
perf_evlist__set_leader(evsel_list);
- first = perf_evlist__first(evsel_list);
-
list_for_each_entry(counter, &evsel_list->entries, node) {
- if (create_perf_stat_counter(counter, first) < 0) {
+ if (create_perf_stat_counter(counter) < 0) {
/*
* PPC returns ENXIO for HW counters until 2.6.37
* (behavior changed with commit b0a873e).
@@ -405,6 +407,32 @@ static int run_perf_stat(int argc __maybe_unused, const char **argv)
return WEXITSTATUS(status);
}
+static int run_perf_stat(int argc __maybe_unused, const char **argv)
+{
+ int ret;
+
+ if (pre_cmd) {
+ ret = system(pre_cmd);
+ if (ret)
+ return ret;
+ }
+
+ if (sync_run)
+ sync();
+
+ ret = __run_perf_stat(argc, argv);
+ if (ret)
+ return ret;
+
+ if (post_cmd) {
+ ret = system(post_cmd);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
+
static void print_noise_pct(double total, double avg)
{
double pct = rel_stddev_stats(total, avg);
@@ -1069,8 +1097,7 @@ static int add_default_attributes(void)
int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
{
- bool append_file = false,
- sync_run = false;
+ bool append_file = false;
int output_fd = 0;
const char *output_name = NULL;
const struct option options[] = {
@@ -1114,6 +1141,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
OPT_INTEGER(0, "log-fd", &output_fd,
"log output to fd, instead of stderr"),
+ OPT_STRING(0, "pre", &pre_cmd, "command",
+ "command to run prior to the measured command"),
+ OPT_STRING(0, "post", &post_cmd, "command",
+ "command to run after to the measured command"),
OPT_END()
};
const char * const stat_usage[] = {
@@ -1238,9 +1269,6 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
fprintf(output, "[ perf stat: executing run #%d ... ]\n",
run_idx + 1);
- if (sync_run)
- sync();
-
status = run_perf_stat(argc, argv);
}
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
deleted file mode 100644
index 484f26cc0c0..00000000000
--- a/tools/perf/builtin-test.c
+++ /dev/null
@@ -1,1547 +0,0 @@
-/*
- * builtin-test.c
- *
- * Builtin regression testing command: ever growing number of sanity tests
- */
-#include "builtin.h"
-
-#include "util/cache.h"
-#include "util/debug.h"
-#include "util/debugfs.h"
-#include "util/evlist.h"
-#include "util/parse-options.h"
-#include "util/parse-events.h"
-#include "util/symbol.h"
-#include "util/thread_map.h"
-#include "util/pmu.h"
-#include "event-parse.h"
-#include "../../include/linux/hw_breakpoint.h"
-
-#include <sys/mman.h>
-
-static int vmlinux_matches_kallsyms_filter(struct map *map __maybe_unused,
- struct symbol *sym)
-{
- bool *visited = symbol__priv(sym);
- *visited = true;
- return 0;
-}
-
-static int test__vmlinux_matches_kallsyms(void)
-{
- int err = -1;
- struct rb_node *nd;
- struct symbol *sym;
- struct map *kallsyms_map, *vmlinux_map;
- struct machine kallsyms, vmlinux;
- enum map_type type = MAP__FUNCTION;
- long page_size = sysconf(_SC_PAGE_SIZE);
- struct ref_reloc_sym ref_reloc_sym = { .name = "_stext", };
-
- /*
- * Step 1:
- *
- * Init the machines that will hold kernel, modules obtained from
- * both vmlinux + .ko files and from /proc/kallsyms split by modules.
- */
- machine__init(&kallsyms, "", HOST_KERNEL_ID);
- machine__init(&vmlinux, "", HOST_KERNEL_ID);
-
- /*
- * Step 2:
- *
- * Create the kernel maps for kallsyms and the DSO where we will then
- * load /proc/kallsyms. Also create the modules maps from /proc/modules
- * and find the .ko files that match them in /lib/modules/`uname -r`/.
- */
- if (machine__create_kernel_maps(&kallsyms) < 0) {
- pr_debug("machine__create_kernel_maps ");
- return -1;
- }
-
- /*
- * Step 3:
- *
- * Load and split /proc/kallsyms into multiple maps, one per module.
- */
- if (machine__load_kallsyms(&kallsyms, "/proc/kallsyms", type, NULL) <= 0) {
- pr_debug("dso__load_kallsyms ");
- goto out;
- }
-
- /*
- * Step 4:
- *
- * kallsyms will be internally on demand sorted by name so that we can
- * find the reference relocation * symbol, i.e. the symbol we will use
- * to see if the running kernel was relocated by checking if it has the
- * same value in the vmlinux file we load.
- */
- kallsyms_map = machine__kernel_map(&kallsyms, type);
-
- sym = map__find_symbol_by_name(kallsyms_map, ref_reloc_sym.name, NULL);
- if (sym == NULL) {
- pr_debug("dso__find_symbol_by_name ");
- goto out;
- }
-
- ref_reloc_sym.addr = sym->start;
-
- /*
- * Step 5:
- *
- * Now repeat step 2, this time for the vmlinux file we'll auto-locate.
- */
- if (machine__create_kernel_maps(&vmlinux) < 0) {
- pr_debug("machine__create_kernel_maps ");
- goto out;
- }
-
- vmlinux_map = machine__kernel_map(&vmlinux, type);
- map__kmap(vmlinux_map)->ref_reloc_sym = &ref_reloc_sym;
-
- /*
- * Step 6:
- *
- * Locate a vmlinux file in the vmlinux path that has a buildid that
- * matches the one of the running kernel.
- *
- * While doing that look if we find the ref reloc symbol, if we find it
- * we'll have its ref_reloc_symbol.unrelocated_addr and then
- * maps__reloc_vmlinux will notice and set proper ->[un]map_ip routines
- * to fixup the symbols.
- */
- if (machine__load_vmlinux_path(&vmlinux, type,
- vmlinux_matches_kallsyms_filter) <= 0) {
- pr_debug("machine__load_vmlinux_path ");
- goto out;
- }
-
- err = 0;
- /*
- * Step 7:
- *
- * Now look at the symbols in the vmlinux DSO and check if we find all of them
- * in the kallsyms dso. For the ones that are in both, check its names and
- * end addresses too.
- */
- for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) {
- struct symbol *pair, *first_pair;
- bool backwards = true;
-
- sym = rb_entry(nd, struct symbol, rb_node);
-
- if (sym->start == sym->end)
- continue;
-
- first_pair = machine__find_kernel_symbol(&kallsyms, type, sym->start, NULL, NULL);
- pair = first_pair;
-
- if (pair && pair->start == sym->start) {
-next_pair:
- if (strcmp(sym->name, pair->name) == 0) {
- /*
- * kallsyms don't have the symbol end, so we
- * set that by using the next symbol start - 1,
- * in some cases we get this up to a page
- * wrong, trace_kmalloc when I was developing
- * this code was one such example, 2106 bytes
- * off the real size. More than that and we
- * _really_ have a problem.
- */
- s64 skew = sym->end - pair->end;
- if (llabs(skew) < page_size)
- continue;
-
- pr_debug("%#" PRIx64 ": diff end addr for %s v: %#" PRIx64 " k: %#" PRIx64 "\n",
- sym->start, sym->name, sym->end, pair->end);
- } else {
- struct rb_node *nnd;
-detour:
- nnd = backwards ? rb_prev(&pair->rb_node) :
- rb_next(&pair->rb_node);
- if (nnd) {
- struct symbol *next = rb_entry(nnd, struct symbol, rb_node);
-
- if (next->start == sym->start) {
- pair = next;
- goto next_pair;
- }
- }
-
- if (backwards) {
- backwards = false;
- pair = first_pair;
- goto detour;
- }
-
- pr_debug("%#" PRIx64 ": diff name v: %s k: %s\n",
- sym->start, sym->name, pair->name);
- }
- } else
- pr_debug("%#" PRIx64 ": %s not on kallsyms\n", sym->start, sym->name);
-
- err = -1;
- }
-
- if (!verbose)
- goto out;
-
- pr_info("Maps only in vmlinux:\n");
-
- for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) {
- struct map *pos = rb_entry(nd, struct map, rb_node), *pair;
- /*
- * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while
- * the kernel will have the path for the vmlinux file being used,
- * so use the short name, less descriptive but the same ("[kernel]" in
- * both cases.
- */
- pair = map_groups__find_by_name(&kallsyms.kmaps, type,
- (pos->dso->kernel ?
- pos->dso->short_name :
- pos->dso->name));
- if (pair)
- pair->priv = 1;
- else
- map__fprintf(pos, stderr);
- }
-
- pr_info("Maps in vmlinux with a different name in kallsyms:\n");
-
- for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) {
- struct map *pos = rb_entry(nd, struct map, rb_node), *pair;
-
- pair = map_groups__find(&kallsyms.kmaps, type, pos->start);
- if (pair == NULL || pair->priv)
- continue;
-
- if (pair->start == pos->start) {
- pair->priv = 1;
- pr_info(" %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as",
- pos->start, pos->end, pos->pgoff, pos->dso->name);
- if (pos->pgoff != pair->pgoff || pos->end != pair->end)
- pr_info(": \n*%" PRIx64 "-%" PRIx64 " %" PRIx64 "",
- pair->start, pair->end, pair->pgoff);
- pr_info(" %s\n", pair->dso->name);
- pair->priv = 1;
- }
- }
-
- pr_info("Maps only in kallsyms:\n");
-
- for (nd = rb_first(&kallsyms.kmaps.maps[type]);
- nd; nd = rb_next(nd)) {
- struct map *pos = rb_entry(nd, struct map, rb_node);
-
- if (!pos->priv)
- map__fprintf(pos, stderr);
- }
-out:
- return err;
-}
-
-#include "util/cpumap.h"
-#include "util/evsel.h"
-#include <sys/types.h>
-
-static int trace_event__id(const char *evname)
-{
- char *filename;
- int err = -1, fd;
-
- if (asprintf(&filename,
- "%s/syscalls/%s/id",
- tracing_events_path, evname) < 0)
- return -1;
-
- fd = open(filename, O_RDONLY);
- if (fd >= 0) {
- char id[16];
- if (read(fd, id, sizeof(id)) > 0)
- err = atoi(id);
- close(fd);
- }
-
- free(filename);
- return err;
-}
-
-static int test__open_syscall_event(void)
-{
- int err = -1, fd;
- struct thread_map *threads;
- struct perf_evsel *evsel;
- struct perf_event_attr attr;
- unsigned int nr_open_calls = 111, i;
- int id = trace_event__id("sys_enter_open");
-
- if (id < 0) {
- pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
- return -1;
- }
-
- threads = thread_map__new(-1, getpid(), UINT_MAX);
- if (threads == NULL) {
- pr_debug("thread_map__new\n");
- return -1;
- }
-
- memset(&attr, 0, sizeof(attr));
- attr.type = PERF_TYPE_TRACEPOINT;
- attr.config = id;
- evsel = perf_evsel__new(&attr, 0);
- if (evsel == NULL) {
- pr_debug("perf_evsel__new\n");
- goto out_thread_map_delete;
- }
-
- if (perf_evsel__open_per_thread(evsel, threads) < 0) {
- pr_debug("failed to open counter: %s, "
- "tweak /proc/sys/kernel/perf_event_paranoid?\n",
- strerror(errno));
- goto out_evsel_delete;
- }
-
- for (i = 0; i < nr_open_calls; ++i) {
- fd = open("/etc/passwd", O_RDONLY);
- close(fd);
- }
-
- if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) {
- pr_debug("perf_evsel__read_on_cpu\n");
- goto out_close_fd;
- }
-
- if (evsel->counts->cpu[0].val != nr_open_calls) {
- pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
- nr_open_calls, evsel->counts->cpu[0].val);
- goto out_close_fd;
- }
-
- err = 0;
-out_close_fd:
- perf_evsel__close_fd(evsel, 1, threads->nr);
-out_evsel_delete:
- perf_evsel__delete(evsel);
-out_thread_map_delete:
- thread_map__delete(threads);
- return err;
-}
-
-#include <sched.h>
-
-static int test__open_syscall_event_on_all_cpus(void)
-{
- int err = -1, fd, cpu;
- struct thread_map *threads;
- struct cpu_map *cpus;
- struct perf_evsel *evsel;
- struct perf_event_attr attr;
- unsigned int nr_open_calls = 111, i;
- cpu_set_t cpu_set;
- int id = trace_event__id("sys_enter_open");
-
- if (id < 0) {
- pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
- return -1;
- }
-
- threads = thread_map__new(-1, getpid(), UINT_MAX);
- if (threads == NULL) {
- pr_debug("thread_map__new\n");
- return -1;
- }
-
- cpus = cpu_map__new(NULL);
- if (cpus == NULL) {
- pr_debug("cpu_map__new\n");
- goto out_thread_map_delete;
- }
-
-
- CPU_ZERO(&cpu_set);
-
- memset(&attr, 0, sizeof(attr));
- attr.type = PERF_TYPE_TRACEPOINT;
- attr.config = id;
- evsel = perf_evsel__new(&attr, 0);
- if (evsel == NULL) {
- pr_debug("perf_evsel__new\n");
- goto out_thread_map_delete;
- }
-
- if (perf_evsel__open(evsel, cpus, threads) < 0) {
- pr_debug("failed to open counter: %s, "
- "tweak /proc/sys/kernel/perf_event_paranoid?\n",
- strerror(errno));
- goto out_evsel_delete;
- }
-
- for (cpu = 0; cpu < cpus->nr; ++cpu) {
- unsigned int ncalls = nr_open_calls + cpu;
- /*
- * XXX eventually lift this restriction in a way that
- * keeps perf building on older glibc installations
- * without CPU_ALLOC. 1024 cpus in 2010 still seems
- * a reasonable upper limit tho :-)
- */
- if (cpus->map[cpu] >= CPU_SETSIZE) {
- pr_debug("Ignoring CPU %d\n", cpus->map[cpu]);
- continue;
- }
-
- CPU_SET(cpus->map[cpu], &cpu_set);
- if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
- pr_debug("sched_setaffinity() failed on CPU %d: %s ",
- cpus->map[cpu],
- strerror(errno));
- goto out_close_fd;
- }
- for (i = 0; i < ncalls; ++i) {
- fd = open("/etc/passwd", O_RDONLY);
- close(fd);
- }
- CPU_CLR(cpus->map[cpu], &cpu_set);
- }
-
- /*
- * Here we need to explicitely preallocate the counts, as if
- * we use the auto allocation it will allocate just for 1 cpu,
- * as we start by cpu 0.
- */
- if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) {
- pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr);
- goto out_close_fd;
- }
-
- err = 0;
-
- for (cpu = 0; cpu < cpus->nr; ++cpu) {
- unsigned int expected;
-
- if (cpus->map[cpu] >= CPU_SETSIZE)
- continue;
-
- if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) {
- pr_debug("perf_evsel__read_on_cpu\n");
- err = -1;
- break;
- }
-
- expected = nr_open_calls + cpu;
- if (evsel->counts->cpu[cpu].val != expected) {
- pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
- expected, cpus->map[cpu], evsel->counts->cpu[cpu].val);
- err = -1;
- }
- }
-
-out_close_fd:
- perf_evsel__close_fd(evsel, 1, threads->nr);
-out_evsel_delete:
- perf_evsel__delete(evsel);
-out_thread_map_delete:
- thread_map__delete(threads);
- return err;
-}
-
-/*
- * This test will generate random numbers of calls to some getpid syscalls,
- * then establish an mmap for a group of events that are created to monitor
- * the syscalls.
- *
- * It will receive the events, using mmap, use its PERF_SAMPLE_ID generated
- * sample.id field to map back to its respective perf_evsel instance.
- *
- * Then it checks if the number of syscalls reported as perf events by
- * the kernel corresponds to the number of syscalls made.
- */
-static int test__basic_mmap(void)
-{
- int err = -1;
- union perf_event *event;
- struct thread_map *threads;
- struct cpu_map *cpus;
- struct perf_evlist *evlist;
- struct perf_event_attr attr = {
- .type = PERF_TYPE_TRACEPOINT,
- .read_format = PERF_FORMAT_ID,
- .sample_type = PERF_SAMPLE_ID,
- .watermark = 0,
- };
- cpu_set_t cpu_set;
- const char *syscall_names[] = { "getsid", "getppid", "getpgrp",
- "getpgid", };
- pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp,
- (void*)getpgid };
-#define nsyscalls ARRAY_SIZE(syscall_names)
- int ids[nsyscalls];
- unsigned int nr_events[nsyscalls],
- expected_nr_events[nsyscalls], i, j;
- struct perf_evsel *evsels[nsyscalls], *evsel;
-
- for (i = 0; i < nsyscalls; ++i) {
- char name[64];
-
- snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]);
- ids[i] = trace_event__id(name);
- if (ids[i] < 0) {
- pr_debug("Is debugfs mounted on /sys/kernel/debug?\n");
- return -1;
- }
- nr_events[i] = 0;
- expected_nr_events[i] = random() % 257;
- }
-
- threads = thread_map__new(-1, getpid(), UINT_MAX);
- if (threads == NULL) {
- pr_debug("thread_map__new\n");
- return -1;
- }
-
- cpus = cpu_map__new(NULL);
- if (cpus == NULL) {
- pr_debug("cpu_map__new\n");
- goto out_free_threads;
- }
-
- CPU_ZERO(&cpu_set);
- CPU_SET(cpus->map[0], &cpu_set);
- sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
- if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
- pr_debug("sched_setaffinity() failed on CPU %d: %s ",
- cpus->map[0], strerror(errno));
- goto out_free_cpus;
- }
-
- evlist = perf_evlist__new(cpus, threads);
- if (evlist == NULL) {
- pr_debug("perf_evlist__new\n");
- goto out_free_cpus;
- }
-
- /* anonymous union fields, can't be initialized above */
- attr.wakeup_events = 1;
- attr.sample_period = 1;
-
- for (i = 0; i < nsyscalls; ++i) {
- attr.config = ids[i];
- evsels[i] = perf_evsel__new(&attr, i);
- if (evsels[i] == NULL) {
- pr_debug("perf_evsel__new\n");
- goto out_free_evlist;
- }
-
- perf_evlist__add(evlist, evsels[i]);
-
- if (perf_evsel__open(evsels[i], cpus, threads) < 0) {
- pr_debug("failed to open counter: %s, "
- "tweak /proc/sys/kernel/perf_event_paranoid?\n",
- strerror(errno));
- goto out_close_fd;
- }
- }
-
- if (perf_evlist__mmap(evlist, 128, true) < 0) {
- pr_debug("failed to mmap events: %d (%s)\n", errno,
- strerror(errno));
- goto out_close_fd;
- }
-
- for (i = 0; i < nsyscalls; ++i)
- for (j = 0; j < expected_nr_events[i]; ++j) {
- int foo = syscalls[i]();
- ++foo;
- }
-
- while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {
- struct perf_sample sample;
-
- if (event->header.type != PERF_RECORD_SAMPLE) {
- pr_debug("unexpected %s event\n",
- perf_event__name(event->header.type));
- goto out_munmap;
- }
-
- err = perf_evlist__parse_sample(evlist, event, &sample);
- if (err) {
- pr_err("Can't parse sample, err = %d\n", err);
- goto out_munmap;
- }
-
- evsel = perf_evlist__id2evsel(evlist, sample.id);
- if (evsel == NULL) {
- pr_debug("event with id %" PRIu64
- " doesn't map to an evsel\n", sample.id);
- goto out_munmap;
- }
- nr_events[evsel->idx]++;
- }
-
- list_for_each_entry(evsel, &evlist->entries, node) {
- if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) {
- pr_debug("expected %d %s events, got %d\n",
- expected_nr_events[evsel->idx],
- perf_evsel__name(evsel), nr_events[evsel->idx]);
- goto out_munmap;
- }
- }
-
- err = 0;
-out_munmap:
- perf_evlist__munmap(evlist);
-out_close_fd:
- for (i = 0; i < nsyscalls; ++i)
- perf_evsel__close_fd(evsels[i], 1, threads->nr);
-out_free_evlist:
- perf_evlist__delete(evlist);
-out_free_cpus:
- cpu_map__delete(cpus);
-out_free_threads:
- thread_map__delete(threads);
- return err;
-#undef nsyscalls
-}
-
-static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t **maskp,
- size_t *sizep)
-{
- cpu_set_t *mask;
- size_t size;
- int i, cpu = -1, nrcpus = 1024;
-realloc:
- mask = CPU_ALLOC(nrcpus);
- size = CPU_ALLOC_SIZE(nrcpus);
- CPU_ZERO_S(size, mask);
-
- if (sched_getaffinity(pid, size, mask) == -1) {
- CPU_FREE(mask);
- if (errno == EINVAL && nrcpus < (1024 << 8)) {
- nrcpus = nrcpus << 2;
- goto realloc;
- }
- perror("sched_getaffinity");
- return -1;
- }
-
- for (i = 0; i < nrcpus; i++) {
- if (CPU_ISSET_S(i, size, mask)) {
- if (cpu == -1) {
- cpu = i;
- *maskp = mask;
- *sizep = size;
- } else
- CPU_CLR_S(i, size, mask);
- }
- }
-
- if (cpu == -1)
- CPU_FREE(mask);
-
- return cpu;
-}
-
-static int test__PERF_RECORD(void)
-{
- struct perf_record_opts opts = {
- .target = {
- .uid = UINT_MAX,
- .uses_mmap = true,
- },
- .no_delay = true,
- .freq = 10,
- .mmap_pages = 256,
- };
- cpu_set_t *cpu_mask = NULL;
- size_t cpu_mask_size = 0;
- struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
- struct perf_evsel *evsel;
- struct perf_sample sample;
- const char *cmd = "sleep";
- const char *argv[] = { cmd, "1", NULL, };
- char *bname;
- u64 prev_time = 0;
- bool found_cmd_mmap = false,
- found_libc_mmap = false,
- found_vdso_mmap = false,
- found_ld_mmap = false;
- int err = -1, errs = 0, i, wakeups = 0;
- u32 cpu;
- int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, };
-
- if (evlist == NULL || argv == NULL) {
- pr_debug("Not enough memory to create evlist\n");
- 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
- * perf_evlist__prepare_workload we'll fill in the only thread
- * we're monitoring, the one forked there.
- */
- err = perf_evlist__create_maps(evlist, &opts.target);
- if (err < 0) {
- pr_debug("Not enough memory to create thread/cpu maps\n");
- goto out_delete_evlist;
- }
-
- /*
- * Prepare the workload in argv[] to run, it'll fork it, and then wait
- * for perf_evlist__start_workload() to exec it. This is done this way
- * so that we have time to open the evlist (calling sys_perf_event_open
- * on all the fds) and then mmap them.
- */
- err = perf_evlist__prepare_workload(evlist, &opts, argv);
- if (err < 0) {
- pr_debug("Couldn't run the workload!\n");
- goto out_delete_evlist;
- }
-
- /*
- * Config the evsels, setting attr->comm on the first one, etc.
- */
- evsel = perf_evlist__first(evlist);
- evsel->attr.sample_type |= PERF_SAMPLE_CPU;
- evsel->attr.sample_type |= PERF_SAMPLE_TID;
- evsel->attr.sample_type |= PERF_SAMPLE_TIME;
- perf_evlist__config_attrs(evlist, &opts);
-
- err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask,
- &cpu_mask_size);
- if (err < 0) {
- pr_debug("sched__get_first_possible_cpu: %s\n", strerror(errno));
- goto out_delete_evlist;
- }
-
- cpu = err;
-
- /*
- * So that we can check perf_sample.cpu on all the samples.
- */
- if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, cpu_mask) < 0) {
- pr_debug("sched_setaffinity: %s\n", strerror(errno));
- goto out_free_cpu_mask;
- }
-
- /*
- * Call sys_perf_event_open on all the fds on all the evsels,
- * grouping them if asked to.
- */
- err = perf_evlist__open(evlist);
- if (err < 0) {
- pr_debug("perf_evlist__open: %s\n", strerror(errno));
- goto out_delete_evlist;
- }
-
- /*
- * mmap the first fd on a given CPU and ask for events for the other
- * fds in the same CPU to be injected in the same mmap ring buffer
- * (using ioctl(PERF_EVENT_IOC_SET_OUTPUT)).
- */
- err = perf_evlist__mmap(evlist, opts.mmap_pages, false);
- if (err < 0) {
- pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
- goto out_delete_evlist;
- }
-
- /*
- * Now that all is properly set up, enable the events, they will
- * count just on workload.pid, which will start...
- */
- perf_evlist__enable(evlist);
-
- /*
- * Now!
- */
- perf_evlist__start_workload(evlist);
-
- while (1) {
- int before = total_events;
-
- for (i = 0; i < evlist->nr_mmaps; i++) {
- union perf_event *event;
-
- while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
- const u32 type = event->header.type;
- const char *name = perf_event__name(type);
-
- ++total_events;
- if (type < PERF_RECORD_MAX)
- nr_events[type]++;
-
- err = perf_evlist__parse_sample(evlist, event, &sample);
- if (err < 0) {
- if (verbose)
- perf_event__fprintf(event, stderr);
- pr_debug("Couldn't parse sample\n");
- goto out_err;
- }
-
- if (verbose) {
- pr_info("%" PRIu64" %d ", sample.time, sample.cpu);
- perf_event__fprintf(event, stderr);
- }
-
- if (prev_time > sample.time) {
- pr_debug("%s going backwards in time, prev=%" PRIu64 ", curr=%" PRIu64 "\n",
- name, prev_time, sample.time);
- ++errs;
- }
-
- prev_time = sample.time;
-
- if (sample.cpu != cpu) {
- pr_debug("%s with unexpected cpu, expected %d, got %d\n",
- name, cpu, sample.cpu);
- ++errs;
- }
-
- if ((pid_t)sample.pid != evlist->workload.pid) {
- pr_debug("%s with unexpected pid, expected %d, got %d\n",
- name, evlist->workload.pid, sample.pid);
- ++errs;
- }
-
- if ((pid_t)sample.tid != evlist->workload.pid) {
- pr_debug("%s with unexpected tid, expected %d, got %d\n",
- name, evlist->workload.pid, sample.tid);
- ++errs;
- }
-
- if ((type == PERF_RECORD_COMM ||
- type == PERF_RECORD_MMAP ||
- type == PERF_RECORD_FORK ||
- type == PERF_RECORD_EXIT) &&
- (pid_t)event->comm.pid != evlist->workload.pid) {
- pr_debug("%s with unexpected pid/tid\n", name);
- ++errs;
- }
-
- if ((type == PERF_RECORD_COMM ||
- type == PERF_RECORD_MMAP) &&
- event->comm.pid != event->comm.tid) {
- pr_debug("%s with different pid/tid!\n", name);
- ++errs;
- }
-
- switch (type) {
- case PERF_RECORD_COMM:
- if (strcmp(event->comm.comm, cmd)) {
- pr_debug("%s with unexpected comm!\n", name);
- ++errs;
- }
- break;
- case PERF_RECORD_EXIT:
- goto found_exit;
- case PERF_RECORD_MMAP:
- bname = strrchr(event->mmap.filename, '/');
- if (bname != NULL) {
- if (!found_cmd_mmap)
- found_cmd_mmap = !strcmp(bname + 1, cmd);
- if (!found_libc_mmap)
- found_libc_mmap = !strncmp(bname + 1, "libc", 4);
- if (!found_ld_mmap)
- found_ld_mmap = !strncmp(bname + 1, "ld", 2);
- } else if (!found_vdso_mmap)
- found_vdso_mmap = !strcmp(event->mmap.filename, "[vdso]");
- break;
-
- case PERF_RECORD_SAMPLE:
- /* Just ignore samples for now */
- break;
- default:
- pr_debug("Unexpected perf_event->header.type %d!\n",
- type);
- ++errs;
- }
- }
- }
-
- /*
- * We don't use poll here because at least at 3.1 times the
- * PERF_RECORD_{!SAMPLE} events don't honour
- * perf_event_attr.wakeup_events, just PERF_EVENT_SAMPLE does.
- */
- if (total_events == before && false)
- poll(evlist->pollfd, evlist->nr_fds, -1);
-
- sleep(1);
- if (++wakeups > 5) {
- pr_debug("No PERF_RECORD_EXIT event!\n");
- break;
- }
- }
-
-found_exit:
- if (nr_events[PERF_RECORD_COMM] > 1) {
- pr_debug("Excessive number of PERF_RECORD_COMM events!\n");
- ++errs;
- }
-
- if (nr_events[PERF_RECORD_COMM] == 0) {
- pr_debug("Missing PERF_RECORD_COMM for %s!\n", cmd);
- ++errs;
- }
-
- if (!found_cmd_mmap) {
- pr_debug("PERF_RECORD_MMAP for %s missing!\n", cmd);
- ++errs;
- }
-
- if (!found_libc_mmap) {
- pr_debug("PERF_RECORD_MMAP for %s missing!\n", "libc");
- ++errs;
- }
-
- if (!found_ld_mmap) {
- pr_debug("PERF_RECORD_MMAP for %s missing!\n", "ld");
- ++errs;
- }
-
- if (!found_vdso_mmap) {
- pr_debug("PERF_RECORD_MMAP for %s missing!\n", "[vdso]");
- ++errs;
- }
-out_err:
- perf_evlist__munmap(evlist);
-out_free_cpu_mask:
- CPU_FREE(cpu_mask);
-out_delete_evlist:
- perf_evlist__delete(evlist);
-out:
- return (err < 0 || errs > 0) ? -1 : 0;
-}
-
-
-#if defined(__x86_64__) || defined(__i386__)
-
-#define barrier() asm volatile("" ::: "memory")
-
-static u64 rdpmc(unsigned int counter)
-{
- unsigned int low, high;
-
- asm volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (counter));
-
- return low | ((u64)high) << 32;
-}
-
-static u64 rdtsc(void)
-{
- unsigned int low, high;
-
- asm volatile("rdtsc" : "=a" (low), "=d" (high));
-
- return low | ((u64)high) << 32;
-}
-
-static u64 mmap_read_self(void *addr)
-{
- struct perf_event_mmap_page *pc = addr;
- u32 seq, idx, time_mult = 0, time_shift = 0;
- u64 count, cyc = 0, time_offset = 0, enabled, running, delta;
-
- do {
- seq = pc->lock;
- barrier();
-
- enabled = pc->time_enabled;
- running = pc->time_running;
-
- if (enabled != running) {
- cyc = rdtsc();
- time_mult = pc->time_mult;
- time_shift = pc->time_shift;
- time_offset = pc->time_offset;
- }
-
- idx = pc->index;
- count = pc->offset;
- if (idx)
- count += rdpmc(idx - 1);
-
- barrier();
- } while (pc->lock != seq);
-
- if (enabled != running) {
- u64 quot, rem;
-
- quot = (cyc >> time_shift);
- rem = cyc & ((1 << time_shift) - 1);
- delta = time_offset + quot * time_mult +
- ((rem * time_mult) >> time_shift);
-
- enabled += delta;
- if (idx)
- running += delta;
-
- quot = count / running;
- rem = count % running;
- count = quot * enabled + (rem * enabled) / running;
- }
-
- return count;
-}
-
-/*
- * If the RDPMC instruction faults then signal this back to the test parent task:
- */
-static void segfault_handler(int sig __maybe_unused,
- siginfo_t *info __maybe_unused,
- void *uc __maybe_unused)
-{
- exit(-1);
-}
-
-static int __test__rdpmc(void)
-{
- long page_size = sysconf(_SC_PAGE_SIZE);
- volatile int tmp = 0;
- u64 i, loops = 1000;
- int n;
- int fd;
- void *addr;
- struct perf_event_attr attr = {
- .type = PERF_TYPE_HARDWARE,
- .config = PERF_COUNT_HW_INSTRUCTIONS,
- .exclude_kernel = 1,
- };
- u64 delta_sum = 0;
- struct sigaction sa;
-
- sigfillset(&sa.sa_mask);
- sa.sa_sigaction = segfault_handler;
- sigaction(SIGSEGV, &sa, NULL);
-
- fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
- if (fd < 0) {
- pr_err("Error: sys_perf_event_open() syscall returned "
- "with %d (%s)\n", fd, strerror(errno));
- return -1;
- }
-
- addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0);
- if (addr == (void *)(-1)) {
- pr_err("Error: mmap() syscall returned with (%s)\n",
- strerror(errno));
- goto out_close;
- }
-
- for (n = 0; n < 6; n++) {
- u64 stamp, now, delta;
-
- stamp = mmap_read_self(addr);
-
- for (i = 0; i < loops; i++)
- tmp++;
-
- now = mmap_read_self(addr);
- loops *= 10;
-
- delta = now - stamp;
- pr_debug("%14d: %14Lu\n", n, (long long)delta);
-
- delta_sum += delta;
- }
-
- munmap(addr, page_size);
- pr_debug(" ");
-out_close:
- close(fd);
-
- if (!delta_sum)
- return -1;
-
- return 0;
-}
-
-static int test__rdpmc(void)
-{
- int status = 0;
- int wret = 0;
- int ret;
- int pid;
-
- pid = fork();
- if (pid < 0)
- return -1;
-
- if (!pid) {
- ret = __test__rdpmc();
-
- exit(ret);
- }
-
- wret = waitpid(pid, &status, 0);
- if (wret < 0 || status)
- return -1;
-
- return 0;
-}
-
-#endif
-
-static int test__perf_pmu(void)
-{
- return perf_pmu__test();
-}
-
-static int perf_evsel__roundtrip_cache_name_test(void)
-{
- char name[128];
- int type, op, err = 0, ret = 0, i, idx;
- struct perf_evsel *evsel;
- struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
-
- if (evlist == NULL)
- return -ENOMEM;
-
- for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
- for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
- /* skip invalid cache type */
- if (!perf_evsel__is_cache_op_valid(type, op))
- continue;
-
- for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
- __perf_evsel__hw_cache_type_op_res_name(type, op, i,
- name, sizeof(name));
- err = parse_events(evlist, name, 0);
- if (err)
- ret = err;
- }
- }
- }
-
- idx = 0;
- evsel = perf_evlist__first(evlist);
-
- for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
- for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
- /* skip invalid cache type */
- if (!perf_evsel__is_cache_op_valid(type, op))
- continue;
-
- for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
- __perf_evsel__hw_cache_type_op_res_name(type, op, i,
- name, sizeof(name));
- if (evsel->idx != idx)
- continue;
-
- ++idx;
-
- if (strcmp(perf_evsel__name(evsel), name)) {
- pr_debug("%s != %s\n", perf_evsel__name(evsel), name);
- ret = -1;
- }
-
- evsel = perf_evsel__next(evsel);
- }
- }
- }
-
- perf_evlist__delete(evlist);
- return ret;
-}
-
-static int __perf_evsel__name_array_test(const char *names[], int nr_names)
-{
- int i, err;
- struct perf_evsel *evsel;
- struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
-
- if (evlist == NULL)
- return -ENOMEM;
-
- for (i = 0; i < nr_names; ++i) {
- err = parse_events(evlist, names[i], 0);
- if (err) {
- pr_debug("failed to parse event '%s', err %d\n",
- names[i], err);
- goto out_delete_evlist;
- }
- }
-
- err = 0;
- list_for_each_entry(evsel, &evlist->entries, node) {
- if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) {
- --err;
- pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]);
- }
- }
-
-out_delete_evlist:
- perf_evlist__delete(evlist);
- return err;
-}
-
-#define perf_evsel__name_array_test(names) \
- __perf_evsel__name_array_test(names, ARRAY_SIZE(names))
-
-static int perf_evsel__roundtrip_name_test(void)
-{
- int err = 0, ret = 0;
-
- err = perf_evsel__name_array_test(perf_evsel__hw_names);
- if (err)
- ret = err;
-
- err = perf_evsel__name_array_test(perf_evsel__sw_names);
- if (err)
- ret = err;
-
- err = perf_evsel__roundtrip_cache_name_test();
- if (err)
- ret = err;
-
- return ret;
-}
-
-static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name,
- int size, bool should_be_signed)
-{
- struct format_field *field = perf_evsel__field(evsel, name);
- int is_signed;
- int ret = 0;
-
- if (field == NULL) {
- pr_debug("%s: \"%s\" field not found!\n", evsel->name, name);
- return -1;
- }
-
- is_signed = !!(field->flags | FIELD_IS_SIGNED);
- if (should_be_signed && !is_signed) {
- pr_debug("%s: \"%s\" signedness(%d) is wrong, should be %d\n",
- evsel->name, name, is_signed, should_be_signed);
- ret = -1;
- }
-
- if (field->size != size) {
- pr_debug("%s: \"%s\" size (%d) should be %d!\n",
- evsel->name, name, field->size, size);
- ret = -1;
- }
-
- return ret;
-}
-
-static int perf_evsel__tp_sched_test(void)
-{
- struct perf_evsel *evsel = perf_evsel__newtp("sched", "sched_switch", 0);
- int ret = 0;
-
- if (evsel == NULL) {
- pr_debug("perf_evsel__new\n");
- return -1;
- }
-
- if (perf_evsel__test_field(evsel, "prev_comm", 16, true))
- ret = -1;
-
- if (perf_evsel__test_field(evsel, "prev_pid", 4, true))
- ret = -1;
-
- if (perf_evsel__test_field(evsel, "prev_prio", 4, true))
- ret = -1;
-
- if (perf_evsel__test_field(evsel, "prev_state", 8, true))
- ret = -1;
-
- if (perf_evsel__test_field(evsel, "next_comm", 16, true))
- ret = -1;
-
- if (perf_evsel__test_field(evsel, "next_pid", 4, true))
- ret = -1;
-
- if (perf_evsel__test_field(evsel, "next_prio", 4, true))
- ret = -1;
-
- perf_evsel__delete(evsel);
-
- evsel = perf_evsel__newtp("sched", "sched_wakeup", 0);
-
- if (perf_evsel__test_field(evsel, "comm", 16, true))
- ret = -1;
-
- if (perf_evsel__test_field(evsel, "pid", 4, true))
- ret = -1;
-
- if (perf_evsel__test_field(evsel, "prio", 4, true))
- ret = -1;
-
- if (perf_evsel__test_field(evsel, "success", 4, true))
- ret = -1;
-
- if (perf_evsel__test_field(evsel, "target_cpu", 4, true))
- ret = -1;
-
- return ret;
-}
-
-static int test__syscall_open_tp_fields(void)
-{
- struct perf_record_opts opts = {
- .target = {
- .uid = UINT_MAX,
- .uses_mmap = true,
- },
- .no_delay = true,
- .freq = 1,
- .mmap_pages = 256,
- .raw_samples = true,
- };
- const char *filename = "/etc/passwd";
- int flags = O_RDONLY | O_DIRECTORY;
- struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
- struct perf_evsel *evsel;
- int err = -1, i, nr_events = 0, nr_polls = 0;
-
- if (evlist == NULL) {
- pr_debug("%s: perf_evlist__new\n", __func__);
- goto out;
- }
-
- evsel = perf_evsel__newtp("syscalls", "sys_enter_open", 0);
- if (evsel == NULL) {
- pr_debug("%s: perf_evsel__newtp\n", __func__);
- goto out_delete_evlist;
- }
-
- perf_evlist__add(evlist, evsel);
-
- err = perf_evlist__create_maps(evlist, &opts.target);
- if (err < 0) {
- pr_debug("%s: perf_evlist__create_maps\n", __func__);
- goto out_delete_evlist;
- }
-
- perf_evsel__config(evsel, &opts, evsel);
-
- evlist->threads->map[0] = getpid();
-
- err = perf_evlist__open(evlist);
- if (err < 0) {
- pr_debug("perf_evlist__open: %s\n", strerror(errno));
- goto out_delete_evlist;
- }
-
- err = perf_evlist__mmap(evlist, UINT_MAX, false);
- if (err < 0) {
- pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
- goto out_delete_evlist;
- }
-
- perf_evlist__enable(evlist);
-
- /*
- * Generate the event:
- */
- open(filename, flags);
-
- while (1) {
- int before = nr_events;
-
- for (i = 0; i < evlist->nr_mmaps; i++) {
- union perf_event *event;
-
- while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
- const u32 type = event->header.type;
- int tp_flags;
- struct perf_sample sample;
-
- ++nr_events;
-
- if (type != PERF_RECORD_SAMPLE)
- continue;
-
- err = perf_evsel__parse_sample(evsel, event, &sample);
- if (err) {
- pr_err("Can't parse sample, err = %d\n", err);
- goto out_munmap;
- }
-
- tp_flags = perf_evsel__intval(evsel, &sample, "flags");
-
- if (flags != tp_flags) {
- pr_debug("%s: Expected flags=%#x, got %#x\n",
- __func__, flags, tp_flags);
- goto out_munmap;
- }
-
- goto out_ok;
- }
- }
-
- if (nr_events == before)
- poll(evlist->pollfd, evlist->nr_fds, 10);
-
- if (++nr_polls > 5) {
- pr_debug("%s: no events!\n", __func__);
- goto out_munmap;
- }
- }
-out_ok:
- err = 0;
-out_munmap:
- perf_evlist__munmap(evlist);
-out_delete_evlist:
- perf_evlist__delete(evlist);
-out:
- return err;
-}
-
-static struct test {
- const char *desc;
- int (*func)(void);
-} tests[] = {
- {
- .desc = "vmlinux symtab matches kallsyms",
- .func = test__vmlinux_matches_kallsyms,
- },
- {
- .desc = "detect open syscall event",
- .func = test__open_syscall_event,
- },
- {
- .desc = "detect open syscall event on all cpus",
- .func = test__open_syscall_event_on_all_cpus,
- },
- {
- .desc = "read samples using the mmap interface",
- .func = test__basic_mmap,
- },
- {
- .desc = "parse events tests",
- .func = parse_events__test,
- },
-#if defined(__x86_64__) || defined(__i386__)
- {
- .desc = "x86 rdpmc test",
- .func = test__rdpmc,
- },
-#endif
- {
- .desc = "Validate PERF_RECORD_* events & perf_sample fields",
- .func = test__PERF_RECORD,
- },
- {
- .desc = "Test perf pmu format parsing",
- .func = test__perf_pmu,
- },
- {
- .desc = "Test dso data interface",
- .func = dso__test_data,
- },
- {
- .desc = "roundtrip evsel->name check",
- .func = perf_evsel__roundtrip_name_test,
- },
- {
- .desc = "Check parsing of sched tracepoints fields",
- .func = perf_evsel__tp_sched_test,
- },
- {
- .desc = "Generate and check syscalls:sys_enter_open event fields",
- .func = test__syscall_open_tp_fields,
- },
- {
- .func = NULL,
- },
-};
-
-static bool perf_test__matches(int curr, int argc, const char *argv[])
-{
- int i;
-
- if (argc == 0)
- return true;
-
- for (i = 0; i < argc; ++i) {
- char *end;
- long nr = strtoul(argv[i], &end, 10);
-
- if (*end == '\0') {
- if (nr == curr + 1)
- return true;
- continue;
- }
-
- if (strstr(tests[curr].desc, argv[i]))
- return true;
- }
-
- return false;
-}
-
-static int __cmd_test(int argc, const char *argv[])
-{
- int i = 0;
-
- while (tests[i].func) {
- int curr = i++, err;
-
- if (!perf_test__matches(curr, argc, argv))
- continue;
-
- pr_info("%2d: %s:", i, tests[curr].desc);
- pr_debug("\n--- start ---\n");
- err = tests[curr].func();
- pr_debug("---- end ----\n%s:", tests[curr].desc);
- pr_info(" %s\n", err ? "FAILED!\n" : "Ok");
- }
-
- return 0;
-}
-
-static int perf_test__list(int argc, const char **argv)
-{
- int i = 0;
-
- while (tests[i].func) {
- int curr = i++;
-
- if (argc > 1 && !strstr(tests[curr].desc, argv[1]))
- continue;
-
- pr_info("%2d: %s\n", i, tests[curr].desc);
- }
-
- return 0;
-}
-
-int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)
-{
- const char * const test_usage[] = {
- "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]",
- NULL,
- };
- const struct option test_options[] = {
- OPT_INCR('v', "verbose", &verbose,
- "be more verbose (show symbol address, etc)"),
- OPT_END()
- };
-
- argc = parse_options(argc, argv, test_options, test_usage, 0);
- if (argc >= 1 && !strcmp(argv[0], "list"))
- return perf_test__list(argc, argv);
-
- symbol_conf.priv_size = sizeof(int);
- symbol_conf.sort_by_name = true;
- symbol_conf.try_vmlinux_path = true;
-
- if (symbol__init() < 0)
- return -1;
-
- return __cmd_test(argc, argv);
-}
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index f251b613b2f..ab4cf232b85 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -965,7 +965,7 @@ static void write_svg_file(const char *filename)
svg_close();
}
-static int __cmd_timechart(const char *input_name, const char *output_name)
+static int __cmd_timechart(const char *output_name)
{
struct perf_tool perf_timechart = {
.comm = process_comm_event,
@@ -1061,7 +1061,6 @@ parse_process(const struct option *opt __maybe_unused, const char *arg,
int cmd_timechart(int argc, const char **argv,
const char *prefix __maybe_unused)
{
- const char *input_name;
const char *output_name = "output.svg";
const struct option options[] = {
OPT_STRING('i', "input", &input_name, "file", "input file name"),
@@ -1092,5 +1091,5 @@ int cmd_timechart(int argc, const char **argv,
setup_pager();
- return __cmd_timechart(input_name, output_name);
+ return __cmd_timechart(output_name);
}
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index ff6db808680..c9ff3950cd4 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -26,6 +26,7 @@
#include "util/color.h"
#include "util/evlist.h"
#include "util/evsel.h"
+#include "util/machine.h"
#include "util/session.h"
#include "util/symbol.h"
#include "util/thread.h"
@@ -581,6 +582,11 @@ static void *display_thread_tui(void *arg)
struct perf_evsel *pos;
struct perf_top *top = arg;
const char *help = "For a higher level overview, try: perf top --sort comm,dso";
+ struct hist_browser_timer hbt = {
+ .timer = perf_top__sort_new_samples,
+ .arg = top,
+ .refresh = top->delay_secs,
+ };
perf_top__sort_new_samples(top);
@@ -592,9 +598,8 @@ static void *display_thread_tui(void *arg)
list_for_each_entry(pos, &top->evlist->entries, node)
pos->hists.uid_filter_str = top->target.uid_str;
- perf_evlist__tui_browse_hists(top->evlist, help,
- perf_top__sort_new_samples,
- top, top->delay_secs);
+ perf_evlist__tui_browse_hists(top->evlist, help, &hbt,
+ &top->session->header.env);
exit_browser(0);
exit(0);
@@ -871,7 +876,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);
- perf_event__process(&top->tool, event, &sample, machine);
+ machine__process_event(machine, event);
} else
++session->hists.stats.nr_unknown_events;
}
@@ -976,6 +981,10 @@ try_again:
ui__error("Too many events are opened.\n"
"Try again after reducing the number of events\n");
goto out_err;
+ } else if ((err == EOPNOTSUPP) && (attr->precise_ip)) {
+ ui__error("\'precise\' request may not be supported. "
+ "Try removing 'p' modifier\n");
+ goto out_err;
}
ui__error("The sys_perf_event_open() syscall "
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 7aaee39f677..7932ffa2988 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1,5 +1,8 @@
#include "builtin.h"
+#include "util/color.h"
#include "util/evlist.h"
+#include "util/machine.h"
+#include "util/thread.h"
#include "util/parse-options.h"
#include "util/thread_map.h"
#include "event-parse.h"
@@ -13,15 +16,18 @@ static struct syscall_fmt {
bool errmsg;
bool timeout;
} syscall_fmts[] = {
+ { .name = "access", .errmsg = true, },
{ .name = "arch_prctl", .errmsg = true, .alias = "prctl", },
{ .name = "fstat", .errmsg = true, .alias = "newfstat", },
{ .name = "fstatat", .errmsg = true, .alias = "newfstatat", },
{ .name = "futex", .errmsg = true, },
+ { .name = "open", .errmsg = true, },
{ .name = "poll", .errmsg = true, .timeout = true, },
{ .name = "ppoll", .errmsg = true, .timeout = true, },
{ .name = "read", .errmsg = true, },
{ .name = "recvfrom", .errmsg = true, },
{ .name = "select", .errmsg = true, .timeout = true, },
+ { .name = "socket", .errmsg = true, },
{ .name = "stat", .errmsg = true, .alias = "newstat", },
};
@@ -43,6 +49,57 @@ struct syscall {
struct syscall_fmt *fmt;
};
+static size_t fprintf_duration(unsigned long t, FILE *fp)
+{
+ double duration = (double)t / NSEC_PER_MSEC;
+ size_t printed = fprintf(fp, "(");
+
+ if (duration >= 1.0)
+ printed += color_fprintf(fp, PERF_COLOR_RED, "%6.3f ms", duration);
+ else if (duration >= 0.01)
+ printed += color_fprintf(fp, PERF_COLOR_YELLOW, "%6.3f ms", duration);
+ else
+ printed += color_fprintf(fp, PERF_COLOR_NORMAL, "%6.3f ms", duration);
+ return printed + fprintf(stdout, "): ");
+}
+
+struct thread_trace {
+ u64 entry_time;
+ u64 exit_time;
+ bool entry_pending;
+ unsigned long nr_events;
+ char *entry_str;
+ double runtime_ms;
+};
+
+static struct thread_trace *thread_trace__new(void)
+{
+ return zalloc(sizeof(struct thread_trace));
+}
+
+static struct thread_trace *thread__trace(struct thread *thread)
+{
+ struct thread_trace *ttrace;
+
+ if (thread == NULL)
+ goto fail;
+
+ if (thread->priv == NULL)
+ thread->priv = thread_trace__new();
+
+ if (thread->priv == NULL)
+ goto fail;
+
+ ttrace = thread->priv;
+ ++ttrace->nr_events;
+
+ return ttrace;
+fail:
+ color_fprintf(stdout, PERF_COLOR_RED,
+ "WARNING: not enough memory, dropping samples!\n");
+ return NULL;
+}
+
struct trace {
int audit_machine;
struct {
@@ -50,8 +107,96 @@ struct trace {
struct syscall *table;
} syscalls;
struct perf_record_opts opts;
+ struct machine host;
+ u64 base_time;
+ unsigned long nr_events;
+ bool sched;
+ bool multiple_threads;
+ double duration_filter;
+ double runtime_ms;
};
+static bool trace__filter_duration(struct trace *trace, double t)
+{
+ return t < (trace->duration_filter * NSEC_PER_MSEC);
+}
+
+static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp)
+{
+ double ts = (double)(tstamp - trace->base_time) / NSEC_PER_MSEC;
+
+ return fprintf(fp, "%10.3f ", ts);
+}
+
+static bool done = false;
+
+static void sig_handler(int sig __maybe_unused)
+{
+ done = true;
+}
+
+static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thread,
+ u64 duration, u64 tstamp, FILE *fp)
+{
+ size_t printed = trace__fprintf_tstamp(trace, tstamp, fp);
+ printed += fprintf_duration(duration, fp);
+
+ if (trace->multiple_threads)
+ printed += fprintf(fp, "%d ", thread->pid);
+
+ return printed;
+}
+
+static int trace__process_event(struct machine *machine, union perf_event *event)
+{
+ int ret = 0;
+
+ switch (event->header.type) {
+ case PERF_RECORD_LOST:
+ color_fprintf(stdout, PERF_COLOR_RED,
+ "LOST %" PRIu64 " events!\n", event->lost.lost);
+ ret = machine__process_lost_event(machine, event);
+ default:
+ ret = machine__process_event(machine, event);
+ break;
+ }
+
+ return ret;
+}
+
+static int trace__tool_process(struct perf_tool *tool __maybe_unused,
+ union perf_event *event,
+ struct perf_sample *sample __maybe_unused,
+ struct machine *machine)
+{
+ return trace__process_event(machine, event);
+}
+
+static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
+{
+ int err = symbol__init();
+
+ if (err)
+ return err;
+
+ machine__init(&trace->host, "", HOST_KERNEL_ID);
+ machine__create_kernel_maps(&trace->host);
+
+ if (perf_target__has_task(&trace->opts.target)) {
+ err = perf_event__synthesize_thread_map(NULL, evlist->threads,
+ trace__tool_process,
+ &trace->host);
+ } else {
+ err = perf_event__synthesize_threads(NULL, trace__tool_process,
+ &trace->host);
+ }
+
+ if (err)
+ symbol__exit();
+
+ return err;
+}
+
static int trace__read_syscall_info(struct trace *trace, int id)
{
char tp_name[128];
@@ -93,7 +238,8 @@ static int trace__read_syscall_info(struct trace *trace, int id)
return sc->tp_format != NULL ? 0 : -1;
}
-static size_t syscall__fprintf_args(struct syscall *sc, unsigned long *args, FILE *fp)
+static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
+ unsigned long *args)
{
int i = 0;
size_t printed = 0;
@@ -102,12 +248,15 @@ static size_t syscall__fprintf_args(struct syscall *sc, unsigned long *args, FIL
struct format_field *field;
for (field = sc->tp_format->format.fields->next; field; field = field->next) {
- printed += fprintf(fp, "%s%s: %ld", printed ? ", " : "",
- field->name, args[i++]);
+ printed += scnprintf(bf + printed, size - printed,
+ "%s%s: %ld", printed ? ", " : "",
+ field->name, args[i++]);
}
} else {
while (i < 6) {
- printed += fprintf(fp, "%sarg%d: %ld", printed ? ", " : "", i, args[i]);
+ printed += scnprintf(bf + printed, size - printed,
+ "%sarg%d: %ld",
+ printed ? ", " : "", i, args[i]);
++i;
}
}
@@ -139,17 +288,24 @@ static struct syscall *trace__syscall_info(struct trace *trace,
return &trace->syscalls.table[id];
out_cant_read:
- printf("Problems reading syscall %d information\n", id);
+ printf("Problems reading syscall %d", id);
+ if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL)
+ printf("(%s)", trace->syscalls.table[id].name);
+ puts(" information");
return NULL;
}
static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
struct perf_sample *sample)
{
+ char *msg;
void *args;
+ size_t printed = 0;
+ struct thread *thread = machine__findnew_thread(&trace->host, sample->tid);
struct syscall *sc = trace__syscall_info(trace, evsel, sample);
+ struct thread_trace *ttrace = thread__trace(thread);
- if (sc == NULL)
+ if (ttrace == NULL || sc == NULL)
return -1;
args = perf_evsel__rawptr(evsel, sample, "args");
@@ -158,8 +314,27 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
return -1;
}
- printf("%s(", sc->name);
- syscall__fprintf_args(sc, args, stdout);
+ ttrace = thread->priv;
+
+ if (ttrace->entry_str == NULL) {
+ ttrace->entry_str = malloc(1024);
+ if (!ttrace->entry_str)
+ return -1;
+ }
+
+ ttrace->entry_time = sample->time;
+ msg = ttrace->entry_str;
+ printed += scnprintf(msg + printed, 1024 - printed, "%s(", sc->name);
+
+ printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed, args);
+
+ if (!strcmp(sc->name, "exit_group") || !strcmp(sc->name, "exit")) {
+ if (!trace->duration_filter) {
+ trace__fprintf_entry_head(trace, thread, 1, sample->time, stdout);
+ printf("%-70s\n", ttrace->entry_str);
+ }
+ } else
+ ttrace->entry_pending = true;
return 0;
}
@@ -168,13 +343,37 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
struct perf_sample *sample)
{
int ret;
+ u64 duration = 0;
+ struct thread *thread = machine__findnew_thread(&trace->host, sample->tid);
+ struct thread_trace *ttrace = thread__trace(thread);
struct syscall *sc = trace__syscall_info(trace, evsel, sample);
- if (sc == NULL)
+ if (ttrace == NULL || sc == NULL)
return -1;
ret = perf_evsel__intval(evsel, sample, "ret");
+ ttrace = thread->priv;
+
+ ttrace->exit_time = sample->time;
+
+ if (ttrace->entry_time) {
+ duration = sample->time - ttrace->entry_time;
+ if (trace__filter_duration(trace, duration))
+ goto out;
+ } else if (trace->duration_filter)
+ goto out;
+
+ trace__fprintf_entry_head(trace, thread, duration, sample->time, stdout);
+
+ if (ttrace->entry_pending) {
+ printf("%-70s", ttrace->entry_str);
+ } else {
+ printf(" ... [");
+ color_fprintf(stdout, PERF_COLOR_YELLOW, "continued");
+ printf("]: %s()", sc->name);
+ }
+
if (ret < 0 && sc->fmt && sc->fmt->errmsg) {
char bf[256];
const char *emsg = strerror_r(-ret, bf, sizeof(bf)),
@@ -187,14 +386,44 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
printf(") = %d", ret);
putchar('\n');
+out:
+ ttrace->entry_pending = false;
+
+ 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, sample->tid);
+ struct thread_trace *ttrace = thread__trace(thread);
+
+ if (ttrace == NULL)
+ goto out_dump;
+
+ ttrace->runtime_ms += runtime_ms;
+ trace->runtime_ms += runtime_ms;
+ return 0;
+
+out_dump:
+ printf("%s: comm=%s,pid=%u,runtime=%" PRIu64 ",vruntime=%" PRIu64 ")\n",
+ evsel->name,
+ perf_evsel__strval(evsel, sample, "comm"),
+ (pid_t)perf_evsel__intval(evsel, sample, "pid"),
+ runtime,
+ perf_evsel__intval(evsel, sample, "vruntime"));
return 0;
}
-static int trace__run(struct trace *trace)
+static int trace__run(struct trace *trace, int argc, const char **argv)
{
struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
struct perf_evsel *evsel;
- int err = -1, i, nr_events = 0, before;
+ int err = -1, i;
+ unsigned long before;
+ const bool forks = argc > 0;
if (evlist == NULL) {
printf("Not enough memory to run!\n");
@@ -207,14 +436,38 @@ static int trace__run(struct trace *trace)
goto out_delete_evlist;
}
+ if (trace->sched &&
+ perf_evlist__add_newtp(evlist, "sched", "sched_stat_runtime",
+ trace__sched_stat_runtime)) {
+ printf("Couldn't read the sched_stat_runtime tracepoint information!\n");
+ goto out_delete_evlist;
+ }
+
err = perf_evlist__create_maps(evlist, &trace->opts.target);
if (err < 0) {
printf("Problems parsing the target to trace, check your options!\n");
goto out_delete_evlist;
}
+ err = trace__symbols_init(trace, evlist);
+ if (err < 0) {
+ printf("Problems initializing symbol libraries!\n");
+ goto out_delete_evlist;
+ }
+
perf_evlist__config_attrs(evlist, &trace->opts);
+ signal(SIGCHLD, sig_handler);
+ signal(SIGINT, sig_handler);
+
+ if (forks) {
+ err = perf_evlist__prepare_workload(evlist, &trace->opts, argv);
+ if (err < 0) {
+ printf("Couldn't run the workload!\n");
+ goto out_delete_evlist;
+ }
+ }
+
err = perf_evlist__open(evlist);
if (err < 0) {
printf("Couldn't create the events: %s\n", strerror(errno));
@@ -228,8 +481,13 @@ static int trace__run(struct trace *trace)
}
perf_evlist__enable(evlist);
+
+ if (forks)
+ perf_evlist__start_workload(evlist);
+
+ trace->multiple_threads = evlist->threads->map[0] == -1 || evlist->threads->nr > 1;
again:
- before = nr_events;
+ before = trace->nr_events;
for (i = 0; i < evlist->nr_mmaps; i++) {
union perf_event *event;
@@ -239,19 +497,7 @@ again:
tracepoint_handler handler;
struct perf_sample sample;
- ++nr_events;
-
- switch (type) {
- case PERF_RECORD_SAMPLE:
- break;
- case PERF_RECORD_LOST:
- printf("LOST %" PRIu64 " events!\n", event->lost.lost);
- continue;
- default:
- printf("Unexpected %s event, skipping...\n",
- perf_event__name(type));
- continue;
- }
+ ++trace->nr_events;
err = perf_evlist__parse_sample(evlist, event, &sample);
if (err) {
@@ -259,14 +505,26 @@ again:
continue;
}
+ if (trace->base_time == 0)
+ trace->base_time = sample.time;
+
+ if (type != PERF_RECORD_SAMPLE) {
+ trace__process_event(&trace->host, event);
+ continue;
+ }
+
evsel = perf_evlist__id2evsel(evlist, sample.id);
if (evsel == NULL) {
printf("Unknown tp ID %" PRIu64 ", skipping...\n", sample.id);
continue;
}
- if (evlist->threads->map[0] == -1 || evlist->threads->nr > 1)
- printf("%d ", sample.tid);
+ if (sample.raw_data == NULL) {
+ printf("%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
+ perf_evsel__name(evsel), sample.tid,
+ sample.cpu, sample.raw_size);
+ continue;
+ }
if (sample.raw_data == NULL) {
printf("%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
@@ -280,8 +538,15 @@ again:
}
}
- if (nr_events == before)
+ if (trace->nr_events == before) {
+ if (done)
+ goto out_delete_evlist;
+
poll(evlist->pollfd, evlist->nr_fds, -1);
+ }
+
+ if (done)
+ perf_evlist__disable(evlist);
goto again;
@@ -291,10 +556,65 @@ out:
return err;
}
+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");
+
+ return printed;
+}
+
+static size_t trace__fprintf_thread_summary(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;
+
+ 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);
+ printed += fprintf(fp, " - %-5d :%11lu [", thread->pid, ttrace->nr_events);
+ printed += color_fprintf(fp, color, "%5.1f%%", ratio);
+ printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms);
+ }
+
+ return printed;
+}
+
+static int trace__set_duration(const struct option *opt, const char *str,
+ int unset __maybe_unused)
+{
+ struct trace *trace = opt->value;
+
+ trace->duration_filter = atof(str);
+ return 0;
+}
+
int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
{
const char * const trace_usage[] = {
- "perf trace [<options>]",
+ "perf trace [<options>] [<command>]",
+ "perf trace [<options>] -- <command> [<options>]",
NULL
};
struct trace trace = {
@@ -328,21 +648,38 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
"number of mmap data pages"),
OPT_STRING(0, "uid", &trace.opts.target.uid_str, "user",
"user to profile"),
+ OPT_CALLBACK(0, "duration", &trace, "float",
+ "show only events with duration > N.M ms",
+ trace__set_duration),
+ OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"),
OPT_END()
};
int err;
+ char bf[BUFSIZ];
argc = parse_options(argc, argv, trace_options, trace_usage, 0);
- if (argc)
- usage_with_options(trace_usage, trace_options);
+
+ err = perf_target__validate(&trace.opts.target);
+ if (err) {
+ perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf));
+ printf("%s", bf);
+ return err;
+ }
err = perf_target__parse_uid(&trace.opts.target);
if (err) {
- char bf[BUFSIZ];
perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf));
printf("%s", bf);
return err;
}
- return trace__run(&trace);
+ if (!argc && perf_target__none(&trace.opts.target))
+ trace.opts.target.system_wide = true;
+
+ err = trace__run(&trace, argc, argv);
+
+ if (trace.sched && !err)
+ trace__fprintf_thread_summary(&trace, stdout);
+
+ return err;
}
diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak
index 4add41bb0c7..f5ac77485a4 100644
--- a/tools/perf/config/feature-tests.mak
+++ b/tools/perf/config/feature-tests.mak
@@ -43,6 +43,15 @@ int main(void)
}
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)
@@ -112,7 +121,10 @@ define SOURCE_PYTHON_VERSION
#if PY_VERSION_HEX >= 0x03000000
#error
#endif
-int main(void){}
+int main(void)
+{
+ return 0;
+}
endef
define SOURCE_PYTHON_EMBED
#include <Python.h>
@@ -203,4 +215,13 @@ int main(void)
return audit_open();
}
endef
-endif \ No newline at end of file
+endif
+
+define SOURCE_ON_EXIT
+#include <stdio.h>
+
+int main(void)
+{
+ return on_exit(NULL, NULL);
+}
+endef
diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak
index 8046182a19e..e5413125e6b 100644
--- a/tools/perf/config/utilities.mak
+++ b/tools/perf/config/utilities.mak
@@ -180,9 +180,15 @@ _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)
+# Usage: option = $(call try-cc, source-to-build, cc-options, msg)
+ifndef V
+TRY_CC_OUTPUT= > /dev/null 2>&1
+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" > /dev/null 2>&1 && echo y; \
+ $(CC) -x c - $(2) -o "$$TMP" $(TRY_CC_OUTPUT) && echo y; \
rm -f "$$TMP"')
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 6d50eb0b425..0f661fbce6a 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -24,6 +24,7 @@ const char perf_more_info_string[] =
int use_browser = -1;
static int use_pager = -1;
+const char *input_name;
struct cmd_struct {
const char *cmd;
@@ -84,21 +85,26 @@ int check_pager_config(const char *cmd)
return c.val;
}
-static int tui_command_config(const char *var, const char *value, void *data)
+static int browser_command_config(const char *var, const char *value, void *data)
{
struct pager_config *c = data;
if (!prefixcmp(var, "tui.") && !strcmp(var + 4, c->cmd))
c->val = perf_config_bool(var, value);
+ if (!prefixcmp(var, "gtk.") && !strcmp(var + 4, c->cmd))
+ c->val = perf_config_bool(var, value) ? 2 : 0;
return 0;
}
-/* returns 0 for "no tui", 1 for "use tui", and -1 for "not specified" */
-static int check_tui_config(const char *cmd)
+/*
+ * returns 0 for "no tui", 1 for "use tui", 2 for "use gtk",
+ * and -1 for "not specified"
+ */
+static int check_browser_config(const char *cmd)
{
struct pager_config c;
c.cmd = cmd;
c.val = -1;
- perf_config(tui_command_config, &c);
+ perf_config(browser_command_config, &c);
return c.val;
}
@@ -301,7 +307,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
prefix = NULL; /* setup_perf_directory(); */
if (use_browser == -1)
- use_browser = check_tui_config(p->cmd);
+ use_browser = check_browser_config(p->cmd);
if (use_pager == -1 && p->option & RUN_SETUP)
use_pager = check_pager_config(p->cmd);
@@ -440,6 +446,8 @@ int main(int argc, const char **argv)
{
const char *cmd;
+ page_size = sysconf(_SC_PAGE_SIZE);
+
cmd = perf_extract_argv0_path(argv[0]);
if (!cmd)
cmd = "perf-help";
@@ -481,6 +489,8 @@ int main(int argc, const char **argv)
}
cmd = argv[0];
+ test_attr__init();
+
/*
* We use PATH to find perf commands, but we prepend some higher
* precedence paths: the "--exec-path" option, the PERF_EXEC_PATH
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index c50985eaec4..2c340e7da45 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -5,8 +5,9 @@ struct winsize;
void get_term_dimensions(struct winsize *ws);
+#include <asm/unistd.h>
+
#if defined(__i386__)
-#include "../../arch/x86/include/asm/unistd.h"
#define rmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory")
#define cpu_relax() asm volatile("rep; nop" ::: "memory");
#define CPUINFO_PROC "model name"
@@ -16,7 +17,6 @@ void get_term_dimensions(struct winsize *ws);
#endif
#if defined(__x86_64__)
-#include "../../arch/x86/include/asm/unistd.h"
#define rmb() asm volatile("lfence" ::: "memory")
#define cpu_relax() asm volatile("rep; nop" ::: "memory");
#define CPUINFO_PROC "model name"
@@ -26,20 +26,18 @@ void get_term_dimensions(struct winsize *ws);
#endif
#ifdef __powerpc__
-#include "../../arch/powerpc/include/asm/unistd.h"
+#include "../../arch/powerpc/include/uapi/asm/unistd.h"
#define rmb() asm volatile ("sync" ::: "memory")
#define cpu_relax() asm volatile ("" ::: "memory");
#define CPUINFO_PROC "cpu"
#endif
#ifdef __s390__
-#include "../../arch/s390/include/asm/unistd.h"
#define rmb() asm volatile("bcr 15,0" ::: "memory")
#define cpu_relax() asm volatile("" ::: "memory");
#endif
#ifdef __sh__
-#include "../../arch/sh/include/asm/unistd.h"
#if defined(__SH4A__) || defined(__SH5__)
# define rmb() asm volatile("synco" ::: "memory")
#else
@@ -50,35 +48,30 @@ void get_term_dimensions(struct winsize *ws);
#endif
#ifdef __hppa__
-#include "../../arch/parisc/include/asm/unistd.h"
#define rmb() asm volatile("" ::: "memory")
#define cpu_relax() asm volatile("" ::: "memory");
#define CPUINFO_PROC "cpu"
#endif
#ifdef __sparc__
-#include "../../arch/sparc/include/uapi/asm/unistd.h"
#define rmb() asm volatile("":::"memory")
#define cpu_relax() asm volatile("":::"memory")
#define CPUINFO_PROC "cpu"
#endif
#ifdef __alpha__
-#include "../../arch/alpha/include/asm/unistd.h"
#define rmb() asm volatile("mb" ::: "memory")
#define cpu_relax() asm volatile("" ::: "memory")
#define CPUINFO_PROC "cpu model"
#endif
#ifdef __ia64__
-#include "../../arch/ia64/include/asm/unistd.h"
#define rmb() asm volatile ("mf" ::: "memory")
#define cpu_relax() asm volatile ("hint @pause" ::: "memory")
#define CPUINFO_PROC "model name"
#endif
#ifdef __arm__
-#include "../../arch/arm/include/asm/unistd.h"
/*
* Use the __kuser_memory_barrier helper in the CPU helper page. See
* arch/arm/kernel/entry-armv.S in the kernel source for details.
@@ -89,13 +82,11 @@ void get_term_dimensions(struct winsize *ws);
#endif
#ifdef __aarch64__
-#include "../../arch/arm64/include/asm/unistd.h"
#define rmb() asm volatile("dmb ld" ::: "memory")
#define cpu_relax() asm volatile("yield" ::: "memory")
#endif
#ifdef __mips__
-#include "../../arch/mips/include/asm/unistd.h"
#define rmb() asm volatile( \
".set mips2\n\t" \
"sync\n\t" \
@@ -112,7 +103,7 @@ void get_term_dimensions(struct winsize *ws);
#include <sys/types.h>
#include <sys/syscall.h>
-#include "../../include/uapi/linux/perf_event.h"
+#include <linux/perf_event.h>
#include "util/types.h"
#include <stdbool.h>
@@ -174,13 +165,25 @@ static inline unsigned long long rdclock(void)
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
+extern bool test_attr__enabled;
+void test_attr__init(void);
+void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu,
+ int fd, int group_fd, unsigned long flags);
+
static inline int
sys_perf_event_open(struct perf_event_attr *attr,
pid_t pid, int cpu, int group_fd,
unsigned long flags)
{
- return syscall(__NR_perf_event_open, attr, pid, cpu,
- group_fd, flags);
+ int fd;
+
+ fd = syscall(__NR_perf_event_open, attr, pid, cpu,
+ group_fd, flags);
+
+ if (unlikely(test_attr__enabled))
+ test_attr__open(attr, pid, cpu, fd, group_fd, flags);
+
+ return fd;
}
#define MAX_COUNTERS 256
@@ -208,6 +211,7 @@ struct branch_stack {
struct branch_entry entries[0];
};
+extern const char *input_name;
extern bool perf_host, perf_guest;
extern const char perf_version_string[];
diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c
new file mode 100644
index 00000000000..25638a98625
--- /dev/null
+++ b/tools/perf/tests/attr.c
@@ -0,0 +1,175 @@
+
+/*
+ * The struct perf_event_attr test support.
+ *
+ * This test is embedded inside into perf directly and is governed
+ * by the PERF_TEST_ATTR environment variable and hook inside
+ * sys_perf_event_open function.
+ *
+ * The general idea is to store 'struct perf_event_attr' details for
+ * each event created within single perf command. Each event details
+ * are stored into separate text file. Once perf command is finished
+ * these files can be checked for values we expect for command.
+ *
+ * Besides 'struct perf_event_attr' values we also store 'fd' and
+ * 'group_fd' values to allow checking for groups created.
+ *
+ * This all is triggered by setting PERF_TEST_ATTR environment variable.
+ * It must contain name of existing directory with access and write
+ * permissions. All the event text files are stored there.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include "../perf.h"
+#include "util.h"
+#include "exec_cmd.h"
+#include "tests.h"
+
+#define ENV "PERF_TEST_ATTR"
+
+extern int verbose;
+
+bool test_attr__enabled;
+
+static char *dir;
+
+void test_attr__init(void)
+{
+ dir = getenv(ENV);
+ test_attr__enabled = (dir != NULL);
+}
+
+#define BUFSIZE 1024
+
+#define __WRITE_ASS(str, fmt, data) \
+do { \
+ char buf[BUFSIZE]; \
+ size_t size; \
+ \
+ size = snprintf(buf, BUFSIZE, #str "=%"fmt "\n", data); \
+ if (1 != fwrite(buf, size, 1, file)) { \
+ perror("test attr - failed to write event file"); \
+ fclose(file); \
+ return -1; \
+ } \
+ \
+} while (0)
+
+#define WRITE_ASS(field, fmt) __WRITE_ASS(field, fmt, attr->field)
+
+static int store_event(struct perf_event_attr *attr, pid_t pid, int cpu,
+ int fd, int group_fd, unsigned long flags)
+{
+ FILE *file;
+ char path[PATH_MAX];
+
+ snprintf(path, PATH_MAX, "%s/event-%d-%llu-%d", dir,
+ attr->type, attr->config, fd);
+
+ file = fopen(path, "w+");
+ if (!file) {
+ perror("test attr - failed to open event file");
+ return -1;
+ }
+
+ if (fprintf(file, "[event-%d-%llu-%d]\n",
+ attr->type, attr->config, fd) < 0) {
+ perror("test attr - failed to write event file");
+ fclose(file);
+ return -1;
+ }
+
+ /* syscall arguments */
+ __WRITE_ASS(fd, "d", fd);
+ __WRITE_ASS(group_fd, "d", group_fd);
+ __WRITE_ASS(cpu, "d", cpu);
+ __WRITE_ASS(pid, "d", pid);
+ __WRITE_ASS(flags, "lu", flags);
+
+ /* struct perf_event_attr */
+ WRITE_ASS(type, PRIu32);
+ WRITE_ASS(size, PRIu32);
+ WRITE_ASS(config, "llu");
+ WRITE_ASS(sample_period, "llu");
+ WRITE_ASS(sample_type, "llu");
+ WRITE_ASS(read_format, "llu");
+ WRITE_ASS(disabled, "d");
+ WRITE_ASS(inherit, "d");
+ WRITE_ASS(pinned, "d");
+ WRITE_ASS(exclusive, "d");
+ WRITE_ASS(exclude_user, "d");
+ WRITE_ASS(exclude_kernel, "d");
+ WRITE_ASS(exclude_hv, "d");
+ WRITE_ASS(exclude_idle, "d");
+ WRITE_ASS(mmap, "d");
+ WRITE_ASS(comm, "d");
+ WRITE_ASS(freq, "d");
+ WRITE_ASS(inherit_stat, "d");
+ WRITE_ASS(enable_on_exec, "d");
+ WRITE_ASS(task, "d");
+ WRITE_ASS(watermark, "d");
+ WRITE_ASS(precise_ip, "d");
+ WRITE_ASS(mmap_data, "d");
+ WRITE_ASS(sample_id_all, "d");
+ WRITE_ASS(exclude_host, "d");
+ WRITE_ASS(exclude_guest, "d");
+ WRITE_ASS(exclude_callchain_kernel, "d");
+ WRITE_ASS(exclude_callchain_user, "d");
+ WRITE_ASS(wakeup_events, PRIu32);
+ WRITE_ASS(bp_type, PRIu32);
+ WRITE_ASS(config1, "llu");
+ WRITE_ASS(config2, "llu");
+ WRITE_ASS(branch_sample_type, "llu");
+ WRITE_ASS(sample_regs_user, "llu");
+ WRITE_ASS(sample_stack_user, PRIu32);
+
+ fclose(file);
+ return 0;
+}
+
+void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu,
+ int fd, int group_fd, unsigned long flags)
+{
+ int errno_saved = errno;
+
+ if (store_event(attr, pid, cpu, fd, group_fd, flags))
+ die("test attr FAILED");
+
+ errno = errno_saved;
+}
+
+static int run_dir(const char *d, const char *perf)
+{
+ char cmd[3*PATH_MAX];
+
+ snprintf(cmd, 3*PATH_MAX, "python %s/attr.py -d %s/attr/ -p %s %s",
+ d, d, perf, verbose ? "-v" : "");
+
+ return system(cmd);
+}
+
+int test__attr(void)
+{
+ struct stat st;
+ char path_perf[PATH_MAX];
+ char path_dir[PATH_MAX];
+
+ /* First try developement tree tests. */
+ if (!lstat("./tests", &st))
+ return run_dir("./tests", "./perf");
+
+ /* Then installed path. */
+ snprintf(path_dir, PATH_MAX, "%s/tests", perf_exec_path());
+ snprintf(path_perf, PATH_MAX, "%s/perf", BINDIR);
+
+ if (!lstat(path_dir, &st) &&
+ !lstat(path_perf, &st))
+ return run_dir(path_dir, path_perf);
+
+ fprintf(stderr, " (ommitted)");
+ return 0;
+}
diff --git a/tools/perf/tests/attr.py b/tools/perf/tests/attr.py
new file mode 100644
index 00000000000..e702b82dcb8
--- /dev/null
+++ b/tools/perf/tests/attr.py
@@ -0,0 +1,322 @@
+#! /usr/bin/python
+
+import os
+import sys
+import glob
+import optparse
+import tempfile
+import logging
+import shutil
+import ConfigParser
+
+class Fail(Exception):
+ def __init__(self, test, msg):
+ self.msg = msg
+ self.test = test
+ def getMsg(self):
+ return '\'%s\' - %s' % (self.test.path, self.msg)
+
+class Unsup(Exception):
+ def __init__(self, test):
+ self.test = test
+ def getMsg(self):
+ return '\'%s\'' % self.test.path
+
+class Event(dict):
+ terms = [
+ 'flags',
+ 'type',
+ 'size',
+ 'config',
+ 'sample_period',
+ 'sample_type',
+ 'read_format',
+ 'disabled',
+ 'inherit',
+ 'pinned',
+ 'exclusive',
+ 'exclude_user',
+ 'exclude_kernel',
+ 'exclude_hv',
+ 'exclude_idle',
+ 'mmap',
+ 'comm',
+ 'freq',
+ 'inherit_stat',
+ 'enable_on_exec',
+ 'task',
+ 'watermark',
+ 'precise_ip',
+ 'mmap_data',
+ 'sample_id_all',
+ 'exclude_host',
+ 'exclude_guest',
+ 'exclude_callchain_kernel',
+ 'exclude_callchain_user',
+ 'wakeup_events',
+ 'bp_type',
+ 'config1',
+ 'config2',
+ 'branch_sample_type',
+ 'sample_regs_user',
+ 'sample_stack_user',
+ ]
+
+ def add(self, data):
+ for key, val in data:
+ log.debug(" %s = %s" % (key, val))
+ self[key] = val
+
+ def __init__(self, name, data, base):
+ log.info(" Event %s" % name);
+ self.name = name;
+ self.group = ''
+ self.add(base)
+ self.add(data)
+
+ def compare_data(self, a, b):
+ # Allow multiple values in assignment separated by '|'
+ a_list = a.split('|')
+ b_list = b.split('|')
+
+ for a_item in a_list:
+ for b_item in b_list:
+ if (a_item == b_item):
+ return True
+ elif (a_item == '*') or (b_item == '*'):
+ return True
+
+ return False
+
+ def equal(self, other):
+ for t in Event.terms:
+ log.debug(" [%s] %s %s" % (t, self[t], other[t]));
+ if not self.has_key(t) or not other.has_key(t):
+ return False
+ if not self.compare_data(self[t], other[t]):
+ return False
+ return True
+
+# Test file description needs to have following sections:
+# [config]
+# - just single instance in file
+# - needs to specify:
+# 'command' - perf command name
+# 'args' - special command arguments
+# 'ret' - expected command return value (0 by default)
+#
+# [eventX:base]
+# - one or multiple instances in file
+# - expected values assignments
+class Test(object):
+ def __init__(self, path, options):
+ parser = ConfigParser.SafeConfigParser()
+ parser.read(path)
+
+ log.warning("running '%s'" % path)
+
+ self.path = path
+ self.test_dir = options.test_dir
+ self.perf = options.perf
+ self.command = parser.get('config', 'command')
+ self.args = parser.get('config', 'args')
+
+ try:
+ self.ret = parser.get('config', 'ret')
+ except:
+ self.ret = 0
+
+ self.expect = {}
+ self.result = {}
+ log.info(" loading expected events");
+ self.load_events(path, self.expect)
+
+ def is_event(self, name):
+ if name.find("event") == -1:
+ return False
+ else:
+ return True
+
+ def load_events(self, path, events):
+ parser_event = ConfigParser.SafeConfigParser()
+ parser_event.read(path)
+
+ # The event record section header contains 'event' word,
+ # optionaly followed by ':' allowing to load 'parent
+ # event' first as a base
+ for section in filter(self.is_event, parser_event.sections()):
+
+ parser_items = parser_event.items(section);
+ base_items = {}
+
+ # Read parent event if there's any
+ if (':' in section):
+ base = section[section.index(':') + 1:]
+ parser_base = ConfigParser.SafeConfigParser()
+ parser_base.read(self.test_dir + '/' + base)
+ base_items = parser_base.items('event')
+
+ e = Event(section, parser_items, base_items)
+ events[section] = e
+
+ def run_cmd(self, tempdir):
+ cmd = "PERF_TEST_ATTR=%s %s %s -o %s/perf.data %s" % (tempdir,
+ self.perf, self.command, tempdir, self.args)
+ ret = os.WEXITSTATUS(os.system(cmd))
+
+ log.info(" running '%s' ret %d " % (cmd, ret))
+
+ if ret != int(self.ret):
+ raise Unsup(self)
+
+ def compare(self, expect, result):
+ match = {}
+
+ log.info(" compare");
+
+ # For each expected event find all matching
+ # events in result. Fail if there's not any.
+ for exp_name, exp_event in expect.items():
+ exp_list = []
+ log.debug(" matching [%s]" % exp_name)
+ for res_name, res_event in result.items():
+ log.debug(" to [%s]" % res_name)
+ if (exp_event.equal(res_event)):
+ exp_list.append(res_name)
+ log.debug(" ->OK")
+ else:
+ log.debug(" ->FAIL");
+
+ log.info(" match: [%s] matches %s" % (exp_name, str(exp_list)))
+
+ # we did not any matching event - fail
+ if (not exp_list):
+ raise Fail(self, 'match failure');
+
+ match[exp_name] = exp_list
+
+ # For each defined group in the expected events
+ # check we match the same group in the result.
+ for exp_name, exp_event in expect.items():
+ group = exp_event.group
+
+ if (group == ''):
+ continue
+
+ for res_name in match[exp_name]:
+ res_group = result[res_name].group
+ if res_group not in match[group]:
+ raise Fail(self, 'group failure')
+
+ log.info(" group: [%s] matches group leader %s" %
+ (exp_name, str(match[group])))
+
+ log.info(" matched")
+
+ def resolve_groups(self, events):
+ for name, event in events.items():
+ group_fd = event['group_fd'];
+ if group_fd == '-1':
+ continue;
+
+ for iname, ievent in events.items():
+ if (ievent['fd'] == group_fd):
+ event.group = iname
+ log.debug('[%s] has group leader [%s]' % (name, iname))
+ break;
+
+ def run(self):
+ tempdir = tempfile.mkdtemp();
+
+ try:
+ # run the test script
+ self.run_cmd(tempdir);
+
+ # load events expectation for the test
+ log.info(" loading result events");
+ for f in glob.glob(tempdir + '/event*'):
+ self.load_events(f, self.result);
+
+ # resolve group_fd to event names
+ self.resolve_groups(self.expect);
+ self.resolve_groups(self.result);
+
+ # do the expectation - results matching - both ways
+ self.compare(self.expect, self.result)
+ self.compare(self.result, self.expect)
+
+ finally:
+ # cleanup
+ shutil.rmtree(tempdir)
+
+
+def run_tests(options):
+ for f in glob.glob(options.test_dir + '/' + options.test):
+ try:
+ Test(f, options).run()
+ except Unsup, obj:
+ log.warning("unsupp %s" % obj.getMsg())
+
+def setup_log(verbose):
+ global log
+ level = logging.CRITICAL
+
+ if verbose == 1:
+ level = logging.WARNING
+ if verbose == 2:
+ level = logging.INFO
+ if verbose >= 3:
+ level = logging.DEBUG
+
+ log = logging.getLogger('test')
+ log.setLevel(level)
+ ch = logging.StreamHandler()
+ ch.setLevel(level)
+ formatter = logging.Formatter('%(message)s')
+ ch.setFormatter(formatter)
+ log.addHandler(ch)
+
+USAGE = '''%s [OPTIONS]
+ -d dir # tests dir
+ -p path # perf binary
+ -t test # single test
+ -v # verbose level
+''' % sys.argv[0]
+
+def main():
+ parser = optparse.OptionParser(usage=USAGE)
+
+ parser.add_option("-t", "--test",
+ action="store", type="string", dest="test")
+ parser.add_option("-d", "--test-dir",
+ action="store", type="string", dest="test_dir")
+ parser.add_option("-p", "--perf",
+ action="store", type="string", dest="perf")
+ parser.add_option("-v", "--verbose",
+ action="count", dest="verbose")
+
+ options, args = parser.parse_args()
+ if args:
+ parser.error('FAILED wrong arguments %s' % ' '.join(args))
+ return -1
+
+ setup_log(options.verbose)
+
+ if not options.test_dir:
+ print 'FAILED no -d option specified'
+ sys.exit(-1)
+
+ if not options.test:
+ options.test = 'test*'
+
+ try:
+ run_tests(options)
+
+ except Fail, obj:
+ print "FAILED %s" % obj.getMsg();
+ sys.exit(-1)
+
+ sys.exit(0)
+
+if __name__ == '__main__':
+ main()
diff --git a/tools/perf/tests/attr/README b/tools/perf/tests/attr/README
new file mode 100644
index 00000000000..d102957cd59
--- /dev/null
+++ b/tools/perf/tests/attr/README
@@ -0,0 +1,64 @@
+The struct perf_event_attr test (attr tests) support
+====================================================
+This testing support is embedded into perf directly and is governed
+by the PERF_TEST_ATTR environment variable and hook inside the
+sys_perf_event_open function.
+
+The general idea is to store 'struct perf_event_attr' details for
+each event created within single perf command. Each event details
+are stored into separate text file. Once perf command is finished
+these files are checked for values we expect for command.
+
+The attr tests consist of following parts:
+
+tests/attr.c
+------------
+This is the sys_perf_event_open hook implementation. The hook
+is triggered when the PERF_TEST_ATTR environment variable is
+defined. It must contain name of existing directory with access
+and write permissions.
+
+For each sys_perf_event_open call event details are stored in
+separate file. Besides 'struct perf_event_attr' values we also
+store 'fd' and 'group_fd' values to allow checking for groups.
+
+tests/attr.py
+-------------
+This is the python script that does all the hard work. It reads
+the test definition, executes it and checks results.
+
+tests/attr/
+-----------
+Directory containing all attr test definitions.
+Following tests are defined (with perf commands):
+
+ perf record kill (test-record-basic)
+ perf record -b kill (test-record-branch-any)
+ perf record -j any kill (test-record-branch-filter-any)
+ perf record -j any_call kill (test-record-branch-filter-any_call)
+ perf record -j any_ret kill (test-record-branch-filter-any_ret)
+ perf record -j hv kill (test-record-branch-filter-hv)
+ perf record -j ind_call kill (test-record-branch-filter-ind_call)
+ perf record -j k kill (test-record-branch-filter-k)
+ perf record -j u kill (test-record-branch-filter-u)
+ 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 --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)
+ perf record -i kill (test-record-no-inherit)
+ perf record -n kill (test-record-no-samples)
+ perf record -c 100 -P kill (test-record-period)
+ perf record -R kill (test-record-raw)
+ perf stat -e cycles kill (test-stat-basic)
+ perf stat kill (test-stat-default)
+ perf stat -d kill (test-stat-detailed-1)
+ perf stat -dd kill (test-stat-detailed-2)
+ perf stat -ddd kill (test-stat-detailed-3)
+ perf stat --group -e cycles,instructions kill (test-stat-group)
+ perf stat -e '{cycles,instructions}' kill (test-stat-group1)
+ perf stat -i -e cycles kill (test-stat-no-inherit)
diff --git a/tools/perf/tests/attr/base-record b/tools/perf/tests/attr/base-record
new file mode 100644
index 00000000000..f1485d8e6a0
--- /dev/null
+++ b/tools/perf/tests/attr/base-record
@@ -0,0 +1,39 @@
+[event]
+fd=1
+group_fd=-1
+flags=0
+type=0|1
+size=96
+config=0
+sample_period=4000
+sample_type=263
+read_format=7
+disabled=1
+inherit=1
+pinned=0
+exclusive=0
+exclude_user=0
+exclude_kernel=0
+exclude_hv=0
+exclude_idle=0
+mmap=1
+comm=1
+freq=1
+inherit_stat=0
+enable_on_exec=1
+task=0
+watermark=0
+precise_ip=0
+mmap_data=0
+sample_id_all=1
+exclude_host=0
+exclude_guest=1
+exclude_callchain_kernel=0
+exclude_callchain_user=0
+wakeup_events=0
+bp_type=0
+config1=0
+config2=0
+branch_sample_type=0
+sample_regs_user=0
+sample_stack_user=0
diff --git a/tools/perf/tests/attr/base-stat b/tools/perf/tests/attr/base-stat
new file mode 100644
index 00000000000..4bd79a82784
--- /dev/null
+++ b/tools/perf/tests/attr/base-stat
@@ -0,0 +1,39 @@
+[event]
+fd=1
+group_fd=-1
+flags=0
+type=0
+size=96
+config=0
+sample_period=0
+sample_type=0
+read_format=3
+disabled=1
+inherit=1
+pinned=0
+exclusive=0
+exclude_user=0
+exclude_kernel=0
+exclude_hv=0
+exclude_idle=0
+mmap=0
+comm=0
+freq=0
+inherit_stat=0
+enable_on_exec=1
+task=0
+watermark=0
+precise_ip=0
+mmap_data=0
+sample_id_all=0
+exclude_host=0
+exclude_guest=1
+exclude_callchain_kernel=0
+exclude_callchain_user=0
+wakeup_events=0
+bp_type=0
+config1=0
+config2=0
+branch_sample_type=0
+sample_regs_user=0
+sample_stack_user=0
diff --git a/tools/perf/tests/attr/test-record-basic b/tools/perf/tests/attr/test-record-basic
new file mode 100644
index 00000000000..55c0428370c
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-basic
@@ -0,0 +1,5 @@
+[config]
+command = record
+args = kill >/dev/null 2>&1
+
+[event:base-record]
diff --git a/tools/perf/tests/attr/test-record-branch-any b/tools/perf/tests/attr/test-record-branch-any
new file mode 100644
index 00000000000..1421960ed4e
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-any
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = -b kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=4000
+sample_type=2311
+branch_sample_type=8
diff --git a/tools/perf/tests/attr/test-record-branch-filter-any b/tools/perf/tests/attr/test-record-branch-filter-any
new file mode 100644
index 00000000000..915c4df0e0c
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-filter-any
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = -j any kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=4000
+sample_type=2311
+branch_sample_type=8
diff --git a/tools/perf/tests/attr/test-record-branch-filter-any_call b/tools/perf/tests/attr/test-record-branch-filter-any_call
new file mode 100644
index 00000000000..8708dbd4f37
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-filter-any_call
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = -j any_call kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=4000
+sample_type=2311
+branch_sample_type=16
diff --git a/tools/perf/tests/attr/test-record-branch-filter-any_ret b/tools/perf/tests/attr/test-record-branch-filter-any_ret
new file mode 100644
index 00000000000..0d3607a6dcb
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-filter-any_ret
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = -j any_ret kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=4000
+sample_type=2311
+branch_sample_type=32
diff --git a/tools/perf/tests/attr/test-record-branch-filter-hv b/tools/perf/tests/attr/test-record-branch-filter-hv
new file mode 100644
index 00000000000..f25526740ce
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-filter-hv
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = -j hv kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=4000
+sample_type=2311
+branch_sample_type=8
diff --git a/tools/perf/tests/attr/test-record-branch-filter-ind_call b/tools/perf/tests/attr/test-record-branch-filter-ind_call
new file mode 100644
index 00000000000..e862dd17912
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-filter-ind_call
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = -j ind_call kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=4000
+sample_type=2311
+branch_sample_type=64
diff --git a/tools/perf/tests/attr/test-record-branch-filter-k b/tools/perf/tests/attr/test-record-branch-filter-k
new file mode 100644
index 00000000000..182971e898f
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-filter-k
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = -j k kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=4000
+sample_type=2311
+branch_sample_type=8
diff --git a/tools/perf/tests/attr/test-record-branch-filter-u b/tools/perf/tests/attr/test-record-branch-filter-u
new file mode 100644
index 00000000000..83449ef9e68
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-filter-u
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = -j u kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=4000
+sample_type=2311
+branch_sample_type=8
diff --git a/tools/perf/tests/attr/test-record-count b/tools/perf/tests/attr/test-record-count
new file mode 100644
index 00000000000..2f841de56f6
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-count
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = -c 123 kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=123
+sample_type=7
+freq=0
diff --git a/tools/perf/tests/attr/test-record-data b/tools/perf/tests/attr/test-record-data
new file mode 100644
index 00000000000..6627c3e7534
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-data
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = -d kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=4000
+sample_type=271
+mmap_data=1
diff --git a/tools/perf/tests/attr/test-record-freq b/tools/perf/tests/attr/test-record-freq
new file mode 100644
index 00000000000..600d0f8f258
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-freq
@@ -0,0 +1,6 @@
+[config]
+command = record
+args = -F 100 kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=100
diff --git a/tools/perf/tests/attr/test-record-graph-default b/tools/perf/tests/attr/test-record-graph-default
new file mode 100644
index 00000000000..833d1849d76
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-graph-default
@@ -0,0 +1,6 @@
+[config]
+command = record
+args = -g -- kill >/dev/null 2>&1
+
+[event:base-record]
+sample_type=295
diff --git a/tools/perf/tests/attr/test-record-graph-dwarf b/tools/perf/tests/attr/test-record-graph-dwarf
new file mode 100644
index 00000000000..e93e082f520
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-graph-dwarf
@@ -0,0 +1,10 @@
+[config]
+command = record
+args = -g dwarf -- kill >/dev/null 2>&1
+
+[event:base-record]
+sample_type=12583
+exclude_callchain_user=1
+sample_stack_user=8192
+# TODO different for each arch, no support for that now
+sample_regs_user=*
diff --git a/tools/perf/tests/attr/test-record-graph-fp b/tools/perf/tests/attr/test-record-graph-fp
new file mode 100644
index 00000000000..7cef3743f03
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-graph-fp
@@ -0,0 +1,6 @@
+[config]
+command = record
+args = -g fp kill >/dev/null 2>&1
+
+[event:base-record]
+sample_type=295
diff --git a/tools/perf/tests/attr/test-record-group b/tools/perf/tests/attr/test-record-group
new file mode 100644
index 00000000000..a6599e9a19d
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-group
@@ -0,0 +1,18 @@
+[config]
+command = record
+args = --group -e cycles,instructions kill >/dev/null 2>&1
+
+[event-1:base-record]
+fd=1
+group_fd=-1
+sample_type=327
+
+[event-2:base-record]
+fd=2
+group_fd=1
+config=1
+sample_type=327
+mmap=0
+comm=0
+enable_on_exec=0
+disabled=0
diff --git a/tools/perf/tests/attr/test-record-group1 b/tools/perf/tests/attr/test-record-group1
new file mode 100644
index 00000000000..5a8359da38a
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-group1
@@ -0,0 +1,19 @@
+[config]
+command = record
+args = -e '{cycles,instructions}' kill >/tmp/krava 2>&1
+
+[event-1:base-record]
+fd=1
+group_fd=-1
+sample_type=327
+
+[event-2:base-record]
+fd=2
+group_fd=1
+type=0
+config=1
+sample_type=327
+mmap=0
+comm=0
+enable_on_exec=0
+disabled=0
diff --git a/tools/perf/tests/attr/test-record-no-delay b/tools/perf/tests/attr/test-record-no-delay
new file mode 100644
index 00000000000..f253b78cdbf
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-no-delay
@@ -0,0 +1,9 @@
+[config]
+command = record
+args = -D kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=4000
+sample_type=263
+watermark=0
+wakeup_events=1
diff --git a/tools/perf/tests/attr/test-record-no-inherit b/tools/perf/tests/attr/test-record-no-inherit
new file mode 100644
index 00000000000..9079a25cd64
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-no-inherit
@@ -0,0 +1,7 @@
+[config]
+command = record
+args = -i kill >/dev/null 2>&1
+
+[event:base-record]
+sample_type=259
+inherit=0
diff --git a/tools/perf/tests/attr/test-record-no-samples b/tools/perf/tests/attr/test-record-no-samples
new file mode 100644
index 00000000000..d0141b2418b
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-no-samples
@@ -0,0 +1,6 @@
+[config]
+command = record
+args = -n kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=0
diff --git a/tools/perf/tests/attr/test-record-period b/tools/perf/tests/attr/test-record-period
new file mode 100644
index 00000000000..8abc5314fc5
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-period
@@ -0,0 +1,7 @@
+[config]
+command = record
+args = -c 100 -P kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=100
+freq=0
diff --git a/tools/perf/tests/attr/test-record-raw b/tools/perf/tests/attr/test-record-raw
new file mode 100644
index 00000000000..4a8ef25b5f4
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-raw
@@ -0,0 +1,7 @@
+[config]
+command = record
+args = -R kill >/dev/null 2>&1
+
+[event:base-record]
+sample_period=4000
+sample_type=1415
diff --git a/tools/perf/tests/attr/test-stat-basic b/tools/perf/tests/attr/test-stat-basic
new file mode 100644
index 00000000000..74e17881f2b
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-basic
@@ -0,0 +1,6 @@
+[config]
+command = stat
+args = -e cycles kill >/dev/null 2>&1
+ret = 1
+
+[event:base-stat]
diff --git a/tools/perf/tests/attr/test-stat-default b/tools/perf/tests/attr/test-stat-default
new file mode 100644
index 00000000000..19270f54c96
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-default
@@ -0,0 +1,64 @@
+[config]
+command = stat
+args = kill >/dev/null 2>&1
+ret = 1
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK
+[event1:base-stat]
+fd=1
+type=1
+config=1
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES
+[event2:base-stat]
+fd=2
+type=1
+config=3
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS
+[event3:base-stat]
+fd=3
+type=1
+config=4
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS
+[event4:base-stat]
+fd=4
+type=1
+config=2
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES
+[event5:base-stat]
+fd=5
+type=0
+config=0
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
+[event6:base-stat]
+fd=6
+type=0
+config=7
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND
+[event7:base-stat]
+fd=7
+type=0
+config=8
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS
+[event8:base-stat]
+fd=8
+type=0
+config=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS
+[event9:base-stat]
+fd=9
+type=0
+config=4
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES
+[event10:base-stat]
+fd=10
+type=0
+config=5
diff --git a/tools/perf/tests/attr/test-stat-detailed-1 b/tools/perf/tests/attr/test-stat-detailed-1
new file mode 100644
index 00000000000..51426b87153
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-detailed-1
@@ -0,0 +1,101 @@
+[config]
+command = stat
+args = -d kill >/dev/null 2>&1
+ret = 1
+
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK
+[event1:base-stat]
+fd=1
+type=1
+config=1
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES
+[event2:base-stat]
+fd=2
+type=1
+config=3
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS
+[event3:base-stat]
+fd=3
+type=1
+config=4
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS
+[event4:base-stat]
+fd=4
+type=1
+config=2
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES
+[event5:base-stat]
+fd=5
+type=0
+config=0
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
+[event6:base-stat]
+fd=6
+type=0
+config=7
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND
+[event7:base-stat]
+fd=7
+type=0
+config=8
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS
+[event8:base-stat]
+fd=8
+type=0
+config=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS
+[event9:base-stat]
+fd=9
+type=0
+config=4
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES
+[event10:base-stat]
+fd=10
+type=0
+config=5
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event11:base-stat]
+fd=11
+type=3
+config=0
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event12:base-stat]
+fd=12
+type=3
+config=65536
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_LL << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event13:base-stat]
+fd=13
+type=3
+config=2
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_LL << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event14:base-stat]
+fd=14
+type=3
+config=65538
diff --git a/tools/perf/tests/attr/test-stat-detailed-2 b/tools/perf/tests/attr/test-stat-detailed-2
new file mode 100644
index 00000000000..8de5acc31c2
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-detailed-2
@@ -0,0 +1,155 @@
+[config]
+command = stat
+args = -dd kill >/dev/null 2>&1
+ret = 1
+
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK
+[event1:base-stat]
+fd=1
+type=1
+config=1
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES
+[event2:base-stat]
+fd=2
+type=1
+config=3
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS
+[event3:base-stat]
+fd=3
+type=1
+config=4
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS
+[event4:base-stat]
+fd=4
+type=1
+config=2
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES
+[event5:base-stat]
+fd=5
+type=0
+config=0
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
+[event6:base-stat]
+fd=6
+type=0
+config=7
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND
+[event7:base-stat]
+fd=7
+type=0
+config=8
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS
+[event8:base-stat]
+fd=8
+type=0
+config=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS
+[event9:base-stat]
+fd=9
+type=0
+config=4
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES
+[event10:base-stat]
+fd=10
+type=0
+config=5
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event11:base-stat]
+fd=11
+type=3
+config=0
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event12:base-stat]
+fd=12
+type=3
+config=65536
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_LL << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event13:base-stat]
+fd=13
+type=3
+config=2
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_LL << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event14:base-stat]
+fd=14
+type=3
+config=65538
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_L1I << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event15:base-stat]
+fd=15
+type=3
+config=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_L1I << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event16:base-stat]
+fd=16
+type=3
+config=65537
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_DTLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event17:base-stat]
+fd=17
+type=3
+config=3
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_DTLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event18:base-stat]
+fd=18
+type=3
+config=65539
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_ITLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event19:base-stat]
+fd=19
+type=3
+config=4
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_ITLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event20:base-stat]
+fd=20
+type=3
+config=65540
diff --git a/tools/perf/tests/attr/test-stat-detailed-3 b/tools/perf/tests/attr/test-stat-detailed-3
new file mode 100644
index 00000000000..0a1f45bf7d7
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-detailed-3
@@ -0,0 +1,173 @@
+[config]
+command = stat
+args = -ddd kill >/dev/null 2>&1
+ret = 1
+
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK
+[event1:base-stat]
+fd=1
+type=1
+config=1
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES
+[event2:base-stat]
+fd=2
+type=1
+config=3
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS
+[event3:base-stat]
+fd=3
+type=1
+config=4
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS
+[event4:base-stat]
+fd=4
+type=1
+config=2
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES
+[event5:base-stat]
+fd=5
+type=0
+config=0
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
+[event6:base-stat]
+fd=6
+type=0
+config=7
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND
+[event7:base-stat]
+fd=7
+type=0
+config=8
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS
+[event8:base-stat]
+fd=8
+type=0
+config=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS
+[event9:base-stat]
+fd=9
+type=0
+config=4
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES
+[event10:base-stat]
+fd=10
+type=0
+config=5
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event11:base-stat]
+fd=11
+type=3
+config=0
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event12:base-stat]
+fd=12
+type=3
+config=65536
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_LL << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event13:base-stat]
+fd=13
+type=3
+config=2
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_LL << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event14:base-stat]
+fd=14
+type=3
+config=65538
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_L1I << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event15:base-stat]
+fd=15
+type=3
+config=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_L1I << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event16:base-stat]
+fd=16
+type=3
+config=65537
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_DTLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event17:base-stat]
+fd=17
+type=3
+config=3
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_DTLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event18:base-stat]
+fd=18
+type=3
+config=65539
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_ITLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event19:base-stat]
+fd=19
+type=3
+config=4
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_ITLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event20:base-stat]
+fd=20
+type=3
+config=65540
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event21:base-stat]
+fd=21
+type=3
+config=512
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event22:base-stat]
+fd=22
+type=3
+config=66048
diff --git a/tools/perf/tests/attr/test-stat-group b/tools/perf/tests/attr/test-stat-group
new file mode 100644
index 00000000000..fdc1596a886
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-group
@@ -0,0 +1,15 @@
+[config]
+command = stat
+args = --group -e cycles,instructions kill >/dev/null 2>&1
+ret = 1
+
+[event-1:base-stat]
+fd=1
+group_fd=-1
+
+[event-2:base-stat]
+fd=2
+group_fd=1
+config=1
+disabled=0
+enable_on_exec=0
diff --git a/tools/perf/tests/attr/test-stat-group1 b/tools/perf/tests/attr/test-stat-group1
new file mode 100644
index 00000000000..2a1f86e4a90
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-group1
@@ -0,0 +1,15 @@
+[config]
+command = stat
+args = -e '{cycles,instructions}' kill >/dev/null 2>&1
+ret = 1
+
+[event-1:base-stat]
+fd=1
+group_fd=-1
+
+[event-2:base-stat]
+fd=2
+group_fd=1
+config=1
+disabled=0
+enable_on_exec=0
diff --git a/tools/perf/tests/attr/test-stat-no-inherit b/tools/perf/tests/attr/test-stat-no-inherit
new file mode 100644
index 00000000000..d54b2a1e3e2
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-no-inherit
@@ -0,0 +1,7 @@
+[config]
+command = stat
+args = -i -e cycles kill >/dev/null 2>&1
+ret = 1
+
+[event:base-stat]
+inherit=0
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
new file mode 100644
index 00000000000..186f6753549
--- /dev/null
+++ b/tools/perf/tests/builtin-test.c
@@ -0,0 +1,173 @@
+/*
+ * builtin-test.c
+ *
+ * Builtin regression testing command: ever growing number of sanity tests
+ */
+#include "builtin.h"
+#include "tests.h"
+#include "debug.h"
+#include "color.h"
+#include "parse-options.h"
+#include "symbol.h"
+
+static struct test {
+ const char *desc;
+ int (*func)(void);
+} tests[] = {
+ {
+ .desc = "vmlinux symtab matches kallsyms",
+ .func = test__vmlinux_matches_kallsyms,
+ },
+ {
+ .desc = "detect open syscall event",
+ .func = test__open_syscall_event,
+ },
+ {
+ .desc = "detect open syscall event on all cpus",
+ .func = test__open_syscall_event_on_all_cpus,
+ },
+ {
+ .desc = "read samples using the mmap interface",
+ .func = test__basic_mmap,
+ },
+ {
+ .desc = "parse events tests",
+ .func = test__parse_events,
+ },
+#if defined(__x86_64__) || defined(__i386__)
+ {
+ .desc = "x86 rdpmc test",
+ .func = test__rdpmc,
+ },
+#endif
+ {
+ .desc = "Validate PERF_RECORD_* events & perf_sample fields",
+ .func = test__PERF_RECORD,
+ },
+ {
+ .desc = "Test perf pmu format parsing",
+ .func = test__pmu,
+ },
+ {
+ .desc = "Test dso data interface",
+ .func = test__dso_data,
+ },
+ {
+ .desc = "roundtrip evsel->name check",
+ .func = test__perf_evsel__roundtrip_name_test,
+ },
+ {
+ .desc = "Check parsing of sched tracepoints fields",
+ .func = test__perf_evsel__tp_sched_test,
+ },
+ {
+ .desc = "Generate and check syscalls:sys_enter_open event fields",
+ .func = test__syscall_open_tp_fields,
+ },
+ {
+ .desc = "struct perf_event_attr setup",
+ .func = test__attr,
+ },
+ {
+ .func = NULL,
+ },
+};
+
+static bool perf_test__matches(int curr, int argc, const char *argv[])
+{
+ int i;
+
+ if (argc == 0)
+ return true;
+
+ for (i = 0; i < argc; ++i) {
+ char *end;
+ long nr = strtoul(argv[i], &end, 10);
+
+ if (*end == '\0') {
+ if (nr == curr + 1)
+ return true;
+ continue;
+ }
+
+ if (strstr(tests[curr].desc, argv[i]))
+ return true;
+ }
+
+ return false;
+}
+
+static int __cmd_test(int argc, const char *argv[])
+{
+ int i = 0;
+ int width = 0;
+
+ while (tests[i].func) {
+ int len = strlen(tests[i].desc);
+
+ if (width < len)
+ width = len;
+ ++i;
+ }
+
+ i = 0;
+ while (tests[i].func) {
+ int curr = i++, err;
+
+ if (!perf_test__matches(curr, argc, argv))
+ continue;
+
+ pr_info("%2d: %-*s:", i, width, tests[curr].desc);
+ pr_debug("\n--- start ---\n");
+ err = tests[curr].func();
+ pr_debug("---- end ----\n%s:", tests[curr].desc);
+ if (err)
+ color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
+ else
+ pr_info(" Ok\n");
+ }
+
+ return 0;
+}
+
+static int perf_test__list(int argc, const char **argv)
+{
+ int i = 0;
+
+ while (tests[i].func) {
+ int curr = i++;
+
+ if (argc > 1 && !strstr(tests[curr].desc, argv[1]))
+ continue;
+
+ pr_info("%2d: %s\n", i, tests[curr].desc);
+ }
+
+ return 0;
+}
+
+int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)
+{
+ const char * const test_usage[] = {
+ "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]",
+ NULL,
+ };
+ const struct option test_options[] = {
+ OPT_INCR('v', "verbose", &verbose,
+ "be more verbose (show symbol address, etc)"),
+ OPT_END()
+ };
+
+ argc = parse_options(argc, argv, test_options, test_usage, 0);
+ if (argc >= 1 && !strcmp(argv[0], "list"))
+ return perf_test__list(argc, argv);
+
+ symbol_conf.priv_size = sizeof(int);
+ symbol_conf.sort_by_name = true;
+ symbol_conf.try_vmlinux_path = true;
+
+ if (symbol__init() < 0)
+ return -1;
+
+ return __cmd_test(argc, argv);
+}
diff --git a/tools/perf/util/dso-test-data.c b/tools/perf/tests/dso-data.c
index c6caedeb1d6..5eaffa2de9c 100644
--- a/tools/perf/util/dso-test-data.c
+++ b/tools/perf/tests/dso-data.c
@@ -6,7 +6,9 @@
#include <fcntl.h>
#include <string.h>
+#include "machine.h"
#include "symbol.h"
+#include "tests.h"
#define TEST_ASSERT_VAL(text, cond) \
do { \
@@ -24,6 +26,10 @@ static char *test_file(int size)
unsigned char *buf;
fd = mkstemp(templ);
+ if (fd < 0) {
+ perror("mkstemp failed");
+ return NULL;
+ }
buf = malloc(size);
if (!buf) {
@@ -94,7 +100,7 @@ struct test_data_offset offsets[] = {
},
};
-int dso__test_data(void)
+int test__dso_data(void)
{
struct machine machine;
struct dso *dso;
diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c
new file mode 100644
index 00000000000..e61fc828a15
--- /dev/null
+++ b/tools/perf/tests/evsel-roundtrip-name.c
@@ -0,0 +1,114 @@
+#include "evlist.h"
+#include "evsel.h"
+#include "parse-events.h"
+#include "tests.h"
+
+static int perf_evsel__roundtrip_cache_name_test(void)
+{
+ char name[128];
+ int type, op, err = 0, ret = 0, i, idx;
+ struct perf_evsel *evsel;
+ struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
+
+ if (evlist == NULL)
+ return -ENOMEM;
+
+ for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
+ for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
+ /* skip invalid cache type */
+ if (!perf_evsel__is_cache_op_valid(type, op))
+ continue;
+
+ for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
+ __perf_evsel__hw_cache_type_op_res_name(type, op, i,
+ name, sizeof(name));
+ err = parse_events(evlist, name, 0);
+ if (err)
+ ret = err;
+ }
+ }
+ }
+
+ idx = 0;
+ evsel = perf_evlist__first(evlist);
+
+ for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
+ for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
+ /* skip invalid cache type */
+ if (!perf_evsel__is_cache_op_valid(type, op))
+ continue;
+
+ for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
+ __perf_evsel__hw_cache_type_op_res_name(type, op, i,
+ name, sizeof(name));
+ if (evsel->idx != idx)
+ continue;
+
+ ++idx;
+
+ if (strcmp(perf_evsel__name(evsel), name)) {
+ pr_debug("%s != %s\n", perf_evsel__name(evsel), name);
+ ret = -1;
+ }
+
+ evsel = perf_evsel__next(evsel);
+ }
+ }
+ }
+
+ perf_evlist__delete(evlist);
+ return ret;
+}
+
+static int __perf_evsel__name_array_test(const char *names[], int nr_names)
+{
+ int i, err;
+ struct perf_evsel *evsel;
+ struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
+
+ if (evlist == NULL)
+ return -ENOMEM;
+
+ for (i = 0; i < nr_names; ++i) {
+ err = parse_events(evlist, names[i], 0);
+ if (err) {
+ pr_debug("failed to parse event '%s', err %d\n",
+ names[i], err);
+ goto out_delete_evlist;
+ }
+ }
+
+ err = 0;
+ list_for_each_entry(evsel, &evlist->entries, node) {
+ if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) {
+ --err;
+ pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]);
+ }
+ }
+
+out_delete_evlist:
+ perf_evlist__delete(evlist);
+ return err;
+}
+
+#define perf_evsel__name_array_test(names) \
+ __perf_evsel__name_array_test(names, ARRAY_SIZE(names))
+
+int test__perf_evsel__roundtrip_name_test(void)
+{
+ int err = 0, ret = 0;
+
+ err = perf_evsel__name_array_test(perf_evsel__hw_names);
+ if (err)
+ ret = err;
+
+ err = perf_evsel__name_array_test(perf_evsel__sw_names);
+ if (err)
+ ret = err;
+
+ err = perf_evsel__roundtrip_cache_name_test();
+ if (err)
+ ret = err;
+
+ return ret;
+}
diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-sched.c
new file mode 100644
index 00000000000..a5d2fcc5ae3
--- /dev/null
+++ b/tools/perf/tests/evsel-tp-sched.c
@@ -0,0 +1,84 @@
+#include "evsel.h"
+#include "tests.h"
+#include "event-parse.h"
+
+static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name,
+ int size, bool should_be_signed)
+{
+ struct format_field *field = perf_evsel__field(evsel, name);
+ int is_signed;
+ int ret = 0;
+
+ if (field == NULL) {
+ pr_debug("%s: \"%s\" field not found!\n", evsel->name, name);
+ return -1;
+ }
+
+ is_signed = !!(field->flags | FIELD_IS_SIGNED);
+ if (should_be_signed && !is_signed) {
+ pr_debug("%s: \"%s\" signedness(%d) is wrong, should be %d\n",
+ evsel->name, name, is_signed, should_be_signed);
+ ret = -1;
+ }
+
+ if (field->size != size) {
+ pr_debug("%s: \"%s\" size (%d) should be %d!\n",
+ evsel->name, name, field->size, size);
+ ret = -1;
+ }
+
+ return ret;
+}
+
+int test__perf_evsel__tp_sched_test(void)
+{
+ struct perf_evsel *evsel = perf_evsel__newtp("sched", "sched_switch", 0);
+ int ret = 0;
+
+ if (evsel == NULL) {
+ pr_debug("perf_evsel__new\n");
+ return -1;
+ }
+
+ if (perf_evsel__test_field(evsel, "prev_comm", 16, true))
+ ret = -1;
+
+ if (perf_evsel__test_field(evsel, "prev_pid", 4, true))
+ ret = -1;
+
+ if (perf_evsel__test_field(evsel, "prev_prio", 4, true))
+ ret = -1;
+
+ if (perf_evsel__test_field(evsel, "prev_state", 8, true))
+ ret = -1;
+
+ if (perf_evsel__test_field(evsel, "next_comm", 16, true))
+ ret = -1;
+
+ if (perf_evsel__test_field(evsel, "next_pid", 4, true))
+ ret = -1;
+
+ if (perf_evsel__test_field(evsel, "next_prio", 4, true))
+ ret = -1;
+
+ perf_evsel__delete(evsel);
+
+ evsel = perf_evsel__newtp("sched", "sched_wakeup", 0);
+
+ if (perf_evsel__test_field(evsel, "comm", 16, true))
+ ret = -1;
+
+ if (perf_evsel__test_field(evsel, "pid", 4, true))
+ ret = -1;
+
+ if (perf_evsel__test_field(evsel, "prio", 4, true))
+ ret = -1;
+
+ if (perf_evsel__test_field(evsel, "success", 4, true))
+ ret = -1;
+
+ if (perf_evsel__test_field(evsel, "target_cpu", 4, true))
+ ret = -1;
+
+ return ret;
+}
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
new file mode 100644
index 00000000000..e1746811e14
--- /dev/null
+++ b/tools/perf/tests/mmap-basic.c
@@ -0,0 +1,162 @@
+#include "evlist.h"
+#include "evsel.h"
+#include "thread_map.h"
+#include "cpumap.h"
+#include "tests.h"
+
+/*
+ * This test will generate random numbers of calls to some getpid syscalls,
+ * then establish an mmap for a group of events that are created to monitor
+ * the syscalls.
+ *
+ * It will receive the events, using mmap, use its PERF_SAMPLE_ID generated
+ * sample.id field to map back to its respective perf_evsel instance.
+ *
+ * Then it checks if the number of syscalls reported as perf events by
+ * the kernel corresponds to the number of syscalls made.
+ */
+int test__basic_mmap(void)
+{
+ int err = -1;
+ union perf_event *event;
+ struct thread_map *threads;
+ struct cpu_map *cpus;
+ struct perf_evlist *evlist;
+ struct perf_event_attr attr = {
+ .type = PERF_TYPE_TRACEPOINT,
+ .read_format = PERF_FORMAT_ID,
+ .sample_type = PERF_SAMPLE_ID,
+ .watermark = 0,
+ };
+ cpu_set_t cpu_set;
+ const char *syscall_names[] = { "getsid", "getppid", "getpgrp",
+ "getpgid", };
+ pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp,
+ (void*)getpgid };
+#define nsyscalls ARRAY_SIZE(syscall_names)
+ int ids[nsyscalls];
+ unsigned int nr_events[nsyscalls],
+ expected_nr_events[nsyscalls], i, j;
+ struct perf_evsel *evsels[nsyscalls], *evsel;
+
+ for (i = 0; i < nsyscalls; ++i) {
+ char name[64];
+
+ snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]);
+ ids[i] = trace_event__id(name);
+ if (ids[i] < 0) {
+ pr_debug("Is debugfs mounted on /sys/kernel/debug?\n");
+ return -1;
+ }
+ nr_events[i] = 0;
+ expected_nr_events[i] = random() % 257;
+ }
+
+ threads = thread_map__new(-1, getpid(), UINT_MAX);
+ if (threads == NULL) {
+ pr_debug("thread_map__new\n");
+ return -1;
+ }
+
+ cpus = cpu_map__new(NULL);
+ if (cpus == NULL) {
+ pr_debug("cpu_map__new\n");
+ goto out_free_threads;
+ }
+
+ CPU_ZERO(&cpu_set);
+ CPU_SET(cpus->map[0], &cpu_set);
+ sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
+ if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
+ pr_debug("sched_setaffinity() failed on CPU %d: %s ",
+ cpus->map[0], strerror(errno));
+ goto out_free_cpus;
+ }
+
+ evlist = perf_evlist__new(cpus, threads);
+ if (evlist == NULL) {
+ pr_debug("perf_evlist__new\n");
+ goto out_free_cpus;
+ }
+
+ /* anonymous union fields, can't be initialized above */
+ attr.wakeup_events = 1;
+ attr.sample_period = 1;
+
+ for (i = 0; i < nsyscalls; ++i) {
+ attr.config = ids[i];
+ evsels[i] = perf_evsel__new(&attr, i);
+ if (evsels[i] == NULL) {
+ pr_debug("perf_evsel__new\n");
+ goto out_free_evlist;
+ }
+
+ perf_evlist__add(evlist, evsels[i]);
+
+ if (perf_evsel__open(evsels[i], cpus, threads) < 0) {
+ pr_debug("failed to open counter: %s, "
+ "tweak /proc/sys/kernel/perf_event_paranoid?\n",
+ strerror(errno));
+ goto out_close_fd;
+ }
+ }
+
+ if (perf_evlist__mmap(evlist, 128, true) < 0) {
+ pr_debug("failed to mmap events: %d (%s)\n", errno,
+ strerror(errno));
+ goto out_close_fd;
+ }
+
+ for (i = 0; i < nsyscalls; ++i)
+ for (j = 0; j < expected_nr_events[i]; ++j) {
+ int foo = syscalls[i]();
+ ++foo;
+ }
+
+ while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {
+ struct perf_sample sample;
+
+ if (event->header.type != PERF_RECORD_SAMPLE) {
+ pr_debug("unexpected %s event\n",
+ perf_event__name(event->header.type));
+ goto out_munmap;
+ }
+
+ err = perf_evlist__parse_sample(evlist, event, &sample);
+ if (err) {
+ pr_err("Can't parse sample, err = %d\n", err);
+ goto out_munmap;
+ }
+
+ evsel = perf_evlist__id2evsel(evlist, sample.id);
+ if (evsel == NULL) {
+ pr_debug("event with id %" PRIu64
+ " doesn't map to an evsel\n", sample.id);
+ goto out_munmap;
+ }
+ nr_events[evsel->idx]++;
+ }
+
+ list_for_each_entry(evsel, &evlist->entries, node) {
+ if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) {
+ pr_debug("expected %d %s events, got %d\n",
+ expected_nr_events[evsel->idx],
+ perf_evsel__name(evsel), nr_events[evsel->idx]);
+ goto out_munmap;
+ }
+ }
+
+ err = 0;
+out_munmap:
+ perf_evlist__munmap(evlist);
+out_close_fd:
+ for (i = 0; i < nsyscalls; ++i)
+ perf_evsel__close_fd(evsels[i], 1, threads->nr);
+out_free_evlist:
+ perf_evlist__delete(evlist);
+out_free_cpus:
+ cpu_map__delete(cpus);
+out_free_threads:
+ thread_map__delete(threads);
+ return err;
+}
diff --git a/tools/perf/tests/open-syscall-all-cpus.c b/tools/perf/tests/open-syscall-all-cpus.c
new file mode 100644
index 00000000000..31072aba0d5
--- /dev/null
+++ b/tools/perf/tests/open-syscall-all-cpus.c
@@ -0,0 +1,120 @@
+#include "evsel.h"
+#include "tests.h"
+#include "thread_map.h"
+#include "cpumap.h"
+#include "debug.h"
+
+int test__open_syscall_event_on_all_cpus(void)
+{
+ int err = -1, fd, cpu;
+ struct thread_map *threads;
+ struct cpu_map *cpus;
+ struct perf_evsel *evsel;
+ struct perf_event_attr attr;
+ unsigned int nr_open_calls = 111, i;
+ cpu_set_t cpu_set;
+ int id = trace_event__id("sys_enter_open");
+
+ if (id < 0) {
+ pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
+ return -1;
+ }
+
+ threads = thread_map__new(-1, getpid(), UINT_MAX);
+ if (threads == NULL) {
+ pr_debug("thread_map__new\n");
+ return -1;
+ }
+
+ cpus = cpu_map__new(NULL);
+ if (cpus == NULL) {
+ pr_debug("cpu_map__new\n");
+ goto out_thread_map_delete;
+ }
+
+
+ CPU_ZERO(&cpu_set);
+
+ memset(&attr, 0, sizeof(attr));
+ attr.type = PERF_TYPE_TRACEPOINT;
+ attr.config = id;
+ evsel = perf_evsel__new(&attr, 0);
+ if (evsel == NULL) {
+ pr_debug("perf_evsel__new\n");
+ goto out_thread_map_delete;
+ }
+
+ if (perf_evsel__open(evsel, cpus, threads) < 0) {
+ pr_debug("failed to open counter: %s, "
+ "tweak /proc/sys/kernel/perf_event_paranoid?\n",
+ strerror(errno));
+ goto out_evsel_delete;
+ }
+
+ for (cpu = 0; cpu < cpus->nr; ++cpu) {
+ unsigned int ncalls = nr_open_calls + cpu;
+ /*
+ * XXX eventually lift this restriction in a way that
+ * keeps perf building on older glibc installations
+ * without CPU_ALLOC. 1024 cpus in 2010 still seems
+ * a reasonable upper limit tho :-)
+ */
+ if (cpus->map[cpu] >= CPU_SETSIZE) {
+ pr_debug("Ignoring CPU %d\n", cpus->map[cpu]);
+ continue;
+ }
+
+ CPU_SET(cpus->map[cpu], &cpu_set);
+ if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
+ pr_debug("sched_setaffinity() failed on CPU %d: %s ",
+ cpus->map[cpu],
+ strerror(errno));
+ goto out_close_fd;
+ }
+ for (i = 0; i < ncalls; ++i) {
+ fd = open("/etc/passwd", O_RDONLY);
+ close(fd);
+ }
+ CPU_CLR(cpus->map[cpu], &cpu_set);
+ }
+
+ /*
+ * Here we need to explicitely preallocate the counts, as if
+ * we use the auto allocation it will allocate just for 1 cpu,
+ * as we start by cpu 0.
+ */
+ if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) {
+ pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr);
+ goto out_close_fd;
+ }
+
+ err = 0;
+
+ for (cpu = 0; cpu < cpus->nr; ++cpu) {
+ unsigned int expected;
+
+ if (cpus->map[cpu] >= CPU_SETSIZE)
+ continue;
+
+ if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) {
+ pr_debug("perf_evsel__read_on_cpu\n");
+ err = -1;
+ break;
+ }
+
+ expected = nr_open_calls + cpu;
+ if (evsel->counts->cpu[cpu].val != expected) {
+ pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
+ expected, cpus->map[cpu], evsel->counts->cpu[cpu].val);
+ err = -1;
+ }
+ }
+
+out_close_fd:
+ perf_evsel__close_fd(evsel, 1, threads->nr);
+out_evsel_delete:
+ perf_evsel__delete(evsel);
+out_thread_map_delete:
+ thread_map__delete(threads);
+ return err;
+}
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c
new file mode 100644
index 00000000000..1c52fdc1164
--- /dev/null
+++ b/tools/perf/tests/open-syscall-tp-fields.c
@@ -0,0 +1,117 @@
+#include "perf.h"
+#include "evlist.h"
+#include "evsel.h"
+#include "thread_map.h"
+#include "tests.h"
+
+int test__syscall_open_tp_fields(void)
+{
+ struct perf_record_opts opts = {
+ .target = {
+ .uid = UINT_MAX,
+ .uses_mmap = true,
+ },
+ .no_delay = true,
+ .freq = 1,
+ .mmap_pages = 256,
+ .raw_samples = true,
+ };
+ const char *filename = "/etc/passwd";
+ int flags = O_RDONLY | O_DIRECTORY;
+ struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
+ struct perf_evsel *evsel;
+ int err = -1, i, nr_events = 0, nr_polls = 0;
+
+ if (evlist == NULL) {
+ pr_debug("%s: perf_evlist__new\n", __func__);
+ goto out;
+ }
+
+ evsel = perf_evsel__newtp("syscalls", "sys_enter_open", 0);
+ if (evsel == NULL) {
+ pr_debug("%s: perf_evsel__newtp\n", __func__);
+ goto out_delete_evlist;
+ }
+
+ perf_evlist__add(evlist, evsel);
+
+ err = perf_evlist__create_maps(evlist, &opts.target);
+ if (err < 0) {
+ pr_debug("%s: perf_evlist__create_maps\n", __func__);
+ goto out_delete_evlist;
+ }
+
+ perf_evsel__config(evsel, &opts);
+
+ evlist->threads->map[0] = getpid();
+
+ err = perf_evlist__open(evlist);
+ if (err < 0) {
+ pr_debug("perf_evlist__open: %s\n", strerror(errno));
+ goto out_delete_evlist;
+ }
+
+ err = perf_evlist__mmap(evlist, UINT_MAX, false);
+ if (err < 0) {
+ pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
+ goto out_delete_evlist;
+ }
+
+ perf_evlist__enable(evlist);
+
+ /*
+ * Generate the event:
+ */
+ open(filename, flags);
+
+ while (1) {
+ int before = nr_events;
+
+ for (i = 0; i < evlist->nr_mmaps; i++) {
+ union perf_event *event;
+
+ while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
+ const u32 type = event->header.type;
+ int tp_flags;
+ struct perf_sample sample;
+
+ ++nr_events;
+
+ if (type != PERF_RECORD_SAMPLE)
+ continue;
+
+ err = perf_evsel__parse_sample(evsel, event, &sample);
+ if (err) {
+ pr_err("Can't parse sample, err = %d\n", err);
+ goto out_munmap;
+ }
+
+ tp_flags = perf_evsel__intval(evsel, &sample, "flags");
+
+ if (flags != tp_flags) {
+ pr_debug("%s: Expected flags=%#x, got %#x\n",
+ __func__, flags, tp_flags);
+ goto out_munmap;
+ }
+
+ goto out_ok;
+ }
+ }
+
+ if (nr_events == before)
+ poll(evlist->pollfd, evlist->nr_fds, 10);
+
+ if (++nr_polls > 5) {
+ pr_debug("%s: no events!\n", __func__);
+ goto out_munmap;
+ }
+ }
+out_ok:
+ err = 0;
+out_munmap:
+ perf_evlist__munmap(evlist);
+out_delete_evlist:
+ perf_evlist__delete(evlist);
+out:
+ return err;
+}
diff --git a/tools/perf/tests/open-syscall.c b/tools/perf/tests/open-syscall.c
new file mode 100644
index 00000000000..98be8b518b4
--- /dev/null
+++ b/tools/perf/tests/open-syscall.c
@@ -0,0 +1,66 @@
+#include "thread_map.h"
+#include "evsel.h"
+#include "debug.h"
+#include "tests.h"
+
+int test__open_syscall_event(void)
+{
+ int err = -1, fd;
+ struct thread_map *threads;
+ struct perf_evsel *evsel;
+ struct perf_event_attr attr;
+ unsigned int nr_open_calls = 111, i;
+ int id = trace_event__id("sys_enter_open");
+
+ if (id < 0) {
+ pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
+ return -1;
+ }
+
+ threads = thread_map__new(-1, getpid(), UINT_MAX);
+ if (threads == NULL) {
+ pr_debug("thread_map__new\n");
+ return -1;
+ }
+
+ memset(&attr, 0, sizeof(attr));
+ attr.type = PERF_TYPE_TRACEPOINT;
+ attr.config = id;
+ evsel = perf_evsel__new(&attr, 0);
+ if (evsel == NULL) {
+ pr_debug("perf_evsel__new\n");
+ goto out_thread_map_delete;
+ }
+
+ if (perf_evsel__open_per_thread(evsel, threads) < 0) {
+ pr_debug("failed to open counter: %s, "
+ "tweak /proc/sys/kernel/perf_event_paranoid?\n",
+ strerror(errno));
+ goto out_evsel_delete;
+ }
+
+ for (i = 0; i < nr_open_calls; ++i) {
+ fd = open("/etc/passwd", O_RDONLY);
+ close(fd);
+ }
+
+ if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) {
+ pr_debug("perf_evsel__read_on_cpu\n");
+ goto out_close_fd;
+ }
+
+ if (evsel->counts->cpu[0].val != nr_open_calls) {
+ pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
+ nr_open_calls, evsel->counts->cpu[0].val);
+ goto out_close_fd;
+ }
+
+ err = 0;
+out_close_fd:
+ perf_evsel__close_fd(evsel, 1, threads->nr);
+out_evsel_delete:
+ perf_evsel__delete(evsel);
+out_thread_map_delete:
+ thread_map__delete(threads);
+ return err;
+}
diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/tests/parse-events.c
index 516ecd9ddd6..32ee478905e 100644
--- a/tools/perf/util/parse-events-test.c
+++ b/tools/perf/tests/parse-events.c
@@ -3,7 +3,8 @@
#include "evsel.h"
#include "evlist.h"
#include "sysfs.h"
-#include "../../../include/linux/hw_breakpoint.h"
+#include "tests.h"
+#include <linux/hw_breakpoint.h>
#define TEST_ASSERT_VAL(text, cond) \
do { \
@@ -443,6 +444,23 @@ static int test__checkevent_pmu_name(struct perf_evlist *evlist)
return 0;
}
+static int test__checkevent_pmu_events(struct perf_evlist *evlist)
+{
+ struct perf_evsel *evsel;
+
+ evsel = list_entry(evlist->entries.next, struct perf_evsel, node);
+ TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
+ TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
+ TEST_ASSERT_VAL("wrong exclude_user",
+ !evsel->attr.exclude_user);
+ TEST_ASSERT_VAL("wrong exclude_kernel",
+ evsel->attr.exclude_kernel);
+ TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
+ TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
+
+ return 0;
+}
+
static int test__checkterms_simple(struct list_head *terms)
{
struct parse_events__term *term;
@@ -503,7 +521,7 @@ static int test__group1(struct perf_evlist *evlist)
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
- TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
+ TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel));
/* cycles:upp */
evsel = perf_evsel__next(evsel);
@@ -539,7 +557,7 @@ static int test__group2(struct perf_evlist *evlist)
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
- TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
+ TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel));
/* cache-references + :u modifier */
evsel = perf_evsel__next(evsel);
@@ -565,7 +583,7 @@ static int test__group2(struct perf_evlist *evlist)
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
- TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
+ TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel));
return 0;
}
@@ -588,7 +606,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused)
TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
- TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
+ TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel));
TEST_ASSERT_VAL("wrong group name",
!strcmp(leader->group_name, "group1"));
@@ -618,7 +636,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused)
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
- TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
+ TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel));
TEST_ASSERT_VAL("wrong group name",
!strcmp(leader->group_name, "group2"));
@@ -645,7 +663,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused)
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
- TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
+ TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel));
return 0;
}
@@ -669,7 +687,7 @@ static int test__group4(struct perf_evlist *evlist __maybe_unused)
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 1);
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
- TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
+ TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel));
/* instructions:kp + p */
evsel = perf_evsel__next(evsel);
@@ -706,7 +724,7 @@ static int test__group5(struct perf_evlist *evlist __maybe_unused)
TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
- TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
+ TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel));
/* instructions + G */
evsel = perf_evsel__next(evsel);
@@ -733,7 +751,7 @@ static int test__group5(struct perf_evlist *evlist __maybe_unused)
TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
- TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
+ TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel));
/* instructions:G */
evsel = perf_evsel__next(evsel);
@@ -759,7 +777,7 @@ static int test__group5(struct perf_evlist *evlist __maybe_unused)
TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
- TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
+ TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel));
return 0;
}
@@ -1024,7 +1042,52 @@ static int test_pmu(void)
return !ret;
}
-int parse_events__test(void)
+static int test_pmu_events(void)
+{
+ struct stat st;
+ char path[PATH_MAX];
+ struct dirent *ent;
+ DIR *dir;
+ int ret;
+
+ snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/events/",
+ sysfs_find_mountpoint());
+
+ ret = stat(path, &st);
+ if (ret) {
+ pr_debug("ommiting PMU cpu events tests\n");
+ return 0;
+ }
+
+ dir = opendir(path);
+ if (!dir) {
+ pr_debug("can't open pmu event dir");
+ return -1;
+ }
+
+ while (!ret && (ent = readdir(dir))) {
+#define MAX_NAME 100
+ struct test__event_st e;
+ char name[MAX_NAME];
+
+ if (!strcmp(ent->d_name, ".") ||
+ !strcmp(ent->d_name, ".."))
+ continue;
+
+ snprintf(name, MAX_NAME, "cpu/event=%s/u", ent->d_name);
+
+ e.name = name;
+ e.check = test__checkevent_pmu_events;
+
+ ret = test_event(&e);
+#undef MAX_NAME
+ }
+
+ closedir(dir);
+ return ret;
+}
+
+int test__parse_events(void)
{
int ret1, ret2 = 0;
@@ -1040,6 +1103,12 @@ do { \
if (test_pmu())
TEST_EVENTS(test__events_pmu);
+ if (test_pmu()) {
+ int ret = test_pmu_events();
+ if (ret)
+ return ret;
+ }
+
ret1 = test_terms(test__terms, ARRAY_SIZE(test__terms));
if (!ret2)
ret2 = ret1;
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
new file mode 100644
index 00000000000..70e0d4421df
--- /dev/null
+++ b/tools/perf/tests/perf-record.c
@@ -0,0 +1,312 @@
+#include <sched.h>
+#include "evlist.h"
+#include "evsel.h"
+#include "perf.h"
+#include "debug.h"
+#include "tests.h"
+
+static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp)
+{
+ int i, cpu = -1, nrcpus = 1024;
+realloc:
+ CPU_ZERO(maskp);
+
+ if (sched_getaffinity(pid, sizeof(*maskp), maskp) == -1) {
+ if (errno == EINVAL && nrcpus < (1024 << 8)) {
+ nrcpus = nrcpus << 2;
+ goto realloc;
+ }
+ perror("sched_getaffinity");
+ return -1;
+ }
+
+ for (i = 0; i < nrcpus; i++) {
+ if (CPU_ISSET(i, maskp)) {
+ if (cpu == -1)
+ cpu = i;
+ else
+ CPU_CLR(i, maskp);
+ }
+ }
+
+ return cpu;
+}
+
+int test__PERF_RECORD(void)
+{
+ struct perf_record_opts opts = {
+ .target = {
+ .uid = UINT_MAX,
+ .uses_mmap = true,
+ },
+ .no_delay = true,
+ .freq = 10,
+ .mmap_pages = 256,
+ };
+ cpu_set_t cpu_mask;
+ size_t cpu_mask_size = sizeof(cpu_mask);
+ struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
+ struct perf_evsel *evsel;
+ struct perf_sample sample;
+ const char *cmd = "sleep";
+ const char *argv[] = { cmd, "1", NULL, };
+ char *bname;
+ u64 prev_time = 0;
+ bool found_cmd_mmap = false,
+ found_libc_mmap = false,
+ found_vdso_mmap = false,
+ found_ld_mmap = false;
+ int err = -1, errs = 0, i, wakeups = 0;
+ u32 cpu;
+ int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, };
+
+ if (evlist == NULL || argv == NULL) {
+ pr_debug("Not enough memory to create evlist\n");
+ 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
+ * perf_evlist__prepare_workload we'll fill in the only thread
+ * we're monitoring, the one forked there.
+ */
+ err = perf_evlist__create_maps(evlist, &opts.target);
+ if (err < 0) {
+ pr_debug("Not enough memory to create thread/cpu maps\n");
+ goto out_delete_evlist;
+ }
+
+ /*
+ * Prepare the workload in argv[] to run, it'll fork it, and then wait
+ * for perf_evlist__start_workload() to exec it. This is done this way
+ * so that we have time to open the evlist (calling sys_perf_event_open
+ * on all the fds) and then mmap them.
+ */
+ err = perf_evlist__prepare_workload(evlist, &opts, argv);
+ if (err < 0) {
+ pr_debug("Couldn't run the workload!\n");
+ goto out_delete_evlist;
+ }
+
+ /*
+ * Config the evsels, setting attr->comm on the first one, etc.
+ */
+ evsel = perf_evlist__first(evlist);
+ evsel->attr.sample_type |= PERF_SAMPLE_CPU;
+ evsel->attr.sample_type |= PERF_SAMPLE_TID;
+ evsel->attr.sample_type |= PERF_SAMPLE_TIME;
+ perf_evlist__config_attrs(evlist, &opts);
+
+ err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask);
+ if (err < 0) {
+ pr_debug("sched__get_first_possible_cpu: %s\n", strerror(errno));
+ goto out_delete_evlist;
+ }
+
+ cpu = err;
+
+ /*
+ * So that we can check perf_sample.cpu on all the samples.
+ */
+ if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, &cpu_mask) < 0) {
+ pr_debug("sched_setaffinity: %s\n", strerror(errno));
+ goto out_delete_evlist;
+ }
+
+ /*
+ * Call sys_perf_event_open on all the fds on all the evsels,
+ * grouping them if asked to.
+ */
+ err = perf_evlist__open(evlist);
+ if (err < 0) {
+ pr_debug("perf_evlist__open: %s\n", strerror(errno));
+ goto out_delete_evlist;
+ }
+
+ /*
+ * mmap the first fd on a given CPU and ask for events for the other
+ * fds in the same CPU to be injected in the same mmap ring buffer
+ * (using ioctl(PERF_EVENT_IOC_SET_OUTPUT)).
+ */
+ err = perf_evlist__mmap(evlist, opts.mmap_pages, false);
+ if (err < 0) {
+ pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
+ goto out_delete_evlist;
+ }
+
+ /*
+ * Now that all is properly set up, enable the events, they will
+ * count just on workload.pid, which will start...
+ */
+ perf_evlist__enable(evlist);
+
+ /*
+ * Now!
+ */
+ perf_evlist__start_workload(evlist);
+
+ while (1) {
+ int before = total_events;
+
+ for (i = 0; i < evlist->nr_mmaps; i++) {
+ union perf_event *event;
+
+ while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
+ const u32 type = event->header.type;
+ const char *name = perf_event__name(type);
+
+ ++total_events;
+ if (type < PERF_RECORD_MAX)
+ nr_events[type]++;
+
+ err = perf_evlist__parse_sample(evlist, event, &sample);
+ if (err < 0) {
+ if (verbose)
+ perf_event__fprintf(event, stderr);
+ pr_debug("Couldn't parse sample\n");
+ goto out_err;
+ }
+
+ if (verbose) {
+ pr_info("%" PRIu64" %d ", sample.time, sample.cpu);
+ perf_event__fprintf(event, stderr);
+ }
+
+ if (prev_time > sample.time) {
+ pr_debug("%s going backwards in time, prev=%" PRIu64 ", curr=%" PRIu64 "\n",
+ name, prev_time, sample.time);
+ ++errs;
+ }
+
+ prev_time = sample.time;
+
+ if (sample.cpu != cpu) {
+ pr_debug("%s with unexpected cpu, expected %d, got %d\n",
+ name, cpu, sample.cpu);
+ ++errs;
+ }
+
+ if ((pid_t)sample.pid != evlist->workload.pid) {
+ pr_debug("%s with unexpected pid, expected %d, got %d\n",
+ name, evlist->workload.pid, sample.pid);
+ ++errs;
+ }
+
+ if ((pid_t)sample.tid != evlist->workload.pid) {
+ pr_debug("%s with unexpected tid, expected %d, got %d\n",
+ name, evlist->workload.pid, sample.tid);
+ ++errs;
+ }
+
+ if ((type == PERF_RECORD_COMM ||
+ type == PERF_RECORD_MMAP ||
+ type == PERF_RECORD_FORK ||
+ type == PERF_RECORD_EXIT) &&
+ (pid_t)event->comm.pid != evlist->workload.pid) {
+ pr_debug("%s with unexpected pid/tid\n", name);
+ ++errs;
+ }
+
+ if ((type == PERF_RECORD_COMM ||
+ type == PERF_RECORD_MMAP) &&
+ event->comm.pid != event->comm.tid) {
+ pr_debug("%s with different pid/tid!\n", name);
+ ++errs;
+ }
+
+ switch (type) {
+ case PERF_RECORD_COMM:
+ if (strcmp(event->comm.comm, cmd)) {
+ pr_debug("%s with unexpected comm!\n", name);
+ ++errs;
+ }
+ break;
+ case PERF_RECORD_EXIT:
+ goto found_exit;
+ case PERF_RECORD_MMAP:
+ bname = strrchr(event->mmap.filename, '/');
+ if (bname != NULL) {
+ if (!found_cmd_mmap)
+ found_cmd_mmap = !strcmp(bname + 1, cmd);
+ if (!found_libc_mmap)
+ found_libc_mmap = !strncmp(bname + 1, "libc", 4);
+ if (!found_ld_mmap)
+ found_ld_mmap = !strncmp(bname + 1, "ld", 2);
+ } else if (!found_vdso_mmap)
+ found_vdso_mmap = !strcmp(event->mmap.filename, "[vdso]");
+ break;
+
+ case PERF_RECORD_SAMPLE:
+ /* Just ignore samples for now */
+ break;
+ default:
+ pr_debug("Unexpected perf_event->header.type %d!\n",
+ type);
+ ++errs;
+ }
+ }
+ }
+
+ /*
+ * We don't use poll here because at least at 3.1 times the
+ * PERF_RECORD_{!SAMPLE} events don't honour
+ * perf_event_attr.wakeup_events, just PERF_EVENT_SAMPLE does.
+ */
+ if (total_events == before && false)
+ poll(evlist->pollfd, evlist->nr_fds, -1);
+
+ sleep(1);
+ if (++wakeups > 5) {
+ pr_debug("No PERF_RECORD_EXIT event!\n");
+ break;
+ }
+ }
+
+found_exit:
+ if (nr_events[PERF_RECORD_COMM] > 1) {
+ pr_debug("Excessive number of PERF_RECORD_COMM events!\n");
+ ++errs;
+ }
+
+ if (nr_events[PERF_RECORD_COMM] == 0) {
+ pr_debug("Missing PERF_RECORD_COMM for %s!\n", cmd);
+ ++errs;
+ }
+
+ if (!found_cmd_mmap) {
+ pr_debug("PERF_RECORD_MMAP for %s missing!\n", cmd);
+ ++errs;
+ }
+
+ if (!found_libc_mmap) {
+ pr_debug("PERF_RECORD_MMAP for %s missing!\n", "libc");
+ ++errs;
+ }
+
+ if (!found_ld_mmap) {
+ pr_debug("PERF_RECORD_MMAP for %s missing!\n", "ld");
+ ++errs;
+ }
+
+ if (!found_vdso_mmap) {
+ pr_debug("PERF_RECORD_MMAP for %s missing!\n", "[vdso]");
+ ++errs;
+ }
+out_err:
+ perf_evlist__munmap(evlist);
+out_delete_evlist:
+ perf_evlist__delete(evlist);
+out:
+ return (err < 0 || errs > 0) ? -1 : 0;
+}
diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c
new file mode 100644
index 00000000000..a5f379863b8
--- /dev/null
+++ b/tools/perf/tests/pmu.c
@@ -0,0 +1,178 @@
+#include "parse-events.h"
+#include "pmu.h"
+#include "util.h"
+#include "tests.h"
+
+/* Simulated format definitions. */
+static struct test_format {
+ const char *name;
+ const char *value;
+} test_formats[] = {
+ { "krava01", "config:0-1,62-63\n", },
+ { "krava02", "config:10-17\n", },
+ { "krava03", "config:5\n", },
+ { "krava11", "config1:0,2,4,6,8,20-28\n", },
+ { "krava12", "config1:63\n", },
+ { "krava13", "config1:45-47\n", },
+ { "krava21", "config2:0-3,10-13,20-23,30-33,40-43,50-53,60-63\n", },
+ { "krava22", "config2:8,18,48,58\n", },
+ { "krava23", "config2:28-29,38\n", },
+};
+
+#define TEST_FORMATS_CNT (sizeof(test_formats) / sizeof(struct test_format))
+
+/* Simulated users input. */
+static struct parse_events__term test_terms[] = {
+ {
+ .config = (char *) "krava01",
+ .val.num = 15,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
+ },
+ {
+ .config = (char *) "krava02",
+ .val.num = 170,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
+ },
+ {
+ .config = (char *) "krava03",
+ .val.num = 1,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
+ },
+ {
+ .config = (char *) "krava11",
+ .val.num = 27,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
+ },
+ {
+ .config = (char *) "krava12",
+ .val.num = 1,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
+ },
+ {
+ .config = (char *) "krava13",
+ .val.num = 2,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
+ },
+ {
+ .config = (char *) "krava21",
+ .val.num = 119,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
+ },
+ {
+ .config = (char *) "krava22",
+ .val.num = 11,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
+ },
+ {
+ .config = (char *) "krava23",
+ .val.num = 2,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
+ },
+};
+#define TERMS_CNT (sizeof(test_terms) / sizeof(struct parse_events__term))
+
+/*
+ * Prepare format directory data, exported by kernel
+ * at /sys/bus/event_source/devices/<dev>/format.
+ */
+static char *test_format_dir_get(void)
+{
+ static char dir[PATH_MAX];
+ unsigned int i;
+
+ snprintf(dir, PATH_MAX, "/tmp/perf-pmu-test-format-XXXXXX");
+ if (!mkdtemp(dir))
+ return NULL;
+
+ for (i = 0; i < TEST_FORMATS_CNT; i++) {
+ static char name[PATH_MAX];
+ struct test_format *format = &test_formats[i];
+ FILE *file;
+
+ snprintf(name, PATH_MAX, "%s/%s", dir, format->name);
+
+ file = fopen(name, "w");
+ if (!file)
+ return NULL;
+
+ if (1 != fwrite(format->value, strlen(format->value), 1, file))
+ break;
+
+ fclose(file);
+ }
+
+ return dir;
+}
+
+/* Cleanup format directory. */
+static int test_format_dir_put(char *dir)
+{
+ char buf[PATH_MAX];
+ snprintf(buf, PATH_MAX, "rm -f %s/*\n", dir);
+ if (system(buf))
+ return -1;
+
+ snprintf(buf, PATH_MAX, "rmdir %s\n", dir);
+ return system(buf);
+}
+
+static struct list_head *test_terms_list(void)
+{
+ static LIST_HEAD(terms);
+ unsigned int i;
+
+ for (i = 0; i < TERMS_CNT; i++)
+ list_add_tail(&test_terms[i].list, &terms);
+
+ return &terms;
+}
+
+#undef TERMS_CNT
+
+int test__pmu(void)
+{
+ char *format = test_format_dir_get();
+ LIST_HEAD(formats);
+ struct list_head *terms = test_terms_list();
+ int ret;
+
+ if (!format)
+ return -EINVAL;
+
+ do {
+ struct perf_event_attr attr;
+
+ memset(&attr, 0, sizeof(attr));
+
+ ret = perf_pmu__format_parse(format, &formats);
+ if (ret)
+ break;
+
+ ret = perf_pmu__config_terms(&formats, &attr, terms);
+ if (ret)
+ break;
+
+ ret = -EINVAL;
+
+ if (attr.config != 0xc00000000002a823)
+ break;
+ if (attr.config1 != 0x8000400000000145)
+ break;
+ if (attr.config2 != 0x0400000020041d07)
+ break;
+
+ ret = 0;
+ } while (0);
+
+ test_format_dir_put(format);
+ return ret;
+}
diff --git a/tools/perf/tests/rdpmc.c b/tools/perf/tests/rdpmc.c
new file mode 100644
index 00000000000..ff94886aad9
--- /dev/null
+++ b/tools/perf/tests/rdpmc.c
@@ -0,0 +1,175 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include "types.h"
+#include "perf.h"
+#include "debug.h"
+#include "tests.h"
+
+#if defined(__x86_64__) || defined(__i386__)
+
+#define barrier() asm volatile("" ::: "memory")
+
+static u64 rdpmc(unsigned int counter)
+{
+ unsigned int low, high;
+
+ asm volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (counter));
+
+ return low | ((u64)high) << 32;
+}
+
+static u64 rdtsc(void)
+{
+ unsigned int low, high;
+
+ asm volatile("rdtsc" : "=a" (low), "=d" (high));
+
+ return low | ((u64)high) << 32;
+}
+
+static u64 mmap_read_self(void *addr)
+{
+ struct perf_event_mmap_page *pc = addr;
+ u32 seq, idx, time_mult = 0, time_shift = 0;
+ u64 count, cyc = 0, time_offset = 0, enabled, running, delta;
+
+ do {
+ seq = pc->lock;
+ barrier();
+
+ enabled = pc->time_enabled;
+ running = pc->time_running;
+
+ if (enabled != running) {
+ cyc = rdtsc();
+ time_mult = pc->time_mult;
+ time_shift = pc->time_shift;
+ time_offset = pc->time_offset;
+ }
+
+ idx = pc->index;
+ count = pc->offset;
+ if (idx)
+ count += rdpmc(idx - 1);
+
+ barrier();
+ } while (pc->lock != seq);
+
+ if (enabled != running) {
+ u64 quot, rem;
+
+ quot = (cyc >> time_shift);
+ rem = cyc & ((1 << time_shift) - 1);
+ delta = time_offset + quot * time_mult +
+ ((rem * time_mult) >> time_shift);
+
+ enabled += delta;
+ if (idx)
+ running += delta;
+
+ quot = count / running;
+ rem = count % running;
+ count = quot * enabled + (rem * enabled) / running;
+ }
+
+ return count;
+}
+
+/*
+ * If the RDPMC instruction faults then signal this back to the test parent task:
+ */
+static void segfault_handler(int sig __maybe_unused,
+ siginfo_t *info __maybe_unused,
+ void *uc __maybe_unused)
+{
+ exit(-1);
+}
+
+static int __test__rdpmc(void)
+{
+ volatile int tmp = 0;
+ u64 i, loops = 1000;
+ int n;
+ int fd;
+ void *addr;
+ struct perf_event_attr attr = {
+ .type = PERF_TYPE_HARDWARE,
+ .config = PERF_COUNT_HW_INSTRUCTIONS,
+ .exclude_kernel = 1,
+ };
+ u64 delta_sum = 0;
+ struct sigaction sa;
+
+ sigfillset(&sa.sa_mask);
+ sa.sa_sigaction = segfault_handler;
+ sigaction(SIGSEGV, &sa, NULL);
+
+ fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
+ if (fd < 0) {
+ pr_err("Error: sys_perf_event_open() syscall returned "
+ "with %d (%s)\n", fd, strerror(errno));
+ return -1;
+ }
+
+ addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (addr == (void *)(-1)) {
+ pr_err("Error: mmap() syscall returned with (%s)\n",
+ strerror(errno));
+ goto out_close;
+ }
+
+ for (n = 0; n < 6; n++) {
+ u64 stamp, now, delta;
+
+ stamp = mmap_read_self(addr);
+
+ for (i = 0; i < loops; i++)
+ tmp++;
+
+ now = mmap_read_self(addr);
+ loops *= 10;
+
+ delta = now - stamp;
+ pr_debug("%14d: %14Lu\n", n, (long long)delta);
+
+ delta_sum += delta;
+ }
+
+ munmap(addr, page_size);
+ pr_debug(" ");
+out_close:
+ close(fd);
+
+ if (!delta_sum)
+ return -1;
+
+ return 0;
+}
+
+int test__rdpmc(void)
+{
+ int status = 0;
+ int wret = 0;
+ int ret;
+ int pid;
+
+ pid = fork();
+ if (pid < 0)
+ return -1;
+
+ if (!pid) {
+ ret = __test__rdpmc();
+
+ exit(ret);
+ }
+
+ wret = waitpid(pid, &status, 0);
+ if (wret < 0 || status)
+ return -1;
+
+ return 0;
+}
+
+#endif
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
new file mode 100644
index 00000000000..fc121edab01
--- /dev/null
+++ b/tools/perf/tests/tests.h
@@ -0,0 +1,22 @@
+#ifndef TESTS_H
+#define TESTS_H
+
+/* Tests */
+int test__vmlinux_matches_kallsyms(void);
+int test__open_syscall_event(void);
+int test__open_syscall_event_on_all_cpus(void);
+int test__basic_mmap(void);
+int test__PERF_RECORD(void);
+int test__rdpmc(void);
+int test__perf_evsel__roundtrip_name_test(void);
+int test__perf_evsel__tp_sched_test(void);
+int test__syscall_open_tp_fields(void);
+int test__pmu(void);
+int test__attr(void);
+int test__dso_data(void);
+int test__parse_events(void);
+
+/* Util */
+int trace_event__id(const char *evname);
+
+#endif /* TESTS_H */
diff --git a/tools/perf/tests/util.c b/tools/perf/tests/util.c
new file mode 100644
index 00000000000..748f2e8f696
--- /dev/null
+++ b/tools/perf/tests/util.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "tests.h"
+#include "debugfs.h"
+
+int trace_event__id(const char *evname)
+{
+ char *filename;
+ int err = -1, fd;
+
+ if (asprintf(&filename,
+ "%s/syscalls/%s/id",
+ tracing_events_path, evname) < 0)
+ return -1;
+
+ fd = open(filename, O_RDONLY);
+ if (fd >= 0) {
+ char id[16];
+ if (read(fd, id, sizeof(id)) > 0)
+ err = atoi(id);
+ close(fd);
+ }
+
+ free(filename);
+ return err;
+}
diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c
new file mode 100644
index 00000000000..0d1cdbee2f5
--- /dev/null
+++ b/tools/perf/tests/vmlinux-kallsyms.c
@@ -0,0 +1,230 @@
+#include <linux/compiler.h>
+#include <linux/rbtree.h>
+#include <string.h>
+#include "map.h"
+#include "symbol.h"
+#include "util.h"
+#include "tests.h"
+#include "debug.h"
+#include "machine.h"
+
+static int vmlinux_matches_kallsyms_filter(struct map *map __maybe_unused,
+ struct symbol *sym)
+{
+ bool *visited = symbol__priv(sym);
+ *visited = true;
+ return 0;
+}
+
+int test__vmlinux_matches_kallsyms(void)
+{
+ int err = -1;
+ struct rb_node *nd;
+ struct symbol *sym;
+ struct map *kallsyms_map, *vmlinux_map;
+ struct machine kallsyms, vmlinux;
+ enum map_type type = MAP__FUNCTION;
+ struct ref_reloc_sym ref_reloc_sym = { .name = "_stext", };
+
+ /*
+ * Step 1:
+ *
+ * Init the machines that will hold kernel, modules obtained from
+ * both vmlinux + .ko files and from /proc/kallsyms split by modules.
+ */
+ machine__init(&kallsyms, "", HOST_KERNEL_ID);
+ machine__init(&vmlinux, "", HOST_KERNEL_ID);
+
+ /*
+ * Step 2:
+ *
+ * Create the kernel maps for kallsyms and the DSO where we will then
+ * load /proc/kallsyms. Also create the modules maps from /proc/modules
+ * and find the .ko files that match them in /lib/modules/`uname -r`/.
+ */
+ if (machine__create_kernel_maps(&kallsyms) < 0) {
+ pr_debug("machine__create_kernel_maps ");
+ return -1;
+ }
+
+ /*
+ * Step 3:
+ *
+ * Load and split /proc/kallsyms into multiple maps, one per module.
+ */
+ if (machine__load_kallsyms(&kallsyms, "/proc/kallsyms", type, NULL) <= 0) {
+ pr_debug("dso__load_kallsyms ");
+ goto out;
+ }
+
+ /*
+ * Step 4:
+ *
+ * kallsyms will be internally on demand sorted by name so that we can
+ * find the reference relocation * symbol, i.e. the symbol we will use
+ * to see if the running kernel was relocated by checking if it has the
+ * same value in the vmlinux file we load.
+ */
+ kallsyms_map = machine__kernel_map(&kallsyms, type);
+
+ sym = map__find_symbol_by_name(kallsyms_map, ref_reloc_sym.name, NULL);
+ if (sym == NULL) {
+ pr_debug("dso__find_symbol_by_name ");
+ goto out;
+ }
+
+ ref_reloc_sym.addr = sym->start;
+
+ /*
+ * Step 5:
+ *
+ * Now repeat step 2, this time for the vmlinux file we'll auto-locate.
+ */
+ if (machine__create_kernel_maps(&vmlinux) < 0) {
+ pr_debug("machine__create_kernel_maps ");
+ goto out;
+ }
+
+ vmlinux_map = machine__kernel_map(&vmlinux, type);
+ map__kmap(vmlinux_map)->ref_reloc_sym = &ref_reloc_sym;
+
+ /*
+ * Step 6:
+ *
+ * Locate a vmlinux file in the vmlinux path that has a buildid that
+ * matches the one of the running kernel.
+ *
+ * While doing that look if we find the ref reloc symbol, if we find it
+ * we'll have its ref_reloc_symbol.unrelocated_addr and then
+ * maps__reloc_vmlinux will notice and set proper ->[un]map_ip routines
+ * to fixup the symbols.
+ */
+ if (machine__load_vmlinux_path(&vmlinux, type,
+ vmlinux_matches_kallsyms_filter) <= 0) {
+ pr_debug("machine__load_vmlinux_path ");
+ goto out;
+ }
+
+ err = 0;
+ /*
+ * Step 7:
+ *
+ * Now look at the symbols in the vmlinux DSO and check if we find all of them
+ * in the kallsyms dso. For the ones that are in both, check its names and
+ * end addresses too.
+ */
+ for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) {
+ struct symbol *pair, *first_pair;
+ bool backwards = true;
+
+ sym = rb_entry(nd, struct symbol, rb_node);
+
+ if (sym->start == sym->end)
+ continue;
+
+ first_pair = machine__find_kernel_symbol(&kallsyms, type, sym->start, NULL, NULL);
+ pair = first_pair;
+
+ if (pair && pair->start == sym->start) {
+next_pair:
+ if (strcmp(sym->name, pair->name) == 0) {
+ /*
+ * kallsyms don't have the symbol end, so we
+ * set that by using the next symbol start - 1,
+ * in some cases we get this up to a page
+ * wrong, trace_kmalloc when I was developing
+ * this code was one such example, 2106 bytes
+ * off the real size. More than that and we
+ * _really_ have a problem.
+ */
+ s64 skew = sym->end - pair->end;
+ if (llabs(skew) < page_size)
+ continue;
+
+ pr_debug("%#" PRIx64 ": diff end addr for %s v: %#" PRIx64 " k: %#" PRIx64 "\n",
+ sym->start, sym->name, sym->end, pair->end);
+ } else {
+ struct rb_node *nnd;
+detour:
+ nnd = backwards ? rb_prev(&pair->rb_node) :
+ rb_next(&pair->rb_node);
+ if (nnd) {
+ struct symbol *next = rb_entry(nnd, struct symbol, rb_node);
+
+ if (next->start == sym->start) {
+ pair = next;
+ goto next_pair;
+ }
+ }
+
+ if (backwards) {
+ backwards = false;
+ pair = first_pair;
+ goto detour;
+ }
+
+ pr_debug("%#" PRIx64 ": diff name v: %s k: %s\n",
+ sym->start, sym->name, pair->name);
+ }
+ } else
+ pr_debug("%#" PRIx64 ": %s not on kallsyms\n", sym->start, sym->name);
+
+ err = -1;
+ }
+
+ if (!verbose)
+ goto out;
+
+ pr_info("Maps only in vmlinux:\n");
+
+ for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) {
+ struct map *pos = rb_entry(nd, struct map, rb_node), *pair;
+ /*
+ * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while
+ * the kernel will have the path for the vmlinux file being used,
+ * so use the short name, less descriptive but the same ("[kernel]" in
+ * both cases.
+ */
+ pair = map_groups__find_by_name(&kallsyms.kmaps, type,
+ (pos->dso->kernel ?
+ pos->dso->short_name :
+ pos->dso->name));
+ if (pair)
+ pair->priv = 1;
+ else
+ map__fprintf(pos, stderr);
+ }
+
+ pr_info("Maps in vmlinux with a different name in kallsyms:\n");
+
+ for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) {
+ struct map *pos = rb_entry(nd, struct map, rb_node), *pair;
+
+ pair = map_groups__find(&kallsyms.kmaps, type, pos->start);
+ if (pair == NULL || pair->priv)
+ continue;
+
+ if (pair->start == pos->start) {
+ pair->priv = 1;
+ pr_info(" %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as",
+ pos->start, pos->end, pos->pgoff, pos->dso->name);
+ if (pos->pgoff != pair->pgoff || pos->end != pair->end)
+ pr_info(": \n*%" PRIx64 "-%" PRIx64 " %" PRIx64 "",
+ pair->start, pair->end, pair->pgoff);
+ pr_info(" %s\n", pair->dso->name);
+ pair->priv = 1;
+ }
+ }
+
+ pr_info("Maps only in kallsyms:\n");
+
+ for (nd = rb_first(&kallsyms.kmaps.maps[type]);
+ nd; nd = rb_next(nd)) {
+ struct map *pos = rb_entry(nd, struct map, rb_node);
+
+ if (!pos->priv)
+ map__fprintf(pos, stderr);
+ }
+out:
+ return err;
+}
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 8f8cd2d73b3..5dab3ca9698 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -188,6 +188,12 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
struct disasm_line *cursor = ab->selection, *target;
struct browser_disasm_line *btarget, *bcursor;
unsigned int from, to;
+ struct map_symbol *ms = ab->b.priv;
+ struct symbol *sym = ms->sym;
+
+ /* PLT symbols contain external offsets */
+ if (strstr(sym->name, "@plt"))
+ return;
if (!cursor || !cursor->ins || !ins__is_jump(cursor->ins) ||
!disasm_line__has_offset(cursor))
@@ -386,9 +392,8 @@ static void annotate_browser__init_asm_mode(struct annotate_browser *browser)
browser->b.nr_entries = browser->nr_asm_entries;
}
-static bool annotate_browser__callq(struct annotate_browser *browser,
- int evidx, void (*timer)(void *arg),
- void *arg, int delay_secs)
+static bool annotate_browser__callq(struct annotate_browser *browser, int evidx,
+ struct hist_browser_timer *hbt)
{
struct map_symbol *ms = browser->b.priv;
struct disasm_line *dl = browser->selection;
@@ -418,7 +423,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser,
}
pthread_mutex_unlock(&notes->lock);
- symbol__tui_annotate(target, ms->map, evidx, timer, arg, delay_secs);
+ symbol__tui_annotate(target, ms->map, evidx, hbt);
ui_browser__show_title(&browser->b, sym->name);
return true;
}
@@ -602,13 +607,13 @@ static void annotate_browser__update_addr_width(struct annotate_browser *browser
}
static int annotate_browser__run(struct annotate_browser *browser, int evidx,
- void(*timer)(void *arg),
- void *arg, int delay_secs)
+ struct hist_browser_timer *hbt)
{
struct rb_node *nd = NULL;
struct map_symbol *ms = browser->b.priv;
struct symbol *sym = ms->sym;
const char *help = "Press 'h' for help on key bindings";
+ int delay_secs = hbt ? hbt->refresh : 0;
int key;
if (ui_browser__show(&browser->b, sym->name, help) < 0)
@@ -639,8 +644,8 @@ static int annotate_browser__run(struct annotate_browser *browser, int evidx,
switch (key) {
case K_TIMER:
- if (timer != NULL)
- timer(arg);
+ if (hbt)
+ hbt->timer(hbt->arg);
if (delay_secs != 0)
symbol__annotate_decay_histogram(sym, evidx);
@@ -676,8 +681,14 @@ static int annotate_browser__run(struct annotate_browser *browser, int evidx,
"o Toggle disassembler output/simplified view\n"
"s Toggle source code view\n"
"/ Search string\n"
+ "r Run available scripts\n"
"? Search previous string\n");
continue;
+ case 'r':
+ {
+ script_browse(NULL);
+ continue;
+ }
case 'H':
nd = browser->curr_hot;
break;
@@ -734,7 +745,7 @@ show_help:
goto show_sup_ins;
goto out;
} else if (!(annotate_browser__jump(browser) ||
- annotate_browser__callq(browser, evidx, timer, arg, delay_secs))) {
+ annotate_browser__callq(browser, evidx, hbt))) {
show_sup_ins:
ui_helpline__puts("Actions are only available for 'callq', 'retq' & jump instructions.");
}
@@ -757,16 +768,21 @@ out:
}
int hist_entry__tui_annotate(struct hist_entry *he, int evidx,
- void(*timer)(void *arg), void *arg, int delay_secs)
+ struct hist_browser_timer *hbt)
{
- return symbol__tui_annotate(he->ms.sym, he->ms.map, evidx,
- timer, arg, delay_secs);
+ return symbol__tui_annotate(he->ms.sym, he->ms.map, evidx, hbt);
}
static void annotate_browser__mark_jump_targets(struct annotate_browser *browser,
size_t size)
{
u64 offset;
+ struct map_symbol *ms = browser->b.priv;
+ struct symbol *sym = ms->sym;
+
+ /* PLT symbols contain external offsets */
+ if (strstr(sym->name, "@plt"))
+ return;
for (offset = 0; offset < size; ++offset) {
struct disasm_line *dl = browser->offsets[offset], *dlt;
@@ -810,8 +826,7 @@ static inline int width_jumps(int n)
}
int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
- void(*timer)(void *arg), void *arg,
- int delay_secs)
+ struct hist_browser_timer *hbt)
{
struct disasm_line *pos, *n;
struct annotation *notes;
@@ -893,7 +908,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
annotate_browser__update_addr_width(&browser);
- ret = annotate_browser__run(&browser, evidx, timer, arg, delay_secs);
+ ret = annotate_browser__run(&browser, evidx, hbt);
list_for_each_entry_safe(pos, n, &notes->src->source, node) {
list_del(&pos->node);
disasm_line__free(pos);
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index ef2f93ca749..ccc4bd16142 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -11,6 +11,7 @@
#include "../../util/pstack.h"
#include "../../util/sort.h"
#include "../../util/util.h"
+#include "../../arch/common.h"
#include "../browser.h"
#include "../helpline.h"
@@ -310,10 +311,11 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser)
}
static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
- void(*timer)(void *arg), void *arg, int delay_secs)
+ struct hist_browser_timer *hbt)
{
int key;
char title[160];
+ int delay_secs = hbt ? hbt->refresh : 0;
browser->b.entries = &browser->hists->entries;
browser->b.nr_entries = browser->hists->nr_entries;
@@ -330,7 +332,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
switch (key) {
case K_TIMER:
- timer(arg);
+ hbt->timer(hbt->arg);
ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries);
if (browser->hists->stats.nr_lost_warned !=
@@ -1127,11 +1129,17 @@ static inline void free_popup_options(char **options, int n)
}
}
+/* Check whether the browser is for 'top' or 'report' */
+static inline bool is_report_browser(void *timer)
+{
+ return timer == NULL;
+}
+
static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
const char *helpline, const char *ev_name,
bool left_exits,
- void(*timer)(void *arg), void *arg,
- int delay_secs)
+ struct hist_browser_timer *hbt,
+ struct perf_session_env *env)
{
struct hists *hists = &evsel->hists;
struct hist_browser *browser = hist_browser__new(hists);
@@ -1141,6 +1149,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
int nr_options = 0;
int key = -1;
char buf[64];
+ char script_opt[64];
+ int delay_secs = hbt ? hbt->refresh : 0;
if (browser == NULL)
return -1;
@@ -1159,10 +1169,11 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
int choice = 0,
annotate = -2, zoom_dso = -2, zoom_thread = -2,
annotate_f = -2, annotate_t = -2, browse_map = -2;
+ int scripts_comm = -2, scripts_symbol = -2, scripts_all = -2;
nr_options = 0;
- key = hist_browser__run(browser, ev_name, timer, arg, delay_secs);
+ key = hist_browser__run(browser, ev_name, hbt);
if (browser->he_selection != NULL) {
thread = hist_browser__selected_thread(browser);
@@ -1211,6 +1222,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
hist_browser__reset(browser);
}
continue;
+ case 'r':
+ if (is_report_browser(hbt))
+ goto do_scripts;
+ continue;
case K_F1:
case 'h':
case '?':
@@ -1229,6 +1244,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
"E Expand all callchains\n"
"d Zoom into current DSO\n"
"t Zoom into current Thread\n"
+ "r Run available scripts('perf report' only)\n"
"P Print histograms to perf.hist.N\n"
"V Verbose (DSO names in callchains, etc)\n"
"/ Filter symbol by name");
@@ -1317,6 +1333,25 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
browser->selection->map != NULL &&
asprintf(&options[nr_options], "Browse map details") > 0)
browse_map = nr_options++;
+
+ /* perf script support */
+ if (browser->he_selection) {
+ struct symbol *sym;
+
+ if (asprintf(&options[nr_options], "Run scripts for samples of thread [%s]",
+ browser->he_selection->thread->comm) > 0)
+ scripts_comm = nr_options++;
+
+ sym = browser->he_selection->ms.sym;
+ if (sym && sym->namelen &&
+ asprintf(&options[nr_options], "Run scripts for samples of symbol [%s]",
+ sym->name) > 0)
+ scripts_symbol = nr_options++;
+ }
+
+ if (asprintf(&options[nr_options], "Run scripts for all samples") > 0)
+ scripts_all = nr_options++;
+
add_exit_option:
options[nr_options++] = (char *)"Exit";
retry_popup_menu:
@@ -1334,6 +1369,9 @@ retry_popup_menu:
struct hist_entry *he;
int err;
do_annotate:
+ if (!objdump_path && perf_session_env__lookup_objdump(env))
+ continue;
+
he = hist_browser__selected_entry(browser);
if (he == NULL)
continue;
@@ -1356,8 +1394,7 @@ do_annotate:
* Don't let this be freed, say, by hists__decay_entry.
*/
he->used = true;
- err = hist_entry__tui_annotate(he, evsel->idx,
- timer, arg, delay_secs);
+ err = hist_entry__tui_annotate(he, evsel->idx, hbt);
he->used = false;
/*
* offer option to annotate the other branch source or target
@@ -1411,6 +1448,20 @@ zoom_out_thread:
hists__filter_by_thread(hists);
hist_browser__reset(browser);
}
+ /* perf scripts support */
+ else if (choice == scripts_all || choice == scripts_comm ||
+ choice == scripts_symbol) {
+do_scripts:
+ memset(script_opt, 0, 64);
+
+ if (choice == scripts_comm)
+ sprintf(script_opt, " -c %s ", browser->he_selection->thread->comm);
+
+ if (choice == scripts_symbol)
+ sprintf(script_opt, " -S %s ", browser->he_selection->ms.sym->name);
+
+ script_browse(script_opt);
+ }
}
out_free_stack:
pstack__delete(fstack);
@@ -1424,6 +1475,7 @@ struct perf_evsel_menu {
struct ui_browser b;
struct perf_evsel *selection;
bool lost_events, lost_events_warned;
+ struct perf_session_env *env;
};
static void perf_evsel_menu__write(struct ui_browser *browser,
@@ -1466,11 +1518,12 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
int nr_events, const char *help,
- void(*timer)(void *arg), void *arg, int delay_secs)
+ struct hist_browser_timer *hbt)
{
struct perf_evlist *evlist = menu->b.priv;
struct perf_evsel *pos;
const char *ev_name, *title = "Available samples";
+ int delay_secs = hbt ? hbt->refresh : 0;
int key;
if (ui_browser__show(&menu->b, title,
@@ -1482,7 +1535,7 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
switch (key) {
case K_TIMER:
- timer(arg);
+ hbt->timer(hbt->arg);
if (!menu->lost_events_warned && menu->lost_events) {
ui_browser__warn_lost_events(&menu->b);
@@ -1500,12 +1553,12 @@ browse_hists:
* Give the calling tool a chance to populate the non
* default evsel resorted hists tree.
*/
- if (timer)
- timer(arg);
+ if (hbt)
+ hbt->timer(hbt->arg);
ev_name = perf_evsel__name(pos);
key = perf_evsel__hists_browse(pos, nr_events, help,
- ev_name, true, timer,
- arg, delay_secs);
+ ev_name, true, hbt,
+ menu->env);
ui_browser__show_title(&menu->b, title);
switch (key) {
case K_TAB:
@@ -1553,8 +1606,8 @@ out:
static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
const char *help,
- void(*timer)(void *arg), void *arg,
- int delay_secs)
+ struct hist_browser_timer *hbt,
+ struct perf_session_env *env)
{
struct perf_evsel *pos;
struct perf_evsel_menu menu = {
@@ -1566,6 +1619,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
.nr_entries = evlist->nr_entries,
.priv = evlist,
},
+ .env = env,
};
ui_helpline__push("Press ESC to exit");
@@ -1578,23 +1632,20 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
menu.b.width = line_len;
}
- return perf_evsel_menu__run(&menu, evlist->nr_entries, help, timer,
- arg, delay_secs);
+ return perf_evsel_menu__run(&menu, evlist->nr_entries, help, hbt);
}
int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
- void(*timer)(void *arg), void *arg,
- int delay_secs)
+ struct hist_browser_timer *hbt,
+ struct perf_session_env *env)
{
if (evlist->nr_entries == 1) {
struct perf_evsel *first = list_entry(evlist->entries.next,
struct perf_evsel, node);
const char *ev_name = perf_evsel__name(first);
return perf_evsel__hists_browse(first, evlist->nr_entries, help,
- ev_name, false, timer, arg,
- delay_secs);
+ ev_name, false, hbt, env);
}
- return __perf_evlist__tui_browse_hists(evlist, help,
- timer, arg, delay_secs);
+ return __perf_evlist__tui_browse_hists(evlist, help, hbt, env);
}
diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c
new file mode 100644
index 00000000000..cbbd44b0d93
--- /dev/null
+++ b/tools/perf/ui/browsers/scripts.c
@@ -0,0 +1,189 @@
+#include <elf.h>
+#include <newt.h>
+#include <inttypes.h>
+#include <sys/ttydefaults.h>
+#include <string.h>
+#include "../../util/sort.h"
+#include "../../util/util.h"
+#include "../../util/hist.h"
+#include "../../util/debug.h"
+#include "../../util/symbol.h"
+#include "../browser.h"
+#include "../helpline.h"
+#include "../libslang.h"
+
+/* 2048 lines should be enough for a script output */
+#define MAX_LINES 2048
+
+/* 160 bytes for one output line */
+#define AVERAGE_LINE_LEN 160
+
+struct script_line {
+ struct list_head node;
+ char line[AVERAGE_LINE_LEN];
+};
+
+struct perf_script_browser {
+ struct ui_browser b;
+ struct list_head entries;
+ const char *script_name;
+ int nr_lines;
+};
+
+#define SCRIPT_NAMELEN 128
+#define SCRIPT_MAX_NO 64
+/*
+ * Usually the full path for a script is:
+ * /home/username/libexec/perf-core/scripts/python/xxx.py
+ * /home/username/libexec/perf-core/scripts/perl/xxx.pl
+ * So 256 should be long enough to contain the full path.
+ */
+#define SCRIPT_FULLPATH_LEN 256
+
+/*
+ * When success, will copy the full path of the selected script
+ * into the buffer pointed by script_name, and return 0.
+ * Return -1 on failure.
+ */
+static int list_scripts(char *script_name)
+{
+ char *buf, *names[SCRIPT_MAX_NO], *paths[SCRIPT_MAX_NO];
+ int i, num, choice, ret = -1;
+
+ /* Preset the script name to SCRIPT_NAMELEN */
+ buf = malloc(SCRIPT_MAX_NO * (SCRIPT_NAMELEN + SCRIPT_FULLPATH_LEN));
+ if (!buf)
+ return ret;
+
+ for (i = 0; i < SCRIPT_MAX_NO; i++) {
+ names[i] = buf + i * (SCRIPT_NAMELEN + SCRIPT_FULLPATH_LEN);
+ paths[i] = names[i] + SCRIPT_NAMELEN;
+ }
+
+ num = find_scripts(names, paths);
+ if (num > 0) {
+ choice = ui__popup_menu(num, names);
+ if (choice < num && choice >= 0) {
+ strcpy(script_name, paths[choice]);
+ ret = 0;
+ }
+ }
+
+ free(buf);
+ return ret;
+}
+
+static void script_browser__write(struct ui_browser *browser,
+ void *entry, int row)
+{
+ struct script_line *sline = list_entry(entry, struct script_line, node);
+ bool current_entry = ui_browser__is_current_entry(browser, row);
+
+ ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
+ HE_COLORSET_NORMAL);
+
+ slsmg_write_nstring(sline->line, browser->width);
+}
+
+static int script_browser__run(struct perf_script_browser *self)
+{
+ int key;
+
+ if (ui_browser__show(&self->b, self->script_name,
+ "Press <- or ESC to exit") < 0)
+ return -1;
+
+ while (1) {
+ key = ui_browser__run(&self->b, 0);
+
+ /* We can add some special key handling here if needed */
+ break;
+ }
+
+ ui_browser__hide(&self->b);
+ return key;
+}
+
+
+int script_browse(const char *script_opt)
+{
+ char cmd[SCRIPT_FULLPATH_LEN*2], script_name[SCRIPT_FULLPATH_LEN];
+ char *line = NULL;
+ size_t len = 0;
+ ssize_t retlen;
+ int ret = -1, nr_entries = 0;
+ FILE *fp;
+ void *buf;
+ struct script_line *sline;
+
+ struct perf_script_browser script = {
+ .b = {
+ .refresh = ui_browser__list_head_refresh,
+ .seek = ui_browser__list_head_seek,
+ .write = script_browser__write,
+ },
+ .script_name = script_name,
+ };
+
+ INIT_LIST_HEAD(&script.entries);
+
+ /* Save each line of the output in one struct script_line object. */
+ buf = zalloc((sizeof(*sline)) * MAX_LINES);
+ if (!buf)
+ return -1;
+ sline = buf;
+
+ memset(script_name, 0, SCRIPT_FULLPATH_LEN);
+ if (list_scripts(script_name))
+ goto exit;
+
+ sprintf(cmd, "perf script -s %s ", script_name);
+
+ if (script_opt)
+ strcat(cmd, script_opt);
+
+ if (input_name) {
+ strcat(cmd, " -i ");
+ strcat(cmd, input_name);
+ }
+
+ strcat(cmd, " 2>&1");
+
+ fp = popen(cmd, "r");
+ if (!fp)
+ goto exit;
+
+ while ((retlen = getline(&line, &len, fp)) != -1) {
+ strncpy(sline->line, line, AVERAGE_LINE_LEN);
+
+ /* If one output line is very large, just cut it short */
+ if (retlen >= AVERAGE_LINE_LEN) {
+ sline->line[AVERAGE_LINE_LEN - 1] = '\0';
+ sline->line[AVERAGE_LINE_LEN - 2] = '\n';
+ }
+ list_add_tail(&sline->node, &script.entries);
+
+ if (script.b.width < retlen)
+ script.b.width = retlen;
+
+ if (nr_entries++ >= MAX_LINES - 1)
+ break;
+ sline++;
+ }
+
+ if (script.b.width > AVERAGE_LINE_LEN)
+ script.b.width = AVERAGE_LINE_LEN;
+
+ if (line)
+ free(line);
+ pclose(fp);
+
+ script.nr_lines = nr_entries;
+ script.b.nr_entries = nr_entries;
+ script.b.entries = &script.entries;
+
+ ret = script_browser__run(&script);
+exit:
+ free(buf);
+ return ret;
+}
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index 4125c628411..253b6219a39 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -237,9 +237,7 @@ static GtkWidget *perf_gtk__setup_statusbar(void)
int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
const char *help,
- void (*timer) (void *arg)__maybe_unused,
- void *arg __maybe_unused,
- int delay_secs __maybe_unused)
+ struct hist_browser_timer *hbt __maybe_unused)
{
struct perf_evsel *pos;
GtkWidget *vbox;
diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h
index 687af0bba18..856320e2cc0 100644
--- a/tools/perf/ui/gtk/gtk.h
+++ b/tools/perf/ui/gtk/gtk.h
@@ -30,6 +30,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 perf_gtk__init_hpp(void);
#ifndef HAVE_GTK_INFO_BAR
diff --git a/tools/perf/ui/gtk/progress.c b/tools/perf/ui/gtk/progress.c
new file mode 100644
index 00000000000..482bcf3df9b
--- /dev/null
+++ b/tools/perf/ui/gtk/progress.c
@@ -0,0 +1,59 @@
+#include <inttypes.h>
+
+#include "gtk.h"
+#include "../progress.h"
+#include "util.h"
+
+static GtkWidget *dialog;
+static GtkWidget *progress;
+
+static void gtk_progress_update(u64 curr, u64 total, const char *title)
+{
+ double fraction = total ? 1.0 * curr / total : 0.0;
+ char buf[1024];
+
+ if (dialog == NULL) {
+ GtkWidget *vbox = gtk_vbox_new(TRUE, 5);
+ GtkWidget *label = gtk_label_new(title);
+
+ dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ progress = gtk_progress_bar_new();
+
+ gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, FALSE, 3);
+ gtk_box_pack_start(GTK_BOX(vbox), progress, TRUE, TRUE, 3);
+
+ gtk_container_add(GTK_CONTAINER(dialog), vbox);
+
+ gtk_window_set_title(GTK_WINDOW(dialog), "perf");
+ gtk_window_resize(GTK_WINDOW(dialog), 300, 80);
+ gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
+
+ gtk_widget_show_all(dialog);
+ }
+
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), fraction);
+ snprintf(buf, sizeof(buf), "%"PRIu64" / %"PRIu64, curr, total);
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), buf);
+
+ /* we didn't call gtk_main yet, so do it manually */
+ while (gtk_events_pending())
+ gtk_main_iteration();
+}
+
+static void gtk_progress_finish(void)
+{
+ /* this will also destroy all of its children */
+ gtk_widget_destroy(dialog);
+
+ dialog = NULL;
+}
+
+static struct ui_progress gtk_progress_fns = {
+ .update = gtk_progress_update,
+ .finish = gtk_progress_finish,
+};
+
+void perf_gtk__init_progress(void)
+{
+ progress_fns = &gtk_progress_fns;
+}
diff --git a/tools/perf/ui/gtk/setup.c b/tools/perf/ui/gtk/setup.c
index 3c4c6ef7828..6c2dd2e423f 100644
--- a/tools/perf/ui/gtk/setup.c
+++ b/tools/perf/ui/gtk/setup.c
@@ -8,7 +8,9 @@ int perf_gtk__init(void)
{
perf_error__register(&perf_gtk_eops);
perf_gtk__init_helpline();
+ perf_gtk__init_progress();
perf_gtk__init_hpp();
+
return gtk_init_check(NULL, NULL) ? 0 : -1;
}
diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c
index ccb046aac98..c06942a41c7 100644
--- a/tools/perf/ui/gtk/util.c
+++ b/tools/perf/ui/gtk/util.c
@@ -111,14 +111,3 @@ struct perf_error_ops perf_gtk_eops = {
.warning = perf_gtk__warning_statusbar,
#endif
};
-
-/*
- * FIXME: Functions below should be implemented properly.
- * For now, just add stubs for NO_NEWT=1 build.
- */
-#ifndef NEWT_SUPPORT
-void ui_progress__update(u64 curr __maybe_unused, u64 total __maybe_unused,
- const char *title __maybe_unused)
-{
-}
-#endif
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index f5a1e4f6526..aa84130024d 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -161,7 +161,7 @@ static int hpp__width_baseline(struct perf_hpp *hpp __maybe_unused)
static double baseline_percent(struct hist_entry *he)
{
- struct hist_entry *pair = he->pair;
+ struct hist_entry *pair = hist_entry__next_pair(he);
struct hists *pair_hists = pair ? pair->hists : NULL;
double percent = 0.0;
@@ -179,7 +179,10 @@ static int hpp__color_baseline(struct perf_hpp *hpp, struct hist_entry *he)
{
double percent = baseline_percent(he);
- return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent);
+ if (hist_entry__has_pairs(he))
+ return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent);
+ else
+ return scnprintf(hpp->buf, hpp->size, " ");
}
static int hpp__entry_baseline(struct perf_hpp *hpp, struct hist_entry *he)
@@ -187,7 +190,10 @@ static int hpp__entry_baseline(struct perf_hpp *hpp, struct hist_entry *he)
double percent = baseline_percent(he);
const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%%";
- return scnprintf(hpp->buf, hpp->size, fmt, percent);
+ if (hist_entry__has_pairs(he) || symbol_conf.field_sep)
+ return scnprintf(hpp->buf, hpp->size, fmt, percent);
+ else
+ return scnprintf(hpp->buf, hpp->size, " ");
}
static int hpp__header_samples(struct perf_hpp *hpp)
@@ -228,6 +234,26 @@ static int hpp__entry_period(struct perf_hpp *hpp, struct hist_entry *he)
return scnprintf(hpp->buf, hpp->size, fmt, he->stat.period);
}
+static int hpp__header_period_baseline(struct perf_hpp *hpp)
+{
+ const char *fmt = symbol_conf.field_sep ? "%s" : "%12s";
+
+ return scnprintf(hpp->buf, hpp->size, fmt, "Period Base");
+}
+
+static int hpp__width_period_baseline(struct perf_hpp *hpp __maybe_unused)
+{
+ return 12;
+}
+
+static int hpp__entry_period_baseline(struct perf_hpp *hpp, struct hist_entry *he)
+{
+ struct hist_entry *pair = hist_entry__next_pair(he);
+ u64 period = pair ? pair->stat.period : 0;
+ const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%12" PRIu64;
+
+ return scnprintf(hpp->buf, hpp->size, fmt, period);
+}
static int hpp__header_delta(struct perf_hpp *hpp)
{
const char *fmt = symbol_conf.field_sep ? "%s" : "%7s";
@@ -242,30 +268,79 @@ static int hpp__width_delta(struct perf_hpp *hpp __maybe_unused)
static int hpp__entry_delta(struct perf_hpp *hpp, struct hist_entry *he)
{
- struct hist_entry *pair = he->pair;
- struct hists *pair_hists = pair ? pair->hists : NULL;
- struct hists *hists = he->hists;
- u64 old_total, new_total;
- double old_percent = 0, new_percent = 0;
- double diff;
const char *fmt = symbol_conf.field_sep ? "%s" : "%7.7s";
char buf[32] = " ";
+ double diff;
- old_total = pair_hists ? pair_hists->stats.total_period : 0;
- if (old_total > 0 && pair)
- old_percent = 100.0 * pair->stat.period / old_total;
-
- new_total = hists->stats.total_period;
- if (new_total > 0)
- new_percent = 100.0 * he->stat.period / new_total;
+ if (he->diff.computed)
+ diff = he->diff.period_ratio_delta;
+ else
+ diff = perf_diff__compute_delta(he);
- diff = new_percent - old_percent;
if (fabs(diff) >= 0.01)
scnprintf(buf, sizeof(buf), "%+4.2F%%", diff);
return scnprintf(hpp->buf, hpp->size, fmt, buf);
}
+static int hpp__header_ratio(struct perf_hpp *hpp)
+{
+ const char *fmt = symbol_conf.field_sep ? "%s" : "%14s";
+
+ return scnprintf(hpp->buf, hpp->size, fmt, "Ratio");
+}
+
+static int hpp__width_ratio(struct perf_hpp *hpp __maybe_unused)
+{
+ return 14;
+}
+
+static int hpp__entry_ratio(struct perf_hpp *hpp, struct hist_entry *he)
+{
+ const char *fmt = symbol_conf.field_sep ? "%s" : "%14s";
+ char buf[32] = " ";
+ double ratio;
+
+ if (he->diff.computed)
+ ratio = he->diff.period_ratio;
+ else
+ ratio = perf_diff__compute_ratio(he);
+
+ if (ratio > 0.0)
+ scnprintf(buf, sizeof(buf), "%+14.6F", ratio);
+
+ return scnprintf(hpp->buf, hpp->size, fmt, buf);
+}
+
+static int hpp__header_wdiff(struct perf_hpp *hpp)
+{
+ const char *fmt = symbol_conf.field_sep ? "%s" : "%14s";
+
+ return scnprintf(hpp->buf, hpp->size, fmt, "Weighted diff");
+}
+
+static int hpp__width_wdiff(struct perf_hpp *hpp __maybe_unused)
+{
+ return 14;
+}
+
+static int hpp__entry_wdiff(struct perf_hpp *hpp, struct hist_entry *he)
+{
+ const char *fmt = symbol_conf.field_sep ? "%s" : "%14s";
+ char buf[32] = " ";
+ s64 wdiff;
+
+ if (he->diff.computed)
+ wdiff = he->diff.wdiff;
+ else
+ wdiff = perf_diff__compute_wdiff(he);
+
+ if (wdiff != 0)
+ scnprintf(buf, sizeof(buf), "%14ld", wdiff);
+
+ return scnprintf(hpp->buf, hpp->size, fmt, buf);
+}
+
static int hpp__header_displ(struct perf_hpp *hpp)
{
return scnprintf(hpp->buf, hpp->size, "Displ.");
@@ -279,7 +354,7 @@ static int hpp__width_displ(struct perf_hpp *hpp __maybe_unused)
static int hpp__entry_displ(struct perf_hpp *hpp,
struct hist_entry *he)
{
- struct hist_entry *pair = he->pair;
+ struct hist_entry *pair = hist_entry__next_pair(he);
long displacement = pair ? pair->position - he->position : 0;
const char *fmt = symbol_conf.field_sep ? "%s" : "%6.6s";
char buf[32] = " ";
@@ -290,6 +365,27 @@ static int hpp__entry_displ(struct perf_hpp *hpp,
return scnprintf(hpp->buf, hpp->size, fmt, buf);
}
+static int hpp__header_formula(struct perf_hpp *hpp)
+{
+ const char *fmt = symbol_conf.field_sep ? "%s" : "%70s";
+
+ return scnprintf(hpp->buf, hpp->size, fmt, "Formula");
+}
+
+static int hpp__width_formula(struct perf_hpp *hpp __maybe_unused)
+{
+ return 70;
+}
+
+static int hpp__entry_formula(struct perf_hpp *hpp, struct hist_entry *he)
+{
+ const char *fmt = symbol_conf.field_sep ? "%s" : "%-70s";
+ char buf[96] = " ";
+
+ perf_diff__formula(buf, sizeof(buf), he);
+ return scnprintf(hpp->buf, hpp->size, fmt, buf);
+}
+
#define HPP__COLOR_PRINT_FNS(_name) \
.header = hpp__header_ ## _name, \
.width = hpp__width_ ## _name, \
@@ -310,8 +406,12 @@ struct perf_hpp_fmt perf_hpp__format[] = {
{ .cond = false, HPP__COLOR_PRINT_FNS(overhead_guest_us) },
{ .cond = false, HPP__PRINT_FNS(samples) },
{ .cond = false, HPP__PRINT_FNS(period) },
+ { .cond = false, HPP__PRINT_FNS(period_baseline) },
{ .cond = false, HPP__PRINT_FNS(delta) },
- { .cond = false, HPP__PRINT_FNS(displ) }
+ { .cond = false, HPP__PRINT_FNS(ratio) },
+ { .cond = false, HPP__PRINT_FNS(wdiff) },
+ { .cond = false, HPP__PRINT_FNS(displ) },
+ { .cond = false, HPP__PRINT_FNS(formula) }
};
#undef HPP__COLOR_PRINT_FNS
diff --git a/tools/perf/ui/progress.c b/tools/perf/ui/progress.c
index 13aa64e50e1..3ec695607a4 100644
--- a/tools/perf/ui/progress.c
+++ b/tools/perf/ui/progress.c
@@ -1,32 +1,26 @@
#include "../cache.h"
#include "progress.h"
-#include "libslang.h"
-#include "ui.h"
-#include "browser.h"
-void ui_progress__update(u64 curr, u64 total, const char *title)
+static void nop_progress_update(u64 curr __maybe_unused,
+ u64 total __maybe_unused,
+ const char *title __maybe_unused)
{
- int bar, y;
- /*
- * FIXME: We should have a per UI backend way of showing progress,
- * stdio will just show a percentage as NN%, etc.
- */
- if (use_browser <= 0)
- return;
+}
- if (total == 0)
- return;
+static struct ui_progress default_progress_fns =
+{
+ .update = nop_progress_update,
+};
- ui__refresh_dimensions(true);
- pthread_mutex_lock(&ui__lock);
- y = SLtt_Screen_Rows / 2 - 2;
- SLsmg_set_color(0);
- SLsmg_draw_box(y, 0, 3, SLtt_Screen_Cols);
- SLsmg_gotorc(y++, 1);
- SLsmg_write_string((char *)title);
- SLsmg_set_color(HE_COLORSET_SELECTED);
- bar = ((SLtt_Screen_Cols - 2) * curr) / total;
- SLsmg_fill_region(y, 1, 1, bar, ' ');
- SLsmg_refresh();
- pthread_mutex_unlock(&ui__lock);
+struct ui_progress *progress_fns = &default_progress_fns;
+
+void ui_progress__update(u64 curr, u64 total, const char *title)
+{
+ return progress_fns->update(curr, total, title);
+}
+
+void ui_progress__finish(void)
+{
+ if (progress_fns->finish)
+ progress_fns->finish();
}
diff --git a/tools/perf/ui/progress.h b/tools/perf/ui/progress.h
index d9c205b59aa..257cc224f9c 100644
--- a/tools/perf/ui/progress.h
+++ b/tools/perf/ui/progress.h
@@ -3,6 +3,16 @@
#include <../types.h>
+struct ui_progress {
+ void (*update)(u64, u64, const char *);
+ void (*finish)(void);
+};
+
+extern struct ui_progress *progress_fns;
+
+void ui_progress__init(void);
+
void ui_progress__update(u64 curr, u64 total, const char *title);
+void ui_progress__finish(void);
#endif
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index fbd4e32d074..f0ee204f99b 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -342,7 +342,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
const char *sep = symbol_conf.field_sep;
const char *col_width = symbol_conf.col_width_list_str;
int idx, nr_rows = 0;
- char bf[64];
+ char bf[96];
struct perf_hpp dummy_hpp = {
.buf = bf,
.size = sizeof(bf),
diff --git a/tools/perf/ui/tui/progress.c b/tools/perf/ui/tui/progress.c
new file mode 100644
index 00000000000..6c2184d53cb
--- /dev/null
+++ b/tools/perf/ui/tui/progress.c
@@ -0,0 +1,42 @@
+#include "../cache.h"
+#include "../progress.h"
+#include "../libslang.h"
+#include "../ui.h"
+#include "../browser.h"
+
+static void tui_progress__update(u64 curr, u64 total, const char *title)
+{
+ int bar, y;
+ /*
+ * FIXME: We should have a per UI backend way of showing progress,
+ * stdio will just show a percentage as NN%, etc.
+ */
+ if (use_browser <= 0)
+ return;
+
+ if (total == 0)
+ return;
+
+ ui__refresh_dimensions(true);
+ pthread_mutex_lock(&ui__lock);
+ y = SLtt_Screen_Rows / 2 - 2;
+ SLsmg_set_color(0);
+ SLsmg_draw_box(y, 0, 3, SLtt_Screen_Cols);
+ SLsmg_gotorc(y++, 1);
+ SLsmg_write_string((char *)title);
+ SLsmg_set_color(HE_COLORSET_SELECTED);
+ bar = ((SLtt_Screen_Cols - 2) * curr) / total;
+ SLsmg_fill_region(y, 1, 1, bar, ' ');
+ SLsmg_refresh();
+ pthread_mutex_unlock(&ui__lock);
+}
+
+static struct ui_progress tui_progress_fns =
+{
+ .update = tui_progress__update,
+};
+
+void ui_progress__init(void)
+{
+ progress_fns = &tui_progress_fns;
+}
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c
index 60debb81537..81efa192e86 100644
--- a/tools/perf/ui/tui/setup.c
+++ b/tools/perf/ui/tui/setup.c
@@ -118,6 +118,7 @@ int ui__init(void)
newtSetSuspendCallback(newt_suspend, NULL);
ui_helpline__init();
ui_browser__init();
+ ui_progress__init();
signal(SIGSEGV, ui__signal);
signal(SIGFPE, ui__signal);
diff --git a/tools/perf/ui/ui.h b/tools/perf/ui/ui.h
index 7b67045479f..d86359c9990 100644
--- a/tools/perf/ui/ui.h
+++ b/tools/perf/ui/ui.h
@@ -3,9 +3,37 @@
#include <pthread.h>
#include <stdbool.h>
+#include <linux/compiler.h>
extern pthread_mutex_t ui__lock;
+extern int use_browser;
+
+void setup_browser(bool fallback_to_pager);
+void exit_browser(bool wait_for_ok);
+
+#ifdef NEWT_SUPPORT
+int ui__init(void);
+void ui__exit(bool wait_for_ok);
+#else
+static inline int ui__init(void)
+{
+ return -1;
+}
+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_ */
diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN
index 95264f30417..6aa34e5afdc 100755
--- a/tools/perf/util/PERF-VERSION-GEN
+++ b/tools/perf/util/PERF-VERSION-GEN
@@ -9,18 +9,14 @@ GVF=${OUTPUT}PERF-VERSION-FILE
LF='
'
+#
# First check if there is a .git to get the version from git describe
-# otherwise try to get the version from the kernel makefile
+# otherwise try to get the version from the kernel Makefile
+#
if test -d ../../.git -o -f ../../.git &&
- VN=$(git describe --match 'v[0-9].[0-9]*' --abbrev=4 HEAD 2>/dev/null) &&
- case "$VN" in
- *$LF*) (exit 1) ;;
- v[0-9]*)
- git update-index -q --refresh
- test -z "$(git diff-index --name-only HEAD --)" ||
- VN="$VN-dirty" ;;
- esac
+ VN=$(git tag 2>/dev/null | tail -1 | grep -E "v[0-9].[0-9]*")
then
+ VN=$(echo $VN"-g"$(git log -1 --abbrev=4 --pretty=format:"%h" HEAD))
VN=$(echo "$VN" | sed -e 's/-/./g');
else
VN=$(MAKEFLAGS= make -sC ../.. kernelversion)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index f0a91037137..07aaeea6000 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -15,6 +15,7 @@
#include "debug.h"
#include "annotate.h"
#include <pthread.h>
+#include <linux/bitops.h>
const char *disassembler_style;
const char *objdump_path;
@@ -170,15 +171,15 @@ static int lock__parse(struct ins_operands *ops)
if (disasm_line__parse(ops->raw, &name, &ops->locked.ops->raw) < 0)
goto out_free_ops;
- ops->locked.ins = ins__find(name);
- if (ops->locked.ins == NULL)
- goto out_free_ops;
+ ops->locked.ins = ins__find(name);
+ if (ops->locked.ins == NULL)
+ goto out_free_ops;
- if (!ops->locked.ins->ops)
- return 0;
+ if (!ops->locked.ins->ops)
+ return 0;
- if (ops->locked.ins->ops->parse)
- ops->locked.ins->ops->parse(ops->locked.ops);
+ if (ops->locked.ins->ops->parse)
+ ops->locked.ins->ops->parse(ops->locked.ops);
return 0;
@@ -400,6 +401,8 @@ static struct ins instructions[] = {
{ .name = "testb", .ops = &mov_ops, },
{ .name = "testl", .ops = &mov_ops, },
{ .name = "xadd", .ops = &mov_ops, },
+ { .name = "xbeginl", .ops = &jump_ops, },
+ { .name = "xbeginq", .ops = &jump_ops, },
};
static int ins__cmp(const void *name, const void *insp)
@@ -855,21 +858,68 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin
struct source_line *iter;
struct rb_node **p = &root->rb_node;
struct rb_node *parent = NULL;
+ int ret;
while (*p != NULL) {
parent = *p;
iter = rb_entry(parent, struct source_line, node);
- if (src_line->percent > iter->percent)
+ ret = strcmp(iter->path, src_line->path);
+ if (ret == 0) {
+ iter->percent_sum += src_line->percent;
+ return;
+ }
+
+ if (ret < 0)
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
}
+ src_line->percent_sum = src_line->percent;
+
rb_link_node(&src_line->node, parent, p);
rb_insert_color(&src_line->node, root);
}
+static void __resort_source_line(struct rb_root *root, struct source_line *src_line)
+{
+ struct source_line *iter;
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+
+ while (*p != NULL) {
+ parent = *p;
+ iter = rb_entry(parent, struct source_line, node);
+
+ if (src_line->percent_sum > iter->percent_sum)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+
+ rb_link_node(&src_line->node, parent, p);
+ rb_insert_color(&src_line->node, root);
+}
+
+static void resort_source_line(struct rb_root *dest_root, struct rb_root *src_root)
+{
+ struct source_line *src_line;
+ struct rb_node *node;
+
+ node = rb_first(src_root);
+ while (node) {
+ struct rb_node *next;
+
+ src_line = rb_entry(node, struct source_line, node);
+ next = rb_next(node);
+ rb_erase(node, src_root);
+
+ __resort_source_line(dest_root, src_line);
+ node = next;
+ }
+}
+
static void symbol__free_source_line(struct symbol *sym, int len)
{
struct annotation *notes = symbol__annotation(sym);
@@ -894,6 +944,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
struct source_line *src_line;
struct annotation *notes = symbol__annotation(sym);
struct sym_hist *h = annotation__histogram(notes, evidx);
+ struct rb_root tmp_root = RB_ROOT;
if (!h->sum)
return 0;
@@ -928,12 +979,13 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
goto next;
strcpy(src_line[i].path, path);
- insert_source_line(root, &src_line[i]);
+ insert_source_line(&tmp_root, &src_line[i]);
next:
pclose(fp);
}
+ resort_source_line(root, &tmp_root);
return 0;
}
@@ -957,7 +1009,7 @@ static void print_summary(struct rb_root *root, const char *filename)
char *path;
src_line = rb_entry(node, struct source_line, node);
- percent = src_line->percent;
+ percent = src_line->percent_sum;
color = get_percent_color(percent);
path = src_line->path;
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 39242dcee8f..8eec94358a4 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -5,6 +5,7 @@
#include <stdint.h>
#include "types.h"
#include "symbol.h"
+#include "hist.h"
#include <linux/list.h>
#include <linux/rbtree.h>
#include <pthread.h>
@@ -75,6 +76,7 @@ struct sym_hist {
struct source_line {
struct rb_node node;
double percent;
+ double percent_sum;
char *path;
};
@@ -140,20 +142,18 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx,
#ifdef NEWT_SUPPORT
int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
- void(*timer)(void *arg), void *arg, int delay_secs);
+ struct hist_browser_timer *hbt);
#else
static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
struct map *map __maybe_unused,
int evidx __maybe_unused,
- void(*timer)(void *arg) __maybe_unused,
- void *arg __maybe_unused,
- int delay_secs __maybe_unused)
+ struct hist_browser_timer *hbt
+ __maybe_unused)
{
return 0;
}
#endif
extern const char *disassembler_style;
-extern const char *objdump_path;
#endif /* __PERF_ANNOTATE_H */
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 8e3a740ddbd..5295625c0c0 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -16,11 +16,11 @@
#include "session.h"
#include "tool.h"
-static int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused,
- union perf_event *event,
- struct perf_sample *sample __maybe_unused,
- struct perf_evsel *evsel __maybe_unused,
- struct machine *machine)
+int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused,
+ union perf_event *event,
+ struct perf_sample *sample __maybe_unused,
+ struct perf_evsel *evsel __maybe_unused,
+ struct machine *machine)
{
struct addr_location al;
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
@@ -64,12 +64,27 @@ static int perf_event__exit_del_thread(struct perf_tool *tool __maybe_unused,
struct perf_tool build_id__mark_dso_hit_ops = {
.sample = build_id__mark_dso_hit,
.mmap = perf_event__process_mmap,
- .fork = perf_event__process_task,
+ .fork = perf_event__process_fork,
.exit = perf_event__exit_del_thread,
.attr = perf_event__process_attr,
.build_id = perf_event__process_build_id,
};
+int build_id__sprintf(const u8 *build_id, int len, char *bf)
+{
+ char *bid = bf;
+ const u8 *raw = build_id;
+ int i;
+
+ for (i = 0; i < len; ++i) {
+ sprintf(bid, "%02x", *raw);
+ ++raw;
+ bid += 2;
+ }
+
+ return raw - build_id;
+}
+
char *dso__build_id_filename(struct dso *self, char *bf, size_t size)
{
char build_id_hex[BUILD_ID_SIZE * 2 + 1];
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index a993ba87d99..a811f5c62e1 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -1,10 +1,19 @@
#ifndef PERF_BUILD_ID_H_
#define PERF_BUILD_ID_H_ 1
-#include "session.h"
+#define BUILD_ID_SIZE 20
+
+#include "tool.h"
+#include "types.h"
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);
+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
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 2bd51370ad2..26e36723987 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -5,6 +5,7 @@
#include "util.h"
#include "strbuf.h"
#include "../perf.h"
+#include "../ui/ui.h"
#define CMD_EXEC_PATH "--exec-path"
#define CMD_PERF_DIR "--perf-dir="
@@ -31,44 +32,6 @@ extern const char *pager_program;
extern int pager_in_use(void);
extern int pager_use_color;
-extern int use_browser;
-
-#if defined(NEWT_SUPPORT) || defined(GTK2_SUPPORT)
-void setup_browser(bool fallback_to_pager);
-void exit_browser(bool wait_for_ok);
-
-#ifdef NEWT_SUPPORT
-int ui__init(void);
-void ui__exit(bool wait_for_ok);
-#else
-static inline int ui__init(void)
-{
- return -1;
-}
-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
-
-#else /* NEWT_SUPPORT || GTK2_SUPPORT */
-
-static inline void setup_browser(bool fallback_to_pager)
-{
- if (fallback_to_pager)
- setup_pager();
-}
-static inline void exit_browser(bool wait_for_ok __maybe_unused) {}
-#endif /* NEWT_SUPPORT || GTK2_SUPPORT */
-
char *alias_lookup(const char *alias);
int split_cmdline(char *cmdline, const char ***argv);
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index dec98750b48..83e8d234af6 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -26,6 +26,7 @@ int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2)));
static inline void ui_progress__update(u64 curr __maybe_unused,
u64 total __maybe_unused,
const char *title __maybe_unused) {}
+static inline void ui_progress__finish(void) {}
#define ui__error(format, arg...) ui__warning(format, ##arg)
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
new file mode 100644
index 00000000000..d6d9a465acd
--- /dev/null
+++ b/tools/perf/util/dso.c
@@ -0,0 +1,595 @@
+#include "symbol.h"
+#include "dso.h"
+#include "machine.h"
+#include "util.h"
+#include "debug.h"
+
+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',
+ };
+
+ if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
+ return '!';
+ return origin[dso->symtab_type];
+}
+
+int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
+ char *root_dir, char *file, size_t size)
+{
+ char build_id_hex[BUILD_ID_SIZE * 2 + 1];
+ int ret = 0;
+
+ switch (type) {
+ case DSO_BINARY_TYPE__DEBUGLINK: {
+ char *debuglink;
+
+ strncpy(file, dso->long_name, size);
+ debuglink = file + dso->long_name_len;
+ while (debuglink != file && *debuglink != '/')
+ debuglink--;
+ if (*debuglink == '/')
+ debuglink++;
+ filename__read_debuglink(dso->long_name, debuglink,
+ size - (debuglink - file));
+ }
+ break;
+ case DSO_BINARY_TYPE__BUILD_ID_CACHE:
+ /* skip the locally configured cache if a symfs is given */
+ if (symbol_conf.symfs[0] ||
+ (dso__build_id_filename(dso, file, size) == NULL))
+ ret = -1;
+ break;
+
+ case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
+ snprintf(file, size, "%s/usr/lib/debug%s.debug",
+ symbol_conf.symfs, dso->long_name);
+ break;
+
+ case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
+ snprintf(file, size, "%s/usr/lib/debug%s",
+ symbol_conf.symfs, dso->long_name);
+ break;
+
+ case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
+ if (!dso->has_build_id) {
+ ret = -1;
+ break;
+ }
+
+ build_id__sprintf(dso->build_id,
+ sizeof(dso->build_id),
+ build_id_hex);
+ snprintf(file, size,
+ "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
+ symbol_conf.symfs, build_id_hex, build_id_hex + 2);
+ break;
+
+ case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
+ snprintf(file, size, "%s%s",
+ symbol_conf.symfs, dso->long_name);
+ break;
+
+ case DSO_BINARY_TYPE__GUEST_KMODULE:
+ snprintf(file, size, "%s%s%s", symbol_conf.symfs,
+ root_dir, dso->long_name);
+ break;
+
+ case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
+ snprintf(file, size, "%s%s", symbol_conf.symfs,
+ dso->long_name);
+ break;
+
+ default:
+ case DSO_BINARY_TYPE__KALLSYMS:
+ case DSO_BINARY_TYPE__VMLINUX:
+ case DSO_BINARY_TYPE__GUEST_KALLSYMS:
+ case DSO_BINARY_TYPE__GUEST_VMLINUX:
+ case DSO_BINARY_TYPE__JAVA_JIT:
+ case DSO_BINARY_TYPE__NOT_FOUND:
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+static int open_dso(struct dso *dso, struct machine *machine)
+{
+ char *root_dir = (char *) "";
+ char *name;
+ int fd;
+
+ name = malloc(PATH_MAX);
+ if (!name)
+ return -ENOMEM;
+
+ if (machine)
+ root_dir = machine->root_dir;
+
+ if (dso__binary_type_file(dso, dso->data_type,
+ root_dir, name, PATH_MAX)) {
+ free(name);
+ return -EINVAL;
+ }
+
+ fd = open(name, O_RDONLY);
+ free(name);
+ return fd;
+}
+
+int dso__data_fd(struct dso *dso, struct machine *machine)
+{
+ static enum dso_binary_type binary_type_data[] = {
+ DSO_BINARY_TYPE__BUILD_ID_CACHE,
+ DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
+ DSO_BINARY_TYPE__NOT_FOUND,
+ };
+ int i = 0;
+
+ if (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND)
+ return open_dso(dso, machine);
+
+ do {
+ int fd;
+
+ dso->data_type = binary_type_data[i++];
+
+ fd = open_dso(dso, machine);
+ if (fd >= 0)
+ return fd;
+
+ } while (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND);
+
+ return -EINVAL;
+}
+
+static void
+dso_cache__free(struct rb_root *root)
+{
+ struct rb_node *next = rb_first(root);
+
+ while (next) {
+ struct dso_cache *cache;
+
+ cache = rb_entry(next, struct dso_cache, rb_node);
+ next = rb_next(&cache->rb_node);
+ rb_erase(&cache->rb_node, root);
+ free(cache);
+ }
+}
+
+static struct dso_cache*
+dso_cache__find(struct rb_root *root, u64 offset)
+{
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+ struct dso_cache *cache;
+
+ while (*p != NULL) {
+ u64 end;
+
+ parent = *p;
+ cache = rb_entry(parent, struct dso_cache, rb_node);
+ end = cache->offset + DSO__DATA_CACHE_SIZE;
+
+ if (offset < cache->offset)
+ p = &(*p)->rb_left;
+ else if (offset >= end)
+ p = &(*p)->rb_right;
+ else
+ return cache;
+ }
+ return NULL;
+}
+
+static void
+dso_cache__insert(struct rb_root *root, struct dso_cache *new)
+{
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+ struct dso_cache *cache;
+ u64 offset = new->offset;
+
+ while (*p != NULL) {
+ u64 end;
+
+ parent = *p;
+ cache = rb_entry(parent, struct dso_cache, rb_node);
+ end = cache->offset + DSO__DATA_CACHE_SIZE;
+
+ if (offset < cache->offset)
+ p = &(*p)->rb_left;
+ else if (offset >= end)
+ p = &(*p)->rb_right;
+ }
+
+ rb_link_node(&new->rb_node, parent, p);
+ rb_insert_color(&new->rb_node, root);
+}
+
+static ssize_t
+dso_cache__memcpy(struct dso_cache *cache, u64 offset,
+ u8 *data, u64 size)
+{
+ u64 cache_offset = offset - cache->offset;
+ u64 cache_size = min(cache->size - cache_offset, size);
+
+ memcpy(data, cache->data + cache_offset, cache_size);
+ return cache_size;
+}
+
+static ssize_t
+dso_cache__read(struct dso *dso, struct machine *machine,
+ u64 offset, u8 *data, ssize_t size)
+{
+ struct dso_cache *cache;
+ ssize_t ret;
+ int fd;
+
+ fd = dso__data_fd(dso, machine);
+ if (fd < 0)
+ return -1;
+
+ do {
+ u64 cache_offset;
+
+ ret = -ENOMEM;
+
+ cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE);
+ if (!cache)
+ break;
+
+ cache_offset = offset & DSO__DATA_CACHE_MASK;
+ ret = -EINVAL;
+
+ if (-1 == lseek(fd, cache_offset, SEEK_SET))
+ break;
+
+ ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE);
+ if (ret <= 0)
+ break;
+
+ cache->offset = cache_offset;
+ cache->size = ret;
+ dso_cache__insert(&dso->cache, cache);
+
+ ret = dso_cache__memcpy(cache, offset, data, size);
+
+ } while (0);
+
+ if (ret <= 0)
+ free(cache);
+
+ close(fd);
+ return ret;
+}
+
+static ssize_t dso_cache_read(struct dso *dso, struct machine *machine,
+ u64 offset, u8 *data, ssize_t size)
+{
+ struct dso_cache *cache;
+
+ cache = dso_cache__find(&dso->cache, offset);
+ if (cache)
+ return dso_cache__memcpy(cache, offset, data, size);
+ else
+ return dso_cache__read(dso, machine, offset, data, size);
+}
+
+ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
+ u64 offset, u8 *data, ssize_t size)
+{
+ ssize_t r = 0;
+ u8 *p = data;
+
+ do {
+ ssize_t ret;
+
+ ret = dso_cache_read(dso, machine, offset, p, size);
+ if (ret < 0)
+ return ret;
+
+ /* Reached EOF, return what we have. */
+ if (!ret)
+ break;
+
+ BUG_ON(ret > size);
+
+ r += ret;
+ p += ret;
+ offset += ret;
+ size -= ret;
+
+ } while (size);
+
+ return r;
+}
+
+ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
+ struct machine *machine, u64 addr,
+ u8 *data, ssize_t size)
+{
+ u64 offset = map->map_ip(map, addr);
+ return dso__data_read_offset(dso, machine, offset, data, size);
+}
+
+struct map *dso__new_map(const char *name)
+{
+ struct map *map = NULL;
+ struct dso *dso = dso__new(name);
+
+ if (dso)
+ map = map__new2(0, dso, MAP__FUNCTION);
+
+ return map;
+}
+
+struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
+ const char *short_name, int dso_type)
+{
+ /*
+ * The kernel dso could be created by build_id processing.
+ */
+ struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name);
+
+ /*
+ * We need to run this in all cases, since during the build_id
+ * processing we had no idea this was the kernel dso.
+ */
+ if (dso != NULL) {
+ dso__set_short_name(dso, short_name);
+ dso->kernel = dso_type;
+ }
+
+ return dso;
+}
+
+void dso__set_long_name(struct dso *dso, char *name)
+{
+ if (name == NULL)
+ return;
+ dso->long_name = name;
+ dso->long_name_len = strlen(name);
+}
+
+void dso__set_short_name(struct dso *dso, const char *name)
+{
+ if (name == NULL)
+ return;
+ dso->short_name = name;
+ dso->short_name_len = strlen(name);
+}
+
+static void dso__set_basename(struct dso *dso)
+{
+ dso__set_short_name(dso, basename(dso->long_name));
+}
+
+int dso__name_len(const struct dso *dso)
+{
+ if (!dso)
+ return strlen("[unknown]");
+ if (verbose)
+ return dso->long_name_len;
+
+ return dso->short_name_len;
+}
+
+bool dso__loaded(const struct dso *dso, enum map_type type)
+{
+ return dso->loaded & (1 << type);
+}
+
+bool dso__sorted_by_name(const struct dso *dso, enum map_type type)
+{
+ return dso->sorted_by_name & (1 << type);
+}
+
+void dso__set_sorted_by_name(struct dso *dso, enum map_type type)
+{
+ dso->sorted_by_name |= (1 << type);
+}
+
+struct dso *dso__new(const char *name)
+{
+ struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
+
+ if (dso != NULL) {
+ int i;
+ strcpy(dso->name, name);
+ dso__set_long_name(dso, dso->name);
+ dso__set_short_name(dso, dso->name);
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
+ dso->cache = RB_ROOT;
+ dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
+ dso->data_type = DSO_BINARY_TYPE__NOT_FOUND;
+ dso->loaded = 0;
+ dso->sorted_by_name = 0;
+ dso->has_build_id = 0;
+ dso->kernel = DSO_TYPE_USER;
+ dso->needs_swap = DSO_SWAP__UNSET;
+ INIT_LIST_HEAD(&dso->node);
+ }
+
+ return dso;
+}
+
+void dso__delete(struct dso *dso)
+{
+ int i;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ symbols__delete(&dso->symbols[i]);
+ if (dso->sname_alloc)
+ free((char *)dso->short_name);
+ if (dso->lname_alloc)
+ free(dso->long_name);
+ dso_cache__free(&dso->cache);
+ free(dso);
+}
+
+void dso__set_build_id(struct dso *dso, void *build_id)
+{
+ memcpy(dso->build_id, build_id, sizeof(dso->build_id));
+ dso->has_build_id = 1;
+}
+
+bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
+{
+ return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
+}
+
+void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
+{
+ char path[PATH_MAX];
+
+ if (machine__is_default_guest(machine))
+ return;
+ sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
+ if (sysfs__read_build_id(path, dso->build_id,
+ sizeof(dso->build_id)) == 0)
+ dso->has_build_id = true;
+}
+
+int dso__kernel_module_get_build_id(struct dso *dso,
+ const char *root_dir)
+{
+ char filename[PATH_MAX];
+ /*
+ * kernel module short names are of the form "[module]" and
+ * we need just "module" here.
+ */
+ const char *name = dso->short_name + 1;
+
+ snprintf(filename, sizeof(filename),
+ "%s/sys/module/%.*s/notes/.note.gnu.build-id",
+ root_dir, (int)strlen(name) - 1, name);
+
+ if (sysfs__read_build_id(filename, dso->build_id,
+ sizeof(dso->build_id)) == 0)
+ dso->has_build_id = true;
+
+ return 0;
+}
+
+bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
+{
+ bool have_build_id = false;
+ struct dso *pos;
+
+ list_for_each_entry(pos, head, node) {
+ if (with_hits && !pos->hit)
+ continue;
+ if (pos->has_build_id) {
+ have_build_id = true;
+ continue;
+ }
+ if (filename__read_build_id(pos->long_name, pos->build_id,
+ sizeof(pos->build_id)) > 0) {
+ have_build_id = true;
+ pos->has_build_id = true;
+ }
+ }
+
+ return have_build_id;
+}
+
+void dsos__add(struct list_head *head, struct dso *dso)
+{
+ list_add_tail(&dso->node, head);
+}
+
+struct dso *dsos__find(struct list_head *head, const char *name)
+{
+ struct dso *pos;
+
+ list_for_each_entry(pos, head, node)
+ if (strcmp(pos->long_name, name) == 0)
+ return pos;
+ return NULL;
+}
+
+struct dso *__dsos__findnew(struct list_head *head, const char *name)
+{
+ struct dso *dso = dsos__find(head, name);
+
+ if (!dso) {
+ dso = dso__new(name);
+ if (dso != NULL) {
+ dsos__add(head, dso);
+ dso__set_basename(dso);
+ }
+ }
+
+ return dso;
+}
+
+size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
+ bool with_hits)
+{
+ struct dso *pos;
+ size_t ret = 0;
+
+ list_for_each_entry(pos, head, node) {
+ if (with_hits && !pos->hit)
+ continue;
+ ret += dso__fprintf_buildid(pos, fp);
+ ret += fprintf(fp, " %s\n", pos->long_name);
+ }
+ return ret;
+}
+
+size_t __dsos__fprintf(struct list_head *head, FILE *fp)
+{
+ struct dso *pos;
+ size_t ret = 0;
+
+ list_for_each_entry(pos, head, node) {
+ int i;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ ret += dso__fprintf(pos, i, fp);
+ }
+
+ return ret;
+}
+
+size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
+{
+ char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+
+ build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
+ return fprintf(fp, "%s", sbuild_id);
+}
+
+size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp)
+{
+ struct rb_node *nd;
+ size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
+
+ if (dso->short_name != dso->long_name)
+ ret += fprintf(fp, "%s, ", dso->long_name);
+ ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
+ dso->loaded ? "" : "NOT ");
+ ret += dso__fprintf_buildid(dso, fp);
+ ret += fprintf(fp, ")\n");
+ for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) {
+ struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
+ ret += symbol__fprintf(pos, fp);
+ }
+
+ return ret;
+}
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
new file mode 100644
index 00000000000..e03276940b9
--- /dev/null
+++ b/tools/perf/util/dso.h
@@ -0,0 +1,148 @@
+#ifndef __PERF_DSO
+#define __PERF_DSO
+
+#include <linux/types.h>
+#include <linux/rbtree.h>
+#include "types.h"
+#include "map.h"
+
+enum dso_binary_type {
+ DSO_BINARY_TYPE__KALLSYMS = 0,
+ DSO_BINARY_TYPE__GUEST_KALLSYMS,
+ DSO_BINARY_TYPE__VMLINUX,
+ DSO_BINARY_TYPE__GUEST_VMLINUX,
+ DSO_BINARY_TYPE__JAVA_JIT,
+ DSO_BINARY_TYPE__DEBUGLINK,
+ DSO_BINARY_TYPE__BUILD_ID_CACHE,
+ DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
+ DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
+ DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
+ DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
+ DSO_BINARY_TYPE__GUEST_KMODULE,
+ DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
+ DSO_BINARY_TYPE__NOT_FOUND,
+};
+
+enum dso_kernel_type {
+ DSO_TYPE_USER = 0,
+ DSO_TYPE_KERNEL,
+ DSO_TYPE_GUEST_KERNEL
+};
+
+enum dso_swap_type {
+ DSO_SWAP__UNSET,
+ DSO_SWAP__NO,
+ DSO_SWAP__YES,
+};
+
+#define DSO__SWAP(dso, type, val) \
+({ \
+ type ____r = val; \
+ BUG_ON(dso->needs_swap == DSO_SWAP__UNSET); \
+ if (dso->needs_swap == DSO_SWAP__YES) { \
+ switch (sizeof(____r)) { \
+ case 2: \
+ ____r = bswap_16(val); \
+ break; \
+ case 4: \
+ ____r = bswap_32(val); \
+ break; \
+ case 8: \
+ ____r = bswap_64(val); \
+ break; \
+ default: \
+ BUG_ON(1); \
+ } \
+ } \
+ ____r; \
+})
+
+#define DSO__DATA_CACHE_SIZE 4096
+#define DSO__DATA_CACHE_MASK ~(DSO__DATA_CACHE_SIZE - 1)
+
+struct dso_cache {
+ struct rb_node rb_node;
+ u64 offset;
+ u64 size;
+ char data[0];
+};
+
+struct dso {
+ struct list_head node;
+ struct rb_root symbols[MAP__NR_TYPES];
+ struct rb_root symbol_names[MAP__NR_TYPES];
+ struct rb_root cache;
+ enum dso_kernel_type kernel;
+ enum dso_swap_type needs_swap;
+ enum dso_binary_type symtab_type;
+ enum dso_binary_type data_type;
+ u8 adjust_symbols:1;
+ u8 has_build_id:1;
+ u8 hit:1;
+ u8 annotate_warned:1;
+ u8 sname_alloc:1;
+ u8 lname_alloc:1;
+ u8 sorted_by_name;
+ u8 loaded;
+ u8 build_id[BUILD_ID_SIZE];
+ const char *short_name;
+ char *long_name;
+ u16 long_name_len;
+ u16 short_name_len;
+ char name[0];
+};
+
+static inline void dso__set_loaded(struct dso *dso, enum map_type type)
+{
+ dso->loaded |= (1 << type);
+}
+
+struct dso *dso__new(const char *name);
+void dso__delete(struct dso *dso);
+
+void dso__set_short_name(struct dso *dso, const char *name);
+void dso__set_long_name(struct dso *dso, char *name);
+
+int dso__name_len(const struct dso *dso);
+
+bool dso__loaded(const struct dso *dso, enum map_type type);
+
+bool dso__sorted_by_name(const struct dso *dso, enum map_type type);
+void dso__set_sorted_by_name(struct dso *dso, enum map_type type);
+void dso__sort_by_name(struct dso *dso, enum map_type type);
+
+void dso__set_build_id(struct dso *dso, void *build_id);
+bool dso__build_id_equal(const struct dso *dso, u8 *build_id);
+void dso__read_running_kernel_build_id(struct dso *dso,
+ struct machine *machine);
+int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir);
+
+char dso__symtab_origin(const struct dso *dso);
+int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
+ char *root_dir, char *file, size_t size);
+
+int dso__data_fd(struct dso *dso, struct machine *machine);
+ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
+ u64 offset, u8 *data, ssize_t size);
+ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
+ struct machine *machine, u64 addr,
+ u8 *data, ssize_t size);
+
+struct map *dso__new_map(const char *name);
+struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
+ const char *short_name, int dso_type);
+
+void dsos__add(struct list_head *head, struct dso *dso);
+struct dso *dsos__find(struct list_head *head, const char *name);
+struct dso *__dsos__findnew(struct list_head *head, const char *name);
+bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
+
+size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
+ bool with_hits);
+size_t __dsos__fprintf(struct list_head *head, FILE *fp);
+
+size_t dso__fprintf_buildid(struct dso *dso, FILE *fp);
+size_t dso__fprintf_symbols_by_name(struct dso *dso,
+ enum map_type type, FILE *fp);
+size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp);
+#endif /* __PERF_DSO */
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 6715b193872..3cf2c3e0605 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1,6 +1,7 @@
#include <linux/types.h>
#include "event.h"
#include "debug.h"
+#include "machine.h"
#include "sort.h"
#include "string.h"
#include "strlist.h"
@@ -192,55 +193,43 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
event->header.misc = PERF_RECORD_MISC_USER;
while (1) {
- char bf[BUFSIZ], *pbf = bf;
- int n;
+ char bf[BUFSIZ];
+ char prot[5];
+ char execname[PATH_MAX];
+ char anonstr[] = "//anon";
size_t size;
+
if (fgets(bf, sizeof(bf), fp) == NULL)
break;
+ /* ensure null termination since stack will be reused. */
+ strcpy(execname, "");
+
/* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */
- n = hex2u64(pbf, &event->mmap.start);
- if (n < 0)
- continue;
- pbf += n + 1;
- n = hex2u64(pbf, &event->mmap.len);
- if (n < 0)
+ sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %*x:%*x %*u %s\n",
+ &event->mmap.start, &event->mmap.len, prot,
+ &event->mmap.pgoff, execname);
+
+ if (prot[2] != 'x')
continue;
- pbf += n + 3;
- if (*pbf == 'x') { /* vm_exec */
- char anonstr[] = "//anon\n";
- char *execname = strchr(bf, '/');
-
- /* Catch VDSO */
- if (execname == NULL)
- execname = strstr(bf, "[vdso]");
-
- /* Catch anonymous mmaps */
- if ((execname == NULL) && !strstr(bf, "["))
- execname = anonstr;
-
- if (execname == NULL)
- continue;
-
- pbf += 3;
- n = hex2u64(pbf, &event->mmap.pgoff);
-
- size = strlen(execname);
- execname[size - 1] = '\0'; /* Remove \n */
- memcpy(event->mmap.filename, execname, size);
- size = PERF_ALIGN(size, sizeof(u64));
- event->mmap.len -= event->mmap.start;
- event->mmap.header.size = (sizeof(event->mmap) -
- (sizeof(event->mmap.filename) - size));
- memset(event->mmap.filename + size, 0, machine->id_hdr_size);
- event->mmap.header.size += machine->id_hdr_size;
- event->mmap.pid = tgid;
- event->mmap.tid = pid;
-
- if (process(tool, event, &synth_sample, machine) != 0) {
- rc = -1;
- break;
- }
+
+ if (!strcmp(execname, ""))
+ strcpy(execname, anonstr);
+
+ size = strlen(execname) + 1;
+ memcpy(event->mmap.filename, execname, size);
+ size = PERF_ALIGN(size, sizeof(u64));
+ event->mmap.len -= event->mmap.start;
+ event->mmap.header.size = (sizeof(event->mmap) -
+ (sizeof(event->mmap.filename) - size));
+ memset(event->mmap.filename + size, 0, machine->id_hdr_size);
+ event->mmap.header.size += machine->id_hdr_size;
+ event->mmap.pid = tgid;
+ event->mmap.tid = pid;
+
+ if (process(tool, event, &synth_sample, machine) != 0) {
+ rc = -1;
+ break;
}
}
@@ -404,16 +393,15 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
if (*end) /* only interested in proper numerical dirents */
continue;
-
- if (__event__synthesize_thread(comm_event, mmap_event, pid, 1,
- process, tool, machine) != 0) {
- err = -1;
- goto out_closedir;
- }
+ /*
+ * We may race with exiting thread, so don't stop just because
+ * one thread couldn't be synthesized.
+ */
+ __event__synthesize_thread(comm_event, mmap_event, pid, 1,
+ process, tool, machine);
}
err = 0;
-out_closedir:
closedir(proc);
out_free_mmap:
free(mmap_event);
@@ -519,134 +507,15 @@ int perf_event__process_comm(struct perf_tool *tool __maybe_unused,
struct perf_sample *sample __maybe_unused,
struct machine *machine)
{
- struct thread *thread = machine__findnew_thread(machine, event->comm.tid);
-
- if (dump_trace)
- perf_event__fprintf_comm(event, stdout);
-
- if (thread == NULL || thread__set_comm(thread, event->comm.comm)) {
- dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
- return -1;
- }
-
- return 0;
+ return machine__process_comm_event(machine, event);
}
int perf_event__process_lost(struct perf_tool *tool __maybe_unused,
union perf_event *event,
struct perf_sample *sample __maybe_unused,
- struct machine *machine __maybe_unused)
-{
- dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n",
- event->lost.id, event->lost.lost);
- return 0;
-}
-
-static void perf_event__set_kernel_mmap_len(union perf_event *event,
- struct map **maps)
-{
- maps[MAP__FUNCTION]->start = event->mmap.start;
- maps[MAP__FUNCTION]->end = event->mmap.start + event->mmap.len;
- /*
- * Be a bit paranoid here, some perf.data file came with
- * a zero sized synthesized MMAP event for the kernel.
- */
- if (maps[MAP__FUNCTION]->end == 0)
- maps[MAP__FUNCTION]->end = ~0ULL;
-}
-
-static int perf_event__process_kernel_mmap(struct perf_tool *tool
- __maybe_unused,
- union perf_event *event,
- struct machine *machine)
+ struct machine *machine)
{
- struct map *map;
- char kmmap_prefix[PATH_MAX];
- enum dso_kernel_type kernel_type;
- bool is_kernel_mmap;
-
- machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix));
- if (machine__is_host(machine))
- kernel_type = DSO_TYPE_KERNEL;
- else
- kernel_type = DSO_TYPE_GUEST_KERNEL;
-
- is_kernel_mmap = memcmp(event->mmap.filename,
- kmmap_prefix,
- strlen(kmmap_prefix) - 1) == 0;
- if (event->mmap.filename[0] == '/' ||
- (!is_kernel_mmap && event->mmap.filename[0] == '[')) {
-
- char short_module_name[1024];
- char *name, *dot;
-
- if (event->mmap.filename[0] == '/') {
- name = strrchr(event->mmap.filename, '/');
- if (name == NULL)
- goto out_problem;
-
- ++name; /* skip / */
- dot = strrchr(name, '.');
- if (dot == NULL)
- goto out_problem;
- snprintf(short_module_name, sizeof(short_module_name),
- "[%.*s]", (int)(dot - name), name);
- strxfrchar(short_module_name, '-', '_');
- } else
- strcpy(short_module_name, event->mmap.filename);
-
- map = machine__new_module(machine, event->mmap.start,
- event->mmap.filename);
- if (map == NULL)
- goto out_problem;
-
- name = strdup(short_module_name);
- if (name == NULL)
- goto out_problem;
-
- map->dso->short_name = name;
- map->dso->sname_alloc = 1;
- map->end = map->start + event->mmap.len;
- } else if (is_kernel_mmap) {
- const char *symbol_name = (event->mmap.filename +
- strlen(kmmap_prefix));
- /*
- * Should be there already, from the build-id table in
- * the header.
- */
- struct dso *kernel = __dsos__findnew(&machine->kernel_dsos,
- kmmap_prefix);
- if (kernel == NULL)
- goto out_problem;
-
- kernel->kernel = kernel_type;
- if (__machine__create_kernel_maps(machine, kernel) < 0)
- goto out_problem;
-
- perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps);
-
- /*
- * Avoid using a zero address (kptr_restrict) for the ref reloc
- * symbol. Effectively having zero here means that at record
- * time /proc/sys/kernel/kptr_restrict was non zero.
- */
- if (event->mmap.pgoff != 0) {
- maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps,
- symbol_name,
- event->mmap.pgoff);
- }
-
- if (machine__is_default_guest(machine)) {
- /*
- * preload dso of guest kernel and modules
- */
- dso__load(kernel, machine->vmlinux_maps[MAP__FUNCTION],
- NULL);
- }
- }
- return 0;
-out_problem:
- return -1;
+ return machine__process_lost_event(machine, event);
}
size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
@@ -656,43 +525,12 @@ size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
event->mmap.len, event->mmap.pgoff, event->mmap.filename);
}
-int perf_event__process_mmap(struct perf_tool *tool,
+int perf_event__process_mmap(struct perf_tool *tool __maybe_unused,
union perf_event *event,
struct perf_sample *sample __maybe_unused,
struct machine *machine)
{
- struct thread *thread;
- struct map *map;
- u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
- int ret = 0;
-
- if (dump_trace)
- perf_event__fprintf_mmap(event, stdout);
-
- if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
- cpumode == PERF_RECORD_MISC_KERNEL) {
- ret = perf_event__process_kernel_mmap(tool, event, machine);
- if (ret < 0)
- goto out_problem;
- return 0;
- }
-
- thread = machine__findnew_thread(machine, event->mmap.pid);
- if (thread == NULL)
- goto out_problem;
- map = map__new(&machine->user_dsos, event->mmap.start,
- event->mmap.len, event->mmap.pgoff,
- event->mmap.pid, event->mmap.filename,
- MAP__FUNCTION);
- if (map == NULL)
- goto out_problem;
-
- thread__insert_map(thread, map);
- return 0;
-
-out_problem:
- dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
- return 0;
+ return machine__process_mmap_event(machine, event);
}
size_t perf_event__fprintf_task(union perf_event *event, FILE *fp)
@@ -702,29 +540,20 @@ size_t perf_event__fprintf_task(union perf_event *event, FILE *fp)
event->fork.ppid, event->fork.ptid);
}
-int perf_event__process_task(struct perf_tool *tool __maybe_unused,
+int perf_event__process_fork(struct perf_tool *tool __maybe_unused,
union perf_event *event,
struct perf_sample *sample __maybe_unused,
- struct machine *machine)
+ struct machine *machine)
{
- struct thread *thread = machine__findnew_thread(machine, event->fork.tid);
- struct thread *parent = machine__findnew_thread(machine, event->fork.ptid);
-
- if (dump_trace)
- perf_event__fprintf_task(event, stdout);
-
- if (event->header.type == PERF_RECORD_EXIT) {
- machine__remove_thread(machine, thread);
- return 0;
- }
-
- if (thread == NULL || parent == NULL ||
- thread__fork(thread, parent) < 0) {
- dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
- return -1;
- }
+ return machine__process_fork_event(machine, event);
+}
- return 0;
+int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
+ union perf_event *event,
+ struct perf_sample *sample __maybe_unused,
+ struct machine *machine)
+{
+ return machine__process_exit_event(machine, event);
}
size_t perf_event__fprintf(union perf_event *event, FILE *fp)
@@ -750,27 +579,12 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp)
return ret;
}
-int perf_event__process(struct perf_tool *tool, union perf_event *event,
- struct perf_sample *sample, struct machine *machine)
+int perf_event__process(struct perf_tool *tool __maybe_unused,
+ union perf_event *event,
+ struct perf_sample *sample __maybe_unused,
+ struct machine *machine)
{
- switch (event->header.type) {
- case PERF_RECORD_COMM:
- perf_event__process_comm(tool, event, sample, machine);
- break;
- case PERF_RECORD_MMAP:
- perf_event__process_mmap(tool, event, sample, machine);
- break;
- case PERF_RECORD_FORK:
- case PERF_RECORD_EXIT:
- perf_event__process_task(tool, event, sample, machine);
- break;
- case PERF_RECORD_LOST:
- perf_event__process_lost(tool, event, sample, machine);
- default:
- break;
- }
-
- return 0;
+ return machine__process_event(machine, event);
}
void thread__find_addr_map(struct thread *self,
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 21b99e741a8..0d573ff4771 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -6,6 +6,7 @@
#include "../perf.h"
#include "map.h"
+#include "build-id.h"
/*
* PERF_SAMPLE_IP | PERF_SAMPLE_TID | *
@@ -96,8 +97,6 @@ struct perf_sample {
struct stack_dump user_stack;
};
-#define BUILD_ID_SIZE 20
-
struct build_id_event {
struct perf_event_header header;
pid_t pid;
@@ -191,7 +190,11 @@ int perf_event__process_mmap(struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample,
struct machine *machine);
-int perf_event__process_task(struct perf_tool *tool,
+int perf_event__process_fork(struct perf_tool *tool,
+ union perf_event *event,
+ struct perf_sample *sample,
+ struct machine *machine);
+int perf_event__process_exit(struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample,
struct machine *machine);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 186b8773039..705293489e3 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -52,15 +52,13 @@ struct perf_evlist *perf_evlist__new(struct cpu_map *cpus,
void perf_evlist__config_attrs(struct perf_evlist *evlist,
struct perf_record_opts *opts)
{
- struct perf_evsel *evsel, *first;
+ struct perf_evsel *evsel;
if (evlist->cpus->map[0] < 0)
opts->no_inherit = true;
- first = perf_evlist__first(evlist);
-
list_for_each_entry(evsel, &evlist->entries, node) {
- perf_evsel__config(evsel, opts, first);
+ perf_evsel__config(evsel, opts);
if (evlist->nr_entries > 1)
evsel->attr.sample_type |= PERF_SAMPLE_ID;
@@ -224,6 +222,8 @@ void perf_evlist__disable(struct perf_evlist *evlist)
for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
list_for_each_entry(pos, &evlist->entries, node) {
+ if (perf_evsel__is_group_member(pos))
+ continue;
for (thread = 0; thread < evlist->threads->nr; thread++)
ioctl(FD(pos, cpu, thread),
PERF_EVENT_IOC_DISABLE, 0);
@@ -238,6 +238,8 @@ void perf_evlist__enable(struct perf_evlist *evlist)
for (cpu = 0; cpu < cpu_map__nr(evlist->cpus); cpu++) {
list_for_each_entry(pos, &evlist->entries, node) {
+ if (perf_evsel__is_group_member(pos))
+ continue;
for (thread = 0; thread < evlist->threads->nr; thread++)
ioctl(FD(pos, cpu, thread),
PERF_EVENT_IOC_ENABLE, 0);
@@ -325,8 +327,6 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
{
- /* XXX Move this to perf.c, making it generally available */
- unsigned int page_size = sysconf(_SC_PAGE_SIZE);
struct perf_mmap *md = &evlist->mmap[idx];
unsigned int head = perf_mmap__read_head(md);
unsigned int old = md->prev;
@@ -528,7 +528,6 @@ out_unmap:
int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
bool overwrite)
{
- unsigned int page_size = sysconf(_SC_PAGE_SIZE);
struct perf_evsel *evsel;
const struct cpu_map *cpus = evlist->cpus;
const struct thread_map *threads = evlist->threads;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 618d41140ab..1b16dd1edc8 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -18,8 +18,8 @@
#include "cpumap.h"
#include "thread_map.h"
#include "target.h"
-#include "../../../include/linux/hw_breakpoint.h"
-#include "../../../include/uapi/linux/perf_event.h"
+#include <linux/hw_breakpoint.h>
+#include <linux/perf_event.h>
#include "perf_regs.h"
#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
@@ -404,13 +404,40 @@ const char *perf_evsel__name(struct perf_evsel *evsel)
return evsel->name ?: "unknown";
}
-void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts,
- struct perf_evsel *first)
+/*
+ * The enable_on_exec/disabled value strategy:
+ *
+ * 1) For any type of traced program:
+ * - all independent events and group leaders are disabled
+ * - all group members are enabled
+ *
+ * Group members are ruled by group leaders. They need to
+ * be enabled, because the group scheduling relies on that.
+ *
+ * 2) For traced programs executed by perf:
+ * - all independent events and group leaders have
+ * enable_on_exec set
+ * - we don't specifically enable or disable any event during
+ * the record command
+ *
+ * Independent events and group leaders are initially disabled
+ * and get enabled by exec. Group members are ruled by group
+ * leaders as stated in 1).
+ *
+ * 3) For traced programs attached by perf (pid/tid):
+ * - we specifically enable or disable all events during
+ * the record command
+ *
+ * When attaching events to already running traced we
+ * enable/disable events specifically, as there's no
+ * initial traced exec call.
+ */
+void perf_evsel__config(struct perf_evsel *evsel,
+ struct perf_record_opts *opts)
{
struct perf_event_attr *attr = &evsel->attr;
int track = !evsel->idx; /* only the first counter needs these */
- attr->disabled = 1;
attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1;
attr->inherit = !opts->no_inherit;
attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
@@ -486,10 +513,21 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts,
attr->mmap = track;
attr->comm = track;
- if (perf_target__none(&opts->target) &&
- (!opts->group || evsel == first)) {
+ /*
+ * XXX see the function comment above
+ *
+ * Disabling only independent events or group leaders,
+ * keeping group members enabled.
+ */
+ if (!perf_evsel__is_group_member(evsel))
+ attr->disabled = 1;
+
+ /*
+ * Setting enable_on_exec for independent events and
+ * group leaders for traced executed by perf.
+ */
+ if (perf_target__none(&opts->target) && !perf_evsel__is_group_member(evsel))
attr->enable_on_exec = 1;
- }
}
int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
@@ -669,7 +707,7 @@ static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread)
struct perf_evsel *leader = evsel->leader;
int fd;
- if (!leader)
+ if (!perf_evsel__is_group_member(evsel))
return -1;
/*
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 6f94d6dea00..3d2b8017438 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -3,7 +3,8 @@
#include <linux/list.h>
#include <stdbool.h>
-#include "../../../include/uapi/linux/perf_event.h"
+#include <stddef.h>
+#include <linux/perf_event.h>
#include "types.h"
#include "xyarray.h"
#include "cgroup.h"
@@ -92,8 +93,7 @@ void perf_evsel__exit(struct perf_evsel *evsel);
void perf_evsel__delete(struct perf_evsel *evsel);
void perf_evsel__config(struct perf_evsel *evsel,
- struct perf_record_opts *opts,
- struct perf_evsel *first);
+ struct perf_record_opts *opts);
bool perf_evsel__is_cache_op_valid(u8 type, u8 op);
@@ -225,4 +225,9 @@ static inline struct perf_evsel *perf_evsel__next(struct perf_evsel *evsel)
{
return list_entry(evsel->node.next, struct perf_evsel, node);
}
+
+static inline bool perf_evsel__is_group_member(const struct perf_evsel *evsel)
+{
+ return evsel->leader != NULL;
+}
#endif /* __PERF_EVSEL_H */
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 7daad237dea..b7da4634a04 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -23,6 +23,7 @@
#include "pmu.h"
#include "vdso.h"
#include "strbuf.h"
+#include "build-id.h"
static bool no_buildid_cache = false;
@@ -1378,6 +1379,8 @@ static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused,
str = tmp + 1;
fprintf(fp, "# node%u cpu list : %s\n", c, str);
+
+ str += strlen(str) + 1;
}
return;
error:
@@ -2340,6 +2343,16 @@ static int try_all_pipe_abis(uint64_t hdr_sz, struct perf_header *ph)
return -1;
}
+bool is_perf_magic(u64 magic)
+{
+ if (!memcmp(&magic, __perf_magic1, sizeof(magic))
+ || magic == __perf_magic2
+ || magic == __perf_magic2_sw)
+ return true;
+
+ return false;
+}
+
static int check_magic_endian(u64 magic, uint64_t hdr_sz,
bool is_pipe, struct perf_header *ph)
{
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 879d215cdac..20f0344accb 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -1,7 +1,7 @@
#ifndef __PERF_HEADER_H
#define __PERF_HEADER_H
-#include "../../../include/uapi/linux/perf_event.h"
+#include <linux/perf_event.h>
#include <sys/types.h>
#include <stdbool.h>
#include "types.h"
@@ -154,6 +154,7 @@ int perf_event__synthesize_build_id(struct perf_tool *tool,
int perf_event__process_build_id(struct perf_tool *tool,
union perf_event *event,
struct perf_session *session);
+bool is_perf_magic(u64 magic);
/*
* arch specific callback
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 277947a669b..cb17e2a8c6e 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -244,6 +244,8 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
he->ms.map->referenced = true;
if (symbol_conf.use_callchain)
callchain_init(he->callchain);
+
+ INIT_LIST_HEAD(&he->pairs.node);
}
return he;
@@ -410,6 +412,7 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
void hist_entry__free(struct hist_entry *he)
{
+ free(he->branch_info);
free(he);
}
@@ -713,3 +716,99 @@ void hists__inc_nr_events(struct hists *hists, u32 type)
++hists->stats.nr_events[0];
++hists->stats.nr_events[type];
}
+
+static struct hist_entry *hists__add_dummy_entry(struct hists *hists,
+ struct hist_entry *pair)
+{
+ struct rb_node **p = &hists->entries.rb_node;
+ struct rb_node *parent = NULL;
+ struct hist_entry *he;
+ int cmp;
+
+ while (*p != NULL) {
+ parent = *p;
+ he = rb_entry(parent, struct hist_entry, rb_node);
+
+ cmp = hist_entry__cmp(pair, he);
+
+ if (!cmp)
+ goto out;
+
+ if (cmp < 0)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+
+ he = hist_entry__new(pair);
+ if (he) {
+ memset(&he->stat, 0, sizeof(he->stat));
+ he->hists = hists;
+ rb_link_node(&he->rb_node, parent, p);
+ rb_insert_color(&he->rb_node, &hists->entries);
+ hists__inc_nr_entries(hists, he);
+ }
+out:
+ return he;
+}
+
+static struct hist_entry *hists__find_entry(struct hists *hists,
+ struct hist_entry *he)
+{
+ struct rb_node *n = hists->entries.rb_node;
+
+ while (n) {
+ struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node);
+ int64_t cmp = hist_entry__cmp(he, iter);
+
+ if (cmp < 0)
+ n = n->rb_left;
+ else if (cmp > 0)
+ n = n->rb_right;
+ else
+ return iter;
+ }
+
+ return NULL;
+}
+
+/*
+ * Look for pairs to link to the leader buckets (hist_entries):
+ */
+void hists__match(struct hists *leader, struct hists *other)
+{
+ struct rb_node *nd;
+ struct hist_entry *pos, *pair;
+
+ for (nd = rb_first(&leader->entries); nd; nd = rb_next(nd)) {
+ pos = rb_entry(nd, struct hist_entry, rb_node);
+ pair = hists__find_entry(other, pos);
+
+ if (pair)
+ hist__entry_add_pair(pos, pair);
+ }
+}
+
+/*
+ * Look for entries in the other hists that are not present in the leader, if
+ * we find them, just add a dummy entry on the leader hists, with period=0,
+ * nr_events=0, to serve as the list header.
+ */
+int hists__link(struct hists *leader, struct hists *other)
+{
+ struct rb_node *nd;
+ struct hist_entry *pos, *pair;
+
+ for (nd = rb_first(&other->entries); nd; nd = rb_next(nd)) {
+ pos = rb_entry(nd, struct hist_entry, rb_node);
+
+ if (!hist_entry__has_pairs(pos)) {
+ pair = hists__add_dummy_entry(leader, pos);
+ if (pair == NULL)
+ return -1;
+ hist__entry_add_pair(pair, pos);
+ }
+ }
+
+ return 0;
+}
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 66cb31fe81d..8b091a51e4a 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -4,6 +4,7 @@
#include <linux/types.h>
#include <pthread.h>
#include "callchain.h"
+#include "header.h"
extern struct callchain_param callchain_param;
@@ -114,6 +115,9 @@ bool hists__new_col_len(struct hists *self, 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);
+void hists__match(struct hists *leader, struct hists *other);
+int hists__link(struct hists *leader, struct hists *other);
+
struct perf_hpp {
char *buf;
size_t size;
@@ -140,8 +144,12 @@ enum {
PERF_HPP__OVERHEAD_GUEST_US,
PERF_HPP__SAMPLES,
PERF_HPP__PERIOD,
+ PERF_HPP__PERIOD_BASELINE,
PERF_HPP__DELTA,
+ PERF_HPP__RATIO,
+ PERF_HPP__WEIGHTED_DIFF,
PERF_HPP__DISPL,
+ PERF_HPP__FORMULA,
PERF_HPP__MAX_INDEX
};
@@ -153,21 +161,27 @@ int hist_entry__period_snprintf(struct perf_hpp *hpp, struct hist_entry *he,
struct perf_evlist;
+struct hist_browser_timer {
+ void (*timer)(void *arg);
+ void *arg;
+ int refresh;
+};
+
#ifdef NEWT_SUPPORT
#include "../ui/keysyms.h"
int hist_entry__tui_annotate(struct hist_entry *he, int evidx,
- void(*timer)(void *arg), void *arg, int delay_secs);
+ struct hist_browser_timer *hbt);
int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
- void(*timer)(void *arg), void *arg,
- int refresh);
+ struct hist_browser_timer *hbt,
+ struct perf_session_env *env);
+int script_browse(const char *script_opt);
#else
static inline
int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
const char *help __maybe_unused,
- void(*timer)(void *arg) __maybe_unused,
- void *arg __maybe_unused,
- int refresh __maybe_unused)
+ struct hist_browser_timer *hbt __maybe_unused,
+ struct perf_session_env *env __maybe_unused)
{
return 0;
}
@@ -175,28 +189,29 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
static inline int hist_entry__tui_annotate(struct hist_entry *self
__maybe_unused,
int evidx __maybe_unused,
- void(*timer)(void *arg)
- __maybe_unused,
- void *arg __maybe_unused,
- int delay_secs __maybe_unused)
+ struct hist_browser_timer *hbt
+ __maybe_unused)
{
return 0;
}
+
+static inline int script_browse(const char *script_opt __maybe_unused)
+{
+ return 0;
+}
+
#define K_LEFT -1
#define K_RIGHT -2
#endif
#ifdef GTK2_SUPPORT
int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
- void(*timer)(void *arg), void *arg,
- int refresh);
+ struct hist_browser_timer *hbt __maybe_unused);
#else
static inline
int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused,
const char *help __maybe_unused,
- void(*timer)(void *arg) __maybe_unused,
- void *arg __maybe_unused,
- int refresh __maybe_unused)
+ struct hist_browser_timer *hbt __maybe_unused)
{
return 0;
}
@@ -204,4 +219,8 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused,
unsigned int hists__sort_list_width(struct hists *self);
+double perf_diff__compute_delta(struct hist_entry *he);
+double perf_diff__compute_ratio(struct hist_entry *he);
+s64 perf_diff__compute_wdiff(struct hist_entry *he);
+int perf_diff__formula(char *buf, size_t size, struct hist_entry *he);
#endif /* __PERF_HIST_H */
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
new file mode 100644
index 00000000000..1f09d0581e6
--- /dev/null
+++ b/tools/perf/util/machine.c
@@ -0,0 +1,464 @@
+#include "debug.h"
+#include "event.h"
+#include "machine.h"
+#include "map.h"
+#include "strlist.h"
+#include "thread.h"
+#include <stdbool.h>
+
+int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
+{
+ map_groups__init(&machine->kmaps);
+ RB_CLEAR_NODE(&machine->rb_node);
+ INIT_LIST_HEAD(&machine->user_dsos);
+ INIT_LIST_HEAD(&machine->kernel_dsos);
+
+ machine->threads = RB_ROOT;
+ INIT_LIST_HEAD(&machine->dead_threads);
+ machine->last_match = NULL;
+
+ machine->kmaps.machine = machine;
+ machine->pid = pid;
+
+ machine->root_dir = strdup(root_dir);
+ if (machine->root_dir == NULL)
+ return -ENOMEM;
+
+ if (pid != HOST_KERNEL_ID) {
+ struct thread *thread = machine__findnew_thread(machine, pid);
+ char comm[64];
+
+ if (thread == NULL)
+ return -ENOMEM;
+
+ snprintf(comm, sizeof(comm), "[guest/%d]", pid);
+ thread__set_comm(thread, comm);
+ }
+
+ return 0;
+}
+
+static void dsos__delete(struct list_head *dsos)
+{
+ struct dso *pos, *n;
+
+ list_for_each_entry_safe(pos, n, dsos, node) {
+ list_del(&pos->node);
+ dso__delete(pos);
+ }
+}
+
+void machine__exit(struct machine *machine)
+{
+ map_groups__exit(&machine->kmaps);
+ dsos__delete(&machine->user_dsos);
+ dsos__delete(&machine->kernel_dsos);
+ free(machine->root_dir);
+ machine->root_dir = NULL;
+}
+
+void machine__delete(struct machine *machine)
+{
+ machine__exit(machine);
+ free(machine);
+}
+
+struct machine *machines__add(struct rb_root *machines, pid_t pid,
+ const char *root_dir)
+{
+ struct rb_node **p = &machines->rb_node;
+ struct rb_node *parent = NULL;
+ struct machine *pos, *machine = malloc(sizeof(*machine));
+
+ if (machine == NULL)
+ return NULL;
+
+ if (machine__init(machine, root_dir, pid) != 0) {
+ free(machine);
+ return NULL;
+ }
+
+ while (*p != NULL) {
+ parent = *p;
+ pos = rb_entry(parent, struct machine, rb_node);
+ if (pid < pos->pid)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+
+ rb_link_node(&machine->rb_node, parent, p);
+ rb_insert_color(&machine->rb_node, machines);
+
+ return machine;
+}
+
+struct machine *machines__find(struct rb_root *machines, pid_t pid)
+{
+ struct rb_node **p = &machines->rb_node;
+ struct rb_node *parent = NULL;
+ struct machine *machine;
+ struct machine *default_machine = NULL;
+
+ while (*p != NULL) {
+ parent = *p;
+ machine = rb_entry(parent, struct machine, rb_node);
+ if (pid < machine->pid)
+ p = &(*p)->rb_left;
+ else if (pid > machine->pid)
+ p = &(*p)->rb_right;
+ else
+ return machine;
+ if (!machine->pid)
+ default_machine = machine;
+ }
+
+ return default_machine;
+}
+
+struct machine *machines__findnew(struct rb_root *machines, pid_t pid)
+{
+ char path[PATH_MAX];
+ const char *root_dir = "";
+ struct machine *machine = machines__find(machines, pid);
+
+ if (machine && (machine->pid == pid))
+ goto out;
+
+ if ((pid != HOST_KERNEL_ID) &&
+ (pid != DEFAULT_GUEST_KERNEL_ID) &&
+ (symbol_conf.guestmount)) {
+ sprintf(path, "%s/%d", symbol_conf.guestmount, pid);
+ if (access(path, R_OK)) {
+ static struct strlist *seen;
+
+ if (!seen)
+ seen = strlist__new(true, NULL);
+
+ if (!strlist__has_entry(seen, path)) {
+ pr_err("Can't access file %s\n", path);
+ strlist__add(seen, path);
+ }
+ machine = NULL;
+ goto out;
+ }
+ root_dir = path;
+ }
+
+ machine = machines__add(machines, pid, root_dir);
+out:
+ return machine;
+}
+
+void machines__process(struct rb_root *machines,
+ machine__process_t process, void *data)
+{
+ struct rb_node *nd;
+
+ for (nd = rb_first(machines); nd; nd = rb_next(nd)) {
+ struct machine *pos = rb_entry(nd, struct machine, rb_node);
+ process(pos, data);
+ }
+}
+
+char *machine__mmap_name(struct machine *machine, char *bf, size_t size)
+{
+ if (machine__is_host(machine))
+ snprintf(bf, size, "[%s]", "kernel.kallsyms");
+ else if (machine__is_default_guest(machine))
+ snprintf(bf, size, "[%s]", "guest.kernel.kallsyms");
+ else {
+ snprintf(bf, size, "[%s.%d]", "guest.kernel.kallsyms",
+ machine->pid);
+ }
+
+ return bf;
+}
+
+void machines__set_id_hdr_size(struct rb_root *machines, u16 id_hdr_size)
+{
+ struct rb_node *node;
+ struct machine *machine;
+
+ for (node = rb_first(machines); node; node = rb_next(node)) {
+ machine = rb_entry(node, struct machine, rb_node);
+ machine->id_hdr_size = id_hdr_size;
+ }
+
+ return;
+}
+
+static struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid,
+ bool create)
+{
+ struct rb_node **p = &machine->threads.rb_node;
+ struct rb_node *parent = NULL;
+ struct thread *th;
+
+ /*
+ * Font-end cache - PID lookups come in blocks,
+ * so most of the time we dont have to look up
+ * the full rbtree:
+ */
+ if (machine->last_match && machine->last_match->pid == pid)
+ return machine->last_match;
+
+ while (*p != NULL) {
+ parent = *p;
+ th = rb_entry(parent, struct thread, rb_node);
+
+ if (th->pid == pid) {
+ machine->last_match = th;
+ return th;
+ }
+
+ if (pid < th->pid)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+
+ if (!create)
+ return NULL;
+
+ th = thread__new(pid);
+ if (th != NULL) {
+ rb_link_node(&th->rb_node, parent, p);
+ rb_insert_color(&th->rb_node, &machine->threads);
+ machine->last_match = th;
+ }
+
+ return th;
+}
+
+struct thread *machine__findnew_thread(struct machine *machine, pid_t pid)
+{
+ return __machine__findnew_thread(machine, pid, true);
+}
+
+struct thread *machine__find_thread(struct machine *machine, pid_t pid)
+{
+ return __machine__findnew_thread(machine, pid, false);
+}
+
+int machine__process_comm_event(struct machine *machine, union perf_event *event)
+{
+ struct thread *thread = machine__findnew_thread(machine, event->comm.tid);
+
+ if (dump_trace)
+ perf_event__fprintf_comm(event, stdout);
+
+ if (thread == NULL || thread__set_comm(thread, event->comm.comm)) {
+ dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int machine__process_lost_event(struct machine *machine __maybe_unused,
+ union perf_event *event)
+{
+ dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n",
+ event->lost.id, event->lost.lost);
+ return 0;
+}
+
+static void machine__set_kernel_mmap_len(struct machine *machine,
+ union perf_event *event)
+{
+ int i;
+
+ for (i = 0; i < MAP__NR_TYPES; i++) {
+ machine->vmlinux_maps[i]->start = event->mmap.start;
+ machine->vmlinux_maps[i]->end = (event->mmap.start +
+ event->mmap.len);
+ /*
+ * Be a bit paranoid here, some perf.data file came with
+ * a zero sized synthesized MMAP event for the kernel.
+ */
+ if (machine->vmlinux_maps[i]->end == 0)
+ machine->vmlinux_maps[i]->end = ~0ULL;
+ }
+}
+
+static int machine__process_kernel_mmap_event(struct machine *machine,
+ union perf_event *event)
+{
+ struct map *map;
+ char kmmap_prefix[PATH_MAX];
+ enum dso_kernel_type kernel_type;
+ bool is_kernel_mmap;
+
+ machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix));
+ if (machine__is_host(machine))
+ kernel_type = DSO_TYPE_KERNEL;
+ else
+ kernel_type = DSO_TYPE_GUEST_KERNEL;
+
+ is_kernel_mmap = memcmp(event->mmap.filename,
+ kmmap_prefix,
+ strlen(kmmap_prefix) - 1) == 0;
+ if (event->mmap.filename[0] == '/' ||
+ (!is_kernel_mmap && event->mmap.filename[0] == '[')) {
+
+ char short_module_name[1024];
+ char *name, *dot;
+
+ if (event->mmap.filename[0] == '/') {
+ name = strrchr(event->mmap.filename, '/');
+ if (name == NULL)
+ goto out_problem;
+
+ ++name; /* skip / */
+ dot = strrchr(name, '.');
+ if (dot == NULL)
+ goto out_problem;
+ snprintf(short_module_name, sizeof(short_module_name),
+ "[%.*s]", (int)(dot - name), name);
+ strxfrchar(short_module_name, '-', '_');
+ } else
+ strcpy(short_module_name, event->mmap.filename);
+
+ map = machine__new_module(machine, event->mmap.start,
+ event->mmap.filename);
+ if (map == NULL)
+ goto out_problem;
+
+ name = strdup(short_module_name);
+ if (name == NULL)
+ goto out_problem;
+
+ map->dso->short_name = name;
+ map->dso->sname_alloc = 1;
+ map->end = map->start + event->mmap.len;
+ } else if (is_kernel_mmap) {
+ const char *symbol_name = (event->mmap.filename +
+ strlen(kmmap_prefix));
+ /*
+ * Should be there already, from the build-id table in
+ * the header.
+ */
+ struct dso *kernel = __dsos__findnew(&machine->kernel_dsos,
+ kmmap_prefix);
+ if (kernel == NULL)
+ goto out_problem;
+
+ kernel->kernel = kernel_type;
+ if (__machine__create_kernel_maps(machine, kernel) < 0)
+ goto out_problem;
+
+ machine__set_kernel_mmap_len(machine, event);
+
+ /*
+ * Avoid using a zero address (kptr_restrict) for the ref reloc
+ * symbol. Effectively having zero here means that at record
+ * time /proc/sys/kernel/kptr_restrict was non zero.
+ */
+ if (event->mmap.pgoff != 0) {
+ maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps,
+ symbol_name,
+ event->mmap.pgoff);
+ }
+
+ if (machine__is_default_guest(machine)) {
+ /*
+ * preload dso of guest kernel and modules
+ */
+ dso__load(kernel, machine->vmlinux_maps[MAP__FUNCTION],
+ NULL);
+ }
+ }
+ return 0;
+out_problem:
+ return -1;
+}
+
+int machine__process_mmap_event(struct machine *machine, union perf_event *event)
+{
+ u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+ struct thread *thread;
+ struct map *map;
+ int ret = 0;
+
+ if (dump_trace)
+ perf_event__fprintf_mmap(event, stdout);
+
+ if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
+ cpumode == PERF_RECORD_MISC_KERNEL) {
+ ret = machine__process_kernel_mmap_event(machine, event);
+ if (ret < 0)
+ goto out_problem;
+ return 0;
+ }
+
+ thread = machine__findnew_thread(machine, event->mmap.pid);
+ if (thread == NULL)
+ goto out_problem;
+ map = map__new(&machine->user_dsos, event->mmap.start,
+ event->mmap.len, event->mmap.pgoff,
+ event->mmap.pid, event->mmap.filename,
+ MAP__FUNCTION);
+ if (map == NULL)
+ goto out_problem;
+
+ thread__insert_map(thread, map);
+ return 0;
+
+out_problem:
+ dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
+ return 0;
+}
+
+int machine__process_fork_event(struct machine *machine, union perf_event *event)
+{
+ struct thread *thread = machine__findnew_thread(machine, event->fork.tid);
+ struct thread *parent = machine__findnew_thread(machine, event->fork.ptid);
+
+ if (dump_trace)
+ perf_event__fprintf_task(event, stdout);
+
+ if (thread == NULL || parent == NULL ||
+ thread__fork(thread, parent) < 0) {
+ dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int machine__process_exit_event(struct machine *machine, union perf_event *event)
+{
+ struct thread *thread = machine__find_thread(machine, event->fork.tid);
+
+ if (dump_trace)
+ perf_event__fprintf_task(event, stdout);
+
+ if (thread != NULL)
+ machine__remove_thread(machine, thread);
+
+ return 0;
+}
+
+int machine__process_event(struct machine *machine, union perf_event *event)
+{
+ int ret;
+
+ switch (event->header.type) {
+ case PERF_RECORD_COMM:
+ ret = machine__process_comm_event(machine, event); break;
+ case PERF_RECORD_MMAP:
+ ret = machine__process_mmap_event(machine, event); break;
+ case PERF_RECORD_FORK:
+ ret = machine__process_fork_event(machine, event); break;
+ case PERF_RECORD_EXIT:
+ ret = machine__process_exit_event(machine, event); break;
+ case PERF_RECORD_LOST:
+ ret = machine__process_lost_event(machine, event); break;
+ default:
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
new file mode 100644
index 00000000000..b7cde7467d5
--- /dev/null
+++ b/tools/perf/util/machine.h
@@ -0,0 +1,148 @@
+#ifndef __PERF_MACHINE_H
+#define __PERF_MACHINE_H
+
+#include <sys/types.h>
+#include <linux/rbtree.h>
+#include "map.h"
+
+struct branch_stack;
+struct perf_evsel;
+struct perf_sample;
+struct symbol;
+struct thread;
+union perf_event;
+
+/* Native host kernel uses -1 as pid index in machine */
+#define HOST_KERNEL_ID (-1)
+#define DEFAULT_GUEST_KERNEL_ID (0)
+
+struct machine {
+ struct rb_node rb_node;
+ pid_t pid;
+ u16 id_hdr_size;
+ char *root_dir;
+ struct rb_root threads;
+ struct list_head dead_threads;
+ struct thread *last_match;
+ struct list_head user_dsos;
+ struct list_head kernel_dsos;
+ struct map_groups kmaps;
+ struct map *vmlinux_maps[MAP__NR_TYPES];
+};
+
+static inline
+struct map *machine__kernel_map(struct machine *machine, enum map_type type)
+{
+ return machine->vmlinux_maps[type];
+}
+
+struct thread *machine__find_thread(struct machine *machine, pid_t pid);
+
+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_event(struct machine *machine, union perf_event *event);
+
+typedef void (*machine__process_t)(struct machine *machine, void *data);
+
+void machines__process(struct rb_root *machines,
+ machine__process_t process, void *data);
+
+struct machine *machines__add(struct rb_root *machines, pid_t pid,
+ const char *root_dir);
+struct machine *machines__find_host(struct rb_root *machines);
+struct machine *machines__find(struct rb_root *machines, pid_t pid);
+struct machine *machines__findnew(struct rb_root *machines, pid_t pid);
+
+void machines__set_id_hdr_size(struct rb_root *machines, u16 id_hdr_size);
+char *machine__mmap_name(struct machine *machine, char *bf, size_t size);
+
+int machine__init(struct machine *machine, const char *root_dir, pid_t pid);
+void machine__exit(struct machine *machine);
+void machine__delete(struct machine *machine);
+
+
+struct branch_info *machine__resolve_bstack(struct machine *machine,
+ struct thread *thread,
+ struct branch_stack *bs);
+int machine__resolve_callchain(struct machine *machine,
+ struct perf_evsel *evsel,
+ struct thread *thread,
+ struct perf_sample *sample,
+ struct symbol **parent);
+
+/*
+ * Default guest kernel is defined by parameter --guestkallsyms
+ * and --guestmodules
+ */
+static inline bool machine__is_default_guest(struct machine *machine)
+{
+ return machine ? machine->pid == DEFAULT_GUEST_KERNEL_ID : false;
+}
+
+static inline bool machine__is_host(struct machine *machine)
+{
+ return machine ? machine->pid == HOST_KERNEL_ID : false;
+}
+
+struct thread *machine__findnew_thread(struct machine *machine, pid_t pid);
+void machine__remove_thread(struct machine *machine, struct thread *th);
+
+size_t machine__fprintf(struct machine *machine, FILE *fp);
+
+static inline
+struct symbol *machine__find_kernel_symbol(struct machine *machine,
+ enum map_type type, u64 addr,
+ struct map **mapp,
+ symbol_filter_t filter)
+{
+ return map_groups__find_symbol(&machine->kmaps, type, addr,
+ mapp, filter);
+}
+
+static inline
+struct symbol *machine__find_kernel_function(struct machine *machine, u64 addr,
+ struct map **mapp,
+ symbol_filter_t filter)
+{
+ return machine__find_kernel_symbol(machine, MAP__FUNCTION, addr,
+ mapp, filter);
+}
+
+static inline
+struct symbol *machine__find_kernel_function_by_name(struct machine *machine,
+ const char *name,
+ struct map **mapp,
+ symbol_filter_t filter)
+{
+ return map_groups__find_function_by_name(&machine->kmaps, name, mapp,
+ filter);
+}
+
+struct map *machine__new_module(struct machine *machine, u64 start,
+ const char *filename);
+
+int machine__load_kallsyms(struct machine *machine, const char *filename,
+ enum map_type type, symbol_filter_t filter);
+int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
+ symbol_filter_t filter);
+
+size_t machine__fprintf_dsos_buildid(struct machine *machine,
+ FILE *fp, bool with_hits);
+size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp);
+size_t machines__fprintf_dsos_buildid(struct rb_root *machines,
+ FILE *fp, bool with_hits);
+
+void machine__destroy_kernel_maps(struct machine *machine);
+int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel);
+int machine__create_kernel_maps(struct machine *machine);
+
+int machines__create_kernel_maps(struct rb_root *machines, pid_t pid);
+int machines__create_guest_kernel_maps(struct rb_root *machines);
+void machines__destroy_guest_kernel_maps(struct rb_root *machines);
+
+size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp);
+
+#endif /* __PERF_MACHINE_H */
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 6109fa4d14c..0328d45c4f2 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -10,6 +10,7 @@
#include "thread.h"
#include "strlist.h"
#include "vdso.h"
+#include "build-id.h"
const char *map_type__name[MAP__NR_TYPES] = {
[MAP__FUNCTION] = "Functions",
@@ -23,7 +24,7 @@ static inline int is_anon_memory(const char *filename)
static inline int is_no_dso_memory(const char *filename)
{
- return !strcmp(filename, "[stack]") ||
+ return !strncmp(filename, "[stack", 6) ||
!strcmp(filename, "[heap]");
}
@@ -589,182 +590,3 @@ struct map *maps__find(struct rb_root *maps, u64 ip)
return NULL;
}
-
-int machine__init(struct machine *self, const char *root_dir, pid_t pid)
-{
- map_groups__init(&self->kmaps);
- RB_CLEAR_NODE(&self->rb_node);
- INIT_LIST_HEAD(&self->user_dsos);
- INIT_LIST_HEAD(&self->kernel_dsos);
-
- self->threads = RB_ROOT;
- INIT_LIST_HEAD(&self->dead_threads);
- self->last_match = NULL;
-
- self->kmaps.machine = self;
- self->pid = pid;
- self->root_dir = strdup(root_dir);
- if (self->root_dir == NULL)
- return -ENOMEM;
-
- if (pid != HOST_KERNEL_ID) {
- struct thread *thread = machine__findnew_thread(self, pid);
- char comm[64];
-
- if (thread == NULL)
- return -ENOMEM;
-
- snprintf(comm, sizeof(comm), "[guest/%d]", pid);
- thread__set_comm(thread, comm);
- }
-
- return 0;
-}
-
-static void dsos__delete(struct list_head *self)
-{
- struct dso *pos, *n;
-
- list_for_each_entry_safe(pos, n, self, node) {
- list_del(&pos->node);
- dso__delete(pos);
- }
-}
-
-void machine__exit(struct machine *self)
-{
- map_groups__exit(&self->kmaps);
- dsos__delete(&self->user_dsos);
- dsos__delete(&self->kernel_dsos);
- free(self->root_dir);
- self->root_dir = NULL;
-}
-
-void machine__delete(struct machine *self)
-{
- machine__exit(self);
- free(self);
-}
-
-struct machine *machines__add(struct rb_root *self, pid_t pid,
- const char *root_dir)
-{
- struct rb_node **p = &self->rb_node;
- struct rb_node *parent = NULL;
- struct machine *pos, *machine = malloc(sizeof(*machine));
-
- if (!machine)
- return NULL;
-
- if (machine__init(machine, root_dir, pid) != 0) {
- free(machine);
- return NULL;
- }
-
- while (*p != NULL) {
- parent = *p;
- pos = rb_entry(parent, struct machine, rb_node);
- if (pid < pos->pid)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
-
- rb_link_node(&machine->rb_node, parent, p);
- rb_insert_color(&machine->rb_node, self);
-
- return machine;
-}
-
-struct machine *machines__find(struct rb_root *self, pid_t pid)
-{
- struct rb_node **p = &self->rb_node;
- struct rb_node *parent = NULL;
- struct machine *machine;
- struct machine *default_machine = NULL;
-
- while (*p != NULL) {
- parent = *p;
- machine = rb_entry(parent, struct machine, rb_node);
- if (pid < machine->pid)
- p = &(*p)->rb_left;
- else if (pid > machine->pid)
- p = &(*p)->rb_right;
- else
- return machine;
- if (!machine->pid)
- default_machine = machine;
- }
-
- return default_machine;
-}
-
-struct machine *machines__findnew(struct rb_root *self, pid_t pid)
-{
- char path[PATH_MAX];
- const char *root_dir = "";
- struct machine *machine = machines__find(self, pid);
-
- if (machine && (machine->pid == pid))
- goto out;
-
- if ((pid != HOST_KERNEL_ID) &&
- (pid != DEFAULT_GUEST_KERNEL_ID) &&
- (symbol_conf.guestmount)) {
- sprintf(path, "%s/%d", symbol_conf.guestmount, pid);
- if (access(path, R_OK)) {
- static struct strlist *seen;
-
- if (!seen)
- seen = strlist__new(true, NULL);
-
- if (!strlist__has_entry(seen, path)) {
- pr_err("Can't access file %s\n", path);
- strlist__add(seen, path);
- }
- machine = NULL;
- goto out;
- }
- root_dir = path;
- }
-
- machine = machines__add(self, pid, root_dir);
-
-out:
- return machine;
-}
-
-void machines__process(struct rb_root *self, machine__process_t process, void *data)
-{
- struct rb_node *nd;
-
- for (nd = rb_first(self); nd; nd = rb_next(nd)) {
- struct machine *pos = rb_entry(nd, struct machine, rb_node);
- process(pos, data);
- }
-}
-
-char *machine__mmap_name(struct machine *self, char *bf, size_t size)
-{
- if (machine__is_host(self))
- snprintf(bf, size, "[%s]", "kernel.kallsyms");
- else if (machine__is_default_guest(self))
- snprintf(bf, size, "[%s]", "guest.kernel.kallsyms");
- else
- snprintf(bf, size, "[%s.%d]", "guest.kernel.kallsyms", self->pid);
-
- return bf;
-}
-
-void machines__set_id_hdr_size(struct rb_root *machines, u16 id_hdr_size)
-{
- struct rb_node *node;
- struct machine *machine;
-
- for (node = rb_first(machines); node; node = rb_next(node)) {
- machine = rb_entry(node, struct machine, rb_node);
- machine->id_hdr_size = id_hdr_size;
- }
-
- return;
-}
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index d2250fc97e2..bcb39e2a696 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -57,30 +57,6 @@ struct map_groups {
struct machine *machine;
};
-/* Native host kernel uses -1 as pid index in machine */
-#define HOST_KERNEL_ID (-1)
-#define DEFAULT_GUEST_KERNEL_ID (0)
-
-struct machine {
- struct rb_node rb_node;
- pid_t pid;
- u16 id_hdr_size;
- char *root_dir;
- struct rb_root threads;
- struct list_head dead_threads;
- struct thread *last_match;
- struct list_head user_dsos;
- struct list_head kernel_dsos;
- struct map_groups kmaps;
- struct map *vmlinux_maps[MAP__NR_TYPES];
-};
-
-static inline
-struct map *machine__kernel_map(struct machine *self, enum map_type type)
-{
- return self->vmlinux_maps[type];
-}
-
static inline struct kmap *map__kmap(struct map *self)
{
return (struct kmap *)(self + 1);
@@ -143,44 +119,9 @@ int map_groups__clone(struct map_groups *mg,
size_t map_groups__fprintf(struct map_groups *mg, int verbose, FILE *fp);
size_t map_groups__fprintf_maps(struct map_groups *mg, int verbose, FILE *fp);
-typedef void (*machine__process_t)(struct machine *self, void *data);
-
-void machines__process(struct rb_root *self, machine__process_t process, void *data);
-struct machine *machines__add(struct rb_root *self, pid_t pid,
- const char *root_dir);
-struct machine *machines__find_host(struct rb_root *self);
-struct machine *machines__find(struct rb_root *self, pid_t pid);
-struct machine *machines__findnew(struct rb_root *self, pid_t pid);
-void machines__set_id_hdr_size(struct rb_root *self, u16 id_hdr_size);
-char *machine__mmap_name(struct machine *self, char *bf, size_t size);
-int machine__init(struct machine *self, const char *root_dir, pid_t pid);
-void machine__exit(struct machine *self);
-void machine__delete(struct machine *self);
-
-struct perf_evsel;
-struct perf_sample;
-int machine__resolve_callchain(struct machine *machine,
- struct perf_evsel *evsel,
- struct thread *thread,
- struct perf_sample *sample,
- struct symbol **parent);
int maps__set_kallsyms_ref_reloc_sym(struct map **maps, const char *symbol_name,
u64 addr);
-/*
- * Default guest kernel is defined by parameter --guestkallsyms
- * and --guestmodules
- */
-static inline bool machine__is_default_guest(struct machine *self)
-{
- return self ? self->pid == DEFAULT_GUEST_KERNEL_ID : false;
-}
-
-static inline bool machine__is_host(struct machine *self)
-{
- return self ? self->pid == HOST_KERNEL_ID : false;
-}
-
static inline void map_groups__insert(struct map_groups *mg, struct map *map)
{
maps__insert(&mg->maps[map->type], map);
@@ -209,29 +150,6 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
struct map **mapp,
symbol_filter_t filter);
-
-struct thread *machine__findnew_thread(struct machine *machine, pid_t pid);
-void machine__remove_thread(struct machine *machine, struct thread *th);
-
-size_t machine__fprintf(struct machine *machine, FILE *fp);
-
-static inline
-struct symbol *machine__find_kernel_symbol(struct machine *self,
- enum map_type type, u64 addr,
- struct map **mapp,
- symbol_filter_t filter)
-{
- return map_groups__find_symbol(&self->kmaps, type, addr, mapp, filter);
-}
-
-static inline
-struct symbol *machine__find_kernel_function(struct machine *self, u64 addr,
- struct map **mapp,
- symbol_filter_t filter)
-{
- return machine__find_kernel_symbol(self, MAP__FUNCTION, addr, mapp, filter);
-}
-
static inline
struct symbol *map_groups__find_function_by_name(struct map_groups *mg,
const char *name, struct map **mapp,
@@ -240,22 +158,11 @@ struct symbol *map_groups__find_function_by_name(struct map_groups *mg,
return map_groups__find_symbol_by_name(mg, MAP__FUNCTION, name, mapp, filter);
}
-static inline
-struct symbol *machine__find_kernel_function_by_name(struct machine *self,
- const char *name,
- struct map **mapp,
- symbol_filter_t filter)
-{
- return map_groups__find_function_by_name(&self->kmaps, name, mapp,
- filter);
-}
-
int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
int verbose, FILE *fp);
struct map *map_groups__find_by_name(struct map_groups *mg,
enum map_type type, const char *name);
-struct map *machine__new_module(struct machine *self, u64 start, const char *filename);
void map_groups__flush(struct map_groups *mg);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 75c7b0fca6d..2d8d53bec17 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1,4 +1,4 @@
-#include "../../../include/linux/hw_breakpoint.h"
+#include <linux/hw_breakpoint.h>
#include "util.h"
#include "../perf.h"
#include "evlist.h"
@@ -722,6 +722,27 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
return 0;
}
+/*
+ * Basic modifier sanity check to validate it contains only one
+ * instance of any modifier (apart from 'p') present.
+ */
+static int check_modifier(char *str)
+{
+ char *p = str;
+
+ /* The sizeof includes 0 byte as well. */
+ if (strlen(str) > (sizeof("ukhGHppp") - 1))
+ return -1;
+
+ while (*p) {
+ if (*p != 'p' && strchr(p + 1, *p))
+ return -1;
+ p++;
+ }
+
+ return 0;
+}
+
int parse_events__modifier_event(struct list_head *list, char *str, bool add)
{
struct perf_evsel *evsel;
@@ -730,6 +751,9 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
if (str == NULL)
return 0;
+ if (check_modifier(str))
+ return -EINVAL;
+
if (!add && get_event_modifier(&mod, str, NULL))
return -EINVAL;
@@ -827,8 +851,6 @@ int parse_events(struct perf_evlist *evlist, const char *str,
* Both call perf_evlist__delete in case of error, so we dont
* need to bother.
*/
- fprintf(stderr, "invalid or unsupported event: '%s'\n", str);
- fprintf(stderr, "Run 'perf list' for a list of valid events\n");
return ret;
}
@@ -836,7 +858,13 @@ int parse_events_option(const struct option *opt, const char *str,
int unset __maybe_unused)
{
struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
- return parse_events(evlist, str, unset);
+ int ret = parse_events(evlist, str, unset);
+
+ if (ret) {
+ fprintf(stderr, "invalid or unsupported event: '%s'\n", str);
+ fprintf(stderr, "Run 'perf list' for a list of valid events\n");
+ }
+ return ret;
}
int parse_filter(const struct option *opt, const char *str,
@@ -1081,7 +1109,7 @@ void print_events(const char *event_glob, bool name_only)
printf(" %-50s [%s]\n",
"cpu/t1=v1[,t2=v2,t3 ...]/modifier",
event_type_descriptors[PERF_TYPE_RAW]);
- printf(" (see 'perf list --help' on how to encode it)\n");
+ printf(" (see 'man perf-list' on how to encode it)\n");
printf("\n");
printf(" %-50s [%s]\n",
@@ -1142,6 +1170,24 @@ int parse_events__term_str(struct parse_events__term **term,
config, str, 0);
}
+int parse_events__term_sym_hw(struct parse_events__term **term,
+ char *config, unsigned idx)
+{
+ struct event_symbol *sym;
+
+ BUG_ON(idx >= PERF_COUNT_HW_MAX);
+ sym = &event_symbols_hw[idx];
+
+ if (config)
+ return new_term(term, PARSE_EVENTS__TERM_TYPE_STR,
+ PARSE_EVENTS__TERM_TYPE_USER, config,
+ (char *) sym->symbol, 0);
+ else
+ return new_term(term, PARSE_EVENTS__TERM_TYPE_STR,
+ PARSE_EVENTS__TERM_TYPE_USER,
+ (char *) "event", (char *) sym->symbol, 0);
+}
+
int parse_events__term_clone(struct parse_events__term **new,
struct parse_events__term *term)
{
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 839230ceb18..b7af80b8bdd 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -7,7 +7,7 @@
#include <linux/list.h>
#include <stdbool.h>
#include "types.h"
-#include "../../../include/uapi/linux/perf_event.h"
+#include <linux/perf_event.h>
#include "types.h"
struct list_head;
@@ -76,6 +76,8 @@ int parse_events__term_num(struct parse_events__term **_term,
int type_term, char *config, u64 num);
int parse_events__term_str(struct parse_events__term **_term,
int type_term, char *config, char *str);
+int parse_events__term_sym_hw(struct parse_events__term **term,
+ char *config, unsigned idx);
int parse_events__term_clone(struct parse_events__term **new,
struct parse_events__term *term);
void parse_events__free_terms(struct list_head *terms);
@@ -97,7 +99,6 @@ void parse_events__set_leader(char *name, struct list_head *list);
void parse_events_update_lists(struct list_head *list_event,
struct list_head *list_all);
void parse_events_error(void *data, void *scanner, char const *msg);
-int parse_events__test(void);
void print_events(const char *event_glob, bool name_only);
void print_events_type(u8 type);
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index c87efc12579..e9d1134c2c6 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -81,7 +81,8 @@ num_dec [0-9]+
num_hex 0x[a-fA-F0-9]+
num_raw_hex [a-fA-F0-9]+
name [a-zA-Z_*?][a-zA-Z0-9_*?]*
-modifier_event [ukhpGH]{1,8}
+name_minus [a-zA-Z_*?][a-zA-Z0-9\-_*?]*
+modifier_event [ukhpGH]+
modifier_bp [rwx]{1,3}
%%
@@ -168,6 +169,7 @@ 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; }
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index cd88209e3c5..0f9914ae6ba 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -352,6 +352,15 @@ PE_NAME '=' PE_VALUE
$$ = term;
}
|
+PE_NAME '=' PE_VALUE_SYM_HW
+{
+ struct parse_events__term *term;
+ int config = $3 & 255;
+
+ ABORT_ON(parse_events__term_sym_hw(&term, $1, config));
+ $$ = term;
+}
+|
PE_NAME
{
struct parse_events__term *term;
@@ -361,6 +370,15 @@ PE_NAME
$$ = term;
}
|
+PE_VALUE_SYM_HW
+{
+ struct parse_events__term *term;
+ int config = $1 & 255;
+
+ ABORT_ON(parse_events__term_sym_hw(&term, NULL, config));
+ $$ = term;
+}
+|
PE_TERM '=' PE_NAME
{
struct parse_events__term *term;
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 8a2229da594..9bdc60c6f13 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -22,7 +22,7 @@ static LIST_HEAD(pmus);
* Parse & process all the sysfs attributes located under
* the directory specified in 'dir' parameter.
*/
-static int pmu_format_parse(char *dir, struct list_head *head)
+int perf_pmu__format_parse(char *dir, struct list_head *head)
{
struct dirent *evt_ent;
DIR *format_dir;
@@ -77,7 +77,7 @@ static int pmu_format(char *name, struct list_head *format)
if (stat(path, &st) < 0)
return 0; /* no error if format does not exist */
- if (pmu_format_parse(path, format))
+ if (perf_pmu__format_parse(path, format))
return -1;
return 0;
@@ -164,7 +164,7 @@ static int pmu_aliases(char *name, struct list_head *head)
"%s/bus/event_source/devices/%s/events", sysfs, name);
if (stat(path, &st) < 0)
- return -1;
+ return 0; /* no error if 'events' does not exist */
if (pmu_aliases_parse(path, head))
return -1;
@@ -296,6 +296,9 @@ static struct perf_pmu *pmu_lookup(char *name)
if (pmu_format(name, &format))
return NULL;
+ if (pmu_aliases(name, &aliases))
+ return NULL;
+
if (pmu_type(name, &type))
return NULL;
@@ -305,8 +308,6 @@ static struct perf_pmu *pmu_lookup(char *name)
pmu->cpus = pmu_cpumask(name);
- pmu_aliases(name, &aliases);
-
INIT_LIST_HEAD(&pmu->format);
INIT_LIST_HEAD(&pmu->aliases);
list_splice(&format, &pmu->format);
@@ -445,8 +446,9 @@ static int pmu_config_term(struct list_head *formats,
return 0;
}
-static int pmu_config(struct list_head *formats, struct perf_event_attr *attr,
- struct list_head *head_terms)
+int perf_pmu__config_terms(struct list_head *formats,
+ struct perf_event_attr *attr,
+ struct list_head *head_terms)
{
struct parse_events__term *term;
@@ -466,7 +468,7 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
struct list_head *head_terms)
{
attr->type = pmu->type;
- return pmu_config(&pmu->format, attr, head_terms);
+ return perf_pmu__config_terms(&pmu->format, attr, head_terms);
}
static struct perf_pmu__alias *pmu_find_alias(struct perf_pmu *pmu,
@@ -550,177 +552,3 @@ void perf_pmu__set_format(unsigned long *bits, long from, long to)
for (b = from; b <= to; b++)
set_bit(b, bits);
}
-
-/* Simulated format definitions. */
-static struct test_format {
- const char *name;
- const char *value;
-} test_formats[] = {
- { "krava01", "config:0-1,62-63\n", },
- { "krava02", "config:10-17\n", },
- { "krava03", "config:5\n", },
- { "krava11", "config1:0,2,4,6,8,20-28\n", },
- { "krava12", "config1:63\n", },
- { "krava13", "config1:45-47\n", },
- { "krava21", "config2:0-3,10-13,20-23,30-33,40-43,50-53,60-63\n", },
- { "krava22", "config2:8,18,48,58\n", },
- { "krava23", "config2:28-29,38\n", },
-};
-
-#define TEST_FORMATS_CNT (sizeof(test_formats) / sizeof(struct test_format))
-
-/* Simulated users input. */
-static struct parse_events__term test_terms[] = {
- {
- .config = (char *) "krava01",
- .val.num = 15,
- .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
- .type_term = PARSE_EVENTS__TERM_TYPE_USER,
- },
- {
- .config = (char *) "krava02",
- .val.num = 170,
- .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
- .type_term = PARSE_EVENTS__TERM_TYPE_USER,
- },
- {
- .config = (char *) "krava03",
- .val.num = 1,
- .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
- .type_term = PARSE_EVENTS__TERM_TYPE_USER,
- },
- {
- .config = (char *) "krava11",
- .val.num = 27,
- .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
- .type_term = PARSE_EVENTS__TERM_TYPE_USER,
- },
- {
- .config = (char *) "krava12",
- .val.num = 1,
- .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
- .type_term = PARSE_EVENTS__TERM_TYPE_USER,
- },
- {
- .config = (char *) "krava13",
- .val.num = 2,
- .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
- .type_term = PARSE_EVENTS__TERM_TYPE_USER,
- },
- {
- .config = (char *) "krava21",
- .val.num = 119,
- .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
- .type_term = PARSE_EVENTS__TERM_TYPE_USER,
- },
- {
- .config = (char *) "krava22",
- .val.num = 11,
- .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
- .type_term = PARSE_EVENTS__TERM_TYPE_USER,
- },
- {
- .config = (char *) "krava23",
- .val.num = 2,
- .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
- .type_term = PARSE_EVENTS__TERM_TYPE_USER,
- },
-};
-#define TERMS_CNT (sizeof(test_terms) / sizeof(struct parse_events__term))
-
-/*
- * Prepare format directory data, exported by kernel
- * at /sys/bus/event_source/devices/<dev>/format.
- */
-static char *test_format_dir_get(void)
-{
- static char dir[PATH_MAX];
- unsigned int i;
-
- snprintf(dir, PATH_MAX, "/tmp/perf-pmu-test-format-XXXXXX");
- if (!mkdtemp(dir))
- return NULL;
-
- for (i = 0; i < TEST_FORMATS_CNT; i++) {
- static char name[PATH_MAX];
- struct test_format *format = &test_formats[i];
- FILE *file;
-
- snprintf(name, PATH_MAX, "%s/%s", dir, format->name);
-
- file = fopen(name, "w");
- if (!file)
- return NULL;
-
- if (1 != fwrite(format->value, strlen(format->value), 1, file))
- break;
-
- fclose(file);
- }
-
- return dir;
-}
-
-/* Cleanup format directory. */
-static int test_format_dir_put(char *dir)
-{
- char buf[PATH_MAX];
- snprintf(buf, PATH_MAX, "rm -f %s/*\n", dir);
- if (system(buf))
- return -1;
-
- snprintf(buf, PATH_MAX, "rmdir %s\n", dir);
- return system(buf);
-}
-
-static struct list_head *test_terms_list(void)
-{
- static LIST_HEAD(terms);
- unsigned int i;
-
- for (i = 0; i < TERMS_CNT; i++)
- list_add_tail(&test_terms[i].list, &terms);
-
- return &terms;
-}
-
-#undef TERMS_CNT
-
-int perf_pmu__test(void)
-{
- char *format = test_format_dir_get();
- LIST_HEAD(formats);
- struct list_head *terms = test_terms_list();
- int ret;
-
- if (!format)
- return -EINVAL;
-
- do {
- struct perf_event_attr attr;
-
- memset(&attr, 0, sizeof(attr));
-
- ret = pmu_format_parse(format, &formats);
- if (ret)
- break;
-
- ret = pmu_config(&formats, &attr, terms);
- if (ret)
- break;
-
- ret = -EINVAL;
-
- if (attr.config != 0xc00000000002a823)
- break;
- if (attr.config1 != 0x8000400000000145)
- break;
- if (attr.config2 != 0x0400000020041d07)
- break;
-
- ret = 0;
- } while (0);
-
- test_format_dir_put(format);
- return ret;
-}
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 39f3abac774..a313ed76a49 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -2,7 +2,7 @@
#define __PMU_H
#include <linux/bitops.h>
-#include "../../../include/uapi/linux/perf_event.h"
+#include <linux/perf_event.h>
enum {
PERF_PMU_FORMAT_VALUE_CONFIG,
@@ -37,6 +37,9 @@ struct perf_pmu {
struct perf_pmu *perf_pmu__find(char *name);
int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
struct list_head *head_terms);
+int perf_pmu__config_terms(struct list_head *formats,
+ struct perf_event_attr *attr,
+ struct list_head *head_terms);
int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms);
struct list_head *perf_pmu__alias(struct perf_pmu *pmu,
struct list_head *head_terms);
@@ -46,6 +49,7 @@ void perf_pmu_error(struct list_head *list, char *name, char const *msg);
int perf_pmu__new_format(struct list_head *list, char *name,
int config, unsigned long *bits);
void perf_pmu__set_format(unsigned long *bits, long from, long to);
+int perf_pmu__format_parse(char *dir, struct list_head *head);
struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu);
diff --git a/tools/perf/util/pstack.c b/tools/perf/util/pstack.c
index 13d36faf64e..daa17aeb6c6 100644
--- a/tools/perf/util/pstack.c
+++ b/tools/perf/util/pstack.c
@@ -17,59 +17,59 @@ struct pstack {
struct pstack *pstack__new(unsigned short max_nr_entries)
{
- struct pstack *self = zalloc((sizeof(*self) +
- max_nr_entries * sizeof(void *)));
- if (self != NULL)
- self->max_nr_entries = max_nr_entries;
- return self;
+ struct pstack *pstack = zalloc((sizeof(*pstack) +
+ max_nr_entries * sizeof(void *)));
+ if (pstack != NULL)
+ pstack->max_nr_entries = max_nr_entries;
+ return pstack;
}
-void pstack__delete(struct pstack *self)
+void pstack__delete(struct pstack *pstack)
{
- free(self);
+ free(pstack);
}
-bool pstack__empty(const struct pstack *self)
+bool pstack__empty(const struct pstack *pstack)
{
- return self->top == 0;
+ return pstack->top == 0;
}
-void pstack__remove(struct pstack *self, void *key)
+void pstack__remove(struct pstack *pstack, void *key)
{
- unsigned short i = self->top, last_index = self->top - 1;
+ unsigned short i = pstack->top, last_index = pstack->top - 1;
while (i-- != 0) {
- if (self->entries[i] == key) {
+ if (pstack->entries[i] == key) {
if (i < last_index)
- memmove(self->entries + i,
- self->entries + i + 1,
+ memmove(pstack->entries + i,
+ pstack->entries + i + 1,
(last_index - i) * sizeof(void *));
- --self->top;
+ --pstack->top;
return;
}
}
pr_err("%s: %p not on the pstack!\n", __func__, key);
}
-void pstack__push(struct pstack *self, void *key)
+void pstack__push(struct pstack *pstack, void *key)
{
- if (self->top == self->max_nr_entries) {
- pr_err("%s: top=%d, overflow!\n", __func__, self->top);
+ if (pstack->top == pstack->max_nr_entries) {
+ pr_err("%s: top=%d, overflow!\n", __func__, pstack->top);
return;
}
- self->entries[self->top++] = key;
+ pstack->entries[pstack->top++] = key;
}
-void *pstack__pop(struct pstack *self)
+void *pstack__pop(struct pstack *pstack)
{
void *ret;
- if (self->top == 0) {
+ if (pstack->top == 0) {
pr_err("%s: underflow!\n", __func__);
return NULL;
}
- ret = self->entries[--self->top];
- self->entries[self->top] = NULL;
+ ret = pstack->entries[--pstack->top];
+ pstack->entries[pstack->top] = NULL;
return ret;
}
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 9181bf212fb..a2657fd9683 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -1015,6 +1015,8 @@ PyMODINIT_FUNC initperf(void)
pyrf_cpu_map__setup_types() < 0)
return;
+ page_size = sysconf(_SC_PAGE_SIZE);
+
Py_INCREF(&pyrf_evlist__type);
PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type);
diff --git a/tools/perf/util/rblist.c b/tools/perf/util/rblist.c
index 0171fb61100..a16cdd2625a 100644
--- a/tools/perf/util/rblist.c
+++ b/tools/perf/util/rblist.c
@@ -44,6 +44,7 @@ int rblist__add_node(struct rblist *rblist, const void *new_entry)
void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node)
{
rb_erase(rb_node, &rblist->entries);
+ --rblist->nr_entries;
rblist->node_delete(rblist, rb_node);
}
@@ -87,8 +88,7 @@ void rblist__delete(struct rblist *rblist)
while (next) {
pos = next;
next = rb_next(pos);
- rb_erase(pos, &rblist->entries);
- rblist->node_delete(rblist, pos);
+ rblist__remove_node(rblist, pos);
}
free(rblist);
}
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 730c6630cba..14683dfca2e 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -32,7 +32,6 @@
#include "../event.h"
#include "../thread.h"
#include "../trace-event.h"
-#include "../evsel.h"
PyMODINIT_FUNC initperf_trace_context(void);
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 8cdd23239c9..ce6f5116238 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1375,15 +1375,13 @@ int __perf_session__process_events(struct perf_session *session,
{
u64 head, page_offset, file_offset, file_pos, progress_next;
int err, mmap_prot, mmap_flags, map_idx = 0;
- size_t page_size, mmap_size;
+ size_t mmap_size;
char *buf, *mmaps[8];
union perf_event *event;
uint32_t size;
perf_tool__fill_defaults(tool);
- page_size = sysconf(_SC_PAGESIZE);
-
page_offset = page_size * (data_offset / page_size);
file_offset = page_offset;
head = data_offset - page_offset;
@@ -1460,6 +1458,7 @@ more:
session->ordered_samples.next_flush = ULLONG_MAX;
err = flush_sample_queue(session, tool);
out_err:
+ ui_progress__finish();
perf_session__warn_about_errors(session, tool);
perf_session_free_sample_buffers(session);
return err;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index dd6426163ba..cea133a6bdf 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -4,10 +4,11 @@
#include "hist.h"
#include "event.h"
#include "header.h"
+#include "machine.h"
#include "symbol.h"
#include "thread.h"
#include <linux/rbtree.h>
-#include "../../../include/uapi/linux/perf_event.h"
+#include <linux/perf_event.h>
struct sample_queue;
struct ip_callchain;
@@ -68,10 +69,6 @@ int perf_session__resolve_callchain(struct perf_session *self, struct perf_evsel
struct ip_callchain *chain,
struct symbol **parent);
-struct branch_info *machine__resolve_bstack(struct machine *self,
- struct thread *thread,
- struct branch_stack *bs);
-
bool perf_session__has_traces(struct perf_session *self, const char *msg);
void mem_bswap_64(void *src, int byte_size);
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 5786f323b59..b4e8c3ba559 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -52,6 +52,22 @@ struct he_stat {
u32 nr_events;
};
+struct hist_entry_diff {
+ bool computed;
+
+ /* PERF_HPP__DISPL */
+ int displacement;
+
+ /* PERF_HPP__DELTA */
+ double period_ratio_delta;
+
+ /* PERF_HPP__RATIO */
+ double period_ratio;
+
+ /* HISTC_WEIGHTED_DIFF */
+ s64 wdiff;
+};
+
/**
* struct hist_entry - histogram entry
*
@@ -61,12 +77,18 @@ struct he_stat {
struct hist_entry {
struct rb_node rb_node_in;
struct rb_node rb_node;
+ union {
+ struct list_head node;
+ struct list_head head;
+ } pairs;
struct he_stat stat;
struct map_symbol ms;
struct thread *thread;
u64 ip;
s32 cpu;
+ struct hist_entry_diff diff;
+
/* XXX These two should move to some tree widget lib */
u16 row_offset;
u16 nr_rows;
@@ -78,15 +100,30 @@ struct hist_entry {
char *srcline;
struct symbol *parent;
unsigned long position;
- union {
- struct hist_entry *pair;
- struct rb_root sorted_chain;
- };
+ struct rb_root sorted_chain;
struct branch_info *branch_info;
struct hists *hists;
struct callchain_root callchain[0];
};
+static inline bool hist_entry__has_pairs(struct hist_entry *he)
+{
+ return !list_empty(&he->pairs.node);
+}
+
+static inline struct hist_entry *hist_entry__next_pair(struct hist_entry *he)
+{
+ if (hist_entry__has_pairs(he))
+ return list_entry(he->pairs.node.next, struct hist_entry, pairs.node);
+ return NULL;
+}
+
+static inline void hist__entry_add_pair(struct hist_entry *he,
+ struct hist_entry *pair)
+{
+ list_add_tail(&he->pairs.head, &pair->pairs.node);
+}
+
enum sort_type {
SORT_PID,
SORT_COMM,
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c
index 2eeb51baf07..cfa906882e2 100644
--- a/tools/perf/util/strbuf.c
+++ b/tools/perf/util/strbuf.c
@@ -90,17 +90,17 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
if (!strbuf_avail(sb))
strbuf_grow(sb, 64);
va_start(ap, fmt);
- len = vscnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
+ len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
va_end(ap);
if (len < 0)
- die("your vscnprintf is broken");
+ die("your vsnprintf is broken");
if (len > strbuf_avail(sb)) {
strbuf_grow(sb, len);
va_start(ap, fmt);
- len = vscnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
+ len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
va_end(ap);
if (len > strbuf_avail(sb)) {
- die("this should not happen, your snprintf is broken");
+ die("this should not happen, your vsnprintf is broken");
}
}
strbuf_setlen(sb, sb->len + len);
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index 32170590892..346707df04b 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -314,6 +314,24 @@ int strtailcmp(const char *s1, const char *s2)
}
/**
+ * strxfrchar - Locate and replace character in @s
+ * @s: The string to be searched/changed.
+ * @from: Source character to be replaced.
+ * @to: Destination character.
+ *
+ * Return pointer to the changed string.
+ */
+char *strxfrchar(char *s, char from, char to)
+{
+ char *p = s;
+
+ while ((p = strchr(p, from)) != NULL)
+ *p++ = to;
+
+ return s;
+}
+
+/**
* rtrim - Removes trailing whitespace from @s.
* @s: The string to be stripped.
*
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e2e8c697cff..295f8d4feed 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -12,6 +12,7 @@
#include "build-id.h"
#include "util.h"
#include "debug.h"
+#include "machine.h"
#include "symbol.h"
#include "strlist.h"
@@ -23,7 +24,6 @@
#define KSYM_NAME_LEN 256
#endif
-static void dso_cache__free(struct rb_root *root);
static int dso__load_kernel_sym(struct dso *dso, struct map *map,
symbol_filter_t filter);
static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
@@ -56,39 +56,6 @@ static enum dso_binary_type binary_type_symtab[] = {
#define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab)
-static enum dso_binary_type binary_type_data[] = {
- DSO_BINARY_TYPE__BUILD_ID_CACHE,
- DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
- DSO_BINARY_TYPE__NOT_FOUND,
-};
-
-#define DSO_BINARY_TYPE__DATA_CNT ARRAY_SIZE(binary_type_data)
-
-int dso__name_len(const struct dso *dso)
-{
- if (!dso)
- return strlen("[unknown]");
- if (verbose)
- return dso->long_name_len;
-
- return dso->short_name_len;
-}
-
-bool dso__loaded(const struct dso *dso, enum map_type type)
-{
- return dso->loaded & (1 << type);
-}
-
-bool dso__sorted_by_name(const struct dso *dso, enum map_type type)
-{
- return dso->sorted_by_name & (1 << type);
-}
-
-static void dso__set_sorted_by_name(struct dso *dso, enum map_type type)
-{
- dso->sorted_by_name |= (1 << type);
-}
-
bool symbol_type__is_a(char symbol_type, enum map_type map_type)
{
symbol_type = toupper(symbol_type);
@@ -270,7 +237,7 @@ void symbol__delete(struct symbol *sym)
free(((void *)sym) - symbol_conf.priv_size);
}
-static size_t symbol__fprintf(struct symbol *sym, FILE *fp)
+size_t symbol__fprintf(struct symbol *sym, FILE *fp)
{
return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
sym->start, sym->end,
@@ -301,53 +268,7 @@ size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
return symbol__fprintf_symname_offs(sym, NULL, fp);
}
-void dso__set_long_name(struct dso *dso, char *name)
-{
- if (name == NULL)
- return;
- dso->long_name = name;
- dso->long_name_len = strlen(name);
-}
-
-static void dso__set_short_name(struct dso *dso, const char *name)
-{
- if (name == NULL)
- return;
- dso->short_name = name;
- dso->short_name_len = strlen(name);
-}
-
-static void dso__set_basename(struct dso *dso)
-{
- dso__set_short_name(dso, basename(dso->long_name));
-}
-
-struct dso *dso__new(const char *name)
-{
- struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
-
- if (dso != NULL) {
- int i;
- strcpy(dso->name, name);
- dso__set_long_name(dso, dso->name);
- dso__set_short_name(dso, dso->name);
- for (i = 0; i < MAP__NR_TYPES; ++i)
- dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
- dso->cache = RB_ROOT;
- dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
- dso->data_type = DSO_BINARY_TYPE__NOT_FOUND;
- dso->loaded = 0;
- dso->sorted_by_name = 0;
- dso->has_build_id = 0;
- dso->kernel = DSO_TYPE_USER;
- dso->needs_swap = DSO_SWAP__UNSET;
- INIT_LIST_HEAD(&dso->node);
- }
-
- return dso;
-}
-
-static void symbols__delete(struct rb_root *symbols)
+void symbols__delete(struct rb_root *symbols)
{
struct symbol *pos;
struct rb_node *next = rb_first(symbols);
@@ -360,25 +281,6 @@ static void symbols__delete(struct rb_root *symbols)
}
}
-void dso__delete(struct dso *dso)
-{
- int i;
- for (i = 0; i < MAP__NR_TYPES; ++i)
- symbols__delete(&dso->symbols[i]);
- if (dso->sname_alloc)
- free((char *)dso->short_name);
- if (dso->lname_alloc)
- free(dso->long_name);
- dso_cache__free(&dso->cache);
- free(dso);
-}
-
-void dso__set_build_id(struct dso *dso, void *build_id)
-{
- memcpy(dso->build_id, build_id, sizeof(dso->build_id));
- dso->has_build_id = 1;
-}
-
void symbols__insert(struct rb_root *symbols, struct symbol *sym)
{
struct rb_node **p = &symbols->rb_node;
@@ -504,29 +406,6 @@ void dso__sort_by_name(struct dso *dso, enum map_type type)
&dso->symbols[type]);
}
-int build_id__sprintf(const u8 *build_id, int len, char *bf)
-{
- char *bid = bf;
- const u8 *raw = build_id;
- int i;
-
- for (i = 0; i < len; ++i) {
- sprintf(bid, "%02x", *raw);
- ++raw;
- bid += 2;
- }
-
- return raw - build_id;
-}
-
-size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
-{
- char sbuild_id[BUILD_ID_SIZE * 2 + 1];
-
- build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
- return fprintf(fp, "%s", sbuild_id);
-}
-
size_t dso__fprintf_symbols_by_name(struct dso *dso,
enum map_type type, FILE *fp)
{
@@ -542,25 +421,6 @@ size_t dso__fprintf_symbols_by_name(struct dso *dso,
return ret;
}
-size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp)
-{
- struct rb_node *nd;
- size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
-
- if (dso->short_name != dso->long_name)
- ret += fprintf(fp, "%s, ", dso->long_name);
- ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
- dso->loaded ? "" : "NOT ");
- ret += dso__fprintf_buildid(dso, fp);
- ret += fprintf(fp, ")\n");
- for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) {
- struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
- ret += symbol__fprintf(pos, fp);
- }
-
- return ret;
-}
-
int kallsyms__parse(const char *filename, void *arg,
int (*process_symbol)(void *arg, const char *name,
char type, u64 start))
@@ -892,136 +752,6 @@ out_failure:
return -1;
}
-bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
-{
- return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
-}
-
-bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
-{
- bool have_build_id = false;
- struct dso *pos;
-
- list_for_each_entry(pos, head, node) {
- if (with_hits && !pos->hit)
- continue;
- if (pos->has_build_id) {
- have_build_id = true;
- continue;
- }
- if (filename__read_build_id(pos->long_name, pos->build_id,
- sizeof(pos->build_id)) > 0) {
- have_build_id = true;
- pos->has_build_id = true;
- }
- }
-
- return have_build_id;
-}
-
-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',
- };
-
- if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
- return '!';
- return origin[dso->symtab_type];
-}
-
-int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
- char *root_dir, char *file, size_t size)
-{
- char build_id_hex[BUILD_ID_SIZE * 2 + 1];
- int ret = 0;
-
- switch (type) {
- case DSO_BINARY_TYPE__DEBUGLINK: {
- char *debuglink;
-
- strncpy(file, dso->long_name, size);
- debuglink = file + dso->long_name_len;
- while (debuglink != file && *debuglink != '/')
- debuglink--;
- if (*debuglink == '/')
- debuglink++;
- filename__read_debuglink(dso->long_name, debuglink,
- size - (debuglink - file));
- }
- break;
- case DSO_BINARY_TYPE__BUILD_ID_CACHE:
- /* skip the locally configured cache if a symfs is given */
- if (symbol_conf.symfs[0] ||
- (dso__build_id_filename(dso, file, size) == NULL))
- ret = -1;
- break;
-
- case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
- snprintf(file, size, "%s/usr/lib/debug%s.debug",
- symbol_conf.symfs, dso->long_name);
- break;
-
- case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
- snprintf(file, size, "%s/usr/lib/debug%s",
- symbol_conf.symfs, dso->long_name);
- break;
-
- case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
- if (!dso->has_build_id) {
- ret = -1;
- break;
- }
-
- build_id__sprintf(dso->build_id,
- sizeof(dso->build_id),
- build_id_hex);
- snprintf(file, size,
- "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
- symbol_conf.symfs, build_id_hex, build_id_hex + 2);
- break;
-
- case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
- snprintf(file, size, "%s%s",
- symbol_conf.symfs, dso->long_name);
- break;
-
- case DSO_BINARY_TYPE__GUEST_KMODULE:
- snprintf(file, size, "%s%s%s", symbol_conf.symfs,
- root_dir, dso->long_name);
- break;
-
- case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
- snprintf(file, size, "%s%s", symbol_conf.symfs,
- dso->long_name);
- break;
-
- default:
- case DSO_BINARY_TYPE__KALLSYMS:
- case DSO_BINARY_TYPE__VMLINUX:
- case DSO_BINARY_TYPE__GUEST_KALLSYMS:
- case DSO_BINARY_TYPE__GUEST_VMLINUX:
- case DSO_BINARY_TYPE__JAVA_JIT:
- case DSO_BINARY_TYPE__NOT_FOUND:
- ret = -1;
- break;
- }
-
- return ret;
-}
-
int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
{
char *name;
@@ -1157,27 +887,6 @@ struct map *map_groups__find_by_name(struct map_groups *mg,
return NULL;
}
-static int dso__kernel_module_get_build_id(struct dso *dso,
- const char *root_dir)
-{
- char filename[PATH_MAX];
- /*
- * kernel module short names are of the form "[module]" and
- * we need just "module" here.
- */
- const char *name = dso->short_name + 1;
-
- snprintf(filename, sizeof(filename),
- "%s/sys/module/%.*s/notes/.note.gnu.build-id",
- root_dir, (int)strlen(name) - 1, name);
-
- if (sysfs__read_build_id(filename, dso->build_id,
- sizeof(dso->build_id)) == 0)
- dso->has_build_id = true;
-
- return 0;
-}
-
static int map_groups__set_modules_path_dir(struct map_groups *mg,
const char *dir_name)
{
@@ -1591,50 +1300,6 @@ out_try_fixup:
return err;
}
-void dsos__add(struct list_head *head, struct dso *dso)
-{
- list_add_tail(&dso->node, head);
-}
-
-struct dso *dsos__find(struct list_head *head, const char *name)
-{
- struct dso *pos;
-
- list_for_each_entry(pos, head, node)
- if (strcmp(pos->long_name, name) == 0)
- return pos;
- return NULL;
-}
-
-struct dso *__dsos__findnew(struct list_head *head, const char *name)
-{
- struct dso *dso = dsos__find(head, name);
-
- if (!dso) {
- dso = dso__new(name);
- if (dso != NULL) {
- dsos__add(head, dso);
- dso__set_basename(dso);
- }
- }
-
- return dso;
-}
-
-size_t __dsos__fprintf(struct list_head *head, FILE *fp)
-{
- struct dso *pos;
- size_t ret = 0;
-
- list_for_each_entry(pos, head, node) {
- int i;
- for (i = 0; i < MAP__NR_TYPES; ++i)
- ret += dso__fprintf(pos, i, fp);
- }
-
- return ret;
-}
-
size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp)
{
struct rb_node *nd;
@@ -1649,21 +1314,6 @@ size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp)
return ret;
}
-static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
- bool with_hits)
-{
- struct dso *pos;
- size_t ret = 0;
-
- list_for_each_entry(pos, head, node) {
- if (with_hits && !pos->hit)
- continue;
- ret += dso__fprintf_buildid(pos, fp);
- ret += fprintf(fp, " %s\n", pos->long_name);
- }
- return ret;
-}
-
size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp,
bool with_hits)
{
@@ -1684,39 +1334,6 @@ size_t machines__fprintf_dsos_buildid(struct rb_root *machines,
return ret;
}
-static struct dso*
-dso__kernel_findnew(struct machine *machine, const char *name,
- const char *short_name, int dso_type)
-{
- /*
- * The kernel dso could be created by build_id processing.
- */
- struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name);
-
- /*
- * We need to run this in all cases, since during the build_id
- * processing we had no idea this was the kernel dso.
- */
- if (dso != NULL) {
- dso__set_short_name(dso, short_name);
- dso->kernel = dso_type;
- }
-
- return dso;
-}
-
-void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
-{
- char path[PATH_MAX];
-
- if (machine__is_default_guest(machine))
- return;
- sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
- if (sysfs__read_build_id(path, dso->build_id,
- sizeof(dso->build_id)) == 0)
- dso->has_build_id = true;
-}
-
static struct dso *machine__get_kernel(struct machine *machine)
{
const char *vmlinux_name = NULL;
@@ -2065,49 +1682,6 @@ int machines__create_kernel_maps(struct rb_root *machines, pid_t pid)
return machine__create_kernel_maps(machine);
}
-static int hex(char ch)
-{
- if ((ch >= '0') && (ch <= '9'))
- return ch - '0';
- if ((ch >= 'a') && (ch <= 'f'))
- return ch - 'a' + 10;
- if ((ch >= 'A') && (ch <= 'F'))
- return ch - 'A' + 10;
- return -1;
-}
-
-/*
- * While we find nice hex chars, build a long_val.
- * Return number of chars processed.
- */
-int hex2u64(const char *ptr, u64 *long_val)
-{
- const char *p = ptr;
- *long_val = 0;
-
- while (*p) {
- const int hex_val = hex(*p);
-
- if (hex_val < 0)
- break;
-
- *long_val = (*long_val << 4) | hex_val;
- p++;
- }
-
- return p - ptr;
-}
-
-char *strxfrchar(char *s, char from, char to)
-{
- char *p = s;
-
- while ((p = strchr(p, from)) != NULL)
- *p++ = to;
-
- return s;
-}
-
int machines__create_guest_kernel_maps(struct rb_root *machines)
{
int ret = 0;
@@ -2202,229 +1776,3 @@ int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
return ret;
}
-
-struct map *dso__new_map(const char *name)
-{
- struct map *map = NULL;
- struct dso *dso = dso__new(name);
-
- if (dso)
- map = map__new2(0, dso, MAP__FUNCTION);
-
- return map;
-}
-
-static int open_dso(struct dso *dso, struct machine *machine)
-{
- char *root_dir = (char *) "";
- char *name;
- int fd;
-
- name = malloc(PATH_MAX);
- if (!name)
- return -ENOMEM;
-
- if (machine)
- root_dir = machine->root_dir;
-
- if (dso__binary_type_file(dso, dso->data_type,
- root_dir, name, PATH_MAX)) {
- free(name);
- return -EINVAL;
- }
-
- fd = open(name, O_RDONLY);
- free(name);
- return fd;
-}
-
-int dso__data_fd(struct dso *dso, struct machine *machine)
-{
- int i = 0;
-
- if (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND)
- return open_dso(dso, machine);
-
- do {
- int fd;
-
- dso->data_type = binary_type_data[i++];
-
- fd = open_dso(dso, machine);
- if (fd >= 0)
- return fd;
-
- } while (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND);
-
- return -EINVAL;
-}
-
-static void
-dso_cache__free(struct rb_root *root)
-{
- struct rb_node *next = rb_first(root);
-
- while (next) {
- struct dso_cache *cache;
-
- cache = rb_entry(next, struct dso_cache, rb_node);
- next = rb_next(&cache->rb_node);
- rb_erase(&cache->rb_node, root);
- free(cache);
- }
-}
-
-static struct dso_cache*
-dso_cache__find(struct rb_root *root, u64 offset)
-{
- struct rb_node **p = &root->rb_node;
- struct rb_node *parent = NULL;
- struct dso_cache *cache;
-
- while (*p != NULL) {
- u64 end;
-
- parent = *p;
- cache = rb_entry(parent, struct dso_cache, rb_node);
- end = cache->offset + DSO__DATA_CACHE_SIZE;
-
- if (offset < cache->offset)
- p = &(*p)->rb_left;
- else if (offset >= end)
- p = &(*p)->rb_right;
- else
- return cache;
- }
- return NULL;
-}
-
-static void
-dso_cache__insert(struct rb_root *root, struct dso_cache *new)
-{
- struct rb_node **p = &root->rb_node;
- struct rb_node *parent = NULL;
- struct dso_cache *cache;
- u64 offset = new->offset;
-
- while (*p != NULL) {
- u64 end;
-
- parent = *p;
- cache = rb_entry(parent, struct dso_cache, rb_node);
- end = cache->offset + DSO__DATA_CACHE_SIZE;
-
- if (offset < cache->offset)
- p = &(*p)->rb_left;
- else if (offset >= end)
- p = &(*p)->rb_right;
- }
-
- rb_link_node(&new->rb_node, parent, p);
- rb_insert_color(&new->rb_node, root);
-}
-
-static ssize_t
-dso_cache__memcpy(struct dso_cache *cache, u64 offset,
- u8 *data, u64 size)
-{
- u64 cache_offset = offset - cache->offset;
- u64 cache_size = min(cache->size - cache_offset, size);
-
- memcpy(data, cache->data + cache_offset, cache_size);
- return cache_size;
-}
-
-static ssize_t
-dso_cache__read(struct dso *dso, struct machine *machine,
- u64 offset, u8 *data, ssize_t size)
-{
- struct dso_cache *cache;
- ssize_t ret;
- int fd;
-
- fd = dso__data_fd(dso, machine);
- if (fd < 0)
- return -1;
-
- do {
- u64 cache_offset;
-
- ret = -ENOMEM;
-
- cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE);
- if (!cache)
- break;
-
- cache_offset = offset & DSO__DATA_CACHE_MASK;
- ret = -EINVAL;
-
- if (-1 == lseek(fd, cache_offset, SEEK_SET))
- break;
-
- ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE);
- if (ret <= 0)
- break;
-
- cache->offset = cache_offset;
- cache->size = ret;
- dso_cache__insert(&dso->cache, cache);
-
- ret = dso_cache__memcpy(cache, offset, data, size);
-
- } while (0);
-
- if (ret <= 0)
- free(cache);
-
- close(fd);
- return ret;
-}
-
-static ssize_t dso_cache_read(struct dso *dso, struct machine *machine,
- u64 offset, u8 *data, ssize_t size)
-{
- struct dso_cache *cache;
-
- cache = dso_cache__find(&dso->cache, offset);
- if (cache)
- return dso_cache__memcpy(cache, offset, data, size);
- else
- return dso_cache__read(dso, machine, offset, data, size);
-}
-
-ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
- u64 offset, u8 *data, ssize_t size)
-{
- ssize_t r = 0;
- u8 *p = data;
-
- do {
- ssize_t ret;
-
- ret = dso_cache_read(dso, machine, offset, p, size);
- if (ret < 0)
- return ret;
-
- /* Reached EOF, return what we have. */
- if (!ret)
- break;
-
- BUG_ON(ret > size);
-
- r += ret;
- p += ret;
- offset += ret;
- size -= ret;
-
- } while (size);
-
- return r;
-}
-
-ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
- struct machine *machine, u64 addr,
- u8 *data, ssize_t size)
-{
- u64 offset = map->map_ip(map, addr);
- return dso__data_read_offset(dso, machine, offset, data, size);
-}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 8b6ef7fac74..de68f98b236 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <byteswap.h>
#include <libgen.h>
+#include "build-id.h"
#ifdef LIBELF_SUPPORT
#include <libelf.h>
@@ -18,6 +19,8 @@
#include <elf.h>
#endif
+#include "dso.h"
+
#ifdef HAVE_CPLUS_DEMANGLE
extern char *cplus_demangle(const char *, int);
@@ -39,9 +42,6 @@ static inline char *bfd_demangle(void __maybe_unused *v,
#endif
#endif
-int hex2u64(const char *ptr, u64 *val);
-char *strxfrchar(char *s, char from, char to);
-
/*
* libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
* for newer versions we can use mmap to reduce memory usage:
@@ -57,8 +57,6 @@ char *strxfrchar(char *s, char from, char to);
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
#endif
-#define BUILD_ID_SIZE 20
-
/** struct symbol - symtab entry
*
* @ignore - resolvable but tools ignore it (e.g. idle routines)
@@ -74,6 +72,7 @@ struct symbol {
};
void symbol__delete(struct symbol *sym);
+void symbols__delete(struct rb_root *symbols);
static inline size_t symbol__size(const struct symbol *sym)
{
@@ -164,70 +163,6 @@ struct addr_location {
s32 cpu;
};
-enum dso_binary_type {
- DSO_BINARY_TYPE__KALLSYMS = 0,
- DSO_BINARY_TYPE__GUEST_KALLSYMS,
- DSO_BINARY_TYPE__VMLINUX,
- DSO_BINARY_TYPE__GUEST_VMLINUX,
- DSO_BINARY_TYPE__JAVA_JIT,
- DSO_BINARY_TYPE__DEBUGLINK,
- DSO_BINARY_TYPE__BUILD_ID_CACHE,
- DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
- DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
- DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
- DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
- DSO_BINARY_TYPE__GUEST_KMODULE,
- DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
- DSO_BINARY_TYPE__NOT_FOUND,
-};
-
-enum dso_kernel_type {
- DSO_TYPE_USER = 0,
- DSO_TYPE_KERNEL,
- DSO_TYPE_GUEST_KERNEL
-};
-
-enum dso_swap_type {
- DSO_SWAP__UNSET,
- DSO_SWAP__NO,
- DSO_SWAP__YES,
-};
-
-#define DSO__DATA_CACHE_SIZE 4096
-#define DSO__DATA_CACHE_MASK ~(DSO__DATA_CACHE_SIZE - 1)
-
-struct dso_cache {
- struct rb_node rb_node;
- u64 offset;
- u64 size;
- char data[0];
-};
-
-struct dso {
- struct list_head node;
- struct rb_root symbols[MAP__NR_TYPES];
- struct rb_root symbol_names[MAP__NR_TYPES];
- struct rb_root cache;
- enum dso_kernel_type kernel;
- enum dso_swap_type needs_swap;
- enum dso_binary_type symtab_type;
- enum dso_binary_type data_type;
- u8 adjust_symbols:1;
- u8 has_build_id:1;
- u8 hit:1;
- u8 annotate_warned:1;
- u8 sname_alloc:1;
- u8 lname_alloc:1;
- u8 sorted_by_name;
- u8 loaded;
- u8 build_id[BUILD_ID_SIZE];
- const char *short_name;
- char *long_name;
- u16 long_name_len;
- u16 short_name_len;
- char name[0];
-};
-
struct symsrc {
char *name;
int fd;
@@ -258,47 +193,6 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
bool symsrc__has_symtab(struct symsrc *ss);
bool symsrc__possibly_runtime(struct symsrc *ss);
-#define DSO__SWAP(dso, type, val) \
-({ \
- type ____r = val; \
- BUG_ON(dso->needs_swap == DSO_SWAP__UNSET); \
- if (dso->needs_swap == DSO_SWAP__YES) { \
- switch (sizeof(____r)) { \
- case 2: \
- ____r = bswap_16(val); \
- break; \
- case 4: \
- ____r = bswap_32(val); \
- break; \
- case 8: \
- ____r = bswap_64(val); \
- break; \
- default: \
- BUG_ON(1); \
- } \
- } \
- ____r; \
-})
-
-struct dso *dso__new(const char *name);
-void dso__delete(struct dso *dso);
-
-int dso__name_len(const struct dso *dso);
-
-bool dso__loaded(const struct dso *dso, enum map_type type);
-bool dso__sorted_by_name(const struct dso *dso, enum map_type type);
-
-static inline void dso__set_loaded(struct dso *dso, enum map_type type)
-{
- dso->loaded |= (1 << type);
-}
-
-void dso__sort_by_name(struct dso *dso, enum map_type type);
-
-void dsos__add(struct list_head *head, struct dso *dso);
-struct dso *dsos__find(struct list_head *head, const char *name);
-struct dso *__dsos__findnew(struct list_head *head, const char *name);
-
int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter);
int dso__load_vmlinux(struct dso *dso, struct map *map,
const char *vmlinux, symbol_filter_t filter);
@@ -306,30 +200,7 @@ int dso__load_vmlinux_path(struct dso *dso, struct map *map,
symbol_filter_t filter);
int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map,
symbol_filter_t filter);
-int machine__load_kallsyms(struct machine *machine, const char *filename,
- enum map_type type, symbol_filter_t filter);
-int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
- symbol_filter_t filter);
-
-size_t __dsos__fprintf(struct list_head *head, FILE *fp);
-
-size_t machine__fprintf_dsos_buildid(struct machine *machine,
- FILE *fp, bool with_hits);
-size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp);
-size_t machines__fprintf_dsos_buildid(struct rb_root *machines,
- FILE *fp, bool with_hits);
-size_t dso__fprintf_buildid(struct dso *dso, FILE *fp);
-size_t dso__fprintf_symbols_by_name(struct dso *dso,
- enum map_type type, FILE *fp);
-size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp);
-
-char dso__symtab_origin(const struct dso *dso);
-void dso__set_long_name(struct dso *dso, char *name);
-void dso__set_build_id(struct dso *dso, void *build_id);
-bool dso__build_id_equal(const struct dso *dso, u8 *build_id);
-void dso__read_running_kernel_build_id(struct dso *dso,
- struct machine *machine);
-struct map *dso__new_map(const char *name);
+
struct symbol *dso__find_symbol(struct dso *dso, enum map_type type,
u64 addr);
struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
@@ -337,22 +208,12 @@ struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
int filename__read_build_id(const char *filename, void *bf, size_t size);
int sysfs__read_build_id(const char *filename, void *bf, size_t size);
-bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
-int build_id__sprintf(const u8 *build_id, int len, char *bf);
int kallsyms__parse(const char *filename, void *arg,
int (*process_symbol)(void *arg, const char *name,
char type, u64 start));
int filename__read_debuglink(const char *filename, char *debuglink,
size_t size);
-void machine__destroy_kernel_maps(struct machine *machine);
-int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel);
-int machine__create_kernel_maps(struct machine *machine);
-
-int machines__create_kernel_maps(struct rb_root *machines, pid_t pid);
-int machines__create_guest_kernel_maps(struct rb_root *machines);
-void machines__destroy_guest_kernel_maps(struct rb_root *machines);
-
int symbol__init(void);
void symbol__exit(void);
void symbol__elf_init(void);
@@ -360,20 +221,9 @@ struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name);
size_t symbol__fprintf_symname_offs(const struct symbol *sym,
const struct addr_location *al, FILE *fp);
size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp);
+size_t symbol__fprintf(struct symbol *sym, FILE *fp);
bool symbol_type__is_a(char symbol_type, enum map_type map_type);
-size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp);
-
-int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
- char *root_dir, char *file, size_t size);
-
-int dso__data_fd(struct dso *dso, struct machine *machine);
-ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
- u64 offset, u8 *data, ssize_t size);
-ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
- struct machine *machine, u64 addr,
- u8 *data, ssize_t size);
-int dso__test_data(void);
int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
struct symsrc *runtime_ss, symbol_filter_t filter,
int kmodule);
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 8b3e5939afb..df59623ac76 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -7,7 +7,7 @@
#include "util.h"
#include "debug.h"
-static struct thread *thread__new(pid_t pid)
+struct thread *thread__new(pid_t pid)
{
struct thread *self = zalloc(sizeof(*self));
@@ -60,45 +60,6 @@ static size_t thread__fprintf(struct thread *self, FILE *fp)
map_groups__fprintf(&self->mg, verbose, fp);
}
-struct thread *machine__findnew_thread(struct machine *self, pid_t pid)
-{
- struct rb_node **p = &self->threads.rb_node;
- struct rb_node *parent = NULL;
- struct thread *th;
-
- /*
- * Font-end cache - PID lookups come in blocks,
- * so most of the time we dont have to look up
- * the full rbtree:
- */
- if (self->last_match && self->last_match->pid == pid)
- return self->last_match;
-
- while (*p != NULL) {
- parent = *p;
- th = rb_entry(parent, struct thread, rb_node);
-
- if (th->pid == pid) {
- self->last_match = th;
- return th;
- }
-
- if (pid < th->pid)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
-
- th = thread__new(pid);
- if (th != NULL) {
- rb_link_node(&th->rb_node, parent, p);
- rb_insert_color(&th->rb_node, &self->threads);
- self->last_match = th;
- }
-
- return th;
-}
-
void thread__insert_map(struct thread *self, struct map *map)
{
map_groups__fixup_overlappings(&self->mg, map, verbose, stderr);
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index f66610b7bac..f2fa17caa7d 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -3,6 +3,7 @@
#include <linux/rbtree.h>
#include <unistd.h>
+#include <sys/types.h>
#include "symbol.h"
struct thread {
@@ -22,6 +23,7 @@ struct thread {
struct machine;
+struct thread *thread__new(pid_t pid);
void thread__delete(struct thread *self);
int thread__set_comm(struct thread *self, const char *comm);
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index 719ed74a856..3741572696a 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -47,8 +47,6 @@ int file_bigendian;
int host_bigendian;
static int long_size;
-static unsigned long page_size;
-
static ssize_t calc_data_size;
static bool repipe;
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 99664598bc1..5906e8426cc 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -10,6 +10,8 @@
/*
* XXX We need to find a better place for these things...
*/
+unsigned int page_size;
+
bool perf_host = true;
bool perf_guest = false;
@@ -164,6 +166,39 @@ size_t hex_width(u64 v)
return n;
}
+static int hex(char ch)
+{
+ if ((ch >= '0') && (ch <= '9'))
+ return ch - '0';
+ if ((ch >= 'a') && (ch <= 'f'))
+ return ch - 'a' + 10;
+ if ((ch >= 'A') && (ch <= 'F'))
+ return ch - 'A' + 10;
+ return -1;
+}
+
+/*
+ * While we find nice hex chars, build a long_val.
+ * Return number of chars processed.
+ */
+int hex2u64(const char *ptr, u64 *long_val)
+{
+ const char *p = ptr;
+ *long_val = 0;
+
+ while (*p) {
+ const int hex_val = hex(*p);
+
+ if (hex_val < 0)
+ break;
+
+ *long_val = (*long_val << 4) | hex_val;
+ p++;
+ }
+
+ return p - ptr;
+}
+
/* Obtain a backtrace and print it to stdout. */
#ifdef BACKTRACE_SUPPORT
void dump_stack(void)
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 70fa70b535b..c2330918110 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -198,6 +198,10 @@ static inline int has_extension(const char *filename, const char *ext)
#undef tolower
#undef toupper
+#ifndef NSEC_PER_MSEC
+#define NSEC_PER_MSEC 1000000L
+#endif
+
extern unsigned char sane_ctype[256];
#define GIT_SPACE 0x01
#define GIT_DIGIT 0x02
@@ -236,6 +240,7 @@ void argv_free(char **argv);
bool strglobmatch(const char *str, const char *pat);
bool strlazymatch(const char *str, const char *pat);
int strtailcmp(const char *s1, const char *s2);
+char *strxfrchar(char *s, char from, char to);
unsigned long convert_unit(unsigned long value, char *unit);
int readn(int fd, void *buf, size_t size);
@@ -258,9 +263,12 @@ bool is_power_of_2(unsigned long n)
}
size_t hex_width(u64 v);
+int hex2u64(const char *ptr, u64 *val);
char *rtrim(char *s);
void dump_stack(void);
+extern unsigned int page_size;
+
#endif
diff --git a/tools/power/cpupower/.gitignore b/tools/power/cpupower/.gitignore
index 8a83dd2ffc1..d42073f1260 100644
--- a/tools/power/cpupower/.gitignore
+++ b/tools/power/cpupower/.gitignore
@@ -20,3 +20,10 @@ utils/cpufreq-set.o
utils/cpufreq-aperf.o
cpupower
bench/cpufreq-bench
+debug/kernel/Module.symvers
+debug/i386/centrino-decode
+debug/i386/dump_psb
+debug/i386/intel_gsic
+debug/i386/powernow-k8-decode
+debug/x86_64/centrino-decode
+debug/x86_64/powernow-k8-decode
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile
index cf397bd26d0..d875a74a3bd 100644
--- a/tools/power/cpupower/Makefile
+++ b/tools/power/cpupower/Makefile
@@ -253,7 +253,8 @@ clean:
| xargs rm -f
-rm -f $(OUTPUT)cpupower
-rm -f $(OUTPUT)libcpupower.so*
- -rm -rf $(OUTPUT)po/*.{gmo,pot}
+ -rm -rf $(OUTPUT)po/*.gmo
+ -rm -rf $(OUTPUT)po/*.pot
$(MAKE) -C bench O=$(OUTPUT) clean
diff --git a/tools/power/cpupower/debug/i386/Makefile b/tools/power/cpupower/debug/i386/Makefile
index 3ba158f0e28..c05cc0ac80c 100644
--- a/tools/power/cpupower/debug/i386/Makefile
+++ b/tools/power/cpupower/debug/i386/Makefile
@@ -26,7 +26,10 @@ $(OUTPUT)powernow-k8-decode: powernow-k8-decode.c
all: $(OUTPUT)centrino-decode $(OUTPUT)dump_psb $(OUTPUT)intel_gsic $(OUTPUT)powernow-k8-decode
clean:
- rm -rf $(OUTPUT){centrino-decode,dump_psb,intel_gsic,powernow-k8-decode}
+ rm -rf $(OUTPUT)centrino-decode
+ rm -rf $(OUTPUT)dump_psb
+ rm -rf $(OUTPUT)intel_gsic
+ rm -rf $(OUTPUT)powernow-k8-decode
install:
$(INSTALL) -d $(DESTDIR)${bindir}
diff --git a/tools/power/cpupower/man/cpupower-monitor.1 b/tools/power/cpupower/man/cpupower-monitor.1
index 1141c207371..e01c35d13b6 100644
--- a/tools/power/cpupower/man/cpupower-monitor.1
+++ b/tools/power/cpupower/man/cpupower-monitor.1
@@ -7,11 +7,11 @@ cpupower\-monitor \- Report processor frequency and idle statistics
.RB "\-l"
.B cpupower monitor
-.RB [ "\-m <mon1>," [ "<mon2>,..." ] ]
+.RB [ -c ] [ "\-m <mon1>," [ "<mon2>,..." ] ]
.RB [ "\-i seconds" ]
.br
.B cpupower monitor
-.RB [ "\-m <mon1>," [ "<mon2>,..." ] ]
+.RB [ -c ][ "\-m <mon1>," [ "<mon2>,..." ] ]
.RB command
.br
.SH DESCRIPTION
@@ -64,6 +64,17 @@ Only display specific monitors. Use the monitor string(s) provided by \-l option
Measure intervall.
.RE
.PP
+\-c
+.RS 4
+Schedule the process on every core before starting and ending measuring.
+This could be needed for the Idle_Stats monitor when no other MSR based
+monitor (has to be run on the core that is measured) is run in parallel.
+This is to wake up the processors from deeper sleep states and let the
+kernel re
+-account its cpuidle (C-state) information before reading the
+cpuidle timings from sysfs.
+.RE
+.PP
command
.RS 4
Measure idle and frequency characteristics of an arbitrary command/workload.
diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c
index 906895d21cc..93b0aa74ca0 100644
--- a/tools/power/cpupower/utils/helpers/cpuid.c
+++ b/tools/power/cpupower/utils/helpers/cpuid.c
@@ -158,6 +158,8 @@ out:
cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
case 0x2A: /* SNB */
case 0x2D: /* SNB Xeon */
+ case 0x3A: /* IVB */
+ case 0x3E: /* IVB Xeon */
cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
cpu_info->caps |= CPUPOWER_CAP_IS_SNB;
break;
diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h
index 2eb584cf2f5..aa9e95486a2 100644
--- a/tools/power/cpupower/utils/helpers/helpers.h
+++ b/tools/power/cpupower/utils/helpers/helpers.h
@@ -92,6 +92,14 @@ extern int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info);
extern struct cpupower_cpu_info cpupower_cpu_info;
/* cpuid and cpuinfo helpers **************************/
+struct cpuid_core_info {
+ int pkg;
+ int core;
+ int cpu;
+
+ /* flags */
+ unsigned int is_online:1;
+};
/* CPU topology/hierarchy parsing ******************/
struct cpupower_topology {
@@ -101,18 +109,12 @@ struct cpupower_topology {
unsigned int threads; /* per core */
/* Array gets mallocated with cores entries, holding per core info */
- struct {
- int pkg;
- int core;
- int cpu;
-
- /* flags */
- unsigned int is_online:1;
- } *core_info;
+ struct cpuid_core_info *core_info;
};
extern int get_cpu_topology(struct cpupower_topology *cpu_top);
extern void cpu_topology_release(struct cpupower_topology cpu_top);
+
/* CPU topology/hierarchy parsing ******************/
/* X86 ONLY ****************************************/
diff --git a/tools/power/cpupower/utils/helpers/sysfs.c b/tools/power/cpupower/utils/helpers/sysfs.c
index 96e28c124b5..38ab9162946 100644
--- a/tools/power/cpupower/utils/helpers/sysfs.c
+++ b/tools/power/cpupower/utils/helpers/sysfs.c
@@ -37,25 +37,6 @@ unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen)
return (unsigned int) numread;
}
-static unsigned int sysfs_write_file(const char *path,
- const char *value, size_t len)
-{
- int fd;
- ssize_t numwrite;
-
- fd = open(path, O_WRONLY);
- if (fd == -1)
- return 0;
-
- numwrite = write(fd, value, len);
- if (numwrite < 1) {
- close(fd);
- return 0;
- }
- close(fd);
- return (unsigned int) numwrite;
-}
-
/*
* Detect whether a CPU is online
*
diff --git a/tools/power/cpupower/utils/helpers/topology.c b/tools/power/cpupower/utils/helpers/topology.c
index 4eae2c47ba4..c13120af519 100644
--- a/tools/power/cpupower/utils/helpers/topology.c
+++ b/tools/power/cpupower/utils/helpers/topology.c
@@ -20,9 +20,8 @@
#include <helpers/sysfs.h>
/* returns -1 on failure, 0 on success */
-int sysfs_topology_read_file(unsigned int cpu, const char *fname)
+static int sysfs_topology_read_file(unsigned int cpu, const char *fname, int *result)
{
- unsigned long value;
char linebuf[MAX_LINE_LEN];
char *endp;
char path[SYSFS_PATH_MAX];
@@ -31,20 +30,12 @@ int sysfs_topology_read_file(unsigned int cpu, const char *fname)
cpu, fname);
if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0)
return -1;
- value = strtoul(linebuf, &endp, 0);
+ *result = strtol(linebuf, &endp, 0);
if (endp == linebuf || errno == ERANGE)
return -1;
- return value;
+ return 0;
}
-struct cpuid_core_info {
- unsigned int pkg;
- unsigned int thread;
- unsigned int cpu;
- /* flags */
- unsigned int is_online:1;
-};
-
static int __compare(const void *t1, const void *t2)
{
struct cpuid_core_info *top1 = (struct cpuid_core_info *)t1;
@@ -53,9 +44,9 @@ static int __compare(const void *t1, const void *t2)
return -1;
else if (top1->pkg > top2->pkg)
return 1;
- else if (top1->thread < top2->thread)
+ else if (top1->core < top2->core)
return -1;
- else if (top1->thread > top2->thread)
+ else if (top1->core > top2->core)
return 1;
else if (top1->cpu < top2->cpu)
return -1;
@@ -73,28 +64,42 @@ static int __compare(const void *t1, const void *t2)
*/
int get_cpu_topology(struct cpupower_topology *cpu_top)
{
- int cpu, cpus = sysconf(_SC_NPROCESSORS_CONF);
+ int cpu, last_pkg, cpus = sysconf(_SC_NPROCESSORS_CONF);
- cpu_top->core_info = malloc(sizeof(struct cpupower_topology) * cpus);
+ cpu_top->core_info = malloc(sizeof(struct cpuid_core_info) * cpus);
if (cpu_top->core_info == NULL)
return -ENOMEM;
cpu_top->pkgs = cpu_top->cores = 0;
for (cpu = 0; cpu < cpus; cpu++) {
cpu_top->core_info[cpu].cpu = cpu;
cpu_top->core_info[cpu].is_online = sysfs_is_cpu_online(cpu);
- cpu_top->core_info[cpu].pkg =
- sysfs_topology_read_file(cpu, "physical_package_id");
- if ((int)cpu_top->core_info[cpu].pkg != -1 &&
- cpu_top->core_info[cpu].pkg > cpu_top->pkgs)
- cpu_top->pkgs = cpu_top->core_info[cpu].pkg;
- cpu_top->core_info[cpu].core =
- sysfs_topology_read_file(cpu, "core_id");
+ if(sysfs_topology_read_file(
+ cpu,
+ "physical_package_id",
+ &(cpu_top->core_info[cpu].pkg)) < 0)
+ return -1;
+ if(sysfs_topology_read_file(
+ cpu,
+ "core_id",
+ &(cpu_top->core_info[cpu].core)) < 0)
+ return -1;
}
- cpu_top->pkgs++;
qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info),
__compare);
+ /* Count the number of distinct pkgs values. This works
+ because the primary sort of the core_info struct was just
+ done by pkg value. */
+ last_pkg = cpu_top->core_info[0].pkg;
+ for(cpu = 1; cpu < cpus; cpu++) {
+ if(cpu_top->core_info[cpu].pkg != last_pkg) {
+ last_pkg = cpu_top->core_info[cpu].pkg;
+ cpu_top->pkgs++;
+ }
+ }
+ cpu_top->pkgs++;
+
/* Intel's cores count is not consecutively numbered, there may
* be a core_id of 3, but none of 2. Assume there always is 0
* Get amount of cores by counting duplicates in a package
diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
index 0d6571e418d..c4bae9203a6 100644
--- a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
+++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
@@ -39,6 +39,7 @@ static int mode;
static int interval = 1;
static char *show_monitors_param;
static struct cpupower_topology cpu_top;
+static unsigned int wake_cpus;
/* ToDo: Document this in the manpage */
static char range_abbr[RANGE_MAX] = { 'T', 'C', 'P', 'M', };
@@ -84,7 +85,7 @@ int fill_string_with_spaces(char *s, int n)
void print_header(int topology_depth)
{
int unsigned mon;
- int state, need_len, pr_mon_len;
+ int state, need_len;
cstate_t s;
char buf[128] = "";
int percent_width = 4;
@@ -93,7 +94,6 @@ void print_header(int topology_depth)
printf("%s|", buf);
for (mon = 0; mon < avail_monitors; mon++) {
- pr_mon_len = 0;
need_len = monitors[mon]->hw_states_num * (percent_width + 3)
- 1;
if (mon != 0) {
@@ -315,16 +315,28 @@ int fork_it(char **argv)
int do_interval_measure(int i)
{
unsigned int num;
+ int cpu;
+
+ if (wake_cpus)
+ for (cpu = 0; cpu < cpu_count; cpu++)
+ bind_cpu(cpu);
for (num = 0; num < avail_monitors; num++) {
dprint("HW C-state residency monitor: %s - States: %d\n",
monitors[num]->name, monitors[num]->hw_states_num);
monitors[num]->start();
}
+
sleep(i);
+
+ if (wake_cpus)
+ for (cpu = 0; cpu < cpu_count; cpu++)
+ bind_cpu(cpu);
+
for (num = 0; num < avail_monitors; num++)
monitors[num]->stop();
+
return 0;
}
@@ -333,7 +345,7 @@ static void cmdline(int argc, char *argv[])
int opt;
progname = basename(argv[0]);
- while ((opt = getopt(argc, argv, "+li:m:")) != -1) {
+ while ((opt = getopt(argc, argv, "+lci:m:")) != -1) {
switch (opt) {
case 'l':
if (mode)
@@ -352,6 +364,9 @@ static void cmdline(int argc, char *argv[])
mode = show;
show_monitors_param = optarg;
break;
+ case 'c':
+ wake_cpus = 1;
+ break;
default:
print_wrong_arg_exit();
}
diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
index 9312ee1f2db..9e43f3371fb 100644
--- a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
+++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
@@ -65,4 +65,21 @@ extern long long timespec_diff_us(struct timespec start, struct timespec end);
"could be inaccurate\n"), mes, ov); \
}
+
+/* Taken over from x86info project sources -> return 0 on success */
+#include <sched.h>
+#include <sys/types.h>
+#include <unistd.h>
+static inline int bind_cpu(int cpu)
+{
+ cpu_set_t set;
+
+ if (sched_getaffinity(getpid(), sizeof(set), &set) == 0) {
+ CPU_ZERO(&set);
+ CPU_SET(cpu, &set);
+ return sched_setaffinity(getpid(), sizeof(set), &set);
+ }
+ return 1;
+}
+
#endif /* __CPUIDLE_INFO_HW__ */
diff --git a/tools/power/cpupower/utils/idle_monitor/snb_idle.c b/tools/power/cpupower/utils/idle_monitor/snb_idle.c
index a1bc07cd53e..a99b43b97d6 100644
--- a/tools/power/cpupower/utils/idle_monitor/snb_idle.c
+++ b/tools/power/cpupower/utils/idle_monitor/snb_idle.c
@@ -150,9 +150,15 @@ static struct cpuidle_monitor *snb_register(void)
|| cpupower_cpu_info.family != 6)
return NULL;
- if (cpupower_cpu_info.model != 0x2A
- && cpupower_cpu_info.model != 0x2D)
+ switch (cpupower_cpu_info.model) {
+ case 0x2A: /* SNB */
+ case 0x2D: /* SNB Xeon */
+ case 0x3A: /* IVB */
+ case 0x3E: /* IVB Xeon */
+ break;
+ default:
return NULL;
+ }
is_valid = calloc(cpu_count, sizeof(int));
for (num = 0; num < SNB_CSTATE_COUNT; num++) {
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 2655ae9a3ad..ea095abbe97 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -206,8 +206,10 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr)
retval = pread(fd, msr, sizeof *msr, offset);
close(fd);
- if (retval != sizeof *msr)
+ if (retval != sizeof *msr) {
+ fprintf(stderr, "%s offset 0x%zx read failed\n", pathname, offset);
return -1;
+ }
return 0;
}
@@ -1101,7 +1103,9 @@ void turbostat_loop()
restart:
retval = for_all_cpus(get_counters, EVEN_COUNTERS);
- if (retval) {
+ if (retval < -1) {
+ exit(retval);
+ } else if (retval == -1) {
re_initialize();
goto restart;
}
@@ -1114,7 +1118,9 @@ restart:
}
sleep(interval_sec);
retval = for_all_cpus(get_counters, ODD_COUNTERS);
- if (retval) {
+ if (retval < -1) {
+ exit(retval);
+ } else if (retval == -1) {
re_initialize();
goto restart;
}
@@ -1126,7 +1132,9 @@ restart:
flush_stdout();
sleep(interval_sec);
retval = for_all_cpus(get_counters, EVEN_COUNTERS);
- if (retval) {
+ if (retval < -1) {
+ exit(retval);
+ } else if (retval == -1) {
re_initialize();
goto restart;
}
@@ -1545,8 +1553,11 @@ void turbostat_init()
int fork_it(char **argv)
{
pid_t child_pid;
+ int status;
- for_all_cpus(get_counters, EVEN_COUNTERS);
+ status = for_all_cpus(get_counters, EVEN_COUNTERS);
+ if (status)
+ exit(status);
/* clear affinity side-effect of get_counters() */
sched_setaffinity(0, cpu_present_setsize, cpu_present_set);
gettimeofday(&tv_even, (struct timezone *)NULL);
@@ -1556,7 +1567,6 @@ int fork_it(char **argv)
/* child */
execvp(argv[0], argv);
} else {
- int status;
/* parent */
if (child_pid == -1) {
@@ -1568,7 +1578,7 @@ int fork_it(char **argv)
signal(SIGQUIT, SIG_IGN);
if (waitpid(child_pid, &status, 0) == -1) {
perror("wait");
- exit(1);
+ exit(status);
}
}
/*
@@ -1585,7 +1595,7 @@ int fork_it(char **argv)
fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);
- return 0;
+ return status;
}
void cmdline(int argc, char **argv)
@@ -1594,7 +1604,7 @@ void cmdline(int argc, char **argv)
progname = argv[0];
- while ((opt = getopt(argc, argv, "+pPSvisc:sC:m:M:")) != -1) {
+ while ((opt = getopt(argc, argv, "+pPSvi:sc:sC:m:M:")) != -1) {
switch (opt) {
case 'p':
show_core_only++;
diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include
index 96ce80a3743..2964b96aa55 100644
--- a/tools/scripts/Makefile.include
+++ b/tools/scripts/Makefile.include
@@ -1,8 +1,11 @@
-ifeq ("$(origin O)", "command line")
+ifeq ($(origin O), command line)
dummy := $(if $(shell test -d $(O) || echo $(O)),$(error O=$(O) does not exist),)
ABSOLUTE_O := $(shell cd $(O) ; pwd)
- OUTPUT := $(ABSOLUTE_O)/
+ OUTPUT := $(ABSOLUTE_O)/$(if $(subdir),$(subdir)/)
COMMAND_O := O=$(ABSOLUTE_O)
+ifeq ($(objtree),)
+ objtree := $(O)
+endif
endif
ifneq ($(OUTPUT),)
@@ -41,7 +44,16 @@ else
NO_SUBDIR = :
endif
-QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir
+#
+# Define a callable command for descending to a new directory
+#
+# Call by doing: $(call descend,directory[,target])
+#
+descend = \
+ +mkdir -p $(OUTPUT)$(1) && \
+ $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2)
+
+QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir
QUIET_SUBDIR1 =
ifneq ($(findstring $(MAKEFLAGS),s),s)
@@ -56,5 +68,10 @@ ifndef V
$(MAKE) $(PRINT_DIR) -C $$subdir
QUIET_FLEX = @echo ' ' FLEX $@;
QUIET_BISON = @echo ' ' BISON $@;
+
+ descend = \
+ @echo ' ' DESCEND $(1); \
+ mkdir -p $(OUTPUT)$(1) && \
+ $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2)
endif
endif
diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile
index b336b24aa6c..7300d0702ef 100644
--- a/tools/testing/selftests/vm/Makefile
+++ b/tools/testing/selftests/vm/Makefile
@@ -1,9 +1,9 @@
# Makefile for vm selftests
CC = $(CROSS_COMPILE)gcc
-CFLAGS = -Wall -Wextra
+CFLAGS = -Wall
-all: hugepage-mmap hugepage-shm map_hugetlb
+all: hugepage-mmap hugepage-shm map_hugetlb thuge-gen
%: %.c
$(CC) $(CFLAGS) -o $@ $^
diff --git a/tools/testing/selftests/vm/thuge-gen.c b/tools/testing/selftests/vm/thuge-gen.c
new file mode 100644
index 00000000000..c87957295f7
--- /dev/null
+++ b/tools/testing/selftests/vm/thuge-gen.c
@@ -0,0 +1,254 @@
+/* Test selecting other page sizes for mmap/shmget.
+
+ Before running this huge pages for each huge page size must have been
+ reserved.
+ For large pages beyond MAX_ORDER (like 1GB on x86) boot options must be used.
+ Also shmmax must be increased.
+ And you need to run as root to work around some weird permissions in shm.
+ And nothing using huge pages should run in parallel.
+ When the program aborts you may need to clean up the shm segments with
+ ipcrm -m by hand, like this
+ sudo ipcs | awk '$1 == "0x00000000" {print $2}' | xargs -n1 sudo ipcrm -m
+ (warning this will remove all if someone else uses them) */
+
+#define _GNU_SOURCE 1
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <glob.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <string.h>
+
+#define err(x) perror(x), exit(1)
+
+#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT)
+#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT)
+#define MAP_HUGE_SHIFT 26
+#define MAP_HUGE_MASK 0x3f
+#define MAP_HUGETLB 0x40000
+
+#define SHM_HUGETLB 04000 /* segment will use huge TLB pages */
+#define SHM_HUGE_SHIFT 26
+#define SHM_HUGE_MASK 0x3f
+#define SHM_HUGE_2MB (21 << SHM_HUGE_SHIFT)
+#define SHM_HUGE_1GB (30 << SHM_HUGE_SHIFT)
+
+#define NUM_PAGESIZES 5
+
+#define NUM_PAGES 4
+
+#define Dprintf(fmt...) // printf(fmt)
+
+unsigned long page_sizes[NUM_PAGESIZES];
+int num_page_sizes;
+
+int ilog2(unsigned long v)
+{
+ int l = 0;
+ while ((1UL << l) < v)
+ l++;
+ return l;
+}
+
+void find_pagesizes(void)
+{
+ glob_t g;
+ int i;
+ glob("/sys/kernel/mm/hugepages/hugepages-*kB", 0, NULL, &g);
+ assert(g.gl_pathc <= NUM_PAGESIZES);
+ for (i = 0; i < g.gl_pathc; i++) {
+ sscanf(g.gl_pathv[i], "/sys/kernel/mm/hugepages/hugepages-%lukB",
+ &page_sizes[i]);
+ page_sizes[i] <<= 10;
+ printf("Found %luMB\n", page_sizes[i] >> 20);
+ }
+ num_page_sizes = g.gl_pathc;
+ globfree(&g);
+}
+
+unsigned long default_huge_page_size(void)
+{
+ unsigned long hps = 0;
+ char *line = NULL;
+ size_t linelen = 0;
+ FILE *f = fopen("/proc/meminfo", "r");
+ if (!f)
+ return 0;
+ while (getline(&line, &linelen, f) > 0) {
+ if (sscanf(line, "Hugepagesize: %lu kB", &hps) == 1) {
+ hps <<= 10;
+ break;
+ }
+ }
+ free(line);
+ return hps;
+}
+
+void show(unsigned long ps)
+{
+ char buf[100];
+ if (ps == getpagesize())
+ return;
+ printf("%luMB: ", ps >> 20);
+ fflush(stdout);
+ snprintf(buf, sizeof buf,
+ "cat /sys/kernel/mm/hugepages/hugepages-%lukB/free_hugepages",
+ ps >> 10);
+ system(buf);
+}
+
+unsigned long read_sysfs(int warn, char *fmt, ...)
+{
+ char *line = NULL;
+ size_t linelen = 0;
+ char buf[100];
+ FILE *f;
+ va_list ap;
+ unsigned long val = 0;
+
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof buf, fmt, ap);
+ va_end(ap);
+
+ f = fopen(buf, "r");
+ if (!f) {
+ if (warn)
+ printf("missing %s\n", buf);
+ return 0;
+ }
+ if (getline(&line, &linelen, f) > 0) {
+ sscanf(line, "%lu", &val);
+ }
+ fclose(f);
+ free(line);
+ return val;
+}
+
+unsigned long read_free(unsigned long ps)
+{
+ return read_sysfs(ps != getpagesize(),
+ "/sys/kernel/mm/hugepages/hugepages-%lukB/free_hugepages",
+ ps >> 10);
+}
+
+void test_mmap(unsigned long size, unsigned flags)
+{
+ char *map;
+ unsigned long before, after;
+ int err;
+
+ before = read_free(size);
+ map = mmap(NULL, size*NUM_PAGES, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB|flags, 0, 0);
+
+ if (map == (char *)-1) err("mmap");
+ memset(map, 0xff, size*NUM_PAGES);
+ after = read_free(size);
+ Dprintf("before %lu after %lu diff %ld size %lu\n",
+ before, after, before - after, size);
+ assert(size == getpagesize() || (before - after) == NUM_PAGES);
+ show(size);
+ err = munmap(map, size);
+ assert(!err);
+}
+
+void test_shmget(unsigned long size, unsigned flags)
+{
+ int id;
+ unsigned long before, after;
+ int err;
+
+ before = read_free(size);
+ id = shmget(IPC_PRIVATE, size * NUM_PAGES, IPC_CREAT|0600|flags);
+ if (id < 0) err("shmget");
+
+ struct shm_info i;
+ if (shmctl(id, SHM_INFO, (void *)&i) < 0) err("shmctl");
+ Dprintf("alloc %lu res %lu\n", i.shm_tot, i.shm_rss);
+
+
+ Dprintf("id %d\n", id);
+ char *map = shmat(id, NULL, 0600);
+ if (map == (char*)-1) err("shmat");
+
+ shmctl(id, IPC_RMID, NULL);
+
+ memset(map, 0xff, size*NUM_PAGES);
+ after = read_free(size);
+
+ Dprintf("before %lu after %lu diff %ld size %lu\n",
+ before, after, before - after, size);
+ assert(size == getpagesize() || (before - after) == NUM_PAGES);
+ show(size);
+ err = shmdt(map);
+ assert(!err);
+}
+
+void sanity_checks(void)
+{
+ int i;
+ unsigned long largest = getpagesize();
+
+ for (i = 0; i < num_page_sizes; i++) {
+ if (page_sizes[i] > largest)
+ largest = page_sizes[i];
+
+ if (read_free(page_sizes[i]) < NUM_PAGES) {
+ printf("Not enough huge pages for page size %lu MB, need %u\n",
+ page_sizes[i] >> 20,
+ NUM_PAGES);
+ exit(0);
+ }
+ }
+
+ if (read_sysfs(0, "/proc/sys/kernel/shmmax") < NUM_PAGES * largest) {
+ printf("Please do echo %lu > /proc/sys/kernel/shmmax", largest * NUM_PAGES);
+ exit(0);
+ }
+
+#if defined(__x86_64__)
+ if (largest != 1U<<30) {
+ printf("No GB pages available on x86-64\n"
+ "Please boot with hugepagesz=1G hugepages=%d\n", NUM_PAGES);
+ exit(0);
+ }
+#endif
+}
+
+int main(void)
+{
+ int i;
+ unsigned default_hps = default_huge_page_size();
+
+ find_pagesizes();
+
+ sanity_checks();
+
+ for (i = 0; i < num_page_sizes; i++) {
+ unsigned long ps = page_sizes[i];
+ int arg = ilog2(ps) << MAP_HUGE_SHIFT;
+ printf("Testing %luMB mmap with shift %x\n", ps >> 20, arg);
+ test_mmap(ps, MAP_HUGETLB | arg);
+ }
+ printf("Testing default huge mmap\n");
+ test_mmap(default_hps, SHM_HUGETLB);
+
+ puts("Testing non-huge shmget");
+ test_shmget(getpagesize(), 0);
+
+ for (i = 0; i < num_page_sizes; i++) {
+ unsigned long ps = page_sizes[i];
+ int arg = ilog2(ps) << SHM_HUGE_SHIFT;
+ printf("Testing %luMB shmget with shift %x\n", ps >> 20, arg);
+ test_shmget(ps, SHM_HUGETLB | arg);
+ }
+ puts("default huge shmget");
+ test_shmget(default_hps, SHM_HUGETLB);
+
+ return 0;
+}